23776 lines
3.2 MiB
23776 lines
3.2 MiB
(() => {
|
|
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __defProps = Object.defineProperties;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
var __getProtoOf = Object.getPrototypeOf;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __spreadValues = (a, b) => {
|
|
for (var prop in b || (b = {}))
|
|
if (__hasOwnProp.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
if (__getOwnPropSymbols)
|
|
for (var prop of __getOwnPropSymbols(b)) {
|
|
if (__propIsEnum.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
}
|
|
return a;
|
|
};
|
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
var __commonJS = (cb, mod) => function __require() {
|
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
|
|
// node_modules/react/cjs/react.development.js
|
|
var require_react_development = __commonJS({
|
|
"node_modules/react/cjs/react.development.js"(exports, module) {
|
|
"use strict";
|
|
if (true) {
|
|
(function() {
|
|
"use strict";
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
|
|
}
|
|
var ReactVersion = "18.1.0";
|
|
var enableScopeAPI = false;
|
|
var enableCacheElement = false;
|
|
var enableTransitionTracing = false;
|
|
var enableLegacyHidden = false;
|
|
var enableDebugTracing = false;
|
|
var REACT_ELEMENT_TYPE = Symbol.for("react.element");
|
|
var REACT_PORTAL_TYPE = Symbol.for("react.portal");
|
|
var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
|
|
var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode");
|
|
var REACT_PROFILER_TYPE = Symbol.for("react.profiler");
|
|
var REACT_PROVIDER_TYPE = Symbol.for("react.provider");
|
|
var REACT_CONTEXT_TYPE = Symbol.for("react.context");
|
|
var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref");
|
|
var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense");
|
|
var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list");
|
|
var REACT_MEMO_TYPE = Symbol.for("react.memo");
|
|
var REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen");
|
|
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
|
|
var FAUX_ITERATOR_SYMBOL = "@@iterator";
|
|
function getIteratorFn(maybeIterable) {
|
|
if (maybeIterable === null || typeof maybeIterable !== "object") {
|
|
return null;
|
|
}
|
|
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
|
if (typeof maybeIterator === "function") {
|
|
return maybeIterator;
|
|
}
|
|
return null;
|
|
}
|
|
var ReactCurrentDispatcher = {
|
|
current: null
|
|
};
|
|
var ReactCurrentBatchConfig = {
|
|
transition: null
|
|
};
|
|
var ReactCurrentActQueue = {
|
|
current: null,
|
|
isBatchingLegacy: false,
|
|
didScheduleLegacyUpdate: false
|
|
};
|
|
var ReactCurrentOwner = {
|
|
current: null
|
|
};
|
|
var ReactDebugCurrentFrame = {};
|
|
var currentExtraStackFrame = null;
|
|
function setExtraStackFrame(stack) {
|
|
{
|
|
currentExtraStackFrame = stack;
|
|
}
|
|
}
|
|
{
|
|
ReactDebugCurrentFrame.setExtraStackFrame = function(stack) {
|
|
{
|
|
currentExtraStackFrame = stack;
|
|
}
|
|
};
|
|
ReactDebugCurrentFrame.getCurrentStack = null;
|
|
ReactDebugCurrentFrame.getStackAddendum = function() {
|
|
var stack = "";
|
|
if (currentExtraStackFrame) {
|
|
stack += currentExtraStackFrame;
|
|
}
|
|
var impl = ReactDebugCurrentFrame.getCurrentStack;
|
|
if (impl) {
|
|
stack += impl() || "";
|
|
}
|
|
return stack;
|
|
};
|
|
}
|
|
var ReactSharedInternals = {
|
|
ReactCurrentDispatcher,
|
|
ReactCurrentBatchConfig,
|
|
ReactCurrentOwner
|
|
};
|
|
{
|
|
ReactSharedInternals.ReactDebugCurrentFrame = ReactDebugCurrentFrame;
|
|
ReactSharedInternals.ReactCurrentActQueue = ReactCurrentActQueue;
|
|
}
|
|
function warn(format) {
|
|
{
|
|
{
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
args[_key - 1] = arguments[_key];
|
|
}
|
|
printWarning("warn", format, args);
|
|
}
|
|
}
|
|
}
|
|
function error(format) {
|
|
{
|
|
{
|
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
args[_key2 - 1] = arguments[_key2];
|
|
}
|
|
printWarning("error", format, args);
|
|
}
|
|
}
|
|
}
|
|
function printWarning(level, format, args) {
|
|
{
|
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
if (stack !== "") {
|
|
format += "%s";
|
|
args = args.concat([stack]);
|
|
}
|
|
var argsWithFormat = args.map(function(item) {
|
|
return String(item);
|
|
});
|
|
argsWithFormat.unshift("Warning: " + format);
|
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
}
|
|
}
|
|
var didWarnStateUpdateForUnmountedComponent = {};
|
|
function warnNoop(publicInstance, callerName) {
|
|
{
|
|
var _constructor = publicInstance.constructor;
|
|
var componentName = _constructor && (_constructor.displayName || _constructor.name) || "ReactClass";
|
|
var warningKey = componentName + "." + callerName;
|
|
if (didWarnStateUpdateForUnmountedComponent[warningKey]) {
|
|
return;
|
|
}
|
|
error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.", callerName, componentName);
|
|
didWarnStateUpdateForUnmountedComponent[warningKey] = true;
|
|
}
|
|
}
|
|
var ReactNoopUpdateQueue = {
|
|
isMounted: function(publicInstance) {
|
|
return false;
|
|
},
|
|
enqueueForceUpdate: function(publicInstance, callback, callerName) {
|
|
warnNoop(publicInstance, "forceUpdate");
|
|
},
|
|
enqueueReplaceState: function(publicInstance, completeState, callback, callerName) {
|
|
warnNoop(publicInstance, "replaceState");
|
|
},
|
|
enqueueSetState: function(publicInstance, partialState, callback, callerName) {
|
|
warnNoop(publicInstance, "setState");
|
|
}
|
|
};
|
|
var assign = Object.assign;
|
|
var emptyObject = {};
|
|
{
|
|
Object.freeze(emptyObject);
|
|
}
|
|
function Component(props, context, updater) {
|
|
this.props = props;
|
|
this.context = context;
|
|
this.refs = emptyObject;
|
|
this.updater = updater || ReactNoopUpdateQueue;
|
|
}
|
|
Component.prototype.isReactComponent = {};
|
|
Component.prototype.setState = function(partialState, callback) {
|
|
if (typeof partialState !== "object" && typeof partialState !== "function" && partialState != null) {
|
|
throw new Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
|
|
}
|
|
this.updater.enqueueSetState(this, partialState, callback, "setState");
|
|
};
|
|
Component.prototype.forceUpdate = function(callback) {
|
|
this.updater.enqueueForceUpdate(this, callback, "forceUpdate");
|
|
};
|
|
{
|
|
var deprecatedAPIs = {
|
|
isMounted: ["isMounted", "Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],
|
|
replaceState: ["replaceState", "Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]
|
|
};
|
|
var defineDeprecationWarning = function(methodName, info) {
|
|
Object.defineProperty(Component.prototype, methodName, {
|
|
get: function() {
|
|
warn("%s(...) is deprecated in plain JavaScript React classes. %s", info[0], info[1]);
|
|
return void 0;
|
|
}
|
|
});
|
|
};
|
|
for (var fnName in deprecatedAPIs) {
|
|
if (deprecatedAPIs.hasOwnProperty(fnName)) {
|
|
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
|
|
}
|
|
}
|
|
}
|
|
function ComponentDummy() {
|
|
}
|
|
ComponentDummy.prototype = Component.prototype;
|
|
function PureComponent(props, context, updater) {
|
|
this.props = props;
|
|
this.context = context;
|
|
this.refs = emptyObject;
|
|
this.updater = updater || ReactNoopUpdateQueue;
|
|
}
|
|
var pureComponentPrototype = PureComponent.prototype = new ComponentDummy();
|
|
pureComponentPrototype.constructor = PureComponent;
|
|
assign(pureComponentPrototype, Component.prototype);
|
|
pureComponentPrototype.isPureReactComponent = true;
|
|
function createRef() {
|
|
var refObject = {
|
|
current: null
|
|
};
|
|
{
|
|
Object.seal(refObject);
|
|
}
|
|
return refObject;
|
|
}
|
|
var isArrayImpl = Array.isArray;
|
|
function isArray(a) {
|
|
return isArrayImpl(a);
|
|
}
|
|
function typeName(value) {
|
|
{
|
|
var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag;
|
|
var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
|
|
return type;
|
|
}
|
|
}
|
|
function willCoercionThrow(value) {
|
|
{
|
|
try {
|
|
testStringCoercion(value);
|
|
return false;
|
|
} catch (e) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
function testStringCoercion(value) {
|
|
return "" + value;
|
|
}
|
|
function checkKeyStringCoercion(value) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
function getWrappedName(outerType, innerType, wrapperName) {
|
|
var displayName = outerType.displayName;
|
|
if (displayName) {
|
|
return displayName;
|
|
}
|
|
var functionName = innerType.displayName || innerType.name || "";
|
|
return functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName;
|
|
}
|
|
function getContextName(type) {
|
|
return type.displayName || "Context";
|
|
}
|
|
function getComponentNameFromType(type) {
|
|
if (type == null) {
|
|
return null;
|
|
}
|
|
{
|
|
if (typeof type.tag === "number") {
|
|
error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
if (typeof type === "function") {
|
|
return type.displayName || type.name || null;
|
|
}
|
|
if (typeof type === "string") {
|
|
return type;
|
|
}
|
|
switch (type) {
|
|
case REACT_FRAGMENT_TYPE:
|
|
return "Fragment";
|
|
case REACT_PORTAL_TYPE:
|
|
return "Portal";
|
|
case REACT_PROFILER_TYPE:
|
|
return "Profiler";
|
|
case REACT_STRICT_MODE_TYPE:
|
|
return "StrictMode";
|
|
case REACT_SUSPENSE_TYPE:
|
|
return "Suspense";
|
|
case REACT_SUSPENSE_LIST_TYPE:
|
|
return "SuspenseList";
|
|
}
|
|
if (typeof type === "object") {
|
|
switch (type.$$typeof) {
|
|
case REACT_CONTEXT_TYPE:
|
|
var context = type;
|
|
return getContextName(context) + ".Consumer";
|
|
case REACT_PROVIDER_TYPE:
|
|
var provider = type;
|
|
return getContextName(provider._context) + ".Provider";
|
|
case REACT_FORWARD_REF_TYPE:
|
|
return getWrappedName(type, type.render, "ForwardRef");
|
|
case REACT_MEMO_TYPE:
|
|
var outerName = type.displayName || null;
|
|
if (outerName !== null) {
|
|
return outerName;
|
|
}
|
|
return getComponentNameFromType(type.type) || "Memo";
|
|
case REACT_LAZY_TYPE: {
|
|
var lazyComponent = type;
|
|
var payload = lazyComponent._payload;
|
|
var init = lazyComponent._init;
|
|
try {
|
|
return getComponentNameFromType(init(payload));
|
|
} catch (x) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
var RESERVED_PROPS = {
|
|
key: true,
|
|
ref: true,
|
|
__self: true,
|
|
__source: true
|
|
};
|
|
var specialPropKeyWarningShown, specialPropRefWarningShown, didWarnAboutStringRefs;
|
|
{
|
|
didWarnAboutStringRefs = {};
|
|
}
|
|
function hasValidRef(config) {
|
|
{
|
|
if (hasOwnProperty.call(config, "ref")) {
|
|
var getter = Object.getOwnPropertyDescriptor(config, "ref").get;
|
|
if (getter && getter.isReactWarning) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return config.ref !== void 0;
|
|
}
|
|
function hasValidKey(config) {
|
|
{
|
|
if (hasOwnProperty.call(config, "key")) {
|
|
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
|
|
if (getter && getter.isReactWarning) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return config.key !== void 0;
|
|
}
|
|
function defineKeyPropWarningGetter(props, displayName) {
|
|
var warnAboutAccessingKey = function() {
|
|
{
|
|
if (!specialPropKeyWarningShown) {
|
|
specialPropKeyWarningShown = true;
|
|
error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", displayName);
|
|
}
|
|
}
|
|
};
|
|
warnAboutAccessingKey.isReactWarning = true;
|
|
Object.defineProperty(props, "key", {
|
|
get: warnAboutAccessingKey,
|
|
configurable: true
|
|
});
|
|
}
|
|
function defineRefPropWarningGetter(props, displayName) {
|
|
var warnAboutAccessingRef = function() {
|
|
{
|
|
if (!specialPropRefWarningShown) {
|
|
specialPropRefWarningShown = true;
|
|
error("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", displayName);
|
|
}
|
|
}
|
|
};
|
|
warnAboutAccessingRef.isReactWarning = true;
|
|
Object.defineProperty(props, "ref", {
|
|
get: warnAboutAccessingRef,
|
|
configurable: true
|
|
});
|
|
}
|
|
function warnIfStringRefCannotBeAutoConverted(config) {
|
|
{
|
|
if (typeof config.ref === "string" && ReactCurrentOwner.current && config.__self && ReactCurrentOwner.current.stateNode !== config.__self) {
|
|
var componentName = getComponentNameFromType(ReactCurrentOwner.current.type);
|
|
if (!didWarnAboutStringRefs[componentName]) {
|
|
error('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', componentName, config.ref);
|
|
didWarnAboutStringRefs[componentName] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var ReactElement = function(type, key, ref, self, source, owner, props) {
|
|
var element = {
|
|
$$typeof: REACT_ELEMENT_TYPE,
|
|
type,
|
|
key,
|
|
ref,
|
|
props,
|
|
_owner: owner
|
|
};
|
|
{
|
|
element._store = {};
|
|
Object.defineProperty(element._store, "validated", {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: true,
|
|
value: false
|
|
});
|
|
Object.defineProperty(element, "_self", {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: false,
|
|
value: self
|
|
});
|
|
Object.defineProperty(element, "_source", {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: false,
|
|
value: source
|
|
});
|
|
if (Object.freeze) {
|
|
Object.freeze(element.props);
|
|
Object.freeze(element);
|
|
}
|
|
}
|
|
return element;
|
|
};
|
|
function createElement3(type, config, children) {
|
|
var propName;
|
|
var props = {};
|
|
var key = null;
|
|
var ref = null;
|
|
var self = null;
|
|
var source = null;
|
|
if (config != null) {
|
|
if (hasValidRef(config)) {
|
|
ref = config.ref;
|
|
{
|
|
warnIfStringRefCannotBeAutoConverted(config);
|
|
}
|
|
}
|
|
if (hasValidKey(config)) {
|
|
{
|
|
checkKeyStringCoercion(config.key);
|
|
}
|
|
key = "" + config.key;
|
|
}
|
|
self = config.__self === void 0 ? null : config.__self;
|
|
source = config.__source === void 0 ? null : config.__source;
|
|
for (propName in config) {
|
|
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
|
props[propName] = config[propName];
|
|
}
|
|
}
|
|
}
|
|
var childrenLength = arguments.length - 2;
|
|
if (childrenLength === 1) {
|
|
props.children = children;
|
|
} else if (childrenLength > 1) {
|
|
var childArray = Array(childrenLength);
|
|
for (var i = 0; i < childrenLength; i++) {
|
|
childArray[i] = arguments[i + 2];
|
|
}
|
|
{
|
|
if (Object.freeze) {
|
|
Object.freeze(childArray);
|
|
}
|
|
}
|
|
props.children = childArray;
|
|
}
|
|
if (type && type.defaultProps) {
|
|
var defaultProps = type.defaultProps;
|
|
for (propName in defaultProps) {
|
|
if (props[propName] === void 0) {
|
|
props[propName] = defaultProps[propName];
|
|
}
|
|
}
|
|
}
|
|
{
|
|
if (key || ref) {
|
|
var displayName = typeof type === "function" ? type.displayName || type.name || "Unknown" : type;
|
|
if (key) {
|
|
defineKeyPropWarningGetter(props, displayName);
|
|
}
|
|
if (ref) {
|
|
defineRefPropWarningGetter(props, displayName);
|
|
}
|
|
}
|
|
}
|
|
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
|
}
|
|
function cloneAndReplaceKey(oldElement, newKey) {
|
|
var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);
|
|
return newElement;
|
|
}
|
|
function cloneElement(element, config, children) {
|
|
if (element === null || element === void 0) {
|
|
throw new Error("React.cloneElement(...): The argument must be a React element, but you passed " + element + ".");
|
|
}
|
|
var propName;
|
|
var props = assign({}, element.props);
|
|
var key = element.key;
|
|
var ref = element.ref;
|
|
var self = element._self;
|
|
var source = element._source;
|
|
var owner = element._owner;
|
|
if (config != null) {
|
|
if (hasValidRef(config)) {
|
|
ref = config.ref;
|
|
owner = ReactCurrentOwner.current;
|
|
}
|
|
if (hasValidKey(config)) {
|
|
{
|
|
checkKeyStringCoercion(config.key);
|
|
}
|
|
key = "" + config.key;
|
|
}
|
|
var defaultProps;
|
|
if (element.type && element.type.defaultProps) {
|
|
defaultProps = element.type.defaultProps;
|
|
}
|
|
for (propName in config) {
|
|
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
|
if (config[propName] === void 0 && defaultProps !== void 0) {
|
|
props[propName] = defaultProps[propName];
|
|
} else {
|
|
props[propName] = config[propName];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var childrenLength = arguments.length - 2;
|
|
if (childrenLength === 1) {
|
|
props.children = children;
|
|
} else if (childrenLength > 1) {
|
|
var childArray = Array(childrenLength);
|
|
for (var i = 0; i < childrenLength; i++) {
|
|
childArray[i] = arguments[i + 2];
|
|
}
|
|
props.children = childArray;
|
|
}
|
|
return ReactElement(element.type, key, ref, self, source, owner, props);
|
|
}
|
|
function isValidElement2(object) {
|
|
return typeof object === "object" && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
}
|
|
var SEPARATOR = ".";
|
|
var SUBSEPARATOR = ":";
|
|
function escape(key) {
|
|
var escapeRegex = /[=:]/g;
|
|
var escaperLookup = {
|
|
"=": "=0",
|
|
":": "=2"
|
|
};
|
|
var escapedString = key.replace(escapeRegex, function(match) {
|
|
return escaperLookup[match];
|
|
});
|
|
return "$" + escapedString;
|
|
}
|
|
var didWarnAboutMaps = false;
|
|
var userProvidedKeyEscapeRegex = /\/+/g;
|
|
function escapeUserProvidedKey(text) {
|
|
return text.replace(userProvidedKeyEscapeRegex, "$&/");
|
|
}
|
|
function getElementKey(element, index) {
|
|
if (typeof element === "object" && element !== null && element.key != null) {
|
|
{
|
|
checkKeyStringCoercion(element.key);
|
|
}
|
|
return escape("" + element.key);
|
|
}
|
|
return index.toString(36);
|
|
}
|
|
function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
|
|
var type = typeof children;
|
|
if (type === "undefined" || type === "boolean") {
|
|
children = null;
|
|
}
|
|
var invokeCallback = false;
|
|
if (children === null) {
|
|
invokeCallback = true;
|
|
} else {
|
|
switch (type) {
|
|
case "string":
|
|
case "number":
|
|
invokeCallback = true;
|
|
break;
|
|
case "object":
|
|
switch (children.$$typeof) {
|
|
case REACT_ELEMENT_TYPE:
|
|
case REACT_PORTAL_TYPE:
|
|
invokeCallback = true;
|
|
}
|
|
}
|
|
}
|
|
if (invokeCallback) {
|
|
var _child = children;
|
|
var mappedChild = callback(_child);
|
|
var childKey = nameSoFar === "" ? SEPARATOR + getElementKey(_child, 0) : nameSoFar;
|
|
if (isArray(mappedChild)) {
|
|
var escapedChildKey = "";
|
|
if (childKey != null) {
|
|
escapedChildKey = escapeUserProvidedKey(childKey) + "/";
|
|
}
|
|
mapIntoArray(mappedChild, array, escapedChildKey, "", function(c) {
|
|
return c;
|
|
});
|
|
} else if (mappedChild != null) {
|
|
if (isValidElement2(mappedChild)) {
|
|
{
|
|
if (mappedChild.key && (!_child || _child.key !== mappedChild.key)) {
|
|
checkKeyStringCoercion(mappedChild.key);
|
|
}
|
|
}
|
|
mappedChild = cloneAndReplaceKey(mappedChild, escapedPrefix + (mappedChild.key && (!_child || _child.key !== mappedChild.key) ? escapeUserProvidedKey("" + mappedChild.key) + "/" : "") + childKey);
|
|
}
|
|
array.push(mappedChild);
|
|
}
|
|
return 1;
|
|
}
|
|
var child;
|
|
var nextName;
|
|
var subtreeCount = 0;
|
|
var nextNamePrefix = nameSoFar === "" ? SEPARATOR : nameSoFar + SUBSEPARATOR;
|
|
if (isArray(children)) {
|
|
for (var i = 0; i < children.length; i++) {
|
|
child = children[i];
|
|
nextName = nextNamePrefix + getElementKey(child, i);
|
|
subtreeCount += mapIntoArray(child, array, escapedPrefix, nextName, callback);
|
|
}
|
|
} else {
|
|
var iteratorFn = getIteratorFn(children);
|
|
if (typeof iteratorFn === "function") {
|
|
var iterableChildren = children;
|
|
{
|
|
if (iteratorFn === iterableChildren.entries) {
|
|
if (!didWarnAboutMaps) {
|
|
warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead.");
|
|
}
|
|
didWarnAboutMaps = true;
|
|
}
|
|
}
|
|
var iterator = iteratorFn.call(iterableChildren);
|
|
var step;
|
|
var ii = 0;
|
|
while (!(step = iterator.next()).done) {
|
|
child = step.value;
|
|
nextName = nextNamePrefix + getElementKey(child, ii++);
|
|
subtreeCount += mapIntoArray(child, array, escapedPrefix, nextName, callback);
|
|
}
|
|
} else if (type === "object") {
|
|
var childrenString = String(children);
|
|
throw new Error("Objects are not valid as a React child (found: " + (childrenString === "[object Object]" ? "object with keys {" + Object.keys(children).join(", ") + "}" : childrenString) + "). If you meant to render a collection of children, use an array instead.");
|
|
}
|
|
}
|
|
return subtreeCount;
|
|
}
|
|
function mapChildren(children, func, context) {
|
|
if (children == null) {
|
|
return children;
|
|
}
|
|
var result = [];
|
|
var count = 0;
|
|
mapIntoArray(children, result, "", "", function(child) {
|
|
return func.call(context, child, count++);
|
|
});
|
|
return result;
|
|
}
|
|
function countChildren(children) {
|
|
var n = 0;
|
|
mapChildren(children, function() {
|
|
n++;
|
|
});
|
|
return n;
|
|
}
|
|
function forEachChildren(children, forEachFunc, forEachContext) {
|
|
mapChildren(children, function() {
|
|
forEachFunc.apply(this, arguments);
|
|
}, forEachContext);
|
|
}
|
|
function toArray(children) {
|
|
return mapChildren(children, function(child) {
|
|
return child;
|
|
}) || [];
|
|
}
|
|
function onlyChild(children) {
|
|
if (!isValidElement2(children)) {
|
|
throw new Error("React.Children.only expected to receive a single React element child.");
|
|
}
|
|
return children;
|
|
}
|
|
function createContext2(defaultValue) {
|
|
var context = {
|
|
$$typeof: REACT_CONTEXT_TYPE,
|
|
_currentValue: defaultValue,
|
|
_currentValue2: defaultValue,
|
|
_threadCount: 0,
|
|
Provider: null,
|
|
Consumer: null,
|
|
_defaultValue: null,
|
|
_globalName: null
|
|
};
|
|
context.Provider = {
|
|
$$typeof: REACT_PROVIDER_TYPE,
|
|
_context: context
|
|
};
|
|
var hasWarnedAboutUsingNestedContextConsumers = false;
|
|
var hasWarnedAboutUsingConsumerProvider = false;
|
|
var hasWarnedAboutDisplayNameOnConsumer = false;
|
|
{
|
|
var Consumer = {
|
|
$$typeof: REACT_CONTEXT_TYPE,
|
|
_context: context
|
|
};
|
|
Object.defineProperties(Consumer, {
|
|
Provider: {
|
|
get: function() {
|
|
if (!hasWarnedAboutUsingConsumerProvider) {
|
|
hasWarnedAboutUsingConsumerProvider = true;
|
|
error("Rendering <Context.Consumer.Provider> is not supported and will be removed in a future major release. Did you mean to render <Context.Provider> instead?");
|
|
}
|
|
return context.Provider;
|
|
},
|
|
set: function(_Provider) {
|
|
context.Provider = _Provider;
|
|
}
|
|
},
|
|
_currentValue: {
|
|
get: function() {
|
|
return context._currentValue;
|
|
},
|
|
set: function(_currentValue) {
|
|
context._currentValue = _currentValue;
|
|
}
|
|
},
|
|
_currentValue2: {
|
|
get: function() {
|
|
return context._currentValue2;
|
|
},
|
|
set: function(_currentValue2) {
|
|
context._currentValue2 = _currentValue2;
|
|
}
|
|
},
|
|
_threadCount: {
|
|
get: function() {
|
|
return context._threadCount;
|
|
},
|
|
set: function(_threadCount) {
|
|
context._threadCount = _threadCount;
|
|
}
|
|
},
|
|
Consumer: {
|
|
get: function() {
|
|
if (!hasWarnedAboutUsingNestedContextConsumers) {
|
|
hasWarnedAboutUsingNestedContextConsumers = true;
|
|
error("Rendering <Context.Consumer.Consumer> is not supported and will be removed in a future major release. Did you mean to render <Context.Consumer> instead?");
|
|
}
|
|
return context.Consumer;
|
|
}
|
|
},
|
|
displayName: {
|
|
get: function() {
|
|
return context.displayName;
|
|
},
|
|
set: function(displayName) {
|
|
if (!hasWarnedAboutDisplayNameOnConsumer) {
|
|
warn("Setting `displayName` on Context.Consumer has no effect. You should set it directly on the context with Context.displayName = '%s'.", displayName);
|
|
hasWarnedAboutDisplayNameOnConsumer = true;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
context.Consumer = Consumer;
|
|
}
|
|
{
|
|
context._currentRenderer = null;
|
|
context._currentRenderer2 = null;
|
|
}
|
|
return context;
|
|
}
|
|
var Uninitialized = -1;
|
|
var Pending = 0;
|
|
var Resolved = 1;
|
|
var Rejected = 2;
|
|
function lazyInitializer(payload) {
|
|
if (payload._status === Uninitialized) {
|
|
var ctor = payload._result;
|
|
var thenable = ctor();
|
|
thenable.then(function(moduleObject2) {
|
|
if (payload._status === Pending || payload._status === Uninitialized) {
|
|
var resolved = payload;
|
|
resolved._status = Resolved;
|
|
resolved._result = moduleObject2;
|
|
}
|
|
}, function(error2) {
|
|
if (payload._status === Pending || payload._status === Uninitialized) {
|
|
var rejected = payload;
|
|
rejected._status = Rejected;
|
|
rejected._result = error2;
|
|
}
|
|
});
|
|
if (payload._status === Uninitialized) {
|
|
var pending = payload;
|
|
pending._status = Pending;
|
|
pending._result = thenable;
|
|
}
|
|
}
|
|
if (payload._status === Resolved) {
|
|
var moduleObject = payload._result;
|
|
{
|
|
if (moduleObject === void 0) {
|
|
error("lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))\n\nDid you accidentally put curly braces around the import?", moduleObject);
|
|
}
|
|
}
|
|
{
|
|
if (!("default" in moduleObject)) {
|
|
error("lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
|
|
}
|
|
}
|
|
return moduleObject.default;
|
|
} else {
|
|
throw payload._result;
|
|
}
|
|
}
|
|
function lazy(ctor) {
|
|
var payload = {
|
|
_status: Uninitialized,
|
|
_result: ctor
|
|
};
|
|
var lazyType = {
|
|
$$typeof: REACT_LAZY_TYPE,
|
|
_payload: payload,
|
|
_init: lazyInitializer
|
|
};
|
|
{
|
|
var defaultProps;
|
|
var propTypes;
|
|
Object.defineProperties(lazyType, {
|
|
defaultProps: {
|
|
configurable: true,
|
|
get: function() {
|
|
return defaultProps;
|
|
},
|
|
set: function(newDefaultProps) {
|
|
error("React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it.");
|
|
defaultProps = newDefaultProps;
|
|
Object.defineProperty(lazyType, "defaultProps", {
|
|
enumerable: true
|
|
});
|
|
}
|
|
},
|
|
propTypes: {
|
|
configurable: true,
|
|
get: function() {
|
|
return propTypes;
|
|
},
|
|
set: function(newPropTypes) {
|
|
error("React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it.");
|
|
propTypes = newPropTypes;
|
|
Object.defineProperty(lazyType, "propTypes", {
|
|
enumerable: true
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return lazyType;
|
|
}
|
|
function forwardRef2(render) {
|
|
{
|
|
if (render != null && render.$$typeof === REACT_MEMO_TYPE) {
|
|
error("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...)).");
|
|
} else if (typeof render !== "function") {
|
|
error("forwardRef requires a render function but was given %s.", render === null ? "null" : typeof render);
|
|
} else {
|
|
if (render.length !== 0 && render.length !== 2) {
|
|
error("forwardRef render functions accept exactly two parameters: props and ref. %s", render.length === 1 ? "Did you forget to use the ref parameter?" : "Any additional parameter will be undefined.");
|
|
}
|
|
}
|
|
if (render != null) {
|
|
if (render.defaultProps != null || render.propTypes != null) {
|
|
error("forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?");
|
|
}
|
|
}
|
|
}
|
|
var elementType = {
|
|
$$typeof: REACT_FORWARD_REF_TYPE,
|
|
render
|
|
};
|
|
{
|
|
var ownName;
|
|
Object.defineProperty(elementType, "displayName", {
|
|
enumerable: false,
|
|
configurable: true,
|
|
get: function() {
|
|
return ownName;
|
|
},
|
|
set: function(name) {
|
|
ownName = name;
|
|
if (!render.name && !render.displayName) {
|
|
render.displayName = name;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return elementType;
|
|
}
|
|
var REACT_MODULE_REFERENCE;
|
|
{
|
|
REACT_MODULE_REFERENCE = Symbol.for("react.module.reference");
|
|
}
|
|
function isValidElementType(type) {
|
|
if (typeof type === "string" || typeof type === "function") {
|
|
return true;
|
|
}
|
|
if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing) {
|
|
return true;
|
|
}
|
|
if (typeof type === "object" && type !== null) {
|
|
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== void 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function memo(type, compare) {
|
|
{
|
|
if (!isValidElementType(type)) {
|
|
error("memo: The first argument must be a component. Instead received: %s", type === null ? "null" : typeof type);
|
|
}
|
|
}
|
|
var elementType = {
|
|
$$typeof: REACT_MEMO_TYPE,
|
|
type,
|
|
compare: compare === void 0 ? null : compare
|
|
};
|
|
{
|
|
var ownName;
|
|
Object.defineProperty(elementType, "displayName", {
|
|
enumerable: false,
|
|
configurable: true,
|
|
get: function() {
|
|
return ownName;
|
|
},
|
|
set: function(name) {
|
|
ownName = name;
|
|
if (!type.name && !type.displayName) {
|
|
type.displayName = name;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return elementType;
|
|
}
|
|
function resolveDispatcher() {
|
|
var dispatcher = ReactCurrentDispatcher.current;
|
|
{
|
|
if (dispatcher === null) {
|
|
error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.");
|
|
}
|
|
}
|
|
return dispatcher;
|
|
}
|
|
function useContext2(Context) {
|
|
var dispatcher = resolveDispatcher();
|
|
{
|
|
if (Context._context !== void 0) {
|
|
var realContext = Context._context;
|
|
if (realContext.Consumer === Context) {
|
|
error("Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?");
|
|
} else if (realContext.Provider === Context) {
|
|
error("Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?");
|
|
}
|
|
}
|
|
}
|
|
return dispatcher.useContext(Context);
|
|
}
|
|
function useState5(initialState) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useState(initialState);
|
|
}
|
|
function useReducer(reducer, initialArg, init) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useReducer(reducer, initialArg, init);
|
|
}
|
|
function useRef3(initialValue) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useRef(initialValue);
|
|
}
|
|
function useEffect4(create, deps) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useEffect(create, deps);
|
|
}
|
|
function useInsertionEffect(create, deps) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useInsertionEffect(create, deps);
|
|
}
|
|
function useLayoutEffect3(create, deps) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useLayoutEffect(create, deps);
|
|
}
|
|
function useCallback3(callback, deps) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useCallback(callback, deps);
|
|
}
|
|
function useMemo3(create, deps) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useMemo(create, deps);
|
|
}
|
|
function useImperativeHandle(ref, create, deps) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useImperativeHandle(ref, create, deps);
|
|
}
|
|
function useDebugValue(value, formatterFn) {
|
|
{
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useDebugValue(value, formatterFn);
|
|
}
|
|
}
|
|
function useTransition() {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useTransition();
|
|
}
|
|
function useDeferredValue(value) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useDeferredValue(value);
|
|
}
|
|
function useId() {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useId();
|
|
}
|
|
function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
|
|
var dispatcher = resolveDispatcher();
|
|
return dispatcher.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
}
|
|
var disabledDepth = 0;
|
|
var prevLog;
|
|
var prevInfo;
|
|
var prevWarn;
|
|
var prevError;
|
|
var prevGroup;
|
|
var prevGroupCollapsed;
|
|
var prevGroupEnd;
|
|
function disabledLog() {
|
|
}
|
|
disabledLog.__reactDisabledLog = true;
|
|
function disableLogs() {
|
|
{
|
|
if (disabledDepth === 0) {
|
|
prevLog = console.log;
|
|
prevInfo = console.info;
|
|
prevWarn = console.warn;
|
|
prevError = console.error;
|
|
prevGroup = console.group;
|
|
prevGroupCollapsed = console.groupCollapsed;
|
|
prevGroupEnd = console.groupEnd;
|
|
var props = {
|
|
configurable: true,
|
|
enumerable: true,
|
|
value: disabledLog,
|
|
writable: true
|
|
};
|
|
Object.defineProperties(console, {
|
|
info: props,
|
|
log: props,
|
|
warn: props,
|
|
error: props,
|
|
group: props,
|
|
groupCollapsed: props,
|
|
groupEnd: props
|
|
});
|
|
}
|
|
disabledDepth++;
|
|
}
|
|
}
|
|
function reenableLogs() {
|
|
{
|
|
disabledDepth--;
|
|
if (disabledDepth === 0) {
|
|
var props = {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true
|
|
};
|
|
Object.defineProperties(console, {
|
|
log: assign({}, props, {
|
|
value: prevLog
|
|
}),
|
|
info: assign({}, props, {
|
|
value: prevInfo
|
|
}),
|
|
warn: assign({}, props, {
|
|
value: prevWarn
|
|
}),
|
|
error: assign({}, props, {
|
|
value: prevError
|
|
}),
|
|
group: assign({}, props, {
|
|
value: prevGroup
|
|
}),
|
|
groupCollapsed: assign({}, props, {
|
|
value: prevGroupCollapsed
|
|
}),
|
|
groupEnd: assign({}, props, {
|
|
value: prevGroupEnd
|
|
})
|
|
});
|
|
}
|
|
if (disabledDepth < 0) {
|
|
error("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
}
|
|
var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
|
|
var prefix;
|
|
function describeBuiltInComponentFrame(name, source, ownerFn) {
|
|
{
|
|
if (prefix === void 0) {
|
|
try {
|
|
throw Error();
|
|
} catch (x) {
|
|
var match = x.stack.trim().match(/\n( *(at )?)/);
|
|
prefix = match && match[1] || "";
|
|
}
|
|
}
|
|
return "\n" + prefix + name;
|
|
}
|
|
}
|
|
var reentry = false;
|
|
var componentFrameCache;
|
|
{
|
|
var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map;
|
|
componentFrameCache = new PossiblyWeakMap();
|
|
}
|
|
function describeNativeComponentFrame(fn, construct) {
|
|
if (!fn || reentry) {
|
|
return "";
|
|
}
|
|
{
|
|
var frame = componentFrameCache.get(fn);
|
|
if (frame !== void 0) {
|
|
return frame;
|
|
}
|
|
}
|
|
var control;
|
|
reentry = true;
|
|
var previousPrepareStackTrace = Error.prepareStackTrace;
|
|
Error.prepareStackTrace = void 0;
|
|
var previousDispatcher;
|
|
{
|
|
previousDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = null;
|
|
disableLogs();
|
|
}
|
|
try {
|
|
if (construct) {
|
|
var Fake = function() {
|
|
throw Error();
|
|
};
|
|
Object.defineProperty(Fake.prototype, "props", {
|
|
set: function() {
|
|
throw Error();
|
|
}
|
|
});
|
|
if (typeof Reflect === "object" && Reflect.construct) {
|
|
try {
|
|
Reflect.construct(Fake, []);
|
|
} catch (x) {
|
|
control = x;
|
|
}
|
|
Reflect.construct(fn, [], Fake);
|
|
} else {
|
|
try {
|
|
Fake.call();
|
|
} catch (x) {
|
|
control = x;
|
|
}
|
|
fn.call(Fake.prototype);
|
|
}
|
|
} else {
|
|
try {
|
|
throw Error();
|
|
} catch (x) {
|
|
control = x;
|
|
}
|
|
fn();
|
|
}
|
|
} catch (sample) {
|
|
if (sample && control && typeof sample.stack === "string") {
|
|
var sampleLines = sample.stack.split("\n");
|
|
var controlLines = control.stack.split("\n");
|
|
var s = sampleLines.length - 1;
|
|
var c = controlLines.length - 1;
|
|
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
|
|
c--;
|
|
}
|
|
for (; s >= 1 && c >= 0; s--, c--) {
|
|
if (sampleLines[s] !== controlLines[c]) {
|
|
if (s !== 1 || c !== 1) {
|
|
do {
|
|
s--;
|
|
c--;
|
|
if (c < 0 || sampleLines[s] !== controlLines[c]) {
|
|
var _frame = "\n" + sampleLines[s].replace(" at new ", " at ");
|
|
if (fn.displayName && _frame.includes("<anonymous>")) {
|
|
_frame = _frame.replace("<anonymous>", fn.displayName);
|
|
}
|
|
{
|
|
if (typeof fn === "function") {
|
|
componentFrameCache.set(fn, _frame);
|
|
}
|
|
}
|
|
return _frame;
|
|
}
|
|
} while (s >= 1 && c >= 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
reentry = false;
|
|
{
|
|
ReactCurrentDispatcher$1.current = previousDispatcher;
|
|
reenableLogs();
|
|
}
|
|
Error.prepareStackTrace = previousPrepareStackTrace;
|
|
}
|
|
var name = fn ? fn.displayName || fn.name : "";
|
|
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
|
|
{
|
|
if (typeof fn === "function") {
|
|
componentFrameCache.set(fn, syntheticFrame);
|
|
}
|
|
}
|
|
return syntheticFrame;
|
|
}
|
|
function describeFunctionComponentFrame(fn, source, ownerFn) {
|
|
{
|
|
return describeNativeComponentFrame(fn, false);
|
|
}
|
|
}
|
|
function shouldConstruct(Component2) {
|
|
var prototype = Component2.prototype;
|
|
return !!(prototype && prototype.isReactComponent);
|
|
}
|
|
function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
|
|
if (type == null) {
|
|
return "";
|
|
}
|
|
if (typeof type === "function") {
|
|
{
|
|
return describeNativeComponentFrame(type, shouldConstruct(type));
|
|
}
|
|
}
|
|
if (typeof type === "string") {
|
|
return describeBuiltInComponentFrame(type);
|
|
}
|
|
switch (type) {
|
|
case REACT_SUSPENSE_TYPE:
|
|
return describeBuiltInComponentFrame("Suspense");
|
|
case REACT_SUSPENSE_LIST_TYPE:
|
|
return describeBuiltInComponentFrame("SuspenseList");
|
|
}
|
|
if (typeof type === "object") {
|
|
switch (type.$$typeof) {
|
|
case REACT_FORWARD_REF_TYPE:
|
|
return describeFunctionComponentFrame(type.render);
|
|
case REACT_MEMO_TYPE:
|
|
return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
|
|
case REACT_LAZY_TYPE: {
|
|
var lazyComponent = type;
|
|
var payload = lazyComponent._payload;
|
|
var init = lazyComponent._init;
|
|
try {
|
|
return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
|
|
} catch (x) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
var loggedTypeFailures = {};
|
|
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
function setCurrentlyValidatingElement(element) {
|
|
{
|
|
if (element) {
|
|
var owner = element._owner;
|
|
var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
|
|
ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
|
|
} else {
|
|
ReactDebugCurrentFrame$1.setExtraStackFrame(null);
|
|
}
|
|
}
|
|
}
|
|
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
|
{
|
|
var has = Function.call.bind(hasOwnProperty);
|
|
for (var typeSpecName in typeSpecs) {
|
|
if (has(typeSpecs, typeSpecName)) {
|
|
var error$1 = void 0;
|
|
try {
|
|
if (typeof typeSpecs[typeSpecName] !== "function") {
|
|
var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
|
|
err.name = "Invariant Violation";
|
|
throw err;
|
|
}
|
|
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
|
|
} catch (ex) {
|
|
error$1 = ex;
|
|
}
|
|
if (error$1 && !(error$1 instanceof Error)) {
|
|
setCurrentlyValidatingElement(element);
|
|
error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1);
|
|
setCurrentlyValidatingElement(null);
|
|
}
|
|
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
|
loggedTypeFailures[error$1.message] = true;
|
|
setCurrentlyValidatingElement(element);
|
|
error("Failed %s type: %s", location, error$1.message);
|
|
setCurrentlyValidatingElement(null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function setCurrentlyValidatingElement$1(element) {
|
|
{
|
|
if (element) {
|
|
var owner = element._owner;
|
|
var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
|
|
setExtraStackFrame(stack);
|
|
} else {
|
|
setExtraStackFrame(null);
|
|
}
|
|
}
|
|
}
|
|
var propTypesMisspellWarningShown;
|
|
{
|
|
propTypesMisspellWarningShown = false;
|
|
}
|
|
function getDeclarationErrorAddendum() {
|
|
if (ReactCurrentOwner.current) {
|
|
var name = getComponentNameFromType(ReactCurrentOwner.current.type);
|
|
if (name) {
|
|
return "\n\nCheck the render method of `" + name + "`.";
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
function getSourceInfoErrorAddendum(source) {
|
|
if (source !== void 0) {
|
|
var fileName = source.fileName.replace(/^.*[\\\/]/, "");
|
|
var lineNumber = source.lineNumber;
|
|
return "\n\nCheck your code at " + fileName + ":" + lineNumber + ".";
|
|
}
|
|
return "";
|
|
}
|
|
function getSourceInfoErrorAddendumForProps(elementProps) {
|
|
if (elementProps !== null && elementProps !== void 0) {
|
|
return getSourceInfoErrorAddendum(elementProps.__source);
|
|
}
|
|
return "";
|
|
}
|
|
var ownerHasKeyUseWarning = {};
|
|
function getCurrentComponentErrorInfo(parentType) {
|
|
var info = getDeclarationErrorAddendum();
|
|
if (!info) {
|
|
var parentName = typeof parentType === "string" ? parentType : parentType.displayName || parentType.name;
|
|
if (parentName) {
|
|
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
|
}
|
|
}
|
|
return info;
|
|
}
|
|
function validateExplicitKey(element, parentType) {
|
|
if (!element._store || element._store.validated || element.key != null) {
|
|
return;
|
|
}
|
|
element._store.validated = true;
|
|
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
|
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
|
return;
|
|
}
|
|
ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
|
|
var childOwner = "";
|
|
if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
|
|
childOwner = " It was passed a child from " + getComponentNameFromType(element._owner.type) + ".";
|
|
}
|
|
{
|
|
setCurrentlyValidatingElement$1(element);
|
|
error('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
|
setCurrentlyValidatingElement$1(null);
|
|
}
|
|
}
|
|
function validateChildKeys(node, parentType) {
|
|
if (typeof node !== "object") {
|
|
return;
|
|
}
|
|
if (isArray(node)) {
|
|
for (var i = 0; i < node.length; i++) {
|
|
var child = node[i];
|
|
if (isValidElement2(child)) {
|
|
validateExplicitKey(child, parentType);
|
|
}
|
|
}
|
|
} else if (isValidElement2(node)) {
|
|
if (node._store) {
|
|
node._store.validated = true;
|
|
}
|
|
} else if (node) {
|
|
var iteratorFn = getIteratorFn(node);
|
|
if (typeof iteratorFn === "function") {
|
|
if (iteratorFn !== node.entries) {
|
|
var iterator = iteratorFn.call(node);
|
|
var step;
|
|
while (!(step = iterator.next()).done) {
|
|
if (isValidElement2(step.value)) {
|
|
validateExplicitKey(step.value, parentType);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function validatePropTypes(element) {
|
|
{
|
|
var type = element.type;
|
|
if (type === null || type === void 0 || typeof type === "string") {
|
|
return;
|
|
}
|
|
var propTypes;
|
|
if (typeof type === "function") {
|
|
propTypes = type.propTypes;
|
|
} else if (typeof type === "object" && (type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_MEMO_TYPE)) {
|
|
propTypes = type.propTypes;
|
|
} else {
|
|
return;
|
|
}
|
|
if (propTypes) {
|
|
var name = getComponentNameFromType(type);
|
|
checkPropTypes(propTypes, element.props, "prop", name, element);
|
|
} else if (type.PropTypes !== void 0 && !propTypesMisspellWarningShown) {
|
|
propTypesMisspellWarningShown = true;
|
|
var _name = getComponentNameFromType(type);
|
|
error("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", _name || "Unknown");
|
|
}
|
|
if (typeof type.getDefaultProps === "function" && !type.getDefaultProps.isReactClassApproved) {
|
|
error("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
|
|
}
|
|
}
|
|
}
|
|
function validateFragmentProps(fragment) {
|
|
{
|
|
var keys = Object.keys(fragment.props);
|
|
for (var i = 0; i < keys.length; i++) {
|
|
var key = keys[i];
|
|
if (key !== "children" && key !== "key") {
|
|
setCurrentlyValidatingElement$1(fragment);
|
|
error("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", key);
|
|
setCurrentlyValidatingElement$1(null);
|
|
break;
|
|
}
|
|
}
|
|
if (fragment.ref !== null) {
|
|
setCurrentlyValidatingElement$1(fragment);
|
|
error("Invalid attribute `ref` supplied to `React.Fragment`.");
|
|
setCurrentlyValidatingElement$1(null);
|
|
}
|
|
}
|
|
}
|
|
function createElementWithValidation(type, props, children) {
|
|
var validType = isValidElementType(type);
|
|
if (!validType) {
|
|
var info = "";
|
|
if (type === void 0 || typeof type === "object" && type !== null && Object.keys(type).length === 0) {
|
|
info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.";
|
|
}
|
|
var sourceInfo = getSourceInfoErrorAddendumForProps(props);
|
|
if (sourceInfo) {
|
|
info += sourceInfo;
|
|
} else {
|
|
info += getDeclarationErrorAddendum();
|
|
}
|
|
var typeString;
|
|
if (type === null) {
|
|
typeString = "null";
|
|
} else if (isArray(type)) {
|
|
typeString = "array";
|
|
} else if (type !== void 0 && type.$$typeof === REACT_ELEMENT_TYPE) {
|
|
typeString = "<" + (getComponentNameFromType(type.type) || "Unknown") + " />";
|
|
info = " Did you accidentally export a JSX literal instead of a component?";
|
|
} else {
|
|
typeString = typeof type;
|
|
}
|
|
{
|
|
error("React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", typeString, info);
|
|
}
|
|
}
|
|
var element = createElement3.apply(this, arguments);
|
|
if (element == null) {
|
|
return element;
|
|
}
|
|
if (validType) {
|
|
for (var i = 2; i < arguments.length; i++) {
|
|
validateChildKeys(arguments[i], type);
|
|
}
|
|
}
|
|
if (type === REACT_FRAGMENT_TYPE) {
|
|
validateFragmentProps(element);
|
|
} else {
|
|
validatePropTypes(element);
|
|
}
|
|
return element;
|
|
}
|
|
var didWarnAboutDeprecatedCreateFactory = false;
|
|
function createFactoryWithValidation(type) {
|
|
var validatedFactory = createElementWithValidation.bind(null, type);
|
|
validatedFactory.type = type;
|
|
{
|
|
if (!didWarnAboutDeprecatedCreateFactory) {
|
|
didWarnAboutDeprecatedCreateFactory = true;
|
|
warn("React.createFactory() is deprecated and will be removed in a future major release. Consider using JSX or use React.createElement() directly instead.");
|
|
}
|
|
Object.defineProperty(validatedFactory, "type", {
|
|
enumerable: false,
|
|
get: function() {
|
|
warn("Factory.type is deprecated. Access the class directly before passing it to createFactory.");
|
|
Object.defineProperty(this, "type", {
|
|
value: type
|
|
});
|
|
return type;
|
|
}
|
|
});
|
|
}
|
|
return validatedFactory;
|
|
}
|
|
function cloneElementWithValidation(element, props, children) {
|
|
var newElement = cloneElement.apply(this, arguments);
|
|
for (var i = 2; i < arguments.length; i++) {
|
|
validateChildKeys(arguments[i], newElement.type);
|
|
}
|
|
validatePropTypes(newElement);
|
|
return newElement;
|
|
}
|
|
function startTransition(scope, options) {
|
|
var prevTransition = ReactCurrentBatchConfig.transition;
|
|
ReactCurrentBatchConfig.transition = {};
|
|
var currentTransition = ReactCurrentBatchConfig.transition;
|
|
{
|
|
ReactCurrentBatchConfig.transition._updatedFibers = /* @__PURE__ */ new Set();
|
|
}
|
|
try {
|
|
scope();
|
|
} finally {
|
|
ReactCurrentBatchConfig.transition = prevTransition;
|
|
{
|
|
if (prevTransition === null && currentTransition._updatedFibers) {
|
|
var updatedFibersCount = currentTransition._updatedFibers.size;
|
|
if (updatedFibersCount > 10) {
|
|
warn("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.");
|
|
}
|
|
currentTransition._updatedFibers.clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var didWarnAboutMessageChannel = false;
|
|
var enqueueTaskImpl = null;
|
|
function enqueueTask(task) {
|
|
if (enqueueTaskImpl === null) {
|
|
try {
|
|
var requireString = ("require" + Math.random()).slice(0, 7);
|
|
var nodeRequire = module && module[requireString];
|
|
enqueueTaskImpl = nodeRequire.call(module, "timers").setImmediate;
|
|
} catch (_err) {
|
|
enqueueTaskImpl = function(callback) {
|
|
{
|
|
if (didWarnAboutMessageChannel === false) {
|
|
didWarnAboutMessageChannel = true;
|
|
if (typeof MessageChannel === "undefined") {
|
|
error("This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning.");
|
|
}
|
|
}
|
|
}
|
|
var channel = new MessageChannel();
|
|
channel.port1.onmessage = callback;
|
|
channel.port2.postMessage(void 0);
|
|
};
|
|
}
|
|
}
|
|
return enqueueTaskImpl(task);
|
|
}
|
|
var actScopeDepth = 0;
|
|
var didWarnNoAwaitAct = false;
|
|
function act(callback) {
|
|
{
|
|
var prevActScopeDepth = actScopeDepth;
|
|
actScopeDepth++;
|
|
if (ReactCurrentActQueue.current === null) {
|
|
ReactCurrentActQueue.current = [];
|
|
}
|
|
var prevIsBatchingLegacy = ReactCurrentActQueue.isBatchingLegacy;
|
|
var result;
|
|
try {
|
|
ReactCurrentActQueue.isBatchingLegacy = true;
|
|
result = callback();
|
|
if (!prevIsBatchingLegacy && ReactCurrentActQueue.didScheduleLegacyUpdate) {
|
|
var queue = ReactCurrentActQueue.current;
|
|
if (queue !== null) {
|
|
ReactCurrentActQueue.didScheduleLegacyUpdate = false;
|
|
flushActQueue(queue);
|
|
}
|
|
}
|
|
} catch (error2) {
|
|
popActScope(prevActScopeDepth);
|
|
throw error2;
|
|
} finally {
|
|
ReactCurrentActQueue.isBatchingLegacy = prevIsBatchingLegacy;
|
|
}
|
|
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
var thenableResult = result;
|
|
var wasAwaited = false;
|
|
var thenable = {
|
|
then: function(resolve, reject) {
|
|
wasAwaited = true;
|
|
thenableResult.then(function(returnValue2) {
|
|
popActScope(prevActScopeDepth);
|
|
if (actScopeDepth === 0) {
|
|
recursivelyFlushAsyncActWork(returnValue2, resolve, reject);
|
|
} else {
|
|
resolve(returnValue2);
|
|
}
|
|
}, function(error2) {
|
|
popActScope(prevActScopeDepth);
|
|
reject(error2);
|
|
});
|
|
}
|
|
};
|
|
{
|
|
if (!didWarnNoAwaitAct && typeof Promise !== "undefined") {
|
|
Promise.resolve().then(function() {
|
|
}).then(function() {
|
|
if (!wasAwaited) {
|
|
didWarnNoAwaitAct = true;
|
|
error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return thenable;
|
|
} else {
|
|
var returnValue = result;
|
|
popActScope(prevActScopeDepth);
|
|
if (actScopeDepth === 0) {
|
|
var _queue = ReactCurrentActQueue.current;
|
|
if (_queue !== null) {
|
|
flushActQueue(_queue);
|
|
ReactCurrentActQueue.current = null;
|
|
}
|
|
var _thenable = {
|
|
then: function(resolve, reject) {
|
|
if (ReactCurrentActQueue.current === null) {
|
|
ReactCurrentActQueue.current = [];
|
|
recursivelyFlushAsyncActWork(returnValue, resolve, reject);
|
|
} else {
|
|
resolve(returnValue);
|
|
}
|
|
}
|
|
};
|
|
return _thenable;
|
|
} else {
|
|
var _thenable2 = {
|
|
then: function(resolve, reject) {
|
|
resolve(returnValue);
|
|
}
|
|
};
|
|
return _thenable2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function popActScope(prevActScopeDepth) {
|
|
{
|
|
if (prevActScopeDepth !== actScopeDepth - 1) {
|
|
error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
|
|
}
|
|
actScopeDepth = prevActScopeDepth;
|
|
}
|
|
}
|
|
function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {
|
|
{
|
|
var queue = ReactCurrentActQueue.current;
|
|
if (queue !== null) {
|
|
try {
|
|
flushActQueue(queue);
|
|
enqueueTask(function() {
|
|
if (queue.length === 0) {
|
|
ReactCurrentActQueue.current = null;
|
|
resolve(returnValue);
|
|
} else {
|
|
recursivelyFlushAsyncActWork(returnValue, resolve, reject);
|
|
}
|
|
});
|
|
} catch (error2) {
|
|
reject(error2);
|
|
}
|
|
} else {
|
|
resolve(returnValue);
|
|
}
|
|
}
|
|
}
|
|
var isFlushing = false;
|
|
function flushActQueue(queue) {
|
|
{
|
|
if (!isFlushing) {
|
|
isFlushing = true;
|
|
var i = 0;
|
|
try {
|
|
for (; i < queue.length; i++) {
|
|
var callback = queue[i];
|
|
do {
|
|
callback = callback(true);
|
|
} while (callback !== null);
|
|
}
|
|
queue.length = 0;
|
|
} catch (error2) {
|
|
queue = queue.slice(i + 1);
|
|
throw error2;
|
|
} finally {
|
|
isFlushing = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var createElement$1 = createElementWithValidation;
|
|
var cloneElement$1 = cloneElementWithValidation;
|
|
var createFactory = createFactoryWithValidation;
|
|
var Children2 = {
|
|
map: mapChildren,
|
|
forEach: forEachChildren,
|
|
count: countChildren,
|
|
toArray,
|
|
only: onlyChild
|
|
};
|
|
exports.Children = Children2;
|
|
exports.Component = Component;
|
|
exports.Fragment = REACT_FRAGMENT_TYPE;
|
|
exports.Profiler = REACT_PROFILER_TYPE;
|
|
exports.PureComponent = PureComponent;
|
|
exports.StrictMode = REACT_STRICT_MODE_TYPE;
|
|
exports.Suspense = REACT_SUSPENSE_TYPE;
|
|
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactSharedInternals;
|
|
exports.cloneElement = cloneElement$1;
|
|
exports.createContext = createContext2;
|
|
exports.createElement = createElement$1;
|
|
exports.createFactory = createFactory;
|
|
exports.createRef = createRef;
|
|
exports.forwardRef = forwardRef2;
|
|
exports.isValidElement = isValidElement2;
|
|
exports.lazy = lazy;
|
|
exports.memo = memo;
|
|
exports.startTransition = startTransition;
|
|
exports.unstable_act = act;
|
|
exports.useCallback = useCallback3;
|
|
exports.useContext = useContext2;
|
|
exports.useDebugValue = useDebugValue;
|
|
exports.useDeferredValue = useDeferredValue;
|
|
exports.useEffect = useEffect4;
|
|
exports.useId = useId;
|
|
exports.useImperativeHandle = useImperativeHandle;
|
|
exports.useInsertionEffect = useInsertionEffect;
|
|
exports.useLayoutEffect = useLayoutEffect3;
|
|
exports.useMemo = useMemo3;
|
|
exports.useReducer = useReducer;
|
|
exports.useRef = useRef3;
|
|
exports.useState = useState5;
|
|
exports.useSyncExternalStore = useSyncExternalStore;
|
|
exports.useTransition = useTransition;
|
|
exports.version = ReactVersion;
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
|
|
}
|
|
})();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/react/index.js
|
|
var require_react = __commonJS({
|
|
"node_modules/react/index.js"(exports, module) {
|
|
"use strict";
|
|
if (false) {
|
|
module.exports = null;
|
|
} else {
|
|
module.exports = require_react_development();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/scheduler/cjs/scheduler.development.js
|
|
var require_scheduler_development = __commonJS({
|
|
"node_modules/scheduler/cjs/scheduler.development.js"(exports) {
|
|
"use strict";
|
|
if (true) {
|
|
(function() {
|
|
"use strict";
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
|
|
}
|
|
var enableSchedulerDebugging = false;
|
|
var enableProfiling = false;
|
|
var frameYieldMs = 5;
|
|
function push(heap, node) {
|
|
var index = heap.length;
|
|
heap.push(node);
|
|
siftUp(heap, node, index);
|
|
}
|
|
function peek(heap) {
|
|
return heap.length === 0 ? null : heap[0];
|
|
}
|
|
function pop(heap) {
|
|
if (heap.length === 0) {
|
|
return null;
|
|
}
|
|
var first = heap[0];
|
|
var last = heap.pop();
|
|
if (last !== first) {
|
|
heap[0] = last;
|
|
siftDown(heap, last, 0);
|
|
}
|
|
return first;
|
|
}
|
|
function siftUp(heap, node, i) {
|
|
var index = i;
|
|
while (index > 0) {
|
|
var parentIndex = index - 1 >>> 1;
|
|
var parent = heap[parentIndex];
|
|
if (compare(parent, node) > 0) {
|
|
heap[parentIndex] = node;
|
|
heap[index] = parent;
|
|
index = parentIndex;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function siftDown(heap, node, i) {
|
|
var index = i;
|
|
var length = heap.length;
|
|
var halfLength = length >>> 1;
|
|
while (index < halfLength) {
|
|
var leftIndex = (index + 1) * 2 - 1;
|
|
var left = heap[leftIndex];
|
|
var rightIndex = leftIndex + 1;
|
|
var right = heap[rightIndex];
|
|
if (compare(left, node) < 0) {
|
|
if (rightIndex < length && compare(right, left) < 0) {
|
|
heap[index] = right;
|
|
heap[rightIndex] = node;
|
|
index = rightIndex;
|
|
} else {
|
|
heap[index] = left;
|
|
heap[leftIndex] = node;
|
|
index = leftIndex;
|
|
}
|
|
} else if (rightIndex < length && compare(right, node) < 0) {
|
|
heap[index] = right;
|
|
heap[rightIndex] = node;
|
|
index = rightIndex;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function compare(a, b) {
|
|
var diff = a.sortIndex - b.sortIndex;
|
|
return diff !== 0 ? diff : a.id - b.id;
|
|
}
|
|
var ImmediatePriority = 1;
|
|
var UserBlockingPriority = 2;
|
|
var NormalPriority = 3;
|
|
var LowPriority = 4;
|
|
var IdlePriority = 5;
|
|
function markTaskErrored(task, ms) {
|
|
}
|
|
var hasPerformanceNow = typeof performance === "object" && typeof performance.now === "function";
|
|
if (hasPerformanceNow) {
|
|
var localPerformance = performance;
|
|
exports.unstable_now = function() {
|
|
return localPerformance.now();
|
|
};
|
|
} else {
|
|
var localDate = Date;
|
|
var initialTime = localDate.now();
|
|
exports.unstable_now = function() {
|
|
return localDate.now() - initialTime;
|
|
};
|
|
}
|
|
var maxSigned31BitInt = 1073741823;
|
|
var IMMEDIATE_PRIORITY_TIMEOUT = -1;
|
|
var USER_BLOCKING_PRIORITY_TIMEOUT = 250;
|
|
var NORMAL_PRIORITY_TIMEOUT = 5e3;
|
|
var LOW_PRIORITY_TIMEOUT = 1e4;
|
|
var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt;
|
|
var taskQueue = [];
|
|
var timerQueue = [];
|
|
var taskIdCounter = 1;
|
|
var currentTask = null;
|
|
var currentPriorityLevel = NormalPriority;
|
|
var isPerformingWork = false;
|
|
var isHostCallbackScheduled = false;
|
|
var isHostTimeoutScheduled = false;
|
|
var localSetTimeout = typeof setTimeout === "function" ? setTimeout : null;
|
|
var localClearTimeout = typeof clearTimeout === "function" ? clearTimeout : null;
|
|
var localSetImmediate = typeof setImmediate !== "undefined" ? setImmediate : null;
|
|
var isInputPending = typeof navigator !== "undefined" && navigator.scheduling !== void 0 && navigator.scheduling.isInputPending !== void 0 ? navigator.scheduling.isInputPending.bind(navigator.scheduling) : null;
|
|
function advanceTimers(currentTime) {
|
|
var timer = peek(timerQueue);
|
|
while (timer !== null) {
|
|
if (timer.callback === null) {
|
|
pop(timerQueue);
|
|
} else if (timer.startTime <= currentTime) {
|
|
pop(timerQueue);
|
|
timer.sortIndex = timer.expirationTime;
|
|
push(taskQueue, timer);
|
|
} else {
|
|
return;
|
|
}
|
|
timer = peek(timerQueue);
|
|
}
|
|
}
|
|
function handleTimeout(currentTime) {
|
|
isHostTimeoutScheduled = false;
|
|
advanceTimers(currentTime);
|
|
if (!isHostCallbackScheduled) {
|
|
if (peek(taskQueue) !== null) {
|
|
isHostCallbackScheduled = true;
|
|
requestHostCallback(flushWork);
|
|
} else {
|
|
var firstTimer = peek(timerQueue);
|
|
if (firstTimer !== null) {
|
|
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function flushWork(hasTimeRemaining, initialTime2) {
|
|
isHostCallbackScheduled = false;
|
|
if (isHostTimeoutScheduled) {
|
|
isHostTimeoutScheduled = false;
|
|
cancelHostTimeout();
|
|
}
|
|
isPerformingWork = true;
|
|
var previousPriorityLevel = currentPriorityLevel;
|
|
try {
|
|
if (enableProfiling) {
|
|
try {
|
|
return workLoop(hasTimeRemaining, initialTime2);
|
|
} catch (error) {
|
|
if (currentTask !== null) {
|
|
var currentTime = exports.unstable_now();
|
|
markTaskErrored(currentTask, currentTime);
|
|
currentTask.isQueued = false;
|
|
}
|
|
throw error;
|
|
}
|
|
} else {
|
|
return workLoop(hasTimeRemaining, initialTime2);
|
|
}
|
|
} finally {
|
|
currentTask = null;
|
|
currentPriorityLevel = previousPriorityLevel;
|
|
isPerformingWork = false;
|
|
}
|
|
}
|
|
function workLoop(hasTimeRemaining, initialTime2) {
|
|
var currentTime = initialTime2;
|
|
advanceTimers(currentTime);
|
|
currentTask = peek(taskQueue);
|
|
while (currentTask !== null && !enableSchedulerDebugging) {
|
|
if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) {
|
|
break;
|
|
}
|
|
var callback = currentTask.callback;
|
|
if (typeof callback === "function") {
|
|
currentTask.callback = null;
|
|
currentPriorityLevel = currentTask.priorityLevel;
|
|
var didUserCallbackTimeout = currentTask.expirationTime <= currentTime;
|
|
var continuationCallback = callback(didUserCallbackTimeout);
|
|
currentTime = exports.unstable_now();
|
|
if (typeof continuationCallback === "function") {
|
|
currentTask.callback = continuationCallback;
|
|
} else {
|
|
if (currentTask === peek(taskQueue)) {
|
|
pop(taskQueue);
|
|
}
|
|
}
|
|
advanceTimers(currentTime);
|
|
} else {
|
|
pop(taskQueue);
|
|
}
|
|
currentTask = peek(taskQueue);
|
|
}
|
|
if (currentTask !== null) {
|
|
return true;
|
|
} else {
|
|
var firstTimer = peek(timerQueue);
|
|
if (firstTimer !== null) {
|
|
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
function unstable_runWithPriority(priorityLevel, eventHandler) {
|
|
switch (priorityLevel) {
|
|
case ImmediatePriority:
|
|
case UserBlockingPriority:
|
|
case NormalPriority:
|
|
case LowPriority:
|
|
case IdlePriority:
|
|
break;
|
|
default:
|
|
priorityLevel = NormalPriority;
|
|
}
|
|
var previousPriorityLevel = currentPriorityLevel;
|
|
currentPriorityLevel = priorityLevel;
|
|
try {
|
|
return eventHandler();
|
|
} finally {
|
|
currentPriorityLevel = previousPriorityLevel;
|
|
}
|
|
}
|
|
function unstable_next(eventHandler) {
|
|
var priorityLevel;
|
|
switch (currentPriorityLevel) {
|
|
case ImmediatePriority:
|
|
case UserBlockingPriority:
|
|
case NormalPriority:
|
|
priorityLevel = NormalPriority;
|
|
break;
|
|
default:
|
|
priorityLevel = currentPriorityLevel;
|
|
break;
|
|
}
|
|
var previousPriorityLevel = currentPriorityLevel;
|
|
currentPriorityLevel = priorityLevel;
|
|
try {
|
|
return eventHandler();
|
|
} finally {
|
|
currentPriorityLevel = previousPriorityLevel;
|
|
}
|
|
}
|
|
function unstable_wrapCallback(callback) {
|
|
var parentPriorityLevel = currentPriorityLevel;
|
|
return function() {
|
|
var previousPriorityLevel = currentPriorityLevel;
|
|
currentPriorityLevel = parentPriorityLevel;
|
|
try {
|
|
return callback.apply(this, arguments);
|
|
} finally {
|
|
currentPriorityLevel = previousPriorityLevel;
|
|
}
|
|
};
|
|
}
|
|
function unstable_scheduleCallback(priorityLevel, callback, options) {
|
|
var currentTime = exports.unstable_now();
|
|
var startTime2;
|
|
if (typeof options === "object" && options !== null) {
|
|
var delay = options.delay;
|
|
if (typeof delay === "number" && delay > 0) {
|
|
startTime2 = currentTime + delay;
|
|
} else {
|
|
startTime2 = currentTime;
|
|
}
|
|
} else {
|
|
startTime2 = currentTime;
|
|
}
|
|
var timeout;
|
|
switch (priorityLevel) {
|
|
case ImmediatePriority:
|
|
timeout = IMMEDIATE_PRIORITY_TIMEOUT;
|
|
break;
|
|
case UserBlockingPriority:
|
|
timeout = USER_BLOCKING_PRIORITY_TIMEOUT;
|
|
break;
|
|
case IdlePriority:
|
|
timeout = IDLE_PRIORITY_TIMEOUT;
|
|
break;
|
|
case LowPriority:
|
|
timeout = LOW_PRIORITY_TIMEOUT;
|
|
break;
|
|
case NormalPriority:
|
|
default:
|
|
timeout = NORMAL_PRIORITY_TIMEOUT;
|
|
break;
|
|
}
|
|
var expirationTime = startTime2 + timeout;
|
|
var newTask = {
|
|
id: taskIdCounter++,
|
|
callback,
|
|
priorityLevel,
|
|
startTime: startTime2,
|
|
expirationTime,
|
|
sortIndex: -1
|
|
};
|
|
if (startTime2 > currentTime) {
|
|
newTask.sortIndex = startTime2;
|
|
push(timerQueue, newTask);
|
|
if (peek(taskQueue) === null && newTask === peek(timerQueue)) {
|
|
if (isHostTimeoutScheduled) {
|
|
cancelHostTimeout();
|
|
} else {
|
|
isHostTimeoutScheduled = true;
|
|
}
|
|
requestHostTimeout(handleTimeout, startTime2 - currentTime);
|
|
}
|
|
} else {
|
|
newTask.sortIndex = expirationTime;
|
|
push(taskQueue, newTask);
|
|
if (!isHostCallbackScheduled && !isPerformingWork) {
|
|
isHostCallbackScheduled = true;
|
|
requestHostCallback(flushWork);
|
|
}
|
|
}
|
|
return newTask;
|
|
}
|
|
function unstable_pauseExecution() {
|
|
}
|
|
function unstable_continueExecution() {
|
|
if (!isHostCallbackScheduled && !isPerformingWork) {
|
|
isHostCallbackScheduled = true;
|
|
requestHostCallback(flushWork);
|
|
}
|
|
}
|
|
function unstable_getFirstCallbackNode() {
|
|
return peek(taskQueue);
|
|
}
|
|
function unstable_cancelCallback(task) {
|
|
task.callback = null;
|
|
}
|
|
function unstable_getCurrentPriorityLevel() {
|
|
return currentPriorityLevel;
|
|
}
|
|
var isMessageLoopRunning = false;
|
|
var scheduledHostCallback = null;
|
|
var taskTimeoutID = -1;
|
|
var frameInterval = frameYieldMs;
|
|
var startTime = -1;
|
|
function shouldYieldToHost() {
|
|
var timeElapsed = exports.unstable_now() - startTime;
|
|
if (timeElapsed < frameInterval) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
function requestPaint() {
|
|
}
|
|
function forceFrameRate(fps) {
|
|
if (fps < 0 || fps > 125) {
|
|
console["error"]("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported");
|
|
return;
|
|
}
|
|
if (fps > 0) {
|
|
frameInterval = Math.floor(1e3 / fps);
|
|
} else {
|
|
frameInterval = frameYieldMs;
|
|
}
|
|
}
|
|
var performWorkUntilDeadline = function() {
|
|
if (scheduledHostCallback !== null) {
|
|
var currentTime = exports.unstable_now();
|
|
startTime = currentTime;
|
|
var hasTimeRemaining = true;
|
|
var hasMoreWork = true;
|
|
try {
|
|
hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime);
|
|
} finally {
|
|
if (hasMoreWork) {
|
|
schedulePerformWorkUntilDeadline();
|
|
} else {
|
|
isMessageLoopRunning = false;
|
|
scheduledHostCallback = null;
|
|
}
|
|
}
|
|
} else {
|
|
isMessageLoopRunning = false;
|
|
}
|
|
};
|
|
var schedulePerformWorkUntilDeadline;
|
|
if (typeof localSetImmediate === "function") {
|
|
schedulePerformWorkUntilDeadline = function() {
|
|
localSetImmediate(performWorkUntilDeadline);
|
|
};
|
|
} else if (typeof MessageChannel !== "undefined") {
|
|
var channel = new MessageChannel();
|
|
var port = channel.port2;
|
|
channel.port1.onmessage = performWorkUntilDeadline;
|
|
schedulePerformWorkUntilDeadline = function() {
|
|
port.postMessage(null);
|
|
};
|
|
} else {
|
|
schedulePerformWorkUntilDeadline = function() {
|
|
localSetTimeout(performWorkUntilDeadline, 0);
|
|
};
|
|
}
|
|
function requestHostCallback(callback) {
|
|
scheduledHostCallback = callback;
|
|
if (!isMessageLoopRunning) {
|
|
isMessageLoopRunning = true;
|
|
schedulePerformWorkUntilDeadline();
|
|
}
|
|
}
|
|
function requestHostTimeout(callback, ms) {
|
|
taskTimeoutID = localSetTimeout(function() {
|
|
callback(exports.unstable_now());
|
|
}, ms);
|
|
}
|
|
function cancelHostTimeout() {
|
|
localClearTimeout(taskTimeoutID);
|
|
taskTimeoutID = -1;
|
|
}
|
|
var unstable_requestPaint = requestPaint;
|
|
var unstable_Profiling = null;
|
|
exports.unstable_IdlePriority = IdlePriority;
|
|
exports.unstable_ImmediatePriority = ImmediatePriority;
|
|
exports.unstable_LowPriority = LowPriority;
|
|
exports.unstable_NormalPriority = NormalPriority;
|
|
exports.unstable_Profiling = unstable_Profiling;
|
|
exports.unstable_UserBlockingPriority = UserBlockingPriority;
|
|
exports.unstable_cancelCallback = unstable_cancelCallback;
|
|
exports.unstable_continueExecution = unstable_continueExecution;
|
|
exports.unstable_forceFrameRate = forceFrameRate;
|
|
exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
|
|
exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode;
|
|
exports.unstable_next = unstable_next;
|
|
exports.unstable_pauseExecution = unstable_pauseExecution;
|
|
exports.unstable_requestPaint = unstable_requestPaint;
|
|
exports.unstable_runWithPriority = unstable_runWithPriority;
|
|
exports.unstable_scheduleCallback = unstable_scheduleCallback;
|
|
exports.unstable_shouldYield = shouldYieldToHost;
|
|
exports.unstable_wrapCallback = unstable_wrapCallback;
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
|
|
}
|
|
})();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/scheduler/index.js
|
|
var require_scheduler = __commonJS({
|
|
"node_modules/scheduler/index.js"(exports, module) {
|
|
"use strict";
|
|
if (false) {
|
|
module.exports = null;
|
|
} else {
|
|
module.exports = require_scheduler_development();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/react-dom/cjs/react-dom.development.js
|
|
var require_react_dom_development = __commonJS({
|
|
"node_modules/react-dom/cjs/react-dom.development.js"(exports) {
|
|
"use strict";
|
|
if (true) {
|
|
(function() {
|
|
"use strict";
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
|
|
}
|
|
var React4 = require_react();
|
|
var Scheduler = require_scheduler();
|
|
var ReactSharedInternals = React4.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
var suppressWarning = false;
|
|
function setSuppressWarning(newSuppressWarning) {
|
|
{
|
|
suppressWarning = newSuppressWarning;
|
|
}
|
|
}
|
|
function warn(format) {
|
|
{
|
|
if (!suppressWarning) {
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
args[_key - 1] = arguments[_key];
|
|
}
|
|
printWarning("warn", format, args);
|
|
}
|
|
}
|
|
}
|
|
function error(format) {
|
|
{
|
|
if (!suppressWarning) {
|
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
args[_key2 - 1] = arguments[_key2];
|
|
}
|
|
printWarning("error", format, args);
|
|
}
|
|
}
|
|
}
|
|
function printWarning(level, format, args) {
|
|
{
|
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
if (stack !== "") {
|
|
format += "%s";
|
|
args = args.concat([stack]);
|
|
}
|
|
var argsWithFormat = args.map(function(item) {
|
|
return String(item);
|
|
});
|
|
argsWithFormat.unshift("Warning: " + format);
|
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
}
|
|
}
|
|
var FunctionComponent = 0;
|
|
var ClassComponent = 1;
|
|
var IndeterminateComponent = 2;
|
|
var HostRoot = 3;
|
|
var HostPortal = 4;
|
|
var HostComponent = 5;
|
|
var HostText = 6;
|
|
var Fragment2 = 7;
|
|
var Mode = 8;
|
|
var ContextConsumer = 9;
|
|
var ContextProvider = 10;
|
|
var ForwardRef = 11;
|
|
var Profiler = 12;
|
|
var SuspenseComponent = 13;
|
|
var MemoComponent = 14;
|
|
var SimpleMemoComponent = 15;
|
|
var LazyComponent = 16;
|
|
var IncompleteClassComponent = 17;
|
|
var DehydratedFragment = 18;
|
|
var SuspenseListComponent = 19;
|
|
var ScopeComponent = 21;
|
|
var OffscreenComponent = 22;
|
|
var LegacyHiddenComponent = 23;
|
|
var CacheComponent = 24;
|
|
var TracingMarkerComponent = 25;
|
|
var enableClientRenderFallbackOnTextMismatch = true;
|
|
var enableNewReconciler = false;
|
|
var enableLazyContextPropagation = false;
|
|
var enableLegacyHidden = false;
|
|
var enableSuspenseAvoidThisFallback = false;
|
|
var disableCommentsAsDOMContainers = true;
|
|
var enableCustomElementPropertySupport = false;
|
|
var warnAboutStringRefs = false;
|
|
var enableSchedulingProfiler = true;
|
|
var enableProfilerTimer = true;
|
|
var enableProfilerCommitHooks = true;
|
|
var allNativeEvents = /* @__PURE__ */ new Set();
|
|
var registrationNameDependencies = {};
|
|
var possibleRegistrationNames = {};
|
|
function registerTwoPhaseEvent(registrationName, dependencies) {
|
|
registerDirectEvent(registrationName, dependencies);
|
|
registerDirectEvent(registrationName + "Capture", dependencies);
|
|
}
|
|
function registerDirectEvent(registrationName, dependencies) {
|
|
{
|
|
if (registrationNameDependencies[registrationName]) {
|
|
error("EventRegistry: More than one plugin attempted to publish the same registration name, `%s`.", registrationName);
|
|
}
|
|
}
|
|
registrationNameDependencies[registrationName] = dependencies;
|
|
{
|
|
var lowerCasedName = registrationName.toLowerCase();
|
|
possibleRegistrationNames[lowerCasedName] = registrationName;
|
|
if (registrationName === "onDoubleClick") {
|
|
possibleRegistrationNames.ondblclick = registrationName;
|
|
}
|
|
}
|
|
for (var i = 0; i < dependencies.length; i++) {
|
|
allNativeEvents.add(dependencies[i]);
|
|
}
|
|
}
|
|
var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
function typeName(value) {
|
|
{
|
|
var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag;
|
|
var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
|
|
return type;
|
|
}
|
|
}
|
|
function willCoercionThrow(value) {
|
|
{
|
|
try {
|
|
testStringCoercion(value);
|
|
return false;
|
|
} catch (e) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
function testStringCoercion(value) {
|
|
return "" + value;
|
|
}
|
|
function checkAttributeStringCoercion(value, attributeName) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("The provided `%s` attribute is an unsupported type %s. This value must be coerced to a string before before using it here.", attributeName, typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
function checkKeyStringCoercion(value) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
function checkPropStringCoercion(value, propName) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("The provided `%s` prop is an unsupported type %s. This value must be coerced to a string before before using it here.", propName, typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
function checkCSSPropertyStringCoercion(value, propName) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("The provided `%s` CSS property is an unsupported type %s. This value must be coerced to a string before before using it here.", propName, typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
function checkHtmlStringCoercion(value) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("The provided HTML markup uses a value of unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
function checkFormFieldValueStringCoercion(value) {
|
|
{
|
|
if (willCoercionThrow(value)) {
|
|
error("Form field values (value, checked, defaultValue, or defaultChecked props) must be strings, not %s. This value must be coerced to a string before before using it here.", typeName(value));
|
|
return testStringCoercion(value);
|
|
}
|
|
}
|
|
}
|
|
var RESERVED = 0;
|
|
var STRING = 1;
|
|
var BOOLEANISH_STRING = 2;
|
|
var BOOLEAN = 3;
|
|
var OVERLOADED_BOOLEAN = 4;
|
|
var NUMERIC = 5;
|
|
var POSITIVE_NUMERIC = 6;
|
|
var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
|
|
var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
|
|
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp("^[" + ATTRIBUTE_NAME_START_CHAR + "][" + ATTRIBUTE_NAME_CHAR + "]*$");
|
|
var illegalAttributeNameCache = {};
|
|
var validatedAttributeNameCache = {};
|
|
function isAttributeNameSafe(attributeName) {
|
|
if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
|
|
return true;
|
|
}
|
|
if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
|
|
return false;
|
|
}
|
|
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
|
|
validatedAttributeNameCache[attributeName] = true;
|
|
return true;
|
|
}
|
|
illegalAttributeNameCache[attributeName] = true;
|
|
{
|
|
error("Invalid attribute name: `%s`", attributeName);
|
|
}
|
|
return false;
|
|
}
|
|
function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
|
|
if (propertyInfo !== null) {
|
|
return propertyInfo.type === RESERVED;
|
|
}
|
|
if (isCustomComponentTag) {
|
|
return false;
|
|
}
|
|
if (name.length > 2 && (name[0] === "o" || name[0] === "O") && (name[1] === "n" || name[1] === "N")) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
|
|
if (propertyInfo !== null && propertyInfo.type === RESERVED) {
|
|
return false;
|
|
}
|
|
switch (typeof value) {
|
|
case "function":
|
|
case "symbol":
|
|
return true;
|
|
case "boolean": {
|
|
if (isCustomComponentTag) {
|
|
return false;
|
|
}
|
|
if (propertyInfo !== null) {
|
|
return !propertyInfo.acceptsBooleans;
|
|
} else {
|
|
var prefix2 = name.toLowerCase().slice(0, 5);
|
|
return prefix2 !== "data-" && prefix2 !== "aria-";
|
|
}
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
|
|
if (value === null || typeof value === "undefined") {
|
|
return true;
|
|
}
|
|
if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
|
|
return true;
|
|
}
|
|
if (isCustomComponentTag) {
|
|
return false;
|
|
}
|
|
if (propertyInfo !== null) {
|
|
switch (propertyInfo.type) {
|
|
case BOOLEAN:
|
|
return !value;
|
|
case OVERLOADED_BOOLEAN:
|
|
return value === false;
|
|
case NUMERIC:
|
|
return isNaN(value);
|
|
case POSITIVE_NUMERIC:
|
|
return isNaN(value) || value < 1;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function getPropertyInfo(name) {
|
|
return properties.hasOwnProperty(name) ? properties[name] : null;
|
|
}
|
|
function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL2, removeEmptyString) {
|
|
this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
|
|
this.attributeName = attributeName;
|
|
this.attributeNamespace = attributeNamespace;
|
|
this.mustUseProperty = mustUseProperty;
|
|
this.propertyName = name;
|
|
this.type = type;
|
|
this.sanitizeURL = sanitizeURL2;
|
|
this.removeEmptyString = removeEmptyString;
|
|
}
|
|
var properties = {};
|
|
var reservedProps = [
|
|
"children",
|
|
"dangerouslySetInnerHTML",
|
|
"defaultValue",
|
|
"defaultChecked",
|
|
"innerHTML",
|
|
"suppressContentEditableWarning",
|
|
"suppressHydrationWarning",
|
|
"style"
|
|
];
|
|
reservedProps.forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, RESERVED, false, name, null, false, false);
|
|
});
|
|
[["acceptCharset", "accept-charset"], ["className", "class"], ["htmlFor", "for"], ["httpEquiv", "http-equiv"]].forEach(function(_ref) {
|
|
var name = _ref[0], attributeName = _ref[1];
|
|
properties[name] = new PropertyInfoRecord(name, STRING, false, attributeName, null, false, false);
|
|
});
|
|
["contentEditable", "draggable", "spellCheck", "value"].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, name.toLowerCase(), null, false, false);
|
|
});
|
|
["autoReverse", "externalResourcesRequired", "focusable", "preserveAlpha"].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, name, null, false, false);
|
|
});
|
|
[
|
|
"allowFullScreen",
|
|
"async",
|
|
"autoFocus",
|
|
"autoPlay",
|
|
"controls",
|
|
"default",
|
|
"defer",
|
|
"disabled",
|
|
"disablePictureInPicture",
|
|
"disableRemotePlayback",
|
|
"formNoValidate",
|
|
"hidden",
|
|
"loop",
|
|
"noModule",
|
|
"noValidate",
|
|
"open",
|
|
"playsInline",
|
|
"readOnly",
|
|
"required",
|
|
"reversed",
|
|
"scoped",
|
|
"seamless",
|
|
"itemScope"
|
|
].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, name.toLowerCase(), null, false, false);
|
|
});
|
|
[
|
|
"checked",
|
|
"multiple",
|
|
"muted",
|
|
"selected"
|
|
].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, name, null, false, false);
|
|
});
|
|
[
|
|
"capture",
|
|
"download"
|
|
].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, name, null, false, false);
|
|
});
|
|
[
|
|
"cols",
|
|
"rows",
|
|
"size",
|
|
"span"
|
|
].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, name, null, false, false);
|
|
});
|
|
["rowSpan", "start"].forEach(function(name) {
|
|
properties[name] = new PropertyInfoRecord(name, NUMERIC, false, name.toLowerCase(), null, false, false);
|
|
});
|
|
var CAMELIZE = /[\-\:]([a-z])/g;
|
|
var capitalize = function(token) {
|
|
return token[1].toUpperCase();
|
|
};
|
|
[
|
|
"accent-height",
|
|
"alignment-baseline",
|
|
"arabic-form",
|
|
"baseline-shift",
|
|
"cap-height",
|
|
"clip-path",
|
|
"clip-rule",
|
|
"color-interpolation",
|
|
"color-interpolation-filters",
|
|
"color-profile",
|
|
"color-rendering",
|
|
"dominant-baseline",
|
|
"enable-background",
|
|
"fill-opacity",
|
|
"fill-rule",
|
|
"flood-color",
|
|
"flood-opacity",
|
|
"font-family",
|
|
"font-size",
|
|
"font-size-adjust",
|
|
"font-stretch",
|
|
"font-style",
|
|
"font-variant",
|
|
"font-weight",
|
|
"glyph-name",
|
|
"glyph-orientation-horizontal",
|
|
"glyph-orientation-vertical",
|
|
"horiz-adv-x",
|
|
"horiz-origin-x",
|
|
"image-rendering",
|
|
"letter-spacing",
|
|
"lighting-color",
|
|
"marker-end",
|
|
"marker-mid",
|
|
"marker-start",
|
|
"overline-position",
|
|
"overline-thickness",
|
|
"paint-order",
|
|
"panose-1",
|
|
"pointer-events",
|
|
"rendering-intent",
|
|
"shape-rendering",
|
|
"stop-color",
|
|
"stop-opacity",
|
|
"strikethrough-position",
|
|
"strikethrough-thickness",
|
|
"stroke-dasharray",
|
|
"stroke-dashoffset",
|
|
"stroke-linecap",
|
|
"stroke-linejoin",
|
|
"stroke-miterlimit",
|
|
"stroke-opacity",
|
|
"stroke-width",
|
|
"text-anchor",
|
|
"text-decoration",
|
|
"text-rendering",
|
|
"underline-position",
|
|
"underline-thickness",
|
|
"unicode-bidi",
|
|
"unicode-range",
|
|
"units-per-em",
|
|
"v-alphabetic",
|
|
"v-hanging",
|
|
"v-ideographic",
|
|
"v-mathematical",
|
|
"vector-effect",
|
|
"vert-adv-y",
|
|
"vert-origin-x",
|
|
"vert-origin-y",
|
|
"word-spacing",
|
|
"writing-mode",
|
|
"xmlns:xlink",
|
|
"x-height"
|
|
].forEach(function(attributeName) {
|
|
var name = attributeName.replace(CAMELIZE, capitalize);
|
|
properties[name] = new PropertyInfoRecord(name, STRING, false, attributeName, null, false, false);
|
|
});
|
|
[
|
|
"xlink:actuate",
|
|
"xlink:arcrole",
|
|
"xlink:role",
|
|
"xlink:show",
|
|
"xlink:title",
|
|
"xlink:type"
|
|
].forEach(function(attributeName) {
|
|
var name = attributeName.replace(CAMELIZE, capitalize);
|
|
properties[name] = new PropertyInfoRecord(name, STRING, false, attributeName, "http://www.w3.org/1999/xlink", false, false);
|
|
});
|
|
[
|
|
"xml:base",
|
|
"xml:lang",
|
|
"xml:space"
|
|
].forEach(function(attributeName) {
|
|
var name = attributeName.replace(CAMELIZE, capitalize);
|
|
properties[name] = new PropertyInfoRecord(name, STRING, false, attributeName, "http://www.w3.org/XML/1998/namespace", false, false);
|
|
});
|
|
["tabIndex", "crossOrigin"].forEach(function(attributeName) {
|
|
properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, attributeName.toLowerCase(), null, false, false);
|
|
});
|
|
var xlinkHref = "xlinkHref";
|
|
properties[xlinkHref] = new PropertyInfoRecord("xlinkHref", STRING, false, "xlink:href", "http://www.w3.org/1999/xlink", true, false);
|
|
["src", "href", "action", "formAction"].forEach(function(attributeName) {
|
|
properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, attributeName.toLowerCase(), null, true, true);
|
|
});
|
|
var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
|
|
var didWarn = false;
|
|
function sanitizeURL(url) {
|
|
{
|
|
if (!didWarn && isJavaScriptProtocol.test(url)) {
|
|
didWarn = true;
|
|
error("A future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead. React was passed %s.", JSON.stringify(url));
|
|
}
|
|
}
|
|
}
|
|
function getValueForProperty(node, name, expected, propertyInfo) {
|
|
{
|
|
if (propertyInfo.mustUseProperty) {
|
|
var propertyName = propertyInfo.propertyName;
|
|
return node[propertyName];
|
|
} else {
|
|
{
|
|
checkAttributeStringCoercion(expected, name);
|
|
}
|
|
if (propertyInfo.sanitizeURL) {
|
|
sanitizeURL("" + expected);
|
|
}
|
|
var attributeName = propertyInfo.attributeName;
|
|
var stringValue = null;
|
|
if (propertyInfo.type === OVERLOADED_BOOLEAN) {
|
|
if (node.hasAttribute(attributeName)) {
|
|
var value = node.getAttribute(attributeName);
|
|
if (value === "") {
|
|
return true;
|
|
}
|
|
if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
|
|
return value;
|
|
}
|
|
if (value === "" + expected) {
|
|
return expected;
|
|
}
|
|
return value;
|
|
}
|
|
} else if (node.hasAttribute(attributeName)) {
|
|
if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
|
|
return node.getAttribute(attributeName);
|
|
}
|
|
if (propertyInfo.type === BOOLEAN) {
|
|
return expected;
|
|
}
|
|
stringValue = node.getAttribute(attributeName);
|
|
}
|
|
if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
|
|
return stringValue === null ? expected : stringValue;
|
|
} else if (stringValue === "" + expected) {
|
|
return expected;
|
|
} else {
|
|
return stringValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function getValueForAttribute(node, name, expected) {
|
|
{
|
|
if (!isAttributeNameSafe(name)) {
|
|
return;
|
|
}
|
|
if (!node.hasAttribute(name)) {
|
|
return expected === void 0 ? void 0 : null;
|
|
}
|
|
var value = node.getAttribute(name);
|
|
{
|
|
checkAttributeStringCoercion(expected, name);
|
|
}
|
|
if (value === "" + expected) {
|
|
return expected;
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
function setValueForProperty(node, name, value, isCustomComponentTag) {
|
|
var propertyInfo = getPropertyInfo(name);
|
|
if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
|
|
return;
|
|
}
|
|
if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
|
|
value = null;
|
|
}
|
|
if (isCustomComponentTag || propertyInfo === null) {
|
|
if (isAttributeNameSafe(name)) {
|
|
var _attributeName = name;
|
|
if (value === null) {
|
|
node.removeAttribute(_attributeName);
|
|
} else {
|
|
{
|
|
checkAttributeStringCoercion(value, name);
|
|
}
|
|
node.setAttribute(_attributeName, "" + value);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
var mustUseProperty = propertyInfo.mustUseProperty;
|
|
if (mustUseProperty) {
|
|
var propertyName = propertyInfo.propertyName;
|
|
if (value === null) {
|
|
var type = propertyInfo.type;
|
|
node[propertyName] = type === BOOLEAN ? false : "";
|
|
} else {
|
|
node[propertyName] = value;
|
|
}
|
|
return;
|
|
}
|
|
var attributeName = propertyInfo.attributeName, attributeNamespace = propertyInfo.attributeNamespace;
|
|
if (value === null) {
|
|
node.removeAttribute(attributeName);
|
|
} else {
|
|
var _type = propertyInfo.type;
|
|
var attributeValue;
|
|
if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
|
|
attributeValue = "";
|
|
} else {
|
|
{
|
|
{
|
|
checkAttributeStringCoercion(value, attributeName);
|
|
}
|
|
attributeValue = "" + value;
|
|
}
|
|
if (propertyInfo.sanitizeURL) {
|
|
sanitizeURL(attributeValue.toString());
|
|
}
|
|
}
|
|
if (attributeNamespace) {
|
|
node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
|
|
} else {
|
|
node.setAttribute(attributeName, attributeValue);
|
|
}
|
|
}
|
|
}
|
|
var REACT_ELEMENT_TYPE = Symbol.for("react.element");
|
|
var REACT_PORTAL_TYPE = Symbol.for("react.portal");
|
|
var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
|
|
var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode");
|
|
var REACT_PROFILER_TYPE = Symbol.for("react.profiler");
|
|
var REACT_PROVIDER_TYPE = Symbol.for("react.provider");
|
|
var REACT_CONTEXT_TYPE = Symbol.for("react.context");
|
|
var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref");
|
|
var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense");
|
|
var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list");
|
|
var REACT_MEMO_TYPE = Symbol.for("react.memo");
|
|
var REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
var REACT_SCOPE_TYPE = Symbol.for("react.scope");
|
|
var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode");
|
|
var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen");
|
|
var REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden");
|
|
var REACT_CACHE_TYPE = Symbol.for("react.cache");
|
|
var REACT_TRACING_MARKER_TYPE = Symbol.for("react.tracing_marker");
|
|
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
|
|
var FAUX_ITERATOR_SYMBOL = "@@iterator";
|
|
function getIteratorFn(maybeIterable) {
|
|
if (maybeIterable === null || typeof maybeIterable !== "object") {
|
|
return null;
|
|
}
|
|
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
|
if (typeof maybeIterator === "function") {
|
|
return maybeIterator;
|
|
}
|
|
return null;
|
|
}
|
|
var assign = Object.assign;
|
|
var disabledDepth = 0;
|
|
var prevLog;
|
|
var prevInfo;
|
|
var prevWarn;
|
|
var prevError;
|
|
var prevGroup;
|
|
var prevGroupCollapsed;
|
|
var prevGroupEnd;
|
|
function disabledLog() {
|
|
}
|
|
disabledLog.__reactDisabledLog = true;
|
|
function disableLogs() {
|
|
{
|
|
if (disabledDepth === 0) {
|
|
prevLog = console.log;
|
|
prevInfo = console.info;
|
|
prevWarn = console.warn;
|
|
prevError = console.error;
|
|
prevGroup = console.group;
|
|
prevGroupCollapsed = console.groupCollapsed;
|
|
prevGroupEnd = console.groupEnd;
|
|
var props = {
|
|
configurable: true,
|
|
enumerable: true,
|
|
value: disabledLog,
|
|
writable: true
|
|
};
|
|
Object.defineProperties(console, {
|
|
info: props,
|
|
log: props,
|
|
warn: props,
|
|
error: props,
|
|
group: props,
|
|
groupCollapsed: props,
|
|
groupEnd: props
|
|
});
|
|
}
|
|
disabledDepth++;
|
|
}
|
|
}
|
|
function reenableLogs() {
|
|
{
|
|
disabledDepth--;
|
|
if (disabledDepth === 0) {
|
|
var props = {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true
|
|
};
|
|
Object.defineProperties(console, {
|
|
log: assign({}, props, {
|
|
value: prevLog
|
|
}),
|
|
info: assign({}, props, {
|
|
value: prevInfo
|
|
}),
|
|
warn: assign({}, props, {
|
|
value: prevWarn
|
|
}),
|
|
error: assign({}, props, {
|
|
value: prevError
|
|
}),
|
|
group: assign({}, props, {
|
|
value: prevGroup
|
|
}),
|
|
groupCollapsed: assign({}, props, {
|
|
value: prevGroupCollapsed
|
|
}),
|
|
groupEnd: assign({}, props, {
|
|
value: prevGroupEnd
|
|
})
|
|
});
|
|
}
|
|
if (disabledDepth < 0) {
|
|
error("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
}
|
|
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
|
|
var prefix;
|
|
function describeBuiltInComponentFrame(name, source, ownerFn) {
|
|
{
|
|
if (prefix === void 0) {
|
|
try {
|
|
throw Error();
|
|
} catch (x) {
|
|
var match = x.stack.trim().match(/\n( *(at )?)/);
|
|
prefix = match && match[1] || "";
|
|
}
|
|
}
|
|
return "\n" + prefix + name;
|
|
}
|
|
}
|
|
var reentry = false;
|
|
var componentFrameCache;
|
|
{
|
|
var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map;
|
|
componentFrameCache = new PossiblyWeakMap();
|
|
}
|
|
function describeNativeComponentFrame(fn, construct) {
|
|
if (!fn || reentry) {
|
|
return "";
|
|
}
|
|
{
|
|
var frame = componentFrameCache.get(fn);
|
|
if (frame !== void 0) {
|
|
return frame;
|
|
}
|
|
}
|
|
var control;
|
|
reentry = true;
|
|
var previousPrepareStackTrace = Error.prepareStackTrace;
|
|
Error.prepareStackTrace = void 0;
|
|
var previousDispatcher;
|
|
{
|
|
previousDispatcher = ReactCurrentDispatcher.current;
|
|
ReactCurrentDispatcher.current = null;
|
|
disableLogs();
|
|
}
|
|
try {
|
|
if (construct) {
|
|
var Fake = function() {
|
|
throw Error();
|
|
};
|
|
Object.defineProperty(Fake.prototype, "props", {
|
|
set: function() {
|
|
throw Error();
|
|
}
|
|
});
|
|
if (typeof Reflect === "object" && Reflect.construct) {
|
|
try {
|
|
Reflect.construct(Fake, []);
|
|
} catch (x) {
|
|
control = x;
|
|
}
|
|
Reflect.construct(fn, [], Fake);
|
|
} else {
|
|
try {
|
|
Fake.call();
|
|
} catch (x) {
|
|
control = x;
|
|
}
|
|
fn.call(Fake.prototype);
|
|
}
|
|
} else {
|
|
try {
|
|
throw Error();
|
|
} catch (x) {
|
|
control = x;
|
|
}
|
|
fn();
|
|
}
|
|
} catch (sample) {
|
|
if (sample && control && typeof sample.stack === "string") {
|
|
var sampleLines = sample.stack.split("\n");
|
|
var controlLines = control.stack.split("\n");
|
|
var s = sampleLines.length - 1;
|
|
var c = controlLines.length - 1;
|
|
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
|
|
c--;
|
|
}
|
|
for (; s >= 1 && c >= 0; s--, c--) {
|
|
if (sampleLines[s] !== controlLines[c]) {
|
|
if (s !== 1 || c !== 1) {
|
|
do {
|
|
s--;
|
|
c--;
|
|
if (c < 0 || sampleLines[s] !== controlLines[c]) {
|
|
var _frame = "\n" + sampleLines[s].replace(" at new ", " at ");
|
|
if (fn.displayName && _frame.includes("<anonymous>")) {
|
|
_frame = _frame.replace("<anonymous>", fn.displayName);
|
|
}
|
|
{
|
|
if (typeof fn === "function") {
|
|
componentFrameCache.set(fn, _frame);
|
|
}
|
|
}
|
|
return _frame;
|
|
}
|
|
} while (s >= 1 && c >= 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
reentry = false;
|
|
{
|
|
ReactCurrentDispatcher.current = previousDispatcher;
|
|
reenableLogs();
|
|
}
|
|
Error.prepareStackTrace = previousPrepareStackTrace;
|
|
}
|
|
var name = fn ? fn.displayName || fn.name : "";
|
|
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
|
|
{
|
|
if (typeof fn === "function") {
|
|
componentFrameCache.set(fn, syntheticFrame);
|
|
}
|
|
}
|
|
return syntheticFrame;
|
|
}
|
|
function describeClassComponentFrame(ctor, source, ownerFn) {
|
|
{
|
|
return describeNativeComponentFrame(ctor, true);
|
|
}
|
|
}
|
|
function describeFunctionComponentFrame(fn, source, ownerFn) {
|
|
{
|
|
return describeNativeComponentFrame(fn, false);
|
|
}
|
|
}
|
|
function shouldConstruct(Component) {
|
|
var prototype = Component.prototype;
|
|
return !!(prototype && prototype.isReactComponent);
|
|
}
|
|
function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
|
|
if (type == null) {
|
|
return "";
|
|
}
|
|
if (typeof type === "function") {
|
|
{
|
|
return describeNativeComponentFrame(type, shouldConstruct(type));
|
|
}
|
|
}
|
|
if (typeof type === "string") {
|
|
return describeBuiltInComponentFrame(type);
|
|
}
|
|
switch (type) {
|
|
case REACT_SUSPENSE_TYPE:
|
|
return describeBuiltInComponentFrame("Suspense");
|
|
case REACT_SUSPENSE_LIST_TYPE:
|
|
return describeBuiltInComponentFrame("SuspenseList");
|
|
}
|
|
if (typeof type === "object") {
|
|
switch (type.$$typeof) {
|
|
case REACT_FORWARD_REF_TYPE:
|
|
return describeFunctionComponentFrame(type.render);
|
|
case REACT_MEMO_TYPE:
|
|
return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
|
|
case REACT_LAZY_TYPE: {
|
|
var lazyComponent = type;
|
|
var payload = lazyComponent._payload;
|
|
var init = lazyComponent._init;
|
|
try {
|
|
return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
|
|
} catch (x) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
function describeFiber(fiber) {
|
|
var owner = fiber._debugOwner ? fiber._debugOwner.type : null;
|
|
var source = fiber._debugSource;
|
|
switch (fiber.tag) {
|
|
case HostComponent:
|
|
return describeBuiltInComponentFrame(fiber.type);
|
|
case LazyComponent:
|
|
return describeBuiltInComponentFrame("Lazy");
|
|
case SuspenseComponent:
|
|
return describeBuiltInComponentFrame("Suspense");
|
|
case SuspenseListComponent:
|
|
return describeBuiltInComponentFrame("SuspenseList");
|
|
case FunctionComponent:
|
|
case IndeterminateComponent:
|
|
case SimpleMemoComponent:
|
|
return describeFunctionComponentFrame(fiber.type);
|
|
case ForwardRef:
|
|
return describeFunctionComponentFrame(fiber.type.render);
|
|
case ClassComponent:
|
|
return describeClassComponentFrame(fiber.type);
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
function getStackByFiberInDevAndProd(workInProgress2) {
|
|
try {
|
|
var info = "";
|
|
var node = workInProgress2;
|
|
do {
|
|
info += describeFiber(node);
|
|
node = node.return;
|
|
} while (node);
|
|
return info;
|
|
} catch (x) {
|
|
return "\nError generating stack: " + x.message + "\n" + x.stack;
|
|
}
|
|
}
|
|
function getWrappedName(outerType, innerType, wrapperName) {
|
|
var displayName = outerType.displayName;
|
|
if (displayName) {
|
|
return displayName;
|
|
}
|
|
var functionName = innerType.displayName || innerType.name || "";
|
|
return functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName;
|
|
}
|
|
function getContextName(type) {
|
|
return type.displayName || "Context";
|
|
}
|
|
function getComponentNameFromType(type) {
|
|
if (type == null) {
|
|
return null;
|
|
}
|
|
{
|
|
if (typeof type.tag === "number") {
|
|
error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
if (typeof type === "function") {
|
|
return type.displayName || type.name || null;
|
|
}
|
|
if (typeof type === "string") {
|
|
return type;
|
|
}
|
|
switch (type) {
|
|
case REACT_FRAGMENT_TYPE:
|
|
return "Fragment";
|
|
case REACT_PORTAL_TYPE:
|
|
return "Portal";
|
|
case REACT_PROFILER_TYPE:
|
|
return "Profiler";
|
|
case REACT_STRICT_MODE_TYPE:
|
|
return "StrictMode";
|
|
case REACT_SUSPENSE_TYPE:
|
|
return "Suspense";
|
|
case REACT_SUSPENSE_LIST_TYPE:
|
|
return "SuspenseList";
|
|
}
|
|
if (typeof type === "object") {
|
|
switch (type.$$typeof) {
|
|
case REACT_CONTEXT_TYPE:
|
|
var context = type;
|
|
return getContextName(context) + ".Consumer";
|
|
case REACT_PROVIDER_TYPE:
|
|
var provider = type;
|
|
return getContextName(provider._context) + ".Provider";
|
|
case REACT_FORWARD_REF_TYPE:
|
|
return getWrappedName(type, type.render, "ForwardRef");
|
|
case REACT_MEMO_TYPE:
|
|
var outerName = type.displayName || null;
|
|
if (outerName !== null) {
|
|
return outerName;
|
|
}
|
|
return getComponentNameFromType(type.type) || "Memo";
|
|
case REACT_LAZY_TYPE: {
|
|
var lazyComponent = type;
|
|
var payload = lazyComponent._payload;
|
|
var init = lazyComponent._init;
|
|
try {
|
|
return getComponentNameFromType(init(payload));
|
|
} catch (x) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function getWrappedName$1(outerType, innerType, wrapperName) {
|
|
var functionName = innerType.displayName || innerType.name || "";
|
|
return outerType.displayName || (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName);
|
|
}
|
|
function getContextName$1(type) {
|
|
return type.displayName || "Context";
|
|
}
|
|
function getComponentNameFromFiber(fiber) {
|
|
var tag = fiber.tag, type = fiber.type;
|
|
switch (tag) {
|
|
case CacheComponent:
|
|
return "Cache";
|
|
case ContextConsumer:
|
|
var context = type;
|
|
return getContextName$1(context) + ".Consumer";
|
|
case ContextProvider:
|
|
var provider = type;
|
|
return getContextName$1(provider._context) + ".Provider";
|
|
case DehydratedFragment:
|
|
return "DehydratedFragment";
|
|
case ForwardRef:
|
|
return getWrappedName$1(type, type.render, "ForwardRef");
|
|
case Fragment2:
|
|
return "Fragment";
|
|
case HostComponent:
|
|
return type;
|
|
case HostPortal:
|
|
return "Portal";
|
|
case HostRoot:
|
|
return "Root";
|
|
case HostText:
|
|
return "Text";
|
|
case LazyComponent:
|
|
return getComponentNameFromType(type);
|
|
case Mode:
|
|
if (type === REACT_STRICT_MODE_TYPE) {
|
|
return "StrictMode";
|
|
}
|
|
return "Mode";
|
|
case OffscreenComponent:
|
|
return "Offscreen";
|
|
case Profiler:
|
|
return "Profiler";
|
|
case ScopeComponent:
|
|
return "Scope";
|
|
case SuspenseComponent:
|
|
return "Suspense";
|
|
case SuspenseListComponent:
|
|
return "SuspenseList";
|
|
case TracingMarkerComponent:
|
|
return "TracingMarker";
|
|
case ClassComponent:
|
|
case FunctionComponent:
|
|
case IncompleteClassComponent:
|
|
case IndeterminateComponent:
|
|
case MemoComponent:
|
|
case SimpleMemoComponent:
|
|
if (typeof type === "function") {
|
|
return type.displayName || type.name || null;
|
|
}
|
|
if (typeof type === "string") {
|
|
return type;
|
|
}
|
|
break;
|
|
}
|
|
return null;
|
|
}
|
|
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
var current = null;
|
|
var isRendering = false;
|
|
function getCurrentFiberOwnerNameInDevOrNull() {
|
|
{
|
|
if (current === null) {
|
|
return null;
|
|
}
|
|
var owner = current._debugOwner;
|
|
if (owner !== null && typeof owner !== "undefined") {
|
|
return getComponentNameFromFiber(owner);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function getCurrentFiberStackInDev() {
|
|
{
|
|
if (current === null) {
|
|
return "";
|
|
}
|
|
return getStackByFiberInDevAndProd(current);
|
|
}
|
|
}
|
|
function resetCurrentFiber() {
|
|
{
|
|
ReactDebugCurrentFrame.getCurrentStack = null;
|
|
current = null;
|
|
isRendering = false;
|
|
}
|
|
}
|
|
function setCurrentFiber(fiber) {
|
|
{
|
|
ReactDebugCurrentFrame.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev;
|
|
current = fiber;
|
|
isRendering = false;
|
|
}
|
|
}
|
|
function getCurrentFiber() {
|
|
{
|
|
return current;
|
|
}
|
|
}
|
|
function setIsRendering(rendering) {
|
|
{
|
|
isRendering = rendering;
|
|
}
|
|
}
|
|
function toString(value) {
|
|
return "" + value;
|
|
}
|
|
function getToStringValue(value) {
|
|
switch (typeof value) {
|
|
case "boolean":
|
|
case "number":
|
|
case "string":
|
|
case "undefined":
|
|
return value;
|
|
case "object":
|
|
{
|
|
checkFormFieldValueStringCoercion(value);
|
|
}
|
|
return value;
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
var hasReadOnlyValue = {
|
|
button: true,
|
|
checkbox: true,
|
|
image: true,
|
|
hidden: true,
|
|
radio: true,
|
|
reset: true,
|
|
submit: true
|
|
};
|
|
function checkControlledValueProps(tagName, props) {
|
|
{
|
|
if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
|
|
error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.");
|
|
}
|
|
if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
|
|
error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.");
|
|
}
|
|
}
|
|
}
|
|
function isCheckable(elem) {
|
|
var type = elem.type;
|
|
var nodeName = elem.nodeName;
|
|
return nodeName && nodeName.toLowerCase() === "input" && (type === "checkbox" || type === "radio");
|
|
}
|
|
function getTracker(node) {
|
|
return node._valueTracker;
|
|
}
|
|
function detachTracker(node) {
|
|
node._valueTracker = null;
|
|
}
|
|
function getValueFromNode(node) {
|
|
var value = "";
|
|
if (!node) {
|
|
return value;
|
|
}
|
|
if (isCheckable(node)) {
|
|
value = node.checked ? "true" : "false";
|
|
} else {
|
|
value = node.value;
|
|
}
|
|
return value;
|
|
}
|
|
function trackValueOnNode(node) {
|
|
var valueField = isCheckable(node) ? "checked" : "value";
|
|
var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
|
|
{
|
|
checkFormFieldValueStringCoercion(node[valueField]);
|
|
}
|
|
var currentValue = "" + node[valueField];
|
|
if (node.hasOwnProperty(valueField) || typeof descriptor === "undefined" || typeof descriptor.get !== "function" || typeof descriptor.set !== "function") {
|
|
return;
|
|
}
|
|
var get2 = descriptor.get, set2 = descriptor.set;
|
|
Object.defineProperty(node, valueField, {
|
|
configurable: true,
|
|
get: function() {
|
|
return get2.call(this);
|
|
},
|
|
set: function(value) {
|
|
{
|
|
checkFormFieldValueStringCoercion(value);
|
|
}
|
|
currentValue = "" + value;
|
|
set2.call(this, value);
|
|
}
|
|
});
|
|
Object.defineProperty(node, valueField, {
|
|
enumerable: descriptor.enumerable
|
|
});
|
|
var tracker = {
|
|
getValue: function() {
|
|
return currentValue;
|
|
},
|
|
setValue: function(value) {
|
|
{
|
|
checkFormFieldValueStringCoercion(value);
|
|
}
|
|
currentValue = "" + value;
|
|
},
|
|
stopTracking: function() {
|
|
detachTracker(node);
|
|
delete node[valueField];
|
|
}
|
|
};
|
|
return tracker;
|
|
}
|
|
function track(node) {
|
|
if (getTracker(node)) {
|
|
return;
|
|
}
|
|
node._valueTracker = trackValueOnNode(node);
|
|
}
|
|
function updateValueIfChanged(node) {
|
|
if (!node) {
|
|
return false;
|
|
}
|
|
var tracker = getTracker(node);
|
|
if (!tracker) {
|
|
return true;
|
|
}
|
|
var lastValue = tracker.getValue();
|
|
var nextValue = getValueFromNode(node);
|
|
if (nextValue !== lastValue) {
|
|
tracker.setValue(nextValue);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function getActiveElement(doc) {
|
|
doc = doc || (typeof document !== "undefined" ? document : void 0);
|
|
if (typeof doc === "undefined") {
|
|
return null;
|
|
}
|
|
try {
|
|
return doc.activeElement || doc.body;
|
|
} catch (e) {
|
|
return doc.body;
|
|
}
|
|
}
|
|
var didWarnValueDefaultValue = false;
|
|
var didWarnCheckedDefaultChecked = false;
|
|
var didWarnControlledToUncontrolled = false;
|
|
var didWarnUncontrolledToControlled = false;
|
|
function isControlled(props) {
|
|
var usesChecked = props.type === "checkbox" || props.type === "radio";
|
|
return usesChecked ? props.checked != null : props.value != null;
|
|
}
|
|
function getHostProps(element, props) {
|
|
var node = element;
|
|
var checked = props.checked;
|
|
var hostProps = assign({}, props, {
|
|
defaultChecked: void 0,
|
|
defaultValue: void 0,
|
|
value: void 0,
|
|
checked: checked != null ? checked : node._wrapperState.initialChecked
|
|
});
|
|
return hostProps;
|
|
}
|
|
function initWrapperState(element, props) {
|
|
{
|
|
checkControlledValueProps("input", props);
|
|
if (props.checked !== void 0 && props.defaultChecked !== void 0 && !didWarnCheckedDefaultChecked) {
|
|
error("%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components", getCurrentFiberOwnerNameInDevOrNull() || "A component", props.type);
|
|
didWarnCheckedDefaultChecked = true;
|
|
}
|
|
if (props.value !== void 0 && props.defaultValue !== void 0 && !didWarnValueDefaultValue) {
|
|
error("%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components", getCurrentFiberOwnerNameInDevOrNull() || "A component", props.type);
|
|
didWarnValueDefaultValue = true;
|
|
}
|
|
}
|
|
var node = element;
|
|
var defaultValue = props.defaultValue == null ? "" : props.defaultValue;
|
|
node._wrapperState = {
|
|
initialChecked: props.checked != null ? props.checked : props.defaultChecked,
|
|
initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
|
|
controlled: isControlled(props)
|
|
};
|
|
}
|
|
function updateChecked(element, props) {
|
|
var node = element;
|
|
var checked = props.checked;
|
|
if (checked != null) {
|
|
setValueForProperty(node, "checked", checked, false);
|
|
}
|
|
}
|
|
function updateWrapper(element, props) {
|
|
var node = element;
|
|
{
|
|
var controlled = isControlled(props);
|
|
if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
|
|
error("A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components");
|
|
didWarnUncontrolledToControlled = true;
|
|
}
|
|
if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
|
|
error("A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components");
|
|
didWarnControlledToUncontrolled = true;
|
|
}
|
|
}
|
|
updateChecked(element, props);
|
|
var value = getToStringValue(props.value);
|
|
var type = props.type;
|
|
if (value != null) {
|
|
if (type === "number") {
|
|
if (value === 0 && node.value === "" || node.value != value) {
|
|
node.value = toString(value);
|
|
}
|
|
} else if (node.value !== toString(value)) {
|
|
node.value = toString(value);
|
|
}
|
|
} else if (type === "submit" || type === "reset") {
|
|
node.removeAttribute("value");
|
|
return;
|
|
}
|
|
{
|
|
if (props.hasOwnProperty("value")) {
|
|
setDefaultValue(node, props.type, value);
|
|
} else if (props.hasOwnProperty("defaultValue")) {
|
|
setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
|
|
}
|
|
}
|
|
{
|
|
if (props.checked == null && props.defaultChecked != null) {
|
|
node.defaultChecked = !!props.defaultChecked;
|
|
}
|
|
}
|
|
}
|
|
function postMountWrapper(element, props, isHydrating2) {
|
|
var node = element;
|
|
if (props.hasOwnProperty("value") || props.hasOwnProperty("defaultValue")) {
|
|
var type = props.type;
|
|
var isButton = type === "submit" || type === "reset";
|
|
if (isButton && (props.value === void 0 || props.value === null)) {
|
|
return;
|
|
}
|
|
var initialValue = toString(node._wrapperState.initialValue);
|
|
if (!isHydrating2) {
|
|
{
|
|
if (initialValue !== node.value) {
|
|
node.value = initialValue;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
node.defaultValue = initialValue;
|
|
}
|
|
}
|
|
var name = node.name;
|
|
if (name !== "") {
|
|
node.name = "";
|
|
}
|
|
{
|
|
node.defaultChecked = !node.defaultChecked;
|
|
node.defaultChecked = !!node._wrapperState.initialChecked;
|
|
}
|
|
if (name !== "") {
|
|
node.name = name;
|
|
}
|
|
}
|
|
function restoreControlledState(element, props) {
|
|
var node = element;
|
|
updateWrapper(node, props);
|
|
updateNamedCousins(node, props);
|
|
}
|
|
function updateNamedCousins(rootNode, props) {
|
|
var name = props.name;
|
|
if (props.type === "radio" && name != null) {
|
|
var queryRoot = rootNode;
|
|
while (queryRoot.parentNode) {
|
|
queryRoot = queryRoot.parentNode;
|
|
}
|
|
{
|
|
checkAttributeStringCoercion(name, "name");
|
|
}
|
|
var group = queryRoot.querySelectorAll("input[name=" + JSON.stringify("" + name) + '][type="radio"]');
|
|
for (var i = 0; i < group.length; i++) {
|
|
var otherNode = group[i];
|
|
if (otherNode === rootNode || otherNode.form !== rootNode.form) {
|
|
continue;
|
|
}
|
|
var otherProps = getFiberCurrentPropsFromNode(otherNode);
|
|
if (!otherProps) {
|
|
throw new Error("ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.");
|
|
}
|
|
updateValueIfChanged(otherNode);
|
|
updateWrapper(otherNode, otherProps);
|
|
}
|
|
}
|
|
}
|
|
function setDefaultValue(node, type, value) {
|
|
if (type !== "number" || getActiveElement(node.ownerDocument) !== node) {
|
|
if (value == null) {
|
|
node.defaultValue = toString(node._wrapperState.initialValue);
|
|
} else if (node.defaultValue !== toString(value)) {
|
|
node.defaultValue = toString(value);
|
|
}
|
|
}
|
|
}
|
|
var didWarnSelectedSetOnOption = false;
|
|
var didWarnInvalidChild = false;
|
|
var didWarnInvalidInnerHTML = false;
|
|
function validateProps(element, props) {
|
|
{
|
|
if (props.value == null) {
|
|
if (typeof props.children === "object" && props.children !== null) {
|
|
React4.Children.forEach(props.children, function(child) {
|
|
if (child == null) {
|
|
return;
|
|
}
|
|
if (typeof child === "string" || typeof child === "number") {
|
|
return;
|
|
}
|
|
if (!didWarnInvalidChild) {
|
|
didWarnInvalidChild = true;
|
|
error("Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to <option>.");
|
|
}
|
|
});
|
|
} else if (props.dangerouslySetInnerHTML != null) {
|
|
if (!didWarnInvalidInnerHTML) {
|
|
didWarnInvalidInnerHTML = true;
|
|
error("Pass a `value` prop if you set dangerouslyInnerHTML so React knows which value should be selected.");
|
|
}
|
|
}
|
|
}
|
|
if (props.selected != null && !didWarnSelectedSetOnOption) {
|
|
error("Use the `defaultValue` or `value` props on <select> instead of setting `selected` on <option>.");
|
|
didWarnSelectedSetOnOption = true;
|
|
}
|
|
}
|
|
}
|
|
function postMountWrapper$1(element, props) {
|
|
if (props.value != null) {
|
|
element.setAttribute("value", toString(getToStringValue(props.value)));
|
|
}
|
|
}
|
|
var isArrayImpl = Array.isArray;
|
|
function isArray(a) {
|
|
return isArrayImpl(a);
|
|
}
|
|
var didWarnValueDefaultValue$1;
|
|
{
|
|
didWarnValueDefaultValue$1 = false;
|
|
}
|
|
function getDeclarationErrorAddendum() {
|
|
var ownerName = getCurrentFiberOwnerNameInDevOrNull();
|
|
if (ownerName) {
|
|
return "\n\nCheck the render method of `" + ownerName + "`.";
|
|
}
|
|
return "";
|
|
}
|
|
var valuePropNames = ["value", "defaultValue"];
|
|
function checkSelectPropTypes(props) {
|
|
{
|
|
checkControlledValueProps("select", props);
|
|
for (var i = 0; i < valuePropNames.length; i++) {
|
|
var propName = valuePropNames[i];
|
|
if (props[propName] == null) {
|
|
continue;
|
|
}
|
|
var propNameIsArray = isArray(props[propName]);
|
|
if (props.multiple && !propNameIsArray) {
|
|
error("The `%s` prop supplied to <select> must be an array if `multiple` is true.%s", propName, getDeclarationErrorAddendum());
|
|
} else if (!props.multiple && propNameIsArray) {
|
|
error("The `%s` prop supplied to <select> must be a scalar value if `multiple` is false.%s", propName, getDeclarationErrorAddendum());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function updateOptions(node, multiple, propValue, setDefaultSelected) {
|
|
var options2 = node.options;
|
|
if (multiple) {
|
|
var selectedValues = propValue;
|
|
var selectedValue = {};
|
|
for (var i = 0; i < selectedValues.length; i++) {
|
|
selectedValue["$" + selectedValues[i]] = true;
|
|
}
|
|
for (var _i = 0; _i < options2.length; _i++) {
|
|
var selected = selectedValue.hasOwnProperty("$" + options2[_i].value);
|
|
if (options2[_i].selected !== selected) {
|
|
options2[_i].selected = selected;
|
|
}
|
|
if (selected && setDefaultSelected) {
|
|
options2[_i].defaultSelected = true;
|
|
}
|
|
}
|
|
} else {
|
|
var _selectedValue = toString(getToStringValue(propValue));
|
|
var defaultSelected = null;
|
|
for (var _i2 = 0; _i2 < options2.length; _i2++) {
|
|
if (options2[_i2].value === _selectedValue) {
|
|
options2[_i2].selected = true;
|
|
if (setDefaultSelected) {
|
|
options2[_i2].defaultSelected = true;
|
|
}
|
|
return;
|
|
}
|
|
if (defaultSelected === null && !options2[_i2].disabled) {
|
|
defaultSelected = options2[_i2];
|
|
}
|
|
}
|
|
if (defaultSelected !== null) {
|
|
defaultSelected.selected = true;
|
|
}
|
|
}
|
|
}
|
|
function getHostProps$1(element, props) {
|
|
return assign({}, props, {
|
|
value: void 0
|
|
});
|
|
}
|
|
function initWrapperState$1(element, props) {
|
|
var node = element;
|
|
{
|
|
checkSelectPropTypes(props);
|
|
}
|
|
node._wrapperState = {
|
|
wasMultiple: !!props.multiple
|
|
};
|
|
{
|
|
if (props.value !== void 0 && props.defaultValue !== void 0 && !didWarnValueDefaultValue$1) {
|
|
error("Select elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled select element and remove one of these props. More info: https://reactjs.org/link/controlled-components");
|
|
didWarnValueDefaultValue$1 = true;
|
|
}
|
|
}
|
|
}
|
|
function postMountWrapper$2(element, props) {
|
|
var node = element;
|
|
node.multiple = !!props.multiple;
|
|
var value = props.value;
|
|
if (value != null) {
|
|
updateOptions(node, !!props.multiple, value, false);
|
|
} else if (props.defaultValue != null) {
|
|
updateOptions(node, !!props.multiple, props.defaultValue, true);
|
|
}
|
|
}
|
|
function postUpdateWrapper(element, props) {
|
|
var node = element;
|
|
var wasMultiple = node._wrapperState.wasMultiple;
|
|
node._wrapperState.wasMultiple = !!props.multiple;
|
|
var value = props.value;
|
|
if (value != null) {
|
|
updateOptions(node, !!props.multiple, value, false);
|
|
} else if (wasMultiple !== !!props.multiple) {
|
|
if (props.defaultValue != null) {
|
|
updateOptions(node, !!props.multiple, props.defaultValue, true);
|
|
} else {
|
|
updateOptions(node, !!props.multiple, props.multiple ? [] : "", false);
|
|
}
|
|
}
|
|
}
|
|
function restoreControlledState$1(element, props) {
|
|
var node = element;
|
|
var value = props.value;
|
|
if (value != null) {
|
|
updateOptions(node, !!props.multiple, value, false);
|
|
}
|
|
}
|
|
var didWarnValDefaultVal = false;
|
|
function getHostProps$2(element, props) {
|
|
var node = element;
|
|
if (props.dangerouslySetInnerHTML != null) {
|
|
throw new Error("`dangerouslySetInnerHTML` does not make sense on <textarea>.");
|
|
}
|
|
var hostProps = assign({}, props, {
|
|
value: void 0,
|
|
defaultValue: void 0,
|
|
children: toString(node._wrapperState.initialValue)
|
|
});
|
|
return hostProps;
|
|
}
|
|
function initWrapperState$2(element, props) {
|
|
var node = element;
|
|
{
|
|
checkControlledValueProps("textarea", props);
|
|
if (props.value !== void 0 && props.defaultValue !== void 0 && !didWarnValDefaultVal) {
|
|
error("%s contains a textarea with both value and defaultValue props. Textarea elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled textarea and remove one of these props. More info: https://reactjs.org/link/controlled-components", getCurrentFiberOwnerNameInDevOrNull() || "A component");
|
|
didWarnValDefaultVal = true;
|
|
}
|
|
}
|
|
var initialValue = props.value;
|
|
if (initialValue == null) {
|
|
var children = props.children, defaultValue = props.defaultValue;
|
|
if (children != null) {
|
|
{
|
|
error("Use the `defaultValue` or `value` props instead of setting children on <textarea>.");
|
|
}
|
|
{
|
|
if (defaultValue != null) {
|
|
throw new Error("If you supply `defaultValue` on a <textarea>, do not pass children.");
|
|
}
|
|
if (isArray(children)) {
|
|
if (children.length > 1) {
|
|
throw new Error("<textarea> can only have at most one child.");
|
|
}
|
|
children = children[0];
|
|
}
|
|
defaultValue = children;
|
|
}
|
|
}
|
|
if (defaultValue == null) {
|
|
defaultValue = "";
|
|
}
|
|
initialValue = defaultValue;
|
|
}
|
|
node._wrapperState = {
|
|
initialValue: getToStringValue(initialValue)
|
|
};
|
|
}
|
|
function updateWrapper$1(element, props) {
|
|
var node = element;
|
|
var value = getToStringValue(props.value);
|
|
var defaultValue = getToStringValue(props.defaultValue);
|
|
if (value != null) {
|
|
var newValue = toString(value);
|
|
if (newValue !== node.value) {
|
|
node.value = newValue;
|
|
}
|
|
if (props.defaultValue == null && node.defaultValue !== newValue) {
|
|
node.defaultValue = newValue;
|
|
}
|
|
}
|
|
if (defaultValue != null) {
|
|
node.defaultValue = toString(defaultValue);
|
|
}
|
|
}
|
|
function postMountWrapper$3(element, props) {
|
|
var node = element;
|
|
var textContent = node.textContent;
|
|
if (textContent === node._wrapperState.initialValue) {
|
|
if (textContent !== "" && textContent !== null) {
|
|
node.value = textContent;
|
|
}
|
|
}
|
|
}
|
|
function restoreControlledState$2(element, props) {
|
|
updateWrapper$1(element, props);
|
|
}
|
|
var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|
var MATH_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
|
|
var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
function getIntrinsicNamespace(type) {
|
|
switch (type) {
|
|
case "svg":
|
|
return SVG_NAMESPACE;
|
|
case "math":
|
|
return MATH_NAMESPACE;
|
|
default:
|
|
return HTML_NAMESPACE;
|
|
}
|
|
}
|
|
function getChildNamespace(parentNamespace, type) {
|
|
if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
|
|
return getIntrinsicNamespace(type);
|
|
}
|
|
if (parentNamespace === SVG_NAMESPACE && type === "foreignObject") {
|
|
return HTML_NAMESPACE;
|
|
}
|
|
return parentNamespace;
|
|
}
|
|
var createMicrosoftUnsafeLocalFunction = function(func) {
|
|
if (typeof MSApp !== "undefined" && MSApp.execUnsafeLocalFunction) {
|
|
return function(arg0, arg1, arg2, arg3) {
|
|
MSApp.execUnsafeLocalFunction(function() {
|
|
return func(arg0, arg1, arg2, arg3);
|
|
});
|
|
};
|
|
} else {
|
|
return func;
|
|
}
|
|
};
|
|
var reusableSVGContainer;
|
|
var setInnerHTML = createMicrosoftUnsafeLocalFunction(function(node, html) {
|
|
if (node.namespaceURI === SVG_NAMESPACE) {
|
|
if (!("innerHTML" in node)) {
|
|
reusableSVGContainer = reusableSVGContainer || document.createElement("div");
|
|
reusableSVGContainer.innerHTML = "<svg>" + html.valueOf().toString() + "</svg>";
|
|
var svgNode = reusableSVGContainer.firstChild;
|
|
while (node.firstChild) {
|
|
node.removeChild(node.firstChild);
|
|
}
|
|
while (svgNode.firstChild) {
|
|
node.appendChild(svgNode.firstChild);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
node.innerHTML = html;
|
|
});
|
|
var ELEMENT_NODE = 1;
|
|
var TEXT_NODE = 3;
|
|
var COMMENT_NODE = 8;
|
|
var DOCUMENT_NODE = 9;
|
|
var DOCUMENT_FRAGMENT_NODE = 11;
|
|
var setTextContent = function(node, text) {
|
|
if (text) {
|
|
var firstChild = node.firstChild;
|
|
if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
|
|
firstChild.nodeValue = text;
|
|
return;
|
|
}
|
|
}
|
|
node.textContent = text;
|
|
};
|
|
var shorthandToLonghand = {
|
|
animation: ["animationDelay", "animationDirection", "animationDuration", "animationFillMode", "animationIterationCount", "animationName", "animationPlayState", "animationTimingFunction"],
|
|
background: ["backgroundAttachment", "backgroundClip", "backgroundColor", "backgroundImage", "backgroundOrigin", "backgroundPositionX", "backgroundPositionY", "backgroundRepeat", "backgroundSize"],
|
|
backgroundPosition: ["backgroundPositionX", "backgroundPositionY"],
|
|
border: ["borderBottomColor", "borderBottomStyle", "borderBottomWidth", "borderImageOutset", "borderImageRepeat", "borderImageSlice", "borderImageSource", "borderImageWidth", "borderLeftColor", "borderLeftStyle", "borderLeftWidth", "borderRightColor", "borderRightStyle", "borderRightWidth", "borderTopColor", "borderTopStyle", "borderTopWidth"],
|
|
borderBlockEnd: ["borderBlockEndColor", "borderBlockEndStyle", "borderBlockEndWidth"],
|
|
borderBlockStart: ["borderBlockStartColor", "borderBlockStartStyle", "borderBlockStartWidth"],
|
|
borderBottom: ["borderBottomColor", "borderBottomStyle", "borderBottomWidth"],
|
|
borderColor: ["borderBottomColor", "borderLeftColor", "borderRightColor", "borderTopColor"],
|
|
borderImage: ["borderImageOutset", "borderImageRepeat", "borderImageSlice", "borderImageSource", "borderImageWidth"],
|
|
borderInlineEnd: ["borderInlineEndColor", "borderInlineEndStyle", "borderInlineEndWidth"],
|
|
borderInlineStart: ["borderInlineStartColor", "borderInlineStartStyle", "borderInlineStartWidth"],
|
|
borderLeft: ["borderLeftColor", "borderLeftStyle", "borderLeftWidth"],
|
|
borderRadius: ["borderBottomLeftRadius", "borderBottomRightRadius", "borderTopLeftRadius", "borderTopRightRadius"],
|
|
borderRight: ["borderRightColor", "borderRightStyle", "borderRightWidth"],
|
|
borderStyle: ["borderBottomStyle", "borderLeftStyle", "borderRightStyle", "borderTopStyle"],
|
|
borderTop: ["borderTopColor", "borderTopStyle", "borderTopWidth"],
|
|
borderWidth: ["borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth"],
|
|
columnRule: ["columnRuleColor", "columnRuleStyle", "columnRuleWidth"],
|
|
columns: ["columnCount", "columnWidth"],
|
|
flex: ["flexBasis", "flexGrow", "flexShrink"],
|
|
flexFlow: ["flexDirection", "flexWrap"],
|
|
font: ["fontFamily", "fontFeatureSettings", "fontKerning", "fontLanguageOverride", "fontSize", "fontSizeAdjust", "fontStretch", "fontStyle", "fontVariant", "fontVariantAlternates", "fontVariantCaps", "fontVariantEastAsian", "fontVariantLigatures", "fontVariantNumeric", "fontVariantPosition", "fontWeight", "lineHeight"],
|
|
fontVariant: ["fontVariantAlternates", "fontVariantCaps", "fontVariantEastAsian", "fontVariantLigatures", "fontVariantNumeric", "fontVariantPosition"],
|
|
gap: ["columnGap", "rowGap"],
|
|
grid: ["gridAutoColumns", "gridAutoFlow", "gridAutoRows", "gridTemplateAreas", "gridTemplateColumns", "gridTemplateRows"],
|
|
gridArea: ["gridColumnEnd", "gridColumnStart", "gridRowEnd", "gridRowStart"],
|
|
gridColumn: ["gridColumnEnd", "gridColumnStart"],
|
|
gridColumnGap: ["columnGap"],
|
|
gridGap: ["columnGap", "rowGap"],
|
|
gridRow: ["gridRowEnd", "gridRowStart"],
|
|
gridRowGap: ["rowGap"],
|
|
gridTemplate: ["gridTemplateAreas", "gridTemplateColumns", "gridTemplateRows"],
|
|
listStyle: ["listStyleImage", "listStylePosition", "listStyleType"],
|
|
margin: ["marginBottom", "marginLeft", "marginRight", "marginTop"],
|
|
marker: ["markerEnd", "markerMid", "markerStart"],
|
|
mask: ["maskClip", "maskComposite", "maskImage", "maskMode", "maskOrigin", "maskPositionX", "maskPositionY", "maskRepeat", "maskSize"],
|
|
maskPosition: ["maskPositionX", "maskPositionY"],
|
|
outline: ["outlineColor", "outlineStyle", "outlineWidth"],
|
|
overflow: ["overflowX", "overflowY"],
|
|
padding: ["paddingBottom", "paddingLeft", "paddingRight", "paddingTop"],
|
|
placeContent: ["alignContent", "justifyContent"],
|
|
placeItems: ["alignItems", "justifyItems"],
|
|
placeSelf: ["alignSelf", "justifySelf"],
|
|
textDecoration: ["textDecorationColor", "textDecorationLine", "textDecorationStyle"],
|
|
textEmphasis: ["textEmphasisColor", "textEmphasisStyle"],
|
|
transition: ["transitionDelay", "transitionDuration", "transitionProperty", "transitionTimingFunction"],
|
|
wordWrap: ["overflowWrap"]
|
|
};
|
|
var isUnitlessNumber = {
|
|
animationIterationCount: true,
|
|
aspectRatio: true,
|
|
borderImageOutset: true,
|
|
borderImageSlice: true,
|
|
borderImageWidth: true,
|
|
boxFlex: true,
|
|
boxFlexGroup: true,
|
|
boxOrdinalGroup: true,
|
|
columnCount: true,
|
|
columns: true,
|
|
flex: true,
|
|
flexGrow: true,
|
|
flexPositive: true,
|
|
flexShrink: true,
|
|
flexNegative: true,
|
|
flexOrder: true,
|
|
gridArea: true,
|
|
gridRow: true,
|
|
gridRowEnd: true,
|
|
gridRowSpan: true,
|
|
gridRowStart: true,
|
|
gridColumn: true,
|
|
gridColumnEnd: true,
|
|
gridColumnSpan: true,
|
|
gridColumnStart: true,
|
|
fontWeight: true,
|
|
lineClamp: true,
|
|
lineHeight: true,
|
|
opacity: true,
|
|
order: true,
|
|
orphans: true,
|
|
tabSize: true,
|
|
widows: true,
|
|
zIndex: true,
|
|
zoom: true,
|
|
fillOpacity: true,
|
|
floodOpacity: true,
|
|
stopOpacity: true,
|
|
strokeDasharray: true,
|
|
strokeDashoffset: true,
|
|
strokeMiterlimit: true,
|
|
strokeOpacity: true,
|
|
strokeWidth: true
|
|
};
|
|
function prefixKey(prefix2, key) {
|
|
return prefix2 + key.charAt(0).toUpperCase() + key.substring(1);
|
|
}
|
|
var prefixes = ["Webkit", "ms", "Moz", "O"];
|
|
Object.keys(isUnitlessNumber).forEach(function(prop) {
|
|
prefixes.forEach(function(prefix2) {
|
|
isUnitlessNumber[prefixKey(prefix2, prop)] = isUnitlessNumber[prop];
|
|
});
|
|
});
|
|
function dangerousStyleValue(name, value, isCustomProperty) {
|
|
var isEmpty = value == null || typeof value === "boolean" || value === "";
|
|
if (isEmpty) {
|
|
return "";
|
|
}
|
|
if (!isCustomProperty && typeof value === "number" && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
|
|
return value + "px";
|
|
}
|
|
{
|
|
checkCSSPropertyStringCoercion(value, name);
|
|
}
|
|
return ("" + value).trim();
|
|
}
|
|
var uppercasePattern = /([A-Z])/g;
|
|
var msPattern = /^ms-/;
|
|
function hyphenateStyleName(name) {
|
|
return name.replace(uppercasePattern, "-$1").toLowerCase().replace(msPattern, "-ms-");
|
|
}
|
|
var warnValidStyle = function() {
|
|
};
|
|
{
|
|
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
|
|
var msPattern$1 = /^-ms-/;
|
|
var hyphenPattern = /-(.)/g;
|
|
var badStyleValueWithSemicolonPattern = /;\s*$/;
|
|
var warnedStyleNames = {};
|
|
var warnedStyleValues = {};
|
|
var warnedForNaNValue = false;
|
|
var warnedForInfinityValue = false;
|
|
var camelize = function(string) {
|
|
return string.replace(hyphenPattern, function(_, character) {
|
|
return character.toUpperCase();
|
|
});
|
|
};
|
|
var warnHyphenatedStyleName = function(name) {
|
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
|
return;
|
|
}
|
|
warnedStyleNames[name] = true;
|
|
error("Unsupported style property %s. Did you mean %s?", name, camelize(name.replace(msPattern$1, "ms-")));
|
|
};
|
|
var warnBadVendoredStyleName = function(name) {
|
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
|
return;
|
|
}
|
|
warnedStyleNames[name] = true;
|
|
error("Unsupported vendor-prefixed style property %s. Did you mean %s?", name, name.charAt(0).toUpperCase() + name.slice(1));
|
|
};
|
|
var warnStyleValueWithSemicolon = function(name, value) {
|
|
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
|
|
return;
|
|
}
|
|
warnedStyleValues[value] = true;
|
|
error(`Style property values shouldn't contain a semicolon. Try "%s: %s" instead.`, name, value.replace(badStyleValueWithSemicolonPattern, ""));
|
|
};
|
|
var warnStyleValueIsNaN = function(name, value) {
|
|
if (warnedForNaNValue) {
|
|
return;
|
|
}
|
|
warnedForNaNValue = true;
|
|
error("`NaN` is an invalid value for the `%s` css style property.", name);
|
|
};
|
|
var warnStyleValueIsInfinity = function(name, value) {
|
|
if (warnedForInfinityValue) {
|
|
return;
|
|
}
|
|
warnedForInfinityValue = true;
|
|
error("`Infinity` is an invalid value for the `%s` css style property.", name);
|
|
};
|
|
warnValidStyle = function(name, value) {
|
|
if (name.indexOf("-") > -1) {
|
|
warnHyphenatedStyleName(name);
|
|
} else if (badVendoredStyleNamePattern.test(name)) {
|
|
warnBadVendoredStyleName(name);
|
|
} else if (badStyleValueWithSemicolonPattern.test(value)) {
|
|
warnStyleValueWithSemicolon(name, value);
|
|
}
|
|
if (typeof value === "number") {
|
|
if (isNaN(value)) {
|
|
warnStyleValueIsNaN(name, value);
|
|
} else if (!isFinite(value)) {
|
|
warnStyleValueIsInfinity(name, value);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
var warnValidStyle$1 = warnValidStyle;
|
|
function createDangerousStringForStyles(styles) {
|
|
{
|
|
var serialized = "";
|
|
var delimiter = "";
|
|
for (var styleName in styles) {
|
|
if (!styles.hasOwnProperty(styleName)) {
|
|
continue;
|
|
}
|
|
var styleValue = styles[styleName];
|
|
if (styleValue != null) {
|
|
var isCustomProperty = styleName.indexOf("--") === 0;
|
|
serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ":";
|
|
serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
|
|
delimiter = ";";
|
|
}
|
|
}
|
|
return serialized || null;
|
|
}
|
|
}
|
|
function setValueForStyles(node, styles) {
|
|
var style2 = node.style;
|
|
for (var styleName in styles) {
|
|
if (!styles.hasOwnProperty(styleName)) {
|
|
continue;
|
|
}
|
|
var isCustomProperty = styleName.indexOf("--") === 0;
|
|
{
|
|
if (!isCustomProperty) {
|
|
warnValidStyle$1(styleName, styles[styleName]);
|
|
}
|
|
}
|
|
var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
|
|
if (styleName === "float") {
|
|
styleName = "cssFloat";
|
|
}
|
|
if (isCustomProperty) {
|
|
style2.setProperty(styleName, styleValue);
|
|
} else {
|
|
style2[styleName] = styleValue;
|
|
}
|
|
}
|
|
}
|
|
function isValueEmpty(value) {
|
|
return value == null || typeof value === "boolean" || value === "";
|
|
}
|
|
function expandShorthandMap(styles) {
|
|
var expanded = {};
|
|
for (var key in styles) {
|
|
var longhands = shorthandToLonghand[key] || [key];
|
|
for (var i = 0; i < longhands.length; i++) {
|
|
expanded[longhands[i]] = key;
|
|
}
|
|
}
|
|
return expanded;
|
|
}
|
|
function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
|
|
{
|
|
if (!nextStyles) {
|
|
return;
|
|
}
|
|
var expandedUpdates = expandShorthandMap(styleUpdates);
|
|
var expandedStyles = expandShorthandMap(nextStyles);
|
|
var warnedAbout = {};
|
|
for (var key in expandedUpdates) {
|
|
var originalKey = expandedUpdates[key];
|
|
var correctOriginalKey = expandedStyles[key];
|
|
if (correctOriginalKey && originalKey !== correctOriginalKey) {
|
|
var warningKey = originalKey + "," + correctOriginalKey;
|
|
if (warnedAbout[warningKey]) {
|
|
continue;
|
|
}
|
|
warnedAbout[warningKey] = true;
|
|
error("%s a style property during rerender (%s) when a conflicting property is set (%s) can lead to styling bugs. To avoid this, don't mix shorthand and non-shorthand properties for the same value; instead, replace the shorthand with separate values.", isValueEmpty(styleUpdates[originalKey]) ? "Removing" : "Updating", originalKey, correctOriginalKey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var omittedCloseTags = {
|
|
area: true,
|
|
base: true,
|
|
br: true,
|
|
col: true,
|
|
embed: true,
|
|
hr: true,
|
|
img: true,
|
|
input: true,
|
|
keygen: true,
|
|
link: true,
|
|
meta: true,
|
|
param: true,
|
|
source: true,
|
|
track: true,
|
|
wbr: true
|
|
};
|
|
var voidElementTags = assign({
|
|
menuitem: true
|
|
}, omittedCloseTags);
|
|
var HTML = "__html";
|
|
function assertValidProps(tag, props) {
|
|
if (!props) {
|
|
return;
|
|
}
|
|
if (voidElementTags[tag]) {
|
|
if (props.children != null || props.dangerouslySetInnerHTML != null) {
|
|
throw new Error(tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.");
|
|
}
|
|
}
|
|
if (props.dangerouslySetInnerHTML != null) {
|
|
if (props.children != null) {
|
|
throw new Error("Can only set one of `children` or `props.dangerouslySetInnerHTML`.");
|
|
}
|
|
if (typeof props.dangerouslySetInnerHTML !== "object" || !(HTML in props.dangerouslySetInnerHTML)) {
|
|
throw new Error("`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://reactjs.org/link/dangerously-set-inner-html for more information.");
|
|
}
|
|
}
|
|
{
|
|
if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
|
|
error("A component is `contentEditable` and contains `children` managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.");
|
|
}
|
|
}
|
|
if (props.style != null && typeof props.style !== "object") {
|
|
throw new Error("The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.");
|
|
}
|
|
}
|
|
function isCustomComponent(tagName, props) {
|
|
if (tagName.indexOf("-") === -1) {
|
|
return typeof props.is === "string";
|
|
}
|
|
switch (tagName) {
|
|
case "annotation-xml":
|
|
case "color-profile":
|
|
case "font-face":
|
|
case "font-face-src":
|
|
case "font-face-uri":
|
|
case "font-face-format":
|
|
case "font-face-name":
|
|
case "missing-glyph":
|
|
return false;
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
var possibleStandardNames = {
|
|
accept: "accept",
|
|
acceptcharset: "acceptCharset",
|
|
"accept-charset": "acceptCharset",
|
|
accesskey: "accessKey",
|
|
action: "action",
|
|
allowfullscreen: "allowFullScreen",
|
|
alt: "alt",
|
|
as: "as",
|
|
async: "async",
|
|
autocapitalize: "autoCapitalize",
|
|
autocomplete: "autoComplete",
|
|
autocorrect: "autoCorrect",
|
|
autofocus: "autoFocus",
|
|
autoplay: "autoPlay",
|
|
autosave: "autoSave",
|
|
capture: "capture",
|
|
cellpadding: "cellPadding",
|
|
cellspacing: "cellSpacing",
|
|
challenge: "challenge",
|
|
charset: "charSet",
|
|
checked: "checked",
|
|
children: "children",
|
|
cite: "cite",
|
|
class: "className",
|
|
classid: "classID",
|
|
classname: "className",
|
|
cols: "cols",
|
|
colspan: "colSpan",
|
|
content: "content",
|
|
contenteditable: "contentEditable",
|
|
contextmenu: "contextMenu",
|
|
controls: "controls",
|
|
controlslist: "controlsList",
|
|
coords: "coords",
|
|
crossorigin: "crossOrigin",
|
|
dangerouslysetinnerhtml: "dangerouslySetInnerHTML",
|
|
data: "data",
|
|
datetime: "dateTime",
|
|
default: "default",
|
|
defaultchecked: "defaultChecked",
|
|
defaultvalue: "defaultValue",
|
|
defer: "defer",
|
|
dir: "dir",
|
|
disabled: "disabled",
|
|
disablepictureinpicture: "disablePictureInPicture",
|
|
disableremoteplayback: "disableRemotePlayback",
|
|
download: "download",
|
|
draggable: "draggable",
|
|
enctype: "encType",
|
|
enterkeyhint: "enterKeyHint",
|
|
for: "htmlFor",
|
|
form: "form",
|
|
formmethod: "formMethod",
|
|
formaction: "formAction",
|
|
formenctype: "formEncType",
|
|
formnovalidate: "formNoValidate",
|
|
formtarget: "formTarget",
|
|
frameborder: "frameBorder",
|
|
headers: "headers",
|
|
height: "height",
|
|
hidden: "hidden",
|
|
high: "high",
|
|
href: "href",
|
|
hreflang: "hrefLang",
|
|
htmlfor: "htmlFor",
|
|
httpequiv: "httpEquiv",
|
|
"http-equiv": "httpEquiv",
|
|
icon: "icon",
|
|
id: "id",
|
|
imagesizes: "imageSizes",
|
|
imagesrcset: "imageSrcSet",
|
|
innerhtml: "innerHTML",
|
|
inputmode: "inputMode",
|
|
integrity: "integrity",
|
|
is: "is",
|
|
itemid: "itemID",
|
|
itemprop: "itemProp",
|
|
itemref: "itemRef",
|
|
itemscope: "itemScope",
|
|
itemtype: "itemType",
|
|
keyparams: "keyParams",
|
|
keytype: "keyType",
|
|
kind: "kind",
|
|
label: "label",
|
|
lang: "lang",
|
|
list: "list",
|
|
loop: "loop",
|
|
low: "low",
|
|
manifest: "manifest",
|
|
marginwidth: "marginWidth",
|
|
marginheight: "marginHeight",
|
|
max: "max",
|
|
maxlength: "maxLength",
|
|
media: "media",
|
|
mediagroup: "mediaGroup",
|
|
method: "method",
|
|
min: "min",
|
|
minlength: "minLength",
|
|
multiple: "multiple",
|
|
muted: "muted",
|
|
name: "name",
|
|
nomodule: "noModule",
|
|
nonce: "nonce",
|
|
novalidate: "noValidate",
|
|
open: "open",
|
|
optimum: "optimum",
|
|
pattern: "pattern",
|
|
placeholder: "placeholder",
|
|
playsinline: "playsInline",
|
|
poster: "poster",
|
|
preload: "preload",
|
|
profile: "profile",
|
|
radiogroup: "radioGroup",
|
|
readonly: "readOnly",
|
|
referrerpolicy: "referrerPolicy",
|
|
rel: "rel",
|
|
required: "required",
|
|
reversed: "reversed",
|
|
role: "role",
|
|
rows: "rows",
|
|
rowspan: "rowSpan",
|
|
sandbox: "sandbox",
|
|
scope: "scope",
|
|
scoped: "scoped",
|
|
scrolling: "scrolling",
|
|
seamless: "seamless",
|
|
selected: "selected",
|
|
shape: "shape",
|
|
size: "size",
|
|
sizes: "sizes",
|
|
span: "span",
|
|
spellcheck: "spellCheck",
|
|
src: "src",
|
|
srcdoc: "srcDoc",
|
|
srclang: "srcLang",
|
|
srcset: "srcSet",
|
|
start: "start",
|
|
step: "step",
|
|
style: "style",
|
|
summary: "summary",
|
|
tabindex: "tabIndex",
|
|
target: "target",
|
|
title: "title",
|
|
type: "type",
|
|
usemap: "useMap",
|
|
value: "value",
|
|
width: "width",
|
|
wmode: "wmode",
|
|
wrap: "wrap",
|
|
about: "about",
|
|
accentheight: "accentHeight",
|
|
"accent-height": "accentHeight",
|
|
accumulate: "accumulate",
|
|
additive: "additive",
|
|
alignmentbaseline: "alignmentBaseline",
|
|
"alignment-baseline": "alignmentBaseline",
|
|
allowreorder: "allowReorder",
|
|
alphabetic: "alphabetic",
|
|
amplitude: "amplitude",
|
|
arabicform: "arabicForm",
|
|
"arabic-form": "arabicForm",
|
|
ascent: "ascent",
|
|
attributename: "attributeName",
|
|
attributetype: "attributeType",
|
|
autoreverse: "autoReverse",
|
|
azimuth: "azimuth",
|
|
basefrequency: "baseFrequency",
|
|
baselineshift: "baselineShift",
|
|
"baseline-shift": "baselineShift",
|
|
baseprofile: "baseProfile",
|
|
bbox: "bbox",
|
|
begin: "begin",
|
|
bias: "bias",
|
|
by: "by",
|
|
calcmode: "calcMode",
|
|
capheight: "capHeight",
|
|
"cap-height": "capHeight",
|
|
clip: "clip",
|
|
clippath: "clipPath",
|
|
"clip-path": "clipPath",
|
|
clippathunits: "clipPathUnits",
|
|
cliprule: "clipRule",
|
|
"clip-rule": "clipRule",
|
|
color: "color",
|
|
colorinterpolation: "colorInterpolation",
|
|
"color-interpolation": "colorInterpolation",
|
|
colorinterpolationfilters: "colorInterpolationFilters",
|
|
"color-interpolation-filters": "colorInterpolationFilters",
|
|
colorprofile: "colorProfile",
|
|
"color-profile": "colorProfile",
|
|
colorrendering: "colorRendering",
|
|
"color-rendering": "colorRendering",
|
|
contentscripttype: "contentScriptType",
|
|
contentstyletype: "contentStyleType",
|
|
cursor: "cursor",
|
|
cx: "cx",
|
|
cy: "cy",
|
|
d: "d",
|
|
datatype: "datatype",
|
|
decelerate: "decelerate",
|
|
descent: "descent",
|
|
diffuseconstant: "diffuseConstant",
|
|
direction: "direction",
|
|
display: "display",
|
|
divisor: "divisor",
|
|
dominantbaseline: "dominantBaseline",
|
|
"dominant-baseline": "dominantBaseline",
|
|
dur: "dur",
|
|
dx: "dx",
|
|
dy: "dy",
|
|
edgemode: "edgeMode",
|
|
elevation: "elevation",
|
|
enablebackground: "enableBackground",
|
|
"enable-background": "enableBackground",
|
|
end: "end",
|
|
exponent: "exponent",
|
|
externalresourcesrequired: "externalResourcesRequired",
|
|
fill: "fill",
|
|
fillopacity: "fillOpacity",
|
|
"fill-opacity": "fillOpacity",
|
|
fillrule: "fillRule",
|
|
"fill-rule": "fillRule",
|
|
filter: "filter",
|
|
filterres: "filterRes",
|
|
filterunits: "filterUnits",
|
|
floodopacity: "floodOpacity",
|
|
"flood-opacity": "floodOpacity",
|
|
floodcolor: "floodColor",
|
|
"flood-color": "floodColor",
|
|
focusable: "focusable",
|
|
fontfamily: "fontFamily",
|
|
"font-family": "fontFamily",
|
|
fontsize: "fontSize",
|
|
"font-size": "fontSize",
|
|
fontsizeadjust: "fontSizeAdjust",
|
|
"font-size-adjust": "fontSizeAdjust",
|
|
fontstretch: "fontStretch",
|
|
"font-stretch": "fontStretch",
|
|
fontstyle: "fontStyle",
|
|
"font-style": "fontStyle",
|
|
fontvariant: "fontVariant",
|
|
"font-variant": "fontVariant",
|
|
fontweight: "fontWeight",
|
|
"font-weight": "fontWeight",
|
|
format: "format",
|
|
from: "from",
|
|
fx: "fx",
|
|
fy: "fy",
|
|
g1: "g1",
|
|
g2: "g2",
|
|
glyphname: "glyphName",
|
|
"glyph-name": "glyphName",
|
|
glyphorientationhorizontal: "glyphOrientationHorizontal",
|
|
"glyph-orientation-horizontal": "glyphOrientationHorizontal",
|
|
glyphorientationvertical: "glyphOrientationVertical",
|
|
"glyph-orientation-vertical": "glyphOrientationVertical",
|
|
glyphref: "glyphRef",
|
|
gradienttransform: "gradientTransform",
|
|
gradientunits: "gradientUnits",
|
|
hanging: "hanging",
|
|
horizadvx: "horizAdvX",
|
|
"horiz-adv-x": "horizAdvX",
|
|
horizoriginx: "horizOriginX",
|
|
"horiz-origin-x": "horizOriginX",
|
|
ideographic: "ideographic",
|
|
imagerendering: "imageRendering",
|
|
"image-rendering": "imageRendering",
|
|
in2: "in2",
|
|
in: "in",
|
|
inlist: "inlist",
|
|
intercept: "intercept",
|
|
k1: "k1",
|
|
k2: "k2",
|
|
k3: "k3",
|
|
k4: "k4",
|
|
k: "k",
|
|
kernelmatrix: "kernelMatrix",
|
|
kernelunitlength: "kernelUnitLength",
|
|
kerning: "kerning",
|
|
keypoints: "keyPoints",
|
|
keysplines: "keySplines",
|
|
keytimes: "keyTimes",
|
|
lengthadjust: "lengthAdjust",
|
|
letterspacing: "letterSpacing",
|
|
"letter-spacing": "letterSpacing",
|
|
lightingcolor: "lightingColor",
|
|
"lighting-color": "lightingColor",
|
|
limitingconeangle: "limitingConeAngle",
|
|
local: "local",
|
|
markerend: "markerEnd",
|
|
"marker-end": "markerEnd",
|
|
markerheight: "markerHeight",
|
|
markermid: "markerMid",
|
|
"marker-mid": "markerMid",
|
|
markerstart: "markerStart",
|
|
"marker-start": "markerStart",
|
|
markerunits: "markerUnits",
|
|
markerwidth: "markerWidth",
|
|
mask: "mask",
|
|
maskcontentunits: "maskContentUnits",
|
|
maskunits: "maskUnits",
|
|
mathematical: "mathematical",
|
|
mode: "mode",
|
|
numoctaves: "numOctaves",
|
|
offset: "offset",
|
|
opacity: "opacity",
|
|
operator: "operator",
|
|
order: "order",
|
|
orient: "orient",
|
|
orientation: "orientation",
|
|
origin: "origin",
|
|
overflow: "overflow",
|
|
overlineposition: "overlinePosition",
|
|
"overline-position": "overlinePosition",
|
|
overlinethickness: "overlineThickness",
|
|
"overline-thickness": "overlineThickness",
|
|
paintorder: "paintOrder",
|
|
"paint-order": "paintOrder",
|
|
panose1: "panose1",
|
|
"panose-1": "panose1",
|
|
pathlength: "pathLength",
|
|
patterncontentunits: "patternContentUnits",
|
|
patterntransform: "patternTransform",
|
|
patternunits: "patternUnits",
|
|
pointerevents: "pointerEvents",
|
|
"pointer-events": "pointerEvents",
|
|
points: "points",
|
|
pointsatx: "pointsAtX",
|
|
pointsaty: "pointsAtY",
|
|
pointsatz: "pointsAtZ",
|
|
prefix: "prefix",
|
|
preservealpha: "preserveAlpha",
|
|
preserveaspectratio: "preserveAspectRatio",
|
|
primitiveunits: "primitiveUnits",
|
|
property: "property",
|
|
r: "r",
|
|
radius: "radius",
|
|
refx: "refX",
|
|
refy: "refY",
|
|
renderingintent: "renderingIntent",
|
|
"rendering-intent": "renderingIntent",
|
|
repeatcount: "repeatCount",
|
|
repeatdur: "repeatDur",
|
|
requiredextensions: "requiredExtensions",
|
|
requiredfeatures: "requiredFeatures",
|
|
resource: "resource",
|
|
restart: "restart",
|
|
result: "result",
|
|
results: "results",
|
|
rotate: "rotate",
|
|
rx: "rx",
|
|
ry: "ry",
|
|
scale: "scale",
|
|
security: "security",
|
|
seed: "seed",
|
|
shaperendering: "shapeRendering",
|
|
"shape-rendering": "shapeRendering",
|
|
slope: "slope",
|
|
spacing: "spacing",
|
|
specularconstant: "specularConstant",
|
|
specularexponent: "specularExponent",
|
|
speed: "speed",
|
|
spreadmethod: "spreadMethod",
|
|
startoffset: "startOffset",
|
|
stddeviation: "stdDeviation",
|
|
stemh: "stemh",
|
|
stemv: "stemv",
|
|
stitchtiles: "stitchTiles",
|
|
stopcolor: "stopColor",
|
|
"stop-color": "stopColor",
|
|
stopopacity: "stopOpacity",
|
|
"stop-opacity": "stopOpacity",
|
|
strikethroughposition: "strikethroughPosition",
|
|
"strikethrough-position": "strikethroughPosition",
|
|
strikethroughthickness: "strikethroughThickness",
|
|
"strikethrough-thickness": "strikethroughThickness",
|
|
string: "string",
|
|
stroke: "stroke",
|
|
strokedasharray: "strokeDasharray",
|
|
"stroke-dasharray": "strokeDasharray",
|
|
strokedashoffset: "strokeDashoffset",
|
|
"stroke-dashoffset": "strokeDashoffset",
|
|
strokelinecap: "strokeLinecap",
|
|
"stroke-linecap": "strokeLinecap",
|
|
strokelinejoin: "strokeLinejoin",
|
|
"stroke-linejoin": "strokeLinejoin",
|
|
strokemiterlimit: "strokeMiterlimit",
|
|
"stroke-miterlimit": "strokeMiterlimit",
|
|
strokewidth: "strokeWidth",
|
|
"stroke-width": "strokeWidth",
|
|
strokeopacity: "strokeOpacity",
|
|
"stroke-opacity": "strokeOpacity",
|
|
suppresscontenteditablewarning: "suppressContentEditableWarning",
|
|
suppresshydrationwarning: "suppressHydrationWarning",
|
|
surfacescale: "surfaceScale",
|
|
systemlanguage: "systemLanguage",
|
|
tablevalues: "tableValues",
|
|
targetx: "targetX",
|
|
targety: "targetY",
|
|
textanchor: "textAnchor",
|
|
"text-anchor": "textAnchor",
|
|
textdecoration: "textDecoration",
|
|
"text-decoration": "textDecoration",
|
|
textlength: "textLength",
|
|
textrendering: "textRendering",
|
|
"text-rendering": "textRendering",
|
|
to: "to",
|
|
transform: "transform",
|
|
typeof: "typeof",
|
|
u1: "u1",
|
|
u2: "u2",
|
|
underlineposition: "underlinePosition",
|
|
"underline-position": "underlinePosition",
|
|
underlinethickness: "underlineThickness",
|
|
"underline-thickness": "underlineThickness",
|
|
unicode: "unicode",
|
|
unicodebidi: "unicodeBidi",
|
|
"unicode-bidi": "unicodeBidi",
|
|
unicoderange: "unicodeRange",
|
|
"unicode-range": "unicodeRange",
|
|
unitsperem: "unitsPerEm",
|
|
"units-per-em": "unitsPerEm",
|
|
unselectable: "unselectable",
|
|
valphabetic: "vAlphabetic",
|
|
"v-alphabetic": "vAlphabetic",
|
|
values: "values",
|
|
vectoreffect: "vectorEffect",
|
|
"vector-effect": "vectorEffect",
|
|
version: "version",
|
|
vertadvy: "vertAdvY",
|
|
"vert-adv-y": "vertAdvY",
|
|
vertoriginx: "vertOriginX",
|
|
"vert-origin-x": "vertOriginX",
|
|
vertoriginy: "vertOriginY",
|
|
"vert-origin-y": "vertOriginY",
|
|
vhanging: "vHanging",
|
|
"v-hanging": "vHanging",
|
|
videographic: "vIdeographic",
|
|
"v-ideographic": "vIdeographic",
|
|
viewbox: "viewBox",
|
|
viewtarget: "viewTarget",
|
|
visibility: "visibility",
|
|
vmathematical: "vMathematical",
|
|
"v-mathematical": "vMathematical",
|
|
vocab: "vocab",
|
|
widths: "widths",
|
|
wordspacing: "wordSpacing",
|
|
"word-spacing": "wordSpacing",
|
|
writingmode: "writingMode",
|
|
"writing-mode": "writingMode",
|
|
x1: "x1",
|
|
x2: "x2",
|
|
x: "x",
|
|
xchannelselector: "xChannelSelector",
|
|
xheight: "xHeight",
|
|
"x-height": "xHeight",
|
|
xlinkactuate: "xlinkActuate",
|
|
"xlink:actuate": "xlinkActuate",
|
|
xlinkarcrole: "xlinkArcrole",
|
|
"xlink:arcrole": "xlinkArcrole",
|
|
xlinkhref: "xlinkHref",
|
|
"xlink:href": "xlinkHref",
|
|
xlinkrole: "xlinkRole",
|
|
"xlink:role": "xlinkRole",
|
|
xlinkshow: "xlinkShow",
|
|
"xlink:show": "xlinkShow",
|
|
xlinktitle: "xlinkTitle",
|
|
"xlink:title": "xlinkTitle",
|
|
xlinktype: "xlinkType",
|
|
"xlink:type": "xlinkType",
|
|
xmlbase: "xmlBase",
|
|
"xml:base": "xmlBase",
|
|
xmllang: "xmlLang",
|
|
"xml:lang": "xmlLang",
|
|
xmlns: "xmlns",
|
|
"xml:space": "xmlSpace",
|
|
xmlnsxlink: "xmlnsXlink",
|
|
"xmlns:xlink": "xmlnsXlink",
|
|
xmlspace: "xmlSpace",
|
|
y1: "y1",
|
|
y2: "y2",
|
|
y: "y",
|
|
ychannelselector: "yChannelSelector",
|
|
z: "z",
|
|
zoomandpan: "zoomAndPan"
|
|
};
|
|
var ariaProperties = {
|
|
"aria-current": 0,
|
|
"aria-description": 0,
|
|
"aria-details": 0,
|
|
"aria-disabled": 0,
|
|
"aria-hidden": 0,
|
|
"aria-invalid": 0,
|
|
"aria-keyshortcuts": 0,
|
|
"aria-label": 0,
|
|
"aria-roledescription": 0,
|
|
"aria-autocomplete": 0,
|
|
"aria-checked": 0,
|
|
"aria-expanded": 0,
|
|
"aria-haspopup": 0,
|
|
"aria-level": 0,
|
|
"aria-modal": 0,
|
|
"aria-multiline": 0,
|
|
"aria-multiselectable": 0,
|
|
"aria-orientation": 0,
|
|
"aria-placeholder": 0,
|
|
"aria-pressed": 0,
|
|
"aria-readonly": 0,
|
|
"aria-required": 0,
|
|
"aria-selected": 0,
|
|
"aria-sort": 0,
|
|
"aria-valuemax": 0,
|
|
"aria-valuemin": 0,
|
|
"aria-valuenow": 0,
|
|
"aria-valuetext": 0,
|
|
"aria-atomic": 0,
|
|
"aria-busy": 0,
|
|
"aria-live": 0,
|
|
"aria-relevant": 0,
|
|
"aria-dropeffect": 0,
|
|
"aria-grabbed": 0,
|
|
"aria-activedescendant": 0,
|
|
"aria-colcount": 0,
|
|
"aria-colindex": 0,
|
|
"aria-colspan": 0,
|
|
"aria-controls": 0,
|
|
"aria-describedby": 0,
|
|
"aria-errormessage": 0,
|
|
"aria-flowto": 0,
|
|
"aria-labelledby": 0,
|
|
"aria-owns": 0,
|
|
"aria-posinset": 0,
|
|
"aria-rowcount": 0,
|
|
"aria-rowindex": 0,
|
|
"aria-rowspan": 0,
|
|
"aria-setsize": 0
|
|
};
|
|
var warnedProperties = {};
|
|
var rARIA = new RegExp("^(aria)-[" + ATTRIBUTE_NAME_CHAR + "]*$");
|
|
var rARIACamel = new RegExp("^(aria)[A-Z][" + ATTRIBUTE_NAME_CHAR + "]*$");
|
|
function validateProperty(tagName, name) {
|
|
{
|
|
if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
|
|
return true;
|
|
}
|
|
if (rARIACamel.test(name)) {
|
|
var ariaName = "aria-" + name.slice(4).toLowerCase();
|
|
var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
|
|
if (correctName == null) {
|
|
error("Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.", name);
|
|
warnedProperties[name] = true;
|
|
return true;
|
|
}
|
|
if (name !== correctName) {
|
|
error("Invalid ARIA attribute `%s`. Did you mean `%s`?", name, correctName);
|
|
warnedProperties[name] = true;
|
|
return true;
|
|
}
|
|
}
|
|
if (rARIA.test(name)) {
|
|
var lowerCasedName = name.toLowerCase();
|
|
var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
|
|
if (standardName == null) {
|
|
warnedProperties[name] = true;
|
|
return false;
|
|
}
|
|
if (name !== standardName) {
|
|
error("Unknown ARIA attribute `%s`. Did you mean `%s`?", name, standardName);
|
|
warnedProperties[name] = true;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function warnInvalidARIAProps(type, props) {
|
|
{
|
|
var invalidProps = [];
|
|
for (var key in props) {
|
|
var isValid = validateProperty(type, key);
|
|
if (!isValid) {
|
|
invalidProps.push(key);
|
|
}
|
|
}
|
|
var unknownPropString = invalidProps.map(function(prop) {
|
|
return "`" + prop + "`";
|
|
}).join(", ");
|
|
if (invalidProps.length === 1) {
|
|
error("Invalid aria prop %s on <%s> tag. For details, see https://reactjs.org/link/invalid-aria-props", unknownPropString, type);
|
|
} else if (invalidProps.length > 1) {
|
|
error("Invalid aria props %s on <%s> tag. For details, see https://reactjs.org/link/invalid-aria-props", unknownPropString, type);
|
|
}
|
|
}
|
|
}
|
|
function validateProperties(type, props) {
|
|
if (isCustomComponent(type, props)) {
|
|
return;
|
|
}
|
|
warnInvalidARIAProps(type, props);
|
|
}
|
|
var didWarnValueNull = false;
|
|
function validateProperties$1(type, props) {
|
|
{
|
|
if (type !== "input" && type !== "textarea" && type !== "select") {
|
|
return;
|
|
}
|
|
if (props != null && props.value === null && !didWarnValueNull) {
|
|
didWarnValueNull = true;
|
|
if (type === "select" && props.multiple) {
|
|
error("`value` prop on `%s` should not be null. Consider using an empty array when `multiple` is set to `true` to clear the component or `undefined` for uncontrolled components.", type);
|
|
} else {
|
|
error("`value` prop on `%s` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components.", type);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var validateProperty$1 = function() {
|
|
};
|
|
{
|
|
var warnedProperties$1 = {};
|
|
var EVENT_NAME_REGEX = /^on./;
|
|
var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
|
|
var rARIA$1 = new RegExp("^(aria)-[" + ATTRIBUTE_NAME_CHAR + "]*$");
|
|
var rARIACamel$1 = new RegExp("^(aria)[A-Z][" + ATTRIBUTE_NAME_CHAR + "]*$");
|
|
validateProperty$1 = function(tagName, name, value, eventRegistry) {
|
|
if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
|
|
return true;
|
|
}
|
|
var lowerCasedName = name.toLowerCase();
|
|
if (lowerCasedName === "onfocusin" || lowerCasedName === "onfocusout") {
|
|
error("React uses onFocus and onBlur instead of onFocusIn and onFocusOut. All React events are normalized to bubble, so onFocusIn and onFocusOut are not needed/supported by React.");
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (eventRegistry != null) {
|
|
var registrationNameDependencies2 = eventRegistry.registrationNameDependencies, possibleRegistrationNames2 = eventRegistry.possibleRegistrationNames;
|
|
if (registrationNameDependencies2.hasOwnProperty(name)) {
|
|
return true;
|
|
}
|
|
var registrationName = possibleRegistrationNames2.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames2[lowerCasedName] : null;
|
|
if (registrationName != null) {
|
|
error("Invalid event handler property `%s`. Did you mean `%s`?", name, registrationName);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (EVENT_NAME_REGEX.test(name)) {
|
|
error("Unknown event handler property `%s`. It will be ignored.", name);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
} else if (EVENT_NAME_REGEX.test(name)) {
|
|
if (INVALID_EVENT_NAME_REGEX.test(name)) {
|
|
error("Invalid event handler property `%s`. React events use the camelCase naming convention, for example `onClick`.", name);
|
|
}
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
|
|
return true;
|
|
}
|
|
if (lowerCasedName === "innerhtml") {
|
|
error("Directly setting property `innerHTML` is not permitted. For more information, lookup documentation on `dangerouslySetInnerHTML`.");
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (lowerCasedName === "aria") {
|
|
error("The `aria` attribute is reserved for future use in React. Pass individual `aria-` attributes instead.");
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (lowerCasedName === "is" && value !== null && value !== void 0 && typeof value !== "string") {
|
|
error("Received a `%s` for a string attribute `is`. If this is expected, cast the value to a string.", typeof value);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (typeof value === "number" && isNaN(value)) {
|
|
error("Received NaN for the `%s` attribute. If this is expected, cast the value to a string.", name);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
var propertyInfo = getPropertyInfo(name);
|
|
var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
|
|
if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
|
|
var standardName = possibleStandardNames[lowerCasedName];
|
|
if (standardName !== name) {
|
|
error("Invalid DOM property `%s`. Did you mean `%s`?", name, standardName);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
} else if (!isReserved && name !== lowerCasedName) {
|
|
error("React does not recognize the `%s` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `%s` instead. If you accidentally passed it from a parent component, remove it from the DOM element.", name, lowerCasedName);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (typeof value === "boolean" && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
|
|
if (value) {
|
|
error('Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s="%s" or %s={value.toString()}.', value, name, name, value, name);
|
|
} else {
|
|
error('Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s="%s" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);
|
|
}
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
if (isReserved) {
|
|
return true;
|
|
}
|
|
if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
|
|
warnedProperties$1[name] = true;
|
|
return false;
|
|
}
|
|
if ((value === "false" || value === "true") && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
|
|
error("Received the string `%s` for the boolean attribute `%s`. %s Did you mean %s={%s}?", value, name, value === "false" ? "The browser will interpret it as a truthy value." : 'Although this works, it will not work as expected if you pass the string "false".', name, value);
|
|
warnedProperties$1[name] = true;
|
|
return true;
|
|
}
|
|
return true;
|
|
};
|
|
}
|
|
var warnUnknownProperties = function(type, props, eventRegistry) {
|
|
{
|
|
var unknownProps = [];
|
|
for (var key in props) {
|
|
var isValid = validateProperty$1(type, key, props[key], eventRegistry);
|
|
if (!isValid) {
|
|
unknownProps.push(key);
|
|
}
|
|
}
|
|
var unknownPropString = unknownProps.map(function(prop) {
|
|
return "`" + prop + "`";
|
|
}).join(", ");
|
|
if (unknownProps.length === 1) {
|
|
error("Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://reactjs.org/link/attribute-behavior ", unknownPropString, type);
|
|
} else if (unknownProps.length > 1) {
|
|
error("Invalid values for props %s on <%s> tag. Either remove them from the element, or pass a string or number value to keep them in the DOM. For details, see https://reactjs.org/link/attribute-behavior ", unknownPropString, type);
|
|
}
|
|
}
|
|
};
|
|
function validateProperties$2(type, props, eventRegistry) {
|
|
if (isCustomComponent(type, props)) {
|
|
return;
|
|
}
|
|
warnUnknownProperties(type, props, eventRegistry);
|
|
}
|
|
var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
|
|
var IS_NON_DELEGATED = 1 << 1;
|
|
var IS_CAPTURE_PHASE = 1 << 2;
|
|
var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
|
|
var currentReplayingEvent = null;
|
|
function setReplayingEvent(event) {
|
|
{
|
|
if (currentReplayingEvent !== null) {
|
|
error("Expected currently replaying event to be null. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
currentReplayingEvent = event;
|
|
}
|
|
function resetReplayingEvent() {
|
|
{
|
|
if (currentReplayingEvent === null) {
|
|
error("Expected currently replaying event to not be null. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
currentReplayingEvent = null;
|
|
}
|
|
function isReplayingEvent(event) {
|
|
return event === currentReplayingEvent;
|
|
}
|
|
function getEventTarget(nativeEvent) {
|
|
var target = nativeEvent.target || nativeEvent.srcElement || window;
|
|
if (target.correspondingUseElement) {
|
|
target = target.correspondingUseElement;
|
|
}
|
|
return target.nodeType === TEXT_NODE ? target.parentNode : target;
|
|
}
|
|
var restoreImpl = null;
|
|
var restoreTarget = null;
|
|
var restoreQueue = null;
|
|
function restoreStateOfTarget(target) {
|
|
var internalInstance = getInstanceFromNode(target);
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
if (typeof restoreImpl !== "function") {
|
|
throw new Error("setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
var stateNode = internalInstance.stateNode;
|
|
if (stateNode) {
|
|
var _props = getFiberCurrentPropsFromNode(stateNode);
|
|
restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
|
|
}
|
|
}
|
|
function setRestoreImplementation(impl) {
|
|
restoreImpl = impl;
|
|
}
|
|
function enqueueStateRestore(target) {
|
|
if (restoreTarget) {
|
|
if (restoreQueue) {
|
|
restoreQueue.push(target);
|
|
} else {
|
|
restoreQueue = [target];
|
|
}
|
|
} else {
|
|
restoreTarget = target;
|
|
}
|
|
}
|
|
function needsStateRestore() {
|
|
return restoreTarget !== null || restoreQueue !== null;
|
|
}
|
|
function restoreStateIfNeeded() {
|
|
if (!restoreTarget) {
|
|
return;
|
|
}
|
|
var target = restoreTarget;
|
|
var queuedTargets = restoreQueue;
|
|
restoreTarget = null;
|
|
restoreQueue = null;
|
|
restoreStateOfTarget(target);
|
|
if (queuedTargets) {
|
|
for (var i = 0; i < queuedTargets.length; i++) {
|
|
restoreStateOfTarget(queuedTargets[i]);
|
|
}
|
|
}
|
|
}
|
|
var batchedUpdatesImpl = function(fn, bookkeeping) {
|
|
return fn(bookkeeping);
|
|
};
|
|
var flushSyncImpl = function() {
|
|
};
|
|
var isInsideEventHandler = false;
|
|
function finishEventHandler() {
|
|
var controlledComponentsHavePendingUpdates = needsStateRestore();
|
|
if (controlledComponentsHavePendingUpdates) {
|
|
flushSyncImpl();
|
|
restoreStateIfNeeded();
|
|
}
|
|
}
|
|
function batchedUpdates(fn, a, b) {
|
|
if (isInsideEventHandler) {
|
|
return fn(a, b);
|
|
}
|
|
isInsideEventHandler = true;
|
|
try {
|
|
return batchedUpdatesImpl(fn, a, b);
|
|
} finally {
|
|
isInsideEventHandler = false;
|
|
finishEventHandler();
|
|
}
|
|
}
|
|
function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushSyncImpl) {
|
|
batchedUpdatesImpl = _batchedUpdatesImpl;
|
|
flushSyncImpl = _flushSyncImpl;
|
|
}
|
|
function isInteractive(tag) {
|
|
return tag === "button" || tag === "input" || tag === "select" || tag === "textarea";
|
|
}
|
|
function shouldPreventMouseEvent(name, type, props) {
|
|
switch (name) {
|
|
case "onClick":
|
|
case "onClickCapture":
|
|
case "onDoubleClick":
|
|
case "onDoubleClickCapture":
|
|
case "onMouseDown":
|
|
case "onMouseDownCapture":
|
|
case "onMouseMove":
|
|
case "onMouseMoveCapture":
|
|
case "onMouseUp":
|
|
case "onMouseUpCapture":
|
|
case "onMouseEnter":
|
|
return !!(props.disabled && isInteractive(type));
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function getListener(inst, registrationName) {
|
|
var stateNode = inst.stateNode;
|
|
if (stateNode === null) {
|
|
return null;
|
|
}
|
|
var props = getFiberCurrentPropsFromNode(stateNode);
|
|
if (props === null) {
|
|
return null;
|
|
}
|
|
var listener = props[registrationName];
|
|
if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
|
|
return null;
|
|
}
|
|
if (listener && typeof listener !== "function") {
|
|
throw new Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type.");
|
|
}
|
|
return listener;
|
|
}
|
|
var passiveBrowserEventsSupported = false;
|
|
if (canUseDOM) {
|
|
try {
|
|
var options = {};
|
|
Object.defineProperty(options, "passive", {
|
|
get: function() {
|
|
passiveBrowserEventsSupported = true;
|
|
}
|
|
});
|
|
window.addEventListener("test", options, options);
|
|
window.removeEventListener("test", options, options);
|
|
} catch (e) {
|
|
passiveBrowserEventsSupported = false;
|
|
}
|
|
}
|
|
function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
|
|
var funcArgs = Array.prototype.slice.call(arguments, 3);
|
|
try {
|
|
func.apply(context, funcArgs);
|
|
} catch (error2) {
|
|
this.onError(error2);
|
|
}
|
|
}
|
|
var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
|
|
{
|
|
if (typeof window !== "undefined" && typeof window.dispatchEvent === "function" && typeof document !== "undefined" && typeof document.createEvent === "function") {
|
|
var fakeNode = document.createElement("react");
|
|
invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
|
|
if (typeof document === "undefined" || document === null) {
|
|
throw new Error("The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.");
|
|
}
|
|
var evt = document.createEvent("Event");
|
|
var didCall = false;
|
|
var didError = true;
|
|
var windowEvent = window.event;
|
|
var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, "event");
|
|
function restoreAfterDispatch() {
|
|
fakeNode.removeEventListener(evtType, callCallback2, false);
|
|
if (typeof window.event !== "undefined" && window.hasOwnProperty("event")) {
|
|
window.event = windowEvent;
|
|
}
|
|
}
|
|
var funcArgs = Array.prototype.slice.call(arguments, 3);
|
|
function callCallback2() {
|
|
didCall = true;
|
|
restoreAfterDispatch();
|
|
func.apply(context, funcArgs);
|
|
didError = false;
|
|
}
|
|
var error2;
|
|
var didSetError = false;
|
|
var isCrossOriginError = false;
|
|
function handleWindowError(event) {
|
|
error2 = event.error;
|
|
didSetError = true;
|
|
if (error2 === null && event.colno === 0 && event.lineno === 0) {
|
|
isCrossOriginError = true;
|
|
}
|
|
if (event.defaultPrevented) {
|
|
if (error2 != null && typeof error2 === "object") {
|
|
try {
|
|
error2._suppressLogging = true;
|
|
} catch (inner) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var evtType = "react-" + (name ? name : "invokeguardedcallback");
|
|
window.addEventListener("error", handleWindowError);
|
|
fakeNode.addEventListener(evtType, callCallback2, false);
|
|
evt.initEvent(evtType, false, false);
|
|
fakeNode.dispatchEvent(evt);
|
|
if (windowEventDescriptor) {
|
|
Object.defineProperty(window, "event", windowEventDescriptor);
|
|
}
|
|
if (didCall && didError) {
|
|
if (!didSetError) {
|
|
error2 = new Error(`An error was thrown inside one of your components, but React doesn't know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It's possible that these don't work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.`);
|
|
} else if (isCrossOriginError) {
|
|
error2 = new Error("A cross-origin error was thrown. React doesn't have access to the actual error object in development. See https://reactjs.org/link/crossorigin-error for more information.");
|
|
}
|
|
this.onError(error2);
|
|
}
|
|
window.removeEventListener("error", handleWindowError);
|
|
if (!didCall) {
|
|
restoreAfterDispatch();
|
|
return invokeGuardedCallbackProd.apply(this, arguments);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
|
|
var hasError = false;
|
|
var caughtError = null;
|
|
var hasRethrowError = false;
|
|
var rethrowError = null;
|
|
var reporter = {
|
|
onError: function(error2) {
|
|
hasError = true;
|
|
caughtError = error2;
|
|
}
|
|
};
|
|
function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
|
|
hasError = false;
|
|
caughtError = null;
|
|
invokeGuardedCallbackImpl$1.apply(reporter, arguments);
|
|
}
|
|
function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
|
|
invokeGuardedCallback.apply(this, arguments);
|
|
if (hasError) {
|
|
var error2 = clearCaughtError();
|
|
if (!hasRethrowError) {
|
|
hasRethrowError = true;
|
|
rethrowError = error2;
|
|
}
|
|
}
|
|
}
|
|
function rethrowCaughtError() {
|
|
if (hasRethrowError) {
|
|
var error2 = rethrowError;
|
|
hasRethrowError = false;
|
|
rethrowError = null;
|
|
throw error2;
|
|
}
|
|
}
|
|
function hasCaughtError() {
|
|
return hasError;
|
|
}
|
|
function clearCaughtError() {
|
|
if (hasError) {
|
|
var error2 = caughtError;
|
|
hasError = false;
|
|
caughtError = null;
|
|
return error2;
|
|
} else {
|
|
throw new Error("clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
function get(key) {
|
|
return key._reactInternals;
|
|
}
|
|
function has(key) {
|
|
return key._reactInternals !== void 0;
|
|
}
|
|
function set(key, value) {
|
|
key._reactInternals = value;
|
|
}
|
|
var NoFlags = 0;
|
|
var PerformedWork = 1;
|
|
var Placement = 2;
|
|
var Update = 4;
|
|
var ChildDeletion = 16;
|
|
var ContentReset = 32;
|
|
var Callback = 64;
|
|
var DidCapture = 128;
|
|
var ForceClientRender = 256;
|
|
var Ref = 512;
|
|
var Snapshot = 1024;
|
|
var Passive = 2048;
|
|
var Hydrating = 4096;
|
|
var Visibility = 8192;
|
|
var StoreConsistency = 16384;
|
|
var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency;
|
|
var HostEffectMask = 32767;
|
|
var Incomplete = 32768;
|
|
var ShouldCapture = 65536;
|
|
var ForceUpdateForLegacySuspense = 131072;
|
|
var Forked = 1048576;
|
|
var RefStatic = 2097152;
|
|
var LayoutStatic = 4194304;
|
|
var PassiveStatic = 8388608;
|
|
var MountLayoutDev = 16777216;
|
|
var MountPassiveDev = 33554432;
|
|
var BeforeMutationMask = Update | Snapshot | 0;
|
|
var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
|
|
var LayoutMask = Update | Callback | Ref | Visibility;
|
|
var PassiveMask = Passive | ChildDeletion;
|
|
var StaticMask = LayoutStatic | PassiveStatic | RefStatic;
|
|
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
|
|
function getNearestMountedFiber(fiber) {
|
|
var node = fiber;
|
|
var nearestMounted = fiber;
|
|
if (!fiber.alternate) {
|
|
var nextNode = node;
|
|
do {
|
|
node = nextNode;
|
|
if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
|
|
nearestMounted = node.return;
|
|
}
|
|
nextNode = node.return;
|
|
} while (nextNode);
|
|
} else {
|
|
while (node.return) {
|
|
node = node.return;
|
|
}
|
|
}
|
|
if (node.tag === HostRoot) {
|
|
return nearestMounted;
|
|
}
|
|
return null;
|
|
}
|
|
function getSuspenseInstanceFromFiber(fiber) {
|
|
if (fiber.tag === SuspenseComponent) {
|
|
var suspenseState = fiber.memoizedState;
|
|
if (suspenseState === null) {
|
|
var current2 = fiber.alternate;
|
|
if (current2 !== null) {
|
|
suspenseState = current2.memoizedState;
|
|
}
|
|
}
|
|
if (suspenseState !== null) {
|
|
return suspenseState.dehydrated;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function getContainerFromFiber(fiber) {
|
|
return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
|
|
}
|
|
function isFiberMounted(fiber) {
|
|
return getNearestMountedFiber(fiber) === fiber;
|
|
}
|
|
function isMounted(component) {
|
|
{
|
|
var owner = ReactCurrentOwner.current;
|
|
if (owner !== null && owner.tag === ClassComponent) {
|
|
var ownerFiber = owner;
|
|
var instance = ownerFiber.stateNode;
|
|
if (!instance._warnedAboutRefsInRender) {
|
|
error("%s is accessing isMounted inside its render() function. render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", getComponentNameFromFiber(ownerFiber) || "A component");
|
|
}
|
|
instance._warnedAboutRefsInRender = true;
|
|
}
|
|
}
|
|
var fiber = get(component);
|
|
if (!fiber) {
|
|
return false;
|
|
}
|
|
return getNearestMountedFiber(fiber) === fiber;
|
|
}
|
|
function assertIsMounted(fiber) {
|
|
if (getNearestMountedFiber(fiber) !== fiber) {
|
|
throw new Error("Unable to find node on an unmounted component.");
|
|
}
|
|
}
|
|
function findCurrentFiberUsingSlowPath(fiber) {
|
|
var alternate = fiber.alternate;
|
|
if (!alternate) {
|
|
var nearestMounted = getNearestMountedFiber(fiber);
|
|
if (nearestMounted === null) {
|
|
throw new Error("Unable to find node on an unmounted component.");
|
|
}
|
|
if (nearestMounted !== fiber) {
|
|
return null;
|
|
}
|
|
return fiber;
|
|
}
|
|
var a = fiber;
|
|
var b = alternate;
|
|
while (true) {
|
|
var parentA = a.return;
|
|
if (parentA === null) {
|
|
break;
|
|
}
|
|
var parentB = parentA.alternate;
|
|
if (parentB === null) {
|
|
var nextParent = parentA.return;
|
|
if (nextParent !== null) {
|
|
a = b = nextParent;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
if (parentA.child === parentB.child) {
|
|
var child = parentA.child;
|
|
while (child) {
|
|
if (child === a) {
|
|
assertIsMounted(parentA);
|
|
return fiber;
|
|
}
|
|
if (child === b) {
|
|
assertIsMounted(parentA);
|
|
return alternate;
|
|
}
|
|
child = child.sibling;
|
|
}
|
|
throw new Error("Unable to find node on an unmounted component.");
|
|
}
|
|
if (a.return !== b.return) {
|
|
a = parentA;
|
|
b = parentB;
|
|
} else {
|
|
var didFindChild = false;
|
|
var _child = parentA.child;
|
|
while (_child) {
|
|
if (_child === a) {
|
|
didFindChild = true;
|
|
a = parentA;
|
|
b = parentB;
|
|
break;
|
|
}
|
|
if (_child === b) {
|
|
didFindChild = true;
|
|
b = parentA;
|
|
a = parentB;
|
|
break;
|
|
}
|
|
_child = _child.sibling;
|
|
}
|
|
if (!didFindChild) {
|
|
_child = parentB.child;
|
|
while (_child) {
|
|
if (_child === a) {
|
|
didFindChild = true;
|
|
a = parentB;
|
|
b = parentA;
|
|
break;
|
|
}
|
|
if (_child === b) {
|
|
didFindChild = true;
|
|
b = parentB;
|
|
a = parentA;
|
|
break;
|
|
}
|
|
_child = _child.sibling;
|
|
}
|
|
if (!didFindChild) {
|
|
throw new Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.");
|
|
}
|
|
}
|
|
}
|
|
if (a.alternate !== b) {
|
|
throw new Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
if (a.tag !== HostRoot) {
|
|
throw new Error("Unable to find node on an unmounted component.");
|
|
}
|
|
if (a.stateNode.current === a) {
|
|
return fiber;
|
|
}
|
|
return alternate;
|
|
}
|
|
function findCurrentHostFiber(parent) {
|
|
var currentParent = findCurrentFiberUsingSlowPath(parent);
|
|
return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
|
|
}
|
|
function findCurrentHostFiberImpl(node) {
|
|
if (node.tag === HostComponent || node.tag === HostText) {
|
|
return node;
|
|
}
|
|
var child = node.child;
|
|
while (child !== null) {
|
|
var match = findCurrentHostFiberImpl(child);
|
|
if (match !== null) {
|
|
return match;
|
|
}
|
|
child = child.sibling;
|
|
}
|
|
return null;
|
|
}
|
|
function findCurrentHostFiberWithNoPortals(parent) {
|
|
var currentParent = findCurrentFiberUsingSlowPath(parent);
|
|
return currentParent !== null ? findCurrentHostFiberWithNoPortalsImpl(currentParent) : null;
|
|
}
|
|
function findCurrentHostFiberWithNoPortalsImpl(node) {
|
|
if (node.tag === HostComponent || node.tag === HostText) {
|
|
return node;
|
|
}
|
|
var child = node.child;
|
|
while (child !== null) {
|
|
if (child.tag !== HostPortal) {
|
|
var match = findCurrentHostFiberWithNoPortalsImpl(child);
|
|
if (match !== null) {
|
|
return match;
|
|
}
|
|
}
|
|
child = child.sibling;
|
|
}
|
|
return null;
|
|
}
|
|
var scheduleCallback = Scheduler.unstable_scheduleCallback;
|
|
var cancelCallback = Scheduler.unstable_cancelCallback;
|
|
var shouldYield = Scheduler.unstable_shouldYield;
|
|
var requestPaint = Scheduler.unstable_requestPaint;
|
|
var now = Scheduler.unstable_now;
|
|
var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel;
|
|
var ImmediatePriority = Scheduler.unstable_ImmediatePriority;
|
|
var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
|
|
var NormalPriority = Scheduler.unstable_NormalPriority;
|
|
var LowPriority = Scheduler.unstable_LowPriority;
|
|
var IdlePriority = Scheduler.unstable_IdlePriority;
|
|
var unstable_yieldValue = Scheduler.unstable_yieldValue;
|
|
var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue;
|
|
var rendererID = null;
|
|
var injectedHook = null;
|
|
var injectedProfilingHooks = null;
|
|
var hasLoggedError = false;
|
|
var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined";
|
|
function injectInternals(internals) {
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") {
|
|
return false;
|
|
}
|
|
var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
if (hook.isDisabled) {
|
|
return true;
|
|
}
|
|
if (!hook.supportsFiber) {
|
|
{
|
|
error("The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://reactjs.org/link/react-devtools");
|
|
}
|
|
return true;
|
|
}
|
|
try {
|
|
if (enableSchedulingProfiler) {
|
|
internals = assign({}, internals, {
|
|
getLaneLabelMap,
|
|
injectProfilingHooks
|
|
});
|
|
}
|
|
rendererID = hook.inject(internals);
|
|
injectedHook = hook;
|
|
} catch (err) {
|
|
{
|
|
error("React instrumentation encountered an error: %s.", err);
|
|
}
|
|
}
|
|
if (hook.checkDCE) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
function onScheduleRoot(root3, children) {
|
|
{
|
|
if (injectedHook && typeof injectedHook.onScheduleFiberRoot === "function") {
|
|
try {
|
|
injectedHook.onScheduleFiberRoot(rendererID, root3, children);
|
|
} catch (err) {
|
|
if (!hasLoggedError) {
|
|
hasLoggedError = true;
|
|
error("React instrumentation encountered an error: %s", err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function onCommitRoot(root3, eventPriority) {
|
|
if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") {
|
|
try {
|
|
var didError = (root3.current.flags & DidCapture) === DidCapture;
|
|
if (enableProfilerTimer) {
|
|
var schedulerPriority;
|
|
switch (eventPriority) {
|
|
case DiscreteEventPriority:
|
|
schedulerPriority = ImmediatePriority;
|
|
break;
|
|
case ContinuousEventPriority:
|
|
schedulerPriority = UserBlockingPriority;
|
|
break;
|
|
case DefaultEventPriority:
|
|
schedulerPriority = NormalPriority;
|
|
break;
|
|
case IdleEventPriority:
|
|
schedulerPriority = IdlePriority;
|
|
break;
|
|
default:
|
|
schedulerPriority = NormalPriority;
|
|
break;
|
|
}
|
|
injectedHook.onCommitFiberRoot(rendererID, root3, schedulerPriority, didError);
|
|
} else {
|
|
injectedHook.onCommitFiberRoot(rendererID, root3, void 0, didError);
|
|
}
|
|
} catch (err) {
|
|
{
|
|
if (!hasLoggedError) {
|
|
hasLoggedError = true;
|
|
error("React instrumentation encountered an error: %s", err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function onPostCommitRoot(root3) {
|
|
if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === "function") {
|
|
try {
|
|
injectedHook.onPostCommitFiberRoot(rendererID, root3);
|
|
} catch (err) {
|
|
{
|
|
if (!hasLoggedError) {
|
|
hasLoggedError = true;
|
|
error("React instrumentation encountered an error: %s", err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function onCommitUnmount(fiber) {
|
|
if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") {
|
|
try {
|
|
injectedHook.onCommitFiberUnmount(rendererID, fiber);
|
|
} catch (err) {
|
|
{
|
|
if (!hasLoggedError) {
|
|
hasLoggedError = true;
|
|
error("React instrumentation encountered an error: %s", err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function setIsStrictModeForDevtools(newIsStrictMode) {
|
|
{
|
|
if (typeof unstable_yieldValue === "function") {
|
|
unstable_setDisableYieldValue(newIsStrictMode);
|
|
setSuppressWarning(newIsStrictMode);
|
|
}
|
|
if (injectedHook && typeof injectedHook.setStrictMode === "function") {
|
|
try {
|
|
injectedHook.setStrictMode(rendererID, newIsStrictMode);
|
|
} catch (err) {
|
|
{
|
|
if (!hasLoggedError) {
|
|
hasLoggedError = true;
|
|
error("React instrumentation encountered an error: %s", err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function injectProfilingHooks(profilingHooks) {
|
|
injectedProfilingHooks = profilingHooks;
|
|
}
|
|
function getLaneLabelMap() {
|
|
{
|
|
var map = /* @__PURE__ */ new Map();
|
|
var lane = 1;
|
|
for (var index2 = 0; index2 < TotalLanes; index2++) {
|
|
var label = getLabelForLane(lane);
|
|
map.set(lane, label);
|
|
lane *= 2;
|
|
}
|
|
return map;
|
|
}
|
|
}
|
|
function markCommitStarted(lanes) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === "function") {
|
|
injectedProfilingHooks.markCommitStarted(lanes);
|
|
}
|
|
}
|
|
}
|
|
function markCommitStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === "function") {
|
|
injectedProfilingHooks.markCommitStopped();
|
|
}
|
|
}
|
|
}
|
|
function markComponentRenderStarted(fiber) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === "function") {
|
|
injectedProfilingHooks.markComponentRenderStarted(fiber);
|
|
}
|
|
}
|
|
}
|
|
function markComponentRenderStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === "function") {
|
|
injectedProfilingHooks.markComponentRenderStopped();
|
|
}
|
|
}
|
|
}
|
|
function markComponentPassiveEffectMountStarted(fiber) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === "function") {
|
|
injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber);
|
|
}
|
|
}
|
|
}
|
|
function markComponentPassiveEffectMountStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === "function") {
|
|
injectedProfilingHooks.markComponentPassiveEffectMountStopped();
|
|
}
|
|
}
|
|
}
|
|
function markComponentPassiveEffectUnmountStarted(fiber) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === "function") {
|
|
injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber);
|
|
}
|
|
}
|
|
}
|
|
function markComponentPassiveEffectUnmountStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === "function") {
|
|
injectedProfilingHooks.markComponentPassiveEffectUnmountStopped();
|
|
}
|
|
}
|
|
}
|
|
function markComponentLayoutEffectMountStarted(fiber) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === "function") {
|
|
injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber);
|
|
}
|
|
}
|
|
}
|
|
function markComponentLayoutEffectMountStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === "function") {
|
|
injectedProfilingHooks.markComponentLayoutEffectMountStopped();
|
|
}
|
|
}
|
|
}
|
|
function markComponentLayoutEffectUnmountStarted(fiber) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === "function") {
|
|
injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber);
|
|
}
|
|
}
|
|
}
|
|
function markComponentLayoutEffectUnmountStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === "function") {
|
|
injectedProfilingHooks.markComponentLayoutEffectUnmountStopped();
|
|
}
|
|
}
|
|
}
|
|
function markComponentErrored(fiber, thrownValue, lanes) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === "function") {
|
|
injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes);
|
|
}
|
|
}
|
|
}
|
|
function markComponentSuspended(fiber, wakeable, lanes) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === "function") {
|
|
injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes);
|
|
}
|
|
}
|
|
}
|
|
function markLayoutEffectsStarted(lanes) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === "function") {
|
|
injectedProfilingHooks.markLayoutEffectsStarted(lanes);
|
|
}
|
|
}
|
|
}
|
|
function markLayoutEffectsStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === "function") {
|
|
injectedProfilingHooks.markLayoutEffectsStopped();
|
|
}
|
|
}
|
|
}
|
|
function markPassiveEffectsStarted(lanes) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === "function") {
|
|
injectedProfilingHooks.markPassiveEffectsStarted(lanes);
|
|
}
|
|
}
|
|
}
|
|
function markPassiveEffectsStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === "function") {
|
|
injectedProfilingHooks.markPassiveEffectsStopped();
|
|
}
|
|
}
|
|
}
|
|
function markRenderStarted(lanes) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === "function") {
|
|
injectedProfilingHooks.markRenderStarted(lanes);
|
|
}
|
|
}
|
|
}
|
|
function markRenderYielded() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === "function") {
|
|
injectedProfilingHooks.markRenderYielded();
|
|
}
|
|
}
|
|
}
|
|
function markRenderStopped() {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === "function") {
|
|
injectedProfilingHooks.markRenderStopped();
|
|
}
|
|
}
|
|
}
|
|
function markRenderScheduled(lane) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === "function") {
|
|
injectedProfilingHooks.markRenderScheduled(lane);
|
|
}
|
|
}
|
|
}
|
|
function markForceUpdateScheduled(fiber, lane) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === "function") {
|
|
injectedProfilingHooks.markForceUpdateScheduled(fiber, lane);
|
|
}
|
|
}
|
|
}
|
|
function markStateUpdateScheduled(fiber, lane) {
|
|
{
|
|
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === "function") {
|
|
injectedProfilingHooks.markStateUpdateScheduled(fiber, lane);
|
|
}
|
|
}
|
|
}
|
|
var NoMode = 0;
|
|
var ConcurrentMode = 1;
|
|
var ProfileMode = 2;
|
|
var StrictLegacyMode = 8;
|
|
var StrictEffectsMode = 16;
|
|
var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback;
|
|
var log = Math.log;
|
|
var LN2 = Math.LN2;
|
|
function clz32Fallback(x) {
|
|
var asUint = x >>> 0;
|
|
if (asUint === 0) {
|
|
return 32;
|
|
}
|
|
return 31 - (log(asUint) / LN2 | 0) | 0;
|
|
}
|
|
var TotalLanes = 31;
|
|
var NoLanes = 0;
|
|
var NoLane = 0;
|
|
var SyncLane = 1;
|
|
var InputContinuousHydrationLane = 2;
|
|
var InputContinuousLane = 4;
|
|
var DefaultHydrationLane = 8;
|
|
var DefaultLane = 16;
|
|
var TransitionHydrationLane = 32;
|
|
var TransitionLanes = 4194240;
|
|
var TransitionLane1 = 64;
|
|
var TransitionLane2 = 128;
|
|
var TransitionLane3 = 256;
|
|
var TransitionLane4 = 512;
|
|
var TransitionLane5 = 1024;
|
|
var TransitionLane6 = 2048;
|
|
var TransitionLane7 = 4096;
|
|
var TransitionLane8 = 8192;
|
|
var TransitionLane9 = 16384;
|
|
var TransitionLane10 = 32768;
|
|
var TransitionLane11 = 65536;
|
|
var TransitionLane12 = 131072;
|
|
var TransitionLane13 = 262144;
|
|
var TransitionLane14 = 524288;
|
|
var TransitionLane15 = 1048576;
|
|
var TransitionLane16 = 2097152;
|
|
var RetryLanes = 130023424;
|
|
var RetryLane1 = 4194304;
|
|
var RetryLane2 = 8388608;
|
|
var RetryLane3 = 16777216;
|
|
var RetryLane4 = 33554432;
|
|
var RetryLane5 = 67108864;
|
|
var SomeRetryLane = RetryLane1;
|
|
var SelectiveHydrationLane = 134217728;
|
|
var NonIdleLanes = 268435455;
|
|
var IdleHydrationLane = 268435456;
|
|
var IdleLane = 536870912;
|
|
var OffscreenLane = 1073741824;
|
|
function getLabelForLane(lane) {
|
|
{
|
|
if (lane & SyncLane) {
|
|
return "Sync";
|
|
}
|
|
if (lane & InputContinuousHydrationLane) {
|
|
return "InputContinuousHydration";
|
|
}
|
|
if (lane & InputContinuousLane) {
|
|
return "InputContinuous";
|
|
}
|
|
if (lane & DefaultHydrationLane) {
|
|
return "DefaultHydration";
|
|
}
|
|
if (lane & DefaultLane) {
|
|
return "Default";
|
|
}
|
|
if (lane & TransitionHydrationLane) {
|
|
return "TransitionHydration";
|
|
}
|
|
if (lane & TransitionLanes) {
|
|
return "Transition";
|
|
}
|
|
if (lane & RetryLanes) {
|
|
return "Retry";
|
|
}
|
|
if (lane & SelectiveHydrationLane) {
|
|
return "SelectiveHydration";
|
|
}
|
|
if (lane & IdleHydrationLane) {
|
|
return "IdleHydration";
|
|
}
|
|
if (lane & IdleLane) {
|
|
return "Idle";
|
|
}
|
|
if (lane & OffscreenLane) {
|
|
return "Offscreen";
|
|
}
|
|
}
|
|
}
|
|
var NoTimestamp = -1;
|
|
var nextTransitionLane = TransitionLane1;
|
|
var nextRetryLane = RetryLane1;
|
|
function getHighestPriorityLanes(lanes) {
|
|
switch (getHighestPriorityLane(lanes)) {
|
|
case SyncLane:
|
|
return SyncLane;
|
|
case InputContinuousHydrationLane:
|
|
return InputContinuousHydrationLane;
|
|
case InputContinuousLane:
|
|
return InputContinuousLane;
|
|
case DefaultHydrationLane:
|
|
return DefaultHydrationLane;
|
|
case DefaultLane:
|
|
return DefaultLane;
|
|
case TransitionHydrationLane:
|
|
return TransitionHydrationLane;
|
|
case TransitionLane1:
|
|
case TransitionLane2:
|
|
case TransitionLane3:
|
|
case TransitionLane4:
|
|
case TransitionLane5:
|
|
case TransitionLane6:
|
|
case TransitionLane7:
|
|
case TransitionLane8:
|
|
case TransitionLane9:
|
|
case TransitionLane10:
|
|
case TransitionLane11:
|
|
case TransitionLane12:
|
|
case TransitionLane13:
|
|
case TransitionLane14:
|
|
case TransitionLane15:
|
|
case TransitionLane16:
|
|
return lanes & TransitionLanes;
|
|
case RetryLane1:
|
|
case RetryLane2:
|
|
case RetryLane3:
|
|
case RetryLane4:
|
|
case RetryLane5:
|
|
return lanes & RetryLanes;
|
|
case SelectiveHydrationLane:
|
|
return SelectiveHydrationLane;
|
|
case IdleHydrationLane:
|
|
return IdleHydrationLane;
|
|
case IdleLane:
|
|
return IdleLane;
|
|
case OffscreenLane:
|
|
return OffscreenLane;
|
|
default:
|
|
{
|
|
error("Should have found matching lanes. This is a bug in React.");
|
|
}
|
|
return lanes;
|
|
}
|
|
}
|
|
function getNextLanes(root3, wipLanes) {
|
|
var pendingLanes = root3.pendingLanes;
|
|
if (pendingLanes === NoLanes) {
|
|
return NoLanes;
|
|
}
|
|
var nextLanes = NoLanes;
|
|
var suspendedLanes = root3.suspendedLanes;
|
|
var pingedLanes = root3.pingedLanes;
|
|
var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
|
|
if (nonIdlePendingLanes !== NoLanes) {
|
|
var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
|
|
if (nonIdleUnblockedLanes !== NoLanes) {
|
|
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
|
|
} else {
|
|
var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
|
|
if (nonIdlePingedLanes !== NoLanes) {
|
|
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
|
|
}
|
|
}
|
|
} else {
|
|
var unblockedLanes = pendingLanes & ~suspendedLanes;
|
|
if (unblockedLanes !== NoLanes) {
|
|
nextLanes = getHighestPriorityLanes(unblockedLanes);
|
|
} else {
|
|
if (pingedLanes !== NoLanes) {
|
|
nextLanes = getHighestPriorityLanes(pingedLanes);
|
|
}
|
|
}
|
|
}
|
|
if (nextLanes === NoLanes) {
|
|
return NoLanes;
|
|
}
|
|
if (wipLanes !== NoLanes && wipLanes !== nextLanes && (wipLanes & suspendedLanes) === NoLanes) {
|
|
var nextLane = getHighestPriorityLane(nextLanes);
|
|
var wipLane = getHighestPriorityLane(wipLanes);
|
|
if (nextLane >= wipLane || nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
|
|
return wipLanes;
|
|
}
|
|
}
|
|
if ((nextLanes & InputContinuousLane) !== NoLanes) {
|
|
nextLanes |= pendingLanes & DefaultLane;
|
|
}
|
|
var entangledLanes = root3.entangledLanes;
|
|
if (entangledLanes !== NoLanes) {
|
|
var entanglements = root3.entanglements;
|
|
var lanes = nextLanes & entangledLanes;
|
|
while (lanes > 0) {
|
|
var index2 = pickArbitraryLaneIndex(lanes);
|
|
var lane = 1 << index2;
|
|
nextLanes |= entanglements[index2];
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
return nextLanes;
|
|
}
|
|
function getMostRecentEventTime(root3, lanes) {
|
|
var eventTimes = root3.eventTimes;
|
|
var mostRecentEventTime = NoTimestamp;
|
|
while (lanes > 0) {
|
|
var index2 = pickArbitraryLaneIndex(lanes);
|
|
var lane = 1 << index2;
|
|
var eventTime = eventTimes[index2];
|
|
if (eventTime > mostRecentEventTime) {
|
|
mostRecentEventTime = eventTime;
|
|
}
|
|
lanes &= ~lane;
|
|
}
|
|
return mostRecentEventTime;
|
|
}
|
|
function computeExpirationTime(lane, currentTime) {
|
|
switch (lane) {
|
|
case SyncLane:
|
|
case InputContinuousHydrationLane:
|
|
case InputContinuousLane:
|
|
return currentTime + 250;
|
|
case DefaultHydrationLane:
|
|
case DefaultLane:
|
|
case TransitionHydrationLane:
|
|
case TransitionLane1:
|
|
case TransitionLane2:
|
|
case TransitionLane3:
|
|
case TransitionLane4:
|
|
case TransitionLane5:
|
|
case TransitionLane6:
|
|
case TransitionLane7:
|
|
case TransitionLane8:
|
|
case TransitionLane9:
|
|
case TransitionLane10:
|
|
case TransitionLane11:
|
|
case TransitionLane12:
|
|
case TransitionLane13:
|
|
case TransitionLane14:
|
|
case TransitionLane15:
|
|
case TransitionLane16:
|
|
return currentTime + 5e3;
|
|
case RetryLane1:
|
|
case RetryLane2:
|
|
case RetryLane3:
|
|
case RetryLane4:
|
|
case RetryLane5:
|
|
return NoTimestamp;
|
|
case SelectiveHydrationLane:
|
|
case IdleHydrationLane:
|
|
case IdleLane:
|
|
case OffscreenLane:
|
|
return NoTimestamp;
|
|
default:
|
|
{
|
|
error("Should have found matching lanes. This is a bug in React.");
|
|
}
|
|
return NoTimestamp;
|
|
}
|
|
}
|
|
function markStarvedLanesAsExpired(root3, currentTime) {
|
|
var pendingLanes = root3.pendingLanes;
|
|
var suspendedLanes = root3.suspendedLanes;
|
|
var pingedLanes = root3.pingedLanes;
|
|
var expirationTimes = root3.expirationTimes;
|
|
var lanes = pendingLanes;
|
|
while (lanes > 0) {
|
|
var index2 = pickArbitraryLaneIndex(lanes);
|
|
var lane = 1 << index2;
|
|
var expirationTime = expirationTimes[index2];
|
|
if (expirationTime === NoTimestamp) {
|
|
if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
|
|
expirationTimes[index2] = computeExpirationTime(lane, currentTime);
|
|
}
|
|
} else if (expirationTime <= currentTime) {
|
|
root3.expiredLanes |= lane;
|
|
}
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
function getHighestPriorityPendingLanes(root3) {
|
|
return getHighestPriorityLanes(root3.pendingLanes);
|
|
}
|
|
function getLanesToRetrySynchronouslyOnError(root3) {
|
|
var everythingButOffscreen = root3.pendingLanes & ~OffscreenLane;
|
|
if (everythingButOffscreen !== NoLanes) {
|
|
return everythingButOffscreen;
|
|
}
|
|
if (everythingButOffscreen & OffscreenLane) {
|
|
return OffscreenLane;
|
|
}
|
|
return NoLanes;
|
|
}
|
|
function includesSyncLane(lanes) {
|
|
return (lanes & SyncLane) !== NoLanes;
|
|
}
|
|
function includesNonIdleWork(lanes) {
|
|
return (lanes & NonIdleLanes) !== NoLanes;
|
|
}
|
|
function includesOnlyRetries(lanes) {
|
|
return (lanes & RetryLanes) === lanes;
|
|
}
|
|
function includesOnlyNonUrgentLanes(lanes) {
|
|
var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane;
|
|
return (lanes & UrgentLanes) === NoLanes;
|
|
}
|
|
function includesOnlyTransitions(lanes) {
|
|
return (lanes & TransitionLanes) === lanes;
|
|
}
|
|
function includesBlockingLane(root3, lanes) {
|
|
var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
|
|
return (lanes & SyncDefaultLanes) !== NoLanes;
|
|
}
|
|
function includesExpiredLane(root3, lanes) {
|
|
return (lanes & root3.expiredLanes) !== NoLanes;
|
|
}
|
|
function isTransitionLane(lane) {
|
|
return (lane & TransitionLanes) !== NoLanes;
|
|
}
|
|
function claimNextTransitionLane() {
|
|
var lane = nextTransitionLane;
|
|
nextTransitionLane <<= 1;
|
|
if ((nextTransitionLane & TransitionLanes) === NoLanes) {
|
|
nextTransitionLane = TransitionLane1;
|
|
}
|
|
return lane;
|
|
}
|
|
function claimNextRetryLane() {
|
|
var lane = nextRetryLane;
|
|
nextRetryLane <<= 1;
|
|
if ((nextRetryLane & RetryLanes) === NoLanes) {
|
|
nextRetryLane = RetryLane1;
|
|
}
|
|
return lane;
|
|
}
|
|
function getHighestPriorityLane(lanes) {
|
|
return lanes & -lanes;
|
|
}
|
|
function pickArbitraryLane(lanes) {
|
|
return getHighestPriorityLane(lanes);
|
|
}
|
|
function pickArbitraryLaneIndex(lanes) {
|
|
return 31 - clz32(lanes);
|
|
}
|
|
function laneToIndex(lane) {
|
|
return pickArbitraryLaneIndex(lane);
|
|
}
|
|
function includesSomeLane(a, b) {
|
|
return (a & b) !== NoLanes;
|
|
}
|
|
function isSubsetOfLanes(set2, subset) {
|
|
return (set2 & subset) === subset;
|
|
}
|
|
function mergeLanes(a, b) {
|
|
return a | b;
|
|
}
|
|
function removeLanes(set2, subset) {
|
|
return set2 & ~subset;
|
|
}
|
|
function intersectLanes(a, b) {
|
|
return a & b;
|
|
}
|
|
function laneToLanes(lane) {
|
|
return lane;
|
|
}
|
|
function higherPriorityLane(a, b) {
|
|
return a !== NoLane && a < b ? a : b;
|
|
}
|
|
function createLaneMap(initial) {
|
|
var laneMap = [];
|
|
for (var i = 0; i < TotalLanes; i++) {
|
|
laneMap.push(initial);
|
|
}
|
|
return laneMap;
|
|
}
|
|
function markRootUpdated(root3, updateLane, eventTime) {
|
|
root3.pendingLanes |= updateLane;
|
|
if (updateLane !== IdleLane) {
|
|
root3.suspendedLanes = NoLanes;
|
|
root3.pingedLanes = NoLanes;
|
|
}
|
|
var eventTimes = root3.eventTimes;
|
|
var index2 = laneToIndex(updateLane);
|
|
eventTimes[index2] = eventTime;
|
|
}
|
|
function markRootSuspended(root3, suspendedLanes) {
|
|
root3.suspendedLanes |= suspendedLanes;
|
|
root3.pingedLanes &= ~suspendedLanes;
|
|
var expirationTimes = root3.expirationTimes;
|
|
var lanes = suspendedLanes;
|
|
while (lanes > 0) {
|
|
var index2 = pickArbitraryLaneIndex(lanes);
|
|
var lane = 1 << index2;
|
|
expirationTimes[index2] = NoTimestamp;
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
function markRootPinged(root3, pingedLanes, eventTime) {
|
|
root3.pingedLanes |= root3.suspendedLanes & pingedLanes;
|
|
}
|
|
function markRootFinished(root3, remainingLanes) {
|
|
var noLongerPendingLanes = root3.pendingLanes & ~remainingLanes;
|
|
root3.pendingLanes = remainingLanes;
|
|
root3.suspendedLanes = NoLanes;
|
|
root3.pingedLanes = NoLanes;
|
|
root3.expiredLanes &= remainingLanes;
|
|
root3.mutableReadLanes &= remainingLanes;
|
|
root3.entangledLanes &= remainingLanes;
|
|
var entanglements = root3.entanglements;
|
|
var eventTimes = root3.eventTimes;
|
|
var expirationTimes = root3.expirationTimes;
|
|
var lanes = noLongerPendingLanes;
|
|
while (lanes > 0) {
|
|
var index2 = pickArbitraryLaneIndex(lanes);
|
|
var lane = 1 << index2;
|
|
entanglements[index2] = NoLanes;
|
|
eventTimes[index2] = NoTimestamp;
|
|
expirationTimes[index2] = NoTimestamp;
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
function markRootEntangled(root3, entangledLanes) {
|
|
var rootEntangledLanes = root3.entangledLanes |= entangledLanes;
|
|
var entanglements = root3.entanglements;
|
|
var lanes = rootEntangledLanes;
|
|
while (lanes) {
|
|
var index2 = pickArbitraryLaneIndex(lanes);
|
|
var lane = 1 << index2;
|
|
if (lane & entangledLanes | entanglements[index2] & entangledLanes) {
|
|
entanglements[index2] |= entangledLanes;
|
|
}
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
function getBumpedLaneForHydration(root3, renderLanes2) {
|
|
var renderLane = getHighestPriorityLane(renderLanes2);
|
|
var lane;
|
|
switch (renderLane) {
|
|
case InputContinuousLane:
|
|
lane = InputContinuousHydrationLane;
|
|
break;
|
|
case DefaultLane:
|
|
lane = DefaultHydrationLane;
|
|
break;
|
|
case TransitionLane1:
|
|
case TransitionLane2:
|
|
case TransitionLane3:
|
|
case TransitionLane4:
|
|
case TransitionLane5:
|
|
case TransitionLane6:
|
|
case TransitionLane7:
|
|
case TransitionLane8:
|
|
case TransitionLane9:
|
|
case TransitionLane10:
|
|
case TransitionLane11:
|
|
case TransitionLane12:
|
|
case TransitionLane13:
|
|
case TransitionLane14:
|
|
case TransitionLane15:
|
|
case TransitionLane16:
|
|
case RetryLane1:
|
|
case RetryLane2:
|
|
case RetryLane3:
|
|
case RetryLane4:
|
|
case RetryLane5:
|
|
lane = TransitionHydrationLane;
|
|
break;
|
|
case IdleLane:
|
|
lane = IdleHydrationLane;
|
|
break;
|
|
default:
|
|
lane = NoLane;
|
|
break;
|
|
}
|
|
if ((lane & (root3.suspendedLanes | renderLanes2)) !== NoLane) {
|
|
return NoLane;
|
|
}
|
|
return lane;
|
|
}
|
|
function addFiberToLanesMap(root3, fiber, lanes) {
|
|
if (!isDevToolsPresent) {
|
|
return;
|
|
}
|
|
var pendingUpdatersLaneMap = root3.pendingUpdatersLaneMap;
|
|
while (lanes > 0) {
|
|
var index2 = laneToIndex(lanes);
|
|
var lane = 1 << index2;
|
|
var updaters = pendingUpdatersLaneMap[index2];
|
|
updaters.add(fiber);
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
function movePendingFibersToMemoized(root3, lanes) {
|
|
if (!isDevToolsPresent) {
|
|
return;
|
|
}
|
|
var pendingUpdatersLaneMap = root3.pendingUpdatersLaneMap;
|
|
var memoizedUpdaters = root3.memoizedUpdaters;
|
|
while (lanes > 0) {
|
|
var index2 = laneToIndex(lanes);
|
|
var lane = 1 << index2;
|
|
var updaters = pendingUpdatersLaneMap[index2];
|
|
if (updaters.size > 0) {
|
|
updaters.forEach(function(fiber) {
|
|
var alternate = fiber.alternate;
|
|
if (alternate === null || !memoizedUpdaters.has(alternate)) {
|
|
memoizedUpdaters.add(fiber);
|
|
}
|
|
});
|
|
updaters.clear();
|
|
}
|
|
lanes &= ~lane;
|
|
}
|
|
}
|
|
function getTransitionsForLanes(root3, lanes) {
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
var DiscreteEventPriority = SyncLane;
|
|
var ContinuousEventPriority = InputContinuousLane;
|
|
var DefaultEventPriority = DefaultLane;
|
|
var IdleEventPriority = IdleLane;
|
|
var currentUpdatePriority = NoLane;
|
|
function getCurrentUpdatePriority() {
|
|
return currentUpdatePriority;
|
|
}
|
|
function setCurrentUpdatePriority(newPriority) {
|
|
currentUpdatePriority = newPriority;
|
|
}
|
|
function runWithPriority(priority, fn) {
|
|
var previousPriority = currentUpdatePriority;
|
|
try {
|
|
currentUpdatePriority = priority;
|
|
return fn();
|
|
} finally {
|
|
currentUpdatePriority = previousPriority;
|
|
}
|
|
}
|
|
function higherEventPriority(a, b) {
|
|
return a !== 0 && a < b ? a : b;
|
|
}
|
|
function lowerEventPriority(a, b) {
|
|
return a === 0 || a > b ? a : b;
|
|
}
|
|
function isHigherEventPriority(a, b) {
|
|
return a !== 0 && a < b;
|
|
}
|
|
function lanesToEventPriority(lanes) {
|
|
var lane = getHighestPriorityLane(lanes);
|
|
if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
|
|
return DiscreteEventPriority;
|
|
}
|
|
if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
|
|
return ContinuousEventPriority;
|
|
}
|
|
if (includesNonIdleWork(lane)) {
|
|
return DefaultEventPriority;
|
|
}
|
|
return IdleEventPriority;
|
|
}
|
|
function isRootDehydrated(root3) {
|
|
var currentState = root3.current.memoizedState;
|
|
return currentState.isDehydrated;
|
|
}
|
|
var _attemptSynchronousHydration;
|
|
function setAttemptSynchronousHydration(fn) {
|
|
_attemptSynchronousHydration = fn;
|
|
}
|
|
function attemptSynchronousHydration(fiber) {
|
|
_attemptSynchronousHydration(fiber);
|
|
}
|
|
var attemptContinuousHydration;
|
|
function setAttemptContinuousHydration(fn) {
|
|
attemptContinuousHydration = fn;
|
|
}
|
|
var attemptHydrationAtCurrentPriority;
|
|
function setAttemptHydrationAtCurrentPriority(fn) {
|
|
attemptHydrationAtCurrentPriority = fn;
|
|
}
|
|
var getCurrentUpdatePriority$1;
|
|
function setGetCurrentUpdatePriority(fn) {
|
|
getCurrentUpdatePriority$1 = fn;
|
|
}
|
|
var attemptHydrationAtPriority;
|
|
function setAttemptHydrationAtPriority(fn) {
|
|
attemptHydrationAtPriority = fn;
|
|
}
|
|
var hasScheduledReplayAttempt = false;
|
|
var queuedDiscreteEvents = [];
|
|
var queuedFocus = null;
|
|
var queuedDrag = null;
|
|
var queuedMouse = null;
|
|
var queuedPointers = /* @__PURE__ */ new Map();
|
|
var queuedPointerCaptures = /* @__PURE__ */ new Map();
|
|
var queuedExplicitHydrationTargets = [];
|
|
var discreteReplayableEvents = [
|
|
"mousedown",
|
|
"mouseup",
|
|
"touchcancel",
|
|
"touchend",
|
|
"touchstart",
|
|
"auxclick",
|
|
"dblclick",
|
|
"pointercancel",
|
|
"pointerdown",
|
|
"pointerup",
|
|
"dragend",
|
|
"dragstart",
|
|
"drop",
|
|
"compositionend",
|
|
"compositionstart",
|
|
"keydown",
|
|
"keypress",
|
|
"keyup",
|
|
"input",
|
|
"textInput",
|
|
"copy",
|
|
"cut",
|
|
"paste",
|
|
"click",
|
|
"change",
|
|
"contextmenu",
|
|
"reset",
|
|
"submit"
|
|
];
|
|
function isDiscreteEventThatRequiresHydration(eventType) {
|
|
return discreteReplayableEvents.indexOf(eventType) > -1;
|
|
}
|
|
function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
|
|
return {
|
|
blockedOn,
|
|
domEventName,
|
|
eventSystemFlags,
|
|
nativeEvent,
|
|
targetContainers: [targetContainer]
|
|
};
|
|
}
|
|
function clearIfContinuousEvent(domEventName, nativeEvent) {
|
|
switch (domEventName) {
|
|
case "focusin":
|
|
case "focusout":
|
|
queuedFocus = null;
|
|
break;
|
|
case "dragenter":
|
|
case "dragleave":
|
|
queuedDrag = null;
|
|
break;
|
|
case "mouseover":
|
|
case "mouseout":
|
|
queuedMouse = null;
|
|
break;
|
|
case "pointerover":
|
|
case "pointerout": {
|
|
var pointerId = nativeEvent.pointerId;
|
|
queuedPointers.delete(pointerId);
|
|
break;
|
|
}
|
|
case "gotpointercapture":
|
|
case "lostpointercapture": {
|
|
var _pointerId = nativeEvent.pointerId;
|
|
queuedPointerCaptures.delete(_pointerId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
|
|
if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
|
|
var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
|
|
if (blockedOn !== null) {
|
|
var _fiber2 = getInstanceFromNode(blockedOn);
|
|
if (_fiber2 !== null) {
|
|
attemptContinuousHydration(_fiber2);
|
|
}
|
|
}
|
|
return queuedEvent;
|
|
}
|
|
existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
|
|
var targetContainers = existingQueuedEvent.targetContainers;
|
|
if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
|
|
targetContainers.push(targetContainer);
|
|
}
|
|
return existingQueuedEvent;
|
|
}
|
|
function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
|
|
switch (domEventName) {
|
|
case "focusin": {
|
|
var focusEvent = nativeEvent;
|
|
queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
|
|
return true;
|
|
}
|
|
case "dragenter": {
|
|
var dragEvent = nativeEvent;
|
|
queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
|
|
return true;
|
|
}
|
|
case "mouseover": {
|
|
var mouseEvent = nativeEvent;
|
|
queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
|
|
return true;
|
|
}
|
|
case "pointerover": {
|
|
var pointerEvent = nativeEvent;
|
|
var pointerId = pointerEvent.pointerId;
|
|
queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
|
|
return true;
|
|
}
|
|
case "gotpointercapture": {
|
|
var _pointerEvent = nativeEvent;
|
|
var _pointerId2 = _pointerEvent.pointerId;
|
|
queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function attemptExplicitHydrationTarget(queuedTarget) {
|
|
var targetInst = getClosestInstanceFromNode(queuedTarget.target);
|
|
if (targetInst !== null) {
|
|
var nearestMounted = getNearestMountedFiber(targetInst);
|
|
if (nearestMounted !== null) {
|
|
var tag = nearestMounted.tag;
|
|
if (tag === SuspenseComponent) {
|
|
var instance = getSuspenseInstanceFromFiber(nearestMounted);
|
|
if (instance !== null) {
|
|
queuedTarget.blockedOn = instance;
|
|
attemptHydrationAtPriority(queuedTarget.priority, function() {
|
|
attemptHydrationAtCurrentPriority(nearestMounted);
|
|
});
|
|
return;
|
|
}
|
|
} else if (tag === HostRoot) {
|
|
var root3 = nearestMounted.stateNode;
|
|
if (isRootDehydrated(root3)) {
|
|
queuedTarget.blockedOn = getContainerFromFiber(nearestMounted);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
queuedTarget.blockedOn = null;
|
|
}
|
|
function queueExplicitHydrationTarget(target) {
|
|
var updatePriority = getCurrentUpdatePriority$1();
|
|
var queuedTarget = {
|
|
blockedOn: null,
|
|
target,
|
|
priority: updatePriority
|
|
};
|
|
var i = 0;
|
|
for (; i < queuedExplicitHydrationTargets.length; i++) {
|
|
if (!isHigherEventPriority(updatePriority, queuedExplicitHydrationTargets[i].priority)) {
|
|
break;
|
|
}
|
|
}
|
|
queuedExplicitHydrationTargets.splice(i, 0, queuedTarget);
|
|
if (i === 0) {
|
|
attemptExplicitHydrationTarget(queuedTarget);
|
|
}
|
|
}
|
|
function attemptReplayContinuousQueuedEvent(queuedEvent) {
|
|
if (queuedEvent.blockedOn !== null) {
|
|
return false;
|
|
}
|
|
var targetContainers = queuedEvent.targetContainers;
|
|
while (targetContainers.length > 0) {
|
|
var targetContainer = targetContainers[0];
|
|
var nextBlockedOn = findInstanceBlockingEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent);
|
|
if (nextBlockedOn === null) {
|
|
{
|
|
var nativeEvent = queuedEvent.nativeEvent;
|
|
var nativeEventClone = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
|
setReplayingEvent(nativeEventClone);
|
|
nativeEvent.target.dispatchEvent(nativeEventClone);
|
|
resetReplayingEvent();
|
|
}
|
|
} else {
|
|
var _fiber3 = getInstanceFromNode(nextBlockedOn);
|
|
if (_fiber3 !== null) {
|
|
attemptContinuousHydration(_fiber3);
|
|
}
|
|
queuedEvent.blockedOn = nextBlockedOn;
|
|
return false;
|
|
}
|
|
targetContainers.shift();
|
|
}
|
|
return true;
|
|
}
|
|
function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
|
|
if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
|
|
map.delete(key);
|
|
}
|
|
}
|
|
function replayUnblockedEvents() {
|
|
hasScheduledReplayAttempt = false;
|
|
if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
|
|
queuedFocus = null;
|
|
}
|
|
if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
|
|
queuedDrag = null;
|
|
}
|
|
if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
|
|
queuedMouse = null;
|
|
}
|
|
queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
|
|
queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
|
|
}
|
|
function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
|
|
if (queuedEvent.blockedOn === unblocked) {
|
|
queuedEvent.blockedOn = null;
|
|
if (!hasScheduledReplayAttempt) {
|
|
hasScheduledReplayAttempt = true;
|
|
Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);
|
|
}
|
|
}
|
|
}
|
|
function retryIfBlockedOn(unblocked) {
|
|
if (queuedDiscreteEvents.length > 0) {
|
|
scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked);
|
|
for (var i = 1; i < queuedDiscreteEvents.length; i++) {
|
|
var queuedEvent = queuedDiscreteEvents[i];
|
|
if (queuedEvent.blockedOn === unblocked) {
|
|
queuedEvent.blockedOn = null;
|
|
}
|
|
}
|
|
}
|
|
if (queuedFocus !== null) {
|
|
scheduleCallbackIfUnblocked(queuedFocus, unblocked);
|
|
}
|
|
if (queuedDrag !== null) {
|
|
scheduleCallbackIfUnblocked(queuedDrag, unblocked);
|
|
}
|
|
if (queuedMouse !== null) {
|
|
scheduleCallbackIfUnblocked(queuedMouse, unblocked);
|
|
}
|
|
var unblock = function(queuedEvent2) {
|
|
return scheduleCallbackIfUnblocked(queuedEvent2, unblocked);
|
|
};
|
|
queuedPointers.forEach(unblock);
|
|
queuedPointerCaptures.forEach(unblock);
|
|
for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
|
|
var queuedTarget = queuedExplicitHydrationTargets[_i];
|
|
if (queuedTarget.blockedOn === unblocked) {
|
|
queuedTarget.blockedOn = null;
|
|
}
|
|
}
|
|
while (queuedExplicitHydrationTargets.length > 0) {
|
|
var nextExplicitTarget = queuedExplicitHydrationTargets[0];
|
|
if (nextExplicitTarget.blockedOn !== null) {
|
|
break;
|
|
} else {
|
|
attemptExplicitHydrationTarget(nextExplicitTarget);
|
|
if (nextExplicitTarget.blockedOn === null) {
|
|
queuedExplicitHydrationTargets.shift();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
|
var _enabled = true;
|
|
function setEnabled(enabled) {
|
|
_enabled = !!enabled;
|
|
}
|
|
function isEnabled() {
|
|
return _enabled;
|
|
}
|
|
function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
|
|
var eventPriority = getEventPriority(domEventName);
|
|
var listenerWrapper;
|
|
switch (eventPriority) {
|
|
case DiscreteEventPriority:
|
|
listenerWrapper = dispatchDiscreteEvent;
|
|
break;
|
|
case ContinuousEventPriority:
|
|
listenerWrapper = dispatchContinuousEvent;
|
|
break;
|
|
case DefaultEventPriority:
|
|
default:
|
|
listenerWrapper = dispatchEvent;
|
|
break;
|
|
}
|
|
return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
|
|
}
|
|
function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
var prevTransition = ReactCurrentBatchConfig.transition;
|
|
ReactCurrentBatchConfig.transition = null;
|
|
try {
|
|
setCurrentUpdatePriority(DiscreteEventPriority);
|
|
dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
|
|
} finally {
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig.transition = prevTransition;
|
|
}
|
|
}
|
|
function dispatchContinuousEvent(domEventName, eventSystemFlags, container, nativeEvent) {
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
var prevTransition = ReactCurrentBatchConfig.transition;
|
|
ReactCurrentBatchConfig.transition = null;
|
|
try {
|
|
setCurrentUpdatePriority(ContinuousEventPriority);
|
|
dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
|
|
} finally {
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig.transition = prevTransition;
|
|
}
|
|
}
|
|
function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
|
|
if (!_enabled) {
|
|
return;
|
|
}
|
|
{
|
|
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent);
|
|
}
|
|
}
|
|
function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
|
|
var blockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
|
|
if (blockedOn === null) {
|
|
dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
|
|
clearIfContinuousEvent(domEventName, nativeEvent);
|
|
return;
|
|
}
|
|
if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
|
|
nativeEvent.stopPropagation();
|
|
return;
|
|
}
|
|
clearIfContinuousEvent(domEventName, nativeEvent);
|
|
if (eventSystemFlags & IS_CAPTURE_PHASE && isDiscreteEventThatRequiresHydration(domEventName)) {
|
|
while (blockedOn !== null) {
|
|
var fiber = getInstanceFromNode(blockedOn);
|
|
if (fiber !== null) {
|
|
attemptSynchronousHydration(fiber);
|
|
}
|
|
var nextBlockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
|
|
if (nextBlockedOn === null) {
|
|
dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
|
|
}
|
|
if (nextBlockedOn === blockedOn) {
|
|
break;
|
|
}
|
|
blockedOn = nextBlockedOn;
|
|
}
|
|
if (blockedOn !== null) {
|
|
nativeEvent.stopPropagation();
|
|
}
|
|
return;
|
|
}
|
|
dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
|
|
}
|
|
var return_targetInst = null;
|
|
function findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
|
|
return_targetInst = null;
|
|
var nativeEventTarget = getEventTarget(nativeEvent);
|
|
var targetInst = getClosestInstanceFromNode(nativeEventTarget);
|
|
if (targetInst !== null) {
|
|
var nearestMounted = getNearestMountedFiber(targetInst);
|
|
if (nearestMounted === null) {
|
|
targetInst = null;
|
|
} else {
|
|
var tag = nearestMounted.tag;
|
|
if (tag === SuspenseComponent) {
|
|
var instance = getSuspenseInstanceFromFiber(nearestMounted);
|
|
if (instance !== null) {
|
|
return instance;
|
|
}
|
|
targetInst = null;
|
|
} else if (tag === HostRoot) {
|
|
var root3 = nearestMounted.stateNode;
|
|
if (isRootDehydrated(root3)) {
|
|
return getContainerFromFiber(nearestMounted);
|
|
}
|
|
targetInst = null;
|
|
} else if (nearestMounted !== targetInst) {
|
|
targetInst = null;
|
|
}
|
|
}
|
|
}
|
|
return_targetInst = targetInst;
|
|
return null;
|
|
}
|
|
function getEventPriority(domEventName) {
|
|
switch (domEventName) {
|
|
case "cancel":
|
|
case "click":
|
|
case "close":
|
|
case "contextmenu":
|
|
case "copy":
|
|
case "cut":
|
|
case "auxclick":
|
|
case "dblclick":
|
|
case "dragend":
|
|
case "dragstart":
|
|
case "drop":
|
|
case "focusin":
|
|
case "focusout":
|
|
case "input":
|
|
case "invalid":
|
|
case "keydown":
|
|
case "keypress":
|
|
case "keyup":
|
|
case "mousedown":
|
|
case "mouseup":
|
|
case "paste":
|
|
case "pause":
|
|
case "play":
|
|
case "pointercancel":
|
|
case "pointerdown":
|
|
case "pointerup":
|
|
case "ratechange":
|
|
case "reset":
|
|
case "resize":
|
|
case "seeked":
|
|
case "submit":
|
|
case "touchcancel":
|
|
case "touchend":
|
|
case "touchstart":
|
|
case "volumechange":
|
|
case "change":
|
|
case "selectionchange":
|
|
case "textInput":
|
|
case "compositionstart":
|
|
case "compositionend":
|
|
case "compositionupdate":
|
|
case "beforeblur":
|
|
case "afterblur":
|
|
case "beforeinput":
|
|
case "blur":
|
|
case "fullscreenchange":
|
|
case "focus":
|
|
case "hashchange":
|
|
case "popstate":
|
|
case "select":
|
|
case "selectstart":
|
|
return DiscreteEventPriority;
|
|
case "drag":
|
|
case "dragenter":
|
|
case "dragexit":
|
|
case "dragleave":
|
|
case "dragover":
|
|
case "mousemove":
|
|
case "mouseout":
|
|
case "mouseover":
|
|
case "pointermove":
|
|
case "pointerout":
|
|
case "pointerover":
|
|
case "scroll":
|
|
case "toggle":
|
|
case "touchmove":
|
|
case "wheel":
|
|
case "mouseenter":
|
|
case "mouseleave":
|
|
case "pointerenter":
|
|
case "pointerleave":
|
|
return ContinuousEventPriority;
|
|
case "message": {
|
|
var schedulerPriority = getCurrentPriorityLevel();
|
|
switch (schedulerPriority) {
|
|
case ImmediatePriority:
|
|
return DiscreteEventPriority;
|
|
case UserBlockingPriority:
|
|
return ContinuousEventPriority;
|
|
case NormalPriority:
|
|
case LowPriority:
|
|
return DefaultEventPriority;
|
|
case IdlePriority:
|
|
return IdleEventPriority;
|
|
default:
|
|
return DefaultEventPriority;
|
|
}
|
|
}
|
|
default:
|
|
return DefaultEventPriority;
|
|
}
|
|
}
|
|
function addEventBubbleListener(target, eventType, listener) {
|
|
target.addEventListener(eventType, listener, false);
|
|
return listener;
|
|
}
|
|
function addEventCaptureListener(target, eventType, listener) {
|
|
target.addEventListener(eventType, listener, true);
|
|
return listener;
|
|
}
|
|
function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
|
|
target.addEventListener(eventType, listener, {
|
|
capture: true,
|
|
passive
|
|
});
|
|
return listener;
|
|
}
|
|
function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
|
|
target.addEventListener(eventType, listener, {
|
|
passive
|
|
});
|
|
return listener;
|
|
}
|
|
var root2 = null;
|
|
var startText = null;
|
|
var fallbackText = null;
|
|
function initialize(nativeEventTarget) {
|
|
root2 = nativeEventTarget;
|
|
startText = getText();
|
|
return true;
|
|
}
|
|
function reset() {
|
|
root2 = null;
|
|
startText = null;
|
|
fallbackText = null;
|
|
}
|
|
function getData() {
|
|
if (fallbackText) {
|
|
return fallbackText;
|
|
}
|
|
var start;
|
|
var startValue = startText;
|
|
var startLength = startValue.length;
|
|
var end;
|
|
var endValue = getText();
|
|
var endLength = endValue.length;
|
|
for (start = 0; start < startLength; start++) {
|
|
if (startValue[start] !== endValue[start]) {
|
|
break;
|
|
}
|
|
}
|
|
var minEnd = startLength - start;
|
|
for (end = 1; end <= minEnd; end++) {
|
|
if (startValue[startLength - end] !== endValue[endLength - end]) {
|
|
break;
|
|
}
|
|
}
|
|
var sliceTail = end > 1 ? 1 - end : void 0;
|
|
fallbackText = endValue.slice(start, sliceTail);
|
|
return fallbackText;
|
|
}
|
|
function getText() {
|
|
if ("value" in root2) {
|
|
return root2.value;
|
|
}
|
|
return root2.textContent;
|
|
}
|
|
function getEventCharCode(nativeEvent) {
|
|
var charCode;
|
|
var keyCode = nativeEvent.keyCode;
|
|
if ("charCode" in nativeEvent) {
|
|
charCode = nativeEvent.charCode;
|
|
if (charCode === 0 && keyCode === 13) {
|
|
charCode = 13;
|
|
}
|
|
} else {
|
|
charCode = keyCode;
|
|
}
|
|
if (charCode === 10) {
|
|
charCode = 13;
|
|
}
|
|
if (charCode >= 32 || charCode === 13) {
|
|
return charCode;
|
|
}
|
|
return 0;
|
|
}
|
|
function functionThatReturnsTrue() {
|
|
return true;
|
|
}
|
|
function functionThatReturnsFalse() {
|
|
return false;
|
|
}
|
|
function createSyntheticEvent(Interface) {
|
|
function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
|
|
this._reactName = reactName;
|
|
this._targetInst = targetInst;
|
|
this.type = reactEventType;
|
|
this.nativeEvent = nativeEvent;
|
|
this.target = nativeEventTarget;
|
|
this.currentTarget = null;
|
|
for (var _propName in Interface) {
|
|
if (!Interface.hasOwnProperty(_propName)) {
|
|
continue;
|
|
}
|
|
var normalize = Interface[_propName];
|
|
if (normalize) {
|
|
this[_propName] = normalize(nativeEvent);
|
|
} else {
|
|
this[_propName] = nativeEvent[_propName];
|
|
}
|
|
}
|
|
var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
|
|
if (defaultPrevented) {
|
|
this.isDefaultPrevented = functionThatReturnsTrue;
|
|
} else {
|
|
this.isDefaultPrevented = functionThatReturnsFalse;
|
|
}
|
|
this.isPropagationStopped = functionThatReturnsFalse;
|
|
return this;
|
|
}
|
|
assign(SyntheticBaseEvent.prototype, {
|
|
preventDefault: function() {
|
|
this.defaultPrevented = true;
|
|
var event = this.nativeEvent;
|
|
if (!event) {
|
|
return;
|
|
}
|
|
if (event.preventDefault) {
|
|
event.preventDefault();
|
|
} else if (typeof event.returnValue !== "unknown") {
|
|
event.returnValue = false;
|
|
}
|
|
this.isDefaultPrevented = functionThatReturnsTrue;
|
|
},
|
|
stopPropagation: function() {
|
|
var event = this.nativeEvent;
|
|
if (!event) {
|
|
return;
|
|
}
|
|
if (event.stopPropagation) {
|
|
event.stopPropagation();
|
|
} else if (typeof event.cancelBubble !== "unknown") {
|
|
event.cancelBubble = true;
|
|
}
|
|
this.isPropagationStopped = functionThatReturnsTrue;
|
|
},
|
|
persist: function() {
|
|
},
|
|
isPersistent: functionThatReturnsTrue
|
|
});
|
|
return SyntheticBaseEvent;
|
|
}
|
|
var EventInterface = {
|
|
eventPhase: 0,
|
|
bubbles: 0,
|
|
cancelable: 0,
|
|
timeStamp: function(event) {
|
|
return event.timeStamp || Date.now();
|
|
},
|
|
defaultPrevented: 0,
|
|
isTrusted: 0
|
|
};
|
|
var SyntheticEvent = createSyntheticEvent(EventInterface);
|
|
var UIEventInterface = assign({}, EventInterface, {
|
|
view: 0,
|
|
detail: 0
|
|
});
|
|
var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
|
|
var lastMovementX;
|
|
var lastMovementY;
|
|
var lastMouseEvent;
|
|
function updateMouseMovementPolyfillState(event) {
|
|
if (event !== lastMouseEvent) {
|
|
if (lastMouseEvent && event.type === "mousemove") {
|
|
lastMovementX = event.screenX - lastMouseEvent.screenX;
|
|
lastMovementY = event.screenY - lastMouseEvent.screenY;
|
|
} else {
|
|
lastMovementX = 0;
|
|
lastMovementY = 0;
|
|
}
|
|
lastMouseEvent = event;
|
|
}
|
|
}
|
|
var MouseEventInterface = assign({}, UIEventInterface, {
|
|
screenX: 0,
|
|
screenY: 0,
|
|
clientX: 0,
|
|
clientY: 0,
|
|
pageX: 0,
|
|
pageY: 0,
|
|
ctrlKey: 0,
|
|
shiftKey: 0,
|
|
altKey: 0,
|
|
metaKey: 0,
|
|
getModifierState: getEventModifierState,
|
|
button: 0,
|
|
buttons: 0,
|
|
relatedTarget: function(event) {
|
|
if (event.relatedTarget === void 0)
|
|
return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
|
|
return event.relatedTarget;
|
|
},
|
|
movementX: function(event) {
|
|
if ("movementX" in event) {
|
|
return event.movementX;
|
|
}
|
|
updateMouseMovementPolyfillState(event);
|
|
return lastMovementX;
|
|
},
|
|
movementY: function(event) {
|
|
if ("movementY" in event) {
|
|
return event.movementY;
|
|
}
|
|
return lastMovementY;
|
|
}
|
|
});
|
|
var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
|
|
var DragEventInterface = assign({}, MouseEventInterface, {
|
|
dataTransfer: 0
|
|
});
|
|
var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
|
|
var FocusEventInterface = assign({}, UIEventInterface, {
|
|
relatedTarget: 0
|
|
});
|
|
var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
|
|
var AnimationEventInterface = assign({}, EventInterface, {
|
|
animationName: 0,
|
|
elapsedTime: 0,
|
|
pseudoElement: 0
|
|
});
|
|
var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
|
|
var ClipboardEventInterface = assign({}, EventInterface, {
|
|
clipboardData: function(event) {
|
|
return "clipboardData" in event ? event.clipboardData : window.clipboardData;
|
|
}
|
|
});
|
|
var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
|
|
var CompositionEventInterface = assign({}, EventInterface, {
|
|
data: 0
|
|
});
|
|
var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
|
|
var SyntheticInputEvent = SyntheticCompositionEvent;
|
|
var normalizeKey = {
|
|
Esc: "Escape",
|
|
Spacebar: " ",
|
|
Left: "ArrowLeft",
|
|
Up: "ArrowUp",
|
|
Right: "ArrowRight",
|
|
Down: "ArrowDown",
|
|
Del: "Delete",
|
|
Win: "OS",
|
|
Menu: "ContextMenu",
|
|
Apps: "ContextMenu",
|
|
Scroll: "ScrollLock",
|
|
MozPrintableKey: "Unidentified"
|
|
};
|
|
var translateToKey = {
|
|
"8": "Backspace",
|
|
"9": "Tab",
|
|
"12": "Clear",
|
|
"13": "Enter",
|
|
"16": "Shift",
|
|
"17": "Control",
|
|
"18": "Alt",
|
|
"19": "Pause",
|
|
"20": "CapsLock",
|
|
"27": "Escape",
|
|
"32": " ",
|
|
"33": "PageUp",
|
|
"34": "PageDown",
|
|
"35": "End",
|
|
"36": "Home",
|
|
"37": "ArrowLeft",
|
|
"38": "ArrowUp",
|
|
"39": "ArrowRight",
|
|
"40": "ArrowDown",
|
|
"45": "Insert",
|
|
"46": "Delete",
|
|
"112": "F1",
|
|
"113": "F2",
|
|
"114": "F3",
|
|
"115": "F4",
|
|
"116": "F5",
|
|
"117": "F6",
|
|
"118": "F7",
|
|
"119": "F8",
|
|
"120": "F9",
|
|
"121": "F10",
|
|
"122": "F11",
|
|
"123": "F12",
|
|
"144": "NumLock",
|
|
"145": "ScrollLock",
|
|
"224": "Meta"
|
|
};
|
|
function getEventKey(nativeEvent) {
|
|
if (nativeEvent.key) {
|
|
var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
|
|
if (key !== "Unidentified") {
|
|
return key;
|
|
}
|
|
}
|
|
if (nativeEvent.type === "keypress") {
|
|
var charCode = getEventCharCode(nativeEvent);
|
|
return charCode === 13 ? "Enter" : String.fromCharCode(charCode);
|
|
}
|
|
if (nativeEvent.type === "keydown" || nativeEvent.type === "keyup") {
|
|
return translateToKey[nativeEvent.keyCode] || "Unidentified";
|
|
}
|
|
return "";
|
|
}
|
|
var modifierKeyToProp = {
|
|
Alt: "altKey",
|
|
Control: "ctrlKey",
|
|
Meta: "metaKey",
|
|
Shift: "shiftKey"
|
|
};
|
|
function modifierStateGetter(keyArg) {
|
|
var syntheticEvent = this;
|
|
var nativeEvent = syntheticEvent.nativeEvent;
|
|
if (nativeEvent.getModifierState) {
|
|
return nativeEvent.getModifierState(keyArg);
|
|
}
|
|
var keyProp = modifierKeyToProp[keyArg];
|
|
return keyProp ? !!nativeEvent[keyProp] : false;
|
|
}
|
|
function getEventModifierState(nativeEvent) {
|
|
return modifierStateGetter;
|
|
}
|
|
var KeyboardEventInterface = assign({}, UIEventInterface, {
|
|
key: getEventKey,
|
|
code: 0,
|
|
location: 0,
|
|
ctrlKey: 0,
|
|
shiftKey: 0,
|
|
altKey: 0,
|
|
metaKey: 0,
|
|
repeat: 0,
|
|
locale: 0,
|
|
getModifierState: getEventModifierState,
|
|
charCode: function(event) {
|
|
if (event.type === "keypress") {
|
|
return getEventCharCode(event);
|
|
}
|
|
return 0;
|
|
},
|
|
keyCode: function(event) {
|
|
if (event.type === "keydown" || event.type === "keyup") {
|
|
return event.keyCode;
|
|
}
|
|
return 0;
|
|
},
|
|
which: function(event) {
|
|
if (event.type === "keypress") {
|
|
return getEventCharCode(event);
|
|
}
|
|
if (event.type === "keydown" || event.type === "keyup") {
|
|
return event.keyCode;
|
|
}
|
|
return 0;
|
|
}
|
|
});
|
|
var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
|
|
var PointerEventInterface = assign({}, MouseEventInterface, {
|
|
pointerId: 0,
|
|
width: 0,
|
|
height: 0,
|
|
pressure: 0,
|
|
tangentialPressure: 0,
|
|
tiltX: 0,
|
|
tiltY: 0,
|
|
twist: 0,
|
|
pointerType: 0,
|
|
isPrimary: 0
|
|
});
|
|
var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
|
|
var TouchEventInterface = assign({}, UIEventInterface, {
|
|
touches: 0,
|
|
targetTouches: 0,
|
|
changedTouches: 0,
|
|
altKey: 0,
|
|
metaKey: 0,
|
|
ctrlKey: 0,
|
|
shiftKey: 0,
|
|
getModifierState: getEventModifierState
|
|
});
|
|
var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
|
|
var TransitionEventInterface = assign({}, EventInterface, {
|
|
propertyName: 0,
|
|
elapsedTime: 0,
|
|
pseudoElement: 0
|
|
});
|
|
var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
|
|
var WheelEventInterface = assign({}, MouseEventInterface, {
|
|
deltaX: function(event) {
|
|
return "deltaX" in event ? event.deltaX : "wheelDeltaX" in event ? -event.wheelDeltaX : 0;
|
|
},
|
|
deltaY: function(event) {
|
|
return "deltaY" in event ? event.deltaY : "wheelDeltaY" in event ? -event.wheelDeltaY : "wheelDelta" in event ? -event.wheelDelta : 0;
|
|
},
|
|
deltaZ: 0,
|
|
deltaMode: 0
|
|
});
|
|
var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
|
|
var END_KEYCODES = [9, 13, 27, 32];
|
|
var START_KEYCODE = 229;
|
|
var canUseCompositionEvent = canUseDOM && "CompositionEvent" in window;
|
|
var documentMode = null;
|
|
if (canUseDOM && "documentMode" in document) {
|
|
documentMode = document.documentMode;
|
|
}
|
|
var canUseTextInputEvent = canUseDOM && "TextEvent" in window && !documentMode;
|
|
var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
|
|
var SPACEBAR_CODE = 32;
|
|
var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
|
|
function registerEvents() {
|
|
registerTwoPhaseEvent("onBeforeInput", ["compositionend", "keypress", "textInput", "paste"]);
|
|
registerTwoPhaseEvent("onCompositionEnd", ["compositionend", "focusout", "keydown", "keypress", "keyup", "mousedown"]);
|
|
registerTwoPhaseEvent("onCompositionStart", ["compositionstart", "focusout", "keydown", "keypress", "keyup", "mousedown"]);
|
|
registerTwoPhaseEvent("onCompositionUpdate", ["compositionupdate", "focusout", "keydown", "keypress", "keyup", "mousedown"]);
|
|
}
|
|
var hasSpaceKeypress = false;
|
|
function isKeypressCommand(nativeEvent) {
|
|
return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && !(nativeEvent.ctrlKey && nativeEvent.altKey);
|
|
}
|
|
function getCompositionEventType(domEventName) {
|
|
switch (domEventName) {
|
|
case "compositionstart":
|
|
return "onCompositionStart";
|
|
case "compositionend":
|
|
return "onCompositionEnd";
|
|
case "compositionupdate":
|
|
return "onCompositionUpdate";
|
|
}
|
|
}
|
|
function isFallbackCompositionStart(domEventName, nativeEvent) {
|
|
return domEventName === "keydown" && nativeEvent.keyCode === START_KEYCODE;
|
|
}
|
|
function isFallbackCompositionEnd(domEventName, nativeEvent) {
|
|
switch (domEventName) {
|
|
case "keyup":
|
|
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
|
|
case "keydown":
|
|
return nativeEvent.keyCode !== START_KEYCODE;
|
|
case "keypress":
|
|
case "mousedown":
|
|
case "focusout":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function getDataFromCustomEvent(nativeEvent) {
|
|
var detail = nativeEvent.detail;
|
|
if (typeof detail === "object" && "data" in detail) {
|
|
return detail.data;
|
|
}
|
|
return null;
|
|
}
|
|
function isUsingKoreanIME(nativeEvent) {
|
|
return nativeEvent.locale === "ko";
|
|
}
|
|
var isComposing = false;
|
|
function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
|
|
var eventType;
|
|
var fallbackData;
|
|
if (canUseCompositionEvent) {
|
|
eventType = getCompositionEventType(domEventName);
|
|
} else if (!isComposing) {
|
|
if (isFallbackCompositionStart(domEventName, nativeEvent)) {
|
|
eventType = "onCompositionStart";
|
|
}
|
|
} else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
|
|
eventType = "onCompositionEnd";
|
|
}
|
|
if (!eventType) {
|
|
return null;
|
|
}
|
|
if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
|
|
if (!isComposing && eventType === "onCompositionStart") {
|
|
isComposing = initialize(nativeEventTarget);
|
|
} else if (eventType === "onCompositionEnd") {
|
|
if (isComposing) {
|
|
fallbackData = getData();
|
|
}
|
|
}
|
|
}
|
|
var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
|
|
if (listeners.length > 0) {
|
|
var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
|
|
dispatchQueue.push({
|
|
event,
|
|
listeners
|
|
});
|
|
if (fallbackData) {
|
|
event.data = fallbackData;
|
|
} else {
|
|
var customData = getDataFromCustomEvent(nativeEvent);
|
|
if (customData !== null) {
|
|
event.data = customData;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function getNativeBeforeInputChars(domEventName, nativeEvent) {
|
|
switch (domEventName) {
|
|
case "compositionend":
|
|
return getDataFromCustomEvent(nativeEvent);
|
|
case "keypress":
|
|
var which = nativeEvent.which;
|
|
if (which !== SPACEBAR_CODE) {
|
|
return null;
|
|
}
|
|
hasSpaceKeypress = true;
|
|
return SPACEBAR_CHAR;
|
|
case "textInput":
|
|
var chars = nativeEvent.data;
|
|
if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
|
|
return null;
|
|
}
|
|
return chars;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
function getFallbackBeforeInputChars(domEventName, nativeEvent) {
|
|
if (isComposing) {
|
|
if (domEventName === "compositionend" || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
|
|
var chars = getData();
|
|
reset();
|
|
isComposing = false;
|
|
return chars;
|
|
}
|
|
return null;
|
|
}
|
|
switch (domEventName) {
|
|
case "paste":
|
|
return null;
|
|
case "keypress":
|
|
if (!isKeypressCommand(nativeEvent)) {
|
|
if (nativeEvent.char && nativeEvent.char.length > 1) {
|
|
return nativeEvent.char;
|
|
} else if (nativeEvent.which) {
|
|
return String.fromCharCode(nativeEvent.which);
|
|
}
|
|
}
|
|
return null;
|
|
case "compositionend":
|
|
return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
|
|
var chars;
|
|
if (canUseTextInputEvent) {
|
|
chars = getNativeBeforeInputChars(domEventName, nativeEvent);
|
|
} else {
|
|
chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
|
|
}
|
|
if (!chars) {
|
|
return null;
|
|
}
|
|
var listeners = accumulateTwoPhaseListeners(targetInst, "onBeforeInput");
|
|
if (listeners.length > 0) {
|
|
var event = new SyntheticInputEvent("onBeforeInput", "beforeinput", null, nativeEvent, nativeEventTarget);
|
|
dispatchQueue.push({
|
|
event,
|
|
listeners
|
|
});
|
|
event.data = chars;
|
|
}
|
|
}
|
|
function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
|
|
extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
|
|
extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
|
|
}
|
|
var supportedInputTypes = {
|
|
color: true,
|
|
date: true,
|
|
datetime: true,
|
|
"datetime-local": true,
|
|
email: true,
|
|
month: true,
|
|
number: true,
|
|
password: true,
|
|
range: true,
|
|
search: true,
|
|
tel: true,
|
|
text: true,
|
|
time: true,
|
|
url: true,
|
|
week: true
|
|
};
|
|
function isTextInputElement(elem) {
|
|
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
|
|
if (nodeName === "input") {
|
|
return !!supportedInputTypes[elem.type];
|
|
}
|
|
if (nodeName === "textarea") {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isEventSupported(eventNameSuffix) {
|
|
if (!canUseDOM) {
|
|
return false;
|
|
}
|
|
var eventName = "on" + eventNameSuffix;
|
|
var isSupported = eventName in document;
|
|
if (!isSupported) {
|
|
var element = document.createElement("div");
|
|
element.setAttribute(eventName, "return;");
|
|
isSupported = typeof element[eventName] === "function";
|
|
}
|
|
return isSupported;
|
|
}
|
|
function registerEvents$1() {
|
|
registerTwoPhaseEvent("onChange", ["change", "click", "focusin", "focusout", "input", "keydown", "keyup", "selectionchange"]);
|
|
}
|
|
function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
|
|
enqueueStateRestore(target);
|
|
var listeners = accumulateTwoPhaseListeners(inst, "onChange");
|
|
if (listeners.length > 0) {
|
|
var event = new SyntheticEvent("onChange", "change", null, nativeEvent, target);
|
|
dispatchQueue.push({
|
|
event,
|
|
listeners
|
|
});
|
|
}
|
|
}
|
|
var activeElement = null;
|
|
var activeElementInst = null;
|
|
function shouldUseChangeEvent(elem) {
|
|
var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
|
|
return nodeName === "select" || nodeName === "input" && elem.type === "file";
|
|
}
|
|
function manualDispatchChangeEvent(nativeEvent) {
|
|
var dispatchQueue = [];
|
|
createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent));
|
|
batchedUpdates(runEventInBatch, dispatchQueue);
|
|
}
|
|
function runEventInBatch(dispatchQueue) {
|
|
processDispatchQueue(dispatchQueue, 0);
|
|
}
|
|
function getInstIfValueChanged(targetInst) {
|
|
var targetNode = getNodeFromInstance(targetInst);
|
|
if (updateValueIfChanged(targetNode)) {
|
|
return targetInst;
|
|
}
|
|
}
|
|
function getTargetInstForChangeEvent(domEventName, targetInst) {
|
|
if (domEventName === "change") {
|
|
return targetInst;
|
|
}
|
|
}
|
|
var isInputEventSupported = false;
|
|
if (canUseDOM) {
|
|
isInputEventSupported = isEventSupported("input") && (!document.documentMode || document.documentMode > 9);
|
|
}
|
|
function startWatchingForValueChange(target, targetInst) {
|
|
activeElement = target;
|
|
activeElementInst = targetInst;
|
|
activeElement.attachEvent("onpropertychange", handlePropertyChange);
|
|
}
|
|
function stopWatchingForValueChange() {
|
|
if (!activeElement) {
|
|
return;
|
|
}
|
|
activeElement.detachEvent("onpropertychange", handlePropertyChange);
|
|
activeElement = null;
|
|
activeElementInst = null;
|
|
}
|
|
function handlePropertyChange(nativeEvent) {
|
|
if (nativeEvent.propertyName !== "value") {
|
|
return;
|
|
}
|
|
if (getInstIfValueChanged(activeElementInst)) {
|
|
manualDispatchChangeEvent(nativeEvent);
|
|
}
|
|
}
|
|
function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
|
|
if (domEventName === "focusin") {
|
|
stopWatchingForValueChange();
|
|
startWatchingForValueChange(target, targetInst);
|
|
} else if (domEventName === "focusout") {
|
|
stopWatchingForValueChange();
|
|
}
|
|
}
|
|
function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
|
|
if (domEventName === "selectionchange" || domEventName === "keyup" || domEventName === "keydown") {
|
|
return getInstIfValueChanged(activeElementInst);
|
|
}
|
|
}
|
|
function shouldUseClickEvent(elem) {
|
|
var nodeName = elem.nodeName;
|
|
return nodeName && nodeName.toLowerCase() === "input" && (elem.type === "checkbox" || elem.type === "radio");
|
|
}
|
|
function getTargetInstForClickEvent(domEventName, targetInst) {
|
|
if (domEventName === "click") {
|
|
return getInstIfValueChanged(targetInst);
|
|
}
|
|
}
|
|
function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
|
|
if (domEventName === "input" || domEventName === "change") {
|
|
return getInstIfValueChanged(targetInst);
|
|
}
|
|
}
|
|
function handleControlledInputBlur(node) {
|
|
var state = node._wrapperState;
|
|
if (!state || !state.controlled || node.type !== "number") {
|
|
return;
|
|
}
|
|
{
|
|
setDefaultValue(node, "number", node.value);
|
|
}
|
|
}
|
|
function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
|
|
var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
|
|
var getTargetInstFunc, handleEventFunc;
|
|
if (shouldUseChangeEvent(targetNode)) {
|
|
getTargetInstFunc = getTargetInstForChangeEvent;
|
|
} else if (isTextInputElement(targetNode)) {
|
|
if (isInputEventSupported) {
|
|
getTargetInstFunc = getTargetInstForInputOrChangeEvent;
|
|
} else {
|
|
getTargetInstFunc = getTargetInstForInputEventPolyfill;
|
|
handleEventFunc = handleEventsForInputEventPolyfill;
|
|
}
|
|
} else if (shouldUseClickEvent(targetNode)) {
|
|
getTargetInstFunc = getTargetInstForClickEvent;
|
|
}
|
|
if (getTargetInstFunc) {
|
|
var inst = getTargetInstFunc(domEventName, targetInst);
|
|
if (inst) {
|
|
createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
|
|
return;
|
|
}
|
|
}
|
|
if (handleEventFunc) {
|
|
handleEventFunc(domEventName, targetNode, targetInst);
|
|
}
|
|
if (domEventName === "focusout") {
|
|
handleControlledInputBlur(targetNode);
|
|
}
|
|
}
|
|
function registerEvents$2() {
|
|
registerDirectEvent("onMouseEnter", ["mouseout", "mouseover"]);
|
|
registerDirectEvent("onMouseLeave", ["mouseout", "mouseover"]);
|
|
registerDirectEvent("onPointerEnter", ["pointerout", "pointerover"]);
|
|
registerDirectEvent("onPointerLeave", ["pointerout", "pointerover"]);
|
|
}
|
|
function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
|
|
var isOverEvent = domEventName === "mouseover" || domEventName === "pointerover";
|
|
var isOutEvent = domEventName === "mouseout" || domEventName === "pointerout";
|
|
if (isOverEvent && !isReplayingEvent(nativeEvent)) {
|
|
var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
|
|
if (related) {
|
|
if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (!isOutEvent && !isOverEvent) {
|
|
return;
|
|
}
|
|
var win;
|
|
if (nativeEventTarget.window === nativeEventTarget) {
|
|
win = nativeEventTarget;
|
|
} else {
|
|
var doc = nativeEventTarget.ownerDocument;
|
|
if (doc) {
|
|
win = doc.defaultView || doc.parentWindow;
|
|
} else {
|
|
win = window;
|
|
}
|
|
}
|
|
var from;
|
|
var to;
|
|
if (isOutEvent) {
|
|
var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
|
|
from = targetInst;
|
|
to = _related ? getClosestInstanceFromNode(_related) : null;
|
|
if (to !== null) {
|
|
var nearestMounted = getNearestMountedFiber(to);
|
|
if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
|
|
to = null;
|
|
}
|
|
}
|
|
} else {
|
|
from = null;
|
|
to = targetInst;
|
|
}
|
|
if (from === to) {
|
|
return;
|
|
}
|
|
var SyntheticEventCtor = SyntheticMouseEvent;
|
|
var leaveEventType = "onMouseLeave";
|
|
var enterEventType = "onMouseEnter";
|
|
var eventTypePrefix = "mouse";
|
|
if (domEventName === "pointerout" || domEventName === "pointerover") {
|
|
SyntheticEventCtor = SyntheticPointerEvent;
|
|
leaveEventType = "onPointerLeave";
|
|
enterEventType = "onPointerEnter";
|
|
eventTypePrefix = "pointer";
|
|
}
|
|
var fromNode = from == null ? win : getNodeFromInstance(from);
|
|
var toNode = to == null ? win : getNodeFromInstance(to);
|
|
var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + "leave", from, nativeEvent, nativeEventTarget);
|
|
leave.target = fromNode;
|
|
leave.relatedTarget = toNode;
|
|
var enter = null;
|
|
var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
|
|
if (nativeTargetInst === targetInst) {
|
|
var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + "enter", to, nativeEvent, nativeEventTarget);
|
|
enterEvent.target = toNode;
|
|
enterEvent.relatedTarget = fromNode;
|
|
enter = enterEvent;
|
|
}
|
|
accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
|
|
}
|
|
function is(x, y) {
|
|
return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
|
|
}
|
|
var objectIs = typeof Object.is === "function" ? Object.is : is;
|
|
function shallowEqual(objA, objB) {
|
|
if (objectIs(objA, objB)) {
|
|
return true;
|
|
}
|
|
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
|
return false;
|
|
}
|
|
var keysA = Object.keys(objA);
|
|
var keysB = Object.keys(objB);
|
|
if (keysA.length !== keysB.length) {
|
|
return false;
|
|
}
|
|
for (var i = 0; i < keysA.length; i++) {
|
|
var currentKey = keysA[i];
|
|
if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function getLeafNode(node) {
|
|
while (node && node.firstChild) {
|
|
node = node.firstChild;
|
|
}
|
|
return node;
|
|
}
|
|
function getSiblingNode(node) {
|
|
while (node) {
|
|
if (node.nextSibling) {
|
|
return node.nextSibling;
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
}
|
|
function getNodeForCharacterOffset(root3, offset) {
|
|
var node = getLeafNode(root3);
|
|
var nodeStart = 0;
|
|
var nodeEnd = 0;
|
|
while (node) {
|
|
if (node.nodeType === TEXT_NODE) {
|
|
nodeEnd = nodeStart + node.textContent.length;
|
|
if (nodeStart <= offset && nodeEnd >= offset) {
|
|
return {
|
|
node,
|
|
offset: offset - nodeStart
|
|
};
|
|
}
|
|
nodeStart = nodeEnd;
|
|
}
|
|
node = getLeafNode(getSiblingNode(node));
|
|
}
|
|
}
|
|
function getOffsets(outerNode) {
|
|
var ownerDocument = outerNode.ownerDocument;
|
|
var win = ownerDocument && ownerDocument.defaultView || window;
|
|
var selection = win.getSelection && win.getSelection();
|
|
if (!selection || selection.rangeCount === 0) {
|
|
return null;
|
|
}
|
|
var anchorNode = selection.anchorNode, anchorOffset = selection.anchorOffset, focusNode = selection.focusNode, focusOffset = selection.focusOffset;
|
|
try {
|
|
anchorNode.nodeType;
|
|
focusNode.nodeType;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
|
|
}
|
|
function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
|
|
var length = 0;
|
|
var start = -1;
|
|
var end = -1;
|
|
var indexWithinAnchor = 0;
|
|
var indexWithinFocus = 0;
|
|
var node = outerNode;
|
|
var parentNode = null;
|
|
outer:
|
|
while (true) {
|
|
var next = null;
|
|
while (true) {
|
|
if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
|
|
start = length + anchorOffset;
|
|
}
|
|
if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
|
|
end = length + focusOffset;
|
|
}
|
|
if (node.nodeType === TEXT_NODE) {
|
|
length += node.nodeValue.length;
|
|
}
|
|
if ((next = node.firstChild) === null) {
|
|
break;
|
|
}
|
|
parentNode = node;
|
|
node = next;
|
|
}
|
|
while (true) {
|
|
if (node === outerNode) {
|
|
break outer;
|
|
}
|
|
if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
|
|
start = length;
|
|
}
|
|
if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
|
|
end = length;
|
|
}
|
|
if ((next = node.nextSibling) !== null) {
|
|
break;
|
|
}
|
|
node = parentNode;
|
|
parentNode = node.parentNode;
|
|
}
|
|
node = next;
|
|
}
|
|
if (start === -1 || end === -1) {
|
|
return null;
|
|
}
|
|
return {
|
|
start,
|
|
end
|
|
};
|
|
}
|
|
function setOffsets(node, offsets) {
|
|
var doc = node.ownerDocument || document;
|
|
var win = doc && doc.defaultView || window;
|
|
if (!win.getSelection) {
|
|
return;
|
|
}
|
|
var selection = win.getSelection();
|
|
var length = node.textContent.length;
|
|
var start = Math.min(offsets.start, length);
|
|
var end = offsets.end === void 0 ? start : Math.min(offsets.end, length);
|
|
if (!selection.extend && start > end) {
|
|
var temp = end;
|
|
end = start;
|
|
start = temp;
|
|
}
|
|
var startMarker = getNodeForCharacterOffset(node, start);
|
|
var endMarker = getNodeForCharacterOffset(node, end);
|
|
if (startMarker && endMarker) {
|
|
if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
|
|
return;
|
|
}
|
|
var range = doc.createRange();
|
|
range.setStart(startMarker.node, startMarker.offset);
|
|
selection.removeAllRanges();
|
|
if (start > end) {
|
|
selection.addRange(range);
|
|
selection.extend(endMarker.node, endMarker.offset);
|
|
} else {
|
|
range.setEnd(endMarker.node, endMarker.offset);
|
|
selection.addRange(range);
|
|
}
|
|
}
|
|
}
|
|
function isTextNode(node) {
|
|
return node && node.nodeType === TEXT_NODE;
|
|
}
|
|
function containsNode(outerNode, innerNode) {
|
|
if (!outerNode || !innerNode) {
|
|
return false;
|
|
} else if (outerNode === innerNode) {
|
|
return true;
|
|
} else if (isTextNode(outerNode)) {
|
|
return false;
|
|
} else if (isTextNode(innerNode)) {
|
|
return containsNode(outerNode, innerNode.parentNode);
|
|
} else if ("contains" in outerNode) {
|
|
return outerNode.contains(innerNode);
|
|
} else if (outerNode.compareDocumentPosition) {
|
|
return !!(outerNode.compareDocumentPosition(innerNode) & 16);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
function isInDocument(node) {
|
|
return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
|
|
}
|
|
function isSameOriginFrame(iframe) {
|
|
try {
|
|
return typeof iframe.contentWindow.location.href === "string";
|
|
} catch (err) {
|
|
return false;
|
|
}
|
|
}
|
|
function getActiveElementDeep() {
|
|
var win = window;
|
|
var element = getActiveElement();
|
|
while (element instanceof win.HTMLIFrameElement) {
|
|
if (isSameOriginFrame(element)) {
|
|
win = element.contentWindow;
|
|
} else {
|
|
return element;
|
|
}
|
|
element = getActiveElement(win.document);
|
|
}
|
|
return element;
|
|
}
|
|
function hasSelectionCapabilities(elem) {
|
|
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
|
|
return nodeName && (nodeName === "input" && (elem.type === "text" || elem.type === "search" || elem.type === "tel" || elem.type === "url" || elem.type === "password") || nodeName === "textarea" || elem.contentEditable === "true");
|
|
}
|
|
function getSelectionInformation() {
|
|
var focusedElem = getActiveElementDeep();
|
|
return {
|
|
focusedElem,
|
|
selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
|
|
};
|
|
}
|
|
function restoreSelection(priorSelectionInformation) {
|
|
var curFocusedElem = getActiveElementDeep();
|
|
var priorFocusedElem = priorSelectionInformation.focusedElem;
|
|
var priorSelectionRange = priorSelectionInformation.selectionRange;
|
|
if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
|
|
if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
|
|
setSelection(priorFocusedElem, priorSelectionRange);
|
|
}
|
|
var ancestors = [];
|
|
var ancestor = priorFocusedElem;
|
|
while (ancestor = ancestor.parentNode) {
|
|
if (ancestor.nodeType === ELEMENT_NODE) {
|
|
ancestors.push({
|
|
element: ancestor,
|
|
left: ancestor.scrollLeft,
|
|
top: ancestor.scrollTop
|
|
});
|
|
}
|
|
}
|
|
if (typeof priorFocusedElem.focus === "function") {
|
|
priorFocusedElem.focus();
|
|
}
|
|
for (var i = 0; i < ancestors.length; i++) {
|
|
var info = ancestors[i];
|
|
info.element.scrollLeft = info.left;
|
|
info.element.scrollTop = info.top;
|
|
}
|
|
}
|
|
}
|
|
function getSelection(input) {
|
|
var selection;
|
|
if ("selectionStart" in input) {
|
|
selection = {
|
|
start: input.selectionStart,
|
|
end: input.selectionEnd
|
|
};
|
|
} else {
|
|
selection = getOffsets(input);
|
|
}
|
|
return selection || {
|
|
start: 0,
|
|
end: 0
|
|
};
|
|
}
|
|
function setSelection(input, offsets) {
|
|
var start = offsets.start;
|
|
var end = offsets.end;
|
|
if (end === void 0) {
|
|
end = start;
|
|
}
|
|
if ("selectionStart" in input) {
|
|
input.selectionStart = start;
|
|
input.selectionEnd = Math.min(end, input.value.length);
|
|
} else {
|
|
setOffsets(input, offsets);
|
|
}
|
|
}
|
|
var skipSelectionChangeEvent = canUseDOM && "documentMode" in document && document.documentMode <= 11;
|
|
function registerEvents$3() {
|
|
registerTwoPhaseEvent("onSelect", ["focusout", "contextmenu", "dragend", "focusin", "keydown", "keyup", "mousedown", "mouseup", "selectionchange"]);
|
|
}
|
|
var activeElement$1 = null;
|
|
var activeElementInst$1 = null;
|
|
var lastSelection = null;
|
|
var mouseDown = false;
|
|
function getSelection$1(node) {
|
|
if ("selectionStart" in node && hasSelectionCapabilities(node)) {
|
|
return {
|
|
start: node.selectionStart,
|
|
end: node.selectionEnd
|
|
};
|
|
} else {
|
|
var win = node.ownerDocument && node.ownerDocument.defaultView || window;
|
|
var selection = win.getSelection();
|
|
return {
|
|
anchorNode: selection.anchorNode,
|
|
anchorOffset: selection.anchorOffset,
|
|
focusNode: selection.focusNode,
|
|
focusOffset: selection.focusOffset
|
|
};
|
|
}
|
|
}
|
|
function getEventTargetDocument(eventTarget) {
|
|
return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
|
|
}
|
|
function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
|
|
var doc = getEventTargetDocument(nativeEventTarget);
|
|
if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
|
|
return;
|
|
}
|
|
var currentSelection = getSelection$1(activeElement$1);
|
|
if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
|
|
lastSelection = currentSelection;
|
|
var listeners = accumulateTwoPhaseListeners(activeElementInst$1, "onSelect");
|
|
if (listeners.length > 0) {
|
|
var event = new SyntheticEvent("onSelect", "select", null, nativeEvent, nativeEventTarget);
|
|
dispatchQueue.push({
|
|
event,
|
|
listeners
|
|
});
|
|
event.target = activeElement$1;
|
|
}
|
|
}
|
|
}
|
|
function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
|
|
var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
|
|
switch (domEventName) {
|
|
case "focusin":
|
|
if (isTextInputElement(targetNode) || targetNode.contentEditable === "true") {
|
|
activeElement$1 = targetNode;
|
|
activeElementInst$1 = targetInst;
|
|
lastSelection = null;
|
|
}
|
|
break;
|
|
case "focusout":
|
|
activeElement$1 = null;
|
|
activeElementInst$1 = null;
|
|
lastSelection = null;
|
|
break;
|
|
case "mousedown":
|
|
mouseDown = true;
|
|
break;
|
|
case "contextmenu":
|
|
case "mouseup":
|
|
case "dragend":
|
|
mouseDown = false;
|
|
constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
|
|
break;
|
|
case "selectionchange":
|
|
if (skipSelectionChangeEvent) {
|
|
break;
|
|
}
|
|
case "keydown":
|
|
case "keyup":
|
|
constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
|
|
}
|
|
}
|
|
function makePrefixMap(styleProp, eventName) {
|
|
var prefixes2 = {};
|
|
prefixes2[styleProp.toLowerCase()] = eventName.toLowerCase();
|
|
prefixes2["Webkit" + styleProp] = "webkit" + eventName;
|
|
prefixes2["Moz" + styleProp] = "moz" + eventName;
|
|
return prefixes2;
|
|
}
|
|
var vendorPrefixes = {
|
|
animationend: makePrefixMap("Animation", "AnimationEnd"),
|
|
animationiteration: makePrefixMap("Animation", "AnimationIteration"),
|
|
animationstart: makePrefixMap("Animation", "AnimationStart"),
|
|
transitionend: makePrefixMap("Transition", "TransitionEnd")
|
|
};
|
|
var prefixedEventNames = {};
|
|
var style = {};
|
|
if (canUseDOM) {
|
|
style = document.createElement("div").style;
|
|
if (!("AnimationEvent" in window)) {
|
|
delete vendorPrefixes.animationend.animation;
|
|
delete vendorPrefixes.animationiteration.animation;
|
|
delete vendorPrefixes.animationstart.animation;
|
|
}
|
|
if (!("TransitionEvent" in window)) {
|
|
delete vendorPrefixes.transitionend.transition;
|
|
}
|
|
}
|
|
function getVendorPrefixedEventName(eventName) {
|
|
if (prefixedEventNames[eventName]) {
|
|
return prefixedEventNames[eventName];
|
|
} else if (!vendorPrefixes[eventName]) {
|
|
return eventName;
|
|
}
|
|
var prefixMap = vendorPrefixes[eventName];
|
|
for (var styleProp in prefixMap) {
|
|
if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
|
|
return prefixedEventNames[eventName] = prefixMap[styleProp];
|
|
}
|
|
}
|
|
return eventName;
|
|
}
|
|
var ANIMATION_END = getVendorPrefixedEventName("animationend");
|
|
var ANIMATION_ITERATION = getVendorPrefixedEventName("animationiteration");
|
|
var ANIMATION_START = getVendorPrefixedEventName("animationstart");
|
|
var TRANSITION_END = getVendorPrefixedEventName("transitionend");
|
|
var topLevelEventsToReactNames = /* @__PURE__ */ new Map();
|
|
var simpleEventPluginEvents = ["abort", "auxClick", "cancel", "canPlay", "canPlayThrough", "click", "close", "contextMenu", "copy", "cut", "drag", "dragEnd", "dragEnter", "dragExit", "dragLeave", "dragOver", "dragStart", "drop", "durationChange", "emptied", "encrypted", "ended", "error", "gotPointerCapture", "input", "invalid", "keyDown", "keyPress", "keyUp", "load", "loadedData", "loadedMetadata", "loadStart", "lostPointerCapture", "mouseDown", "mouseMove", "mouseOut", "mouseOver", "mouseUp", "paste", "pause", "play", "playing", "pointerCancel", "pointerDown", "pointerMove", "pointerOut", "pointerOver", "pointerUp", "progress", "rateChange", "reset", "resize", "seeked", "seeking", "stalled", "submit", "suspend", "timeUpdate", "touchCancel", "touchEnd", "touchStart", "volumeChange", "scroll", "toggle", "touchMove", "waiting", "wheel"];
|
|
function registerSimpleEvent(domEventName, reactName) {
|
|
topLevelEventsToReactNames.set(domEventName, reactName);
|
|
registerTwoPhaseEvent(reactName, [domEventName]);
|
|
}
|
|
function registerSimpleEvents() {
|
|
for (var i = 0; i < simpleEventPluginEvents.length; i++) {
|
|
var eventName = simpleEventPluginEvents[i];
|
|
var domEventName = eventName.toLowerCase();
|
|
var capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1);
|
|
registerSimpleEvent(domEventName, "on" + capitalizedEvent);
|
|
}
|
|
registerSimpleEvent(ANIMATION_END, "onAnimationEnd");
|
|
registerSimpleEvent(ANIMATION_ITERATION, "onAnimationIteration");
|
|
registerSimpleEvent(ANIMATION_START, "onAnimationStart");
|
|
registerSimpleEvent("dblclick", "onDoubleClick");
|
|
registerSimpleEvent("focusin", "onFocus");
|
|
registerSimpleEvent("focusout", "onBlur");
|
|
registerSimpleEvent(TRANSITION_END, "onTransitionEnd");
|
|
}
|
|
function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
|
|
var reactName = topLevelEventsToReactNames.get(domEventName);
|
|
if (reactName === void 0) {
|
|
return;
|
|
}
|
|
var SyntheticEventCtor = SyntheticEvent;
|
|
var reactEventType = domEventName;
|
|
switch (domEventName) {
|
|
case "keypress":
|
|
if (getEventCharCode(nativeEvent) === 0) {
|
|
return;
|
|
}
|
|
case "keydown":
|
|
case "keyup":
|
|
SyntheticEventCtor = SyntheticKeyboardEvent;
|
|
break;
|
|
case "focusin":
|
|
reactEventType = "focus";
|
|
SyntheticEventCtor = SyntheticFocusEvent;
|
|
break;
|
|
case "focusout":
|
|
reactEventType = "blur";
|
|
SyntheticEventCtor = SyntheticFocusEvent;
|
|
break;
|
|
case "beforeblur":
|
|
case "afterblur":
|
|
SyntheticEventCtor = SyntheticFocusEvent;
|
|
break;
|
|
case "click":
|
|
if (nativeEvent.button === 2) {
|
|
return;
|
|
}
|
|
case "auxclick":
|
|
case "dblclick":
|
|
case "mousedown":
|
|
case "mousemove":
|
|
case "mouseup":
|
|
case "mouseout":
|
|
case "mouseover":
|
|
case "contextmenu":
|
|
SyntheticEventCtor = SyntheticMouseEvent;
|
|
break;
|
|
case "drag":
|
|
case "dragend":
|
|
case "dragenter":
|
|
case "dragexit":
|
|
case "dragleave":
|
|
case "dragover":
|
|
case "dragstart":
|
|
case "drop":
|
|
SyntheticEventCtor = SyntheticDragEvent;
|
|
break;
|
|
case "touchcancel":
|
|
case "touchend":
|
|
case "touchmove":
|
|
case "touchstart":
|
|
SyntheticEventCtor = SyntheticTouchEvent;
|
|
break;
|
|
case ANIMATION_END:
|
|
case ANIMATION_ITERATION:
|
|
case ANIMATION_START:
|
|
SyntheticEventCtor = SyntheticAnimationEvent;
|
|
break;
|
|
case TRANSITION_END:
|
|
SyntheticEventCtor = SyntheticTransitionEvent;
|
|
break;
|
|
case "scroll":
|
|
SyntheticEventCtor = SyntheticUIEvent;
|
|
break;
|
|
case "wheel":
|
|
SyntheticEventCtor = SyntheticWheelEvent;
|
|
break;
|
|
case "copy":
|
|
case "cut":
|
|
case "paste":
|
|
SyntheticEventCtor = SyntheticClipboardEvent;
|
|
break;
|
|
case "gotpointercapture":
|
|
case "lostpointercapture":
|
|
case "pointercancel":
|
|
case "pointerdown":
|
|
case "pointermove":
|
|
case "pointerout":
|
|
case "pointerover":
|
|
case "pointerup":
|
|
SyntheticEventCtor = SyntheticPointerEvent;
|
|
break;
|
|
}
|
|
var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
|
|
{
|
|
var accumulateTargetOnly = !inCapturePhase && domEventName === "scroll";
|
|
var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
|
|
if (_listeners.length > 0) {
|
|
var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
|
|
dispatchQueue.push({
|
|
event: _event,
|
|
listeners: _listeners
|
|
});
|
|
}
|
|
}
|
|
}
|
|
registerSimpleEvents();
|
|
registerEvents$2();
|
|
registerEvents$1();
|
|
registerEvents$3();
|
|
registerEvents();
|
|
function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
|
|
extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
|
|
var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0;
|
|
if (shouldProcessPolyfillPlugins) {
|
|
extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
|
|
extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
|
|
extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
|
|
extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
|
|
}
|
|
}
|
|
var mediaEventTypes = ["abort", "canplay", "canplaythrough", "durationchange", "emptied", "encrypted", "ended", "error", "loadeddata", "loadedmetadata", "loadstart", "pause", "play", "playing", "progress", "ratechange", "resize", "seeked", "seeking", "stalled", "suspend", "timeupdate", "volumechange", "waiting"];
|
|
var nonDelegatedEvents = new Set(["cancel", "close", "invalid", "load", "scroll", "toggle"].concat(mediaEventTypes));
|
|
function executeDispatch(event, listener, currentTarget) {
|
|
var type = event.type || "unknown-event";
|
|
event.currentTarget = currentTarget;
|
|
invokeGuardedCallbackAndCatchFirstError(type, listener, void 0, event);
|
|
event.currentTarget = null;
|
|
}
|
|
function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
|
|
var previousInstance;
|
|
if (inCapturePhase) {
|
|
for (var i = dispatchListeners.length - 1; i >= 0; i--) {
|
|
var _dispatchListeners$i = dispatchListeners[i], instance = _dispatchListeners$i.instance, currentTarget = _dispatchListeners$i.currentTarget, listener = _dispatchListeners$i.listener;
|
|
if (instance !== previousInstance && event.isPropagationStopped()) {
|
|
return;
|
|
}
|
|
executeDispatch(event, listener, currentTarget);
|
|
previousInstance = instance;
|
|
}
|
|
} else {
|
|
for (var _i = 0; _i < dispatchListeners.length; _i++) {
|
|
var _dispatchListeners$_i = dispatchListeners[_i], _instance = _dispatchListeners$_i.instance, _currentTarget = _dispatchListeners$_i.currentTarget, _listener = _dispatchListeners$_i.listener;
|
|
if (_instance !== previousInstance && event.isPropagationStopped()) {
|
|
return;
|
|
}
|
|
executeDispatch(event, _listener, _currentTarget);
|
|
previousInstance = _instance;
|
|
}
|
|
}
|
|
}
|
|
function processDispatchQueue(dispatchQueue, eventSystemFlags) {
|
|
var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
|
|
for (var i = 0; i < dispatchQueue.length; i++) {
|
|
var _dispatchQueue$i = dispatchQueue[i], event = _dispatchQueue$i.event, listeners = _dispatchQueue$i.listeners;
|
|
processDispatchQueueItemsInOrder(event, listeners, inCapturePhase);
|
|
}
|
|
rethrowCaughtError();
|
|
}
|
|
function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
|
|
var nativeEventTarget = getEventTarget(nativeEvent);
|
|
var dispatchQueue = [];
|
|
extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
|
|
processDispatchQueue(dispatchQueue, eventSystemFlags);
|
|
}
|
|
function listenToNonDelegatedEvent(domEventName, targetElement) {
|
|
{
|
|
if (!nonDelegatedEvents.has(domEventName)) {
|
|
error('Did not expect a listenToNonDelegatedEvent() call for "%s". This is a bug in React. Please file an issue.', domEventName);
|
|
}
|
|
}
|
|
var isCapturePhaseListener = false;
|
|
var listenerSet = getEventListenerSet(targetElement);
|
|
var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
|
|
if (!listenerSet.has(listenerSetKey)) {
|
|
addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
|
|
listenerSet.add(listenerSetKey);
|
|
}
|
|
}
|
|
function listenToNativeEvent(domEventName, isCapturePhaseListener, target) {
|
|
{
|
|
if (nonDelegatedEvents.has(domEventName) && !isCapturePhaseListener) {
|
|
error('Did not expect a listenToNativeEvent() call for "%s" in the bubble phase. This is a bug in React. Please file an issue.', domEventName);
|
|
}
|
|
}
|
|
var eventSystemFlags = 0;
|
|
if (isCapturePhaseListener) {
|
|
eventSystemFlags |= IS_CAPTURE_PHASE;
|
|
}
|
|
addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
|
|
}
|
|
var listeningMarker = "_reactListening" + Math.random().toString(36).slice(2);
|
|
function listenToAllSupportedEvents(rootContainerElement) {
|
|
if (!rootContainerElement[listeningMarker]) {
|
|
rootContainerElement[listeningMarker] = true;
|
|
allNativeEvents.forEach(function(domEventName) {
|
|
if (domEventName !== "selectionchange") {
|
|
if (!nonDelegatedEvents.has(domEventName)) {
|
|
listenToNativeEvent(domEventName, false, rootContainerElement);
|
|
}
|
|
listenToNativeEvent(domEventName, true, rootContainerElement);
|
|
}
|
|
});
|
|
var ownerDocument = rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
|
|
if (ownerDocument !== null) {
|
|
if (!ownerDocument[listeningMarker]) {
|
|
ownerDocument[listeningMarker] = true;
|
|
listenToNativeEvent("selectionchange", false, ownerDocument);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
|
|
var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags);
|
|
var isPassiveListener = void 0;
|
|
if (passiveBrowserEventsSupported) {
|
|
if (domEventName === "touchstart" || domEventName === "touchmove" || domEventName === "wheel") {
|
|
isPassiveListener = true;
|
|
}
|
|
}
|
|
targetContainer = targetContainer;
|
|
var unsubscribeListener;
|
|
if (isCapturePhaseListener) {
|
|
if (isPassiveListener !== void 0) {
|
|
unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
|
|
} else {
|
|
unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener);
|
|
}
|
|
} else {
|
|
if (isPassiveListener !== void 0) {
|
|
unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
|
|
} else {
|
|
unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener);
|
|
}
|
|
}
|
|
}
|
|
function isMatchingRootContainer(grandContainer, targetContainer) {
|
|
return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
|
|
}
|
|
function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
|
|
var ancestorInst = targetInst;
|
|
if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
|
|
var targetContainerNode = targetContainer;
|
|
if (targetInst !== null) {
|
|
var node = targetInst;
|
|
mainLoop:
|
|
while (true) {
|
|
if (node === null) {
|
|
return;
|
|
}
|
|
var nodeTag = node.tag;
|
|
if (nodeTag === HostRoot || nodeTag === HostPortal) {
|
|
var container = node.stateNode.containerInfo;
|
|
if (isMatchingRootContainer(container, targetContainerNode)) {
|
|
break;
|
|
}
|
|
if (nodeTag === HostPortal) {
|
|
var grandNode = node.return;
|
|
while (grandNode !== null) {
|
|
var grandTag = grandNode.tag;
|
|
if (grandTag === HostRoot || grandTag === HostPortal) {
|
|
var grandContainer = grandNode.stateNode.containerInfo;
|
|
if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
|
|
return;
|
|
}
|
|
}
|
|
grandNode = grandNode.return;
|
|
}
|
|
}
|
|
while (container !== null) {
|
|
var parentNode = getClosestInstanceFromNode(container);
|
|
if (parentNode === null) {
|
|
return;
|
|
}
|
|
var parentTag = parentNode.tag;
|
|
if (parentTag === HostComponent || parentTag === HostText) {
|
|
node = ancestorInst = parentNode;
|
|
continue mainLoop;
|
|
}
|
|
container = container.parentNode;
|
|
}
|
|
}
|
|
node = node.return;
|
|
}
|
|
}
|
|
}
|
|
batchedUpdates(function() {
|
|
return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
|
|
});
|
|
}
|
|
function createDispatchListener(instance, listener, currentTarget) {
|
|
return {
|
|
instance,
|
|
listener,
|
|
currentTarget
|
|
};
|
|
}
|
|
function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly, nativeEvent) {
|
|
var captureName = reactName !== null ? reactName + "Capture" : null;
|
|
var reactEventName = inCapturePhase ? captureName : reactName;
|
|
var listeners = [];
|
|
var instance = targetFiber;
|
|
var lastHostComponent = null;
|
|
while (instance !== null) {
|
|
var _instance2 = instance, stateNode = _instance2.stateNode, tag = _instance2.tag;
|
|
if (tag === HostComponent && stateNode !== null) {
|
|
lastHostComponent = stateNode;
|
|
if (reactEventName !== null) {
|
|
var listener = getListener(instance, reactEventName);
|
|
if (listener != null) {
|
|
listeners.push(createDispatchListener(instance, listener, lastHostComponent));
|
|
}
|
|
}
|
|
}
|
|
if (accumulateTargetOnly) {
|
|
break;
|
|
}
|
|
instance = instance.return;
|
|
}
|
|
return listeners;
|
|
}
|
|
function accumulateTwoPhaseListeners(targetFiber, reactName) {
|
|
var captureName = reactName + "Capture";
|
|
var listeners = [];
|
|
var instance = targetFiber;
|
|
while (instance !== null) {
|
|
var _instance3 = instance, stateNode = _instance3.stateNode, tag = _instance3.tag;
|
|
if (tag === HostComponent && stateNode !== null) {
|
|
var currentTarget = stateNode;
|
|
var captureListener = getListener(instance, captureName);
|
|
if (captureListener != null) {
|
|
listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
|
|
}
|
|
var bubbleListener = getListener(instance, reactName);
|
|
if (bubbleListener != null) {
|
|
listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
|
|
}
|
|
}
|
|
instance = instance.return;
|
|
}
|
|
return listeners;
|
|
}
|
|
function getParent(inst) {
|
|
if (inst === null) {
|
|
return null;
|
|
}
|
|
do {
|
|
inst = inst.return;
|
|
} while (inst && inst.tag !== HostComponent);
|
|
if (inst) {
|
|
return inst;
|
|
}
|
|
return null;
|
|
}
|
|
function getLowestCommonAncestor(instA, instB) {
|
|
var nodeA = instA;
|
|
var nodeB = instB;
|
|
var depthA = 0;
|
|
for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
|
|
depthA++;
|
|
}
|
|
var depthB = 0;
|
|
for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
|
|
depthB++;
|
|
}
|
|
while (depthA - depthB > 0) {
|
|
nodeA = getParent(nodeA);
|
|
depthA--;
|
|
}
|
|
while (depthB - depthA > 0) {
|
|
nodeB = getParent(nodeB);
|
|
depthB--;
|
|
}
|
|
var depth = depthA;
|
|
while (depth--) {
|
|
if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
|
|
return nodeA;
|
|
}
|
|
nodeA = getParent(nodeA);
|
|
nodeB = getParent(nodeB);
|
|
}
|
|
return null;
|
|
}
|
|
function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
|
|
var registrationName = event._reactName;
|
|
var listeners = [];
|
|
var instance = target;
|
|
while (instance !== null) {
|
|
if (instance === common) {
|
|
break;
|
|
}
|
|
var _instance4 = instance, alternate = _instance4.alternate, stateNode = _instance4.stateNode, tag = _instance4.tag;
|
|
if (alternate !== null && alternate === common) {
|
|
break;
|
|
}
|
|
if (tag === HostComponent && stateNode !== null) {
|
|
var currentTarget = stateNode;
|
|
if (inCapturePhase) {
|
|
var captureListener = getListener(instance, registrationName);
|
|
if (captureListener != null) {
|
|
listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
|
|
}
|
|
} else if (!inCapturePhase) {
|
|
var bubbleListener = getListener(instance, registrationName);
|
|
if (bubbleListener != null) {
|
|
listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
|
|
}
|
|
}
|
|
}
|
|
instance = instance.return;
|
|
}
|
|
if (listeners.length !== 0) {
|
|
dispatchQueue.push({
|
|
event,
|
|
listeners
|
|
});
|
|
}
|
|
}
|
|
function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
|
|
var common = from && to ? getLowestCommonAncestor(from, to) : null;
|
|
if (from !== null) {
|
|
accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
|
|
}
|
|
if (to !== null && enterEvent !== null) {
|
|
accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
|
|
}
|
|
}
|
|
function getListenerSetKey(domEventName, capture) {
|
|
return domEventName + "__" + (capture ? "capture" : "bubble");
|
|
}
|
|
var didWarnInvalidHydration = false;
|
|
var DANGEROUSLY_SET_INNER_HTML = "dangerouslySetInnerHTML";
|
|
var SUPPRESS_CONTENT_EDITABLE_WARNING = "suppressContentEditableWarning";
|
|
var SUPPRESS_HYDRATION_WARNING = "suppressHydrationWarning";
|
|
var AUTOFOCUS = "autoFocus";
|
|
var CHILDREN = "children";
|
|
var STYLE = "style";
|
|
var HTML$1 = "__html";
|
|
var warnedUnknownTags;
|
|
var validatePropertiesInDevelopment;
|
|
var warnForPropDifference;
|
|
var warnForExtraAttributes;
|
|
var warnForInvalidEventListener;
|
|
var canDiffStyleForHydrationWarning;
|
|
var normalizeHTML;
|
|
{
|
|
warnedUnknownTags = {
|
|
dialog: true,
|
|
webview: true
|
|
};
|
|
validatePropertiesInDevelopment = function(type, props) {
|
|
validateProperties(type, props);
|
|
validateProperties$1(type, props);
|
|
validateProperties$2(type, props, {
|
|
registrationNameDependencies,
|
|
possibleRegistrationNames
|
|
});
|
|
};
|
|
canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
|
|
warnForPropDifference = function(propName, serverValue, clientValue) {
|
|
if (didWarnInvalidHydration) {
|
|
return;
|
|
}
|
|
var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
|
|
var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
|
|
if (normalizedServerValue === normalizedClientValue) {
|
|
return;
|
|
}
|
|
didWarnInvalidHydration = true;
|
|
error("Prop `%s` did not match. Server: %s Client: %s", propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
|
|
};
|
|
warnForExtraAttributes = function(attributeNames) {
|
|
if (didWarnInvalidHydration) {
|
|
return;
|
|
}
|
|
didWarnInvalidHydration = true;
|
|
var names = [];
|
|
attributeNames.forEach(function(name) {
|
|
names.push(name);
|
|
});
|
|
error("Extra attributes from the server: %s", names);
|
|
};
|
|
warnForInvalidEventListener = function(registrationName, listener) {
|
|
if (listener === false) {
|
|
error("Expected `%s` listener to be a function, instead got `false`.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.", registrationName, registrationName, registrationName);
|
|
} else {
|
|
error("Expected `%s` listener to be a function, instead got a value of `%s` type.", registrationName, typeof listener);
|
|
}
|
|
};
|
|
normalizeHTML = function(parent, html) {
|
|
var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
|
|
testElement.innerHTML = html;
|
|
return testElement.innerHTML;
|
|
};
|
|
}
|
|
var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
|
|
var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
|
|
function normalizeMarkupForTextOrAttribute(markup) {
|
|
{
|
|
checkHtmlStringCoercion(markup);
|
|
}
|
|
var markupString = typeof markup === "string" ? markup : "" + markup;
|
|
return markupString.replace(NORMALIZE_NEWLINES_REGEX, "\n").replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, "");
|
|
}
|
|
function checkForUnmatchedText(serverText, clientText, isConcurrentMode, shouldWarnDev) {
|
|
var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
|
|
var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
|
|
if (normalizedServerText === normalizedClientText) {
|
|
return;
|
|
}
|
|
if (shouldWarnDev) {
|
|
{
|
|
if (!didWarnInvalidHydration) {
|
|
didWarnInvalidHydration = true;
|
|
error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
|
|
}
|
|
}
|
|
}
|
|
if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) {
|
|
throw new Error("Text content does not match server-rendered HTML.");
|
|
}
|
|
}
|
|
function getOwnerDocumentFromRootContainer(rootContainerElement) {
|
|
return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
|
|
}
|
|
function noop() {
|
|
}
|
|
function trapClickOnNonInteractiveElement(node) {
|
|
node.onclick = noop;
|
|
}
|
|
function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
|
|
for (var propKey in nextProps) {
|
|
if (!nextProps.hasOwnProperty(propKey)) {
|
|
continue;
|
|
}
|
|
var nextProp = nextProps[propKey];
|
|
if (propKey === STYLE) {
|
|
{
|
|
if (nextProp) {
|
|
Object.freeze(nextProp);
|
|
}
|
|
}
|
|
setValueForStyles(domElement, nextProp);
|
|
} else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
|
|
var nextHtml = nextProp ? nextProp[HTML$1] : void 0;
|
|
if (nextHtml != null) {
|
|
setInnerHTML(domElement, nextHtml);
|
|
}
|
|
} else if (propKey === CHILDREN) {
|
|
if (typeof nextProp === "string") {
|
|
var canSetTextContent = tag !== "textarea" || nextProp !== "";
|
|
if (canSetTextContent) {
|
|
setTextContent(domElement, nextProp);
|
|
}
|
|
} else if (typeof nextProp === "number") {
|
|
setTextContent(domElement, "" + nextProp);
|
|
}
|
|
} else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING)
|
|
;
|
|
else if (propKey === AUTOFOCUS)
|
|
;
|
|
else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
|
if (nextProp != null) {
|
|
if (typeof nextProp !== "function") {
|
|
warnForInvalidEventListener(propKey, nextProp);
|
|
}
|
|
if (propKey === "onScroll") {
|
|
listenToNonDelegatedEvent("scroll", domElement);
|
|
}
|
|
}
|
|
} else if (nextProp != null) {
|
|
setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
|
|
}
|
|
}
|
|
}
|
|
function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
|
|
for (var i = 0; i < updatePayload.length; i += 2) {
|
|
var propKey = updatePayload[i];
|
|
var propValue = updatePayload[i + 1];
|
|
if (propKey === STYLE) {
|
|
setValueForStyles(domElement, propValue);
|
|
} else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
|
|
setInnerHTML(domElement, propValue);
|
|
} else if (propKey === CHILDREN) {
|
|
setTextContent(domElement, propValue);
|
|
} else {
|
|
setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
|
|
}
|
|
}
|
|
}
|
|
function createElement3(type, props, rootContainerElement, parentNamespace) {
|
|
var isCustomComponentTag;
|
|
var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
|
|
var domElement;
|
|
var namespaceURI = parentNamespace;
|
|
if (namespaceURI === HTML_NAMESPACE) {
|
|
namespaceURI = getIntrinsicNamespace(type);
|
|
}
|
|
if (namespaceURI === HTML_NAMESPACE) {
|
|
{
|
|
isCustomComponentTag = isCustomComponent(type, props);
|
|
if (!isCustomComponentTag && type !== type.toLowerCase()) {
|
|
error("<%s /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.", type);
|
|
}
|
|
}
|
|
if (type === "script") {
|
|
var div = ownerDocument.createElement("div");
|
|
div.innerHTML = "<script><\/script>";
|
|
var firstChild = div.firstChild;
|
|
domElement = div.removeChild(firstChild);
|
|
} else if (typeof props.is === "string") {
|
|
domElement = ownerDocument.createElement(type, {
|
|
is: props.is
|
|
});
|
|
} else {
|
|
domElement = ownerDocument.createElement(type);
|
|
if (type === "select") {
|
|
var node = domElement;
|
|
if (props.multiple) {
|
|
node.multiple = true;
|
|
} else if (props.size) {
|
|
node.size = props.size;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
domElement = ownerDocument.createElementNS(namespaceURI, type);
|
|
}
|
|
{
|
|
if (namespaceURI === HTML_NAMESPACE) {
|
|
if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === "[object HTMLUnknownElement]" && !hasOwnProperty.call(warnedUnknownTags, type)) {
|
|
warnedUnknownTags[type] = true;
|
|
error("The tag <%s> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.", type);
|
|
}
|
|
}
|
|
}
|
|
return domElement;
|
|
}
|
|
function createTextNode(text, rootContainerElement) {
|
|
return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
|
|
}
|
|
function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
|
|
var isCustomComponentTag = isCustomComponent(tag, rawProps);
|
|
{
|
|
validatePropertiesInDevelopment(tag, rawProps);
|
|
}
|
|
var props;
|
|
switch (tag) {
|
|
case "dialog":
|
|
listenToNonDelegatedEvent("cancel", domElement);
|
|
listenToNonDelegatedEvent("close", domElement);
|
|
props = rawProps;
|
|
break;
|
|
case "iframe":
|
|
case "object":
|
|
case "embed":
|
|
listenToNonDelegatedEvent("load", domElement);
|
|
props = rawProps;
|
|
break;
|
|
case "video":
|
|
case "audio":
|
|
for (var i = 0; i < mediaEventTypes.length; i++) {
|
|
listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
|
|
}
|
|
props = rawProps;
|
|
break;
|
|
case "source":
|
|
listenToNonDelegatedEvent("error", domElement);
|
|
props = rawProps;
|
|
break;
|
|
case "img":
|
|
case "image":
|
|
case "link":
|
|
listenToNonDelegatedEvent("error", domElement);
|
|
listenToNonDelegatedEvent("load", domElement);
|
|
props = rawProps;
|
|
break;
|
|
case "details":
|
|
listenToNonDelegatedEvent("toggle", domElement);
|
|
props = rawProps;
|
|
break;
|
|
case "input":
|
|
initWrapperState(domElement, rawProps);
|
|
props = getHostProps(domElement, rawProps);
|
|
listenToNonDelegatedEvent("invalid", domElement);
|
|
break;
|
|
case "option":
|
|
validateProps(domElement, rawProps);
|
|
props = rawProps;
|
|
break;
|
|
case "select":
|
|
initWrapperState$1(domElement, rawProps);
|
|
props = getHostProps$1(domElement, rawProps);
|
|
listenToNonDelegatedEvent("invalid", domElement);
|
|
break;
|
|
case "textarea":
|
|
initWrapperState$2(domElement, rawProps);
|
|
props = getHostProps$2(domElement, rawProps);
|
|
listenToNonDelegatedEvent("invalid", domElement);
|
|
break;
|
|
default:
|
|
props = rawProps;
|
|
}
|
|
assertValidProps(tag, props);
|
|
setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
|
|
switch (tag) {
|
|
case "input":
|
|
track(domElement);
|
|
postMountWrapper(domElement, rawProps, false);
|
|
break;
|
|
case "textarea":
|
|
track(domElement);
|
|
postMountWrapper$3(domElement);
|
|
break;
|
|
case "option":
|
|
postMountWrapper$1(domElement, rawProps);
|
|
break;
|
|
case "select":
|
|
postMountWrapper$2(domElement, rawProps);
|
|
break;
|
|
default:
|
|
if (typeof props.onClick === "function") {
|
|
trapClickOnNonInteractiveElement(domElement);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
|
|
{
|
|
validatePropertiesInDevelopment(tag, nextRawProps);
|
|
}
|
|
var updatePayload = null;
|
|
var lastProps;
|
|
var nextProps;
|
|
switch (tag) {
|
|
case "input":
|
|
lastProps = getHostProps(domElement, lastRawProps);
|
|
nextProps = getHostProps(domElement, nextRawProps);
|
|
updatePayload = [];
|
|
break;
|
|
case "select":
|
|
lastProps = getHostProps$1(domElement, lastRawProps);
|
|
nextProps = getHostProps$1(domElement, nextRawProps);
|
|
updatePayload = [];
|
|
break;
|
|
case "textarea":
|
|
lastProps = getHostProps$2(domElement, lastRawProps);
|
|
nextProps = getHostProps$2(domElement, nextRawProps);
|
|
updatePayload = [];
|
|
break;
|
|
default:
|
|
lastProps = lastRawProps;
|
|
nextProps = nextRawProps;
|
|
if (typeof lastProps.onClick !== "function" && typeof nextProps.onClick === "function") {
|
|
trapClickOnNonInteractiveElement(domElement);
|
|
}
|
|
break;
|
|
}
|
|
assertValidProps(tag, nextProps);
|
|
var propKey;
|
|
var styleName;
|
|
var styleUpdates = null;
|
|
for (propKey in lastProps) {
|
|
if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
|
|
continue;
|
|
}
|
|
if (propKey === STYLE) {
|
|
var lastStyle = lastProps[propKey];
|
|
for (styleName in lastStyle) {
|
|
if (lastStyle.hasOwnProperty(styleName)) {
|
|
if (!styleUpdates) {
|
|
styleUpdates = {};
|
|
}
|
|
styleUpdates[styleName] = "";
|
|
}
|
|
}
|
|
} else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN)
|
|
;
|
|
else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING)
|
|
;
|
|
else if (propKey === AUTOFOCUS)
|
|
;
|
|
else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
|
if (!updatePayload) {
|
|
updatePayload = [];
|
|
}
|
|
} else {
|
|
(updatePayload = updatePayload || []).push(propKey, null);
|
|
}
|
|
}
|
|
for (propKey in nextProps) {
|
|
var nextProp = nextProps[propKey];
|
|
var lastProp = lastProps != null ? lastProps[propKey] : void 0;
|
|
if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
|
|
continue;
|
|
}
|
|
if (propKey === STYLE) {
|
|
{
|
|
if (nextProp) {
|
|
Object.freeze(nextProp);
|
|
}
|
|
}
|
|
if (lastProp) {
|
|
for (styleName in lastProp) {
|
|
if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
|
|
if (!styleUpdates) {
|
|
styleUpdates = {};
|
|
}
|
|
styleUpdates[styleName] = "";
|
|
}
|
|
}
|
|
for (styleName in nextProp) {
|
|
if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
|
|
if (!styleUpdates) {
|
|
styleUpdates = {};
|
|
}
|
|
styleUpdates[styleName] = nextProp[styleName];
|
|
}
|
|
}
|
|
} else {
|
|
if (!styleUpdates) {
|
|
if (!updatePayload) {
|
|
updatePayload = [];
|
|
}
|
|
updatePayload.push(propKey, styleUpdates);
|
|
}
|
|
styleUpdates = nextProp;
|
|
}
|
|
} else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
|
|
var nextHtml = nextProp ? nextProp[HTML$1] : void 0;
|
|
var lastHtml = lastProp ? lastProp[HTML$1] : void 0;
|
|
if (nextHtml != null) {
|
|
if (lastHtml !== nextHtml) {
|
|
(updatePayload = updatePayload || []).push(propKey, nextHtml);
|
|
}
|
|
}
|
|
} else if (propKey === CHILDREN) {
|
|
if (typeof nextProp === "string" || typeof nextProp === "number") {
|
|
(updatePayload = updatePayload || []).push(propKey, "" + nextProp);
|
|
}
|
|
} else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING)
|
|
;
|
|
else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
|
if (nextProp != null) {
|
|
if (typeof nextProp !== "function") {
|
|
warnForInvalidEventListener(propKey, nextProp);
|
|
}
|
|
if (propKey === "onScroll") {
|
|
listenToNonDelegatedEvent("scroll", domElement);
|
|
}
|
|
}
|
|
if (!updatePayload && lastProp !== nextProp) {
|
|
updatePayload = [];
|
|
}
|
|
} else {
|
|
(updatePayload = updatePayload || []).push(propKey, nextProp);
|
|
}
|
|
}
|
|
if (styleUpdates) {
|
|
{
|
|
validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
|
|
}
|
|
(updatePayload = updatePayload || []).push(STYLE, styleUpdates);
|
|
}
|
|
return updatePayload;
|
|
}
|
|
function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
|
|
if (tag === "input" && nextRawProps.type === "radio" && nextRawProps.name != null) {
|
|
updateChecked(domElement, nextRawProps);
|
|
}
|
|
var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
|
|
var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
|
|
updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
|
|
switch (tag) {
|
|
case "input":
|
|
updateWrapper(domElement, nextRawProps);
|
|
break;
|
|
case "textarea":
|
|
updateWrapper$1(domElement, nextRawProps);
|
|
break;
|
|
case "select":
|
|
postUpdateWrapper(domElement, nextRawProps);
|
|
break;
|
|
}
|
|
}
|
|
function getPossibleStandardName(propName) {
|
|
{
|
|
var lowerCasedName = propName.toLowerCase();
|
|
if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
|
|
return null;
|
|
}
|
|
return possibleStandardNames[lowerCasedName] || null;
|
|
}
|
|
}
|
|
function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement, isConcurrentMode, shouldWarnDev) {
|
|
var isCustomComponentTag;
|
|
var extraAttributeNames;
|
|
{
|
|
isCustomComponentTag = isCustomComponent(tag, rawProps);
|
|
validatePropertiesInDevelopment(tag, rawProps);
|
|
}
|
|
switch (tag) {
|
|
case "dialog":
|
|
listenToNonDelegatedEvent("cancel", domElement);
|
|
listenToNonDelegatedEvent("close", domElement);
|
|
break;
|
|
case "iframe":
|
|
case "object":
|
|
case "embed":
|
|
listenToNonDelegatedEvent("load", domElement);
|
|
break;
|
|
case "video":
|
|
case "audio":
|
|
for (var i = 0; i < mediaEventTypes.length; i++) {
|
|
listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
|
|
}
|
|
break;
|
|
case "source":
|
|
listenToNonDelegatedEvent("error", domElement);
|
|
break;
|
|
case "img":
|
|
case "image":
|
|
case "link":
|
|
listenToNonDelegatedEvent("error", domElement);
|
|
listenToNonDelegatedEvent("load", domElement);
|
|
break;
|
|
case "details":
|
|
listenToNonDelegatedEvent("toggle", domElement);
|
|
break;
|
|
case "input":
|
|
initWrapperState(domElement, rawProps);
|
|
listenToNonDelegatedEvent("invalid", domElement);
|
|
break;
|
|
case "option":
|
|
validateProps(domElement, rawProps);
|
|
break;
|
|
case "select":
|
|
initWrapperState$1(domElement, rawProps);
|
|
listenToNonDelegatedEvent("invalid", domElement);
|
|
break;
|
|
case "textarea":
|
|
initWrapperState$2(domElement, rawProps);
|
|
listenToNonDelegatedEvent("invalid", domElement);
|
|
break;
|
|
}
|
|
assertValidProps(tag, rawProps);
|
|
{
|
|
extraAttributeNames = /* @__PURE__ */ new Set();
|
|
var attributes = domElement.attributes;
|
|
for (var _i = 0; _i < attributes.length; _i++) {
|
|
var name = attributes[_i].name.toLowerCase();
|
|
switch (name) {
|
|
case "value":
|
|
break;
|
|
case "checked":
|
|
break;
|
|
case "selected":
|
|
break;
|
|
default:
|
|
extraAttributeNames.add(attributes[_i].name);
|
|
}
|
|
}
|
|
}
|
|
var updatePayload = null;
|
|
for (var propKey in rawProps) {
|
|
if (!rawProps.hasOwnProperty(propKey)) {
|
|
continue;
|
|
}
|
|
var nextProp = rawProps[propKey];
|
|
if (propKey === CHILDREN) {
|
|
if (typeof nextProp === "string") {
|
|
if (domElement.textContent !== nextProp) {
|
|
if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
|
checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
|
|
}
|
|
updatePayload = [CHILDREN, nextProp];
|
|
}
|
|
} else if (typeof nextProp === "number") {
|
|
if (domElement.textContent !== "" + nextProp) {
|
|
if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
|
checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
|
|
}
|
|
updatePayload = [CHILDREN, "" + nextProp];
|
|
}
|
|
}
|
|
} else if (registrationNameDependencies.hasOwnProperty(propKey)) {
|
|
if (nextProp != null) {
|
|
if (typeof nextProp !== "function") {
|
|
warnForInvalidEventListener(propKey, nextProp);
|
|
}
|
|
if (propKey === "onScroll") {
|
|
listenToNonDelegatedEvent("scroll", domElement);
|
|
}
|
|
}
|
|
} else if (shouldWarnDev && true && typeof isCustomComponentTag === "boolean") {
|
|
var serverValue = void 0;
|
|
var propertyInfo = isCustomComponentTag && enableCustomElementPropertySupport ? null : getPropertyInfo(propKey);
|
|
if (rawProps[SUPPRESS_HYDRATION_WARNING] === true)
|
|
;
|
|
else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || propKey === "value" || propKey === "checked" || propKey === "selected")
|
|
;
|
|
else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
|
|
var serverHTML = domElement.innerHTML;
|
|
var nextHtml = nextProp ? nextProp[HTML$1] : void 0;
|
|
if (nextHtml != null) {
|
|
var expectedHTML = normalizeHTML(domElement, nextHtml);
|
|
if (expectedHTML !== serverHTML) {
|
|
warnForPropDifference(propKey, serverHTML, expectedHTML);
|
|
}
|
|
}
|
|
} else if (propKey === STYLE) {
|
|
extraAttributeNames.delete(propKey);
|
|
if (canDiffStyleForHydrationWarning) {
|
|
var expectedStyle = createDangerousStringForStyles(nextProp);
|
|
serverValue = domElement.getAttribute("style");
|
|
if (expectedStyle !== serverValue) {
|
|
warnForPropDifference(propKey, serverValue, expectedStyle);
|
|
}
|
|
}
|
|
} else if (isCustomComponentTag && !enableCustomElementPropertySupport) {
|
|
extraAttributeNames.delete(propKey.toLowerCase());
|
|
serverValue = getValueForAttribute(domElement, propKey, nextProp);
|
|
if (nextProp !== serverValue) {
|
|
warnForPropDifference(propKey, serverValue, nextProp);
|
|
}
|
|
} else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
|
|
var isMismatchDueToBadCasing = false;
|
|
if (propertyInfo !== null) {
|
|
extraAttributeNames.delete(propertyInfo.attributeName);
|
|
serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
|
|
} else {
|
|
var ownNamespace = parentNamespace;
|
|
if (ownNamespace === HTML_NAMESPACE) {
|
|
ownNamespace = getIntrinsicNamespace(tag);
|
|
}
|
|
if (ownNamespace === HTML_NAMESPACE) {
|
|
extraAttributeNames.delete(propKey.toLowerCase());
|
|
} else {
|
|
var standardName = getPossibleStandardName(propKey);
|
|
if (standardName !== null && standardName !== propKey) {
|
|
isMismatchDueToBadCasing = true;
|
|
extraAttributeNames.delete(standardName);
|
|
}
|
|
extraAttributeNames.delete(propKey);
|
|
}
|
|
serverValue = getValueForAttribute(domElement, propKey, nextProp);
|
|
}
|
|
var dontWarnCustomElement = enableCustomElementPropertySupport;
|
|
if (!dontWarnCustomElement && nextProp !== serverValue && !isMismatchDueToBadCasing) {
|
|
warnForPropDifference(propKey, serverValue, nextProp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
{
|
|
if (shouldWarnDev) {
|
|
if (extraAttributeNames.size > 0 && rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
|
warnForExtraAttributes(extraAttributeNames);
|
|
}
|
|
}
|
|
}
|
|
switch (tag) {
|
|
case "input":
|
|
track(domElement);
|
|
postMountWrapper(domElement, rawProps, true);
|
|
break;
|
|
case "textarea":
|
|
track(domElement);
|
|
postMountWrapper$3(domElement);
|
|
break;
|
|
case "select":
|
|
case "option":
|
|
break;
|
|
default:
|
|
if (typeof rawProps.onClick === "function") {
|
|
trapClickOnNonInteractiveElement(domElement);
|
|
}
|
|
break;
|
|
}
|
|
return updatePayload;
|
|
}
|
|
function diffHydratedText(textNode, text, isConcurrentMode) {
|
|
var isDifferent = textNode.nodeValue !== text;
|
|
return isDifferent;
|
|
}
|
|
function warnForDeletedHydratableElement(parentNode, child) {
|
|
{
|
|
if (didWarnInvalidHydration) {
|
|
return;
|
|
}
|
|
didWarnInvalidHydration = true;
|
|
error("Did not expect server HTML to contain a <%s> in <%s>.", child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
|
|
}
|
|
}
|
|
function warnForDeletedHydratableText(parentNode, child) {
|
|
{
|
|
if (didWarnInvalidHydration) {
|
|
return;
|
|
}
|
|
didWarnInvalidHydration = true;
|
|
error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
|
|
}
|
|
}
|
|
function warnForInsertedHydratedElement(parentNode, tag, props) {
|
|
{
|
|
if (didWarnInvalidHydration) {
|
|
return;
|
|
}
|
|
didWarnInvalidHydration = true;
|
|
error("Expected server HTML to contain a matching <%s> in <%s>.", tag, parentNode.nodeName.toLowerCase());
|
|
}
|
|
}
|
|
function warnForInsertedHydratedText(parentNode, text) {
|
|
{
|
|
if (text === "") {
|
|
return;
|
|
}
|
|
if (didWarnInvalidHydration) {
|
|
return;
|
|
}
|
|
didWarnInvalidHydration = true;
|
|
error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
|
|
}
|
|
}
|
|
function restoreControlledState$3(domElement, tag, props) {
|
|
switch (tag) {
|
|
case "input":
|
|
restoreControlledState(domElement, props);
|
|
return;
|
|
case "textarea":
|
|
restoreControlledState$2(domElement, props);
|
|
return;
|
|
case "select":
|
|
restoreControlledState$1(domElement, props);
|
|
return;
|
|
}
|
|
}
|
|
var validateDOMNesting = function() {
|
|
};
|
|
var updatedAncestorInfo = function() {
|
|
};
|
|
{
|
|
var specialTags = ["address", "applet", "area", "article", "aside", "base", "basefont", "bgsound", "blockquote", "body", "br", "button", "caption", "center", "col", "colgroup", "dd", "details", "dir", "div", "dl", "dt", "embed", "fieldset", "figcaption", "figure", "footer", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "iframe", "img", "input", "isindex", "li", "link", "listing", "main", "marquee", "menu", "menuitem", "meta", "nav", "noembed", "noframes", "noscript", "object", "ol", "p", "param", "plaintext", "pre", "script", "section", "select", "source", "style", "summary", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "title", "tr", "track", "ul", "wbr", "xmp"];
|
|
var inScopeTags = [
|
|
"applet",
|
|
"caption",
|
|
"html",
|
|
"table",
|
|
"td",
|
|
"th",
|
|
"marquee",
|
|
"object",
|
|
"template",
|
|
"foreignObject",
|
|
"desc",
|
|
"title"
|
|
];
|
|
var buttonScopeTags = inScopeTags.concat(["button"]);
|
|
var impliedEndTags = ["dd", "dt", "li", "option", "optgroup", "p", "rp", "rt"];
|
|
var emptyAncestorInfo = {
|
|
current: null,
|
|
formTag: null,
|
|
aTagInScope: null,
|
|
buttonTagInScope: null,
|
|
nobrTagInScope: null,
|
|
pTagInButtonScope: null,
|
|
listItemTagAutoclosing: null,
|
|
dlItemTagAutoclosing: null
|
|
};
|
|
updatedAncestorInfo = function(oldInfo, tag) {
|
|
var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
|
|
var info = {
|
|
tag
|
|
};
|
|
if (inScopeTags.indexOf(tag) !== -1) {
|
|
ancestorInfo.aTagInScope = null;
|
|
ancestorInfo.buttonTagInScope = null;
|
|
ancestorInfo.nobrTagInScope = null;
|
|
}
|
|
if (buttonScopeTags.indexOf(tag) !== -1) {
|
|
ancestorInfo.pTagInButtonScope = null;
|
|
}
|
|
if (specialTags.indexOf(tag) !== -1 && tag !== "address" && tag !== "div" && tag !== "p") {
|
|
ancestorInfo.listItemTagAutoclosing = null;
|
|
ancestorInfo.dlItemTagAutoclosing = null;
|
|
}
|
|
ancestorInfo.current = info;
|
|
if (tag === "form") {
|
|
ancestorInfo.formTag = info;
|
|
}
|
|
if (tag === "a") {
|
|
ancestorInfo.aTagInScope = info;
|
|
}
|
|
if (tag === "button") {
|
|
ancestorInfo.buttonTagInScope = info;
|
|
}
|
|
if (tag === "nobr") {
|
|
ancestorInfo.nobrTagInScope = info;
|
|
}
|
|
if (tag === "p") {
|
|
ancestorInfo.pTagInButtonScope = info;
|
|
}
|
|
if (tag === "li") {
|
|
ancestorInfo.listItemTagAutoclosing = info;
|
|
}
|
|
if (tag === "dd" || tag === "dt") {
|
|
ancestorInfo.dlItemTagAutoclosing = info;
|
|
}
|
|
return ancestorInfo;
|
|
};
|
|
var isTagValidWithParent = function(tag, parentTag) {
|
|
switch (parentTag) {
|
|
case "select":
|
|
return tag === "option" || tag === "optgroup" || tag === "#text";
|
|
case "optgroup":
|
|
return tag === "option" || tag === "#text";
|
|
case "option":
|
|
return tag === "#text";
|
|
case "tr":
|
|
return tag === "th" || tag === "td" || tag === "style" || tag === "script" || tag === "template";
|
|
case "tbody":
|
|
case "thead":
|
|
case "tfoot":
|
|
return tag === "tr" || tag === "style" || tag === "script" || tag === "template";
|
|
case "colgroup":
|
|
return tag === "col" || tag === "template";
|
|
case "table":
|
|
return tag === "caption" || tag === "colgroup" || tag === "tbody" || tag === "tfoot" || tag === "thead" || tag === "style" || tag === "script" || tag === "template";
|
|
case "head":
|
|
return tag === "base" || tag === "basefont" || tag === "bgsound" || tag === "link" || tag === "meta" || tag === "title" || tag === "noscript" || tag === "noframes" || tag === "style" || tag === "script" || tag === "template";
|
|
case "html":
|
|
return tag === "head" || tag === "body" || tag === "frameset";
|
|
case "frameset":
|
|
return tag === "frame";
|
|
case "#document":
|
|
return tag === "html";
|
|
}
|
|
switch (tag) {
|
|
case "h1":
|
|
case "h2":
|
|
case "h3":
|
|
case "h4":
|
|
case "h5":
|
|
case "h6":
|
|
return parentTag !== "h1" && parentTag !== "h2" && parentTag !== "h3" && parentTag !== "h4" && parentTag !== "h5" && parentTag !== "h6";
|
|
case "rp":
|
|
case "rt":
|
|
return impliedEndTags.indexOf(parentTag) === -1;
|
|
case "body":
|
|
case "caption":
|
|
case "col":
|
|
case "colgroup":
|
|
case "frameset":
|
|
case "frame":
|
|
case "head":
|
|
case "html":
|
|
case "tbody":
|
|
case "td":
|
|
case "tfoot":
|
|
case "th":
|
|
case "thead":
|
|
case "tr":
|
|
return parentTag == null;
|
|
}
|
|
return true;
|
|
};
|
|
var findInvalidAncestorForTag = function(tag, ancestorInfo) {
|
|
switch (tag) {
|
|
case "address":
|
|
case "article":
|
|
case "aside":
|
|
case "blockquote":
|
|
case "center":
|
|
case "details":
|
|
case "dialog":
|
|
case "dir":
|
|
case "div":
|
|
case "dl":
|
|
case "fieldset":
|
|
case "figcaption":
|
|
case "figure":
|
|
case "footer":
|
|
case "header":
|
|
case "hgroup":
|
|
case "main":
|
|
case "menu":
|
|
case "nav":
|
|
case "ol":
|
|
case "p":
|
|
case "section":
|
|
case "summary":
|
|
case "ul":
|
|
case "pre":
|
|
case "listing":
|
|
case "table":
|
|
case "hr":
|
|
case "xmp":
|
|
case "h1":
|
|
case "h2":
|
|
case "h3":
|
|
case "h4":
|
|
case "h5":
|
|
case "h6":
|
|
return ancestorInfo.pTagInButtonScope;
|
|
case "form":
|
|
return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
|
|
case "li":
|
|
return ancestorInfo.listItemTagAutoclosing;
|
|
case "dd":
|
|
case "dt":
|
|
return ancestorInfo.dlItemTagAutoclosing;
|
|
case "button":
|
|
return ancestorInfo.buttonTagInScope;
|
|
case "a":
|
|
return ancestorInfo.aTagInScope;
|
|
case "nobr":
|
|
return ancestorInfo.nobrTagInScope;
|
|
}
|
|
return null;
|
|
};
|
|
var didWarn$1 = {};
|
|
validateDOMNesting = function(childTag, childText, ancestorInfo) {
|
|
ancestorInfo = ancestorInfo || emptyAncestorInfo;
|
|
var parentInfo = ancestorInfo.current;
|
|
var parentTag = parentInfo && parentInfo.tag;
|
|
if (childText != null) {
|
|
if (childTag != null) {
|
|
error("validateDOMNesting: when childText is passed, childTag should be null");
|
|
}
|
|
childTag = "#text";
|
|
}
|
|
var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
|
|
var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
|
|
var invalidParentOrAncestor = invalidParent || invalidAncestor;
|
|
if (!invalidParentOrAncestor) {
|
|
return;
|
|
}
|
|
var ancestorTag = invalidParentOrAncestor.tag;
|
|
var warnKey = !!invalidParent + "|" + childTag + "|" + ancestorTag;
|
|
if (didWarn$1[warnKey]) {
|
|
return;
|
|
}
|
|
didWarn$1[warnKey] = true;
|
|
var tagDisplayName = childTag;
|
|
var whitespaceInfo = "";
|
|
if (childTag === "#text") {
|
|
if (/\S/.test(childText)) {
|
|
tagDisplayName = "Text nodes";
|
|
} else {
|
|
tagDisplayName = "Whitespace text nodes";
|
|
whitespaceInfo = " Make sure you don't have any extra whitespace between tags on each line of your source code.";
|
|
}
|
|
} else {
|
|
tagDisplayName = "<" + childTag + ">";
|
|
}
|
|
if (invalidParent) {
|
|
var info = "";
|
|
if (ancestorTag === "table" && childTag === "tr") {
|
|
info += " Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by the browser.";
|
|
}
|
|
error("validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s", tagDisplayName, ancestorTag, whitespaceInfo, info);
|
|
} else {
|
|
error("validateDOMNesting(...): %s cannot appear as a descendant of <%s>.", tagDisplayName, ancestorTag);
|
|
}
|
|
};
|
|
}
|
|
var SUPPRESS_HYDRATION_WARNING$1 = "suppressHydrationWarning";
|
|
var SUSPENSE_START_DATA = "$";
|
|
var SUSPENSE_END_DATA = "/$";
|
|
var SUSPENSE_PENDING_START_DATA = "$?";
|
|
var SUSPENSE_FALLBACK_START_DATA = "$!";
|
|
var STYLE$1 = "style";
|
|
var eventsEnabled = null;
|
|
var selectionInformation = null;
|
|
function getRootHostContext(rootContainerInstance) {
|
|
var type;
|
|
var namespace;
|
|
var nodeType = rootContainerInstance.nodeType;
|
|
switch (nodeType) {
|
|
case DOCUMENT_NODE:
|
|
case DOCUMENT_FRAGMENT_NODE: {
|
|
type = nodeType === DOCUMENT_NODE ? "#document" : "#fragment";
|
|
var root3 = rootContainerInstance.documentElement;
|
|
namespace = root3 ? root3.namespaceURI : getChildNamespace(null, "");
|
|
break;
|
|
}
|
|
default: {
|
|
var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
|
|
var ownNamespace = container.namespaceURI || null;
|
|
type = container.tagName;
|
|
namespace = getChildNamespace(ownNamespace, type);
|
|
break;
|
|
}
|
|
}
|
|
{
|
|
var validatedTag = type.toLowerCase();
|
|
var ancestorInfo = updatedAncestorInfo(null, validatedTag);
|
|
return {
|
|
namespace,
|
|
ancestorInfo
|
|
};
|
|
}
|
|
}
|
|
function getChildHostContext(parentHostContext, type, rootContainerInstance) {
|
|
{
|
|
var parentHostContextDev = parentHostContext;
|
|
var namespace = getChildNamespace(parentHostContextDev.namespace, type);
|
|
var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
|
|
return {
|
|
namespace,
|
|
ancestorInfo
|
|
};
|
|
}
|
|
}
|
|
function getPublicInstance(instance) {
|
|
return instance;
|
|
}
|
|
function prepareForCommit(containerInfo) {
|
|
eventsEnabled = isEnabled();
|
|
selectionInformation = getSelectionInformation();
|
|
var activeInstance = null;
|
|
setEnabled(false);
|
|
return activeInstance;
|
|
}
|
|
function resetAfterCommit(containerInfo) {
|
|
restoreSelection(selectionInformation);
|
|
setEnabled(eventsEnabled);
|
|
eventsEnabled = null;
|
|
selectionInformation = null;
|
|
}
|
|
function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
|
|
var parentNamespace;
|
|
{
|
|
var hostContextDev = hostContext;
|
|
validateDOMNesting(type, null, hostContextDev.ancestorInfo);
|
|
if (typeof props.children === "string" || typeof props.children === "number") {
|
|
var string = "" + props.children;
|
|
var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
|
|
validateDOMNesting(null, string, ownAncestorInfo);
|
|
}
|
|
parentNamespace = hostContextDev.namespace;
|
|
}
|
|
var domElement = createElement3(type, props, rootContainerInstance, parentNamespace);
|
|
precacheFiberNode(internalInstanceHandle, domElement);
|
|
updateFiberProps(domElement, props);
|
|
return domElement;
|
|
}
|
|
function appendInitialChild(parentInstance, child) {
|
|
parentInstance.appendChild(child);
|
|
}
|
|
function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
|
|
setInitialProperties(domElement, type, props, rootContainerInstance);
|
|
switch (type) {
|
|
case "button":
|
|
case "input":
|
|
case "select":
|
|
case "textarea":
|
|
return !!props.autoFocus;
|
|
case "img":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
|
|
{
|
|
var hostContextDev = hostContext;
|
|
if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === "string" || typeof newProps.children === "number")) {
|
|
var string = "" + newProps.children;
|
|
var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
|
|
validateDOMNesting(null, string, ownAncestorInfo);
|
|
}
|
|
}
|
|
return diffProperties(domElement, type, oldProps, newProps);
|
|
}
|
|
function shouldSetTextContent(type, props) {
|
|
return type === "textarea" || type === "noscript" || typeof props.children === "string" || typeof props.children === "number" || typeof props.dangerouslySetInnerHTML === "object" && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
|
|
}
|
|
function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
|
|
{
|
|
var hostContextDev = hostContext;
|
|
validateDOMNesting(null, text, hostContextDev.ancestorInfo);
|
|
}
|
|
var textNode = createTextNode(text, rootContainerInstance);
|
|
precacheFiberNode(internalInstanceHandle, textNode);
|
|
return textNode;
|
|
}
|
|
function getCurrentEventPriority() {
|
|
var currentEvent = window.event;
|
|
if (currentEvent === void 0) {
|
|
return DefaultEventPriority;
|
|
}
|
|
return getEventPriority(currentEvent.type);
|
|
}
|
|
var scheduleTimeout = typeof setTimeout === "function" ? setTimeout : void 0;
|
|
var cancelTimeout = typeof clearTimeout === "function" ? clearTimeout : void 0;
|
|
var noTimeout = -1;
|
|
var localPromise = typeof Promise === "function" ? Promise : void 0;
|
|
var scheduleMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : typeof localPromise !== "undefined" ? function(callback) {
|
|
return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
|
|
} : scheduleTimeout;
|
|
function handleErrorInNextTick(error2) {
|
|
setTimeout(function() {
|
|
throw error2;
|
|
});
|
|
}
|
|
function commitMount(domElement, type, newProps, internalInstanceHandle) {
|
|
switch (type) {
|
|
case "button":
|
|
case "input":
|
|
case "select":
|
|
case "textarea":
|
|
if (newProps.autoFocus) {
|
|
domElement.focus();
|
|
}
|
|
return;
|
|
case "img": {
|
|
if (newProps.src) {
|
|
domElement.src = newProps.src;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
|
|
updateProperties(domElement, updatePayload, type, oldProps, newProps);
|
|
updateFiberProps(domElement, newProps);
|
|
}
|
|
function resetTextContent(domElement) {
|
|
setTextContent(domElement, "");
|
|
}
|
|
function commitTextUpdate(textInstance, oldText, newText) {
|
|
textInstance.nodeValue = newText;
|
|
}
|
|
function appendChild(parentInstance, child) {
|
|
parentInstance.appendChild(child);
|
|
}
|
|
function appendChildToContainer(container, child) {
|
|
var parentNode;
|
|
if (container.nodeType === COMMENT_NODE) {
|
|
parentNode = container.parentNode;
|
|
parentNode.insertBefore(child, container);
|
|
} else {
|
|
parentNode = container;
|
|
parentNode.appendChild(child);
|
|
}
|
|
var reactRootContainer = container._reactRootContainer;
|
|
if ((reactRootContainer === null || reactRootContainer === void 0) && parentNode.onclick === null) {
|
|
trapClickOnNonInteractiveElement(parentNode);
|
|
}
|
|
}
|
|
function insertBefore(parentInstance, child, beforeChild) {
|
|
parentInstance.insertBefore(child, beforeChild);
|
|
}
|
|
function insertInContainerBefore(container, child, beforeChild) {
|
|
if (container.nodeType === COMMENT_NODE) {
|
|
container.parentNode.insertBefore(child, beforeChild);
|
|
} else {
|
|
container.insertBefore(child, beforeChild);
|
|
}
|
|
}
|
|
function removeChild(parentInstance, child) {
|
|
parentInstance.removeChild(child);
|
|
}
|
|
function removeChildFromContainer(container, child) {
|
|
if (container.nodeType === COMMENT_NODE) {
|
|
container.parentNode.removeChild(child);
|
|
} else {
|
|
container.removeChild(child);
|
|
}
|
|
}
|
|
function clearSuspenseBoundary(parentInstance, suspenseInstance) {
|
|
var node = suspenseInstance;
|
|
var depth = 0;
|
|
do {
|
|
var nextNode = node.nextSibling;
|
|
parentInstance.removeChild(node);
|
|
if (nextNode && nextNode.nodeType === COMMENT_NODE) {
|
|
var data = nextNode.data;
|
|
if (data === SUSPENSE_END_DATA) {
|
|
if (depth === 0) {
|
|
parentInstance.removeChild(nextNode);
|
|
retryIfBlockedOn(suspenseInstance);
|
|
return;
|
|
} else {
|
|
depth--;
|
|
}
|
|
} else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
|
|
depth++;
|
|
}
|
|
}
|
|
node = nextNode;
|
|
} while (node);
|
|
retryIfBlockedOn(suspenseInstance);
|
|
}
|
|
function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
|
|
if (container.nodeType === COMMENT_NODE) {
|
|
clearSuspenseBoundary(container.parentNode, suspenseInstance);
|
|
} else if (container.nodeType === ELEMENT_NODE) {
|
|
clearSuspenseBoundary(container, suspenseInstance);
|
|
}
|
|
retryIfBlockedOn(container);
|
|
}
|
|
function hideInstance(instance) {
|
|
instance = instance;
|
|
var style2 = instance.style;
|
|
if (typeof style2.setProperty === "function") {
|
|
style2.setProperty("display", "none", "important");
|
|
} else {
|
|
style2.display = "none";
|
|
}
|
|
}
|
|
function hideTextInstance(textInstance) {
|
|
textInstance.nodeValue = "";
|
|
}
|
|
function unhideInstance(instance, props) {
|
|
instance = instance;
|
|
var styleProp = props[STYLE$1];
|
|
var display = styleProp !== void 0 && styleProp !== null && styleProp.hasOwnProperty("display") ? styleProp.display : null;
|
|
instance.style.display = dangerousStyleValue("display", display);
|
|
}
|
|
function unhideTextInstance(textInstance, text) {
|
|
textInstance.nodeValue = text;
|
|
}
|
|
function clearContainer(container) {
|
|
if (container.nodeType === ELEMENT_NODE) {
|
|
container.textContent = "";
|
|
} else if (container.nodeType === DOCUMENT_NODE) {
|
|
var body = container.body;
|
|
if (body != null) {
|
|
body.textContent = "";
|
|
}
|
|
}
|
|
}
|
|
function canHydrateInstance(instance, type, props) {
|
|
if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
|
|
return null;
|
|
}
|
|
return instance;
|
|
}
|
|
function canHydrateTextInstance(instance, text) {
|
|
if (text === "" || instance.nodeType !== TEXT_NODE) {
|
|
return null;
|
|
}
|
|
return instance;
|
|
}
|
|
function canHydrateSuspenseInstance(instance) {
|
|
if (instance.nodeType !== COMMENT_NODE) {
|
|
return null;
|
|
}
|
|
return instance;
|
|
}
|
|
function isSuspenseInstancePending(instance) {
|
|
return instance.data === SUSPENSE_PENDING_START_DATA;
|
|
}
|
|
function isSuspenseInstanceFallback(instance) {
|
|
return instance.data === SUSPENSE_FALLBACK_START_DATA;
|
|
}
|
|
function registerSuspenseInstanceRetry(instance, callback) {
|
|
instance._reactRetry = callback;
|
|
}
|
|
function getNextHydratable(node) {
|
|
for (; node != null; node = node.nextSibling) {
|
|
var nodeType = node.nodeType;
|
|
if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
|
|
break;
|
|
}
|
|
if (nodeType === COMMENT_NODE) {
|
|
var nodeData = node.data;
|
|
if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
|
|
break;
|
|
}
|
|
if (nodeData === SUSPENSE_END_DATA) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
return node;
|
|
}
|
|
function getNextHydratableSibling(instance) {
|
|
return getNextHydratable(instance.nextSibling);
|
|
}
|
|
function getFirstHydratableChild(parentInstance) {
|
|
return getNextHydratable(parentInstance.firstChild);
|
|
}
|
|
function getFirstHydratableChildWithinContainer(parentContainer) {
|
|
return getNextHydratable(parentContainer.firstChild);
|
|
}
|
|
function getFirstHydratableChildWithinSuspenseInstance(parentInstance) {
|
|
return getNextHydratable(parentInstance.nextSibling);
|
|
}
|
|
function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) {
|
|
precacheFiberNode(internalInstanceHandle, instance);
|
|
updateFiberProps(instance, props);
|
|
var parentNamespace;
|
|
{
|
|
var hostContextDev = hostContext;
|
|
parentNamespace = hostContextDev.namespace;
|
|
}
|
|
var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
|
|
return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev);
|
|
}
|
|
function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) {
|
|
precacheFiberNode(internalInstanceHandle, textInstance);
|
|
var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
|
|
return diffHydratedText(textInstance, text);
|
|
}
|
|
function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
|
|
precacheFiberNode(internalInstanceHandle, suspenseInstance);
|
|
}
|
|
function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
|
|
var node = suspenseInstance.nextSibling;
|
|
var depth = 0;
|
|
while (node) {
|
|
if (node.nodeType === COMMENT_NODE) {
|
|
var data = node.data;
|
|
if (data === SUSPENSE_END_DATA) {
|
|
if (depth === 0) {
|
|
return getNextHydratableSibling(node);
|
|
} else {
|
|
depth--;
|
|
}
|
|
} else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
|
|
depth++;
|
|
}
|
|
}
|
|
node = node.nextSibling;
|
|
}
|
|
return null;
|
|
}
|
|
function getParentSuspenseInstance(targetInstance) {
|
|
var node = targetInstance.previousSibling;
|
|
var depth = 0;
|
|
while (node) {
|
|
if (node.nodeType === COMMENT_NODE) {
|
|
var data = node.data;
|
|
if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
|
|
if (depth === 0) {
|
|
return node;
|
|
} else {
|
|
depth--;
|
|
}
|
|
} else if (data === SUSPENSE_END_DATA) {
|
|
depth++;
|
|
}
|
|
}
|
|
node = node.previousSibling;
|
|
}
|
|
return null;
|
|
}
|
|
function commitHydratedContainer(container) {
|
|
retryIfBlockedOn(container);
|
|
}
|
|
function commitHydratedSuspenseInstance(suspenseInstance) {
|
|
retryIfBlockedOn(suspenseInstance);
|
|
}
|
|
function shouldDeleteUnhydratedTailInstances(parentType) {
|
|
return parentType !== "head" && parentType !== "body";
|
|
}
|
|
function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) {
|
|
var shouldWarnDev = true;
|
|
checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
|
|
}
|
|
function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) {
|
|
if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
|
|
var shouldWarnDev = true;
|
|
checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
|
|
}
|
|
}
|
|
function didNotHydrateInstanceWithinContainer(parentContainer, instance) {
|
|
{
|
|
if (instance.nodeType === ELEMENT_NODE) {
|
|
warnForDeletedHydratableElement(parentContainer, instance);
|
|
} else if (instance.nodeType === COMMENT_NODE)
|
|
;
|
|
else {
|
|
warnForDeletedHydratableText(parentContainer, instance);
|
|
}
|
|
}
|
|
}
|
|
function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) {
|
|
{
|
|
var parentNode = parentInstance.parentNode;
|
|
if (parentNode !== null) {
|
|
if (instance.nodeType === ELEMENT_NODE) {
|
|
warnForDeletedHydratableElement(parentNode, instance);
|
|
} else if (instance.nodeType === COMMENT_NODE)
|
|
;
|
|
else {
|
|
warnForDeletedHydratableText(parentNode, instance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function didNotHydrateInstance(parentType, parentProps, parentInstance, instance, isConcurrentMode) {
|
|
{
|
|
if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
|
|
if (instance.nodeType === ELEMENT_NODE) {
|
|
warnForDeletedHydratableElement(parentInstance, instance);
|
|
} else if (instance.nodeType === COMMENT_NODE)
|
|
;
|
|
else {
|
|
warnForDeletedHydratableText(parentInstance, instance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) {
|
|
{
|
|
warnForInsertedHydratedElement(parentContainer, type);
|
|
}
|
|
}
|
|
function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) {
|
|
{
|
|
warnForInsertedHydratedText(parentContainer, text);
|
|
}
|
|
}
|
|
function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) {
|
|
{
|
|
var parentNode = parentInstance.parentNode;
|
|
if (parentNode !== null)
|
|
warnForInsertedHydratedElement(parentNode, type);
|
|
}
|
|
}
|
|
function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) {
|
|
{
|
|
var parentNode = parentInstance.parentNode;
|
|
if (parentNode !== null)
|
|
warnForInsertedHydratedText(parentNode, text);
|
|
}
|
|
}
|
|
function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props, isConcurrentMode) {
|
|
{
|
|
if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
|
|
warnForInsertedHydratedElement(parentInstance, type);
|
|
}
|
|
}
|
|
}
|
|
function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text, isConcurrentMode) {
|
|
{
|
|
if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
|
|
warnForInsertedHydratedText(parentInstance, text);
|
|
}
|
|
}
|
|
}
|
|
function errorHydratingContainer(parentContainer) {
|
|
{
|
|
error("An error occurred during hydration. The server HTML was replaced with client content in <%s>.", parentContainer.nodeName.toLowerCase());
|
|
}
|
|
}
|
|
function preparePortalMount(portalInstance) {
|
|
listenToAllSupportedEvents(portalInstance);
|
|
}
|
|
var randomKey = Math.random().toString(36).slice(2);
|
|
var internalInstanceKey = "__reactFiber$" + randomKey;
|
|
var internalPropsKey = "__reactProps$" + randomKey;
|
|
var internalContainerInstanceKey = "__reactContainer$" + randomKey;
|
|
var internalEventHandlersKey = "__reactEvents$" + randomKey;
|
|
var internalEventHandlerListenersKey = "__reactListeners$" + randomKey;
|
|
var internalEventHandlesSetKey = "__reactHandles$" + randomKey;
|
|
function detachDeletedInstance(node) {
|
|
delete node[internalInstanceKey];
|
|
delete node[internalPropsKey];
|
|
delete node[internalEventHandlersKey];
|
|
delete node[internalEventHandlerListenersKey];
|
|
delete node[internalEventHandlesSetKey];
|
|
}
|
|
function precacheFiberNode(hostInst, node) {
|
|
node[internalInstanceKey] = hostInst;
|
|
}
|
|
function markContainerAsRoot(hostRoot, node) {
|
|
node[internalContainerInstanceKey] = hostRoot;
|
|
}
|
|
function unmarkContainerAsRoot(node) {
|
|
node[internalContainerInstanceKey] = null;
|
|
}
|
|
function isContainerMarkedAsRoot(node) {
|
|
return !!node[internalContainerInstanceKey];
|
|
}
|
|
function getClosestInstanceFromNode(targetNode) {
|
|
var targetInst = targetNode[internalInstanceKey];
|
|
if (targetInst) {
|
|
return targetInst;
|
|
}
|
|
var parentNode = targetNode.parentNode;
|
|
while (parentNode) {
|
|
targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
|
|
if (targetInst) {
|
|
var alternate = targetInst.alternate;
|
|
if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
|
|
var suspenseInstance = getParentSuspenseInstance(targetNode);
|
|
while (suspenseInstance !== null) {
|
|
var targetSuspenseInst = suspenseInstance[internalInstanceKey];
|
|
if (targetSuspenseInst) {
|
|
return targetSuspenseInst;
|
|
}
|
|
suspenseInstance = getParentSuspenseInstance(suspenseInstance);
|
|
}
|
|
}
|
|
return targetInst;
|
|
}
|
|
targetNode = parentNode;
|
|
parentNode = targetNode.parentNode;
|
|
}
|
|
return null;
|
|
}
|
|
function getInstanceFromNode(node) {
|
|
var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
|
|
if (inst) {
|
|
if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
|
|
return inst;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function getNodeFromInstance(inst) {
|
|
if (inst.tag === HostComponent || inst.tag === HostText) {
|
|
return inst.stateNode;
|
|
}
|
|
throw new Error("getNodeFromInstance: Invalid argument.");
|
|
}
|
|
function getFiberCurrentPropsFromNode(node) {
|
|
return node[internalPropsKey] || null;
|
|
}
|
|
function updateFiberProps(node, props) {
|
|
node[internalPropsKey] = props;
|
|
}
|
|
function getEventListenerSet(node) {
|
|
var elementListenerSet = node[internalEventHandlersKey];
|
|
if (elementListenerSet === void 0) {
|
|
elementListenerSet = node[internalEventHandlersKey] = /* @__PURE__ */ new Set();
|
|
}
|
|
return elementListenerSet;
|
|
}
|
|
var loggedTypeFailures = {};
|
|
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
function setCurrentlyValidatingElement(element) {
|
|
{
|
|
if (element) {
|
|
var owner = element._owner;
|
|
var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
|
|
ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
|
|
} else {
|
|
ReactDebugCurrentFrame$1.setExtraStackFrame(null);
|
|
}
|
|
}
|
|
}
|
|
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
|
{
|
|
var has2 = Function.call.bind(hasOwnProperty);
|
|
for (var typeSpecName in typeSpecs) {
|
|
if (has2(typeSpecs, typeSpecName)) {
|
|
var error$1 = void 0;
|
|
try {
|
|
if (typeof typeSpecs[typeSpecName] !== "function") {
|
|
var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
|
|
err.name = "Invariant Violation";
|
|
throw err;
|
|
}
|
|
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
|
|
} catch (ex) {
|
|
error$1 = ex;
|
|
}
|
|
if (error$1 && !(error$1 instanceof Error)) {
|
|
setCurrentlyValidatingElement(element);
|
|
error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1);
|
|
setCurrentlyValidatingElement(null);
|
|
}
|
|
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
|
loggedTypeFailures[error$1.message] = true;
|
|
setCurrentlyValidatingElement(element);
|
|
error("Failed %s type: %s", location, error$1.message);
|
|
setCurrentlyValidatingElement(null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var valueStack = [];
|
|
var fiberStack;
|
|
{
|
|
fiberStack = [];
|
|
}
|
|
var index = -1;
|
|
function createCursor(defaultValue) {
|
|
return {
|
|
current: defaultValue
|
|
};
|
|
}
|
|
function pop(cursor, fiber) {
|
|
if (index < 0) {
|
|
{
|
|
error("Unexpected pop.");
|
|
}
|
|
return;
|
|
}
|
|
{
|
|
if (fiber !== fiberStack[index]) {
|
|
error("Unexpected Fiber popped.");
|
|
}
|
|
}
|
|
cursor.current = valueStack[index];
|
|
valueStack[index] = null;
|
|
{
|
|
fiberStack[index] = null;
|
|
}
|
|
index--;
|
|
}
|
|
function push(cursor, value, fiber) {
|
|
index++;
|
|
valueStack[index] = cursor.current;
|
|
{
|
|
fiberStack[index] = fiber;
|
|
}
|
|
cursor.current = value;
|
|
}
|
|
var warnedAboutMissingGetChildContext;
|
|
{
|
|
warnedAboutMissingGetChildContext = {};
|
|
}
|
|
var emptyContextObject = {};
|
|
{
|
|
Object.freeze(emptyContextObject);
|
|
}
|
|
var contextStackCursor = createCursor(emptyContextObject);
|
|
var didPerformWorkStackCursor = createCursor(false);
|
|
var previousContext = emptyContextObject;
|
|
function getUnmaskedContext(workInProgress2, Component, didPushOwnContextIfProvider) {
|
|
{
|
|
if (didPushOwnContextIfProvider && isContextProvider(Component)) {
|
|
return previousContext;
|
|
}
|
|
return contextStackCursor.current;
|
|
}
|
|
}
|
|
function cacheContext(workInProgress2, unmaskedContext, maskedContext) {
|
|
{
|
|
var instance = workInProgress2.stateNode;
|
|
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
|
|
instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
|
|
}
|
|
}
|
|
function getMaskedContext(workInProgress2, unmaskedContext) {
|
|
{
|
|
var type = workInProgress2.type;
|
|
var contextTypes = type.contextTypes;
|
|
if (!contextTypes) {
|
|
return emptyContextObject;
|
|
}
|
|
var instance = workInProgress2.stateNode;
|
|
if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
|
|
return instance.__reactInternalMemoizedMaskedChildContext;
|
|
}
|
|
var context = {};
|
|
for (var key in contextTypes) {
|
|
context[key] = unmaskedContext[key];
|
|
}
|
|
{
|
|
var name = getComponentNameFromFiber(workInProgress2) || "Unknown";
|
|
checkPropTypes(contextTypes, context, "context", name);
|
|
}
|
|
if (instance) {
|
|
cacheContext(workInProgress2, unmaskedContext, context);
|
|
}
|
|
return context;
|
|
}
|
|
}
|
|
function hasContextChanged() {
|
|
{
|
|
return didPerformWorkStackCursor.current;
|
|
}
|
|
}
|
|
function isContextProvider(type) {
|
|
{
|
|
var childContextTypes = type.childContextTypes;
|
|
return childContextTypes !== null && childContextTypes !== void 0;
|
|
}
|
|
}
|
|
function popContext(fiber) {
|
|
{
|
|
pop(didPerformWorkStackCursor, fiber);
|
|
pop(contextStackCursor, fiber);
|
|
}
|
|
}
|
|
function popTopLevelContextObject(fiber) {
|
|
{
|
|
pop(didPerformWorkStackCursor, fiber);
|
|
pop(contextStackCursor, fiber);
|
|
}
|
|
}
|
|
function pushTopLevelContextObject(fiber, context, didChange) {
|
|
{
|
|
if (contextStackCursor.current !== emptyContextObject) {
|
|
throw new Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
push(contextStackCursor, context, fiber);
|
|
push(didPerformWorkStackCursor, didChange, fiber);
|
|
}
|
|
}
|
|
function processChildContext(fiber, type, parentContext) {
|
|
{
|
|
var instance = fiber.stateNode;
|
|
var childContextTypes = type.childContextTypes;
|
|
if (typeof instance.getChildContext !== "function") {
|
|
{
|
|
var componentName = getComponentNameFromFiber(fiber) || "Unknown";
|
|
if (!warnedAboutMissingGetChildContext[componentName]) {
|
|
warnedAboutMissingGetChildContext[componentName] = true;
|
|
error("%s.childContextTypes is specified but there is no getChildContext() method on the instance. You can either define getChildContext() on %s or remove childContextTypes from it.", componentName, componentName);
|
|
}
|
|
}
|
|
return parentContext;
|
|
}
|
|
var childContext = instance.getChildContext();
|
|
for (var contextKey in childContext) {
|
|
if (!(contextKey in childContextTypes)) {
|
|
throw new Error((getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.');
|
|
}
|
|
}
|
|
{
|
|
var name = getComponentNameFromFiber(fiber) || "Unknown";
|
|
checkPropTypes(childContextTypes, childContext, "child context", name);
|
|
}
|
|
return assign({}, parentContext, childContext);
|
|
}
|
|
}
|
|
function pushContextProvider(workInProgress2) {
|
|
{
|
|
var instance = workInProgress2.stateNode;
|
|
var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
|
|
previousContext = contextStackCursor.current;
|
|
push(contextStackCursor, memoizedMergedChildContext, workInProgress2);
|
|
push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress2);
|
|
return true;
|
|
}
|
|
}
|
|
function invalidateContextProvider(workInProgress2, type, didChange) {
|
|
{
|
|
var instance = workInProgress2.stateNode;
|
|
if (!instance) {
|
|
throw new Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
if (didChange) {
|
|
var mergedContext = processChildContext(workInProgress2, type, previousContext);
|
|
instance.__reactInternalMemoizedMergedChildContext = mergedContext;
|
|
pop(didPerformWorkStackCursor, workInProgress2);
|
|
pop(contextStackCursor, workInProgress2);
|
|
push(contextStackCursor, mergedContext, workInProgress2);
|
|
push(didPerformWorkStackCursor, didChange, workInProgress2);
|
|
} else {
|
|
pop(didPerformWorkStackCursor, workInProgress2);
|
|
push(didPerformWorkStackCursor, didChange, workInProgress2);
|
|
}
|
|
}
|
|
}
|
|
function findCurrentUnmaskedContext(fiber) {
|
|
{
|
|
if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) {
|
|
throw new Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
var node = fiber;
|
|
do {
|
|
switch (node.tag) {
|
|
case HostRoot:
|
|
return node.stateNode.context;
|
|
case ClassComponent: {
|
|
var Component = node.type;
|
|
if (isContextProvider(Component)) {
|
|
return node.stateNode.__reactInternalMemoizedMergedChildContext;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
node = node.return;
|
|
} while (node !== null);
|
|
throw new Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
var LegacyRoot = 0;
|
|
var ConcurrentRoot = 1;
|
|
var syncQueue = null;
|
|
var includesLegacySyncCallbacks = false;
|
|
var isFlushingSyncQueue = false;
|
|
function scheduleSyncCallback(callback) {
|
|
if (syncQueue === null) {
|
|
syncQueue = [callback];
|
|
} else {
|
|
syncQueue.push(callback);
|
|
}
|
|
}
|
|
function scheduleLegacySyncCallback(callback) {
|
|
includesLegacySyncCallbacks = true;
|
|
scheduleSyncCallback(callback);
|
|
}
|
|
function flushSyncCallbacksOnlyInLegacyMode() {
|
|
if (includesLegacySyncCallbacks) {
|
|
flushSyncCallbacks();
|
|
}
|
|
}
|
|
function flushSyncCallbacks() {
|
|
if (!isFlushingSyncQueue && syncQueue !== null) {
|
|
isFlushingSyncQueue = true;
|
|
var i = 0;
|
|
var previousUpdatePriority = getCurrentUpdatePriority();
|
|
try {
|
|
var isSync = true;
|
|
var queue = syncQueue;
|
|
setCurrentUpdatePriority(DiscreteEventPriority);
|
|
for (; i < queue.length; i++) {
|
|
var callback = queue[i];
|
|
do {
|
|
callback = callback(isSync);
|
|
} while (callback !== null);
|
|
}
|
|
syncQueue = null;
|
|
includesLegacySyncCallbacks = false;
|
|
} catch (error2) {
|
|
if (syncQueue !== null) {
|
|
syncQueue = syncQueue.slice(i + 1);
|
|
}
|
|
scheduleCallback(ImmediatePriority, flushSyncCallbacks);
|
|
throw error2;
|
|
} finally {
|
|
setCurrentUpdatePriority(previousUpdatePriority);
|
|
isFlushingSyncQueue = false;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
|
|
var NoTransition = null;
|
|
function requestCurrentTransition() {
|
|
return ReactCurrentBatchConfig$1.transition;
|
|
}
|
|
var ReactStrictModeWarnings = {
|
|
recordUnsafeLifecycleWarnings: function(fiber, instance) {
|
|
},
|
|
flushPendingUnsafeLifecycleWarnings: function() {
|
|
},
|
|
recordLegacyContextWarning: function(fiber, instance) {
|
|
},
|
|
flushLegacyContextWarning: function() {
|
|
},
|
|
discardPendingWarnings: function() {
|
|
}
|
|
};
|
|
{
|
|
var findStrictRoot = function(fiber) {
|
|
var maybeStrictRoot = null;
|
|
var node = fiber;
|
|
while (node !== null) {
|
|
if (node.mode & StrictLegacyMode) {
|
|
maybeStrictRoot = node;
|
|
}
|
|
node = node.return;
|
|
}
|
|
return maybeStrictRoot;
|
|
};
|
|
var setToSortedString = function(set2) {
|
|
var array = [];
|
|
set2.forEach(function(value) {
|
|
array.push(value);
|
|
});
|
|
return array.sort().join(", ");
|
|
};
|
|
var pendingComponentWillMountWarnings = [];
|
|
var pendingUNSAFE_ComponentWillMountWarnings = [];
|
|
var pendingComponentWillReceivePropsWarnings = [];
|
|
var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
|
|
var pendingComponentWillUpdateWarnings = [];
|
|
var pendingUNSAFE_ComponentWillUpdateWarnings = [];
|
|
var didWarnAboutUnsafeLifecycles = /* @__PURE__ */ new Set();
|
|
ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function(fiber, instance) {
|
|
if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
|
|
return;
|
|
}
|
|
if (typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true) {
|
|
pendingComponentWillMountWarnings.push(fiber);
|
|
}
|
|
if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function") {
|
|
pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
|
|
}
|
|
if (typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
|
|
pendingComponentWillReceivePropsWarnings.push(fiber);
|
|
}
|
|
if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function") {
|
|
pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
|
|
}
|
|
if (typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
|
|
pendingComponentWillUpdateWarnings.push(fiber);
|
|
}
|
|
if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function") {
|
|
pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
|
|
}
|
|
};
|
|
ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() {
|
|
var componentWillMountUniqueNames = /* @__PURE__ */ new Set();
|
|
if (pendingComponentWillMountWarnings.length > 0) {
|
|
pendingComponentWillMountWarnings.forEach(function(fiber) {
|
|
componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutUnsafeLifecycles.add(fiber.type);
|
|
});
|
|
pendingComponentWillMountWarnings = [];
|
|
}
|
|
var UNSAFE_componentWillMountUniqueNames = /* @__PURE__ */ new Set();
|
|
if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
|
|
pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) {
|
|
UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutUnsafeLifecycles.add(fiber.type);
|
|
});
|
|
pendingUNSAFE_ComponentWillMountWarnings = [];
|
|
}
|
|
var componentWillReceivePropsUniqueNames = /* @__PURE__ */ new Set();
|
|
if (pendingComponentWillReceivePropsWarnings.length > 0) {
|
|
pendingComponentWillReceivePropsWarnings.forEach(function(fiber) {
|
|
componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutUnsafeLifecycles.add(fiber.type);
|
|
});
|
|
pendingComponentWillReceivePropsWarnings = [];
|
|
}
|
|
var UNSAFE_componentWillReceivePropsUniqueNames = /* @__PURE__ */ new Set();
|
|
if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
|
|
pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) {
|
|
UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutUnsafeLifecycles.add(fiber.type);
|
|
});
|
|
pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
|
|
}
|
|
var componentWillUpdateUniqueNames = /* @__PURE__ */ new Set();
|
|
if (pendingComponentWillUpdateWarnings.length > 0) {
|
|
pendingComponentWillUpdateWarnings.forEach(function(fiber) {
|
|
componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutUnsafeLifecycles.add(fiber.type);
|
|
});
|
|
pendingComponentWillUpdateWarnings = [];
|
|
}
|
|
var UNSAFE_componentWillUpdateUniqueNames = /* @__PURE__ */ new Set();
|
|
if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
|
|
pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) {
|
|
UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutUnsafeLifecycles.add(fiber.type);
|
|
});
|
|
pendingUNSAFE_ComponentWillUpdateWarnings = [];
|
|
}
|
|
if (UNSAFE_componentWillMountUniqueNames.size > 0) {
|
|
var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
|
|
error("Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\nPlease update the following components: %s", sortedNames);
|
|
}
|
|
if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
|
|
var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
|
|
error("Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n\nPlease update the following components: %s", _sortedNames);
|
|
}
|
|
if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
|
|
var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
|
|
error("Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n\nPlease update the following components: %s", _sortedNames2);
|
|
}
|
|
if (componentWillMountUniqueNames.size > 0) {
|
|
var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
|
|
warn("componentWillMount has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames3);
|
|
}
|
|
if (componentWillReceivePropsUniqueNames.size > 0) {
|
|
var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
|
|
warn("componentWillReceiveProps has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames4);
|
|
}
|
|
if (componentWillUpdateUniqueNames.size > 0) {
|
|
var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
|
|
warn("componentWillUpdate has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames5);
|
|
}
|
|
};
|
|
var pendingLegacyContextWarning = /* @__PURE__ */ new Map();
|
|
var didWarnAboutLegacyContext = /* @__PURE__ */ new Set();
|
|
ReactStrictModeWarnings.recordLegacyContextWarning = function(fiber, instance) {
|
|
var strictRoot = findStrictRoot(fiber);
|
|
if (strictRoot === null) {
|
|
error("Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue.");
|
|
return;
|
|
}
|
|
if (didWarnAboutLegacyContext.has(fiber.type)) {
|
|
return;
|
|
}
|
|
var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
|
|
if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === "function") {
|
|
if (warningsForRoot === void 0) {
|
|
warningsForRoot = [];
|
|
pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
|
|
}
|
|
warningsForRoot.push(fiber);
|
|
}
|
|
};
|
|
ReactStrictModeWarnings.flushLegacyContextWarning = function() {
|
|
pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) {
|
|
if (fiberArray.length === 0) {
|
|
return;
|
|
}
|
|
var firstFiber = fiberArray[0];
|
|
var uniqueNames = /* @__PURE__ */ new Set();
|
|
fiberArray.forEach(function(fiber) {
|
|
uniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
|
|
didWarnAboutLegacyContext.add(fiber.type);
|
|
});
|
|
var sortedNames = setToSortedString(uniqueNames);
|
|
try {
|
|
setCurrentFiber(firstFiber);
|
|
error("Legacy context API has been detected within a strict-mode tree.\n\nThe old API will be supported in all 16.x releases, but applications using it should migrate to the new version.\n\nPlease update the following components: %s\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context", sortedNames);
|
|
} finally {
|
|
resetCurrentFiber();
|
|
}
|
|
});
|
|
};
|
|
ReactStrictModeWarnings.discardPendingWarnings = function() {
|
|
pendingComponentWillMountWarnings = [];
|
|
pendingUNSAFE_ComponentWillMountWarnings = [];
|
|
pendingComponentWillReceivePropsWarnings = [];
|
|
pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
|
|
pendingComponentWillUpdateWarnings = [];
|
|
pendingUNSAFE_ComponentWillUpdateWarnings = [];
|
|
pendingLegacyContextWarning = /* @__PURE__ */ new Map();
|
|
};
|
|
}
|
|
function resolveDefaultProps(Component, baseProps) {
|
|
if (Component && Component.defaultProps) {
|
|
var props = assign({}, baseProps);
|
|
var defaultProps = Component.defaultProps;
|
|
for (var propName in defaultProps) {
|
|
if (props[propName] === void 0) {
|
|
props[propName] = defaultProps[propName];
|
|
}
|
|
}
|
|
return props;
|
|
}
|
|
return baseProps;
|
|
}
|
|
var valueCursor = createCursor(null);
|
|
var rendererSigil;
|
|
{
|
|
rendererSigil = {};
|
|
}
|
|
var currentlyRenderingFiber = null;
|
|
var lastContextDependency = null;
|
|
var lastFullyObservedContext = null;
|
|
var isDisallowedContextReadInDEV = false;
|
|
function resetContextDependencies() {
|
|
currentlyRenderingFiber = null;
|
|
lastContextDependency = null;
|
|
lastFullyObservedContext = null;
|
|
{
|
|
isDisallowedContextReadInDEV = false;
|
|
}
|
|
}
|
|
function enterDisallowedContextReadInDEV() {
|
|
{
|
|
isDisallowedContextReadInDEV = true;
|
|
}
|
|
}
|
|
function exitDisallowedContextReadInDEV() {
|
|
{
|
|
isDisallowedContextReadInDEV = false;
|
|
}
|
|
}
|
|
function pushProvider(providerFiber, context, nextValue) {
|
|
{
|
|
push(valueCursor, context._currentValue, providerFiber);
|
|
context._currentValue = nextValue;
|
|
{
|
|
if (context._currentRenderer !== void 0 && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
|
|
error("Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.");
|
|
}
|
|
context._currentRenderer = rendererSigil;
|
|
}
|
|
}
|
|
}
|
|
function popProvider(context, providerFiber) {
|
|
var currentValue = valueCursor.current;
|
|
pop(valueCursor, providerFiber);
|
|
{
|
|
{
|
|
context._currentValue = currentValue;
|
|
}
|
|
}
|
|
}
|
|
function scheduleContextWorkOnParentPath(parent, renderLanes2, propagationRoot) {
|
|
var node = parent;
|
|
while (node !== null) {
|
|
var alternate = node.alternate;
|
|
if (!isSubsetOfLanes(node.childLanes, renderLanes2)) {
|
|
node.childLanes = mergeLanes(node.childLanes, renderLanes2);
|
|
if (alternate !== null) {
|
|
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes2);
|
|
}
|
|
} else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes2)) {
|
|
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes2);
|
|
}
|
|
if (node === propagationRoot) {
|
|
break;
|
|
}
|
|
node = node.return;
|
|
}
|
|
{
|
|
if (node !== propagationRoot) {
|
|
error("Expected to find the propagation root when scheduling context work. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
}
|
|
function propagateContextChange(workInProgress2, context, renderLanes2) {
|
|
{
|
|
propagateContextChange_eager(workInProgress2, context, renderLanes2);
|
|
}
|
|
}
|
|
function propagateContextChange_eager(workInProgress2, context, renderLanes2) {
|
|
var fiber = workInProgress2.child;
|
|
if (fiber !== null) {
|
|
fiber.return = workInProgress2;
|
|
}
|
|
while (fiber !== null) {
|
|
var nextFiber = void 0;
|
|
var list = fiber.dependencies;
|
|
if (list !== null) {
|
|
nextFiber = fiber.child;
|
|
var dependency = list.firstContext;
|
|
while (dependency !== null) {
|
|
if (dependency.context === context) {
|
|
if (fiber.tag === ClassComponent) {
|
|
var lane = pickArbitraryLane(renderLanes2);
|
|
var update = createUpdate(NoTimestamp, lane);
|
|
update.tag = ForceUpdate;
|
|
var updateQueue = fiber.updateQueue;
|
|
if (updateQueue === null)
|
|
;
|
|
else {
|
|
var sharedQueue = updateQueue.shared;
|
|
var pending = sharedQueue.pending;
|
|
if (pending === null) {
|
|
update.next = update;
|
|
} else {
|
|
update.next = pending.next;
|
|
pending.next = update;
|
|
}
|
|
sharedQueue.pending = update;
|
|
}
|
|
}
|
|
fiber.lanes = mergeLanes(fiber.lanes, renderLanes2);
|
|
var alternate = fiber.alternate;
|
|
if (alternate !== null) {
|
|
alternate.lanes = mergeLanes(alternate.lanes, renderLanes2);
|
|
}
|
|
scheduleContextWorkOnParentPath(fiber.return, renderLanes2, workInProgress2);
|
|
list.lanes = mergeLanes(list.lanes, renderLanes2);
|
|
break;
|
|
}
|
|
dependency = dependency.next;
|
|
}
|
|
} else if (fiber.tag === ContextProvider) {
|
|
nextFiber = fiber.type === workInProgress2.type ? null : fiber.child;
|
|
} else if (fiber.tag === DehydratedFragment) {
|
|
var parentSuspense = fiber.return;
|
|
if (parentSuspense === null) {
|
|
throw new Error("We just came from a parent so we must have had a parent. This is a bug in React.");
|
|
}
|
|
parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes2);
|
|
var _alternate = parentSuspense.alternate;
|
|
if (_alternate !== null) {
|
|
_alternate.lanes = mergeLanes(_alternate.lanes, renderLanes2);
|
|
}
|
|
scheduleContextWorkOnParentPath(parentSuspense, renderLanes2, workInProgress2);
|
|
nextFiber = fiber.sibling;
|
|
} else {
|
|
nextFiber = fiber.child;
|
|
}
|
|
if (nextFiber !== null) {
|
|
nextFiber.return = fiber;
|
|
} else {
|
|
nextFiber = fiber;
|
|
while (nextFiber !== null) {
|
|
if (nextFiber === workInProgress2) {
|
|
nextFiber = null;
|
|
break;
|
|
}
|
|
var sibling = nextFiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = nextFiber.return;
|
|
nextFiber = sibling;
|
|
break;
|
|
}
|
|
nextFiber = nextFiber.return;
|
|
}
|
|
}
|
|
fiber = nextFiber;
|
|
}
|
|
}
|
|
function prepareToReadContext(workInProgress2, renderLanes2) {
|
|
currentlyRenderingFiber = workInProgress2;
|
|
lastContextDependency = null;
|
|
lastFullyObservedContext = null;
|
|
var dependencies = workInProgress2.dependencies;
|
|
if (dependencies !== null) {
|
|
{
|
|
var firstContext = dependencies.firstContext;
|
|
if (firstContext !== null) {
|
|
if (includesSomeLane(dependencies.lanes, renderLanes2)) {
|
|
markWorkInProgressReceivedUpdate();
|
|
}
|
|
dependencies.firstContext = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function readContext(context) {
|
|
{
|
|
if (isDisallowedContextReadInDEV) {
|
|
error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
|
|
}
|
|
}
|
|
var value = context._currentValue;
|
|
if (lastFullyObservedContext === context)
|
|
;
|
|
else {
|
|
var contextItem = {
|
|
context,
|
|
memoizedValue: value,
|
|
next: null
|
|
};
|
|
if (lastContextDependency === null) {
|
|
if (currentlyRenderingFiber === null) {
|
|
throw new Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
|
|
}
|
|
lastContextDependency = contextItem;
|
|
currentlyRenderingFiber.dependencies = {
|
|
lanes: NoLanes,
|
|
firstContext: contextItem
|
|
};
|
|
} else {
|
|
lastContextDependency = lastContextDependency.next = contextItem;
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
var interleavedQueues = null;
|
|
function pushInterleavedQueue(queue) {
|
|
if (interleavedQueues === null) {
|
|
interleavedQueues = [queue];
|
|
} else {
|
|
interleavedQueues.push(queue);
|
|
}
|
|
}
|
|
function hasInterleavedUpdates() {
|
|
return interleavedQueues !== null;
|
|
}
|
|
function enqueueInterleavedUpdates() {
|
|
if (interleavedQueues !== null) {
|
|
for (var i = 0; i < interleavedQueues.length; i++) {
|
|
var queue = interleavedQueues[i];
|
|
var lastInterleavedUpdate = queue.interleaved;
|
|
if (lastInterleavedUpdate !== null) {
|
|
queue.interleaved = null;
|
|
var firstInterleavedUpdate = lastInterleavedUpdate.next;
|
|
var lastPendingUpdate = queue.pending;
|
|
if (lastPendingUpdate !== null) {
|
|
var firstPendingUpdate = lastPendingUpdate.next;
|
|
lastPendingUpdate.next = firstInterleavedUpdate;
|
|
lastInterleavedUpdate.next = firstPendingUpdate;
|
|
}
|
|
queue.pending = lastInterleavedUpdate;
|
|
}
|
|
}
|
|
interleavedQueues = null;
|
|
}
|
|
}
|
|
var UpdateState = 0;
|
|
var ReplaceState = 1;
|
|
var ForceUpdate = 2;
|
|
var CaptureUpdate = 3;
|
|
var hasForceUpdate = false;
|
|
var didWarnUpdateInsideUpdate;
|
|
var currentlyProcessingQueue;
|
|
{
|
|
didWarnUpdateInsideUpdate = false;
|
|
currentlyProcessingQueue = null;
|
|
}
|
|
function initializeUpdateQueue(fiber) {
|
|
var queue = {
|
|
baseState: fiber.memoizedState,
|
|
firstBaseUpdate: null,
|
|
lastBaseUpdate: null,
|
|
shared: {
|
|
pending: null,
|
|
interleaved: null,
|
|
lanes: NoLanes
|
|
},
|
|
effects: null
|
|
};
|
|
fiber.updateQueue = queue;
|
|
}
|
|
function cloneUpdateQueue(current2, workInProgress2) {
|
|
var queue = workInProgress2.updateQueue;
|
|
var currentQueue = current2.updateQueue;
|
|
if (queue === currentQueue) {
|
|
var clone = {
|
|
baseState: currentQueue.baseState,
|
|
firstBaseUpdate: currentQueue.firstBaseUpdate,
|
|
lastBaseUpdate: currentQueue.lastBaseUpdate,
|
|
shared: currentQueue.shared,
|
|
effects: currentQueue.effects
|
|
};
|
|
workInProgress2.updateQueue = clone;
|
|
}
|
|
}
|
|
function createUpdate(eventTime, lane) {
|
|
var update = {
|
|
eventTime,
|
|
lane,
|
|
tag: UpdateState,
|
|
payload: null,
|
|
callback: null,
|
|
next: null
|
|
};
|
|
return update;
|
|
}
|
|
function enqueueUpdate(fiber, update, lane) {
|
|
var updateQueue = fiber.updateQueue;
|
|
if (updateQueue === null) {
|
|
return;
|
|
}
|
|
var sharedQueue = updateQueue.shared;
|
|
if (isInterleavedUpdate(fiber)) {
|
|
var interleaved = sharedQueue.interleaved;
|
|
if (interleaved === null) {
|
|
update.next = update;
|
|
pushInterleavedQueue(sharedQueue);
|
|
} else {
|
|
update.next = interleaved.next;
|
|
interleaved.next = update;
|
|
}
|
|
sharedQueue.interleaved = update;
|
|
} else {
|
|
var pending = sharedQueue.pending;
|
|
if (pending === null) {
|
|
update.next = update;
|
|
} else {
|
|
update.next = pending.next;
|
|
pending.next = update;
|
|
}
|
|
sharedQueue.pending = update;
|
|
}
|
|
{
|
|
if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
|
|
error("An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback.");
|
|
didWarnUpdateInsideUpdate = true;
|
|
}
|
|
}
|
|
}
|
|
function entangleTransitions(root3, fiber, lane) {
|
|
var updateQueue = fiber.updateQueue;
|
|
if (updateQueue === null) {
|
|
return;
|
|
}
|
|
var sharedQueue = updateQueue.shared;
|
|
if (isTransitionLane(lane)) {
|
|
var queueLanes = sharedQueue.lanes;
|
|
queueLanes = intersectLanes(queueLanes, root3.pendingLanes);
|
|
var newQueueLanes = mergeLanes(queueLanes, lane);
|
|
sharedQueue.lanes = newQueueLanes;
|
|
markRootEntangled(root3, newQueueLanes);
|
|
}
|
|
}
|
|
function enqueueCapturedUpdate(workInProgress2, capturedUpdate) {
|
|
var queue = workInProgress2.updateQueue;
|
|
var current2 = workInProgress2.alternate;
|
|
if (current2 !== null) {
|
|
var currentQueue = current2.updateQueue;
|
|
if (queue === currentQueue) {
|
|
var newFirst = null;
|
|
var newLast = null;
|
|
var firstBaseUpdate = queue.firstBaseUpdate;
|
|
if (firstBaseUpdate !== null) {
|
|
var update = firstBaseUpdate;
|
|
do {
|
|
var clone = {
|
|
eventTime: update.eventTime,
|
|
lane: update.lane,
|
|
tag: update.tag,
|
|
payload: update.payload,
|
|
callback: update.callback,
|
|
next: null
|
|
};
|
|
if (newLast === null) {
|
|
newFirst = newLast = clone;
|
|
} else {
|
|
newLast.next = clone;
|
|
newLast = clone;
|
|
}
|
|
update = update.next;
|
|
} while (update !== null);
|
|
if (newLast === null) {
|
|
newFirst = newLast = capturedUpdate;
|
|
} else {
|
|
newLast.next = capturedUpdate;
|
|
newLast = capturedUpdate;
|
|
}
|
|
} else {
|
|
newFirst = newLast = capturedUpdate;
|
|
}
|
|
queue = {
|
|
baseState: currentQueue.baseState,
|
|
firstBaseUpdate: newFirst,
|
|
lastBaseUpdate: newLast,
|
|
shared: currentQueue.shared,
|
|
effects: currentQueue.effects
|
|
};
|
|
workInProgress2.updateQueue = queue;
|
|
return;
|
|
}
|
|
}
|
|
var lastBaseUpdate = queue.lastBaseUpdate;
|
|
if (lastBaseUpdate === null) {
|
|
queue.firstBaseUpdate = capturedUpdate;
|
|
} else {
|
|
lastBaseUpdate.next = capturedUpdate;
|
|
}
|
|
queue.lastBaseUpdate = capturedUpdate;
|
|
}
|
|
function getStateFromUpdate(workInProgress2, queue, update, prevState, nextProps, instance) {
|
|
switch (update.tag) {
|
|
case ReplaceState: {
|
|
var payload = update.payload;
|
|
if (typeof payload === "function") {
|
|
{
|
|
enterDisallowedContextReadInDEV();
|
|
}
|
|
var nextState = payload.call(instance, prevState, nextProps);
|
|
{
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
payload.call(instance, prevState, nextProps);
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
exitDisallowedContextReadInDEV();
|
|
}
|
|
return nextState;
|
|
}
|
|
return payload;
|
|
}
|
|
case CaptureUpdate: {
|
|
workInProgress2.flags = workInProgress2.flags & ~ShouldCapture | DidCapture;
|
|
}
|
|
case UpdateState: {
|
|
var _payload = update.payload;
|
|
var partialState;
|
|
if (typeof _payload === "function") {
|
|
{
|
|
enterDisallowedContextReadInDEV();
|
|
}
|
|
partialState = _payload.call(instance, prevState, nextProps);
|
|
{
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
_payload.call(instance, prevState, nextProps);
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
exitDisallowedContextReadInDEV();
|
|
}
|
|
} else {
|
|
partialState = _payload;
|
|
}
|
|
if (partialState === null || partialState === void 0) {
|
|
return prevState;
|
|
}
|
|
return assign({}, prevState, partialState);
|
|
}
|
|
case ForceUpdate: {
|
|
hasForceUpdate = true;
|
|
return prevState;
|
|
}
|
|
}
|
|
return prevState;
|
|
}
|
|
function processUpdateQueue(workInProgress2, props, instance, renderLanes2) {
|
|
var queue = workInProgress2.updateQueue;
|
|
hasForceUpdate = false;
|
|
{
|
|
currentlyProcessingQueue = queue.shared;
|
|
}
|
|
var firstBaseUpdate = queue.firstBaseUpdate;
|
|
var lastBaseUpdate = queue.lastBaseUpdate;
|
|
var pendingQueue = queue.shared.pending;
|
|
if (pendingQueue !== null) {
|
|
queue.shared.pending = null;
|
|
var lastPendingUpdate = pendingQueue;
|
|
var firstPendingUpdate = lastPendingUpdate.next;
|
|
lastPendingUpdate.next = null;
|
|
if (lastBaseUpdate === null) {
|
|
firstBaseUpdate = firstPendingUpdate;
|
|
} else {
|
|
lastBaseUpdate.next = firstPendingUpdate;
|
|
}
|
|
lastBaseUpdate = lastPendingUpdate;
|
|
var current2 = workInProgress2.alternate;
|
|
if (current2 !== null) {
|
|
var currentQueue = current2.updateQueue;
|
|
var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
|
|
if (currentLastBaseUpdate !== lastBaseUpdate) {
|
|
if (currentLastBaseUpdate === null) {
|
|
currentQueue.firstBaseUpdate = firstPendingUpdate;
|
|
} else {
|
|
currentLastBaseUpdate.next = firstPendingUpdate;
|
|
}
|
|
currentQueue.lastBaseUpdate = lastPendingUpdate;
|
|
}
|
|
}
|
|
}
|
|
if (firstBaseUpdate !== null) {
|
|
var newState = queue.baseState;
|
|
var newLanes = NoLanes;
|
|
var newBaseState = null;
|
|
var newFirstBaseUpdate = null;
|
|
var newLastBaseUpdate = null;
|
|
var update = firstBaseUpdate;
|
|
do {
|
|
var updateLane = update.lane;
|
|
var updateEventTime = update.eventTime;
|
|
if (!isSubsetOfLanes(renderLanes2, updateLane)) {
|
|
var clone = {
|
|
eventTime: updateEventTime,
|
|
lane: updateLane,
|
|
tag: update.tag,
|
|
payload: update.payload,
|
|
callback: update.callback,
|
|
next: null
|
|
};
|
|
if (newLastBaseUpdate === null) {
|
|
newFirstBaseUpdate = newLastBaseUpdate = clone;
|
|
newBaseState = newState;
|
|
} else {
|
|
newLastBaseUpdate = newLastBaseUpdate.next = clone;
|
|
}
|
|
newLanes = mergeLanes(newLanes, updateLane);
|
|
} else {
|
|
if (newLastBaseUpdate !== null) {
|
|
var _clone = {
|
|
eventTime: updateEventTime,
|
|
lane: NoLane,
|
|
tag: update.tag,
|
|
payload: update.payload,
|
|
callback: update.callback,
|
|
next: null
|
|
};
|
|
newLastBaseUpdate = newLastBaseUpdate.next = _clone;
|
|
}
|
|
newState = getStateFromUpdate(workInProgress2, queue, update, newState, props, instance);
|
|
var callback = update.callback;
|
|
if (callback !== null && update.lane !== NoLane) {
|
|
workInProgress2.flags |= Callback;
|
|
var effects = queue.effects;
|
|
if (effects === null) {
|
|
queue.effects = [update];
|
|
} else {
|
|
effects.push(update);
|
|
}
|
|
}
|
|
}
|
|
update = update.next;
|
|
if (update === null) {
|
|
pendingQueue = queue.shared.pending;
|
|
if (pendingQueue === null) {
|
|
break;
|
|
} else {
|
|
var _lastPendingUpdate = pendingQueue;
|
|
var _firstPendingUpdate = _lastPendingUpdate.next;
|
|
_lastPendingUpdate.next = null;
|
|
update = _firstPendingUpdate;
|
|
queue.lastBaseUpdate = _lastPendingUpdate;
|
|
queue.shared.pending = null;
|
|
}
|
|
}
|
|
} while (true);
|
|
if (newLastBaseUpdate === null) {
|
|
newBaseState = newState;
|
|
}
|
|
queue.baseState = newBaseState;
|
|
queue.firstBaseUpdate = newFirstBaseUpdate;
|
|
queue.lastBaseUpdate = newLastBaseUpdate;
|
|
var lastInterleaved = queue.shared.interleaved;
|
|
if (lastInterleaved !== null) {
|
|
var interleaved = lastInterleaved;
|
|
do {
|
|
newLanes = mergeLanes(newLanes, interleaved.lane);
|
|
interleaved = interleaved.next;
|
|
} while (interleaved !== lastInterleaved);
|
|
} else if (firstBaseUpdate === null) {
|
|
queue.shared.lanes = NoLanes;
|
|
}
|
|
markSkippedUpdateLanes(newLanes);
|
|
workInProgress2.lanes = newLanes;
|
|
workInProgress2.memoizedState = newState;
|
|
}
|
|
{
|
|
currentlyProcessingQueue = null;
|
|
}
|
|
}
|
|
function callCallback(callback, context) {
|
|
if (typeof callback !== "function") {
|
|
throw new Error("Invalid argument passed as callback. Expected a function. Instead " + ("received: " + callback));
|
|
}
|
|
callback.call(context);
|
|
}
|
|
function resetHasForceUpdateBeforeProcessing() {
|
|
hasForceUpdate = false;
|
|
}
|
|
function checkHasForceUpdateAfterProcessing() {
|
|
return hasForceUpdate;
|
|
}
|
|
function commitUpdateQueue(finishedWork, finishedQueue, instance) {
|
|
var effects = finishedQueue.effects;
|
|
finishedQueue.effects = null;
|
|
if (effects !== null) {
|
|
for (var i = 0; i < effects.length; i++) {
|
|
var effect = effects[i];
|
|
var callback = effect.callback;
|
|
if (callback !== null) {
|
|
effect.callback = null;
|
|
callCallback(callback, instance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var fakeInternalInstance = {};
|
|
var emptyRefsObject = new React4.Component().refs;
|
|
var didWarnAboutStateAssignmentForComponent;
|
|
var didWarnAboutUninitializedState;
|
|
var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
|
|
var didWarnAboutLegacyLifecyclesAndDerivedState;
|
|
var didWarnAboutUndefinedDerivedState;
|
|
var warnOnUndefinedDerivedState;
|
|
var warnOnInvalidCallback;
|
|
var didWarnAboutDirectlyAssigningPropsToState;
|
|
var didWarnAboutContextTypeAndContextTypes;
|
|
var didWarnAboutInvalidateContextType;
|
|
{
|
|
didWarnAboutStateAssignmentForComponent = /* @__PURE__ */ new Set();
|
|
didWarnAboutUninitializedState = /* @__PURE__ */ new Set();
|
|
didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = /* @__PURE__ */ new Set();
|
|
didWarnAboutLegacyLifecyclesAndDerivedState = /* @__PURE__ */ new Set();
|
|
didWarnAboutDirectlyAssigningPropsToState = /* @__PURE__ */ new Set();
|
|
didWarnAboutUndefinedDerivedState = /* @__PURE__ */ new Set();
|
|
didWarnAboutContextTypeAndContextTypes = /* @__PURE__ */ new Set();
|
|
didWarnAboutInvalidateContextType = /* @__PURE__ */ new Set();
|
|
var didWarnOnInvalidCallback = /* @__PURE__ */ new Set();
|
|
warnOnInvalidCallback = function(callback, callerName) {
|
|
if (callback === null || typeof callback === "function") {
|
|
return;
|
|
}
|
|
var key = callerName + "_" + callback;
|
|
if (!didWarnOnInvalidCallback.has(key)) {
|
|
didWarnOnInvalidCallback.add(key);
|
|
error("%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callerName, callback);
|
|
}
|
|
};
|
|
warnOnUndefinedDerivedState = function(type, partialState) {
|
|
if (partialState === void 0) {
|
|
var componentName = getComponentNameFromType(type) || "Component";
|
|
if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
|
|
didWarnAboutUndefinedDerivedState.add(componentName);
|
|
error("%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.", componentName);
|
|
}
|
|
}
|
|
};
|
|
Object.defineProperty(fakeInternalInstance, "_processChildContext", {
|
|
enumerable: false,
|
|
value: function() {
|
|
throw new Error("_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).");
|
|
}
|
|
});
|
|
Object.freeze(fakeInternalInstance);
|
|
}
|
|
function applyDerivedStateFromProps(workInProgress2, ctor, getDerivedStateFromProps, nextProps) {
|
|
var prevState = workInProgress2.memoizedState;
|
|
var partialState = getDerivedStateFromProps(nextProps, prevState);
|
|
{
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
partialState = getDerivedStateFromProps(nextProps, prevState);
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
warnOnUndefinedDerivedState(ctor, partialState);
|
|
}
|
|
var memoizedState = partialState === null || partialState === void 0 ? prevState : assign({}, prevState, partialState);
|
|
workInProgress2.memoizedState = memoizedState;
|
|
if (workInProgress2.lanes === NoLanes) {
|
|
var updateQueue = workInProgress2.updateQueue;
|
|
updateQueue.baseState = memoizedState;
|
|
}
|
|
}
|
|
var classComponentUpdater = {
|
|
isMounted,
|
|
enqueueSetState: function(inst, payload, callback) {
|
|
var fiber = get(inst);
|
|
var eventTime = requestEventTime();
|
|
var lane = requestUpdateLane(fiber);
|
|
var update = createUpdate(eventTime, lane);
|
|
update.payload = payload;
|
|
if (callback !== void 0 && callback !== null) {
|
|
{
|
|
warnOnInvalidCallback(callback, "setState");
|
|
}
|
|
update.callback = callback;
|
|
}
|
|
enqueueUpdate(fiber, update);
|
|
var root3 = scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
if (root3 !== null) {
|
|
entangleTransitions(root3, fiber, lane);
|
|
}
|
|
{
|
|
markStateUpdateScheduled(fiber, lane);
|
|
}
|
|
},
|
|
enqueueReplaceState: function(inst, payload, callback) {
|
|
var fiber = get(inst);
|
|
var eventTime = requestEventTime();
|
|
var lane = requestUpdateLane(fiber);
|
|
var update = createUpdate(eventTime, lane);
|
|
update.tag = ReplaceState;
|
|
update.payload = payload;
|
|
if (callback !== void 0 && callback !== null) {
|
|
{
|
|
warnOnInvalidCallback(callback, "replaceState");
|
|
}
|
|
update.callback = callback;
|
|
}
|
|
enqueueUpdate(fiber, update);
|
|
var root3 = scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
if (root3 !== null) {
|
|
entangleTransitions(root3, fiber, lane);
|
|
}
|
|
{
|
|
markStateUpdateScheduled(fiber, lane);
|
|
}
|
|
},
|
|
enqueueForceUpdate: function(inst, callback) {
|
|
var fiber = get(inst);
|
|
var eventTime = requestEventTime();
|
|
var lane = requestUpdateLane(fiber);
|
|
var update = createUpdate(eventTime, lane);
|
|
update.tag = ForceUpdate;
|
|
if (callback !== void 0 && callback !== null) {
|
|
{
|
|
warnOnInvalidCallback(callback, "forceUpdate");
|
|
}
|
|
update.callback = callback;
|
|
}
|
|
enqueueUpdate(fiber, update);
|
|
var root3 = scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
if (root3 !== null) {
|
|
entangleTransitions(root3, fiber, lane);
|
|
}
|
|
{
|
|
markForceUpdateScheduled(fiber, lane);
|
|
}
|
|
}
|
|
};
|
|
function checkShouldComponentUpdate(workInProgress2, ctor, oldProps, newProps, oldState, newState, nextContext) {
|
|
var instance = workInProgress2.stateNode;
|
|
if (typeof instance.shouldComponentUpdate === "function") {
|
|
var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
|
|
{
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
if (shouldUpdate === void 0) {
|
|
error("%s.shouldComponentUpdate(): Returned undefined instead of a boolean value. Make sure to return true or false.", getComponentNameFromType(ctor) || "Component");
|
|
}
|
|
}
|
|
return shouldUpdate;
|
|
}
|
|
if (ctor.prototype && ctor.prototype.isPureReactComponent) {
|
|
return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
|
|
}
|
|
return true;
|
|
}
|
|
function checkClassInstance(workInProgress2, ctor, newProps) {
|
|
var instance = workInProgress2.stateNode;
|
|
{
|
|
var name = getComponentNameFromType(ctor) || "Component";
|
|
var renderPresent = instance.render;
|
|
if (!renderPresent) {
|
|
if (ctor.prototype && typeof ctor.prototype.render === "function") {
|
|
error("%s(...): No `render` method found on the returned component instance: did you accidentally return an object from the constructor?", name);
|
|
} else {
|
|
error("%s(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.", name);
|
|
}
|
|
}
|
|
if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
|
|
error("getInitialState was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?", name);
|
|
}
|
|
if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
|
|
error("getDefaultProps was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Use a static property to define defaultProps instead.", name);
|
|
}
|
|
if (instance.propTypes) {
|
|
error("propTypes was defined as an instance property on %s. Use a static property to define propTypes instead.", name);
|
|
}
|
|
if (instance.contextType) {
|
|
error("contextType was defined as an instance property on %s. Use a static property to define contextType instead.", name);
|
|
}
|
|
{
|
|
if (instance.contextTypes) {
|
|
error("contextTypes was defined as an instance property on %s. Use a static property to define contextTypes instead.", name);
|
|
}
|
|
if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
|
|
didWarnAboutContextTypeAndContextTypes.add(ctor);
|
|
error("%s declares both contextTypes and contextType static properties. The legacy contextTypes property will be ignored.", name);
|
|
}
|
|
}
|
|
if (typeof instance.componentShouldUpdate === "function") {
|
|
error("%s has a method called componentShouldUpdate(). Did you mean shouldComponentUpdate()? The name is phrased as a question because the function is expected to return a value.", name);
|
|
}
|
|
if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined") {
|
|
error("%s has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.", getComponentNameFromType(ctor) || "A pure component");
|
|
}
|
|
if (typeof instance.componentDidUnmount === "function") {
|
|
error("%s has a method called componentDidUnmount(). But there is no such lifecycle method. Did you mean componentWillUnmount()?", name);
|
|
}
|
|
if (typeof instance.componentDidReceiveProps === "function") {
|
|
error("%s has a method called componentDidReceiveProps(). But there is no such lifecycle method. If you meant to update the state in response to changing props, use componentWillReceiveProps(). If you meant to fetch data or run side-effects or mutations after React has updated the UI, use componentDidUpdate().", name);
|
|
}
|
|
if (typeof instance.componentWillRecieveProps === "function") {
|
|
error("%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", name);
|
|
}
|
|
if (typeof instance.UNSAFE_componentWillRecieveProps === "function") {
|
|
error("%s has a method called UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", name);
|
|
}
|
|
var hasMutatedProps = instance.props !== newProps;
|
|
if (instance.props !== void 0 && hasMutatedProps) {
|
|
error("%s(...): When calling super() in `%s`, make sure to pass up the same props that your component's constructor was passed.", name, name);
|
|
}
|
|
if (instance.defaultProps) {
|
|
error("Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", name, name);
|
|
}
|
|
if (typeof instance.getSnapshotBeforeUpdate === "function" && typeof instance.componentDidUpdate !== "function" && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
|
|
didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
|
|
error("%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.", getComponentNameFromType(ctor));
|
|
}
|
|
if (typeof instance.getDerivedStateFromProps === "function") {
|
|
error("%s: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.", name);
|
|
}
|
|
if (typeof instance.getDerivedStateFromError === "function") {
|
|
error("%s: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.", name);
|
|
}
|
|
if (typeof ctor.getSnapshotBeforeUpdate === "function") {
|
|
error("%s: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.", name);
|
|
}
|
|
var _state = instance.state;
|
|
if (_state && (typeof _state !== "object" || isArray(_state))) {
|
|
error("%s.state: must be set to an object or null", name);
|
|
}
|
|
if (typeof instance.getChildContext === "function" && typeof ctor.childContextTypes !== "object") {
|
|
error("%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().", name);
|
|
}
|
|
}
|
|
}
|
|
function adoptClassInstance(workInProgress2, instance) {
|
|
instance.updater = classComponentUpdater;
|
|
workInProgress2.stateNode = instance;
|
|
set(instance, workInProgress2);
|
|
{
|
|
instance._reactInternalInstance = fakeInternalInstance;
|
|
}
|
|
}
|
|
function constructClassInstance(workInProgress2, ctor, props) {
|
|
var isLegacyContextConsumer = false;
|
|
var unmaskedContext = emptyContextObject;
|
|
var context = emptyContextObject;
|
|
var contextType = ctor.contextType;
|
|
{
|
|
if ("contextType" in ctor) {
|
|
var isValid = contextType === null || contextType !== void 0 && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === void 0;
|
|
if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
|
|
didWarnAboutInvalidateContextType.add(ctor);
|
|
var addendum = "";
|
|
if (contextType === void 0) {
|
|
addendum = " However, it is set to undefined. This can be caused by a typo or by mixing up named and default imports. This can also happen due to a circular dependency, so try moving the createContext() call to a separate file.";
|
|
} else if (typeof contextType !== "object") {
|
|
addendum = " However, it is set to a " + typeof contextType + ".";
|
|
} else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
|
|
addendum = " Did you accidentally pass the Context.Provider instead?";
|
|
} else if (contextType._context !== void 0) {
|
|
addendum = " Did you accidentally pass the Context.Consumer instead?";
|
|
} else {
|
|
addendum = " However, it is set to an object with keys {" + Object.keys(contextType).join(", ") + "}.";
|
|
}
|
|
error("%s defines an invalid contextType. contextType should point to the Context object returned by React.createContext().%s", getComponentNameFromType(ctor) || "Component", addendum);
|
|
}
|
|
}
|
|
}
|
|
if (typeof contextType === "object" && contextType !== null) {
|
|
context = readContext(contextType);
|
|
} else {
|
|
unmaskedContext = getUnmaskedContext(workInProgress2, ctor, true);
|
|
var contextTypes = ctor.contextTypes;
|
|
isLegacyContextConsumer = contextTypes !== null && contextTypes !== void 0;
|
|
context = isLegacyContextConsumer ? getMaskedContext(workInProgress2, unmaskedContext) : emptyContextObject;
|
|
}
|
|
var instance = new ctor(props, context);
|
|
{
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
instance = new ctor(props, context);
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
}
|
|
var state = workInProgress2.memoizedState = instance.state !== null && instance.state !== void 0 ? instance.state : null;
|
|
adoptClassInstance(workInProgress2, instance);
|
|
{
|
|
if (typeof ctor.getDerivedStateFromProps === "function" && state === null) {
|
|
var componentName = getComponentNameFromType(ctor) || "Component";
|
|
if (!didWarnAboutUninitializedState.has(componentName)) {
|
|
didWarnAboutUninitializedState.add(componentName);
|
|
error("`%s` uses `getDerivedStateFromProps` but its initial state is %s. This is not recommended. Instead, define the initial state by assigning an object to `this.state` in the constructor of `%s`. This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", componentName, instance.state === null ? "null" : "undefined", componentName);
|
|
}
|
|
}
|
|
if (typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function") {
|
|
var foundWillMountName = null;
|
|
var foundWillReceivePropsName = null;
|
|
var foundWillUpdateName = null;
|
|
if (typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true) {
|
|
foundWillMountName = "componentWillMount";
|
|
} else if (typeof instance.UNSAFE_componentWillMount === "function") {
|
|
foundWillMountName = "UNSAFE_componentWillMount";
|
|
}
|
|
if (typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
|
|
foundWillReceivePropsName = "componentWillReceiveProps";
|
|
} else if (typeof instance.UNSAFE_componentWillReceiveProps === "function") {
|
|
foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps";
|
|
}
|
|
if (typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
|
|
foundWillUpdateName = "componentWillUpdate";
|
|
} else if (typeof instance.UNSAFE_componentWillUpdate === "function") {
|
|
foundWillUpdateName = "UNSAFE_componentWillUpdate";
|
|
}
|
|
if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
|
|
var _componentName = getComponentNameFromType(ctor) || "Component";
|
|
var newApiName = typeof ctor.getDerivedStateFromProps === "function" ? "getDerivedStateFromProps()" : "getSnapshotBeforeUpdate()";
|
|
if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
|
|
didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
|
|
error("Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://reactjs.org/link/unsafe-component-lifecycles", _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : "", foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : "", foundWillUpdateName !== null ? "\n " + foundWillUpdateName : "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (isLegacyContextConsumer) {
|
|
cacheContext(workInProgress2, unmaskedContext, context);
|
|
}
|
|
return instance;
|
|
}
|
|
function callComponentWillMount(workInProgress2, instance) {
|
|
var oldState = instance.state;
|
|
if (typeof instance.componentWillMount === "function") {
|
|
instance.componentWillMount();
|
|
}
|
|
if (typeof instance.UNSAFE_componentWillMount === "function") {
|
|
instance.UNSAFE_componentWillMount();
|
|
}
|
|
if (oldState !== instance.state) {
|
|
{
|
|
error("%s.componentWillMount(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", getComponentNameFromFiber(workInProgress2) || "Component");
|
|
}
|
|
classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
|
|
}
|
|
}
|
|
function callComponentWillReceiveProps(workInProgress2, instance, newProps, nextContext) {
|
|
var oldState = instance.state;
|
|
if (typeof instance.componentWillReceiveProps === "function") {
|
|
instance.componentWillReceiveProps(newProps, nextContext);
|
|
}
|
|
if (typeof instance.UNSAFE_componentWillReceiveProps === "function") {
|
|
instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
|
|
}
|
|
if (instance.state !== oldState) {
|
|
{
|
|
var componentName = getComponentNameFromFiber(workInProgress2) || "Component";
|
|
if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
|
|
didWarnAboutStateAssignmentForComponent.add(componentName);
|
|
error("%s.componentWillReceiveProps(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", componentName);
|
|
}
|
|
}
|
|
classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
|
|
}
|
|
}
|
|
function mountClassInstance(workInProgress2, ctor, newProps, renderLanes2) {
|
|
{
|
|
checkClassInstance(workInProgress2, ctor, newProps);
|
|
}
|
|
var instance = workInProgress2.stateNode;
|
|
instance.props = newProps;
|
|
instance.state = workInProgress2.memoizedState;
|
|
instance.refs = emptyRefsObject;
|
|
initializeUpdateQueue(workInProgress2);
|
|
var contextType = ctor.contextType;
|
|
if (typeof contextType === "object" && contextType !== null) {
|
|
instance.context = readContext(contextType);
|
|
} else {
|
|
var unmaskedContext = getUnmaskedContext(workInProgress2, ctor, true);
|
|
instance.context = getMaskedContext(workInProgress2, unmaskedContext);
|
|
}
|
|
{
|
|
if (instance.state === newProps) {
|
|
var componentName = getComponentNameFromType(ctor) || "Component";
|
|
if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
|
|
didWarnAboutDirectlyAssigningPropsToState.add(componentName);
|
|
error("%s: It is not recommended to assign props directly to state because updates to props won't be reflected in state. In most cases, it is better to use props directly.", componentName);
|
|
}
|
|
}
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress2, instance);
|
|
}
|
|
{
|
|
ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress2, instance);
|
|
}
|
|
}
|
|
instance.state = workInProgress2.memoizedState;
|
|
var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
|
|
if (typeof getDerivedStateFromProps === "function") {
|
|
applyDerivedStateFromProps(workInProgress2, ctor, getDerivedStateFromProps, newProps);
|
|
instance.state = workInProgress2.memoizedState;
|
|
}
|
|
if (typeof ctor.getDerivedStateFromProps !== "function" && typeof instance.getSnapshotBeforeUpdate !== "function" && (typeof instance.UNSAFE_componentWillMount === "function" || typeof instance.componentWillMount === "function")) {
|
|
callComponentWillMount(workInProgress2, instance);
|
|
processUpdateQueue(workInProgress2, newProps, instance, renderLanes2);
|
|
instance.state = workInProgress2.memoizedState;
|
|
}
|
|
if (typeof instance.componentDidMount === "function") {
|
|
var fiberFlags = Update;
|
|
{
|
|
fiberFlags |= LayoutStatic;
|
|
}
|
|
if ((workInProgress2.mode & StrictEffectsMode) !== NoMode) {
|
|
fiberFlags |= MountLayoutDev;
|
|
}
|
|
workInProgress2.flags |= fiberFlags;
|
|
}
|
|
}
|
|
function resumeMountClassInstance(workInProgress2, ctor, newProps, renderLanes2) {
|
|
var instance = workInProgress2.stateNode;
|
|
var oldProps = workInProgress2.memoizedProps;
|
|
instance.props = oldProps;
|
|
var oldContext = instance.context;
|
|
var contextType = ctor.contextType;
|
|
var nextContext = emptyContextObject;
|
|
if (typeof contextType === "object" && contextType !== null) {
|
|
nextContext = readContext(contextType);
|
|
} else {
|
|
var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress2, ctor, true);
|
|
nextContext = getMaskedContext(workInProgress2, nextLegacyUnmaskedContext);
|
|
}
|
|
var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
|
|
var hasNewLifecycles = typeof getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function";
|
|
if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || typeof instance.componentWillReceiveProps === "function")) {
|
|
if (oldProps !== newProps || oldContext !== nextContext) {
|
|
callComponentWillReceiveProps(workInProgress2, instance, newProps, nextContext);
|
|
}
|
|
}
|
|
resetHasForceUpdateBeforeProcessing();
|
|
var oldState = workInProgress2.memoizedState;
|
|
var newState = instance.state = oldState;
|
|
processUpdateQueue(workInProgress2, newProps, instance, renderLanes2);
|
|
newState = workInProgress2.memoizedState;
|
|
if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
|
|
if (typeof instance.componentDidMount === "function") {
|
|
var fiberFlags = Update;
|
|
{
|
|
fiberFlags |= LayoutStatic;
|
|
}
|
|
if ((workInProgress2.mode & StrictEffectsMode) !== NoMode) {
|
|
fiberFlags |= MountLayoutDev;
|
|
}
|
|
workInProgress2.flags |= fiberFlags;
|
|
}
|
|
return false;
|
|
}
|
|
if (typeof getDerivedStateFromProps === "function") {
|
|
applyDerivedStateFromProps(workInProgress2, ctor, getDerivedStateFromProps, newProps);
|
|
newState = workInProgress2.memoizedState;
|
|
}
|
|
var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress2, ctor, oldProps, newProps, oldState, newState, nextContext);
|
|
if (shouldUpdate) {
|
|
if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === "function" || typeof instance.componentWillMount === "function")) {
|
|
if (typeof instance.componentWillMount === "function") {
|
|
instance.componentWillMount();
|
|
}
|
|
if (typeof instance.UNSAFE_componentWillMount === "function") {
|
|
instance.UNSAFE_componentWillMount();
|
|
}
|
|
}
|
|
if (typeof instance.componentDidMount === "function") {
|
|
var _fiberFlags = Update;
|
|
{
|
|
_fiberFlags |= LayoutStatic;
|
|
}
|
|
if ((workInProgress2.mode & StrictEffectsMode) !== NoMode) {
|
|
_fiberFlags |= MountLayoutDev;
|
|
}
|
|
workInProgress2.flags |= _fiberFlags;
|
|
}
|
|
} else {
|
|
if (typeof instance.componentDidMount === "function") {
|
|
var _fiberFlags2 = Update;
|
|
{
|
|
_fiberFlags2 |= LayoutStatic;
|
|
}
|
|
if ((workInProgress2.mode & StrictEffectsMode) !== NoMode) {
|
|
_fiberFlags2 |= MountLayoutDev;
|
|
}
|
|
workInProgress2.flags |= _fiberFlags2;
|
|
}
|
|
workInProgress2.memoizedProps = newProps;
|
|
workInProgress2.memoizedState = newState;
|
|
}
|
|
instance.props = newProps;
|
|
instance.state = newState;
|
|
instance.context = nextContext;
|
|
return shouldUpdate;
|
|
}
|
|
function updateClassInstance(current2, workInProgress2, ctor, newProps, renderLanes2) {
|
|
var instance = workInProgress2.stateNode;
|
|
cloneUpdateQueue(current2, workInProgress2);
|
|
var unresolvedOldProps = workInProgress2.memoizedProps;
|
|
var oldProps = workInProgress2.type === workInProgress2.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress2.type, unresolvedOldProps);
|
|
instance.props = oldProps;
|
|
var unresolvedNewProps = workInProgress2.pendingProps;
|
|
var oldContext = instance.context;
|
|
var contextType = ctor.contextType;
|
|
var nextContext = emptyContextObject;
|
|
if (typeof contextType === "object" && contextType !== null) {
|
|
nextContext = readContext(contextType);
|
|
} else {
|
|
var nextUnmaskedContext = getUnmaskedContext(workInProgress2, ctor, true);
|
|
nextContext = getMaskedContext(workInProgress2, nextUnmaskedContext);
|
|
}
|
|
var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
|
|
var hasNewLifecycles = typeof getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function";
|
|
if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || typeof instance.componentWillReceiveProps === "function")) {
|
|
if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
|
|
callComponentWillReceiveProps(workInProgress2, instance, newProps, nextContext);
|
|
}
|
|
}
|
|
resetHasForceUpdateBeforeProcessing();
|
|
var oldState = workInProgress2.memoizedState;
|
|
var newState = instance.state = oldState;
|
|
processUpdateQueue(workInProgress2, newProps, instance, renderLanes2);
|
|
newState = workInProgress2.memoizedState;
|
|
if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !enableLazyContextPropagation) {
|
|
if (typeof instance.componentDidUpdate === "function") {
|
|
if (unresolvedOldProps !== current2.memoizedProps || oldState !== current2.memoizedState) {
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
}
|
|
if (typeof instance.getSnapshotBeforeUpdate === "function") {
|
|
if (unresolvedOldProps !== current2.memoizedProps || oldState !== current2.memoizedState) {
|
|
workInProgress2.flags |= Snapshot;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
if (typeof getDerivedStateFromProps === "function") {
|
|
applyDerivedStateFromProps(workInProgress2, ctor, getDerivedStateFromProps, newProps);
|
|
newState = workInProgress2.memoizedState;
|
|
}
|
|
var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress2, ctor, oldProps, newProps, oldState, newState, nextContext) || enableLazyContextPropagation;
|
|
if (shouldUpdate) {
|
|
if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === "function" || typeof instance.componentWillUpdate === "function")) {
|
|
if (typeof instance.componentWillUpdate === "function") {
|
|
instance.componentWillUpdate(newProps, newState, nextContext);
|
|
}
|
|
if (typeof instance.UNSAFE_componentWillUpdate === "function") {
|
|
instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
|
|
}
|
|
}
|
|
if (typeof instance.componentDidUpdate === "function") {
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
if (typeof instance.getSnapshotBeforeUpdate === "function") {
|
|
workInProgress2.flags |= Snapshot;
|
|
}
|
|
} else {
|
|
if (typeof instance.componentDidUpdate === "function") {
|
|
if (unresolvedOldProps !== current2.memoizedProps || oldState !== current2.memoizedState) {
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
}
|
|
if (typeof instance.getSnapshotBeforeUpdate === "function") {
|
|
if (unresolvedOldProps !== current2.memoizedProps || oldState !== current2.memoizedState) {
|
|
workInProgress2.flags |= Snapshot;
|
|
}
|
|
}
|
|
workInProgress2.memoizedProps = newProps;
|
|
workInProgress2.memoizedState = newState;
|
|
}
|
|
instance.props = newProps;
|
|
instance.state = newState;
|
|
instance.context = nextContext;
|
|
return shouldUpdate;
|
|
}
|
|
var forkStack = [];
|
|
var forkStackIndex = 0;
|
|
var treeForkProvider = null;
|
|
var treeForkCount = 0;
|
|
var idStack = [];
|
|
var idStackIndex = 0;
|
|
var treeContextProvider = null;
|
|
var treeContextId = 1;
|
|
var treeContextOverflow = "";
|
|
function isForkedChild(workInProgress2) {
|
|
warnIfNotHydrating();
|
|
return (workInProgress2.flags & Forked) !== NoFlags;
|
|
}
|
|
function getForksAtLevel(workInProgress2) {
|
|
warnIfNotHydrating();
|
|
return treeForkCount;
|
|
}
|
|
function getTreeId() {
|
|
var overflow = treeContextOverflow;
|
|
var idWithLeadingBit = treeContextId;
|
|
var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit);
|
|
return id.toString(32) + overflow;
|
|
}
|
|
function pushTreeFork(workInProgress2, totalChildren) {
|
|
warnIfNotHydrating();
|
|
forkStack[forkStackIndex++] = treeForkCount;
|
|
forkStack[forkStackIndex++] = treeForkProvider;
|
|
treeForkProvider = workInProgress2;
|
|
treeForkCount = totalChildren;
|
|
}
|
|
function pushTreeId(workInProgress2, totalChildren, index2) {
|
|
warnIfNotHydrating();
|
|
idStack[idStackIndex++] = treeContextId;
|
|
idStack[idStackIndex++] = treeContextOverflow;
|
|
idStack[idStackIndex++] = treeContextProvider;
|
|
treeContextProvider = workInProgress2;
|
|
var baseIdWithLeadingBit = treeContextId;
|
|
var baseOverflow = treeContextOverflow;
|
|
var baseLength = getBitLength(baseIdWithLeadingBit) - 1;
|
|
var baseId = baseIdWithLeadingBit & ~(1 << baseLength);
|
|
var slot = index2 + 1;
|
|
var length = getBitLength(totalChildren) + baseLength;
|
|
if (length > 30) {
|
|
var numberOfOverflowBits = baseLength - baseLength % 5;
|
|
var newOverflowBits = (1 << numberOfOverflowBits) - 1;
|
|
var newOverflow = (baseId & newOverflowBits).toString(32);
|
|
var restOfBaseId = baseId >> numberOfOverflowBits;
|
|
var restOfBaseLength = baseLength - numberOfOverflowBits;
|
|
var restOfLength = getBitLength(totalChildren) + restOfBaseLength;
|
|
var restOfNewBits = slot << restOfBaseLength;
|
|
var id = restOfNewBits | restOfBaseId;
|
|
var overflow = newOverflow + baseOverflow;
|
|
treeContextId = 1 << restOfLength | id;
|
|
treeContextOverflow = overflow;
|
|
} else {
|
|
var newBits = slot << baseLength;
|
|
var _id = newBits | baseId;
|
|
var _overflow = baseOverflow;
|
|
treeContextId = 1 << length | _id;
|
|
treeContextOverflow = _overflow;
|
|
}
|
|
}
|
|
function pushMaterializedTreeId(workInProgress2) {
|
|
warnIfNotHydrating();
|
|
var returnFiber = workInProgress2.return;
|
|
if (returnFiber !== null) {
|
|
var numberOfForks = 1;
|
|
var slotIndex = 0;
|
|
pushTreeFork(workInProgress2, numberOfForks);
|
|
pushTreeId(workInProgress2, numberOfForks, slotIndex);
|
|
}
|
|
}
|
|
function getBitLength(number) {
|
|
return 32 - clz32(number);
|
|
}
|
|
function getLeadingBit(id) {
|
|
return 1 << getBitLength(id) - 1;
|
|
}
|
|
function popTreeContext(workInProgress2) {
|
|
while (workInProgress2 === treeForkProvider) {
|
|
treeForkProvider = forkStack[--forkStackIndex];
|
|
forkStack[forkStackIndex] = null;
|
|
treeForkCount = forkStack[--forkStackIndex];
|
|
forkStack[forkStackIndex] = null;
|
|
}
|
|
while (workInProgress2 === treeContextProvider) {
|
|
treeContextProvider = idStack[--idStackIndex];
|
|
idStack[idStackIndex] = null;
|
|
treeContextOverflow = idStack[--idStackIndex];
|
|
idStack[idStackIndex] = null;
|
|
treeContextId = idStack[--idStackIndex];
|
|
idStack[idStackIndex] = null;
|
|
}
|
|
}
|
|
function getSuspendedTreeContext() {
|
|
warnIfNotHydrating();
|
|
if (treeContextProvider !== null) {
|
|
return {
|
|
id: treeContextId,
|
|
overflow: treeContextOverflow
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
function restoreSuspendedTreeContext(workInProgress2, suspendedContext) {
|
|
warnIfNotHydrating();
|
|
idStack[idStackIndex++] = treeContextId;
|
|
idStack[idStackIndex++] = treeContextOverflow;
|
|
idStack[idStackIndex++] = treeContextProvider;
|
|
treeContextId = suspendedContext.id;
|
|
treeContextOverflow = suspendedContext.overflow;
|
|
treeContextProvider = workInProgress2;
|
|
}
|
|
function warnIfNotHydrating() {
|
|
{
|
|
if (!getIsHydrating()) {
|
|
error("Expected to be hydrating. This is a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
}
|
|
var hydrationParentFiber = null;
|
|
var nextHydratableInstance = null;
|
|
var isHydrating = false;
|
|
var didSuspendOrErrorDEV = false;
|
|
var hydrationErrors = null;
|
|
function warnIfHydrating() {
|
|
{
|
|
if (isHydrating) {
|
|
error("We should not be hydrating here. This is a bug in React. Please file a bug.");
|
|
}
|
|
}
|
|
}
|
|
function markDidThrowWhileHydratingDEV() {
|
|
{
|
|
didSuspendOrErrorDEV = true;
|
|
}
|
|
}
|
|
function enterHydrationState(fiber) {
|
|
var parentInstance = fiber.stateNode.containerInfo;
|
|
nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance);
|
|
hydrationParentFiber = fiber;
|
|
isHydrating = true;
|
|
hydrationErrors = null;
|
|
didSuspendOrErrorDEV = false;
|
|
return true;
|
|
}
|
|
function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
|
|
nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance);
|
|
hydrationParentFiber = fiber;
|
|
isHydrating = true;
|
|
hydrationErrors = null;
|
|
didSuspendOrErrorDEV = false;
|
|
if (treeContext !== null) {
|
|
restoreSuspendedTreeContext(fiber, treeContext);
|
|
}
|
|
return true;
|
|
}
|
|
function warnUnhydratedInstance(returnFiber, instance) {
|
|
{
|
|
switch (returnFiber.tag) {
|
|
case HostRoot: {
|
|
didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance);
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
|
didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance, isConcurrentMode);
|
|
break;
|
|
}
|
|
case SuspenseComponent: {
|
|
var suspenseState = returnFiber.memoizedState;
|
|
if (suspenseState.dehydrated !== null)
|
|
didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function deleteHydratableInstance(returnFiber, instance) {
|
|
warnUnhydratedInstance(returnFiber, instance);
|
|
var childToDelete = createFiberFromHostInstanceForDeletion();
|
|
childToDelete.stateNode = instance;
|
|
childToDelete.return = returnFiber;
|
|
var deletions = returnFiber.deletions;
|
|
if (deletions === null) {
|
|
returnFiber.deletions = [childToDelete];
|
|
returnFiber.flags |= ChildDeletion;
|
|
} else {
|
|
deletions.push(childToDelete);
|
|
}
|
|
}
|
|
function warnNonhydratedInstance(returnFiber, fiber) {
|
|
{
|
|
if (didSuspendOrErrorDEV) {
|
|
return;
|
|
}
|
|
switch (returnFiber.tag) {
|
|
case HostRoot: {
|
|
var parentContainer = returnFiber.stateNode.containerInfo;
|
|
switch (fiber.tag) {
|
|
case HostComponent:
|
|
var type = fiber.type;
|
|
var props = fiber.pendingProps;
|
|
didNotFindHydratableInstanceWithinContainer(parentContainer, type);
|
|
break;
|
|
case HostText:
|
|
var text = fiber.pendingProps;
|
|
didNotFindHydratableTextInstanceWithinContainer(parentContainer, text);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
var parentType = returnFiber.type;
|
|
var parentProps = returnFiber.memoizedProps;
|
|
var parentInstance = returnFiber.stateNode;
|
|
switch (fiber.tag) {
|
|
case HostComponent: {
|
|
var _type = fiber.type;
|
|
var _props = fiber.pendingProps;
|
|
var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
|
didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props, isConcurrentMode);
|
|
break;
|
|
}
|
|
case HostText: {
|
|
var _text = fiber.pendingProps;
|
|
var _isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
|
didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text, _isConcurrentMode);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SuspenseComponent: {
|
|
var suspenseState = returnFiber.memoizedState;
|
|
var _parentInstance = suspenseState.dehydrated;
|
|
if (_parentInstance !== null)
|
|
switch (fiber.tag) {
|
|
case HostComponent:
|
|
var _type2 = fiber.type;
|
|
var _props2 = fiber.pendingProps;
|
|
didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2);
|
|
break;
|
|
case HostText:
|
|
var _text2 = fiber.pendingProps;
|
|
didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function insertNonHydratedInstance(returnFiber, fiber) {
|
|
fiber.flags = fiber.flags & ~Hydrating | Placement;
|
|
warnNonhydratedInstance(returnFiber, fiber);
|
|
}
|
|
function tryHydrate(fiber, nextInstance) {
|
|
switch (fiber.tag) {
|
|
case HostComponent: {
|
|
var type = fiber.type;
|
|
var props = fiber.pendingProps;
|
|
var instance = canHydrateInstance(nextInstance, type);
|
|
if (instance !== null) {
|
|
fiber.stateNode = instance;
|
|
hydrationParentFiber = fiber;
|
|
nextHydratableInstance = getFirstHydratableChild(instance);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
case HostText: {
|
|
var text = fiber.pendingProps;
|
|
var textInstance = canHydrateTextInstance(nextInstance, text);
|
|
if (textInstance !== null) {
|
|
fiber.stateNode = textInstance;
|
|
hydrationParentFiber = fiber;
|
|
nextHydratableInstance = null;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
case SuspenseComponent: {
|
|
var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
|
|
if (suspenseInstance !== null) {
|
|
var suspenseState = {
|
|
dehydrated: suspenseInstance,
|
|
treeContext: getSuspendedTreeContext(),
|
|
retryLane: OffscreenLane
|
|
};
|
|
fiber.memoizedState = suspenseState;
|
|
var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
|
|
dehydratedFragment.return = fiber;
|
|
fiber.child = dehydratedFragment;
|
|
hydrationParentFiber = fiber;
|
|
nextHydratableInstance = null;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function shouldClientRenderOnMismatch(fiber) {
|
|
return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags;
|
|
}
|
|
function throwOnHydrationMismatch(fiber) {
|
|
throw new Error("Hydration failed because the initial UI does not match what was rendered on the server.");
|
|
}
|
|
function tryToClaimNextHydratableInstance(fiber) {
|
|
if (!isHydrating) {
|
|
return;
|
|
}
|
|
var nextInstance = nextHydratableInstance;
|
|
if (!nextInstance) {
|
|
if (shouldClientRenderOnMismatch(fiber)) {
|
|
warnNonhydratedInstance(hydrationParentFiber, fiber);
|
|
throwOnHydrationMismatch();
|
|
}
|
|
insertNonHydratedInstance(hydrationParentFiber, fiber);
|
|
isHydrating = false;
|
|
hydrationParentFiber = fiber;
|
|
return;
|
|
}
|
|
var firstAttemptedInstance = nextInstance;
|
|
if (!tryHydrate(fiber, nextInstance)) {
|
|
if (shouldClientRenderOnMismatch(fiber)) {
|
|
warnNonhydratedInstance(hydrationParentFiber, fiber);
|
|
throwOnHydrationMismatch();
|
|
}
|
|
nextInstance = getNextHydratableSibling(firstAttemptedInstance);
|
|
var prevHydrationParentFiber = hydrationParentFiber;
|
|
if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
|
|
insertNonHydratedInstance(hydrationParentFiber, fiber);
|
|
isHydrating = false;
|
|
hydrationParentFiber = fiber;
|
|
return;
|
|
}
|
|
deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
|
|
}
|
|
}
|
|
function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
|
|
var instance = fiber.stateNode;
|
|
var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV;
|
|
var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev);
|
|
fiber.updateQueue = updatePayload;
|
|
if (updatePayload !== null) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function prepareToHydrateHostTextInstance(fiber) {
|
|
var textInstance = fiber.stateNode;
|
|
var textContent = fiber.memoizedProps;
|
|
var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
|
|
if (shouldUpdate) {
|
|
var returnFiber = hydrationParentFiber;
|
|
if (returnFiber !== null) {
|
|
switch (returnFiber.tag) {
|
|
case HostRoot: {
|
|
var parentContainer = returnFiber.stateNode.containerInfo;
|
|
var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
|
didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, isConcurrentMode);
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
var parentType = returnFiber.type;
|
|
var parentProps = returnFiber.memoizedProps;
|
|
var parentInstance = returnFiber.stateNode;
|
|
var _isConcurrentMode2 = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
|
didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, _isConcurrentMode2);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return shouldUpdate;
|
|
}
|
|
function prepareToHydrateHostSuspenseInstance(fiber) {
|
|
var suspenseState = fiber.memoizedState;
|
|
var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
|
|
if (!suspenseInstance) {
|
|
throw new Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
hydrateSuspenseInstance(suspenseInstance, fiber);
|
|
}
|
|
function skipPastDehydratedSuspenseInstance(fiber) {
|
|
var suspenseState = fiber.memoizedState;
|
|
var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
|
|
if (!suspenseInstance) {
|
|
throw new Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
|
|
}
|
|
function popToNextHostParent(fiber) {
|
|
var parent = fiber.return;
|
|
while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
|
|
parent = parent.return;
|
|
}
|
|
hydrationParentFiber = parent;
|
|
}
|
|
function popHydrationState(fiber) {
|
|
if (fiber !== hydrationParentFiber) {
|
|
return false;
|
|
}
|
|
if (!isHydrating) {
|
|
popToNextHostParent(fiber);
|
|
isHydrating = true;
|
|
return false;
|
|
}
|
|
if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) {
|
|
var nextInstance = nextHydratableInstance;
|
|
if (nextInstance) {
|
|
if (shouldClientRenderOnMismatch(fiber)) {
|
|
warnIfUnhydratedTailNodes(fiber);
|
|
throwOnHydrationMismatch();
|
|
} else {
|
|
while (nextInstance) {
|
|
deleteHydratableInstance(fiber, nextInstance);
|
|
nextInstance = getNextHydratableSibling(nextInstance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
popToNextHostParent(fiber);
|
|
if (fiber.tag === SuspenseComponent) {
|
|
nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
|
|
} else {
|
|
nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
|
|
}
|
|
return true;
|
|
}
|
|
function hasUnhydratedTailNodes() {
|
|
return isHydrating && nextHydratableInstance !== null;
|
|
}
|
|
function warnIfUnhydratedTailNodes(fiber) {
|
|
var nextInstance = nextHydratableInstance;
|
|
while (nextInstance) {
|
|
warnUnhydratedInstance(fiber, nextInstance);
|
|
nextInstance = getNextHydratableSibling(nextInstance);
|
|
}
|
|
}
|
|
function resetHydrationState() {
|
|
hydrationParentFiber = null;
|
|
nextHydratableInstance = null;
|
|
isHydrating = false;
|
|
didSuspendOrErrorDEV = false;
|
|
}
|
|
function upgradeHydrationErrorsToRecoverable() {
|
|
if (hydrationErrors !== null) {
|
|
queueRecoverableErrors(hydrationErrors);
|
|
hydrationErrors = null;
|
|
}
|
|
}
|
|
function getIsHydrating() {
|
|
return isHydrating;
|
|
}
|
|
function queueHydrationError(error2) {
|
|
if (hydrationErrors === null) {
|
|
hydrationErrors = [error2];
|
|
} else {
|
|
hydrationErrors.push(error2);
|
|
}
|
|
}
|
|
var didWarnAboutMaps;
|
|
var didWarnAboutGenerators;
|
|
var didWarnAboutStringRefs;
|
|
var ownerHasKeyUseWarning;
|
|
var ownerHasFunctionTypeWarning;
|
|
var warnForMissingKey = function(child, returnFiber) {
|
|
};
|
|
{
|
|
didWarnAboutMaps = false;
|
|
didWarnAboutGenerators = false;
|
|
didWarnAboutStringRefs = {};
|
|
ownerHasKeyUseWarning = {};
|
|
ownerHasFunctionTypeWarning = {};
|
|
warnForMissingKey = function(child, returnFiber) {
|
|
if (child === null || typeof child !== "object") {
|
|
return;
|
|
}
|
|
if (!child._store || child._store.validated || child.key != null) {
|
|
return;
|
|
}
|
|
if (typeof child._store !== "object") {
|
|
throw new Error("React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
child._store.validated = true;
|
|
var componentName = getComponentNameFromFiber(returnFiber) || "Component";
|
|
if (ownerHasKeyUseWarning[componentName]) {
|
|
return;
|
|
}
|
|
ownerHasKeyUseWarning[componentName] = true;
|
|
error('Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.');
|
|
};
|
|
}
|
|
function coerceRef(returnFiber, current2, element) {
|
|
var mixedRef = element.ref;
|
|
if (mixedRef !== null && typeof mixedRef !== "function" && typeof mixedRef !== "object") {
|
|
{
|
|
if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && !(element._owner && element._self && element._owner.stateNode !== element._self)) {
|
|
var componentName = getComponentNameFromFiber(returnFiber) || "Component";
|
|
if (!didWarnAboutStringRefs[componentName]) {
|
|
{
|
|
error('A string ref, "%s", has been found within a strict mode tree. String refs are a source of potential bugs and should be avoided. We recommend using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', mixedRef);
|
|
}
|
|
didWarnAboutStringRefs[componentName] = true;
|
|
}
|
|
}
|
|
}
|
|
if (element._owner) {
|
|
var owner = element._owner;
|
|
var inst;
|
|
if (owner) {
|
|
var ownerFiber = owner;
|
|
if (ownerFiber.tag !== ClassComponent) {
|
|
throw new Error("Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref");
|
|
}
|
|
inst = ownerFiber.stateNode;
|
|
}
|
|
if (!inst) {
|
|
throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
var resolvedInst = inst;
|
|
{
|
|
checkPropStringCoercion(mixedRef, "ref");
|
|
}
|
|
var stringRef = "" + mixedRef;
|
|
if (current2 !== null && current2.ref !== null && typeof current2.ref === "function" && current2.ref._stringRef === stringRef) {
|
|
return current2.ref;
|
|
}
|
|
var ref = function(value) {
|
|
var refs = resolvedInst.refs;
|
|
if (refs === emptyRefsObject) {
|
|
refs = resolvedInst.refs = {};
|
|
}
|
|
if (value === null) {
|
|
delete refs[stringRef];
|
|
} else {
|
|
refs[stringRef] = value;
|
|
}
|
|
};
|
|
ref._stringRef = stringRef;
|
|
return ref;
|
|
} else {
|
|
if (typeof mixedRef !== "string") {
|
|
throw new Error("Expected ref to be a function, a string, an object returned by React.createRef(), or null.");
|
|
}
|
|
if (!element._owner) {
|
|
throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://reactjs.org/link/refs-must-have-owner for more information.");
|
|
}
|
|
}
|
|
}
|
|
return mixedRef;
|
|
}
|
|
function throwOnInvalidObjectType(returnFiber, newChild) {
|
|
var childString = Object.prototype.toString.call(newChild);
|
|
throw new Error("Objects are not valid as a React child (found: " + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" : childString) + "). If you meant to render a collection of children, use an array instead.");
|
|
}
|
|
function warnOnFunctionType(returnFiber) {
|
|
{
|
|
var componentName = getComponentNameFromFiber(returnFiber) || "Component";
|
|
if (ownerHasFunctionTypeWarning[componentName]) {
|
|
return;
|
|
}
|
|
ownerHasFunctionTypeWarning[componentName] = true;
|
|
error("Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.");
|
|
}
|
|
}
|
|
function resolveLazy(lazyType) {
|
|
var payload = lazyType._payload;
|
|
var init = lazyType._init;
|
|
return init(payload);
|
|
}
|
|
function ChildReconciler(shouldTrackSideEffects) {
|
|
function deleteChild(returnFiber, childToDelete) {
|
|
if (!shouldTrackSideEffects) {
|
|
return;
|
|
}
|
|
var deletions = returnFiber.deletions;
|
|
if (deletions === null) {
|
|
returnFiber.deletions = [childToDelete];
|
|
returnFiber.flags |= ChildDeletion;
|
|
} else {
|
|
deletions.push(childToDelete);
|
|
}
|
|
}
|
|
function deleteRemainingChildren(returnFiber, currentFirstChild) {
|
|
if (!shouldTrackSideEffects) {
|
|
return null;
|
|
}
|
|
var childToDelete = currentFirstChild;
|
|
while (childToDelete !== null) {
|
|
deleteChild(returnFiber, childToDelete);
|
|
childToDelete = childToDelete.sibling;
|
|
}
|
|
return null;
|
|
}
|
|
function mapRemainingChildren(returnFiber, currentFirstChild) {
|
|
var existingChildren = /* @__PURE__ */ new Map();
|
|
var existingChild = currentFirstChild;
|
|
while (existingChild !== null) {
|
|
if (existingChild.key !== null) {
|
|
existingChildren.set(existingChild.key, existingChild);
|
|
} else {
|
|
existingChildren.set(existingChild.index, existingChild);
|
|
}
|
|
existingChild = existingChild.sibling;
|
|
}
|
|
return existingChildren;
|
|
}
|
|
function useFiber(fiber, pendingProps) {
|
|
var clone = createWorkInProgress(fiber, pendingProps);
|
|
clone.index = 0;
|
|
clone.sibling = null;
|
|
return clone;
|
|
}
|
|
function placeChild(newFiber, lastPlacedIndex, newIndex) {
|
|
newFiber.index = newIndex;
|
|
if (!shouldTrackSideEffects) {
|
|
newFiber.flags |= Forked;
|
|
return lastPlacedIndex;
|
|
}
|
|
var current2 = newFiber.alternate;
|
|
if (current2 !== null) {
|
|
var oldIndex = current2.index;
|
|
if (oldIndex < lastPlacedIndex) {
|
|
newFiber.flags |= Placement;
|
|
return lastPlacedIndex;
|
|
} else {
|
|
return oldIndex;
|
|
}
|
|
} else {
|
|
newFiber.flags |= Placement;
|
|
return lastPlacedIndex;
|
|
}
|
|
}
|
|
function placeSingleChild(newFiber) {
|
|
if (shouldTrackSideEffects && newFiber.alternate === null) {
|
|
newFiber.flags |= Placement;
|
|
}
|
|
return newFiber;
|
|
}
|
|
function updateTextNode(returnFiber, current2, textContent, lanes) {
|
|
if (current2 === null || current2.tag !== HostText) {
|
|
var created = createFiberFromText(textContent, returnFiber.mode, lanes);
|
|
created.return = returnFiber;
|
|
return created;
|
|
} else {
|
|
var existing = useFiber(current2, textContent);
|
|
existing.return = returnFiber;
|
|
return existing;
|
|
}
|
|
}
|
|
function updateElement(returnFiber, current2, element, lanes) {
|
|
var elementType = element.type;
|
|
if (elementType === REACT_FRAGMENT_TYPE) {
|
|
return updateFragment2(returnFiber, current2, element.props.children, lanes, element.key);
|
|
}
|
|
if (current2 !== null) {
|
|
if (current2.elementType === elementType || isCompatibleFamilyForHotReloading(current2, element) || typeof elementType === "object" && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current2.type) {
|
|
var existing = useFiber(current2, element.props);
|
|
existing.ref = coerceRef(returnFiber, current2, element);
|
|
existing.return = returnFiber;
|
|
{
|
|
existing._debugSource = element._source;
|
|
existing._debugOwner = element._owner;
|
|
}
|
|
return existing;
|
|
}
|
|
}
|
|
var created = createFiberFromElement(element, returnFiber.mode, lanes);
|
|
created.ref = coerceRef(returnFiber, current2, element);
|
|
created.return = returnFiber;
|
|
return created;
|
|
}
|
|
function updatePortal(returnFiber, current2, portal, lanes) {
|
|
if (current2 === null || current2.tag !== HostPortal || current2.stateNode.containerInfo !== portal.containerInfo || current2.stateNode.implementation !== portal.implementation) {
|
|
var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
|
|
created.return = returnFiber;
|
|
return created;
|
|
} else {
|
|
var existing = useFiber(current2, portal.children || []);
|
|
existing.return = returnFiber;
|
|
return existing;
|
|
}
|
|
}
|
|
function updateFragment2(returnFiber, current2, fragment, lanes, key) {
|
|
if (current2 === null || current2.tag !== Fragment2) {
|
|
var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
|
|
created.return = returnFiber;
|
|
return created;
|
|
} else {
|
|
var existing = useFiber(current2, fragment);
|
|
existing.return = returnFiber;
|
|
return existing;
|
|
}
|
|
}
|
|
function createChild(returnFiber, newChild, lanes) {
|
|
if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
|
|
var created = createFiberFromText("" + newChild, returnFiber.mode, lanes);
|
|
created.return = returnFiber;
|
|
return created;
|
|
}
|
|
if (typeof newChild === "object" && newChild !== null) {
|
|
switch (newChild.$$typeof) {
|
|
case REACT_ELEMENT_TYPE: {
|
|
var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
|
|
_created.ref = coerceRef(returnFiber, null, newChild);
|
|
_created.return = returnFiber;
|
|
return _created;
|
|
}
|
|
case REACT_PORTAL_TYPE: {
|
|
var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
|
|
_created2.return = returnFiber;
|
|
return _created2;
|
|
}
|
|
case REACT_LAZY_TYPE: {
|
|
var payload = newChild._payload;
|
|
var init = newChild._init;
|
|
return createChild(returnFiber, init(payload), lanes);
|
|
}
|
|
}
|
|
if (isArray(newChild) || getIteratorFn(newChild)) {
|
|
var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
|
|
_created3.return = returnFiber;
|
|
return _created3;
|
|
}
|
|
throwOnInvalidObjectType(returnFiber, newChild);
|
|
}
|
|
{
|
|
if (typeof newChild === "function") {
|
|
warnOnFunctionType(returnFiber);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function updateSlot(returnFiber, oldFiber, newChild, lanes) {
|
|
var key = oldFiber !== null ? oldFiber.key : null;
|
|
if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
|
|
if (key !== null) {
|
|
return null;
|
|
}
|
|
return updateTextNode(returnFiber, oldFiber, "" + newChild, lanes);
|
|
}
|
|
if (typeof newChild === "object" && newChild !== null) {
|
|
switch (newChild.$$typeof) {
|
|
case REACT_ELEMENT_TYPE: {
|
|
if (newChild.key === key) {
|
|
return updateElement(returnFiber, oldFiber, newChild, lanes);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
case REACT_PORTAL_TYPE: {
|
|
if (newChild.key === key) {
|
|
return updatePortal(returnFiber, oldFiber, newChild, lanes);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
case REACT_LAZY_TYPE: {
|
|
var payload = newChild._payload;
|
|
var init = newChild._init;
|
|
return updateSlot(returnFiber, oldFiber, init(payload), lanes);
|
|
}
|
|
}
|
|
if (isArray(newChild) || getIteratorFn(newChild)) {
|
|
if (key !== null) {
|
|
return null;
|
|
}
|
|
return updateFragment2(returnFiber, oldFiber, newChild, lanes, null);
|
|
}
|
|
throwOnInvalidObjectType(returnFiber, newChild);
|
|
}
|
|
{
|
|
if (typeof newChild === "function") {
|
|
warnOnFunctionType(returnFiber);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
|
|
if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
|
|
var matchedFiber = existingChildren.get(newIdx) || null;
|
|
return updateTextNode(returnFiber, matchedFiber, "" + newChild, lanes);
|
|
}
|
|
if (typeof newChild === "object" && newChild !== null) {
|
|
switch (newChild.$$typeof) {
|
|
case REACT_ELEMENT_TYPE: {
|
|
var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
|
|
return updateElement(returnFiber, _matchedFiber, newChild, lanes);
|
|
}
|
|
case REACT_PORTAL_TYPE: {
|
|
var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
|
|
return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
|
|
}
|
|
case REACT_LAZY_TYPE:
|
|
var payload = newChild._payload;
|
|
var init = newChild._init;
|
|
return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes);
|
|
}
|
|
if (isArray(newChild) || getIteratorFn(newChild)) {
|
|
var _matchedFiber3 = existingChildren.get(newIdx) || null;
|
|
return updateFragment2(returnFiber, _matchedFiber3, newChild, lanes, null);
|
|
}
|
|
throwOnInvalidObjectType(returnFiber, newChild);
|
|
}
|
|
{
|
|
if (typeof newChild === "function") {
|
|
warnOnFunctionType(returnFiber);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function warnOnInvalidKey(child, knownKeys, returnFiber) {
|
|
{
|
|
if (typeof child !== "object" || child === null) {
|
|
return knownKeys;
|
|
}
|
|
switch (child.$$typeof) {
|
|
case REACT_ELEMENT_TYPE:
|
|
case REACT_PORTAL_TYPE:
|
|
warnForMissingKey(child, returnFiber);
|
|
var key = child.key;
|
|
if (typeof key !== "string") {
|
|
break;
|
|
}
|
|
if (knownKeys === null) {
|
|
knownKeys = /* @__PURE__ */ new Set();
|
|
knownKeys.add(key);
|
|
break;
|
|
}
|
|
if (!knownKeys.has(key)) {
|
|
knownKeys.add(key);
|
|
break;
|
|
}
|
|
error("Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted \u2014 the behavior is unsupported and could change in a future version.", key);
|
|
break;
|
|
case REACT_LAZY_TYPE:
|
|
var payload = child._payload;
|
|
var init = child._init;
|
|
warnOnInvalidKey(init(payload), knownKeys, returnFiber);
|
|
break;
|
|
}
|
|
}
|
|
return knownKeys;
|
|
}
|
|
function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
|
|
{
|
|
var knownKeys = null;
|
|
for (var i = 0; i < newChildren.length; i++) {
|
|
var child = newChildren[i];
|
|
knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
|
|
}
|
|
}
|
|
var resultingFirstChild = null;
|
|
var previousNewFiber = null;
|
|
var oldFiber = currentFirstChild;
|
|
var lastPlacedIndex = 0;
|
|
var newIdx = 0;
|
|
var nextOldFiber = null;
|
|
for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
|
|
if (oldFiber.index > newIdx) {
|
|
nextOldFiber = oldFiber;
|
|
oldFiber = null;
|
|
} else {
|
|
nextOldFiber = oldFiber.sibling;
|
|
}
|
|
var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
|
|
if (newFiber === null) {
|
|
if (oldFiber === null) {
|
|
oldFiber = nextOldFiber;
|
|
}
|
|
break;
|
|
}
|
|
if (shouldTrackSideEffects) {
|
|
if (oldFiber && newFiber.alternate === null) {
|
|
deleteChild(returnFiber, oldFiber);
|
|
}
|
|
}
|
|
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
|
|
if (previousNewFiber === null) {
|
|
resultingFirstChild = newFiber;
|
|
} else {
|
|
previousNewFiber.sibling = newFiber;
|
|
}
|
|
previousNewFiber = newFiber;
|
|
oldFiber = nextOldFiber;
|
|
}
|
|
if (newIdx === newChildren.length) {
|
|
deleteRemainingChildren(returnFiber, oldFiber);
|
|
if (getIsHydrating()) {
|
|
var numberOfForks = newIdx;
|
|
pushTreeFork(returnFiber, numberOfForks);
|
|
}
|
|
return resultingFirstChild;
|
|
}
|
|
if (oldFiber === null) {
|
|
for (; newIdx < newChildren.length; newIdx++) {
|
|
var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
|
|
if (_newFiber === null) {
|
|
continue;
|
|
}
|
|
lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
|
|
if (previousNewFiber === null) {
|
|
resultingFirstChild = _newFiber;
|
|
} else {
|
|
previousNewFiber.sibling = _newFiber;
|
|
}
|
|
previousNewFiber = _newFiber;
|
|
}
|
|
if (getIsHydrating()) {
|
|
var _numberOfForks = newIdx;
|
|
pushTreeFork(returnFiber, _numberOfForks);
|
|
}
|
|
return resultingFirstChild;
|
|
}
|
|
var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
|
|
for (; newIdx < newChildren.length; newIdx++) {
|
|
var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
|
|
if (_newFiber2 !== null) {
|
|
if (shouldTrackSideEffects) {
|
|
if (_newFiber2.alternate !== null) {
|
|
existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
|
|
}
|
|
}
|
|
lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
|
|
if (previousNewFiber === null) {
|
|
resultingFirstChild = _newFiber2;
|
|
} else {
|
|
previousNewFiber.sibling = _newFiber2;
|
|
}
|
|
previousNewFiber = _newFiber2;
|
|
}
|
|
}
|
|
if (shouldTrackSideEffects) {
|
|
existingChildren.forEach(function(child2) {
|
|
return deleteChild(returnFiber, child2);
|
|
});
|
|
}
|
|
if (getIsHydrating()) {
|
|
var _numberOfForks2 = newIdx;
|
|
pushTreeFork(returnFiber, _numberOfForks2);
|
|
}
|
|
return resultingFirstChild;
|
|
}
|
|
function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
|
|
var iteratorFn = getIteratorFn(newChildrenIterable);
|
|
if (typeof iteratorFn !== "function") {
|
|
throw new Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
{
|
|
if (typeof Symbol === "function" && newChildrenIterable[Symbol.toStringTag] === "Generator") {
|
|
if (!didWarnAboutGenerators) {
|
|
error("Using Generators as children is unsupported and will likely yield unexpected results because enumerating a generator mutates it. You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. Keep in mind you might need to polyfill these features for older browsers.");
|
|
}
|
|
didWarnAboutGenerators = true;
|
|
}
|
|
if (newChildrenIterable.entries === iteratorFn) {
|
|
if (!didWarnAboutMaps) {
|
|
error("Using Maps as children is not supported. Use an array of keyed ReactElements instead.");
|
|
}
|
|
didWarnAboutMaps = true;
|
|
}
|
|
var _newChildren = iteratorFn.call(newChildrenIterable);
|
|
if (_newChildren) {
|
|
var knownKeys = null;
|
|
var _step = _newChildren.next();
|
|
for (; !_step.done; _step = _newChildren.next()) {
|
|
var child = _step.value;
|
|
knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
|
|
}
|
|
}
|
|
}
|
|
var newChildren = iteratorFn.call(newChildrenIterable);
|
|
if (newChildren == null) {
|
|
throw new Error("An iterable object provided no iterator.");
|
|
}
|
|
var resultingFirstChild = null;
|
|
var previousNewFiber = null;
|
|
var oldFiber = currentFirstChild;
|
|
var lastPlacedIndex = 0;
|
|
var newIdx = 0;
|
|
var nextOldFiber = null;
|
|
var step = newChildren.next();
|
|
for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
|
|
if (oldFiber.index > newIdx) {
|
|
nextOldFiber = oldFiber;
|
|
oldFiber = null;
|
|
} else {
|
|
nextOldFiber = oldFiber.sibling;
|
|
}
|
|
var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
|
|
if (newFiber === null) {
|
|
if (oldFiber === null) {
|
|
oldFiber = nextOldFiber;
|
|
}
|
|
break;
|
|
}
|
|
if (shouldTrackSideEffects) {
|
|
if (oldFiber && newFiber.alternate === null) {
|
|
deleteChild(returnFiber, oldFiber);
|
|
}
|
|
}
|
|
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
|
|
if (previousNewFiber === null) {
|
|
resultingFirstChild = newFiber;
|
|
} else {
|
|
previousNewFiber.sibling = newFiber;
|
|
}
|
|
previousNewFiber = newFiber;
|
|
oldFiber = nextOldFiber;
|
|
}
|
|
if (step.done) {
|
|
deleteRemainingChildren(returnFiber, oldFiber);
|
|
if (getIsHydrating()) {
|
|
var numberOfForks = newIdx;
|
|
pushTreeFork(returnFiber, numberOfForks);
|
|
}
|
|
return resultingFirstChild;
|
|
}
|
|
if (oldFiber === null) {
|
|
for (; !step.done; newIdx++, step = newChildren.next()) {
|
|
var _newFiber3 = createChild(returnFiber, step.value, lanes);
|
|
if (_newFiber3 === null) {
|
|
continue;
|
|
}
|
|
lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
|
|
if (previousNewFiber === null) {
|
|
resultingFirstChild = _newFiber3;
|
|
} else {
|
|
previousNewFiber.sibling = _newFiber3;
|
|
}
|
|
previousNewFiber = _newFiber3;
|
|
}
|
|
if (getIsHydrating()) {
|
|
var _numberOfForks3 = newIdx;
|
|
pushTreeFork(returnFiber, _numberOfForks3);
|
|
}
|
|
return resultingFirstChild;
|
|
}
|
|
var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
|
|
for (; !step.done; newIdx++, step = newChildren.next()) {
|
|
var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
|
|
if (_newFiber4 !== null) {
|
|
if (shouldTrackSideEffects) {
|
|
if (_newFiber4.alternate !== null) {
|
|
existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
|
|
}
|
|
}
|
|
lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
|
|
if (previousNewFiber === null) {
|
|
resultingFirstChild = _newFiber4;
|
|
} else {
|
|
previousNewFiber.sibling = _newFiber4;
|
|
}
|
|
previousNewFiber = _newFiber4;
|
|
}
|
|
}
|
|
if (shouldTrackSideEffects) {
|
|
existingChildren.forEach(function(child2) {
|
|
return deleteChild(returnFiber, child2);
|
|
});
|
|
}
|
|
if (getIsHydrating()) {
|
|
var _numberOfForks4 = newIdx;
|
|
pushTreeFork(returnFiber, _numberOfForks4);
|
|
}
|
|
return resultingFirstChild;
|
|
}
|
|
function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
|
|
if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
|
|
deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
|
|
var existing = useFiber(currentFirstChild, textContent);
|
|
existing.return = returnFiber;
|
|
return existing;
|
|
}
|
|
deleteRemainingChildren(returnFiber, currentFirstChild);
|
|
var created = createFiberFromText(textContent, returnFiber.mode, lanes);
|
|
created.return = returnFiber;
|
|
return created;
|
|
}
|
|
function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
|
|
var key = element.key;
|
|
var child = currentFirstChild;
|
|
while (child !== null) {
|
|
if (child.key === key) {
|
|
var elementType = element.type;
|
|
if (elementType === REACT_FRAGMENT_TYPE) {
|
|
if (child.tag === Fragment2) {
|
|
deleteRemainingChildren(returnFiber, child.sibling);
|
|
var existing = useFiber(child, element.props.children);
|
|
existing.return = returnFiber;
|
|
{
|
|
existing._debugSource = element._source;
|
|
existing._debugOwner = element._owner;
|
|
}
|
|
return existing;
|
|
}
|
|
} else {
|
|
if (child.elementType === elementType || isCompatibleFamilyForHotReloading(child, element) || typeof elementType === "object" && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
|
|
deleteRemainingChildren(returnFiber, child.sibling);
|
|
var _existing = useFiber(child, element.props);
|
|
_existing.ref = coerceRef(returnFiber, child, element);
|
|
_existing.return = returnFiber;
|
|
{
|
|
_existing._debugSource = element._source;
|
|
_existing._debugOwner = element._owner;
|
|
}
|
|
return _existing;
|
|
}
|
|
}
|
|
deleteRemainingChildren(returnFiber, child);
|
|
break;
|
|
} else {
|
|
deleteChild(returnFiber, child);
|
|
}
|
|
child = child.sibling;
|
|
}
|
|
if (element.type === REACT_FRAGMENT_TYPE) {
|
|
var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
|
|
created.return = returnFiber;
|
|
return created;
|
|
} else {
|
|
var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
|
|
_created4.ref = coerceRef(returnFiber, currentFirstChild, element);
|
|
_created4.return = returnFiber;
|
|
return _created4;
|
|
}
|
|
}
|
|
function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
|
|
var key = portal.key;
|
|
var child = currentFirstChild;
|
|
while (child !== null) {
|
|
if (child.key === key) {
|
|
if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
|
|
deleteRemainingChildren(returnFiber, child.sibling);
|
|
var existing = useFiber(child, portal.children || []);
|
|
existing.return = returnFiber;
|
|
return existing;
|
|
} else {
|
|
deleteRemainingChildren(returnFiber, child);
|
|
break;
|
|
}
|
|
} else {
|
|
deleteChild(returnFiber, child);
|
|
}
|
|
child = child.sibling;
|
|
}
|
|
var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
|
|
created.return = returnFiber;
|
|
return created;
|
|
}
|
|
function reconcileChildFibers2(returnFiber, currentFirstChild, newChild, lanes) {
|
|
var isUnkeyedTopLevelFragment = typeof newChild === "object" && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
|
|
if (isUnkeyedTopLevelFragment) {
|
|
newChild = newChild.props.children;
|
|
}
|
|
if (typeof newChild === "object" && newChild !== null) {
|
|
switch (newChild.$$typeof) {
|
|
case REACT_ELEMENT_TYPE:
|
|
return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
|
|
case REACT_PORTAL_TYPE:
|
|
return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
|
|
case REACT_LAZY_TYPE:
|
|
var payload = newChild._payload;
|
|
var init = newChild._init;
|
|
return reconcileChildFibers2(returnFiber, currentFirstChild, init(payload), lanes);
|
|
}
|
|
if (isArray(newChild)) {
|
|
return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
|
|
}
|
|
if (getIteratorFn(newChild)) {
|
|
return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
|
|
}
|
|
throwOnInvalidObjectType(returnFiber, newChild);
|
|
}
|
|
if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
|
|
return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, "" + newChild, lanes));
|
|
}
|
|
{
|
|
if (typeof newChild === "function") {
|
|
warnOnFunctionType(returnFiber);
|
|
}
|
|
}
|
|
return deleteRemainingChildren(returnFiber, currentFirstChild);
|
|
}
|
|
return reconcileChildFibers2;
|
|
}
|
|
var reconcileChildFibers = ChildReconciler(true);
|
|
var mountChildFibers = ChildReconciler(false);
|
|
function cloneChildFibers(current2, workInProgress2) {
|
|
if (current2 !== null && workInProgress2.child !== current2.child) {
|
|
throw new Error("Resuming work not yet implemented.");
|
|
}
|
|
if (workInProgress2.child === null) {
|
|
return;
|
|
}
|
|
var currentChild = workInProgress2.child;
|
|
var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
|
|
workInProgress2.child = newChild;
|
|
newChild.return = workInProgress2;
|
|
while (currentChild.sibling !== null) {
|
|
currentChild = currentChild.sibling;
|
|
newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
|
|
newChild.return = workInProgress2;
|
|
}
|
|
newChild.sibling = null;
|
|
}
|
|
function resetChildFibers(workInProgress2, lanes) {
|
|
var child = workInProgress2.child;
|
|
while (child !== null) {
|
|
resetWorkInProgress(child, lanes);
|
|
child = child.sibling;
|
|
}
|
|
}
|
|
var NO_CONTEXT = {};
|
|
var contextStackCursor$1 = createCursor(NO_CONTEXT);
|
|
var contextFiberStackCursor = createCursor(NO_CONTEXT);
|
|
var rootInstanceStackCursor = createCursor(NO_CONTEXT);
|
|
function requiredContext(c) {
|
|
if (c === NO_CONTEXT) {
|
|
throw new Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
return c;
|
|
}
|
|
function getRootHostContainer() {
|
|
var rootInstance = requiredContext(rootInstanceStackCursor.current);
|
|
return rootInstance;
|
|
}
|
|
function pushHostContainer(fiber, nextRootInstance) {
|
|
push(rootInstanceStackCursor, nextRootInstance, fiber);
|
|
push(contextFiberStackCursor, fiber, fiber);
|
|
push(contextStackCursor$1, NO_CONTEXT, fiber);
|
|
var nextRootContext = getRootHostContext(nextRootInstance);
|
|
pop(contextStackCursor$1, fiber);
|
|
push(contextStackCursor$1, nextRootContext, fiber);
|
|
}
|
|
function popHostContainer(fiber) {
|
|
pop(contextStackCursor$1, fiber);
|
|
pop(contextFiberStackCursor, fiber);
|
|
pop(rootInstanceStackCursor, fiber);
|
|
}
|
|
function getHostContext() {
|
|
var context = requiredContext(contextStackCursor$1.current);
|
|
return context;
|
|
}
|
|
function pushHostContext(fiber) {
|
|
var rootInstance = requiredContext(rootInstanceStackCursor.current);
|
|
var context = requiredContext(contextStackCursor$1.current);
|
|
var nextContext = getChildHostContext(context, fiber.type);
|
|
if (context === nextContext) {
|
|
return;
|
|
}
|
|
push(contextFiberStackCursor, fiber, fiber);
|
|
push(contextStackCursor$1, nextContext, fiber);
|
|
}
|
|
function popHostContext(fiber) {
|
|
if (contextFiberStackCursor.current !== fiber) {
|
|
return;
|
|
}
|
|
pop(contextStackCursor$1, fiber);
|
|
pop(contextFiberStackCursor, fiber);
|
|
}
|
|
var DefaultSuspenseContext = 0;
|
|
var SubtreeSuspenseContextMask = 1;
|
|
var InvisibleParentSuspenseContext = 1;
|
|
var ForceSuspenseFallback = 2;
|
|
var suspenseStackCursor = createCursor(DefaultSuspenseContext);
|
|
function hasSuspenseContext(parentContext, flag) {
|
|
return (parentContext & flag) !== 0;
|
|
}
|
|
function setDefaultShallowSuspenseContext(parentContext) {
|
|
return parentContext & SubtreeSuspenseContextMask;
|
|
}
|
|
function setShallowSuspenseContext(parentContext, shallowContext) {
|
|
return parentContext & SubtreeSuspenseContextMask | shallowContext;
|
|
}
|
|
function addSubtreeSuspenseContext(parentContext, subtreeContext) {
|
|
return parentContext | subtreeContext;
|
|
}
|
|
function pushSuspenseContext(fiber, newContext) {
|
|
push(suspenseStackCursor, newContext, fiber);
|
|
}
|
|
function popSuspenseContext(fiber) {
|
|
pop(suspenseStackCursor, fiber);
|
|
}
|
|
function shouldCaptureSuspense(workInProgress2, hasInvisibleParent) {
|
|
var nextState = workInProgress2.memoizedState;
|
|
if (nextState !== null) {
|
|
if (nextState.dehydrated !== null) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
var props = workInProgress2.memoizedProps;
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
function findFirstSuspended(row) {
|
|
var node = row;
|
|
while (node !== null) {
|
|
if (node.tag === SuspenseComponent) {
|
|
var state = node.memoizedState;
|
|
if (state !== null) {
|
|
var dehydrated = state.dehydrated;
|
|
if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
|
|
return node;
|
|
}
|
|
}
|
|
} else if (node.tag === SuspenseListComponent && node.memoizedProps.revealOrder !== void 0) {
|
|
var didSuspend = (node.flags & DidCapture) !== NoFlags;
|
|
if (didSuspend) {
|
|
return node;
|
|
}
|
|
} else if (node.child !== null) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === row) {
|
|
return null;
|
|
}
|
|
while (node.sibling === null) {
|
|
if (node.return === null || node.return === row) {
|
|
return null;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
return null;
|
|
}
|
|
var NoFlags$1 = 0;
|
|
var HasEffect = 1;
|
|
var Insertion = 2;
|
|
var Layout = 4;
|
|
var Passive$1 = 8;
|
|
var workInProgressSources = [];
|
|
function resetWorkInProgressVersions() {
|
|
for (var i = 0; i < workInProgressSources.length; i++) {
|
|
var mutableSource = workInProgressSources[i];
|
|
{
|
|
mutableSource._workInProgressVersionPrimary = null;
|
|
}
|
|
}
|
|
workInProgressSources.length = 0;
|
|
}
|
|
function registerMutableSourceForHydration(root3, mutableSource) {
|
|
var getVersion = mutableSource._getVersion;
|
|
var version = getVersion(mutableSource._source);
|
|
if (root3.mutableSourceEagerHydrationData == null) {
|
|
root3.mutableSourceEagerHydrationData = [mutableSource, version];
|
|
} else {
|
|
root3.mutableSourceEagerHydrationData.push(mutableSource, version);
|
|
}
|
|
}
|
|
var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig;
|
|
var didWarnAboutMismatchedHooksForComponent;
|
|
var didWarnUncachedGetSnapshot;
|
|
{
|
|
didWarnAboutMismatchedHooksForComponent = /* @__PURE__ */ new Set();
|
|
}
|
|
var renderLanes = NoLanes;
|
|
var currentlyRenderingFiber$1 = null;
|
|
var currentHook = null;
|
|
var workInProgressHook = null;
|
|
var didScheduleRenderPhaseUpdate = false;
|
|
var didScheduleRenderPhaseUpdateDuringThisPass = false;
|
|
var localIdCounter = 0;
|
|
var globalClientIdCounter = 0;
|
|
var RE_RENDER_LIMIT = 25;
|
|
var currentHookNameInDev = null;
|
|
var hookTypesDev = null;
|
|
var hookTypesUpdateIndexDev = -1;
|
|
var ignorePreviousDependencies = false;
|
|
function mountHookTypesDev() {
|
|
{
|
|
var hookName = currentHookNameInDev;
|
|
if (hookTypesDev === null) {
|
|
hookTypesDev = [hookName];
|
|
} else {
|
|
hookTypesDev.push(hookName);
|
|
}
|
|
}
|
|
}
|
|
function updateHookTypesDev() {
|
|
{
|
|
var hookName = currentHookNameInDev;
|
|
if (hookTypesDev !== null) {
|
|
hookTypesUpdateIndexDev++;
|
|
if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
|
|
warnOnHookMismatchInDev(hookName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function checkDepsAreArrayDev(deps) {
|
|
{
|
|
if (deps !== void 0 && deps !== null && !isArray(deps)) {
|
|
error("%s received a final argument that is not an array (instead, received `%s`). When specified, the final argument must be an array.", currentHookNameInDev, typeof deps);
|
|
}
|
|
}
|
|
}
|
|
function warnOnHookMismatchInDev(currentHookName) {
|
|
{
|
|
var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
|
|
if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
|
|
didWarnAboutMismatchedHooksForComponent.add(componentName);
|
|
if (hookTypesDev !== null) {
|
|
var table = "";
|
|
var secondColumnStart = 30;
|
|
for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
|
|
var oldHookName = hookTypesDev[i];
|
|
var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
|
|
var row = i + 1 + ". " + oldHookName;
|
|
while (row.length < secondColumnStart) {
|
|
row += " ";
|
|
}
|
|
row += newHookName + "\n";
|
|
table += row;
|
|
}
|
|
error("React has detected a change in the order of Hooks called by %s. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n Previous render Next render\n ------------------------------------------------------\n%s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", componentName, table);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function throwInvalidHookError() {
|
|
throw new Error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.");
|
|
}
|
|
function areHookInputsEqual(nextDeps, prevDeps) {
|
|
{
|
|
if (ignorePreviousDependencies) {
|
|
return false;
|
|
}
|
|
}
|
|
if (prevDeps === null) {
|
|
{
|
|
error("%s received a final argument during this render, but not during the previous render. Even though the final argument is optional, its type cannot change between renders.", currentHookNameInDev);
|
|
}
|
|
return false;
|
|
}
|
|
{
|
|
if (nextDeps.length !== prevDeps.length) {
|
|
error("The final argument passed to %s changed size between renders. The order and size of this array must remain constant.\n\nPrevious: %s\nIncoming: %s", currentHookNameInDev, "[" + prevDeps.join(", ") + "]", "[" + nextDeps.join(", ") + "]");
|
|
}
|
|
}
|
|
for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
|
|
if (objectIs(nextDeps[i], prevDeps[i])) {
|
|
continue;
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
function renderWithHooks(current2, workInProgress2, Component, props, secondArg, nextRenderLanes) {
|
|
renderLanes = nextRenderLanes;
|
|
currentlyRenderingFiber$1 = workInProgress2;
|
|
{
|
|
hookTypesDev = current2 !== null ? current2._debugHookTypes : null;
|
|
hookTypesUpdateIndexDev = -1;
|
|
ignorePreviousDependencies = current2 !== null && current2.type !== workInProgress2.type;
|
|
}
|
|
workInProgress2.memoizedState = null;
|
|
workInProgress2.updateQueue = null;
|
|
workInProgress2.lanes = NoLanes;
|
|
{
|
|
if (current2 !== null && current2.memoizedState !== null) {
|
|
ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
|
|
} else if (hookTypesDev !== null) {
|
|
ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
|
|
} else {
|
|
ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
|
|
}
|
|
}
|
|
var children = Component(props, secondArg);
|
|
if (didScheduleRenderPhaseUpdateDuringThisPass) {
|
|
var numberOfReRenders = 0;
|
|
do {
|
|
didScheduleRenderPhaseUpdateDuringThisPass = false;
|
|
localIdCounter = 0;
|
|
if (numberOfReRenders >= RE_RENDER_LIMIT) {
|
|
throw new Error("Too many re-renders. React limits the number of renders to prevent an infinite loop.");
|
|
}
|
|
numberOfReRenders += 1;
|
|
{
|
|
ignorePreviousDependencies = false;
|
|
}
|
|
currentHook = null;
|
|
workInProgressHook = null;
|
|
workInProgress2.updateQueue = null;
|
|
{
|
|
hookTypesUpdateIndexDev = -1;
|
|
}
|
|
ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV;
|
|
children = Component(props, secondArg);
|
|
} while (didScheduleRenderPhaseUpdateDuringThisPass);
|
|
}
|
|
ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
|
|
{
|
|
workInProgress2._debugHookTypes = hookTypesDev;
|
|
}
|
|
var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
|
|
renderLanes = NoLanes;
|
|
currentlyRenderingFiber$1 = null;
|
|
currentHook = null;
|
|
workInProgressHook = null;
|
|
{
|
|
currentHookNameInDev = null;
|
|
hookTypesDev = null;
|
|
hookTypesUpdateIndexDev = -1;
|
|
if (current2 !== null && (current2.flags & StaticMask) !== (workInProgress2.flags & StaticMask) && (current2.mode & ConcurrentMode) !== NoMode) {
|
|
error("Internal React error: Expected static flag was missing. Please notify the React team.");
|
|
}
|
|
}
|
|
didScheduleRenderPhaseUpdate = false;
|
|
if (didRenderTooFewHooks) {
|
|
throw new Error("Rendered fewer hooks than expected. This may be caused by an accidental early return statement.");
|
|
}
|
|
return children;
|
|
}
|
|
function checkDidRenderIdHook() {
|
|
var didRenderIdHook = localIdCounter !== 0;
|
|
localIdCounter = 0;
|
|
return didRenderIdHook;
|
|
}
|
|
function bailoutHooks(current2, workInProgress2, lanes) {
|
|
workInProgress2.updateQueue = current2.updateQueue;
|
|
if ((workInProgress2.mode & StrictEffectsMode) !== NoMode) {
|
|
workInProgress2.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update);
|
|
} else {
|
|
workInProgress2.flags &= ~(Passive | Update);
|
|
}
|
|
current2.lanes = removeLanes(current2.lanes, lanes);
|
|
}
|
|
function resetHooksAfterThrow() {
|
|
ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
|
|
if (didScheduleRenderPhaseUpdate) {
|
|
var hook = currentlyRenderingFiber$1.memoizedState;
|
|
while (hook !== null) {
|
|
var queue = hook.queue;
|
|
if (queue !== null) {
|
|
queue.pending = null;
|
|
}
|
|
hook = hook.next;
|
|
}
|
|
didScheduleRenderPhaseUpdate = false;
|
|
}
|
|
renderLanes = NoLanes;
|
|
currentlyRenderingFiber$1 = null;
|
|
currentHook = null;
|
|
workInProgressHook = null;
|
|
{
|
|
hookTypesDev = null;
|
|
hookTypesUpdateIndexDev = -1;
|
|
currentHookNameInDev = null;
|
|
isUpdatingOpaqueValueInRenderPhase = false;
|
|
}
|
|
didScheduleRenderPhaseUpdateDuringThisPass = false;
|
|
localIdCounter = 0;
|
|
}
|
|
function mountWorkInProgressHook() {
|
|
var hook = {
|
|
memoizedState: null,
|
|
baseState: null,
|
|
baseQueue: null,
|
|
queue: null,
|
|
next: null
|
|
};
|
|
if (workInProgressHook === null) {
|
|
currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
|
|
} else {
|
|
workInProgressHook = workInProgressHook.next = hook;
|
|
}
|
|
return workInProgressHook;
|
|
}
|
|
function updateWorkInProgressHook() {
|
|
var nextCurrentHook;
|
|
if (currentHook === null) {
|
|
var current2 = currentlyRenderingFiber$1.alternate;
|
|
if (current2 !== null) {
|
|
nextCurrentHook = current2.memoizedState;
|
|
} else {
|
|
nextCurrentHook = null;
|
|
}
|
|
} else {
|
|
nextCurrentHook = currentHook.next;
|
|
}
|
|
var nextWorkInProgressHook;
|
|
if (workInProgressHook === null) {
|
|
nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
|
|
} else {
|
|
nextWorkInProgressHook = workInProgressHook.next;
|
|
}
|
|
if (nextWorkInProgressHook !== null) {
|
|
workInProgressHook = nextWorkInProgressHook;
|
|
nextWorkInProgressHook = workInProgressHook.next;
|
|
currentHook = nextCurrentHook;
|
|
} else {
|
|
if (nextCurrentHook === null) {
|
|
throw new Error("Rendered more hooks than during the previous render.");
|
|
}
|
|
currentHook = nextCurrentHook;
|
|
var newHook = {
|
|
memoizedState: currentHook.memoizedState,
|
|
baseState: currentHook.baseState,
|
|
baseQueue: currentHook.baseQueue,
|
|
queue: currentHook.queue,
|
|
next: null
|
|
};
|
|
if (workInProgressHook === null) {
|
|
currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
|
|
} else {
|
|
workInProgressHook = workInProgressHook.next = newHook;
|
|
}
|
|
}
|
|
return workInProgressHook;
|
|
}
|
|
function createFunctionComponentUpdateQueue() {
|
|
return {
|
|
lastEffect: null,
|
|
stores: null
|
|
};
|
|
}
|
|
function basicStateReducer(state, action) {
|
|
return typeof action === "function" ? action(state) : action;
|
|
}
|
|
function mountReducer(reducer, initialArg, init) {
|
|
var hook = mountWorkInProgressHook();
|
|
var initialState;
|
|
if (init !== void 0) {
|
|
initialState = init(initialArg);
|
|
} else {
|
|
initialState = initialArg;
|
|
}
|
|
hook.memoizedState = hook.baseState = initialState;
|
|
var queue = {
|
|
pending: null,
|
|
interleaved: null,
|
|
lanes: NoLanes,
|
|
dispatch: null,
|
|
lastRenderedReducer: reducer,
|
|
lastRenderedState: initialState
|
|
};
|
|
hook.queue = queue;
|
|
var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
|
|
return [hook.memoizedState, dispatch];
|
|
}
|
|
function updateReducer(reducer, initialArg, init) {
|
|
var hook = updateWorkInProgressHook();
|
|
var queue = hook.queue;
|
|
if (queue === null) {
|
|
throw new Error("Should have a queue. This is likely a bug in React. Please file an issue.");
|
|
}
|
|
queue.lastRenderedReducer = reducer;
|
|
var current2 = currentHook;
|
|
var baseQueue = current2.baseQueue;
|
|
var pendingQueue = queue.pending;
|
|
if (pendingQueue !== null) {
|
|
if (baseQueue !== null) {
|
|
var baseFirst = baseQueue.next;
|
|
var pendingFirst = pendingQueue.next;
|
|
baseQueue.next = pendingFirst;
|
|
pendingQueue.next = baseFirst;
|
|
}
|
|
{
|
|
if (current2.baseQueue !== baseQueue) {
|
|
error("Internal error: Expected work-in-progress queue to be a clone. This is a bug in React.");
|
|
}
|
|
}
|
|
current2.baseQueue = baseQueue = pendingQueue;
|
|
queue.pending = null;
|
|
}
|
|
if (baseQueue !== null) {
|
|
var first = baseQueue.next;
|
|
var newState = current2.baseState;
|
|
var newBaseState = null;
|
|
var newBaseQueueFirst = null;
|
|
var newBaseQueueLast = null;
|
|
var update = first;
|
|
do {
|
|
var updateLane = update.lane;
|
|
if (!isSubsetOfLanes(renderLanes, updateLane)) {
|
|
var clone = {
|
|
lane: updateLane,
|
|
action: update.action,
|
|
hasEagerState: update.hasEagerState,
|
|
eagerState: update.eagerState,
|
|
next: null
|
|
};
|
|
if (newBaseQueueLast === null) {
|
|
newBaseQueueFirst = newBaseQueueLast = clone;
|
|
newBaseState = newState;
|
|
} else {
|
|
newBaseQueueLast = newBaseQueueLast.next = clone;
|
|
}
|
|
currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
|
|
markSkippedUpdateLanes(updateLane);
|
|
} else {
|
|
if (newBaseQueueLast !== null) {
|
|
var _clone = {
|
|
lane: NoLane,
|
|
action: update.action,
|
|
hasEagerState: update.hasEagerState,
|
|
eagerState: update.eagerState,
|
|
next: null
|
|
};
|
|
newBaseQueueLast = newBaseQueueLast.next = _clone;
|
|
}
|
|
if (update.hasEagerState) {
|
|
newState = update.eagerState;
|
|
} else {
|
|
var action = update.action;
|
|
newState = reducer(newState, action);
|
|
}
|
|
}
|
|
update = update.next;
|
|
} while (update !== null && update !== first);
|
|
if (newBaseQueueLast === null) {
|
|
newBaseState = newState;
|
|
} else {
|
|
newBaseQueueLast.next = newBaseQueueFirst;
|
|
}
|
|
if (!objectIs(newState, hook.memoizedState)) {
|
|
markWorkInProgressReceivedUpdate();
|
|
}
|
|
hook.memoizedState = newState;
|
|
hook.baseState = newBaseState;
|
|
hook.baseQueue = newBaseQueueLast;
|
|
queue.lastRenderedState = newState;
|
|
}
|
|
var lastInterleaved = queue.interleaved;
|
|
if (lastInterleaved !== null) {
|
|
var interleaved = lastInterleaved;
|
|
do {
|
|
var interleavedLane = interleaved.lane;
|
|
currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
|
|
markSkippedUpdateLanes(interleavedLane);
|
|
interleaved = interleaved.next;
|
|
} while (interleaved !== lastInterleaved);
|
|
} else if (baseQueue === null) {
|
|
queue.lanes = NoLanes;
|
|
}
|
|
var dispatch = queue.dispatch;
|
|
return [hook.memoizedState, dispatch];
|
|
}
|
|
function rerenderReducer(reducer, initialArg, init) {
|
|
var hook = updateWorkInProgressHook();
|
|
var queue = hook.queue;
|
|
if (queue === null) {
|
|
throw new Error("Should have a queue. This is likely a bug in React. Please file an issue.");
|
|
}
|
|
queue.lastRenderedReducer = reducer;
|
|
var dispatch = queue.dispatch;
|
|
var lastRenderPhaseUpdate = queue.pending;
|
|
var newState = hook.memoizedState;
|
|
if (lastRenderPhaseUpdate !== null) {
|
|
queue.pending = null;
|
|
var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
|
|
var update = firstRenderPhaseUpdate;
|
|
do {
|
|
var action = update.action;
|
|
newState = reducer(newState, action);
|
|
update = update.next;
|
|
} while (update !== firstRenderPhaseUpdate);
|
|
if (!objectIs(newState, hook.memoizedState)) {
|
|
markWorkInProgressReceivedUpdate();
|
|
}
|
|
hook.memoizedState = newState;
|
|
if (hook.baseQueue === null) {
|
|
hook.baseState = newState;
|
|
}
|
|
queue.lastRenderedState = newState;
|
|
}
|
|
return [newState, dispatch];
|
|
}
|
|
function mountMutableSource(source, getSnapshot, subscribe) {
|
|
{
|
|
return void 0;
|
|
}
|
|
}
|
|
function updateMutableSource(source, getSnapshot, subscribe) {
|
|
{
|
|
return void 0;
|
|
}
|
|
}
|
|
function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
|
|
var fiber = currentlyRenderingFiber$1;
|
|
var hook = mountWorkInProgressHook();
|
|
var nextSnapshot;
|
|
var isHydrating2 = getIsHydrating();
|
|
if (isHydrating2) {
|
|
if (getServerSnapshot === void 0) {
|
|
throw new Error("Missing getServerSnapshot, which is required for server-rendered content. Will revert to client rendering.");
|
|
}
|
|
nextSnapshot = getServerSnapshot();
|
|
{
|
|
if (!didWarnUncachedGetSnapshot) {
|
|
if (nextSnapshot !== getServerSnapshot()) {
|
|
error("The result of getServerSnapshot should be cached to avoid an infinite loop");
|
|
didWarnUncachedGetSnapshot = true;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
nextSnapshot = getSnapshot();
|
|
{
|
|
if (!didWarnUncachedGetSnapshot) {
|
|
var cachedSnapshot = getSnapshot();
|
|
if (!objectIs(nextSnapshot, cachedSnapshot)) {
|
|
error("The result of getSnapshot should be cached to avoid an infinite loop");
|
|
didWarnUncachedGetSnapshot = true;
|
|
}
|
|
}
|
|
}
|
|
var root3 = getWorkInProgressRoot();
|
|
if (root3 === null) {
|
|
throw new Error("Expected a work-in-progress root. This is a bug in React. Please file an issue.");
|
|
}
|
|
if (!includesBlockingLane(root3, renderLanes)) {
|
|
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
|
}
|
|
}
|
|
hook.memoizedState = nextSnapshot;
|
|
var inst = {
|
|
value: nextSnapshot,
|
|
getSnapshot
|
|
};
|
|
hook.queue = inst;
|
|
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]);
|
|
fiber.flags |= Passive;
|
|
pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), void 0, null);
|
|
return nextSnapshot;
|
|
}
|
|
function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
|
|
var fiber = currentlyRenderingFiber$1;
|
|
var hook = updateWorkInProgressHook();
|
|
var nextSnapshot = getSnapshot();
|
|
{
|
|
if (!didWarnUncachedGetSnapshot) {
|
|
var cachedSnapshot = getSnapshot();
|
|
if (!objectIs(nextSnapshot, cachedSnapshot)) {
|
|
error("The result of getSnapshot should be cached to avoid an infinite loop");
|
|
didWarnUncachedGetSnapshot = true;
|
|
}
|
|
}
|
|
}
|
|
var prevSnapshot = hook.memoizedState;
|
|
var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
|
|
if (snapshotChanged) {
|
|
hook.memoizedState = nextSnapshot;
|
|
markWorkInProgressReceivedUpdate();
|
|
}
|
|
var inst = hook.queue;
|
|
updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]);
|
|
if (inst.getSnapshot !== getSnapshot || snapshotChanged || workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
|
|
fiber.flags |= Passive;
|
|
pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), void 0, null);
|
|
var root3 = getWorkInProgressRoot();
|
|
if (root3 === null) {
|
|
throw new Error("Expected a work-in-progress root. This is a bug in React. Please file an issue.");
|
|
}
|
|
if (!includesBlockingLane(root3, renderLanes)) {
|
|
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
|
}
|
|
}
|
|
return nextSnapshot;
|
|
}
|
|
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
|
fiber.flags |= StoreConsistency;
|
|
var check = {
|
|
getSnapshot,
|
|
value: renderedSnapshot
|
|
};
|
|
var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
|
|
if (componentUpdateQueue === null) {
|
|
componentUpdateQueue = createFunctionComponentUpdateQueue();
|
|
currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
|
|
componentUpdateQueue.stores = [check];
|
|
} else {
|
|
var stores = componentUpdateQueue.stores;
|
|
if (stores === null) {
|
|
componentUpdateQueue.stores = [check];
|
|
} else {
|
|
stores.push(check);
|
|
}
|
|
}
|
|
}
|
|
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
|
inst.value = nextSnapshot;
|
|
inst.getSnapshot = getSnapshot;
|
|
if (checkIfSnapshotChanged(inst)) {
|
|
forceStoreRerender(fiber);
|
|
}
|
|
}
|
|
function subscribeToStore(fiber, inst, subscribe) {
|
|
var handleStoreChange = function() {
|
|
if (checkIfSnapshotChanged(inst)) {
|
|
forceStoreRerender(fiber);
|
|
}
|
|
};
|
|
return subscribe(handleStoreChange);
|
|
}
|
|
function checkIfSnapshotChanged(inst) {
|
|
var latestGetSnapshot = inst.getSnapshot;
|
|
var prevValue = inst.value;
|
|
try {
|
|
var nextValue = latestGetSnapshot();
|
|
return !objectIs(prevValue, nextValue);
|
|
} catch (error2) {
|
|
return true;
|
|
}
|
|
}
|
|
function forceStoreRerender(fiber) {
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
}
|
|
function mountState(initialState) {
|
|
var hook = mountWorkInProgressHook();
|
|
if (typeof initialState === "function") {
|
|
initialState = initialState();
|
|
}
|
|
hook.memoizedState = hook.baseState = initialState;
|
|
var queue = {
|
|
pending: null,
|
|
interleaved: null,
|
|
lanes: NoLanes,
|
|
dispatch: null,
|
|
lastRenderedReducer: basicStateReducer,
|
|
lastRenderedState: initialState
|
|
};
|
|
hook.queue = queue;
|
|
var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
|
|
return [hook.memoizedState, dispatch];
|
|
}
|
|
function updateState(initialState) {
|
|
return updateReducer(basicStateReducer);
|
|
}
|
|
function rerenderState(initialState) {
|
|
return rerenderReducer(basicStateReducer);
|
|
}
|
|
function pushEffect(tag, create, destroy, deps) {
|
|
var effect = {
|
|
tag,
|
|
create,
|
|
destroy,
|
|
deps,
|
|
next: null
|
|
};
|
|
var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
|
|
if (componentUpdateQueue === null) {
|
|
componentUpdateQueue = createFunctionComponentUpdateQueue();
|
|
currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
|
|
componentUpdateQueue.lastEffect = effect.next = effect;
|
|
} else {
|
|
var lastEffect = componentUpdateQueue.lastEffect;
|
|
if (lastEffect === null) {
|
|
componentUpdateQueue.lastEffect = effect.next = effect;
|
|
} else {
|
|
var firstEffect = lastEffect.next;
|
|
lastEffect.next = effect;
|
|
effect.next = firstEffect;
|
|
componentUpdateQueue.lastEffect = effect;
|
|
}
|
|
}
|
|
return effect;
|
|
}
|
|
function mountRef(initialValue) {
|
|
var hook = mountWorkInProgressHook();
|
|
{
|
|
var _ref2 = {
|
|
current: initialValue
|
|
};
|
|
hook.memoizedState = _ref2;
|
|
return _ref2;
|
|
}
|
|
}
|
|
function updateRef(initialValue) {
|
|
var hook = updateWorkInProgressHook();
|
|
return hook.memoizedState;
|
|
}
|
|
function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
|
|
var hook = mountWorkInProgressHook();
|
|
var nextDeps = deps === void 0 ? null : deps;
|
|
currentlyRenderingFiber$1.flags |= fiberFlags;
|
|
hook.memoizedState = pushEffect(HasEffect | hookFlags, create, void 0, nextDeps);
|
|
}
|
|
function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
|
|
var hook = updateWorkInProgressHook();
|
|
var nextDeps = deps === void 0 ? null : deps;
|
|
var destroy = void 0;
|
|
if (currentHook !== null) {
|
|
var prevEffect = currentHook.memoizedState;
|
|
destroy = prevEffect.destroy;
|
|
if (nextDeps !== null) {
|
|
var prevDeps = prevEffect.deps;
|
|
if (areHookInputsEqual(nextDeps, prevDeps)) {
|
|
hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
currentlyRenderingFiber$1.flags |= fiberFlags;
|
|
hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
|
|
}
|
|
function mountEffect(create, deps) {
|
|
if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
|
|
return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps);
|
|
} else {
|
|
return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
|
|
}
|
|
}
|
|
function updateEffect(create, deps) {
|
|
return updateEffectImpl(Passive, Passive$1, create, deps);
|
|
}
|
|
function mountInsertionEffect(create, deps) {
|
|
return mountEffectImpl(Update, Insertion, create, deps);
|
|
}
|
|
function updateInsertionEffect(create, deps) {
|
|
return updateEffectImpl(Update, Insertion, create, deps);
|
|
}
|
|
function mountLayoutEffect(create, deps) {
|
|
var fiberFlags = Update;
|
|
{
|
|
fiberFlags |= LayoutStatic;
|
|
}
|
|
if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
|
|
fiberFlags |= MountLayoutDev;
|
|
}
|
|
return mountEffectImpl(fiberFlags, Layout, create, deps);
|
|
}
|
|
function updateLayoutEffect(create, deps) {
|
|
return updateEffectImpl(Update, Layout, create, deps);
|
|
}
|
|
function imperativeHandleEffect(create, ref) {
|
|
if (typeof ref === "function") {
|
|
var refCallback = ref;
|
|
var _inst = create();
|
|
refCallback(_inst);
|
|
return function() {
|
|
refCallback(null);
|
|
};
|
|
} else if (ref !== null && ref !== void 0) {
|
|
var refObject = ref;
|
|
{
|
|
if (!refObject.hasOwnProperty("current")) {
|
|
error("Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.", "an object with keys {" + Object.keys(refObject).join(", ") + "}");
|
|
}
|
|
}
|
|
var _inst2 = create();
|
|
refObject.current = _inst2;
|
|
return function() {
|
|
refObject.current = null;
|
|
};
|
|
}
|
|
}
|
|
function mountImperativeHandle(ref, create, deps) {
|
|
{
|
|
if (typeof create !== "function") {
|
|
error("Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", create !== null ? typeof create : "null");
|
|
}
|
|
}
|
|
var effectDeps = deps !== null && deps !== void 0 ? deps.concat([ref]) : null;
|
|
var fiberFlags = Update;
|
|
{
|
|
fiberFlags |= LayoutStatic;
|
|
}
|
|
if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
|
|
fiberFlags |= MountLayoutDev;
|
|
}
|
|
return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
|
|
}
|
|
function updateImperativeHandle(ref, create, deps) {
|
|
{
|
|
if (typeof create !== "function") {
|
|
error("Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", create !== null ? typeof create : "null");
|
|
}
|
|
}
|
|
var effectDeps = deps !== null && deps !== void 0 ? deps.concat([ref]) : null;
|
|
return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
|
|
}
|
|
function mountDebugValue(value, formatterFn) {
|
|
}
|
|
var updateDebugValue = mountDebugValue;
|
|
function mountCallback(callback, deps) {
|
|
var hook = mountWorkInProgressHook();
|
|
var nextDeps = deps === void 0 ? null : deps;
|
|
hook.memoizedState = [callback, nextDeps];
|
|
return callback;
|
|
}
|
|
function updateCallback(callback, deps) {
|
|
var hook = updateWorkInProgressHook();
|
|
var nextDeps = deps === void 0 ? null : deps;
|
|
var prevState = hook.memoizedState;
|
|
if (prevState !== null) {
|
|
if (nextDeps !== null) {
|
|
var prevDeps = prevState[1];
|
|
if (areHookInputsEqual(nextDeps, prevDeps)) {
|
|
return prevState[0];
|
|
}
|
|
}
|
|
}
|
|
hook.memoizedState = [callback, nextDeps];
|
|
return callback;
|
|
}
|
|
function mountMemo(nextCreate, deps) {
|
|
var hook = mountWorkInProgressHook();
|
|
var nextDeps = deps === void 0 ? null : deps;
|
|
var nextValue = nextCreate();
|
|
hook.memoizedState = [nextValue, nextDeps];
|
|
return nextValue;
|
|
}
|
|
function updateMemo(nextCreate, deps) {
|
|
var hook = updateWorkInProgressHook();
|
|
var nextDeps = deps === void 0 ? null : deps;
|
|
var prevState = hook.memoizedState;
|
|
if (prevState !== null) {
|
|
if (nextDeps !== null) {
|
|
var prevDeps = prevState[1];
|
|
if (areHookInputsEqual(nextDeps, prevDeps)) {
|
|
return prevState[0];
|
|
}
|
|
}
|
|
}
|
|
var nextValue = nextCreate();
|
|
hook.memoizedState = [nextValue, nextDeps];
|
|
return nextValue;
|
|
}
|
|
function mountDeferredValue(value) {
|
|
var hook = mountWorkInProgressHook();
|
|
hook.memoizedState = value;
|
|
return value;
|
|
}
|
|
function updateDeferredValue(value) {
|
|
var hook = updateWorkInProgressHook();
|
|
var resolvedCurrentHook = currentHook;
|
|
var prevValue = resolvedCurrentHook.memoizedState;
|
|
return updateDeferredValueImpl(hook, prevValue, value);
|
|
}
|
|
function rerenderDeferredValue(value) {
|
|
var hook = updateWorkInProgressHook();
|
|
if (currentHook === null) {
|
|
hook.memoizedState = value;
|
|
return value;
|
|
} else {
|
|
var prevValue = currentHook.memoizedState;
|
|
return updateDeferredValueImpl(hook, prevValue, value);
|
|
}
|
|
}
|
|
function updateDeferredValueImpl(hook, prevValue, value) {
|
|
var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
|
|
if (shouldDeferValue) {
|
|
if (!objectIs(value, prevValue)) {
|
|
var deferredLane = claimNextTransitionLane();
|
|
currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
|
|
markSkippedUpdateLanes(deferredLane);
|
|
hook.baseState = true;
|
|
}
|
|
return prevValue;
|
|
} else {
|
|
if (hook.baseState) {
|
|
hook.baseState = false;
|
|
markWorkInProgressReceivedUpdate();
|
|
}
|
|
hook.memoizedState = value;
|
|
return value;
|
|
}
|
|
}
|
|
function startTransition(setPending, callback, options2) {
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
|
|
setPending(true);
|
|
var prevTransition = ReactCurrentBatchConfig$2.transition;
|
|
ReactCurrentBatchConfig$2.transition = {};
|
|
var currentTransition = ReactCurrentBatchConfig$2.transition;
|
|
{
|
|
ReactCurrentBatchConfig$2.transition._updatedFibers = /* @__PURE__ */ new Set();
|
|
}
|
|
try {
|
|
setPending(false);
|
|
callback();
|
|
} finally {
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig$2.transition = prevTransition;
|
|
{
|
|
if (prevTransition === null && currentTransition._updatedFibers) {
|
|
var updatedFibersCount = currentTransition._updatedFibers.size;
|
|
if (updatedFibersCount > 10) {
|
|
warn("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.");
|
|
}
|
|
currentTransition._updatedFibers.clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function mountTransition() {
|
|
var _mountState = mountState(false), isPending = _mountState[0], setPending = _mountState[1];
|
|
var start = startTransition.bind(null, setPending);
|
|
var hook = mountWorkInProgressHook();
|
|
hook.memoizedState = start;
|
|
return [isPending, start];
|
|
}
|
|
function updateTransition() {
|
|
var _updateState = updateState(), isPending = _updateState[0];
|
|
var hook = updateWorkInProgressHook();
|
|
var start = hook.memoizedState;
|
|
return [isPending, start];
|
|
}
|
|
function rerenderTransition() {
|
|
var _rerenderState = rerenderState(), isPending = _rerenderState[0];
|
|
var hook = updateWorkInProgressHook();
|
|
var start = hook.memoizedState;
|
|
return [isPending, start];
|
|
}
|
|
var isUpdatingOpaqueValueInRenderPhase = false;
|
|
function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
|
|
{
|
|
return isUpdatingOpaqueValueInRenderPhase;
|
|
}
|
|
}
|
|
function mountId() {
|
|
var hook = mountWorkInProgressHook();
|
|
var root3 = getWorkInProgressRoot();
|
|
var identifierPrefix = root3.identifierPrefix;
|
|
var id;
|
|
if (getIsHydrating()) {
|
|
var treeId = getTreeId();
|
|
id = ":" + identifierPrefix + "R" + treeId;
|
|
var localId = localIdCounter++;
|
|
if (localId > 0) {
|
|
id += "H" + localId.toString(32);
|
|
}
|
|
id += ":";
|
|
} else {
|
|
var globalClientId = globalClientIdCounter++;
|
|
id = ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":";
|
|
}
|
|
hook.memoizedState = id;
|
|
return id;
|
|
}
|
|
function updateId() {
|
|
var hook = updateWorkInProgressHook();
|
|
var id = hook.memoizedState;
|
|
return id;
|
|
}
|
|
function dispatchReducerAction(fiber, queue, action) {
|
|
{
|
|
if (typeof arguments[3] === "function") {
|
|
error("State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().");
|
|
}
|
|
}
|
|
var lane = requestUpdateLane(fiber);
|
|
var update = {
|
|
lane,
|
|
action,
|
|
hasEagerState: false,
|
|
eagerState: null,
|
|
next: null
|
|
};
|
|
if (isRenderPhaseUpdate(fiber)) {
|
|
enqueueRenderPhaseUpdate(queue, update);
|
|
} else {
|
|
enqueueUpdate$1(fiber, queue, update);
|
|
var eventTime = requestEventTime();
|
|
var root3 = scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
if (root3 !== null) {
|
|
entangleTransitionUpdate(root3, queue, lane);
|
|
}
|
|
}
|
|
markUpdateInDevTools(fiber, lane);
|
|
}
|
|
function dispatchSetState(fiber, queue, action) {
|
|
{
|
|
if (typeof arguments[3] === "function") {
|
|
error("State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().");
|
|
}
|
|
}
|
|
var lane = requestUpdateLane(fiber);
|
|
var update = {
|
|
lane,
|
|
action,
|
|
hasEagerState: false,
|
|
eagerState: null,
|
|
next: null
|
|
};
|
|
if (isRenderPhaseUpdate(fiber)) {
|
|
enqueueRenderPhaseUpdate(queue, update);
|
|
} else {
|
|
enqueueUpdate$1(fiber, queue, update);
|
|
var alternate = fiber.alternate;
|
|
if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
|
|
var lastRenderedReducer = queue.lastRenderedReducer;
|
|
if (lastRenderedReducer !== null) {
|
|
var prevDispatcher;
|
|
{
|
|
prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
}
|
|
try {
|
|
var currentState = queue.lastRenderedState;
|
|
var eagerState = lastRenderedReducer(currentState, action);
|
|
update.hasEagerState = true;
|
|
update.eagerState = eagerState;
|
|
if (objectIs(eagerState, currentState)) {
|
|
return;
|
|
}
|
|
} catch (error2) {
|
|
} finally {
|
|
{
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var eventTime = requestEventTime();
|
|
var root3 = scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
if (root3 !== null) {
|
|
entangleTransitionUpdate(root3, queue, lane);
|
|
}
|
|
}
|
|
markUpdateInDevTools(fiber, lane);
|
|
}
|
|
function isRenderPhaseUpdate(fiber) {
|
|
var alternate = fiber.alternate;
|
|
return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
|
|
}
|
|
function enqueueRenderPhaseUpdate(queue, update) {
|
|
didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
|
|
var pending = queue.pending;
|
|
if (pending === null) {
|
|
update.next = update;
|
|
} else {
|
|
update.next = pending.next;
|
|
pending.next = update;
|
|
}
|
|
queue.pending = update;
|
|
}
|
|
function enqueueUpdate$1(fiber, queue, update, lane) {
|
|
if (isInterleavedUpdate(fiber)) {
|
|
var interleaved = queue.interleaved;
|
|
if (interleaved === null) {
|
|
update.next = update;
|
|
pushInterleavedQueue(queue);
|
|
} else {
|
|
update.next = interleaved.next;
|
|
interleaved.next = update;
|
|
}
|
|
queue.interleaved = update;
|
|
} else {
|
|
var pending = queue.pending;
|
|
if (pending === null) {
|
|
update.next = update;
|
|
} else {
|
|
update.next = pending.next;
|
|
pending.next = update;
|
|
}
|
|
queue.pending = update;
|
|
}
|
|
}
|
|
function entangleTransitionUpdate(root3, queue, lane) {
|
|
if (isTransitionLane(lane)) {
|
|
var queueLanes = queue.lanes;
|
|
queueLanes = intersectLanes(queueLanes, root3.pendingLanes);
|
|
var newQueueLanes = mergeLanes(queueLanes, lane);
|
|
queue.lanes = newQueueLanes;
|
|
markRootEntangled(root3, newQueueLanes);
|
|
}
|
|
}
|
|
function markUpdateInDevTools(fiber, lane, action) {
|
|
{
|
|
markStateUpdateScheduled(fiber, lane);
|
|
}
|
|
}
|
|
var ContextOnlyDispatcher = {
|
|
readContext,
|
|
useCallback: throwInvalidHookError,
|
|
useContext: throwInvalidHookError,
|
|
useEffect: throwInvalidHookError,
|
|
useImperativeHandle: throwInvalidHookError,
|
|
useInsertionEffect: throwInvalidHookError,
|
|
useLayoutEffect: throwInvalidHookError,
|
|
useMemo: throwInvalidHookError,
|
|
useReducer: throwInvalidHookError,
|
|
useRef: throwInvalidHookError,
|
|
useState: throwInvalidHookError,
|
|
useDebugValue: throwInvalidHookError,
|
|
useDeferredValue: throwInvalidHookError,
|
|
useTransition: throwInvalidHookError,
|
|
useMutableSource: throwInvalidHookError,
|
|
useSyncExternalStore: throwInvalidHookError,
|
|
useId: throwInvalidHookError,
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
var HooksDispatcherOnMountInDEV = null;
|
|
var HooksDispatcherOnMountWithHookTypesInDEV = null;
|
|
var HooksDispatcherOnUpdateInDEV = null;
|
|
var HooksDispatcherOnRerenderInDEV = null;
|
|
var InvalidNestedHooksDispatcherOnMountInDEV = null;
|
|
var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
|
|
var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|
{
|
|
var warnInvalidContextAccess = function() {
|
|
error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
|
|
};
|
|
var warnInvalidHookAccess = function() {
|
|
error("Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://reactjs.org/link/rules-of-hooks");
|
|
};
|
|
HooksDispatcherOnMountInDEV = {
|
|
readContext: function(context) {
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
mountHookTypesDev();
|
|
checkDepsAreArrayDev(deps);
|
|
return mountCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
mountHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
mountHookTypesDev();
|
|
checkDepsAreArrayDev(deps);
|
|
return mountEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
mountHookTypesDev();
|
|
checkDepsAreArrayDev(deps);
|
|
return mountImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
mountHookTypesDev();
|
|
checkDepsAreArrayDev(deps);
|
|
return mountInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
mountHookTypesDev();
|
|
checkDepsAreArrayDev(deps);
|
|
return mountLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
mountHookTypesDev();
|
|
checkDepsAreArrayDev(deps);
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
mountHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
mountHookTypesDev();
|
|
return mountRef(initialValue);
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
mountHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
mountHookTypesDev();
|
|
return mountDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
mountHookTypesDev();
|
|
return mountDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
mountHookTypesDev();
|
|
return mountTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
mountHookTypesDev();
|
|
return mountMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
mountHookTypesDev();
|
|
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
mountHookTypesDev();
|
|
return mountId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
HooksDispatcherOnMountWithHookTypesInDEV = {
|
|
readContext: function(context) {
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
updateHookTypesDev();
|
|
return mountCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
updateHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
updateHookTypesDev();
|
|
return mountEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
updateHookTypesDev();
|
|
return mountImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
updateHookTypesDev();
|
|
return mountInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
updateHookTypesDev();
|
|
return mountLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
updateHookTypesDev();
|
|
return mountRef(initialValue);
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
updateHookTypesDev();
|
|
return mountDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
updateHookTypesDev();
|
|
return mountDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
updateHookTypesDev();
|
|
return mountTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
updateHookTypesDev();
|
|
return mountMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
updateHookTypesDev();
|
|
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
updateHookTypesDev();
|
|
return mountId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
HooksDispatcherOnUpdateInDEV = {
|
|
readContext: function(context) {
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
updateHookTypesDev();
|
|
return updateCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
updateHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
updateHookTypesDev();
|
|
return updateEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
updateHookTypesDev();
|
|
return updateImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
updateHookTypesDev();
|
|
return updateInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
updateHookTypesDev();
|
|
return updateLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
updateHookTypesDev();
|
|
return updateRef();
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
updateHookTypesDev();
|
|
return updateDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
updateHookTypesDev();
|
|
return updateDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
updateHookTypesDev();
|
|
return updateTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
updateHookTypesDev();
|
|
return updateMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
updateHookTypesDev();
|
|
return updateSyncExternalStore(subscribe, getSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
updateHookTypesDev();
|
|
return updateId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
HooksDispatcherOnRerenderInDEV = {
|
|
readContext: function(context) {
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
updateHookTypesDev();
|
|
return updateCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
updateHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
updateHookTypesDev();
|
|
return updateEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
updateHookTypesDev();
|
|
return updateImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
updateHookTypesDev();
|
|
return updateInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
updateHookTypesDev();
|
|
return updateLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
|
|
try {
|
|
return updateMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
|
|
try {
|
|
return rerenderReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
updateHookTypesDev();
|
|
return updateRef();
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
|
|
try {
|
|
return rerenderState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
updateHookTypesDev();
|
|
return updateDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
updateHookTypesDev();
|
|
return rerenderDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
updateHookTypesDev();
|
|
return rerenderTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
updateHookTypesDev();
|
|
return updateMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
updateHookTypesDev();
|
|
return updateSyncExternalStore(subscribe, getSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
updateHookTypesDev();
|
|
return updateId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
InvalidNestedHooksDispatcherOnMountInDEV = {
|
|
readContext: function(context) {
|
|
warnInvalidContextAccess();
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountRef(initialValue);
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
try {
|
|
return mountState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
warnInvalidHookAccess();
|
|
mountHookTypesDev();
|
|
return mountId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
InvalidNestedHooksDispatcherOnUpdateInDEV = {
|
|
readContext: function(context) {
|
|
warnInvalidContextAccess();
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateRef();
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateSyncExternalStore(subscribe, getSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
InvalidNestedHooksDispatcherOnRerenderInDEV = {
|
|
readContext: function(context) {
|
|
warnInvalidContextAccess();
|
|
return readContext(context);
|
|
},
|
|
useCallback: function(callback, deps) {
|
|
currentHookNameInDev = "useCallback";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateCallback(callback, deps);
|
|
},
|
|
useContext: function(context) {
|
|
currentHookNameInDev = "useContext";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return readContext(context);
|
|
},
|
|
useEffect: function(create, deps) {
|
|
currentHookNameInDev = "useEffect";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateEffect(create, deps);
|
|
},
|
|
useImperativeHandle: function(ref, create, deps) {
|
|
currentHookNameInDev = "useImperativeHandle";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateImperativeHandle(ref, create, deps);
|
|
},
|
|
useInsertionEffect: function(create, deps) {
|
|
currentHookNameInDev = "useInsertionEffect";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateInsertionEffect(create, deps);
|
|
},
|
|
useLayoutEffect: function(create, deps) {
|
|
currentHookNameInDev = "useLayoutEffect";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateLayoutEffect(create, deps);
|
|
},
|
|
useMemo: function(create, deps) {
|
|
currentHookNameInDev = "useMemo";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return updateMemo(create, deps);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useReducer: function(reducer, initialArg, init) {
|
|
currentHookNameInDev = "useReducer";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return rerenderReducer(reducer, initialArg, init);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useRef: function(initialValue) {
|
|
currentHookNameInDev = "useRef";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateRef();
|
|
},
|
|
useState: function(initialState) {
|
|
currentHookNameInDev = "useState";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
try {
|
|
return rerenderState(initialState);
|
|
} finally {
|
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
}
|
|
},
|
|
useDebugValue: function(value, formatterFn) {
|
|
currentHookNameInDev = "useDebugValue";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateDebugValue();
|
|
},
|
|
useDeferredValue: function(value) {
|
|
currentHookNameInDev = "useDeferredValue";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return rerenderDeferredValue(value);
|
|
},
|
|
useTransition: function() {
|
|
currentHookNameInDev = "useTransition";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return rerenderTransition();
|
|
},
|
|
useMutableSource: function(source, getSnapshot, subscribe) {
|
|
currentHookNameInDev = "useMutableSource";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateMutableSource();
|
|
},
|
|
useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
|
|
currentHookNameInDev = "useSyncExternalStore";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateSyncExternalStore(subscribe, getSnapshot);
|
|
},
|
|
useId: function() {
|
|
currentHookNameInDev = "useId";
|
|
warnInvalidHookAccess();
|
|
updateHookTypesDev();
|
|
return updateId();
|
|
},
|
|
unstable_isNewReconciler: enableNewReconciler
|
|
};
|
|
}
|
|
var now$1 = Scheduler.unstable_now;
|
|
var commitTime = 0;
|
|
var layoutEffectStartTime = -1;
|
|
var profilerStartTime = -1;
|
|
var passiveEffectStartTime = -1;
|
|
var currentUpdateIsNested = false;
|
|
var nestedUpdateScheduled = false;
|
|
function isCurrentUpdateNested() {
|
|
return currentUpdateIsNested;
|
|
}
|
|
function markNestedUpdateScheduled() {
|
|
{
|
|
nestedUpdateScheduled = true;
|
|
}
|
|
}
|
|
function resetNestedUpdateFlag() {
|
|
{
|
|
currentUpdateIsNested = false;
|
|
nestedUpdateScheduled = false;
|
|
}
|
|
}
|
|
function syncNestedUpdateFlag() {
|
|
{
|
|
currentUpdateIsNested = nestedUpdateScheduled;
|
|
nestedUpdateScheduled = false;
|
|
}
|
|
}
|
|
function getCommitTime() {
|
|
return commitTime;
|
|
}
|
|
function recordCommitTime() {
|
|
commitTime = now$1();
|
|
}
|
|
function startProfilerTimer(fiber) {
|
|
profilerStartTime = now$1();
|
|
if (fiber.actualStartTime < 0) {
|
|
fiber.actualStartTime = now$1();
|
|
}
|
|
}
|
|
function stopProfilerTimerIfRunning(fiber) {
|
|
profilerStartTime = -1;
|
|
}
|
|
function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
|
|
if (profilerStartTime >= 0) {
|
|
var elapsedTime = now$1() - profilerStartTime;
|
|
fiber.actualDuration += elapsedTime;
|
|
if (overrideBaseTime) {
|
|
fiber.selfBaseDuration = elapsedTime;
|
|
}
|
|
profilerStartTime = -1;
|
|
}
|
|
}
|
|
function recordLayoutEffectDuration(fiber) {
|
|
if (layoutEffectStartTime >= 0) {
|
|
var elapsedTime = now$1() - layoutEffectStartTime;
|
|
layoutEffectStartTime = -1;
|
|
var parentFiber = fiber.return;
|
|
while (parentFiber !== null) {
|
|
switch (parentFiber.tag) {
|
|
case HostRoot:
|
|
var root3 = parentFiber.stateNode;
|
|
root3.effectDuration += elapsedTime;
|
|
return;
|
|
case Profiler:
|
|
var parentStateNode = parentFiber.stateNode;
|
|
parentStateNode.effectDuration += elapsedTime;
|
|
return;
|
|
}
|
|
parentFiber = parentFiber.return;
|
|
}
|
|
}
|
|
}
|
|
function recordPassiveEffectDuration(fiber) {
|
|
if (passiveEffectStartTime >= 0) {
|
|
var elapsedTime = now$1() - passiveEffectStartTime;
|
|
passiveEffectStartTime = -1;
|
|
var parentFiber = fiber.return;
|
|
while (parentFiber !== null) {
|
|
switch (parentFiber.tag) {
|
|
case HostRoot:
|
|
var root3 = parentFiber.stateNode;
|
|
if (root3 !== null) {
|
|
root3.passiveEffectDuration += elapsedTime;
|
|
}
|
|
return;
|
|
case Profiler:
|
|
var parentStateNode = parentFiber.stateNode;
|
|
if (parentStateNode !== null) {
|
|
parentStateNode.passiveEffectDuration += elapsedTime;
|
|
}
|
|
return;
|
|
}
|
|
parentFiber = parentFiber.return;
|
|
}
|
|
}
|
|
}
|
|
function startLayoutEffectTimer() {
|
|
layoutEffectStartTime = now$1();
|
|
}
|
|
function startPassiveEffectTimer() {
|
|
passiveEffectStartTime = now$1();
|
|
}
|
|
function transferActualDuration(fiber) {
|
|
var child = fiber.child;
|
|
while (child) {
|
|
fiber.actualDuration += child.actualDuration;
|
|
child = child.sibling;
|
|
}
|
|
}
|
|
function createCapturedValue(value, source) {
|
|
return {
|
|
value,
|
|
source,
|
|
stack: getStackByFiberInDevAndProd(source)
|
|
};
|
|
}
|
|
function showErrorDialog(boundary, errorInfo) {
|
|
return true;
|
|
}
|
|
function logCapturedError(boundary, errorInfo) {
|
|
try {
|
|
var logError = showErrorDialog(boundary, errorInfo);
|
|
if (logError === false) {
|
|
return;
|
|
}
|
|
var error2 = errorInfo.value;
|
|
if (true) {
|
|
var source = errorInfo.source;
|
|
var stack = errorInfo.stack;
|
|
var componentStack = stack !== null ? stack : "";
|
|
if (error2 != null && error2._suppressLogging) {
|
|
if (boundary.tag === ClassComponent) {
|
|
return;
|
|
}
|
|
console["error"](error2);
|
|
}
|
|
var componentName = source ? getComponentNameFromFiber(source) : null;
|
|
var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : "The above error occurred in one of your React components:";
|
|
var errorBoundaryMessage;
|
|
if (boundary.tag === HostRoot) {
|
|
errorBoundaryMessage = "Consider adding an error boundary to your tree to customize error handling behavior.\nVisit https://reactjs.org/link/error-boundaries to learn more about error boundaries.";
|
|
} else {
|
|
var errorBoundaryName = getComponentNameFromFiber(boundary) || "Anonymous";
|
|
errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
|
|
}
|
|
var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage);
|
|
console["error"](combinedMessage);
|
|
} else {
|
|
console["error"](error2);
|
|
}
|
|
} catch (e) {
|
|
setTimeout(function() {
|
|
throw e;
|
|
});
|
|
}
|
|
}
|
|
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
|
|
function createRootErrorUpdate(fiber, errorInfo, lane) {
|
|
var update = createUpdate(NoTimestamp, lane);
|
|
update.tag = CaptureUpdate;
|
|
update.payload = {
|
|
element: null
|
|
};
|
|
var error2 = errorInfo.value;
|
|
update.callback = function() {
|
|
onUncaughtError(error2);
|
|
logCapturedError(fiber, errorInfo);
|
|
};
|
|
return update;
|
|
}
|
|
function createClassErrorUpdate(fiber, errorInfo, lane) {
|
|
var update = createUpdate(NoTimestamp, lane);
|
|
update.tag = CaptureUpdate;
|
|
var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
|
|
if (typeof getDerivedStateFromError === "function") {
|
|
var error$1 = errorInfo.value;
|
|
update.payload = function() {
|
|
return getDerivedStateFromError(error$1);
|
|
};
|
|
update.callback = function() {
|
|
{
|
|
markFailedErrorBoundaryForHotReloading(fiber);
|
|
}
|
|
logCapturedError(fiber, errorInfo);
|
|
};
|
|
}
|
|
var inst = fiber.stateNode;
|
|
if (inst !== null && typeof inst.componentDidCatch === "function") {
|
|
update.callback = function callback() {
|
|
{
|
|
markFailedErrorBoundaryForHotReloading(fiber);
|
|
}
|
|
logCapturedError(fiber, errorInfo);
|
|
if (typeof getDerivedStateFromError !== "function") {
|
|
markLegacyErrorBoundaryAsFailed(this);
|
|
}
|
|
var error$12 = errorInfo.value;
|
|
var stack = errorInfo.stack;
|
|
this.componentDidCatch(error$12, {
|
|
componentStack: stack !== null ? stack : ""
|
|
});
|
|
{
|
|
if (typeof getDerivedStateFromError !== "function") {
|
|
if (!includesSomeLane(fiber.lanes, SyncLane)) {
|
|
error("%s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.", getComponentNameFromFiber(fiber) || "Unknown");
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
return update;
|
|
}
|
|
function attachPingListener(root3, wakeable, lanes) {
|
|
var pingCache = root3.pingCache;
|
|
var threadIDs;
|
|
if (pingCache === null) {
|
|
pingCache = root3.pingCache = new PossiblyWeakMap$1();
|
|
threadIDs = /* @__PURE__ */ new Set();
|
|
pingCache.set(wakeable, threadIDs);
|
|
} else {
|
|
threadIDs = pingCache.get(wakeable);
|
|
if (threadIDs === void 0) {
|
|
threadIDs = /* @__PURE__ */ new Set();
|
|
pingCache.set(wakeable, threadIDs);
|
|
}
|
|
}
|
|
if (!threadIDs.has(lanes)) {
|
|
threadIDs.add(lanes);
|
|
var ping = pingSuspendedRoot.bind(null, root3, wakeable, lanes);
|
|
{
|
|
if (isDevToolsPresent) {
|
|
restorePendingUpdaters(root3, lanes);
|
|
}
|
|
}
|
|
wakeable.then(ping, ping);
|
|
}
|
|
}
|
|
function attachRetryListener(suspenseBoundary, root3, wakeable, lanes) {
|
|
var wakeables = suspenseBoundary.updateQueue;
|
|
if (wakeables === null) {
|
|
var updateQueue = /* @__PURE__ */ new Set();
|
|
updateQueue.add(wakeable);
|
|
suspenseBoundary.updateQueue = updateQueue;
|
|
} else {
|
|
wakeables.add(wakeable);
|
|
}
|
|
}
|
|
function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
|
|
var tag = sourceFiber.tag;
|
|
if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
|
|
var currentSource = sourceFiber.alternate;
|
|
if (currentSource) {
|
|
sourceFiber.updateQueue = currentSource.updateQueue;
|
|
sourceFiber.memoizedState = currentSource.memoizedState;
|
|
sourceFiber.lanes = currentSource.lanes;
|
|
} else {
|
|
sourceFiber.updateQueue = null;
|
|
sourceFiber.memoizedState = null;
|
|
}
|
|
}
|
|
}
|
|
function getNearestSuspenseBoundaryToCapture(returnFiber) {
|
|
var node = returnFiber;
|
|
do {
|
|
if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) {
|
|
return node;
|
|
}
|
|
node = node.return;
|
|
} while (node !== null);
|
|
return null;
|
|
}
|
|
function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root3, rootRenderLanes) {
|
|
if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
|
|
if (suspenseBoundary === returnFiber) {
|
|
suspenseBoundary.flags |= ShouldCapture;
|
|
} else {
|
|
suspenseBoundary.flags |= DidCapture;
|
|
sourceFiber.flags |= ForceUpdateForLegacySuspense;
|
|
sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
|
|
if (sourceFiber.tag === ClassComponent) {
|
|
var currentSourceFiber = sourceFiber.alternate;
|
|
if (currentSourceFiber === null) {
|
|
sourceFiber.tag = IncompleteClassComponent;
|
|
} else {
|
|
var update = createUpdate(NoTimestamp, SyncLane);
|
|
update.tag = ForceUpdate;
|
|
enqueueUpdate(sourceFiber, update);
|
|
}
|
|
}
|
|
sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
|
|
}
|
|
return suspenseBoundary;
|
|
}
|
|
suspenseBoundary.flags |= ShouldCapture;
|
|
suspenseBoundary.lanes = rootRenderLanes;
|
|
return suspenseBoundary;
|
|
}
|
|
function throwException(root3, returnFiber, sourceFiber, value, rootRenderLanes) {
|
|
sourceFiber.flags |= Incomplete;
|
|
{
|
|
if (isDevToolsPresent) {
|
|
restorePendingUpdaters(root3, rootRenderLanes);
|
|
}
|
|
}
|
|
if (value !== null && typeof value === "object" && typeof value.then === "function") {
|
|
var wakeable = value;
|
|
resetSuspendedComponent(sourceFiber);
|
|
{
|
|
if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
|
|
markDidThrowWhileHydratingDEV();
|
|
}
|
|
}
|
|
var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
|
|
if (suspenseBoundary !== null) {
|
|
suspenseBoundary.flags &= ~ForceClientRender;
|
|
markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root3, rootRenderLanes);
|
|
if (suspenseBoundary.mode & ConcurrentMode) {
|
|
attachPingListener(root3, wakeable, rootRenderLanes);
|
|
}
|
|
attachRetryListener(suspenseBoundary, root3, wakeable);
|
|
return;
|
|
} else {
|
|
if (!includesSyncLane(rootRenderLanes)) {
|
|
attachPingListener(root3, wakeable, rootRenderLanes);
|
|
renderDidSuspendDelayIfPossible();
|
|
return;
|
|
}
|
|
var uncaughtSuspenseError = new Error("A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.");
|
|
value = uncaughtSuspenseError;
|
|
}
|
|
} else {
|
|
if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
|
|
markDidThrowWhileHydratingDEV();
|
|
var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
|
|
if (_suspenseBoundary !== null) {
|
|
if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) {
|
|
_suspenseBoundary.flags |= ForceClientRender;
|
|
}
|
|
markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root3, rootRenderLanes);
|
|
queueHydrationError(value);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
renderDidError(value);
|
|
value = createCapturedValue(value, sourceFiber);
|
|
var workInProgress2 = returnFiber;
|
|
do {
|
|
switch (workInProgress2.tag) {
|
|
case HostRoot: {
|
|
var _errorInfo = value;
|
|
workInProgress2.flags |= ShouldCapture;
|
|
var lane = pickArbitraryLane(rootRenderLanes);
|
|
workInProgress2.lanes = mergeLanes(workInProgress2.lanes, lane);
|
|
var update = createRootErrorUpdate(workInProgress2, _errorInfo, lane);
|
|
enqueueCapturedUpdate(workInProgress2, update);
|
|
return;
|
|
}
|
|
case ClassComponent:
|
|
var errorInfo = value;
|
|
var ctor = workInProgress2.type;
|
|
var instance = workInProgress2.stateNode;
|
|
if ((workInProgress2.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === "function" || instance !== null && typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance))) {
|
|
workInProgress2.flags |= ShouldCapture;
|
|
var _lane = pickArbitraryLane(rootRenderLanes);
|
|
workInProgress2.lanes = mergeLanes(workInProgress2.lanes, _lane);
|
|
var _update = createClassErrorUpdate(workInProgress2, errorInfo, _lane);
|
|
enqueueCapturedUpdate(workInProgress2, _update);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
workInProgress2 = workInProgress2.return;
|
|
} while (workInProgress2 !== null);
|
|
}
|
|
function getSuspendedCache() {
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
function markUpdate(workInProgress2) {
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
function markRef(workInProgress2) {
|
|
workInProgress2.flags |= Ref;
|
|
{
|
|
workInProgress2.flags |= RefStatic;
|
|
}
|
|
}
|
|
var appendAllChildren;
|
|
var updateHostContainer;
|
|
var updateHostComponent;
|
|
var updateHostText;
|
|
{
|
|
appendAllChildren = function(parent, workInProgress2, needsVisibilityToggle, isHidden) {
|
|
var node = workInProgress2.child;
|
|
while (node !== null) {
|
|
if (node.tag === HostComponent || node.tag === HostText) {
|
|
appendInitialChild(parent, node.stateNode);
|
|
} else if (node.tag === HostPortal)
|
|
;
|
|
else if (node.child !== null) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === workInProgress2) {
|
|
return;
|
|
}
|
|
while (node.sibling === null) {
|
|
if (node.return === null || node.return === workInProgress2) {
|
|
return;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
};
|
|
updateHostContainer = function(current2, workInProgress2) {
|
|
};
|
|
updateHostComponent = function(current2, workInProgress2, type, newProps, rootContainerInstance) {
|
|
var oldProps = current2.memoizedProps;
|
|
if (oldProps === newProps) {
|
|
return;
|
|
}
|
|
var instance = workInProgress2.stateNode;
|
|
var currentHostContext = getHostContext();
|
|
var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
|
|
workInProgress2.updateQueue = updatePayload;
|
|
if (updatePayload) {
|
|
markUpdate(workInProgress2);
|
|
}
|
|
};
|
|
updateHostText = function(current2, workInProgress2, oldText, newText) {
|
|
if (oldText !== newText) {
|
|
markUpdate(workInProgress2);
|
|
}
|
|
};
|
|
}
|
|
function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
|
|
if (getIsHydrating()) {
|
|
return;
|
|
}
|
|
switch (renderState.tailMode) {
|
|
case "hidden": {
|
|
var tailNode = renderState.tail;
|
|
var lastTailNode = null;
|
|
while (tailNode !== null) {
|
|
if (tailNode.alternate !== null) {
|
|
lastTailNode = tailNode;
|
|
}
|
|
tailNode = tailNode.sibling;
|
|
}
|
|
if (lastTailNode === null) {
|
|
renderState.tail = null;
|
|
} else {
|
|
lastTailNode.sibling = null;
|
|
}
|
|
break;
|
|
}
|
|
case "collapsed": {
|
|
var _tailNode = renderState.tail;
|
|
var _lastTailNode = null;
|
|
while (_tailNode !== null) {
|
|
if (_tailNode.alternate !== null) {
|
|
_lastTailNode = _tailNode;
|
|
}
|
|
_tailNode = _tailNode.sibling;
|
|
}
|
|
if (_lastTailNode === null) {
|
|
if (!hasRenderedATailFallback && renderState.tail !== null) {
|
|
renderState.tail.sibling = null;
|
|
} else {
|
|
renderState.tail = null;
|
|
}
|
|
} else {
|
|
_lastTailNode.sibling = null;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function bubbleProperties(completedWork) {
|
|
var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
|
|
var newChildLanes = NoLanes;
|
|
var subtreeFlags = NoFlags;
|
|
if (!didBailout) {
|
|
if ((completedWork.mode & ProfileMode) !== NoMode) {
|
|
var actualDuration = completedWork.actualDuration;
|
|
var treeBaseDuration = completedWork.selfBaseDuration;
|
|
var child = completedWork.child;
|
|
while (child !== null) {
|
|
newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
|
|
subtreeFlags |= child.subtreeFlags;
|
|
subtreeFlags |= child.flags;
|
|
actualDuration += child.actualDuration;
|
|
treeBaseDuration += child.treeBaseDuration;
|
|
child = child.sibling;
|
|
}
|
|
completedWork.actualDuration = actualDuration;
|
|
completedWork.treeBaseDuration = treeBaseDuration;
|
|
} else {
|
|
var _child = completedWork.child;
|
|
while (_child !== null) {
|
|
newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
|
|
subtreeFlags |= _child.subtreeFlags;
|
|
subtreeFlags |= _child.flags;
|
|
_child.return = completedWork;
|
|
_child = _child.sibling;
|
|
}
|
|
}
|
|
completedWork.subtreeFlags |= subtreeFlags;
|
|
} else {
|
|
if ((completedWork.mode & ProfileMode) !== NoMode) {
|
|
var _treeBaseDuration = completedWork.selfBaseDuration;
|
|
var _child2 = completedWork.child;
|
|
while (_child2 !== null) {
|
|
newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes));
|
|
subtreeFlags |= _child2.subtreeFlags & StaticMask;
|
|
subtreeFlags |= _child2.flags & StaticMask;
|
|
_treeBaseDuration += _child2.treeBaseDuration;
|
|
_child2 = _child2.sibling;
|
|
}
|
|
completedWork.treeBaseDuration = _treeBaseDuration;
|
|
} else {
|
|
var _child3 = completedWork.child;
|
|
while (_child3 !== null) {
|
|
newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes));
|
|
subtreeFlags |= _child3.subtreeFlags & StaticMask;
|
|
subtreeFlags |= _child3.flags & StaticMask;
|
|
_child3.return = completedWork;
|
|
_child3 = _child3.sibling;
|
|
}
|
|
}
|
|
completedWork.subtreeFlags |= subtreeFlags;
|
|
}
|
|
completedWork.childLanes = newChildLanes;
|
|
return didBailout;
|
|
}
|
|
function completeWork(current2, workInProgress2, renderLanes2) {
|
|
var newProps = workInProgress2.pendingProps;
|
|
popTreeContext(workInProgress2);
|
|
switch (workInProgress2.tag) {
|
|
case IndeterminateComponent:
|
|
case LazyComponent:
|
|
case SimpleMemoComponent:
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case Fragment2:
|
|
case Mode:
|
|
case Profiler:
|
|
case ContextConsumer:
|
|
case MemoComponent:
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
case ClassComponent: {
|
|
var Component = workInProgress2.type;
|
|
if (isContextProvider(Component)) {
|
|
popContext(workInProgress2);
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
case HostRoot: {
|
|
var fiberRoot = workInProgress2.stateNode;
|
|
popHostContainer(workInProgress2);
|
|
popTopLevelContextObject(workInProgress2);
|
|
resetWorkInProgressVersions();
|
|
if (fiberRoot.pendingContext) {
|
|
fiberRoot.context = fiberRoot.pendingContext;
|
|
fiberRoot.pendingContext = null;
|
|
}
|
|
if (current2 === null || current2.child === null) {
|
|
var wasHydrated = popHydrationState(workInProgress2);
|
|
if (wasHydrated) {
|
|
markUpdate(workInProgress2);
|
|
} else {
|
|
if (current2 !== null) {
|
|
var prevState = current2.memoizedState;
|
|
if (!prevState.isDehydrated || (workInProgress2.flags & ForceClientRender) !== NoFlags) {
|
|
workInProgress2.flags |= Snapshot;
|
|
upgradeHydrationErrorsToRecoverable();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
updateHostContainer(current2, workInProgress2);
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
case HostComponent: {
|
|
popHostContext(workInProgress2);
|
|
var rootContainerInstance = getRootHostContainer();
|
|
var type = workInProgress2.type;
|
|
if (current2 !== null && workInProgress2.stateNode != null) {
|
|
updateHostComponent(current2, workInProgress2, type, newProps, rootContainerInstance);
|
|
if (current2.ref !== workInProgress2.ref) {
|
|
markRef(workInProgress2);
|
|
}
|
|
} else {
|
|
if (!newProps) {
|
|
if (workInProgress2.stateNode === null) {
|
|
throw new Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
var currentHostContext = getHostContext();
|
|
var _wasHydrated = popHydrationState(workInProgress2);
|
|
if (_wasHydrated) {
|
|
if (prepareToHydrateHostInstance(workInProgress2, rootContainerInstance, currentHostContext)) {
|
|
markUpdate(workInProgress2);
|
|
}
|
|
} else {
|
|
var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress2);
|
|
appendAllChildren(instance, workInProgress2, false, false);
|
|
workInProgress2.stateNode = instance;
|
|
if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
|
|
markUpdate(workInProgress2);
|
|
}
|
|
}
|
|
if (workInProgress2.ref !== null) {
|
|
markRef(workInProgress2);
|
|
}
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
case HostText: {
|
|
var newText = newProps;
|
|
if (current2 && workInProgress2.stateNode != null) {
|
|
var oldText = current2.memoizedProps;
|
|
updateHostText(current2, workInProgress2, oldText, newText);
|
|
} else {
|
|
if (typeof newText !== "string") {
|
|
if (workInProgress2.stateNode === null) {
|
|
throw new Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
var _rootContainerInstance = getRootHostContainer();
|
|
var _currentHostContext = getHostContext();
|
|
var _wasHydrated2 = popHydrationState(workInProgress2);
|
|
if (_wasHydrated2) {
|
|
if (prepareToHydrateHostTextInstance(workInProgress2)) {
|
|
markUpdate(workInProgress2);
|
|
}
|
|
} else {
|
|
workInProgress2.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress2);
|
|
}
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
case SuspenseComponent: {
|
|
popSuspenseContext(workInProgress2);
|
|
var nextState = workInProgress2.memoizedState;
|
|
if (hasUnhydratedTailNodes() && (workInProgress2.mode & ConcurrentMode) !== NoMode && (workInProgress2.flags & DidCapture) === NoFlags) {
|
|
warnIfUnhydratedTailNodes(workInProgress2);
|
|
resetHydrationState();
|
|
workInProgress2.flags |= ForceClientRender | Incomplete | ShouldCapture;
|
|
return workInProgress2;
|
|
}
|
|
if (nextState !== null && nextState.dehydrated !== null) {
|
|
var _wasHydrated3 = popHydrationState(workInProgress2);
|
|
if (current2 === null) {
|
|
if (!_wasHydrated3) {
|
|
throw new Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.");
|
|
}
|
|
prepareToHydrateHostSuspenseInstance(workInProgress2);
|
|
bubbleProperties(workInProgress2);
|
|
{
|
|
if ((workInProgress2.mode & ProfileMode) !== NoMode) {
|
|
var isTimedOutSuspense = nextState !== null;
|
|
if (isTimedOutSuspense) {
|
|
var primaryChildFragment = workInProgress2.child;
|
|
if (primaryChildFragment !== null) {
|
|
workInProgress2.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
} else {
|
|
resetHydrationState();
|
|
if ((workInProgress2.flags & DidCapture) === NoFlags) {
|
|
workInProgress2.memoizedState = null;
|
|
}
|
|
workInProgress2.flags |= Update;
|
|
bubbleProperties(workInProgress2);
|
|
{
|
|
if ((workInProgress2.mode & ProfileMode) !== NoMode) {
|
|
var _isTimedOutSuspense = nextState !== null;
|
|
if (_isTimedOutSuspense) {
|
|
var _primaryChildFragment = workInProgress2.child;
|
|
if (_primaryChildFragment !== null) {
|
|
workInProgress2.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
upgradeHydrationErrorsToRecoverable();
|
|
if ((workInProgress2.flags & DidCapture) !== NoFlags) {
|
|
workInProgress2.lanes = renderLanes2;
|
|
if ((workInProgress2.mode & ProfileMode) !== NoMode) {
|
|
transferActualDuration(workInProgress2);
|
|
}
|
|
return workInProgress2;
|
|
}
|
|
var nextDidTimeout = nextState !== null;
|
|
var prevDidTimeout = false;
|
|
if (current2 === null) {
|
|
popHydrationState(workInProgress2);
|
|
} else {
|
|
var _prevState = current2.memoizedState;
|
|
prevDidTimeout = _prevState !== null;
|
|
}
|
|
if (nextDidTimeout !== prevDidTimeout) {
|
|
if (nextDidTimeout) {
|
|
var _offscreenFiber2 = workInProgress2.child;
|
|
_offscreenFiber2.flags |= Visibility;
|
|
if ((workInProgress2.mode & ConcurrentMode) !== NoMode) {
|
|
var hasInvisibleChildContext = current2 === null && (workInProgress2.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
|
|
if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
|
|
renderDidSuspend();
|
|
} else {
|
|
renderDidSuspendDelayIfPossible();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var wakeables = workInProgress2.updateQueue;
|
|
if (wakeables !== null) {
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
{
|
|
if ((workInProgress2.mode & ProfileMode) !== NoMode) {
|
|
if (nextDidTimeout) {
|
|
var _primaryChildFragment2 = workInProgress2.child;
|
|
if (_primaryChildFragment2 !== null) {
|
|
workInProgress2.treeBaseDuration -= _primaryChildFragment2.treeBaseDuration;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
case HostPortal:
|
|
popHostContainer(workInProgress2);
|
|
updateHostContainer(current2, workInProgress2);
|
|
if (current2 === null) {
|
|
preparePortalMount(workInProgress2.stateNode.containerInfo);
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
case ContextProvider:
|
|
var context = workInProgress2.type._context;
|
|
popProvider(context, workInProgress2);
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
case IncompleteClassComponent: {
|
|
var _Component = workInProgress2.type;
|
|
if (isContextProvider(_Component)) {
|
|
popContext(workInProgress2);
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
case SuspenseListComponent: {
|
|
popSuspenseContext(workInProgress2);
|
|
var renderState = workInProgress2.memoizedState;
|
|
if (renderState === null) {
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
var didSuspendAlready = (workInProgress2.flags & DidCapture) !== NoFlags;
|
|
var renderedTail = renderState.rendering;
|
|
if (renderedTail === null) {
|
|
if (!didSuspendAlready) {
|
|
var cannotBeSuspended = renderHasNotSuspendedYet() && (current2 === null || (current2.flags & DidCapture) === NoFlags);
|
|
if (!cannotBeSuspended) {
|
|
var row = workInProgress2.child;
|
|
while (row !== null) {
|
|
var suspended = findFirstSuspended(row);
|
|
if (suspended !== null) {
|
|
didSuspendAlready = true;
|
|
workInProgress2.flags |= DidCapture;
|
|
cutOffTailIfNeeded(renderState, false);
|
|
var newThenables = suspended.updateQueue;
|
|
if (newThenables !== null) {
|
|
workInProgress2.updateQueue = newThenables;
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
workInProgress2.subtreeFlags = NoFlags;
|
|
resetChildFibers(workInProgress2, renderLanes2);
|
|
pushSuspenseContext(workInProgress2, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
|
|
return workInProgress2.child;
|
|
}
|
|
row = row.sibling;
|
|
}
|
|
}
|
|
if (renderState.tail !== null && now() > getRenderTargetTime()) {
|
|
workInProgress2.flags |= DidCapture;
|
|
didSuspendAlready = true;
|
|
cutOffTailIfNeeded(renderState, false);
|
|
workInProgress2.lanes = SomeRetryLane;
|
|
}
|
|
} else {
|
|
cutOffTailIfNeeded(renderState, false);
|
|
}
|
|
} else {
|
|
if (!didSuspendAlready) {
|
|
var _suspended = findFirstSuspended(renderedTail);
|
|
if (_suspended !== null) {
|
|
workInProgress2.flags |= DidCapture;
|
|
didSuspendAlready = true;
|
|
var _newThenables = _suspended.updateQueue;
|
|
if (_newThenables !== null) {
|
|
workInProgress2.updateQueue = _newThenables;
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
cutOffTailIfNeeded(renderState, true);
|
|
if (renderState.tail === null && renderState.tailMode === "hidden" && !renderedTail.alternate && !getIsHydrating()) {
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
} else if (now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes2 !== OffscreenLane) {
|
|
workInProgress2.flags |= DidCapture;
|
|
didSuspendAlready = true;
|
|
cutOffTailIfNeeded(renderState, false);
|
|
workInProgress2.lanes = SomeRetryLane;
|
|
}
|
|
}
|
|
if (renderState.isBackwards) {
|
|
renderedTail.sibling = workInProgress2.child;
|
|
workInProgress2.child = renderedTail;
|
|
} else {
|
|
var previousSibling = renderState.last;
|
|
if (previousSibling !== null) {
|
|
previousSibling.sibling = renderedTail;
|
|
} else {
|
|
workInProgress2.child = renderedTail;
|
|
}
|
|
renderState.last = renderedTail;
|
|
}
|
|
}
|
|
if (renderState.tail !== null) {
|
|
var next = renderState.tail;
|
|
renderState.rendering = next;
|
|
renderState.tail = next.sibling;
|
|
renderState.renderingStartTime = now();
|
|
next.sibling = null;
|
|
var suspenseContext = suspenseStackCursor.current;
|
|
if (didSuspendAlready) {
|
|
suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
|
|
} else {
|
|
suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
|
|
}
|
|
pushSuspenseContext(workInProgress2, suspenseContext);
|
|
return next;
|
|
}
|
|
bubbleProperties(workInProgress2);
|
|
return null;
|
|
}
|
|
case ScopeComponent: {
|
|
break;
|
|
}
|
|
case OffscreenComponent:
|
|
case LegacyHiddenComponent: {
|
|
popRenderLanes(workInProgress2);
|
|
var _nextState = workInProgress2.memoizedState;
|
|
var nextIsHidden = _nextState !== null;
|
|
if (current2 !== null) {
|
|
var _prevState2 = current2.memoizedState;
|
|
var prevIsHidden = _prevState2 !== null;
|
|
if (prevIsHidden !== nextIsHidden && !enableLegacyHidden) {
|
|
workInProgress2.flags |= Visibility;
|
|
}
|
|
}
|
|
if (!nextIsHidden || (workInProgress2.mode & ConcurrentMode) === NoMode) {
|
|
bubbleProperties(workInProgress2);
|
|
} else {
|
|
if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
|
|
bubbleProperties(workInProgress2);
|
|
{
|
|
if (workInProgress2.subtreeFlags & (Placement | Update)) {
|
|
workInProgress2.flags |= Visibility;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
case CacheComponent: {
|
|
return null;
|
|
}
|
|
case TracingMarkerComponent: {
|
|
return null;
|
|
}
|
|
}
|
|
throw new Error("Unknown unit of work tag (" + workInProgress2.tag + "). This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
|
|
var didReceiveUpdate = false;
|
|
var didWarnAboutBadClass;
|
|
var didWarnAboutModulePatternComponent;
|
|
var didWarnAboutContextTypeOnFunctionComponent;
|
|
var didWarnAboutGetDerivedStateOnFunctionComponent;
|
|
var didWarnAboutFunctionRefs;
|
|
var didWarnAboutReassigningProps;
|
|
var didWarnAboutRevealOrder;
|
|
var didWarnAboutTailOptions;
|
|
{
|
|
didWarnAboutBadClass = {};
|
|
didWarnAboutModulePatternComponent = {};
|
|
didWarnAboutContextTypeOnFunctionComponent = {};
|
|
didWarnAboutGetDerivedStateOnFunctionComponent = {};
|
|
didWarnAboutFunctionRefs = {};
|
|
didWarnAboutReassigningProps = false;
|
|
didWarnAboutRevealOrder = {};
|
|
didWarnAboutTailOptions = {};
|
|
}
|
|
function reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2) {
|
|
if (current2 === null) {
|
|
workInProgress2.child = mountChildFibers(workInProgress2, null, nextChildren, renderLanes2);
|
|
} else {
|
|
workInProgress2.child = reconcileChildFibers(workInProgress2, current2.child, nextChildren, renderLanes2);
|
|
}
|
|
}
|
|
function forceUnmountCurrentAndReconcile(current2, workInProgress2, nextChildren, renderLanes2) {
|
|
workInProgress2.child = reconcileChildFibers(workInProgress2, current2.child, null, renderLanes2);
|
|
workInProgress2.child = reconcileChildFibers(workInProgress2, null, nextChildren, renderLanes2);
|
|
}
|
|
function updateForwardRef(current2, workInProgress2, Component, nextProps, renderLanes2) {
|
|
{
|
|
if (workInProgress2.type !== workInProgress2.elementType) {
|
|
var innerPropTypes = Component.propTypes;
|
|
if (innerPropTypes) {
|
|
checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component));
|
|
}
|
|
}
|
|
}
|
|
var render2 = Component.render;
|
|
var ref = workInProgress2.ref;
|
|
var nextChildren;
|
|
var hasId;
|
|
prepareToReadContext(workInProgress2, renderLanes2);
|
|
{
|
|
markComponentRenderStarted(workInProgress2);
|
|
}
|
|
{
|
|
ReactCurrentOwner$1.current = workInProgress2;
|
|
setIsRendering(true);
|
|
nextChildren = renderWithHooks(current2, workInProgress2, render2, nextProps, ref, renderLanes2);
|
|
hasId = checkDidRenderIdHook();
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
nextChildren = renderWithHooks(current2, workInProgress2, render2, nextProps, ref, renderLanes2);
|
|
hasId = checkDidRenderIdHook();
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
setIsRendering(false);
|
|
}
|
|
{
|
|
markComponentRenderStopped();
|
|
}
|
|
if (current2 !== null && !didReceiveUpdate) {
|
|
bailoutHooks(current2, workInProgress2, renderLanes2);
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
if (getIsHydrating() && hasId) {
|
|
pushMaterializedTreeId(workInProgress2);
|
|
}
|
|
workInProgress2.flags |= PerformedWork;
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function updateMemoComponent(current2, workInProgress2, Component, nextProps, renderLanes2) {
|
|
if (current2 === null) {
|
|
var type = Component.type;
|
|
if (isSimpleFunctionComponent(type) && Component.compare === null && Component.defaultProps === void 0) {
|
|
var resolvedType = type;
|
|
{
|
|
resolvedType = resolveFunctionForHotReloading(type);
|
|
}
|
|
workInProgress2.tag = SimpleMemoComponent;
|
|
workInProgress2.type = resolvedType;
|
|
{
|
|
validateFunctionComponentInDev(workInProgress2, type);
|
|
}
|
|
return updateSimpleMemoComponent(current2, workInProgress2, resolvedType, nextProps, renderLanes2);
|
|
}
|
|
{
|
|
var innerPropTypes = type.propTypes;
|
|
if (innerPropTypes) {
|
|
checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(type));
|
|
}
|
|
}
|
|
var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress2, workInProgress2.mode, renderLanes2);
|
|
child.ref = workInProgress2.ref;
|
|
child.return = workInProgress2;
|
|
workInProgress2.child = child;
|
|
return child;
|
|
}
|
|
{
|
|
var _type = Component.type;
|
|
var _innerPropTypes = _type.propTypes;
|
|
if (_innerPropTypes) {
|
|
checkPropTypes(_innerPropTypes, nextProps, "prop", getComponentNameFromType(_type));
|
|
}
|
|
}
|
|
var currentChild = current2.child;
|
|
var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current2, renderLanes2);
|
|
if (!hasScheduledUpdateOrContext) {
|
|
var prevProps = currentChild.memoizedProps;
|
|
var compare = Component.compare;
|
|
compare = compare !== null ? compare : shallowEqual;
|
|
if (compare(prevProps, nextProps) && current2.ref === workInProgress2.ref) {
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
}
|
|
workInProgress2.flags |= PerformedWork;
|
|
var newChild = createWorkInProgress(currentChild, nextProps);
|
|
newChild.ref = workInProgress2.ref;
|
|
newChild.return = workInProgress2;
|
|
workInProgress2.child = newChild;
|
|
return newChild;
|
|
}
|
|
function updateSimpleMemoComponent(current2, workInProgress2, Component, nextProps, renderLanes2) {
|
|
{
|
|
if (workInProgress2.type !== workInProgress2.elementType) {
|
|
var outerMemoType = workInProgress2.elementType;
|
|
if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
|
|
var lazyComponent = outerMemoType;
|
|
var payload = lazyComponent._payload;
|
|
var init = lazyComponent._init;
|
|
try {
|
|
outerMemoType = init(payload);
|
|
} catch (x) {
|
|
outerMemoType = null;
|
|
}
|
|
var outerPropTypes = outerMemoType && outerMemoType.propTypes;
|
|
if (outerPropTypes) {
|
|
checkPropTypes(outerPropTypes, nextProps, "prop", getComponentNameFromType(outerMemoType));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (current2 !== null) {
|
|
var prevProps = current2.memoizedProps;
|
|
if (shallowEqual(prevProps, nextProps) && current2.ref === workInProgress2.ref && workInProgress2.type === current2.type) {
|
|
didReceiveUpdate = false;
|
|
workInProgress2.pendingProps = nextProps = prevProps;
|
|
if (!checkScheduledUpdateOrContext(current2, renderLanes2)) {
|
|
workInProgress2.lanes = current2.lanes;
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
} else if ((current2.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
|
|
didReceiveUpdate = true;
|
|
}
|
|
}
|
|
}
|
|
return updateFunctionComponent(current2, workInProgress2, Component, nextProps, renderLanes2);
|
|
}
|
|
function updateOffscreenComponent(current2, workInProgress2, renderLanes2) {
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var nextChildren = nextProps.children;
|
|
var prevState = current2 !== null ? current2.memoizedState : null;
|
|
if (nextProps.mode === "hidden" || enableLegacyHidden) {
|
|
if ((workInProgress2.mode & ConcurrentMode) === NoMode) {
|
|
var nextState = {
|
|
baseLanes: NoLanes,
|
|
cachePool: null,
|
|
transitions: null
|
|
};
|
|
workInProgress2.memoizedState = nextState;
|
|
pushRenderLanes(workInProgress2, renderLanes2);
|
|
} else if (!includesSomeLane(renderLanes2, OffscreenLane)) {
|
|
var spawnedCachePool = null;
|
|
var nextBaseLanes;
|
|
if (prevState !== null) {
|
|
var prevBaseLanes = prevState.baseLanes;
|
|
nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes2);
|
|
} else {
|
|
nextBaseLanes = renderLanes2;
|
|
}
|
|
workInProgress2.lanes = workInProgress2.childLanes = laneToLanes(OffscreenLane);
|
|
var _nextState = {
|
|
baseLanes: nextBaseLanes,
|
|
cachePool: spawnedCachePool,
|
|
transitions: null
|
|
};
|
|
workInProgress2.memoizedState = _nextState;
|
|
workInProgress2.updateQueue = null;
|
|
pushRenderLanes(workInProgress2, nextBaseLanes);
|
|
return null;
|
|
} else {
|
|
var _nextState2 = {
|
|
baseLanes: NoLanes,
|
|
cachePool: null,
|
|
transitions: null
|
|
};
|
|
workInProgress2.memoizedState = _nextState2;
|
|
var subtreeRenderLanes2 = prevState !== null ? prevState.baseLanes : renderLanes2;
|
|
pushRenderLanes(workInProgress2, subtreeRenderLanes2);
|
|
}
|
|
} else {
|
|
var _subtreeRenderLanes;
|
|
if (prevState !== null) {
|
|
_subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes2);
|
|
workInProgress2.memoizedState = null;
|
|
} else {
|
|
_subtreeRenderLanes = renderLanes2;
|
|
}
|
|
pushRenderLanes(workInProgress2, _subtreeRenderLanes);
|
|
}
|
|
{
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
}
|
|
function updateFragment(current2, workInProgress2, renderLanes2) {
|
|
var nextChildren = workInProgress2.pendingProps;
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function updateMode(current2, workInProgress2, renderLanes2) {
|
|
var nextChildren = workInProgress2.pendingProps.children;
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function updateProfiler(current2, workInProgress2, renderLanes2) {
|
|
{
|
|
workInProgress2.flags |= Update;
|
|
{
|
|
var stateNode = workInProgress2.stateNode;
|
|
stateNode.effectDuration = 0;
|
|
stateNode.passiveEffectDuration = 0;
|
|
}
|
|
}
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var nextChildren = nextProps.children;
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function markRef$1(current2, workInProgress2) {
|
|
var ref = workInProgress2.ref;
|
|
if (current2 === null && ref !== null || current2 !== null && current2.ref !== ref) {
|
|
workInProgress2.flags |= Ref;
|
|
{
|
|
workInProgress2.flags |= RefStatic;
|
|
}
|
|
}
|
|
}
|
|
function updateFunctionComponent(current2, workInProgress2, Component, nextProps, renderLanes2) {
|
|
{
|
|
if (workInProgress2.type !== workInProgress2.elementType) {
|
|
var innerPropTypes = Component.propTypes;
|
|
if (innerPropTypes) {
|
|
checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component));
|
|
}
|
|
}
|
|
}
|
|
var context;
|
|
{
|
|
var unmaskedContext = getUnmaskedContext(workInProgress2, Component, true);
|
|
context = getMaskedContext(workInProgress2, unmaskedContext);
|
|
}
|
|
var nextChildren;
|
|
var hasId;
|
|
prepareToReadContext(workInProgress2, renderLanes2);
|
|
{
|
|
markComponentRenderStarted(workInProgress2);
|
|
}
|
|
{
|
|
ReactCurrentOwner$1.current = workInProgress2;
|
|
setIsRendering(true);
|
|
nextChildren = renderWithHooks(current2, workInProgress2, Component, nextProps, context, renderLanes2);
|
|
hasId = checkDidRenderIdHook();
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
nextChildren = renderWithHooks(current2, workInProgress2, Component, nextProps, context, renderLanes2);
|
|
hasId = checkDidRenderIdHook();
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
setIsRendering(false);
|
|
}
|
|
{
|
|
markComponentRenderStopped();
|
|
}
|
|
if (current2 !== null && !didReceiveUpdate) {
|
|
bailoutHooks(current2, workInProgress2, renderLanes2);
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
if (getIsHydrating() && hasId) {
|
|
pushMaterializedTreeId(workInProgress2);
|
|
}
|
|
workInProgress2.flags |= PerformedWork;
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function updateClassComponent(current2, workInProgress2, Component, nextProps, renderLanes2) {
|
|
{
|
|
switch (shouldError(workInProgress2)) {
|
|
case false: {
|
|
var _instance = workInProgress2.stateNode;
|
|
var ctor = workInProgress2.type;
|
|
var tempInstance = new ctor(workInProgress2.memoizedProps, _instance.context);
|
|
var state = tempInstance.state;
|
|
_instance.updater.enqueueSetState(_instance, state, null);
|
|
break;
|
|
}
|
|
case true: {
|
|
workInProgress2.flags |= DidCapture;
|
|
workInProgress2.flags |= ShouldCapture;
|
|
var error$1 = new Error("Simulated error coming from DevTools");
|
|
var lane = pickArbitraryLane(renderLanes2);
|
|
workInProgress2.lanes = mergeLanes(workInProgress2.lanes, lane);
|
|
var update = createClassErrorUpdate(workInProgress2, createCapturedValue(error$1, workInProgress2), lane);
|
|
enqueueCapturedUpdate(workInProgress2, update);
|
|
break;
|
|
}
|
|
}
|
|
if (workInProgress2.type !== workInProgress2.elementType) {
|
|
var innerPropTypes = Component.propTypes;
|
|
if (innerPropTypes) {
|
|
checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component));
|
|
}
|
|
}
|
|
}
|
|
var hasContext;
|
|
if (isContextProvider(Component)) {
|
|
hasContext = true;
|
|
pushContextProvider(workInProgress2);
|
|
} else {
|
|
hasContext = false;
|
|
}
|
|
prepareToReadContext(workInProgress2, renderLanes2);
|
|
var instance = workInProgress2.stateNode;
|
|
var shouldUpdate;
|
|
if (instance === null) {
|
|
if (current2 !== null) {
|
|
current2.alternate = null;
|
|
workInProgress2.alternate = null;
|
|
workInProgress2.flags |= Placement;
|
|
}
|
|
constructClassInstance(workInProgress2, Component, nextProps);
|
|
mountClassInstance(workInProgress2, Component, nextProps, renderLanes2);
|
|
shouldUpdate = true;
|
|
} else if (current2 === null) {
|
|
shouldUpdate = resumeMountClassInstance(workInProgress2, Component, nextProps, renderLanes2);
|
|
} else {
|
|
shouldUpdate = updateClassInstance(current2, workInProgress2, Component, nextProps, renderLanes2);
|
|
}
|
|
var nextUnitOfWork = finishClassComponent(current2, workInProgress2, Component, shouldUpdate, hasContext, renderLanes2);
|
|
{
|
|
var inst = workInProgress2.stateNode;
|
|
if (shouldUpdate && inst.props !== nextProps) {
|
|
if (!didWarnAboutReassigningProps) {
|
|
error("It looks like %s is reassigning its own `this.props` while rendering. This is not supported and can lead to confusing bugs.", getComponentNameFromFiber(workInProgress2) || "a component");
|
|
}
|
|
didWarnAboutReassigningProps = true;
|
|
}
|
|
}
|
|
return nextUnitOfWork;
|
|
}
|
|
function finishClassComponent(current2, workInProgress2, Component, shouldUpdate, hasContext, renderLanes2) {
|
|
markRef$1(current2, workInProgress2);
|
|
var didCaptureError = (workInProgress2.flags & DidCapture) !== NoFlags;
|
|
if (!shouldUpdate && !didCaptureError) {
|
|
if (hasContext) {
|
|
invalidateContextProvider(workInProgress2, Component, false);
|
|
}
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
var instance = workInProgress2.stateNode;
|
|
ReactCurrentOwner$1.current = workInProgress2;
|
|
var nextChildren;
|
|
if (didCaptureError && typeof Component.getDerivedStateFromError !== "function") {
|
|
nextChildren = null;
|
|
{
|
|
stopProfilerTimerIfRunning();
|
|
}
|
|
} else {
|
|
{
|
|
markComponentRenderStarted(workInProgress2);
|
|
}
|
|
{
|
|
setIsRendering(true);
|
|
nextChildren = instance.render();
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
instance.render();
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
setIsRendering(false);
|
|
}
|
|
{
|
|
markComponentRenderStopped();
|
|
}
|
|
}
|
|
workInProgress2.flags |= PerformedWork;
|
|
if (current2 !== null && didCaptureError) {
|
|
forceUnmountCurrentAndReconcile(current2, workInProgress2, nextChildren, renderLanes2);
|
|
} else {
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
}
|
|
workInProgress2.memoizedState = instance.state;
|
|
if (hasContext) {
|
|
invalidateContextProvider(workInProgress2, Component, true);
|
|
}
|
|
return workInProgress2.child;
|
|
}
|
|
function pushHostRootContext(workInProgress2) {
|
|
var root3 = workInProgress2.stateNode;
|
|
if (root3.pendingContext) {
|
|
pushTopLevelContextObject(workInProgress2, root3.pendingContext, root3.pendingContext !== root3.context);
|
|
} else if (root3.context) {
|
|
pushTopLevelContextObject(workInProgress2, root3.context, false);
|
|
}
|
|
pushHostContainer(workInProgress2, root3.containerInfo);
|
|
}
|
|
function updateHostRoot(current2, workInProgress2, renderLanes2) {
|
|
pushHostRootContext(workInProgress2);
|
|
if (current2 === null) {
|
|
throw new Error("Should have a current fiber. This is a bug in React.");
|
|
}
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var prevState = workInProgress2.memoizedState;
|
|
var prevChildren = prevState.element;
|
|
cloneUpdateQueue(current2, workInProgress2);
|
|
processUpdateQueue(workInProgress2, nextProps, null, renderLanes2);
|
|
var nextState = workInProgress2.memoizedState;
|
|
var root3 = workInProgress2.stateNode;
|
|
var nextChildren = nextState.element;
|
|
if (prevState.isDehydrated) {
|
|
var overrideState = {
|
|
element: nextChildren,
|
|
isDehydrated: false,
|
|
cache: nextState.cache,
|
|
pendingSuspenseBoundaries: nextState.pendingSuspenseBoundaries,
|
|
transitions: nextState.transitions
|
|
};
|
|
var updateQueue = workInProgress2.updateQueue;
|
|
updateQueue.baseState = overrideState;
|
|
workInProgress2.memoizedState = overrideState;
|
|
if (workInProgress2.flags & ForceClientRender) {
|
|
var recoverableError = new Error("There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.");
|
|
return mountHostRootWithoutHydrating(current2, workInProgress2, nextChildren, renderLanes2, recoverableError);
|
|
} else if (nextChildren !== prevChildren) {
|
|
var _recoverableError = new Error("This root received an early update, before anything was able hydrate. Switched the entire root to client rendering.");
|
|
return mountHostRootWithoutHydrating(current2, workInProgress2, nextChildren, renderLanes2, _recoverableError);
|
|
} else {
|
|
enterHydrationState(workInProgress2);
|
|
var child = mountChildFibers(workInProgress2, null, nextChildren, renderLanes2);
|
|
workInProgress2.child = child;
|
|
var node = child;
|
|
while (node) {
|
|
node.flags = node.flags & ~Placement | Hydrating;
|
|
node = node.sibling;
|
|
}
|
|
}
|
|
} else {
|
|
resetHydrationState();
|
|
if (nextChildren === prevChildren) {
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
}
|
|
return workInProgress2.child;
|
|
}
|
|
function mountHostRootWithoutHydrating(current2, workInProgress2, nextChildren, renderLanes2, recoverableError) {
|
|
resetHydrationState();
|
|
queueHydrationError(recoverableError);
|
|
workInProgress2.flags |= ForceClientRender;
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function updateHostComponent$1(current2, workInProgress2, renderLanes2) {
|
|
pushHostContext(workInProgress2);
|
|
if (current2 === null) {
|
|
tryToClaimNextHydratableInstance(workInProgress2);
|
|
}
|
|
var type = workInProgress2.type;
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var prevProps = current2 !== null ? current2.memoizedProps : null;
|
|
var nextChildren = nextProps.children;
|
|
var isDirectTextChild = shouldSetTextContent(type, nextProps);
|
|
if (isDirectTextChild) {
|
|
nextChildren = null;
|
|
} else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
|
|
workInProgress2.flags |= ContentReset;
|
|
}
|
|
markRef$1(current2, workInProgress2);
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function updateHostText$1(current2, workInProgress2) {
|
|
if (current2 === null) {
|
|
tryToClaimNextHydratableInstance(workInProgress2);
|
|
}
|
|
return null;
|
|
}
|
|
function mountLazyComponent(_current, workInProgress2, elementType, renderLanes2) {
|
|
if (_current !== null) {
|
|
_current.alternate = null;
|
|
workInProgress2.alternate = null;
|
|
workInProgress2.flags |= Placement;
|
|
}
|
|
var props = workInProgress2.pendingProps;
|
|
var lazyComponent = elementType;
|
|
var payload = lazyComponent._payload;
|
|
var init = lazyComponent._init;
|
|
var Component = init(payload);
|
|
workInProgress2.type = Component;
|
|
var resolvedTag = workInProgress2.tag = resolveLazyComponentTag(Component);
|
|
var resolvedProps = resolveDefaultProps(Component, props);
|
|
var child;
|
|
switch (resolvedTag) {
|
|
case FunctionComponent: {
|
|
{
|
|
validateFunctionComponentInDev(workInProgress2, Component);
|
|
workInProgress2.type = Component = resolveFunctionForHotReloading(Component);
|
|
}
|
|
child = updateFunctionComponent(null, workInProgress2, Component, resolvedProps, renderLanes2);
|
|
return child;
|
|
}
|
|
case ClassComponent: {
|
|
{
|
|
workInProgress2.type = Component = resolveClassForHotReloading(Component);
|
|
}
|
|
child = updateClassComponent(null, workInProgress2, Component, resolvedProps, renderLanes2);
|
|
return child;
|
|
}
|
|
case ForwardRef: {
|
|
{
|
|
workInProgress2.type = Component = resolveForwardRefForHotReloading(Component);
|
|
}
|
|
child = updateForwardRef(null, workInProgress2, Component, resolvedProps, renderLanes2);
|
|
return child;
|
|
}
|
|
case MemoComponent: {
|
|
{
|
|
if (workInProgress2.type !== workInProgress2.elementType) {
|
|
var outerPropTypes = Component.propTypes;
|
|
if (outerPropTypes) {
|
|
checkPropTypes(outerPropTypes, resolvedProps, "prop", getComponentNameFromType(Component));
|
|
}
|
|
}
|
|
}
|
|
child = updateMemoComponent(null, workInProgress2, Component, resolveDefaultProps(Component.type, resolvedProps), renderLanes2);
|
|
return child;
|
|
}
|
|
}
|
|
var hint = "";
|
|
{
|
|
if (Component !== null && typeof Component === "object" && Component.$$typeof === REACT_LAZY_TYPE) {
|
|
hint = " Did you wrap a component in React.lazy() more than once?";
|
|
}
|
|
}
|
|
throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint));
|
|
}
|
|
function mountIncompleteClassComponent(_current, workInProgress2, Component, nextProps, renderLanes2) {
|
|
if (_current !== null) {
|
|
_current.alternate = null;
|
|
workInProgress2.alternate = null;
|
|
workInProgress2.flags |= Placement;
|
|
}
|
|
workInProgress2.tag = ClassComponent;
|
|
var hasContext;
|
|
if (isContextProvider(Component)) {
|
|
hasContext = true;
|
|
pushContextProvider(workInProgress2);
|
|
} else {
|
|
hasContext = false;
|
|
}
|
|
prepareToReadContext(workInProgress2, renderLanes2);
|
|
constructClassInstance(workInProgress2, Component, nextProps);
|
|
mountClassInstance(workInProgress2, Component, nextProps, renderLanes2);
|
|
return finishClassComponent(null, workInProgress2, Component, true, hasContext, renderLanes2);
|
|
}
|
|
function mountIndeterminateComponent(_current, workInProgress2, Component, renderLanes2) {
|
|
if (_current !== null) {
|
|
_current.alternate = null;
|
|
workInProgress2.alternate = null;
|
|
workInProgress2.flags |= Placement;
|
|
}
|
|
var props = workInProgress2.pendingProps;
|
|
var context;
|
|
{
|
|
var unmaskedContext = getUnmaskedContext(workInProgress2, Component, false);
|
|
context = getMaskedContext(workInProgress2, unmaskedContext);
|
|
}
|
|
prepareToReadContext(workInProgress2, renderLanes2);
|
|
var value;
|
|
var hasId;
|
|
{
|
|
markComponentRenderStarted(workInProgress2);
|
|
}
|
|
{
|
|
if (Component.prototype && typeof Component.prototype.render === "function") {
|
|
var componentName = getComponentNameFromType(Component) || "Unknown";
|
|
if (!didWarnAboutBadClass[componentName]) {
|
|
error("The <%s /> component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change %s to extend React.Component instead.", componentName, componentName);
|
|
didWarnAboutBadClass[componentName] = true;
|
|
}
|
|
}
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress2, null);
|
|
}
|
|
setIsRendering(true);
|
|
ReactCurrentOwner$1.current = workInProgress2;
|
|
value = renderWithHooks(null, workInProgress2, Component, props, context, renderLanes2);
|
|
hasId = checkDidRenderIdHook();
|
|
setIsRendering(false);
|
|
}
|
|
{
|
|
markComponentRenderStopped();
|
|
}
|
|
workInProgress2.flags |= PerformedWork;
|
|
{
|
|
if (typeof value === "object" && value !== null && typeof value.render === "function" && value.$$typeof === void 0) {
|
|
var _componentName = getComponentNameFromType(Component) || "Unknown";
|
|
if (!didWarnAboutModulePatternComponent[_componentName]) {
|
|
error("The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.", _componentName, _componentName, _componentName);
|
|
didWarnAboutModulePatternComponent[_componentName] = true;
|
|
}
|
|
}
|
|
}
|
|
if (typeof value === "object" && value !== null && typeof value.render === "function" && value.$$typeof === void 0) {
|
|
{
|
|
var _componentName2 = getComponentNameFromType(Component) || "Unknown";
|
|
if (!didWarnAboutModulePatternComponent[_componentName2]) {
|
|
error("The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.", _componentName2, _componentName2, _componentName2);
|
|
didWarnAboutModulePatternComponent[_componentName2] = true;
|
|
}
|
|
}
|
|
workInProgress2.tag = ClassComponent;
|
|
workInProgress2.memoizedState = null;
|
|
workInProgress2.updateQueue = null;
|
|
var hasContext = false;
|
|
if (isContextProvider(Component)) {
|
|
hasContext = true;
|
|
pushContextProvider(workInProgress2);
|
|
} else {
|
|
hasContext = false;
|
|
}
|
|
workInProgress2.memoizedState = value.state !== null && value.state !== void 0 ? value.state : null;
|
|
initializeUpdateQueue(workInProgress2);
|
|
adoptClassInstance(workInProgress2, value);
|
|
mountClassInstance(workInProgress2, Component, props, renderLanes2);
|
|
return finishClassComponent(null, workInProgress2, Component, true, hasContext, renderLanes2);
|
|
} else {
|
|
workInProgress2.tag = FunctionComponent;
|
|
{
|
|
if (workInProgress2.mode & StrictLegacyMode) {
|
|
setIsStrictModeForDevtools(true);
|
|
try {
|
|
value = renderWithHooks(null, workInProgress2, Component, props, context, renderLanes2);
|
|
hasId = checkDidRenderIdHook();
|
|
} finally {
|
|
setIsStrictModeForDevtools(false);
|
|
}
|
|
}
|
|
}
|
|
if (getIsHydrating() && hasId) {
|
|
pushMaterializedTreeId(workInProgress2);
|
|
}
|
|
reconcileChildren(null, workInProgress2, value, renderLanes2);
|
|
{
|
|
validateFunctionComponentInDev(workInProgress2, Component);
|
|
}
|
|
return workInProgress2.child;
|
|
}
|
|
}
|
|
function validateFunctionComponentInDev(workInProgress2, Component) {
|
|
{
|
|
if (Component) {
|
|
if (Component.childContextTypes) {
|
|
error("%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component");
|
|
}
|
|
}
|
|
if (workInProgress2.ref !== null) {
|
|
var info = "";
|
|
var ownerName = getCurrentFiberOwnerNameInDevOrNull();
|
|
if (ownerName) {
|
|
info += "\n\nCheck the render method of `" + ownerName + "`.";
|
|
}
|
|
var warningKey = ownerName || "";
|
|
var debugSource = workInProgress2._debugSource;
|
|
if (debugSource) {
|
|
warningKey = debugSource.fileName + ":" + debugSource.lineNumber;
|
|
}
|
|
if (!didWarnAboutFunctionRefs[warningKey]) {
|
|
didWarnAboutFunctionRefs[warningKey] = true;
|
|
error("Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?%s", info);
|
|
}
|
|
}
|
|
if (typeof Component.getDerivedStateFromProps === "function") {
|
|
var _componentName3 = getComponentNameFromType(Component) || "Unknown";
|
|
if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
|
|
error("%s: Function components do not support getDerivedStateFromProps.", _componentName3);
|
|
didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
|
|
}
|
|
}
|
|
if (typeof Component.contextType === "object" && Component.contextType !== null) {
|
|
var _componentName4 = getComponentNameFromType(Component) || "Unknown";
|
|
if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
|
|
error("%s: Function components do not support contextType.", _componentName4);
|
|
didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var SUSPENDED_MARKER = {
|
|
dehydrated: null,
|
|
treeContext: null,
|
|
retryLane: NoLane
|
|
};
|
|
function mountSuspenseOffscreenState(renderLanes2) {
|
|
return {
|
|
baseLanes: renderLanes2,
|
|
cachePool: getSuspendedCache(),
|
|
transitions: null
|
|
};
|
|
}
|
|
function updateSuspenseOffscreenState(prevOffscreenState, renderLanes2) {
|
|
var cachePool = null;
|
|
return {
|
|
baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes2),
|
|
cachePool,
|
|
transitions: prevOffscreenState.transitions
|
|
};
|
|
}
|
|
function shouldRemainOnFallback(suspenseContext, current2, workInProgress2, renderLanes2) {
|
|
if (current2 !== null) {
|
|
var suspenseState = current2.memoizedState;
|
|
if (suspenseState === null) {
|
|
return false;
|
|
}
|
|
}
|
|
return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
|
|
}
|
|
function getRemainingWorkInPrimaryTree(current2, renderLanes2) {
|
|
return removeLanes(current2.childLanes, renderLanes2);
|
|
}
|
|
function updateSuspenseComponent(current2, workInProgress2, renderLanes2) {
|
|
var nextProps = workInProgress2.pendingProps;
|
|
{
|
|
if (shouldSuspend(workInProgress2)) {
|
|
workInProgress2.flags |= DidCapture;
|
|
}
|
|
}
|
|
var suspenseContext = suspenseStackCursor.current;
|
|
var showFallback = false;
|
|
var didSuspend = (workInProgress2.flags & DidCapture) !== NoFlags;
|
|
if (didSuspend || shouldRemainOnFallback(suspenseContext, current2)) {
|
|
showFallback = true;
|
|
workInProgress2.flags &= ~DidCapture;
|
|
} else {
|
|
if (current2 === null || current2.memoizedState !== null) {
|
|
{
|
|
suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
|
|
}
|
|
}
|
|
}
|
|
suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
|
|
pushSuspenseContext(workInProgress2, suspenseContext);
|
|
if (current2 === null) {
|
|
tryToClaimNextHydratableInstance(workInProgress2);
|
|
var suspenseState = workInProgress2.memoizedState;
|
|
if (suspenseState !== null) {
|
|
var dehydrated = suspenseState.dehydrated;
|
|
if (dehydrated !== null) {
|
|
return mountDehydratedSuspenseComponent(workInProgress2, dehydrated);
|
|
}
|
|
}
|
|
var nextPrimaryChildren = nextProps.children;
|
|
var nextFallbackChildren = nextProps.fallback;
|
|
if (showFallback) {
|
|
var fallbackFragment = mountSuspenseFallbackChildren(workInProgress2, nextPrimaryChildren, nextFallbackChildren, renderLanes2);
|
|
var primaryChildFragment = workInProgress2.child;
|
|
primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes2);
|
|
workInProgress2.memoizedState = SUSPENDED_MARKER;
|
|
return fallbackFragment;
|
|
} else {
|
|
return mountSuspensePrimaryChildren(workInProgress2, nextPrimaryChildren);
|
|
}
|
|
} else {
|
|
var prevState = current2.memoizedState;
|
|
if (prevState !== null) {
|
|
var _dehydrated = prevState.dehydrated;
|
|
if (_dehydrated !== null) {
|
|
if (!didSuspend) {
|
|
return updateDehydratedSuspenseComponent(current2, workInProgress2, _dehydrated, prevState, renderLanes2);
|
|
} else if (workInProgress2.flags & ForceClientRender) {
|
|
workInProgress2.flags &= ~ForceClientRender;
|
|
return retrySuspenseComponentWithoutHydrating(current2, workInProgress2, renderLanes2, new Error("There was an error while hydrating this Suspense boundary. Switched to client rendering."));
|
|
} else if (workInProgress2.memoizedState !== null) {
|
|
workInProgress2.child = current2.child;
|
|
workInProgress2.flags |= DidCapture;
|
|
return null;
|
|
} else {
|
|
var _nextPrimaryChildren = nextProps.children;
|
|
var _nextFallbackChildren = nextProps.fallback;
|
|
var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current2, workInProgress2, _nextPrimaryChildren, _nextFallbackChildren, renderLanes2);
|
|
var _primaryChildFragment2 = workInProgress2.child;
|
|
_primaryChildFragment2.memoizedState = mountSuspenseOffscreenState(renderLanes2);
|
|
workInProgress2.memoizedState = SUSPENDED_MARKER;
|
|
return fallbackChildFragment;
|
|
}
|
|
}
|
|
if (showFallback) {
|
|
var _nextFallbackChildren2 = nextProps.fallback;
|
|
var _nextPrimaryChildren2 = nextProps.children;
|
|
var _fallbackChildFragment = updateSuspenseFallbackChildren(current2, workInProgress2, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes2);
|
|
var _primaryChildFragment3 = workInProgress2.child;
|
|
var prevOffscreenState = current2.child.memoizedState;
|
|
_primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes2) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes2);
|
|
_primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current2, renderLanes2);
|
|
workInProgress2.memoizedState = SUSPENDED_MARKER;
|
|
return _fallbackChildFragment;
|
|
} else {
|
|
var _nextPrimaryChildren3 = nextProps.children;
|
|
var _primaryChildFragment4 = updateSuspensePrimaryChildren(current2, workInProgress2, _nextPrimaryChildren3, renderLanes2);
|
|
workInProgress2.memoizedState = null;
|
|
return _primaryChildFragment4;
|
|
}
|
|
} else {
|
|
if (showFallback) {
|
|
var _nextFallbackChildren3 = nextProps.fallback;
|
|
var _nextPrimaryChildren4 = nextProps.children;
|
|
var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current2, workInProgress2, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes2);
|
|
var _primaryChildFragment5 = workInProgress2.child;
|
|
var _prevOffscreenState = current2.child.memoizedState;
|
|
_primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes2) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes2);
|
|
_primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current2, renderLanes2);
|
|
workInProgress2.memoizedState = SUSPENDED_MARKER;
|
|
return _fallbackChildFragment2;
|
|
} else {
|
|
var _nextPrimaryChildren5 = nextProps.children;
|
|
var _primaryChildFragment6 = updateSuspensePrimaryChildren(current2, workInProgress2, _nextPrimaryChildren5, renderLanes2);
|
|
workInProgress2.memoizedState = null;
|
|
return _primaryChildFragment6;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function mountSuspensePrimaryChildren(workInProgress2, primaryChildren, renderLanes2) {
|
|
var mode = workInProgress2.mode;
|
|
var primaryChildProps = {
|
|
mode: "visible",
|
|
children: primaryChildren
|
|
};
|
|
var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
|
|
primaryChildFragment.return = workInProgress2;
|
|
workInProgress2.child = primaryChildFragment;
|
|
return primaryChildFragment;
|
|
}
|
|
function mountSuspenseFallbackChildren(workInProgress2, primaryChildren, fallbackChildren, renderLanes2) {
|
|
var mode = workInProgress2.mode;
|
|
var progressedPrimaryFragment = workInProgress2.child;
|
|
var primaryChildProps = {
|
|
mode: "hidden",
|
|
children: primaryChildren
|
|
};
|
|
var primaryChildFragment;
|
|
var fallbackChildFragment;
|
|
if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
|
|
primaryChildFragment = progressedPrimaryFragment;
|
|
primaryChildFragment.childLanes = NoLanes;
|
|
primaryChildFragment.pendingProps = primaryChildProps;
|
|
if (workInProgress2.mode & ProfileMode) {
|
|
primaryChildFragment.actualDuration = 0;
|
|
primaryChildFragment.actualStartTime = -1;
|
|
primaryChildFragment.selfBaseDuration = 0;
|
|
primaryChildFragment.treeBaseDuration = 0;
|
|
}
|
|
fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes2, null);
|
|
} else {
|
|
primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
|
|
fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes2, null);
|
|
}
|
|
primaryChildFragment.return = workInProgress2;
|
|
fallbackChildFragment.return = workInProgress2;
|
|
primaryChildFragment.sibling = fallbackChildFragment;
|
|
workInProgress2.child = primaryChildFragment;
|
|
return fallbackChildFragment;
|
|
}
|
|
function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes2) {
|
|
return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
|
|
}
|
|
function updateWorkInProgressOffscreenFiber(current2, offscreenProps) {
|
|
return createWorkInProgress(current2, offscreenProps);
|
|
}
|
|
function updateSuspensePrimaryChildren(current2, workInProgress2, primaryChildren, renderLanes2) {
|
|
var currentPrimaryChildFragment = current2.child;
|
|
var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
|
|
var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
|
|
mode: "visible",
|
|
children: primaryChildren
|
|
});
|
|
if ((workInProgress2.mode & ConcurrentMode) === NoMode) {
|
|
primaryChildFragment.lanes = renderLanes2;
|
|
}
|
|
primaryChildFragment.return = workInProgress2;
|
|
primaryChildFragment.sibling = null;
|
|
if (currentFallbackChildFragment !== null) {
|
|
var deletions = workInProgress2.deletions;
|
|
if (deletions === null) {
|
|
workInProgress2.deletions = [currentFallbackChildFragment];
|
|
workInProgress2.flags |= ChildDeletion;
|
|
} else {
|
|
deletions.push(currentFallbackChildFragment);
|
|
}
|
|
}
|
|
workInProgress2.child = primaryChildFragment;
|
|
return primaryChildFragment;
|
|
}
|
|
function updateSuspenseFallbackChildren(current2, workInProgress2, primaryChildren, fallbackChildren, renderLanes2) {
|
|
var mode = workInProgress2.mode;
|
|
var currentPrimaryChildFragment = current2.child;
|
|
var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
|
|
var primaryChildProps = {
|
|
mode: "hidden",
|
|
children: primaryChildren
|
|
};
|
|
var primaryChildFragment;
|
|
if ((mode & ConcurrentMode) === NoMode && workInProgress2.child !== currentPrimaryChildFragment) {
|
|
var progressedPrimaryFragment = workInProgress2.child;
|
|
primaryChildFragment = progressedPrimaryFragment;
|
|
primaryChildFragment.childLanes = NoLanes;
|
|
primaryChildFragment.pendingProps = primaryChildProps;
|
|
if (workInProgress2.mode & ProfileMode) {
|
|
primaryChildFragment.actualDuration = 0;
|
|
primaryChildFragment.actualStartTime = -1;
|
|
primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
|
|
primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
|
|
}
|
|
workInProgress2.deletions = null;
|
|
} else {
|
|
primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps);
|
|
primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
|
|
}
|
|
var fallbackChildFragment;
|
|
if (currentFallbackChildFragment !== null) {
|
|
fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
|
|
} else {
|
|
fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes2, null);
|
|
fallbackChildFragment.flags |= Placement;
|
|
}
|
|
fallbackChildFragment.return = workInProgress2;
|
|
primaryChildFragment.return = workInProgress2;
|
|
primaryChildFragment.sibling = fallbackChildFragment;
|
|
workInProgress2.child = primaryChildFragment;
|
|
return fallbackChildFragment;
|
|
}
|
|
function retrySuspenseComponentWithoutHydrating(current2, workInProgress2, renderLanes2, recoverableError) {
|
|
if (recoverableError !== null) {
|
|
queueHydrationError(recoverableError);
|
|
}
|
|
reconcileChildFibers(workInProgress2, current2.child, null, renderLanes2);
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var primaryChildren = nextProps.children;
|
|
var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress2, primaryChildren);
|
|
primaryChildFragment.flags |= Placement;
|
|
workInProgress2.memoizedState = null;
|
|
return primaryChildFragment;
|
|
}
|
|
function mountSuspenseFallbackAfterRetryWithoutHydrating(current2, workInProgress2, primaryChildren, fallbackChildren, renderLanes2) {
|
|
var fiberMode = workInProgress2.mode;
|
|
var primaryChildProps = {
|
|
mode: "visible",
|
|
children: primaryChildren
|
|
};
|
|
var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
|
|
var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes2, null);
|
|
fallbackChildFragment.flags |= Placement;
|
|
primaryChildFragment.return = workInProgress2;
|
|
fallbackChildFragment.return = workInProgress2;
|
|
primaryChildFragment.sibling = fallbackChildFragment;
|
|
workInProgress2.child = primaryChildFragment;
|
|
if ((workInProgress2.mode & ConcurrentMode) !== NoMode) {
|
|
reconcileChildFibers(workInProgress2, current2.child, null, renderLanes2);
|
|
}
|
|
return fallbackChildFragment;
|
|
}
|
|
function mountDehydratedSuspenseComponent(workInProgress2, suspenseInstance, renderLanes2) {
|
|
if ((workInProgress2.mode & ConcurrentMode) === NoMode) {
|
|
{
|
|
error("Cannot hydrate Suspense in legacy mode. Switch from ReactDOM.hydrate(element, container) to ReactDOMClient.hydrateRoot(container, <App />).render(element) or remove the Suspense components from the server rendered components.");
|
|
}
|
|
workInProgress2.lanes = laneToLanes(SyncLane);
|
|
} else if (isSuspenseInstanceFallback(suspenseInstance)) {
|
|
workInProgress2.lanes = laneToLanes(DefaultHydrationLane);
|
|
} else {
|
|
workInProgress2.lanes = laneToLanes(OffscreenLane);
|
|
}
|
|
return null;
|
|
}
|
|
function updateDehydratedSuspenseComponent(current2, workInProgress2, suspenseInstance, suspenseState, renderLanes2) {
|
|
warnIfHydrating();
|
|
if ((workInProgress2.mode & ConcurrentMode) === NoMode) {
|
|
return retrySuspenseComponentWithoutHydrating(current2, workInProgress2, renderLanes2, null);
|
|
}
|
|
if (isSuspenseInstanceFallback(suspenseInstance)) {
|
|
return retrySuspenseComponentWithoutHydrating(current2, workInProgress2, renderLanes2, new Error("The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering."));
|
|
}
|
|
var hasContextChanged2 = includesSomeLane(renderLanes2, current2.childLanes);
|
|
if (didReceiveUpdate || hasContextChanged2) {
|
|
var root3 = getWorkInProgressRoot();
|
|
if (root3 !== null) {
|
|
var attemptHydrationAtLane = getBumpedLaneForHydration(root3, renderLanes2);
|
|
if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
|
|
suspenseState.retryLane = attemptHydrationAtLane;
|
|
var eventTime = NoTimestamp;
|
|
scheduleUpdateOnFiber(current2, attemptHydrationAtLane, eventTime);
|
|
}
|
|
}
|
|
renderDidSuspendDelayIfPossible();
|
|
return retrySuspenseComponentWithoutHydrating(current2, workInProgress2, renderLanes2, new Error("This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition."));
|
|
} else if (isSuspenseInstancePending(suspenseInstance)) {
|
|
workInProgress2.flags |= DidCapture;
|
|
workInProgress2.child = current2.child;
|
|
var retry = retryDehydratedSuspenseBoundary.bind(null, current2);
|
|
registerSuspenseInstanceRetry(suspenseInstance, retry);
|
|
return null;
|
|
} else {
|
|
reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress2, suspenseInstance, suspenseState.treeContext);
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var primaryChildren = nextProps.children;
|
|
var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress2, primaryChildren);
|
|
primaryChildFragment.flags |= Hydrating;
|
|
return primaryChildFragment;
|
|
}
|
|
}
|
|
function scheduleSuspenseWorkOnFiber(fiber, renderLanes2, propagationRoot) {
|
|
fiber.lanes = mergeLanes(fiber.lanes, renderLanes2);
|
|
var alternate = fiber.alternate;
|
|
if (alternate !== null) {
|
|
alternate.lanes = mergeLanes(alternate.lanes, renderLanes2);
|
|
}
|
|
scheduleContextWorkOnParentPath(fiber.return, renderLanes2, propagationRoot);
|
|
}
|
|
function propagateSuspenseContextChange(workInProgress2, firstChild, renderLanes2) {
|
|
var node = firstChild;
|
|
while (node !== null) {
|
|
if (node.tag === SuspenseComponent) {
|
|
var state = node.memoizedState;
|
|
if (state !== null) {
|
|
scheduleSuspenseWorkOnFiber(node, renderLanes2, workInProgress2);
|
|
}
|
|
} else if (node.tag === SuspenseListComponent) {
|
|
scheduleSuspenseWorkOnFiber(node, renderLanes2, workInProgress2);
|
|
} else if (node.child !== null) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === workInProgress2) {
|
|
return;
|
|
}
|
|
while (node.sibling === null) {
|
|
if (node.return === null || node.return === workInProgress2) {
|
|
return;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
}
|
|
function findLastContentRow(firstChild) {
|
|
var row = firstChild;
|
|
var lastContentRow = null;
|
|
while (row !== null) {
|
|
var currentRow = row.alternate;
|
|
if (currentRow !== null && findFirstSuspended(currentRow) === null) {
|
|
lastContentRow = row;
|
|
}
|
|
row = row.sibling;
|
|
}
|
|
return lastContentRow;
|
|
}
|
|
function validateRevealOrder(revealOrder) {
|
|
{
|
|
if (revealOrder !== void 0 && revealOrder !== "forwards" && revealOrder !== "backwards" && revealOrder !== "together" && !didWarnAboutRevealOrder[revealOrder]) {
|
|
didWarnAboutRevealOrder[revealOrder] = true;
|
|
if (typeof revealOrder === "string") {
|
|
switch (revealOrder.toLowerCase()) {
|
|
case "together":
|
|
case "forwards":
|
|
case "backwards": {
|
|
error('"%s" is not a valid value for revealOrder on <SuspenseList />. Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
|
|
break;
|
|
}
|
|
case "forward":
|
|
case "backward": {
|
|
error('"%s" is not a valid value for revealOrder on <SuspenseList />. React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
|
|
break;
|
|
}
|
|
default:
|
|
error('"%s" is not a supported revealOrder on <SuspenseList />. Did you mean "together", "forwards" or "backwards"?', revealOrder);
|
|
break;
|
|
}
|
|
} else {
|
|
error('%s is not a supported value for revealOrder on <SuspenseList />. Did you mean "together", "forwards" or "backwards"?', revealOrder);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function validateTailOptions(tailMode, revealOrder) {
|
|
{
|
|
if (tailMode !== void 0 && !didWarnAboutTailOptions[tailMode]) {
|
|
if (tailMode !== "collapsed" && tailMode !== "hidden") {
|
|
didWarnAboutTailOptions[tailMode] = true;
|
|
error('"%s" is not a supported value for tail on <SuspenseList />. Did you mean "collapsed" or "hidden"?', tailMode);
|
|
} else if (revealOrder !== "forwards" && revealOrder !== "backwards") {
|
|
didWarnAboutTailOptions[tailMode] = true;
|
|
error('<SuspenseList tail="%s" /> is only valid if revealOrder is "forwards" or "backwards". Did you mean to specify revealOrder="forwards"?', tailMode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function validateSuspenseListNestedChild(childSlot, index2) {
|
|
{
|
|
var isAnArray = isArray(childSlot);
|
|
var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === "function";
|
|
if (isAnArray || isIterable) {
|
|
var type = isAnArray ? "array" : "iterable";
|
|
error("A nested %s was passed to row #%s in <SuspenseList />. Wrap it in an additional SuspenseList to configure its revealOrder: <SuspenseList revealOrder=...> ... <SuspenseList revealOrder=...>{%s}</SuspenseList> ... </SuspenseList>", type, index2, type);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function validateSuspenseListChildren(children, revealOrder) {
|
|
{
|
|
if ((revealOrder === "forwards" || revealOrder === "backwards") && children !== void 0 && children !== null && children !== false) {
|
|
if (isArray(children)) {
|
|
for (var i = 0; i < children.length; i++) {
|
|
if (!validateSuspenseListNestedChild(children[i], i)) {
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
var iteratorFn = getIteratorFn(children);
|
|
if (typeof iteratorFn === "function") {
|
|
var childrenIterator = iteratorFn.call(children);
|
|
if (childrenIterator) {
|
|
var step = childrenIterator.next();
|
|
var _i = 0;
|
|
for (; !step.done; step = childrenIterator.next()) {
|
|
if (!validateSuspenseListNestedChild(step.value, _i)) {
|
|
return;
|
|
}
|
|
_i++;
|
|
}
|
|
}
|
|
} else {
|
|
error('A single row was passed to a <SuspenseList revealOrder="%s" />. This is not useful since it needs multiple rows. Did you mean to pass multiple children or an array?', revealOrder);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function initSuspenseListRenderState(workInProgress2, isBackwards, tail, lastContentRow, tailMode) {
|
|
var renderState = workInProgress2.memoizedState;
|
|
if (renderState === null) {
|
|
workInProgress2.memoizedState = {
|
|
isBackwards,
|
|
rendering: null,
|
|
renderingStartTime: 0,
|
|
last: lastContentRow,
|
|
tail,
|
|
tailMode
|
|
};
|
|
} else {
|
|
renderState.isBackwards = isBackwards;
|
|
renderState.rendering = null;
|
|
renderState.renderingStartTime = 0;
|
|
renderState.last = lastContentRow;
|
|
renderState.tail = tail;
|
|
renderState.tailMode = tailMode;
|
|
}
|
|
}
|
|
function updateSuspenseListComponent(current2, workInProgress2, renderLanes2) {
|
|
var nextProps = workInProgress2.pendingProps;
|
|
var revealOrder = nextProps.revealOrder;
|
|
var tailMode = nextProps.tail;
|
|
var newChildren = nextProps.children;
|
|
validateRevealOrder(revealOrder);
|
|
validateTailOptions(tailMode, revealOrder);
|
|
validateSuspenseListChildren(newChildren, revealOrder);
|
|
reconcileChildren(current2, workInProgress2, newChildren, renderLanes2);
|
|
var suspenseContext = suspenseStackCursor.current;
|
|
var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
|
|
if (shouldForceFallback) {
|
|
suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
|
|
workInProgress2.flags |= DidCapture;
|
|
} else {
|
|
var didSuspendBefore = current2 !== null && (current2.flags & DidCapture) !== NoFlags;
|
|
if (didSuspendBefore) {
|
|
propagateSuspenseContextChange(workInProgress2, workInProgress2.child, renderLanes2);
|
|
}
|
|
suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
|
|
}
|
|
pushSuspenseContext(workInProgress2, suspenseContext);
|
|
if ((workInProgress2.mode & ConcurrentMode) === NoMode) {
|
|
workInProgress2.memoizedState = null;
|
|
} else {
|
|
switch (revealOrder) {
|
|
case "forwards": {
|
|
var lastContentRow = findLastContentRow(workInProgress2.child);
|
|
var tail;
|
|
if (lastContentRow === null) {
|
|
tail = workInProgress2.child;
|
|
workInProgress2.child = null;
|
|
} else {
|
|
tail = lastContentRow.sibling;
|
|
lastContentRow.sibling = null;
|
|
}
|
|
initSuspenseListRenderState(workInProgress2, false, tail, lastContentRow, tailMode);
|
|
break;
|
|
}
|
|
case "backwards": {
|
|
var _tail = null;
|
|
var row = workInProgress2.child;
|
|
workInProgress2.child = null;
|
|
while (row !== null) {
|
|
var currentRow = row.alternate;
|
|
if (currentRow !== null && findFirstSuspended(currentRow) === null) {
|
|
workInProgress2.child = row;
|
|
break;
|
|
}
|
|
var nextRow = row.sibling;
|
|
row.sibling = _tail;
|
|
_tail = row;
|
|
row = nextRow;
|
|
}
|
|
initSuspenseListRenderState(workInProgress2, true, _tail, null, tailMode);
|
|
break;
|
|
}
|
|
case "together": {
|
|
initSuspenseListRenderState(workInProgress2, false, null, null, void 0);
|
|
break;
|
|
}
|
|
default: {
|
|
workInProgress2.memoizedState = null;
|
|
}
|
|
}
|
|
}
|
|
return workInProgress2.child;
|
|
}
|
|
function updatePortalComponent(current2, workInProgress2, renderLanes2) {
|
|
pushHostContainer(workInProgress2, workInProgress2.stateNode.containerInfo);
|
|
var nextChildren = workInProgress2.pendingProps;
|
|
if (current2 === null) {
|
|
workInProgress2.child = reconcileChildFibers(workInProgress2, null, nextChildren, renderLanes2);
|
|
} else {
|
|
reconcileChildren(current2, workInProgress2, nextChildren, renderLanes2);
|
|
}
|
|
return workInProgress2.child;
|
|
}
|
|
var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
|
|
function updateContextProvider(current2, workInProgress2, renderLanes2) {
|
|
var providerType = workInProgress2.type;
|
|
var context = providerType._context;
|
|
var newProps = workInProgress2.pendingProps;
|
|
var oldProps = workInProgress2.memoizedProps;
|
|
var newValue = newProps.value;
|
|
{
|
|
if (!("value" in newProps)) {
|
|
if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
|
|
hasWarnedAboutUsingNoValuePropOnContextProvider = true;
|
|
error("The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?");
|
|
}
|
|
}
|
|
var providerPropTypes = workInProgress2.type.propTypes;
|
|
if (providerPropTypes) {
|
|
checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider");
|
|
}
|
|
}
|
|
pushProvider(workInProgress2, context, newValue);
|
|
{
|
|
if (oldProps !== null) {
|
|
var oldValue = oldProps.value;
|
|
if (objectIs(oldValue, newValue)) {
|
|
if (oldProps.children === newProps.children && !hasContextChanged()) {
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
} else {
|
|
propagateContextChange(workInProgress2, context, renderLanes2);
|
|
}
|
|
}
|
|
}
|
|
var newChildren = newProps.children;
|
|
reconcileChildren(current2, workInProgress2, newChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
var hasWarnedAboutUsingContextAsConsumer = false;
|
|
function updateContextConsumer(current2, workInProgress2, renderLanes2) {
|
|
var context = workInProgress2.type;
|
|
{
|
|
if (context._context === void 0) {
|
|
if (context !== context.Consumer) {
|
|
if (!hasWarnedAboutUsingContextAsConsumer) {
|
|
hasWarnedAboutUsingContextAsConsumer = true;
|
|
error("Rendering <Context> directly is not supported and will be removed in a future major release. Did you mean to render <Context.Consumer> instead?");
|
|
}
|
|
}
|
|
} else {
|
|
context = context._context;
|
|
}
|
|
}
|
|
var newProps = workInProgress2.pendingProps;
|
|
var render2 = newProps.children;
|
|
{
|
|
if (typeof render2 !== "function") {
|
|
error("A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it.");
|
|
}
|
|
}
|
|
prepareToReadContext(workInProgress2, renderLanes2);
|
|
var newValue = readContext(context);
|
|
{
|
|
markComponentRenderStarted(workInProgress2);
|
|
}
|
|
var newChildren;
|
|
{
|
|
ReactCurrentOwner$1.current = workInProgress2;
|
|
setIsRendering(true);
|
|
newChildren = render2(newValue);
|
|
setIsRendering(false);
|
|
}
|
|
{
|
|
markComponentRenderStopped();
|
|
}
|
|
workInProgress2.flags |= PerformedWork;
|
|
reconcileChildren(current2, workInProgress2, newChildren, renderLanes2);
|
|
return workInProgress2.child;
|
|
}
|
|
function markWorkInProgressReceivedUpdate() {
|
|
didReceiveUpdate = true;
|
|
}
|
|
function bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2) {
|
|
if (current2 !== null) {
|
|
workInProgress2.dependencies = current2.dependencies;
|
|
}
|
|
{
|
|
stopProfilerTimerIfRunning();
|
|
}
|
|
markSkippedUpdateLanes(workInProgress2.lanes);
|
|
if (!includesSomeLane(renderLanes2, workInProgress2.childLanes)) {
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
cloneChildFibers(current2, workInProgress2);
|
|
return workInProgress2.child;
|
|
}
|
|
function remountFiber(current2, oldWorkInProgress, newWorkInProgress) {
|
|
{
|
|
var returnFiber = oldWorkInProgress.return;
|
|
if (returnFiber === null) {
|
|
throw new Error("Cannot swap the root fiber.");
|
|
}
|
|
current2.alternate = null;
|
|
oldWorkInProgress.alternate = null;
|
|
newWorkInProgress.index = oldWorkInProgress.index;
|
|
newWorkInProgress.sibling = oldWorkInProgress.sibling;
|
|
newWorkInProgress.return = oldWorkInProgress.return;
|
|
newWorkInProgress.ref = oldWorkInProgress.ref;
|
|
if (oldWorkInProgress === returnFiber.child) {
|
|
returnFiber.child = newWorkInProgress;
|
|
} else {
|
|
var prevSibling = returnFiber.child;
|
|
if (prevSibling === null) {
|
|
throw new Error("Expected parent to have a child.");
|
|
}
|
|
while (prevSibling.sibling !== oldWorkInProgress) {
|
|
prevSibling = prevSibling.sibling;
|
|
if (prevSibling === null) {
|
|
throw new Error("Expected to find the previous sibling.");
|
|
}
|
|
}
|
|
prevSibling.sibling = newWorkInProgress;
|
|
}
|
|
var deletions = returnFiber.deletions;
|
|
if (deletions === null) {
|
|
returnFiber.deletions = [current2];
|
|
returnFiber.flags |= ChildDeletion;
|
|
} else {
|
|
deletions.push(current2);
|
|
}
|
|
newWorkInProgress.flags |= Placement;
|
|
return newWorkInProgress;
|
|
}
|
|
}
|
|
function checkScheduledUpdateOrContext(current2, renderLanes2) {
|
|
var updateLanes = current2.lanes;
|
|
if (includesSomeLane(updateLanes, renderLanes2)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function attemptEarlyBailoutIfNoScheduledUpdate(current2, workInProgress2, renderLanes2) {
|
|
switch (workInProgress2.tag) {
|
|
case HostRoot:
|
|
pushHostRootContext(workInProgress2);
|
|
var root3 = workInProgress2.stateNode;
|
|
resetHydrationState();
|
|
break;
|
|
case HostComponent:
|
|
pushHostContext(workInProgress2);
|
|
break;
|
|
case ClassComponent: {
|
|
var Component = workInProgress2.type;
|
|
if (isContextProvider(Component)) {
|
|
pushContextProvider(workInProgress2);
|
|
}
|
|
break;
|
|
}
|
|
case HostPortal:
|
|
pushHostContainer(workInProgress2, workInProgress2.stateNode.containerInfo);
|
|
break;
|
|
case ContextProvider: {
|
|
var newValue = workInProgress2.memoizedProps.value;
|
|
var context = workInProgress2.type._context;
|
|
pushProvider(workInProgress2, context, newValue);
|
|
break;
|
|
}
|
|
case Profiler:
|
|
{
|
|
var hasChildWork = includesSomeLane(renderLanes2, workInProgress2.childLanes);
|
|
if (hasChildWork) {
|
|
workInProgress2.flags |= Update;
|
|
}
|
|
{
|
|
var stateNode = workInProgress2.stateNode;
|
|
stateNode.effectDuration = 0;
|
|
stateNode.passiveEffectDuration = 0;
|
|
}
|
|
}
|
|
break;
|
|
case SuspenseComponent: {
|
|
var state = workInProgress2.memoizedState;
|
|
if (state !== null) {
|
|
if (state.dehydrated !== null) {
|
|
pushSuspenseContext(workInProgress2, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
|
|
workInProgress2.flags |= DidCapture;
|
|
return null;
|
|
}
|
|
var primaryChildFragment = workInProgress2.child;
|
|
var primaryChildLanes = primaryChildFragment.childLanes;
|
|
if (includesSomeLane(renderLanes2, primaryChildLanes)) {
|
|
return updateSuspenseComponent(current2, workInProgress2, renderLanes2);
|
|
} else {
|
|
pushSuspenseContext(workInProgress2, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
|
|
var child = bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
if (child !== null) {
|
|
return child.sibling;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
} else {
|
|
pushSuspenseContext(workInProgress2, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
|
|
}
|
|
break;
|
|
}
|
|
case SuspenseListComponent: {
|
|
var didSuspendBefore = (current2.flags & DidCapture) !== NoFlags;
|
|
var _hasChildWork = includesSomeLane(renderLanes2, workInProgress2.childLanes);
|
|
if (didSuspendBefore) {
|
|
if (_hasChildWork) {
|
|
return updateSuspenseListComponent(current2, workInProgress2, renderLanes2);
|
|
}
|
|
workInProgress2.flags |= DidCapture;
|
|
}
|
|
var renderState = workInProgress2.memoizedState;
|
|
if (renderState !== null) {
|
|
renderState.rendering = null;
|
|
renderState.tail = null;
|
|
renderState.lastEffect = null;
|
|
}
|
|
pushSuspenseContext(workInProgress2, suspenseStackCursor.current);
|
|
if (_hasChildWork) {
|
|
break;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
case OffscreenComponent:
|
|
case LegacyHiddenComponent: {
|
|
workInProgress2.lanes = NoLanes;
|
|
return updateOffscreenComponent(current2, workInProgress2, renderLanes2);
|
|
}
|
|
}
|
|
return bailoutOnAlreadyFinishedWork(current2, workInProgress2, renderLanes2);
|
|
}
|
|
function beginWork(current2, workInProgress2, renderLanes2) {
|
|
{
|
|
if (workInProgress2._debugNeedsRemount && current2 !== null) {
|
|
return remountFiber(current2, workInProgress2, createFiberFromTypeAndProps(workInProgress2.type, workInProgress2.key, workInProgress2.pendingProps, workInProgress2._debugOwner || null, workInProgress2.mode, workInProgress2.lanes));
|
|
}
|
|
}
|
|
if (current2 !== null) {
|
|
var oldProps = current2.memoizedProps;
|
|
var newProps = workInProgress2.pendingProps;
|
|
if (oldProps !== newProps || hasContextChanged() || workInProgress2.type !== current2.type) {
|
|
didReceiveUpdate = true;
|
|
} else {
|
|
var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current2, renderLanes2);
|
|
if (!hasScheduledUpdateOrContext && (workInProgress2.flags & DidCapture) === NoFlags) {
|
|
didReceiveUpdate = false;
|
|
return attemptEarlyBailoutIfNoScheduledUpdate(current2, workInProgress2, renderLanes2);
|
|
}
|
|
if ((current2.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
|
|
didReceiveUpdate = true;
|
|
} else {
|
|
didReceiveUpdate = false;
|
|
}
|
|
}
|
|
} else {
|
|
didReceiveUpdate = false;
|
|
if (getIsHydrating() && isForkedChild(workInProgress2)) {
|
|
var slotIndex = workInProgress2.index;
|
|
var numberOfForks = getForksAtLevel();
|
|
pushTreeId(workInProgress2, numberOfForks, slotIndex);
|
|
}
|
|
}
|
|
workInProgress2.lanes = NoLanes;
|
|
switch (workInProgress2.tag) {
|
|
case IndeterminateComponent: {
|
|
return mountIndeterminateComponent(current2, workInProgress2, workInProgress2.type, renderLanes2);
|
|
}
|
|
case LazyComponent: {
|
|
var elementType = workInProgress2.elementType;
|
|
return mountLazyComponent(current2, workInProgress2, elementType, renderLanes2);
|
|
}
|
|
case FunctionComponent: {
|
|
var Component = workInProgress2.type;
|
|
var unresolvedProps = workInProgress2.pendingProps;
|
|
var resolvedProps = workInProgress2.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
|
|
return updateFunctionComponent(current2, workInProgress2, Component, resolvedProps, renderLanes2);
|
|
}
|
|
case ClassComponent: {
|
|
var _Component = workInProgress2.type;
|
|
var _unresolvedProps = workInProgress2.pendingProps;
|
|
var _resolvedProps = workInProgress2.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
|
|
return updateClassComponent(current2, workInProgress2, _Component, _resolvedProps, renderLanes2);
|
|
}
|
|
case HostRoot:
|
|
return updateHostRoot(current2, workInProgress2, renderLanes2);
|
|
case HostComponent:
|
|
return updateHostComponent$1(current2, workInProgress2, renderLanes2);
|
|
case HostText:
|
|
return updateHostText$1(current2, workInProgress2);
|
|
case SuspenseComponent:
|
|
return updateSuspenseComponent(current2, workInProgress2, renderLanes2);
|
|
case HostPortal:
|
|
return updatePortalComponent(current2, workInProgress2, renderLanes2);
|
|
case ForwardRef: {
|
|
var type = workInProgress2.type;
|
|
var _unresolvedProps2 = workInProgress2.pendingProps;
|
|
var _resolvedProps2 = workInProgress2.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
|
|
return updateForwardRef(current2, workInProgress2, type, _resolvedProps2, renderLanes2);
|
|
}
|
|
case Fragment2:
|
|
return updateFragment(current2, workInProgress2, renderLanes2);
|
|
case Mode:
|
|
return updateMode(current2, workInProgress2, renderLanes2);
|
|
case Profiler:
|
|
return updateProfiler(current2, workInProgress2, renderLanes2);
|
|
case ContextProvider:
|
|
return updateContextProvider(current2, workInProgress2, renderLanes2);
|
|
case ContextConsumer:
|
|
return updateContextConsumer(current2, workInProgress2, renderLanes2);
|
|
case MemoComponent: {
|
|
var _type2 = workInProgress2.type;
|
|
var _unresolvedProps3 = workInProgress2.pendingProps;
|
|
var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
|
|
{
|
|
if (workInProgress2.type !== workInProgress2.elementType) {
|
|
var outerPropTypes = _type2.propTypes;
|
|
if (outerPropTypes) {
|
|
checkPropTypes(outerPropTypes, _resolvedProps3, "prop", getComponentNameFromType(_type2));
|
|
}
|
|
}
|
|
}
|
|
_resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
|
|
return updateMemoComponent(current2, workInProgress2, _type2, _resolvedProps3, renderLanes2);
|
|
}
|
|
case SimpleMemoComponent: {
|
|
return updateSimpleMemoComponent(current2, workInProgress2, workInProgress2.type, workInProgress2.pendingProps, renderLanes2);
|
|
}
|
|
case IncompleteClassComponent: {
|
|
var _Component2 = workInProgress2.type;
|
|
var _unresolvedProps4 = workInProgress2.pendingProps;
|
|
var _resolvedProps4 = workInProgress2.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
|
|
return mountIncompleteClassComponent(current2, workInProgress2, _Component2, _resolvedProps4, renderLanes2);
|
|
}
|
|
case SuspenseListComponent: {
|
|
return updateSuspenseListComponent(current2, workInProgress2, renderLanes2);
|
|
}
|
|
case ScopeComponent: {
|
|
break;
|
|
}
|
|
case OffscreenComponent: {
|
|
return updateOffscreenComponent(current2, workInProgress2, renderLanes2);
|
|
}
|
|
}
|
|
throw new Error("Unknown unit of work tag (" + workInProgress2.tag + "). This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
function unwindWork(current2, workInProgress2, renderLanes2) {
|
|
popTreeContext(workInProgress2);
|
|
switch (workInProgress2.tag) {
|
|
case ClassComponent: {
|
|
var Component = workInProgress2.type;
|
|
if (isContextProvider(Component)) {
|
|
popContext(workInProgress2);
|
|
}
|
|
var flags = workInProgress2.flags;
|
|
if (flags & ShouldCapture) {
|
|
workInProgress2.flags = flags & ~ShouldCapture | DidCapture;
|
|
if ((workInProgress2.mode & ProfileMode) !== NoMode) {
|
|
transferActualDuration(workInProgress2);
|
|
}
|
|
return workInProgress2;
|
|
}
|
|
return null;
|
|
}
|
|
case HostRoot: {
|
|
var root3 = workInProgress2.stateNode;
|
|
popHostContainer(workInProgress2);
|
|
popTopLevelContextObject(workInProgress2);
|
|
resetWorkInProgressVersions();
|
|
var _flags = workInProgress2.flags;
|
|
if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
|
|
workInProgress2.flags = _flags & ~ShouldCapture | DidCapture;
|
|
return workInProgress2;
|
|
}
|
|
return null;
|
|
}
|
|
case HostComponent: {
|
|
popHostContext(workInProgress2);
|
|
return null;
|
|
}
|
|
case SuspenseComponent: {
|
|
popSuspenseContext(workInProgress2);
|
|
var suspenseState = workInProgress2.memoizedState;
|
|
if (suspenseState !== null && suspenseState.dehydrated !== null) {
|
|
if (workInProgress2.alternate === null) {
|
|
throw new Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue.");
|
|
}
|
|
resetHydrationState();
|
|
}
|
|
var _flags2 = workInProgress2.flags;
|
|
if (_flags2 & ShouldCapture) {
|
|
workInProgress2.flags = _flags2 & ~ShouldCapture | DidCapture;
|
|
if ((workInProgress2.mode & ProfileMode) !== NoMode) {
|
|
transferActualDuration(workInProgress2);
|
|
}
|
|
return workInProgress2;
|
|
}
|
|
return null;
|
|
}
|
|
case SuspenseListComponent: {
|
|
popSuspenseContext(workInProgress2);
|
|
return null;
|
|
}
|
|
case HostPortal:
|
|
popHostContainer(workInProgress2);
|
|
return null;
|
|
case ContextProvider:
|
|
var context = workInProgress2.type._context;
|
|
popProvider(context, workInProgress2);
|
|
return null;
|
|
case OffscreenComponent:
|
|
case LegacyHiddenComponent:
|
|
popRenderLanes(workInProgress2);
|
|
return null;
|
|
case CacheComponent:
|
|
return null;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
function unwindInterruptedWork(current2, interruptedWork, renderLanes2) {
|
|
popTreeContext(interruptedWork);
|
|
switch (interruptedWork.tag) {
|
|
case ClassComponent: {
|
|
var childContextTypes = interruptedWork.type.childContextTypes;
|
|
if (childContextTypes !== null && childContextTypes !== void 0) {
|
|
popContext(interruptedWork);
|
|
}
|
|
break;
|
|
}
|
|
case HostRoot: {
|
|
var root3 = interruptedWork.stateNode;
|
|
popHostContainer(interruptedWork);
|
|
popTopLevelContextObject(interruptedWork);
|
|
resetWorkInProgressVersions();
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
popHostContext(interruptedWork);
|
|
break;
|
|
}
|
|
case HostPortal:
|
|
popHostContainer(interruptedWork);
|
|
break;
|
|
case SuspenseComponent:
|
|
popSuspenseContext(interruptedWork);
|
|
break;
|
|
case SuspenseListComponent:
|
|
popSuspenseContext(interruptedWork);
|
|
break;
|
|
case ContextProvider:
|
|
var context = interruptedWork.type._context;
|
|
popProvider(context, interruptedWork);
|
|
break;
|
|
case OffscreenComponent:
|
|
case LegacyHiddenComponent:
|
|
popRenderLanes(interruptedWork);
|
|
break;
|
|
}
|
|
}
|
|
var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
|
|
{
|
|
didWarnAboutUndefinedSnapshotBeforeUpdate = /* @__PURE__ */ new Set();
|
|
}
|
|
var offscreenSubtreeIsHidden = false;
|
|
var offscreenSubtreeWasHidden = false;
|
|
var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set;
|
|
var nextEffect = null;
|
|
var inProgressLanes = null;
|
|
var inProgressRoot = null;
|
|
function reportUncaughtErrorInDEV(error2) {
|
|
{
|
|
invokeGuardedCallback(null, function() {
|
|
throw error2;
|
|
});
|
|
clearCaughtError();
|
|
}
|
|
}
|
|
var callComponentWillUnmountWithTimer = function(current2, instance) {
|
|
instance.props = current2.memoizedProps;
|
|
instance.state = current2.memoizedState;
|
|
if (current2.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
instance.componentWillUnmount();
|
|
} finally {
|
|
recordLayoutEffectDuration(current2);
|
|
}
|
|
} else {
|
|
instance.componentWillUnmount();
|
|
}
|
|
};
|
|
function safelyCallCommitHookLayoutEffectListMount(current2, nearestMountedAncestor) {
|
|
try {
|
|
commitHookEffectListMount(Layout, current2);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(current2, nearestMountedAncestor, error2);
|
|
}
|
|
}
|
|
function safelyCallComponentWillUnmount(current2, nearestMountedAncestor, instance) {
|
|
try {
|
|
callComponentWillUnmountWithTimer(current2, instance);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(current2, nearestMountedAncestor, error2);
|
|
}
|
|
}
|
|
function safelyCallComponentDidMount(current2, nearestMountedAncestor, instance) {
|
|
try {
|
|
instance.componentDidMount();
|
|
} catch (error2) {
|
|
captureCommitPhaseError(current2, nearestMountedAncestor, error2);
|
|
}
|
|
}
|
|
function safelyAttachRef(current2, nearestMountedAncestor) {
|
|
try {
|
|
commitAttachRef(current2);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(current2, nearestMountedAncestor, error2);
|
|
}
|
|
}
|
|
function safelyDetachRef(current2, nearestMountedAncestor) {
|
|
var ref = current2.ref;
|
|
if (ref !== null) {
|
|
if (typeof ref === "function") {
|
|
var retVal;
|
|
try {
|
|
if (enableProfilerTimer && enableProfilerCommitHooks && current2.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
retVal = ref(null);
|
|
} finally {
|
|
recordLayoutEffectDuration(current2);
|
|
}
|
|
} else {
|
|
retVal = ref(null);
|
|
}
|
|
} catch (error2) {
|
|
captureCommitPhaseError(current2, nearestMountedAncestor, error2);
|
|
}
|
|
{
|
|
if (typeof retVal === "function") {
|
|
error("Unexpected return value from a callback ref in %s. A callback ref should not return a function.", getComponentNameFromFiber(current2));
|
|
}
|
|
}
|
|
} else {
|
|
ref.current = null;
|
|
}
|
|
}
|
|
}
|
|
function safelyCallDestroy(current2, nearestMountedAncestor, destroy) {
|
|
try {
|
|
destroy();
|
|
} catch (error2) {
|
|
captureCommitPhaseError(current2, nearestMountedAncestor, error2);
|
|
}
|
|
}
|
|
var focusedInstanceHandle = null;
|
|
var shouldFireAfterActiveInstanceBlur = false;
|
|
function commitBeforeMutationEffects(root3, firstChild) {
|
|
focusedInstanceHandle = prepareForCommit(root3.containerInfo);
|
|
nextEffect = firstChild;
|
|
commitBeforeMutationEffects_begin();
|
|
var shouldFire = shouldFireAfterActiveInstanceBlur;
|
|
shouldFireAfterActiveInstanceBlur = false;
|
|
focusedInstanceHandle = null;
|
|
return shouldFire;
|
|
}
|
|
function commitBeforeMutationEffects_begin() {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var child = fiber.child;
|
|
if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
|
|
child.return = fiber;
|
|
nextEffect = child;
|
|
} else {
|
|
commitBeforeMutationEffects_complete();
|
|
}
|
|
}
|
|
}
|
|
function commitBeforeMutationEffects_complete() {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
setCurrentFiber(fiber);
|
|
try {
|
|
commitBeforeMutationEffectsOnFiber(fiber);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
resetCurrentFiber();
|
|
var sibling = fiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = fiber.return;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = fiber.return;
|
|
}
|
|
}
|
|
function commitBeforeMutationEffectsOnFiber(finishedWork) {
|
|
var current2 = finishedWork.alternate;
|
|
var flags = finishedWork.flags;
|
|
if ((flags & Snapshot) !== NoFlags) {
|
|
setCurrentFiber(finishedWork);
|
|
switch (finishedWork.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
if (current2 !== null) {
|
|
var prevProps = current2.memoizedProps;
|
|
var prevState = current2.memoizedState;
|
|
var instance = finishedWork.stateNode;
|
|
{
|
|
if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
|
|
if (instance.props !== finishedWork.memoizedProps) {
|
|
error("Expected %s props to match memoized props before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
if (instance.state !== finishedWork.memoizedState) {
|
|
error("Expected %s state to match memoized state before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
}
|
|
}
|
|
var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
|
|
{
|
|
var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
|
|
if (snapshot === void 0 && !didWarnSet.has(finishedWork.type)) {
|
|
didWarnSet.add(finishedWork.type);
|
|
error("%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.", getComponentNameFromFiber(finishedWork));
|
|
}
|
|
}
|
|
instance.__reactInternalSnapshotBeforeUpdate = snapshot;
|
|
}
|
|
break;
|
|
}
|
|
case HostRoot: {
|
|
{
|
|
var root3 = finishedWork.stateNode;
|
|
clearContainer(root3.containerInfo);
|
|
}
|
|
break;
|
|
}
|
|
case HostComponent:
|
|
case HostText:
|
|
case HostPortal:
|
|
case IncompleteClassComponent:
|
|
break;
|
|
default: {
|
|
throw new Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
resetCurrentFiber();
|
|
}
|
|
}
|
|
function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
|
|
var updateQueue = finishedWork.updateQueue;
|
|
var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
|
|
if (lastEffect !== null) {
|
|
var firstEffect = lastEffect.next;
|
|
var effect = firstEffect;
|
|
do {
|
|
if ((effect.tag & flags) === flags) {
|
|
var destroy = effect.destroy;
|
|
effect.destroy = void 0;
|
|
if (destroy !== void 0) {
|
|
{
|
|
if ((flags & Passive$1) !== NoFlags$1) {
|
|
markComponentPassiveEffectUnmountStarted(finishedWork);
|
|
} else if ((flags & Layout) !== NoFlags$1) {
|
|
markComponentLayoutEffectUnmountStarted(finishedWork);
|
|
}
|
|
}
|
|
{
|
|
if ((flags & Insertion) !== NoFlags$1) {
|
|
setIsRunningInsertionEffect(true);
|
|
}
|
|
}
|
|
safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
|
|
{
|
|
if ((flags & Insertion) !== NoFlags$1) {
|
|
setIsRunningInsertionEffect(false);
|
|
}
|
|
}
|
|
{
|
|
if ((flags & Passive$1) !== NoFlags$1) {
|
|
markComponentPassiveEffectUnmountStopped();
|
|
} else if ((flags & Layout) !== NoFlags$1) {
|
|
markComponentLayoutEffectUnmountStopped();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
effect = effect.next;
|
|
} while (effect !== firstEffect);
|
|
}
|
|
}
|
|
function commitHookEffectListMount(flags, finishedWork) {
|
|
var updateQueue = finishedWork.updateQueue;
|
|
var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
|
|
if (lastEffect !== null) {
|
|
var firstEffect = lastEffect.next;
|
|
var effect = firstEffect;
|
|
do {
|
|
if ((effect.tag & flags) === flags) {
|
|
{
|
|
if ((flags & Passive$1) !== NoFlags$1) {
|
|
markComponentPassiveEffectMountStarted(finishedWork);
|
|
} else if ((flags & Layout) !== NoFlags$1) {
|
|
markComponentLayoutEffectMountStarted(finishedWork);
|
|
}
|
|
}
|
|
var create = effect.create;
|
|
{
|
|
if ((flags & Insertion) !== NoFlags$1) {
|
|
setIsRunningInsertionEffect(true);
|
|
}
|
|
}
|
|
effect.destroy = create();
|
|
{
|
|
if ((flags & Insertion) !== NoFlags$1) {
|
|
setIsRunningInsertionEffect(false);
|
|
}
|
|
}
|
|
{
|
|
if ((flags & Passive$1) !== NoFlags$1) {
|
|
markComponentPassiveEffectMountStopped();
|
|
} else if ((flags & Layout) !== NoFlags$1) {
|
|
markComponentLayoutEffectMountStopped();
|
|
}
|
|
}
|
|
{
|
|
var destroy = effect.destroy;
|
|
if (destroy !== void 0 && typeof destroy !== "function") {
|
|
var hookName = void 0;
|
|
if ((effect.tag & Layout) !== NoFlags) {
|
|
hookName = "useLayoutEffect";
|
|
} else if ((effect.tag & Insertion) !== NoFlags) {
|
|
hookName = "useInsertionEffect";
|
|
} else {
|
|
hookName = "useEffect";
|
|
}
|
|
var addendum = void 0;
|
|
if (destroy === null) {
|
|
addendum = " You returned null. If your effect does not require clean up, return undefined (or nothing).";
|
|
} else if (typeof destroy.then === "function") {
|
|
addendum = "\n\nIt looks like you wrote " + hookName + "(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately:\n\n" + hookName + "(() => {\n async function fetchData() {\n // You can await here\n const response = await MyAPI.getData(someId);\n // ...\n }\n fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching";
|
|
} else {
|
|
addendum = " You returned: " + destroy;
|
|
}
|
|
error("%s must not return anything besides a function, which is used for clean-up.%s", hookName, addendum);
|
|
}
|
|
}
|
|
}
|
|
effect = effect.next;
|
|
} while (effect !== firstEffect);
|
|
}
|
|
}
|
|
function commitPassiveEffectDurations(finishedRoot, finishedWork) {
|
|
{
|
|
if ((finishedWork.flags & Update) !== NoFlags) {
|
|
switch (finishedWork.tag) {
|
|
case Profiler: {
|
|
var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
|
|
var _finishedWork$memoize = finishedWork.memoizedProps, id = _finishedWork$memoize.id, onPostCommit = _finishedWork$memoize.onPostCommit;
|
|
var commitTime2 = getCommitTime();
|
|
var phase = finishedWork.alternate === null ? "mount" : "update";
|
|
{
|
|
if (isCurrentUpdateNested()) {
|
|
phase = "nested-update";
|
|
}
|
|
}
|
|
if (typeof onPostCommit === "function") {
|
|
onPostCommit(id, phase, passiveEffectDuration, commitTime2);
|
|
}
|
|
var parentFiber = finishedWork.return;
|
|
outer:
|
|
while (parentFiber !== null) {
|
|
switch (parentFiber.tag) {
|
|
case HostRoot:
|
|
var root3 = parentFiber.stateNode;
|
|
root3.passiveEffectDuration += passiveEffectDuration;
|
|
break outer;
|
|
case Profiler:
|
|
var parentStateNode = parentFiber.stateNode;
|
|
parentStateNode.passiveEffectDuration += passiveEffectDuration;
|
|
break outer;
|
|
}
|
|
parentFiber = parentFiber.return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function commitLayoutEffectOnFiber(finishedRoot, current2, finishedWork, committedLanes) {
|
|
if ((finishedWork.flags & LayoutMask) !== NoFlags) {
|
|
switch (finishedWork.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
if (!offscreenSubtreeWasHidden) {
|
|
if (finishedWork.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
commitHookEffectListMount(Layout | HasEffect, finishedWork);
|
|
} finally {
|
|
recordLayoutEffectDuration(finishedWork);
|
|
}
|
|
} else {
|
|
commitHookEffectListMount(Layout | HasEffect, finishedWork);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
var instance = finishedWork.stateNode;
|
|
if (finishedWork.flags & Update) {
|
|
if (!offscreenSubtreeWasHidden) {
|
|
if (current2 === null) {
|
|
{
|
|
if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
|
|
if (instance.props !== finishedWork.memoizedProps) {
|
|
error("Expected %s props to match memoized props before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
if (instance.state !== finishedWork.memoizedState) {
|
|
error("Expected %s state to match memoized state before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
}
|
|
}
|
|
if (finishedWork.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
instance.componentDidMount();
|
|
} finally {
|
|
recordLayoutEffectDuration(finishedWork);
|
|
}
|
|
} else {
|
|
instance.componentDidMount();
|
|
}
|
|
} else {
|
|
var prevProps = finishedWork.elementType === finishedWork.type ? current2.memoizedProps : resolveDefaultProps(finishedWork.type, current2.memoizedProps);
|
|
var prevState = current2.memoizedState;
|
|
{
|
|
if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
|
|
if (instance.props !== finishedWork.memoizedProps) {
|
|
error("Expected %s props to match memoized props before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
if (instance.state !== finishedWork.memoizedState) {
|
|
error("Expected %s state to match memoized state before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
}
|
|
}
|
|
if (finishedWork.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
|
|
} finally {
|
|
recordLayoutEffectDuration(finishedWork);
|
|
}
|
|
} else {
|
|
instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var updateQueue = finishedWork.updateQueue;
|
|
if (updateQueue !== null) {
|
|
{
|
|
if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
|
|
if (instance.props !== finishedWork.memoizedProps) {
|
|
error("Expected %s props to match memoized props before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
if (instance.state !== finishedWork.memoizedState) {
|
|
error("Expected %s state to match memoized state before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
|
|
}
|
|
}
|
|
}
|
|
commitUpdateQueue(finishedWork, updateQueue, instance);
|
|
}
|
|
break;
|
|
}
|
|
case HostRoot: {
|
|
var _updateQueue = finishedWork.updateQueue;
|
|
if (_updateQueue !== null) {
|
|
var _instance = null;
|
|
if (finishedWork.child !== null) {
|
|
switch (finishedWork.child.tag) {
|
|
case HostComponent:
|
|
_instance = getPublicInstance(finishedWork.child.stateNode);
|
|
break;
|
|
case ClassComponent:
|
|
_instance = finishedWork.child.stateNode;
|
|
break;
|
|
}
|
|
}
|
|
commitUpdateQueue(finishedWork, _updateQueue, _instance);
|
|
}
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
var _instance2 = finishedWork.stateNode;
|
|
if (current2 === null && finishedWork.flags & Update) {
|
|
var type = finishedWork.type;
|
|
var props = finishedWork.memoizedProps;
|
|
commitMount(_instance2, type, props);
|
|
}
|
|
break;
|
|
}
|
|
case HostText: {
|
|
break;
|
|
}
|
|
case HostPortal: {
|
|
break;
|
|
}
|
|
case Profiler: {
|
|
{
|
|
var _finishedWork$memoize2 = finishedWork.memoizedProps, onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender;
|
|
var effectDuration = finishedWork.stateNode.effectDuration;
|
|
var commitTime2 = getCommitTime();
|
|
var phase = current2 === null ? "mount" : "update";
|
|
{
|
|
if (isCurrentUpdateNested()) {
|
|
phase = "nested-update";
|
|
}
|
|
}
|
|
if (typeof onRender === "function") {
|
|
onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime2);
|
|
}
|
|
{
|
|
if (typeof onCommit === "function") {
|
|
onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime2);
|
|
}
|
|
enqueuePendingPassiveProfilerEffect(finishedWork);
|
|
var parentFiber = finishedWork.return;
|
|
outer:
|
|
while (parentFiber !== null) {
|
|
switch (parentFiber.tag) {
|
|
case HostRoot:
|
|
var root3 = parentFiber.stateNode;
|
|
root3.effectDuration += effectDuration;
|
|
break outer;
|
|
case Profiler:
|
|
var parentStateNode = parentFiber.stateNode;
|
|
parentStateNode.effectDuration += effectDuration;
|
|
break outer;
|
|
}
|
|
parentFiber = parentFiber.return;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SuspenseComponent: {
|
|
commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
|
|
break;
|
|
}
|
|
case SuspenseListComponent:
|
|
case IncompleteClassComponent:
|
|
case ScopeComponent:
|
|
case OffscreenComponent:
|
|
case LegacyHiddenComponent: {
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
if (!offscreenSubtreeWasHidden) {
|
|
{
|
|
if (finishedWork.flags & Ref) {
|
|
commitAttachRef(finishedWork);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function reappearLayoutEffectsOnFiber(node) {
|
|
switch (node.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
if (node.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
safelyCallCommitHookLayoutEffectListMount(node, node.return);
|
|
} finally {
|
|
recordLayoutEffectDuration(node);
|
|
}
|
|
} else {
|
|
safelyCallCommitHookLayoutEffectListMount(node, node.return);
|
|
}
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
var instance = node.stateNode;
|
|
if (typeof instance.componentDidMount === "function") {
|
|
safelyCallComponentDidMount(node, node.return, instance);
|
|
}
|
|
safelyAttachRef(node, node.return);
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
safelyAttachRef(node, node.return);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function hideOrUnhideAllChildren(finishedWork, isHidden) {
|
|
var hostSubtreeRoot = null;
|
|
{
|
|
var node = finishedWork;
|
|
while (true) {
|
|
if (node.tag === HostComponent) {
|
|
if (hostSubtreeRoot === null) {
|
|
hostSubtreeRoot = node;
|
|
try {
|
|
var instance = node.stateNode;
|
|
if (isHidden) {
|
|
hideInstance(instance);
|
|
} else {
|
|
unhideInstance(node.stateNode, node.memoizedProps);
|
|
}
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
} else if (node.tag === HostText) {
|
|
if (hostSubtreeRoot === null) {
|
|
try {
|
|
var _instance3 = node.stateNode;
|
|
if (isHidden) {
|
|
hideTextInstance(_instance3);
|
|
} else {
|
|
unhideTextInstance(_instance3, node.memoizedProps);
|
|
}
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
} else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork)
|
|
;
|
|
else if (node.child !== null) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === finishedWork) {
|
|
return;
|
|
}
|
|
while (node.sibling === null) {
|
|
if (node.return === null || node.return === finishedWork) {
|
|
return;
|
|
}
|
|
if (hostSubtreeRoot === node) {
|
|
hostSubtreeRoot = null;
|
|
}
|
|
node = node.return;
|
|
}
|
|
if (hostSubtreeRoot === node) {
|
|
hostSubtreeRoot = null;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
}
|
|
}
|
|
function commitAttachRef(finishedWork) {
|
|
var ref = finishedWork.ref;
|
|
if (ref !== null) {
|
|
var instance = finishedWork.stateNode;
|
|
var instanceToUse;
|
|
switch (finishedWork.tag) {
|
|
case HostComponent:
|
|
instanceToUse = getPublicInstance(instance);
|
|
break;
|
|
default:
|
|
instanceToUse = instance;
|
|
}
|
|
if (typeof ref === "function") {
|
|
var retVal;
|
|
if (finishedWork.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
retVal = ref(instanceToUse);
|
|
} finally {
|
|
recordLayoutEffectDuration(finishedWork);
|
|
}
|
|
} else {
|
|
retVal = ref(instanceToUse);
|
|
}
|
|
{
|
|
if (typeof retVal === "function") {
|
|
error("Unexpected return value from a callback ref in %s. A callback ref should not return a function.", getComponentNameFromFiber(finishedWork));
|
|
}
|
|
}
|
|
} else {
|
|
{
|
|
if (!ref.hasOwnProperty("current")) {
|
|
error("Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().", getComponentNameFromFiber(finishedWork));
|
|
}
|
|
}
|
|
ref.current = instanceToUse;
|
|
}
|
|
}
|
|
}
|
|
function detachFiberMutation(fiber) {
|
|
var alternate = fiber.alternate;
|
|
if (alternate !== null) {
|
|
alternate.return = null;
|
|
}
|
|
fiber.return = null;
|
|
}
|
|
function detachFiberAfterEffects(fiber) {
|
|
var alternate = fiber.alternate;
|
|
if (alternate !== null) {
|
|
fiber.alternate = null;
|
|
detachFiberAfterEffects(alternate);
|
|
}
|
|
{
|
|
fiber.child = null;
|
|
fiber.deletions = null;
|
|
fiber.sibling = null;
|
|
if (fiber.tag === HostComponent) {
|
|
var hostInstance = fiber.stateNode;
|
|
if (hostInstance !== null) {
|
|
detachDeletedInstance(hostInstance);
|
|
}
|
|
}
|
|
fiber.stateNode = null;
|
|
{
|
|
fiber._debugOwner = null;
|
|
}
|
|
{
|
|
fiber.return = null;
|
|
fiber.dependencies = null;
|
|
fiber.memoizedProps = null;
|
|
fiber.memoizedState = null;
|
|
fiber.pendingProps = null;
|
|
fiber.stateNode = null;
|
|
fiber.updateQueue = null;
|
|
}
|
|
}
|
|
}
|
|
function getHostParentFiber(fiber) {
|
|
var parent = fiber.return;
|
|
while (parent !== null) {
|
|
if (isHostParent(parent)) {
|
|
return parent;
|
|
}
|
|
parent = parent.return;
|
|
}
|
|
throw new Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
function isHostParent(fiber) {
|
|
return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
|
|
}
|
|
function getHostSibling(fiber) {
|
|
var node = fiber;
|
|
siblings:
|
|
while (true) {
|
|
while (node.sibling === null) {
|
|
if (node.return === null || isHostParent(node.return)) {
|
|
return null;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
|
|
if (node.flags & Placement) {
|
|
continue siblings;
|
|
}
|
|
if (node.child === null || node.tag === HostPortal) {
|
|
continue siblings;
|
|
} else {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
}
|
|
}
|
|
if (!(node.flags & Placement)) {
|
|
return node.stateNode;
|
|
}
|
|
}
|
|
}
|
|
function commitPlacement(finishedWork) {
|
|
var parentFiber = getHostParentFiber(finishedWork);
|
|
switch (parentFiber.tag) {
|
|
case HostComponent: {
|
|
var parent = parentFiber.stateNode;
|
|
if (parentFiber.flags & ContentReset) {
|
|
resetTextContent(parent);
|
|
parentFiber.flags &= ~ContentReset;
|
|
}
|
|
var before = getHostSibling(finishedWork);
|
|
insertOrAppendPlacementNode(finishedWork, before, parent);
|
|
break;
|
|
}
|
|
case HostRoot:
|
|
case HostPortal: {
|
|
var _parent = parentFiber.stateNode.containerInfo;
|
|
var _before = getHostSibling(finishedWork);
|
|
insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
|
|
var tag = node.tag;
|
|
var isHost = tag === HostComponent || tag === HostText;
|
|
if (isHost) {
|
|
var stateNode = node.stateNode;
|
|
if (before) {
|
|
insertInContainerBefore(parent, stateNode, before);
|
|
} else {
|
|
appendChildToContainer(parent, stateNode);
|
|
}
|
|
} else if (tag === HostPortal)
|
|
;
|
|
else {
|
|
var child = node.child;
|
|
if (child !== null) {
|
|
insertOrAppendPlacementNodeIntoContainer(child, before, parent);
|
|
var sibling = child.sibling;
|
|
while (sibling !== null) {
|
|
insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
|
|
sibling = sibling.sibling;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function insertOrAppendPlacementNode(node, before, parent) {
|
|
var tag = node.tag;
|
|
var isHost = tag === HostComponent || tag === HostText;
|
|
if (isHost) {
|
|
var stateNode = node.stateNode;
|
|
if (before) {
|
|
insertBefore(parent, stateNode, before);
|
|
} else {
|
|
appendChild(parent, stateNode);
|
|
}
|
|
} else if (tag === HostPortal)
|
|
;
|
|
else {
|
|
var child = node.child;
|
|
if (child !== null) {
|
|
insertOrAppendPlacementNode(child, before, parent);
|
|
var sibling = child.sibling;
|
|
while (sibling !== null) {
|
|
insertOrAppendPlacementNode(sibling, before, parent);
|
|
sibling = sibling.sibling;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var hostParent = null;
|
|
var hostParentIsContainer = false;
|
|
function commitDeletionEffects(root3, returnFiber, deletedFiber) {
|
|
{
|
|
var parent = returnFiber;
|
|
findParent:
|
|
while (parent !== null) {
|
|
switch (parent.tag) {
|
|
case HostComponent: {
|
|
hostParent = parent.stateNode;
|
|
hostParentIsContainer = false;
|
|
break findParent;
|
|
}
|
|
case HostRoot: {
|
|
hostParent = parent.stateNode.containerInfo;
|
|
hostParentIsContainer = true;
|
|
break findParent;
|
|
}
|
|
case HostPortal: {
|
|
hostParent = parent.stateNode.containerInfo;
|
|
hostParentIsContainer = true;
|
|
break findParent;
|
|
}
|
|
}
|
|
parent = parent.return;
|
|
}
|
|
if (hostParent === null) {
|
|
throw new Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
commitDeletionEffectsOnFiber(root3, returnFiber, deletedFiber);
|
|
hostParent = null;
|
|
hostParentIsContainer = false;
|
|
}
|
|
detachFiberMutation(deletedFiber);
|
|
}
|
|
function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) {
|
|
var child = parent.child;
|
|
while (child !== null) {
|
|
commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child);
|
|
child = child.sibling;
|
|
}
|
|
}
|
|
function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) {
|
|
onCommitUnmount(deletedFiber);
|
|
switch (deletedFiber.tag) {
|
|
case HostComponent: {
|
|
if (!offscreenSubtreeWasHidden) {
|
|
safelyDetachRef(deletedFiber, nearestMountedAncestor);
|
|
}
|
|
}
|
|
case HostText: {
|
|
{
|
|
var prevHostParent = hostParent;
|
|
var prevHostParentIsContainer = hostParentIsContainer;
|
|
hostParent = null;
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
hostParent = prevHostParent;
|
|
hostParentIsContainer = prevHostParentIsContainer;
|
|
if (hostParent !== null) {
|
|
if (hostParentIsContainer) {
|
|
removeChildFromContainer(hostParent, deletedFiber.stateNode);
|
|
} else {
|
|
removeChild(hostParent, deletedFiber.stateNode);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case DehydratedFragment: {
|
|
{
|
|
if (hostParent !== null) {
|
|
if (hostParentIsContainer) {
|
|
clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode);
|
|
} else {
|
|
clearSuspenseBoundary(hostParent, deletedFiber.stateNode);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case HostPortal: {
|
|
{
|
|
var _prevHostParent = hostParent;
|
|
var _prevHostParentIsContainer = hostParentIsContainer;
|
|
hostParent = deletedFiber.stateNode.containerInfo;
|
|
hostParentIsContainer = true;
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
hostParent = _prevHostParent;
|
|
hostParentIsContainer = _prevHostParentIsContainer;
|
|
}
|
|
return;
|
|
}
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case MemoComponent:
|
|
case SimpleMemoComponent: {
|
|
if (!offscreenSubtreeWasHidden) {
|
|
var updateQueue = deletedFiber.updateQueue;
|
|
if (updateQueue !== null) {
|
|
var lastEffect = updateQueue.lastEffect;
|
|
if (lastEffect !== null) {
|
|
var firstEffect = lastEffect.next;
|
|
var effect = firstEffect;
|
|
do {
|
|
var _effect = effect, destroy = _effect.destroy, tag = _effect.tag;
|
|
if (destroy !== void 0) {
|
|
if ((tag & Insertion) !== NoFlags$1) {
|
|
safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
|
|
} else if ((tag & Layout) !== NoFlags$1) {
|
|
{
|
|
markComponentLayoutEffectUnmountStarted(deletedFiber);
|
|
}
|
|
if (deletedFiber.mode & ProfileMode) {
|
|
startLayoutEffectTimer();
|
|
safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
|
|
recordLayoutEffectDuration(deletedFiber);
|
|
} else {
|
|
safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
|
|
}
|
|
{
|
|
markComponentLayoutEffectUnmountStopped();
|
|
}
|
|
}
|
|
}
|
|
effect = effect.next;
|
|
} while (effect !== firstEffect);
|
|
}
|
|
}
|
|
}
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
return;
|
|
}
|
|
case ClassComponent: {
|
|
if (!offscreenSubtreeWasHidden) {
|
|
safelyDetachRef(deletedFiber, nearestMountedAncestor);
|
|
var instance = deletedFiber.stateNode;
|
|
if (typeof instance.componentWillUnmount === "function") {
|
|
safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance);
|
|
}
|
|
}
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
return;
|
|
}
|
|
case ScopeComponent: {
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
return;
|
|
}
|
|
case OffscreenComponent: {
|
|
if (deletedFiber.mode & ConcurrentMode) {
|
|
var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
|
|
offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null;
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
|
|
} else {
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function commitSuspenseCallback(finishedWork) {
|
|
var newState = finishedWork.memoizedState;
|
|
}
|
|
function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
|
|
var newState = finishedWork.memoizedState;
|
|
if (newState === null) {
|
|
var current2 = finishedWork.alternate;
|
|
if (current2 !== null) {
|
|
var prevState = current2.memoizedState;
|
|
if (prevState !== null) {
|
|
var suspenseInstance = prevState.dehydrated;
|
|
if (suspenseInstance !== null) {
|
|
commitHydratedSuspenseInstance(suspenseInstance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function attachSuspenseRetryListeners(finishedWork) {
|
|
var wakeables = finishedWork.updateQueue;
|
|
if (wakeables !== null) {
|
|
finishedWork.updateQueue = null;
|
|
var retryCache = finishedWork.stateNode;
|
|
if (retryCache === null) {
|
|
retryCache = finishedWork.stateNode = new PossiblyWeakSet();
|
|
}
|
|
wakeables.forEach(function(wakeable) {
|
|
var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
|
|
if (!retryCache.has(wakeable)) {
|
|
retryCache.add(wakeable);
|
|
{
|
|
if (isDevToolsPresent) {
|
|
if (inProgressLanes !== null && inProgressRoot !== null) {
|
|
restorePendingUpdaters(inProgressRoot, inProgressLanes);
|
|
} else {
|
|
throw Error("Expected finished root and lanes to be set. This is a bug in React.");
|
|
}
|
|
}
|
|
}
|
|
wakeable.then(retry, retry);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function commitMutationEffects(root3, finishedWork, committedLanes) {
|
|
inProgressLanes = committedLanes;
|
|
inProgressRoot = root3;
|
|
setCurrentFiber(finishedWork);
|
|
commitMutationEffectsOnFiber(finishedWork, root3);
|
|
setCurrentFiber(finishedWork);
|
|
inProgressLanes = null;
|
|
inProgressRoot = null;
|
|
}
|
|
function recursivelyTraverseMutationEffects(root3, parentFiber, lanes) {
|
|
var deletions = parentFiber.deletions;
|
|
if (deletions !== null) {
|
|
for (var i = 0; i < deletions.length; i++) {
|
|
var childToDelete = deletions[i];
|
|
try {
|
|
commitDeletionEffects(root3, parentFiber, childToDelete);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(childToDelete, parentFiber, error2);
|
|
}
|
|
}
|
|
}
|
|
var prevDebugFiber = getCurrentFiber();
|
|
if (parentFiber.subtreeFlags & MutationMask) {
|
|
var child = parentFiber.child;
|
|
while (child !== null) {
|
|
setCurrentFiber(child);
|
|
commitMutationEffectsOnFiber(child, root3);
|
|
child = child.sibling;
|
|
}
|
|
}
|
|
setCurrentFiber(prevDebugFiber);
|
|
}
|
|
function commitMutationEffectsOnFiber(finishedWork, root3, lanes) {
|
|
var current2 = finishedWork.alternate;
|
|
var flags = finishedWork.flags;
|
|
switch (finishedWork.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case MemoComponent:
|
|
case SimpleMemoComponent: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Update) {
|
|
try {
|
|
commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
|
|
commitHookEffectListMount(Insertion | HasEffect, finishedWork);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
if (finishedWork.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
recordLayoutEffectDuration(finishedWork);
|
|
} else {
|
|
try {
|
|
commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case ClassComponent: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Ref) {
|
|
if (current2 !== null) {
|
|
safelyDetachRef(current2, current2.return);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case HostComponent: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Ref) {
|
|
if (current2 !== null) {
|
|
safelyDetachRef(current2, current2.return);
|
|
}
|
|
}
|
|
{
|
|
if (finishedWork.flags & ContentReset) {
|
|
var instance = finishedWork.stateNode;
|
|
try {
|
|
resetTextContent(instance);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
if (flags & Update) {
|
|
var _instance4 = finishedWork.stateNode;
|
|
if (_instance4 != null) {
|
|
var newProps = finishedWork.memoizedProps;
|
|
var oldProps = current2 !== null ? current2.memoizedProps : newProps;
|
|
var type = finishedWork.type;
|
|
var updatePayload = finishedWork.updateQueue;
|
|
finishedWork.updateQueue = null;
|
|
if (updatePayload !== null) {
|
|
try {
|
|
commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case HostText: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Update) {
|
|
{
|
|
if (finishedWork.stateNode === null) {
|
|
throw new Error("This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
var textInstance = finishedWork.stateNode;
|
|
var newText = finishedWork.memoizedProps;
|
|
var oldText = current2 !== null ? current2.memoizedProps : newText;
|
|
try {
|
|
commitTextUpdate(textInstance, oldText, newText);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case HostRoot: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Update) {
|
|
{
|
|
if (current2 !== null) {
|
|
var prevRootState = current2.memoizedState;
|
|
if (prevRootState.isDehydrated) {
|
|
try {
|
|
commitHydratedContainer(root3.containerInfo);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case HostPortal: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
return;
|
|
}
|
|
case SuspenseComponent: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
var offscreenFiber = finishedWork.child;
|
|
if (offscreenFiber.flags & Visibility) {
|
|
var newState = offscreenFiber.memoizedState;
|
|
var isHidden = newState !== null;
|
|
if (isHidden) {
|
|
var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null;
|
|
if (!wasHidden) {
|
|
markCommitTimeOfFallback();
|
|
}
|
|
}
|
|
}
|
|
if (flags & Update) {
|
|
try {
|
|
commitSuspenseCallback(finishedWork);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
attachSuspenseRetryListeners(finishedWork);
|
|
}
|
|
return;
|
|
}
|
|
case OffscreenComponent: {
|
|
var _wasHidden = current2 !== null && current2.memoizedState !== null;
|
|
if (finishedWork.mode & ConcurrentMode) {
|
|
var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
|
|
offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || _wasHidden;
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
|
|
} else {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
}
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Visibility) {
|
|
var _newState = finishedWork.memoizedState;
|
|
var _isHidden = _newState !== null;
|
|
var offscreenBoundary = finishedWork;
|
|
{
|
|
hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
|
|
}
|
|
{
|
|
if (_isHidden) {
|
|
if (!_wasHidden) {
|
|
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
|
|
nextEffect = offscreenBoundary;
|
|
var offscreenChild = offscreenBoundary.child;
|
|
while (offscreenChild !== null) {
|
|
nextEffect = offscreenChild;
|
|
disappearLayoutEffects_begin(offscreenChild);
|
|
offscreenChild = offscreenChild.sibling;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
case SuspenseListComponent: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
if (flags & Update) {
|
|
attachSuspenseRetryListeners(finishedWork);
|
|
}
|
|
return;
|
|
}
|
|
case ScopeComponent: {
|
|
return;
|
|
}
|
|
default: {
|
|
recursivelyTraverseMutationEffects(root3, finishedWork);
|
|
commitReconciliationEffects(finishedWork);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function commitReconciliationEffects(finishedWork) {
|
|
var flags = finishedWork.flags;
|
|
if (flags & Placement) {
|
|
try {
|
|
commitPlacement(finishedWork);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(finishedWork, finishedWork.return, error2);
|
|
}
|
|
finishedWork.flags &= ~Placement;
|
|
}
|
|
if (flags & Hydrating) {
|
|
finishedWork.flags &= ~Hydrating;
|
|
}
|
|
}
|
|
function commitLayoutEffects(finishedWork, root3, committedLanes) {
|
|
inProgressLanes = committedLanes;
|
|
inProgressRoot = root3;
|
|
nextEffect = finishedWork;
|
|
commitLayoutEffects_begin(finishedWork, root3, committedLanes);
|
|
inProgressLanes = null;
|
|
inProgressRoot = null;
|
|
}
|
|
function commitLayoutEffects_begin(subtreeRoot, root3, committedLanes) {
|
|
var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var firstChild = fiber.child;
|
|
if (fiber.tag === OffscreenComponent && isModernRoot) {
|
|
var isHidden = fiber.memoizedState !== null;
|
|
var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden;
|
|
if (newOffscreenSubtreeIsHidden) {
|
|
commitLayoutMountEffects_complete(subtreeRoot, root3, committedLanes);
|
|
continue;
|
|
} else {
|
|
var current2 = fiber.alternate;
|
|
var wasHidden = current2 !== null && current2.memoizedState !== null;
|
|
var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden;
|
|
var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
|
|
var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
|
|
offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden;
|
|
offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden;
|
|
if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) {
|
|
nextEffect = fiber;
|
|
reappearLayoutEffects_begin(fiber);
|
|
}
|
|
var child = firstChild;
|
|
while (child !== null) {
|
|
nextEffect = child;
|
|
commitLayoutEffects_begin(child, root3, committedLanes);
|
|
child = child.sibling;
|
|
}
|
|
nextEffect = fiber;
|
|
offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
|
|
offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
|
|
commitLayoutMountEffects_complete(subtreeRoot, root3, committedLanes);
|
|
continue;
|
|
}
|
|
}
|
|
if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
|
|
firstChild.return = fiber;
|
|
nextEffect = firstChild;
|
|
} else {
|
|
commitLayoutMountEffects_complete(subtreeRoot, root3, committedLanes);
|
|
}
|
|
}
|
|
}
|
|
function commitLayoutMountEffects_complete(subtreeRoot, root3, committedLanes) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
if ((fiber.flags & LayoutMask) !== NoFlags) {
|
|
var current2 = fiber.alternate;
|
|
setCurrentFiber(fiber);
|
|
try {
|
|
commitLayoutEffectOnFiber(root3, current2, fiber, committedLanes);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
resetCurrentFiber();
|
|
}
|
|
if (fiber === subtreeRoot) {
|
|
nextEffect = null;
|
|
return;
|
|
}
|
|
var sibling = fiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = fiber.return;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = fiber.return;
|
|
}
|
|
}
|
|
function disappearLayoutEffects_begin(subtreeRoot) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var firstChild = fiber.child;
|
|
switch (fiber.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case MemoComponent:
|
|
case SimpleMemoComponent: {
|
|
if (fiber.mode & ProfileMode) {
|
|
try {
|
|
startLayoutEffectTimer();
|
|
commitHookEffectListUnmount(Layout, fiber, fiber.return);
|
|
} finally {
|
|
recordLayoutEffectDuration(fiber);
|
|
}
|
|
} else {
|
|
commitHookEffectListUnmount(Layout, fiber, fiber.return);
|
|
}
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
safelyDetachRef(fiber, fiber.return);
|
|
var instance = fiber.stateNode;
|
|
if (typeof instance.componentWillUnmount === "function") {
|
|
safelyCallComponentWillUnmount(fiber, fiber.return, instance);
|
|
}
|
|
break;
|
|
}
|
|
case HostComponent: {
|
|
safelyDetachRef(fiber, fiber.return);
|
|
break;
|
|
}
|
|
case OffscreenComponent: {
|
|
var isHidden = fiber.memoizedState !== null;
|
|
if (isHidden) {
|
|
disappearLayoutEffects_complete(subtreeRoot);
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (firstChild !== null) {
|
|
firstChild.return = fiber;
|
|
nextEffect = firstChild;
|
|
} else {
|
|
disappearLayoutEffects_complete(subtreeRoot);
|
|
}
|
|
}
|
|
}
|
|
function disappearLayoutEffects_complete(subtreeRoot) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
if (fiber === subtreeRoot) {
|
|
nextEffect = null;
|
|
return;
|
|
}
|
|
var sibling = fiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = fiber.return;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = fiber.return;
|
|
}
|
|
}
|
|
function reappearLayoutEffects_begin(subtreeRoot) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var firstChild = fiber.child;
|
|
if (fiber.tag === OffscreenComponent) {
|
|
var isHidden = fiber.memoizedState !== null;
|
|
if (isHidden) {
|
|
reappearLayoutEffects_complete(subtreeRoot);
|
|
continue;
|
|
}
|
|
}
|
|
if (firstChild !== null) {
|
|
firstChild.return = fiber;
|
|
nextEffect = firstChild;
|
|
} else {
|
|
reappearLayoutEffects_complete(subtreeRoot);
|
|
}
|
|
}
|
|
}
|
|
function reappearLayoutEffects_complete(subtreeRoot) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
setCurrentFiber(fiber);
|
|
try {
|
|
reappearLayoutEffectsOnFiber(fiber);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
resetCurrentFiber();
|
|
if (fiber === subtreeRoot) {
|
|
nextEffect = null;
|
|
return;
|
|
}
|
|
var sibling = fiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = fiber.return;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = fiber.return;
|
|
}
|
|
}
|
|
function commitPassiveMountEffects(root3, finishedWork, committedLanes, committedTransitions) {
|
|
nextEffect = finishedWork;
|
|
commitPassiveMountEffects_begin(finishedWork, root3, committedLanes, committedTransitions);
|
|
}
|
|
function commitPassiveMountEffects_begin(subtreeRoot, root3, committedLanes, committedTransitions) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var firstChild = fiber.child;
|
|
if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
|
|
firstChild.return = fiber;
|
|
nextEffect = firstChild;
|
|
} else {
|
|
commitPassiveMountEffects_complete(subtreeRoot, root3, committedLanes, committedTransitions);
|
|
}
|
|
}
|
|
}
|
|
function commitPassiveMountEffects_complete(subtreeRoot, root3, committedLanes, committedTransitions) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
if ((fiber.flags & Passive) !== NoFlags) {
|
|
setCurrentFiber(fiber);
|
|
try {
|
|
commitPassiveMountOnFiber(root3, fiber, committedLanes, committedTransitions);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
resetCurrentFiber();
|
|
}
|
|
if (fiber === subtreeRoot) {
|
|
nextEffect = null;
|
|
return;
|
|
}
|
|
var sibling = fiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = fiber.return;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = fiber.return;
|
|
}
|
|
}
|
|
function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) {
|
|
switch (finishedWork.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
if (finishedWork.mode & ProfileMode) {
|
|
startPassiveEffectTimer();
|
|
try {
|
|
commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
|
|
} finally {
|
|
recordPassiveEffectDuration(finishedWork);
|
|
}
|
|
} else {
|
|
commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function commitPassiveUnmountEffects(firstChild) {
|
|
nextEffect = firstChild;
|
|
commitPassiveUnmountEffects_begin();
|
|
}
|
|
function commitPassiveUnmountEffects_begin() {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var child = fiber.child;
|
|
if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
|
|
var deletions = fiber.deletions;
|
|
if (deletions !== null) {
|
|
for (var i = 0; i < deletions.length; i++) {
|
|
var fiberToDelete = deletions[i];
|
|
nextEffect = fiberToDelete;
|
|
commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
|
|
}
|
|
{
|
|
var previousFiber = fiber.alternate;
|
|
if (previousFiber !== null) {
|
|
var detachedChild = previousFiber.child;
|
|
if (detachedChild !== null) {
|
|
previousFiber.child = null;
|
|
do {
|
|
var detachedSibling = detachedChild.sibling;
|
|
detachedChild.sibling = null;
|
|
detachedChild = detachedSibling;
|
|
} while (detachedChild !== null);
|
|
}
|
|
}
|
|
}
|
|
nextEffect = fiber;
|
|
}
|
|
}
|
|
if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
|
|
child.return = fiber;
|
|
nextEffect = child;
|
|
} else {
|
|
commitPassiveUnmountEffects_complete();
|
|
}
|
|
}
|
|
}
|
|
function commitPassiveUnmountEffects_complete() {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
if ((fiber.flags & Passive) !== NoFlags) {
|
|
setCurrentFiber(fiber);
|
|
commitPassiveUnmountOnFiber(fiber);
|
|
resetCurrentFiber();
|
|
}
|
|
var sibling = fiber.sibling;
|
|
if (sibling !== null) {
|
|
sibling.return = fiber.return;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = fiber.return;
|
|
}
|
|
}
|
|
function commitPassiveUnmountOnFiber(finishedWork) {
|
|
switch (finishedWork.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
if (finishedWork.mode & ProfileMode) {
|
|
startPassiveEffectTimer();
|
|
commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
|
|
recordPassiveEffectDuration(finishedWork);
|
|
} else {
|
|
commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
setCurrentFiber(fiber);
|
|
commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
|
|
resetCurrentFiber();
|
|
var child = fiber.child;
|
|
if (child !== null) {
|
|
child.return = fiber;
|
|
nextEffect = child;
|
|
} else {
|
|
commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
|
|
}
|
|
}
|
|
}
|
|
function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
|
|
while (nextEffect !== null) {
|
|
var fiber = nextEffect;
|
|
var sibling = fiber.sibling;
|
|
var returnFiber = fiber.return;
|
|
{
|
|
detachFiberAfterEffects(fiber);
|
|
if (fiber === deletedSubtreeRoot) {
|
|
nextEffect = null;
|
|
return;
|
|
}
|
|
}
|
|
if (sibling !== null) {
|
|
sibling.return = returnFiber;
|
|
nextEffect = sibling;
|
|
return;
|
|
}
|
|
nextEffect = returnFiber;
|
|
}
|
|
}
|
|
function commitPassiveUnmountInsideDeletedTreeOnFiber(current2, nearestMountedAncestor) {
|
|
switch (current2.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
if (current2.mode & ProfileMode) {
|
|
startPassiveEffectTimer();
|
|
commitHookEffectListUnmount(Passive$1, current2, nearestMountedAncestor);
|
|
recordPassiveEffectDuration(current2);
|
|
} else {
|
|
commitHookEffectListUnmount(Passive$1, current2, nearestMountedAncestor);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function invokeLayoutEffectMountInDEV(fiber) {
|
|
{
|
|
switch (fiber.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
try {
|
|
commitHookEffectListMount(Layout | HasEffect, fiber);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
var instance = fiber.stateNode;
|
|
try {
|
|
instance.componentDidMount();
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function invokePassiveEffectMountInDEV(fiber) {
|
|
{
|
|
switch (fiber.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
try {
|
|
commitHookEffectListMount(Passive$1 | HasEffect, fiber);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function invokeLayoutEffectUnmountInDEV(fiber) {
|
|
{
|
|
switch (fiber.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
try {
|
|
commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
var instance = fiber.stateNode;
|
|
if (typeof instance.componentWillUnmount === "function") {
|
|
safelyCallComponentWillUnmount(fiber, fiber.return, instance);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function invokePassiveEffectUnmountInDEV(fiber) {
|
|
{
|
|
switch (fiber.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
try {
|
|
commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return);
|
|
} catch (error2) {
|
|
captureCommitPhaseError(fiber, fiber.return, error2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var COMPONENT_TYPE = 0;
|
|
var HAS_PSEUDO_CLASS_TYPE = 1;
|
|
var ROLE_TYPE = 2;
|
|
var TEST_NAME_TYPE = 3;
|
|
var TEXT_TYPE = 4;
|
|
if (typeof Symbol === "function" && Symbol.for) {
|
|
var symbolFor = Symbol.for;
|
|
COMPONENT_TYPE = symbolFor("selector.component");
|
|
HAS_PSEUDO_CLASS_TYPE = symbolFor("selector.has_pseudo_class");
|
|
ROLE_TYPE = symbolFor("selector.role");
|
|
TEST_NAME_TYPE = symbolFor("selector.test_id");
|
|
TEXT_TYPE = symbolFor("selector.text");
|
|
}
|
|
var commitHooks = [];
|
|
function onCommitRoot$1() {
|
|
{
|
|
commitHooks.forEach(function(commitHook) {
|
|
return commitHook();
|
|
});
|
|
}
|
|
}
|
|
var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
|
|
function isLegacyActEnvironment(fiber) {
|
|
{
|
|
var isReactActEnvironmentGlobal = typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" ? IS_REACT_ACT_ENVIRONMENT : void 0;
|
|
var jestIsDefined = typeof jest !== "undefined";
|
|
return jestIsDefined && isReactActEnvironmentGlobal !== false;
|
|
}
|
|
}
|
|
function isConcurrentActEnvironment() {
|
|
{
|
|
var isReactActEnvironmentGlobal = typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" ? IS_REACT_ACT_ENVIRONMENT : void 0;
|
|
if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) {
|
|
error("The current testing environment is not configured to support act(...)");
|
|
}
|
|
return isReactActEnvironmentGlobal;
|
|
}
|
|
}
|
|
var ceil = Math.ceil;
|
|
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig, ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
|
|
var NoContext = 0;
|
|
var BatchedContext = 1;
|
|
var RenderContext = 2;
|
|
var CommitContext = 4;
|
|
var RootInProgress = 0;
|
|
var RootFatalErrored = 1;
|
|
var RootErrored = 2;
|
|
var RootSuspended = 3;
|
|
var RootSuspendedWithDelay = 4;
|
|
var RootCompleted = 5;
|
|
var RootDidNotComplete = 6;
|
|
var executionContext = NoContext;
|
|
var workInProgressRoot = null;
|
|
var workInProgress = null;
|
|
var workInProgressRootRenderLanes = NoLanes;
|
|
var subtreeRenderLanes = NoLanes;
|
|
var subtreeRenderLanesCursor = createCursor(NoLanes);
|
|
var workInProgressRootExitStatus = RootInProgress;
|
|
var workInProgressRootFatalError = null;
|
|
var workInProgressRootIncludedLanes = NoLanes;
|
|
var workInProgressRootSkippedLanes = NoLanes;
|
|
var workInProgressRootInterleavedUpdatedLanes = NoLanes;
|
|
var workInProgressRootPingedLanes = NoLanes;
|
|
var workInProgressRootConcurrentErrors = null;
|
|
var workInProgressRootRecoverableErrors = null;
|
|
var globalMostRecentFallbackTime = 0;
|
|
var FALLBACK_THROTTLE_MS = 500;
|
|
var workInProgressRootRenderTargetTime = Infinity;
|
|
var RENDER_TIMEOUT_MS = 500;
|
|
var workInProgressTransitions = null;
|
|
function resetRenderTimer() {
|
|
workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
|
|
}
|
|
function getRenderTargetTime() {
|
|
return workInProgressRootRenderTargetTime;
|
|
}
|
|
var hasUncaughtError = false;
|
|
var firstUncaughtError = null;
|
|
var legacyErrorBoundariesThatAlreadyFailed = null;
|
|
var rootDoesHavePassiveEffects = false;
|
|
var rootWithPendingPassiveEffects = null;
|
|
var pendingPassiveEffectsLanes = NoLanes;
|
|
var pendingPassiveProfilerEffects = [];
|
|
var pendingPassiveTransitions = null;
|
|
var NESTED_UPDATE_LIMIT = 50;
|
|
var nestedUpdateCount = 0;
|
|
var rootWithNestedUpdates = null;
|
|
var isFlushingPassiveEffects = false;
|
|
var didScheduleUpdateDuringPassiveEffects = false;
|
|
var NESTED_PASSIVE_UPDATE_LIMIT = 50;
|
|
var nestedPassiveUpdateCount = 0;
|
|
var rootWithPassiveNestedUpdates = null;
|
|
var currentEventTime = NoTimestamp;
|
|
var currentEventTransitionLane = NoLanes;
|
|
var isRunningInsertionEffect = false;
|
|
function getWorkInProgressRoot() {
|
|
return workInProgressRoot;
|
|
}
|
|
function requestEventTime() {
|
|
if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
|
|
return now();
|
|
}
|
|
if (currentEventTime !== NoTimestamp) {
|
|
return currentEventTime;
|
|
}
|
|
currentEventTime = now();
|
|
return currentEventTime;
|
|
}
|
|
function requestUpdateLane(fiber) {
|
|
var mode = fiber.mode;
|
|
if ((mode & ConcurrentMode) === NoMode) {
|
|
return SyncLane;
|
|
} else if ((executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
|
|
return pickArbitraryLane(workInProgressRootRenderLanes);
|
|
}
|
|
var isTransition = requestCurrentTransition() !== NoTransition;
|
|
if (isTransition) {
|
|
if (ReactCurrentBatchConfig$3.transition !== null) {
|
|
var transition = ReactCurrentBatchConfig$3.transition;
|
|
if (!transition._updatedFibers) {
|
|
transition._updatedFibers = /* @__PURE__ */ new Set();
|
|
}
|
|
transition._updatedFibers.add(fiber);
|
|
}
|
|
if (currentEventTransitionLane === NoLane) {
|
|
currentEventTransitionLane = claimNextTransitionLane();
|
|
}
|
|
return currentEventTransitionLane;
|
|
}
|
|
var updateLane = getCurrentUpdatePriority();
|
|
if (updateLane !== NoLane) {
|
|
return updateLane;
|
|
}
|
|
var eventLane = getCurrentEventPriority();
|
|
return eventLane;
|
|
}
|
|
function requestRetryLane(fiber) {
|
|
var mode = fiber.mode;
|
|
if ((mode & ConcurrentMode) === NoMode) {
|
|
return SyncLane;
|
|
}
|
|
return claimNextRetryLane();
|
|
}
|
|
function scheduleUpdateOnFiber(fiber, lane, eventTime) {
|
|
checkForNestedUpdates();
|
|
{
|
|
if (isRunningInsertionEffect) {
|
|
error("useInsertionEffect must not schedule updates.");
|
|
}
|
|
}
|
|
var root3 = markUpdateLaneFromFiberToRoot(fiber, lane);
|
|
if (root3 === null) {
|
|
return null;
|
|
}
|
|
{
|
|
if (isFlushingPassiveEffects) {
|
|
didScheduleUpdateDuringPassiveEffects = true;
|
|
}
|
|
}
|
|
markRootUpdated(root3, lane, eventTime);
|
|
if ((executionContext & RenderContext) !== NoLanes && root3 === workInProgressRoot) {
|
|
warnAboutRenderPhaseUpdatesInDEV(fiber);
|
|
} else {
|
|
{
|
|
if (isDevToolsPresent) {
|
|
addFiberToLanesMap(root3, fiber, lane);
|
|
}
|
|
}
|
|
warnIfUpdatesNotWrappedWithActDEV(fiber);
|
|
if (root3 === workInProgressRoot) {
|
|
if ((executionContext & RenderContext) === NoContext) {
|
|
workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
|
|
}
|
|
if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
|
|
markRootSuspended$1(root3, workInProgressRootRenderLanes);
|
|
}
|
|
}
|
|
ensureRootIsScheduled(root3, eventTime);
|
|
if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && !ReactCurrentActQueue$1.isBatchingLegacy) {
|
|
resetRenderTimer();
|
|
flushSyncCallbacksOnlyInLegacyMode();
|
|
}
|
|
}
|
|
return root3;
|
|
}
|
|
function scheduleInitialHydrationOnRoot(root3, lane, eventTime) {
|
|
var current2 = root3.current;
|
|
current2.lanes = lane;
|
|
markRootUpdated(root3, lane, eventTime);
|
|
ensureRootIsScheduled(root3, eventTime);
|
|
}
|
|
function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
|
|
sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
|
|
var alternate = sourceFiber.alternate;
|
|
if (alternate !== null) {
|
|
alternate.lanes = mergeLanes(alternate.lanes, lane);
|
|
}
|
|
{
|
|
if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
|
|
warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
|
|
}
|
|
}
|
|
var node = sourceFiber;
|
|
var parent = sourceFiber.return;
|
|
while (parent !== null) {
|
|
parent.childLanes = mergeLanes(parent.childLanes, lane);
|
|
alternate = parent.alternate;
|
|
if (alternate !== null) {
|
|
alternate.childLanes = mergeLanes(alternate.childLanes, lane);
|
|
} else {
|
|
{
|
|
if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
|
|
warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
|
|
}
|
|
}
|
|
}
|
|
node = parent;
|
|
parent = parent.return;
|
|
}
|
|
if (node.tag === HostRoot) {
|
|
var root3 = node.stateNode;
|
|
return root3;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
function isInterleavedUpdate(fiber, lane) {
|
|
return (workInProgressRoot !== null || hasInterleavedUpdates()) && (fiber.mode & ConcurrentMode) !== NoMode && (executionContext & RenderContext) === NoContext;
|
|
}
|
|
function ensureRootIsScheduled(root3, currentTime) {
|
|
var existingCallbackNode = root3.callbackNode;
|
|
markStarvedLanesAsExpired(root3, currentTime);
|
|
var nextLanes = getNextLanes(root3, root3 === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
|
|
if (nextLanes === NoLanes) {
|
|
if (existingCallbackNode !== null) {
|
|
cancelCallback$1(existingCallbackNode);
|
|
}
|
|
root3.callbackNode = null;
|
|
root3.callbackPriority = NoLane;
|
|
return;
|
|
}
|
|
var newCallbackPriority = getHighestPriorityLane(nextLanes);
|
|
var existingCallbackPriority = root3.callbackPriority;
|
|
if (existingCallbackPriority === newCallbackPriority && !(ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
|
|
{
|
|
if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) {
|
|
error("Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (existingCallbackNode != null) {
|
|
cancelCallback$1(existingCallbackNode);
|
|
}
|
|
var newCallbackNode;
|
|
if (newCallbackPriority === SyncLane) {
|
|
if (root3.tag === LegacyRoot) {
|
|
if (ReactCurrentActQueue$1.isBatchingLegacy !== null) {
|
|
ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
|
|
}
|
|
scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root3));
|
|
} else {
|
|
scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root3));
|
|
}
|
|
{
|
|
if (ReactCurrentActQueue$1.current !== null) {
|
|
ReactCurrentActQueue$1.current.push(flushSyncCallbacks);
|
|
} else {
|
|
scheduleMicrotask(function() {
|
|
if (executionContext === NoContext) {
|
|
flushSyncCallbacks();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
newCallbackNode = null;
|
|
} else {
|
|
var schedulerPriorityLevel;
|
|
switch (lanesToEventPriority(nextLanes)) {
|
|
case DiscreteEventPriority:
|
|
schedulerPriorityLevel = ImmediatePriority;
|
|
break;
|
|
case ContinuousEventPriority:
|
|
schedulerPriorityLevel = UserBlockingPriority;
|
|
break;
|
|
case DefaultEventPriority:
|
|
schedulerPriorityLevel = NormalPriority;
|
|
break;
|
|
case IdleEventPriority:
|
|
schedulerPriorityLevel = IdlePriority;
|
|
break;
|
|
default:
|
|
schedulerPriorityLevel = NormalPriority;
|
|
break;
|
|
}
|
|
newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root3));
|
|
}
|
|
root3.callbackPriority = newCallbackPriority;
|
|
root3.callbackNode = newCallbackNode;
|
|
}
|
|
function performConcurrentWorkOnRoot(root3, didTimeout) {
|
|
{
|
|
resetNestedUpdateFlag();
|
|
}
|
|
currentEventTime = NoTimestamp;
|
|
currentEventTransitionLane = NoLanes;
|
|
if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
|
|
throw new Error("Should not already be working.");
|
|
}
|
|
var originalCallbackNode = root3.callbackNode;
|
|
var didFlushPassiveEffects = flushPassiveEffects();
|
|
if (didFlushPassiveEffects) {
|
|
if (root3.callbackNode !== originalCallbackNode) {
|
|
return null;
|
|
}
|
|
}
|
|
var lanes = getNextLanes(root3, root3 === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
|
|
if (lanes === NoLanes) {
|
|
return null;
|
|
}
|
|
var shouldTimeSlice = !includesBlockingLane(root3, lanes) && !includesExpiredLane(root3, lanes) && !didTimeout;
|
|
var exitStatus = shouldTimeSlice ? renderRootConcurrent(root3, lanes) : renderRootSync(root3, lanes);
|
|
if (exitStatus !== RootInProgress) {
|
|
if (exitStatus === RootErrored) {
|
|
var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root3);
|
|
if (errorRetryLanes !== NoLanes) {
|
|
lanes = errorRetryLanes;
|
|
exitStatus = recoverFromConcurrentError(root3, errorRetryLanes);
|
|
}
|
|
}
|
|
if (exitStatus === RootFatalErrored) {
|
|
var fatalError = workInProgressRootFatalError;
|
|
prepareFreshStack(root3, NoLanes);
|
|
markRootSuspended$1(root3, lanes);
|
|
ensureRootIsScheduled(root3, now());
|
|
throw fatalError;
|
|
}
|
|
if (exitStatus === RootDidNotComplete) {
|
|
markRootSuspended$1(root3, lanes);
|
|
} else {
|
|
var renderWasConcurrent = !includesBlockingLane(root3, lanes);
|
|
var finishedWork = root3.current.alternate;
|
|
if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
|
|
exitStatus = renderRootSync(root3, lanes);
|
|
if (exitStatus === RootErrored) {
|
|
var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root3);
|
|
if (_errorRetryLanes !== NoLanes) {
|
|
lanes = _errorRetryLanes;
|
|
exitStatus = recoverFromConcurrentError(root3, _errorRetryLanes);
|
|
}
|
|
}
|
|
if (exitStatus === RootFatalErrored) {
|
|
var _fatalError = workInProgressRootFatalError;
|
|
prepareFreshStack(root3, NoLanes);
|
|
markRootSuspended$1(root3, lanes);
|
|
ensureRootIsScheduled(root3, now());
|
|
throw _fatalError;
|
|
}
|
|
}
|
|
root3.finishedWork = finishedWork;
|
|
root3.finishedLanes = lanes;
|
|
finishConcurrentRender(root3, exitStatus, lanes);
|
|
}
|
|
}
|
|
ensureRootIsScheduled(root3, now());
|
|
if (root3.callbackNode === originalCallbackNode) {
|
|
return performConcurrentWorkOnRoot.bind(null, root3);
|
|
}
|
|
return null;
|
|
}
|
|
function recoverFromConcurrentError(root3, errorRetryLanes) {
|
|
var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
|
|
if (isRootDehydrated(root3)) {
|
|
var rootWorkInProgress = prepareFreshStack(root3, errorRetryLanes);
|
|
rootWorkInProgress.flags |= ForceClientRender;
|
|
{
|
|
errorHydratingContainer(root3.containerInfo);
|
|
}
|
|
}
|
|
var exitStatus = renderRootSync(root3, errorRetryLanes);
|
|
if (exitStatus !== RootErrored) {
|
|
var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
|
|
workInProgressRootRecoverableErrors = errorsFromFirstAttempt;
|
|
if (errorsFromSecondAttempt !== null) {
|
|
queueRecoverableErrors(errorsFromSecondAttempt);
|
|
}
|
|
}
|
|
return exitStatus;
|
|
}
|
|
function queueRecoverableErrors(errors) {
|
|
if (workInProgressRootRecoverableErrors === null) {
|
|
workInProgressRootRecoverableErrors = errors;
|
|
} else {
|
|
workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
|
|
}
|
|
}
|
|
function finishConcurrentRender(root3, exitStatus, lanes) {
|
|
switch (exitStatus) {
|
|
case RootInProgress:
|
|
case RootFatalErrored: {
|
|
throw new Error("Root did not complete. This is a bug in React.");
|
|
}
|
|
case RootErrored: {
|
|
commitRoot(root3, workInProgressRootRecoverableErrors, workInProgressTransitions);
|
|
break;
|
|
}
|
|
case RootSuspended: {
|
|
markRootSuspended$1(root3, lanes);
|
|
if (includesOnlyRetries(lanes) && !shouldForceFlushFallbacksInDEV()) {
|
|
var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
|
|
if (msUntilTimeout > 10) {
|
|
var nextLanes = getNextLanes(root3, NoLanes);
|
|
if (nextLanes !== NoLanes) {
|
|
break;
|
|
}
|
|
var suspendedLanes = root3.suspendedLanes;
|
|
if (!isSubsetOfLanes(suspendedLanes, lanes)) {
|
|
var eventTime = requestEventTime();
|
|
markRootPinged(root3, suspendedLanes);
|
|
break;
|
|
}
|
|
root3.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root3, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout);
|
|
break;
|
|
}
|
|
}
|
|
commitRoot(root3, workInProgressRootRecoverableErrors, workInProgressTransitions);
|
|
break;
|
|
}
|
|
case RootSuspendedWithDelay: {
|
|
markRootSuspended$1(root3, lanes);
|
|
if (includesOnlyTransitions(lanes)) {
|
|
break;
|
|
}
|
|
if (!shouldForceFlushFallbacksInDEV()) {
|
|
var mostRecentEventTime = getMostRecentEventTime(root3, lanes);
|
|
var eventTimeMs = mostRecentEventTime;
|
|
var timeElapsedMs = now() - eventTimeMs;
|
|
var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs;
|
|
if (_msUntilTimeout > 10) {
|
|
root3.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root3, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout);
|
|
break;
|
|
}
|
|
}
|
|
commitRoot(root3, workInProgressRootRecoverableErrors, workInProgressTransitions);
|
|
break;
|
|
}
|
|
case RootCompleted: {
|
|
commitRoot(root3, workInProgressRootRecoverableErrors, workInProgressTransitions);
|
|
break;
|
|
}
|
|
default: {
|
|
throw new Error("Unknown root exit status.");
|
|
}
|
|
}
|
|
}
|
|
function isRenderConsistentWithExternalStores(finishedWork) {
|
|
var node = finishedWork;
|
|
while (true) {
|
|
if (node.flags & StoreConsistency) {
|
|
var updateQueue = node.updateQueue;
|
|
if (updateQueue !== null) {
|
|
var checks = updateQueue.stores;
|
|
if (checks !== null) {
|
|
for (var i = 0; i < checks.length; i++) {
|
|
var check = checks[i];
|
|
var getSnapshot = check.getSnapshot;
|
|
var renderedValue = check.value;
|
|
try {
|
|
if (!objectIs(getSnapshot(), renderedValue)) {
|
|
return false;
|
|
}
|
|
} catch (error2) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var child = node.child;
|
|
if (node.subtreeFlags & StoreConsistency && child !== null) {
|
|
child.return = node;
|
|
node = child;
|
|
continue;
|
|
}
|
|
if (node === finishedWork) {
|
|
return true;
|
|
}
|
|
while (node.sibling === null) {
|
|
if (node.return === null || node.return === finishedWork) {
|
|
return true;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
return true;
|
|
}
|
|
function markRootSuspended$1(root3, suspendedLanes) {
|
|
suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
|
|
suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
|
|
markRootSuspended(root3, suspendedLanes);
|
|
}
|
|
function performSyncWorkOnRoot(root3) {
|
|
{
|
|
syncNestedUpdateFlag();
|
|
}
|
|
if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
|
|
throw new Error("Should not already be working.");
|
|
}
|
|
flushPassiveEffects();
|
|
var lanes = getNextLanes(root3, NoLanes);
|
|
if (!includesSomeLane(lanes, SyncLane)) {
|
|
ensureRootIsScheduled(root3, now());
|
|
return null;
|
|
}
|
|
var exitStatus = renderRootSync(root3, lanes);
|
|
if (root3.tag !== LegacyRoot && exitStatus === RootErrored) {
|
|
var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root3);
|
|
if (errorRetryLanes !== NoLanes) {
|
|
lanes = errorRetryLanes;
|
|
exitStatus = recoverFromConcurrentError(root3, errorRetryLanes);
|
|
}
|
|
}
|
|
if (exitStatus === RootFatalErrored) {
|
|
var fatalError = workInProgressRootFatalError;
|
|
prepareFreshStack(root3, NoLanes);
|
|
markRootSuspended$1(root3, lanes);
|
|
ensureRootIsScheduled(root3, now());
|
|
throw fatalError;
|
|
}
|
|
if (exitStatus === RootDidNotComplete) {
|
|
throw new Error("Root did not complete. This is a bug in React.");
|
|
}
|
|
var finishedWork = root3.current.alternate;
|
|
root3.finishedWork = finishedWork;
|
|
root3.finishedLanes = lanes;
|
|
commitRoot(root3, workInProgressRootRecoverableErrors, workInProgressTransitions);
|
|
ensureRootIsScheduled(root3, now());
|
|
return null;
|
|
}
|
|
function flushRoot(root3, lanes) {
|
|
if (lanes !== NoLanes) {
|
|
markRootEntangled(root3, mergeLanes(lanes, SyncLane));
|
|
ensureRootIsScheduled(root3, now());
|
|
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
|
|
resetRenderTimer();
|
|
flushSyncCallbacks();
|
|
}
|
|
}
|
|
}
|
|
function batchedUpdates$1(fn, a) {
|
|
var prevExecutionContext = executionContext;
|
|
executionContext |= BatchedContext;
|
|
try {
|
|
return fn(a);
|
|
} finally {
|
|
executionContext = prevExecutionContext;
|
|
if (executionContext === NoContext && !ReactCurrentActQueue$1.isBatchingLegacy) {
|
|
resetRenderTimer();
|
|
flushSyncCallbacksOnlyInLegacyMode();
|
|
}
|
|
}
|
|
}
|
|
function discreteUpdates(fn, a, b, c, d) {
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
var prevTransition = ReactCurrentBatchConfig$3.transition;
|
|
try {
|
|
ReactCurrentBatchConfig$3.transition = null;
|
|
setCurrentUpdatePriority(DiscreteEventPriority);
|
|
return fn(a, b, c, d);
|
|
} finally {
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig$3.transition = prevTransition;
|
|
if (executionContext === NoContext) {
|
|
resetRenderTimer();
|
|
}
|
|
}
|
|
}
|
|
function flushSync(fn) {
|
|
if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) {
|
|
flushPassiveEffects();
|
|
}
|
|
var prevExecutionContext = executionContext;
|
|
executionContext |= BatchedContext;
|
|
var prevTransition = ReactCurrentBatchConfig$3.transition;
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
try {
|
|
ReactCurrentBatchConfig$3.transition = null;
|
|
setCurrentUpdatePriority(DiscreteEventPriority);
|
|
if (fn) {
|
|
return fn();
|
|
} else {
|
|
return void 0;
|
|
}
|
|
} finally {
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig$3.transition = prevTransition;
|
|
executionContext = prevExecutionContext;
|
|
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
|
|
flushSyncCallbacks();
|
|
}
|
|
}
|
|
}
|
|
function isAlreadyRendering() {
|
|
return (executionContext & (RenderContext | CommitContext)) !== NoContext;
|
|
}
|
|
function pushRenderLanes(fiber, lanes) {
|
|
push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
|
|
subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
|
|
workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
|
|
}
|
|
function popRenderLanes(fiber) {
|
|
subtreeRenderLanes = subtreeRenderLanesCursor.current;
|
|
pop(subtreeRenderLanesCursor, fiber);
|
|
}
|
|
function prepareFreshStack(root3, lanes) {
|
|
root3.finishedWork = null;
|
|
root3.finishedLanes = NoLanes;
|
|
var timeoutHandle = root3.timeoutHandle;
|
|
if (timeoutHandle !== noTimeout) {
|
|
root3.timeoutHandle = noTimeout;
|
|
cancelTimeout(timeoutHandle);
|
|
}
|
|
if (workInProgress !== null) {
|
|
var interruptedWork = workInProgress.return;
|
|
while (interruptedWork !== null) {
|
|
var current2 = interruptedWork.alternate;
|
|
unwindInterruptedWork(current2, interruptedWork);
|
|
interruptedWork = interruptedWork.return;
|
|
}
|
|
}
|
|
workInProgressRoot = root3;
|
|
var rootWorkInProgress = createWorkInProgress(root3.current, null);
|
|
workInProgress = rootWorkInProgress;
|
|
workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
|
|
workInProgressRootExitStatus = RootInProgress;
|
|
workInProgressRootFatalError = null;
|
|
workInProgressRootSkippedLanes = NoLanes;
|
|
workInProgressRootInterleavedUpdatedLanes = NoLanes;
|
|
workInProgressRootPingedLanes = NoLanes;
|
|
workInProgressRootConcurrentErrors = null;
|
|
workInProgressRootRecoverableErrors = null;
|
|
enqueueInterleavedUpdates();
|
|
{
|
|
ReactStrictModeWarnings.discardPendingWarnings();
|
|
}
|
|
return rootWorkInProgress;
|
|
}
|
|
function handleError(root3, thrownValue) {
|
|
do {
|
|
var erroredWork = workInProgress;
|
|
try {
|
|
resetContextDependencies();
|
|
resetHooksAfterThrow();
|
|
resetCurrentFiber();
|
|
ReactCurrentOwner$2.current = null;
|
|
if (erroredWork === null || erroredWork.return === null) {
|
|
workInProgressRootExitStatus = RootFatalErrored;
|
|
workInProgressRootFatalError = thrownValue;
|
|
workInProgress = null;
|
|
return;
|
|
}
|
|
if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
|
|
stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
|
|
}
|
|
if (enableSchedulingProfiler) {
|
|
markComponentRenderStopped();
|
|
if (thrownValue !== null && typeof thrownValue === "object" && typeof thrownValue.then === "function") {
|
|
var wakeable = thrownValue;
|
|
markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
|
|
} else {
|
|
markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
|
|
}
|
|
}
|
|
throwException(root3, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
|
|
completeUnitOfWork(erroredWork);
|
|
} catch (yetAnotherThrownValue) {
|
|
thrownValue = yetAnotherThrownValue;
|
|
if (workInProgress === erroredWork && erroredWork !== null) {
|
|
erroredWork = erroredWork.return;
|
|
workInProgress = erroredWork;
|
|
} else {
|
|
erroredWork = workInProgress;
|
|
}
|
|
continue;
|
|
}
|
|
return;
|
|
} while (true);
|
|
}
|
|
function pushDispatcher() {
|
|
var prevDispatcher = ReactCurrentDispatcher$2.current;
|
|
ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
|
|
if (prevDispatcher === null) {
|
|
return ContextOnlyDispatcher;
|
|
} else {
|
|
return prevDispatcher;
|
|
}
|
|
}
|
|
function popDispatcher(prevDispatcher) {
|
|
ReactCurrentDispatcher$2.current = prevDispatcher;
|
|
}
|
|
function markCommitTimeOfFallback() {
|
|
globalMostRecentFallbackTime = now();
|
|
}
|
|
function markSkippedUpdateLanes(lane) {
|
|
workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
|
|
}
|
|
function renderDidSuspend() {
|
|
if (workInProgressRootExitStatus === RootInProgress) {
|
|
workInProgressRootExitStatus = RootSuspended;
|
|
}
|
|
}
|
|
function renderDidSuspendDelayIfPossible() {
|
|
if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) {
|
|
workInProgressRootExitStatus = RootSuspendedWithDelay;
|
|
}
|
|
if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) {
|
|
markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
|
|
}
|
|
}
|
|
function renderDidError(error2) {
|
|
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
|
|
workInProgressRootExitStatus = RootErrored;
|
|
}
|
|
if (workInProgressRootConcurrentErrors === null) {
|
|
workInProgressRootConcurrentErrors = [error2];
|
|
} else {
|
|
workInProgressRootConcurrentErrors.push(error2);
|
|
}
|
|
}
|
|
function renderHasNotSuspendedYet() {
|
|
return workInProgressRootExitStatus === RootInProgress;
|
|
}
|
|
function renderRootSync(root3, lanes) {
|
|
var prevExecutionContext = executionContext;
|
|
executionContext |= RenderContext;
|
|
var prevDispatcher = pushDispatcher();
|
|
if (workInProgressRoot !== root3 || workInProgressRootRenderLanes !== lanes) {
|
|
{
|
|
if (isDevToolsPresent) {
|
|
var memoizedUpdaters = root3.memoizedUpdaters;
|
|
if (memoizedUpdaters.size > 0) {
|
|
restorePendingUpdaters(root3, workInProgressRootRenderLanes);
|
|
memoizedUpdaters.clear();
|
|
}
|
|
movePendingFibersToMemoized(root3, lanes);
|
|
}
|
|
}
|
|
workInProgressTransitions = getTransitionsForLanes();
|
|
prepareFreshStack(root3, lanes);
|
|
}
|
|
{
|
|
markRenderStarted(lanes);
|
|
}
|
|
do {
|
|
try {
|
|
workLoopSync();
|
|
break;
|
|
} catch (thrownValue) {
|
|
handleError(root3, thrownValue);
|
|
}
|
|
} while (true);
|
|
resetContextDependencies();
|
|
executionContext = prevExecutionContext;
|
|
popDispatcher(prevDispatcher);
|
|
if (workInProgress !== null) {
|
|
throw new Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
{
|
|
markRenderStopped();
|
|
}
|
|
workInProgressRoot = null;
|
|
workInProgressRootRenderLanes = NoLanes;
|
|
return workInProgressRootExitStatus;
|
|
}
|
|
function workLoopSync() {
|
|
while (workInProgress !== null) {
|
|
performUnitOfWork(workInProgress);
|
|
}
|
|
}
|
|
function renderRootConcurrent(root3, lanes) {
|
|
var prevExecutionContext = executionContext;
|
|
executionContext |= RenderContext;
|
|
var prevDispatcher = pushDispatcher();
|
|
if (workInProgressRoot !== root3 || workInProgressRootRenderLanes !== lanes) {
|
|
{
|
|
if (isDevToolsPresent) {
|
|
var memoizedUpdaters = root3.memoizedUpdaters;
|
|
if (memoizedUpdaters.size > 0) {
|
|
restorePendingUpdaters(root3, workInProgressRootRenderLanes);
|
|
memoizedUpdaters.clear();
|
|
}
|
|
movePendingFibersToMemoized(root3, lanes);
|
|
}
|
|
}
|
|
workInProgressTransitions = getTransitionsForLanes();
|
|
resetRenderTimer();
|
|
prepareFreshStack(root3, lanes);
|
|
}
|
|
{
|
|
markRenderStarted(lanes);
|
|
}
|
|
do {
|
|
try {
|
|
workLoopConcurrent();
|
|
break;
|
|
} catch (thrownValue) {
|
|
handleError(root3, thrownValue);
|
|
}
|
|
} while (true);
|
|
resetContextDependencies();
|
|
popDispatcher(prevDispatcher);
|
|
executionContext = prevExecutionContext;
|
|
if (workInProgress !== null) {
|
|
{
|
|
markRenderYielded();
|
|
}
|
|
return RootInProgress;
|
|
} else {
|
|
{
|
|
markRenderStopped();
|
|
}
|
|
workInProgressRoot = null;
|
|
workInProgressRootRenderLanes = NoLanes;
|
|
return workInProgressRootExitStatus;
|
|
}
|
|
}
|
|
function workLoopConcurrent() {
|
|
while (workInProgress !== null && !shouldYield()) {
|
|
performUnitOfWork(workInProgress);
|
|
}
|
|
}
|
|
function performUnitOfWork(unitOfWork) {
|
|
var current2 = unitOfWork.alternate;
|
|
setCurrentFiber(unitOfWork);
|
|
var next;
|
|
if ((unitOfWork.mode & ProfileMode) !== NoMode) {
|
|
startProfilerTimer(unitOfWork);
|
|
next = beginWork$1(current2, unitOfWork, subtreeRenderLanes);
|
|
stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
|
|
} else {
|
|
next = beginWork$1(current2, unitOfWork, subtreeRenderLanes);
|
|
}
|
|
resetCurrentFiber();
|
|
unitOfWork.memoizedProps = unitOfWork.pendingProps;
|
|
if (next === null) {
|
|
completeUnitOfWork(unitOfWork);
|
|
} else {
|
|
workInProgress = next;
|
|
}
|
|
ReactCurrentOwner$2.current = null;
|
|
}
|
|
function completeUnitOfWork(unitOfWork) {
|
|
var completedWork = unitOfWork;
|
|
do {
|
|
var current2 = completedWork.alternate;
|
|
var returnFiber = completedWork.return;
|
|
if ((completedWork.flags & Incomplete) === NoFlags) {
|
|
setCurrentFiber(completedWork);
|
|
var next = void 0;
|
|
if ((completedWork.mode & ProfileMode) === NoMode) {
|
|
next = completeWork(current2, completedWork, subtreeRenderLanes);
|
|
} else {
|
|
startProfilerTimer(completedWork);
|
|
next = completeWork(current2, completedWork, subtreeRenderLanes);
|
|
stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
|
|
}
|
|
resetCurrentFiber();
|
|
if (next !== null) {
|
|
workInProgress = next;
|
|
return;
|
|
}
|
|
} else {
|
|
var _next = unwindWork(current2, completedWork);
|
|
if (_next !== null) {
|
|
_next.flags &= HostEffectMask;
|
|
workInProgress = _next;
|
|
return;
|
|
}
|
|
if ((completedWork.mode & ProfileMode) !== NoMode) {
|
|
stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
|
|
var actualDuration = completedWork.actualDuration;
|
|
var child = completedWork.child;
|
|
while (child !== null) {
|
|
actualDuration += child.actualDuration;
|
|
child = child.sibling;
|
|
}
|
|
completedWork.actualDuration = actualDuration;
|
|
}
|
|
if (returnFiber !== null) {
|
|
returnFiber.flags |= Incomplete;
|
|
returnFiber.subtreeFlags = NoFlags;
|
|
returnFiber.deletions = null;
|
|
} else {
|
|
workInProgressRootExitStatus = RootDidNotComplete;
|
|
workInProgress = null;
|
|
return;
|
|
}
|
|
}
|
|
var siblingFiber = completedWork.sibling;
|
|
if (siblingFiber !== null) {
|
|
workInProgress = siblingFiber;
|
|
return;
|
|
}
|
|
completedWork = returnFiber;
|
|
workInProgress = completedWork;
|
|
} while (completedWork !== null);
|
|
if (workInProgressRootExitStatus === RootInProgress) {
|
|
workInProgressRootExitStatus = RootCompleted;
|
|
}
|
|
}
|
|
function commitRoot(root3, recoverableErrors, transitions) {
|
|
var previousUpdateLanePriority = getCurrentUpdatePriority();
|
|
var prevTransition = ReactCurrentBatchConfig$3.transition;
|
|
try {
|
|
ReactCurrentBatchConfig$3.transition = null;
|
|
setCurrentUpdatePriority(DiscreteEventPriority);
|
|
commitRootImpl(root3, recoverableErrors, transitions, previousUpdateLanePriority);
|
|
} finally {
|
|
ReactCurrentBatchConfig$3.transition = prevTransition;
|
|
setCurrentUpdatePriority(previousUpdateLanePriority);
|
|
}
|
|
return null;
|
|
}
|
|
function commitRootImpl(root3, recoverableErrors, transitions, renderPriorityLevel) {
|
|
do {
|
|
flushPassiveEffects();
|
|
} while (rootWithPendingPassiveEffects !== null);
|
|
flushRenderPhaseStrictModeWarningsInDEV();
|
|
if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
|
|
throw new Error("Should not already be working.");
|
|
}
|
|
var finishedWork = root3.finishedWork;
|
|
var lanes = root3.finishedLanes;
|
|
{
|
|
markCommitStarted(lanes);
|
|
}
|
|
if (finishedWork === null) {
|
|
{
|
|
markCommitStopped();
|
|
}
|
|
return null;
|
|
} else {
|
|
{
|
|
if (lanes === NoLanes) {
|
|
error("root.finishedLanes should not be empty during a commit. This is a bug in React.");
|
|
}
|
|
}
|
|
}
|
|
root3.finishedWork = null;
|
|
root3.finishedLanes = NoLanes;
|
|
if (finishedWork === root3.current) {
|
|
throw new Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.");
|
|
}
|
|
root3.callbackNode = null;
|
|
root3.callbackPriority = NoLane;
|
|
var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
|
|
markRootFinished(root3, remainingLanes);
|
|
if (root3 === workInProgressRoot) {
|
|
workInProgressRoot = null;
|
|
workInProgress = null;
|
|
workInProgressRootRenderLanes = NoLanes;
|
|
}
|
|
if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
|
|
if (!rootDoesHavePassiveEffects) {
|
|
rootDoesHavePassiveEffects = true;
|
|
pendingPassiveTransitions = transitions;
|
|
scheduleCallback$1(NormalPriority, function() {
|
|
flushPassiveEffects();
|
|
return null;
|
|
});
|
|
}
|
|
}
|
|
var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
|
|
var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
|
|
if (subtreeHasEffects || rootHasEffect) {
|
|
var prevTransition = ReactCurrentBatchConfig$3.transition;
|
|
ReactCurrentBatchConfig$3.transition = null;
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
setCurrentUpdatePriority(DiscreteEventPriority);
|
|
var prevExecutionContext = executionContext;
|
|
executionContext |= CommitContext;
|
|
ReactCurrentOwner$2.current = null;
|
|
var shouldFireAfterActiveInstanceBlur2 = commitBeforeMutationEffects(root3, finishedWork);
|
|
{
|
|
recordCommitTime();
|
|
}
|
|
commitMutationEffects(root3, finishedWork, lanes);
|
|
resetAfterCommit(root3.containerInfo);
|
|
root3.current = finishedWork;
|
|
{
|
|
markLayoutEffectsStarted(lanes);
|
|
}
|
|
commitLayoutEffects(finishedWork, root3, lanes);
|
|
{
|
|
markLayoutEffectsStopped();
|
|
}
|
|
requestPaint();
|
|
executionContext = prevExecutionContext;
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig$3.transition = prevTransition;
|
|
} else {
|
|
root3.current = finishedWork;
|
|
{
|
|
recordCommitTime();
|
|
}
|
|
}
|
|
var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
|
|
if (rootDoesHavePassiveEffects) {
|
|
rootDoesHavePassiveEffects = false;
|
|
rootWithPendingPassiveEffects = root3;
|
|
pendingPassiveEffectsLanes = lanes;
|
|
} else {
|
|
{
|
|
nestedPassiveUpdateCount = 0;
|
|
rootWithPassiveNestedUpdates = null;
|
|
}
|
|
}
|
|
remainingLanes = root3.pendingLanes;
|
|
if (remainingLanes === NoLanes) {
|
|
legacyErrorBoundariesThatAlreadyFailed = null;
|
|
}
|
|
{
|
|
if (!rootDidHavePassiveEffects) {
|
|
commitDoubleInvokeEffectsInDEV(root3.current, false);
|
|
}
|
|
}
|
|
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
|
{
|
|
if (isDevToolsPresent) {
|
|
root3.memoizedUpdaters.clear();
|
|
}
|
|
}
|
|
{
|
|
onCommitRoot$1();
|
|
}
|
|
ensureRootIsScheduled(root3, now());
|
|
if (recoverableErrors !== null) {
|
|
var onRecoverableError = root3.onRecoverableError;
|
|
for (var i = 0; i < recoverableErrors.length; i++) {
|
|
var recoverableError = recoverableErrors[i];
|
|
onRecoverableError(recoverableError);
|
|
}
|
|
}
|
|
if (hasUncaughtError) {
|
|
hasUncaughtError = false;
|
|
var error$1 = firstUncaughtError;
|
|
firstUncaughtError = null;
|
|
throw error$1;
|
|
}
|
|
if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root3.tag !== LegacyRoot) {
|
|
flushPassiveEffects();
|
|
}
|
|
remainingLanes = root3.pendingLanes;
|
|
if (includesSomeLane(remainingLanes, SyncLane)) {
|
|
{
|
|
markNestedUpdateScheduled();
|
|
}
|
|
if (root3 === rootWithNestedUpdates) {
|
|
nestedUpdateCount++;
|
|
} else {
|
|
nestedUpdateCount = 0;
|
|
rootWithNestedUpdates = root3;
|
|
}
|
|
} else {
|
|
nestedUpdateCount = 0;
|
|
}
|
|
flushSyncCallbacks();
|
|
{
|
|
markCommitStopped();
|
|
}
|
|
return null;
|
|
}
|
|
function flushPassiveEffects() {
|
|
if (rootWithPendingPassiveEffects !== null) {
|
|
var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
|
|
var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
|
|
var prevTransition = ReactCurrentBatchConfig$3.transition;
|
|
var previousPriority = getCurrentUpdatePriority();
|
|
try {
|
|
ReactCurrentBatchConfig$3.transition = null;
|
|
setCurrentUpdatePriority(priority);
|
|
return flushPassiveEffectsImpl();
|
|
} finally {
|
|
setCurrentUpdatePriority(previousPriority);
|
|
ReactCurrentBatchConfig$3.transition = prevTransition;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function enqueuePendingPassiveProfilerEffect(fiber) {
|
|
{
|
|
pendingPassiveProfilerEffects.push(fiber);
|
|
if (!rootDoesHavePassiveEffects) {
|
|
rootDoesHavePassiveEffects = true;
|
|
scheduleCallback$1(NormalPriority, function() {
|
|
flushPassiveEffects();
|
|
return null;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
function flushPassiveEffectsImpl() {
|
|
if (rootWithPendingPassiveEffects === null) {
|
|
return false;
|
|
}
|
|
var transitions = pendingPassiveTransitions;
|
|
pendingPassiveTransitions = null;
|
|
var root3 = rootWithPendingPassiveEffects;
|
|
var lanes = pendingPassiveEffectsLanes;
|
|
rootWithPendingPassiveEffects = null;
|
|
pendingPassiveEffectsLanes = NoLanes;
|
|
if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
|
|
throw new Error("Cannot flush passive effects while already rendering.");
|
|
}
|
|
{
|
|
isFlushingPassiveEffects = true;
|
|
didScheduleUpdateDuringPassiveEffects = false;
|
|
}
|
|
{
|
|
markPassiveEffectsStarted(lanes);
|
|
}
|
|
var prevExecutionContext = executionContext;
|
|
executionContext |= CommitContext;
|
|
commitPassiveUnmountEffects(root3.current);
|
|
commitPassiveMountEffects(root3, root3.current, lanes, transitions);
|
|
{
|
|
var profilerEffects = pendingPassiveProfilerEffects;
|
|
pendingPassiveProfilerEffects = [];
|
|
for (var i = 0; i < profilerEffects.length; i++) {
|
|
var _fiber = profilerEffects[i];
|
|
commitPassiveEffectDurations(root3, _fiber);
|
|
}
|
|
}
|
|
{
|
|
markPassiveEffectsStopped();
|
|
}
|
|
{
|
|
commitDoubleInvokeEffectsInDEV(root3.current, true);
|
|
}
|
|
executionContext = prevExecutionContext;
|
|
flushSyncCallbacks();
|
|
{
|
|
if (didScheduleUpdateDuringPassiveEffects) {
|
|
if (root3 === rootWithPassiveNestedUpdates) {
|
|
nestedPassiveUpdateCount++;
|
|
} else {
|
|
nestedPassiveUpdateCount = 0;
|
|
rootWithPassiveNestedUpdates = root3;
|
|
}
|
|
} else {
|
|
nestedPassiveUpdateCount = 0;
|
|
}
|
|
isFlushingPassiveEffects = false;
|
|
didScheduleUpdateDuringPassiveEffects = false;
|
|
}
|
|
onPostCommitRoot(root3);
|
|
{
|
|
var stateNode = root3.current.stateNode;
|
|
stateNode.effectDuration = 0;
|
|
stateNode.passiveEffectDuration = 0;
|
|
}
|
|
return true;
|
|
}
|
|
function isAlreadyFailedLegacyErrorBoundary(instance) {
|
|
return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
|
|
}
|
|
function markLegacyErrorBoundaryAsFailed(instance) {
|
|
if (legacyErrorBoundariesThatAlreadyFailed === null) {
|
|
legacyErrorBoundariesThatAlreadyFailed = /* @__PURE__ */ new Set([instance]);
|
|
} else {
|
|
legacyErrorBoundariesThatAlreadyFailed.add(instance);
|
|
}
|
|
}
|
|
function prepareToThrowUncaughtError(error2) {
|
|
if (!hasUncaughtError) {
|
|
hasUncaughtError = true;
|
|
firstUncaughtError = error2;
|
|
}
|
|
}
|
|
var onUncaughtError = prepareToThrowUncaughtError;
|
|
function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error2) {
|
|
var errorInfo = createCapturedValue(error2, sourceFiber);
|
|
var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
|
|
enqueueUpdate(rootFiber, update);
|
|
var eventTime = requestEventTime();
|
|
var root3 = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);
|
|
if (root3 !== null) {
|
|
markRootUpdated(root3, SyncLane, eventTime);
|
|
ensureRootIsScheduled(root3, eventTime);
|
|
}
|
|
}
|
|
function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
|
|
{
|
|
reportUncaughtErrorInDEV(error$1);
|
|
setIsRunningInsertionEffect(false);
|
|
}
|
|
if (sourceFiber.tag === HostRoot) {
|
|
captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
|
|
return;
|
|
}
|
|
var fiber = null;
|
|
{
|
|
fiber = nearestMountedAncestor;
|
|
}
|
|
while (fiber !== null) {
|
|
if (fiber.tag === HostRoot) {
|
|
captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
|
|
return;
|
|
} else if (fiber.tag === ClassComponent) {
|
|
var ctor = fiber.type;
|
|
var instance = fiber.stateNode;
|
|
if (typeof ctor.getDerivedStateFromError === "function" || typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) {
|
|
var errorInfo = createCapturedValue(error$1, sourceFiber);
|
|
var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
|
|
enqueueUpdate(fiber, update);
|
|
var eventTime = requestEventTime();
|
|
var root3 = markUpdateLaneFromFiberToRoot(fiber, SyncLane);
|
|
if (root3 !== null) {
|
|
markRootUpdated(root3, SyncLane, eventTime);
|
|
ensureRootIsScheduled(root3, eventTime);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
fiber = fiber.return;
|
|
}
|
|
{
|
|
error("Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.\n\nError message:\n\n%s", error$1);
|
|
}
|
|
}
|
|
function pingSuspendedRoot(root3, wakeable, pingedLanes) {
|
|
var pingCache = root3.pingCache;
|
|
if (pingCache !== null) {
|
|
pingCache.delete(wakeable);
|
|
}
|
|
var eventTime = requestEventTime();
|
|
markRootPinged(root3, pingedLanes);
|
|
warnIfSuspenseResolutionNotWrappedWithActDEV(root3);
|
|
if (workInProgressRoot === root3 && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
|
|
if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
|
|
prepareFreshStack(root3, NoLanes);
|
|
} else {
|
|
workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
|
|
}
|
|
}
|
|
ensureRootIsScheduled(root3, eventTime);
|
|
}
|
|
function retryTimedOutBoundary(boundaryFiber, retryLane) {
|
|
if (retryLane === NoLane) {
|
|
retryLane = requestRetryLane(boundaryFiber);
|
|
}
|
|
var eventTime = requestEventTime();
|
|
var root3 = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);
|
|
if (root3 !== null) {
|
|
markRootUpdated(root3, retryLane, eventTime);
|
|
ensureRootIsScheduled(root3, eventTime);
|
|
}
|
|
}
|
|
function retryDehydratedSuspenseBoundary(boundaryFiber) {
|
|
var suspenseState = boundaryFiber.memoizedState;
|
|
var retryLane = NoLane;
|
|
if (suspenseState !== null) {
|
|
retryLane = suspenseState.retryLane;
|
|
}
|
|
retryTimedOutBoundary(boundaryFiber, retryLane);
|
|
}
|
|
function resolveRetryWakeable(boundaryFiber, wakeable) {
|
|
var retryLane = NoLane;
|
|
var retryCache;
|
|
switch (boundaryFiber.tag) {
|
|
case SuspenseComponent:
|
|
retryCache = boundaryFiber.stateNode;
|
|
var suspenseState = boundaryFiber.memoizedState;
|
|
if (suspenseState !== null) {
|
|
retryLane = suspenseState.retryLane;
|
|
}
|
|
break;
|
|
case SuspenseListComponent:
|
|
retryCache = boundaryFiber.stateNode;
|
|
break;
|
|
default:
|
|
throw new Error("Pinged unknown suspense boundary type. This is probably a bug in React.");
|
|
}
|
|
if (retryCache !== null) {
|
|
retryCache.delete(wakeable);
|
|
}
|
|
retryTimedOutBoundary(boundaryFiber, retryLane);
|
|
}
|
|
function jnd(timeElapsed) {
|
|
return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3e3 ? 3e3 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
|
|
}
|
|
function checkForNestedUpdates() {
|
|
if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
|
|
nestedUpdateCount = 0;
|
|
rootWithNestedUpdates = null;
|
|
throw new Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.");
|
|
}
|
|
{
|
|
if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
|
|
nestedPassiveUpdateCount = 0;
|
|
rootWithPassiveNestedUpdates = null;
|
|
error("Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.");
|
|
}
|
|
}
|
|
}
|
|
function flushRenderPhaseStrictModeWarningsInDEV() {
|
|
{
|
|
ReactStrictModeWarnings.flushLegacyContextWarning();
|
|
{
|
|
ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
|
|
}
|
|
}
|
|
}
|
|
function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) {
|
|
{
|
|
setCurrentFiber(fiber);
|
|
invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV);
|
|
if (hasPassiveEffects) {
|
|
invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV);
|
|
}
|
|
invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV);
|
|
if (hasPassiveEffects) {
|
|
invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV);
|
|
}
|
|
resetCurrentFiber();
|
|
}
|
|
}
|
|
function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) {
|
|
{
|
|
var current2 = firstChild;
|
|
var subtreeRoot = null;
|
|
while (current2 !== null) {
|
|
var primarySubtreeFlag = current2.subtreeFlags & fiberFlags;
|
|
if (current2 !== subtreeRoot && current2.child !== null && primarySubtreeFlag !== NoFlags) {
|
|
current2 = current2.child;
|
|
} else {
|
|
if ((current2.flags & fiberFlags) !== NoFlags) {
|
|
invokeEffectFn(current2);
|
|
}
|
|
if (current2.sibling !== null) {
|
|
current2 = current2.sibling;
|
|
} else {
|
|
current2 = subtreeRoot = current2.return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var didWarnStateUpdateForNotYetMountedComponent = null;
|
|
function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
|
|
{
|
|
if ((executionContext & RenderContext) !== NoContext) {
|
|
return;
|
|
}
|
|
if (!(fiber.mode & ConcurrentMode)) {
|
|
return;
|
|
}
|
|
var tag = fiber.tag;
|
|
if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
|
|
return;
|
|
}
|
|
var componentName = getComponentNameFromFiber(fiber) || "ReactComponent";
|
|
if (didWarnStateUpdateForNotYetMountedComponent !== null) {
|
|
if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
|
|
return;
|
|
}
|
|
didWarnStateUpdateForNotYetMountedComponent.add(componentName);
|
|
} else {
|
|
didWarnStateUpdateForNotYetMountedComponent = /* @__PURE__ */ new Set([componentName]);
|
|
}
|
|
var previousFiber = current;
|
|
try {
|
|
setCurrentFiber(fiber);
|
|
error("Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously later calls tries to update the component. Move this work to useEffect instead.");
|
|
} finally {
|
|
if (previousFiber) {
|
|
setCurrentFiber(fiber);
|
|
} else {
|
|
resetCurrentFiber();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var beginWork$1;
|
|
{
|
|
var dummyFiber = null;
|
|
beginWork$1 = function(current2, unitOfWork, lanes) {
|
|
var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
|
|
try {
|
|
return beginWork(current2, unitOfWork, lanes);
|
|
} catch (originalError) {
|
|
if (originalError !== null && typeof originalError === "object" && typeof originalError.then === "function") {
|
|
throw originalError;
|
|
}
|
|
resetContextDependencies();
|
|
resetHooksAfterThrow();
|
|
unwindInterruptedWork(current2, unitOfWork);
|
|
assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
|
|
if (unitOfWork.mode & ProfileMode) {
|
|
startProfilerTimer(unitOfWork);
|
|
}
|
|
invokeGuardedCallback(null, beginWork, null, current2, unitOfWork, lanes);
|
|
if (hasCaughtError()) {
|
|
var replayError = clearCaughtError();
|
|
if (typeof replayError === "object" && replayError !== null && replayError._suppressLogging && typeof originalError === "object" && originalError !== null && !originalError._suppressLogging) {
|
|
originalError._suppressLogging = true;
|
|
}
|
|
}
|
|
throw originalError;
|
|
}
|
|
};
|
|
}
|
|
var didWarnAboutUpdateInRender = false;
|
|
var didWarnAboutUpdateInRenderForAnotherComponent;
|
|
{
|
|
didWarnAboutUpdateInRenderForAnotherComponent = /* @__PURE__ */ new Set();
|
|
}
|
|
function warnAboutRenderPhaseUpdatesInDEV(fiber) {
|
|
{
|
|
if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
|
|
switch (fiber.tag) {
|
|
case FunctionComponent:
|
|
case ForwardRef:
|
|
case SimpleMemoComponent: {
|
|
var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || "Unknown";
|
|
var dedupeKey = renderingComponentName;
|
|
if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
|
|
didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
|
|
var setStateComponentName = getComponentNameFromFiber(fiber) || "Unknown";
|
|
error("Cannot update a component (`%s`) while rendering a different component (`%s`). To locate the bad setState() call inside `%s`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render", setStateComponentName, renderingComponentName, renderingComponentName);
|
|
}
|
|
break;
|
|
}
|
|
case ClassComponent: {
|
|
if (!didWarnAboutUpdateInRender) {
|
|
error("Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.");
|
|
didWarnAboutUpdateInRender = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function restorePendingUpdaters(root3, lanes) {
|
|
{
|
|
if (isDevToolsPresent) {
|
|
var memoizedUpdaters = root3.memoizedUpdaters;
|
|
memoizedUpdaters.forEach(function(schedulingFiber) {
|
|
addFiberToLanesMap(root3, schedulingFiber, lanes);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
var fakeActCallbackNode = {};
|
|
function scheduleCallback$1(priorityLevel, callback) {
|
|
{
|
|
var actQueue = ReactCurrentActQueue$1.current;
|
|
if (actQueue !== null) {
|
|
actQueue.push(callback);
|
|
return fakeActCallbackNode;
|
|
} else {
|
|
return scheduleCallback(priorityLevel, callback);
|
|
}
|
|
}
|
|
}
|
|
function cancelCallback$1(callbackNode) {
|
|
if (callbackNode === fakeActCallbackNode) {
|
|
return;
|
|
}
|
|
return cancelCallback(callbackNode);
|
|
}
|
|
function shouldForceFlushFallbacksInDEV() {
|
|
return ReactCurrentActQueue$1.current !== null;
|
|
}
|
|
function warnIfUpdatesNotWrappedWithActDEV(fiber) {
|
|
{
|
|
if (fiber.mode & ConcurrentMode) {
|
|
if (!isConcurrentActEnvironment()) {
|
|
return;
|
|
}
|
|
} else {
|
|
if (!isLegacyActEnvironment()) {
|
|
return;
|
|
}
|
|
if (executionContext !== NoContext) {
|
|
return;
|
|
}
|
|
if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) {
|
|
return;
|
|
}
|
|
}
|
|
if (ReactCurrentActQueue$1.current === null) {
|
|
var previousFiber = current;
|
|
try {
|
|
setCurrentFiber(fiber);
|
|
error("An update to %s inside a test was not wrapped in act(...).\n\nWhen testing, code that causes React state updates should be wrapped into act(...):\n\nact(() => {\n /* fire events that update state */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act", getComponentNameFromFiber(fiber));
|
|
} finally {
|
|
if (previousFiber) {
|
|
setCurrentFiber(fiber);
|
|
} else {
|
|
resetCurrentFiber();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function warnIfSuspenseResolutionNotWrappedWithActDEV(root3) {
|
|
{
|
|
if (root3.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) {
|
|
error("A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n\nWhen testing, code that resolves suspended data should be wrapped into act(...):\n\nact(() => {\n /* finish loading suspended data */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act");
|
|
}
|
|
}
|
|
}
|
|
function setIsRunningInsertionEffect(isRunning) {
|
|
{
|
|
isRunningInsertionEffect = isRunning;
|
|
}
|
|
}
|
|
var resolveFamily = null;
|
|
var failedBoundaries = null;
|
|
var setRefreshHandler = function(handler) {
|
|
{
|
|
resolveFamily = handler;
|
|
}
|
|
};
|
|
function resolveFunctionForHotReloading(type) {
|
|
{
|
|
if (resolveFamily === null) {
|
|
return type;
|
|
}
|
|
var family = resolveFamily(type);
|
|
if (family === void 0) {
|
|
return type;
|
|
}
|
|
return family.current;
|
|
}
|
|
}
|
|
function resolveClassForHotReloading(type) {
|
|
return resolveFunctionForHotReloading(type);
|
|
}
|
|
function resolveForwardRefForHotReloading(type) {
|
|
{
|
|
if (resolveFamily === null) {
|
|
return type;
|
|
}
|
|
var family = resolveFamily(type);
|
|
if (family === void 0) {
|
|
if (type !== null && type !== void 0 && typeof type.render === "function") {
|
|
var currentRender = resolveFunctionForHotReloading(type.render);
|
|
if (type.render !== currentRender) {
|
|
var syntheticType = {
|
|
$$typeof: REACT_FORWARD_REF_TYPE,
|
|
render: currentRender
|
|
};
|
|
if (type.displayName !== void 0) {
|
|
syntheticType.displayName = type.displayName;
|
|
}
|
|
return syntheticType;
|
|
}
|
|
}
|
|
return type;
|
|
}
|
|
return family.current;
|
|
}
|
|
}
|
|
function isCompatibleFamilyForHotReloading(fiber, element) {
|
|
{
|
|
if (resolveFamily === null) {
|
|
return false;
|
|
}
|
|
var prevType = fiber.elementType;
|
|
var nextType = element.type;
|
|
var needsCompareFamilies = false;
|
|
var $$typeofNextType = typeof nextType === "object" && nextType !== null ? nextType.$$typeof : null;
|
|
switch (fiber.tag) {
|
|
case ClassComponent: {
|
|
if (typeof nextType === "function") {
|
|
needsCompareFamilies = true;
|
|
}
|
|
break;
|
|
}
|
|
case FunctionComponent: {
|
|
if (typeof nextType === "function") {
|
|
needsCompareFamilies = true;
|
|
} else if ($$typeofNextType === REACT_LAZY_TYPE) {
|
|
needsCompareFamilies = true;
|
|
}
|
|
break;
|
|
}
|
|
case ForwardRef: {
|
|
if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
|
|
needsCompareFamilies = true;
|
|
} else if ($$typeofNextType === REACT_LAZY_TYPE) {
|
|
needsCompareFamilies = true;
|
|
}
|
|
break;
|
|
}
|
|
case MemoComponent:
|
|
case SimpleMemoComponent: {
|
|
if ($$typeofNextType === REACT_MEMO_TYPE) {
|
|
needsCompareFamilies = true;
|
|
} else if ($$typeofNextType === REACT_LAZY_TYPE) {
|
|
needsCompareFamilies = true;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
if (needsCompareFamilies) {
|
|
var prevFamily = resolveFamily(prevType);
|
|
if (prevFamily !== void 0 && prevFamily === resolveFamily(nextType)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
function markFailedErrorBoundaryForHotReloading(fiber) {
|
|
{
|
|
if (resolveFamily === null) {
|
|
return;
|
|
}
|
|
if (typeof WeakSet !== "function") {
|
|
return;
|
|
}
|
|
if (failedBoundaries === null) {
|
|
failedBoundaries = /* @__PURE__ */ new WeakSet();
|
|
}
|
|
failedBoundaries.add(fiber);
|
|
}
|
|
}
|
|
var scheduleRefresh = function(root3, update) {
|
|
{
|
|
if (resolveFamily === null) {
|
|
return;
|
|
}
|
|
var staleFamilies = update.staleFamilies, updatedFamilies = update.updatedFamilies;
|
|
flushPassiveEffects();
|
|
flushSync(function() {
|
|
scheduleFibersWithFamiliesRecursively(root3.current, updatedFamilies, staleFamilies);
|
|
});
|
|
}
|
|
};
|
|
var scheduleRoot = function(root3, element) {
|
|
{
|
|
if (root3.context !== emptyContextObject) {
|
|
return;
|
|
}
|
|
flushPassiveEffects();
|
|
flushSync(function() {
|
|
updateContainer(element, root3, null, null);
|
|
});
|
|
}
|
|
};
|
|
function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
|
|
{
|
|
var alternate = fiber.alternate, child = fiber.child, sibling = fiber.sibling, tag = fiber.tag, type = fiber.type;
|
|
var candidateType = null;
|
|
switch (tag) {
|
|
case FunctionComponent:
|
|
case SimpleMemoComponent:
|
|
case ClassComponent:
|
|
candidateType = type;
|
|
break;
|
|
case ForwardRef:
|
|
candidateType = type.render;
|
|
break;
|
|
}
|
|
if (resolveFamily === null) {
|
|
throw new Error("Expected resolveFamily to be set during hot reload.");
|
|
}
|
|
var needsRender = false;
|
|
var needsRemount = false;
|
|
if (candidateType !== null) {
|
|
var family = resolveFamily(candidateType);
|
|
if (family !== void 0) {
|
|
if (staleFamilies.has(family)) {
|
|
needsRemount = true;
|
|
} else if (updatedFamilies.has(family)) {
|
|
if (tag === ClassComponent) {
|
|
needsRemount = true;
|
|
} else {
|
|
needsRender = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (failedBoundaries !== null) {
|
|
if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
|
|
needsRemount = true;
|
|
}
|
|
}
|
|
if (needsRemount) {
|
|
fiber._debugNeedsRemount = true;
|
|
}
|
|
if (needsRemount || needsRender) {
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
}
|
|
if (child !== null && !needsRemount) {
|
|
scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
|
|
}
|
|
if (sibling !== null) {
|
|
scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
|
|
}
|
|
}
|
|
}
|
|
var findHostInstancesForRefresh = function(root3, families) {
|
|
{
|
|
var hostInstances = /* @__PURE__ */ new Set();
|
|
var types = new Set(families.map(function(family) {
|
|
return family.current;
|
|
}));
|
|
findHostInstancesForMatchingFibersRecursively(root3.current, types, hostInstances);
|
|
return hostInstances;
|
|
}
|
|
};
|
|
function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
|
|
{
|
|
var child = fiber.child, sibling = fiber.sibling, tag = fiber.tag, type = fiber.type;
|
|
var candidateType = null;
|
|
switch (tag) {
|
|
case FunctionComponent:
|
|
case SimpleMemoComponent:
|
|
case ClassComponent:
|
|
candidateType = type;
|
|
break;
|
|
case ForwardRef:
|
|
candidateType = type.render;
|
|
break;
|
|
}
|
|
var didMatch = false;
|
|
if (candidateType !== null) {
|
|
if (types.has(candidateType)) {
|
|
didMatch = true;
|
|
}
|
|
}
|
|
if (didMatch) {
|
|
findHostInstancesForFiberShallowly(fiber, hostInstances);
|
|
} else {
|
|
if (child !== null) {
|
|
findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
|
|
}
|
|
}
|
|
if (sibling !== null) {
|
|
findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
|
|
}
|
|
}
|
|
}
|
|
function findHostInstancesForFiberShallowly(fiber, hostInstances) {
|
|
{
|
|
var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
|
|
if (foundHostInstances) {
|
|
return;
|
|
}
|
|
var node = fiber;
|
|
while (true) {
|
|
switch (node.tag) {
|
|
case HostComponent:
|
|
hostInstances.add(node.stateNode);
|
|
return;
|
|
case HostPortal:
|
|
hostInstances.add(node.stateNode.containerInfo);
|
|
return;
|
|
case HostRoot:
|
|
hostInstances.add(node.stateNode.containerInfo);
|
|
return;
|
|
}
|
|
if (node.return === null) {
|
|
throw new Error("Expected to reach root first.");
|
|
}
|
|
node = node.return;
|
|
}
|
|
}
|
|
}
|
|
function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
|
|
{
|
|
var node = fiber;
|
|
var foundHostInstances = false;
|
|
while (true) {
|
|
if (node.tag === HostComponent) {
|
|
foundHostInstances = true;
|
|
hostInstances.add(node.stateNode);
|
|
} else if (node.child !== null) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === fiber) {
|
|
return foundHostInstances;
|
|
}
|
|
while (node.sibling === null) {
|
|
if (node.return === null || node.return === fiber) {
|
|
return foundHostInstances;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
var hasBadMapPolyfill;
|
|
{
|
|
hasBadMapPolyfill = false;
|
|
try {
|
|
var nonExtensibleObject = Object.preventExtensions({});
|
|
/* @__PURE__ */ new Map([[nonExtensibleObject, null]]);
|
|
/* @__PURE__ */ new Set([nonExtensibleObject]);
|
|
} catch (e) {
|
|
hasBadMapPolyfill = true;
|
|
}
|
|
}
|
|
function FiberNode(tag, pendingProps, key, mode) {
|
|
this.tag = tag;
|
|
this.key = key;
|
|
this.elementType = null;
|
|
this.type = null;
|
|
this.stateNode = null;
|
|
this.return = null;
|
|
this.child = null;
|
|
this.sibling = null;
|
|
this.index = 0;
|
|
this.ref = null;
|
|
this.pendingProps = pendingProps;
|
|
this.memoizedProps = null;
|
|
this.updateQueue = null;
|
|
this.memoizedState = null;
|
|
this.dependencies = null;
|
|
this.mode = mode;
|
|
this.flags = NoFlags;
|
|
this.subtreeFlags = NoFlags;
|
|
this.deletions = null;
|
|
this.lanes = NoLanes;
|
|
this.childLanes = NoLanes;
|
|
this.alternate = null;
|
|
{
|
|
this.actualDuration = Number.NaN;
|
|
this.actualStartTime = Number.NaN;
|
|
this.selfBaseDuration = Number.NaN;
|
|
this.treeBaseDuration = Number.NaN;
|
|
this.actualDuration = 0;
|
|
this.actualStartTime = -1;
|
|
this.selfBaseDuration = 0;
|
|
this.treeBaseDuration = 0;
|
|
}
|
|
{
|
|
this._debugSource = null;
|
|
this._debugOwner = null;
|
|
this._debugNeedsRemount = false;
|
|
this._debugHookTypes = null;
|
|
if (!hasBadMapPolyfill && typeof Object.preventExtensions === "function") {
|
|
Object.preventExtensions(this);
|
|
}
|
|
}
|
|
}
|
|
var createFiber = function(tag, pendingProps, key, mode) {
|
|
return new FiberNode(tag, pendingProps, key, mode);
|
|
};
|
|
function shouldConstruct$1(Component) {
|
|
var prototype = Component.prototype;
|
|
return !!(prototype && prototype.isReactComponent);
|
|
}
|
|
function isSimpleFunctionComponent(type) {
|
|
return typeof type === "function" && !shouldConstruct$1(type) && type.defaultProps === void 0;
|
|
}
|
|
function resolveLazyComponentTag(Component) {
|
|
if (typeof Component === "function") {
|
|
return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
|
|
} else if (Component !== void 0 && Component !== null) {
|
|
var $$typeof = Component.$$typeof;
|
|
if ($$typeof === REACT_FORWARD_REF_TYPE) {
|
|
return ForwardRef;
|
|
}
|
|
if ($$typeof === REACT_MEMO_TYPE) {
|
|
return MemoComponent;
|
|
}
|
|
}
|
|
return IndeterminateComponent;
|
|
}
|
|
function createWorkInProgress(current2, pendingProps) {
|
|
var workInProgress2 = current2.alternate;
|
|
if (workInProgress2 === null) {
|
|
workInProgress2 = createFiber(current2.tag, pendingProps, current2.key, current2.mode);
|
|
workInProgress2.elementType = current2.elementType;
|
|
workInProgress2.type = current2.type;
|
|
workInProgress2.stateNode = current2.stateNode;
|
|
{
|
|
workInProgress2._debugSource = current2._debugSource;
|
|
workInProgress2._debugOwner = current2._debugOwner;
|
|
workInProgress2._debugHookTypes = current2._debugHookTypes;
|
|
}
|
|
workInProgress2.alternate = current2;
|
|
current2.alternate = workInProgress2;
|
|
} else {
|
|
workInProgress2.pendingProps = pendingProps;
|
|
workInProgress2.type = current2.type;
|
|
workInProgress2.flags = NoFlags;
|
|
workInProgress2.subtreeFlags = NoFlags;
|
|
workInProgress2.deletions = null;
|
|
{
|
|
workInProgress2.actualDuration = 0;
|
|
workInProgress2.actualStartTime = -1;
|
|
}
|
|
}
|
|
workInProgress2.flags = current2.flags & StaticMask;
|
|
workInProgress2.childLanes = current2.childLanes;
|
|
workInProgress2.lanes = current2.lanes;
|
|
workInProgress2.child = current2.child;
|
|
workInProgress2.memoizedProps = current2.memoizedProps;
|
|
workInProgress2.memoizedState = current2.memoizedState;
|
|
workInProgress2.updateQueue = current2.updateQueue;
|
|
var currentDependencies = current2.dependencies;
|
|
workInProgress2.dependencies = currentDependencies === null ? null : {
|
|
lanes: currentDependencies.lanes,
|
|
firstContext: currentDependencies.firstContext
|
|
};
|
|
workInProgress2.sibling = current2.sibling;
|
|
workInProgress2.index = current2.index;
|
|
workInProgress2.ref = current2.ref;
|
|
{
|
|
workInProgress2.selfBaseDuration = current2.selfBaseDuration;
|
|
workInProgress2.treeBaseDuration = current2.treeBaseDuration;
|
|
}
|
|
{
|
|
workInProgress2._debugNeedsRemount = current2._debugNeedsRemount;
|
|
switch (workInProgress2.tag) {
|
|
case IndeterminateComponent:
|
|
case FunctionComponent:
|
|
case SimpleMemoComponent:
|
|
workInProgress2.type = resolveFunctionForHotReloading(current2.type);
|
|
break;
|
|
case ClassComponent:
|
|
workInProgress2.type = resolveClassForHotReloading(current2.type);
|
|
break;
|
|
case ForwardRef:
|
|
workInProgress2.type = resolveForwardRefForHotReloading(current2.type);
|
|
break;
|
|
}
|
|
}
|
|
return workInProgress2;
|
|
}
|
|
function resetWorkInProgress(workInProgress2, renderLanes2) {
|
|
workInProgress2.flags &= StaticMask | Placement;
|
|
var current2 = workInProgress2.alternate;
|
|
if (current2 === null) {
|
|
workInProgress2.childLanes = NoLanes;
|
|
workInProgress2.lanes = renderLanes2;
|
|
workInProgress2.child = null;
|
|
workInProgress2.subtreeFlags = NoFlags;
|
|
workInProgress2.memoizedProps = null;
|
|
workInProgress2.memoizedState = null;
|
|
workInProgress2.updateQueue = null;
|
|
workInProgress2.dependencies = null;
|
|
workInProgress2.stateNode = null;
|
|
{
|
|
workInProgress2.selfBaseDuration = 0;
|
|
workInProgress2.treeBaseDuration = 0;
|
|
}
|
|
} else {
|
|
workInProgress2.childLanes = current2.childLanes;
|
|
workInProgress2.lanes = current2.lanes;
|
|
workInProgress2.child = current2.child;
|
|
workInProgress2.subtreeFlags = NoFlags;
|
|
workInProgress2.deletions = null;
|
|
workInProgress2.memoizedProps = current2.memoizedProps;
|
|
workInProgress2.memoizedState = current2.memoizedState;
|
|
workInProgress2.updateQueue = current2.updateQueue;
|
|
workInProgress2.type = current2.type;
|
|
var currentDependencies = current2.dependencies;
|
|
workInProgress2.dependencies = currentDependencies === null ? null : {
|
|
lanes: currentDependencies.lanes,
|
|
firstContext: currentDependencies.firstContext
|
|
};
|
|
{
|
|
workInProgress2.selfBaseDuration = current2.selfBaseDuration;
|
|
workInProgress2.treeBaseDuration = current2.treeBaseDuration;
|
|
}
|
|
}
|
|
return workInProgress2;
|
|
}
|
|
function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
|
|
var mode;
|
|
if (tag === ConcurrentRoot) {
|
|
mode = ConcurrentMode;
|
|
if (isStrictMode === true) {
|
|
mode |= StrictLegacyMode;
|
|
{
|
|
mode |= StrictEffectsMode;
|
|
}
|
|
}
|
|
} else {
|
|
mode = NoMode;
|
|
}
|
|
if (isDevToolsPresent) {
|
|
mode |= ProfileMode;
|
|
}
|
|
return createFiber(HostRoot, null, null, mode);
|
|
}
|
|
function createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes) {
|
|
var fiberTag = IndeterminateComponent;
|
|
var resolvedType = type;
|
|
if (typeof type === "function") {
|
|
if (shouldConstruct$1(type)) {
|
|
fiberTag = ClassComponent;
|
|
{
|
|
resolvedType = resolveClassForHotReloading(resolvedType);
|
|
}
|
|
} else {
|
|
{
|
|
resolvedType = resolveFunctionForHotReloading(resolvedType);
|
|
}
|
|
}
|
|
} else if (typeof type === "string") {
|
|
fiberTag = HostComponent;
|
|
} else {
|
|
getTag:
|
|
switch (type) {
|
|
case REACT_FRAGMENT_TYPE:
|
|
return createFiberFromFragment(pendingProps.children, mode, lanes, key);
|
|
case REACT_STRICT_MODE_TYPE:
|
|
fiberTag = Mode;
|
|
mode |= StrictLegacyMode;
|
|
if ((mode & ConcurrentMode) !== NoMode) {
|
|
mode |= StrictEffectsMode;
|
|
}
|
|
break;
|
|
case REACT_PROFILER_TYPE:
|
|
return createFiberFromProfiler(pendingProps, mode, lanes, key);
|
|
case REACT_SUSPENSE_TYPE:
|
|
return createFiberFromSuspense(pendingProps, mode, lanes, key);
|
|
case REACT_SUSPENSE_LIST_TYPE:
|
|
return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
|
|
case REACT_OFFSCREEN_TYPE:
|
|
return createFiberFromOffscreen(pendingProps, mode, lanes, key);
|
|
case REACT_LEGACY_HIDDEN_TYPE:
|
|
case REACT_SCOPE_TYPE:
|
|
case REACT_CACHE_TYPE:
|
|
case REACT_TRACING_MARKER_TYPE:
|
|
case REACT_DEBUG_TRACING_MODE_TYPE:
|
|
default: {
|
|
if (typeof type === "object" && type !== null) {
|
|
switch (type.$$typeof) {
|
|
case REACT_PROVIDER_TYPE:
|
|
fiberTag = ContextProvider;
|
|
break getTag;
|
|
case REACT_CONTEXT_TYPE:
|
|
fiberTag = ContextConsumer;
|
|
break getTag;
|
|
case REACT_FORWARD_REF_TYPE:
|
|
fiberTag = ForwardRef;
|
|
{
|
|
resolvedType = resolveForwardRefForHotReloading(resolvedType);
|
|
}
|
|
break getTag;
|
|
case REACT_MEMO_TYPE:
|
|
fiberTag = MemoComponent;
|
|
break getTag;
|
|
case REACT_LAZY_TYPE:
|
|
fiberTag = LazyComponent;
|
|
resolvedType = null;
|
|
break getTag;
|
|
}
|
|
}
|
|
var info = "";
|
|
{
|
|
if (type === void 0 || typeof type === "object" && type !== null && Object.keys(type).length === 0) {
|
|
info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.";
|
|
}
|
|
var ownerName = owner ? getComponentNameFromFiber(owner) : null;
|
|
if (ownerName) {
|
|
info += "\n\nCheck the render method of `" + ownerName + "`.";
|
|
}
|
|
}
|
|
throw new Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) " + ("but got: " + (type == null ? type : typeof type) + "." + info));
|
|
}
|
|
}
|
|
}
|
|
var fiber = createFiber(fiberTag, pendingProps, key, mode);
|
|
fiber.elementType = type;
|
|
fiber.type = resolvedType;
|
|
fiber.lanes = lanes;
|
|
{
|
|
fiber._debugOwner = owner;
|
|
}
|
|
return fiber;
|
|
}
|
|
function createFiberFromElement(element, mode, lanes) {
|
|
var owner = null;
|
|
{
|
|
owner = element._owner;
|
|
}
|
|
var type = element.type;
|
|
var key = element.key;
|
|
var pendingProps = element.props;
|
|
var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
|
|
{
|
|
fiber._debugSource = element._source;
|
|
fiber._debugOwner = element._owner;
|
|
}
|
|
return fiber;
|
|
}
|
|
function createFiberFromFragment(elements, mode, lanes, key) {
|
|
var fiber = createFiber(Fragment2, elements, key, mode);
|
|
fiber.lanes = lanes;
|
|
return fiber;
|
|
}
|
|
function createFiberFromProfiler(pendingProps, mode, lanes, key) {
|
|
{
|
|
if (typeof pendingProps.id !== "string") {
|
|
error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
|
|
}
|
|
}
|
|
var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
|
|
fiber.elementType = REACT_PROFILER_TYPE;
|
|
fiber.lanes = lanes;
|
|
{
|
|
fiber.stateNode = {
|
|
effectDuration: 0,
|
|
passiveEffectDuration: 0
|
|
};
|
|
}
|
|
return fiber;
|
|
}
|
|
function createFiberFromSuspense(pendingProps, mode, lanes, key) {
|
|
var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
|
|
fiber.elementType = REACT_SUSPENSE_TYPE;
|
|
fiber.lanes = lanes;
|
|
return fiber;
|
|
}
|
|
function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
|
|
var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
|
|
fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
|
|
fiber.lanes = lanes;
|
|
return fiber;
|
|
}
|
|
function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
|
|
var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
|
|
fiber.elementType = REACT_OFFSCREEN_TYPE;
|
|
fiber.lanes = lanes;
|
|
var primaryChildInstance = {};
|
|
fiber.stateNode = primaryChildInstance;
|
|
return fiber;
|
|
}
|
|
function createFiberFromText(content, mode, lanes) {
|
|
var fiber = createFiber(HostText, content, null, mode);
|
|
fiber.lanes = lanes;
|
|
return fiber;
|
|
}
|
|
function createFiberFromHostInstanceForDeletion() {
|
|
var fiber = createFiber(HostComponent, null, null, NoMode);
|
|
fiber.elementType = "DELETED";
|
|
return fiber;
|
|
}
|
|
function createFiberFromDehydratedFragment(dehydratedNode) {
|
|
var fiber = createFiber(DehydratedFragment, null, null, NoMode);
|
|
fiber.stateNode = dehydratedNode;
|
|
return fiber;
|
|
}
|
|
function createFiberFromPortal(portal, mode, lanes) {
|
|
var pendingProps = portal.children !== null ? portal.children : [];
|
|
var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
|
|
fiber.lanes = lanes;
|
|
fiber.stateNode = {
|
|
containerInfo: portal.containerInfo,
|
|
pendingChildren: null,
|
|
implementation: portal.implementation
|
|
};
|
|
return fiber;
|
|
}
|
|
function assignFiberPropertiesInDEV(target, source) {
|
|
if (target === null) {
|
|
target = createFiber(IndeterminateComponent, null, null, NoMode);
|
|
}
|
|
target.tag = source.tag;
|
|
target.key = source.key;
|
|
target.elementType = source.elementType;
|
|
target.type = source.type;
|
|
target.stateNode = source.stateNode;
|
|
target.return = source.return;
|
|
target.child = source.child;
|
|
target.sibling = source.sibling;
|
|
target.index = source.index;
|
|
target.ref = source.ref;
|
|
target.pendingProps = source.pendingProps;
|
|
target.memoizedProps = source.memoizedProps;
|
|
target.updateQueue = source.updateQueue;
|
|
target.memoizedState = source.memoizedState;
|
|
target.dependencies = source.dependencies;
|
|
target.mode = source.mode;
|
|
target.flags = source.flags;
|
|
target.subtreeFlags = source.subtreeFlags;
|
|
target.deletions = source.deletions;
|
|
target.lanes = source.lanes;
|
|
target.childLanes = source.childLanes;
|
|
target.alternate = source.alternate;
|
|
{
|
|
target.actualDuration = source.actualDuration;
|
|
target.actualStartTime = source.actualStartTime;
|
|
target.selfBaseDuration = source.selfBaseDuration;
|
|
target.treeBaseDuration = source.treeBaseDuration;
|
|
}
|
|
target._debugSource = source._debugSource;
|
|
target._debugOwner = source._debugOwner;
|
|
target._debugNeedsRemount = source._debugNeedsRemount;
|
|
target._debugHookTypes = source._debugHookTypes;
|
|
return target;
|
|
}
|
|
function FiberRootNode(containerInfo, tag, hydrate2, identifierPrefix, onRecoverableError) {
|
|
this.tag = tag;
|
|
this.containerInfo = containerInfo;
|
|
this.pendingChildren = null;
|
|
this.current = null;
|
|
this.pingCache = null;
|
|
this.finishedWork = null;
|
|
this.timeoutHandle = noTimeout;
|
|
this.context = null;
|
|
this.pendingContext = null;
|
|
this.callbackNode = null;
|
|
this.callbackPriority = NoLane;
|
|
this.eventTimes = createLaneMap(NoLanes);
|
|
this.expirationTimes = createLaneMap(NoTimestamp);
|
|
this.pendingLanes = NoLanes;
|
|
this.suspendedLanes = NoLanes;
|
|
this.pingedLanes = NoLanes;
|
|
this.expiredLanes = NoLanes;
|
|
this.mutableReadLanes = NoLanes;
|
|
this.finishedLanes = NoLanes;
|
|
this.entangledLanes = NoLanes;
|
|
this.entanglements = createLaneMap(NoLanes);
|
|
this.identifierPrefix = identifierPrefix;
|
|
this.onRecoverableError = onRecoverableError;
|
|
{
|
|
this.mutableSourceEagerHydrationData = null;
|
|
}
|
|
{
|
|
this.effectDuration = 0;
|
|
this.passiveEffectDuration = 0;
|
|
}
|
|
{
|
|
this.memoizedUpdaters = /* @__PURE__ */ new Set();
|
|
var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = [];
|
|
for (var _i = 0; _i < TotalLanes; _i++) {
|
|
pendingUpdatersLaneMap.push(/* @__PURE__ */ new Set());
|
|
}
|
|
}
|
|
{
|
|
switch (tag) {
|
|
case ConcurrentRoot:
|
|
this._debugRootType = hydrate2 ? "hydrateRoot()" : "createRoot()";
|
|
break;
|
|
case LegacyRoot:
|
|
this._debugRootType = hydrate2 ? "hydrate()" : "render()";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function createFiberRoot(containerInfo, tag, hydrate2, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
|
|
var root3 = new FiberRootNode(containerInfo, tag, hydrate2, identifierPrefix, onRecoverableError);
|
|
var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
|
|
root3.current = uninitializedFiber;
|
|
uninitializedFiber.stateNode = root3;
|
|
{
|
|
var _initialState = {
|
|
element: initialChildren,
|
|
isDehydrated: hydrate2,
|
|
cache: null,
|
|
transitions: null,
|
|
pendingSuspenseBoundaries: null
|
|
};
|
|
uninitializedFiber.memoizedState = _initialState;
|
|
}
|
|
initializeUpdateQueue(uninitializedFiber);
|
|
return root3;
|
|
}
|
|
var ReactVersion = "18.1.0";
|
|
function createPortal(children, containerInfo, implementation) {
|
|
var key = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : null;
|
|
{
|
|
checkKeyStringCoercion(key);
|
|
}
|
|
return {
|
|
$$typeof: REACT_PORTAL_TYPE,
|
|
key: key == null ? null : "" + key,
|
|
children,
|
|
containerInfo,
|
|
implementation
|
|
};
|
|
}
|
|
var didWarnAboutNestedUpdates;
|
|
var didWarnAboutFindNodeInStrictMode;
|
|
{
|
|
didWarnAboutNestedUpdates = false;
|
|
didWarnAboutFindNodeInStrictMode = {};
|
|
}
|
|
function getContextForSubtree(parentComponent) {
|
|
if (!parentComponent) {
|
|
return emptyContextObject;
|
|
}
|
|
var fiber = get(parentComponent);
|
|
var parentContext = findCurrentUnmaskedContext(fiber);
|
|
if (fiber.tag === ClassComponent) {
|
|
var Component = fiber.type;
|
|
if (isContextProvider(Component)) {
|
|
return processChildContext(fiber, Component, parentContext);
|
|
}
|
|
}
|
|
return parentContext;
|
|
}
|
|
function findHostInstanceWithWarning(component, methodName) {
|
|
{
|
|
var fiber = get(component);
|
|
if (fiber === void 0) {
|
|
if (typeof component.render === "function") {
|
|
throw new Error("Unable to find node on an unmounted component.");
|
|
} else {
|
|
var keys = Object.keys(component).join(",");
|
|
throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys);
|
|
}
|
|
}
|
|
var hostFiber = findCurrentHostFiber(fiber);
|
|
if (hostFiber === null) {
|
|
return null;
|
|
}
|
|
if (hostFiber.mode & StrictLegacyMode) {
|
|
var componentName = getComponentNameFromFiber(fiber) || "Component";
|
|
if (!didWarnAboutFindNodeInStrictMode[componentName]) {
|
|
didWarnAboutFindNodeInStrictMode[componentName] = true;
|
|
var previousFiber = current;
|
|
try {
|
|
setCurrentFiber(hostFiber);
|
|
if (fiber.mode & StrictLegacyMode) {
|
|
error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node", methodName, methodName, componentName);
|
|
} else {
|
|
error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node", methodName, methodName, componentName);
|
|
}
|
|
} finally {
|
|
if (previousFiber) {
|
|
setCurrentFiber(previousFiber);
|
|
} else {
|
|
resetCurrentFiber();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hostFiber.stateNode;
|
|
}
|
|
}
|
|
function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
|
|
var hydrate2 = false;
|
|
var initialChildren = null;
|
|
return createFiberRoot(containerInfo, tag, hydrate2, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
|
|
}
|
|
function createHydrationContainer(initialChildren, callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
|
|
var hydrate2 = true;
|
|
var root3 = createFiberRoot(containerInfo, tag, hydrate2, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
|
|
root3.context = getContextForSubtree(null);
|
|
var current2 = root3.current;
|
|
var eventTime = requestEventTime();
|
|
var lane = requestUpdateLane(current2);
|
|
var update = createUpdate(eventTime, lane);
|
|
update.callback = callback !== void 0 && callback !== null ? callback : null;
|
|
enqueueUpdate(current2, update);
|
|
scheduleInitialHydrationOnRoot(root3, lane, eventTime);
|
|
return root3;
|
|
}
|
|
function updateContainer(element, container, parentComponent, callback) {
|
|
{
|
|
onScheduleRoot(container, element);
|
|
}
|
|
var current$1 = container.current;
|
|
var eventTime = requestEventTime();
|
|
var lane = requestUpdateLane(current$1);
|
|
{
|
|
markRenderScheduled(lane);
|
|
}
|
|
var context = getContextForSubtree(parentComponent);
|
|
if (container.context === null) {
|
|
container.context = context;
|
|
} else {
|
|
container.pendingContext = context;
|
|
}
|
|
{
|
|
if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
|
|
didWarnAboutNestedUpdates = true;
|
|
error("Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\nCheck the render method of %s.", getComponentNameFromFiber(current) || "Unknown");
|
|
}
|
|
}
|
|
var update = createUpdate(eventTime, lane);
|
|
update.payload = {
|
|
element
|
|
};
|
|
callback = callback === void 0 ? null : callback;
|
|
if (callback !== null) {
|
|
{
|
|
if (typeof callback !== "function") {
|
|
error("render(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callback);
|
|
}
|
|
}
|
|
update.callback = callback;
|
|
}
|
|
enqueueUpdate(current$1, update);
|
|
var root3 = scheduleUpdateOnFiber(current$1, lane, eventTime);
|
|
if (root3 !== null) {
|
|
entangleTransitions(root3, current$1, lane);
|
|
}
|
|
return lane;
|
|
}
|
|
function getPublicRootInstance(container) {
|
|
var containerFiber = container.current;
|
|
if (!containerFiber.child) {
|
|
return null;
|
|
}
|
|
switch (containerFiber.child.tag) {
|
|
case HostComponent:
|
|
return getPublicInstance(containerFiber.child.stateNode);
|
|
default:
|
|
return containerFiber.child.stateNode;
|
|
}
|
|
}
|
|
function attemptSynchronousHydration$1(fiber) {
|
|
switch (fiber.tag) {
|
|
case HostRoot:
|
|
var root3 = fiber.stateNode;
|
|
if (isRootDehydrated(root3)) {
|
|
var lanes = getHighestPriorityPendingLanes(root3);
|
|
flushRoot(root3, lanes);
|
|
}
|
|
break;
|
|
case SuspenseComponent:
|
|
var eventTime = requestEventTime();
|
|
flushSync(function() {
|
|
return scheduleUpdateOnFiber(fiber, SyncLane, eventTime);
|
|
});
|
|
var retryLane = SyncLane;
|
|
markRetryLaneIfNotHydrated(fiber, retryLane);
|
|
break;
|
|
}
|
|
}
|
|
function markRetryLaneImpl(fiber, retryLane) {
|
|
var suspenseState = fiber.memoizedState;
|
|
if (suspenseState !== null && suspenseState.dehydrated !== null) {
|
|
suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
|
|
}
|
|
}
|
|
function markRetryLaneIfNotHydrated(fiber, retryLane) {
|
|
markRetryLaneImpl(fiber, retryLane);
|
|
var alternate = fiber.alternate;
|
|
if (alternate) {
|
|
markRetryLaneImpl(alternate, retryLane);
|
|
}
|
|
}
|
|
function attemptContinuousHydration$1(fiber) {
|
|
if (fiber.tag !== SuspenseComponent) {
|
|
return;
|
|
}
|
|
var eventTime = requestEventTime();
|
|
var lane = SelectiveHydrationLane;
|
|
scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
markRetryLaneIfNotHydrated(fiber, lane);
|
|
}
|
|
function attemptHydrationAtCurrentPriority$1(fiber) {
|
|
if (fiber.tag !== SuspenseComponent) {
|
|
return;
|
|
}
|
|
var eventTime = requestEventTime();
|
|
var lane = requestUpdateLane(fiber);
|
|
scheduleUpdateOnFiber(fiber, lane, eventTime);
|
|
markRetryLaneIfNotHydrated(fiber, lane);
|
|
}
|
|
function findHostInstanceWithNoPortals(fiber) {
|
|
var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
|
|
if (hostFiber === null) {
|
|
return null;
|
|
}
|
|
return hostFiber.stateNode;
|
|
}
|
|
var shouldErrorImpl = function(fiber) {
|
|
return null;
|
|
};
|
|
function shouldError(fiber) {
|
|
return shouldErrorImpl(fiber);
|
|
}
|
|
var shouldSuspendImpl = function(fiber) {
|
|
return false;
|
|
};
|
|
function shouldSuspend(fiber) {
|
|
return shouldSuspendImpl(fiber);
|
|
}
|
|
var overrideHookState = null;
|
|
var overrideHookStateDeletePath = null;
|
|
var overrideHookStateRenamePath = null;
|
|
var overrideProps = null;
|
|
var overridePropsDeletePath = null;
|
|
var overridePropsRenamePath = null;
|
|
var scheduleUpdate = null;
|
|
var setErrorHandler = null;
|
|
var setSuspenseHandler = null;
|
|
{
|
|
var copyWithDeleteImpl = function(obj, path, index2) {
|
|
var key = path[index2];
|
|
var updated = isArray(obj) ? obj.slice() : assign({}, obj);
|
|
if (index2 + 1 === path.length) {
|
|
if (isArray(updated)) {
|
|
updated.splice(key, 1);
|
|
} else {
|
|
delete updated[key];
|
|
}
|
|
return updated;
|
|
}
|
|
updated[key] = copyWithDeleteImpl(obj[key], path, index2 + 1);
|
|
return updated;
|
|
};
|
|
var copyWithDelete = function(obj, path) {
|
|
return copyWithDeleteImpl(obj, path, 0);
|
|
};
|
|
var copyWithRenameImpl = function(obj, oldPath, newPath, index2) {
|
|
var oldKey = oldPath[index2];
|
|
var updated = isArray(obj) ? obj.slice() : assign({}, obj);
|
|
if (index2 + 1 === oldPath.length) {
|
|
var newKey = newPath[index2];
|
|
updated[newKey] = updated[oldKey];
|
|
if (isArray(updated)) {
|
|
updated.splice(oldKey, 1);
|
|
} else {
|
|
delete updated[oldKey];
|
|
}
|
|
} else {
|
|
updated[oldKey] = copyWithRenameImpl(obj[oldKey], oldPath, newPath, index2 + 1);
|
|
}
|
|
return updated;
|
|
};
|
|
var copyWithRename = function(obj, oldPath, newPath) {
|
|
if (oldPath.length !== newPath.length) {
|
|
warn("copyWithRename() expects paths of the same length");
|
|
return;
|
|
} else {
|
|
for (var i = 0; i < newPath.length - 1; i++) {
|
|
if (oldPath[i] !== newPath[i]) {
|
|
warn("copyWithRename() expects paths to be the same except for the deepest key");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
return copyWithRenameImpl(obj, oldPath, newPath, 0);
|
|
};
|
|
var copyWithSetImpl = function(obj, path, index2, value) {
|
|
if (index2 >= path.length) {
|
|
return value;
|
|
}
|
|
var key = path[index2];
|
|
var updated = isArray(obj) ? obj.slice() : assign({}, obj);
|
|
updated[key] = copyWithSetImpl(obj[key], path, index2 + 1, value);
|
|
return updated;
|
|
};
|
|
var copyWithSet = function(obj, path, value) {
|
|
return copyWithSetImpl(obj, path, 0, value);
|
|
};
|
|
var findHook = function(fiber, id) {
|
|
var currentHook2 = fiber.memoizedState;
|
|
while (currentHook2 !== null && id > 0) {
|
|
currentHook2 = currentHook2.next;
|
|
id--;
|
|
}
|
|
return currentHook2;
|
|
};
|
|
overrideHookState = function(fiber, id, path, value) {
|
|
var hook = findHook(fiber, id);
|
|
if (hook !== null) {
|
|
var newState = copyWithSet(hook.memoizedState, path, value);
|
|
hook.memoizedState = newState;
|
|
hook.baseState = newState;
|
|
fiber.memoizedProps = assign({}, fiber.memoizedProps);
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
}
|
|
};
|
|
overrideHookStateDeletePath = function(fiber, id, path) {
|
|
var hook = findHook(fiber, id);
|
|
if (hook !== null) {
|
|
var newState = copyWithDelete(hook.memoizedState, path);
|
|
hook.memoizedState = newState;
|
|
hook.baseState = newState;
|
|
fiber.memoizedProps = assign({}, fiber.memoizedProps);
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
}
|
|
};
|
|
overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
|
|
var hook = findHook(fiber, id);
|
|
if (hook !== null) {
|
|
var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
|
|
hook.memoizedState = newState;
|
|
hook.baseState = newState;
|
|
fiber.memoizedProps = assign({}, fiber.memoizedProps);
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
}
|
|
};
|
|
overrideProps = function(fiber, path, value) {
|
|
fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
|
|
if (fiber.alternate) {
|
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
}
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
};
|
|
overridePropsDeletePath = function(fiber, path) {
|
|
fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
|
|
if (fiber.alternate) {
|
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
}
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
};
|
|
overridePropsRenamePath = function(fiber, oldPath, newPath) {
|
|
fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
|
|
if (fiber.alternate) {
|
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
}
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
};
|
|
scheduleUpdate = function(fiber) {
|
|
scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
|
|
};
|
|
setErrorHandler = function(newShouldErrorImpl) {
|
|
shouldErrorImpl = newShouldErrorImpl;
|
|
};
|
|
setSuspenseHandler = function(newShouldSuspendImpl) {
|
|
shouldSuspendImpl = newShouldSuspendImpl;
|
|
};
|
|
}
|
|
function findHostInstanceByFiber(fiber) {
|
|
var hostFiber = findCurrentHostFiber(fiber);
|
|
if (hostFiber === null) {
|
|
return null;
|
|
}
|
|
return hostFiber.stateNode;
|
|
}
|
|
function emptyFindFiberByHostInstance(instance) {
|
|
return null;
|
|
}
|
|
function getCurrentFiberForDevTools() {
|
|
return current;
|
|
}
|
|
function injectIntoDevTools(devToolsConfig) {
|
|
var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
|
|
var ReactCurrentDispatcher2 = ReactSharedInternals.ReactCurrentDispatcher;
|
|
return injectInternals({
|
|
bundleType: devToolsConfig.bundleType,
|
|
version: devToolsConfig.version,
|
|
rendererPackageName: devToolsConfig.rendererPackageName,
|
|
rendererConfig: devToolsConfig.rendererConfig,
|
|
overrideHookState,
|
|
overrideHookStateDeletePath,
|
|
overrideHookStateRenamePath,
|
|
overrideProps,
|
|
overridePropsDeletePath,
|
|
overridePropsRenamePath,
|
|
setErrorHandler,
|
|
setSuspenseHandler,
|
|
scheduleUpdate,
|
|
currentDispatcherRef: ReactCurrentDispatcher2,
|
|
findHostInstanceByFiber,
|
|
findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
|
|
findHostInstancesForRefresh,
|
|
scheduleRefresh,
|
|
scheduleRoot,
|
|
setRefreshHandler,
|
|
getCurrentFiber: getCurrentFiberForDevTools,
|
|
reconcilerVersion: ReactVersion
|
|
});
|
|
}
|
|
var defaultOnRecoverableError = typeof reportError === "function" ? reportError : function(error2) {
|
|
console["error"](error2);
|
|
};
|
|
function ReactDOMRoot(internalRoot) {
|
|
this._internalRoot = internalRoot;
|
|
}
|
|
ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function(children) {
|
|
var root3 = this._internalRoot;
|
|
if (root3 === null) {
|
|
throw new Error("Cannot update an unmounted root.");
|
|
}
|
|
{
|
|
if (typeof arguments[1] === "function") {
|
|
error("render(...): does not support the second callback argument. To execute a side effect after rendering, declare it in a component body with useEffect().");
|
|
} else if (isValidContainer(arguments[1])) {
|
|
error("You passed a container to the second argument of root.render(...). You don't need to pass it again since you already passed it to create the root.");
|
|
} else if (typeof arguments[1] !== "undefined") {
|
|
error("You passed a second argument to root.render(...) but it only accepts one argument.");
|
|
}
|
|
var container = root3.containerInfo;
|
|
if (container.nodeType !== COMMENT_NODE) {
|
|
var hostInstance = findHostInstanceWithNoPortals(root3.current);
|
|
if (hostInstance) {
|
|
if (hostInstance.parentNode !== container) {
|
|
error("render(...): It looks like the React-rendered content of the root container was removed without using React. This is not supported and will cause errors. Instead, call root.unmount() to empty a root's container.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
updateContainer(children, root3, null, null);
|
|
};
|
|
ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function() {
|
|
{
|
|
if (typeof arguments[0] === "function") {
|
|
error("unmount(...): does not support a callback argument. To execute a side effect after rendering, declare it in a component body with useEffect().");
|
|
}
|
|
}
|
|
var root3 = this._internalRoot;
|
|
if (root3 !== null) {
|
|
this._internalRoot = null;
|
|
var container = root3.containerInfo;
|
|
{
|
|
if (isAlreadyRendering()) {
|
|
error("Attempted to synchronously unmount a root while React was already rendering. React cannot finish unmounting the root until the current render has completed, which may lead to a race condition.");
|
|
}
|
|
}
|
|
flushSync(function() {
|
|
updateContainer(null, root3, null, null);
|
|
});
|
|
unmarkContainerAsRoot(container);
|
|
}
|
|
};
|
|
function createRoot(container, options2) {
|
|
if (!isValidContainer(container)) {
|
|
throw new Error("createRoot(...): Target container is not a DOM element.");
|
|
}
|
|
warnIfReactDOMContainerInDEV(container);
|
|
var isStrictMode = false;
|
|
var concurrentUpdatesByDefaultOverride = false;
|
|
var identifierPrefix = "";
|
|
var onRecoverableError = defaultOnRecoverableError;
|
|
var transitionCallbacks = null;
|
|
if (options2 !== null && options2 !== void 0) {
|
|
{
|
|
if (options2.hydrate) {
|
|
warn("hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, <App />) instead.");
|
|
} else {
|
|
if (typeof options2 === "object" && options2 !== null && options2.$$typeof === REACT_ELEMENT_TYPE) {
|
|
error("You passed a JSX element to createRoot. You probably meant to call root.render instead. Example usage:\n\n let root = createRoot(domContainer);\n root.render(<App />);");
|
|
}
|
|
}
|
|
}
|
|
if (options2.unstable_strictMode === true) {
|
|
isStrictMode = true;
|
|
}
|
|
if (options2.identifierPrefix !== void 0) {
|
|
identifierPrefix = options2.identifierPrefix;
|
|
}
|
|
if (options2.onRecoverableError !== void 0) {
|
|
onRecoverableError = options2.onRecoverableError;
|
|
}
|
|
if (options2.transitionCallbacks !== void 0) {
|
|
transitionCallbacks = options2.transitionCallbacks;
|
|
}
|
|
}
|
|
var root3 = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
|
|
markContainerAsRoot(root3.current, container);
|
|
var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
|
|
listenToAllSupportedEvents(rootContainerElement);
|
|
return new ReactDOMRoot(root3);
|
|
}
|
|
function ReactDOMHydrationRoot(internalRoot) {
|
|
this._internalRoot = internalRoot;
|
|
}
|
|
function scheduleHydration(target) {
|
|
if (target) {
|
|
queueExplicitHydrationTarget(target);
|
|
}
|
|
}
|
|
ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
|
|
function hydrateRoot(container, initialChildren, options2) {
|
|
if (!isValidContainer(container)) {
|
|
throw new Error("hydrateRoot(...): Target container is not a DOM element.");
|
|
}
|
|
warnIfReactDOMContainerInDEV(container);
|
|
{
|
|
if (initialChildren === void 0) {
|
|
error("Must provide initial children as second argument to hydrateRoot. Example usage: hydrateRoot(domContainer, <App />)");
|
|
}
|
|
}
|
|
var hydrationCallbacks = options2 != null ? options2 : null;
|
|
var mutableSources = options2 != null && options2.hydratedSources || null;
|
|
var isStrictMode = false;
|
|
var concurrentUpdatesByDefaultOverride = false;
|
|
var identifierPrefix = "";
|
|
var onRecoverableError = defaultOnRecoverableError;
|
|
if (options2 !== null && options2 !== void 0) {
|
|
if (options2.unstable_strictMode === true) {
|
|
isStrictMode = true;
|
|
}
|
|
if (options2.identifierPrefix !== void 0) {
|
|
identifierPrefix = options2.identifierPrefix;
|
|
}
|
|
if (options2.onRecoverableError !== void 0) {
|
|
onRecoverableError = options2.onRecoverableError;
|
|
}
|
|
}
|
|
var root3 = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
|
|
markContainerAsRoot(root3.current, container);
|
|
listenToAllSupportedEvents(container);
|
|
if (mutableSources) {
|
|
for (var i = 0; i < mutableSources.length; i++) {
|
|
var mutableSource = mutableSources[i];
|
|
registerMutableSourceForHydration(root3, mutableSource);
|
|
}
|
|
}
|
|
return new ReactDOMHydrationRoot(root3);
|
|
}
|
|
function isValidContainer(node) {
|
|
return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers));
|
|
}
|
|
function isValidContainerLegacy(node) {
|
|
return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === " react-mount-point-unstable "));
|
|
}
|
|
function warnIfReactDOMContainerInDEV(container) {
|
|
{
|
|
if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === "BODY") {
|
|
error("createRoot(): Creating roots directly with document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try using a container element created for your app.");
|
|
}
|
|
if (isContainerMarkedAsRoot(container)) {
|
|
if (container._reactRootContainer) {
|
|
error("You are calling ReactDOMClient.createRoot() on a container that was previously passed to ReactDOM.render(). This is not supported.");
|
|
} else {
|
|
error("You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
|
|
var topLevelUpdateWarnings;
|
|
{
|
|
topLevelUpdateWarnings = function(container) {
|
|
if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
|
|
var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current);
|
|
if (hostInstance) {
|
|
if (hostInstance.parentNode !== container) {
|
|
error("render(...): It looks like the React-rendered content of this container was removed without using React. This is not supported and will cause errors. Instead, call ReactDOM.unmountComponentAtNode to empty a container.");
|
|
}
|
|
}
|
|
}
|
|
var isRootRenderedBySomeReact = !!container._reactRootContainer;
|
|
var rootEl = getReactRootElementInContainer(container);
|
|
var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
|
|
if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
|
|
error("render(...): Replacing React-rendered children with a new root component. If you intended to update the children of this node, you should instead have the existing children update their state and render the new components instead of calling ReactDOM.render.");
|
|
}
|
|
if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === "BODY") {
|
|
error("render(): Rendering components directly into document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try rendering into a container element created for your app.");
|
|
}
|
|
};
|
|
}
|
|
function getReactRootElementInContainer(container) {
|
|
if (!container) {
|
|
return null;
|
|
}
|
|
if (container.nodeType === DOCUMENT_NODE) {
|
|
return container.documentElement;
|
|
} else {
|
|
return container.firstChild;
|
|
}
|
|
}
|
|
function noopOnRecoverableError() {
|
|
}
|
|
function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) {
|
|
if (isHydrationContainer) {
|
|
if (typeof callback === "function") {
|
|
var originalCallback = callback;
|
|
callback = function() {
|
|
var instance = getPublicRootInstance(root3);
|
|
originalCallback.call(instance);
|
|
};
|
|
}
|
|
var root3 = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, false, false, "", noopOnRecoverableError);
|
|
container._reactRootContainer = root3;
|
|
markContainerAsRoot(root3.current, container);
|
|
var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
|
|
listenToAllSupportedEvents(rootContainerElement);
|
|
flushSync();
|
|
return root3;
|
|
} else {
|
|
var rootSibling;
|
|
while (rootSibling = container.lastChild) {
|
|
container.removeChild(rootSibling);
|
|
}
|
|
if (typeof callback === "function") {
|
|
var _originalCallback = callback;
|
|
callback = function() {
|
|
var instance = getPublicRootInstance(_root);
|
|
_originalCallback.call(instance);
|
|
};
|
|
}
|
|
var _root = createContainer(container, LegacyRoot, null, false, false, "", noopOnRecoverableError);
|
|
container._reactRootContainer = _root;
|
|
markContainerAsRoot(_root.current, container);
|
|
var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
|
|
listenToAllSupportedEvents(_rootContainerElement);
|
|
flushSync(function() {
|
|
updateContainer(initialChildren, _root, parentComponent, callback);
|
|
});
|
|
return _root;
|
|
}
|
|
}
|
|
function warnOnInvalidCallback$1(callback, callerName) {
|
|
{
|
|
if (callback !== null && typeof callback !== "function") {
|
|
error("%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callerName, callback);
|
|
}
|
|
}
|
|
}
|
|
function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
|
|
{
|
|
topLevelUpdateWarnings(container);
|
|
warnOnInvalidCallback$1(callback === void 0 ? null : callback, "render");
|
|
}
|
|
var maybeRoot = container._reactRootContainer;
|
|
var root3;
|
|
if (!maybeRoot) {
|
|
root3 = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate);
|
|
} else {
|
|
root3 = maybeRoot;
|
|
if (typeof callback === "function") {
|
|
var originalCallback = callback;
|
|
callback = function() {
|
|
var instance = getPublicRootInstance(root3);
|
|
originalCallback.call(instance);
|
|
};
|
|
}
|
|
updateContainer(children, root3, parentComponent, callback);
|
|
}
|
|
return getPublicRootInstance(root3);
|
|
}
|
|
function findDOMNode(componentOrElement) {
|
|
{
|
|
var owner = ReactCurrentOwner$3.current;
|
|
if (owner !== null && owner.stateNode !== null) {
|
|
var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
|
|
if (!warnedAboutRefsInRender) {
|
|
error("%s is accessing findDOMNode inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", getComponentNameFromType(owner.type) || "A component");
|
|
}
|
|
owner.stateNode._warnedAboutRefsInRender = true;
|
|
}
|
|
}
|
|
if (componentOrElement == null) {
|
|
return null;
|
|
}
|
|
if (componentOrElement.nodeType === ELEMENT_NODE) {
|
|
return componentOrElement;
|
|
}
|
|
{
|
|
return findHostInstanceWithWarning(componentOrElement, "findDOMNode");
|
|
}
|
|
}
|
|
function hydrate(element, container, callback) {
|
|
{
|
|
error("ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot");
|
|
}
|
|
if (!isValidContainerLegacy(container)) {
|
|
throw new Error("Target container is not a DOM element.");
|
|
}
|
|
{
|
|
var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === void 0;
|
|
if (isModernRoot) {
|
|
error("You are calling ReactDOM.hydrate() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call hydrateRoot(container, element)?");
|
|
}
|
|
}
|
|
return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
|
|
}
|
|
function render(element, container, callback) {
|
|
{
|
|
error("ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot");
|
|
}
|
|
if (!isValidContainerLegacy(container)) {
|
|
throw new Error("Target container is not a DOM element.");
|
|
}
|
|
{
|
|
var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === void 0;
|
|
if (isModernRoot) {
|
|
error("You are calling ReactDOM.render() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.render(element)?");
|
|
}
|
|
}
|
|
return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
|
|
}
|
|
function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
|
|
{
|
|
error("ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18. Consider using a portal instead. Until you switch to the createRoot API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot");
|
|
}
|
|
if (!isValidContainerLegacy(containerNode)) {
|
|
throw new Error("Target container is not a DOM element.");
|
|
}
|
|
if (parentComponent == null || !has(parentComponent)) {
|
|
throw new Error("parentComponent must be a valid React Component");
|
|
}
|
|
return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
|
|
}
|
|
function unmountComponentAtNode(container) {
|
|
if (!isValidContainerLegacy(container)) {
|
|
throw new Error("unmountComponentAtNode(...): Target container is not a DOM element.");
|
|
}
|
|
{
|
|
var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === void 0;
|
|
if (isModernRoot) {
|
|
error("You are calling ReactDOM.unmountComponentAtNode() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?");
|
|
}
|
|
}
|
|
if (container._reactRootContainer) {
|
|
{
|
|
var rootEl = getReactRootElementInContainer(container);
|
|
var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
|
|
if (renderedByDifferentReact) {
|
|
error("unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React.");
|
|
}
|
|
}
|
|
flushSync(function() {
|
|
legacyRenderSubtreeIntoContainer(null, null, container, false, function() {
|
|
container._reactRootContainer = null;
|
|
unmarkContainerAsRoot(container);
|
|
});
|
|
});
|
|
return true;
|
|
} else {
|
|
{
|
|
var _rootEl = getReactRootElementInContainer(container);
|
|
var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl));
|
|
var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer;
|
|
if (hasNonRootReactChild) {
|
|
error("unmountComponentAtNode(): The node you're attempting to unmount was rendered by React and is not a top-level container. %s", isContainerReactRoot ? "You may have accidentally passed in a React root node instead of its container." : "Instead, have the parent component update its state and rerender in order to remove this component.");
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
setAttemptSynchronousHydration(attemptSynchronousHydration$1);
|
|
setAttemptContinuousHydration(attemptContinuousHydration$1);
|
|
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
|
|
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
|
|
setAttemptHydrationAtPriority(runWithPriority);
|
|
{
|
|
if (typeof Map !== "function" || Map.prototype == null || typeof Map.prototype.forEach !== "function" || typeof Set !== "function" || Set.prototype == null || typeof Set.prototype.clear !== "function" || typeof Set.prototype.forEach !== "function") {
|
|
error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills");
|
|
}
|
|
}
|
|
setRestoreImplementation(restoreControlledState$3);
|
|
setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync);
|
|
function createPortal$1(children, container) {
|
|
var key = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : null;
|
|
if (!isValidContainer(container)) {
|
|
throw new Error("Target container is not a DOM element.");
|
|
}
|
|
return createPortal(children, container, null, key);
|
|
}
|
|
function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
|
|
return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
|
|
}
|
|
var Internals = {
|
|
usingClientEntryPoint: false,
|
|
Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, batchedUpdates$1]
|
|
};
|
|
function createRoot$1(container, options2) {
|
|
{
|
|
if (!Internals.usingClientEntryPoint && true) {
|
|
error('You are importing createRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client".');
|
|
}
|
|
}
|
|
return createRoot(container, options2);
|
|
}
|
|
function hydrateRoot$1(container, initialChildren, options2) {
|
|
{
|
|
if (!Internals.usingClientEntryPoint && true) {
|
|
error('You are importing hydrateRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client".');
|
|
}
|
|
}
|
|
return hydrateRoot(container, initialChildren, options2);
|
|
}
|
|
function flushSync$1(fn) {
|
|
{
|
|
if (isAlreadyRendering()) {
|
|
error("flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.");
|
|
}
|
|
}
|
|
return flushSync(fn);
|
|
}
|
|
var foundDevTools = injectIntoDevTools({
|
|
findFiberByHostInstance: getClosestInstanceFromNode,
|
|
bundleType: 1,
|
|
version: ReactVersion,
|
|
rendererPackageName: "react-dom"
|
|
});
|
|
{
|
|
if (!foundDevTools && canUseDOM && window.top === window.self) {
|
|
if (navigator.userAgent.indexOf("Chrome") > -1 && navigator.userAgent.indexOf("Edge") === -1 || navigator.userAgent.indexOf("Firefox") > -1) {
|
|
var protocol = window.location.protocol;
|
|
if (/^(https?|file):$/.test(protocol)) {
|
|
console.info("%cDownload the React DevTools for a better development experience: https://reactjs.org/link/react-devtools" + (protocol === "file:" ? "\nYou might need to use a local HTTP server (instead of file://): https://reactjs.org/link/react-devtools-faq" : ""), "font-weight:bold");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
|
|
exports.createPortal = createPortal$1;
|
|
exports.createRoot = createRoot$1;
|
|
exports.findDOMNode = findDOMNode;
|
|
exports.flushSync = flushSync$1;
|
|
exports.hydrate = hydrate;
|
|
exports.hydrateRoot = hydrateRoot$1;
|
|
exports.render = render;
|
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
exports.unstable_batchedUpdates = batchedUpdates$1;
|
|
exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
|
|
exports.version = ReactVersion;
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
|
|
}
|
|
})();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/react-dom/index.js
|
|
var require_react_dom = __commonJS({
|
|
"node_modules/react-dom/index.js"(exports, module) {
|
|
"use strict";
|
|
if (false) {
|
|
checkDCE();
|
|
module.exports = null;
|
|
} else {
|
|
module.exports = require_react_dom_development();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/react-dom/client.js
|
|
var require_client = __commonJS({
|
|
"node_modules/react-dom/client.js"(exports) {
|
|
"use strict";
|
|
var m = require_react_dom();
|
|
if (false) {
|
|
exports.createRoot = m.createRoot;
|
|
exports.hydrateRoot = m.hydrateRoot;
|
|
} else {
|
|
i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
exports.createRoot = function(c, o) {
|
|
i.usingClientEntryPoint = true;
|
|
try {
|
|
return m.createRoot(c, o);
|
|
} finally {
|
|
i.usingClientEntryPoint = false;
|
|
}
|
|
};
|
|
exports.hydrateRoot = function(c, h, o) {
|
|
i.usingClientEntryPoint = true;
|
|
try {
|
|
return m.hydrateRoot(c, h, o);
|
|
} finally {
|
|
i.usingClientEntryPoint = false;
|
|
}
|
|
};
|
|
}
|
|
var i;
|
|
}
|
|
});
|
|
|
|
// js/app.js
|
|
var import_react5 = __toESM(require_react());
|
|
var import_client = __toESM(require_client());
|
|
|
|
// node_modules/react-router-dom/index.js
|
|
var import_react2 = __toESM(require_react());
|
|
|
|
// node_modules/@babel/runtime/helpers/esm/extends.js
|
|
function _extends() {
|
|
_extends = Object.assign ? Object.assign.bind() : function(target) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
var source = arguments[i];
|
|
for (var key in source) {
|
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
target[key] = source[key];
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
};
|
|
return _extends.apply(this, arguments);
|
|
}
|
|
|
|
// node_modules/history/index.js
|
|
var Action;
|
|
(function(Action2) {
|
|
Action2["Pop"] = "POP";
|
|
Action2["Push"] = "PUSH";
|
|
Action2["Replace"] = "REPLACE";
|
|
})(Action || (Action = {}));
|
|
var readOnly = true ? function(obj) {
|
|
return Object.freeze(obj);
|
|
} : function(obj) {
|
|
return obj;
|
|
};
|
|
function warning(cond, message) {
|
|
if (!cond) {
|
|
if (typeof console !== "undefined")
|
|
console.warn(message);
|
|
try {
|
|
throw new Error(message);
|
|
} catch (e) {
|
|
}
|
|
}
|
|
}
|
|
var BeforeUnloadEventType = "beforeunload";
|
|
var PopStateEventType = "popstate";
|
|
function createBrowserHistory(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
var _options = options, _options$window = _options.window, window2 = _options$window === void 0 ? document.defaultView : _options$window;
|
|
var globalHistory = window2.history;
|
|
function getIndexAndLocation() {
|
|
var _window$location = window2.location, pathname = _window$location.pathname, search = _window$location.search, hash = _window$location.hash;
|
|
var state = globalHistory.state || {};
|
|
return [state.idx, readOnly({
|
|
pathname,
|
|
search,
|
|
hash,
|
|
state: state.usr || null,
|
|
key: state.key || "default"
|
|
})];
|
|
}
|
|
var blockedPopTx = null;
|
|
function handlePop() {
|
|
if (blockedPopTx) {
|
|
blockers.call(blockedPopTx);
|
|
blockedPopTx = null;
|
|
} else {
|
|
var nextAction = Action.Pop;
|
|
var _getIndexAndLocation = getIndexAndLocation(), nextIndex = _getIndexAndLocation[0], nextLocation = _getIndexAndLocation[1];
|
|
if (blockers.length) {
|
|
if (nextIndex != null) {
|
|
var delta = index - nextIndex;
|
|
if (delta) {
|
|
blockedPopTx = {
|
|
action: nextAction,
|
|
location: nextLocation,
|
|
retry: function retry() {
|
|
go(delta * -1);
|
|
}
|
|
};
|
|
go(delta);
|
|
}
|
|
} else {
|
|
true ? warning(false, "You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation.") : void 0;
|
|
}
|
|
} else {
|
|
applyTx(nextAction);
|
|
}
|
|
}
|
|
}
|
|
window2.addEventListener(PopStateEventType, handlePop);
|
|
var action = Action.Pop;
|
|
var _getIndexAndLocation2 = getIndexAndLocation(), index = _getIndexAndLocation2[0], location = _getIndexAndLocation2[1];
|
|
var listeners = createEvents();
|
|
var blockers = createEvents();
|
|
if (index == null) {
|
|
index = 0;
|
|
globalHistory.replaceState(_extends({}, globalHistory.state, {
|
|
idx: index
|
|
}), "");
|
|
}
|
|
function createHref(to) {
|
|
return typeof to === "string" ? to : createPath(to);
|
|
}
|
|
function getNextLocation(to, state) {
|
|
if (state === void 0) {
|
|
state = null;
|
|
}
|
|
return readOnly(_extends({
|
|
pathname: location.pathname,
|
|
hash: "",
|
|
search: ""
|
|
}, typeof to === "string" ? parsePath(to) : to, {
|
|
state,
|
|
key: createKey()
|
|
}));
|
|
}
|
|
function getHistoryStateAndUrl(nextLocation, index2) {
|
|
return [{
|
|
usr: nextLocation.state,
|
|
key: nextLocation.key,
|
|
idx: index2
|
|
}, createHref(nextLocation)];
|
|
}
|
|
function allowTx(action2, location2, retry) {
|
|
return !blockers.length || (blockers.call({
|
|
action: action2,
|
|
location: location2,
|
|
retry
|
|
}), false);
|
|
}
|
|
function applyTx(nextAction) {
|
|
action = nextAction;
|
|
var _getIndexAndLocation3 = getIndexAndLocation();
|
|
index = _getIndexAndLocation3[0];
|
|
location = _getIndexAndLocation3[1];
|
|
listeners.call({
|
|
action,
|
|
location
|
|
});
|
|
}
|
|
function push(to, state) {
|
|
var nextAction = Action.Push;
|
|
var nextLocation = getNextLocation(to, state);
|
|
function retry() {
|
|
push(to, state);
|
|
}
|
|
if (allowTx(nextAction, nextLocation, retry)) {
|
|
var _getHistoryStateAndUr = getHistoryStateAndUrl(nextLocation, index + 1), historyState = _getHistoryStateAndUr[0], url = _getHistoryStateAndUr[1];
|
|
try {
|
|
globalHistory.pushState(historyState, "", url);
|
|
} catch (error) {
|
|
window2.location.assign(url);
|
|
}
|
|
applyTx(nextAction);
|
|
}
|
|
}
|
|
function replace(to, state) {
|
|
var nextAction = Action.Replace;
|
|
var nextLocation = getNextLocation(to, state);
|
|
function retry() {
|
|
replace(to, state);
|
|
}
|
|
if (allowTx(nextAction, nextLocation, retry)) {
|
|
var _getHistoryStateAndUr2 = getHistoryStateAndUrl(nextLocation, index), historyState = _getHistoryStateAndUr2[0], url = _getHistoryStateAndUr2[1];
|
|
globalHistory.replaceState(historyState, "", url);
|
|
applyTx(nextAction);
|
|
}
|
|
}
|
|
function go(delta) {
|
|
globalHistory.go(delta);
|
|
}
|
|
var history = {
|
|
get action() {
|
|
return action;
|
|
},
|
|
get location() {
|
|
return location;
|
|
},
|
|
createHref,
|
|
push,
|
|
replace,
|
|
go,
|
|
back: function back() {
|
|
go(-1);
|
|
},
|
|
forward: function forward() {
|
|
go(1);
|
|
},
|
|
listen: function listen(listener) {
|
|
return listeners.push(listener);
|
|
},
|
|
block: function block(blocker) {
|
|
var unblock = blockers.push(blocker);
|
|
if (blockers.length === 1) {
|
|
window2.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
}
|
|
return function() {
|
|
unblock();
|
|
if (!blockers.length) {
|
|
window2.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
return history;
|
|
}
|
|
function promptBeforeUnload(event) {
|
|
event.preventDefault();
|
|
event.returnValue = "";
|
|
}
|
|
function createEvents() {
|
|
var handlers = [];
|
|
return {
|
|
get length() {
|
|
return handlers.length;
|
|
},
|
|
push: function push(fn) {
|
|
handlers.push(fn);
|
|
return function() {
|
|
handlers = handlers.filter(function(handler) {
|
|
return handler !== fn;
|
|
});
|
|
};
|
|
},
|
|
call: function call(arg) {
|
|
handlers.forEach(function(fn) {
|
|
return fn && fn(arg);
|
|
});
|
|
}
|
|
};
|
|
}
|
|
function createKey() {
|
|
return Math.random().toString(36).substr(2, 8);
|
|
}
|
|
function createPath(_ref) {
|
|
var _ref$pathname = _ref.pathname, pathname = _ref$pathname === void 0 ? "/" : _ref$pathname, _ref$search = _ref.search, search = _ref$search === void 0 ? "" : _ref$search, _ref$hash = _ref.hash, hash = _ref$hash === void 0 ? "" : _ref$hash;
|
|
if (search && search !== "?")
|
|
pathname += search.charAt(0) === "?" ? search : "?" + search;
|
|
if (hash && hash !== "#")
|
|
pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
|
|
return pathname;
|
|
}
|
|
function parsePath(path) {
|
|
var parsedPath = {};
|
|
if (path) {
|
|
var hashIndex = path.indexOf("#");
|
|
if (hashIndex >= 0) {
|
|
parsedPath.hash = path.substr(hashIndex);
|
|
path = path.substr(0, hashIndex);
|
|
}
|
|
var searchIndex = path.indexOf("?");
|
|
if (searchIndex >= 0) {
|
|
parsedPath.search = path.substr(searchIndex);
|
|
path = path.substr(0, searchIndex);
|
|
}
|
|
if (path) {
|
|
parsedPath.pathname = path;
|
|
}
|
|
}
|
|
return parsedPath;
|
|
}
|
|
|
|
// node_modules/react-router/index.js
|
|
var import_react = __toESM(require_react());
|
|
var NavigationContext = /* @__PURE__ */ (0, import_react.createContext)(null);
|
|
if (true) {
|
|
NavigationContext.displayName = "Navigation";
|
|
}
|
|
var LocationContext = /* @__PURE__ */ (0, import_react.createContext)(null);
|
|
if (true) {
|
|
LocationContext.displayName = "Location";
|
|
}
|
|
var RouteContext = /* @__PURE__ */ (0, import_react.createContext)({
|
|
outlet: null,
|
|
matches: []
|
|
});
|
|
if (true) {
|
|
RouteContext.displayName = "Route";
|
|
}
|
|
function invariant(cond, message) {
|
|
if (!cond)
|
|
throw new Error(message);
|
|
}
|
|
function warning2(cond, message) {
|
|
if (!cond) {
|
|
if (typeof console !== "undefined")
|
|
console.warn(message);
|
|
try {
|
|
throw new Error(message);
|
|
} catch (e) {
|
|
}
|
|
}
|
|
}
|
|
var alreadyWarned = {};
|
|
function warningOnce(key, cond, message) {
|
|
if (!cond && !alreadyWarned[key]) {
|
|
alreadyWarned[key] = true;
|
|
true ? warning2(false, message) : void 0;
|
|
}
|
|
}
|
|
function matchRoutes(routes, locationArg, basename) {
|
|
if (basename === void 0) {
|
|
basename = "/";
|
|
}
|
|
let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
|
|
let pathname = stripBasename(location.pathname || "/", basename);
|
|
if (pathname == null) {
|
|
return null;
|
|
}
|
|
let branches = flattenRoutes(routes);
|
|
rankRouteBranches(branches);
|
|
let matches = null;
|
|
for (let i = 0; matches == null && i < branches.length; ++i) {
|
|
matches = matchRouteBranch(branches[i], pathname);
|
|
}
|
|
return matches;
|
|
}
|
|
function flattenRoutes(routes, branches, parentsMeta, parentPath) {
|
|
if (branches === void 0) {
|
|
branches = [];
|
|
}
|
|
if (parentsMeta === void 0) {
|
|
parentsMeta = [];
|
|
}
|
|
if (parentPath === void 0) {
|
|
parentPath = "";
|
|
}
|
|
routes.forEach((route, index) => {
|
|
let meta = {
|
|
relativePath: route.path || "",
|
|
caseSensitive: route.caseSensitive === true,
|
|
childrenIndex: index,
|
|
route
|
|
};
|
|
if (meta.relativePath.startsWith("/")) {
|
|
!meta.relativePath.startsWith(parentPath) ? true ? invariant(false, 'Absolute route path "' + meta.relativePath + '" nested under path ' + ('"' + parentPath + '" is not valid. An absolute child route path ') + "must start with the combined path of all its parent routes.") : invariant(false) : void 0;
|
|
meta.relativePath = meta.relativePath.slice(parentPath.length);
|
|
}
|
|
let path = joinPaths([parentPath, meta.relativePath]);
|
|
let routesMeta = parentsMeta.concat(meta);
|
|
if (route.children && route.children.length > 0) {
|
|
!(route.index !== true) ? true ? invariant(false, "Index routes must not have child routes. Please remove " + ('all child routes from route path "' + path + '".')) : invariant(false) : void 0;
|
|
flattenRoutes(route.children, branches, routesMeta, path);
|
|
}
|
|
if (route.path == null && !route.index) {
|
|
return;
|
|
}
|
|
branches.push({
|
|
path,
|
|
score: computeScore(path, route.index),
|
|
routesMeta
|
|
});
|
|
});
|
|
return branches;
|
|
}
|
|
function rankRouteBranches(branches) {
|
|
branches.sort((a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(a.routesMeta.map((meta) => meta.childrenIndex), b.routesMeta.map((meta) => meta.childrenIndex)));
|
|
}
|
|
var paramRe = /^:\w+$/;
|
|
var dynamicSegmentValue = 3;
|
|
var indexRouteValue = 2;
|
|
var emptySegmentValue = 1;
|
|
var staticSegmentValue = 10;
|
|
var splatPenalty = -2;
|
|
var isSplat = (s) => s === "*";
|
|
function computeScore(path, index) {
|
|
let segments = path.split("/");
|
|
let initialScore = segments.length;
|
|
if (segments.some(isSplat)) {
|
|
initialScore += splatPenalty;
|
|
}
|
|
if (index) {
|
|
initialScore += indexRouteValue;
|
|
}
|
|
return segments.filter((s) => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
|
|
}
|
|
function compareIndexes(a, b) {
|
|
let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
|
|
return siblings ? a[a.length - 1] - b[b.length - 1] : 0;
|
|
}
|
|
function matchRouteBranch(branch, pathname) {
|
|
let {
|
|
routesMeta
|
|
} = branch;
|
|
let matchedParams = {};
|
|
let matchedPathname = "/";
|
|
let matches = [];
|
|
for (let i = 0; i < routesMeta.length; ++i) {
|
|
let meta = routesMeta[i];
|
|
let end = i === routesMeta.length - 1;
|
|
let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
|
|
let match = matchPath({
|
|
path: meta.relativePath,
|
|
caseSensitive: meta.caseSensitive,
|
|
end
|
|
}, remainingPathname);
|
|
if (!match)
|
|
return null;
|
|
Object.assign(matchedParams, match.params);
|
|
let route = meta.route;
|
|
matches.push({
|
|
params: matchedParams,
|
|
pathname: joinPaths([matchedPathname, match.pathname]),
|
|
pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])),
|
|
route
|
|
});
|
|
if (match.pathnameBase !== "/") {
|
|
matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
|
|
}
|
|
}
|
|
return matches;
|
|
}
|
|
function matchPath(pattern, pathname) {
|
|
if (typeof pattern === "string") {
|
|
pattern = {
|
|
path: pattern,
|
|
caseSensitive: false,
|
|
end: true
|
|
};
|
|
}
|
|
let [matcher, paramNames] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
|
|
let match = pathname.match(matcher);
|
|
if (!match)
|
|
return null;
|
|
let matchedPathname = match[0];
|
|
let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
|
|
let captureGroups = match.slice(1);
|
|
let params = paramNames.reduce((memo, paramName, index) => {
|
|
if (paramName === "*") {
|
|
let splatValue = captureGroups[index] || "";
|
|
pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
|
|
}
|
|
memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || "", paramName);
|
|
return memo;
|
|
}, {});
|
|
return {
|
|
params,
|
|
pathname: matchedPathname,
|
|
pathnameBase,
|
|
pattern
|
|
};
|
|
}
|
|
function compilePath(path, caseSensitive, end) {
|
|
if (caseSensitive === void 0) {
|
|
caseSensitive = false;
|
|
}
|
|
if (end === void 0) {
|
|
end = true;
|
|
}
|
|
true ? warning2(path === "*" || !path.endsWith("*") || path.endsWith("/*"), 'Route path "' + path + '" will be treated as if it were ' + ('"' + path.replace(/\*$/, "/*") + '" because the `*` character must ') + "always follow a `/` in the pattern. To get rid of this warning, " + ('please change the route path to "' + path.replace(/\*$/, "/*") + '".')) : void 0;
|
|
let paramNames = [];
|
|
let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^$?{}|()[\]]/g, "\\$&").replace(/:(\w+)/g, (_, paramName) => {
|
|
paramNames.push(paramName);
|
|
return "([^\\/]+)";
|
|
});
|
|
if (path.endsWith("*")) {
|
|
paramNames.push("*");
|
|
regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
|
|
} else {
|
|
regexpSource += end ? "\\/*$" : "(?:(?=[.~-]|%[0-9A-F]{2})|\\b|\\/|$)";
|
|
}
|
|
let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
|
|
return [matcher, paramNames];
|
|
}
|
|
function safelyDecodeURIComponent(value, paramName) {
|
|
try {
|
|
return decodeURIComponent(value);
|
|
} catch (error) {
|
|
true ? warning2(false, 'The value for the URL param "' + paramName + '" will not be decoded because' + (' the string "' + value + '" is a malformed URL segment. This is probably') + (" due to a bad percent encoding (" + error + ").")) : void 0;
|
|
return value;
|
|
}
|
|
}
|
|
function resolvePath(to, fromPathname) {
|
|
if (fromPathname === void 0) {
|
|
fromPathname = "/";
|
|
}
|
|
let {
|
|
pathname: toPathname,
|
|
search = "",
|
|
hash = ""
|
|
} = typeof to === "string" ? parsePath(to) : to;
|
|
let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname;
|
|
return {
|
|
pathname,
|
|
search: normalizeSearch(search),
|
|
hash: normalizeHash(hash)
|
|
};
|
|
}
|
|
function resolvePathname(relativePath, fromPathname) {
|
|
let segments = fromPathname.replace(/\/+$/, "").split("/");
|
|
let relativeSegments = relativePath.split("/");
|
|
relativeSegments.forEach((segment) => {
|
|
if (segment === "..") {
|
|
if (segments.length > 1)
|
|
segments.pop();
|
|
} else if (segment !== ".") {
|
|
segments.push(segment);
|
|
}
|
|
});
|
|
return segments.length > 1 ? segments.join("/") : "/";
|
|
}
|
|
function resolveTo(toArg, routePathnames, locationPathname) {
|
|
let to = typeof toArg === "string" ? parsePath(toArg) : toArg;
|
|
let toPathname = toArg === "" || to.pathname === "" ? "/" : to.pathname;
|
|
let from;
|
|
if (toPathname == null) {
|
|
from = locationPathname;
|
|
} else {
|
|
let routePathnameIndex = routePathnames.length - 1;
|
|
if (toPathname.startsWith("..")) {
|
|
let toSegments = toPathname.split("/");
|
|
while (toSegments[0] === "..") {
|
|
toSegments.shift();
|
|
routePathnameIndex -= 1;
|
|
}
|
|
to.pathname = toSegments.join("/");
|
|
}
|
|
from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
|
|
}
|
|
let path = resolvePath(to, from);
|
|
if (toPathname && toPathname !== "/" && toPathname.endsWith("/") && !path.pathname.endsWith("/")) {
|
|
path.pathname += "/";
|
|
}
|
|
return path;
|
|
}
|
|
function getToPathname(to) {
|
|
return to === "" || to.pathname === "" ? "/" : typeof to === "string" ? parsePath(to).pathname : to.pathname;
|
|
}
|
|
function stripBasename(pathname, basename) {
|
|
if (basename === "/")
|
|
return pathname;
|
|
if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
|
|
return null;
|
|
}
|
|
let nextChar = pathname.charAt(basename.length);
|
|
if (nextChar && nextChar !== "/") {
|
|
return null;
|
|
}
|
|
return pathname.slice(basename.length) || "/";
|
|
}
|
|
var joinPaths = (paths) => paths.join("/").replace(/\/\/+/g, "/");
|
|
var normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
|
|
var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
|
|
var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
|
|
function useHref(to) {
|
|
!useInRouterContext() ? true ? invariant(false, "useHref() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
let {
|
|
basename,
|
|
navigator: navigator2
|
|
} = (0, import_react.useContext)(NavigationContext);
|
|
let {
|
|
hash,
|
|
pathname,
|
|
search
|
|
} = useResolvedPath(to);
|
|
let joinedPathname = pathname;
|
|
if (basename !== "/") {
|
|
let toPathname = getToPathname(to);
|
|
let endsWithSlash = toPathname != null && toPathname.endsWith("/");
|
|
joinedPathname = pathname === "/" ? basename + (endsWithSlash ? "/" : "") : joinPaths([basename, pathname]);
|
|
}
|
|
return navigator2.createHref({
|
|
pathname: joinedPathname,
|
|
search,
|
|
hash
|
|
});
|
|
}
|
|
function useInRouterContext() {
|
|
return (0, import_react.useContext)(LocationContext) != null;
|
|
}
|
|
function useLocation() {
|
|
!useInRouterContext() ? true ? invariant(false, "useLocation() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
return (0, import_react.useContext)(LocationContext).location;
|
|
}
|
|
function useNavigate() {
|
|
!useInRouterContext() ? true ? invariant(false, "useNavigate() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
let {
|
|
basename,
|
|
navigator: navigator2
|
|
} = (0, import_react.useContext)(NavigationContext);
|
|
let {
|
|
matches
|
|
} = (0, import_react.useContext)(RouteContext);
|
|
let {
|
|
pathname: locationPathname
|
|
} = useLocation();
|
|
let routePathnamesJson = JSON.stringify(matches.map((match) => match.pathnameBase));
|
|
let activeRef = (0, import_react.useRef)(false);
|
|
(0, import_react.useEffect)(() => {
|
|
activeRef.current = true;
|
|
});
|
|
let navigate = (0, import_react.useCallback)(function(to, options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
true ? warning2(activeRef.current, "You should call navigate() in a React.useEffect(), not when your component is first rendered.") : void 0;
|
|
if (!activeRef.current)
|
|
return;
|
|
if (typeof to === "number") {
|
|
navigator2.go(to);
|
|
return;
|
|
}
|
|
let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname);
|
|
if (basename !== "/") {
|
|
path.pathname = joinPaths([basename, path.pathname]);
|
|
}
|
|
(!!options.replace ? navigator2.replace : navigator2.push)(path, options.state);
|
|
}, [basename, navigator2, routePathnamesJson, locationPathname]);
|
|
return navigate;
|
|
}
|
|
function useParams() {
|
|
let {
|
|
matches
|
|
} = (0, import_react.useContext)(RouteContext);
|
|
let routeMatch = matches[matches.length - 1];
|
|
return routeMatch ? routeMatch.params : {};
|
|
}
|
|
function useResolvedPath(to) {
|
|
let {
|
|
matches
|
|
} = (0, import_react.useContext)(RouteContext);
|
|
let {
|
|
pathname: locationPathname
|
|
} = useLocation();
|
|
let routePathnamesJson = JSON.stringify(matches.map((match) => match.pathnameBase));
|
|
return (0, import_react.useMemo)(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname), [to, routePathnamesJson, locationPathname]);
|
|
}
|
|
function useRoutes(routes, locationArg) {
|
|
!useInRouterContext() ? true ? invariant(false, "useRoutes() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
let {
|
|
matches: parentMatches
|
|
} = (0, import_react.useContext)(RouteContext);
|
|
let routeMatch = parentMatches[parentMatches.length - 1];
|
|
let parentParams = routeMatch ? routeMatch.params : {};
|
|
let parentPathname = routeMatch ? routeMatch.pathname : "/";
|
|
let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
|
|
let parentRoute = routeMatch && routeMatch.route;
|
|
if (true) {
|
|
let parentPath = parentRoute && parentRoute.path || "";
|
|
warningOnce(parentPathname, !parentRoute || parentPath.endsWith("*"), "You rendered descendant <Routes> (or called `useRoutes()`) at " + ('"' + parentPathname + '" (under <Route path="' + parentPath + '">) but the ') + `parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
|
|
|
|
` + ('Please change the parent <Route path="' + parentPath + '"> to <Route ') + ('path="' + (parentPath === "/" ? "*" : parentPath + "/*") + '">.'));
|
|
}
|
|
let locationFromContext = useLocation();
|
|
let location;
|
|
if (locationArg) {
|
|
var _parsedLocationArg$pa;
|
|
let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
|
|
!(parentPathnameBase === "/" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? true ? invariant(false, "When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, the location pathname must begin with the portion of the URL pathname that was " + ('matched by all parent routes. The current pathname base is "' + parentPathnameBase + '" ') + ('but pathname "' + parsedLocationArg.pathname + '" was given in the `location` prop.')) : invariant(false) : void 0;
|
|
location = parsedLocationArg;
|
|
} else {
|
|
location = locationFromContext;
|
|
}
|
|
let pathname = location.pathname || "/";
|
|
let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/";
|
|
let matches = matchRoutes(routes, {
|
|
pathname: remainingPathname
|
|
});
|
|
if (true) {
|
|
true ? warning2(parentRoute || matches != null, 'No routes matched location "' + location.pathname + location.search + location.hash + '" ') : void 0;
|
|
true ? warning2(matches == null || matches[matches.length - 1].route.element !== void 0, 'Matched leaf route at location "' + location.pathname + location.search + location.hash + '" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.') : void 0;
|
|
}
|
|
return _renderMatches(matches && matches.map((match) => Object.assign({}, match, {
|
|
params: Object.assign({}, parentParams, match.params),
|
|
pathname: joinPaths([parentPathnameBase, match.pathname]),
|
|
pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase, match.pathnameBase])
|
|
})), parentMatches);
|
|
}
|
|
function _renderMatches(matches, parentMatches) {
|
|
if (parentMatches === void 0) {
|
|
parentMatches = [];
|
|
}
|
|
if (matches == null)
|
|
return null;
|
|
return matches.reduceRight((outlet, match, index) => {
|
|
return /* @__PURE__ */ (0, import_react.createElement)(RouteContext.Provider, {
|
|
children: match.route.element !== void 0 ? match.route.element : outlet,
|
|
value: {
|
|
outlet,
|
|
matches: parentMatches.concat(matches.slice(0, index + 1))
|
|
}
|
|
});
|
|
}, null);
|
|
}
|
|
function Route(_props) {
|
|
true ? invariant(false, "A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.") : invariant(false);
|
|
}
|
|
function Router(_ref3) {
|
|
let {
|
|
basename: basenameProp = "/",
|
|
children = null,
|
|
location: locationProp,
|
|
navigationType = Action.Pop,
|
|
navigator: navigator2,
|
|
static: staticProp = false
|
|
} = _ref3;
|
|
!!useInRouterContext() ? true ? invariant(false, "You cannot render a <Router> inside another <Router>. You should never have more than one in your app.") : invariant(false) : void 0;
|
|
let basename = normalizePathname(basenameProp);
|
|
let navigationContext = (0, import_react.useMemo)(() => ({
|
|
basename,
|
|
navigator: navigator2,
|
|
static: staticProp
|
|
}), [basename, navigator2, staticProp]);
|
|
if (typeof locationProp === "string") {
|
|
locationProp = parsePath(locationProp);
|
|
}
|
|
let {
|
|
pathname = "/",
|
|
search = "",
|
|
hash = "",
|
|
state = null,
|
|
key = "default"
|
|
} = locationProp;
|
|
let location = (0, import_react.useMemo)(() => {
|
|
let trailingPathname = stripBasename(pathname, basename);
|
|
if (trailingPathname == null) {
|
|
return null;
|
|
}
|
|
return {
|
|
pathname: trailingPathname,
|
|
search,
|
|
hash,
|
|
state,
|
|
key
|
|
};
|
|
}, [basename, pathname, search, hash, state, key]);
|
|
true ? warning2(location != null, '<Router basename="' + basename + '"> is not able to match the URL ' + ('"' + pathname + search + hash + '" because it does not start with the ') + "basename, so the <Router> won't render anything.") : void 0;
|
|
if (location == null) {
|
|
return null;
|
|
}
|
|
return /* @__PURE__ */ (0, import_react.createElement)(NavigationContext.Provider, {
|
|
value: navigationContext
|
|
}, /* @__PURE__ */ (0, import_react.createElement)(LocationContext.Provider, {
|
|
children,
|
|
value: {
|
|
location,
|
|
navigationType
|
|
}
|
|
}));
|
|
}
|
|
function Routes(_ref4) {
|
|
let {
|
|
children,
|
|
location
|
|
} = _ref4;
|
|
return useRoutes(createRoutesFromChildren(children), location);
|
|
}
|
|
function createRoutesFromChildren(children) {
|
|
let routes = [];
|
|
import_react.Children.forEach(children, (element) => {
|
|
if (!/* @__PURE__ */ (0, import_react.isValidElement)(element)) {
|
|
return;
|
|
}
|
|
if (element.type === import_react.Fragment) {
|
|
routes.push.apply(routes, createRoutesFromChildren(element.props.children));
|
|
return;
|
|
}
|
|
!(element.type === Route) ? true ? invariant(false, "[" + (typeof element.type === "string" ? element.type : element.type.name) + "] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>") : invariant(false) : void 0;
|
|
let route = {
|
|
caseSensitive: element.props.caseSensitive,
|
|
element: element.props.element,
|
|
index: element.props.index,
|
|
path: element.props.path
|
|
};
|
|
if (element.props.children) {
|
|
route.children = createRoutesFromChildren(element.props.children);
|
|
}
|
|
routes.push(route);
|
|
});
|
|
return routes;
|
|
}
|
|
|
|
// node_modules/react-router-dom/index.js
|
|
function _extends2() {
|
|
_extends2 = Object.assign || function(target) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
var source = arguments[i];
|
|
for (var key in source) {
|
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
target[key] = source[key];
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
};
|
|
return _extends2.apply(this, arguments);
|
|
}
|
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
if (source == null)
|
|
return {};
|
|
var target = {};
|
|
var sourceKeys = Object.keys(source);
|
|
var key, i;
|
|
for (i = 0; i < sourceKeys.length; i++) {
|
|
key = sourceKeys[i];
|
|
if (excluded.indexOf(key) >= 0)
|
|
continue;
|
|
target[key] = source[key];
|
|
}
|
|
return target;
|
|
}
|
|
var _excluded = ["onClick", "reloadDocument", "replace", "state", "target", "to"];
|
|
var _excluded2 = ["aria-current", "caseSensitive", "className", "end", "style", "to", "children"];
|
|
function BrowserRouter(_ref) {
|
|
let {
|
|
basename,
|
|
children,
|
|
window: window2
|
|
} = _ref;
|
|
let historyRef = (0, import_react2.useRef)();
|
|
if (historyRef.current == null) {
|
|
historyRef.current = createBrowserHistory({
|
|
window: window2
|
|
});
|
|
}
|
|
let history = historyRef.current;
|
|
let [state, setState] = (0, import_react2.useState)({
|
|
action: history.action,
|
|
location: history.location
|
|
});
|
|
(0, import_react2.useLayoutEffect)(() => history.listen(setState), [history]);
|
|
return /* @__PURE__ */ (0, import_react2.createElement)(Router, {
|
|
basename,
|
|
children,
|
|
location: state.location,
|
|
navigationType: state.action,
|
|
navigator: history
|
|
});
|
|
}
|
|
function HistoryRouter(_ref3) {
|
|
let {
|
|
basename,
|
|
children,
|
|
history
|
|
} = _ref3;
|
|
const [state, setState] = (0, import_react2.useState)({
|
|
action: history.action,
|
|
location: history.location
|
|
});
|
|
(0, import_react2.useLayoutEffect)(() => history.listen(setState), [history]);
|
|
return /* @__PURE__ */ (0, import_react2.createElement)(Router, {
|
|
basename,
|
|
children,
|
|
location: state.location,
|
|
navigationType: state.action,
|
|
navigator: history
|
|
});
|
|
}
|
|
if (true) {
|
|
HistoryRouter.displayName = "unstable_HistoryRouter";
|
|
}
|
|
function isModifiedEvent(event) {
|
|
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
|
}
|
|
var Link = /* @__PURE__ */ (0, import_react2.forwardRef)(function LinkWithRef(_ref4, ref) {
|
|
let {
|
|
onClick,
|
|
reloadDocument,
|
|
replace = false,
|
|
state,
|
|
target,
|
|
to
|
|
} = _ref4, rest = _objectWithoutPropertiesLoose(_ref4, _excluded);
|
|
let href = useHref(to);
|
|
let internalOnClick = useLinkClickHandler(to, {
|
|
replace,
|
|
state,
|
|
target
|
|
});
|
|
function handleClick(event) {
|
|
if (onClick)
|
|
onClick(event);
|
|
if (!event.defaultPrevented && !reloadDocument) {
|
|
internalOnClick(event);
|
|
}
|
|
}
|
|
return /* @__PURE__ */ (0, import_react2.createElement)("a", _extends2({}, rest, {
|
|
href,
|
|
onClick: handleClick,
|
|
ref,
|
|
target
|
|
}));
|
|
});
|
|
if (true) {
|
|
Link.displayName = "Link";
|
|
}
|
|
var NavLink = /* @__PURE__ */ (0, import_react2.forwardRef)(function NavLinkWithRef(_ref5, ref) {
|
|
let {
|
|
"aria-current": ariaCurrentProp = "page",
|
|
caseSensitive = false,
|
|
className: classNameProp = "",
|
|
end = false,
|
|
style: styleProp,
|
|
to,
|
|
children
|
|
} = _ref5, rest = _objectWithoutPropertiesLoose(_ref5, _excluded2);
|
|
let location = useLocation();
|
|
let path = useResolvedPath(to);
|
|
let locationPathname = location.pathname;
|
|
let toPathname = path.pathname;
|
|
if (!caseSensitive) {
|
|
locationPathname = locationPathname.toLowerCase();
|
|
toPathname = toPathname.toLowerCase();
|
|
}
|
|
let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(toPathname.length) === "/";
|
|
let ariaCurrent = isActive ? ariaCurrentProp : void 0;
|
|
let className;
|
|
if (typeof classNameProp === "function") {
|
|
className = classNameProp({
|
|
isActive
|
|
});
|
|
} else {
|
|
className = [classNameProp, isActive ? "active" : null].filter(Boolean).join(" ");
|
|
}
|
|
let style = typeof styleProp === "function" ? styleProp({
|
|
isActive
|
|
}) : styleProp;
|
|
return /* @__PURE__ */ (0, import_react2.createElement)(Link, _extends2({}, rest, {
|
|
"aria-current": ariaCurrent,
|
|
className,
|
|
ref,
|
|
style,
|
|
to
|
|
}), typeof children === "function" ? children({
|
|
isActive
|
|
}) : children);
|
|
});
|
|
if (true) {
|
|
NavLink.displayName = "NavLink";
|
|
}
|
|
function useLinkClickHandler(to, _temp) {
|
|
let {
|
|
target,
|
|
replace: replaceProp,
|
|
state
|
|
} = _temp === void 0 ? {} : _temp;
|
|
let navigate = useNavigate();
|
|
let location = useLocation();
|
|
let path = useResolvedPath(to);
|
|
return (0, import_react2.useCallback)((event) => {
|
|
if (event.button === 0 && (!target || target === "_self") && !isModifiedEvent(event)) {
|
|
event.preventDefault();
|
|
let replace = !!replaceProp || createPath(location) === createPath(path);
|
|
navigate(to, {
|
|
replace,
|
|
state
|
|
});
|
|
}
|
|
}, [location, navigate, path, replaceProp, state, target, to]);
|
|
}
|
|
|
|
// js/home.js
|
|
var import_react3 = __toESM(require_react());
|
|
var Home = (props) => {
|
|
const [randomURL, setRandomURL] = (0, import_react3.useState)(null);
|
|
const navigate = useNavigate();
|
|
(0, import_react3.useEffect)(() => {
|
|
const params = new URLSearchParams(window.location.search);
|
|
const id = params.get("u");
|
|
if (id != null) {
|
|
navigate("/u/" + id);
|
|
}
|
|
const randomID = Math.floor(Math.random() * 1e6);
|
|
setRandomURL("/u/" + randomID);
|
|
}, []);
|
|
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
className: "main-container"
|
|
}, /* @__PURE__ */ import_react3.default.createElement("h1", null, " Welcome to Cat Bookmarker "), /* @__PURE__ */ import_react3.default.createElement("p", null, "Cat Bookmarker is a tool that serves random cat images from the ", /* @__PURE__ */ import_react3.default.createElement("a", {
|
|
href: "https://cataas.com"
|
|
}, "Cataas"), " (Cat As A Service) API and invites you to bookmark the ones you like so that you can come back to them later. You can categorize your cat photos with user-generated tags and you can leave a note to remind yourself why you liked the cat so much in the first place."), /* @__PURE__ */ import_react3.default.createElement("p", null, "Cat Bookmarker features a very rudimentary user authentication system using randomly generated user IDs and HTTP Authorization headers. Every number that won't cause an integer overflow is a valid user that has its own bookmarks and categories."), randomURL != null ? /* @__PURE__ */ import_react3.default.createElement("p", null, "Don't already have an account? Try:", /* @__PURE__ */ import_react3.default.createElement("br", null), /* @__PURE__ */ import_react3.default.createElement(Link, {
|
|
to: randomURL
|
|
}, randomURL)) : /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null));
|
|
};
|
|
var home_default = Home;
|
|
|
|
// js/bookmarks.js
|
|
var import_react4 = __toESM(require_react());
|
|
var cataas = (endpoint) => "https://cataas.com" + endpoint;
|
|
var bookmarker = (endpoint) => "http://localhost:4000/api/v1" + endpoint;
|
|
var Bookmarks = (props) => {
|
|
const { id } = useParams();
|
|
const headers = {
|
|
"Authorization": "Basic " + id
|
|
};
|
|
const [randomCat, setRandomCat] = (0, import_react4.useState)(null);
|
|
const [formState, setFormState] = (0, import_react4.useState)({
|
|
category: "",
|
|
notes: ""
|
|
});
|
|
const [categories, setCategories] = (0, import_react4.useState)([]);
|
|
const [activeCategory, setActiveCategory] = (0, import_react4.useState)(null);
|
|
const [categoryCollection, setCategoryCollection] = (0, import_react4.useState)([]);
|
|
(0, import_react4.useEffect)(() => {
|
|
showNewCat();
|
|
getAllCategories();
|
|
}, []);
|
|
(0, import_react4.useEffect)(() => {
|
|
(async () => {
|
|
if (activeCategory != null) {
|
|
const req = await fetch(bookmarker("/bookmark/category/" + activeCategory), { headers });
|
|
setCategoryCollection(await req.json());
|
|
}
|
|
})();
|
|
}, [activeCategory]);
|
|
const showNewCat = async () => {
|
|
setRandomCat(null);
|
|
const req = await fetch(cataas("/cat?json=true"));
|
|
setRandomCat(await req.json());
|
|
};
|
|
const getAllCategories = async () => {
|
|
const req = await fetch(bookmarker("/bookmark/categories"), { headers });
|
|
setCategories(await req.json());
|
|
};
|
|
const chooseCategory = (category) => {
|
|
setActiveCategory(category);
|
|
};
|
|
const bookmarkCat = async () => {
|
|
const req = await fetch(bookmarker("/bookmark"), {
|
|
method: "POST",
|
|
headers: __spreadProps(__spreadValues({}, headers), {
|
|
"Content-Type": "application/json"
|
|
}),
|
|
body: JSON.stringify(__spreadProps(__spreadValues({}, formState), { remote_id: randomCat.id }))
|
|
});
|
|
await getAllCategories();
|
|
setFormState({
|
|
category: "",
|
|
notes: ""
|
|
});
|
|
await showNewCat();
|
|
};
|
|
const removeBookmark = async (id2) => {
|
|
const req = await fetch(bookmarker("/bookmark/" + id2), {
|
|
headers,
|
|
method: "DELETE"
|
|
});
|
|
setCategoryCollection(categoryCollection.filter((c) => c.id != id2));
|
|
};
|
|
return /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
className: "main-container"
|
|
}, /* @__PURE__ */ import_react4.default.createElement("h2", {
|
|
className: "center-text"
|
|
}, " Random Cat "), /* @__PURE__ */ import_react4.default.createElement("div", null, /* @__PURE__ */ import_react4.default.createElement("img", {
|
|
className: "random-image center-box-inner",
|
|
src: randomCat != null ? cataas(randomCat.url) : null,
|
|
alt: randomCat != null ? randomCat.tags.join(" ") : "Loading cat..."
|
|
}), /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
className: "center-text"
|
|
}, /* @__PURE__ */ import_react4.default.createElement("button", {
|
|
onClick: showNewCat
|
|
}, "Show New Cat"))), /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
className: "form-container"
|
|
}, /* @__PURE__ */ import_react4.default.createElement("h3", {
|
|
className: "center-text"
|
|
}, "Like this cat? Bookmark them."), /* @__PURE__ */ import_react4.default.createElement(NewBookmarkForm, {
|
|
submitCallback: bookmarkCat,
|
|
setter: setFormState,
|
|
state: formState
|
|
})), /* @__PURE__ */ import_react4.default.createElement("h2", null, " Browse your collections "), /* @__PURE__ */ import_react4.default.createElement(SelectCategory, {
|
|
categories,
|
|
activeCategory,
|
|
callback: chooseCategory
|
|
}), /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
style: { height: 50 }
|
|
}), activeCategory != null && categoryCollection.length > 0 ? /* @__PURE__ */ import_react4.default.createElement(BookmarkCollection, {
|
|
removeCallback: removeBookmark,
|
|
bookmarks: categoryCollection
|
|
}) : /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null));
|
|
};
|
|
var Form = (props) => {
|
|
const updaterFactory = (key) => (e) => props.setter(__spreadProps(__spreadValues({}, props.state), {
|
|
[key]: e.target.value
|
|
}));
|
|
return /* @__PURE__ */ import_react4.default.createElement("form", {
|
|
onSubmit: (e) => e.preventDefault()
|
|
}, props.inputs.map((data, i) => /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
key: i
|
|
}, /* @__PURE__ */ import_react4.default.createElement("p", {
|
|
className: "form-label"
|
|
}, " ", data.label, " "), /* @__PURE__ */ import_react4.default.createElement("input", {
|
|
placeholder: data.placeholder,
|
|
value: props.state[data.name],
|
|
onChange: updaterFactory(data.name)
|
|
}))), /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
className: "center-text"
|
|
}, /* @__PURE__ */ import_react4.default.createElement("button", {
|
|
className: "form-submit-button",
|
|
onClick: props.submitCallback
|
|
}, "Submit")));
|
|
};
|
|
var NewBookmarkForm = (props) => /* @__PURE__ */ import_react4.default.createElement(Form, __spreadProps(__spreadValues({}, props), {
|
|
inputs: [
|
|
{
|
|
name: "category",
|
|
label: "Category name",
|
|
placeholder: " Something really cool..."
|
|
},
|
|
{ name: "notes", label: "Notes", placeholder: "Any other notes" }
|
|
]
|
|
}));
|
|
var SelectCategory = ({ categories, activeCategory, callback }) => {
|
|
return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, categories.length > 0 ? categories.map((category, i) => /* @__PURE__ */ import_react4.default.createElement("button", {
|
|
className: category == activeCategory ? "active" : "",
|
|
key: i,
|
|
onClick: () => callback(category)
|
|
}, category)) : /* @__PURE__ */ import_react4.default.createElement("p", null, "Nothing to show"));
|
|
};
|
|
var BookmarkCollection = ({
|
|
bookmarks,
|
|
removeCallback
|
|
}) => bookmarks.map((b, i) => /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
key: i
|
|
}, /* @__PURE__ */ import_react4.default.createElement("img", {
|
|
className: "collection-image",
|
|
src: cataas("/cat/" + b.remote_id)
|
|
}), /* @__PURE__ */ import_react4.default.createElement("div", {
|
|
className: "collection-item-caption"
|
|
}, /* @__PURE__ */ import_react4.default.createElement("button", {
|
|
onClick: () => removeCallback(b.id)
|
|
}, "\u{1F5D1}\uFE0F"), b.notes != null && b.notes.length > 0 ? /* @__PURE__ */ import_react4.default.createElement("p", {
|
|
className: "collection-note"
|
|
}, " ", b.notes, " ") : /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null))));
|
|
var bookmarks_default = Bookmarks;
|
|
|
|
// js/app.js
|
|
var root = import_client.default.createRoot(document.getElementById("root"));
|
|
root.render(/* @__PURE__ */ import_react5.default.createElement(BrowserRouter, null, /* @__PURE__ */ import_react5.default.createElement(Routes, null, /* @__PURE__ */ import_react5.default.createElement(Route, {
|
|
path: "/",
|
|
element: /* @__PURE__ */ import_react5.default.createElement(home_default, null)
|
|
}), /* @__PURE__ */ import_react5.default.createElement(Route, {
|
|
path: "u/:id",
|
|
element: /* @__PURE__ */ import_react5.default.createElement(bookmarks_default, null)
|
|
}))));
|
|
})();
|
|
/**
|
|
* @license React
|
|
* react-dom.development.js
|
|
*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
/**
|
|
* @license React
|
|
* react.development.js
|
|
*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
/**
|
|
* @license React
|
|
* scheduler.development.js
|
|
*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
/**
|
|
* Checks if an event is supported in the current execution environment.
|
|
*
|
|
* NOTE: This will not work correctly for non-generic events such as `change`,
|
|
* `reset`, `load`, `error`, and `select`.
|
|
*
|
|
* Borrows from Modernizr.
|
|
*
|
|
* @param {string} eventNameSuffix Event name, e.g. "click".
|
|
* @return {boolean} True if the event is supported.
|
|
* @internal
|
|
* @license Modernizr 3.0.0pre (Custom Build) | MIT
|
|
*/
|
|
/**
|
|
* React Router DOM v6.3.0
|
|
*
|
|
* Copyright (c) Remix Software Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE.md file in the root directory of this source tree.
|
|
*
|
|
* @license MIT
|
|
*/
|
|
/**
|
|
* React Router v6.3.0
|
|
*
|
|
* Copyright (c) Remix Software Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE.md file in the root directory of this source tree.
|
|
*
|
|
* @license MIT
|
|
*/
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vYXNzZXRzL25vZGVfbW9kdWxlcy9yZWFjdC9janMvcmVhY3QuZGV2ZWxvcG1lbnQuanMiLCAiLi4vLi4vLi4vYXNzZXRzL25vZGVfbW9kdWxlcy9yZWFjdC9pbmRleC5qcyIsICIuLi8uLi8uLi9hc3NldHMvbm9kZV9tb2R1bGVzL3NjaGVkdWxlci9janMvc2NoZWR1bGVyLmRldmVsb3BtZW50LmpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9ub2RlX21vZHVsZXMvc2NoZWR1bGVyL2luZGV4LmpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9ub2RlX21vZHVsZXMvcmVhY3QtZG9tL2Nqcy9yZWFjdC1kb20uZGV2ZWxvcG1lbnQuanMiLCAiLi4vLi4vLi4vYXNzZXRzL25vZGVfbW9kdWxlcy9yZWFjdC1kb20vaW5kZXguanMiLCAiLi4vLi4vLi4vYXNzZXRzL25vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2xpZW50LmpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9qcy9hcHAuanMiLCAiLi4vLi4vLi4vYXNzZXRzL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzLmpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9ub2RlX21vZHVsZXMvaGlzdG9yeS9pbmRleC5qcyIsICIuLi8uLi8uLi9wYWNrYWdlcy9yZWFjdC1yb3V0ZXIvbGliL2NvbnRleHQudHMiLCAiLi4vLi4vLi4vcGFja2FnZXMvcmVhY3Qtcm91dGVyL2xpYi9yb3V0ZXIudHMiLCAiLi4vLi4vLi4vcGFja2FnZXMvcmVhY3Qtcm91dGVyL2xpYi9ob29rcy50c3giLCAiLi4vLi4vLi4vcGFja2FnZXMvcmVhY3Qtcm91dGVyL2xpYi9jb21wb25lbnRzLnRzeCIsICIuLi8uLi8uLi9wYWNrYWdlcy9yZWFjdC1yb3V0ZXItZG9tL2luZGV4LnRzeCIsICIuLi8uLi8uLi9hc3NldHMvanMvaG9tZS5qcyIsICIuLi8uLi8uLi9hc3NldHMvanMvYm9va21hcmtzLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC5kZXZlbG9wbWVudC5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQobmV3IEVycm9yKCkpO1xufVxuICAgICAgICAgIHZhciBSZWFjdFZlcnNpb24gPSAnMTguMS4wJztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIGVuYWJsZVNjb3BlQVBJID0gZmFsc2U7IC8vIEV4cGVyaW1lbnRhbCBDcmVhdGUgRXZlbnQgSGFuZGxlIEFQSS5cbnZhciBlbmFibGVDYWNoZUVsZW1lbnQgPSBmYWxzZTtcbnZhciBlbmFibGVUcmFuc2l0aW9uVHJhY2luZyA9IGZhbHNlOyAvLyBObyBrbm93biBidWdzLCBidXQgbmVlZHMgcGVyZm9ybWFuY2UgdGVzdGluZ1xuXG52YXIgZW5hYmxlTGVnYWN5SGlkZGVuID0gZmFsc2U7IC8vIEVuYWJsZXMgdW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgZmVhdHVyZSBpbiBGaWJlclxuLy8gc3R1ZmYuIEludGVuZGVkIHRvIGVuYWJsZSBSZWFjdCBjb3JlIG1lbWJlcnMgdG8gbW9yZSBlYXNpbHkgZGVidWcgc2NoZWR1bGluZ1xuLy8gaXNzdWVzIGluIERFViBidWlsZHMuXG5cbnZhciBlbmFibGVEZWJ1Z1RyYWNpbmcgPSBmYWxzZTsgLy8gVHJhY2sgd2hpY2ggRmliZXIocykgc2NoZWR1bGUgcmVuZGVyIHdvcmsuXG5cbi8vIEFUVEVOVElPTlxuXG52YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKTtcbnZhciBSRUFDVF9QT1JUQUxfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5wb3J0YWwnKTtcbnZhciBSRUFDVF9GUkFHTUVOVF9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmZyYWdtZW50Jyk7XG52YXIgUkVBQ1RfU1RSSUNUX01PREVfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5zdHJpY3RfbW9kZScpO1xudmFyIFJFQUNUX1BST0ZJTEVSX1RZUEUgPSAgU3ltYm9sLmZvcigncmVhY3QucHJvZmlsZXInKTtcbnZhciBSRUFDVF9QUk9WSURFUl9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LnByb3ZpZGVyJyk7XG52YXIgUkVBQ1RfQ09OVEVYVF9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmNvbnRleHQnKTtcbnZhciBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmZvcndhcmRfcmVmJyk7XG52YXIgUkVBQ1RfU1VTUEVOU0VfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZScpO1xudmFyIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZV9saXN0Jyk7XG52YXIgUkVBQ1RfTUVNT19UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0Lm1lbW8nKTtcbnZhciBSRUFDVF9MQVpZX1RZUEUgPSAgU3ltYm9sLmZvcigncmVhY3QubGF6eScpO1xudmFyIFJFQUNUX09GRlNDUkVFTl9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0Lm9mZnNjcmVlbicpO1xudmFyIE1BWUJFX0lURVJBVE9SX1NZTUJPTCA9ICBTeW1ib2wuaXRlcmF0b3I7XG52YXIgRkFVWF9JVEVSQVRPUl9TWU1CT0wgPSAnQEBpdGVyYXRvcic7XG5mdW5jdGlvbiBnZXRJdGVyYXRvckZuKG1heWJlSXRlcmFibGUpIHtcbiAgaWYgKG1heWJlSXRlcmFibGUgPT09IG51bGwgfHwgdHlwZW9mIG1heWJlSXRlcmFibGUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbWF5YmVJdGVyYXRvciA9IE1BWUJFX0lURVJBVE9SX1NZTUJPTCAmJiBtYXliZUl0ZXJhYmxlW01BWUJFX0lURVJBVE9SX1NZTUJPTF0gfHwgbWF5YmVJdGVyYWJsZVtGQVVYX0lURVJBVE9SX1NZTUJPTF07XG5cbiAgaWYgKHR5cGVvZiBtYXliZUl0ZXJhdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIG1heWJlSXRlcmF0b3I7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBkaXNwYXRjaGVyLlxuICovXG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciA9IHtcbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKiBAdHlwZSB7UmVhY3RDb21wb25lbnR9XG4gICAqL1xuICBjdXJyZW50OiBudWxsXG59O1xuXG4vKipcbiAqIEtlZXBzIHRyYWNrIG9mIHRoZSBjdXJyZW50IGJhdGNoJ3MgY29uZmlndXJhdGlvbiBzdWNoIGFzIGhvdyBsb25nIGFuIHVwZGF0ZVxuICogc2hvdWxkIHN1c3BlbmQgZm9yIGlmIGl0IG5lZWRzIHRvLlxuICovXG52YXIgUmVhY3RDdXJyZW50QmF0Y2hDb25maWcgPSB7XG4gIHRyYW5zaXRpb246IG51bGxcbn07XG5cbnZhciBSZWFjdEN1cnJlbnRBY3RRdWV1ZSA9IHtcbiAgY3VycmVudDogbnVsbCxcbiAgLy8gVXNlZCB0byByZXByb2R1Y2UgYmVoYXZpb3Igb2YgYGJhdGNoZWRVcGRhdGVzYCBpbiBsZWdhY3kgbW9kZS5cbiAgaXNCYXRjaGluZ0xlZ2FjeTogZmFsc2UsXG4gIGRpZFNjaGVkdWxlTGVnYWN5VXBkYXRlOiBmYWxzZVxufTtcblxuLyoqXG4gKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBvd25lci5cbiAqXG4gKiBUaGUgY3VycmVudCBvd25lciBpcyB0aGUgY29tcG9uZW50IHdobyBzaG91bGQgb3duIGFueSBjb21wb25lbnRzIHRoYXQgYXJlXG4gKiBjdXJyZW50bHkgYmVpbmcgY29uc3RydWN0ZWQuXG4gKi9cbnZhciBSZWFjdEN1cnJlbnRPd25lciA9IHtcbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKiBAdHlwZSB7UmVhY3RDb21wb25lbnR9XG4gICAqL1xuICBjdXJyZW50OiBudWxsXG59O1xuXG52YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IHt9O1xudmFyIGN1cnJlbnRFeHRyYVN0YWNrRnJhbWUgPSBudWxsO1xuZnVuY3Rpb24gc2V0RXh0cmFTdGFja0ZyYW1lKHN0YWNrKSB7XG4gIHtcbiAgICBjdXJyZW50RXh0cmFTdGFja0ZyYW1lID0gc3RhY2s7XG4gIH1cbn1cblxue1xuICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLnNldEV4dHJhU3RhY2tGcmFtZSA9IGZ1bmN0aW9uIChzdGFjaykge1xuICAgIHtcbiAgICAgIGN1cnJlbnRFeHRyYVN0YWNrRnJhbWUgPSBzdGFjaztcbiAgICB9XG4gIH07IC8vIFN0YWNrIGltcGxlbWVudGF0aW9uIGluamVjdGVkIGJ5IHRoZSBjdXJyZW50IHJlbmRlcmVyLlxuXG5cbiAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRDdXJyZW50U3RhY2sgPSBudWxsO1xuXG4gIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0U3RhY2tBZGRlbmR1bSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhY2sgPSAnJzsgLy8gQWRkIGFuIGV4dHJhIHRvcCBmcmFtZSB3aGlsZSBhbiBlbGVtZW50IGlzIGJlaW5nIHZhbGlkYXRlZFxuXG4gICAgaWYgKGN1cnJlbnRFeHRyYVN0YWNrRnJhbWUpIHtcbiAgICAgIHN0YWNrICs9IGN1cnJlbnRFeHRyYVN0YWNrRnJhbWU7XG4gICAgfSAvLyBEZWxlZ2F0ZSB0byB0aGUgaW5qZWN0ZWQgcmVuZGVyZXItc3BlY2lmaWMgaW1wbGVtZW50YXRpb25cblxuXG4gICAgdmFyIGltcGwgPSBSZWFjdERlYnVnQ3VycmVudEZyYW1lLmdldEN1cnJlbnRTdGFjaztcblxuICAgIGlmIChpbXBsKSB7XG4gICAgICBzdGFjayArPSBpbXBsKCkgfHwgJyc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YWNrO1xuICB9O1xufVxuXG52YXIgUmVhY3RTaGFyZWRJbnRlcm5hbHMgPSB7XG4gIFJlYWN0Q3VycmVudERpc3BhdGNoZXI6IFJlYWN0Q3VycmVudERpc3BhdGNoZXIsXG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnOiBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyxcbiAgUmVhY3RDdXJyZW50T3duZXI6IFJlYWN0Q3VycmVudE93bmVyXG59O1xuXG57XG4gIFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSBSZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuICBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZSA9IFJlYWN0Q3VycmVudEFjdFF1ZXVlO1xufVxuXG4vLyBieSBjYWxscyB0byB0aGVzZSBtZXRob2RzIGJ5IGEgQmFiZWwgcGx1Z2luLlxuLy9cbi8vIEluIFBST0QgKG9yIGluIHBhY2thZ2VzIHdpdGhvdXQgYWNjZXNzIHRvIFJlYWN0IGludGVybmFscyksXG4vLyB0aGV5IGFyZSBsZWZ0IGFzIHRoZXkgYXJlIGluc3RlYWQuXG5cbmZ1bmN0aW9uIHdhcm4oZm9ybWF0KSB7XG4gIHtcbiAgICB7XG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgIGFyZ3NbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgfVxuXG4gICAgICBwcmludFdhcm5pbmcoJ3dhcm4nLCBmb3JtYXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZXJyb3IoZm9ybWF0KSB7XG4gIHtcbiAgICB7XG4gICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIgPiAxID8gX2xlbjIgLSAxIDogMCksIF9rZXkyID0gMTsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICBhcmdzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgfVxuXG4gICAgICBwcmludFdhcm5pbmcoJ2Vycm9yJywgZm9ybWF0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJpbnRXYXJuaW5nKGxldmVsLCBmb3JtYXQsIGFyZ3MpIHtcbiAgLy8gV2hlbiBjaGFuZ2luZyB0aGlzIGxvZ2ljLCB5b3UgbWlnaHQgd2FudCB0byBhbHNvXG4gIC8vIHVwZGF0ZSBjb25zb2xlV2l0aFN0YWNrRGV2Lnd3dy5qcyBhcyB3ZWxsLlxuICB7XG4gICAgdmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuICAgIHZhciBzdGFjayA9IFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0U3RhY2tBZGRlbmR1bSgpO1xuXG4gICAgaWYgKHN0YWNrICE9PSAnJykge1xuICAgICAgZm9ybWF0ICs9ICclcyc7XG4gICAgICBhcmdzID0gYXJncy5jb25jYXQoW3N0YWNrXSk7XG4gICAgfSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb25cblxuXG4gICAgdmFyIGFyZ3NXaXRoRm9ybWF0ID0gYXJncy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBTdHJpbmcoaXRlbSk7XG4gICAgfSk7IC8vIENhcmVmdWw6IFJOIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJlZml4XG5cbiAgICBhcmdzV2l0aEZvcm1hdC51bnNoaWZ0KCdXYXJuaW5nOiAnICsgZm9ybWF0KTsgLy8gV2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2Ugc3ByZWFkIChvciAuYXBwbHkpIGRpcmVjdGx5IGJlY2F1c2UgaXRcbiAgICAvLyBicmVha3MgSUU5OiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEzNjEwXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuXG4gICAgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZVtsZXZlbF0sIGNvbnNvbGUsIGFyZ3NXaXRoRm9ybWF0KTtcbiAgfVxufVxuXG52YXIgZGlkV2FyblN0YXRlVXBkYXRlRm9yVW5tb3VudGVkQ29tcG9uZW50ID0ge307XG5cbmZ1bmN0aW9uIHdhcm5Ob29wKHB1YmxpY0luc3RhbmNlLCBjYWxsZXJOYW1lKSB7XG4gIHtcbiAgICB2YXIgX2NvbnN0cnVjdG9yID0gcHVibGljSW5zdGFuY2UuY29uc3RydWN0b3I7XG4gICAgdmFyIGNvbXBvbmVudE5hbWUgPSBfY29uc3RydWN0b3IgJiYgKF9jb25zdHJ1Y3Rvci5kaXNwbGF5TmFtZSB8fCBfY29uc3RydWN0b3IubmFtZSkgfHwgJ1JlYWN0Q2xhc3MnO1xuICAgIHZhciB3YXJuaW5nS2V5ID0gY29tcG9uZW50TmFtZSArIFwiLlwiICsgY2FsbGVyTmFtZTtcblxuICAgIGlmIChkaWRXYXJuU3RhdGVVcGRhdGVGb3JVbm1vdW50ZWRDb21wb25lbnRbd2FybmluZ0tleV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBlcnJvcihcIkNhbid0IGNhbGwgJXMgb24gYSBjb21wb25lbnQgdGhhdCBpcyBub3QgeWV0IG1vdW50ZWQuIFwiICsgJ1RoaXMgaXMgYSBuby1vcCwgYnV0IGl0IG1pZ2h0IGluZGljYXRlIGEgYnVnIGluIHlvdXIgYXBwbGljYXRpb24uICcgKyAnSW5zdGVhZCwgYXNzaWduIHRvIGB0aGlzLnN0YXRlYCBkaXJlY3RseSBvciBkZWZpbmUgYSBgc3RhdGUgPSB7fTtgICcgKyAnY2xhc3MgcHJvcGVydHkgd2l0aCB0aGUgZGVzaXJlZCBzdGF0ZSBpbiB0aGUgJXMgY29tcG9uZW50LicsIGNhbGxlck5hbWUsIGNvbXBvbmVudE5hbWUpO1xuXG4gICAgZGlkV2FyblN0YXRlVXBkYXRlRm9yVW5tb3VudGVkQ29tcG9uZW50W3dhcm5pbmdLZXldID0gdHJ1ZTtcbiAgfVxufVxuLyoqXG4gKiBUaGlzIGlzIHRoZSBhYnN0cmFjdCBBUEkgZm9yIGFuIHVwZGF0ZSBxdWV1ZS5cbiAqL1xuXG5cbnZhciBSZWFjdE5vb3BVcGRhdGVRdWV1ZSA9IHtcbiAgLyoqXG4gICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGlzIGNvbXBvc2l0ZSBjb21wb25lbnQgaXMgbW91bnRlZC5cbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2Ugd2Ugd2FudCB0byB0ZXN0LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG1vdW50ZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAZmluYWxcbiAgICovXG4gIGlzTW91bnRlZDogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBGb3JjZXMgYW4gdXBkYXRlLiBUaGlzIHNob3VsZCBvbmx5IGJlIGludm9rZWQgd2hlbiBpdCBpcyBrbm93biB3aXRoXG4gICAqIGNlcnRhaW50eSB0aGF0IHdlIGFyZSAqKm5vdCoqIGluIGEgRE9NIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBZb3UgbWF5IHdhbnQgdG8gY2FsbCB0aGlzIHdoZW4geW91IGtub3cgdGhhdCBzb21lIGRlZXBlciBhc3BlY3Qgb2YgdGhlXG4gICAqIGNvbXBvbmVudCdzIHN0YXRlIGhhcyBjaGFuZ2VkIGJ1dCBgc2V0U3RhdGVgIHdhcyBub3QgY2FsbGVkLlxuICAgKlxuICAgKiBUaGlzIHdpbGwgbm90IGludm9rZSBgc2hvdWxkQ29tcG9uZW50VXBkYXRlYCwgYnV0IGl0IHdpbGwgaW52b2tlXG4gICAqIGBjb21wb25lbnRXaWxsVXBkYXRlYCBhbmQgYGNvbXBvbmVudERpZFVwZGF0ZWAuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIGNvbXBvbmVudCBpcyB1cGRhdGVkLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNhbGxlck5hbWUgbmFtZSBvZiB0aGUgY2FsbGluZyBmdW5jdGlvbiBpbiB0aGUgcHVibGljIEFQSS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlRm9yY2VVcGRhdGU6IGZ1bmN0aW9uIChwdWJsaWNJbnN0YW5jZSwgY2FsbGJhY2ssIGNhbGxlck5hbWUpIHtcbiAgICB3YXJuTm9vcChwdWJsaWNJbnN0YW5jZSwgJ2ZvcmNlVXBkYXRlJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBvZiB0aGUgc3RhdGUuIEFsd2F5cyB1c2UgdGhpcyBvciBgc2V0U3RhdGVgIHRvIG11dGF0ZSBzdGF0ZS5cbiAgICogWW91IHNob3VsZCB0cmVhdCBgdGhpcy5zdGF0ZWAgYXMgaW1tdXRhYmxlLlxuICAgKlxuICAgKiBUaGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCBgdGhpcy5zdGF0ZWAgd2lsbCBiZSBpbW1lZGlhdGVseSB1cGRhdGVkLCBzb1xuICAgKiBhY2Nlc3NpbmcgYHRoaXMuc3RhdGVgIGFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2QgbWF5IHJldHVybiB0aGUgb2xkIHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0ge1JlYWN0Q2xhc3N9IHB1YmxpY0luc3RhbmNlIFRoZSBpbnN0YW5jZSB0aGF0IHNob3VsZCByZXJlbmRlci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbXBsZXRlU3RhdGUgTmV4dCBzdGF0ZS5cbiAgICogQHBhcmFtIHs/ZnVuY3Rpb259IGNhbGxiYWNrIENhbGxlZCBhZnRlciBjb21wb25lbnQgaXMgdXBkYXRlZC5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBjYWxsZXJOYW1lIG5hbWUgb2YgdGhlIGNhbGxpbmcgZnVuY3Rpb24gaW4gdGhlIHB1YmxpYyBBUEkuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZVJlcGxhY2VTdGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBjb21wbGV0ZVN0YXRlLCBjYWxsYmFjaywgY2FsbGVyTmFtZSkge1xuICAgIHdhcm5Ob29wKHB1YmxpY0luc3RhbmNlLCAncmVwbGFjZVN0YXRlJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFNldHMgYSBzdWJzZXQgb2YgdGhlIHN0YXRlLiBUaGlzIG9ubHkgZXhpc3RzIGJlY2F1c2UgX3BlbmRpbmdTdGF0ZSBpc1xuICAgKiBpbnRlcm5hbC4gVGhpcyBwcm92aWRlcyBhIG1lcmdpbmcgc3RyYXRlZ3kgdGhhdCBpcyBub3QgYXZhaWxhYmxlIHRvIGRlZXBcbiAgICogcHJvcGVydGllcyB3aGljaCBpcyBjb25mdXNpbmcuIFRPRE86IEV4cG9zZSBwZW5kaW5nU3RhdGUgb3IgZG9uJ3QgdXNlIGl0XG4gICAqIGR1cmluZyB0aGUgbWVyZ2UuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGFydGlhbFN0YXRlIE5leHQgcGFydGlhbCBzdGF0ZSB0byBiZSBtZXJnZWQgd2l0aCBzdGF0ZS5cbiAgICogQHBhcmFtIHs/ZnVuY3Rpb259IGNhbGxiYWNrIENhbGxlZCBhZnRlciBjb21wb25lbnQgaXMgdXBkYXRlZC5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBOYW1lIG9mIHRoZSBjYWxsaW5nIGZ1bmN0aW9uIGluIHRoZSBwdWJsaWMgQVBJLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVTZXRTdGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBwYXJ0aWFsU3RhdGUsIGNhbGxiYWNrLCBjYWxsZXJOYW1lKSB7XG4gICAgd2Fybk5vb3AocHVibGljSW5zdGFuY2UsICdzZXRTdGF0ZScpO1xuICB9XG59O1xuXG52YXIgYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxudmFyIGVtcHR5T2JqZWN0ID0ge307XG5cbntcbiAgT2JqZWN0LmZyZWV6ZShlbXB0eU9iamVjdCk7XG59XG4vKipcbiAqIEJhc2UgY2xhc3MgaGVscGVycyBmb3IgdGhlIHVwZGF0aW5nIHN0YXRlIG9mIGEgY29tcG9uZW50LlxuICovXG5cblxuZnVuY3Rpb24gQ29tcG9uZW50KHByb3BzLCBjb250ZXh0LCB1cGRhdGVyKSB7XG4gIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsgLy8gSWYgYSBjb21wb25lbnQgaGFzIHN0cmluZyByZWZzLCB3ZSB3aWxsIGFzc2lnbiBhIGRpZmZlcmVudCBvYmplY3QgbGF0ZXIuXG5cbiAgdGhpcy5yZWZzID0gZW1wdHlPYmplY3Q7IC8vIFdlIGluaXRpYWxpemUgdGhlIGRlZmF1bHQgdXBkYXRlciBidXQgdGhlIHJlYWwgb25lIGdldHMgaW5qZWN0ZWQgYnkgdGhlXG4gIC8vIHJlbmRlcmVyLlxuXG4gIHRoaXMudXBkYXRlciA9IHVwZGF0ZXIgfHwgUmVhY3ROb29wVXBkYXRlUXVldWU7XG59XG5cbkNvbXBvbmVudC5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudCA9IHt9O1xuLyoqXG4gKiBTZXRzIGEgc3Vic2V0IG9mIHRoZSBzdGF0ZS4gQWx3YXlzIHVzZSB0aGlzIHRvIG11dGF0ZVxuICogc3RhdGUuIFlvdSBzaG91bGQgdHJlYXQgYHRoaXMuc3RhdGVgIGFzIGltbXV0YWJsZS5cbiAqXG4gKiBUaGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCBgdGhpcy5zdGF0ZWAgd2lsbCBiZSBpbW1lZGlhdGVseSB1cGRhdGVkLCBzb1xuICogYWNjZXNzaW5nIGB0aGlzLnN0YXRlYCBhZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kIG1heSByZXR1cm4gdGhlIG9sZCB2YWx1ZS5cbiAqXG4gKiBUaGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCBjYWxscyB0byBgc2V0U3RhdGVgIHdpbGwgcnVuIHN5bmNocm9ub3VzbHksXG4gKiBhcyB0aGV5IG1heSBldmVudHVhbGx5IGJlIGJhdGNoZWQgdG9nZXRoZXIuICBZb3UgY2FuIHByb3ZpZGUgYW4gb3B0aW9uYWxcbiAqIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBleGVjdXRlZCB3aGVuIHRoZSBjYWxsIHRvIHNldFN0YXRlIGlzIGFjdHVhbGx5XG4gKiBjb21wbGV0ZWQuXG4gKlxuICogV2hlbiBhIGZ1bmN0aW9uIGlzIHByb3ZpZGVkIHRvIHNldFN0YXRlLCBpdCB3aWxsIGJlIGNhbGxlZCBhdCBzb21lIHBvaW50IGluXG4gKiB0aGUgZnV0dXJlIChub3Qgc3luY2hyb25vdXNseSkuIEl0IHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIHVwIHRvIGRhdGVcbiAqIGNvbXBvbmVudCBhcmd1bWVudHMgKHN0YXRlLCBwcm9wcywgY29udGV4dCkuIFRoZXNlIHZhbHVlcyBjYW4gYmUgZGlmZmVyZW50XG4gKiBmcm9tIHRoaXMuKiBiZWNhdXNlIHlvdXIgZnVuY3Rpb24gbWF5IGJlIGNhbGxlZCBhZnRlciByZWNlaXZlUHJvcHMgYnV0IGJlZm9yZVxuICogc2hvdWxkQ29tcG9uZW50VXBkYXRlLCBhbmQgdGhpcyBuZXcgc3RhdGUsIHByb3BzLCBhbmQgY29udGV4dCB3aWxsIG5vdCB5ZXQgYmVcbiAqIGFzc2lnbmVkIHRvIHRoaXMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R8ZnVuY3Rpb259IHBhcnRpYWxTdGF0ZSBOZXh0IHBhcnRpYWwgc3RhdGUgb3IgZnVuY3Rpb24gdG9cbiAqICAgICAgICBwcm9kdWNlIG5leHQgcGFydGlhbCBzdGF0ZSB0byBiZSBtZXJnZWQgd2l0aCBjdXJyZW50IHN0YXRlLlxuICogQHBhcmFtIHs/ZnVuY3Rpb259IGNhbGxiYWNrIENhbGxlZCBhZnRlciBzdGF0ZSBpcyB1cGRhdGVkLlxuICogQGZpbmFsXG4gKiBAcHJvdGVjdGVkXG4gKi9cblxuQ29tcG9uZW50LnByb3RvdHlwZS5zZXRTdGF0ZSA9IGZ1bmN0aW9uIChwYXJ0aWFsU3RhdGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgcGFydGlhbFN0YXRlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgcGFydGlhbFN0YXRlICE9PSAnZnVuY3Rpb24nICYmIHBhcnRpYWxTdGF0ZSAhPSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRTdGF0ZSguLi4pOiB0YWtlcyBhbiBvYmplY3Qgb2Ygc3RhdGUgdmFyaWFibGVzIHRvIHVwZGF0ZSBvciBhICcgKyAnZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhbiBvYmplY3Qgb2Ygc3RhdGUgdmFyaWFibGVzLicpO1xuICB9XG5cbiAgdGhpcy51cGRhdGVyLmVucXVldWVTZXRTdGF0ZSh0aGlzLCBwYXJ0aWFsU3RhdGUsIGNhbGxiYWNrLCAnc2V0U3RhdGUnKTtcbn07XG4vKipcbiAqIEZvcmNlcyBhbiB1cGRhdGUuIFRoaXMgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCB3aGVuIGl0IGlzIGtub3duIHdpdGhcbiAqIGNlcnRhaW50eSB0aGF0IHdlIGFyZSAqKm5vdCoqIGluIGEgRE9NIHRyYW5zYWN0aW9uLlxuICpcbiAqIFlvdSBtYXkgd2FudCB0byBjYWxsIHRoaXMgd2hlbiB5b3Uga25vdyB0aGF0IHNvbWUgZGVlcGVyIGFzcGVjdCBvZiB0aGVcbiAqIGNvbXBvbmVudCdzIHN0YXRlIGhhcyBjaGFuZ2VkIGJ1dCBgc2V0U3RhdGVgIHdhcyBub3QgY2FsbGVkLlxuICpcbiAqIFRoaXMgd2lsbCBub3QgaW52b2tlIGBzaG91bGRDb21wb25lbnRVcGRhdGVgLCBidXQgaXQgd2lsbCBpbnZva2VcbiAqIGBjb21wb25lbnRXaWxsVXBkYXRlYCBhbmQgYGNvbXBvbmVudERpZFVwZGF0ZWAuXG4gKlxuICogQHBhcmFtIHs/ZnVuY3Rpb259IGNhbGxiYWNrIENhbGxlZCBhZnRlciB1cGRhdGUgaXMgY29tcGxldGUuXG4gKiBAZmluYWxcbiAqIEBwcm90ZWN0ZWRcbiAqL1xuXG5cbkNvbXBvbmVudC5wcm90b3R5cGUuZm9yY2VVcGRhdGUgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgdGhpcy51cGRhdGVyLmVucXVldWVGb3JjZVVwZGF0ZSh0aGlzLCBjYWxsYmFjaywgJ2ZvcmNlVXBkYXRlJyk7XG59O1xuLyoqXG4gKiBEZXByZWNhdGVkIEFQSXMuIFRoZXNlIEFQSXMgdXNlZCB0byBleGlzdCBvbiBjbGFzc2ljIFJlYWN0IGNsYXNzZXMgYnV0IHNpbmNlXG4gKiB3ZSB3b3VsZCBsaWtlIHRvIGRlcHJlY2F0ZSB0aGVtLCB3ZSdyZSBub3QgZ29pbmcgdG8gbW92ZSB0aGVtIG92ZXIgdG8gdGhpc1xuICogbW9kZXJuIGJhc2UgY2xhc3MuIEluc3RlYWQsIHdlIGRlZmluZSBhIGdldHRlciB0aGF0IHdhcm5zIGlmIGl0J3MgYWNjZXNzZWQuXG4gKi9cblxuXG57XG4gIHZhciBkZXByZWNhdGVkQVBJcyA9IHtcbiAgICBpc01vdW50ZWQ6IFsnaXNNb3VudGVkJywgJ0luc3RlYWQsIG1ha2Ugc3VyZSB0byBjbGVhbiB1cCBzdWJzY3JpcHRpb25zIGFuZCBwZW5kaW5nIHJlcXVlc3RzIGluICcgKyAnY29tcG9uZW50V2lsbFVubW91bnQgdG8gcHJldmVudCBtZW1vcnkgbGVha3MuJ10sXG4gICAgcmVwbGFjZVN0YXRlOiBbJ3JlcGxhY2VTdGF0ZScsICdSZWZhY3RvciB5b3VyIGNvZGUgdG8gdXNlIHNldFN0YXRlIGluc3RlYWQgKHNlZSAnICsgJ2h0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMzIzNikuJ11cbiAgfTtcblxuICB2YXIgZGVmaW5lRGVwcmVjYXRpb25XYXJuaW5nID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUsIGluZm8pIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29tcG9uZW50LnByb3RvdHlwZSwgbWV0aG9kTmFtZSwge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhcm4oJyVzKC4uLikgaXMgZGVwcmVjYXRlZCBpbiBwbGFpbiBKYXZhU2NyaXB0IFJlYWN0IGNsYXNzZXMuICVzJywgaW5mb1swXSwgaW5mb1sxXSk7XG5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBmb3IgKHZhciBmbk5hbWUgaW4gZGVwcmVjYXRlZEFQSXMpIHtcbiAgICBpZiAoZGVwcmVjYXRlZEFQSXMuaGFzT3duUHJvcGVydHkoZm5OYW1lKSkge1xuICAgICAgZGVmaW5lRGVwcmVjYXRpb25XYXJuaW5nKGZuTmFtZSwgZGVwcmVjYXRlZEFQSXNbZm5OYW1lXSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIENvbXBvbmVudER1bW15KCkge31cblxuQ29tcG9uZW50RHVtbXkucHJvdG90eXBlID0gQ29tcG9uZW50LnByb3RvdHlwZTtcbi8qKlxuICogQ29udmVuaWVuY2UgY29tcG9uZW50IHdpdGggZGVmYXVsdCBzaGFsbG93IGVxdWFsaXR5IGNoZWNrIGZvciBzQ1UuXG4gKi9cblxuZnVuY3Rpb24gUHVyZUNvbXBvbmVudChwcm9wcywgY29udGV4dCwgdXBkYXRlcikge1xuICB0aGlzLnByb3BzID0gcHJvcHM7XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7IC8vIElmIGEgY29tcG9uZW50IGhhcyBzdHJpbmcgcmVmcywgd2Ugd2lsbCBhc3NpZ24gYSBkaWZmZXJlbnQgb2JqZWN0IGxhdGVyLlxuXG4gIHRoaXMucmVmcyA9IGVtcHR5T2JqZWN0O1xuICB0aGlzLnVwZGF0ZXIgPSB1cGRhdGVyIHx8IFJlYWN0Tm9vcFVwZGF0ZVF1ZXVlO1xufVxuXG52YXIgcHVyZUNvbXBvbmVudFByb3RvdHlwZSA9IFB1cmVDb21wb25lbnQucHJvdG90eXBlID0gbmV3IENvbXBvbmVudER1bW15KCk7XG5wdXJlQ29tcG9uZW50UHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUHVyZUNvbXBvbmVudDsgLy8gQXZvaWQgYW4gZXh0cmEgcHJvdG90eXBlIGp1bXAgZm9yIHRoZXNlIG1ldGhvZHMuXG5cbmFzc2lnbihwdXJlQ29tcG9uZW50UHJvdG90eXBlLCBDb21wb25lbnQucHJvdG90eXBlKTtcbnB1cmVDb21wb25lbnRQcm90b3R5cGUuaXNQdXJlUmVhY3RDb21wb25lbnQgPSB0cnVlO1xuXG4vLyBhbiBpbW11dGFibGUgb2JqZWN0IHdpdGggYSBzaW5nbGUgbXV0YWJsZSB2YWx1ZVxuZnVuY3Rpb24gY3JlYXRlUmVmKCkge1xuICB2YXIgcmVmT2JqZWN0ID0ge1xuICAgIGN1cnJlbnQ6IG51bGxcbiAgfTtcblxuICB7XG4gICAgT2JqZWN0LnNlYWwocmVmT2JqZWN0KTtcbiAgfVxuXG4gIHJldHVybiByZWZPYmplY3Q7XG59XG5cbnZhciBpc0FycmF5SW1wbCA9IEFycmF5LmlzQXJyYXk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZWRlY2xhcmVcblxuZnVuY3Rpb24gaXNBcnJheShhKSB7XG4gIHJldHVybiBpc0FycmF5SW1wbChhKTtcbn1cblxuLypcbiAqIFRoZSBgJycgKyB2YWx1ZWAgcGF0dGVybiAodXNlZCBpbiBpbiBwZXJmLXNlbnNpdGl2ZSBjb2RlKSB0aHJvd3MgZm9yIFN5bWJvbFxuICogYW5kIFRlbXBvcmFsLiogdHlwZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8yMjA2NC5cbiAqXG4gKiBUaGUgZnVuY3Rpb25zIGluIHRoaXMgbW9kdWxlIHdpbGwgdGhyb3cgYW4gZWFzaWVyLXRvLXVuZGVyc3RhbmQsXG4gKiBlYXNpZXItdG8tZGVidWcgZXhjZXB0aW9uIHdpdGggYSBjbGVhciBlcnJvcnMgbWVzc2FnZSBtZXNzYWdlIGV4cGxhaW5pbmcgdGhlXG4gKiBwcm9ibGVtLiAoSW5zdGVhZCBvZiBhIGNvbmZ1c2luZyBleGNlcHRpb24gdGhyb3duIGluc2lkZSB0aGUgaW1wbGVtZW50YXRpb25cbiAqIG9mIHRoZSBgdmFsdWVgIG9iamVjdCkuXG4gKi9cbi8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5mdW5jdGlvbiB0eXBlTmFtZSh2YWx1ZSkge1xuICB7XG4gICAgLy8gdG9TdHJpbmdUYWcgaXMgbmVlZGVkIGZvciBuYW1lc3BhY2VkIHR5cGVzIGxpa2UgVGVtcG9yYWwuSW5zdGFudFxuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLnRvU3RyaW5nVGFnO1xuICAgIHZhciB0eXBlID0gaGFzVG9TdHJpbmdUYWcgJiYgdmFsdWVbU3ltYm9sLnRvU3RyaW5nVGFnXSB8fCB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdPYmplY3QnO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG59IC8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5cblxuZnVuY3Rpb24gd2lsbENvZXJjaW9uVGhyb3codmFsdWUpIHtcbiAge1xuICAgIHRyeSB7XG4gICAgICB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAgLy8gSWYgeW91IGVuZGVkIHVwIGhlcmUgYnkgZm9sbG93aW5nIGFuIGV4Y2VwdGlvbiBjYWxsIHN0YWNrLCBoZXJlJ3Mgd2hhdCdzXG4gIC8vIGhhcHBlbmVkOiB5b3Ugc3VwcGxpZWQgYW4gb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBSZWFjdCAoYXMgYSBwcm9wLCBrZXksXG4gIC8vIERPTSBhdHRyaWJ1dGUsIENTUyBwcm9wZXJ0eSwgc3RyaW5nIHJlZiwgZXRjLikgYW5kIHdoZW4gUmVhY3QgdHJpZWQgdG9cbiAgLy8gY29lcmNlIGl0IHRvIGEgc3RyaW5nIHVzaW5nIGAnJyArIHZhbHVlYCwgYW4gZXhjZXB0aW9uIHdhcyB0aHJvd24uXG4gIC8vXG4gIC8vIFRoZSBtb3N0IGNvbW1vbiB0eXBlcyB0aGF0IHdpbGwgY2F1c2UgdGhpcyBleGNlcHRpb24gYXJlIGBTeW1ib2xgIGluc3RhbmNlc1xuICAvLyBhbmQgVGVtcG9yYWwgb2JqZWN0cyBsaWtlIGBUZW1wb3JhbC5JbnN0YW50YC4gQnV0IGFueSBvYmplY3QgdGhhdCBoYXMgYVxuICAvLyBgdmFsdWVPZmAgb3IgYFtTeW1ib2wudG9QcmltaXRpdmVdYCBtZXRob2QgdGhhdCB0aHJvd3Mgd2lsbCBhbHNvIGNhdXNlIHRoaXNcbiAgLy8gZXhjZXB0aW9uLiAoTGlicmFyeSBhdXRob3JzIGRvIHRoaXMgdG8gcHJldmVudCB1c2VycyBmcm9tIHVzaW5nIGJ1aWx0LWluXG4gIC8vIG51bWVyaWMgb3BlcmF0b3JzIGxpa2UgYCtgIG9yIGNvbXBhcmlzb24gb3BlcmF0b3JzIGxpa2UgYD49YCBiZWNhdXNlIGN1c3RvbVxuICAvLyBtZXRob2RzIGFyZSBuZWVkZWQgdG8gcGVyZm9ybSBhY2N1cmF0ZSBhcml0aG1ldGljIG9yIGNvbXBhcmlzb24uKVxuICAvL1xuICAvLyBUbyBmaXggdGhlIHByb2JsZW0sIGNvZXJjZSB0aGlzIG9iamVjdCBvciBzeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcgYmVmb3JlXG4gIC8vIHBhc3NpbmcgaXQgdG8gUmVhY3QuIFRoZSBtb3N0IHJlbGlhYmxlIHdheSBpcyB1c3VhbGx5IGBTdHJpbmcodmFsdWUpYC5cbiAgLy9cbiAgLy8gVG8gZmluZCB3aGljaCB2YWx1ZSBpcyB0aHJvd2luZywgY2hlY2sgdGhlIGJyb3dzZXIgb3IgZGVidWdnZXIgY29uc29sZS5cbiAgLy8gQmVmb3JlIHRoaXMgZXhjZXB0aW9uIHdhcyB0aHJvd24sIHRoZXJlIHNob3VsZCBiZSBgY29uc29sZS5lcnJvcmAgb3V0cHV0XG4gIC8vIHRoYXQgc2hvd3MgdGhlIHR5cGUgKFN5bWJvbCwgVGVtcG9yYWwuUGxhaW5EYXRlLCBldGMuKSB0aGF0IGNhdXNlZCB0aGVcbiAgLy8gcHJvYmxlbSBhbmQgaG93IHRoYXQgdHlwZSB3YXMgdXNlZDoga2V5LCBhdHJyaWJ1dGUsIGlucHV0IHZhbHVlIHByb3AsIGV0Yy5cbiAgLy8gSW4gbW9zdCBjYXNlcywgdGhpcyBjb25zb2xlIG91dHB1dCBhbHNvIHNob3dzIHRoZSBjb21wb25lbnQgYW5kIGl0c1xuICAvLyBhbmNlc3RvciBjb21wb25lbnRzIHdoZXJlIHRoZSBleGNlcHRpb24gaGFwcGVuZWQuXG4gIC8vXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICByZXR1cm4gJycgKyB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQga2V5IGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRXcmFwcGVkTmFtZShvdXRlclR5cGUsIGlubmVyVHlwZSwgd3JhcHBlck5hbWUpIHtcbiAgdmFyIGRpc3BsYXlOYW1lID0gb3V0ZXJUeXBlLmRpc3BsYXlOYW1lO1xuXG4gIGlmIChkaXNwbGF5TmFtZSkge1xuICAgIHJldHVybiBkaXNwbGF5TmFtZTtcbiAgfVxuXG4gIHZhciBmdW5jdGlvbk5hbWUgPSBpbm5lclR5cGUuZGlzcGxheU5hbWUgfHwgaW5uZXJUeXBlLm5hbWUgfHwgJyc7XG4gIHJldHVybiBmdW5jdGlvbk5hbWUgIT09ICcnID8gd3JhcHBlck5hbWUgKyBcIihcIiArIGZ1bmN0aW9uTmFtZSArIFwiKVwiIDogd3JhcHBlck5hbWU7XG59IC8vIEtlZXAgaW4gc3luYyB3aXRoIHJlYWN0LXJlY29uY2lsZXIvZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlclxuXG5cbmZ1bmN0aW9uIGdldENvbnRleHROYW1lKHR5cGUpIHtcbiAgcmV0dXJuIHR5cGUuZGlzcGxheU5hbWUgfHwgJ0NvbnRleHQnO1xufSAvLyBOb3RlIHRoYXQgdGhlIHJlY29uY2lsZXIgcGFja2FnZSBzaG91bGQgZ2VuZXJhbGx5IHByZWZlciB0byB1c2UgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcigpIGluc3RlYWQuXG5cblxuZnVuY3Rpb24gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpIHtcbiAgaWYgKHR5cGUgPT0gbnVsbCkge1xuICAgIC8vIEhvc3Qgcm9vdCwgdGV4dCBub2RlIG9yIGp1c3QgaW52YWxpZCB0eXBlLlxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAge1xuICAgIGlmICh0eXBlb2YgdHlwZS50YWcgPT09ICdudW1iZXInKSB7XG4gICAgICBlcnJvcignUmVjZWl2ZWQgYW4gdW5leHBlY3RlZCBvYmplY3QgaW4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKCkuICcgKyAnVGhpcyBpcyBsaWtlbHkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8IHR5cGUubmFtZSB8fCBudWxsO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBSRUFDVF9GUkFHTUVOVF9UWVBFOlxuICAgICAgcmV0dXJuICdGcmFnbWVudCc7XG5cbiAgICBjYXNlIFJFQUNUX1BPUlRBTF9UWVBFOlxuICAgICAgcmV0dXJuICdQb3J0YWwnO1xuXG4gICAgY2FzZSBSRUFDVF9QUk9GSUxFUl9UWVBFOlxuICAgICAgcmV0dXJuICdQcm9maWxlcic7XG5cbiAgICBjYXNlIFJFQUNUX1NUUklDVF9NT0RFX1RZUEU6XG4gICAgICByZXR1cm4gJ1N0cmljdE1vZGUnO1xuXG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9UWVBFOlxuICAgICAgcmV0dXJuICdTdXNwZW5zZSc7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTpcbiAgICAgIHJldHVybiAnU3VzcGVuc2VMaXN0JztcblxuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0Jykge1xuICAgIHN3aXRjaCAodHlwZS4kJHR5cGVvZikge1xuICAgICAgY2FzZSBSRUFDVF9DT05URVhUX1RZUEU6XG4gICAgICAgIHZhciBjb250ZXh0ID0gdHlwZTtcbiAgICAgICAgcmV0dXJuIGdldENvbnRleHROYW1lKGNvbnRleHQpICsgJy5Db25zdW1lcic7XG5cbiAgICAgIGNhc2UgUkVBQ1RfUFJPVklERVJfVFlQRTpcbiAgICAgICAgdmFyIHByb3ZpZGVyID0gdHlwZTtcbiAgICAgICAgcmV0dXJuIGdldENvbnRleHROYW1lKHByb3ZpZGVyLl9jb250ZXh0KSArICcuUHJvdmlkZXInO1xuXG4gICAgICBjYXNlIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEU6XG4gICAgICAgIHJldHVybiBnZXRXcmFwcGVkTmFtZSh0eXBlLCB0eXBlLnJlbmRlciwgJ0ZvcndhcmRSZWYnKTtcblxuICAgICAgY2FzZSBSRUFDVF9NRU1PX1RZUEU6XG4gICAgICAgIHZhciBvdXRlck5hbWUgPSB0eXBlLmRpc3BsYXlOYW1lIHx8IG51bGw7XG5cbiAgICAgICAgaWYgKG91dGVyTmFtZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBvdXRlck5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUudHlwZSkgfHwgJ01lbW8nO1xuXG4gICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBsYXp5Q29tcG9uZW50ID0gdHlwZTtcbiAgICAgICAgICB2YXIgcGF5bG9hZCA9IGxhenlDb21wb25lbnQuX3BheWxvYWQ7XG4gICAgICAgICAgdmFyIGluaXQgPSBsYXp5Q29tcG9uZW50Ll9pbml0O1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoaW5pdChwYXlsb2FkKSk7XG4gICAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgUkVTRVJWRURfUFJPUFMgPSB7XG4gIGtleTogdHJ1ZSxcbiAgcmVmOiB0cnVlLFxuICBfX3NlbGY6IHRydWUsXG4gIF9fc291cmNlOiB0cnVlXG59O1xudmFyIHNwZWNpYWxQcm9wS2V5V2FybmluZ1Nob3duLCBzcGVjaWFsUHJvcFJlZldhcm5pbmdTaG93biwgZGlkV2FybkFib3V0U3RyaW5nUmVmcztcblxue1xuICBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzID0ge307XG59XG5cbmZ1bmN0aW9uIGhhc1ZhbGlkUmVmKGNvbmZpZykge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCAncmVmJykpIHtcbiAgICAgIHZhciBnZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGNvbmZpZywgJ3JlZicpLmdldDtcblxuICAgICAgaWYgKGdldHRlciAmJiBnZXR0ZXIuaXNSZWFjdFdhcm5pbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25maWcucmVmICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGhhc1ZhbGlkS2V5KGNvbmZpZykge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCAna2V5JykpIHtcbiAgICAgIHZhciBnZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGNvbmZpZywgJ2tleScpLmdldDtcblxuICAgICAgaWYgKGdldHRlciAmJiBnZXR0ZXIuaXNSZWFjdFdhcm5pbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25maWcua2V5ICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGRlZmluZUtleVByb3BXYXJuaW5nR2V0dGVyKHByb3BzLCBkaXNwbGF5TmFtZSkge1xuICB2YXIgd2FybkFib3V0QWNjZXNzaW5nS2V5ID0gZnVuY3Rpb24gKCkge1xuICAgIHtcbiAgICAgIGlmICghc3BlY2lhbFByb3BLZXlXYXJuaW5nU2hvd24pIHtcbiAgICAgICAgc3BlY2lhbFByb3BLZXlXYXJuaW5nU2hvd24gPSB0cnVlO1xuXG4gICAgICAgIGVycm9yKCclczogYGtleWAgaXMgbm90IGEgcHJvcC4gVHJ5aW5nIHRvIGFjY2VzcyBpdCB3aWxsIHJlc3VsdCAnICsgJ2luIGB1bmRlZmluZWRgIGJlaW5nIHJldHVybmVkLiBJZiB5b3UgbmVlZCB0byBhY2Nlc3MgdGhlIHNhbWUgJyArICd2YWx1ZSB3aXRoaW4gdGhlIGNoaWxkIGNvbXBvbmVudCwgeW91IHNob3VsZCBwYXNzIGl0IGFzIGEgZGlmZmVyZW50ICcgKyAncHJvcC4gKGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zcGVjaWFsLXByb3BzKScsIGRpc3BsYXlOYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgd2FybkFib3V0QWNjZXNzaW5nS2V5LmlzUmVhY3RXYXJuaW5nID0gdHJ1ZTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3BzLCAna2V5Jywge1xuICAgIGdldDogd2FybkFib3V0QWNjZXNzaW5nS2V5LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmaW5lUmVmUHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKSB7XG4gIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYgPSBmdW5jdGlvbiAoKSB7XG4gICAge1xuICAgICAgaWYgKCFzcGVjaWFsUHJvcFJlZldhcm5pbmdTaG93bikge1xuICAgICAgICBzcGVjaWFsUHJvcFJlZldhcm5pbmdTaG93biA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJyVzOiBgcmVmYCBpcyBub3QgYSBwcm9wLiBUcnlpbmcgdG8gYWNjZXNzIGl0IHdpbGwgcmVzdWx0ICcgKyAnaW4gYHVuZGVmaW5lZGAgYmVpbmcgcmV0dXJuZWQuIElmIHlvdSBuZWVkIHRvIGFjY2VzcyB0aGUgc2FtZSAnICsgJ3ZhbHVlIHdpdGhpbiB0aGUgY2hpbGQgY29tcG9uZW50LCB5b3Ugc2hvdWxkIHBhc3MgaXQgYXMgYSBkaWZmZXJlbnQgJyArICdwcm9wLiAoaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3NwZWNpYWwtcHJvcHMpJywgZGlzcGxheU5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYuaXNSZWFjdFdhcm5pbmcgPSB0cnVlO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvcHMsICdyZWYnLCB7XG4gICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufVxuXG5mdW5jdGlvbiB3YXJuSWZTdHJpbmdSZWZDYW5ub3RCZUF1dG9Db252ZXJ0ZWQoY29uZmlnKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5yZWYgPT09ICdzdHJpbmcnICYmIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgJiYgY29uZmlnLl9fc2VsZiAmJiBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnN0YXRlTm9kZSAhPT0gY29uZmlnLl9fc2VsZikge1xuICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoUmVhY3RDdXJyZW50T3duZXIuY3VycmVudC50eXBlKTtcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRTdHJpbmdSZWZzW2NvbXBvbmVudE5hbWVdKSB7XG4gICAgICAgIGVycm9yKCdDb21wb25lbnQgXCIlc1wiIGNvbnRhaW5zIHRoZSBzdHJpbmcgcmVmIFwiJXNcIi4gJyArICdTdXBwb3J0IGZvciBzdHJpbmcgcmVmcyB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgbWFqb3IgcmVsZWFzZS4gJyArICdUaGlzIGNhc2UgY2Fubm90IGJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGFuIGFycm93IGZ1bmN0aW9uLiAnICsgJ1dlIGFzayB5b3UgdG8gbWFudWFsbHkgZml4IHRoaXMgY2FzZSBieSB1c2luZyB1c2VSZWYoKSBvciBjcmVhdGVSZWYoKSBpbnN0ZWFkLiAnICsgJ0xlYXJuIG1vcmUgYWJvdXQgdXNpbmcgcmVmcyBzYWZlbHkgaGVyZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3RyaWN0LW1vZGUtc3RyaW5nLXJlZicsIGNvbXBvbmVudE5hbWUsIGNvbmZpZy5yZWYpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgYSBuZXcgUmVhY3QgZWxlbWVudC4gVGhpcyBubyBsb25nZXIgYWRoZXJlcyB0b1xuICogdGhlIGNsYXNzIHBhdHRlcm4sIHNvIGRvIG5vdCB1c2UgbmV3IHRvIGNhbGwgaXQuIEFsc28sIGluc3RhbmNlb2YgY2hlY2tcbiAqIHdpbGwgbm90IHdvcmsuIEluc3RlYWQgdGVzdCAkJHR5cGVvZiBmaWVsZCBhZ2FpbnN0IFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKSB0byBjaGVja1xuICogaWYgc29tZXRoaW5nIGlzIGEgUmVhY3QgRWxlbWVudC5cbiAqXG4gKiBAcGFyYW0geyp9IHR5cGVcbiAqIEBwYXJhbSB7Kn0gcHJvcHNcbiAqIEBwYXJhbSB7Kn0ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHJlZlxuICogQHBhcmFtIHsqfSBvd25lclxuICogQHBhcmFtIHsqfSBzZWxmIEEgKnRlbXBvcmFyeSogaGVscGVyIHRvIGRldGVjdCBwbGFjZXMgd2hlcmUgYHRoaXNgIGlzXG4gKiBkaWZmZXJlbnQgZnJvbSB0aGUgYG93bmVyYCB3aGVuIFJlYWN0LmNyZWF0ZUVsZW1lbnQgaXMgY2FsbGVkLCBzbyB0aGF0IHdlXG4gKiBjYW4gd2Fybi4gV2Ugd2FudCB0byBnZXQgcmlkIG9mIG93bmVyIGFuZCByZXBsYWNlIHN0cmluZyBgcmVmYHMgd2l0aCBhcnJvd1xuICogZnVuY3Rpb25zLCBhbmQgYXMgbG9uZyBhcyBgdGhpc2AgYW5kIG93bmVyIGFyZSB0aGUgc2FtZSwgdGhlcmUgd2lsbCBiZSBub1xuICogY2hhbmdlIGluIGJlaGF2aW9yLlxuICogQHBhcmFtIHsqfSBzb3VyY2UgQW4gYW5ub3RhdGlvbiBvYmplY3QgKGFkZGVkIGJ5IGEgdHJhbnNwaWxlciBvciBvdGhlcndpc2UpXG4gKiBpbmRpY2F0aW5nIGZpbGVuYW1lLCBsaW5lIG51bWJlciwgYW5kL29yIG90aGVyIGluZm9ybWF0aW9uLlxuICogQGludGVybmFsXG4gKi9cblxuXG52YXIgUmVhY3RFbGVtZW50ID0gZnVuY3Rpb24gKHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIG93bmVyLCBwcm9wcykge1xuICB2YXIgZWxlbWVudCA9IHtcbiAgICAvLyBUaGlzIHRhZyBhbGxvd3MgdXMgdG8gdW5pcXVlbHkgaWRlbnRpZnkgdGhpcyBhcyBhIFJlYWN0IEVsZW1lbnRcbiAgICAkJHR5cGVvZjogUkVBQ1RfRUxFTUVOVF9UWVBFLFxuICAgIC8vIEJ1aWx0LWluIHByb3BlcnRpZXMgdGhhdCBiZWxvbmcgb24gdGhlIGVsZW1lbnRcbiAgICB0eXBlOiB0eXBlLFxuICAgIGtleToga2V5LFxuICAgIHJlZjogcmVmLFxuICAgIHByb3BzOiBwcm9wcyxcbiAgICAvLyBSZWNvcmQgdGhlIGNvbXBvbmVudCByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgdGhpcyBlbGVtZW50LlxuICAgIF9vd25lcjogb3duZXJcbiAgfTtcblxuICB7XG4gICAgLy8gVGhlIHZhbGlkYXRpb24gZmxhZyBpcyBjdXJyZW50bHkgbXV0YXRpdmUuIFdlIHB1dCBpdCBvblxuICAgIC8vIGFuIGV4dGVybmFsIGJhY2tpbmcgc3RvcmUgc28gdGhhdCB3ZSBjYW4gZnJlZXplIHRoZSB3aG9sZSBvYmplY3QuXG4gICAgLy8gVGhpcyBjYW4gYmUgcmVwbGFjZWQgd2l0aCBhIFdlYWtNYXAgb25jZSB0aGV5IGFyZSBpbXBsZW1lbnRlZCBpblxuICAgIC8vIGNvbW1vbmx5IHVzZWQgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnRzLlxuICAgIGVsZW1lbnQuX3N0b3JlID0ge307IC8vIFRvIG1ha2UgY29tcGFyaW5nIFJlYWN0RWxlbWVudHMgZWFzaWVyIGZvciB0ZXN0aW5nIHB1cnBvc2VzLCB3ZSBtYWtlXG4gICAgLy8gdGhlIHZhbGlkYXRpb24gZmxhZyBub24tZW51bWVyYWJsZSAod2hlcmUgcG9zc2libGUsIHdoaWNoIHNob3VsZFxuICAgIC8vIGluY2x1ZGUgZXZlcnkgZW52aXJvbm1lbnQgd2UgcnVuIHRlc3RzIGluKSwgc28gdGhlIHRlc3QgZnJhbWV3b3JrXG4gICAgLy8gaWdub3JlcyBpdC5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50Ll9zdG9yZSwgJ3ZhbGlkYXRlZCcsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGZhbHNlXG4gICAgfSk7IC8vIHNlbGYgYW5kIHNvdXJjZSBhcmUgREVWIG9ubHkgcHJvcGVydGllcy5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50LCAnX3NlbGYnLCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogc2VsZlxuICAgIH0pOyAvLyBUd28gZWxlbWVudHMgY3JlYXRlZCBpbiB0d28gZGlmZmVyZW50IHBsYWNlcyBzaG91bGQgYmUgY29uc2lkZXJlZFxuICAgIC8vIGVxdWFsIGZvciB0ZXN0aW5nIHB1cnBvc2VzIGFuZCB0aGVyZWZvcmUgd2UgaGlkZSBpdCBmcm9tIGVudW1lcmF0aW9uLlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc291cmNlJywge1xuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IHNvdXJjZVxuICAgIH0pO1xuXG4gICAgaWYgKE9iamVjdC5mcmVlemUpIHtcbiAgICAgIE9iamVjdC5mcmVlemUoZWxlbWVudC5wcm9wcyk7XG4gICAgICBPYmplY3QuZnJlZXplKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufTtcbi8qKlxuICogQ3JlYXRlIGFuZCByZXR1cm4gYSBuZXcgUmVhY3RFbGVtZW50IG9mIHRoZSBnaXZlbiB0eXBlLlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNjcmVhdGVlbGVtZW50XG4gKi9cblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCh0eXBlLCBjb25maWcsIGNoaWxkcmVuKSB7XG4gIHZhciBwcm9wTmFtZTsgLy8gUmVzZXJ2ZWQgbmFtZXMgYXJlIGV4dHJhY3RlZFxuXG4gIHZhciBwcm9wcyA9IHt9O1xuICB2YXIga2V5ID0gbnVsbDtcbiAgdmFyIHJlZiA9IG51bGw7XG4gIHZhciBzZWxmID0gbnVsbDtcbiAgdmFyIHNvdXJjZSA9IG51bGw7XG5cbiAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgaWYgKGhhc1ZhbGlkUmVmKGNvbmZpZykpIHtcbiAgICAgIHJlZiA9IGNvbmZpZy5yZWY7XG5cbiAgICAgIHtcbiAgICAgICAgd2FybklmU3RyaW5nUmVmQ2Fubm90QmVBdXRvQ29udmVydGVkKGNvbmZpZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGhhc1ZhbGlkS2V5KGNvbmZpZykpIHtcbiAgICAgIHtcbiAgICAgICAgY2hlY2tLZXlTdHJpbmdDb2VyY2lvbihjb25maWcua2V5KTtcbiAgICAgIH1cblxuICAgICAga2V5ID0gJycgKyBjb25maWcua2V5O1xuICAgIH1cblxuICAgIHNlbGYgPSBjb25maWcuX19zZWxmID09PSB1bmRlZmluZWQgPyBudWxsIDogY29uZmlnLl9fc2VsZjtcbiAgICBzb3VyY2UgPSBjb25maWcuX19zb3VyY2UgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb25maWcuX19zb3VyY2U7IC8vIFJlbWFpbmluZyBwcm9wZXJ0aWVzIGFyZSBhZGRlZCB0byBhIG5ldyBwcm9wcyBvYmplY3RcblxuICAgIGZvciAocHJvcE5hbWUgaW4gY29uZmlnKSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChjb25maWcsIHByb3BOYW1lKSAmJiAhUkVTRVJWRURfUFJPUFMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGNvbmZpZ1twcm9wTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9IC8vIENoaWxkcmVuIGNhbiBiZSBtb3JlIHRoYW4gb25lIGFyZ3VtZW50LCBhbmQgdGhvc2UgYXJlIHRyYW5zZmVycmVkIG9udG9cbiAgLy8gdGhlIG5ld2x5IGFsbG9jYXRlZCBwcm9wcyBvYmplY3QuXG5cblxuICB2YXIgY2hpbGRyZW5MZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoIC0gMjtcblxuICBpZiAoY2hpbGRyZW5MZW5ndGggPT09IDEpIHtcbiAgICBwcm9wcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuICB9IGVsc2UgaWYgKGNoaWxkcmVuTGVuZ3RoID4gMSkge1xuICAgIHZhciBjaGlsZEFycmF5ID0gQXJyYXkoY2hpbGRyZW5MZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbkxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGlsZEFycmF5W2ldID0gYXJndW1lbnRzW2kgKyAyXTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAoT2JqZWN0LmZyZWV6ZSkge1xuICAgICAgICBPYmplY3QuZnJlZXplKGNoaWxkQXJyYXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRBcnJheTtcbiAgfSAvLyBSZXNvbHZlIGRlZmF1bHQgcHJvcHNcblxuXG4gIGlmICh0eXBlICYmIHR5cGUuZGVmYXVsdFByb3BzKSB7XG4gICAgdmFyIGRlZmF1bHRQcm9wcyA9IHR5cGUuZGVmYXVsdFByb3BzO1xuXG4gICAgZm9yIChwcm9wTmFtZSBpbiBkZWZhdWx0UHJvcHMpIHtcbiAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkZWZhdWx0UHJvcHNbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHtcbiAgICBpZiAoa2V5IHx8IHJlZikge1xuICAgICAgdmFyIGRpc3BsYXlOYW1lID0gdHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicgPyB0eXBlLmRpc3BsYXlOYW1lIHx8IHR5cGUubmFtZSB8fCAnVW5rbm93bicgOiB0eXBlO1xuXG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGRlZmluZUtleVByb3BXYXJuaW5nR2V0dGVyKHByb3BzLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgZGVmaW5lUmVmUHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gUmVhY3RFbGVtZW50KHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQsIHByb3BzKTtcbn1cbmZ1bmN0aW9uIGNsb25lQW5kUmVwbGFjZUtleShvbGRFbGVtZW50LCBuZXdLZXkpIHtcbiAgdmFyIG5ld0VsZW1lbnQgPSBSZWFjdEVsZW1lbnQob2xkRWxlbWVudC50eXBlLCBuZXdLZXksIG9sZEVsZW1lbnQucmVmLCBvbGRFbGVtZW50Ll9zZWxmLCBvbGRFbGVtZW50Ll9zb3VyY2UsIG9sZEVsZW1lbnQuX293bmVyLCBvbGRFbGVtZW50LnByb3BzKTtcbiAgcmV0dXJuIG5ld0VsZW1lbnQ7XG59XG4vKipcbiAqIENsb25lIGFuZCByZXR1cm4gYSBuZXcgUmVhY3RFbGVtZW50IHVzaW5nIGVsZW1lbnQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50LlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNjbG9uZWVsZW1lbnRcbiAqL1xuXG5mdW5jdGlvbiBjbG9uZUVsZW1lbnQoZWxlbWVudCwgY29uZmlnLCBjaGlsZHJlbikge1xuICBpZiAoZWxlbWVudCA9PT0gbnVsbCB8fCBlbGVtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWFjdC5jbG9uZUVsZW1lbnQoLi4uKTogVGhlIGFyZ3VtZW50IG11c3QgYmUgYSBSZWFjdCBlbGVtZW50LCBidXQgeW91IHBhc3NlZCBcIiArIGVsZW1lbnQgKyBcIi5cIik7XG4gIH1cblxuICB2YXIgcHJvcE5hbWU7IC8vIE9yaWdpbmFsIHByb3BzIGFyZSBjb3BpZWRcblxuICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIGVsZW1lbnQucHJvcHMpOyAvLyBSZXNlcnZlZCBuYW1lcyBhcmUgZXh0cmFjdGVkXG5cbiAgdmFyIGtleSA9IGVsZW1lbnQua2V5O1xuICB2YXIgcmVmID0gZWxlbWVudC5yZWY7IC8vIFNlbGYgaXMgcHJlc2VydmVkIHNpbmNlIHRoZSBvd25lciBpcyBwcmVzZXJ2ZWQuXG5cbiAgdmFyIHNlbGYgPSBlbGVtZW50Ll9zZWxmOyAvLyBTb3VyY2UgaXMgcHJlc2VydmVkIHNpbmNlIGNsb25lRWxlbWVudCBpcyB1bmxpa2VseSB0byBiZSB0YXJnZXRlZCBieSBhXG4gIC8vIHRyYW5zcGlsZXIsIGFuZCB0aGUgb3JpZ2luYWwgc291cmNlIGlzIHByb2JhYmx5IGEgYmV0dGVyIGluZGljYXRvciBvZiB0aGVcbiAgLy8gdHJ1ZSBvd25lci5cblxuICB2YXIgc291cmNlID0gZWxlbWVudC5fc291cmNlOyAvLyBPd25lciB3aWxsIGJlIHByZXNlcnZlZCwgdW5sZXNzIHJlZiBpcyBvdmVycmlkZGVuXG5cbiAgdmFyIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG5cbiAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgaWYgKGhhc1ZhbGlkUmVmKGNvbmZpZykpIHtcbiAgICAgIC8vIFNpbGVudGx5IHN0ZWFsIHRoZSByZWYgZnJvbSB0aGUgcGFyZW50LlxuICAgICAgcmVmID0gY29uZmlnLnJlZjtcbiAgICAgIG93bmVyID0gUmVhY3RDdXJyZW50T3duZXIuY3VycmVudDtcbiAgICB9XG5cbiAgICBpZiAoaGFzVmFsaWRLZXkoY29uZmlnKSkge1xuICAgICAge1xuICAgICAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKGNvbmZpZy5rZXkpO1xuICAgICAgfVxuXG4gICAgICBrZXkgPSAnJyArIGNvbmZpZy5rZXk7XG4gICAgfSAvLyBSZW1haW5pbmcgcHJvcGVydGllcyBvdmVycmlkZSBleGlzdGluZyBwcm9wc1xuXG5cbiAgICB2YXIgZGVmYXVsdFByb3BzO1xuXG4gICAgaWYgKGVsZW1lbnQudHlwZSAmJiBlbGVtZW50LnR5cGUuZGVmYXVsdFByb3BzKSB7XG4gICAgICBkZWZhdWx0UHJvcHMgPSBlbGVtZW50LnR5cGUuZGVmYXVsdFByb3BzO1xuICAgIH1cblxuICAgIGZvciAocHJvcE5hbWUgaW4gY29uZmlnKSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChjb25maWcsIHByb3BOYW1lKSAmJiAhUkVTRVJWRURfUFJPUFMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAgIGlmIChjb25maWdbcHJvcE5hbWVdID09PSB1bmRlZmluZWQgJiYgZGVmYXVsdFByb3BzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBSZXNvbHZlIGRlZmF1bHQgcHJvcHNcbiAgICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkZWZhdWx0UHJvcHNbcHJvcE5hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGNvbmZpZ1twcm9wTmFtZV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gQ2hpbGRyZW4gY2FuIGJlIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQsIGFuZCB0aG9zZSBhcmUgdHJhbnNmZXJyZWQgb250b1xuICAvLyB0aGUgbmV3bHkgYWxsb2NhdGVkIHByb3BzIG9iamVjdC5cblxuXG4gIHZhciBjaGlsZHJlbkxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGggLSAyO1xuXG4gIGlmIChjaGlsZHJlbkxlbmd0aCA9PT0gMSkge1xuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH0gZWxzZSBpZiAoY2hpbGRyZW5MZW5ndGggPiAxKSB7XG4gICAgdmFyIGNoaWxkQXJyYXkgPSBBcnJheShjaGlsZHJlbkxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuTGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkQXJyYXlbaV0gPSBhcmd1bWVudHNbaSArIDJdO1xuICAgIH1cblxuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRBcnJheTtcbiAgfVxuXG4gIHJldHVybiBSZWFjdEVsZW1lbnQoZWxlbWVudC50eXBlLCBrZXksIHJlZiwgc2VsZiwgc291cmNlLCBvd25lciwgcHJvcHMpO1xufVxuLyoqXG4gKiBWZXJpZmllcyB0aGUgb2JqZWN0IGlzIGEgUmVhY3RFbGVtZW50LlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNpc3ZhbGlkZWxlbWVudFxuICogQHBhcmFtIHs/b2JqZWN0fSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYG9iamVjdGAgaXMgYSBSZWFjdEVsZW1lbnQuXG4gKiBAZmluYWxcbiAqL1xuXG5mdW5jdGlvbiBpc1ZhbGlkRWxlbWVudChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmIG9iamVjdCAhPT0gbnVsbCAmJiBvYmplY3QuJCR0eXBlb2YgPT09IFJFQUNUX0VMRU1FTlRfVFlQRTtcbn1cblxudmFyIFNFUEFSQVRPUiA9ICcuJztcbnZhciBTVUJTRVBBUkFUT1IgPSAnOic7XG4vKipcbiAqIEVzY2FwZSBhbmQgd3JhcCBrZXkgc28gaXQgaXMgc2FmZSB0byB1c2UgYXMgYSByZWFjdGlkXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSB0byBiZSBlc2NhcGVkLlxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgZXNjYXBlZCBrZXkuXG4gKi9cblxuZnVuY3Rpb24gZXNjYXBlKGtleSkge1xuICB2YXIgZXNjYXBlUmVnZXggPSAvWz06XS9nO1xuICB2YXIgZXNjYXBlckxvb2t1cCA9IHtcbiAgICAnPSc6ICc9MCcsXG4gICAgJzonOiAnPTInXG4gIH07XG4gIHZhciBlc2NhcGVkU3RyaW5nID0ga2V5LnJlcGxhY2UoZXNjYXBlUmVnZXgsIGZ1bmN0aW9uIChtYXRjaCkge1xuICAgIHJldHVybiBlc2NhcGVyTG9va3VwW21hdGNoXTtcbiAgfSk7XG4gIHJldHVybiAnJCcgKyBlc2NhcGVkU3RyaW5nO1xufVxuLyoqXG4gKiBUT0RPOiBUZXN0IHRoYXQgYSBzaW5nbGUgY2hpbGQgYW5kIGFuIGFycmF5IHdpdGggb25lIGl0ZW0gaGF2ZSB0aGUgc2FtZSBrZXlcbiAqIHBhdHRlcm4uXG4gKi9cblxuXG52YXIgZGlkV2FybkFib3V0TWFwcyA9IGZhbHNlO1xudmFyIHVzZXJQcm92aWRlZEtleUVzY2FwZVJlZ2V4ID0gL1xcLysvZztcblxuZnVuY3Rpb24gZXNjYXBlVXNlclByb3ZpZGVkS2V5KHRleHQpIHtcbiAgcmV0dXJuIHRleHQucmVwbGFjZSh1c2VyUHJvdmlkZWRLZXlFc2NhcGVSZWdleCwgJyQmLycpO1xufVxuLyoqXG4gKiBHZW5lcmF0ZSBhIGtleSBzdHJpbmcgdGhhdCBpZGVudGlmaWVzIGEgZWxlbWVudCB3aXRoaW4gYSBzZXQuXG4gKlxuICogQHBhcmFtIHsqfSBlbGVtZW50IEEgZWxlbWVudCB0aGF0IGNvdWxkIGNvbnRhaW4gYSBtYW51YWwga2V5LlxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IEluZGV4IHRoYXQgaXMgdXNlZCBpZiBhIG1hbnVhbCBrZXkgaXMgbm90IHByb3ZpZGVkLlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5cblxuZnVuY3Rpb24gZ2V0RWxlbWVudEtleShlbGVtZW50LCBpbmRleCkge1xuICAvLyBEbyBzb21lIHR5cGVjaGVja2luZyBoZXJlIHNpbmNlIHdlIGNhbGwgdGhpcyBibGluZGx5LiBXZSB3YW50IHRvIGVuc3VyZVxuICAvLyB0aGF0IHdlIGRvbid0IGJsb2NrIHBvdGVudGlhbCBmdXR1cmUgRVMgQVBJcy5cbiAgaWYgKHR5cGVvZiBlbGVtZW50ID09PSAnb2JqZWN0JyAmJiBlbGVtZW50ICE9PSBudWxsICYmIGVsZW1lbnQua2V5ICE9IG51bGwpIHtcbiAgICAvLyBFeHBsaWNpdCBrZXlcbiAgICB7XG4gICAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKGVsZW1lbnQua2V5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXNjYXBlKCcnICsgZWxlbWVudC5rZXkpO1xuICB9IC8vIEltcGxpY2l0IGtleSBkZXRlcm1pbmVkIGJ5IHRoZSBpbmRleCBpbiB0aGUgc2V0XG5cblxuICByZXR1cm4gaW5kZXgudG9TdHJpbmcoMzYpO1xufVxuXG5mdW5jdGlvbiBtYXBJbnRvQXJyYXkoY2hpbGRyZW4sIGFycmF5LCBlc2NhcGVkUHJlZml4LCBuYW1lU29GYXIsIGNhbGxiYWNrKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIGNoaWxkcmVuO1xuXG4gIGlmICh0eXBlID09PSAndW5kZWZpbmVkJyB8fCB0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAvLyBBbGwgb2YgdGhlIGFib3ZlIGFyZSBwZXJjZWl2ZWQgYXMgbnVsbC5cbiAgICBjaGlsZHJlbiA9IG51bGw7XG4gIH1cblxuICB2YXIgaW52b2tlQ2FsbGJhY2sgPSBmYWxzZTtcblxuICBpZiAoY2hpbGRyZW4gPT09IG51bGwpIHtcbiAgICBpbnZva2VDYWxsYmFjayA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgICAgaW52b2tlQ2FsbGJhY2sgPSB0cnVlO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgc3dpdGNoIChjaGlsZHJlbi4kJHR5cGVvZikge1xuICAgICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICAgICAgICBpbnZva2VDYWxsYmFjayA9IHRydWU7XG4gICAgICAgIH1cblxuICAgIH1cbiAgfVxuXG4gIGlmIChpbnZva2VDYWxsYmFjaykge1xuICAgIHZhciBfY2hpbGQgPSBjaGlsZHJlbjtcbiAgICB2YXIgbWFwcGVkQ2hpbGQgPSBjYWxsYmFjayhfY2hpbGQpOyAvLyBJZiBpdCdzIHRoZSBvbmx5IGNoaWxkLCB0cmVhdCB0aGUgbmFtZSBhcyBpZiBpdCB3YXMgd3JhcHBlZCBpbiBhbiBhcnJheVxuICAgIC8vIHNvIHRoYXQgaXQncyBjb25zaXN0ZW50IGlmIHRoZSBudW1iZXIgb2YgY2hpbGRyZW4gZ3Jvd3M6XG5cbiAgICB2YXIgY2hpbGRLZXkgPSBuYW1lU29GYXIgPT09ICcnID8gU0VQQVJBVE9SICsgZ2V0RWxlbWVudEtleShfY2hpbGQsIDApIDogbmFtZVNvRmFyO1xuXG4gICAgaWYgKGlzQXJyYXkobWFwcGVkQ2hpbGQpKSB7XG4gICAgICB2YXIgZXNjYXBlZENoaWxkS2V5ID0gJyc7XG5cbiAgICAgIGlmIChjaGlsZEtleSAhPSBudWxsKSB7XG4gICAgICAgIGVzY2FwZWRDaGlsZEtleSA9IGVzY2FwZVVzZXJQcm92aWRlZEtleShjaGlsZEtleSkgKyAnLyc7XG4gICAgICB9XG5cbiAgICAgIG1hcEludG9BcnJheShtYXBwZWRDaGlsZCwgYXJyYXksIGVzY2FwZWRDaGlsZEtleSwgJycsIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChtYXBwZWRDaGlsZCAhPSBudWxsKSB7XG4gICAgICBpZiAoaXNWYWxpZEVsZW1lbnQobWFwcGVkQ2hpbGQpKSB7XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBUaGUgYGlmYCBzdGF0ZW1lbnQgaGVyZSBwcmV2ZW50cyBhdXRvLWRpc2FibGluZyBvZiB0aGUgc2FmZVxuICAgICAgICAgIC8vIGNvZXJjaW9uIEVTTGludCBydWxlLCBzbyB3ZSBtdXN0IG1hbnVhbGx5IGRpc2FibGUgaXQgYmVsb3cuXG4gICAgICAgICAgLy8gJEZsb3dGaXhNZSBGbG93IGluY29ycmVjdGx5IHRoaW5rcyBSZWFjdC5Qb3J0YWwgZG9lc24ndCBoYXZlIGEga2V5XG4gICAgICAgICAgaWYgKG1hcHBlZENoaWxkLmtleSAmJiAoIV9jaGlsZCB8fCBfY2hpbGQua2V5ICE9PSBtYXBwZWRDaGlsZC5rZXkpKSB7XG4gICAgICAgICAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKG1hcHBlZENoaWxkLmtleSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbWFwcGVkQ2hpbGQgPSBjbG9uZUFuZFJlcGxhY2VLZXkobWFwcGVkQ2hpbGQsIC8vIEtlZXAgYm90aCB0aGUgKG1hcHBlZCkgYW5kIG9sZCBrZXlzIGlmIHRoZXkgZGlmZmVyLCBqdXN0IGFzXG4gICAgICAgIC8vIHRyYXZlcnNlQWxsQ2hpbGRyZW4gdXNlZCB0byBkbyBmb3Igb2JqZWN0cyBhcyBjaGlsZHJlblxuICAgICAgICBlc2NhcGVkUHJlZml4ICsgKCAvLyAkRmxvd0ZpeE1lIEZsb3cgaW5jb3JyZWN0bHkgdGhpbmtzIFJlYWN0LlBvcnRhbCBkb2Vzbid0IGhhdmUgYSBrZXlcbiAgICAgICAgbWFwcGVkQ2hpbGQua2V5ICYmICghX2NoaWxkIHx8IF9jaGlsZC5rZXkgIT09IG1hcHBlZENoaWxkLmtleSkgPyAvLyAkRmxvd0ZpeE1lIEZsb3cgaW5jb3JyZWN0bHkgdGhpbmtzIGV4aXN0aW5nIGVsZW1lbnQncyBrZXkgY2FuIGJlIGEgbnVtYmVyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgICBlc2NhcGVVc2VyUHJvdmlkZWRLZXkoJycgKyBtYXBwZWRDaGlsZC5rZXkpICsgJy8nIDogJycpICsgY2hpbGRLZXkpO1xuICAgICAgfVxuXG4gICAgICBhcnJheS5wdXNoKG1hcHBlZENoaWxkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIHZhciBjaGlsZDtcbiAgdmFyIG5leHROYW1lO1xuICB2YXIgc3VidHJlZUNvdW50ID0gMDsgLy8gQ291bnQgb2YgY2hpbGRyZW4gZm91bmQgaW4gdGhlIGN1cnJlbnQgc3VidHJlZS5cblxuICB2YXIgbmV4dE5hbWVQcmVmaXggPSBuYW1lU29GYXIgPT09ICcnID8gU0VQQVJBVE9SIDogbmFtZVNvRmFyICsgU1VCU0VQQVJBVE9SO1xuXG4gIGlmIChpc0FycmF5KGNoaWxkcmVuKSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgICBuZXh0TmFtZSA9IG5leHROYW1lUHJlZml4ICsgZ2V0RWxlbWVudEtleShjaGlsZCwgaSk7XG4gICAgICBzdWJ0cmVlQ291bnQgKz0gbWFwSW50b0FycmF5KGNoaWxkLCBhcnJheSwgZXNjYXBlZFByZWZpeCwgbmV4dE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKGNoaWxkcmVuKTtcblxuICAgIGlmICh0eXBlb2YgaXRlcmF0b3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIGl0ZXJhYmxlQ2hpbGRyZW4gPSBjaGlsZHJlbjtcblxuICAgICAge1xuICAgICAgICAvLyBXYXJuIGFib3V0IHVzaW5nIE1hcHMgYXMgY2hpbGRyZW5cbiAgICAgICAgaWYgKGl0ZXJhdG9yRm4gPT09IGl0ZXJhYmxlQ2hpbGRyZW4uZW50cmllcykge1xuICAgICAgICAgIGlmICghZGlkV2FybkFib3V0TWFwcykge1xuICAgICAgICAgICAgd2FybignVXNpbmcgTWFwcyBhcyBjaGlsZHJlbiBpcyBub3Qgc3VwcG9ydGVkLiAnICsgJ1VzZSBhbiBhcnJheSBvZiBrZXllZCBSZWFjdEVsZW1lbnRzIGluc3RlYWQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGlkV2FybkFib3V0TWFwcyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKGl0ZXJhYmxlQ2hpbGRyZW4pO1xuICAgICAgdmFyIHN0ZXA7XG4gICAgICB2YXIgaWkgPSAwO1xuXG4gICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgIGNoaWxkID0gc3RlcC52YWx1ZTtcbiAgICAgICAgbmV4dE5hbWUgPSBuZXh0TmFtZVByZWZpeCArIGdldEVsZW1lbnRLZXkoY2hpbGQsIGlpKyspO1xuICAgICAgICBzdWJ0cmVlQ291bnQgKz0gbWFwSW50b0FycmF5KGNoaWxkLCBhcnJheSwgZXNjYXBlZFByZWZpeCwgbmV4dE5hbWUsIGNhbGxiYWNrKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb25cbiAgICAgIHZhciBjaGlsZHJlblN0cmluZyA9IFN0cmluZyhjaGlsZHJlbik7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPYmplY3RzIGFyZSBub3QgdmFsaWQgYXMgYSBSZWFjdCBjaGlsZCAoZm91bmQ6IFwiICsgKGNoaWxkcmVuU3RyaW5nID09PSAnW29iamVjdCBPYmplY3RdJyA/ICdvYmplY3Qgd2l0aCBrZXlzIHsnICsgT2JqZWN0LmtleXMoY2hpbGRyZW4pLmpvaW4oJywgJykgKyAnfScgOiBjaGlsZHJlblN0cmluZykgKyBcIikuIFwiICsgJ0lmIHlvdSBtZWFudCB0byByZW5kZXIgYSBjb2xsZWN0aW9uIG9mIGNoaWxkcmVuLCB1c2UgYW4gYXJyYXkgJyArICdpbnN0ZWFkLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdWJ0cmVlQ291bnQ7XG59XG5cbi8qKlxuICogTWFwcyBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzIGBwcm9wcy5jaGlsZHJlbmAuXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVubWFwXG4gKlxuICogVGhlIHByb3ZpZGVkIG1hcEZ1bmN0aW9uKGNoaWxkLCBpbmRleCkgd2lsbCBiZSBjYWxsZWQgZm9yIGVhY2hcbiAqIGxlYWYgY2hpbGQuXG4gKlxuICogQHBhcmFtIHs/Kn0gY2hpbGRyZW4gQ2hpbGRyZW4gdHJlZSBjb250YWluZXIuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosIGludCl9IGZ1bmMgVGhlIG1hcCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7Kn0gY29udGV4dCBDb250ZXh0IGZvciBtYXBGdW5jdGlvbi5cbiAqIEByZXR1cm4ge29iamVjdH0gT2JqZWN0IGNvbnRhaW5pbmcgdGhlIG9yZGVyZWQgbWFwIG9mIHJlc3VsdHMuXG4gKi9cbmZ1bmN0aW9uIG1hcENoaWxkcmVuKGNoaWxkcmVuLCBmdW5jLCBjb250ZXh0KSB7XG4gIGlmIChjaGlsZHJlbiA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGNoaWxkcmVuO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgY291bnQgPSAwO1xuICBtYXBJbnRvQXJyYXkoY2hpbGRyZW4sIHJlc3VsdCwgJycsICcnLCBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICByZXR1cm4gZnVuYy5jYWxsKGNvbnRleHQsIGNoaWxkLCBjb3VudCsrKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG4vKipcbiAqIENvdW50IHRoZSBudW1iZXIgb2YgY2hpbGRyZW4gdGhhdCBhcmUgdHlwaWNhbGx5IHNwZWNpZmllZCBhc1xuICogYHByb3BzLmNoaWxkcmVuYC5cbiAqXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI3JlYWN0Y2hpbGRyZW5jb3VudFxuICpcbiAqIEBwYXJhbSB7Pyp9IGNoaWxkcmVuIENoaWxkcmVuIHRyZWUgY29udGFpbmVyLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGNoaWxkcmVuLlxuICovXG5cblxuZnVuY3Rpb24gY291bnRDaGlsZHJlbihjaGlsZHJlbikge1xuICB2YXIgbiA9IDA7XG4gIG1hcENoaWxkcmVuKGNoaWxkcmVuLCBmdW5jdGlvbiAoKSB7XG4gICAgbisrOyAvLyBEb24ndCByZXR1cm4gYW55dGhpbmdcbiAgfSk7XG4gIHJldHVybiBuO1xufVxuXG4vKipcbiAqIEl0ZXJhdGVzIHRocm91Z2ggY2hpbGRyZW4gdGhhdCBhcmUgdHlwaWNhbGx5IHNwZWNpZmllZCBhcyBgcHJvcHMuY2hpbGRyZW5gLlxuICpcbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjcmVhY3RjaGlsZHJlbmZvcmVhY2hcbiAqXG4gKiBUaGUgcHJvdmlkZWQgZm9yRWFjaEZ1bmMoY2hpbGQsIGluZGV4KSB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaFxuICogbGVhZiBjaGlsZC5cbiAqXG4gKiBAcGFyYW0gez8qfSBjaGlsZHJlbiBDaGlsZHJlbiB0cmVlIGNvbnRhaW5lci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgaW50KX0gZm9yRWFjaEZ1bmNcbiAqIEBwYXJhbSB7Kn0gZm9yRWFjaENvbnRleHQgQ29udGV4dCBmb3IgZm9yRWFjaENvbnRleHQuXG4gKi9cbmZ1bmN0aW9uIGZvckVhY2hDaGlsZHJlbihjaGlsZHJlbiwgZm9yRWFjaEZ1bmMsIGZvckVhY2hDb250ZXh0KSB7XG4gIG1hcENoaWxkcmVuKGNoaWxkcmVuLCBmdW5jdGlvbiAoKSB7XG4gICAgZm9yRWFjaEZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gRG9uJ3QgcmV0dXJuIGFueXRoaW5nLlxuICB9LCBmb3JFYWNoQ29udGV4dCk7XG59XG4vKipcbiAqIEZsYXR0ZW4gYSBjaGlsZHJlbiBvYmplY3QgKHR5cGljYWxseSBzcGVjaWZpZWQgYXMgYHByb3BzLmNoaWxkcmVuYCkgYW5kXG4gKiByZXR1cm4gYW4gYXJyYXkgd2l0aCBhcHByb3ByaWF0ZWx5IHJlLWtleWVkIGNoaWxkcmVuLlxuICpcbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjcmVhY3RjaGlsZHJlbnRvYXJyYXlcbiAqL1xuXG5cbmZ1bmN0aW9uIHRvQXJyYXkoY2hpbGRyZW4pIHtcbiAgcmV0dXJuIG1hcENoaWxkcmVuKGNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICByZXR1cm4gY2hpbGQ7XG4gIH0pIHx8IFtdO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBpbiBhIGNvbGxlY3Rpb24gb2YgY2hpbGRyZW4gYW5kIHZlcmlmaWVzIHRoYXQgdGhlcmVcbiAqIGlzIG9ubHkgb25lIGNoaWxkIGluIHRoZSBjb2xsZWN0aW9uLlxuICpcbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjcmVhY3RjaGlsZHJlbm9ubHlcbiAqXG4gKiBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCBhIHNpbmdsZSBjaGlsZCBnZXRzXG4gKiBwYXNzZWQgd2l0aG91dCBhIHdyYXBwZXIsIGJ1dCB0aGUgcHVycG9zZSBvZiB0aGlzIGhlbHBlciBmdW5jdGlvbiBpcyB0b1xuICogYWJzdHJhY3QgYXdheSB0aGUgcGFydGljdWxhciBzdHJ1Y3R1cmUgb2YgY2hpbGRyZW4uXG4gKlxuICogQHBhcmFtIHs/b2JqZWN0fSBjaGlsZHJlbiBDaGlsZCBjb2xsZWN0aW9uIHN0cnVjdHVyZS5cbiAqIEByZXR1cm4ge1JlYWN0RWxlbWVudH0gVGhlIGZpcnN0IGFuZCBvbmx5IGBSZWFjdEVsZW1lbnRgIGNvbnRhaW5lZCBpbiB0aGVcbiAqIHN0cnVjdHVyZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIG9ubHlDaGlsZChjaGlsZHJlbikge1xuICBpZiAoIWlzVmFsaWRFbGVtZW50KGNoaWxkcmVuKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVhY3QuQ2hpbGRyZW4ub25seSBleHBlY3RlZCB0byByZWNlaXZlIGEgc2luZ2xlIFJlYWN0IGVsZW1lbnQgY2hpbGQuJyk7XG4gIH1cblxuICByZXR1cm4gY2hpbGRyZW47XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbnRleHQoZGVmYXVsdFZhbHVlKSB7XG4gIC8vIFRPRE86IFNlY29uZCBhcmd1bWVudCB1c2VkIHRvIGJlIGFuIG9wdGlvbmFsIGBjYWxjdWxhdGVDaGFuZ2VkQml0c2BcbiAgLy8gZnVuY3Rpb24uIFdhcm4gdG8gcmVzZXJ2ZSBmb3IgZnV0dXJlIHVzZT9cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgJCR0eXBlb2Y6IFJFQUNUX0NPTlRFWFRfVFlQRSxcbiAgICAvLyBBcyBhIHdvcmthcm91bmQgdG8gc3VwcG9ydCBtdWx0aXBsZSBjb25jdXJyZW50IHJlbmRlcmVycywgd2UgY2F0ZWdvcml6ZVxuICAgIC8vIHNvbWUgcmVuZGVyZXJzIGFzIHByaW1hcnkgYW5kIG90aGVycyBhcyBzZWNvbmRhcnkuIFdlIG9ubHkgZXhwZWN0XG4gICAgLy8gdGhlcmUgdG8gYmUgdHdvIGNvbmN1cnJlbnQgcmVuZGVyZXJzIGF0IG1vc3Q6IFJlYWN0IE5hdGl2ZSAocHJpbWFyeSkgYW5kXG4gICAgLy8gRmFicmljIChzZWNvbmRhcnkpOyBSZWFjdCBET00gKHByaW1hcnkpIGFuZCBSZWFjdCBBUlQgKHNlY29uZGFyeSkuXG4gICAgLy8gU2Vjb25kYXJ5IHJlbmRlcmVycyBzdG9yZSB0aGVpciBjb250ZXh0IHZhbHVlcyBvbiBzZXBhcmF0ZSBmaWVsZHMuXG4gICAgX2N1cnJlbnRWYWx1ZTogZGVmYXVsdFZhbHVlLFxuICAgIF9jdXJyZW50VmFsdWUyOiBkZWZhdWx0VmFsdWUsXG4gICAgLy8gVXNlZCB0byB0cmFjayBob3cgbWFueSBjb25jdXJyZW50IHJlbmRlcmVycyB0aGlzIGNvbnRleHQgY3VycmVudGx5XG4gICAgLy8gc3VwcG9ydHMgd2l0aGluIGluIGEgc2luZ2xlIHJlbmRlcmVyLiBTdWNoIGFzIHBhcmFsbGVsIHNlcnZlciByZW5kZXJpbmcuXG4gICAgX3RocmVhZENvdW50OiAwLFxuICAgIC8vIFRoZXNlIGFyZSBjaXJjdWxhclxuICAgIFByb3ZpZGVyOiBudWxsLFxuICAgIENvbnN1bWVyOiBudWxsLFxuICAgIC8vIEFkZCB0aGVzZSB0byB1c2Ugc2FtZSBoaWRkZW4gY2xhc3MgaW4gVk0gYXMgU2VydmVyQ29udGV4dFxuICAgIF9kZWZhdWx0VmFsdWU6IG51bGwsXG4gICAgX2dsb2JhbE5hbWU6IG51bGxcbiAgfTtcbiAgY29udGV4dC5Qcm92aWRlciA9IHtcbiAgICAkJHR5cGVvZjogUkVBQ1RfUFJPVklERVJfVFlQRSxcbiAgICBfY29udGV4dDogY29udGV4dFxuICB9O1xuICB2YXIgaGFzV2FybmVkQWJvdXRVc2luZ05lc3RlZENvbnRleHRDb25zdW1lcnMgPSBmYWxzZTtcbiAgdmFyIGhhc1dhcm5lZEFib3V0VXNpbmdDb25zdW1lclByb3ZpZGVyID0gZmFsc2U7XG4gIHZhciBoYXNXYXJuZWRBYm91dERpc3BsYXlOYW1lT25Db25zdW1lciA9IGZhbHNlO1xuXG4gIHtcbiAgICAvLyBBIHNlcGFyYXRlIG9iamVjdCwgYnV0IHByb3hpZXMgYmFjayB0byB0aGUgb3JpZ2luYWwgY29udGV4dCBvYmplY3QgZm9yXG4gICAgLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuIEl0IGhhcyBhIGRpZmZlcmVudCAkJHR5cGVvZiwgc28gd2UgY2FuIHByb3Blcmx5XG4gICAgLy8gd2FybiBmb3IgdGhlIGluY29ycmVjdCB1c2FnZSBvZiBDb250ZXh0IGFzIGEgQ29uc3VtZXIuXG4gICAgdmFyIENvbnN1bWVyID0ge1xuICAgICAgJCR0eXBlb2Y6IFJFQUNUX0NPTlRFWFRfVFlQRSxcbiAgICAgIF9jb250ZXh0OiBjb250ZXh0XG4gICAgfTsgLy8gJEZsb3dGaXhNZTogRmxvdyBjb21wbGFpbnMgYWJvdXQgbm90IHNldHRpbmcgYSB2YWx1ZSwgd2hpY2ggaXMgaW50ZW50aW9uYWwgaGVyZVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQ29uc3VtZXIsIHtcbiAgICAgIFByb3ZpZGVyOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICghaGFzV2FybmVkQWJvdXRVc2luZ0NvbnN1bWVyUHJvdmlkZXIpIHtcbiAgICAgICAgICAgIGhhc1dhcm5lZEFib3V0VXNpbmdDb25zdW1lclByb3ZpZGVyID0gdHJ1ZTtcblxuICAgICAgICAgICAgZXJyb3IoJ1JlbmRlcmluZyA8Q29udGV4dC5Db25zdW1lci5Qcm92aWRlcj4gaXMgbm90IHN1cHBvcnRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluICcgKyAnYSBmdXR1cmUgbWFqb3IgcmVsZWFzZS4gRGlkIHlvdSBtZWFuIHRvIHJlbmRlciA8Q29udGV4dC5Qcm92aWRlcj4gaW5zdGVhZD8nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gY29udGV4dC5Qcm92aWRlcjtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoX1Byb3ZpZGVyKSB7XG4gICAgICAgICAgY29udGV4dC5Qcm92aWRlciA9IF9Qcm92aWRlcjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIF9jdXJyZW50VmFsdWU6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQuX2N1cnJlbnRWYWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoX2N1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgIGNvbnRleHQuX2N1cnJlbnRWYWx1ZSA9IF9jdXJyZW50VmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBfY3VycmVudFZhbHVlMjoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gY29udGV4dC5fY3VycmVudFZhbHVlMjtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoX2N1cnJlbnRWYWx1ZTIpIHtcbiAgICAgICAgICBjb250ZXh0Ll9jdXJyZW50VmFsdWUyID0gX2N1cnJlbnRWYWx1ZTI7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBfdGhyZWFkQ291bnQ6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQuX3RocmVhZENvdW50O1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfdGhyZWFkQ291bnQpIHtcbiAgICAgICAgICBjb250ZXh0Ll90aHJlYWRDb3VudCA9IF90aHJlYWRDb3VudDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIENvbnN1bWVyOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICghaGFzV2FybmVkQWJvdXRVc2luZ05lc3RlZENvbnRleHRDb25zdW1lcnMpIHtcbiAgICAgICAgICAgIGhhc1dhcm5lZEFib3V0VXNpbmdOZXN0ZWRDb250ZXh0Q29uc3VtZXJzID0gdHJ1ZTtcblxuICAgICAgICAgICAgZXJyb3IoJ1JlbmRlcmluZyA8Q29udGV4dC5Db25zdW1lci5Db25zdW1lcj4gaXMgbm90IHN1cHBvcnRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluICcgKyAnYSBmdXR1cmUgbWFqb3IgcmVsZWFzZS4gRGlkIHlvdSBtZWFuIHRvIHJlbmRlciA8Q29udGV4dC5Db25zdW1lcj4gaW5zdGVhZD8nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gY29udGV4dC5Db25zdW1lcjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGRpc3BsYXlOYW1lOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBjb250ZXh0LmRpc3BsYXlOYW1lO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChkaXNwbGF5TmFtZSkge1xuICAgICAgICAgIGlmICghaGFzV2FybmVkQWJvdXREaXNwbGF5TmFtZU9uQ29uc3VtZXIpIHtcbiAgICAgICAgICAgIHdhcm4oJ1NldHRpbmcgYGRpc3BsYXlOYW1lYCBvbiBDb250ZXh0LkNvbnN1bWVyIGhhcyBubyBlZmZlY3QuICcgKyBcIllvdSBzaG91bGQgc2V0IGl0IGRpcmVjdGx5IG9uIHRoZSBjb250ZXh0IHdpdGggQ29udGV4dC5kaXNwbGF5TmFtZSA9ICclcycuXCIsIGRpc3BsYXlOYW1lKTtcblxuICAgICAgICAgICAgaGFzV2FybmVkQWJvdXREaXNwbGF5TmFtZU9uQ29uc3VtZXIgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pOyAvLyAkRmxvd0ZpeE1lOiBGbG93IGNvbXBsYWlucyBhYm91dCBtaXNzaW5nIHByb3BlcnRpZXMgYmVjYXVzZSBpdCBkb2Vzbid0IHVuZGVyc3RhbmQgZGVmaW5lUHJvcGVydHlcblxuICAgIGNvbnRleHQuQ29uc3VtZXIgPSBDb25zdW1lcjtcbiAgfVxuXG4gIHtcbiAgICBjb250ZXh0Ll9jdXJyZW50UmVuZGVyZXIgPSBudWxsO1xuICAgIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlcjIgPSBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbnZhciBVbmluaXRpYWxpemVkID0gLTE7XG52YXIgUGVuZGluZyA9IDA7XG52YXIgUmVzb2x2ZWQgPSAxO1xudmFyIFJlamVjdGVkID0gMjtcblxuZnVuY3Rpb24gbGF6eUluaXRpYWxpemVyKHBheWxvYWQpIHtcbiAgaWYgKHBheWxvYWQuX3N0YXR1cyA9PT0gVW5pbml0aWFsaXplZCkge1xuICAgIHZhciBjdG9yID0gcGF5bG9hZC5fcmVzdWx0O1xuICAgIHZhciB0aGVuYWJsZSA9IGN0b3IoKTsgLy8gVHJhbnNpdGlvbiB0byB0aGUgbmV4dCBzdGF0ZS5cbiAgICAvLyBUaGlzIG1pZ2h0IHRocm93IGVpdGhlciBiZWNhdXNlIGl0J3MgbWlzc2luZyBvciB0aHJvd3MuIElmIHNvLCB3ZSB0cmVhdCBpdFxuICAgIC8vIGFzIHN0aWxsIHVuaW5pdGlhbGl6ZWQgYW5kIHRyeSBhZ2FpbiBuZXh0IHRpbWUuIFdoaWNoIGlzIHRoZSBzYW1lIGFzIHdoYXRcbiAgICAvLyBoYXBwZW5zIGlmIHRoZSBjdG9yIG9yIGFueSB3cmFwcGVycyBwcm9jZXNzaW5nIHRoZSBjdG9yIHRocm93cy4gVGhpcyBtaWdodFxuICAgIC8vIGVuZCB1cCBmaXhpbmcgaXQgaWYgdGhlIHJlc29sdXRpb24gd2FzIGEgY29uY3VycmVuY3kgYnVnLlxuXG4gICAgdGhlbmFibGUudGhlbihmdW5jdGlvbiAobW9kdWxlT2JqZWN0KSB7XG4gICAgICBpZiAocGF5bG9hZC5fc3RhdHVzID09PSBQZW5kaW5nIHx8IHBheWxvYWQuX3N0YXR1cyA9PT0gVW5pbml0aWFsaXplZCkge1xuICAgICAgICAvLyBUcmFuc2l0aW9uIHRvIHRoZSBuZXh0IHN0YXRlLlxuICAgICAgICB2YXIgcmVzb2x2ZWQgPSBwYXlsb2FkO1xuICAgICAgICByZXNvbHZlZC5fc3RhdHVzID0gUmVzb2x2ZWQ7XG4gICAgICAgIHJlc29sdmVkLl9yZXN1bHQgPSBtb2R1bGVPYmplY3Q7XG4gICAgICB9XG4gICAgfSwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBpZiAocGF5bG9hZC5fc3RhdHVzID09PSBQZW5kaW5nIHx8IHBheWxvYWQuX3N0YXR1cyA9PT0gVW5pbml0aWFsaXplZCkge1xuICAgICAgICAvLyBUcmFuc2l0aW9uIHRvIHRoZSBuZXh0IHN0YXRlLlxuICAgICAgICB2YXIgcmVqZWN0ZWQgPSBwYXlsb2FkO1xuICAgICAgICByZWplY3RlZC5fc3RhdHVzID0gUmVqZWN0ZWQ7XG4gICAgICAgIHJlamVjdGVkLl9yZXN1bHQgPSBlcnJvcjtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChwYXlsb2FkLl9zdGF0dXMgPT09IFVuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIEluIGNhc2UsIHdlJ3JlIHN0aWxsIHVuaW5pdGlhbGl6ZWQsIHRoZW4gd2UncmUgd2FpdGluZyBmb3IgdGhlIHRoZW5hYmxlXG4gICAgICAvLyB0byByZXNvbHZlLiBTZXQgaXQgYXMgcGVuZGluZyBpbiB0aGUgbWVhbnRpbWUuXG4gICAgICB2YXIgcGVuZGluZyA9IHBheWxvYWQ7XG4gICAgICBwZW5kaW5nLl9zdGF0dXMgPSBQZW5kaW5nO1xuICAgICAgcGVuZGluZy5fcmVzdWx0ID0gdGhlbmFibGU7XG4gICAgfVxuICB9XG5cbiAgaWYgKHBheWxvYWQuX3N0YXR1cyA9PT0gUmVzb2x2ZWQpIHtcbiAgICB2YXIgbW9kdWxlT2JqZWN0ID0gcGF5bG9hZC5fcmVzdWx0O1xuXG4gICAge1xuICAgICAgaWYgKG1vZHVsZU9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVycm9yKCdsYXp5OiBFeHBlY3RlZCB0aGUgcmVzdWx0IG9mIGEgZHluYW1pYyBpbXAnICsgJ29ydCgpIGNhbGwuICcgKyAnSW5zdGVhZCByZWNlaXZlZDogJXNcXG5cXG5Zb3VyIGNvZGUgc2hvdWxkIGxvb2sgbGlrZTogXFxuICAnICsgLy8gQnJlYWsgdXAgaW1wb3J0cyB0byBhdm9pZCBhY2NpZGVudGFsbHkgcGFyc2luZyB0aGVtIGFzIGRlcGVuZGVuY2llcy5cbiAgICAgICAgJ2NvbnN0IE15Q29tcG9uZW50ID0gbGF6eSgoKSA9PiBpbXAnICsgXCJvcnQoJy4vTXlDb21wb25lbnQnKSlcXG5cXG5cIiArICdEaWQgeW91IGFjY2lkZW50YWxseSBwdXQgY3VybHkgYnJhY2VzIGFyb3VuZCB0aGUgaW1wb3J0PycsIG1vZHVsZU9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKCEoJ2RlZmF1bHQnIGluIG1vZHVsZU9iamVjdCkpIHtcbiAgICAgICAgZXJyb3IoJ2xhenk6IEV4cGVjdGVkIHRoZSByZXN1bHQgb2YgYSBkeW5hbWljIGltcCcgKyAnb3J0KCkgY2FsbC4gJyArICdJbnN0ZWFkIHJlY2VpdmVkOiAlc1xcblxcbllvdXIgY29kZSBzaG91bGQgbG9vayBsaWtlOiBcXG4gICcgKyAvLyBCcmVhayB1cCBpbXBvcnRzIHRvIGF2b2lkIGFjY2lkZW50YWxseSBwYXJzaW5nIHRoZW0gYXMgZGVwZW5kZW5jaWVzLlxuICAgICAgICAnY29uc3QgTXlDb21wb25lbnQgPSBsYXp5KCgpID0+IGltcCcgKyBcIm9ydCgnLi9NeUNvbXBvbmVudCcpKVwiLCBtb2R1bGVPYmplY3QpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtb2R1bGVPYmplY3QuZGVmYXVsdDtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBwYXlsb2FkLl9yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbGF6eShjdG9yKSB7XG4gIHZhciBwYXlsb2FkID0ge1xuICAgIC8vIFdlIHVzZSB0aGVzZSBmaWVsZHMgdG8gc3RvcmUgdGhlIHJlc3VsdC5cbiAgICBfc3RhdHVzOiBVbmluaXRpYWxpemVkLFxuICAgIF9yZXN1bHQ6IGN0b3JcbiAgfTtcbiAgdmFyIGxhenlUeXBlID0ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9MQVpZX1RZUEUsXG4gICAgX3BheWxvYWQ6IHBheWxvYWQsXG4gICAgX2luaXQ6IGxhenlJbml0aWFsaXplclxuICB9O1xuXG4gIHtcbiAgICAvLyBJbiBwcm9kdWN0aW9uLCB0aGlzIHdvdWxkIGp1c3Qgc2V0IGl0IG9uIHRoZSBvYmplY3QuXG4gICAgdmFyIGRlZmF1bHRQcm9wcztcbiAgICB2YXIgcHJvcFR5cGVzOyAvLyAkRmxvd0ZpeE1lXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhsYXp5VHlwZSwge1xuICAgICAgZGVmYXVsdFByb3BzOiB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGRlZmF1bHRQcm9wcztcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3RGVmYXVsdFByb3BzKSB7XG4gICAgICAgICAgZXJyb3IoJ1JlYWN0LmxhenkoLi4uKTogSXQgaXMgbm90IHN1cHBvcnRlZCB0byBhc3NpZ24gYGRlZmF1bHRQcm9wc2AgdG8gJyArICdhIGxhenkgY29tcG9uZW50IGltcG9ydC4gRWl0aGVyIHNwZWNpZnkgdGhlbSB3aGVyZSB0aGUgY29tcG9uZW50ICcgKyAnaXMgZGVmaW5lZCwgb3IgY3JlYXRlIGEgd3JhcHBpbmcgY29tcG9uZW50IGFyb3VuZCBpdC4nKTtcblxuICAgICAgICAgIGRlZmF1bHRQcm9wcyA9IG5ld0RlZmF1bHRQcm9wczsgLy8gTWF0Y2ggcHJvZHVjdGlvbiBiZWhhdmlvciBtb3JlIGNsb3NlbHk6XG4gICAgICAgICAgLy8gJEZsb3dGaXhNZVxuXG4gICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGxhenlUeXBlLCAnZGVmYXVsdFByb3BzJywge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIHByb3BUeXBlcztcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3UHJvcFR5cGVzKSB7XG4gICAgICAgICAgZXJyb3IoJ1JlYWN0LmxhenkoLi4uKTogSXQgaXMgbm90IHN1cHBvcnRlZCB0byBhc3NpZ24gYHByb3BUeXBlc2AgdG8gJyArICdhIGxhenkgY29tcG9uZW50IGltcG9ydC4gRWl0aGVyIHNwZWNpZnkgdGhlbSB3aGVyZSB0aGUgY29tcG9uZW50ICcgKyAnaXMgZGVmaW5lZCwgb3IgY3JlYXRlIGEgd3JhcHBpbmcgY29tcG9uZW50IGFyb3VuZCBpdC4nKTtcblxuICAgICAgICAgIHByb3BUeXBlcyA9IG5ld1Byb3BUeXBlczsgLy8gTWF0Y2ggcHJvZHVjdGlvbiBiZWhhdmlvciBtb3JlIGNsb3NlbHk6XG4gICAgICAgICAgLy8gJEZsb3dGaXhNZVxuXG4gICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGxhenlUeXBlLCAncHJvcFR5cGVzJywge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gbGF6eVR5cGU7XG59XG5cbmZ1bmN0aW9uIGZvcndhcmRSZWYocmVuZGVyKSB7XG4gIHtcbiAgICBpZiAocmVuZGVyICE9IG51bGwgJiYgcmVuZGVyLiQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUpIHtcbiAgICAgIGVycm9yKCdmb3J3YXJkUmVmIHJlcXVpcmVzIGEgcmVuZGVyIGZ1bmN0aW9uIGJ1dCByZWNlaXZlZCBhIGBtZW1vYCAnICsgJ2NvbXBvbmVudC4gSW5zdGVhZCBvZiBmb3J3YXJkUmVmKG1lbW8oLi4uKSksIHVzZSAnICsgJ21lbW8oZm9yd2FyZFJlZiguLi4pKS4nKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiByZW5kZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCdmb3J3YXJkUmVmIHJlcXVpcmVzIGEgcmVuZGVyIGZ1bmN0aW9uIGJ1dCB3YXMgZ2l2ZW4gJXMuJywgcmVuZGVyID09PSBudWxsID8gJ251bGwnIDogdHlwZW9mIHJlbmRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyZW5kZXIubGVuZ3RoICE9PSAwICYmIHJlbmRlci5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVuZGVyIGZ1bmN0aW9ucyBhY2NlcHQgZXhhY3RseSB0d28gcGFyYW1ldGVyczogcHJvcHMgYW5kIHJlZi4gJXMnLCByZW5kZXIubGVuZ3RoID09PSAxID8gJ0RpZCB5b3UgZm9yZ2V0IHRvIHVzZSB0aGUgcmVmIHBhcmFtZXRlcj8nIDogJ0FueSBhZGRpdGlvbmFsIHBhcmFtZXRlciB3aWxsIGJlIHVuZGVmaW5lZC4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocmVuZGVyICE9IG51bGwpIHtcbiAgICAgIGlmIChyZW5kZXIuZGVmYXVsdFByb3BzICE9IG51bGwgfHwgcmVuZGVyLnByb3BUeXBlcyAhPSBudWxsKSB7XG4gICAgICAgIGVycm9yKCdmb3J3YXJkUmVmIHJlbmRlciBmdW5jdGlvbnMgZG8gbm90IHN1cHBvcnQgcHJvcFR5cGVzIG9yIGRlZmF1bHRQcm9wcy4gJyArICdEaWQgeW91IGFjY2lkZW50YWxseSBwYXNzIGEgUmVhY3QgY29tcG9uZW50PycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBlbGVtZW50VHlwZSA9IHtcbiAgICAkJHR5cGVvZjogUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSxcbiAgICByZW5kZXI6IHJlbmRlclxuICB9O1xuXG4gIHtcbiAgICB2YXIgb3duTmFtZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZWxlbWVudFR5cGUsICdkaXNwbGF5TmFtZScsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBvd25OYW1lO1xuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgb3duTmFtZSA9IG5hbWU7IC8vIFRoZSBpbm5lciBjb21wb25lbnQgc2hvdWxkbid0IGluaGVyaXQgdGhpcyBkaXNwbGF5IG5hbWUgaW4gbW9zdCBjYXNlcyxcbiAgICAgICAgLy8gYmVjYXVzZSB0aGUgY29tcG9uZW50IG1heSBiZSB1c2VkIGVsc2V3aGVyZS5cbiAgICAgICAgLy8gQnV0IGl0J3MgbmljZSBmb3IgYW5vbnltb3VzIGZ1bmN0aW9ucyB0byBpbmhlcml0IHRoZSBuYW1lLFxuICAgICAgICAvLyBzbyB0aGF0IG91ciBjb21wb25lbnQtc3RhY2sgZ2VuZXJhdGlvbiBsb2dpYyB3aWxsIGRpc3BsYXkgdGhlaXIgZnJhbWVzLlxuICAgICAgICAvLyBBbiBhbm9ueW1vdXMgZnVuY3Rpb24gZ2VuZXJhbGx5IHN1Z2dlc3RzIGEgcGF0dGVybiBsaWtlOlxuICAgICAgICAvLyAgIFJlYWN0LmZvcndhcmRSZWYoKHByb3BzLCByZWYpID0+IHsuLi59KTtcbiAgICAgICAgLy8gVGhpcyBraW5kIG9mIGlubmVyIGZ1bmN0aW9uIGlzIG5vdCB1c2VkIGVsc2V3aGVyZSBzbyB0aGUgc2lkZSBlZmZlY3QgaXMgb2theS5cblxuICAgICAgICBpZiAoIXJlbmRlci5uYW1lICYmICFyZW5kZXIuZGlzcGxheU5hbWUpIHtcbiAgICAgICAgICByZW5kZXIuZGlzcGxheU5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudFR5cGU7XG59XG5cbnZhciBSRUFDVF9NT0RVTEVfUkVGRVJFTkNFO1xuXG57XG4gIFJFQUNUX01PRFVMRV9SRUZFUkVOQ0UgPSBTeW1ib2wuZm9yKCdyZWFjdC5tb2R1bGUucmVmZXJlbmNlJyk7XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWRFbGVtZW50VHlwZSh0eXBlKSB7XG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSAvLyBOb3RlOiB0eXBlb2YgbWlnaHQgYmUgb3RoZXIgdGhhbiAnc3ltYm9sJyBvciAnbnVtYmVyJyAoZS5nLiBpZiBpdCdzIGEgcG9seWZpbGwpLlxuXG5cbiAgaWYgKHR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUgfHwgdHlwZSA9PT0gUkVBQ1RfUFJPRklMRVJfVFlQRSB8fCBlbmFibGVEZWJ1Z1RyYWNpbmcgIHx8IHR5cGUgPT09IFJFQUNUX1NUUklDVF9NT0RFX1RZUEUgfHwgdHlwZSA9PT0gUkVBQ1RfU1VTUEVOU0VfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEUgfHwgZW5hYmxlTGVnYWN5SGlkZGVuICB8fCB0eXBlID09PSBSRUFDVF9PRkZTQ1JFRU5fVFlQRSB8fCBlbmFibGVTY29wZUFQSSAgfHwgZW5hYmxlQ2FjaGVFbGVtZW50ICB8fCBlbmFibGVUcmFuc2l0aW9uVHJhY2luZyApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gbnVsbCkge1xuICAgIGlmICh0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9MQVpZX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTUVNT19UWVBFIHx8IHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX1BST1ZJREVSX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfQ09OVEVYVF9UWVBFIHx8IHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgfHwgLy8gVGhpcyBuZWVkcyB0byBpbmNsdWRlIGFsbCBwb3NzaWJsZSBtb2R1bGUgcmVmZXJlbmNlIG9iamVjdFxuICAgIC8vIHR5cGVzIHN1cHBvcnRlZCBieSBhbnkgRmxpZ2h0IGNvbmZpZ3VyYXRpb24gYW55d2hlcmUgc2luY2VcbiAgICAvLyB3ZSBkb24ndCBrbm93IHdoaWNoIEZsaWdodCBidWlsZCB0aGlzIHdpbGwgZW5kIHVwIGJlaW5nIHVzZWRcbiAgICAvLyB3aXRoLlxuICAgIHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX01PRFVMRV9SRUZFUkVOQ0UgfHwgdHlwZS5nZXRNb2R1bGVJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG1lbW8odHlwZSwgY29tcGFyZSkge1xuICB7XG4gICAgaWYgKCFpc1ZhbGlkRWxlbWVudFR5cGUodHlwZSkpIHtcbiAgICAgIGVycm9yKCdtZW1vOiBUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIGNvbXBvbmVudC4gSW5zdGVhZCAnICsgJ3JlY2VpdmVkOiAlcycsIHR5cGUgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2YgdHlwZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGVsZW1lbnRUeXBlID0ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9NRU1PX1RZUEUsXG4gICAgdHlwZTogdHlwZSxcbiAgICBjb21wYXJlOiBjb21wYXJlID09PSB1bmRlZmluZWQgPyBudWxsIDogY29tcGFyZVxuICB9O1xuXG4gIHtcbiAgICB2YXIgb3duTmFtZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZWxlbWVudFR5cGUsICdkaXNwbGF5TmFtZScsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBvd25OYW1lO1xuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgb3duTmFtZSA9IG5hbWU7IC8vIFRoZSBpbm5lciBjb21wb25lbnQgc2hvdWxkbid0IGluaGVyaXQgdGhpcyBkaXNwbGF5IG5hbWUgaW4gbW9zdCBjYXNlcyxcbiAgICAgICAgLy8gYmVjYXVzZSB0aGUgY29tcG9uZW50IG1heSBiZSB1c2VkIGVsc2V3aGVyZS5cbiAgICAgICAgLy8gQnV0IGl0J3MgbmljZSBmb3IgYW5vbnltb3VzIGZ1bmN0aW9ucyB0byBpbmhlcml0IHRoZSBuYW1lLFxuICAgICAgICAvLyBzbyB0aGF0IG91ciBjb21wb25lbnQtc3RhY2sgZ2VuZXJhdGlvbiBsb2dpYyB3aWxsIGRpc3BsYXkgdGhlaXIgZnJhbWVzLlxuICAgICAgICAvLyBBbiBhbm9ueW1vdXMgZnVuY3Rpb24gZ2VuZXJhbGx5IHN1Z2dlc3RzIGEgcGF0dGVybiBsaWtlOlxuICAgICAgICAvLyAgIFJlYWN0Lm1lbW8oKHByb3BzKSA9PiB7Li4ufSk7XG4gICAgICAgIC8vIFRoaXMga2luZCBvZiBpbm5lciBmdW5jdGlvbiBpcyBub3QgdXNlZCBlbHNld2hlcmUgc28gdGhlIHNpZGUgZWZmZWN0IGlzIG9rYXkuXG5cbiAgICAgICAgaWYgKCF0eXBlLm5hbWUgJiYgIXR5cGUuZGlzcGxheU5hbWUpIHtcbiAgICAgICAgICB0eXBlLmRpc3BsYXlOYW1lID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRUeXBlO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRGlzcGF0Y2hlcigpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLmN1cnJlbnQ7XG5cbiAge1xuICAgIGlmIChkaXNwYXRjaGVyID09PSBudWxsKSB7XG4gICAgICBlcnJvcignSW52YWxpZCBob29rIGNhbGwuIEhvb2tzIGNhbiBvbmx5IGJlIGNhbGxlZCBpbnNpZGUgb2YgdGhlIGJvZHkgb2YgYSBmdW5jdGlvbiBjb21wb25lbnQuIFRoaXMgY291bGQgaGFwcGVuIGZvcicgKyAnIG9uZSBvZiB0aGUgZm9sbG93aW5nIHJlYXNvbnM6XFxuJyArICcxLiBZb3UgbWlnaHQgaGF2ZSBtaXNtYXRjaGluZyB2ZXJzaW9ucyBvZiBSZWFjdCBhbmQgdGhlIHJlbmRlcmVyIChzdWNoIGFzIFJlYWN0IERPTSlcXG4nICsgJzIuIFlvdSBtaWdodCBiZSBicmVha2luZyB0aGUgUnVsZXMgb2YgSG9va3NcXG4nICsgJzMuIFlvdSBtaWdodCBoYXZlIG1vcmUgdGhhbiBvbmUgY29weSBvZiBSZWFjdCBpbiB0aGUgc2FtZSBhcHBcXG4nICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvaW52YWxpZC1ob29rLWNhbGwgZm9yIHRpcHMgYWJvdXQgaG93IHRvIGRlYnVnIGFuZCBmaXggdGhpcyBwcm9ibGVtLicpO1xuICAgIH1cbiAgfSAvLyBXaWxsIHJlc3VsdCBpbiBhIG51bGwgYWNjZXNzIGVycm9yIGlmIGFjY2Vzc2VkIG91dHNpZGUgcmVuZGVyIHBoYXNlLiBXZVxuICAvLyBpbnRlbnRpb25hbGx5IGRvbid0IHRocm93IG91ciBvd24gZXJyb3IgYmVjYXVzZSB0aGlzIGlzIGluIGEgaG90IHBhdGguXG4gIC8vIEFsc28gaGVscHMgZW5zdXJlIHRoaXMgaXMgaW5saW5lZC5cblxuXG4gIHJldHVybiBkaXNwYXRjaGVyO1xufVxuZnVuY3Rpb24gdXNlQ29udGV4dChDb250ZXh0KSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcblxuICB7XG4gICAgLy8gVE9ETzogYWRkIGEgbW9yZSBnZW5lcmljIHdhcm5pbmcgZm9yIGludmFsaWQgdmFsdWVzLlxuICAgIGlmIChDb250ZXh0Ll9jb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciByZWFsQ29udGV4dCA9IENvbnRleHQuX2NvbnRleHQ7IC8vIERvbid0IGRlZHVwbGljYXRlIGJlY2F1c2UgdGhpcyBsZWdpdGltYXRlbHkgY2F1c2VzIGJ1Z3NcbiAgICAgIC8vIGFuZCBub2JvZHkgc2hvdWxkIGJlIHVzaW5nIHRoaXMgaW4gZXhpc3RpbmcgY29kZS5cblxuICAgICAgaWYgKHJlYWxDb250ZXh0LkNvbnN1bWVyID09PSBDb250ZXh0KSB7XG4gICAgICAgIGVycm9yKCdDYWxsaW5nIHVzZUNvbnRleHQoQ29udGV4dC5Db25zdW1lcikgaXMgbm90IHN1cHBvcnRlZCwgbWF5IGNhdXNlIGJ1Z3MsIGFuZCB3aWxsIGJlICcgKyAncmVtb3ZlZCBpbiBhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiBEaWQgeW91IG1lYW4gdG8gY2FsbCB1c2VDb250ZXh0KENvbnRleHQpIGluc3RlYWQ/Jyk7XG4gICAgICB9IGVsc2UgaWYgKHJlYWxDb250ZXh0LlByb3ZpZGVyID09PSBDb250ZXh0KSB7XG4gICAgICAgIGVycm9yKCdDYWxsaW5nIHVzZUNvbnRleHQoQ29udGV4dC5Qcm92aWRlcikgaXMgbm90IHN1cHBvcnRlZC4gJyArICdEaWQgeW91IG1lYW4gdG8gY2FsbCB1c2VDb250ZXh0KENvbnRleHQpIGluc3RlYWQ/Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlQ29udGV4dChDb250ZXh0KTtcbn1cbmZ1bmN0aW9uIHVzZVN0YXRlKGluaXRpYWxTdGF0ZSkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZVN0YXRlKGluaXRpYWxTdGF0ZSk7XG59XG5mdW5jdGlvbiB1c2VSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSByZXNvbHZlRGlzcGF0Y2hlcigpO1xuICByZXR1cm4gZGlzcGF0Y2hlci51c2VSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xufVxuZnVuY3Rpb24gdXNlUmVmKGluaXRpYWxWYWx1ZSkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZVJlZihpbml0aWFsVmFsdWUpO1xufVxuZnVuY3Rpb24gdXNlRWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUVmZmVjdChjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUxheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlQ2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSByZXNvbHZlRGlzcGF0Y2hlcigpO1xuICByZXR1cm4gZGlzcGF0Y2hlci51c2VDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VNZW1vKGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZU1lbW8oY3JlYXRlLCBkZXBzKTtcbn1cbmZ1bmN0aW9uIHVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSByZXNvbHZlRGlzcGF0Y2hlcigpO1xuICByZXR1cm4gZGlzcGF0Y2hlci51c2VJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKTtcbn1cbmZ1bmN0aW9uIHVzZURlYnVnVmFsdWUodmFsdWUsIGZvcm1hdHRlckZuKSB7XG4gIHtcbiAgICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gICAgcmV0dXJuIGRpc3BhdGNoZXIudXNlRGVidWdWYWx1ZSh2YWx1ZSwgZm9ybWF0dGVyRm4pO1xuICB9XG59XG5mdW5jdGlvbiB1c2VUcmFuc2l0aW9uKCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZVRyYW5zaXRpb24oKTtcbn1cbmZ1bmN0aW9uIHVzZURlZmVycmVkVmFsdWUodmFsdWUpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSByZXNvbHZlRGlzcGF0Y2hlcigpO1xuICByZXR1cm4gZGlzcGF0Y2hlci51c2VEZWZlcnJlZFZhbHVlKHZhbHVlKTtcbn1cbmZ1bmN0aW9uIHVzZUlkKCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUlkKCk7XG59XG5mdW5jdGlvbiB1c2VTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KTtcbn1cblxuLy8gSGVscGVycyB0byBwYXRjaCBjb25zb2xlLmxvZ3MgdG8gYXZvaWQgbG9nZ2luZyBkdXJpbmcgc2lkZS1lZmZlY3QgZnJlZVxuLy8gcmVwbGF5aW5nIG9uIHJlbmRlciBmdW5jdGlvbi4gVGhpcyBjdXJyZW50bHkgb25seSBwYXRjaGVzIHRoZSBvYmplY3Rcbi8vIGxhemlseSB3aGljaCB3b24ndCBjb3ZlciBpZiB0aGUgbG9nIGZ1bmN0aW9uIHdhcyBleHRyYWN0ZWQgZWFnZXJseS5cbi8vIFdlIGNvdWxkIGFsc28gZWFnZXJseSBwYXRjaCB0aGUgbWV0aG9kLlxudmFyIGRpc2FibGVkRGVwdGggPSAwO1xudmFyIHByZXZMb2c7XG52YXIgcHJldkluZm87XG52YXIgcHJldldhcm47XG52YXIgcHJldkVycm9yO1xudmFyIHByZXZHcm91cDtcbnZhciBwcmV2R3JvdXBDb2xsYXBzZWQ7XG52YXIgcHJldkdyb3VwRW5kO1xuXG5mdW5jdGlvbiBkaXNhYmxlZExvZygpIHt9XG5cbmRpc2FibGVkTG9nLl9fcmVhY3REaXNhYmxlZExvZyA9IHRydWU7XG5mdW5jdGlvbiBkaXNhYmxlTG9ncygpIHtcbiAge1xuICAgIGlmIChkaXNhYmxlZERlcHRoID09PSAwKSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICAgIHByZXZMb2cgPSBjb25zb2xlLmxvZztcbiAgICAgIHByZXZJbmZvID0gY29uc29sZS5pbmZvO1xuICAgICAgcHJldldhcm4gPSBjb25zb2xlLndhcm47XG4gICAgICBwcmV2RXJyb3IgPSBjb25zb2xlLmVycm9yO1xuICAgICAgcHJldkdyb3VwID0gY29uc29sZS5ncm91cDtcbiAgICAgIHByZXZHcm91cENvbGxhcHNlZCA9IGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQ7XG4gICAgICBwcmV2R3JvdXBFbmQgPSBjb25zb2xlLmdyb3VwRW5kOyAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE5MDk5XG5cbiAgICAgIHZhciBwcm9wcyA9IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogZGlzYWJsZWRMb2csXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lIEZsb3cgdGhpbmtzIGNvbnNvbGUgaXMgaW1tdXRhYmxlLlxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zb2xlLCB7XG4gICAgICAgIGluZm86IHByb3BzLFxuICAgICAgICBsb2c6IHByb3BzLFxuICAgICAgICB3YXJuOiBwcm9wcyxcbiAgICAgICAgZXJyb3I6IHByb3BzLFxuICAgICAgICBncm91cDogcHJvcHMsXG4gICAgICAgIGdyb3VwQ29sbGFwc2VkOiBwcm9wcyxcbiAgICAgICAgZ3JvdXBFbmQ6IHByb3BzXG4gICAgICB9KTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgfVxuXG4gICAgZGlzYWJsZWREZXB0aCsrO1xuICB9XG59XG5mdW5jdGlvbiByZWVuYWJsZUxvZ3MoKSB7XG4gIHtcbiAgICBkaXNhYmxlZERlcHRoLS07XG5cbiAgICBpZiAoZGlzYWJsZWREZXB0aCA9PT0gMCkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH07IC8vICRGbG93Rml4TWUgRmxvdyB0aGlua3MgY29uc29sZSBpcyBpbW11dGFibGUuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGNvbnNvbGUsIHtcbiAgICAgICAgbG9nOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZMb2dcbiAgICAgICAgfSksXG4gICAgICAgIGluZm86IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkluZm9cbiAgICAgICAgfSksXG4gICAgICAgIHdhcm46IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldldhcm5cbiAgICAgICAgfSksXG4gICAgICAgIGVycm9yOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZFcnJvclxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXA6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cENvbGxhcHNlZDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBDb2xsYXBzZWRcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwRW5kOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cEVuZFxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgIH1cblxuICAgIGlmIChkaXNhYmxlZERlcHRoIDwgMCkge1xuICAgICAgZXJyb3IoJ2Rpc2FibGVkRGVwdGggZmVsbCBiZWxvdyB6ZXJvLiAnICsgJ1RoaXMgaXMgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcjtcbnZhciBwcmVmaXg7XG5mdW5jdGlvbiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZShuYW1lLCBzb3VyY2UsIG93bmVyRm4pIHtcbiAge1xuICAgIGlmIChwcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gRXh0cmFjdCB0aGUgVk0gc3BlY2lmaWMgcHJlZml4IHVzZWQgYnkgZWFjaCBsaW5lLlxuICAgICAgdHJ5IHtcbiAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgdmFyIG1hdGNoID0geC5zdGFjay50cmltKCkubWF0Y2goL1xcbiggKihhdCApPykvKTtcbiAgICAgICAgcHJlZml4ID0gbWF0Y2ggJiYgbWF0Y2hbMV0gfHwgJyc7XG4gICAgICB9XG4gICAgfSAvLyBXZSB1c2UgdGhlIHByZWZpeCB0byBlbnN1cmUgb3VyIHN0YWNrcyBsaW5lIHVwIHdpdGggbmF0aXZlIHN0YWNrIGZyYW1lcy5cblxuXG4gICAgcmV0dXJuICdcXG4nICsgcHJlZml4ICsgbmFtZTtcbiAgfVxufVxudmFyIHJlZW50cnkgPSBmYWxzZTtcbnZhciBjb21wb25lbnRGcmFtZUNhY2hlO1xuXG57XG4gIHZhciBQb3NzaWJseVdlYWtNYXAgPSB0eXBlb2YgV2Vha01hcCA9PT0gJ2Z1bmN0aW9uJyA/IFdlYWtNYXAgOiBNYXA7XG4gIGNvbXBvbmVudEZyYW1lQ2FjaGUgPSBuZXcgUG9zc2libHlXZWFrTWFwKCk7XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoZm4sIGNvbnN0cnVjdCkge1xuICAvLyBJZiBzb21ldGhpbmcgYXNrZWQgZm9yIGEgc3RhY2sgaW5zaWRlIGEgZmFrZSByZW5kZXIsIGl0IHNob3VsZCBnZXQgaWdub3JlZC5cbiAgaWYgKCAhZm4gfHwgcmVlbnRyeSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHtcbiAgICB2YXIgZnJhbWUgPSBjb21wb25lbnRGcmFtZUNhY2hlLmdldChmbik7XG5cbiAgICBpZiAoZnJhbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZyYW1lO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjb250cm9sO1xuICByZWVudHJ5ID0gdHJ1ZTtcbiAgdmFyIHByZXZpb3VzUHJlcGFyZVN0YWNrVHJhY2UgPSBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZTsgLy8gJEZsb3dGaXhNZSBJdCBkb2VzIGFjY2VwdCB1bmRlZmluZWQuXG5cbiAgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPSB1bmRlZmluZWQ7XG4gIHZhciBwcmV2aW91c0Rpc3BhdGNoZXI7XG5cbiAge1xuICAgIHByZXZpb3VzRGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50OyAvLyBTZXQgdGhlIGRpc3BhdGNoZXIgaW4gREVWIGJlY2F1c2UgdGhpcyBtaWdodCBiZSBjYWxsIGluIHRoZSByZW5kZXIgZnVuY3Rpb25cbiAgICAvLyBmb3Igd2FybmluZ3MuXG5cbiAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IG51bGw7XG4gICAgZGlzYWJsZUxvZ3MoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gVGhpcyBzaG91bGQgdGhyb3cuXG4gICAgaWYgKGNvbnN0cnVjdCkge1xuICAgICAgLy8gU29tZXRoaW5nIHNob3VsZCBiZSBzZXR0aW5nIHRoZSBwcm9wcyBpbiB0aGUgY29uc3RydWN0b3IuXG4gICAgICB2YXIgRmFrZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgIH07IC8vICRGbG93Rml4TWVcblxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRmFrZS5wcm90b3R5cGUsICdwcm9wcycsIHtcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gV2UgdXNlIGEgdGhyb3dpbmcgc2V0dGVyIGluc3RlYWQgb2YgZnJvemVuIG9yIG5vbi13cml0YWJsZSBwcm9wc1xuICAgICAgICAgIC8vIGJlY2F1c2UgdGhhdCB3b24ndCB0aHJvdyBpbiBhIG5vbi1zdHJpY3QgbW9kZSBmdW5jdGlvbi5cbiAgICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyAmJiBSZWZsZWN0LmNvbnN0cnVjdCkge1xuICAgICAgICAvLyBXZSBjb25zdHJ1Y3QgYSBkaWZmZXJlbnQgY29udHJvbCBmb3IgdGhpcyBjYXNlIHRvIGluY2x1ZGUgYW55IGV4dHJhXG4gICAgICAgIC8vIGZyYW1lcyBhZGRlZCBieSB0aGUgY29uc3RydWN0IGNhbGwuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoRmFrZSwgW10pO1xuICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICAgIH1cblxuICAgICAgICBSZWZsZWN0LmNvbnN0cnVjdChmbiwgW10sIEZha2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBGYWtlLmNhbGwoKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgICB9XG5cbiAgICAgICAgZm4uY2FsbChGYWtlLnByb3RvdHlwZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgfVxuXG4gICAgICBmbigpO1xuICAgIH1cbiAgfSBjYXRjaCAoc2FtcGxlKSB7XG4gICAgLy8gVGhpcyBpcyBpbmxpbmVkIG1hbnVhbGx5IGJlY2F1c2UgY2xvc3VyZSBkb2Vzbid0IGRvIGl0IGZvciB1cy5cbiAgICBpZiAoc2FtcGxlICYmIGNvbnRyb2wgJiYgdHlwZW9mIHNhbXBsZS5zdGFjayA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFRoaXMgZXh0cmFjdHMgdGhlIGZpcnN0IGZyYW1lIGZyb20gdGhlIHNhbXBsZSB0aGF0IGlzbid0IGFsc28gaW4gdGhlIGNvbnRyb2wuXG4gICAgICAvLyBTa2lwcGluZyBvbmUgZnJhbWUgdGhhdCB3ZSBhc3N1bWUgaXMgdGhlIGZyYW1lIHRoYXQgY2FsbHMgdGhlIHR3by5cbiAgICAgIHZhciBzYW1wbGVMaW5lcyA9IHNhbXBsZS5zdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICB2YXIgY29udHJvbExpbmVzID0gY29udHJvbC5zdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICB2YXIgcyA9IHNhbXBsZUxpbmVzLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgYyA9IGNvbnRyb2xMaW5lcy5sZW5ndGggLSAxO1xuXG4gICAgICB3aGlsZSAocyA+PSAxICYmIGMgPj0gMCAmJiBzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgIC8vIFdlIGV4cGVjdCBhdCBsZWFzdCBvbmUgc3RhY2sgZnJhbWUgdG8gYmUgc2hhcmVkLlxuICAgICAgICAvLyBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIHRoZSByb290IG1vc3Qgb25lLiBIb3dldmVyLCBzdGFjayBmcmFtZXMgbWF5IGJlXG4gICAgICAgIC8vIGN1dCBvZmYgZHVlIHRvIG1heGltdW0gc3RhY2sgbGltaXRzLiBJbiB0aGlzIGNhc2UsIG9uZSBtYXliZSBjdXQgb2ZmXG4gICAgICAgIC8vIGVhcmxpZXIgdGhhbiB0aGUgb3RoZXIuIFdlIGFzc3VtZSB0aGF0IHRoZSBzYW1wbGUgaXMgbG9uZ2VyIG9yIHRoZSBzYW1lXG4gICAgICAgIC8vIGFuZCB0aGVyZSBmb3IgY3V0IG9mZiBlYXJsaWVyLiBTbyB3ZSBzaG91bGQgZmluZCB0aGUgcm9vdCBtb3N0IGZyYW1lIGluXG4gICAgICAgIC8vIHRoZSBzYW1wbGUgc29tZXdoZXJlIGluIHRoZSBjb250cm9sLlxuICAgICAgICBjLS07XG4gICAgICB9XG5cbiAgICAgIGZvciAoOyBzID49IDEgJiYgYyA+PSAwOyBzLS0sIGMtLSkge1xuICAgICAgICAvLyBOZXh0IHdlIGZpbmQgdGhlIGZpcnN0IG9uZSB0aGF0IGlzbid0IHRoZSBzYW1lIHdoaWNoIHNob3VsZCBiZSB0aGVcbiAgICAgICAgLy8gZnJhbWUgdGhhdCBjYWxsZWQgb3VyIHNhbXBsZSBmdW5jdGlvbiBhbmQgdGhlIGNvbnRyb2wuXG4gICAgICAgIGlmIChzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgICAgLy8gSW4gVjgsIHRoZSBmaXJzdCBsaW5lIGlzIGRlc2NyaWJpbmcgdGhlIG1lc3NhZ2UgYnV0IG90aGVyIFZNcyBkb24ndC5cbiAgICAgICAgICAvLyBJZiB3ZSdyZSBhYm91dCB0byByZXR1cm4gdGhlIGZpcnN0IGxpbmUsIGFuZCB0aGUgY29udHJvbCBpcyBhbHNvIG9uIHRoZSBzYW1lXG4gICAgICAgICAgLy8gbGluZSwgdGhhdCdzIGEgcHJldHR5IGdvb2QgaW5kaWNhdG9yIHRoYXQgb3VyIHNhbXBsZSB0aHJldyBhdCBzYW1lIGxpbmUgYXNcbiAgICAgICAgICAvLyB0aGUgY29udHJvbC4gSS5lLiBiZWZvcmUgd2UgZW50ZXJlZCB0aGUgc2FtcGxlIGZyYW1lLiBTbyB3ZSBpZ25vcmUgdGhpcyByZXN1bHQuXG4gICAgICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIHlvdSBwYXNzZWQgYSBjbGFzcyB0byBmdW5jdGlvbiBjb21wb25lbnQsIG9yIG5vbi1mdW5jdGlvbi5cbiAgICAgICAgICBpZiAocyAhPT0gMSB8fCBjICE9PSAxKSB7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgIHMtLTtcbiAgICAgICAgICAgICAgYy0tOyAvLyBXZSBtYXkgc3RpbGwgaGF2ZSBzaW1pbGFyIGludGVybWVkaWF0ZSBmcmFtZXMgZnJvbSB0aGUgY29uc3RydWN0IGNhbGwuXG4gICAgICAgICAgICAgIC8vIFRoZSBuZXh0IG9uZSB0aGF0IGlzbid0IHRoZSBzYW1lIHNob3VsZCBiZSBvdXIgbWF0Y2ggdGhvdWdoLlxuXG4gICAgICAgICAgICAgIGlmIChjIDwgMCB8fCBzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgICAgICAgICAgLy8gVjggYWRkcyBhIFwibmV3XCIgcHJlZml4IGZvciBuYXRpdmUgY2xhc3Nlcy4gTGV0J3MgcmVtb3ZlIGl0IHRvIG1ha2UgaXQgcHJldHRpZXIuXG4gICAgICAgICAgICAgICAgdmFyIF9mcmFtZSA9ICdcXG4nICsgc2FtcGxlTGluZXNbc10ucmVwbGFjZSgnIGF0IG5ldyAnLCAnIGF0ICcpOyAvLyBJZiBvdXIgY29tcG9uZW50IGZyYW1lIGlzIGxhYmVsZWQgXCI8YW5vbnltb3VzPlwiXG4gICAgICAgICAgICAgICAgLy8gYnV0IHdlIGhhdmUgYSB1c2VyLXByb3ZpZGVkIFwiZGlzcGxheU5hbWVcIlxuICAgICAgICAgICAgICAgIC8vIHNwbGljZSBpdCBpbiB0byBtYWtlIHRoZSBzdGFjayBtb3JlIHJlYWRhYmxlLlxuXG5cbiAgICAgICAgICAgICAgICBpZiAoZm4uZGlzcGxheU5hbWUgJiYgX2ZyYW1lLmluY2x1ZGVzKCc8YW5vbnltb3VzPicpKSB7XG4gICAgICAgICAgICAgICAgICBfZnJhbWUgPSBfZnJhbWUucmVwbGFjZSgnPGFub255bW91cz4nLCBmbi5kaXNwbGF5TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRGcmFtZUNhY2hlLnNldChmbiwgX2ZyYW1lKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IC8vIFJldHVybiB0aGUgbGluZSB3ZSBmb3VuZC5cblxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9mcmFtZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAocyA+PSAxICYmIGMgPj0gMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgcmVlbnRyeSA9IGZhbHNlO1xuXG4gICAge1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2aW91c0Rpc3BhdGNoZXI7XG4gICAgICByZWVuYWJsZUxvZ3MoKTtcbiAgICB9XG5cbiAgICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IHByZXZpb3VzUHJlcGFyZVN0YWNrVHJhY2U7XG4gIH0gLy8gRmFsbGJhY2sgdG8ganVzdCB1c2luZyB0aGUgbmFtZSBpZiB3ZSBjb3VsZG4ndCBtYWtlIGl0IHRocm93LlxuXG5cbiAgdmFyIG5hbWUgPSBmbiA/IGZuLmRpc3BsYXlOYW1lIHx8IGZuLm5hbWUgOiAnJztcbiAgdmFyIHN5bnRoZXRpY0ZyYW1lID0gbmFtZSA/IGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKG5hbWUpIDogJyc7XG5cbiAge1xuICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbXBvbmVudEZyYW1lQ2FjaGUuc2V0KGZuLCBzeW50aGV0aWNGcmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN5bnRoZXRpY0ZyYW1lO1xufVxuZnVuY3Rpb24gZGVzY3JpYmVGdW5jdGlvbkNvbXBvbmVudEZyYW1lKGZuLCBzb3VyY2UsIG93bmVyRm4pIHtcbiAge1xuICAgIHJldHVybiBkZXNjcmliZU5hdGl2ZUNvbXBvbmVudEZyYW1lKGZuLCBmYWxzZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2hvdWxkQ29uc3RydWN0KENvbXBvbmVudCkge1xuICB2YXIgcHJvdG90eXBlID0gQ29tcG9uZW50LnByb3RvdHlwZTtcbiAgcmV0dXJuICEhKHByb3RvdHlwZSAmJiBwcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudCk7XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVih0eXBlLCBzb3VyY2UsIG93bmVyRm4pIHtcblxuICBpZiAodHlwZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAge1xuICAgICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUodHlwZSwgc2hvdWxkQ29uc3RydWN0KHR5cGUpKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKHR5cGUpO1xuICB9XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9UWVBFOlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKCdTdXNwZW5zZScpO1xuXG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEU6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlTGlzdCcpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0Jykge1xuICAgIHN3aXRjaCAodHlwZS4kJHR5cGVvZikge1xuICAgICAgY2FzZSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFOlxuICAgICAgICByZXR1cm4gZGVzY3JpYmVGdW5jdGlvbkNvbXBvbmVudEZyYW1lKHR5cGUucmVuZGVyKTtcblxuICAgICAgY2FzZSBSRUFDVF9NRU1PX1RZUEU6XG4gICAgICAgIC8vIE1lbW8gbWF5IGNvbnRhaW4gYW55IGNvbXBvbmVudCB0eXBlIHNvIHdlIHJlY3Vyc2l2ZWx5IHJlc29sdmUgaXQuXG4gICAgICAgIHJldHVybiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYodHlwZS50eXBlLCBzb3VyY2UsIG93bmVyRm4pO1xuXG4gICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBsYXp5Q29tcG9uZW50ID0gdHlwZTtcbiAgICAgICAgICB2YXIgcGF5bG9hZCA9IGxhenlDb21wb25lbnQuX3BheWxvYWQ7XG4gICAgICAgICAgdmFyIGluaXQgPSBsYXp5Q29tcG9uZW50Ll9pbml0O1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIExhenkgbWF5IGNvbnRhaW4gYW55IGNvbXBvbmVudCB0eXBlIHNvIHdlIHJlY3Vyc2l2ZWx5IHJlc29sdmUgaXQuXG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGluaXQocGF5bG9hZCksIHNvdXJjZSwgb3duZXJGbik7XG4gICAgICAgICAgfSBjYXRjaCAoeCkge31cbiAgICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAnJztcbn1cblxudmFyIGxvZ2dlZFR5cGVGYWlsdXJlcyA9IHt9O1xudmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpIHtcbiAge1xuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgIHZhciBzdGFjayA9IGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihlbGVtZW50LnR5cGUsIGVsZW1lbnQuX3NvdXJjZSwgb3duZXIgPyBvd25lci50eXBlIDogbnVsbCk7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEuc2V0RXh0cmFTdGFja0ZyYW1lKHN0YWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSQxLnNldEV4dHJhU3RhY2tGcmFtZShudWxsKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tQcm9wVHlwZXModHlwZVNwZWNzLCB2YWx1ZXMsIGxvY2F0aW9uLCBjb21wb25lbnROYW1lLCBlbGVtZW50KSB7XG4gIHtcbiAgICAvLyAkRmxvd0ZpeE1lIFRoaXMgaXMgb2theSBidXQgRmxvdyBkb2Vzbid0IGtub3cgaXQuXG4gICAgdmFyIGhhcyA9IEZ1bmN0aW9uLmNhbGwuYmluZChoYXNPd25Qcm9wZXJ0eSk7XG5cbiAgICBmb3IgKHZhciB0eXBlU3BlY05hbWUgaW4gdHlwZVNwZWNzKSB7XG4gICAgICBpZiAoaGFzKHR5cGVTcGVjcywgdHlwZVNwZWNOYW1lKSkge1xuICAgICAgICB2YXIgZXJyb3IkMSA9IHZvaWQgMDsgLy8gUHJvcCB0eXBlIHZhbGlkYXRpb24gbWF5IHRocm93LiBJbiBjYXNlIHRoZXkgZG8sIHdlIGRvbid0IHdhbnQgdG9cbiAgICAgICAgLy8gZmFpbCB0aGUgcmVuZGVyIHBoYXNlIHdoZXJlIGl0IGRpZG4ndCBmYWlsIGJlZm9yZS4gU28gd2UgbG9nIGl0LlxuICAgICAgICAvLyBBZnRlciB0aGVzZSBoYXZlIGJlZW4gY2xlYW5lZCB1cCwgd2UnbGwgbGV0IHRoZW0gdGhyb3cuXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBUaGlzIGlzIGludGVudGlvbmFsbHkgYW4gaW52YXJpYW50IHRoYXQgZ2V0cyBjYXVnaHQuIEl0J3MgdGhlIHNhbWVcbiAgICAgICAgICAvLyBiZWhhdmlvciBhcyB3aXRob3V0IHRoaXMgc3RhdGVtZW50IGV4Y2VwdCB3aXRoIGEgYmV0dGVyIG1lc3NhZ2UuXG4gICAgICAgICAgaWYgKHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcbiAgICAgICAgICAgIHZhciBlcnIgPSBFcnJvcigoY29tcG9uZW50TmFtZSB8fCAnUmVhY3QgY2xhc3MnKSArICc6ICcgKyBsb2NhdGlvbiArICcgdHlwZSBgJyArIHR5cGVTcGVjTmFtZSArICdgIGlzIGludmFsaWQ7ICcgKyAnaXQgbXVzdCBiZSBhIGZ1bmN0aW9uLCB1c3VhbGx5IGZyb20gdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLCBidXQgcmVjZWl2ZWQgYCcgKyB0eXBlb2YgdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0gKyAnYC4nICsgJ1RoaXMgb2Z0ZW4gaGFwcGVucyBiZWNhdXNlIG9mIHR5cG9zIHN1Y2ggYXMgYFByb3BUeXBlcy5mdW5jdGlvbmAgaW5zdGVhZCBvZiBgUHJvcFR5cGVzLmZ1bmNgLicpO1xuICAgICAgICAgICAgZXJyLm5hbWUgPSAnSW52YXJpYW50IFZpb2xhdGlvbic7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZXJyb3IkMSA9IHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdKHZhbHVlcywgdHlwZVNwZWNOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgbnVsbCwgJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJyk7XG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgZXJyb3IkMSA9IGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yJDEgJiYgIShlcnJvciQxIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQoZWxlbWVudCk7XG5cbiAgICAgICAgICBlcnJvcignJXM6IHR5cGUgc3BlY2lmaWNhdGlvbiBvZiAlcycgKyAnIGAlc2AgaXMgaW52YWxpZDsgdGhlIHR5cGUgY2hlY2tlciAnICsgJ2Z1bmN0aW9uIG11c3QgcmV0dXJuIGBudWxsYCBvciBhbiBgRXJyb3JgIGJ1dCByZXR1cm5lZCBhICVzLiAnICsgJ1lvdSBtYXkgaGF2ZSBmb3Jnb3R0ZW4gdG8gcGFzcyBhbiBhcmd1bWVudCB0byB0aGUgdHlwZSBjaGVja2VyICcgKyAnY3JlYXRvciAoYXJyYXlPZiwgaW5zdGFuY2VPZiwgb2JqZWN0T2YsIG9uZU9mLCBvbmVPZlR5cGUsIGFuZCAnICsgJ3NoYXBlIGFsbCByZXF1aXJlIGFuIGFyZ3VtZW50KS4nLCBjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycsIGxvY2F0aW9uLCB0eXBlU3BlY05hbWUsIHR5cGVvZiBlcnJvciQxKTtcblxuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yJDEgaW5zdGFuY2VvZiBFcnJvciAmJiAhKGVycm9yJDEubWVzc2FnZSBpbiBsb2dnZWRUeXBlRmFpbHVyZXMpKSB7XG4gICAgICAgICAgLy8gT25seSBtb25pdG9yIHRoaXMgZmFpbHVyZSBvbmNlIGJlY2F1c2UgdGhlcmUgdGVuZHMgdG8gYmUgYSBsb3Qgb2YgdGhlXG4gICAgICAgICAgLy8gc2FtZSBlcnJvci5cbiAgICAgICAgICBsb2dnZWRUeXBlRmFpbHVyZXNbZXJyb3IkMS5tZXNzYWdlXSA9IHRydWU7XG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQoZWxlbWVudCk7XG5cbiAgICAgICAgICBlcnJvcignRmFpbGVkICVzIHR5cGU6ICVzJywgbG9jYXRpb24sIGVycm9yJDEubWVzc2FnZSk7XG5cbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChudWxsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKGVsZW1lbnQpIHtcbiAge1xuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgIHZhciBzdGFjayA9IGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihlbGVtZW50LnR5cGUsIGVsZW1lbnQuX3NvdXJjZSwgb3duZXIgPyBvd25lci50eXBlIDogbnVsbCk7XG4gICAgICBzZXRFeHRyYVN0YWNrRnJhbWUoc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRFeHRyYVN0YWNrRnJhbWUobnVsbCk7XG4gICAgfVxuICB9XG59XG5cbnZhciBwcm9wVHlwZXNNaXNzcGVsbFdhcm5pbmdTaG93bjtcblxue1xuICBwcm9wVHlwZXNNaXNzcGVsbFdhcm5pbmdTaG93biA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKSB7XG4gIGlmIChSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50KSB7XG4gICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoUmVhY3RDdXJyZW50T3duZXIuY3VycmVudC50eXBlKTtcblxuICAgIGlmIChuYW1lKSB7XG4gICAgICByZXR1cm4gJ1xcblxcbkNoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgbmFtZSArICdgLic7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBnZXRTb3VyY2VJbmZvRXJyb3JBZGRlbmR1bShzb3VyY2UpIHtcbiAgaWYgKHNvdXJjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGZpbGVOYW1lID0gc291cmNlLmZpbGVOYW1lLnJlcGxhY2UoL14uKltcXFxcXFwvXS8sICcnKTtcbiAgICB2YXIgbGluZU51bWJlciA9IHNvdXJjZS5saW5lTnVtYmVyO1xuICAgIHJldHVybiAnXFxuXFxuQ2hlY2sgeW91ciBjb2RlIGF0ICcgKyBmaWxlTmFtZSArICc6JyArIGxpbmVOdW1iZXIgKyAnLic7XG4gIH1cblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtRm9yUHJvcHMoZWxlbWVudFByb3BzKSB7XG4gIGlmIChlbGVtZW50UHJvcHMgIT09IG51bGwgJiYgZWxlbWVudFByb3BzICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZ2V0U291cmNlSW5mb0Vycm9yQWRkZW5kdW0oZWxlbWVudFByb3BzLl9fc291cmNlKTtcbiAgfVxuXG4gIHJldHVybiAnJztcbn1cbi8qKlxuICogV2FybiBpZiB0aGVyZSdzIG5vIGtleSBleHBsaWNpdGx5IHNldCBvbiBkeW5hbWljIGFycmF5cyBvZiBjaGlsZHJlbiBvclxuICogb2JqZWN0IGtleXMgYXJlIG5vdCB2YWxpZC4gVGhpcyBhbGxvd3MgdXMgdG8ga2VlcCB0cmFjayBvZiBjaGlsZHJlbiBiZXR3ZWVuXG4gKiB1cGRhdGVzLlxuICovXG5cblxudmFyIG93bmVySGFzS2V5VXNlV2FybmluZyA9IHt9O1xuXG5mdW5jdGlvbiBnZXRDdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvKHBhcmVudFR5cGUpIHtcbiAgdmFyIGluZm8gPSBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKTtcblxuICBpZiAoIWluZm8pIHtcbiAgICB2YXIgcGFyZW50TmFtZSA9IHR5cGVvZiBwYXJlbnRUeXBlID09PSAnc3RyaW5nJyA/IHBhcmVudFR5cGUgOiBwYXJlbnRUeXBlLmRpc3BsYXlOYW1lIHx8IHBhcmVudFR5cGUubmFtZTtcblxuICAgIGlmIChwYXJlbnROYW1lKSB7XG4gICAgICBpbmZvID0gXCJcXG5cXG5DaGVjayB0aGUgdG9wLWxldmVsIHJlbmRlciBjYWxsIHVzaW5nIDxcIiArIHBhcmVudE5hbWUgKyBcIj4uXCI7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGluZm87XG59XG4vKipcbiAqIFdhcm4gaWYgdGhlIGVsZW1lbnQgZG9lc24ndCBoYXZlIGFuIGV4cGxpY2l0IGtleSBhc3NpZ25lZCB0byBpdC5cbiAqIFRoaXMgZWxlbWVudCBpcyBpbiBhbiBhcnJheS4gVGhlIGFycmF5IGNvdWxkIGdyb3cgYW5kIHNocmluayBvciBiZVxuICogcmVvcmRlcmVkLiBBbGwgY2hpbGRyZW4gdGhhdCBoYXZlbid0IGFscmVhZHkgYmVlbiB2YWxpZGF0ZWQgYXJlIHJlcXVpcmVkIHRvXG4gKiBoYXZlIGEgXCJrZXlcIiBwcm9wZXJ0eSBhc3NpZ25lZCB0byBpdC4gRXJyb3Igc3RhdHVzZXMgYXJlIGNhY2hlZCBzbyBhIHdhcm5pbmdcbiAqIHdpbGwgb25seSBiZSBzaG93biBvbmNlLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnQgRWxlbWVudCB0aGF0IHJlcXVpcmVzIGEga2V5LlxuICogQHBhcmFtIHsqfSBwYXJlbnRUeXBlIGVsZW1lbnQncyBwYXJlbnQncyB0eXBlLlxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVFeHBsaWNpdEtleShlbGVtZW50LCBwYXJlbnRUeXBlKSB7XG4gIGlmICghZWxlbWVudC5fc3RvcmUgfHwgZWxlbWVudC5fc3RvcmUudmFsaWRhdGVkIHx8IGVsZW1lbnQua2V5ICE9IG51bGwpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBlbGVtZW50Ll9zdG9yZS52YWxpZGF0ZWQgPSB0cnVlO1xuICB2YXIgY3VycmVudENvbXBvbmVudEVycm9ySW5mbyA9IGdldEN1cnJlbnRDb21wb25lbnRFcnJvckluZm8ocGFyZW50VHlwZSk7XG5cbiAgaWYgKG93bmVySGFzS2V5VXNlV2FybmluZ1tjdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvXSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIG93bmVySGFzS2V5VXNlV2FybmluZ1tjdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvXSA9IHRydWU7IC8vIFVzdWFsbHkgdGhlIGN1cnJlbnQgb3duZXIgaXMgdGhlIG9mZmVuZGVyLCBidXQgaWYgaXQgYWNjZXB0cyBjaGlsZHJlbiBhcyBhXG4gIC8vIHByb3BlcnR5LCBpdCBtYXkgYmUgdGhlIGNyZWF0b3Igb2YgdGhlIGNoaWxkIHRoYXQncyByZXNwb25zaWJsZSBmb3JcbiAgLy8gYXNzaWduaW5nIGl0IGEga2V5LlxuXG4gIHZhciBjaGlsZE93bmVyID0gJyc7XG5cbiAgaWYgKGVsZW1lbnQgJiYgZWxlbWVudC5fb3duZXIgJiYgZWxlbWVudC5fb3duZXIgIT09IFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQpIHtcbiAgICAvLyBHaXZlIHRoZSBjb21wb25lbnQgdGhhdCBvcmlnaW5hbGx5IGNyZWF0ZWQgdGhpcyBjaGlsZC5cbiAgICBjaGlsZE93bmVyID0gXCIgSXQgd2FzIHBhc3NlZCBhIGNoaWxkIGZyb20gXCIgKyBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoZWxlbWVudC5fb3duZXIudHlwZSkgKyBcIi5cIjtcbiAgfVxuXG4gIHtcbiAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKGVsZW1lbnQpO1xuXG4gICAgZXJyb3IoJ0VhY2ggY2hpbGQgaW4gYSBsaXN0IHNob3VsZCBoYXZlIGEgdW5pcXVlIFwia2V5XCIgcHJvcC4nICsgJyVzJXMgU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay93YXJuaW5nLWtleXMgZm9yIG1vcmUgaW5mb3JtYXRpb24uJywgY3VycmVudENvbXBvbmVudEVycm9ySW5mbywgY2hpbGRPd25lcik7XG5cbiAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKG51bGwpO1xuICB9XG59XG4vKipcbiAqIEVuc3VyZSB0aGF0IGV2ZXJ5IGVsZW1lbnQgZWl0aGVyIGlzIHBhc3NlZCBpbiBhIHN0YXRpYyBsb2NhdGlvbiwgaW4gYW5cbiAqIGFycmF5IHdpdGggYW4gZXhwbGljaXQga2V5cyBwcm9wZXJ0eSBkZWZpbmVkLCBvciBpbiBhbiBvYmplY3QgbGl0ZXJhbFxuICogd2l0aCB2YWxpZCBrZXkgcHJvcGVydHkuXG4gKlxuICogQGludGVybmFsXG4gKiBAcGFyYW0ge1JlYWN0Tm9kZX0gbm9kZSBTdGF0aWNhbGx5IHBhc3NlZCBjaGlsZCBvZiBhbnkgdHlwZS5cbiAqIEBwYXJhbSB7Kn0gcGFyZW50VHlwZSBub2RlJ3MgcGFyZW50J3MgdHlwZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2hpbGRLZXlzKG5vZGUsIHBhcmVudFR5cGUpIHtcbiAgaWYgKHR5cGVvZiBub2RlICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChpc0FycmF5KG5vZGUpKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGQgPSBub2RlW2ldO1xuXG4gICAgICBpZiAoaXNWYWxpZEVsZW1lbnQoY2hpbGQpKSB7XG4gICAgICAgIHZhbGlkYXRlRXhwbGljaXRLZXkoY2hpbGQsIHBhcmVudFR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1ZhbGlkRWxlbWVudChub2RlKSkge1xuICAgIC8vIFRoaXMgZWxlbWVudCB3YXMgcGFzc2VkIGluIGEgdmFsaWQgbG9jYXRpb24uXG4gICAgaWYgKG5vZGUuX3N0b3JlKSB7XG4gICAgICBub2RlLl9zdG9yZS52YWxpZGF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIGlmIChub2RlKSB7XG4gICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKG5vZGUpO1xuXG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBFbnRyeSBpdGVyYXRvcnMgdXNlZCB0byBwcm92aWRlIGltcGxpY2l0IGtleXMsXG4gICAgICAvLyBidXQgbm93IHdlIHByaW50IGEgc2VwYXJhdGUgd2FybmluZyBmb3IgdGhlbSBsYXRlci5cbiAgICAgIGlmIChpdGVyYXRvckZuICE9PSBub2RlLmVudHJpZXMpIHtcbiAgICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKG5vZGUpO1xuICAgICAgICB2YXIgc3RlcDtcblxuICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgaWYgKGlzVmFsaWRFbGVtZW50KHN0ZXAudmFsdWUpKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZUV4cGxpY2l0S2V5KHN0ZXAudmFsdWUsIHBhcmVudFR5cGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBHaXZlbiBhbiBlbGVtZW50LCB2YWxpZGF0ZSB0aGF0IGl0cyBwcm9wcyBmb2xsb3cgdGhlIHByb3BUeXBlcyBkZWZpbml0aW9uLFxuICogcHJvdmlkZWQgYnkgdGhlIHR5cGUuXG4gKlxuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnRcbiAqL1xuXG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcFR5cGVzKGVsZW1lbnQpIHtcbiAge1xuICAgIHZhciB0eXBlID0gZWxlbWVudC50eXBlO1xuXG4gICAgaWYgKHR5cGUgPT09IG51bGwgfHwgdHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBwcm9wVHlwZXM7XG5cbiAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHByb3BUeXBlcyA9IHR5cGUucHJvcFR5cGVzO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnICYmICh0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFIHx8IC8vIE5vdGU6IE1lbW8gb25seSBjaGVja3Mgb3V0ZXIgcHJvcHMgaGVyZS5cbiAgICAvLyBJbm5lciBwcm9wcyBhcmUgY2hlY2tlZCBpbiB0aGUgcmVjb25jaWxlci5cbiAgICB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUpKSB7XG4gICAgICBwcm9wVHlwZXMgPSB0eXBlLnByb3BUeXBlcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwcm9wVHlwZXMpIHtcbiAgICAgIC8vIEludGVudGlvbmFsbHkgaW5zaWRlIHRvIGF2b2lkIHRyaWdnZXJpbmcgbGF6eSBpbml0aWFsaXplcnM6XG4gICAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKTtcbiAgICAgIGNoZWNrUHJvcFR5cGVzKHByb3BUeXBlcywgZWxlbWVudC5wcm9wcywgJ3Byb3AnLCBuYW1lLCBlbGVtZW50KTtcbiAgICB9IGVsc2UgaWYgKHR5cGUuUHJvcFR5cGVzICE9PSB1bmRlZmluZWQgJiYgIXByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duKSB7XG4gICAgICBwcm9wVHlwZXNNaXNzcGVsbFdhcm5pbmdTaG93biA9IHRydWU7IC8vIEludGVudGlvbmFsbHkgaW5zaWRlIHRvIGF2b2lkIHRyaWdnZXJpbmcgbGF6eSBpbml0aWFsaXplcnM6XG5cbiAgICAgIHZhciBfbmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKTtcblxuICAgICAgZXJyb3IoJ0NvbXBvbmVudCAlcyBkZWNsYXJlZCBgUHJvcFR5cGVzYCBpbnN0ZWFkIG9mIGBwcm9wVHlwZXNgLiBEaWQgeW91IG1pc3NwZWxsIHRoZSBwcm9wZXJ0eSBhc3NpZ25tZW50PycsIF9uYW1lIHx8ICdVbmtub3duJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0eXBlLmdldERlZmF1bHRQcm9wcyA9PT0gJ2Z1bmN0aW9uJyAmJiAhdHlwZS5nZXREZWZhdWx0UHJvcHMuaXNSZWFjdENsYXNzQXBwcm92ZWQpIHtcbiAgICAgIGVycm9yKCdnZXREZWZhdWx0UHJvcHMgaXMgb25seSB1c2VkIG9uIGNsYXNzaWMgUmVhY3QuY3JlYXRlQ2xhc3MgJyArICdkZWZpbml0aW9ucy4gVXNlIGEgc3RhdGljIHByb3BlcnR5IG5hbWVkIGBkZWZhdWx0UHJvcHNgIGluc3RlYWQuJyk7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEdpdmVuIGEgZnJhZ21lbnQsIHZhbGlkYXRlIHRoYXQgaXQgY2FuIG9ubHkgYmUgcHJvdmlkZWQgd2l0aCBmcmFnbWVudCBwcm9wc1xuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGZyYWdtZW50XG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZUZyYWdtZW50UHJvcHMoZnJhZ21lbnQpIHtcbiAge1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZnJhZ21lbnQucHJvcHMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIga2V5ID0ga2V5c1tpXTtcblxuICAgICAgaWYgKGtleSAhPT0gJ2NoaWxkcmVuJyAmJiBrZXkgIT09ICdrZXknKSB7XG4gICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZnJhZ21lbnQpO1xuXG4gICAgICAgIGVycm9yKCdJbnZhbGlkIHByb3AgYCVzYCBzdXBwbGllZCB0byBgUmVhY3QuRnJhZ21lbnRgLiAnICsgJ1JlYWN0LkZyYWdtZW50IGNhbiBvbmx5IGhhdmUgYGtleWAgYW5kIGBjaGlsZHJlbmAgcHJvcHMuJywga2V5KTtcblxuICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKG51bGwpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZnJhZ21lbnQucmVmICE9PSBudWxsKSB7XG4gICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKGZyYWdtZW50KTtcblxuICAgICAgZXJyb3IoJ0ludmFsaWQgYXR0cmlidXRlIGByZWZgIHN1cHBsaWVkIHRvIGBSZWFjdC5GcmFnbWVudGAuJyk7XG5cbiAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEobnVsbCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50V2l0aFZhbGlkYXRpb24odHlwZSwgcHJvcHMsIGNoaWxkcmVuKSB7XG4gIHZhciB2YWxpZFR5cGUgPSBpc1ZhbGlkRWxlbWVudFR5cGUodHlwZSk7IC8vIFdlIHdhcm4gaW4gdGhpcyBjYXNlIGJ1dCBkb24ndCB0aHJvdy4gV2UgZXhwZWN0IHRoZSBlbGVtZW50IGNyZWF0aW9uIHRvXG4gIC8vIHN1Y2NlZWQgYW5kIHRoZXJlIHdpbGwgbGlrZWx5IGJlIGVycm9ycyBpbiByZW5kZXIuXG5cbiAgaWYgKCF2YWxpZFR5cGUpIHtcbiAgICB2YXIgaW5mbyA9ICcnO1xuXG4gICAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gbnVsbCAmJiBPYmplY3Qua2V5cyh0eXBlKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGluZm8gKz0gJyBZb3UgbGlrZWx5IGZvcmdvdCB0byBleHBvcnQgeW91ciBjb21wb25lbnQgZnJvbSB0aGUgZmlsZSAnICsgXCJpdCdzIGRlZmluZWQgaW4sIG9yIHlvdSBtaWdodCBoYXZlIG1peGVkIHVwIGRlZmF1bHQgYW5kIG5hbWVkIGltcG9ydHMuXCI7XG4gICAgfVxuXG4gICAgdmFyIHNvdXJjZUluZm8gPSBnZXRTb3VyY2VJbmZvRXJyb3JBZGRlbmR1bUZvclByb3BzKHByb3BzKTtcblxuICAgIGlmIChzb3VyY2VJbmZvKSB7XG4gICAgICBpbmZvICs9IHNvdXJjZUluZm87XG4gICAgfSBlbHNlIHtcbiAgICAgIGluZm8gKz0gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCk7XG4gICAgfVxuXG4gICAgdmFyIHR5cGVTdHJpbmc7XG5cbiAgICBpZiAodHlwZSA9PT0gbnVsbCkge1xuICAgICAgdHlwZVN0cmluZyA9ICdudWxsJztcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkodHlwZSkpIHtcbiAgICAgIHR5cGVTdHJpbmcgPSAnYXJyYXknO1xuICAgIH0gZWxzZSBpZiAodHlwZSAhPT0gdW5kZWZpbmVkICYmIHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0VMRU1FTlRfVFlQRSkge1xuICAgICAgdHlwZVN0cmluZyA9IFwiPFwiICsgKGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlLnR5cGUpIHx8ICdVbmtub3duJykgKyBcIiAvPlwiO1xuICAgICAgaW5mbyA9ICcgRGlkIHlvdSBhY2NpZGVudGFsbHkgZXhwb3J0IGEgSlNYIGxpdGVyYWwgaW5zdGVhZCBvZiBhIGNvbXBvbmVudD8nO1xuICAgIH0gZWxzZSB7XG4gICAgICB0eXBlU3RyaW5nID0gdHlwZW9mIHR5cGU7XG4gICAgfVxuXG4gICAge1xuICAgICAgZXJyb3IoJ1JlYWN0LmNyZWF0ZUVsZW1lbnQ6IHR5cGUgaXMgaW52YWxpZCAtLSBleHBlY3RlZCBhIHN0cmluZyAoZm9yICcgKyAnYnVpbHQtaW4gY29tcG9uZW50cykgb3IgYSBjbGFzcy9mdW5jdGlvbiAoZm9yIGNvbXBvc2l0ZSAnICsgJ2NvbXBvbmVudHMpIGJ1dCBnb3Q6ICVzLiVzJywgdHlwZVN0cmluZywgaW5mbyk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGVsZW1lbnQgPSBjcmVhdGVFbGVtZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IC8vIFRoZSByZXN1bHQgY2FuIGJlIG51bGxpc2ggaWYgYSBtb2NrIG9yIGEgY3VzdG9tIGZ1bmN0aW9uIGlzIHVzZWQuXG4gIC8vIFRPRE86IERyb3AgdGhpcyB3aGVuIHRoZXNlIGFyZSBubyBsb25nZXIgYWxsb3dlZCBhcyB0aGUgdHlwZSBhcmd1bWVudC5cblxuICBpZiAoZWxlbWVudCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH0gLy8gU2tpcCBrZXkgd2FybmluZyBpZiB0aGUgdHlwZSBpc24ndCB2YWxpZCBzaW5jZSBvdXIga2V5IHZhbGlkYXRpb24gbG9naWNcbiAgLy8gZG9lc24ndCBleHBlY3QgYSBub24tc3RyaW5nL2Z1bmN0aW9uIHR5cGUgYW5kIGNhbiB0aHJvdyBjb25mdXNpbmcgZXJyb3JzLlxuICAvLyBXZSBkb24ndCB3YW50IGV4Y2VwdGlvbiBiZWhhdmlvciB0byBkaWZmZXIgYmV0d2VlbiBkZXYgYW5kIHByb2QuXG4gIC8vIChSZW5kZXJpbmcgd2lsbCB0aHJvdyB3aXRoIGEgaGVscGZ1bCBtZXNzYWdlIGFuZCBhcyBzb29uIGFzIHRoZSB0eXBlIGlzXG4gIC8vIGZpeGVkLCB0aGUga2V5IHdhcm5pbmdzIHdpbGwgYXBwZWFyLilcblxuXG4gIGlmICh2YWxpZFR5cGUpIHtcbiAgICBmb3IgKHZhciBpID0gMjsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFsaWRhdGVDaGlsZEtleXMoYXJndW1lbnRzW2ldLCB0eXBlKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSkge1xuICAgIHZhbGlkYXRlRnJhZ21lbnRQcm9wcyhlbGVtZW50KTtcbiAgfSBlbHNlIHtcbiAgICB2YWxpZGF0ZVByb3BUeXBlcyhlbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufVxudmFyIGRpZFdhcm5BYm91dERlcHJlY2F0ZWRDcmVhdGVGYWN0b3J5ID0gZmFsc2U7XG5mdW5jdGlvbiBjcmVhdGVGYWN0b3J5V2l0aFZhbGlkYXRpb24odHlwZSkge1xuICB2YXIgdmFsaWRhdGVkRmFjdG9yeSA9IGNyZWF0ZUVsZW1lbnRXaXRoVmFsaWRhdGlvbi5iaW5kKG51bGwsIHR5cGUpO1xuICB2YWxpZGF0ZWRGYWN0b3J5LnR5cGUgPSB0eXBlO1xuXG4gIHtcbiAgICBpZiAoIWRpZFdhcm5BYm91dERlcHJlY2F0ZWRDcmVhdGVGYWN0b3J5KSB7XG4gICAgICBkaWRXYXJuQWJvdXREZXByZWNhdGVkQ3JlYXRlRmFjdG9yeSA9IHRydWU7XG5cbiAgICAgIHdhcm4oJ1JlYWN0LmNyZWF0ZUZhY3RvcnkoKSBpcyBkZXByZWNhdGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gJyArICdhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiBDb25zaWRlciB1c2luZyBKU1ggJyArICdvciB1c2UgUmVhY3QuY3JlYXRlRWxlbWVudCgpIGRpcmVjdGx5IGluc3RlYWQuJyk7XG4gICAgfSAvLyBMZWdhY3kgaG9vazogcmVtb3ZlIGl0XG5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh2YWxpZGF0ZWRGYWN0b3J5LCAndHlwZScsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhcm4oJ0ZhY3RvcnkudHlwZSBpcyBkZXByZWNhdGVkLiBBY2Nlc3MgdGhlIGNsYXNzIGRpcmVjdGx5ICcgKyAnYmVmb3JlIHBhc3NpbmcgaXQgdG8gY3JlYXRlRmFjdG9yeS4nKTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3R5cGUnLCB7XG4gICAgICAgICAgdmFsdWU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0eXBlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHZhbGlkYXRlZEZhY3Rvcnk7XG59XG5mdW5jdGlvbiBjbG9uZUVsZW1lbnRXaXRoVmFsaWRhdGlvbihlbGVtZW50LCBwcm9wcywgY2hpbGRyZW4pIHtcbiAgdmFyIG5ld0VsZW1lbnQgPSBjbG9uZUVsZW1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICBmb3IgKHZhciBpID0gMjsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhbGlkYXRlQ2hpbGRLZXlzKGFyZ3VtZW50c1tpXSwgbmV3RWxlbWVudC50eXBlKTtcbiAgfVxuXG4gIHZhbGlkYXRlUHJvcFR5cGVzKG5ld0VsZW1lbnQpO1xuICByZXR1cm4gbmV3RWxlbWVudDtcbn1cblxuZnVuY3Rpb24gc3RhcnRUcmFuc2l0aW9uKHNjb3BlLCBvcHRpb25zKSB7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSB7fTtcbiAgdmFyIGN1cnJlbnRUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbjtcblxuICB7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycyA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgc2NvcGUoKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG5cbiAgICB7XG4gICAgICBpZiAocHJldlRyYW5zaXRpb24gPT09IG51bGwgJiYgY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMpIHtcbiAgICAgICAgdmFyIHVwZGF0ZWRGaWJlcnNDb3VudCA9IGN1cnJlbnRUcmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLnNpemU7XG5cbiAgICAgICAgaWYgKHVwZGF0ZWRGaWJlcnNDb3VudCA+IDEwKSB7XG4gICAgICAgICAgd2FybignRGV0ZWN0ZWQgYSBsYXJnZSBudW1iZXIgb2YgdXBkYXRlcyBpbnNpZGUgc3RhcnRUcmFuc2l0aW9uLiAnICsgJ0lmIHRoaXMgaXMgZHVlIHRvIGEgc3Vic2NyaXB0aW9uIHBsZWFzZSByZS13cml0ZSBpdCB0byB1c2UgUmVhY3QgcHJvdmlkZWQgaG9va3MuICcgKyAnT3RoZXJ3aXNlIGNvbmN1cnJlbnQgbW9kZSBndWFyYW50ZWVzIGFyZSBvZmYgdGhlIHRhYmxlLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMuY2xlYXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIGRpZFdhcm5BYm91dE1lc3NhZ2VDaGFubmVsID0gZmFsc2U7XG52YXIgZW5xdWV1ZVRhc2tJbXBsID0gbnVsbDtcbmZ1bmN0aW9uIGVucXVldWVUYXNrKHRhc2spIHtcbiAgaWYgKGVucXVldWVUYXNrSW1wbCA9PT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICAvLyByZWFkIHJlcXVpcmUgb2ZmIHRoZSBtb2R1bGUgb2JqZWN0IHRvIGdldCBhcm91bmQgdGhlIGJ1bmRsZXJzLlxuICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0aGVtIHRvIGRldGVjdCBhIHJlcXVpcmUgYW5kIGJ1bmRsZSBhIE5vZGUgcG9seWZpbGwuXG4gICAgICB2YXIgcmVxdWlyZVN0cmluZyA9ICgncmVxdWlyZScgKyBNYXRoLnJhbmRvbSgpKS5zbGljZSgwLCA3KTtcbiAgICAgIHZhciBub2RlUmVxdWlyZSA9IG1vZHVsZSAmJiBtb2R1bGVbcmVxdWlyZVN0cmluZ107IC8vIGFzc3VtaW5nIHdlJ3JlIGluIG5vZGUsIGxldCdzIHRyeSB0byBnZXQgbm9kZSdzXG4gICAgICAvLyB2ZXJzaW9uIG9mIHNldEltbWVkaWF0ZSwgYnlwYXNzaW5nIGZha2UgdGltZXJzIGlmIGFueS5cblxuICAgICAgZW5xdWV1ZVRhc2tJbXBsID0gbm9kZVJlcXVpcmUuY2FsbChtb2R1bGUsICd0aW1lcnMnKS5zZXRJbW1lZGlhdGU7XG4gICAgfSBjYXRjaCAoX2Vycikge1xuICAgICAgLy8gd2UncmUgaW4gYSBicm93c2VyXG4gICAgICAvLyB3ZSBjYW4ndCB1c2UgcmVndWxhciB0aW1lcnMgYmVjYXVzZSB0aGV5IG1heSBzdGlsbCBiZSBmYWtlZFxuICAgICAgLy8gc28gd2UgdHJ5IE1lc3NhZ2VDaGFubmVsK3Bvc3RNZXNzYWdlIGluc3RlYWRcbiAgICAgIGVucXVldWVUYXNrSW1wbCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKGRpZFdhcm5BYm91dE1lc3NhZ2VDaGFubmVsID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZGlkV2FybkFib3V0TWVzc2FnZUNoYW5uZWwgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICBlcnJvcignVGhpcyBicm93c2VyIGRvZXMgbm90IGhhdmUgYSBNZXNzYWdlQ2hhbm5lbCBpbXBsZW1lbnRhdGlvbiwgJyArICdzbyBlbnF1ZXVpbmcgdGFza3MgdmlhIGF3YWl0IGFjdChhc3luYyAoKSA9PiAuLi4pIHdpbGwgZmFpbC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZSBhdCBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzICcgKyAnaWYgeW91IGVuY291bnRlciB0aGlzIHdhcm5pbmcuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBjYWxsYmFjaztcbiAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSh1bmRlZmluZWQpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5xdWV1ZVRhc2tJbXBsKHRhc2spO1xufVxuXG52YXIgYWN0U2NvcGVEZXB0aCA9IDA7XG52YXIgZGlkV2Fybk5vQXdhaXRBY3QgPSBmYWxzZTtcbmZ1bmN0aW9uIGFjdChjYWxsYmFjaykge1xuICB7XG4gICAgLy8gYGFjdGAgY2FsbHMgY2FuIGJlIG5lc3RlZCwgc28gd2UgdHJhY2sgdGhlIGRlcHRoLiBUaGlzIHJlcHJlc2VudHMgdGhlXG4gICAgLy8gbnVtYmVyIG9mIGBhY3RgIHNjb3BlcyBvbiB0aGUgc3RhY2suXG4gICAgdmFyIHByZXZBY3RTY29wZURlcHRoID0gYWN0U2NvcGVEZXB0aDtcbiAgICBhY3RTY29wZURlcHRoKys7XG5cbiAgICBpZiAoUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyBpcyB0aGUgb3V0ZXJtb3N0IGBhY3RgIHNjb3BlLiBJbml0aWFsaXplIHRoZSBxdWV1ZS4gVGhlIHJlY29uY2lsZXJcbiAgICAgIC8vIHdpbGwgZGV0ZWN0IHRoZSBxdWV1ZSBhbmQgdXNlIGl0IGluc3RlYWQgb2YgU2NoZWR1bGVyLlxuICAgICAgUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCA9IFtdO1xuICAgIH1cblxuICAgIHZhciBwcmV2SXNCYXRjaGluZ0xlZ2FjeSA9IFJlYWN0Q3VycmVudEFjdFF1ZXVlLmlzQmF0Y2hpbmdMZWdhY3k7XG4gICAgdmFyIHJlc3VsdDtcblxuICAgIHRyeSB7XG4gICAgICAvLyBVc2VkIHRvIHJlcHJvZHVjZSBiZWhhdmlvciBvZiBgYmF0Y2hlZFVwZGF0ZXNgIGluIGxlZ2FjeSBtb2RlLiBPbmx5XG4gICAgICAvLyBzZXQgdG8gYHRydWVgIHdoaWxlIHRoZSBnaXZlbiBjYWxsYmFjayBpcyBleGVjdXRlZCwgbm90IGZvciB1cGRhdGVzXG4gICAgICAvLyB0cmlnZ2VyZWQgZHVyaW5nIGFuIGFzeW5jIGV2ZW50LCBiZWNhdXNlIHRoaXMgaXMgaG93IHRoZSBsZWdhY3lcbiAgICAgIC8vIGltcGxlbWVudGF0aW9uIG9mIGBhY3RgIGJlaGF2ZWQuXG4gICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5pc0JhdGNoaW5nTGVnYWN5ID0gdHJ1ZTtcbiAgICAgIHJlc3VsdCA9IGNhbGxiYWNrKCk7IC8vIFJlcGxpY2F0ZSBiZWhhdmlvciBvZiBvcmlnaW5hbCBgYWN0YCBpbXBsZW1lbnRhdGlvbiBpbiBsZWdhY3kgbW9kZSxcbiAgICAgIC8vIHdoaWNoIGZsdXNoZWQgdXBkYXRlcyBpbW1lZGlhdGVseSBhZnRlciB0aGUgc2NvcGUgZnVuY3Rpb24gZXhpdHMsIGV2ZW5cbiAgICAgIC8vIGlmIGl0J3MgYW4gYXN5bmMgZnVuY3Rpb24uXG5cbiAgICAgIGlmICghcHJldklzQmF0Y2hpbmdMZWdhY3kgJiYgUmVhY3RDdXJyZW50QWN0UXVldWUuZGlkU2NoZWR1bGVMZWdhY3lVcGRhdGUpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudDtcblxuICAgICAgICBpZiAocXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5kaWRTY2hlZHVsZUxlZ2FjeVVwZGF0ZSA9IGZhbHNlO1xuICAgICAgICAgIGZsdXNoQWN0UXVldWUocXVldWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHBvcEFjdFNjb3BlKHByZXZBY3RTY29wZURlcHRoKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5pc0JhdGNoaW5nTGVnYWN5ID0gcHJldklzQmF0Y2hpbmdMZWdhY3k7XG4gICAgfVxuXG4gICAgaWYgKHJlc3VsdCAhPT0gbnVsbCAmJiB0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciB0aGVuYWJsZVJlc3VsdCA9IHJlc3VsdDsgLy8gVGhlIGNhbGxiYWNrIGlzIGFuIGFzeW5jIGZ1bmN0aW9uIChpLmUuIHJldHVybmVkIGEgcHJvbWlzZSkuIFdhaXRcbiAgICAgIC8vIGZvciBpdCB0byByZXNvbHZlIGJlZm9yZSBleGl0aW5nIHRoZSBjdXJyZW50IHNjb3BlLlxuXG4gICAgICB2YXIgd2FzQXdhaXRlZCA9IGZhbHNlO1xuICAgICAgdmFyIHRoZW5hYmxlID0ge1xuICAgICAgICB0aGVuOiBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgd2FzQXdhaXRlZCA9IHRydWU7XG4gICAgICAgICAgdGhlbmFibGVSZXN1bHQudGhlbihmdW5jdGlvbiAocmV0dXJuVmFsdWUpIHtcbiAgICAgICAgICAgIHBvcEFjdFNjb3BlKHByZXZBY3RTY29wZURlcHRoKTtcblxuICAgICAgICAgICAgaWYgKGFjdFNjb3BlRGVwdGggPT09IDApIHtcbiAgICAgICAgICAgICAgLy8gV2UndmUgZXhpdGVkIHRoZSBvdXRlcm1vc3QgYWN0IHNjb3BlLiBSZWN1cnNpdmVseSBmbHVzaCB0aGVcbiAgICAgICAgICAgICAgLy8gcXVldWUgdW50aWwgdGhlcmUncyBubyByZW1haW5pbmcgd29yay5cbiAgICAgICAgICAgICAgcmVjdXJzaXZlbHlGbHVzaEFzeW5jQWN0V29yayhyZXR1cm5WYWx1ZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc29sdmUocmV0dXJuVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgLy8gVGhlIGNhbGxiYWNrIHRocmV3IGFuIGVycm9yLlxuICAgICAgICAgICAgcG9wQWN0U2NvcGUocHJldkFjdFNjb3BlRGVwdGgpO1xuICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAge1xuICAgICAgICBpZiAoIWRpZFdhcm5Ob0F3YWl0QWN0ICYmIHR5cGVvZiBQcm9taXNlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge30pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF3YXNBd2FpdGVkKSB7XG4gICAgICAgICAgICAgIGRpZFdhcm5Ob0F3YWl0QWN0ID0gdHJ1ZTtcblxuICAgICAgICAgICAgICBlcnJvcignWW91IGNhbGxlZCBhY3QoYXN5bmMgKCkgPT4gLi4uKSB3aXRob3V0IGF3YWl0LiAnICsgJ1RoaXMgY291bGQgbGVhZCB0byB1bmV4cGVjdGVkIHRlc3RpbmcgYmVoYXZpb3VyLCAnICsgJ2ludGVybGVhdmluZyBtdWx0aXBsZSBhY3QgY2FsbHMgYW5kIG1peGluZyB0aGVpciAnICsgJ3Njb3Blcy4gJyArICdZb3Ugc2hvdWxkIC0gYXdhaXQgYWN0KGFzeW5jICgpID0+IC4uLik7Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoZW5hYmxlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcmV0dXJuVmFsdWUgPSByZXN1bHQ7IC8vIFRoZSBjYWxsYmFjayBpcyBub3QgYW4gYXN5bmMgZnVuY3Rpb24uIEV4aXQgdGhlIGN1cnJlbnQgc2NvcGVcbiAgICAgIC8vIGltbWVkaWF0ZWx5LCB3aXRob3V0IGF3YWl0aW5nLlxuXG4gICAgICBwb3BBY3RTY29wZShwcmV2QWN0U2NvcGVEZXB0aCk7XG5cbiAgICAgIGlmIChhY3RTY29wZURlcHRoID09PSAwKSB7XG4gICAgICAgIC8vIEV4aXRpbmcgdGhlIG91dGVybW9zdCBhY3Qgc2NvcGUuIEZsdXNoIHRoZSBxdWV1ZS5cbiAgICAgICAgdmFyIF9xdWV1ZSA9IFJlYWN0Q3VycmVudEFjdFF1ZXVlLmN1cnJlbnQ7XG5cbiAgICAgICAgaWYgKF9xdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGZsdXNoQWN0UXVldWUoX3F1ZXVlKTtcbiAgICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgfSAvLyBSZXR1cm4gYSB0aGVuYWJsZS4gSWYgdGhlIHVzZXIgYXdhaXRzIGl0LCB3ZSdsbCBmbHVzaCBhZ2FpbiBpblxuICAgICAgICAvLyBjYXNlIGFkZGl0aW9uYWwgd29yayB3YXMgc2NoZWR1bGVkIGJ5IGEgbWljcm90YXNrLlxuXG5cbiAgICAgICAgdmFyIF90aGVuYWJsZSA9IHtcbiAgICAgICAgICB0aGVuOiBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICAvLyBDb25maXJtIHdlIGhhdmVuJ3QgcmUtZW50ZXJlZCBhbm90aGVyIGBhY3RgIHNjb3BlLCBpbiBjYXNlXG4gICAgICAgICAgICAvLyB0aGUgdXNlciBkb2VzIHNvbWV0aGluZyB3ZWlyZCBsaWtlIGF3YWl0IHRoZSB0aGVuYWJsZVxuICAgICAgICAgICAgLy8gbXVsdGlwbGUgdGltZXMuXG4gICAgICAgICAgICBpZiAoUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBmbHVzaCB0aGUgcXVldWUgdW50aWwgdGhlcmUncyBubyByZW1haW5pbmcgd29yay5cbiAgICAgICAgICAgICAgUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCA9IFtdO1xuICAgICAgICAgICAgICByZWN1cnNpdmVseUZsdXNoQXN5bmNBY3RXb3JrKHJldHVyblZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXR1cm5WYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gX3RoZW5hYmxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU2luY2Ugd2UncmUgaW5zaWRlIGEgbmVzdGVkIGBhY3RgIHNjb3BlLCB0aGUgcmV0dXJuZWQgdGhlbmFibGVcbiAgICAgICAgLy8gaW1tZWRpYXRlbHkgcmVzb2x2ZXMuIFRoZSBvdXRlciBzY29wZSB3aWxsIGZsdXNoIHRoZSBxdWV1ZS5cbiAgICAgICAgdmFyIF90aGVuYWJsZTIgPSB7XG4gICAgICAgICAgdGhlbjogZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXR1cm5WYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gX3RoZW5hYmxlMjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9wQWN0U2NvcGUocHJldkFjdFNjb3BlRGVwdGgpIHtcbiAge1xuICAgIGlmIChwcmV2QWN0U2NvcGVEZXB0aCAhPT0gYWN0U2NvcGVEZXB0aCAtIDEpIHtcbiAgICAgIGVycm9yKCdZb3Ugc2VlbSB0byBoYXZlIG92ZXJsYXBwaW5nIGFjdCgpIGNhbGxzLCB0aGlzIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnQmUgc3VyZSB0byBhd2FpdCBwcmV2aW91cyBhY3QoKSBjYWxscyBiZWZvcmUgbWFraW5nIGEgbmV3IG9uZS4gJyk7XG4gICAgfVxuXG4gICAgYWN0U2NvcGVEZXB0aCA9IHByZXZBY3RTY29wZURlcHRoO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZWx5Rmx1c2hBc3luY0FjdFdvcmsocmV0dXJuVmFsdWUsIHJlc29sdmUsIHJlamVjdCkge1xuICB7XG4gICAgdmFyIHF1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudDtcblxuICAgIGlmIChxdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZmx1c2hBY3RRdWV1ZShxdWV1ZSk7XG4gICAgICAgIGVucXVldWVUYXNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBObyBhZGRpdGlvbmFsIHdvcmsgd2FzIHNjaGVkdWxlZC4gRmluaXNoLlxuICAgICAgICAgICAgUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCA9IG51bGw7XG4gICAgICAgICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gS2VlcCBmbHVzaGluZyB3b3JrIHVudGlsIHRoZXJlJ3Mgbm9uZSBsZWZ0LlxuICAgICAgICAgICAgcmVjdXJzaXZlbHlGbHVzaEFzeW5jQWN0V29yayhyZXR1cm5WYWx1ZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzb2x2ZShyZXR1cm5WYWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbnZhciBpc0ZsdXNoaW5nID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGZsdXNoQWN0UXVldWUocXVldWUpIHtcbiAge1xuICAgIGlmICghaXNGbHVzaGluZykge1xuICAgICAgLy8gUHJldmVudCByZS1lbnRyYW5jZS5cbiAgICAgIGlzRmx1c2hpbmcgPSB0cnVlO1xuICAgICAgdmFyIGkgPSAwO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGNhbGxiYWNrID0gcXVldWVbaV07XG5cbiAgICAgICAgICBkbyB7XG4gICAgICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrKHRydWUpO1xuICAgICAgICAgIH0gd2hpbGUgKGNhbGxiYWNrICE9PSBudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHF1ZXVlLmxlbmd0aCA9IDA7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBJZiBzb21ldGhpbmcgdGhyb3dzLCBsZWF2ZSB0aGUgcmVtYWluaW5nIGNhbGxiYWNrcyBvbiB0aGUgcXVldWUuXG4gICAgICAgIHF1ZXVlID0gcXVldWUuc2xpY2UoaSArIDEpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlzRmx1c2hpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIGNyZWF0ZUVsZW1lbnQkMSA9ICBjcmVhdGVFbGVtZW50V2l0aFZhbGlkYXRpb24gO1xudmFyIGNsb25lRWxlbWVudCQxID0gIGNsb25lRWxlbWVudFdpdGhWYWxpZGF0aW9uIDtcbnZhciBjcmVhdGVGYWN0b3J5ID0gIGNyZWF0ZUZhY3RvcnlXaXRoVmFsaWRhdGlvbiA7XG52YXIgQ2hpbGRyZW4gPSB7XG4gIG1hcDogbWFwQ2hpbGRyZW4sXG4gIGZvckVhY2g6IGZvckVhY2hDaGlsZHJlbixcbiAgY291bnQ6IGNvdW50Q2hpbGRyZW4sXG4gIHRvQXJyYXk6IHRvQXJyYXksXG4gIG9ubHk6IG9ubHlDaGlsZFxufTtcblxuZXhwb3J0cy5DaGlsZHJlbiA9IENoaWxkcmVuO1xuZXhwb3J0cy5Db21wb25lbnQgPSBDb21wb25lbnQ7XG5leHBvcnRzLkZyYWdtZW50ID0gUkVBQ1RfRlJBR01FTlRfVFlQRTtcbmV4cG9ydHMuUHJvZmlsZXIgPSBSRUFDVF9QUk9GSUxFUl9UWVBFO1xuZXhwb3J0cy5QdXJlQ29tcG9uZW50ID0gUHVyZUNvbXBvbmVudDtcbmV4cG9ydHMuU3RyaWN0TW9kZSA9IFJFQUNUX1NUUklDVF9NT0RFX1RZUEU7XG5leHBvcnRzLlN1c3BlbnNlID0gUkVBQ1RfU1VTUEVOU0VfVFlQRTtcbmV4cG9ydHMuX19TRUNSRVRfSU5URVJOQUxTX0RPX05PVF9VU0VfT1JfWU9VX1dJTExfQkVfRklSRUQgPSBSZWFjdFNoYXJlZEludGVybmFscztcbmV4cG9ydHMuY2xvbmVFbGVtZW50ID0gY2xvbmVFbGVtZW50JDE7XG5leHBvcnRzLmNyZWF0ZUNvbnRleHQgPSBjcmVhdGVDb250ZXh0O1xuZXhwb3J0cy5jcmVhdGVFbGVtZW50ID0gY3JlYXRlRWxlbWVudCQxO1xuZXhwb3J0cy5jcmVhdGVGYWN0b3J5ID0gY3JlYXRlRmFjdG9yeTtcbmV4cG9ydHMuY3JlYXRlUmVmID0gY3JlYXRlUmVmO1xuZXhwb3J0cy5mb3J3YXJkUmVmID0gZm9yd2FyZFJlZjtcbmV4cG9ydHMuaXNWYWxpZEVsZW1lbnQgPSBpc1ZhbGlkRWxlbWVudDtcbmV4cG9ydHMubGF6eSA9IGxhenk7XG5leHBvcnRzLm1lbW8gPSBtZW1vO1xuZXhwb3J0cy5zdGFydFRyYW5zaXRpb24gPSBzdGFydFRyYW5zaXRpb247XG5leHBvcnRzLnVuc3RhYmxlX2FjdCA9IGFjdDtcbmV4cG9ydHMudXNlQ2FsbGJhY2sgPSB1c2VDYWxsYmFjaztcbmV4cG9ydHMudXNlQ29udGV4dCA9IHVzZUNvbnRleHQ7XG5leHBvcnRzLnVzZURlYnVnVmFsdWUgPSB1c2VEZWJ1Z1ZhbHVlO1xuZXhwb3J0cy51c2VEZWZlcnJlZFZhbHVlID0gdXNlRGVmZXJyZWRWYWx1ZTtcbmV4cG9ydHMudXNlRWZmZWN0ID0gdXNlRWZmZWN0O1xuZXhwb3J0cy51c2VJZCA9IHVzZUlkO1xuZXhwb3J0cy51c2VJbXBlcmF0aXZlSGFuZGxlID0gdXNlSW1wZXJhdGl2ZUhhbmRsZTtcbmV4cG9ydHMudXNlSW5zZXJ0aW9uRWZmZWN0ID0gdXNlSW5zZXJ0aW9uRWZmZWN0O1xuZXhwb3J0cy51c2VMYXlvdXRFZmZlY3QgPSB1c2VMYXlvdXRFZmZlY3Q7XG5leHBvcnRzLnVzZU1lbW8gPSB1c2VNZW1vO1xuZXhwb3J0cy51c2VSZWR1Y2VyID0gdXNlUmVkdWNlcjtcbmV4cG9ydHMudXNlUmVmID0gdXNlUmVmO1xuZXhwb3J0cy51c2VTdGF0ZSA9IHVzZVN0YXRlO1xuZXhwb3J0cy51c2VTeW5jRXh0ZXJuYWxTdG9yZSA9IHVzZVN5bmNFeHRlcm5hbFN0b3JlO1xuZXhwb3J0cy51c2VUcmFuc2l0aW9uID0gdXNlVHJhbnNpdGlvbjtcbmV4cG9ydHMudmVyc2lvbiA9IFJlYWN0VmVyc2lvbjtcbiAgICAgICAgICAvKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0b3AgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcChuZXcgRXJyb3IoKSk7XG59XG4gICAgICAgIFxuICB9KSgpO1xufVxuIiwgIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC5kZXZlbG9wbWVudC5qcycpO1xufVxuIiwgIi8qKlxuICogQGxpY2Vuc2UgUmVhY3RcbiAqIHNjaGVkdWxlci5kZXZlbG9wbWVudC5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQobmV3IEVycm9yKCkpO1xufVxuICAgICAgICAgIHZhciBlbmFibGVTY2hlZHVsZXJEZWJ1Z2dpbmcgPSBmYWxzZTtcbnZhciBlbmFibGVQcm9maWxpbmcgPSBmYWxzZTtcbnZhciBmcmFtZVlpZWxkTXMgPSA1O1xuXG5mdW5jdGlvbiBwdXNoKGhlYXAsIG5vZGUpIHtcbiAgdmFyIGluZGV4ID0gaGVhcC5sZW5ndGg7XG4gIGhlYXAucHVzaChub2RlKTtcbiAgc2lmdFVwKGhlYXAsIG5vZGUsIGluZGV4KTtcbn1cbmZ1bmN0aW9uIHBlZWsoaGVhcCkge1xuICByZXR1cm4gaGVhcC5sZW5ndGggPT09IDAgPyBudWxsIDogaGVhcFswXTtcbn1cbmZ1bmN0aW9uIHBvcChoZWFwKSB7XG4gIGlmIChoZWFwLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGZpcnN0ID0gaGVhcFswXTtcbiAgdmFyIGxhc3QgPSBoZWFwLnBvcCgpO1xuXG4gIGlmIChsYXN0ICE9PSBmaXJzdCkge1xuICAgIGhlYXBbMF0gPSBsYXN0O1xuICAgIHNpZnREb3duKGhlYXAsIGxhc3QsIDApO1xuICB9XG5cbiAgcmV0dXJuIGZpcnN0O1xufVxuXG5mdW5jdGlvbiBzaWZ0VXAoaGVhcCwgbm9kZSwgaSkge1xuICB2YXIgaW5kZXggPSBpO1xuXG4gIHdoaWxlIChpbmRleCA+IDApIHtcbiAgICB2YXIgcGFyZW50SW5kZXggPSBpbmRleCAtIDEgPj4+IDE7XG4gICAgdmFyIHBhcmVudCA9IGhlYXBbcGFyZW50SW5kZXhdO1xuXG4gICAgaWYgKGNvbXBhcmUocGFyZW50LCBub2RlKSA+IDApIHtcbiAgICAgIC8vIFRoZSBwYXJlbnQgaXMgbGFyZ2VyLiBTd2FwIHBvc2l0aW9ucy5cbiAgICAgIGhlYXBbcGFyZW50SW5kZXhdID0gbm9kZTtcbiAgICAgIGhlYXBbaW5kZXhdID0gcGFyZW50O1xuICAgICAgaW5kZXggPSBwYXJlbnRJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHBhcmVudCBpcyBzbWFsbGVyLiBFeGl0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzaWZ0RG93bihoZWFwLCBub2RlLCBpKSB7XG4gIHZhciBpbmRleCA9IGk7XG4gIHZhciBsZW5ndGggPSBoZWFwLmxlbmd0aDtcbiAgdmFyIGhhbGZMZW5ndGggPSBsZW5ndGggPj4+IDE7XG5cbiAgd2hpbGUgKGluZGV4IDwgaGFsZkxlbmd0aCkge1xuICAgIHZhciBsZWZ0SW5kZXggPSAoaW5kZXggKyAxKSAqIDIgLSAxO1xuICAgIHZhciBsZWZ0ID0gaGVhcFtsZWZ0SW5kZXhdO1xuICAgIHZhciByaWdodEluZGV4ID0gbGVmdEluZGV4ICsgMTtcbiAgICB2YXIgcmlnaHQgPSBoZWFwW3JpZ2h0SW5kZXhdOyAvLyBJZiB0aGUgbGVmdCBvciByaWdodCBub2RlIGlzIHNtYWxsZXIsIHN3YXAgd2l0aCB0aGUgc21hbGxlciBvZiB0aG9zZS5cblxuICAgIGlmIChjb21wYXJlKGxlZnQsIG5vZGUpIDwgMCkge1xuICAgICAgaWYgKHJpZ2h0SW5kZXggPCBsZW5ndGggJiYgY29tcGFyZShyaWdodCwgbGVmdCkgPCAwKSB7XG4gICAgICAgIGhlYXBbaW5kZXhdID0gcmlnaHQ7XG4gICAgICAgIGhlYXBbcmlnaHRJbmRleF0gPSBub2RlO1xuICAgICAgICBpbmRleCA9IHJpZ2h0SW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoZWFwW2luZGV4XSA9IGxlZnQ7XG4gICAgICAgIGhlYXBbbGVmdEluZGV4XSA9IG5vZGU7XG4gICAgICAgIGluZGV4ID0gbGVmdEluZGV4O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmlnaHRJbmRleCA8IGxlbmd0aCAmJiBjb21wYXJlKHJpZ2h0LCBub2RlKSA8IDApIHtcbiAgICAgIGhlYXBbaW5kZXhdID0gcmlnaHQ7XG4gICAgICBoZWFwW3JpZ2h0SW5kZXhdID0gbm9kZTtcbiAgICAgIGluZGV4ID0gcmlnaHRJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmVpdGhlciBjaGlsZCBpcyBzbWFsbGVyLiBFeGl0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgLy8gQ29tcGFyZSBzb3J0IGluZGV4IGZpcnN0LCB0aGVuIHRhc2sgaWQuXG4gIHZhciBkaWZmID0gYS5zb3J0SW5kZXggLSBiLnNvcnRJbmRleDtcbiAgcmV0dXJuIGRpZmYgIT09IDAgPyBkaWZmIDogYS5pZCAtIGIuaWQ7XG59XG5cbi8vIFRPRE86IFVzZSBzeW1ib2xzP1xudmFyIEltbWVkaWF0ZVByaW9yaXR5ID0gMTtcbnZhciBVc2VyQmxvY2tpbmdQcmlvcml0eSA9IDI7XG52YXIgTm9ybWFsUHJpb3JpdHkgPSAzO1xudmFyIExvd1ByaW9yaXR5ID0gNDtcbnZhciBJZGxlUHJpb3JpdHkgPSA1O1xuXG5mdW5jdGlvbiBtYXJrVGFza0Vycm9yZWQodGFzaywgbXMpIHtcbn1cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdmFyICovXG5cbnZhciBoYXNQZXJmb3JtYW5jZU5vdyA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHBlcmZvcm1hbmNlLm5vdyA9PT0gJ2Z1bmN0aW9uJztcblxuaWYgKGhhc1BlcmZvcm1hbmNlTm93KSB7XG4gIHZhciBsb2NhbFBlcmZvcm1hbmNlID0gcGVyZm9ybWFuY2U7XG5cbiAgZXhwb3J0cy51bnN0YWJsZV9ub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGxvY2FsUGVyZm9ybWFuY2Uubm93KCk7XG4gIH07XG59IGVsc2Uge1xuICB2YXIgbG9jYWxEYXRlID0gRGF0ZTtcbiAgdmFyIGluaXRpYWxUaW1lID0gbG9jYWxEYXRlLm5vdygpO1xuXG4gIGV4cG9ydHMudW5zdGFibGVfbm93ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBsb2NhbERhdGUubm93KCkgLSBpbml0aWFsVGltZTtcbiAgfTtcbn0gLy8gTWF4IDMxIGJpdCBpbnRlZ2VyLiBUaGUgbWF4IGludGVnZXIgc2l6ZSBpbiBWOCBmb3IgMzItYml0IHN5c3RlbXMuXG4vLyBNYXRoLnBvdygyLCAzMCkgLSAxXG4vLyAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTExMVxuXG5cbnZhciBtYXhTaWduZWQzMUJpdEludCA9IDEwNzM3NDE4MjM7IC8vIFRpbWVzIG91dCBpbW1lZGlhdGVseVxuXG52YXIgSU1NRURJQVRFX1BSSU9SSVRZX1RJTUVPVVQgPSAtMTsgLy8gRXZlbnR1YWxseSB0aW1lcyBvdXRcblxudmFyIFVTRVJfQkxPQ0tJTkdfUFJJT1JJVFlfVElNRU9VVCA9IDI1MDtcbnZhciBOT1JNQUxfUFJJT1JJVFlfVElNRU9VVCA9IDUwMDA7XG52YXIgTE9XX1BSSU9SSVRZX1RJTUVPVVQgPSAxMDAwMDsgLy8gTmV2ZXIgdGltZXMgb3V0XG5cbnZhciBJRExFX1BSSU9SSVRZX1RJTUVPVVQgPSBtYXhTaWduZWQzMUJpdEludDsgLy8gVGFza3MgYXJlIHN0b3JlZCBvbiBhIG1pbiBoZWFwXG5cbnZhciB0YXNrUXVldWUgPSBbXTtcbnZhciB0aW1lclF1ZXVlID0gW107IC8vIEluY3JlbWVudGluZyBpZCBjb3VudGVyLiBVc2VkIHRvIG1haW50YWluIGluc2VydGlvbiBvcmRlci5cblxudmFyIHRhc2tJZENvdW50ZXIgPSAxOyAvLyBQYXVzaW5nIHRoZSBzY2hlZHVsZXIgaXMgdXNlZnVsIGZvciBkZWJ1Z2dpbmcuXG52YXIgY3VycmVudFRhc2sgPSBudWxsO1xudmFyIGN1cnJlbnRQcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7IC8vIFRoaXMgaXMgc2V0IHdoaWxlIHBlcmZvcm1pbmcgd29yaywgdG8gcHJldmVudCByZS1lbnRyYW5jZS5cblxudmFyIGlzUGVyZm9ybWluZ1dvcmsgPSBmYWxzZTtcbnZhciBpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCA9IGZhbHNlO1xudmFyIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTsgLy8gQ2FwdHVyZSBsb2NhbCByZWZlcmVuY2VzIHRvIG5hdGl2ZSBBUElzLCBpbiBjYXNlIGEgcG9seWZpbGwgb3ZlcnJpZGVzIHRoZW0uXG5cbnZhciBsb2NhbFNldFRpbWVvdXQgPSB0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IHNldFRpbWVvdXQgOiBudWxsO1xudmFyIGxvY2FsQ2xlYXJUaW1lb3V0ID0gdHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IGNsZWFyVGltZW91dCA6IG51bGw7XG52YXIgbG9jYWxTZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSAndW5kZWZpbmVkJyA/IHNldEltbWVkaWF0ZSA6IG51bGw7IC8vIElFIGFuZCBOb2RlLmpzICsganNkb21cblxudmFyIGlzSW5wdXRQZW5kaW5nID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnNjaGVkdWxpbmcgIT09IHVuZGVmaW5lZCAmJiBuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZyAhPT0gdW5kZWZpbmVkID8gbmF2aWdhdG9yLnNjaGVkdWxpbmcuaXNJbnB1dFBlbmRpbmcuYmluZChuYXZpZ2F0b3Iuc2NoZWR1bGluZykgOiBudWxsO1xuXG5mdW5jdGlvbiBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKSB7XG4gIC8vIENoZWNrIGZvciB0YXNrcyB0aGF0IGFyZSBubyBsb25nZXIgZGVsYXllZCBhbmQgYWRkIHRoZW0gdG8gdGhlIHF1ZXVlLlxuICB2YXIgdGltZXIgPSBwZWVrKHRpbWVyUXVldWUpO1xuXG4gIHdoaWxlICh0aW1lciAhPT0gbnVsbCkge1xuICAgIGlmICh0aW1lci5jYWxsYmFjayA9PT0gbnVsbCkge1xuICAgICAgLy8gVGltZXIgd2FzIGNhbmNlbGxlZC5cbiAgICAgIHBvcCh0aW1lclF1ZXVlKTtcbiAgICB9IGVsc2UgaWYgKHRpbWVyLnN0YXJ0VGltZSA8PSBjdXJyZW50VGltZSkge1xuICAgICAgLy8gVGltZXIgZmlyZWQuIFRyYW5zZmVyIHRvIHRoZSB0YXNrIHF1ZXVlLlxuICAgICAgcG9wKHRpbWVyUXVldWUpO1xuICAgICAgdGltZXIuc29ydEluZGV4ID0gdGltZXIuZXhwaXJhdGlvblRpbWU7XG4gICAgICBwdXNoKHRhc2tRdWV1ZSwgdGltZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZW1haW5pbmcgdGltZXJzIGFyZSBwZW5kaW5nLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRpbWVyID0gcGVlayh0aW1lclF1ZXVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVUaW1lb3V0KGN1cnJlbnRUaW1lKSB7XG4gIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgYWR2YW5jZVRpbWVycyhjdXJyZW50VGltZSk7XG5cbiAgaWYgKCFpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCkge1xuICAgIGlmIChwZWVrKHRhc2tRdWV1ZSkgIT09IG51bGwpIHtcbiAgICAgIGlzSG9zdENhbGxiYWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RIb3N0Q2FsbGJhY2soZmx1c2hXb3JrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpcnN0VGltZXIgPSBwZWVrKHRpbWVyUXVldWUpO1xuXG4gICAgICBpZiAoZmlyc3RUaW1lciAhPT0gbnVsbCkge1xuICAgICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgZmlyc3RUaW1lci5zdGFydFRpbWUgLSBjdXJyZW50VGltZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZsdXNoV29yayhoYXNUaW1lUmVtYWluaW5nLCBpbml0aWFsVGltZSkge1xuXG5cbiAgaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgPSBmYWxzZTtcblxuICBpZiAoaXNIb3N0VGltZW91dFNjaGVkdWxlZCkge1xuICAgIC8vIFdlIHNjaGVkdWxlZCBhIHRpbWVvdXQgYnV0IGl0J3Mgbm8gbG9uZ2VyIG5lZWRlZC4gQ2FuY2VsIGl0LlxuICAgIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICBjYW5jZWxIb3N0VGltZW91dCgpO1xuICB9XG5cbiAgaXNQZXJmb3JtaW5nV29yayA9IHRydWU7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcblxuICB0cnkge1xuICAgIGlmIChlbmFibGVQcm9maWxpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB3b3JrTG9vcChoYXNUaW1lUmVtYWluaW5nLCBpbml0aWFsVGltZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoY3VycmVudFRhc2sgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgY3VycmVudFRpbWUgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpO1xuICAgICAgICAgIG1hcmtUYXNrRXJyb3JlZChjdXJyZW50VGFzaywgY3VycmVudFRpbWUpO1xuICAgICAgICAgIGN1cnJlbnRUYXNrLmlzUXVldWVkID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gY2F0Y2ggaW4gcHJvZCBjb2RlIHBhdGguXG4gICAgICByZXR1cm4gd29ya0xvb3AoaGFzVGltZVJlbWFpbmluZywgaW5pdGlhbFRpbWUpO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50VGFzayA9IG51bGw7XG4gICAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBwcmV2aW91c1ByaW9yaXR5TGV2ZWw7XG4gICAgaXNQZXJmb3JtaW5nV29yayA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdvcmtMb29wKGhhc1RpbWVSZW1haW5pbmcsIGluaXRpYWxUaW1lKSB7XG4gIHZhciBjdXJyZW50VGltZSA9IGluaXRpYWxUaW1lO1xuICBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKTtcbiAgY3VycmVudFRhc2sgPSBwZWVrKHRhc2tRdWV1ZSk7XG5cbiAgd2hpbGUgKGN1cnJlbnRUYXNrICE9PSBudWxsICYmICEoZW5hYmxlU2NoZWR1bGVyRGVidWdnaW5nICkpIHtcbiAgICBpZiAoY3VycmVudFRhc2suZXhwaXJhdGlvblRpbWUgPiBjdXJyZW50VGltZSAmJiAoIWhhc1RpbWVSZW1haW5pbmcgfHwgc2hvdWxkWWllbGRUb0hvc3QoKSkpIHtcbiAgICAgIC8vIFRoaXMgY3VycmVudFRhc2sgaGFzbid0IGV4cGlyZWQsIGFuZCB3ZSd2ZSByZWFjaGVkIHRoZSBkZWFkbGluZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBjYWxsYmFjayA9IGN1cnJlbnRUYXNrLmNhbGxiYWNrO1xuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY3VycmVudFRhc2suY2FsbGJhY2sgPSBudWxsO1xuICAgICAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBjdXJyZW50VGFzay5wcmlvcml0eUxldmVsO1xuICAgICAgdmFyIGRpZFVzZXJDYWxsYmFja1RpbWVvdXQgPSBjdXJyZW50VGFzay5leHBpcmF0aW9uVGltZSA8PSBjdXJyZW50VGltZTtcblxuICAgICAgdmFyIGNvbnRpbnVhdGlvbkNhbGxiYWNrID0gY2FsbGJhY2soZGlkVXNlckNhbGxiYWNrVGltZW91dCk7XG4gICAgICBjdXJyZW50VGltZSA9IGV4cG9ydHMudW5zdGFibGVfbm93KCk7XG5cbiAgICAgIGlmICh0eXBlb2YgY29udGludWF0aW9uQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY3VycmVudFRhc2suY2FsbGJhY2sgPSBjb250aW51YXRpb25DYWxsYmFjaztcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRUYXNrID09PSBwZWVrKHRhc2tRdWV1ZSkpIHtcbiAgICAgICAgICBwb3AodGFza1F1ZXVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9wKHRhc2tRdWV1ZSk7XG4gICAgfVxuXG4gICAgY3VycmVudFRhc2sgPSBwZWVrKHRhc2tRdWV1ZSk7XG4gIH0gLy8gUmV0dXJuIHdoZXRoZXIgdGhlcmUncyBhZGRpdGlvbmFsIHdvcmtcblxuXG4gIGlmIChjdXJyZW50VGFzayAhPT0gbnVsbCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHZhciBmaXJzdFRpbWVyID0gcGVlayh0aW1lclF1ZXVlKTtcblxuICAgIGlmIChmaXJzdFRpbWVyICE9PSBudWxsKSB7XG4gICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgZmlyc3RUaW1lci5zdGFydFRpbWUgLSBjdXJyZW50VGltZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX3J1bldpdGhQcmlvcml0eShwcmlvcml0eUxldmVsLCBldmVudEhhbmRsZXIpIHtcbiAgc3dpdGNoIChwcmlvcml0eUxldmVsKSB7XG4gICAgY2FzZSBJbW1lZGlhdGVQcmlvcml0eTpcbiAgICBjYXNlIFVzZXJCbG9ja2luZ1ByaW9yaXR5OlxuICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgY2FzZSBMb3dQcmlvcml0eTpcbiAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHByaW9yaXR5TGV2ZWwgPSBOb3JtYWxQcmlvcml0eTtcbiAgfVxuXG4gIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBwcmlvcml0eUxldmVsO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGV2ZW50SGFuZGxlcigpO1xuICB9IGZpbmFsbHkge1xuICAgIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJldmlvdXNQcmlvcml0eUxldmVsO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX25leHQoZXZlbnRIYW5kbGVyKSB7XG4gIHZhciBwcmlvcml0eUxldmVsO1xuXG4gIHN3aXRjaCAoY3VycmVudFByaW9yaXR5TGV2ZWwpIHtcbiAgICBjYXNlIEltbWVkaWF0ZVByaW9yaXR5OlxuICAgIGNhc2UgVXNlckJsb2NraW5nUHJpb3JpdHk6XG4gICAgY2FzZSBOb3JtYWxQcmlvcml0eTpcbiAgICAgIC8vIFNoaWZ0IGRvd24gdG8gbm9ybWFsIHByaW9yaXR5XG4gICAgICBwcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBBbnl0aGluZyBsb3dlciB0aGFuIG5vcm1hbCBwcmlvcml0eSBzaG91bGQgcmVtYWluIGF0IHRoZSBjdXJyZW50IGxldmVsLlxuICAgICAgcHJpb3JpdHlMZXZlbCA9IGN1cnJlbnRQcmlvcml0eUxldmVsO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICB2YXIgcHJldmlvdXNQcmlvcml0eUxldmVsID0gY3VycmVudFByaW9yaXR5TGV2ZWw7XG4gIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJpb3JpdHlMZXZlbDtcblxuICB0cnkge1xuICAgIHJldHVybiBldmVudEhhbmRsZXIoKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50UHJpb3JpdHlMZXZlbCA9IHByZXZpb3VzUHJpb3JpdHlMZXZlbDtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV93cmFwQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgdmFyIHBhcmVudFByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBUaGlzIGlzIGEgZm9yayBvZiBydW5XaXRoUHJpb3JpdHksIGlubGluZWQgZm9yIHBlcmZvcm1hbmNlLlxuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgICBjdXJyZW50UHJpb3JpdHlMZXZlbCA9IHBhcmVudFByaW9yaXR5TGV2ZWw7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJldmlvdXNQcmlvcml0eUxldmVsO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gdW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjayhwcmlvcml0eUxldmVsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICB2YXIgY3VycmVudFRpbWUgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpO1xuICB2YXIgc3RhcnRUaW1lO1xuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCkge1xuICAgIHZhciBkZWxheSA9IG9wdGlvbnMuZGVsYXk7XG5cbiAgICBpZiAodHlwZW9mIGRlbGF5ID09PSAnbnVtYmVyJyAmJiBkZWxheSA+IDApIHtcbiAgICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lICsgZGVsYXk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzdGFydFRpbWUgPSBjdXJyZW50VGltZTtcbiAgfVxuXG4gIHZhciB0aW1lb3V0O1xuXG4gIHN3aXRjaCAocHJpb3JpdHlMZXZlbCkge1xuICAgIGNhc2UgSW1tZWRpYXRlUHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gSU1NRURJQVRFX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgVXNlckJsb2NraW5nUHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gVVNFUl9CTE9DS0lOR19QUklPUklUWV9USU1FT1VUO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgIHRpbWVvdXQgPSBJRExFX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgTG93UHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gTE9XX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgZGVmYXVsdDpcbiAgICAgIHRpbWVvdXQgPSBOT1JNQUxfUFJJT1JJVFlfVElNRU9VVDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgdmFyIGV4cGlyYXRpb25UaW1lID0gc3RhcnRUaW1lICsgdGltZW91dDtcbiAgdmFyIG5ld1Rhc2sgPSB7XG4gICAgaWQ6IHRhc2tJZENvdW50ZXIrKyxcbiAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgcHJpb3JpdHlMZXZlbDogcHJpb3JpdHlMZXZlbCxcbiAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICBleHBpcmF0aW9uVGltZTogZXhwaXJhdGlvblRpbWUsXG4gICAgc29ydEluZGV4OiAtMVxuICB9O1xuXG4gIGlmIChzdGFydFRpbWUgPiBjdXJyZW50VGltZSkge1xuICAgIC8vIFRoaXMgaXMgYSBkZWxheWVkIHRhc2suXG4gICAgbmV3VGFzay5zb3J0SW5kZXggPSBzdGFydFRpbWU7XG4gICAgcHVzaCh0aW1lclF1ZXVlLCBuZXdUYXNrKTtcblxuICAgIGlmIChwZWVrKHRhc2tRdWV1ZSkgPT09IG51bGwgJiYgbmV3VGFzayA9PT0gcGVlayh0aW1lclF1ZXVlKSkge1xuICAgICAgLy8gQWxsIHRhc2tzIGFyZSBkZWxheWVkLCBhbmQgdGhpcyBpcyB0aGUgdGFzayB3aXRoIHRoZSBlYXJsaWVzdCBkZWxheS5cbiAgICAgIGlmIChpc0hvc3RUaW1lb3V0U2NoZWR1bGVkKSB7XG4gICAgICAgIC8vIENhbmNlbCBhbiBleGlzdGluZyB0aW1lb3V0LlxuICAgICAgICBjYW5jZWxIb3N0VGltZW91dCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXNIb3N0VGltZW91dFNjaGVkdWxlZCA9IHRydWU7XG4gICAgICB9IC8vIFNjaGVkdWxlIGEgdGltZW91dC5cblxuXG4gICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgc3RhcnRUaW1lIC0gY3VycmVudFRpbWUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBuZXdUYXNrLnNvcnRJbmRleCA9IGV4cGlyYXRpb25UaW1lO1xuICAgIHB1c2godGFza1F1ZXVlLCBuZXdUYXNrKTtcbiAgICAvLyB3YWl0IHVudGlsIHRoZSBuZXh0IHRpbWUgd2UgeWllbGQuXG5cblxuICAgIGlmICghaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgJiYgIWlzUGVyZm9ybWluZ1dvcmspIHtcbiAgICAgIGlzSG9zdENhbGxiYWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RIb3N0Q2FsbGJhY2soZmx1c2hXb3JrKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3VGFzaztcbn1cblxuZnVuY3Rpb24gdW5zdGFibGVfcGF1c2VFeGVjdXRpb24oKSB7XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX2NvbnRpbnVlRXhlY3V0aW9uKCkge1xuXG4gIGlmICghaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgJiYgIWlzUGVyZm9ybWluZ1dvcmspIHtcbiAgICBpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCA9IHRydWU7XG4gICAgcmVxdWVzdEhvc3RDYWxsYmFjayhmbHVzaFdvcmspO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX2dldEZpcnN0Q2FsbGJhY2tOb2RlKCkge1xuICByZXR1cm4gcGVlayh0YXNrUXVldWUpO1xufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV9jYW5jZWxDYWxsYmFjayh0YXNrKSB7XG4gIC8vIHJlbW92ZSBmcm9tIHRoZSBxdWV1ZSBiZWNhdXNlIHlvdSBjYW4ndCByZW1vdmUgYXJiaXRyYXJ5IG5vZGVzIGZyb20gYW5cbiAgLy8gYXJyYXkgYmFzZWQgaGVhcCwgb25seSB0aGUgZmlyc3Qgb25lLilcblxuXG4gIHRhc2suY2FsbGJhY2sgPSBudWxsO1xufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV9nZXRDdXJyZW50UHJpb3JpdHlMZXZlbCgpIHtcbiAgcmV0dXJuIGN1cnJlbnRQcmlvcml0eUxldmVsO1xufVxuXG52YXIgaXNNZXNzYWdlTG9vcFJ1bm5pbmcgPSBmYWxzZTtcbnZhciBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBudWxsO1xudmFyIHRhc2tUaW1lb3V0SUQgPSAtMTsgLy8gU2NoZWR1bGVyIHBlcmlvZGljYWxseSB5aWVsZHMgaW4gY2FzZSB0aGVyZSBpcyBvdGhlciB3b3JrIG9uIHRoZSBtYWluXG4vLyB0aHJlYWQsIGxpa2UgdXNlciBldmVudHMuIEJ5IGRlZmF1bHQsIGl0IHlpZWxkcyBtdWx0aXBsZSB0aW1lcyBwZXIgZnJhbWUuXG4vLyBJdCBkb2VzIG5vdCBhdHRlbXB0IHRvIGFsaWduIHdpdGggZnJhbWUgYm91bmRhcmllcywgc2luY2UgbW9zdCB0YXNrcyBkb24ndFxuLy8gbmVlZCB0byBiZSBmcmFtZSBhbGlnbmVkOyBmb3IgdGhvc2UgdGhhdCBkbywgdXNlIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cblxudmFyIGZyYW1lSW50ZXJ2YWwgPSBmcmFtZVlpZWxkTXM7XG52YXIgc3RhcnRUaW1lID0gLTE7XG5cbmZ1bmN0aW9uIHNob3VsZFlpZWxkVG9Ib3N0KCkge1xuICB2YXIgdGltZUVsYXBzZWQgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpIC0gc3RhcnRUaW1lO1xuXG4gIGlmICh0aW1lRWxhcHNlZCA8IGZyYW1lSW50ZXJ2YWwpIHtcbiAgICAvLyBUaGUgbWFpbiB0aHJlYWQgaGFzIG9ubHkgYmVlbiBibG9ja2VkIGZvciBhIHJlYWxseSBzaG9ydCBhbW91bnQgb2YgdGltZTtcbiAgICAvLyBzbWFsbGVyIHRoYW4gYSBzaW5nbGUgZnJhbWUuIERvbid0IHlpZWxkIHlldC5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gLy8gVGhlIG1haW4gdGhyZWFkIGhhcyBiZWVuIGJsb2NrZWQgZm9yIGEgbm9uLW5lZ2xpZ2libGUgYW1vdW50IG9mIHRpbWUuIFdlXG5cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFBhaW50KCkge1xuXG59XG5cbmZ1bmN0aW9uIGZvcmNlRnJhbWVSYXRlKGZwcykge1xuICBpZiAoZnBzIDwgMCB8fCBmcHMgPiAxMjUpIHtcbiAgICAvLyBVc2luZyBjb25zb2xlWydlcnJvciddIHRvIGV2YWRlIEJhYmVsIGFuZCBFU0xpbnRcbiAgICBjb25zb2xlWydlcnJvciddKCdmb3JjZUZyYW1lUmF0ZSB0YWtlcyBhIHBvc2l0aXZlIGludCBiZXR3ZWVuIDAgYW5kIDEyNSwgJyArICdmb3JjaW5nIGZyYW1lIHJhdGVzIGhpZ2hlciB0aGFuIDEyNSBmcHMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmcHMgPiAwKSB7XG4gICAgZnJhbWVJbnRlcnZhbCA9IE1hdGguZmxvb3IoMTAwMCAvIGZwcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVzZXQgdGhlIGZyYW1lcmF0ZVxuICAgIGZyYW1lSW50ZXJ2YWwgPSBmcmFtZVlpZWxkTXM7XG4gIH1cbn1cblxudmFyIHBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHNjaGVkdWxlZEhvc3RDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgIHZhciBjdXJyZW50VGltZSA9IGV4cG9ydHMudW5zdGFibGVfbm93KCk7IC8vIEtlZXAgdHJhY2sgb2YgdGhlIHN0YXJ0IHRpbWUgc28gd2UgY2FuIG1lYXN1cmUgaG93IGxvbmcgdGhlIG1haW4gdGhyZWFkXG4gICAgLy8gaGFzIGJlZW4gYmxvY2tlZC5cblxuICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIHZhciBoYXNUaW1lUmVtYWluaW5nID0gdHJ1ZTsgLy8gSWYgYSBzY2hlZHVsZXIgdGFzayB0aHJvd3MsIGV4aXQgdGhlIGN1cnJlbnQgYnJvd3NlciB0YXNrIHNvIHRoZVxuICAgIC8vIGVycm9yIGNhbiBiZSBvYnNlcnZlZC5cbiAgICAvL1xuICAgIC8vIEludGVudGlvbmFsbHkgbm90IHVzaW5nIGEgdHJ5LWNhdGNoLCBzaW5jZSB0aGF0IG1ha2VzIHNvbWUgZGVidWdnaW5nXG4gICAgLy8gdGVjaG5pcXVlcyBoYXJkZXIuIEluc3RlYWQsIGlmIGBzY2hlZHVsZWRIb3N0Q2FsbGJhY2tgIGVycm9ycywgdGhlblxuICAgIC8vIGBoYXNNb3JlV29ya2Agd2lsbCByZW1haW4gdHJ1ZSwgYW5kIHdlJ2xsIGNvbnRpbnVlIHRoZSB3b3JrIGxvb3AuXG5cbiAgICB2YXIgaGFzTW9yZVdvcmsgPSB0cnVlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGhhc01vcmVXb3JrID0gc2NoZWR1bGVkSG9zdENhbGxiYWNrKGhhc1RpbWVSZW1haW5pbmcsIGN1cnJlbnRUaW1lKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKGhhc01vcmVXb3JrKSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3MgbW9yZSB3b3JrLCBzY2hlZHVsZSB0aGUgbmV4dCBtZXNzYWdlIGV2ZW50IGF0IHRoZSBlbmRcbiAgICAgICAgLy8gb2YgdGhlIHByZWNlZGluZyBvbmUuXG4gICAgICAgIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpc01lc3NhZ2VMb29wUnVubmluZyA9IGZhbHNlO1xuICAgICAgICBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpc01lc3NhZ2VMb29wUnVubmluZyA9IGZhbHNlO1xuICB9IC8vIFlpZWxkaW5nIHRvIHRoZSBicm93c2VyIHdpbGwgZ2l2ZSBpdCBhIGNoYW5jZSB0byBwYWludCwgc28gd2UgY2FuXG59O1xuXG52YXIgc2NoZWR1bGVQZXJmb3JtV29ya1VudGlsRGVhZGxpbmU7XG5cbmlmICh0eXBlb2YgbG9jYWxTZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gTm9kZS5qcyBhbmQgb2xkIElFLlxuICAvLyBUaGVyZSdzIGEgZmV3IHJlYXNvbnMgZm9yIHdoeSB3ZSBwcmVmZXIgc2V0SW1tZWRpYXRlLlxuICAvL1xuICAvLyBVbmxpa2UgTWVzc2FnZUNoYW5uZWwsIGl0IGRvZXNuJ3QgcHJldmVudCBhIE5vZGUuanMgcHJvY2VzcyBmcm9tIGV4aXRpbmcuXG4gIC8vIChFdmVuIHRob3VnaCB0aGlzIGlzIGEgRE9NIGZvcmsgb2YgdGhlIFNjaGVkdWxlciwgeW91IGNvdWxkIGdldCBoZXJlXG4gIC8vIHdpdGggYSBtaXggb2YgTm9kZS5qcyAxNSssIHdoaWNoIGhhcyBhIE1lc3NhZ2VDaGFubmVsLCBhbmQganNkb20uKVxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzIwNzU2XG4gIC8vXG4gIC8vIEJ1dCBhbHNvLCBpdCBydW5zIGVhcmxpZXIgd2hpY2ggaXMgdGhlIHNlbWFudGljIHdlIHdhbnQuXG4gIC8vIElmIG90aGVyIGJyb3dzZXJzIGV2ZXIgaW1wbGVtZW50IGl0LCBpdCdzIGJldHRlciB0byB1c2UgaXQuXG4gIC8vIEFsdGhvdWdoIGJvdGggb2YgdGhlc2Ugd291bGQgYmUgaW5mZXJpb3IgdG8gbmF0aXZlIHNjaGVkdWxpbmcuXG4gIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lID0gZnVuY3Rpb24gKCkge1xuICAgIGxvY2FsU2V0SW1tZWRpYXRlKHBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSk7XG4gIH07XG59IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgLy8gRE9NIGFuZCBXb3JrZXIgZW52aXJvbm1lbnRzLlxuICAvLyBXZSBwcmVmZXIgTWVzc2FnZUNoYW5uZWwgYmVjYXVzZSBvZiB0aGUgNG1zIHNldFRpbWVvdXQgY2xhbXBpbmcuXG4gIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gIHZhciBwb3J0ID0gY2hhbm5lbC5wb3J0MjtcbiAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBwZXJmb3JtV29ya1VudGlsRGVhZGxpbmU7XG5cbiAgc2NoZWR1bGVQZXJmb3JtV29ya1VudGlsRGVhZGxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydC5wb3N0TWVzc2FnZShudWxsKTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIFdlIHNob3VsZCBvbmx5IGZhbGxiYWNrIGhlcmUgaW4gbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRzLlxuICBzY2hlZHVsZVBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBsb2NhbFNldFRpbWVvdXQocGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lLCAwKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhvc3RDYWxsYmFjayhjYWxsYmFjaykge1xuICBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBpZiAoIWlzTWVzc2FnZUxvb3BSdW5uaW5nKSB7XG4gICAgaXNNZXNzYWdlTG9vcFJ1bm5pbmcgPSB0cnVlO1xuICAgIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhvc3RUaW1lb3V0KGNhbGxiYWNrLCBtcykge1xuICB0YXNrVGltZW91dElEID0gbG9jYWxTZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYWxsYmFjayhleHBvcnRzLnVuc3RhYmxlX25vdygpKTtcbiAgfSwgbXMpO1xufVxuXG5mdW5jdGlvbiBjYW5jZWxIb3N0VGltZW91dCgpIHtcbiAgbG9jYWxDbGVhclRpbWVvdXQodGFza1RpbWVvdXRJRCk7XG4gIHRhc2tUaW1lb3V0SUQgPSAtMTtcbn1cblxudmFyIHVuc3RhYmxlX3JlcXVlc3RQYWludCA9IHJlcXVlc3RQYWludDtcbnZhciB1bnN0YWJsZV9Qcm9maWxpbmcgPSAgbnVsbDtcblxuZXhwb3J0cy51bnN0YWJsZV9JZGxlUHJpb3JpdHkgPSBJZGxlUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5ID0gSW1tZWRpYXRlUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX0xvd1ByaW9yaXR5ID0gTG93UHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5ID0gTm9ybWFsUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX1Byb2ZpbGluZyA9IHVuc3RhYmxlX1Byb2ZpbGluZztcbmV4cG9ydHMudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHkgPSBVc2VyQmxvY2tpbmdQcmlvcml0eTtcbmV4cG9ydHMudW5zdGFibGVfY2FuY2VsQ2FsbGJhY2sgPSB1bnN0YWJsZV9jYW5jZWxDYWxsYmFjaztcbmV4cG9ydHMudW5zdGFibGVfY29udGludWVFeGVjdXRpb24gPSB1bnN0YWJsZV9jb250aW51ZUV4ZWN1dGlvbjtcbmV4cG9ydHMudW5zdGFibGVfZm9yY2VGcmFtZVJhdGUgPSBmb3JjZUZyYW1lUmF0ZTtcbmV4cG9ydHMudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwgPSB1bnN0YWJsZV9nZXRDdXJyZW50UHJpb3JpdHlMZXZlbDtcbmV4cG9ydHMudW5zdGFibGVfZ2V0Rmlyc3RDYWxsYmFja05vZGUgPSB1bnN0YWJsZV9nZXRGaXJzdENhbGxiYWNrTm9kZTtcbmV4cG9ydHMudW5zdGFibGVfbmV4dCA9IHVuc3RhYmxlX25leHQ7XG5leHBvcnRzLnVuc3RhYmxlX3BhdXNlRXhlY3V0aW9uID0gdW5zdGFibGVfcGF1c2VFeGVjdXRpb247XG5leHBvcnRzLnVuc3RhYmxlX3JlcXVlc3RQYWludCA9IHVuc3RhYmxlX3JlcXVlc3RQYWludDtcbmV4cG9ydHMudW5zdGFibGVfcnVuV2l0aFByaW9yaXR5ID0gdW5zdGFibGVfcnVuV2l0aFByaW9yaXR5O1xuZXhwb3J0cy51bnN0YWJsZV9zY2hlZHVsZUNhbGxiYWNrID0gdW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjaztcbmV4cG9ydHMudW5zdGFibGVfc2hvdWxkWWllbGQgPSBzaG91bGRZaWVsZFRvSG9zdDtcbmV4cG9ydHMudW5zdGFibGVfd3JhcENhbGxiYWNrID0gdW5zdGFibGVfd3JhcENhbGxiYWNrO1xuICAgICAgICAgIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcCA9PT1cbiAgICAnZnVuY3Rpb24nXG4pIHtcbiAgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fLnJlZ2lzdGVySW50ZXJuYWxNb2R1bGVTdG9wKG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgXG4gIH0pKCk7XG59XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3NjaGVkdWxlci5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiIsICIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC1kb20uZGV2ZWxvcG1lbnQuanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4vKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0YXJ0ID09PVxuICAgICdmdW5jdGlvbidcbikge1xuICBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0YXJ0KG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgICB2YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFNjaGVkdWxlciA9IHJlcXVpcmUoJ3NjaGVkdWxlcicpO1xuXG52YXIgUmVhY3RTaGFyZWRJbnRlcm5hbHMgPSBSZWFjdC5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRDtcblxudmFyIHN1cHByZXNzV2FybmluZyA9IGZhbHNlO1xuZnVuY3Rpb24gc2V0U3VwcHJlc3NXYXJuaW5nKG5ld1N1cHByZXNzV2FybmluZykge1xuICB7XG4gICAgc3VwcHJlc3NXYXJuaW5nID0gbmV3U3VwcHJlc3NXYXJuaW5nO1xuICB9XG59IC8vIEluIERFViwgY2FsbHMgdG8gY29uc29sZS53YXJuIGFuZCBjb25zb2xlLmVycm9yIGdldCByZXBsYWNlZFxuLy8gYnkgY2FsbHMgdG8gdGhlc2UgbWV0aG9kcyBieSBhIEJhYmVsIHBsdWdpbi5cbi8vXG4vLyBJbiBQUk9EIChvciBpbiBwYWNrYWdlcyB3aXRob3V0IGFjY2VzcyB0byBSZWFjdCBpbnRlcm5hbHMpLFxuLy8gdGhleSBhcmUgbGVmdCBhcyB0aGV5IGFyZSBpbnN0ZWFkLlxuXG5mdW5jdGlvbiB3YXJuKGZvcm1hdCkge1xuICB7XG4gICAgaWYgKCFzdXBwcmVzc1dhcm5pbmcpIHtcbiAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnd2FybicsIGZvcm1hdCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBlcnJvcihmb3JtYXQpIHtcbiAge1xuICAgIGlmICghc3VwcHJlc3NXYXJuaW5nKSB7XG4gICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIgPiAxID8gX2xlbjIgLSAxIDogMCksIF9rZXkyID0gMTsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICBhcmdzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgfVxuXG4gICAgICBwcmludFdhcm5pbmcoJ2Vycm9yJywgZm9ybWF0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJpbnRXYXJuaW5nKGxldmVsLCBmb3JtYXQsIGFyZ3MpIHtcbiAgLy8gV2hlbiBjaGFuZ2luZyB0aGlzIGxvZ2ljLCB5b3UgbWlnaHQgd2FudCB0byBhbHNvXG4gIC8vIHVwZGF0ZSBjb25zb2xlV2l0aFN0YWNrRGV2Lnd3dy5qcyBhcyB3ZWxsLlxuICB7XG4gICAgdmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuICAgIHZhciBzdGFjayA9IFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0U3RhY2tBZGRlbmR1bSgpO1xuXG4gICAgaWYgKHN0YWNrICE9PSAnJykge1xuICAgICAgZm9ybWF0ICs9ICclcyc7XG4gICAgICBhcmdzID0gYXJncy5jb25jYXQoW3N0YWNrXSk7XG4gICAgfSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb25cblxuXG4gICAgdmFyIGFyZ3NXaXRoRm9ybWF0ID0gYXJncy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBTdHJpbmcoaXRlbSk7XG4gICAgfSk7IC8vIENhcmVmdWw6IFJOIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJlZml4XG5cbiAgICBhcmdzV2l0aEZvcm1hdC51bnNoaWZ0KCdXYXJuaW5nOiAnICsgZm9ybWF0KTsgLy8gV2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2Ugc3ByZWFkIChvciAuYXBwbHkpIGRpcmVjdGx5IGJlY2F1c2UgaXRcbiAgICAvLyBicmVha3MgSUU5OiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEzNjEwXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuXG4gICAgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZVtsZXZlbF0sIGNvbnNvbGUsIGFyZ3NXaXRoRm9ybWF0KTtcbiAgfVxufVxuXG52YXIgRnVuY3Rpb25Db21wb25lbnQgPSAwO1xudmFyIENsYXNzQ29tcG9uZW50ID0gMTtcbnZhciBJbmRldGVybWluYXRlQ29tcG9uZW50ID0gMjsgLy8gQmVmb3JlIHdlIGtub3cgd2hldGhlciBpdCBpcyBmdW5jdGlvbiBvciBjbGFzc1xuXG52YXIgSG9zdFJvb3QgPSAzOyAvLyBSb290IG9mIGEgaG9zdCB0cmVlLiBDb3VsZCBiZSBuZXN0ZWQgaW5zaWRlIGFub3RoZXIgbm9kZS5cblxudmFyIEhvc3RQb3J0YWwgPSA0OyAvLyBBIHN1YnRyZWUuIENvdWxkIGJlIGFuIGVudHJ5IHBvaW50IHRvIGEgZGlmZmVyZW50IHJlbmRlcmVyLlxuXG52YXIgSG9zdENvbXBvbmVudCA9IDU7XG52YXIgSG9zdFRleHQgPSA2O1xudmFyIEZyYWdtZW50ID0gNztcbnZhciBNb2RlID0gODtcbnZhciBDb250ZXh0Q29uc3VtZXIgPSA5O1xudmFyIENvbnRleHRQcm92aWRlciA9IDEwO1xudmFyIEZvcndhcmRSZWYgPSAxMTtcbnZhciBQcm9maWxlciA9IDEyO1xudmFyIFN1c3BlbnNlQ29tcG9uZW50ID0gMTM7XG52YXIgTWVtb0NvbXBvbmVudCA9IDE0O1xudmFyIFNpbXBsZU1lbW9Db21wb25lbnQgPSAxNTtcbnZhciBMYXp5Q29tcG9uZW50ID0gMTY7XG52YXIgSW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50ID0gMTc7XG52YXIgRGVoeWRyYXRlZEZyYWdtZW50ID0gMTg7XG52YXIgU3VzcGVuc2VMaXN0Q29tcG9uZW50ID0gMTk7XG52YXIgU2NvcGVDb21wb25lbnQgPSAyMTtcbnZhciBPZmZzY3JlZW5Db21wb25lbnQgPSAyMjtcbnZhciBMZWdhY3lIaWRkZW5Db21wb25lbnQgPSAyMztcbnZhciBDYWNoZUNvbXBvbmVudCA9IDI0O1xudmFyIFRyYWNpbmdNYXJrZXJDb21wb25lbnQgPSAyNTtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIGVuYWJsZUNsaWVudFJlbmRlckZhbGxiYWNrT25UZXh0TWlzbWF0Y2ggPSB0cnVlOyAvLyBUT0RPOiBOZWVkIHRvIHJldmlldyB0aGlzIGNvZGUgb25lIG1vcmUgdGltZSBiZWZvcmUgbGFuZGluZ1xuLy8gdGhlIHJlYWN0LXJlY29uY2lsZXIgcGFja2FnZS5cblxudmFyIGVuYWJsZU5ld1JlY29uY2lsZXIgPSBmYWxzZTsgLy8gU3VwcG9ydCBsZWdhY3kgUHJpbWVyIHN1cHBvcnQgb24gaW50ZXJuYWwgRkIgd3d3XG5cbnZhciBlbmFibGVMYXp5Q29udGV4dFByb3BhZ2F0aW9uID0gZmFsc2U7IC8vIEZCLW9ubHkgdXNhZ2UuIFRoZSBuZXcgQVBJIGhhcyBkaWZmZXJlbnQgc2VtYW50aWNzLlxuXG52YXIgZW5hYmxlTGVnYWN5SGlkZGVuID0gZmFsc2U7IC8vIEVuYWJsZXMgdW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgZmVhdHVyZSBpbiBGaWJlclxuXG52YXIgZW5hYmxlU3VzcGVuc2VBdm9pZFRoaXNGYWxsYmFjayA9IGZhbHNlOyAvLyBFbmFibGVzIHVuc3RhYmxlX2F2b2lkVGhpc0ZhbGxiYWNrIGZlYXR1cmUgaW4gRml6elxuLy8gUmVhY3QgRE9NIENob3BwaW5nIEJsb2NrXG4vL1xuLy8gU2ltaWxhciB0byBtYWluIENob3BwaW5nIEJsb2NrIGJ1dCBvbmx5IGZsYWdzIHJlbGF0ZWQgdG8gUmVhY3QgRE9NLiBUaGVzZSBhcmVcbi8vIGdyb3VwZWQgYmVjYXVzZSB3ZSB3aWxsIGxpa2VseSBiYXRjaCBhbGwgb2YgdGhlbSBpbnRvIGEgc2luZ2xlIG1ham9yIHJlbGVhc2UuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRGlzYWJsZSBzdXBwb3J0IGZvciBjb21tZW50IG5vZGVzIGFzIFJlYWN0IERPTSBjb250YWluZXJzLiBBbHJlYWR5IGRpc2FibGVkXG4vLyBpbiBvcGVuIHNvdXJjZSwgYnV0IHd3dyBjb2RlYmFzZSBzdGlsbCByZWxpZXMgb24gaXQuIE5lZWQgdG8gcmVtb3ZlLlxuXG52YXIgZGlzYWJsZUNvbW1lbnRzQXNET01Db250YWluZXJzID0gdHJ1ZTsgLy8gRGlzYWJsZSBqYXZhc2NyaXB0OiBVUkwgc3RyaW5ncyBpbiBocmVmIGZvciBYU1MgcHJvdGVjdGlvbi5cbi8vIGFuZCBjbGllbnQgcmVuZGVyaW5nLCBtb3N0bHkgdG8gYWxsb3cgSlNYIGF0dHJpYnV0ZXMgdG8gYXBwbHkgdG8gdGhlIGN1c3RvbVxuLy8gZWxlbWVudCdzIG9iamVjdCBwcm9wZXJ0aWVzIGluc3RlYWQgb2Ygb25seSBIVE1MIGF0dHJpYnV0ZXMuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzExMzQ3XG5cbnZhciBlbmFibGVDdXN0b21FbGVtZW50UHJvcGVydHlTdXBwb3J0ID0gZmFsc2U7IC8vIERpc2FibGVzIGNoaWxkcmVuIGZvciA8dGV4dGFyZWE+IGVsZW1lbnRzXG52YXIgd2FybkFib3V0U3RyaW5nUmVmcyA9IGZhbHNlOyAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRGVidWdnaW5nIGFuZCBEZXZUb29sc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEFkZHMgdXNlciB0aW1pbmcgbWFya3MgZm9yIGUuZy4gc3RhdGUgdXBkYXRlcywgc3VzcGVuc2UsIGFuZCB3b3JrIGxvb3Agc3R1ZmYsXG4vLyBmb3IgYW4gZXhwZXJpbWVudGFsIHRpbWVsaW5lIHRvb2wuXG5cbnZhciBlbmFibGVTY2hlZHVsaW5nUHJvZmlsZXIgPSB0cnVlOyAvLyBIZWxwcyBpZGVudGlmeSBzaWRlIGVmZmVjdHMgaW4gcmVuZGVyLXBoYXNlIGxpZmVjeWNsZSBob29rcyBhbmQgc2V0U3RhdGVcblxudmFyIGVuYWJsZVByb2ZpbGVyVGltZXIgPSB0cnVlOyAvLyBSZWNvcmQgZHVyYXRpb25zIGZvciBjb21taXQgYW5kIHBhc3NpdmUgZWZmZWN0cyBwaGFzZXMuXG5cbnZhciBlbmFibGVQcm9maWxlckNvbW1pdEhvb2tzID0gdHJ1ZTsgLy8gUGhhc2UgcGFyYW0gcGFzc2VkIHRvIG9uUmVuZGVyIGNhbGxiYWNrIGRpZmZlcmVudGlhdGVzIGJldHdlZW4gYW4gXCJ1cGRhdGVcIiBhbmQgYSBcImNhc2NhZGluZy11cGRhdGVcIi5cblxudmFyIGFsbE5hdGl2ZUV2ZW50cyA9IG5ldyBTZXQoKTtcbi8qKlxuICogTWFwcGluZyBmcm9tIHJlZ2lzdHJhdGlvbiBuYW1lIHRvIGV2ZW50IG5hbWVcbiAqL1xuXG5cbnZhciByZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzID0ge307XG4vKipcbiAqIE1hcHBpbmcgZnJvbSBsb3dlcmNhc2UgcmVnaXN0cmF0aW9uIG5hbWVzIHRvIHRoZSBwcm9wZXJseSBjYXNlZCB2ZXJzaW9uLFxuICogdXNlZCB0byB3YXJuIGluIHRoZSBjYXNlIG9mIG1pc3NpbmcgZXZlbnQgaGFuZGxlcnMuIEF2YWlsYWJsZVxuICogb25seSBpbiB0cnVlLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuXG52YXIgcG9zc2libGVSZWdpc3RyYXRpb25OYW1lcyA9ICB7fSA7IC8vIFRydXN0IHRoZSBkZXZlbG9wZXIgdG8gb25seSB1c2UgcG9zc2libGVSZWdpc3RyYXRpb25OYW1lcyBpbiB0cnVlXG5cbmZ1bmN0aW9uIHJlZ2lzdGVyVHdvUGhhc2VFdmVudChyZWdpc3RyYXRpb25OYW1lLCBkZXBlbmRlbmNpZXMpIHtcbiAgcmVnaXN0ZXJEaXJlY3RFdmVudChyZWdpc3RyYXRpb25OYW1lLCBkZXBlbmRlbmNpZXMpO1xuICByZWdpc3RlckRpcmVjdEV2ZW50KHJlZ2lzdHJhdGlvbk5hbWUgKyAnQ2FwdHVyZScsIGRlcGVuZGVuY2llcyk7XG59XG5mdW5jdGlvbiByZWdpc3RlckRpcmVjdEV2ZW50KHJlZ2lzdHJhdGlvbk5hbWUsIGRlcGVuZGVuY2llcykge1xuICB7XG4gICAgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXNbcmVnaXN0cmF0aW9uTmFtZV0pIHtcbiAgICAgIGVycm9yKCdFdmVudFJlZ2lzdHJ5OiBNb3JlIHRoYW4gb25lIHBsdWdpbiBhdHRlbXB0ZWQgdG8gcHVibGlzaCB0aGUgc2FtZSAnICsgJ3JlZ2lzdHJhdGlvbiBuYW1lLCBgJXNgLicsIHJlZ2lzdHJhdGlvbk5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXNbcmVnaXN0cmF0aW9uTmFtZV0gPSBkZXBlbmRlbmNpZXM7XG5cbiAge1xuICAgIHZhciBsb3dlckNhc2VkTmFtZSA9IHJlZ2lzdHJhdGlvbk5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzW2xvd2VyQ2FzZWROYW1lXSA9IHJlZ2lzdHJhdGlvbk5hbWU7XG5cbiAgICBpZiAocmVnaXN0cmF0aW9uTmFtZSA9PT0gJ29uRG91YmxlQ2xpY2snKSB7XG4gICAgICBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzLm9uZGJsY2xpY2sgPSByZWdpc3RyYXRpb25OYW1lO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgYWxsTmF0aXZlRXZlbnRzLmFkZChkZXBlbmRlbmNpZXNbaV0pO1xuICB9XG59XG5cbnZhciBjYW5Vc2VET00gPSAhISh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93LmRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgIT09ICd1bmRlZmluZWQnKTtcblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLypcbiAqIFRoZSBgJycgKyB2YWx1ZWAgcGF0dGVybiAodXNlZCBpbiBpbiBwZXJmLXNlbnNpdGl2ZSBjb2RlKSB0aHJvd3MgZm9yIFN5bWJvbFxuICogYW5kIFRlbXBvcmFsLiogdHlwZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8yMjA2NC5cbiAqXG4gKiBUaGUgZnVuY3Rpb25zIGluIHRoaXMgbW9kdWxlIHdpbGwgdGhyb3cgYW4gZWFzaWVyLXRvLXVuZGVyc3RhbmQsXG4gKiBlYXNpZXItdG8tZGVidWcgZXhjZXB0aW9uIHdpdGggYSBjbGVhciBlcnJvcnMgbWVzc2FnZSBtZXNzYWdlIGV4cGxhaW5pbmcgdGhlXG4gKiBwcm9ibGVtLiAoSW5zdGVhZCBvZiBhIGNvbmZ1c2luZyBleGNlcHRpb24gdGhyb3duIGluc2lkZSB0aGUgaW1wbGVtZW50YXRpb25cbiAqIG9mIHRoZSBgdmFsdWVgIG9iamVjdCkuXG4gKi9cbi8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5mdW5jdGlvbiB0eXBlTmFtZSh2YWx1ZSkge1xuICB7XG4gICAgLy8gdG9TdHJpbmdUYWcgaXMgbmVlZGVkIGZvciBuYW1lc3BhY2VkIHR5cGVzIGxpa2UgVGVtcG9yYWwuSW5zdGFudFxuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLnRvU3RyaW5nVGFnO1xuICAgIHZhciB0eXBlID0gaGFzVG9TdHJpbmdUYWcgJiYgdmFsdWVbU3ltYm9sLnRvU3RyaW5nVGFnXSB8fCB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdPYmplY3QnO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG59IC8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5cblxuZnVuY3Rpb24gd2lsbENvZXJjaW9uVGhyb3codmFsdWUpIHtcbiAge1xuICAgIHRyeSB7XG4gICAgICB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAgLy8gSWYgeW91IGVuZGVkIHVwIGhlcmUgYnkgZm9sbG93aW5nIGFuIGV4Y2VwdGlvbiBjYWxsIHN0YWNrLCBoZXJlJ3Mgd2hhdCdzXG4gIC8vIGhhcHBlbmVkOiB5b3Ugc3VwcGxpZWQgYW4gb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBSZWFjdCAoYXMgYSBwcm9wLCBrZXksXG4gIC8vIERPTSBhdHRyaWJ1dGUsIENTUyBwcm9wZXJ0eSwgc3RyaW5nIHJlZiwgZXRjLikgYW5kIHdoZW4gUmVhY3QgdHJpZWQgdG9cbiAgLy8gY29lcmNlIGl0IHRvIGEgc3RyaW5nIHVzaW5nIGAnJyArIHZhbHVlYCwgYW4gZXhjZXB0aW9uIHdhcyB0aHJvd24uXG4gIC8vXG4gIC8vIFRoZSBtb3N0IGNvbW1vbiB0eXBlcyB0aGF0IHdpbGwgY2F1c2UgdGhpcyBleGNlcHRpb24gYXJlIGBTeW1ib2xgIGluc3RhbmNlc1xuICAvLyBhbmQgVGVtcG9yYWwgb2JqZWN0cyBsaWtlIGBUZW1wb3JhbC5JbnN0YW50YC4gQnV0IGFueSBvYmplY3QgdGhhdCBoYXMgYVxuICAvLyBgdmFsdWVPZmAgb3IgYFtTeW1ib2wudG9QcmltaXRpdmVdYCBtZXRob2QgdGhhdCB0aHJvd3Mgd2lsbCBhbHNvIGNhdXNlIHRoaXNcbiAgLy8gZXhjZXB0aW9uLiAoTGlicmFyeSBhdXRob3JzIGRvIHRoaXMgdG8gcHJldmVudCB1c2VycyBmcm9tIHVzaW5nIGJ1aWx0LWluXG4gIC8vIG51bWVyaWMgb3BlcmF0b3JzIGxpa2UgYCtgIG9yIGNvbXBhcmlzb24gb3BlcmF0b3JzIGxpa2UgYD49YCBiZWNhdXNlIGN1c3RvbVxuICAvLyBtZXRob2RzIGFyZSBuZWVkZWQgdG8gcGVyZm9ybSBhY2N1cmF0ZSBhcml0aG1ldGljIG9yIGNvbXBhcmlzb24uKVxuICAvL1xuICAvLyBUbyBmaXggdGhlIHByb2JsZW0sIGNvZXJjZSB0aGlzIG9iamVjdCBvciBzeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcgYmVmb3JlXG4gIC8vIHBhc3NpbmcgaXQgdG8gUmVhY3QuIFRoZSBtb3N0IHJlbGlhYmxlIHdheSBpcyB1c3VhbGx5IGBTdHJpbmcodmFsdWUpYC5cbiAgLy9cbiAgLy8gVG8gZmluZCB3aGljaCB2YWx1ZSBpcyB0aHJvd2luZywgY2hlY2sgdGhlIGJyb3dzZXIgb3IgZGVidWdnZXIgY29uc29sZS5cbiAgLy8gQmVmb3JlIHRoaXMgZXhjZXB0aW9uIHdhcyB0aHJvd24sIHRoZXJlIHNob3VsZCBiZSBgY29uc29sZS5lcnJvcmAgb3V0cHV0XG4gIC8vIHRoYXQgc2hvd3MgdGhlIHR5cGUgKFN5bWJvbCwgVGVtcG9yYWwuUGxhaW5EYXRlLCBldGMuKSB0aGF0IGNhdXNlZCB0aGVcbiAgLy8gcHJvYmxlbSBhbmQgaG93IHRoYXQgdHlwZSB3YXMgdXNlZDoga2V5LCBhdHJyaWJ1dGUsIGlucHV0IHZhbHVlIHByb3AsIGV0Yy5cbiAgLy8gSW4gbW9zdCBjYXNlcywgdGhpcyBjb25zb2xlIG91dHB1dCBhbHNvIHNob3dzIHRoZSBjb21wb25lbnQgYW5kIGl0c1xuICAvLyBhbmNlc3RvciBjb21wb25lbnRzIHdoZXJlIHRoZSBleGNlcHRpb24gaGFwcGVuZWQuXG4gIC8vXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICByZXR1cm4gJycgKyB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gY2hlY2tBdHRyaWJ1dGVTdHJpbmdDb2VyY2lvbih2YWx1ZSwgYXR0cmlidXRlTmFtZSkge1xuICB7XG4gICAgaWYgKHdpbGxDb2VyY2lvblRocm93KHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1RoZSBwcm92aWRlZCBgJXNgIGF0dHJpYnV0ZSBpcyBhbiB1bnN1cHBvcnRlZCB0eXBlICVzLicgKyAnIFRoaXMgdmFsdWUgbXVzdCBiZSBjb2VyY2VkIHRvIGEgc3RyaW5nIGJlZm9yZSBiZWZvcmUgdXNpbmcgaXQgaGVyZS4nLCBhdHRyaWJ1dGVOYW1lLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQga2V5IGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tQcm9wU3RyaW5nQ29lcmNpb24odmFsdWUsIHByb3BOYW1lKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignVGhlIHByb3ZpZGVkIGAlc2AgcHJvcCBpcyBhbiB1bnN1cHBvcnRlZCB0eXBlICVzLicgKyAnIFRoaXMgdmFsdWUgbXVzdCBiZSBjb2VyY2VkIHRvIGEgc3RyaW5nIGJlZm9yZSBiZWZvcmUgdXNpbmcgaXQgaGVyZS4nLCBwcm9wTmFtZSwgdHlwZU5hbWUodmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7IC8vIHRocm93ICh0byBoZWxwIGNhbGxlcnMgZmluZCB0cm91Ymxlc2hvb3RpbmcgY29tbWVudHMpXG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBjaGVja0NTU1Byb3BlcnR5U3RyaW5nQ29lcmNpb24odmFsdWUsIHByb3BOYW1lKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignVGhlIHByb3ZpZGVkIGAlc2AgQ1NTIHByb3BlcnR5IGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHByb3BOYW1lLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNoZWNrSHRtbFN0cmluZ0NvZXJjaW9uKHZhbHVlKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignVGhlIHByb3ZpZGVkIEhUTUwgbWFya3VwIHVzZXMgYSB2YWx1ZSBvZiB1bnN1cHBvcnRlZCB0eXBlICVzLicgKyAnIFRoaXMgdmFsdWUgbXVzdCBiZSBjb2VyY2VkIHRvIGEgc3RyaW5nIGJlZm9yZSBiZWZvcmUgdXNpbmcgaXQgaGVyZS4nLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICB7XG4gICAgaWYgKHdpbGxDb2VyY2lvblRocm93KHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ0Zvcm0gZmllbGQgdmFsdWVzICh2YWx1ZSwgY2hlY2tlZCwgZGVmYXVsdFZhbHVlLCBvciBkZWZhdWx0Q2hlY2tlZCBwcm9wcyknICsgJyBtdXN0IGJlIHN0cmluZ3MsIG5vdCAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgdHlwZU5hbWUodmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7IC8vIHRocm93ICh0byBoZWxwIGNhbGxlcnMgZmluZCB0cm91Ymxlc2hvb3RpbmcgY29tbWVudHMpXG4gICAgfVxuICB9XG59XG5cbi8vIEEgcmVzZXJ2ZWQgYXR0cmlidXRlLlxuLy8gSXQgaXMgaGFuZGxlZCBieSBSZWFjdCBzZXBhcmF0ZWx5IGFuZCBzaG91bGRuJ3QgYmUgd3JpdHRlbiB0byB0aGUgRE9NLlxudmFyIFJFU0VSVkVEID0gMDsgLy8gQSBzaW1wbGUgc3RyaW5nIGF0dHJpYnV0ZS5cbi8vIEF0dHJpYnV0ZXMgdGhhdCBhcmVuJ3QgaW4gdGhlIGZpbHRlciBhcmUgcHJlc3VtZWQgdG8gaGF2ZSB0aGlzIHR5cGUuXG5cbnZhciBTVFJJTkcgPSAxOyAvLyBBIHN0cmluZyBhdHRyaWJ1dGUgdGhhdCBhY2NlcHRzIGJvb2xlYW5zIGluIFJlYWN0LiBJbiBIVE1MLCB0aGVzZSBhcmUgY2FsbGVkXG4vLyBcImVudW1lcmF0ZWRcIiBhdHRyaWJ1dGVzIHdpdGggXCJ0cnVlXCIgYW5kIFwiZmFsc2VcIiBhcyBwb3NzaWJsZSB2YWx1ZXMuXG4vLyBXaGVuIHRydWUsIGl0IHNob3VsZCBiZSBzZXQgdG8gYSBcInRydWVcIiBzdHJpbmcuXG4vLyBXaGVuIGZhbHNlLCBpdCBzaG91bGQgYmUgc2V0IHRvIGEgXCJmYWxzZVwiIHN0cmluZy5cblxudmFyIEJPT0xFQU5JU0hfU1RSSU5HID0gMjsgLy8gQSByZWFsIGJvb2xlYW4gYXR0cmlidXRlLlxuLy8gV2hlbiB0cnVlLCBpdCBzaG91bGQgYmUgcHJlc2VudCAoc2V0IGVpdGhlciB0byBhbiBlbXB0eSBzdHJpbmcgb3IgaXRzIG5hbWUpLlxuLy8gV2hlbiBmYWxzZSwgaXQgc2hvdWxkIGJlIG9taXR0ZWQuXG5cbnZhciBCT09MRUFOID0gMzsgLy8gQW4gYXR0cmlidXRlIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBmbGFnIGFzIHdlbGwgYXMgd2l0aCBhIHZhbHVlLlxuLy8gV2hlbiB0cnVlLCBpdCBzaG91bGQgYmUgcHJlc2VudCAoc2V0IGVpdGhlciB0byBhbiBlbXB0eSBzdHJpbmcgb3IgaXRzIG5hbWUpLlxuLy8gV2hlbiBmYWxzZSwgaXQgc2hvdWxkIGJlIG9taXR0ZWQuXG4vLyBGb3IgYW55IG90aGVyIHZhbHVlLCBzaG91bGQgYmUgcHJlc2VudCB3aXRoIHRoYXQgdmFsdWUuXG5cbnZhciBPVkVSTE9BREVEX0JPT0xFQU4gPSA0OyAvLyBBbiBhdHRyaWJ1dGUgdGhhdCBtdXN0IGJlIG51bWVyaWMgb3IgcGFyc2UgYXMgYSBudW1lcmljLlxuLy8gV2hlbiBmYWxzeSwgaXQgc2hvdWxkIGJlIHJlbW92ZWQuXG5cbnZhciBOVU1FUklDID0gNTsgLy8gQW4gYXR0cmlidXRlIHRoYXQgbXVzdCBiZSBwb3NpdGl2ZSBudW1lcmljIG9yIHBhcnNlIGFzIGEgcG9zaXRpdmUgbnVtZXJpYy5cbi8vIFdoZW4gZmFsc3ksIGl0IHNob3VsZCBiZSByZW1vdmVkLlxuXG52YXIgUE9TSVRJVkVfTlVNRVJJQyA9IDY7XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cbnZhciBBVFRSSUJVVEVfTkFNRV9TVEFSVF9DSEFSID0gXCI6QS1aX2EtelxcXFx1MDBDMC1cXFxcdTAwRDZcXFxcdTAwRDgtXFxcXHUwMEY2XFxcXHUwMEY4LVxcXFx1MDJGRlxcXFx1MDM3MC1cXFxcdTAzN0RcXFxcdTAzN0YtXFxcXHUxRkZGXFxcXHUyMDBDLVxcXFx1MjAwRFxcXFx1MjA3MC1cXFxcdTIxOEZcXFxcdTJDMDAtXFxcXHUyRkVGXFxcXHUzMDAxLVxcXFx1RDdGRlxcXFx1RjkwMC1cXFxcdUZEQ0ZcXFxcdUZERjAtXFxcXHVGRkZEXCI7XG4vKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi9cblxudmFyIEFUVFJJQlVURV9OQU1FX0NIQVIgPSBBVFRSSUJVVEVfTkFNRV9TVEFSVF9DSEFSICsgXCJcXFxcLS4wLTlcXFxcdTAwQjdcXFxcdTAzMDAtXFxcXHUwMzZGXFxcXHUyMDNGLVxcXFx1MjA0MFwiO1xudmFyIFZBTElEX0FUVFJJQlVURV9OQU1FX1JFR0VYID0gbmV3IFJlZ0V4cCgnXlsnICsgQVRUUklCVVRFX05BTUVfU1RBUlRfQ0hBUiArICddWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xudmFyIGlsbGVnYWxBdHRyaWJ1dGVOYW1lQ2FjaGUgPSB7fTtcbnZhciB2YWxpZGF0ZWRBdHRyaWJ1dGVOYW1lQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIGlzQXR0cmlidXRlTmFtZVNhZmUoYXR0cmlidXRlTmFtZSkge1xuICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWxpZGF0ZWRBdHRyaWJ1dGVOYW1lQ2FjaGUsIGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChpbGxlZ2FsQXR0cmlidXRlTmFtZUNhY2hlLCBhdHRyaWJ1dGVOYW1lKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChWQUxJRF9BVFRSSUJVVEVfTkFNRV9SRUdFWC50ZXN0KGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgdmFsaWRhdGVkQXR0cmlidXRlTmFtZUNhY2hlW2F0dHJpYnV0ZU5hbWVdID0gdHJ1ZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlsbGVnYWxBdHRyaWJ1dGVOYW1lQ2FjaGVbYXR0cmlidXRlTmFtZV0gPSB0cnVlO1xuXG4gIHtcbiAgICBlcnJvcignSW52YWxpZCBhdHRyaWJ1dGUgbmFtZTogYCVzYCcsIGF0dHJpYnV0ZU5hbWUpO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gc2hvdWxkSWdub3JlQXR0cmlidXRlKG5hbWUsIHByb3BlcnR5SW5mbywgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgaWYgKHByb3BlcnR5SW5mbyAhPT0gbnVsbCkge1xuICAgIHJldHVybiBwcm9wZXJ0eUluZm8udHlwZSA9PT0gUkVTRVJWRUQ7XG4gIH1cblxuICBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAobmFtZS5sZW5ndGggPiAyICYmIChuYW1lWzBdID09PSAnbycgfHwgbmFtZVswXSA9PT0gJ08nKSAmJiAobmFtZVsxXSA9PT0gJ24nIHx8IG5hbWVbMV0gPT09ICdOJykpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHNob3VsZFJlbW92ZUF0dHJpYnV0ZVdpdGhXYXJuaW5nKG5hbWUsIHZhbHVlLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gIGlmIChwcm9wZXJ0eUluZm8gIT09IG51bGwgJiYgcHJvcGVydHlJbmZvLnR5cGUgPT09IFJFU0VSVkVEKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICBjYXNlICdmdW5jdGlvbic6IC8vICRGbG93SXNzdWUgc3ltYm9sIGlzIHBlcmZlY3RseSB2YWxpZCBoZXJlXG5cbiAgICBjYXNlICdzeW1ib2wnOlxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHtcbiAgICAgICAgaWYgKGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BlcnR5SW5mbyAhPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiAhcHJvcGVydHlJbmZvLmFjY2VwdHNCb29sZWFucztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgcHJlZml4ID0gbmFtZS50b0xvd2VyQ2FzZSgpLnNsaWNlKDAsIDUpO1xuICAgICAgICAgIHJldHVybiBwcmVmaXggIT09ICdkYXRhLScgJiYgcHJlZml4ICE9PSAnYXJpYS0nO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5mdW5jdGlvbiBzaG91bGRSZW1vdmVBdHRyaWJ1dGUobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGVXaXRoV2FybmluZyhuYW1lLCB2YWx1ZSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChwcm9wZXJ0eUluZm8gIT09IG51bGwpIHtcblxuICAgIHN3aXRjaCAocHJvcGVydHlJbmZvLnR5cGUpIHtcbiAgICAgIGNhc2UgQk9PTEVBTjpcbiAgICAgICAgcmV0dXJuICF2YWx1ZTtcblxuICAgICAgY2FzZSBPVkVSTE9BREVEX0JPT0xFQU46XG4gICAgICAgIHJldHVybiB2YWx1ZSA9PT0gZmFsc2U7XG5cbiAgICAgIGNhc2UgTlVNRVJJQzpcbiAgICAgICAgcmV0dXJuIGlzTmFOKHZhbHVlKTtcblxuICAgICAgY2FzZSBQT1NJVElWRV9OVU1FUklDOlxuICAgICAgICByZXR1cm4gaXNOYU4odmFsdWUpIHx8IHZhbHVlIDwgMTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBnZXRQcm9wZXJ0eUluZm8obmFtZSkge1xuICByZXR1cm4gcHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IHByb3BlcnRpZXNbbmFtZV0gOiBudWxsO1xufVxuXG5mdW5jdGlvbiBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgdHlwZSwgbXVzdFVzZVByb3BlcnR5LCBhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVOYW1lc3BhY2UsIHNhbml0aXplVVJMLCByZW1vdmVFbXB0eVN0cmluZykge1xuICB0aGlzLmFjY2VwdHNCb29sZWFucyA9IHR5cGUgPT09IEJPT0xFQU5JU0hfU1RSSU5HIHx8IHR5cGUgPT09IEJPT0xFQU4gfHwgdHlwZSA9PT0gT1ZFUkxPQURFRF9CT09MRUFOO1xuICB0aGlzLmF0dHJpYnV0ZU5hbWUgPSBhdHRyaWJ1dGVOYW1lO1xuICB0aGlzLmF0dHJpYnV0ZU5hbWVzcGFjZSA9IGF0dHJpYnV0ZU5hbWVzcGFjZTtcbiAgdGhpcy5tdXN0VXNlUHJvcGVydHkgPSBtdXN0VXNlUHJvcGVydHk7XG4gIHRoaXMucHJvcGVydHlOYW1lID0gbmFtZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5zYW5pdGl6ZVVSTCA9IHNhbml0aXplVVJMO1xuICB0aGlzLnJlbW92ZUVtcHR5U3RyaW5nID0gcmVtb3ZlRW1wdHlTdHJpbmc7XG59IC8vIFdoZW4gYWRkaW5nIGF0dHJpYnV0ZXMgdG8gdGhpcyBsaXN0LCBiZSBzdXJlIHRvIGFsc28gYWRkIHRoZW0gdG9cbi8vIHRoZSBgcG9zc2libGVTdGFuZGFyZE5hbWVzYCBtb2R1bGUgdG8gZW5zdXJlIGNhc2luZyBhbmQgaW5jb3JyZWN0XG4vLyBuYW1lIHdhcm5pbmdzLlxuXG5cbnZhciBwcm9wZXJ0aWVzID0ge307IC8vIFRoZXNlIHByb3BzIGFyZSByZXNlcnZlZCBieSBSZWFjdC4gVGhleSBzaG91bGRuJ3QgYmUgd3JpdHRlbiB0byB0aGUgRE9NLlxuXG52YXIgcmVzZXJ2ZWRQcm9wcyA9IFsnY2hpbGRyZW4nLCAnZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwnLCAvLyBUT0RPOiBUaGlzIHByZXZlbnRzIHRoZSBhc3NpZ25tZW50IG9mIGRlZmF1bHRWYWx1ZSB0byByZWd1bGFyXG4vLyBlbGVtZW50cyAobm90IGp1c3QgaW5wdXRzKS4gTm93IHRoYXQgUmVhY3RET01JbnB1dCBhc3NpZ25zIHRvIHRoZVxuLy8gZGVmYXVsdFZhbHVlIHByb3BlcnR5IC0tIGRvIHdlIG5lZWQgdGhpcz9cbidkZWZhdWx0VmFsdWUnLCAnZGVmYXVsdENoZWNrZWQnLCAnaW5uZXJIVE1MJywgJ3N1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZycsICdzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcnLCAnc3R5bGUnXTtcblxucmVzZXJ2ZWRQcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFJFU0VSVkVELCBmYWxzZSwgLy8gbXVzdFVzZVByb3BlcnR5XG4gIG5hbWUsIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gQSBmZXcgUmVhY3Qgc3RyaW5nIGF0dHJpYnV0ZXMgaGF2ZSBhIGRpZmZlcmVudCBuYW1lLlxuLy8gVGhpcyBpcyBhIG1hcHBpbmcgZnJvbSBSZWFjdCBwcm9wIG5hbWVzIHRvIHRoZSBhdHRyaWJ1dGUgbmFtZXMuXG5cbltbJ2FjY2VwdENoYXJzZXQnLCAnYWNjZXB0LWNoYXJzZXQnXSwgWydjbGFzc05hbWUnLCAnY2xhc3MnXSwgWydodG1sRm9yJywgJ2ZvciddLCBbJ2h0dHBFcXVpdicsICdodHRwLWVxdWl2J11dLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHtcbiAgdmFyIG5hbWUgPSBfcmVmWzBdLFxuICAgICAgYXR0cmlidXRlTmFtZSA9IF9yZWZbMV07XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBcImVudW1lcmF0ZWRcIiBIVE1MIGF0dHJpYnV0ZXMgdGhhdCBhY2NlcHQgXCJ0cnVlXCIgYW5kIFwiZmFsc2VcIi5cbi8vIEluIFJlYWN0LCB3ZSBsZXQgdXNlcnMgcGFzcyBgdHJ1ZWAgYW5kIGBmYWxzZWAgZXZlbiB0aG91Z2ggdGVjaG5pY2FsbHlcbi8vIHRoZXNlIGFyZW4ndCBib29sZWFuIGF0dHJpYnV0ZXMgKHRoZXkgYXJlIGNvZXJjZWQgdG8gc3RyaW5ncykuXG5cblsnY29udGVudEVkaXRhYmxlJywgJ2RyYWdnYWJsZScsICdzcGVsbENoZWNrJywgJ3ZhbHVlJ10uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBCT09MRUFOSVNIX1NUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLnRvTG93ZXJDYXNlKCksIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXJlIFwiZW51bWVyYXRlZFwiIFNWRyBhdHRyaWJ1dGVzIHRoYXQgYWNjZXB0IFwidHJ1ZVwiIGFuZCBcImZhbHNlXCIuXG4vLyBJbiBSZWFjdCwgd2UgbGV0IHVzZXJzIHBhc3MgYHRydWVgIGFuZCBgZmFsc2VgIGV2ZW4gdGhvdWdoIHRlY2huaWNhbGx5XG4vLyB0aGVzZSBhcmVuJ3QgYm9vbGVhbiBhdHRyaWJ1dGVzICh0aGV5IGFyZSBjb2VyY2VkIHRvIHN0cmluZ3MpLlxuLy8gU2luY2UgdGhlc2UgYXJlIFNWRyBhdHRyaWJ1dGVzLCB0aGVpciBhdHRyaWJ1dGUgbmFtZXMgYXJlIGNhc2Utc2Vuc2l0aXZlLlxuXG5bJ2F1dG9SZXZlcnNlJywgJ2V4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQnLCAnZm9jdXNhYmxlJywgJ3ByZXNlcnZlQWxwaGEnXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIEJPT0xFQU5JU0hfU1RSSU5HLCBmYWxzZSwgLy8gbXVzdFVzZVByb3BlcnR5XG4gIG5hbWUsIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXJlIEhUTUwgYm9vbGVhbiBhdHRyaWJ1dGVzLlxuXG5bJ2FsbG93RnVsbFNjcmVlbicsICdhc3luYycsIC8vIE5vdGU6IHRoZXJlIGlzIGEgc3BlY2lhbCBjYXNlIHRoYXQgcHJldmVudHMgaXQgZnJvbSBiZWluZyB3cml0dGVuIHRvIHRoZSBET01cbi8vIG9uIHRoZSBjbGllbnQgc2lkZSBiZWNhdXNlIHRoZSBicm93c2VycyBhcmUgaW5jb25zaXN0ZW50LiBJbnN0ZWFkIHdlIGNhbGwgZm9jdXMoKS5cbidhdXRvRm9jdXMnLCAnYXV0b1BsYXknLCAnY29udHJvbHMnLCAnZGVmYXVsdCcsICdkZWZlcicsICdkaXNhYmxlZCcsICdkaXNhYmxlUGljdHVyZUluUGljdHVyZScsICdkaXNhYmxlUmVtb3RlUGxheWJhY2snLCAnZm9ybU5vVmFsaWRhdGUnLCAnaGlkZGVuJywgJ2xvb3AnLCAnbm9Nb2R1bGUnLCAnbm9WYWxpZGF0ZScsICdvcGVuJywgJ3BsYXlzSW5saW5lJywgJ3JlYWRPbmx5JywgJ3JlcXVpcmVkJywgJ3JldmVyc2VkJywgJ3Njb3BlZCcsICdzZWFtbGVzcycsIC8vIE1pY3JvZGF0YVxuJ2l0ZW1TY29wZSddLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgcHJvcGVydGllc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgQk9PTEVBTiwgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLnRvTG93ZXJDYXNlKCksIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXJlIHRoZSBmZXcgUmVhY3QgcHJvcHMgdGhhdCB3ZSBzZXQgYXMgRE9NIHByb3BlcnRpZXNcbi8vIHJhdGhlciB0aGFuIGF0dHJpYnV0ZXMuIFRoZXNlIGFyZSBhbGwgYm9vbGVhbnMuXG5cblsnY2hlY2tlZCcsIC8vIE5vdGU6IGBvcHRpb24uc2VsZWN0ZWRgIGlzIG5vdCB1cGRhdGVkIGlmIGBzZWxlY3QubXVsdGlwbGVgIGlzXG4vLyBkaXNhYmxlZCB3aXRoIGByZW1vdmVBdHRyaWJ1dGVgLiBXZSBoYXZlIHNwZWNpYWwgbG9naWMgZm9yIGhhbmRsaW5nIHRoaXMuXG4nbXVsdGlwbGUnLCAnbXV0ZWQnLCAnc2VsZWN0ZWQnIC8vIE5PVEU6IGlmIHlvdSBhZGQgYSBjYW1lbENhc2VkIHByb3AgdG8gdGhpcyBsaXN0LFxuLy8geW91J2xsIG5lZWQgdG8gc2V0IGF0dHJpYnV0ZU5hbWUgdG8gbmFtZS50b0xvd2VyQ2FzZSgpXG4vLyBpbnN0ZWFkIGluIHRoZSBhc3NpZ25tZW50IGJlbG93LlxuXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIEJPT0xFQU4sIHRydWUsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBIVE1MIGF0dHJpYnV0ZXMgdGhhdCBhcmUgXCJvdmVybG9hZGVkIGJvb2xlYW5zXCI6IHRoZXkgYmVoYXZlIGxpa2Vcbi8vIGJvb2xlYW5zLCBidXQgY2FuIGFsc28gYWNjZXB0IGEgc3RyaW5nIHZhbHVlLlxuXG5bJ2NhcHR1cmUnLCAnZG93bmxvYWQnIC8vIE5PVEU6IGlmIHlvdSBhZGQgYSBjYW1lbENhc2VkIHByb3AgdG8gdGhpcyBsaXN0LFxuLy8geW91J2xsIG5lZWQgdG8gc2V0IGF0dHJpYnV0ZU5hbWUgdG8gbmFtZS50b0xvd2VyQ2FzZSgpXG4vLyBpbnN0ZWFkIGluIHRoZSBhc3NpZ25tZW50IGJlbG93LlxuXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIE9WRVJMT0FERURfQk9PTEVBTiwgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBIVE1MIGF0dHJpYnV0ZXMgdGhhdCBtdXN0IGJlIHBvc2l0aXZlIG51bWJlcnMuXG5cblsnY29scycsICdyb3dzJywgJ3NpemUnLCAnc3BhbicgLy8gTk9URTogaWYgeW91IGFkZCBhIGNhbWVsQ2FzZWQgcHJvcCB0byB0aGlzIGxpc3QsXG4vLyB5b3UnbGwgbmVlZCB0byBzZXQgYXR0cmlidXRlTmFtZSB0byBuYW1lLnRvTG93ZXJDYXNlKClcbi8vIGluc3RlYWQgaW4gdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG5dLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgcHJvcGVydGllc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgUE9TSVRJVkVfTlVNRVJJQywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBIVE1MIGF0dHJpYnV0ZXMgdGhhdCBtdXN0IGJlIG51bWJlcnMuXG5cblsncm93U3BhbicsICdzdGFydCddLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgcHJvcGVydGllc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgTlVNRVJJQywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLnRvTG93ZXJDYXNlKCksIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTtcbnZhciBDQU1FTElaRSA9IC9bXFwtXFw6XShbYS16XSkvZztcblxudmFyIGNhcGl0YWxpemUgPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgcmV0dXJuIHRva2VuWzFdLnRvVXBwZXJDYXNlKCk7XG59OyAvLyBUaGlzIGlzIGEgbGlzdCBvZiBhbGwgU1ZHIGF0dHJpYnV0ZXMgdGhhdCBuZWVkIHNwZWNpYWwgY2FzaW5nLCBuYW1lc3BhY2luZyxcbi8vIG9yIGJvb2xlYW4gdmFsdWUgYXNzaWdubWVudC4gUmVndWxhciBhdHRyaWJ1dGVzIHRoYXQganVzdCBhY2NlcHQgc3RyaW5nc1xuLy8gYW5kIGhhdmUgdGhlIHNhbWUgbmFtZXMgYXJlIG9taXR0ZWQsIGp1c3QgbGlrZSBpbiB0aGUgSFRNTCBhdHRyaWJ1dGUgZmlsdGVyLlxuLy8gU29tZSBvZiB0aGVzZSBhdHRyaWJ1dGVzIGNhbiBiZSBoYXJkIHRvIGZpbmQuIFRoaXMgbGlzdCB3YXMgY3JlYXRlZCBieVxuLy8gc2NyYXBpbmcgdGhlIE1ETiBkb2N1bWVudGF0aW9uLlxuXG5cblsnYWNjZW50LWhlaWdodCcsICdhbGlnbm1lbnQtYmFzZWxpbmUnLCAnYXJhYmljLWZvcm0nLCAnYmFzZWxpbmUtc2hpZnQnLCAnY2FwLWhlaWdodCcsICdjbGlwLXBhdGgnLCAnY2xpcC1ydWxlJywgJ2NvbG9yLWludGVycG9sYXRpb24nLCAnY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzJywgJ2NvbG9yLXByb2ZpbGUnLCAnY29sb3ItcmVuZGVyaW5nJywgJ2RvbWluYW50LWJhc2VsaW5lJywgJ2VuYWJsZS1iYWNrZ3JvdW5kJywgJ2ZpbGwtb3BhY2l0eScsICdmaWxsLXJ1bGUnLCAnZmxvb2QtY29sb3InLCAnZmxvb2Qtb3BhY2l0eScsICdmb250LWZhbWlseScsICdmb250LXNpemUnLCAnZm9udC1zaXplLWFkanVzdCcsICdmb250LXN0cmV0Y2gnLCAnZm9udC1zdHlsZScsICdmb250LXZhcmlhbnQnLCAnZm9udC13ZWlnaHQnLCAnZ2x5cGgtbmFtZScsICdnbHlwaC1vcmllbnRhdGlvbi1ob3Jpem9udGFsJywgJ2dseXBoLW9yaWVudGF0aW9uLXZlcnRpY2FsJywgJ2hvcml6LWFkdi14JywgJ2hvcml6LW9yaWdpbi14JywgJ2ltYWdlLXJlbmRlcmluZycsICdsZXR0ZXItc3BhY2luZycsICdsaWdodGluZy1jb2xvcicsICdtYXJrZXItZW5kJywgJ21hcmtlci1taWQnLCAnbWFya2VyLXN0YXJ0JywgJ292ZXJsaW5lLXBvc2l0aW9uJywgJ292ZXJsaW5lLXRoaWNrbmVzcycsICdwYWludC1vcmRlcicsICdwYW5vc2UtMScsICdwb2ludGVyLWV2ZW50cycsICdyZW5kZXJpbmctaW50ZW50JywgJ3NoYXBlLXJlbmRlcmluZycsICdzdG9wLWNvbG9yJywgJ3N0b3Atb3BhY2l0eScsICdzdHJpa2V0aHJvdWdoLXBvc2l0aW9uJywgJ3N0cmlrZXRocm91Z2gtdGhpY2tuZXNzJywgJ3N0cm9rZS1kYXNoYXJyYXknLCAnc3Ryb2tlLWRhc2hvZmZzZXQnLCAnc3Ryb2tlLWxpbmVjYXAnLCAnc3Ryb2tlLWxpbmVqb2luJywgJ3N0cm9rZS1taXRlcmxpbWl0JywgJ3N0cm9rZS1vcGFjaXR5JywgJ3N0cm9rZS13aWR0aCcsICd0ZXh0LWFuY2hvcicsICd0ZXh0LWRlY29yYXRpb24nLCAndGV4dC1yZW5kZXJpbmcnLCAndW5kZXJsaW5lLXBvc2l0aW9uJywgJ3VuZGVybGluZS10aGlja25lc3MnLCAndW5pY29kZS1iaWRpJywgJ3VuaWNvZGUtcmFuZ2UnLCAndW5pdHMtcGVyLWVtJywgJ3YtYWxwaGFiZXRpYycsICd2LWhhbmdpbmcnLCAndi1pZGVvZ3JhcGhpYycsICd2LW1hdGhlbWF0aWNhbCcsICd2ZWN0b3ItZWZmZWN0JywgJ3ZlcnQtYWR2LXknLCAndmVydC1vcmlnaW4teCcsICd2ZXJ0LW9yaWdpbi15JywgJ3dvcmQtc3BhY2luZycsICd3cml0aW5nLW1vZGUnLCAneG1sbnM6eGxpbmsnLCAneC1oZWlnaHQnIC8vIE5PVEU6IGlmIHlvdSBhZGQgYSBjYW1lbENhc2VkIHByb3AgdG8gdGhpcyBsaXN0LFxuLy8geW91J2xsIG5lZWQgdG8gc2V0IGF0dHJpYnV0ZU5hbWUgdG8gbmFtZS50b0xvd2VyQ2FzZSgpXG4vLyBpbnN0ZWFkIGluIHRoZSBhc3NpZ25tZW50IGJlbG93LlxuXS5mb3JFYWNoKGZ1bmN0aW9uIChhdHRyaWJ1dGVOYW1lKSB7XG4gIHZhciBuYW1lID0gYXR0cmlidXRlTmFtZS5yZXBsYWNlKENBTUVMSVpFLCBjYXBpdGFsaXplKTtcbiAgcHJvcGVydGllc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgU1RSSU5HLCBmYWxzZSwgLy8gbXVzdFVzZVByb3BlcnR5XG4gIGF0dHJpYnV0ZU5hbWUsIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFN0cmluZyBTVkcgYXR0cmlidXRlcyB3aXRoIHRoZSB4bGluayBuYW1lc3BhY2UuXG5cblsneGxpbms6YWN0dWF0ZScsICd4bGluazphcmNyb2xlJywgJ3hsaW5rOnJvbGUnLCAneGxpbms6c2hvdycsICd4bGluazp0aXRsZScsICd4bGluazp0eXBlJyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkge1xuICB2YXIgbmFtZSA9IGF0dHJpYnV0ZU5hbWUucmVwbGFjZShDQU1FTElaRSwgY2FwaXRhbGl6ZSk7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLCAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaycsIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gU3RyaW5nIFNWRyBhdHRyaWJ1dGVzIHdpdGggdGhlIHhtbCBuYW1lc3BhY2UuXG5cblsneG1sOmJhc2UnLCAneG1sOmxhbmcnLCAneG1sOnNwYWNlJyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkge1xuICB2YXIgbmFtZSA9IGF0dHJpYnV0ZU5hbWUucmVwbGFjZShDQU1FTElaRSwgY2FwaXRhbGl6ZSk7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLCAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJywgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhdHRyaWJ1dGUgZXhpc3RzIGJvdGggaW4gSFRNTCBhbmQgU1ZHLlxuLy8gVGhlIGF0dHJpYnV0ZSBuYW1lIGlzIGNhc2Utc2Vuc2l0aXZlIGluIFNWRyBzbyB3ZSBjYW4ndCBqdXN0IHVzZVxuLy8gdGhlIFJlYWN0IG5hbWUgbGlrZSB3ZSBkbyBmb3IgYXR0cmlidXRlcyB0aGF0IGV4aXN0IG9ubHkgaW4gSFRNTC5cblxuWyd0YWJJbmRleCcsICdjcm9zc09yaWdpbiddLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgcHJvcGVydGllc1thdHRyaWJ1dGVOYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQoYXR0cmlidXRlTmFtZSwgU1RSSU5HLCBmYWxzZSwgLy8gbXVzdFVzZVByb3BlcnR5XG4gIGF0dHJpYnV0ZU5hbWUudG9Mb3dlckNhc2UoKSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhdHRyaWJ1dGVzIGFjY2VwdCBVUkxzLiBUaGVzZSBtdXN0IG5vdCBhbGxvdyBqYXZhc2NyaXB0OiBVUkxTLlxuLy8gVGhlc2Ugd2lsbCBhbHNvIG5lZWQgdG8gYWNjZXB0IFRydXN0ZWQgVHlwZXMgb2JqZWN0IGluIHRoZSBmdXR1cmUuXG5cbnZhciB4bGlua0hyZWYgPSAneGxpbmtIcmVmJztcbnByb3BlcnRpZXNbeGxpbmtIcmVmXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQoJ3hsaW5rSHJlZicsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuJ3hsaW5rOmhyZWYnLCAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaycsIHRydWUsIC8vIHNhbml0aXplVVJMXG5mYWxzZSk7XG5bJ3NyYycsICdocmVmJywgJ2FjdGlvbicsICdmb3JtQWN0aW9uJ10uZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkge1xuICBwcm9wZXJ0aWVzW2F0dHJpYnV0ZU5hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChhdHRyaWJ1dGVOYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICB0cnVlLCAvLyBzYW5pdGl6ZVVSTFxuICB0cnVlKTtcbn0pO1xuXG4vLyBhbmQgYW55IG5ld2xpbmUgb3IgdGFiIGFyZSBmaWx0ZXJlZCBvdXQgYXMgaWYgdGhleSdyZSBub3QgcGFydCBvZiB0aGUgVVJMLlxuLy8gaHR0cHM6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmwtcGFyc2luZ1xuLy8gVGFiIG9yIG5ld2xpbmUgYXJlIGRlZmluZWQgYXMgXFxyXFxuXFx0OlxuLy8gaHR0cHM6Ly9pbmZyYS5zcGVjLndoYXR3Zy5vcmcvI2FzY2lpLXRhYi1vci1uZXdsaW5lXG4vLyBBIEMwIGNvbnRyb2wgaXMgYSBjb2RlIHBvaW50IGluIHRoZSByYW5nZSBcXHUwMDAwIE5VTEwgdG8gXFx1MDAxRlxuLy8gSU5GT1JNQVRJT04gU0VQQVJBVE9SIE9ORSwgaW5jbHVzaXZlOlxuLy8gaHR0cHM6Ly9pbmZyYS5zcGVjLndoYXR3Zy5vcmcvI2MwLWNvbnRyb2wtb3Itc3BhY2VcblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG52YXIgaXNKYXZhU2NyaXB0UHJvdG9jb2wgPSAvXltcXHUwMDAwLVxcdTAwMUYgXSpqW1xcclxcblxcdF0qYVtcXHJcXG5cXHRdKnZbXFxyXFxuXFx0XSphW1xcclxcblxcdF0qc1tcXHJcXG5cXHRdKmNbXFxyXFxuXFx0XSpyW1xcclxcblxcdF0qaVtcXHJcXG5cXHRdKnBbXFxyXFxuXFx0XSp0W1xcclxcblxcdF0qXFw6L2k7XG52YXIgZGlkV2FybiA9IGZhbHNlO1xuXG5mdW5jdGlvbiBzYW5pdGl6ZVVSTCh1cmwpIHtcbiAge1xuICAgIGlmICghZGlkV2FybiAmJiBpc0phdmFTY3JpcHRQcm90b2NvbC50ZXN0KHVybCkpIHtcbiAgICAgIGRpZFdhcm4gPSB0cnVlO1xuXG4gICAgICBlcnJvcignQSBmdXR1cmUgdmVyc2lvbiBvZiBSZWFjdCB3aWxsIGJsb2NrIGphdmFzY3JpcHQ6IFVSTHMgYXMgYSBzZWN1cml0eSBwcmVjYXV0aW9uLiAnICsgJ1VzZSBldmVudCBoYW5kbGVycyBpbnN0ZWFkIGlmIHlvdSBjYW4uIElmIHlvdSBuZWVkIHRvIGdlbmVyYXRlIHVuc2FmZSBIVE1MIHRyeSAnICsgJ3VzaW5nIGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MIGluc3RlYWQuIFJlYWN0IHdhcyBwYXNzZWQgJXMuJywgSlNPTi5zdHJpbmdpZnkodXJsKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSB2YWx1ZSBmb3IgYSBwcm9wZXJ0eSBvbiBhIG5vZGUuIE9ubHkgdXNlZCBpbiBERVYgZm9yIFNTUiB2YWxpZGF0aW9uLlxuICogVGhlIFwiZXhwZWN0ZWRcIiBhcmd1bWVudCBpcyB1c2VkIGFzIGEgaGludCBvZiB3aGF0IHRoZSBleHBlY3RlZCB2YWx1ZSBpcy5cbiAqIFNvbWUgcHJvcGVydGllcyBoYXZlIG11bHRpcGxlIGVxdWl2YWxlbnQgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBnZXRWYWx1ZUZvclByb3BlcnR5KG5vZGUsIG5hbWUsIGV4cGVjdGVkLCBwcm9wZXJ0eUluZm8pIHtcbiAge1xuICAgIGlmIChwcm9wZXJ0eUluZm8ubXVzdFVzZVByb3BlcnR5KSB7XG4gICAgICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHlJbmZvLnByb3BlcnR5TmFtZTtcbiAgICAgIHJldHVybiBub2RlW3Byb3BlcnR5TmFtZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoaXMgY2hlY2sgcHJvdGVjdHMgbXVsdGlwbGUgdXNlcyBvZiBgZXhwZWN0ZWRgLCB3aGljaCBpcyB3aHkgdGhlXG4gICAgICAvLyByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvbiBydWxlIGlzIGRpc2FibGVkIGluIHNldmVyYWwgc3BvdHNcbiAgICAgIC8vIGJlbG93LlxuICAgICAge1xuICAgICAgICBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKGV4cGVjdGVkLCBuYW1lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCBwcm9wZXJ0eUluZm8uc2FuaXRpemVVUkwpIHtcbiAgICAgICAgLy8gSWYgd2UgaGF2ZW4ndCBmdWxseSBkaXNhYmxlZCBqYXZhc2NyaXB0OiBVUkxzLCBhbmQgaWZcbiAgICAgICAgLy8gdGhlIGh5ZHJhdGlvbiBpcyBzdWNjZXNzZnVsIG9mIGEgamF2YXNjcmlwdDogVVJMLCB3ZVxuICAgICAgICAvLyBzdGlsbCB3YW50IHRvIHdhcm4gb24gdGhlIGNsaWVudC5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gICAgICAgIHNhbml0aXplVVJMKCcnICsgZXhwZWN0ZWQpO1xuICAgICAgfVxuXG4gICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IHByb3BlcnR5SW5mby5hdHRyaWJ1dGVOYW1lO1xuICAgICAgdmFyIHN0cmluZ1ZhbHVlID0gbnVsbDtcblxuICAgICAgaWYgKHByb3BlcnR5SW5mby50eXBlID09PSBPVkVSTE9BREVEX0JPT0xFQU4pIHtcbiAgICAgICAgaWYgKG5vZGUuaGFzQXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gbm9kZS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSk7XG5cbiAgICAgICAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2hvdWxkUmVtb3ZlQXR0cmlidXRlKG5hbWUsIGV4cGVjdGVkLCBwcm9wZXJ0eUluZm8sIGZhbHNlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIH0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG5cblxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJycgKyBleHBlY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGVkO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub2RlLmhhc0F0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgICBpZiAoc2hvdWxkUmVtb3ZlQXR0cmlidXRlKG5hbWUsIGV4cGVjdGVkLCBwcm9wZXJ0eUluZm8sIGZhbHNlKSkge1xuICAgICAgICAgIC8vIFdlIGhhZCBhbiBhdHRyaWJ1dGUgYnV0IHNob3VsZG4ndCBoYXZlIGhhZCBvbmUsIHNvIHJlYWQgaXRcbiAgICAgICAgICAvLyBmb3IgdGhlIGVycm9yIG1lc3NhZ2UuXG4gICAgICAgICAgcmV0dXJuIG5vZGUuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BlcnR5SW5mby50eXBlID09PSBCT09MRUFOKSB7XG4gICAgICAgICAgLy8gSWYgdGhpcyB3YXMgYSBib29sZWFuLCBpdCBkb2Vzbid0IG1hdHRlciB3aGF0IHRoZSB2YWx1ZSBpc1xuICAgICAgICAgIC8vIHRoZSBmYWN0IHRoYXQgd2UgaGF2ZSBpdCBpcyB0aGUgc2FtZSBhcyB0aGUgZXhwZWN0ZWQuXG4gICAgICAgICAgcmV0dXJuIGV4cGVjdGVkO1xuICAgICAgICB9IC8vIEV2ZW4gaWYgdGhpcyBwcm9wZXJ0eSB1c2VzIGEgbmFtZXNwYWNlIHdlIHVzZSBnZXRBdHRyaWJ1dGVcbiAgICAgICAgLy8gYmVjYXVzZSB3ZSBhc3N1bWUgaXRzIG5hbWVzcGFjZWQgbmFtZSBpcyB0aGUgc2FtZSBhcyBvdXIgY29uZmlnLlxuICAgICAgICAvLyBUbyB1c2UgZ2V0QXR0cmlidXRlTlMgd2UgbmVlZCB0aGUgbG9jYWwgbmFtZSB3aGljaCB3ZSBkb24ndCBoYXZlXG4gICAgICAgIC8vIGluIG91ciBjb25maWcgYXRtLlxuXG5cbiAgICAgICAgc3RyaW5nVmFsdWUgPSBub2RlLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZ1ZhbHVlID09PSBudWxsID8gZXhwZWN0ZWQgOiBzdHJpbmdWYWx1ZTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gICAgICB9IGVsc2UgaWYgKHN0cmluZ1ZhbHVlID09PSAnJyArIGV4cGVjdGVkKSB7XG4gICAgICAgIHJldHVybiBleHBlY3RlZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzdHJpbmdWYWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbi8qKlxuICogR2V0IHRoZSB2YWx1ZSBmb3IgYSBhdHRyaWJ1dGUgb24gYSBub2RlLiBPbmx5IHVzZWQgaW4gREVWIGZvciBTU1IgdmFsaWRhdGlvbi5cbiAqIFRoZSB0aGlyZCBhcmd1bWVudCBpcyB1c2VkIGFzIGEgaGludCBvZiB3aGF0IHRoZSBleHBlY3RlZCB2YWx1ZSBpcy4gU29tZVxuICogYXR0cmlidXRlcyBoYXZlIG11bHRpcGxlIGVxdWl2YWxlbnQgdmFsdWVzLlxuICovXG5cbmZ1bmN0aW9uIGdldFZhbHVlRm9yQXR0cmlidXRlKG5vZGUsIG5hbWUsIGV4cGVjdGVkKSB7XG4gIHtcbiAgICBpZiAoIWlzQXR0cmlidXRlTmFtZVNhZmUobmFtZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIW5vZGUuaGFzQXR0cmlidXRlKG5hbWUpKSB7XG4gICAgICByZXR1cm4gZXhwZWN0ZWQgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlID0gbm9kZS5nZXRBdHRyaWJ1dGUobmFtZSk7XG5cbiAgICB7XG4gICAgICBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKGV4cGVjdGVkLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgPT09ICcnICsgZXhwZWN0ZWQpIHtcbiAgICAgIHJldHVybiBleHBlY3RlZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgZm9yIGEgcHJvcGVydHkgb24gYSBub2RlLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuXG5mdW5jdGlvbiBzZXRWYWx1ZUZvclByb3BlcnR5KG5vZGUsIG5hbWUsIHZhbHVlLCBpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICB2YXIgcHJvcGVydHlJbmZvID0gZ2V0UHJvcGVydHlJbmZvKG5hbWUpO1xuXG4gIGlmIChzaG91bGRJZ25vcmVBdHRyaWJ1dGUobmFtZSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoc2hvdWxkUmVtb3ZlQXR0cmlidXRlKG5hbWUsIHZhbHVlLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgIHZhbHVlID0gbnVsbDtcbiAgfSAvLyBJZiB0aGUgcHJvcCBpc24ndCBpbiB0aGUgc3BlY2lhbCBsaXN0LCB0cmVhdCBpdCBhcyBhIHNpbXBsZSBhdHRyaWJ1dGUuXG5cblxuICBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcgfHwgcHJvcGVydHlJbmZvID09PSBudWxsKSB7XG4gICAgaWYgKGlzQXR0cmlidXRlTmFtZVNhZmUobmFtZSkpIHtcbiAgICAgIHZhciBfYXR0cmlidXRlTmFtZSA9IG5hbWU7XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShfYXR0cmlidXRlTmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB7XG4gICAgICAgICAgY2hlY2tBdHRyaWJ1dGVTdHJpbmdDb2VyY2lvbih2YWx1ZSwgbmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShfYXR0cmlidXRlTmFtZSwgICcnICsgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBtdXN0VXNlUHJvcGVydHkgPSBwcm9wZXJ0eUluZm8ubXVzdFVzZVByb3BlcnR5O1xuXG4gIGlmIChtdXN0VXNlUHJvcGVydHkpIHtcbiAgICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHlJbmZvLnByb3BlcnR5TmFtZTtcblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdmFyIHR5cGUgPSBwcm9wZXJ0eUluZm8udHlwZTtcbiAgICAgIG5vZGVbcHJvcGVydHlOYW1lXSA9IHR5cGUgPT09IEJPT0xFQU4gPyBmYWxzZSA6ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDb250cmFyeSB0byBgc2V0QXR0cmlidXRlYCwgb2JqZWN0IHByb3BlcnRpZXMgYXJlIHByb3Blcmx5XG4gICAgICAvLyBgdG9TdHJpbmdgZWQgYnkgSUU4LzkuXG4gICAgICBub2RlW3Byb3BlcnR5TmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH0gLy8gVGhlIHJlc3QgYXJlIHRyZWF0ZWQgYXMgYXR0cmlidXRlcyB3aXRoIHNwZWNpYWwgY2FzZXMuXG5cblxuICB2YXIgYXR0cmlidXRlTmFtZSA9IHByb3BlcnR5SW5mby5hdHRyaWJ1dGVOYW1lLFxuICAgICAgYXR0cmlidXRlTmFtZXNwYWNlID0gcHJvcGVydHlJbmZvLmF0dHJpYnV0ZU5hbWVzcGFjZTtcblxuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgX3R5cGUgPSBwcm9wZXJ0eUluZm8udHlwZTtcbiAgICB2YXIgYXR0cmlidXRlVmFsdWU7XG5cbiAgICBpZiAoX3R5cGUgPT09IEJPT0xFQU4gfHwgX3R5cGUgPT09IE9WRVJMT0FERURfQk9PTEVBTiAmJiB2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgLy8gSWYgYXR0cmlidXRlIHR5cGUgaXMgYm9vbGVhbiwgd2Uga25vdyBmb3Igc3VyZSBpdCB3b24ndCBiZSBhbiBleGVjdXRpb24gc2lua1xuICAgICAgLy8gYW5kIHdlIHdvbid0IHJlcXVpcmUgVHJ1c3RlZCBUeXBlIGhlcmUuXG4gICAgICBhdHRyaWJ1dGVWYWx1ZSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBgc2V0QXR0cmlidXRlYCB3aXRoIG9iamVjdHMgYmVjb21lcyBvbmx5IGBbb2JqZWN0XWAgaW4gSUU4LzksXG4gICAgICAvLyAoJycgKyB2YWx1ZSkgbWFrZXMgaXQgb3V0cHV0IHRoZSBjb3JyZWN0IHRvU3RyaW5nKCktdmFsdWUuXG4gICAgICB7XG4gICAgICAgIHtcbiAgICAgICAgICBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBhdHRyaWJ1dGVOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gJycgKyB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3BlcnR5SW5mby5zYW5pdGl6ZVVSTCkge1xuICAgICAgICBzYW5pdGl6ZVVSTChhdHRyaWJ1dGVWYWx1ZS50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXR0cmlidXRlTmFtZXNwYWNlKSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZU5TKGF0dHJpYnV0ZU5hbWVzcGFjZSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVWYWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIEFUVEVOVElPTlxuXG52YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKTtcbnZhciBSRUFDVF9QT1JUQUxfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5wb3J0YWwnKTtcbnZhciBSRUFDVF9GUkFHTUVOVF9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmZyYWdtZW50Jyk7XG52YXIgUkVBQ1RfU1RSSUNUX01PREVfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5zdHJpY3RfbW9kZScpO1xudmFyIFJFQUNUX1BST0ZJTEVSX1RZUEUgPSAgU3ltYm9sLmZvcigncmVhY3QucHJvZmlsZXInKTtcbnZhciBSRUFDVF9QUk9WSURFUl9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LnByb3ZpZGVyJyk7XG52YXIgUkVBQ1RfQ09OVEVYVF9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmNvbnRleHQnKTtcbnZhciBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmZvcndhcmRfcmVmJyk7XG52YXIgUkVBQ1RfU1VTUEVOU0VfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZScpO1xudmFyIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZV9saXN0Jyk7XG52YXIgUkVBQ1RfTUVNT19UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0Lm1lbW8nKTtcbnZhciBSRUFDVF9MQVpZX1RZUEUgPSAgU3ltYm9sLmZvcigncmVhY3QubGF6eScpO1xudmFyIFJFQUNUX1NDT1BFX1RZUEUgPSAgU3ltYm9sLmZvcigncmVhY3Quc2NvcGUnKTtcbnZhciBSRUFDVF9ERUJVR19UUkFDSU5HX01PREVfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC5kZWJ1Z190cmFjZV9tb2RlJyk7XG52YXIgUkVBQ1RfT0ZGU0NSRUVOX1RZUEUgPSAgU3ltYm9sLmZvcigncmVhY3Qub2Zmc2NyZWVuJyk7XG52YXIgUkVBQ1RfTEVHQUNZX0hJRERFTl9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmxlZ2FjeV9oaWRkZW4nKTtcbnZhciBSRUFDVF9DQUNIRV9UWVBFID0gIFN5bWJvbC5mb3IoJ3JlYWN0LmNhY2hlJyk7XG52YXIgUkVBQ1RfVFJBQ0lOR19NQVJLRVJfVFlQRSA9ICBTeW1ib2wuZm9yKCdyZWFjdC50cmFjaW5nX21hcmtlcicpO1xudmFyIE1BWUJFX0lURVJBVE9SX1NZTUJPTCA9ICBTeW1ib2wuaXRlcmF0b3I7XG52YXIgRkFVWF9JVEVSQVRPUl9TWU1CT0wgPSAnQEBpdGVyYXRvcic7XG5mdW5jdGlvbiBnZXRJdGVyYXRvckZuKG1heWJlSXRlcmFibGUpIHtcbiAgaWYgKG1heWJlSXRlcmFibGUgPT09IG51bGwgfHwgdHlwZW9mIG1heWJlSXRlcmFibGUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbWF5YmVJdGVyYXRvciA9IE1BWUJFX0lURVJBVE9SX1NZTUJPTCAmJiBtYXliZUl0ZXJhYmxlW01BWUJFX0lURVJBVE9SX1NZTUJPTF0gfHwgbWF5YmVJdGVyYWJsZVtGQVVYX0lURVJBVE9SX1NZTUJPTF07XG5cbiAgaWYgKHR5cGVvZiBtYXliZUl0ZXJhdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIG1heWJlSXRlcmF0b3I7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxudmFyIGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIEhlbHBlcnMgdG8gcGF0Y2ggY29uc29sZS5sb2dzIHRvIGF2b2lkIGxvZ2dpbmcgZHVyaW5nIHNpZGUtZWZmZWN0IGZyZWVcbi8vIHJlcGxheWluZyBvbiByZW5kZXIgZnVuY3Rpb24uIFRoaXMgY3VycmVudGx5IG9ubHkgcGF0Y2hlcyB0aGUgb2JqZWN0XG4vLyBsYXppbHkgd2hpY2ggd29uJ3QgY292ZXIgaWYgdGhlIGxvZyBmdW5jdGlvbiB3YXMgZXh0cmFjdGVkIGVhZ2VybHkuXG4vLyBXZSBjb3VsZCBhbHNvIGVhZ2VybHkgcGF0Y2ggdGhlIG1ldGhvZC5cbnZhciBkaXNhYmxlZERlcHRoID0gMDtcbnZhciBwcmV2TG9nO1xudmFyIHByZXZJbmZvO1xudmFyIHByZXZXYXJuO1xudmFyIHByZXZFcnJvcjtcbnZhciBwcmV2R3JvdXA7XG52YXIgcHJldkdyb3VwQ29sbGFwc2VkO1xudmFyIHByZXZHcm91cEVuZDtcblxuZnVuY3Rpb24gZGlzYWJsZWRMb2coKSB7fVxuXG5kaXNhYmxlZExvZy5fX3JlYWN0RGlzYWJsZWRMb2cgPSB0cnVlO1xuZnVuY3Rpb24gZGlzYWJsZUxvZ3MoKSB7XG4gIHtcbiAgICBpZiAoZGlzYWJsZWREZXB0aCA9PT0gMCkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgICBwcmV2TG9nID0gY29uc29sZS5sb2c7XG4gICAgICBwcmV2SW5mbyA9IGNvbnNvbGUuaW5mbztcbiAgICAgIHByZXZXYXJuID0gY29uc29sZS53YXJuO1xuICAgICAgcHJldkVycm9yID0gY29uc29sZS5lcnJvcjtcbiAgICAgIHByZXZHcm91cCA9IGNvbnNvbGUuZ3JvdXA7XG4gICAgICBwcmV2R3JvdXBDb2xsYXBzZWQgPSBjb25zb2xlLmdyb3VwQ29sbGFwc2VkO1xuICAgICAgcHJldkdyb3VwRW5kID0gY29uc29sZS5ncm91cEVuZDsgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xOTA5OVxuXG4gICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGRpc2FibGVkTG9nLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgfTsgLy8gJEZsb3dGaXhNZSBGbG93IHRoaW5rcyBjb25zb2xlIGlzIGltbXV0YWJsZS5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc29sZSwge1xuICAgICAgICBpbmZvOiBwcm9wcyxcbiAgICAgICAgbG9nOiBwcm9wcyxcbiAgICAgICAgd2FybjogcHJvcHMsXG4gICAgICAgIGVycm9yOiBwcm9wcyxcbiAgICAgICAgZ3JvdXA6IHByb3BzLFxuICAgICAgICBncm91cENvbGxhcHNlZDogcHJvcHMsXG4gICAgICAgIGdyb3VwRW5kOiBwcm9wc1xuICAgICAgfSk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgIH1cblxuICAgIGRpc2FibGVkRGVwdGgrKztcbiAgfVxufVxuZnVuY3Rpb24gcmVlbmFibGVMb2dzKCkge1xuICB7XG4gICAgZGlzYWJsZWREZXB0aC0tO1xuXG4gICAgaWYgKGRpc2FibGVkRGVwdGggPT09IDApIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgICAgdmFyIHByb3BzID0ge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lIEZsb3cgdGhpbmtzIGNvbnNvbGUgaXMgaW1tdXRhYmxlLlxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zb2xlLCB7XG4gICAgICAgIGxvZzogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2TG9nXG4gICAgICAgIH0pLFxuICAgICAgICBpbmZvOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZJbmZvXG4gICAgICAgIH0pLFxuICAgICAgICB3YXJuOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZXYXJuXG4gICAgICAgIH0pLFxuICAgICAgICBlcnJvcjogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2RXJyb3JcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cFxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXBDb2xsYXBzZWQ6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwQ29sbGFwc2VkXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cEVuZDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBFbmRcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgICAgLyogZXNsaW50LWVuYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICB9XG5cbiAgICBpZiAoZGlzYWJsZWREZXB0aCA8IDApIHtcbiAgICAgIGVycm9yKCdkaXNhYmxlZERlcHRoIGZlbGwgYmVsb3cgemVyby4gJyArICdUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnREaXNwYXRjaGVyO1xudmFyIHByZWZpeDtcbmZ1bmN0aW9uIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKG5hbWUsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBWTSBzcGVjaWZpYyBwcmVmaXggdXNlZCBieSBlYWNoIGxpbmUuXG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICB2YXIgbWF0Y2ggPSB4LnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO1xuICAgICAgICBwcmVmaXggPSBtYXRjaCAmJiBtYXRjaFsxXSB8fCAnJztcbiAgICAgIH1cbiAgICB9IC8vIFdlIHVzZSB0aGUgcHJlZml4IHRvIGVuc3VyZSBvdXIgc3RhY2tzIGxpbmUgdXAgd2l0aCBuYXRpdmUgc3RhY2sgZnJhbWVzLlxuXG5cbiAgICByZXR1cm4gJ1xcbicgKyBwcmVmaXggKyBuYW1lO1xuICB9XG59XG52YXIgcmVlbnRyeSA9IGZhbHNlO1xudmFyIGNvbXBvbmVudEZyYW1lQ2FjaGU7XG5cbntcbiAgdmFyIFBvc3NpYmx5V2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcbiAgY29tcG9uZW50RnJhbWVDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAoKTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgY29uc3RydWN0KSB7XG4gIC8vIElmIHNvbWV0aGluZyBhc2tlZCBmb3IgYSBzdGFjayBpbnNpZGUgYSBmYWtlIHJlbmRlciwgaXQgc2hvdWxkIGdldCBpZ25vcmVkLlxuICBpZiAoICFmbiB8fCByZWVudHJ5KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAge1xuICAgIHZhciBmcmFtZSA9IGNvbXBvbmVudEZyYW1lQ2FjaGUuZ2V0KGZuKTtcblxuICAgIGlmIChmcmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZnJhbWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbnRyb2w7XG4gIHJlZW50cnkgPSB0cnVlO1xuICB2YXIgcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZSA9IEVycm9yLnByZXBhcmVTdGFja1RyYWNlOyAvLyAkRmxvd0ZpeE1lIEl0IGRvZXMgYWNjZXB0IHVuZGVmaW5lZC5cblxuICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IHVuZGVmaW5lZDtcbiAgdmFyIHByZXZpb3VzRGlzcGF0Y2hlcjtcblxuICB7XG4gICAgcHJldmlvdXNEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlci5jdXJyZW50OyAvLyBTZXQgdGhlIGRpc3BhdGNoZXIgaW4gREVWIGJlY2F1c2UgdGhpcyBtaWdodCBiZSBjYWxsIGluIHRoZSByZW5kZXIgZnVuY3Rpb25cbiAgICAvLyBmb3Igd2FybmluZ3MuXG5cbiAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLmN1cnJlbnQgPSBudWxsO1xuICAgIGRpc2FibGVMb2dzKCk7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIFRoaXMgc2hvdWxkIHRocm93LlxuICAgIGlmIChjb25zdHJ1Y3QpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBzaG91bGQgYmUgc2V0dGluZyB0aGUgcHJvcHMgaW4gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAgdmFyIEZha2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lXG5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEZha2UucHJvdG90eXBlLCAncHJvcHMnLCB7XG4gICAgICAgIHNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIFdlIHVzZSBhIHRocm93aW5nIHNldHRlciBpbnN0ZWFkIG9mIGZyb3plbiBvciBub24td3JpdGFibGUgcHJvcHNcbiAgICAgICAgICAvLyBiZWNhdXNlIHRoYXQgd29uJ3QgdGhyb3cgaW4gYSBub24tc3RyaWN0IG1vZGUgZnVuY3Rpb24uXG4gICAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gJ29iamVjdCcgJiYgUmVmbGVjdC5jb25zdHJ1Y3QpIHtcbiAgICAgICAgLy8gV2UgY29uc3RydWN0IGEgZGlmZmVyZW50IGNvbnRyb2wgZm9yIHRoaXMgY2FzZSB0byBpbmNsdWRlIGFueSBleHRyYVxuICAgICAgICAvLyBmcmFtZXMgYWRkZWQgYnkgdGhlIGNvbnN0cnVjdCBjYWxsLlxuICAgICAgICB0cnkge1xuICAgICAgICAgIFJlZmxlY3QuY29uc3RydWN0KEZha2UsIFtdKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgICB9XG5cbiAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoZm4sIFtdLCBGYWtlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgRmFrZS5jYWxsKCk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBjb250cm9sID0geDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZuLmNhbGwoRmFrZS5wcm90b3R5cGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICBjb250cm9sID0geDtcbiAgICAgIH1cblxuICAgICAgZm4oKTtcbiAgICB9XG4gIH0gY2F0Y2ggKHNhbXBsZSkge1xuICAgIC8vIFRoaXMgaXMgaW5saW5lZCBtYW51YWxseSBiZWNhdXNlIGNsb3N1cmUgZG9lc24ndCBkbyBpdCBmb3IgdXMuXG4gICAgaWYgKHNhbXBsZSAmJiBjb250cm9sICYmIHR5cGVvZiBzYW1wbGUuc3RhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBUaGlzIGV4dHJhY3RzIHRoZSBmaXJzdCBmcmFtZSBmcm9tIHRoZSBzYW1wbGUgdGhhdCBpc24ndCBhbHNvIGluIHRoZSBjb250cm9sLlxuICAgICAgLy8gU2tpcHBpbmcgb25lIGZyYW1lIHRoYXQgd2UgYXNzdW1lIGlzIHRoZSBmcmFtZSB0aGF0IGNhbGxzIHRoZSB0d28uXG4gICAgICB2YXIgc2FtcGxlTGluZXMgPSBzYW1wbGUuc3RhY2suc3BsaXQoJ1xcbicpO1xuICAgICAgdmFyIGNvbnRyb2xMaW5lcyA9IGNvbnRyb2wuc3RhY2suc3BsaXQoJ1xcbicpO1xuICAgICAgdmFyIHMgPSBzYW1wbGVMaW5lcy5sZW5ndGggLSAxO1xuICAgICAgdmFyIGMgPSBjb250cm9sTGluZXMubGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKHMgPj0gMSAmJiBjID49IDAgJiYgc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAvLyBXZSBleHBlY3QgYXQgbGVhc3Qgb25lIHN0YWNrIGZyYW1lIHRvIGJlIHNoYXJlZC5cbiAgICAgICAgLy8gVHlwaWNhbGx5IHRoaXMgd2lsbCBiZSB0aGUgcm9vdCBtb3N0IG9uZS4gSG93ZXZlciwgc3RhY2sgZnJhbWVzIG1heSBiZVxuICAgICAgICAvLyBjdXQgb2ZmIGR1ZSB0byBtYXhpbXVtIHN0YWNrIGxpbWl0cy4gSW4gdGhpcyBjYXNlLCBvbmUgbWF5YmUgY3V0IG9mZlxuICAgICAgICAvLyBlYXJsaWVyIHRoYW4gdGhlIG90aGVyLiBXZSBhc3N1bWUgdGhhdCB0aGUgc2FtcGxlIGlzIGxvbmdlciBvciB0aGUgc2FtZVxuICAgICAgICAvLyBhbmQgdGhlcmUgZm9yIGN1dCBvZmYgZWFybGllci4gU28gd2Ugc2hvdWxkIGZpbmQgdGhlIHJvb3QgbW9zdCBmcmFtZSBpblxuICAgICAgICAvLyB0aGUgc2FtcGxlIHNvbWV3aGVyZSBpbiB0aGUgY29udHJvbC5cbiAgICAgICAgYy0tO1xuICAgICAgfVxuXG4gICAgICBmb3IgKDsgcyA+PSAxICYmIGMgPj0gMDsgcy0tLCBjLS0pIHtcbiAgICAgICAgLy8gTmV4dCB3ZSBmaW5kIHRoZSBmaXJzdCBvbmUgdGhhdCBpc24ndCB0aGUgc2FtZSB3aGljaCBzaG91bGQgYmUgdGhlXG4gICAgICAgIC8vIGZyYW1lIHRoYXQgY2FsbGVkIG91ciBzYW1wbGUgZnVuY3Rpb24gYW5kIHRoZSBjb250cm9sLlxuICAgICAgICBpZiAoc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAgIC8vIEluIFY4LCB0aGUgZmlyc3QgbGluZSBpcyBkZXNjcmliaW5nIHRoZSBtZXNzYWdlIGJ1dCBvdGhlciBWTXMgZG9uJ3QuXG4gICAgICAgICAgLy8gSWYgd2UncmUgYWJvdXQgdG8gcmV0dXJuIHRoZSBmaXJzdCBsaW5lLCBhbmQgdGhlIGNvbnRyb2wgaXMgYWxzbyBvbiB0aGUgc2FtZVxuICAgICAgICAgIC8vIGxpbmUsIHRoYXQncyBhIHByZXR0eSBnb29kIGluZGljYXRvciB0aGF0IG91ciBzYW1wbGUgdGhyZXcgYXQgc2FtZSBsaW5lIGFzXG4gICAgICAgICAgLy8gdGhlIGNvbnRyb2wuIEkuZS4gYmVmb3JlIHdlIGVudGVyZWQgdGhlIHNhbXBsZSBmcmFtZS4gU28gd2UgaWdub3JlIHRoaXMgcmVzdWx0LlxuICAgICAgICAgIC8vIFRoaXMgY2FuIGhhcHBlbiBpZiB5b3UgcGFzc2VkIGEgY2xhc3MgdG8gZnVuY3Rpb24gY29tcG9uZW50LCBvciBub24tZnVuY3Rpb24uXG4gICAgICAgICAgaWYgKHMgIT09IDEgfHwgYyAhPT0gMSkge1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBzLS07XG4gICAgICAgICAgICAgIGMtLTsgLy8gV2UgbWF5IHN0aWxsIGhhdmUgc2ltaWxhciBpbnRlcm1lZGlhdGUgZnJhbWVzIGZyb20gdGhlIGNvbnN0cnVjdCBjYWxsLlxuICAgICAgICAgICAgICAvLyBUaGUgbmV4dCBvbmUgdGhhdCBpc24ndCB0aGUgc2FtZSBzaG91bGQgYmUgb3VyIG1hdGNoIHRob3VnaC5cblxuICAgICAgICAgICAgICBpZiAoYyA8IDAgfHwgc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAgICAgICAgIC8vIFY4IGFkZHMgYSBcIm5ld1wiIHByZWZpeCBmb3IgbmF0aXZlIGNsYXNzZXMuIExldCdzIHJlbW92ZSBpdCB0byBtYWtlIGl0IHByZXR0aWVyLlxuICAgICAgICAgICAgICAgIHZhciBfZnJhbWUgPSAnXFxuJyArIHNhbXBsZUxpbmVzW3NdLnJlcGxhY2UoJyBhdCBuZXcgJywgJyBhdCAnKTsgLy8gSWYgb3VyIGNvbXBvbmVudCBmcmFtZSBpcyBsYWJlbGVkIFwiPGFub255bW91cz5cIlxuICAgICAgICAgICAgICAgIC8vIGJ1dCB3ZSBoYXZlIGEgdXNlci1wcm92aWRlZCBcImRpc3BsYXlOYW1lXCJcbiAgICAgICAgICAgICAgICAvLyBzcGxpY2UgaXQgaW4gdG8gbWFrZSB0aGUgc3RhY2sgbW9yZSByZWFkYWJsZS5cblxuXG4gICAgICAgICAgICAgICAgaWYgKGZuLmRpc3BsYXlOYW1lICYmIF9mcmFtZS5pbmNsdWRlcygnPGFub255bW91cz4nKSkge1xuICAgICAgICAgICAgICAgICAgX2ZyYW1lID0gX2ZyYW1lLnJlcGxhY2UoJzxhbm9ueW1vdXM+JywgZm4uZGlzcGxheU5hbWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIF9mcmFtZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSAvLyBSZXR1cm4gdGhlIGxpbmUgd2UgZm91bmQuXG5cblxuICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gd2hpbGUgKHMgPj0gMSAmJiBjID49IDApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIHJlZW50cnkgPSBmYWxzZTtcblxuICAgIHtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudCA9IHByZXZpb3VzRGlzcGF0Y2hlcjtcbiAgICAgIHJlZW5hYmxlTG9ncygpO1xuICAgIH1cblxuICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZTtcbiAgfSAvLyBGYWxsYmFjayB0byBqdXN0IHVzaW5nIHRoZSBuYW1lIGlmIHdlIGNvdWxkbid0IG1ha2UgaXQgdGhyb3cuXG5cblxuICB2YXIgbmFtZSA9IGZuID8gZm4uZGlzcGxheU5hbWUgfHwgZm4ubmFtZSA6ICcnO1xuICB2YXIgc3ludGhldGljRnJhbWUgPSBuYW1lID8gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSkgOiAnJztcblxuICB7XG4gICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIHN5bnRoZXRpY0ZyYW1lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3ludGhldGljRnJhbWU7XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlQ2xhc3NDb21wb25lbnRGcmFtZShjdG9yLCBzb3VyY2UsIG93bmVyRm4pIHtcbiAge1xuICAgIHJldHVybiBkZXNjcmliZU5hdGl2ZUNvbXBvbmVudEZyYW1lKGN0b3IsIHRydWUpO1xuICB9XG59XG5mdW5jdGlvbiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUoZm4sIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoZm4sIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QoQ29tcG9uZW50KSB7XG4gIHZhciBwcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuICByZXR1cm4gISEocHJvdG90eXBlICYmIHByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50KTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUsIHNvdXJjZSwgb3duZXJGbikge1xuXG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB7XG4gICAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZSh0eXBlLCBzaG91bGRDb25zdHJ1Y3QodHlwZSkpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUodHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEU6XG4gICAgICAgIHJldHVybiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUodHlwZS5yZW5kZXIpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgLy8gTWVtbyBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVih0eXBlLnR5cGUsIHNvdXJjZSwgb3duZXJGbik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTGF6eSBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoaW5pdChwYXlsb2FkKSwgc291cmNlLCBvd25lckZuKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7fVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBkZXNjcmliZUZpYmVyKGZpYmVyKSB7XG4gIHZhciBvd25lciA9ICBmaWJlci5fZGVidWdPd25lciA/IGZpYmVyLl9kZWJ1Z093bmVyLnR5cGUgOiBudWxsIDtcbiAgdmFyIHNvdXJjZSA9ICBmaWJlci5fZGVidWdTb3VyY2UgO1xuXG4gIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKGZpYmVyLnR5cGUpO1xuXG4gICAgY2FzZSBMYXp5Q29tcG9uZW50OlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKCdMYXp5Jyk7XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKCdTdXNwZW5zZScpO1xuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlTGlzdCcpO1xuXG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEluZGV0ZXJtaW5hdGVDb21wb25lbnQ6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgcmV0dXJuIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZShmaWJlci50eXBlKTtcblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHJldHVybiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUoZmliZXIudHlwZS5yZW5kZXIpO1xuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHJldHVybiBkZXNjcmliZUNsYXNzQ29tcG9uZW50RnJhbWUoZmliZXIudHlwZSk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICcnO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFN0YWNrQnlGaWJlckluRGV2QW5kUHJvZCh3b3JrSW5Qcm9ncmVzcykge1xuICB0cnkge1xuICAgIHZhciBpbmZvID0gJyc7XG4gICAgdmFyIG5vZGUgPSB3b3JrSW5Qcm9ncmVzcztcblxuICAgIGRvIHtcbiAgICAgIGluZm8gKz0gZGVzY3JpYmVGaWJlcihub2RlKTtcbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9IHdoaWxlIChub2RlKTtcblxuICAgIHJldHVybiBpbmZvO1xuICB9IGNhdGNoICh4KSB7XG4gICAgcmV0dXJuICdcXG5FcnJvciBnZW5lcmF0aW5nIHN0YWNrOiAnICsgeC5tZXNzYWdlICsgJ1xcbicgKyB4LnN0YWNrO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFdyYXBwZWROYW1lKG91dGVyVHlwZSwgaW5uZXJUeXBlLCB3cmFwcGVyTmFtZSkge1xuICB2YXIgZGlzcGxheU5hbWUgPSBvdXRlclR5cGUuZGlzcGxheU5hbWU7XG5cbiAgaWYgKGRpc3BsYXlOYW1lKSB7XG4gICAgcmV0dXJuIGRpc3BsYXlOYW1lO1xuICB9XG5cbiAgdmFyIGZ1bmN0aW9uTmFtZSA9IGlubmVyVHlwZS5kaXNwbGF5TmFtZSB8fCBpbm5lclR5cGUubmFtZSB8fCAnJztcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZSAhPT0gJycgPyB3cmFwcGVyTmFtZSArIFwiKFwiICsgZnVuY3Rpb25OYW1lICsgXCIpXCIgOiB3cmFwcGVyTmFtZTtcbn0gLy8gS2VlcCBpbiBzeW5jIHdpdGggcmVhY3QtcmVjb25jaWxlci9nZXRDb21wb25lbnROYW1lRnJvbUZpYmVyXG5cblxuZnVuY3Rpb24gZ2V0Q29udGV4dE5hbWUodHlwZSkge1xuICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCAnQ29udGV4dCc7XG59IC8vIE5vdGUgdGhhdCB0aGUgcmVjb25jaWxlciBwYWNrYWdlIHNob3VsZCBnZW5lcmFsbHkgcHJlZmVyIHRvIHVzZSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKCkgaW5zdGVhZC5cblxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSkge1xuICBpZiAodHlwZSA9PSBudWxsKSB7XG4gICAgLy8gSG9zdCByb290LCB0ZXh0IG5vZGUgb3IganVzdCBpbnZhbGlkIHR5cGUuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB7XG4gICAgaWYgKHR5cGVvZiB0eXBlLnRhZyA9PT0gJ251bWJlcicpIHtcbiAgICAgIGVycm9yKCdSZWNlaXZlZCBhbiB1bmV4cGVjdGVkIG9iamVjdCBpbiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoKS4gJyArICdUaGlzIGlzIGxpa2VseSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHR5cGUuZGlzcGxheU5hbWUgfHwgdHlwZS5uYW1lIHx8IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX0ZSQUdNRU5UX1RZUEU6XG4gICAgICByZXR1cm4gJ0ZyYWdtZW50JztcblxuICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICByZXR1cm4gJ1BvcnRhbCc7XG5cbiAgICBjYXNlIFJFQUNUX1BST0ZJTEVSX1RZUEU6XG4gICAgICByZXR1cm4gJ1Byb2ZpbGVyJztcblxuICAgIGNhc2UgUkVBQ1RfU1RSSUNUX01PREVfVFlQRTpcbiAgICAgIHJldHVybiAnU3RyaWN0TW9kZSc7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgcmV0dXJuICdTdXNwZW5zZUxpc3QnO1xuXG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0NPTlRFWFRfVFlQRTpcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0eXBlO1xuICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUoY29udGV4dCkgKyAnLkNvbnN1bWVyJztcblxuICAgICAgY2FzZSBSRUFDVF9QUk9WSURFUl9UWVBFOlxuICAgICAgICB2YXIgcHJvdmlkZXIgPSB0eXBlO1xuICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUocHJvdmlkZXIuX2NvbnRleHQpICsgJy5Qcm92aWRlcic7XG5cbiAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgcmV0dXJuIGdldFdyYXBwZWROYW1lKHR5cGUsIHR5cGUucmVuZGVyLCAnRm9yd2FyZFJlZicpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgdmFyIG91dGVyTmFtZSA9IHR5cGUuZGlzcGxheU5hbWUgfHwgbnVsbDtcblxuICAgICAgICBpZiAob3V0ZXJOYW1lICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG91dGVyTmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZS50eXBlKSB8fCAnTWVtbyc7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShpbml0KHBheWxvYWQpKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFdyYXBwZWROYW1lJDEob3V0ZXJUeXBlLCBpbm5lclR5cGUsIHdyYXBwZXJOYW1lKSB7XG4gIHZhciBmdW5jdGlvbk5hbWUgPSBpbm5lclR5cGUuZGlzcGxheU5hbWUgfHwgaW5uZXJUeXBlLm5hbWUgfHwgJyc7XG4gIHJldHVybiBvdXRlclR5cGUuZGlzcGxheU5hbWUgfHwgKGZ1bmN0aW9uTmFtZSAhPT0gJycgPyB3cmFwcGVyTmFtZSArIFwiKFwiICsgZnVuY3Rpb25OYW1lICsgXCIpXCIgOiB3cmFwcGVyTmFtZSk7XG59IC8vIEtlZXAgaW4gc3luYyB3aXRoIHNoYXJlZC9nZXRDb21wb25lbnROYW1lRnJvbVR5cGVcblxuXG5mdW5jdGlvbiBnZXRDb250ZXh0TmFtZSQxKHR5cGUpIHtcbiAgcmV0dXJuIHR5cGUuZGlzcGxheU5hbWUgfHwgJ0NvbnRleHQnO1xufVxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB7XG4gIHZhciB0YWcgPSBmaWJlci50YWcsXG4gICAgICB0eXBlID0gZmliZXIudHlwZTtcblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgQ2FjaGVDb21wb25lbnQ6XG4gICAgICByZXR1cm4gJ0NhY2hlJztcblxuICAgIGNhc2UgQ29udGV4dENvbnN1bWVyOlxuICAgICAgdmFyIGNvbnRleHQgPSB0eXBlO1xuICAgICAgcmV0dXJuIGdldENvbnRleHROYW1lJDEoY29udGV4dCkgKyAnLkNvbnN1bWVyJztcblxuICAgIGNhc2UgQ29udGV4dFByb3ZpZGVyOlxuICAgICAgdmFyIHByb3ZpZGVyID0gdHlwZTtcbiAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZSQxKHByb3ZpZGVyLl9jb250ZXh0KSArICcuUHJvdmlkZXInO1xuXG4gICAgY2FzZSBEZWh5ZHJhdGVkRnJhZ21lbnQ6XG4gICAgICByZXR1cm4gJ0RlaHlkcmF0ZWRGcmFnbWVudCc7XG5cbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICByZXR1cm4gZ2V0V3JhcHBlZE5hbWUkMSh0eXBlLCB0eXBlLnJlbmRlciwgJ0ZvcndhcmRSZWYnKTtcblxuICAgIGNhc2UgRnJhZ21lbnQ6XG4gICAgICByZXR1cm4gJ0ZyYWdtZW50JztcblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIC8vIEhvc3QgY29tcG9uZW50IHR5cGUgaXMgdGhlIGRpc3BsYXkgbmFtZSAoZS5nLiBcImRpdlwiLCBcIlZpZXdcIilcbiAgICAgIHJldHVybiB0eXBlO1xuXG4gICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgcmV0dXJuICdQb3J0YWwnO1xuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHJldHVybiAnUm9vdCc7XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgcmV0dXJuICdUZXh0JztcblxuICAgIGNhc2UgTGF6eUNvbXBvbmVudDpcbiAgICAgIC8vIE5hbWUgY29tZXMgZnJvbSB0aGUgdHlwZSBpbiB0aGlzIGNhc2U7IHdlIGRvbid0IGhhdmUgYSB0YWcuXG4gICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpO1xuXG4gICAgY2FzZSBNb2RlOlxuICAgICAgaWYgKHR5cGUgPT09IFJFQUNUX1NUUklDVF9NT0RFX1RZUEUpIHtcbiAgICAgICAgLy8gRG9uJ3QgYmUgbGVzcyBzcGVjaWZpYyB0aGFuIHNoYXJlZC9nZXRDb21wb25lbnROYW1lRnJvbVR5cGVcbiAgICAgICAgcmV0dXJuICdTdHJpY3RNb2RlJztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuICdNb2RlJztcblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgICAgcmV0dXJuICdPZmZzY3JlZW4nO1xuXG4gICAgY2FzZSBQcm9maWxlcjpcbiAgICAgIHJldHVybiAnUHJvZmlsZXInO1xuXG4gICAgY2FzZSBTY29wZUNvbXBvbmVudDpcbiAgICAgIHJldHVybiAnU2NvcGUnO1xuXG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHJldHVybiAnU3VzcGVuc2UnO1xuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlTGlzdCc7XG5cbiAgICBjYXNlIFRyYWNpbmdNYXJrZXJDb21wb25lbnQ6XG4gICAgICByZXR1cm4gJ1RyYWNpbmdNYXJrZXInO1xuICAgIC8vIFRoZSBkaXNwbGF5IG5hbWUgZm9yIHRoaXMgdGFncyBjb21lIGZyb20gdGhlIHVzZXItcHJvdmlkZWQgdHlwZTpcblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICBjYXNlIEluZGV0ZXJtaW5hdGVDb21wb25lbnQ6XG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCB0eXBlLm5hbWUgfHwgbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdHlwZTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG52YXIgY3VycmVudCA9IG51bGw7XG52YXIgaXNSZW5kZXJpbmcgPSBmYWxzZTtcbmZ1bmN0aW9uIGdldEN1cnJlbnRGaWJlck93bmVyTmFtZUluRGV2T3JOdWxsKCkge1xuICB7XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBvd25lciA9IGN1cnJlbnQuX2RlYnVnT3duZXI7XG5cbiAgICBpZiAob3duZXIgIT09IG51bGwgJiYgdHlwZW9mIG93bmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIob3duZXIpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBnZXRDdXJyZW50RmliZXJTdGFja0luRGV2KCkge1xuICB7XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9IC8vIFNhZmUgYmVjYXVzZSBpZiBjdXJyZW50IGZpYmVyIGV4aXN0cywgd2UgYXJlIHJlY29uY2lsaW5nLFxuICAgIC8vIGFuZCBpdCBpcyBndWFyYW50ZWVkIHRvIGJlIHRoZSB3b3JrLWluLXByb2dyZXNzIHZlcnNpb24uXG5cblxuICAgIHJldHVybiBnZXRTdGFja0J5RmliZXJJbkRldkFuZFByb2QoY3VycmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzZXRDdXJyZW50RmliZXIoKSB7XG4gIHtcbiAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLmdldEN1cnJlbnRTdGFjayA9IG51bGw7XG4gICAgY3VycmVudCA9IG51bGw7XG4gICAgaXNSZW5kZXJpbmcgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gc2V0Q3VycmVudEZpYmVyKGZpYmVyKSB7XG4gIHtcbiAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLmdldEN1cnJlbnRTdGFjayA9IGZpYmVyID09PSBudWxsID8gbnVsbCA6IGdldEN1cnJlbnRGaWJlclN0YWNrSW5EZXY7XG4gICAgY3VycmVudCA9IGZpYmVyO1xuICAgIGlzUmVuZGVyaW5nID0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIGdldEN1cnJlbnRGaWJlcigpIHtcbiAge1xuICAgIHJldHVybiBjdXJyZW50O1xuICB9XG59XG5mdW5jdGlvbiBzZXRJc1JlbmRlcmluZyhyZW5kZXJpbmcpIHtcbiAge1xuICAgIGlzUmVuZGVyaW5nID0gcmVuZGVyaW5nO1xuICB9XG59XG5cbi8vIEZsb3cgZG9lcyBub3QgYWxsb3cgc3RyaW5nIGNvbmNhdGVuYXRpb24gb2YgbW9zdCBub24tc3RyaW5nIHR5cGVzLiBUbyB3b3JrXG4vLyBhcm91bmQgdGhpcyBsaW1pdGF0aW9uLCB3ZSB1c2UgYW4gb3BhcXVlIHR5cGUgdGhhdCBjYW4gb25seSBiZSBvYnRhaW5lZCBieVxuLy8gcGFzc2luZyB0aGUgdmFsdWUgdGhyb3VnaCBnZXRUb1N0cmluZ1ZhbHVlIGZpcnN0LlxuZnVuY3Rpb24gdG9TdHJpbmcodmFsdWUpIHtcbiAgLy8gVGhlIGNvZXJjaW9uIHNhZmV0eSBjaGVjayBpcyBwZXJmb3JtZWQgaW4gZ2V0VG9TdHJpbmdWYWx1ZSgpLlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb25cbiAgcmV0dXJuICcnICsgdmFsdWU7XG59XG5mdW5jdGlvbiBnZXRUb1N0cmluZ1ZhbHVlKHZhbHVlKSB7XG4gIHN3aXRjaCAodHlwZW9mIHZhbHVlKSB7XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gdmFsdWU7XG5cbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAge1xuICAgICAgICBjaGVja0Zvcm1GaWVsZFZhbHVlU3RyaW5nQ29lcmNpb24odmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsdWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgLy8gZnVuY3Rpb24sIHN5bWJvbCBhcmUgYXNzaWduZWQgYXMgZW1wdHkgc3RyaW5nc1xuICAgICAgcmV0dXJuICcnO1xuICB9XG59XG5cbnZhciBoYXNSZWFkT25seVZhbHVlID0ge1xuICBidXR0b246IHRydWUsXG4gIGNoZWNrYm94OiB0cnVlLFxuICBpbWFnZTogdHJ1ZSxcbiAgaGlkZGVuOiB0cnVlLFxuICByYWRpbzogdHJ1ZSxcbiAgcmVzZXQ6IHRydWUsXG4gIHN1Ym1pdDogdHJ1ZVxufTtcbmZ1bmN0aW9uIGNoZWNrQ29udHJvbGxlZFZhbHVlUHJvcHModGFnTmFtZSwgcHJvcHMpIHtcbiAge1xuICAgIGlmICghKGhhc1JlYWRPbmx5VmFsdWVbcHJvcHMudHlwZV0gfHwgcHJvcHMub25DaGFuZ2UgfHwgcHJvcHMub25JbnB1dCB8fCBwcm9wcy5yZWFkT25seSB8fCBwcm9wcy5kaXNhYmxlZCB8fCBwcm9wcy52YWx1ZSA9PSBudWxsKSkge1xuICAgICAgZXJyb3IoJ1lvdSBwcm92aWRlZCBhIGB2YWx1ZWAgcHJvcCB0byBhIGZvcm0gZmllbGQgd2l0aG91dCBhbiAnICsgJ2BvbkNoYW5nZWAgaGFuZGxlci4gVGhpcyB3aWxsIHJlbmRlciBhIHJlYWQtb25seSBmaWVsZC4gSWYgJyArICd0aGUgZmllbGQgc2hvdWxkIGJlIG11dGFibGUgdXNlIGBkZWZhdWx0VmFsdWVgLiBPdGhlcndpc2UsICcgKyAnc2V0IGVpdGhlciBgb25DaGFuZ2VgIG9yIGByZWFkT25seWAuJyk7XG4gICAgfVxuXG4gICAgaWYgKCEocHJvcHMub25DaGFuZ2UgfHwgcHJvcHMucmVhZE9ubHkgfHwgcHJvcHMuZGlzYWJsZWQgfHwgcHJvcHMuY2hlY2tlZCA9PSBudWxsKSkge1xuICAgICAgZXJyb3IoJ1lvdSBwcm92aWRlZCBhIGBjaGVja2VkYCBwcm9wIHRvIGEgZm9ybSBmaWVsZCB3aXRob3V0IGFuICcgKyAnYG9uQ2hhbmdlYCBoYW5kbGVyLiBUaGlzIHdpbGwgcmVuZGVyIGEgcmVhZC1vbmx5IGZpZWxkLiBJZiAnICsgJ3RoZSBmaWVsZCBzaG91bGQgYmUgbXV0YWJsZSB1c2UgYGRlZmF1bHRDaGVja2VkYC4gT3RoZXJ3aXNlLCAnICsgJ3NldCBlaXRoZXIgYG9uQ2hhbmdlYCBvciBgcmVhZE9ubHlgLicpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc0NoZWNrYWJsZShlbGVtKSB7XG4gIHZhciB0eXBlID0gZWxlbS50eXBlO1xuICB2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lO1xuICByZXR1cm4gbm9kZU5hbWUgJiYgbm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JyAmJiAodHlwZSA9PT0gJ2NoZWNrYm94JyB8fCB0eXBlID09PSAncmFkaW8nKTtcbn1cblxuZnVuY3Rpb24gZ2V0VHJhY2tlcihub2RlKSB7XG4gIHJldHVybiBub2RlLl92YWx1ZVRyYWNrZXI7XG59XG5cbmZ1bmN0aW9uIGRldGFjaFRyYWNrZXIobm9kZSkge1xuICBub2RlLl92YWx1ZVRyYWNrZXIgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZUZyb21Ob2RlKG5vZGUpIHtcbiAgdmFyIHZhbHVlID0gJyc7XG5cbiAgaWYgKCFub2RlKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzQ2hlY2thYmxlKG5vZGUpKSB7XG4gICAgdmFsdWUgPSBub2RlLmNoZWNrZWQgPyAndHJ1ZScgOiAnZmFsc2UnO1xuICB9IGVsc2Uge1xuICAgIHZhbHVlID0gbm9kZS52YWx1ZTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gdHJhY2tWYWx1ZU9uTm9kZShub2RlKSB7XG4gIHZhciB2YWx1ZUZpZWxkID0gaXNDaGVja2FibGUobm9kZSkgPyAnY2hlY2tlZCcgOiAndmFsdWUnO1xuICB2YXIgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iobm9kZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHZhbHVlRmllbGQpO1xuXG4gIHtcbiAgICBjaGVja0Zvcm1GaWVsZFZhbHVlU3RyaW5nQ29lcmNpb24obm9kZVt2YWx1ZUZpZWxkXSk7XG4gIH1cblxuICB2YXIgY3VycmVudFZhbHVlID0gJycgKyBub2RlW3ZhbHVlRmllbGRdOyAvLyBpZiBzb21lb25lIGhhcyBhbHJlYWR5IGRlZmluZWQgYSB2YWx1ZSBvciBTYWZhcmksIHRoZW4gYmFpbFxuICAvLyBhbmQgZG9uJ3QgdHJhY2sgdmFsdWUgd2lsbCBjYXVzZSBvdmVyIHJlcG9ydGluZyBvZiBjaGFuZ2VzLFxuICAvLyBidXQgaXQncyBiZXR0ZXIgdGhlbiBhIGhhcmQgZmFpbHVyZVxuICAvLyAobmVlZGVkIGZvciBjZXJ0YWluIHRlc3RzIHRoYXQgc3B5T24gaW5wdXQgdmFsdWVzIGFuZCBTYWZhcmkpXG5cbiAgaWYgKG5vZGUuaGFzT3duUHJvcGVydHkodmFsdWVGaWVsZCkgfHwgdHlwZW9mIGRlc2NyaXB0b3IgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBkZXNjcmlwdG9yLmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgZGVzY3JpcHRvci5zZXQgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZ2V0ID0gZGVzY3JpcHRvci5nZXQsXG4gICAgICBzZXQgPSBkZXNjcmlwdG9yLnNldDtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5vZGUsIHZhbHVlRmllbGQsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gZ2V0LmNhbGwodGhpcyk7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAge1xuICAgICAgICBjaGVja0Zvcm1GaWVsZFZhbHVlU3RyaW5nQ29lcmNpb24odmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50VmFsdWUgPSAnJyArIHZhbHVlO1xuICAgICAgc2V0LmNhbGwodGhpcywgdmFsdWUpO1xuICAgIH1cbiAgfSk7IC8vIFdlIGNvdWxkJ3ZlIHBhc3NlZCB0aGlzIHRoZSBmaXJzdCB0aW1lXG4gIC8vIGJ1dCBpdCB0cmlnZ2VycyBhIGJ1ZyBpbiBJRTExIGFuZCBFZGdlIDE0LzE1LlxuICAvLyBDYWxsaW5nIGRlZmluZVByb3BlcnR5KCkgYWdhaW4gc2hvdWxkIGJlIGVxdWl2YWxlbnQuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTE3NjhcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkobm9kZSwgdmFsdWVGaWVsZCwge1xuICAgIGVudW1lcmFibGU6IGRlc2NyaXB0b3IuZW51bWVyYWJsZVxuICB9KTtcbiAgdmFyIHRyYWNrZXIgPSB7XG4gICAgZ2V0VmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBjdXJyZW50VmFsdWU7XG4gICAgfSxcbiAgICBzZXRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRWYWx1ZSA9ICcnICsgdmFsdWU7XG4gICAgfSxcbiAgICBzdG9wVHJhY2tpbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGRldGFjaFRyYWNrZXIobm9kZSk7XG4gICAgICBkZWxldGUgbm9kZVt2YWx1ZUZpZWxkXTtcbiAgICB9XG4gIH07XG4gIHJldHVybiB0cmFja2VyO1xufVxuXG5mdW5jdGlvbiB0cmFjayhub2RlKSB7XG4gIGlmIChnZXRUcmFja2VyKG5vZGUpKSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIFRPRE86IE9uY2UgaXQncyBqdXN0IEZpYmVyIHdlIGNhbiBtb3ZlIHRoaXMgdG8gbm9kZS5fd3JhcHBlclN0YXRlXG5cblxuICBub2RlLl92YWx1ZVRyYWNrZXIgPSB0cmFja1ZhbHVlT25Ob2RlKG5vZGUpO1xufVxuZnVuY3Rpb24gdXBkYXRlVmFsdWVJZkNoYW5nZWQobm9kZSkge1xuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgdHJhY2tlciA9IGdldFRyYWNrZXIobm9kZSk7IC8vIGlmIHRoZXJlIGlzIG5vIHRyYWNrZXIgYXQgdGhpcyBwb2ludCBpdCdzIHVubGlrZWx5XG4gIC8vIHRoYXQgdHJ5aW5nIGFnYWluIHdpbGwgc3VjY2VlZFxuXG4gIGlmICghdHJhY2tlcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdmFyIGxhc3RWYWx1ZSA9IHRyYWNrZXIuZ2V0VmFsdWUoKTtcbiAgdmFyIG5leHRWYWx1ZSA9IGdldFZhbHVlRnJvbU5vZGUobm9kZSk7XG5cbiAgaWYgKG5leHRWYWx1ZSAhPT0gbGFzdFZhbHVlKSB7XG4gICAgdHJhY2tlci5zZXRWYWx1ZShuZXh0VmFsdWUpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXRBY3RpdmVFbGVtZW50KGRvYykge1xuICBkb2MgPSBkb2MgfHwgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudCA6IHVuZGVmaW5lZCk7XG5cbiAgaWYgKHR5cGVvZiBkb2MgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBkb2MuYWN0aXZlRWxlbWVudCB8fCBkb2MuYm9keTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBkb2MuYm9keTtcbiAgfVxufVxuXG52YXIgZGlkV2FyblZhbHVlRGVmYXVsdFZhbHVlID0gZmFsc2U7XG52YXIgZGlkV2FybkNoZWNrZWREZWZhdWx0Q2hlY2tlZCA9IGZhbHNlO1xudmFyIGRpZFdhcm5Db250cm9sbGVkVG9VbmNvbnRyb2xsZWQgPSBmYWxzZTtcbnZhciBkaWRXYXJuVW5jb250cm9sbGVkVG9Db250cm9sbGVkID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGlzQ29udHJvbGxlZChwcm9wcykge1xuICB2YXIgdXNlc0NoZWNrZWQgPSBwcm9wcy50eXBlID09PSAnY2hlY2tib3gnIHx8IHByb3BzLnR5cGUgPT09ICdyYWRpbyc7XG4gIHJldHVybiB1c2VzQ2hlY2tlZCA/IHByb3BzLmNoZWNrZWQgIT0gbnVsbCA6IHByb3BzLnZhbHVlICE9IG51bGw7XG59XG4vKipcbiAqIEltcGxlbWVudHMgYW4gPGlucHV0PiBob3N0IGNvbXBvbmVudCB0aGF0IGFsbG93cyBzZXR0aW5nIHRoZXNlIG9wdGlvbmFsXG4gKiBwcm9wczogYGNoZWNrZWRgLCBgdmFsdWVgLCBgZGVmYXVsdENoZWNrZWRgLCBhbmQgYGRlZmF1bHRWYWx1ZWAuXG4gKlxuICogSWYgYGNoZWNrZWRgIG9yIGB2YWx1ZWAgYXJlIG5vdCBzdXBwbGllZCAob3IgbnVsbC91bmRlZmluZWQpLCB1c2VyIGFjdGlvbnNcbiAqIHRoYXQgYWZmZWN0IHRoZSBjaGVja2VkIHN0YXRlIG9yIHZhbHVlIHdpbGwgdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIElmIHRoZXkgYXJlIHN1cHBsaWVkIChhbmQgbm90IG51bGwvdW5kZWZpbmVkKSwgdGhlIHJlbmRlcmVkIGVsZW1lbnQgd2lsbCBub3RcbiAqIHRyaWdnZXIgdXBkYXRlcyB0byB0aGUgZWxlbWVudC4gSW5zdGVhZCwgdGhlIHByb3BzIG11c3QgY2hhbmdlIGluIG9yZGVyIGZvclxuICogdGhlIHJlbmRlcmVkIGVsZW1lbnQgdG8gYmUgdXBkYXRlZC5cbiAqXG4gKiBUaGUgcmVuZGVyZWQgZWxlbWVudCB3aWxsIGJlIGluaXRpYWxpemVkIGFzIHVuY2hlY2tlZCAob3IgYGRlZmF1bHRDaGVja2VkYClcbiAqIHdpdGggYW4gZW1wdHkgdmFsdWUgKG9yIGBkZWZhdWx0VmFsdWVgKS5cbiAqXG4gKiBTZWUgaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMi9XRC1odG1sNS0yMDEyMTAyNS90aGUtaW5wdXQtZWxlbWVudC5odG1sXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRIb3N0UHJvcHMoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB2YXIgY2hlY2tlZCA9IHByb3BzLmNoZWNrZWQ7XG4gIHZhciBob3N0UHJvcHMgPSBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgZGVmYXVsdENoZWNrZWQ6IHVuZGVmaW5lZCxcbiAgICBkZWZhdWx0VmFsdWU6IHVuZGVmaW5lZCxcbiAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgIGNoZWNrZWQ6IGNoZWNrZWQgIT0gbnVsbCA/IGNoZWNrZWQgOiBub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbENoZWNrZWRcbiAgfSk7XG4gIHJldHVybiBob3N0UHJvcHM7XG59XG5mdW5jdGlvbiBpbml0V3JhcHBlclN0YXRlKGVsZW1lbnQsIHByb3BzKSB7XG4gIHtcbiAgICBjaGVja0NvbnRyb2xsZWRWYWx1ZVByb3BzKCdpbnB1dCcsIHByb3BzKTtcblxuICAgIGlmIChwcm9wcy5jaGVja2VkICE9PSB1bmRlZmluZWQgJiYgcHJvcHMuZGVmYXVsdENoZWNrZWQgIT09IHVuZGVmaW5lZCAmJiAhZGlkV2FybkNoZWNrZWREZWZhdWx0Q2hlY2tlZCkge1xuICAgICAgZXJyb3IoJyVzIGNvbnRhaW5zIGFuIGlucHV0IG9mIHR5cGUgJXMgd2l0aCBib3RoIGNoZWNrZWQgYW5kIGRlZmF1bHRDaGVja2VkIHByb3BzLiAnICsgJ0lucHV0IGVsZW1lbnRzIG11c3QgYmUgZWl0aGVyIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkICcgKyAnKHNwZWNpZnkgZWl0aGVyIHRoZSBjaGVja2VkIHByb3AsIG9yIHRoZSBkZWZhdWx0Q2hlY2tlZCBwcm9wLCBidXQgbm90ICcgKyAnYm90aCkuIERlY2lkZSBiZXR3ZWVuIHVzaW5nIGEgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgaW5wdXQgJyArICdlbGVtZW50IGFuZCByZW1vdmUgb25lIG9mIHRoZXNlIHByb3BzLiBNb3JlIGluZm86ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycsIGdldEN1cnJlbnRGaWJlck93bmVyTmFtZUluRGV2T3JOdWxsKCkgfHwgJ0EgY29tcG9uZW50JywgcHJvcHMudHlwZSk7XG5cbiAgICAgIGRpZFdhcm5DaGVja2VkRGVmYXVsdENoZWNrZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy52YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHByb3BzLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmICFkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUpIHtcbiAgICAgIGVycm9yKCclcyBjb250YWlucyBhbiBpbnB1dCBvZiB0eXBlICVzIHdpdGggYm90aCB2YWx1ZSBhbmQgZGVmYXVsdFZhbHVlIHByb3BzLiAnICsgJ0lucHV0IGVsZW1lbnRzIG11c3QgYmUgZWl0aGVyIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkICcgKyAnKHNwZWNpZnkgZWl0aGVyIHRoZSB2YWx1ZSBwcm9wLCBvciB0aGUgZGVmYXVsdFZhbHVlIHByb3AsIGJ1dCBub3QgJyArICdib3RoKS4gRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCBpbnB1dCAnICsgJ2VsZW1lbnQgYW5kIHJlbW92ZSBvbmUgb2YgdGhlc2UgcHJvcHMuIE1vcmUgaW5mbzogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJywgZ2V0Q3VycmVudEZpYmVyT3duZXJOYW1lSW5EZXZPck51bGwoKSB8fCAnQSBjb21wb25lbnQnLCBwcm9wcy50eXBlKTtcblxuICAgICAgZGlkV2FyblZhbHVlRGVmYXVsdFZhbHVlID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIHZhciBkZWZhdWx0VmFsdWUgPSBwcm9wcy5kZWZhdWx0VmFsdWUgPT0gbnVsbCA/ICcnIDogcHJvcHMuZGVmYXVsdFZhbHVlO1xuICBub2RlLl93cmFwcGVyU3RhdGUgPSB7XG4gICAgaW5pdGlhbENoZWNrZWQ6IHByb3BzLmNoZWNrZWQgIT0gbnVsbCA/IHByb3BzLmNoZWNrZWQgOiBwcm9wcy5kZWZhdWx0Q2hlY2tlZCxcbiAgICBpbml0aWFsVmFsdWU6IGdldFRvU3RyaW5nVmFsdWUocHJvcHMudmFsdWUgIT0gbnVsbCA/IHByb3BzLnZhbHVlIDogZGVmYXVsdFZhbHVlKSxcbiAgICBjb250cm9sbGVkOiBpc0NvbnRyb2xsZWQocHJvcHMpXG4gIH07XG59XG5mdW5jdGlvbiB1cGRhdGVDaGVja2VkKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdmFyIGNoZWNrZWQgPSBwcm9wcy5jaGVja2VkO1xuXG4gIGlmIChjaGVja2VkICE9IG51bGwpIHtcbiAgICBzZXRWYWx1ZUZvclByb3BlcnR5KG5vZGUsICdjaGVja2VkJywgY2hlY2tlZCwgZmFsc2UpO1xuICB9XG59XG5mdW5jdGlvbiB1cGRhdGVXcmFwcGVyKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcblxuICB7XG4gICAgdmFyIGNvbnRyb2xsZWQgPSBpc0NvbnRyb2xsZWQocHJvcHMpO1xuXG4gICAgaWYgKCFub2RlLl93cmFwcGVyU3RhdGUuY29udHJvbGxlZCAmJiBjb250cm9sbGVkICYmICFkaWRXYXJuVW5jb250cm9sbGVkVG9Db250cm9sbGVkKSB7XG4gICAgICBlcnJvcignQSBjb21wb25lbnQgaXMgY2hhbmdpbmcgYW4gdW5jb250cm9sbGVkIGlucHV0IHRvIGJlIGNvbnRyb2xsZWQuICcgKyAnVGhpcyBpcyBsaWtlbHkgY2F1c2VkIGJ5IHRoZSB2YWx1ZSBjaGFuZ2luZyBmcm9tIHVuZGVmaW5lZCB0byAnICsgJ2EgZGVmaW5lZCB2YWx1ZSwgd2hpY2ggc2hvdWxkIG5vdCBoYXBwZW4uICcgKyAnRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCBpbnB1dCAnICsgJ2VsZW1lbnQgZm9yIHRoZSBsaWZldGltZSBvZiB0aGUgY29tcG9uZW50LiBNb3JlIGluZm86IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9jb250cm9sbGVkLWNvbXBvbmVudHMnKTtcblxuICAgICAgZGlkV2FyblVuY29udHJvbGxlZFRvQ29udHJvbGxlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUuX3dyYXBwZXJTdGF0ZS5jb250cm9sbGVkICYmICFjb250cm9sbGVkICYmICFkaWRXYXJuQ29udHJvbGxlZFRvVW5jb250cm9sbGVkKSB7XG4gICAgICBlcnJvcignQSBjb21wb25lbnQgaXMgY2hhbmdpbmcgYSBjb250cm9sbGVkIGlucHV0IHRvIGJlIHVuY29udHJvbGxlZC4gJyArICdUaGlzIGlzIGxpa2VseSBjYXVzZWQgYnkgdGhlIHZhbHVlIGNoYW5naW5nIGZyb20gYSBkZWZpbmVkIHRvICcgKyAndW5kZWZpbmVkLCB3aGljaCBzaG91bGQgbm90IGhhcHBlbi4gJyArICdEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIGlucHV0ICcgKyAnZWxlbWVudCBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBjb21wb25lbnQuIE1vcmUgaW5mbzogaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycpO1xuXG4gICAgICBkaWRXYXJuQ29udHJvbGxlZFRvVW5jb250cm9sbGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVDaGVja2VkKGVsZW1lbnQsIHByb3BzKTtcbiAgdmFyIHZhbHVlID0gZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy52YWx1ZSk7XG4gIHZhciB0eXBlID0gcHJvcHMudHlwZTtcblxuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKHZhbHVlID09PSAwICYmIG5vZGUudmFsdWUgPT09ICcnIHx8IC8vIFdlIGV4cGxpY2l0bHkgd2FudCB0byBjb2VyY2UgdG8gbnVtYmVyIGhlcmUgaWYgcG9zc2libGUuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgIG5vZGUudmFsdWUgIT0gdmFsdWUpIHtcbiAgICAgICAgbm9kZS52YWx1ZSA9IHRvU3RyaW5nKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5vZGUudmFsdWUgIT09IHRvU3RyaW5nKHZhbHVlKSkge1xuICAgICAgbm9kZS52YWx1ZSA9IHRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N1Ym1pdCcgfHwgdHlwZSA9PT0gJ3Jlc2V0Jykge1xuICAgIC8vIFN1Ym1pdC9yZXNldCBpbnB1dHMgbmVlZCB0aGUgYXR0cmlidXRlIHJlbW92ZWQgY29tcGxldGVseSB0byBhdm9pZFxuICAgIC8vIGJsYW5rLXRleHQgYnV0dG9ucy5cbiAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZSgndmFsdWUnKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB7XG4gICAgLy8gV2hlbiBzeW5jaW5nIHRoZSB2YWx1ZSBhdHRyaWJ1dGUsIHRoZSB2YWx1ZSBjb21lcyBmcm9tIGEgY2FzY2FkZSBvZlxuICAgIC8vIHByb3BlcnRpZXM6XG4gICAgLy8gIDEuIFRoZSB2YWx1ZSBSZWFjdCBwcm9wZXJ0eVxuICAgIC8vICAyLiBUaGUgZGVmYXVsdFZhbHVlIFJlYWN0IHByb3BlcnR5XG4gICAgLy8gIDMuIE90aGVyd2lzZSB0aGVyZSBzaG91bGQgYmUgbm8gY2hhbmdlXG4gICAgaWYgKHByb3BzLmhhc093blByb3BlcnR5KCd2YWx1ZScpKSB7XG4gICAgICBzZXREZWZhdWx0VmFsdWUobm9kZSwgcHJvcHMudHlwZSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocHJvcHMuaGFzT3duUHJvcGVydHkoJ2RlZmF1bHRWYWx1ZScpKSB7XG4gICAgICBzZXREZWZhdWx0VmFsdWUobm9kZSwgcHJvcHMudHlwZSwgZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy5kZWZhdWx0VmFsdWUpKTtcbiAgICB9XG4gIH1cblxuICB7XG4gICAgLy8gV2hlbiBzeW5jaW5nIHRoZSBjaGVja2VkIGF0dHJpYnV0ZSwgaXQgb25seSBjaGFuZ2VzIHdoZW4gaXQgbmVlZHNcbiAgICAvLyB0byBiZSByZW1vdmVkLCBzdWNoIGFzIHRyYW5zaXRpb25pbmcgZnJvbSBhIGNoZWNrYm94IGludG8gYSB0ZXh0IGlucHV0XG4gICAgaWYgKHByb3BzLmNoZWNrZWQgPT0gbnVsbCAmJiBwcm9wcy5kZWZhdWx0Q2hlY2tlZCAhPSBudWxsKSB7XG4gICAgICBub2RlLmRlZmF1bHRDaGVja2VkID0gISFwcm9wcy5kZWZhdWx0Q2hlY2tlZDtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHBvc3RNb3VudFdyYXBwZXIoZWxlbWVudCwgcHJvcHMsIGlzSHlkcmF0aW5nKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDsgLy8gRG8gbm90IGFzc2lnbiB2YWx1ZSBpZiBpdCBpcyBhbHJlYWR5IHNldC4gVGhpcyBwcmV2ZW50cyB1c2VyIHRleHQgaW5wdXRcbiAgLy8gZnJvbSBiZWluZyBsb3N0IGR1cmluZyBTU1IgaHlkcmF0aW9uLlxuXG4gIGlmIChwcm9wcy5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSB8fCBwcm9wcy5oYXNPd25Qcm9wZXJ0eSgnZGVmYXVsdFZhbHVlJykpIHtcbiAgICB2YXIgdHlwZSA9IHByb3BzLnR5cGU7XG4gICAgdmFyIGlzQnV0dG9uID0gdHlwZSA9PT0gJ3N1Ym1pdCcgfHwgdHlwZSA9PT0gJ3Jlc2V0JzsgLy8gQXZvaWQgc2V0dGluZyB2YWx1ZSBhdHRyaWJ1dGUgb24gc3VibWl0L3Jlc2V0IGlucHV0cyBhcyBpdCBvdmVycmlkZXMgdGhlXG4gICAgLy8gZGVmYXVsdCB2YWx1ZSBwcm92aWRlZCBieSB0aGUgYnJvd3Nlci4gU2VlOiAjMTI4NzJcblxuICAgIGlmIChpc0J1dHRvbiAmJiAocHJvcHMudmFsdWUgPT09IHVuZGVmaW5lZCB8fCBwcm9wcy52YWx1ZSA9PT0gbnVsbCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaW5pdGlhbFZhbHVlID0gdG9TdHJpbmcobm9kZS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZSk7IC8vIERvIG5vdCBhc3NpZ24gdmFsdWUgaWYgaXQgaXMgYWxyZWFkeSBzZXQuIFRoaXMgcHJldmVudHMgdXNlciB0ZXh0IGlucHV0XG4gICAgLy8gZnJvbSBiZWluZyBsb3N0IGR1cmluZyBTU1IgaHlkcmF0aW9uLlxuXG4gICAgaWYgKCFpc0h5ZHJhdGluZykge1xuICAgICAge1xuICAgICAgICAvLyBXaGVuIHN5bmNpbmcgdGhlIHZhbHVlIGF0dHJpYnV0ZSwgdGhlIHZhbHVlIHByb3BlcnR5IHNob3VsZCB1c2VcbiAgICAgICAgLy8gdGhlIHdyYXBwZXJTdGF0ZS5faW5pdGlhbFZhbHVlIHByb3BlcnR5LiBUaGlzIHVzZXM6XG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgMS4gVGhlIHZhbHVlIFJlYWN0IHByb3BlcnR5IHdoZW4gcHJlc2VudFxuICAgICAgICAvLyAgIDIuIFRoZSBkZWZhdWx0VmFsdWUgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgICAgIC8vICAgMy4gQW4gZW1wdHkgc3RyaW5nXG4gICAgICAgIGlmIChpbml0aWFsVmFsdWUgIT09IG5vZGUudmFsdWUpIHtcbiAgICAgICAgICBub2RlLnZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAge1xuICAgICAgLy8gT3RoZXJ3aXNlLCB0aGUgdmFsdWUgYXR0cmlidXRlIGlzIHN5bmNocm9uaXplZCB0byB0aGUgcHJvcGVydHksXG4gICAgICAvLyBzbyB3ZSBhc3NpZ24gZGVmYXVsdFZhbHVlIHRvIHRoZSBzYW1lIHRoaW5nIGFzIHRoZSB2YWx1ZSBwcm9wZXJ0eVxuICAgICAgLy8gYXNzaWdubWVudCBzdGVwIGFib3ZlLlxuICAgICAgbm9kZS5kZWZhdWx0VmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgfVxuICB9IC8vIE5vcm1hbGx5LCB3ZSdkIGp1c3QgZG8gYG5vZGUuY2hlY2tlZCA9IG5vZGUuY2hlY2tlZGAgdXBvbiBpbml0aWFsIG1vdW50LCBsZXNzIHRoaXMgYnVnXG4gIC8vIHRoaXMgaXMgbmVlZGVkIHRvIHdvcmsgYXJvdW5kIGEgY2hyb21lIGJ1ZyB3aGVyZSBzZXR0aW5nIGRlZmF1bHRDaGVja2VkXG4gIC8vIHdpbGwgc29tZXRpbWVzIGluZmx1ZW5jZSB0aGUgdmFsdWUgb2YgY2hlY2tlZCAoZXZlbiBhZnRlciBkZXRhY2htZW50KS5cbiAgLy8gUmVmZXJlbmNlOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD02MDg0MTZcbiAgLy8gV2UgbmVlZCB0byB0ZW1wb3JhcmlseSB1bnNldCBuYW1lIHRvIGF2b2lkIGRpc3J1cHRpbmcgcmFkaW8gYnV0dG9uIGdyb3Vwcy5cblxuXG4gIHZhciBuYW1lID0gbm9kZS5uYW1lO1xuXG4gIGlmIChuYW1lICE9PSAnJykge1xuICAgIG5vZGUubmFtZSA9ICcnO1xuICB9XG5cbiAge1xuICAgIC8vIFdoZW4gc3luY2luZyB0aGUgY2hlY2tlZCBhdHRyaWJ1dGUsIGJvdGggdGhlIGNoZWNrZWQgcHJvcGVydHkgYW5kXG4gICAgLy8gYXR0cmlidXRlIGFyZSBhc3NpZ25lZCBhdCB0aGUgc2FtZSB0aW1lIHVzaW5nIGRlZmF1bHRDaGVja2VkLiBUaGlzIHVzZXM6XG4gICAgLy9cbiAgICAvLyAgIDEuIFRoZSBjaGVja2VkIFJlYWN0IHByb3BlcnR5IHdoZW4gcHJlc2VudFxuICAgIC8vICAgMi4gVGhlIGRlZmF1bHRDaGVja2VkIFJlYWN0IHByb3BlcnR5IHdoZW4gcHJlc2VudFxuICAgIC8vICAgMy4gT3RoZXJ3aXNlLCBmYWxzZVxuICAgIG5vZGUuZGVmYXVsdENoZWNrZWQgPSAhbm9kZS5kZWZhdWx0Q2hlY2tlZDtcbiAgICBub2RlLmRlZmF1bHRDaGVja2VkID0gISFub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbENoZWNrZWQ7XG4gIH1cblxuICBpZiAobmFtZSAhPT0gJycpIHtcbiAgICBub2RlLm5hbWUgPSBuYW1lO1xuICB9XG59XG5mdW5jdGlvbiByZXN0b3JlQ29udHJvbGxlZFN0YXRlKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdXBkYXRlV3JhcHBlcihub2RlLCBwcm9wcyk7XG4gIHVwZGF0ZU5hbWVkQ291c2lucyhub2RlLCBwcm9wcyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU5hbWVkQ291c2lucyhyb290Tm9kZSwgcHJvcHMpIHtcbiAgdmFyIG5hbWUgPSBwcm9wcy5uYW1lO1xuXG4gIGlmIChwcm9wcy50eXBlID09PSAncmFkaW8nICYmIG5hbWUgIT0gbnVsbCkge1xuICAgIHZhciBxdWVyeVJvb3QgPSByb290Tm9kZTtcblxuICAgIHdoaWxlIChxdWVyeVJvb3QucGFyZW50Tm9kZSkge1xuICAgICAgcXVlcnlSb290ID0gcXVlcnlSb290LnBhcmVudE5vZGU7XG4gICAgfSAvLyBJZiBgcm9vdE5vZGUuZm9ybWAgd2FzIG5vbi1udWxsLCB0aGVuIHdlIGNvdWxkIHRyeSBgZm9ybS5lbGVtZW50c2AsXG4gICAgLy8gYnV0IHRoYXQgc29tZXRpbWVzIGJlaGF2ZXMgc3RyYW5nZWx5IGluIElFOC4gV2UgY291bGQgYWxzbyB0cnkgdXNpbmdcbiAgICAvLyBgZm9ybS5nZXRFbGVtZW50c0J5TmFtZWAsIGJ1dCB0aGF0IHdpbGwgb25seSByZXR1cm4gZGlyZWN0IGNoaWxkcmVuXG4gICAgLy8gYW5kIHdvbid0IGluY2x1ZGUgaW5wdXRzIHRoYXQgdXNlIHRoZSBIVE1MNSBgZm9ybT1gIGF0dHJpYnV0ZS4gU2luY2VcbiAgICAvLyB0aGUgaW5wdXQgbWlnaHQgbm90IGV2ZW4gYmUgaW4gYSBmb3JtLiBJdCBtaWdodCBub3QgZXZlbiBiZSBpbiB0aGVcbiAgICAvLyBkb2N1bWVudC4gTGV0J3MganVzdCB1c2UgdGhlIGxvY2FsIGBxdWVyeVNlbGVjdG9yQWxsYCB0byBlbnN1cmUgd2UgZG9uJ3RcbiAgICAvLyBtaXNzIGFueXRoaW5nLlxuXG5cbiAgICB7XG4gICAgICBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKG5hbWUsICduYW1lJyk7XG4gICAgfVxuXG4gICAgdmFyIGdyb3VwID0gcXVlcnlSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W25hbWU9JyArIEpTT04uc3RyaW5naWZ5KCcnICsgbmFtZSkgKyAnXVt0eXBlPVwicmFkaW9cIl0nKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ3JvdXAubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBvdGhlck5vZGUgPSBncm91cFtpXTtcblxuICAgICAgaWYgKG90aGVyTm9kZSA9PT0gcm9vdE5vZGUgfHwgb3RoZXJOb2RlLmZvcm0gIT09IHJvb3ROb2RlLmZvcm0pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IC8vIFRoaXMgd2lsbCB0aHJvdyBpZiByYWRpbyBidXR0b25zIHJlbmRlcmVkIGJ5IGRpZmZlcmVudCBjb3BpZXMgb2YgUmVhY3RcbiAgICAgIC8vIGFuZCB0aGUgc2FtZSBuYW1lIGFyZSByZW5kZXJlZCBpbnRvIHRoZSBzYW1lIGZvcm0gKHNhbWUgYXMgIzE5MzkpLlxuICAgICAgLy8gVGhhdCdzIHByb2JhYmx5IG9rYXk7IHdlIGRvbid0IHN1cHBvcnQgaXQganVzdCBhcyB3ZSBkb24ndCBzdXBwb3J0XG4gICAgICAvLyBtaXhpbmcgUmVhY3QgcmFkaW8gYnV0dG9ucyB3aXRoIG5vbi1SZWFjdCBvbmVzLlxuXG5cbiAgICAgIHZhciBvdGhlclByb3BzID0gZ2V0RmliZXJDdXJyZW50UHJvcHNGcm9tTm9kZShvdGhlck5vZGUpO1xuXG4gICAgICBpZiAoIW90aGVyUHJvcHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWFjdERPTUlucHV0OiBNaXhpbmcgUmVhY3QgYW5kIG5vbi1SZWFjdCByYWRpbyBpbnB1dHMgd2l0aCB0aGUgJyArICdzYW1lIGBuYW1lYCBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgICAgfSAvLyBXZSBuZWVkIHVwZGF0ZSB0aGUgdHJhY2tlZCB2YWx1ZSBvbiB0aGUgbmFtZWQgY291c2luIHNpbmNlIHRoZSB2YWx1ZVxuICAgICAgLy8gd2FzIGNoYW5nZWQgYnV0IHRoZSBpbnB1dCBzYXcgbm8gZXZlbnQgb3IgdmFsdWUgc2V0XG5cblxuICAgICAgdXBkYXRlVmFsdWVJZkNoYW5nZWQob3RoZXJOb2RlKTsgLy8gSWYgdGhpcyBpcyBhIGNvbnRyb2xsZWQgcmFkaW8gYnV0dG9uIGdyb3VwLCBmb3JjaW5nIHRoZSBpbnB1dCB0aGF0XG4gICAgICAvLyB3YXMgcHJldmlvdXNseSBjaGVja2VkIHRvIHVwZGF0ZSB3aWxsIGNhdXNlIGl0IHRvIGJlIGNvbWUgcmUtY2hlY2tlZFxuICAgICAgLy8gYXMgYXBwcm9wcmlhdGUuXG5cbiAgICAgIHVwZGF0ZVdyYXBwZXIob3RoZXJOb2RlLCBvdGhlclByb3BzKTtcbiAgICB9XG4gIH1cbn0gLy8gSW4gQ2hyb21lLCBhc3NpZ25pbmcgZGVmYXVsdFZhbHVlIHRvIGNlcnRhaW4gaW5wdXQgdHlwZXMgdHJpZ2dlcnMgaW5wdXQgdmFsaWRhdGlvbi5cbi8vIEZvciBudW1iZXIgaW5wdXRzLCB0aGUgZGlzcGxheSB2YWx1ZSBsb3NlcyB0cmFpbGluZyBkZWNpbWFsIHBvaW50cy4gRm9yIGVtYWlsIGlucHV0cyxcbi8vIENocm9tZSByYWlzZXMgXCJUaGUgc3BlY2lmaWVkIHZhbHVlIDx4PiBpcyBub3QgYSB2YWxpZCBlbWFpbCBhZGRyZXNzXCIuXG4vL1xuLy8gSGVyZSB3ZSBjaGVjayB0byBzZWUgaWYgdGhlIGRlZmF1bHRWYWx1ZSBoYXMgYWN0dWFsbHkgY2hhbmdlZCwgYXZvaWRpbmcgdGhlc2UgcHJvYmxlbXNcbi8vIHdoZW4gdGhlIHVzZXIgaXMgaW5wdXR0aW5nIHRleHRcbi8vXG4vLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzcyNTNcblxuXG5mdW5jdGlvbiBzZXREZWZhdWx0VmFsdWUobm9kZSwgdHlwZSwgdmFsdWUpIHtcbiAgaWYgKCAvLyBGb2N1c2VkIG51bWJlciBpbnB1dHMgc3luY2hyb25pemUgb24gYmx1ci4gU2VlIENoYW5nZUV2ZW50UGx1Z2luLmpzXG4gIHR5cGUgIT09ICdudW1iZXInIHx8IGdldEFjdGl2ZUVsZW1lbnQobm9kZS5vd25lckRvY3VtZW50KSAhPT0gbm9kZSkge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IHRvU3RyaW5nKG5vZGUuX3dyYXBwZXJTdGF0ZS5pbml0aWFsVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAobm9kZS5kZWZhdWx0VmFsdWUgIT09IHRvU3RyaW5nKHZhbHVlKSkge1xuICAgICAgbm9kZS5kZWZhdWx0VmFsdWUgPSB0b1N0cmluZyh2YWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbnZhciBkaWRXYXJuU2VsZWN0ZWRTZXRPbk9wdGlvbiA9IGZhbHNlO1xudmFyIGRpZFdhcm5JbnZhbGlkQ2hpbGQgPSBmYWxzZTtcbnZhciBkaWRXYXJuSW52YWxpZElubmVySFRNTCA9IGZhbHNlO1xuLyoqXG4gKiBJbXBsZW1lbnRzIGFuIDxvcHRpb24+IGhvc3QgY29tcG9uZW50IHRoYXQgd2FybnMgd2hlbiBgc2VsZWN0ZWRgIGlzIHNldC5cbiAqL1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BzKGVsZW1lbnQsIHByb3BzKSB7XG4gIHtcbiAgICAvLyBJZiBhIHZhbHVlIGlzIG5vdCBwcm92aWRlZCwgdGhlbiB0aGUgY2hpbGRyZW4gbXVzdCBiZSBzaW1wbGUuXG4gICAgaWYgKHByb3BzLnZhbHVlID09IG51bGwpIHtcbiAgICAgIGlmICh0eXBlb2YgcHJvcHMuY2hpbGRyZW4gPT09ICdvYmplY3QnICYmIHByb3BzLmNoaWxkcmVuICE9PSBudWxsKSB7XG4gICAgICAgIFJlYWN0LkNoaWxkcmVuLmZvckVhY2gocHJvcHMuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgIGlmIChjaGlsZCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjaGlsZCA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGNoaWxkID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghZGlkV2FybkludmFsaWRDaGlsZCkge1xuICAgICAgICAgICAgZGlkV2FybkludmFsaWRDaGlsZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGVycm9yKCdDYW5ub3QgaW5mZXIgdGhlIG9wdGlvbiB2YWx1ZSBvZiBjb21wbGV4IGNoaWxkcmVuLiAnICsgJ1Bhc3MgYSBgdmFsdWVgIHByb3Agb3IgdXNlIGEgcGxhaW4gc3RyaW5nIGFzIGNoaWxkcmVuIHRvIDxvcHRpb24+LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICAgICAgaWYgKCFkaWRXYXJuSW52YWxpZElubmVySFRNTCkge1xuICAgICAgICAgIGRpZFdhcm5JbnZhbGlkSW5uZXJIVE1MID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCdQYXNzIGEgYHZhbHVlYCBwcm9wIGlmIHlvdSBzZXQgZGFuZ2Vyb3VzbHlJbm5lckhUTUwgc28gUmVhY3Qga25vd3MgJyArICd3aGljaCB2YWx1ZSBzaG91bGQgYmUgc2VsZWN0ZWQuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IC8vIFRPRE86IFJlbW92ZSBzdXBwb3J0IGZvciBgc2VsZWN0ZWRgIGluIDxvcHRpb24+LlxuXG5cbiAgICBpZiAocHJvcHMuc2VsZWN0ZWQgIT0gbnVsbCAmJiAhZGlkV2FyblNlbGVjdGVkU2V0T25PcHRpb24pIHtcbiAgICAgIGVycm9yKCdVc2UgdGhlIGBkZWZhdWx0VmFsdWVgIG9yIGB2YWx1ZWAgcHJvcHMgb24gPHNlbGVjdD4gaW5zdGVhZCBvZiAnICsgJ3NldHRpbmcgYHNlbGVjdGVkYCBvbiA8b3B0aW9uPi4nKTtcblxuICAgICAgZGlkV2FyblNlbGVjdGVkU2V0T25PcHRpb24gPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcG9zdE1vdW50V3JhcHBlciQxKGVsZW1lbnQsIHByb3BzKSB7XG4gIC8vIHZhbHVlPVwiXCIgc2hvdWxkIG1ha2UgYSB2YWx1ZSBhdHRyaWJ1dGUgKCM2MjE5KVxuICBpZiAocHJvcHMudmFsdWUgIT0gbnVsbCkge1xuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIHRvU3RyaW5nKGdldFRvU3RyaW5nVmFsdWUocHJvcHMudmFsdWUpKSk7XG4gIH1cbn1cblxudmFyIGlzQXJyYXlJbXBsID0gQXJyYXkuaXNBcnJheTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuXG5mdW5jdGlvbiBpc0FycmF5KGEpIHtcbiAgcmV0dXJuIGlzQXJyYXlJbXBsKGEpO1xufVxuXG52YXIgZGlkV2FyblZhbHVlRGVmYXVsdFZhbHVlJDE7XG5cbntcbiAgZGlkV2FyblZhbHVlRGVmYXVsdFZhbHVlJDEgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCkge1xuICB2YXIgb3duZXJOYW1lID0gZ2V0Q3VycmVudEZpYmVyT3duZXJOYW1lSW5EZXZPck51bGwoKTtcblxuICBpZiAob3duZXJOYW1lKSB7XG4gICAgcmV0dXJuICdcXG5cXG5DaGVjayB0aGUgcmVuZGVyIG1ldGhvZCBvZiBgJyArIG93bmVyTmFtZSArICdgLic7XG4gIH1cblxuICByZXR1cm4gJyc7XG59XG5cbnZhciB2YWx1ZVByb3BOYW1lcyA9IFsndmFsdWUnLCAnZGVmYXVsdFZhbHVlJ107XG4vKipcbiAqIFZhbGlkYXRpb24gZnVuY3Rpb24gZm9yIGB2YWx1ZWAgYW5kIGBkZWZhdWx0VmFsdWVgLlxuICovXG5cbmZ1bmN0aW9uIGNoZWNrU2VsZWN0UHJvcFR5cGVzKHByb3BzKSB7XG4gIHtcbiAgICBjaGVja0NvbnRyb2xsZWRWYWx1ZVByb3BzKCdzZWxlY3QnLCBwcm9wcyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlUHJvcE5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcHJvcE5hbWUgPSB2YWx1ZVByb3BOYW1lc1tpXTtcblxuICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSA9PSBudWxsKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgcHJvcE5hbWVJc0FycmF5ID0gaXNBcnJheShwcm9wc1twcm9wTmFtZV0pO1xuXG4gICAgICBpZiAocHJvcHMubXVsdGlwbGUgJiYgIXByb3BOYW1lSXNBcnJheSkge1xuICAgICAgICBlcnJvcignVGhlIGAlc2AgcHJvcCBzdXBwbGllZCB0byA8c2VsZWN0PiBtdXN0IGJlIGFuIGFycmF5IGlmICcgKyAnYG11bHRpcGxlYCBpcyB0cnVlLiVzJywgcHJvcE5hbWUsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpKTtcbiAgICAgIH0gZWxzZSBpZiAoIXByb3BzLm11bHRpcGxlICYmIHByb3BOYW1lSXNBcnJheSkge1xuICAgICAgICBlcnJvcignVGhlIGAlc2AgcHJvcCBzdXBwbGllZCB0byA8c2VsZWN0PiBtdXN0IGJlIGEgc2NhbGFyICcgKyAndmFsdWUgaWYgYG11bHRpcGxlYCBpcyBmYWxzZS4lcycsIHByb3BOYW1lLCBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU9wdGlvbnMobm9kZSwgbXVsdGlwbGUsIHByb3BWYWx1ZSwgc2V0RGVmYXVsdFNlbGVjdGVkKSB7XG4gIHZhciBvcHRpb25zID0gbm9kZS5vcHRpb25zO1xuXG4gIGlmIChtdWx0aXBsZSkge1xuICAgIHZhciBzZWxlY3RlZFZhbHVlcyA9IHByb3BWYWx1ZTtcbiAgICB2YXIgc2VsZWN0ZWRWYWx1ZSA9IHt9O1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxlY3RlZFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gUHJlZml4IHRvIGF2b2lkIGNoYW9zIHdpdGggc3BlY2lhbCBrZXlzLlxuICAgICAgc2VsZWN0ZWRWYWx1ZVsnJCcgKyBzZWxlY3RlZFZhbHVlc1tpXV0gPSB0cnVlO1xuICAgIH1cblxuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBvcHRpb25zLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIHNlbGVjdGVkID0gc2VsZWN0ZWRWYWx1ZS5oYXNPd25Qcm9wZXJ0eSgnJCcgKyBvcHRpb25zW19pXS52YWx1ZSk7XG5cbiAgICAgIGlmIChvcHRpb25zW19pXS5zZWxlY3RlZCAhPT0gc2VsZWN0ZWQpIHtcbiAgICAgICAgb3B0aW9uc1tfaV0uc2VsZWN0ZWQgPSBzZWxlY3RlZDtcbiAgICAgIH1cblxuICAgICAgaWYgKHNlbGVjdGVkICYmIHNldERlZmF1bHRTZWxlY3RlZCkge1xuICAgICAgICBvcHRpb25zW19pXS5kZWZhdWx0U2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBEbyBub3Qgc2V0IGBzZWxlY3QudmFsdWVgIGFzIGV4YWN0IGJlaGF2aW9yIGlzbid0IGNvbnNpc3RlbnQgYWNyb3NzIGFsbFxuICAgIC8vIGJyb3dzZXJzIGZvciBhbGwgY2FzZXMuXG4gICAgdmFyIF9zZWxlY3RlZFZhbHVlID0gdG9TdHJpbmcoZ2V0VG9TdHJpbmdWYWx1ZShwcm9wVmFsdWUpKTtcblxuICAgIHZhciBkZWZhdWx0U2VsZWN0ZWQgPSBudWxsO1xuXG4gICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgb3B0aW9ucy5sZW5ndGg7IF9pMisrKSB7XG4gICAgICBpZiAob3B0aW9uc1tfaTJdLnZhbHVlID09PSBfc2VsZWN0ZWRWYWx1ZSkge1xuICAgICAgICBvcHRpb25zW19pMl0uc2VsZWN0ZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmIChzZXREZWZhdWx0U2VsZWN0ZWQpIHtcbiAgICAgICAgICBvcHRpb25zW19pMl0uZGVmYXVsdFNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRlZmF1bHRTZWxlY3RlZCA9PT0gbnVsbCAmJiAhb3B0aW9uc1tfaTJdLmRpc2FibGVkKSB7XG4gICAgICAgIGRlZmF1bHRTZWxlY3RlZCA9IG9wdGlvbnNbX2kyXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGVmYXVsdFNlbGVjdGVkICE9PSBudWxsKSB7XG4gICAgICBkZWZhdWx0U2VsZWN0ZWQuc2VsZWN0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBJbXBsZW1lbnRzIGEgPHNlbGVjdD4gaG9zdCBjb21wb25lbnQgdGhhdCBhbGxvd3Mgb3B0aW9uYWxseSBzZXR0aW5nIHRoZVxuICogcHJvcHMgYHZhbHVlYCBhbmQgYGRlZmF1bHRWYWx1ZWAuIElmIGBtdWx0aXBsZWAgaXMgZmFsc2UsIHRoZSBwcm9wIG11c3QgYmUgYVxuICogc3RyaW5nYWJsZS4gSWYgYG11bHRpcGxlYCBpcyB0cnVlLCB0aGUgcHJvcCBtdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ2FibGVzLlxuICpcbiAqIElmIGB2YWx1ZWAgaXMgbm90IHN1cHBsaWVkIChvciBudWxsL3VuZGVmaW5lZCksIHVzZXIgYWN0aW9ucyB0aGF0IGNoYW5nZSB0aGVcbiAqIHNlbGVjdGVkIG9wdGlvbiB3aWxsIHRyaWdnZXIgdXBkYXRlcyB0byB0aGUgcmVuZGVyZWQgb3B0aW9ucy5cbiAqXG4gKiBJZiBpdCBpcyBzdXBwbGllZCAoYW5kIG5vdCBudWxsL3VuZGVmaW5lZCksIHRoZSByZW5kZXJlZCBvcHRpb25zIHdpbGwgbm90XG4gKiB1cGRhdGUgaW4gcmVzcG9uc2UgdG8gdXNlciBhY3Rpb25zLiBJbnN0ZWFkLCB0aGUgYHZhbHVlYCBwcm9wIG11c3QgY2hhbmdlIGluXG4gKiBvcmRlciBmb3IgdGhlIHJlbmRlcmVkIG9wdGlvbnMgdG8gdXBkYXRlLlxuICpcbiAqIElmIGBkZWZhdWx0VmFsdWVgIGlzIHByb3ZpZGVkLCBhbnkgb3B0aW9ucyB3aXRoIHRoZSBzdXBwbGllZCB2YWx1ZXMgd2lsbCBiZVxuICogc2VsZWN0ZWQuXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRIb3N0UHJvcHMkMShlbGVtZW50LCBwcm9wcykge1xuICByZXR1cm4gYXNzaWduKHt9LCBwcm9wcywge1xuICAgIHZhbHVlOiB1bmRlZmluZWRcbiAgfSk7XG59XG5mdW5jdGlvbiBpbml0V3JhcHBlclN0YXRlJDEoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuXG4gIHtcbiAgICBjaGVja1NlbGVjdFByb3BUeXBlcyhwcm9wcyk7XG4gIH1cblxuICBub2RlLl93cmFwcGVyU3RhdGUgPSB7XG4gICAgd2FzTXVsdGlwbGU6ICEhcHJvcHMubXVsdGlwbGVcbiAgfTtcblxuICB7XG4gICAgaWYgKHByb3BzLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgcHJvcHMuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWRpZFdhcm5WYWx1ZURlZmF1bHRWYWx1ZSQxKSB7XG4gICAgICBlcnJvcignU2VsZWN0IGVsZW1lbnRzIG11c3QgYmUgZWl0aGVyIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkICcgKyAnKHNwZWNpZnkgZWl0aGVyIHRoZSB2YWx1ZSBwcm9wLCBvciB0aGUgZGVmYXVsdFZhbHVlIHByb3AsIGJ1dCBub3QgJyArICdib3RoKS4gRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCBzZWxlY3QgJyArICdlbGVtZW50IGFuZCByZW1vdmUgb25lIG9mIHRoZXNlIHByb3BzLiBNb3JlIGluZm86ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycpO1xuXG4gICAgICBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUkMSA9IHRydWU7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwb3N0TW91bnRXcmFwcGVyJDIoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICBub2RlLm11bHRpcGxlID0gISFwcm9wcy5tdWx0aXBsZTtcbiAgdmFyIHZhbHVlID0gcHJvcHMudmFsdWU7XG5cbiAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICB1cGRhdGVPcHRpb25zKG5vZGUsICEhcHJvcHMubXVsdGlwbGUsIHZhbHVlLCBmYWxzZSk7XG4gIH0gZWxzZSBpZiAocHJvcHMuZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICB1cGRhdGVPcHRpb25zKG5vZGUsICEhcHJvcHMubXVsdGlwbGUsIHByb3BzLmRlZmF1bHRWYWx1ZSwgdHJ1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHBvc3RVcGRhdGVXcmFwcGVyKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdmFyIHdhc011bHRpcGxlID0gbm9kZS5fd3JhcHBlclN0YXRlLndhc011bHRpcGxlO1xuICBub2RlLl93cmFwcGVyU3RhdGUud2FzTXVsdGlwbGUgPSAhIXByb3BzLm11bHRpcGxlO1xuICB2YXIgdmFsdWUgPSBwcm9wcy52YWx1ZTtcblxuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIHVwZGF0ZU9wdGlvbnMobm9kZSwgISFwcm9wcy5tdWx0aXBsZSwgdmFsdWUsIGZhbHNlKTtcbiAgfSBlbHNlIGlmICh3YXNNdWx0aXBsZSAhPT0gISFwcm9wcy5tdWx0aXBsZSkge1xuICAgIC8vIEZvciBzaW1wbGljaXR5LCByZWFwcGx5IGBkZWZhdWx0VmFsdWVgIGlmIGBtdWx0aXBsZWAgaXMgdG9nZ2xlZC5cbiAgICBpZiAocHJvcHMuZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICAgIHVwZGF0ZU9wdGlvbnMobm9kZSwgISFwcm9wcy5tdWx0aXBsZSwgcHJvcHMuZGVmYXVsdFZhbHVlLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmV2ZXJ0IHRoZSBzZWxlY3QgYmFjayB0byBpdHMgZGVmYXVsdCB1bnNlbGVjdGVkIHN0YXRlLlxuICAgICAgdXBkYXRlT3B0aW9ucyhub2RlLCAhIXByb3BzLm11bHRpcGxlLCBwcm9wcy5tdWx0aXBsZSA/IFtdIDogJycsIGZhbHNlKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMShlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIHZhciB2YWx1ZSA9IHByb3BzLnZhbHVlO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgdXBkYXRlT3B0aW9ucyhub2RlLCAhIXByb3BzLm11bHRpcGxlLCB2YWx1ZSwgZmFsc2UpO1xuICB9XG59XG5cbnZhciBkaWRXYXJuVmFsRGVmYXVsdFZhbCA9IGZhbHNlO1xuXG4vKipcbiAqIEltcGxlbWVudHMgYSA8dGV4dGFyZWE+IGhvc3QgY29tcG9uZW50IHRoYXQgYWxsb3dzIHNldHRpbmcgYHZhbHVlYCwgYW5kXG4gKiBgZGVmYXVsdFZhbHVlYC4gVGhpcyBkaWZmZXJzIGZyb20gdGhlIHRyYWRpdGlvbmFsIERPTSBBUEkgYmVjYXVzZSB2YWx1ZSBpc1xuICogdXN1YWxseSBzZXQgYXMgUENEQVRBIGNoaWxkcmVuLlxuICpcbiAqIElmIGB2YWx1ZWAgaXMgbm90IHN1cHBsaWVkIChvciBudWxsL3VuZGVmaW5lZCksIHVzZXIgYWN0aW9ucyB0aGF0IGFmZmVjdCB0aGVcbiAqIHZhbHVlIHdpbGwgdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIElmIGB2YWx1ZWAgaXMgc3VwcGxpZWQgKGFuZCBub3QgbnVsbC91bmRlZmluZWQpLCB0aGUgcmVuZGVyZWQgZWxlbWVudCB3aWxsXG4gKiBub3QgdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSBlbGVtZW50LiBJbnN0ZWFkLCB0aGUgYHZhbHVlYCBwcm9wIG11c3QgY2hhbmdlIGluXG4gKiBvcmRlciBmb3IgdGhlIHJlbmRlcmVkIGVsZW1lbnQgdG8gYmUgdXBkYXRlZC5cbiAqXG4gKiBUaGUgcmVuZGVyZWQgZWxlbWVudCB3aWxsIGJlIGluaXRpYWxpemVkIHdpdGggYW4gZW1wdHkgdmFsdWUsIHRoZSBwcm9wXG4gKiBgZGVmYXVsdFZhbHVlYCBpZiBzcGVjaWZpZWQsIG9yIHRoZSBjaGlsZHJlbiBjb250ZW50IChkZXByZWNhdGVkKS5cbiAqL1xuZnVuY3Rpb24gZ2V0SG9zdFByb3BzJDIoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuXG4gIGlmIChwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCAhPSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUxgIGRvZXMgbm90IG1ha2Ugc2Vuc2Ugb24gPHRleHRhcmVhPi4nKTtcbiAgfSAvLyBBbHdheXMgc2V0IGNoaWxkcmVuIHRvIHRoZSBzYW1lIHRoaW5nLiBJbiBJRTksIHRoZSBzZWxlY3Rpb24gcmFuZ2Ugd2lsbFxuICAvLyBnZXQgcmVzZXQgaWYgYHRleHRDb250ZW50YCBpcyBtdXRhdGVkLiAgV2UgY291bGQgYWRkIGEgY2hlY2sgaW4gc2V0VGV4dENvbnRlbnRcbiAgLy8gdG8gb25seSBzZXQgdGhlIHZhbHVlIGlmL3doZW4gdGhlIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgbm9kZSB2YWx1ZSAod2hpY2ggd291bGRcbiAgLy8gY29tcGxldGVseSBzb2x2ZSB0aGlzIElFOSBidWcpLCBidXQgU2ViYXN0aWFuK1NvcGhpZSBzZWVtZWQgdG8gbGlrZSB0aGlzXG4gIC8vIHNvbHV0aW9uLiBUaGUgdmFsdWUgY2FuIGJlIGEgYm9vbGVhbiBvciBvYmplY3Qgc28gdGhhdCdzIHdoeSBpdCdzIGZvcmNlZFxuICAvLyB0byBiZSBhIHN0cmluZy5cblxuXG4gIHZhciBob3N0UHJvcHMgPSBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICBkZWZhdWx0VmFsdWU6IHVuZGVmaW5lZCxcbiAgICBjaGlsZHJlbjogdG9TdHJpbmcobm9kZS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZSlcbiAgfSk7XG5cbiAgcmV0dXJuIGhvc3RQcm9wcztcbn1cbmZ1bmN0aW9uIGluaXRXcmFwcGVyU3RhdGUkMihlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG5cbiAge1xuICAgIGNoZWNrQ29udHJvbGxlZFZhbHVlUHJvcHMoJ3RleHRhcmVhJywgcHJvcHMpO1xuXG4gICAgaWYgKHByb3BzLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgcHJvcHMuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWRpZFdhcm5WYWxEZWZhdWx0VmFsKSB7XG4gICAgICBlcnJvcignJXMgY29udGFpbnMgYSB0ZXh0YXJlYSB3aXRoIGJvdGggdmFsdWUgYW5kIGRlZmF1bHRWYWx1ZSBwcm9wcy4gJyArICdUZXh0YXJlYSBlbGVtZW50cyBtdXN0IGJlIGVpdGhlciBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCAnICsgJyhzcGVjaWZ5IGVpdGhlciB0aGUgdmFsdWUgcHJvcCwgb3IgdGhlIGRlZmF1bHRWYWx1ZSBwcm9wLCBidXQgbm90ICcgKyAnYm90aCkuIERlY2lkZSBiZXR3ZWVuIHVzaW5nIGEgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgdGV4dGFyZWEgJyArICdhbmQgcmVtb3ZlIG9uZSBvZiB0aGVzZSBwcm9wcy4gTW9yZSBpbmZvOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9jb250cm9sbGVkLWNvbXBvbmVudHMnLCBnZXRDdXJyZW50RmliZXJPd25lck5hbWVJbkRldk9yTnVsbCgpIHx8ICdBIGNvbXBvbmVudCcpO1xuXG4gICAgICBkaWRXYXJuVmFsRGVmYXVsdFZhbCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGluaXRpYWxWYWx1ZSA9IHByb3BzLnZhbHVlOyAvLyBPbmx5IGJvdGhlciBmZXRjaGluZyBkZWZhdWx0IHZhbHVlIGlmIHdlJ3JlIGdvaW5nIHRvIHVzZSBpdFxuXG4gIGlmIChpbml0aWFsVmFsdWUgPT0gbnVsbCkge1xuICAgIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLFxuICAgICAgICBkZWZhdWx0VmFsdWUgPSBwcm9wcy5kZWZhdWx0VmFsdWU7XG5cbiAgICBpZiAoY2hpbGRyZW4gIT0gbnVsbCkge1xuICAgICAge1xuICAgICAgICBlcnJvcignVXNlIHRoZSBgZGVmYXVsdFZhbHVlYCBvciBgdmFsdWVgIHByb3BzIGluc3RlYWQgb2Ygc2V0dGluZyAnICsgJ2NoaWxkcmVuIG9uIDx0ZXh0YXJlYT4uJyk7XG4gICAgICB9XG5cbiAgICAgIHtcbiAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJZiB5b3Ugc3VwcGx5IGBkZWZhdWx0VmFsdWVgIG9uIGEgPHRleHRhcmVhPiwgZG8gbm90IHBhc3MgY2hpbGRyZW4uJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNBcnJheShjaGlsZHJlbikpIHtcbiAgICAgICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCc8dGV4dGFyZWE+IGNhbiBvbmx5IGhhdmUgYXQgbW9zdCBvbmUgY2hpbGQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlblswXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlZmF1bHRWYWx1ZSA9IGNoaWxkcmVuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkZWZhdWx0VmFsdWUgPT0gbnVsbCkge1xuICAgICAgZGVmYXVsdFZhbHVlID0gJyc7XG4gICAgfVxuXG4gICAgaW5pdGlhbFZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgbm9kZS5fd3JhcHBlclN0YXRlID0ge1xuICAgIGluaXRpYWxWYWx1ZTogZ2V0VG9TdHJpbmdWYWx1ZShpbml0aWFsVmFsdWUpXG4gIH07XG59XG5mdW5jdGlvbiB1cGRhdGVXcmFwcGVyJDEoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB2YXIgdmFsdWUgPSBnZXRUb1N0cmluZ1ZhbHVlKHByb3BzLnZhbHVlKTtcbiAgdmFyIGRlZmF1bHRWYWx1ZSA9IGdldFRvU3RyaW5nVmFsdWUocHJvcHMuZGVmYXVsdFZhbHVlKTtcblxuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIC8vIENhc3QgYHZhbHVlYCB0byBhIHN0cmluZyB0byBlbnN1cmUgdGhlIHZhbHVlIGlzIHNldCBjb3JyZWN0bHkuIFdoaWxlXG4gICAgLy8gYnJvd3NlcnMgdHlwaWNhbGx5IGRvIHRoaXMgYXMgbmVjZXNzYXJ5LCBqc2RvbSBkb2Vzbid0LlxuICAgIHZhciBuZXdWYWx1ZSA9IHRvU3RyaW5nKHZhbHVlKTsgLy8gVG8gYXZvaWQgc2lkZSBlZmZlY3RzIChzdWNoIGFzIGxvc2luZyB0ZXh0IHNlbGVjdGlvbiksIG9ubHkgc2V0IHZhbHVlIGlmIGNoYW5nZWRcblxuICAgIGlmIChuZXdWYWx1ZSAhPT0gbm9kZS52YWx1ZSkge1xuICAgICAgbm9kZS52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5kZWZhdWx0VmFsdWUgPT0gbnVsbCAmJiBub2RlLmRlZmF1bHRWYWx1ZSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgIG5vZGUuZGVmYXVsdFZhbHVlID0gbmV3VmFsdWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRlZmF1bHRWYWx1ZSAhPSBudWxsKSB7XG4gICAgbm9kZS5kZWZhdWx0VmFsdWUgPSB0b1N0cmluZyhkZWZhdWx0VmFsdWUpO1xuICB9XG59XG5mdW5jdGlvbiBwb3N0TW91bnRXcmFwcGVyJDMoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50OyAvLyBUaGlzIGlzIGluIHBvc3RNb3VudCBiZWNhdXNlIHdlIG5lZWQgYWNjZXNzIHRvIHRoZSBET00gbm9kZSwgd2hpY2ggaXMgbm90XG4gIC8vIGF2YWlsYWJsZSB1bnRpbCBhZnRlciB0aGUgY29tcG9uZW50IGhhcyBtb3VudGVkLlxuXG4gIHZhciB0ZXh0Q29udGVudCA9IG5vZGUudGV4dENvbnRlbnQ7IC8vIE9ubHkgc2V0IG5vZGUudmFsdWUgaWYgdGV4dENvbnRlbnQgaXMgZXF1YWwgdG8gdGhlIGV4cGVjdGVkXG4gIC8vIGluaXRpYWwgdmFsdWUuIEluIElFMTAvSUUxMSB0aGVyZSBpcyBhIGJ1ZyB3aGVyZSB0aGUgcGxhY2Vob2xkZXIgYXR0cmlidXRlXG4gIC8vIHdpbGwgcG9wdWxhdGUgdGV4dENvbnRlbnQgYXMgd2VsbC5cbiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9taWNyb3NvZnQtZWRnZS9wbGF0Zm9ybS9pc3N1ZXMvMTAxNTI1L1xuXG4gIGlmICh0ZXh0Q29udGVudCA9PT0gbm9kZS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZSkge1xuICAgIGlmICh0ZXh0Q29udGVudCAhPT0gJycgJiYgdGV4dENvbnRlbnQgIT09IG51bGwpIHtcbiAgICAgIG5vZGUudmFsdWUgPSB0ZXh0Q29udGVudDtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMihlbGVtZW50LCBwcm9wcykge1xuICAvLyBET00gY29tcG9uZW50IGlzIHN0aWxsIG1vdW50ZWQ7IHVwZGF0ZVxuICB1cGRhdGVXcmFwcGVyJDEoZWxlbWVudCwgcHJvcHMpO1xufVxuXG52YXIgSFRNTF9OQU1FU1BBQ0UgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCc7XG52YXIgTUFUSF9OQU1FU1BBQ0UgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCc7XG52YXIgU1ZHX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc7IC8vIEFzc3VtZXMgdGhlcmUgaXMgbm8gcGFyZW50IG5hbWVzcGFjZS5cblxuZnVuY3Rpb24gZ2V0SW50cmluc2ljTmFtZXNwYWNlKHR5cGUpIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnc3ZnJzpcbiAgICAgIHJldHVybiBTVkdfTkFNRVNQQUNFO1xuXG4gICAgY2FzZSAnbWF0aCc6XG4gICAgICByZXR1cm4gTUFUSF9OQU1FU1BBQ0U7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIEhUTUxfTkFNRVNQQUNFO1xuICB9XG59XG5mdW5jdGlvbiBnZXRDaGlsZE5hbWVzcGFjZShwYXJlbnROYW1lc3BhY2UsIHR5cGUpIHtcbiAgaWYgKHBhcmVudE5hbWVzcGFjZSA9PSBudWxsIHx8IHBhcmVudE5hbWVzcGFjZSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICAvLyBObyAob3IgZGVmYXVsdCkgcGFyZW50IG5hbWVzcGFjZTogcG90ZW50aWFsIGVudHJ5IHBvaW50LlxuICAgIHJldHVybiBnZXRJbnRyaW5zaWNOYW1lc3BhY2UodHlwZSk7XG4gIH1cblxuICBpZiAocGFyZW50TmFtZXNwYWNlID09PSBTVkdfTkFNRVNQQUNFICYmIHR5cGUgPT09ICdmb3JlaWduT2JqZWN0Jykge1xuICAgIC8vIFdlJ3JlIGxlYXZpbmcgU1ZHLlxuICAgIHJldHVybiBIVE1MX05BTUVTUEFDRTtcbiAgfSAvLyBCeSBkZWZhdWx0LCBwYXNzIG5hbWVzcGFjZSBiZWxvdy5cblxuXG4gIHJldHVybiBwYXJlbnROYW1lc3BhY2U7XG59XG5cbi8qIGdsb2JhbHMgTVNBcHAgKi9cblxuLyoqXG4gKiBDcmVhdGUgYSBmdW5jdGlvbiB3aGljaCBoYXMgJ3Vuc2FmZScgcHJpdmlsZWdlcyAocmVxdWlyZWQgYnkgd2luZG93czggYXBwcylcbiAqL1xudmFyIGNyZWF0ZU1pY3Jvc29mdFVuc2FmZUxvY2FsRnVuY3Rpb24gPSBmdW5jdGlvbiAoZnVuYykge1xuICBpZiAodHlwZW9mIE1TQXBwICE9PSAndW5kZWZpbmVkJyAmJiBNU0FwcC5leGVjVW5zYWZlTG9jYWxGdW5jdGlvbikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoYXJnMCwgYXJnMSwgYXJnMiwgYXJnMykge1xuICAgICAgTVNBcHAuZXhlY1Vuc2FmZUxvY2FsRnVuY3Rpb24oZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gZnVuYyhhcmcwLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbn07XG5cbnZhciByZXVzYWJsZVNWR0NvbnRhaW5lcjtcbi8qKlxuICogU2V0IHRoZSBpbm5lckhUTUwgcHJvcGVydHkgb2YgYSBub2RlXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbFxuICogQGludGVybmFsXG4gKi9cblxudmFyIHNldElubmVySFRNTCA9IGNyZWF0ZU1pY3Jvc29mdFVuc2FmZUxvY2FsRnVuY3Rpb24oZnVuY3Rpb24gKG5vZGUsIGh0bWwpIHtcbiAgaWYgKG5vZGUubmFtZXNwYWNlVVJJID09PSBTVkdfTkFNRVNQQUNFKSB7XG5cbiAgICBpZiAoISgnaW5uZXJIVE1MJyBpbiBub2RlKSkge1xuICAgICAgLy8gSUUgZG9lcyBub3QgaGF2ZSBpbm5lckhUTUwgZm9yIFNWRyBub2Rlcywgc28gaW5zdGVhZCB3ZSBpbmplY3QgdGhlXG4gICAgICAvLyBuZXcgbWFya3VwIGluIGEgdGVtcCBub2RlIGFuZCB0aGVuIG1vdmUgdGhlIGNoaWxkIG5vZGVzIGFjcm9zcyBpbnRvXG4gICAgICAvLyB0aGUgdGFyZ2V0IG5vZGVcbiAgICAgIHJldXNhYmxlU1ZHQ29udGFpbmVyID0gcmV1c2FibGVTVkdDb250YWluZXIgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICByZXVzYWJsZVNWR0NvbnRhaW5lci5pbm5lckhUTUwgPSAnPHN2Zz4nICsgaHRtbC52YWx1ZU9mKCkudG9TdHJpbmcoKSArICc8L3N2Zz4nO1xuICAgICAgdmFyIHN2Z05vZGUgPSByZXVzYWJsZVNWR0NvbnRhaW5lci5maXJzdENoaWxkO1xuXG4gICAgICB3aGlsZSAobm9kZS5maXJzdENoaWxkKSB7XG4gICAgICAgIG5vZGUucmVtb3ZlQ2hpbGQobm9kZS5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKHN2Z05vZGUuZmlyc3RDaGlsZCkge1xuICAgICAgICBub2RlLmFwcGVuZENoaWxkKHN2Z05vZGUuZmlyc3RDaGlsZCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBub2RlLmlubmVySFRNTCA9IGh0bWw7XG59KTtcblxuLyoqXG4gKiBIVE1MIG5vZGVUeXBlIHZhbHVlcyB0aGF0IHJlcHJlc2VudCB0aGUgdHlwZSBvZiB0aGUgbm9kZVxuICovXG52YXIgRUxFTUVOVF9OT0RFID0gMTtcbnZhciBURVhUX05PREUgPSAzO1xudmFyIENPTU1FTlRfTk9ERSA9IDg7XG52YXIgRE9DVU1FTlRfTk9ERSA9IDk7XG52YXIgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9IDExO1xuXG4vKipcbiAqIFNldCB0aGUgdGV4dENvbnRlbnQgcHJvcGVydHkgb2YgYSBub2RlLiBGb3IgdGV4dCB1cGRhdGVzLCBpdCdzIGZhc3RlclxuICogdG8gc2V0IHRoZSBgbm9kZVZhbHVlYCBvZiB0aGUgVGV4dCBub2RlIGRpcmVjdGx5IGluc3RlYWQgb2YgdXNpbmdcbiAqIGAudGV4dENvbnRlbnRgIHdoaWNoIHdpbGwgcmVtb3ZlIHRoZSBleGlzdGluZyBub2RlIGFuZCBjcmVhdGUgYSBuZXcgb25lLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBpbnRlcm5hbFxuICovXG5cbnZhciBzZXRUZXh0Q29udGVudCA9IGZ1bmN0aW9uIChub2RlLCB0ZXh0KSB7XG4gIGlmICh0ZXh0KSB7XG4gICAgdmFyIGZpcnN0Q2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQ7XG5cbiAgICBpZiAoZmlyc3RDaGlsZCAmJiBmaXJzdENoaWxkID09PSBub2RlLmxhc3RDaGlsZCAmJiBmaXJzdENoaWxkLm5vZGVUeXBlID09PSBURVhUX05PREUpIHtcbiAgICAgIGZpcnN0Q2hpbGQubm9kZVZhbHVlID0gdGV4dDtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBub2RlLnRleHRDb250ZW50ID0gdGV4dDtcbn07XG5cbi8vIExpc3QgZGVyaXZlZCBmcm9tIEdlY2tvIHNvdXJjZSBjb2RlOlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL21vemlsbGEvZ2Vja28tZGV2L2Jsb2IvNGU2MzhlZmM3MS9sYXlvdXQvc3R5bGUvdGVzdC9wcm9wZXJ0eV9kYXRhYmFzZS5qc1xudmFyIHNob3J0aGFuZFRvTG9uZ2hhbmQgPSB7XG4gIGFuaW1hdGlvbjogWydhbmltYXRpb25EZWxheScsICdhbmltYXRpb25EaXJlY3Rpb24nLCAnYW5pbWF0aW9uRHVyYXRpb24nLCAnYW5pbWF0aW9uRmlsbE1vZGUnLCAnYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQnLCAnYW5pbWF0aW9uTmFtZScsICdhbmltYXRpb25QbGF5U3RhdGUnLCAnYW5pbWF0aW9uVGltaW5nRnVuY3Rpb24nXSxcbiAgYmFja2dyb3VuZDogWydiYWNrZ3JvdW5kQXR0YWNobWVudCcsICdiYWNrZ3JvdW5kQ2xpcCcsICdiYWNrZ3JvdW5kQ29sb3InLCAnYmFja2dyb3VuZEltYWdlJywgJ2JhY2tncm91bmRPcmlnaW4nLCAnYmFja2dyb3VuZFBvc2l0aW9uWCcsICdiYWNrZ3JvdW5kUG9zaXRpb25ZJywgJ2JhY2tncm91bmRSZXBlYXQnLCAnYmFja2dyb3VuZFNpemUnXSxcbiAgYmFja2dyb3VuZFBvc2l0aW9uOiBbJ2JhY2tncm91bmRQb3NpdGlvblgnLCAnYmFja2dyb3VuZFBvc2l0aW9uWSddLFxuICBib3JkZXI6IFsnYm9yZGVyQm90dG9tQ29sb3InLCAnYm9yZGVyQm90dG9tU3R5bGUnLCAnYm9yZGVyQm90dG9tV2lkdGgnLCAnYm9yZGVySW1hZ2VPdXRzZXQnLCAnYm9yZGVySW1hZ2VSZXBlYXQnLCAnYm9yZGVySW1hZ2VTbGljZScsICdib3JkZXJJbWFnZVNvdXJjZScsICdib3JkZXJJbWFnZVdpZHRoJywgJ2JvcmRlckxlZnRDb2xvcicsICdib3JkZXJMZWZ0U3R5bGUnLCAnYm9yZGVyTGVmdFdpZHRoJywgJ2JvcmRlclJpZ2h0Q29sb3InLCAnYm9yZGVyUmlnaHRTdHlsZScsICdib3JkZXJSaWdodFdpZHRoJywgJ2JvcmRlclRvcENvbG9yJywgJ2JvcmRlclRvcFN0eWxlJywgJ2JvcmRlclRvcFdpZHRoJ10sXG4gIGJvcmRlckJsb2NrRW5kOiBbJ2JvcmRlckJsb2NrRW5kQ29sb3InLCAnYm9yZGVyQmxvY2tFbmRTdHlsZScsICdib3JkZXJCbG9ja0VuZFdpZHRoJ10sXG4gIGJvcmRlckJsb2NrU3RhcnQ6IFsnYm9yZGVyQmxvY2tTdGFydENvbG9yJywgJ2JvcmRlckJsb2NrU3RhcnRTdHlsZScsICdib3JkZXJCbG9ja1N0YXJ0V2lkdGgnXSxcbiAgYm9yZGVyQm90dG9tOiBbJ2JvcmRlckJvdHRvbUNvbG9yJywgJ2JvcmRlckJvdHRvbVN0eWxlJywgJ2JvcmRlckJvdHRvbVdpZHRoJ10sXG4gIGJvcmRlckNvbG9yOiBbJ2JvcmRlckJvdHRvbUNvbG9yJywgJ2JvcmRlckxlZnRDb2xvcicsICdib3JkZXJSaWdodENvbG9yJywgJ2JvcmRlclRvcENvbG9yJ10sXG4gIGJvcmRlckltYWdlOiBbJ2JvcmRlckltYWdlT3V0c2V0JywgJ2JvcmRlckltYWdlUmVwZWF0JywgJ2JvcmRlckltYWdlU2xpY2UnLCAnYm9yZGVySW1hZ2VTb3VyY2UnLCAnYm9yZGVySW1hZ2VXaWR0aCddLFxuICBib3JkZXJJbmxpbmVFbmQ6IFsnYm9yZGVySW5saW5lRW5kQ29sb3InLCAnYm9yZGVySW5saW5lRW5kU3R5bGUnLCAnYm9yZGVySW5saW5lRW5kV2lkdGgnXSxcbiAgYm9yZGVySW5saW5lU3RhcnQ6IFsnYm9yZGVySW5saW5lU3RhcnRDb2xvcicsICdib3JkZXJJbmxpbmVTdGFydFN0eWxlJywgJ2JvcmRlcklubGluZVN0YXJ0V2lkdGgnXSxcbiAgYm9yZGVyTGVmdDogWydib3JkZXJMZWZ0Q29sb3InLCAnYm9yZGVyTGVmdFN0eWxlJywgJ2JvcmRlckxlZnRXaWR0aCddLFxuICBib3JkZXJSYWRpdXM6IFsnYm9yZGVyQm90dG9tTGVmdFJhZGl1cycsICdib3JkZXJCb3R0b21SaWdodFJhZGl1cycsICdib3JkZXJUb3BMZWZ0UmFkaXVzJywgJ2JvcmRlclRvcFJpZ2h0UmFkaXVzJ10sXG4gIGJvcmRlclJpZ2h0OiBbJ2JvcmRlclJpZ2h0Q29sb3InLCAnYm9yZGVyUmlnaHRTdHlsZScsICdib3JkZXJSaWdodFdpZHRoJ10sXG4gIGJvcmRlclN0eWxlOiBbJ2JvcmRlckJvdHRvbVN0eWxlJywgJ2JvcmRlckxlZnRTdHlsZScsICdib3JkZXJSaWdodFN0eWxlJywgJ2JvcmRlclRvcFN0eWxlJ10sXG4gIGJvcmRlclRvcDogWydib3JkZXJUb3BDb2xvcicsICdib3JkZXJUb3BTdHlsZScsICdib3JkZXJUb3BXaWR0aCddLFxuICBib3JkZXJXaWR0aDogWydib3JkZXJCb3R0b21XaWR0aCcsICdib3JkZXJMZWZ0V2lkdGgnLCAnYm9yZGVyUmlnaHRXaWR0aCcsICdib3JkZXJUb3BXaWR0aCddLFxuICBjb2x1bW5SdWxlOiBbJ2NvbHVtblJ1bGVDb2xvcicsICdjb2x1bW5SdWxlU3R5bGUnLCAnY29sdW1uUnVsZVdpZHRoJ10sXG4gIGNvbHVtbnM6IFsnY29sdW1uQ291bnQnLCAnY29sdW1uV2lkdGgnXSxcbiAgZmxleDogWydmbGV4QmFzaXMnLCAnZmxleEdyb3cnLCAnZmxleFNocmluayddLFxuICBmbGV4RmxvdzogWydmbGV4RGlyZWN0aW9uJywgJ2ZsZXhXcmFwJ10sXG4gIGZvbnQ6IFsnZm9udEZhbWlseScsICdmb250RmVhdHVyZVNldHRpbmdzJywgJ2ZvbnRLZXJuaW5nJywgJ2ZvbnRMYW5ndWFnZU92ZXJyaWRlJywgJ2ZvbnRTaXplJywgJ2ZvbnRTaXplQWRqdXN0JywgJ2ZvbnRTdHJldGNoJywgJ2ZvbnRTdHlsZScsICdmb250VmFyaWFudCcsICdmb250VmFyaWFudEFsdGVybmF0ZXMnLCAnZm9udFZhcmlhbnRDYXBzJywgJ2ZvbnRWYXJpYW50RWFzdEFzaWFuJywgJ2ZvbnRWYXJpYW50TGlnYXR1cmVzJywgJ2ZvbnRWYXJpYW50TnVtZXJpYycsICdmb250VmFyaWFudFBvc2l0aW9uJywgJ2ZvbnRXZWlnaHQnLCAnbGluZUhlaWdodCddLFxuICBmb250VmFyaWFudDogWydmb250VmFyaWFudEFsdGVybmF0ZXMnLCAnZm9udFZhcmlhbnRDYXBzJywgJ2ZvbnRWYXJpYW50RWFzdEFzaWFuJywgJ2ZvbnRWYXJpYW50TGlnYXR1cmVzJywgJ2ZvbnRWYXJpYW50TnVtZXJpYycsICdmb250VmFyaWFudFBvc2l0aW9uJ10sXG4gIGdhcDogWydjb2x1bW5HYXAnLCAncm93R2FwJ10sXG4gIGdyaWQ6IFsnZ3JpZEF1dG9Db2x1bW5zJywgJ2dyaWRBdXRvRmxvdycsICdncmlkQXV0b1Jvd3MnLCAnZ3JpZFRlbXBsYXRlQXJlYXMnLCAnZ3JpZFRlbXBsYXRlQ29sdW1ucycsICdncmlkVGVtcGxhdGVSb3dzJ10sXG4gIGdyaWRBcmVhOiBbJ2dyaWRDb2x1bW5FbmQnLCAnZ3JpZENvbHVtblN0YXJ0JywgJ2dyaWRSb3dFbmQnLCAnZ3JpZFJvd1N0YXJ0J10sXG4gIGdyaWRDb2x1bW46IFsnZ3JpZENvbHVtbkVuZCcsICdncmlkQ29sdW1uU3RhcnQnXSxcbiAgZ3JpZENvbHVtbkdhcDogWydjb2x1bW5HYXAnXSxcbiAgZ3JpZEdhcDogWydjb2x1bW5HYXAnLCAncm93R2FwJ10sXG4gIGdyaWRSb3c6IFsnZ3JpZFJvd0VuZCcsICdncmlkUm93U3RhcnQnXSxcbiAgZ3JpZFJvd0dhcDogWydyb3dHYXAnXSxcbiAgZ3JpZFRlbXBsYXRlOiBbJ2dyaWRUZW1wbGF0ZUFyZWFzJywgJ2dyaWRUZW1wbGF0ZUNvbHVtbnMnLCAnZ3JpZFRlbXBsYXRlUm93cyddLFxuICBsaXN0U3R5bGU6IFsnbGlzdFN0eWxlSW1hZ2UnLCAnbGlzdFN0eWxlUG9zaXRpb24nLCAnbGlzdFN0eWxlVHlwZSddLFxuICBtYXJnaW46IFsnbWFyZ2luQm90dG9tJywgJ21hcmdpbkxlZnQnLCAnbWFyZ2luUmlnaHQnLCAnbWFyZ2luVG9wJ10sXG4gIG1hcmtlcjogWydtYXJrZXJFbmQnLCAnbWFya2VyTWlkJywgJ21hcmtlclN0YXJ0J10sXG4gIG1hc2s6IFsnbWFza0NsaXAnLCAnbWFza0NvbXBvc2l0ZScsICdtYXNrSW1hZ2UnLCAnbWFza01vZGUnLCAnbWFza09yaWdpbicsICdtYXNrUG9zaXRpb25YJywgJ21hc2tQb3NpdGlvblknLCAnbWFza1JlcGVhdCcsICdtYXNrU2l6ZSddLFxuICBtYXNrUG9zaXRpb246IFsnbWFza1Bvc2l0aW9uWCcsICdtYXNrUG9zaXRpb25ZJ10sXG4gIG91dGxpbmU6IFsnb3V0bGluZUNvbG9yJywgJ291dGxpbmVTdHlsZScsICdvdXRsaW5lV2lkdGgnXSxcbiAgb3ZlcmZsb3c6IFsnb3ZlcmZsb3dYJywgJ292ZXJmbG93WSddLFxuICBwYWRkaW5nOiBbJ3BhZGRpbmdCb3R0b20nLCAncGFkZGluZ0xlZnQnLCAncGFkZGluZ1JpZ2h0JywgJ3BhZGRpbmdUb3AnXSxcbiAgcGxhY2VDb250ZW50OiBbJ2FsaWduQ29udGVudCcsICdqdXN0aWZ5Q29udGVudCddLFxuICBwbGFjZUl0ZW1zOiBbJ2FsaWduSXRlbXMnLCAnanVzdGlmeUl0ZW1zJ10sXG4gIHBsYWNlU2VsZjogWydhbGlnblNlbGYnLCAnanVzdGlmeVNlbGYnXSxcbiAgdGV4dERlY29yYXRpb246IFsndGV4dERlY29yYXRpb25Db2xvcicsICd0ZXh0RGVjb3JhdGlvbkxpbmUnLCAndGV4dERlY29yYXRpb25TdHlsZSddLFxuICB0ZXh0RW1waGFzaXM6IFsndGV4dEVtcGhhc2lzQ29sb3InLCAndGV4dEVtcGhhc2lzU3R5bGUnXSxcbiAgdHJhbnNpdGlvbjogWyd0cmFuc2l0aW9uRGVsYXknLCAndHJhbnNpdGlvbkR1cmF0aW9uJywgJ3RyYW5zaXRpb25Qcm9wZXJ0eScsICd0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb24nXSxcbiAgd29yZFdyYXA6IFsnb3ZlcmZsb3dXcmFwJ11cbn07XG5cbi8qKlxuICogQ1NTIHByb3BlcnRpZXMgd2hpY2ggYWNjZXB0IG51bWJlcnMgYnV0IGFyZSBub3QgaW4gdW5pdHMgb2YgXCJweFwiLlxuICovXG52YXIgaXNVbml0bGVzc051bWJlciA9IHtcbiAgYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6IHRydWUsXG4gIGFzcGVjdFJhdGlvOiB0cnVlLFxuICBib3JkZXJJbWFnZU91dHNldDogdHJ1ZSxcbiAgYm9yZGVySW1hZ2VTbGljZTogdHJ1ZSxcbiAgYm9yZGVySW1hZ2VXaWR0aDogdHJ1ZSxcbiAgYm94RmxleDogdHJ1ZSxcbiAgYm94RmxleEdyb3VwOiB0cnVlLFxuICBib3hPcmRpbmFsR3JvdXA6IHRydWUsXG4gIGNvbHVtbkNvdW50OiB0cnVlLFxuICBjb2x1bW5zOiB0cnVlLFxuICBmbGV4OiB0cnVlLFxuICBmbGV4R3JvdzogdHJ1ZSxcbiAgZmxleFBvc2l0aXZlOiB0cnVlLFxuICBmbGV4U2hyaW5rOiB0cnVlLFxuICBmbGV4TmVnYXRpdmU6IHRydWUsXG4gIGZsZXhPcmRlcjogdHJ1ZSxcbiAgZ3JpZEFyZWE6IHRydWUsXG4gIGdyaWRSb3c6IHRydWUsXG4gIGdyaWRSb3dFbmQ6IHRydWUsXG4gIGdyaWRSb3dTcGFuOiB0cnVlLFxuICBncmlkUm93U3RhcnQ6IHRydWUsXG4gIGdyaWRDb2x1bW46IHRydWUsXG4gIGdyaWRDb2x1bW5FbmQ6IHRydWUsXG4gIGdyaWRDb2x1bW5TcGFuOiB0cnVlLFxuICBncmlkQ29sdW1uU3RhcnQ6IHRydWUsXG4gIGZvbnRXZWlnaHQ6IHRydWUsXG4gIGxpbmVDbGFtcDogdHJ1ZSxcbiAgbGluZUhlaWdodDogdHJ1ZSxcbiAgb3BhY2l0eTogdHJ1ZSxcbiAgb3JkZXI6IHRydWUsXG4gIG9ycGhhbnM6IHRydWUsXG4gIHRhYlNpemU6IHRydWUsXG4gIHdpZG93czogdHJ1ZSxcbiAgekluZGV4OiB0cnVlLFxuICB6b29tOiB0cnVlLFxuICAvLyBTVkctcmVsYXRlZCBwcm9wZXJ0aWVzXG4gIGZpbGxPcGFjaXR5OiB0cnVlLFxuICBmbG9vZE9wYWNpdHk6IHRydWUsXG4gIHN0b3BPcGFjaXR5OiB0cnVlLFxuICBzdHJva2VEYXNoYXJyYXk6IHRydWUsXG4gIHN0cm9rZURhc2hvZmZzZXQ6IHRydWUsXG4gIHN0cm9rZU1pdGVybGltaXQ6IHRydWUsXG4gIHN0cm9rZU9wYWNpdHk6IHRydWUsXG4gIHN0cm9rZVdpZHRoOiB0cnVlXG59O1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4IHZlbmRvci1zcGVjaWZpYyBwcmVmaXgsIGVnOiBXZWJraXRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgc3R5bGUgbmFtZSwgZWc6IHRyYW5zaXRpb25EdXJhdGlvblxuICogQHJldHVybiB7c3RyaW5nfSBzdHlsZSBuYW1lIHByZWZpeGVkIHdpdGggYHByZWZpeGAsIHByb3Blcmx5IGNhbWVsQ2FzZWQsIGVnOlxuICogV2Via2l0VHJhbnNpdGlvbkR1cmF0aW9uXG4gKi9cblxuZnVuY3Rpb24gcHJlZml4S2V5KHByZWZpeCwga2V5KSB7XG4gIHJldHVybiBwcmVmaXggKyBrZXkuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBrZXkuc3Vic3RyaW5nKDEpO1xufVxuLyoqXG4gKiBTdXBwb3J0IHN0eWxlIG5hbWVzIHRoYXQgbWF5IGNvbWUgcGFzc2VkIGluIHByZWZpeGVkIGJ5IGFkZGluZyBwZXJtdXRhdGlvbnNcbiAqIG9mIHZlbmRvciBwcmVmaXhlcy5cbiAqL1xuXG5cbnZhciBwcmVmaXhlcyA9IFsnV2Via2l0JywgJ21zJywgJ01veicsICdPJ107IC8vIFVzaW5nIE9iamVjdC5rZXlzIGhlcmUsIG9yIGVsc2UgdGhlIHZhbmlsbGEgZm9yLWluIGxvb3AgbWFrZXMgSUU4IGdvIGludG8gYW5cbi8vIGluZmluaXRlIGxvb3AsIGJlY2F1c2UgaXQgaXRlcmF0ZXMgb3ZlciB0aGUgbmV3bHkgYWRkZWQgcHJvcHMgdG9vLlxuXG5PYmplY3Qua2V5cyhpc1VuaXRsZXNzTnVtYmVyKS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7XG4gIHByZWZpeGVzLmZvckVhY2goZnVuY3Rpb24gKHByZWZpeCkge1xuICAgIGlzVW5pdGxlc3NOdW1iZXJbcHJlZml4S2V5KHByZWZpeCwgcHJvcCldID0gaXNVbml0bGVzc051bWJlcltwcm9wXTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBDb252ZXJ0IGEgdmFsdWUgaW50byB0aGUgcHJvcGVyIGNzcyB3cml0YWJsZSB2YWx1ZS4gVGhlIHN0eWxlIG5hbWUgYG5hbWVgXG4gKiBzaG91bGQgYmUgbG9naWNhbCAobm8gaHlwaGVucyksIGFzIHNwZWNpZmllZFxuICogaW4gYENTU1Byb3BlcnR5LmlzVW5pdGxlc3NOdW1iZXJgLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIENTUyBwcm9wZXJ0eSBuYW1lIHN1Y2ggYXMgYHRvcE1hcmdpbmAuXG4gKiBAcGFyYW0geyp9IHZhbHVlIENTUyBwcm9wZXJ0eSB2YWx1ZSBzdWNoIGFzIGAxMHB4YC5cbiAqIEByZXR1cm4ge3N0cmluZ30gTm9ybWFsaXplZCBzdHlsZSB2YWx1ZSB3aXRoIGRpbWVuc2lvbnMgYXBwbGllZC5cbiAqL1xuXG5mdW5jdGlvbiBkYW5nZXJvdXNTdHlsZVZhbHVlKG5hbWUsIHZhbHVlLCBpc0N1c3RvbVByb3BlcnR5KSB7XG4gIC8vIE5vdGUgdGhhdCB3ZSd2ZSByZW1vdmVkIGVzY2FwZVRleHRGb3JCcm93c2VyKCkgY2FsbHMgaGVyZSBzaW5jZSB0aGVcbiAgLy8gd2hvbGUgc3RyaW5nIHdpbGwgYmUgZXNjYXBlZCB3aGVuIHRoZSBhdHRyaWJ1dGUgaXMgaW5qZWN0ZWQgaW50b1xuICAvLyB0aGUgbWFya3VwLiBJZiB5b3UgcHJvdmlkZSB1bnNhZmUgdXNlciBkYXRhIGhlcmUgdGhleSBjYW4gaW5qZWN0XG4gIC8vIGFyYml0cmFyeSBDU1Mgd2hpY2ggbWF5IGJlIHByb2JsZW1hdGljIChJIGNvdWxkbid0IHJlcHJvIHRoaXMpOlxuICAvLyBodHRwczovL3d3dy5vd2FzcC5vcmcvaW5kZXgucGhwL1hTU19GaWx0ZXJfRXZhc2lvbl9DaGVhdF9TaGVldFxuICAvLyBodHRwOi8vd3d3LnRoZXNwYW5uZXIuY28udWsvMjAwNy8xMS8yNi91bHRpbWF0ZS14c3MtY3NzLWluamVjdGlvbi9cbiAgLy8gVGhpcyBpcyBub3QgYW4gWFNTIGhvbGUgYnV0IGluc3RlYWQgYSBwb3RlbnRpYWwgQ1NTIGluamVjdGlvbiBpc3N1ZVxuICAvLyB3aGljaCBoYXMgbGVhZCB0byBhIGdyZWF0ZXIgZGlzY3Vzc2lvbiBhYm91dCBob3cgd2UncmUgZ29pbmcgdG9cbiAgLy8gdHJ1c3QgVVJMcyBtb3ZpbmcgZm9yd2FyZC4gU2VlICMyMTE1OTAxXG4gIHZhciBpc0VtcHR5ID0gdmFsdWUgPT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyB8fCB2YWx1ZSA9PT0gJyc7XG5cbiAgaWYgKGlzRW1wdHkpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZiAoIWlzQ3VzdG9tUHJvcGVydHkgJiYgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiB2YWx1ZSAhPT0gMCAmJiAhKGlzVW5pdGxlc3NOdW1iZXIuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgaXNVbml0bGVzc051bWJlcltuYW1lXSkpIHtcbiAgICByZXR1cm4gdmFsdWUgKyAncHgnOyAvLyBQcmVzdW1lcyBpbXBsaWNpdCAncHgnIHN1ZmZpeCBmb3IgdW5pdGxlc3MgbnVtYmVyc1xuICB9XG5cbiAge1xuICAgIGNoZWNrQ1NTUHJvcGVydHlTdHJpbmdDb2VyY2lvbih2YWx1ZSwgbmFtZSk7XG4gIH1cblxuICByZXR1cm4gKCcnICsgdmFsdWUpLnRyaW0oKTtcbn1cblxudmFyIHVwcGVyY2FzZVBhdHRlcm4gPSAvKFtBLVpdKS9nO1xudmFyIG1zUGF0dGVybiA9IC9ebXMtLztcbi8qKlxuICogSHlwaGVuYXRlcyBhIGNhbWVsY2FzZWQgQ1NTIHByb3BlcnR5IG5hbWUsIGZvciBleGFtcGxlOlxuICpcbiAqICAgPiBoeXBoZW5hdGVTdHlsZU5hbWUoJ2JhY2tncm91bmRDb2xvcicpXG4gKiAgIDwgXCJiYWNrZ3JvdW5kLWNvbG9yXCJcbiAqICAgPiBoeXBoZW5hdGVTdHlsZU5hbWUoJ01velRyYW5zaXRpb24nKVxuICogICA8IFwiLW1vei10cmFuc2l0aW9uXCJcbiAqICAgPiBoeXBoZW5hdGVTdHlsZU5hbWUoJ21zVHJhbnNpdGlvbicpXG4gKiAgIDwgXCItbXMtdHJhbnNpdGlvblwiXG4gKlxuICogQXMgTW9kZXJuaXpyIHN1Z2dlc3RzIChodHRwOi8vbW9kZXJuaXpyLmNvbS9kb2NzLyNwcmVmaXhlZCksIGFuIGBtc2AgcHJlZml4XG4gKiBpcyBjb252ZXJ0ZWQgdG8gYC1tcy1gLlxuICovXG5cbmZ1bmN0aW9uIGh5cGhlbmF0ZVN0eWxlTmFtZShuYW1lKSB7XG4gIHJldHVybiBuYW1lLnJlcGxhY2UodXBwZXJjYXNlUGF0dGVybiwgJy0kMScpLnRvTG93ZXJDYXNlKCkucmVwbGFjZShtc1BhdHRlcm4sICctbXMtJyk7XG59XG5cbnZhciB3YXJuVmFsaWRTdHlsZSA9IGZ1bmN0aW9uICgpIHt9O1xuXG57XG4gIC8vICdtc1RyYW5zZm9ybScgaXMgY29ycmVjdCwgYnV0IHRoZSBvdGhlciBwcmVmaXhlcyBzaG91bGQgYmUgY2FwaXRhbGl6ZWRcbiAgdmFyIGJhZFZlbmRvcmVkU3R5bGVOYW1lUGF0dGVybiA9IC9eKD86d2Via2l0fG1venxvKVtBLVpdLztcbiAgdmFyIG1zUGF0dGVybiQxID0gL14tbXMtLztcbiAgdmFyIGh5cGhlblBhdHRlcm4gPSAvLSguKS9nOyAvLyBzdHlsZSB2YWx1ZXMgc2hvdWxkbid0IGNvbnRhaW4gYSBzZW1pY29sb25cblxuICB2YXIgYmFkU3R5bGVWYWx1ZVdpdGhTZW1pY29sb25QYXR0ZXJuID0gLztcXHMqJC87XG4gIHZhciB3YXJuZWRTdHlsZU5hbWVzID0ge307XG4gIHZhciB3YXJuZWRTdHlsZVZhbHVlcyA9IHt9O1xuICB2YXIgd2FybmVkRm9yTmFOVmFsdWUgPSBmYWxzZTtcbiAgdmFyIHdhcm5lZEZvckluZmluaXR5VmFsdWUgPSBmYWxzZTtcblxuICB2YXIgY2FtZWxpemUgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKGh5cGhlblBhdHRlcm4sIGZ1bmN0aW9uIChfLCBjaGFyYWN0ZXIpIHtcbiAgICAgIHJldHVybiBjaGFyYWN0ZXIudG9VcHBlckNhc2UoKTtcbiAgICB9KTtcbiAgfTtcblxuICB2YXIgd2Fybkh5cGhlbmF0ZWRTdHlsZU5hbWUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmICh3YXJuZWRTdHlsZU5hbWVzLmhhc093blByb3BlcnR5KG5hbWUpICYmIHdhcm5lZFN0eWxlTmFtZXNbbmFtZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3YXJuZWRTdHlsZU5hbWVzW25hbWVdID0gdHJ1ZTtcblxuICAgIGVycm9yKCdVbnN1cHBvcnRlZCBzdHlsZSBwcm9wZXJ0eSAlcy4gRGlkIHlvdSBtZWFuICVzPycsIG5hbWUsIC8vIEFzIEFuZGkgU21pdGggc3VnZ2VzdHNcbiAgICAvLyAoaHR0cDovL3d3dy5hbmRpc21pdGguY29tL2Jsb2cvMjAxMi8wMi9tb2Rlcm5penItcHJlZml4ZWQvKSwgYW4gYC1tc2AgcHJlZml4XG4gICAgLy8gaXMgY29udmVydGVkIHRvIGxvd2VyY2FzZSBgbXNgLlxuICAgIGNhbWVsaXplKG5hbWUucmVwbGFjZShtc1BhdHRlcm4kMSwgJ21zLScpKSk7XG4gIH07XG5cbiAgdmFyIHdhcm5CYWRWZW5kb3JlZFN0eWxlTmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKHdhcm5lZFN0eWxlTmFtZXMuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgd2FybmVkU3R5bGVOYW1lc1tuYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZFN0eWxlTmFtZXNbbmFtZV0gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ1Vuc3VwcG9ydGVkIHZlbmRvci1wcmVmaXhlZCBzdHlsZSBwcm9wZXJ0eSAlcy4gRGlkIHlvdSBtZWFuICVzPycsIG5hbWUsIG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpKTtcbiAgfTtcblxuICB2YXIgd2FyblN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKHdhcm5lZFN0eWxlVmFsdWVzLmhhc093blByb3BlcnR5KHZhbHVlKSAmJiB3YXJuZWRTdHlsZVZhbHVlc1t2YWx1ZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3YXJuZWRTdHlsZVZhbHVlc1t2YWx1ZV0gPSB0cnVlO1xuXG4gICAgZXJyb3IoXCJTdHlsZSBwcm9wZXJ0eSB2YWx1ZXMgc2hvdWxkbid0IGNvbnRhaW4gYSBzZW1pY29sb24uIFwiICsgJ1RyeSBcIiVzOiAlc1wiIGluc3RlYWQuJywgbmFtZSwgdmFsdWUucmVwbGFjZShiYWRTdHlsZVZhbHVlV2l0aFNlbWljb2xvblBhdHRlcm4sICcnKSk7XG4gIH07XG5cbiAgdmFyIHdhcm5TdHlsZVZhbHVlSXNOYU4gPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICBpZiAod2FybmVkRm9yTmFOVmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3YXJuZWRGb3JOYU5WYWx1ZSA9IHRydWU7XG5cbiAgICBlcnJvcignYE5hTmAgaXMgYW4gaW52YWxpZCB2YWx1ZSBmb3IgdGhlIGAlc2AgY3NzIHN0eWxlIHByb3BlcnR5LicsIG5hbWUpO1xuICB9O1xuXG4gIHZhciB3YXJuU3R5bGVWYWx1ZUlzSW5maW5pdHkgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICBpZiAod2FybmVkRm9ySW5maW5pdHlWYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZEZvckluZmluaXR5VmFsdWUgPSB0cnVlO1xuXG4gICAgZXJyb3IoJ2BJbmZpbml0eWAgaXMgYW4gaW52YWxpZCB2YWx1ZSBmb3IgdGhlIGAlc2AgY3NzIHN0eWxlIHByb3BlcnR5LicsIG5hbWUpO1xuICB9O1xuXG4gIHdhcm5WYWxpZFN0eWxlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKG5hbWUuaW5kZXhPZignLScpID4gLTEpIHtcbiAgICAgIHdhcm5IeXBoZW5hdGVkU3R5bGVOYW1lKG5hbWUpO1xuICAgIH0gZWxzZSBpZiAoYmFkVmVuZG9yZWRTdHlsZU5hbWVQYXR0ZXJuLnRlc3QobmFtZSkpIHtcbiAgICAgIHdhcm5CYWRWZW5kb3JlZFN0eWxlTmFtZShuYW1lKTtcbiAgICB9IGVsc2UgaWYgKGJhZFN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uUGF0dGVybi50ZXN0KHZhbHVlKSkge1xuICAgICAgd2FyblN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uKG5hbWUsIHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKGlzTmFOKHZhbHVlKSkge1xuICAgICAgICB3YXJuU3R5bGVWYWx1ZUlzTmFOKG5hbWUsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzRmluaXRlKHZhbHVlKSkge1xuICAgICAgICB3YXJuU3R5bGVWYWx1ZUlzSW5maW5pdHkobmFtZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxudmFyIHdhcm5WYWxpZFN0eWxlJDEgPSB3YXJuVmFsaWRTdHlsZTtcblxuLyoqXG4gKiBPcGVyYXRpb25zIGZvciBkZWFsaW5nIHdpdGggQ1NTIHByb3BlcnRpZXMuXG4gKi9cblxuLyoqXG4gKiBUaGlzIGNyZWF0ZXMgYSBzdHJpbmcgdGhhdCBpcyBleHBlY3RlZCB0byBiZSBlcXVpdmFsZW50IHRvIHRoZSBzdHlsZVxuICogYXR0cmlidXRlIGdlbmVyYXRlZCBieSBzZXJ2ZXItc2lkZSByZW5kZXJpbmcuIEl0IGJ5LXBhc3NlcyB3YXJuaW5ncyBhbmRcbiAqIHNlY3VyaXR5IGNoZWNrcyBzbyBpdCdzIG5vdCBzYWZlIHRvIHVzZSB0aGlzIHZhbHVlIGZvciBhbnl0aGluZyBvdGhlciB0aGFuXG4gKiBjb21wYXJpc29uLiBJdCBpcyBvbmx5IHVzZWQgaW4gREVWIGZvciBTU1IgdmFsaWRhdGlvbi5cbiAqL1xuXG5mdW5jdGlvbiBjcmVhdGVEYW5nZXJvdXNTdHJpbmdGb3JTdHlsZXMoc3R5bGVzKSB7XG4gIHtcbiAgICB2YXIgc2VyaWFsaXplZCA9ICcnO1xuICAgIHZhciBkZWxpbWl0ZXIgPSAnJztcblxuICAgIGZvciAodmFyIHN0eWxlTmFtZSBpbiBzdHlsZXMpIHtcbiAgICAgIGlmICghc3R5bGVzLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBzdHlsZVZhbHVlID0gc3R5bGVzW3N0eWxlTmFtZV07XG5cbiAgICAgIGlmIChzdHlsZVZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgdmFyIGlzQ3VzdG9tUHJvcGVydHkgPSBzdHlsZU5hbWUuaW5kZXhPZignLS0nKSA9PT0gMDtcbiAgICAgICAgc2VyaWFsaXplZCArPSBkZWxpbWl0ZXIgKyAoaXNDdXN0b21Qcm9wZXJ0eSA/IHN0eWxlTmFtZSA6IGh5cGhlbmF0ZVN0eWxlTmFtZShzdHlsZU5hbWUpKSArICc6JztcbiAgICAgICAgc2VyaWFsaXplZCArPSBkYW5nZXJvdXNTdHlsZVZhbHVlKHN0eWxlTmFtZSwgc3R5bGVWYWx1ZSwgaXNDdXN0b21Qcm9wZXJ0eSk7XG4gICAgICAgIGRlbGltaXRlciA9ICc7JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWFsaXplZCB8fCBudWxsO1xuICB9XG59XG4vKipcbiAqIFNldHMgdGhlIHZhbHVlIGZvciBtdWx0aXBsZSBzdHlsZXMgb24gYSBub2RlLiAgSWYgYSB2YWx1ZSBpcyBzcGVjaWZpZWQgYXNcbiAqICcnIChlbXB0eSBzdHJpbmcpLCB0aGUgY29ycmVzcG9uZGluZyBzdHlsZSBwcm9wZXJ0eSB3aWxsIGJlIHVuc2V0LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICogQHBhcmFtIHtvYmplY3R9IHN0eWxlc1xuICovXG5cbmZ1bmN0aW9uIHNldFZhbHVlRm9yU3R5bGVzKG5vZGUsIHN0eWxlcykge1xuICB2YXIgc3R5bGUgPSBub2RlLnN0eWxlO1xuXG4gIGZvciAodmFyIHN0eWxlTmFtZSBpbiBzdHlsZXMpIHtcbiAgICBpZiAoIXN0eWxlcy5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB2YXIgaXNDdXN0b21Qcm9wZXJ0eSA9IHN0eWxlTmFtZS5pbmRleE9mKCctLScpID09PSAwO1xuXG4gICAge1xuICAgICAgaWYgKCFpc0N1c3RvbVByb3BlcnR5KSB7XG4gICAgICAgIHdhcm5WYWxpZFN0eWxlJDEoc3R5bGVOYW1lLCBzdHlsZXNbc3R5bGVOYW1lXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHN0eWxlVmFsdWUgPSBkYW5nZXJvdXNTdHlsZVZhbHVlKHN0eWxlTmFtZSwgc3R5bGVzW3N0eWxlTmFtZV0sIGlzQ3VzdG9tUHJvcGVydHkpO1xuXG4gICAgaWYgKHN0eWxlTmFtZSA9PT0gJ2Zsb2F0Jykge1xuICAgICAgc3R5bGVOYW1lID0gJ2Nzc0Zsb2F0JztcbiAgICB9XG5cbiAgICBpZiAoaXNDdXN0b21Qcm9wZXJ0eSkge1xuICAgICAgc3R5bGUuc2V0UHJvcGVydHkoc3R5bGVOYW1lLCBzdHlsZVZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGVbc3R5bGVOYW1lXSA9IHN0eWxlVmFsdWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzVmFsdWVFbXB0eSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyB8fCB2YWx1ZSA9PT0gJyc7XG59XG4vKipcbiAqIEdpdmVuIHtjb2xvcjogJ3JlZCcsIG92ZXJmbG93OiAnaGlkZGVuJ30gcmV0dXJucyB7XG4gKiAgIGNvbG9yOiAnY29sb3InLFxuICogICBvdmVyZmxvd1g6ICdvdmVyZmxvdycsXG4gKiAgIG92ZXJmbG93WTogJ292ZXJmbG93JyxcbiAqIH0uIFRoaXMgY2FuIGJlIHJlYWQgYXMgXCJ0aGUgb3ZlcmZsb3dZIHByb3BlcnR5IHdhcyBzZXQgYnkgdGhlIG92ZXJmbG93XG4gKiBzaG9ydGhhbmRcIi4gVGhhdCBpcywgdGhlIHZhbHVlcyBhcmUgdGhlIHByb3BlcnR5IHRoYXQgZWFjaCB3YXMgZGVyaXZlZCBmcm9tLlxuICovXG5cblxuZnVuY3Rpb24gZXhwYW5kU2hvcnRoYW5kTWFwKHN0eWxlcykge1xuICB2YXIgZXhwYW5kZWQgPSB7fTtcblxuICBmb3IgKHZhciBrZXkgaW4gc3R5bGVzKSB7XG4gICAgdmFyIGxvbmdoYW5kcyA9IHNob3J0aGFuZFRvTG9uZ2hhbmRba2V5XSB8fCBba2V5XTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbG9uZ2hhbmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBleHBhbmRlZFtsb25naGFuZHNbaV1dID0ga2V5O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBhbmRlZDtcbn1cbi8qKlxuICogV2hlbiBtaXhpbmcgc2hvcnRoYW5kIGFuZCBsb25naGFuZCBwcm9wZXJ0eSBuYW1lcywgd2Ugd2FybiBkdXJpbmcgdXBkYXRlcyBpZlxuICogd2UgZXhwZWN0IGFuIGluY29ycmVjdCByZXN1bHQgdG8gb2NjdXIuIEluIHBhcnRpY3VsYXIsIHdlIHdhcm4gZm9yOlxuICpcbiAqIFVwZGF0aW5nIGEgc2hvcnRoYW5kIHByb3BlcnR5IChsb25naGFuZCBnZXRzIG92ZXJ3cml0dGVuKTpcbiAqICAge2ZvbnQ6ICdmb28nLCBmb250VmFyaWFudDogJ2Jhcid9IC0+IHtmb250OiAnYmF6JywgZm9udFZhcmlhbnQ6ICdiYXInfVxuICogICBiZWNvbWVzIC5zdHlsZS5mb250ID0gJ2JheidcbiAqIFJlbW92aW5nIGEgc2hvcnRoYW5kIHByb3BlcnR5IChsb25naGFuZCBnZXRzIGxvc3QgdG9vKTpcbiAqICAge2ZvbnQ6ICdmb28nLCBmb250VmFyaWFudDogJ2Jhcid9IC0+IHtmb250VmFyaWFudDogJ2Jhcid9XG4gKiAgIGJlY29tZXMgLnN0eWxlLmZvbnQgPSAnJ1xuICogUmVtb3ZpbmcgYSBsb25naGFuZCBwcm9wZXJ0eSAoc2hvdWxkIHJldmVydCB0byBzaG9ydGhhbmQ7IGRvZXNuJ3QpOlxuICogICB7Zm9udDogJ2ZvbycsIGZvbnRWYXJpYW50OiAnYmFyJ30gLT4ge2ZvbnQ6ICdmb28nfVxuICogICBiZWNvbWVzIC5zdHlsZS5mb250VmFyaWFudCA9ICcnXG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZVNob3J0aGFuZFByb3BlcnR5Q29sbGlzaW9uSW5EZXYoc3R5bGVVcGRhdGVzLCBuZXh0U3R5bGVzKSB7XG4gIHtcbiAgICBpZiAoIW5leHRTdHlsZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZXhwYW5kZWRVcGRhdGVzID0gZXhwYW5kU2hvcnRoYW5kTWFwKHN0eWxlVXBkYXRlcyk7XG4gICAgdmFyIGV4cGFuZGVkU3R5bGVzID0gZXhwYW5kU2hvcnRoYW5kTWFwKG5leHRTdHlsZXMpO1xuICAgIHZhciB3YXJuZWRBYm91dCA9IHt9O1xuXG4gICAgZm9yICh2YXIga2V5IGluIGV4cGFuZGVkVXBkYXRlcykge1xuICAgICAgdmFyIG9yaWdpbmFsS2V5ID0gZXhwYW5kZWRVcGRhdGVzW2tleV07XG4gICAgICB2YXIgY29ycmVjdE9yaWdpbmFsS2V5ID0gZXhwYW5kZWRTdHlsZXNba2V5XTtcblxuICAgICAgaWYgKGNvcnJlY3RPcmlnaW5hbEtleSAmJiBvcmlnaW5hbEtleSAhPT0gY29ycmVjdE9yaWdpbmFsS2V5KSB7XG4gICAgICAgIHZhciB3YXJuaW5nS2V5ID0gb3JpZ2luYWxLZXkgKyAnLCcgKyBjb3JyZWN0T3JpZ2luYWxLZXk7XG5cbiAgICAgICAgaWYgKHdhcm5lZEFib3V0W3dhcm5pbmdLZXldKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB3YXJuZWRBYm91dFt3YXJuaW5nS2V5XSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJyVzIGEgc3R5bGUgcHJvcGVydHkgZHVyaW5nIHJlcmVuZGVyICglcykgd2hlbiBhICcgKyAnY29uZmxpY3RpbmcgcHJvcGVydHkgaXMgc2V0ICglcykgY2FuIGxlYWQgdG8gc3R5bGluZyBidWdzLiBUbyAnICsgXCJhdm9pZCB0aGlzLCBkb24ndCBtaXggc2hvcnRoYW5kIGFuZCBub24tc2hvcnRoYW5kIHByb3BlcnRpZXMgXCIgKyAnZm9yIHRoZSBzYW1lIHZhbHVlOyBpbnN0ZWFkLCByZXBsYWNlIHRoZSBzaG9ydGhhbmQgd2l0aCAnICsgJ3NlcGFyYXRlIHZhbHVlcy4nLCBpc1ZhbHVlRW1wdHkoc3R5bGVVcGRhdGVzW29yaWdpbmFsS2V5XSkgPyAnUmVtb3ZpbmcnIDogJ1VwZGF0aW5nJywgb3JpZ2luYWxLZXksIGNvcnJlY3RPcmlnaW5hbEtleSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEZvciBIVE1MLCBjZXJ0YWluIHRhZ3Mgc2hvdWxkIG9taXQgdGhlaXIgY2xvc2UgdGFnLiBXZSBrZWVwIGEgbGlzdCBmb3Jcbi8vIHRob3NlIHNwZWNpYWwtY2FzZSB0YWdzLlxudmFyIG9taXR0ZWRDbG9zZVRhZ3MgPSB7XG4gIGFyZWE6IHRydWUsXG4gIGJhc2U6IHRydWUsXG4gIGJyOiB0cnVlLFxuICBjb2w6IHRydWUsXG4gIGVtYmVkOiB0cnVlLFxuICBocjogdHJ1ZSxcbiAgaW1nOiB0cnVlLFxuICBpbnB1dDogdHJ1ZSxcbiAga2V5Z2VuOiB0cnVlLFxuICBsaW5rOiB0cnVlLFxuICBtZXRhOiB0cnVlLFxuICBwYXJhbTogdHJ1ZSxcbiAgc291cmNlOiB0cnVlLFxuICB0cmFjazogdHJ1ZSxcbiAgd2JyOiB0cnVlIC8vIE5PVEU6IG1lbnVpdGVtJ3MgY2xvc2UgdGFnIHNob3VsZCBiZSBvbWl0dGVkLCBidXQgdGhhdCBjYXVzZXMgcHJvYmxlbXMuXG5cbn07XG5cbi8vIGBvbWl0dGVkQ2xvc2VUYWdzYCBleGNlcHQgdGhhdCBgbWVudWl0ZW1gIHNob3VsZCBzdGlsbCBoYXZlIGl0cyBjbG9zaW5nIHRhZy5cblxudmFyIHZvaWRFbGVtZW50VGFncyA9IGFzc2lnbih7XG4gIG1lbnVpdGVtOiB0cnVlXG59LCBvbWl0dGVkQ2xvc2VUYWdzKTtcblxudmFyIEhUTUwgPSAnX19odG1sJztcblxuZnVuY3Rpb24gYXNzZXJ0VmFsaWRQcm9wcyh0YWcsIHByb3BzKSB7XG4gIGlmICghcHJvcHMpIHtcbiAgICByZXR1cm47XG4gIH0gLy8gTm90ZSB0aGUgdXNlIG9mIGA9PWAgd2hpY2ggY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZC5cblxuXG4gIGlmICh2b2lkRWxlbWVudFRhZ3NbdGFnXSkge1xuICAgIGlmIChwcm9wcy5jaGlsZHJlbiAhPSBudWxsIHx8IHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0YWcgKyBcIiBpcyBhIHZvaWQgZWxlbWVudCB0YWcgYW5kIG11c3QgbmVpdGhlciBoYXZlIGBjaGlsZHJlbmAgbm9yIFwiICsgJ3VzZSBgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUxgLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCAhPSBudWxsKSB7XG4gICAgaWYgKHByb3BzLmNoaWxkcmVuICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG9ubHkgc2V0IG9uZSBvZiBgY2hpbGRyZW5gIG9yIGBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTGAuJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCAhPT0gJ29iamVjdCcgfHwgIShIVE1MIGluIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUxgIG11c3QgYmUgaW4gdGhlIGZvcm0gYHtfX2h0bWw6IC4uLn1gLiAnICsgJ1BsZWFzZSB2aXNpdCBodHRwczovL3JlYWN0anMub3JnL2xpbmsvZGFuZ2Vyb3VzbHktc2V0LWlubmVyLWh0bWwgJyArICdmb3IgbW9yZSBpbmZvcm1hdGlvbi4nKTtcbiAgICB9XG4gIH1cblxuICB7XG4gICAgaWYgKCFwcm9wcy5zdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmcgJiYgcHJvcHMuY29udGVudEVkaXRhYmxlICYmIHByb3BzLmNoaWxkcmVuICE9IG51bGwpIHtcbiAgICAgIGVycm9yKCdBIGNvbXBvbmVudCBpcyBgY29udGVudEVkaXRhYmxlYCBhbmQgY29udGFpbnMgYGNoaWxkcmVuYCBtYW5hZ2VkIGJ5ICcgKyAnUmVhY3QuIEl0IGlzIG5vdyB5b3VyIHJlc3BvbnNpYmlsaXR5IHRvIGd1YXJhbnRlZSB0aGF0IG5vbmUgb2YgJyArICd0aG9zZSBub2RlcyBhcmUgdW5leHBlY3RlZGx5IG1vZGlmaWVkIG9yIGR1cGxpY2F0ZWQuIFRoaXMgaXMgJyArICdwcm9iYWJseSBub3QgaW50ZW50aW9uYWwuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHByb3BzLnN0eWxlICE9IG51bGwgJiYgdHlwZW9mIHByb3BzLnN0eWxlICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGBzdHlsZWAgcHJvcCBleHBlY3RzIGEgbWFwcGluZyBmcm9tIHN0eWxlIHByb3BlcnRpZXMgdG8gdmFsdWVzLCAnICsgXCJub3QgYSBzdHJpbmcuIEZvciBleGFtcGxlLCBzdHlsZT17e21hcmdpblJpZ2h0OiBzcGFjaW5nICsgJ2VtJ319IHdoZW4gXCIgKyAndXNpbmcgSlNYLicpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ3VzdG9tQ29tcG9uZW50KHRhZ05hbWUsIHByb3BzKSB7XG4gIGlmICh0YWdOYW1lLmluZGV4T2YoJy0nKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gdHlwZW9mIHByb3BzLmlzID09PSAnc3RyaW5nJztcbiAgfVxuXG4gIHN3aXRjaCAodGFnTmFtZSkge1xuICAgIC8vIFRoZXNlIGFyZSByZXNlcnZlZCBTVkcgYW5kIE1hdGhNTCBlbGVtZW50cy5cbiAgICAvLyBXZSBkb24ndCBtaW5kIHRoaXMgbGlzdCB0b28gbXVjaCBiZWNhdXNlIHdlIGV4cGVjdCBpdCB0byBuZXZlciBncm93LlxuICAgIC8vIFRoZSBhbHRlcm5hdGl2ZSBpcyB0byB0cmFjayB0aGUgbmFtZXNwYWNlIGluIGEgZmV3IHBsYWNlcyB3aGljaCBpcyBjb252b2x1dGVkLlxuICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJjb21wb25lbnRzL3NwZWMvY3VzdG9tLyNjdXN0b20tZWxlbWVudHMtY29yZS1jb25jZXB0c1xuICAgIGNhc2UgJ2Fubm90YXRpb24teG1sJzpcbiAgICBjYXNlICdjb2xvci1wcm9maWxlJzpcbiAgICBjYXNlICdmb250LWZhY2UnOlxuICAgIGNhc2UgJ2ZvbnQtZmFjZS1zcmMnOlxuICAgIGNhc2UgJ2ZvbnQtZmFjZS11cmknOlxuICAgIGNhc2UgJ2ZvbnQtZmFjZS1mb3JtYXQnOlxuICAgIGNhc2UgJ2ZvbnQtZmFjZS1uYW1lJzpcbiAgICBjYXNlICdtaXNzaW5nLWdseXBoJzpcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vLyBXaGVuIGFkZGluZyBhdHRyaWJ1dGVzIHRvIHRoZSBIVE1MIG9yIFNWRyBhbGxvd2VkIGF0dHJpYnV0ZSBsaXN0LCBiZSBzdXJlIHRvXG4vLyBhbHNvIGFkZCB0aGVtIHRvIHRoaXMgbW9kdWxlIHRvIGVuc3VyZSBjYXNpbmcgYW5kIGluY29ycmVjdCBuYW1lXG4vLyB3YXJuaW5ncy5cbnZhciBwb3NzaWJsZVN0YW5kYXJkTmFtZXMgPSB7XG4gIC8vIEhUTUxcbiAgYWNjZXB0OiAnYWNjZXB0JyxcbiAgYWNjZXB0Y2hhcnNldDogJ2FjY2VwdENoYXJzZXQnLFxuICAnYWNjZXB0LWNoYXJzZXQnOiAnYWNjZXB0Q2hhcnNldCcsXG4gIGFjY2Vzc2tleTogJ2FjY2Vzc0tleScsXG4gIGFjdGlvbjogJ2FjdGlvbicsXG4gIGFsbG93ZnVsbHNjcmVlbjogJ2FsbG93RnVsbFNjcmVlbicsXG4gIGFsdDogJ2FsdCcsXG4gIGFzOiAnYXMnLFxuICBhc3luYzogJ2FzeW5jJyxcbiAgYXV0b2NhcGl0YWxpemU6ICdhdXRvQ2FwaXRhbGl6ZScsXG4gIGF1dG9jb21wbGV0ZTogJ2F1dG9Db21wbGV0ZScsXG4gIGF1dG9jb3JyZWN0OiAnYXV0b0NvcnJlY3QnLFxuICBhdXRvZm9jdXM6ICdhdXRvRm9jdXMnLFxuICBhdXRvcGxheTogJ2F1dG9QbGF5JyxcbiAgYXV0b3NhdmU6ICdhdXRvU2F2ZScsXG4gIGNhcHR1cmU6ICdjYXB0dXJlJyxcbiAgY2VsbHBhZGRpbmc6ICdjZWxsUGFkZGluZycsXG4gIGNlbGxzcGFjaW5nOiAnY2VsbFNwYWNpbmcnLFxuICBjaGFsbGVuZ2U6ICdjaGFsbGVuZ2UnLFxuICBjaGFyc2V0OiAnY2hhclNldCcsXG4gIGNoZWNrZWQ6ICdjaGVja2VkJyxcbiAgY2hpbGRyZW46ICdjaGlsZHJlbicsXG4gIGNpdGU6ICdjaXRlJyxcbiAgY2xhc3M6ICdjbGFzc05hbWUnLFxuICBjbGFzc2lkOiAnY2xhc3NJRCcsXG4gIGNsYXNzbmFtZTogJ2NsYXNzTmFtZScsXG4gIGNvbHM6ICdjb2xzJyxcbiAgY29sc3BhbjogJ2NvbFNwYW4nLFxuICBjb250ZW50OiAnY29udGVudCcsXG4gIGNvbnRlbnRlZGl0YWJsZTogJ2NvbnRlbnRFZGl0YWJsZScsXG4gIGNvbnRleHRtZW51OiAnY29udGV4dE1lbnUnLFxuICBjb250cm9sczogJ2NvbnRyb2xzJyxcbiAgY29udHJvbHNsaXN0OiAnY29udHJvbHNMaXN0JyxcbiAgY29vcmRzOiAnY29vcmRzJyxcbiAgY3Jvc3NvcmlnaW46ICdjcm9zc09yaWdpbicsXG4gIGRhbmdlcm91c2x5c2V0aW5uZXJodG1sOiAnZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwnLFxuICBkYXRhOiAnZGF0YScsXG4gIGRhdGV0aW1lOiAnZGF0ZVRpbWUnLFxuICBkZWZhdWx0OiAnZGVmYXVsdCcsXG4gIGRlZmF1bHRjaGVja2VkOiAnZGVmYXVsdENoZWNrZWQnLFxuICBkZWZhdWx0dmFsdWU6ICdkZWZhdWx0VmFsdWUnLFxuICBkZWZlcjogJ2RlZmVyJyxcbiAgZGlyOiAnZGlyJyxcbiAgZGlzYWJsZWQ6ICdkaXNhYmxlZCcsXG4gIGRpc2FibGVwaWN0dXJlaW5waWN0dXJlOiAnZGlzYWJsZVBpY3R1cmVJblBpY3R1cmUnLFxuICBkaXNhYmxlcmVtb3RlcGxheWJhY2s6ICdkaXNhYmxlUmVtb3RlUGxheWJhY2snLFxuICBkb3dubG9hZDogJ2Rvd25sb2FkJyxcbiAgZHJhZ2dhYmxlOiAnZHJhZ2dhYmxlJyxcbiAgZW5jdHlwZTogJ2VuY1R5cGUnLFxuICBlbnRlcmtleWhpbnQ6ICdlbnRlcktleUhpbnQnLFxuICBmb3I6ICdodG1sRm9yJyxcbiAgZm9ybTogJ2Zvcm0nLFxuICBmb3JtbWV0aG9kOiAnZm9ybU1ldGhvZCcsXG4gIGZvcm1hY3Rpb246ICdmb3JtQWN0aW9uJyxcbiAgZm9ybWVuY3R5cGU6ICdmb3JtRW5jVHlwZScsXG4gIGZvcm1ub3ZhbGlkYXRlOiAnZm9ybU5vVmFsaWRhdGUnLFxuICBmb3JtdGFyZ2V0OiAnZm9ybVRhcmdldCcsXG4gIGZyYW1lYm9yZGVyOiAnZnJhbWVCb3JkZXInLFxuICBoZWFkZXJzOiAnaGVhZGVycycsXG4gIGhlaWdodDogJ2hlaWdodCcsXG4gIGhpZGRlbjogJ2hpZGRlbicsXG4gIGhpZ2g6ICdoaWdoJyxcbiAgaHJlZjogJ2hyZWYnLFxuICBocmVmbGFuZzogJ2hyZWZMYW5nJyxcbiAgaHRtbGZvcjogJ2h0bWxGb3InLFxuICBodHRwZXF1aXY6ICdodHRwRXF1aXYnLFxuICAnaHR0cC1lcXVpdic6ICdodHRwRXF1aXYnLFxuICBpY29uOiAnaWNvbicsXG4gIGlkOiAnaWQnLFxuICBpbWFnZXNpemVzOiAnaW1hZ2VTaXplcycsXG4gIGltYWdlc3Jjc2V0OiAnaW1hZ2VTcmNTZXQnLFxuICBpbm5lcmh0bWw6ICdpbm5lckhUTUwnLFxuICBpbnB1dG1vZGU6ICdpbnB1dE1vZGUnLFxuICBpbnRlZ3JpdHk6ICdpbnRlZ3JpdHknLFxuICBpczogJ2lzJyxcbiAgaXRlbWlkOiAnaXRlbUlEJyxcbiAgaXRlbXByb3A6ICdpdGVtUHJvcCcsXG4gIGl0ZW1yZWY6ICdpdGVtUmVmJyxcbiAgaXRlbXNjb3BlOiAnaXRlbVNjb3BlJyxcbiAgaXRlbXR5cGU6ICdpdGVtVHlwZScsXG4gIGtleXBhcmFtczogJ2tleVBhcmFtcycsXG4gIGtleXR5cGU6ICdrZXlUeXBlJyxcbiAga2luZDogJ2tpbmQnLFxuICBsYWJlbDogJ2xhYmVsJyxcbiAgbGFuZzogJ2xhbmcnLFxuICBsaXN0OiAnbGlzdCcsXG4gIGxvb3A6ICdsb29wJyxcbiAgbG93OiAnbG93JyxcbiAgbWFuaWZlc3Q6ICdtYW5pZmVzdCcsXG4gIG1hcmdpbndpZHRoOiAnbWFyZ2luV2lkdGgnLFxuICBtYXJnaW5oZWlnaHQ6ICdtYXJnaW5IZWlnaHQnLFxuICBtYXg6ICdtYXgnLFxuICBtYXhsZW5ndGg6ICdtYXhMZW5ndGgnLFxuICBtZWRpYTogJ21lZGlhJyxcbiAgbWVkaWFncm91cDogJ21lZGlhR3JvdXAnLFxuICBtZXRob2Q6ICdtZXRob2QnLFxuICBtaW46ICdtaW4nLFxuICBtaW5sZW5ndGg6ICdtaW5MZW5ndGgnLFxuICBtdWx0aXBsZTogJ211bHRpcGxlJyxcbiAgbXV0ZWQ6ICdtdXRlZCcsXG4gIG5hbWU6ICduYW1lJyxcbiAgbm9tb2R1bGU6ICdub01vZHVsZScsXG4gIG5vbmNlOiAnbm9uY2UnLFxuICBub3ZhbGlkYXRlOiAnbm9WYWxpZGF0ZScsXG4gIG9wZW46ICdvcGVuJyxcbiAgb3B0aW11bTogJ29wdGltdW0nLFxuICBwYXR0ZXJuOiAncGF0dGVybicsXG4gIHBsYWNlaG9sZGVyOiAncGxhY2Vob2xkZXInLFxuICBwbGF5c2lubGluZTogJ3BsYXlzSW5saW5lJyxcbiAgcG9zdGVyOiAncG9zdGVyJyxcbiAgcHJlbG9hZDogJ3ByZWxvYWQnLFxuICBwcm9maWxlOiAncHJvZmlsZScsXG4gIHJhZGlvZ3JvdXA6ICdyYWRpb0dyb3VwJyxcbiAgcmVhZG9ubHk6ICdyZWFkT25seScsXG4gIHJlZmVycmVycG9saWN5OiAncmVmZXJyZXJQb2xpY3knLFxuICByZWw6ICdyZWwnLFxuICByZXF1aXJlZDogJ3JlcXVpcmVkJyxcbiAgcmV2ZXJzZWQ6ICdyZXZlcnNlZCcsXG4gIHJvbGU6ICdyb2xlJyxcbiAgcm93czogJ3Jvd3MnLFxuICByb3dzcGFuOiAncm93U3BhbicsXG4gIHNhbmRib3g6ICdzYW5kYm94JyxcbiAgc2NvcGU6ICdzY29wZScsXG4gIHNjb3BlZDogJ3Njb3BlZCcsXG4gIHNjcm9sbGluZzogJ3Njcm9sbGluZycsXG4gIHNlYW1sZXNzOiAnc2VhbWxlc3MnLFxuICBzZWxlY3RlZDogJ3NlbGVjdGVkJyxcbiAgc2hhcGU6ICdzaGFwZScsXG4gIHNpemU6ICdzaXplJyxcbiAgc2l6ZXM6ICdzaXplcycsXG4gIHNwYW46ICdzcGFuJyxcbiAgc3BlbGxjaGVjazogJ3NwZWxsQ2hlY2snLFxuICBzcmM6ICdzcmMnLFxuICBzcmNkb2M6ICdzcmNEb2MnLFxuICBzcmNsYW5nOiAnc3JjTGFuZycsXG4gIHNyY3NldDogJ3NyY1NldCcsXG4gIHN0YXJ0OiAnc3RhcnQnLFxuICBzdGVwOiAnc3RlcCcsXG4gIHN0eWxlOiAnc3R5bGUnLFxuICBzdW1tYXJ5OiAnc3VtbWFyeScsXG4gIHRhYmluZGV4OiAndGFiSW5kZXgnLFxuICB0YXJnZXQ6ICd0YXJnZXQnLFxuICB0aXRsZTogJ3RpdGxlJyxcbiAgdHlwZTogJ3R5cGUnLFxuICB1c2VtYXA6ICd1c2VNYXAnLFxuICB2YWx1ZTogJ3ZhbHVlJyxcbiAgd2lkdGg6ICd3aWR0aCcsXG4gIHdtb2RlOiAnd21vZGUnLFxuICB3cmFwOiAnd3JhcCcsXG4gIC8vIFNWR1xuICBhYm91dDogJ2Fib3V0JyxcbiAgYWNjZW50aGVpZ2h0OiAnYWNjZW50SGVpZ2h0JyxcbiAgJ2FjY2VudC1oZWlnaHQnOiAnYWNjZW50SGVpZ2h0JyxcbiAgYWNjdW11bGF0ZTogJ2FjY3VtdWxhdGUnLFxuICBhZGRpdGl2ZTogJ2FkZGl0aXZlJyxcbiAgYWxpZ25tZW50YmFzZWxpbmU6ICdhbGlnbm1lbnRCYXNlbGluZScsXG4gICdhbGlnbm1lbnQtYmFzZWxpbmUnOiAnYWxpZ25tZW50QmFzZWxpbmUnLFxuICBhbGxvd3Jlb3JkZXI6ICdhbGxvd1Jlb3JkZXInLFxuICBhbHBoYWJldGljOiAnYWxwaGFiZXRpYycsXG4gIGFtcGxpdHVkZTogJ2FtcGxpdHVkZScsXG4gIGFyYWJpY2Zvcm06ICdhcmFiaWNGb3JtJyxcbiAgJ2FyYWJpYy1mb3JtJzogJ2FyYWJpY0Zvcm0nLFxuICBhc2NlbnQ6ICdhc2NlbnQnLFxuICBhdHRyaWJ1dGVuYW1lOiAnYXR0cmlidXRlTmFtZScsXG4gIGF0dHJpYnV0ZXR5cGU6ICdhdHRyaWJ1dGVUeXBlJyxcbiAgYXV0b3JldmVyc2U6ICdhdXRvUmV2ZXJzZScsXG4gIGF6aW11dGg6ICdhemltdXRoJyxcbiAgYmFzZWZyZXF1ZW5jeTogJ2Jhc2VGcmVxdWVuY3knLFxuICBiYXNlbGluZXNoaWZ0OiAnYmFzZWxpbmVTaGlmdCcsXG4gICdiYXNlbGluZS1zaGlmdCc6ICdiYXNlbGluZVNoaWZ0JyxcbiAgYmFzZXByb2ZpbGU6ICdiYXNlUHJvZmlsZScsXG4gIGJib3g6ICdiYm94JyxcbiAgYmVnaW46ICdiZWdpbicsXG4gIGJpYXM6ICdiaWFzJyxcbiAgYnk6ICdieScsXG4gIGNhbGNtb2RlOiAnY2FsY01vZGUnLFxuICBjYXBoZWlnaHQ6ICdjYXBIZWlnaHQnLFxuICAnY2FwLWhlaWdodCc6ICdjYXBIZWlnaHQnLFxuICBjbGlwOiAnY2xpcCcsXG4gIGNsaXBwYXRoOiAnY2xpcFBhdGgnLFxuICAnY2xpcC1wYXRoJzogJ2NsaXBQYXRoJyxcbiAgY2xpcHBhdGh1bml0czogJ2NsaXBQYXRoVW5pdHMnLFxuICBjbGlwcnVsZTogJ2NsaXBSdWxlJyxcbiAgJ2NsaXAtcnVsZSc6ICdjbGlwUnVsZScsXG4gIGNvbG9yOiAnY29sb3InLFxuICBjb2xvcmludGVycG9sYXRpb246ICdjb2xvckludGVycG9sYXRpb24nLFxuICAnY29sb3ItaW50ZXJwb2xhdGlvbic6ICdjb2xvckludGVycG9sYXRpb24nLFxuICBjb2xvcmludGVycG9sYXRpb25maWx0ZXJzOiAnY29sb3JJbnRlcnBvbGF0aW9uRmlsdGVycycsXG4gICdjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnMnOiAnY29sb3JJbnRlcnBvbGF0aW9uRmlsdGVycycsXG4gIGNvbG9ycHJvZmlsZTogJ2NvbG9yUHJvZmlsZScsXG4gICdjb2xvci1wcm9maWxlJzogJ2NvbG9yUHJvZmlsZScsXG4gIGNvbG9ycmVuZGVyaW5nOiAnY29sb3JSZW5kZXJpbmcnLFxuICAnY29sb3ItcmVuZGVyaW5nJzogJ2NvbG9yUmVuZGVyaW5nJyxcbiAgY29udGVudHNjcmlwdHR5cGU6ICdjb250ZW50U2NyaXB0VHlwZScsXG4gIGNvbnRlbnRzdHlsZXR5cGU6ICdjb250ZW50U3R5bGVUeXBlJyxcbiAgY3Vyc29yOiAnY3Vyc29yJyxcbiAgY3g6ICdjeCcsXG4gIGN5OiAnY3knLFxuICBkOiAnZCcsXG4gIGRhdGF0eXBlOiAnZGF0YXR5cGUnLFxuICBkZWNlbGVyYXRlOiAnZGVjZWxlcmF0ZScsXG4gIGRlc2NlbnQ6ICdkZXNjZW50JyxcbiAgZGlmZnVzZWNvbnN0YW50OiAnZGlmZnVzZUNvbnN0YW50JyxcbiAgZGlyZWN0aW9uOiAnZGlyZWN0aW9uJyxcbiAgZGlzcGxheTogJ2Rpc3BsYXknLFxuICBkaXZpc29yOiAnZGl2aXNvcicsXG4gIGRvbWluYW50YmFzZWxpbmU6ICdkb21pbmFudEJhc2VsaW5lJyxcbiAgJ2RvbWluYW50LWJhc2VsaW5lJzogJ2RvbWluYW50QmFzZWxpbmUnLFxuICBkdXI6ICdkdXInLFxuICBkeDogJ2R4JyxcbiAgZHk6ICdkeScsXG4gIGVkZ2Vtb2RlOiAnZWRnZU1vZGUnLFxuICBlbGV2YXRpb246ICdlbGV2YXRpb24nLFxuICBlbmFibGViYWNrZ3JvdW5kOiAnZW5hYmxlQmFja2dyb3VuZCcsXG4gICdlbmFibGUtYmFja2dyb3VuZCc6ICdlbmFibGVCYWNrZ3JvdW5kJyxcbiAgZW5kOiAnZW5kJyxcbiAgZXhwb25lbnQ6ICdleHBvbmVudCcsXG4gIGV4dGVybmFscmVzb3VyY2VzcmVxdWlyZWQ6ICdleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkJyxcbiAgZmlsbDogJ2ZpbGwnLFxuICBmaWxsb3BhY2l0eTogJ2ZpbGxPcGFjaXR5JyxcbiAgJ2ZpbGwtb3BhY2l0eSc6ICdmaWxsT3BhY2l0eScsXG4gIGZpbGxydWxlOiAnZmlsbFJ1bGUnLFxuICAnZmlsbC1ydWxlJzogJ2ZpbGxSdWxlJyxcbiAgZmlsdGVyOiAnZmlsdGVyJyxcbiAgZmlsdGVycmVzOiAnZmlsdGVyUmVzJyxcbiAgZmlsdGVydW5pdHM6ICdmaWx0ZXJVbml0cycsXG4gIGZsb29kb3BhY2l0eTogJ2Zsb29kT3BhY2l0eScsXG4gICdmbG9vZC1vcGFjaXR5JzogJ2Zsb29kT3BhY2l0eScsXG4gIGZsb29kY29sb3I6ICdmbG9vZENvbG9yJyxcbiAgJ2Zsb29kLWNvbG9yJzogJ2Zsb29kQ29sb3InLFxuICBmb2N1c2FibGU6ICdmb2N1c2FibGUnLFxuICBmb250ZmFtaWx5OiAnZm9udEZhbWlseScsXG4gICdmb250LWZhbWlseSc6ICdmb250RmFtaWx5JyxcbiAgZm9udHNpemU6ICdmb250U2l6ZScsXG4gICdmb250LXNpemUnOiAnZm9udFNpemUnLFxuICBmb250c2l6ZWFkanVzdDogJ2ZvbnRTaXplQWRqdXN0JyxcbiAgJ2ZvbnQtc2l6ZS1hZGp1c3QnOiAnZm9udFNpemVBZGp1c3QnLFxuICBmb250c3RyZXRjaDogJ2ZvbnRTdHJldGNoJyxcbiAgJ2ZvbnQtc3RyZXRjaCc6ICdmb250U3RyZXRjaCcsXG4gIGZvbnRzdHlsZTogJ2ZvbnRTdHlsZScsXG4gICdmb250LXN0eWxlJzogJ2ZvbnRTdHlsZScsXG4gIGZvbnR2YXJpYW50OiAnZm9udFZhcmlhbnQnLFxuICAnZm9udC12YXJpYW50JzogJ2ZvbnRWYXJpYW50JyxcbiAgZm9udHdlaWdodDogJ2ZvbnRXZWlnaHQnLFxuICAnZm9udC13ZWlnaHQnOiAnZm9udFdlaWdodCcsXG4gIGZvcm1hdDogJ2Zvcm1hdCcsXG4gIGZyb206ICdmcm9tJyxcbiAgZng6ICdmeCcsXG4gIGZ5OiAnZnknLFxuICBnMTogJ2cxJyxcbiAgZzI6ICdnMicsXG4gIGdseXBobmFtZTogJ2dseXBoTmFtZScsXG4gICdnbHlwaC1uYW1lJzogJ2dseXBoTmFtZScsXG4gIGdseXBob3JpZW50YXRpb25ob3Jpem9udGFsOiAnZ2x5cGhPcmllbnRhdGlvbkhvcml6b250YWwnLFxuICAnZ2x5cGgtb3JpZW50YXRpb24taG9yaXpvbnRhbCc6ICdnbHlwaE9yaWVudGF0aW9uSG9yaXpvbnRhbCcsXG4gIGdseXBob3JpZW50YXRpb252ZXJ0aWNhbDogJ2dseXBoT3JpZW50YXRpb25WZXJ0aWNhbCcsXG4gICdnbHlwaC1vcmllbnRhdGlvbi12ZXJ0aWNhbCc6ICdnbHlwaE9yaWVudGF0aW9uVmVydGljYWwnLFxuICBnbHlwaHJlZjogJ2dseXBoUmVmJyxcbiAgZ3JhZGllbnR0cmFuc2Zvcm06ICdncmFkaWVudFRyYW5zZm9ybScsXG4gIGdyYWRpZW50dW5pdHM6ICdncmFkaWVudFVuaXRzJyxcbiAgaGFuZ2luZzogJ2hhbmdpbmcnLFxuICBob3JpemFkdng6ICdob3JpekFkdlgnLFxuICAnaG9yaXotYWR2LXgnOiAnaG9yaXpBZHZYJyxcbiAgaG9yaXpvcmlnaW54OiAnaG9yaXpPcmlnaW5YJyxcbiAgJ2hvcml6LW9yaWdpbi14JzogJ2hvcml6T3JpZ2luWCcsXG4gIGlkZW9ncmFwaGljOiAnaWRlb2dyYXBoaWMnLFxuICBpbWFnZXJlbmRlcmluZzogJ2ltYWdlUmVuZGVyaW5nJyxcbiAgJ2ltYWdlLXJlbmRlcmluZyc6ICdpbWFnZVJlbmRlcmluZycsXG4gIGluMjogJ2luMicsXG4gIGluOiAnaW4nLFxuICBpbmxpc3Q6ICdpbmxpc3QnLFxuICBpbnRlcmNlcHQ6ICdpbnRlcmNlcHQnLFxuICBrMTogJ2sxJyxcbiAgazI6ICdrMicsXG4gIGszOiAnazMnLFxuICBrNDogJ2s0JyxcbiAgazogJ2snLFxuICBrZXJuZWxtYXRyaXg6ICdrZXJuZWxNYXRyaXgnLFxuICBrZXJuZWx1bml0bGVuZ3RoOiAna2VybmVsVW5pdExlbmd0aCcsXG4gIGtlcm5pbmc6ICdrZXJuaW5nJyxcbiAga2V5cG9pbnRzOiAna2V5UG9pbnRzJyxcbiAga2V5c3BsaW5lczogJ2tleVNwbGluZXMnLFxuICBrZXl0aW1lczogJ2tleVRpbWVzJyxcbiAgbGVuZ3RoYWRqdXN0OiAnbGVuZ3RoQWRqdXN0JyxcbiAgbGV0dGVyc3BhY2luZzogJ2xldHRlclNwYWNpbmcnLFxuICAnbGV0dGVyLXNwYWNpbmcnOiAnbGV0dGVyU3BhY2luZycsXG4gIGxpZ2h0aW5nY29sb3I6ICdsaWdodGluZ0NvbG9yJyxcbiAgJ2xpZ2h0aW5nLWNvbG9yJzogJ2xpZ2h0aW5nQ29sb3InLFxuICBsaW1pdGluZ2NvbmVhbmdsZTogJ2xpbWl0aW5nQ29uZUFuZ2xlJyxcbiAgbG9jYWw6ICdsb2NhbCcsXG4gIG1hcmtlcmVuZDogJ21hcmtlckVuZCcsXG4gICdtYXJrZXItZW5kJzogJ21hcmtlckVuZCcsXG4gIG1hcmtlcmhlaWdodDogJ21hcmtlckhlaWdodCcsXG4gIG1hcmtlcm1pZDogJ21hcmtlck1pZCcsXG4gICdtYXJrZXItbWlkJzogJ21hcmtlck1pZCcsXG4gIG1hcmtlcnN0YXJ0OiAnbWFya2VyU3RhcnQnLFxuICAnbWFya2VyLXN0YXJ0JzogJ21hcmtlclN0YXJ0JyxcbiAgbWFya2VydW5pdHM6ICdtYXJrZXJVbml0cycsXG4gIG1hcmtlcndpZHRoOiAnbWFya2VyV2lkdGgnLFxuICBtYXNrOiAnbWFzaycsXG4gIG1hc2tjb250ZW50dW5pdHM6ICdtYXNrQ29udGVudFVuaXRzJyxcbiAgbWFza3VuaXRzOiAnbWFza1VuaXRzJyxcbiAgbWF0aGVtYXRpY2FsOiAnbWF0aGVtYXRpY2FsJyxcbiAgbW9kZTogJ21vZGUnLFxuICBudW1vY3RhdmVzOiAnbnVtT2N0YXZlcycsXG4gIG9mZnNldDogJ29mZnNldCcsXG4gIG9wYWNpdHk6ICdvcGFjaXR5JyxcbiAgb3BlcmF0b3I6ICdvcGVyYXRvcicsXG4gIG9yZGVyOiAnb3JkZXInLFxuICBvcmllbnQ6ICdvcmllbnQnLFxuICBvcmllbnRhdGlvbjogJ29yaWVudGF0aW9uJyxcbiAgb3JpZ2luOiAnb3JpZ2luJyxcbiAgb3ZlcmZsb3c6ICdvdmVyZmxvdycsXG4gIG92ZXJsaW5lcG9zaXRpb246ICdvdmVybGluZVBvc2l0aW9uJyxcbiAgJ292ZXJsaW5lLXBvc2l0aW9uJzogJ292ZXJsaW5lUG9zaXRpb24nLFxuICBvdmVybGluZXRoaWNrbmVzczogJ292ZXJsaW5lVGhpY2tuZXNzJyxcbiAgJ292ZXJsaW5lLXRoaWNrbmVzcyc6ICdvdmVybGluZVRoaWNrbmVzcycsXG4gIHBhaW50b3JkZXI6ICdwYWludE9yZGVyJyxcbiAgJ3BhaW50LW9yZGVyJzogJ3BhaW50T3JkZXInLFxuICBwYW5vc2UxOiAncGFub3NlMScsXG4gICdwYW5vc2UtMSc6ICdwYW5vc2UxJyxcbiAgcGF0aGxlbmd0aDogJ3BhdGhMZW5ndGgnLFxuICBwYXR0ZXJuY29udGVudHVuaXRzOiAncGF0dGVybkNvbnRlbnRVbml0cycsXG4gIHBhdHRlcm50cmFuc2Zvcm06ICdwYXR0ZXJuVHJhbnNmb3JtJyxcbiAgcGF0dGVybnVuaXRzOiAncGF0dGVyblVuaXRzJyxcbiAgcG9pbnRlcmV2ZW50czogJ3BvaW50ZXJFdmVudHMnLFxuICAncG9pbnRlci1ldmVudHMnOiAncG9pbnRlckV2ZW50cycsXG4gIHBvaW50czogJ3BvaW50cycsXG4gIHBvaW50c2F0eDogJ3BvaW50c0F0WCcsXG4gIHBvaW50c2F0eTogJ3BvaW50c0F0WScsXG4gIHBvaW50c2F0ejogJ3BvaW50c0F0WicsXG4gIHByZWZpeDogJ3ByZWZpeCcsXG4gIHByZXNlcnZlYWxwaGE6ICdwcmVzZXJ2ZUFscGhhJyxcbiAgcHJlc2VydmVhc3BlY3RyYXRpbzogJ3ByZXNlcnZlQXNwZWN0UmF0aW8nLFxuICBwcmltaXRpdmV1bml0czogJ3ByaW1pdGl2ZVVuaXRzJyxcbiAgcHJvcGVydHk6ICdwcm9wZXJ0eScsXG4gIHI6ICdyJyxcbiAgcmFkaXVzOiAncmFkaXVzJyxcbiAgcmVmeDogJ3JlZlgnLFxuICByZWZ5OiAncmVmWScsXG4gIHJlbmRlcmluZ2ludGVudDogJ3JlbmRlcmluZ0ludGVudCcsXG4gICdyZW5kZXJpbmctaW50ZW50JzogJ3JlbmRlcmluZ0ludGVudCcsXG4gIHJlcGVhdGNvdW50OiAncmVwZWF0Q291bnQnLFxuICByZXBlYXRkdXI6ICdyZXBlYXREdXInLFxuICByZXF1aXJlZGV4dGVuc2lvbnM6ICdyZXF1aXJlZEV4dGVuc2lvbnMnLFxuICByZXF1aXJlZGZlYXR1cmVzOiAncmVxdWlyZWRGZWF0dXJlcycsXG4gIHJlc291cmNlOiAncmVzb3VyY2UnLFxuICByZXN0YXJ0OiAncmVzdGFydCcsXG4gIHJlc3VsdDogJ3Jlc3VsdCcsXG4gIHJlc3VsdHM6ICdyZXN1bHRzJyxcbiAgcm90YXRlOiAncm90YXRlJyxcbiAgcng6ICdyeCcsXG4gIHJ5OiAncnknLFxuICBzY2FsZTogJ3NjYWxlJyxcbiAgc2VjdXJpdHk6ICdzZWN1cml0eScsXG4gIHNlZWQ6ICdzZWVkJyxcbiAgc2hhcGVyZW5kZXJpbmc6ICdzaGFwZVJlbmRlcmluZycsXG4gICdzaGFwZS1yZW5kZXJpbmcnOiAnc2hhcGVSZW5kZXJpbmcnLFxuICBzbG9wZTogJ3Nsb3BlJyxcbiAgc3BhY2luZzogJ3NwYWNpbmcnLFxuICBzcGVjdWxhcmNvbnN0YW50OiAnc3BlY3VsYXJDb25zdGFudCcsXG4gIHNwZWN1bGFyZXhwb25lbnQ6ICdzcGVjdWxhckV4cG9uZW50JyxcbiAgc3BlZWQ6ICdzcGVlZCcsXG4gIHNwcmVhZG1ldGhvZDogJ3NwcmVhZE1ldGhvZCcsXG4gIHN0YXJ0b2Zmc2V0OiAnc3RhcnRPZmZzZXQnLFxuICBzdGRkZXZpYXRpb246ICdzdGREZXZpYXRpb24nLFxuICBzdGVtaDogJ3N0ZW1oJyxcbiAgc3RlbXY6ICdzdGVtdicsXG4gIHN0aXRjaHRpbGVzOiAnc3RpdGNoVGlsZXMnLFxuICBzdG9wY29sb3I6ICdzdG9wQ29sb3InLFxuICAnc3RvcC1jb2xvcic6ICdzdG9wQ29sb3InLFxuICBzdG9wb3BhY2l0eTogJ3N0b3BPcGFjaXR5JyxcbiAgJ3N0b3Atb3BhY2l0eSc6ICdzdG9wT3BhY2l0eScsXG4gIHN0cmlrZXRocm91Z2hwb3NpdGlvbjogJ3N0cmlrZXRocm91Z2hQb3NpdGlvbicsXG4gICdzdHJpa2V0aHJvdWdoLXBvc2l0aW9uJzogJ3N0cmlrZXRocm91Z2hQb3NpdGlvbicsXG4gIHN0cmlrZXRocm91Z2h0aGlja25lc3M6ICdzdHJpa2V0aHJvdWdoVGhpY2tuZXNzJyxcbiAgJ3N0cmlrZXRocm91Z2gtdGhpY2tuZXNzJzogJ3N0cmlrZXRocm91Z2hUaGlja25lc3MnLFxuICBzdHJpbmc6ICdzdHJpbmcnLFxuICBzdHJva2U6ICdzdHJva2UnLFxuICBzdHJva2VkYXNoYXJyYXk6ICdzdHJva2VEYXNoYXJyYXknLFxuICAnc3Ryb2tlLWRhc2hhcnJheSc6ICdzdHJva2VEYXNoYXJyYXknLFxuICBzdHJva2VkYXNob2Zmc2V0OiAnc3Ryb2tlRGFzaG9mZnNldCcsXG4gICdzdHJva2UtZGFzaG9mZnNldCc6ICdzdHJva2VEYXNob2Zmc2V0JyxcbiAgc3Ryb2tlbGluZWNhcDogJ3N0cm9rZUxpbmVjYXAnLFxuICAnc3Ryb2tlLWxpbmVjYXAnOiAnc3Ryb2tlTGluZWNhcCcsXG4gIHN0cm9rZWxpbmVqb2luOiAnc3Ryb2tlTGluZWpvaW4nLFxuICAnc3Ryb2tlLWxpbmVqb2luJzogJ3N0cm9rZUxpbmVqb2luJyxcbiAgc3Ryb2tlbWl0ZXJsaW1pdDogJ3N0cm9rZU1pdGVybGltaXQnLFxuICAnc3Ryb2tlLW1pdGVybGltaXQnOiAnc3Ryb2tlTWl0ZXJsaW1pdCcsXG4gIHN0cm9rZXdpZHRoOiAnc3Ryb2tlV2lkdGgnLFxuICAnc3Ryb2tlLXdpZHRoJzogJ3N0cm9rZVdpZHRoJyxcbiAgc3Ryb2tlb3BhY2l0eTogJ3N0cm9rZU9wYWNpdHknLFxuICAnc3Ryb2tlLW9wYWNpdHknOiAnc3Ryb2tlT3BhY2l0eScsXG4gIHN1cHByZXNzY29udGVudGVkaXRhYmxld2FybmluZzogJ3N1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZycsXG4gIHN1cHByZXNzaHlkcmF0aW9ud2FybmluZzogJ3N1cHByZXNzSHlkcmF0aW9uV2FybmluZycsXG4gIHN1cmZhY2VzY2FsZTogJ3N1cmZhY2VTY2FsZScsXG4gIHN5c3RlbWxhbmd1YWdlOiAnc3lzdGVtTGFuZ3VhZ2UnLFxuICB0YWJsZXZhbHVlczogJ3RhYmxlVmFsdWVzJyxcbiAgdGFyZ2V0eDogJ3RhcmdldFgnLFxuICB0YXJnZXR5OiAndGFyZ2V0WScsXG4gIHRleHRhbmNob3I6ICd0ZXh0QW5jaG9yJyxcbiAgJ3RleHQtYW5jaG9yJzogJ3RleHRBbmNob3InLFxuICB0ZXh0ZGVjb3JhdGlvbjogJ3RleHREZWNvcmF0aW9uJyxcbiAgJ3RleHQtZGVjb3JhdGlvbic6ICd0ZXh0RGVjb3JhdGlvbicsXG4gIHRleHRsZW5ndGg6ICd0ZXh0TGVuZ3RoJyxcbiAgdGV4dHJlbmRlcmluZzogJ3RleHRSZW5kZXJpbmcnLFxuICAndGV4dC1yZW5kZXJpbmcnOiAndGV4dFJlbmRlcmluZycsXG4gIHRvOiAndG8nLFxuICB0cmFuc2Zvcm06ICd0cmFuc2Zvcm0nLFxuICB0eXBlb2Y6ICd0eXBlb2YnLFxuICB1MTogJ3UxJyxcbiAgdTI6ICd1MicsXG4gIHVuZGVybGluZXBvc2l0aW9uOiAndW5kZXJsaW5lUG9zaXRpb24nLFxuICAndW5kZXJsaW5lLXBvc2l0aW9uJzogJ3VuZGVybGluZVBvc2l0aW9uJyxcbiAgdW5kZXJsaW5ldGhpY2tuZXNzOiAndW5kZXJsaW5lVGhpY2tuZXNzJyxcbiAgJ3VuZGVybGluZS10aGlja25lc3MnOiAndW5kZXJsaW5lVGhpY2tuZXNzJyxcbiAgdW5pY29kZTogJ3VuaWNvZGUnLFxuICB1bmljb2RlYmlkaTogJ3VuaWNvZGVCaWRpJyxcbiAgJ3VuaWNvZGUtYmlkaSc6ICd1bmljb2RlQmlkaScsXG4gIHVuaWNvZGVyYW5nZTogJ3VuaWNvZGVSYW5nZScsXG4gICd1bmljb2RlLXJhbmdlJzogJ3VuaWNvZGVSYW5nZScsXG4gIHVuaXRzcGVyZW06ICd1bml0c1BlckVtJyxcbiAgJ3VuaXRzLXBlci1lbSc6ICd1bml0c1BlckVtJyxcbiAgdW5zZWxlY3RhYmxlOiAndW5zZWxlY3RhYmxlJyxcbiAgdmFscGhhYmV0aWM6ICd2QWxwaGFiZXRpYycsXG4gICd2LWFscGhhYmV0aWMnOiAndkFscGhhYmV0aWMnLFxuICB2YWx1ZXM6ICd2YWx1ZXMnLFxuICB2ZWN0b3JlZmZlY3Q6ICd2ZWN0b3JFZmZlY3QnLFxuICAndmVjdG9yLWVmZmVjdCc6ICd2ZWN0b3JFZmZlY3QnLFxuICB2ZXJzaW9uOiAndmVyc2lvbicsXG4gIHZlcnRhZHZ5OiAndmVydEFkdlknLFxuICAndmVydC1hZHYteSc6ICd2ZXJ0QWR2WScsXG4gIHZlcnRvcmlnaW54OiAndmVydE9yaWdpblgnLFxuICAndmVydC1vcmlnaW4teCc6ICd2ZXJ0T3JpZ2luWCcsXG4gIHZlcnRvcmlnaW55OiAndmVydE9yaWdpblknLFxuICAndmVydC1vcmlnaW4teSc6ICd2ZXJ0T3JpZ2luWScsXG4gIHZoYW5naW5nOiAndkhhbmdpbmcnLFxuICAndi1oYW5naW5nJzogJ3ZIYW5naW5nJyxcbiAgdmlkZW9ncmFwaGljOiAndklkZW9ncmFwaGljJyxcbiAgJ3YtaWRlb2dyYXBoaWMnOiAndklkZW9ncmFwaGljJyxcbiAgdmlld2JveDogJ3ZpZXdCb3gnLFxuICB2aWV3dGFyZ2V0OiAndmlld1RhcmdldCcsXG4gIHZpc2liaWxpdHk6ICd2aXNpYmlsaXR5JyxcbiAgdm1hdGhlbWF0aWNhbDogJ3ZNYXRoZW1hdGljYWwnLFxuICAndi1tYXRoZW1hdGljYWwnOiAndk1hdGhlbWF0aWNhbCcsXG4gIHZvY2FiOiAndm9jYWInLFxuICB3aWR0aHM6ICd3aWR0aHMnLFxuICB3b3Jkc3BhY2luZzogJ3dvcmRTcGFjaW5nJyxcbiAgJ3dvcmQtc3BhY2luZyc6ICd3b3JkU3BhY2luZycsXG4gIHdyaXRpbmdtb2RlOiAnd3JpdGluZ01vZGUnLFxuICAnd3JpdGluZy1tb2RlJzogJ3dyaXRpbmdNb2RlJyxcbiAgeDE6ICd4MScsXG4gIHgyOiAneDInLFxuICB4OiAneCcsXG4gIHhjaGFubmVsc2VsZWN0b3I6ICd4Q2hhbm5lbFNlbGVjdG9yJyxcbiAgeGhlaWdodDogJ3hIZWlnaHQnLFxuICAneC1oZWlnaHQnOiAneEhlaWdodCcsXG4gIHhsaW5rYWN0dWF0ZTogJ3hsaW5rQWN0dWF0ZScsXG4gICd4bGluazphY3R1YXRlJzogJ3hsaW5rQWN0dWF0ZScsXG4gIHhsaW5rYXJjcm9sZTogJ3hsaW5rQXJjcm9sZScsXG4gICd4bGluazphcmNyb2xlJzogJ3hsaW5rQXJjcm9sZScsXG4gIHhsaW5raHJlZjogJ3hsaW5rSHJlZicsXG4gICd4bGluazpocmVmJzogJ3hsaW5rSHJlZicsXG4gIHhsaW5rcm9sZTogJ3hsaW5rUm9sZScsXG4gICd4bGluazpyb2xlJzogJ3hsaW5rUm9sZScsXG4gIHhsaW5rc2hvdzogJ3hsaW5rU2hvdycsXG4gICd4bGluazpzaG93JzogJ3hsaW5rU2hvdycsXG4gIHhsaW5rdGl0bGU6ICd4bGlua1RpdGxlJyxcbiAgJ3hsaW5rOnRpdGxlJzogJ3hsaW5rVGl0bGUnLFxuICB4bGlua3R5cGU6ICd4bGlua1R5cGUnLFxuICAneGxpbms6dHlwZSc6ICd4bGlua1R5cGUnLFxuICB4bWxiYXNlOiAneG1sQmFzZScsXG4gICd4bWw6YmFzZSc6ICd4bWxCYXNlJyxcbiAgeG1sbGFuZzogJ3htbExhbmcnLFxuICAneG1sOmxhbmcnOiAneG1sTGFuZycsXG4gIHhtbG5zOiAneG1sbnMnLFxuICAneG1sOnNwYWNlJzogJ3htbFNwYWNlJyxcbiAgeG1sbnN4bGluazogJ3htbG5zWGxpbmsnLFxuICAneG1sbnM6eGxpbmsnOiAneG1sbnNYbGluaycsXG4gIHhtbHNwYWNlOiAneG1sU3BhY2UnLFxuICB5MTogJ3kxJyxcbiAgeTI6ICd5MicsXG4gIHk6ICd5JyxcbiAgeWNoYW5uZWxzZWxlY3RvcjogJ3lDaGFubmVsU2VsZWN0b3InLFxuICB6OiAneicsXG4gIHpvb21hbmRwYW46ICd6b29tQW5kUGFuJ1xufTtcblxudmFyIGFyaWFQcm9wZXJ0aWVzID0ge1xuICAnYXJpYS1jdXJyZW50JzogMCxcbiAgLy8gc3RhdGVcbiAgJ2FyaWEtZGVzY3JpcHRpb24nOiAwLFxuICAnYXJpYS1kZXRhaWxzJzogMCxcbiAgJ2FyaWEtZGlzYWJsZWQnOiAwLFxuICAvLyBzdGF0ZVxuICAnYXJpYS1oaWRkZW4nOiAwLFxuICAvLyBzdGF0ZVxuICAnYXJpYS1pbnZhbGlkJzogMCxcbiAgLy8gc3RhdGVcbiAgJ2FyaWEta2V5c2hvcnRjdXRzJzogMCxcbiAgJ2FyaWEtbGFiZWwnOiAwLFxuICAnYXJpYS1yb2xlZGVzY3JpcHRpb24nOiAwLFxuICAvLyBXaWRnZXQgQXR0cmlidXRlc1xuICAnYXJpYS1hdXRvY29tcGxldGUnOiAwLFxuICAnYXJpYS1jaGVja2VkJzogMCxcbiAgJ2FyaWEtZXhwYW5kZWQnOiAwLFxuICAnYXJpYS1oYXNwb3B1cCc6IDAsXG4gICdhcmlhLWxldmVsJzogMCxcbiAgJ2FyaWEtbW9kYWwnOiAwLFxuICAnYXJpYS1tdWx0aWxpbmUnOiAwLFxuICAnYXJpYS1tdWx0aXNlbGVjdGFibGUnOiAwLFxuICAnYXJpYS1vcmllbnRhdGlvbic6IDAsXG4gICdhcmlhLXBsYWNlaG9sZGVyJzogMCxcbiAgJ2FyaWEtcHJlc3NlZCc6IDAsXG4gICdhcmlhLXJlYWRvbmx5JzogMCxcbiAgJ2FyaWEtcmVxdWlyZWQnOiAwLFxuICAnYXJpYS1zZWxlY3RlZCc6IDAsXG4gICdhcmlhLXNvcnQnOiAwLFxuICAnYXJpYS12YWx1ZW1heCc6IDAsXG4gICdhcmlhLXZhbHVlbWluJzogMCxcbiAgJ2FyaWEtdmFsdWVub3cnOiAwLFxuICAnYXJpYS12YWx1ZXRleHQnOiAwLFxuICAvLyBMaXZlIFJlZ2lvbiBBdHRyaWJ1dGVzXG4gICdhcmlhLWF0b21pYyc6IDAsXG4gICdhcmlhLWJ1c3knOiAwLFxuICAnYXJpYS1saXZlJzogMCxcbiAgJ2FyaWEtcmVsZXZhbnQnOiAwLFxuICAvLyBEcmFnLWFuZC1Ecm9wIEF0dHJpYnV0ZXNcbiAgJ2FyaWEtZHJvcGVmZmVjdCc6IDAsXG4gICdhcmlhLWdyYWJiZWQnOiAwLFxuICAvLyBSZWxhdGlvbnNoaXAgQXR0cmlidXRlc1xuICAnYXJpYS1hY3RpdmVkZXNjZW5kYW50JzogMCxcbiAgJ2FyaWEtY29sY291bnQnOiAwLFxuICAnYXJpYS1jb2xpbmRleCc6IDAsXG4gICdhcmlhLWNvbHNwYW4nOiAwLFxuICAnYXJpYS1jb250cm9scyc6IDAsXG4gICdhcmlhLWRlc2NyaWJlZGJ5JzogMCxcbiAgJ2FyaWEtZXJyb3JtZXNzYWdlJzogMCxcbiAgJ2FyaWEtZmxvd3RvJzogMCxcbiAgJ2FyaWEtbGFiZWxsZWRieSc6IDAsXG4gICdhcmlhLW93bnMnOiAwLFxuICAnYXJpYS1wb3NpbnNldCc6IDAsXG4gICdhcmlhLXJvd2NvdW50JzogMCxcbiAgJ2FyaWEtcm93aW5kZXgnOiAwLFxuICAnYXJpYS1yb3dzcGFuJzogMCxcbiAgJ2FyaWEtc2V0c2l6ZSc6IDBcbn07XG5cbnZhciB3YXJuZWRQcm9wZXJ0aWVzID0ge307XG52YXIgckFSSUEgPSBuZXcgUmVnRXhwKCdeKGFyaWEpLVsnICsgQVRUUklCVVRFX05BTUVfQ0hBUiArICddKiQnKTtcbnZhciByQVJJQUNhbWVsID0gbmV3IFJlZ0V4cCgnXihhcmlhKVtBLVpdWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BlcnR5KHRhZ05hbWUsIG5hbWUpIHtcbiAge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHdhcm5lZFByb3BlcnRpZXMsIG5hbWUpICYmIHdhcm5lZFByb3BlcnRpZXNbbmFtZV0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyQVJJQUNhbWVsLnRlc3QobmFtZSkpIHtcbiAgICAgIHZhciBhcmlhTmFtZSA9ICdhcmlhLScgKyBuYW1lLnNsaWNlKDQpLnRvTG93ZXJDYXNlKCk7XG4gICAgICB2YXIgY29ycmVjdE5hbWUgPSBhcmlhUHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShhcmlhTmFtZSkgPyBhcmlhTmFtZSA6IG51bGw7IC8vIElmIHRoaXMgaXMgYW4gYXJpYS0qIGF0dHJpYnV0ZSwgYnV0IGlzIG5vdCBsaXN0ZWQgaW4gdGhlIGtub3duIERPTVxuICAgICAgLy8gRE9NIHByb3BlcnRpZXMsIHRoZW4gaXQgaXMgYW4gaW52YWxpZCBhcmlhLSogYXR0cmlidXRlLlxuXG4gICAgICBpZiAoY29ycmVjdE5hbWUgPT0gbnVsbCkge1xuICAgICAgICBlcnJvcignSW52YWxpZCBBUklBIGF0dHJpYnV0ZSBgJXNgLiBBUklBIGF0dHJpYnV0ZXMgZm9sbG93IHRoZSBwYXR0ZXJuIGFyaWEtKiBhbmQgbXVzdCBiZSBsb3dlcmNhc2UuJywgbmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSAvLyBhcmlhLSogYXR0cmlidXRlcyBzaG91bGQgYmUgbG93ZXJjYXNlOyBzdWdnZXN0IHRoZSBsb3dlcmNhc2UgdmVyc2lvbi5cblxuXG4gICAgICBpZiAobmFtZSAhPT0gY29ycmVjdE5hbWUpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgQVJJQSBhdHRyaWJ1dGUgYCVzYC4gRGlkIHlvdSBtZWFuIGAlc2A/JywgbmFtZSwgY29ycmVjdE5hbWUpO1xuXG4gICAgICAgIHdhcm5lZFByb3BlcnRpZXNbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAockFSSUEudGVzdChuYW1lKSkge1xuICAgICAgdmFyIGxvd2VyQ2FzZWROYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdmFyIHN0YW5kYXJkTmFtZSA9IGFyaWFQcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KGxvd2VyQ2FzZWROYW1lKSA/IGxvd2VyQ2FzZWROYW1lIDogbnVsbDsgLy8gSWYgdGhpcyBpcyBhbiBhcmlhLSogYXR0cmlidXRlLCBidXQgaXMgbm90IGxpc3RlZCBpbiB0aGUga25vd24gRE9NXG4gICAgICAvLyBET00gcHJvcGVydGllcywgdGhlbiBpdCBpcyBhbiBpbnZhbGlkIGFyaWEtKiBhdHRyaWJ1dGUuXG5cbiAgICAgIGlmIChzdGFuZGFyZE5hbWUgPT0gbnVsbCkge1xuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSAvLyBhcmlhLSogYXR0cmlidXRlcyBzaG91bGQgYmUgbG93ZXJjYXNlOyBzdWdnZXN0IHRoZSBsb3dlcmNhc2UgdmVyc2lvbi5cblxuXG4gICAgICBpZiAobmFtZSAhPT0gc3RhbmRhcmROYW1lKSB7XG4gICAgICAgIGVycm9yKCdVbmtub3duIEFSSUEgYXR0cmlidXRlIGAlc2AuIERpZCB5b3UgbWVhbiBgJXNgPycsIG5hbWUsIHN0YW5kYXJkTmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiB3YXJuSW52YWxpZEFSSUFQcm9wcyh0eXBlLCBwcm9wcykge1xuICB7XG4gICAgdmFyIGludmFsaWRQcm9wcyA9IFtdO1xuXG4gICAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgICB2YXIgaXNWYWxpZCA9IHZhbGlkYXRlUHJvcGVydHkodHlwZSwga2V5KTtcblxuICAgICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgIGludmFsaWRQcm9wcy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHVua25vd25Qcm9wU3RyaW5nID0gaW52YWxpZFByb3BzLm1hcChmdW5jdGlvbiAocHJvcCkge1xuICAgICAgcmV0dXJuICdgJyArIHByb3AgKyAnYCc7XG4gICAgfSkuam9pbignLCAnKTtcblxuICAgIGlmIChpbnZhbGlkUHJvcHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBlcnJvcignSW52YWxpZCBhcmlhIHByb3AgJXMgb24gPCVzPiB0YWcuICcgKyAnRm9yIGRldGFpbHMsIHNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvaW52YWxpZC1hcmlhLXByb3BzJywgdW5rbm93blByb3BTdHJpbmcsIHR5cGUpO1xuICAgIH0gZWxzZSBpZiAoaW52YWxpZFByb3BzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIGFyaWEgcHJvcHMgJXMgb24gPCVzPiB0YWcuICcgKyAnRm9yIGRldGFpbHMsIHNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvaW52YWxpZC1hcmlhLXByb3BzJywgdW5rbm93blByb3BTdHJpbmcsIHR5cGUpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BlcnRpZXModHlwZSwgcHJvcHMpIHtcbiAgaWYgKGlzQ3VzdG9tQ29tcG9uZW50KHR5cGUsIHByb3BzKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHdhcm5JbnZhbGlkQVJJQVByb3BzKHR5cGUsIHByb3BzKTtcbn1cblxudmFyIGRpZFdhcm5WYWx1ZU51bGwgPSBmYWxzZTtcbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcGVydGllcyQxKHR5cGUsIHByb3BzKSB7XG4gIHtcbiAgICBpZiAodHlwZSAhPT0gJ2lucHV0JyAmJiB0eXBlICE9PSAndGV4dGFyZWEnICYmIHR5cGUgIT09ICdzZWxlY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHByb3BzICE9IG51bGwgJiYgcHJvcHMudmFsdWUgPT09IG51bGwgJiYgIWRpZFdhcm5WYWx1ZU51bGwpIHtcbiAgICAgIGRpZFdhcm5WYWx1ZU51bGwgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZSA9PT0gJ3NlbGVjdCcgJiYgcHJvcHMubXVsdGlwbGUpIHtcbiAgICAgICAgZXJyb3IoJ2B2YWx1ZWAgcHJvcCBvbiBgJXNgIHNob3VsZCBub3QgYmUgbnVsbC4gJyArICdDb25zaWRlciB1c2luZyBhbiBlbXB0eSBhcnJheSB3aGVuIGBtdWx0aXBsZWAgaXMgc2V0IHRvIGB0cnVlYCAnICsgJ3RvIGNsZWFyIHRoZSBjb21wb25lbnQgb3IgYHVuZGVmaW5lZGAgZm9yIHVuY29udHJvbGxlZCBjb21wb25lbnRzLicsIHR5cGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IoJ2B2YWx1ZWAgcHJvcCBvbiBgJXNgIHNob3VsZCBub3QgYmUgbnVsbC4gJyArICdDb25zaWRlciB1c2luZyBhbiBlbXB0eSBzdHJpbmcgdG8gY2xlYXIgdGhlIGNvbXBvbmVudCBvciBgdW5kZWZpbmVkYCAnICsgJ2ZvciB1bmNvbnRyb2xsZWQgY29tcG9uZW50cy4nLCB0eXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIHZhbGlkYXRlUHJvcGVydHkkMSA9IGZ1bmN0aW9uICgpIHt9O1xuXG57XG4gIHZhciB3YXJuZWRQcm9wZXJ0aWVzJDEgPSB7fTtcbiAgdmFyIEVWRU5UX05BTUVfUkVHRVggPSAvXm9uLi87XG4gIHZhciBJTlZBTElEX0VWRU5UX05BTUVfUkVHRVggPSAvXm9uW15BLVpdLztcbiAgdmFyIHJBUklBJDEgPSBuZXcgUmVnRXhwKCdeKGFyaWEpLVsnICsgQVRUUklCVVRFX05BTUVfQ0hBUiArICddKiQnKTtcbiAgdmFyIHJBUklBQ2FtZWwkMSA9IG5ldyBSZWdFeHAoJ14oYXJpYSlbQS1aXVsnICsgQVRUUklCVVRFX05BTUVfQ0hBUiArICddKiQnKTtcblxuICB2YWxpZGF0ZVByb3BlcnR5JDEgPSBmdW5jdGlvbiAodGFnTmFtZSwgbmFtZSwgdmFsdWUsIGV2ZW50UmVnaXN0cnkpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh3YXJuZWRQcm9wZXJ0aWVzJDEsIG5hbWUpICYmIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIGxvd2VyQ2FzZWROYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKGxvd2VyQ2FzZWROYW1lID09PSAnb25mb2N1c2luJyB8fCBsb3dlckNhc2VkTmFtZSA9PT0gJ29uZm9jdXNvdXQnKSB7XG4gICAgICBlcnJvcignUmVhY3QgdXNlcyBvbkZvY3VzIGFuZCBvbkJsdXIgaW5zdGVhZCBvZiBvbkZvY3VzSW4gYW5kIG9uRm9jdXNPdXQuICcgKyAnQWxsIFJlYWN0IGV2ZW50cyBhcmUgbm9ybWFsaXplZCB0byBidWJibGUsIHNvIG9uRm9jdXNJbiBhbmQgb25Gb2N1c091dCAnICsgJ2FyZSBub3QgbmVlZGVkL3N1cHBvcnRlZCBieSBSZWFjdC4nKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gLy8gV2UgY2FuJ3QgcmVseSBvbiB0aGUgZXZlbnQgc3lzdGVtIGJlaW5nIGluamVjdGVkIG9uIHRoZSBzZXJ2ZXIuXG5cblxuICAgIGlmIChldmVudFJlZ2lzdHJ5ICE9IG51bGwpIHtcbiAgICAgIHZhciByZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzID0gZXZlbnRSZWdpc3RyeS5yZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLFxuICAgICAgICAgIHBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXMgPSBldmVudFJlZ2lzdHJ5LnBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXM7XG5cbiAgICAgIGlmIChyZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVnaXN0cmF0aW9uTmFtZSA9IHBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXMuaGFzT3duUHJvcGVydHkobG93ZXJDYXNlZE5hbWUpID8gcG9zc2libGVSZWdpc3RyYXRpb25OYW1lc1tsb3dlckNhc2VkTmFtZV0gOiBudWxsO1xuXG4gICAgICBpZiAocmVnaXN0cmF0aW9uTmFtZSAhPSBudWxsKSB7XG4gICAgICAgIGVycm9yKCdJbnZhbGlkIGV2ZW50IGhhbmRsZXIgcHJvcGVydHkgYCVzYC4gRGlkIHlvdSBtZWFuIGAlc2A/JywgbmFtZSwgcmVnaXN0cmF0aW9uTmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChFVkVOVF9OQU1FX1JFR0VYLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZXJyb3IoJ1Vua25vd24gZXZlbnQgaGFuZGxlciBwcm9wZXJ0eSBgJXNgLiBJdCB3aWxsIGJlIGlnbm9yZWQuJywgbmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChFVkVOVF9OQU1FX1JFR0VYLnRlc3QobmFtZSkpIHtcbiAgICAgIC8vIElmIG5vIGV2ZW50IHBsdWdpbnMgaGF2ZSBiZWVuIGluamVjdGVkLCB3ZSBhcmUgaW4gYSBzZXJ2ZXIgZW52aXJvbm1lbnQuXG4gICAgICAvLyBTbyB3ZSBjYW4ndCB0ZWxsIGlmIHRoZSBldmVudCBuYW1lIGlzIGNvcnJlY3QgZm9yIHN1cmUsIGJ1dCB3ZSBjYW4gZmlsdGVyXG4gICAgICAvLyBvdXQga25vd24gYmFkIG9uZXMgbGlrZSBgb25jbGlja2AuIFdlIGNhbid0IHN1Z2dlc3QgYSBzcGVjaWZpYyByZXBsYWNlbWVudCB0aG91Z2guXG4gICAgICBpZiAoSU5WQUxJRF9FVkVOVF9OQU1FX1JFR0VYLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgZXZlbnQgaGFuZGxlciBwcm9wZXJ0eSBgJXNgLiAnICsgJ1JlYWN0IGV2ZW50cyB1c2UgdGhlIGNhbWVsQ2FzZSBuYW1pbmcgY29udmVudGlvbiwgZm9yIGV4YW1wbGUgYG9uQ2xpY2tgLicsIG5hbWUpO1xuICAgICAgfVxuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSAvLyBMZXQgdGhlIEFSSUEgYXR0cmlidXRlIGhvb2sgdmFsaWRhdGUgQVJJQSBhdHRyaWJ1dGVzXG5cblxuICAgIGlmIChyQVJJQSQxLnRlc3QobmFtZSkgfHwgckFSSUFDYW1lbCQxLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChsb3dlckNhc2VkTmFtZSA9PT0gJ2lubmVyaHRtbCcpIHtcbiAgICAgIGVycm9yKCdEaXJlY3RseSBzZXR0aW5nIHByb3BlcnR5IGBpbm5lckhUTUxgIGlzIG5vdCBwZXJtaXR0ZWQuICcgKyAnRm9yIG1vcmUgaW5mb3JtYXRpb24sIGxvb2t1cCBkb2N1bWVudGF0aW9uIG9uIGBkYW5nZXJvdXNseVNldElubmVySFRNTGAuJyk7XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAobG93ZXJDYXNlZE5hbWUgPT09ICdhcmlhJykge1xuICAgICAgZXJyb3IoJ1RoZSBgYXJpYWAgYXR0cmlidXRlIGlzIHJlc2VydmVkIGZvciBmdXR1cmUgdXNlIGluIFJlYWN0LiAnICsgJ1Bhc3MgaW5kaXZpZHVhbCBgYXJpYS1gIGF0dHJpYnV0ZXMgaW5zdGVhZC4nKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChsb3dlckNhc2VkTmFtZSA9PT0gJ2lzJyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9yKCdSZWNlaXZlZCBhIGAlc2AgZm9yIGEgc3RyaW5nIGF0dHJpYnV0ZSBgaXNgLiBJZiB0aGlzIGlzIGV4cGVjdGVkLCBjYXN0ICcgKyAndGhlIHZhbHVlIHRvIGEgc3RyaW5nLicsIHR5cGVvZiB2YWx1ZSk7XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBpc05hTih2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdSZWNlaXZlZCBOYU4gZm9yIHRoZSBgJXNgIGF0dHJpYnV0ZS4gSWYgdGhpcyBpcyBleHBlY3RlZCwgY2FzdCAnICsgJ3RoZSB2YWx1ZSB0byBhIHN0cmluZy4nLCBuYW1lKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBwcm9wZXJ0eUluZm8gPSBnZXRQcm9wZXJ0eUluZm8obmFtZSk7XG4gICAgdmFyIGlzUmVzZXJ2ZWQgPSBwcm9wZXJ0eUluZm8gIT09IG51bGwgJiYgcHJvcGVydHlJbmZvLnR5cGUgPT09IFJFU0VSVkVEOyAvLyBLbm93biBhdHRyaWJ1dGVzIHNob3VsZCBtYXRjaCB0aGUgY2FzaW5nIHNwZWNpZmllZCBpbiB0aGUgcHJvcGVydHkgY29uZmlnLlxuXG4gICAgaWYgKHBvc3NpYmxlU3RhbmRhcmROYW1lcy5oYXNPd25Qcm9wZXJ0eShsb3dlckNhc2VkTmFtZSkpIHtcbiAgICAgIHZhciBzdGFuZGFyZE5hbWUgPSBwb3NzaWJsZVN0YW5kYXJkTmFtZXNbbG93ZXJDYXNlZE5hbWVdO1xuXG4gICAgICBpZiAoc3RhbmRhcmROYW1lICE9PSBuYW1lKSB7XG4gICAgICAgIGVycm9yKCdJbnZhbGlkIERPTSBwcm9wZXJ0eSBgJXNgLiBEaWQgeW91IG1lYW4gYCVzYD8nLCBuYW1lLCBzdGFuZGFyZE5hbWUpO1xuXG4gICAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWlzUmVzZXJ2ZWQgJiYgbmFtZSAhPT0gbG93ZXJDYXNlZE5hbWUpIHtcbiAgICAgIC8vIFVua25vd24gYXR0cmlidXRlcyBzaG91bGQgaGF2ZSBsb3dlcmNhc2UgY2FzaW5nIHNpbmNlIHRoYXQncyBob3cgdGhleVxuICAgICAgLy8gd2lsbCBiZSBjYXNlZCBhbnl3YXkgd2l0aCBzZXJ2ZXIgcmVuZGVyaW5nLlxuICAgICAgZXJyb3IoJ1JlYWN0IGRvZXMgbm90IHJlY29nbml6ZSB0aGUgYCVzYCBwcm9wIG9uIGEgRE9NIGVsZW1lbnQuIElmIHlvdSAnICsgJ2ludGVudGlvbmFsbHkgd2FudCBpdCB0byBhcHBlYXIgaW4gdGhlIERPTSBhcyBhIGN1c3RvbSAnICsgJ2F0dHJpYnV0ZSwgc3BlbGwgaXQgYXMgbG93ZXJjYXNlIGAlc2AgaW5zdGVhZC4gJyArICdJZiB5b3UgYWNjaWRlbnRhbGx5IHBhc3NlZCBpdCBmcm9tIGEgcGFyZW50IGNvbXBvbmVudCwgcmVtb3ZlICcgKyAnaXQgZnJvbSB0aGUgRE9NIGVsZW1lbnQuJywgbmFtZSwgbG93ZXJDYXNlZE5hbWUpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nICYmIHNob3VsZFJlbW92ZUF0dHJpYnV0ZVdpdGhXYXJuaW5nKG5hbWUsIHZhbHVlLCBwcm9wZXJ0eUluZm8sIGZhbHNlKSkge1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGVycm9yKCdSZWNlaXZlZCBgJXNgIGZvciBhIG5vbi1ib29sZWFuIGF0dHJpYnV0ZSBgJXNgLlxcblxcbicgKyAnSWYgeW91IHdhbnQgdG8gd3JpdGUgaXQgdG8gdGhlIERPTSwgcGFzcyBhIHN0cmluZyBpbnN0ZWFkOiAnICsgJyVzPVwiJXNcIiBvciAlcz17dmFsdWUudG9TdHJpbmcoKX0uJywgdmFsdWUsIG5hbWUsIG5hbWUsIHZhbHVlLCBuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCdSZWNlaXZlZCBgJXNgIGZvciBhIG5vbi1ib29sZWFuIGF0dHJpYnV0ZSBgJXNgLlxcblxcbicgKyAnSWYgeW91IHdhbnQgdG8gd3JpdGUgaXQgdG8gdGhlIERPTSwgcGFzcyBhIHN0cmluZyBpbnN0ZWFkOiAnICsgJyVzPVwiJXNcIiBvciAlcz17dmFsdWUudG9TdHJpbmcoKX0uXFxuXFxuJyArICdJZiB5b3UgdXNlZCB0byBjb25kaXRpb25hbGx5IG9taXQgaXQgd2l0aCAlcz17Y29uZGl0aW9uICYmIHZhbHVlfSwgJyArICdwYXNzICVzPXtjb25kaXRpb24gPyB2YWx1ZSA6IHVuZGVmaW5lZH0gaW5zdGVhZC4nLCB2YWx1ZSwgbmFtZSwgbmFtZSwgdmFsdWUsIG5hbWUsIG5hbWUsIG5hbWUpO1xuICAgICAgfVxuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSAvLyBOb3cgdGhhdCB3ZSd2ZSB2YWxpZGF0ZWQgY2FzaW5nLCBkbyBub3QgdmFsaWRhdGVcbiAgICAvLyBkYXRhIHR5cGVzIGZvciByZXNlcnZlZCBwcm9wc1xuXG5cbiAgICBpZiAoaXNSZXNlcnZlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSAvLyBXYXJuIHdoZW4gYSBrbm93biBhdHRyaWJ1dGUgaXMgYSBiYWQgdHlwZVxuXG5cbiAgICBpZiAoc2hvdWxkUmVtb3ZlQXR0cmlidXRlV2l0aFdhcm5pbmcobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgZmFsc2UpKSB7XG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gLy8gV2FybiB3aGVuIHBhc3NpbmcgdGhlIHN0cmluZ3MgJ2ZhbHNlJyBvciAndHJ1ZScgaW50byBhIGJvb2xlYW4gcHJvcFxuXG5cbiAgICBpZiAoKHZhbHVlID09PSAnZmFsc2UnIHx8IHZhbHVlID09PSAndHJ1ZScpICYmIHByb3BlcnR5SW5mbyAhPT0gbnVsbCAmJiBwcm9wZXJ0eUluZm8udHlwZSA9PT0gQk9PTEVBTikge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIHRoZSBzdHJpbmcgYCVzYCBmb3IgdGhlIGJvb2xlYW4gYXR0cmlidXRlIGAlc2AuICcgKyAnJXMgJyArICdEaWQgeW91IG1lYW4gJXM9eyVzfT8nLCB2YWx1ZSwgbmFtZSwgdmFsdWUgPT09ICdmYWxzZScgPyAnVGhlIGJyb3dzZXIgd2lsbCBpbnRlcnByZXQgaXQgYXMgYSB0cnV0aHkgdmFsdWUuJyA6ICdBbHRob3VnaCB0aGlzIHdvcmtzLCBpdCB3aWxsIG5vdCB3b3JrIGFzIGV4cGVjdGVkIGlmIHlvdSBwYXNzIHRoZSBzdHJpbmcgXCJmYWxzZVwiLicsIG5hbWUsIHZhbHVlKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufVxuXG52YXIgd2FyblVua25vd25Qcm9wZXJ0aWVzID0gZnVuY3Rpb24gKHR5cGUsIHByb3BzLCBldmVudFJlZ2lzdHJ5KSB7XG4gIHtcbiAgICB2YXIgdW5rbm93blByb3BzID0gW107XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHtcbiAgICAgIHZhciBpc1ZhbGlkID0gdmFsaWRhdGVQcm9wZXJ0eSQxKHR5cGUsIGtleSwgcHJvcHNba2V5XSwgZXZlbnRSZWdpc3RyeSk7XG5cbiAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICB1bmtub3duUHJvcHMucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciB1bmtub3duUHJvcFN0cmluZyA9IHVua25vd25Qcm9wcy5tYXAoZnVuY3Rpb24gKHByb3ApIHtcbiAgICAgIHJldHVybiAnYCcgKyBwcm9wICsgJ2AnO1xuICAgIH0pLmpvaW4oJywgJyk7XG5cbiAgICBpZiAodW5rbm93blByb3BzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgZXJyb3IoJ0ludmFsaWQgdmFsdWUgZm9yIHByb3AgJXMgb24gPCVzPiB0YWcuIEVpdGhlciByZW1vdmUgaXQgZnJvbSB0aGUgZWxlbWVudCwgJyArICdvciBwYXNzIGEgc3RyaW5nIG9yIG51bWJlciB2YWx1ZSB0byBrZWVwIGl0IGluIHRoZSBET00uICcgKyAnRm9yIGRldGFpbHMsIHNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvYXR0cmlidXRlLWJlaGF2aW9yICcsIHVua25vd25Qcm9wU3RyaW5nLCB0eXBlKTtcbiAgICB9IGVsc2UgaWYgKHVua25vd25Qcm9wcy5sZW5ndGggPiAxKSB7XG4gICAgICBlcnJvcignSW52YWxpZCB2YWx1ZXMgZm9yIHByb3BzICVzIG9uIDwlcz4gdGFnLiBFaXRoZXIgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgZWxlbWVudCwgJyArICdvciBwYXNzIGEgc3RyaW5nIG9yIG51bWJlciB2YWx1ZSB0byBrZWVwIHRoZW0gaW4gdGhlIERPTS4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9hdHRyaWJ1dGUtYmVoYXZpb3IgJywgdW5rbm93blByb3BTdHJpbmcsIHR5cGUpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gdmFsaWRhdGVQcm9wZXJ0aWVzJDIodHlwZSwgcHJvcHMsIGV2ZW50UmVnaXN0cnkpIHtcbiAgaWYgKGlzQ3VzdG9tQ29tcG9uZW50KHR5cGUsIHByb3BzKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHdhcm5Vbmtub3duUHJvcGVydGllcyh0eXBlLCBwcm9wcywgZXZlbnRSZWdpc3RyeSk7XG59XG5cbnZhciBJU19FVkVOVF9IQU5ETEVfTk9OX01BTkFHRURfTk9ERSA9IDE7XG52YXIgSVNfTk9OX0RFTEVHQVRFRCA9IDEgPDwgMTtcbnZhciBJU19DQVBUVVJFX1BIQVNFID0gMSA8PCAyO1xuLy8gc2V0IHRvIExFR0FDWV9GQl9TVVBQT1JULiBMRUdBQ1lfRkJfU1VQUE9SVCBvbmx5IGdldHMgc2V0IHdoZW5cbi8vIHdlIGNhbGwgd2lsbERlZmVyTGF0ZXJGb3JMZWdhY3lGQlN1cHBvcnQsIHRodXMgbm90IGJhaWxpbmcgb3V0XG4vLyB3aWxsIHJlc3VsdCBpbiBlbmRsZXNzIGN5Y2xlcyBsaWtlIGFuIGluZmluaXRlIGxvb3AuXG4vLyBXZSBhbHNvIGRvbid0IHdhbnQgdG8gZGVmZXIgZHVyaW5nIGV2ZW50IHJlcGxheWluZy5cblxudmFyIFNIT1VMRF9OT1RfUFJPQ0VTU19QT0xZRklMTF9FVkVOVF9QTFVHSU5TID0gSVNfRVZFTlRfSEFORExFX05PTl9NQU5BR0VEX05PREUgfCBJU19OT05fREVMRUdBVEVEIHwgSVNfQ0FQVFVSRV9QSEFTRTtcblxuLy8gVGhpcyBleGlzdHMgdG8gYXZvaWQgY2lyY3VsYXIgZGVwZW5kZW5jeSBiZXR3ZWVuIFJlYWN0RE9NRXZlbnRSZXBsYXlpbmdcbi8vIGFuZCBET01QbHVnaW5FdmVudFN5c3RlbS5cbnZhciBjdXJyZW50UmVwbGF5aW5nRXZlbnQgPSBudWxsO1xuZnVuY3Rpb24gc2V0UmVwbGF5aW5nRXZlbnQoZXZlbnQpIHtcbiAge1xuICAgIGlmIChjdXJyZW50UmVwbGF5aW5nRXZlbnQgIT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCBjdXJyZW50bHkgcmVwbGF5aW5nIGV2ZW50IHRvIGJlIG51bGwuIFRoaXMgZXJyb3IgJyArICdpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cblxuICBjdXJyZW50UmVwbGF5aW5nRXZlbnQgPSBldmVudDtcbn1cbmZ1bmN0aW9uIHJlc2V0UmVwbGF5aW5nRXZlbnQoKSB7XG4gIHtcbiAgICBpZiAoY3VycmVudFJlcGxheWluZ0V2ZW50ID09PSBudWxsKSB7XG4gICAgICBlcnJvcignRXhwZWN0ZWQgY3VycmVudGx5IHJlcGxheWluZyBldmVudCB0byBub3QgYmUgbnVsbC4gVGhpcyBlcnJvciAnICsgJ2lzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGN1cnJlbnRSZXBsYXlpbmdFdmVudCA9IG51bGw7XG59XG5mdW5jdGlvbiBpc1JlcGxheWluZ0V2ZW50KGV2ZW50KSB7XG4gIHJldHVybiBldmVudCA9PT0gY3VycmVudFJlcGxheWluZ0V2ZW50O1xufVxuXG4vKipcbiAqIEdldHMgdGhlIHRhcmdldCBub2RlIGZyb20gYSBuYXRpdmUgYnJvd3NlciBldmVudCBieSBhY2NvdW50aW5nIGZvclxuICogaW5jb25zaXN0ZW5jaWVzIGluIGJyb3dzZXIgRE9NIEFQSXMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7RE9NRXZlbnRUYXJnZXR9IFRhcmdldCBub2RlLlxuICovXG5cbmZ1bmN0aW9uIGdldEV2ZW50VGFyZ2V0KG5hdGl2ZUV2ZW50KSB7XG4gIC8vIEZhbGxiYWNrIHRvIG5hdGl2ZUV2ZW50LnNyY0VsZW1lbnQgZm9yIElFOVxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEyNTA2XG4gIHZhciB0YXJnZXQgPSBuYXRpdmVFdmVudC50YXJnZXQgfHwgbmF0aXZlRXZlbnQuc3JjRWxlbWVudCB8fCB3aW5kb3c7IC8vIE5vcm1hbGl6ZSBTVkcgPHVzZT4gZWxlbWVudCBldmVudHMgIzQ5NjNcblxuICBpZiAodGFyZ2V0LmNvcnJlc3BvbmRpbmdVc2VFbGVtZW50KSB7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0LmNvcnJlc3BvbmRpbmdVc2VFbGVtZW50O1xuICB9IC8vIFNhZmFyaSBtYXkgZmlyZSBldmVudHMgb24gdGV4dCBub2RlcyAoTm9kZS5URVhUX05PREUgaXMgMykuXG4gIC8vIEBzZWUgaHR0cDovL3d3dy5xdWlya3Ntb2RlLm9yZy9qcy9ldmVudHNfcHJvcGVydGllcy5odG1sXG5cblxuICByZXR1cm4gdGFyZ2V0Lm5vZGVUeXBlID09PSBURVhUX05PREUgPyB0YXJnZXQucGFyZW50Tm9kZSA6IHRhcmdldDtcbn1cblxudmFyIHJlc3RvcmVJbXBsID0gbnVsbDtcbnZhciByZXN0b3JlVGFyZ2V0ID0gbnVsbDtcbnZhciByZXN0b3JlUXVldWUgPSBudWxsO1xuXG5mdW5jdGlvbiByZXN0b3JlU3RhdGVPZlRhcmdldCh0YXJnZXQpIHtcbiAgLy8gV2UgcGVyZm9ybSB0aGlzIHRyYW5zbGF0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGV2ZW50IGxvb3Agc28gdGhhdCB3ZVxuICAvLyBhbHdheXMgcmVjZWl2ZSB0aGUgY29ycmVjdCBmaWJlciBoZXJlXG4gIHZhciBpbnRlcm5hbEluc3RhbmNlID0gZ2V0SW5zdGFuY2VGcm9tTm9kZSh0YXJnZXQpO1xuXG4gIGlmICghaW50ZXJuYWxJbnN0YW5jZSkge1xuICAgIC8vIFVubW91bnRlZFxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcmVzdG9yZUltcGwgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFJlc3RvcmVJbXBsZW1lbnRhdGlvbigpIG5lZWRzIHRvIGJlIGNhbGxlZCB0byBoYW5kbGUgYSB0YXJnZXQgZm9yIGNvbnRyb2xsZWQgJyArICdldmVudHMuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cblxuICB2YXIgc3RhdGVOb2RlID0gaW50ZXJuYWxJbnN0YW5jZS5zdGF0ZU5vZGU7IC8vIEd1YXJkIGFnYWluc3QgRmliZXIgYmVpbmcgdW5tb3VudGVkLlxuXG4gIGlmIChzdGF0ZU5vZGUpIHtcbiAgICB2YXIgX3Byb3BzID0gZ2V0RmliZXJDdXJyZW50UHJvcHNGcm9tTm9kZShzdGF0ZU5vZGUpO1xuXG4gICAgcmVzdG9yZUltcGwoaW50ZXJuYWxJbnN0YW5jZS5zdGF0ZU5vZGUsIGludGVybmFsSW5zdGFuY2UudHlwZSwgX3Byb3BzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRSZXN0b3JlSW1wbGVtZW50YXRpb24oaW1wbCkge1xuICByZXN0b3JlSW1wbCA9IGltcGw7XG59XG5mdW5jdGlvbiBlbnF1ZXVlU3RhdGVSZXN0b3JlKHRhcmdldCkge1xuICBpZiAocmVzdG9yZVRhcmdldCkge1xuICAgIGlmIChyZXN0b3JlUXVldWUpIHtcbiAgICAgIHJlc3RvcmVRdWV1ZS5wdXNoKHRhcmdldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3RvcmVRdWV1ZSA9IFt0YXJnZXRdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXN0b3JlVGFyZ2V0ID0gdGFyZ2V0O1xuICB9XG59XG5mdW5jdGlvbiBuZWVkc1N0YXRlUmVzdG9yZSgpIHtcbiAgcmV0dXJuIHJlc3RvcmVUYXJnZXQgIT09IG51bGwgfHwgcmVzdG9yZVF1ZXVlICE9PSBudWxsO1xufVxuZnVuY3Rpb24gcmVzdG9yZVN0YXRlSWZOZWVkZWQoKSB7XG4gIGlmICghcmVzdG9yZVRhcmdldCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB0YXJnZXQgPSByZXN0b3JlVGFyZ2V0O1xuICB2YXIgcXVldWVkVGFyZ2V0cyA9IHJlc3RvcmVRdWV1ZTtcbiAgcmVzdG9yZVRhcmdldCA9IG51bGw7XG4gIHJlc3RvcmVRdWV1ZSA9IG51bGw7XG4gIHJlc3RvcmVTdGF0ZU9mVGFyZ2V0KHRhcmdldCk7XG5cbiAgaWYgKHF1ZXVlZFRhcmdldHMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlZFRhcmdldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3RvcmVTdGF0ZU9mVGFyZ2V0KHF1ZXVlZFRhcmdldHNbaV0pO1xuICAgIH1cbiAgfVxufVxuXG4vLyB0aGUgcmVuZGVyZXIuIFN1Y2ggYXMgd2hlbiB3ZSdyZSBkaXNwYXRjaGluZyBldmVudHMgb3IgaWYgdGhpcmQgcGFydHlcbi8vIGxpYnJhcmllcyBuZWVkIHRvIGNhbGwgYmF0Y2hlZFVwZGF0ZXMuIEV2ZW50dWFsbHksIHRoaXMgQVBJIHdpbGwgZ28gYXdheSB3aGVuXG4vLyBldmVyeXRoaW5nIGlzIGJhdGNoZWQgYnkgZGVmYXVsdC4gV2UnbGwgdGhlbiBoYXZlIGEgc2ltaWxhciBBUEkgdG8gb3B0LW91dCBvZlxuLy8gc2NoZWR1bGVkIHdvcmsgYW5kIGluc3RlYWQgZG8gc3luY2hyb25vdXMgd29yay5cbi8vIERlZmF1bHRzXG5cbnZhciBiYXRjaGVkVXBkYXRlc0ltcGwgPSBmdW5jdGlvbiAoZm4sIGJvb2trZWVwaW5nKSB7XG4gIHJldHVybiBmbihib29ra2VlcGluZyk7XG59O1xuXG52YXIgZmx1c2hTeW5jSW1wbCA9IGZ1bmN0aW9uICgpIHt9O1xuXG52YXIgaXNJbnNpZGVFdmVudEhhbmRsZXIgPSBmYWxzZTtcblxuZnVuY3Rpb24gZmluaXNoRXZlbnRIYW5kbGVyKCkge1xuICAvLyBIZXJlIHdlIHdhaXQgdW50aWwgYWxsIHVwZGF0ZXMgaGF2ZSBwcm9wYWdhdGVkLCB3aGljaCBpcyBpbXBvcnRhbnRcbiAgLy8gd2hlbiB1c2luZyBjb250cm9sbGVkIGNvbXBvbmVudHMgd2l0aGluIGxheWVyczpcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xNjk4XG4gIC8vIFRoZW4gd2UgcmVzdG9yZSBzdGF0ZSBvZiBhbnkgY29udHJvbGxlZCBjb21wb25lbnQuXG4gIHZhciBjb250cm9sbGVkQ29tcG9uZW50c0hhdmVQZW5kaW5nVXBkYXRlcyA9IG5lZWRzU3RhdGVSZXN0b3JlKCk7XG5cbiAgaWYgKGNvbnRyb2xsZWRDb21wb25lbnRzSGF2ZVBlbmRpbmdVcGRhdGVzKSB7XG4gICAgLy8gSWYgYSBjb250cm9sbGVkIGV2ZW50IHdhcyBmaXJlZCwgd2UgbWF5IG5lZWQgdG8gcmVzdG9yZSB0aGUgc3RhdGUgb2ZcbiAgICAvLyB0aGUgRE9NIG5vZGUgYmFjayB0byB0aGUgY29udHJvbGxlZCB2YWx1ZS4gVGhpcyBpcyBuZWNlc3Nhcnkgd2hlbiBSZWFjdFxuICAgIC8vIGJhaWxzIG91dCBvZiB0aGUgdXBkYXRlIHdpdGhvdXQgdG91Y2hpbmcgdGhlIERPTS5cbiAgICAvLyBUT0RPOiBSZXN0b3JlIHN0YXRlIGluIHRoZSBtaWNyb3Rhc2ssIGFmdGVyIHRoZSBkaXNjcmV0ZSB1cGRhdGVzIGZsdXNoLFxuICAgIC8vIGluc3RlYWQgb2YgZWFybHkgZmx1c2hpbmcgdGhlbSBoZXJlLlxuICAgIGZsdXNoU3luY0ltcGwoKTtcbiAgICByZXN0b3JlU3RhdGVJZk5lZWRlZCgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJhdGNoZWRVcGRhdGVzKGZuLCBhLCBiKSB7XG4gIGlmIChpc0luc2lkZUV2ZW50SGFuZGxlcikge1xuICAgIC8vIElmIHdlIGFyZSBjdXJyZW50bHkgaW5zaWRlIGFub3RoZXIgYmF0Y2gsIHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdFxuICAgIC8vIGZ1bGx5IGNvbXBsZXRlcyBiZWZvcmUgcmVzdG9yaW5nIHN0YXRlLlxuICAgIHJldHVybiBmbihhLCBiKTtcbiAgfVxuXG4gIGlzSW5zaWRlRXZlbnRIYW5kbGVyID0gdHJ1ZTtcblxuICB0cnkge1xuICAgIHJldHVybiBiYXRjaGVkVXBkYXRlc0ltcGwoZm4sIGEsIGIpO1xuICB9IGZpbmFsbHkge1xuICAgIGlzSW5zaWRlRXZlbnRIYW5kbGVyID0gZmFsc2U7XG4gICAgZmluaXNoRXZlbnRIYW5kbGVyKCk7XG4gIH1cbn0gLy8gVE9ETzogUmVwbGFjZSB3aXRoIGZsdXNoU3luY1xuZnVuY3Rpb24gc2V0QmF0Y2hpbmdJbXBsZW1lbnRhdGlvbihfYmF0Y2hlZFVwZGF0ZXNJbXBsLCBfZGlzY3JldGVVcGRhdGVzSW1wbCwgX2ZsdXNoU3luY0ltcGwpIHtcbiAgYmF0Y2hlZFVwZGF0ZXNJbXBsID0gX2JhdGNoZWRVcGRhdGVzSW1wbDtcbiAgZmx1c2hTeW5jSW1wbCA9IF9mbHVzaFN5bmNJbXBsO1xufVxuXG5mdW5jdGlvbiBpc0ludGVyYWN0aXZlKHRhZykge1xuICByZXR1cm4gdGFnID09PSAnYnV0dG9uJyB8fCB0YWcgPT09ICdpbnB1dCcgfHwgdGFnID09PSAnc2VsZWN0JyB8fCB0YWcgPT09ICd0ZXh0YXJlYSc7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFByZXZlbnRNb3VzZUV2ZW50KG5hbWUsIHR5cGUsIHByb3BzKSB7XG4gIHN3aXRjaCAobmFtZSkge1xuICAgIGNhc2UgJ29uQ2xpY2snOlxuICAgIGNhc2UgJ29uQ2xpY2tDYXB0dXJlJzpcbiAgICBjYXNlICdvbkRvdWJsZUNsaWNrJzpcbiAgICBjYXNlICdvbkRvdWJsZUNsaWNrQ2FwdHVyZSc6XG4gICAgY2FzZSAnb25Nb3VzZURvd24nOlxuICAgIGNhc2UgJ29uTW91c2VEb3duQ2FwdHVyZSc6XG4gICAgY2FzZSAnb25Nb3VzZU1vdmUnOlxuICAgIGNhc2UgJ29uTW91c2VNb3ZlQ2FwdHVyZSc6XG4gICAgY2FzZSAnb25Nb3VzZVVwJzpcbiAgICBjYXNlICdvbk1vdXNlVXBDYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlRW50ZXInOlxuICAgICAgcmV0dXJuICEhKHByb3BzLmRpc2FibGVkICYmIGlzSW50ZXJhY3RpdmUodHlwZSkpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gaW5zdCBUaGUgaW5zdGFuY2UsIHdoaWNoIGlzIHRoZSBzb3VyY2Ugb2YgZXZlbnRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZ2lzdHJhdGlvbk5hbWUgTmFtZSBvZiBsaXN0ZW5lciAoZS5nLiBgb25DbGlja2ApLlxuICogQHJldHVybiB7P2Z1bmN0aW9ufSBUaGUgc3RvcmVkIGNhbGxiYWNrLlxuICovXG5cblxuZnVuY3Rpb24gZ2V0TGlzdGVuZXIoaW5zdCwgcmVnaXN0cmF0aW9uTmFtZSkge1xuICB2YXIgc3RhdGVOb2RlID0gaW5zdC5zdGF0ZU5vZGU7XG5cbiAgaWYgKHN0YXRlTm9kZSA9PT0gbnVsbCkge1xuICAgIC8vIFdvcmsgaW4gcHJvZ3Jlc3MgKGV4OiBvbmxvYWQgZXZlbnRzIGluIGluY3JlbWVudGFsIG1vZGUpLlxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIHByb3BzID0gZ2V0RmliZXJDdXJyZW50UHJvcHNGcm9tTm9kZShzdGF0ZU5vZGUpO1xuXG4gIGlmIChwcm9wcyA9PT0gbnVsbCkge1xuICAgIC8vIFdvcmsgaW4gcHJvZ3Jlc3MuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbGlzdGVuZXIgPSBwcm9wc1tyZWdpc3RyYXRpb25OYW1lXTtcblxuICBpZiAoc2hvdWxkUHJldmVudE1vdXNlRXZlbnQocmVnaXN0cmF0aW9uTmFtZSwgaW5zdC50eXBlLCBwcm9wcykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChsaXN0ZW5lciAmJiB0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBgXCIgKyByZWdpc3RyYXRpb25OYW1lICsgXCJgIGxpc3RlbmVyIHRvIGJlIGEgZnVuY3Rpb24sIGluc3RlYWQgZ290IGEgdmFsdWUgb2YgYFwiICsgdHlwZW9mIGxpc3RlbmVyICsgXCJgIHR5cGUuXCIpO1xuICB9XG5cbiAgcmV0dXJuIGxpc3RlbmVyO1xufVxuXG52YXIgcGFzc2l2ZUJyb3dzZXJFdmVudHNTdXBwb3J0ZWQgPSBmYWxzZTsgLy8gQ2hlY2sgaWYgYnJvd3NlciBzdXBwb3J0IGV2ZW50cyB3aXRoIHBhc3NpdmUgbGlzdGVuZXJzXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciNTYWZlbHlfZGV0ZWN0aW5nX29wdGlvbl9zdXBwb3J0XG5cbmlmIChjYW5Vc2VET00pIHtcbiAgdHJ5IHtcbiAgICB2YXIgb3B0aW9ucyA9IHt9OyAvLyAkRmxvd0ZpeE1lOiBJZ25vcmUgRmxvdyBjb21wbGFpbmluZyBhYm91dCBuZWVkaW5nIGEgdmFsdWVcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvcHRpb25zLCAncGFzc2l2ZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICBwYXNzaXZlQnJvd3NlckV2ZW50c1N1cHBvcnRlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCBvcHRpb25zLCBvcHRpb25zKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigndGVzdCcsIG9wdGlvbnMsIG9wdGlvbnMpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcGFzc2l2ZUJyb3dzZXJFdmVudHNTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tQcm9kKG5hbWUsIGZ1bmMsIGNvbnRleHQsIGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgdmFyIGZ1bmNBcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAzKTtcblxuICB0cnkge1xuICAgIGZ1bmMuYXBwbHkoY29udGV4dCwgZnVuY0FyZ3MpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRoaXMub25FcnJvcihlcnJvcik7XG4gIH1cbn1cblxudmFyIGludm9rZUd1YXJkZWRDYWxsYmFja0ltcGwgPSBpbnZva2VHdWFyZGVkQ2FsbGJhY2tQcm9kO1xuXG57XG4gIC8vIEluIERFViBtb2RlLCB3ZSBzd2FwIG91dCBpbnZva2VHdWFyZGVkQ2FsbGJhY2sgZm9yIGEgc3BlY2lhbCB2ZXJzaW9uXG4gIC8vIHRoYXQgcGxheXMgbW9yZSBuaWNlbHkgd2l0aCB0aGUgYnJvd3NlcidzIERldlRvb2xzLiBUaGUgaWRlYSBpcyB0byBwcmVzZXJ2ZVxuICAvLyBcIlBhdXNlIG9uIGV4Y2VwdGlvbnNcIiBiZWhhdmlvci4gQmVjYXVzZSBSZWFjdCB3cmFwcyBhbGwgdXNlci1wcm92aWRlZFxuICAvLyBmdW5jdGlvbnMgaW4gaW52b2tlR3VhcmRlZENhbGxiYWNrLCBhbmQgdGhlIHByb2R1Y3Rpb24gdmVyc2lvbiBvZlxuICAvLyBpbnZva2VHdWFyZGVkQ2FsbGJhY2sgdXNlcyBhIHRyeS1jYXRjaCwgYWxsIHVzZXIgZXhjZXB0aW9ucyBhcmUgdHJlYXRlZFxuICAvLyBsaWtlIGNhdWdodCBleGNlcHRpb25zLCBhbmQgdGhlIERldlRvb2xzIHdvbid0IHBhdXNlIHVubGVzcyB0aGUgZGV2ZWxvcGVyXG4gIC8vIHRha2VzIHRoZSBleHRyYSBzdGVwIG9mIGVuYWJsaW5nIHBhdXNlIG9uIGNhdWdodCBleGNlcHRpb25zLiBUaGlzIGlzXG4gIC8vIHVuaW50dWl0aXZlLCB0aG91Z2gsIGJlY2F1c2UgZXZlbiB0aG91Z2ggUmVhY3QgaGFzIGNhdWdodCB0aGUgZXJyb3IsIGZyb21cbiAgLy8gdGhlIGRldmVsb3BlcidzIHBlcnNwZWN0aXZlLCB0aGUgZXJyb3IgaXMgdW5jYXVnaHQuXG4gIC8vXG4gIC8vIFRvIHByZXNlcnZlIHRoZSBleHBlY3RlZCBcIlBhdXNlIG9uIGV4Y2VwdGlvbnNcIiBiZWhhdmlvciwgd2UgZG9uJ3QgdXNlIGFcbiAgLy8gdHJ5LWNhdGNoIGluIERFVi4gSW5zdGVhZCwgd2Ugc3luY2hyb25vdXNseSBkaXNwYXRjaCBhIGZha2UgZXZlbnQgdG8gYSBmYWtlXG4gIC8vIERPTSBub2RlLCBhbmQgY2FsbCB0aGUgdXNlci1wcm92aWRlZCBjYWxsYmFjayBmcm9tIGluc2lkZSBhbiBldmVudCBoYW5kbGVyXG4gIC8vIGZvciB0aGF0IGZha2UgZXZlbnQuIElmIHRoZSBjYWxsYmFjayB0aHJvd3MsIHRoZSBlcnJvciBpcyBcImNhcHR1cmVkXCIgdXNpbmdcbiAgLy8gYSBnbG9iYWwgZXZlbnQgaGFuZGxlci4gQnV0IGJlY2F1c2UgdGhlIGVycm9yIGhhcHBlbnMgaW4gYSBkaWZmZXJlbnRcbiAgLy8gZXZlbnQgbG9vcCBjb250ZXh0LCBpdCBkb2VzIG5vdCBpbnRlcnJ1cHQgdGhlIG5vcm1hbCBwcm9ncmFtIGZsb3cuXG4gIC8vIEVmZmVjdGl2ZWx5LCB0aGlzIGdpdmVzIHVzIHRyeS1jYXRjaCBiZWhhdmlvciB3aXRob3V0IGFjdHVhbGx5IHVzaW5nXG4gIC8vIHRyeS1jYXRjaC4gTmVhdCFcbiAgLy8gQ2hlY2sgdGhhdCB0aGUgYnJvd3NlciBzdXBwb3J0cyB0aGUgQVBJcyB3ZSBuZWVkIHRvIGltcGxlbWVudCBvdXIgc3BlY2lhbFxuICAvLyBERVYgdmVyc2lvbiBvZiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tcbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZGlzcGF0Y2hFdmVudCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciBmYWtlTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3JlYWN0Jyk7XG5cbiAgICBpbnZva2VHdWFyZGVkQ2FsbGJhY2tJbXBsID0gZnVuY3Rpb24gaW52b2tlR3VhcmRlZENhbGxiYWNrRGV2KG5hbWUsIGZ1bmMsIGNvbnRleHQsIGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICAgIC8vIElmIGRvY3VtZW50IGRvZXNuJ3QgZXhpc3Qgd2Uga25vdyBmb3Igc3VyZSB3ZSB3aWxsIGNyYXNoIGluIHRoaXMgbWV0aG9kXG4gICAgICAvLyB3aGVuIHdlIGNhbGwgZG9jdW1lbnQuY3JlYXRlRXZlbnQoKS4gSG93ZXZlciB0aGlzIGNhbiBjYXVzZSBjb25mdXNpbmdcbiAgICAgIC8vIGVycm9yczogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2NyZWF0ZS1yZWFjdC1hcHAvaXNzdWVzLzM0ODJcbiAgICAgIC8vIFNvIHdlIHByZWVtcHRpdmVseSB0aHJvdyB3aXRoIGEgYmV0dGVyIG1lc3NhZ2UgaW5zdGVhZC5cbiAgICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8IGRvY3VtZW50ID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGBkb2N1bWVudGAgZ2xvYmFsIHdhcyBkZWZpbmVkIHdoZW4gUmVhY3Qgd2FzIGluaXRpYWxpemVkLCBidXQgaXMgbm90ICcgKyAnZGVmaW5lZCBhbnltb3JlLiBUaGlzIGNhbiBoYXBwZW4gaW4gYSB0ZXN0IGVudmlyb25tZW50IGlmIGEgY29tcG9uZW50ICcgKyAnc2NoZWR1bGVzIGFuIHVwZGF0ZSBmcm9tIGFuIGFzeW5jaHJvbm91cyBjYWxsYmFjaywgYnV0IHRoZSB0ZXN0IGhhcyBhbHJlYWR5ICcgKyAnZmluaXNoZWQgcnVubmluZy4gVG8gc29sdmUgdGhpcywgeW91IGNhbiBlaXRoZXIgdW5tb3VudCB0aGUgY29tcG9uZW50IGF0ICcgKyAndGhlIGVuZCBvZiB5b3VyIHRlc3QgKGFuZCBlbnN1cmUgdGhhdCBhbnkgYXN5bmNocm9ub3VzIG9wZXJhdGlvbnMgZ2V0ICcgKyAnY2FuY2VsZWQgaW4gYGNvbXBvbmVudFdpbGxVbm1vdW50YCksIG9yIHlvdSBjYW4gY2hhbmdlIHRoZSB0ZXN0IGl0c2VsZiAnICsgJ3RvIGJlIGFzeW5jaHJvbm91cy4nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgICAgdmFyIGRpZENhbGwgPSBmYWxzZTsgLy8gS2VlcHMgdHJhY2sgb2Ygd2hldGhlciB0aGUgdXNlci1wcm92aWRlZCBjYWxsYmFjayB0aHJldyBhbiBlcnJvci4gV2VcbiAgICAgIC8vIHNldCB0aGlzIHRvIHRydWUgYXQgdGhlIGJlZ2lubmluZywgdGhlbiBzZXQgaXQgdG8gZmFsc2UgcmlnaHQgYWZ0ZXJcbiAgICAgIC8vIGNhbGxpbmcgdGhlIGZ1bmN0aW9uLiBJZiB0aGUgZnVuY3Rpb24gZXJyb3JzLCBgZGlkRXJyb3JgIHdpbGwgbmV2ZXIgYmVcbiAgICAgIC8vIHNldCB0byBmYWxzZS4gVGhpcyBzdHJhdGVneSB3b3JrcyBldmVuIGlmIHRoZSBicm93c2VyIGlzIGZsYWt5IGFuZFxuICAgICAgLy8gZmFpbHMgdG8gY2FsbCBvdXIgZ2xvYmFsIGVycm9yIGhhbmRsZXIsIGJlY2F1c2UgaXQgZG9lc24ndCByZWx5IG9uXG4gICAgICAvLyB0aGUgZXJyb3IgZXZlbnQgYXQgYWxsLlxuXG4gICAgICB2YXIgZGlkRXJyb3IgPSB0cnVlOyAvLyBLZWVwcyB0cmFjayBvZiB0aGUgdmFsdWUgb2Ygd2luZG93LmV2ZW50IHNvIHRoYXQgd2UgY2FuIHJlc2V0IGl0XG4gICAgICAvLyBkdXJpbmcgdGhlIGNhbGxiYWNrIHRvIGxldCB1c2VyIGNvZGUgYWNjZXNzIHdpbmRvdy5ldmVudCBpbiB0aGVcbiAgICAgIC8vIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBpdC5cblxuICAgICAgdmFyIHdpbmRvd0V2ZW50ID0gd2luZG93LmV2ZW50OyAvLyBLZWVwcyB0cmFjayBvZiB0aGUgZGVzY3JpcHRvciBvZiB3aW5kb3cuZXZlbnQgdG8gcmVzdG9yZSBpdCBhZnRlciBldmVudFxuICAgICAgLy8gZGlzcGF0Y2hpbmc6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTM2ODhcblxuICAgICAgdmFyIHdpbmRvd0V2ZW50RGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iod2luZG93LCAnZXZlbnQnKTtcblxuICAgICAgZnVuY3Rpb24gcmVzdG9yZUFmdGVyRGlzcGF0Y2goKSB7XG4gICAgICAgIC8vIFdlIGltbWVkaWF0ZWx5IHJlbW92ZSB0aGUgY2FsbGJhY2sgZnJvbSBldmVudCBsaXN0ZW5lcnMgc28gdGhhdFxuICAgICAgICAvLyBuZXN0ZWQgYGludm9rZUd1YXJkZWRDYWxsYmFja2AgY2FsbHMgZG8gbm90IGNsYXNoLiBPdGhlcndpc2UsIGFcbiAgICAgICAgLy8gbmVzdGVkIGNhbGwgd291bGQgdHJpZ2dlciB0aGUgZmFrZSBldmVudCBoYW5kbGVycyBvZiBhbnkgY2FsbCBoaWdoZXJcbiAgICAgICAgLy8gaW4gdGhlIHN0YWNrLlxuICAgICAgICBmYWtlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGV2dFR5cGUsIGNhbGxDYWxsYmFjaywgZmFsc2UpOyAvLyBXZSBjaGVjayBmb3Igd2luZG93Lmhhc093blByb3BlcnR5KCdldmVudCcpIHRvIHByZXZlbnQgdGhlXG4gICAgICAgIC8vIHdpbmRvdy5ldmVudCBhc3NpZ25tZW50IGluIGJvdGggSUUgPD0gMTAgYXMgdGhleSB0aHJvdyBhbiBlcnJvclxuICAgICAgICAvLyBcIk1lbWJlciBub3QgZm91bmRcIiBpbiBzdHJpY3QgbW9kZSwgYW5kIGluIEZpcmVmb3ggd2hpY2ggZG9lcyBub3RcbiAgICAgICAgLy8gc3VwcG9ydCB3aW5kb3cuZXZlbnQuXG5cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuZXZlbnQgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnZXZlbnQnKSkge1xuICAgICAgICAgIHdpbmRvdy5ldmVudCA9IHdpbmRvd0V2ZW50O1xuICAgICAgICB9XG4gICAgICB9IC8vIENyZWF0ZSBhbiBldmVudCBoYW5kbGVyIGZvciBvdXIgZmFrZSBldmVudC4gV2Ugd2lsbCBzeW5jaHJvbm91c2x5XG4gICAgICAvLyBkaXNwYXRjaCBvdXIgZmFrZSBldmVudCB1c2luZyBgZGlzcGF0Y2hFdmVudGAuIEluc2lkZSB0aGUgaGFuZGxlciwgd2VcbiAgICAgIC8vIGNhbGwgdGhlIHVzZXItcHJvdmlkZWQgY2FsbGJhY2suXG5cblxuICAgICAgdmFyIGZ1bmNBcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAzKTtcblxuICAgICAgZnVuY3Rpb24gY2FsbENhbGxiYWNrKCkge1xuICAgICAgICBkaWRDYWxsID0gdHJ1ZTtcbiAgICAgICAgcmVzdG9yZUFmdGVyRGlzcGF0Y2goKTtcbiAgICAgICAgZnVuYy5hcHBseShjb250ZXh0LCBmdW5jQXJncyk7XG4gICAgICAgIGRpZEVycm9yID0gZmFsc2U7XG4gICAgICB9IC8vIENyZWF0ZSBhIGdsb2JhbCBlcnJvciBldmVudCBoYW5kbGVyLiBXZSB1c2UgdGhpcyB0byBjYXB0dXJlIHRoZSB2YWx1ZVxuICAgICAgLy8gdGhhdCB3YXMgdGhyb3duLiBJdCdzIHBvc3NpYmxlIHRoYXQgdGhpcyBlcnJvciBoYW5kbGVyIHdpbGwgZmlyZSBtb3JlXG4gICAgICAvLyB0aGFuIG9uY2U7IGZvciBleGFtcGxlLCBpZiBub24tUmVhY3QgY29kZSBhbHNvIGNhbGxzIGBkaXNwYXRjaEV2ZW50YFxuICAgICAgLy8gYW5kIGEgaGFuZGxlciBmb3IgdGhhdCBldmVudCB0aHJvd3MuIFdlIHNob3VsZCBiZSByZXNpbGllbnQgdG8gbW9zdCBvZlxuICAgICAgLy8gdGhvc2UgY2FzZXMuIEV2ZW4gaWYgb3VyIGVycm9yIGV2ZW50IGhhbmRsZXIgZmlyZXMgbW9yZSB0aGFuIG9uY2UsIHRoZVxuICAgICAgLy8gbGFzdCBlcnJvciBldmVudCBpcyBhbHdheXMgdXNlZC4gSWYgdGhlIGNhbGxiYWNrIGFjdHVhbGx5IGRvZXMgZXJyb3IsXG4gICAgICAvLyB3ZSBrbm93IHRoYXQgdGhlIGxhc3QgZXJyb3IgZXZlbnQgaXMgdGhlIGNvcnJlY3Qgb25lLCBiZWNhdXNlIGl0J3Mgbm90XG4gICAgICAvLyBwb3NzaWJsZSBmb3IgYW55dGhpbmcgZWxzZSB0byBoYXZlIGhhcHBlbmVkIGluIGJldHdlZW4gb3VyIGNhbGxiYWNrXG4gICAgICAvLyBlcnJvcmluZyBhbmQgdGhlIGNvZGUgdGhhdCBmb2xsb3dzIHRoZSBgZGlzcGF0Y2hFdmVudGAgY2FsbCBiZWxvdy4gSWZcbiAgICAgIC8vIHRoZSBjYWxsYmFjayBkb2Vzbid0IGVycm9yLCBidXQgdGhlIGVycm9yIGV2ZW50IHdhcyBmaXJlZCwgd2Uga25vdyB0b1xuICAgICAgLy8gaWdub3JlIGl0IGJlY2F1c2UgYGRpZEVycm9yYCB3aWxsIGJlIGZhbHNlLCBhcyBkZXNjcmliZWQgYWJvdmUuXG5cblxuICAgICAgdmFyIGVycm9yOyAvLyBVc2UgdGhpcyB0byB0cmFjayB3aGV0aGVyIHRoZSBlcnJvciBldmVudCBpcyBldmVyIGNhbGxlZC5cblxuICAgICAgdmFyIGRpZFNldEVycm9yID0gZmFsc2U7XG4gICAgICB2YXIgaXNDcm9zc09yaWdpbkVycm9yID0gZmFsc2U7XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZVdpbmRvd0Vycm9yKGV2ZW50KSB7XG4gICAgICAgIGVycm9yID0gZXZlbnQuZXJyb3I7XG4gICAgICAgIGRpZFNldEVycm9yID0gdHJ1ZTtcblxuICAgICAgICBpZiAoZXJyb3IgPT09IG51bGwgJiYgZXZlbnQuY29sbm8gPT09IDAgJiYgZXZlbnQubGluZW5vID09PSAwKSB7XG4gICAgICAgICAgaXNDcm9zc09yaWdpbkVycm9yID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgLy8gU29tZSBvdGhlciBlcnJvciBoYW5kbGVyIGhhcyBwcmV2ZW50ZWQgZGVmYXVsdC5cbiAgICAgICAgICAvLyBCcm93c2VycyBzaWxlbmNlIHRoZSBlcnJvciByZXBvcnQgaWYgdGhpcyBoYXBwZW5zLlxuICAgICAgICAgIC8vIFdlJ2xsIHJlbWVtYmVyIHRoaXMgdG8gbGF0ZXIgZGVjaWRlIHdoZXRoZXIgdG8gbG9nIGl0IG9yIG5vdC5cbiAgICAgICAgICBpZiAoZXJyb3IgIT0gbnVsbCAmJiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBlcnJvci5fc3VwcHJlc3NMb2dnaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGlubmVyKSB7Ly8gSWdub3JlLlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSAvLyBDcmVhdGUgYSBmYWtlIGV2ZW50IHR5cGUuXG5cblxuICAgICAgdmFyIGV2dFR5cGUgPSBcInJlYWN0LVwiICsgKG5hbWUgPyBuYW1lIDogJ2ludm9rZWd1YXJkZWRjYWxsYmFjaycpOyAvLyBBdHRhY2ggb3VyIGV2ZW50IGhhbmRsZXJzXG5cbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIGhhbmRsZVdpbmRvd0Vycm9yKTtcbiAgICAgIGZha2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoZXZ0VHlwZSwgY2FsbENhbGxiYWNrLCBmYWxzZSk7IC8vIFN5bmNocm9ub3VzbHkgZGlzcGF0Y2ggb3VyIGZha2UgZXZlbnQuIElmIHRoZSB1c2VyLXByb3ZpZGVkIGZ1bmN0aW9uXG4gICAgICAvLyBlcnJvcnMsIGl0IHdpbGwgdHJpZ2dlciBvdXIgZ2xvYmFsIGVycm9yIGhhbmRsZXIuXG5cbiAgICAgIGV2dC5pbml0RXZlbnQoZXZ0VHlwZSwgZmFsc2UsIGZhbHNlKTtcbiAgICAgIGZha2VOb2RlLmRpc3BhdGNoRXZlbnQoZXZ0KTtcblxuICAgICAgaWYgKHdpbmRvd0V2ZW50RGVzY3JpcHRvcikge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnZXZlbnQnLCB3aW5kb3dFdmVudERlc2NyaXB0b3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGlkQ2FsbCAmJiBkaWRFcnJvcikge1xuICAgICAgICBpZiAoIWRpZFNldEVycm9yKSB7XG4gICAgICAgICAgLy8gVGhlIGNhbGxiYWNrIGVycm9yZWQsIGJ1dCB0aGUgZXJyb3IgZXZlbnQgbmV2ZXIgZmlyZWQuXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcbiAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcignQW4gZXJyb3Igd2FzIHRocm93biBpbnNpZGUgb25lIG9mIHlvdXIgY29tcG9uZW50cywgYnV0IFJlYWN0ICcgKyBcImRvZXNuJ3Qga25vdyB3aGF0IGl0IHdhcy4gVGhpcyBpcyBsaWtlbHkgZHVlIHRvIGJyb3dzZXIgXCIgKyAnZmxha2luZXNzLiBSZWFjdCBkb2VzIGl0cyBiZXN0IHRvIHByZXNlcnZlIHRoZSBcIlBhdXNlIG9uICcgKyAnZXhjZXB0aW9uc1wiIGJlaGF2aW9yIG9mIHRoZSBEZXZUb29scywgd2hpY2ggcmVxdWlyZXMgc29tZSAnICsgXCJERVYtbW9kZSBvbmx5IHRyaWNrcy4gSXQncyBwb3NzaWJsZSB0aGF0IHRoZXNlIGRvbid0IHdvcmsgaW4gXCIgKyAneW91ciBicm93c2VyLiBUcnkgdHJpZ2dlcmluZyB0aGUgZXJyb3IgaW4gcHJvZHVjdGlvbiBtb2RlLCAnICsgJ29yIHN3aXRjaGluZyB0byBhIG1vZGVybiBicm93c2VyLiBJZiB5b3Ugc3VzcGVjdCB0aGF0IHRoaXMgaXMgJyArICdhY3R1YWxseSBhbiBpc3N1ZSB3aXRoIFJlYWN0LCBwbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0Nyb3NzT3JpZ2luRXJyb3IpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKFwiQSBjcm9zcy1vcmlnaW4gZXJyb3Igd2FzIHRocm93bi4gUmVhY3QgZG9lc24ndCBoYXZlIGFjY2VzcyB0byBcIiArICd0aGUgYWN0dWFsIGVycm9yIG9iamVjdCBpbiBkZXZlbG9wbWVudC4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2Nyb3Nzb3JpZ2luLWVycm9yIGZvciBtb3JlIGluZm9ybWF0aW9uLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vbkVycm9yKGVycm9yKTtcbiAgICAgIH0gLy8gUmVtb3ZlIG91ciBldmVudCBsaXN0ZW5lcnNcblxuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZXJyb3InLCBoYW5kbGVXaW5kb3dFcnJvcik7XG5cbiAgICAgIGlmICghZGlkQ2FsbCkge1xuICAgICAgICAvLyBTb21ldGhpbmcgd2VudCByZWFsbHkgd3JvbmcsIGFuZCBvdXIgZXZlbnQgd2FzIG5vdCBkaXNwYXRjaGVkLlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE2NzM0XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTY1ODVcbiAgICAgICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBwcm9kdWN0aW9uIGltcGxlbWVudGF0aW9uLlxuICAgICAgICByZXN0b3JlQWZ0ZXJEaXNwYXRjaCgpO1xuICAgICAgICByZXR1cm4gaW52b2tlR3VhcmRlZENhbGxiYWNrUHJvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn1cblxudmFyIGludm9rZUd1YXJkZWRDYWxsYmFja0ltcGwkMSA9IGludm9rZUd1YXJkZWRDYWxsYmFja0ltcGw7XG5cbnZhciBoYXNFcnJvciA9IGZhbHNlO1xudmFyIGNhdWdodEVycm9yID0gbnVsbDsgLy8gVXNlZCBieSBldmVudCBzeXN0ZW0gdG8gY2FwdHVyZS9yZXRocm93IHRoZSBmaXJzdCBlcnJvci5cblxudmFyIGhhc1JldGhyb3dFcnJvciA9IGZhbHNlO1xudmFyIHJldGhyb3dFcnJvciA9IG51bGw7XG52YXIgcmVwb3J0ZXIgPSB7XG4gIG9uRXJyb3I6IGZ1bmN0aW9uIChlcnJvcikge1xuICAgIGhhc0Vycm9yID0gdHJ1ZTtcbiAgICBjYXVnaHRFcnJvciA9IGVycm9yO1xuICB9XG59O1xuLyoqXG4gKiBDYWxsIGEgZnVuY3Rpb24gd2hpbGUgZ3VhcmRpbmcgYWdhaW5zdCBlcnJvcnMgdGhhdCBoYXBwZW5zIHdpdGhpbiBpdC5cbiAqIFJldHVybnMgYW4gZXJyb3IgaWYgaXQgdGhyb3dzLCBvdGhlcndpc2UgbnVsbC5cbiAqXG4gKiBJbiBwcm9kdWN0aW9uLCB0aGlzIGlzIGltcGxlbWVudGVkIHVzaW5nIGEgdHJ5LWNhdGNoLiBUaGUgcmVhc29uIHdlIGRvbid0XG4gKiB1c2UgYSB0cnktY2F0Y2ggZGlyZWN0bHkgaXMgc28gdGhhdCB3ZSBjYW4gc3dhcCBvdXQgYSBkaWZmZXJlbnRcbiAqIGltcGxlbWVudGF0aW9uIGluIERFViBtb2RlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIHRoZSBndWFyZCB0byB1c2UgZm9yIGxvZ2dpbmcgb3IgZGVidWdnaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnZva2VcbiAqIEBwYXJhbSB7Kn0gY29udGV4dCBUaGUgY29udGV4dCB0byB1c2Ugd2hlbiBjYWxsaW5nIHRoZSBmdW5jdGlvblxuICogQHBhcmFtIHsuLi4qfSBhcmdzIEFyZ3VtZW50cyBmb3IgZnVuY3Rpb25cbiAqL1xuXG5mdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2sobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICBoYXNFcnJvciA9IGZhbHNlO1xuICBjYXVnaHRFcnJvciA9IG51bGw7XG4gIGludm9rZUd1YXJkZWRDYWxsYmFja0ltcGwkMS5hcHBseShyZXBvcnRlciwgYXJndW1lbnRzKTtcbn1cbi8qKlxuICogU2FtZSBhcyBpbnZva2VHdWFyZGVkQ2FsbGJhY2ssIGJ1dCBpbnN0ZWFkIG9mIHJldHVybmluZyBhbiBlcnJvciwgaXQgc3RvcmVzXG4gKiBpdCBpbiBhIGdsb2JhbCBzbyBpdCBjYW4gYmUgcmV0aHJvd24gYnkgYHJldGhyb3dDYXVnaHRFcnJvcmAgbGF0ZXIuXG4gKiBUT0RPOiBTZWUgaWYgY2F1Z2h0RXJyb3IgYW5kIHJldGhyb3dFcnJvciBjYW4gYmUgdW5pZmllZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiB0aGUgZ3VhcmQgdG8gdXNlIGZvciBsb2dnaW5nIG9yIGRlYnVnZ2luZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW52b2tlXG4gKiBAcGFyYW0geyp9IGNvbnRleHQgVGhlIGNvbnRleHQgdG8gdXNlIHdoZW4gY2FsbGluZyB0aGUgZnVuY3Rpb25cbiAqIEBwYXJhbSB7Li4uKn0gYXJncyBBcmd1bWVudHMgZm9yIGZ1bmN0aW9uXG4gKi9cblxuZnVuY3Rpb24gaW52b2tlR3VhcmRlZENhbGxiYWNrQW5kQ2F0Y2hGaXJzdEVycm9yKG5hbWUsIGZ1bmMsIGNvbnRleHQsIGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgaW52b2tlR3VhcmRlZENhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgaWYgKGhhc0Vycm9yKSB7XG4gICAgdmFyIGVycm9yID0gY2xlYXJDYXVnaHRFcnJvcigpO1xuXG4gICAgaWYgKCFoYXNSZXRocm93RXJyb3IpIHtcbiAgICAgIGhhc1JldGhyb3dFcnJvciA9IHRydWU7XG4gICAgICByZXRocm93RXJyb3IgPSBlcnJvcjtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogRHVyaW5nIGV4ZWN1dGlvbiBvZiBndWFyZGVkIGZ1bmN0aW9ucyB3ZSB3aWxsIGNhcHR1cmUgdGhlIGZpcnN0IGVycm9yIHdoaWNoXG4gKiB3ZSB3aWxsIHJldGhyb3cgdG8gYmUgaGFuZGxlZCBieSB0aGUgdG9wIGxldmVsIGVycm9yIGhhbmRsZXIuXG4gKi9cblxuZnVuY3Rpb24gcmV0aHJvd0NhdWdodEVycm9yKCkge1xuICBpZiAoaGFzUmV0aHJvd0Vycm9yKSB7XG4gICAgdmFyIGVycm9yID0gcmV0aHJvd0Vycm9yO1xuICAgIGhhc1JldGhyb3dFcnJvciA9IGZhbHNlO1xuICAgIHJldGhyb3dFcnJvciA9IG51bGw7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbmZ1bmN0aW9uIGhhc0NhdWdodEVycm9yKCkge1xuICByZXR1cm4gaGFzRXJyb3I7XG59XG5mdW5jdGlvbiBjbGVhckNhdWdodEVycm9yKCkge1xuICBpZiAoaGFzRXJyb3IpIHtcbiAgICB2YXIgZXJyb3IgPSBjYXVnaHRFcnJvcjtcbiAgICBoYXNFcnJvciA9IGZhbHNlO1xuICAgIGNhdWdodEVycm9yID0gbnVsbDtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhckNhdWdodEVycm9yIHdhcyBjYWxsZWQgYnV0IG5vIGVycm9yIHdhcyBjYXB0dXJlZC4gVGhpcyBlcnJvciAnICsgJ2lzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG59XG5cbi8qKlxuICogYFJlYWN0SW5zdGFuY2VNYXBgIG1haW50YWlucyBhIG1hcHBpbmcgZnJvbSBhIHB1YmxpYyBmYWNpbmcgc3RhdGVmdWxcbiAqIGluc3RhbmNlIChrZXkpIGFuZCB0aGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gKHZhbHVlKS4gVGhpcyBhbGxvd3MgcHVibGljXG4gKiBtZXRob2RzIHRvIGFjY2VwdCB0aGUgdXNlciBmYWNpbmcgaW5zdGFuY2UgYXMgYW4gYXJndW1lbnQgYW5kIG1hcCB0aGVtIGJhY2tcbiAqIHRvIGludGVybmFsIG1ldGhvZHMuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgbW9kdWxlIGlzIGN1cnJlbnRseSBzaGFyZWQgYW5kIGFzc3VtZWQgdG8gYmUgc3RhdGVsZXNzLlxuICogSWYgdGhpcyBiZWNvbWVzIGFuIGFjdHVhbCBNYXAsIHRoYXQgd2lsbCBicmVhay5cbiAqL1xuZnVuY3Rpb24gZ2V0KGtleSkge1xuICByZXR1cm4ga2V5Ll9yZWFjdEludGVybmFscztcbn1cbmZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgcmV0dXJuIGtleS5fcmVhY3RJbnRlcm5hbHMgIT09IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIHNldChrZXksIHZhbHVlKSB7XG4gIGtleS5fcmVhY3RJbnRlcm5hbHMgPSB2YWx1ZTtcbn1cblxuLy8gRG9uJ3QgY2hhbmdlIHRoZXNlIHR3byB2YWx1ZXMuIFRoZXkncmUgdXNlZCBieSBSZWFjdCBEZXYgVG9vbHMuXG52YXIgTm9GbGFncyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAqL1xuMDtcbnZhciBQZXJmb3JtZWRXb3JrID1cbi8qICAgICAgICAgICAgICAgICovXG4xOyAvLyBZb3UgY2FuIGNoYW5nZSB0aGUgcmVzdCAoYW5kIGFkZCBtb3JlKS5cblxudmFyIFBsYWNlbWVudCA9XG4vKiAgICAgICAgICAgICAgICAgICAgKi9cbjI7XG52YXIgVXBkYXRlID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuNDtcbnZhciBDaGlsZERlbGV0aW9uID1cbi8qICAgICAgICAgICAgICAgICovXG4xNjtcbnZhciBDb250ZW50UmVzZXQgPVxuLyogICAgICAgICAgICAgICAgICovXG4zMjtcbnZhciBDYWxsYmFjayA9XG4vKiAgICAgICAgICAgICAgICAgICAgICovXG42NDtcbnZhciBEaWRDYXB0dXJlID1cbi8qICAgICAgICAgICAgICAgICAgICovXG4xMjg7XG52YXIgRm9yY2VDbGllbnRSZW5kZXIgPVxuLyogICAgICAgICAgICAqL1xuMjU2O1xudmFyIFJlZiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjUxMjtcbnZhciBTbmFwc2hvdCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICovXG4xMDI0O1xudmFyIFBhc3NpdmUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgKi9cbjIwNDg7XG52YXIgSHlkcmF0aW5nID1cbi8qICAgICAgICAgICAgICAgICAgICAqL1xuNDA5NjtcbnZhciBWaXNpYmlsaXR5ID1cbi8qICAgICAgICAgICAgICAgICAgICovXG44MTkyO1xudmFyIFN0b3JlQ29uc2lzdGVuY3kgPVxuLyogICAgICAgICAgICAgKi9cbjE2Mzg0O1xudmFyIExpZmVjeWNsZUVmZmVjdE1hc2sgPSBQYXNzaXZlIHwgVXBkYXRlIHwgQ2FsbGJhY2sgfCBSZWYgfCBTbmFwc2hvdCB8IFN0b3JlQ29uc2lzdGVuY3k7IC8vIFVuaW9uIG9mIGFsbCBjb21taXQgZmxhZ3MgKGZsYWdzIHdpdGggdGhlIGxpZmV0aW1lIG9mIGEgcGFydGljdWxhciBjb21taXQpXG5cbnZhciBIb3N0RWZmZWN0TWFzayA9XG4vKiAgICAgICAgICAgICAgICovXG4zMjc2NzsgLy8gVGhlc2UgYXJlIG5vdCByZWFsbHkgc2lkZSBlZmZlY3RzLCBidXQgd2Ugc3RpbGwgcmV1c2UgdGhpcyBmaWVsZC5cblxudmFyIEluY29tcGxldGUgPVxuLyogICAgICAgICAgICAgICAgICAgKi9cbjMyNzY4O1xudmFyIFNob3VsZENhcHR1cmUgPVxuLyogICAgICAgICAgICAgICAgKi9cbjY1NTM2O1xudmFyIEZvcmNlVXBkYXRlRm9yTGVnYWN5U3VzcGVuc2UgPVxuLyogKi9cbjEzMTA3MjtcbnZhciBGb3JrZWQgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG4xMDQ4NTc2OyAvLyBTdGF0aWMgdGFncyBkZXNjcmliZSBhc3BlY3RzIG9mIGEgZmliZXIgdGhhdCBhcmUgbm90IHNwZWNpZmljIHRvIGEgcmVuZGVyLFxuLy8gZS5nLiBhIGZpYmVyIHVzZXMgYSBwYXNzaXZlIGVmZmVjdCAoZXZlbiBpZiB0aGVyZSBhcmUgbm8gdXBkYXRlcyBvbiB0aGlzIHBhcnRpY3VsYXIgcmVuZGVyKS5cbi8vIFRoaXMgZW5hYmxlcyB1cyB0byBkZWZlciBtb3JlIHdvcmsgaW4gdGhlIHVubW91bnQgY2FzZSxcbi8vIHNpbmNlIHdlIGNhbiBkZWZlciB0cmF2ZXJzaW5nIHRoZSB0cmVlIGR1cmluZyBsYXlvdXQgdG8gbG9vayBmb3IgUGFzc2l2ZSBlZmZlY3RzLFxuLy8gYW5kIGluc3RlYWQgcmVseSBvbiB0aGUgc3RhdGljIGZsYWcgYXMgYSBzaWduYWwgdGhhdCB0aGVyZSBtYXkgYmUgY2xlYW51cCB3b3JrLlxuXG52YXIgUmVmU3RhdGljID1cbi8qICAgICAgICAgICAgICAgICAgICAqL1xuMjA5NzE1MjtcbnZhciBMYXlvdXRTdGF0aWMgPVxuLyogICAgICAgICAgICAgICAgICovXG40MTk0MzA0O1xudmFyIFBhc3NpdmVTdGF0aWMgPVxuLyogICAgICAgICAgICAgICAgKi9cbjgzODg2MDg7IC8vIFRoZXNlIGZsYWdzIGFsbG93IHVzIHRvIHRyYXZlcnNlIHRvIGZpYmVycyB0aGF0IGhhdmUgZWZmZWN0cyBvbiBtb3VudFxuLy8gd2l0aG91dCB0cmF2ZXJzaW5nIHRoZSBlbnRpcmUgdHJlZSBhZnRlciBldmVyeSBjb21taXQgZm9yXG4vLyBkb3VibGUgaW52b2tpbmdcblxudmFyIE1vdW50TGF5b3V0RGV2ID1cbi8qICAgICAgICAgICAgICAgKi9cbjE2Nzc3MjE2O1xudmFyIE1vdW50UGFzc2l2ZURldiA9XG4vKiAgICAgICAgICAgICAgKi9cbjMzNTU0NDMyOyAvLyBHcm91cHMgb2YgZmxhZ3MgdGhhdCBhcmUgdXNlZCBpbiB0aGUgY29tbWl0IHBoYXNlIHRvIHNraXAgb3ZlciB0cmVlcyB0aGF0XG4vLyBkb24ndCBjb250YWluIGVmZmVjdHMsIGJ5IGNoZWNraW5nIHN1YnRyZWVGbGFncy5cblxudmFyIEJlZm9yZU11dGF0aW9uTWFzayA9IC8vIFRPRE86IFJlbW92ZSBVcGRhdGUgZmxhZyBmcm9tIGJlZm9yZSBtdXRhdGlvbiBwaGFzZSBieSByZS1sYW5kaW5nIFZpc2liaWxpdHlcbi8vIGZsYWcgbG9naWMgKHNlZSAjMjAwNDMpXG5VcGRhdGUgfCBTbmFwc2hvdCB8ICggMCk7XG52YXIgTXV0YXRpb25NYXNrID0gUGxhY2VtZW50IHwgVXBkYXRlIHwgQ2hpbGREZWxldGlvbiB8IENvbnRlbnRSZXNldCB8IFJlZiB8IEh5ZHJhdGluZyB8IFZpc2liaWxpdHk7XG52YXIgTGF5b3V0TWFzayA9IFVwZGF0ZSB8IENhbGxiYWNrIHwgUmVmIHwgVmlzaWJpbGl0eTsgLy8gVE9ETzogU3BsaXQgaW50byBQYXNzaXZlTW91bnRNYXNrIGFuZCBQYXNzaXZlVW5tb3VudE1hc2tcblxudmFyIFBhc3NpdmVNYXNrID0gUGFzc2l2ZSB8IENoaWxkRGVsZXRpb247IC8vIFVuaW9uIG9mIHRhZ3MgdGhhdCBkb24ndCBnZXQgcmVzZXQgb24gY2xvbmVzLlxuLy8gVGhpcyBhbGxvd3MgY2VydGFpbiBjb25jZXB0cyB0byBwZXJzaXN0IHdpdGhvdXQgcmVjYWxjdWxhdGluZyB0aGVtLFxuLy8gZS5nLiB3aGV0aGVyIGEgc3VidHJlZSBjb250YWlucyBwYXNzaXZlIGVmZmVjdHMgb3IgcG9ydGFscy5cblxudmFyIFN0YXRpY01hc2sgPSBMYXlvdXRTdGF0aWMgfCBQYXNzaXZlU3RhdGljIHwgUmVmU3RhdGljO1xuXG52YXIgUmVhY3RDdXJyZW50T3duZXIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbmZ1bmN0aW9uIGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpIHtcbiAgdmFyIG5vZGUgPSBmaWJlcjtcbiAgdmFyIG5lYXJlc3RNb3VudGVkID0gZmliZXI7XG5cbiAgaWYgKCFmaWJlci5hbHRlcm5hdGUpIHtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBhbHRlcm5hdGUsIHRoaXMgbWlnaHQgYmUgYSBuZXcgdHJlZSB0aGF0IGlzbid0IGluc2VydGVkXG4gICAgLy8geWV0LiBJZiBpdCBpcywgdGhlbiBpdCB3aWxsIGhhdmUgYSBwZW5kaW5nIGluc2VydGlvbiBlZmZlY3Qgb24gaXQuXG4gICAgdmFyIG5leHROb2RlID0gbm9kZTtcblxuICAgIGRvIHtcbiAgICAgIG5vZGUgPSBuZXh0Tm9kZTtcblxuICAgICAgaWYgKChub2RlLmZsYWdzICYgKFBsYWNlbWVudCB8IEh5ZHJhdGluZykpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYW4gaW5zZXJ0aW9uIG9yIGluLXByb2dyZXNzIGh5ZHJhdGlvbi4gVGhlIG5lYXJlc3QgcG9zc2libGVcbiAgICAgICAgLy8gbW91bnRlZCBmaWJlciBpcyB0aGUgcGFyZW50IGJ1dCB3ZSBuZWVkIHRvIGNvbnRpbnVlIHRvIGZpZ3VyZSBvdXRcbiAgICAgICAgLy8gaWYgdGhhdCBvbmUgaXMgc3RpbGwgbW91bnRlZC5cbiAgICAgICAgbmVhcmVzdE1vdW50ZWQgPSBub2RlLnJldHVybjtcbiAgICAgIH1cblxuICAgICAgbmV4dE5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9IHdoaWxlIChuZXh0Tm9kZSk7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKG5vZGUucmV0dXJuKSB7XG4gICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgfVxuICB9XG5cbiAgaWYgKG5vZGUudGFnID09PSBIb3N0Um9vdCkge1xuICAgIC8vIFRPRE86IENoZWNrIGlmIHRoaXMgd2FzIGEgbmVzdGVkIEhvc3RSb290IHdoZW4gdXNlZCB3aXRoXG4gICAgLy8gcmVuZGVyQ29udGFpbmVySW50b1N1YnRyZWUuXG4gICAgcmV0dXJuIG5lYXJlc3RNb3VudGVkO1xuICB9IC8vIElmIHdlIGRpZG4ndCBoaXQgdGhlIHJvb3QsIHRoYXQgbWVhbnMgdGhhdCB3ZSdyZSBpbiBhbiBkaXNjb25uZWN0ZWQgdHJlZVxuICAvLyB0aGF0IGhhcyBiZWVuIHVubW91bnRlZC5cblxuXG4gIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0U3VzcGVuc2VJbnN0YW5jZUZyb21GaWJlcihmaWJlcikge1xuICBpZiAoZmliZXIudGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICAgIGlmIChzdXNwZW5zZVN0YXRlID09PSBudWxsKSB7XG4gICAgICB2YXIgY3VycmVudCA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgc3VzcGVuc2VTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldENvbnRhaW5lckZyb21GaWJlcihmaWJlcikge1xuICByZXR1cm4gZmliZXIudGFnID09PSBIb3N0Um9vdCA/IGZpYmVyLnN0YXRlTm9kZS5jb250YWluZXJJbmZvIDogbnVsbDtcbn1cbmZ1bmN0aW9uIGlzRmliZXJNb3VudGVkKGZpYmVyKSB7XG4gIHJldHVybiBnZXROZWFyZXN0TW91bnRlZEZpYmVyKGZpYmVyKSA9PT0gZmliZXI7XG59XG5mdW5jdGlvbiBpc01vdW50ZWQoY29tcG9uZW50KSB7XG4gIHtcbiAgICB2YXIgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50O1xuXG4gICAgaWYgKG93bmVyICE9PSBudWxsICYmIG93bmVyLnRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgIHZhciBvd25lckZpYmVyID0gb3duZXI7XG4gICAgICB2YXIgaW5zdGFuY2UgPSBvd25lckZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgaWYgKCFpbnN0YW5jZS5fd2FybmVkQWJvdXRSZWZzSW5SZW5kZXIpIHtcbiAgICAgICAgZXJyb3IoJyVzIGlzIGFjY2Vzc2luZyBpc01vdW50ZWQgaW5zaWRlIGl0cyByZW5kZXIoKSBmdW5jdGlvbi4gJyArICdyZW5kZXIoKSBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4gSXQgc2hvdWxkICcgKyAnbmV2ZXIgYWNjZXNzIHNvbWV0aGluZyB0aGF0IHJlcXVpcmVzIHN0YWxlIGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgJyArICdyZW5kZXIsIHN1Y2ggYXMgcmVmcy4gTW92ZSB0aGlzIGxvZ2ljIHRvIGNvbXBvbmVudERpZE1vdW50IGFuZCAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZSBpbnN0ZWFkLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIob3duZXJGaWJlcikgfHwgJ0EgY29tcG9uZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGluc3RhbmNlLl93YXJuZWRBYm91dFJlZnNJblJlbmRlciA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGZpYmVyID0gZ2V0KGNvbXBvbmVudCk7XG5cbiAgaWYgKCFmaWJlcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBnZXROZWFyZXN0TW91bnRlZEZpYmVyKGZpYmVyKSA9PT0gZmliZXI7XG59XG5cbmZ1bmN0aW9uIGFzc2VydElzTW91bnRlZChmaWJlcikge1xuICBpZiAoZ2V0TmVhcmVzdE1vdW50ZWRGaWJlcihmaWJlcikgIT09IGZpYmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZEN1cnJlbnRGaWJlclVzaW5nU2xvd1BhdGgoZmliZXIpIHtcbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoIWFsdGVybmF0ZSkge1xuICAgIC8vIElmIHRoZXJlIGlzIG5vIGFsdGVybmF0ZSwgdGhlbiB3ZSBvbmx5IG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgbW91bnRlZC5cbiAgICB2YXIgbmVhcmVzdE1vdW50ZWQgPSBnZXROZWFyZXN0TW91bnRlZEZpYmVyKGZpYmVyKTtcblxuICAgIGlmIChuZWFyZXN0TW91bnRlZCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJyk7XG4gICAgfVxuXG4gICAgaWYgKG5lYXJlc3RNb3VudGVkICE9PSBmaWJlcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpYmVyO1xuICB9IC8vIElmIHdlIGhhdmUgdHdvIHBvc3NpYmxlIGJyYW5jaGVzLCB3ZSdsbCB3YWxrIGJhY2t3YXJkcyB1cCB0byB0aGUgcm9vdFxuICAvLyB0byBzZWUgd2hhdCBwYXRoIHRoZSByb290IHBvaW50cyB0by4gT24gdGhlIHdheSB3ZSBtYXkgaGl0IG9uZSBvZiB0aGVcbiAgLy8gc3BlY2lhbCBjYXNlcyBhbmQgd2UnbGwgZGVhbCB3aXRoIHRoZW0uXG5cblxuICB2YXIgYSA9IGZpYmVyO1xuICB2YXIgYiA9IGFsdGVybmF0ZTtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHZhciBwYXJlbnRBID0gYS5yZXR1cm47XG5cbiAgICBpZiAocGFyZW50QSA9PT0gbnVsbCkge1xuICAgICAgLy8gV2UncmUgYXQgdGhlIHJvb3QuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgcGFyZW50QiA9IHBhcmVudEEuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKHBhcmVudEIgPT09IG51bGwpIHtcbiAgICAgIC8vIFRoZXJlIGlzIG5vIGFsdGVybmF0ZS4gVGhpcyBpcyBhbiB1bnVzdWFsIGNhc2UuIEN1cnJlbnRseSwgaXQgb25seVxuICAgICAgLy8gaGFwcGVucyB3aGVuIGEgU3VzcGVuc2UgY29tcG9uZW50IGlzIGhpZGRlbi4gQW4gZXh0cmEgZnJhZ21lbnQgZmliZXJcbiAgICAgIC8vIGlzIGluc2VydGVkIGluIGJldHdlZW4gdGhlIFN1c3BlbnNlIGZpYmVyIGFuZCBpdHMgY2hpbGRyZW4uIFNraXBcbiAgICAgIC8vIG92ZXIgdGhpcyBleHRyYSBmcmFnbWVudCBmaWJlciBhbmQgcHJvY2VlZCB0byB0aGUgbmV4dCBwYXJlbnQuXG4gICAgICB2YXIgbmV4dFBhcmVudCA9IHBhcmVudEEucmV0dXJuO1xuXG4gICAgICBpZiAobmV4dFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICBhID0gYiA9IG5leHRQYXJlbnQ7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSAvLyBJZiB0aGVyZSdzIG5vIHBhcmVudCwgd2UncmUgYXQgdGhlIHJvb3QuXG5cblxuICAgICAgYnJlYWs7XG4gICAgfSAvLyBJZiBib3RoIGNvcGllcyBvZiB0aGUgcGFyZW50IGZpYmVyIHBvaW50IHRvIHRoZSBzYW1lIGNoaWxkLCB3ZSBjYW5cbiAgICAvLyBhc3N1bWUgdGhhdCB0aGUgY2hpbGQgaXMgY3VycmVudC4gVGhpcyBoYXBwZW5zIHdoZW4gd2UgYmFpbG91dCBvbiBsb3dcbiAgICAvLyBwcmlvcml0eTogdGhlIGJhaWxlZCBvdXQgZmliZXIncyBjaGlsZCByZXVzZXMgdGhlIGN1cnJlbnQgY2hpbGQuXG5cblxuICAgIGlmIChwYXJlbnRBLmNoaWxkID09PSBwYXJlbnRCLmNoaWxkKSB7XG4gICAgICB2YXIgY2hpbGQgPSBwYXJlbnRBLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgaWYgKGNoaWxkID09PSBhKSB7XG4gICAgICAgICAgLy8gV2UndmUgZGV0ZXJtaW5lZCB0aGF0IEEgaXMgdGhlIGN1cnJlbnQgYnJhbmNoLlxuICAgICAgICAgIGFzc2VydElzTW91bnRlZChwYXJlbnRBKTtcbiAgICAgICAgICByZXR1cm4gZmliZXI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hpbGQgPT09IGIpIHtcbiAgICAgICAgICAvLyBXZSd2ZSBkZXRlcm1pbmVkIHRoYXQgQiBpcyB0aGUgY3VycmVudCBicmFuY2guXG4gICAgICAgICAgYXNzZXJ0SXNNb3VudGVkKHBhcmVudEEpO1xuICAgICAgICAgIHJldHVybiBhbHRlcm5hdGU7XG4gICAgICAgIH1cblxuICAgICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgICB9IC8vIFdlIHNob3VsZCBuZXZlciBoYXZlIGFuIGFsdGVybmF0ZSBmb3IgYW55IG1vdW50aW5nIG5vZGUuIFNvIHRoZSBvbmx5XG4gICAgICAvLyB3YXkgdGhpcyBjb3VsZCBwb3NzaWJseSBoYXBwZW4gaXMgaWYgdGhpcyB3YXMgdW5tb3VudGVkLCBpZiBhdCBhbGwuXG5cblxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJyk7XG4gICAgfVxuXG4gICAgaWYgKGEucmV0dXJuICE9PSBiLnJldHVybikge1xuICAgICAgLy8gVGhlIHJldHVybiBwb2ludGVyIG9mIEEgYW5kIHRoZSByZXR1cm4gcG9pbnRlciBvZiBCIHBvaW50IHRvIGRpZmZlcmVudFxuICAgICAgLy8gZmliZXJzLiBXZSBhc3N1bWUgdGhhdCByZXR1cm4gcG9pbnRlcnMgbmV2ZXIgY3Jpc3MtY3Jvc3MsIHNvIEEgbXVzdFxuICAgICAgLy8gYmVsb25nIHRvIHRoZSBjaGlsZCBzZXQgb2YgQS5yZXR1cm4sIGFuZCBCIG11c3QgYmVsb25nIHRvIHRoZSBjaGlsZFxuICAgICAgLy8gc2V0IG9mIEIucmV0dXJuLlxuICAgICAgYSA9IHBhcmVudEE7XG4gICAgICBiID0gcGFyZW50QjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHJldHVybiBwb2ludGVycyBwb2ludCB0byB0aGUgc2FtZSBmaWJlci4gV2UnbGwgaGF2ZSB0byB1c2UgdGhlXG4gICAgICAvLyBkZWZhdWx0LCBzbG93IHBhdGg6IHNjYW4gdGhlIGNoaWxkIHNldHMgb2YgZWFjaCBwYXJlbnQgYWx0ZXJuYXRlIHRvIHNlZVxuICAgICAgLy8gd2hpY2ggY2hpbGQgYmVsb25ncyB0byB3aGljaCBzZXQuXG4gICAgICAvL1xuICAgICAgLy8gU2VhcmNoIHBhcmVudCBBJ3MgY2hpbGQgc2V0XG4gICAgICB2YXIgZGlkRmluZENoaWxkID0gZmFsc2U7XG4gICAgICB2YXIgX2NoaWxkID0gcGFyZW50QS5jaGlsZDtcblxuICAgICAgd2hpbGUgKF9jaGlsZCkge1xuICAgICAgICBpZiAoX2NoaWxkID09PSBhKSB7XG4gICAgICAgICAgZGlkRmluZENoaWxkID0gdHJ1ZTtcbiAgICAgICAgICBhID0gcGFyZW50QTtcbiAgICAgICAgICBiID0gcGFyZW50QjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfY2hpbGQgPT09IGIpIHtcbiAgICAgICAgICBkaWRGaW5kQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgIGIgPSBwYXJlbnRBO1xuICAgICAgICAgIGEgPSBwYXJlbnRCO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgX2NoaWxkID0gX2NoaWxkLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIGlmICghZGlkRmluZENoaWxkKSB7XG4gICAgICAgIC8vIFNlYXJjaCBwYXJlbnQgQidzIGNoaWxkIHNldFxuICAgICAgICBfY2hpbGQgPSBwYXJlbnRCLmNoaWxkO1xuXG4gICAgICAgIHdoaWxlIChfY2hpbGQpIHtcbiAgICAgICAgICBpZiAoX2NoaWxkID09PSBhKSB7XG4gICAgICAgICAgICBkaWRGaW5kQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgICAgYSA9IHBhcmVudEI7XG4gICAgICAgICAgICBiID0gcGFyZW50QTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChfY2hpbGQgPT09IGIpIHtcbiAgICAgICAgICAgIGRpZEZpbmRDaGlsZCA9IHRydWU7XG4gICAgICAgICAgICBiID0gcGFyZW50QjtcbiAgICAgICAgICAgIGEgPSBwYXJlbnRBO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgX2NoaWxkID0gX2NoaWxkLnNpYmxpbmc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWRpZEZpbmRDaGlsZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hpbGQgd2FzIG5vdCBmb3VuZCBpbiBlaXRoZXIgcGFyZW50IHNldC4gVGhpcyBpbmRpY2F0ZXMgYSBidWcgJyArICdpbiBSZWFjdCByZWxhdGVkIHRvIHRoZSByZXR1cm4gcG9pbnRlci4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYS5hbHRlcm5hdGUgIT09IGIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJldHVybiBmaWJlcnMgc2hvdWxkIGFsd2F5cyBiZSBlYWNoIG90aGVycycgYWx0ZXJuYXRlcy4gXCIgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH0gLy8gSWYgdGhlIHJvb3QgaXMgbm90IGEgaG9zdCBjb250YWluZXIsIHdlJ3JlIGluIGEgZGlzY29ubmVjdGVkIHRyZWUuIEkuZS5cbiAgLy8gdW5tb3VudGVkLlxuXG5cbiAgaWYgKGEudGFnICE9PSBIb3N0Um9vdCkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGZpbmQgbm9kZSBvbiBhbiB1bm1vdW50ZWQgY29tcG9uZW50LicpO1xuICB9XG5cbiAgaWYgKGEuc3RhdGVOb2RlLmN1cnJlbnQgPT09IGEpIHtcbiAgICAvLyBXZSd2ZSBkZXRlcm1pbmVkIHRoYXQgQSBpcyB0aGUgY3VycmVudCBicmFuY2guXG4gICAgcmV0dXJuIGZpYmVyO1xuICB9IC8vIE90aGVyd2lzZSBCIGhhcyB0byBiZSBjdXJyZW50IGJyYW5jaC5cblxuXG4gIHJldHVybiBhbHRlcm5hdGU7XG59XG5mdW5jdGlvbiBmaW5kQ3VycmVudEhvc3RGaWJlcihwYXJlbnQpIHtcbiAgdmFyIGN1cnJlbnRQYXJlbnQgPSBmaW5kQ3VycmVudEZpYmVyVXNpbmdTbG93UGF0aChwYXJlbnQpO1xuICByZXR1cm4gY3VycmVudFBhcmVudCAhPT0gbnVsbCA/IGZpbmRDdXJyZW50SG9zdEZpYmVySW1wbChjdXJyZW50UGFyZW50KSA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIGZpbmRDdXJyZW50SG9zdEZpYmVySW1wbChub2RlKSB7XG4gIC8vIE5leHQgd2UnbGwgZHJpbGwgZG93biB0aGlzIGNvbXBvbmVudCB0byBmaW5kIHRoZSBmaXJzdCBIb3N0Q29tcG9uZW50L1RleHQuXG4gIGlmIChub2RlLnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBub2RlLnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHZhciBjaGlsZCA9IG5vZGUuY2hpbGQ7XG5cbiAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgdmFyIG1hdGNoID0gZmluZEN1cnJlbnRIb3N0RmliZXJJbXBsKGNoaWxkKTtcblxuICAgIGlmIChtYXRjaCAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH1cblxuICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudEhvc3RGaWJlcldpdGhOb1BvcnRhbHMocGFyZW50KSB7XG4gIHZhciBjdXJyZW50UGFyZW50ID0gZmluZEN1cnJlbnRGaWJlclVzaW5nU2xvd1BhdGgocGFyZW50KTtcbiAgcmV0dXJuIGN1cnJlbnRQYXJlbnQgIT09IG51bGwgPyBmaW5kQ3VycmVudEhvc3RGaWJlcldpdGhOb1BvcnRhbHNJbXBsKGN1cnJlbnRQYXJlbnQpIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZmluZEN1cnJlbnRIb3N0RmliZXJXaXRoTm9Qb3J0YWxzSW1wbChub2RlKSB7XG4gIC8vIE5leHQgd2UnbGwgZHJpbGwgZG93biB0aGlzIGNvbXBvbmVudCB0byBmaW5kIHRoZSBmaXJzdCBIb3N0Q29tcG9uZW50L1RleHQuXG4gIGlmIChub2RlLnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBub2RlLnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHZhciBjaGlsZCA9IG5vZGUuY2hpbGQ7XG5cbiAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgaWYgKGNoaWxkLnRhZyAhPT0gSG9zdFBvcnRhbCkge1xuICAgICAgdmFyIG1hdGNoID0gZmluZEN1cnJlbnRIb3N0RmliZXJXaXRoTm9Qb3J0YWxzSW1wbChjaGlsZCk7XG5cbiAgICAgIGlmIChtYXRjaCAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8vIFRoaXMgbW9kdWxlIG9ubHkgZXhpc3RzIGFzIGFuIEVTTSB3cmFwcGVyIGFyb3VuZCB0aGUgZXh0ZXJuYWwgQ29tbW9uSlNcbnZhciBzY2hlZHVsZUNhbGxiYWNrID0gU2NoZWR1bGVyLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2s7XG52YXIgY2FuY2VsQ2FsbGJhY2sgPSBTY2hlZHVsZXIudW5zdGFibGVfY2FuY2VsQ2FsbGJhY2s7XG52YXIgc2hvdWxkWWllbGQgPSBTY2hlZHVsZXIudW5zdGFibGVfc2hvdWxkWWllbGQ7XG52YXIgcmVxdWVzdFBhaW50ID0gU2NoZWR1bGVyLnVuc3RhYmxlX3JlcXVlc3RQYWludDtcbnZhciBub3cgPSBTY2hlZHVsZXIudW5zdGFibGVfbm93O1xudmFyIGdldEN1cnJlbnRQcmlvcml0eUxldmVsID0gU2NoZWR1bGVyLnVuc3RhYmxlX2dldEN1cnJlbnRQcmlvcml0eUxldmVsO1xudmFyIEltbWVkaWF0ZVByaW9yaXR5ID0gU2NoZWR1bGVyLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5O1xudmFyIFVzZXJCbG9ja2luZ1ByaW9yaXR5ID0gU2NoZWR1bGVyLnVuc3RhYmxlX1VzZXJCbG9ja2luZ1ByaW9yaXR5O1xudmFyIE5vcm1hbFByaW9yaXR5ID0gU2NoZWR1bGVyLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5O1xudmFyIExvd1ByaW9yaXR5ID0gU2NoZWR1bGVyLnVuc3RhYmxlX0xvd1ByaW9yaXR5O1xudmFyIElkbGVQcmlvcml0eSA9IFNjaGVkdWxlci51bnN0YWJsZV9JZGxlUHJpb3JpdHk7XG4vLyB0aGlzIGRvZXNuJ3QgYWN0dWFsbHkgZXhpc3Qgb24gdGhlIHNjaGVkdWxlciwgYnV0IGl0ICpkb2VzKlxuLy8gb24gc2NoZWR1bGVyL3Vuc3RhYmxlX21vY2ssIHdoaWNoIHdlJ2xsIG5lZWQgZm9yIGludGVybmFsIHRlc3RpbmdcbnZhciB1bnN0YWJsZV95aWVsZFZhbHVlID0gU2NoZWR1bGVyLnVuc3RhYmxlX3lpZWxkVmFsdWU7XG52YXIgdW5zdGFibGVfc2V0RGlzYWJsZVlpZWxkVmFsdWUgPSBTY2hlZHVsZXIudW5zdGFibGVfc2V0RGlzYWJsZVlpZWxkVmFsdWU7XG5cbnZhciByZW5kZXJlcklEID0gbnVsbDtcbnZhciBpbmplY3RlZEhvb2sgPSBudWxsO1xudmFyIGluamVjdGVkUHJvZmlsaW5nSG9va3MgPSBudWxsO1xudmFyIGhhc0xvZ2dlZEVycm9yID0gZmFsc2U7XG52YXIgaXNEZXZUb29sc1ByZXNlbnQgPSB0eXBlb2YgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICE9PSAndW5kZWZpbmVkJztcbmZ1bmN0aW9uIGluamVjdEludGVybmFscyhpbnRlcm5hbHMpIHtcbiAgaWYgKHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gTm8gRGV2VG9vbHNcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgaG9vayA9IF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztcblxuICBpZiAoaG9vay5pc0Rpc2FibGVkKSB7XG4gICAgLy8gVGhpcyBpc24ndCBhIHJlYWwgcHJvcGVydHkgb24gdGhlIGhvb2ssIGJ1dCBpdCBjYW4gYmUgc2V0IHRvIG9wdCBvdXRcbiAgICAvLyBvZiBEZXZUb29scyBpbnRlZ3JhdGlvbiBhbmQgYXNzb2NpYXRlZCB3YXJuaW5ncyBhbmQgbG9ncy5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzM4NzdcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmICghaG9vay5zdXBwb3J0c0ZpYmVyKSB7XG4gICAge1xuICAgICAgZXJyb3IoJ1RoZSBpbnN0YWxsZWQgdmVyc2lvbiBvZiBSZWFjdCBEZXZUb29scyBpcyB0b28gb2xkIGFuZCB3aWxsIG5vdCB3b3JrICcgKyAnd2l0aCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIFJlYWN0LiBQbGVhc2UgdXBkYXRlIFJlYWN0IERldlRvb2xzLiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9yZWFjdC1kZXZ0b29scycpO1xuICAgIH0gLy8gRGV2VG9vbHMgZXhpc3RzLCBldmVuIHRob3VnaCBpdCBkb2Vzbid0IHN1cHBvcnQgRmliZXIuXG5cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoZW5hYmxlU2NoZWR1bGluZ1Byb2ZpbGVyKSB7XG4gICAgICAvLyBDb25kaXRpb25hbGx5IGluamVjdCB0aGVzZSBob29rcyBvbmx5IGlmIFRpbWVsaW5lIHByb2ZpbGVyIGlzIHN1cHBvcnRlZCBieSB0aGlzIGJ1aWxkLlxuICAgICAgLy8gVGhpcyBnaXZlcyBEZXZUb29scyBhIHdheSB0byBmZWF0dXJlIGRldGVjdCB0aGF0IGlzbid0IHRpZWQgdG8gdmVyc2lvbiBudW1iZXJcbiAgICAgIC8vIChzaW5jZSBwcm9maWxpbmcgYW5kIHRpbWVsaW5lIGFyZSBjb250cm9sbGVkIGJ5IGRpZmZlcmVudCBmZWF0dXJlIGZsYWdzKS5cbiAgICAgIGludGVybmFscyA9IGFzc2lnbih7fSwgaW50ZXJuYWxzLCB7XG4gICAgICAgIGdldExhbmVMYWJlbE1hcDogZ2V0TGFuZUxhYmVsTWFwLFxuICAgICAgICBpbmplY3RQcm9maWxpbmdIb29rczogaW5qZWN0UHJvZmlsaW5nSG9va3NcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlbmRlcmVySUQgPSBob29rLmluamVjdChpbnRlcm5hbHMpOyAvLyBXZSBoYXZlIHN1Y2Nlc3NmdWxseSBpbmplY3RlZCwgc28gbm93IGl0IGlzIHNhZmUgdG8gc2V0IHVwIGhvb2tzLlxuXG4gICAgaW5qZWN0ZWRIb29rID0gaG9vaztcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gQ2F0Y2ggYWxsIGVycm9ycyBiZWNhdXNlIGl0IGlzIHVuc2FmZSB0byB0aHJvdyBkdXJpbmcgaW5pdGlhbGl6YXRpb24uXG4gICAge1xuICAgICAgZXJyb3IoJ1JlYWN0IGluc3RydW1lbnRhdGlvbiBlbmNvdW50ZXJlZCBhbiBlcnJvcjogJXMuJywgZXJyKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaG9vay5jaGVja0RDRSkge1xuICAgIC8vIFRoaXMgaXMgdGhlIHJlYWwgRGV2VG9vbHMuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBsaWtlbHkgYSBob29rIGluc3RhbGxlZCBieSBGYXN0IFJlZnJlc2ggcnVudGltZS5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIG9uU2NoZWR1bGVSb290KHJvb3QsIGNoaWxkcmVuKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2sub25TY2hlZHVsZUZpYmVyUm9vdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW5qZWN0ZWRIb29rLm9uU2NoZWR1bGVGaWJlclJvb3QocmVuZGVyZXJJRCwgcm9vdCwgY2hpbGRyZW4pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmICggIWhhc0xvZ2dlZEVycm9yKSB7XG4gICAgICAgICAgaGFzTG9nZ2VkRXJyb3IgPSB0cnVlO1xuXG4gICAgICAgICAgZXJyb3IoJ1JlYWN0IGluc3RydW1lbnRhdGlvbiBlbmNvdW50ZXJlZCBhbiBlcnJvcjogJXMnLCBlcnIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBvbkNvbW1pdFJvb3Qocm9vdCwgZXZlbnRQcmlvcml0eSkge1xuICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2sub25Db21taXRGaWJlclJvb3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIGRpZEVycm9yID0gKHJvb3QuY3VycmVudC5mbGFncyAmIERpZENhcHR1cmUpID09PSBEaWRDYXB0dXJlO1xuXG4gICAgICBpZiAoZW5hYmxlUHJvZmlsZXJUaW1lcikge1xuICAgICAgICB2YXIgc2NoZWR1bGVyUHJpb3JpdHk7XG5cbiAgICAgICAgc3dpdGNoIChldmVudFByaW9yaXR5KSB7XG4gICAgICAgICAgY2FzZSBEaXNjcmV0ZUV2ZW50UHJpb3JpdHk6XG4gICAgICAgICAgICBzY2hlZHVsZXJQcmlvcml0eSA9IEltbWVkaWF0ZVByaW9yaXR5O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIENvbnRpbnVvdXNFdmVudFByaW9yaXR5OlxuICAgICAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHkgPSBVc2VyQmxvY2tpbmdQcmlvcml0eTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBEZWZhdWx0RXZlbnRQcmlvcml0eTpcbiAgICAgICAgICAgIHNjaGVkdWxlclByaW9yaXR5ID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgSWRsZUV2ZW50UHJpb3JpdHk6XG4gICAgICAgICAgICBzY2hlZHVsZXJQcmlvcml0eSA9IElkbGVQcmlvcml0eTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHNjaGVkdWxlclByaW9yaXR5ID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGluamVjdGVkSG9vay5vbkNvbW1pdEZpYmVyUm9vdChyZW5kZXJlcklELCByb290LCBzY2hlZHVsZXJQcmlvcml0eSwgZGlkRXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5qZWN0ZWRIb29rLm9uQ29tbWl0RmliZXJSb290KHJlbmRlcmVySUQsIHJvb3QsIHVuZGVmaW5lZCwgZGlkRXJyb3IpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAge1xuICAgICAgICBpZiAoIWhhc0xvZ2dlZEVycm9yKSB7XG4gICAgICAgICAgaGFzTG9nZ2VkRXJyb3IgPSB0cnVlO1xuXG4gICAgICAgICAgZXJyb3IoJ1JlYWN0IGluc3RydW1lbnRhdGlvbiBlbmNvdW50ZXJlZCBhbiBlcnJvcjogJXMnLCBlcnIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBvblBvc3RDb21taXRSb290KHJvb3QpIHtcbiAgaWYgKGluamVjdGVkSG9vayAmJiB0eXBlb2YgaW5qZWN0ZWRIb29rLm9uUG9zdENvbW1pdEZpYmVyUm9vdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBpbmplY3RlZEhvb2sub25Qb3N0Q29tbWl0RmliZXJSb290KHJlbmRlcmVySUQsIHJvb3QpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAge1xuICAgICAgICBpZiAoIWhhc0xvZ2dlZEVycm9yKSB7XG4gICAgICAgICAgaGFzTG9nZ2VkRXJyb3IgPSB0cnVlO1xuXG4gICAgICAgICAgZXJyb3IoJ1JlYWN0IGluc3RydW1lbnRhdGlvbiBlbmNvdW50ZXJlZCBhbiBlcnJvcjogJXMnLCBlcnIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBvbkNvbW1pdFVubW91bnQoZmliZXIpIHtcbiAgaWYgKGluamVjdGVkSG9vayAmJiB0eXBlb2YgaW5qZWN0ZWRIb29rLm9uQ29tbWl0RmliZXJVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGluamVjdGVkSG9vay5vbkNvbW1pdEZpYmVyVW5tb3VudChyZW5kZXJlcklELCBmaWJlcik7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB7XG4gICAgICAgIGlmICghaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKG5ld0lzU3RyaWN0TW9kZSkge1xuICB7XG4gICAgaWYgKHR5cGVvZiB1bnN0YWJsZV95aWVsZFZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBXZSdyZSBpbiBhIHRlc3QgYmVjYXVzZSBTY2hlZHVsZXIudW5zdGFibGVfeWllbGRWYWx1ZSBvbmx5IGV4aXN0c1xuICAgICAgLy8gaW4gU2NoZWR1bGVyTW9jay4gVG8gcmVkdWNlIHRoZSBub2lzZSBpbiBzdHJpY3QgbW9kZSB0ZXN0cyxcbiAgICAgIC8vIHN1cHByZXNzIHdhcm5pbmdzIGFuZCBkaXNhYmxlIHNjaGVkdWxlciB5aWVsZGluZyBkdXJpbmcgdGhlIGRvdWJsZSByZW5kZXJcbiAgICAgIHVuc3RhYmxlX3NldERpc2FibGVZaWVsZFZhbHVlKG5ld0lzU3RyaWN0TW9kZSk7XG4gICAgICBzZXRTdXBwcmVzc1dhcm5pbmcobmV3SXNTdHJpY3RNb2RlKTtcbiAgICB9XG5cbiAgICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2suc2V0U3RyaWN0TW9kZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW5qZWN0ZWRIb29rLnNldFN0cmljdE1vZGUocmVuZGVyZXJJRCwgbmV3SXNTdHJpY3RNb2RlKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKCFoYXNMb2dnZWRFcnJvcikge1xuICAgICAgICAgICAgaGFzTG9nZ2VkRXJyb3IgPSB0cnVlO1xuXG4gICAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59IC8vIFByb2ZpbGVyIEFQSSBob29rc1xuXG5mdW5jdGlvbiBpbmplY3RQcm9maWxpbmdIb29rcyhwcm9maWxpbmdIb29rcykge1xuICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzID0gcHJvZmlsaW5nSG9va3M7XG59XG5cbmZ1bmN0aW9uIGdldExhbmVMYWJlbE1hcCgpIHtcbiAge1xuICAgIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gICAgdmFyIGxhbmUgPSAxO1xuXG4gICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IFRvdGFsTGFuZXM7IGluZGV4KyspIHtcbiAgICAgIHZhciBsYWJlbCA9IGdldExhYmVsRm9yTGFuZShsYW5lKTtcbiAgICAgIG1hcC5zZXQobGFuZSwgbGFiZWwpO1xuICAgICAgbGFuZSAqPSAyO1xuICAgIH1cblxuICAgIHJldHVybiBtYXA7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFya0NvbW1pdFN0YXJ0ZWQobGFuZXMpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21taXRTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21taXRTdGFydGVkKGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21taXRTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbW1pdFN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbW1pdFN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZChmaWJlcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RhcnRlZChmaWJlcikge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RNb3VudFN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RNb3VudFN0YXJ0ZWQoZmliZXIpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RNb3VudFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RhcnRlZChmaWJlcikge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdFVubW91bnRTdGFydGVkKGZpYmVyKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdFVubW91bnRTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RNb3VudFN0YXJ0ZWQoZmliZXIpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RNb3VudFN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZChmaWJlcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0VW5tb3VudFN0YXJ0ZWQoZmliZXIpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0VW5tb3VudFN0YXJ0ZWQoZmliZXIpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudEVycm9yZWQoZmliZXIsIHRocm93blZhbHVlLCBsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudEVycm9yZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudEVycm9yZWQoZmliZXIsIHRocm93blZhbHVlLCBsYW5lcyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50U3VzcGVuZGVkKGZpYmVyLCB3YWtlYWJsZSwgbGFuZXMpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRTdXNwZW5kZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFN1c3BlbmRlZChmaWJlciwgd2FrZWFibGUsIGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtMYXlvdXRFZmZlY3RzU3RhcnRlZChsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0xheW91dEVmZmVjdHNTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtMYXlvdXRFZmZlY3RzU3RhcnRlZChsYW5lcyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrTGF5b3V0RWZmZWN0c1N0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrTGF5b3V0RWZmZWN0c1N0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0xheW91dEVmZmVjdHNTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrUGFzc2l2ZUVmZmVjdHNTdGFydGVkKGxhbmVzKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUGFzc2l2ZUVmZmVjdHNTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtQYXNzaXZlRWZmZWN0c1N0YXJ0ZWQobGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1Bhc3NpdmVFZmZlY3RzU3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtQYXNzaXZlRWZmZWN0c1N0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1Bhc3NpdmVFZmZlY3RzU3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlclN0YXJ0ZWQobGFuZXMpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtSZW5kZXJTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtSZW5kZXJTdGFydGVkKGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtSZW5kZXJZaWVsZGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlcllpZWxkZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlcllpZWxkZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtSZW5kZXJTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtSZW5kZXJTY2hlZHVsZWQobGFuZSkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclNjaGVkdWxlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU2NoZWR1bGVkKGxhbmUpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0ZvcmNlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrRm9yY2VVcGRhdGVTY2hlZHVsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0ZvcmNlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtTdGF0ZVVwZGF0ZVNjaGVkdWxlZChmaWJlciwgbGFuZSkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtTdGF0ZVVwZGF0ZVNjaGVkdWxlZChmaWJlciwgbGFuZSk7XG4gICAgfVxuICB9XG59XG5cbnZhciBOb01vZGUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjA7IC8vIFRPRE86IFJlbW92ZSBDb25jdXJyZW50TW9kZSBieSByZWFkaW5nIGZyb20gdGhlIHJvb3QgdGFnIGluc3RlYWRcblxudmFyIENvbmN1cnJlbnRNb2RlID1cbi8qICAgICAgICAgICAgICAgICAqL1xuMTtcbnZhciBQcm9maWxlTW9kZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgKi9cbjI7XG52YXIgU3RyaWN0TGVnYWN5TW9kZSA9XG4vKiAgICAgICAgICAgICAgICovXG44O1xudmFyIFN0cmljdEVmZmVjdHNNb2RlID1cbi8qICAgICAgICAgICAgICAqL1xuMTY7XG5cbi8vIFRPRE86IFRoaXMgaXMgcHJldHR5IHdlbGwgc3VwcG9ydGVkIGJ5IGJyb3dzZXJzLiBNYXliZSB3ZSBjYW4gZHJvcCBpdC5cbnZhciBjbHozMiA9IE1hdGguY2x6MzIgPyBNYXRoLmNsejMyIDogY2x6MzJGYWxsYmFjazsgLy8gQ291bnQgbGVhZGluZyB6ZXJvcy5cbi8vIEJhc2VkIG9uOlxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWF0aC9jbHozMlxuXG52YXIgbG9nID0gTWF0aC5sb2c7XG52YXIgTE4yID0gTWF0aC5MTjI7XG5cbmZ1bmN0aW9uIGNsejMyRmFsbGJhY2soeCkge1xuICB2YXIgYXNVaW50ID0geCA+Pj4gMDtcblxuICBpZiAoYXNVaW50ID09PSAwKSB7XG4gICAgcmV0dXJuIDMyO1xuICB9XG5cbiAgcmV0dXJuIDMxIC0gKGxvZyhhc1VpbnQpIC8gTE4yIHwgMCkgfCAwO1xufVxuXG4vLyBJZiB0aG9zZSB2YWx1ZXMgYXJlIGNoYW5nZWQgdGhhdCBwYWNrYWdlIHNob3VsZCBiZSByZWJ1aWx0IGFuZCByZWRlcGxveWVkLlxuXG52YXIgVG90YWxMYW5lcyA9IDMxO1xudmFyIE5vTGFuZXMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuMDtcbnZhciBOb0xhbmUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICovXG4wO1xudmFyIFN5bmNMYW5lID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjE7XG52YXIgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZSA9XG4vKiAgICAqL1xuMjtcbnZhciBJbnB1dENvbnRpbnVvdXNMYW5lID1cbi8qICAgICAgICAgICAgICovXG40O1xudmFyIERlZmF1bHRIeWRyYXRpb25MYW5lID1cbi8qICAgICAgICAgICAgKi9cbjg7XG52YXIgRGVmYXVsdExhbmUgPVxuLyogICAgICAgICAgICAgICAgICAgICAqL1xuMTY7XG52YXIgVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgICAgICAgKi9cbjMyO1xudmFyIFRyYW5zaXRpb25MYW5lcyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjQxOTQyNDA7XG52YXIgVHJhbnNpdGlvbkxhbmUxID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjY0O1xudmFyIFRyYW5zaXRpb25MYW5lMiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG4xMjg7XG52YXIgVHJhbnNpdGlvbkxhbmUzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjI1NjtcbnZhciBUcmFuc2l0aW9uTGFuZTQgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuNTEyO1xudmFyIFRyYW5zaXRpb25MYW5lNSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG4xMDI0O1xudmFyIFRyYW5zaXRpb25MYW5lNiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG4yMDQ4O1xudmFyIFRyYW5zaXRpb25MYW5lNyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG40MDk2O1xudmFyIFRyYW5zaXRpb25MYW5lOCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG44MTkyO1xudmFyIFRyYW5zaXRpb25MYW5lOSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG4xNjM4NDtcbnZhciBUcmFuc2l0aW9uTGFuZTEwID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuMzI3Njg7XG52YXIgVHJhbnNpdGlvbkxhbmUxMSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjY1NTM2O1xudmFyIFRyYW5zaXRpb25MYW5lMTIgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG4xMzEwNzI7XG52YXIgVHJhbnNpdGlvbkxhbmUxMyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjI2MjE0NDtcbnZhciBUcmFuc2l0aW9uTGFuZTE0ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuNTI0Mjg4O1xudmFyIFRyYW5zaXRpb25MYW5lMTUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG4xMDQ4NTc2O1xudmFyIFRyYW5zaXRpb25MYW5lMTYgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG4yMDk3MTUyO1xudmFyIFJldHJ5TGFuZXMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEzMDAyMzQyNDtcbnZhciBSZXRyeUxhbmUxID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuNDE5NDMwNDtcbnZhciBSZXRyeUxhbmUyID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuODM4ODYwODtcbnZhciBSZXRyeUxhbmUzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMTY3NzcyMTY7XG52YXIgUmV0cnlMYW5lNCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjMzNTU0NDMyO1xudmFyIFJldHJ5TGFuZTUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG42NzEwODg2NDtcbnZhciBTb21lUmV0cnlMYW5lID0gUmV0cnlMYW5lMTtcbnZhciBTZWxlY3RpdmVIeWRyYXRpb25MYW5lID1cbi8qICAgICAgICAgICovXG4xMzQyMTc3Mjg7XG52YXIgTm9uSWRsZUxhbmVzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMjY4NDM1NDU1O1xudmFyIElkbGVIeWRyYXRpb25MYW5lID1cbi8qICAgICAgICAgICAgICAgKi9cbjI2ODQzNTQ1NjtcbnZhciBJZGxlTGFuZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG41MzY4NzA5MTI7XG52YXIgT2Zmc2NyZWVuTGFuZSA9XG4vKiAgICAgICAgICAgICAgICAgICAqL1xuMTA3Mzc0MTgyNDsgLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciB0aGUgZXhwZXJpbWVudGFsIHRpbWVsaW5lIChyZWFjdC1kZXZ0b29scy10aW1lbGluZSlcbi8vIEl0IHNob3VsZCBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUgTGFuZXMgdmFsdWVzIGFib3ZlLlxuXG5mdW5jdGlvbiBnZXRMYWJlbEZvckxhbmUobGFuZSkge1xuICB7XG4gICAgaWYgKGxhbmUgJiBTeW5jTGFuZSkge1xuICAgICAgcmV0dXJuICdTeW5jJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIElucHV0Q29udGludW91c0h5ZHJhdGlvbkxhbmUpIHtcbiAgICAgIHJldHVybiAnSW5wdXRDb250aW51b3VzSHlkcmF0aW9uJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIElucHV0Q29udGludW91c0xhbmUpIHtcbiAgICAgIHJldHVybiAnSW5wdXRDb250aW51b3VzJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIERlZmF1bHRIeWRyYXRpb25MYW5lKSB7XG4gICAgICByZXR1cm4gJ0RlZmF1bHRIeWRyYXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgRGVmYXVsdExhbmUpIHtcbiAgICAgIHJldHVybiAnRGVmYXVsdCc7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBUcmFuc2l0aW9uSHlkcmF0aW9uTGFuZSkge1xuICAgICAgcmV0dXJuICdUcmFuc2l0aW9uSHlkcmF0aW9uJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIFRyYW5zaXRpb25MYW5lcykge1xuICAgICAgcmV0dXJuICdUcmFuc2l0aW9uJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIFJldHJ5TGFuZXMpIHtcbiAgICAgIHJldHVybiAnUmV0cnknO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgU2VsZWN0aXZlSHlkcmF0aW9uTGFuZSkge1xuICAgICAgcmV0dXJuICdTZWxlY3RpdmVIeWRyYXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgSWRsZUh5ZHJhdGlvbkxhbmUpIHtcbiAgICAgIHJldHVybiAnSWRsZUh5ZHJhdGlvbic7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBJZGxlTGFuZSkge1xuICAgICAgcmV0dXJuICdJZGxlJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIE9mZnNjcmVlbkxhbmUpIHtcbiAgICAgIHJldHVybiAnT2Zmc2NyZWVuJztcbiAgICB9XG4gIH1cbn1cbnZhciBOb1RpbWVzdGFtcCA9IC0xO1xudmFyIG5leHRUcmFuc2l0aW9uTGFuZSA9IFRyYW5zaXRpb25MYW5lMTtcbnZhciBuZXh0UmV0cnlMYW5lID0gUmV0cnlMYW5lMTtcblxuZnVuY3Rpb24gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZXMobGFuZXMpIHtcbiAgc3dpdGNoIChnZXRIaWdoZXN0UHJpb3JpdHlMYW5lKGxhbmVzKSkge1xuICAgIGNhc2UgU3luY0xhbmU6XG4gICAgICByZXR1cm4gU3luY0xhbmU7XG5cbiAgICBjYXNlIElucHV0Q29udGludW91c0h5ZHJhdGlvbkxhbmU6XG4gICAgICByZXR1cm4gSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZTtcblxuICAgIGNhc2UgSW5wdXRDb250aW51b3VzTGFuZTpcbiAgICAgIHJldHVybiBJbnB1dENvbnRpbnVvdXNMYW5lO1xuXG4gICAgY2FzZSBEZWZhdWx0SHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBEZWZhdWx0SHlkcmF0aW9uTGFuZTtcblxuICAgIGNhc2UgRGVmYXVsdExhbmU6XG4gICAgICByZXR1cm4gRGVmYXVsdExhbmU7XG5cbiAgICBjYXNlIFRyYW5zaXRpb25IeWRyYXRpb25MYW5lOlxuICAgICAgcmV0dXJuIFRyYW5zaXRpb25IeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTQ6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTY6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTc6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTg6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTk6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEwOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEzOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE2OlxuICAgICAgcmV0dXJuIGxhbmVzICYgVHJhbnNpdGlvbkxhbmVzO1xuXG4gICAgY2FzZSBSZXRyeUxhbmUxOlxuICAgIGNhc2UgUmV0cnlMYW5lMjpcbiAgICBjYXNlIFJldHJ5TGFuZTM6XG4gICAgY2FzZSBSZXRyeUxhbmU0OlxuICAgIGNhc2UgUmV0cnlMYW5lNTpcbiAgICAgIHJldHVybiBsYW5lcyAmIFJldHJ5TGFuZXM7XG5cbiAgICBjYXNlIFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmU6XG4gICAgICByZXR1cm4gU2VsZWN0aXZlSHlkcmF0aW9uTGFuZTtcblxuICAgIGNhc2UgSWRsZUh5ZHJhdGlvbkxhbmU6XG4gICAgICByZXR1cm4gSWRsZUh5ZHJhdGlvbkxhbmU7XG5cbiAgICBjYXNlIElkbGVMYW5lOlxuICAgICAgcmV0dXJuIElkbGVMYW5lO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5MYW5lOlxuICAgICAgcmV0dXJuIE9mZnNjcmVlbkxhbmU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAge1xuICAgICAgICBlcnJvcignU2hvdWxkIGhhdmUgZm91bmQgbWF0Y2hpbmcgbGFuZXMuIFRoaXMgaXMgYSBidWcgaW4gUmVhY3QuJyk7XG4gICAgICB9IC8vIFRoaXMgc2hvdWxkbid0IGJlIHJlYWNoYWJsZSwgYnV0IGFzIGEgZmFsbGJhY2ssIHJldHVybiB0aGUgZW50aXJlIGJpdG1hc2suXG5cblxuICAgICAgcmV0dXJuIGxhbmVzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE5leHRMYW5lcyhyb290LCB3aXBMYW5lcykge1xuICAvLyBFYXJseSBiYWlsb3V0IGlmIHRoZXJlJ3Mgbm8gcGVuZGluZyB3b3JrIGxlZnQuXG4gIHZhciBwZW5kaW5nTGFuZXMgPSByb290LnBlbmRpbmdMYW5lcztcblxuICBpZiAocGVuZGluZ0xhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgcmV0dXJuIE5vTGFuZXM7XG4gIH1cblxuICB2YXIgbmV4dExhbmVzID0gTm9MYW5lcztcbiAgdmFyIHN1c3BlbmRlZExhbmVzID0gcm9vdC5zdXNwZW5kZWRMYW5lcztcbiAgdmFyIHBpbmdlZExhbmVzID0gcm9vdC5waW5nZWRMYW5lczsgLy8gRG8gbm90IHdvcmsgb24gYW55IGlkbGUgd29yayB1bnRpbCBhbGwgdGhlIG5vbi1pZGxlIHdvcmsgaGFzIGZpbmlzaGVkLFxuICAvLyBldmVuIGlmIHRoZSB3b3JrIGlzIHN1c3BlbmRlZC5cblxuICB2YXIgbm9uSWRsZVBlbmRpbmdMYW5lcyA9IHBlbmRpbmdMYW5lcyAmIE5vbklkbGVMYW5lcztcblxuICBpZiAobm9uSWRsZVBlbmRpbmdMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgIHZhciBub25JZGxlVW5ibG9ja2VkTGFuZXMgPSBub25JZGxlUGVuZGluZ0xhbmVzICYgfnN1c3BlbmRlZExhbmVzO1xuXG4gICAgaWYgKG5vbklkbGVVbmJsb2NrZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgbmV4dExhbmVzID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZXMobm9uSWRsZVVuYmxvY2tlZExhbmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG5vbklkbGVQaW5nZWRMYW5lcyA9IG5vbklkbGVQZW5kaW5nTGFuZXMgJiBwaW5nZWRMYW5lcztcblxuICAgICAgaWYgKG5vbklkbGVQaW5nZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhub25JZGxlUGluZ2VkTGFuZXMpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBUaGUgb25seSByZW1haW5pbmcgd29yayBpcyBJZGxlLlxuICAgIHZhciB1bmJsb2NrZWRMYW5lcyA9IHBlbmRpbmdMYW5lcyAmIH5zdXNwZW5kZWRMYW5lcztcblxuICAgIGlmICh1bmJsb2NrZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgbmV4dExhbmVzID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZXModW5ibG9ja2VkTGFuZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocGluZ2VkTGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICAgICAgbmV4dExhbmVzID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZXMocGluZ2VkTGFuZXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChuZXh0TGFuZXMgPT09IE5vTGFuZXMpIHtcbiAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGJlIHJlYWNoYWJsZSBpZiB3ZSdyZSBzdXNwZW5kZWRcbiAgICAvLyBUT0RPOiBDb25zaWRlciB3YXJuaW5nIGluIHRoaXMgcGF0aCBpZiBhIGZhbGxiYWNrIHRpbWVyIGlzIG5vdCBzY2hlZHVsZWQuXG4gICAgcmV0dXJuIE5vTGFuZXM7XG4gIH0gLy8gSWYgd2UncmUgYWxyZWFkeSBpbiB0aGUgbWlkZGxlIG9mIGEgcmVuZGVyLCBzd2l0Y2hpbmcgbGFuZXMgd2lsbCBpbnRlcnJ1cHRcbiAgLy8gaXQgYW5kIHdlJ2xsIGxvc2Ugb3VyIHByb2dyZXNzLiBXZSBzaG91bGQgb25seSBkbyB0aGlzIGlmIHRoZSBuZXcgbGFuZXMgYXJlXG4gIC8vIGhpZ2hlciBwcmlvcml0eS5cblxuXG4gIGlmICh3aXBMYW5lcyAhPT0gTm9MYW5lcyAmJiB3aXBMYW5lcyAhPT0gbmV4dExhbmVzICYmIC8vIElmIHdlIGFscmVhZHkgc3VzcGVuZGVkIHdpdGggYSBkZWxheSwgdGhlbiBpbnRlcnJ1cHRpbmcgaXMgZmluZS4gRG9uJ3RcbiAgLy8gYm90aGVyIHdhaXRpbmcgdW50aWwgdGhlIHJvb3QgaXMgY29tcGxldGUuXG4gICh3aXBMYW5lcyAmIHN1c3BlbmRlZExhbmVzKSA9PT0gTm9MYW5lcykge1xuICAgIHZhciBuZXh0TGFuZSA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmUobmV4dExhbmVzKTtcbiAgICB2YXIgd2lwTGFuZSA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmUod2lwTGFuZXMpO1xuXG4gICAgaWYgKCAvLyBUZXN0cyB3aGV0aGVyIHRoZSBuZXh0IGxhbmUgaXMgZXF1YWwgb3IgbG93ZXIgcHJpb3JpdHkgdGhhbiB0aGUgd2lwXG4gICAgLy8gb25lLiBUaGlzIHdvcmtzIGJlY2F1c2UgdGhlIGJpdHMgZGVjcmVhc2UgaW4gcHJpb3JpdHkgYXMgeW91IGdvIGxlZnQuXG4gICAgbmV4dExhbmUgPj0gd2lwTGFuZSB8fCAvLyBEZWZhdWx0IHByaW9yaXR5IHVwZGF0ZXMgc2hvdWxkIG5vdCBpbnRlcnJ1cHQgdHJhbnNpdGlvbiB1cGRhdGVzLiBUaGVcbiAgICAvLyBvbmx5IGRpZmZlcmVuY2UgYmV0d2VlbiBkZWZhdWx0IHVwZGF0ZXMgYW5kIHRyYW5zaXRpb24gdXBkYXRlcyBpcyB0aGF0XG4gICAgLy8gZGVmYXVsdCB1cGRhdGVzIGRvIG5vdCBzdXBwb3J0IHJlZnJlc2ggdHJhbnNpdGlvbnMuXG4gICAgbmV4dExhbmUgPT09IERlZmF1bHRMYW5lICYmICh3aXBMYW5lICYgVHJhbnNpdGlvbkxhbmVzKSAhPT0gTm9MYW5lcykge1xuICAgICAgLy8gS2VlcCB3b3JraW5nIG9uIHRoZSBleGlzdGluZyBpbi1wcm9ncmVzcyB0cmVlLiBEbyBub3QgaW50ZXJydXB0LlxuICAgICAgcmV0dXJuIHdpcExhbmVzO1xuICAgIH1cbiAgfVxuXG4gIGlmICgobmV4dExhbmVzICYgSW5wdXRDb250aW51b3VzTGFuZSkgIT09IE5vTGFuZXMpIHtcbiAgICAvLyBXaGVuIHVwZGF0ZXMgYXJlIHN5bmMgYnkgZGVmYXVsdCwgd2UgZW50YW5nbGUgY29udGludW91cyBwcmlvcml0eSB1cGRhdGVzXG4gICAgLy8gYW5kIGRlZmF1bHQgdXBkYXRlcywgc28gdGhleSByZW5kZXIgaW4gdGhlIHNhbWUgYmF0Y2guIFRoZSBvbmx5IHJlYXNvblxuICAgIC8vIHRoZXkgdXNlIHNlcGFyYXRlIGxhbmVzIGlzIGJlY2F1c2UgY29udGludW91cyB1cGRhdGVzIHNob3VsZCBpbnRlcnJ1cHRcbiAgICAvLyB0cmFuc2l0aW9ucywgYnV0IGRlZmF1bHQgdXBkYXRlcyBzaG91bGQgbm90LlxuICAgIG5leHRMYW5lcyB8PSBwZW5kaW5nTGFuZXMgJiBEZWZhdWx0TGFuZTtcbiAgfSAvLyBDaGVjayBmb3IgZW50YW5nbGVkIGxhbmVzIGFuZCBhZGQgdGhlbSB0byB0aGUgYmF0Y2guXG4gIC8vXG4gIC8vIEEgbGFuZSBpcyBzYWlkIHRvIGJlIGVudGFuZ2xlZCB3aXRoIGFub3RoZXIgd2hlbiBpdCdzIG5vdCBhbGxvd2VkIHRvIHJlbmRlclxuICAvLyBpbiBhIGJhdGNoIHRoYXQgZG9lcyBub3QgYWxzbyBpbmNsdWRlIHRoZSBvdGhlciBsYW5lLiBUeXBpY2FsbHkgd2UgZG8gdGhpc1xuICAvLyB3aGVuIG11bHRpcGxlIHVwZGF0ZXMgaGF2ZSB0aGUgc2FtZSBzb3VyY2UsIGFuZCB3ZSBvbmx5IHdhbnQgdG8gcmVzcG9uZCB0b1xuICAvLyB0aGUgbW9zdCByZWNlbnQgZXZlbnQgZnJvbSB0aGF0IHNvdXJjZS5cbiAgLy9cbiAgLy8gTm90ZSB0aGF0IHdlIGFwcGx5IGVudGFuZ2xlbWVudHMgKmFmdGVyKiBjaGVja2luZyBmb3IgcGFydGlhbCB3b3JrIGFib3ZlLlxuICAvLyBUaGlzIG1lYW5zIHRoYXQgaWYgYSBsYW5lIGlzIGVudGFuZ2xlZCBkdXJpbmcgYW4gaW50ZXJsZWF2ZWQgZXZlbnQgd2hpbGVcbiAgLy8gaXQncyBhbHJlYWR5IHJlbmRlcmluZywgd2Ugd29uJ3QgaW50ZXJydXB0IGl0LiBUaGlzIGlzIGludGVudGlvbmFsLCBzaW5jZVxuICAvLyBlbnRhbmdsZW1lbnQgaXMgdXN1YWxseSBcImJlc3QgZWZmb3J0XCI6IHdlJ2xsIHRyeSBvdXIgYmVzdCB0byByZW5kZXIgdGhlXG4gIC8vIGxhbmVzIGluIHRoZSBzYW1lIGJhdGNoLCBidXQgaXQncyBub3Qgd29ydGggdGhyb3dpbmcgb3V0IHBhcnRpYWxseVxuICAvLyBjb21wbGV0ZWQgd29yayBpbiBvcmRlciB0byBkbyBpdC5cbiAgLy8gVE9ETzogUmVjb25zaWRlciB0aGlzLiBUaGUgY291bnRlci1hcmd1bWVudCBpcyB0aGF0IHRoZSBwYXJ0aWFsIHdvcmtcbiAgLy8gcmVwcmVzZW50cyBhbiBpbnRlcm1lZGlhdGUgc3RhdGUsIHdoaWNoIHdlIGRvbid0IHdhbnQgdG8gc2hvdyB0byB0aGUgdXNlci5cbiAgLy8gQW5kIGJ5IHNwZW5kaW5nIGV4dHJhIHRpbWUgZmluaXNoaW5nIGl0LCB3ZSdyZSBpbmNyZWFzaW5nIHRoZSBhbW91bnQgb2ZcbiAgLy8gdGltZSBpdCB0YWtlcyB0byBzaG93IHRoZSBmaW5hbCBzdGF0ZSwgd2hpY2ggaXMgd2hhdCB0aGV5IGFyZSBhY3R1YWxseVxuICAvLyB3YWl0aW5nIGZvci5cbiAgLy9cbiAgLy8gRm9yIHRob3NlIGV4Y2VwdGlvbnMgd2hlcmUgZW50YW5nbGVtZW50IGlzIHNlbWFudGljYWxseSBpbXBvcnRhbnQsIGxpa2VcbiAgLy8gdXNlTXV0YWJsZVNvdXJjZSwgd2Ugc2hvdWxkIGVuc3VyZSB0aGF0IHRoZXJlIGlzIG5vIHBhcnRpYWwgd29yayBhdCB0aGVcbiAgLy8gdGltZSB3ZSBhcHBseSB0aGUgZW50YW5nbGVtZW50LlxuXG5cbiAgdmFyIGVudGFuZ2xlZExhbmVzID0gcm9vdC5lbnRhbmdsZWRMYW5lcztcblxuICBpZiAoZW50YW5nbGVkTGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICB2YXIgZW50YW5nbGVtZW50cyA9IHJvb3QuZW50YW5nbGVtZW50cztcbiAgICB2YXIgbGFuZXMgPSBuZXh0TGFuZXMgJiBlbnRhbmdsZWRMYW5lcztcblxuICAgIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICAgIHZhciBpbmRleCA9IHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZXMpO1xuICAgICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgICAgbmV4dExhbmVzIHw9IGVudGFuZ2xlbWVudHNbaW5kZXhdO1xuICAgICAgbGFuZXMgJj0gfmxhbmU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRMYW5lcztcbn1cbmZ1bmN0aW9uIGdldE1vc3RSZWNlbnRFdmVudFRpbWUocm9vdCwgbGFuZXMpIHtcbiAgdmFyIGV2ZW50VGltZXMgPSByb290LmV2ZW50VGltZXM7XG4gIHZhciBtb3N0UmVjZW50RXZlbnRUaW1lID0gTm9UaW1lc3RhbXA7XG5cbiAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgIHZhciBpbmRleCA9IHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZXMpO1xuICAgIHZhciBsYW5lID0gMSA8PCBpbmRleDtcbiAgICB2YXIgZXZlbnRUaW1lID0gZXZlbnRUaW1lc1tpbmRleF07XG5cbiAgICBpZiAoZXZlbnRUaW1lID4gbW9zdFJlY2VudEV2ZW50VGltZSkge1xuICAgICAgbW9zdFJlY2VudEV2ZW50VGltZSA9IGV2ZW50VGltZTtcbiAgICB9XG5cbiAgICBsYW5lcyAmPSB+bGFuZTtcbiAgfVxuXG4gIHJldHVybiBtb3N0UmVjZW50RXZlbnRUaW1lO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlRXhwaXJhdGlvblRpbWUobGFuZSwgY3VycmVudFRpbWUpIHtcbiAgc3dpdGNoIChsYW5lKSB7XG4gICAgY2FzZSBTeW5jTGFuZTpcbiAgICBjYXNlIElucHV0Q29udGludW91c0h5ZHJhdGlvbkxhbmU6XG4gICAgY2FzZSBJbnB1dENvbnRpbnVvdXNMYW5lOlxuICAgICAgLy8gVXNlciBpbnRlcmFjdGlvbnMgc2hvdWxkIGV4cGlyZSBzbGlnaHRseSBtb3JlIHF1aWNrbHkuXG4gICAgICAvL1xuICAgICAgLy8gTk9URTogVGhpcyBpcyBzZXQgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY29uc3RhbnQgYXMgaW4gU2NoZWR1bGVyLmpzLlxuICAgICAgLy8gV2hlbiB3ZSBtYWRlIGl0IGxhcmdlciwgYSBwcm9kdWN0IG1ldHJpYyBpbiB3d3cgcmVncmVzc2VkLCBzdWdnZXN0aW5nXG4gICAgICAvLyB0aGVyZSdzIGEgdXNlciBpbnRlcmFjdGlvbiB0aGF0J3MgYmVpbmcgc3RhcnZlZCBieSBhIHNlcmllcyBvZlxuICAgICAgLy8gc3luY2hyb25vdXMgdXBkYXRlcy4gSWYgdGhhdCB0aGVvcnkgaXMgY29ycmVjdCwgdGhlIHByb3BlciBzb2x1dGlvbiBpc1xuICAgICAgLy8gdG8gZml4IHRoZSBzdGFydmF0aW9uLiBIb3dldmVyLCB0aGlzIHNjZW5hcmlvIHN1cHBvcnRzIHRoZSBpZGVhIHRoYXRcbiAgICAgIC8vIGV4cGlyYXRpb24gdGltZXMgYXJlIGFuIGltcG9ydGFudCBzYWZlZ3VhcmQgd2hlbiBzdGFydmF0aW9uXG4gICAgICAvLyBkb2VzIGhhcHBlbi5cbiAgICAgIHJldHVybiBjdXJyZW50VGltZSArIDI1MDtcblxuICAgIGNhc2UgRGVmYXVsdEh5ZHJhdGlvbkxhbmU6XG4gICAgY2FzZSBEZWZhdWx0TGFuZTpcbiAgICBjYXNlIFRyYW5zaXRpb25IeWRyYXRpb25MYW5lOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUyOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUzOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmU0OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmU1OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmU2OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmU3OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmU4OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmU5OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTE6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEyOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTQ6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE1OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNjpcbiAgICAgIHJldHVybiBjdXJyZW50VGltZSArIDUwMDA7XG5cbiAgICBjYXNlIFJldHJ5TGFuZTE6XG4gICAgY2FzZSBSZXRyeUxhbmUyOlxuICAgIGNhc2UgUmV0cnlMYW5lMzpcbiAgICBjYXNlIFJldHJ5TGFuZTQ6XG4gICAgY2FzZSBSZXRyeUxhbmU1OlxuICAgICAgLy8gVE9ETzogUmV0cmllcyBzaG91bGQgYmUgYWxsb3dlZCB0byBleHBpcmUgaWYgdGhleSBhcmUgQ1BVIGJvdW5kIGZvclxuICAgICAgLy8gdG9vIGxvbmcsIGJ1dCB3aGVuIEkgbWFkZSB0aGlzIGNoYW5nZSBpdCBjYXVzZWQgYSBzcGlrZSBpbiBicm93c2VyXG4gICAgICAvLyBjcmFzaGVzLiBUaGVyZSBtdXN0IGJlIHNvbWUgb3RoZXIgdW5kZXJseWluZyBidWc7IG5vdCBzdXBlciB1cmdlbnQgYnV0XG4gICAgICAvLyBpZGVhbGx5IHNob3VsZCBmaWd1cmUgb3V0IHdoeSBhbmQgZml4IGl0LiBVbmZvcnR1bmF0ZWx5IHdlIGRvbid0IGhhdmVcbiAgICAgIC8vIGEgcmVwcm8gZm9yIHRoZSBjcmFzaGVzLCBvbmx5IGRldGVjdGVkIHZpYSBwcm9kdWN0aW9uIG1ldHJpY3MuXG4gICAgICByZXR1cm4gTm9UaW1lc3RhbXA7XG5cbiAgICBjYXNlIFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmU6XG4gICAgY2FzZSBJZGxlSHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIElkbGVMYW5lOlxuICAgIGNhc2UgT2Zmc2NyZWVuTGFuZTpcbiAgICAgIC8vIEFueXRoaW5nIGlkbGUgcHJpb3JpdHkgb3IgbG93ZXIgc2hvdWxkIG5ldmVyIGV4cGlyZS5cbiAgICAgIHJldHVybiBOb1RpbWVzdGFtcDtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIGVycm9yKCdTaG91bGQgaGF2ZSBmb3VuZCBtYXRjaGluZyBsYW5lcy4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIE5vVGltZXN0YW1wO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtTdGFydmVkTGFuZXNBc0V4cGlyZWQocm9vdCwgY3VycmVudFRpbWUpIHtcbiAgLy8gVE9ETzogVGhpcyBnZXRzIGNhbGxlZCBldmVyeSB0aW1lIHdlIHlpZWxkLiBXZSBjYW4gb3B0aW1pemUgYnkgc3RvcmluZ1xuICAvLyB0aGUgZWFybGllc3QgZXhwaXJhdGlvbiB0aW1lIG9uIHRoZSByb290LiBUaGVuIHVzZSB0aGF0IHRvIHF1aWNrbHkgYmFpbCBvdXRcbiAgLy8gb2YgdGhpcyBmdW5jdGlvbi5cbiAgdmFyIHBlbmRpbmdMYW5lcyA9IHJvb3QucGVuZGluZ0xhbmVzO1xuICB2YXIgc3VzcGVuZGVkTGFuZXMgPSByb290LnN1c3BlbmRlZExhbmVzO1xuICB2YXIgcGluZ2VkTGFuZXMgPSByb290LnBpbmdlZExhbmVzO1xuICB2YXIgZXhwaXJhdGlvblRpbWVzID0gcm9vdC5leHBpcmF0aW9uVGltZXM7IC8vIEl0ZXJhdGUgdGhyb3VnaCB0aGUgcGVuZGluZyBsYW5lcyBhbmQgY2hlY2sgaWYgd2UndmUgcmVhY2hlZCB0aGVpclxuICAvLyBleHBpcmF0aW9uIHRpbWUuIElmIHNvLCB3ZSdsbCBhc3N1bWUgdGhlIHVwZGF0ZSBpcyBiZWluZyBzdGFydmVkIGFuZCBtYXJrXG4gIC8vIGl0IGFzIGV4cGlyZWQgdG8gZm9yY2UgaXQgdG8gZmluaXNoLlxuXG4gIHZhciBsYW5lcyA9IHBlbmRpbmdMYW5lcztcblxuICB3aGlsZSAobGFuZXMgPiAwKSB7XG4gICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIHZhciBleHBpcmF0aW9uVGltZSA9IGV4cGlyYXRpb25UaW1lc1tpbmRleF07XG5cbiAgICBpZiAoZXhwaXJhdGlvblRpbWUgPT09IE5vVGltZXN0YW1wKSB7XG4gICAgICAvLyBGb3VuZCBhIHBlbmRpbmcgbGFuZSB3aXRoIG5vIGV4cGlyYXRpb24gdGltZS4gSWYgaXQncyBub3Qgc3VzcGVuZGVkLCBvclxuICAgICAgLy8gaWYgaXQncyBwaW5nZWQsIGFzc3VtZSBpdCdzIENQVS1ib3VuZC4gQ29tcHV0ZSBhIG5ldyBleHBpcmF0aW9uIHRpbWVcbiAgICAgIC8vIHVzaW5nIHRoZSBjdXJyZW50IHRpbWUuXG4gICAgICBpZiAoKGxhbmUgJiBzdXNwZW5kZWRMYW5lcykgPT09IE5vTGFuZXMgfHwgKGxhbmUgJiBwaW5nZWRMYW5lcykgIT09IE5vTGFuZXMpIHtcbiAgICAgICAgLy8gQXNzdW1lcyB0aW1lc3RhbXBzIGFyZSBtb25vdG9uaWNhbGx5IGluY3JlYXNpbmcuXG4gICAgICAgIGV4cGlyYXRpb25UaW1lc1tpbmRleF0gPSBjb21wdXRlRXhwaXJhdGlvblRpbWUobGFuZSwgY3VycmVudFRpbWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXhwaXJhdGlvblRpbWUgPD0gY3VycmVudFRpbWUpIHtcbiAgICAgIC8vIFRoaXMgbGFuZSBleHBpcmVkXG4gICAgICByb290LmV4cGlyZWRMYW5lcyB8PSBsYW5lO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59IC8vIFRoaXMgcmV0dXJucyB0aGUgaGlnaGVzdCBwcmlvcml0eSBwZW5kaW5nIGxhbmVzIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGV5XG4vLyBhcmUgc3VzcGVuZGVkLlxuXG5mdW5jdGlvbiBnZXRIaWdoZXN0UHJpb3JpdHlQZW5kaW5nTGFuZXMocm9vdCkge1xuICByZXR1cm4gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZXMocm9vdC5wZW5kaW5nTGFuZXMpO1xufVxuZnVuY3Rpb24gZ2V0TGFuZXNUb1JldHJ5U3luY2hyb25vdXNseU9uRXJyb3Iocm9vdCkge1xuICB2YXIgZXZlcnl0aGluZ0J1dE9mZnNjcmVlbiA9IHJvb3QucGVuZGluZ0xhbmVzICYgfk9mZnNjcmVlbkxhbmU7XG5cbiAgaWYgKGV2ZXJ5dGhpbmdCdXRPZmZzY3JlZW4gIT09IE5vTGFuZXMpIHtcbiAgICByZXR1cm4gZXZlcnl0aGluZ0J1dE9mZnNjcmVlbjtcbiAgfVxuXG4gIGlmIChldmVyeXRoaW5nQnV0T2Zmc2NyZWVuICYgT2Zmc2NyZWVuTGFuZSkge1xuICAgIHJldHVybiBPZmZzY3JlZW5MYW5lO1xuICB9XG5cbiAgcmV0dXJuIE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc1N5bmNMYW5lKGxhbmVzKSB7XG4gIHJldHVybiAobGFuZXMgJiBTeW5jTGFuZSkgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc05vbklkbGVXb3JrKGxhbmVzKSB7XG4gIHJldHVybiAobGFuZXMgJiBOb25JZGxlTGFuZXMpICE9PSBOb0xhbmVzO1xufVxuZnVuY3Rpb24gaW5jbHVkZXNPbmx5UmV0cmllcyhsYW5lcykge1xuICByZXR1cm4gKGxhbmVzICYgUmV0cnlMYW5lcykgPT09IGxhbmVzO1xufVxuZnVuY3Rpb24gaW5jbHVkZXNPbmx5Tm9uVXJnZW50TGFuZXMobGFuZXMpIHtcbiAgdmFyIFVyZ2VudExhbmVzID0gU3luY0xhbmUgfCBJbnB1dENvbnRpbnVvdXNMYW5lIHwgRGVmYXVsdExhbmU7XG4gIHJldHVybiAobGFuZXMgJiBVcmdlbnRMYW5lcykgPT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc09ubHlUcmFuc2l0aW9ucyhsYW5lcykge1xuICByZXR1cm4gKGxhbmVzICYgVHJhbnNpdGlvbkxhbmVzKSA9PT0gbGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc0Jsb2NraW5nTGFuZShyb290LCBsYW5lcykge1xuXG4gIHZhciBTeW5jRGVmYXVsdExhbmVzID0gSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZSB8IElucHV0Q29udGludW91c0xhbmUgfCBEZWZhdWx0SHlkcmF0aW9uTGFuZSB8IERlZmF1bHRMYW5lO1xuICByZXR1cm4gKGxhbmVzICYgU3luY0RlZmF1bHRMYW5lcykgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc0V4cGlyZWRMYW5lKHJvb3QsIGxhbmVzKSB7XG4gIC8vIFRoaXMgaXMgYSBzZXBhcmF0ZSBjaGVjayBmcm9tIGluY2x1ZGVzQmxvY2tpbmdMYW5lIGJlY2F1c2UgYSBsYW5lIGNhblxuICAvLyBleHBpcmUgYWZ0ZXIgYSByZW5kZXIgaGFzIGFscmVhZHkgc3RhcnRlZC5cbiAgcmV0dXJuIChsYW5lcyAmIHJvb3QuZXhwaXJlZExhbmVzKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGlzVHJhbnNpdGlvbkxhbmUobGFuZSkge1xuICByZXR1cm4gKGxhbmUgJiBUcmFuc2l0aW9uTGFuZXMpICE9PSBOb0xhbmVzO1xufVxuZnVuY3Rpb24gY2xhaW1OZXh0VHJhbnNpdGlvbkxhbmUoKSB7XG4gIC8vIEN5Y2xlIHRocm91Z2ggdGhlIGxhbmVzLCBhc3NpZ25pbmcgZWFjaCBuZXcgdHJhbnNpdGlvbiB0byB0aGUgbmV4dCBsYW5lLlxuICAvLyBJbiBtb3N0IGNhc2VzLCB0aGlzIG1lYW5zIGV2ZXJ5IHRyYW5zaXRpb24gZ2V0cyBpdHMgb3duIGxhbmUsIHVudGlsIHdlXG4gIC8vIHJ1biBvdXQgb2YgbGFuZXMgYW5kIGN5Y2xlIGJhY2sgdG8gdGhlIGJlZ2lubmluZy5cbiAgdmFyIGxhbmUgPSBuZXh0VHJhbnNpdGlvbkxhbmU7XG4gIG5leHRUcmFuc2l0aW9uTGFuZSA8PD0gMTtcblxuICBpZiAoKG5leHRUcmFuc2l0aW9uTGFuZSAmIFRyYW5zaXRpb25MYW5lcykgPT09IE5vTGFuZXMpIHtcbiAgICBuZXh0VHJhbnNpdGlvbkxhbmUgPSBUcmFuc2l0aW9uTGFuZTE7XG4gIH1cblxuICByZXR1cm4gbGFuZTtcbn1cbmZ1bmN0aW9uIGNsYWltTmV4dFJldHJ5TGFuZSgpIHtcbiAgdmFyIGxhbmUgPSBuZXh0UmV0cnlMYW5lO1xuICBuZXh0UmV0cnlMYW5lIDw8PSAxO1xuXG4gIGlmICgobmV4dFJldHJ5TGFuZSAmIFJldHJ5TGFuZXMpID09PSBOb0xhbmVzKSB7XG4gICAgbmV4dFJldHJ5TGFuZSA9IFJldHJ5TGFuZTE7XG4gIH1cblxuICByZXR1cm4gbGFuZTtcbn1cbmZ1bmN0aW9uIGdldEhpZ2hlc3RQcmlvcml0eUxhbmUobGFuZXMpIHtcbiAgcmV0dXJuIGxhbmVzICYgLWxhbmVzO1xufVxuZnVuY3Rpb24gcGlja0FyYml0cmFyeUxhbmUobGFuZXMpIHtcbiAgLy8gVGhpcyB3cmFwcGVyIGZ1bmN0aW9uIGdldHMgaW5saW5lZC4gT25seSBleGlzdHMgc28gdG8gY29tbXVuaWNhdGUgdGhhdCBpdFxuICAvLyBkb2Vzbid0IG1hdHRlciB3aGljaCBiaXQgaXMgc2VsZWN0ZWQ7IHlvdSBjYW4gcGljayBhbnkgYml0IHdpdGhvdXRcbiAgLy8gYWZmZWN0aW5nIHRoZSBhbGdvcml0aG1zIHdoZXJlIGl0cyB1c2VkLiBIZXJlIEknbSB1c2luZ1xuICAvLyBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lIGJlY2F1c2UgaXQgcmVxdWlyZXMgdGhlIGZld2VzdCBvcGVyYXRpb25zLlxuICByZXR1cm4gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShsYW5lcyk7XG59XG5cbmZ1bmN0aW9uIHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZXMpIHtcbiAgcmV0dXJuIDMxIC0gY2x6MzIobGFuZXMpO1xufVxuXG5mdW5jdGlvbiBsYW5lVG9JbmRleChsYW5lKSB7XG4gIHJldHVybiBwaWNrQXJiaXRyYXJ5TGFuZUluZGV4KGxhbmUpO1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlc1NvbWVMYW5lKGEsIGIpIHtcbiAgcmV0dXJuIChhICYgYikgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpc1N1YnNldE9mTGFuZXMoc2V0LCBzdWJzZXQpIHtcbiAgcmV0dXJuIChzZXQgJiBzdWJzZXQpID09PSBzdWJzZXQ7XG59XG5mdW5jdGlvbiBtZXJnZUxhbmVzKGEsIGIpIHtcbiAgcmV0dXJuIGEgfCBiO1xufVxuZnVuY3Rpb24gcmVtb3ZlTGFuZXMoc2V0LCBzdWJzZXQpIHtcbiAgcmV0dXJuIHNldCAmIH5zdWJzZXQ7XG59XG5mdW5jdGlvbiBpbnRlcnNlY3RMYW5lcyhhLCBiKSB7XG4gIHJldHVybiBhICYgYjtcbn0gLy8gU2VlbXMgcmVkdW5kYW50LCBidXQgaXQgY2hhbmdlcyB0aGUgdHlwZSBmcm9tIGEgc2luZ2xlIGxhbmUgKHVzZWQgZm9yXG4vLyB1cGRhdGVzKSB0byBhIGdyb3VwIG9mIGxhbmVzICh1c2VkIGZvciBmbHVzaGluZyB3b3JrKS5cblxuZnVuY3Rpb24gbGFuZVRvTGFuZXMobGFuZSkge1xuICByZXR1cm4gbGFuZTtcbn1cbmZ1bmN0aW9uIGhpZ2hlclByaW9yaXR5TGFuZShhLCBiKSB7XG4gIC8vIFRoaXMgd29ya3MgYmVjYXVzZSB0aGUgYml0IHJhbmdlcyBkZWNyZWFzZSBpbiBwcmlvcml0eSBhcyB5b3UgZ28gbGVmdC5cbiAgcmV0dXJuIGEgIT09IE5vTGFuZSAmJiBhIDwgYiA/IGEgOiBiO1xufVxuZnVuY3Rpb24gY3JlYXRlTGFuZU1hcChpbml0aWFsKSB7XG4gIC8vIEludGVudGlvbmFsbHkgcHVzaGluZyBvbmUgYnkgb25lLlxuICAvLyBodHRwczovL3Y4LmRldi9ibG9nL2VsZW1lbnRzLWtpbmRzI2F2b2lkLWNyZWF0aW5nLWhvbGVzXG4gIHZhciBsYW5lTWFwID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBUb3RhbExhbmVzOyBpKyspIHtcbiAgICBsYW5lTWFwLnB1c2goaW5pdGlhbCk7XG4gIH1cblxuICByZXR1cm4gbGFuZU1hcDtcbn1cbmZ1bmN0aW9uIG1hcmtSb290VXBkYXRlZChyb290LCB1cGRhdGVMYW5lLCBldmVudFRpbWUpIHtcbiAgcm9vdC5wZW5kaW5nTGFuZXMgfD0gdXBkYXRlTGFuZTsgLy8gSWYgdGhlcmUgYXJlIGFueSBzdXNwZW5kZWQgdHJhbnNpdGlvbnMsIGl0J3MgcG9zc2libGUgdGhpcyBuZXcgdXBkYXRlXG4gIC8vIGNvdWxkIHVuYmxvY2sgdGhlbS4gQ2xlYXIgdGhlIHN1c3BlbmRlZCBsYW5lcyBzbyB0aGF0IHdlIGNhbiB0cnkgcmVuZGVyaW5nXG4gIC8vIHRoZW0gYWdhaW4uXG4gIC8vXG4gIC8vIFRPRE86IFdlIHJlYWxseSBvbmx5IG5lZWQgdG8gdW5zdXNwZW5kIG9ubHkgbGFuZXMgdGhhdCBhcmUgaW4gdGhlXG4gIC8vIGBzdWJ0cmVlTGFuZXNgIG9mIHRoZSB1cGRhdGVkIGZpYmVyLCBvciB0aGUgdXBkYXRlIGxhbmVzIG9mIHRoZSByZXR1cm5cbiAgLy8gcGF0aC4gVGhpcyB3b3VsZCBleGNsdWRlIHN1c3BlbmRlZCB1cGRhdGVzIGluIGFuIHVucmVsYXRlZCBzaWJsaW5nIHRyZWUsXG4gIC8vIHNpbmNlIHRoZXJlJ3Mgbm8gd2F5IGZvciB0aGlzIHVwZGF0ZSB0byB1bmJsb2NrIGl0LlxuICAvL1xuICAvLyBXZSBkb24ndCBkbyB0aGlzIGlmIHRoZSBpbmNvbWluZyB1cGRhdGUgaXMgaWRsZSwgYmVjYXVzZSB3ZSBuZXZlciBwcm9jZXNzXG4gIC8vIGlkbGUgdXBkYXRlcyB1bnRpbCBhZnRlciBhbGwgdGhlIHJlZ3VsYXIgdXBkYXRlcyBoYXZlIGZpbmlzaGVkOyB0aGVyZSdzIG5vXG4gIC8vIHdheSBpdCBjb3VsZCB1bmJsb2NrIGEgdHJhbnNpdGlvbi5cblxuICBpZiAodXBkYXRlTGFuZSAhPT0gSWRsZUxhbmUpIHtcbiAgICByb290LnN1c3BlbmRlZExhbmVzID0gTm9MYW5lcztcbiAgICByb290LnBpbmdlZExhbmVzID0gTm9MYW5lcztcbiAgfVxuXG4gIHZhciBldmVudFRpbWVzID0gcm9vdC5ldmVudFRpbWVzO1xuICB2YXIgaW5kZXggPSBsYW5lVG9JbmRleCh1cGRhdGVMYW5lKTsgLy8gV2UgY2FuIGFsd2F5cyBvdmVyd3JpdGUgYW4gZXhpc3RpbmcgdGltZXN0YW1wIGJlY2F1c2Ugd2UgcHJlZmVyIHRoZSBtb3N0XG4gIC8vIHJlY2VudCBldmVudCwgYW5kIHdlIGFzc3VtZSB0aW1lIGlzIG1vbm90b25pY2FsbHkgaW5jcmVhc2luZy5cblxuICBldmVudFRpbWVzW2luZGV4XSA9IGV2ZW50VGltZTtcbn1cbmZ1bmN0aW9uIG1hcmtSb290U3VzcGVuZGVkKHJvb3QsIHN1c3BlbmRlZExhbmVzKSB7XG4gIHJvb3Quc3VzcGVuZGVkTGFuZXMgfD0gc3VzcGVuZGVkTGFuZXM7XG4gIHJvb3QucGluZ2VkTGFuZXMgJj0gfnN1c3BlbmRlZExhbmVzOyAvLyBUaGUgc3VzcGVuZGVkIGxhbmVzIGFyZSBubyBsb25nZXIgQ1BVLWJvdW5kLiBDbGVhciB0aGVpciBleHBpcmF0aW9uIHRpbWVzLlxuXG4gIHZhciBleHBpcmF0aW9uVGltZXMgPSByb290LmV4cGlyYXRpb25UaW1lcztcbiAgdmFyIGxhbmVzID0gc3VzcGVuZGVkTGFuZXM7XG5cbiAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgIHZhciBpbmRleCA9IHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZXMpO1xuICAgIHZhciBsYW5lID0gMSA8PCBpbmRleDtcbiAgICBleHBpcmF0aW9uVGltZXNbaW5kZXhdID0gTm9UaW1lc3RhbXA7XG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtSb290UGluZ2VkKHJvb3QsIHBpbmdlZExhbmVzLCBldmVudFRpbWUpIHtcbiAgcm9vdC5waW5nZWRMYW5lcyB8PSByb290LnN1c3BlbmRlZExhbmVzICYgcGluZ2VkTGFuZXM7XG59XG5mdW5jdGlvbiBtYXJrUm9vdEZpbmlzaGVkKHJvb3QsIHJlbWFpbmluZ0xhbmVzKSB7XG4gIHZhciBub0xvbmdlclBlbmRpbmdMYW5lcyA9IHJvb3QucGVuZGluZ0xhbmVzICYgfnJlbWFpbmluZ0xhbmVzO1xuICByb290LnBlbmRpbmdMYW5lcyA9IHJlbWFpbmluZ0xhbmVzOyAvLyBMZXQncyB0cnkgZXZlcnl0aGluZyBhZ2FpblxuXG4gIHJvb3Quc3VzcGVuZGVkTGFuZXMgPSBOb0xhbmVzO1xuICByb290LnBpbmdlZExhbmVzID0gTm9MYW5lcztcbiAgcm9vdC5leHBpcmVkTGFuZXMgJj0gcmVtYWluaW5nTGFuZXM7XG4gIHJvb3QubXV0YWJsZVJlYWRMYW5lcyAmPSByZW1haW5pbmdMYW5lcztcbiAgcm9vdC5lbnRhbmdsZWRMYW5lcyAmPSByZW1haW5pbmdMYW5lcztcbiAgdmFyIGVudGFuZ2xlbWVudHMgPSByb290LmVudGFuZ2xlbWVudHM7XG4gIHZhciBldmVudFRpbWVzID0gcm9vdC5ldmVudFRpbWVzO1xuICB2YXIgZXhwaXJhdGlvblRpbWVzID0gcm9vdC5leHBpcmF0aW9uVGltZXM7IC8vIENsZWFyIHRoZSBsYW5lcyB0aGF0IG5vIGxvbmdlciBoYXZlIHBlbmRpbmcgd29ya1xuXG4gIHZhciBsYW5lcyA9IG5vTG9uZ2VyUGVuZGluZ0xhbmVzO1xuXG4gIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICB2YXIgaW5kZXggPSBwaWNrQXJiaXRyYXJ5TGFuZUluZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgZW50YW5nbGVtZW50c1tpbmRleF0gPSBOb0xhbmVzO1xuICAgIGV2ZW50VGltZXNbaW5kZXhdID0gTm9UaW1lc3RhbXA7XG4gICAgZXhwaXJhdGlvblRpbWVzW2luZGV4XSA9IE5vVGltZXN0YW1wO1xuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59XG5mdW5jdGlvbiBtYXJrUm9vdEVudGFuZ2xlZChyb290LCBlbnRhbmdsZWRMYW5lcykge1xuICAvLyBJbiBhZGRpdGlvbiB0byBlbnRhbmdsaW5nIGVhY2ggb2YgdGhlIGdpdmVuIGxhbmVzIHdpdGggZWFjaCBvdGhlciwgd2UgYWxzb1xuICAvLyBoYXZlIHRvIGNvbnNpZGVyIF90cmFuc2l0aXZlXyBlbnRhbmdsZW1lbnRzLiBGb3IgZWFjaCBsYW5lIHRoYXQgaXMgYWxyZWFkeVxuICAvLyBlbnRhbmdsZWQgd2l0aCAqYW55KiBvZiB0aGUgZ2l2ZW4gbGFuZXMsIHRoYXQgbGFuZSBpcyBub3cgdHJhbnNpdGl2ZWx5XG4gIC8vIGVudGFuZ2xlZCB3aXRoICphbGwqIHRoZSBnaXZlbiBsYW5lcy5cbiAgLy9cbiAgLy8gVHJhbnNsYXRlZDogSWYgQyBpcyBlbnRhbmdsZWQgd2l0aCBBLCB0aGVuIGVudGFuZ2xpbmcgQSB3aXRoIEIgYWxzb1xuICAvLyBlbnRhbmdsZXMgQyB3aXRoIEIuXG4gIC8vXG4gIC8vIElmIHRoaXMgaXMgaGFyZCB0byBncmFzcCwgaXQgbWlnaHQgaGVscCB0byBpbnRlbnRpb25hbGx5IGJyZWFrIHRoaXNcbiAgLy8gZnVuY3Rpb24gYW5kIGxvb2sgYXQgdGhlIHRlc3RzIHRoYXQgZmFpbCBpbiBSZWFjdFRyYW5zaXRpb24tdGVzdC5qcy4gVHJ5XG4gIC8vIGNvbW1lbnRpbmcgb3V0IG9uZSBvZiB0aGUgY29uZGl0aW9ucyBiZWxvdy5cbiAgdmFyIHJvb3RFbnRhbmdsZWRMYW5lcyA9IHJvb3QuZW50YW5nbGVkTGFuZXMgfD0gZW50YW5nbGVkTGFuZXM7XG4gIHZhciBlbnRhbmdsZW1lbnRzID0gcm9vdC5lbnRhbmdsZW1lbnRzO1xuICB2YXIgbGFuZXMgPSByb290RW50YW5nbGVkTGFuZXM7XG5cbiAgd2hpbGUgKGxhbmVzKSB7XG4gICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuXG4gICAgaWYgKCAvLyBJcyB0aGlzIG9uZSBvZiB0aGUgbmV3bHkgZW50YW5nbGVkIGxhbmVzP1xuICAgIGxhbmUgJiBlbnRhbmdsZWRMYW5lcyB8IC8vIElzIHRoaXMgbGFuZSB0cmFuc2l0aXZlbHkgZW50YW5nbGVkIHdpdGggdGhlIG5ld2x5IGVudGFuZ2xlZCBsYW5lcz9cbiAgICBlbnRhbmdsZW1lbnRzW2luZGV4XSAmIGVudGFuZ2xlZExhbmVzKSB7XG4gICAgICBlbnRhbmdsZW1lbnRzW2luZGV4XSB8PSBlbnRhbmdsZWRMYW5lcztcbiAgICB9XG5cbiAgICBsYW5lcyAmPSB+bGFuZTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0QnVtcGVkTGFuZUZvckh5ZHJhdGlvbihyb290LCByZW5kZXJMYW5lcykge1xuICB2YXIgcmVuZGVyTGFuZSA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmUocmVuZGVyTGFuZXMpO1xuICB2YXIgbGFuZTtcblxuICBzd2l0Y2ggKHJlbmRlckxhbmUpIHtcbiAgICBjYXNlIElucHV0Q29udGludW91c0xhbmU6XG4gICAgICBsYW5lID0gSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBEZWZhdWx0TGFuZTpcbiAgICAgIGxhbmUgPSBEZWZhdWx0SHlkcmF0aW9uTGFuZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTQ6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTY6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTc6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTg6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTk6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEwOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEzOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE2OlxuICAgIGNhc2UgUmV0cnlMYW5lMTpcbiAgICBjYXNlIFJldHJ5TGFuZTI6XG4gICAgY2FzZSBSZXRyeUxhbmUzOlxuICAgIGNhc2UgUmV0cnlMYW5lNDpcbiAgICBjYXNlIFJldHJ5TGFuZTU6XG4gICAgICBsYW5lID0gVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgSWRsZUxhbmU6XG4gICAgICBsYW5lID0gSWRsZUh5ZHJhdGlvbkxhbmU7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBFdmVyeXRoaW5nIGVsc2UgaXMgYWxyZWFkeSBlaXRoZXIgYSBoeWRyYXRpb24gbGFuZSwgb3Igc2hvdWxkbid0XG4gICAgICAvLyBiZSByZXRyaWVkIGF0IGEgaHlkcmF0aW9uIGxhbmUuXG4gICAgICBsYW5lID0gTm9MYW5lO1xuICAgICAgYnJlYWs7XG4gIH0gLy8gQ2hlY2sgaWYgdGhlIGxhbmUgd2UgY2hvc2UgaXMgc3VzcGVuZGVkLiBJZiBzbywgdGhhdCBpbmRpY2F0ZXMgdGhhdCB3ZVxuICAvLyBhbHJlYWR5IGF0dGVtcHRlZCBhbmQgZmFpbGVkIHRvIGh5ZHJhdGUgYXQgdGhhdCBsZXZlbC4gQWxzbyBjaGVjayBpZiB3ZSdyZVxuICAvLyBhbHJlYWR5IHJlbmRlcmluZyB0aGF0IGxhbmUsIHdoaWNoIGlzIHJhcmUgYnV0IGNvdWxkIGhhcHBlbi5cblxuXG4gIGlmICgobGFuZSAmIChyb290LnN1c3BlbmRlZExhbmVzIHwgcmVuZGVyTGFuZXMpKSAhPT0gTm9MYW5lKSB7XG4gICAgLy8gR2l2ZSB1cCB0cnlpbmcgdG8gaHlkcmF0ZSBhbmQgZmFsbCBiYWNrIHRvIGNsaWVudCByZW5kZXIuXG4gICAgcmV0dXJuIE5vTGFuZTtcbiAgfVxuXG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gYWRkRmliZXJUb0xhbmVzTWFwKHJvb3QsIGZpYmVyLCBsYW5lcykge1xuXG4gIGlmICghaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGVuZGluZ1VwZGF0ZXJzTGFuZU1hcCA9IHJvb3QucGVuZGluZ1VwZGF0ZXJzTGFuZU1hcDtcblxuICB3aGlsZSAobGFuZXMgPiAwKSB7XG4gICAgdmFyIGluZGV4ID0gbGFuZVRvSW5kZXgobGFuZXMpO1xuICAgIHZhciBsYW5lID0gMSA8PCBpbmRleDtcbiAgICB2YXIgdXBkYXRlcnMgPSBwZW5kaW5nVXBkYXRlcnNMYW5lTWFwW2luZGV4XTtcbiAgICB1cGRhdGVycy5hZGQoZmliZXIpO1xuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59XG5mdW5jdGlvbiBtb3ZlUGVuZGluZ0ZpYmVyc1RvTWVtb2l6ZWQocm9vdCwgbGFuZXMpIHtcblxuICBpZiAoIWlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBlbmRpbmdVcGRhdGVyc0xhbmVNYXAgPSByb290LnBlbmRpbmdVcGRhdGVyc0xhbmVNYXA7XG4gIHZhciBtZW1vaXplZFVwZGF0ZXJzID0gcm9vdC5tZW1vaXplZFVwZGF0ZXJzO1xuXG4gIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICB2YXIgaW5kZXggPSBsYW5lVG9JbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIHZhciB1cGRhdGVycyA9IHBlbmRpbmdVcGRhdGVyc0xhbmVNYXBbaW5kZXhdO1xuXG4gICAgaWYgKHVwZGF0ZXJzLnNpemUgPiAwKSB7XG4gICAgICB1cGRhdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgICAgIGlmIChhbHRlcm5hdGUgPT09IG51bGwgfHwgIW1lbW9pemVkVXBkYXRlcnMuaGFzKGFsdGVybmF0ZSkpIHtcbiAgICAgICAgICBtZW1vaXplZFVwZGF0ZXJzLmFkZChmaWJlcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdXBkYXRlcnMuY2xlYXIoKTtcbiAgICB9XG5cbiAgICBsYW5lcyAmPSB+bGFuZTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0VHJhbnNpdGlvbnNGb3JMYW5lcyhyb290LCBsYW5lcykge1xuICB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxudmFyIERpc2NyZXRlRXZlbnRQcmlvcml0eSA9IFN5bmNMYW5lO1xudmFyIENvbnRpbnVvdXNFdmVudFByaW9yaXR5ID0gSW5wdXRDb250aW51b3VzTGFuZTtcbnZhciBEZWZhdWx0RXZlbnRQcmlvcml0eSA9IERlZmF1bHRMYW5lO1xudmFyIElkbGVFdmVudFByaW9yaXR5ID0gSWRsZUxhbmU7XG52YXIgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gTm9MYW5lO1xuZnVuY3Rpb24gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCkge1xuICByZXR1cm4gY3VycmVudFVwZGF0ZVByaW9yaXR5O1xufVxuZnVuY3Rpb24gc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KG5ld1ByaW9yaXR5KSB7XG4gIGN1cnJlbnRVcGRhdGVQcmlvcml0eSA9IG5ld1ByaW9yaXR5O1xufVxuZnVuY3Rpb24gcnVuV2l0aFByaW9yaXR5KHByaW9yaXR5LCBmbikge1xuICB2YXIgcHJldmlvdXNQcmlvcml0eSA9IGN1cnJlbnRVcGRhdGVQcmlvcml0eTtcblxuICB0cnkge1xuICAgIGN1cnJlbnRVcGRhdGVQcmlvcml0eSA9IHByaW9yaXR5O1xuICAgIHJldHVybiBmbigpO1xuICB9IGZpbmFsbHkge1xuICAgIGN1cnJlbnRVcGRhdGVQcmlvcml0eSA9IHByZXZpb3VzUHJpb3JpdHk7XG4gIH1cbn1cbmZ1bmN0aW9uIGhpZ2hlckV2ZW50UHJpb3JpdHkoYSwgYikge1xuICByZXR1cm4gYSAhPT0gMCAmJiBhIDwgYiA/IGEgOiBiO1xufVxuZnVuY3Rpb24gbG93ZXJFdmVudFByaW9yaXR5KGEsIGIpIHtcbiAgcmV0dXJuIGEgPT09IDAgfHwgYSA+IGIgPyBhIDogYjtcbn1cbmZ1bmN0aW9uIGlzSGlnaGVyRXZlbnRQcmlvcml0eShhLCBiKSB7XG4gIHJldHVybiBhICE9PSAwICYmIGEgPCBiO1xufVxuZnVuY3Rpb24gbGFuZXNUb0V2ZW50UHJpb3JpdHkobGFuZXMpIHtcbiAgdmFyIGxhbmUgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lKGxhbmVzKTtcblxuICBpZiAoIWlzSGlnaGVyRXZlbnRQcmlvcml0eShEaXNjcmV0ZUV2ZW50UHJpb3JpdHksIGxhbmUpKSB7XG4gICAgcmV0dXJuIERpc2NyZXRlRXZlbnRQcmlvcml0eTtcbiAgfVxuXG4gIGlmICghaXNIaWdoZXJFdmVudFByaW9yaXR5KENvbnRpbnVvdXNFdmVudFByaW9yaXR5LCBsYW5lKSkge1xuICAgIHJldHVybiBDb250aW51b3VzRXZlbnRQcmlvcml0eTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlc05vbklkbGVXb3JrKGxhbmUpKSB7XG4gICAgcmV0dXJuIERlZmF1bHRFdmVudFByaW9yaXR5O1xuICB9XG5cbiAgcmV0dXJuIElkbGVFdmVudFByaW9yaXR5O1xufVxuXG4vLyBUaGlzIGlzIGltcG9ydGVkIGJ5IHRoZSBldmVudCByZXBsYXlpbmcgaW1wbGVtZW50YXRpb24gaW4gUmVhY3QgRE9NLiBJdCdzXG4vLyBpbiBhIHNlcGFyYXRlIGZpbGUgdG8gYnJlYWsgYSBjaXJjdWxhciBkZXBlbmRlbmN5IGJldHdlZW4gdGhlIHJlbmRlcmVyIGFuZFxuLy8gdGhlIHJlY29uY2lsZXIuXG5mdW5jdGlvbiBpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpIHtcbiAgdmFyIGN1cnJlbnRTdGF0ZSA9IHJvb3QuY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICByZXR1cm4gY3VycmVudFN0YXRlLmlzRGVoeWRyYXRlZDtcbn1cblxudmFyIF9hdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb247XG5cbmZ1bmN0aW9uIHNldEF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihmbikge1xuICBfYXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uID0gZm47XG59XG5mdW5jdGlvbiBhdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24oZmliZXIpIHtcbiAgX2F0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihmaWJlcik7XG59XG52YXIgYXR0ZW1wdENvbnRpbnVvdXNIeWRyYXRpb247XG5mdW5jdGlvbiBzZXRBdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbihmbikge1xuICBhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbiA9IGZuO1xufVxudmFyIGF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eTtcbmZ1bmN0aW9uIHNldEF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eShmbikge1xuICBhdHRlbXB0SHlkcmF0aW9uQXRDdXJyZW50UHJpb3JpdHkgPSBmbjtcbn1cbnZhciBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkkMTtcbmZ1bmN0aW9uIHNldEdldEN1cnJlbnRVcGRhdGVQcmlvcml0eShmbikge1xuICBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkkMSA9IGZuO1xufVxudmFyIGF0dGVtcHRIeWRyYXRpb25BdFByaW9yaXR5O1xuZnVuY3Rpb24gc2V0QXR0ZW1wdEh5ZHJhdGlvbkF0UHJpb3JpdHkoZm4pIHtcbiAgYXR0ZW1wdEh5ZHJhdGlvbkF0UHJpb3JpdHkgPSBmbjtcbn0gLy8gVE9ETzogVXBncmFkZSB0aGlzIGRlZmluaXRpb24gb25jZSB3ZSdyZSBvbiBhIG5ld2VyIHZlcnNpb24gb2YgRmxvdyB0aGF0XG4vLyBoYXMgdGhpcyBkZWZpbml0aW9uIGJ1aWx0LWluLlxuXG52YXIgaGFzU2NoZWR1bGVkUmVwbGF5QXR0ZW1wdCA9IGZhbHNlOyAvLyBUaGUgcXVldWUgb2YgZGlzY3JldGUgZXZlbnRzIHRvIGJlIHJlcGxheWVkLlxuXG52YXIgcXVldWVkRGlzY3JldGVFdmVudHMgPSBbXTsgLy8gSW5kaWNhdGVzIGlmIGFueSBjb250aW51b3VzIGV2ZW50IHRhcmdldHMgYXJlIG5vbi1udWxsIGZvciBlYXJseSBiYWlsb3V0LlxuLy8gaWYgdGhlIGxhc3QgdGFyZ2V0IHdhcyBkZWh5ZHJhdGVkLlxuXG52YXIgcXVldWVkRm9jdXMgPSBudWxsO1xudmFyIHF1ZXVlZERyYWcgPSBudWxsO1xudmFyIHF1ZXVlZE1vdXNlID0gbnVsbDsgLy8gRm9yIHBvaW50ZXIgZXZlbnRzIHRoZXJlIGNhbiBiZSBvbmUgbGF0ZXN0IGV2ZW50IHBlciBwb2ludGVySWQuXG5cbnZhciBxdWV1ZWRQb2ludGVycyA9IG5ldyBNYXAoKTtcbnZhciBxdWV1ZWRQb2ludGVyQ2FwdHVyZXMgPSBuZXcgTWFwKCk7IC8vIFdlIGNvdWxkIGNvbnNpZGVyIHJlcGxheWluZyBzZWxlY3Rpb25jaGFuZ2UgYW5kIHRvdWNobW92ZXMgdG9vLlxuXG52YXIgcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzID0gW107XG52YXIgZGlzY3JldGVSZXBsYXlhYmxlRXZlbnRzID0gWydtb3VzZWRvd24nLCAnbW91c2V1cCcsICd0b3VjaGNhbmNlbCcsICd0b3VjaGVuZCcsICd0b3VjaHN0YXJ0JywgJ2F1eGNsaWNrJywgJ2RibGNsaWNrJywgJ3BvaW50ZXJjYW5jZWwnLCAncG9pbnRlcmRvd24nLCAncG9pbnRlcnVwJywgJ2RyYWdlbmQnLCAnZHJhZ3N0YXJ0JywgJ2Ryb3AnLCAnY29tcG9zaXRpb25lbmQnLCAnY29tcG9zaXRpb25zdGFydCcsICdrZXlkb3duJywgJ2tleXByZXNzJywgJ2tleXVwJywgJ2lucHV0JywgJ3RleHRJbnB1dCcsIC8vIEludGVudGlvbmFsbHkgY2FtZWxDYXNlXG4nY29weScsICdjdXQnLCAncGFzdGUnLCAnY2xpY2snLCAnY2hhbmdlJywgJ2NvbnRleHRtZW51JywgJ3Jlc2V0JywgJ3N1Ym1pdCddO1xuZnVuY3Rpb24gaXNEaXNjcmV0ZUV2ZW50VGhhdFJlcXVpcmVzSHlkcmF0aW9uKGV2ZW50VHlwZSkge1xuICByZXR1cm4gZGlzY3JldGVSZXBsYXlhYmxlRXZlbnRzLmluZGV4T2YoZXZlbnRUeXBlKSA+IC0xO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVRdWV1ZWRSZXBsYXlhYmxlRXZlbnQoYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpIHtcbiAgcmV0dXJuIHtcbiAgICBibG9ja2VkT246IGJsb2NrZWRPbixcbiAgICBkb21FdmVudE5hbWU6IGRvbUV2ZW50TmFtZSxcbiAgICBldmVudFN5c3RlbUZsYWdzOiBldmVudFN5c3RlbUZsYWdzLFxuICAgIG5hdGl2ZUV2ZW50OiBuYXRpdmVFdmVudCxcbiAgICB0YXJnZXRDb250YWluZXJzOiBbdGFyZ2V0Q29udGFpbmVyXVxuICB9O1xufVxuXG5mdW5jdGlvbiBjbGVhcklmQ29udGludW91c0V2ZW50KGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpIHtcbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICBjYXNlICdmb2N1c2luJzpcbiAgICBjYXNlICdmb2N1c291dCc6XG4gICAgICBxdWV1ZWRGb2N1cyA9IG51bGw7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2RyYWdlbnRlcic6XG4gICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICAgIHF1ZXVlZERyYWcgPSBudWxsO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdtb3VzZW92ZXInOlxuICAgIGNhc2UgJ21vdXNlb3V0JzpcbiAgICAgIHF1ZXVlZE1vdXNlID0gbnVsbDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAncG9pbnRlcm92ZXInOlxuICAgIGNhc2UgJ3BvaW50ZXJvdXQnOlxuICAgICAge1xuICAgICAgICB2YXIgcG9pbnRlcklkID0gbmF0aXZlRXZlbnQucG9pbnRlcklkO1xuICAgICAgICBxdWV1ZWRQb2ludGVycy5kZWxldGUocG9pbnRlcklkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlICdnb3Rwb2ludGVyY2FwdHVyZSc6XG4gICAgY2FzZSAnbG9zdHBvaW50ZXJjYXB0dXJlJzpcbiAgICAgIHtcbiAgICAgICAgdmFyIF9wb2ludGVySWQgPSBuYXRpdmVFdmVudC5wb2ludGVySWQ7XG4gICAgICAgIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcy5kZWxldGUoX3BvaW50ZXJJZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFjY3VtdWxhdGVPckNyZWF0ZUNvbnRpbnVvdXNRdWV1ZWRSZXBsYXlhYmxlRXZlbnQoZXhpc3RpbmdRdWV1ZWRFdmVudCwgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpIHtcbiAgaWYgKGV4aXN0aW5nUXVldWVkRXZlbnQgPT09IG51bGwgfHwgZXhpc3RpbmdRdWV1ZWRFdmVudC5uYXRpdmVFdmVudCAhPT0gbmF0aXZlRXZlbnQpIHtcbiAgICB2YXIgcXVldWVkRXZlbnQgPSBjcmVhdGVRdWV1ZWRSZXBsYXlhYmxlRXZlbnQoYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuXG4gICAgaWYgKGJsb2NrZWRPbiAhPT0gbnVsbCkge1xuICAgICAgdmFyIF9maWJlcjIgPSBnZXRJbnN0YW5jZUZyb21Ob2RlKGJsb2NrZWRPbik7XG5cbiAgICAgIGlmIChfZmliZXIyICE9PSBudWxsKSB7XG4gICAgICAgIC8vIEF0dGVtcHQgdG8gaW5jcmVhc2UgdGhlIHByaW9yaXR5IG9mIHRoaXMgdGFyZ2V0LlxuICAgICAgICBhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbihfZmliZXIyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcXVldWVkRXZlbnQ7XG4gIH0gLy8gSWYgd2UgaGF2ZSBhbHJlYWR5IHF1ZXVlZCB0aGlzIGV4YWN0IGV2ZW50LCB0aGVuIGl0J3MgYmVjYXVzZVxuICAvLyB0aGUgZGlmZmVyZW50IGV2ZW50IHN5c3RlbXMgaGF2ZSBkaWZmZXJlbnQgRE9NIGV2ZW50IGxpc3RlbmVycy5cbiAgLy8gV2UgY2FuIGFjY3VtdWxhdGUgdGhlIGZsYWdzLCBhbmQgdGhlIHRhcmdldENvbnRhaW5lcnMsIGFuZFxuICAvLyBzdG9yZSBhIHNpbmdsZSBldmVudCB0byBiZSByZXBsYXllZC5cblxuXG4gIGV4aXN0aW5nUXVldWVkRXZlbnQuZXZlbnRTeXN0ZW1GbGFncyB8PSBldmVudFN5c3RlbUZsYWdzO1xuICB2YXIgdGFyZ2V0Q29udGFpbmVycyA9IGV4aXN0aW5nUXVldWVkRXZlbnQudGFyZ2V0Q29udGFpbmVycztcblxuICBpZiAodGFyZ2V0Q29udGFpbmVyICE9PSBudWxsICYmIHRhcmdldENvbnRhaW5lcnMuaW5kZXhPZih0YXJnZXRDb250YWluZXIpID09PSAtMSkge1xuICAgIHRhcmdldENvbnRhaW5lcnMucHVzaCh0YXJnZXRDb250YWluZXIpO1xuICB9XG5cbiAgcmV0dXJuIGV4aXN0aW5nUXVldWVkRXZlbnQ7XG59XG5cbmZ1bmN0aW9uIHF1ZXVlSWZDb250aW51b3VzRXZlbnQoYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpIHtcbiAgLy8gVGhlc2Ugc2V0IHJlbGF0ZWRUYXJnZXQgdG8gbnVsbCBiZWNhdXNlIHRoZSByZXBsYXllZCBldmVudCB3aWxsIGJlIHRyZWF0ZWQgYXMgaWYgd2VcbiAgLy8gbW92ZWQgZnJvbSBvdXRzaWRlIHRoZSB3aW5kb3cgKG5vIHRhcmdldCkgb250byB0aGUgdGFyZ2V0IG9uY2UgaXQgaHlkcmF0ZXMuXG4gIC8vIEluc3RlYWQgb2YgbXV0YXRpbmcgd2UgY291bGQgY2xvbmUgdGhlIGV2ZW50LlxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgICAge1xuICAgICAgICB2YXIgZm9jdXNFdmVudCA9IG5hdGl2ZUV2ZW50O1xuICAgICAgICBxdWV1ZWRGb2N1cyA9IGFjY3VtdWxhdGVPckNyZWF0ZUNvbnRpbnVvdXNRdWV1ZWRSZXBsYXlhYmxlRXZlbnQocXVldWVkRm9jdXMsIGJsb2NrZWRPbiwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIGZvY3VzRXZlbnQpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ2RyYWdlbnRlcic6XG4gICAgICB7XG4gICAgICAgIHZhciBkcmFnRXZlbnQgPSBuYXRpdmVFdmVudDtcbiAgICAgICAgcXVldWVkRHJhZyA9IGFjY3VtdWxhdGVPckNyZWF0ZUNvbnRpbnVvdXNRdWV1ZWRSZXBsYXlhYmxlRXZlbnQocXVldWVkRHJhZywgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgZHJhZ0V2ZW50KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICBjYXNlICdtb3VzZW92ZXInOlxuICAgICAge1xuICAgICAgICB2YXIgbW91c2VFdmVudCA9IG5hdGl2ZUV2ZW50O1xuICAgICAgICBxdWV1ZWRNb3VzZSA9IGFjY3VtdWxhdGVPckNyZWF0ZUNvbnRpbnVvdXNRdWV1ZWRSZXBsYXlhYmxlRXZlbnQocXVldWVkTW91c2UsIGJsb2NrZWRPbiwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIG1vdXNlRXZlbnQpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ3BvaW50ZXJvdmVyJzpcbiAgICAgIHtcbiAgICAgICAgdmFyIHBvaW50ZXJFdmVudCA9IG5hdGl2ZUV2ZW50O1xuICAgICAgICB2YXIgcG9pbnRlcklkID0gcG9pbnRlckV2ZW50LnBvaW50ZXJJZDtcbiAgICAgICAgcXVldWVkUG9pbnRlcnMuc2V0KHBvaW50ZXJJZCwgYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWRQb2ludGVycy5nZXQocG9pbnRlcklkKSB8fCBudWxsLCBibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBwb2ludGVyRXZlbnQpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICBjYXNlICdnb3Rwb2ludGVyY2FwdHVyZSc6XG4gICAgICB7XG4gICAgICAgIHZhciBfcG9pbnRlckV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHZhciBfcG9pbnRlcklkMiA9IF9wb2ludGVyRXZlbnQucG9pbnRlcklkO1xuICAgICAgICBxdWV1ZWRQb2ludGVyQ2FwdHVyZXMuc2V0KF9wb2ludGVySWQyLCBhY2N1bXVsYXRlT3JDcmVhdGVDb250aW51b3VzUXVldWVkUmVwbGF5YWJsZUV2ZW50KHF1ZXVlZFBvaW50ZXJDYXB0dXJlcy5nZXQoX3BvaW50ZXJJZDIpIHx8IG51bGwsIGJsb2NrZWRPbiwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIF9wb2ludGVyRXZlbnQpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59IC8vIENoZWNrIGlmIHRoaXMgdGFyZ2V0IGlzIHVuYmxvY2tlZC4gUmV0dXJucyB0cnVlIGlmIGl0J3MgdW5ibG9ja2VkLlxuXG5mdW5jdGlvbiBhdHRlbXB0RXhwbGljaXRIeWRyYXRpb25UYXJnZXQocXVldWVkVGFyZ2V0KSB7XG4gIC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gc2hhcmVzIGEgbG90IG9mIGxvZ2ljIHdpdGggZmluZEluc3RhbmNlQmxvY2tpbmdFdmVudC5cbiAgLy8gVHJ5IHRvIHVuaWZ5IHRoZW0uIEl0J3MgYSBiaXQgdHJpY2t5IHNpbmNlIGl0IHdvdWxkIHJlcXVpcmUgdHdvIHJldHVyblxuICAvLyB2YWx1ZXMuXG4gIHZhciB0YXJnZXRJbnN0ID0gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUocXVldWVkVGFyZ2V0LnRhcmdldCk7XG5cbiAgaWYgKHRhcmdldEluc3QgIT09IG51bGwpIHtcbiAgICB2YXIgbmVhcmVzdE1vdW50ZWQgPSBnZXROZWFyZXN0TW91bnRlZEZpYmVyKHRhcmdldEluc3QpO1xuXG4gICAgaWYgKG5lYXJlc3RNb3VudGVkICE9PSBudWxsKSB7XG4gICAgICB2YXIgdGFnID0gbmVhcmVzdE1vdW50ZWQudGFnO1xuXG4gICAgICBpZiAodGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBnZXRTdXNwZW5zZUluc3RhbmNlRnJvbUZpYmVyKG5lYXJlc3RNb3VudGVkKTtcblxuICAgICAgICBpZiAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBXZSdyZSBibG9ja2VkIG9uIGh5ZHJhdGluZyB0aGlzIGJvdW5kYXJ5LlxuICAgICAgICAgIC8vIEluY3JlYXNlIGl0cyBwcmlvcml0eS5cbiAgICAgICAgICBxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID0gaW5zdGFuY2U7XG4gICAgICAgICAgYXR0ZW1wdEh5ZHJhdGlvbkF0UHJpb3JpdHkocXVldWVkVGFyZ2V0LnByaW9yaXR5LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhdHRlbXB0SHlkcmF0aW9uQXRDdXJyZW50UHJpb3JpdHkobmVhcmVzdE1vdW50ZWQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0YWcgPT09IEhvc3RSb290KSB7XG4gICAgICAgIHZhciByb290ID0gbmVhcmVzdE1vdW50ZWQuc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmIChpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpKSB7XG4gICAgICAgICAgcXVldWVkVGFyZ2V0LmJsb2NrZWRPbiA9IGdldENvbnRhaW5lckZyb21GaWJlcihuZWFyZXN0TW91bnRlZCk7IC8vIFdlIGRvbid0IGN1cnJlbnRseSBoYXZlIGEgd2F5IHRvIGluY3JlYXNlIHRoZSBwcmlvcml0eSBvZlxuICAgICAgICAgIC8vIGEgcm9vdCBvdGhlciB0aGFuIHN5bmMuXG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gcXVldWVFeHBsaWNpdEh5ZHJhdGlvblRhcmdldCh0YXJnZXQpIHtcbiAgLy8gVE9ETzogVGhpcyB3aWxsIHJlYWQgdGhlIHByaW9yaXR5IGlmIGl0J3MgZGlzcGF0Y2hlZCBieSB0aGUgUmVhY3RcbiAgLy8gZXZlbnQgc3lzdGVtIGJ1dCBub3QgbmF0aXZlIGV2ZW50cy4gU2hvdWxkIHJlYWQgd2luZG93LmV2ZW50LnR5cGUsIGxpa2VcbiAgLy8gd2UgZG8gZm9yIHVwZGF0ZXMgKGdldEN1cnJlbnRFdmVudFByaW9yaXR5KS5cbiAgdmFyIHVwZGF0ZVByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5JDEoKTtcbiAgdmFyIHF1ZXVlZFRhcmdldCA9IHtcbiAgICBibG9ja2VkT246IG51bGwsXG4gICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgcHJpb3JpdHk6IHVwZGF0ZVByaW9yaXR5XG4gIH07XG4gIHZhciBpID0gMDtcblxuICBmb3IgKDsgaSA8IHF1ZXVlZEV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgIC8vIFN0b3Agb25jZSB3ZSBoaXQgdGhlIGZpcnN0IHRhcmdldCB3aXRoIGxvd2VyIHByaW9yaXR5IHRoYW5cbiAgICBpZiAoIWlzSGlnaGVyRXZlbnRQcmlvcml0eSh1cGRhdGVQcmlvcml0eSwgcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzW2ldLnByaW9yaXR5KSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzLnNwbGljZShpLCAwLCBxdWV1ZWRUYXJnZXQpO1xuXG4gIGlmIChpID09PSAwKSB7XG4gICAgYXR0ZW1wdEV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0KHF1ZXVlZFRhcmdldCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudChxdWV1ZWRFdmVudCkge1xuICBpZiAocXVldWVkRXZlbnQuYmxvY2tlZE9uICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHRhcmdldENvbnRhaW5lcnMgPSBxdWV1ZWRFdmVudC50YXJnZXRDb250YWluZXJzO1xuXG4gIHdoaWxlICh0YXJnZXRDb250YWluZXJzLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgdGFyZ2V0Q29udGFpbmVyID0gdGFyZ2V0Q29udGFpbmVyc1swXTtcbiAgICB2YXIgbmV4dEJsb2NrZWRPbiA9IGZpbmRJbnN0YW5jZUJsb2NraW5nRXZlbnQocXVldWVkRXZlbnQuZG9tRXZlbnROYW1lLCBxdWV1ZWRFdmVudC5ldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIHF1ZXVlZEV2ZW50Lm5hdGl2ZUV2ZW50KTtcblxuICAgIGlmIChuZXh0QmxvY2tlZE9uID09PSBudWxsKSB7XG4gICAgICB7XG4gICAgICAgIHZhciBuYXRpdmVFdmVudCA9IHF1ZXVlZEV2ZW50Lm5hdGl2ZUV2ZW50O1xuICAgICAgICB2YXIgbmF0aXZlRXZlbnRDbG9uZSA9IG5ldyBuYXRpdmVFdmVudC5jb25zdHJ1Y3RvcihuYXRpdmVFdmVudC50eXBlLCBuYXRpdmVFdmVudCk7XG4gICAgICAgIHNldFJlcGxheWluZ0V2ZW50KG5hdGl2ZUV2ZW50Q2xvbmUpO1xuICAgICAgICBuYXRpdmVFdmVudC50YXJnZXQuZGlzcGF0Y2hFdmVudChuYXRpdmVFdmVudENsb25lKTtcbiAgICAgICAgcmVzZXRSZXBsYXlpbmdFdmVudCgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSdyZSBzdGlsbCBibG9ja2VkLiBUcnkgYWdhaW4gbGF0ZXIuXG4gICAgICB2YXIgX2ZpYmVyMyA9IGdldEluc3RhbmNlRnJvbU5vZGUobmV4dEJsb2NrZWRPbik7XG5cbiAgICAgIGlmIChfZmliZXIzICE9PSBudWxsKSB7XG4gICAgICAgIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uKF9maWJlcjMpO1xuICAgICAgfVxuXG4gICAgICBxdWV1ZWRFdmVudC5ibG9ja2VkT24gPSBuZXh0QmxvY2tlZE9uO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gLy8gVGhpcyB0YXJnZXQgY29udGFpbmVyIHdhcyBzdWNjZXNzZnVsbHkgZGlzcGF0Y2hlZC4gVHJ5IHRoZSBuZXh0LlxuXG5cbiAgICB0YXJnZXRDb250YWluZXJzLnNoaWZ0KCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudEluTWFwKHF1ZXVlZEV2ZW50LCBrZXksIG1hcCkge1xuICBpZiAoYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudChxdWV1ZWRFdmVudCkpIHtcbiAgICBtYXAuZGVsZXRlKGtleSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVwbGF5VW5ibG9ja2VkRXZlbnRzKCkge1xuICBoYXNTY2hlZHVsZWRSZXBsYXlBdHRlbXB0ID0gZmFsc2U7XG5cblxuICBpZiAocXVldWVkRm9jdXMgIT09IG51bGwgJiYgYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudChxdWV1ZWRGb2N1cykpIHtcbiAgICBxdWV1ZWRGb2N1cyA9IG51bGw7XG4gIH1cblxuICBpZiAocXVldWVkRHJhZyAhPT0gbnVsbCAmJiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZERyYWcpKSB7XG4gICAgcXVldWVkRHJhZyA9IG51bGw7XG4gIH1cblxuICBpZiAocXVldWVkTW91c2UgIT09IG51bGwgJiYgYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudChxdWV1ZWRNb3VzZSkpIHtcbiAgICBxdWV1ZWRNb3VzZSA9IG51bGw7XG4gIH1cblxuICBxdWV1ZWRQb2ludGVycy5mb3JFYWNoKGF0dGVtcHRSZXBsYXlDb250aW51b3VzUXVldWVkRXZlbnRJbk1hcCk7XG4gIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcy5mb3JFYWNoKGF0dGVtcHRSZXBsYXlDb250aW51b3VzUXVldWVkRXZlbnRJbk1hcCk7XG59XG5cbmZ1bmN0aW9uIHNjaGVkdWxlQ2FsbGJhY2tJZlVuYmxvY2tlZChxdWV1ZWRFdmVudCwgdW5ibG9ja2VkKSB7XG4gIGlmIChxdWV1ZWRFdmVudC5ibG9ja2VkT24gPT09IHVuYmxvY2tlZCkge1xuICAgIHF1ZXVlZEV2ZW50LmJsb2NrZWRPbiA9IG51bGw7XG5cbiAgICBpZiAoIWhhc1NjaGVkdWxlZFJlcGxheUF0dGVtcHQpIHtcbiAgICAgIGhhc1NjaGVkdWxlZFJlcGxheUF0dGVtcHQgPSB0cnVlOyAvLyBTY2hlZHVsZSBhIGNhbGxiYWNrIHRvIGF0dGVtcHQgcmVwbGF5aW5nIGFzIG1hbnkgZXZlbnRzIGFzIGFyZVxuICAgICAgLy8gbm93IHVuYmxvY2tlZC4gVGhpcyBmaXJzdCBtaWdodCBub3QgYWN0dWFsbHkgYmUgdW5ibG9ja2VkIHlldC5cbiAgICAgIC8vIFdlIGNvdWxkIGNoZWNrIGl0IGVhcmx5IHRvIGF2b2lkIHNjaGVkdWxpbmcgYW4gdW5uZWNlc3NhcnkgY2FsbGJhY2suXG5cbiAgICAgIFNjaGVkdWxlci51bnN0YWJsZV9zY2hlZHVsZUNhbGxiYWNrKFNjaGVkdWxlci51bnN0YWJsZV9Ob3JtYWxQcmlvcml0eSwgcmVwbGF5VW5ibG9ja2VkRXZlbnRzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV0cnlJZkJsb2NrZWRPbih1bmJsb2NrZWQpIHtcbiAgLy8gTWFyayBhbnl0aGluZyB0aGF0IHdhcyBibG9ja2VkIG9uIHRoaXMgYXMgbm8gbG9uZ2VyIGJsb2NrZWRcbiAgLy8gYW5kIGVsaWdpYmxlIGZvciBhIHJlcGxheS5cbiAgaWYgKHF1ZXVlZERpc2NyZXRlRXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICBzY2hlZHVsZUNhbGxiYWNrSWZVbmJsb2NrZWQocXVldWVkRGlzY3JldGVFdmVudHNbMF0sIHVuYmxvY2tlZCk7IC8vIFRoaXMgaXMgYSBleHBvbmVudGlhbCBzZWFyY2ggZm9yIGVhY2ggYm91bmRhcnkgdGhhdCBjb21taXRzLiBJIHRoaW5rIGl0J3NcbiAgICAvLyB3b3J0aCBpdCBiZWNhdXNlIHdlIGV4cGVjdCB2ZXJ5IGZldyBkaXNjcmV0ZSBldmVudHMgdG8gcXVldWUgdXAgYW5kIG9uY2VcbiAgICAvLyB3ZSBhcmUgYWN0dWFsbHkgZnVsbHkgdW5ibG9ja2VkIGl0IHdpbGwgYmUgZmFzdCB0byByZXBsYXkgdGhlbS5cblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcXVldWVkRGlzY3JldGVFdmVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBxdWV1ZWRFdmVudCA9IHF1ZXVlZERpc2NyZXRlRXZlbnRzW2ldO1xuXG4gICAgICBpZiAocXVldWVkRXZlbnQuYmxvY2tlZE9uID09PSB1bmJsb2NrZWQpIHtcbiAgICAgICAgcXVldWVkRXZlbnQuYmxvY2tlZE9uID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAocXVldWVkRm9jdXMgIT09IG51bGwpIHtcbiAgICBzY2hlZHVsZUNhbGxiYWNrSWZVbmJsb2NrZWQocXVldWVkRm9jdXMsIHVuYmxvY2tlZCk7XG4gIH1cblxuICBpZiAocXVldWVkRHJhZyAhPT0gbnVsbCkge1xuICAgIHNjaGVkdWxlQ2FsbGJhY2tJZlVuYmxvY2tlZChxdWV1ZWREcmFnLCB1bmJsb2NrZWQpO1xuICB9XG5cbiAgaWYgKHF1ZXVlZE1vdXNlICE9PSBudWxsKSB7XG4gICAgc2NoZWR1bGVDYWxsYmFja0lmVW5ibG9ja2VkKHF1ZXVlZE1vdXNlLCB1bmJsb2NrZWQpO1xuICB9XG5cbiAgdmFyIHVuYmxvY2sgPSBmdW5jdGlvbiAocXVldWVkRXZlbnQpIHtcbiAgICByZXR1cm4gc2NoZWR1bGVDYWxsYmFja0lmVW5ibG9ja2VkKHF1ZXVlZEV2ZW50LCB1bmJsb2NrZWQpO1xuICB9O1xuXG4gIHF1ZXVlZFBvaW50ZXJzLmZvckVhY2godW5ibG9jayk7XG4gIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcy5mb3JFYWNoKHVuYmxvY2spO1xuXG4gIGZvciAodmFyIF9pID0gMDsgX2kgPCBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgdmFyIHF1ZXVlZFRhcmdldCA9IHF1ZXVlZEV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0c1tfaV07XG5cbiAgICBpZiAocXVldWVkVGFyZ2V0LmJsb2NrZWRPbiA9PT0gdW5ibG9ja2VkKSB7XG4gICAgICBxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAocXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgbmV4dEV4cGxpY2l0VGFyZ2V0ID0gcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzWzBdO1xuXG4gICAgaWYgKG5leHRFeHBsaWNpdFRhcmdldC5ibG9ja2VkT24gIT09IG51bGwpIHtcbiAgICAgIC8vIFdlJ3JlIHN0aWxsIGJsb2NrZWQuXG4gICAgICBicmVhaztcbiAgICB9IGVsc2Uge1xuICAgICAgYXR0ZW1wdEV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0KG5leHRFeHBsaWNpdFRhcmdldCk7XG5cbiAgICAgIGlmIChuZXh0RXhwbGljaXRUYXJnZXQuYmxvY2tlZE9uID09PSBudWxsKSB7XG4gICAgICAgIC8vIFdlJ3JlIHVuYmxvY2tlZC5cbiAgICAgICAgcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzLnNoaWZ0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnOyAvLyBUT0RPOiBjYW4gd2Ugc3RvcCBleHBvcnRpbmcgdGhlc2U/XG5cbnZhciBfZW5hYmxlZCA9IHRydWU7IC8vIFRoaXMgaXMgZXhwb3J0ZWQgaW4gRkIgYnVpbGRzIGZvciB1c2UgYnkgbGVnYWN5IEZCIGxheWVyIGluZnJhLlxuLy8gV2UnZCBsaWtlIHRvIHJlbW92ZSB0aGlzIGJ1dCBpdCdzIG5vdCBjbGVhciBpZiB0aGlzIGlzIHNhZmUuXG5cbmZ1bmN0aW9uIHNldEVuYWJsZWQoZW5hYmxlZCkge1xuICBfZW5hYmxlZCA9ICEhZW5hYmxlZDtcbn1cbmZ1bmN0aW9uIGlzRW5hYmxlZCgpIHtcbiAgcmV0dXJuIF9lbmFibGVkO1xufVxuZnVuY3Rpb24gY3JlYXRlRXZlbnRMaXN0ZW5lcldyYXBwZXJXaXRoUHJpb3JpdHkodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MpIHtcbiAgdmFyIGV2ZW50UHJpb3JpdHkgPSBnZXRFdmVudFByaW9yaXR5KGRvbUV2ZW50TmFtZSk7XG4gIHZhciBsaXN0ZW5lcldyYXBwZXI7XG5cbiAgc3dpdGNoIChldmVudFByaW9yaXR5KSB7XG4gICAgY2FzZSBEaXNjcmV0ZUV2ZW50UHJpb3JpdHk6XG4gICAgICBsaXN0ZW5lcldyYXBwZXIgPSBkaXNwYXRjaERpc2NyZXRlRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgQ29udGludW91c0V2ZW50UHJpb3JpdHk6XG4gICAgICBsaXN0ZW5lcldyYXBwZXIgPSBkaXNwYXRjaENvbnRpbnVvdXNFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBEZWZhdWx0RXZlbnRQcmlvcml0eTpcbiAgICBkZWZhdWx0OlxuICAgICAgbGlzdGVuZXJXcmFwcGVyID0gZGlzcGF0Y2hFdmVudDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIGxpc3RlbmVyV3JhcHBlci5iaW5kKG51bGwsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hEaXNjcmV0ZUV2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgY29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICB2YXIgcHJldmlvdXNQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uO1xuICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uID0gbnVsbDtcblxuICB0cnkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShEaXNjcmV0ZUV2ZW50UHJpb3JpdHkpO1xuICAgIGRpc3BhdGNoRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBjb250YWluZXIsIG5hdGl2ZUV2ZW50KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSk7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbiA9IHByZXZUcmFuc2l0aW9uO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoQ29udGludW91c0V2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgY29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICB2YXIgcHJldmlvdXNQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uO1xuICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uID0gbnVsbDtcblxuICB0cnkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShDb250aW51b3VzRXZlbnRQcmlvcml0eSk7XG4gICAgZGlzcGF0Y2hFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIGNvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpIHtcbiAgaWYgKCFfZW5hYmxlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHtcbiAgICBkaXNwYXRjaEV2ZW50V2l0aEVuYWJsZUNhcHR1cmVQaGFzZVNlbGVjdGl2ZUh5ZHJhdGlvbldpdGhvdXREaXNjcmV0ZUV2ZW50UmVwbGF5KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudFdpdGhFbmFibGVDYXB0dXJlUGhhc2VTZWxlY3RpdmVIeWRyYXRpb25XaXRob3V0RGlzY3JldGVFdmVudFJlcGxheShkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpIHtcbiAgdmFyIGJsb2NrZWRPbiA9IGZpbmRJbnN0YW5jZUJsb2NraW5nRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIG5hdGl2ZUV2ZW50KTtcblxuICBpZiAoYmxvY2tlZE9uID09PSBudWxsKSB7XG4gICAgZGlzcGF0Y2hFdmVudEZvclBsdWdpbkV2ZW50U3lzdGVtKGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgbmF0aXZlRXZlbnQsIHJldHVybl90YXJnZXRJbnN0LCB0YXJnZXRDb250YWluZXIpO1xuICAgIGNsZWFySWZDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHF1ZXVlSWZDb250aW51b3VzRXZlbnQoYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpKSB7XG4gICAgbmF0aXZlRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgcmV0dXJuO1xuICB9IC8vIFdlIG5lZWQgdG8gY2xlYXIgb25seSBpZiB3ZSBkaWRuJ3QgcXVldWUgYmVjYXVzZVxuICAvLyBxdWV1ZWluZyBpcyBhY2N1bXVsYXRpdmUuXG5cblxuICBjbGVhcklmQ29udGludW91c0V2ZW50KGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpO1xuXG4gIGlmIChldmVudFN5c3RlbUZsYWdzICYgSVNfQ0FQVFVSRV9QSEFTRSAmJiBpc0Rpc2NyZXRlRXZlbnRUaGF0UmVxdWlyZXNIeWRyYXRpb24oZG9tRXZlbnROYW1lKSkge1xuICAgIHdoaWxlIChibG9ja2VkT24gIT09IG51bGwpIHtcbiAgICAgIHZhciBmaWJlciA9IGdldEluc3RhbmNlRnJvbU5vZGUoYmxvY2tlZE9uKTtcblxuICAgICAgaWYgKGZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgIGF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihmaWJlcik7XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXh0QmxvY2tlZE9uID0gZmluZEluc3RhbmNlQmxvY2tpbmdFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuXG4gICAgICBpZiAobmV4dEJsb2NrZWRPbiA9PT0gbnVsbCkge1xuICAgICAgICBkaXNwYXRjaEV2ZW50Rm9yUGx1Z2luRXZlbnRTeXN0ZW0oZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgcmV0dXJuX3RhcmdldEluc3QsIHRhcmdldENvbnRhaW5lcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChuZXh0QmxvY2tlZE9uID09PSBibG9ja2VkT24pIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGJsb2NrZWRPbiA9IG5leHRCbG9ja2VkT247XG4gICAgfVxuXG4gICAgaWYgKGJsb2NrZWRPbiAhPT0gbnVsbCkge1xuICAgICAgbmF0aXZlRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuO1xuICB9IC8vIFRoaXMgaXMgbm90IHJlcGxheWFibGUgc28gd2UnbGwgaW52b2tlIGl0IGJ1dCB3aXRob3V0IGEgdGFyZ2V0LFxuICAvLyBpbiBjYXNlIHRoZSBldmVudCBzeXN0ZW0gbmVlZHMgdG8gdHJhY2UgaXQuXG5cblxuICBkaXNwYXRjaEV2ZW50Rm9yUGx1Z2luRXZlbnRTeXN0ZW0oZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgbnVsbCwgdGFyZ2V0Q29udGFpbmVyKTtcbn1cblxudmFyIHJldHVybl90YXJnZXRJbnN0ID0gbnVsbDsgLy8gUmV0dXJucyBhIFN1c3BlbnNlSW5zdGFuY2Ugb3IgQ29udGFpbmVyIGlmIGl0J3MgYmxvY2tlZC5cbi8vIFRoZSByZXR1cm5fdGFyZ2V0SW5zdCBmaWVsZCBhYm92ZSBpcyBjb25jZXB0dWFsbHkgcGFydCBvZiB0aGUgcmV0dXJuIHZhbHVlLlxuXG5mdW5jdGlvbiBmaW5kSW5zdGFuY2VCbG9ja2luZ0V2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICAvLyBUT0RPOiBXYXJuIGlmIF9lbmFibGVkIGlzIGZhbHNlLlxuICByZXR1cm5fdGFyZ2V0SW5zdCA9IG51bGw7XG4gIHZhciBuYXRpdmVFdmVudFRhcmdldCA9IGdldEV2ZW50VGFyZ2V0KG5hdGl2ZUV2ZW50KTtcbiAgdmFyIHRhcmdldEluc3QgPSBnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZShuYXRpdmVFdmVudFRhcmdldCk7XG5cbiAgaWYgKHRhcmdldEluc3QgIT09IG51bGwpIHtcbiAgICB2YXIgbmVhcmVzdE1vdW50ZWQgPSBnZXROZWFyZXN0TW91bnRlZEZpYmVyKHRhcmdldEluc3QpO1xuXG4gICAgaWYgKG5lYXJlc3RNb3VudGVkID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIHRyZWUgaGFzIGJlZW4gdW5tb3VudGVkIGFscmVhZHkuIERpc3BhdGNoIHdpdGhvdXQgYSB0YXJnZXQuXG4gICAgICB0YXJnZXRJbnN0ID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHRhZyA9IG5lYXJlc3RNb3VudGVkLnRhZztcblxuICAgICAgaWYgKHRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gZ2V0U3VzcGVuc2VJbnN0YW5jZUZyb21GaWJlcihuZWFyZXN0TW91bnRlZCk7XG5cbiAgICAgICAgaWYgKGluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gUXVldWUgdGhlIGV2ZW50IHRvIGJlIHJlcGxheWVkIGxhdGVyLiBBYm9ydCBkaXNwYXRjaGluZyBzaW5jZSB3ZVxuICAgICAgICAgIC8vIGRvbid0IHdhbnQgdGhpcyBldmVudCBkaXNwYXRjaGVkIHR3aWNlIHRocm91Z2ggdGhlIGV2ZW50IHN5c3RlbS5cbiAgICAgICAgICAvLyBUT0RPOiBJZiB0aGlzIGlzIHRoZSBmaXJzdCBkaXNjcmV0ZSBldmVudCBpbiB0aGUgcXVldWUuIFNjaGVkdWxlIGFuIGluY3JlYXNlZFxuICAgICAgICAgIC8vIHByaW9yaXR5IGZvciB0aGlzIGJvdW5kYXJ5LlxuICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgICAgfSAvLyBUaGlzIHNob3VsZG4ndCBoYXBwZW4sIHNvbWV0aGluZyB3ZW50IHdyb25nIGJ1dCB0byBhdm9pZCBibG9ja2luZ1xuICAgICAgICAvLyB0aGUgd2hvbGUgc3lzdGVtLCBkaXNwYXRjaCB0aGUgZXZlbnQgd2l0aG91dCBhIHRhcmdldC5cbiAgICAgICAgLy8gVE9ETzogV2Fybi5cblxuXG4gICAgICAgIHRhcmdldEluc3QgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmICh0YWcgPT09IEhvc3RSb290KSB7XG4gICAgICAgIHZhciByb290ID0gbmVhcmVzdE1vdW50ZWQuc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmIChpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpKSB7XG4gICAgICAgICAgLy8gSWYgdGhpcyBoYXBwZW5zIGR1cmluZyBhIHJlcGxheSBzb21ldGhpbmcgd2VudCB3cm9uZyBhbmQgaXQgbWlnaHQgYmxvY2tcbiAgICAgICAgICAvLyB0aGUgd2hvbGUgc3lzdGVtLlxuICAgICAgICAgIHJldHVybiBnZXRDb250YWluZXJGcm9tRmliZXIobmVhcmVzdE1vdW50ZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGFyZ2V0SW5zdCA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKG5lYXJlc3RNb3VudGVkICE9PSB0YXJnZXRJbnN0KSB7XG4gICAgICAgIC8vIElmIHdlIGdldCBhbiBldmVudCAoZXg6IGltZyBvbmxvYWQpIGJlZm9yZSBjb21taXR0aW5nIHRoYXRcbiAgICAgICAgLy8gY29tcG9uZW50J3MgbW91bnQsIGlnbm9yZSBpdCBmb3Igbm93ICh0aGF0IGlzLCB0cmVhdCBpdCBhcyBpZiBpdCB3YXMgYW5cbiAgICAgICAgLy8gZXZlbnQgb24gYSBub24tUmVhY3QgdHJlZSkuIFdlIG1pZ2h0IGFsc28gY29uc2lkZXIgcXVldWVpbmcgZXZlbnRzIGFuZFxuICAgICAgICAvLyBkaXNwYXRjaGluZyB0aGVtIGFmdGVyIHRoZSBtb3VudC5cbiAgICAgICAgdGFyZ2V0SW5zdCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuX3RhcmdldEluc3QgPSB0YXJnZXRJbnN0OyAvLyBXZSdyZSBub3QgYmxvY2tlZCBvbiBhbnl0aGluZy5cblxuICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldEV2ZW50UHJpb3JpdHkoZG9tRXZlbnROYW1lKSB7XG4gIHN3aXRjaCAoZG9tRXZlbnROYW1lKSB7XG4gICAgLy8gVXNlZCBieSBTaW1wbGVFdmVudFBsdWdpbjpcbiAgICBjYXNlICdjYW5jZWwnOlxuICAgIGNhc2UgJ2NsaWNrJzpcbiAgICBjYXNlICdjbG9zZSc6XG4gICAgY2FzZSAnY29udGV4dG1lbnUnOlxuICAgIGNhc2UgJ2NvcHknOlxuICAgIGNhc2UgJ2N1dCc6XG4gICAgY2FzZSAnYXV4Y2xpY2snOlxuICAgIGNhc2UgJ2RibGNsaWNrJzpcbiAgICBjYXNlICdkcmFnZW5kJzpcbiAgICBjYXNlICdkcmFnc3RhcnQnOlxuICAgIGNhc2UgJ2Ryb3AnOlxuICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgIGNhc2UgJ2ZvY3Vzb3V0JzpcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgY2FzZSAnaW52YWxpZCc6XG4gICAgY2FzZSAna2V5ZG93bic6XG4gICAgY2FzZSAna2V5cHJlc3MnOlxuICAgIGNhc2UgJ2tleXVwJzpcbiAgICBjYXNlICdtb3VzZWRvd24nOlxuICAgIGNhc2UgJ21vdXNldXAnOlxuICAgIGNhc2UgJ3Bhc3RlJzpcbiAgICBjYXNlICdwYXVzZSc6XG4gICAgY2FzZSAncGxheSc6XG4gICAgY2FzZSAncG9pbnRlcmNhbmNlbCc6XG4gICAgY2FzZSAncG9pbnRlcmRvd24nOlxuICAgIGNhc2UgJ3BvaW50ZXJ1cCc6XG4gICAgY2FzZSAncmF0ZWNoYW5nZSc6XG4gICAgY2FzZSAncmVzZXQnOlxuICAgIGNhc2UgJ3Jlc2l6ZSc6XG4gICAgY2FzZSAnc2Vla2VkJzpcbiAgICBjYXNlICdzdWJtaXQnOlxuICAgIGNhc2UgJ3RvdWNoY2FuY2VsJzpcbiAgICBjYXNlICd0b3VjaGVuZCc6XG4gICAgY2FzZSAndG91Y2hzdGFydCc6XG4gICAgY2FzZSAndm9sdW1lY2hhbmdlJzogLy8gVXNlZCBieSBwb2x5ZmlsbHM6XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICBjYXNlICdjaGFuZ2UnOlxuICAgIGNhc2UgJ3NlbGVjdGlvbmNoYW5nZSc6XG4gICAgY2FzZSAndGV4dElucHV0JzpcbiAgICBjYXNlICdjb21wb3NpdGlvbnN0YXJ0JzpcbiAgICBjYXNlICdjb21wb3NpdGlvbmVuZCc6XG4gICAgY2FzZSAnY29tcG9zaXRpb251cGRhdGUnOiAvLyBPbmx5IGVuYWJsZUNyZWF0ZUV2ZW50SGFuZGxlQVBJOlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgY2FzZSAnYmVmb3JlYmx1cic6XG4gICAgY2FzZSAnYWZ0ZXJibHVyJzogLy8gTm90IHVzZWQgYnkgUmVhY3QgYnV0IGNvdWxkIGJlIGJ5IHVzZXIgY29kZTpcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgIGNhc2UgJ2JlZm9yZWlucHV0JzpcbiAgICBjYXNlICdibHVyJzpcbiAgICBjYXNlICdmdWxsc2NyZWVuY2hhbmdlJzpcbiAgICBjYXNlICdmb2N1cyc6XG4gICAgY2FzZSAnaGFzaGNoYW5nZSc6XG4gICAgY2FzZSAncG9wc3RhdGUnOlxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgY2FzZSAnc2VsZWN0c3RhcnQnOlxuICAgICAgcmV0dXJuIERpc2NyZXRlRXZlbnRQcmlvcml0eTtcblxuICAgIGNhc2UgJ2RyYWcnOlxuICAgIGNhc2UgJ2RyYWdlbnRlcic6XG4gICAgY2FzZSAnZHJhZ2V4aXQnOlxuICAgIGNhc2UgJ2RyYWdsZWF2ZSc6XG4gICAgY2FzZSAnZHJhZ292ZXInOlxuICAgIGNhc2UgJ21vdXNlbW92ZSc6XG4gICAgY2FzZSAnbW91c2VvdXQnOlxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgY2FzZSAncG9pbnRlcm1vdmUnOlxuICAgIGNhc2UgJ3BvaW50ZXJvdXQnOlxuICAgIGNhc2UgJ3BvaW50ZXJvdmVyJzpcbiAgICBjYXNlICdzY3JvbGwnOlxuICAgIGNhc2UgJ3RvZ2dsZSc6XG4gICAgY2FzZSAndG91Y2htb3ZlJzpcbiAgICBjYXNlICd3aGVlbCc6IC8vIE5vdCB1c2VkIGJ5IFJlYWN0IGJ1dCBjb3VsZCBiZSBieSB1c2VyIGNvZGU6XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICBjYXNlICdtb3VzZWVudGVyJzpcbiAgICBjYXNlICdtb3VzZWxlYXZlJzpcbiAgICBjYXNlICdwb2ludGVyZW50ZXInOlxuICAgIGNhc2UgJ3BvaW50ZXJsZWF2ZSc6XG4gICAgICByZXR1cm4gQ29udGludW91c0V2ZW50UHJpb3JpdHk7XG5cbiAgICBjYXNlICdtZXNzYWdlJzpcbiAgICAgIHtcbiAgICAgICAgLy8gV2UgbWlnaHQgYmUgaW4gdGhlIFNjaGVkdWxlciBjYWxsYmFjay5cbiAgICAgICAgLy8gRXZlbnR1YWxseSB0aGlzIG1lY2hhbmlzbSB3aWxsIGJlIHJlcGxhY2VkIGJ5IGEgY2hlY2tcbiAgICAgICAgLy8gb2YgdGhlIGN1cnJlbnQgcHJpb3JpdHkgb24gdGhlIG5hdGl2ZSBzY2hlZHVsZXIuXG4gICAgICAgIHZhciBzY2hlZHVsZXJQcmlvcml0eSA9IGdldEN1cnJlbnRQcmlvcml0eUxldmVsKCk7XG5cbiAgICAgICAgc3dpdGNoIChzY2hlZHVsZXJQcmlvcml0eSkge1xuICAgICAgICAgIGNhc2UgSW1tZWRpYXRlUHJpb3JpdHk6XG4gICAgICAgICAgICByZXR1cm4gRGlzY3JldGVFdmVudFByaW9yaXR5O1xuXG4gICAgICAgICAgY2FzZSBVc2VyQmxvY2tpbmdQcmlvcml0eTpcbiAgICAgICAgICAgIHJldHVybiBDb250aW51b3VzRXZlbnRQcmlvcml0eTtcblxuICAgICAgICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgICAgICAgY2FzZSBMb3dQcmlvcml0eTpcbiAgICAgICAgICAgIC8vIFRPRE86IEhhbmRsZSBMb3dTY2hlZHVsZXJQcmlvcml0eSwgc29tZWhvdy4gTWF5YmUgdGhlIHNhbWUgbGFuZSBhcyBoeWRyYXRpb24uXG4gICAgICAgICAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG5cbiAgICAgICAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgICAgICAgIHJldHVybiBJZGxlRXZlbnRQcmlvcml0eTtcblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkRXZlbnRCdWJibGVMaXN0ZW5lcih0YXJnZXQsIGV2ZW50VHlwZSwgbGlzdGVuZXIpIHtcbiAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xuICByZXR1cm4gbGlzdGVuZXI7XG59XG5mdW5jdGlvbiBhZGRFdmVudENhcHR1cmVMaXN0ZW5lcih0YXJnZXQsIGV2ZW50VHlwZSwgbGlzdGVuZXIpIHtcbiAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lciwgdHJ1ZSk7XG4gIHJldHVybiBsaXN0ZW5lcjtcbn1cbmZ1bmN0aW9uIGFkZEV2ZW50Q2FwdHVyZUxpc3RlbmVyV2l0aFBhc3NpdmVGbGFnKHRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lciwgcGFzc2l2ZSkge1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCB7XG4gICAgY2FwdHVyZTogdHJ1ZSxcbiAgICBwYXNzaXZlOiBwYXNzaXZlXG4gIH0pO1xuICByZXR1cm4gbGlzdGVuZXI7XG59XG5mdW5jdGlvbiBhZGRFdmVudEJ1YmJsZUxpc3RlbmVyV2l0aFBhc3NpdmVGbGFnKHRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lciwgcGFzc2l2ZSkge1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCB7XG4gICAgcGFzc2l2ZTogcGFzc2l2ZVxuICB9KTtcbiAgcmV0dXJuIGxpc3RlbmVyO1xufVxuXG4vKipcbiAqIFRoZXNlIHZhcmlhYmxlcyBzdG9yZSBpbmZvcm1hdGlvbiBhYm91dCB0ZXh0IGNvbnRlbnQgb2YgYSB0YXJnZXQgbm9kZSxcbiAqIGFsbG93aW5nIGNvbXBhcmlzb24gb2YgY29udGVudCBiZWZvcmUgYW5kIGFmdGVyIGEgZ2l2ZW4gZXZlbnQuXG4gKlxuICogSWRlbnRpZnkgdGhlIG5vZGUgd2hlcmUgc2VsZWN0aW9uIGN1cnJlbnRseSBiZWdpbnMsIHRoZW4gb2JzZXJ2ZVxuICogYm90aCBpdHMgdGV4dCBjb250ZW50IGFuZCBpdHMgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgRE9NLiBTaW5jZSB0aGVcbiAqIGJyb3dzZXIgbWF5IG5hdGl2ZWx5IHJlcGxhY2UgdGhlIHRhcmdldCBub2RlIGR1cmluZyBjb21wb3NpdGlvbiwgd2UgY2FuXG4gKiB1c2UgaXRzIHBvc2l0aW9uIHRvIGZpbmQgaXRzIHJlcGxhY2VtZW50LlxuICpcbiAqXG4gKi9cbnZhciByb290ID0gbnVsbDtcbnZhciBzdGFydFRleHQgPSBudWxsO1xudmFyIGZhbGxiYWNrVGV4dCA9IG51bGw7XG5mdW5jdGlvbiBpbml0aWFsaXplKG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIHJvb3QgPSBuYXRpdmVFdmVudFRhcmdldDtcbiAgc3RhcnRUZXh0ID0gZ2V0VGV4dCgpO1xuICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIHJlc2V0KCkge1xuICByb290ID0gbnVsbDtcbiAgc3RhcnRUZXh0ID0gbnVsbDtcbiAgZmFsbGJhY2tUZXh0ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldERhdGEoKSB7XG4gIGlmIChmYWxsYmFja1RleHQpIHtcbiAgICByZXR1cm4gZmFsbGJhY2tUZXh0O1xuICB9XG5cbiAgdmFyIHN0YXJ0O1xuICB2YXIgc3RhcnRWYWx1ZSA9IHN0YXJ0VGV4dDtcbiAgdmFyIHN0YXJ0TGVuZ3RoID0gc3RhcnRWYWx1ZS5sZW5ndGg7XG4gIHZhciBlbmQ7XG4gIHZhciBlbmRWYWx1ZSA9IGdldFRleHQoKTtcbiAgdmFyIGVuZExlbmd0aCA9IGVuZFZhbHVlLmxlbmd0aDtcblxuICBmb3IgKHN0YXJ0ID0gMDsgc3RhcnQgPCBzdGFydExlbmd0aDsgc3RhcnQrKykge1xuICAgIGlmIChzdGFydFZhbHVlW3N0YXJ0XSAhPT0gZW5kVmFsdWVbc3RhcnRdKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICB2YXIgbWluRW5kID0gc3RhcnRMZW5ndGggLSBzdGFydDtcblxuICBmb3IgKGVuZCA9IDE7IGVuZCA8PSBtaW5FbmQ7IGVuZCsrKSB7XG4gICAgaWYgKHN0YXJ0VmFsdWVbc3RhcnRMZW5ndGggLSBlbmRdICE9PSBlbmRWYWx1ZVtlbmRMZW5ndGggLSBlbmRdKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICB2YXIgc2xpY2VUYWlsID0gZW5kID4gMSA/IDEgLSBlbmQgOiB1bmRlZmluZWQ7XG4gIGZhbGxiYWNrVGV4dCA9IGVuZFZhbHVlLnNsaWNlKHN0YXJ0LCBzbGljZVRhaWwpO1xuICByZXR1cm4gZmFsbGJhY2tUZXh0O1xufVxuZnVuY3Rpb24gZ2V0VGV4dCgpIHtcbiAgaWYgKCd2YWx1ZScgaW4gcm9vdCkge1xuICAgIHJldHVybiByb290LnZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHJvb3QudGV4dENvbnRlbnQ7XG59XG5cbi8qKlxuICogYGNoYXJDb2RlYCByZXByZXNlbnRzIHRoZSBhY3R1YWwgXCJjaGFyYWN0ZXIgY29kZVwiIGFuZCBpcyBzYWZlIHRvIHVzZSB3aXRoXG4gKiBgU3RyaW5nLmZyb21DaGFyQ29kZWAuIEFzIHN1Y2gsIG9ubHkga2V5cyB0aGF0IGNvcnJlc3BvbmQgdG8gcHJpbnRhYmxlXG4gKiBjaGFyYWN0ZXJzIHByb2R1Y2UgYSB2YWxpZCBgY2hhckNvZGVgLCB0aGUgb25seSBleGNlcHRpb24gdG8gdGhpcyBpcyBFbnRlci5cbiAqIFRoZSBUYWIta2V5IGlzIGNvbnNpZGVyZWQgbm9uLXByaW50YWJsZSBhbmQgZG9lcyBub3QgaGF2ZSBhIGBjaGFyQ29kZWAsXG4gKiBwcmVzdW1hYmx5IGJlY2F1c2UgaXQgZG9lcyBub3QgcHJvZHVjZSBhIHRhYi1jaGFyYWN0ZXIgaW4gYnJvd3NlcnMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7bnVtYmVyfSBOb3JtYWxpemVkIGBjaGFyQ29kZWAgcHJvcGVydHkuXG4gKi9cbmZ1bmN0aW9uIGdldEV2ZW50Q2hhckNvZGUobmF0aXZlRXZlbnQpIHtcbiAgdmFyIGNoYXJDb2RlO1xuICB2YXIga2V5Q29kZSA9IG5hdGl2ZUV2ZW50LmtleUNvZGU7XG5cbiAgaWYgKCdjaGFyQ29kZScgaW4gbmF0aXZlRXZlbnQpIHtcbiAgICBjaGFyQ29kZSA9IG5hdGl2ZUV2ZW50LmNoYXJDb2RlOyAvLyBGRiBkb2VzIG5vdCBzZXQgYGNoYXJDb2RlYCBmb3IgdGhlIEVudGVyLWtleSwgY2hlY2sgYWdhaW5zdCBga2V5Q29kZWAuXG5cbiAgICBpZiAoY2hhckNvZGUgPT09IDAgJiYga2V5Q29kZSA9PT0gMTMpIHtcbiAgICAgIGNoYXJDb2RlID0gMTM7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElFOCBkb2VzIG5vdCBpbXBsZW1lbnQgYGNoYXJDb2RlYCwgYnV0IGBrZXlDb2RlYCBoYXMgdGhlIGNvcnJlY3QgdmFsdWUuXG4gICAgY2hhckNvZGUgPSBrZXlDb2RlO1xuICB9IC8vIElFIGFuZCBFZGdlIChvbiBXaW5kb3dzKSBhbmQgQ2hyb21lIC8gU2FmYXJpIChvbiBXaW5kb3dzIGFuZCBMaW51eClcbiAgLy8gcmVwb3J0IEVudGVyIGFzIGNoYXJDb2RlIDEwIHdoZW4gY3RybCBpcyBwcmVzc2VkLlxuXG5cbiAgaWYgKGNoYXJDb2RlID09PSAxMCkge1xuICAgIGNoYXJDb2RlID0gMTM7XG4gIH0gLy8gU29tZSBub24tcHJpbnRhYmxlIGtleXMgYXJlIHJlcG9ydGVkIGluIGBjaGFyQ29kZWAvYGtleUNvZGVgLCBkaXNjYXJkIHRoZW0uXG4gIC8vIE11c3Qgbm90IGRpc2NhcmQgdGhlIChub24tKXByaW50YWJsZSBFbnRlci1rZXkuXG5cblxuICBpZiAoY2hhckNvZGUgPj0gMzIgfHwgY2hhckNvZGUgPT09IDEzKSB7XG4gICAgcmV0dXJuIGNoYXJDb2RlO1xuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGZ1bmN0aW9uVGhhdFJldHVybnNUcnVlKCkge1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gZnVuY3Rpb25UaGF0UmV0dXJuc0ZhbHNlKCkge1xuICByZXR1cm4gZmFsc2U7XG59IC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBhIGZhY3Rvcnkgc28gdGhhdCB3ZSBoYXZlIGRpZmZlcmVudCByZXR1cm5lZCBjb25zdHJ1Y3RvcnMuXG4vLyBJZiB3ZSBoYWQgYSBzaW5nbGUgY29uc3RydWN0b3IsIGl0IHdvdWxkIGJlIG1lZ2Ftb3JwaGljIGFuZCBlbmdpbmVzIHdvdWxkIGRlb3B0LlxuXG5cbmZ1bmN0aW9uIGNyZWF0ZVN5bnRoZXRpY0V2ZW50KEludGVyZmFjZSkge1xuICAvKipcbiAgICogU3ludGhldGljIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBldmVudCBwbHVnaW5zLCB0eXBpY2FsbHkgaW4gcmVzcG9uc2UgdG8gYVxuICAgKiB0b3AtbGV2ZWwgZXZlbnQgZGVsZWdhdGlvbiBoYW5kbGVyLlxuICAgKlxuICAgKiBUaGVzZSBzeXN0ZW1zIHNob3VsZCBnZW5lcmFsbHkgdXNlIHBvb2xpbmcgdG8gcmVkdWNlIHRoZSBmcmVxdWVuY3kgb2YgZ2FyYmFnZVxuICAgKiBjb2xsZWN0aW9uLiBUaGUgc3lzdGVtIHNob3VsZCBjaGVjayBgaXNQZXJzaXN0ZW50YCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGVcbiAgICogZXZlbnQgc2hvdWxkIGJlIHJlbGVhc2VkIGludG8gdGhlIHBvb2wgYWZ0ZXIgYmVpbmcgZGlzcGF0Y2hlZC4gVXNlcnMgdGhhdFxuICAgKiBuZWVkIGEgcGVyc2lzdGVkIGV2ZW50IHNob3VsZCBpbnZva2UgYHBlcnNpc3RgLlxuICAgKlxuICAgKiBTeW50aGV0aWMgZXZlbnRzIChhbmQgc3ViY2xhc3NlcykgaW1wbGVtZW50IHRoZSBET00gTGV2ZWwgMyBFdmVudHMgQVBJIGJ5XG4gICAqIG5vcm1hbGl6aW5nIGJyb3dzZXIgcXVpcmtzLiBTdWJjbGFzc2VzIGRvIG5vdCBuZWNlc3NhcmlseSBoYXZlIHRvIGltcGxlbWVudCBhXG4gICAqIERPTSBpbnRlcmZhY2U7IGN1c3RvbSBhcHBsaWNhdGlvbi1zcGVjaWZpYyBldmVudHMgY2FuIGFsc28gc3ViY2xhc3MgdGhpcy5cbiAgICovXG4gIGZ1bmN0aW9uIFN5bnRoZXRpY0Jhc2VFdmVudChyZWFjdE5hbWUsIHJlYWN0RXZlbnRUeXBlLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgICB0aGlzLl9yZWFjdE5hbWUgPSByZWFjdE5hbWU7XG4gICAgdGhpcy5fdGFyZ2V0SW5zdCA9IHRhcmdldEluc3Q7XG4gICAgdGhpcy50eXBlID0gcmVhY3RFdmVudFR5cGU7XG4gICAgdGhpcy5uYXRpdmVFdmVudCA9IG5hdGl2ZUV2ZW50O1xuICAgIHRoaXMudGFyZ2V0ID0gbmF0aXZlRXZlbnRUYXJnZXQ7XG4gICAgdGhpcy5jdXJyZW50VGFyZ2V0ID0gbnVsbDtcblxuICAgIGZvciAodmFyIF9wcm9wTmFtZSBpbiBJbnRlcmZhY2UpIHtcbiAgICAgIGlmICghSW50ZXJmYWNlLmhhc093blByb3BlcnR5KF9wcm9wTmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBub3JtYWxpemUgPSBJbnRlcmZhY2VbX3Byb3BOYW1lXTtcblxuICAgICAgaWYgKG5vcm1hbGl6ZSkge1xuICAgICAgICB0aGlzW19wcm9wTmFtZV0gPSBub3JtYWxpemUobmF0aXZlRXZlbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpc1tfcHJvcE5hbWVdID0gbmF0aXZlRXZlbnRbX3Byb3BOYW1lXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdFByZXZlbnRlZCA9IG5hdGl2ZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgIT0gbnVsbCA/IG5hdGl2ZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgOiBuYXRpdmVFdmVudC5yZXR1cm5WYWx1ZSA9PT0gZmFsc2U7XG5cbiAgICBpZiAoZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgdGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBmdW5jdGlvblRoYXRSZXR1cm5zVHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBmdW5jdGlvblRoYXRSZXR1cm5zRmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNGYWxzZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFzc2lnbihTeW50aGV0aWNCYXNlRXZlbnQucHJvdG90eXBlLCB7XG4gICAgcHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7XG4gICAgICB2YXIgZXZlbnQgPSB0aGlzLm5hdGl2ZUV2ZW50O1xuXG4gICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vICRGbG93Rml4TWUgLSBmbG93IGlzIG5vdCBhd2FyZSBvZiBgdW5rbm93bmAgaW4gSUVcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGV2ZW50LnJldHVyblZhbHVlICE9PSAndW5rbm93bicpIHtcbiAgICAgICAgZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBmdW5jdGlvblRoYXRSZXR1cm5zVHJ1ZTtcbiAgICB9LFxuICAgIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGV2ZW50ID0gdGhpcy5uYXRpdmVFdmVudDtcblxuICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5zdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IC8vICRGbG93Rml4TWUgLSBmbG93IGlzIG5vdCBhd2FyZSBvZiBgdW5rbm93bmAgaW4gSUVcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGV2ZW50LmNhbmNlbEJ1YmJsZSAhPT0gJ3Vua25vd24nKSB7XG4gICAgICAgIC8vIFRoZSBDaGFuZ2VFdmVudFBsdWdpbiByZWdpc3RlcnMgYSBcInByb3BlcnR5Y2hhbmdlXCIgZXZlbnQgZm9yXG4gICAgICAgIC8vIElFLiBUaGlzIGV2ZW50IGRvZXMgbm90IHN1cHBvcnQgYnViYmxpbmcgb3IgY2FuY2VsbGluZywgYW5kXG4gICAgICAgIC8vIGFueSByZWZlcmVuY2VzIHRvIGNhbmNlbEJ1YmJsZSB0aHJvdyBcIk1lbWJlciBub3QgZm91bmRcIi4gIEFcbiAgICAgICAgLy8gdHlwZW9mIGNoZWNrIG9mIFwidW5rbm93blwiIGNpcmN1bXZlbnRzIHRoaXMgaXNzdWUgKGFuZCBpcyBhbHNvXG4gICAgICAgIC8vIElFIHNwZWNpZmljKS5cbiAgICAgICAgZXZlbnQuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNUcnVlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBXZSByZWxlYXNlIGFsbCBkaXNwYXRjaGVkIGBTeW50aGV0aWNFdmVudGBzIGFmdGVyIGVhY2ggZXZlbnQgbG9vcCwgYWRkaW5nXG4gICAgICogdGhlbSBiYWNrIGludG8gdGhlIHBvb2wuIFRoaXMgYWxsb3dzIGEgd2F5IHRvIGhvbGQgb250byBhIHJlZmVyZW5jZSB0aGF0XG4gICAgICogd29uJ3QgYmUgYWRkZWQgYmFjayBpbnRvIHRoZSBwb29sLlxuICAgICAqL1xuICAgIHBlcnNpc3Q6IGZ1bmN0aW9uICgpIHsvLyBNb2Rlcm4gZXZlbnQgc3lzdGVtIGRvZXNuJ3QgdXNlIHBvb2xpbmcuXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGlzIGV2ZW50IHNob3VsZCBiZSByZWxlYXNlZCBiYWNrIGludG8gdGhlIHBvb2wuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoaXMgc2hvdWxkIG5vdCBiZSByZWxlYXNlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGlzUGVyc2lzdGVudDogZnVuY3Rpb25UaGF0UmV0dXJuc1RydWVcbiAgfSk7XG4gIHJldHVybiBTeW50aGV0aWNCYXNlRXZlbnQ7XG59XG4vKipcbiAqIEBpbnRlcmZhY2UgRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzL1xuICovXG5cblxudmFyIEV2ZW50SW50ZXJmYWNlID0ge1xuICBldmVudFBoYXNlOiAwLFxuICBidWJibGVzOiAwLFxuICBjYW5jZWxhYmxlOiAwLFxuICB0aW1lU3RhbXA6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiBldmVudC50aW1lU3RhbXAgfHwgRGF0ZS5ub3coKTtcbiAgfSxcbiAgZGVmYXVsdFByZXZlbnRlZDogMCxcbiAgaXNUcnVzdGVkOiAwXG59O1xudmFyIFN5bnRoZXRpY0V2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoRXZlbnRJbnRlcmZhY2UpO1xuXG52YXIgVUlFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgRXZlbnRJbnRlcmZhY2UsIHtcbiAgdmlldzogMCxcbiAgZGV0YWlsOiAwXG59KTtcblxudmFyIFN5bnRoZXRpY1VJRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChVSUV2ZW50SW50ZXJmYWNlKTtcbnZhciBsYXN0TW92ZW1lbnRYO1xudmFyIGxhc3RNb3ZlbWVudFk7XG52YXIgbGFzdE1vdXNlRXZlbnQ7XG5cbmZ1bmN0aW9uIHVwZGF0ZU1vdXNlTW92ZW1lbnRQb2x5ZmlsbFN0YXRlKGV2ZW50KSB7XG4gIGlmIChldmVudCAhPT0gbGFzdE1vdXNlRXZlbnQpIHtcbiAgICBpZiAobGFzdE1vdXNlRXZlbnQgJiYgZXZlbnQudHlwZSA9PT0gJ21vdXNlbW92ZScpIHtcbiAgICAgIGxhc3RNb3ZlbWVudFggPSBldmVudC5zY3JlZW5YIC0gbGFzdE1vdXNlRXZlbnQuc2NyZWVuWDtcbiAgICAgIGxhc3RNb3ZlbWVudFkgPSBldmVudC5zY3JlZW5ZIC0gbGFzdE1vdXNlRXZlbnQuc2NyZWVuWTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGFzdE1vdmVtZW50WCA9IDA7XG4gICAgICBsYXN0TW92ZW1lbnRZID0gMDtcbiAgICB9XG5cbiAgICBsYXN0TW91c2VFdmVudCA9IGV2ZW50O1xuICB9XG59XG4vKipcbiAqIEBpbnRlcmZhY2UgTW91c2VFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cblxuXG52YXIgTW91c2VFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgVUlFdmVudEludGVyZmFjZSwge1xuICBzY3JlZW5YOiAwLFxuICBzY3JlZW5ZOiAwLFxuICBjbGllbnRYOiAwLFxuICBjbGllbnRZOiAwLFxuICBwYWdlWDogMCxcbiAgcGFnZVk6IDAsXG4gIGN0cmxLZXk6IDAsXG4gIHNoaWZ0S2V5OiAwLFxuICBhbHRLZXk6IDAsXG4gIG1ldGFLZXk6IDAsXG4gIGdldE1vZGlmaWVyU3RhdGU6IGdldEV2ZW50TW9kaWZpZXJTdGF0ZSxcbiAgYnV0dG9uOiAwLFxuICBidXR0b25zOiAwLFxuICByZWxhdGVkVGFyZ2V0OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQucmVsYXRlZFRhcmdldCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZXZlbnQuZnJvbUVsZW1lbnQgPT09IGV2ZW50LnNyY0VsZW1lbnQgPyBldmVudC50b0VsZW1lbnQgOiBldmVudC5mcm9tRWxlbWVudDtcbiAgICByZXR1cm4gZXZlbnQucmVsYXRlZFRhcmdldDtcbiAgfSxcbiAgbW92ZW1lbnRYOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoJ21vdmVtZW50WCcgaW4gZXZlbnQpIHtcbiAgICAgIHJldHVybiBldmVudC5tb3ZlbWVudFg7XG4gICAgfVxuXG4gICAgdXBkYXRlTW91c2VNb3ZlbWVudFBvbHlmaWxsU3RhdGUoZXZlbnQpO1xuICAgIHJldHVybiBsYXN0TW92ZW1lbnRYO1xuICB9LFxuICBtb3ZlbWVudFk6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmICgnbW92ZW1lbnRZJyBpbiBldmVudCkge1xuICAgICAgcmV0dXJuIGV2ZW50Lm1vdmVtZW50WTtcbiAgICB9IC8vIERvbid0IG5lZWQgdG8gY2FsbCB1cGRhdGVNb3VzZU1vdmVtZW50UG9seWZpbGxTdGF0ZSgpIGhlcmVcbiAgICAvLyBiZWNhdXNlIGl0J3MgZ3VhcmFudGVlZCB0byBoYXZlIGFscmVhZHkgcnVuIHdoZW4gbW92ZW1lbnRYXG4gICAgLy8gd2FzIGNvcGllZC5cblxuXG4gICAgcmV0dXJuIGxhc3RNb3ZlbWVudFk7XG4gIH1cbn0pO1xuXG52YXIgU3ludGhldGljTW91c2VFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KE1vdXNlRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIERyYWdFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cblxudmFyIERyYWdFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgTW91c2VFdmVudEludGVyZmFjZSwge1xuICBkYXRhVHJhbnNmZXI6IDBcbn0pO1xuXG52YXIgU3ludGhldGljRHJhZ0V2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoRHJhZ0V2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBGb2N1c0V2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG52YXIgRm9jdXNFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgVUlFdmVudEludGVyZmFjZSwge1xuICByZWxhdGVkVGFyZ2V0OiAwXG59KTtcblxudmFyIFN5bnRoZXRpY0ZvY3VzRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChGb2N1c0V2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLWFuaW1hdGlvbnMvI0FuaW1hdGlvbkV2ZW50LWludGVyZmFjZVxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQW5pbWF0aW9uRXZlbnRcbiAqL1xuXG52YXIgQW5pbWF0aW9uRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIEV2ZW50SW50ZXJmYWNlLCB7XG4gIGFuaW1hdGlvbk5hbWU6IDAsXG4gIGVsYXBzZWRUaW1lOiAwLFxuICBwc2V1ZG9FbGVtZW50OiAwXG59KTtcblxudmFyIFN5bnRoZXRpY0FuaW1hdGlvbkV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoQW5pbWF0aW9uRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL2NsaXBib2FyZC1hcGlzL1xuICovXG5cbnZhciBDbGlwYm9hcmRFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgRXZlbnRJbnRlcmZhY2UsIHtcbiAgY2xpcGJvYXJkRGF0YTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuICdjbGlwYm9hcmREYXRhJyBpbiBldmVudCA/IGV2ZW50LmNsaXBib2FyZERhdGEgOiB3aW5kb3cuY2xpcGJvYXJkRGF0YTtcbiAgfVxufSk7XG5cbnZhciBTeW50aGV0aWNDbGlwYm9hcmRFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KENsaXBib2FyZEV2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1jb21wb3NpdGlvbmV2ZW50c1xuICovXG5cbnZhciBDb21wb3NpdGlvbkV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBFdmVudEludGVyZmFjZSwge1xuICBkYXRhOiAwXG59KTtcblxudmFyIFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChDb21wb3NpdGlvbkV2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDEzL1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDEzMTEwNVxuICogICAgICAvI2V2ZW50cy1pbnB1dGV2ZW50c1xuICovXG4vLyBIYXBwZW5zIHRvIHNoYXJlIHRoZSBzYW1lIGxpc3QgZm9yIG5vdy5cblxudmFyIFN5bnRoZXRpY0lucHV0RXZlbnQgPSBTeW50aGV0aWNDb21wb3NpdGlvbkV2ZW50O1xuLyoqXG4gKiBOb3JtYWxpemF0aW9uIG9mIGRlcHJlY2F0ZWQgSFRNTDUgYGtleWAgdmFsdWVzXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9LZXlib2FyZEV2ZW50I0tleV9uYW1lc1xuICovXG5cbnZhciBub3JtYWxpemVLZXkgPSB7XG4gIEVzYzogJ0VzY2FwZScsXG4gIFNwYWNlYmFyOiAnICcsXG4gIExlZnQ6ICdBcnJvd0xlZnQnLFxuICBVcDogJ0Fycm93VXAnLFxuICBSaWdodDogJ0Fycm93UmlnaHQnLFxuICBEb3duOiAnQXJyb3dEb3duJyxcbiAgRGVsOiAnRGVsZXRlJyxcbiAgV2luOiAnT1MnLFxuICBNZW51OiAnQ29udGV4dE1lbnUnLFxuICBBcHBzOiAnQ29udGV4dE1lbnUnLFxuICBTY3JvbGw6ICdTY3JvbGxMb2NrJyxcbiAgTW96UHJpbnRhYmxlS2V5OiAnVW5pZGVudGlmaWVkJ1xufTtcbi8qKlxuICogVHJhbnNsYXRpb24gZnJvbSBsZWdhY3kgYGtleUNvZGVgIHRvIEhUTUw1IGBrZXlgXG4gKiBPbmx5IHNwZWNpYWwga2V5cyBzdXBwb3J0ZWQsIGFsbCBvdGhlcnMgZGVwZW5kIG9uIGtleWJvYXJkIGxheW91dCBvciBicm93c2VyXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9LZXlib2FyZEV2ZW50I0tleV9uYW1lc1xuICovXG5cbnZhciB0cmFuc2xhdGVUb0tleSA9IHtcbiAgJzgnOiAnQmFja3NwYWNlJyxcbiAgJzknOiAnVGFiJyxcbiAgJzEyJzogJ0NsZWFyJyxcbiAgJzEzJzogJ0VudGVyJyxcbiAgJzE2JzogJ1NoaWZ0JyxcbiAgJzE3JzogJ0NvbnRyb2wnLFxuICAnMTgnOiAnQWx0JyxcbiAgJzE5JzogJ1BhdXNlJyxcbiAgJzIwJzogJ0NhcHNMb2NrJyxcbiAgJzI3JzogJ0VzY2FwZScsXG4gICczMic6ICcgJyxcbiAgJzMzJzogJ1BhZ2VVcCcsXG4gICczNCc6ICdQYWdlRG93bicsXG4gICczNSc6ICdFbmQnLFxuICAnMzYnOiAnSG9tZScsXG4gICczNyc6ICdBcnJvd0xlZnQnLFxuICAnMzgnOiAnQXJyb3dVcCcsXG4gICczOSc6ICdBcnJvd1JpZ2h0JyxcbiAgJzQwJzogJ0Fycm93RG93bicsXG4gICc0NSc6ICdJbnNlcnQnLFxuICAnNDYnOiAnRGVsZXRlJyxcbiAgJzExMic6ICdGMScsXG4gICcxMTMnOiAnRjInLFxuICAnMTE0JzogJ0YzJyxcbiAgJzExNSc6ICdGNCcsXG4gICcxMTYnOiAnRjUnLFxuICAnMTE3JzogJ0Y2JyxcbiAgJzExOCc6ICdGNycsXG4gICcxMTknOiAnRjgnLFxuICAnMTIwJzogJ0Y5JyxcbiAgJzEyMSc6ICdGMTAnLFxuICAnMTIyJzogJ0YxMScsXG4gICcxMjMnOiAnRjEyJyxcbiAgJzE0NCc6ICdOdW1Mb2NrJyxcbiAgJzE0NSc6ICdTY3JvbGxMb2NrJyxcbiAgJzIyNCc6ICdNZXRhJ1xufTtcbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7c3RyaW5nfSBOb3JtYWxpemVkIGBrZXlgIHByb3BlcnR5LlxuICovXG5cbmZ1bmN0aW9uIGdldEV2ZW50S2V5KG5hdGl2ZUV2ZW50KSB7XG4gIGlmIChuYXRpdmVFdmVudC5rZXkpIHtcbiAgICAvLyBOb3JtYWxpemUgaW5jb25zaXN0ZW50IHZhbHVlcyByZXBvcnRlZCBieSBicm93c2VycyBkdWUgdG9cbiAgICAvLyBpbXBsZW1lbnRhdGlvbnMgb2YgYSB3b3JraW5nIGRyYWZ0IHNwZWNpZmljYXRpb24uXG4gICAgLy8gRmlyZUZveCBpbXBsZW1lbnRzIGBrZXlgIGJ1dCByZXR1cm5zIGBNb3pQcmludGFibGVLZXlgIGZvciBhbGxcbiAgICAvLyBwcmludGFibGUgY2hhcmFjdGVycyAobm9ybWFsaXplZCB0byBgVW5pZGVudGlmaWVkYCksIGlnbm9yZSBpdC5cbiAgICB2YXIga2V5ID0gbm9ybWFsaXplS2V5W25hdGl2ZUV2ZW50LmtleV0gfHwgbmF0aXZlRXZlbnQua2V5O1xuXG4gICAgaWYgKGtleSAhPT0gJ1VuaWRlbnRpZmllZCcpIHtcbiAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICB9IC8vIEJyb3dzZXIgZG9lcyBub3QgaW1wbGVtZW50IGBrZXlgLCBwb2x5ZmlsbCBhcyBtdWNoIG9mIGl0IGFzIHdlIGNhbi5cblxuXG4gIGlmIChuYXRpdmVFdmVudC50eXBlID09PSAna2V5cHJlc3MnKSB7XG4gICAgdmFyIGNoYXJDb2RlID0gZ2V0RXZlbnRDaGFyQ29kZShuYXRpdmVFdmVudCk7IC8vIFRoZSBlbnRlci1rZXkgaXMgdGVjaG5pY2FsbHkgYm90aCBwcmludGFibGUgYW5kIG5vbi1wcmludGFibGUgYW5kIGNhblxuICAgIC8vIHRodXMgYmUgY2FwdHVyZWQgYnkgYGtleXByZXNzYCwgbm8gb3RoZXIgbm9uLXByaW50YWJsZSBrZXkgc2hvdWxkLlxuXG4gICAgcmV0dXJuIGNoYXJDb2RlID09PSAxMyA/ICdFbnRlcicgOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoYXJDb2RlKTtcbiAgfVxuXG4gIGlmIChuYXRpdmVFdmVudC50eXBlID09PSAna2V5ZG93bicgfHwgbmF0aXZlRXZlbnQudHlwZSA9PT0gJ2tleXVwJykge1xuICAgIC8vIFdoaWxlIHVzZXIga2V5Ym9hcmQgbGF5b3V0IGRldGVybWluZXMgdGhlIGFjdHVhbCBtZWFuaW5nIG9mIGVhY2hcbiAgICAvLyBga2V5Q29kZWAgdmFsdWUsIGFsbW9zdCBhbGwgZnVuY3Rpb24ga2V5cyBoYXZlIGEgdW5pdmVyc2FsIHZhbHVlLlxuICAgIHJldHVybiB0cmFuc2xhdGVUb0tleVtuYXRpdmVFdmVudC5rZXlDb2RlXSB8fCAnVW5pZGVudGlmaWVkJztcbiAgfVxuXG4gIHJldHVybiAnJztcbn1cbi8qKlxuICogVHJhbnNsYXRpb24gZnJvbSBtb2RpZmllciBrZXkgdG8gdGhlIGFzc29jaWF0ZWQgcHJvcGVydHkgaW4gdGhlIGV2ZW50LlxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2tleXMtTW9kaWZpZXJzXG4gKi9cblxuXG52YXIgbW9kaWZpZXJLZXlUb1Byb3AgPSB7XG4gIEFsdDogJ2FsdEtleScsXG4gIENvbnRyb2w6ICdjdHJsS2V5JyxcbiAgTWV0YTogJ21ldGFLZXknLFxuICBTaGlmdDogJ3NoaWZ0S2V5J1xufTsgLy8gT2xkZXIgYnJvd3NlcnMgKFNhZmFyaSA8PSAxMCwgaU9TIFNhZmFyaSA8PSAxMC4yKSBkbyBub3Qgc3VwcG9ydFxuLy8gZ2V0TW9kaWZpZXJTdGF0ZS4gSWYgZ2V0TW9kaWZpZXJTdGF0ZSBpcyBub3Qgc3VwcG9ydGVkLCB3ZSBtYXAgaXQgdG8gYSBzZXQgb2Zcbi8vIG1vZGlmaWVyIGtleXMgZXhwb3NlZCBieSB0aGUgZXZlbnQuIEluIHRoaXMgY2FzZSwgTG9jay1rZXlzIGFyZSBub3Qgc3VwcG9ydGVkLlxuXG5mdW5jdGlvbiBtb2RpZmllclN0YXRlR2V0dGVyKGtleUFyZykge1xuICB2YXIgc3ludGhldGljRXZlbnQgPSB0aGlzO1xuICB2YXIgbmF0aXZlRXZlbnQgPSBzeW50aGV0aWNFdmVudC5uYXRpdmVFdmVudDtcblxuICBpZiAobmF0aXZlRXZlbnQuZ2V0TW9kaWZpZXJTdGF0ZSkge1xuICAgIHJldHVybiBuYXRpdmVFdmVudC5nZXRNb2RpZmllclN0YXRlKGtleUFyZyk7XG4gIH1cblxuICB2YXIga2V5UHJvcCA9IG1vZGlmaWVyS2V5VG9Qcm9wW2tleUFyZ107XG4gIHJldHVybiBrZXlQcm9wID8gISFuYXRpdmVFdmVudFtrZXlQcm9wXSA6IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXRFdmVudE1vZGlmaWVyU3RhdGUobmF0aXZlRXZlbnQpIHtcbiAgcmV0dXJuIG1vZGlmaWVyU3RhdGVHZXR0ZXI7XG59XG4vKipcbiAqIEBpbnRlcmZhY2UgS2V5Ym9hcmRFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cblxuXG52YXIgS2V5Ym9hcmRFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgVUlFdmVudEludGVyZmFjZSwge1xuICBrZXk6IGdldEV2ZW50S2V5LFxuICBjb2RlOiAwLFxuICBsb2NhdGlvbjogMCxcbiAgY3RybEtleTogMCxcbiAgc2hpZnRLZXk6IDAsXG4gIGFsdEtleTogMCxcbiAgbWV0YUtleTogMCxcbiAgcmVwZWF0OiAwLFxuICBsb2NhbGU6IDAsXG4gIGdldE1vZGlmaWVyU3RhdGU6IGdldEV2ZW50TW9kaWZpZXJTdGF0ZSxcbiAgLy8gTGVnYWN5IEludGVyZmFjZVxuICBjaGFyQ29kZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYGNoYXJDb2RlYCBpcyB0aGUgcmVzdWx0IG9mIGEgS2V5UHJlc3MgZXZlbnQgYW5kIHJlcHJlc2VudHMgdGhlIHZhbHVlIG9mXG4gICAgLy8gdGhlIGFjdHVhbCBwcmludGFibGUgY2hhcmFjdGVyLlxuICAgIC8vIEtleVByZXNzIGlzIGRlcHJlY2F0ZWQsIGJ1dCBpdHMgcmVwbGFjZW1lbnQgaXMgbm90IHlldCBmaW5hbCBhbmQgbm90XG4gICAgLy8gaW1wbGVtZW50ZWQgaW4gYW55IG1ham9yIGJyb3dzZXIuIE9ubHkgS2V5UHJlc3MgaGFzIGNoYXJDb2RlLlxuICAgIGlmIChldmVudC50eXBlID09PSAna2V5cHJlc3MnKSB7XG4gICAgICByZXR1cm4gZ2V0RXZlbnRDaGFyQ29kZShldmVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIDA7XG4gIH0sXG4gIGtleUNvZGU6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIC8vIGBrZXlDb2RlYCBpcyB0aGUgcmVzdWx0IG9mIGEgS2V5RG93bi9VcCBldmVudCBhbmQgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2ZcbiAgICAvLyBwaHlzaWNhbCBrZXlib2FyZCBrZXkuXG4gICAgLy8gVGhlIGFjdHVhbCBtZWFuaW5nIG9mIHRoZSB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB1c2Vycycga2V5Ym9hcmQgbGF5b3V0XG4gICAgLy8gd2hpY2ggY2Fubm90IGJlIGRldGVjdGVkLiBBc3N1bWluZyB0aGF0IGl0IGlzIGEgVVMga2V5Ym9hcmQgbGF5b3V0XG4gICAgLy8gcHJvdmlkZXMgYSBzdXJwcmlzaW5nbHkgYWNjdXJhdGUgbWFwcGluZyBmb3IgVVMgYW5kIEV1cm9wZWFuIHVzZXJzLlxuICAgIC8vIER1ZSB0byB0aGlzLCBpdCBpcyBsZWZ0IHRvIHRoZSB1c2VyIHRvIGltcGxlbWVudCBhdCB0aGlzIHRpbWUuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdrZXlkb3duJyB8fCBldmVudC50eXBlID09PSAna2V5dXAnKSB7XG4gICAgICByZXR1cm4gZXZlbnQua2V5Q29kZTtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfSxcbiAgd2hpY2g6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIC8vIGB3aGljaGAgaXMgYW4gYWxpYXMgZm9yIGVpdGhlciBga2V5Q29kZWAgb3IgYGNoYXJDb2RlYCBkZXBlbmRpbmcgb24gdGhlXG4gICAgLy8gdHlwZSBvZiB0aGUgZXZlbnQuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdrZXlwcmVzcycpIHtcbiAgICAgIHJldHVybiBnZXRFdmVudENoYXJDb2RlKGV2ZW50KTtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleWRvd24nIHx8IGV2ZW50LnR5cGUgPT09ICdrZXl1cCcpIHtcbiAgICAgIHJldHVybiBldmVudC5rZXlDb2RlO1xuICAgIH1cblxuICAgIHJldHVybiAwO1xuICB9XG59KTtcblxudmFyIFN5bnRoZXRpY0tleWJvYXJkRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChLZXlib2FyZEV2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBQb2ludGVyRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvcG9pbnRlcmV2ZW50cy9cbiAqL1xuXG52YXIgUG9pbnRlckV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBNb3VzZUV2ZW50SW50ZXJmYWNlLCB7XG4gIHBvaW50ZXJJZDogMCxcbiAgd2lkdGg6IDAsXG4gIGhlaWdodDogMCxcbiAgcHJlc3N1cmU6IDAsXG4gIHRhbmdlbnRpYWxQcmVzc3VyZTogMCxcbiAgdGlsdFg6IDAsXG4gIHRpbHRZOiAwLFxuICB0d2lzdDogMCxcbiAgcG9pbnRlclR5cGU6IDAsXG4gIGlzUHJpbWFyeTogMFxufSk7XG5cbnZhciBTeW50aGV0aWNQb2ludGVyRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChQb2ludGVyRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIFRvdWNoRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvdG91Y2gtZXZlbnRzL1xuICovXG5cbnZhciBUb3VjaEV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIHRvdWNoZXM6IDAsXG4gIHRhcmdldFRvdWNoZXM6IDAsXG4gIGNoYW5nZWRUb3VjaGVzOiAwLFxuICBhbHRLZXk6IDAsXG4gIG1ldGFLZXk6IDAsXG4gIGN0cmxLZXk6IDAsXG4gIHNoaWZ0S2V5OiAwLFxuICBnZXRNb2RpZmllclN0YXRlOiBnZXRFdmVudE1vZGlmaWVyU3RhdGVcbn0pO1xuXG52YXIgU3ludGhldGljVG91Y2hFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KFRvdWNoRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDkvV0QtY3NzMy10cmFuc2l0aW9ucy0yMDA5MDMyMC8jdHJhbnNpdGlvbi1ldmVudHMtXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9UcmFuc2l0aW9uRXZlbnRcbiAqL1xuXG52YXIgVHJhbnNpdGlvbkV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBFdmVudEludGVyZmFjZSwge1xuICBwcm9wZXJ0eU5hbWU6IDAsXG4gIGVsYXBzZWRUaW1lOiAwLFxuICBwc2V1ZG9FbGVtZW50OiAwXG59KTtcblxudmFyIFN5bnRoZXRpY1RyYW5zaXRpb25FdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KFRyYW5zaXRpb25FdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgV2hlZWxFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cblxudmFyIFdoZWVsRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIE1vdXNlRXZlbnRJbnRlcmZhY2UsIHtcbiAgZGVsdGFYOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICByZXR1cm4gJ2RlbHRhWCcgaW4gZXZlbnQgPyBldmVudC5kZWx0YVggOiAvLyBGYWxsYmFjayB0byBgd2hlZWxEZWx0YVhgIGZvciBXZWJraXQgYW5kIG5vcm1hbGl6ZSAocmlnaHQgaXMgcG9zaXRpdmUpLlxuICAgICd3aGVlbERlbHRhWCcgaW4gZXZlbnQgPyAtZXZlbnQud2hlZWxEZWx0YVggOiAwO1xuICB9LFxuICBkZWx0YVk6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiAnZGVsdGFZJyBpbiBldmVudCA/IGV2ZW50LmRlbHRhWSA6IC8vIEZhbGxiYWNrIHRvIGB3aGVlbERlbHRhWWAgZm9yIFdlYmtpdCBhbmQgbm9ybWFsaXplIChkb3duIGlzIHBvc2l0aXZlKS5cbiAgICAnd2hlZWxEZWx0YVknIGluIGV2ZW50ID8gLWV2ZW50LndoZWVsRGVsdGFZIDogLy8gRmFsbGJhY2sgdG8gYHdoZWVsRGVsdGFgIGZvciBJRTw5IGFuZCBub3JtYWxpemUgKGRvd24gaXMgcG9zaXRpdmUpLlxuICAgICd3aGVlbERlbHRhJyBpbiBldmVudCA/IC1ldmVudC53aGVlbERlbHRhIDogMDtcbiAgfSxcbiAgZGVsdGFaOiAwLFxuICAvLyBCcm93c2VycyB3aXRob3V0IFwiZGVsdGFNb2RlXCIgaXMgcmVwb3J0aW5nIGluIHJhdyB3aGVlbCBkZWx0YSB3aGVyZSBvbmVcbiAgLy8gbm90Y2ggb24gdGhlIHNjcm9sbCBpcyBhbHdheXMgKy8tIDEyMCwgcm91Z2hseSBlcXVpdmFsZW50IHRvIHBpeGVscy5cbiAgLy8gQSBnb29kIGFwcHJveGltYXRpb24gb2YgRE9NX0RFTFRBX0xJTkUgKDEpIGlzIDUlIG9mIHZpZXdwb3J0IHNpemUgb3JcbiAgLy8gfjQwIHBpeGVscywgZm9yIERPTV9ERUxUQV9TQ1JFRU4gKDIpIGl0IGlzIDg3LjUlIG9mIHZpZXdwb3J0IHNpemUuXG4gIGRlbHRhTW9kZTogMFxufSk7XG5cbnZhciBTeW50aGV0aWNXaGVlbEV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoV2hlZWxFdmVudEludGVyZmFjZSk7XG5cbnZhciBFTkRfS0VZQ09ERVMgPSBbOSwgMTMsIDI3LCAzMl07IC8vIFRhYiwgUmV0dXJuLCBFc2MsIFNwYWNlXG5cbnZhciBTVEFSVF9LRVlDT0RFID0gMjI5O1xudmFyIGNhblVzZUNvbXBvc2l0aW9uRXZlbnQgPSBjYW5Vc2VET00gJiYgJ0NvbXBvc2l0aW9uRXZlbnQnIGluIHdpbmRvdztcbnZhciBkb2N1bWVudE1vZGUgPSBudWxsO1xuXG5pZiAoY2FuVXNlRE9NICYmICdkb2N1bWVudE1vZGUnIGluIGRvY3VtZW50KSB7XG4gIGRvY3VtZW50TW9kZSA9IGRvY3VtZW50LmRvY3VtZW50TW9kZTtcbn0gLy8gV2Via2l0IG9mZmVycyBhIHZlcnkgdXNlZnVsIGB0ZXh0SW5wdXRgIGV2ZW50IHRoYXQgY2FuIGJlIHVzZWQgdG9cbi8vIGRpcmVjdGx5IHJlcHJlc2VudCBgYmVmb3JlSW5wdXRgLiBUaGUgSUUgYHRleHRpbnB1dGAgZXZlbnQgaXMgbm90IGFzXG4vLyB1c2VmdWwsIHNvIHdlIGRvbid0IHVzZSBpdC5cblxuXG52YXIgY2FuVXNlVGV4dElucHV0RXZlbnQgPSBjYW5Vc2VET00gJiYgJ1RleHRFdmVudCcgaW4gd2luZG93ICYmICFkb2N1bWVudE1vZGU7IC8vIEluIElFOSssIHdlIGhhdmUgYWNjZXNzIHRvIGNvbXBvc2l0aW9uIGV2ZW50cywgYnV0IHRoZSBkYXRhIHN1cHBsaWVkXG4vLyBieSB0aGUgbmF0aXZlIGNvbXBvc2l0aW9uZW5kIGV2ZW50IG1heSBiZSBpbmNvcnJlY3QuIEphcGFuZXNlIGlkZW9ncmFwaGljXG4vLyBzcGFjZXMsIGZvciBpbnN0YW5jZSAoXFx1MzAwMCkgYXJlIG5vdCByZWNvcmRlZCBjb3JyZWN0bHkuXG5cbnZhciB1c2VGYWxsYmFja0NvbXBvc2l0aW9uRGF0YSA9IGNhblVzZURPTSAmJiAoIWNhblVzZUNvbXBvc2l0aW9uRXZlbnQgfHwgZG9jdW1lbnRNb2RlICYmIGRvY3VtZW50TW9kZSA+IDggJiYgZG9jdW1lbnRNb2RlIDw9IDExKTtcbnZhciBTUEFDRUJBUl9DT0RFID0gMzI7XG52YXIgU1BBQ0VCQVJfQ0hBUiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoU1BBQ0VCQVJfQ09ERSk7XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyRXZlbnRzKCkge1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQmVmb3JlSW5wdXQnLCBbJ2NvbXBvc2l0aW9uZW5kJywgJ2tleXByZXNzJywgJ3RleHRJbnB1dCcsICdwYXN0ZSddKTtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvbkNvbXBvc2l0aW9uRW5kJywgWydjb21wb3NpdGlvbmVuZCcsICdmb2N1c291dCcsICdrZXlkb3duJywgJ2tleXByZXNzJywgJ2tleXVwJywgJ21vdXNlZG93biddKTtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvbkNvbXBvc2l0aW9uU3RhcnQnLCBbJ2NvbXBvc2l0aW9uc3RhcnQnLCAnZm9jdXNvdXQnLCAna2V5ZG93bicsICdrZXlwcmVzcycsICdrZXl1cCcsICdtb3VzZWRvd24nXSk7XG4gIHJlZ2lzdGVyVHdvUGhhc2VFdmVudCgnb25Db21wb3NpdGlvblVwZGF0ZScsIFsnY29tcG9zaXRpb251cGRhdGUnLCAnZm9jdXNvdXQnLCAna2V5ZG93bicsICdrZXlwcmVzcycsICdrZXl1cCcsICdtb3VzZWRvd24nXSk7XG59IC8vIFRyYWNrIHdoZXRoZXIgd2UndmUgZXZlciBoYW5kbGVkIGEga2V5cHJlc3Mgb24gdGhlIHNwYWNlIGtleS5cblxuXG52YXIgaGFzU3BhY2VLZXlwcmVzcyA9IGZhbHNlO1xuLyoqXG4gKiBSZXR1cm4gd2hldGhlciBhIG5hdGl2ZSBrZXlwcmVzcyBldmVudCBpcyBhc3N1bWVkIHRvIGJlIGEgY29tbWFuZC5cbiAqIFRoaXMgaXMgcmVxdWlyZWQgYmVjYXVzZSBGaXJlZm94IGZpcmVzIGBrZXlwcmVzc2AgZXZlbnRzIGZvciBrZXkgY29tbWFuZHNcbiAqIChjdXQsIGNvcHksIHNlbGVjdC1hbGwsIGV0Yy4pIGV2ZW4gdGhvdWdoIG5vIGNoYXJhY3RlciBpcyBpbnNlcnRlZC5cbiAqL1xuXG5mdW5jdGlvbiBpc0tleXByZXNzQ29tbWFuZChuYXRpdmVFdmVudCkge1xuICByZXR1cm4gKG5hdGl2ZUV2ZW50LmN0cmxLZXkgfHwgbmF0aXZlRXZlbnQuYWx0S2V5IHx8IG5hdGl2ZUV2ZW50Lm1ldGFLZXkpICYmIC8vIGN0cmxLZXkgJiYgYWx0S2V5IGlzIGVxdWl2YWxlbnQgdG8gQWx0R3IsIGFuZCBpcyBub3QgYSBjb21tYW5kLlxuICAhKG5hdGl2ZUV2ZW50LmN0cmxLZXkgJiYgbmF0aXZlRXZlbnQuYWx0S2V5KTtcbn1cbi8qKlxuICogVHJhbnNsYXRlIG5hdGl2ZSB0b3AgbGV2ZWwgZXZlbnRzIGludG8gZXZlbnQgdHlwZXMuXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRDb21wb3NpdGlvbkV2ZW50VHlwZShkb21FdmVudE5hbWUpIHtcbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICBjYXNlICdjb21wb3NpdGlvbnN0YXJ0JzpcbiAgICAgIHJldHVybiAnb25Db21wb3NpdGlvblN0YXJ0JztcblxuICAgIGNhc2UgJ2NvbXBvc2l0aW9uZW5kJzpcbiAgICAgIHJldHVybiAnb25Db21wb3NpdGlvbkVuZCc7XG5cbiAgICBjYXNlICdjb21wb3NpdGlvbnVwZGF0ZSc6XG4gICAgICByZXR1cm4gJ29uQ29tcG9zaXRpb25VcGRhdGUnO1xuICB9XG59XG4vKipcbiAqIERvZXMgb3VyIGZhbGxiYWNrIGJlc3QtZ3Vlc3MgbW9kZWwgdGhpbmsgdGhpcyBldmVudCBzaWduaWZpZXMgdGhhdFxuICogY29tcG9zaXRpb24gaGFzIGJlZ3VuP1xuICovXG5cblxuZnVuY3Rpb24gaXNGYWxsYmFja0NvbXBvc2l0aW9uU3RhcnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkge1xuICByZXR1cm4gZG9tRXZlbnROYW1lID09PSAna2V5ZG93bicgJiYgbmF0aXZlRXZlbnQua2V5Q29kZSA9PT0gU1RBUlRfS0VZQ09ERTtcbn1cbi8qKlxuICogRG9lcyBvdXIgZmFsbGJhY2sgbW9kZSB0aGluayB0aGF0IHRoaXMgZXZlbnQgaXMgdGhlIGVuZCBvZiBjb21wb3NpdGlvbj9cbiAqL1xuXG5cbmZ1bmN0aW9uIGlzRmFsbGJhY2tDb21wb3NpdGlvbkVuZChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSB7XG4gIHN3aXRjaCAoZG9tRXZlbnROYW1lKSB7XG4gICAgY2FzZSAna2V5dXAnOlxuICAgICAgLy8gQ29tbWFuZCBrZXlzIGluc2VydCBvciBjbGVhciBJTUUgaW5wdXQuXG4gICAgICByZXR1cm4gRU5EX0tFWUNPREVTLmluZGV4T2YobmF0aXZlRXZlbnQua2V5Q29kZSkgIT09IC0xO1xuXG4gICAgY2FzZSAna2V5ZG93bic6XG4gICAgICAvLyBFeHBlY3QgSU1FIGtleUNvZGUgb24gZWFjaCBrZXlkb3duLiBJZiB3ZSBnZXQgYW55IG90aGVyXG4gICAgICAvLyBjb2RlIHdlIG11c3QgaGF2ZSBleGl0ZWQgZWFybGllci5cbiAgICAgIHJldHVybiBuYXRpdmVFdmVudC5rZXlDb2RlICE9PSBTVEFSVF9LRVlDT0RFO1xuXG4gICAgY2FzZSAna2V5cHJlc3MnOlxuICAgIGNhc2UgJ21vdXNlZG93bic6XG4gICAgY2FzZSAnZm9jdXNvdXQnOlxuICAgICAgLy8gRXZlbnRzIGFyZSBub3QgcG9zc2libGUgd2l0aG91dCBjYW5jZWxsaW5nIElNRS5cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuLyoqXG4gKiBHb29nbGUgSW5wdXQgVG9vbHMgcHJvdmlkZXMgY29tcG9zaXRpb24gZGF0YSB2aWEgYSBDdXN0b21FdmVudCxcbiAqIHdpdGggdGhlIGBkYXRhYCBwcm9wZXJ0eSBwb3B1bGF0ZWQgaW4gdGhlIGBkZXRhaWxgIG9iamVjdC4gSWYgdGhpc1xuICogaXMgYXZhaWxhYmxlIG9uIHRoZSBldmVudCBvYmplY3QsIHVzZSBpdC4gSWYgbm90LCB0aGlzIGlzIGEgcGxhaW5cbiAqIGNvbXBvc2l0aW9uIGV2ZW50IGFuZCB3ZSBoYXZlIG5vdGhpbmcgc3BlY2lhbCB0byBleHRyYWN0LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFxuICogQHJldHVybiB7P3N0cmluZ31cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldERhdGFGcm9tQ3VzdG9tRXZlbnQobmF0aXZlRXZlbnQpIHtcbiAgdmFyIGRldGFpbCA9IG5hdGl2ZUV2ZW50LmRldGFpbDtcblxuICBpZiAodHlwZW9mIGRldGFpbCA9PT0gJ29iamVjdCcgJiYgJ2RhdGEnIGluIGRldGFpbCkge1xuICAgIHJldHVybiBkZXRhaWwuZGF0YTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBDaGVjayBpZiBhIGNvbXBvc2l0aW9uIGV2ZW50IHdhcyB0cmlnZ2VyZWQgYnkgS29yZWFuIElNRS5cbiAqIE91ciBmYWxsYmFjayBtb2RlIGRvZXMgbm90IHdvcmsgd2VsbCB3aXRoIElFJ3MgS29yZWFuIElNRSxcbiAqIHNvIGp1c3QgdXNlIG5hdGl2ZSBjb21wb3NpdGlvbiBldmVudHMgd2hlbiBLb3JlYW4gSU1FIGlzIHVzZWQuXG4gKiBBbHRob3VnaCBDb21wb3NpdGlvbkV2ZW50LmxvY2FsZSBwcm9wZXJ0eSBpcyBkZXByZWNhdGVkLFxuICogaXQgaXMgYXZhaWxhYmxlIGluIElFLCB3aGVyZSBvdXIgZmFsbGJhY2sgbW9kZSBpcyBlbmFibGVkLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuXG5cbmZ1bmN0aW9uIGlzVXNpbmdLb3JlYW5JTUUobmF0aXZlRXZlbnQpIHtcbiAgcmV0dXJuIG5hdGl2ZUV2ZW50LmxvY2FsZSA9PT0gJ2tvJztcbn0gLy8gVHJhY2sgdGhlIGN1cnJlbnQgSU1FIGNvbXBvc2l0aW9uIHN0YXR1cywgaWYgYW55LlxuXG5cbnZhciBpc0NvbXBvc2luZyA9IGZhbHNlO1xuLyoqXG4gKiBAcmV0dXJuIHs/b2JqZWN0fSBBIFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQuXG4gKi9cblxuZnVuY3Rpb24gZXh0cmFjdENvbXBvc2l0aW9uRXZlbnQoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgdmFyIGV2ZW50VHlwZTtcbiAgdmFyIGZhbGxiYWNrRGF0YTtcblxuICBpZiAoY2FuVXNlQ29tcG9zaXRpb25FdmVudCkge1xuICAgIGV2ZW50VHlwZSA9IGdldENvbXBvc2l0aW9uRXZlbnRUeXBlKGRvbUV2ZW50TmFtZSk7XG4gIH0gZWxzZSBpZiAoIWlzQ29tcG9zaW5nKSB7XG4gICAgaWYgKGlzRmFsbGJhY2tDb21wb3NpdGlvblN0YXJ0KGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpKSB7XG4gICAgICBldmVudFR5cGUgPSAnb25Db21wb3NpdGlvblN0YXJ0JztcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNGYWxsYmFja0NvbXBvc2l0aW9uRW5kKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpKSB7XG4gICAgZXZlbnRUeXBlID0gJ29uQ29tcG9zaXRpb25FbmQnO1xuICB9XG5cbiAgaWYgKCFldmVudFR5cGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmICh1c2VGYWxsYmFja0NvbXBvc2l0aW9uRGF0YSAmJiAhaXNVc2luZ0tvcmVhbklNRShuYXRpdmVFdmVudCkpIHtcbiAgICAvLyBUaGUgY3VycmVudCBjb21wb3NpdGlvbiBpcyBzdG9yZWQgc3RhdGljYWxseSBhbmQgbXVzdCBub3QgYmVcbiAgICAvLyBvdmVyd3JpdHRlbiB3aGlsZSBjb21wb3NpdGlvbiBjb250aW51ZXMuXG4gICAgaWYgKCFpc0NvbXBvc2luZyAmJiBldmVudFR5cGUgPT09ICdvbkNvbXBvc2l0aW9uU3RhcnQnKSB7XG4gICAgICBpc0NvbXBvc2luZyA9IGluaXRpYWxpemUobmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnRUeXBlID09PSAnb25Db21wb3NpdGlvbkVuZCcpIHtcbiAgICAgIGlmIChpc0NvbXBvc2luZykge1xuICAgICAgICBmYWxsYmFja0RhdGEgPSBnZXREYXRhKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGxpc3RlbmVycyA9IGFjY3VtdWxhdGVUd29QaGFzZUxpc3RlbmVycyh0YXJnZXRJbnN0LCBldmVudFR5cGUpO1xuXG4gIGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgIHZhciBldmVudCA9IG5ldyBTeW50aGV0aWNDb21wb3NpdGlvbkV2ZW50KGV2ZW50VHlwZSwgZG9tRXZlbnROYW1lLCBudWxsLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICBsaXN0ZW5lcnM6IGxpc3RlbmVyc1xuICAgIH0pO1xuXG4gICAgaWYgKGZhbGxiYWNrRGF0YSkge1xuICAgICAgLy8gSW5qZWN0IGRhdGEgZ2VuZXJhdGVkIGZyb20gZmFsbGJhY2sgcGF0aCBpbnRvIHRoZSBzeW50aGV0aWMgZXZlbnQuXG4gICAgICAvLyBUaGlzIG1hdGNoZXMgdGhlIHByb3BlcnR5IG9mIG5hdGl2ZSBDb21wb3NpdGlvbkV2ZW50SW50ZXJmYWNlLlxuICAgICAgZXZlbnQuZGF0YSA9IGZhbGxiYWNrRGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGN1c3RvbURhdGEgPSBnZXREYXRhRnJvbUN1c3RvbUV2ZW50KG5hdGl2ZUV2ZW50KTtcblxuICAgICAgaWYgKGN1c3RvbURhdGEgIT09IG51bGwpIHtcbiAgICAgICAgZXZlbnQuZGF0YSA9IGN1c3RvbURhdGE7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldE5hdGl2ZUJlZm9yZUlucHV0Q2hhcnMoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkge1xuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2NvbXBvc2l0aW9uZW5kJzpcbiAgICAgIHJldHVybiBnZXREYXRhRnJvbUN1c3RvbUV2ZW50KG5hdGl2ZUV2ZW50KTtcblxuICAgIGNhc2UgJ2tleXByZXNzJzpcbiAgICAgIC8qKlxuICAgICAgICogSWYgbmF0aXZlIGB0ZXh0SW5wdXRgIGV2ZW50cyBhcmUgYXZhaWxhYmxlLCBvdXIgZ29hbCBpcyB0byBtYWtlXG4gICAgICAgKiB1c2Ugb2YgdGhlbS4gSG93ZXZlciwgdGhlcmUgaXMgYSBzcGVjaWFsIGNhc2U6IHRoZSBzcGFjZWJhciBrZXkuXG4gICAgICAgKiBJbiBXZWJraXQsIHByZXZlbnRpbmcgZGVmYXVsdCBvbiBhIHNwYWNlYmFyIGB0ZXh0SW5wdXRgIGV2ZW50XG4gICAgICAgKiBjYW5jZWxzIGNoYXJhY3RlciBpbnNlcnRpb24sIGJ1dCBpdCAqYWxzbyogY2F1c2VzIHRoZSBicm93c2VyXG4gICAgICAgKiB0byBmYWxsIGJhY2sgdG8gaXRzIGRlZmF1bHQgc3BhY2ViYXIgYmVoYXZpb3Igb2Ygc2Nyb2xsaW5nIHRoZVxuICAgICAgICogcGFnZS5cbiAgICAgICAqXG4gICAgICAgKiBUcmFja2luZyBhdDpcbiAgICAgICAqIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zNTUxMDNcbiAgICAgICAqXG4gICAgICAgKiBUbyBhdm9pZCB0aGlzIGlzc3VlLCB1c2UgdGhlIGtleXByZXNzIGV2ZW50IGFzIGlmIG5vIGB0ZXh0SW5wdXRgXG4gICAgICAgKiBldmVudCBpcyBhdmFpbGFibGUuXG4gICAgICAgKi9cbiAgICAgIHZhciB3aGljaCA9IG5hdGl2ZUV2ZW50LndoaWNoO1xuXG4gICAgICBpZiAod2hpY2ggIT09IFNQQUNFQkFSX0NPREUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGhhc1NwYWNlS2V5cHJlc3MgPSB0cnVlO1xuICAgICAgcmV0dXJuIFNQQUNFQkFSX0NIQVI7XG5cbiAgICBjYXNlICd0ZXh0SW5wdXQnOlxuICAgICAgLy8gUmVjb3JkIHRoZSBjaGFyYWN0ZXJzIHRvIGJlIGFkZGVkIHRvIHRoZSBET00uXG4gICAgICB2YXIgY2hhcnMgPSBuYXRpdmVFdmVudC5kYXRhOyAvLyBJZiBpdCdzIGEgc3BhY2ViYXIgY2hhcmFjdGVyLCBhc3N1bWUgdGhhdCB3ZSBoYXZlIGFscmVhZHkgaGFuZGxlZFxuICAgICAgLy8gaXQgYXQgdGhlIGtleXByZXNzIGxldmVsIGFuZCBiYWlsIGltbWVkaWF0ZWx5LiBBbmRyb2lkIENocm9tZVxuICAgICAgLy8gZG9lc24ndCBnaXZlIHVzIGtleWNvZGVzLCBzbyB3ZSBuZWVkIHRvIGlnbm9yZSBpdC5cblxuICAgICAgaWYgKGNoYXJzID09PSBTUEFDRUJBUl9DSEFSICYmIGhhc1NwYWNlS2V5cHJlc3MpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjaGFycztcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBGb3Igb3RoZXIgbmF0aXZlIGV2ZW50IHR5cGVzLCBkbyBub3RoaW5nLlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbi8qKlxuICogRm9yIGJyb3dzZXJzIHRoYXQgZG8gbm90IHByb3ZpZGUgdGhlIGB0ZXh0SW5wdXRgIGV2ZW50LCBleHRyYWN0IHRoZVxuICogYXBwcm9wcmlhdGUgc3RyaW5nIHRvIHVzZSBmb3IgU3ludGhldGljSW5wdXRFdmVudC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEZhbGxiYWNrQmVmb3JlSW5wdXRDaGFycyhkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSB7XG4gIC8vIElmIHdlIGFyZSBjdXJyZW50bHkgY29tcG9zaW5nIChJTUUpIGFuZCB1c2luZyBhIGZhbGxiYWNrIHRvIGRvIHNvLFxuICAvLyB0cnkgdG8gZXh0cmFjdCB0aGUgY29tcG9zZWQgY2hhcmFjdGVycyBmcm9tIHRoZSBmYWxsYmFjayBvYmplY3QuXG4gIC8vIElmIGNvbXBvc2l0aW9uIGV2ZW50IGlzIGF2YWlsYWJsZSwgd2UgZXh0cmFjdCBhIHN0cmluZyBvbmx5IGF0XG4gIC8vIGNvbXBvc2l0aW9uZXZlbnQsIG90aGVyd2lzZSBleHRyYWN0IGl0IGF0IGZhbGxiYWNrIGV2ZW50cy5cbiAgaWYgKGlzQ29tcG9zaW5nKSB7XG4gICAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ2NvbXBvc2l0aW9uZW5kJyB8fCAhY2FuVXNlQ29tcG9zaXRpb25FdmVudCAmJiBpc0ZhbGxiYWNrQ29tcG9zaXRpb25FbmQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkpIHtcbiAgICAgIHZhciBjaGFycyA9IGdldERhdGEoKTtcbiAgICAgIHJlc2V0KCk7XG4gICAgICBpc0NvbXBvc2luZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuIGNoYXJzO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICBjYXNlICdwYXN0ZSc6XG4gICAgICAvLyBJZiBhIHBhc3RlIGV2ZW50IG9jY3VycyBhZnRlciBhIGtleXByZXNzLCB0aHJvdyBvdXQgdGhlIGlucHV0XG4gICAgICAvLyBjaGFycy4gUGFzdGUgZXZlbnRzIHNob3VsZCBub3QgbGVhZCB0byBCZWZvcmVJbnB1dCBldmVudHMuXG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgJ2tleXByZXNzJzpcbiAgICAgIC8qKlxuICAgICAgICogQXMgb2YgdjI3LCBGaXJlZm94IG1heSBmaXJlIGtleXByZXNzIGV2ZW50cyBldmVuIHdoZW4gbm8gY2hhcmFjdGVyXG4gICAgICAgKiB3aWxsIGJlIGluc2VydGVkLiBBIGZldyBwb3NzaWJpbGl0aWVzOlxuICAgICAgICpcbiAgICAgICAqIC0gYHdoaWNoYCBpcyBgMGAuIEFycm93IGtleXMsIEVzYyBrZXksIGV0Yy5cbiAgICAgICAqXG4gICAgICAgKiAtIGB3aGljaGAgaXMgdGhlIHByZXNzZWQga2V5IGNvZGUsIGJ1dCBubyBjaGFyIGlzIGF2YWlsYWJsZS5cbiAgICAgICAqICAgRXg6ICdBbHRHciArIGRgIGluIFBvbGlzaC4gVGhlcmUgaXMgbm8gbW9kaWZpZWQgY2hhcmFjdGVyIGZvclxuICAgICAgICogICB0aGlzIGtleSBjb21iaW5hdGlvbiBhbmQgbm8gY2hhcmFjdGVyIGlzIGluc2VydGVkIGludG8gdGhlXG4gICAgICAgKiAgIGRvY3VtZW50LCBidXQgRkYgZmlyZXMgdGhlIGtleXByZXNzIGZvciBjaGFyIGNvZGUgYDEwMGAgYW55d2F5LlxuICAgICAgICogICBObyBgaW5wdXRgIGV2ZW50IHdpbGwgb2NjdXIuXG4gICAgICAgKlxuICAgICAgICogLSBgd2hpY2hgIGlzIHRoZSBwcmVzc2VkIGtleSBjb2RlLCBidXQgYSBjb21tYW5kIGNvbWJpbmF0aW9uIGlzXG4gICAgICAgKiAgIGJlaW5nIHVzZWQuIEV4OiBgQ21kK0NgLiBObyBjaGFyYWN0ZXIgaXMgaW5zZXJ0ZWQsIGFuZCBub1xuICAgICAgICogICBgaW5wdXRgIGV2ZW50IHdpbGwgb2NjdXIuXG4gICAgICAgKi9cbiAgICAgIGlmICghaXNLZXlwcmVzc0NvbW1hbmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgIC8vIElFIGZpcmVzIHRoZSBga2V5cHJlc3NgIGV2ZW50IHdoZW4gYSB1c2VyIHR5cGVzIGFuIGVtb2ppIHZpYVxuICAgICAgICAvLyBUb3VjaCBrZXlib2FyZCBvZiBXaW5kb3dzLiAgSW4gc3VjaCBhIGNhc2UsIHRoZSBgY2hhcmAgcHJvcGVydHlcbiAgICAgICAgLy8gaG9sZHMgYW4gZW1vamkgY2hhcmFjdGVyIGxpa2UgYFxcdUQ4M0RcXHVERTBBYC4gIEJlY2F1c2UgaXRzIGxlbmd0aFxuICAgICAgICAvLyBpcyAyLCB0aGUgcHJvcGVydHkgYHdoaWNoYCBkb2VzIG5vdCByZXByZXNlbnQgYW4gZW1vamkgY29ycmVjdGx5LlxuICAgICAgICAvLyBJbiBzdWNoIGEgY2FzZSwgd2UgZGlyZWN0bHkgcmV0dXJuIHRoZSBgY2hhcmAgcHJvcGVydHkgaW5zdGVhZCBvZlxuICAgICAgICAvLyB1c2luZyBgd2hpY2hgLlxuICAgICAgICBpZiAobmF0aXZlRXZlbnQuY2hhciAmJiBuYXRpdmVFdmVudC5jaGFyLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICByZXR1cm4gbmF0aXZlRXZlbnQuY2hhcjtcbiAgICAgICAgfSBlbHNlIGlmIChuYXRpdmVFdmVudC53aGljaCkge1xuICAgICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKG5hdGl2ZUV2ZW50LndoaWNoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgJ2NvbXBvc2l0aW9uZW5kJzpcbiAgICAgIHJldHVybiB1c2VGYWxsYmFja0NvbXBvc2l0aW9uRGF0YSAmJiAhaXNVc2luZ0tvcmVhbklNRShuYXRpdmVFdmVudCkgPyBudWxsIDogbmF0aXZlRXZlbnQuZGF0YTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuLyoqXG4gKiBFeHRyYWN0IGEgU3ludGhldGljSW5wdXRFdmVudCBmb3IgYGJlZm9yZUlucHV0YCwgYmFzZWQgb24gZWl0aGVyIG5hdGl2ZVxuICogYHRleHRJbnB1dGAgb3IgZmFsbGJhY2sgYmVoYXZpb3IuXG4gKlxuICogQHJldHVybiB7P29iamVjdH0gQSBTeW50aGV0aWNJbnB1dEV2ZW50LlxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEJlZm9yZUlucHV0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgdmFyIGNoYXJzO1xuXG4gIGlmIChjYW5Vc2VUZXh0SW5wdXRFdmVudCkge1xuICAgIGNoYXJzID0gZ2V0TmF0aXZlQmVmb3JlSW5wdXRDaGFycyhkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBjaGFycyA9IGdldEZhbGxiYWNrQmVmb3JlSW5wdXRDaGFycyhkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KTtcbiAgfSAvLyBJZiBubyBjaGFyYWN0ZXJzIGFyZSBiZWluZyBpbnNlcnRlZCwgbm8gQmVmb3JlSW5wdXQgZXZlbnQgc2hvdWxkXG4gIC8vIGJlIGZpcmVkLlxuXG5cbiAgaWYgKCFjaGFycykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGxpc3RlbmVycyA9IGFjY3VtdWxhdGVUd29QaGFzZUxpc3RlbmVycyh0YXJnZXRJbnN0LCAnb25CZWZvcmVJbnB1dCcpO1xuXG4gIGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgIHZhciBldmVudCA9IG5ldyBTeW50aGV0aWNJbnB1dEV2ZW50KCdvbkJlZm9yZUlucHV0JywgJ2JlZm9yZWlucHV0JywgbnVsbCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBkaXNwYXRjaFF1ZXVlLnB1c2goe1xuICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgICB9KTtcbiAgICBldmVudC5kYXRhID0gY2hhcnM7XG4gIH1cbn1cbi8qKlxuICogQ3JlYXRlIGFuIGBvbkJlZm9yZUlucHV0YCBldmVudCB0byBtYXRjaFxuICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAxMzExMDUvI2V2ZW50cy1pbnB1dGV2ZW50cy5cbiAqXG4gKiBUaGlzIGV2ZW50IHBsdWdpbiBpcyBiYXNlZCBvbiB0aGUgbmF0aXZlIGB0ZXh0SW5wdXRgIGV2ZW50XG4gKiBhdmFpbGFibGUgaW4gQ2hyb21lLCBTYWZhcmksIE9wZXJhLCBhbmQgSUUuIFRoaXMgZXZlbnQgZmlyZXMgYWZ0ZXJcbiAqIGBvbktleVByZXNzYCBhbmQgYG9uQ29tcG9zaXRpb25FbmRgLCBidXQgYmVmb3JlIGBvbklucHV0YC5cbiAqXG4gKiBgYmVmb3JlSW5wdXRgIGlzIHNwZWMnZCBidXQgbm90IGltcGxlbWVudGVkIGluIGFueSBicm93c2VycywgYW5kXG4gKiB0aGUgYGlucHV0YCBldmVudCBkb2VzIG5vdCBwcm92aWRlIGFueSB1c2VmdWwgaW5mb3JtYXRpb24gYWJvdXQgd2hhdCBoYXNcbiAqIGFjdHVhbGx5IGJlZW4gYWRkZWQsIGNvbnRyYXJ5IHRvIHRoZSBzcGVjLiBUaHVzLCBgdGV4dElucHV0YCBpcyB0aGUgYmVzdFxuICogYXZhaWxhYmxlIGV2ZW50IHRvIGlkZW50aWZ5IHRoZSBjaGFyYWN0ZXJzIHRoYXQgaGF2ZSBhY3R1YWxseSBiZWVuIGluc2VydGVkXG4gKiBpbnRvIHRoZSB0YXJnZXQgbm9kZS5cbiAqXG4gKiBUaGlzIHBsdWdpbiBpcyBhbHNvIHJlc3BvbnNpYmxlIGZvciBlbWl0dGluZyBgY29tcG9zaXRpb25gIGV2ZW50cywgdGh1c1xuICogYWxsb3dpbmcgdXMgdG8gc2hhcmUgY29tcG9zaXRpb24gZmFsbGJhY2sgY29kZSBmb3IgYm90aCBgYmVmb3JlSW5wdXRgIGFuZFxuICogYGNvbXBvc2l0aW9uYCBldmVudCB0eXBlcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGV4dHJhY3RFdmVudHMoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lcikge1xuICBleHRyYWN0Q29tcG9zaXRpb25FdmVudChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gIGV4dHJhY3RCZWZvcmVJbnB1dEV2ZW50KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbn1cblxuLyoqXG4gKiBAc2VlIGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL3RoZS1pbnB1dC1lbGVtZW50Lmh0bWwjaW5wdXQtdHlwZS1hdHRyLXN1bW1hcnlcbiAqL1xudmFyIHN1cHBvcnRlZElucHV0VHlwZXMgPSB7XG4gIGNvbG9yOiB0cnVlLFxuICBkYXRlOiB0cnVlLFxuICBkYXRldGltZTogdHJ1ZSxcbiAgJ2RhdGV0aW1lLWxvY2FsJzogdHJ1ZSxcbiAgZW1haWw6IHRydWUsXG4gIG1vbnRoOiB0cnVlLFxuICBudW1iZXI6IHRydWUsXG4gIHBhc3N3b3JkOiB0cnVlLFxuICByYW5nZTogdHJ1ZSxcbiAgc2VhcmNoOiB0cnVlLFxuICB0ZWw6IHRydWUsXG4gIHRleHQ6IHRydWUsXG4gIHRpbWU6IHRydWUsXG4gIHVybDogdHJ1ZSxcbiAgd2VlazogdHJ1ZVxufTtcblxuZnVuY3Rpb24gaXNUZXh0SW5wdXRFbGVtZW50KGVsZW0pIHtcbiAgdmFyIG5vZGVOYW1lID0gZWxlbSAmJiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICBpZiAobm9kZU5hbWUgPT09ICdpbnB1dCcpIHtcbiAgICByZXR1cm4gISFzdXBwb3J0ZWRJbnB1dFR5cGVzW2VsZW0udHlwZV07XG4gIH1cblxuICBpZiAobm9kZU5hbWUgPT09ICd0ZXh0YXJlYScpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYW4gZXZlbnQgaXMgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBlbnZpcm9ubWVudC5cbiAqXG4gKiBOT1RFOiBUaGlzIHdpbGwgbm90IHdvcmsgY29ycmVjdGx5IGZvciBub24tZ2VuZXJpYyBldmVudHMgc3VjaCBhcyBgY2hhbmdlYCxcbiAqIGByZXNldGAsIGBsb2FkYCwgYGVycm9yYCwgYW5kIGBzZWxlY3RgLlxuICpcbiAqIEJvcnJvd3MgZnJvbSBNb2Rlcm5penIuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVN1ZmZpeCBFdmVudCBuYW1lLCBlLmcuIFwiY2xpY2tcIi5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV2ZW50IGlzIHN1cHBvcnRlZC5cbiAqIEBpbnRlcm5hbFxuICogQGxpY2Vuc2UgTW9kZXJuaXpyIDMuMC4wcHJlIChDdXN0b20gQnVpbGQpIHwgTUlUXG4gKi9cblxuZnVuY3Rpb24gaXNFdmVudFN1cHBvcnRlZChldmVudE5hbWVTdWZmaXgpIHtcbiAgaWYgKCFjYW5Vc2VET00pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgZXZlbnROYW1lID0gJ29uJyArIGV2ZW50TmFtZVN1ZmZpeDtcbiAgdmFyIGlzU3VwcG9ydGVkID0gKGV2ZW50TmFtZSBpbiBkb2N1bWVudCk7XG5cbiAgaWYgKCFpc1N1cHBvcnRlZCkge1xuICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoZXZlbnROYW1lLCAncmV0dXJuOycpO1xuICAgIGlzU3VwcG9ydGVkID0gdHlwZW9mIGVsZW1lbnRbZXZlbnROYW1lXSA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxuXG4gIHJldHVybiBpc1N1cHBvcnRlZDtcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMkMSgpIHtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvbkNoYW5nZScsIFsnY2hhbmdlJywgJ2NsaWNrJywgJ2ZvY3VzaW4nLCAnZm9jdXNvdXQnLCAnaW5wdXQnLCAna2V5ZG93bicsICdrZXl1cCcsICdzZWxlY3Rpb25jaGFuZ2UnXSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUFuZEFjY3VtdWxhdGVDaGFuZ2VFdmVudChkaXNwYXRjaFF1ZXVlLCBpbnN0LCBuYXRpdmVFdmVudCwgdGFyZ2V0KSB7XG4gIC8vIEZsYWcgdGhpcyBldmVudCBsb29wIGFzIG5lZWRpbmcgc3RhdGUgcmVzdG9yZS5cbiAgZW5xdWV1ZVN0YXRlUmVzdG9yZSh0YXJnZXQpO1xuICB2YXIgbGlzdGVuZXJzID0gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKGluc3QsICdvbkNoYW5nZScpO1xuXG4gIGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgIHZhciBldmVudCA9IG5ldyBTeW50aGV0aWNFdmVudCgnb25DaGFuZ2UnLCAnY2hhbmdlJywgbnVsbCwgbmF0aXZlRXZlbnQsIHRhcmdldCk7XG4gICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgfSk7XG4gIH1cbn1cbi8qKlxuICogRm9yIElFIHNoaW1zXG4gKi9cblxuXG52YXIgYWN0aXZlRWxlbWVudCA9IG51bGw7XG52YXIgYWN0aXZlRWxlbWVudEluc3QgPSBudWxsO1xuLyoqXG4gKiBTRUNUSU9OOiBoYW5kbGUgYGNoYW5nZWAgZXZlbnRcbiAqL1xuXG5mdW5jdGlvbiBzaG91bGRVc2VDaGFuZ2VFdmVudChlbGVtKSB7XG4gIHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gbm9kZU5hbWUgPT09ICdzZWxlY3QnIHx8IG5vZGVOYW1lID09PSAnaW5wdXQnICYmIGVsZW0udHlwZSA9PT0gJ2ZpbGUnO1xufVxuXG5mdW5jdGlvbiBtYW51YWxEaXNwYXRjaENoYW5nZUV2ZW50KG5hdGl2ZUV2ZW50KSB7XG4gIHZhciBkaXNwYXRjaFF1ZXVlID0gW107XG4gIGNyZWF0ZUFuZEFjY3VtdWxhdGVDaGFuZ2VFdmVudChkaXNwYXRjaFF1ZXVlLCBhY3RpdmVFbGVtZW50SW5zdCwgbmF0aXZlRXZlbnQsIGdldEV2ZW50VGFyZ2V0KG5hdGl2ZUV2ZW50KSk7IC8vIElmIGNoYW5nZSBhbmQgcHJvcGVydHljaGFuZ2UgYnViYmxlZCwgd2UnZCBqdXN0IGJpbmQgdG8gaXQgbGlrZSBhbGwgdGhlXG4gIC8vIG90aGVyIGV2ZW50cyBhbmQgaGF2ZSBpdCBnbyB0aHJvdWdoIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci4gU2luY2UgaXRcbiAgLy8gZG9lc24ndCwgd2UgbWFudWFsbHkgbGlzdGVuIGZvciB0aGUgZXZlbnRzIGFuZCBzbyB3ZSBoYXZlIHRvIGVucXVldWUgYW5kXG4gIC8vIHByb2Nlc3MgdGhlIGFic3RyYWN0IGV2ZW50IG1hbnVhbGx5LlxuICAvL1xuICAvLyBCYXRjaGluZyBpcyBuZWNlc3NhcnkgaGVyZSBpbiBvcmRlciB0byBlbnN1cmUgdGhhdCBhbGwgZXZlbnQgaGFuZGxlcnMgcnVuXG4gIC8vIGJlZm9yZSB0aGUgbmV4dCByZXJlbmRlciAoaW5jbHVkaW5nIGV2ZW50IGhhbmRsZXJzIGF0dGFjaGVkIHRvIGFuY2VzdG9yXG4gIC8vIGVsZW1lbnRzIGluc3RlYWQgb2YgZGlyZWN0bHkgb24gdGhlIGlucHV0KS4gV2l0aG91dCB0aGlzLCBjb250cm9sbGVkXG4gIC8vIGNvbXBvbmVudHMgZG9uJ3Qgd29yayBwcm9wZXJseSBpbiBjb25qdW5jdGlvbiB3aXRoIGV2ZW50IGJ1YmJsaW5nIGJlY2F1c2VcbiAgLy8gdGhlIGNvbXBvbmVudCBpcyByZXJlbmRlcmVkIGFuZCB0aGUgdmFsdWUgcmV2ZXJ0ZWQgYmVmb3JlIGFsbCB0aGUgZXZlbnRcbiAgLy8gaGFuZGxlcnMgY2FuIHJ1bi4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvNzA4LlxuXG4gIGJhdGNoZWRVcGRhdGVzKHJ1bkV2ZW50SW5CYXRjaCwgZGlzcGF0Y2hRdWV1ZSk7XG59XG5cbmZ1bmN0aW9uIHJ1bkV2ZW50SW5CYXRjaChkaXNwYXRjaFF1ZXVlKSB7XG4gIHByb2Nlc3NEaXNwYXRjaFF1ZXVlKGRpc3BhdGNoUXVldWUsIDApO1xufVxuXG5mdW5jdGlvbiBnZXRJbnN0SWZWYWx1ZUNoYW5nZWQodGFyZ2V0SW5zdCkge1xuICB2YXIgdGFyZ2V0Tm9kZSA9IGdldE5vZGVGcm9tSW5zdGFuY2UodGFyZ2V0SW5zdCk7XG5cbiAgaWYgKHVwZGF0ZVZhbHVlSWZDaGFuZ2VkKHRhcmdldE5vZGUpKSB7XG4gICAgcmV0dXJuIHRhcmdldEluc3Q7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VGFyZ2V0SW5zdEZvckNoYW5nZUV2ZW50KGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnY2hhbmdlJykge1xuICAgIHJldHVybiB0YXJnZXRJbnN0O1xuICB9XG59XG4vKipcbiAqIFNFQ1RJT046IGhhbmRsZSBgaW5wdXRgIGV2ZW50XG4gKi9cblxuXG52YXIgaXNJbnB1dEV2ZW50U3VwcG9ydGVkID0gZmFsc2U7XG5cbmlmIChjYW5Vc2VET00pIHtcbiAgLy8gSUU5IGNsYWltcyB0byBzdXBwb3J0IHRoZSBpbnB1dCBldmVudCBidXQgZmFpbHMgdG8gdHJpZ2dlciBpdCB3aGVuXG4gIC8vIGRlbGV0aW5nIHRleHQsIHNvIHdlIGlnbm9yZSBpdHMgaW5wdXQgZXZlbnRzLlxuICBpc0lucHV0RXZlbnRTdXBwb3J0ZWQgPSBpc0V2ZW50U3VwcG9ydGVkKCdpbnB1dCcpICYmICghZG9jdW1lbnQuZG9jdW1lbnRNb2RlIHx8IGRvY3VtZW50LmRvY3VtZW50TW9kZSA+IDkpO1xufVxuLyoqXG4gKiAoRm9yIElFIDw9OSkgU3RhcnRzIHRyYWNraW5nIHByb3BlcnR5Y2hhbmdlIGV2ZW50cyBvbiB0aGUgcGFzc2VkLWluIGVsZW1lbnRcbiAqIGFuZCBvdmVycmlkZSB0aGUgdmFsdWUgcHJvcGVydHkgc28gdGhhdCB3ZSBjYW4gZGlzdGluZ3Vpc2ggdXNlciBldmVudHMgZnJvbVxuICogdmFsdWUgY2hhbmdlcyBpbiBKUy5cbiAqL1xuXG5cbmZ1bmN0aW9uIHN0YXJ0V2F0Y2hpbmdGb3JWYWx1ZUNoYW5nZSh0YXJnZXQsIHRhcmdldEluc3QpIHtcbiAgYWN0aXZlRWxlbWVudCA9IHRhcmdldDtcbiAgYWN0aXZlRWxlbWVudEluc3QgPSB0YXJnZXRJbnN0O1xuICBhY3RpdmVFbGVtZW50LmF0dGFjaEV2ZW50KCdvbnByb3BlcnR5Y2hhbmdlJywgaGFuZGxlUHJvcGVydHlDaGFuZ2UpO1xufVxuLyoqXG4gKiAoRm9yIElFIDw9OSkgUmVtb3ZlcyB0aGUgZXZlbnQgbGlzdGVuZXJzIGZyb20gdGhlIGN1cnJlbnRseS10cmFja2VkIGVsZW1lbnQsXG4gKiBpZiBhbnkgZXhpc3RzLlxuICovXG5cblxuZnVuY3Rpb24gc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKSB7XG4gIGlmICghYWN0aXZlRWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGFjdGl2ZUVsZW1lbnQuZGV0YWNoRXZlbnQoJ29ucHJvcGVydHljaGFuZ2UnLCBoYW5kbGVQcm9wZXJ0eUNoYW5nZSk7XG4gIGFjdGl2ZUVsZW1lbnQgPSBudWxsO1xuICBhY3RpdmVFbGVtZW50SW5zdCA9IG51bGw7XG59XG4vKipcbiAqIChGb3IgSUUgPD05KSBIYW5kbGVzIGEgcHJvcGVydHljaGFuZ2UgZXZlbnQsIHNlbmRpbmcgYSBgY2hhbmdlYCBldmVudCBpZlxuICogdGhlIHZhbHVlIG9mIHRoZSBhY3RpdmUgZWxlbWVudCBoYXMgY2hhbmdlZC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGhhbmRsZVByb3BlcnR5Q2hhbmdlKG5hdGl2ZUV2ZW50KSB7XG4gIGlmIChuYXRpdmVFdmVudC5wcm9wZXJ0eU5hbWUgIT09ICd2YWx1ZScpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZ2V0SW5zdElmVmFsdWVDaGFuZ2VkKGFjdGl2ZUVsZW1lbnRJbnN0KSkge1xuICAgIG1hbnVhbERpc3BhdGNoQ2hhbmdlRXZlbnQobmF0aXZlRXZlbnQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUV2ZW50c0ZvcklucHV0RXZlbnRQb2x5ZmlsbChkb21FdmVudE5hbWUsIHRhcmdldCwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnZm9jdXNpbicpIHtcbiAgICAvLyBJbiBJRTksIHByb3BlcnR5Y2hhbmdlIGZpcmVzIGZvciBtb3N0IGlucHV0IGV2ZW50cyBidXQgaXMgYnVnZ3kgYW5kXG4gICAgLy8gZG9lc24ndCBmaXJlIHdoZW4gdGV4dCBpcyBkZWxldGVkLCBidXQgY29udmVuaWVudGx5LCBzZWxlY3Rpb25jaGFuZ2VcbiAgICAvLyBhcHBlYXJzIHRvIGZpcmUgaW4gYWxsIG9mIHRoZSByZW1haW5pbmcgY2FzZXMgc28gd2UgY2F0Y2ggdGhvc2UgYW5kXG4gICAgLy8gZm9yd2FyZCB0aGUgZXZlbnQgaWYgdGhlIHZhbHVlIGhhcyBjaGFuZ2VkXG4gICAgLy8gSW4gZWl0aGVyIGNhc2UsIHdlIGRvbid0IHdhbnQgdG8gY2FsbCB0aGUgZXZlbnQgaGFuZGxlciBpZiB0aGUgdmFsdWVcbiAgICAvLyBpcyBjaGFuZ2VkIGZyb20gSlMgc28gd2UgcmVkZWZpbmUgYSBzZXR0ZXIgZm9yIGAudmFsdWVgIHRoYXQgdXBkYXRlc1xuICAgIC8vIG91ciBhY3RpdmVFbGVtZW50VmFsdWUgdmFyaWFibGUsIGFsbG93aW5nIHVzIHRvIGlnbm9yZSB0aG9zZSBjaGFuZ2VzXG4gICAgLy9cbiAgICAvLyBzdG9wV2F0Y2hpbmcoKSBzaG91bGQgYmUgYSBub29wIGhlcmUgYnV0IHdlIGNhbGwgaXQganVzdCBpbiBjYXNlIHdlXG4gICAgLy8gbWlzc2VkIGEgYmx1ciBldmVudCBzb21laG93LlxuICAgIHN0b3BXYXRjaGluZ0ZvclZhbHVlQ2hhbmdlKCk7XG4gICAgc3RhcnRXYXRjaGluZ0ZvclZhbHVlQ2hhbmdlKHRhcmdldCwgdGFyZ2V0SW5zdCk7XG4gIH0gZWxzZSBpZiAoZG9tRXZlbnROYW1lID09PSAnZm9jdXNvdXQnKSB7XG4gICAgc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKTtcbiAgfVxufSAvLyBGb3IgSUU4IGFuZCBJRTkuXG5cblxuZnVuY3Rpb24gZ2V0VGFyZ2V0SW5zdEZvcklucHV0RXZlbnRQb2x5ZmlsbChkb21FdmVudE5hbWUsIHRhcmdldEluc3QpIHtcbiAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ3NlbGVjdGlvbmNoYW5nZScgfHwgZG9tRXZlbnROYW1lID09PSAna2V5dXAnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ2tleWRvd24nKSB7XG4gICAgLy8gT24gdGhlIHNlbGVjdGlvbmNoYW5nZSBldmVudCwgdGhlIHRhcmdldCBpcyBqdXN0IGRvY3VtZW50IHdoaWNoIGlzbid0XG4gICAgLy8gaGVscGZ1bCBmb3IgdXMgc28ganVzdCBjaGVjayBhY3RpdmVFbGVtZW50IGluc3RlYWQuXG4gICAgLy9cbiAgICAvLyA5OSUgb2YgdGhlIHRpbWUsIGtleWRvd24gYW5kIGtleXVwIGFyZW4ndCBuZWNlc3NhcnkuIElFOCBmYWlscyB0byBmaXJlXG4gICAgLy8gcHJvcGVydHljaGFuZ2Ugb24gdGhlIGZpcnN0IGlucHV0IGV2ZW50IGFmdGVyIHNldHRpbmcgYHZhbHVlYCBmcm9tIGFcbiAgICAvLyBzY3JpcHQgYW5kIGZpcmVzIG9ubHkga2V5ZG93biwga2V5cHJlc3MsIGtleXVwLiBDYXRjaGluZyBrZXl1cCB1c3VhbGx5XG4gICAgLy8gZ2V0cyBpdCBhbmQgY2F0Y2hpbmcga2V5ZG93biBsZXRzIHVzIGZpcmUgYW4gZXZlbnQgZm9yIHRoZSBmaXJzdFxuICAgIC8vIGtleXN0cm9rZSBpZiB1c2VyIGRvZXMgYSBrZXkgcmVwZWF0IChpdCdsbCBiZSBhIGxpdHRsZSBkZWxheWVkOiByaWdodFxuICAgIC8vIGJlZm9yZSB0aGUgc2Vjb25kIGtleXN0cm9rZSkuIE90aGVyIGlucHV0IG1ldGhvZHMgKGUuZy4sIHBhc3RlKSBzZWVtIHRvXG4gICAgLy8gZmlyZSBzZWxlY3Rpb25jaGFuZ2Ugbm9ybWFsbHkuXG4gICAgcmV0dXJuIGdldEluc3RJZlZhbHVlQ2hhbmdlZChhY3RpdmVFbGVtZW50SW5zdCk7XG4gIH1cbn1cbi8qKlxuICogU0VDVElPTjogaGFuZGxlIGBjbGlja2AgZXZlbnRcbiAqL1xuXG5cbmZ1bmN0aW9uIHNob3VsZFVzZUNsaWNrRXZlbnQoZWxlbSkge1xuICAvLyBVc2UgdGhlIGBjbGlja2AgZXZlbnQgdG8gZGV0ZWN0IGNoYW5nZXMgdG8gY2hlY2tib3ggYW5kIHJhZGlvIGlucHV0cy5cbiAgLy8gVGhpcyBhcHByb2FjaCB3b3JrcyBhY3Jvc3MgYWxsIGJyb3dzZXJzLCB3aGVyZWFzIGBjaGFuZ2VgIGRvZXMgbm90IGZpcmVcbiAgLy8gdW50aWwgYGJsdXJgIGluIElFOC5cbiAgdmFyIG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZTtcbiAgcmV0dXJuIG5vZGVOYW1lICYmIG5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpbnB1dCcgJiYgKGVsZW0udHlwZSA9PT0gJ2NoZWNrYm94JyB8fCBlbGVtLnR5cGUgPT09ICdyYWRpbycpO1xufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9yQ2xpY2tFdmVudChkb21FdmVudE5hbWUsIHRhcmdldEluc3QpIHtcbiAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ2NsaWNrJykge1xuICAgIHJldHVybiBnZXRJbnN0SWZWYWx1ZUNoYW5nZWQodGFyZ2V0SW5zdCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VGFyZ2V0SW5zdEZvcklucHV0T3JDaGFuZ2VFdmVudChkb21FdmVudE5hbWUsIHRhcmdldEluc3QpIHtcbiAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ2lucHV0JyB8fCBkb21FdmVudE5hbWUgPT09ICdjaGFuZ2UnKSB7XG4gICAgcmV0dXJuIGdldEluc3RJZlZhbHVlQ2hhbmdlZCh0YXJnZXRJbnN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVDb250cm9sbGVkSW5wdXRCbHVyKG5vZGUpIHtcbiAgdmFyIHN0YXRlID0gbm9kZS5fd3JhcHBlclN0YXRlO1xuXG4gIGlmICghc3RhdGUgfHwgIXN0YXRlLmNvbnRyb2xsZWQgfHwgbm9kZS50eXBlICE9PSAnbnVtYmVyJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHtcbiAgICAvLyBJZiBjb250cm9sbGVkLCBhc3NpZ24gdGhlIHZhbHVlIGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudCB2YWx1ZSBvbiBibHVyXG4gICAgc2V0RGVmYXVsdFZhbHVlKG5vZGUsICdudW1iZXInLCBub2RlLnZhbHVlKTtcbiAgfVxufVxuLyoqXG4gKiBUaGlzIHBsdWdpbiBjcmVhdGVzIGFuIGBvbkNoYW5nZWAgZXZlbnQgdGhhdCBub3JtYWxpemVzIGNoYW5nZSBldmVudHNcbiAqIGFjcm9zcyBmb3JtIGVsZW1lbnRzLiBUaGlzIGV2ZW50IGZpcmVzIGF0IGEgdGltZSB3aGVuIGl0J3MgcG9zc2libGUgdG9cbiAqIGNoYW5nZSB0aGUgZWxlbWVudCdzIHZhbHVlIHdpdGhvdXQgc2VlaW5nIGEgZmxpY2tlci5cbiAqXG4gKiBTdXBwb3J0ZWQgZWxlbWVudHMgYXJlOlxuICogLSBpbnB1dCAoc2VlIGBpc1RleHRJbnB1dEVsZW1lbnRgKVxuICogLSB0ZXh0YXJlYVxuICogLSBzZWxlY3RcbiAqL1xuXG5cbmZ1bmN0aW9uIGV4dHJhY3RFdmVudHMkMShkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIHZhciB0YXJnZXROb2RlID0gdGFyZ2V0SW5zdCA/IGdldE5vZGVGcm9tSW5zdGFuY2UodGFyZ2V0SW5zdCkgOiB3aW5kb3c7XG4gIHZhciBnZXRUYXJnZXRJbnN0RnVuYywgaGFuZGxlRXZlbnRGdW5jO1xuXG4gIGlmIChzaG91bGRVc2VDaGFuZ2VFdmVudCh0YXJnZXROb2RlKSkge1xuICAgIGdldFRhcmdldEluc3RGdW5jID0gZ2V0VGFyZ2V0SW5zdEZvckNoYW5nZUV2ZW50O1xuICB9IGVsc2UgaWYgKGlzVGV4dElucHV0RWxlbWVudCh0YXJnZXROb2RlKSkge1xuICAgIGlmIChpc0lucHV0RXZlbnRTdXBwb3J0ZWQpIHtcbiAgICAgIGdldFRhcmdldEluc3RGdW5jID0gZ2V0VGFyZ2V0SW5zdEZvcklucHV0T3JDaGFuZ2VFdmVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2V0VGFyZ2V0SW5zdEZ1bmMgPSBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRFdmVudFBvbHlmaWxsO1xuICAgICAgaGFuZGxlRXZlbnRGdW5jID0gaGFuZGxlRXZlbnRzRm9ySW5wdXRFdmVudFBvbHlmaWxsO1xuICAgIH1cbiAgfSBlbHNlIGlmIChzaG91bGRVc2VDbGlja0V2ZW50KHRhcmdldE5vZGUpKSB7XG4gICAgZ2V0VGFyZ2V0SW5zdEZ1bmMgPSBnZXRUYXJnZXRJbnN0Rm9yQ2xpY2tFdmVudDtcbiAgfVxuXG4gIGlmIChnZXRUYXJnZXRJbnN0RnVuYykge1xuICAgIHZhciBpbnN0ID0gZ2V0VGFyZ2V0SW5zdEZ1bmMoZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0KTtcblxuICAgIGlmIChpbnN0KSB7XG4gICAgICBjcmVhdGVBbmRBY2N1bXVsYXRlQ2hhbmdlRXZlbnQoZGlzcGF0Y2hRdWV1ZSwgaW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAoaGFuZGxlRXZlbnRGdW5jKSB7XG4gICAgaGFuZGxlRXZlbnRGdW5jKGRvbUV2ZW50TmFtZSwgdGFyZ2V0Tm9kZSwgdGFyZ2V0SW5zdCk7XG4gIH0gLy8gV2hlbiBibHVycmluZywgc2V0IHRoZSB2YWx1ZSBhdHRyaWJ1dGUgZm9yIG51bWJlciBpbnB1dHNcblxuXG4gIGlmIChkb21FdmVudE5hbWUgPT09ICdmb2N1c291dCcpIHtcbiAgICBoYW5kbGVDb250cm9sbGVkSW5wdXRCbHVyKHRhcmdldE5vZGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyRXZlbnRzJDIoKSB7XG4gIHJlZ2lzdGVyRGlyZWN0RXZlbnQoJ29uTW91c2VFbnRlcicsIFsnbW91c2VvdXQnLCAnbW91c2VvdmVyJ10pO1xuICByZWdpc3RlckRpcmVjdEV2ZW50KCdvbk1vdXNlTGVhdmUnLCBbJ21vdXNlb3V0JywgJ21vdXNlb3ZlciddKTtcbiAgcmVnaXN0ZXJEaXJlY3RFdmVudCgnb25Qb2ludGVyRW50ZXInLCBbJ3BvaW50ZXJvdXQnLCAncG9pbnRlcm92ZXInXSk7XG4gIHJlZ2lzdGVyRGlyZWN0RXZlbnQoJ29uUG9pbnRlckxlYXZlJywgWydwb2ludGVyb3V0JywgJ3BvaW50ZXJvdmVyJ10pO1xufVxuLyoqXG4gKiBGb3IgYWxtb3N0IGV2ZXJ5IGludGVyYWN0aW9uIHdlIGNhcmUgYWJvdXQsIHRoZXJlIHdpbGwgYmUgYm90aCBhIHRvcC1sZXZlbFxuICogYG1vdXNlb3ZlcmAgYW5kIGBtb3VzZW91dGAgZXZlbnQgdGhhdCBvY2N1cnMuIE9ubHkgdXNlIGBtb3VzZW91dGAgc28gdGhhdFxuICogd2UgZG8gbm90IGV4dHJhY3QgZHVwbGljYXRlIGV2ZW50cy4gSG93ZXZlciwgbW92aW5nIHRoZSBtb3VzZSBpbnRvIHRoZVxuICogYnJvd3NlciBmcm9tIG91dHNpZGUgd2lsbCBub3QgZmlyZSBhIGBtb3VzZW91dGAgZXZlbnQuIEluIHRoaXMgY2FzZSwgd2UgdXNlXG4gKiB0aGUgYG1vdXNlb3ZlcmAgdG9wLWxldmVsIGV2ZW50LlxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyQyKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpIHtcbiAgdmFyIGlzT3ZlckV2ZW50ID0gZG9tRXZlbnROYW1lID09PSAnbW91c2VvdmVyJyB8fCBkb21FdmVudE5hbWUgPT09ICdwb2ludGVyb3Zlcic7XG4gIHZhciBpc091dEV2ZW50ID0gZG9tRXZlbnROYW1lID09PSAnbW91c2VvdXQnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3BvaW50ZXJvdXQnO1xuXG4gIGlmIChpc092ZXJFdmVudCAmJiAhaXNSZXBsYXlpbmdFdmVudChuYXRpdmVFdmVudCkpIHtcbiAgICAvLyBJZiB0aGlzIGlzIGFuIG92ZXIgZXZlbnQgd2l0aCBhIHRhcmdldCwgd2UgbWlnaHQgaGF2ZSBhbHJlYWR5IGRpc3BhdGNoZWRcbiAgICAvLyB0aGUgZXZlbnQgaW4gdGhlIG91dCBldmVudCBvZiB0aGUgb3RoZXIgdGFyZ2V0LiBJZiB0aGlzIGlzIHJlcGxheWVkLFxuICAgIC8vIHRoZW4gaXQncyBiZWNhdXNlIHdlIGNvdWxkbid0IGRpc3BhdGNoIGFnYWluc3QgdGhpcyB0YXJnZXQgcHJldmlvdXNseVxuICAgIC8vIHNvIHdlIGhhdmUgdG8gZG8gaXQgbm93IGluc3RlYWQuXG4gICAgdmFyIHJlbGF0ZWQgPSBuYXRpdmVFdmVudC5yZWxhdGVkVGFyZ2V0IHx8IG5hdGl2ZUV2ZW50LmZyb21FbGVtZW50O1xuXG4gICAgaWYgKHJlbGF0ZWQpIHtcbiAgICAgIC8vIElmIHRoZSByZWxhdGVkIG5vZGUgaXMgbWFuYWdlZCBieSBSZWFjdCwgd2UgY2FuIGFzc3VtZSB0aGF0IHdlIGhhdmVcbiAgICAgIC8vIGFscmVhZHkgZGlzcGF0Y2hlZCB0aGUgY29ycmVzcG9uZGluZyBldmVudHMgZHVyaW5nIGl0cyBtb3VzZW91dC5cbiAgICAgIGlmIChnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZShyZWxhdGVkKSB8fCBpc0NvbnRhaW5lck1hcmtlZEFzUm9vdChyZWxhdGVkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKCFpc091dEV2ZW50ICYmICFpc092ZXJFdmVudCkge1xuICAgIC8vIE11c3Qgbm90IGJlIGEgbW91c2Ugb3IgcG9pbnRlciBpbiBvciBvdXQgLSBpZ25vcmluZy5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgd2luOyAvLyBUT0RPOiB3aHkgaXMgdGhpcyBudWxsYWJsZSBpbiB0aGUgdHlwZXMgYnV0IHdlIHJlYWQgZnJvbSBpdD9cblxuICBpZiAobmF0aXZlRXZlbnRUYXJnZXQud2luZG93ID09PSBuYXRpdmVFdmVudFRhcmdldCkge1xuICAgIC8vIGBuYXRpdmVFdmVudFRhcmdldGAgaXMgcHJvYmFibHkgYSB3aW5kb3cgb2JqZWN0LlxuICAgIHdpbiA9IG5hdGl2ZUV2ZW50VGFyZ2V0O1xuICB9IGVsc2Uge1xuICAgIC8vIFRPRE86IEZpZ3VyZSBvdXQgd2h5IGBvd25lckRvY3VtZW50YCBpcyBzb21ldGltZXMgdW5kZWZpbmVkIGluIElFOC5cbiAgICB2YXIgZG9jID0gbmF0aXZlRXZlbnRUYXJnZXQub3duZXJEb2N1bWVudDtcblxuICAgIGlmIChkb2MpIHtcbiAgICAgIHdpbiA9IGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93O1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW4gPSB3aW5kb3c7XG4gICAgfVxuICB9XG5cbiAgdmFyIGZyb207XG4gIHZhciB0bztcblxuICBpZiAoaXNPdXRFdmVudCkge1xuICAgIHZhciBfcmVsYXRlZCA9IG5hdGl2ZUV2ZW50LnJlbGF0ZWRUYXJnZXQgfHwgbmF0aXZlRXZlbnQudG9FbGVtZW50O1xuXG4gICAgZnJvbSA9IHRhcmdldEluc3Q7XG4gICAgdG8gPSBfcmVsYXRlZCA/IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKF9yZWxhdGVkKSA6IG51bGw7XG5cbiAgICBpZiAodG8gIT09IG51bGwpIHtcbiAgICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIodG8pO1xuXG4gICAgICBpZiAodG8gIT09IG5lYXJlc3RNb3VudGVkIHx8IHRvLnRhZyAhPT0gSG9zdENvbXBvbmVudCAmJiB0by50YWcgIT09IEhvc3RUZXh0KSB7XG4gICAgICAgIHRvID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gTW92aW5nIHRvIGEgbm9kZSBmcm9tIG91dHNpZGUgdGhlIHdpbmRvdy5cbiAgICBmcm9tID0gbnVsbDtcbiAgICB0byA9IHRhcmdldEluc3Q7XG4gIH1cblxuICBpZiAoZnJvbSA9PT0gdG8pIHtcbiAgICAvLyBOb3RoaW5nIHBlcnRhaW5zIHRvIG91ciBtYW5hZ2VkIGNvbXBvbmVudHMuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY01vdXNlRXZlbnQ7XG4gIHZhciBsZWF2ZUV2ZW50VHlwZSA9ICdvbk1vdXNlTGVhdmUnO1xuICB2YXIgZW50ZXJFdmVudFR5cGUgPSAnb25Nb3VzZUVudGVyJztcbiAgdmFyIGV2ZW50VHlwZVByZWZpeCA9ICdtb3VzZSc7XG5cbiAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ3BvaW50ZXJvdXQnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3BvaW50ZXJvdmVyJykge1xuICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1BvaW50ZXJFdmVudDtcbiAgICBsZWF2ZUV2ZW50VHlwZSA9ICdvblBvaW50ZXJMZWF2ZSc7XG4gICAgZW50ZXJFdmVudFR5cGUgPSAnb25Qb2ludGVyRW50ZXInO1xuICAgIGV2ZW50VHlwZVByZWZpeCA9ICdwb2ludGVyJztcbiAgfVxuXG4gIHZhciBmcm9tTm9kZSA9IGZyb20gPT0gbnVsbCA/IHdpbiA6IGdldE5vZGVGcm9tSW5zdGFuY2UoZnJvbSk7XG4gIHZhciB0b05vZGUgPSB0byA9PSBudWxsID8gd2luIDogZ2V0Tm9kZUZyb21JbnN0YW5jZSh0byk7XG4gIHZhciBsZWF2ZSA9IG5ldyBTeW50aGV0aWNFdmVudEN0b3IobGVhdmVFdmVudFR5cGUsIGV2ZW50VHlwZVByZWZpeCArICdsZWF2ZScsIGZyb20sIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gIGxlYXZlLnRhcmdldCA9IGZyb21Ob2RlO1xuICBsZWF2ZS5yZWxhdGVkVGFyZ2V0ID0gdG9Ob2RlO1xuICB2YXIgZW50ZXIgPSBudWxsOyAvLyBXZSBzaG91bGQgb25seSBwcm9jZXNzIHRoaXMgbmF0aXZlRXZlbnQgaWYgd2UgYXJlIHByb2Nlc3NpbmdcbiAgLy8gdGhlIGZpcnN0IGFuY2VzdG9yLiBOZXh0IHRpbWUsIHdlIHdpbGwgaWdub3JlIHRoZSBldmVudC5cblxuICB2YXIgbmF0aXZlVGFyZ2V0SW5zdCA9IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICBpZiAobmF0aXZlVGFyZ2V0SW5zdCA9PT0gdGFyZ2V0SW5zdCkge1xuICAgIHZhciBlbnRlckV2ZW50ID0gbmV3IFN5bnRoZXRpY0V2ZW50Q3RvcihlbnRlckV2ZW50VHlwZSwgZXZlbnRUeXBlUHJlZml4ICsgJ2VudGVyJywgdG8sIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgZW50ZXJFdmVudC50YXJnZXQgPSB0b05vZGU7XG4gICAgZW50ZXJFdmVudC5yZWxhdGVkVGFyZ2V0ID0gZnJvbU5vZGU7XG4gICAgZW50ZXIgPSBlbnRlckV2ZW50O1xuICB9XG5cbiAgYWNjdW11bGF0ZUVudGVyTGVhdmVUd29QaGFzZUxpc3RlbmVycyhkaXNwYXRjaFF1ZXVlLCBsZWF2ZSwgZW50ZXIsIGZyb20sIHRvKTtcbn1cblxuLyoqXG4gKiBpbmxpbmVkIE9iamVjdC5pcyBwb2x5ZmlsbCB0byBhdm9pZCByZXF1aXJpbmcgY29uc3VtZXJzIHNoaXAgdGhlaXIgb3duXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvaXNcbiAqL1xuZnVuY3Rpb24gaXMoeCwgeSkge1xuICByZXR1cm4geCA9PT0geSAmJiAoeCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkpIHx8IHggIT09IHggJiYgeSAhPT0geSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxuICA7XG59XG5cbnZhciBvYmplY3RJcyA9IHR5cGVvZiBPYmplY3QuaXMgPT09ICdmdW5jdGlvbicgPyBPYmplY3QuaXMgOiBpcztcblxuLyoqXG4gKiBQZXJmb3JtcyBlcXVhbGl0eSBieSBpdGVyYXRpbmcgdGhyb3VnaCBrZXlzIG9uIGFuIG9iamVjdCBhbmQgcmV0dXJuaW5nIGZhbHNlXG4gKiB3aGVuIGFueSBrZXkgaGFzIHZhbHVlcyB3aGljaCBhcmUgbm90IHN0cmljdGx5IGVxdWFsIGJldHdlZW4gdGhlIGFyZ3VtZW50cy5cbiAqIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSB2YWx1ZXMgb2YgYWxsIGtleXMgYXJlIHN0cmljdGx5IGVxdWFsLlxuICovXG5cbmZ1bmN0aW9uIHNoYWxsb3dFcXVhbChvYmpBLCBvYmpCKSB7XG4gIGlmIChvYmplY3RJcyhvYmpBLCBvYmpCKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmpBICE9PSAnb2JqZWN0JyB8fCBvYmpBID09PSBudWxsIHx8IHR5cGVvZiBvYmpCICE9PSAnb2JqZWN0JyB8fCBvYmpCID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIGtleXNBID0gT2JqZWN0LmtleXMob2JqQSk7XG4gIHZhciBrZXlzQiA9IE9iamVjdC5rZXlzKG9iakIpO1xuXG4gIGlmIChrZXlzQS5sZW5ndGggIT09IGtleXNCLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSAvLyBUZXN0IGZvciBBJ3Mga2V5cyBkaWZmZXJlbnQgZnJvbSBCLlxuXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzQS5sZW5ndGg7IGkrKykge1xuICAgIHZhciBjdXJyZW50S2V5ID0ga2V5c0FbaV07XG5cbiAgICBpZiAoIWhhc093blByb3BlcnR5LmNhbGwob2JqQiwgY3VycmVudEtleSkgfHwgIW9iamVjdElzKG9iakFbY3VycmVudEtleV0sIG9iakJbY3VycmVudEtleV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogR2l2ZW4gYW55IG5vZGUgcmV0dXJuIHRoZSBmaXJzdCBsZWFmIG5vZGUgd2l0aG91dCBjaGlsZHJlbi5cbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9IG5vZGVcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9XG4gKi9cblxuZnVuY3Rpb24gZ2V0TGVhZk5vZGUobm9kZSkge1xuICB3aGlsZSAobm9kZSAmJiBub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICBub2RlID0gbm9kZS5maXJzdENoaWxkO1xuICB9XG5cbiAgcmV0dXJuIG5vZGU7XG59XG4vKipcbiAqIEdldCB0aGUgbmV4dCBzaWJsaW5nIHdpdGhpbiBhIGNvbnRhaW5lci4gVGhpcyB3aWxsIHdhbGsgdXAgdGhlXG4gKiBET00gaWYgYSBub2RlJ3Mgc2libGluZ3MgaGF2ZSBiZWVuIGV4aGF1c3RlZC5cbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9IG5vZGVcbiAqIEByZXR1cm4gez9ET01FbGVtZW50fERPTVRleHROb2RlfVxuICovXG5cblxuZnVuY3Rpb24gZ2V0U2libGluZ05vZGUobm9kZSkge1xuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChub2RlLm5leHRTaWJsaW5nKSB7XG4gICAgICByZXR1cm4gbm9kZS5uZXh0U2libGluZztcbiAgICB9XG5cbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG59XG4vKipcbiAqIEdldCBvYmplY3QgZGVzY3JpYmluZyB0aGUgbm9kZXMgd2hpY2ggY29udGFpbiBjaGFyYWN0ZXJzIGF0IG9mZnNldC5cbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9IHJvb3RcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm4gez9vYmplY3R9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0KHJvb3QsIG9mZnNldCkge1xuICB2YXIgbm9kZSA9IGdldExlYWZOb2RlKHJvb3QpO1xuICB2YXIgbm9kZVN0YXJ0ID0gMDtcbiAgdmFyIG5vZGVFbmQgPSAwO1xuXG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IFRFWFRfTk9ERSkge1xuICAgICAgbm9kZUVuZCA9IG5vZGVTdGFydCArIG5vZGUudGV4dENvbnRlbnQubGVuZ3RoO1xuXG4gICAgICBpZiAobm9kZVN0YXJ0IDw9IG9mZnNldCAmJiBub2RlRW5kID49IG9mZnNldCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5vZGU6IG5vZGUsXG4gICAgICAgICAgb2Zmc2V0OiBvZmZzZXQgLSBub2RlU3RhcnRcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgbm9kZVN0YXJ0ID0gbm9kZUVuZDtcbiAgICB9XG5cbiAgICBub2RlID0gZ2V0TGVhZk5vZGUoZ2V0U2libGluZ05vZGUobm9kZSkpO1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBvdXRlck5vZGVcbiAqIEByZXR1cm4gez9vYmplY3R9XG4gKi9cblxuZnVuY3Rpb24gZ2V0T2Zmc2V0cyhvdXRlck5vZGUpIHtcbiAgdmFyIG93bmVyRG9jdW1lbnQgPSBvdXRlck5vZGUub3duZXJEb2N1bWVudDtcbiAgdmFyIHdpbiA9IG93bmVyRG9jdW1lbnQgJiYgb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3c7XG4gIHZhciBzZWxlY3Rpb24gPSB3aW4uZ2V0U2VsZWN0aW9uICYmIHdpbi5nZXRTZWxlY3Rpb24oKTtcblxuICBpZiAoIXNlbGVjdGlvbiB8fCBzZWxlY3Rpb24ucmFuZ2VDb3VudCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGFuY2hvck5vZGUgPSBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgIGFuY2hvck9mZnNldCA9IHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICBmb2N1c05vZGUgPSBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgZm9jdXNPZmZzZXQgPSBzZWxlY3Rpb24uZm9jdXNPZmZzZXQ7IC8vIEluIEZpcmVmb3gsIGFuY2hvck5vZGUgYW5kIGZvY3VzTm9kZSBjYW4gYmUgXCJhbm9ueW1vdXMgZGl2c1wiLCBlLmcuIHRoZVxuICAvLyB1cC9kb3duIGJ1dHRvbnMgb24gYW4gPGlucHV0IHR5cGU9XCJudW1iZXJcIj4uIEFub255bW91cyBkaXZzIGRvIG5vdCBzZWVtIHRvXG4gIC8vIGV4cG9zZSBwcm9wZXJ0aWVzLCB0cmlnZ2VyaW5nIGEgXCJQZXJtaXNzaW9uIGRlbmllZCBlcnJvclwiIGlmIGFueSBvZiBpdHNcbiAgLy8gcHJvcGVydGllcyBhcmUgYWNjZXNzZWQuIFRoZSBvbmx5IHNlZW1pbmdseSBwb3NzaWJsZSB3YXkgdG8gYXZvaWQgZXJyb3JpbmdcbiAgLy8gaXMgdG8gYWNjZXNzIGEgcHJvcGVydHkgdGhhdCB0eXBpY2FsbHkgd29ya3MgZm9yIG5vbi1hbm9ueW1vdXMgZGl2cyBhbmRcbiAgLy8gY2F0Y2ggYW55IGVycm9yIHRoYXQgbWF5IG90aGVyd2lzZSBhcmlzZS4gU2VlXG4gIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTIwODQyN1xuXG4gIHRyeSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLWV4cHJlc3Npb25zICovXG4gICAgYW5jaG9yTm9kZS5ub2RlVHlwZTtcbiAgICBmb2N1c05vZGUubm9kZVR5cGU7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtZXhwcmVzc2lvbnMgKi9cbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGdldE1vZGVybk9mZnNldHNGcm9tUG9pbnRzKG91dGVyTm9kZSwgYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0LCBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0KTtcbn1cbi8qKlxuICogUmV0dXJucyB7c3RhcnQsIGVuZH0gd2hlcmUgYHN0YXJ0YCBpcyB0aGUgY2hhcmFjdGVyL2NvZGVwb2ludCBpbmRleCBvZlxuICogKGFuY2hvck5vZGUsIGFuY2hvck9mZnNldCkgd2l0aGluIHRoZSB0ZXh0Q29udGVudCBvZiBgb3V0ZXJOb2RlYCwgYW5kXG4gKiBgZW5kYCBpcyB0aGUgaW5kZXggb2YgKGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpLlxuICpcbiAqIFJldHVybnMgbnVsbCBpZiB5b3UgcGFzcyBpbiBnYXJiYWdlIGlucHV0IGJ1dCB3ZSBzaG91bGQgcHJvYmFibHkganVzdCBjcmFzaC5cbiAqXG4gKiBFeHBvcnRlZCBvbmx5IGZvciB0ZXN0aW5nLlxuICovXG5cbmZ1bmN0aW9uIGdldE1vZGVybk9mZnNldHNGcm9tUG9pbnRzKG91dGVyTm9kZSwgYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0LCBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0KSB7XG4gIHZhciBsZW5ndGggPSAwO1xuICB2YXIgc3RhcnQgPSAtMTtcbiAgdmFyIGVuZCA9IC0xO1xuICB2YXIgaW5kZXhXaXRoaW5BbmNob3IgPSAwO1xuICB2YXIgaW5kZXhXaXRoaW5Gb2N1cyA9IDA7XG4gIHZhciBub2RlID0gb3V0ZXJOb2RlO1xuICB2YXIgcGFyZW50Tm9kZSA9IG51bGw7XG5cbiAgb3V0ZXI6IHdoaWxlICh0cnVlKSB7XG4gICAgdmFyIG5leHQgPSBudWxsO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChub2RlID09PSBhbmNob3JOb2RlICYmIChhbmNob3JPZmZzZXQgPT09IDAgfHwgbm9kZS5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSkge1xuICAgICAgICBzdGFydCA9IGxlbmd0aCArIGFuY2hvck9mZnNldDtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUgPT09IGZvY3VzTm9kZSAmJiAoZm9jdXNPZmZzZXQgPT09IDAgfHwgbm9kZS5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSkge1xuICAgICAgICBlbmQgPSBsZW5ndGggKyBmb2N1c09mZnNldDtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IFRFWFRfTk9ERSkge1xuICAgICAgICBsZW5ndGggKz0gbm9kZS5ub2RlVmFsdWUubGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICBpZiAoKG5leHQgPSBub2RlLmZpcnN0Q2hpbGQpID09PSBudWxsKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSAvLyBNb3ZpbmcgZnJvbSBgbm9kZWAgdG8gaXRzIGZpcnN0IGNoaWxkIGBuZXh0YC5cblxuXG4gICAgICBwYXJlbnROb2RlID0gbm9kZTtcbiAgICAgIG5vZGUgPSBuZXh0O1xuICAgIH1cblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAobm9kZSA9PT0gb3V0ZXJOb2RlKSB7XG4gICAgICAgIC8vIElmIGBvdXRlck5vZGVgIGhhcyBjaGlsZHJlbiwgdGhpcyBpcyBhbHdheXMgdGhlIHNlY29uZCB0aW1lIHZpc2l0aW5nXG4gICAgICAgIC8vIGl0LiBJZiBpdCBoYXMgbm8gY2hpbGRyZW4sIHRoaXMgaXMgc3RpbGwgdGhlIGZpcnN0IGxvb3AsIGFuZCB0aGUgb25seVxuICAgICAgICAvLyB2YWxpZCBzZWxlY3Rpb24gaXMgYW5jaG9yTm9kZSBhbmQgZm9jdXNOb2RlIGJvdGggZXF1YWwgdG8gdGhpcyBub2RlXG4gICAgICAgIC8vIGFuZCBib3RoIG9mZnNldHMgMCwgaW4gd2hpY2ggY2FzZSB3ZSB3aWxsIGhhdmUgaGFuZGxlZCBhYm92ZS5cbiAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJlbnROb2RlID09PSBhbmNob3JOb2RlICYmICsraW5kZXhXaXRoaW5BbmNob3IgPT09IGFuY2hvck9mZnNldCkge1xuICAgICAgICBzdGFydCA9IGxlbmd0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudE5vZGUgPT09IGZvY3VzTm9kZSAmJiArK2luZGV4V2l0aGluRm9jdXMgPT09IGZvY3VzT2Zmc2V0KSB7XG4gICAgICAgIGVuZCA9IGxlbmd0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKChuZXh0ID0gbm9kZS5uZXh0U2libGluZykgIT09IG51bGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBwYXJlbnROb2RlO1xuICAgICAgcGFyZW50Tm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICB9IC8vIE1vdmluZyBmcm9tIGBub2RlYCB0byBpdHMgbmV4dCBzaWJsaW5nIGBuZXh0YC5cblxuXG4gICAgbm9kZSA9IG5leHQ7XG4gIH1cblxuICBpZiAoc3RhcnQgPT09IC0xIHx8IGVuZCA9PT0gLTEpIHtcbiAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4uIChXb3VsZCBoYXBwZW4gaWYgdGhlIGFuY2hvci9mb2N1cyBub2RlcyBhcmVuJ3RcbiAgICAvLyBhY3R1YWxseSBpbnNpZGUgdGhlIHBhc3NlZC1pbiBub2RlLilcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IHN0YXJ0LFxuICAgIGVuZDogZW5kXG4gIH07XG59XG4vKipcbiAqIEluIG1vZGVybiBub24tSUUgYnJvd3NlcnMsIHdlIGNhbiBzdXBwb3J0IGJvdGggZm9yd2FyZCBhbmQgYmFja3dhcmRcbiAqIHNlbGVjdGlvbnMuXG4gKlxuICogTm90ZTogSUUxMCsgc3VwcG9ydHMgdGhlIFNlbGVjdGlvbiBvYmplY3QsIGJ1dCBpdCBkb2VzIG5vdCBzdXBwb3J0XG4gKiB0aGUgYGV4dGVuZGAgbWV0aG9kLCB3aGljaCBtZWFucyB0aGF0IGV2ZW4gaW4gbW9kZXJuIElFLCBpdCdzIG5vdCBwb3NzaWJsZVxuICogdG8gcHJvZ3JhbW1hdGljYWxseSBjcmVhdGUgYSBiYWNrd2FyZCBzZWxlY3Rpb24uIFRodXMsIGZvciBhbGwgSUVcbiAqIHZlcnNpb25zLCB3ZSB1c2UgdGhlIG9sZCBJRSBBUEkgdG8gY3JlYXRlIG91ciBzZWxlY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHBhcmFtIHtvYmplY3R9IG9mZnNldHNcbiAqL1xuXG5mdW5jdGlvbiBzZXRPZmZzZXRzKG5vZGUsIG9mZnNldHMpIHtcbiAgdmFyIGRvYyA9IG5vZGUub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudDtcbiAgdmFyIHdpbiA9IGRvYyAmJiBkb2MuZGVmYXVsdFZpZXcgfHwgd2luZG93OyAvLyBFZGdlIGZhaWxzIHdpdGggXCJPYmplY3QgZXhwZWN0ZWRcIiBpbiBzb21lIHNjZW5hcmlvcy5cbiAgLy8gKEZvciBpbnN0YW5jZTogVGlueU1DRSBlZGl0b3IgdXNlZCBpbiBhIGxpc3QgY29tcG9uZW50IHRoYXQgc3VwcG9ydHMgcGFzdGluZyB0byBhZGQgbW9yZSxcbiAgLy8gZmFpbHMgd2hlbiBwYXN0aW5nIDEwMCsgaXRlbXMpXG5cbiAgaWYgKCF3aW4uZ2V0U2VsZWN0aW9uKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHNlbGVjdGlvbiA9IHdpbi5nZXRTZWxlY3Rpb24oKTtcbiAgdmFyIGxlbmd0aCA9IG5vZGUudGV4dENvbnRlbnQubGVuZ3RoO1xuICB2YXIgc3RhcnQgPSBNYXRoLm1pbihvZmZzZXRzLnN0YXJ0LCBsZW5ndGgpO1xuICB2YXIgZW5kID0gb2Zmc2V0cy5lbmQgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDogTWF0aC5taW4ob2Zmc2V0cy5lbmQsIGxlbmd0aCk7IC8vIElFIDExIHVzZXMgbW9kZXJuIHNlbGVjdGlvbiwgYnV0IGRvZXNuJ3Qgc3VwcG9ydCB0aGUgZXh0ZW5kIG1ldGhvZC5cbiAgLy8gRmxpcCBiYWNrd2FyZCBzZWxlY3Rpb25zLCBzbyB3ZSBjYW4gc2V0IHdpdGggYSBzaW5nbGUgcmFuZ2UuXG5cbiAgaWYgKCFzZWxlY3Rpb24uZXh0ZW5kICYmIHN0YXJ0ID4gZW5kKSB7XG4gICAgdmFyIHRlbXAgPSBlbmQ7XG4gICAgZW5kID0gc3RhcnQ7XG4gICAgc3RhcnQgPSB0ZW1wO1xuICB9XG5cbiAgdmFyIHN0YXJ0TWFya2VyID0gZ2V0Tm9kZUZvckNoYXJhY3Rlck9mZnNldChub2RlLCBzdGFydCk7XG4gIHZhciBlbmRNYXJrZXIgPSBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0KG5vZGUsIGVuZCk7XG5cbiAgaWYgKHN0YXJ0TWFya2VyICYmIGVuZE1hcmtlcikge1xuICAgIGlmIChzZWxlY3Rpb24ucmFuZ2VDb3VudCA9PT0gMSAmJiBzZWxlY3Rpb24uYW5jaG9yTm9kZSA9PT0gc3RhcnRNYXJrZXIubm9kZSAmJiBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0ID09PSBzdGFydE1hcmtlci5vZmZzZXQgJiYgc2VsZWN0aW9uLmZvY3VzTm9kZSA9PT0gZW5kTWFya2VyLm5vZGUgJiYgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0ID09PSBlbmRNYXJrZXIub2Zmc2V0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHJhbmdlID0gZG9jLmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnRNYXJrZXIubm9kZSwgc3RhcnRNYXJrZXIub2Zmc2V0KTtcbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG5cbiAgICBpZiAoc3RhcnQgPiBlbmQpIHtcbiAgICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gICAgICBzZWxlY3Rpb24uZXh0ZW5kKGVuZE1hcmtlci5ub2RlLCBlbmRNYXJrZXIub2Zmc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmFuZ2Uuc2V0RW5kKGVuZE1hcmtlci5ub2RlLCBlbmRNYXJrZXIub2Zmc2V0KTtcbiAgICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzVGV4dE5vZGUobm9kZSkge1xuICByZXR1cm4gbm9kZSAmJiBub2RlLm5vZGVUeXBlID09PSBURVhUX05PREU7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zTm9kZShvdXRlck5vZGUsIGlubmVyTm9kZSkge1xuICBpZiAoIW91dGVyTm9kZSB8fCAhaW5uZXJOb2RlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKG91dGVyTm9kZSA9PT0gaW5uZXJOb2RlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoaXNUZXh0Tm9kZShvdXRlck5vZGUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKGlzVGV4dE5vZGUoaW5uZXJOb2RlKSkge1xuICAgIHJldHVybiBjb250YWluc05vZGUob3V0ZXJOb2RlLCBpbm5lck5vZGUucGFyZW50Tm9kZSk7XG4gIH0gZWxzZSBpZiAoJ2NvbnRhaW5zJyBpbiBvdXRlck5vZGUpIHtcbiAgICByZXR1cm4gb3V0ZXJOb2RlLmNvbnRhaW5zKGlubmVyTm9kZSk7XG4gIH0gZWxzZSBpZiAob3V0ZXJOb2RlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKSB7XG4gICAgcmV0dXJuICEhKG91dGVyTm9kZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihpbm5lck5vZGUpICYgMTYpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0luRG9jdW1lbnQobm9kZSkge1xuICByZXR1cm4gbm9kZSAmJiBub2RlLm93bmVyRG9jdW1lbnQgJiYgY29udGFpbnNOb2RlKG5vZGUub3duZXJEb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIG5vZGUpO1xufVxuXG5mdW5jdGlvbiBpc1NhbWVPcmlnaW5GcmFtZShpZnJhbWUpIHtcbiAgdHJ5IHtcbiAgICAvLyBBY2Nlc3NpbmcgdGhlIGNvbnRlbnREb2N1bWVudCBvZiBhIEhUTUxJZnJhbWVFbGVtZW50IGNhbiBjYXVzZSB0aGUgYnJvd3NlclxuICAgIC8vIHRvIHRocm93LCBlLmcuIGlmIGl0IGhhcyBhIGNyb3NzLW9yaWdpbiBzcmMgYXR0cmlidXRlLlxuICAgIC8vIFNhZmFyaSB3aWxsIHNob3cgYW4gZXJyb3IgaW4gdGhlIGNvbnNvbGUgd2hlbiB0aGUgYWNjZXNzIHJlc3VsdHMgaW4gXCJCbG9ja2VkIGEgZnJhbWUgd2l0aCBvcmlnaW5cIi4gZS5nOlxuICAgIC8vIGlmcmFtZS5jb250ZW50RG9jdW1lbnQuZGVmYXVsdFZpZXc7XG4gICAgLy8gQSBzYWZldHkgd2F5IGlzIHRvIGFjY2VzcyBvbmUgb2YgdGhlIGNyb3NzIG9yaWdpbiBwcm9wZXJ0aWVzOiBXaW5kb3cgb3IgTG9jYXRpb25cbiAgICAvLyBXaGljaCBtaWdodCByZXN1bHQgaW4gXCJTZWN1cml0eUVycm9yXCIgRE9NIEV4Y2VwdGlvbiBhbmQgaXQgaXMgY29tcGF0aWJsZSB0byBTYWZhcmkuXG4gICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvYnJvd3NlcnMuaHRtbCNpbnRlZ3JhdGlvbi13aXRoLWlkbFxuICAgIHJldHVybiB0eXBlb2YgaWZyYW1lLmNvbnRlbnRXaW5kb3cubG9jYXRpb24uaHJlZiA9PT0gJ3N0cmluZyc7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRBY3RpdmVFbGVtZW50RGVlcCgpIHtcbiAgdmFyIHdpbiA9IHdpbmRvdztcbiAgdmFyIGVsZW1lbnQgPSBnZXRBY3RpdmVFbGVtZW50KCk7XG5cbiAgd2hpbGUgKGVsZW1lbnQgaW5zdGFuY2VvZiB3aW4uSFRNTElGcmFtZUVsZW1lbnQpIHtcbiAgICBpZiAoaXNTYW1lT3JpZ2luRnJhbWUoZWxlbWVudCkpIHtcbiAgICAgIHdpbiA9IGVsZW1lbnQuY29udGVudFdpbmRvdztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZWxlbWVudCA9IGdldEFjdGl2ZUVsZW1lbnQod2luLmRvY3VtZW50KTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufVxuLyoqXG4gKiBAUmVhY3RJbnB1dFNlbGVjdGlvbjogUmVhY3QgaW5wdXQgc2VsZWN0aW9uIG1vZHVsZS4gQmFzZWQgb24gU2VsZWN0aW9uLmpzLFxuICogYnV0IG1vZGlmaWVkIHRvIGJlIHN1aXRhYmxlIGZvciByZWFjdCBhbmQgaGFzIGEgY291cGxlIG9mIGJ1ZyBmaXhlcyAoZG9lc24ndFxuICogYXNzdW1lIGJ1dHRvbnMgaGF2ZSByYW5nZSBzZWxlY3Rpb25zIGFsbG93ZWQpLlxuICogSW5wdXQgc2VsZWN0aW9uIG1vZHVsZSBmb3IgUmVhY3QuXG4gKi9cblxuLyoqXG4gKiBAaGFzU2VsZWN0aW9uQ2FwYWJpbGl0aWVzOiB3ZSBnZXQgdGhlIGVsZW1lbnQgdHlwZXMgdGhhdCBzdXBwb3J0IHNlbGVjdGlvblxuICogZnJvbSBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNkby1ub3QtYXBwbHksIGxvb2tpbmcgYXQgYHNlbGVjdGlvblN0YXJ0YFxuICogYW5kIGBzZWxlY3Rpb25FbmRgIHJvd3MuXG4gKi9cblxuXG5mdW5jdGlvbiBoYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXMoZWxlbSkge1xuICB2YXIgbm9kZU5hbWUgPSBlbGVtICYmIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gbm9kZU5hbWUgJiYgKG5vZGVOYW1lID09PSAnaW5wdXQnICYmIChlbGVtLnR5cGUgPT09ICd0ZXh0JyB8fCBlbGVtLnR5cGUgPT09ICdzZWFyY2gnIHx8IGVsZW0udHlwZSA9PT0gJ3RlbCcgfHwgZWxlbS50eXBlID09PSAndXJsJyB8fCBlbGVtLnR5cGUgPT09ICdwYXNzd29yZCcpIHx8IG5vZGVOYW1lID09PSAndGV4dGFyZWEnIHx8IGVsZW0uY29udGVudEVkaXRhYmxlID09PSAndHJ1ZScpO1xufVxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uSW5mb3JtYXRpb24oKSB7XG4gIHZhciBmb2N1c2VkRWxlbSA9IGdldEFjdGl2ZUVsZW1lbnREZWVwKCk7XG4gIHJldHVybiB7XG4gICAgZm9jdXNlZEVsZW06IGZvY3VzZWRFbGVtLFxuICAgIHNlbGVjdGlvblJhbmdlOiBoYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXMoZm9jdXNlZEVsZW0pID8gZ2V0U2VsZWN0aW9uKGZvY3VzZWRFbGVtKSA6IG51bGxcbiAgfTtcbn1cbi8qKlxuICogQHJlc3RvcmVTZWxlY3Rpb246IElmIGFueSBzZWxlY3Rpb24gaW5mb3JtYXRpb24gd2FzIHBvdGVudGlhbGx5IGxvc3QsXG4gKiByZXN0b3JlIGl0LiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHBlcmZvcm1pbmcgb3BlcmF0aW9ucyB0aGF0IGNvdWxkIHJlbW92ZSBkb21cbiAqIG5vZGVzIGFuZCBwbGFjZSB0aGVtIGJhY2sgaW4sIHJlc3VsdGluZyBpbiBmb2N1cyBiZWluZyBsb3N0LlxuICovXG5cbmZ1bmN0aW9uIHJlc3RvcmVTZWxlY3Rpb24ocHJpb3JTZWxlY3Rpb25JbmZvcm1hdGlvbikge1xuICB2YXIgY3VyRm9jdXNlZEVsZW0gPSBnZXRBY3RpdmVFbGVtZW50RGVlcCgpO1xuICB2YXIgcHJpb3JGb2N1c2VkRWxlbSA9IHByaW9yU2VsZWN0aW9uSW5mb3JtYXRpb24uZm9jdXNlZEVsZW07XG4gIHZhciBwcmlvclNlbGVjdGlvblJhbmdlID0gcHJpb3JTZWxlY3Rpb25JbmZvcm1hdGlvbi5zZWxlY3Rpb25SYW5nZTtcblxuICBpZiAoY3VyRm9jdXNlZEVsZW0gIT09IHByaW9yRm9jdXNlZEVsZW0gJiYgaXNJbkRvY3VtZW50KHByaW9yRm9jdXNlZEVsZW0pKSB7XG4gICAgaWYgKHByaW9yU2VsZWN0aW9uUmFuZ2UgIT09IG51bGwgJiYgaGFzU2VsZWN0aW9uQ2FwYWJpbGl0aWVzKHByaW9yRm9jdXNlZEVsZW0pKSB7XG4gICAgICBzZXRTZWxlY3Rpb24ocHJpb3JGb2N1c2VkRWxlbSwgcHJpb3JTZWxlY3Rpb25SYW5nZSk7XG4gICAgfSAvLyBGb2N1c2luZyBhIG5vZGUgY2FuIGNoYW5nZSB0aGUgc2Nyb2xsIHBvc2l0aW9uLCB3aGljaCBpcyB1bmRlc2lyYWJsZVxuXG5cbiAgICB2YXIgYW5jZXN0b3JzID0gW107XG4gICAgdmFyIGFuY2VzdG9yID0gcHJpb3JGb2N1c2VkRWxlbTtcblxuICAgIHdoaWxlIChhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudE5vZGUpIHtcbiAgICAgIGlmIChhbmNlc3Rvci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIGFuY2VzdG9ycy5wdXNoKHtcbiAgICAgICAgICBlbGVtZW50OiBhbmNlc3RvcixcbiAgICAgICAgICBsZWZ0OiBhbmNlc3Rvci5zY3JvbGxMZWZ0LFxuICAgICAgICAgIHRvcDogYW5jZXN0b3Iuc2Nyb2xsVG9wXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcHJpb3JGb2N1c2VkRWxlbS5mb2N1cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJpb3JGb2N1c2VkRWxlbS5mb2N1cygpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYW5jZXN0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaW5mbyA9IGFuY2VzdG9yc1tpXTtcbiAgICAgIGluZm8uZWxlbWVudC5zY3JvbGxMZWZ0ID0gaW5mby5sZWZ0O1xuICAgICAgaW5mby5lbGVtZW50LnNjcm9sbFRvcCA9IGluZm8udG9wO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAZ2V0U2VsZWN0aW9uOiBHZXRzIHRoZSBzZWxlY3Rpb24gYm91bmRzIG9mIGEgZm9jdXNlZCB0ZXh0YXJlYSwgaW5wdXQgb3JcbiAqIGNvbnRlbnRFZGl0YWJsZSBub2RlLlxuICogLUBpbnB1dDogTG9vayB1cCBzZWxlY3Rpb24gYm91bmRzIG9mIHRoaXMgaW5wdXRcbiAqIC1AcmV0dXJuIHtzdGFydDogc2VsZWN0aW9uU3RhcnQsIGVuZDogc2VsZWN0aW9uRW5kfVxuICovXG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvbihpbnB1dCkge1xuICB2YXIgc2VsZWN0aW9uO1xuXG4gIGlmICgnc2VsZWN0aW9uU3RhcnQnIGluIGlucHV0KSB7XG4gICAgLy8gTW9kZXJuIGJyb3dzZXIgd2l0aCBpbnB1dCBvciB0ZXh0YXJlYS5cbiAgICBzZWxlY3Rpb24gPSB7XG4gICAgICBzdGFydDogaW5wdXQuc2VsZWN0aW9uU3RhcnQsXG4gICAgICBlbmQ6IGlucHV0LnNlbGVjdGlvbkVuZFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgLy8gQ29udGVudCBlZGl0YWJsZSBvciBvbGQgSUUgdGV4dGFyZWEuXG4gICAgc2VsZWN0aW9uID0gZ2V0T2Zmc2V0cyhpbnB1dCk7XG4gIH1cblxuICByZXR1cm4gc2VsZWN0aW9uIHx8IHtcbiAgICBzdGFydDogMCxcbiAgICBlbmQ6IDBcbiAgfTtcbn1cbi8qKlxuICogQHNldFNlbGVjdGlvbjogU2V0cyB0aGUgc2VsZWN0aW9uIGJvdW5kcyBvZiBhIHRleHRhcmVhIG9yIGlucHV0IGFuZCBmb2N1c2VzXG4gKiB0aGUgaW5wdXQuXG4gKiAtQGlucHV0ICAgICBTZXQgc2VsZWN0aW9uIGJvdW5kcyBvZiB0aGlzIGlucHV0IG9yIHRleHRhcmVhXG4gKiAtQG9mZnNldHMgICBPYmplY3Qgb2Ygc2FtZSBmb3JtIHRoYXQgaXMgcmV0dXJuZWQgZnJvbSBnZXQqXG4gKi9cblxuZnVuY3Rpb24gc2V0U2VsZWN0aW9uKGlucHV0LCBvZmZzZXRzKSB7XG4gIHZhciBzdGFydCA9IG9mZnNldHMuc3RhcnQ7XG4gIHZhciBlbmQgPSBvZmZzZXRzLmVuZDtcblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSBzdGFydDtcbiAgfVxuXG4gIGlmICgnc2VsZWN0aW9uU3RhcnQnIGluIGlucHV0KSB7XG4gICAgaW5wdXQuc2VsZWN0aW9uU3RhcnQgPSBzdGFydDtcbiAgICBpbnB1dC5zZWxlY3Rpb25FbmQgPSBNYXRoLm1pbihlbmQsIGlucHV0LnZhbHVlLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgc2V0T2Zmc2V0cyhpbnB1dCwgb2Zmc2V0cyk7XG4gIH1cbn1cblxudmFyIHNraXBTZWxlY3Rpb25DaGFuZ2VFdmVudCA9IGNhblVzZURPTSAmJiAnZG9jdW1lbnRNb2RlJyBpbiBkb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudE1vZGUgPD0gMTE7XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyRXZlbnRzJDMoKSB7XG4gIHJlZ2lzdGVyVHdvUGhhc2VFdmVudCgnb25TZWxlY3QnLCBbJ2ZvY3Vzb3V0JywgJ2NvbnRleHRtZW51JywgJ2RyYWdlbmQnLCAnZm9jdXNpbicsICdrZXlkb3duJywgJ2tleXVwJywgJ21vdXNlZG93bicsICdtb3VzZXVwJywgJ3NlbGVjdGlvbmNoYW5nZSddKTtcbn1cblxudmFyIGFjdGl2ZUVsZW1lbnQkMSA9IG51bGw7XG52YXIgYWN0aXZlRWxlbWVudEluc3QkMSA9IG51bGw7XG52YXIgbGFzdFNlbGVjdGlvbiA9IG51bGw7XG52YXIgbW91c2VEb3duID0gZmFsc2U7XG4vKipcbiAqIEdldCBhbiBvYmplY3Qgd2hpY2ggaXMgYSB1bmlxdWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgc2VsZWN0aW9uLlxuICpcbiAqIFRoZSByZXR1cm4gdmFsdWUgd2lsbCBub3QgYmUgY29uc2lzdGVudCBhY3Jvc3Mgbm9kZXMgb3IgYnJvd3NlcnMsIGJ1dFxuICogdHdvIGlkZW50aWNhbCBzZWxlY3Rpb25zIG9uIHRoZSBzYW1lIG5vZGUgd2lsbCByZXR1cm4gaWRlbnRpY2FsIG9iamVjdHMuXG4gKi9cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uJDEobm9kZSkge1xuICBpZiAoJ3NlbGVjdGlvblN0YXJ0JyBpbiBub2RlICYmIGhhc1NlbGVjdGlvbkNhcGFiaWxpdGllcyhub2RlKSkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydDogbm9kZS5zZWxlY3Rpb25TdGFydCxcbiAgICAgIGVuZDogbm9kZS5zZWxlY3Rpb25FbmRcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHZhciB3aW4gPSBub2RlLm93bmVyRG9jdW1lbnQgJiYgbm9kZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcbiAgICB2YXIgc2VsZWN0aW9uID0gd2luLmdldFNlbGVjdGlvbigpO1xuICAgIHJldHVybiB7XG4gICAgICBhbmNob3JOb2RlOiBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgIGFuY2hvck9mZnNldDogc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgIGZvY3VzTm9kZTogc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgIGZvY3VzT2Zmc2V0OiBzZWxlY3Rpb24uZm9jdXNPZmZzZXRcbiAgICB9O1xuICB9XG59XG4vKipcbiAqIEdldCBkb2N1bWVudCBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50IHRhcmdldC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEV2ZW50VGFyZ2V0RG9jdW1lbnQoZXZlbnRUYXJnZXQpIHtcbiAgcmV0dXJuIGV2ZW50VGFyZ2V0LndpbmRvdyA9PT0gZXZlbnRUYXJnZXQgPyBldmVudFRhcmdldC5kb2N1bWVudCA6IGV2ZW50VGFyZ2V0Lm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFID8gZXZlbnRUYXJnZXQgOiBldmVudFRhcmdldC5vd25lckRvY3VtZW50O1xufVxuLyoqXG4gKiBQb2xsIHNlbGVjdGlvbiB0byBzZWUgd2hldGhlciBpdCdzIGNoYW5nZWQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50XG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnRUYXJnZXRcbiAqIEByZXR1cm4gez9TeW50aGV0aWNFdmVudH1cbiAqL1xuXG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFNlbGVjdEV2ZW50KGRpc3BhdGNoUXVldWUsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAvLyBFbnN1cmUgd2UgaGF2ZSB0aGUgcmlnaHQgZWxlbWVudCwgYW5kIHRoYXQgdGhlIHVzZXIgaXMgbm90IGRyYWdnaW5nIGFcbiAgLy8gc2VsZWN0aW9uICh0aGlzIG1hdGNoZXMgbmF0aXZlIGBzZWxlY3RgIGV2ZW50IGJlaGF2aW9yKS4gSW4gSFRNTDUsIHNlbGVjdFxuICAvLyBmaXJlcyBvbmx5IG9uIGlucHV0IGFuZCB0ZXh0YXJlYSB0aHVzIGlmIHRoZXJlJ3Mgbm8gZm9jdXNlZCBlbGVtZW50IHdlXG4gIC8vIHdvbid0IGRpc3BhdGNoLlxuICB2YXIgZG9jID0gZ2V0RXZlbnRUYXJnZXREb2N1bWVudChuYXRpdmVFdmVudFRhcmdldCk7XG5cbiAgaWYgKG1vdXNlRG93biB8fCBhY3RpdmVFbGVtZW50JDEgPT0gbnVsbCB8fCBhY3RpdmVFbGVtZW50JDEgIT09IGdldEFjdGl2ZUVsZW1lbnQoZG9jKSkge1xuICAgIHJldHVybjtcbiAgfSAvLyBPbmx5IGZpcmUgd2hlbiBzZWxlY3Rpb24gaGFzIGFjdHVhbGx5IGNoYW5nZWQuXG5cblxuICB2YXIgY3VycmVudFNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbiQxKGFjdGl2ZUVsZW1lbnQkMSk7XG5cbiAgaWYgKCFsYXN0U2VsZWN0aW9uIHx8ICFzaGFsbG93RXF1YWwobGFzdFNlbGVjdGlvbiwgY3VycmVudFNlbGVjdGlvbikpIHtcbiAgICBsYXN0U2VsZWN0aW9uID0gY3VycmVudFNlbGVjdGlvbjtcbiAgICB2YXIgbGlzdGVuZXJzID0gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKGFjdGl2ZUVsZW1lbnRJbnN0JDEsICdvblNlbGVjdCcpO1xuXG4gICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgICB2YXIgZXZlbnQgPSBuZXcgU3ludGhldGljRXZlbnQoJ29uU2VsZWN0JywgJ3NlbGVjdCcsIG51bGwsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgICBkaXNwYXRjaFF1ZXVlLnB1c2goe1xuICAgICAgICBldmVudDogZXZlbnQsXG4gICAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgICB9KTtcbiAgICAgIGV2ZW50LnRhcmdldCA9IGFjdGl2ZUVsZW1lbnQkMTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogVGhpcyBwbHVnaW4gY3JlYXRlcyBhbiBgb25TZWxlY3RgIGV2ZW50IHRoYXQgbm9ybWFsaXplcyBzZWxlY3QgZXZlbnRzXG4gKiBhY3Jvc3MgZm9ybSBlbGVtZW50cy5cbiAqXG4gKiBTdXBwb3J0ZWQgZWxlbWVudHMgYXJlOlxuICogLSBpbnB1dCAoc2VlIGBpc1RleHRJbnB1dEVsZW1lbnRgKVxuICogLSB0ZXh0YXJlYVxuICogLSBjb250ZW50RWRpdGFibGVcbiAqXG4gKiBUaGlzIGRpZmZlcnMgZnJvbSBuYXRpdmUgYnJvd3NlciBpbXBsZW1lbnRhdGlvbnMgaW4gdGhlIGZvbGxvd2luZyB3YXlzOlxuICogLSBGaXJlcyBvbiBjb250ZW50RWRpdGFibGUgZmllbGRzIGFzIHdlbGwgYXMgaW5wdXRzLlxuICogLSBGaXJlcyBmb3IgY29sbGFwc2VkIHNlbGVjdGlvbi5cbiAqIC0gRmlyZXMgYWZ0ZXIgdXNlciBpbnB1dC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGV4dHJhY3RFdmVudHMkMyhkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIHZhciB0YXJnZXROb2RlID0gdGFyZ2V0SW5zdCA/IGdldE5vZGVGcm9tSW5zdGFuY2UodGFyZ2V0SW5zdCkgOiB3aW5kb3c7XG5cbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICAvLyBUcmFjayB0aGUgaW5wdXQgbm9kZSB0aGF0IGhhcyBmb2N1cy5cbiAgICBjYXNlICdmb2N1c2luJzpcbiAgICAgIGlmIChpc1RleHRJbnB1dEVsZW1lbnQodGFyZ2V0Tm9kZSkgfHwgdGFyZ2V0Tm9kZS5jb250ZW50RWRpdGFibGUgPT09ICd0cnVlJykge1xuICAgICAgICBhY3RpdmVFbGVtZW50JDEgPSB0YXJnZXROb2RlO1xuICAgICAgICBhY3RpdmVFbGVtZW50SW5zdCQxID0gdGFyZ2V0SW5zdDtcbiAgICAgICAgbGFzdFNlbGVjdGlvbiA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZm9jdXNvdXQnOlxuICAgICAgYWN0aXZlRWxlbWVudCQxID0gbnVsbDtcbiAgICAgIGFjdGl2ZUVsZW1lbnRJbnN0JDEgPSBudWxsO1xuICAgICAgbGFzdFNlbGVjdGlvbiA9IG51bGw7XG4gICAgICBicmVhaztcbiAgICAvLyBEb24ndCBmaXJlIHRoZSBldmVudCB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZy4gVGhpcyBtYXRjaGVzIHRoZVxuICAgIC8vIHNlbWFudGljcyBvZiB0aGUgbmF0aXZlIHNlbGVjdCBldmVudC5cblxuICAgIGNhc2UgJ21vdXNlZG93bic6XG4gICAgICBtb3VzZURvd24gPSB0cnVlO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdjb250ZXh0bWVudSc6XG4gICAgY2FzZSAnbW91c2V1cCc6XG4gICAgY2FzZSAnZHJhZ2VuZCc6XG4gICAgICBtb3VzZURvd24gPSBmYWxzZTtcbiAgICAgIGNvbnN0cnVjdFNlbGVjdEV2ZW50KGRpc3BhdGNoUXVldWUsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgICBicmVhaztcbiAgICAvLyBDaHJvbWUgYW5kIElFIGZpcmUgbm9uLXN0YW5kYXJkIGV2ZW50IHdoZW4gc2VsZWN0aW9uIGlzIGNoYW5nZWQgKGFuZFxuICAgIC8vIHNvbWV0aW1lcyB3aGVuIGl0IGhhc24ndCkuIElFJ3MgZXZlbnQgZmlyZXMgb3V0IG9mIG9yZGVyIHdpdGggcmVzcGVjdFxuICAgIC8vIHRvIGtleSBhbmQgaW5wdXQgZXZlbnRzIG9uIGRlbGV0aW9uLCBzbyB3ZSBkaXNjYXJkIGl0LlxuICAgIC8vXG4gICAgLy8gRmlyZWZveCBkb2Vzbid0IHN1cHBvcnQgc2VsZWN0aW9uY2hhbmdlLCBzbyBjaGVjayBzZWxlY3Rpb24gc3RhdHVzXG4gICAgLy8gYWZ0ZXIgZWFjaCBrZXkgZW50cnkuIFRoZSBzZWxlY3Rpb24gY2hhbmdlcyBhZnRlciBrZXlkb3duIGFuZCBiZWZvcmVcbiAgICAvLyBrZXl1cCwgYnV0IHdlIGNoZWNrIG9uIGtleWRvd24gYXMgd2VsbCBpbiB0aGUgY2FzZSBvZiBob2xkaW5nIGRvd24gYVxuICAgIC8vIGtleSwgd2hlbiBtdWx0aXBsZSBrZXlkb3duIGV2ZW50cyBhcmUgZmlyZWQgYnV0IG9ubHkgb25lIGtleXVwIGlzLlxuICAgIC8vIFRoaXMgaXMgYWxzbyBvdXIgYXBwcm9hY2ggZm9yIElFIGhhbmRsaW5nLCBmb3IgdGhlIHJlYXNvbiBhYm92ZS5cblxuICAgIGNhc2UgJ3NlbGVjdGlvbmNoYW5nZSc6XG4gICAgICBpZiAoc2tpcFNlbGVjdGlvbkNoYW5nZUV2ZW50KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgLy8gZmFsbHMgdGhyb3VnaFxuXG4gICAgY2FzZSAna2V5ZG93bic6XG4gICAgY2FzZSAna2V5dXAnOlxuICAgICAgY29uc3RydWN0U2VsZWN0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgfVxufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgbWFwcGluZyBvZiBzdGFuZGFyZCB2ZW5kb3IgcHJlZml4ZXMgdXNpbmcgdGhlIGRlZmluZWQgc3R5bGUgcHJvcGVydHkgYW5kIGV2ZW50IG5hbWUuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0eWxlUHJvcFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHJldHVybnMge29iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBtYWtlUHJlZml4TWFwKHN0eWxlUHJvcCwgZXZlbnROYW1lKSB7XG4gIHZhciBwcmVmaXhlcyA9IHt9O1xuICBwcmVmaXhlc1tzdHlsZVByb3AudG9Mb3dlckNhc2UoKV0gPSBldmVudE5hbWUudG9Mb3dlckNhc2UoKTtcbiAgcHJlZml4ZXNbJ1dlYmtpdCcgKyBzdHlsZVByb3BdID0gJ3dlYmtpdCcgKyBldmVudE5hbWU7XG4gIHByZWZpeGVzWydNb3onICsgc3R5bGVQcm9wXSA9ICdtb3onICsgZXZlbnROYW1lO1xuICByZXR1cm4gcHJlZml4ZXM7XG59XG4vKipcbiAqIEEgbGlzdCBvZiBldmVudCBuYW1lcyB0byBhIGNvbmZpZ3VyYWJsZSBsaXN0IG9mIHZlbmRvciBwcmVmaXhlcy5cbiAqL1xuXG5cbnZhciB2ZW5kb3JQcmVmaXhlcyA9IHtcbiAgYW5pbWF0aW9uZW5kOiBtYWtlUHJlZml4TWFwKCdBbmltYXRpb24nLCAnQW5pbWF0aW9uRW5kJyksXG4gIGFuaW1hdGlvbml0ZXJhdGlvbjogbWFrZVByZWZpeE1hcCgnQW5pbWF0aW9uJywgJ0FuaW1hdGlvbkl0ZXJhdGlvbicpLFxuICBhbmltYXRpb25zdGFydDogbWFrZVByZWZpeE1hcCgnQW5pbWF0aW9uJywgJ0FuaW1hdGlvblN0YXJ0JyksXG4gIHRyYW5zaXRpb25lbmQ6IG1ha2VQcmVmaXhNYXAoJ1RyYW5zaXRpb24nLCAnVHJhbnNpdGlvbkVuZCcpXG59O1xuLyoqXG4gKiBFdmVudCBuYW1lcyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIGRldGVjdGVkIGFuZCBwcmVmaXhlZCAoaWYgYXBwbGljYWJsZSkuXG4gKi9cblxudmFyIHByZWZpeGVkRXZlbnROYW1lcyA9IHt9O1xuLyoqXG4gKiBFbGVtZW50IHRvIGNoZWNrIGZvciBwcmVmaXhlcyBvbi5cbiAqL1xuXG52YXIgc3R5bGUgPSB7fTtcbi8qKlxuICogQm9vdHN0cmFwIGlmIGEgRE9NIGV4aXN0cy5cbiAqL1xuXG5pZiAoY2FuVXNlRE9NKSB7XG4gIHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jykuc3R5bGU7IC8vIE9uIHNvbWUgcGxhdGZvcm1zLCBpbiBwYXJ0aWN1bGFyIHNvbWUgcmVsZWFzZXMgb2YgQW5kcm9pZCA0LngsXG4gIC8vIHRoZSB1bi1wcmVmaXhlZCBcImFuaW1hdGlvblwiIGFuZCBcInRyYW5zaXRpb25cIiBwcm9wZXJ0aWVzIGFyZSBkZWZpbmVkIG9uIHRoZVxuICAvLyBzdHlsZSBvYmplY3QgYnV0IHRoZSBldmVudHMgdGhhdCBmaXJlIHdpbGwgc3RpbGwgYmUgcHJlZml4ZWQsIHNvIHdlIG5lZWRcbiAgLy8gdG8gY2hlY2sgaWYgdGhlIHVuLXByZWZpeGVkIGV2ZW50cyBhcmUgdXNhYmxlLCBhbmQgaWYgbm90IHJlbW92ZSB0aGVtIGZyb20gdGhlIG1hcC5cblxuICBpZiAoISgnQW5pbWF0aW9uRXZlbnQnIGluIHdpbmRvdykpIHtcbiAgICBkZWxldGUgdmVuZG9yUHJlZml4ZXMuYW5pbWF0aW9uZW5kLmFuaW1hdGlvbjtcbiAgICBkZWxldGUgdmVuZG9yUHJlZml4ZXMuYW5pbWF0aW9uaXRlcmF0aW9uLmFuaW1hdGlvbjtcbiAgICBkZWxldGUgdmVuZG9yUHJlZml4ZXMuYW5pbWF0aW9uc3RhcnQuYW5pbWF0aW9uO1xuICB9IC8vIFNhbWUgYXMgYWJvdmVcblxuXG4gIGlmICghKCdUcmFuc2l0aW9uRXZlbnQnIGluIHdpbmRvdykpIHtcbiAgICBkZWxldGUgdmVuZG9yUHJlZml4ZXMudHJhbnNpdGlvbmVuZC50cmFuc2l0aW9uO1xuICB9XG59XG4vKipcbiAqIEF0dGVtcHRzIHRvIGRldGVybWluZSB0aGUgY29ycmVjdCB2ZW5kb3IgcHJlZml4ZWQgZXZlbnQgbmFtZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5cblxuZnVuY3Rpb24gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoZXZlbnROYW1lKSB7XG4gIGlmIChwcmVmaXhlZEV2ZW50TmFtZXNbZXZlbnROYW1lXSkge1xuICAgIHJldHVybiBwcmVmaXhlZEV2ZW50TmFtZXNbZXZlbnROYW1lXTtcbiAgfSBlbHNlIGlmICghdmVuZG9yUHJlZml4ZXNbZXZlbnROYW1lXSkge1xuICAgIHJldHVybiBldmVudE5hbWU7XG4gIH1cblxuICB2YXIgcHJlZml4TWFwID0gdmVuZG9yUHJlZml4ZXNbZXZlbnROYW1lXTtcblxuICBmb3IgKHZhciBzdHlsZVByb3AgaW4gcHJlZml4TWFwKSB7XG4gICAgaWYgKHByZWZpeE1hcC5oYXNPd25Qcm9wZXJ0eShzdHlsZVByb3ApICYmIHN0eWxlUHJvcCBpbiBzdHlsZSkge1xuICAgICAgcmV0dXJuIHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdID0gcHJlZml4TWFwW3N0eWxlUHJvcF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGV2ZW50TmFtZTtcbn1cblxudmFyIEFOSU1BVElPTl9FTkQgPSBnZXRWZW5kb3JQcmVmaXhlZEV2ZW50TmFtZSgnYW5pbWF0aW9uZW5kJyk7XG52YXIgQU5JTUFUSU9OX0lURVJBVElPTiA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCdhbmltYXRpb25pdGVyYXRpb24nKTtcbnZhciBBTklNQVRJT05fU1RBUlQgPSBnZXRWZW5kb3JQcmVmaXhlZEV2ZW50TmFtZSgnYW5pbWF0aW9uc3RhcnQnKTtcbnZhciBUUkFOU0lUSU9OX0VORCA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCd0cmFuc2l0aW9uZW5kJyk7XG5cbnZhciB0b3BMZXZlbEV2ZW50c1RvUmVhY3ROYW1lcyA9IG5ldyBNYXAoKTsgLy8gTk9URTogQ2FwaXRhbGl6YXRpb24gaXMgaW1wb3J0YW50IGluIHRoaXMgbGlzdCFcbi8vXG4vLyBFLmcuIGl0IG5lZWRzIFwicG9pbnRlckRvd25cIiwgbm90IFwicG9pbnRlcmRvd25cIi5cbi8vIFRoaXMgaXMgYmVjYXVzZSB3ZSBkZXJpdmUgYm90aCBSZWFjdCBuYW1lIChcIm9uUG9pbnRlckRvd25cIilcbi8vIGFuZCBET00gbmFtZSAoXCJwb2ludGVyZG93blwiKSBmcm9tIHRoZSBzYW1lIGxpc3QuXG4vL1xuLy8gRXhjZXB0aW9ucyB0aGF0IGRvbid0IG1hdGNoIHRoaXMgY29udmVudGlvbiBhcmUgbGlzdGVkIHNlcGFyYXRlbHkuXG4vL1xuLy8gcHJldHRpZXItaWdub3JlXG5cbnZhciBzaW1wbGVFdmVudFBsdWdpbkV2ZW50cyA9IFsnYWJvcnQnLCAnYXV4Q2xpY2snLCAnY2FuY2VsJywgJ2NhblBsYXknLCAnY2FuUGxheVRocm91Z2gnLCAnY2xpY2snLCAnY2xvc2UnLCAnY29udGV4dE1lbnUnLCAnY29weScsICdjdXQnLCAnZHJhZycsICdkcmFnRW5kJywgJ2RyYWdFbnRlcicsICdkcmFnRXhpdCcsICdkcmFnTGVhdmUnLCAnZHJhZ092ZXInLCAnZHJhZ1N0YXJ0JywgJ2Ryb3AnLCAnZHVyYXRpb25DaGFuZ2UnLCAnZW1wdGllZCcsICdlbmNyeXB0ZWQnLCAnZW5kZWQnLCAnZXJyb3InLCAnZ290UG9pbnRlckNhcHR1cmUnLCAnaW5wdXQnLCAnaW52YWxpZCcsICdrZXlEb3duJywgJ2tleVByZXNzJywgJ2tleVVwJywgJ2xvYWQnLCAnbG9hZGVkRGF0YScsICdsb2FkZWRNZXRhZGF0YScsICdsb2FkU3RhcnQnLCAnbG9zdFBvaW50ZXJDYXB0dXJlJywgJ21vdXNlRG93bicsICdtb3VzZU1vdmUnLCAnbW91c2VPdXQnLCAnbW91c2VPdmVyJywgJ21vdXNlVXAnLCAncGFzdGUnLCAncGF1c2UnLCAncGxheScsICdwbGF5aW5nJywgJ3BvaW50ZXJDYW5jZWwnLCAncG9pbnRlckRvd24nLCAncG9pbnRlck1vdmUnLCAncG9pbnRlck91dCcsICdwb2ludGVyT3ZlcicsICdwb2ludGVyVXAnLCAncHJvZ3Jlc3MnLCAncmF0ZUNoYW5nZScsICdyZXNldCcsICdyZXNpemUnLCAnc2Vla2VkJywgJ3NlZWtpbmcnLCAnc3RhbGxlZCcsICdzdWJtaXQnLCAnc3VzcGVuZCcsICd0aW1lVXBkYXRlJywgJ3RvdWNoQ2FuY2VsJywgJ3RvdWNoRW5kJywgJ3RvdWNoU3RhcnQnLCAndm9sdW1lQ2hhbmdlJywgJ3Njcm9sbCcsICd0b2dnbGUnLCAndG91Y2hNb3ZlJywgJ3dhaXRpbmcnLCAnd2hlZWwnXTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJTaW1wbGVFdmVudChkb21FdmVudE5hbWUsIHJlYWN0TmFtZSkge1xuICB0b3BMZXZlbEV2ZW50c1RvUmVhY3ROYW1lcy5zZXQoZG9tRXZlbnROYW1lLCByZWFjdE5hbWUpO1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQocmVhY3ROYW1lLCBbZG9tRXZlbnROYW1lXSk7XG59XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyU2ltcGxlRXZlbnRzKCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpbXBsZUV2ZW50UGx1Z2luRXZlbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGV2ZW50TmFtZSA9IHNpbXBsZUV2ZW50UGx1Z2luRXZlbnRzW2ldO1xuICAgIHZhciBkb21FdmVudE5hbWUgPSBldmVudE5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgY2FwaXRhbGl6ZWRFdmVudCA9IGV2ZW50TmFtZVswXS50b1VwcGVyQ2FzZSgpICsgZXZlbnROYW1lLnNsaWNlKDEpO1xuICAgIHJlZ2lzdGVyU2ltcGxlRXZlbnQoZG9tRXZlbnROYW1lLCAnb24nICsgY2FwaXRhbGl6ZWRFdmVudCk7XG4gIH0gLy8gU3BlY2lhbCBjYXNlcyB3aGVyZSBldmVudCBuYW1lcyBkb24ndCBtYXRjaC5cblxuXG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoQU5JTUFUSU9OX0VORCwgJ29uQW5pbWF0aW9uRW5kJyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoQU5JTUFUSU9OX0lURVJBVElPTiwgJ29uQW5pbWF0aW9uSXRlcmF0aW9uJyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoQU5JTUFUSU9OX1NUQVJULCAnb25BbmltYXRpb25TdGFydCcpO1xuICByZWdpc3RlclNpbXBsZUV2ZW50KCdkYmxjbGljaycsICdvbkRvdWJsZUNsaWNrJyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoJ2ZvY3VzaW4nLCAnb25Gb2N1cycpO1xuICByZWdpc3RlclNpbXBsZUV2ZW50KCdmb2N1c291dCcsICdvbkJsdXInKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChUUkFOU0lUSU9OX0VORCwgJ29uVHJhbnNpdGlvbkVuZCcpO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RXZlbnRzJDQoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lcikge1xuICB2YXIgcmVhY3ROYW1lID0gdG9wTGV2ZWxFdmVudHNUb1JlYWN0TmFtZXMuZ2V0KGRvbUV2ZW50TmFtZSk7XG5cbiAgaWYgKHJlYWN0TmFtZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0V2ZW50O1xuICB2YXIgcmVhY3RFdmVudFR5cGUgPSBkb21FdmVudE5hbWU7XG5cbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICBjYXNlICdrZXlwcmVzcyc6XG4gICAgICAvLyBGaXJlZm94IGNyZWF0ZXMgYSBrZXlwcmVzcyBldmVudCBmb3IgZnVuY3Rpb24ga2V5cyB0b28uIFRoaXMgcmVtb3Zlc1xuICAgICAgLy8gdGhlIHVud2FudGVkIGtleXByZXNzIGV2ZW50cy4gRW50ZXIgaXMgaG93ZXZlciBib3RoIHByaW50YWJsZSBhbmRcbiAgICAgIC8vIG5vbi1wcmludGFibGUuIE9uZSB3b3VsZCBleHBlY3QgVGFiIHRvIGJlIGFzIHdlbGwgKGJ1dCBpdCBpc24ndCkuXG4gICAgICBpZiAoZ2V0RXZlbnRDaGFyQ29kZShuYXRpdmVFdmVudCkgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuXG4gICAgY2FzZSAna2V5ZG93bic6XG4gICAgY2FzZSAna2V5dXAnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljS2V5Ym9hcmRFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZm9jdXNpbic6XG4gICAgICByZWFjdEV2ZW50VHlwZSA9ICdmb2N1cyc7XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNGb2N1c0V2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdmb2N1c291dCc6XG4gICAgICByZWFjdEV2ZW50VHlwZSA9ICdibHVyJztcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0ZvY3VzRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2JlZm9yZWJsdXInOlxuICAgIGNhc2UgJ2FmdGVyYmx1cic6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNGb2N1c0V2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdjbGljayc6XG4gICAgICAvLyBGaXJlZm94IGNyZWF0ZXMgYSBjbGljayBldmVudCBvbiByaWdodCBtb3VzZSBjbGlja3MuIFRoaXMgcmVtb3ZlcyB0aGVcbiAgICAgIC8vIHVud2FudGVkIGNsaWNrIGV2ZW50cy5cbiAgICAgIGlmIChuYXRpdmVFdmVudC5idXR0b24gPT09IDIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuXG4gICAgY2FzZSAnYXV4Y2xpY2snOlxuICAgIGNhc2UgJ2RibGNsaWNrJzpcbiAgICBjYXNlICdtb3VzZWRvd24nOlxuICAgIGNhc2UgJ21vdXNlbW92ZSc6XG4gICAgY2FzZSAnbW91c2V1cCc6IC8vIFRPRE86IERpc2FibGVkIGVsZW1lbnRzIHNob3VsZCBub3QgcmVzcG9uZCB0byBtb3VzZSBldmVudHNcblxuICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cblxuICAgIGNhc2UgJ21vdXNlb3V0JzpcbiAgICBjYXNlICdtb3VzZW92ZXInOlxuICAgIGNhc2UgJ2NvbnRleHRtZW51JzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY01vdXNlRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2RyYWcnOlxuICAgIGNhc2UgJ2RyYWdlbmQnOlxuICAgIGNhc2UgJ2RyYWdlbnRlcic6XG4gICAgY2FzZSAnZHJhZ2V4aXQnOlxuICAgIGNhc2UgJ2RyYWdsZWF2ZSc6XG4gICAgY2FzZSAnZHJhZ292ZXInOlxuICAgIGNhc2UgJ2RyYWdzdGFydCc6XG4gICAgY2FzZSAnZHJvcCc6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNEcmFnRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3RvdWNoY2FuY2VsJzpcbiAgICBjYXNlICd0b3VjaGVuZCc6XG4gICAgY2FzZSAndG91Y2htb3ZlJzpcbiAgICBjYXNlICd0b3VjaHN0YXJ0JzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1RvdWNoRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgQU5JTUFUSU9OX0VORDpcbiAgICBjYXNlIEFOSU1BVElPTl9JVEVSQVRJT046XG4gICAgY2FzZSBBTklNQVRJT05fU1RBUlQ6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNBbmltYXRpb25FdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBUUkFOU0lUSU9OX0VORDpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1RyYW5zaXRpb25FdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnc2Nyb2xsJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1VJRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3doZWVsJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1doZWVsRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2NvcHknOlxuICAgIGNhc2UgJ2N1dCc6XG4gICAgY2FzZSAncGFzdGUnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljQ2xpcGJvYXJkRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2dvdHBvaW50ZXJjYXB0dXJlJzpcbiAgICBjYXNlICdsb3N0cG9pbnRlcmNhcHR1cmUnOlxuICAgIGNhc2UgJ3BvaW50ZXJjYW5jZWwnOlxuICAgIGNhc2UgJ3BvaW50ZXJkb3duJzpcbiAgICBjYXNlICdwb2ludGVybW92ZSc6XG4gICAgY2FzZSAncG9pbnRlcm91dCc6XG4gICAgY2FzZSAncG9pbnRlcm92ZXInOlxuICAgIGNhc2UgJ3BvaW50ZXJ1cCc6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNQb2ludGVyRXZlbnQ7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHZhciBpbkNhcHR1cmVQaGFzZSA9IChldmVudFN5c3RlbUZsYWdzICYgSVNfQ0FQVFVSRV9QSEFTRSkgIT09IDA7XG5cbiAge1xuICAgIC8vIFNvbWUgZXZlbnRzIGRvbid0IGJ1YmJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgICAvLyBJbiB0aGUgcGFzdCwgUmVhY3QgaGFzIGFsd2F5cyBidWJibGVkIHRoZW0sIGJ1dCB0aGlzIGNhbiBiZSBzdXJwcmlzaW5nLlxuICAgIC8vIFdlJ3JlIGdvaW5nIHRvIHRyeSBhbGlnbmluZyBjbG9zZXIgdG8gdGhlIGJyb3dzZXIgYmVoYXZpb3IgYnkgbm90IGJ1YmJsaW5nXG4gICAgLy8gdGhlbSBpbiBSZWFjdCBlaXRoZXIuIFdlJ2xsIHN0YXJ0IGJ5IG5vdCBidWJibGluZyBvblNjcm9sbCwgYW5kIHRoZW4gZXhwYW5kLlxuICAgIHZhciBhY2N1bXVsYXRlVGFyZ2V0T25seSA9ICFpbkNhcHR1cmVQaGFzZSAmJiAvLyBUT0RPOiBpZGVhbGx5LCB3ZSdkIGV2ZW50dWFsbHkgYWRkIGFsbCBldmVudHMgZnJvbVxuICAgIC8vIG5vbkRlbGVnYXRlZEV2ZW50cyBsaXN0IGluIERPTVBsdWdpbkV2ZW50U3lzdGVtLlxuICAgIC8vIFRoZW4gd2UgY2FuIHJlbW92ZSB0aGlzIHNwZWNpYWwgbGlzdC5cbiAgICAvLyBUaGlzIGlzIGEgYnJlYWtpbmcgY2hhbmdlIHRoYXQgY2FuIHdhaXQgdW50aWwgUmVhY3QgMTguXG4gICAgZG9tRXZlbnROYW1lID09PSAnc2Nyb2xsJztcblxuICAgIHZhciBfbGlzdGVuZXJzID0gYWNjdW11bGF0ZVNpbmdsZVBoYXNlTGlzdGVuZXJzKHRhcmdldEluc3QsIHJlYWN0TmFtZSwgbmF0aXZlRXZlbnQudHlwZSwgaW5DYXB0dXJlUGhhc2UsIGFjY3VtdWxhdGVUYXJnZXRPbmx5KTtcblxuICAgIGlmIChfbGlzdGVuZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIEludGVudGlvbmFsbHkgY3JlYXRlIGV2ZW50IGxhemlseS5cbiAgICAgIHZhciBfZXZlbnQgPSBuZXcgU3ludGhldGljRXZlbnRDdG9yKHJlYWN0TmFtZSwgcmVhY3RFdmVudFR5cGUsIG51bGwsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG5cbiAgICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICAgIGV2ZW50OiBfZXZlbnQsXG4gICAgICAgIGxpc3RlbmVyczogX2xpc3RlbmVyc1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8vIFRPRE86IHJlbW92ZSB0b3AtbGV2ZWwgc2lkZSBlZmZlY3QuXG5yZWdpc3RlclNpbXBsZUV2ZW50cygpO1xucmVnaXN0ZXJFdmVudHMkMigpO1xucmVnaXN0ZXJFdmVudHMkMSgpO1xucmVnaXN0ZXJFdmVudHMkMygpO1xucmVnaXN0ZXJFdmVudHMoKTtcblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyQ1KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpIHtcbiAgLy8gVE9ETzogd2Ugc2hvdWxkIHJlbW92ZSB0aGUgY29uY2VwdCBvZiBhIFwiU2ltcGxlRXZlbnRQbHVnaW5cIi5cbiAgLy8gVGhpcyBpcyB0aGUgYmFzaWMgZnVuY3Rpb25hbGl0eSBvZiB0aGUgZXZlbnQgc3lzdGVtLiBBbGxcbiAgLy8gdGhlIG90aGVyIHBsdWdpbnMgYXJlIGVzc2VudGlhbGx5IHBvbHlmaWxscy4gU28gdGhlIHBsdWdpblxuICAvLyBzaG91bGQgcHJvYmFibHkgYmUgaW5saW5lZCBzb21ld2hlcmUgYW5kIGhhdmUgaXRzIGxvZ2ljXG4gIC8vIGJlIGNvcmUgdGhlIHRvIGV2ZW50IHN5c3RlbS4gVGhpcyB3b3VsZCBwb3RlbnRpYWxseSBhbGxvd1xuICAvLyB1cyB0byBzaGlwIGJ1aWxkcyBvZiBSZWFjdCB3aXRob3V0IHRoZSBwb2x5ZmlsbGVkIHBsdWdpbnMgYmVsb3cuXG4gIGV4dHJhY3RFdmVudHMkNChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncyk7XG4gIHZhciBzaG91bGRQcm9jZXNzUG9seWZpbGxQbHVnaW5zID0gKGV2ZW50U3lzdGVtRmxhZ3MgJiBTSE9VTERfTk9UX1BST0NFU1NfUE9MWUZJTExfRVZFTlRfUExVR0lOUykgPT09IDA7IC8vIFdlIGRvbid0IHByb2Nlc3MgdGhlc2UgZXZlbnRzIHVubGVzcyB3ZSBhcmUgaW4gdGhlXG4gIC8vIGV2ZW50J3MgbmF0aXZlIFwiYnViYmxlXCIgcGhhc2UsIHdoaWNoIG1lYW5zIHRoYXQgd2UncmVcbiAgLy8gbm90IGluIHRoZSBjYXB0dXJlIHBoYXNlLiBUaGF0J3MgYmVjYXVzZSB3ZSBlbXVsYXRlXG4gIC8vIHRoZSBjYXB0dXJlIHBoYXNlIGhlcmUgc3RpbGwuIFRoaXMgaXMgYSB0cmFkZS1vZmYsXG4gIC8vIGJlY2F1c2UgaW4gYW4gaWRlYWwgd29ybGQgd2Ugd291bGQgbm90IGVtdWxhdGUgYW5kIHVzZVxuICAvLyB0aGUgcGhhc2VzIHByb3Blcmx5LCBsaWtlIHdlIGRvIHdpdGggdGhlIFNpbXBsZUV2ZW50XG4gIC8vIHBsdWdpbi4gSG93ZXZlciwgdGhlIHBsdWdpbnMgYmVsb3cgZWl0aGVyIGV4cGVjdFxuICAvLyBlbXVsYXRpb24gKEVudGVyTGVhdmUpIG9yIHVzZSBzdGF0ZSBsb2NhbGl6ZWQgdG8gdGhhdFxuICAvLyBwbHVnaW4gKEJlZm9yZUlucHV0LCBDaGFuZ2UsIFNlbGVjdCkuIFRoZSBzdGF0ZSBpblxuICAvLyB0aGVzZSBtb2R1bGVzIGNvbXBsaWNhdGVzIHRoaW5ncywgYXMgeW91J2xsIGVzc2VudGlhbGx5XG4gIC8vIGdldCB0aGUgY2FzZSB3aGVyZSB0aGUgY2FwdHVyZSBwaGFzZSBldmVudCBtaWdodCBjaGFuZ2VcbiAgLy8gc3RhdGUsIG9ubHkgZm9yIHRoZSBmb2xsb3dpbmcgYnViYmxlIGV2ZW50IHRvIGNvbWUgaW5cbiAgLy8gbGF0ZXIgYW5kIG5vdCB0cmlnZ2VyIGFueXRoaW5nIGFzIHRoZSBzdGF0ZSBub3dcbiAgLy8gaW52YWxpZGF0ZXMgdGhlIGhldXJpc3RpY3Mgb2YgdGhlIGV2ZW50IHBsdWdpbi4gV2VcbiAgLy8gY291bGQgYWx0ZXIgYWxsIHRoZXNlIHBsdWdpbnMgdG8gd29yayBpbiBzdWNoIHdheXMsIGJ1dFxuICAvLyB0aGF0IG1pZ2h0IGNhdXNlIG90aGVyIHVua25vd24gc2lkZS1lZmZlY3RzIHRoYXQgd2VcbiAgLy8gY2FuJ3QgZm9yZXNlZSByaWdodCBub3cuXG5cbiAgaWYgKHNob3VsZFByb2Nlc3NQb2x5ZmlsbFBsdWdpbnMpIHtcbiAgICBleHRyYWN0RXZlbnRzJDIoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIGV4dHJhY3RFdmVudHMkMShkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgZXh0cmFjdEV2ZW50cyQzKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBleHRyYWN0RXZlbnRzKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgfVxufSAvLyBMaXN0IG9mIGV2ZW50cyB0aGF0IG5lZWQgdG8gYmUgaW5kaXZpZHVhbGx5IGF0dGFjaGVkIHRvIG1lZGlhIGVsZW1lbnRzLlxuXG5cbnZhciBtZWRpYUV2ZW50VHlwZXMgPSBbJ2Fib3J0JywgJ2NhbnBsYXknLCAnY2FucGxheXRocm91Z2gnLCAnZHVyYXRpb25jaGFuZ2UnLCAnZW1wdGllZCcsICdlbmNyeXB0ZWQnLCAnZW5kZWQnLCAnZXJyb3InLCAnbG9hZGVkZGF0YScsICdsb2FkZWRtZXRhZGF0YScsICdsb2Fkc3RhcnQnLCAncGF1c2UnLCAncGxheScsICdwbGF5aW5nJywgJ3Byb2dyZXNzJywgJ3JhdGVjaGFuZ2UnLCAncmVzaXplJywgJ3NlZWtlZCcsICdzZWVraW5nJywgJ3N0YWxsZWQnLCAnc3VzcGVuZCcsICd0aW1ldXBkYXRlJywgJ3ZvbHVtZWNoYW5nZScsICd3YWl0aW5nJ107IC8vIFdlIHNob3VsZCBub3QgZGVsZWdhdGUgdGhlc2UgZXZlbnRzIHRvIHRoZSBjb250YWluZXIsIGJ1dCByYXRoZXJcbi8vIHNldCB0aGVtIG9uIHRoZSBhY3R1YWwgdGFyZ2V0IGVsZW1lbnQgaXRzZWxmLiBUaGlzIGlzIHByaW1hcmlseVxuLy8gYmVjYXVzZSB0aGVzZSBldmVudHMgZG8gbm90IGNvbnNpc3RlbnRseSBidWJibGUgaW4gdGhlIERPTS5cblxudmFyIG5vbkRlbGVnYXRlZEV2ZW50cyA9IG5ldyBTZXQoWydjYW5jZWwnLCAnY2xvc2UnLCAnaW52YWxpZCcsICdsb2FkJywgJ3Njcm9sbCcsICd0b2dnbGUnXS5jb25jYXQobWVkaWFFdmVudFR5cGVzKSk7XG5cbmZ1bmN0aW9uIGV4ZWN1dGVEaXNwYXRjaChldmVudCwgbGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpIHtcbiAgdmFyIHR5cGUgPSBldmVudC50eXBlIHx8ICd1bmtub3duLWV2ZW50JztcbiAgZXZlbnQuY3VycmVudFRhcmdldCA9IGN1cnJlbnRUYXJnZXQ7XG4gIGludm9rZUd1YXJkZWRDYWxsYmFja0FuZENhdGNoRmlyc3RFcnJvcih0eXBlLCBsaXN0ZW5lciwgdW5kZWZpbmVkLCBldmVudCk7XG4gIGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzRGlzcGF0Y2hRdWV1ZUl0ZW1zSW5PcmRlcihldmVudCwgZGlzcGF0Y2hMaXN0ZW5lcnMsIGluQ2FwdHVyZVBoYXNlKSB7XG4gIHZhciBwcmV2aW91c0luc3RhbmNlO1xuXG4gIGlmIChpbkNhcHR1cmVQaGFzZSkge1xuICAgIGZvciAodmFyIGkgPSBkaXNwYXRjaExpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIF9kaXNwYXRjaExpc3RlbmVycyRpID0gZGlzcGF0Y2hMaXN0ZW5lcnNbaV0sXG4gICAgICAgICAgaW5zdGFuY2UgPSBfZGlzcGF0Y2hMaXN0ZW5lcnMkaS5pbnN0YW5jZSxcbiAgICAgICAgICBjdXJyZW50VGFyZ2V0ID0gX2Rpc3BhdGNoTGlzdGVuZXJzJGkuY3VycmVudFRhcmdldCxcbiAgICAgICAgICBsaXN0ZW5lciA9IF9kaXNwYXRjaExpc3RlbmVycyRpLmxpc3RlbmVyO1xuXG4gICAgICBpZiAoaW5zdGFuY2UgIT09IHByZXZpb3VzSW5zdGFuY2UgJiYgZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGV4ZWN1dGVEaXNwYXRjaChldmVudCwgbGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpO1xuICAgICAgcHJldmlvdXNJbnN0YW5jZSA9IGluc3RhbmNlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgZGlzcGF0Y2hMaXN0ZW5lcnMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgX2Rpc3BhdGNoTGlzdGVuZXJzJF9pID0gZGlzcGF0Y2hMaXN0ZW5lcnNbX2ldLFxuICAgICAgICAgIF9pbnN0YW5jZSA9IF9kaXNwYXRjaExpc3RlbmVycyRfaS5pbnN0YW5jZSxcbiAgICAgICAgICBfY3VycmVudFRhcmdldCA9IF9kaXNwYXRjaExpc3RlbmVycyRfaS5jdXJyZW50VGFyZ2V0LFxuICAgICAgICAgIF9saXN0ZW5lciA9IF9kaXNwYXRjaExpc3RlbmVycyRfaS5saXN0ZW5lcjtcblxuICAgICAgaWYgKF9pbnN0YW5jZSAhPT0gcHJldmlvdXNJbnN0YW5jZSAmJiBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBfbGlzdGVuZXIsIF9jdXJyZW50VGFyZ2V0KTtcbiAgICAgIHByZXZpb3VzSW5zdGFuY2UgPSBfaW5zdGFuY2U7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NEaXNwYXRjaFF1ZXVlKGRpc3BhdGNoUXVldWUsIGV2ZW50U3lzdGVtRmxhZ3MpIHtcbiAgdmFyIGluQ2FwdHVyZVBoYXNlID0gKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19DQVBUVVJFX1BIQVNFKSAhPT0gMDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRpc3BhdGNoUXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgX2Rpc3BhdGNoUXVldWUkaSA9IGRpc3BhdGNoUXVldWVbaV0sXG4gICAgICAgIGV2ZW50ID0gX2Rpc3BhdGNoUXVldWUkaS5ldmVudCxcbiAgICAgICAgbGlzdGVuZXJzID0gX2Rpc3BhdGNoUXVldWUkaS5saXN0ZW5lcnM7XG4gICAgcHJvY2Vzc0Rpc3BhdGNoUXVldWVJdGVtc0luT3JkZXIoZXZlbnQsIGxpc3RlbmVycywgaW5DYXB0dXJlUGhhc2UpOyAvLyAgZXZlbnQgc3lzdGVtIGRvZXNuJ3QgdXNlIHBvb2xpbmcuXG4gIH0gLy8gVGhpcyB3b3VsZCBiZSBhIGdvb2QgdGltZSB0byByZXRocm93IGlmIGFueSBvZiB0aGUgZXZlbnQgaGFuZGxlcnMgdGhyZXcuXG5cblxuICByZXRocm93Q2F1Z2h0RXJyb3IoKTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudHNGb3JQbHVnaW5zKGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgbmF0aXZlRXZlbnQsIHRhcmdldEluc3QsIHRhcmdldENvbnRhaW5lcikge1xuICB2YXIgbmF0aXZlRXZlbnRUYXJnZXQgPSBnZXRFdmVudFRhcmdldChuYXRpdmVFdmVudCk7XG4gIHZhciBkaXNwYXRjaFF1ZXVlID0gW107XG4gIGV4dHJhY3RFdmVudHMkNShkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncyk7XG4gIHByb2Nlc3NEaXNwYXRjaFF1ZXVlKGRpc3BhdGNoUXVldWUsIGV2ZW50U3lzdGVtRmxhZ3MpO1xufVxuXG5mdW5jdGlvbiBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KGRvbUV2ZW50TmFtZSwgdGFyZ2V0RWxlbWVudCkge1xuICB7XG4gICAgaWYgKCFub25EZWxlZ2F0ZWRFdmVudHMuaGFzKGRvbUV2ZW50TmFtZSkpIHtcbiAgICAgIGVycm9yKCdEaWQgbm90IGV4cGVjdCBhIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoKSBjYWxsIGZvciBcIiVzXCIuICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZG9tRXZlbnROYW1lKTtcbiAgICB9XG4gIH1cblxuICB2YXIgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lciA9IGZhbHNlO1xuICB2YXIgbGlzdGVuZXJTZXQgPSBnZXRFdmVudExpc3RlbmVyU2V0KHRhcmdldEVsZW1lbnQpO1xuICB2YXIgbGlzdGVuZXJTZXRLZXkgPSBnZXRMaXN0ZW5lclNldEtleShkb21FdmVudE5hbWUsIGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIpO1xuXG4gIGlmICghbGlzdGVuZXJTZXQuaGFzKGxpc3RlbmVyU2V0S2V5KSkge1xuICAgIGFkZFRyYXBwZWRFdmVudExpc3RlbmVyKHRhcmdldEVsZW1lbnQsIGRvbUV2ZW50TmFtZSwgSVNfTk9OX0RFTEVHQVRFRCwgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcik7XG4gICAgbGlzdGVuZXJTZXQuYWRkKGxpc3RlbmVyU2V0S2V5KTtcbiAgfVxufVxuZnVuY3Rpb24gbGlzdGVuVG9OYXRpdmVFdmVudChkb21FdmVudE5hbWUsIGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIsIHRhcmdldCkge1xuICB7XG4gICAgaWYgKG5vbkRlbGVnYXRlZEV2ZW50cy5oYXMoZG9tRXZlbnROYW1lKSAmJiAhaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcikge1xuICAgICAgZXJyb3IoJ0RpZCBub3QgZXhwZWN0IGEgbGlzdGVuVG9OYXRpdmVFdmVudCgpIGNhbGwgZm9yIFwiJXNcIiBpbiB0aGUgYnViYmxlIHBoYXNlLiAnICsgJ1RoaXMgaXMgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGRvbUV2ZW50TmFtZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGV2ZW50U3lzdGVtRmxhZ3MgPSAwO1xuXG4gIGlmIChpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKSB7XG4gICAgZXZlbnRTeXN0ZW1GbGFncyB8PSBJU19DQVBUVVJFX1BIQVNFO1xuICB9XG5cbiAgYWRkVHJhcHBlZEV2ZW50TGlzdGVuZXIodGFyZ2V0LCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIpO1xufSAvLyBUaGlzIGlzIG9ubHkgdXNlZCBieSBjcmVhdGVFdmVudEhhbmRsZSB3aGVuIHRoZVxudmFyIGxpc3RlbmluZ01hcmtlciA9ICdfcmVhY3RMaXN0ZW5pbmcnICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG5mdW5jdGlvbiBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhyb290Q29udGFpbmVyRWxlbWVudCkge1xuICBpZiAoIXJvb3RDb250YWluZXJFbGVtZW50W2xpc3RlbmluZ01hcmtlcl0pIHtcbiAgICByb290Q29udGFpbmVyRWxlbWVudFtsaXN0ZW5pbmdNYXJrZXJdID0gdHJ1ZTtcbiAgICBhbGxOYXRpdmVFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZG9tRXZlbnROYW1lKSB7XG4gICAgICAvLyBXZSBoYW5kbGUgc2VsZWN0aW9uY2hhbmdlIHNlcGFyYXRlbHkgYmVjYXVzZSBpdFxuICAgICAgLy8gZG9lc24ndCBidWJibGUgYW5kIG5lZWRzIHRvIGJlIG9uIHRoZSBkb2N1bWVudC5cbiAgICAgIGlmIChkb21FdmVudE5hbWUgIT09ICdzZWxlY3Rpb25jaGFuZ2UnKSB7XG4gICAgICAgIGlmICghbm9uRGVsZWdhdGVkRXZlbnRzLmhhcyhkb21FdmVudE5hbWUpKSB7XG4gICAgICAgICAgbGlzdGVuVG9OYXRpdmVFdmVudChkb21FdmVudE5hbWUsIGZhbHNlLCByb290Q29udGFpbmVyRWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBsaXN0ZW5Ub05hdGl2ZUV2ZW50KGRvbUV2ZW50TmFtZSwgdHJ1ZSwgcm9vdENvbnRhaW5lckVsZW1lbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gcm9vdENvbnRhaW5lckVsZW1lbnQubm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUgPyByb290Q29udGFpbmVyRWxlbWVudCA6IHJvb3RDb250YWluZXJFbGVtZW50Lm93bmVyRG9jdW1lbnQ7XG5cbiAgICBpZiAob3duZXJEb2N1bWVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhlIHNlbGVjdGlvbmNoYW5nZSBldmVudCBhbHNvIG5lZWRzIGRlZHVwbGljYXRpb25cbiAgICAgIC8vIGJ1dCBpdCBpcyBhdHRhY2hlZCB0byB0aGUgZG9jdW1lbnQuXG4gICAgICBpZiAoIW93bmVyRG9jdW1lbnRbbGlzdGVuaW5nTWFya2VyXSkge1xuICAgICAgICBvd25lckRvY3VtZW50W2xpc3RlbmluZ01hcmtlcl0gPSB0cnVlO1xuICAgICAgICBsaXN0ZW5Ub05hdGl2ZUV2ZW50KCdzZWxlY3Rpb25jaGFuZ2UnLCBmYWxzZSwgb3duZXJEb2N1bWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkZFRyYXBwZWRFdmVudExpc3RlbmVyKHRhcmdldENvbnRhaW5lciwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBpc0NhcHR1cmVQaGFzZUxpc3RlbmVyLCBpc0RlZmVycmVkTGlzdGVuZXJGb3JMZWdhY3lGQlN1cHBvcnQpIHtcbiAgdmFyIGxpc3RlbmVyID0gY3JlYXRlRXZlbnRMaXN0ZW5lcldyYXBwZXJXaXRoUHJpb3JpdHkodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MpOyAvLyBJZiBwYXNzaXZlIG9wdGlvbiBpcyBub3Qgc3VwcG9ydGVkLCB0aGVuIHRoZSBldmVudCB3aWxsIGJlXG4gIC8vIGFjdGl2ZSBhbmQgbm90IHBhc3NpdmUuXG5cbiAgdmFyIGlzUGFzc2l2ZUxpc3RlbmVyID0gdW5kZWZpbmVkO1xuXG4gIGlmIChwYXNzaXZlQnJvd3NlckV2ZW50c1N1cHBvcnRlZCkge1xuICAgIC8vIEJyb3dzZXJzIGludHJvZHVjZWQgYW4gaW50ZXJ2ZW50aW9uLCBtYWtpbmcgdGhlc2UgZXZlbnRzXG4gICAgLy8gcGFzc2l2ZSBieSBkZWZhdWx0IG9uIGRvY3VtZW50LiBSZWFjdCBkb2Vzbid0IGJpbmQgdGhlbVxuICAgIC8vIHRvIGRvY3VtZW50IGFueW1vcmUsIGJ1dCBjaGFuZ2luZyB0aGlzIG5vdyB3b3VsZCB1bmRvXG4gICAgLy8gdGhlIHBlcmZvcm1hbmNlIHdpbnMgZnJvbSB0aGUgY2hhbmdlLiBTbyB3ZSBlbXVsYXRlXG4gICAgLy8gdGhlIGV4aXN0aW5nIGJlaGF2aW9yIG1hbnVhbGx5IG9uIHRoZSByb290cyBub3cuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xOTY1MVxuICAgIGlmIChkb21FdmVudE5hbWUgPT09ICd0b3VjaHN0YXJ0JyB8fCBkb21FdmVudE5hbWUgPT09ICd0b3VjaG1vdmUnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3doZWVsJykge1xuICAgICAgaXNQYXNzaXZlTGlzdGVuZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRhcmdldENvbnRhaW5lciA9ICB0YXJnZXRDb250YWluZXI7XG4gIHZhciB1bnN1YnNjcmliZUxpc3RlbmVyOyAvLyBXaGVuIGxlZ2FjeUZCU3VwcG9ydCBpcyBlbmFibGVkLCBpdCdzIGZvciB3aGVuIHdlXG5cblxuICBpZiAoaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcikge1xuICAgIGlmIChpc1Bhc3NpdmVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB1bnN1YnNjcmliZUxpc3RlbmVyID0gYWRkRXZlbnRDYXB0dXJlTGlzdGVuZXJXaXRoUGFzc2l2ZUZsYWcodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGxpc3RlbmVyLCBpc1Bhc3NpdmVMaXN0ZW5lcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuc3Vic2NyaWJlTGlzdGVuZXIgPSBhZGRFdmVudENhcHR1cmVMaXN0ZW5lcih0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoaXNQYXNzaXZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdW5zdWJzY3JpYmVMaXN0ZW5lciA9IGFkZEV2ZW50QnViYmxlTGlzdGVuZXJXaXRoUGFzc2l2ZUZsYWcodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGxpc3RlbmVyLCBpc1Bhc3NpdmVMaXN0ZW5lcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuc3Vic2NyaWJlTGlzdGVuZXIgPSBhZGRFdmVudEJ1YmJsZUxpc3RlbmVyKHRhcmdldENvbnRhaW5lciwgZG9tRXZlbnROYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzTWF0Y2hpbmdSb290Q29udGFpbmVyKGdyYW5kQ29udGFpbmVyLCB0YXJnZXRDb250YWluZXIpIHtcbiAgcmV0dXJuIGdyYW5kQ29udGFpbmVyID09PSB0YXJnZXRDb250YWluZXIgfHwgZ3JhbmRDb250YWluZXIubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSAmJiBncmFuZENvbnRhaW5lci5wYXJlbnROb2RlID09PSB0YXJnZXRDb250YWluZXI7XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoRXZlbnRGb3JQbHVnaW5FdmVudFN5c3RlbShkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCB0YXJnZXRJbnN0LCB0YXJnZXRDb250YWluZXIpIHtcbiAgdmFyIGFuY2VzdG9ySW5zdCA9IHRhcmdldEluc3Q7XG5cbiAgaWYgKChldmVudFN5c3RlbUZsYWdzICYgSVNfRVZFTlRfSEFORExFX05PTl9NQU5BR0VEX05PREUpID09PSAwICYmIChldmVudFN5c3RlbUZsYWdzICYgSVNfTk9OX0RFTEVHQVRFRCkgPT09IDApIHtcbiAgICB2YXIgdGFyZ2V0Q29udGFpbmVyTm9kZSA9IHRhcmdldENvbnRhaW5lcjsgLy8gSWYgd2UgYXJlIHVzaW5nIHRoZSBsZWdhY3kgRkIgc3VwcG9ydCBmbGFnLCB3ZVxuXG4gICAgaWYgKHRhcmdldEluc3QgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoZSBiZWxvdyBsb2dpYyBhdHRlbXB0cyB0byB3b3JrIG91dCBpZiB3ZSBuZWVkIHRvIGNoYW5nZVxuICAgICAgLy8gdGhlIHRhcmdldCBmaWJlciB0byBhIGRpZmZlcmVudCBhbmNlc3Rvci4gV2UgaGFkIHNpbWlsYXIgbG9naWNcbiAgICAgIC8vIGluIHRoZSBsZWdhY3kgZXZlbnQgc3lzdGVtLCBleGNlcHQgdGhlIGJpZyBkaWZmZXJlbmNlIGJldHdlZW5cbiAgICAgIC8vIHN5c3RlbXMgaXMgdGhhdCB0aGUgbW9kZXJuIGV2ZW50IHN5c3RlbSBub3cgaGFzIGFuIGV2ZW50IGxpc3RlbmVyXG4gICAgICAvLyBhdHRhY2hlZCB0byBlYWNoIFJlYWN0IFJvb3QgYW5kIFJlYWN0IFBvcnRhbCBSb290LiBUb2dldGhlcixcbiAgICAgIC8vIHRoZSBET00gbm9kZXMgcmVwcmVzZW50aW5nIHRoZXNlIHJvb3RzIGFyZSB0aGUgXCJyb290Q29udGFpbmVyXCIuXG4gICAgICAvLyBUbyBmaWd1cmUgb3V0IHdoaWNoIGFuY2VzdG9yIGluc3RhbmNlIHdlIHNob3VsZCB1c2UsIHdlIHRyYXZlcnNlXG4gICAgICAvLyB1cCB0aGUgZmliZXIgdHJlZSBmcm9tIHRoZSB0YXJnZXQgaW5zdGFuY2UgYW5kIGF0dGVtcHQgdG8gZmluZFxuICAgICAgLy8gcm9vdCBib3VuZGFyaWVzIHRoYXQgbWF0Y2ggdGhhdCBvZiBvdXIgY3VycmVudCBcInJvb3RDb250YWluZXJcIi5cbiAgICAgIC8vIElmIHdlIGZpbmQgdGhhdCBcInJvb3RDb250YWluZXJcIiwgd2UgZmluZCB0aGUgcGFyZW50IGZpYmVyXG4gICAgICAvLyBzdWItdHJlZSBmb3IgdGhhdCByb290IGFuZCBtYWtlIHRoYXQgb3VyIGFuY2VzdG9yIGluc3RhbmNlLlxuICAgICAgdmFyIG5vZGUgPSB0YXJnZXRJbnN0O1xuXG4gICAgICBtYWluTG9vcDogd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKG5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbm9kZVRhZyA9IG5vZGUudGFnO1xuXG4gICAgICAgIGlmIChub2RlVGFnID09PSBIb3N0Um9vdCB8fCBub2RlVGFnID09PSBIb3N0UG9ydGFsKSB7XG4gICAgICAgICAgdmFyIGNvbnRhaW5lciA9IG5vZGUuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG5cbiAgICAgICAgICBpZiAoaXNNYXRjaGluZ1Jvb3RDb250YWluZXIoY29udGFpbmVyLCB0YXJnZXRDb250YWluZXJOb2RlKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5vZGVUYWcgPT09IEhvc3RQb3J0YWwpIHtcbiAgICAgICAgICAgIC8vIFRoZSB0YXJnZXQgaXMgYSBwb3J0YWwsIGJ1dCBpdCdzIG5vdCB0aGUgcm9vdENvbnRhaW5lciB3ZSdyZSBsb29raW5nIGZvci5cbiAgICAgICAgICAgIC8vIE5vcm1hbGx5IHBvcnRhbHMgaGFuZGxlIHRoZWlyIG93biBldmVudHMgYWxsIHRoZSB3YXkgZG93biB0byB0aGUgcm9vdC5cbiAgICAgICAgICAgIC8vIFNvIHdlIHNob3VsZCBiZSBhYmxlIHRvIHN0b3Agbm93LiBIb3dldmVyLCB3ZSBkb24ndCBrbm93IGlmIHRoaXMgcG9ydGFsXG4gICAgICAgICAgICAvLyB3YXMgcGFydCBvZiAqb3VyKiByb290LlxuICAgICAgICAgICAgdmFyIGdyYW5kTm9kZSA9IG5vZGUucmV0dXJuO1xuXG4gICAgICAgICAgICB3aGlsZSAoZ3JhbmROb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHZhciBncmFuZFRhZyA9IGdyYW5kTm9kZS50YWc7XG5cbiAgICAgICAgICAgICAgaWYgKGdyYW5kVGFnID09PSBIb3N0Um9vdCB8fCBncmFuZFRhZyA9PT0gSG9zdFBvcnRhbCkge1xuICAgICAgICAgICAgICAgIHZhciBncmFuZENvbnRhaW5lciA9IGdyYW5kTm9kZS5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcblxuICAgICAgICAgICAgICAgIGlmIChpc01hdGNoaW5nUm9vdENvbnRhaW5lcihncmFuZENvbnRhaW5lciwgdGFyZ2V0Q29udGFpbmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIHJvb3RDb250YWluZXIgd2UncmUgbG9va2luZyBmb3IgYW5kIHdlIGZvdW5kIGl0IGFzXG4gICAgICAgICAgICAgICAgICAvLyBhIHBhcmVudCBvZiB0aGUgUG9ydGFsLiBUaGF0IG1lYW5zIHdlIGNhbiBpZ25vcmUgaXQgYmVjYXVzZSB0aGVcbiAgICAgICAgICAgICAgICAgIC8vIFBvcnRhbCB3aWxsIGJ1YmJsZSB0aHJvdWdoIHRvIHVzLlxuICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGdyYW5kTm9kZSA9IGdyYW5kTm9kZS5yZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSAvLyBOb3cgd2UgbmVlZCB0byBmaW5kIGl0J3MgY29ycmVzcG9uZGluZyBob3N0IGZpYmVyIGluIHRoZSBvdGhlclxuICAgICAgICAgIC8vIHRyZWUuIFRvIGRvIHRoaXMgd2UgY2FuIHVzZSBnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZSwgYnV0IHdlXG4gICAgICAgICAgLy8gbmVlZCB0byB2YWxpZGF0ZSB0aGF0IHRoZSBmaWJlciBpcyBhIGhvc3QgaW5zdGFuY2UsIG90aGVyd2lzZVxuICAgICAgICAgIC8vIHdlIG5lZWQgdG8gdHJhdmVyc2UgdXAgdGhyb3VnaCB0aGUgRE9NIHRpbGwgd2UgZmluZCB0aGUgY29ycmVjdFxuICAgICAgICAgIC8vIG5vZGUgdGhhdCBpcyBmcm9tIHRoZSBvdGhlciB0cmVlLlxuXG5cbiAgICAgICAgICB3aGlsZSAoY29udGFpbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKGNvbnRhaW5lcik7XG5cbiAgICAgICAgICAgIGlmIChwYXJlbnROb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHBhcmVudFRhZyA9IHBhcmVudE5vZGUudGFnO1xuXG4gICAgICAgICAgICBpZiAocGFyZW50VGFnID09PSBIb3N0Q29tcG9uZW50IHx8IHBhcmVudFRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICAgICAgICAgICAgbm9kZSA9IGFuY2VzdG9ySW5zdCA9IHBhcmVudE5vZGU7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG1haW5Mb29wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb250YWluZXIgPSBjb250YWluZXIucGFyZW50Tm9kZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYmF0Y2hlZFVwZGF0ZXMoZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBkaXNwYXRjaEV2ZW50c0ZvclBsdWdpbnMoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgYW5jZXN0b3JJbnN0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGxpc3RlbmVyLCBjdXJyZW50VGFyZ2V0KSB7XG4gIHJldHVybiB7XG4gICAgaW5zdGFuY2U6IGluc3RhbmNlLFxuICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICBjdXJyZW50VGFyZ2V0OiBjdXJyZW50VGFyZ2V0XG4gIH07XG59XG5cbmZ1bmN0aW9uIGFjY3VtdWxhdGVTaW5nbGVQaGFzZUxpc3RlbmVycyh0YXJnZXRGaWJlciwgcmVhY3ROYW1lLCBuYXRpdmVFdmVudFR5cGUsIGluQ2FwdHVyZVBoYXNlLCBhY2N1bXVsYXRlVGFyZ2V0T25seSwgbmF0aXZlRXZlbnQpIHtcbiAgdmFyIGNhcHR1cmVOYW1lID0gcmVhY3ROYW1lICE9PSBudWxsID8gcmVhY3ROYW1lICsgJ0NhcHR1cmUnIDogbnVsbDtcbiAgdmFyIHJlYWN0RXZlbnROYW1lID0gaW5DYXB0dXJlUGhhc2UgPyBjYXB0dXJlTmFtZSA6IHJlYWN0TmFtZTtcbiAgdmFyIGxpc3RlbmVycyA9IFtdO1xuICB2YXIgaW5zdGFuY2UgPSB0YXJnZXRGaWJlcjtcbiAgdmFyIGxhc3RIb3N0Q29tcG9uZW50ID0gbnVsbDsgLy8gQWNjdW11bGF0ZSBhbGwgaW5zdGFuY2VzIGFuZCBsaXN0ZW5lcnMgdmlhIHRoZSB0YXJnZXQgLT4gcm9vdCBwYXRoLlxuXG4gIHdoaWxlIChpbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgIHZhciBfaW5zdGFuY2UyID0gaW5zdGFuY2UsXG4gICAgICAgIHN0YXRlTm9kZSA9IF9pbnN0YW5jZTIuc3RhdGVOb2RlLFxuICAgICAgICB0YWcgPSBfaW5zdGFuY2UyLnRhZzsgLy8gSGFuZGxlIGxpc3RlbmVycyB0aGF0IGFyZSBvbiBIb3N0Q29tcG9uZW50cyAoaS5lLiA8ZGl2PilcblxuICAgIGlmICh0YWcgPT09IEhvc3RDb21wb25lbnQgJiYgc3RhdGVOb2RlICE9PSBudWxsKSB7XG4gICAgICBsYXN0SG9zdENvbXBvbmVudCA9IHN0YXRlTm9kZTsgLy8gY3JlYXRlRXZlbnRIYW5kbGUgbGlzdGVuZXJzXG5cblxuICAgICAgaWYgKHJlYWN0RXZlbnROYW1lICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lciA9IGdldExpc3RlbmVyKGluc3RhbmNlLCByZWFjdEV2ZW50TmFtZSk7XG5cbiAgICAgICAgaWYgKGxpc3RlbmVyICE9IG51bGwpIHtcbiAgICAgICAgICBsaXN0ZW5lcnMucHVzaChjcmVhdGVEaXNwYXRjaExpc3RlbmVyKGluc3RhbmNlLCBsaXN0ZW5lciwgbGFzdEhvc3RDb21wb25lbnQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gSWYgd2UgYXJlIG9ubHkgYWNjdW11bGF0aW5nIGV2ZW50cyBmb3IgdGhlIHRhcmdldCwgdGhlbiB3ZSBkb24ndFxuICAgIC8vIGNvbnRpbnVlIHRvIHByb3BhZ2F0ZSB0aHJvdWdoIHRoZSBSZWFjdCBmaWJlciB0cmVlIHRvIGZpbmQgb3RoZXJcbiAgICAvLyBsaXN0ZW5lcnMuXG5cblxuICAgIGlmIChhY2N1bXVsYXRlVGFyZ2V0T25seSkge1xuICAgICAgYnJlYWs7XG4gICAgfSAvLyBJZiB3ZSBhcmUgcHJvY2Vzc2luZyB0aGUgb25CZWZvcmVCbHVyIGV2ZW50LCB0aGVuIHdlIG5lZWQgdG8gdGFrZVxuXG4gICAgaW5zdGFuY2UgPSBpbnN0YW5jZS5yZXR1cm47XG4gIH1cblxuICByZXR1cm4gbGlzdGVuZXJzO1xufSAvLyBXZSBzaG91bGQgb25seSB1c2UgdGhpcyBmdW5jdGlvbiBmb3I6XG4vLyAtIEJlZm9yZUlucHV0RXZlbnRQbHVnaW5cbi8vIC0gQ2hhbmdlRXZlbnRQbHVnaW5cbi8vIC0gU2VsZWN0RXZlbnRQbHVnaW5cbi8vIFRoaXMgaXMgYmVjYXVzZSB3ZSBvbmx5IHByb2Nlc3MgdGhlc2UgcGx1Z2luc1xuLy8gaW4gdGhlIGJ1YmJsZSBwaGFzZSwgc28gd2UgbmVlZCB0byBhY2N1bXVsYXRlIHR3b1xuLy8gcGhhc2UgZXZlbnQgbGlzdGVuZXJzICh2aWEgZW11bGF0aW9uKS5cblxuZnVuY3Rpb24gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKHRhcmdldEZpYmVyLCByZWFjdE5hbWUpIHtcbiAgdmFyIGNhcHR1cmVOYW1lID0gcmVhY3ROYW1lICsgJ0NhcHR1cmUnO1xuICB2YXIgbGlzdGVuZXJzID0gW107XG4gIHZhciBpbnN0YW5jZSA9IHRhcmdldEZpYmVyOyAvLyBBY2N1bXVsYXRlIGFsbCBpbnN0YW5jZXMgYW5kIGxpc3RlbmVycyB2aWEgdGhlIHRhcmdldCAtPiByb290IHBhdGguXG5cbiAgd2hpbGUgKGluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgdmFyIF9pbnN0YW5jZTMgPSBpbnN0YW5jZSxcbiAgICAgICAgc3RhdGVOb2RlID0gX2luc3RhbmNlMy5zdGF0ZU5vZGUsXG4gICAgICAgIHRhZyA9IF9pbnN0YW5jZTMudGFnOyAvLyBIYW5kbGUgbGlzdGVuZXJzIHRoYXQgYXJlIG9uIEhvc3RDb21wb25lbnRzIChpLmUuIDxkaXY+KVxuXG4gICAgaWYgKHRhZyA9PT0gSG9zdENvbXBvbmVudCAmJiBzdGF0ZU5vZGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBjdXJyZW50VGFyZ2V0ID0gc3RhdGVOb2RlO1xuICAgICAgdmFyIGNhcHR1cmVMaXN0ZW5lciA9IGdldExpc3RlbmVyKGluc3RhbmNlLCBjYXB0dXJlTmFtZSk7XG5cbiAgICAgIGlmIChjYXB0dXJlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICBsaXN0ZW5lcnMudW5zaGlmdChjcmVhdGVEaXNwYXRjaExpc3RlbmVyKGluc3RhbmNlLCBjYXB0dXJlTGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGJ1YmJsZUxpc3RlbmVyID0gZ2V0TGlzdGVuZXIoaW5zdGFuY2UsIHJlYWN0TmFtZSk7XG5cbiAgICAgIGlmIChidWJibGVMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgIGxpc3RlbmVycy5wdXNoKGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGJ1YmJsZUxpc3RlbmVyLCBjdXJyZW50VGFyZ2V0KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaW5zdGFuY2UgPSBpbnN0YW5jZS5yZXR1cm47XG4gIH1cblxuICByZXR1cm4gbGlzdGVuZXJzO1xufVxuXG5mdW5jdGlvbiBnZXRQYXJlbnQoaW5zdCkge1xuICBpZiAoaW5zdCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZG8ge1xuICAgIGluc3QgPSBpbnN0LnJldHVybjsgLy8gVE9ETzogSWYgdGhpcyBpcyBhIEhvc3RSb290IHdlIG1pZ2h0IHdhbnQgdG8gYmFpbCBvdXQuXG4gICAgLy8gVGhhdCBpcyBkZXBlbmRpbmcgb24gaWYgd2Ugd2FudCBuZXN0ZWQgc3VidHJlZXMgKGxheWVycykgdG8gYnViYmxlXG4gICAgLy8gZXZlbnRzIHRvIHRoZWlyIHBhcmVudC4gV2UgY291bGQgYWxzbyBnbyB0aHJvdWdoIHBhcmVudE5vZGUgb24gdGhlXG4gICAgLy8gaG9zdCBub2RlIGJ1dCB0aGF0IHdvdWxkbid0IHdvcmsgZm9yIFJlYWN0IE5hdGl2ZSBhbmQgZG9lc24ndCBsZXQgdXNcbiAgICAvLyBkbyB0aGUgcG9ydGFsIGZlYXR1cmUuXG4gIH0gd2hpbGUgKGluc3QgJiYgaW5zdC50YWcgIT09IEhvc3RDb21wb25lbnQpO1xuXG4gIGlmIChpbnN0KSB7XG4gICAgcmV0dXJuIGluc3Q7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogUmV0dXJuIHRoZSBsb3dlc3QgY29tbW9uIGFuY2VzdG9yIG9mIEEgYW5kIEIsIG9yIG51bGwgaWYgdGhleSBhcmUgaW5cbiAqIGRpZmZlcmVudCB0cmVlcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldExvd2VzdENvbW1vbkFuY2VzdG9yKGluc3RBLCBpbnN0Qikge1xuICB2YXIgbm9kZUEgPSBpbnN0QTtcbiAgdmFyIG5vZGVCID0gaW5zdEI7XG4gIHZhciBkZXB0aEEgPSAwO1xuXG4gIGZvciAodmFyIHRlbXBBID0gbm9kZUE7IHRlbXBBOyB0ZW1wQSA9IGdldFBhcmVudCh0ZW1wQSkpIHtcbiAgICBkZXB0aEErKztcbiAgfVxuXG4gIHZhciBkZXB0aEIgPSAwO1xuXG4gIGZvciAodmFyIHRlbXBCID0gbm9kZUI7IHRlbXBCOyB0ZW1wQiA9IGdldFBhcmVudCh0ZW1wQikpIHtcbiAgICBkZXB0aEIrKztcbiAgfSAvLyBJZiBBIGlzIGRlZXBlciwgY3Jhd2wgdXAuXG5cblxuICB3aGlsZSAoZGVwdGhBIC0gZGVwdGhCID4gMCkge1xuICAgIG5vZGVBID0gZ2V0UGFyZW50KG5vZGVBKTtcbiAgICBkZXB0aEEtLTtcbiAgfSAvLyBJZiBCIGlzIGRlZXBlciwgY3Jhd2wgdXAuXG5cblxuICB3aGlsZSAoZGVwdGhCIC0gZGVwdGhBID4gMCkge1xuICAgIG5vZGVCID0gZ2V0UGFyZW50KG5vZGVCKTtcbiAgICBkZXB0aEItLTtcbiAgfSAvLyBXYWxrIGluIGxvY2tzdGVwIHVudGlsIHdlIGZpbmQgYSBtYXRjaC5cblxuXG4gIHZhciBkZXB0aCA9IGRlcHRoQTtcblxuICB3aGlsZSAoZGVwdGgtLSkge1xuICAgIGlmIChub2RlQSA9PT0gbm9kZUIgfHwgbm9kZUIgIT09IG51bGwgJiYgbm9kZUEgPT09IG5vZGVCLmFsdGVybmF0ZSkge1xuICAgICAgcmV0dXJuIG5vZGVBO1xuICAgIH1cblxuICAgIG5vZGVBID0gZ2V0UGFyZW50KG5vZGVBKTtcbiAgICBub2RlQiA9IGdldFBhcmVudChub2RlQik7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZUVudGVyTGVhdmVMaXN0ZW5lcnNGb3JFdmVudChkaXNwYXRjaFF1ZXVlLCBldmVudCwgdGFyZ2V0LCBjb21tb24sIGluQ2FwdHVyZVBoYXNlKSB7XG4gIHZhciByZWdpc3RyYXRpb25OYW1lID0gZXZlbnQuX3JlYWN0TmFtZTtcbiAgdmFyIGxpc3RlbmVycyA9IFtdO1xuICB2YXIgaW5zdGFuY2UgPSB0YXJnZXQ7XG5cbiAgd2hpbGUgKGluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgaWYgKGluc3RhbmNlID09PSBjb21tb24pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBfaW5zdGFuY2U0ID0gaW5zdGFuY2UsXG4gICAgICAgIGFsdGVybmF0ZSA9IF9pbnN0YW5jZTQuYWx0ZXJuYXRlLFxuICAgICAgICBzdGF0ZU5vZGUgPSBfaW5zdGFuY2U0LnN0YXRlTm9kZSxcbiAgICAgICAgdGFnID0gX2luc3RhbmNlNC50YWc7XG5cbiAgICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsICYmIGFsdGVybmF0ZSA9PT0gY29tbW9uKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSBIb3N0Q29tcG9uZW50ICYmIHN0YXRlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIGN1cnJlbnRUYXJnZXQgPSBzdGF0ZU5vZGU7XG5cbiAgICAgIGlmIChpbkNhcHR1cmVQaGFzZSkge1xuICAgICAgICB2YXIgY2FwdHVyZUxpc3RlbmVyID0gZ2V0TGlzdGVuZXIoaW5zdGFuY2UsIHJlZ2lzdHJhdGlvbk5hbWUpO1xuXG4gICAgICAgIGlmIChjYXB0dXJlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgIGxpc3RlbmVycy51bnNoaWZ0KGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGNhcHR1cmVMaXN0ZW5lciwgY3VycmVudFRhcmdldCkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFpbkNhcHR1cmVQaGFzZSkge1xuICAgICAgICB2YXIgYnViYmxlTGlzdGVuZXIgPSBnZXRMaXN0ZW5lcihpbnN0YW5jZSwgcmVnaXN0cmF0aW9uTmFtZSk7XG5cbiAgICAgICAgaWYgKGJ1YmJsZUxpc3RlbmVyICE9IG51bGwpIHtcbiAgICAgICAgICBsaXN0ZW5lcnMucHVzaChjcmVhdGVEaXNwYXRjaExpc3RlbmVyKGluc3RhbmNlLCBidWJibGVMaXN0ZW5lciwgY3VycmVudFRhcmdldCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaW5zdGFuY2UgPSBpbnN0YW5jZS5yZXR1cm47XG4gIH1cblxuICBpZiAobGlzdGVuZXJzLmxlbmd0aCAhPT0gMCkge1xuICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICBsaXN0ZW5lcnM6IGxpc3RlbmVyc1xuICAgIH0pO1xuICB9XG59IC8vIFdlIHNob3VsZCBvbmx5IHVzZSB0aGlzIGZ1bmN0aW9uIGZvcjpcbi8vIC0gRW50ZXJMZWF2ZUV2ZW50UGx1Z2luXG4vLyBUaGlzIGlzIGJlY2F1c2Ugd2Ugb25seSBwcm9jZXNzIHRoaXMgcGx1Z2luXG4vLyBpbiB0aGUgYnViYmxlIHBoYXNlLCBzbyB3ZSBuZWVkIHRvIGFjY3VtdWxhdGUgdHdvXG4vLyBwaGFzZSBldmVudCBsaXN0ZW5lcnMuXG5cblxuZnVuY3Rpb24gYWNjdW11bGF0ZUVudGVyTGVhdmVUd29QaGFzZUxpc3RlbmVycyhkaXNwYXRjaFF1ZXVlLCBsZWF2ZUV2ZW50LCBlbnRlckV2ZW50LCBmcm9tLCB0bykge1xuICB2YXIgY29tbW9uID0gZnJvbSAmJiB0byA/IGdldExvd2VzdENvbW1vbkFuY2VzdG9yKGZyb20sIHRvKSA6IG51bGw7XG5cbiAgaWYgKGZyb20gIT09IG51bGwpIHtcbiAgICBhY2N1bXVsYXRlRW50ZXJMZWF2ZUxpc3RlbmVyc0ZvckV2ZW50KGRpc3BhdGNoUXVldWUsIGxlYXZlRXZlbnQsIGZyb20sIGNvbW1vbiwgZmFsc2UpO1xuICB9XG5cbiAgaWYgKHRvICE9PSBudWxsICYmIGVudGVyRXZlbnQgIT09IG51bGwpIHtcbiAgICBhY2N1bXVsYXRlRW50ZXJMZWF2ZUxpc3RlbmVyc0ZvckV2ZW50KGRpc3BhdGNoUXVldWUsIGVudGVyRXZlbnQsIHRvLCBjb21tb24sIHRydWUpO1xuICB9XG59XG5mdW5jdGlvbiBnZXRMaXN0ZW5lclNldEtleShkb21FdmVudE5hbWUsIGNhcHR1cmUpIHtcbiAgcmV0dXJuIGRvbUV2ZW50TmFtZSArIFwiX19cIiArIChjYXB0dXJlID8gJ2NhcHR1cmUnIDogJ2J1YmJsZScpO1xufVxuXG52YXIgZGlkV2FybkludmFsaWRIeWRyYXRpb24gPSBmYWxzZTtcbnZhciBEQU5HRVJPVVNMWV9TRVRfSU5ORVJfSFRNTCA9ICdkYW5nZXJvdXNseVNldElubmVySFRNTCc7XG52YXIgU1VQUFJFU1NfQ09OVEVOVF9FRElUQUJMRV9XQVJOSU5HID0gJ3N1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZyc7XG52YXIgU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkcgPSAnc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nJztcbnZhciBBVVRPRk9DVVMgPSAnYXV0b0ZvY3VzJztcbnZhciBDSElMRFJFTiA9ICdjaGlsZHJlbic7XG52YXIgU1RZTEUgPSAnc3R5bGUnO1xudmFyIEhUTUwkMSA9ICdfX2h0bWwnO1xudmFyIHdhcm5lZFVua25vd25UYWdzO1xudmFyIHZhbGlkYXRlUHJvcGVydGllc0luRGV2ZWxvcG1lbnQ7XG52YXIgd2FybkZvclByb3BEaWZmZXJlbmNlO1xudmFyIHdhcm5Gb3JFeHRyYUF0dHJpYnV0ZXM7XG52YXIgd2FybkZvckludmFsaWRFdmVudExpc3RlbmVyO1xudmFyIGNhbkRpZmZTdHlsZUZvckh5ZHJhdGlvbldhcm5pbmc7XG52YXIgbm9ybWFsaXplSFRNTDtcblxue1xuICB3YXJuZWRVbmtub3duVGFncyA9IHtcbiAgICAvLyBUaGVyZSBhcmUgd29ya2luZyBwb2x5ZmlsbHMgZm9yIDxkaWFsb2c+LiBMZXQgcGVvcGxlIHVzZSBpdC5cbiAgICBkaWFsb2c6IHRydWUsXG4gICAgLy8gRWxlY3Ryb24gc2hpcHMgYSBjdXN0b20gPHdlYnZpZXc+IHRhZyB0byBkaXNwbGF5IGV4dGVybmFsIHdlYiBjb250ZW50IGluXG4gICAgLy8gYW4gaXNvbGF0ZWQgZnJhbWUgYW5kIHByb2Nlc3MuXG4gICAgLy8gVGhpcyB0YWcgaXMgbm90IHByZXNlbnQgaW4gbm9uIEVsZWN0cm9uIGVudmlyb25tZW50cyBzdWNoIGFzIEpTRG9tIHdoaWNoXG4gICAgLy8gaXMgb2Z0ZW4gdXNlZCBmb3IgdGVzdGluZyBwdXJwb3Nlcy5cbiAgICAvLyBAc2VlIGh0dHBzOi8vZWxlY3Ryb25qcy5vcmcvZG9jcy9hcGkvd2Vidmlldy10YWdcbiAgICB3ZWJ2aWV3OiB0cnVlXG4gIH07XG5cbiAgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudCA9IGZ1bmN0aW9uICh0eXBlLCBwcm9wcykge1xuICAgIHZhbGlkYXRlUHJvcGVydGllcyh0eXBlLCBwcm9wcyk7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzJDEodHlwZSwgcHJvcHMpO1xuICAgIHZhbGlkYXRlUHJvcGVydGllcyQyKHR5cGUsIHByb3BzLCB7XG4gICAgICByZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzOiByZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLFxuICAgICAgcG9zc2libGVSZWdpc3RyYXRpb25OYW1lczogcG9zc2libGVSZWdpc3RyYXRpb25OYW1lc1xuICAgIH0pO1xuICB9OyAvLyBJRSAxMSBwYXJzZXMgJiBub3JtYWxpemVzIHRoZSBzdHlsZSBhdHRyaWJ1dGUgYXMgb3Bwb3NlZCB0byBvdGhlclxuICAvLyBicm93c2Vycy4gSXQgYWRkcyBzcGFjZXMgYW5kIHNvcnRzIHRoZSBwcm9wZXJ0aWVzIGluIHNvbWVcbiAgLy8gbm9uLWFscGhhYmV0aWNhbCBvcmRlci4gSGFuZGxpbmcgdGhhdCB3b3VsZCByZXF1aXJlIHNvcnRpbmcgQ1NTXG4gIC8vIHByb3BlcnRpZXMgaW4gdGhlIGNsaWVudCAmIHNlcnZlciB2ZXJzaW9ucyBvciBhcHBseWluZ1xuICAvLyBgZXhwZWN0ZWRTdHlsZWAgdG8gYSB0ZW1wb3JhcnkgRE9NIG5vZGUgdG8gcmVhZCBpdHMgYHN0eWxlYCBhdHRyaWJ1dGVcbiAgLy8gbm9ybWFsaXplZC4gU2luY2UgaXQgb25seSBhZmZlY3RzIElFLCB3ZSdyZSBza2lwcGluZyBzdHlsZSB3YXJuaW5nc1xuICAvLyBpbiB0aGF0IGJyb3dzZXIgY29tcGxldGVseSBpbiBmYXZvciBvZiBkb2luZyBhbGwgdGhhdCB3b3JrLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMTgwN1xuXG5cbiAgY2FuRGlmZlN0eWxlRm9ySHlkcmF0aW9uV2FybmluZyA9IGNhblVzZURPTSAmJiAhZG9jdW1lbnQuZG9jdW1lbnRNb2RlO1xuXG4gIHdhcm5Gb3JQcm9wRGlmZmVyZW5jZSA9IGZ1bmN0aW9uIChwcm9wTmFtZSwgc2VydmVyVmFsdWUsIGNsaWVudFZhbHVlKSB7XG4gICAgaWYgKGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5vcm1hbGl6ZWRDbGllbnRWYWx1ZSA9IG5vcm1hbGl6ZU1hcmt1cEZvclRleHRPckF0dHJpYnV0ZShjbGllbnRWYWx1ZSk7XG4gICAgdmFyIG5vcm1hbGl6ZWRTZXJ2ZXJWYWx1ZSA9IG5vcm1hbGl6ZU1hcmt1cEZvclRleHRPckF0dHJpYnV0ZShzZXJ2ZXJWYWx1ZSk7XG5cbiAgICBpZiAobm9ybWFsaXplZFNlcnZlclZhbHVlID09PSBub3JtYWxpemVkQ2xpZW50VmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICBlcnJvcignUHJvcCBgJXNgIGRpZCBub3QgbWF0Y2guIFNlcnZlcjogJXMgQ2xpZW50OiAlcycsIHByb3BOYW1lLCBKU09OLnN0cmluZ2lmeShub3JtYWxpemVkU2VydmVyVmFsdWUpLCBKU09OLnN0cmluZ2lmeShub3JtYWxpemVkQ2xpZW50VmFsdWUpKTtcbiAgfTtcblxuICB3YXJuRm9yRXh0cmFBdHRyaWJ1dGVzID0gZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWVzKSB7XG4gICAgaWYgKGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkludmFsaWRIeWRyYXRpb24gPSB0cnVlO1xuICAgIHZhciBuYW1lcyA9IFtdO1xuICAgIGF0dHJpYnV0ZU5hbWVzLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIG5hbWVzLnB1c2gobmFtZSk7XG4gICAgfSk7XG5cbiAgICBlcnJvcignRXh0cmEgYXR0cmlidXRlcyBmcm9tIHRoZSBzZXJ2ZXI6ICVzJywgbmFtZXMpO1xuICB9O1xuXG4gIHdhcm5Gb3JJbnZhbGlkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIChyZWdpc3RyYXRpb25OYW1lLCBsaXN0ZW5lcikge1xuICAgIGlmIChsaXN0ZW5lciA9PT0gZmFsc2UpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCBgJXNgIGxpc3RlbmVyIHRvIGJlIGEgZnVuY3Rpb24sIGluc3RlYWQgZ290IGBmYWxzZWAuXFxuXFxuJyArICdJZiB5b3UgdXNlZCB0byBjb25kaXRpb25hbGx5IG9taXQgaXQgd2l0aCAlcz17Y29uZGl0aW9uICYmIHZhbHVlfSwgJyArICdwYXNzICVzPXtjb25kaXRpb24gPyB2YWx1ZSA6IHVuZGVmaW5lZH0gaW5zdGVhZC4nLCByZWdpc3RyYXRpb25OYW1lLCByZWdpc3RyYXRpb25OYW1lLCByZWdpc3RyYXRpb25OYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIGAlc2AgbGlzdGVuZXIgdG8gYmUgYSBmdW5jdGlvbiwgaW5zdGVhZCBnb3QgYSB2YWx1ZSBvZiBgJXNgIHR5cGUuJywgcmVnaXN0cmF0aW9uTmFtZSwgdHlwZW9mIGxpc3RlbmVyKTtcbiAgICB9XG4gIH07IC8vIFBhcnNlIHRoZSBIVE1MIGFuZCByZWFkIGl0IGJhY2sgdG8gbm9ybWFsaXplIHRoZSBIVE1MIHN0cmluZyBzbyB0aGF0IGl0XG4gIC8vIGNhbiBiZSB1c2VkIGZvciBjb21wYXJpc29uLlxuXG5cbiAgbm9ybWFsaXplSFRNTCA9IGZ1bmN0aW9uIChwYXJlbnQsIGh0bWwpIHtcbiAgICAvLyBXZSBjb3VsZCBoYXZlIGNyZWF0ZWQgYSBzZXBhcmF0ZSBkb2N1bWVudCBoZXJlIHRvIGF2b2lkXG4gICAgLy8gcmUtaW5pdGlhbGl6aW5nIGN1c3RvbSBlbGVtZW50cyBpZiB0aGV5IGV4aXN0LiBCdXQgdGhpcyBicmVha3NcbiAgICAvLyBob3cgPG5vc2NyaXB0PiBpcyBiZWluZyBoYW5kbGVkLiBTbyB3ZSB1c2UgdGhlIHNhbWUgZG9jdW1lbnQuXG4gICAgLy8gU2VlIHRoZSBkaXNjdXNzaW9uIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzExMTU3LlxuICAgIHZhciB0ZXN0RWxlbWVudCA9IHBhcmVudC5uYW1lc3BhY2VVUkkgPT09IEhUTUxfTkFNRVNQQUNFID8gcGFyZW50Lm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChwYXJlbnQudGFnTmFtZSkgOiBwYXJlbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50TlMocGFyZW50Lm5hbWVzcGFjZVVSSSwgcGFyZW50LnRhZ05hbWUpO1xuICAgIHRlc3RFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRlc3RFbGVtZW50LmlubmVySFRNTDtcbiAgfTtcbn0gLy8gSFRNTCBwYXJzaW5nIG5vcm1hbGl6ZXMgQ1IgYW5kIENSTEYgdG8gTEYuXG4vLyBJdCBhbHNvIGNhbiB0dXJuIFxcdTAwMDAgaW50byBcXHVGRkZEIGluc2lkZSBhdHRyaWJ1dGVzLlxuLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL2h0bWw1L3NpbmdsZS1wYWdlLmh0bWwjcHJlcHJvY2Vzc2luZy10aGUtaW5wdXQtc3RyZWFtXG4vLyBJZiB3ZSBoYXZlIGEgbWlzbWF0Y2gsIGl0IG1pZ2h0IGJlIGNhdXNlZCBieSB0aGF0LlxuLy8gV2Ugd2lsbCBzdGlsbCBwYXRjaCB1cCBpbiB0aGlzIGNhc2UgYnV0IG5vdCBmaXJlIHRoZSB3YXJuaW5nLlxuXG5cbnZhciBOT1JNQUxJWkVfTkVXTElORVNfUkVHRVggPSAvXFxyXFxuPy9nO1xudmFyIE5PUk1BTElaRV9OVUxMX0FORF9SRVBMQUNFTUVOVF9SRUdFWCA9IC9cXHUwMDAwfFxcdUZGRkQvZztcblxuZnVuY3Rpb24gbm9ybWFsaXplTWFya3VwRm9yVGV4dE9yQXR0cmlidXRlKG1hcmt1cCkge1xuICB7XG4gICAgY2hlY2tIdG1sU3RyaW5nQ29lcmNpb24obWFya3VwKTtcbiAgfVxuXG4gIHZhciBtYXJrdXBTdHJpbmcgPSB0eXBlb2YgbWFya3VwID09PSAnc3RyaW5nJyA/IG1hcmt1cCA6ICcnICsgbWFya3VwO1xuICByZXR1cm4gbWFya3VwU3RyaW5nLnJlcGxhY2UoTk9STUFMSVpFX05FV0xJTkVTX1JFR0VYLCAnXFxuJykucmVwbGFjZShOT1JNQUxJWkVfTlVMTF9BTkRfUkVQTEFDRU1FTlRfUkVHRVgsICcnKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tGb3JVbm1hdGNoZWRUZXh0KHNlcnZlclRleHQsIGNsaWVudFRleHQsIGlzQ29uY3VycmVudE1vZGUsIHNob3VsZFdhcm5EZXYpIHtcbiAgdmFyIG5vcm1hbGl6ZWRDbGllbnRUZXh0ID0gbm9ybWFsaXplTWFya3VwRm9yVGV4dE9yQXR0cmlidXRlKGNsaWVudFRleHQpO1xuICB2YXIgbm9ybWFsaXplZFNlcnZlclRleHQgPSBub3JtYWxpemVNYXJrdXBGb3JUZXh0T3JBdHRyaWJ1dGUoc2VydmVyVGV4dCk7XG5cbiAgaWYgKG5vcm1hbGl6ZWRTZXJ2ZXJUZXh0ID09PSBub3JtYWxpemVkQ2xpZW50VGV4dCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChzaG91bGRXYXJuRGV2KSB7XG4gICAge1xuICAgICAgaWYgKCFkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbikge1xuICAgICAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1RleHQgY29udGVudCBkaWQgbm90IG1hdGNoLiBTZXJ2ZXI6IFwiJXNcIiBDbGllbnQ6IFwiJXNcIicsIG5vcm1hbGl6ZWRTZXJ2ZXJUZXh0LCBub3JtYWxpemVkQ2xpZW50VGV4dCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzQ29uY3VycmVudE1vZGUgJiYgZW5hYmxlQ2xpZW50UmVuZGVyRmFsbGJhY2tPblRleHRNaXNtYXRjaCkge1xuICAgIC8vIEluIGNvbmN1cnJlbnQgcm9vdHMsIHdlIHRocm93IHdoZW4gdGhlcmUncyBhIHRleHQgbWlzbWF0Y2ggYW5kIHJldmVydCB0b1xuICAgIC8vIGNsaWVudCByZW5kZXJpbmcsIHVwIHRvIHRoZSBuZWFyZXN0IFN1c3BlbnNlIGJvdW5kYXJ5LlxuICAgIHRocm93IG5ldyBFcnJvcignVGV4dCBjb250ZW50IGRvZXMgbm90IG1hdGNoIHNlcnZlci1yZW5kZXJlZCBIVE1MLicpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE93bmVyRG9jdW1lbnRGcm9tUm9vdENvbnRhaW5lcihyb290Q29udGFpbmVyRWxlbWVudCkge1xuICByZXR1cm4gcm9vdENvbnRhaW5lckVsZW1lbnQubm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUgPyByb290Q29udGFpbmVyRWxlbWVudCA6IHJvb3RDb250YWluZXJFbGVtZW50Lm93bmVyRG9jdW1lbnQ7XG59XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5mdW5jdGlvbiB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChub2RlKSB7XG4gIC8vIE1vYmlsZSBTYWZhcmkgZG9lcyBub3QgZmlyZSBwcm9wZXJseSBidWJibGUgY2xpY2sgZXZlbnRzIG9uXG4gIC8vIG5vbi1pbnRlcmFjdGl2ZSBlbGVtZW50cywgd2hpY2ggbWVhbnMgZGVsZWdhdGVkIGNsaWNrIGxpc3RlbmVycyBkbyBub3RcbiAgLy8gZmlyZS4gVGhlIHdvcmthcm91bmQgZm9yIHRoaXMgYnVnIGludm9sdmVzIGF0dGFjaGluZyBhbiBlbXB0eSBjbGlja1xuICAvLyBsaXN0ZW5lciBvbiB0aGUgdGFyZ2V0IG5vZGUuXG4gIC8vIGh0dHBzOi8vd3d3LnF1aXJrc21vZGUub3JnL2Jsb2cvYXJjaGl2ZXMvMjAxMC8wOS9jbGlja19ldmVudF9kZWwuaHRtbFxuICAvLyBKdXN0IHNldCBpdCB1c2luZyB0aGUgb25jbGljayBwcm9wZXJ0eSBzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gbWFuYWdlIGFueVxuICAvLyBib29ra2VlcGluZyBmb3IgaXQuIE5vdCBzdXJlIGlmIHdlIG5lZWQgdG8gY2xlYXIgaXQgd2hlbiB0aGUgbGlzdGVuZXIgaXNcbiAgLy8gcmVtb3ZlZC5cbiAgLy8gVE9ETzogT25seSBkbyB0aGlzIGZvciB0aGUgcmVsZXZhbnQgU2FmYXJpcyBtYXliZT9cbiAgbm9kZS5vbmNsaWNrID0gbm9vcDtcbn1cblxuZnVuY3Rpb24gc2V0SW5pdGlhbERPTVByb3BlcnRpZXModGFnLCBkb21FbGVtZW50LCByb290Q29udGFpbmVyRWxlbWVudCwgbmV4dFByb3BzLCBpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICBmb3IgKHZhciBwcm9wS2V5IGluIG5leHRQcm9wcykge1xuICAgIGlmICghbmV4dFByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB2YXIgbmV4dFByb3AgPSBuZXh0UHJvcHNbcHJvcEtleV07XG5cbiAgICBpZiAocHJvcEtleSA9PT0gU1RZTEUpIHtcbiAgICAgIHtcbiAgICAgICAgaWYgKG5leHRQcm9wKSB7XG4gICAgICAgICAgLy8gRnJlZXplIHRoZSBuZXh0IHN0eWxlIG9iamVjdCBzbyB0aGF0IHdlIGNhbiBhc3N1bWUgaXQgd29uJ3QgYmVcbiAgICAgICAgICAvLyBtdXRhdGVkLiBXZSBoYXZlIGFscmVhZHkgd2FybmVkIGZvciB0aGlzIGluIHRoZSBwYXN0LlxuICAgICAgICAgIE9iamVjdC5mcmVlemUobmV4dFByb3ApO1xuICAgICAgICB9XG4gICAgICB9IC8vIFJlbGllcyBvbiBgdXBkYXRlU3R5bGVzQnlJRGAgbm90IG11dGF0aW5nIGBzdHlsZVVwZGF0ZXNgLlxuXG5cbiAgICAgIHNldFZhbHVlRm9yU3R5bGVzKGRvbUVsZW1lbnQsIG5leHRQcm9wKTtcbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IERBTkdFUk9VU0xZX1NFVF9JTk5FUl9IVE1MKSB7XG4gICAgICB2YXIgbmV4dEh0bWwgPSBuZXh0UHJvcCA/IG5leHRQcm9wW0hUTUwkMV0gOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChuZXh0SHRtbCAhPSBudWxsKSB7XG4gICAgICAgIHNldElubmVySFRNTChkb21FbGVtZW50LCBuZXh0SHRtbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBDSElMRFJFTikge1xuICAgICAgaWYgKHR5cGVvZiBuZXh0UHJvcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gQXZvaWQgc2V0dGluZyBpbml0aWFsIHRleHRDb250ZW50IHdoZW4gdGhlIHRleHQgaXMgZW1wdHkuIEluIElFMTEgc2V0dGluZ1xuICAgICAgICAvLyB0ZXh0Q29udGVudCBvbiBhIDx0ZXh0YXJlYT4gd2lsbCBjYXVzZSB0aGUgcGxhY2Vob2xkZXIgdG8gbm90XG4gICAgICAgIC8vIHNob3cgd2l0aGluIHRoZSA8dGV4dGFyZWE+IHVudGlsIGl0IGhhcyBiZWVuIGZvY3VzZWQgYW5kIGJsdXJyZWQgYWdhaW4uXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvNjczMSNpc3N1ZWNvbW1lbnQtMjU0ODc0NTUzXG4gICAgICAgIHZhciBjYW5TZXRUZXh0Q29udGVudCA9IHRhZyAhPT0gJ3RleHRhcmVhJyB8fCBuZXh0UHJvcCAhPT0gJyc7XG5cbiAgICAgICAgaWYgKGNhblNldFRleHRDb250ZW50KSB7XG4gICAgICAgICAgc2V0VGV4dENvbnRlbnQoZG9tRWxlbWVudCwgbmV4dFByb3ApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBuZXh0UHJvcCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgc2V0VGV4dENvbnRlbnQoZG9tRWxlbWVudCwgJycgKyBuZXh0UHJvcCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgfHwgcHJvcEtleSA9PT0gU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkcpIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gQVVUT0ZPQ1VTKSA7IGVsc2UgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIGlmIChuZXh0UHJvcCAhPSBudWxsKSB7XG4gICAgICAgIGlmICggdHlwZW9mIG5leHRQcm9wICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgd2FybkZvckludmFsaWRFdmVudExpc3RlbmVyKHByb3BLZXksIG5leHRQcm9wKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wS2V5ID09PSAnb25TY3JvbGwnKSB7XG4gICAgICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnc2Nyb2xsJywgZG9tRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5leHRQcm9wICE9IG51bGwpIHtcbiAgICAgIHNldFZhbHVlRm9yUHJvcGVydHkoZG9tRWxlbWVudCwgcHJvcEtleSwgbmV4dFByb3AsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlRE9NUHJvcGVydGllcyhkb21FbGVtZW50LCB1cGRhdGVQYXlsb2FkLCB3YXNDdXN0b21Db21wb25lbnRUYWcsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gIC8vIFRPRE86IEhhbmRsZSB3YXNDdXN0b21Db21wb25lbnRUYWdcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB1cGRhdGVQYXlsb2FkLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIHByb3BLZXkgPSB1cGRhdGVQYXlsb2FkW2ldO1xuICAgIHZhciBwcm9wVmFsdWUgPSB1cGRhdGVQYXlsb2FkW2kgKyAxXTtcblxuICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAgc2V0VmFsdWVGb3JTdHlsZXMoZG9tRWxlbWVudCwgcHJvcFZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IERBTkdFUk9VU0xZX1NFVF9JTk5FUl9IVE1MKSB7XG4gICAgICBzZXRJbm5lckhUTUwoZG9tRWxlbWVudCwgcHJvcFZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IENISUxEUkVOKSB7XG4gICAgICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCBwcm9wVmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRWYWx1ZUZvclByb3BlcnR5KGRvbUVsZW1lbnQsIHByb3BLZXksIHByb3BWYWx1ZSwgaXNDdXN0b21Db21wb25lbnRUYWcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIHByb3BzLCByb290Q29udGFpbmVyRWxlbWVudCwgcGFyZW50TmFtZXNwYWNlKSB7XG4gIHZhciBpc0N1c3RvbUNvbXBvbmVudFRhZzsgLy8gV2UgY3JlYXRlIHRhZ3MgaW4gdGhlIG5hbWVzcGFjZSBvZiB0aGVpciBwYXJlbnQgY29udGFpbmVyLCBleGNlcHQgSFRNTFxuICAvLyB0YWdzIGdldCBubyBuYW1lc3BhY2UuXG5cbiAgdmFyIG93bmVyRG9jdW1lbnQgPSBnZXRPd25lckRvY3VtZW50RnJvbVJvb3RDb250YWluZXIocm9vdENvbnRhaW5lckVsZW1lbnQpO1xuICB2YXIgZG9tRWxlbWVudDtcbiAgdmFyIG5hbWVzcGFjZVVSSSA9IHBhcmVudE5hbWVzcGFjZTtcblxuICBpZiAobmFtZXNwYWNlVVJJID09PSBIVE1MX05BTUVTUEFDRSkge1xuICAgIG5hbWVzcGFjZVVSSSA9IGdldEludHJpbnNpY05hbWVzcGFjZSh0eXBlKTtcbiAgfVxuXG4gIGlmIChuYW1lc3BhY2VVUkkgPT09IEhUTUxfTkFNRVNQQUNFKSB7XG4gICAge1xuICAgICAgaXNDdXN0b21Db21wb25lbnRUYWcgPSBpc0N1c3RvbUNvbXBvbmVudCh0eXBlLCBwcm9wcyk7IC8vIFNob3VsZCB0aGlzIGNoZWNrIGJlIGdhdGVkIGJ5IHBhcmVudCBuYW1lc3BhY2U/IE5vdCBzdXJlIHdlIHdhbnQgdG9cbiAgICAgIC8vIGFsbG93IDxTVkc+IG9yIDxtQVRIPi5cblxuICAgICAgaWYgKCFpc0N1c3RvbUNvbXBvbmVudFRhZyAmJiB0eXBlICE9PSB0eXBlLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgZXJyb3IoJzwlcyAvPiBpcyB1c2luZyBpbmNvcnJlY3QgY2FzaW5nLiAnICsgJ1VzZSBQYXNjYWxDYXNlIGZvciBSZWFjdCBjb21wb25lbnRzLCAnICsgJ29yIGxvd2VyY2FzZSBmb3IgSFRNTCBlbGVtZW50cy4nLCB0eXBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gJ3NjcmlwdCcpIHtcbiAgICAgIC8vIENyZWF0ZSB0aGUgc2NyaXB0IHZpYSAuaW5uZXJIVE1MIHNvIGl0cyBcInBhcnNlci1pbnNlcnRlZFwiIGZsYWcgaXNcbiAgICAgIC8vIHNldCB0byB0cnVlIGFuZCBpdCBkb2VzIG5vdCBleGVjdXRlXG4gICAgICB2YXIgZGl2ID0gb3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAgICAgZGl2LmlubmVySFRNTCA9ICc8c2NyaXB0PjwnICsgJy9zY3JpcHQ+JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgLy8gVGhpcyBpcyBndWFyYW50ZWVkIHRvIHlpZWxkIGEgc2NyaXB0IGVsZW1lbnQuXG5cbiAgICAgIHZhciBmaXJzdENoaWxkID0gZGl2LmZpcnN0Q2hpbGQ7XG4gICAgICBkb21FbGVtZW50ID0gZGl2LnJlbW92ZUNoaWxkKGZpcnN0Q2hpbGQpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHByb3BzLmlzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gJEZsb3dJc3N1ZSBgY3JlYXRlRWxlbWVudGAgc2hvdWxkIGJlIHVwZGF0ZWQgZm9yIFdlYiBDb21wb25lbnRzXG4gICAgICBkb21FbGVtZW50ID0gb3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHR5cGUsIHtcbiAgICAgICAgaXM6IHByb3BzLmlzXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2VwYXJhdGUgZWxzZSBicmFuY2ggaW5zdGVhZCBvZiB1c2luZyBgcHJvcHMuaXMgfHwgdW5kZWZpbmVkYCBhYm92ZSBiZWNhdXNlIG9mIGEgRmlyZWZveCBidWcuXG4gICAgICAvLyBTZWUgZGlzY3Vzc2lvbiBpbiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC82ODk2XG4gICAgICAvLyBhbmQgZGlzY3Vzc2lvbiBpbiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xMjc2MjQwXG4gICAgICBkb21FbGVtZW50ID0gb3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHR5cGUpOyAvLyBOb3JtYWxseSBhdHRyaWJ1dGVzIGFyZSBhc3NpZ25lZCBpbiBgc2V0SW5pdGlhbERPTVByb3BlcnRpZXNgLCBob3dldmVyIHRoZSBgbXVsdGlwbGVgIGFuZCBgc2l6ZWBcbiAgICAgIC8vIGF0dHJpYnV0ZXMgb24gYHNlbGVjdGBzIG5lZWRzIHRvIGJlIGFkZGVkIGJlZm9yZSBgb3B0aW9uYHMgYXJlIGluc2VydGVkLlxuICAgICAgLy8gVGhpcyBwcmV2ZW50czpcbiAgICAgIC8vIC0gYSBidWcgd2hlcmUgdGhlIGBzZWxlY3RgIGRvZXMgbm90IHNjcm9sbCB0byB0aGUgY29ycmVjdCBvcHRpb24gYmVjYXVzZSBzaW5ndWxhclxuICAgICAgLy8gIGBzZWxlY3RgIGVsZW1lbnRzIGF1dG9tYXRpY2FsbHkgcGljayB0aGUgZmlyc3QgaXRlbSAjMTMyMjJcbiAgICAgIC8vIC0gYSBidWcgd2hlcmUgdGhlIGBzZWxlY3RgIHNldCB0aGUgZmlyc3QgaXRlbSBhcyBzZWxlY3RlZCBkZXNwaXRlIHRoZSBgc2l6ZWAgYXR0cmlidXRlICMxNDIzOVxuICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTMyMjJcbiAgICAgIC8vIGFuZCBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE0MjM5XG5cbiAgICAgIGlmICh0eXBlID09PSAnc2VsZWN0Jykge1xuICAgICAgICB2YXIgbm9kZSA9IGRvbUVsZW1lbnQ7XG5cbiAgICAgICAgaWYgKHByb3BzLm11bHRpcGxlKSB7XG4gICAgICAgICAgbm9kZS5tdWx0aXBsZSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAocHJvcHMuc2l6ZSkge1xuICAgICAgICAgIC8vIFNldHRpbmcgYSBzaXplIGdyZWF0ZXIgdGhhbiAxIGNhdXNlcyBhIHNlbGVjdCB0byBiZWhhdmUgbGlrZSBgbXVsdGlwbGU9dHJ1ZWAsIHdoZXJlXG4gICAgICAgICAgLy8gaXQgaXMgcG9zc2libGUgdGhhdCBubyBvcHRpb24gaXMgc2VsZWN0ZWQuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBUaGlzIGlzIG9ubHkgbmVjZXNzYXJ5IHdoZW4gYSBzZWxlY3QgaW4gXCJzaW5nbGUgc2VsZWN0aW9uIG1vZGVcIi5cbiAgICAgICAgICBub2RlLnNpemUgPSBwcm9wcy5zaXplO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRvbUVsZW1lbnQgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIHR5cGUpO1xuICB9XG5cbiAge1xuICAgIGlmIChuYW1lc3BhY2VVUkkgPT09IEhUTUxfTkFNRVNQQUNFKSB7XG4gICAgICBpZiAoIWlzQ3VzdG9tQ29tcG9uZW50VGFnICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkb21FbGVtZW50KSA9PT0gJ1tvYmplY3QgSFRNTFVua25vd25FbGVtZW50XScgJiYgIWhhc093blByb3BlcnR5LmNhbGwod2FybmVkVW5rbm93blRhZ3MsIHR5cGUpKSB7XG4gICAgICAgIHdhcm5lZFVua25vd25UYWdzW3R5cGVdID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignVGhlIHRhZyA8JXM+IGlzIHVucmVjb2duaXplZCBpbiB0aGlzIGJyb3dzZXIuICcgKyAnSWYgeW91IG1lYW50IHRvIHJlbmRlciBhIFJlYWN0IGNvbXBvbmVudCwgc3RhcnQgaXRzIG5hbWUgd2l0aCAnICsgJ2FuIHVwcGVyY2FzZSBsZXR0ZXIuJywgdHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRvbUVsZW1lbnQ7XG59XG5mdW5jdGlvbiBjcmVhdGVUZXh0Tm9kZSh0ZXh0LCByb290Q29udGFpbmVyRWxlbWVudCkge1xuICByZXR1cm4gZ2V0T3duZXJEb2N1bWVudEZyb21Sb290Q29udGFpbmVyKHJvb3RDb250YWluZXJFbGVtZW50KS5jcmVhdGVUZXh0Tm9kZSh0ZXh0KTtcbn1cbmZ1bmN0aW9uIHNldEluaXRpYWxQcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHRhZywgcmF3UHJvcHMsIHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIHZhciBpc0N1c3RvbUNvbXBvbmVudFRhZyA9IGlzQ3VzdG9tQ29tcG9uZW50KHRhZywgcmF3UHJvcHMpO1xuXG4gIHtcbiAgICB2YWxpZGF0ZVByb3BlcnRpZXNJbkRldmVsb3BtZW50KHRhZywgcmF3UHJvcHMpO1xuICB9IC8vIFRPRE86IE1ha2Ugc3VyZSB0aGF0IHdlIGNoZWNrIGlzTW91bnRlZCBiZWZvcmUgZmlyaW5nIGFueSBvZiB0aGVzZSBldmVudHMuXG5cblxuICB2YXIgcHJvcHM7XG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdkaWFsb2cnOlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnY2FuY2VsJywgZG9tRWxlbWVudCk7XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdjbG9zZScsIGRvbUVsZW1lbnQpO1xuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaWZyYW1lJzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgIGNhc2UgJ2VtYmVkJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBsb2FkIGV2ZW50LlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnbG9hZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndmlkZW8nOlxuICAgIGNhc2UgJ2F1ZGlvJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGVzZSBldmVudHMgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgYWxsIHRoZSBtZWRpYSBldmVudHMuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lZGlhRXZlbnRUeXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KG1lZGlhRXZlbnRUeXBlc1tpXSwgZG9tRWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NvdXJjZSc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgZXJyb3IgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdlcnJvcicsIGRvbUVsZW1lbnQpO1xuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaW1nJzpcbiAgICBjYXNlICdpbWFnZSc6XG4gICAgY2FzZSAnbGluayc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIGVycm9yIGFuZCBsb2FkIGV2ZW50cy5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2Vycm9yJywgZG9tRWxlbWVudCk7XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdsb2FkJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdkZXRhaWxzJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSB0b2dnbGUgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCd0b2dnbGUnLCBkb21FbGVtZW50KTtcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIGluaXRXcmFwcGVyU3RhdGUoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgcHJvcHMgPSBnZXRIb3N0UHJvcHMoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdvcHRpb24nOlxuICAgICAgdmFsaWRhdGVQcm9wcyhkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgaW5pdFdyYXBwZXJTdGF0ZSQxKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTtcbiAgICAgIHByb3BzID0gZ2V0SG9zdFByb3BzJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDIoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgcHJvcHMgPSBnZXRIb3N0UHJvcHMkMihkb21FbGVtZW50LCByYXdQcm9wcyk7IC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBpbnZhbGlkIGV2ZW50LlxuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdpbnZhbGlkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICB9XG5cbiAgYXNzZXJ0VmFsaWRQcm9wcyh0YWcsIHByb3BzKTtcbiAgc2V0SW5pdGlhbERPTVByb3BlcnRpZXModGFnLCBkb21FbGVtZW50LCByb290Q29udGFpbmVyRWxlbWVudCwgcHJvcHMsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKTtcblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIC8vIFRPRE86IE1ha2Ugc3VyZSB3ZSBjaGVjayBpZiB0aGlzIGlzIHN0aWxsIHVubW91bnRlZCBvciBkbyBhbnkgY2xlYW5cbiAgICAgIC8vIHVwIG5lY2Vzc2FyeSBzaW5jZSB3ZSBuZXZlciBzdG9wIHRyYWNraW5nIGFueW1vcmUuXG4gICAgICB0cmFjayhkb21FbGVtZW50KTtcbiAgICAgIHBvc3RNb3VudFdyYXBwZXIoZG9tRWxlbWVudCwgcmF3UHJvcHMsIGZhbHNlKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgLy8gVE9ETzogTWFrZSBzdXJlIHdlIGNoZWNrIGlmIHRoaXMgaXMgc3RpbGwgdW5tb3VudGVkIG9yIGRvIGFueSBjbGVhblxuICAgICAgLy8gdXAgbmVjZXNzYXJ5IHNpbmNlIHdlIG5ldmVyIHN0b3AgdHJhY2tpbmcgYW55bW9yZS5cbiAgICAgIHRyYWNrKGRvbUVsZW1lbnQpO1xuICAgICAgcG9zdE1vdW50V3JhcHBlciQzKGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdvcHRpb24nOlxuICAgICAgcG9zdE1vdW50V3JhcHBlciQxKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgIHBvc3RNb3VudFdyYXBwZXIkMihkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBpZiAodHlwZW9mIHByb3BzLm9uQ2xpY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVE9ETzogVGhpcyBjYXN0IG1heSBub3QgYmUgc291bmQgZm9yIFNWRywgTWF0aE1MIG9yIGN1c3RvbSBlbGVtZW50cy5cbiAgICAgICAgdHJhcENsaWNrT25Ob25JbnRlcmFjdGl2ZUVsZW1lbnQoZG9tRWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuICB9XG59IC8vIENhbGN1bGF0ZSB0aGUgZGlmZiBiZXR3ZWVuIHRoZSB0d28gb2JqZWN0cy5cblxuZnVuY3Rpb24gZGlmZlByb3BlcnRpZXMoZG9tRWxlbWVudCwgdGFnLCBsYXN0UmF3UHJvcHMsIG5leHRSYXdQcm9wcywgcm9vdENvbnRhaW5lckVsZW1lbnQpIHtcbiAge1xuICAgIHZhbGlkYXRlUHJvcGVydGllc0luRGV2ZWxvcG1lbnQodGFnLCBuZXh0UmF3UHJvcHMpO1xuICB9XG5cbiAgdmFyIHVwZGF0ZVBheWxvYWQgPSBudWxsO1xuICB2YXIgbGFzdFByb3BzO1xuICB2YXIgbmV4dFByb3BzO1xuXG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgbGFzdFByb3BzID0gZ2V0SG9zdFByb3BzKGRvbUVsZW1lbnQsIGxhc3RSYXdQcm9wcyk7XG4gICAgICBuZXh0UHJvcHMgPSBnZXRIb3N0UHJvcHMoZG9tRWxlbWVudCwgbmV4dFJhd1Byb3BzKTtcbiAgICAgIHVwZGF0ZVBheWxvYWQgPSBbXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgIGxhc3RQcm9wcyA9IGdldEhvc3RQcm9wcyQxKGRvbUVsZW1lbnQsIGxhc3RSYXdQcm9wcyk7XG4gICAgICBuZXh0UHJvcHMgPSBnZXRIb3N0UHJvcHMkMShkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICBsYXN0UHJvcHMgPSBnZXRIb3N0UHJvcHMkMihkb21FbGVtZW50LCBsYXN0UmF3UHJvcHMpO1xuICAgICAgbmV4dFByb3BzID0gZ2V0SG9zdFByb3BzJDIoZG9tRWxlbWVudCwgbmV4dFJhd1Byb3BzKTtcbiAgICAgIHVwZGF0ZVBheWxvYWQgPSBbXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGxhc3RQcm9wcyA9IGxhc3RSYXdQcm9wcztcbiAgICAgIG5leHRQcm9wcyA9IG5leHRSYXdQcm9wcztcblxuICAgICAgaWYgKHR5cGVvZiBsYXN0UHJvcHMub25DbGljayAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbmV4dFByb3BzLm9uQ2xpY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVE9ETzogVGhpcyBjYXN0IG1heSBub3QgYmUgc291bmQgZm9yIFNWRywgTWF0aE1MIG9yIGN1c3RvbSBlbGVtZW50cy5cbiAgICAgICAgdHJhcENsaWNrT25Ob25JbnRlcmFjdGl2ZUVsZW1lbnQoZG9tRWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgYXNzZXJ0VmFsaWRQcm9wcyh0YWcsIG5leHRQcm9wcyk7XG4gIHZhciBwcm9wS2V5O1xuICB2YXIgc3R5bGVOYW1lO1xuICB2YXIgc3R5bGVVcGRhdGVzID0gbnVsbDtcblxuICBmb3IgKHByb3BLZXkgaW4gbGFzdFByb3BzKSB7XG4gICAgaWYgKG5leHRQcm9wcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSB8fCAhbGFzdFByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpIHx8IGxhc3RQcm9wc1twcm9wS2V5XSA9PSBudWxsKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAocHJvcEtleSA9PT0gU1RZTEUpIHtcbiAgICAgIHZhciBsYXN0U3R5bGUgPSBsYXN0UHJvcHNbcHJvcEtleV07XG5cbiAgICAgIGZvciAoc3R5bGVOYW1lIGluIGxhc3RTdHlsZSkge1xuICAgICAgICBpZiAobGFzdFN0eWxlLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpIHtcbiAgICAgICAgICBpZiAoIXN0eWxlVXBkYXRlcykge1xuICAgICAgICAgICAgc3R5bGVVcGRhdGVzID0ge307XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3R5bGVVcGRhdGVzW3N0eWxlTmFtZV0gPSAnJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwgfHwgcHJvcEtleSA9PT0gQ0hJTERSRU4pIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gU1VQUFJFU1NfQ09OVEVOVF9FRElUQUJMRV9XQVJOSU5HIHx8IHByb3BLZXkgPT09IFNVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HKSA7IGVsc2UgaWYgKHByb3BLZXkgPT09IEFVVE9GT0NVUykgOyBlbHNlIGlmIChyZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICAvLyBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlLiBJZiBhbnkgbGlzdGVuZXIgdXBkYXRlcyB3ZSBuZWVkIHRvIGVuc3VyZVxuICAgICAgLy8gdGhhdCB0aGUgXCJjdXJyZW50XCIgZmliZXIgcG9pbnRlciBnZXRzIHVwZGF0ZWQgc28gd2UgbmVlZCBhIGNvbW1pdFxuICAgICAgLy8gdG8gdXBkYXRlIHRoaXMgZWxlbWVudC5cbiAgICAgIGlmICghdXBkYXRlUGF5bG9hZCkge1xuICAgICAgICB1cGRhdGVQYXlsb2FkID0gW107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciBhbGwgb3RoZXIgZGVsZXRlZCBwcm9wZXJ0aWVzIHdlIGFkZCBpdCB0byB0aGUgcXVldWUuIFdlIHVzZVxuICAgICAgLy8gdGhlIGFsbG93ZWQgcHJvcGVydHkgbGlzdCBpbiB0aGUgY29tbWl0IHBoYXNlIGluc3RlYWQuXG4gICAgICAodXBkYXRlUGF5bG9hZCA9IHVwZGF0ZVBheWxvYWQgfHwgW10pLnB1c2gocHJvcEtleSwgbnVsbCk7XG4gICAgfVxuICB9XG5cbiAgZm9yIChwcm9wS2V5IGluIG5leHRQcm9wcykge1xuICAgIHZhciBuZXh0UHJvcCA9IG5leHRQcm9wc1twcm9wS2V5XTtcbiAgICB2YXIgbGFzdFByb3AgPSBsYXN0UHJvcHMgIT0gbnVsbCA/IGxhc3RQcm9wc1twcm9wS2V5XSA6IHVuZGVmaW5lZDtcblxuICAgIGlmICghbmV4dFByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpIHx8IG5leHRQcm9wID09PSBsYXN0UHJvcCB8fCBuZXh0UHJvcCA9PSBudWxsICYmIGxhc3RQcm9wID09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAge1xuICAgICAgICBpZiAobmV4dFByb3ApIHtcbiAgICAgICAgICAvLyBGcmVlemUgdGhlIG5leHQgc3R5bGUgb2JqZWN0IHNvIHRoYXQgd2UgY2FuIGFzc3VtZSBpdCB3b24ndCBiZVxuICAgICAgICAgIC8vIG11dGF0ZWQuIFdlIGhhdmUgYWxyZWFkeSB3YXJuZWQgZm9yIHRoaXMgaW4gdGhlIHBhc3QuXG4gICAgICAgICAgT2JqZWN0LmZyZWV6ZShuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGxhc3RQcm9wKSB7XG4gICAgICAgIC8vIFVuc2V0IHN0eWxlcyBvbiBgbGFzdFByb3BgIGJ1dCBub3Qgb24gYG5leHRQcm9wYC5cbiAgICAgICAgZm9yIChzdHlsZU5hbWUgaW4gbGFzdFByb3ApIHtcbiAgICAgICAgICBpZiAobGFzdFByb3AuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSAmJiAoIW5leHRQcm9wIHx8ICFuZXh0UHJvcC5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpKSkge1xuICAgICAgICAgICAgaWYgKCFzdHlsZVVwZGF0ZXMpIHtcbiAgICAgICAgICAgICAgc3R5bGVVcGRhdGVzID0ge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0eWxlVXBkYXRlc1tzdHlsZU5hbWVdID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIFVwZGF0ZSBzdHlsZXMgdGhhdCBjaGFuZ2VkIHNpbmNlIGBsYXN0UHJvcGAuXG5cblxuICAgICAgICBmb3IgKHN0eWxlTmFtZSBpbiBuZXh0UHJvcCkge1xuICAgICAgICAgIGlmIChuZXh0UHJvcC5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpICYmIGxhc3RQcm9wW3N0eWxlTmFtZV0gIT09IG5leHRQcm9wW3N0eWxlTmFtZV0pIHtcbiAgICAgICAgICAgIGlmICghc3R5bGVVcGRhdGVzKSB7XG4gICAgICAgICAgICAgIHN0eWxlVXBkYXRlcyA9IHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdHlsZVVwZGF0ZXNbc3R5bGVOYW1lXSA9IG5leHRQcm9wW3N0eWxlTmFtZV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZWxpZXMgb24gYHVwZGF0ZVN0eWxlc0J5SURgIG5vdCBtdXRhdGluZyBgc3R5bGVVcGRhdGVzYC5cbiAgICAgICAgaWYgKCFzdHlsZVVwZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoIXVwZGF0ZVBheWxvYWQpIHtcbiAgICAgICAgICAgIHVwZGF0ZVBheWxvYWQgPSBbXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB1cGRhdGVQYXlsb2FkLnB1c2gocHJvcEtleSwgc3R5bGVVcGRhdGVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0eWxlVXBkYXRlcyA9IG5leHRQcm9wO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgIHZhciBuZXh0SHRtbCA9IG5leHRQcm9wID8gbmV4dFByb3BbSFRNTCQxXSA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciBsYXN0SHRtbCA9IGxhc3RQcm9wID8gbGFzdFByb3BbSFRNTCQxXSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKG5leHRIdG1sICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGxhc3RIdG1sICE9PSBuZXh0SHRtbCkge1xuICAgICAgICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChwcm9wS2V5LCBuZXh0SHRtbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IENISUxEUkVOKSB7XG4gICAgICBpZiAodHlwZW9mIG5leHRQcm9wID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgbmV4dFByb3AgPT09ICdudW1iZXInKSB7XG4gICAgICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChwcm9wS2V5LCAnJyArIG5leHRQcm9wKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IFNVUFBSRVNTX0NPTlRFTlRfRURJVEFCTEVfV0FSTklORyB8fCBwcm9wS2V5ID09PSBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORykgOyBlbHNlIGlmIChyZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICBpZiAobmV4dFByb3AgIT0gbnVsbCkge1xuICAgICAgICAvLyBXZSBlYWdlcmx5IGxpc3RlbiB0byB0aGlzIGV2ZW4gdGhvdWdoIHdlIGhhdmVuJ3QgY29tbWl0dGVkIHlldC5cbiAgICAgICAgaWYgKCB0eXBlb2YgbmV4dFByb3AgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB3YXJuRm9ySW52YWxpZEV2ZW50TGlzdGVuZXIocHJvcEtleSwgbmV4dFByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BLZXkgPT09ICdvblNjcm9sbCcpIHtcbiAgICAgICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdzY3JvbGwnLCBkb21FbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXVwZGF0ZVBheWxvYWQgJiYgbGFzdFByb3AgIT09IG5leHRQcm9wKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UuIElmIGFueSBsaXN0ZW5lciB1cGRhdGVzIHdlIG5lZWQgdG8gZW5zdXJlXG4gICAgICAgIC8vIHRoYXQgdGhlIFwiY3VycmVudFwiIHByb3BzIHBvaW50ZXIgZ2V0cyB1cGRhdGVkIHNvIHdlIG5lZWQgYSBjb21taXRcbiAgICAgICAgLy8gdG8gdXBkYXRlIHRoaXMgZWxlbWVudC5cbiAgICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGb3IgYW55IG90aGVyIHByb3BlcnR5IHdlIGFsd2F5cyBhZGQgaXQgdG8gdGhlIHF1ZXVlIGFuZCB0aGVuIHdlXG4gICAgICAvLyBmaWx0ZXIgaXQgb3V0IHVzaW5nIHRoZSBhbGxvd2VkIHByb3BlcnR5IGxpc3QgZHVyaW5nIHRoZSBjb21taXQuXG4gICAgICAodXBkYXRlUGF5bG9hZCA9IHVwZGF0ZVBheWxvYWQgfHwgW10pLnB1c2gocHJvcEtleSwgbmV4dFByb3ApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdHlsZVVwZGF0ZXMpIHtcbiAgICB7XG4gICAgICB2YWxpZGF0ZVNob3J0aGFuZFByb3BlcnR5Q29sbGlzaW9uSW5EZXYoc3R5bGVVcGRhdGVzLCBuZXh0UHJvcHNbU1RZTEVdKTtcbiAgICB9XG5cbiAgICAodXBkYXRlUGF5bG9hZCA9IHVwZGF0ZVBheWxvYWQgfHwgW10pLnB1c2goU1RZTEUsIHN0eWxlVXBkYXRlcyk7XG4gIH1cblxuICByZXR1cm4gdXBkYXRlUGF5bG9hZDtcbn0gLy8gQXBwbHkgdGhlIGRpZmYuXG5cbmZ1bmN0aW9uIHVwZGF0ZVByb3BlcnRpZXMoZG9tRWxlbWVudCwgdXBkYXRlUGF5bG9hZCwgdGFnLCBsYXN0UmF3UHJvcHMsIG5leHRSYXdQcm9wcykge1xuICAvLyBVcGRhdGUgY2hlY2tlZCAqYmVmb3JlKiBuYW1lLlxuICAvLyBJbiB0aGUgbWlkZGxlIG9mIGFuIHVwZGF0ZSwgaXQgaXMgcG9zc2libGUgdG8gaGF2ZSBtdWx0aXBsZSBjaGVja2VkLlxuICAvLyBXaGVuIGEgY2hlY2tlZCByYWRpbyB0cmllcyB0byBjaGFuZ2UgbmFtZSwgYnJvd3NlciBtYWtlcyBhbm90aGVyIHJhZGlvJ3MgY2hlY2tlZCBmYWxzZS5cbiAgaWYgKHRhZyA9PT0gJ2lucHV0JyAmJiBuZXh0UmF3UHJvcHMudHlwZSA9PT0gJ3JhZGlvJyAmJiBuZXh0UmF3UHJvcHMubmFtZSAhPSBudWxsKSB7XG4gICAgdXBkYXRlQ2hlY2tlZChkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICB9XG5cbiAgdmFyIHdhc0N1c3RvbUNvbXBvbmVudFRhZyA9IGlzQ3VzdG9tQ29tcG9uZW50KHRhZywgbGFzdFJhd1Byb3BzKTtcbiAgdmFyIGlzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCBuZXh0UmF3UHJvcHMpOyAvLyBBcHBseSB0aGUgZGlmZi5cblxuICB1cGRhdGVET01Qcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHVwZGF0ZVBheWxvYWQsIHdhc0N1c3RvbUNvbXBvbmVudFRhZywgaXNDdXN0b21Db21wb25lbnRUYWcpOyAvLyBUT0RPOiBFbnN1cmUgdGhhdCBhbiB1cGRhdGUgZ2V0cyBzY2hlZHVsZWQgaWYgYW55IG9mIHRoZSBzcGVjaWFsIHByb3BzXG4gIC8vIGNoYW5nZWQuXG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgICAvLyBVcGRhdGUgdGhlIHdyYXBwZXIgYXJvdW5kIGlucHV0cyAqYWZ0ZXIqIHVwZGF0aW5nIHByb3BzLiBUaGlzIGhhcyB0b1xuICAgICAgLy8gaGFwcGVuIGFmdGVyIGB1cGRhdGVET01Qcm9wZXJ0aWVzYC4gT3RoZXJ3aXNlIEhUTUw1IGlucHV0IHZhbGlkYXRpb25zXG4gICAgICAvLyByYWlzZSB3YXJuaW5ncyBhbmQgcHJldmVudCB0aGUgbmV3IHZhbHVlIGZyb20gYmVpbmcgYXNzaWduZWQuXG4gICAgICB1cGRhdGVXcmFwcGVyKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3RleHRhcmVhJzpcbiAgICAgIHVwZGF0ZVdyYXBwZXIkMShkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgLy8gPHNlbGVjdD4gdmFsdWUgdXBkYXRlIG5lZWRzIHRvIG9jY3VyIGFmdGVyIDxvcHRpb24+IGNoaWxkcmVuXG4gICAgICAvLyByZWNvbmNpbGlhdGlvblxuICAgICAgcG9zdFVwZGF0ZVdyYXBwZXIoZG9tRWxlbWVudCwgbmV4dFJhd1Byb3BzKTtcbiAgICAgIGJyZWFrO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFBvc3NpYmxlU3RhbmRhcmROYW1lKHByb3BOYW1lKSB7XG4gIHtcbiAgICB2YXIgbG93ZXJDYXNlZE5hbWUgPSBwcm9wTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKCFwb3NzaWJsZVN0YW5kYXJkTmFtZXMuaGFzT3duUHJvcGVydHkobG93ZXJDYXNlZE5hbWUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gcG9zc2libGVTdGFuZGFyZE5hbWVzW2xvd2VyQ2FzZWROYW1lXSB8fCBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRpZmZIeWRyYXRlZFByb3BlcnRpZXMoZG9tRWxlbWVudCwgdGFnLCByYXdQcm9wcywgcGFyZW50TmFtZXNwYWNlLCByb290Q29udGFpbmVyRWxlbWVudCwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldikge1xuICB2YXIgaXNDdXN0b21Db21wb25lbnRUYWc7XG4gIHZhciBleHRyYUF0dHJpYnV0ZU5hbWVzO1xuXG4gIHtcbiAgICBpc0N1c3RvbUNvbXBvbmVudFRhZyA9IGlzQ3VzdG9tQ29tcG9uZW50KHRhZywgcmF3UHJvcHMpO1xuICAgIHZhbGlkYXRlUHJvcGVydGllc0luRGV2ZWxvcG1lbnQodGFnLCByYXdQcm9wcyk7XG4gIH0gLy8gVE9ETzogTWFrZSBzdXJlIHRoYXQgd2UgY2hlY2sgaXNNb3VudGVkIGJlZm9yZSBmaXJpbmcgYW55IG9mIHRoZXNlIGV2ZW50cy5cblxuXG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSAnZGlhbG9nJzpcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2NhbmNlbCcsIGRvbUVsZW1lbnQpO1xuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnY2xvc2UnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaWZyYW1lJzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgIGNhc2UgJ2VtYmVkJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBsb2FkIGV2ZW50LlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnbG9hZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd2aWRlbyc6XG4gICAgY2FzZSAnYXVkaW8nOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoZXNlIGV2ZW50cyBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciBhbGwgdGhlIG1lZGlhIGV2ZW50cy5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVkaWFFdmVudFR5cGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQobWVkaWFFdmVudFR5cGVzW2ldLCBkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzb3VyY2UnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGVycm9yIGV2ZW50LlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnZXJyb3InLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaW1nJzpcbiAgICBjYXNlICdpbWFnZSc6XG4gICAgY2FzZSAnbGluayc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIGVycm9yIGFuZCBsb2FkIGV2ZW50cy5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2Vycm9yJywgZG9tRWxlbWVudCk7XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdsb2FkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2RldGFpbHMnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIHRvZ2dsZSBldmVudC5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3RvZ2dsZScsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpbnB1dCc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTsgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGludmFsaWQgZXZlbnQuXG5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2ludmFsaWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgIHZhbGlkYXRlUHJvcHMoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgaW5pdFdyYXBwZXJTdGF0ZSQxKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTsgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGludmFsaWQgZXZlbnQuXG5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2ludmFsaWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgaW5pdFdyYXBwZXJTdGF0ZSQyKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTsgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGludmFsaWQgZXZlbnQuXG5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2ludmFsaWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgYXNzZXJ0VmFsaWRQcm9wcyh0YWcsIHJhd1Byb3BzKTtcblxuICB7XG4gICAgZXh0cmFBdHRyaWJ1dGVOYW1lcyA9IG5ldyBTZXQoKTtcbiAgICB2YXIgYXR0cmlidXRlcyA9IGRvbUVsZW1lbnQuYXR0cmlidXRlcztcblxuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIG5hbWUgPSBhdHRyaWJ1dGVzW19pXS5uYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgICAvLyBDb250cm9sbGVkIGF0dHJpYnV0ZXMgYXJlIG5vdCB2YWxpZGF0ZWRcbiAgICAgICAgLy8gVE9ETzogT25seSBpZ25vcmUgdGhlbSBvbiBjb250cm9sbGVkIHRhZ3MuXG4gICAgICAgIGNhc2UgJ3ZhbHVlJzpcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdjaGVja2VkJzpcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdzZWxlY3RlZCc6XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IHVzZSB0aGUgb3JpZ2luYWwgbmFtZS5cbiAgICAgICAgICAvLyBTZWUgZGlzY3Vzc2lvbiBpbiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8xMDY3Ni5cbiAgICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmFkZChhdHRyaWJ1dGVzW19pXS5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgdXBkYXRlUGF5bG9hZCA9IG51bGw7XG5cbiAgZm9yICh2YXIgcHJvcEtleSBpbiByYXdQcm9wcykge1xuICAgIGlmICghcmF3UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBuZXh0UHJvcCA9IHJhd1Byb3BzW3Byb3BLZXldO1xuXG4gICAgaWYgKHByb3BLZXkgPT09IENISUxEUkVOKSB7XG4gICAgICAvLyBGb3IgdGV4dCBjb250ZW50IGNoaWxkcmVuIHdlIGNvbXBhcmUgYWdhaW5zdCB0ZXh0Q29udGVudC4gVGhpc1xuICAgICAgLy8gbWlnaHQgbWF0Y2ggYWRkaXRpb25hbCBIVE1MIHRoYXQgaXMgaGlkZGVuIHdoZW4gd2UgcmVhZCBpdCB1c2luZ1xuICAgICAgLy8gdGV4dENvbnRlbnQuIEUuZy4gXCJmb29cIiB3aWxsIG1hdGNoIFwiZjxzcGFuPm9vPC9zcGFuPlwiIGJ1dCB0aGF0IHN0aWxsXG4gICAgICAvLyBzYXRpc2ZpZXMgb3VyIHJlcXVpcmVtZW50LiBPdXIgcmVxdWlyZW1lbnQgaXMgbm90IHRvIHByb2R1Y2UgcGVyZmVjdFxuICAgICAgLy8gSFRNTCBhbmQgYXR0cmlidXRlcy4gSWRlYWxseSB3ZSBzaG91bGQgcHJlc2VydmUgc3RydWN0dXJlIGJ1dCBpdCdzXG4gICAgICAvLyBvayBub3QgdG8gaWYgdGhlIHZpc2libGUgY29udGVudCBpcyBzdGlsbCBlbm91Z2ggdG8gaW5kaWNhdGUgd2hhdFxuICAgICAgLy8gZXZlbiBsaXN0ZW5lcnMgdGhlc2Ugbm9kZXMgbWlnaHQgYmUgd2lyZWQgdXAgdG8uXG4gICAgICAvLyBUT0RPOiBXYXJuIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBhIHNpbmdsZSB0ZXh0Tm9kZSBhcyBhIGNoaWxkLlxuICAgICAgLy8gVE9ETzogU2hvdWxkIHdlIHVzZSBkb21FbGVtZW50LmZpcnN0Q2hpbGQubm9kZVZhbHVlIHRvIGNvbXBhcmU/XG4gICAgICBpZiAodHlwZW9mIG5leHRQcm9wID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoZG9tRWxlbWVudC50ZXh0Q29udGVudCAhPT0gbmV4dFByb3ApIHtcbiAgICAgICAgICBpZiAocmF3UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkddICE9PSB0cnVlKSB7XG4gICAgICAgICAgICBjaGVja0ZvclVubWF0Y2hlZFRleHQoZG9tRWxlbWVudC50ZXh0Q29udGVudCwgbmV4dFByb3AsIGlzQ29uY3VycmVudE1vZGUsIHNob3VsZFdhcm5EZXYpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHVwZGF0ZVBheWxvYWQgPSBbQ0hJTERSRU4sIG5leHRQcm9wXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbmV4dFByb3AgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGlmIChkb21FbGVtZW50LnRleHRDb250ZW50ICE9PSAnJyArIG5leHRQcm9wKSB7XG4gICAgICAgICAgaWYgKHJhd1Byb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HXSAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgY2hlY2tGb3JVbm1hdGNoZWRUZXh0KGRvbUVsZW1lbnQudGV4dENvbnRlbnQsIG5leHRQcm9wLCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB1cGRhdGVQYXlsb2FkID0gW0NISUxEUkVOLCAnJyArIG5leHRQcm9wXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSkge1xuICAgICAgaWYgKG5leHRQcm9wICE9IG51bGwpIHtcbiAgICAgICAgaWYgKCB0eXBlb2YgbmV4dFByb3AgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB3YXJuRm9ySW52YWxpZEV2ZW50TGlzdGVuZXIocHJvcEtleSwgbmV4dFByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BLZXkgPT09ICdvblNjcm9sbCcpIHtcbiAgICAgICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdzY3JvbGwnLCBkb21FbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc2hvdWxkV2FybkRldiAmJiB0cnVlICYmIC8vIENvbnZpbmNlIEZsb3cgd2UndmUgY2FsY3VsYXRlZCBpdCAoaXQncyBERVYtb25seSBpbiB0aGlzIG1ldGhvZC4pXG4gICAgdHlwZW9mIGlzQ3VzdG9tQ29tcG9uZW50VGFnID09PSAnYm9vbGVhbicpIHtcbiAgICAgIC8vIFZhbGlkYXRlIHRoYXQgdGhlIHByb3BlcnRpZXMgY29ycmVzcG9uZCB0byB0aGVpciBleHBlY3RlZCB2YWx1ZXMuXG4gICAgICB2YXIgc2VydmVyVmFsdWUgPSB2b2lkIDA7XG4gICAgICB2YXIgcHJvcGVydHlJbmZvID0gaXNDdXN0b21Db21wb25lbnRUYWcgJiYgZW5hYmxlQ3VzdG9tRWxlbWVudFByb3BlcnR5U3VwcG9ydCA/IG51bGwgOiBnZXRQcm9wZXJ0eUluZm8ocHJvcEtleSk7XG5cbiAgICAgIGlmIChyYXdQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklOR10gPT09IHRydWUpIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gU1VQUFJFU1NfQ09OVEVOVF9FRElUQUJMRV9XQVJOSU5HIHx8IHByb3BLZXkgPT09IFNVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HIHx8IC8vIENvbnRyb2xsZWQgYXR0cmlidXRlcyBhcmUgbm90IHZhbGlkYXRlZFxuICAgICAgLy8gVE9ETzogT25seSBpZ25vcmUgdGhlbSBvbiBjb250cm9sbGVkIHRhZ3MuXG4gICAgICBwcm9wS2V5ID09PSAndmFsdWUnIHx8IHByb3BLZXkgPT09ICdjaGVja2VkJyB8fCBwcm9wS2V5ID09PSAnc2VsZWN0ZWQnKSA7IGVsc2UgaWYgKHByb3BLZXkgPT09IERBTkdFUk9VU0xZX1NFVF9JTk5FUl9IVE1MKSB7XG4gICAgICAgIHZhciBzZXJ2ZXJIVE1MID0gZG9tRWxlbWVudC5pbm5lckhUTUw7XG4gICAgICAgIHZhciBuZXh0SHRtbCA9IG5leHRQcm9wID8gbmV4dFByb3BbSFRNTCQxXSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAobmV4dEh0bWwgIT0gbnVsbCkge1xuICAgICAgICAgIHZhciBleHBlY3RlZEhUTUwgPSBub3JtYWxpemVIVE1MKGRvbUVsZW1lbnQsIG5leHRIdG1sKTtcblxuICAgICAgICAgIGlmIChleHBlY3RlZEhUTUwgIT09IHNlcnZlckhUTUwpIHtcbiAgICAgICAgICAgIHdhcm5Gb3JQcm9wRGlmZmVyZW5jZShwcm9wS2V5LCBzZXJ2ZXJIVE1MLCBleHBlY3RlZEhUTUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG4gICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuZGVsZXRlKHByb3BLZXkpO1xuXG4gICAgICAgIGlmIChjYW5EaWZmU3R5bGVGb3JIeWRyYXRpb25XYXJuaW5nKSB7XG4gICAgICAgICAgdmFyIGV4cGVjdGVkU3R5bGUgPSBjcmVhdGVEYW5nZXJvdXNTdHJpbmdGb3JTdHlsZXMobmV4dFByb3ApO1xuICAgICAgICAgIHNlcnZlclZhbHVlID0gZG9tRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJyk7XG5cbiAgICAgICAgICBpZiAoZXhwZWN0ZWRTdHlsZSAhPT0gc2VydmVyVmFsdWUpIHtcbiAgICAgICAgICAgIHdhcm5Gb3JQcm9wRGlmZmVyZW5jZShwcm9wS2V5LCBzZXJ2ZXJWYWx1ZSwgZXhwZWN0ZWRTdHlsZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzQ3VzdG9tQ29tcG9uZW50VGFnICYmICFlbmFibGVDdXN0b21FbGVtZW50UHJvcGVydHlTdXBwb3J0KSB7XG4gICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgZXh0cmFBdHRyaWJ1dGVOYW1lcy5kZWxldGUocHJvcEtleS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgc2VydmVyVmFsdWUgPSBnZXRWYWx1ZUZvckF0dHJpYnV0ZShkb21FbGVtZW50LCBwcm9wS2V5LCBuZXh0UHJvcCk7XG5cbiAgICAgICAgaWYgKG5leHRQcm9wICE9PSBzZXJ2ZXJWYWx1ZSkge1xuICAgICAgICAgIHdhcm5Gb3JQcm9wRGlmZmVyZW5jZShwcm9wS2V5LCBzZXJ2ZXJWYWx1ZSwgbmV4dFByb3ApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFzaG91bGRJZ25vcmVBdHRyaWJ1dGUocHJvcEtleSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykgJiYgIXNob3VsZFJlbW92ZUF0dHJpYnV0ZShwcm9wS2V5LCBuZXh0UHJvcCwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykpIHtcbiAgICAgICAgdmFyIGlzTWlzbWF0Y2hEdWVUb0JhZENhc2luZyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChwcm9wZXJ0eUluZm8gIT09IG51bGwpIHtcbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG4gICAgICAgICAgZXh0cmFBdHRyaWJ1dGVOYW1lcy5kZWxldGUocHJvcGVydHlJbmZvLmF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICAgIHNlcnZlclZhbHVlID0gZ2V0VmFsdWVGb3JQcm9wZXJ0eShkb21FbGVtZW50LCBwcm9wS2V5LCBuZXh0UHJvcCwgcHJvcGVydHlJbmZvKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgb3duTmFtZXNwYWNlID0gcGFyZW50TmFtZXNwYWNlO1xuXG4gICAgICAgICAgaWYgKG93bk5hbWVzcGFjZSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICAgICAgICAgIG93bk5hbWVzcGFjZSA9IGdldEludHJpbnNpY05hbWVzcGFjZSh0YWcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChvd25OYW1lc3BhY2UgPT09IEhUTUxfTkFNRVNQQUNFKSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG4gICAgICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmRlbGV0ZShwcm9wS2V5LnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgc3RhbmRhcmROYW1lID0gZ2V0UG9zc2libGVTdGFuZGFyZE5hbWUocHJvcEtleSk7XG5cbiAgICAgICAgICAgIGlmIChzdGFuZGFyZE5hbWUgIT09IG51bGwgJiYgc3RhbmRhcmROYW1lICE9PSBwcm9wS2V5KSB7XG4gICAgICAgICAgICAgIC8vIElmIGFuIFNWRyBwcm9wIGlzIHN1cHBsaWVkIHdpdGggYmFkIGNhc2luZywgaXQgd2lsbFxuICAgICAgICAgICAgICAvLyBiZSBzdWNjZXNzZnVsbHkgcGFyc2VkIGZyb20gSFRNTCwgYnV0IHdpbGwgcHJvZHVjZSBhIG1pc21hdGNoXG4gICAgICAgICAgICAgIC8vIChhbmQgd291bGQgYmUgaW5jb3JyZWN0bHkgcmVuZGVyZWQgb24gdGhlIGNsaWVudCkuXG4gICAgICAgICAgICAgIC8vIEhvd2V2ZXIsIHdlIGFscmVhZHkgd2FybiBhYm91dCBiYWQgY2FzaW5nIGVsc2V3aGVyZS5cbiAgICAgICAgICAgICAgLy8gU28gd2UnbGwgc2tpcCB0aGUgbWlzbGVhZGluZyBleHRyYSBtaXNtYXRjaCB3YXJuaW5nIGluIHRoaXMgY2FzZS5cbiAgICAgICAgICAgICAgaXNNaXNtYXRjaER1ZVRvQmFkQ2FzaW5nID0gdHJ1ZTsgLy8gJEZsb3dGaXhNZSAtIFNob3VsZCBiZSBpbmZlcnJlZCBhcyBub3QgdW5kZWZpbmVkLlxuXG4gICAgICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuZGVsZXRlKHN0YW5kYXJkTmFtZSk7XG4gICAgICAgICAgICB9IC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cblxuXG4gICAgICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmRlbGV0ZShwcm9wS2V5KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzZXJ2ZXJWYWx1ZSA9IGdldFZhbHVlRm9yQXR0cmlidXRlKGRvbUVsZW1lbnQsIHByb3BLZXksIG5leHRQcm9wKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkb250V2FybkN1c3RvbUVsZW1lbnQgPSBlbmFibGVDdXN0b21FbGVtZW50UHJvcGVydHlTdXBwb3J0ICA7XG5cbiAgICAgICAgaWYgKCFkb250V2FybkN1c3RvbUVsZW1lbnQgJiYgbmV4dFByb3AgIT09IHNlcnZlclZhbHVlICYmICFpc01pc21hdGNoRHVlVG9CYWRDYXNpbmcpIHtcbiAgICAgICAgICB3YXJuRm9yUHJvcERpZmZlcmVuY2UocHJvcEtleSwgc2VydmVyVmFsdWUsIG5leHRQcm9wKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHtcbiAgICBpZiAoc2hvdWxkV2FybkRldikge1xuICAgICAgaWYgKCAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG4gICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLnNpemUgPiAwICYmIHJhd1Byb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HXSAhPT0gdHJ1ZSkge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG4gICAgICAgIHdhcm5Gb3JFeHRyYUF0dHJpYnV0ZXMoZXh0cmFBdHRyaWJ1dGVOYW1lcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgd2UgY2hlY2sgaWYgdGhpcyBpcyBzdGlsbCB1bm1vdW50ZWQgb3IgZG8gYW55IGNsZWFuXG4gICAgICAvLyB1cCBuZWNlc3Nhcnkgc2luY2Ugd2UgbmV2ZXIgc3RvcCB0cmFja2luZyBhbnltb3JlLlxuICAgICAgdHJhY2soZG9tRWxlbWVudCk7XG4gICAgICBwb3N0TW91bnRXcmFwcGVyKGRvbUVsZW1lbnQsIHJhd1Byb3BzLCB0cnVlKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgLy8gVE9ETzogTWFrZSBzdXJlIHdlIGNoZWNrIGlmIHRoaXMgaXMgc3RpbGwgdW5tb3VudGVkIG9yIGRvIGFueSBjbGVhblxuICAgICAgLy8gdXAgbmVjZXNzYXJ5IHNpbmNlIHdlIG5ldmVyIHN0b3AgdHJhY2tpbmcgYW55bW9yZS5cbiAgICAgIHRyYWNrKGRvbUVsZW1lbnQpO1xuICAgICAgcG9zdE1vdW50V3JhcHBlciQzKGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgIGNhc2UgJ29wdGlvbic6XG4gICAgICAvLyBGb3IgaW5wdXQgYW5kIHRleHRhcmVhIHdlIGN1cnJlbnQgYWx3YXlzIHNldCB0aGUgdmFsdWUgcHJvcGVydHkgYXRcbiAgICAgIC8vIHBvc3QgbW91bnQgdG8gZm9yY2UgaXQgdG8gZGl2ZXJnZSBmcm9tIGF0dHJpYnV0ZXMuIEhvd2V2ZXIsIGZvclxuICAgICAgLy8gb3B0aW9uIGFuZCBzZWxlY3Qgd2UgZG9uJ3QgcXVpdGUgZG8gdGhlIHNhbWUgdGhpbmcgYW5kIHNlbGVjdFxuICAgICAgLy8gaXMgbm90IHJlc2lsaWVudCB0byB0aGUgRE9NIHN0YXRlIGNoYW5naW5nIHNvIHdlIGRvbid0IGRvIHRoYXQgaGVyZS5cbiAgICAgIC8vIFRPRE86IENvbnNpZGVyIG5vdCBkb2luZyB0aGlzIGZvciBpbnB1dCBhbmQgdGV4dGFyZWEuXG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBpZiAodHlwZW9mIHJhd1Byb3BzLm9uQ2xpY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVE9ETzogVGhpcyBjYXN0IG1heSBub3QgYmUgc291bmQgZm9yIFNWRywgTWF0aE1MIG9yIGN1c3RvbSBlbGVtZW50cy5cbiAgICAgICAgdHJhcENsaWNrT25Ob25JbnRlcmFjdGl2ZUVsZW1lbnQoZG9tRWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZVBheWxvYWQ7XG59XG5mdW5jdGlvbiBkaWZmSHlkcmF0ZWRUZXh0KHRleHROb2RlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlKSB7XG4gIHZhciBpc0RpZmZlcmVudCA9IHRleHROb2RlLm5vZGVWYWx1ZSAhPT0gdGV4dDtcbiAgcmV0dXJuIGlzRGlmZmVyZW50O1xufVxuZnVuY3Rpb24gd2FybkZvckRlbGV0ZWRIeWRyYXRhYmxlRWxlbWVudChwYXJlbnROb2RlLCBjaGlsZCkge1xuICB7XG4gICAgaWYgKGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkludmFsaWRIeWRyYXRpb24gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ0RpZCBub3QgZXhwZWN0IHNlcnZlciBIVE1MIHRvIGNvbnRhaW4gYSA8JXM+IGluIDwlcz4uJywgY2hpbGQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSwgcGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gd2FybkZvckRlbGV0ZWRIeWRyYXRhYmxlVGV4dChwYXJlbnROb2RlLCBjaGlsZCkge1xuICB7XG4gICAgaWYgKGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkludmFsaWRIeWRyYXRpb24gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ0RpZCBub3QgZXhwZWN0IHNlcnZlciBIVE1MIHRvIGNvbnRhaW4gdGhlIHRleHQgbm9kZSBcIiVzXCIgaW4gPCVzPi4nLCBjaGlsZC5ub2RlVmFsdWUsIHBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkRWxlbWVudChwYXJlbnROb2RlLCB0YWcsIHByb3BzKSB7XG4gIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICBlcnJvcignRXhwZWN0ZWQgc2VydmVyIEhUTUwgdG8gY29udGFpbiBhIG1hdGNoaW5nIDwlcz4gaW4gPCVzPi4nLCB0YWcsIHBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkVGV4dChwYXJlbnROb2RlLCB0ZXh0KSB7XG4gIHtcbiAgICBpZiAodGV4dCA9PT0gJycpIHtcbiAgICAgIC8vIFdlIGV4cGVjdCB0byBpbnNlcnQgZW1wdHkgdGV4dCBub2RlcyBzaW5jZSB0aGV5J3JlIG5vdCByZXByZXNlbnRlZCBpblxuICAgICAgLy8gdGhlIEhUTUwuXG4gICAgICAvLyBUT0RPOiBSZW1vdmUgdGhpcyBzcGVjaWFsIGNhc2UgaWYgd2UgY2FuIGp1c3QgYXZvaWQgaW5zZXJ0aW5nIGVtcHR5XG4gICAgICAvLyB0ZXh0IG5vZGVzLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgIGVycm9yKCdFeHBlY3RlZCBzZXJ2ZXIgSFRNTCB0byBjb250YWluIGEgbWF0Y2hpbmcgdGV4dCBub2RlIGZvciBcIiVzXCIgaW4gPCVzPi4nLCB0ZXh0LCBwYXJlbnROb2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpO1xuICB9XG59XG5mdW5jdGlvbiByZXN0b3JlQ29udHJvbGxlZFN0YXRlJDMoZG9tRWxlbWVudCwgdGFnLCBwcm9wcykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIHJlc3RvcmVDb250cm9sbGVkU3RhdGUoZG9tRWxlbWVudCwgcHJvcHMpO1xuICAgICAgcmV0dXJuO1xuXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZSQyKGRvbUVsZW1lbnQsIHByb3BzKTtcbiAgICAgIHJldHVybjtcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICByZXN0b3JlQ29udHJvbGxlZFN0YXRlJDEoZG9tRWxlbWVudCwgcHJvcHMpO1xuICAgICAgcmV0dXJuO1xuICB9XG59XG5cbnZhciB2YWxpZGF0ZURPTU5lc3RpbmcgPSBmdW5jdGlvbiAoKSB7fTtcblxudmFyIHVwZGF0ZWRBbmNlc3RvckluZm8gPSBmdW5jdGlvbiAoKSB7fTtcblxue1xuICAvLyBUaGlzIHZhbGlkYXRpb24gY29kZSB3YXMgd3JpdHRlbiBiYXNlZCBvbiB0aGUgSFRNTDUgcGFyc2luZyBzcGVjOlxuICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNoYXMtYW4tZWxlbWVudC1pbi1zY29wZVxuICAvL1xuICAvLyBOb3RlOiB0aGlzIGRvZXMgbm90IGNhdGNoIGFsbCBpbnZhbGlkIG5lc3RpbmcsIG5vciBkb2VzIGl0IHRyeSB0byAoYXMgaXQnc1xuICAvLyBub3QgY2xlYXIgd2hhdCBwcmFjdGljYWwgYmVuZWZpdCBkb2luZyBzbyBwcm92aWRlcyk7IGluc3RlYWQsIHdlIHdhcm4gb25seVxuICAvLyBmb3IgY2FzZXMgd2hlcmUgdGhlIHBhcnNlciB3aWxsIGdpdmUgYSBwYXJzZSB0cmVlIGRpZmZlcmluZyBmcm9tIHdoYXQgUmVhY3RcbiAgLy8gaW50ZW5kZWQuIEZvciBleGFtcGxlLCA8Yj48ZGl2PjwvZGl2PjwvYj4gaXMgaW52YWxpZCBidXQgd2UgZG9uJ3Qgd2FyblxuICAvLyBiZWNhdXNlIGl0IHN0aWxsIHBhcnNlcyBjb3JyZWN0bHk7IHdlIGRvIHdhcm4gZm9yIG90aGVyIGNhc2VzIGxpa2UgbmVzdGVkXG4gIC8vIDxwPiB0YWdzIHdoZXJlIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlY29uZCBlbGVtZW50IGltcGxpY2l0bHkgY2xvc2VzIHRoZVxuICAvLyBmaXJzdCwgY2F1c2luZyBhIGNvbmZ1c2luZyBtZXNzLlxuICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNzcGVjaWFsXG4gIHZhciBzcGVjaWFsVGFncyA9IFsnYWRkcmVzcycsICdhcHBsZXQnLCAnYXJlYScsICdhcnRpY2xlJywgJ2FzaWRlJywgJ2Jhc2UnLCAnYmFzZWZvbnQnLCAnYmdzb3VuZCcsICdibG9ja3F1b3RlJywgJ2JvZHknLCAnYnInLCAnYnV0dG9uJywgJ2NhcHRpb24nLCAnY2VudGVyJywgJ2NvbCcsICdjb2xncm91cCcsICdkZCcsICdkZXRhaWxzJywgJ2RpcicsICdkaXYnLCAnZGwnLCAnZHQnLCAnZW1iZWQnLCAnZmllbGRzZXQnLCAnZmlnY2FwdGlvbicsICdmaWd1cmUnLCAnZm9vdGVyJywgJ2Zvcm0nLCAnZnJhbWUnLCAnZnJhbWVzZXQnLCAnaDEnLCAnaDInLCAnaDMnLCAnaDQnLCAnaDUnLCAnaDYnLCAnaGVhZCcsICdoZWFkZXInLCAnaGdyb3VwJywgJ2hyJywgJ2h0bWwnLCAnaWZyYW1lJywgJ2ltZycsICdpbnB1dCcsICdpc2luZGV4JywgJ2xpJywgJ2xpbmsnLCAnbGlzdGluZycsICdtYWluJywgJ21hcnF1ZWUnLCAnbWVudScsICdtZW51aXRlbScsICdtZXRhJywgJ25hdicsICdub2VtYmVkJywgJ25vZnJhbWVzJywgJ25vc2NyaXB0JywgJ29iamVjdCcsICdvbCcsICdwJywgJ3BhcmFtJywgJ3BsYWludGV4dCcsICdwcmUnLCAnc2NyaXB0JywgJ3NlY3Rpb24nLCAnc2VsZWN0JywgJ3NvdXJjZScsICdzdHlsZScsICdzdW1tYXJ5JywgJ3RhYmxlJywgJ3Rib2R5JywgJ3RkJywgJ3RlbXBsYXRlJywgJ3RleHRhcmVhJywgJ3Rmb290JywgJ3RoJywgJ3RoZWFkJywgJ3RpdGxlJywgJ3RyJywgJ3RyYWNrJywgJ3VsJywgJ3dicicsICd4bXAnXTsgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjaGFzLWFuLWVsZW1lbnQtaW4tc2NvcGVcblxuICB2YXIgaW5TY29wZVRhZ3MgPSBbJ2FwcGxldCcsICdjYXB0aW9uJywgJ2h0bWwnLCAndGFibGUnLCAndGQnLCAndGgnLCAnbWFycXVlZScsICdvYmplY3QnLCAndGVtcGxhdGUnLCAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNodG1sLWludGVncmF0aW9uLXBvaW50XG4gIC8vIFRPRE86IERpc3Rpbmd1aXNoIGJ5IG5hbWVzcGFjZSBoZXJlIC0tIGZvciA8dGl0bGU+LCBpbmNsdWRpbmcgaXQgaGVyZVxuICAvLyBlcnJzIG9uIHRoZSBzaWRlIG9mIGZld2VyIHdhcm5pbmdzXG4gICdmb3JlaWduT2JqZWN0JywgJ2Rlc2MnLCAndGl0bGUnXTsgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjaGFzLWFuLWVsZW1lbnQtaW4tYnV0dG9uLXNjb3BlXG5cbiAgdmFyIGJ1dHRvblNjb3BlVGFncyA9IGluU2NvcGVUYWdzLmNvbmNhdChbJ2J1dHRvbiddKTsgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjZ2VuZXJhdGUtaW1wbGllZC1lbmQtdGFnc1xuXG4gIHZhciBpbXBsaWVkRW5kVGFncyA9IFsnZGQnLCAnZHQnLCAnbGknLCAnb3B0aW9uJywgJ29wdGdyb3VwJywgJ3AnLCAncnAnLCAncnQnXTtcbiAgdmFyIGVtcHR5QW5jZXN0b3JJbmZvID0ge1xuICAgIGN1cnJlbnQ6IG51bGwsXG4gICAgZm9ybVRhZzogbnVsbCxcbiAgICBhVGFnSW5TY29wZTogbnVsbCxcbiAgICBidXR0b25UYWdJblNjb3BlOiBudWxsLFxuICAgIG5vYnJUYWdJblNjb3BlOiBudWxsLFxuICAgIHBUYWdJbkJ1dHRvblNjb3BlOiBudWxsLFxuICAgIGxpc3RJdGVtVGFnQXV0b2Nsb3Npbmc6IG51bGwsXG4gICAgZGxJdGVtVGFnQXV0b2Nsb3Npbmc6IG51bGxcbiAgfTtcblxuICB1cGRhdGVkQW5jZXN0b3JJbmZvID0gZnVuY3Rpb24gKG9sZEluZm8sIHRhZykge1xuICAgIHZhciBhbmNlc3RvckluZm8gPSBhc3NpZ24oe30sIG9sZEluZm8gfHwgZW1wdHlBbmNlc3RvckluZm8pO1xuXG4gICAgdmFyIGluZm8gPSB7XG4gICAgICB0YWc6IHRhZ1xuICAgIH07XG5cbiAgICBpZiAoaW5TY29wZVRhZ3MuaW5kZXhPZih0YWcpICE9PSAtMSkge1xuICAgICAgYW5jZXN0b3JJbmZvLmFUYWdJblNjb3BlID0gbnVsbDtcbiAgICAgIGFuY2VzdG9ySW5mby5idXR0b25UYWdJblNjb3BlID0gbnVsbDtcbiAgICAgIGFuY2VzdG9ySW5mby5ub2JyVGFnSW5TY29wZSA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGJ1dHRvblNjb3BlVGFncy5pbmRleE9mKHRhZykgIT09IC0xKSB7XG4gICAgICBhbmNlc3RvckluZm8ucFRhZ0luQnV0dG9uU2NvcGUgPSBudWxsO1xuICAgIH0gLy8gU2VlIHJ1bGVzIGZvciAnbGknLCAnZGQnLCAnZHQnIHN0YXJ0IHRhZ3MgaW5cbiAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5ib2R5XG5cblxuICAgIGlmIChzcGVjaWFsVGFncy5pbmRleE9mKHRhZykgIT09IC0xICYmIHRhZyAhPT0gJ2FkZHJlc3MnICYmIHRhZyAhPT0gJ2RpdicgJiYgdGFnICE9PSAncCcpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5saXN0SXRlbVRhZ0F1dG9jbG9zaW5nID0gbnVsbDtcbiAgICAgIGFuY2VzdG9ySW5mby5kbEl0ZW1UYWdBdXRvY2xvc2luZyA9IG51bGw7XG4gICAgfVxuXG4gICAgYW5jZXN0b3JJbmZvLmN1cnJlbnQgPSBpbmZvO1xuXG4gICAgaWYgKHRhZyA9PT0gJ2Zvcm0nKSB7XG4gICAgICBhbmNlc3RvckluZm8uZm9ybVRhZyA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ2EnKSB7XG4gICAgICBhbmNlc3RvckluZm8uYVRhZ0luU2NvcGUgPSBpbmZvO1xuICAgIH1cblxuICAgIGlmICh0YWcgPT09ICdidXR0b24nKSB7XG4gICAgICBhbmNlc3RvckluZm8uYnV0dG9uVGFnSW5TY29wZSA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ25vYnInKSB7XG4gICAgICBhbmNlc3RvckluZm8ubm9iclRhZ0luU2NvcGUgPSBpbmZvO1xuICAgIH1cblxuICAgIGlmICh0YWcgPT09ICdwJykge1xuICAgICAgYW5jZXN0b3JJbmZvLnBUYWdJbkJ1dHRvblNjb3BlID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnbGknKSB7XG4gICAgICBhbmNlc3RvckluZm8ubGlzdEl0ZW1UYWdBdXRvY2xvc2luZyA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ2RkJyB8fCB0YWcgPT09ICdkdCcpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5kbEl0ZW1UYWdBdXRvY2xvc2luZyA9IGluZm87XG4gICAgfVxuXG4gICAgcmV0dXJuIGFuY2VzdG9ySW5mbztcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlclxuICAgKi9cblxuXG4gIHZhciBpc1RhZ1ZhbGlkV2l0aFBhcmVudCA9IGZ1bmN0aW9uICh0YWcsIHBhcmVudFRhZykge1xuICAgIC8vIEZpcnN0LCBsZXQncyBjaGVjayBpZiB3ZSdyZSBpbiBhbiB1bnVzdWFsIHBhcnNpbmcgbW9kZS4uLlxuICAgIHN3aXRjaCAocGFyZW50VGFnKSB7XG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5zZWxlY3RcbiAgICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdvcHRpb24nIHx8IHRhZyA9PT0gJ29wdGdyb3VwJyB8fCB0YWcgPT09ICcjdGV4dCc7XG5cbiAgICAgIGNhc2UgJ29wdGdyb3VwJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ29wdGlvbicgfHwgdGFnID09PSAnI3RleHQnO1xuICAgICAgLy8gU3RyaWN0bHkgc3BlYWtpbmcsIHNlZWluZyBhbiA8b3B0aW9uPiBkb2Vzbid0IG1lYW4gd2UncmUgaW4gYSA8c2VsZWN0PlxuICAgICAgLy8gYnV0XG5cbiAgICAgIGNhc2UgJ29wdGlvbic6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICcjdGV4dCc7XG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW50ZFxuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWluY2FwdGlvblxuICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvciBzaW5jZSB0aGVzZSBydWxlcyBmYWxsIGJhY2sgdG8gXCJpbiBib2R5XCIgbW9kZSBmb3JcbiAgICAgIC8vIGFsbCBleGNlcHQgc3BlY2lhbCB0YWJsZSBub2RlcyB3aGljaCBjYXVzZSBiYWQgcGFyc2luZyBiZWhhdmlvciBhbnl3YXkuXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW50clxuXG4gICAgICBjYXNlICd0cic6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICd0aCcgfHwgdGFnID09PSAndGQnIHx8IHRhZyA9PT0gJ3N0eWxlJyB8fCB0YWcgPT09ICdzY3JpcHQnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRib2R5XG5cbiAgICAgIGNhc2UgJ3Rib2R5JzpcbiAgICAgIGNhc2UgJ3RoZWFkJzpcbiAgICAgIGNhc2UgJ3Rmb290JzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ3RyJyB8fCB0YWcgPT09ICdzdHlsZScgfHwgdGFnID09PSAnc2NyaXB0JyB8fCB0YWcgPT09ICd0ZW1wbGF0ZSc7XG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5jb2xncm91cFxuXG4gICAgICBjYXNlICdjb2xncm91cCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdjb2wnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRhYmxlXG5cbiAgICAgIGNhc2UgJ3RhYmxlJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2NhcHRpb24nIHx8IHRhZyA9PT0gJ2NvbGdyb3VwJyB8fCB0YWcgPT09ICd0Ym9keScgfHwgdGFnID09PSAndGZvb3QnIHx8IHRhZyA9PT0gJ3RoZWFkJyB8fCB0YWcgPT09ICdzdHlsZScgfHwgdGFnID09PSAnc2NyaXB0JyB8fCB0YWcgPT09ICd0ZW1wbGF0ZSc7XG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5oZWFkXG5cbiAgICAgIGNhc2UgJ2hlYWQnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnYmFzZScgfHwgdGFnID09PSAnYmFzZWZvbnQnIHx8IHRhZyA9PT0gJ2Jnc291bmQnIHx8IHRhZyA9PT0gJ2xpbmsnIHx8IHRhZyA9PT0gJ21ldGEnIHx8IHRhZyA9PT0gJ3RpdGxlJyB8fCB0YWcgPT09ICdub3NjcmlwdCcgfHwgdGFnID09PSAnbm9mcmFtZXMnIHx8IHRhZyA9PT0gJ3N0eWxlJyB8fCB0YWcgPT09ICdzY3JpcHQnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NlbWFudGljcy5odG1sI3RoZS1odG1sLWVsZW1lbnRcblxuICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdoZWFkJyB8fCB0YWcgPT09ICdib2R5JyB8fCB0YWcgPT09ICdmcmFtZXNldCc7XG5cbiAgICAgIGNhc2UgJ2ZyYW1lc2V0JzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2ZyYW1lJztcblxuICAgICAgY2FzZSAnI2RvY3VtZW50JzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2h0bWwnO1xuICAgIH0gLy8gUHJvYmFibHkgaW4gdGhlIFwiaW4gYm9keVwiIHBhcnNpbmcgbW9kZSwgc28gd2Ugb3V0bGF3IG9ubHkgdGFnIGNvbWJvc1xuICAgIC8vIHdoZXJlIHRoZSBwYXJzaW5nIHJ1bGVzIGNhdXNlIGltcGxpY2l0IG9wZW5zIG9yIGNsb3NlcyB0byBiZSBhZGRlZC5cbiAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5ib2R5XG5cblxuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlICdoMSc6XG4gICAgICBjYXNlICdoMic6XG4gICAgICBjYXNlICdoMyc6XG4gICAgICBjYXNlICdoNCc6XG4gICAgICBjYXNlICdoNSc6XG4gICAgICBjYXNlICdoNic6XG4gICAgICAgIHJldHVybiBwYXJlbnRUYWcgIT09ICdoMScgJiYgcGFyZW50VGFnICE9PSAnaDInICYmIHBhcmVudFRhZyAhPT0gJ2gzJyAmJiBwYXJlbnRUYWcgIT09ICdoNCcgJiYgcGFyZW50VGFnICE9PSAnaDUnICYmIHBhcmVudFRhZyAhPT0gJ2g2JztcblxuICAgICAgY2FzZSAncnAnOlxuICAgICAgY2FzZSAncnQnOlxuICAgICAgICByZXR1cm4gaW1wbGllZEVuZFRhZ3MuaW5kZXhPZihwYXJlbnRUYWcpID09PSAtMTtcblxuICAgICAgY2FzZSAnYm9keSc6XG4gICAgICBjYXNlICdjYXB0aW9uJzpcbiAgICAgIGNhc2UgJ2NvbCc6XG4gICAgICBjYXNlICdjb2xncm91cCc6XG4gICAgICBjYXNlICdmcmFtZXNldCc6XG4gICAgICBjYXNlICdmcmFtZSc6XG4gICAgICBjYXNlICdoZWFkJzpcbiAgICAgIGNhc2UgJ2h0bWwnOlxuICAgICAgY2FzZSAndGJvZHknOlxuICAgICAgY2FzZSAndGQnOlxuICAgICAgY2FzZSAndGZvb3QnOlxuICAgICAgY2FzZSAndGgnOlxuICAgICAgY2FzZSAndGhlYWQnOlxuICAgICAgY2FzZSAndHInOlxuICAgICAgICAvLyBUaGVzZSB0YWdzIGFyZSBvbmx5IHZhbGlkIHdpdGggYSBmZXcgcGFyZW50cyB0aGF0IGhhdmUgc3BlY2lhbCBjaGlsZFxuICAgICAgICAvLyBwYXJzaW5nIHJ1bGVzIC0tIGlmIHdlJ3JlIGRvd24gaGVyZSwgdGhlbiBub25lIG9mIHRob3NlIG1hdGNoZWQgYW5kXG4gICAgICAgIC8vIHNvIHdlIGFsbG93IGl0IG9ubHkgaWYgd2UgZG9uJ3Qga25vdyB3aGF0IHRoZSBwYXJlbnQgaXMsIGFzIGFsbCBvdGhlclxuICAgICAgICAvLyBjYXNlcyBhcmUgaW52YWxpZC5cbiAgICAgICAgcmV0dXJuIHBhcmVudFRhZyA9PSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyXG4gICAqL1xuXG5cbiAgdmFyIGZpbmRJbnZhbGlkQW5jZXN0b3JGb3JUYWcgPSBmdW5jdGlvbiAodGFnLCBhbmNlc3RvckluZm8pIHtcbiAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgY2FzZSAnYWRkcmVzcyc6XG4gICAgICBjYXNlICdhcnRpY2xlJzpcbiAgICAgIGNhc2UgJ2FzaWRlJzpcbiAgICAgIGNhc2UgJ2Jsb2NrcXVvdGUnOlxuICAgICAgY2FzZSAnY2VudGVyJzpcbiAgICAgIGNhc2UgJ2RldGFpbHMnOlxuICAgICAgY2FzZSAnZGlhbG9nJzpcbiAgICAgIGNhc2UgJ2Rpcic6XG4gICAgICBjYXNlICdkaXYnOlxuICAgICAgY2FzZSAnZGwnOlxuICAgICAgY2FzZSAnZmllbGRzZXQnOlxuICAgICAgY2FzZSAnZmlnY2FwdGlvbic6XG4gICAgICBjYXNlICdmaWd1cmUnOlxuICAgICAgY2FzZSAnZm9vdGVyJzpcbiAgICAgIGNhc2UgJ2hlYWRlcic6XG4gICAgICBjYXNlICdoZ3JvdXAnOlxuICAgICAgY2FzZSAnbWFpbic6XG4gICAgICBjYXNlICdtZW51JzpcbiAgICAgIGNhc2UgJ25hdic6XG4gICAgICBjYXNlICdvbCc6XG4gICAgICBjYXNlICdwJzpcbiAgICAgIGNhc2UgJ3NlY3Rpb24nOlxuICAgICAgY2FzZSAnc3VtbWFyeSc6XG4gICAgICBjYXNlICd1bCc6XG4gICAgICBjYXNlICdwcmUnOlxuICAgICAgY2FzZSAnbGlzdGluZyc6XG4gICAgICBjYXNlICd0YWJsZSc6XG4gICAgICBjYXNlICdocic6XG4gICAgICBjYXNlICd4bXAnOlxuICAgICAgY2FzZSAnaDEnOlxuICAgICAgY2FzZSAnaDInOlxuICAgICAgY2FzZSAnaDMnOlxuICAgICAgY2FzZSAnaDQnOlxuICAgICAgY2FzZSAnaDUnOlxuICAgICAgY2FzZSAnaDYnOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLnBUYWdJbkJ1dHRvblNjb3BlO1xuXG4gICAgICBjYXNlICdmb3JtJzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5mb3JtVGFnIHx8IGFuY2VzdG9ySW5mby5wVGFnSW5CdXR0b25TY29wZTtcblxuICAgICAgY2FzZSAnbGknOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmxpc3RJdGVtVGFnQXV0b2Nsb3Npbmc7XG5cbiAgICAgIGNhc2UgJ2RkJzpcbiAgICAgIGNhc2UgJ2R0JzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5kbEl0ZW1UYWdBdXRvY2xvc2luZztcblxuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5idXR0b25UYWdJblNjb3BlO1xuXG4gICAgICBjYXNlICdhJzpcbiAgICAgICAgLy8gU3BlYyBzYXlzIHNvbWV0aGluZyBhYm91dCBzdG9yaW5nIGEgbGlzdCBvZiBtYXJrZXJzLCBidXQgaXQgc291bmRzXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gdGhpcyBjaGVjay5cbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5hVGFnSW5TY29wZTtcblxuICAgICAgY2FzZSAnbm9icic6XG4gICAgICAgIHJldHVybiBhbmNlc3RvckluZm8ubm9iclRhZ0luU2NvcGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgdmFyIGRpZFdhcm4kMSA9IHt9O1xuXG4gIHZhbGlkYXRlRE9NTmVzdGluZyA9IGZ1bmN0aW9uIChjaGlsZFRhZywgY2hpbGRUZXh0LCBhbmNlc3RvckluZm8pIHtcbiAgICBhbmNlc3RvckluZm8gPSBhbmNlc3RvckluZm8gfHwgZW1wdHlBbmNlc3RvckluZm87XG4gICAgdmFyIHBhcmVudEluZm8gPSBhbmNlc3RvckluZm8uY3VycmVudDtcbiAgICB2YXIgcGFyZW50VGFnID0gcGFyZW50SW5mbyAmJiBwYXJlbnRJbmZvLnRhZztcblxuICAgIGlmIChjaGlsZFRleHQgIT0gbnVsbCkge1xuICAgICAgaWYgKGNoaWxkVGFnICE9IG51bGwpIHtcbiAgICAgICAgZXJyb3IoJ3ZhbGlkYXRlRE9NTmVzdGluZzogd2hlbiBjaGlsZFRleHQgaXMgcGFzc2VkLCBjaGlsZFRhZyBzaG91bGQgYmUgbnVsbCcpO1xuICAgICAgfVxuXG4gICAgICBjaGlsZFRhZyA9ICcjdGV4dCc7XG4gICAgfVxuXG4gICAgdmFyIGludmFsaWRQYXJlbnQgPSBpc1RhZ1ZhbGlkV2l0aFBhcmVudChjaGlsZFRhZywgcGFyZW50VGFnKSA/IG51bGwgOiBwYXJlbnRJbmZvO1xuICAgIHZhciBpbnZhbGlkQW5jZXN0b3IgPSBpbnZhbGlkUGFyZW50ID8gbnVsbCA6IGZpbmRJbnZhbGlkQW5jZXN0b3JGb3JUYWcoY2hpbGRUYWcsIGFuY2VzdG9ySW5mbyk7XG4gICAgdmFyIGludmFsaWRQYXJlbnRPckFuY2VzdG9yID0gaW52YWxpZFBhcmVudCB8fCBpbnZhbGlkQW5jZXN0b3I7XG5cbiAgICBpZiAoIWludmFsaWRQYXJlbnRPckFuY2VzdG9yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGFuY2VzdG9yVGFnID0gaW52YWxpZFBhcmVudE9yQW5jZXN0b3IudGFnO1xuICAgIHZhciB3YXJuS2V5ID0gISFpbnZhbGlkUGFyZW50ICsgJ3wnICsgY2hpbGRUYWcgKyAnfCcgKyBhbmNlc3RvclRhZztcblxuICAgIGlmIChkaWRXYXJuJDFbd2FybktleV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuJDFbd2FybktleV0gPSB0cnVlO1xuICAgIHZhciB0YWdEaXNwbGF5TmFtZSA9IGNoaWxkVGFnO1xuICAgIHZhciB3aGl0ZXNwYWNlSW5mbyA9ICcnO1xuXG4gICAgaWYgKGNoaWxkVGFnID09PSAnI3RleHQnKSB7XG4gICAgICBpZiAoL1xcUy8udGVzdChjaGlsZFRleHQpKSB7XG4gICAgICAgIHRhZ0Rpc3BsYXlOYW1lID0gJ1RleHQgbm9kZXMnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFnRGlzcGxheU5hbWUgPSAnV2hpdGVzcGFjZSB0ZXh0IG5vZGVzJztcbiAgICAgICAgd2hpdGVzcGFjZUluZm8gPSBcIiBNYWtlIHN1cmUgeW91IGRvbid0IGhhdmUgYW55IGV4dHJhIHdoaXRlc3BhY2UgYmV0d2VlbiB0YWdzIG9uIFwiICsgJ2VhY2ggbGluZSBvZiB5b3VyIHNvdXJjZSBjb2RlLic7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhZ0Rpc3BsYXlOYW1lID0gJzwnICsgY2hpbGRUYWcgKyAnPic7XG4gICAgfVxuXG4gICAgaWYgKGludmFsaWRQYXJlbnQpIHtcbiAgICAgIHZhciBpbmZvID0gJyc7XG5cbiAgICAgIGlmIChhbmNlc3RvclRhZyA9PT0gJ3RhYmxlJyAmJiBjaGlsZFRhZyA9PT0gJ3RyJykge1xuICAgICAgICBpbmZvICs9ICcgQWRkIGEgPHRib2R5PiwgPHRoZWFkPiBvciA8dGZvb3Q+IHRvIHlvdXIgY29kZSB0byBtYXRjaCB0aGUgRE9NIHRyZWUgZ2VuZXJhdGVkIGJ5ICcgKyAndGhlIGJyb3dzZXIuJztcbiAgICAgIH1cblxuICAgICAgZXJyb3IoJ3ZhbGlkYXRlRE9NTmVzdGluZyguLi4pOiAlcyBjYW5ub3QgYXBwZWFyIGFzIGEgY2hpbGQgb2YgPCVzPi4lcyVzJywgdGFnRGlzcGxheU5hbWUsIGFuY2VzdG9yVGFnLCB3aGl0ZXNwYWNlSW5mbywgaW5mbyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yKCd2YWxpZGF0ZURPTU5lc3RpbmcoLi4uKTogJXMgY2Fubm90IGFwcGVhciBhcyBhIGRlc2NlbmRhbnQgb2YgJyArICc8JXM+LicsIHRhZ0Rpc3BsYXlOYW1lLCBhbmNlc3RvclRhZyk7XG4gICAgfVxuICB9O1xufVxuXG52YXIgU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkckMSA9ICdzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcnO1xudmFyIFNVU1BFTlNFX1NUQVJUX0RBVEEgPSAnJCc7XG52YXIgU1VTUEVOU0VfRU5EX0RBVEEgPSAnLyQnO1xudmFyIFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSA9ICckPyc7XG52YXIgU1VTUEVOU0VfRkFMTEJBQ0tfU1RBUlRfREFUQSA9ICckISc7XG52YXIgU1RZTEUkMSA9ICdzdHlsZSc7XG52YXIgZXZlbnRzRW5hYmxlZCA9IG51bGw7XG52YXIgc2VsZWN0aW9uSW5mb3JtYXRpb24gPSBudWxsO1xuZnVuY3Rpb24gZ2V0Um9vdEhvc3RDb250ZXh0KHJvb3RDb250YWluZXJJbnN0YW5jZSkge1xuICB2YXIgdHlwZTtcbiAgdmFyIG5hbWVzcGFjZTtcbiAgdmFyIG5vZGVUeXBlID0gcm9vdENvbnRhaW5lckluc3RhbmNlLm5vZGVUeXBlO1xuXG4gIHN3aXRjaCAobm9kZVR5cGUpIHtcbiAgICBjYXNlIERPQ1VNRU5UX05PREU6XG4gICAgY2FzZSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFOlxuICAgICAge1xuICAgICAgICB0eXBlID0gbm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUgPyAnI2RvY3VtZW50JyA6ICcjZnJhZ21lbnQnO1xuICAgICAgICB2YXIgcm9vdCA9IHJvb3RDb250YWluZXJJbnN0YW5jZS5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIG5hbWVzcGFjZSA9IHJvb3QgPyByb290Lm5hbWVzcGFjZVVSSSA6IGdldENoaWxkTmFtZXNwYWNlKG51bGwsICcnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gbm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSA/IHJvb3RDb250YWluZXJJbnN0YW5jZS5wYXJlbnROb2RlIDogcm9vdENvbnRhaW5lckluc3RhbmNlO1xuICAgICAgICB2YXIgb3duTmFtZXNwYWNlID0gY29udGFpbmVyLm5hbWVzcGFjZVVSSSB8fCBudWxsO1xuICAgICAgICB0eXBlID0gY29udGFpbmVyLnRhZ05hbWU7XG4gICAgICAgIG5hbWVzcGFjZSA9IGdldENoaWxkTmFtZXNwYWNlKG93bk5hbWVzcGFjZSwgdHlwZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG5cbiAge1xuICAgIHZhciB2YWxpZGF0ZWRUYWcgPSB0eXBlLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFyIGFuY2VzdG9ySW5mbyA9IHVwZGF0ZWRBbmNlc3RvckluZm8obnVsbCwgdmFsaWRhdGVkVGFnKTtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZXNwYWNlOiBuYW1lc3BhY2UsXG4gICAgICBhbmNlc3RvckluZm86IGFuY2VzdG9ySW5mb1xuICAgIH07XG4gIH1cbn1cbmZ1bmN0aW9uIGdldENoaWxkSG9zdENvbnRleHQocGFyZW50SG9zdENvbnRleHQsIHR5cGUsIHJvb3RDb250YWluZXJJbnN0YW5jZSkge1xuICB7XG4gICAgdmFyIHBhcmVudEhvc3RDb250ZXh0RGV2ID0gcGFyZW50SG9zdENvbnRleHQ7XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldENoaWxkTmFtZXNwYWNlKHBhcmVudEhvc3RDb250ZXh0RGV2Lm5hbWVzcGFjZSwgdHlwZSk7XG4gICAgdmFyIGFuY2VzdG9ySW5mbyA9IHVwZGF0ZWRBbmNlc3RvckluZm8ocGFyZW50SG9zdENvbnRleHREZXYuYW5jZXN0b3JJbmZvLCB0eXBlKTtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZXNwYWNlOiBuYW1lc3BhY2UsXG4gICAgICBhbmNlc3RvckluZm86IGFuY2VzdG9ySW5mb1xuICAgIH07XG4gIH1cbn1cbmZ1bmN0aW9uIGdldFB1YmxpY0luc3RhbmNlKGluc3RhbmNlKSB7XG4gIHJldHVybiBpbnN0YW5jZTtcbn1cbmZ1bmN0aW9uIHByZXBhcmVGb3JDb21taXQoY29udGFpbmVySW5mbykge1xuICBldmVudHNFbmFibGVkID0gaXNFbmFibGVkKCk7XG4gIHNlbGVjdGlvbkluZm9ybWF0aW9uID0gZ2V0U2VsZWN0aW9uSW5mb3JtYXRpb24oKTtcbiAgdmFyIGFjdGl2ZUluc3RhbmNlID0gbnVsbDtcblxuICBzZXRFbmFibGVkKGZhbHNlKTtcbiAgcmV0dXJuIGFjdGl2ZUluc3RhbmNlO1xufVxuZnVuY3Rpb24gcmVzZXRBZnRlckNvbW1pdChjb250YWluZXJJbmZvKSB7XG4gIHJlc3RvcmVTZWxlY3Rpb24oc2VsZWN0aW9uSW5mb3JtYXRpb24pO1xuICBzZXRFbmFibGVkKGV2ZW50c0VuYWJsZWQpO1xuICBldmVudHNFbmFibGVkID0gbnVsbDtcbiAgc2VsZWN0aW9uSW5mb3JtYXRpb24gPSBudWxsO1xufVxuZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2UodHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAgdmFyIHBhcmVudE5hbWVzcGFjZTtcblxuICB7XG4gICAgLy8gVE9ETzogdGFrZSBuYW1lc3BhY2UgaW50byBhY2NvdW50IHdoZW4gdmFsaWRhdGluZy5cbiAgICB2YXIgaG9zdENvbnRleHREZXYgPSBob3N0Q29udGV4dDtcbiAgICB2YWxpZGF0ZURPTU5lc3RpbmcodHlwZSwgbnVsbCwgaG9zdENvbnRleHREZXYuYW5jZXN0b3JJbmZvKTtcblxuICAgIGlmICh0eXBlb2YgcHJvcHMuY2hpbGRyZW4gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ251bWJlcicpIHtcbiAgICAgIHZhciBzdHJpbmcgPSAnJyArIHByb3BzLmNoaWxkcmVuO1xuICAgICAgdmFyIG93bkFuY2VzdG9ySW5mbyA9IHVwZGF0ZWRBbmNlc3RvckluZm8oaG9zdENvbnRleHREZXYuYW5jZXN0b3JJbmZvLCB0eXBlKTtcbiAgICAgIHZhbGlkYXRlRE9NTmVzdGluZyhudWxsLCBzdHJpbmcsIG93bkFuY2VzdG9ySW5mbyk7XG4gICAgfVxuXG4gICAgcGFyZW50TmFtZXNwYWNlID0gaG9zdENvbnRleHREZXYubmFtZXNwYWNlO1xuICB9XG5cbiAgdmFyIGRvbUVsZW1lbnQgPSBjcmVhdGVFbGVtZW50KHR5cGUsIHByb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UsIHBhcmVudE5hbWVzcGFjZSk7XG4gIHByZWNhY2hlRmliZXJOb2RlKGludGVybmFsSW5zdGFuY2VIYW5kbGUsIGRvbUVsZW1lbnQpO1xuICB1cGRhdGVGaWJlclByb3BzKGRvbUVsZW1lbnQsIHByb3BzKTtcbiAgcmV0dXJuIGRvbUVsZW1lbnQ7XG59XG5mdW5jdGlvbiBhcHBlbmRJbml0aWFsQ2hpbGQocGFyZW50SW5zdGFuY2UsIGNoaWxkKSB7XG4gIHBhcmVudEluc3RhbmNlLmFwcGVuZENoaWxkKGNoaWxkKTtcbn1cbmZ1bmN0aW9uIGZpbmFsaXplSW5pdGlhbENoaWxkcmVuKGRvbUVsZW1lbnQsIHR5cGUsIHByb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UsIGhvc3RDb250ZXh0KSB7XG4gIHNldEluaXRpYWxQcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHR5cGUsIHByb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UpO1xuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgcmV0dXJuICEhcHJvcHMuYXV0b0ZvY3VzO1xuXG4gICAgY2FzZSAnaW1nJzpcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gcHJlcGFyZVVwZGF0ZShkb21FbGVtZW50LCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQpIHtcbiAge1xuICAgIHZhciBob3N0Q29udGV4dERldiA9IGhvc3RDb250ZXh0O1xuXG4gICAgaWYgKHR5cGVvZiBuZXdQcm9wcy5jaGlsZHJlbiAhPT0gdHlwZW9mIG9sZFByb3BzLmNoaWxkcmVuICYmICh0eXBlb2YgbmV3UHJvcHMuY2hpbGRyZW4gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBuZXdQcm9wcy5jaGlsZHJlbiA9PT0gJ251bWJlcicpKSB7XG4gICAgICB2YXIgc3RyaW5nID0gJycgKyBuZXdQcm9wcy5jaGlsZHJlbjtcbiAgICAgIHZhciBvd25BbmNlc3RvckluZm8gPSB1cGRhdGVkQW5jZXN0b3JJbmZvKGhvc3RDb250ZXh0RGV2LmFuY2VzdG9ySW5mbywgdHlwZSk7XG4gICAgICB2YWxpZGF0ZURPTU5lc3RpbmcobnVsbCwgc3RyaW5nLCBvd25BbmNlc3RvckluZm8pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkaWZmUHJvcGVydGllcyhkb21FbGVtZW50LCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMpO1xufVxuZnVuY3Rpb24gc2hvdWxkU2V0VGV4dENvbnRlbnQodHlwZSwgcHJvcHMpIHtcbiAgcmV0dXJuIHR5cGUgPT09ICd0ZXh0YXJlYScgfHwgdHlwZSA9PT0gJ25vc2NyaXB0JyB8fCB0eXBlb2YgcHJvcHMuY2hpbGRyZW4gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MID09PSAnb2JqZWN0JyAmJiBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCAhPT0gbnVsbCAmJiBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTC5fX2h0bWwgIT0gbnVsbDtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVRleHRJbnN0YW5jZSh0ZXh0LCByb290Q29udGFpbmVySW5zdGFuY2UsIGhvc3RDb250ZXh0LCBpbnRlcm5hbEluc3RhbmNlSGFuZGxlKSB7XG4gIHtcbiAgICB2YXIgaG9zdENvbnRleHREZXYgPSBob3N0Q29udGV4dDtcbiAgICB2YWxpZGF0ZURPTU5lc3RpbmcobnVsbCwgdGV4dCwgaG9zdENvbnRleHREZXYuYW5jZXN0b3JJbmZvKTtcbiAgfVxuXG4gIHZhciB0ZXh0Tm9kZSA9IGNyZWF0ZVRleHROb2RlKHRleHQsIHJvb3RDb250YWluZXJJbnN0YW5jZSk7XG4gIHByZWNhY2hlRmliZXJOb2RlKGludGVybmFsSW5zdGFuY2VIYW5kbGUsIHRleHROb2RlKTtcbiAgcmV0dXJuIHRleHROb2RlO1xufVxuZnVuY3Rpb24gZ2V0Q3VycmVudEV2ZW50UHJpb3JpdHkoKSB7XG4gIHZhciBjdXJyZW50RXZlbnQgPSB3aW5kb3cuZXZlbnQ7XG5cbiAgaWYgKGN1cnJlbnRFdmVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIERlZmF1bHRFdmVudFByaW9yaXR5O1xuICB9XG5cbiAgcmV0dXJuIGdldEV2ZW50UHJpb3JpdHkoY3VycmVudEV2ZW50LnR5cGUpO1xufVxuLy8gaWYgYSBjb21wb25lbnQganVzdCBpbXBvcnRzIFJlYWN0RE9NIChlLmcuIGZvciBmaW5kRE9NTm9kZSkuXG4vLyBTb21lIGVudmlyb25tZW50cyBtaWdodCBub3QgaGF2ZSBzZXRUaW1lb3V0IG9yIGNsZWFyVGltZW91dC5cblxudmFyIHNjaGVkdWxlVGltZW91dCA9IHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nID8gc2V0VGltZW91dCA6IHVuZGVmaW5lZDtcbnZhciBjYW5jZWxUaW1lb3V0ID0gdHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IGNsZWFyVGltZW91dCA6IHVuZGVmaW5lZDtcbnZhciBub1RpbWVvdXQgPSAtMTtcbnZhciBsb2NhbFByb21pc2UgPSB0eXBlb2YgUHJvbWlzZSA9PT0gJ2Z1bmN0aW9uJyA/IFByb21pc2UgOiB1bmRlZmluZWQ7IC8vIC0tLS0tLS0tLS0tLS0tLS0tLS1cbnZhciBzY2hlZHVsZU1pY3JvdGFzayA9IHR5cGVvZiBxdWV1ZU1pY3JvdGFzayA9PT0gJ2Z1bmN0aW9uJyA/IHF1ZXVlTWljcm90YXNrIDogdHlwZW9mIGxvY2FsUHJvbWlzZSAhPT0gJ3VuZGVmaW5lZCcgPyBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgcmV0dXJuIGxvY2FsUHJvbWlzZS5yZXNvbHZlKG51bGwpLnRoZW4oY2FsbGJhY2spLmNhdGNoKGhhbmRsZUVycm9ySW5OZXh0VGljayk7XG59IDogc2NoZWR1bGVUaW1lb3V0OyAvLyBUT0RPOiBEZXRlcm1pbmUgdGhlIGJlc3QgZmFsbGJhY2sgaGVyZS5cblxuZnVuY3Rpb24gaGFuZGxlRXJyb3JJbk5leHRUaWNrKGVycm9yKSB7XG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIHRocm93IGVycm9yO1xuICB9KTtcbn0gLy8gLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gY29tbWl0TW91bnQoZG9tRWxlbWVudCwgdHlwZSwgbmV3UHJvcHMsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAgLy8gRGVzcGl0ZSB0aGUgbmFtaW5nIHRoYXQgbWlnaHQgaW1wbHkgb3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCBvbmx5XG4gIC8vIGZpcmVzIGlmIHRoZXJlIGlzIGFuIGBVcGRhdGVgIGVmZmVjdCBzY2hlZHVsZWQgZHVyaW5nIG1vdW50aW5nLlxuICAvLyBUaGlzIGhhcHBlbnMgaWYgYGZpbmFsaXplSW5pdGlhbENoaWxkcmVuYCByZXR1cm5zIGB0cnVlYCAod2hpY2ggaXRcbiAgLy8gZG9lcyB0byBpbXBsZW1lbnQgdGhlIGBhdXRvRm9jdXNgIGF0dHJpYnV0ZSBvbiB0aGUgY2xpZW50KS4gQnV0XG4gIC8vIHRoZXJlIGFyZSBhbHNvIG90aGVyIGNhc2VzIHdoZW4gdGhpcyBtaWdodCBoYXBwZW4gKHN1Y2ggYXMgcGF0Y2hpbmdcbiAgLy8gdXAgdGV4dCBjb250ZW50IGR1cmluZyBoeWRyYXRpb24gbWlzbWF0Y2gpLiBTbyB3ZSdsbCBjaGVjayB0aGlzIGFnYWluLlxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdidXR0b24nOlxuICAgIGNhc2UgJ2lucHV0JzpcbiAgICBjYXNlICdzZWxlY3QnOlxuICAgIGNhc2UgJ3RleHRhcmVhJzpcbiAgICAgIGlmIChuZXdQcm9wcy5hdXRvRm9jdXMpIHtcbiAgICAgICAgZG9tRWxlbWVudC5mb2N1cygpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG5cbiAgICBjYXNlICdpbWcnOlxuICAgICAge1xuICAgICAgICBpZiAobmV3UHJvcHMuc3JjKSB7XG4gICAgICAgICAgZG9tRWxlbWVudC5zcmMgPSBuZXdQcm9wcy5zcmM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNvbW1pdFVwZGF0ZShkb21FbGVtZW50LCB1cGRhdGVQYXlsb2FkLCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAgLy8gQXBwbHkgdGhlIGRpZmYgdG8gdGhlIERPTSBub2RlLlxuICB1cGRhdGVQcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHVwZGF0ZVBheWxvYWQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcyk7IC8vIFVwZGF0ZSB0aGUgcHJvcHMgaGFuZGxlIHNvIHRoYXQgd2Uga25vdyB3aGljaCBwcm9wcyBhcmUgdGhlIG9uZXMgd2l0aFxuICAvLyB3aXRoIGN1cnJlbnQgZXZlbnQgaGFuZGxlcnMuXG5cbiAgdXBkYXRlRmliZXJQcm9wcyhkb21FbGVtZW50LCBuZXdQcm9wcyk7XG59XG5mdW5jdGlvbiByZXNldFRleHRDb250ZW50KGRvbUVsZW1lbnQpIHtcbiAgc2V0VGV4dENvbnRlbnQoZG9tRWxlbWVudCwgJycpO1xufVxuZnVuY3Rpb24gY29tbWl0VGV4dFVwZGF0ZSh0ZXh0SW5zdGFuY2UsIG9sZFRleHQsIG5ld1RleHQpIHtcbiAgdGV4dEluc3RhbmNlLm5vZGVWYWx1ZSA9IG5ld1RleHQ7XG59XG5mdW5jdGlvbiBhcHBlbmRDaGlsZChwYXJlbnRJbnN0YW5jZSwgY2hpbGQpIHtcbiAgcGFyZW50SW5zdGFuY2UuYXBwZW5kQ2hpbGQoY2hpbGQpO1xufVxuZnVuY3Rpb24gYXBwZW5kQ2hpbGRUb0NvbnRhaW5lcihjb250YWluZXIsIGNoaWxkKSB7XG4gIHZhciBwYXJlbnROb2RlO1xuXG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgIHBhcmVudE5vZGUgPSBjb250YWluZXIucGFyZW50Tm9kZTtcbiAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShjaGlsZCwgY29udGFpbmVyKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJlbnROb2RlID0gY29udGFpbmVyO1xuICAgIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICB9IC8vIFRoaXMgY29udGFpbmVyIG1pZ2h0IGJlIHVzZWQgZm9yIGEgcG9ydGFsLlxuICAvLyBJZiBzb21ldGhpbmcgaW5zaWRlIGEgcG9ydGFsIGlzIGNsaWNrZWQsIHRoYXQgY2xpY2sgc2hvdWxkIGJ1YmJsZVxuICAvLyB0aHJvdWdoIHRoZSBSZWFjdCB0cmVlLiBIb3dldmVyLCBvbiBNb2JpbGUgU2FmYXJpIHRoZSBjbGljayB3b3VsZFxuICAvLyBuZXZlciBidWJibGUgdGhyb3VnaCB0aGUgKkRPTSogdHJlZSB1bmxlc3MgYW4gYW5jZXN0b3Igd2l0aCBvbmNsaWNrXG4gIC8vIGV2ZW50IGV4aXN0cy4gU28gd2Ugd291bGRuJ3Qgc2VlIGl0IGFuZCBkaXNwYXRjaCBpdC5cbiAgLy8gVGhpcyBpcyB3aHkgd2UgZW5zdXJlIHRoYXQgbm9uIFJlYWN0IHJvb3QgY29udGFpbmVycyBoYXZlIGlubGluZSBvbmNsaWNrXG4gIC8vIGRlZmluZWQuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTE5MThcblxuXG4gIHZhciByZWFjdFJvb3RDb250YWluZXIgPSBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lcjtcblxuICBpZiAoKHJlYWN0Um9vdENvbnRhaW5lciA9PT0gbnVsbCB8fCByZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZCkgJiYgcGFyZW50Tm9kZS5vbmNsaWNrID09PSBudWxsKSB7XG4gICAgLy8gVE9ETzogVGhpcyBjYXN0IG1heSBub3QgYmUgc291bmQgZm9yIFNWRywgTWF0aE1MIG9yIGN1c3RvbSBlbGVtZW50cy5cbiAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChwYXJlbnROb2RlKTtcbiAgfVxufVxuZnVuY3Rpb24gaW5zZXJ0QmVmb3JlKHBhcmVudEluc3RhbmNlLCBjaGlsZCwgYmVmb3JlQ2hpbGQpIHtcbiAgcGFyZW50SW5zdGFuY2UuaW5zZXJ0QmVmb3JlKGNoaWxkLCBiZWZvcmVDaGlsZCk7XG59XG5mdW5jdGlvbiBpbnNlcnRJbkNvbnRhaW5lckJlZm9yZShjb250YWluZXIsIGNoaWxkLCBiZWZvcmVDaGlsZCkge1xuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICBjb250YWluZXIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZUNoaWxkKTtcbiAgfSBlbHNlIHtcbiAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKGNoaWxkLCBiZWZvcmVDaGlsZCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlQ2hpbGQocGFyZW50SW5zdGFuY2UsIGNoaWxkKSB7XG4gIHBhcmVudEluc3RhbmNlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbn1cbmZ1bmN0aW9uIHJlbW92ZUNoaWxkRnJvbUNvbnRhaW5lcihjb250YWluZXIsIGNoaWxkKSB7XG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgIGNvbnRhaW5lci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbiAgfSBlbHNlIHtcbiAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICB9XG59XG5mdW5jdGlvbiBjbGVhclN1c3BlbnNlQm91bmRhcnkocGFyZW50SW5zdGFuY2UsIHN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgdmFyIG5vZGUgPSBzdXNwZW5zZUluc3RhbmNlOyAvLyBEZWxldGUgYWxsIG5vZGVzIHdpdGhpbiB0aGlzIHN1c3BlbnNlIGJvdW5kYXJ5LlxuICAvLyBUaGVyZSBtaWdodCBiZSBuZXN0ZWQgbm9kZXMgc28gd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIGhvd1xuICAvLyBkZWVwIHdlIGFyZSBhbmQgb25seSBicmVhayBvdXQgd2hlbiB3ZSdyZSBiYWNrIG9uIHRvcC5cblxuICB2YXIgZGVwdGggPSAwO1xuXG4gIGRvIHtcbiAgICB2YXIgbmV4dE5vZGUgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgIHBhcmVudEluc3RhbmNlLnJlbW92ZUNoaWxkKG5vZGUpO1xuXG4gICAgaWYgKG5leHROb2RlICYmIG5leHROb2RlLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICAgIHZhciBkYXRhID0gbmV4dE5vZGUuZGF0YTtcblxuICAgICAgaWYgKGRhdGEgPT09IFNVU1BFTlNFX0VORF9EQVRBKSB7XG4gICAgICAgIGlmIChkZXB0aCA9PT0gMCkge1xuICAgICAgICAgIHBhcmVudEluc3RhbmNlLnJlbW92ZUNoaWxkKG5leHROb2RlKTsgLy8gUmV0cnkgaWYgYW55IGV2ZW50IHJlcGxheWluZyB3YXMgYmxvY2tlZCBvbiB0aGlzLlxuXG4gICAgICAgICAgcmV0cnlJZkJsb2NrZWRPbihzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChkYXRhID09PSBTVVNQRU5TRV9TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSB8fCBkYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBKSB7XG4gICAgICAgIGRlcHRoKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbm9kZSA9IG5leHROb2RlO1xuICB9IHdoaWxlIChub2RlKTsgLy8gVE9ETzogV2Fybiwgd2UgZGlkbid0IGZpbmQgdGhlIGVuZCBjb21tZW50IGJvdW5kYXJ5LlxuICAvLyBSZXRyeSBpZiBhbnkgZXZlbnQgcmVwbGF5aW5nIHdhcyBibG9ja2VkIG9uIHRoaXMuXG5cblxuICByZXRyeUlmQmxvY2tlZE9uKHN1c3BlbnNlSW5zdGFuY2UpO1xufVxuZnVuY3Rpb24gY2xlYXJTdXNwZW5zZUJvdW5kYXJ5RnJvbUNvbnRhaW5lcihjb250YWluZXIsIHN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgY2xlYXJTdXNwZW5zZUJvdW5kYXJ5KGNvbnRhaW5lci5wYXJlbnROb2RlLCBzdXNwZW5zZUluc3RhbmNlKTtcbiAgfSBlbHNlIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgIGNsZWFyU3VzcGVuc2VCb3VuZGFyeShjb250YWluZXIsIHN1c3BlbnNlSW5zdGFuY2UpO1xuICB9IC8vIFJldHJ5IGlmIGFueSBldmVudCByZXBsYXlpbmcgd2FzIGJsb2NrZWQgb24gdGhpcy5cblxuXG4gIHJldHJ5SWZCbG9ja2VkT24oY29udGFpbmVyKTtcbn1cbmZ1bmN0aW9uIGhpZGVJbnN0YW5jZShpbnN0YW5jZSkge1xuICAvLyBUT0RPOiBEb2VzIHRoaXMgd29yayBmb3IgYWxsIGVsZW1lbnQgdHlwZXM/IFdoYXQgYWJvdXQgTWF0aE1MPyBTaG91bGQgd2VcbiAgLy8gcGFzcyBob3N0IGNvbnRleHQgdG8gdGhpcyBtZXRob2Q/XG4gIGluc3RhbmNlID0gaW5zdGFuY2U7XG4gIHZhciBzdHlsZSA9IGluc3RhbmNlLnN0eWxlO1xuXG4gIGlmICh0eXBlb2Ygc3R5bGUuc2V0UHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcbiAgICBzdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdub25lJywgJ2ltcG9ydGFudCcpO1xuICB9IGVsc2Uge1xuICAgIHN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIH1cbn1cbmZ1bmN0aW9uIGhpZGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlKSB7XG4gIHRleHRJbnN0YW5jZS5ub2RlVmFsdWUgPSAnJztcbn1cbmZ1bmN0aW9uIHVuaGlkZUluc3RhbmNlKGluc3RhbmNlLCBwcm9wcykge1xuICBpbnN0YW5jZSA9IGluc3RhbmNlO1xuICB2YXIgc3R5bGVQcm9wID0gcHJvcHNbU1RZTEUkMV07XG4gIHZhciBkaXNwbGF5ID0gc3R5bGVQcm9wICE9PSB1bmRlZmluZWQgJiYgc3R5bGVQcm9wICE9PSBudWxsICYmIHN0eWxlUHJvcC5oYXNPd25Qcm9wZXJ0eSgnZGlzcGxheScpID8gc3R5bGVQcm9wLmRpc3BsYXkgOiBudWxsO1xuICBpbnN0YW5jZS5zdHlsZS5kaXNwbGF5ID0gZGFuZ2Vyb3VzU3R5bGVWYWx1ZSgnZGlzcGxheScsIGRpc3BsYXkpO1xufVxuZnVuY3Rpb24gdW5oaWRlVGV4dEluc3RhbmNlKHRleHRJbnN0YW5jZSwgdGV4dCkge1xuICB0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlID0gdGV4dDtcbn1cbmZ1bmN0aW9uIGNsZWFyQ29udGFpbmVyKGNvbnRhaW5lcikge1xuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICBjb250YWluZXIudGV4dENvbnRlbnQgPSAnJztcbiAgfSBlbHNlIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUpIHtcbiAgICB2YXIgYm9keSA9IGNvbnRhaW5lci5ib2R5O1xuXG4gICAgaWYgKGJvZHkgIT0gbnVsbCkge1xuICAgICAgYm9keS50ZXh0Q29udGVudCA9ICcnO1xuICAgIH1cbiAgfVxufSAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBjYW5IeWRyYXRlSW5zdGFuY2UoaW5zdGFuY2UsIHR5cGUsIHByb3BzKSB7XG4gIGlmIChpbnN0YW5jZS5ub2RlVHlwZSAhPT0gRUxFTUVOVF9OT0RFIHx8IHR5cGUudG9Mb3dlckNhc2UoKSAhPT0gaW5zdGFuY2Uubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9IC8vIFRoaXMgaGFzIG5vdyBiZWVuIHJlZmluZWQgdG8gYW4gZWxlbWVudCBub2RlLlxuXG5cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuZnVuY3Rpb24gY2FuSHlkcmF0ZVRleHRJbnN0YW5jZShpbnN0YW5jZSwgdGV4dCkge1xuICBpZiAodGV4dCA9PT0gJycgfHwgaW5zdGFuY2Uubm9kZVR5cGUgIT09IFRFWFRfTk9ERSkge1xuICAgIC8vIEVtcHR5IHN0cmluZ3MgYXJlIG5vdCBwYXJzZWQgYnkgSFRNTCBzbyB0aGVyZSB3b24ndCBiZSBhIGNvcnJlY3QgbWF0Y2ggaGVyZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSAvLyBUaGlzIGhhcyBub3cgYmVlbiByZWZpbmVkIHRvIGEgdGV4dCBub2RlLlxuXG5cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuZnVuY3Rpb24gY2FuSHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2UoaW5zdGFuY2UpIHtcbiAgaWYgKGluc3RhbmNlLm5vZGVUeXBlICE9PSBDT01NRU5UX05PREUpIHtcbiAgICAvLyBFbXB0eSBzdHJpbmdzIGFyZSBub3QgcGFyc2VkIGJ5IEhUTUwgc28gdGhlcmUgd29uJ3QgYmUgYSBjb3JyZWN0IG1hdGNoIGhlcmUuXG4gICAgcmV0dXJuIG51bGw7XG4gIH0gLy8gVGhpcyBoYXMgbm93IGJlZW4gcmVmaW5lZCB0byBhIHN1c3BlbnNlIG5vZGUuXG5cblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5mdW5jdGlvbiBpc1N1c3BlbnNlSW5zdGFuY2VQZW5kaW5nKGluc3RhbmNlKSB7XG4gIHJldHVybiBpbnN0YW5jZS5kYXRhID09PSBTVVNQRU5TRV9QRU5ESU5HX1NUQVJUX0RBVEE7XG59XG5mdW5jdGlvbiBpc1N1c3BlbnNlSW5zdGFuY2VGYWxsYmFjayhpbnN0YW5jZSkge1xuICByZXR1cm4gaW5zdGFuY2UuZGF0YSA9PT0gU1VTUEVOU0VfRkFMTEJBQ0tfU1RBUlRfREFUQTtcbn1cbmZ1bmN0aW9uIHJlZ2lzdGVyU3VzcGVuc2VJbnN0YW5jZVJldHJ5KGluc3RhbmNlLCBjYWxsYmFjaykge1xuICBpbnN0YW5jZS5fcmVhY3RSZXRyeSA9IGNhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiBnZXROZXh0SHlkcmF0YWJsZShub2RlKSB7XG4gIC8vIFNraXAgbm9uLWh5ZHJhdGFibGUgbm9kZXMuXG4gIGZvciAoOyBub2RlICE9IG51bGw7IG5vZGUgPSBub2RlLm5leHRTaWJsaW5nKSB7XG4gICAgdmFyIG5vZGVUeXBlID0gbm9kZS5ub2RlVHlwZTtcblxuICAgIGlmIChub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFIHx8IG5vZGVUeXBlID09PSBURVhUX05PREUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgbm9kZURhdGEgPSBub2RlLmRhdGE7XG5cbiAgICAgIGlmIChub2RlRGF0YSA9PT0gU1VTUEVOU0VfU1RBUlRfREFUQSB8fCBub2RlRGF0YSA9PT0gU1VTUEVOU0VfRkFMTEJBQ0tfU1RBUlRfREFUQSB8fCBub2RlRGF0YSA9PT0gU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZURhdGEgPT09IFNVU1BFTlNFX0VORF9EQVRBKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBnZXROZXh0SHlkcmF0YWJsZVNpYmxpbmcoaW5zdGFuY2UpIHtcbiAgcmV0dXJuIGdldE5leHRIeWRyYXRhYmxlKGluc3RhbmNlLm5leHRTaWJsaW5nKTtcbn1cbmZ1bmN0aW9uIGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkKHBhcmVudEluc3RhbmNlKSB7XG4gIHJldHVybiBnZXROZXh0SHlkcmF0YWJsZShwYXJlbnRJbnN0YW5jZS5maXJzdENoaWxkKTtcbn1cbmZ1bmN0aW9uIGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lcikge1xuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGUocGFyZW50Q29udGFpbmVyLmZpcnN0Q2hpbGQpO1xufVxuZnVuY3Rpb24gZ2V0Rmlyc3RIeWRyYXRhYmxlQ2hpbGRXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHBhcmVudEluc3RhbmNlKSB7XG4gIHJldHVybiBnZXROZXh0SHlkcmF0YWJsZShwYXJlbnRJbnN0YW5jZS5uZXh0U2libGluZyk7XG59XG5mdW5jdGlvbiBoeWRyYXRlSW5zdGFuY2UoaW5zdGFuY2UsIHR5cGUsIHByb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UsIGhvc3RDb250ZXh0LCBpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCBzaG91bGRXYXJuRGV2KSB7XG4gIHByZWNhY2hlRmliZXJOb2RlKGludGVybmFsSW5zdGFuY2VIYW5kbGUsIGluc3RhbmNlKTsgLy8gVE9ETzogUG9zc2libHkgZGVmZXIgdGhpcyB1bnRpbCB0aGUgY29tbWl0IHBoYXNlIHdoZXJlIGFsbCB0aGUgZXZlbnRzXG4gIC8vIGdldCBhdHRhY2hlZC5cblxuICB1cGRhdGVGaWJlclByb3BzKGluc3RhbmNlLCBwcm9wcyk7XG4gIHZhciBwYXJlbnROYW1lc3BhY2U7XG5cbiAge1xuICAgIHZhciBob3N0Q29udGV4dERldiA9IGhvc3RDb250ZXh0O1xuICAgIHBhcmVudE5hbWVzcGFjZSA9IGhvc3RDb250ZXh0RGV2Lm5hbWVzcGFjZTtcbiAgfSAvLyBUT0RPOiBUZW1wb3JhcnkgaGFjayB0byBjaGVjayBpZiB3ZSdyZSBpbiBhIGNvbmN1cnJlbnQgcm9vdC4gV2UgY2FuIGRlbGV0ZVxuICAvLyB3aGVuIHRoZSBsZWdhY3kgcm9vdCBBUEkgaXMgcmVtb3ZlZC5cblxuXG4gIHZhciBpc0NvbmN1cnJlbnRNb2RlID0gKGludGVybmFsSW5zdGFuY2VIYW5kbGUubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlO1xuICByZXR1cm4gZGlmZkh5ZHJhdGVkUHJvcGVydGllcyhpbnN0YW5jZSwgdHlwZSwgcHJvcHMsIHBhcmVudE5hbWVzcGFjZSwgcm9vdENvbnRhaW5lckluc3RhbmNlLCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KTtcbn1cbmZ1bmN0aW9uIGh5ZHJhdGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlLCB0ZXh0LCBpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCBzaG91bGRXYXJuRGV2KSB7XG4gIHByZWNhY2hlRmliZXJOb2RlKGludGVybmFsSW5zdGFuY2VIYW5kbGUsIHRleHRJbnN0YW5jZSk7IC8vIFRPRE86IFRlbXBvcmFyeSBoYWNrIHRvIGNoZWNrIGlmIHdlJ3JlIGluIGEgY29uY3VycmVudCByb290LiBXZSBjYW4gZGVsZXRlXG4gIC8vIHdoZW4gdGhlIGxlZ2FjeSByb290IEFQSSBpcyByZW1vdmVkLlxuXG4gIHZhciBpc0NvbmN1cnJlbnRNb2RlID0gKGludGVybmFsSW5zdGFuY2VIYW5kbGUubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlO1xuICByZXR1cm4gZGlmZkh5ZHJhdGVkVGV4dCh0ZXh0SW5zdGFuY2UsIHRleHQpO1xufVxuZnVuY3Rpb24gaHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICBwcmVjYWNoZUZpYmVyTm9kZShpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCBzdXNwZW5zZUluc3RhbmNlKTtcbn1cbmZ1bmN0aW9uIGdldE5leHRIeWRyYXRhYmxlSW5zdGFuY2VBZnRlclN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSkge1xuICB2YXIgbm9kZSA9IHN1c3BlbnNlSW5zdGFuY2UubmV4dFNpYmxpbmc7IC8vIFNraXAgcGFzdCBhbGwgbm9kZXMgd2l0aGluIHRoaXMgc3VzcGVuc2UgYm91bmRhcnkuXG4gIC8vIFRoZXJlIG1pZ2h0IGJlIG5lc3RlZCBub2RlcyBzbyB3ZSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgaG93XG4gIC8vIGRlZXAgd2UgYXJlIGFuZCBvbmx5IGJyZWFrIG91dCB3aGVuIHdlJ3JlIGJhY2sgb24gdG9wLlxuXG4gIHZhciBkZXB0aCA9IDA7XG5cbiAgd2hpbGUgKG5vZGUpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgZGF0YSA9IG5vZGUuZGF0YTtcblxuICAgICAgaWYgKGRhdGEgPT09IFNVU1BFTlNFX0VORF9EQVRBKSB7XG4gICAgICAgIGlmIChkZXB0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBnZXROZXh0SHlkcmF0YWJsZVNpYmxpbmcobm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChkYXRhID09PSBTVVNQRU5TRV9TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX0ZBTExCQUNLX1NUQVJUX0RBVEEgfHwgZGF0YSA9PT0gU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBKSB7XG4gICAgICAgIGRlcHRoKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7XG4gIH0gLy8gVE9ETzogV2Fybiwgd2UgZGlkbid0IGZpbmQgdGhlIGVuZCBjb21tZW50IGJvdW5kYXJ5LlxuXG5cbiAgcmV0dXJuIG51bGw7XG59IC8vIFJldHVybnMgdGhlIFN1c3BlbnNlSW5zdGFuY2UgaWYgdGhpcyBub2RlIGlzIGEgZGlyZWN0IGNoaWxkIG9mIGFcbi8vIFN1c3BlbnNlSW5zdGFuY2UuIEkuZS4gaWYgaXRzIHByZXZpb3VzIHNpYmxpbmcgaXMgYSBDb21tZW50IHdpdGhcbi8vIFNVU1BFTlNFX3hfU1RBUlRfREFUQS4gT3RoZXJ3aXNlLCBudWxsLlxuXG5mdW5jdGlvbiBnZXRQYXJlbnRTdXNwZW5zZUluc3RhbmNlKHRhcmdldEluc3RhbmNlKSB7XG4gIHZhciBub2RlID0gdGFyZ2V0SW5zdGFuY2UucHJldmlvdXNTaWJsaW5nOyAvLyBTa2lwIHBhc3QgYWxsIG5vZGVzIHdpdGhpbiB0aGlzIHN1c3BlbnNlIGJvdW5kYXJ5LlxuICAvLyBUaGVyZSBtaWdodCBiZSBuZXN0ZWQgbm9kZXMgc28gd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIGhvd1xuICAvLyBkZWVwIHdlIGFyZSBhbmQgb25seSBicmVhayBvdXQgd2hlbiB3ZSdyZSBiYWNrIG9uIHRvcC5cblxuICB2YXIgZGVwdGggPSAwO1xuXG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIGRhdGEgPSBub2RlLmRhdGE7XG5cbiAgICAgIGlmIChkYXRhID09PSBTVVNQRU5TRV9TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX0ZBTExCQUNLX1NUQVJUX0RBVEEgfHwgZGF0YSA9PT0gU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBKSB7XG4gICAgICAgIGlmIChkZXB0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfRU5EX0RBVEEpIHtcbiAgICAgICAgZGVwdGgrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGNvbW1pdEh5ZHJhdGVkQ29udGFpbmVyKGNvbnRhaW5lcikge1xuICAvLyBSZXRyeSBpZiBhbnkgZXZlbnQgcmVwbGF5aW5nIHdhcyBibG9ja2VkIG9uIHRoaXMuXG4gIHJldHJ5SWZCbG9ja2VkT24oY29udGFpbmVyKTtcbn1cbmZ1bmN0aW9uIGNvbW1pdEh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKSB7XG4gIC8vIFJldHJ5IGlmIGFueSBldmVudCByZXBsYXlpbmcgd2FzIGJsb2NrZWQgb24gdGhpcy5cbiAgcmV0cnlJZkJsb2NrZWRPbihzdXNwZW5zZUluc3RhbmNlKTtcbn1cbmZ1bmN0aW9uIHNob3VsZERlbGV0ZVVuaHlkcmF0ZWRUYWlsSW5zdGFuY2VzKHBhcmVudFR5cGUpIHtcbiAgcmV0dXJuIHBhcmVudFR5cGUgIT09ICdoZWFkJyAmJiBwYXJlbnRUeXBlICE9PSAnYm9keSc7XG59XG5mdW5jdGlvbiBkaWROb3RNYXRjaEh5ZHJhdGVkQ29udGFpbmVyVGV4dEluc3RhbmNlKHBhcmVudENvbnRhaW5lciwgdGV4dEluc3RhbmNlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlKSB7XG4gIHZhciBzaG91bGRXYXJuRGV2ID0gdHJ1ZTtcbiAgY2hlY2tGb3JVbm1hdGNoZWRUZXh0KHRleHRJbnN0YW5jZS5ub2RlVmFsdWUsIHRleHQsIGlzQ29uY3VycmVudE1vZGUsIHNob3VsZFdhcm5EZXYpO1xufVxuZnVuY3Rpb24gZGlkTm90TWF0Y2hIeWRyYXRlZFRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIHRleHRJbnN0YW5jZSwgdGV4dCwgaXNDb25jdXJyZW50TW9kZSkge1xuICBpZiAocGFyZW50UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkckMV0gIT09IHRydWUpIHtcbiAgICB2YXIgc2hvdWxkV2FybkRldiA9IHRydWU7XG4gICAgY2hlY2tGb3JVbm1hdGNoZWRUZXh0KHRleHRJbnN0YW5jZS5ub2RlVmFsdWUsIHRleHQsIGlzQ29uY3VycmVudE1vZGUsIHNob3VsZFdhcm5EZXYpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5Db250YWluZXIocGFyZW50Q29udGFpbmVyLCBpbnN0YW5jZSkge1xuICB7XG4gICAgaWYgKGluc3RhbmNlLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZUVsZW1lbnQocGFyZW50Q29udGFpbmVyLCBpbnN0YW5jZSk7XG4gICAgfSBlbHNlIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSA7IGVsc2Uge1xuICAgICAgd2FybkZvckRlbGV0ZWRIeWRyYXRhYmxlVGV4dChwYXJlbnRDb250YWluZXIsIGluc3RhbmNlKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEh5ZHJhdGVJbnN0YW5jZVdpdGhpblN1c3BlbnNlSW5zdGFuY2UocGFyZW50SW5zdGFuY2UsIGluc3RhbmNlKSB7XG4gIHtcbiAgICAvLyAkRmxvd0ZpeE1lOiBPbmx5IEVsZW1lbnQgb3IgRG9jdW1lbnQgY2FuIGJlIHBhcmVudCBub2Rlcy5cbiAgICB2YXIgcGFyZW50Tm9kZSA9IHBhcmVudEluc3RhbmNlLnBhcmVudE5vZGU7XG5cbiAgICBpZiAocGFyZW50Tm9kZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKGluc3RhbmNlLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgd2FybkZvckRlbGV0ZWRIeWRyYXRhYmxlRWxlbWVudChwYXJlbnROb2RlLCBpbnN0YW5jZSk7XG4gICAgICB9IGVsc2UgaWYgKGluc3RhbmNlLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIDsgZWxzZSB7XG4gICAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZVRleHQocGFyZW50Tm9kZSwgaW5zdGFuY2UpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGlkTm90SHlkcmF0ZUluc3RhbmNlKHBhcmVudFR5cGUsIHBhcmVudFByb3BzLCBwYXJlbnRJbnN0YW5jZSwgaW5zdGFuY2UsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAge1xuICAgIGlmIChpc0NvbmN1cnJlbnRNb2RlIHx8IHBhcmVudFByb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HJDFdICE9PSB0cnVlKSB7XG4gICAgICBpZiAoaW5zdGFuY2Uubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVFbGVtZW50KHBhcmVudEluc3RhbmNlLCBpbnN0YW5jZSk7XG4gICAgICB9IGVsc2UgaWYgKGluc3RhbmNlLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIDsgZWxzZSB7XG4gICAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZVRleHQocGFyZW50SW5zdGFuY2UsIGluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEZpbmRIeWRyYXRhYmxlSW5zdGFuY2VXaXRoaW5Db250YWluZXIocGFyZW50Q29udGFpbmVyLCB0eXBlLCBwcm9wcykge1xuICB7XG4gICAgd2FybkZvckluc2VydGVkSHlkcmF0ZWRFbGVtZW50KHBhcmVudENvbnRhaW5lciwgdHlwZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEZpbmRIeWRyYXRhYmxlVGV4dEluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgdGV4dCkge1xuICB7XG4gICAgd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudENvbnRhaW5lciwgdGV4dCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEZpbmRIeWRyYXRhYmxlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHBhcmVudEluc3RhbmNlLCB0eXBlLCBwcm9wcykge1xuICB7XG4gICAgLy8gJEZsb3dGaXhNZTogT25seSBFbGVtZW50IG9yIERvY3VtZW50IGNhbiBiZSBwYXJlbnQgbm9kZXMuXG4gICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnRJbnN0YW5jZS5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnROb2RlICE9PSBudWxsKSB3YXJuRm9ySW5zZXJ0ZWRIeWRyYXRlZEVsZW1lbnQocGFyZW50Tm9kZSwgdHlwZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEZpbmRIeWRyYXRhYmxlVGV4dEluc3RhbmNlV2l0aGluU3VzcGVuc2VJbnN0YW5jZShwYXJlbnRJbnN0YW5jZSwgdGV4dCkge1xuICB7XG4gICAgLy8gJEZsb3dGaXhNZTogT25seSBFbGVtZW50IG9yIERvY3VtZW50IGNhbiBiZSBwYXJlbnQgbm9kZXMuXG4gICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnRJbnN0YW5jZS5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnROb2RlICE9PSBudWxsKSB3YXJuRm9ySW5zZXJ0ZWRIeWRyYXRlZFRleHQocGFyZW50Tm9kZSwgdGV4dCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEZpbmRIeWRyYXRhYmxlSW5zdGFuY2UocGFyZW50VHlwZSwgcGFyZW50UHJvcHMsIHBhcmVudEluc3RhbmNlLCB0eXBlLCBwcm9wcywgaXNDb25jdXJyZW50TW9kZSkge1xuICB7XG4gICAgaWYgKGlzQ29uY3VycmVudE1vZGUgfHwgcGFyZW50UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkckMV0gIT09IHRydWUpIHtcbiAgICAgIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkRWxlbWVudChwYXJlbnRJbnN0YW5jZSwgdHlwZSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIHRleHQsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAge1xuICAgIGlmIChpc0NvbmN1cnJlbnRNb2RlIHx8IHBhcmVudFByb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HJDFdICE9PSB0cnVlKSB7XG4gICAgICB3YXJuRm9ySW5zZXJ0ZWRIeWRyYXRlZFRleHQocGFyZW50SW5zdGFuY2UsIHRleHQpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZXJyb3JIeWRyYXRpbmdDb250YWluZXIocGFyZW50Q29udGFpbmVyKSB7XG4gIHtcbiAgICAvLyBUT0RPOiBUaGlzIGdldHMgbG9nZ2VkIGJ5IG9uUmVjb3ZlcmFibGVFcnJvciwgdG9vLCBzbyB3ZSBzaG91bGQgYmVcbiAgICAvLyBhYmxlIHRvIHJlbW92ZSBpdC5cbiAgICBlcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIGh5ZHJhdGlvbi4gVGhlIHNlcnZlciBIVE1MIHdhcyByZXBsYWNlZCB3aXRoIGNsaWVudCBjb250ZW50IGluIDwlcz4uJywgcGFyZW50Q29udGFpbmVyLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpO1xuICB9XG59XG5mdW5jdGlvbiBwcmVwYXJlUG9ydGFsTW91bnQocG9ydGFsSW5zdGFuY2UpIHtcbiAgbGlzdGVuVG9BbGxTdXBwb3J0ZWRFdmVudHMocG9ydGFsSW5zdGFuY2UpO1xufVxuXG52YXIgcmFuZG9tS2V5ID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG52YXIgaW50ZXJuYWxJbnN0YW5jZUtleSA9ICdfX3JlYWN0RmliZXIkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbFByb3BzS2V5ID0gJ19fcmVhY3RQcm9wcyQnICsgcmFuZG9tS2V5O1xudmFyIGludGVybmFsQ29udGFpbmVySW5zdGFuY2VLZXkgPSAnX19yZWFjdENvbnRhaW5lciQnICsgcmFuZG9tS2V5O1xudmFyIGludGVybmFsRXZlbnRIYW5kbGVyc0tleSA9ICdfX3JlYWN0RXZlbnRzJCcgKyByYW5kb21LZXk7XG52YXIgaW50ZXJuYWxFdmVudEhhbmRsZXJMaXN0ZW5lcnNLZXkgPSAnX19yZWFjdExpc3RlbmVycyQnICsgcmFuZG9tS2V5O1xudmFyIGludGVybmFsRXZlbnRIYW5kbGVzU2V0S2V5ID0gJ19fcmVhY3RIYW5kbGVzJCcgKyByYW5kb21LZXk7XG5mdW5jdGlvbiBkZXRhY2hEZWxldGVkSW5zdGFuY2Uobm9kZSkge1xuICAvLyBUT0RPOiBUaGlzIGZ1bmN0aW9uIGlzIG9ubHkgY2FsbGVkIG9uIGhvc3QgY29tcG9uZW50cy4gSSBkb24ndCB0aGluayBhbGwgb2ZcbiAgLy8gdGhlc2UgZmllbGRzIGFyZSByZWxldmFudC5cbiAgZGVsZXRlIG5vZGVbaW50ZXJuYWxJbnN0YW5jZUtleV07XG4gIGRlbGV0ZSBub2RlW2ludGVybmFsUHJvcHNLZXldO1xuICBkZWxldGUgbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlcnNLZXldO1xuICBkZWxldGUgbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlckxpc3RlbmVyc0tleV07XG4gIGRlbGV0ZSBub2RlW2ludGVybmFsRXZlbnRIYW5kbGVzU2V0S2V5XTtcbn1cbmZ1bmN0aW9uIHByZWNhY2hlRmliZXJOb2RlKGhvc3RJbnN0LCBub2RlKSB7XG4gIG5vZGVbaW50ZXJuYWxJbnN0YW5jZUtleV0gPSBob3N0SW5zdDtcbn1cbmZ1bmN0aW9uIG1hcmtDb250YWluZXJBc1Jvb3QoaG9zdFJvb3QsIG5vZGUpIHtcbiAgbm9kZVtpbnRlcm5hbENvbnRhaW5lckluc3RhbmNlS2V5XSA9IGhvc3RSb290O1xufVxuZnVuY3Rpb24gdW5tYXJrQ29udGFpbmVyQXNSb290KG5vZGUpIHtcbiAgbm9kZVtpbnRlcm5hbENvbnRhaW5lckluc3RhbmNlS2V5XSA9IG51bGw7XG59XG5mdW5jdGlvbiBpc0NvbnRhaW5lck1hcmtlZEFzUm9vdChub2RlKSB7XG4gIHJldHVybiAhIW5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV07XG59IC8vIEdpdmVuIGEgRE9NIG5vZGUsIHJldHVybiB0aGUgY2xvc2VzdCBIb3N0Q29tcG9uZW50IG9yIEhvc3RUZXh0IGZpYmVyIGFuY2VzdG9yLlxuLy8gSWYgdGhlIHRhcmdldCBub2RlIGlzIHBhcnQgb2YgYSBoeWRyYXRlZCBvciBub3QgeWV0IHJlbmRlcmVkIHN1YnRyZWUsIHRoZW5cbi8vIHRoaXMgbWF5IGFsc28gcmV0dXJuIGEgU3VzcGVuc2VDb21wb25lbnQgb3IgSG9zdFJvb3QgdG8gaW5kaWNhdGUgdGhhdC5cbi8vIENvbmNlcHR1YWxseSB0aGUgSG9zdFJvb3QgZmliZXIgaXMgYSBjaGlsZCBvZiB0aGUgQ29udGFpbmVyIG5vZGUuIFNvIGlmIHlvdVxuLy8gcGFzcyB0aGUgQ29udGFpbmVyIG5vZGUgYXMgdGhlIHRhcmdldE5vZGUsIHlvdSB3aWxsIG5vdCBhY3R1YWxseSBnZXQgdGhlXG4vLyBIb3N0Um9vdCBiYWNrLiBUbyBnZXQgdG8gdGhlIEhvc3RSb290LCB5b3UgbmVlZCB0byBwYXNzIGEgY2hpbGQgb2YgaXQuXG4vLyBUaGUgc2FtZSB0aGluZyBhcHBsaWVzIHRvIFN1c3BlbnNlIGJvdW5kYXJpZXMuXG5cbmZ1bmN0aW9uIGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKHRhcmdldE5vZGUpIHtcbiAgdmFyIHRhcmdldEluc3QgPSB0YXJnZXROb2RlW2ludGVybmFsSW5zdGFuY2VLZXldO1xuXG4gIGlmICh0YXJnZXRJbnN0KSB7XG4gICAgLy8gRG9uJ3QgcmV0dXJuIEhvc3RSb290IG9yIFN1c3BlbnNlQ29tcG9uZW50IGhlcmUuXG4gICAgcmV0dXJuIHRhcmdldEluc3Q7XG4gIH0gLy8gSWYgdGhlIGRpcmVjdCBldmVudCB0YXJnZXQgaXNuJ3QgYSBSZWFjdCBvd25lZCBET00gbm9kZSwgd2UgbmVlZCB0byBsb29rXG4gIC8vIHRvIHNlZSBpZiBvbmUgb2YgaXRzIHBhcmVudHMgaXMgYSBSZWFjdCBvd25lZCBET00gbm9kZS5cblxuXG4gIHZhciBwYXJlbnROb2RlID0gdGFyZ2V0Tm9kZS5wYXJlbnROb2RlO1xuXG4gIHdoaWxlIChwYXJlbnROb2RlKSB7XG4gICAgLy8gV2UnbGwgY2hlY2sgaWYgdGhpcyBpcyBhIGNvbnRhaW5lciByb290IHRoYXQgY291bGQgaW5jbHVkZVxuICAgIC8vIFJlYWN0IG5vZGVzIGluIHRoZSBmdXR1cmUuIFdlIG5lZWQgdG8gY2hlY2sgdGhpcyBmaXJzdCBiZWNhdXNlXG4gICAgLy8gaWYgd2UncmUgYSBjaGlsZCBvZiBhIGRlaHlkcmF0ZWQgY29udGFpbmVyLCB3ZSBuZWVkIHRvIGZpcnN0XG4gICAgLy8gZmluZCB0aGF0IGlubmVyIGNvbnRhaW5lciBiZWZvcmUgbW92aW5nIG9uIHRvIGZpbmRpbmcgdGhlIHBhcmVudFxuICAgIC8vIGluc3RhbmNlLiBOb3RlIHRoYXQgd2UgZG9uJ3QgY2hlY2sgdGhpcyBmaWVsZCBvbiAgdGhlIHRhcmdldE5vZGVcbiAgICAvLyBpdHNlbGYgYmVjYXVzZSB0aGUgZmliZXJzIGFyZSBjb25jZXB0dWFsbHkgYmV0d2VlbiB0aGUgY29udGFpbmVyXG4gICAgLy8gbm9kZSBhbmQgdGhlIGZpcnN0IGNoaWxkLiBJdCBpc24ndCBzdXJyb3VuZGluZyB0aGUgY29udGFpbmVyIG5vZGUuXG4gICAgLy8gSWYgaXQncyBub3QgYSBjb250YWluZXIsIHdlIGNoZWNrIGlmIGl0J3MgYW4gaW5zdGFuY2UuXG4gICAgdGFyZ2V0SW5zdCA9IHBhcmVudE5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV0gfHwgcGFyZW50Tm9kZVtpbnRlcm5hbEluc3RhbmNlS2V5XTtcblxuICAgIGlmICh0YXJnZXRJbnN0KSB7XG4gICAgICAvLyBTaW5jZSB0aGlzIHdhc24ndCB0aGUgZGlyZWN0IHRhcmdldCBvZiB0aGUgZXZlbnQsIHdlIG1pZ2h0IGhhdmVcbiAgICAgIC8vIHN0ZXBwZWQgcGFzdCBkZWh5ZHJhdGVkIERPTSBub2RlcyB0byBnZXQgaGVyZS4gSG93ZXZlciB0aGV5IGNvdWxkXG4gICAgICAvLyBhbHNvIGhhdmUgYmVlbiBub24tUmVhY3Qgbm9kZXMuIFdlIG5lZWQgdG8gYW5zd2VyIHdoaWNoIG9uZS5cbiAgICAgIC8vIElmIHdlIHRoZSBpbnN0YW5jZSBkb2Vzbid0IGhhdmUgYW55IGNoaWxkcmVuLCB0aGVuIHRoZXJlIGNhbid0IGJlXG4gICAgICAvLyBhIG5lc3RlZCBzdXNwZW5zZSBib3VuZGFyeSB3aXRoaW4gaXQuIFNvIHdlIGNhbiB1c2UgdGhpcyBhcyBhIGZhc3RcbiAgICAgIC8vIGJhaWxvdXQuIE1vc3Qgb2YgdGhlIHRpbWUsIHdoZW4gcGVvcGxlIGFkZCBub24tUmVhY3QgY2hpbGRyZW4gdG9cbiAgICAgIC8vIHRoZSB0cmVlLCBpdCBpcyB1c2luZyBhIHJlZiB0byBhIGNoaWxkLWxlc3MgRE9NIG5vZGUuXG4gICAgICAvLyBOb3JtYWxseSB3ZSdkIG9ubHkgbmVlZCB0byBjaGVjayBvbmUgb2YgdGhlIGZpYmVycyBiZWNhdXNlIGlmIGl0XG4gICAgICAvLyBoYXMgZXZlciBnb25lIGZyb20gaGF2aW5nIGNoaWxkcmVuIHRvIGRlbGV0aW5nIHRoZW0gb3IgdmljZSB2ZXJzYVxuICAgICAgLy8gaXQgd291bGQgaGF2ZSBkZWxldGVkIHRoZSBkZWh5ZHJhdGVkIGJvdW5kYXJ5IG5lc3RlZCBpbnNpZGUgYWxyZWFkeS5cbiAgICAgIC8vIEhvd2V2ZXIsIHNpbmNlIHRoZSBIb3N0Um9vdCBzdGFydHMgb3V0IHdpdGggYW4gYWx0ZXJuYXRlIGl0IG1pZ2h0XG4gICAgICAvLyBoYXZlIG9uZSBvbiB0aGUgYWx0ZXJuYXRlIHNvIHdlIG5lZWQgdG8gY2hlY2sgaW4gY2FzZSB0aGlzIHdhcyBhXG4gICAgICAvLyByb290LlxuICAgICAgdmFyIGFsdGVybmF0ZSA9IHRhcmdldEluc3QuYWx0ZXJuYXRlO1xuXG4gICAgICBpZiAodGFyZ2V0SW5zdC5jaGlsZCAhPT0gbnVsbCB8fCBhbHRlcm5hdGUgIT09IG51bGwgJiYgYWx0ZXJuYXRlLmNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgIC8vIE5leHQgd2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIHRoZSBub2RlIHRoYXQgc2tpcHBlZCBwYXN0IGlzXG4gICAgICAgIC8vIG5lc3RlZCB3aXRoaW4gYSBkZWh5ZHJhdGVkIGJvdW5kYXJ5IGFuZCBpZiBzbywgd2hpY2ggb25lLlxuICAgICAgICB2YXIgc3VzcGVuc2VJbnN0YW5jZSA9IGdldFBhcmVudFN1c3BlbnNlSW5zdGFuY2UodGFyZ2V0Tm9kZSk7XG5cbiAgICAgICAgd2hpbGUgKHN1c3BlbnNlSW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBXZSBmb3VuZCBhIHN1c3BlbnNlIGluc3RhbmNlLiBUaGF0IG1lYW5zIHRoYXQgd2UgaGF2ZW4ndFxuICAgICAgICAgIC8vIGh5ZHJhdGVkIGl0IHlldC4gRXZlbiB0aG91Z2ggd2UgbGVhdmUgdGhlIGNvbW1lbnRzIGluIHRoZVxuICAgICAgICAgIC8vIERPTSBhZnRlciBoeWRyYXRpbmcsIGFuZCB0aGVyZSBhcmUgYm91bmRhcmllcyBpbiB0aGUgRE9NXG4gICAgICAgICAgLy8gdGhhdCBjb3VsZCBhbHJlYWR5IGJlIGh5ZHJhdGVkLCB3ZSB3b3VsZG4ndCBoYXZlIGZvdW5kIHRoZW1cbiAgICAgICAgICAvLyB0aHJvdWdoIHRoaXMgcGFzcyBzaW5jZSBpZiB0aGUgdGFyZ2V0IGlzIGh5ZHJhdGVkIGl0IHdvdWxkXG4gICAgICAgICAgLy8gaGF2ZSBoYWQgYW4gaW50ZXJuYWxJbnN0YW5jZUtleSBvbiBpdC5cbiAgICAgICAgICAvLyBMZXQncyBnZXQgdGhlIGZpYmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgU3VzcGVuc2VDb21wb25lbnRcbiAgICAgICAgICAvLyBhcyB0aGUgZGVlcGVzdCBpbnN0YW5jZS5cbiAgICAgICAgICB2YXIgdGFyZ2V0U3VzcGVuc2VJbnN0ID0gc3VzcGVuc2VJbnN0YW5jZVtpbnRlcm5hbEluc3RhbmNlS2V5XTtcblxuICAgICAgICAgIGlmICh0YXJnZXRTdXNwZW5zZUluc3QpIHtcbiAgICAgICAgICAgIHJldHVybiB0YXJnZXRTdXNwZW5zZUluc3Q7XG4gICAgICAgICAgfSAvLyBJZiB3ZSBkb24ndCBmaW5kIGEgRmliZXIgb24gdGhlIGNvbW1lbnQsIGl0IG1pZ2h0IGJlIGJlY2F1c2VcbiAgICAgICAgICAvLyB3ZSBoYXZlbid0IGdvdHRlbiB0byBoeWRyYXRlIGl0IHlldC4gVGhlcmUgbWlnaHQgc3RpbGwgYmUgYVxuICAgICAgICAgIC8vIHBhcmVudCBib3VuZGFyeSB0aGF0IGhhc24ndCBhYm92ZSB0aGlzIG9uZSBzbyB3ZSBuZWVkIHRvIGZpbmRcbiAgICAgICAgICAvLyB0aGUgb3V0ZXIgbW9zdCB0aGF0IGlzIGtub3duLlxuXG5cbiAgICAgICAgICBzdXNwZW5zZUluc3RhbmNlID0gZ2V0UGFyZW50U3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTsgLy8gSWYgd2UgZG9uJ3QgZmluZCBvbmUsIHRoZW4gdGhhdCBzaG91bGQgbWVhbiB0aGF0IHRoZSBwYXJlbnRcbiAgICAgICAgICAvLyBob3N0IGNvbXBvbmVudCBhbHNvIGhhc24ndCBoeWRyYXRlZCB5ZXQuIFdlIGNhbiByZXR1cm4gaXRcbiAgICAgICAgICAvLyBiZWxvdyBzaW5jZSBpdCB3aWxsIGJhaWwgb3V0IG9uIHRoZSBpc01vdW50ZWQgY2hlY2sgbGF0ZXIuXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRhcmdldEluc3Q7XG4gICAgfVxuXG4gICAgdGFyZ2V0Tm9kZSA9IHBhcmVudE5vZGU7XG4gICAgcGFyZW50Tm9kZSA9IHRhcmdldE5vZGUucGFyZW50Tm9kZTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBHaXZlbiBhIERPTSBub2RlLCByZXR1cm4gdGhlIFJlYWN0RE9NQ29tcG9uZW50IG9yIFJlYWN0RE9NVGV4dENvbXBvbmVudFxuICogaW5zdGFuY2UsIG9yIG51bGwgaWYgdGhlIG5vZGUgd2FzIG5vdCByZW5kZXJlZCBieSB0aGlzIFJlYWN0LlxuICovXG5cbmZ1bmN0aW9uIGdldEluc3RhbmNlRnJvbU5vZGUobm9kZSkge1xuICB2YXIgaW5zdCA9IG5vZGVbaW50ZXJuYWxJbnN0YW5jZUtleV0gfHwgbm9kZVtpbnRlcm5hbENvbnRhaW5lckluc3RhbmNlS2V5XTtcblxuICBpZiAoaW5zdCkge1xuICAgIGlmIChpbnN0LnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBpbnN0LnRhZyA9PT0gSG9zdFRleHQgfHwgaW5zdC50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50IHx8IGluc3QudGFnID09PSBIb3N0Um9vdCkge1xuICAgICAgcmV0dXJuIGluc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBHaXZlbiBhIFJlYWN0RE9NQ29tcG9uZW50IG9yIFJlYWN0RE9NVGV4dENvbXBvbmVudCwgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBET00gbm9kZS5cbiAqL1xuXG5mdW5jdGlvbiBnZXROb2RlRnJvbUluc3RhbmNlKGluc3QpIHtcbiAgaWYgKGluc3QudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IGluc3QudGFnID09PSBIb3N0VGV4dCkge1xuICAgIC8vIEluIEZpYmVyIHRoaXMsIGlzIGp1c3QgdGhlIHN0YXRlIG5vZGUgcmlnaHQgbm93LiBXZSBhc3N1bWUgaXQgd2lsbCBiZVxuICAgIC8vIGEgaG9zdCBjb21wb25lbnQgb3IgaG9zdCB0ZXh0LlxuICAgIHJldHVybiBpbnN0LnN0YXRlTm9kZTtcbiAgfSAvLyBXaXRob3V0IHRoaXMgZmlyc3QgaW52YXJpYW50LCBwYXNzaW5nIGEgbm9uLURPTS1jb21wb25lbnQgdHJpZ2dlcnMgdGhlIG5leHRcbiAgLy8gaW52YXJpYW50IGZvciBhIG1pc3NpbmcgcGFyZW50LCB3aGljaCBpcyBzdXBlciBjb25mdXNpbmcuXG5cblxuICB0aHJvdyBuZXcgRXJyb3IoJ2dldE5vZGVGcm9tSW5zdGFuY2U6IEludmFsaWQgYXJndW1lbnQuJyk7XG59XG5mdW5jdGlvbiBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGVbaW50ZXJuYWxQcm9wc0tleV0gfHwgbnVsbDtcbn1cbmZ1bmN0aW9uIHVwZGF0ZUZpYmVyUHJvcHMobm9kZSwgcHJvcHMpIHtcbiAgbm9kZVtpbnRlcm5hbFByb3BzS2V5XSA9IHByb3BzO1xufVxuZnVuY3Rpb24gZ2V0RXZlbnRMaXN0ZW5lclNldChub2RlKSB7XG4gIHZhciBlbGVtZW50TGlzdGVuZXJTZXQgPSBub2RlW2ludGVybmFsRXZlbnRIYW5kbGVyc0tleV07XG5cbiAgaWYgKGVsZW1lbnRMaXN0ZW5lclNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZWxlbWVudExpc3RlbmVyU2V0ID0gbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlcnNLZXldID0gbmV3IFNldCgpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRMaXN0ZW5lclNldDtcbn1cblxudmFyIGxvZ2dlZFR5cGVGYWlsdXJlcyA9IHt9O1xudmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpIHtcbiAge1xuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgIHZhciBzdGFjayA9IGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihlbGVtZW50LnR5cGUsIGVsZW1lbnQuX3NvdXJjZSwgb3duZXIgPyBvd25lci50eXBlIDogbnVsbCk7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEuc2V0RXh0cmFTdGFja0ZyYW1lKHN0YWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSQxLnNldEV4dHJhU3RhY2tGcmFtZShudWxsKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tQcm9wVHlwZXModHlwZVNwZWNzLCB2YWx1ZXMsIGxvY2F0aW9uLCBjb21wb25lbnROYW1lLCBlbGVtZW50KSB7XG4gIHtcbiAgICAvLyAkRmxvd0ZpeE1lIFRoaXMgaXMgb2theSBidXQgRmxvdyBkb2Vzbid0IGtub3cgaXQuXG4gICAgdmFyIGhhcyA9IEZ1bmN0aW9uLmNhbGwuYmluZChoYXNPd25Qcm9wZXJ0eSk7XG5cbiAgICBmb3IgKHZhciB0eXBlU3BlY05hbWUgaW4gdHlwZVNwZWNzKSB7XG4gICAgICBpZiAoaGFzKHR5cGVTcGVjcywgdHlwZVNwZWNOYW1lKSkge1xuICAgICAgICB2YXIgZXJyb3IkMSA9IHZvaWQgMDsgLy8gUHJvcCB0eXBlIHZhbGlkYXRpb24gbWF5IHRocm93LiBJbiBjYXNlIHRoZXkgZG8sIHdlIGRvbid0IHdhbnQgdG9cbiAgICAgICAgLy8gZmFpbCB0aGUgcmVuZGVyIHBoYXNlIHdoZXJlIGl0IGRpZG4ndCBmYWlsIGJlZm9yZS4gU28gd2UgbG9nIGl0LlxuICAgICAgICAvLyBBZnRlciB0aGVzZSBoYXZlIGJlZW4gY2xlYW5lZCB1cCwgd2UnbGwgbGV0IHRoZW0gdGhyb3cuXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBUaGlzIGlzIGludGVudGlvbmFsbHkgYW4gaW52YXJpYW50IHRoYXQgZ2V0cyBjYXVnaHQuIEl0J3MgdGhlIHNhbWVcbiAgICAgICAgICAvLyBiZWhhdmlvciBhcyB3aXRob3V0IHRoaXMgc3RhdGVtZW50IGV4Y2VwdCB3aXRoIGEgYmV0dGVyIG1lc3NhZ2UuXG4gICAgICAgICAgaWYgKHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcbiAgICAgICAgICAgIHZhciBlcnIgPSBFcnJvcigoY29tcG9uZW50TmFtZSB8fCAnUmVhY3QgY2xhc3MnKSArICc6ICcgKyBsb2NhdGlvbiArICcgdHlwZSBgJyArIHR5cGVTcGVjTmFtZSArICdgIGlzIGludmFsaWQ7ICcgKyAnaXQgbXVzdCBiZSBhIGZ1bmN0aW9uLCB1c3VhbGx5IGZyb20gdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLCBidXQgcmVjZWl2ZWQgYCcgKyB0eXBlb2YgdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0gKyAnYC4nICsgJ1RoaXMgb2Z0ZW4gaGFwcGVucyBiZWNhdXNlIG9mIHR5cG9zIHN1Y2ggYXMgYFByb3BUeXBlcy5mdW5jdGlvbmAgaW5zdGVhZCBvZiBgUHJvcFR5cGVzLmZ1bmNgLicpO1xuICAgICAgICAgICAgZXJyLm5hbWUgPSAnSW52YXJpYW50IFZpb2xhdGlvbic7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZXJyb3IkMSA9IHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdKHZhbHVlcywgdHlwZVNwZWNOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgbnVsbCwgJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJyk7XG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgZXJyb3IkMSA9IGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yJDEgJiYgIShlcnJvciQxIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQoZWxlbWVudCk7XG5cbiAgICAgICAgICBlcnJvcignJXM6IHR5cGUgc3BlY2lmaWNhdGlvbiBvZiAlcycgKyAnIGAlc2AgaXMgaW52YWxpZDsgdGhlIHR5cGUgY2hlY2tlciAnICsgJ2Z1bmN0aW9uIG11c3QgcmV0dXJuIGBudWxsYCBvciBhbiBgRXJyb3JgIGJ1dCByZXR1cm5lZCBhICVzLiAnICsgJ1lvdSBtYXkgaGF2ZSBmb3Jnb3R0ZW4gdG8gcGFzcyBhbiBhcmd1bWVudCB0byB0aGUgdHlwZSBjaGVja2VyICcgKyAnY3JlYXRvciAoYXJyYXlPZiwgaW5zdGFuY2VPZiwgb2JqZWN0T2YsIG9uZU9mLCBvbmVPZlR5cGUsIGFuZCAnICsgJ3NoYXBlIGFsbCByZXF1aXJlIGFuIGFyZ3VtZW50KS4nLCBjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycsIGxvY2F0aW9uLCB0eXBlU3BlY05hbWUsIHR5cGVvZiBlcnJvciQxKTtcblxuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yJDEgaW5zdGFuY2VvZiBFcnJvciAmJiAhKGVycm9yJDEubWVzc2FnZSBpbiBsb2dnZWRUeXBlRmFpbHVyZXMpKSB7XG4gICAgICAgICAgLy8gT25seSBtb25pdG9yIHRoaXMgZmFpbHVyZSBvbmNlIGJlY2F1c2UgdGhlcmUgdGVuZHMgdG8gYmUgYSBsb3Qgb2YgdGhlXG4gICAgICAgICAgLy8gc2FtZSBlcnJvci5cbiAgICAgICAgICBsb2dnZWRUeXBlRmFpbHVyZXNbZXJyb3IkMS5tZXNzYWdlXSA9IHRydWU7XG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQoZWxlbWVudCk7XG5cbiAgICAgICAgICBlcnJvcignRmFpbGVkICVzIHR5cGU6ICVzJywgbG9jYXRpb24sIGVycm9yJDEubWVzc2FnZSk7XG5cbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChudWxsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgdmFsdWVTdGFjayA9IFtdO1xudmFyIGZpYmVyU3RhY2s7XG5cbntcbiAgZmliZXJTdGFjayA9IFtdO1xufVxuXG52YXIgaW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY3JlYXRlQ3Vyc29yKGRlZmF1bHRWYWx1ZSkge1xuICByZXR1cm4ge1xuICAgIGN1cnJlbnQ6IGRlZmF1bHRWYWx1ZVxuICB9O1xufVxuXG5mdW5jdGlvbiBwb3AoY3Vyc29yLCBmaWJlcikge1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAge1xuICAgICAgZXJyb3IoJ1VuZXhwZWN0ZWQgcG9wLicpO1xuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIHtcbiAgICBpZiAoZmliZXIgIT09IGZpYmVyU3RhY2tbaW5kZXhdKSB7XG4gICAgICBlcnJvcignVW5leHBlY3RlZCBGaWJlciBwb3BwZWQuJyk7XG4gICAgfVxuICB9XG5cbiAgY3Vyc29yLmN1cnJlbnQgPSB2YWx1ZVN0YWNrW2luZGV4XTtcbiAgdmFsdWVTdGFja1tpbmRleF0gPSBudWxsO1xuXG4gIHtcbiAgICBmaWJlclN0YWNrW2luZGV4XSA9IG51bGw7XG4gIH1cblxuICBpbmRleC0tO1xufVxuXG5mdW5jdGlvbiBwdXNoKGN1cnNvciwgdmFsdWUsIGZpYmVyKSB7XG4gIGluZGV4Kys7XG4gIHZhbHVlU3RhY2tbaW5kZXhdID0gY3Vyc29yLmN1cnJlbnQ7XG5cbiAge1xuICAgIGZpYmVyU3RhY2tbaW5kZXhdID0gZmliZXI7XG4gIH1cblxuICBjdXJzb3IuY3VycmVudCA9IHZhbHVlO1xufVxuXG52YXIgd2FybmVkQWJvdXRNaXNzaW5nR2V0Q2hpbGRDb250ZXh0O1xuXG57XG4gIHdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dCA9IHt9O1xufVxuXG52YXIgZW1wdHlDb250ZXh0T2JqZWN0ID0ge307XG5cbntcbiAgT2JqZWN0LmZyZWV6ZShlbXB0eUNvbnRleHRPYmplY3QpO1xufSAvLyBBIGN1cnNvciB0byB0aGUgY3VycmVudCBtZXJnZWQgY29udGV4dCBvYmplY3Qgb24gdGhlIHN0YWNrLlxuXG5cbnZhciBjb250ZXh0U3RhY2tDdXJzb3IgPSBjcmVhdGVDdXJzb3IoZW1wdHlDb250ZXh0T2JqZWN0KTsgLy8gQSBjdXJzb3IgdG8gYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgY29udGV4dCBoYXMgY2hhbmdlZC5cblxudmFyIGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IgPSBjcmVhdGVDdXJzb3IoZmFsc2UpOyAvLyBLZWVwIHRyYWNrIG9mIHRoZSBwcmV2aW91cyBjb250ZXh0IG9iamVjdCB0aGF0IHdhcyBvbiB0aGUgc3RhY2suXG4vLyBXZSB1c2UgdGhpcyB0byBnZXQgYWNjZXNzIHRvIHRoZSBwYXJlbnQgY29udGV4dCBhZnRlciB3ZSBoYXZlIGFscmVhZHlcbi8vIHB1c2hlZCB0aGUgbmV4dCBjb250ZXh0IHByb3ZpZGVyLCBhbmQgbm93IG5lZWQgdG8gbWVyZ2UgdGhlaXIgY29udGV4dHMuXG5cbnZhciBwcmV2aW91c0NvbnRleHQgPSBlbXB0eUNvbnRleHRPYmplY3Q7XG5cbmZ1bmN0aW9uIGdldFVubWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBkaWRQdXNoT3duQ29udGV4dElmUHJvdmlkZXIpIHtcbiAge1xuICAgIGlmIChkaWRQdXNoT3duQ29udGV4dElmUHJvdmlkZXIgJiYgaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgLy8gSWYgdGhlIGZpYmVyIGlzIGEgY29udGV4dCBwcm92aWRlciBpdHNlbGYsIHdoZW4gd2UgcmVhZCBpdHMgY29udGV4dFxuICAgICAgLy8gd2UgbWF5IGhhdmUgYWxyZWFkeSBwdXNoZWQgaXRzIG93biBjaGlsZCBjb250ZXh0IG9uIHRoZSBzdGFjay4gQSBjb250ZXh0XG4gICAgICAvLyBwcm92aWRlciBzaG91bGQgbm90IFwic2VlXCIgaXRzIG93biBjaGlsZCBjb250ZXh0LiBUaGVyZWZvcmUgd2UgcmVhZCB0aGVcbiAgICAgIC8vIHByZXZpb3VzIChwYXJlbnQpIGNvbnRleHQgaW5zdGVhZCBmb3IgYSBjb250ZXh0IHByb3ZpZGVyLlxuICAgICAgcmV0dXJuIHByZXZpb3VzQ29udGV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGV4dFN0YWNrQ3Vyc29yLmN1cnJlbnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2FjaGVDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQsIG1hc2tlZENvbnRleHQpIHtcbiAge1xuICAgIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZFVubWFza2VkQ2hpbGRDb250ZXh0ID0gdW5tYXNrZWRDb250ZXh0O1xuICAgIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWFza2VkQ2hpbGRDb250ZXh0ID0gbWFza2VkQ29udGV4dDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpIHtcbiAge1xuICAgIHZhciB0eXBlID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICB2YXIgY29udGV4dFR5cGVzID0gdHlwZS5jb250ZXh0VHlwZXM7XG5cbiAgICBpZiAoIWNvbnRleHRUeXBlcykge1xuICAgICAgcmV0dXJuIGVtcHR5Q29udGV4dE9iamVjdDtcbiAgICB9IC8vIEF2b2lkIHJlY3JlYXRpbmcgbWFza2VkIGNvbnRleHQgdW5sZXNzIHVubWFza2VkIGNvbnRleHQgaGFzIGNoYW5nZWQuXG4gICAgLy8gRmFpbGluZyB0byBkbyB0aGlzIHdpbGwgcmVzdWx0IGluIHVubmVjZXNzYXJ5IGNhbGxzIHRvIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMuXG4gICAgLy8gVGhpcyBtYXkgdHJpZ2dlciBpbmZpbml0ZSBsb29wcyBpZiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIGNhbGxzIHNldFN0YXRlLlxuXG5cbiAgICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAgICBpZiAoaW5zdGFuY2UgJiYgaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRVbm1hc2tlZENoaWxkQ29udGV4dCA9PT0gdW5tYXNrZWRDb250ZXh0KSB7XG4gICAgICByZXR1cm4gaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNYXNrZWRDaGlsZENvbnRleHQ7XG4gICAgfVxuXG4gICAgdmFyIGNvbnRleHQgPSB7fTtcblxuICAgIGZvciAodmFyIGtleSBpbiBjb250ZXh0VHlwZXMpIHtcbiAgICAgIGNvbnRleHRba2V5XSA9IHVubWFza2VkQ29udGV4dFtrZXldO1xuICAgIH1cblxuICAgIHtcbiAgICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ1Vua25vd24nO1xuICAgICAgY2hlY2tQcm9wVHlwZXMoY29udGV4dFR5cGVzLCBjb250ZXh0LCAnY29udGV4dCcsIG5hbWUpO1xuICAgIH0gLy8gQ2FjaGUgdW5tYXNrZWQgY29udGV4dCBzbyB3ZSBjYW4gYXZvaWQgcmVjcmVhdGluZyBtYXNrZWQgY29udGV4dCB1bmxlc3MgbmVjZXNzYXJ5LlxuICAgIC8vIENvbnRleHQgaXMgY3JlYXRlZCBiZWZvcmUgdGhlIGNsYXNzIGNvbXBvbmVudCBpcyBpbnN0YW50aWF0ZWQgc28gY2hlY2sgZm9yIGluc3RhbmNlLlxuXG5cbiAgICBpZiAoaW5zdGFuY2UpIHtcbiAgICAgIGNhY2hlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0LCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYXNDb250ZXh0Q2hhbmdlZCgpIHtcbiAge1xuICAgIHJldHVybiBkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLmN1cnJlbnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDb250ZXh0UHJvdmlkZXIodHlwZSkge1xuICB7XG4gICAgdmFyIGNoaWxkQ29udGV4dFR5cGVzID0gdHlwZS5jaGlsZENvbnRleHRUeXBlcztcbiAgICByZXR1cm4gY2hpbGRDb250ZXh0VHlwZXMgIT09IG51bGwgJiYgY2hpbGRDb250ZXh0VHlwZXMgIT09IHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwb3BDb250ZXh0KGZpYmVyKSB7XG4gIHtcbiAgICBwb3AoZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgZmliZXIpO1xuICAgIHBvcChjb250ZXh0U3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwb3BUb3BMZXZlbENvbnRleHRPYmplY3QoZmliZXIpIHtcbiAge1xuICAgIHBvcChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCBmaWJlcik7XG4gICAgcG9wKGNvbnRleHRTdGFja0N1cnNvciwgZmliZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1c2hUb3BMZXZlbENvbnRleHRPYmplY3QoZmliZXIsIGNvbnRleHQsIGRpZENoYW5nZSkge1xuICB7XG4gICAgaWYgKGNvbnRleHRTdGFja0N1cnNvci5jdXJyZW50ICE9PSBlbXB0eUNvbnRleHRPYmplY3QpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBjb250ZXh0IGZvdW5kIG9uIHN0YWNrLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IsIGNvbnRleHQsIGZpYmVyKTtcbiAgICBwdXNoKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIGRpZENoYW5nZSwgZmliZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NDaGlsZENvbnRleHQoZmliZXIsIHR5cGUsIHBhcmVudENvbnRleHQpIHtcbiAge1xuICAgIHZhciBpbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcbiAgICB2YXIgY2hpbGRDb250ZXh0VHlwZXMgPSB0eXBlLmNoaWxkQ29udGV4dFR5cGVzOyAvLyBUT0RPIChidmF1Z2huKSBSZXBsYWNlIHRoaXMgYmVoYXZpb3Igd2l0aCBhbiBpbnZhcmlhbnQoKSBpbiB0aGUgZnV0dXJlLlxuICAgIC8vIEl0IGhhcyBvbmx5IGJlZW4gYWRkZWQgaW4gRmliZXIgdG8gbWF0Y2ggdGhlICh1bmludGVudGlvbmFsKSBiZWhhdmlvciBpbiBTdGFjay5cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0Q2hpbGRDb250ZXh0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB7XG4gICAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1Vua25vd24nO1xuXG4gICAgICAgIGlmICghd2FybmVkQWJvdXRNaXNzaW5nR2V0Q2hpbGRDb250ZXh0W2NvbXBvbmVudE5hbWVdKSB7XG4gICAgICAgICAgd2FybmVkQWJvdXRNaXNzaW5nR2V0Q2hpbGRDb250ZXh0W2NvbXBvbmVudE5hbWVdID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCclcy5jaGlsZENvbnRleHRUeXBlcyBpcyBzcGVjaWZpZWQgYnV0IHRoZXJlIGlzIG5vIGdldENoaWxkQ29udGV4dCgpIG1ldGhvZCAnICsgJ29uIHRoZSBpbnN0YW5jZS4gWW91IGNhbiBlaXRoZXIgZGVmaW5lIGdldENoaWxkQ29udGV4dCgpIG9uICVzIG9yIHJlbW92ZSAnICsgJ2NoaWxkQ29udGV4dFR5cGVzIGZyb20gaXQuJywgY29tcG9uZW50TmFtZSwgY29tcG9uZW50TmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhcmVudENvbnRleHQ7XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkQ29udGV4dCA9IGluc3RhbmNlLmdldENoaWxkQ29udGV4dCgpO1xuXG4gICAgZm9yICh2YXIgY29udGV4dEtleSBpbiBjaGlsZENvbnRleHQpIHtcbiAgICAgIGlmICghKGNvbnRleHRLZXkgaW4gY2hpbGRDb250ZXh0VHlwZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1Vua25vd24nKSArIFwiLmdldENoaWxkQ29udGV4dCgpOiBrZXkgXFxcIlwiICsgY29udGV4dEtleSArIFwiXFxcIiBpcyBub3QgZGVmaW5lZCBpbiBjaGlsZENvbnRleHRUeXBlcy5cIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAge1xuICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnVW5rbm93bic7XG4gICAgICBjaGVja1Byb3BUeXBlcyhjaGlsZENvbnRleHRUeXBlcywgY2hpbGRDb250ZXh0LCAnY2hpbGQgY29udGV4dCcsIG5hbWUpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3NpZ24oe30sIHBhcmVudENvbnRleHQsIGNoaWxkQ29udGV4dCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcykge1xuICB7XG4gICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlOyAvLyBXZSBwdXNoIHRoZSBjb250ZXh0IGFzIGVhcmx5IGFzIHBvc3NpYmxlIHRvIGVuc3VyZSBzdGFjayBpbnRlZ3JpdHkuXG4gICAgLy8gSWYgdGhlIGluc3RhbmNlIGRvZXMgbm90IGV4aXN0IHlldCwgd2Ugd2lsbCBwdXNoIG51bGwgYXQgZmlyc3QsXG4gICAgLy8gYW5kIHJlcGxhY2UgaXQgb24gdGhlIHN0YWNrIGxhdGVyIHdoZW4gaW52YWxpZGF0aW5nIHRoZSBjb250ZXh0LlxuXG4gICAgdmFyIG1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0ID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNZXJnZWRDaGlsZENvbnRleHQgfHwgZW1wdHlDb250ZXh0T2JqZWN0OyAvLyBSZW1lbWJlciB0aGUgcGFyZW50IGNvbnRleHQgc28gd2UgY2FuIG1lcmdlIHdpdGggaXQgbGF0ZXIuXG4gICAgLy8gSW5oZXJpdCB0aGUgcGFyZW50J3MgZGlkLXBlcmZvcm0td29yayB2YWx1ZSB0byBhdm9pZCBpbmFkdmVydGVudGx5IGJsb2NraW5nIHVwZGF0ZXMuXG5cbiAgICBwcmV2aW91c0NvbnRleHQgPSBjb250ZXh0U3RhY2tDdXJzb3IuY3VycmVudDtcbiAgICBwdXNoKGNvbnRleHRTdGFja0N1cnNvciwgbWVtb2l6ZWRNZXJnZWRDaGlsZENvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICBwdXNoKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IuY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludmFsaWRhdGVDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MsIHR5cGUsIGRpZENoYW5nZSkge1xuICB7XG4gICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCB0byBoYXZlIGFuIGluc3RhbmNlIGJ5IHRoaXMgcG9pbnQuICcgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBpZiAoZGlkQ2hhbmdlKSB7XG4gICAgICAvLyBNZXJnZSBwYXJlbnQgYW5kIG93biBjb250ZXh0LlxuICAgICAgLy8gU2tpcCB0aGlzIGlmIHdlJ3JlIG5vdCB1cGRhdGluZyBkdWUgdG8gc0NVLlxuICAgICAgLy8gVGhpcyBhdm9pZHMgdW5uZWNlc3NhcmlseSByZWNvbXB1dGluZyBtZW1vaXplZCB2YWx1ZXMuXG4gICAgICB2YXIgbWVyZ2VkQ29udGV4dCA9IHByb2Nlc3NDaGlsZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHR5cGUsIHByZXZpb3VzQ29udGV4dCk7XG4gICAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dCA9IG1lcmdlZENvbnRleHQ7IC8vIFJlcGxhY2UgdGhlIG9sZCAob3IgZW1wdHkpIGNvbnRleHQgd2l0aCB0aGUgbmV3IG9uZS5cbiAgICAgIC8vIEl0IGlzIGltcG9ydGFudCB0byB1bndpbmQgdGhlIGNvbnRleHQgaW4gdGhlIHJldmVyc2Ugb3JkZXIuXG5cbiAgICAgIHBvcChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBwb3AoY29udGV4dFN0YWNrQ3Vyc29yLCB3b3JrSW5Qcm9ncmVzcyk7IC8vIE5vdyBwdXNoIHRoZSBuZXcgY29udGV4dCBhbmQgbWFyayB0aGF0IGl0IGhhcyBjaGFuZ2VkLlxuXG4gICAgICBwdXNoKGNvbnRleHRTdGFja0N1cnNvciwgbWVyZ2VkQ29udGV4dCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcHVzaChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCBkaWRDaGFuZ2UsIHdvcmtJblByb2dyZXNzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9wKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHB1c2goZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgZGlkQ2hhbmdlLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRDdXJyZW50VW5tYXNrZWRDb250ZXh0KGZpYmVyKSB7XG4gIHtcbiAgICAvLyBDdXJyZW50bHkgdGhpcyBpcyBvbmx5IHVzZWQgd2l0aCByZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcjsgbm90IHN1cmUgaWYgaXRcbiAgICAvLyBtYWtlcyBzZW5zZSBlbHNld2hlcmVcbiAgICBpZiAoIWlzRmliZXJNb3VudGVkKGZpYmVyKSB8fCBmaWJlci50YWcgIT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHN1YnRyZWUgcGFyZW50IHRvIGJlIGEgbW91bnRlZCBjbGFzcyBjb21wb25lbnQuICcgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICB2YXIgbm9kZSA9IGZpYmVyO1xuXG4gICAgZG8ge1xuICAgICAgc3dpdGNoIChub2RlLnRhZykge1xuICAgICAgICBjYXNlIEhvc3RSb290OlxuICAgICAgICAgIHJldHVybiBub2RlLnN0YXRlTm9kZS5jb250ZXh0O1xuXG4gICAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIENvbXBvbmVudCA9IG5vZGUudHlwZTtcblxuICAgICAgICAgICAgaWYgKGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuc3RhdGVOb2RlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9IHdoaWxlIChub2RlICE9PSBudWxsKTtcblxuICAgIHRocm93IG5ldyBFcnJvcignRm91bmQgdW5leHBlY3RlZCBkZXRhY2hlZCBzdWJ0cmVlIHBhcmVudC4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG59XG5cbnZhciBMZWdhY3lSb290ID0gMDtcbnZhciBDb25jdXJyZW50Um9vdCA9IDE7XG5cbnZhciBzeW5jUXVldWUgPSBudWxsO1xudmFyIGluY2x1ZGVzTGVnYWN5U3luY0NhbGxiYWNrcyA9IGZhbHNlO1xudmFyIGlzRmx1c2hpbmdTeW5jUXVldWUgPSBmYWxzZTtcbmZ1bmN0aW9uIHNjaGVkdWxlU3luY0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gIC8vIFB1c2ggdGhpcyBjYWxsYmFjayBpbnRvIGFuIGludGVybmFsIHF1ZXVlLiBXZSdsbCBmbHVzaCB0aGVzZSBlaXRoZXIgaW5cbiAgLy8gdGhlIG5leHQgdGljaywgb3IgZWFybGllciBpZiBzb21ldGhpbmcgY2FsbHMgYGZsdXNoU3luY0NhbGxiYWNrUXVldWVgLlxuICBpZiAoc3luY1F1ZXVlID09PSBudWxsKSB7XG4gICAgc3luY1F1ZXVlID0gW2NhbGxiYWNrXTtcbiAgfSBlbHNlIHtcbiAgICAvLyBQdXNoIG9udG8gZXhpc3RpbmcgcXVldWUuIERvbid0IG5lZWQgdG8gc2NoZWR1bGUgYSBjYWxsYmFjayBiZWNhdXNlXG4gICAgLy8gd2UgYWxyZWFkeSBzY2hlZHVsZWQgb25lIHdoZW4gd2UgY3JlYXRlZCB0aGUgcXVldWUuXG4gICAgc3luY1F1ZXVlLnB1c2goY2FsbGJhY2spO1xuICB9XG59XG5mdW5jdGlvbiBzY2hlZHVsZUxlZ2FjeVN5bmNDYWxsYmFjayhjYWxsYmFjaykge1xuICBpbmNsdWRlc0xlZ2FjeVN5bmNDYWxsYmFja3MgPSB0cnVlO1xuICBzY2hlZHVsZVN5bmNDYWxsYmFjayhjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBmbHVzaFN5bmNDYWxsYmFja3NPbmx5SW5MZWdhY3lNb2RlKCkge1xuICAvLyBPbmx5IGZsdXNoZXMgdGhlIHF1ZXVlIGlmIHRoZXJlJ3MgYSBsZWdhY3kgc3luYyBjYWxsYmFjayBzY2hlZHVsZWQuXG4gIC8vIFRPRE86IFRoZXJlJ3Mgb25seSBhIHNpbmdsZSB0eXBlIG9mIGNhbGxiYWNrOiBwZXJmb3JtU3luY09uV29ya09uUm9vdC4gU29cbiAgLy8gaXQgbWlnaHQgbWFrZSBtb3JlIHNlbnNlIGZvciB0aGUgcXVldWUgdG8gYmUgYSBsaXN0IG9mIHJvb3RzIGluc3RlYWQgb2YgYVxuICAvLyBsaXN0IG9mIGdlbmVyaWMgY2FsbGJhY2tzLiBUaGVuIHdlIGNhbiBoYXZlIHR3bzogb25lIGZvciBsZWdhY3kgcm9vdHMsIG9uZVxuICAvLyBmb3IgY29uY3VycmVudCByb290cy4gQW5kIHRoaXMgbWV0aG9kIHdvdWxkIG9ubHkgZmx1c2ggdGhlIGxlZ2FjeSBvbmVzLlxuICBpZiAoaW5jbHVkZXNMZWdhY3lTeW5jQ2FsbGJhY2tzKSB7XG4gICAgZmx1c2hTeW5jQ2FsbGJhY2tzKCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGZsdXNoU3luY0NhbGxiYWNrcygpIHtcbiAgaWYgKCFpc0ZsdXNoaW5nU3luY1F1ZXVlICYmIHN5bmNRdWV1ZSAhPT0gbnVsbCkge1xuICAgIC8vIFByZXZlbnQgcmUtZW50cmFuY2UuXG4gICAgaXNGbHVzaGluZ1N5bmNRdWV1ZSA9IHRydWU7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBwcmV2aW91c1VwZGF0ZVByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGlzU3luYyA9IHRydWU7XG4gICAgICB2YXIgcXVldWUgPSBzeW5jUXVldWU7IC8vIFRPRE86IElzIHRoaXMgbmVjZXNzYXJ5IGFueW1vcmU/IFRoZSBvbmx5IHVzZXIgY29kZSB0aGF0IHJ1bnMgaW4gdGhpc1xuICAgICAgLy8gcXVldWUgaXMgaW4gdGhlIHJlbmRlciBvciBjb21taXQgcGhhc2VzLlxuXG4gICAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoRGlzY3JldGVFdmVudFByaW9yaXR5KTtcblxuICAgICAgZm9yICg7IGkgPCBxdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSBxdWV1ZVtpXTtcblxuICAgICAgICBkbyB7XG4gICAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayhpc1N5bmMpO1xuICAgICAgICB9IHdoaWxlIChjYWxsYmFjayAhPT0gbnVsbCk7XG4gICAgICB9XG5cbiAgICAgIHN5bmNRdWV1ZSA9IG51bGw7XG4gICAgICBpbmNsdWRlc0xlZ2FjeVN5bmNDYWxsYmFja3MgPSBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gSWYgc29tZXRoaW5nIHRocm93cywgbGVhdmUgdGhlIHJlbWFpbmluZyBjYWxsYmFja3Mgb24gdGhlIHF1ZXVlLlxuICAgICAgaWYgKHN5bmNRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICBzeW5jUXVldWUgPSBzeW5jUXVldWUuc2xpY2UoaSArIDEpO1xuICAgICAgfSAvLyBSZXN1bWUgZmx1c2hpbmcgaW4gdGhlIG5leHQgdGlja1xuXG5cbiAgICAgIHNjaGVkdWxlQ2FsbGJhY2soSW1tZWRpYXRlUHJpb3JpdHksIGZsdXNoU3luY0NhbGxiYWNrcyk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzVXBkYXRlUHJpb3JpdHkpO1xuICAgICAgaXNGbHVzaGluZ1N5bmNRdWV1ZSA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnO1xudmFyIE5vVHJhbnNpdGlvbiA9IG51bGw7XG5mdW5jdGlvbiByZXF1ZXN0Q3VycmVudFRyYW5zaXRpb24oKSB7XG4gIHJldHVybiBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQxLnRyYW5zaXRpb247XG59XG5cbnZhciBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncyA9IHtcbiAgcmVjb3JkVW5zYWZlTGlmZWN5Y2xlV2FybmluZ3M6IGZ1bmN0aW9uIChmaWJlciwgaW5zdGFuY2UpIHt9LFxuICBmbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5nczogZnVuY3Rpb24gKCkge30sXG4gIHJlY29yZExlZ2FjeUNvbnRleHRXYXJuaW5nOiBmdW5jdGlvbiAoZmliZXIsIGluc3RhbmNlKSB7fSxcbiAgZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZzogZnVuY3Rpb24gKCkge30sXG4gIGRpc2NhcmRQZW5kaW5nV2FybmluZ3M6IGZ1bmN0aW9uICgpIHt9XG59O1xuXG57XG4gIHZhciBmaW5kU3RyaWN0Um9vdCA9IGZ1bmN0aW9uIChmaWJlcikge1xuICAgIHZhciBtYXliZVN0cmljdFJvb3QgPSBudWxsO1xuICAgIHZhciBub2RlID0gZmliZXI7XG5cbiAgICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgbWF5YmVTdHJpY3RSb290ID0gbm9kZTtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIHJldHVybiBtYXliZVN0cmljdFJvb3Q7XG4gIH07XG5cbiAgdmFyIHNldFRvU29ydGVkU3RyaW5nID0gZnVuY3Rpb24gKHNldCkge1xuICAgIHZhciBhcnJheSA9IFtdO1xuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgYXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFycmF5LnNvcnQoKS5qb2luKCcsICcpO1xuICB9O1xuXG4gIHZhciBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1dhcm5pbmdzID0gW107XG4gIHZhciBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gIHZhciBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdOyAvLyBUcmFja3MgY29tcG9uZW50cyB3ZSBoYXZlIGFscmVhZHkgd2FybmVkIGFib3V0LlxuXG4gIHZhciBkaWRXYXJuQWJvdXRVbnNhZmVMaWZlY3ljbGVzID0gbmV3IFNldCgpO1xuXG4gIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZFVuc2FmZUxpZmVjeWNsZVdhcm5pbmdzID0gZnVuY3Rpb24gKGZpYmVyLCBpbnN0YW5jZSkge1xuICAgIC8vIERlZHVwZSBzdHJhdGVneTogV2FybiBvbmNlIHBlciBjb21wb25lbnQuXG4gICAgaWYgKGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuaGFzKGZpYmVyLnR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicgJiYgLy8gRG9uJ3Qgd2FybiBhYm91dCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMuXG4gICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50Ll9fc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmcgIT09IHRydWUpIHtcbiAgICAgIHBlbmRpbmdDb21wb25lbnRXaWxsTW91bnRXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgJiYgdHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MucHVzaChmaWJlcik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nICYmIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgJiYgdHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicgJiYgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZS5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLnB1c2goZmliZXIpO1xuICAgIH1cblxuICAgIGlmIChmaWJlci5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSAmJiB0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLnB1c2goZmliZXIpO1xuICAgIH1cbiAgfTtcblxuICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXZSBkbyBhbiBpbml0aWFsIHBhc3MgdG8gZ2F0aGVyIGNvbXBvbmVudCBuYW1lc1xuICAgIHZhciBjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxNb3VudFdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIGNvbXBvbmVudFdpbGxNb3VudFVuaXF1ZU5hbWVzLmFkZChnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICAgIGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuYWRkKGZpYmVyLnR5cGUpO1xuICAgICAgfSk7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudFVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ1VOU0FGRV9Db21wb25lbnRXaWxsTW91bnRXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50VW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzVW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNVbmlxdWVOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzLmFkZChnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICAgIGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuYWRkKGZpYmVyLnR5cGUpO1xuICAgICAgfSk7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBjb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMgPSBuZXcgU2V0KCk7XG5cbiAgICBpZiAocGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIGNvbXBvbmVudFdpbGxVcGRhdGVVbmlxdWVOYW1lcy5hZGQoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgICBkaWRXYXJuQWJvdXRVbnNhZmVMaWZlY3ljbGVzLmFkZChmaWJlci50eXBlKTtcbiAgICAgIH0pO1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZVVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIFVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gICAgfSAvLyBGaW5hbGx5LCB3ZSBmbHVzaCBhbGwgdGhlIHdhcm5pbmdzXG4gICAgLy8gVU5TQUZFXyBvbmVzIGJlZm9yZSB0aGUgZGVwcmVjYXRlZCBvbmVzLCBzaW5jZSB0aGV5J2xsIGJlICdsb3VkZXInXG5cblxuICAgIGlmIChVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50VW5pcXVlTmFtZXMuc2l6ZSA+IDApIHtcbiAgICAgIHZhciBzb3J0ZWROYW1lcyA9IHNldFRvU29ydGVkU3RyaW5nKFVOU0FGRV9jb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyk7XG5cbiAgICAgIGVycm9yKCdVc2luZyBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50IGluIHN0cmljdCBtb2RlIGlzIG5vdCByZWNvbW1lbmRlZCBhbmQgbWF5IGluZGljYXRlIGJ1Z3MgaW4geW91ciBjb2RlLiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvdW5zYWZlLWNvbXBvbmVudC1saWZlY3ljbGVzIGZvciBkZXRhaWxzLlxcblxcbicgKyAnKiBNb3ZlIGNvZGUgd2l0aCBzaWRlIGVmZmVjdHMgdG8gY29tcG9uZW50RGlkTW91bnQsIGFuZCBzZXQgaW5pdGlhbCBzdGF0ZSBpbiB0aGUgY29uc3RydWN0b3IuXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBzb3J0ZWROYW1lcyk7XG4gICAgfVxuXG4gICAgaWYgKFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzVW5pcXVlTmFtZXMuc2l6ZSA+IDApIHtcbiAgICAgIHZhciBfc29ydGVkTmFtZXMgPSBzZXRUb1NvcnRlZFN0cmluZyhVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzKTtcblxuICAgICAgZXJyb3IoJ1VzaW5nIFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIGluIHN0cmljdCBtb2RlIGlzIG5vdCByZWNvbW1lbmRlZCAnICsgJ2FuZCBtYXkgaW5kaWNhdGUgYnVncyBpbiB5b3VyIGNvZGUuICcgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMgZm9yIGRldGFpbHMuXFxuXFxuJyArICcqIE1vdmUgZGF0YSBmZXRjaGluZyBjb2RlIG9yIHNpZGUgZWZmZWN0cyB0byBjb21wb25lbnREaWRVcGRhdGUuXFxuJyArIFwiKiBJZiB5b3UncmUgdXBkYXRpbmcgc3RhdGUgd2hlbmV2ZXIgcHJvcHMgY2hhbmdlLCBcIiArICdyZWZhY3RvciB5b3VyIGNvZGUgdG8gdXNlIG1lbW9pemF0aW9uIHRlY2huaXF1ZXMgb3IgbW92ZSBpdCB0byAnICsgJ3N0YXRpYyBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuIExlYXJuIG1vcmUgYXQ6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9kZXJpdmVkLXN0YXRlXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBfc29ydGVkTmFtZXMpO1xuICAgIH1cblxuICAgIGlmIChVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZVVuaXF1ZU5hbWVzLnNpemUgPiAwKSB7XG4gICAgICB2YXIgX3NvcnRlZE5hbWVzMiA9IHNldFRvU29ydGVkU3RyaW5nKFVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMpO1xuXG4gICAgICBlcnJvcignVXNpbmcgVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgaW4gc3RyaWN0IG1vZGUgaXMgbm90IHJlY29tbWVuZGVkICcgKyAnYW5kIG1heSBpbmRpY2F0ZSBidWdzIGluIHlvdXIgY29kZS4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcyBmb3IgZGV0YWlscy5cXG5cXG4nICsgJyogTW92ZSBkYXRhIGZldGNoaW5nIGNvZGUgb3Igc2lkZSBlZmZlY3RzIHRvIGNvbXBvbmVudERpZFVwZGF0ZS5cXG4nICsgJ1xcblBsZWFzZSB1cGRhdGUgdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAlcycsIF9zb3J0ZWROYW1lczIpO1xuICAgIH1cblxuICAgIGlmIChjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcy5zaXplID4gMCkge1xuICAgICAgdmFyIF9zb3J0ZWROYW1lczMgPSBzZXRUb1NvcnRlZFN0cmluZyhjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyk7XG5cbiAgICAgIHdhcm4oJ2NvbXBvbmVudFdpbGxNb3VudCBoYXMgYmVlbiByZW5hbWVkLCBhbmQgaXMgbm90IHJlY29tbWVuZGVkIGZvciB1c2UuICcgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMgZm9yIGRldGFpbHMuXFxuXFxuJyArICcqIE1vdmUgY29kZSB3aXRoIHNpZGUgZWZmZWN0cyB0byBjb21wb25lbnREaWRNb3VudCwgYW5kIHNldCBpbml0aWFsIHN0YXRlIGluIHRoZSBjb25zdHJ1Y3Rvci5cXG4nICsgJyogUmVuYW1lIGNvbXBvbmVudFdpbGxNb3VudCB0byBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50IHRvIHN1cHByZXNzICcgKyAndGhpcyB3YXJuaW5nIGluIG5vbi1zdHJpY3QgbW9kZS4gSW4gUmVhY3QgMTgueCwgb25seSB0aGUgVU5TQUZFXyBuYW1lIHdpbGwgd29yay4gJyArICdUbyByZW5hbWUgYWxsIGRlcHJlY2F0ZWQgbGlmZWN5Y2xlcyB0byB0aGVpciBuZXcgbmFtZXMsIHlvdSBjYW4gcnVuICcgKyAnYG5weCByZWFjdC1jb2RlbW9kIHJlbmFtZS11bnNhZmUtbGlmZWN5Y2xlc2AgaW4geW91ciBwcm9qZWN0IHNvdXJjZSBmb2xkZXIuXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBfc29ydGVkTmFtZXMzKTtcbiAgICB9XG5cbiAgICBpZiAoY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzLnNpemUgPiAwKSB7XG4gICAgICB2YXIgX3NvcnRlZE5hbWVzNCA9IHNldFRvU29ydGVkU3RyaW5nKGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNVbmlxdWVOYW1lcyk7XG5cbiAgICAgIHdhcm4oJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgaGFzIGJlZW4gcmVuYW1lZCwgYW5kIGlzIG5vdCByZWNvbW1lbmRlZCBmb3IgdXNlLiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvdW5zYWZlLWNvbXBvbmVudC1saWZlY3ljbGVzIGZvciBkZXRhaWxzLlxcblxcbicgKyAnKiBNb3ZlIGRhdGEgZmV0Y2hpbmcgY29kZSBvciBzaWRlIGVmZmVjdHMgdG8gY29tcG9uZW50RGlkVXBkYXRlLlxcbicgKyBcIiogSWYgeW91J3JlIHVwZGF0aW5nIHN0YXRlIHdoZW5ldmVyIHByb3BzIGNoYW5nZSwgcmVmYWN0b3IgeW91ciBcIiArICdjb2RlIHRvIHVzZSBtZW1vaXphdGlvbiB0ZWNobmlxdWVzIG9yIG1vdmUgaXQgdG8gJyArICdzdGF0aWMgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLiBMZWFybiBtb3JlIGF0OiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvZGVyaXZlZC1zdGF0ZVxcbicgKyAnKiBSZW5hbWUgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyB0byBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyB0byBzdXBwcmVzcyAnICsgJ3RoaXMgd2FybmluZyBpbiBub24tc3RyaWN0IG1vZGUuIEluIFJlYWN0IDE4LngsIG9ubHkgdGhlIFVOU0FGRV8gbmFtZSB3aWxsIHdvcmsuICcgKyAnVG8gcmVuYW1lIGFsbCBkZXByZWNhdGVkIGxpZmVjeWNsZXMgdG8gdGhlaXIgbmV3IG5hbWVzLCB5b3UgY2FuIHJ1biAnICsgJ2BucHggcmVhY3QtY29kZW1vZCByZW5hbWUtdW5zYWZlLWxpZmVjeWNsZXNgIGluIHlvdXIgcHJvamVjdCBzb3VyY2UgZm9sZGVyLlxcbicgKyAnXFxuUGxlYXNlIHVwZGF0ZSB0aGUgZm9sbG93aW5nIGNvbXBvbmVudHM6ICVzJywgX3NvcnRlZE5hbWVzNCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbXBvbmVudFdpbGxVcGRhdGVVbmlxdWVOYW1lcy5zaXplID4gMCkge1xuICAgICAgdmFyIF9zb3J0ZWROYW1lczUgPSBzZXRUb1NvcnRlZFN0cmluZyhjb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMpO1xuXG4gICAgICB3YXJuKCdjb21wb25lbnRXaWxsVXBkYXRlIGhhcyBiZWVuIHJlbmFtZWQsIGFuZCBpcyBub3QgcmVjb21tZW5kZWQgZm9yIHVzZS4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcyBmb3IgZGV0YWlscy5cXG5cXG4nICsgJyogTW92ZSBkYXRhIGZldGNoaW5nIGNvZGUgb3Igc2lkZSBlZmZlY3RzIHRvIGNvbXBvbmVudERpZFVwZGF0ZS5cXG4nICsgJyogUmVuYW1lIGNvbXBvbmVudFdpbGxVcGRhdGUgdG8gVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgdG8gc3VwcHJlc3MgJyArICd0aGlzIHdhcm5pbmcgaW4gbm9uLXN0cmljdCBtb2RlLiBJbiBSZWFjdCAxOC54LCBvbmx5IHRoZSBVTlNBRkVfIG5hbWUgd2lsbCB3b3JrLiAnICsgJ1RvIHJlbmFtZSBhbGwgZGVwcmVjYXRlZCBsaWZlY3ljbGVzIHRvIHRoZWlyIG5ldyBuYW1lcywgeW91IGNhbiBydW4gJyArICdgbnB4IHJlYWN0LWNvZGVtb2QgcmVuYW1lLXVuc2FmZS1saWZlY3ljbGVzYCBpbiB5b3VyIHByb2plY3Qgc291cmNlIGZvbGRlci5cXG4nICsgJ1xcblBsZWFzZSB1cGRhdGUgdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAlcycsIF9zb3J0ZWROYW1lczUpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcGVuZGluZ0xlZ2FjeUNvbnRleHRXYXJuaW5nID0gbmV3IE1hcCgpOyAvLyBUcmFja3MgY29tcG9uZW50cyB3ZSBoYXZlIGFscmVhZHkgd2FybmVkIGFib3V0LlxuXG4gIHZhciBkaWRXYXJuQWJvdXRMZWdhY3lDb250ZXh0ID0gbmV3IFNldCgpO1xuXG4gIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZExlZ2FjeUNvbnRleHRXYXJuaW5nID0gZnVuY3Rpb24gKGZpYmVyLCBpbnN0YW5jZSkge1xuICAgIHZhciBzdHJpY3RSb290ID0gZmluZFN0cmljdFJvb3QoZmliZXIpO1xuXG4gICAgaWYgKHN0cmljdFJvb3QgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCB0byBmaW5kIGEgU3RyaWN0TW9kZSBjb21wb25lbnQgaW4gYSBzdHJpY3QgbW9kZSB0cmVlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9IC8vIERlZHVwIHN0cmF0ZWd5OiBXYXJuIG9uY2UgcGVyIGNvbXBvbmVudC5cblxuXG4gICAgaWYgKGRpZFdhcm5BYm91dExlZ2FjeUNvbnRleHQuaGFzKGZpYmVyLnR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHdhcm5pbmdzRm9yUm9vdCA9IHBlbmRpbmdMZWdhY3lDb250ZXh0V2FybmluZy5nZXQoc3RyaWN0Um9vdCk7XG5cbiAgICBpZiAoZmliZXIudHlwZS5jb250ZXh0VHlwZXMgIT0gbnVsbCB8fCBmaWJlci50eXBlLmNoaWxkQ29udGV4dFR5cGVzICE9IG51bGwgfHwgaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlLmdldENoaWxkQ29udGV4dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHdhcm5pbmdzRm9yUm9vdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHdhcm5pbmdzRm9yUm9vdCA9IFtdO1xuICAgICAgICBwZW5kaW5nTGVnYWN5Q29udGV4dFdhcm5pbmcuc2V0KHN0cmljdFJvb3QsIHdhcm5pbmdzRm9yUm9vdCk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5pbmdzRm9yUm9vdC5wdXNoKGZpYmVyKTtcbiAgICB9XG4gIH07XG5cbiAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICBwZW5kaW5nTGVnYWN5Q29udGV4dFdhcm5pbmcuZm9yRWFjaChmdW5jdGlvbiAoZmliZXJBcnJheSwgc3RyaWN0Um9vdCkge1xuICAgICAgaWYgKGZpYmVyQXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGZpcnN0RmliZXIgPSBmaWJlckFycmF5WzBdO1xuICAgICAgdmFyIHVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuICAgICAgZmliZXJBcnJheS5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICB1bmlxdWVOYW1lcy5hZGQoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgICBkaWRXYXJuQWJvdXRMZWdhY3lDb250ZXh0LmFkZChmaWJlci50eXBlKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIHNvcnRlZE5hbWVzID0gc2V0VG9Tb3J0ZWRTdHJpbmcodW5pcXVlTmFtZXMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBzZXRDdXJyZW50RmliZXIoZmlyc3RGaWJlcik7XG5cbiAgICAgICAgZXJyb3IoJ0xlZ2FjeSBjb250ZXh0IEFQSSBoYXMgYmVlbiBkZXRlY3RlZCB3aXRoaW4gYSBzdHJpY3QtbW9kZSB0cmVlLicgKyAnXFxuXFxuVGhlIG9sZCBBUEkgd2lsbCBiZSBzdXBwb3J0ZWQgaW4gYWxsIDE2LnggcmVsZWFzZXMsIGJ1dCBhcHBsaWNhdGlvbnMgJyArICd1c2luZyBpdCBzaG91bGQgbWlncmF0ZSB0byB0aGUgbmV3IHZlcnNpb24uJyArICdcXG5cXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnICsgJ1xcblxcbkxlYXJuIG1vcmUgYWJvdXQgdGhpcyB3YXJuaW5nIGhlcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9sZWdhY3ktY29udGV4dCcsIHNvcnRlZE5hbWVzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZGlzY2FyZFBlbmRpbmdXYXJuaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxNb3VudFdhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncyA9IFtdO1xuICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1dhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdO1xuICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0xlZ2FjeUNvbnRleHRXYXJuaW5nID0gbmV3IE1hcCgpO1xuICB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudCwgYmFzZVByb3BzKSB7XG4gIGlmIChDb21wb25lbnQgJiYgQ29tcG9uZW50LmRlZmF1bHRQcm9wcykge1xuICAgIC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wcy4gVGFrZW4gZnJvbSBSZWFjdEVsZW1lbnRcbiAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIGJhc2VQcm9wcyk7XG4gICAgdmFyIGRlZmF1bHRQcm9wcyA9IENvbXBvbmVudC5kZWZhdWx0UHJvcHM7XG5cbiAgICBmb3IgKHZhciBwcm9wTmFtZSBpbiBkZWZhdWx0UHJvcHMpIHtcbiAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkZWZhdWx0UHJvcHNbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9wcztcbiAgfVxuXG4gIHJldHVybiBiYXNlUHJvcHM7XG59XG5cbnZhciB2YWx1ZUN1cnNvciA9IGNyZWF0ZUN1cnNvcihudWxsKTtcbnZhciByZW5kZXJlclNpZ2lsO1xuXG57XG4gIC8vIFVzZSB0aGlzIHRvIGRldGVjdCBtdWx0aXBsZSByZW5kZXJlcnMgdXNpbmcgdGhlIHNhbWUgY29udGV4dFxuICByZW5kZXJlclNpZ2lsID0ge307XG59XG5cbnZhciBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IG51bGw7XG52YXIgbGFzdENvbnRleHREZXBlbmRlbmN5ID0gbnVsbDtcbnZhciBsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPSBudWxsO1xudmFyIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSBmYWxzZTtcbmZ1bmN0aW9uIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpIHtcbiAgLy8gVGhpcyBpcyBjYWxsZWQgcmlnaHQgYmVmb3JlIFJlYWN0IHlpZWxkcyBleGVjdXRpb24sIHRvIGVuc3VyZSBgcmVhZENvbnRleHRgXG4gIC8vIGNhbm5vdCBiZSBjYWxsZWQgb3V0c2lkZSB0aGUgcmVuZGVyIHBoYXNlLlxuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IG51bGw7XG4gIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IG51bGw7XG4gIGxhc3RGdWxseU9ic2VydmVkQ29udGV4dCA9IG51bGw7XG5cbiAge1xuICAgIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gZW50ZXJEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpIHtcbiAge1xuICAgIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSB0cnVlO1xuICB9XG59XG5mdW5jdGlvbiBleGl0RGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKSB7XG4gIHtcbiAgICBpc0Rpc2FsbG93ZWRDb250ZXh0UmVhZEluREVWID0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIHB1c2hQcm92aWRlcihwcm92aWRlckZpYmVyLCBjb250ZXh0LCBuZXh0VmFsdWUpIHtcbiAge1xuICAgIHB1c2godmFsdWVDdXJzb3IsIGNvbnRleHQuX2N1cnJlbnRWYWx1ZSwgcHJvdmlkZXJGaWJlcik7XG4gICAgY29udGV4dC5fY3VycmVudFZhbHVlID0gbmV4dFZhbHVlO1xuXG4gICAge1xuICAgICAgaWYgKGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciAhPT0gdW5kZWZpbmVkICYmIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciAhPT0gbnVsbCAmJiBjb250ZXh0Ll9jdXJyZW50UmVuZGVyZXIgIT09IHJlbmRlcmVyU2lnaWwpIHtcbiAgICAgICAgZXJyb3IoJ0RldGVjdGVkIG11bHRpcGxlIHJlbmRlcmVycyBjb25jdXJyZW50bHkgcmVuZGVyaW5nIHRoZSAnICsgJ3NhbWUgY29udGV4dCBwcm92aWRlci4gVGhpcyBpcyBjdXJyZW50bHkgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciA9IHJlbmRlcmVyU2lnaWw7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwb3BQcm92aWRlcihjb250ZXh0LCBwcm92aWRlckZpYmVyKSB7XG4gIHZhciBjdXJyZW50VmFsdWUgPSB2YWx1ZUN1cnNvci5jdXJyZW50O1xuICBwb3AodmFsdWVDdXJzb3IsIHByb3ZpZGVyRmliZXIpO1xuXG4gIHtcbiAgICB7XG4gICAgICBjb250ZXh0Ll9jdXJyZW50VmFsdWUgPSBjdXJyZW50VmFsdWU7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBzY2hlZHVsZUNvbnRleHRXb3JrT25QYXJlbnRQYXRoKHBhcmVudCwgcmVuZGVyTGFuZXMsIHByb3BhZ2F0aW9uUm9vdCkge1xuICAvLyBVcGRhdGUgdGhlIGNoaWxkIGxhbmVzIG9mIGFsbCB0aGUgYW5jZXN0b3JzLCBpbmNsdWRpbmcgdGhlIGFsdGVybmF0ZXMuXG4gIHZhciBub2RlID0gcGFyZW50O1xuXG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgdmFyIGFsdGVybmF0ZSA9IG5vZGUuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKCFpc1N1YnNldE9mTGFuZXMobm9kZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcykpIHtcbiAgICAgIG5vZGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobm9kZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgYWx0ZXJuYXRlLmNoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKGFsdGVybmF0ZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChhbHRlcm5hdGUgIT09IG51bGwgJiYgIWlzU3Vic2V0T2ZMYW5lcyhhbHRlcm5hdGUuY2hpbGRMYW5lcywgcmVuZGVyTGFuZXMpKSB7XG4gICAgICBhbHRlcm5hdGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmNoaWxkTGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICB9XG5cbiAgICBpZiAobm9kZSA9PT0gcHJvcGFnYXRpb25Sb290KSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gIH1cblxuICB7XG4gICAgaWYgKG5vZGUgIT09IHByb3BhZ2F0aW9uUm9vdCkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgdGhlIHByb3BhZ2F0aW9uIHJvb3Qgd2hlbiBzY2hlZHVsaW5nIGNvbnRleHQgd29yay4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcHJvcGFnYXRlQ29udGV4dENoYW5nZSh3b3JrSW5Qcm9ncmVzcywgY29udGV4dCwgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIHByb3BhZ2F0ZUNvbnRleHRDaGFuZ2VfZWFnZXIod29ya0luUHJvZ3Jlc3MsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9wYWdhdGVDb250ZXh0Q2hhbmdlX2VhZ2VyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCByZW5kZXJMYW5lcykge1xuXG4gIHZhciBmaWJlciA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gIGlmIChmaWJlciAhPT0gbnVsbCkge1xuICAgIC8vIFNldCB0aGUgcmV0dXJuIHBvaW50ZXIgb2YgdGhlIGNoaWxkIHRvIHRoZSB3b3JrLWluLXByb2dyZXNzIGZpYmVyLlxuICAgIGZpYmVyLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB9XG5cbiAgd2hpbGUgKGZpYmVyICE9PSBudWxsKSB7XG4gICAgdmFyIG5leHRGaWJlciA9IHZvaWQgMDsgLy8gVmlzaXQgdGhpcyBmaWJlci5cblxuICAgIHZhciBsaXN0ID0gZmliZXIuZGVwZW5kZW5jaWVzO1xuXG4gICAgaWYgKGxpc3QgIT09IG51bGwpIHtcbiAgICAgIG5leHRGaWJlciA9IGZpYmVyLmNoaWxkO1xuICAgICAgdmFyIGRlcGVuZGVuY3kgPSBsaXN0LmZpcnN0Q29udGV4dDtcblxuICAgICAgd2hpbGUgKGRlcGVuZGVuY3kgIT09IG51bGwpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNvbnRleHQgbWF0Y2hlcy5cbiAgICAgICAgaWYgKGRlcGVuZGVuY3kuY29udGV4dCA9PT0gY29udGV4dCkge1xuICAgICAgICAgIC8vIE1hdGNoISBTY2hlZHVsZSBhbiB1cGRhdGUgb24gdGhpcyBmaWJlci5cbiAgICAgICAgICBpZiAoZmliZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgICAgICAgLy8gU2NoZWR1bGUgYSBmb3JjZSB1cGRhdGUgb24gdGhlIHdvcmstaW4tcHJvZ3Jlc3MuXG4gICAgICAgICAgICB2YXIgbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJlbmRlckxhbmVzKTtcbiAgICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIGxhbmUpO1xuICAgICAgICAgICAgdXBkYXRlLnRhZyA9IEZvcmNlVXBkYXRlOyAvLyBUT0RPOiBCZWNhdXNlIHdlIGRvbid0IGhhdmUgYSB3b3JrLWluLXByb2dyZXNzLCB0aGlzIHdpbGwgYWRkIHRoZVxuICAgICAgICAgICAgLy8gdXBkYXRlIHRvIHRoZSBjdXJyZW50IGZpYmVyLCB0b28sIHdoaWNoIG1lYW5zIGl0IHdpbGwgcGVyc2lzdCBldmVuIGlmXG4gICAgICAgICAgICAvLyB0aGlzIHJlbmRlciBpcyB0aHJvd24gYXdheS4gU2luY2UgaXQncyBhIHJhY2UgY29uZGl0aW9uLCBub3Qgc3VyZSBpdCdzXG4gICAgICAgICAgICAvLyB3b3J0aCBmaXhpbmcuXG4gICAgICAgICAgICAvLyBJbmxpbmVkIGBlbnF1ZXVlVXBkYXRlYCB0byByZW1vdmUgaW50ZXJsZWF2ZWQgdXBkYXRlIGNoZWNrXG5cbiAgICAgICAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IGZpYmVyLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgICAgICBpZiAodXBkYXRlUXVldWUgPT09IG51bGwpIDsgZWxzZSB7XG4gICAgICAgICAgICAgIHZhciBzaGFyZWRRdWV1ZSA9IHVwZGF0ZVF1ZXVlLnNoYXJlZDtcbiAgICAgICAgICAgICAgdmFyIHBlbmRpbmcgPSBzaGFyZWRRdWV1ZS5wZW5kaW5nO1xuXG4gICAgICAgICAgICAgIGlmIChwZW5kaW5nID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgICAgICAgICAgICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZS5uZXh0ID0gcGVuZGluZy5uZXh0O1xuICAgICAgICAgICAgICAgIHBlbmRpbmcubmV4dCA9IHVwZGF0ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHNoYXJlZFF1ZXVlLnBlbmRpbmcgPSB1cGRhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKGZpYmVyLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGFsdGVybmF0ZS5sYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2NoZWR1bGVDb250ZXh0V29ya09uUGFyZW50UGF0aChmaWJlci5yZXR1cm4sIHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcyk7IC8vIE1hcmsgdGhlIHVwZGF0ZWQgbGFuZXMgb24gdGhlIGxpc3QsIHRvby5cblxuICAgICAgICAgIGxpc3QubGFuZXMgPSBtZXJnZUxhbmVzKGxpc3QubGFuZXMsIHJlbmRlckxhbmVzKTsgLy8gU2luY2Ugd2UgYWxyZWFkeSBmb3VuZCBhIG1hdGNoLCB3ZSBjYW4gc3RvcCB0cmF2ZXJzaW5nIHRoZVxuICAgICAgICAgIC8vIGRlcGVuZGVuY3kgbGlzdC5cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVwZW5kZW5jeSA9IGRlcGVuZGVuY3kubmV4dDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZpYmVyLnRhZyA9PT0gQ29udGV4dFByb3ZpZGVyKSB7XG4gICAgICAvLyBEb24ndCBzY2FuIGRlZXBlciBpZiB0aGlzIGlzIGEgbWF0Y2hpbmcgcHJvdmlkZXJcbiAgICAgIG5leHRGaWJlciA9IGZpYmVyLnR5cGUgPT09IHdvcmtJblByb2dyZXNzLnR5cGUgPyBudWxsIDogZmliZXIuY2hpbGQ7XG4gICAgfSBlbHNlIGlmIChmaWJlci50YWcgPT09IERlaHlkcmF0ZWRGcmFnbWVudCkge1xuICAgICAgLy8gSWYgYSBkZWh5ZHJhdGVkIHN1c3BlbnNlIGJvdW5kYXJ5IGlzIGluIHRoaXMgc3VidHJlZSwgd2UgZG9uJ3Qga25vd1xuICAgICAgLy8gaWYgaXQgd2lsbCBoYXZlIGFueSBjb250ZXh0IGNvbnN1bWVycyBpbiBpdC4gVGhlIGJlc3Qgd2UgY2FuIGRvIGlzXG4gICAgICAvLyBtYXJrIGl0IGFzIGhhdmluZyB1cGRhdGVzLlxuICAgICAgdmFyIHBhcmVudFN1c3BlbnNlID0gZmliZXIucmV0dXJuO1xuXG4gICAgICBpZiAocGFyZW50U3VzcGVuc2UgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZSBqdXN0IGNhbWUgZnJvbSBhIHBhcmVudCBzbyB3ZSBtdXN0IGhhdmUgaGFkIGEgcGFyZW50LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnRTdXNwZW5zZS5sYW5lcyA9IG1lcmdlTGFuZXMocGFyZW50U3VzcGVuc2UubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICAgIHZhciBfYWx0ZXJuYXRlID0gcGFyZW50U3VzcGVuc2UuYWx0ZXJuYXRlO1xuXG4gICAgICBpZiAoX2FsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgICBfYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhfYWx0ZXJuYXRlLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9IC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBwYXNzaW5nIHRoaXMgZmliZXIgYXMgdGhlIHBhcmVudFxuICAgICAgLy8gYmVjYXVzZSB3ZSB3YW50IHRvIHNjaGVkdWxlIHRoaXMgZmliZXIgYXMgaGF2aW5nIHdvcmtcbiAgICAgIC8vIG9uIGl0cyBjaGlsZHJlbi4gV2UnbGwgdXNlIHRoZSBjaGlsZExhbmVzIG9uXG4gICAgICAvLyB0aGlzIGZpYmVyIHRvIGluZGljYXRlIHRoYXQgYSBjb250ZXh0IGhhcyBjaGFuZ2VkLlxuXG5cbiAgICAgIHNjaGVkdWxlQ29udGV4dFdvcmtPblBhcmVudFBhdGgocGFyZW50U3VzcGVuc2UsIHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBuZXh0RmliZXIgPSBmaWJlci5zaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUcmF2ZXJzZSBkb3duLlxuICAgICAgbmV4dEZpYmVyID0gZmliZXIuY2hpbGQ7XG4gICAgfVxuXG4gICAgaWYgKG5leHRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgLy8gU2V0IHRoZSByZXR1cm4gcG9pbnRlciBvZiB0aGUgY2hpbGQgdG8gdGhlIHdvcmstaW4tcHJvZ3Jlc3MgZmliZXIuXG4gICAgICBuZXh0RmliZXIucmV0dXJuID0gZmliZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGNoaWxkLiBUcmF2ZXJzZSB0byBuZXh0IHNpYmxpbmcuXG4gICAgICBuZXh0RmliZXIgPSBmaWJlcjtcblxuICAgICAgd2hpbGUgKG5leHRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgICBpZiAobmV4dEZpYmVyID09PSB3b3JrSW5Qcm9ncmVzcykge1xuICAgICAgICAgIC8vIFdlJ3JlIGJhY2sgdG8gdGhlIHJvb3Qgb2YgdGhpcyBzdWJ0cmVlLiBFeGl0LlxuICAgICAgICAgIG5leHRGaWJlciA9IG51bGw7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2libGluZyA9IG5leHRGaWJlci5zaWJsaW5nO1xuXG4gICAgICAgIGlmIChzaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gU2V0IHRoZSByZXR1cm4gcG9pbnRlciBvZiB0aGUgc2libGluZyB0byB0aGUgd29yay1pbi1wcm9ncmVzcyBmaWJlci5cbiAgICAgICAgICBzaWJsaW5nLnJldHVybiA9IG5leHRGaWJlci5yZXR1cm47XG4gICAgICAgICAgbmV4dEZpYmVyID0gc2libGluZztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSAvLyBObyBtb3JlIHNpYmxpbmdzLiBUcmF2ZXJzZSB1cC5cblxuXG4gICAgICAgIG5leHRGaWJlciA9IG5leHRGaWJlci5yZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmliZXIgPSBuZXh0RmliZXI7XG4gIH1cbn1cbmZ1bmN0aW9uIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IHdvcmtJblByb2dyZXNzO1xuICBsYXN0Q29udGV4dERlcGVuZGVuY3kgPSBudWxsO1xuICBsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPSBudWxsO1xuICB2YXIgZGVwZW5kZW5jaWVzID0gd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzO1xuXG4gIGlmIChkZXBlbmRlbmNpZXMgIT09IG51bGwpIHtcbiAgICB7XG4gICAgICB2YXIgZmlyc3RDb250ZXh0ID0gZGVwZW5kZW5jaWVzLmZpcnN0Q29udGV4dDtcblxuICAgICAgaWYgKGZpcnN0Q29udGV4dCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaW5jbHVkZXNTb21lTGFuZShkZXBlbmRlbmNpZXMubGFuZXMsIHJlbmRlckxhbmVzKSkge1xuICAgICAgICAgIC8vIENvbnRleHQgbGlzdCBoYXMgYSBwZW5kaW5nIHVwZGF0ZS4gTWFyayB0aGF0IHRoaXMgZmliZXIgcGVyZm9ybWVkIHdvcmsuXG4gICAgICAgICAgbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKTtcbiAgICAgICAgfSAvLyBSZXNldCB0aGUgd29yay1pbi1wcm9ncmVzcyBsaXN0XG5cblxuICAgICAgICBkZXBlbmRlbmNpZXMuZmlyc3RDb250ZXh0ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHJlYWRDb250ZXh0KGNvbnRleHQpIHtcbiAge1xuICAgIC8vIFRoaXMgd2FybmluZyB3b3VsZCBmaXJlIGlmIHlvdSByZWFkIGNvbnRleHQgaW5zaWRlIGEgSG9vayBsaWtlIHVzZU1lbW8uXG4gICAgLy8gVW5saWtlIHRoZSBjbGFzcyBjaGVjayBiZWxvdywgaXQncyBub3QgZW5mb3JjZWQgaW4gcHJvZHVjdGlvbiBmb3IgcGVyZi5cbiAgICBpZiAoaXNEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVikge1xuICAgICAgZXJyb3IoJ0NvbnRleHQgY2FuIG9ubHkgYmUgcmVhZCB3aGlsZSBSZWFjdCBpcyByZW5kZXJpbmcuICcgKyAnSW4gY2xhc3NlcywgeW91IGNhbiByZWFkIGl0IGluIHRoZSByZW5kZXIgbWV0aG9kIG9yIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcy4gJyArICdJbiBmdW5jdGlvbiBjb21wb25lbnRzLCB5b3UgY2FuIHJlYWQgaXQgZGlyZWN0bHkgaW4gdGhlIGZ1bmN0aW9uIGJvZHksIGJ1dCBub3QgJyArICdpbnNpZGUgSG9va3MgbGlrZSB1c2VSZWR1Y2VyKCkgb3IgdXNlTWVtbygpLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciB2YWx1ZSA9ICBjb250ZXh0Ll9jdXJyZW50VmFsdWUgO1xuXG4gIGlmIChsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPT09IGNvbnRleHQpIDsgZWxzZSB7XG4gICAgdmFyIGNvbnRleHRJdGVtID0ge1xuICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgIG1lbW9pemVkVmFsdWU6IHZhbHVlLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG5cbiAgICBpZiAobGFzdENvbnRleHREZXBlbmRlbmN5ID09PSBudWxsKSB7XG4gICAgICBpZiAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZXh0IGNhbiBvbmx5IGJlIHJlYWQgd2hpbGUgUmVhY3QgaXMgcmVuZGVyaW5nLiAnICsgJ0luIGNsYXNzZXMsIHlvdSBjYW4gcmVhZCBpdCBpbiB0aGUgcmVuZGVyIG1ldGhvZCBvciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuICcgKyAnSW4gZnVuY3Rpb24gY29tcG9uZW50cywgeW91IGNhbiByZWFkIGl0IGRpcmVjdGx5IGluIHRoZSBmdW5jdGlvbiBib2R5LCBidXQgbm90ICcgKyAnaW5zaWRlIEhvb2tzIGxpa2UgdXNlUmVkdWNlcigpIG9yIHVzZU1lbW8oKS4nKTtcbiAgICAgIH0gLy8gVGhpcyBpcyB0aGUgZmlyc3QgZGVwZW5kZW5jeSBmb3IgdGhpcyBjb21wb25lbnQuIENyZWF0ZSBhIG5ldyBsaXN0LlxuXG5cbiAgICAgIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IGNvbnRleHRJdGVtO1xuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIuZGVwZW5kZW5jaWVzID0ge1xuICAgICAgICBsYW5lczogTm9MYW5lcyxcbiAgICAgICAgZmlyc3RDb250ZXh0OiBjb250ZXh0SXRlbVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXBwZW5kIGEgbmV3IGNvbnRleHQgaXRlbS5cbiAgICAgIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IGxhc3RDb250ZXh0RGVwZW5kZW5jeS5uZXh0ID0gY29udGV4dEl0ZW07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vLyBBbiBhcnJheSBvZiBhbGwgdXBkYXRlIHF1ZXVlcyB0aGF0IHJlY2VpdmVkIHVwZGF0ZXMgZHVyaW5nIHRoZSBjdXJyZW50XG4vLyByZW5kZXIuIFdoZW4gdGhpcyByZW5kZXIgZXhpdHMsIGVpdGhlciBiZWNhdXNlIGl0IGZpbmlzaGVzIG9yIGJlY2F1c2UgaXQgaXNcbi8vIGludGVycnVwdGVkLCB0aGUgaW50ZXJsZWF2ZWQgdXBkYXRlcyB3aWxsIGJlIHRyYW5zZmVycmVkIG9udG8gdGhlIG1haW4gcGFydFxuLy8gb2YgdGhlIHF1ZXVlLlxudmFyIGludGVybGVhdmVkUXVldWVzID0gbnVsbDtcbmZ1bmN0aW9uIHB1c2hJbnRlcmxlYXZlZFF1ZXVlKHF1ZXVlKSB7XG4gIGlmIChpbnRlcmxlYXZlZFF1ZXVlcyA9PT0gbnVsbCkge1xuICAgIGludGVybGVhdmVkUXVldWVzID0gW3F1ZXVlXTtcbiAgfSBlbHNlIHtcbiAgICBpbnRlcmxlYXZlZFF1ZXVlcy5wdXNoKHF1ZXVlKTtcbiAgfVxufVxuZnVuY3Rpb24gaGFzSW50ZXJsZWF2ZWRVcGRhdGVzKCkge1xuICByZXR1cm4gaW50ZXJsZWF2ZWRRdWV1ZXMgIT09IG51bGw7XG59XG5mdW5jdGlvbiBlbnF1ZXVlSW50ZXJsZWF2ZWRVcGRhdGVzKCkge1xuICAvLyBUcmFuc2ZlciB0aGUgaW50ZXJsZWF2ZWQgdXBkYXRlcyBvbnRvIHRoZSBtYWluIHF1ZXVlLiBFYWNoIHF1ZXVlIGhhcyBhXG4gIC8vIGBwZW5kaW5nYCBmaWVsZCBhbmQgYW4gYGludGVybGVhdmVkYCBmaWVsZC4gV2hlbiB0aGV5IGFyZSBub3QgbnVsbCwgdGhleVxuICAvLyBwb2ludCB0byB0aGUgbGFzdCBub2RlIGluIGEgY2lyY3VsYXIgbGlua2VkIGxpc3QuIFdlIG5lZWQgdG8gYXBwZW5kIHRoZVxuICAvLyBpbnRlcmxlYXZlZCBsaXN0IHRvIHRoZSBlbmQgb2YgdGhlIHBlbmRpbmcgbGlzdCBieSBqb2luaW5nIHRoZW0gaW50byBhXG4gIC8vIHNpbmdsZSwgY2lyY3VsYXIgbGlzdC5cbiAgaWYgKGludGVybGVhdmVkUXVldWVzICE9PSBudWxsKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnRlcmxlYXZlZFF1ZXVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHF1ZXVlID0gaW50ZXJsZWF2ZWRRdWV1ZXNbaV07XG4gICAgICB2YXIgbGFzdEludGVybGVhdmVkVXBkYXRlID0gcXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgICAgIGlmIChsYXN0SW50ZXJsZWF2ZWRVcGRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgcXVldWUuaW50ZXJsZWF2ZWQgPSBudWxsO1xuICAgICAgICB2YXIgZmlyc3RJbnRlcmxlYXZlZFVwZGF0ZSA9IGxhc3RJbnRlcmxlYXZlZFVwZGF0ZS5uZXh0O1xuICAgICAgICB2YXIgbGFzdFBlbmRpbmdVcGRhdGUgPSBxdWV1ZS5wZW5kaW5nO1xuXG4gICAgICAgIGlmIChsYXN0UGVuZGluZ1VwZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBmaXJzdFBlbmRpbmdVcGRhdGUgPSBsYXN0UGVuZGluZ1VwZGF0ZS5uZXh0O1xuICAgICAgICAgIGxhc3RQZW5kaW5nVXBkYXRlLm5leHQgPSBmaXJzdEludGVybGVhdmVkVXBkYXRlO1xuICAgICAgICAgIGxhc3RJbnRlcmxlYXZlZFVwZGF0ZS5uZXh0ID0gZmlyc3RQZW5kaW5nVXBkYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgcXVldWUucGVuZGluZyA9IGxhc3RJbnRlcmxlYXZlZFVwZGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnRlcmxlYXZlZFF1ZXVlcyA9IG51bGw7XG4gIH1cbn1cblxudmFyIFVwZGF0ZVN0YXRlID0gMDtcbnZhciBSZXBsYWNlU3RhdGUgPSAxO1xudmFyIEZvcmNlVXBkYXRlID0gMjtcbnZhciBDYXB0dXJlVXBkYXRlID0gMzsgLy8gR2xvYmFsIHN0YXRlIHRoYXQgaXMgcmVzZXQgYXQgdGhlIGJlZ2lubmluZyBvZiBjYWxsaW5nIGBwcm9jZXNzVXBkYXRlUXVldWVgLlxuLy8gSXQgc2hvdWxkIG9ubHkgYmUgcmVhZCByaWdodCBhZnRlciBjYWxsaW5nIGBwcm9jZXNzVXBkYXRlUXVldWVgLCB2aWFcbi8vIGBjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nYC5cblxudmFyIGhhc0ZvcmNlVXBkYXRlID0gZmFsc2U7XG52YXIgZGlkV2FyblVwZGF0ZUluc2lkZVVwZGF0ZTtcbnZhciBjdXJyZW50bHlQcm9jZXNzaW5nUXVldWU7XG5cbntcbiAgZGlkV2FyblVwZGF0ZUluc2lkZVVwZGF0ZSA9IGZhbHNlO1xuICBjdXJyZW50bHlQcm9jZXNzaW5nUXVldWUgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplVXBkYXRlUXVldWUoZmliZXIpIHtcbiAgdmFyIHF1ZXVlID0ge1xuICAgIGJhc2VTdGF0ZTogZmliZXIubWVtb2l6ZWRTdGF0ZSxcbiAgICBmaXJzdEJhc2VVcGRhdGU6IG51bGwsXG4gICAgbGFzdEJhc2VVcGRhdGU6IG51bGwsXG4gICAgc2hhcmVkOiB7XG4gICAgICBwZW5kaW5nOiBudWxsLFxuICAgICAgaW50ZXJsZWF2ZWQ6IG51bGwsXG4gICAgICBsYW5lczogTm9MYW5lc1xuICAgIH0sXG4gICAgZWZmZWN0czogbnVsbFxuICB9O1xuICBmaWJlci51cGRhdGVRdWV1ZSA9IHF1ZXVlO1xufVxuZnVuY3Rpb24gY2xvbmVVcGRhdGVRdWV1ZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcykge1xuICAvLyBDbG9uZSB0aGUgdXBkYXRlIHF1ZXVlIGZyb20gY3VycmVudC4gVW5sZXNzIGl0J3MgYWxyZWFkeSBhIGNsb25lLlxuICB2YXIgcXVldWUgPSB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZTtcbiAgdmFyIGN1cnJlbnRRdWV1ZSA9IGN1cnJlbnQudXBkYXRlUXVldWU7XG5cbiAgaWYgKHF1ZXVlID09PSBjdXJyZW50UXVldWUpIHtcbiAgICB2YXIgY2xvbmUgPSB7XG4gICAgICBiYXNlU3RhdGU6IGN1cnJlbnRRdWV1ZS5iYXNlU3RhdGUsXG4gICAgICBmaXJzdEJhc2VVcGRhdGU6IGN1cnJlbnRRdWV1ZS5maXJzdEJhc2VVcGRhdGUsXG4gICAgICBsYXN0QmFzZVVwZGF0ZTogY3VycmVudFF1ZXVlLmxhc3RCYXNlVXBkYXRlLFxuICAgICAgc2hhcmVkOiBjdXJyZW50UXVldWUuc2hhcmVkLFxuICAgICAgZWZmZWN0czogY3VycmVudFF1ZXVlLmVmZmVjdHNcbiAgICB9O1xuICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gY2xvbmU7XG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpIHtcbiAgdmFyIHVwZGF0ZSA9IHtcbiAgICBldmVudFRpbWU6IGV2ZW50VGltZSxcbiAgICBsYW5lOiBsYW5lLFxuICAgIHRhZzogVXBkYXRlU3RhdGUsXG4gICAgcGF5bG9hZDogbnVsbCxcbiAgICBjYWxsYmFjazogbnVsbCxcbiAgICBuZXh0OiBudWxsXG4gIH07XG4gIHJldHVybiB1cGRhdGU7XG59XG5mdW5jdGlvbiBlbnF1ZXVlVXBkYXRlKGZpYmVyLCB1cGRhdGUsIGxhbmUpIHtcbiAgdmFyIHVwZGF0ZVF1ZXVlID0gZmliZXIudXBkYXRlUXVldWU7XG5cbiAgaWYgKHVwZGF0ZVF1ZXVlID09PSBudWxsKSB7XG4gICAgLy8gT25seSBvY2N1cnMgaWYgdGhlIGZpYmVyIGhhcyBiZWVuIHVubW91bnRlZC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2hhcmVkUXVldWUgPSB1cGRhdGVRdWV1ZS5zaGFyZWQ7XG5cbiAgaWYgKGlzSW50ZXJsZWF2ZWRVcGRhdGUoZmliZXIpKSB7XG4gICAgdmFyIGludGVybGVhdmVkID0gc2hhcmVkUXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgICBpZiAoaW50ZXJsZWF2ZWQgPT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IHVwZGF0ZS4gQ3JlYXRlIGEgY2lyY3VsYXIgbGlzdC5cbiAgICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlOyAvLyBBdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHJlbmRlciwgdGhpcyBxdWV1ZSdzIGludGVybGVhdmVkIHVwZGF0ZXMgd2lsbFxuICAgICAgLy8gYmUgdHJhbnNmZXJyZWQgdG8gdGhlIHBlbmRpbmcgcXVldWUuXG5cbiAgICAgIHB1c2hJbnRlcmxlYXZlZFF1ZXVlKHNoYXJlZFF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlLm5leHQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgICAgaW50ZXJsZWF2ZWQubmV4dCA9IHVwZGF0ZTtcbiAgICB9XG5cbiAgICBzaGFyZWRRdWV1ZS5pbnRlcmxlYXZlZCA9IHVwZGF0ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcGVuZGluZyA9IHNoYXJlZFF1ZXVlLnBlbmRpbmc7XG5cbiAgICBpZiAocGVuZGluZyA9PT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgICAgdXBkYXRlLm5leHQgPSB1cGRhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZS5uZXh0ID0gcGVuZGluZy5uZXh0O1xuICAgICAgcGVuZGluZy5uZXh0ID0gdXBkYXRlO1xuICAgIH1cblxuICAgIHNoYXJlZFF1ZXVlLnBlbmRpbmcgPSB1cGRhdGU7XG4gIH1cblxuICB7XG4gICAgaWYgKGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZSA9PT0gc2hhcmVkUXVldWUgJiYgIWRpZFdhcm5VcGRhdGVJbnNpZGVVcGRhdGUpIHtcbiAgICAgIGVycm9yKCdBbiB1cGRhdGUgKHNldFN0YXRlLCByZXBsYWNlU3RhdGUsIG9yIGZvcmNlVXBkYXRlKSB3YXMgc2NoZWR1bGVkICcgKyAnZnJvbSBpbnNpZGUgYW4gdXBkYXRlIGZ1bmN0aW9uLiBVcGRhdGUgZnVuY3Rpb25zIHNob3VsZCBiZSBwdXJlLCAnICsgJ3dpdGggemVybyBzaWRlLWVmZmVjdHMuIENvbnNpZGVyIHVzaW5nIGNvbXBvbmVudERpZFVwZGF0ZSBvciBhICcgKyAnY2FsbGJhY2suJyk7XG5cbiAgICAgIGRpZFdhcm5VcGRhdGVJbnNpZGVVcGRhdGUgPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZW50YW5nbGVUcmFuc2l0aW9ucyhyb290LCBmaWJlciwgbGFuZSkge1xuICB2YXIgdXBkYXRlUXVldWUgPSBmaWJlci51cGRhdGVRdWV1ZTtcblxuICBpZiAodXBkYXRlUXVldWUgPT09IG51bGwpIHtcbiAgICAvLyBPbmx5IG9jY3VycyBpZiB0aGUgZmliZXIgaGFzIGJlZW4gdW5tb3VudGVkLlxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzaGFyZWRRdWV1ZSA9IHVwZGF0ZVF1ZXVlLnNoYXJlZDtcblxuICBpZiAoaXNUcmFuc2l0aW9uTGFuZShsYW5lKSkge1xuICAgIHZhciBxdWV1ZUxhbmVzID0gc2hhcmVkUXVldWUubGFuZXM7IC8vIElmIGFueSBlbnRhbmdsZWQgbGFuZXMgYXJlIG5vIGxvbmdlciBwZW5kaW5nIG9uIHRoZSByb290LCB0aGVuIHRoZXkgbXVzdFxuICAgIC8vIGhhdmUgZmluaXNoZWQuIFdlIGNhbiByZW1vdmUgdGhlbSBmcm9tIHRoZSBzaGFyZWQgcXVldWUsIHdoaWNoIHJlcHJlc2VudHNcbiAgICAvLyBhIHN1cGVyc2V0IG9mIHRoZSBhY3R1YWxseSBwZW5kaW5nIGxhbmVzLiBJbiBzb21lIGNhc2VzIHdlIG1heSBlbnRhbmdsZVxuICAgIC8vIG1vcmUgdGhhbiB3ZSBuZWVkIHRvLCBidXQgdGhhdCdzIE9LLiBJbiBmYWN0IGl0J3Mgd29yc2UgaWYgd2UgKmRvbid0KlxuICAgIC8vIGVudGFuZ2xlIHdoZW4gd2Ugc2hvdWxkLlxuXG4gICAgcXVldWVMYW5lcyA9IGludGVyc2VjdExhbmVzKHF1ZXVlTGFuZXMsIHJvb3QucGVuZGluZ0xhbmVzKTsgLy8gRW50YW5nbGUgdGhlIG5ldyB0cmFuc2l0aW9uIGxhbmUgd2l0aCB0aGUgb3RoZXIgdHJhbnNpdGlvbiBsYW5lcy5cblxuICAgIHZhciBuZXdRdWV1ZUxhbmVzID0gbWVyZ2VMYW5lcyhxdWV1ZUxhbmVzLCBsYW5lKTtcbiAgICBzaGFyZWRRdWV1ZS5sYW5lcyA9IG5ld1F1ZXVlTGFuZXM7IC8vIEV2ZW4gaWYgcXVldWUubGFuZXMgYWxyZWFkeSBpbmNsdWRlIGxhbmUsIHdlIGRvbid0IGtub3cgZm9yIGNlcnRhaW4gaWZcbiAgICAvLyB0aGUgbGFuZSBmaW5pc2hlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHdlIGVudGFuZ2xlZCBpdC4gU28gd2UgbmVlZCB0b1xuICAgIC8vIGVudGFuZ2xlIGl0IGFnYWluLCBqdXN0IHRvIGJlIHN1cmUuXG5cbiAgICBtYXJrUm9vdEVudGFuZ2xlZChyb290LCBuZXdRdWV1ZUxhbmVzKTtcbiAgfVxufVxuZnVuY3Rpb24gZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCBjYXB0dXJlZFVwZGF0ZSkge1xuICAvLyBDYXB0dXJlZCB1cGRhdGVzIGFyZSB1cGRhdGVzIHRoYXQgYXJlIHRocm93biBieSBhIGNoaWxkIGR1cmluZyB0aGUgcmVuZGVyXG4gIC8vIHBoYXNlLiBUaGV5IHNob3VsZCBiZSBkaXNjYXJkZWQgaWYgdGhlIHJlbmRlciBpcyBhYm9ydGVkLiBUaGVyZWZvcmUsXG4gIC8vIHdlIHNob3VsZCBvbmx5IHB1dCB0aGVtIG9uIHRoZSB3b3JrLWluLXByb2dyZXNzIHF1ZXVlLCBub3QgdGhlIGN1cnJlbnQgb25lLlxuICB2YXIgcXVldWUgPSB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZTsgLy8gQ2hlY2sgaWYgdGhlIHdvcmstaW4tcHJvZ3Jlc3MgcXVldWUgaXMgYSBjbG9uZS5cblxuICB2YXIgY3VycmVudCA9IHdvcmtJblByb2dyZXNzLmFsdGVybmF0ZTtcblxuICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgIHZhciBjdXJyZW50UXVldWUgPSBjdXJyZW50LnVwZGF0ZVF1ZXVlO1xuXG4gICAgaWYgKHF1ZXVlID09PSBjdXJyZW50UXVldWUpIHtcbiAgICAgIC8vIFRoZSB3b3JrLWluLXByb2dyZXNzIHF1ZXVlIGlzIHRoZSBzYW1lIGFzIGN1cnJlbnQuIFRoaXMgaGFwcGVucyB3aGVuXG4gICAgICAvLyB3ZSBiYWlsIG91dCBvbiBhIHBhcmVudCBmaWJlciB0aGF0IHRoZW4gY2FwdHVyZXMgYW4gZXJyb3IgdGhyb3duIGJ5XG4gICAgICAvLyBhIGNoaWxkLiBTaW5jZSB3ZSB3YW50IHRvIGFwcGVuZCB0aGUgdXBkYXRlIG9ubHkgdG8gdGhlIHdvcmstaW5cbiAgICAgIC8vIC1wcm9ncmVzcyBxdWV1ZSwgd2UgbmVlZCB0byBjbG9uZSB0aGUgdXBkYXRlcy4gV2UgdXN1YWxseSBjbG9uZSBkdXJpbmdcbiAgICAgIC8vIHByb2Nlc3NVcGRhdGVRdWV1ZSwgYnV0IHRoYXQgZGlkbid0IGhhcHBlbiBpbiB0aGlzIGNhc2UgYmVjYXVzZSB3ZVxuICAgICAgLy8gc2tpcHBlZCBvdmVyIHRoZSBwYXJlbnQgd2hlbiB3ZSBiYWlsZWQgb3V0LlxuICAgICAgdmFyIG5ld0ZpcnN0ID0gbnVsbDtcbiAgICAgIHZhciBuZXdMYXN0ID0gbnVsbDtcbiAgICAgIHZhciBmaXJzdEJhc2VVcGRhdGUgPSBxdWV1ZS5maXJzdEJhc2VVcGRhdGU7XG5cbiAgICAgIGlmIChmaXJzdEJhc2VVcGRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgLy8gTG9vcCB0aHJvdWdoIHRoZSB1cGRhdGVzIGFuZCBjbG9uZSB0aGVtLlxuICAgICAgICB2YXIgdXBkYXRlID0gZmlyc3RCYXNlVXBkYXRlO1xuXG4gICAgICAgIGRvIHtcbiAgICAgICAgICB2YXIgY2xvbmUgPSB7XG4gICAgICAgICAgICBldmVudFRpbWU6IHVwZGF0ZS5ldmVudFRpbWUsXG4gICAgICAgICAgICBsYW5lOiB1cGRhdGUubGFuZSxcbiAgICAgICAgICAgIHRhZzogdXBkYXRlLnRhZyxcbiAgICAgICAgICAgIHBheWxvYWQ6IHVwZGF0ZS5wYXlsb2FkLFxuICAgICAgICAgICAgY2FsbGJhY2s6IHVwZGF0ZS5jYWxsYmFjayxcbiAgICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgaWYgKG5ld0xhc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIG5ld0ZpcnN0ID0gbmV3TGFzdCA9IGNsb25lO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdMYXN0Lm5leHQgPSBjbG9uZTtcbiAgICAgICAgICAgIG5ld0xhc3QgPSBjbG9uZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB1cGRhdGUgPSB1cGRhdGUubmV4dDtcbiAgICAgICAgfSB3aGlsZSAodXBkYXRlICE9PSBudWxsKTsgLy8gQXBwZW5kIHRoZSBjYXB0dXJlZCB1cGRhdGUgdGhlIGVuZCBvZiB0aGUgY2xvbmVkIGxpc3QuXG5cblxuICAgICAgICBpZiAobmV3TGFzdCA9PT0gbnVsbCkge1xuICAgICAgICAgIG5ld0ZpcnN0ID0gbmV3TGFzdCA9IGNhcHR1cmVkVXBkYXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0xhc3QubmV4dCA9IGNhcHR1cmVkVXBkYXRlO1xuICAgICAgICAgIG5ld0xhc3QgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhlcmUgYXJlIG5vIGJhc2UgdXBkYXRlcy5cbiAgICAgICAgbmV3Rmlyc3QgPSBuZXdMYXN0ID0gY2FwdHVyZWRVcGRhdGU7XG4gICAgICB9XG5cbiAgICAgIHF1ZXVlID0ge1xuICAgICAgICBiYXNlU3RhdGU6IGN1cnJlbnRRdWV1ZS5iYXNlU3RhdGUsXG4gICAgICAgIGZpcnN0QmFzZVVwZGF0ZTogbmV3Rmlyc3QsXG4gICAgICAgIGxhc3RCYXNlVXBkYXRlOiBuZXdMYXN0LFxuICAgICAgICBzaGFyZWQ6IGN1cnJlbnRRdWV1ZS5zaGFyZWQsXG4gICAgICAgIGVmZmVjdHM6IGN1cnJlbnRRdWV1ZS5lZmZlY3RzXG4gICAgICB9O1xuICAgICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBxdWV1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0gLy8gQXBwZW5kIHRoZSB1cGRhdGUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC5cblxuXG4gIHZhciBsYXN0QmFzZVVwZGF0ZSA9IHF1ZXVlLmxhc3RCYXNlVXBkYXRlO1xuXG4gIGlmIChsYXN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgIHF1ZXVlLmZpcnN0QmFzZVVwZGF0ZSA9IGNhcHR1cmVkVXBkYXRlO1xuICB9IGVsc2Uge1xuICAgIGxhc3RCYXNlVXBkYXRlLm5leHQgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgfVxuXG4gIHF1ZXVlLmxhc3RCYXNlVXBkYXRlID0gY2FwdHVyZWRVcGRhdGU7XG59XG5cbmZ1bmN0aW9uIGdldFN0YXRlRnJvbVVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgcXVldWUsIHVwZGF0ZSwgcHJldlN0YXRlLCBuZXh0UHJvcHMsIGluc3RhbmNlKSB7XG4gIHN3aXRjaCAodXBkYXRlLnRhZykge1xuICAgIGNhc2UgUmVwbGFjZVN0YXRlOlxuICAgICAge1xuICAgICAgICB2YXIgcGF5bG9hZCA9IHVwZGF0ZS5wYXlsb2FkO1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5bG9hZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIC8vIFVwZGF0ZXIgZnVuY3Rpb25cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlbnRlckRpc2FsbG93ZWRDb250ZXh0UmVhZEluREVWKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIG5leHRTdGF0ZSA9IHBheWxvYWQuY2FsbChpbnN0YW5jZSwgcHJldlN0YXRlLCBuZXh0UHJvcHMpO1xuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKCB3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgICAgICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyh0cnVlKTtcblxuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBheWxvYWQuY2FsbChpbnN0YW5jZSwgcHJldlN0YXRlLCBuZXh0UHJvcHMpO1xuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleGl0RGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbmV4dFN0YXRlO1xuICAgICAgICB9IC8vIFN0YXRlIG9iamVjdFxuXG5cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICB9XG5cbiAgICBjYXNlIENhcHR1cmVVcGRhdGU6XG4gICAgICB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7XG4gICAgICB9XG4gICAgLy8gSW50ZW50aW9uYWwgZmFsbHRocm91Z2hcblxuICAgIGNhc2UgVXBkYXRlU3RhdGU6XG4gICAgICB7XG4gICAgICAgIHZhciBfcGF5bG9hZCA9IHVwZGF0ZS5wYXlsb2FkO1xuICAgICAgICB2YXIgcGFydGlhbFN0YXRlO1xuXG4gICAgICAgIGlmICh0eXBlb2YgX3BheWxvYWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAvLyBVcGRhdGVyIGZ1bmN0aW9uXG4gICAgICAgICAge1xuICAgICAgICAgICAgZW50ZXJEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHBhcnRpYWxTdGF0ZSA9IF9wYXlsb2FkLmNhbGwoaW5zdGFuY2UsIHByZXZTdGF0ZSwgbmV4dFByb3BzKTtcblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHModHJ1ZSk7XG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBfcGF5bG9hZC5jYWxsKGluc3RhbmNlLCBwcmV2U3RhdGUsIG5leHRQcm9wcyk7XG4gICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4aXREaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBQYXJ0aWFsIHN0YXRlIG9iamVjdFxuICAgICAgICAgIHBhcnRpYWxTdGF0ZSA9IF9wYXlsb2FkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnRpYWxTdGF0ZSA9PT0gbnVsbCB8fCBwYXJ0aWFsU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIE51bGwgYW5kIHVuZGVmaW5lZCBhcmUgdHJlYXRlZCBhcyBuby1vcHMuXG4gICAgICAgICAgcmV0dXJuIHByZXZTdGF0ZTtcbiAgICAgICAgfSAvLyBNZXJnZSB0aGUgcGFydGlhbCBzdGF0ZSBhbmQgdGhlIHByZXZpb3VzIHN0YXRlLlxuXG5cbiAgICAgICAgcmV0dXJuIGFzc2lnbih7fSwgcHJldlN0YXRlLCBwYXJ0aWFsU3RhdGUpO1xuICAgICAgfVxuXG4gICAgY2FzZSBGb3JjZVVwZGF0ZTpcbiAgICAgIHtcbiAgICAgICAgaGFzRm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgICByZXR1cm4gcHJldlN0YXRlO1xuICAgICAgfVxuICB9XG5cbiAgcmV0dXJuIHByZXZTdGF0ZTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBwcm9wcywgaW5zdGFuY2UsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoaXMgaXMgYWx3YXlzIG5vbi1udWxsIG9uIGEgQ2xhc3NDb21wb25lbnQgb3IgSG9zdFJvb3RcbiAgdmFyIHF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7XG4gIGhhc0ZvcmNlVXBkYXRlID0gZmFsc2U7XG5cbiAge1xuICAgIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZSA9IHF1ZXVlLnNoYXJlZDtcbiAgfVxuXG4gIHZhciBmaXJzdEJhc2VVcGRhdGUgPSBxdWV1ZS5maXJzdEJhc2VVcGRhdGU7XG4gIHZhciBsYXN0QmFzZVVwZGF0ZSA9IHF1ZXVlLmxhc3RCYXNlVXBkYXRlOyAvLyBDaGVjayBpZiB0aGVyZSBhcmUgcGVuZGluZyB1cGRhdGVzLiBJZiBzbywgdHJhbnNmZXIgdGhlbSB0byB0aGUgYmFzZSBxdWV1ZS5cblxuICB2YXIgcGVuZGluZ1F1ZXVlID0gcXVldWUuc2hhcmVkLnBlbmRpbmc7XG5cbiAgaWYgKHBlbmRpbmdRdWV1ZSAhPT0gbnVsbCkge1xuICAgIHF1ZXVlLnNoYXJlZC5wZW5kaW5nID0gbnVsbDsgLy8gVGhlIHBlbmRpbmcgcXVldWUgaXMgY2lyY3VsYXIuIERpc2Nvbm5lY3QgdGhlIHBvaW50ZXIgYmV0d2VlbiBmaXJzdFxuICAgIC8vIGFuZCBsYXN0IHNvIHRoYXQgaXQncyBub24tY2lyY3VsYXIuXG5cbiAgICB2YXIgbGFzdFBlbmRpbmdVcGRhdGUgPSBwZW5kaW5nUXVldWU7XG4gICAgdmFyIGZpcnN0UGVuZGluZ1VwZGF0ZSA9IGxhc3RQZW5kaW5nVXBkYXRlLm5leHQ7XG4gICAgbGFzdFBlbmRpbmdVcGRhdGUubmV4dCA9IG51bGw7IC8vIEFwcGVuZCBwZW5kaW5nIHVwZGF0ZXMgdG8gYmFzZSBxdWV1ZVxuXG4gICAgaWYgKGxhc3RCYXNlVXBkYXRlID09PSBudWxsKSB7XG4gICAgICBmaXJzdEJhc2VVcGRhdGUgPSBmaXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhc3RCYXNlVXBkYXRlLm5leHQgPSBmaXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgfVxuXG4gICAgbGFzdEJhc2VVcGRhdGUgPSBsYXN0UGVuZGluZ1VwZGF0ZTsgLy8gSWYgdGhlcmUncyBhIGN1cnJlbnQgcXVldWUsIGFuZCBpdCdzIGRpZmZlcmVudCBmcm9tIHRoZSBiYXNlIHF1ZXVlLCB0aGVuXG4gICAgLy8gd2UgbmVlZCB0byB0cmFuc2ZlciB0aGUgdXBkYXRlcyB0byB0aGF0IHF1ZXVlLCB0b28uIEJlY2F1c2UgdGhlIGJhc2VcbiAgICAvLyBxdWV1ZSBpcyBhIHNpbmdseS1saW5rZWQgbGlzdCB3aXRoIG5vIGN5Y2xlcywgd2UgY2FuIGFwcGVuZCB0byBib3RoXG4gICAgLy8gbGlzdHMgYW5kIHRha2UgYWR2YW50YWdlIG9mIHN0cnVjdHVyYWwgc2hhcmluZy5cbiAgICAvLyBUT0RPOiBQYXNzIGBjdXJyZW50YCBhcyBhcmd1bWVudFxuXG4gICAgdmFyIGN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGU7XG5cbiAgICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyBpcyBhbHdheXMgbm9uLW51bGwgb24gYSBDbGFzc0NvbXBvbmVudCBvciBIb3N0Um9vdFxuICAgICAgdmFyIGN1cnJlbnRRdWV1ZSA9IGN1cnJlbnQudXBkYXRlUXVldWU7XG4gICAgICB2YXIgY3VycmVudExhc3RCYXNlVXBkYXRlID0gY3VycmVudFF1ZXVlLmxhc3RCYXNlVXBkYXRlO1xuXG4gICAgICBpZiAoY3VycmVudExhc3RCYXNlVXBkYXRlICE9PSBsYXN0QmFzZVVwZGF0ZSkge1xuICAgICAgICBpZiAoY3VycmVudExhc3RCYXNlVXBkYXRlID09PSBudWxsKSB7XG4gICAgICAgICAgY3VycmVudFF1ZXVlLmZpcnN0QmFzZVVwZGF0ZSA9IGZpcnN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50TGFzdEJhc2VVcGRhdGUubmV4dCA9IGZpcnN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRRdWV1ZS5sYXN0QmFzZVVwZGF0ZSA9IGxhc3RQZW5kaW5nVXBkYXRlO1xuICAgICAgfVxuICAgIH1cbiAgfSAvLyBUaGVzZSB2YWx1ZXMgbWF5IGNoYW5nZSBhcyB3ZSBwcm9jZXNzIHRoZSBxdWV1ZS5cblxuXG4gIGlmIChmaXJzdEJhc2VVcGRhdGUgIT09IG51bGwpIHtcbiAgICAvLyBJdGVyYXRlIHRocm91Z2ggdGhlIGxpc3Qgb2YgdXBkYXRlcyB0byBjb21wdXRlIHRoZSByZXN1bHQuXG4gICAgdmFyIG5ld1N0YXRlID0gcXVldWUuYmFzZVN0YXRlOyAvLyBUT0RPOiBEb24ndCBuZWVkIHRvIGFjY3VtdWxhdGUgdGhpcy4gSW5zdGVhZCwgd2UgY2FuIHJlbW92ZSByZW5kZXJMYW5lc1xuICAgIC8vIGZyb20gdGhlIG9yaWdpbmFsIGxhbmVzLlxuXG4gICAgdmFyIG5ld0xhbmVzID0gTm9MYW5lcztcbiAgICB2YXIgbmV3QmFzZVN0YXRlID0gbnVsbDtcbiAgICB2YXIgbmV3Rmlyc3RCYXNlVXBkYXRlID0gbnVsbDtcbiAgICB2YXIgbmV3TGFzdEJhc2VVcGRhdGUgPSBudWxsO1xuICAgIHZhciB1cGRhdGUgPSBmaXJzdEJhc2VVcGRhdGU7XG5cbiAgICBkbyB7XG4gICAgICB2YXIgdXBkYXRlTGFuZSA9IHVwZGF0ZS5sYW5lO1xuICAgICAgdmFyIHVwZGF0ZUV2ZW50VGltZSA9IHVwZGF0ZS5ldmVudFRpbWU7XG5cbiAgICAgIGlmICghaXNTdWJzZXRPZkxhbmVzKHJlbmRlckxhbmVzLCB1cGRhdGVMYW5lKSkge1xuICAgICAgICAvLyBQcmlvcml0eSBpcyBpbnN1ZmZpY2llbnQuIFNraXAgdGhpcyB1cGRhdGUuIElmIHRoaXMgaXMgdGhlIGZpcnN0XG4gICAgICAgIC8vIHNraXBwZWQgdXBkYXRlLCB0aGUgcHJldmlvdXMgdXBkYXRlL3N0YXRlIGlzIHRoZSBuZXcgYmFzZVxuICAgICAgICAvLyB1cGRhdGUvc3RhdGUuXG4gICAgICAgIHZhciBjbG9uZSA9IHtcbiAgICAgICAgICBldmVudFRpbWU6IHVwZGF0ZUV2ZW50VGltZSxcbiAgICAgICAgICBsYW5lOiB1cGRhdGVMYW5lLFxuICAgICAgICAgIHRhZzogdXBkYXRlLnRhZyxcbiAgICAgICAgICBwYXlsb2FkOiB1cGRhdGUucGF5bG9hZCxcbiAgICAgICAgICBjYWxsYmFjazogdXBkYXRlLmNhbGxiYWNrLFxuICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAobmV3TGFzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICAgICAgICBuZXdGaXJzdEJhc2VVcGRhdGUgPSBuZXdMYXN0QmFzZVVwZGF0ZSA9IGNsb25lO1xuICAgICAgICAgIG5ld0Jhc2VTdGF0ZSA9IG5ld1N0YXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0xhc3RCYXNlVXBkYXRlID0gbmV3TGFzdEJhc2VVcGRhdGUubmV4dCA9IGNsb25lO1xuICAgICAgICB9IC8vIFVwZGF0ZSB0aGUgcmVtYWluaW5nIHByaW9yaXR5IGluIHRoZSBxdWV1ZS5cblxuXG4gICAgICAgIG5ld0xhbmVzID0gbWVyZ2VMYW5lcyhuZXdMYW5lcywgdXBkYXRlTGFuZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGlzIHVwZGF0ZSBkb2VzIGhhdmUgc3VmZmljaWVudCBwcmlvcml0eS5cbiAgICAgICAgaWYgKG5ld0xhc3RCYXNlVXBkYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgdmFyIF9jbG9uZSA9IHtcbiAgICAgICAgICAgIGV2ZW50VGltZTogdXBkYXRlRXZlbnRUaW1lLFxuICAgICAgICAgICAgLy8gVGhpcyB1cGRhdGUgaXMgZ29pbmcgdG8gYmUgY29tbWl0dGVkIHNvIHdlIG5ldmVyIHdhbnQgdW5jb21taXRcbiAgICAgICAgICAgIC8vIGl0LiBVc2luZyBOb0xhbmUgd29ya3MgYmVjYXVzZSAwIGlzIGEgc3Vic2V0IG9mIGFsbCBiaXRtYXNrcywgc29cbiAgICAgICAgICAgIC8vIHRoaXMgd2lsbCBuZXZlciBiZSBza2lwcGVkIGJ5IHRoZSBjaGVjayBhYm92ZS5cbiAgICAgICAgICAgIGxhbmU6IE5vTGFuZSxcbiAgICAgICAgICAgIHRhZzogdXBkYXRlLnRhZyxcbiAgICAgICAgICAgIHBheWxvYWQ6IHVwZGF0ZS5wYXlsb2FkLFxuICAgICAgICAgICAgY2FsbGJhY2s6IHVwZGF0ZS5jYWxsYmFjayxcbiAgICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgICB9O1xuICAgICAgICAgIG5ld0xhc3RCYXNlVXBkYXRlID0gbmV3TGFzdEJhc2VVcGRhdGUubmV4dCA9IF9jbG9uZTtcbiAgICAgICAgfSAvLyBQcm9jZXNzIHRoaXMgdXBkYXRlLlxuXG5cbiAgICAgICAgbmV3U3RhdGUgPSBnZXRTdGF0ZUZyb21VcGRhdGUod29ya0luUHJvZ3Jlc3MsIHF1ZXVlLCB1cGRhdGUsIG5ld1N0YXRlLCBwcm9wcywgaW5zdGFuY2UpO1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSB1cGRhdGUuY2FsbGJhY2s7XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrICE9PSBudWxsICYmIC8vIElmIHRoZSB1cGRhdGUgd2FzIGFscmVhZHkgY29tbWl0dGVkLCB3ZSBzaG91bGQgbm90IHF1ZXVlIGl0c1xuICAgICAgICAvLyBjYWxsYmFjayBhZ2Fpbi5cbiAgICAgICAgdXBkYXRlLmxhbmUgIT09IE5vTGFuZSkge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IENhbGxiYWNrO1xuICAgICAgICAgIHZhciBlZmZlY3RzID0gcXVldWUuZWZmZWN0cztcblxuICAgICAgICAgIGlmIChlZmZlY3RzID09PSBudWxsKSB7XG4gICAgICAgICAgICBxdWV1ZS5lZmZlY3RzID0gW3VwZGF0ZV07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVmZmVjdHMucHVzaCh1cGRhdGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB1cGRhdGUgPSB1cGRhdGUubmV4dDtcblxuICAgICAgaWYgKHVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICBwZW5kaW5nUXVldWUgPSBxdWV1ZS5zaGFyZWQucGVuZGluZztcblxuICAgICAgICBpZiAocGVuZGluZ1F1ZXVlID09PSBudWxsKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gQW4gdXBkYXRlIHdhcyBzY2hlZHVsZWQgZnJvbSBpbnNpZGUgYSByZWR1Y2VyLiBBZGQgdGhlIG5ld1xuICAgICAgICAgIC8vIHBlbmRpbmcgdXBkYXRlcyB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IGFuZCBrZWVwIHByb2Nlc3NpbmcuXG4gICAgICAgICAgdmFyIF9sYXN0UGVuZGluZ1VwZGF0ZSA9IHBlbmRpbmdRdWV1ZTsgLy8gSW50ZW50aW9uYWxseSB1bnNvdW5kLiBQZW5kaW5nIHVwZGF0ZXMgZm9ybSBhIGNpcmN1bGFyIGxpc3QsIGJ1dCB3ZVxuICAgICAgICAgIC8vIHVucmF2ZWwgdGhlbSB3aGVuIHRyYW5zZmVycmluZyB0aGVtIHRvIHRoZSBiYXNlIHF1ZXVlLlxuXG4gICAgICAgICAgdmFyIF9maXJzdFBlbmRpbmdVcGRhdGUgPSBfbGFzdFBlbmRpbmdVcGRhdGUubmV4dDtcbiAgICAgICAgICBfbGFzdFBlbmRpbmdVcGRhdGUubmV4dCA9IG51bGw7XG4gICAgICAgICAgdXBkYXRlID0gX2ZpcnN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgICAgICBxdWV1ZS5sYXN0QmFzZVVwZGF0ZSA9IF9sYXN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgICAgICBxdWV1ZS5zaGFyZWQucGVuZGluZyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlICh0cnVlKTtcblxuICAgIGlmIChuZXdMYXN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgbmV3QmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgfVxuXG4gICAgcXVldWUuYmFzZVN0YXRlID0gbmV3QmFzZVN0YXRlO1xuICAgIHF1ZXVlLmZpcnN0QmFzZVVwZGF0ZSA9IG5ld0ZpcnN0QmFzZVVwZGF0ZTtcbiAgICBxdWV1ZS5sYXN0QmFzZVVwZGF0ZSA9IG5ld0xhc3RCYXNlVXBkYXRlOyAvLyBJbnRlcmxlYXZlZCB1cGRhdGVzIGFyZSBzdG9yZWQgb24gYSBzZXBhcmF0ZSBxdWV1ZS4gV2UgYXJlbid0IGdvaW5nIHRvXG4gICAgLy8gcHJvY2VzcyB0aGVtIGR1cmluZyB0aGlzIHJlbmRlciwgYnV0IHdlIGRvIG5lZWQgdG8gdHJhY2sgd2hpY2ggbGFuZXNcbiAgICAvLyBhcmUgcmVtYWluaW5nLlxuXG4gICAgdmFyIGxhc3RJbnRlcmxlYXZlZCA9IHF1ZXVlLnNoYXJlZC5pbnRlcmxlYXZlZDtcblxuICAgIGlmIChsYXN0SW50ZXJsZWF2ZWQgIT09IG51bGwpIHtcbiAgICAgIHZhciBpbnRlcmxlYXZlZCA9IGxhc3RJbnRlcmxlYXZlZDtcblxuICAgICAgZG8ge1xuICAgICAgICBuZXdMYW5lcyA9IG1lcmdlTGFuZXMobmV3TGFuZXMsIGludGVybGVhdmVkLmxhbmUpO1xuICAgICAgICBpbnRlcmxlYXZlZCA9IGludGVybGVhdmVkLm5leHQ7XG4gICAgICB9IHdoaWxlIChpbnRlcmxlYXZlZCAhPT0gbGFzdEludGVybGVhdmVkKTtcbiAgICB9IGVsc2UgaWYgKGZpcnN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgLy8gYHF1ZXVlLmxhbmVzYCBpcyB1c2VkIGZvciBlbnRhbmdsaW5nIHRyYW5zaXRpb25zLiBXZSBjYW4gc2V0IGl0IGJhY2sgdG9cbiAgICAgIC8vIHplcm8gb25jZSB0aGUgcXVldWUgaXMgZW1wdHkuXG4gICAgICBxdWV1ZS5zaGFyZWQubGFuZXMgPSBOb0xhbmVzO1xuICAgIH0gLy8gU2V0IHRoZSByZW1haW5pbmcgZXhwaXJhdGlvbiB0aW1lIHRvIGJlIHdoYXRldmVyIGlzIHJlbWFpbmluZyBpbiB0aGUgcXVldWUuXG4gICAgLy8gVGhpcyBzaG91bGQgYmUgZmluZSBiZWNhdXNlIHRoZSBvbmx5IHR3byBvdGhlciB0aGluZ3MgdGhhdCBjb250cmlidXRlIHRvXG4gICAgLy8gZXhwaXJhdGlvbiB0aW1lIGFyZSBwcm9wcyBhbmQgY29udGV4dC4gV2UncmUgYWxyZWFkeSBpbiB0aGUgbWlkZGxlIG9mIHRoZVxuICAgIC8vIGJlZ2luIHBoYXNlIGJ5IHRoZSB0aW1lIHdlIHN0YXJ0IHByb2Nlc3NpbmcgdGhlIHF1ZXVlLCBzbyB3ZSd2ZSBhbHJlYWR5XG4gICAgLy8gZGVhbHQgd2l0aCB0aGUgcHJvcHMuIENvbnRleHQgaW4gY29tcG9uZW50cyB0aGF0IHNwZWNpZnlcbiAgICAvLyBzaG91bGRDb21wb25lbnRVcGRhdGUgaXMgdHJpY2t5OyBidXQgd2UnbGwgaGF2ZSB0byBhY2NvdW50IGZvclxuICAgIC8vIHRoYXQgcmVnYXJkbGVzcy5cblxuXG4gICAgbWFya1NraXBwZWRVcGRhdGVMYW5lcyhuZXdMYW5lcyk7XG4gICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBuZXdMYW5lcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gIH1cblxuICB7XG4gICAgY3VycmVudGx5UHJvY2Vzc2luZ1F1ZXVlID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWxsQ2FsbGJhY2soY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcmd1bWVudCBwYXNzZWQgYXMgY2FsbGJhY2suIEV4cGVjdGVkIGEgZnVuY3Rpb24uIEluc3RlYWQgJyArIChcInJlY2VpdmVkOiBcIiArIGNhbGxiYWNrKSk7XG4gIH1cblxuICBjYWxsYmFjay5jYWxsKGNvbnRleHQpO1xufVxuXG5mdW5jdGlvbiByZXNldEhhc0ZvcmNlVXBkYXRlQmVmb3JlUHJvY2Vzc2luZygpIHtcbiAgaGFzRm9yY2VVcGRhdGUgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIGNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmcoKSB7XG4gIHJldHVybiBoYXNGb3JjZVVwZGF0ZTtcbn1cbmZ1bmN0aW9uIGNvbW1pdFVwZGF0ZVF1ZXVlKGZpbmlzaGVkV29yaywgZmluaXNoZWRRdWV1ZSwgaW5zdGFuY2UpIHtcbiAgLy8gQ29tbWl0IHRoZSBlZmZlY3RzXG4gIHZhciBlZmZlY3RzID0gZmluaXNoZWRRdWV1ZS5lZmZlY3RzO1xuICBmaW5pc2hlZFF1ZXVlLmVmZmVjdHMgPSBudWxsO1xuXG4gIGlmIChlZmZlY3RzICE9PSBudWxsKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlZmZlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZWZmZWN0ID0gZWZmZWN0c1tpXTtcbiAgICAgIHZhciBjYWxsYmFjayA9IGVmZmVjdC5jYWxsYmFjaztcblxuICAgICAgaWYgKGNhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICAgIGVmZmVjdC5jYWxsYmFjayA9IG51bGw7XG4gICAgICAgIGNhbGxDYWxsYmFjayhjYWxsYmFjaywgaW5zdGFuY2UpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgZmFrZUludGVybmFsSW5zdGFuY2UgPSB7fTsgLy8gUmVhY3QuQ29tcG9uZW50IHVzZXMgYSBzaGFyZWQgZnJvemVuIG9iamVjdCBieSBkZWZhdWx0LlxuLy8gV2UnbGwgdXNlIGl0IHRvIGRldGVybWluZSB3aGV0aGVyIHdlIG5lZWQgdG8gaW5pdGlhbGl6ZSBsZWdhY3kgcmVmcy5cblxudmFyIGVtcHR5UmVmc09iamVjdCA9IG5ldyBSZWFjdC5Db21wb25lbnQoKS5yZWZzO1xudmFyIGRpZFdhcm5BYm91dFN0YXRlQXNzaWdubWVudEZvckNvbXBvbmVudDtcbnZhciBkaWRXYXJuQWJvdXRVbmluaXRpYWxpemVkU3RhdGU7XG52YXIgZGlkV2FybkFib3V0R2V0U25hcHNob3RCZWZvcmVVcGRhdGVXaXRob3V0RGlkVXBkYXRlO1xudmFyIGRpZFdhcm5BYm91dExlZ2FjeUxpZmVjeWNsZXNBbmREZXJpdmVkU3RhdGU7XG52YXIgZGlkV2FybkFib3V0VW5kZWZpbmVkRGVyaXZlZFN0YXRlO1xudmFyIHdhcm5PblVuZGVmaW5lZERlcml2ZWRTdGF0ZTtcbnZhciB3YXJuT25JbnZhbGlkQ2FsbGJhY2s7XG52YXIgZGlkV2FybkFib3V0RGlyZWN0bHlBc3NpZ25pbmdQcm9wc1RvU3RhdGU7XG52YXIgZGlkV2FybkFib3V0Q29udGV4dFR5cGVBbmRDb250ZXh0VHlwZXM7XG52YXIgZGlkV2FybkFib3V0SW52YWxpZGF0ZUNvbnRleHRUeXBlO1xuXG57XG4gIGRpZFdhcm5BYm91dFN0YXRlQXNzaWdubWVudEZvckNvbXBvbmVudCA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0VW5pbml0aWFsaXplZFN0YXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRHZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZVdpdGhvdXREaWRVcGRhdGUgPSBuZXcgU2V0KCk7XG4gIGRpZFdhcm5BYm91dExlZ2FjeUxpZmVjeWNsZXNBbmREZXJpdmVkU3RhdGUgPSBuZXcgU2V0KCk7XG4gIGRpZFdhcm5BYm91dERpcmVjdGx5QXNzaWduaW5nUHJvcHNUb1N0YXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRVbmRlZmluZWREZXJpdmVkU3RhdGUgPSBuZXcgU2V0KCk7XG4gIGRpZFdhcm5BYm91dENvbnRleHRUeXBlQW5kQ29udGV4dFR5cGVzID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRJbnZhbGlkYXRlQ29udGV4dFR5cGUgPSBuZXcgU2V0KCk7XG4gIHZhciBkaWRXYXJuT25JbnZhbGlkQ2FsbGJhY2sgPSBuZXcgU2V0KCk7XG5cbiAgd2Fybk9uSW52YWxpZENhbGxiYWNrID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBjYWxsZXJOYW1lKSB7XG4gICAgaWYgKGNhbGxiYWNrID09PSBudWxsIHx8IHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBrZXkgPSBjYWxsZXJOYW1lICsgJ18nICsgY2FsbGJhY2s7XG5cbiAgICBpZiAoIWRpZFdhcm5PbkludmFsaWRDYWxsYmFjay5oYXMoa2V5KSkge1xuICAgICAgZGlkV2Fybk9uSW52YWxpZENhbGxiYWNrLmFkZChrZXkpO1xuXG4gICAgICBlcnJvcignJXMoLi4uKTogRXhwZWN0ZWQgdGhlIGxhc3Qgb3B0aW9uYWwgYGNhbGxiYWNrYCBhcmd1bWVudCB0byBiZSBhICcgKyAnZnVuY3Rpb24uIEluc3RlYWQgcmVjZWl2ZWQ6ICVzLicsIGNhbGxlck5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG4gIH07XG5cbiAgd2Fybk9uVW5kZWZpbmVkRGVyaXZlZFN0YXRlID0gZnVuY3Rpb24gKHR5cGUsIHBhcnRpYWxTdGF0ZSkge1xuICAgIGlmIChwYXJ0aWFsU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSkgfHwgJ0NvbXBvbmVudCc7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0VW5kZWZpbmVkRGVyaXZlZFN0YXRlLmhhcyhjb21wb25lbnROYW1lKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRVbmRlZmluZWREZXJpdmVkU3RhdGUuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGVycm9yKCclcy5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoKTogQSB2YWxpZCBzdGF0ZSBvYmplY3QgKG9yIG51bGwpIG11c3QgYmUgcmV0dXJuZWQuICcgKyAnWW91IGhhdmUgcmV0dXJuZWQgdW5kZWZpbmVkLicsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTsgLy8gVGhpcyBpcyBzbyBncm9zcyBidXQgaXQncyBhdCBsZWFzdCBub24tY3JpdGljYWwgYW5kIGNhbiBiZSByZW1vdmVkIGlmXG4gIC8vIGl0IGNhdXNlcyBwcm9ibGVtcy4gVGhpcyBpcyBtZWFudCB0byBnaXZlIGEgbmljZXIgZXJyb3IgbWVzc2FnZSBmb3JcbiAgLy8gUmVhY3RET00xNS51bnN0YWJsZV9yZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcihyZWFjdERPTTE2Q29tcG9uZW50LFxuICAvLyAuLi4pKSB3aGljaCBvdGhlcndpc2UgdGhyb3dzIGEgXCJfcHJvY2Vzc0NoaWxkQ29udGV4dCBpcyBub3QgYSBmdW5jdGlvblwiXG4gIC8vIGV4Y2VwdGlvbi5cblxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmYWtlSW50ZXJuYWxJbnN0YW5jZSwgJ19wcm9jZXNzQ2hpbGRDb250ZXh0Jywge1xuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ19wcm9jZXNzQ2hpbGRDb250ZXh0IGlzIG5vdCBhdmFpbGFibGUgaW4gUmVhY3QgMTYrLiBUaGlzIGxpa2VseSAnICsgJ21lYW5zIHlvdSBoYXZlIG11bHRpcGxlIGNvcGllcyBvZiBSZWFjdCBhbmQgYXJlIGF0dGVtcHRpbmcgdG8gbmVzdCAnICsgJ2EgUmVhY3QgMTUgdHJlZSBpbnNpZGUgYSBSZWFjdCAxNiB0cmVlIHVzaW5nICcgKyBcInVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyLCB3aGljaCBpc24ndCBzdXBwb3J0ZWQuIFRyeSBcIiArICd0byBtYWtlIHN1cmUgeW91IGhhdmUgb25seSBvbmUgY29weSBvZiBSZWFjdCAoYW5kIGlkZWFsbHksIHN3aXRjaCAnICsgJ3RvIFJlYWN0RE9NLmNyZWF0ZVBvcnRhbCkuJyk7XG4gICAgfVxuICB9KTtcbiAgT2JqZWN0LmZyZWV6ZShmYWtlSW50ZXJuYWxJbnN0YW5jZSk7XG59XG5cbmZ1bmN0aW9uIGFwcGx5RGVyaXZlZFN0YXRlRnJvbVByb3BzKHdvcmtJblByb2dyZXNzLCBjdG9yLCBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMsIG5leHRQcm9wcykge1xuICB2YXIgcHJldlN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHBhcnRpYWxTdGF0ZSA9IGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyhuZXh0UHJvcHMsIHByZXZTdGF0ZSk7XG5cbiAge1xuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBJbnZva2UgdGhlIGZ1bmN0aW9uIGFuIGV4dHJhIHRpbWUgdG8gaGVscCBkZXRlY3Qgc2lkZS1lZmZlY3RzLlxuICAgICAgICBwYXJ0aWFsU3RhdGUgPSBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMobmV4dFByb3BzLCBwcmV2U3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdhcm5PblVuZGVmaW5lZERlcml2ZWRTdGF0ZShjdG9yLCBwYXJ0aWFsU3RhdGUpO1xuICB9IC8vIE1lcmdlIHRoZSBwYXJ0aWFsIHN0YXRlIGFuZCB0aGUgcHJldmlvdXMgc3RhdGUuXG5cblxuICB2YXIgbWVtb2l6ZWRTdGF0ZSA9IHBhcnRpYWxTdGF0ZSA9PT0gbnVsbCB8fCBwYXJ0aWFsU3RhdGUgPT09IHVuZGVmaW5lZCA/IHByZXZTdGF0ZSA6IGFzc2lnbih7fSwgcHJldlN0YXRlLCBwYXJ0aWFsU3RhdGUpO1xuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbWVtb2l6ZWRTdGF0ZTsgLy8gT25jZSB0aGUgdXBkYXRlIHF1ZXVlIGlzIGVtcHR5LCBwZXJzaXN0IHRoZSBkZXJpdmVkIHN0YXRlIG9udG8gdGhlXG4gIC8vIGJhc2Ugc3RhdGUuXG5cbiAgaWYgKHdvcmtJblByb2dyZXNzLmxhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gUXVldWUgaXMgYWx3YXlzIG5vbi1udWxsIGZvciBjbGFzc2VzXG4gICAgdmFyIHVwZGF0ZVF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7XG4gICAgdXBkYXRlUXVldWUuYmFzZVN0YXRlID0gbWVtb2l6ZWRTdGF0ZTtcbiAgfVxufVxuXG52YXIgY2xhc3NDb21wb25lbnRVcGRhdGVyID0ge1xuICBpc01vdW50ZWQ6IGlzTW91bnRlZCxcbiAgZW5xdWV1ZVNldFN0YXRlOiBmdW5jdGlvbiAoaW5zdCwgcGF5bG9hZCwgY2FsbGJhY2spIHtcbiAgICB2YXIgZmliZXIgPSBnZXQoaW5zdCk7XG4gICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgICB2YXIgdXBkYXRlID0gY3JlYXRlVXBkYXRlKGV2ZW50VGltZSwgbGFuZSk7XG4gICAgdXBkYXRlLnBheWxvYWQgPSBwYXlsb2FkO1xuXG4gICAgaWYgKGNhbGxiYWNrICE9PSB1bmRlZmluZWQgJiYgY2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgd2Fybk9uSW52YWxpZENhbGxiYWNrKGNhbGxiYWNrLCAnc2V0U3RhdGUnKTtcbiAgICAgIH1cblxuICAgICAgdXBkYXRlLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgZW5xdWV1ZVVwZGF0ZShmaWJlciwgdXBkYXRlKTtcbiAgICB2YXIgcm9vdCA9IHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGZpYmVyLCBsYW5lKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfSxcbiAgZW5xdWV1ZVJlcGxhY2VTdGF0ZTogZnVuY3Rpb24gKGluc3QsIHBheWxvYWQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpYmVyID0gZ2V0KGluc3QpO1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICAgIHVwZGF0ZS50YWcgPSBSZXBsYWNlU3RhdGU7XG4gICAgdXBkYXRlLnBheWxvYWQgPSBwYXlsb2FkO1xuXG4gICAgaWYgKGNhbGxiYWNrICE9PSB1bmRlZmluZWQgJiYgY2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgd2Fybk9uSW52YWxpZENhbGxiYWNrKGNhbGxiYWNrLCAncmVwbGFjZVN0YXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIGVucXVldWVVcGRhdGUoZmliZXIsIHVwZGF0ZSk7XG4gICAgdmFyIHJvb3QgPSBzY2hlZHVsZVVwZGF0ZU9uRmliZXIoZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgZW50YW5nbGVUcmFuc2l0aW9ucyhyb290LCBmaWJlciwgbGFuZSk7XG4gICAgfVxuXG4gICAge1xuICAgICAgbWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgICB9XG4gIH0sXG4gIGVucXVldWVGb3JjZVVwZGF0ZTogZnVuY3Rpb24gKGluc3QsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpYmVyID0gZ2V0KGluc3QpO1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICAgIHVwZGF0ZS50YWcgPSBGb3JjZVVwZGF0ZTtcblxuICAgIGlmIChjYWxsYmFjayAhPT0gdW5kZWZpbmVkICYmIGNhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICB7XG4gICAgICAgIHdhcm5PbkludmFsaWRDYWxsYmFjayhjYWxsYmFjaywgJ2ZvcmNlVXBkYXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIGVucXVldWVVcGRhdGUoZmliZXIsIHVwZGF0ZSk7XG4gICAgdmFyIHJvb3QgPSBzY2hlZHVsZVVwZGF0ZU9uRmliZXIoZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgZW50YW5nbGVUcmFuc2l0aW9ucyhyb290LCBmaWJlciwgbGFuZSk7XG4gICAgfVxuXG4gICAge1xuICAgICAgbWFya0ZvcmNlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNoZWNrU2hvdWxkQ29tcG9uZW50VXBkYXRlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBvbGRQcm9wcywgbmV3UHJvcHMsIG9sZFN0YXRlLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpIHtcbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2Uuc2hvdWxkQ29tcG9uZW50VXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIHNob3VsZFVwZGF0ZSA9IGluc3RhbmNlLnNob3VsZENvbXBvbmVudFVwZGF0ZShuZXdQcm9wcywgbmV3U3RhdGUsIG5leHRDb250ZXh0KTtcblxuICAgIHtcbiAgICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHModHJ1ZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBJbnZva2UgdGhlIGZ1bmN0aW9uIGFuIGV4dHJhIHRpbWUgdG8gaGVscCBkZXRlY3Qgc2lkZS1lZmZlY3RzLlxuICAgICAgICAgIHNob3VsZFVwZGF0ZSA9IGluc3RhbmNlLnNob3VsZENvbXBvbmVudFVwZGF0ZShuZXdQcm9wcywgbmV3U3RhdGUsIG5leHRDb250ZXh0KTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyhmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHNob3VsZFVwZGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVycm9yKCclcy5zaG91bGRDb21wb25lbnRVcGRhdGUoKTogUmV0dXJuZWQgdW5kZWZpbmVkIGluc3RlYWQgb2YgYSAnICsgJ2Jvb2xlYW4gdmFsdWUuIE1ha2Ugc3VyZSB0byByZXR1cm4gdHJ1ZSBvciBmYWxzZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoY3RvcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzaG91bGRVcGRhdGU7XG4gIH1cblxuICBpZiAoY3Rvci5wcm90b3R5cGUgJiYgY3Rvci5wcm90b3R5cGUuaXNQdXJlUmVhY3RDb21wb25lbnQpIHtcbiAgICByZXR1cm4gIXNoYWxsb3dFcXVhbChvbGRQcm9wcywgbmV3UHJvcHMpIHx8ICFzaGFsbG93RXF1YWwob2xkU3RhdGUsIG5ld1N0YXRlKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjaGVja0NsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIGN0b3IsIG5ld1Byb3BzKSB7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcblxuICB7XG4gICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoY3RvcikgfHwgJ0NvbXBvbmVudCc7XG4gICAgdmFyIHJlbmRlclByZXNlbnQgPSBpbnN0YW5jZS5yZW5kZXI7XG5cbiAgICBpZiAoIXJlbmRlclByZXNlbnQpIHtcbiAgICAgIGlmIChjdG9yLnByb3RvdHlwZSAmJiB0eXBlb2YgY3Rvci5wcm90b3R5cGUucmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGVycm9yKCclcyguLi4pOiBObyBgcmVuZGVyYCBtZXRob2QgZm91bmQgb24gdGhlIHJldHVybmVkIGNvbXBvbmVudCAnICsgJ2luc3RhbmNlOiBkaWQgeW91IGFjY2lkZW50YWxseSByZXR1cm4gYW4gb2JqZWN0IGZyb20gdGhlIGNvbnN0cnVjdG9yPycsIG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IoJyVzKC4uLik6IE5vIGByZW5kZXJgIG1ldGhvZCBmb3VuZCBvbiB0aGUgcmV0dXJuZWQgY29tcG9uZW50ICcgKyAnaW5zdGFuY2U6IHlvdSBtYXkgaGF2ZSBmb3Jnb3R0ZW4gdG8gZGVmaW5lIGByZW5kZXJgLicsIG5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5nZXRJbml0aWFsU3RhdGUgJiYgIWluc3RhbmNlLmdldEluaXRpYWxTdGF0ZS5pc1JlYWN0Q2xhc3NBcHByb3ZlZCAmJiAhaW5zdGFuY2Uuc3RhdGUpIHtcbiAgICAgIGVycm9yKCdnZXRJbml0aWFsU3RhdGUgd2FzIGRlZmluZWQgb24gJXMsIGEgcGxhaW4gSmF2YVNjcmlwdCBjbGFzcy4gJyArICdUaGlzIGlzIG9ubHkgc3VwcG9ydGVkIGZvciBjbGFzc2VzIGNyZWF0ZWQgdXNpbmcgUmVhY3QuY3JlYXRlQ2xhc3MuICcgKyAnRGlkIHlvdSBtZWFuIHRvIGRlZmluZSBhIHN0YXRlIHByb3BlcnR5IGluc3RlYWQ/JywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGluc3RhbmNlLmdldERlZmF1bHRQcm9wcyAmJiAhaW5zdGFuY2UuZ2V0RGVmYXVsdFByb3BzLmlzUmVhY3RDbGFzc0FwcHJvdmVkKSB7XG4gICAgICBlcnJvcignZ2V0RGVmYXVsdFByb3BzIHdhcyBkZWZpbmVkIG9uICVzLCBhIHBsYWluIEphdmFTY3JpcHQgY2xhc3MuICcgKyAnVGhpcyBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgY2xhc3NlcyBjcmVhdGVkIHVzaW5nIFJlYWN0LmNyZWF0ZUNsYXNzLiAnICsgJ1VzZSBhIHN0YXRpYyBwcm9wZXJ0eSB0byBkZWZpbmUgZGVmYXVsdFByb3BzIGluc3RlYWQuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGluc3RhbmNlLnByb3BUeXBlcykge1xuICAgICAgZXJyb3IoJ3Byb3BUeXBlcyB3YXMgZGVmaW5lZCBhcyBhbiBpbnN0YW5jZSBwcm9wZXJ0eSBvbiAlcy4gVXNlIGEgc3RhdGljICcgKyAncHJvcGVydHkgdG8gZGVmaW5lIHByb3BUeXBlcyBpbnN0ZWFkLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5jb250ZXh0VHlwZSkge1xuICAgICAgZXJyb3IoJ2NvbnRleHRUeXBlIHdhcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIHByb3BlcnR5IG9uICVzLiBVc2UgYSBzdGF0aWMgJyArICdwcm9wZXJ0eSB0byBkZWZpbmUgY29udGV4dFR5cGUgaW5zdGVhZC4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAoaW5zdGFuY2UuY29udGV4dFR5cGVzKSB7XG4gICAgICAgIGVycm9yKCdjb250ZXh0VHlwZXMgd2FzIGRlZmluZWQgYXMgYW4gaW5zdGFuY2UgcHJvcGVydHkgb24gJXMuIFVzZSBhIHN0YXRpYyAnICsgJ3Byb3BlcnR5IHRvIGRlZmluZSBjb250ZXh0VHlwZXMgaW5zdGVhZC4nLCBuYW1lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGN0b3IuY29udGV4dFR5cGUgJiYgY3Rvci5jb250ZXh0VHlwZXMgJiYgIWRpZFdhcm5BYm91dENvbnRleHRUeXBlQW5kQ29udGV4dFR5cGVzLmhhcyhjdG9yKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZUFuZENvbnRleHRUeXBlcy5hZGQoY3Rvcik7XG5cbiAgICAgICAgZXJyb3IoJyVzIGRlY2xhcmVzIGJvdGggY29udGV4dFR5cGVzIGFuZCBjb250ZXh0VHlwZSBzdGF0aWMgcHJvcGVydGllcy4gJyArICdUaGUgbGVnYWN5IGNvbnRleHRUeXBlcyBwcm9wZXJ0eSB3aWxsIGJlIGlnbm9yZWQuJywgbmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRTaG91bGRVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclcyBoYXMgYSBtZXRob2QgY2FsbGVkICcgKyAnY29tcG9uZW50U2hvdWxkVXBkYXRlKCkuIERpZCB5b3UgbWVhbiBzaG91bGRDb21wb25lbnRVcGRhdGUoKT8gJyArICdUaGUgbmFtZSBpcyBwaHJhc2VkIGFzIGEgcXVlc3Rpb24gYmVjYXVzZSB0aGUgZnVuY3Rpb24gaXMgJyArICdleHBlY3RlZCB0byByZXR1cm4gYSB2YWx1ZS4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoY3Rvci5wcm90b3R5cGUgJiYgY3Rvci5wcm90b3R5cGUuaXNQdXJlUmVhY3RDb21wb25lbnQgJiYgdHlwZW9mIGluc3RhbmNlLnNob3VsZENvbXBvbmVudFVwZGF0ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGVycm9yKCclcyBoYXMgYSBtZXRob2QgY2FsbGVkIHNob3VsZENvbXBvbmVudFVwZGF0ZSgpLiAnICsgJ3Nob3VsZENvbXBvbmVudFVwZGF0ZSBzaG91bGQgbm90IGJlIHVzZWQgd2hlbiBleHRlbmRpbmcgUmVhY3QuUHVyZUNvbXBvbmVudC4gJyArICdQbGVhc2UgZXh0ZW5kIFJlYWN0LkNvbXBvbmVudCBpZiBzaG91bGRDb21wb25lbnRVcGRhdGUgaXMgdXNlZC4nLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoY3RvcikgfHwgJ0EgcHVyZSBjb21wb25lbnQnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFVubW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclcyBoYXMgYSBtZXRob2QgY2FsbGVkICcgKyAnY29tcG9uZW50RGlkVW5tb3VudCgpLiBCdXQgdGhlcmUgaXMgbm8gc3VjaCBsaWZlY3ljbGUgbWV0aG9kLiAnICsgJ0RpZCB5b3UgbWVhbiBjb21wb25lbnRXaWxsVW5tb3VudCgpPycsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudERpZFJlY2VpdmVQcm9wcygpLiBCdXQgdGhlcmUgaXMgbm8gc3VjaCBsaWZlY3ljbGUgbWV0aG9kLiAnICsgJ0lmIHlvdSBtZWFudCB0byB1cGRhdGUgdGhlIHN0YXRlIGluIHJlc3BvbnNlIHRvIGNoYW5naW5nIHByb3BzLCAnICsgJ3VzZSBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCkuIElmIHlvdSBtZWFudCB0byBmZXRjaCBkYXRhIG9yICcgKyAncnVuIHNpZGUtZWZmZWN0cyBvciBtdXRhdGlvbnMgYWZ0ZXIgUmVhY3QgaGFzIHVwZGF0ZWQgdGhlIFVJLCB1c2UgY29tcG9uZW50RGlkVXBkYXRlKCkuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudFdpbGxSZWNpZXZlUHJvcHMoKS4gRGlkIHlvdSBtZWFuIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoKT8nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ1VOU0FGRV9jb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzKCkuIERpZCB5b3UgbWVhbiBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcygpPycsIG5hbWUpO1xuICAgIH1cblxuICAgIHZhciBoYXNNdXRhdGVkUHJvcHMgPSBpbnN0YW5jZS5wcm9wcyAhPT0gbmV3UHJvcHM7XG5cbiAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IHVuZGVmaW5lZCAmJiBoYXNNdXRhdGVkUHJvcHMpIHtcbiAgICAgIGVycm9yKCclcyguLi4pOiBXaGVuIGNhbGxpbmcgc3VwZXIoKSBpbiBgJXNgLCBtYWtlIHN1cmUgdG8gcGFzcyAnICsgXCJ1cCB0aGUgc2FtZSBwcm9wcyB0aGF0IHlvdXIgY29tcG9uZW50J3MgY29uc3RydWN0b3Igd2FzIHBhc3NlZC5cIiwgbmFtZSwgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGluc3RhbmNlLmRlZmF1bHRQcm9wcykge1xuICAgICAgZXJyb3IoJ1NldHRpbmcgZGVmYXVsdFByb3BzIGFzIGFuIGluc3RhbmNlIHByb3BlcnR5IG9uICVzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIHdpbGwgYmUgaWdub3JlZC4nICsgJyBJbnN0ZWFkLCBkZWZpbmUgZGVmYXVsdFByb3BzIGFzIGEgc3RhdGljIHByb3BlcnR5IG9uICVzLicsIG5hbWUsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZSAhPT0gJ2Z1bmN0aW9uJyAmJiAhZGlkV2FybkFib3V0R2V0U25hcHNob3RCZWZvcmVVcGRhdGVXaXRob3V0RGlkVXBkYXRlLmhhcyhjdG9yKSkge1xuICAgICAgZGlkV2FybkFib3V0R2V0U25hcHNob3RCZWZvcmVVcGRhdGVXaXRob3V0RGlkVXBkYXRlLmFkZChjdG9yKTtcblxuICAgICAgZXJyb3IoJyVzOiBnZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSgpIHNob3VsZCBiZSB1c2VkIHdpdGggY29tcG9uZW50RGlkVXBkYXRlKCkuICcgKyAnVGhpcyBjb21wb25lbnQgZGVmaW5lcyBnZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSgpIG9ubHkuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzOiBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoKSBpcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIG1ldGhvZCAnICsgJ2FuZCB3aWxsIGJlIGlnbm9yZWQuIEluc3RlYWQsIGRlY2xhcmUgaXQgYXMgYSBzdGF0aWMgbWV0aG9kLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXM6IGdldERlcml2ZWRTdGF0ZUZyb21FcnJvcigpIGlzIGRlZmluZWQgYXMgYW4gaW5zdGFuY2UgbWV0aG9kICcgKyAnYW5kIHdpbGwgYmUgaWdub3JlZC4gSW5zdGVhZCwgZGVjbGFyZSBpdCBhcyBhIHN0YXRpYyBtZXRob2QuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjdG9yLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXM6IGdldFNuYXBzaG90QmVmb3JlVXBkYXRlKCkgaXMgZGVmaW5lZCBhcyBhIHN0YXRpYyBtZXRob2QgJyArICdhbmQgd2lsbCBiZSBpZ25vcmVkLiBJbnN0ZWFkLCBkZWNsYXJlIGl0IGFzIGFuIGluc3RhbmNlIG1ldGhvZC4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgX3N0YXRlID0gaW5zdGFuY2Uuc3RhdGU7XG5cbiAgICBpZiAoX3N0YXRlICYmICh0eXBlb2YgX3N0YXRlICE9PSAnb2JqZWN0JyB8fCBpc0FycmF5KF9zdGF0ZSkpKSB7XG4gICAgICBlcnJvcignJXMuc3RhdGU6IG11c3QgYmUgc2V0IHRvIGFuIG9iamVjdCBvciBudWxsJywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5nZXRDaGlsZENvbnRleHQgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGN0b3IuY2hpbGRDb250ZXh0VHlwZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICBlcnJvcignJXMuZ2V0Q2hpbGRDb250ZXh0KCk6IGNoaWxkQ29udGV4dFR5cGVzIG11c3QgYmUgZGVmaW5lZCBpbiBvcmRlciB0byAnICsgJ3VzZSBnZXRDaGlsZENvbnRleHQoKS4nLCBuYW1lKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRvcHRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSkge1xuICBpbnN0YW5jZS51cGRhdGVyID0gY2xhc3NDb21wb25lbnRVcGRhdGVyO1xuICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBpbnN0YW5jZTsgLy8gVGhlIGluc3RhbmNlIG5lZWRzIGFjY2VzcyB0byB0aGUgZmliZXIgc28gdGhhdCBpdCBjYW4gc2NoZWR1bGUgdXBkYXRlc1xuXG4gIHNldChpbnN0YW5jZSwgd29ya0luUHJvZ3Jlc3MpO1xuXG4gIHtcbiAgICBpbnN0YW5jZS5fcmVhY3RJbnRlcm5hbEluc3RhbmNlID0gZmFrZUludGVybmFsSW5zdGFuY2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3RydWN0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgY3RvciwgcHJvcHMpIHtcbiAgdmFyIGlzTGVnYWN5Q29udGV4dENvbnN1bWVyID0gZmFsc2U7XG4gIHZhciB1bm1hc2tlZENvbnRleHQgPSBlbXB0eUNvbnRleHRPYmplY3Q7XG4gIHZhciBjb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuICB2YXIgY29udGV4dFR5cGUgPSBjdG9yLmNvbnRleHRUeXBlO1xuXG4gIHtcbiAgICBpZiAoJ2NvbnRleHRUeXBlJyBpbiBjdG9yKSB7XG4gICAgICB2YXIgaXNWYWxpZCA9IC8vIEFsbG93IG51bGwgZm9yIGNvbmRpdGlvbmFsIGRlY2xhcmF0aW9uXG4gICAgICBjb250ZXh0VHlwZSA9PT0gbnVsbCB8fCBjb250ZXh0VHlwZSAhPT0gdW5kZWZpbmVkICYmIGNvbnRleHRUeXBlLiQkdHlwZW9mID09PSBSRUFDVF9DT05URVhUX1RZUEUgJiYgY29udGV4dFR5cGUuX2NvbnRleHQgPT09IHVuZGVmaW5lZDsgLy8gTm90IGEgPENvbnRleHQuQ29uc3VtZXI+XG5cbiAgICAgIGlmICghaXNWYWxpZCAmJiAhZGlkV2FybkFib3V0SW52YWxpZGF0ZUNvbnRleHRUeXBlLmhhcyhjdG9yKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRJbnZhbGlkYXRlQ29udGV4dFR5cGUuYWRkKGN0b3IpO1xuICAgICAgICB2YXIgYWRkZW5kdW0gPSAnJztcblxuICAgICAgICBpZiAoY29udGV4dFR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGFkZGVuZHVtID0gJyBIb3dldmVyLCBpdCBpcyBzZXQgdG8gdW5kZWZpbmVkLiAnICsgJ1RoaXMgY2FuIGJlIGNhdXNlZCBieSBhIHR5cG8gb3IgYnkgbWl4aW5nIHVwIG5hbWVkIGFuZCBkZWZhdWx0IGltcG9ydHMuICcgKyAnVGhpcyBjYW4gYWxzbyBoYXBwZW4gZHVlIHRvIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSwgc28gJyArICd0cnkgbW92aW5nIHRoZSBjcmVhdGVDb250ZXh0KCkgY2FsbCB0byBhIHNlcGFyYXRlIGZpbGUuJztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY29udGV4dFR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgYWRkZW5kdW0gPSAnIEhvd2V2ZXIsIGl0IGlzIHNldCB0byBhICcgKyB0eXBlb2YgY29udGV4dFR5cGUgKyAnLic7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dFR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX1BST1ZJREVSX1RZUEUpIHtcbiAgICAgICAgICBhZGRlbmR1bSA9ICcgRGlkIHlvdSBhY2NpZGVudGFsbHkgcGFzcyB0aGUgQ29udGV4dC5Qcm92aWRlciBpbnN0ZWFkPyc7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dFR5cGUuX2NvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIDxDb250ZXh0LkNvbnN1bWVyPlxuICAgICAgICAgIGFkZGVuZHVtID0gJyBEaWQgeW91IGFjY2lkZW50YWxseSBwYXNzIHRoZSBDb250ZXh0LkNvbnN1bWVyIGluc3RlYWQ/JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRlbmR1bSA9ICcgSG93ZXZlciwgaXQgaXMgc2V0IHRvIGFuIG9iamVjdCB3aXRoIGtleXMgeycgKyBPYmplY3Qua2V5cyhjb250ZXh0VHlwZSkuam9pbignLCAnKSArICd9Lic7XG4gICAgICAgIH1cblxuICAgICAgICBlcnJvcignJXMgZGVmaW5lcyBhbiBpbnZhbGlkIGNvbnRleHRUeXBlLiAnICsgJ2NvbnRleHRUeXBlIHNob3VsZCBwb2ludCB0byB0aGUgQ29udGV4dCBvYmplY3QgcmV0dXJuZWQgYnkgUmVhY3QuY3JlYXRlQ29udGV4dCgpLiVzJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnLCBhZGRlbmR1bSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgY29udGV4dFR5cGUgIT09IG51bGwpIHtcbiAgICBjb250ZXh0ID0gcmVhZENvbnRleHQoY29udGV4dFR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHVubWFza2VkQ29udGV4dCA9IGdldFVubWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgY3RvciwgdHJ1ZSk7XG4gICAgdmFyIGNvbnRleHRUeXBlcyA9IGN0b3IuY29udGV4dFR5cGVzO1xuICAgIGlzTGVnYWN5Q29udGV4dENvbnN1bWVyID0gY29udGV4dFR5cGVzICE9PSBudWxsICYmIGNvbnRleHRUeXBlcyAhPT0gdW5kZWZpbmVkO1xuICAgIGNvbnRleHQgPSBpc0xlZ2FjeUNvbnRleHRDb25zdW1lciA/IGdldE1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHVubWFza2VkQ29udGV4dCkgOiBlbXB0eUNvbnRleHRPYmplY3Q7XG4gIH1cblxuICB2YXIgaW5zdGFuY2UgPSBuZXcgY3Rvcihwcm9wcywgY29udGV4dCk7IC8vIEluc3RhbnRpYXRlIHR3aWNlIHRvIGhlbHAgZGV0ZWN0IHNpZGUtZWZmZWN0cy5cblxuICB7XG4gICAgaWYgKCB3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHModHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGluc3RhbmNlID0gbmV3IGN0b3IocHJvcHMsIGNvbnRleHQpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBzdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBpbnN0YW5jZS5zdGF0ZSAhPT0gbnVsbCAmJiBpbnN0YW5jZS5zdGF0ZSAhPT0gdW5kZWZpbmVkID8gaW5zdGFuY2Uuc3RhdGUgOiBudWxsO1xuICBhZG9wdENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIGluc3RhbmNlKTtcblxuICB7XG4gICAgaWYgKHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyAmJiBzdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoY3RvcikgfHwgJ0NvbXBvbmVudCc7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0VW5pbml0aWFsaXplZFN0YXRlLmhhcyhjb21wb25lbnROYW1lKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRVbmluaXRpYWxpemVkU3RhdGUuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGVycm9yKCdgJXNgIHVzZXMgYGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wc2AgYnV0IGl0cyBpbml0aWFsIHN0YXRlIGlzICcgKyAnJXMuIFRoaXMgaXMgbm90IHJlY29tbWVuZGVkLiBJbnN0ZWFkLCBkZWZpbmUgdGhlIGluaXRpYWwgc3RhdGUgYnkgJyArICdhc3NpZ25pbmcgYW4gb2JqZWN0IHRvIGB0aGlzLnN0YXRlYCBpbiB0aGUgY29uc3RydWN0b3Igb2YgYCVzYC4gJyArICdUaGlzIGVuc3VyZXMgdGhhdCBgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzYCBhcmd1bWVudHMgaGF2ZSBhIGNvbnNpc3RlbnQgc2hhcGUuJywgY29tcG9uZW50TmFtZSwgaW5zdGFuY2Uuc3RhdGUgPT09IG51bGwgPyAnbnVsbCcgOiAndW5kZWZpbmVkJywgY29tcG9uZW50TmFtZSk7XG4gICAgICB9XG4gICAgfSAvLyBJZiBuZXcgY29tcG9uZW50IEFQSXMgYXJlIGRlZmluZWQsIFwidW5zYWZlXCIgbGlmZWN5Y2xlcyB3b24ndCBiZSBjYWxsZWQuXG4gICAgLy8gV2FybiBhYm91dCB0aGVzZSBsaWZlY3ljbGVzIGlmIHRoZXkgYXJlIHByZXNlbnQuXG4gICAgLy8gRG9uJ3Qgd2FybiBhYm91dCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIG1ldGhvZHMgdGhvdWdoLlxuXG5cbiAgICBpZiAodHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIGZvdW5kV2lsbE1vdW50TmFtZSA9IG51bGw7XG4gICAgICB2YXIgZm91bmRXaWxsUmVjZWl2ZVByb3BzTmFtZSA9IG51bGw7XG4gICAgICB2YXIgZm91bmRXaWxsVXBkYXRlTmFtZSA9IG51bGw7XG5cbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nICYmIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudC5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICAgIGZvdW5kV2lsbE1vdW50TmFtZSA9ICdjb21wb25lbnRXaWxsTW91bnQnO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3VuZFdpbGxNb3VudE5hbWUgPSAnVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCc7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJyAmJiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzLl9fc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmcgIT09IHRydWUpIHtcbiAgICAgICAgZm91bmRXaWxsUmVjZWl2ZVByb3BzTmFtZSA9ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgPSAnVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMnO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicgJiYgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZS5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICAgIGZvdW5kV2lsbFVwZGF0ZU5hbWUgPSAnY29tcG9uZW50V2lsbFVwZGF0ZSc7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3VuZFdpbGxVcGRhdGVOYW1lID0gJ1VOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlJztcbiAgICAgIH1cblxuICAgICAgaWYgKGZvdW5kV2lsbE1vdW50TmFtZSAhPT0gbnVsbCB8fCBmb3VuZFdpbGxSZWNlaXZlUHJvcHNOYW1lICE9PSBudWxsIHx8IGZvdW5kV2lsbFVwZGF0ZU5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIF9jb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICAgIHZhciBuZXdBcGlOYW1lID0gdHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nID8gJ2dldERlcml2ZWRTdGF0ZUZyb21Qcm9wcygpJyA6ICdnZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSgpJztcblxuICAgICAgICBpZiAoIWRpZFdhcm5BYm91dExlZ2FjeUxpZmVjeWNsZXNBbmREZXJpdmVkU3RhdGUuaGFzKF9jb21wb25lbnROYW1lKSkge1xuICAgICAgICAgIGRpZFdhcm5BYm91dExlZ2FjeUxpZmVjeWNsZXNBbmREZXJpdmVkU3RhdGUuYWRkKF9jb21wb25lbnROYW1lKTtcblxuICAgICAgICAgIGVycm9yKCdVbnNhZmUgbGVnYWN5IGxpZmVjeWNsZXMgd2lsbCBub3QgYmUgY2FsbGVkIGZvciBjb21wb25lbnRzIHVzaW5nIG5ldyBjb21wb25lbnQgQVBJcy5cXG5cXG4nICsgJyVzIHVzZXMgJXMgYnV0IGFsc28gY29udGFpbnMgdGhlIGZvbGxvd2luZyBsZWdhY3kgbGlmZWN5Y2xlczolcyVzJXNcXG5cXG4nICsgJ1RoZSBhYm92ZSBsaWZlY3ljbGVzIHNob3VsZCBiZSByZW1vdmVkLiBMZWFybiBtb3JlIGFib3V0IHRoaXMgd2FybmluZyBoZXJlOlxcbicgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcycsIF9jb21wb25lbnROYW1lLCBuZXdBcGlOYW1lLCBmb3VuZFdpbGxNb3VudE5hbWUgIT09IG51bGwgPyBcIlxcbiAgXCIgKyBmb3VuZFdpbGxNb3VudE5hbWUgOiAnJywgZm91bmRXaWxsUmVjZWl2ZVByb3BzTmFtZSAhPT0gbnVsbCA/IFwiXFxuICBcIiArIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgOiAnJywgZm91bmRXaWxsVXBkYXRlTmFtZSAhPT0gbnVsbCA/IFwiXFxuICBcIiArIGZvdW5kV2lsbFVwZGF0ZU5hbWUgOiAnJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gQ2FjaGUgdW5tYXNrZWQgY29udGV4dCBzbyB3ZSBjYW4gYXZvaWQgcmVjcmVhdGluZyBtYXNrZWQgY29udGV4dCB1bmxlc3MgbmVjZXNzYXJ5LlxuICAvLyBSZWFjdEZpYmVyQ29udGV4dCB1c3VhbGx5IHVwZGF0ZXMgdGhpcyBjYWNoZSBidXQgY2FuJ3QgZm9yIG5ld2x5LWNyZWF0ZWQgaW5zdGFuY2VzLlxuXG5cbiAgaWYgKGlzTGVnYWN5Q29udGV4dENvbnN1bWVyKSB7XG4gICAgY2FjaGVDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQsIGNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuXG5mdW5jdGlvbiBjYWxsQ29tcG9uZW50V2lsbE1vdW50KHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSkge1xuICB2YXIgb2xkU3RhdGUgPSBpbnN0YW5jZS5zdGF0ZTtcblxuICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCgpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpO1xuICB9XG5cbiAgaWYgKG9sZFN0YXRlICE9PSBpbnN0YW5jZS5zdGF0ZSkge1xuICAgIHtcbiAgICAgIGVycm9yKCclcy5jb21wb25lbnRXaWxsTW91bnQoKTogQXNzaWduaW5nIGRpcmVjdGx5IHRvIHRoaXMuc3RhdGUgaXMgJyArIFwiZGVwcmVjYXRlZCAoZXhjZXB0IGluc2lkZSBhIGNvbXBvbmVudCdzIFwiICsgJ2NvbnN0cnVjdG9yKS4gVXNlIHNldFN0YXRlIGluc3RlYWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ0NvbXBvbmVudCcpO1xuICAgIH1cblxuICAgIGNsYXNzQ29tcG9uZW50VXBkYXRlci5lbnF1ZXVlUmVwbGFjZVN0YXRlKGluc3RhbmNlLCBpbnN0YW5jZS5zdGF0ZSwgbnVsbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbENvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMod29ya0luUHJvZ3Jlc3MsIGluc3RhbmNlLCBuZXdQcm9wcywgbmV4dENvbnRleHQpIHtcbiAgdmFyIG9sZFN0YXRlID0gaW5zdGFuY2Uuc3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXdQcm9wcywgbmV4dENvbnRleHQpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5ld1Byb3BzLCBuZXh0Q29udGV4dCk7XG4gIH1cblxuICBpZiAoaW5zdGFuY2Uuc3RhdGUgIT09IG9sZFN0YXRlKSB7XG4gICAge1xuICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHdvcmtJblByb2dyZXNzKSB8fCAnQ29tcG9uZW50JztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQuaGFzKGNvbXBvbmVudE5hbWUpKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFN0YXRlQXNzaWdubWVudEZvckNvbXBvbmVudC5hZGQoY29tcG9uZW50TmFtZSk7XG5cbiAgICAgICAgZXJyb3IoJyVzLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoKTogQXNzaWduaW5nIGRpcmVjdGx5IHRvICcgKyBcInRoaXMuc3RhdGUgaXMgZGVwcmVjYXRlZCAoZXhjZXB0IGluc2lkZSBhIGNvbXBvbmVudCdzIFwiICsgJ2NvbnN0cnVjdG9yKS4gVXNlIHNldFN0YXRlIGluc3RlYWQuJywgY29tcG9uZW50TmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY2xhc3NDb21wb25lbnRVcGRhdGVyLmVucXVldWVSZXBsYWNlU3RhdGUoaW5zdGFuY2UsIGluc3RhbmNlLnN0YXRlLCBudWxsKTtcbiAgfVxufSAvLyBJbnZva2VzIHRoZSBtb3VudCBsaWZlLWN5Y2xlcyBvbiBhIHByZXZpb3VzbHkgbmV2ZXIgcmVuZGVyZWQgaW5zdGFuY2UuXG5cblxuZnVuY3Rpb24gbW91bnRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBuZXdQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIGNoZWNrQ2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgY3RvciwgbmV3UHJvcHMpO1xuICB9XG5cbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICBpbnN0YW5jZS5wcm9wcyA9IG5ld1Byb3BzO1xuICBpbnN0YW5jZS5zdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIGluc3RhbmNlLnJlZnMgPSBlbXB0eVJlZnNPYmplY3Q7XG4gIGluaXRpYWxpemVVcGRhdGVRdWV1ZSh3b3JrSW5Qcm9ncmVzcyk7XG4gIHZhciBjb250ZXh0VHlwZSA9IGN0b3IuY29udGV4dFR5cGU7XG5cbiAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgY29udGV4dFR5cGUgIT09IG51bGwpIHtcbiAgICBpbnN0YW5jZS5jb250ZXh0ID0gcmVhZENvbnRleHQoY29udGV4dFR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHZhciB1bm1hc2tlZENvbnRleHQgPSBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHRydWUpO1xuICAgIGluc3RhbmNlLmNvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpO1xuICB9XG5cbiAge1xuICAgIGlmIChpbnN0YW5jZS5zdGF0ZSA9PT0gbmV3UHJvcHMpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dERpcmVjdGx5QXNzaWduaW5nUHJvcHNUb1N0YXRlLmhhcyhjb21wb25lbnROYW1lKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXREaXJlY3RseUFzc2lnbmluZ1Byb3BzVG9TdGF0ZS5hZGQoY29tcG9uZW50TmFtZSk7XG5cbiAgICAgICAgZXJyb3IoJyVzOiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdG8gYXNzaWduIHByb3BzIGRpcmVjdGx5IHRvIHN0YXRlICcgKyBcImJlY2F1c2UgdXBkYXRlcyB0byBwcm9wcyB3b24ndCBiZSByZWZsZWN0ZWQgaW4gc3RhdGUuIFwiICsgJ0luIG1vc3QgY2FzZXMsIGl0IGlzIGJldHRlciB0byB1c2UgcHJvcHMgZGlyZWN0bHkuJywgY29tcG9uZW50TmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5yZWNvcmRMZWdhY3lDb250ZXh0V2FybmluZyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZFVuc2FmZUxpZmVjeWNsZVdhcm5pbmdzKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSk7XG4gICAgfVxuICB9XG5cbiAgaW5zdGFuY2Uuc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICB2YXIgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID0gY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHM7XG5cbiAgaWYgKHR5cGVvZiBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBhcHBseURlcml2ZWRTdGF0ZUZyb21Qcm9wcyh3b3JrSW5Qcm9ncmVzcywgY3RvciwgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLCBuZXdQcm9wcyk7XG4gICAgaW5zdGFuY2Uuc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICB9IC8vIEluIG9yZGVyIHRvIHN1cHBvcnQgcmVhY3QtbGlmZWN5Y2xlcy1jb21wYXQgcG9seWZpbGxlZCBjb21wb25lbnRzLFxuICAvLyBVbnNhZmUgbGlmZWN5Y2xlcyBzaG91bGQgbm90IGJlIGludm9rZWQgZm9yIGNvbXBvbmVudHMgdXNpbmcgdGhlIG5ldyBBUElzLlxuXG5cbiAgaWYgKHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgIT09ICdmdW5jdGlvbicgJiYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgY2FsbENvbXBvbmVudFdpbGxNb3VudCh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpOyAvLyBJZiB3ZSBoYWQgYWRkaXRpb25hbCBzdGF0ZSB1cGRhdGVzIGR1cmluZyB0aGlzIGxpZmUtY3ljbGUsIGxldCdzXG4gICAgLy8gcHJvY2VzcyB0aGVtIG5vdy5cblxuICAgIHByb2Nlc3NVcGRhdGVRdWV1ZSh3b3JrSW5Qcm9ncmVzcywgbmV3UHJvcHMsIGluc3RhbmNlLCByZW5kZXJMYW5lcyk7XG4gICAgaW5zdGFuY2Uuc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciBmaWJlckZsYWdzID0gVXBkYXRlO1xuXG4gICAge1xuICAgICAgZmliZXJGbGFncyB8PSBMYXlvdXRTdGF0aWM7XG4gICAgfVxuXG4gICAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICBmaWJlckZsYWdzIHw9IE1vdW50TGF5b3V0RGV2O1xuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IGZpYmVyRmxhZ3M7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdW1lTW91bnRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBuZXdQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICB2YXIgb2xkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzO1xuICBpbnN0YW5jZS5wcm9wcyA9IG9sZFByb3BzO1xuICB2YXIgb2xkQ29udGV4dCA9IGluc3RhbmNlLmNvbnRleHQ7XG4gIHZhciBjb250ZXh0VHlwZSA9IGN0b3IuY29udGV4dFR5cGU7XG4gIHZhciBuZXh0Q29udGV4dCA9IGVtcHR5Q29udGV4dE9iamVjdDtcblxuICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnb2JqZWN0JyAmJiBjb250ZXh0VHlwZSAhPT0gbnVsbCkge1xuICAgIG5leHRDb250ZXh0ID0gcmVhZENvbnRleHQoY29udGV4dFR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHZhciBuZXh0TGVnYWN5VW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBjdG9yLCB0cnVlKTtcbiAgICBuZXh0Q29udGV4dCA9IGdldE1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIG5leHRMZWdhY3lVbm1hc2tlZENvbnRleHQpO1xuICB9XG5cbiAgdmFyIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9IGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzO1xuICB2YXIgaGFzTmV3TGlmZWN5Y2xlcyA9IHR5cGVvZiBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nOyAvLyBOb3RlOiBEdXJpbmcgdGhlc2UgbGlmZS1jeWNsZXMsIGluc3RhbmNlLnByb3BzL2luc3RhbmNlLnN0YXRlIGFyZSB3aGF0XG4gIC8vIGV2ZXIgdGhlIHByZXZpb3VzbHkgYXR0ZW1wdGVkIHRvIHJlbmRlciAtIG5vdCB0aGUgXCJjdXJyZW50XCIuIEhvd2V2ZXIsXG4gIC8vIGR1cmluZyBjb21wb25lbnREaWRVcGRhdGUgd2UgcGFzcyB0aGUgXCJjdXJyZW50XCIgcHJvcHMuXG4gIC8vIEluIG9yZGVyIHRvIHN1cHBvcnQgcmVhY3QtbGlmZWN5Y2xlcy1jb21wYXQgcG9seWZpbGxlZCBjb21wb25lbnRzLFxuICAvLyBVbnNhZmUgbGlmZWN5Y2xlcyBzaG91bGQgbm90IGJlIGludm9rZWQgZm9yIGNvbXBvbmVudHMgdXNpbmcgdGhlIG5ldyBBUElzLlxuXG4gIGlmICghaGFzTmV3TGlmZWN5Y2xlcyAmJiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSkge1xuICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMgfHwgb2xkQ29udGV4dCAhPT0gbmV4dENvbnRleHQpIHtcbiAgICAgIGNhbGxDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSwgbmV3UHJvcHMsIG5leHRDb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICByZXNldEhhc0ZvcmNlVXBkYXRlQmVmb3JlUHJvY2Vzc2luZygpO1xuICB2YXIgb2xkU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICB2YXIgbmV3U3RhdGUgPSBpbnN0YW5jZS5zdGF0ZSA9IG9sZFN0YXRlO1xuICBwcm9jZXNzVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MsIG5ld1Byb3BzLCBpbnN0YW5jZSwgcmVuZGVyTGFuZXMpO1xuICBuZXdTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKG9sZFByb3BzID09PSBuZXdQcm9wcyAmJiBvbGRTdGF0ZSA9PT0gbmV3U3RhdGUgJiYgIWhhc0NvbnRleHRDaGFuZ2VkKCkgJiYgIWNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmcoKSkge1xuICAgIC8vIElmIGFuIHVwZGF0ZSB3YXMgYWxyZWFkeSBpbiBwcm9ncmVzcywgd2Ugc2hvdWxkIHNjaGVkdWxlIGFuIFVwZGF0ZVxuICAgIC8vIGVmZmVjdCBldmVuIHRob3VnaCB3ZSdyZSBiYWlsaW5nIG91dCwgc28gdGhhdCBjV1UvY0RVIGFyZSBjYWxsZWQuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIGZpYmVyRmxhZ3MgPSBVcGRhdGU7XG5cbiAgICAgIHtcbiAgICAgICAgZmliZXJGbGFncyB8PSBMYXlvdXRTdGF0aWM7XG4gICAgICB9XG5cbiAgICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICBmaWJlckZsYWdzIHw9IE1vdW50TGF5b3V0RGV2O1xuICAgICAgfVxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBmaWJlckZsYWdzO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgYXBwbHlEZXJpdmVkU3RhdGVGcm9tUHJvcHMod29ya0luUHJvZ3Jlc3MsIGN0b3IsIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcywgbmV3UHJvcHMpO1xuICAgIG5ld1N0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfVxuXG4gIHZhciBzaG91bGRVcGRhdGUgPSBjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkgfHwgY2hlY2tTaG91bGRDb21wb25lbnRVcGRhdGUod29ya0luUHJvZ3Jlc3MsIGN0b3IsIG9sZFByb3BzLCBuZXdQcm9wcywgb2xkU3RhdGUsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG5cbiAgaWYgKHNob3VsZFVwZGF0ZSkge1xuICAgIC8vIEluIG9yZGVyIHRvIHN1cHBvcnQgcmVhY3QtbGlmZWN5Y2xlcy1jb21wYXQgcG9seWZpbGxlZCBjb21wb25lbnRzLFxuICAgIC8vIFVuc2FmZSBsaWZlY3ljbGVzIHNob3VsZCBub3QgYmUgaW52b2tlZCBmb3IgY29tcG9uZW50cyB1c2luZyB0aGUgbmV3IEFQSXMuXG4gICAgaWYgKCFoYXNOZXdMaWZlY3ljbGVzICYmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50KCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50KCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIF9maWJlckZsYWdzID0gVXBkYXRlO1xuXG4gICAgICB7XG4gICAgICAgIF9maWJlckZsYWdzIHw9IExheW91dFN0YXRpYztcbiAgICAgIH1cblxuICAgICAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgIF9maWJlckZsYWdzIHw9IE1vdW50TGF5b3V0RGV2O1xuICAgICAgfVxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBfZmliZXJGbGFncztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSWYgYW4gdXBkYXRlIHdhcyBhbHJlYWR5IGluIHByb2dyZXNzLCB3ZSBzaG91bGQgc2NoZWR1bGUgYW4gVXBkYXRlXG4gICAgLy8gZWZmZWN0IGV2ZW4gdGhvdWdoIHdlJ3JlIGJhaWxpbmcgb3V0LCBzbyB0aGF0IGNXVS9jRFUgYXJlIGNhbGxlZC5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZE1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgX2ZpYmVyRmxhZ3MyID0gVXBkYXRlO1xuXG4gICAgICB7XG4gICAgICAgIF9maWJlckZsYWdzMiB8PSBMYXlvdXRTdGF0aWM7XG4gICAgICB9XG5cbiAgICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICBfZmliZXJGbGFnczIgfD0gTW91bnRMYXlvdXREZXY7XG4gICAgICB9XG5cbiAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IF9maWJlckZsYWdzMjtcbiAgICB9IC8vIElmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5lZCBmYWxzZSwgd2Ugc2hvdWxkIHN0aWxsIHVwZGF0ZSB0aGVcbiAgICAvLyBtZW1vaXplZCBzdGF0ZSB0byBpbmRpY2F0ZSB0aGF0IHRoaXMgd29yayBjYW4gYmUgcmV1c2VkLlxuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzID0gbmV3UHJvcHM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9IC8vIFVwZGF0ZSB0aGUgZXhpc3RpbmcgaW5zdGFuY2UncyBzdGF0ZSwgcHJvcHMsIGFuZCBjb250ZXh0IHBvaW50ZXJzIGV2ZW5cbiAgLy8gaWYgc2hvdWxkQ29tcG9uZW50VXBkYXRlIHJldHVybnMgZmFsc2UuXG5cblxuICBpbnN0YW5jZS5wcm9wcyA9IG5ld1Byb3BzO1xuICBpbnN0YW5jZS5zdGF0ZSA9IG5ld1N0YXRlO1xuICBpbnN0YW5jZS5jb250ZXh0ID0gbmV4dENvbnRleHQ7XG4gIHJldHVybiBzaG91bGRVcGRhdGU7XG59IC8vIEludm9rZXMgdGhlIHVwZGF0ZSBsaWZlLWN5Y2xlcyBhbmQgcmV0dXJucyBmYWxzZSBpZiBpdCBzaG91bGRuJ3QgcmVyZW5kZXIuXG5cblxuZnVuY3Rpb24gdXBkYXRlQ2xhc3NJbnN0YW5jZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgY3RvciwgbmV3UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgY2xvbmVVcGRhdGVRdWV1ZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcyk7XG4gIHZhciB1bnJlc29sdmVkT2xkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzO1xuICB2YXIgb2xkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy50eXBlID09PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSA/IHVucmVzb2x2ZWRPbGRQcm9wcyA6IHJlc29sdmVEZWZhdWx0UHJvcHMod29ya0luUHJvZ3Jlc3MudHlwZSwgdW5yZXNvbHZlZE9sZFByb3BzKTtcbiAgaW5zdGFuY2UucHJvcHMgPSBvbGRQcm9wcztcbiAgdmFyIHVucmVzb2x2ZWROZXdQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcbiAgdmFyIG9sZENvbnRleHQgPSBpbnN0YW5jZS5jb250ZXh0O1xuICB2YXIgY29udGV4dFR5cGUgPSBjdG9yLmNvbnRleHRUeXBlO1xuICB2YXIgbmV4dENvbnRleHQgPSBlbXB0eUNvbnRleHRPYmplY3Q7XG5cbiAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgY29udGV4dFR5cGUgIT09IG51bGwpIHtcbiAgICBuZXh0Q29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbmV4dFVubWFza2VkQ29udGV4dCA9IGdldFVubWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgY3RvciwgdHJ1ZSk7XG4gICAgbmV4dENvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBuZXh0VW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHZhciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPSBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcztcbiAgdmFyIGhhc05ld0xpZmVjeWNsZXMgPSB0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJzsgLy8gTm90ZTogRHVyaW5nIHRoZXNlIGxpZmUtY3ljbGVzLCBpbnN0YW5jZS5wcm9wcy9pbnN0YW5jZS5zdGF0ZSBhcmUgd2hhdFxuICAvLyBldmVyIHRoZSBwcmV2aW91c2x5IGF0dGVtcHRlZCB0byByZW5kZXIgLSBub3QgdGhlIFwiY3VycmVudFwiLiBIb3dldmVyLFxuICAvLyBkdXJpbmcgY29tcG9uZW50RGlkVXBkYXRlIHdlIHBhc3MgdGhlIFwiY3VycmVudFwiIHByb3BzLlxuICAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cblxuICBpZiAoIWhhc05ld0xpZmVjeWNsZXMgJiYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICBpZiAodW5yZXNvbHZlZE9sZFByb3BzICE9PSB1bnJlc29sdmVkTmV3UHJvcHMgfHwgb2xkQ29udGV4dCAhPT0gbmV4dENvbnRleHQpIHtcbiAgICAgIGNhbGxDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSwgbmV3UHJvcHMsIG5leHRDb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICByZXNldEhhc0ZvcmNlVXBkYXRlQmVmb3JlUHJvY2Vzc2luZygpO1xuICB2YXIgb2xkU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICB2YXIgbmV3U3RhdGUgPSBpbnN0YW5jZS5zdGF0ZSA9IG9sZFN0YXRlO1xuICBwcm9jZXNzVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MsIG5ld1Byb3BzLCBpbnN0YW5jZSwgcmVuZGVyTGFuZXMpO1xuICBuZXdTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyA9PT0gdW5yZXNvbHZlZE5ld1Byb3BzICYmIG9sZFN0YXRlID09PSBuZXdTdGF0ZSAmJiAhaGFzQ29udGV4dENoYW5nZWQoKSAmJiAhY2hlY2tIYXNGb3JjZVVwZGF0ZUFmdGVyUHJvY2Vzc2luZygpICYmICEoZW5hYmxlTGF6eUNvbnRleHRQcm9wYWdhdGlvbiAgICkpIHtcbiAgICAvLyBJZiBhbiB1cGRhdGUgd2FzIGFscmVhZHkgaW4gcHJvZ3Jlc3MsIHdlIHNob3VsZCBzY2hlZHVsZSBhbiBVcGRhdGVcbiAgICAvLyBlZmZlY3QgZXZlbiB0aG91Z2ggd2UncmUgYmFpbGluZyBvdXQsIHNvIHRoYXQgY1dVL2NEVSBhcmUgY2FsbGVkLlxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAodW5yZXNvbHZlZE9sZFByb3BzICE9PSBjdXJyZW50Lm1lbW9pemVkUHJvcHMgfHwgb2xkU3RhdGUgIT09IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSkge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyAhPT0gY3VycmVudC5tZW1vaXplZFByb3BzIHx8IG9sZFN0YXRlICE9PSBjdXJyZW50Lm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU25hcHNob3Q7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBhcHBseURlcml2ZWRTdGF0ZUZyb21Qcm9wcyh3b3JrSW5Qcm9ncmVzcywgY3RvciwgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLCBuZXdQcm9wcyk7XG4gICAgbmV3U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICB9XG5cbiAgdmFyIHNob3VsZFVwZGF0ZSA9IGNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmcoKSB8fCBjaGVja1Nob3VsZENvbXBvbmVudFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgY3Rvciwgb2xkUHJvcHMsIG5ld1Byb3BzLCBvbGRTdGF0ZSwgbmV3U3RhdGUsIG5leHRDb250ZXh0KSB8fCAvLyBUT0RPOiBJbiBzb21lIGNhc2VzLCB3ZSdsbCBlbmQgdXAgY2hlY2tpbmcgaWYgY29udGV4dCBoYXMgY2hhbmdlZCB0d2ljZSxcbiAgLy8gYm90aCBiZWZvcmUgYW5kIGFmdGVyIGBzaG91bGRDb21wb25lbnRVcGRhdGVgIGhhcyBiZWVuIGNhbGxlZC4gTm90IGlkZWFsLFxuICAvLyBidXQgSSdtIGxvYXRoIHRvIHJlZmFjdG9yIHRoaXMgZnVuY3Rpb24uIFRoaXMgb25seSBoYXBwZW5zIGZvciBtZW1vaXplZFxuICAvLyBjb21wb25lbnRzIHNvIGl0J3Mgbm90IHRoYXQgY29tbW9uLlxuICBlbmFibGVMYXp5Q29udGV4dFByb3BhZ2F0aW9uICAgO1xuXG4gIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgICAvLyBVbnNhZmUgbGlmZWN5Y2xlcyBzaG91bGQgbm90IGJlIGludm9rZWQgZm9yIGNvbXBvbmVudHMgdXNpbmcgdGhlIG5ldyBBUElzLlxuICAgIGlmICghaGFzTmV3TGlmZWN5Y2xlcyAmJiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUobmV3UHJvcHMsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUobmV3UHJvcHMsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBTbmFwc2hvdDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSWYgYW4gdXBkYXRlIHdhcyBhbHJlYWR5IGluIHByb2dyZXNzLCB3ZSBzaG91bGQgc2NoZWR1bGUgYW4gVXBkYXRlXG4gICAgLy8gZWZmZWN0IGV2ZW4gdGhvdWdoIHdlJ3JlIGJhaWxpbmcgb3V0LCBzbyB0aGF0IGNXVS9jRFUgYXJlIGNhbGxlZC5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyAhPT0gY3VycmVudC5tZW1vaXplZFByb3BzIHx8IG9sZFN0YXRlICE9PSBjdXJyZW50Lm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgIT09IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB8fCBvbGRTdGF0ZSAhPT0gY3VycmVudC5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFNuYXBzaG90O1xuICAgICAgfVxuICAgIH0gLy8gSWYgc2hvdWxkQ29tcG9uZW50VXBkYXRlIHJldHVybmVkIGZhbHNlLCB3ZSBzaG91bGQgc3RpbGwgdXBkYXRlIHRoZVxuICAgIC8vIG1lbW9pemVkIHByb3BzL3N0YXRlIHRvIGluZGljYXRlIHRoYXQgdGhpcyB3b3JrIGNhbiBiZSByZXVzZWQuXG5cblxuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMgPSBuZXdQcm9wcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gIH0gLy8gVXBkYXRlIHRoZSBleGlzdGluZyBpbnN0YW5jZSdzIHN0YXRlLCBwcm9wcywgYW5kIGNvbnRleHQgcG9pbnRlcnMgZXZlblxuICAvLyBpZiBzaG91bGRDb21wb25lbnRVcGRhdGUgcmV0dXJucyBmYWxzZS5cblxuXG4gIGluc3RhbmNlLnByb3BzID0gbmV3UHJvcHM7XG4gIGluc3RhbmNlLnN0YXRlID0gbmV3U3RhdGU7XG4gIGluc3RhbmNlLmNvbnRleHQgPSBuZXh0Q29udGV4dDtcbiAgcmV0dXJuIHNob3VsZFVwZGF0ZTtcbn1cblxuLy8gVE9ETzogVXNlIHRoZSB1bmlmaWVkIGZpYmVyIHN0YWNrIG1vZHVsZSBpbnN0ZWFkIG9mIHRoaXMgbG9jYWwgb25lP1xuLy8gSW50ZW50aW9uYWxseSBub3QgdXNpbmcgaXQgeWV0IHRvIGRlcmlzayB0aGUgaW5pdGlhbCBpbXBsZW1lbnRhdGlvbiwgYmVjYXVzZVxuLy8gdGhlIHdheSB3ZSBwdXNoL3BvcCB0aGVzZSB2YWx1ZXMgaXMgYSBiaXQgdW51c3VhbC4gSWYgdGhlcmUncyBhIG1pc3Rha2UsIEknZFxuLy8gcmF0aGVyIHRoZSBpZHMgYmUgd3JvbmcgdGhhbiBjcmFzaCB0aGUgd2hvbGUgcmVjb25jaWxlci5cbnZhciBmb3JrU3RhY2sgPSBbXTtcbnZhciBmb3JrU3RhY2tJbmRleCA9IDA7XG52YXIgdHJlZUZvcmtQcm92aWRlciA9IG51bGw7XG52YXIgdHJlZUZvcmtDb3VudCA9IDA7XG52YXIgaWRTdGFjayA9IFtdO1xudmFyIGlkU3RhY2tJbmRleCA9IDA7XG52YXIgdHJlZUNvbnRleHRQcm92aWRlciA9IG51bGw7XG52YXIgdHJlZUNvbnRleHRJZCA9IDE7XG52YXIgdHJlZUNvbnRleHRPdmVyZmxvdyA9ICcnO1xuZnVuY3Rpb24gaXNGb3JrZWRDaGlsZCh3b3JrSW5Qcm9ncmVzcykge1xuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgcmV0dXJuICh3b3JrSW5Qcm9ncmVzcy5mbGFncyAmIEZvcmtlZCkgIT09IE5vRmxhZ3M7XG59XG5mdW5jdGlvbiBnZXRGb3Jrc0F0TGV2ZWwod29ya0luUHJvZ3Jlc3MpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7XG4gIHJldHVybiB0cmVlRm9ya0NvdW50O1xufVxuZnVuY3Rpb24gZ2V0VHJlZUlkKCkge1xuICB2YXIgb3ZlcmZsb3cgPSB0cmVlQ29udGV4dE92ZXJmbG93O1xuICB2YXIgaWRXaXRoTGVhZGluZ0JpdCA9IHRyZWVDb250ZXh0SWQ7XG4gIHZhciBpZCA9IGlkV2l0aExlYWRpbmdCaXQgJiB+Z2V0TGVhZGluZ0JpdChpZFdpdGhMZWFkaW5nQml0KTtcbiAgcmV0dXJuIGlkLnRvU3RyaW5nKDMyKSArIG92ZXJmbG93O1xufVxuZnVuY3Rpb24gcHVzaFRyZWVGb3JrKHdvcmtJblByb2dyZXNzLCB0b3RhbENoaWxkcmVuKSB7XG4gIC8vIFRoaXMgaXMgY2FsbGVkIHJpZ2h0IGFmdGVyIHdlIHJlY29uY2lsZSBhbiBhcnJheSAob3IgaXRlcmF0b3IpIG9mIGNoaWxkXG4gIC8vIGZpYmVycywgYmVjYXVzZSB0aGF0J3MgdGhlIG9ubHkgcGxhY2Ugd2hlcmUgd2Uga25vdyBob3cgbWFueSBjaGlsZHJlbiBpblxuICAvLyB0aGUgd2hvbGUgc2V0IHdpdGhvdXQgZG9pbmcgZXh0cmEgd29yayBsYXRlciwgb3Igc3RvcmluZyBhZGR0aW9uYWxcbiAgLy8gaW5mb3JtYXRpb24gb24gdGhlIGZpYmVyLlxuICAvL1xuICAvLyBUaGF0J3Mgd2h5IHRoaXMgZnVuY3Rpb24gaXMgc2VwYXJhdGUgZnJvbSBwdXNoVHJlZUlkIFx1MjAxNCBpdCdzIGNhbGxlZCBkdXJpbmdcbiAgLy8gdGhlIHJlbmRlciBwaGFzZSBvZiB0aGUgZm9yayBwYXJlbnQsIG5vdCB0aGUgY2hpbGQsIHdoaWNoIGlzIHdoZXJlIHdlIHB1c2hcbiAgLy8gdGhlIG90aGVyIGNvbnRleHQgdmFsdWVzLlxuICAvL1xuICAvLyBJbiB0aGUgRml6eiBpbXBsZW1lbnRhdGlvbiB0aGlzIGlzIG11Y2ggc2ltcGxlciBiZWNhdXNlIHRoZSBjaGlsZCBpc1xuICAvLyByZW5kZXJlZCBpbiB0aGUgc2FtZSBjYWxsc3RhY2sgYXMgdGhlIHBhcmVudC5cbiAgLy9cbiAgLy8gSXQgbWlnaHQgYmUgYmV0dGVyIHRvIGp1c3QgYWRkIGEgYGZvcmtzYCBmaWVsZCB0byB0aGUgRmliZXIgdHlwZS4gSXQgd291bGRcbiAgLy8gbWFrZSB0aGlzIG1vZHVsZSBzaW1wbGVyLlxuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4KytdID0gdHJlZUZvcmtDb3VudDtcbiAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4KytdID0gdHJlZUZvcmtQcm92aWRlcjtcbiAgdHJlZUZvcmtQcm92aWRlciA9IHdvcmtJblByb2dyZXNzO1xuICB0cmVlRm9ya0NvdW50ID0gdG90YWxDaGlsZHJlbjtcbn1cbmZ1bmN0aW9uIHB1c2hUcmVlSWQod29ya0luUHJvZ3Jlc3MsIHRvdGFsQ2hpbGRyZW4sIGluZGV4KSB7XG4gIHdhcm5JZk5vdEh5ZHJhdGluZygpO1xuICBpZFN0YWNrW2lkU3RhY2tJbmRleCsrXSA9IHRyZWVDb250ZXh0SWQ7XG4gIGlkU3RhY2tbaWRTdGFja0luZGV4KytdID0gdHJlZUNvbnRleHRPdmVyZmxvdztcbiAgaWRTdGFja1tpZFN0YWNrSW5kZXgrK10gPSB0cmVlQ29udGV4dFByb3ZpZGVyO1xuICB0cmVlQ29udGV4dFByb3ZpZGVyID0gd29ya0luUHJvZ3Jlc3M7XG4gIHZhciBiYXNlSWRXaXRoTGVhZGluZ0JpdCA9IHRyZWVDb250ZXh0SWQ7XG4gIHZhciBiYXNlT3ZlcmZsb3cgPSB0cmVlQ29udGV4dE92ZXJmbG93OyAvLyBUaGUgbGVmdG1vc3QgMSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZSwgbm9uLWluY2x1c2l2ZS4gSXQncyBub3QgcGFydFxuICAvLyBvZiB0aGUgaWQ7IHdlIHVzZSBpdCB0byBhY2NvdW50IGZvciBsZWFkaW5nIDBzLlxuXG4gIHZhciBiYXNlTGVuZ3RoID0gZ2V0Qml0TGVuZ3RoKGJhc2VJZFdpdGhMZWFkaW5nQml0KSAtIDE7XG4gIHZhciBiYXNlSWQgPSBiYXNlSWRXaXRoTGVhZGluZ0JpdCAmIH4oMSA8PCBiYXNlTGVuZ3RoKTtcbiAgdmFyIHNsb3QgPSBpbmRleCArIDE7XG4gIHZhciBsZW5ndGggPSBnZXRCaXRMZW5ndGgodG90YWxDaGlsZHJlbikgKyBiYXNlTGVuZ3RoOyAvLyAzMCBpcyB0aGUgbWF4IGxlbmd0aCB3ZSBjYW4gc3RvcmUgd2l0aG91dCBvdmVyZmxvd2luZywgdGFraW5nIGludG9cbiAgLy8gY29uc2lkZXJhdGlvbiB0aGUgbGVhZGluZyAxIHdlIHVzZSB0byBtYXJrIHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLlxuXG4gIGlmIChsZW5ndGggPiAzMCkge1xuICAgIC8vIFdlIG92ZXJmbG93ZWQgdGhlIGJpdHdpc2Utc2FmZSByYW5nZS4gRmFsbCBiYWNrIHRvIHNsb3dlciBhbGdvcml0aG0uXG4gICAgLy8gVGhpcyBicmFuY2ggYXNzdW1lcyB0aGUgbGVuZ3RoIG9mIHRoZSBiYXNlIGlkIGlzIGdyZWF0ZXIgdGhhbiA1OyBpdCB3b24ndFxuICAgIC8vIHdvcmsgZm9yIHNtYWxsZXIgaWRzLCBiZWNhdXNlIHlvdSBuZWVkIDUgYml0cyBwZXIgY2hhcmFjdGVyLlxuICAgIC8vXG4gICAgLy8gV2UgZW5jb2RlIHRoZSBpZCBpbiBtdWx0aXBsZSBzdGVwczogZmlyc3QgdGhlIGJhc2UgaWQsIHRoZW4gdGhlXG4gICAgLy8gcmVtYWluaW5nIGRpZ2l0cy5cbiAgICAvL1xuICAgIC8vIEVhY2ggNSBiaXQgc2VxdWVuY2UgY29ycmVzcG9uZHMgdG8gYSBzaW5nbGUgYmFzZSAzMiBjaGFyYWN0ZXIuIFNvIGZvclxuICAgIC8vIGV4YW1wbGUsIGlmIHRoZSBjdXJyZW50IGlkIGlzIDIzIGJpdHMgbG9uZywgd2UgY2FuIGNvbnZlcnQgMjAgb2YgdGhvc2VcbiAgICAvLyBiaXRzIGludG8gYSBzdHJpbmcgb2YgNCBjaGFyYWN0ZXJzLCB3aXRoIDMgYml0cyBsZWZ0IG92ZXIuXG4gICAgLy9cbiAgICAvLyBGaXJzdCBjYWxjdWxhdGUgaG93IG1hbnkgYml0cyBpbiB0aGUgYmFzZSBpZCByZXByZXNlbnQgYSBjb21wbGV0ZVxuICAgIC8vIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMuXG4gICAgdmFyIG51bWJlck9mT3ZlcmZsb3dCaXRzID0gYmFzZUxlbmd0aCAtIGJhc2VMZW5ndGggJSA1OyAvLyBUaGVuIGNyZWF0ZSBhIGJpdG1hc2sgdGhhdCBzZWxlY3RzIG9ubHkgdGhvc2UgYml0cy5cblxuICAgIHZhciBuZXdPdmVyZmxvd0JpdHMgPSAoMSA8PCBudW1iZXJPZk92ZXJmbG93Qml0cykgLSAxOyAvLyBTZWxlY3QgdGhlIGJpdHMsIGFuZCBjb252ZXJ0IHRoZW0gdG8gYSBiYXNlIDMyIHN0cmluZy5cblxuICAgIHZhciBuZXdPdmVyZmxvdyA9IChiYXNlSWQgJiBuZXdPdmVyZmxvd0JpdHMpLnRvU3RyaW5nKDMyKTsgLy8gTm93IHdlIGNhbiByZW1vdmUgdGhvc2UgYml0cyBmcm9tIHRoZSBiYXNlIGlkLlxuXG4gICAgdmFyIHJlc3RPZkJhc2VJZCA9IGJhc2VJZCA+PiBudW1iZXJPZk92ZXJmbG93Qml0cztcbiAgICB2YXIgcmVzdE9mQmFzZUxlbmd0aCA9IGJhc2VMZW5ndGggLSBudW1iZXJPZk92ZXJmbG93Qml0czsgLy8gRmluYWxseSwgZW5jb2RlIHRoZSByZXN0IG9mIHRoZSBiaXRzIHVzaW5nIHRoZSBub3JtYWwgYWxnb3JpdGhtLiBCZWNhdXNlXG4gICAgLy8gd2UgbWFkZSBtb3JlIHJvb20sIHRoaXMgdGltZSBpdCB3b24ndCBvdmVyZmxvdy5cblxuICAgIHZhciByZXN0T2ZMZW5ndGggPSBnZXRCaXRMZW5ndGgodG90YWxDaGlsZHJlbikgKyByZXN0T2ZCYXNlTGVuZ3RoO1xuICAgIHZhciByZXN0T2ZOZXdCaXRzID0gc2xvdCA8PCByZXN0T2ZCYXNlTGVuZ3RoO1xuICAgIHZhciBpZCA9IHJlc3RPZk5ld0JpdHMgfCByZXN0T2ZCYXNlSWQ7XG4gICAgdmFyIG92ZXJmbG93ID0gbmV3T3ZlcmZsb3cgKyBiYXNlT3ZlcmZsb3c7XG4gICAgdHJlZUNvbnRleHRJZCA9IDEgPDwgcmVzdE9mTGVuZ3RoIHwgaWQ7XG4gICAgdHJlZUNvbnRleHRPdmVyZmxvdyA9IG92ZXJmbG93O1xuICB9IGVsc2Uge1xuICAgIC8vIE5vcm1hbCBwYXRoXG4gICAgdmFyIG5ld0JpdHMgPSBzbG90IDw8IGJhc2VMZW5ndGg7XG5cbiAgICB2YXIgX2lkID0gbmV3Qml0cyB8IGJhc2VJZDtcblxuICAgIHZhciBfb3ZlcmZsb3cgPSBiYXNlT3ZlcmZsb3c7XG4gICAgdHJlZUNvbnRleHRJZCA9IDEgPDwgbGVuZ3RoIHwgX2lkO1xuICAgIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBfb3ZlcmZsb3c7XG4gIH1cbn1cbmZ1bmN0aW9uIHB1c2hNYXRlcmlhbGl6ZWRUcmVlSWQod29ya0luUHJvZ3Jlc3MpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7IC8vIFRoaXMgY29tcG9uZW50IG1hdGVyaWFsaXplZCBhbiBpZC4gVGhpcyB3aWxsIGFmZmVjdCBhbnkgaWRzIHRoYXQgYXBwZWFyXG4gIC8vIGluIGl0cyBjaGlsZHJlbi5cblxuICB2YXIgcmV0dXJuRmliZXIgPSB3b3JrSW5Qcm9ncmVzcy5yZXR1cm47XG5cbiAgaWYgKHJldHVybkZpYmVyICE9PSBudWxsKSB7XG4gICAgdmFyIG51bWJlck9mRm9ya3MgPSAxO1xuICAgIHZhciBzbG90SW5kZXggPSAwO1xuICAgIHB1c2hUcmVlRm9yayh3b3JrSW5Qcm9ncmVzcywgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgcHVzaFRyZWVJZCh3b3JrSW5Qcm9ncmVzcywgbnVtYmVyT2ZGb3Jrcywgc2xvdEluZGV4KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRCaXRMZW5ndGgobnVtYmVyKSB7XG4gIHJldHVybiAzMiAtIGNsejMyKG51bWJlcik7XG59XG5cbmZ1bmN0aW9uIGdldExlYWRpbmdCaXQoaWQpIHtcbiAgcmV0dXJuIDEgPDwgZ2V0Qml0TGVuZ3RoKGlkKSAtIDE7XG59XG5cbmZ1bmN0aW9uIHBvcFRyZWVDb250ZXh0KHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIFJlc3RvcmUgdGhlIHByZXZpb3VzIHZhbHVlcy5cbiAgLy8gVGhpcyBpcyBhIGJpdCBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gb3RoZXIgY29udGV4dC1saWtlIG1vZHVsZXMgaW4gRmliZXJcbiAgLy8gYmVjYXVzZSB0aGUgc2FtZSBGaWJlciBtYXkgYXBwZWFyIG9uIHRoZSBzdGFjayBtdWx0aXBsZSB0aW1lcyBhbmQgZm9yXG4gIC8vIGRpZmZlcmVudCByZWFzb25zLiBXZSBoYXZlIHRvIGtlZXAgcG9wcGluZyB1bnRpbCB0aGUgd29yay1pbi1wcm9ncmVzcyBpc1xuICAvLyBubyBsb25nZXIgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2suXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyA9PT0gdHJlZUZvcmtQcm92aWRlcikge1xuICAgIHRyZWVGb3JrUHJvdmlkZXIgPSBmb3JrU3RhY2tbLS1mb3JrU3RhY2tJbmRleF07XG4gICAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4XSA9IG51bGw7XG4gICAgdHJlZUZvcmtDb3VudCA9IGZvcmtTdGFja1stLWZvcmtTdGFja0luZGV4XTtcbiAgICBmb3JrU3RhY2tbZm9ya1N0YWNrSW5kZXhdID0gbnVsbDtcbiAgfVxuXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyA9PT0gdHJlZUNvbnRleHRQcm92aWRlcikge1xuICAgIHRyZWVDb250ZXh0UHJvdmlkZXIgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICAgIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICAgIHRyZWVDb250ZXh0SWQgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICB9XG59XG5mdW5jdGlvbiBnZXRTdXNwZW5kZWRUcmVlQ29udGV4dCgpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7XG5cbiAgaWYgKHRyZWVDb250ZXh0UHJvdmlkZXIgIT09IG51bGwpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRyZWVDb250ZXh0SWQsXG4gICAgICBvdmVyZmxvdzogdHJlZUNvbnRleHRPdmVyZmxvd1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVTdXNwZW5kZWRUcmVlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuZGVkQ29udGV4dCkge1xuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgaWRTdGFja1tpZFN0YWNrSW5kZXgrK10gPSB0cmVlQ29udGV4dElkO1xuICBpZFN0YWNrW2lkU3RhY2tJbmRleCsrXSA9IHRyZWVDb250ZXh0T3ZlcmZsb3c7XG4gIGlkU3RhY2tbaWRTdGFja0luZGV4KytdID0gdHJlZUNvbnRleHRQcm92aWRlcjtcbiAgdHJlZUNvbnRleHRJZCA9IHN1c3BlbmRlZENvbnRleHQuaWQ7XG4gIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBzdXNwZW5kZWRDb250ZXh0Lm92ZXJmbG93O1xuICB0cmVlQ29udGV4dFByb3ZpZGVyID0gd29ya0luUHJvZ3Jlc3M7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZk5vdEh5ZHJhdGluZygpIHtcbiAge1xuICAgIGlmICghZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHRvIGJlIGh5ZHJhdGluZy4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgJyArICdhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBtYXkgaGF2ZSBiZWVuIGFuIGluc2VydGlvbiBvciBhIGh5ZHJhdGlvbi5cblxudmFyIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gbnVsbDtcbnZhciBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbnZhciBpc0h5ZHJhdGluZyA9IGZhbHNlOyAvLyBUaGlzIGZsYWcgYWxsb3dzIGZvciB3YXJuaW5nIHN1cHJlc3Npb24gd2hlbiB3ZSBleHBlY3QgdGhlcmUgdG8gYmUgbWlzbWF0Y2hlc1xuLy8gZHVlIHRvIGVhcmxpZXIgbWlzbWF0Y2hlcyBvciBhIHN1c3BlbmRlZCBmaWJlci5cblxudmFyIGRpZFN1c3BlbmRPckVycm9yREVWID0gZmFsc2U7IC8vIEh5ZHJhdGlvbiBlcnJvcnMgdGhhdCB3ZXJlIHRocm93biBpbnNpZGUgdGhpcyBib3VuZGFyeVxuXG52YXIgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcblxuZnVuY3Rpb24gd2FybklmSHlkcmF0aW5nKCkge1xuICB7XG4gICAgaWYgKGlzSHlkcmF0aW5nKSB7XG4gICAgICBlcnJvcignV2Ugc2hvdWxkIG5vdCBiZSBoeWRyYXRpbmcgaGVyZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYSBidWcuJyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtEaWRUaHJvd1doaWxlSHlkcmF0aW5nREVWKCkge1xuICB7XG4gICAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVudGVySHlkcmF0aW9uU3RhdGUoZmliZXIpIHtcblxuICB2YXIgcGFyZW50SW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcbiAgbmV4dEh5ZHJhdGFibGVJbnN0YW5jZSA9IGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkV2l0aGluQ29udGFpbmVyKHBhcmVudEluc3RhbmNlKTtcbiAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjtcbiAgaXNIeWRyYXRpbmcgPSB0cnVlO1xuICBoeWRyYXRpb25FcnJvcnMgPSBudWxsO1xuICBkaWRTdXNwZW5kT3JFcnJvckRFViA9IGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVlbnRlckh5ZHJhdGlvblN0YXRlRnJvbURlaHlkcmF0ZWRTdXNwZW5zZUluc3RhbmNlKGZpYmVyLCBzdXNwZW5zZUluc3RhbmNlLCB0cmVlQ29udGV4dCkge1xuXG4gIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZFdpdGhpblN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSk7XG4gIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7XG4gIGlzSHlkcmF0aW5nID0gdHJ1ZTtcbiAgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcbiAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSBmYWxzZTtcblxuICBpZiAodHJlZUNvbnRleHQgIT09IG51bGwpIHtcbiAgICByZXN0b3JlU3VzcGVuZGVkVHJlZUNvbnRleHQoZmliZXIsIHRyZWVDb250ZXh0KTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiB3YXJuVW5oeWRyYXRlZEluc3RhbmNlKHJldHVybkZpYmVyLCBpbnN0YW5jZSkge1xuICB7XG4gICAgc3dpdGNoIChyZXR1cm5GaWJlci50YWcpIHtcbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5Db250YWluZXIocmV0dXJuRmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8sIGluc3RhbmNlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgZGlkTm90SHlkcmF0ZUluc3RhbmNlKHJldHVybkZpYmVyLnR5cGUsIHJldHVybkZpYmVyLm1lbW9pemVkUHJvcHMsIHJldHVybkZpYmVyLnN0YXRlTm9kZSwgaW5zdGFuY2UsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgaXNDb25jdXJyZW50TW9kZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0gcmV0dXJuRmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICBpZiAoc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZCwgaW5zdGFuY2UpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRlbGV0ZUh5ZHJhdGFibGVJbnN0YW5jZShyZXR1cm5GaWJlciwgaW5zdGFuY2UpIHtcbiAgd2FyblVuaHlkcmF0ZWRJbnN0YW5jZShyZXR1cm5GaWJlciwgaW5zdGFuY2UpO1xuICB2YXIgY2hpbGRUb0RlbGV0ZSA9IGNyZWF0ZUZpYmVyRnJvbUhvc3RJbnN0YW5jZUZvckRlbGV0aW9uKCk7XG4gIGNoaWxkVG9EZWxldGUuc3RhdGVOb2RlID0gaW5zdGFuY2U7XG4gIGNoaWxkVG9EZWxldGUucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gIHZhciBkZWxldGlvbnMgPSByZXR1cm5GaWJlci5kZWxldGlvbnM7XG5cbiAgaWYgKGRlbGV0aW9ucyA9PT0gbnVsbCkge1xuICAgIHJldHVybkZpYmVyLmRlbGV0aW9ucyA9IFtjaGlsZFRvRGVsZXRlXTtcbiAgICByZXR1cm5GaWJlci5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICB9IGVsc2Uge1xuICAgIGRlbGV0aW9ucy5wdXNoKGNoaWxkVG9EZWxldGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdhcm5Ob25oeWRyYXRlZEluc3RhbmNlKHJldHVybkZpYmVyLCBmaWJlcikge1xuICB7XG4gICAgaWYgKGRpZFN1c3BlbmRPckVycm9yREVWKSB7XG4gICAgICAvLyBJbnNpZGUgYSBib3VuZGFyeSB0aGF0IGFscmVhZHkgc3VzcGVuZGVkLiBXZSdyZSBjdXJyZW50bHkgcmVuZGVyaW5nIHRoZVxuICAgICAgLy8gc2libGluZ3Mgb2YgYSBzdXNwZW5kZWQgbm9kZS4gVGhlIG1pc21hdGNoIG1heSBiZSBkdWUgdG8gdGhlIG1pc3NpbmdcbiAgICAgIC8vIGRhdGEsIHNvIGl0J3MgcHJvYmFibHkgYSBmYWxzZSBwb3NpdGl2ZS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHJldHVybkZpYmVyLnRhZykge1xuICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBwYXJlbnRDb250YWluZXIgPSByZXR1cm5GaWJlci5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcblxuICAgICAgICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICAgICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgICAgICAgIHZhciB0eXBlID0gZmliZXIudHlwZTtcbiAgICAgICAgICAgICAgdmFyIHByb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgICAgICAgICAgICBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgdHlwZSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgICAgICAgICB2YXIgdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgICAgICAgZGlkTm90RmluZEh5ZHJhdGFibGVUZXh0SW5zdGFuY2VXaXRoaW5Db250YWluZXIocGFyZW50Q29udGFpbmVyLCB0ZXh0KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHBhcmVudFR5cGUgPSByZXR1cm5GaWJlci50eXBlO1xuICAgICAgICAgIHZhciBwYXJlbnRQcm9wcyA9IHJldHVybkZpYmVyLm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhciBfdHlwZSA9IGZpYmVyLnR5cGU7XG4gICAgICAgICAgICAgICAgdmFyIF9wcm9wcyA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgICAgICAgZGlkTm90RmluZEh5ZHJhdGFibGVJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIF90eXBlLCBfcHJvcHMsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgICAgICAgaXNDb25jdXJyZW50TW9kZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhciBfdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcblxuICAgICAgICAgICAgICAgIHZhciBfaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG5cbiAgICAgICAgICAgICAgICBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIF90ZXh0LCAvLyBUT0RPOiBEZWxldGUgdGhpcyBhcmd1bWVudCB3aGVuIHdlIHJlbW92ZSB0aGUgbGVnYWN5IHJvb3QgQVBJLlxuICAgICAgICAgICAgICAgIF9pc0NvbmN1cnJlbnRNb2RlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgc3VzcGVuc2VTdGF0ZSA9IHJldHVybkZpYmVyLm1lbW9pemVkU3RhdGU7XG4gICAgICAgICAgdmFyIF9wYXJlbnRJbnN0YW5jZSA9IHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZDtcbiAgICAgICAgICBpZiAoX3BhcmVudEluc3RhbmNlICE9PSBudWxsKSBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICAgICAgICB2YXIgX3R5cGUyID0gZmliZXIudHlwZTtcbiAgICAgICAgICAgICAgdmFyIF9wcm9wczIgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgICAgICAgICAgIGRpZE5vdEZpbmRIeWRyYXRhYmxlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKF9wYXJlbnRJbnN0YW5jZSwgX3R5cGUyKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICAgICAgICAgIHZhciBfdGV4dDIgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgICAgICAgICAgIGRpZE5vdEZpbmRIeWRyYXRhYmxlVGV4dEluc3RhbmNlV2l0aGluU3VzcGVuc2VJbnN0YW5jZShfcGFyZW50SW5zdGFuY2UsIF90ZXh0Mik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluc2VydE5vbkh5ZHJhdGVkSW5zdGFuY2UocmV0dXJuRmliZXIsIGZpYmVyKSB7XG4gIGZpYmVyLmZsYWdzID0gZmliZXIuZmxhZ3MgJiB+SHlkcmF0aW5nIHwgUGxhY2VtZW50O1xuICB3YXJuTm9uaHlkcmF0ZWRJbnN0YW5jZShyZXR1cm5GaWJlciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiB0cnlIeWRyYXRlKGZpYmVyLCBuZXh0SW5zdGFuY2UpIHtcbiAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciB0eXBlID0gZmliZXIudHlwZTtcbiAgICAgICAgdmFyIHByb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBjYW5IeWRyYXRlSW5zdGFuY2UobmV4dEluc3RhbmNlLCB0eXBlKTtcblxuICAgICAgICBpZiAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICBmaWJlci5zdGF0ZU5vZGUgPSBpbnN0YW5jZTtcbiAgICAgICAgICBoeWRyYXRpb25QYXJlbnRGaWJlciA9IGZpYmVyO1xuICAgICAgICAgIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZChpbnN0YW5jZSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAge1xuICAgICAgICB2YXIgdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgdmFyIHRleHRJbnN0YW5jZSA9IGNhbkh5ZHJhdGVUZXh0SW5zdGFuY2UobmV4dEluc3RhbmNlLCB0ZXh0KTtcblxuICAgICAgICBpZiAodGV4dEluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgZmliZXIuc3RhdGVOb2RlID0gdGV4dEluc3RhbmNlO1xuICAgICAgICAgIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7IC8vIFRleHQgSW5zdGFuY2VzIGRvbid0IGhhdmUgY2hpbGRyZW4gc28gdGhlcmUncyBub3RoaW5nIHRvIGh5ZHJhdGUuXG5cbiAgICAgICAgICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBzdXNwZW5zZUluc3RhbmNlID0gY2FuSHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2UobmV4dEluc3RhbmNlKTtcblxuICAgICAgICBpZiAoc3VzcGVuc2VJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0ge1xuICAgICAgICAgICAgZGVoeWRyYXRlZDogc3VzcGVuc2VJbnN0YW5jZSxcbiAgICAgICAgICAgIHRyZWVDb250ZXh0OiBnZXRTdXNwZW5kZWRUcmVlQ29udGV4dCgpLFxuICAgICAgICAgICAgcmV0cnlMYW5lOiBPZmZzY3JlZW5MYW5lXG4gICAgICAgICAgfTtcbiAgICAgICAgICBmaWJlci5tZW1vaXplZFN0YXRlID0gc3VzcGVuc2VTdGF0ZTsgLy8gU3RvcmUgdGhlIGRlaHlkcmF0ZWQgZnJhZ21lbnQgYXMgYSBjaGlsZCBmaWJlci5cbiAgICAgICAgICAvLyBUaGlzIHNpbXBsaWZpZXMgdGhlIGNvZGUgZm9yIGdldEhvc3RTaWJsaW5nIGFuZCBkZWxldGluZyBub2RlcyxcbiAgICAgICAgICAvLyBzaW5jZSBpdCBkb2Vzbid0IGhhdmUgdG8gY29uc2lkZXIgYWxsIFN1c3BlbnNlIGJvdW5kYXJpZXMgYW5kXG4gICAgICAgICAgLy8gY2hlY2sgaWYgdGhleSdyZSBkZWh5ZHJhdGVkIG9uZXMgb3Igbm90LlxuXG4gICAgICAgICAgdmFyIGRlaHlkcmF0ZWRGcmFnbWVudCA9IGNyZWF0ZUZpYmVyRnJvbURlaHlkcmF0ZWRGcmFnbWVudChzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgICBkZWh5ZHJhdGVkRnJhZ21lbnQucmV0dXJuID0gZmliZXI7XG4gICAgICAgICAgZmliZXIuY2hpbGQgPSBkZWh5ZHJhdGVkRnJhZ21lbnQ7XG4gICAgICAgICAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjsgLy8gV2hpbGUgYSBTdXNwZW5zZSBJbnN0YW5jZSBkb2VzIGhhdmUgY2hpbGRyZW4sIHdlIHdvbid0IHN0ZXAgaW50b1xuICAgICAgICAgIC8vIGl0IGR1cmluZyB0aGUgZmlyc3QgcGFzcy4gSW5zdGVhZCwgd2UnbGwgcmVlbnRlciBpdCBsYXRlci5cblxuICAgICAgICAgIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBudWxsO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDbGllbnRSZW5kZXJPbk1pc21hdGNoKGZpYmVyKSB7XG4gIHJldHVybiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlICYmIChmaWJlci5mbGFncyAmIERpZENhcHR1cmUpID09PSBOb0ZsYWdzO1xufVxuXG5mdW5jdGlvbiB0aHJvd09uSHlkcmF0aW9uTWlzbWF0Y2goZmliZXIpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdIeWRyYXRpb24gZmFpbGVkIGJlY2F1c2UgdGhlIGluaXRpYWwgVUkgZG9lcyBub3QgbWF0Y2ggd2hhdCB3YXMgJyArICdyZW5kZXJlZCBvbiB0aGUgc2VydmVyLicpO1xufVxuXG5mdW5jdGlvbiB0cnlUb0NsYWltTmV4dEh5ZHJhdGFibGVJbnN0YW5jZShmaWJlcikge1xuICBpZiAoIWlzSHlkcmF0aW5nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5leHRJbnN0YW5jZSA9IG5leHRIeWRyYXRhYmxlSW5zdGFuY2U7XG5cbiAgaWYgKCFuZXh0SW5zdGFuY2UpIHtcbiAgICBpZiAoc2hvdWxkQ2xpZW50UmVuZGVyT25NaXNtYXRjaChmaWJlcikpIHtcbiAgICAgIHdhcm5Ob25oeWRyYXRlZEluc3RhbmNlKGh5ZHJhdGlvblBhcmVudEZpYmVyLCBmaWJlcik7XG4gICAgICB0aHJvd09uSHlkcmF0aW9uTWlzbWF0Y2goKTtcbiAgICB9IC8vIE5vdGhpbmcgdG8gaHlkcmF0ZS4gTWFrZSBpdCBhbiBpbnNlcnRpb24uXG5cblxuICAgIGluc2VydE5vbkh5ZHJhdGVkSW5zdGFuY2UoaHlkcmF0aW9uUGFyZW50RmliZXIsIGZpYmVyKTtcbiAgICBpc0h5ZHJhdGluZyA9IGZhbHNlO1xuICAgIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGZpcnN0QXR0ZW1wdGVkSW5zdGFuY2UgPSBuZXh0SW5zdGFuY2U7XG5cbiAgaWYgKCF0cnlIeWRyYXRlKGZpYmVyLCBuZXh0SW5zdGFuY2UpKSB7XG4gICAgaWYgKHNob3VsZENsaWVudFJlbmRlck9uTWlzbWF0Y2goZmliZXIpKSB7XG4gICAgICB3YXJuTm9uaHlkcmF0ZWRJbnN0YW5jZShoeWRyYXRpb25QYXJlbnRGaWJlciwgZmliZXIpO1xuICAgICAgdGhyb3dPbkh5ZHJhdGlvbk1pc21hdGNoKCk7XG4gICAgfSAvLyBJZiB3ZSBjYW4ndCBoeWRyYXRlIHRoaXMgaW5zdGFuY2UgbGV0J3MgdHJ5IHRoZSBuZXh0IG9uZS5cbiAgICAvLyBXZSB1c2UgdGhpcyBhcyBhIGhldXJpc3RpYy4gSXQncyBiYXNlZCBvbiBpbnR1aXRpb24gYW5kIG5vdCBkYXRhIHNvIGl0XG4gICAgLy8gbWlnaHQgYmUgZmxhd2VkIG9yIHVubmVjZXNzYXJ5LlxuXG5cbiAgICBuZXh0SW5zdGFuY2UgPSBnZXROZXh0SHlkcmF0YWJsZVNpYmxpbmcoZmlyc3RBdHRlbXB0ZWRJbnN0YW5jZSk7XG4gICAgdmFyIHByZXZIeWRyYXRpb25QYXJlbnRGaWJlciA9IGh5ZHJhdGlvblBhcmVudEZpYmVyO1xuXG4gICAgaWYgKCFuZXh0SW5zdGFuY2UgfHwgIXRyeUh5ZHJhdGUoZmliZXIsIG5leHRJbnN0YW5jZSkpIHtcbiAgICAgIC8vIE5vdGhpbmcgdG8gaHlkcmF0ZS4gTWFrZSBpdCBhbiBpbnNlcnRpb24uXG4gICAgICBpbnNlcnROb25IeWRyYXRlZEluc3RhbmNlKGh5ZHJhdGlvblBhcmVudEZpYmVyLCBmaWJlcik7XG4gICAgICBpc0h5ZHJhdGluZyA9IGZhbHNlO1xuICAgICAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIFdlIG1hdGNoZWQgdGhlIG5leHQgb25lLCB3ZSdsbCBub3cgYXNzdW1lIHRoYXQgdGhlIGZpcnN0IG9uZSB3YXNcbiAgICAvLyBzdXBlcmZsdW91cyBhbmQgd2UnbGwgZGVsZXRlIGl0LiBTaW5jZSB3ZSBjYW4ndCBlYWdlcmx5IGRlbGV0ZSBpdFxuICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2NoZWR1bGUgYSBkZWxldGlvbi4gVG8gZG8gdGhhdCwgdGhpcyBub2RlIG5lZWRzIGEgZHVtbXlcbiAgICAvLyBmaWJlciBhc3NvY2lhdGVkIHdpdGggaXQuXG5cblxuICAgIGRlbGV0ZUh5ZHJhdGFibGVJbnN0YW5jZShwcmV2SHlkcmF0aW9uUGFyZW50RmliZXIsIGZpcnN0QXR0ZW1wdGVkSW5zdGFuY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0SW5zdGFuY2UoZmliZXIsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQpIHtcblxuICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG4gIHZhciBzaG91bGRXYXJuSWZNaXNtYXRjaERldiA9ICFkaWRTdXNwZW5kT3JFcnJvckRFVjtcbiAgdmFyIHVwZGF0ZVBheWxvYWQgPSBoeWRyYXRlSW5zdGFuY2UoaW5zdGFuY2UsIGZpYmVyLnR5cGUsIGZpYmVyLm1lbW9pemVkUHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQsIGZpYmVyLCBzaG91bGRXYXJuSWZNaXNtYXRjaERldik7IC8vIFRPRE86IFR5cGUgdGhpcyBzcGVjaWZpYyB0byB0aGlzIHR5cGUgb2YgY29tcG9uZW50LlxuXG4gIGZpYmVyLnVwZGF0ZVF1ZXVlID0gdXBkYXRlUGF5bG9hZDsgLy8gSWYgdGhlIHVwZGF0ZSBwYXlsb2FkIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIGEgY2hhbmdlIG9yIGlmIHRoZXJlXG4gIC8vIGlzIGEgbmV3IHJlZiB3ZSBtYXJrIHRoaXMgYXMgYW4gdXBkYXRlLlxuXG4gIGlmICh1cGRhdGVQYXlsb2FkICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0VGV4dEluc3RhbmNlKGZpYmVyKSB7XG5cbiAgdmFyIHRleHRJbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcbiAgdmFyIHRleHRDb250ZW50ID0gZmliZXIubWVtb2l6ZWRQcm9wcztcbiAgdmFyIHNob3VsZFVwZGF0ZSA9IGh5ZHJhdGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlLCB0ZXh0Q29udGVudCwgZmliZXIpO1xuXG4gIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAvLyBXZSBhc3N1bWUgdGhhdCBwcmVwYXJlVG9IeWRyYXRlSG9zdFRleHRJbnN0YW5jZSBpcyBjYWxsZWQgaW4gYSBjb250ZXh0IHdoZXJlIHRoZVxuICAgIC8vIGh5ZHJhdGlvbiBwYXJlbnQgaXMgdGhlIHBhcmVudCBob3N0IGNvbXBvbmVudCBvZiB0aGlzIGhvc3QgdGV4dC5cbiAgICB2YXIgcmV0dXJuRmliZXIgPSBoeWRyYXRpb25QYXJlbnRGaWJlcjtcblxuICAgIGlmIChyZXR1cm5GaWJlciAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChyZXR1cm5GaWJlci50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGFyZW50Q29udGFpbmVyID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG4gICAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgICBkaWROb3RNYXRjaEh5ZHJhdGVkQ29udGFpbmVyVGV4dEluc3RhbmNlKHBhcmVudENvbnRhaW5lciwgdGV4dEluc3RhbmNlLCB0ZXh0Q29udGVudCwgLy8gVE9ETzogRGVsZXRlIHRoaXMgYXJndW1lbnQgd2hlbiB3ZSByZW1vdmUgdGhlIGxlZ2FjeSByb290IEFQSS5cbiAgICAgICAgICAgIGlzQ29uY3VycmVudE1vZGUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGFyZW50VHlwZSA9IHJldHVybkZpYmVyLnR5cGU7XG4gICAgICAgICAgICB2YXIgcGFyZW50UHJvcHMgPSByZXR1cm5GaWJlci5tZW1vaXplZFByb3BzO1xuICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICB2YXIgX2lzQ29uY3VycmVudE1vZGUyID0gKHJldHVybkZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcblxuICAgICAgICAgICAgZGlkTm90TWF0Y2hIeWRyYXRlZFRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIHRleHRJbnN0YW5jZSwgdGV4dENvbnRlbnQsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgICBfaXNDb25jdXJyZW50TW9kZTIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaG91bGRVcGRhdGU7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0U3VzcGVuc2VJbnN0YW5jZShmaWJlcikge1xuXG4gIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBzdXNwZW5zZVN0YXRlICE9PSBudWxsID8gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkIDogbnVsbDtcblxuICBpZiAoIXN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGhhdmUgYSBoeWRyYXRlZCBzdXNwZW5zZSBpbnN0YW5jZS4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgaHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBza2lwUGFzdERlaHlkcmF0ZWRTdXNwZW5zZUluc3RhbmNlKGZpYmVyKSB7XG5cbiAgdmFyIHN1c3BlbnNlU3RhdGUgPSBmaWJlci5tZW1vaXplZFN0YXRlO1xuICB2YXIgc3VzcGVuc2VJbnN0YW5jZSA9IHN1c3BlbnNlU3RhdGUgIT09IG51bGwgPyBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQgOiBudWxsO1xuXG4gIGlmICghc3VzcGVuc2VJbnN0YW5jZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gaGF2ZSBhIGh5ZHJhdGVkIHN1c3BlbnNlIGluc3RhbmNlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cblxuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGVJbnN0YW5jZUFmdGVyU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTtcbn1cblxuZnVuY3Rpb24gcG9wVG9OZXh0SG9zdFBhcmVudChmaWJlcikge1xuICB2YXIgcGFyZW50ID0gZmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwgJiYgcGFyZW50LnRhZyAhPT0gSG9zdENvbXBvbmVudCAmJiBwYXJlbnQudGFnICE9PSBIb3N0Um9vdCAmJiBwYXJlbnQudGFnICE9PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgIHBhcmVudCA9IHBhcmVudC5yZXR1cm47XG4gIH1cblxuICBoeWRyYXRpb25QYXJlbnRGaWJlciA9IHBhcmVudDtcbn1cblxuZnVuY3Rpb24gcG9wSHlkcmF0aW9uU3RhdGUoZmliZXIpIHtcblxuICBpZiAoZmliZXIgIT09IGh5ZHJhdGlvblBhcmVudEZpYmVyKSB7XG4gICAgLy8gV2UncmUgZGVlcGVyIHRoYW4gdGhlIGN1cnJlbnQgaHlkcmF0aW9uIGNvbnRleHQsIGluc2lkZSBhbiBpbnNlcnRlZFxuICAgIC8vIHRyZWUuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKCFpc0h5ZHJhdGluZykge1xuICAgIC8vIElmIHdlJ3JlIG5vdCBjdXJyZW50bHkgaHlkcmF0aW5nIGJ1dCB3ZSdyZSBpbiBhIGh5ZHJhdGlvbiBjb250ZXh0LCB0aGVuXG4gICAgLy8gd2Ugd2VyZSBhbiBpbnNlcnRpb24gYW5kIG5vdyBuZWVkIHRvIHBvcCB1cCByZWVudGVyIGh5ZHJhdGlvbiBvZiBvdXJcbiAgICAvLyBzaWJsaW5ncy5cbiAgICBwb3BUb05leHRIb3N0UGFyZW50KGZpYmVyKTtcbiAgICBpc0h5ZHJhdGluZyA9IHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIElmIHdlIGhhdmUgYW55IHJlbWFpbmluZyBoeWRyYXRhYmxlIG5vZGVzLCB3ZSBuZWVkIHRvIGRlbGV0ZSB0aGVtIG5vdy5cbiAgLy8gV2Ugb25seSBkbyB0aGlzIGRlZXBlciB0aGFuIGhlYWQgYW5kIGJvZHkgc2luY2UgdGhleSB0ZW5kIHRvIGhhdmUgcmFuZG9tXG4gIC8vIG90aGVyIG5vZGVzIGluIHRoZW0uIFdlIGFsc28gaWdub3JlIGNvbXBvbmVudHMgd2l0aCBwdXJlIHRleHQgY29udGVudCBpblxuICAvLyBzaWRlIG9mIHRoZW0uIFdlIGFsc28gZG9uJ3QgZGVsZXRlIGFueXRoaW5nIGluc2lkZSB0aGUgcm9vdCBjb250YWluZXIuXG5cblxuICBpZiAoZmliZXIudGFnICE9PSBIb3N0Um9vdCAmJiAoZmliZXIudGFnICE9PSBIb3N0Q29tcG9uZW50IHx8IHNob3VsZERlbGV0ZVVuaHlkcmF0ZWRUYWlsSW5zdGFuY2VzKGZpYmVyLnR5cGUpICYmICFzaG91bGRTZXRUZXh0Q29udGVudChmaWJlci50eXBlLCBmaWJlci5tZW1vaXplZFByb3BzKSkpIHtcbiAgICB2YXIgbmV4dEluc3RhbmNlID0gbmV4dEh5ZHJhdGFibGVJbnN0YW5jZTtcblxuICAgIGlmIChuZXh0SW5zdGFuY2UpIHtcbiAgICAgIGlmIChzaG91bGRDbGllbnRSZW5kZXJPbk1pc21hdGNoKGZpYmVyKSkge1xuICAgICAgICB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKGZpYmVyKTtcbiAgICAgICAgdGhyb3dPbkh5ZHJhdGlvbk1pc21hdGNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aGlsZSAobmV4dEluc3RhbmNlKSB7XG4gICAgICAgICAgZGVsZXRlSHlkcmF0YWJsZUluc3RhbmNlKGZpYmVyLCBuZXh0SW5zdGFuY2UpO1xuICAgICAgICAgIG5leHRJbnN0YW5jZSA9IGdldE5leHRIeWRyYXRhYmxlU2libGluZyhuZXh0SW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcG9wVG9OZXh0SG9zdFBhcmVudChmaWJlcik7XG5cbiAgaWYgKGZpYmVyLnRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gc2tpcFBhc3REZWh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShmaWJlcik7XG4gIH0gZWxzZSB7XG4gICAgbmV4dEh5ZHJhdGFibGVJbnN0YW5jZSA9IGh5ZHJhdGlvblBhcmVudEZpYmVyID8gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKGZpYmVyLnN0YXRlTm9kZSkgOiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGhhc1VuaHlkcmF0ZWRUYWlsTm9kZXMoKSB7XG4gIHJldHVybiBpc0h5ZHJhdGluZyAmJiBuZXh0SHlkcmF0YWJsZUluc3RhbmNlICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKGZpYmVyKSB7XG4gIHZhciBuZXh0SW5zdGFuY2UgPSBuZXh0SHlkcmF0YWJsZUluc3RhbmNlO1xuXG4gIHdoaWxlIChuZXh0SW5zdGFuY2UpIHtcbiAgICB3YXJuVW5oeWRyYXRlZEluc3RhbmNlKGZpYmVyLCBuZXh0SW5zdGFuY2UpO1xuICAgIG5leHRJbnN0YW5jZSA9IGdldE5leHRIeWRyYXRhYmxlU2libGluZyhuZXh0SW5zdGFuY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0SHlkcmF0aW9uU3RhdGUoKSB7XG5cbiAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBudWxsO1xuICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbiAgaXNIeWRyYXRpbmcgPSBmYWxzZTtcbiAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gdXBncmFkZUh5ZHJhdGlvbkVycm9yc1RvUmVjb3ZlcmFibGUoKSB7XG4gIGlmIChoeWRyYXRpb25FcnJvcnMgIT09IG51bGwpIHtcbiAgICAvLyBTdWNjZXNzZnVsbHkgY29tcGxldGVkIGEgZm9yY2VkIGNsaWVudCByZW5kZXIuIFRoZSBlcnJvcnMgdGhhdCBvY2N1cnJlZFxuICAgIC8vIGR1cmluZyB0aGUgaHlkcmF0aW9uIGF0dGVtcHQgYXJlIG5vdyByZWNvdmVyZWQuIFdlIHdpbGwgbG9nIHRoZW0gaW5cbiAgICAvLyBjb21taXQgcGhhc2UsIG9uY2UgdGhlIGVudGlyZSB0cmVlIGhhcyBmaW5pc2hlZC5cbiAgICBxdWV1ZVJlY292ZXJhYmxlRXJyb3JzKGh5ZHJhdGlvbkVycm9ycyk7XG4gICAgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRJc0h5ZHJhdGluZygpIHtcbiAgcmV0dXJuIGlzSHlkcmF0aW5nO1xufVxuXG5mdW5jdGlvbiBxdWV1ZUh5ZHJhdGlvbkVycm9yKGVycm9yKSB7XG4gIGlmIChoeWRyYXRpb25FcnJvcnMgPT09IG51bGwpIHtcbiAgICBoeWRyYXRpb25FcnJvcnMgPSBbZXJyb3JdO1xuICB9IGVsc2Uge1xuICAgIGh5ZHJhdGlvbkVycm9ycy5wdXNoKGVycm9yKTtcbiAgfVxufVxuXG52YXIgZGlkV2FybkFib3V0TWFwcztcbnZhciBkaWRXYXJuQWJvdXRHZW5lcmF0b3JzO1xudmFyIGRpZFdhcm5BYm91dFN0cmluZ1JlZnM7XG52YXIgb3duZXJIYXNLZXlVc2VXYXJuaW5nO1xudmFyIG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZztcblxudmFyIHdhcm5Gb3JNaXNzaW5nS2V5ID0gZnVuY3Rpb24gKGNoaWxkLCByZXR1cm5GaWJlcikge307XG5cbntcbiAgZGlkV2FybkFib3V0TWFwcyA9IGZhbHNlO1xuICBkaWRXYXJuQWJvdXRHZW5lcmF0b3JzID0gZmFsc2U7XG4gIGRpZFdhcm5BYm91dFN0cmluZ1JlZnMgPSB7fTtcbiAgLyoqXG4gICAqIFdhcm4gaWYgdGhlcmUncyBubyBrZXkgZXhwbGljaXRseSBzZXQgb24gZHluYW1pYyBhcnJheXMgb2YgY2hpbGRyZW4gb3JcbiAgICogb2JqZWN0IGtleXMgYXJlIG5vdCB2YWxpZC4gVGhpcyBhbGxvd3MgdXMgdG8ga2VlcCB0cmFjayBvZiBjaGlsZHJlbiBiZXR3ZWVuXG4gICAqIHVwZGF0ZXMuXG4gICAqL1xuXG4gIG93bmVySGFzS2V5VXNlV2FybmluZyA9IHt9O1xuICBvd25lckhhc0Z1bmN0aW9uVHlwZVdhcm5pbmcgPSB7fTtcblxuICB3YXJuRm9yTWlzc2luZ0tleSA9IGZ1bmN0aW9uIChjaGlsZCwgcmV0dXJuRmliZXIpIHtcbiAgICBpZiAoY2hpbGQgPT09IG51bGwgfHwgdHlwZW9mIGNoaWxkICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghY2hpbGQuX3N0b3JlIHx8IGNoaWxkLl9zdG9yZS52YWxpZGF0ZWQgfHwgY2hpbGQua2V5ICE9IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNoaWxkLl9zdG9yZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVhY3QgQ29tcG9uZW50IGluIHdhcm5Gb3JNaXNzaW5nS2V5IHNob3VsZCBoYXZlIGEgX3N0b3JlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgY2hpbGQuX3N0b3JlLnZhbGlkYXRlZCA9IHRydWU7XG4gICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHJldHVybkZpYmVyKSB8fCAnQ29tcG9uZW50JztcblxuICAgIGlmIChvd25lckhhc0tleVVzZVdhcm5pbmdbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBvd25lckhhc0tleVVzZVdhcm5pbmdbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ0VhY2ggY2hpbGQgaW4gYSBsaXN0IHNob3VsZCBoYXZlIGEgdW5pcXVlICcgKyAnXCJrZXlcIiBwcm9wLiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3dhcm5pbmcta2V5cyBmb3IgJyArICdtb3JlIGluZm9ybWF0aW9uLicpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjb2VyY2VSZWYocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQpIHtcbiAgdmFyIG1peGVkUmVmID0gZWxlbWVudC5yZWY7XG5cbiAgaWYgKG1peGVkUmVmICE9PSBudWxsICYmIHR5cGVvZiBtaXhlZFJlZiAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbWl4ZWRSZWYgIT09ICdvYmplY3QnKSB7XG4gICAge1xuICAgICAgLy8gVE9ETzogQ2xlYW4gdGhpcyB1cCBvbmNlIHdlIHR1cm4gb24gdGhlIHN0cmluZyByZWYgd2FybmluZyBmb3JcbiAgICAgIC8vIGV2ZXJ5b25lLCBiZWNhdXNlIHRoZSBzdHJpY3QgbW9kZSBjYXNlIHdpbGwgbm8gbG9uZ2VyIGJlIHJlbGV2YW50XG4gICAgICBpZiAoKHJldHVybkZpYmVyLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlIHx8IHdhcm5BYm91dFN0cmluZ1JlZnMpICYmIC8vIFdlIHdhcm4gaW4gUmVhY3RFbGVtZW50LmpzIGlmIG93bmVyIGFuZCBzZWxmIGFyZSBlcXVhbCBmb3Igc3RyaW5nIHJlZnNcbiAgICAgIC8vIGJlY2F1c2UgdGhlc2UgY2Fubm90IGJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGFuIGFycm93IGZ1bmN0aW9uXG4gICAgICAvLyB1c2luZyBhIGNvZGVtb2QuIFRoZXJlZm9yZSwgd2UgZG9uJ3QgaGF2ZSB0byB3YXJuIGFib3V0IHN0cmluZyByZWZzIGFnYWluLlxuICAgICAgIShlbGVtZW50Ll9vd25lciAmJiBlbGVtZW50Ll9zZWxmICYmIGVsZW1lbnQuX293bmVyLnN0YXRlTm9kZSAhPT0gZWxlbWVudC5fc2VsZikpIHtcbiAgICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHJldHVybkZpYmVyKSB8fCAnQ29tcG9uZW50JztcblxuICAgICAgICBpZiAoIWRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcignQSBzdHJpbmcgcmVmLCBcIiVzXCIsIGhhcyBiZWVuIGZvdW5kIHdpdGhpbiBhIHN0cmljdCBtb2RlIHRyZWUuICcgKyAnU3RyaW5nIHJlZnMgYXJlIGEgc291cmNlIG9mIHBvdGVudGlhbCBidWdzIGFuZCBzaG91bGQgYmUgYXZvaWRlZC4gJyArICdXZSByZWNvbW1lbmQgdXNpbmcgdXNlUmVmKCkgb3IgY3JlYXRlUmVmKCkgaW5zdGVhZC4gJyArICdMZWFybiBtb3JlIGFib3V0IHVzaW5nIHJlZnMgc2FmZWx5IGhlcmU6ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3N0cmljdC1tb2RlLXN0cmluZy1yZWYnLCBtaXhlZFJlZik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGlkV2FybkFib3V0U3RyaW5nUmVmc1tjb21wb25lbnROYW1lXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZWxlbWVudC5fb3duZXIpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIGluc3Q7XG5cbiAgICAgIGlmIChvd25lcikge1xuICAgICAgICB2YXIgb3duZXJGaWJlciA9IG93bmVyO1xuXG4gICAgICAgIGlmIChvd25lckZpYmVyLnRhZyAhPT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Z1bmN0aW9uIGNvbXBvbmVudHMgY2Fubm90IGhhdmUgc3RyaW5nIHJlZnMuICcgKyAnV2UgcmVjb21tZW5kIHVzaW5nIHVzZVJlZigpIGluc3RlYWQuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1zdHJpbmctcmVmJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpbnN0ID0gb3duZXJGaWJlci5zdGF0ZU5vZGU7XG4gICAgICB9XG5cbiAgICAgIGlmICghaW5zdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG93bmVyIGZvciBzdHJpbmcgcmVmIFwiICsgbWl4ZWRSZWYgKyBcIi4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgXCIgKyAnYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICAgIH0gLy8gQXNzaWduaW5nIHRoaXMgdG8gYSBjb25zdCBzbyBGbG93IGtub3dzIGl0IHdvbid0IGNoYW5nZSBpbiB0aGUgY2xvc3VyZVxuXG5cbiAgICAgIHZhciByZXNvbHZlZEluc3QgPSBpbnN0O1xuXG4gICAgICB7XG4gICAgICAgIGNoZWNrUHJvcFN0cmluZ0NvZXJjaW9uKG1peGVkUmVmLCAncmVmJyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBzdHJpbmdSZWYgPSAnJyArIG1peGVkUmVmOyAvLyBDaGVjayBpZiBwcmV2aW91cyBzdHJpbmcgcmVmIG1hdGNoZXMgbmV3IHN0cmluZyByZWZcblxuICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5yZWYgIT09IG51bGwgJiYgdHlwZW9mIGN1cnJlbnQucmVmID09PSAnZnVuY3Rpb24nICYmIGN1cnJlbnQucmVmLl9zdHJpbmdSZWYgPT09IHN0cmluZ1JlZikge1xuICAgICAgICByZXR1cm4gY3VycmVudC5yZWY7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWYgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHJlZnMgPSByZXNvbHZlZEluc3QucmVmcztcblxuICAgICAgICBpZiAocmVmcyA9PT0gZW1wdHlSZWZzT2JqZWN0KSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBhIGxhenkgcG9vbGVkIGZyb3plbiBvYmplY3QsIHNvIHdlIG5lZWQgdG8gaW5pdGlhbGl6ZS5cbiAgICAgICAgICByZWZzID0gcmVzb2x2ZWRJbnN0LnJlZnMgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIGRlbGV0ZSByZWZzW3N0cmluZ1JlZl07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVmc1tzdHJpbmdSZWZdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHJlZi5fc3RyaW5nUmVmID0gc3RyaW5nUmVmO1xuICAgICAgcmV0dXJuIHJlZjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBtaXhlZFJlZiAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCByZWYgdG8gYmUgYSBmdW5jdGlvbiwgYSBzdHJpbmcsIGFuIG9iamVjdCByZXR1cm5lZCBieSBSZWFjdC5jcmVhdGVSZWYoKSwgb3IgbnVsbC4nKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50Ll9vd25lcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbGVtZW50IHJlZiB3YXMgc3BlY2lmaWVkIGFzIGEgc3RyaW5nIChcIiArIG1peGVkUmVmICsgXCIpIGJ1dCBubyBvd25lciB3YXMgc2V0LiBUaGlzIGNvdWxkIGhhcHBlbiBmb3Igb25lIG9mXCIgKyAnIHRoZSBmb2xsb3dpbmcgcmVhc29uczpcXG4nICsgJzEuIFlvdSBtYXkgYmUgYWRkaW5nIGEgcmVmIHRvIGEgZnVuY3Rpb24gY29tcG9uZW50XFxuJyArIFwiMi4gWW91IG1heSBiZSBhZGRpbmcgYSByZWYgdG8gYSBjb21wb25lbnQgdGhhdCB3YXMgbm90IGNyZWF0ZWQgaW5zaWRlIGEgY29tcG9uZW50J3MgcmVuZGVyIG1ldGhvZFxcblwiICsgJzMuIFlvdSBoYXZlIG11bHRpcGxlIGNvcGllcyBvZiBSZWFjdCBsb2FkZWRcXG4nICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVmcy1tdXN0LWhhdmUtb3duZXIgZm9yIG1vcmUgaW5mb3JtYXRpb24uJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1peGVkUmVmO1xufVxuXG5mdW5jdGlvbiB0aHJvd09uSW52YWxpZE9iamVjdFR5cGUocmV0dXJuRmliZXIsIG5ld0NoaWxkKSB7XG4gIHZhciBjaGlsZFN0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChuZXdDaGlsZCk7XG4gIHRocm93IG5ldyBFcnJvcihcIk9iamVjdHMgYXJlIG5vdCB2YWxpZCBhcyBhIFJlYWN0IGNoaWxkIChmb3VuZDogXCIgKyAoY2hpbGRTdHJpbmcgPT09ICdbb2JqZWN0IE9iamVjdF0nID8gJ29iamVjdCB3aXRoIGtleXMgeycgKyBPYmplY3Qua2V5cyhuZXdDaGlsZCkuam9pbignLCAnKSArICd9JyA6IGNoaWxkU3RyaW5nKSArIFwiKS4gXCIgKyAnSWYgeW91IG1lYW50IHRvIHJlbmRlciBhIGNvbGxlY3Rpb24gb2YgY2hpbGRyZW4sIHVzZSBhbiBhcnJheSAnICsgJ2luc3RlYWQuJyk7XG59XG5cbmZ1bmN0aW9uIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcikge1xuICB7XG4gICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHJldHVybkZpYmVyKSB8fCAnQ29tcG9uZW50JztcblxuICAgIGlmIChvd25lckhhc0Z1bmN0aW9uVHlwZVdhcm5pbmdbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBvd25lckhhc0Z1bmN0aW9uVHlwZVdhcm5pbmdbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ0Z1bmN0aW9ucyBhcmUgbm90IHZhbGlkIGFzIGEgUmVhY3QgY2hpbGQuIFRoaXMgbWF5IGhhcHBlbiBpZiAnICsgJ3lvdSByZXR1cm4gYSBDb21wb25lbnQgaW5zdGVhZCBvZiA8Q29tcG9uZW50IC8+IGZyb20gcmVuZGVyLiAnICsgJ09yIG1heWJlIHlvdSBtZWFudCB0byBjYWxsIHRoaXMgZnVuY3Rpb24gcmF0aGVyIHRoYW4gcmV0dXJuIGl0LicpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVMYXp5KGxhenlUeXBlKSB7XG4gIHZhciBwYXlsb2FkID0gbGF6eVR5cGUuX3BheWxvYWQ7XG4gIHZhciBpbml0ID0gbGF6eVR5cGUuX2luaXQ7XG4gIHJldHVybiBpbml0KHBheWxvYWQpO1xufSAvLyBUaGlzIHdyYXBwZXIgZnVuY3Rpb24gZXhpc3RzIGJlY2F1c2UgSSBleHBlY3QgdG8gY2xvbmUgdGhlIGNvZGUgaW4gZWFjaCBwYXRoXG4vLyB0byBiZSBhYmxlIHRvIG9wdGltaXplIGVhY2ggcGF0aCBpbmRpdmlkdWFsbHkgYnkgYnJhbmNoaW5nIGVhcmx5LiBUaGlzIG5lZWRzXG4vLyBhIGNvbXBpbGVyIG9yIHdlIGNhbiBkbyBpdCBtYW51YWxseS4gSGVscGVycyB0aGF0IGRvbid0IG5lZWQgdGhpcyBicmFuY2hpbmdcbi8vIGxpdmUgb3V0c2lkZSBvZiB0aGlzIGZ1bmN0aW9uLlxuXG5cbmZ1bmN0aW9uIENoaWxkUmVjb25jaWxlcihzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gIGZ1bmN0aW9uIGRlbGV0ZUNoaWxkKHJldHVybkZpYmVyLCBjaGlsZFRvRGVsZXRlKSB7XG4gICAgaWYgKCFzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAvLyBOb29wLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBkZWxldGlvbnMgPSByZXR1cm5GaWJlci5kZWxldGlvbnM7XG5cbiAgICBpZiAoZGVsZXRpb25zID09PSBudWxsKSB7XG4gICAgICByZXR1cm5GaWJlci5kZWxldGlvbnMgPSBbY2hpbGRUb0RlbGV0ZV07XG4gICAgICByZXR1cm5GaWJlci5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGlvbnMucHVzaChjaGlsZFRvRGVsZXRlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQpIHtcbiAgICBpZiAoIXNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIE5vb3AuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IC8vIFRPRE86IEZvciB0aGUgc2hvdWxkQ2xvbmUgY2FzZSwgdGhpcyBjb3VsZCBiZSBtaWNyby1vcHRpbWl6ZWQgYSBiaXQgYnlcbiAgICAvLyBhc3N1bWluZyB0aGF0IGFmdGVyIHRoZSBmaXJzdCBjaGlsZCB3ZSd2ZSBhbHJlYWR5IGFkZGVkIGV2ZXJ5dGhpbmcuXG5cblxuICAgIHZhciBjaGlsZFRvRGVsZXRlID0gY3VycmVudEZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAoY2hpbGRUb0RlbGV0ZSAhPT0gbnVsbCkge1xuICAgICAgZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkVG9EZWxldGUpO1xuICAgICAgY2hpbGRUb0RlbGV0ZSA9IGNoaWxkVG9EZWxldGUuc2libGluZztcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hcFJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCkge1xuICAgIC8vIEFkZCB0aGUgcmVtYWluaW5nIGNoaWxkcmVuIHRvIGEgdGVtcG9yYXJ5IG1hcCBzbyB0aGF0IHdlIGNhbiBmaW5kIHRoZW0gYnlcbiAgICAvLyBrZXlzIHF1aWNrbHkuIEltcGxpY2l0IChudWxsKSBrZXlzIGdldCBhZGRlZCB0byB0aGlzIHNldCB3aXRoIHRoZWlyIGluZGV4XG4gICAgLy8gaW5zdGVhZC5cbiAgICB2YXIgZXhpc3RpbmdDaGlsZHJlbiA9IG5ldyBNYXAoKTtcbiAgICB2YXIgZXhpc3RpbmdDaGlsZCA9IGN1cnJlbnRGaXJzdENoaWxkO1xuXG4gICAgd2hpbGUgKGV4aXN0aW5nQ2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGlmIChleGlzdGluZ0NoaWxkLmtleSAhPT0gbnVsbCkge1xuICAgICAgICBleGlzdGluZ0NoaWxkcmVuLnNldChleGlzdGluZ0NoaWxkLmtleSwgZXhpc3RpbmdDaGlsZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZ0NoaWxkcmVuLnNldChleGlzdGluZ0NoaWxkLmluZGV4LCBleGlzdGluZ0NoaWxkKTtcbiAgICAgIH1cblxuICAgICAgZXhpc3RpbmdDaGlsZCA9IGV4aXN0aW5nQ2hpbGQuc2libGluZztcbiAgICB9XG5cbiAgICByZXR1cm4gZXhpc3RpbmdDaGlsZHJlbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVzZUZpYmVyKGZpYmVyLCBwZW5kaW5nUHJvcHMpIHtcbiAgICAvLyBXZSBjdXJyZW50bHkgc2V0IHNpYmxpbmcgdG8gbnVsbCBhbmQgaW5kZXggdG8gMCBoZXJlIGJlY2F1c2UgaXQgaXMgZWFzeVxuICAgIC8vIHRvIGZvcmdldCB0byBkbyBiZWZvcmUgcmV0dXJuaW5nIGl0LiBFLmcuIGZvciB0aGUgc2luZ2xlIGNoaWxkIGNhc2UuXG4gICAgdmFyIGNsb25lID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoZmliZXIsIHBlbmRpbmdQcm9wcyk7XG4gICAgY2xvbmUuaW5kZXggPSAwO1xuICAgIGNsb25lLnNpYmxpbmcgPSBudWxsO1xuICAgIHJldHVybiBjbG9uZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBsYWNlQ2hpbGQobmV3RmliZXIsIGxhc3RQbGFjZWRJbmRleCwgbmV3SW5kZXgpIHtcbiAgICBuZXdGaWJlci5pbmRleCA9IG5ld0luZGV4O1xuXG4gICAgaWYgKCFzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAvLyBEdXJpbmcgaHlkcmF0aW9uLCB0aGUgdXNlSWQgYWxnb3JpdGhtIG5lZWRzIHRvIGtub3cgd2hpY2ggZmliZXJzIGFyZVxuICAgICAgLy8gcGFydCBvZiBhIGxpc3Qgb2YgY2hpbGRyZW4gKGFycmF5cywgaXRlcmF0b3JzKS5cbiAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IEZvcmtlZDtcbiAgICAgIHJldHVybiBsYXN0UGxhY2VkSW5kZXg7XG4gICAgfVxuXG4gICAgdmFyIGN1cnJlbnQgPSBuZXdGaWJlci5hbHRlcm5hdGU7XG5cbiAgICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgdmFyIG9sZEluZGV4ID0gY3VycmVudC5pbmRleDtcblxuICAgICAgaWYgKG9sZEluZGV4IDwgbGFzdFBsYWNlZEluZGV4KSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBtb3ZlLlxuICAgICAgICBuZXdGaWJlci5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gICAgICAgIHJldHVybiBsYXN0UGxhY2VkSW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGlzIGl0ZW0gY2FuIHN0YXkgaW4gcGxhY2UuXG4gICAgICAgIHJldHVybiBvbGRJbmRleDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhpcyBpcyBhbiBpbnNlcnRpb24uXG4gICAgICBuZXdGaWJlci5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gICAgICByZXR1cm4gbGFzdFBsYWNlZEluZGV4O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBsYWNlU2luZ2xlQ2hpbGQobmV3RmliZXIpIHtcbiAgICAvLyBUaGlzIGlzIHNpbXBsZXIgZm9yIHRoZSBzaW5nbGUgY2hpbGQgY2FzZS4gV2Ugb25seSBuZWVkIHRvIGRvIGFcbiAgICAvLyBwbGFjZW1lbnQgZm9yIGluc2VydGluZyBuZXcgY2hpbGRyZW4uXG4gICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMgJiYgbmV3RmliZXIuYWx0ZXJuYXRlID09PSBudWxsKSB7XG4gICAgICBuZXdGaWJlci5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld0ZpYmVyO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVGV4dE5vZGUocmV0dXJuRmliZXIsIGN1cnJlbnQsIHRleHRDb250ZW50LCBsYW5lcykge1xuICAgIGlmIChjdXJyZW50ID09PSBudWxsIHx8IGN1cnJlbnQudGFnICE9PSBIb3N0VGV4dCkge1xuICAgICAgLy8gSW5zZXJ0XG4gICAgICB2YXIgY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbVRleHQodGV4dENvbnRlbnQsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzKTtcbiAgICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gY3JlYXRlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVXBkYXRlXG4gICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjdXJyZW50LCB0ZXh0Q29udGVudCk7XG4gICAgICBleGlzdGluZy5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBleGlzdGluZztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVFbGVtZW50KHJldHVybkZpYmVyLCBjdXJyZW50LCBlbGVtZW50LCBsYW5lcykge1xuICAgIHZhciBlbGVtZW50VHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgIGlmIChlbGVtZW50VHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSkge1xuICAgICAgcmV0dXJuIHVwZGF0ZUZyYWdtZW50KHJldHVybkZpYmVyLCBjdXJyZW50LCBlbGVtZW50LnByb3BzLmNoaWxkcmVuLCBsYW5lcywgZWxlbWVudC5rZXkpO1xuICAgIH1cblxuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICBpZiAoY3VycmVudC5lbGVtZW50VHlwZSA9PT0gZWxlbWVudFR5cGUgfHwgKCAvLyBLZWVwIHRoaXMgY2hlY2sgaW5saW5lIHNvIGl0IG9ubHkgcnVucyBvbiB0aGUgZmFsc2UgcGF0aDpcbiAgICAgICBpc0NvbXBhdGlibGVGYW1pbHlGb3JIb3RSZWxvYWRpbmcoY3VycmVudCwgZWxlbWVudCkgKSB8fCAvLyBMYXp5IHR5cGVzIHNob3VsZCByZWNvbmNpbGUgdGhlaXIgcmVzb2x2ZWQgdHlwZS5cbiAgICAgIC8vIFdlIG5lZWQgdG8gZG8gdGhpcyBhZnRlciB0aGUgSG90IFJlbG9hZGluZyBjaGVjayBhYm92ZSxcbiAgICAgIC8vIGJlY2F1c2UgaG90IHJlbG9hZGluZyBoYXMgZGlmZmVyZW50IHNlbWFudGljcyB0aGFuIHByb2QgYmVjYXVzZVxuICAgICAgLy8gaXQgZG9lc24ndCByZXN1c3BlbmQuIFNvIHdlIGNhbid0IGxldCB0aGUgY2FsbCBiZWxvdyBzdXNwZW5kLlxuICAgICAgdHlwZW9mIGVsZW1lbnRUeXBlID09PSAnb2JqZWN0JyAmJiBlbGVtZW50VHlwZSAhPT0gbnVsbCAmJiBlbGVtZW50VHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTEFaWV9UWVBFICYmIHJlc29sdmVMYXp5KGVsZW1lbnRUeXBlKSA9PT0gY3VycmVudC50eXBlKSB7XG4gICAgICAgIC8vIE1vdmUgYmFzZWQgb24gaW5kZXhcbiAgICAgICAgdmFyIGV4aXN0aW5nID0gdXNlRmliZXIoY3VycmVudCwgZWxlbWVudC5wcm9wcyk7XG4gICAgICAgIGV4aXN0aW5nLnJlZiA9IGNvZXJjZVJlZihyZXR1cm5GaWJlciwgY3VycmVudCwgZWxlbWVudCk7XG4gICAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBleGlzdGluZy5fZGVidWdTb3VyY2UgPSBlbGVtZW50Ll9zb3VyY2U7XG4gICAgICAgICAgZXhpc3RpbmcuX2RlYnVnT3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBleGlzdGluZztcbiAgICAgIH1cbiAgICB9IC8vIEluc2VydFxuXG5cbiAgICB2YXIgY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbUVsZW1lbnQoZWxlbWVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgIGNyZWF0ZWQucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjdXJyZW50LCBlbGVtZW50KTtcbiAgICBjcmVhdGVkLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgIHJldHVybiBjcmVhdGVkO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlUG9ydGFsKHJldHVybkZpYmVyLCBjdXJyZW50LCBwb3J0YWwsIGxhbmVzKSB7XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwgfHwgY3VycmVudC50YWcgIT09IEhvc3RQb3J0YWwgfHwgY3VycmVudC5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyAhPT0gcG9ydGFsLmNvbnRhaW5lckluZm8gfHwgY3VycmVudC5zdGF0ZU5vZGUuaW1wbGVtZW50YXRpb24gIT09IHBvcnRhbC5pbXBsZW1lbnRhdGlvbikge1xuICAgICAgLy8gSW5zZXJ0XG4gICAgICB2YXIgY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbVBvcnRhbChwb3J0YWwsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzKTtcbiAgICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gY3JlYXRlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVXBkYXRlXG4gICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjdXJyZW50LCBwb3J0YWwuY2hpbGRyZW4gfHwgW10pO1xuICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlRnJhZ21lbnQocmV0dXJuRmliZXIsIGN1cnJlbnQsIGZyYWdtZW50LCBsYW5lcywga2V5KSB7XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwgfHwgY3VycmVudC50YWcgIT09IEZyYWdtZW50KSB7XG4gICAgICAvLyBJbnNlcnRcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZnJhZ21lbnQsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzLCBrZXkpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVcGRhdGVcbiAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGN1cnJlbnQsIGZyYWdtZW50KTtcbiAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUNoaWxkKHJldHVybkZpYmVyLCBuZXdDaGlsZCwgbGFuZXMpIHtcbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnc3RyaW5nJyAmJiBuZXdDaGlsZCAhPT0gJycgfHwgdHlwZW9mIG5ld0NoaWxkID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gVGV4dCBub2RlcyBkb24ndCBoYXZlIGtleXMuIElmIHRoZSBwcmV2aW91cyBub2RlIGlzIGltcGxpY2l0bHkga2V5ZWRcbiAgICAgIC8vIHdlIGNhbiBjb250aW51ZSB0byByZXBsYWNlIGl0IHdpdGhvdXQgYWJvcnRpbmcgZXZlbiBpZiBpdCBpcyBub3QgYSB0ZXh0XG4gICAgICAvLyBub2RlLlxuICAgICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21UZXh0KCcnICsgbmV3Q2hpbGQsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzKTtcbiAgICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gY3JlYXRlZDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChuZXdDaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgX2NyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21FbGVtZW50KG5ld0NoaWxkLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG5cbiAgICAgICAgICAgIF9jcmVhdGVkLnJlZiA9IGNvZXJjZVJlZihyZXR1cm5GaWJlciwgbnVsbCwgbmV3Q2hpbGQpO1xuICAgICAgICAgICAgX2NyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICAgICAgICByZXR1cm4gX2NyZWF0ZWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIF9jcmVhdGVkMiA9IGNyZWF0ZUZpYmVyRnJvbVBvcnRhbChuZXdDaGlsZCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuXG4gICAgICAgICAgICBfY3JlYXRlZDIucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICAgICAgICByZXR1cm4gX2NyZWF0ZWQyO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGF5bG9hZCA9IG5ld0NoaWxkLl9wYXlsb2FkO1xuICAgICAgICAgICAgdmFyIGluaXQgPSBuZXdDaGlsZC5faW5pdDtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVDaGlsZChyZXR1cm5GaWJlciwgaW5pdChwYXlsb2FkKSwgbGFuZXMpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkobmV3Q2hpbGQpIHx8IGdldEl0ZXJhdG9yRm4obmV3Q2hpbGQpKSB7XG4gICAgICAgIHZhciBfY3JlYXRlZDMgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChuZXdDaGlsZCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMsIG51bGwpO1xuXG4gICAgICAgIF9jcmVhdGVkMy5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgICAgcmV0dXJuIF9jcmVhdGVkMztcbiAgICAgIH1cblxuICAgICAgdGhyb3dPbkludmFsaWRPYmplY3RUeXBlKHJldHVybkZpYmVyLCBuZXdDaGlsZCk7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB3YXJuT25GdW5jdGlvblR5cGUocmV0dXJuRmliZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2xvdChyZXR1cm5GaWJlciwgb2xkRmliZXIsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIC8vIFVwZGF0ZSB0aGUgZmliZXIgaWYgdGhlIGtleXMgbWF0Y2gsIG90aGVyd2lzZSByZXR1cm4gbnVsbC5cbiAgICB2YXIga2V5ID0gb2xkRmliZXIgIT09IG51bGwgPyBvbGRGaWJlci5rZXkgOiBudWxsO1xuXG4gICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ3N0cmluZycgJiYgbmV3Q2hpbGQgIT09ICcnIHx8IHR5cGVvZiBuZXdDaGlsZCA9PT0gJ251bWJlcicpIHtcbiAgICAgIC8vIFRleHQgbm9kZXMgZG9uJ3QgaGF2ZSBrZXlzLiBJZiB0aGUgcHJldmlvdXMgbm9kZSBpcyBpbXBsaWNpdGx5IGtleWVkXG4gICAgICAvLyB3ZSBjYW4gY29udGludWUgdG8gcmVwbGFjZSBpdCB3aXRob3V0IGFib3J0aW5nIGV2ZW4gaWYgaXQgaXMgbm90IGEgdGV4dFxuICAgICAgLy8gbm9kZS5cbiAgICAgIGlmIChrZXkgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1cGRhdGVUZXh0Tm9kZShyZXR1cm5GaWJlciwgb2xkRmliZXIsICcnICsgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChuZXdDaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAobmV3Q2hpbGQua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZUVsZW1lbnQocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBuZXdDaGlsZCwgbGFuZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKG5ld0NoaWxkLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgICAgIHJldHVybiB1cGRhdGVQb3J0YWwocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBuZXdDaGlsZCwgbGFuZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBwYXlsb2FkID0gbmV3Q2hpbGQuX3BheWxvYWQ7XG4gICAgICAgICAgICB2YXIgaW5pdCA9IG5ld0NoaWxkLl9pbml0O1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVNsb3QocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBpbml0KHBheWxvYWQpLCBsYW5lcyk7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheShuZXdDaGlsZCkgfHwgZ2V0SXRlcmF0b3JGbihuZXdDaGlsZCkpIHtcbiAgICAgICAgaWYgKGtleSAhPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVwZGF0ZUZyYWdtZW50KHJldHVybkZpYmVyLCBvbGRGaWJlciwgbmV3Q2hpbGQsIGxhbmVzLCBudWxsKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3dPbkludmFsaWRPYmplY3RUeXBlKHJldHVybkZpYmVyLCBuZXdDaGlsZCk7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB3YXJuT25GdW5jdGlvblR5cGUocmV0dXJuRmliZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlRnJvbU1hcChleGlzdGluZ0NoaWxkcmVuLCByZXR1cm5GaWJlciwgbmV3SWR4LCBuZXdDaGlsZCwgbGFuZXMpIHtcbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnc3RyaW5nJyAmJiBuZXdDaGlsZCAhPT0gJycgfHwgdHlwZW9mIG5ld0NoaWxkID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gVGV4dCBub2RlcyBkb24ndCBoYXZlIGtleXMsIHNvIHdlIG5laXRoZXIgaGF2ZSB0byBjaGVjayB0aGUgb2xkIG5vclxuICAgICAgLy8gbmV3IG5vZGUgZm9yIHRoZSBrZXkuIElmIGJvdGggYXJlIHRleHQgbm9kZXMsIHRoZXkgbWF0Y2guXG4gICAgICB2YXIgbWF0Y2hlZEZpYmVyID0gZXhpc3RpbmdDaGlsZHJlbi5nZXQobmV3SWR4KSB8fCBudWxsO1xuICAgICAgcmV0dXJuIHVwZGF0ZVRleHROb2RlKHJldHVybkZpYmVyLCBtYXRjaGVkRmliZXIsICcnICsgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChuZXdDaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgX21hdGNoZWRGaWJlciA9IGV4aXN0aW5nQ2hpbGRyZW4uZ2V0KG5ld0NoaWxkLmtleSA9PT0gbnVsbCA/IG5ld0lkeCA6IG5ld0NoaWxkLmtleSkgfHwgbnVsbDtcblxuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZUVsZW1lbnQocmV0dXJuRmliZXIsIF9tYXRjaGVkRmliZXIsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIF9tYXRjaGVkRmliZXIyID0gZXhpc3RpbmdDaGlsZHJlbi5nZXQobmV3Q2hpbGQua2V5ID09PSBudWxsID8gbmV3SWR4IDogbmV3Q2hpbGQua2V5KSB8fCBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlUG9ydGFsKHJldHVybkZpYmVyLCBfbWF0Y2hlZEZpYmVyMiwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBuZXdDaGlsZC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IG5ld0NoaWxkLl9pbml0O1xuICAgICAgICAgIHJldHVybiB1cGRhdGVGcm9tTWFwKGV4aXN0aW5nQ2hpbGRyZW4sIHJldHVybkZpYmVyLCBuZXdJZHgsIGluaXQocGF5bG9hZCksIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkobmV3Q2hpbGQpIHx8IGdldEl0ZXJhdG9yRm4obmV3Q2hpbGQpKSB7XG4gICAgICAgIHZhciBfbWF0Y2hlZEZpYmVyMyA9IGV4aXN0aW5nQ2hpbGRyZW4uZ2V0KG5ld0lkeCkgfHwgbnVsbDtcblxuICAgICAgICByZXR1cm4gdXBkYXRlRnJhZ21lbnQocmV0dXJuRmliZXIsIF9tYXRjaGVkRmliZXIzLCBuZXdDaGlsZCwgbGFuZXMsIG51bGwpO1xuICAgICAgfVxuXG4gICAgICB0aHJvd09uSW52YWxpZE9iamVjdFR5cGUocmV0dXJuRmliZXIsIG5ld0NoaWxkKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIFdhcm5zIGlmIHRoZXJlIGlzIGEgZHVwbGljYXRlIG9yIG1pc3Npbmcga2V5XG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gd2Fybk9uSW52YWxpZEtleShjaGlsZCwga25vd25LZXlzLCByZXR1cm5GaWJlcikge1xuICAgIHtcbiAgICAgIGlmICh0eXBlb2YgY2hpbGQgIT09ICdvYmplY3QnIHx8IGNoaWxkID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBrbm93bktleXM7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAoY2hpbGQuJCR0eXBlb2YpIHtcbiAgICAgICAgY2FzZSBSRUFDVF9FTEVNRU5UX1RZUEU6XG4gICAgICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICAgICAgd2FybkZvck1pc3NpbmdLZXkoY2hpbGQsIHJldHVybkZpYmVyKTtcbiAgICAgICAgICB2YXIga2V5ID0gY2hpbGQua2V5O1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoa25vd25LZXlzID09PSBudWxsKSB7XG4gICAgICAgICAgICBrbm93bktleXMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICBrbm93bktleXMuYWRkKGtleSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWtub3duS2V5cy5oYXMoa2V5KSkge1xuICAgICAgICAgICAga25vd25LZXlzLmFkZChrZXkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZXJyb3IoJ0VuY291bnRlcmVkIHR3byBjaGlsZHJlbiB3aXRoIHRoZSBzYW1lIGtleSwgYCVzYC4gJyArICdLZXlzIHNob3VsZCBiZSB1bmlxdWUgc28gdGhhdCBjb21wb25lbnRzIG1haW50YWluIHRoZWlyIGlkZW50aXR5ICcgKyAnYWNyb3NzIHVwZGF0ZXMuIE5vbi11bmlxdWUga2V5cyBtYXkgY2F1c2UgY2hpbGRyZW4gdG8gYmUgJyArICdkdXBsaWNhdGVkIGFuZC9vciBvbWl0dGVkIFx1MjAxNCB0aGUgYmVoYXZpb3IgaXMgdW5zdXBwb3J0ZWQgYW5kICcgKyAnY291bGQgY2hhbmdlIGluIGEgZnV0dXJlIHZlcnNpb24uJywga2V5KTtcblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICAgIHZhciBwYXlsb2FkID0gY2hpbGQuX3BheWxvYWQ7XG4gICAgICAgICAgdmFyIGluaXQgPSBjaGlsZC5faW5pdDtcbiAgICAgICAgICB3YXJuT25JbnZhbGlkS2V5KGluaXQocGF5bG9hZCksIGtub3duS2V5cywgcmV0dXJuRmliZXIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBrbm93bktleXM7XG4gIH1cblxuICBmdW5jdGlvbiByZWNvbmNpbGVDaGlsZHJlbkFycmF5KHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGRyZW4sIGxhbmVzKSB7XG4gICAgLy8gVGhpcyBhbGdvcml0aG0gY2FuJ3Qgb3B0aW1pemUgYnkgc2VhcmNoaW5nIGZyb20gYm90aCBlbmRzIHNpbmNlIHdlXG4gICAgLy8gZG9uJ3QgaGF2ZSBiYWNrcG9pbnRlcnMgb24gZmliZXJzLiBJJ20gdHJ5aW5nIHRvIHNlZSBob3cgZmFyIHdlIGNhbiBnZXRcbiAgICAvLyB3aXRoIHRoYXQgbW9kZWwuIElmIGl0IGVuZHMgdXAgbm90IGJlaW5nIHdvcnRoIHRoZSB0cmFkZW9mZnMsIHdlIGNhblxuICAgIC8vIGFkZCBpdCBsYXRlci5cbiAgICAvLyBFdmVuIHdpdGggYSB0d28gZW5kZWQgb3B0aW1pemF0aW9uLCB3ZSdkIHdhbnQgdG8gb3B0aW1pemUgZm9yIHRoZSBjYXNlXG4gICAgLy8gd2hlcmUgdGhlcmUgYXJlIGZldyBjaGFuZ2VzIGFuZCBicnV0ZSBmb3JjZSB0aGUgY29tcGFyaXNvbiBpbnN0ZWFkIG9mXG4gICAgLy8gZ29pbmcgZm9yIHRoZSBNYXAuIEl0J2QgbGlrZSB0byBleHBsb3JlIGhpdHRpbmcgdGhhdCBwYXRoIGZpcnN0IGluXG4gICAgLy8gZm9yd2FyZC1vbmx5IG1vZGUgYW5kIG9ubHkgZ28gZm9yIHRoZSBNYXAgb25jZSB3ZSBub3RpY2UgdGhhdCB3ZSBuZWVkXG4gICAgLy8gbG90cyBvZiBsb29rIGFoZWFkLiBUaGlzIGRvZXNuJ3QgaGFuZGxlIHJldmVyc2FsIGFzIHdlbGwgYXMgdHdvIGVuZGVkXG4gICAgLy8gc2VhcmNoIGJ1dCB0aGF0J3MgdW51c3VhbC4gQmVzaWRlcywgZm9yIHRoZSB0d28gZW5kZWQgb3B0aW1pemF0aW9uIHRvXG4gICAgLy8gd29yayBvbiBJdGVyYWJsZXMsIHdlJ2QgbmVlZCB0byBjb3B5IHRoZSB3aG9sZSBzZXQuXG4gICAgLy8gSW4gdGhpcyBmaXJzdCBpdGVyYXRpb24sIHdlJ2xsIGp1c3QgbGl2ZSB3aXRoIGhpdHRpbmcgdGhlIGJhZCBjYXNlXG4gICAgLy8gKGFkZGluZyBldmVyeXRoaW5nIHRvIGEgTWFwKSBpbiBmb3IgZXZlcnkgaW5zZXJ0L21vdmUuXG4gICAgLy8gSWYgeW91IGNoYW5nZSB0aGlzIGNvZGUsIGFsc28gdXBkYXRlIHJlY29uY2lsZUNoaWxkcmVuSXRlcmF0b3IoKSB3aGljaFxuICAgIC8vIHVzZXMgdGhlIHNhbWUgYWxnb3JpdGhtLlxuICAgIHtcbiAgICAgIC8vIEZpcnN0LCB2YWxpZGF0ZSBrZXlzLlxuICAgICAgdmFyIGtub3duS2V5cyA9IG51bGw7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbmV3Q2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gbmV3Q2hpbGRyZW5baV07XG4gICAgICAgIGtub3duS2V5cyA9IHdhcm5PbkludmFsaWRLZXkoY2hpbGQsIGtub3duS2V5cywgcmV0dXJuRmliZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciByZXN1bHRpbmdGaXJzdENoaWxkID0gbnVsbDtcbiAgICB2YXIgcHJldmlvdXNOZXdGaWJlciA9IG51bGw7XG4gICAgdmFyIG9sZEZpYmVyID0gY3VycmVudEZpcnN0Q2hpbGQ7XG4gICAgdmFyIGxhc3RQbGFjZWRJbmRleCA9IDA7XG4gICAgdmFyIG5ld0lkeCA9IDA7XG4gICAgdmFyIG5leHRPbGRGaWJlciA9IG51bGw7XG5cbiAgICBmb3IgKDsgb2xkRmliZXIgIT09IG51bGwgJiYgbmV3SWR4IDwgbmV3Q2hpbGRyZW4ubGVuZ3RoOyBuZXdJZHgrKykge1xuICAgICAgaWYgKG9sZEZpYmVyLmluZGV4ID4gbmV3SWR4KSB7XG4gICAgICAgIG5leHRPbGRGaWJlciA9IG9sZEZpYmVyO1xuICAgICAgICBvbGRGaWJlciA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0T2xkRmliZXIgPSBvbGRGaWJlci5zaWJsaW5nO1xuICAgICAgfVxuXG4gICAgICB2YXIgbmV3RmliZXIgPSB1cGRhdGVTbG90KHJldHVybkZpYmVyLCBvbGRGaWJlciwgbmV3Q2hpbGRyZW5bbmV3SWR4XSwgbGFuZXMpO1xuXG4gICAgICBpZiAobmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgLy8gVE9ETzogVGhpcyBicmVha3Mgb24gZW1wdHkgc2xvdHMgbGlrZSBudWxsIGNoaWxkcmVuLiBUaGF0J3NcbiAgICAgICAgLy8gdW5mb3J0dW5hdGUgYmVjYXVzZSBpdCB0cmlnZ2VycyB0aGUgc2xvdyBwYXRoIGFsbCB0aGUgdGltZS4gV2UgbmVlZFxuICAgICAgICAvLyBhIGJldHRlciB3YXkgdG8gY29tbXVuaWNhdGUgd2hldGhlciB0aGlzIHdhcyBhIG1pc3Mgb3IgbnVsbCxcbiAgICAgICAgLy8gYm9vbGVhbiwgdW5kZWZpbmVkLCBldGMuXG4gICAgICAgIGlmIChvbGRGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIG9sZEZpYmVyID0gbmV4dE9sZEZpYmVyO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAgIGlmIChvbGRGaWJlciAmJiBuZXdGaWJlci5hbHRlcm5hdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBzbG90LCBidXQgd2UgZGlkbid0IHJldXNlIHRoZSBleGlzdGluZyBmaWJlciwgc28gd2VcbiAgICAgICAgICAvLyBuZWVkIHRvIGRlbGV0ZSB0aGUgZXhpc3RpbmcgY2hpbGQuXG4gICAgICAgICAgZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIG9sZEZpYmVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsYXN0UGxhY2VkSW5kZXggPSBwbGFjZUNoaWxkKG5ld0ZpYmVyLCBsYXN0UGxhY2VkSW5kZXgsIG5ld0lkeCk7XG5cbiAgICAgIGlmIChwcmV2aW91c05ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgIC8vIFRPRE86IE1vdmUgb3V0IG9mIHRoZSBsb29wLiBUaGlzIG9ubHkgaGFwcGVucyBmb3IgdGhlIGZpcnN0IHJ1bi5cbiAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IG5ld0ZpYmVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVE9ETzogRGVmZXIgc2libGluZ3MgaWYgd2UncmUgbm90IGF0IHRoZSByaWdodCBpbmRleCBmb3IgdGhpcyBzbG90LlxuICAgICAgICAvLyBJLmUuIGlmIHdlIGhhZCBudWxsIHZhbHVlcyBiZWZvcmUsIHRoZW4gd2Ugd2FudCB0byBkZWZlciB0aGlzXG4gICAgICAgIC8vIGZvciBlYWNoIG51bGwgdmFsdWUuIEhvd2V2ZXIsIHdlIGFsc28gZG9uJ3Qgd2FudCB0byBjYWxsIHVwZGF0ZVNsb3RcbiAgICAgICAgLy8gd2l0aCB0aGUgcHJldmlvdXMgb25lLlxuICAgICAgICBwcmV2aW91c05ld0ZpYmVyLnNpYmxpbmcgPSBuZXdGaWJlcjtcbiAgICAgIH1cblxuICAgICAgcHJldmlvdXNOZXdGaWJlciA9IG5ld0ZpYmVyO1xuICAgICAgb2xkRmliZXIgPSBuZXh0T2xkRmliZXI7XG4gICAgfVxuXG4gICAgaWYgKG5ld0lkeCA9PT0gbmV3Q2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAvLyBXZSd2ZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIG5ldyBjaGlsZHJlbi4gV2UgY2FuIGRlbGV0ZSB0aGUgcmVzdC5cbiAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBvbGRGaWJlcik7XG5cbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpKSB7XG4gICAgICAgIHZhciBudW1iZXJPZkZvcmtzID0gbmV3SWR4O1xuICAgICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIG51bWJlck9mRm9ya3MpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0aW5nRmlyc3RDaGlsZDtcbiAgICB9XG5cbiAgICBpZiAob2xkRmliZXIgPT09IG51bGwpIHtcbiAgICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYW55IG1vcmUgZXhpc3RpbmcgY2hpbGRyZW4gd2UgY2FuIGNob29zZSBhIGZhc3QgcGF0aFxuICAgICAgLy8gc2luY2UgdGhlIHJlc3Qgd2lsbCBhbGwgYmUgaW5zZXJ0aW9ucy5cbiAgICAgIGZvciAoOyBuZXdJZHggPCBuZXdDaGlsZHJlbi5sZW5ndGg7IG5ld0lkeCsrKSB7XG4gICAgICAgIHZhciBfbmV3RmliZXIgPSBjcmVhdGVDaGlsZChyZXR1cm5GaWJlciwgbmV3Q2hpbGRyZW5bbmV3SWR4XSwgbGFuZXMpO1xuXG4gICAgICAgIGlmIChfbmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQoX25ld0ZpYmVyLCBsYXN0UGxhY2VkSW5kZXgsIG5ld0lkeCk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBUT0RPOiBNb3ZlIG91dCBvZiB0aGUgbG9vcC4gVGhpcyBvbmx5IGhhcHBlbnMgZm9yIHRoZSBmaXJzdCBydW4uXG4gICAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IF9uZXdGaWJlcjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2aW91c05ld0ZpYmVyLnNpYmxpbmcgPSBfbmV3RmliZXI7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2aW91c05ld0ZpYmVyID0gX25ld0ZpYmVyO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgICB2YXIgX251bWJlck9mRm9ya3MgPSBuZXdJZHg7XG4gICAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgX251bWJlck9mRm9ya3MpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0aW5nRmlyc3RDaGlsZDtcbiAgICB9IC8vIEFkZCBhbGwgY2hpbGRyZW4gdG8gYSBrZXkgbWFwIGZvciBxdWljayBsb29rdXBzLlxuXG5cbiAgICB2YXIgZXhpc3RpbmdDaGlsZHJlbiA9IG1hcFJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBvbGRGaWJlcik7IC8vIEtlZXAgc2Nhbm5pbmcgYW5kIHVzZSB0aGUgbWFwIHRvIHJlc3RvcmUgZGVsZXRlZCBpdGVtcyBhcyBtb3Zlcy5cblxuICAgIGZvciAoOyBuZXdJZHggPCBuZXdDaGlsZHJlbi5sZW5ndGg7IG5ld0lkeCsrKSB7XG4gICAgICB2YXIgX25ld0ZpYmVyMiA9IHVwZGF0ZUZyb21NYXAoZXhpc3RpbmdDaGlsZHJlbiwgcmV0dXJuRmliZXIsIG5ld0lkeCwgbmV3Q2hpbGRyZW5bbmV3SWR4XSwgbGFuZXMpO1xuXG4gICAgICBpZiAoX25ld0ZpYmVyMiAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgICAgIGlmIChfbmV3RmliZXIyLmFsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gVGhlIG5ldyBmaWJlciBpcyBhIHdvcmsgaW4gcHJvZ3Jlc3MsIGJ1dCBpZiB0aGVyZSBleGlzdHMgYVxuICAgICAgICAgICAgLy8gY3VycmVudCwgdGhhdCBtZWFucyB0aGF0IHdlIHJldXNlZCB0aGUgZmliZXIuIFdlIG5lZWQgdG8gZGVsZXRlXG4gICAgICAgICAgICAvLyBpdCBmcm9tIHRoZSBjaGlsZCBsaXN0IHNvIHRoYXQgd2UgZG9uJ3QgYWRkIGl0IHRvIHRoZSBkZWxldGlvblxuICAgICAgICAgICAgLy8gbGlzdC5cbiAgICAgICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uZGVsZXRlKF9uZXdGaWJlcjIua2V5ID09PSBudWxsID8gbmV3SWR4IDogX25ld0ZpYmVyMi5rZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQoX25ld0ZpYmVyMiwgbGFzdFBsYWNlZEluZGV4LCBuZXdJZHgpO1xuXG4gICAgICAgIGlmIChwcmV2aW91c05ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IF9uZXdGaWJlcjI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gX25ld0ZpYmVyMjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXIyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAvLyBBbnkgZXhpc3RpbmcgY2hpbGRyZW4gdGhhdCB3ZXJlbid0IGNvbnN1bWVkIGFib3ZlIHdlcmUgZGVsZXRlZC4gV2UgbmVlZFxuICAgICAgLy8gdG8gYWRkIHRoZW0gdG8gdGhlIGRlbGV0aW9uIGxpc3QuXG4gICAgICBleGlzdGluZ0NoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIHJldHVybiBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgIHZhciBfbnVtYmVyT2ZGb3JrczIgPSBuZXdJZHg7XG4gICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIF9udW1iZXJPZkZvcmtzMik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdGluZ0ZpcnN0Q2hpbGQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWNvbmNpbGVDaGlsZHJlbkl0ZXJhdG9yKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGRyZW5JdGVyYWJsZSwgbGFuZXMpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBzYW1lIGltcGxlbWVudGF0aW9uIGFzIHJlY29uY2lsZUNoaWxkcmVuQXJyYXkoKSxcbiAgICAvLyBidXQgdXNpbmcgdGhlIGl0ZXJhdG9yIGluc3RlYWQuXG4gICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKG5ld0NoaWxkcmVuSXRlcmFibGUpO1xuXG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuIG9iamVjdCBpcyBub3QgYW4gaXRlcmFibGUuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiAnICsgJ1JlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBXZSBkb24ndCBzdXBwb3J0IHJlbmRlcmluZyBHZW5lcmF0b3JzIGJlY2F1c2UgaXQncyBhIG11dGF0aW9uLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTI5OTVcbiAgICAgIGlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIC8vICRGbG93Rml4TWUgRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgdG9TdHJpbmdUYWdcbiAgICAgIG5ld0NoaWxkcmVuSXRlcmFibGVbU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ0dlbmVyYXRvcicpIHtcbiAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRHZW5lcmF0b3JzKSB7XG4gICAgICAgICAgZXJyb3IoJ1VzaW5nIEdlbmVyYXRvcnMgYXMgY2hpbGRyZW4gaXMgdW5zdXBwb3J0ZWQgYW5kIHdpbGwgbGlrZWx5IHlpZWxkICcgKyAndW5leHBlY3RlZCByZXN1bHRzIGJlY2F1c2UgZW51bWVyYXRpbmcgYSBnZW5lcmF0b3IgbXV0YXRlcyBpdC4gJyArICdZb3UgbWF5IGNvbnZlcnQgaXQgdG8gYW4gYXJyYXkgd2l0aCBgQXJyYXkuZnJvbSgpYCBvciB0aGUgJyArICdgWy4uLnNwcmVhZF1gIG9wZXJhdG9yIGJlZm9yZSByZW5kZXJpbmcuIEtlZXAgaW4gbWluZCAnICsgJ3lvdSBtaWdodCBuZWVkIHRvIHBvbHlmaWxsIHRoZXNlIGZlYXR1cmVzIGZvciBvbGRlciBicm93c2Vycy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRpZFdhcm5BYm91dEdlbmVyYXRvcnMgPSB0cnVlO1xuICAgICAgfSAvLyBXYXJuIGFib3V0IHVzaW5nIE1hcHMgYXMgY2hpbGRyZW5cblxuXG4gICAgICBpZiAobmV3Q2hpbGRyZW5JdGVyYWJsZS5lbnRyaWVzID09PSBpdGVyYXRvckZuKSB7XG4gICAgICAgIGlmICghZGlkV2FybkFib3V0TWFwcykge1xuICAgICAgICAgIGVycm9yKCdVc2luZyBNYXBzIGFzIGNoaWxkcmVuIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnVXNlIGFuIGFycmF5IG9mIGtleWVkIFJlYWN0RWxlbWVudHMgaW5zdGVhZC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRpZFdhcm5BYm91dE1hcHMgPSB0cnVlO1xuICAgICAgfSAvLyBGaXJzdCwgdmFsaWRhdGUga2V5cy5cbiAgICAgIC8vIFdlJ2xsIGdldCBhIGRpZmZlcmVudCBpdGVyYXRvciBsYXRlciBmb3IgdGhlIG1haW4gcGFzcy5cblxuXG4gICAgICB2YXIgX25ld0NoaWxkcmVuID0gaXRlcmF0b3JGbi5jYWxsKG5ld0NoaWxkcmVuSXRlcmFibGUpO1xuXG4gICAgICBpZiAoX25ld0NoaWxkcmVuKSB7XG4gICAgICAgIHZhciBrbm93bktleXMgPSBudWxsO1xuXG4gICAgICAgIHZhciBfc3RlcCA9IF9uZXdDaGlsZHJlbi5uZXh0KCk7XG5cbiAgICAgICAgZm9yICg7ICFfc3RlcC5kb25lOyBfc3RlcCA9IF9uZXdDaGlsZHJlbi5uZXh0KCkpIHtcbiAgICAgICAgICB2YXIgY2hpbGQgPSBfc3RlcC52YWx1ZTtcbiAgICAgICAgICBrbm93bktleXMgPSB3YXJuT25JbnZhbGlkS2V5KGNoaWxkLCBrbm93bktleXMsIHJldHVybkZpYmVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuZXdDaGlsZHJlbiA9IGl0ZXJhdG9yRm4uY2FsbChuZXdDaGlsZHJlbkl0ZXJhYmxlKTtcblxuICAgIGlmIChuZXdDaGlsZHJlbiA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuIGl0ZXJhYmxlIG9iamVjdCBwcm92aWRlZCBubyBpdGVyYXRvci4nKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IG51bGw7XG4gICAgdmFyIHByZXZpb3VzTmV3RmliZXIgPSBudWxsO1xuICAgIHZhciBvbGRGaWJlciA9IGN1cnJlbnRGaXJzdENoaWxkO1xuICAgIHZhciBsYXN0UGxhY2VkSW5kZXggPSAwO1xuICAgIHZhciBuZXdJZHggPSAwO1xuICAgIHZhciBuZXh0T2xkRmliZXIgPSBudWxsO1xuICAgIHZhciBzdGVwID0gbmV3Q2hpbGRyZW4ubmV4dCgpO1xuXG4gICAgZm9yICg7IG9sZEZpYmVyICE9PSBudWxsICYmICFzdGVwLmRvbmU7IG5ld0lkeCsrLCBzdGVwID0gbmV3Q2hpbGRyZW4ubmV4dCgpKSB7XG4gICAgICBpZiAob2xkRmliZXIuaW5kZXggPiBuZXdJZHgpIHtcbiAgICAgICAgbmV4dE9sZEZpYmVyID0gb2xkRmliZXI7XG4gICAgICAgIG9sZEZpYmVyID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRPbGRGaWJlciA9IG9sZEZpYmVyLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXdGaWJlciA9IHVwZGF0ZVNsb3QocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBzdGVwLnZhbHVlLCBsYW5lcyk7XG5cbiAgICAgIGlmIChuZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGJyZWFrcyBvbiBlbXB0eSBzbG90cyBsaWtlIG51bGwgY2hpbGRyZW4uIFRoYXQnc1xuICAgICAgICAvLyB1bmZvcnR1bmF0ZSBiZWNhdXNlIGl0IHRyaWdnZXJzIHRoZSBzbG93IHBhdGggYWxsIHRoZSB0aW1lLiBXZSBuZWVkXG4gICAgICAgIC8vIGEgYmV0dGVyIHdheSB0byBjb21tdW5pY2F0ZSB3aGV0aGVyIHRoaXMgd2FzIGEgbWlzcyBvciBudWxsLFxuICAgICAgICAvLyBib29sZWFuLCB1bmRlZmluZWQsIGV0Yy5cbiAgICAgICAgaWYgKG9sZEZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgb2xkRmliZXIgPSBuZXh0T2xkRmliZXI7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgICAgaWYgKG9sZEZpYmVyICYmIG5ld0ZpYmVyLmFsdGVybmF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlIG1hdGNoZWQgdGhlIHNsb3QsIGJ1dCB3ZSBkaWRuJ3QgcmV1c2UgdGhlIGV4aXN0aW5nIGZpYmVyLCBzbyB3ZVxuICAgICAgICAgIC8vIG5lZWQgdG8gZGVsZXRlIHRoZSBleGlzdGluZyBjaGlsZC5cbiAgICAgICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgb2xkRmliZXIpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQobmV3RmliZXIsIGxhc3RQbGFjZWRJbmRleCwgbmV3SWR4KTtcblxuICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgLy8gVE9ETzogTW92ZSBvdXQgb2YgdGhlIGxvb3AuIFRoaXMgb25seSBoYXBwZW5zIGZvciB0aGUgZmlyc3QgcnVuLlxuICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gbmV3RmliZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUT0RPOiBEZWZlciBzaWJsaW5ncyBpZiB3ZSdyZSBub3QgYXQgdGhlIHJpZ2h0IGluZGV4IGZvciB0aGlzIHNsb3QuXG4gICAgICAgIC8vIEkuZS4gaWYgd2UgaGFkIG51bGwgdmFsdWVzIGJlZm9yZSwgdGhlbiB3ZSB3YW50IHRvIGRlZmVyIHRoaXNcbiAgICAgICAgLy8gZm9yIGVhY2ggbnVsbCB2YWx1ZS4gSG93ZXZlciwgd2UgYWxzbyBkb24ndCB3YW50IHRvIGNhbGwgdXBkYXRlU2xvdFxuICAgICAgICAvLyB3aXRoIHRoZSBwcmV2aW91cyBvbmUuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IG5ld0ZpYmVyO1xuICAgICAgfVxuXG4gICAgICBwcmV2aW91c05ld0ZpYmVyID0gbmV3RmliZXI7XG4gICAgICBvbGRGaWJlciA9IG5leHRPbGRGaWJlcjtcbiAgICB9XG5cbiAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAvLyBXZSd2ZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIG5ldyBjaGlsZHJlbi4gV2UgY2FuIGRlbGV0ZSB0aGUgcmVzdC5cbiAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBvbGRGaWJlcik7XG5cbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpKSB7XG4gICAgICAgIHZhciBudW1iZXJPZkZvcmtzID0gbmV3SWR4O1xuICAgICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIG51bWJlck9mRm9ya3MpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0aW5nRmlyc3RDaGlsZDtcbiAgICB9XG5cbiAgICBpZiAob2xkRmliZXIgPT09IG51bGwpIHtcbiAgICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYW55IG1vcmUgZXhpc3RpbmcgY2hpbGRyZW4gd2UgY2FuIGNob29zZSBhIGZhc3QgcGF0aFxuICAgICAgLy8gc2luY2UgdGhlIHJlc3Qgd2lsbCBhbGwgYmUgaW5zZXJ0aW9ucy5cbiAgICAgIGZvciAoOyAhc3RlcC5kb25lOyBuZXdJZHgrKywgc3RlcCA9IG5ld0NoaWxkcmVuLm5leHQoKSkge1xuICAgICAgICB2YXIgX25ld0ZpYmVyMyA9IGNyZWF0ZUNoaWxkKHJldHVybkZpYmVyLCBzdGVwLnZhbHVlLCBsYW5lcyk7XG5cbiAgICAgICAgaWYgKF9uZXdGaWJlcjMgPT09IG51bGwpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQoX25ld0ZpYmVyMywgbGFzdFBsYWNlZEluZGV4LCBuZXdJZHgpO1xuXG4gICAgICAgIGlmIChwcmV2aW91c05ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gVE9ETzogTW92ZSBvdXQgb2YgdGhlIGxvb3AuIFRoaXMgb25seSBoYXBwZW5zIGZvciB0aGUgZmlyc3QgcnVuLlxuICAgICAgICAgIHJlc3VsdGluZ0ZpcnN0Q2hpbGQgPSBfbmV3RmliZXIzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IF9uZXdGaWJlcjM7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2aW91c05ld0ZpYmVyID0gX25ld0ZpYmVyMztcbiAgICAgIH1cblxuICAgICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgICAgdmFyIF9udW1iZXJPZkZvcmtzMyA9IG5ld0lkeDtcbiAgICAgICAgcHVzaFRyZWVGb3JrKHJldHVybkZpYmVyLCBfbnVtYmVyT2ZGb3JrczMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0aW5nRmlyc3RDaGlsZDtcbiAgICB9IC8vIEFkZCBhbGwgY2hpbGRyZW4gdG8gYSBrZXkgbWFwIGZvciBxdWljayBsb29rdXBzLlxuXG5cbiAgICB2YXIgZXhpc3RpbmdDaGlsZHJlbiA9IG1hcFJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBvbGRGaWJlcik7IC8vIEtlZXAgc2Nhbm5pbmcgYW5kIHVzZSB0aGUgbWFwIHRvIHJlc3RvcmUgZGVsZXRlZCBpdGVtcyBhcyBtb3Zlcy5cblxuICAgIGZvciAoOyAhc3RlcC5kb25lOyBuZXdJZHgrKywgc3RlcCA9IG5ld0NoaWxkcmVuLm5leHQoKSkge1xuICAgICAgdmFyIF9uZXdGaWJlcjQgPSB1cGRhdGVGcm9tTWFwKGV4aXN0aW5nQ2hpbGRyZW4sIHJldHVybkZpYmVyLCBuZXdJZHgsIHN0ZXAudmFsdWUsIGxhbmVzKTtcblxuICAgICAgaWYgKF9uZXdGaWJlcjQgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgICAgICBpZiAoX25ld0ZpYmVyNC5hbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFRoZSBuZXcgZmliZXIgaXMgYSB3b3JrIGluIHByb2dyZXNzLCBidXQgaWYgdGhlcmUgZXhpc3RzIGFcbiAgICAgICAgICAgIC8vIGN1cnJlbnQsIHRoYXQgbWVhbnMgdGhhdCB3ZSByZXVzZWQgdGhlIGZpYmVyLiBXZSBuZWVkIHRvIGRlbGV0ZVxuICAgICAgICAgICAgLy8gaXQgZnJvbSB0aGUgY2hpbGQgbGlzdCBzbyB0aGF0IHdlIGRvbid0IGFkZCBpdCB0byB0aGUgZGVsZXRpb25cbiAgICAgICAgICAgIC8vIGxpc3QuXG4gICAgICAgICAgICBleGlzdGluZ0NoaWxkcmVuLmRlbGV0ZShfbmV3RmliZXI0LmtleSA9PT0gbnVsbCA/IG5ld0lkeCA6IF9uZXdGaWJlcjQua2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsYXN0UGxhY2VkSW5kZXggPSBwbGFjZUNoaWxkKF9uZXdGaWJlcjQsIGxhc3RQbGFjZWRJbmRleCwgbmV3SWR4KTtcblxuICAgICAgICBpZiAocHJldmlvdXNOZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIHJlc3VsdGluZ0ZpcnN0Q2hpbGQgPSBfbmV3RmliZXI0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IF9uZXdGaWJlcjQ7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2aW91c05ld0ZpYmVyID0gX25ld0ZpYmVyNDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgLy8gQW55IGV4aXN0aW5nIGNoaWxkcmVuIHRoYXQgd2VyZW4ndCBjb25zdW1lZCBhYm92ZSB3ZXJlIGRlbGV0ZWQuIFdlIG5lZWRcbiAgICAgIC8vIHRvIGFkZCB0aGVtIHRvIHRoZSBkZWxldGlvbiBsaXN0LlxuICAgICAgZXhpc3RpbmdDaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICByZXR1cm4gZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChnZXRJc0h5ZHJhdGluZygpKSB7XG4gICAgICB2YXIgX251bWJlck9mRm9ya3M0ID0gbmV3SWR4O1xuICAgICAgcHVzaFRyZWVGb3JrKHJldHVybkZpYmVyLCBfbnVtYmVyT2ZGb3JrczQpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVjb25jaWxlU2luZ2xlVGV4dE5vZGUocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCB0ZXh0Q29udGVudCwgbGFuZXMpIHtcbiAgICAvLyBUaGVyZSdzIG5vIG5lZWQgdG8gY2hlY2sgZm9yIGtleXMgb24gdGV4dCBub2RlcyBzaW5jZSB3ZSBkb24ndCBoYXZlIGFcbiAgICAvLyB3YXkgdG8gZGVmaW5lIHRoZW0uXG4gICAgaWYgKGN1cnJlbnRGaXJzdENoaWxkICE9PSBudWxsICYmIGN1cnJlbnRGaXJzdENoaWxkLnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICAgIC8vIFdlIGFscmVhZHkgaGF2ZSBhbiBleGlzdGluZyBub2RlIHNvIGxldCdzIGp1c3QgdXBkYXRlIGl0IGFuZCBkZWxldGVcbiAgICAgIC8vIHRoZSByZXN0LlxuICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLnNpYmxpbmcpO1xuICAgICAgdmFyIGV4aXN0aW5nID0gdXNlRmliZXIoY3VycmVudEZpcnN0Q2hpbGQsIHRleHRDb250ZW50KTtcbiAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgIH0gLy8gVGhlIGV4aXN0aW5nIGZpcnN0IGNoaWxkIGlzIG5vdCBhIHRleHQgbm9kZSBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBvbmVcbiAgICAvLyBhbmQgZGVsZXRlIHRoZSBleGlzdGluZyBvbmVzLlxuXG5cbiAgICBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQpO1xuICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tVGV4dCh0ZXh0Q29udGVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgcmV0dXJuIGNyZWF0ZWQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWNvbmNpbGVTaW5nbGVFbGVtZW50KHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgZWxlbWVudCwgbGFuZXMpIHtcbiAgICB2YXIga2V5ID0gZWxlbWVudC5rZXk7XG4gICAgdmFyIGNoaWxkID0gY3VycmVudEZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIC8vIFRPRE86IElmIGtleSA9PT0gbnVsbCBhbmQgY2hpbGQua2V5ID09PSBudWxsLCB0aGVuIHRoaXMgb25seSBhcHBsaWVzIHRvXG4gICAgICAvLyB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgbGlzdC5cbiAgICAgIGlmIChjaGlsZC5rZXkgPT09IGtleSkge1xuICAgICAgICB2YXIgZWxlbWVudFR5cGUgPSBlbGVtZW50LnR5cGU7XG5cbiAgICAgICAgaWYgKGVsZW1lbnRUeXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFKSB7XG4gICAgICAgICAgaWYgKGNoaWxkLnRhZyA9PT0gRnJhZ21lbnQpIHtcbiAgICAgICAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjaGlsZC5zaWJsaW5nKTtcbiAgICAgICAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGNoaWxkLCBlbGVtZW50LnByb3BzLmNoaWxkcmVuKTtcbiAgICAgICAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGV4aXN0aW5nLl9kZWJ1Z1NvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcbiAgICAgICAgICAgICAgZXhpc3RpbmcuX2RlYnVnT3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoY2hpbGQuZWxlbWVudFR5cGUgPT09IGVsZW1lbnRUeXBlIHx8ICggLy8gS2VlcCB0aGlzIGNoZWNrIGlubGluZSBzbyBpdCBvbmx5IHJ1bnMgb24gdGhlIGZhbHNlIHBhdGg6XG4gICAgICAgICAgIGlzQ29tcGF0aWJsZUZhbWlseUZvckhvdFJlbG9hZGluZyhjaGlsZCwgZWxlbWVudCkgKSB8fCAvLyBMYXp5IHR5cGVzIHNob3VsZCByZWNvbmNpbGUgdGhlaXIgcmVzb2x2ZWQgdHlwZS5cbiAgICAgICAgICAvLyBXZSBuZWVkIHRvIGRvIHRoaXMgYWZ0ZXIgdGhlIEhvdCBSZWxvYWRpbmcgY2hlY2sgYWJvdmUsXG4gICAgICAgICAgLy8gYmVjYXVzZSBob3QgcmVsb2FkaW5nIGhhcyBkaWZmZXJlbnQgc2VtYW50aWNzIHRoYW4gcHJvZCBiZWNhdXNlXG4gICAgICAgICAgLy8gaXQgZG9lc24ndCByZXN1c3BlbmQuIFNvIHdlIGNhbid0IGxldCB0aGUgY2FsbCBiZWxvdyBzdXNwZW5kLlxuICAgICAgICAgIHR5cGVvZiBlbGVtZW50VHlwZSA9PT0gJ29iamVjdCcgJiYgZWxlbWVudFR5cGUgIT09IG51bGwgJiYgZWxlbWVudFR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSAmJiByZXNvbHZlTGF6eShlbGVtZW50VHlwZSkgPT09IGNoaWxkLnR5cGUpIHtcbiAgICAgICAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjaGlsZC5zaWJsaW5nKTtcblxuICAgICAgICAgICAgdmFyIF9leGlzdGluZyA9IHVzZUZpYmVyKGNoaWxkLCBlbGVtZW50LnByb3BzKTtcblxuICAgICAgICAgICAgX2V4aXN0aW5nLnJlZiA9IGNvZXJjZVJlZihyZXR1cm5GaWJlciwgY2hpbGQsIGVsZW1lbnQpO1xuICAgICAgICAgICAgX2V4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIF9leGlzdGluZy5fZGVidWdTb3VyY2UgPSBlbGVtZW50Ll9zb3VyY2U7XG4gICAgICAgICAgICAgIF9leGlzdGluZy5fZGVidWdPd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gX2V4aXN0aW5nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSAvLyBEaWRuJ3QgbWF0Y2guXG5cblxuICAgICAgICBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZUNoaWxkKHJldHVybkZpYmVyLCBjaGlsZCk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgICB9XG5cbiAgICBpZiAoZWxlbWVudC50eXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFKSB7XG4gICAgICB2YXIgY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KGVsZW1lbnQucHJvcHMuY2hpbGRyZW4sIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzLCBlbGVtZW50LmtleSk7XG4gICAgICBjcmVhdGVkLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGNyZWF0ZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBfY3JlYXRlZDQgPSBjcmVhdGVGaWJlckZyb21FbGVtZW50KGVsZW1lbnQsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzKTtcblxuICAgICAgX2NyZWF0ZWQ0LnJlZiA9IGNvZXJjZVJlZihyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIGVsZW1lbnQpO1xuICAgICAgX2NyZWF0ZWQ0LnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIF9jcmVhdGVkNDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWNvbmNpbGVTaW5nbGVQb3J0YWwocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBwb3J0YWwsIGxhbmVzKSB7XG4gICAgdmFyIGtleSA9IHBvcnRhbC5rZXk7XG4gICAgdmFyIGNoaWxkID0gY3VycmVudEZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIC8vIFRPRE86IElmIGtleSA9PT0gbnVsbCBhbmQgY2hpbGQua2V5ID09PSBudWxsLCB0aGVuIHRoaXMgb25seSBhcHBsaWVzIHRvXG4gICAgICAvLyB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgbGlzdC5cbiAgICAgIGlmIChjaGlsZC5rZXkgPT09IGtleSkge1xuICAgICAgICBpZiAoY2hpbGQudGFnID09PSBIb3N0UG9ydGFsICYmIGNoaWxkLnN0YXRlTm9kZS5jb250YWluZXJJbmZvID09PSBwb3J0YWwuY29udGFpbmVySW5mbyAmJiBjaGlsZC5zdGF0ZU5vZGUuaW1wbGVtZW50YXRpb24gPT09IHBvcnRhbC5pbXBsZW1lbnRhdGlvbikge1xuICAgICAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjaGlsZC5zaWJsaW5nKTtcbiAgICAgICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjaGlsZCwgcG9ydGFsLmNoaWxkcmVuIHx8IFtdKTtcbiAgICAgICAgICBleGlzdGluZy5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkKTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgIH1cblxuICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tUG9ydGFsKHBvcnRhbCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgcmV0dXJuIGNyZWF0ZWQ7XG4gIH0gLy8gVGhpcyBBUEkgd2lsbCB0YWcgdGhlIGNoaWxkcmVuIHdpdGggdGhlIHNpZGUtZWZmZWN0IG9mIHRoZSByZWNvbmNpbGlhdGlvblxuICAvLyBpdHNlbGYuIFRoZXkgd2lsbCBiZSBhZGRlZCB0byB0aGUgc2lkZS1lZmZlY3QgbGlzdCBhcyB3ZSBwYXNzIHRocm91Z2ggdGhlXG4gIC8vIGNoaWxkcmVuIGFuZCB0aGUgcGFyZW50LlxuXG5cbiAgZnVuY3Rpb24gcmVjb25jaWxlQ2hpbGRGaWJlcnMocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZCwgbGFuZXMpIHtcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG5vdCByZWN1cnNpdmUuXG4gICAgLy8gSWYgdGhlIHRvcCBsZXZlbCBpdGVtIGlzIGFuIGFycmF5LCB3ZSB0cmVhdCBpdCBhcyBhIHNldCBvZiBjaGlsZHJlbixcbiAgICAvLyBub3QgYXMgYSBmcmFnbWVudC4gTmVzdGVkIGFycmF5cyBvbiB0aGUgb3RoZXIgaGFuZCB3aWxsIGJlIHRyZWF0ZWQgYXNcbiAgICAvLyBmcmFnbWVudCBub2Rlcy4gUmVjdXJzaW9uIGhhcHBlbnMgYXQgdGhlIG5vcm1hbCBmbG93LlxuICAgIC8vIEhhbmRsZSB0b3AgbGV2ZWwgdW5rZXllZCBmcmFnbWVudHMgYXMgaWYgdGhleSB3ZXJlIGFycmF5cy5cbiAgICAvLyBUaGlzIGxlYWRzIHRvIGFuIGFtYmlndWl0eSBiZXR3ZWVuIDw+e1suLi5dfTwvPiBhbmQgPD4uLi48Lz4uXG4gICAgLy8gV2UgdHJlYXQgdGhlIGFtYmlndW91cyBjYXNlcyBhYm92ZSB0aGUgc2FtZS5cbiAgICB2YXIgaXNVbmtleWVkVG9wTGV2ZWxGcmFnbWVudCA9IHR5cGVvZiBuZXdDaGlsZCA9PT0gJ29iamVjdCcgJiYgbmV3Q2hpbGQgIT09IG51bGwgJiYgbmV3Q2hpbGQudHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSAmJiBuZXdDaGlsZC5rZXkgPT09IG51bGw7XG5cbiAgICBpZiAoaXNVbmtleWVkVG9wTGV2ZWxGcmFnbWVudCkge1xuICAgICAgbmV3Q2hpbGQgPSBuZXdDaGlsZC5wcm9wcy5jaGlsZHJlbjtcbiAgICB9IC8vIEhhbmRsZSBvYmplY3QgdHlwZXNcblxuXG4gICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ29iamVjdCcgJiYgbmV3Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIHN3aXRjaCAobmV3Q2hpbGQuJCR0eXBlb2YpIHtcbiAgICAgICAgY2FzZSBSRUFDVF9FTEVNRU5UX1RZUEU6XG4gICAgICAgICAgcmV0dXJuIHBsYWNlU2luZ2xlQ2hpbGQocmVjb25jaWxlU2luZ2xlRWxlbWVudChyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIG5ld0NoaWxkLCBsYW5lcykpO1xuXG4gICAgICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICAgICAgcmV0dXJuIHBsYWNlU2luZ2xlQ2hpbGQocmVjb25jaWxlU2luZ2xlUG9ydGFsKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKSk7XG5cbiAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBuZXdDaGlsZC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IG5ld0NoaWxkLl9pbml0OyAvLyBUT0RPOiBUaGlzIGZ1bmN0aW9uIGlzIHN1cHBvc2VkIHRvIGJlIG5vbi1yZWN1cnNpdmUuXG5cbiAgICAgICAgICByZXR1cm4gcmVjb25jaWxlQ2hpbGRGaWJlcnMocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBpbml0KHBheWxvYWQpLCBsYW5lcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KG5ld0NoaWxkKSkge1xuICAgICAgICByZXR1cm4gcmVjb25jaWxlQ2hpbGRyZW5BcnJheShyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChnZXRJdGVyYXRvckZuKG5ld0NoaWxkKSkge1xuICAgICAgICByZXR1cm4gcmVjb25jaWxlQ2hpbGRyZW5JdGVyYXRvcihyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICB9XG5cbiAgICAgIHRocm93T25JbnZhbGlkT2JqZWN0VHlwZShyZXR1cm5GaWJlciwgbmV3Q2hpbGQpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnICYmIG5ld0NoaWxkICE9PSAnJyB8fCB0eXBlb2YgbmV3Q2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gcGxhY2VTaW5nbGVDaGlsZChyZWNvbmNpbGVTaW5nbGVUZXh0Tm9kZShyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsICcnICsgbmV3Q2hpbGQsIGxhbmVzKSk7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB3YXJuT25GdW5jdGlvblR5cGUocmV0dXJuRmliZXIpO1xuICAgICAgfVxuICAgIH0gLy8gUmVtYWluaW5nIGNhc2VzIGFyZSBhbGwgdHJlYXRlZCBhcyBlbXB0eS5cblxuXG4gICAgcmV0dXJuIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCk7XG4gIH1cblxuICByZXR1cm4gcmVjb25jaWxlQ2hpbGRGaWJlcnM7XG59XG5cbnZhciByZWNvbmNpbGVDaGlsZEZpYmVycyA9IENoaWxkUmVjb25jaWxlcih0cnVlKTtcbnZhciBtb3VudENoaWxkRmliZXJzID0gQ2hpbGRSZWNvbmNpbGVyKGZhbHNlKTtcbmZ1bmN0aW9uIGNsb25lQ2hpbGRGaWJlcnMoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpIHtcbiAgaWYgKGN1cnJlbnQgIT09IG51bGwgJiYgd29ya0luUHJvZ3Jlc3MuY2hpbGQgIT09IGN1cnJlbnQuY2hpbGQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc3VtaW5nIHdvcmsgbm90IHlldCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9PT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjdXJyZW50Q2hpbGQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgdmFyIG5ld0NoaWxkID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoY3VycmVudENoaWxkLCBjdXJyZW50Q2hpbGQucGVuZGluZ1Byb3BzKTtcbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBuZXdDaGlsZDtcbiAgbmV3Q2hpbGQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG5cbiAgd2hpbGUgKGN1cnJlbnRDaGlsZC5zaWJsaW5nICE9PSBudWxsKSB7XG4gICAgY3VycmVudENoaWxkID0gY3VycmVudENoaWxkLnNpYmxpbmc7XG4gICAgbmV3Q2hpbGQgPSBuZXdDaGlsZC5zaWJsaW5nID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoY3VycmVudENoaWxkLCBjdXJyZW50Q2hpbGQucGVuZGluZ1Byb3BzKTtcbiAgICBuZXdDaGlsZC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgfVxuXG4gIG5ld0NoaWxkLnNpYmxpbmcgPSBudWxsO1xufSAvLyBSZXNldCBhIHdvcmtJblByb2dyZXNzIGNoaWxkIHNldCB0byBwcmVwYXJlIGl0IGZvciBhIHNlY29uZCBwYXNzLlxuXG5mdW5jdGlvbiByZXNldENoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBsYW5lcykge1xuICB2YXIgY2hpbGQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICByZXNldFdvcmtJblByb2dyZXNzKGNoaWxkLCBsYW5lcyk7XG4gICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICB9XG59XG5cbnZhciBOT19DT05URVhUID0ge307XG52YXIgY29udGV4dFN0YWNrQ3Vyc29yJDEgPSBjcmVhdGVDdXJzb3IoTk9fQ09OVEVYVCk7XG52YXIgY29udGV4dEZpYmVyU3RhY2tDdXJzb3IgPSBjcmVhdGVDdXJzb3IoTk9fQ09OVEVYVCk7XG52YXIgcm9vdEluc3RhbmNlU3RhY2tDdXJzb3IgPSBjcmVhdGVDdXJzb3IoTk9fQ09OVEVYVCk7XG5cbmZ1bmN0aW9uIHJlcXVpcmVkQ29udGV4dChjKSB7XG4gIGlmIChjID09PSBOT19DT05URVhUKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBob3N0IGNvbnRleHQgdG8gZXhpc3QuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyAnICsgJ2luIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHJldHVybiBjO1xufVxuXG5mdW5jdGlvbiBnZXRSb290SG9zdENvbnRhaW5lcigpIHtcbiAgdmFyIHJvb3RJbnN0YW5jZSA9IHJlcXVpcmVkQ29udGV4dChyb290SW5zdGFuY2VTdGFja0N1cnNvci5jdXJyZW50KTtcbiAgcmV0dXJuIHJvb3RJbnN0YW5jZTtcbn1cblxuZnVuY3Rpb24gcHVzaEhvc3RDb250YWluZXIoZmliZXIsIG5leHRSb290SW5zdGFuY2UpIHtcbiAgLy8gUHVzaCBjdXJyZW50IHJvb3QgaW5zdGFuY2Ugb250byB0aGUgc3RhY2s7XG4gIC8vIFRoaXMgYWxsb3dzIHVzIHRvIHJlc2V0IHJvb3Qgd2hlbiBwb3J0YWxzIGFyZSBwb3BwZWQuXG4gIHB1c2gocm9vdEluc3RhbmNlU3RhY2tDdXJzb3IsIG5leHRSb290SW5zdGFuY2UsIGZpYmVyKTsgLy8gVHJhY2sgdGhlIGNvbnRleHQgYW5kIHRoZSBGaWJlciB0aGF0IHByb3ZpZGVkIGl0LlxuICAvLyBUaGlzIGVuYWJsZXMgdXMgdG8gcG9wIG9ubHkgRmliZXJzIHRoYXQgcHJvdmlkZSB1bmlxdWUgY29udGV4dHMuXG5cbiAgcHVzaChjb250ZXh0RmliZXJTdGFja0N1cnNvciwgZmliZXIsIGZpYmVyKTsgLy8gRmluYWxseSwgd2UgbmVlZCB0byBwdXNoIHRoZSBob3N0IGNvbnRleHQgdG8gdGhlIHN0YWNrLlxuICAvLyBIb3dldmVyLCB3ZSBjYW4ndCBqdXN0IGNhbGwgZ2V0Um9vdEhvc3RDb250ZXh0KCkgYW5kIHB1c2ggaXQgYmVjYXVzZVxuICAvLyB3ZSdkIGhhdmUgYSBkaWZmZXJlbnQgbnVtYmVyIG9mIGVudHJpZXMgb24gdGhlIHN0YWNrIGRlcGVuZGluZyBvblxuICAvLyB3aGV0aGVyIGdldFJvb3RIb3N0Q29udGV4dCgpIHRocm93cyBzb21ld2hlcmUgaW4gcmVuZGVyZXIgY29kZSBvciBub3QuXG4gIC8vIFNvIHdlIHB1c2ggYW4gZW1wdHkgdmFsdWUgZmlyc3QuIFRoaXMgbGV0cyB1cyBzYWZlbHkgdW53aW5kIG9uIGVycm9ycy5cblxuICBwdXNoKGNvbnRleHRTdGFja0N1cnNvciQxLCBOT19DT05URVhULCBmaWJlcik7XG4gIHZhciBuZXh0Um9vdENvbnRleHQgPSBnZXRSb290SG9zdENvbnRleHQobmV4dFJvb3RJbnN0YW5jZSk7IC8vIE5vdyB0aGF0IHdlIGtub3cgdGhpcyBmdW5jdGlvbiBkb2Vzbid0IHRocm93LCByZXBsYWNlIGl0LlxuXG4gIHBvcChjb250ZXh0U3RhY2tDdXJzb3IkMSwgZmliZXIpO1xuICBwdXNoKGNvbnRleHRTdGFja0N1cnNvciQxLCBuZXh0Um9vdENvbnRleHQsIGZpYmVyKTtcbn1cblxuZnVuY3Rpb24gcG9wSG9zdENvbnRhaW5lcihmaWJlcikge1xuICBwb3AoY29udGV4dFN0YWNrQ3Vyc29yJDEsIGZpYmVyKTtcbiAgcG9wKGNvbnRleHRGaWJlclN0YWNrQ3Vyc29yLCBmaWJlcik7XG4gIHBvcChyb290SW5zdGFuY2VTdGFja0N1cnNvciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBnZXRIb3N0Q29udGV4dCgpIHtcbiAgdmFyIGNvbnRleHQgPSByZXF1aXJlZENvbnRleHQoY29udGV4dFN0YWNrQ3Vyc29yJDEuY3VycmVudCk7XG4gIHJldHVybiBjb250ZXh0O1xufVxuXG5mdW5jdGlvbiBwdXNoSG9zdENvbnRleHQoZmliZXIpIHtcbiAgdmFyIHJvb3RJbnN0YW5jZSA9IHJlcXVpcmVkQ29udGV4dChyb290SW5zdGFuY2VTdGFja0N1cnNvci5jdXJyZW50KTtcbiAgdmFyIGNvbnRleHQgPSByZXF1aXJlZENvbnRleHQoY29udGV4dFN0YWNrQ3Vyc29yJDEuY3VycmVudCk7XG4gIHZhciBuZXh0Q29udGV4dCA9IGdldENoaWxkSG9zdENvbnRleHQoY29udGV4dCwgZmliZXIudHlwZSk7IC8vIERvbid0IHB1c2ggdGhpcyBGaWJlcidzIGNvbnRleHQgdW5sZXNzIGl0J3MgdW5pcXVlLlxuXG4gIGlmIChjb250ZXh0ID09PSBuZXh0Q29udGV4dCkge1xuICAgIHJldHVybjtcbiAgfSAvLyBUcmFjayB0aGUgY29udGV4dCBhbmQgdGhlIEZpYmVyIHRoYXQgcHJvdmlkZWQgaXQuXG4gIC8vIFRoaXMgZW5hYmxlcyB1cyB0byBwb3Agb25seSBGaWJlcnMgdGhhdCBwcm92aWRlIHVuaXF1ZSBjb250ZXh0cy5cblxuXG4gIHB1c2goY29udGV4dEZpYmVyU3RhY2tDdXJzb3IsIGZpYmVyLCBmaWJlcik7XG4gIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yJDEsIG5leHRDb250ZXh0LCBmaWJlcik7XG59XG5cbmZ1bmN0aW9uIHBvcEhvc3RDb250ZXh0KGZpYmVyKSB7XG4gIC8vIERvIG5vdCBwb3AgdW5sZXNzIHRoaXMgRmliZXIgcHJvdmlkZWQgdGhlIGN1cnJlbnQgY29udGV4dC5cbiAgLy8gcHVzaEhvc3RDb250ZXh0KCkgb25seSBwdXNoZXMgRmliZXJzIHRoYXQgcHJvdmlkZSB1bmlxdWUgY29udGV4dHMuXG4gIGlmIChjb250ZXh0RmliZXJTdGFja0N1cnNvci5jdXJyZW50ICE9PSBmaWJlcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHBvcChjb250ZXh0U3RhY2tDdXJzb3IkMSwgZmliZXIpO1xuICBwb3AoY29udGV4dEZpYmVyU3RhY2tDdXJzb3IsIGZpYmVyKTtcbn1cblxudmFyIERlZmF1bHRTdXNwZW5zZUNvbnRleHQgPSAwOyAvLyBUaGUgU3VzcGVuc2UgQ29udGV4dCBpcyBzcGxpdCBpbnRvIHR3byBwYXJ0cy4gVGhlIGxvd2VyIGJpdHMgaXNcbi8vIGluaGVyaXRlZCBkZWVwbHkgZG93biB0aGUgc3VidHJlZS4gVGhlIHVwcGVyIGJpdHMgb25seSBhZmZlY3Rcbi8vIHRoaXMgaW1tZWRpYXRlIHN1c3BlbnNlIGJvdW5kYXJ5IGFuZCBnZXRzIHJlc2V0IGVhY2ggbmV3XG4vLyBib3VuZGFyeSBvciBzdXNwZW5zZSBsaXN0LlxuXG52YXIgU3VidHJlZVN1c3BlbnNlQ29udGV4dE1hc2sgPSAxOyAvLyBTdWJ0cmVlIEZsYWdzOlxuLy8gSW52aXNpYmxlUGFyZW50U3VzcGVuc2VDb250ZXh0IGluZGljYXRlcyB0aGF0IG9uZSBvZiBvdXIgcGFyZW50IFN1c3BlbnNlXG4vLyBib3VuZGFyaWVzIGlzIG5vdCBjdXJyZW50bHkgc2hvd2luZyB2aXNpYmxlIG1haW4gY29udGVudC5cbi8vIEVpdGhlciBiZWNhdXNlIGl0IGlzIGFscmVhZHkgc2hvd2luZyBhIGZhbGxiYWNrIG9yIGlzIG5vdCBtb3VudGVkIGF0IGFsbC5cbi8vIFdlIGNhbiB1c2UgdGhpcyB0byBkZXRlcm1pbmUgaWYgaXQgaXMgZGVzaXJhYmxlIHRvIHRyaWdnZXIgYSBmYWxsYmFjayBhdFxuLy8gdGhlIHBhcmVudC4gSWYgbm90LCB0aGVuIHdlIG1pZ2h0IG5lZWQgdG8gdHJpZ2dlciB1bmRlc2lyYWJsZSBib3VuZGFyaWVzXG4vLyBhbmQvb3Igc3VzcGVuZCB0aGUgY29tbWl0IHRvIGF2b2lkIGhpZGluZyB0aGUgcGFyZW50IGNvbnRlbnQuXG5cbnZhciBJbnZpc2libGVQYXJlbnRTdXNwZW5zZUNvbnRleHQgPSAxOyAvLyBTaGFsbG93IEZsYWdzOlxuLy8gRm9yY2VTdXNwZW5zZUZhbGxiYWNrIGNhbiBiZSB1c2VkIGJ5IFN1c3BlbnNlTGlzdCB0byBmb3JjZSBuZXdseSBhZGRlZFxuLy8gaXRlbXMgaW50byB0aGVpciBmYWxsYmFjayBzdGF0ZSBkdXJpbmcgb25lIG9mIHRoZSByZW5kZXIgcGFzc2VzLlxuXG52YXIgRm9yY2VTdXNwZW5zZUZhbGxiYWNrID0gMjtcbnZhciBzdXNwZW5zZVN0YWNrQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKERlZmF1bHRTdXNwZW5zZUNvbnRleHQpO1xuZnVuY3Rpb24gaGFzU3VzcGVuc2VDb250ZXh0KHBhcmVudENvbnRleHQsIGZsYWcpIHtcbiAgcmV0dXJuIChwYXJlbnRDb250ZXh0ICYgZmxhZykgIT09IDA7XG59XG5mdW5jdGlvbiBzZXREZWZhdWx0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChwYXJlbnRDb250ZXh0KSB7XG4gIHJldHVybiBwYXJlbnRDb250ZXh0ICYgU3VidHJlZVN1c3BlbnNlQ29udGV4dE1hc2s7XG59XG5mdW5jdGlvbiBzZXRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHBhcmVudENvbnRleHQsIHNoYWxsb3dDb250ZXh0KSB7XG4gIHJldHVybiBwYXJlbnRDb250ZXh0ICYgU3VidHJlZVN1c3BlbnNlQ29udGV4dE1hc2sgfCBzaGFsbG93Q29udGV4dDtcbn1cbmZ1bmN0aW9uIGFkZFN1YnRyZWVTdXNwZW5zZUNvbnRleHQocGFyZW50Q29udGV4dCwgc3VidHJlZUNvbnRleHQpIHtcbiAgcmV0dXJuIHBhcmVudENvbnRleHQgfCBzdWJ0cmVlQ29udGV4dDtcbn1cbmZ1bmN0aW9uIHB1c2hTdXNwZW5zZUNvbnRleHQoZmliZXIsIG5ld0NvbnRleHQpIHtcbiAgcHVzaChzdXNwZW5zZVN0YWNrQ3Vyc29yLCBuZXdDb250ZXh0LCBmaWJlcik7XG59XG5mdW5jdGlvbiBwb3BTdXNwZW5zZUNvbnRleHQoZmliZXIpIHtcbiAgcG9wKHN1c3BlbnNlU3RhY2tDdXJzb3IsIGZpYmVyKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkQ2FwdHVyZVN1c3BlbnNlKHdvcmtJblByb2dyZXNzLCBoYXNJbnZpc2libGVQYXJlbnQpIHtcbiAgLy8gSWYgaXQgd2FzIHRoZSBwcmltYXJ5IGNoaWxkcmVuIHRoYXQganVzdCBzdXNwZW5kZWQsIGNhcHR1cmUgYW5kIHJlbmRlciB0aGVcbiAgLy8gZmFsbGJhY2suIE90aGVyd2lzZSwgZG9uJ3QgY2FwdHVyZSBhbmQgYnViYmxlIHRvIHRoZSBuZXh0IGJvdW5kYXJ5LlxuICB2YXIgbmV4dFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAobmV4dFN0YXRlICE9PSBudWxsKSB7XG4gICAgaWYgKG5leHRTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgICAvLyBBIGRlaHlkcmF0ZWQgYm91bmRhcnkgYWx3YXlzIGNhcHR1cmVzLlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHByb3BzID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wczsgLy8gUmVndWxhciBib3VuZGFyaWVzIGFsd2F5cyBjYXB0dXJlLlxuXG4gIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSAvLyBJZiBpdCdzIGEgYm91bmRhcnkgd2Ugc2hvdWxkIGF2b2lkLCB0aGVuIHdlIHByZWZlciB0byBidWJibGUgdXAgdG8gdGhlXG59XG5mdW5jdGlvbiBmaW5kRmlyc3RTdXNwZW5kZWQocm93KSB7XG4gIHZhciBub2RlID0gcm93O1xuXG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgaWYgKG5vZGUudGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgICAgdmFyIHN0YXRlID0gbm9kZS5tZW1vaXplZFN0YXRlO1xuXG4gICAgICBpZiAoc3RhdGUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIGRlaHlkcmF0ZWQgPSBzdGF0ZS5kZWh5ZHJhdGVkO1xuXG4gICAgICAgIGlmIChkZWh5ZHJhdGVkID09PSBudWxsIHx8IGlzU3VzcGVuc2VJbnN0YW5jZVBlbmRpbmcoZGVoeWRyYXRlZCkgfHwgaXNTdXNwZW5zZUluc3RhbmNlRmFsbGJhY2soZGVoeWRyYXRlZCkpIHtcbiAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlTGlzdENvbXBvbmVudCAmJiAvLyByZXZlYWxPcmRlciB1bmRlZmluZWQgY2FuJ3QgYmUgdHJ1c3RlZCBiZWNhdXNlIGl0IGRvbid0XG4gICAgLy8ga2VlcCB0cmFjayBvZiB3aGV0aGVyIGl0IHN1c3BlbmRlZCBvciBub3QuXG4gICAgbm9kZS5tZW1vaXplZFByb3BzLnJldmVhbE9yZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBkaWRTdXNwZW5kID0gKG5vZGUuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICAgICAgaWYgKGRpZFN1c3BlbmQpIHtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChub2RlLmNoaWxkICE9PSBudWxsKSB7XG4gICAgICBub2RlLmNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICBub2RlID0gbm9kZS5jaGlsZDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChub2RlID09PSByb3cpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBub2RlLnJldHVybiA9PT0gcm93KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5zaWJsaW5nLnJldHVybiA9IG5vZGUucmV0dXJuO1xuICAgIG5vZGUgPSBub2RlLnNpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxudmFyIE5vRmxhZ3MkMSA9XG4vKiAgICovXG4wOyAvLyBSZXByZXNlbnRzIHdoZXRoZXIgZWZmZWN0IHNob3VsZCBmaXJlLlxuXG52YXIgSGFzRWZmZWN0ID1cbi8qICovXG4xOyAvLyBSZXByZXNlbnRzIHRoZSBwaGFzZSBpbiB3aGljaCB0aGUgZWZmZWN0IChub3QgdGhlIGNsZWFuLXVwKSBmaXJlcy5cblxudmFyIEluc2VydGlvbiA9XG4vKiAgKi9cbjI7XG52YXIgTGF5b3V0ID1cbi8qICAgICovXG40O1xudmFyIFBhc3NpdmUkMSA9XG4vKiAgICovXG44O1xuXG4vLyBhbmQgc2hvdWxkIGJlIHJlc2V0IGJlZm9yZSBzdGFydGluZyBhIG5ldyByZW5kZXIuXG4vLyBUaGlzIHRyYWNrcyB3aGljaCBtdXRhYmxlIHNvdXJjZXMgbmVlZCB0byBiZSByZXNldCBhZnRlciBhIHJlbmRlci5cblxudmFyIHdvcmtJblByb2dyZXNzU291cmNlcyA9IFtdO1xuZnVuY3Rpb24gcmVzZXRXb3JrSW5Qcm9ncmVzc1ZlcnNpb25zKCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHdvcmtJblByb2dyZXNzU291cmNlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBtdXRhYmxlU291cmNlID0gd29ya0luUHJvZ3Jlc3NTb3VyY2VzW2ldO1xuXG4gICAge1xuICAgICAgbXV0YWJsZVNvdXJjZS5fd29ya0luUHJvZ3Jlc3NWZXJzaW9uUHJpbWFyeSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgd29ya0luUHJvZ3Jlc3NTb3VyY2VzLmxlbmd0aCA9IDA7XG59XG4vLyBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgdmVyc2lvbiB1c2VkIGZvciBzZXJ2ZXIgcmVuZGVyaW5nIG1hdGNoZXMgdGhlIG9uZVxuLy8gdGhhdCBpcyBldmVudHVhbGx5IHJlYWQgZHVyaW5nIGh5ZHJhdGlvbi5cbi8vIElmIHRoZXkgZG9uJ3QgbWF0Y2ggdGhlcmUncyBhIHBvdGVudGlhbCB0ZWFyIGFuZCBhIGZ1bGwgZGVvcHQgcmVuZGVyIGlzIHJlcXVpcmVkLlxuXG5mdW5jdGlvbiByZWdpc3Rlck11dGFibGVTb3VyY2VGb3JIeWRyYXRpb24ocm9vdCwgbXV0YWJsZVNvdXJjZSkge1xuICB2YXIgZ2V0VmVyc2lvbiA9IG11dGFibGVTb3VyY2UuX2dldFZlcnNpb247XG4gIHZhciB2ZXJzaW9uID0gZ2V0VmVyc2lvbihtdXRhYmxlU291cmNlLl9zb3VyY2UpOyAvLyBUT0RPIENsZWFyIHRoaXMgZGF0YSBvbmNlIGFsbCBwZW5kaW5nIGh5ZHJhdGlvbiB3b3JrIGlzIGZpbmlzaGVkLlxuICAvLyBSZXRhaW5pbmcgaXQgZm9yZXZlciBtYXkgaW50ZXJmZXJlIHdpdGggR0MuXG5cbiAgaWYgKHJvb3QubXV0YWJsZVNvdXJjZUVhZ2VySHlkcmF0aW9uRGF0YSA9PSBudWxsKSB7XG4gICAgcm9vdC5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhID0gW211dGFibGVTb3VyY2UsIHZlcnNpb25dO1xuICB9IGVsc2Uge1xuICAgIHJvb3QubXV0YWJsZVNvdXJjZUVhZ2VySHlkcmF0aW9uRGF0YS5wdXNoKG11dGFibGVTb3VyY2UsIHZlcnNpb24pO1xuICB9XG59XG5cbnZhciBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnREaXNwYXRjaGVyLFxuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZztcbnZhciBkaWRXYXJuQWJvdXRNaXNtYXRjaGVkSG9va3NGb3JDb21wb25lbnQ7XG52YXIgZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3Q7XG5cbntcbiAgZGlkV2FybkFib3V0TWlzbWF0Y2hlZEhvb2tzRm9yQ29tcG9uZW50ID0gbmV3IFNldCgpO1xufVxuXG4vLyBUaGVzZSBhcmUgc2V0IHJpZ2h0IGJlZm9yZSBjYWxsaW5nIHRoZSBjb21wb25lbnQuXG52YXIgcmVuZGVyTGFuZXMgPSBOb0xhbmVzOyAvLyBUaGUgd29yay1pbi1wcm9ncmVzcyBmaWJlci4gSSd2ZSBuYW1lZCBpdCBkaWZmZXJlbnRseSB0byBkaXN0aW5ndWlzaCBpdCBmcm9tXG4vLyB0aGUgd29yay1pbi1wcm9ncmVzcyBob29rLlxuXG52YXIgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSA9IG51bGw7IC8vIEhvb2tzIGFyZSBzdG9yZWQgYXMgYSBsaW5rZWQgbGlzdCBvbiB0aGUgZmliZXIncyBtZW1vaXplZFN0YXRlIGZpZWxkLiBUaGVcbi8vIGN1cnJlbnQgaG9vayBsaXN0IGlzIHRoZSBsaXN0IHRoYXQgYmVsb25ncyB0byB0aGUgY3VycmVudCBmaWJlci4gVGhlXG4vLyB3b3JrLWluLXByb2dyZXNzIGhvb2sgbGlzdCBpcyBhIG5ldyBsaXN0IHRoYXQgd2lsbCBiZSBhZGRlZCB0byB0aGVcbi8vIHdvcmstaW4tcHJvZ3Jlc3MgZmliZXIuXG5cbnZhciBjdXJyZW50SG9vayA9IG51bGw7XG52YXIgd29ya0luUHJvZ3Jlc3NIb29rID0gbnVsbDsgLy8gV2hldGhlciBhbiB1cGRhdGUgd2FzIHNjaGVkdWxlZCBhdCBhbnkgcG9pbnQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuIFRoaXNcbi8vIGRvZXMgbm90IGdldCByZXNldCBpZiB3ZSBkbyBhbm90aGVyIHJlbmRlciBwYXNzOyBvbmx5IHdoZW4gd2UncmUgY29tcGxldGVseVxuLy8gZmluaXNoZWQgZXZhbHVhdGluZyB0aGlzIGNvbXBvbmVudC4gVGhpcyBpcyBhbiBvcHRpbWl6YXRpb24gc28gd2Uga25vd1xuLy8gd2hldGhlciB3ZSBuZWVkIHRvIGNsZWFyIHJlbmRlciBwaGFzZSB1cGRhdGVzIGFmdGVyIGEgdGhyb3cuXG5cbnZhciBkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlID0gZmFsc2U7IC8vIFdoZXJlIGFuIHVwZGF0ZSB3YXMgc2NoZWR1bGVkIG9ubHkgZHVyaW5nIHRoZSBjdXJyZW50IHJlbmRlciBwYXNzLiBUaGlzXG4vLyBnZXRzIHJlc2V0IGFmdGVyIGVhY2ggYXR0ZW1wdC5cbi8vIFRPRE86IE1heWJlIHRoZXJlJ3Mgc29tZSB3YXkgdG8gY29uc29saWRhdGUgdGhpcyB3aXRoXG4vLyBgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZWAuIE9yIHdpdGggYG51bWJlck9mUmVSZW5kZXJzYC5cblxudmFyIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGZhbHNlOyAvLyBDb3VudHMgdGhlIG51bWJlciBvZiB1c2VJZCBob29rcyBpbiB0aGlzIGNvbXBvbmVudC5cblxudmFyIGxvY2FsSWRDb3VudGVyID0gMDsgLy8gVXNlZCBmb3IgaWRzIHRoYXQgYXJlIGdlbmVyYXRlZCBjb21wbGV0ZWx5IGNsaWVudC1zaWRlIChpLmUuIG5vdCBkdXJpbmdcbi8vIGh5ZHJhdGlvbikuIFRoaXMgY291bnRlciBpcyBnbG9iYWwsIHNvIGNsaWVudCBpZHMgYXJlIG5vdCBzdGFibGUgYWNyb3NzXG4vLyByZW5kZXIgYXR0ZW1wdHMuXG5cbnZhciBnbG9iYWxDbGllbnRJZENvdW50ZXIgPSAwO1xudmFyIFJFX1JFTkRFUl9MSU1JVCA9IDI1OyAvLyBJbiBERVYsIHRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIGN1cnJlbnRseSBleGVjdXRpbmcgcHJpbWl0aXZlIGhvb2tcblxudmFyIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gbnVsbDsgLy8gSW4gREVWLCB0aGlzIGxpc3QgZW5zdXJlcyB0aGF0IGhvb2tzIGFyZSBjYWxsZWQgaW4gdGhlIHNhbWUgb3JkZXIgYmV0d2VlbiByZW5kZXJzLlxuLy8gVGhlIGxpc3Qgc3RvcmVzIHRoZSBvcmRlciBvZiBob29rcyB1c2VkIGR1cmluZyB0aGUgaW5pdGlhbCByZW5kZXIgKG1vdW50KS5cbi8vIFN1YnNlcXVlbnQgcmVuZGVycyAodXBkYXRlcykgcmVmZXJlbmNlIHRoaXMgbGlzdC5cblxudmFyIGhvb2tUeXBlc0RldiA9IG51bGw7XG52YXIgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTsgLy8gSW4gREVWLCB0aGlzIHRyYWNrcyB3aGV0aGVyIGN1cnJlbnRseSByZW5kZXJpbmcgY29tcG9uZW50IG5lZWRzIHRvIGlnbm9yZVxuLy8gdGhlIGRlcGVuZGVuY2llcyBmb3IgSG9va3MgdGhhdCBuZWVkIHRoZW0gKGUuZy4gdXNlRWZmZWN0IG9yIHVzZU1lbW8pLlxuLy8gV2hlbiB0cnVlLCBzdWNoIEhvb2tzIHdpbGwgYWx3YXlzIGJlIFwicmVtb3VudGVkXCIuIE9ubHkgdXNlZCBkdXJpbmcgaG90IHJlbG9hZC5cblxudmFyIGlnbm9yZVByZXZpb3VzRGVwZW5kZW5jaWVzID0gZmFsc2U7XG5cbmZ1bmN0aW9uIG1vdW50SG9va1R5cGVzRGV2KCkge1xuICB7XG4gICAgdmFyIGhvb2tOYW1lID0gY3VycmVudEhvb2tOYW1lSW5EZXY7XG5cbiAgICBpZiAoaG9va1R5cGVzRGV2ID09PSBudWxsKSB7XG4gICAgICBob29rVHlwZXNEZXYgPSBbaG9va05hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBob29rVHlwZXNEZXYucHVzaChob29rTmFtZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUhvb2tUeXBlc0RldigpIHtcbiAge1xuICAgIHZhciBob29rTmFtZSA9IGN1cnJlbnRIb29rTmFtZUluRGV2O1xuXG4gICAgaWYgKGhvb2tUeXBlc0RldiAhPT0gbnVsbCkge1xuICAgICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYrKztcblxuICAgICAgaWYgKGhvb2tUeXBlc0Rldltob29rVHlwZXNVcGRhdGVJbmRleERldl0gIT09IGhvb2tOYW1lKSB7XG4gICAgICAgIHdhcm5Pbkhvb2tNaXNtYXRjaEluRGV2KGhvb2tOYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcykge1xuICB7XG4gICAgaWYgKGRlcHMgIT09IHVuZGVmaW5lZCAmJiBkZXBzICE9PSBudWxsICYmICFpc0FycmF5KGRlcHMpKSB7XG4gICAgICAvLyBWZXJpZnkgZGVwcywgYnV0IG9ubHkgb24gbW91bnQgdG8gYXZvaWQgZXh0cmEgY2hlY2tzLlxuICAgICAgLy8gSXQncyB1bmxpa2VseSB0aGVpciB0eXBlIHdvdWxkIGNoYW5nZSBhcyB1c3VhbGx5IHlvdSBkZWZpbmUgdGhlbSBpbmxpbmUuXG4gICAgICBlcnJvcignJXMgcmVjZWl2ZWQgYSBmaW5hbCBhcmd1bWVudCB0aGF0IGlzIG5vdCBhbiBhcnJheSAoaW5zdGVhZCwgcmVjZWl2ZWQgYCVzYCkuIFdoZW4gJyArICdzcGVjaWZpZWQsIHRoZSBmaW5hbCBhcmd1bWVudCBtdXN0IGJlIGFuIGFycmF5LicsIGN1cnJlbnRIb29rTmFtZUluRGV2LCB0eXBlb2YgZGVwcyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHdhcm5Pbkhvb2tNaXNtYXRjaEluRGV2KGN1cnJlbnRIb29rTmFtZSkge1xuICB7XG4gICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEpO1xuXG4gICAgaWYgKCFkaWRXYXJuQWJvdXRNaXNtYXRjaGVkSG9va3NGb3JDb21wb25lbnQuaGFzKGNvbXBvbmVudE5hbWUpKSB7XG4gICAgICBkaWRXYXJuQWJvdXRNaXNtYXRjaGVkSG9va3NGb3JDb21wb25lbnQuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICBpZiAoaG9va1R5cGVzRGV2ICE9PSBudWxsKSB7XG4gICAgICAgIHZhciB0YWJsZSA9ICcnO1xuICAgICAgICB2YXIgc2Vjb25kQ29sdW1uU3RhcnQgPSAzMDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBob29rVHlwZXNVcGRhdGVJbmRleERldjsgaSsrKSB7XG4gICAgICAgICAgdmFyIG9sZEhvb2tOYW1lID0gaG9va1R5cGVzRGV2W2ldO1xuICAgICAgICAgIHZhciBuZXdIb29rTmFtZSA9IGkgPT09IGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2ID8gY3VycmVudEhvb2tOYW1lIDogb2xkSG9va05hbWU7XG4gICAgICAgICAgdmFyIHJvdyA9IGkgKyAxICsgXCIuIFwiICsgb2xkSG9va05hbWU7IC8vIEV4dHJhIHNwYWNlIHNvIHNlY29uZCBjb2x1bW4gbGluZXMgdXBcbiAgICAgICAgICAvLyBsb2wgQCBJRSBub3Qgc3VwcG9ydGluZyBTdHJpbmcjcmVwZWF0XG5cbiAgICAgICAgICB3aGlsZSAocm93Lmxlbmd0aCA8IHNlY29uZENvbHVtblN0YXJ0KSB7XG4gICAgICAgICAgICByb3cgKz0gJyAnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJvdyArPSBuZXdIb29rTmFtZSArICdcXG4nO1xuICAgICAgICAgIHRhYmxlICs9IHJvdztcbiAgICAgICAgfVxuXG4gICAgICAgIGVycm9yKCdSZWFjdCBoYXMgZGV0ZWN0ZWQgYSBjaGFuZ2UgaW4gdGhlIG9yZGVyIG9mIEhvb2tzIGNhbGxlZCBieSAlcy4gJyArICdUaGlzIHdpbGwgbGVhZCB0byBidWdzIGFuZCBlcnJvcnMgaWYgbm90IGZpeGVkLiAnICsgJ0ZvciBtb3JlIGluZm9ybWF0aW9uLCByZWFkIHRoZSBSdWxlcyBvZiBIb29rczogaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3J1bGVzLW9mLWhvb2tzXFxuXFxuJyArICcgICBQcmV2aW91cyByZW5kZXIgICAgICAgICAgICBOZXh0IHJlbmRlclxcbicgKyAnICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXFxuJyArICclcycgKyAnICAgXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXFxuJywgY29tcG9uZW50TmFtZSwgdGFibGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB0aHJvd0ludmFsaWRIb29rRXJyb3IoKSB7XG4gIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBob29rIGNhbGwuIEhvb2tzIGNhbiBvbmx5IGJlIGNhbGxlZCBpbnNpZGUgb2YgdGhlIGJvZHkgb2YgYSBmdW5jdGlvbiBjb21wb25lbnQuIFRoaXMgY291bGQgaGFwcGVuIGZvcicgKyAnIG9uZSBvZiB0aGUgZm9sbG93aW5nIHJlYXNvbnM6XFxuJyArICcxLiBZb3UgbWlnaHQgaGF2ZSBtaXNtYXRjaGluZyB2ZXJzaW9ucyBvZiBSZWFjdCBhbmQgdGhlIHJlbmRlcmVyIChzdWNoIGFzIFJlYWN0IERPTSlcXG4nICsgJzIuIFlvdSBtaWdodCBiZSBicmVha2luZyB0aGUgUnVsZXMgb2YgSG9va3NcXG4nICsgJzMuIFlvdSBtaWdodCBoYXZlIG1vcmUgdGhhbiBvbmUgY29weSBvZiBSZWFjdCBpbiB0aGUgc2FtZSBhcHBcXG4nICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvaW52YWxpZC1ob29rLWNhbGwgZm9yIHRpcHMgYWJvdXQgaG93IHRvIGRlYnVnIGFuZCBmaXggdGhpcyBwcm9ibGVtLicpO1xufVxuXG5mdW5jdGlvbiBhcmVIb29rSW5wdXRzRXF1YWwobmV4dERlcHMsIHByZXZEZXBzKSB7XG4gIHtcbiAgICBpZiAoaWdub3JlUHJldmlvdXNEZXBlbmRlbmNpZXMpIHtcbiAgICAgIC8vIE9ubHkgdHJ1ZSB3aGVuIHRoaXMgY29tcG9uZW50IGlzIGJlaW5nIGhvdCByZWxvYWRlZC5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBpZiAocHJldkRlcHMgPT09IG51bGwpIHtcbiAgICB7XG4gICAgICBlcnJvcignJXMgcmVjZWl2ZWQgYSBmaW5hbCBhcmd1bWVudCBkdXJpbmcgdGhpcyByZW5kZXIsIGJ1dCBub3QgZHVyaW5nICcgKyAndGhlIHByZXZpb3VzIHJlbmRlci4gRXZlbiB0aG91Z2ggdGhlIGZpbmFsIGFyZ3VtZW50IGlzIG9wdGlvbmFsLCAnICsgJ2l0cyB0eXBlIGNhbm5vdCBjaGFuZ2UgYmV0d2VlbiByZW5kZXJzLicsIGN1cnJlbnRIb29rTmFtZUluRGV2KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB7XG4gICAgLy8gRG9uJ3QgYm90aGVyIGNvbXBhcmluZyBsZW5ndGhzIGluIHByb2QgYmVjYXVzZSB0aGVzZSBhcnJheXMgc2hvdWxkIGJlXG4gICAgLy8gcGFzc2VkIGlubGluZS5cbiAgICBpZiAobmV4dERlcHMubGVuZ3RoICE9PSBwcmV2RGVwcy5sZW5ndGgpIHtcbiAgICAgIGVycm9yKCdUaGUgZmluYWwgYXJndW1lbnQgcGFzc2VkIHRvICVzIGNoYW5nZWQgc2l6ZSBiZXR3ZWVuIHJlbmRlcnMuIFRoZSAnICsgJ29yZGVyIGFuZCBzaXplIG9mIHRoaXMgYXJyYXkgbXVzdCByZW1haW4gY29uc3RhbnQuXFxuXFxuJyArICdQcmV2aW91czogJXNcXG4nICsgJ0luY29taW5nOiAlcycsIGN1cnJlbnRIb29rTmFtZUluRGV2LCBcIltcIiArIHByZXZEZXBzLmpvaW4oJywgJykgKyBcIl1cIiwgXCJbXCIgKyBuZXh0RGVwcy5qb2luKCcsICcpICsgXCJdXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJldkRlcHMubGVuZ3RoICYmIGkgPCBuZXh0RGVwcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChvYmplY3RJcyhuZXh0RGVwc1tpXSwgcHJldkRlcHNbaV0pKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyV2l0aEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHByb3BzLCBzZWNvbmRBcmcsIG5leHRSZW5kZXJMYW5lcykge1xuICByZW5kZXJMYW5lcyA9IG5leHRSZW5kZXJMYW5lcztcbiAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSA9IHdvcmtJblByb2dyZXNzO1xuXG4gIHtcbiAgICBob29rVHlwZXNEZXYgPSBjdXJyZW50ICE9PSBudWxsID8gY3VycmVudC5fZGVidWdIb29rVHlwZXMgOiBudWxsO1xuICAgIGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2ID0gLTE7IC8vIFVzZWQgZm9yIGhvdCByZWxvYWRpbmc6XG5cbiAgICBpZ25vcmVQcmV2aW91c0RlcGVuZGVuY2llcyA9IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICB9XG5cbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG51bGw7XG4gIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBOb0xhbmVzOyAvLyBUaGUgZm9sbG93aW5nIHNob3VsZCBoYXZlIGFscmVhZHkgYmVlbiByZXNldFxuICAvLyBjdXJyZW50SG9vayA9IG51bGw7XG4gIC8vIHdvcmtJblByb2dyZXNzSG9vayA9IG51bGw7XG4gIC8vIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSBmYWxzZTtcbiAgLy8gbG9jYWxJZENvdW50ZXIgPSAwO1xuICAvLyBUT0RPIFdhcm4gaWYgbm8gaG9va3MgYXJlIHVzZWQgYXQgYWxsIGR1cmluZyBtb3VudCwgdGhlbiBzb21lIGFyZSB1c2VkIGR1cmluZyB1cGRhdGUuXG4gIC8vIEN1cnJlbnRseSB3ZSB3aWxsIGlkZW50aWZ5IHRoZSB1cGRhdGUgcmVuZGVyIGFzIGEgbW91bnQgYmVjYXVzZSBtZW1vaXplZFN0YXRlID09PSBudWxsLlxuICAvLyBUaGlzIGlzIHRyaWNreSBiZWNhdXNlIGl0J3MgdmFsaWQgZm9yIGNlcnRhaW4gdHlwZXMgb2YgY29tcG9uZW50cyAoZS5nLiBSZWFjdC5sYXp5KVxuICAvLyBVc2luZyBtZW1vaXplZFN0YXRlIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiBtb3VudC91cGRhdGUgb25seSB3b3JrcyBpZiBhdCBsZWFzdCBvbmUgc3RhdGVmdWwgaG9vayBpcyB1c2VkLlxuICAvLyBOb24tc3RhdGVmdWwgaG9va3MgKGUuZy4gY29udGV4dCkgZG9uJ3QgZ2V0IGFkZGVkIHRvIG1lbW9pemVkU3RhdGUsXG4gIC8vIHNvIG1lbW9pemVkU3RhdGUgd291bGQgYmUgbnVsbCBkdXJpbmcgdXBkYXRlcyBhbmQgbW91bnRzLlxuXG4gIHtcbiAgICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcbiAgICB9IGVsc2UgaWYgKGhvb2tUeXBlc0RldiAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyBkaXNwYXRjaGVyIGhhbmRsZXMgYW4gZWRnZSBjYXNlIHdoZXJlIGEgY29tcG9uZW50IGlzIHVwZGF0aW5nLFxuICAgICAgLy8gYnV0IG5vIHN0YXRlZnVsIGhvb2tzIGhhdmUgYmVlbiB1c2VkLlxuICAgICAgLy8gV2Ugd2FudCB0byBtYXRjaCB0aGUgcHJvZHVjdGlvbiBjb2RlIGJlaGF2aW9yICh3aGljaCB3aWxsIHVzZSBIb29rc0Rpc3BhdGNoZXJPbk1vdW50KSxcbiAgICAgIC8vIGJ1dCB3aXRoIHRoZSBleHRyYSBERVYgdmFsaWRhdGlvbiB0byBlbnN1cmUgaG9va3Mgb3JkZXJpbmcgaGFzbid0IGNoYW5nZWQuXG4gICAgICAvLyBUaGlzIGRpc3BhdGNoZXIgZG9lcyB0aGF0LlxuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBIb29rc0Rpc3BhdGNoZXJPbk1vdW50V2l0aEhvb2tUeXBlc0luREVWO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcbiAgICB9XG4gIH1cblxuICB2YXIgY2hpbGRyZW4gPSBDb21wb25lbnQocHJvcHMsIHNlY29uZEFyZyk7IC8vIENoZWNrIGlmIHRoZXJlIHdhcyBhIHJlbmRlciBwaGFzZSB1cGRhdGVcblxuICBpZiAoZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZUR1cmluZ1RoaXNQYXNzKSB7XG4gICAgLy8gS2VlcCByZW5kZXJpbmcgaW4gYSBsb29wIGZvciBhcyBsb25nIGFzIHJlbmRlciBwaGFzZSB1cGRhdGVzIGNvbnRpbnVlIHRvXG4gICAgLy8gYmUgc2NoZWR1bGVkLiBVc2UgYSBjb3VudGVyIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcHMuXG4gICAgdmFyIG51bWJlck9mUmVSZW5kZXJzID0gMDtcblxuICAgIGRvIHtcbiAgICAgIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGZhbHNlO1xuICAgICAgbG9jYWxJZENvdW50ZXIgPSAwO1xuXG4gICAgICBpZiAobnVtYmVyT2ZSZVJlbmRlcnMgPj0gUkVfUkVOREVSX0xJTUlUKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVG9vIG1hbnkgcmUtcmVuZGVycy4gUmVhY3QgbGltaXRzIHRoZSBudW1iZXIgb2YgcmVuZGVycyB0byBwcmV2ZW50ICcgKyAnYW4gaW5maW5pdGUgbG9vcC4nKTtcbiAgICAgIH1cblxuICAgICAgbnVtYmVyT2ZSZVJlbmRlcnMgKz0gMTtcblxuICAgICAge1xuICAgICAgICAvLyBFdmVuIHdoZW4gaG90IHJlbG9hZGluZywgYWxsb3cgZGVwZW5kZW5jaWVzIHRvIHN0YWJpbGl6ZVxuICAgICAgICAvLyBhZnRlciBmaXJzdCByZW5kZXIgdG8gcHJldmVudCBpbmZpbml0ZSByZW5kZXIgcGhhc2UgdXBkYXRlcy5cbiAgICAgICAgaWdub3JlUHJldmlvdXNEZXBlbmRlbmNpZXMgPSBmYWxzZTtcbiAgICAgIH0gLy8gU3RhcnQgb3ZlciBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3RcblxuXG4gICAgICBjdXJyZW50SG9vayA9IG51bGw7XG4gICAgICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSBudWxsO1xuICAgICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBudWxsO1xuXG4gICAgICB7XG4gICAgICAgIC8vIEFsc28gdmFsaWRhdGUgaG9vayBvcmRlciBmb3IgY2FzY2FkaW5nIHVwZGF0ZXMuXG4gICAgICAgIGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2ID0gLTE7XG4gICAgICB9XG5cbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gIEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFViA7XG4gICAgICBjaGlsZHJlbiA9IENvbXBvbmVudChwcm9wcywgc2Vjb25kQXJnKTtcbiAgICB9IHdoaWxlIChkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlRHVyaW5nVGhpc1Bhc3MpO1xuICB9IC8vIFdlIGNhbiBhc3N1bWUgdGhlIHByZXZpb3VzIGRpc3BhdGNoZXIgaXMgYWx3YXlzIHRoaXMgb25lLCBzaW5jZSB3ZSBzZXQgaXRcbiAgLy8gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmVuZGVyIHBoYXNlIGFuZCB0aGVyZSdzIG5vIHJlLWVudHJhbmNlLlxuXG5cbiAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBDb250ZXh0T25seURpc3BhdGNoZXI7XG5cbiAge1xuICAgIHdvcmtJblByb2dyZXNzLl9kZWJ1Z0hvb2tUeXBlcyA9IGhvb2tUeXBlc0RldjtcbiAgfSAvLyBUaGlzIGNoZWNrIHVzZXMgY3VycmVudEhvb2sgc28gdGhhdCBpdCB3b3JrcyB0aGUgc2FtZSBpbiBERVYgYW5kIHByb2QgYnVuZGxlcy5cbiAgLy8gaG9va1R5cGVzRGV2IGNvdWxkIGNhdGNoIG1vcmUgY2FzZXMgKGUuZy4gY29udGV4dCkgYnV0IG9ubHkgaW4gREVWIGJ1bmRsZXMuXG5cblxuICB2YXIgZGlkUmVuZGVyVG9vRmV3SG9va3MgPSBjdXJyZW50SG9vayAhPT0gbnVsbCAmJiBjdXJyZW50SG9vay5uZXh0ICE9PSBudWxsO1xuICByZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG4gIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEgPSBudWxsO1xuICBjdXJyZW50SG9vayA9IG51bGw7XG4gIHdvcmtJblByb2dyZXNzSG9vayA9IG51bGw7XG5cbiAge1xuICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gbnVsbDtcbiAgICBob29rVHlwZXNEZXYgPSBudWxsO1xuICAgIGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2ID0gLTE7IC8vIENvbmZpcm0gdGhhdCBhIHN0YXRpYyBmbGFnIHdhcyBub3QgYWRkZWQgb3IgcmVtb3ZlZCBzaW5jZSB0aGUgbGFzdFxuICAgIC8vIHJlbmRlci4gSWYgdGhpcyBmaXJlcywgaXQgc3VnZ2VzdHMgdGhhdCB3ZSBpbmNvcnJlY3RseSByZXNldCB0aGUgc3RhdGljXG4gICAgLy8gZmxhZ3MgaW4gc29tZSBvdGhlciBwYXJ0IG9mIHRoZSBjb2RlYmFzZS4gVGhpcyBoYXMgaGFwcGVuZWQgYmVmb3JlLCBmb3JcbiAgICAvLyBleGFtcGxlLCBpbiB0aGUgU3VzcGVuc2VMaXN0IGltcGxlbWVudGF0aW9uLlxuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwgJiYgKGN1cnJlbnQuZmxhZ3MgJiBTdGF0aWNNYXNrKSAhPT0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgU3RhdGljTWFzaykgJiYgLy8gRGlzYWJsZSB0aGlzIHdhcm5pbmcgaW4gbGVnYWN5IG1vZGUsIGJlY2F1c2UgbGVnYWN5IFN1c3BlbnNlIGlzIHdlaXJkXG4gICAgLy8gYW5kIGNyZWF0ZXMgZmFsc2UgcG9zaXRpdmVzLiBUbyBtYWtlIHRoaXMgd29yayBpbiBsZWdhY3kgbW9kZSwgd2UnZFxuICAgIC8vIG5lZWQgdG8gbWFyayBmaWJlcnMgdGhhdCBjb21taXQgaW4gYW4gaW5jb21wbGV0ZSBzdGF0ZSwgc29tZWhvdy4gRm9yXG4gICAgLy8gbm93IEknbGwgZGlzYWJsZSB0aGUgd2FybmluZyB0aGF0IG1vc3Qgb2YgdGhlIGJ1Z3MgdGhhdCB3b3VsZCB0cmlnZ2VyXG4gICAgLy8gaXQgYXJlIGVpdGhlciBleGNsdXNpdmUgdG8gY29uY3VycmVudCBtb2RlIG9yIGV4aXN0IGluIGJvdGguXG4gICAgKGN1cnJlbnQubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICBlcnJvcignSW50ZXJuYWwgUmVhY3QgZXJyb3I6IEV4cGVjdGVkIHN0YXRpYyBmbGFnIHdhcyBtaXNzaW5nLiBQbGVhc2UgJyArICdub3RpZnkgdGhlIFJlYWN0IHRlYW0uJyk7XG4gICAgfVxuICB9XG5cbiAgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZSA9IGZhbHNlOyAvLyBUaGlzIGlzIHJlc2V0IGJ5IGNoZWNrRGlkUmVuZGVySWRIb29rXG4gIC8vIGxvY2FsSWRDb3VudGVyID0gMDtcblxuICBpZiAoZGlkUmVuZGVyVG9vRmV3SG9va3MpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbmRlcmVkIGZld2VyIGhvb2tzIHRoYW4gZXhwZWN0ZWQuIFRoaXMgbWF5IGJlIGNhdXNlZCBieSBhbiBhY2NpZGVudGFsICcgKyAnZWFybHkgcmV0dXJuIHN0YXRlbWVudC4nKTtcbiAgfVxuXG4gIHJldHVybiBjaGlsZHJlbjtcbn1cbmZ1bmN0aW9uIGNoZWNrRGlkUmVuZGVySWRIb29rKCkge1xuICAvLyBUaGlzIHNob3VsZCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgZXZlcnkgcmVuZGVyV2l0aEhvb2tzIGNhbGwuXG4gIC8vIENvbmNlcHR1YWxseSwgaXQncyBwYXJ0IG9mIHRoZSByZXR1cm4gdmFsdWUgb2YgcmVuZGVyV2l0aEhvb2tzOyBpdCdzIG9ubHkgYVxuICAvLyBzZXBhcmF0ZSBmdW5jdGlvbiB0byBhdm9pZCB1c2luZyBhbiBhcnJheSB0dXBsZS5cbiAgdmFyIGRpZFJlbmRlcklkSG9vayA9IGxvY2FsSWRDb3VudGVyICE9PSAwO1xuICBsb2NhbElkQ291bnRlciA9IDA7XG4gIHJldHVybiBkaWRSZW5kZXJJZEhvb2s7XG59XG5mdW5jdGlvbiBiYWlsb3V0SG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIGxhbmVzKSB7XG4gIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTsgLy8gVE9ETzogRG9uJ3QgbmVlZCB0byByZXNldCB0aGUgZmxhZ3MgaGVyZSwgYmVjYXVzZSB0aGV5J3JlIHJlc2V0IGluIHRoZVxuICAvLyBjb21wbGV0ZSBwaGFzZSAoYnViYmxlUHJvcGVydGllcykuXG5cbiAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJj0gfihNb3VudFBhc3NpdmVEZXYgfCBNb3VudExheW91dERldiB8IFBhc3NpdmUgfCBVcGRhdGUpO1xuICB9IGVsc2Uge1xuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzICY9IH4oUGFzc2l2ZSB8IFVwZGF0ZSk7XG4gIH1cblxuICBjdXJyZW50LmxhbmVzID0gcmVtb3ZlTGFuZXMoY3VycmVudC5sYW5lcywgbGFuZXMpO1xufVxuZnVuY3Rpb24gcmVzZXRIb29rc0FmdGVyVGhyb3coKSB7XG4gIC8vIFdlIGNhbiBhc3N1bWUgdGhlIHByZXZpb3VzIGRpc3BhdGNoZXIgaXMgYWx3YXlzIHRoaXMgb25lLCBzaW5jZSB3ZSBzZXQgaXRcbiAgLy8gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmVuZGVyIHBoYXNlIGFuZCB0aGVyZSdzIG5vIHJlLWVudHJhbmNlLlxuICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IENvbnRleHRPbmx5RGlzcGF0Y2hlcjtcblxuICBpZiAoZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZSkge1xuICAgIC8vIFRoZXJlIHdlcmUgcmVuZGVyIHBoYXNlIHVwZGF0ZXMuIFRoZXNlIGFyZSBvbmx5IHZhbGlkIGZvciB0aGlzIHJlbmRlclxuICAgIC8vIHBoYXNlLCB3aGljaCB3ZSBhcmUgbm93IGFib3J0aW5nLiBSZW1vdmUgdGhlIHVwZGF0ZXMgZnJvbSB0aGUgcXVldWVzIHNvXG4gICAgLy8gdGhleSBkbyBub3QgcGVyc2lzdCB0byB0aGUgbmV4dCByZW5kZXIuIERvIG5vdCByZW1vdmUgdXBkYXRlcyBmcm9tIGhvb2tzXG4gICAgLy8gdGhhdCB3ZXJlbid0IHByb2Nlc3NlZC5cbiAgICAvL1xuICAgIC8vIE9ubHkgcmVzZXQgdGhlIHVwZGF0ZXMgZnJvbSB0aGUgcXVldWUgaWYgaXQgaGFzIGEgY2xvbmUuIElmIGl0IGRvZXNcbiAgICAvLyBub3QgaGF2ZSBhIGNsb25lLCB0aGF0IG1lYW5zIGl0IHdhc24ndCBwcm9jZXNzZWQsIGFuZCB0aGUgdXBkYXRlcyB3ZXJlXG4gICAgLy8gc2NoZWR1bGVkIGJlZm9yZSB3ZSBlbnRlcmVkIHRoZSByZW5kZXIgcGhhc2UuXG4gICAgdmFyIGhvb2sgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLm1lbW9pemVkU3RhdGU7XG5cbiAgICB3aGlsZSAoaG9vayAhPT0gbnVsbCkge1xuICAgICAgdmFyIHF1ZXVlID0gaG9vay5xdWV1ZTtcblxuICAgICAgaWYgKHF1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgIHF1ZXVlLnBlbmRpbmcgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBob29rID0gaG9vay5uZXh0O1xuICAgIH1cblxuICAgIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSBmYWxzZTtcbiAgfVxuXG4gIHJlbmRlckxhbmVzID0gTm9MYW5lcztcbiAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSA9IG51bGw7XG4gIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3NIb29rID0gbnVsbDtcblxuICB7XG4gICAgaG9va1R5cGVzRGV2ID0gbnVsbDtcbiAgICBob29rVHlwZXNVcGRhdGVJbmRleERldiA9IC0xO1xuICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gbnVsbDtcbiAgICBpc1VwZGF0aW5nT3BhcXVlVmFsdWVJblJlbmRlclBoYXNlID0gZmFsc2U7XG4gIH1cblxuICBkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlRHVyaW5nVGhpc1Bhc3MgPSBmYWxzZTtcbiAgbG9jYWxJZENvdW50ZXIgPSAwO1xufVxuXG5mdW5jdGlvbiBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpIHtcbiAgdmFyIGhvb2sgPSB7XG4gICAgbWVtb2l6ZWRTdGF0ZTogbnVsbCxcbiAgICBiYXNlU3RhdGU6IG51bGwsXG4gICAgYmFzZVF1ZXVlOiBudWxsLFxuICAgIHF1ZXVlOiBudWxsLFxuICAgIG5leHQ6IG51bGxcbiAgfTtcblxuICBpZiAod29ya0luUHJvZ3Jlc3NIb29rID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgaG9vayBpbiB0aGUgbGlzdFxuICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubWVtb2l6ZWRTdGF0ZSA9IHdvcmtJblByb2dyZXNzSG9vayA9IGhvb2s7XG4gIH0gZWxzZSB7XG4gICAgLy8gQXBwZW5kIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RcbiAgICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSB3b3JrSW5Qcm9ncmVzc0hvb2submV4dCA9IGhvb2s7XG4gIH1cblxuICByZXR1cm4gd29ya0luUHJvZ3Jlc3NIb29rO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKSB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBib3RoIGZvciB1cGRhdGVzIGFuZCBmb3IgcmUtcmVuZGVycyB0cmlnZ2VyZWQgYnkgYVxuICAvLyByZW5kZXIgcGhhc2UgdXBkYXRlLiBJdCBhc3N1bWVzIHRoZXJlIGlzIGVpdGhlciBhIGN1cnJlbnQgaG9vayB3ZSBjYW5cbiAgLy8gY2xvbmUsIG9yIGEgd29yay1pbi1wcm9ncmVzcyBob29rIGZyb20gYSBwcmV2aW91cyByZW5kZXIgcGFzcyB0aGF0IHdlIGNhblxuICAvLyB1c2UgYXMgYSBiYXNlLiBXaGVuIHdlIHJlYWNoIHRoZSBlbmQgb2YgdGhlIGJhc2UgbGlzdCwgd2UgbXVzdCBzd2l0Y2ggdG9cbiAgLy8gdGhlIGRpc3BhdGNoZXIgdXNlZCBmb3IgbW91bnRzLlxuICB2YXIgbmV4dEN1cnJlbnRIb29rO1xuXG4gIGlmIChjdXJyZW50SG9vayA9PT0gbnVsbCkge1xuICAgIHZhciBjdXJyZW50ID0gY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5hbHRlcm5hdGU7XG5cbiAgICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgbmV4dEN1cnJlbnRIb29rID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0Q3VycmVudEhvb2sgPSBudWxsO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBuZXh0Q3VycmVudEhvb2sgPSBjdXJyZW50SG9vay5uZXh0O1xuICB9XG5cbiAgdmFyIG5leHRXb3JrSW5Qcm9ncmVzc0hvb2s7XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzSG9vayA9PT0gbnVsbCkge1xuICAgIG5leHRXb3JrSW5Qcm9ncmVzc0hvb2sgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLm1lbW9pemVkU3RhdGU7XG4gIH0gZWxzZSB7XG4gICAgbmV4dFdvcmtJblByb2dyZXNzSG9vayA9IHdvcmtJblByb2dyZXNzSG9vay5uZXh0O1xuICB9XG5cbiAgaWYgKG5leHRXb3JrSW5Qcm9ncmVzc0hvb2sgIT09IG51bGwpIHtcbiAgICAvLyBUaGVyZSdzIGFscmVhZHkgYSB3b3JrLWluLXByb2dyZXNzLiBSZXVzZSBpdC5cbiAgICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSBuZXh0V29ya0luUHJvZ3Jlc3NIb29rO1xuICAgIG5leHRXb3JrSW5Qcm9ncmVzc0hvb2sgPSB3b3JrSW5Qcm9ncmVzc0hvb2submV4dDtcbiAgICBjdXJyZW50SG9vayA9IG5leHRDdXJyZW50SG9vaztcbiAgfSBlbHNlIHtcbiAgICAvLyBDbG9uZSBmcm9tIHRoZSBjdXJyZW50IGhvb2suXG4gICAgaWYgKG5leHRDdXJyZW50SG9vayA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZW5kZXJlZCBtb3JlIGhvb2tzIHRoYW4gZHVyaW5nIHRoZSBwcmV2aW91cyByZW5kZXIuJyk7XG4gICAgfVxuXG4gICAgY3VycmVudEhvb2sgPSBuZXh0Q3VycmVudEhvb2s7XG4gICAgdmFyIG5ld0hvb2sgPSB7XG4gICAgICBtZW1vaXplZFN0YXRlOiBjdXJyZW50SG9vay5tZW1vaXplZFN0YXRlLFxuICAgICAgYmFzZVN0YXRlOiBjdXJyZW50SG9vay5iYXNlU3RhdGUsXG4gICAgICBiYXNlUXVldWU6IGN1cnJlbnRIb29rLmJhc2VRdWV1ZSxcbiAgICAgIHF1ZXVlOiBjdXJyZW50SG9vay5xdWV1ZSxcbiAgICAgIG5leHQ6IG51bGxcbiAgICB9O1xuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzSG9vayA9PT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgaG9vayBpbiB0aGUgbGlzdC5cbiAgICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubWVtb2l6ZWRTdGF0ZSA9IHdvcmtJblByb2dyZXNzSG9vayA9IG5ld0hvb2s7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFwcGVuZCB0byB0aGUgZW5kIG9mIHRoZSBsaXN0LlxuICAgICAgd29ya0luUHJvZ3Jlc3NIb29rID0gd29ya0luUHJvZ3Jlc3NIb29rLm5leHQgPSBuZXdIb29rO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc0hvb2s7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUZ1bmN0aW9uQ29tcG9uZW50VXBkYXRlUXVldWUoKSB7XG4gIHJldHVybiB7XG4gICAgbGFzdEVmZmVjdDogbnVsbCxcbiAgICBzdG9yZXM6IG51bGxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYmFzaWNTdGF0ZVJlZHVjZXIoc3RhdGUsIGFjdGlvbikge1xuICAvLyAkRmxvd0ZpeE1lOiBGbG93IGRvZXNuJ3QgbGlrZSBtaXhlZCB0eXBlc1xuICByZXR1cm4gdHlwZW9mIGFjdGlvbiA9PT0gJ2Z1bmN0aW9uJyA/IGFjdGlvbihzdGF0ZSkgOiBhY3Rpb247XG59XG5cbmZ1bmN0aW9uIG1vdW50UmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIGluaXRpYWxTdGF0ZTtcblxuICBpZiAoaW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaW5pdGlhbFN0YXRlID0gaW5pdChpbml0aWFsQXJnKTtcbiAgfSBlbHNlIHtcbiAgICBpbml0aWFsU3RhdGUgPSBpbml0aWFsQXJnO1xuICB9XG5cbiAgaG9vay5tZW1vaXplZFN0YXRlID0gaG9vay5iYXNlU3RhdGUgPSBpbml0aWFsU3RhdGU7XG4gIHZhciBxdWV1ZSA9IHtcbiAgICBwZW5kaW5nOiBudWxsLFxuICAgIGludGVybGVhdmVkOiBudWxsLFxuICAgIGxhbmVzOiBOb0xhbmVzLFxuICAgIGRpc3BhdGNoOiBudWxsLFxuICAgIGxhc3RSZW5kZXJlZFJlZHVjZXI6IHJlZHVjZXIsXG4gICAgbGFzdFJlbmRlcmVkU3RhdGU6IGluaXRpYWxTdGF0ZVxuICB9O1xuICBob29rLnF1ZXVlID0gcXVldWU7XG4gIHZhciBkaXNwYXRjaCA9IHF1ZXVlLmRpc3BhdGNoID0gZGlzcGF0Y2hSZWR1Y2VyQWN0aW9uLmJpbmQobnVsbCwgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSwgcXVldWUpO1xuICByZXR1cm4gW2hvb2subWVtb2l6ZWRTdGF0ZSwgZGlzcGF0Y2hdO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHF1ZXVlID0gaG9vay5xdWV1ZTtcblxuICBpZiAocXVldWUgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Nob3VsZCBoYXZlIGEgcXVldWUuIFRoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHF1ZXVlLmxhc3RSZW5kZXJlZFJlZHVjZXIgPSByZWR1Y2VyO1xuICB2YXIgY3VycmVudCA9IGN1cnJlbnRIb29rOyAvLyBUaGUgbGFzdCByZWJhc2UgdXBkYXRlIHRoYXQgaXMgTk9UIHBhcnQgb2YgdGhlIGJhc2Ugc3RhdGUuXG5cbiAgdmFyIGJhc2VRdWV1ZSA9IGN1cnJlbnQuYmFzZVF1ZXVlOyAvLyBUaGUgbGFzdCBwZW5kaW5nIHVwZGF0ZSB0aGF0IGhhc24ndCBiZWVuIHByb2Nlc3NlZCB5ZXQuXG5cbiAgdmFyIHBlbmRpbmdRdWV1ZSA9IHF1ZXVlLnBlbmRpbmc7XG5cbiAgaWYgKHBlbmRpbmdRdWV1ZSAhPT0gbnVsbCkge1xuICAgIC8vIFdlIGhhdmUgbmV3IHVwZGF0ZXMgdGhhdCBoYXZlbid0IGJlZW4gcHJvY2Vzc2VkIHlldC5cbiAgICAvLyBXZSdsbCBhZGQgdGhlbSB0byB0aGUgYmFzZSBxdWV1ZS5cbiAgICBpZiAoYmFzZVF1ZXVlICE9PSBudWxsKSB7XG4gICAgICAvLyBNZXJnZSB0aGUgcGVuZGluZyBxdWV1ZSBhbmQgdGhlIGJhc2UgcXVldWUuXG4gICAgICB2YXIgYmFzZUZpcnN0ID0gYmFzZVF1ZXVlLm5leHQ7XG4gICAgICB2YXIgcGVuZGluZ0ZpcnN0ID0gcGVuZGluZ1F1ZXVlLm5leHQ7XG4gICAgICBiYXNlUXVldWUubmV4dCA9IHBlbmRpbmdGaXJzdDtcbiAgICAgIHBlbmRpbmdRdWV1ZS5uZXh0ID0gYmFzZUZpcnN0O1xuICAgIH1cblxuICAgIHtcbiAgICAgIGlmIChjdXJyZW50LmJhc2VRdWV1ZSAhPT0gYmFzZVF1ZXVlKSB7XG4gICAgICAgIC8vIEludGVybmFsIGludmFyaWFudCB0aGF0IHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCBmZWFzaWJseSBjb3VsZCBpblxuICAgICAgICAvLyB0aGUgZnV0dXJlIGlmIHdlIGltcGxlbWVudCByZXN1bWluZywgb3Igc29tZSBmb3JtIG9mIHRoYXQuXG4gICAgICAgIGVycm9yKCdJbnRlcm5hbCBlcnJvcjogRXhwZWN0ZWQgd29yay1pbi1wcm9ncmVzcyBxdWV1ZSB0byBiZSBhIGNsb25lLiAnICsgJ1RoaXMgaXMgYSBidWcgaW4gUmVhY3QuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY3VycmVudC5iYXNlUXVldWUgPSBiYXNlUXVldWUgPSBwZW5kaW5nUXVldWU7XG4gICAgcXVldWUucGVuZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoYmFzZVF1ZXVlICE9PSBudWxsKSB7XG4gICAgLy8gV2UgaGF2ZSBhIHF1ZXVlIHRvIHByb2Nlc3MuXG4gICAgdmFyIGZpcnN0ID0gYmFzZVF1ZXVlLm5leHQ7XG4gICAgdmFyIG5ld1N0YXRlID0gY3VycmVudC5iYXNlU3RhdGU7XG4gICAgdmFyIG5ld0Jhc2VTdGF0ZSA9IG51bGw7XG4gICAgdmFyIG5ld0Jhc2VRdWV1ZUZpcnN0ID0gbnVsbDtcbiAgICB2YXIgbmV3QmFzZVF1ZXVlTGFzdCA9IG51bGw7XG4gICAgdmFyIHVwZGF0ZSA9IGZpcnN0O1xuXG4gICAgZG8ge1xuICAgICAgdmFyIHVwZGF0ZUxhbmUgPSB1cGRhdGUubGFuZTtcblxuICAgICAgaWYgKCFpc1N1YnNldE9mTGFuZXMocmVuZGVyTGFuZXMsIHVwZGF0ZUxhbmUpKSB7XG4gICAgICAgIC8vIFByaW9yaXR5IGlzIGluc3VmZmljaWVudC4gU2tpcCB0aGlzIHVwZGF0ZS4gSWYgdGhpcyBpcyB0aGUgZmlyc3RcbiAgICAgICAgLy8gc2tpcHBlZCB1cGRhdGUsIHRoZSBwcmV2aW91cyB1cGRhdGUvc3RhdGUgaXMgdGhlIG5ldyBiYXNlXG4gICAgICAgIC8vIHVwZGF0ZS9zdGF0ZS5cbiAgICAgICAgdmFyIGNsb25lID0ge1xuICAgICAgICAgIGxhbmU6IHVwZGF0ZUxhbmUsXG4gICAgICAgICAgYWN0aW9uOiB1cGRhdGUuYWN0aW9uLFxuICAgICAgICAgIGhhc0VhZ2VyU3RhdGU6IHVwZGF0ZS5oYXNFYWdlclN0YXRlLFxuICAgICAgICAgIGVhZ2VyU3RhdGU6IHVwZGF0ZS5lYWdlclN0YXRlLFxuICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAobmV3QmFzZVF1ZXVlTGFzdCA9PT0gbnVsbCkge1xuICAgICAgICAgIG5ld0Jhc2VRdWV1ZUZpcnN0ID0gbmV3QmFzZVF1ZXVlTGFzdCA9IGNsb25lO1xuICAgICAgICAgIG5ld0Jhc2VTdGF0ZSA9IG5ld1N0YXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0Jhc2VRdWV1ZUxhc3QgPSBuZXdCYXNlUXVldWVMYXN0Lm5leHQgPSBjbG9uZTtcbiAgICAgICAgfSAvLyBVcGRhdGUgdGhlIHJlbWFpbmluZyBwcmlvcml0eSBpbiB0aGUgcXVldWUuXG4gICAgICAgIC8vIFRPRE86IERvbid0IG5lZWQgdG8gYWNjdW11bGF0ZSB0aGlzLiBJbnN0ZWFkLCB3ZSBjYW4gcmVtb3ZlXG4gICAgICAgIC8vIHJlbmRlckxhbmVzIGZyb20gdGhlIG9yaWdpbmFsIGxhbmVzLlxuXG5cbiAgICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcyA9IG1lcmdlTGFuZXMoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcywgdXBkYXRlTGFuZSk7XG4gICAgICAgIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXModXBkYXRlTGFuZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGlzIHVwZGF0ZSBkb2VzIGhhdmUgc3VmZmljaWVudCBwcmlvcml0eS5cbiAgICAgICAgaWYgKG5ld0Jhc2VRdWV1ZUxhc3QgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgX2Nsb25lID0ge1xuICAgICAgICAgICAgLy8gVGhpcyB1cGRhdGUgaXMgZ29pbmcgdG8gYmUgY29tbWl0dGVkIHNvIHdlIG5ldmVyIHdhbnQgdW5jb21taXRcbiAgICAgICAgICAgIC8vIGl0LiBVc2luZyBOb0xhbmUgd29ya3MgYmVjYXVzZSAwIGlzIGEgc3Vic2V0IG9mIGFsbCBiaXRtYXNrcywgc29cbiAgICAgICAgICAgIC8vIHRoaXMgd2lsbCBuZXZlciBiZSBza2lwcGVkIGJ5IHRoZSBjaGVjayBhYm92ZS5cbiAgICAgICAgICAgIGxhbmU6IE5vTGFuZSxcbiAgICAgICAgICAgIGFjdGlvbjogdXBkYXRlLmFjdGlvbixcbiAgICAgICAgICAgIGhhc0VhZ2VyU3RhdGU6IHVwZGF0ZS5oYXNFYWdlclN0YXRlLFxuICAgICAgICAgICAgZWFnZXJTdGF0ZTogdXBkYXRlLmVhZ2VyU3RhdGUsXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBuZXdCYXNlUXVldWVMYXN0ID0gbmV3QmFzZVF1ZXVlTGFzdC5uZXh0ID0gX2Nsb25lO1xuICAgICAgICB9IC8vIFByb2Nlc3MgdGhpcyB1cGRhdGUuXG5cblxuICAgICAgICBpZiAodXBkYXRlLmhhc0VhZ2VyU3RhdGUpIHtcbiAgICAgICAgICAvLyBJZiB0aGlzIHVwZGF0ZSBpcyBhIHN0YXRlIHVwZGF0ZSAobm90IGEgcmVkdWNlcikgYW5kIHdhcyBwcm9jZXNzZWQgZWFnZXJseSxcbiAgICAgICAgICAvLyB3ZSBjYW4gdXNlIHRoZSBlYWdlcmx5IGNvbXB1dGVkIHN0YXRlXG4gICAgICAgICAgbmV3U3RhdGUgPSB1cGRhdGUuZWFnZXJTdGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgYWN0aW9uID0gdXBkYXRlLmFjdGlvbjtcbiAgICAgICAgICBuZXdTdGF0ZSA9IHJlZHVjZXIobmV3U3RhdGUsIGFjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdXBkYXRlID0gdXBkYXRlLm5leHQ7XG4gICAgfSB3aGlsZSAodXBkYXRlICE9PSBudWxsICYmIHVwZGF0ZSAhPT0gZmlyc3QpO1xuXG4gICAgaWYgKG5ld0Jhc2VRdWV1ZUxhc3QgPT09IG51bGwpIHtcbiAgICAgIG5ld0Jhc2VTdGF0ZSA9IG5ld1N0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdCYXNlUXVldWVMYXN0Lm5leHQgPSBuZXdCYXNlUXVldWVGaXJzdDtcbiAgICB9IC8vIE1hcmsgdGhhdCB0aGUgZmliZXIgcGVyZm9ybWVkIHdvcmssIGJ1dCBvbmx5IGlmIHRoZSBuZXcgc3RhdGUgaXNcbiAgICAvLyBkaWZmZXJlbnQgZnJvbSB0aGUgY3VycmVudCBzdGF0ZS5cblxuXG4gICAgaWYgKCFvYmplY3RJcyhuZXdTdGF0ZSwgaG9vay5tZW1vaXplZFN0YXRlKSkge1xuICAgICAgbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKTtcbiAgICB9XG5cbiAgICBob29rLm1lbW9pemVkU3RhdGUgPSBuZXdTdGF0ZTtcbiAgICBob29rLmJhc2VTdGF0ZSA9IG5ld0Jhc2VTdGF0ZTtcbiAgICBob29rLmJhc2VRdWV1ZSA9IG5ld0Jhc2VRdWV1ZUxhc3Q7XG4gICAgcXVldWUubGFzdFJlbmRlcmVkU3RhdGUgPSBuZXdTdGF0ZTtcbiAgfSAvLyBJbnRlcmxlYXZlZCB1cGRhdGVzIGFyZSBzdG9yZWQgb24gYSBzZXBhcmF0ZSBxdWV1ZS4gV2UgYXJlbid0IGdvaW5nIHRvXG4gIC8vIHByb2Nlc3MgdGhlbSBkdXJpbmcgdGhpcyByZW5kZXIsIGJ1dCB3ZSBkbyBuZWVkIHRvIHRyYWNrIHdoaWNoIGxhbmVzXG4gIC8vIGFyZSByZW1haW5pbmcuXG5cblxuICB2YXIgbGFzdEludGVybGVhdmVkID0gcXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgaWYgKGxhc3RJbnRlcmxlYXZlZCAhPT0gbnVsbCkge1xuICAgIHZhciBpbnRlcmxlYXZlZCA9IGxhc3RJbnRlcmxlYXZlZDtcblxuICAgIGRvIHtcbiAgICAgIHZhciBpbnRlcmxlYXZlZExhbmUgPSBpbnRlcmxlYXZlZC5sYW5lO1xuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcyA9IG1lcmdlTGFuZXMoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcywgaW50ZXJsZWF2ZWRMYW5lKTtcbiAgICAgIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMoaW50ZXJsZWF2ZWRMYW5lKTtcbiAgICAgIGludGVybGVhdmVkID0gaW50ZXJsZWF2ZWQubmV4dDtcbiAgICB9IHdoaWxlIChpbnRlcmxlYXZlZCAhPT0gbGFzdEludGVybGVhdmVkKTtcbiAgfSBlbHNlIGlmIChiYXNlUXVldWUgPT09IG51bGwpIHtcbiAgICAvLyBgcXVldWUubGFuZXNgIGlzIHVzZWQgZm9yIGVudGFuZ2xpbmcgdHJhbnNpdGlvbnMuIFdlIGNhbiBzZXQgaXQgYmFjayB0b1xuICAgIC8vIHplcm8gb25jZSB0aGUgcXVldWUgaXMgZW1wdHkuXG4gICAgcXVldWUubGFuZXMgPSBOb0xhbmVzO1xuICB9XG5cbiAgdmFyIGRpc3BhdGNoID0gcXVldWUuZGlzcGF0Y2g7XG4gIHJldHVybiBbaG9vay5tZW1vaXplZFN0YXRlLCBkaXNwYXRjaF07XG59XG5cbmZ1bmN0aW9uIHJlcmVuZGVyUmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBxdWV1ZSA9IGhvb2sucXVldWU7XG5cbiAgaWYgKHF1ZXVlID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgaGF2ZSBhIHF1ZXVlLiBUaGlzIGlzIGxpa2VseSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cblxuICBxdWV1ZS5sYXN0UmVuZGVyZWRSZWR1Y2VyID0gcmVkdWNlcjsgLy8gVGhpcyBpcyBhIHJlLXJlbmRlci4gQXBwbHkgdGhlIG5ldyByZW5kZXIgcGhhc2UgdXBkYXRlcyB0byB0aGUgcHJldmlvdXNcbiAgLy8gd29yay1pbi1wcm9ncmVzcyBob29rLlxuXG4gIHZhciBkaXNwYXRjaCA9IHF1ZXVlLmRpc3BhdGNoO1xuICB2YXIgbGFzdFJlbmRlclBoYXNlVXBkYXRlID0gcXVldWUucGVuZGluZztcbiAgdmFyIG5ld1N0YXRlID0gaG9vay5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChsYXN0UmVuZGVyUGhhc2VVcGRhdGUgIT09IG51bGwpIHtcbiAgICAvLyBUaGUgcXVldWUgZG9lc24ndCBwZXJzaXN0IHBhc3QgdGhpcyByZW5kZXIgcGFzcy5cbiAgICBxdWV1ZS5wZW5kaW5nID0gbnVsbDtcbiAgICB2YXIgZmlyc3RSZW5kZXJQaGFzZVVwZGF0ZSA9IGxhc3RSZW5kZXJQaGFzZVVwZGF0ZS5uZXh0O1xuICAgIHZhciB1cGRhdGUgPSBmaXJzdFJlbmRlclBoYXNlVXBkYXRlO1xuXG4gICAgZG8ge1xuICAgICAgLy8gUHJvY2VzcyB0aGlzIHJlbmRlciBwaGFzZSB1cGRhdGUuIFdlIGRvbid0IGhhdmUgdG8gY2hlY2sgdGhlXG4gICAgICAvLyBwcmlvcml0eSBiZWNhdXNlIGl0IHdpbGwgYWx3YXlzIGJlIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50XG4gICAgICAvLyByZW5kZXIncy5cbiAgICAgIHZhciBhY3Rpb24gPSB1cGRhdGUuYWN0aW9uO1xuICAgICAgbmV3U3RhdGUgPSByZWR1Y2VyKG5ld1N0YXRlLCBhY3Rpb24pO1xuICAgICAgdXBkYXRlID0gdXBkYXRlLm5leHQ7XG4gICAgfSB3aGlsZSAodXBkYXRlICE9PSBmaXJzdFJlbmRlclBoYXNlVXBkYXRlKTsgLy8gTWFyayB0aGF0IHRoZSBmaWJlciBwZXJmb3JtZWQgd29yaywgYnV0IG9ubHkgaWYgdGhlIG5ldyBzdGF0ZSBpc1xuICAgIC8vIGRpZmZlcmVudCBmcm9tIHRoZSBjdXJyZW50IHN0YXRlLlxuXG5cbiAgICBpZiAoIW9iamVjdElzKG5ld1N0YXRlLCBob29rLm1lbW9pemVkU3RhdGUpKSB7XG4gICAgICBtYXJrV29ya0luUHJvZ3Jlc3NSZWNlaXZlZFVwZGF0ZSgpO1xuICAgIH1cblxuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlOyAvLyBEb24ndCBwZXJzaXN0IHRoZSBzdGF0ZSBhY2N1bXVsYXRlZCBmcm9tIHRoZSByZW5kZXIgcGhhc2UgdXBkYXRlcyB0b1xuICAgIC8vIHRoZSBiYXNlIHN0YXRlIHVubGVzcyB0aGUgcXVldWUgaXMgZW1wdHkuXG4gICAgLy8gVE9ETzogTm90IHN1cmUgaWYgdGhpcyBpcyB0aGUgZGVzaXJlZCBzZW1hbnRpY3MsIGJ1dCBpdCdzIHdoYXQgd2VcbiAgICAvLyBkbyBmb3IgZ0RTRlAuIEkgY2FuJ3QgcmVtZW1iZXIgd2h5LlxuXG4gICAgaWYgKGhvb2suYmFzZVF1ZXVlID09PSBudWxsKSB7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlO1xuICAgIH1cblxuICAgIHF1ZXVlLmxhc3RSZW5kZXJlZFN0YXRlID0gbmV3U3RhdGU7XG4gIH1cblxuICByZXR1cm4gW25ld1N0YXRlLCBkaXNwYXRjaF07XG59XG5cbmZ1bmN0aW9uIG1vdW50TXV0YWJsZVNvdXJjZShzb3VyY2UsIGdldFNuYXBzaG90LCBzdWJzY3JpYmUpIHtcbiAge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlTXV0YWJsZVNvdXJjZShzb3VyY2UsIGdldFNuYXBzaG90LCBzdWJzY3JpYmUpIHtcbiAge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICB2YXIgZmliZXIgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxO1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBuZXh0U25hcHNob3Q7XG4gIHZhciBpc0h5ZHJhdGluZyA9IGdldElzSHlkcmF0aW5nKCk7XG5cbiAgaWYgKGlzSHlkcmF0aW5nKSB7XG4gICAgaWYgKGdldFNlcnZlclNuYXBzaG90ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBnZXRTZXJ2ZXJTbmFwc2hvdCwgd2hpY2ggaXMgcmVxdWlyZWQgZm9yICcgKyAnc2VydmVyLXJlbmRlcmVkIGNvbnRlbnQuIFdpbGwgcmV2ZXJ0IHRvIGNsaWVudCByZW5kZXJpbmcuJyk7XG4gICAgfVxuXG4gICAgbmV4dFNuYXBzaG90ID0gZ2V0U2VydmVyU25hcHNob3QoKTtcblxuICAgIHtcbiAgICAgIGlmICghZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QpIHtcbiAgICAgICAgaWYgKG5leHRTbmFwc2hvdCAhPT0gZ2V0U2VydmVyU25hcHNob3QoKSkge1xuICAgICAgICAgIGVycm9yKCdUaGUgcmVzdWx0IG9mIGdldFNlcnZlclNuYXBzaG90IHNob3VsZCBiZSBjYWNoZWQgdG8gYXZvaWQgYW4gaW5maW5pdGUgbG9vcCcpO1xuXG4gICAgICAgICAgZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG5leHRTbmFwc2hvdCA9IGdldFNuYXBzaG90KCk7XG5cbiAgICB7XG4gICAgICBpZiAoIWRpZFdhcm5VbmNhY2hlZEdldFNuYXBzaG90KSB7XG4gICAgICAgIHZhciBjYWNoZWRTbmFwc2hvdCA9IGdldFNuYXBzaG90KCk7XG5cbiAgICAgICAgaWYgKCFvYmplY3RJcyhuZXh0U25hcHNob3QsIGNhY2hlZFNuYXBzaG90KSkge1xuICAgICAgICAgIGVycm9yKCdUaGUgcmVzdWx0IG9mIGdldFNuYXBzaG90IHNob3VsZCBiZSBjYWNoZWQgdG8gYXZvaWQgYW4gaW5maW5pdGUgbG9vcCcpO1xuXG4gICAgICAgICAgZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSAvLyBVbmxlc3Mgd2UncmUgcmVuZGVyaW5nIGEgYmxvY2tpbmcgbGFuZSwgc2NoZWR1bGUgYSBjb25zaXN0ZW5jeSBjaGVjay5cbiAgICAvLyBSaWdodCBiZWZvcmUgY29tbWl0dGluZywgd2Ugd2lsbCB3YWxrIHRoZSB0cmVlIGFuZCBjaGVjayBpZiBhbnkgb2YgdGhlXG4gICAgLy8gc3RvcmVzIHdlcmUgbXV0YXRlZC5cbiAgICAvL1xuICAgIC8vIFdlIHdvbid0IGRvIHRoaXMgaWYgd2UncmUgaHlkcmF0aW5nIHNlcnZlci1yZW5kZXJlZCBjb250ZW50LCBiZWNhdXNlIGlmXG4gICAgLy8gdGhlIGNvbnRlbnQgaXMgc3RhbGUsIGl0J3MgYWxyZWFkeSB2aXNpYmxlIGFueXdheS4gSW5zdGVhZCB3ZSdsbCBwYXRjaFxuICAgIC8vIGl0IHVwIGluIGEgcGFzc2l2ZSBlZmZlY3QuXG5cblxuICAgIHZhciByb290ID0gZ2V0V29ya0luUHJvZ3Jlc3NSb290KCk7XG5cbiAgICBpZiAocm9vdCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBhIHdvcmstaW4tcHJvZ3Jlc3Mgcm9vdC4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFpbmNsdWRlc0Jsb2NraW5nTGFuZShyb290LCByZW5kZXJMYW5lcykpIHtcbiAgICAgIHB1c2hTdG9yZUNvbnNpc3RlbmN5Q2hlY2soZmliZXIsIGdldFNuYXBzaG90LCBuZXh0U25hcHNob3QpO1xuICAgIH1cbiAgfSAvLyBSZWFkIHRoZSBjdXJyZW50IHNuYXBzaG90IGZyb20gdGhlIHN0b3JlIG9uIGV2ZXJ5IHJlbmRlci4gVGhpcyBicmVha3MgdGhlXG4gIC8vIG5vcm1hbCBydWxlcyBvZiBSZWFjdCwgYW5kIG9ubHkgd29ya3MgYmVjYXVzZSBzdG9yZSB1cGRhdGVzIGFyZVxuICAvLyBhbHdheXMgc3luY2hyb25vdXMuXG5cblxuICBob29rLm1lbW9pemVkU3RhdGUgPSBuZXh0U25hcHNob3Q7XG4gIHZhciBpbnN0ID0ge1xuICAgIHZhbHVlOiBuZXh0U25hcHNob3QsXG4gICAgZ2V0U25hcHNob3Q6IGdldFNuYXBzaG90XG4gIH07XG4gIGhvb2sucXVldWUgPSBpbnN0OyAvLyBTY2hlZHVsZSBhbiBlZmZlY3QgdG8gc3Vic2NyaWJlIHRvIHRoZSBzdG9yZS5cblxuICBtb3VudEVmZmVjdChzdWJzY3JpYmVUb1N0b3JlLmJpbmQobnVsbCwgZmliZXIsIGluc3QsIHN1YnNjcmliZSksIFtzdWJzY3JpYmVdKTsgLy8gU2NoZWR1bGUgYW4gZWZmZWN0IHRvIHVwZGF0ZSB0aGUgbXV0YWJsZSBpbnN0YW5jZSBmaWVsZHMuIFdlIHdpbGwgdXBkYXRlXG4gIC8vIHRoaXMgd2hlbmV2ZXIgc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgb3IgdmFsdWUgY2hhbmdlcy4gQmVjYXVzZSB0aGVyZSdzIG5vXG4gIC8vIGNsZWFuLXVwIGZ1bmN0aW9uLCBhbmQgd2UgdHJhY2sgdGhlIGRlcHMgY29ycmVjdGx5LCB3ZSBjYW4gY2FsbCBwdXNoRWZmZWN0XG4gIC8vIGRpcmVjdGx5LCB3aXRob3V0IHN0b3JpbmcgYW55IGFkZGl0aW9uYWwgc3RhdGUuIEZvciB0aGUgc2FtZSByZWFzb24sIHdlXG4gIC8vIGRvbid0IG5lZWQgdG8gc2V0IGEgc3RhdGljIGZsYWcsIGVpdGhlci5cbiAgLy8gVE9ETzogV2UgY2FuIG1vdmUgdGhpcyB0byB0aGUgcGFzc2l2ZSBwaGFzZSBvbmNlIHdlIGFkZCBhIHByZS1jb21taXRcbiAgLy8gY29uc2lzdGVuY3kgY2hlY2suIFNlZSB0aGUgbmV4dCBjb21tZW50LlxuXG4gIGZpYmVyLmZsYWdzIHw9IFBhc3NpdmU7XG4gIHB1c2hFZmZlY3QoSGFzRWZmZWN0IHwgUGFzc2l2ZSQxLCB1cGRhdGVTdG9yZUluc3RhbmNlLmJpbmQobnVsbCwgZmliZXIsIGluc3QsIG5leHRTbmFwc2hvdCwgZ2V0U25hcHNob3QpLCB1bmRlZmluZWQsIG51bGwpO1xuICByZXR1cm4gbmV4dFNuYXBzaG90O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICB2YXIgZmliZXIgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxO1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpOyAvLyBSZWFkIHRoZSBjdXJyZW50IHNuYXBzaG90IGZyb20gdGhlIHN0b3JlIG9uIGV2ZXJ5IHJlbmRlci4gVGhpcyBicmVha3MgdGhlXG4gIC8vIG5vcm1hbCBydWxlcyBvZiBSZWFjdCwgYW5kIG9ubHkgd29ya3MgYmVjYXVzZSBzdG9yZSB1cGRhdGVzIGFyZVxuICAvLyBhbHdheXMgc3luY2hyb25vdXMuXG5cbiAgdmFyIG5leHRTbmFwc2hvdCA9IGdldFNuYXBzaG90KCk7XG5cbiAge1xuICAgIGlmICghZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QpIHtcbiAgICAgIHZhciBjYWNoZWRTbmFwc2hvdCA9IGdldFNuYXBzaG90KCk7XG5cbiAgICAgIGlmICghb2JqZWN0SXMobmV4dFNuYXBzaG90LCBjYWNoZWRTbmFwc2hvdCkpIHtcbiAgICAgICAgZXJyb3IoJ1RoZSByZXN1bHQgb2YgZ2V0U25hcHNob3Qgc2hvdWxkIGJlIGNhY2hlZCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wJyk7XG5cbiAgICAgICAgZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBwcmV2U25hcHNob3QgPSBob29rLm1lbW9pemVkU3RhdGU7XG4gIHZhciBzbmFwc2hvdENoYW5nZWQgPSAhb2JqZWN0SXMocHJldlNuYXBzaG90LCBuZXh0U25hcHNob3QpO1xuXG4gIGlmIChzbmFwc2hvdENoYW5nZWQpIHtcbiAgICBob29rLm1lbW9pemVkU3RhdGUgPSBuZXh0U25hcHNob3Q7XG4gICAgbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKTtcbiAgfVxuXG4gIHZhciBpbnN0ID0gaG9vay5xdWV1ZTtcbiAgdXBkYXRlRWZmZWN0KHN1YnNjcmliZVRvU3RvcmUuYmluZChudWxsLCBmaWJlciwgaW5zdCwgc3Vic2NyaWJlKSwgW3N1YnNjcmliZV0pOyAvLyBXaGVuZXZlciBnZXRTbmFwc2hvdCBvciBzdWJzY3JpYmUgY2hhbmdlcywgd2UgbmVlZCB0byBjaGVjayBpbiB0aGVcbiAgLy8gY29tbWl0IHBoYXNlIGlmIHRoZXJlIHdhcyBhbiBpbnRlcmxlYXZlZCBtdXRhdGlvbi4gSW4gY29uY3VycmVudCBtb2RlXG4gIC8vIHRoaXMgY2FuIGhhcHBlbiBhbGwgdGhlIHRpbWUsIGJ1dCBldmVuIGluIHN5bmNocm9ub3VzIG1vZGUsIGFuIGVhcmxpZXJcbiAgLy8gZWZmZWN0IG1heSBoYXZlIG11dGF0ZWQgdGhlIHN0b3JlLlxuXG4gIGlmIChpbnN0LmdldFNuYXBzaG90ICE9PSBnZXRTbmFwc2hvdCB8fCBzbmFwc2hvdENoYW5nZWQgfHwgLy8gQ2hlY2sgaWYgdGhlIHN1c2JjcmliZSBmdW5jdGlvbiBjaGFuZ2VkLiBXZSBjYW4gc2F2ZSBzb21lIG1lbW9yeSBieVxuICAvLyBjaGVja2luZyB3aGV0aGVyIHdlIHNjaGVkdWxlZCBhIHN1YnNjcmlwdGlvbiBlZmZlY3QgYWJvdmUuXG4gIHdvcmtJblByb2dyZXNzSG9vayAhPT0gbnVsbCAmJiB3b3JrSW5Qcm9ncmVzc0hvb2subWVtb2l6ZWRTdGF0ZS50YWcgJiBIYXNFZmZlY3QpIHtcbiAgICBmaWJlci5mbGFncyB8PSBQYXNzaXZlO1xuICAgIHB1c2hFZmZlY3QoSGFzRWZmZWN0IHwgUGFzc2l2ZSQxLCB1cGRhdGVTdG9yZUluc3RhbmNlLmJpbmQobnVsbCwgZmliZXIsIGluc3QsIG5leHRTbmFwc2hvdCwgZ2V0U25hcHNob3QpLCB1bmRlZmluZWQsIG51bGwpOyAvLyBVbmxlc3Mgd2UncmUgcmVuZGVyaW5nIGEgYmxvY2tpbmcgbGFuZSwgc2NoZWR1bGUgYSBjb25zaXN0ZW5jeSBjaGVjay5cbiAgICAvLyBSaWdodCBiZWZvcmUgY29tbWl0dGluZywgd2Ugd2lsbCB3YWxrIHRoZSB0cmVlIGFuZCBjaGVjayBpZiBhbnkgb2YgdGhlXG4gICAgLy8gc3RvcmVzIHdlcmUgbXV0YXRlZC5cblxuICAgIHZhciByb290ID0gZ2V0V29ya0luUHJvZ3Jlc3NSb290KCk7XG5cbiAgICBpZiAocm9vdCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBhIHdvcmstaW4tcHJvZ3Jlc3Mgcm9vdC4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFpbmNsdWRlc0Jsb2NraW5nTGFuZShyb290LCByZW5kZXJMYW5lcykpIHtcbiAgICAgIHB1c2hTdG9yZUNvbnNpc3RlbmN5Q2hlY2soZmliZXIsIGdldFNuYXBzaG90LCBuZXh0U25hcHNob3QpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXh0U25hcHNob3Q7XG59XG5cbmZ1bmN0aW9uIHB1c2hTdG9yZUNvbnNpc3RlbmN5Q2hlY2soZmliZXIsIGdldFNuYXBzaG90LCByZW5kZXJlZFNuYXBzaG90KSB7XG4gIGZpYmVyLmZsYWdzIHw9IFN0b3JlQ29uc2lzdGVuY3k7XG4gIHZhciBjaGVjayA9IHtcbiAgICBnZXRTbmFwc2hvdDogZ2V0U25hcHNob3QsXG4gICAgdmFsdWU6IHJlbmRlcmVkU25hcHNob3RcbiAgfTtcbiAgdmFyIGNvbXBvbmVudFVwZGF0ZVF1ZXVlID0gY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS51cGRhdGVRdWV1ZTtcblxuICBpZiAoY29tcG9uZW50VXBkYXRlUXVldWUgPT09IG51bGwpIHtcbiAgICBjb21wb25lbnRVcGRhdGVRdWV1ZSA9IGNyZWF0ZUZ1bmN0aW9uQ29tcG9uZW50VXBkYXRlUXVldWUoKTtcbiAgICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLnVwZGF0ZVF1ZXVlID0gY29tcG9uZW50VXBkYXRlUXVldWU7XG4gICAgY29tcG9uZW50VXBkYXRlUXVldWUuc3RvcmVzID0gW2NoZWNrXTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgc3RvcmVzID0gY29tcG9uZW50VXBkYXRlUXVldWUuc3RvcmVzO1xuXG4gICAgaWYgKHN0b3JlcyA9PT0gbnVsbCkge1xuICAgICAgY29tcG9uZW50VXBkYXRlUXVldWUuc3RvcmVzID0gW2NoZWNrXTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RvcmVzLnB1c2goY2hlY2spO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVTdG9yZUluc3RhbmNlKGZpYmVyLCBpbnN0LCBuZXh0U25hcHNob3QsIGdldFNuYXBzaG90KSB7XG4gIC8vIFRoZXNlIGFyZSB1cGRhdGVkIGluIHRoZSBwYXNzaXZlIHBoYXNlXG4gIGluc3QudmFsdWUgPSBuZXh0U25hcHNob3Q7XG4gIGluc3QuZ2V0U25hcHNob3QgPSBnZXRTbmFwc2hvdDsgLy8gU29tZXRoaW5nIG1heSBoYXZlIGJlZW4gbXV0YXRlZCBpbiBiZXR3ZWVuIHJlbmRlciBhbmQgY29tbWl0LiBUaGlzIGNvdWxkXG4gIC8vIGhhdmUgYmVlbiBpbiBhbiBldmVudCB0aGF0IGZpcmVkIGJlZm9yZSB0aGUgcGFzc2l2ZSBlZmZlY3RzLCBvciBpdCBjb3VsZFxuICAvLyBoYXZlIGJlZW4gaW4gYSBsYXlvdXQgZWZmZWN0LiBJbiB0aGF0IGNhc2UsIHdlIHdvdWxkIGhhdmUgdXNlZCB0aGUgb2xkXG4gIC8vIHNuYXBzaG8gYW5kIGdldFNuYXBzaG90IHZhbHVlcyB0byBiYWlsIG91dC4gV2UgbmVlZCB0byBjaGVjayBvbmUgbW9yZSB0aW1lLlxuXG4gIGlmIChjaGVja0lmU25hcHNob3RDaGFuZ2VkKGluc3QpKSB7XG4gICAgLy8gRm9yY2UgYSByZS1yZW5kZXIuXG4gICAgZm9yY2VTdG9yZVJlcmVuZGVyKGZpYmVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzdWJzY3JpYmVUb1N0b3JlKGZpYmVyLCBpbnN0LCBzdWJzY3JpYmUpIHtcbiAgdmFyIGhhbmRsZVN0b3JlQ2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIFRoZSBzdG9yZSBjaGFuZ2VkLiBDaGVjayBpZiB0aGUgc25hcHNob3QgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHdlXG4gICAgLy8gcmVhZCBmcm9tIHRoZSBzdG9yZS5cbiAgICBpZiAoY2hlY2tJZlNuYXBzaG90Q2hhbmdlZChpbnN0KSkge1xuICAgICAgLy8gRm9yY2UgYSByZS1yZW5kZXIuXG4gICAgICBmb3JjZVN0b3JlUmVyZW5kZXIoZmliZXIpO1xuICAgIH1cbiAgfTsgLy8gU3Vic2NyaWJlIHRvIHRoZSBzdG9yZSBhbmQgcmV0dXJuIGEgY2xlYW4tdXAgZnVuY3Rpb24uXG5cblxuICByZXR1cm4gc3Vic2NyaWJlKGhhbmRsZVN0b3JlQ2hhbmdlKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tJZlNuYXBzaG90Q2hhbmdlZChpbnN0KSB7XG4gIHZhciBsYXRlc3RHZXRTbmFwc2hvdCA9IGluc3QuZ2V0U25hcHNob3Q7XG4gIHZhciBwcmV2VmFsdWUgPSBpbnN0LnZhbHVlO1xuXG4gIHRyeSB7XG4gICAgdmFyIG5leHRWYWx1ZSA9IGxhdGVzdEdldFNuYXBzaG90KCk7XG4gICAgcmV0dXJuICFvYmplY3RJcyhwcmV2VmFsdWUsIG5leHRWYWx1ZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yY2VTdG9yZVJlcmVuZGVyKGZpYmVyKSB7XG4gIHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbn1cblxuZnVuY3Rpb24gbW91bnRTdGF0ZShpbml0aWFsU3RhdGUpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuXG4gIGlmICh0eXBlb2YgaW5pdGlhbFN0YXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gJEZsb3dGaXhNZTogRmxvdyBkb2Vzbid0IGxpa2UgbWl4ZWQgdHlwZXNcbiAgICBpbml0aWFsU3RhdGUgPSBpbml0aWFsU3RhdGUoKTtcbiAgfVxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IGhvb2suYmFzZVN0YXRlID0gaW5pdGlhbFN0YXRlO1xuICB2YXIgcXVldWUgPSB7XG4gICAgcGVuZGluZzogbnVsbCxcbiAgICBpbnRlcmxlYXZlZDogbnVsbCxcbiAgICBsYW5lczogTm9MYW5lcyxcbiAgICBkaXNwYXRjaDogbnVsbCxcbiAgICBsYXN0UmVuZGVyZWRSZWR1Y2VyOiBiYXNpY1N0YXRlUmVkdWNlcixcbiAgICBsYXN0UmVuZGVyZWRTdGF0ZTogaW5pdGlhbFN0YXRlXG4gIH07XG4gIGhvb2sucXVldWUgPSBxdWV1ZTtcbiAgdmFyIGRpc3BhdGNoID0gcXVldWUuZGlzcGF0Y2ggPSBkaXNwYXRjaFNldFN0YXRlLmJpbmQobnVsbCwgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSwgcXVldWUpO1xuICByZXR1cm4gW2hvb2subWVtb2l6ZWRTdGF0ZSwgZGlzcGF0Y2hdO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdGF0ZShpbml0aWFsU3RhdGUpIHtcbiAgcmV0dXJuIHVwZGF0ZVJlZHVjZXIoYmFzaWNTdGF0ZVJlZHVjZXIpO1xufVxuXG5mdW5jdGlvbiByZXJlbmRlclN0YXRlKGluaXRpYWxTdGF0ZSkge1xuICByZXR1cm4gcmVyZW5kZXJSZWR1Y2VyKGJhc2ljU3RhdGVSZWR1Y2VyKTtcbn1cblxuZnVuY3Rpb24gcHVzaEVmZmVjdCh0YWcsIGNyZWF0ZSwgZGVzdHJveSwgZGVwcykge1xuICB2YXIgZWZmZWN0ID0ge1xuICAgIHRhZzogdGFnLFxuICAgIGNyZWF0ZTogY3JlYXRlLFxuICAgIGRlc3Ryb3k6IGRlc3Ryb3ksXG4gICAgZGVwczogZGVwcyxcbiAgICAvLyBDaXJjdWxhclxuICAgIG5leHQ6IG51bGxcbiAgfTtcbiAgdmFyIGNvbXBvbmVudFVwZGF0ZVF1ZXVlID0gY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS51cGRhdGVRdWV1ZTtcblxuICBpZiAoY29tcG9uZW50VXBkYXRlUXVldWUgPT09IG51bGwpIHtcbiAgICBjb21wb25lbnRVcGRhdGVRdWV1ZSA9IGNyZWF0ZUZ1bmN0aW9uQ29tcG9uZW50VXBkYXRlUXVldWUoKTtcbiAgICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLnVwZGF0ZVF1ZXVlID0gY29tcG9uZW50VXBkYXRlUXVldWU7XG4gICAgY29tcG9uZW50VXBkYXRlUXVldWUubGFzdEVmZmVjdCA9IGVmZmVjdC5uZXh0ID0gZWZmZWN0O1xuICB9IGVsc2Uge1xuICAgIHZhciBsYXN0RWZmZWN0ID0gY29tcG9uZW50VXBkYXRlUXVldWUubGFzdEVmZmVjdDtcblxuICAgIGlmIChsYXN0RWZmZWN0ID09PSBudWxsKSB7XG4gICAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5sYXN0RWZmZWN0ID0gZWZmZWN0Lm5leHQgPSBlZmZlY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBmaXJzdEVmZmVjdCA9IGxhc3RFZmZlY3QubmV4dDtcbiAgICAgIGxhc3RFZmZlY3QubmV4dCA9IGVmZmVjdDtcbiAgICAgIGVmZmVjdC5uZXh0ID0gZmlyc3RFZmZlY3Q7XG4gICAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5sYXN0RWZmZWN0ID0gZWZmZWN0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlZmZlY3Q7XG59XG5cbmZ1bmN0aW9uIG1vdW50UmVmKGluaXRpYWxWYWx1ZSkge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG5cbiAge1xuICAgIHZhciBfcmVmMiA9IHtcbiAgICAgIGN1cnJlbnQ6IGluaXRpYWxWYWx1ZVxuICAgIH07XG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gX3JlZjI7XG4gICAgcmV0dXJuIF9yZWYyO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVJlZihpbml0aWFsVmFsdWUpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgcmV0dXJuIGhvb2subWVtb2l6ZWRTdGF0ZTtcbn1cblxuZnVuY3Rpb24gbW91bnRFZmZlY3RJbXBsKGZpYmVyRmxhZ3MsIGhvb2tGbGFncywgY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHREZXBzID0gZGVwcyA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGRlcHM7XG4gIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEuZmxhZ3MgfD0gZmliZXJGbGFncztcbiAgaG9vay5tZW1vaXplZFN0YXRlID0gcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBob29rRmxhZ3MsIGNyZWF0ZSwgdW5kZWZpbmVkLCBuZXh0RGVwcyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVmZmVjdEltcGwoZmliZXJGbGFncywgaG9va0ZsYWdzLCBjcmVhdGUsIGRlcHMpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHREZXBzID0gZGVwcyA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGRlcHM7XG4gIHZhciBkZXN0cm95ID0gdW5kZWZpbmVkO1xuXG4gIGlmIChjdXJyZW50SG9vayAhPT0gbnVsbCkge1xuICAgIHZhciBwcmV2RWZmZWN0ID0gY3VycmVudEhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgICBkZXN0cm95ID0gcHJldkVmZmVjdC5kZXN0cm95O1xuXG4gICAgaWYgKG5leHREZXBzICE9PSBudWxsKSB7XG4gICAgICB2YXIgcHJldkRlcHMgPSBwcmV2RWZmZWN0LmRlcHM7XG5cbiAgICAgIGlmIChhcmVIb29rSW5wdXRzRXF1YWwobmV4dERlcHMsIHByZXZEZXBzKSkge1xuICAgICAgICBob29rLm1lbW9pemVkU3RhdGUgPSBwdXNoRWZmZWN0KGhvb2tGbGFncywgY3JlYXRlLCBkZXN0cm95LCBuZXh0RGVwcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmZsYWdzIHw9IGZpYmVyRmxhZ3M7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHB1c2hFZmZlY3QoSGFzRWZmZWN0IHwgaG9va0ZsYWdzLCBjcmVhdGUsIGRlc3Ryb3ksIG5leHREZXBzKTtcbn1cblxuZnVuY3Rpb24gbW91bnRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIGlmICggKGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChNb3VudFBhc3NpdmVEZXYgfCBQYXNzaXZlIHwgUGFzc2l2ZVN0YXRpYywgUGFzc2l2ZSQxLCBjcmVhdGUsIGRlcHMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBtb3VudEVmZmVjdEltcGwoUGFzc2l2ZSB8IFBhc3NpdmVTdGF0aWMsIFBhc3NpdmUkMSwgY3JlYXRlLCBkZXBzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHJldHVybiB1cGRhdGVFZmZlY3RJbXBsKFBhc3NpdmUsIFBhc3NpdmUkMSwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gbW91bnRJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHJldHVybiBtb3VudEVmZmVjdEltcGwoVXBkYXRlLCBJbnNlcnRpb24sIGNyZWF0ZSwgZGVwcyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgcmV0dXJuIHVwZGF0ZUVmZmVjdEltcGwoVXBkYXRlLCBJbnNlcnRpb24sIGNyZWF0ZSwgZGVwcyk7XG59XG5cbmZ1bmN0aW9uIG1vdW50TGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZmliZXJGbGFncyA9IFVwZGF0ZTtcblxuICB7XG4gICAgZmliZXJGbGFncyB8PSBMYXlvdXRTdGF0aWM7XG4gIH1cblxuICBpZiAoIChjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgIGZpYmVyRmxhZ3MgfD0gTW91bnRMYXlvdXREZXY7XG4gIH1cblxuICByZXR1cm4gbW91bnRFZmZlY3RJbXBsKGZpYmVyRmxhZ3MsIExheW91dCwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICByZXR1cm4gdXBkYXRlRWZmZWN0SW1wbChVcGRhdGUsIExheW91dCwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gaW1wZXJhdGl2ZUhhbmRsZUVmZmVjdChjcmVhdGUsIHJlZikge1xuICBpZiAodHlwZW9mIHJlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciByZWZDYWxsYmFjayA9IHJlZjtcblxuICAgIHZhciBfaW5zdCA9IGNyZWF0ZSgpO1xuXG4gICAgcmVmQ2FsbGJhY2soX2luc3QpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZWZDYWxsYmFjayhudWxsKTtcbiAgICB9O1xuICB9IGVsc2UgaWYgKHJlZiAhPT0gbnVsbCAmJiByZWYgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciByZWZPYmplY3QgPSByZWY7XG5cbiAgICB7XG4gICAgICBpZiAoIXJlZk9iamVjdC5oYXNPd25Qcm9wZXJ0eSgnY3VycmVudCcpKSB7XG4gICAgICAgIGVycm9yKCdFeHBlY3RlZCB1c2VJbXBlcmF0aXZlSGFuZGxlKCkgZmlyc3QgYXJndW1lbnQgdG8gZWl0aGVyIGJlIGEgJyArICdyZWYgY2FsbGJhY2sgb3IgUmVhY3QuY3JlYXRlUmVmKCkgb2JqZWN0LiBJbnN0ZWFkIHJlY2VpdmVkOiAlcy4nLCAnYW4gb2JqZWN0IHdpdGgga2V5cyB7JyArIE9iamVjdC5rZXlzKHJlZk9iamVjdCkuam9pbignLCAnKSArICd9Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIF9pbnN0MiA9IGNyZWF0ZSgpO1xuXG4gICAgcmVmT2JqZWN0LmN1cnJlbnQgPSBfaW5zdDI7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlZk9iamVjdC5jdXJyZW50ID0gbnVsbDtcbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50SW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcykge1xuICB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCB1c2VJbXBlcmF0aXZlSGFuZGxlKCkgc2Vjb25kIGFyZ3VtZW50IHRvIGJlIGEgZnVuY3Rpb24gJyArICd0aGF0IGNyZWF0ZXMgYSBoYW5kbGUuIEluc3RlYWQgcmVjZWl2ZWQ6ICVzLicsIGNyZWF0ZSAhPT0gbnVsbCA/IHR5cGVvZiBjcmVhdGUgOiAnbnVsbCcpO1xuICAgIH1cbiAgfSAvLyBUT0RPOiBJZiBkZXBzIGFyZSBwcm92aWRlZCwgc2hvdWxkIHdlIHNraXAgY29tcGFyaW5nIHRoZSByZWYgaXRzZWxmP1xuXG5cbiAgdmFyIGVmZmVjdERlcHMgPSBkZXBzICE9PSBudWxsICYmIGRlcHMgIT09IHVuZGVmaW5lZCA/IGRlcHMuY29uY2F0KFtyZWZdKSA6IG51bGw7XG4gIHZhciBmaWJlckZsYWdzID0gVXBkYXRlO1xuXG4gIHtcbiAgICBmaWJlckZsYWdzIHw9IExheW91dFN0YXRpYztcbiAgfVxuXG4gIGlmICggKGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgfVxuXG4gIHJldHVybiBtb3VudEVmZmVjdEltcGwoZmliZXJGbGFncywgTGF5b3V0LCBpbXBlcmF0aXZlSGFuZGxlRWZmZWN0LmJpbmQobnVsbCwgY3JlYXRlLCByZWYpLCBlZmZlY3REZXBzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcykge1xuICB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCB1c2VJbXBlcmF0aXZlSGFuZGxlKCkgc2Vjb25kIGFyZ3VtZW50IHRvIGJlIGEgZnVuY3Rpb24gJyArICd0aGF0IGNyZWF0ZXMgYSBoYW5kbGUuIEluc3RlYWQgcmVjZWl2ZWQ6ICVzLicsIGNyZWF0ZSAhPT0gbnVsbCA/IHR5cGVvZiBjcmVhdGUgOiAnbnVsbCcpO1xuICAgIH1cbiAgfSAvLyBUT0RPOiBJZiBkZXBzIGFyZSBwcm92aWRlZCwgc2hvdWxkIHdlIHNraXAgY29tcGFyaW5nIHRoZSByZWYgaXRzZWxmP1xuXG5cbiAgdmFyIGVmZmVjdERlcHMgPSBkZXBzICE9PSBudWxsICYmIGRlcHMgIT09IHVuZGVmaW5lZCA/IGRlcHMuY29uY2F0KFtyZWZdKSA6IG51bGw7XG4gIHJldHVybiB1cGRhdGVFZmZlY3RJbXBsKFVwZGF0ZSwgTGF5b3V0LCBpbXBlcmF0aXZlSGFuZGxlRWZmZWN0LmJpbmQobnVsbCwgY3JlYXRlLCByZWYpLCBlZmZlY3REZXBzKTtcbn1cblxuZnVuY3Rpb24gbW91bnREZWJ1Z1ZhbHVlKHZhbHVlLCBmb3JtYXR0ZXJGbikgey8vIFRoaXMgaG9vayBpcyBub3JtYWxseSBhIG5vLW9wLlxuICAvLyBUaGUgcmVhY3QtZGVidWctaG9va3MgcGFja2FnZSBpbmplY3RzIGl0cyBvd24gaW1wbGVtZW50YXRpb25cbiAgLy8gc28gdGhhdCBlLmcuIERldlRvb2xzIGNhbiBkaXNwbGF5IGN1c3RvbSBob29rIHZhbHVlcy5cbn1cblxudmFyIHVwZGF0ZURlYnVnVmFsdWUgPSBtb3VudERlYnVnVmFsdWU7XG5cbmZ1bmN0aW9uIG1vdW50Q2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgaG9vay5tZW1vaXplZFN0YXRlID0gW2NhbGxiYWNrLCBuZXh0RGVwc107XG4gIHJldHVybiBjYWxsYmFjaztcbn1cblxuZnVuY3Rpb24gdXBkYXRlQ2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHREZXBzID0gZGVwcyA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGRlcHM7XG4gIHZhciBwcmV2U3RhdGUgPSBob29rLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKHByZXZTdGF0ZSAhPT0gbnVsbCkge1xuICAgIGlmIChuZXh0RGVwcyAhPT0gbnVsbCkge1xuICAgICAgdmFyIHByZXZEZXBzID0gcHJldlN0YXRlWzFdO1xuXG4gICAgICBpZiAoYXJlSG9va0lucHV0c0VxdWFsKG5leHREZXBzLCBwcmV2RGVwcykpIHtcbiAgICAgICAgcmV0dXJuIHByZXZTdGF0ZVswXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBob29rLm1lbW9pemVkU3RhdGUgPSBbY2FsbGJhY2ssIG5leHREZXBzXTtcbiAgcmV0dXJuIGNhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiBtb3VudE1lbW8obmV4dENyZWF0ZSwgZGVwcykge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBuZXh0RGVwcyA9IGRlcHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZXBzO1xuICB2YXIgbmV4dFZhbHVlID0gbmV4dENyZWF0ZSgpO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBbbmV4dFZhbHVlLCBuZXh0RGVwc107XG4gIHJldHVybiBuZXh0VmFsdWU7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU1lbW8obmV4dENyZWF0ZSwgZGVwcykge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgdmFyIHByZXZTdGF0ZSA9IGhvb2subWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAocHJldlN0YXRlICE9PSBudWxsKSB7XG4gICAgLy8gQXNzdW1lIHRoZXNlIGFyZSBkZWZpbmVkLiBJZiB0aGV5J3JlIG5vdCwgYXJlSG9va0lucHV0c0VxdWFsIHdpbGwgd2Fybi5cbiAgICBpZiAobmV4dERlcHMgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2RGVwcyA9IHByZXZTdGF0ZVsxXTtcblxuICAgICAgaWYgKGFyZUhvb2tJbnB1dHNFcXVhbChuZXh0RGVwcywgcHJldkRlcHMpKSB7XG4gICAgICAgIHJldHVybiBwcmV2U3RhdGVbMF07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG5leHRWYWx1ZSA9IG5leHRDcmVhdGUoKTtcbiAgaG9vay5tZW1vaXplZFN0YXRlID0gW25leHRWYWx1ZSwgbmV4dERlcHNdO1xuICByZXR1cm4gbmV4dFZhbHVlO1xufVxuXG5mdW5jdGlvbiBtb3VudERlZmVycmVkVmFsdWUodmFsdWUpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSB2YWx1ZTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVEZWZlcnJlZFZhbHVlKHZhbHVlKSB7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciByZXNvbHZlZEN1cnJlbnRIb29rID0gY3VycmVudEhvb2s7XG4gIHZhciBwcmV2VmFsdWUgPSByZXNvbHZlZEN1cnJlbnRIb29rLm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiB1cGRhdGVEZWZlcnJlZFZhbHVlSW1wbChob29rLCBwcmV2VmFsdWUsIHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gcmVyZW5kZXJEZWZlcnJlZFZhbHVlKHZhbHVlKSB7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7XG5cbiAgaWYgKGN1cnJlbnRIb29rID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBpcyBhIHJlcmVuZGVyIGR1cmluZyBhIG1vdW50LlxuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHZhbHVlO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIGlzIGEgcmVyZW5kZXIgZHVyaW5nIGFuIHVwZGF0ZS5cbiAgICB2YXIgcHJldlZhbHVlID0gY3VycmVudEhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgICByZXR1cm4gdXBkYXRlRGVmZXJyZWRWYWx1ZUltcGwoaG9vaywgcHJldlZhbHVlLCB2YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlRGVmZXJyZWRWYWx1ZUltcGwoaG9vaywgcHJldlZhbHVlLCB2YWx1ZSkge1xuICB2YXIgc2hvdWxkRGVmZXJWYWx1ZSA9ICFpbmNsdWRlc09ubHlOb25VcmdlbnRMYW5lcyhyZW5kZXJMYW5lcyk7XG5cbiAgaWYgKHNob3VsZERlZmVyVmFsdWUpIHtcbiAgICAvLyBUaGlzIGlzIGFuIHVyZ2VudCB1cGRhdGUuIElmIHRoZSB2YWx1ZSBoYXMgY2hhbmdlZCwga2VlcCB1c2luZyB0aGVcbiAgICAvLyBwcmV2aW91cyB2YWx1ZSBhbmQgc3Bhd24gYSBkZWZlcnJlZCByZW5kZXIgdG8gdXBkYXRlIGl0IGxhdGVyLlxuICAgIGlmICghb2JqZWN0SXModmFsdWUsIHByZXZWYWx1ZSkpIHtcbiAgICAgIC8vIFNjaGVkdWxlIGEgZGVmZXJyZWQgcmVuZGVyXG4gICAgICB2YXIgZGVmZXJyZWRMYW5lID0gY2xhaW1OZXh0VHJhbnNpdGlvbkxhbmUoKTtcbiAgICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubGFuZXMgPSBtZXJnZUxhbmVzKGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubGFuZXMsIGRlZmVycmVkTGFuZSk7XG4gICAgICBtYXJrU2tpcHBlZFVwZGF0ZUxhbmVzKGRlZmVycmVkTGFuZSk7IC8vIFNldCB0aGlzIHRvIHRydWUgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcmVuZGVyZWQgdmFsdWUgaXMgaW5jb25zaXN0ZW50XG4gICAgICAvLyBmcm9tIHRoZSBsYXRlc3QgdmFsdWUuIFRoZSBuYW1lIFwiYmFzZVN0YXRlXCIgZG9lc24ndCByZWFsbHkgbWF0Y2ggaG93IHdlXG4gICAgICAvLyB1c2UgaXQgYmVjYXVzZSB3ZSdyZSByZXVzaW5nIGEgc3RhdGUgaG9vayBmaWVsZCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGFcbiAgICAgIC8vIG5ldyBvbmUuXG5cbiAgICAgIGhvb2suYmFzZVN0YXRlID0gdHJ1ZTtcbiAgICB9IC8vIFJldXNlIHRoZSBwcmV2aW91cyB2YWx1ZVxuXG5cbiAgICByZXR1cm4gcHJldlZhbHVlO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgbm90IGFuIHVyZ2VudCB1cGRhdGUsIHNvIHdlIGNhbiB1c2UgdGhlIGxhdGVzdCB2YWx1ZSByZWdhcmRsZXNzXG4gICAgLy8gb2Ygd2hhdCBpdCBpcy4gTm8gbmVlZCB0byBkZWZlciBpdC5cbiAgICAvLyBIb3dldmVyLCBpZiB3ZSdyZSBjdXJyZW50bHkgaW5zaWRlIGEgc3Bhd25lZCByZW5kZXIsIHRoZW4gd2UgbmVlZCB0byBtYXJrXG4gICAgLy8gdGhpcyBhcyBhbiB1cGRhdGUgdG8gcHJldmVudCB0aGUgZmliZXIgZnJvbSBiYWlsaW5nIG91dC5cbiAgICAvL1xuICAgIC8vIGBiYXNlU3RhdGVgIGlzIHRydWUgd2hlbiB0aGUgY3VycmVudCB2YWx1ZSBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgcmVuZGVyZWRcbiAgICAvLyB2YWx1ZS4gVGhlIG5hbWUgZG9lc24ndCByZWFsbHkgbWF0Y2ggaG93IHdlIHVzZSBpdCBiZWNhdXNlIHdlJ3JlIHJldXNpbmdcbiAgICAvLyBhIHN0YXRlIGhvb2sgZmllbGQgaW5zdGVhZCBvZiBjcmVhdGluZyBhIG5ldyBvbmUuXG4gICAgaWYgKGhvb2suYmFzZVN0YXRlKSB7XG4gICAgICAvLyBGbGlwIHRoaXMgYmFjayB0byBmYWxzZS5cbiAgICAgIGhvb2suYmFzZVN0YXRlID0gZmFsc2U7XG4gICAgICBtYXJrV29ya0luUHJvZ3Jlc3NSZWNlaXZlZFVwZGF0ZSgpO1xuICAgIH1cblxuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHZhbHVlO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzdGFydFRyYW5zaXRpb24oc2V0UGVuZGluZywgY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgdmFyIHByZXZpb3VzUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcbiAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KGhpZ2hlckV2ZW50UHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSwgQ29udGludW91c0V2ZW50UHJpb3JpdHkpKTtcbiAgc2V0UGVuZGluZyh0cnVlKTtcbiAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMi50cmFuc2l0aW9uO1xuICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQyLnRyYW5zaXRpb24gPSB7fTtcbiAgdmFyIGN1cnJlbnRUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMi50cmFuc2l0aW9uO1xuXG4gIHtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQyLnRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMgPSBuZXcgU2V0KCk7XG4gIH1cblxuICB0cnkge1xuICAgIHNldFBlbmRpbmcoZmFsc2UpO1xuICAgIGNhbGxiYWNrKCk7XG4gIH0gZmluYWxseSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDIudHJhbnNpdGlvbiA9IHByZXZUcmFuc2l0aW9uO1xuXG4gICAge1xuICAgICAgaWYgKHByZXZUcmFuc2l0aW9uID09PSBudWxsICYmIGN1cnJlbnRUcmFuc2l0aW9uLl91cGRhdGVkRmliZXJzKSB7XG4gICAgICAgIHZhciB1cGRhdGVkRmliZXJzQ291bnQgPSBjdXJyZW50VHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycy5zaXplO1xuXG4gICAgICAgIGlmICh1cGRhdGVkRmliZXJzQ291bnQgPiAxMCkge1xuICAgICAgICAgIHdhcm4oJ0RldGVjdGVkIGEgbGFyZ2UgbnVtYmVyIG9mIHVwZGF0ZXMgaW5zaWRlIHN0YXJ0VHJhbnNpdGlvbi4gJyArICdJZiB0aGlzIGlzIGR1ZSB0byBhIHN1YnNjcmlwdGlvbiBwbGVhc2UgcmUtd3JpdGUgaXQgdG8gdXNlIFJlYWN0IHByb3ZpZGVkIGhvb2tzLiAnICsgJ090aGVyd2lzZSBjb25jdXJyZW50IG1vZGUgZ3VhcmFudGVlcyBhcmUgb2ZmIHRoZSB0YWJsZS4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRUcmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLmNsZWFyKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50VHJhbnNpdGlvbigpIHtcbiAgdmFyIF9tb3VudFN0YXRlID0gbW91bnRTdGF0ZShmYWxzZSksXG4gICAgICBpc1BlbmRpbmcgPSBfbW91bnRTdGF0ZVswXSxcbiAgICAgIHNldFBlbmRpbmcgPSBfbW91bnRTdGF0ZVsxXTsgLy8gVGhlIGBzdGFydGAgbWV0aG9kIG5ldmVyIGNoYW5nZXMuXG5cblxuICB2YXIgc3RhcnQgPSBzdGFydFRyYW5zaXRpb24uYmluZChudWxsLCBzZXRQZW5kaW5nKTtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBzdGFydDtcbiAgcmV0dXJuIFtpc1BlbmRpbmcsIHN0YXJ0XTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlVHJhbnNpdGlvbigpIHtcbiAgdmFyIF91cGRhdGVTdGF0ZSA9IHVwZGF0ZVN0YXRlKCksXG4gICAgICBpc1BlbmRpbmcgPSBfdXBkYXRlU3RhdGVbMF07XG5cbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHN0YXJ0ID0gaG9vay5tZW1vaXplZFN0YXRlO1xuICByZXR1cm4gW2lzUGVuZGluZywgc3RhcnRdO1xufVxuXG5mdW5jdGlvbiByZXJlbmRlclRyYW5zaXRpb24oKSB7XG4gIHZhciBfcmVyZW5kZXJTdGF0ZSA9IHJlcmVuZGVyU3RhdGUoKSxcbiAgICAgIGlzUGVuZGluZyA9IF9yZXJlbmRlclN0YXRlWzBdO1xuXG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBzdGFydCA9IGhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgcmV0dXJuIFtpc1BlbmRpbmcsIHN0YXJ0XTtcbn1cblxudmFyIGlzVXBkYXRpbmdPcGFxdWVWYWx1ZUluUmVuZGVyUGhhc2UgPSBmYWxzZTtcbmZ1bmN0aW9uIGdldElzVXBkYXRpbmdPcGFxdWVWYWx1ZUluUmVuZGVyUGhhc2VJbkRFVigpIHtcbiAge1xuICAgIHJldHVybiBpc1VwZGF0aW5nT3BhcXVlVmFsdWVJblJlbmRlclBoYXNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50SWQoKSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHJvb3QgPSBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKTsgLy8gVE9ETzogSW4gRml6eiwgaWQgZ2VuZXJhdGlvbiBpcyBzcGVjaWZpYyB0byBlYWNoIHNlcnZlciBjb25maWcuIE1heWJlIHdlXG4gIC8vIHNob3VsZCBkbyB0aGlzIGluIEZpYmVyLCB0b28/IERlZmVycmluZyB0aGlzIGRlY2lzaW9uIGZvciBub3cgYmVjYXVzZVxuICAvLyB0aGVyZSdzIG5vIG90aGVyIHBsYWNlIHRvIHN0b3JlIHRoZSBwcmVmaXggZXhjZXB0IGZvciBhbiBpbnRlcm5hbCBmaWVsZCBvblxuICAvLyB0aGUgcHVibGljIGNyZWF0ZVJvb3Qgb2JqZWN0LCB3aGljaCB0aGUgZmliZXIgdHJlZSBkb2VzIG5vdCBjdXJyZW50bHkgaGF2ZVxuICAvLyBhIHJlZmVyZW5jZSB0by5cblxuICB2YXIgaWRlbnRpZmllclByZWZpeCA9IHJvb3QuaWRlbnRpZmllclByZWZpeDtcbiAgdmFyIGlkO1xuXG4gIGlmIChnZXRJc0h5ZHJhdGluZygpKSB7XG4gICAgdmFyIHRyZWVJZCA9IGdldFRyZWVJZCgpOyAvLyBVc2UgYSBjYXB0aWFsIFIgcHJlZml4IGZvciBzZXJ2ZXItZ2VuZXJhdGVkIGlkcy5cblxuICAgIGlkID0gJzonICsgaWRlbnRpZmllclByZWZpeCArICdSJyArIHRyZWVJZDsgLy8gVW5sZXNzIHRoaXMgaXMgdGhlIGZpcnN0IGlkIGF0IHRoaXMgbGV2ZWwsIGFwcGVuZCBhIG51bWJlciBhdCB0aGUgZW5kXG4gICAgLy8gdGhhdCByZXByZXNlbnRzIHRoZSBwb3NpdGlvbiBvZiB0aGlzIHVzZUlkIGhvb2sgYW1vbmcgYWxsIHRoZSB1c2VJZFxuICAgIC8vIGhvb2tzIGZvciB0aGlzIGZpYmVyLlxuXG4gICAgdmFyIGxvY2FsSWQgPSBsb2NhbElkQ291bnRlcisrO1xuXG4gICAgaWYgKGxvY2FsSWQgPiAwKSB7XG4gICAgICBpZCArPSAnSCcgKyBsb2NhbElkLnRvU3RyaW5nKDMyKTtcbiAgICB9XG5cbiAgICBpZCArPSAnOic7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIGEgbG93ZXJjYXNlIHIgcHJlZml4IGZvciBjbGllbnQtZ2VuZXJhdGVkIGlkcy5cbiAgICB2YXIgZ2xvYmFsQ2xpZW50SWQgPSBnbG9iYWxDbGllbnRJZENvdW50ZXIrKztcbiAgICBpZCA9ICc6JyArIGlkZW50aWZpZXJQcmVmaXggKyAncicgKyBnbG9iYWxDbGllbnRJZC50b1N0cmluZygzMikgKyAnOic7XG4gIH1cblxuICBob29rLm1lbW9pemVkU3RhdGUgPSBpZDtcbiAgcmV0dXJuIGlkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVJZCgpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIGlkID0gaG9vay5tZW1vaXplZFN0YXRlO1xuICByZXR1cm4gaWQ7XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoUmVkdWNlckFjdGlvbihmaWJlciwgcXVldWUsIGFjdGlvbikge1xuICB7XG4gICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbM10gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKFwiU3RhdGUgdXBkYXRlcyBmcm9tIHRoZSB1c2VTdGF0ZSgpIGFuZCB1c2VSZWR1Y2VyKCkgSG9va3MgZG9uJ3Qgc3VwcG9ydCB0aGUgXCIgKyAnc2Vjb25kIGNhbGxiYWNrIGFyZ3VtZW50LiBUbyBleGVjdXRlIGEgc2lkZSBlZmZlY3QgYWZ0ZXIgJyArICdyZW5kZXJpbmcsIGRlY2xhcmUgaXQgaW4gdGhlIGNvbXBvbmVudCBib2R5IHdpdGggdXNlRWZmZWN0KCkuJyk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gIHZhciB1cGRhdGUgPSB7XG4gICAgbGFuZTogbGFuZSxcbiAgICBhY3Rpb246IGFjdGlvbixcbiAgICBoYXNFYWdlclN0YXRlOiBmYWxzZSxcbiAgICBlYWdlclN0YXRlOiBudWxsLFxuICAgIG5leHQ6IG51bGxcbiAgfTtcblxuICBpZiAoaXNSZW5kZXJQaGFzZVVwZGF0ZShmaWJlcikpIHtcbiAgICBlbnF1ZXVlUmVuZGVyUGhhc2VVcGRhdGUocXVldWUsIHVwZGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgZW5xdWV1ZVVwZGF0ZSQxKGZpYmVyLCBxdWV1ZSwgdXBkYXRlKTtcbiAgICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICAgIHZhciByb290ID0gc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGZpYmVyLCBsYW5lLCBldmVudFRpbWUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIGVudGFuZ2xlVHJhbnNpdGlvblVwZGF0ZShyb290LCBxdWV1ZSwgbGFuZSk7XG4gICAgfVxuICB9XG5cbiAgbWFya1VwZGF0ZUluRGV2VG9vbHMoZmliZXIsIGxhbmUpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaFNldFN0YXRlKGZpYmVyLCBxdWV1ZSwgYWN0aW9uKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1szXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoXCJTdGF0ZSB1cGRhdGVzIGZyb20gdGhlIHVzZVN0YXRlKCkgYW5kIHVzZVJlZHVjZXIoKSBIb29rcyBkb24ndCBzdXBwb3J0IHRoZSBcIiArICdzZWNvbmQgY2FsbGJhY2sgYXJndW1lbnQuIFRvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciAnICsgJ3JlbmRlcmluZywgZGVjbGFyZSBpdCBpbiB0aGUgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHVwZGF0ZSA9IHtcbiAgICBsYW5lOiBsYW5lLFxuICAgIGFjdGlvbjogYWN0aW9uLFxuICAgIGhhc0VhZ2VyU3RhdGU6IGZhbHNlLFxuICAgIGVhZ2VyU3RhdGU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmIChpc1JlbmRlclBoYXNlVXBkYXRlKGZpYmVyKSkge1xuICAgIGVucXVldWVSZW5kZXJQaGFzZVVwZGF0ZShxdWV1ZSwgdXBkYXRlKTtcbiAgfSBlbHNlIHtcbiAgICBlbnF1ZXVlVXBkYXRlJDEoZmliZXIsIHF1ZXVlLCB1cGRhdGUpO1xuICAgIHZhciBhbHRlcm5hdGUgPSBmaWJlci5hbHRlcm5hdGU7XG5cbiAgICBpZiAoZmliZXIubGFuZXMgPT09IE5vTGFuZXMgJiYgKGFsdGVybmF0ZSA9PT0gbnVsbCB8fCBhbHRlcm5hdGUubGFuZXMgPT09IE5vTGFuZXMpKSB7XG4gICAgICAvLyBUaGUgcXVldWUgaXMgY3VycmVudGx5IGVtcHR5LCB3aGljaCBtZWFucyB3ZSBjYW4gZWFnZXJseSBjb21wdXRlIHRoZVxuICAgICAgLy8gbmV4dCBzdGF0ZSBiZWZvcmUgZW50ZXJpbmcgdGhlIHJlbmRlciBwaGFzZS4gSWYgdGhlIG5ldyBzdGF0ZSBpcyB0aGVcbiAgICAgIC8vIHNhbWUgYXMgdGhlIGN1cnJlbnQgc3RhdGUsIHdlIG1heSBiZSBhYmxlIHRvIGJhaWwgb3V0IGVudGlyZWx5LlxuICAgICAgdmFyIGxhc3RSZW5kZXJlZFJlZHVjZXIgPSBxdWV1ZS5sYXN0UmVuZGVyZWRSZWR1Y2VyO1xuXG4gICAgICBpZiAobGFzdFJlbmRlcmVkUmVkdWNlciAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgcHJldkRpc3BhdGNoZXI7XG5cbiAgICAgICAge1xuICAgICAgICAgIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFyIGN1cnJlbnRTdGF0ZSA9IHF1ZXVlLmxhc3RSZW5kZXJlZFN0YXRlO1xuICAgICAgICAgIHZhciBlYWdlclN0YXRlID0gbGFzdFJlbmRlcmVkUmVkdWNlcihjdXJyZW50U3RhdGUsIGFjdGlvbik7IC8vIFN0YXNoIHRoZSBlYWdlcmx5IGNvbXB1dGVkIHN0YXRlLCBhbmQgdGhlIHJlZHVjZXIgdXNlZCB0byBjb21wdXRlXG4gICAgICAgICAgLy8gaXQsIG9uIHRoZSB1cGRhdGUgb2JqZWN0LiBJZiB0aGUgcmVkdWNlciBoYXNuJ3QgY2hhbmdlZCBieSB0aGVcbiAgICAgICAgICAvLyB0aW1lIHdlIGVudGVyIHRoZSByZW5kZXIgcGhhc2UsIHRoZW4gdGhlIGVhZ2VyIHN0YXRlIGNhbiBiZSB1c2VkXG4gICAgICAgICAgLy8gd2l0aG91dCBjYWxsaW5nIHRoZSByZWR1Y2VyIGFnYWluLlxuXG4gICAgICAgICAgdXBkYXRlLmhhc0VhZ2VyU3RhdGUgPSB0cnVlO1xuICAgICAgICAgIHVwZGF0ZS5lYWdlclN0YXRlID0gZWFnZXJTdGF0ZTtcblxuICAgICAgICAgIGlmIChvYmplY3RJcyhlYWdlclN0YXRlLCBjdXJyZW50U3RhdGUpKSB7XG4gICAgICAgICAgICAvLyBGYXN0IHBhdGguIFdlIGNhbiBiYWlsIG91dCB3aXRob3V0IHNjaGVkdWxpbmcgUmVhY3QgdG8gcmUtcmVuZGVyLlxuICAgICAgICAgICAgLy8gSXQncyBzdGlsbCBwb3NzaWJsZSB0aGF0IHdlJ2xsIG5lZWQgdG8gcmViYXNlIHRoaXMgdXBkYXRlIGxhdGVyLFxuICAgICAgICAgICAgLy8gaWYgdGhlIGNvbXBvbmVudCByZS1yZW5kZXJzIGZvciBhIGRpZmZlcmVudCByZWFzb24gYW5kIGJ5IHRoYXRcbiAgICAgICAgICAgIC8vIHRpbWUgdGhlIHJlZHVjZXIgaGFzIGNoYW5nZWQuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikgey8vIFN1cHByZXNzIHRoZSBlcnJvci4gSXQgd2lsbCB0aHJvdyBhZ2FpbiBpbiB0aGUgcmVuZGVyIHBoYXNlLlxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICB2YXIgcm9vdCA9IHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25VcGRhdGUocm9vdCwgcXVldWUsIGxhbmUpO1xuICAgIH1cbiAgfVxuXG4gIG1hcmtVcGRhdGVJbkRldlRvb2xzKGZpYmVyLCBsYW5lKTtcbn1cblxuZnVuY3Rpb24gaXNSZW5kZXJQaGFzZVVwZGF0ZShmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuICByZXR1cm4gZmliZXIgPT09IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGFsdGVybmF0ZSA9PT0gY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMTtcbn1cblxuZnVuY3Rpb24gZW5xdWV1ZVJlbmRlclBoYXNlVXBkYXRlKHF1ZXVlLCB1cGRhdGUpIHtcbiAgLy8gVGhpcyBpcyBhIHJlbmRlciBwaGFzZSB1cGRhdGUuIFN0YXNoIGl0IGluIGEgbGF6aWx5LWNyZWF0ZWQgbWFwIG9mXG4gIC8vIHF1ZXVlIC0+IGxpbmtlZCBsaXN0IG9mIHVwZGF0ZXMuIEFmdGVyIHRoaXMgcmVuZGVyIHBhc3MsIHdlJ2xsIHJlc3RhcnRcbiAgLy8gYW5kIGFwcGx5IHRoZSBzdGFzaGVkIHVwZGF0ZXMgb24gdG9wIG9mIHRoZSB3b3JrLWluLXByb2dyZXNzIGhvb2suXG4gIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSB0cnVlO1xuICB2YXIgcGVuZGluZyA9IHF1ZXVlLnBlbmRpbmc7XG5cbiAgaWYgKHBlbmRpbmcgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgdXBkYXRlLm5leHQgPSB1cGRhdGU7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBwZW5kaW5nLm5leHQ7XG4gICAgcGVuZGluZy5uZXh0ID0gdXBkYXRlO1xuICB9XG5cbiAgcXVldWUucGVuZGluZyA9IHVwZGF0ZTtcbn1cblxuZnVuY3Rpb24gZW5xdWV1ZVVwZGF0ZSQxKGZpYmVyLCBxdWV1ZSwgdXBkYXRlLCBsYW5lKSB7XG4gIGlmIChpc0ludGVybGVhdmVkVXBkYXRlKGZpYmVyKSkge1xuICAgIHZhciBpbnRlcmxlYXZlZCA9IHF1ZXVlLmludGVybGVhdmVkO1xuXG4gICAgaWYgKGludGVybGVhdmVkID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgICB1cGRhdGUubmV4dCA9IHVwZGF0ZTsgLy8gQXQgdGhlIGVuZCBvZiB0aGUgY3VycmVudCByZW5kZXIsIHRoaXMgcXVldWUncyBpbnRlcmxlYXZlZCB1cGRhdGVzIHdpbGxcbiAgICAgIC8vIGJlIHRyYW5zZmVycmVkIHRvIHRoZSBwZW5kaW5nIHF1ZXVlLlxuXG4gICAgICBwdXNoSW50ZXJsZWF2ZWRRdWV1ZShxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZS5uZXh0ID0gaW50ZXJsZWF2ZWQubmV4dDtcbiAgICAgIGludGVybGVhdmVkLm5leHQgPSB1cGRhdGU7XG4gICAgfVxuXG4gICAgcXVldWUuaW50ZXJsZWF2ZWQgPSB1cGRhdGU7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHBlbmRpbmcgPSBxdWV1ZS5wZW5kaW5nO1xuXG4gICAgaWYgKHBlbmRpbmcgPT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IHVwZGF0ZS4gQ3JlYXRlIGEgY2lyY3VsYXIgbGlzdC5cbiAgICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGUubmV4dCA9IHBlbmRpbmcubmV4dDtcbiAgICAgIHBlbmRpbmcubmV4dCA9IHVwZGF0ZTtcbiAgICB9XG5cbiAgICBxdWV1ZS5wZW5kaW5nID0gdXBkYXRlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVudGFuZ2xlVHJhbnNpdGlvblVwZGF0ZShyb290LCBxdWV1ZSwgbGFuZSkge1xuICBpZiAoaXNUcmFuc2l0aW9uTGFuZShsYW5lKSkge1xuICAgIHZhciBxdWV1ZUxhbmVzID0gcXVldWUubGFuZXM7IC8vIElmIGFueSBlbnRhbmdsZWQgbGFuZXMgYXJlIG5vIGxvbmdlciBwZW5kaW5nIG9uIHRoZSByb290LCB0aGVuIHRoZXlcbiAgICAvLyBtdXN0IGhhdmUgZmluaXNoZWQuIFdlIGNhbiByZW1vdmUgdGhlbSBmcm9tIHRoZSBzaGFyZWQgcXVldWUsIHdoaWNoXG4gICAgLy8gcmVwcmVzZW50cyBhIHN1cGVyc2V0IG9mIHRoZSBhY3R1YWxseSBwZW5kaW5nIGxhbmVzLiBJbiBzb21lIGNhc2VzIHdlXG4gICAgLy8gbWF5IGVudGFuZ2xlIG1vcmUgdGhhbiB3ZSBuZWVkIHRvLCBidXQgdGhhdCdzIE9LLiBJbiBmYWN0IGl0J3Mgd29yc2UgaWZcbiAgICAvLyB3ZSAqZG9uJ3QqIGVudGFuZ2xlIHdoZW4gd2Ugc2hvdWxkLlxuXG4gICAgcXVldWVMYW5lcyA9IGludGVyc2VjdExhbmVzKHF1ZXVlTGFuZXMsIHJvb3QucGVuZGluZ0xhbmVzKTsgLy8gRW50YW5nbGUgdGhlIG5ldyB0cmFuc2l0aW9uIGxhbmUgd2l0aCB0aGUgb3RoZXIgdHJhbnNpdGlvbiBsYW5lcy5cblxuICAgIHZhciBuZXdRdWV1ZUxhbmVzID0gbWVyZ2VMYW5lcyhxdWV1ZUxhbmVzLCBsYW5lKTtcbiAgICBxdWV1ZS5sYW5lcyA9IG5ld1F1ZXVlTGFuZXM7IC8vIEV2ZW4gaWYgcXVldWUubGFuZXMgYWxyZWFkeSBpbmNsdWRlIGxhbmUsIHdlIGRvbid0IGtub3cgZm9yIGNlcnRhaW4gaWZcbiAgICAvLyB0aGUgbGFuZSBmaW5pc2hlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHdlIGVudGFuZ2xlZCBpdC4gU28gd2UgbmVlZCB0b1xuICAgIC8vIGVudGFuZ2xlIGl0IGFnYWluLCBqdXN0IHRvIGJlIHN1cmUuXG5cbiAgICBtYXJrUm9vdEVudGFuZ2xlZChyb290LCBuZXdRdWV1ZUxhbmVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrVXBkYXRlSW5EZXZUb29scyhmaWJlciwgbGFuZSwgYWN0aW9uKSB7XG5cbiAge1xuICAgIG1hcmtTdGF0ZVVwZGF0ZVNjaGVkdWxlZChmaWJlciwgbGFuZSk7XG4gIH1cbn1cblxudmFyIENvbnRleHRPbmx5RGlzcGF0Y2hlciA9IHtcbiAgcmVhZENvbnRleHQ6IHJlYWRDb250ZXh0LFxuICB1c2VDYWxsYmFjazogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VDb250ZXh0OiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUVmZmVjdDogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VJbXBlcmF0aXZlSGFuZGxlOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUluc2VydGlvbkVmZmVjdDogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VMYXlvdXRFZmZlY3Q6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlTWVtbzogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VSZWR1Y2VyOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZVJlZjogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VTdGF0ZTogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VEZWJ1Z1ZhbHVlOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZURlZmVycmVkVmFsdWU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlVHJhbnNpdGlvbjogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VNdXRhYmxlU291cmNlOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUlkOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVuc3RhYmxlX2lzTmV3UmVjb25jaWxlcjogZW5hYmxlTmV3UmVjb25jaWxlclxufTtcblxudmFyIEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFViA9IG51bGw7XG52YXIgSG9va3NEaXNwYXRjaGVyT25Nb3VudFdpdGhIb29rVHlwZXNJbkRFViA9IG51bGw7XG52YXIgSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFViA9IG51bGw7XG52YXIgSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWID0gbnVsbDtcbnZhciBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWID0gbnVsbDtcbnZhciBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFViA9IG51bGw7XG52YXIgSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFViA9IG51bGw7XG5cbntcbiAgdmFyIHdhcm5JbnZhbGlkQ29udGV4dEFjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBlcnJvcignQ29udGV4dCBjYW4gb25seSBiZSByZWFkIHdoaWxlIFJlYWN0IGlzIHJlbmRlcmluZy4gJyArICdJbiBjbGFzc2VzLCB5b3UgY2FuIHJlYWQgaXQgaW4gdGhlIHJlbmRlciBtZXRob2Qgb3IgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLiAnICsgJ0luIGZ1bmN0aW9uIGNvbXBvbmVudHMsIHlvdSBjYW4gcmVhZCBpdCBkaXJlY3RseSBpbiB0aGUgZnVuY3Rpb24gYm9keSwgYnV0IG5vdCAnICsgJ2luc2lkZSBIb29rcyBsaWtlIHVzZVJlZHVjZXIoKSBvciB1c2VNZW1vKCkuJyk7XG4gIH07XG5cbiAgdmFyIHdhcm5JbnZhbGlkSG9va0FjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBlcnJvcignRG8gbm90IGNhbGwgSG9va3MgaW5zaWRlIHVzZUVmZmVjdCguLi4pLCB1c2VNZW1vKC4uLiksIG9yIG90aGVyIGJ1aWx0LWluIEhvb2tzLiAnICsgJ1lvdSBjYW4gb25seSBjYWxsIEhvb2tzIGF0IHRoZSB0b3AgbGV2ZWwgb2YgeW91ciBSZWFjdCBmdW5jdGlvbi4gJyArICdGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3J1bGVzLW9mLWhvb2tzJyk7XG4gIH07XG5cbiAgSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWID0ge1xuICAgIHJlYWRDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgcmV0dXJuIG1vdW50Q2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRWZmZWN0JztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICBjaGVja0RlcHNBcmVBcnJheURldihkZXBzKTtcbiAgICAgIHJldHVybiBtb3VudEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW1wZXJhdGl2ZUhhbmRsZTogZnVuY3Rpb24gKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbXBlcmF0aXZlSGFuZGxlJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICBjaGVja0RlcHNBcmVBcnJheURldihkZXBzKTtcbiAgICAgIHJldHVybiBtb3VudEltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgcmV0dXJuIG1vdW50SW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VMYXlvdXRFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUxheW91dEVmZmVjdCc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICByZXR1cm4gbW91bnRMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZU1lbW86IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU1lbW8nO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudE1lbW8oY3JlYXRlLCBkZXBzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWR1Y2VyOiBmdW5jdGlvbiAocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVkdWNlcic7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudFJlZihpbml0aWFsVmFsdWUpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50U3RhdGUoaW5pdGlhbFN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VEZWJ1Z1ZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIGZvcm1hdHRlckZuKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWJ1Z1ZhbHVlJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudERlZmVycmVkVmFsdWUodmFsdWUpO1xuICAgIH0sXG4gICAgdXNlVHJhbnNpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlVHJhbnNpdGlvbic7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50VHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudFN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KTtcbiAgICB9LFxuICAgIHVzZUlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJZCc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50SWQoKTtcbiAgICB9LFxuICAgIHVuc3RhYmxlX2lzTmV3UmVjb25jaWxlcjogZW5hYmxlTmV3UmVjb25jaWxlclxuICB9O1xuXG4gIEhvb2tzRGlzcGF0Y2hlck9uTW91bnRXaXRoSG9va1R5cGVzSW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudENhbGxiYWNrKGNhbGxiYWNrLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUNvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDb250ZXh0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudE1lbW8oY3JlYXRlLCBkZXBzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWR1Y2VyOiBmdW5jdGlvbiAocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVkdWNlcic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZjogZnVuY3Rpb24gKGluaXRpYWxWYWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVmJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50UmVmKGluaXRpYWxWYWx1ZSk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50U3RhdGUoaW5pdGlhbFN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VEZWJ1Z1ZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIGZvcm1hdHRlckZuKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWJ1Z1ZhbHVlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50VHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudE11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50U3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50SWQoKTtcbiAgICB9LFxuICAgIHVuc3RhYmxlX2lzTmV3UmVjb25jaWxlcjogZW5hYmxlTmV3UmVjb25jaWxlclxuICB9O1xuXG4gIEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW1wZXJhdGl2ZUhhbmRsZTogZnVuY3Rpb24gKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbXBlcmF0aXZlSGFuZGxlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VMYXlvdXRFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUxheW91dEVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZU1lbW86IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU1lbW8nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZjogZnVuY3Rpb24gKGluaXRpYWxWYWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVmJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVJlZigpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gdXBkYXRlU3RhdGUoaW5pdGlhbFN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VEZWJ1Z1ZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIGZvcm1hdHRlckZuKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWJ1Z1ZhbHVlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlYnVnVmFsdWUoKTtcbiAgICB9LFxuICAgIHVzZURlZmVycmVkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVmZXJyZWRWYWx1ZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVEZWZlcnJlZFZhbHVlKHZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVRyYW5zaXRpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVRyYW5zaXRpb24nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlVHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVNdXRhYmxlU291cmNlKCk7XG4gICAgfSxcbiAgICB1c2VTeW5jRXh0ZXJuYWxTdG9yZTogZnVuY3Rpb24gKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTeW5jRXh0ZXJuYWxTdG9yZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90KTtcbiAgICB9LFxuICAgIHVzZUlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJZCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWID0ge1xuICAgIHJlYWRDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlQ2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUluc2VydGlvbkVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW5zZXJ0aW9uRWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTGF5b3V0RWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VMYXlvdXRFZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHJlcmVuZGVyUmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWY6IGZ1bmN0aW9uIChpbml0aWFsVmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVSZWYoKTtcbiAgICB9LFxuICAgIHVzZVN0YXRlOiBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTdGF0ZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gcmVyZW5kZXJTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlcmVuZGVyRGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlcmVuZGVyVHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVNdXRhYmxlU291cmNlKCk7XG4gICAgfSxcbiAgICB1c2VTeW5jRXh0ZXJuYWxTdG9yZTogZnVuY3Rpb24gKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTeW5jRXh0ZXJuYWxTdG9yZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90KTtcbiAgICB9LFxuICAgIHVzZUlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJZCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHdhcm5JbnZhbGlkQ29udGV4dEFjY2VzcygpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50Q2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50SW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudExheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50TWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZjogZnVuY3Rpb24gKGluaXRpYWxWYWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVmJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudFJlZihpbml0aWFsVmFsdWUpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudERlZmVycmVkVmFsdWUodmFsdWUpO1xuICAgIH0sXG4gICAgdXNlVHJhbnNpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlVHJhbnNpdGlvbic7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudE11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudFN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KTtcbiAgICB9LFxuICAgIHVzZUlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJZCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICB3YXJuSW52YWxpZENvbnRleHRBY2Nlc3MoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNhbGxiYWNrJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlQ2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUluc2VydGlvbkVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW5zZXJ0aW9uRWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VMYXlvdXRFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUxheW91dEVmZmVjdCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUxheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gdXBkYXRlTWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZjogZnVuY3Rpb24gKGluaXRpYWxWYWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVmJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlUmVmKCk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlYnVnVmFsdWUoKTtcbiAgICB9LFxuICAgIHVzZURlZmVycmVkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVmZXJyZWRWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlZmVycmVkVmFsdWUodmFsdWUpO1xuICAgIH0sXG4gICAgdXNlVHJhbnNpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlVHJhbnNpdGlvbic7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVRyYW5zaXRpb24oKTtcbiAgICB9LFxuICAgIHVzZU11dGFibGVTb3VyY2U6IGZ1bmN0aW9uIChzb3VyY2UsIGdldFNuYXBzaG90LCBzdWJzY3JpYmUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU11dGFibGVTb3VyY2UnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVNdXRhYmxlU291cmNlKCk7XG4gICAgfSxcbiAgICB1c2VTeW5jRXh0ZXJuYWxTdG9yZTogZnVuY3Rpb24gKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTeW5jRXh0ZXJuYWxTdG9yZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSWQoKTtcbiAgICB9LFxuICAgIHVuc3RhYmxlX2lzTmV3UmVjb25jaWxlcjogZW5hYmxlTmV3UmVjb25jaWxlclxuICB9O1xuXG4gIEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICB3YXJuSW52YWxpZENvbnRleHRBY2Nlc3MoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNhbGxiYWNrJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlQ2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUluc2VydGlvbkVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW5zZXJ0aW9uRWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VMYXlvdXRFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUxheW91dEVmZmVjdCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUxheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gdXBkYXRlTWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiByZXJlbmRlclJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVSZWYoKTtcbiAgICB9LFxuICAgIHVzZVN0YXRlOiBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTdGF0ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gcmVyZW5kZXJTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVEZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZXJlbmRlckRlZmVycmVkVmFsdWUodmFsdWUpO1xuICAgIH0sXG4gICAgdXNlVHJhbnNpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlVHJhbnNpdGlvbic7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlcmVuZGVyVHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlU3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCk7XG4gICAgfSxcbiAgICB1c2VJZDogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSWQnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG59XG5cbnZhciBub3ckMSA9IFNjaGVkdWxlci51bnN0YWJsZV9ub3c7XG52YXIgY29tbWl0VGltZSA9IDA7XG52YXIgbGF5b3V0RWZmZWN0U3RhcnRUaW1lID0gLTE7XG52YXIgcHJvZmlsZXJTdGFydFRpbWUgPSAtMTtcbnZhciBwYXNzaXZlRWZmZWN0U3RhcnRUaW1lID0gLTE7XG4vKipcbiAqIFRyYWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IHVwZGF0ZSB3YXMgYSBuZXN0ZWQvY2FzY2FkaW5nIHVwZGF0ZSAoc2NoZWR1bGVkIGZyb20gYSBsYXlvdXQgZWZmZWN0KS5cbiAqXG4gKiBUaGUgb3ZlcmFsbCBzZXF1ZW5jZSBpczpcbiAqICAgMS4gcmVuZGVyXG4gKiAgIDIuIGNvbW1pdCAoYW5kIGNhbGwgYG9uUmVuZGVyYCwgYG9uQ29tbWl0YClcbiAqICAgMy4gY2hlY2sgZm9yIG5lc3RlZCB1cGRhdGVzXG4gKiAgIDQuIGZsdXNoIHBhc3NpdmUgZWZmZWN0cyAoYW5kIGNhbGwgYG9uUG9zdENvbW1pdGApXG4gKlxuICogTmVzdGVkIHVwZGF0ZXMgYXJlIGlkZW50aWZpZWQgaW4gc3RlcCAzIGFib3ZlLFxuICogYnV0IHN0ZXAgNCBzdGlsbCBhcHBsaWVzIHRvIHRoZSB3b3JrIHRoYXQgd2FzIGp1c3QgY29tbWl0dGVkLlxuICogV2UgdXNlIHR3byBmbGFncyB0byB0cmFjayBuZXN0ZWQgdXBkYXRlcyB0aGVuOlxuICogb25lIHRyYWNrcyB3aGV0aGVyIHRoZSB1cGNvbWluZyB1cGRhdGUgaXMgYSBuZXN0ZWQgdXBkYXRlLFxuICogYW5kIHRoZSBvdGhlciB0cmFja3Mgd2hldGhlciB0aGUgY3VycmVudCB1cGRhdGUgd2FzIGEgbmVzdGVkIHVwZGF0ZS5cbiAqIFRoZSBmaXJzdCB2YWx1ZSBnZXRzIHN5bmNlZCB0byB0aGUgc2Vjb25kIGF0IHRoZSBzdGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLlxuICovXG5cbnZhciBjdXJyZW50VXBkYXRlSXNOZXN0ZWQgPSBmYWxzZTtcbnZhciBuZXN0ZWRVcGRhdGVTY2hlZHVsZWQgPSBmYWxzZTtcblxuZnVuY3Rpb24gaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkge1xuICByZXR1cm4gY3VycmVudFVwZGF0ZUlzTmVzdGVkO1xufVxuXG5mdW5jdGlvbiBtYXJrTmVzdGVkVXBkYXRlU2NoZWR1bGVkKCkge1xuICB7XG4gICAgbmVzdGVkVXBkYXRlU2NoZWR1bGVkID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldE5lc3RlZFVwZGF0ZUZsYWcoKSB7XG4gIHtcbiAgICBjdXJyZW50VXBkYXRlSXNOZXN0ZWQgPSBmYWxzZTtcbiAgICBuZXN0ZWRVcGRhdGVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzeW5jTmVzdGVkVXBkYXRlRmxhZygpIHtcbiAge1xuICAgIGN1cnJlbnRVcGRhdGVJc05lc3RlZCA9IG5lc3RlZFVwZGF0ZVNjaGVkdWxlZDtcbiAgICBuZXN0ZWRVcGRhdGVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRDb21taXRUaW1lKCkge1xuICByZXR1cm4gY29tbWl0VGltZTtcbn1cblxuZnVuY3Rpb24gcmVjb3JkQ29tbWl0VGltZSgpIHtcblxuICBjb21taXRUaW1lID0gbm93JDEoKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRQcm9maWxlclRpbWVyKGZpYmVyKSB7XG5cbiAgcHJvZmlsZXJTdGFydFRpbWUgPSBub3ckMSgpO1xuXG4gIGlmIChmaWJlci5hY3R1YWxTdGFydFRpbWUgPCAwKSB7XG4gICAgZmliZXIuYWN0dWFsU3RhcnRUaW1lID0gbm93JDEoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9wUHJvZmlsZXJUaW1lcklmUnVubmluZyhmaWJlcikge1xuXG4gIHByb2ZpbGVyU3RhcnRUaW1lID0gLTE7XG59XG5cbmZ1bmN0aW9uIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoZmliZXIsIG92ZXJyaWRlQmFzZVRpbWUpIHtcblxuICBpZiAocHJvZmlsZXJTdGFydFRpbWUgPj0gMCkge1xuICAgIHZhciBlbGFwc2VkVGltZSA9IG5vdyQxKCkgLSBwcm9maWxlclN0YXJ0VGltZTtcbiAgICBmaWJlci5hY3R1YWxEdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcblxuICAgIGlmIChvdmVycmlkZUJhc2VUaW1lKSB7XG4gICAgICBmaWJlci5zZWxmQmFzZUR1cmF0aW9uID0gZWxhcHNlZFRpbWU7XG4gICAgfVxuXG4gICAgcHJvZmlsZXJTdGFydFRpbWUgPSAtMTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihmaWJlcikge1xuXG4gIGlmIChsYXlvdXRFZmZlY3RTdGFydFRpbWUgPj0gMCkge1xuICAgIHZhciBlbGFwc2VkVGltZSA9IG5vdyQxKCkgLSBsYXlvdXRFZmZlY3RTdGFydFRpbWU7XG4gICAgbGF5b3V0RWZmZWN0U3RhcnRUaW1lID0gLTE7IC8vIFN0b3JlIGR1cmF0aW9uIG9uIHRoZSBuZXh0IG5lYXJlc3QgUHJvZmlsZXIgYW5jZXN0b3JcbiAgICAvLyBPciB0aGUgcm9vdCAoZm9yIHRoZSBEZXZUb29scyBQcm9maWxlciB0byByZWFkKVxuXG4gICAgdmFyIHBhcmVudEZpYmVyID0gZmliZXIucmV0dXJuO1xuXG4gICAgd2hpbGUgKHBhcmVudEZpYmVyICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgICAgICBjYXNlIEhvc3RSb290OlxuICAgICAgICAgIHZhciByb290ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuICAgICAgICAgIHJvb3QuZWZmZWN0RHVyYXRpb24gKz0gZWxhcHNlZFRpbWU7XG4gICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNhc2UgUHJvZmlsZXI6XG4gICAgICAgICAgdmFyIHBhcmVudFN0YXRlTm9kZSA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICBwYXJlbnRTdGF0ZU5vZGUuZWZmZWN0RHVyYXRpb24gKz0gZWxhcHNlZFRpbWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnRGaWJlciA9IHBhcmVudEZpYmVyLnJldHVybjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVjb3JkUGFzc2l2ZUVmZmVjdER1cmF0aW9uKGZpYmVyKSB7XG5cbiAgaWYgKHBhc3NpdmVFZmZlY3RTdGFydFRpbWUgPj0gMCkge1xuICAgIHZhciBlbGFwc2VkVGltZSA9IG5vdyQxKCkgLSBwYXNzaXZlRWZmZWN0U3RhcnRUaW1lO1xuICAgIHBhc3NpdmVFZmZlY3RTdGFydFRpbWUgPSAtMTsgLy8gU3RvcmUgZHVyYXRpb24gb24gdGhlIG5leHQgbmVhcmVzdCBQcm9maWxlciBhbmNlc3RvclxuICAgIC8vIE9yIHRoZSByb290IChmb3IgdGhlIERldlRvb2xzIFByb2ZpbGVyIHRvIHJlYWQpXG5cbiAgICB2YXIgcGFyZW50RmliZXIgPSBmaWJlci5yZXR1cm47XG5cbiAgICB3aGlsZSAocGFyZW50RmliZXIgIT09IG51bGwpIHtcbiAgICAgIHN3aXRjaCAocGFyZW50RmliZXIudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgdmFyIHJvb3QgPSBwYXJlbnRGaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcm9vdC5wYXNzaXZlRWZmZWN0RHVyYXRpb24gKz0gZWxhcHNlZFRpbWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNhc2UgUHJvZmlsZXI6XG4gICAgICAgICAgdmFyIHBhcmVudFN0YXRlTm9kZSA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgICAgIGlmIChwYXJlbnRTdGF0ZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIERldGFjaGVkIGZpYmVycyBoYXZlIHRoZWlyIHN0YXRlIG5vZGUgY2xlYXJlZCBvdXQuXG4gICAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UsIHRoZSByZXR1cm4gcG9pbnRlciBpcyBhbHNvIGNsZWFyZWQgb3V0LFxuICAgICAgICAgICAgLy8gc28gd2Ugd29uJ3QgYmUgYWJsZSB0byByZXBvcnQgdGhlIHRpbWUgc3BlbnQgaW4gdGhpcyBQcm9maWxlcidzIHN1YnRyZWUuXG4gICAgICAgICAgICBwYXJlbnRTdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IGVsYXBzZWRUaW1lO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcGFyZW50RmliZXIgPSBwYXJlbnRGaWJlci5yZXR1cm47XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKSB7XG5cbiAgbGF5b3V0RWZmZWN0U3RhcnRUaW1lID0gbm93JDEoKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKSB7XG5cbiAgcGFzc2l2ZUVmZmVjdFN0YXJ0VGltZSA9IG5vdyQxKCk7XG59XG5cbmZ1bmN0aW9uIHRyYW5zZmVyQWN0dWFsRHVyYXRpb24oZmliZXIpIHtcbiAgLy8gVHJhbnNmZXIgdGltZSBzcGVudCByZW5kZXJpbmcgdGhlc2UgY2hpbGRyZW4gc28gd2UgZG9uJ3QgbG9zZSBpdFxuICAvLyBhZnRlciB3ZSByZXJlbmRlci4gVGhpcyBpcyB1c2VkIGFzIGEgaGVscGVyIGluIHNwZWNpYWwgY2FzZXNcbiAgLy8gd2hlcmUgd2Ugc2hvdWxkIGNvdW50IHRoZSB3b3JrIG9mIG11bHRpcGxlIHBhc3Nlcy5cbiAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgd2hpbGUgKGNoaWxkKSB7XG4gICAgZmliZXIuYWN0dWFsRHVyYXRpb24gKz0gY2hpbGQuYWN0dWFsRHVyYXRpb247XG4gICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNhcHR1cmVkVmFsdWUodmFsdWUsIHNvdXJjZSkge1xuICAvLyBJZiB0aGUgdmFsdWUgaXMgYW4gZXJyb3IsIGNhbGwgdGhpcyBmdW5jdGlvbiBpbW1lZGlhdGVseSBhZnRlciBpdCBpcyB0aHJvd25cbiAgLy8gc28gdGhlIHN0YWNrIGlzIGFjY3VyYXRlLlxuICByZXR1cm4ge1xuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICBzdGFjazogZ2V0U3RhY2tCeUZpYmVySW5EZXZBbmRQcm9kKHNvdXJjZSlcbiAgfTtcbn1cblxuLy8gVGhpcyBtb2R1bGUgaXMgZm9ya2VkIGluIGRpZmZlcmVudCBlbnZpcm9ubWVudHMuXG4vLyBCeSBkZWZhdWx0LCByZXR1cm4gYHRydWVgIHRvIGxvZyBlcnJvcnMgdG8gdGhlIGNvbnNvbGUuXG4vLyBGb3JrcyBjYW4gcmV0dXJuIGBmYWxzZWAgaWYgdGhpcyBpc24ndCBkZXNpcmFibGUuXG5mdW5jdGlvbiBzaG93RXJyb3JEaWFsb2coYm91bmRhcnksIGVycm9ySW5mbykge1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gbG9nQ2FwdHVyZWRFcnJvcihib3VuZGFyeSwgZXJyb3JJbmZvKSB7XG4gIHRyeSB7XG4gICAgdmFyIGxvZ0Vycm9yID0gc2hvd0Vycm9yRGlhbG9nKGJvdW5kYXJ5LCBlcnJvckluZm8pOyAvLyBBbGxvdyBpbmplY3RlZCBzaG93RXJyb3JEaWFsb2coKSB0byBwcmV2ZW50IGRlZmF1bHQgY29uc29sZS5lcnJvciBsb2dnaW5nLlxuICAgIC8vIFRoaXMgZW5hYmxlcyByZW5kZXJlcnMgbGlrZSBSZWFjdE5hdGl2ZSB0byBiZXR0ZXIgbWFuYWdlIHJlZGJveCBiZWhhdmlvci5cblxuICAgIGlmIChsb2dFcnJvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZXJyb3IgPSBlcnJvckluZm8udmFsdWU7XG5cbiAgICBpZiAodHJ1ZSkge1xuICAgICAgdmFyIHNvdXJjZSA9IGVycm9ySW5mby5zb3VyY2U7XG4gICAgICB2YXIgc3RhY2sgPSBlcnJvckluZm8uc3RhY2s7XG4gICAgICB2YXIgY29tcG9uZW50U3RhY2sgPSBzdGFjayAhPT0gbnVsbCA/IHN0YWNrIDogJyc7IC8vIEJyb3dzZXJzIHN1cHBvcnQgc2lsZW5jaW5nIHVuY2F1Z2h0IGVycm9ycyBieSBjYWxsaW5nXG4gICAgICAvLyBgcHJldmVudERlZmF1bHQoKWAgaW4gd2luZG93IGBlcnJvcmAgaGFuZGxlci5cbiAgICAgIC8vIFdlIHJlY29yZCB0aGlzIGluZm9ybWF0aW9uIGFzIGFuIGV4cGFuZG8gb24gdGhlIGVycm9yLlxuXG4gICAgICBpZiAoZXJyb3IgIT0gbnVsbCAmJiBlcnJvci5fc3VwcHJlc3NMb2dnaW5nKSB7XG4gICAgICAgIGlmIChib3VuZGFyeS50YWcgPT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgICAgICAgLy8gVGhlIGVycm9yIGlzIHJlY292ZXJhYmxlIGFuZCB3YXMgc2lsZW5jZWQuXG4gICAgICAgICAgLy8gSWdub3JlIGl0IGFuZCBkb24ndCBwcmludCB0aGUgc3RhY2sgYWRkZW5kdW0uXG4gICAgICAgICAgLy8gVGhpcyBpcyBoYW5keSBmb3IgdGVzdGluZyBlcnJvciBib3VuZGFyaWVzIHdpdGhvdXQgbm9pc2UuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IC8vIFRoZSBlcnJvciBpcyBmYXRhbC4gU2luY2UgdGhlIHNpbGVuY2luZyBtaWdodCBoYXZlXG4gICAgICAgIC8vIGJlZW4gYWNjaWRlbnRhbCwgd2UnbGwgc3VyZmFjZSBpdCBhbnl3YXkuXG4gICAgICAgIC8vIEhvd2V2ZXIsIHRoZSBicm93c2VyIHdvdWxkIGhhdmUgc2lsZW5jZWQgdGhlIG9yaWdpbmFsIGVycm9yXG4gICAgICAgIC8vIHNvIHdlJ2xsIHByaW50IGl0IGZpcnN0LCBhbmQgdGhlbiBwcmludCB0aGUgc3RhY2sgYWRkZW5kdW0uXG5cblxuICAgICAgICBjb25zb2xlWydlcnJvciddKGVycm9yKTsgLy8gRG9uJ3QgdHJhbnNmb3JtIHRvIG91ciB3cmFwcGVyXG4gICAgICAgIC8vIEZvciBhIG1vcmUgZGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhpcyBibG9jaywgc2VlOlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8xMzM4NFxuICAgICAgfVxuXG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IHNvdXJjZSA/IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoc291cmNlKSA6IG51bGw7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZU1lc3NhZ2UgPSBjb21wb25lbnROYW1lID8gXCJUaGUgYWJvdmUgZXJyb3Igb2NjdXJyZWQgaW4gdGhlIDxcIiArIGNvbXBvbmVudE5hbWUgKyBcIj4gY29tcG9uZW50OlwiIDogJ1RoZSBhYm92ZSBlcnJvciBvY2N1cnJlZCBpbiBvbmUgb2YgeW91ciBSZWFjdCBjb21wb25lbnRzOic7XG4gICAgICB2YXIgZXJyb3JCb3VuZGFyeU1lc3NhZ2U7XG5cbiAgICAgIGlmIChib3VuZGFyeS50YWcgPT09IEhvc3RSb290KSB7XG4gICAgICAgIGVycm9yQm91bmRhcnlNZXNzYWdlID0gJ0NvbnNpZGVyIGFkZGluZyBhbiBlcnJvciBib3VuZGFyeSB0byB5b3VyIHRyZWUgdG8gY3VzdG9taXplIGVycm9yIGhhbmRsaW5nIGJlaGF2aW9yLlxcbicgKyAnVmlzaXQgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2Vycm9yLWJvdW5kYXJpZXMgdG8gbGVhcm4gbW9yZSBhYm91dCBlcnJvciBib3VuZGFyaWVzLic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgZXJyb3JCb3VuZGFyeU5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGJvdW5kYXJ5KSB8fCAnQW5vbnltb3VzJztcbiAgICAgICAgZXJyb3JCb3VuZGFyeU1lc3NhZ2UgPSBcIlJlYWN0IHdpbGwgdHJ5IHRvIHJlY3JlYXRlIHRoaXMgY29tcG9uZW50IHRyZWUgZnJvbSBzY3JhdGNoIFwiICsgKFwidXNpbmcgdGhlIGVycm9yIGJvdW5kYXJ5IHlvdSBwcm92aWRlZCwgXCIgKyBlcnJvckJvdW5kYXJ5TmFtZSArIFwiLlwiKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbWJpbmVkTWVzc2FnZSA9IGNvbXBvbmVudE5hbWVNZXNzYWdlICsgXCJcXG5cIiArIGNvbXBvbmVudFN0YWNrICsgXCJcXG5cXG5cIiArIChcIlwiICsgZXJyb3JCb3VuZGFyeU1lc3NhZ2UpOyAvLyBJbiBkZXZlbG9wbWVudCwgd2UgcHJvdmlkZSBvdXIgb3duIG1lc3NhZ2Ugd2l0aCBqdXN0IHRoZSBjb21wb25lbnQgc3RhY2suXG4gICAgICAvLyBXZSBkb24ndCBpbmNsdWRlIHRoZSBvcmlnaW5hbCBlcnJvciBtZXNzYWdlIGFuZCBKUyBzdGFjayBiZWNhdXNlIHRoZSBicm93c2VyXG4gICAgICAvLyBoYXMgYWxyZWFkeSBwcmludGVkIGl0LiBFdmVuIGlmIHRoZSBhcHBsaWNhdGlvbiBzd2FsbG93cyB0aGUgZXJyb3IsIGl0IGlzIHN0aWxsXG4gICAgICAvLyBkaXNwbGF5ZWQgYnkgdGhlIGJyb3dzZXIgdGhhbmtzIHRvIHRoZSBERVYtb25seSBmYWtlIGV2ZW50IHRyaWNrIGluIFJlYWN0RXJyb3JVdGlscy5cblxuICAgICAgY29uc29sZVsnZXJyb3InXShjb21iaW5lZE1lc3NhZ2UpOyAvLyBEb24ndCB0cmFuc2Zvcm0gdG8gb3VyIHdyYXBwZXJcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSW4gcHJvZHVjdGlvbiwgd2UgcHJpbnQgdGhlIGVycm9yIGRpcmVjdGx5LlxuICAgICAgLy8gVGhpcyB3aWxsIGluY2x1ZGUgdGhlIG1lc3NhZ2UsIHRoZSBKUyBzdGFjaywgYW5kIGFueXRoaW5nIHRoZSBicm93c2VyIHdhbnRzIHRvIHNob3cuXG4gICAgICAvLyBXZSBwYXNzIHRoZSBlcnJvciBvYmplY3QgaW5zdGVhZCBvZiBjdXN0b20gbWVzc2FnZSBzbyB0aGF0IHRoZSBicm93c2VyIGRpc3BsYXlzIHRoZSBlcnJvciBuYXRpdmVseS5cbiAgICAgIGNvbnNvbGVbJ2Vycm9yJ10oZXJyb3IpOyAvLyBEb24ndCB0cmFuc2Zvcm0gdG8gb3VyIHdyYXBwZXJcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBUaGlzIG1ldGhvZCBtdXN0IG5vdCB0aHJvdywgb3IgUmVhY3QgaW50ZXJuYWwgc3RhdGUgd2lsbCBnZXQgbWVzc2VkIHVwLlxuICAgIC8vIElmIGNvbnNvbGUuZXJyb3IgaXMgb3ZlcnJpZGRlbiwgb3IgbG9nQ2FwdHVyZWRFcnJvcigpIHNob3dzIGEgZGlhbG9nIHRoYXQgdGhyb3dzLFxuICAgIC8vIHdlIHdhbnQgdG8gcmVwb3J0IHRoaXMgZXJyb3Igb3V0c2lkZSBvZiB0aGUgbm9ybWFsIHN0YWNrIGFzIGEgbGFzdCByZXNvcnQuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMzE4OFxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgZTtcbiAgICB9KTtcbiAgfVxufVxuXG52YXIgUG9zc2libHlXZWFrTWFwJDEgPSB0eXBlb2YgV2Vha01hcCA9PT0gJ2Z1bmN0aW9uJyA/IFdlYWtNYXAgOiBNYXA7XG5cbmZ1bmN0aW9uIGNyZWF0ZVJvb3RFcnJvclVwZGF0ZShmaWJlciwgZXJyb3JJbmZvLCBsYW5lKSB7XG4gIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIGxhbmUpOyAvLyBVbm1vdW50IHRoZSByb290IGJ5IHJlbmRlcmluZyBudWxsLlxuXG4gIHVwZGF0ZS50YWcgPSBDYXB0dXJlVXBkYXRlOyAvLyBDYXV0aW9uOiBSZWFjdCBEZXZUb29scyBjdXJyZW50bHkgZGVwZW5kcyBvbiB0aGlzIHByb3BlcnR5XG4gIC8vIGJlaW5nIGNhbGxlZCBcImVsZW1lbnRcIi5cblxuICB1cGRhdGUucGF5bG9hZCA9IHtcbiAgICBlbGVtZW50OiBudWxsXG4gIH07XG4gIHZhciBlcnJvciA9IGVycm9ySW5mby52YWx1ZTtcblxuICB1cGRhdGUuY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgb25VbmNhdWdodEVycm9yKGVycm9yKTtcbiAgICBsb2dDYXB0dXJlZEVycm9yKGZpYmVyLCBlcnJvckluZm8pO1xuICB9O1xuXG4gIHJldHVybiB1cGRhdGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUoZmliZXIsIGVycm9ySW5mbywgbGFuZSkge1xuICB2YXIgdXBkYXRlID0gY3JlYXRlVXBkYXRlKE5vVGltZXN0YW1wLCBsYW5lKTtcbiAgdXBkYXRlLnRhZyA9IENhcHR1cmVVcGRhdGU7XG4gIHZhciBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgPSBmaWJlci50eXBlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcjtcblxuICBpZiAodHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciBlcnJvciQxID0gZXJyb3JJbmZvLnZhbHVlO1xuXG4gICAgdXBkYXRlLnBheWxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yKGVycm9yJDEpO1xuICAgIH07XG5cbiAgICB1cGRhdGUuY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB7XG4gICAgICAgIG1hcmtGYWlsZWRFcnJvckJvdW5kYXJ5Rm9ySG90UmVsb2FkaW5nKGZpYmVyKTtcbiAgICAgIH1cblxuICAgICAgbG9nQ2FwdHVyZWRFcnJvcihmaWJlciwgZXJyb3JJbmZvKTtcbiAgICB9O1xuICB9XG5cbiAgdmFyIGluc3QgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgaWYgKGluc3QgIT09IG51bGwgJiYgdHlwZW9mIGluc3QuY29tcG9uZW50RGlkQ2F0Y2ggPT09ICdmdW5jdGlvbicpIHtcbiAgICB1cGRhdGUuY2FsbGJhY2sgPSBmdW5jdGlvbiBjYWxsYmFjaygpIHtcbiAgICAgIHtcbiAgICAgICAgbWFya0ZhaWxlZEVycm9yQm91bmRhcnlGb3JIb3RSZWxvYWRpbmcoZmliZXIpO1xuICAgICAgfVxuXG4gICAgICBsb2dDYXB0dXJlZEVycm9yKGZpYmVyLCBlcnJvckluZm8pO1xuXG4gICAgICBpZiAodHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUbyBwcmVzZXJ2ZSB0aGUgcHJlZXhpc3RpbmcgcmV0cnkgYmVoYXZpb3Igb2YgZXJyb3IgYm91bmRhcmllcyxcbiAgICAgICAgLy8gd2Uga2VlcCB0cmFjayBvZiB3aGljaCBvbmVzIGFscmVhZHkgZmFpbGVkIGR1cmluZyB0aGlzIGJhdGNoLlxuICAgICAgICAvLyBUaGlzIGdldHMgcmVzZXQgYmVmb3JlIHdlIHlpZWxkIGJhY2sgdG8gdGhlIGJyb3dzZXIuXG4gICAgICAgIC8vIFRPRE86IFdhcm4gaW4gc3RyaWN0IG1vZGUgaWYgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yIGlzXG4gICAgICAgIC8vIG5vdCBkZWZpbmVkLlxuICAgICAgICBtYXJrTGVnYWN5RXJyb3JCb3VuZGFyeUFzRmFpbGVkKHRoaXMpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZXJyb3IkMSA9IGVycm9ySW5mby52YWx1ZTtcbiAgICAgIHZhciBzdGFjayA9IGVycm9ySW5mby5zdGFjaztcbiAgICAgIHRoaXMuY29tcG9uZW50RGlkQ2F0Y2goZXJyb3IkMSwge1xuICAgICAgICBjb21wb25lbnRTdGFjazogc3RhY2sgIT09IG51bGwgPyBzdGFjayA6ICcnXG4gICAgICB9KTtcblxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIC8vIElmIGNvbXBvbmVudERpZENhdGNoIGlzIHRoZSBvbmx5IGVycm9yIGJvdW5kYXJ5IG1ldGhvZCBkZWZpbmVkLFxuICAgICAgICAgIC8vIHRoZW4gaXQgbmVlZHMgdG8gY2FsbCBzZXRTdGF0ZSB0byByZWNvdmVyIGZyb20gZXJyb3JzLlxuICAgICAgICAgIC8vIElmIG5vIHN0YXRlIHVwZGF0ZSBpcyBzY2hlZHVsZWQgdGhlbiB0aGUgYm91bmRhcnkgd2lsbCBzd2FsbG93IHRoZSBlcnJvci5cbiAgICAgICAgICBpZiAoIWluY2x1ZGVzU29tZUxhbmUoZmliZXIubGFuZXMsIFN5bmNMYW5lKSkge1xuICAgICAgICAgICAgZXJyb3IoJyVzOiBFcnJvciBib3VuZGFyaWVzIHNob3VsZCBpbXBsZW1lbnQgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yKCkuICcgKyAnSW4gdGhhdCBtZXRob2QsIHJldHVybiBhIHN0YXRlIHVwZGF0ZSB0byBkaXNwbGF5IGFuIGVycm9yIG1lc3NhZ2Ugb3IgZmFsbGJhY2sgVUkuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1Vua25vd24nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZTtcbn1cblxuZnVuY3Rpb24gYXR0YWNoUGluZ0xpc3RlbmVyKHJvb3QsIHdha2VhYmxlLCBsYW5lcykge1xuICAvLyBBdHRhY2ggYSBwaW5nIGxpc3RlbmVyXG4gIC8vXG4gIC8vIFRoZSBkYXRhIG1pZ2h0IHJlc29sdmUgYmVmb3JlIHdlIGhhdmUgYSBjaGFuY2UgdG8gY29tbWl0IHRoZSBmYWxsYmFjay4gT3IsXG4gIC8vIGluIHRoZSBjYXNlIG9mIGEgcmVmcmVzaCwgd2UnbGwgbmV2ZXIgY29tbWl0IGEgZmFsbGJhY2suIFNvIHdlIG5lZWQgdG9cbiAgLy8gYXR0YWNoIGEgbGlzdGVuZXIgbm93LiBXaGVuIGl0IHJlc29sdmVzIChcInBpbmdzXCIpLCB3ZSBjYW4gZGVjaWRlIHdoZXRoZXIgdG9cbiAgLy8gdHJ5IHJlbmRlcmluZyB0aGUgdHJlZSBhZ2Fpbi5cbiAgLy9cbiAgLy8gT25seSBhdHRhY2ggYSBsaXN0ZW5lciBpZiBvbmUgZG9lcyBub3QgYWxyZWFkeSBleGlzdCBmb3IgdGhlIGxhbmVzXG4gIC8vIHdlJ3JlIGN1cnJlbnRseSByZW5kZXJpbmcgKHdoaWNoIGFjdHMgbGlrZSBhIFwidGhyZWFkIElEXCIgaGVyZSkuXG4gIC8vXG4gIC8vIFdlIG9ubHkgbmVlZCB0byBkbyB0aGlzIGluIGNvbmN1cnJlbnQgbW9kZS4gTGVnYWN5IFN1c3BlbnNlIGFsd2F5c1xuICAvLyBjb21taXRzIGZhbGxiYWNrcyBzeW5jaHJvbm91c2x5LCBzbyB0aGVyZSBhcmUgbm8gcGluZ3MuXG4gIHZhciBwaW5nQ2FjaGUgPSByb290LnBpbmdDYWNoZTtcbiAgdmFyIHRocmVhZElEcztcblxuICBpZiAocGluZ0NhY2hlID09PSBudWxsKSB7XG4gICAgcGluZ0NhY2hlID0gcm9vdC5waW5nQ2FjaGUgPSBuZXcgUG9zc2libHlXZWFrTWFwJDEoKTtcbiAgICB0aHJlYWRJRHMgPSBuZXcgU2V0KCk7XG4gICAgcGluZ0NhY2hlLnNldCh3YWtlYWJsZSwgdGhyZWFkSURzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJlYWRJRHMgPSBwaW5nQ2FjaGUuZ2V0KHdha2VhYmxlKTtcblxuICAgIGlmICh0aHJlYWRJRHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyZWFkSURzID0gbmV3IFNldCgpO1xuICAgICAgcGluZ0NhY2hlLnNldCh3YWtlYWJsZSwgdGhyZWFkSURzKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRocmVhZElEcy5oYXMobGFuZXMpKSB7XG4gICAgLy8gTWVtb2l6ZSB1c2luZyB0aGUgdGhyZWFkIElEIHRvIHByZXZlbnQgcmVkdW5kYW50IGxpc3RlbmVycy5cbiAgICB0aHJlYWRJRHMuYWRkKGxhbmVzKTtcbiAgICB2YXIgcGluZyA9IHBpbmdTdXNwZW5kZWRSb290LmJpbmQobnVsbCwgcm9vdCwgd2FrZWFibGUsIGxhbmVzKTtcblxuICAgIHtcbiAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgd29yayBzdGlsbCwgcmVzdG9yZSB0aGUgb3JpZ2luYWwgdXBkYXRlcnNcbiAgICAgICAgcmVzdG9yZVBlbmRpbmdVcGRhdGVycyhyb290LCBsYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgd2FrZWFibGUudGhlbihwaW5nLCBwaW5nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhdHRhY2hSZXRyeUxpc3RlbmVyKHN1c3BlbnNlQm91bmRhcnksIHJvb3QsIHdha2VhYmxlLCBsYW5lcykge1xuICAvLyBSZXRyeSBsaXN0ZW5lclxuICAvL1xuICAvLyBJZiB0aGUgZmFsbGJhY2sgZG9lcyBjb21taXQsIHdlIG5lZWQgdG8gYXR0YWNoIGEgZGlmZmVyZW50IHR5cGUgb2ZcbiAgLy8gbGlzdGVuZXIuIFRoaXMgb25lIHNjaGVkdWxlcyBhbiB1cGRhdGUgb24gdGhlIFN1c3BlbnNlIGJvdW5kYXJ5IHRvIHR1cm5cbiAgLy8gdGhlIGZhbGxiYWNrIHN0YXRlIG9mZi5cbiAgLy9cbiAgLy8gU3Rhc2ggdGhlIHdha2VhYmxlIG9uIHRoZSBib3VuZGFyeSBmaWJlciBzbyB3ZSBjYW4gYWNjZXNzIGl0IGluIHRoZVxuICAvLyBjb21taXQgcGhhc2UuXG4gIC8vXG4gIC8vIFdoZW4gdGhlIHdha2VhYmxlIHJlc29sdmVzLCB3ZSdsbCBhdHRlbXB0IHRvIHJlbmRlciB0aGUgYm91bmRhcnlcbiAgLy8gYWdhaW4gKFwicmV0cnlcIikuXG4gIHZhciB3YWtlYWJsZXMgPSBzdXNwZW5zZUJvdW5kYXJ5LnVwZGF0ZVF1ZXVlO1xuXG4gIGlmICh3YWtlYWJsZXMgPT09IG51bGwpIHtcbiAgICB2YXIgdXBkYXRlUXVldWUgPSBuZXcgU2V0KCk7XG4gICAgdXBkYXRlUXVldWUuYWRkKHdha2VhYmxlKTtcbiAgICBzdXNwZW5zZUJvdW5kYXJ5LnVwZGF0ZVF1ZXVlID0gdXBkYXRlUXVldWU7XG4gIH0gZWxzZSB7XG4gICAgd2FrZWFibGVzLmFkZCh3YWtlYWJsZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzZXRTdXNwZW5kZWRDb21wb25lbnQoc291cmNlRmliZXIsIHJvb3RSZW5kZXJMYW5lcykge1xuICAvLyBBIGxlZ2FjeSBtb2RlIFN1c3BlbnNlIHF1aXJrLCBvbmx5IHJlbGV2YW50IHRvIGhvb2sgY29tcG9uZW50cy5cblxuXG4gIHZhciB0YWcgPSBzb3VyY2VGaWJlci50YWc7XG5cbiAgaWYgKChzb3VyY2VGaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgKHRhZyA9PT0gRnVuY3Rpb25Db21wb25lbnQgfHwgdGFnID09PSBGb3J3YXJkUmVmIHx8IHRhZyA9PT0gU2ltcGxlTWVtb0NvbXBvbmVudCkpIHtcbiAgICB2YXIgY3VycmVudFNvdXJjZSA9IHNvdXJjZUZpYmVyLmFsdGVybmF0ZTtcblxuICAgIGlmIChjdXJyZW50U291cmNlKSB7XG4gICAgICBzb3VyY2VGaWJlci51cGRhdGVRdWV1ZSA9IGN1cnJlbnRTb3VyY2UudXBkYXRlUXVldWU7XG4gICAgICBzb3VyY2VGaWJlci5tZW1vaXplZFN0YXRlID0gY3VycmVudFNvdXJjZS5tZW1vaXplZFN0YXRlO1xuICAgICAgc291cmNlRmliZXIubGFuZXMgPSBjdXJyZW50U291cmNlLmxhbmVzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzb3VyY2VGaWJlci51cGRhdGVRdWV1ZSA9IG51bGw7XG4gICAgICBzb3VyY2VGaWJlci5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TmVhcmVzdFN1c3BlbnNlQm91bmRhcnlUb0NhcHR1cmUocmV0dXJuRmliZXIpIHtcbiAgdmFyIG5vZGUgPSByZXR1cm5GaWJlcjtcblxuICBkbyB7XG4gICAgaWYgKG5vZGUudGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCAmJiBzaG91bGRDYXB0dXJlU3VzcGVuc2Uobm9kZSkpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH0gLy8gVGhpcyBib3VuZGFyeSBhbHJlYWR5IGNhcHR1cmVkIGR1cmluZyB0aGlzIHJlbmRlci4gQ29udGludWUgdG8gdGhlIG5leHRcbiAgICAvLyBib3VuZGFyeS5cblxuXG4gICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICB9IHdoaWxlIChub2RlICE9PSBudWxsKTtcblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gbWFya1N1c3BlbnNlQm91bmRhcnlTaG91bGRDYXB0dXJlKHN1c3BlbnNlQm91bmRhcnksIHJldHVybkZpYmVyLCBzb3VyY2VGaWJlciwgcm9vdCwgcm9vdFJlbmRlckxhbmVzKSB7XG4gIC8vIFRoaXMgbWFya3MgYSBTdXNwZW5zZSBib3VuZGFyeSBzbyB0aGF0IHdoZW4gd2UncmUgdW53aW5kaW5nIHRoZSBzdGFjayxcbiAgLy8gaXQgY2FwdHVyZXMgdGhlIHN1c3BlbmRlZCBcImV4Y2VwdGlvblwiIGFuZCBkb2VzIGEgc2Vjb25kIChmYWxsYmFjaykgcGFzcy5cbiAgaWYgKChzdXNwZW5zZUJvdW5kYXJ5Lm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgIC8vIExlZ2FjeSBNb2RlIFN1c3BlbnNlXG4gICAgLy9cbiAgICAvLyBJZiB0aGUgYm91bmRhcnkgaXMgaW4gbGVnYWN5IG1vZGUsIHdlIHNob3VsZCAqbm90KlxuICAgIC8vIHN1c3BlbmQgdGhlIGNvbW1pdC4gUHJldGVuZCBhcyBpZiB0aGUgc3VzcGVuZGVkIGNvbXBvbmVudCByZW5kZXJlZFxuICAgIC8vIG51bGwgYW5kIGtlZXAgcmVuZGVyaW5nLiBXaGVuIHRoZSBTdXNwZW5zZSBib3VuZGFyeSBjb21wbGV0ZXMsXG4gICAgLy8gd2UnbGwgZG8gYSBzZWNvbmQgcGFzcyB0byByZW5kZXIgdGhlIGZhbGxiYWNrLlxuICAgIGlmIChzdXNwZW5zZUJvdW5kYXJ5ID09PSByZXR1cm5GaWJlcikge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlIHdoZXJlIHdlIHN1c3BlbmRlZCB3aGlsZSByZWNvbmNpbGluZyB0aGUgY2hpbGRyZW4gb2ZcbiAgICAgIC8vIGEgU3VzcGVuc2UgYm91bmRhcnkncyBpbm5lciBPZmZzY3JlZW4gd3JhcHBlciBmaWJlci4gVGhpcyBoYXBwZW5zXG4gICAgICAvLyB3aGVuIGEgUmVhY3QubGF6eSBjb21wb25lbnQgaXMgYSBkaXJlY3QgY2hpbGQgb2YgYVxuICAgICAgLy8gU3VzcGVuc2UgYm91bmRhcnkuXG4gICAgICAvL1xuICAgICAgLy8gU3VzcGVuc2UgYm91bmRhcmllcyBhcmUgaW1wbGVtZW50ZWQgYXMgbXVsdGlwbGUgZmliZXJzLCBidXQgdGhleVxuICAgICAgLy8gYXJlIGEgc2luZ2xlIGNvbmNlcHR1YWwgdW5pdC4gVGhlIGxlZ2FjeSBtb2RlIGJlaGF2aW9yIHdoZXJlIHdlXG4gICAgICAvLyBwcmV0ZW5kIHRoZSBzdXNwZW5kZWQgZmliZXIgY29tbWl0dGVkIGFzIGBudWxsYCB3b24ndCB3b3JrLFxuICAgICAgLy8gYmVjYXVzZSBpbiB0aGlzIGNhc2UgdGhlIFwic3VzcGVuZGVkXCIgZmliZXIgaXMgdGhlIGlubmVyXG4gICAgICAvLyBPZmZzY3JlZW4gd3JhcHBlci5cbiAgICAgIC8vXG4gICAgICAvLyBCZWNhdXNlIHRoZSBjb250ZW50cyBvZiB0aGUgYm91bmRhcnkgaGF2ZW4ndCBzdGFydGVkIHJlbmRlcmluZ1xuICAgICAgLy8geWV0IChpLmUuIG5vdGhpbmcgaW4gdGhlIHRyZWUgaGFzIHBhcnRpYWxseSByZW5kZXJlZCkgd2UgY2FuXG4gICAgICAvLyBzd2l0Y2ggdG8gdGhlIHJlZ3VsYXIsIGNvbmN1cnJlbnQgbW9kZSBiZWhhdmlvcjogbWFyayB0aGVcbiAgICAgIC8vIGJvdW5kYXJ5IHdpdGggU2hvdWxkQ2FwdHVyZSBhbmQgZW50ZXIgdGhlIHVud2luZCBwaGFzZS5cbiAgICAgIHN1c3BlbnNlQm91bmRhcnkuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3VzcGVuc2VCb3VuZGFyeS5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgc291cmNlRmliZXIuZmxhZ3MgfD0gRm9yY2VVcGRhdGVGb3JMZWdhY3lTdXNwZW5zZTsgLy8gV2UncmUgZ29pbmcgdG8gY29tbWl0IHRoaXMgZmliZXIgZXZlbiB0aG91Z2ggaXQgZGlkbid0IGNvbXBsZXRlLlxuICAgICAgLy8gQnV0IHdlIHNob3VsZG4ndCBjYWxsIGFueSBsaWZlY3ljbGUgbWV0aG9kcyBvciBjYWxsYmFja3MuIFJlbW92ZVxuICAgICAgLy8gYWxsIGxpZmVjeWNsZSBlZmZlY3QgdGFncy5cblxuICAgICAgc291cmNlRmliZXIuZmxhZ3MgJj0gfihMaWZlY3ljbGVFZmZlY3RNYXNrIHwgSW5jb21wbGV0ZSk7XG5cbiAgICAgIGlmIChzb3VyY2VGaWJlci50YWcgPT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgICAgIHZhciBjdXJyZW50U291cmNlRmliZXIgPSBzb3VyY2VGaWJlci5hbHRlcm5hdGU7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRTb3VyY2VGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgYSBuZXcgbW91bnQuIENoYW5nZSB0aGUgdGFnIHNvIGl0J3Mgbm90IG1pc3Rha2VuIGZvciBhXG4gICAgICAgICAgLy8gY29tcGxldGVkIGNsYXNzIGNvbXBvbmVudC4gRm9yIGV4YW1wbGUsIHdlIHNob3VsZCBub3QgY2FsbFxuICAgICAgICAgIC8vIGNvbXBvbmVudFdpbGxVbm1vdW50IGlmIGl0IGlzIGRlbGV0ZWQuXG4gICAgICAgICAgc291cmNlRmliZXIudGFnID0gSW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFdoZW4gd2UgdHJ5IHJlbmRlcmluZyBhZ2Fpbiwgd2Ugc2hvdWxkIG5vdCByZXVzZSB0aGUgY3VycmVudCBmaWJlcixcbiAgICAgICAgICAvLyBzaW5jZSBpdCdzIGtub3duIHRvIGJlIGluIGFuIGluY29uc2lzdGVudCBzdGF0ZS4gVXNlIGEgZm9yY2UgdXBkYXRlIHRvXG4gICAgICAgICAgLy8gcHJldmVudCBhIGJhaWwgb3V0LlxuICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIFN5bmNMYW5lKTtcbiAgICAgICAgICB1cGRhdGUudGFnID0gRm9yY2VVcGRhdGU7XG4gICAgICAgICAgZW5xdWV1ZVVwZGF0ZShzb3VyY2VGaWJlciwgdXBkYXRlKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBUaGUgc291cmNlIGZpYmVyIGRpZCBub3QgY29tcGxldGUuIE1hcmsgaXQgd2l0aCBTeW5jIHByaW9yaXR5IHRvXG4gICAgICAvLyBpbmRpY2F0ZSB0aGF0IGl0IHN0aWxsIGhhcyBwZW5kaW5nIHdvcmsuXG5cblxuICAgICAgc291cmNlRmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKHNvdXJjZUZpYmVyLmxhbmVzLCBTeW5jTGFuZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1c3BlbnNlQm91bmRhcnk7XG4gIH0gLy8gQ29uZmlybWVkIHRoYXQgdGhlIGJvdW5kYXJ5IGlzIGluIGEgY29uY3VycmVudCBtb2RlIHRyZWUuIENvbnRpbnVlXG4gIC8vIHdpdGggdGhlIG5vcm1hbCBzdXNwZW5kIHBhdGguXG4gIC8vXG4gIC8vIEFmdGVyIHRoaXMgd2UnbGwgdXNlIGEgc2V0IG9mIGhldXJpc3RpY3MgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpc1xuICAvLyByZW5kZXIgcGFzcyB3aWxsIHJ1biB0byBjb21wbGV0aW9uIG9yIHJlc3RhcnQgb3IgXCJzdXNwZW5kXCIgdGhlIGNvbW1pdC5cbiAgLy8gVGhlIGFjdHVhbCBsb2dpYyBmb3IgdGhpcyBpcyBzcHJlYWQgb3V0IGluIGRpZmZlcmVudCBwbGFjZXMuXG4gIC8vXG4gIC8vIFRoaXMgZmlyc3QgcHJpbmNpcGxlIGlzIHRoYXQgaWYgd2UncmUgZ29pbmcgdG8gc3VzcGVuZCB3aGVuIHdlIGNvbXBsZXRlXG4gIC8vIGEgcm9vdCwgdGhlbiB3ZSBzaG91bGQgYWxzbyByZXN0YXJ0IGlmIHdlIGdldCBhbiB1cGRhdGUgb3IgcGluZyB0aGF0XG4gIC8vIG1pZ2h0IHVuc3VzcGVuZCBpdCwgYW5kIHZpY2UgdmVyc2EuIFRoZSBvbmx5IHJlYXNvbiB0byBzdXNwZW5kIGlzXG4gIC8vIGJlY2F1c2UgeW91IHRoaW5rIHlvdSBtaWdodCB3YW50IHRvIHJlc3RhcnQgYmVmb3JlIGNvbW1pdHRpbmcuIEhvd2V2ZXIsXG4gIC8vIGl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byByZXN0YXJ0IG9ubHkgd2hpbGUgaW4gdGhlIHBlcmlvZCB3ZSdyZSBzdXNwZW5kZWQuXG4gIC8vXG4gIC8vIFJlc3RhcnRpbmcgdG9vIGFnZ3Jlc3NpdmVseSBpcyBhbHNvIG5vdCBnb29kIGJlY2F1c2UgaXQgc3RhcnZlcyBvdXQgYW55XG4gIC8vIGludGVybWVkaWF0ZSBsb2FkaW5nIHN0YXRlLiBTbyB3ZSB1c2UgaGV1cmlzdGljcyB0byBkZXRlcm1pbmUgd2hlbi5cbiAgLy8gU3VzcGVuc2UgSGV1cmlzdGljc1xuICAvL1xuICAvLyBJZiBub3RoaW5nIHRocmV3IGEgUHJvbWlzZSBvciBhbGwgdGhlIHNhbWUgZmFsbGJhY2tzIGFyZSBhbHJlYWR5IHNob3dpbmcsXG4gIC8vIHRoZW4gZG9uJ3Qgc3VzcGVuZC9yZXN0YXJ0LlxuICAvL1xuICAvLyBJZiB0aGlzIGlzIGFuIGluaXRpYWwgcmVuZGVyIG9mIGEgbmV3IHRyZWUgb2YgU3VzcGVuc2UgYm91bmRhcmllcyBhbmRcbiAgLy8gdGhvc2UgdHJpZ2dlciBhIGZhbGxiYWNrLCB0aGVuIGRvbid0IHN1c3BlbmQvcmVzdGFydC4gV2Ugd2FudCB0byBlbnN1cmVcbiAgLy8gdGhhdCB3ZSBjYW4gc2hvdyB0aGUgaW5pdGlhbCBsb2FkaW5nIHN0YXRlIGFzIHF1aWNrbHkgYXMgcG9zc2libGUuXG4gIC8vXG4gIC8vIElmIHdlIGhpdCBhIFwiRGVsYXllZFwiIGNhc2UsIHN1Y2ggYXMgd2hlbiB3ZSdkIHN3aXRjaCBmcm9tIGNvbnRlbnQgYmFjayBpbnRvXG4gIC8vIGEgZmFsbGJhY2ssIHRoZW4gd2Ugc2hvdWxkIGFsd2F5cyBzdXNwZW5kL3Jlc3RhcnQuIFRyYW5zaXRpb25zIGFwcGx5XG4gIC8vIHRvIHRoaXMgY2FzZS4gSWYgbm9uZSBpcyBkZWZpbmVkLCBKTkQgaXMgdXNlZCBpbnN0ZWFkLlxuICAvL1xuICAvLyBJZiB3ZSdyZSBhbHJlYWR5IHNob3dpbmcgYSBmYWxsYmFjayBhbmQgaXQgZ2V0cyBcInJldHJpZWRcIiwgYWxsb3dpbmcgdXMgdG8gc2hvd1xuICAvLyBhbm90aGVyIGxldmVsLCBidXQgdGhlcmUncyBzdGlsbCBhbiBpbm5lciBib3VuZGFyeSB0aGF0IHdvdWxkIHNob3cgYSBmYWxsYmFjayxcbiAgLy8gdGhlbiB3ZSBzdXNwZW5kL3Jlc3RhcnQgZm9yIDUwMG1zIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2Ugc2hvd2VkIGEgZmFsbGJhY2tcbiAgLy8gYW55d2hlcmUgaW4gdGhlIHRyZWUuIFRoaXMgZWZmZWN0aXZlbHkgdGhyb3R0bGVzIHByb2dyZXNzaXZlIGxvYWRpbmcgaW50byBhXG4gIC8vIGNvbnNpc3RlbnQgdHJhaW4gb2YgY29tbWl0cy4gVGhpcyBhbHNvIGdpdmVzIHVzIGFuIG9wcG9ydHVuaXR5IHRvIHJlc3RhcnQgdG9cbiAgLy8gZ2V0IHRvIHRoZSBjb21wbGV0ZWQgc3RhdGUgc2xpZ2h0bHkgZWFybGllci5cbiAgLy9cbiAgLy8gSWYgdGhlcmUncyBhbWJpZ3VpdHkgZHVlIHRvIGJhdGNoaW5nIGl0J3MgcmVzb2x2ZWQgaW4gcHJlZmVyZW5jZSBvZjpcbiAgLy8gMSkgXCJkZWxheWVkXCIsIDIpIFwiaW5pdGlhbCByZW5kZXJcIiwgMykgXCJyZXRyeVwiLlxuICAvL1xuICAvLyBXZSB3YW50IHRvIGVuc3VyZSB0aGF0IGEgXCJidXN5XCIgc3RhdGUgZG9lc24ndCBnZXQgZm9yY2UgY29tbWl0dGVkLiBXZSB3YW50IHRvXG4gIC8vIGVuc3VyZSB0aGF0IG5ldyBpbml0aWFsIGxvYWRpbmcgc3RhdGVzIGNhbiBjb21taXQgYXMgc29vbiBhcyBwb3NzaWJsZS5cblxuXG4gIHN1c3BlbnNlQm91bmRhcnkuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTsgLy8gVE9ETzogSSB0aGluayB3ZSBjYW4gcmVtb3ZlIHRoaXMsIHNpbmNlIHdlIG5vdyB1c2UgYERpZENhcHR1cmVgIGluXG4gIC8vIHRoZSBiZWdpbiBwaGFzZSB0byBwcmV2ZW50IGFuIGVhcmx5IGJhaWxvdXQuXG5cbiAgc3VzcGVuc2VCb3VuZGFyeS5sYW5lcyA9IHJvb3RSZW5kZXJMYW5lcztcbiAgcmV0dXJuIHN1c3BlbnNlQm91bmRhcnk7XG59XG5cbmZ1bmN0aW9uIHRocm93RXhjZXB0aW9uKHJvb3QsIHJldHVybkZpYmVyLCBzb3VyY2VGaWJlciwgdmFsdWUsIHJvb3RSZW5kZXJMYW5lcykge1xuICAvLyBUaGUgc291cmNlIGZpYmVyIGRpZCBub3QgY29tcGxldGUuXG4gIHNvdXJjZUZpYmVyLmZsYWdzIHw9IEluY29tcGxldGU7XG5cbiAge1xuICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBwZW5kaW5nIHdvcmsgc3RpbGwsIHJlc3RvcmUgdGhlIG9yaWdpbmFsIHVwZGF0ZXJzXG4gICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIHJvb3RSZW5kZXJMYW5lcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBUaGlzIGlzIGEgd2FrZWFibGUuIFRoZSBjb21wb25lbnQgc3VzcGVuZGVkLlxuICAgIHZhciB3YWtlYWJsZSA9IHZhbHVlO1xuICAgIHJlc2V0U3VzcGVuZGVkQ29tcG9uZW50KHNvdXJjZUZpYmVyKTtcblxuICAgIHtcbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIHNvdXJjZUZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICBtYXJrRGlkVGhyb3dXaGlsZUh5ZHJhdGluZ0RFVigpO1xuICAgICAgfVxuICAgIH1cblxuXG4gICAgdmFyIHN1c3BlbnNlQm91bmRhcnkgPSBnZXROZWFyZXN0U3VzcGVuc2VCb3VuZGFyeVRvQ2FwdHVyZShyZXR1cm5GaWJlcik7XG5cbiAgICBpZiAoc3VzcGVuc2VCb3VuZGFyeSAhPT0gbnVsbCkge1xuICAgICAgc3VzcGVuc2VCb3VuZGFyeS5mbGFncyAmPSB+Rm9yY2VDbGllbnRSZW5kZXI7XG4gICAgICBtYXJrU3VzcGVuc2VCb3VuZGFyeVNob3VsZENhcHR1cmUoc3VzcGVuc2VCb3VuZGFyeSwgcmV0dXJuRmliZXIsIHNvdXJjZUZpYmVyLCByb290LCByb290UmVuZGVyTGFuZXMpOyAvLyBXZSBvbmx5IGF0dGFjaCBwaW5nIGxpc3RlbmVycyBpbiBjb25jdXJyZW50IG1vZGUuIExlZ2FjeSBTdXNwZW5zZSBhbHdheXNcbiAgICAgIC8vIGNvbW1pdHMgZmFsbGJhY2tzIHN5bmNocm9ub3VzbHksIHNvIHRoZXJlIGFyZSBubyBwaW5ncy5cblxuICAgICAgaWYgKHN1c3BlbnNlQm91bmRhcnkubW9kZSAmIENvbmN1cnJlbnRNb2RlKSB7XG4gICAgICAgIGF0dGFjaFBpbmdMaXN0ZW5lcihyb290LCB3YWtlYWJsZSwgcm9vdFJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgYXR0YWNoUmV0cnlMaXN0ZW5lcihzdXNwZW5zZUJvdW5kYXJ5LCByb290LCB3YWtlYWJsZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGJvdW5kYXJ5IHdhcyBmb3VuZC4gVW5sZXNzIHRoaXMgaXMgYSBzeW5jIHVwZGF0ZSwgdGhpcyBpcyBPSy5cbiAgICAgIC8vIFdlIGNhbiBzdXNwZW5kIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEgdG8gYXJyaXZlLlxuICAgICAgaWYgKCFpbmNsdWRlc1N5bmNMYW5lKHJvb3RSZW5kZXJMYW5lcykpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBub3QgYSBzeW5jIHVwZGF0ZS4gU3VzcGVuZC4gU2luY2Ugd2UncmUgbm90IGFjdGl2YXRpbmcgYVxuICAgICAgICAvLyBTdXNwZW5zZSBib3VuZGFyeSwgdGhpcyB3aWxsIHVud2luZCBhbGwgdGhlIHdheSB0byB0aGUgcm9vdCB3aXRob3V0XG4gICAgICAgIC8vIHBlcmZvcm1pbmcgYSBzZWNvbmQgcGFzcyB0byByZW5kZXIgYSBmYWxsYmFjay4gKFRoaXMgaXMgYXJndWFibHkgaG93XG4gICAgICAgIC8vIHJlZnJlc2ggdHJhbnNpdGlvbnMgc2hvdWxkIHdvcmssIHRvbywgc2luY2Ugd2UncmUgbm90IGdvaW5nIHRvIGNvbW1pdFxuICAgICAgICAvLyB0aGUgZmFsbGJhY2tzIGFueXdheS4pXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFRoaXMgY2FzZSBhbHNvIGFwcGxpZXMgdG8gaW5pdGlhbCBoeWRyYXRpb24uXG4gICAgICAgIGF0dGFjaFBpbmdMaXN0ZW5lcihyb290LCB3YWtlYWJsZSwgcm9vdFJlbmRlckxhbmVzKTtcbiAgICAgICAgcmVuZGVyRGlkU3VzcGVuZERlbGF5SWZQb3NzaWJsZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IC8vIFRoaXMgaXMgYSBzeW5jL2Rpc2NyZXRlIHVwZGF0ZS4gV2UgdHJlYXQgdGhpcyBjYXNlIGxpa2UgYW4gZXJyb3JcbiAgICAgIC8vIGJlY2F1c2UgZGlzY3JldGUgcmVuZGVycyBhcmUgZXhwZWN0ZWQgdG8gcHJvZHVjZSBhIGNvbXBsZXRlIHRyZWVcbiAgICAgIC8vIHN5bmNocm9ub3VzbHkgdG8gbWFpbnRhaW4gY29uc2lzdGVuY3kgd2l0aCBleHRlcm5hbCBzdGF0ZS5cblxuXG4gICAgICB2YXIgdW5jYXVnaHRTdXNwZW5zZUVycm9yID0gbmV3IEVycm9yKCdBIGNvbXBvbmVudCBzdXNwZW5kZWQgd2hpbGUgcmVzcG9uZGluZyB0byBzeW5jaHJvbm91cyBpbnB1dC4gVGhpcyAnICsgJ3dpbGwgY2F1c2UgdGhlIFVJIHRvIGJlIHJlcGxhY2VkIHdpdGggYSBsb2FkaW5nIGluZGljYXRvci4gVG8gJyArICdmaXgsIHVwZGF0ZXMgdGhhdCBzdXNwZW5kIHNob3VsZCBiZSB3cmFwcGVkICcgKyAnd2l0aCBzdGFydFRyYW5zaXRpb24uJyk7IC8vIElmIHdlJ3JlIG91dHNpZGUgYSB0cmFuc2l0aW9uLCBmYWxsIHRocm91Z2ggdG8gdGhlIHJlZ3VsYXIgZXJyb3IgcGF0aC5cbiAgICAgIC8vIFRoZSBlcnJvciB3aWxsIGJlIGNhdWdodCBieSB0aGUgbmVhcmVzdCBzdXNwZW5zZSBib3VuZGFyeS5cblxuICAgICAgdmFsdWUgPSB1bmNhdWdodFN1c3BlbnNlRXJyb3I7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSByZWd1bGFyIGVycm9yLCBub3QgYSBTdXNwZW5zZSB3YWtlYWJsZS5cbiAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSAmJiBzb3VyY2VGaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpIHtcbiAgICAgIG1hcmtEaWRUaHJvd1doaWxlSHlkcmF0aW5nREVWKCk7XG5cbiAgICAgIHZhciBfc3VzcGVuc2VCb3VuZGFyeSA9IGdldE5lYXJlc3RTdXNwZW5zZUJvdW5kYXJ5VG9DYXB0dXJlKHJldHVybkZpYmVyKTsgLy8gSWYgdGhlIGVycm9yIHdhcyB0aHJvd24gZHVyaW5nIGh5ZHJhdGlvbiwgd2UgbWF5IGJlIGFibGUgdG8gcmVjb3ZlciBieVxuICAgICAgLy8gZGlzY2FyZGluZyB0aGUgZGVoeWRyYXRlZCBjb250ZW50IGFuZCBzd2l0Y2hpbmcgdG8gYSBjbGllbnQgcmVuZGVyLlxuICAgICAgLy8gSW5zdGVhZCBvZiBzdXJmYWNpbmcgdGhlIGVycm9yLCBmaW5kIHRoZSBuZWFyZXN0IFN1c3BlbnNlIGJvdW5kYXJ5XG4gICAgICAvLyBhbmQgcmVuZGVyIGl0IGFnYWluIHdpdGhvdXQgaHlkcmF0aW9uLlxuXG5cbiAgICAgIGlmIChfc3VzcGVuc2VCb3VuZGFyeSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoKF9zdXNwZW5zZUJvdW5kYXJ5LmZsYWdzICYgU2hvdWxkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAvLyBTZXQgYSBmbGFnIHRvIGluZGljYXRlIHRoYXQgd2Ugc2hvdWxkIHRyeSByZW5kZXJpbmcgdGhlIG5vcm1hbFxuICAgICAgICAgIC8vIGNoaWxkcmVuIGFnYWluLCBub3QgdGhlIGZhbGxiYWNrLlxuICAgICAgICAgIF9zdXNwZW5zZUJvdW5kYXJ5LmZsYWdzIHw9IEZvcmNlQ2xpZW50UmVuZGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFya1N1c3BlbnNlQm91bmRhcnlTaG91bGRDYXB0dXJlKF9zdXNwZW5zZUJvdW5kYXJ5LCByZXR1cm5GaWJlciwgc291cmNlRmliZXIsIHJvb3QsIHJvb3RSZW5kZXJMYW5lcyk7IC8vIEV2ZW4gdGhvdWdoIHRoZSB1c2VyIG1heSBub3QgYmUgYWZmZWN0ZWQgYnkgdGhpcyBlcnJvciwgd2Ugc2hvdWxkXG4gICAgICAgIC8vIHN0aWxsIGxvZyBpdCBzbyBpdCBjYW4gYmUgZml4ZWQuXG5cbiAgICAgICAgcXVldWVIeWRyYXRpb25FcnJvcih2YWx1ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gV2UgZGlkbid0IGZpbmQgYSBib3VuZGFyeSB0aGF0IGNvdWxkIGhhbmRsZSB0aGlzIHR5cGUgb2YgZXhjZXB0aW9uLiBTdGFydFxuICAvLyBvdmVyIGFuZCB0cmF2ZXJzZSBwYXJlbnQgcGF0aCBhZ2FpbiwgdGhpcyB0aW1lIHRyZWF0aW5nIHRoZSBleGNlcHRpb25cbiAgLy8gYXMgYW4gZXJyb3IuXG5cblxuICByZW5kZXJEaWRFcnJvcih2YWx1ZSk7XG4gIHZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZSh2YWx1ZSwgc291cmNlRmliZXIpO1xuICB2YXIgd29ya0luUHJvZ3Jlc3MgPSByZXR1cm5GaWJlcjtcblxuICBkbyB7XG4gICAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgX2Vycm9ySW5mbyA9IHZhbHVlO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFNob3VsZENhcHR1cmU7XG4gICAgICAgICAgdmFyIGxhbmUgPSBwaWNrQXJiaXRyYXJ5TGFuZShyb290UmVuZGVyTGFuZXMpO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzcy5sYW5lcywgbGFuZSk7XG4gICAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVJvb3RFcnJvclVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgX2Vycm9ySW5mbywgbGFuZSk7XG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCB1cGRhdGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICAvLyBDYXB0dXJlIGFuZCByZXRyeVxuICAgICAgICB2YXIgZXJyb3JJbmZvID0gdmFsdWU7XG4gICAgICAgIHZhciBjdG9yID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmICgod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncyAmJiAodHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nIHx8IGluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiAhaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkpKSB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTtcblxuICAgICAgICAgIHZhciBfbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJvb3RSZW5kZXJMYW5lcyk7XG5cbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMsIF9sYW5lKTsgLy8gU2NoZWR1bGUgdGhlIGVycm9yIGJvdW5kYXJ5IHRvIHJlLXJlbmRlciB1c2luZyB1cGRhdGVkIHN0YXRlXG5cbiAgICAgICAgICB2YXIgX3VwZGF0ZSA9IGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUod29ya0luUHJvZ3Jlc3MsIGVycm9ySW5mbywgX2xhbmUpO1xuXG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCBfdXBkYXRlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcyA9IHdvcmtJblByb2dyZXNzLnJldHVybjtcbiAgfSB3aGlsZSAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpO1xufVxuXG5mdW5jdGlvbiBnZXRTdXNwZW5kZWRDYWNoZSgpIHtcbiAge1xuICAgIHJldHVybiBudWxsO1xuICB9IC8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYSBTdXNwZW5zZSBib3VuZGFyeSBzdXNwZW5kcy4gSXQgcmV0dXJucyB0aGVcbn1cblxuZnVuY3Rpb24gbWFya1VwZGF0ZSh3b3JrSW5Qcm9ncmVzcykge1xuICAvLyBUYWcgdGhlIGZpYmVyIHdpdGggYW4gdXBkYXRlIGVmZmVjdC4gVGhpcyB0dXJucyBhIFBsYWNlbWVudCBpbnRvXG4gIC8vIGEgUGxhY2VtZW50QW5kVXBkYXRlLlxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG59XG5cbmZ1bmN0aW9uIG1hcmtSZWYod29ya0luUHJvZ3Jlc3MpIHtcbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUmVmO1xuXG4gIHtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBSZWZTdGF0aWM7XG4gIH1cbn1cblxudmFyIGFwcGVuZEFsbENoaWxkcmVuO1xudmFyIHVwZGF0ZUhvc3RDb250YWluZXI7XG52YXIgdXBkYXRlSG9zdENvbXBvbmVudDtcbnZhciB1cGRhdGVIb3N0VGV4dDtcblxue1xuICAvLyBNdXRhdGlvbiBtb2RlXG4gIGFwcGVuZEFsbENoaWxkcmVuID0gZnVuY3Rpb24gKHBhcmVudCwgd29ya0luUHJvZ3Jlc3MsIG5lZWRzVmlzaWJpbGl0eVRvZ2dsZSwgaXNIaWRkZW4pIHtcbiAgICAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBjcmVhdGVkIGJ1dCB3ZSBuZWVkIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgdmFyIG5vZGUgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgICBpZiAobm9kZS50YWcgPT09IEhvc3RDb21wb25lbnQgfHwgbm9kZS50YWcgPT09IEhvc3RUZXh0KSB7XG4gICAgICAgIGFwcGVuZEluaXRpYWxDaGlsZChwYXJlbnQsIG5vZGUuc3RhdGVOb2RlKTtcbiAgICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IEhvc3RQb3J0YWwpIDsgZWxzZSBpZiAobm9kZS5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICBub2RlLmNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUgPT09IHdvcmtJblByb2dyZXNzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICBpZiAobm9kZS5yZXR1cm4gPT09IG51bGwgfHwgbm9kZS5yZXR1cm4gPT09IHdvcmtJblByb2dyZXNzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICAgIH1cbiAgfTtcblxuICB1cGRhdGVIb3N0Q29udGFpbmVyID0gZnVuY3Rpb24gKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7Ly8gTm9vcFxuICB9O1xuXG4gIHVwZGF0ZUhvc3RDb21wb25lbnQgPSBmdW5jdGlvbiAoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHR5cGUsIG5ld1Byb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UpIHtcbiAgICAvLyBJZiB3ZSBoYXZlIGFuIGFsdGVybmF0ZSwgdGhhdCBtZWFucyB0aGlzIGlzIGFuIHVwZGF0ZSBhbmQgd2UgbmVlZCB0b1xuICAgIC8vIHNjaGVkdWxlIGEgc2lkZS1lZmZlY3QgdG8gZG8gdGhlIHVwZGF0ZXMuXG4gICAgdmFyIG9sZFByb3BzID0gY3VycmVudC5tZW1vaXplZFByb3BzO1xuXG4gICAgaWYgKG9sZFByb3BzID09PSBuZXdQcm9wcykge1xuICAgICAgLy8gSW4gbXV0YXRpb24gbW9kZSwgdGhpcyBpcyBzdWZmaWNpZW50IGZvciBhIGJhaWxvdXQgYmVjYXVzZVxuICAgICAgLy8gd2Ugd29uJ3QgdG91Y2ggdGhpcyBub2RlIGV2ZW4gaWYgY2hpbGRyZW4gY2hhbmdlZC5cbiAgICAgIHJldHVybjtcbiAgICB9IC8vIElmIHdlIGdldCB1cGRhdGVkIGJlY2F1c2Ugb25lIG9mIG91ciBjaGlsZHJlbiB1cGRhdGVkLCB3ZSBkb24ndFxuICAgIC8vIGhhdmUgbmV3UHJvcHMgc28gd2UnbGwgaGF2ZSB0byByZXVzZSB0aGVtLlxuICAgIC8vIFRPRE86IFNwbGl0IHRoZSB1cGRhdGUgQVBJIGFzIHNlcGFyYXRlIGZvciB0aGUgcHJvcHMgdnMuIGNoaWxkcmVuLlxuICAgIC8vIEV2ZW4gYmV0dGVyIHdvdWxkIGJlIGlmIGNoaWxkcmVuIHdlcmVuJ3Qgc3BlY2lhbCBjYXNlZCBhdCBhbGwgdGhvLlxuXG5cbiAgICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgdmFyIGN1cnJlbnRIb3N0Q29udGV4dCA9IGdldEhvc3RDb250ZXh0KCk7IC8vIFRPRE86IEV4cGVyaWVuY2luZyBhbiBlcnJvciB3aGVyZSBvbGRQcm9wcyBpcyBudWxsLiBTdWdnZXN0cyBhIGhvc3RcbiAgICAvLyBjb21wb25lbnQgaXMgaGl0dGluZyB0aGUgcmVzdW1lIHBhdGguIEZpZ3VyZSBvdXQgd2h5LiBQb3NzaWJseVxuICAgIC8vIHJlbGF0ZWQgdG8gYGhpZGRlbmAuXG5cbiAgICB2YXIgdXBkYXRlUGF5bG9hZCA9IHByZXBhcmVVcGRhdGUoaW5zdGFuY2UsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBjdXJyZW50SG9zdENvbnRleHQpOyAvLyBUT0RPOiBUeXBlIHRoaXMgc3BlY2lmaWMgdG8gdGhpcyB0eXBlIG9mIGNvbXBvbmVudC5cblxuICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gdXBkYXRlUGF5bG9hZDsgLy8gSWYgdGhlIHVwZGF0ZSBwYXlsb2FkIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIGEgY2hhbmdlIG9yIGlmIHRoZXJlXG4gICAgLy8gaXMgYSBuZXcgcmVmIHdlIG1hcmsgdGhpcyBhcyBhbiB1cGRhdGUuIEFsbCB0aGUgd29yayBpcyBkb25lIGluIGNvbW1pdFdvcmsuXG5cbiAgICBpZiAodXBkYXRlUGF5bG9hZCkge1xuICAgICAgbWFya1VwZGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgfVxuICB9O1xuXG4gIHVwZGF0ZUhvc3RUZXh0ID0gZnVuY3Rpb24gKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBvbGRUZXh0LCBuZXdUZXh0KSB7XG4gICAgLy8gSWYgdGhlIHRleHQgZGlmZmVycywgbWFyayBpdCBhcyBhbiB1cGRhdGUuIEFsbCB0aGUgd29yayBpbiBkb25lIGluIGNvbW1pdFdvcmsuXG4gICAgaWYgKG9sZFRleHQgIT09IG5ld1RleHQpIHtcbiAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBoYXNSZW5kZXJlZEFUYWlsRmFsbGJhY2spIHtcbiAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAvLyBJZiB3ZSdyZSBoeWRyYXRpbmcsIHdlIHNob3VsZCBjb25zdW1lIGFzIG1hbnkgaXRlbXMgYXMgd2UgY2FuXG4gICAgLy8gc28gd2UgZG9uJ3QgbGVhdmUgYW55IGJlaGluZC5cbiAgICByZXR1cm47XG4gIH1cblxuICBzd2l0Y2ggKHJlbmRlclN0YXRlLnRhaWxNb2RlKSB7XG4gICAgY2FzZSAnaGlkZGVuJzpcbiAgICAgIHtcbiAgICAgICAgLy8gQW55IGluc2VydGlvbnMgYXQgdGhlIGVuZCBvZiB0aGUgdGFpbCBsaXN0IGFmdGVyIHRoaXMgcG9pbnRcbiAgICAgICAgLy8gc2hvdWxkIGJlIGludmlzaWJsZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkgbW91bnRlZCBib3VuZGFyaWVzXG4gICAgICAgIC8vIGFueXRoaW5nIGJlZm9yZSB0aGVtIGFyZSBub3QgY29uc2lkZXJlZCBmb3IgY29sbGFwc2luZy5cbiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCB0aGUgd2hvbGUgdGFpbCB0byBmaW5kIGlmXG4gICAgICAgIC8vIHRoZXJlIGFyZSBhbnkuXG4gICAgICAgIHZhciB0YWlsTm9kZSA9IHJlbmRlclN0YXRlLnRhaWw7XG4gICAgICAgIHZhciBsYXN0VGFpbE5vZGUgPSBudWxsO1xuXG4gICAgICAgIHdoaWxlICh0YWlsTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0YWlsTm9kZS5hbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGxhc3RUYWlsTm9kZSA9IHRhaWxOb2RlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRhaWxOb2RlID0gdGFpbE5vZGUuc2libGluZztcbiAgICAgICAgfSAvLyBOZXh0IHdlJ3JlIHNpbXBseSBnb2luZyB0byBkZWxldGUgYWxsIGluc2VydGlvbnMgYWZ0ZXIgdGhlXG4gICAgICAgIC8vIGxhc3QgcmVuZGVyZWQgaXRlbS5cblxuXG4gICAgICAgIGlmIChsYXN0VGFpbE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBBbGwgcmVtYWluaW5nIGl0ZW1zIGluIHRoZSB0YWlsIGFyZSBpbnNlcnRpb25zLlxuICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIERldGFjaCB0aGUgaW5zZXJ0aW9uIGFmdGVyIHRoZSBsYXN0IG5vZGUgdGhhdCB3YXMgYWxyZWFkeVxuICAgICAgICAgIC8vIGluc2VydGVkLlxuICAgICAgICAgIGxhc3RUYWlsTm9kZS5zaWJsaW5nID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSAnY29sbGFwc2VkJzpcbiAgICAgIHtcbiAgICAgICAgLy8gQW55IGluc2VydGlvbnMgYXQgdGhlIGVuZCBvZiB0aGUgdGFpbCBsaXN0IGFmdGVyIHRoaXMgcG9pbnRcbiAgICAgICAgLy8gc2hvdWxkIGJlIGludmlzaWJsZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkgbW91bnRlZCBib3VuZGFyaWVzXG4gICAgICAgIC8vIGFueXRoaW5nIGJlZm9yZSB0aGVtIGFyZSBub3QgY29uc2lkZXJlZCBmb3IgY29sbGFwc2luZy5cbiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCB0aGUgd2hvbGUgdGFpbCB0byBmaW5kIGlmXG4gICAgICAgIC8vIHRoZXJlIGFyZSBhbnkuXG4gICAgICAgIHZhciBfdGFpbE5vZGUgPSByZW5kZXJTdGF0ZS50YWlsO1xuICAgICAgICB2YXIgX2xhc3RUYWlsTm9kZSA9IG51bGw7XG5cbiAgICAgICAgd2hpbGUgKF90YWlsTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChfdGFpbE5vZGUuYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBfbGFzdFRhaWxOb2RlID0gX3RhaWxOb2RlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF90YWlsTm9kZSA9IF90YWlsTm9kZS5zaWJsaW5nO1xuICAgICAgICB9IC8vIE5leHQgd2UncmUgc2ltcGx5IGdvaW5nIHRvIGRlbGV0ZSBhbGwgaW5zZXJ0aW9ucyBhZnRlciB0aGVcbiAgICAgICAgLy8gbGFzdCByZW5kZXJlZCBpdGVtLlxuXG5cbiAgICAgICAgaWYgKF9sYXN0VGFpbE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBBbGwgcmVtYWluaW5nIGl0ZW1zIGluIHRoZSB0YWlsIGFyZSBpbnNlcnRpb25zLlxuICAgICAgICAgIGlmICghaGFzUmVuZGVyZWRBVGFpbEZhbGxiYWNrICYmIHJlbmRlclN0YXRlLnRhaWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFdlIHN1c3BlbmRlZCBkdXJpbmcgdGhlIGhlYWQuIFdlIHdhbnQgdG8gc2hvdyBhdCBsZWFzdCBvbmVcbiAgICAgICAgICAgIC8vIHJvdyBhdCB0aGUgdGFpbC4gU28gd2UnbGwga2VlcCBvbiBhbmQgY3V0IG9mZiB0aGUgcmVzdC5cbiAgICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXRhY2ggdGhlIGluc2VydGlvbiBhZnRlciB0aGUgbGFzdCBub2RlIHRoYXQgd2FzIGFscmVhZHlcbiAgICAgICAgICAvLyBpbnNlcnRlZC5cbiAgICAgICAgICBfbGFzdFRhaWxOb2RlLnNpYmxpbmcgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYnViYmxlUHJvcGVydGllcyhjb21wbGV0ZWRXb3JrKSB7XG4gIHZhciBkaWRCYWlsb3V0ID0gY29tcGxldGVkV29yay5hbHRlcm5hdGUgIT09IG51bGwgJiYgY29tcGxldGVkV29yay5hbHRlcm5hdGUuY2hpbGQgPT09IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG4gIHZhciBuZXdDaGlsZExhbmVzID0gTm9MYW5lcztcbiAgdmFyIHN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG5cbiAgaWYgKCFkaWRCYWlsb3V0KSB7XG4gICAgLy8gQnViYmxlIHVwIHRoZSBlYXJsaWVzdCBleHBpcmF0aW9uIHRpbWUuXG4gICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgIC8vIEluIHByb2ZpbGluZyBtb2RlLCByZXNldENoaWxkRXhwaXJhdGlvblRpbWUgaXMgYWxzbyB1c2VkIHRvIHJlc2V0XG4gICAgICAvLyBwcm9maWxlciBkdXJhdGlvbnMuXG4gICAgICB2YXIgYWN0dWFsRHVyYXRpb24gPSBjb21wbGV0ZWRXb3JrLmFjdHVhbER1cmF0aW9uO1xuICAgICAgdmFyIHRyZWVCYXNlRHVyYXRpb24gPSBjb21wbGV0ZWRXb3JrLnNlbGZCYXNlRHVyYXRpb247XG4gICAgICB2YXIgY2hpbGQgPSBjb21wbGV0ZWRXb3JrLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbmV3Q2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobmV3Q2hpbGRMYW5lcywgbWVyZ2VMYW5lcyhjaGlsZC5sYW5lcywgY2hpbGQuY2hpbGRMYW5lcykpO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gY2hpbGQuc3VidHJlZUZsYWdzO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gY2hpbGQuZmxhZ3M7IC8vIFdoZW4gYSBmaWJlciBpcyBjbG9uZWQsIGl0cyBhY3R1YWxEdXJhdGlvbiBpcyByZXNldCB0byAwLiBUaGlzIHZhbHVlIHdpbGxcbiAgICAgICAgLy8gb25seSBiZSB1cGRhdGVkIGlmIHdvcmsgaXMgZG9uZSBvbiB0aGUgZmliZXIgKGkuZS4gaXQgZG9lc24ndCBiYWlsb3V0KS5cbiAgICAgICAgLy8gV2hlbiB3b3JrIGlzIGRvbmUsIGl0IHNob3VsZCBidWJibGUgdG8gdGhlIHBhcmVudCdzIGFjdHVhbER1cmF0aW9uLiBJZlxuICAgICAgICAvLyB0aGUgZmliZXIgaGFzIG5vdCBiZWVuIGNsb25lZCB0aG91Z2gsIChtZWFuaW5nIG5vIHdvcmsgd2FzIGRvbmUpLCB0aGVuXG4gICAgICAgIC8vIHRoaXMgdmFsdWUgd2lsbCByZWZsZWN0IHRoZSBhbW91bnQgb2YgdGltZSBzcGVudCB3b3JraW5nIG9uIGEgcHJldmlvdXNcbiAgICAgICAgLy8gcmVuZGVyLiBJbiB0aGF0IGNhc2UgaXQgc2hvdWxkIG5vdCBidWJibGUuIFdlIGRldGVybWluZSB3aGV0aGVyIGl0IHdhc1xuICAgICAgICAvLyBjbG9uZWQgYnkgY29tcGFyaW5nIHRoZSBjaGlsZCBwb2ludGVyLlxuXG4gICAgICAgIGFjdHVhbER1cmF0aW9uICs9IGNoaWxkLmFjdHVhbER1cmF0aW9uO1xuICAgICAgICB0cmVlQmFzZUR1cmF0aW9uICs9IGNoaWxkLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgICAgIH1cblxuICAgICAgY29tcGxldGVkV29yay5hY3R1YWxEdXJhdGlvbiA9IGFjdHVhbER1cmF0aW9uO1xuICAgICAgY29tcGxldGVkV29yay50cmVlQmFzZUR1cmF0aW9uID0gdHJlZUJhc2VEdXJhdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9jaGlsZCA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChfY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbmV3Q2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobmV3Q2hpbGRMYW5lcywgbWVyZ2VMYW5lcyhfY2hpbGQubGFuZXMsIF9jaGlsZC5jaGlsZExhbmVzKSk7XG4gICAgICAgIHN1YnRyZWVGbGFncyB8PSBfY2hpbGQuc3VidHJlZUZsYWdzO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkLmZsYWdzOyAvLyBVcGRhdGUgdGhlIHJldHVybiBwb2ludGVyIHNvIHRoZSB0cmVlIGlzIGNvbnNpc3RlbnQuIFRoaXMgaXMgYSBjb2RlXG4gICAgICAgIC8vIHNtZWxsIGJlY2F1c2UgaXQgYXNzdW1lcyB0aGUgY29tbWl0IHBoYXNlIGlzIG5ldmVyIGNvbmN1cnJlbnQgd2l0aFxuICAgICAgICAvLyB0aGUgcmVuZGVyIHBoYXNlLiBXaWxsIGFkZHJlc3MgZHVyaW5nIHJlZmFjdG9yIHRvIGFsdGVybmF0ZSBtb2RlbC5cblxuICAgICAgICBfY2hpbGQucmV0dXJuID0gY29tcGxldGVkV29yaztcbiAgICAgICAgX2NoaWxkID0gX2NoaWxkLnNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29tcGxldGVkV29yay5zdWJ0cmVlRmxhZ3MgfD0gc3VidHJlZUZsYWdzO1xuICB9IGVsc2Uge1xuICAgIC8vIEJ1YmJsZSB1cCB0aGUgZWFybGllc3QgZXhwaXJhdGlvbiB0aW1lLlxuICAgIGlmICggKGNvbXBsZXRlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAvLyBJbiBwcm9maWxpbmcgbW9kZSwgcmVzZXRDaGlsZEV4cGlyYXRpb25UaW1lIGlzIGFsc28gdXNlZCB0byByZXNldFxuICAgICAgLy8gcHJvZmlsZXIgZHVyYXRpb25zLlxuICAgICAgdmFyIF90cmVlQmFzZUR1cmF0aW9uID0gY29tcGxldGVkV29yay5zZWxmQmFzZUR1cmF0aW9uO1xuICAgICAgdmFyIF9jaGlsZDIgPSBjb21wbGV0ZWRXb3JrLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoX2NoaWxkMiAhPT0gbnVsbCkge1xuICAgICAgICBuZXdDaGlsZExhbmVzID0gbWVyZ2VMYW5lcyhuZXdDaGlsZExhbmVzLCBtZXJnZUxhbmVzKF9jaGlsZDIubGFuZXMsIF9jaGlsZDIuY2hpbGRMYW5lcykpOyAvLyBcIlN0YXRpY1wiIGZsYWdzIHNoYXJlIHRoZSBsaWZldGltZSBvZiB0aGUgZmliZXIvaG9vayB0aGV5IGJlbG9uZyB0byxcbiAgICAgICAgLy8gc28gd2Ugc2hvdWxkIGJ1YmJsZSB0aG9zZSB1cCBldmVuIGR1cmluZyBhIGJhaWxvdXQuIEFsbCB0aGUgb3RoZXJcbiAgICAgICAgLy8gZmxhZ3MgaGF2ZSBhIGxpZmV0aW1lIG9ubHkgb2YgYSBzaW5nbGUgcmVuZGVyICsgY29tbWl0LCBzbyB3ZSBzaG91bGRcbiAgICAgICAgLy8gaWdub3JlIHRoZW0uXG5cbiAgICAgICAgc3VidHJlZUZsYWdzIHw9IF9jaGlsZDIuc3VidHJlZUZsYWdzICYgU3RhdGljTWFzaztcbiAgICAgICAgc3VidHJlZUZsYWdzIHw9IF9jaGlsZDIuZmxhZ3MgJiBTdGF0aWNNYXNrO1xuICAgICAgICBfdHJlZUJhc2VEdXJhdGlvbiArPSBfY2hpbGQyLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgIF9jaGlsZDIgPSBfY2hpbGQyLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIGNvbXBsZXRlZFdvcmsudHJlZUJhc2VEdXJhdGlvbiA9IF90cmVlQmFzZUR1cmF0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgX2NoaWxkMyA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChfY2hpbGQzICE9PSBudWxsKSB7XG4gICAgICAgIG5ld0NoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKG5ld0NoaWxkTGFuZXMsIG1lcmdlTGFuZXMoX2NoaWxkMy5sYW5lcywgX2NoaWxkMy5jaGlsZExhbmVzKSk7IC8vIFwiU3RhdGljXCIgZmxhZ3Mgc2hhcmUgdGhlIGxpZmV0aW1lIG9mIHRoZSBmaWJlci9ob29rIHRoZXkgYmVsb25nIHRvLFxuICAgICAgICAvLyBzbyB3ZSBzaG91bGQgYnViYmxlIHRob3NlIHVwIGV2ZW4gZHVyaW5nIGEgYmFpbG91dC4gQWxsIHRoZSBvdGhlclxuICAgICAgICAvLyBmbGFncyBoYXZlIGEgbGlmZXRpbWUgb25seSBvZiBhIHNpbmdsZSByZW5kZXIgKyBjb21taXQsIHNvIHdlIHNob3VsZFxuICAgICAgICAvLyBpZ25vcmUgdGhlbS5cblxuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkMy5zdWJ0cmVlRmxhZ3MgJiBTdGF0aWNNYXNrO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkMy5mbGFncyAmIFN0YXRpY01hc2s7IC8vIFVwZGF0ZSB0aGUgcmV0dXJuIHBvaW50ZXIgc28gdGhlIHRyZWUgaXMgY29uc2lzdGVudC4gVGhpcyBpcyBhIGNvZGVcbiAgICAgICAgLy8gc21lbGwgYmVjYXVzZSBpdCBhc3N1bWVzIHRoZSBjb21taXQgcGhhc2UgaXMgbmV2ZXIgY29uY3VycmVudCB3aXRoXG4gICAgICAgIC8vIHRoZSByZW5kZXIgcGhhc2UuIFdpbGwgYWRkcmVzcyBkdXJpbmcgcmVmYWN0b3IgdG8gYWx0ZXJuYXRlIG1vZGVsLlxuXG4gICAgICAgIF9jaGlsZDMucmV0dXJuID0gY29tcGxldGVkV29yaztcbiAgICAgICAgX2NoaWxkMyA9IF9jaGlsZDMuc2libGluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wbGV0ZWRXb3JrLnN1YnRyZWVGbGFncyB8PSBzdWJ0cmVlRmxhZ3M7XG4gIH1cblxuICBjb21wbGV0ZWRXb3JrLmNoaWxkTGFuZXMgPSBuZXdDaGlsZExhbmVzO1xuICByZXR1cm4gZGlkQmFpbG91dDtcbn1cblxuZnVuY3Rpb24gY29tcGxldGVXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICB2YXIgbmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7IC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuXG4gIHBvcFRyZWVDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcblxuICBzd2l0Y2ggKHdvcmtJblByb2dyZXNzLnRhZykge1xuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgRnJhZ21lbnQ6XG4gICAgY2FzZSBNb2RlOlxuICAgIGNhc2UgUHJvZmlsZXI6XG4gICAgY2FzZSBDb250ZXh0Q29uc3VtZXI6XG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBDb21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgICAgICAgcG9wQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAge1xuICAgICAgICB2YXIgZmliZXJSb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgICAgICBwb3BIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmVzZXRXb3JrSW5Qcm9ncmVzc1ZlcnNpb25zKCk7XG5cbiAgICAgICAgaWYgKGZpYmVyUm9vdC5wZW5kaW5nQ29udGV4dCkge1xuICAgICAgICAgIGZpYmVyUm9vdC5jb250ZXh0ID0gZmliZXJSb290LnBlbmRpbmdDb250ZXh0O1xuICAgICAgICAgIGZpYmVyUm9vdC5wZW5kaW5nQ29udGV4dCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LmNoaWxkID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gSWYgd2UgaHlkcmF0ZWQsIHBvcCBzbyB0aGF0IHdlIGNhbiBkZWxldGUgYW55IHJlbWFpbmluZyBjaGlsZHJlblxuICAgICAgICAgIC8vIHRoYXQgd2VyZW4ndCBoeWRyYXRlZC5cbiAgICAgICAgICB2YXIgd2FzSHlkcmF0ZWQgPSBwb3BIeWRyYXRpb25TdGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICBpZiAod2FzSHlkcmF0ZWQpIHtcbiAgICAgICAgICAgIC8vIElmIHdlIGh5ZHJhdGVkLCB0aGVuIHdlJ2xsIG5lZWQgdG8gc2NoZWR1bGUgYW4gdXBkYXRlIGZvclxuICAgICAgICAgICAgLy8gdGhlIGNvbW1pdCBzaWRlLWVmZmVjdHMgb24gdGhlIHJvb3QuXG4gICAgICAgICAgICBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgICAgICAgICBpZiAoIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBjbGllbnQgcm9vdFxuICAgICAgICAgICAgICAhcHJldlN0YXRlLmlzRGVoeWRyYXRlZCB8fCAvLyBDaGVjayBpZiB3ZSByZXZlcnRlZCB0byBjbGllbnQgcmVuZGVyaW5nIChlLmcuIGR1ZSB0byBhbiBlcnJvcilcbiAgICAgICAgICAgICAgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRm9yY2VDbGllbnRSZW5kZXIpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgICAgICAgLy8gU2NoZWR1bGUgYW4gZWZmZWN0IHRvIGNsZWFyIHRoaXMgY29udGFpbmVyIGF0IHRoZSBzdGFydCBvZiB0aGVcbiAgICAgICAgICAgICAgICAvLyBuZXh0IGNvbW1pdC4gVGhpcyBoYW5kbGVzIHRoZSBjYXNlIG9mIFJlYWN0IHJlbmRlcmluZyBpbnRvIGFcbiAgICAgICAgICAgICAgICAvLyBjb250YWluZXIgd2l0aCBwcmV2aW91cyBjaGlsZHJlbi4gSXQncyBhbHNvIHNhZmUgdG8gZG8gZm9yXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlcyB0b28sIGJlY2F1c2UgY3VycmVudC5jaGlsZCB3b3VsZCBvbmx5IGJlIG51bGwgaWYgdGhlXG4gICAgICAgICAgICAgICAgLy8gcHJldmlvdXMgcmVuZGVyIHdhcyBudWxsIChzbyB0aGUgY29udGFpbmVyIHdvdWxkIGFscmVhZHlcbiAgICAgICAgICAgICAgICAvLyBiZSBlbXB0eSkuXG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU25hcHNob3Q7IC8vIElmIHRoaXMgd2FzIGEgZm9yY2VkIGNsaWVudCByZW5kZXIsIHRoZXJlIG1heSBoYXZlIGJlZW5cbiAgICAgICAgICAgICAgICAvLyByZWNvdmVyYWJsZSBlcnJvcnMgZHVyaW5nIGZpcnN0IGh5ZHJhdGlvbiBhdHRlbXB0LiBJZiBzbywgYWRkXG4gICAgICAgICAgICAgICAgLy8gdGhlbSB0byBhIHF1ZXVlIHNvIHdlIGNhbiBsb2cgdGhlbSBpbiB0aGUgY29tbWl0IHBoYXNlLlxuXG4gICAgICAgICAgICAgICAgdXBncmFkZUh5ZHJhdGlvbkVycm9yc1RvUmVjb3ZlcmFibGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHVwZGF0ZUhvc3RDb250YWluZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wSG9zdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB2YXIgcm9vdENvbnRhaW5lckluc3RhbmNlID0gZ2V0Um9vdEhvc3RDb250YWluZXIoKTtcbiAgICAgICAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICE9PSBudWxsICYmIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgdXBkYXRlSG9zdENvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgdHlwZSwgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSk7XG5cbiAgICAgICAgICBpZiAoY3VycmVudC5yZWYgIT09IHdvcmtJblByb2dyZXNzLnJlZikge1xuICAgICAgICAgICAgbWFya1JlZih3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghbmV3UHJvcHMpIHtcbiAgICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZSBtdXN0IGhhdmUgbmV3IHByb3BzIGZvciBuZXcgbW91bnRzLiBUaGlzIGVycm9yIGlzIGxpa2VseSAnICsgJ2NhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgICB9IC8vIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIGFib3J0IHdvcmsuXG5cblxuICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgY3VycmVudEhvc3RDb250ZXh0ID0gZ2V0SG9zdENvbnRleHQoKTsgLy8gVE9ETzogTW92ZSBjcmVhdGVJbnN0YW5jZSB0byBiZWdpbldvcmsgYW5kIGtlZXAgaXQgb24gYSBjb250ZXh0XG4gICAgICAgICAgLy8gXCJzdGFja1wiIGFzIHRoZSBwYXJlbnQuIFRoZW4gYXBwZW5kIGNoaWxkcmVuIGFzIHdlIGdvIGluIGJlZ2luV29ya1xuICAgICAgICAgIC8vIG9yIGNvbXBsZXRlV29yayBkZXBlbmRpbmcgb24gd2hldGhlciB3ZSB3YW50IHRvIGFkZCB0aGVtIHRvcC0+ZG93biBvclxuICAgICAgICAgIC8vIGJvdHRvbS0+dXAuIFRvcC0+ZG93biBpcyBmYXN0ZXIgaW4gSUUxMS5cblxuICAgICAgICAgIHZhciBfd2FzSHlkcmF0ZWQgPSBwb3BIeWRyYXRpb25TdGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICBpZiAoX3dhc0h5ZHJhdGVkKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgYW5kIGNyZWF0ZUluc3RhbmNlIHN0ZXAgaW50byB0aGUgYmVnaW5QaGFzZVxuICAgICAgICAgICAgLy8gdG8gY29uc29saWRhdGUuXG4gICAgICAgICAgICBpZiAocHJlcGFyZVRvSHlkcmF0ZUhvc3RJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBjdXJyZW50SG9zdENvbnRleHQpKSB7XG4gICAgICAgICAgICAgIC8vIElmIGNoYW5nZXMgdG8gdGhlIGh5ZHJhdGVkIG5vZGUgbmVlZCB0byBiZSBhcHBsaWVkIGF0IHRoZVxuICAgICAgICAgICAgICAvLyBjb21taXQtcGhhc2Ugd2UgbWFyayB0aGlzIGFzIHN1Y2guXG4gICAgICAgICAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBjcmVhdGVJbnN0YW5jZSh0eXBlLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBjdXJyZW50SG9zdENvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICAgIGFwcGVuZEFsbENoaWxkcmVuKGluc3RhbmNlLCB3b3JrSW5Qcm9ncmVzcywgZmFsc2UsIGZhbHNlKTtcbiAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSA9IGluc3RhbmNlOyAvLyBDZXJ0YWluIHJlbmRlcmVycyByZXF1aXJlIGNvbW1pdC10aW1lIGVmZmVjdHMgZm9yIGluaXRpYWwgbW91bnQuXG4gICAgICAgICAgICAvLyAoZWcgRE9NIHJlbmRlcmVyIHN1cHBvcnRzIGF1dG8tZm9jdXMgZm9yIGNlcnRhaW4gZWxlbWVudHMpLlxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHN1Y2ggcmVuZGVyZXJzIGdldCBzY2hlZHVsZWQgZm9yIGxhdGVyIHdvcmsuXG5cbiAgICAgICAgICAgIGlmIChmaW5hbGl6ZUluaXRpYWxDaGlsZHJlbihpbnN0YW5jZSwgdHlwZSwgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgbWFya1VwZGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHdvcmtJblByb2dyZXNzLnJlZiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSByZWYgb24gYSBob3N0IG5vZGUgd2UgbmVlZCB0byBzY2hlZHVsZSBhIGNhbGxiYWNrXG4gICAgICAgICAgICBtYXJrUmVmKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAge1xuICAgICAgICB2YXIgbmV3VGV4dCA9IG5ld1Byb3BzO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICYmIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIG9sZFRleHQgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7IC8vIElmIHdlIGhhdmUgYW4gYWx0ZXJuYXRlLCB0aGF0IG1lYW5zIHRoaXMgaXMgYW4gdXBkYXRlIGFuZCB3ZSBuZWVkXG4gICAgICAgICAgLy8gdG8gc2NoZWR1bGUgYSBzaWRlLWVmZmVjdCB0byBkbyB0aGUgdXBkYXRlcy5cblxuICAgICAgICAgIHVwZGF0ZUhvc3RUZXh0KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBvbGRUZXh0LCBuZXdUZXh0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5ld1RleHQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAod29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2UgbXVzdCBoYXZlIG5ldyBwcm9wcyBmb3IgbmV3IG1vdW50cy4gVGhpcyBlcnJvciBpcyBsaWtlbHkgJyArICdjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICAgICAgfSAvLyBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSBhYm9ydCB3b3JrLlxuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIF9yb290Q29udGFpbmVySW5zdGFuY2UgPSBnZXRSb290SG9zdENvbnRhaW5lcigpO1xuXG4gICAgICAgICAgdmFyIF9jdXJyZW50SG9zdENvbnRleHQgPSBnZXRIb3N0Q29udGV4dCgpO1xuXG4gICAgICAgICAgdmFyIF93YXNIeWRyYXRlZDIgPSBwb3BIeWRyYXRpb25TdGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICBpZiAoX3dhc0h5ZHJhdGVkMikge1xuICAgICAgICAgICAgaWYgKHByZXBhcmVUb0h5ZHJhdGVIb3N0VGV4dEluc3RhbmNlKHdvcmtJblByb2dyZXNzKSkge1xuICAgICAgICAgICAgICBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID0gY3JlYXRlVGV4dEluc3RhbmNlKG5ld1RleHQsIF9yb290Q29udGFpbmVySW5zdGFuY2UsIF9jdXJyZW50SG9zdENvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBwb3BTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB2YXIgbmV4dFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgICBpZiAoaGFzVW5oeWRyYXRlZFRhaWxOb2RlcygpICYmICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUgJiYgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICByZXNldEh5ZHJhdGlvblN0YXRlKCk7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRm9yY2VDbGllbnRSZW5kZXIgfCBJbmNvbXBsZXRlIHwgU2hvdWxkQ2FwdHVyZTtcbiAgICAgICAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3M7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmV4dFN0YXRlICE9PSBudWxsICYmIG5leHRTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UgbWlnaHQgYmUgaW5zaWRlIGEgaHlkcmF0aW9uIHN0YXRlIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIHBpY2tpbmcgdXAgdGhpc1xuICAgICAgICAgIC8vIFN1c3BlbnNlIGJvdW5kYXJ5LCBhbmQgYWxzbyBhZnRlciB3ZSd2ZSByZWVudGVyZWQgaXQgZm9yIGZ1cnRoZXIgaHlkcmF0aW9uLlxuICAgICAgICAgIHZhciBfd2FzSHlkcmF0ZWQzID0gcG9wSHlkcmF0aW9uU3RhdGUod29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICAgICAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICghX3dhc0h5ZHJhdGVkMykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgZGVoeWRyYXRlZCBzdXNwZW5zZSBjb21wb25lbnQgd2FzIGNvbXBsZXRlZCB3aXRob3V0IGEgaHlkcmF0ZWQgbm9kZS4gJyArICdUaGlzIGlzIHByb2JhYmx5IGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwcmVwYXJlVG9IeWRyYXRlSG9zdFN1c3BlbnNlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgaXNUaW1lZE91dFN1c3BlbnNlID0gbmV4dFN0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzVGltZWRPdXRTdXNwZW5zZSkge1xuICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgY291bnQgdGltZSBzcGVudCBpbiBhIHRpbWVkIG91dCBTdXNwZW5zZSBzdWJ0cmVlIGFzIHBhcnQgb2YgdGhlIGJhc2UgZHVyYXRpb24uXG4gICAgICAgICAgICAgICAgICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgICAgICAgaWYgKHByaW1hcnlDaGlsZEZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWUgRmxvdyBkb2Vzbid0IHN1cHBvcnQgdHlwZSBjYXN0aW5nIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIC09IG9wZXJhdG9yXG4gICAgICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnRyZWVCYXNlRHVyYXRpb24gLT0gcHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFdlIG1pZ2h0IGhhdmUgcmVlbnRlcmVkIHRoaXMgYm91bmRhcnkgdG8gaHlkcmF0ZSBpdC4gSWYgc28sIHdlIG5lZWQgdG8gcmVzZXQgdGhlIGh5ZHJhdGlvblxuICAgICAgICAgICAgLy8gc3RhdGUgc2luY2Ugd2UncmUgbm93IGV4aXRpbmcgb3V0IG9mIGl0LiBwb3BIeWRyYXRpb25TdGF0ZSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLlxuICAgICAgICAgICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuXG4gICAgICAgICAgICBpZiAoKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAgICAgLy8gVGhpcyBib3VuZGFyeSBkaWQgbm90IHN1c3BlbmQgc28gaXQncyBub3cgaHlkcmF0ZWQgYW5kIHVuc3VzcGVuZGVkLlxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIH0gLy8gSWYgbm90aGluZyBzdXNwZW5kZWQsIHdlIG5lZWQgdG8gc2NoZWR1bGUgYW4gZWZmZWN0IHRvIG1hcmsgdGhpcyBib3VuZGFyeVxuICAgICAgICAgICAgLy8gYXMgaGF2aW5nIGh5ZHJhdGVkIHNvIGV2ZW50cyBrbm93IHRoYXQgdGhleSdyZSBmcmVlIHRvIGJlIGludm9rZWQuXG4gICAgICAgICAgICAvLyBJdCdzIGFsc28gYSBzaWduYWwgdG8gcmVwbGF5IGV2ZW50cyBhbmQgdGhlIHN1c3BlbnNlIGNhbGxiYWNrLlxuICAgICAgICAgICAgLy8gSWYgc29tZXRoaW5nIHN1c3BlbmRlZCwgc2NoZWR1bGUgYW4gZWZmZWN0IHRvIGF0dGFjaCByZXRyeSBsaXN0ZW5lcnMuXG4gICAgICAgICAgICAvLyBTbyB3ZSBtaWdodCBhcyB3ZWxsIGFsd2F5cyBtYXJrIHRoaXMuXG5cblxuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2lzVGltZWRPdXRTdXNwZW5zZSA9IG5leHRTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgICAgICAgIGlmIChfaXNUaW1lZE91dFN1c3BlbnNlKSB7XG4gICAgICAgICAgICAgICAgICAvLyBEb24ndCBjb3VudCB0aW1lIHNwZW50IGluIGEgdGltZWQgb3V0IFN1c3BlbnNlIHN1YnRyZWUgYXMgcGFydCBvZiB0aGUgYmFzZSBkdXJhdGlvbi5cbiAgICAgICAgICAgICAgICAgIHZhciBfcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgICAgICAgaWYgKF9wcmltYXJ5Q2hpbGRGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lIEZsb3cgZG9lc24ndCBzdXBwb3J0IHR5cGUgY2FzdGluZyBpbiBjb21iaW5hdGlvbiB3aXRoIHRoZSAtPSBvcGVyYXRvclxuICAgICAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uIC09IF9wcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gU3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCB0aGlzIHRyZWUuIElmIHRoaXMgd2FzIGEgZm9yY2VkIGNsaWVudCByZW5kZXIsXG4gICAgICAgIC8vIHRoZXJlIG1heSBoYXZlIGJlZW4gcmVjb3ZlcmFibGUgZXJyb3JzIGR1cmluZyBmaXJzdCBoeWRyYXRpb25cbiAgICAgICAgLy8gYXR0ZW1wdC4gSWYgc28sIGFkZCB0aGVtIHRvIGEgcXVldWUgc28gd2UgY2FuIGxvZyB0aGVtIGluIHRoZVxuICAgICAgICAvLyBjb21taXQgcGhhc2UuXG5cblxuICAgICAgICB1cGdyYWRlSHlkcmF0aW9uRXJyb3JzVG9SZWNvdmVyYWJsZSgpO1xuXG4gICAgICAgIGlmICgod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncykge1xuICAgICAgICAgIC8vIFNvbWV0aGluZyBzdXNwZW5kZWQuIFJlLXJlbmRlciB3aXRoIHRoZSBmYWxsYmFjayBjaGlsZHJlbi5cbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IHJlbmRlckxhbmVzOyAvLyBEbyBub3QgcmVzZXQgdGhlIGVmZmVjdCBsaXN0LlxuXG4gICAgICAgICAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICB0cmFuc2ZlckFjdHVhbER1cmF0aW9uKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9IC8vIERvbid0IGJ1YmJsZSBwcm9wZXJ0aWVzIGluIHRoaXMgY2FzZS5cblxuXG4gICAgICAgICAgcmV0dXJuIHdvcmtJblByb2dyZXNzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG5leHREaWRUaW1lb3V0ID0gbmV4dFN0YXRlICE9PSBudWxsO1xuICAgICAgICB2YXIgcHJldkRpZFRpbWVvdXQgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgIHBvcEh5ZHJhdGlvblN0YXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgX3ByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICBwcmV2RGlkVGltZW91dCA9IF9wcmV2U3RhdGUgIT09IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYSBwYXNzaXZlIGVmZmVjdCwgd2hpY2ggaXMgd2hlbiB3ZSBwcm9jZXNzIHRoZSB0cmFuc2l0aW9uc1xuXG5cbiAgICAgICAgaWYgKG5leHREaWRUaW1lb3V0ICE9PSBwcmV2RGlkVGltZW91dCkge1xuICAgICAgICAgIC8vIGFuIGVmZmVjdCB0byB0b2dnbGUgdGhlIHN1YnRyZWUncyB2aXNpYmlsaXR5LiBXaGVuIHdlIHN3aXRjaCBmcm9tXG4gICAgICAgICAgLy8gZmFsbGJhY2sgLT4gcHJpbWFyeSwgdGhlIGlubmVyIE9mZnNjcmVlbiBmaWJlciBzY2hlZHVsZXMgdGhpcyBlZmZlY3RcbiAgICAgICAgICAvLyBhcyBwYXJ0IG9mIGl0cyBub3JtYWwgY29tcGxldGUgcGhhc2UuIEJ1dCB3aGVuIHdlIHN3aXRjaCBmcm9tXG4gICAgICAgICAgLy8gcHJpbWFyeSAtPiBmYWxsYmFjaywgdGhlIGlubmVyIE9mZnNjcmVlbiBmaWJlciBkb2VzIG5vdCBoYXZlIGEgY29tcGxldGVcbiAgICAgICAgICAvLyBwaGFzZS4gU28gd2UgbmVlZCB0byBzY2hlZHVsZSBpdHMgZWZmZWN0IGhlcmUuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBXZSBhbHNvIHVzZSB0aGlzIGZsYWcgdG8gY29ubmVjdC9kaXNjb25uZWN0IHRoZSBlZmZlY3RzLCBidXQgdGhlIHNhbWVcbiAgICAgICAgICAvLyBsb2dpYyBhcHBsaWVzOiB3aGVuIHJlLWNvbm5lY3RpbmcsIHRoZSBPZmZzY3JlZW4gZmliZXIncyBjb21wbGV0ZVxuICAgICAgICAgIC8vIHBoYXNlIHdpbGwgaGFuZGxlIHNjaGVkdWxpbmcgdGhlIGVmZmVjdC4gSXQncyBvbmx5IHdoZW4gdGhlIGZhbGxiYWNrXG4gICAgICAgICAgLy8gaXMgYWN0aXZlIHRoYXQgd2UgaGF2ZSB0byBkbyBhbnl0aGluZyBzcGVjaWFsLlxuXG5cbiAgICAgICAgICBpZiAobmV4dERpZFRpbWVvdXQpIHtcbiAgICAgICAgICAgIHZhciBfb2Zmc2NyZWVuRmliZXIyID0gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gICAgICAgICAgICBfb2Zmc2NyZWVuRmliZXIyLmZsYWdzIHw9IFZpc2liaWxpdHk7IC8vIFRPRE86IFRoaXMgd2lsbCBzdGlsbCBzdXNwZW5kIGEgc3luY2hyb25vdXMgdHJlZSBpZiBhbnl0aGluZ1xuICAgICAgICAgICAgLy8gaW4gdGhlIGNvbmN1cnJlbnQgdHJlZSBhbHJlYWR5IHN1c3BlbmRlZCBkdXJpbmcgdGhpcyByZW5kZXIuXG4gICAgICAgICAgICAvLyBUaGlzIGlzIGEga25vd24gYnVnLlxuXG4gICAgICAgICAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgYmFjayB0byB0aHJvd0V4Y2VwdGlvbiBiZWNhdXNlIHRoaXMgaXMgdG9vIGxhdGVcbiAgICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIGxhcmdlIHRyZWUgd2hpY2ggaXMgY29tbW9uIGZvciBpbml0aWFsIGxvYWRzLiBXZVxuICAgICAgICAgICAgICAvLyBkb24ndCBrbm93IGlmIHdlIHNob3VsZCByZXN0YXJ0IGEgcmVuZGVyIG9yIG5vdCB1bnRpbCB3ZSBnZXRcbiAgICAgICAgICAgICAgLy8gdGhpcyBtYXJrZXIsIGFuZCB0aGlzIGlzIHRvbyBsYXRlLlxuICAgICAgICAgICAgICAvLyBJZiB0aGlzIHJlbmRlciBhbHJlYWR5IGhhZCBhIHBpbmcgb3IgbG93ZXIgcHJpIHVwZGF0ZXMsXG4gICAgICAgICAgICAgIC8vIGFuZCB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lIHdlIGtub3cgd2UncmUgZ29pbmcgdG8gc3VzcGVuZCB3ZVxuICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYWJsZSB0byBpbW1lZGlhdGVseSByZXN0YXJ0IGZyb20gd2l0aGluIHRocm93RXhjZXB0aW9uLlxuICAgICAgICAgICAgICB2YXIgaGFzSW52aXNpYmxlQ2hpbGRDb250ZXh0ID0gY3VycmVudCA9PT0gbnVsbCAmJiAod29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcy51bnN0YWJsZV9hdm9pZFRoaXNGYWxsYmFjayAhPT0gdHJ1ZSB8fCAhZW5hYmxlU3VzcGVuc2VBdm9pZFRoaXNGYWxsYmFjayk7XG5cbiAgICAgICAgICAgICAgaWYgKGhhc0ludmlzaWJsZUNoaWxkQ29udGV4dCB8fCBoYXNTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VTdGFja0N1cnNvci5jdXJyZW50LCBJbnZpc2libGVQYXJlbnRTdXNwZW5zZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyB3YXMgaW4gYW4gaW52aXNpYmxlIHRyZWUgb3IgYSBuZXcgcmVuZGVyLCB0aGVuIHNob3dpbmdcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGJvdW5kYXJ5IGlzIG9rLlxuICAgICAgICAgICAgICAgIHJlbmRlckRpZFN1c3BlbmQoKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIHdlJ3JlIGdvaW5nIHRvIGhhdmUgdG8gaGlkZSBjb250ZW50IHNvIHdlIHNob3VsZFxuICAgICAgICAgICAgICAgIC8vIHN1c3BlbmQgZm9yIGxvbmdlciBpZiBwb3NzaWJsZS5cbiAgICAgICAgICAgICAgICByZW5kZXJEaWRTdXNwZW5kRGVsYXlJZlBvc3NpYmxlKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgd2FrZWFibGVzID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7XG5cbiAgICAgICAgaWYgKHdha2VhYmxlcyAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vIFNjaGVkdWxlIGFuIGVmZmVjdCB0byBhdHRhY2ggYSByZXRyeSBsaXN0ZW5lciB0byB0aGUgcHJvbWlzZS5cbiAgICAgICAgICAvLyBUT0RPOiBNb3ZlIHRvIHBhc3NpdmUgcGhhc2VcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgICB7XG4gICAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgIGlmIChuZXh0RGlkVGltZW91dCkge1xuICAgICAgICAgICAgICAvLyBEb24ndCBjb3VudCB0aW1lIHNwZW50IGluIGEgdGltZWQgb3V0IFN1c3BlbnNlIHN1YnRyZWUgYXMgcGFydCBvZiB0aGUgYmFzZSBkdXJhdGlvbi5cbiAgICAgICAgICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDIgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgICBpZiAoX3ByaW1hcnlDaGlsZEZyYWdtZW50MiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWUgRmxvdyBkb2Vzbid0IHN1cHBvcnQgdHlwZSBjYXN0aW5nIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIC09IG9wZXJhdG9yXG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHJlZUJhc2VEdXJhdGlvbiAtPSBfcHJpbWFyeUNoaWxkRnJhZ21lbnQyLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgdXBkYXRlSG9zdENvbnRhaW5lcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAgIHByZXBhcmVQb3J0YWxNb3VudCh3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyk7XG4gICAgICB9XG5cbiAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjYXNlIENvbnRleHRQcm92aWRlcjpcbiAgICAgIC8vIFBvcCBwcm92aWRlciBmaWJlclxuICAgICAgdmFyIGNvbnRleHQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlLl9jb250ZXh0O1xuICAgICAgcG9wUHJvdmlkZXIoY29udGV4dCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgSW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICAvLyBTYW1lIGFzIGNsYXNzIGNvbXBvbmVudCBjYXNlLiBJIHB1dCBpdCBkb3duIGhlcmUgc28gdGhhdCB0aGUgdGFncyBhcmVcbiAgICAgICAgLy8gc2VxdWVudGlhbCB0byBlbnN1cmUgdGhpcyBzd2l0Y2ggaXMgY29tcGlsZWQgdG8gYSBqdW1wIHRhYmxlLlxuICAgICAgICB2YXIgX0NvbXBvbmVudCA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG5cbiAgICAgICAgaWYgKGlzQ29udGV4dFByb3ZpZGVyKF9Db21wb25lbnQpKSB7XG4gICAgICAgICAgcG9wQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgdmFyIHJlbmRlclN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgICBpZiAocmVuZGVyU3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBXZSdyZSBydW5uaW5nIGluIHRoZSBkZWZhdWx0LCBcImluZGVwZW5kZW50XCIgbW9kZS5cbiAgICAgICAgICAvLyBXZSBkb24ndCBkbyBhbnl0aGluZyBpbiB0aGlzIG1vZGUuXG4gICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZGlkU3VzcGVuZEFscmVhZHkgPSAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcbiAgICAgICAgdmFyIHJlbmRlcmVkVGFpbCA9IHJlbmRlclN0YXRlLnJlbmRlcmluZztcblxuICAgICAgICBpZiAocmVuZGVyZWRUYWlsID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UganVzdCByZW5kZXJlZCB0aGUgaGVhZC5cbiAgICAgICAgICBpZiAoIWRpZFN1c3BlbmRBbHJlYWR5KSB7XG4gICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCBwYXNzLiBXZSBuZWVkIHRvIGZpZ3VyZSBvdXQgaWYgYW55dGhpbmcgaXMgc3RpbGxcbiAgICAgICAgICAgIC8vIHN1c3BlbmRlZCBpbiB0aGUgcmVuZGVyZWQgc2V0LlxuICAgICAgICAgICAgLy8gSWYgbmV3IGNvbnRlbnQgdW5zdXNwZW5kZWQsIGJ1dCB0aGVyZSdzIHN0aWxsIHNvbWUgY29udGVudCB0aGF0XG4gICAgICAgICAgICAvLyBkaWRuJ3QuIFRoZW4gd2UgbmVlZCB0byBkbyBhIHNlY29uZCBwYXNzIHRoYXQgZm9yY2VzIGV2ZXJ5dGhpbmdcbiAgICAgICAgICAgIC8vIHRvIGtlZXAgc2hvd2luZyB0aGVpciBmYWxsYmFja3MuXG4gICAgICAgICAgICAvLyBXZSBtaWdodCBiZSBzdXNwZW5kZWQgaWYgc29tZXRoaW5nIGluIHRoaXMgcmVuZGVyIHBhc3Mgc3VzcGVuZGVkLCBvclxuICAgICAgICAgICAgLy8gc29tZXRoaW5nIGluIHRoZSBwcmV2aW91cyBjb21taXR0ZWQgcGFzcyBzdXNwZW5kZWQuIE90aGVyd2lzZSxcbiAgICAgICAgICAgIC8vIHRoZXJlJ3Mgbm8gY2hhbmNlIHNvIHdlIGNhbiBza2lwIHRoZSBleHBlbnNpdmUgY2FsbCB0b1xuICAgICAgICAgICAgLy8gZmluZEZpcnN0U3VzcGVuZGVkLlxuICAgICAgICAgICAgdmFyIGNhbm5vdEJlU3VzcGVuZGVkID0gcmVuZGVySGFzTm90U3VzcGVuZGVkWWV0KCkgJiYgKGN1cnJlbnQgPT09IG51bGwgfHwgKGN1cnJlbnQuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncyk7XG5cbiAgICAgICAgICAgIGlmICghY2Fubm90QmVTdXNwZW5kZWQpIHtcbiAgICAgICAgICAgICAgdmFyIHJvdyA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgICAgICAgICAgIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3VzcGVuZGVkID0gZmluZEZpcnN0U3VzcGVuZGVkKHJvdyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoc3VzcGVuZGVkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBkaWRTdXNwZW5kQWxyZWFkeSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgICAgICAgICAgICAgY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBmYWxzZSk7IC8vIElmIHRoaXMgaXMgYSBuZXdseSBzdXNwZW5kZWQgdHJlZSwgaXQgbWlnaHQgbm90IGdldCBjb21taXR0ZWQgYXNcbiAgICAgICAgICAgICAgICAgIC8vIHBhcnQgb2YgdGhlIHNlY29uZCBwYXNzLiBJbiB0aGF0IGNhc2Ugbm90aGluZyB3aWxsIHN1YnNjcmliZSB0b1xuICAgICAgICAgICAgICAgICAgLy8gaXRzIHRoZW5hYmxlcy4gSW5zdGVhZCwgd2UnbGwgdHJhbnNmZXIgaXRzIHRoZW5hYmxlcyB0byB0aGVcbiAgICAgICAgICAgICAgICAgIC8vIFN1c3BlbnNlTGlzdCBzbyB0aGF0IGl0IGNhbiByZXRyeSBpZiB0aGV5IHJlc29sdmUuXG4gICAgICAgICAgICAgICAgICAvLyBUaGVyZSBtaWdodCBiZSBtdWx0aXBsZSBvZiB0aGVzZSBpbiB0aGUgbGlzdCBidXQgc2luY2Ugd2UncmVcbiAgICAgICAgICAgICAgICAgIC8vIGdvaW5nIHRvIHdhaXQgZm9yIGFsbCBvZiB0aGVtIGFueXdheSwgaXQgZG9lc24ndCByZWFsbHkgbWF0dGVyXG4gICAgICAgICAgICAgICAgICAvLyB3aGljaCBvbmVzIGdldHMgdG8gcGluZy4gSW4gdGhlb3J5IHdlIGNvdWxkIGdldCBjbGV2ZXIgYW5kIGtlZXBcbiAgICAgICAgICAgICAgICAgIC8vIHRyYWNrIG9mIGhvdyBtYW55IGRlcGVuZGVuY2llcyByZW1haW4gYnV0IGl0IGdldHMgdHJpY2t5IGJlY2F1c2VcbiAgICAgICAgICAgICAgICAgIC8vIGluIHRoZSBtZWFudGltZSwgd2UgY2FuIGFkZC9yZW1vdmUvY2hhbmdlIGl0ZW1zIGFuZCBkZXBlbmRlbmNpZXMuXG4gICAgICAgICAgICAgICAgICAvLyBXZSBtaWdodCBiYWlsIG91dCBvZiB0aGUgbG9vcCBiZWZvcmUgZmluZGluZyBhbnkgYnV0IHRoYXRcbiAgICAgICAgICAgICAgICAgIC8vIGRvZXNuJ3QgbWF0dGVyIHNpbmNlIHRoYXQgbWVhbnMgdGhhdCB0aGUgb3RoZXIgYm91bmRhcmllcyB0aGF0XG4gICAgICAgICAgICAgICAgICAvLyB3ZSBkaWQgZmluZCBhbHJlYWR5IGhhcyB0aGVpciBsaXN0ZW5lcnMgYXR0YWNoZWQuXG5cbiAgICAgICAgICAgICAgICAgIHZhciBuZXdUaGVuYWJsZXMgPSBzdXNwZW5kZWQudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChuZXdUaGVuYWJsZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBuZXdUaGVuYWJsZXM7XG4gICAgICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbiAgICAgICAgICAgICAgICAgIH0gLy8gUmVyZW5kZXIgdGhlIHdob2xlIGxpc3QsIGJ1dCB0aGlzIHRpbWUsIHdlJ2xsIGZvcmNlIGZhbGxiYWNrc1xuICAgICAgICAgICAgICAgICAgLy8gdG8gc3RheSBpbiBwbGFjZS5cbiAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBlZmZlY3QgZmxhZ3MgYmVmb3JlIGRvaW5nIHRoZSBzZWNvbmQgcGFzcyBzaW5jZSB0aGF0J3Mgbm93IGludmFsaWQuXG4gICAgICAgICAgICAgICAgICAvLyBSZXNldCB0aGUgY2hpbGQgZmliZXJzIHRvIHRoZWlyIG9yaWdpbmFsIHN0YXRlLlxuXG5cbiAgICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG4gICAgICAgICAgICAgICAgICByZXNldENoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7IC8vIFNldCB1cCB0aGUgU3VzcGVuc2UgQ29udGV4dCB0byBmb3JjZSBzdXNwZW5zZSBhbmQgaW1tZWRpYXRlbHlcbiAgICAgICAgICAgICAgICAgIC8vIHJlcmVuZGVyIHRoZSBjaGlsZHJlbi5cblxuICAgICAgICAgICAgICAgICAgcHVzaFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc2V0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQsIEZvcmNlU3VzcGVuc2VGYWxsYmFjaykpOyAvLyBEb24ndCBidWJibGUgcHJvcGVydGllcyBpbiB0aGlzIGNhc2UuXG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByb3cgPSByb3cuc2libGluZztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVuZGVyU3RhdGUudGFpbCAhPT0gbnVsbCAmJiBub3coKSA+IGdldFJlbmRlclRhcmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAvLyBXZSBoYXZlIGFscmVhZHkgcGFzc2VkIG91ciBDUFUgZGVhZGxpbmUgYnV0IHdlIHN0aWxsIGhhdmUgcm93c1xuICAgICAgICAgICAgICAvLyBsZWZ0IGluIHRoZSB0YWlsLiBXZSdsbCBqdXN0IGdpdmUgdXAgZnVydGhlciBhdHRlbXB0cyB0byByZW5kZXJcbiAgICAgICAgICAgICAgLy8gdGhlIG1haW4gY29udGVudCBhbmQgb25seSByZW5kZXIgZmFsbGJhY2tzLlxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgICAgICAgICBkaWRTdXNwZW5kQWxyZWFkeSA9IHRydWU7XG4gICAgICAgICAgICAgIGN1dE9mZlRhaWxJZk5lZWRlZChyZW5kZXJTdGF0ZSwgZmFsc2UpOyAvLyBTaW5jZSBub3RoaW5nIGFjdHVhbGx5IHN1c3BlbmRlZCwgdGhlcmUgd2lsbCBub3RoaW5nIHRvIHBpbmcgdGhpc1xuICAgICAgICAgICAgICAvLyB0byBnZXQgaXQgc3RhcnRlZCBiYWNrIHVwIHRvIGF0dGVtcHQgdGhlIG5leHQgaXRlbS4gV2hpbGUgaW4gdGVybXNcbiAgICAgICAgICAgICAgLy8gb2YgcHJpb3JpdHkgdGhpcyB3b3JrIGhhcyB0aGUgc2FtZSBwcmlvcml0eSBhcyB0aGlzIGN1cnJlbnQgcmVuZGVyLFxuICAgICAgICAgICAgICAvLyBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBzYW1lIHRyYW5zaXRpb24gb25jZSB0aGUgdHJhbnNpdGlvbiBoYXNcbiAgICAgICAgICAgICAgLy8gY29tbWl0dGVkLiBJZiBpdCdzIHN5bmMsIHdlIHN0aWxsIHdhbnQgdG8geWllbGQgc28gdGhhdCBpdCBjYW4gYmVcbiAgICAgICAgICAgICAgLy8gcGFpbnRlZC4gQ29uY2VwdHVhbGx5LCB0aGlzIGlzIHJlYWxseSB0aGUgc2FtZSBhcyBwaW5naW5nLlxuICAgICAgICAgICAgICAvLyBXZSBjYW4gdXNlIGFueSBSZXRyeUxhbmUgZXZlbiBpZiBpdCdzIHRoZSBvbmUgY3VycmVudGx5IHJlbmRlcmluZ1xuICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSdyZSBsZWF2aW5nIGl0IGJlaGluZCBvbiB0aGlzIG5vZGUuXG5cbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBTb21lUmV0cnlMYW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdXRPZmZUYWlsSWZOZWVkZWQocmVuZGVyU3RhdGUsIGZhbHNlKTtcbiAgICAgICAgICB9IC8vIE5leHQgd2UncmUgZ29pbmcgdG8gcmVuZGVyIHRoZSB0YWlsLlxuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gQXBwZW5kIHRoZSByZW5kZXJlZCByb3cgdG8gdGhlIGNoaWxkIGxpc3QuXG4gICAgICAgICAgaWYgKCFkaWRTdXNwZW5kQWxyZWFkeSkge1xuICAgICAgICAgICAgdmFyIF9zdXNwZW5kZWQgPSBmaW5kRmlyc3RTdXNwZW5kZWQocmVuZGVyZWRUYWlsKTtcblxuICAgICAgICAgICAgaWYgKF9zdXNwZW5kZWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgICAgICAgZGlkU3VzcGVuZEFscmVhZHkgPSB0cnVlOyAvLyBFbnN1cmUgd2UgdHJhbnNmZXIgdGhlIHVwZGF0ZSBxdWV1ZSB0byB0aGUgcGFyZW50IHNvIHRoYXQgaXQgZG9lc24ndFxuICAgICAgICAgICAgICAvLyBnZXQgbG9zdCBpZiB0aGlzIHJvdyBlbmRzIHVwIGRyb3BwZWQgZHVyaW5nIGEgc2Vjb25kIHBhc3MuXG5cbiAgICAgICAgICAgICAgdmFyIF9uZXdUaGVuYWJsZXMgPSBfc3VzcGVuZGVkLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgICAgICAgIGlmIChfbmV3VGhlbmFibGVzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBfbmV3VGhlbmFibGVzO1xuICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGN1dE9mZlRhaWxJZk5lZWRlZChyZW5kZXJTdGF0ZSwgdHJ1ZSk7IC8vIFRoaXMgbWlnaHQgaGF2ZSBiZWVuIG1vZGlmaWVkLlxuXG4gICAgICAgICAgICAgIGlmIChyZW5kZXJTdGF0ZS50YWlsID09PSBudWxsICYmIHJlbmRlclN0YXRlLnRhaWxNb2RlID09PSAnaGlkZGVuJyAmJiAhcmVuZGVyZWRUYWlsLmFsdGVybmF0ZSAmJiAhZ2V0SXNIeWRyYXRpbmcoKSAvLyBXZSBkb24ndCBjdXQgaXQgaWYgd2UncmUgaHlkcmF0aW5nLlxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIC8vIFdlJ3JlIGRvbmUuXG4gICAgICAgICAgICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIC8vIFRoZSB0aW1lIGl0IHRvb2sgdG8gcmVuZGVyIGxhc3Qgcm93IGlzIGdyZWF0ZXIgdGhhbiB0aGUgcmVtYWluaW5nXG4gICAgICAgICAgICAvLyB0aW1lIHdlIGhhdmUgdG8gcmVuZGVyLiBTbyByZW5kZXJpbmcgb25lIG1vcmUgcm93IHdvdWxkIGxpa2VseVxuICAgICAgICAgICAgLy8gZXhjZWVkIGl0LlxuICAgICAgICAgICAgbm93KCkgKiAyIC0gcmVuZGVyU3RhdGUucmVuZGVyaW5nU3RhcnRUaW1lID4gZ2V0UmVuZGVyVGFyZ2V0VGltZSgpICYmIHJlbmRlckxhbmVzICE9PSBPZmZzY3JlZW5MYW5lKSB7XG4gICAgICAgICAgICAgIC8vIFdlIGhhdmUgbm93IHBhc3NlZCBvdXIgQ1BVIGRlYWRsaW5lIGFuZCB3ZSdsbCBqdXN0IGdpdmUgdXAgZnVydGhlclxuICAgICAgICAgICAgICAvLyBhdHRlbXB0cyB0byByZW5kZXIgdGhlIG1haW4gY29udGVudCBhbmQgb25seSByZW5kZXIgZmFsbGJhY2tzLlxuICAgICAgICAgICAgICAvLyBUaGUgYXNzdW1wdGlvbiBpcyB0aGF0IHRoaXMgaXMgdXN1YWxseSBmYXN0ZXIuXG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgICAgICAgIGRpZFN1c3BlbmRBbHJlYWR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBmYWxzZSk7IC8vIFNpbmNlIG5vdGhpbmcgYWN0dWFsbHkgc3VzcGVuZGVkLCB0aGVyZSB3aWxsIG5vdGhpbmcgdG8gcGluZyB0aGlzXG4gICAgICAgICAgICAgIC8vIHRvIGdldCBpdCBzdGFydGVkIGJhY2sgdXAgdG8gYXR0ZW1wdCB0aGUgbmV4dCBpdGVtLiBXaGlsZSBpbiB0ZXJtc1xuICAgICAgICAgICAgICAvLyBvZiBwcmlvcml0eSB0aGlzIHdvcmsgaGFzIHRoZSBzYW1lIHByaW9yaXR5IGFzIHRoaXMgY3VycmVudCByZW5kZXIsXG4gICAgICAgICAgICAgIC8vIGl0J3Mgbm90IHBhcnQgb2YgdGhlIHNhbWUgdHJhbnNpdGlvbiBvbmNlIHRoZSB0cmFuc2l0aW9uIGhhc1xuICAgICAgICAgICAgICAvLyBjb21taXR0ZWQuIElmIGl0J3Mgc3luYywgd2Ugc3RpbGwgd2FudCB0byB5aWVsZCBzbyB0aGF0IGl0IGNhbiBiZVxuICAgICAgICAgICAgICAvLyBwYWludGVkLiBDb25jZXB0dWFsbHksIHRoaXMgaXMgcmVhbGx5IHRoZSBzYW1lIGFzIHBpbmdpbmcuXG4gICAgICAgICAgICAgIC8vIFdlIGNhbiB1c2UgYW55IFJldHJ5TGFuZSBldmVuIGlmIGl0J3MgdGhlIG9uZSBjdXJyZW50bHkgcmVuZGVyaW5nXG4gICAgICAgICAgICAgIC8vIHNpbmNlIHdlJ3JlIGxlYXZpbmcgaXQgYmVoaW5kIG9uIHRoaXMgbm9kZS5cblxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IFNvbWVSZXRyeUxhbmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHJlbmRlclN0YXRlLmlzQmFja3dhcmRzKSB7XG4gICAgICAgICAgICAvLyBUaGUgZWZmZWN0IGxpc3Qgb2YgdGhlIGJhY2t3YXJkcyB0YWlsIHdpbGwgaGF2ZSBiZWVuIGFkZGVkXG4gICAgICAgICAgICAvLyB0byB0aGUgZW5kLiBUaGlzIGJyZWFrcyB0aGUgZ3VhcmFudGVlIHRoYXQgbGlmZS1jeWNsZXMgZmlyZSBpblxuICAgICAgICAgICAgLy8gc2libGluZyBvcmRlciBidXQgdGhhdCBpc24ndCBhIHN0cm9uZyBndWFyYW50ZWUgcHJvbWlzZWQgYnkgUmVhY3QuXG4gICAgICAgICAgICAvLyBFc3BlY2lhbGx5IHNpbmNlIHRoZXNlIG1pZ2h0IGFsc28ganVzdCBwb3AgaW4gZHVyaW5nIGZ1dHVyZSBjb21taXRzLlxuICAgICAgICAgICAgLy8gQXBwZW5kIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3QuXG4gICAgICAgICAgICByZW5kZXJlZFRhaWwuc2libGluZyA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZW5kZXJlZFRhaWw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwcmV2aW91c1NpYmxpbmcgPSByZW5kZXJTdGF0ZS5sYXN0O1xuXG4gICAgICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHByZXZpb3VzU2libGluZy5zaWJsaW5nID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZW5kZXJlZFRhaWw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlbmRlclN0YXRlLmxhc3QgPSByZW5kZXJlZFRhaWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlbmRlclN0YXRlLnRhaWwgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBXZSBzdGlsbCBoYXZlIHRhaWwgcm93cyB0byByZW5kZXIuXG4gICAgICAgICAgLy8gUG9wIGEgcm93LlxuICAgICAgICAgIHZhciBuZXh0ID0gcmVuZGVyU3RhdGUudGFpbDtcbiAgICAgICAgICByZW5kZXJTdGF0ZS5yZW5kZXJpbmcgPSBuZXh0O1xuICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBuZXh0LnNpYmxpbmc7XG4gICAgICAgICAgcmVuZGVyU3RhdGUucmVuZGVyaW5nU3RhcnRUaW1lID0gbm93KCk7XG4gICAgICAgICAgbmV4dC5zaWJsaW5nID0gbnVsbDsgLy8gUmVzdG9yZSB0aGUgY29udGV4dC5cbiAgICAgICAgICAvLyBUT0RPOiBXZSBjYW4gcHJvYmFibHkganVzdCBhdm9pZCBwb3BwaW5nIGl0IGluc3RlYWQgYW5kIG9ubHlcbiAgICAgICAgICAvLyBzZXR0aW5nIGl0IHRoZSBmaXJzdCB0aW1lIHdlIGdvIGZyb20gbm90IHN1c3BlbmRlZCB0byBzdXNwZW5kZWQuXG5cbiAgICAgICAgICB2YXIgc3VzcGVuc2VDb250ZXh0ID0gc3VzcGVuc2VTdGFja0N1cnNvci5jdXJyZW50O1xuXG4gICAgICAgICAgaWYgKGRpZFN1c3BlbmRBbHJlYWR5KSB7XG4gICAgICAgICAgICBzdXNwZW5zZUNvbnRleHQgPSBzZXRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlQ29udGV4dCwgRm9yY2VTdXNwZW5zZUZhbGxiYWNrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0RGVmYXVsdFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzdXNwZW5zZUNvbnRleHQpOyAvLyBEbyBhIHBhc3Mgb3ZlciB0aGUgbmV4dCByb3cuXG4gICAgICAgICAgLy8gRG9uJ3QgYnViYmxlIHByb3BlcnRpZXMgaW4gdGhpcyBjYXNlLlxuXG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAge1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHBvcFJlbmRlckxhbmVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgdmFyIF9uZXh0U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICAgICAgICB2YXIgbmV4dElzSGlkZGVuID0gX25leHRTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBfcHJldlN0YXRlMiA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICB2YXIgcHJldklzSGlkZGVuID0gX3ByZXZTdGF0ZTIgIT09IG51bGw7XG5cbiAgICAgICAgICBpZiAocHJldklzSGlkZGVuICE9PSBuZXh0SXNIaWRkZW4gJiYgKCAvLyBMZWdhY3lIaWRkZW4gZG9lc24ndCBkbyBhbnkgaGlkaW5nIFx1MjAxNCBpdCBvbmx5IHByZS1yZW5kZXJzLlxuICAgICAgICAgICFlbmFibGVMZWdhY3lIaWRkZW4gKSkge1xuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVmlzaWJpbGl0eTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW5leHRJc0hpZGRlbiB8fCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRG9uJ3QgYnViYmxlIHByb3BlcnRpZXMgZm9yIGhpZGRlbiBjaGlsZHJlbiB1bmxlc3Mgd2UncmUgcmVuZGVyaW5nXG4gICAgICAgICAgLy8gYXQgb2Zmc2NyZWVuIHByaW9yaXR5LlxuICAgICAgICAgIGlmIChpbmNsdWRlc1NvbWVMYW5lKHN1YnRyZWVSZW5kZXJMYW5lcywgT2Zmc2NyZWVuTGFuZSkpIHtcbiAgICAgICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZXJlIHdhcyBhbiBpbnNlcnRpb24gb3IgdXBkYXRlIGluIHRoZSBoaWRkZW4gc3VidHJlZS5cbiAgICAgICAgICAgICAgLy8gSWYgc28sIHdlIG5lZWQgdG8gaGlkZSB0aG9zZSBub2RlcyBpbiB0aGUgY29tbWl0IHBoYXNlLCBzb1xuICAgICAgICAgICAgICAvLyBzY2hlZHVsZSBhIHZpc2liaWxpdHkgZWZmZWN0LlxuICAgICAgICAgICAgICBpZiAoIHdvcmtJblByb2dyZXNzLnN1YnRyZWVGbGFncyAmIChQbGFjZW1lbnQgfCBVcGRhdGUpKSB7XG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVmlzaWJpbGl0eTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2FjaGVDb21wb25lbnQ6XG4gICAgICB7XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIFRyYWNpbmdNYXJrZXJDb21wb25lbnQ6XG4gICAgICB7XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHVuaXQgb2Ygd29yayB0YWcgKFwiICsgd29ya0luUHJvZ3Jlc3MudGFnICsgXCIpLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gXCIgKyAnUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xufVxuXG52YXIgUmVhY3RDdXJyZW50T3duZXIkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudE93bmVyO1xudmFyIGRpZFJlY2VpdmVVcGRhdGUgPSBmYWxzZTtcbnZhciBkaWRXYXJuQWJvdXRCYWRDbGFzcztcbnZhciBkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50O1xudmFyIGRpZFdhcm5BYm91dENvbnRleHRUeXBlT25GdW5jdGlvbkNvbXBvbmVudDtcbnZhciBkaWRXYXJuQWJvdXRHZXREZXJpdmVkU3RhdGVPbkZ1bmN0aW9uQ29tcG9uZW50O1xudmFyIGRpZFdhcm5BYm91dEZ1bmN0aW9uUmVmcztcbnZhciBkaWRXYXJuQWJvdXRSZWFzc2lnbmluZ1Byb3BzO1xudmFyIGRpZFdhcm5BYm91dFJldmVhbE9yZGVyO1xudmFyIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zO1xuXG57XG4gIGRpZFdhcm5BYm91dEJhZENsYXNzID0ge307XG4gIGRpZFdhcm5BYm91dE1vZHVsZVBhdHRlcm5Db21wb25lbnQgPSB7fTtcbiAgZGlkV2FybkFib3V0Q29udGV4dFR5cGVPbkZ1bmN0aW9uQ29tcG9uZW50ID0ge307XG4gIGRpZFdhcm5BYm91dEdldERlcml2ZWRTdGF0ZU9uRnVuY3Rpb25Db21wb25lbnQgPSB7fTtcbiAgZGlkV2FybkFib3V0RnVuY3Rpb25SZWZzID0ge307XG4gIGRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMgPSBmYWxzZTtcbiAgZGlkV2FybkFib3V0UmV2ZWFsT3JkZXIgPSB7fTtcbiAgZGlkV2FybkFib3V0VGFpbE9wdGlvbnMgPSB7fTtcbn1cblxuZnVuY3Rpb24gcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAvLyBJZiB0aGlzIGlzIGEgZnJlc2ggbmV3IGNvbXBvbmVudCB0aGF0IGhhc24ndCBiZWVuIHJlbmRlcmVkIHlldCwgd2VcbiAgICAvLyB3b24ndCB1cGRhdGUgaXRzIGNoaWxkIHNldCBieSBhcHBseWluZyBtaW5pbWFsIHNpZGUtZWZmZWN0cy4gSW5zdGVhZCxcbiAgICAvLyB3ZSB3aWxsIGFkZCB0aGVtIGFsbCB0byB0aGUgY2hpbGQgYmVmb3JlIGl0IGdldHMgcmVuZGVyZWQuIFRoYXQgbWVhbnNcbiAgICAvLyB3ZSBjYW4gb3B0aW1pemUgdGhpcyByZWNvbmNpbGlhdGlvbiBwYXNzIGJ5IG5vdCB0cmFja2luZyBzaWRlLWVmZmVjdHMuXG4gICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBtb3VudENoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBudWxsLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBJZiB0aGUgY3VycmVudCBjaGlsZCBpcyB0aGUgc2FtZSBhcyB0aGUgd29yayBpbiBwcm9ncmVzcywgaXQgbWVhbnMgdGhhdFxuICAgIC8vIHdlIGhhdmVuJ3QgeWV0IHN0YXJ0ZWQgYW55IHdvcmsgb24gdGhlc2UgY2hpbGRyZW4uIFRoZXJlZm9yZSwgd2UgdXNlXG4gICAgLy8gdGhlIGNsb25lIGFsZ29yaXRobSB0byBjcmVhdGUgYSBjb3B5IG9mIGFsbCB0aGUgY3VycmVudCBjaGlsZHJlbi5cbiAgICAvLyBJZiB3ZSBoYWQgYW55IHByb2dyZXNzZWQgd29yayBhbHJlYWR5LCB0aGF0IGlzIGludmFsaWQgYXQgdGhpcyBwb2ludCBzb1xuICAgIC8vIGxldCdzIHRocm93IGl0IG91dC5cbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHJlY29uY2lsZUNoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBjdXJyZW50LmNoaWxkLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JjZVVubW91bnRDdXJyZW50QW5kUmVjb25jaWxlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgZm9yayBvZiByZWNvbmNpbGVDaGlsZHJlbi4gSXQncyB1c2VkIGluIGNhc2VzIHdoZXJlIHdlXG4gIC8vIHdhbnQgdG8gcmVjb25jaWxlIHdpdGhvdXQgbWF0Y2hpbmcgYWdhaW5zdCB0aGUgZXhpc3Rpbmcgc2V0LiBUaGlzIGhhcyB0aGVcbiAgLy8gZWZmZWN0IG9mIGFsbCBjdXJyZW50IGNoaWxkcmVuIGJlaW5nIHVubW91bnRlZDsgZXZlbiBpZiB0aGUgdHlwZSBhbmQga2V5XG4gIC8vIGFyZSB0aGUgc2FtZSwgdGhlIG9sZCBjaGlsZCBpcyB1bm1vdW50ZWQgYW5kIGEgbmV3IGNoaWxkIGlzIGNyZWF0ZWQuXG4gIC8vXG4gIC8vIFRvIGRvIHRoaXMsIHdlJ3JlIGdvaW5nIHRvIGdvIHRocm91Z2ggdGhlIHJlY29uY2lsZSBhbGdvcml0aG0gdHdpY2UuIEluXG4gIC8vIHRoZSBmaXJzdCBwYXNzLCB3ZSBzY2hlZHVsZSBhIGRlbGV0aW9uIGZvciBhbGwgdGhlIGN1cnJlbnQgY2hpbGRyZW4gYnlcbiAgLy8gcGFzc2luZyBudWxsLlxuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHJlY29uY2lsZUNoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBjdXJyZW50LmNoaWxkLCBudWxsLCByZW5kZXJMYW5lcyk7IC8vIEluIHRoZSBzZWNvbmQgcGFzcywgd2UgbW91bnQgdGhlIG5ldyBjaGlsZHJlbi4gVGhlIHRyaWNrIGhlcmUgaXMgdGhhdCB3ZVxuICAvLyBwYXNzIG51bGwgaW4gcGxhY2Ugb2Ygd2hlcmUgd2UgdXN1YWxseSBwYXNzIHRoZSBjdXJyZW50IGNoaWxkIHNldC4gVGhpcyBoYXNcbiAgLy8gdGhlIGVmZmVjdCBvZiByZW1vdW50aW5nIGFsbCBjaGlsZHJlbiByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlaXJcbiAgLy8gaWRlbnRpdGllcyBtYXRjaC5cblxuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHJlY29uY2lsZUNoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBudWxsLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRm9yd2FyZFJlZihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRPRE86IGN1cnJlbnQgY2FuIGJlIG5vbi1udWxsIGhlcmUgZXZlbiBpZiB0aGUgY29tcG9uZW50XG4gIC8vIGhhc24ndCB5ZXQgbW91bnRlZC4gVGhpcyBoYXBwZW5zIGFmdGVyIHRoZSBmaXJzdCByZW5kZXIgc3VzcGVuZHMuXG4gIC8vIFdlJ2xsIG5lZWQgdG8gZmlndXJlIG91dCBpZiB0aGlzIGlzIGZpbmUgb3IgY2FuIGNhdXNlIGlzc3Vlcy5cbiAge1xuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSkge1xuICAgICAgLy8gTGF6eSBjb21wb25lbnQgcHJvcHMgY2FuJ3QgYmUgdmFsaWRhdGVkIGluIGNyZWF0ZUVsZW1lbnRcbiAgICAgIC8vIGJlY2F1c2UgdGhleSdyZSBvbmx5IGd1YXJhbnRlZWQgdG8gYmUgcmVzb2x2ZWQgaGVyZS5cbiAgICAgIHZhciBpbm5lclByb3BUeXBlcyA9IENvbXBvbmVudC5wcm9wVHlwZXM7XG5cbiAgICAgIGlmIChpbm5lclByb3BUeXBlcykge1xuICAgICAgICBjaGVja1Byb3BUeXBlcyhpbm5lclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCBwcm9wc1xuICAgICAgICAncHJvcCcsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgcmVuZGVyID0gQ29tcG9uZW50LnJlbmRlcjtcbiAgdmFyIHJlZiA9IHdvcmtJblByb2dyZXNzLnJlZjsgLy8gVGhlIHJlc3QgaXMgYSBmb3JrIG9mIHVwZGF0ZUZ1bmN0aW9uQ29tcG9uZW50XG5cbiAgdmFyIG5leHRDaGlsZHJlbjtcbiAgdmFyIGhhc0lkO1xuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cblxuICB7XG4gICAgUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50ID0gd29ya0luUHJvZ3Jlc3M7XG4gICAgc2V0SXNSZW5kZXJpbmcodHJ1ZSk7XG4gICAgbmV4dENoaWxkcmVuID0gcmVuZGVyV2l0aEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXIsIG5leHRQcm9wcywgcmVmLCByZW5kZXJMYW5lcyk7XG4gICAgaGFzSWQgPSBjaGVja0RpZFJlbmRlcklkSG9vaygpO1xuXG4gICAgaWYgKCB3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHModHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIG5leHRDaGlsZHJlbiA9IHJlbmRlcldpdGhIb29rcyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyLCBuZXh0UHJvcHMsIHJlZiwgcmVuZGVyTGFuZXMpO1xuICAgICAgICBoYXNJZCA9IGNoZWNrRGlkUmVuZGVySWRIb29rKCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyhmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2V0SXNSZW5kZXJpbmcoZmFsc2UpO1xuICB9XG5cbiAge1xuICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gIH1cblxuICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiAhZGlkUmVjZWl2ZVVwZGF0ZSkge1xuICAgIGJhaWxvdXRIb29rcyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgIHJldHVybiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gIH1cblxuICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSAmJiBoYXNJZCkge1xuICAgIHB1c2hNYXRlcmlhbGl6ZWRUcmVlSWQod29ya0luUHJvZ3Jlc3MpO1xuICB9IC8vIFJlYWN0IERldlRvb2xzIHJlYWRzIHRoaXMgZmxhZy5cblxuXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFBlcmZvcm1lZFdvcms7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVNZW1vQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICB2YXIgdHlwZSA9IENvbXBvbmVudC50eXBlO1xuXG4gICAgaWYgKGlzU2ltcGxlRnVuY3Rpb25Db21wb25lbnQodHlwZSkgJiYgQ29tcG9uZW50LmNvbXBhcmUgPT09IG51bGwgJiYgLy8gU2ltcGxlTWVtb0NvbXBvbmVudCBjb2RlcGF0aCBkb2Vzbid0IHJlc29sdmUgb3V0ZXIgcHJvcHMgZWl0aGVyLlxuICAgIENvbXBvbmVudC5kZWZhdWx0UHJvcHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIHJlc29sdmVkVHlwZSA9IHR5cGU7XG5cbiAgICAgIHtcbiAgICAgICAgcmVzb2x2ZWRUeXBlID0gcmVzb2x2ZUZ1bmN0aW9uRm9ySG90UmVsb2FkaW5nKHR5cGUpO1xuICAgICAgfSAvLyBJZiB0aGlzIGlzIGEgcGxhaW4gZnVuY3Rpb24gY29tcG9uZW50IHdpdGhvdXQgZGVmYXVsdCBwcm9wcyxcbiAgICAgIC8vIGFuZCB3aXRoIG9ubHkgdGhlIGRlZmF1bHQgc2hhbGxvdyBjb21wYXJpc29uLCB3ZSB1cGdyYWRlIGl0XG4gICAgICAvLyB0byBhIFNpbXBsZU1lbW9Db21wb25lbnQgdG8gYWxsb3cgZmFzdCBwYXRoIHVwZGF0ZXMuXG5cblxuICAgICAgd29ya0luUHJvZ3Jlc3MudGFnID0gU2ltcGxlTWVtb0NvbXBvbmVudDtcbiAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSByZXNvbHZlZFR5cGU7XG5cbiAgICAgIHtcbiAgICAgICAgdmFsaWRhdGVGdW5jdGlvbkNvbXBvbmVudEluRGV2KHdvcmtJblByb2dyZXNzLCB0eXBlKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVwZGF0ZVNpbXBsZU1lbW9Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlc29sdmVkVHlwZSwgbmV4dFByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgfVxuXG4gICAge1xuICAgICAgdmFyIGlubmVyUHJvcFR5cGVzID0gdHlwZS5wcm9wVHlwZXM7XG5cbiAgICAgIGlmIChpbm5lclByb3BUeXBlcykge1xuICAgICAgICAvLyBJbm5lciBtZW1vIGNvbXBvbmVudCBwcm9wcyBhcmVuJ3QgY3VycmVudGx5IHZhbGlkYXRlZCBpbiBjcmVhdGVFbGVtZW50LlxuICAgICAgICAvLyBXZSBjb3VsZCBtb3ZlIGl0IHRoZXJlLCBidXQgd2UnZCBzdGlsbCBuZWVkIHRoaXMgZm9yIGxhenkgY29kZSBwYXRoLlxuICAgICAgICBjaGVja1Byb3BUeXBlcyhpbm5lclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCBwcm9wc1xuICAgICAgICAncHJvcCcsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkID0gY3JlYXRlRmliZXJGcm9tVHlwZUFuZFByb3BzKENvbXBvbmVudC50eXBlLCBudWxsLCBuZXh0UHJvcHMsIHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy5tb2RlLCByZW5kZXJMYW5lcyk7XG4gICAgY2hpbGQucmVmID0gd29ya0luUHJvZ3Jlc3MucmVmO1xuICAgIGNoaWxkLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gY2hpbGQ7XG4gICAgcmV0dXJuIGNoaWxkO1xuICB9XG5cbiAge1xuICAgIHZhciBfdHlwZSA9IENvbXBvbmVudC50eXBlO1xuICAgIHZhciBfaW5uZXJQcm9wVHlwZXMgPSBfdHlwZS5wcm9wVHlwZXM7XG5cbiAgICBpZiAoX2lubmVyUHJvcFR5cGVzKSB7XG4gICAgICAvLyBJbm5lciBtZW1vIGNvbXBvbmVudCBwcm9wcyBhcmVuJ3QgY3VycmVudGx5IHZhbGlkYXRlZCBpbiBjcmVhdGVFbGVtZW50LlxuICAgICAgLy8gV2UgY291bGQgbW92ZSBpdCB0aGVyZSwgYnV0IHdlJ2Qgc3RpbGwgbmVlZCB0aGlzIGZvciBsYXp5IGNvZGUgcGF0aC5cbiAgICAgIGNoZWNrUHJvcFR5cGVzKF9pbm5lclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCBwcm9wc1xuICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoX3R5cGUpKTtcbiAgICB9XG4gIH1cblxuICB2YXIgY3VycmVudENoaWxkID0gY3VycmVudC5jaGlsZDsgLy8gVGhpcyBpcyBhbHdheXMgZXhhY3RseSBvbmUgY2hpbGRcblxuICB2YXIgaGFzU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0ID0gY2hlY2tTY2hlZHVsZWRVcGRhdGVPckNvbnRleHQoY3VycmVudCwgcmVuZGVyTGFuZXMpO1xuXG4gIGlmICghaGFzU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0KSB7XG4gICAgLy8gVGhpcyB3aWxsIGJlIHRoZSBwcm9wcyB3aXRoIHJlc29sdmVkIGRlZmF1bHRQcm9wcyxcbiAgICAvLyB1bmxpa2UgY3VycmVudC5tZW1vaXplZFByb3BzIHdoaWNoIHdpbGwgYmUgdGhlIHVucmVzb2x2ZWQgb25lcy5cbiAgICB2YXIgcHJldlByb3BzID0gY3VycmVudENoaWxkLm1lbW9pemVkUHJvcHM7IC8vIERlZmF1bHQgdG8gc2hhbGxvdyBjb21wYXJpc29uXG5cbiAgICB2YXIgY29tcGFyZSA9IENvbXBvbmVudC5jb21wYXJlO1xuICAgIGNvbXBhcmUgPSBjb21wYXJlICE9PSBudWxsID8gY29tcGFyZSA6IHNoYWxsb3dFcXVhbDtcblxuICAgIGlmIChjb21wYXJlKHByZXZQcm9wcywgbmV4dFByb3BzKSAmJiBjdXJyZW50LnJlZiA9PT0gd29ya0luUHJvZ3Jlc3MucmVmKSB7XG4gICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgIH1cbiAgfSAvLyBSZWFjdCBEZXZUb29scyByZWFkcyB0aGlzIGZsYWcuXG5cblxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQZXJmb3JtZWRXb3JrO1xuICB2YXIgbmV3Q2hpbGQgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50Q2hpbGQsIG5leHRQcm9wcyk7XG4gIG5ld0NoaWxkLnJlZiA9IHdvcmtJblByb2dyZXNzLnJlZjtcbiAgbmV3Q2hpbGQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbmV3Q2hpbGQ7XG4gIHJldHVybiBuZXdDaGlsZDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU2ltcGxlTWVtb0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRPRE86IGN1cnJlbnQgY2FuIGJlIG5vbi1udWxsIGhlcmUgZXZlbiBpZiB0aGUgY29tcG9uZW50XG4gIC8vIGhhc24ndCB5ZXQgbW91bnRlZC4gVGhpcyBoYXBwZW5zIHdoZW4gdGhlIGlubmVyIHJlbmRlciBzdXNwZW5kcy5cbiAgLy8gV2UnbGwgbmVlZCB0byBmaWd1cmUgb3V0IGlmIHRoaXMgaXMgZmluZSBvciBjYW4gY2F1c2UgaXNzdWVzLlxuICB7XG4gICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAvLyBMYXp5IGNvbXBvbmVudCBwcm9wcyBjYW4ndCBiZSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudFxuICAgICAgLy8gYmVjYXVzZSB0aGV5J3JlIG9ubHkgZ3VhcmFudGVlZCB0byBiZSByZXNvbHZlZCBoZXJlLlxuICAgICAgdmFyIG91dGVyTWVtb1R5cGUgPSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZTtcblxuICAgICAgaWYgKG91dGVyTWVtb1R5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgICAvLyBXZSB3YXJuIHdoZW4geW91IGRlZmluZSBwcm9wVHlwZXMgb24gbGF6eSgpXG4gICAgICAgIC8vIHNvIGxldCdzIGp1c3Qgc2tpcCBvdmVyIGl0IHRvIGZpbmQgbWVtbygpIG91dGVyIHdyYXBwZXIuXG4gICAgICAgIC8vIElubmVyIHByb3BzIGZvciBtZW1vIGFyZSB2YWxpZGF0ZWQgbGF0ZXIuXG4gICAgICAgIHZhciBsYXp5Q29tcG9uZW50ID0gb3V0ZXJNZW1vVHlwZTtcbiAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBvdXRlck1lbW9UeXBlID0gaW5pdChwYXlsb2FkKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIG91dGVyTWVtb1R5cGUgPSBudWxsO1xuICAgICAgICB9IC8vIElubmVyIHByb3BUeXBlcyB3aWxsIGJlIHZhbGlkYXRlZCBpbiB0aGUgZnVuY3Rpb24gY29tcG9uZW50IHBhdGguXG5cblxuICAgICAgICB2YXIgb3V0ZXJQcm9wVHlwZXMgPSBvdXRlck1lbW9UeXBlICYmIG91dGVyTWVtb1R5cGUucHJvcFR5cGVzO1xuXG4gICAgICAgIGlmIChvdXRlclByb3BUeXBlcykge1xuICAgICAgICAgIGNoZWNrUHJvcFR5cGVzKG91dGVyUHJvcFR5cGVzLCBuZXh0UHJvcHMsIC8vIFJlc29sdmVkIChTaW1wbGVNZW1vQ29tcG9uZW50IGhhcyBubyBkZWZhdWx0UHJvcHMpXG4gICAgICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUob3V0ZXJNZW1vVHlwZSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICB2YXIgcHJldlByb3BzID0gY3VycmVudC5tZW1vaXplZFByb3BzO1xuXG4gICAgaWYgKHNoYWxsb3dFcXVhbChwcmV2UHJvcHMsIG5leHRQcm9wcykgJiYgY3VycmVudC5yZWYgPT09IHdvcmtJblByb2dyZXNzLnJlZiAmJiAoIC8vIFByZXZlbnQgYmFpbG91dCBpZiB0aGUgaW1wbGVtZW50YXRpb24gY2hhbmdlZCBkdWUgdG8gaG90IHJlbG9hZC5cbiAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9PT0gY3VycmVudC50eXBlICkpIHtcbiAgICAgIGRpZFJlY2VpdmVVcGRhdGUgPSBmYWxzZTsgLy8gVGhlIHByb3BzIGFyZSBzaGFsbG93bHkgZXF1YWwuIFJldXNlIHRoZSBwcmV2aW91cyBwcm9wcyBvYmplY3QsIGxpa2Ugd2VcbiAgICAgIC8vIHdvdWxkIGR1cmluZyBhIG5vcm1hbCBmaWJlciBiYWlsb3V0LlxuICAgICAgLy9cbiAgICAgIC8vIFdlIGRvbid0IGhhdmUgc3Ryb25nIGd1YXJhbnRlZXMgdGhhdCB0aGUgcHJvcHMgb2JqZWN0IGlzIHJlZmVyZW50aWFsbHlcbiAgICAgIC8vIGVxdWFsIGR1cmluZyB1cGRhdGVzIHdoZXJlIHdlIGNhbid0IGJhaWwgb3V0IGFueXdheSBcdTIwMTQgbGlrZSBpZiB0aGUgcHJvcHNcbiAgICAgIC8vIGFyZSBzaGFsbG93bHkgZXF1YWwsIGJ1dCB0aGVyZSdzIGEgbG9jYWwgc3RhdGUgb3IgY29udGV4dCB1cGRhdGUgaW4gdGhlXG4gICAgICAvLyBzYW1lIGJhdGNoLlxuICAgICAgLy9cbiAgICAgIC8vIEhvd2V2ZXIsIGFzIGEgcHJpbmNpcGxlLCB3ZSBzaG91bGQgYWltIHRvIG1ha2UgdGhlIGJlaGF2aW9yIGNvbnNpc3RlbnRcbiAgICAgIC8vIGFjcm9zcyBkaWZmZXJlbnQgd2F5cyBvZiBtZW1vaXppbmcgYSBjb21wb25lbnQuIEZvciBleGFtcGxlLCBSZWFjdC5tZW1vXG4gICAgICAvLyBoYXMgYSBkaWZmZXJlbnQgaW50ZXJuYWwgRmliZXIgbGF5b3V0IGlmIHlvdSBwYXNzIGEgbm9ybWFsIGZ1bmN0aW9uXG4gICAgICAvLyBjb21wb25lbnQgKFNpbXBsZU1lbW9Db21wb25lbnQpIHZlcnN1cyBpZiB5b3UgcGFzcyBhIGRpZmZlcmVudCB0eXBlXG4gICAgICAvLyBsaWtlIGZvcndhcmRSZWYgKE1lbW9Db21wb25lbnQpLiBCdXQgdGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwuXG4gICAgICAvLyBXcmFwcGluZyBhIGNvbXBvbmVudCBpbiBmb3J3YXJkUmVmIChvciBSZWFjdC5sYXp5LCBldGMpIHNob3VsZG4ndFxuICAgICAgLy8gYWZmZWN0IHdoZXRoZXIgdGhlIHByb3BzIG9iamVjdCBpcyByZXVzZWQgZHVyaW5nIGEgYmFpbG91dC5cblxuICAgICAgd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzID0gbmV4dFByb3BzID0gcHJldlByb3BzO1xuXG4gICAgICBpZiAoIWNoZWNrU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0KGN1cnJlbnQsIHJlbmRlckxhbmVzKSkge1xuICAgICAgICAvLyBUaGUgcGVuZGluZyBsYW5lcyB3ZXJlIGNsZWFyZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBiZWdpbldvcmsuIFdlJ3JlXG4gICAgICAgIC8vIGFib3V0IHRvIGJhaWwgb3V0LCBidXQgdGhlcmUgbWlnaHQgYmUgb3RoZXIgbGFuZXMgdGhhdCB3ZXJlbid0XG4gICAgICAgIC8vIGluY2x1ZGVkIGluIHRoZSBjdXJyZW50IHJlbmRlci4gVXN1YWxseSwgdGhlIHByaW9yaXR5IGxldmVsIG9mIHRoZVxuICAgICAgICAvLyByZW1haW5pbmcgdXBkYXRlcyBpcyBhY2N1bXVsYXRlZCBkdXJpbmcgdGhlIGV2YWx1YXRpb24gb2YgdGhlXG4gICAgICAgIC8vIGNvbXBvbmVudCAoaS5lLiB3aGVuIHByb2Nlc3NpbmcgdGhlIHVwZGF0ZSBxdWV1ZSkuIEJ1dCBzaW5jZSBzaW5jZVxuICAgICAgICAvLyB3ZSdyZSBiYWlsaW5nIG91dCBlYXJseSAqd2l0aG91dCogZXZhbHVhdGluZyB0aGUgY29tcG9uZW50LCB3ZSBuZWVkXG4gICAgICAgIC8vIHRvIGFjY291bnQgZm9yIGl0IGhlcmUsIHRvby4gUmVzZXQgdG8gdGhlIHZhbHVlIG9mIHRoZSBjdXJyZW50IGZpYmVyLlxuICAgICAgICAvLyBOT1RFOiBUaGlzIG9ubHkgYXBwbGllcyB0byBTaW1wbGVNZW1vQ29tcG9uZW50LCBub3QgTWVtb0NvbXBvbmVudCxcbiAgICAgICAgLy8gYmVjYXVzZSBhIE1lbW9Db21wb25lbnQgZmliZXIgZG9lcyBub3QgaGF2ZSBob29rcyBvciBhbiB1cGRhdGUgcXVldWU7XG4gICAgICAgIC8vIHJhdGhlciwgaXQgd3JhcHMgYXJvdW5kIGFuIGlubmVyIGNvbXBvbmVudCwgd2hpY2ggbWF5IG9yIG1heSBub3RcbiAgICAgICAgLy8gY29udGFpbnMgaG9va3MuXG4gICAgICAgIC8vIFRPRE86IE1vdmUgdGhlIHJlc2V0IGF0IGluIGJlZ2luV29yayBvdXQgb2YgdGhlIGNvbW1vbiBwYXRoIHNvIHRoYXRcbiAgICAgICAgLy8gdGhpcyBpcyBubyBsb25nZXIgbmVjZXNzYXJ5LlxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IGN1cnJlbnQubGFuZXM7XG4gICAgICAgIHJldHVybiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9IGVsc2UgaWYgKChjdXJyZW50LmZsYWdzICYgRm9yY2VVcGRhdGVGb3JMZWdhY3lTdXNwZW5zZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSB0aGF0IG9ubHkgZXhpc3RzIGZvciBsZWdhY3kgbW9kZS5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzE5MjE2LlxuICAgICAgICBkaWRSZWNlaXZlVXBkYXRlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU9mZnNjcmVlbkNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG5leHRQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcbiAgdmFyIG5leHRDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Lm1lbW9pemVkU3RhdGUgOiBudWxsO1xuXG4gIGlmIChuZXh0UHJvcHMubW9kZSA9PT0gJ2hpZGRlbicgfHwgZW5hYmxlTGVnYWN5SGlkZGVuICkge1xuICAgIC8vIFJlbmRlcmluZyBhIGhpZGRlbiB0cmVlLlxuICAgIGlmICgod29ya0luUHJvZ3Jlc3MubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgICAvLyBJbiBsZWdhY3kgc3luYyBtb2RlLCBkb24ndCBkZWZlciB0aGUgc3VidHJlZS4gUmVuZGVyIGl0IG5vdy5cbiAgICAgIC8vIFRPRE86IENvbnNpZGVyIGhvdyBPZmZzY3JlZW4gc2hvdWxkIHdvcmsgd2l0aCB0cmFuc2l0aW9ucyBpbiB0aGUgZnV0dXJlXG4gICAgICB2YXIgbmV4dFN0YXRlID0ge1xuICAgICAgICBiYXNlTGFuZXM6IE5vTGFuZXMsXG4gICAgICAgIGNhY2hlUG9vbDogbnVsbCxcbiAgICAgICAgdHJhbnNpdGlvbnM6IG51bGxcbiAgICAgIH07XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbmV4dFN0YXRlO1xuXG4gICAgICBwdXNoUmVuZGVyTGFuZXMod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICB9IGVsc2UgaWYgKCFpbmNsdWRlc1NvbWVMYW5lKHJlbmRlckxhbmVzLCBPZmZzY3JlZW5MYW5lKSkge1xuICAgICAgdmFyIHNwYXduZWRDYWNoZVBvb2wgPSBudWxsOyAvLyBXZSdyZSBoaWRkZW4sIGFuZCB3ZSdyZSBub3QgcmVuZGVyaW5nIGF0IE9mZnNjcmVlbi4gV2Ugd2lsbCBiYWlsIG91dFxuICAgICAgLy8gYW5kIHJlc3VtZSB0aGlzIHRyZWUgbGF0ZXIuXG5cbiAgICAgIHZhciBuZXh0QmFzZUxhbmVzO1xuXG4gICAgICBpZiAocHJldlN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBwcmV2QmFzZUxhbmVzID0gcHJldlN0YXRlLmJhc2VMYW5lcztcbiAgICAgICAgbmV4dEJhc2VMYW5lcyA9IG1lcmdlTGFuZXMocHJldkJhc2VMYW5lcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dEJhc2VMYW5lcyA9IHJlbmRlckxhbmVzO1xuICAgICAgfSAvLyBTY2hlZHVsZSB0aGlzIGZpYmVyIHRvIHJlLXJlbmRlciBhdCBvZmZzY3JlZW4gcHJpb3JpdHkuIFRoZW4gYmFpbG91dC5cblxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMgPSBsYW5lVG9MYW5lcyhPZmZzY3JlZW5MYW5lKTtcbiAgICAgIHZhciBfbmV4dFN0YXRlID0ge1xuICAgICAgICBiYXNlTGFuZXM6IG5leHRCYXNlTGFuZXMsXG4gICAgICAgIGNhY2hlUG9vbDogc3Bhd25lZENhY2hlUG9vbCxcbiAgICAgICAgdHJhbnNpdGlvbnM6IG51bGxcbiAgICAgIH07XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gX25leHRTdGF0ZTtcbiAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICAgIC8vIHRvIGF2b2lkIGEgcHVzaC9wb3AgbWlzYWxpZ25tZW50LlxuXG5cbiAgICAgIHB1c2hSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcywgbmV4dEJhc2VMYW5lcyk7XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBzZWNvbmQgcmVuZGVyLiBUaGUgc3Vycm91bmRpbmcgdmlzaWJsZSBjb250ZW50IGhhcyBhbHJlYWR5XG4gICAgICAvLyBjb21taXR0ZWQuIE5vdyB3ZSByZXN1bWUgcmVuZGVyaW5nIHRoZSBoaWRkZW4gdHJlZS5cbiAgICAgIC8vIFJlbmRlcmluZyBhdCBvZmZzY3JlZW4sIHNvIHdlIGNhbiBjbGVhciB0aGUgYmFzZSBsYW5lcy5cbiAgICAgIHZhciBfbmV4dFN0YXRlMiA9IHtcbiAgICAgICAgYmFzZUxhbmVzOiBOb0xhbmVzLFxuICAgICAgICBjYWNoZVBvb2w6IG51bGwsXG4gICAgICAgIHRyYW5zaXRpb25zOiBudWxsXG4gICAgICB9O1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IF9uZXh0U3RhdGUyOyAvLyBQdXNoIHRoZSBsYW5lcyB0aGF0IHdlcmUgc2tpcHBlZCB3aGVuIHdlIGJhaWxlZCBvdXQuXG5cbiAgICAgIHZhciBzdWJ0cmVlUmVuZGVyTGFuZXMgPSBwcmV2U3RhdGUgIT09IG51bGwgPyBwcmV2U3RhdGUuYmFzZUxhbmVzIDogcmVuZGVyTGFuZXM7XG5cbiAgICAgIHB1c2hSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcywgc3VidHJlZVJlbmRlckxhbmVzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gUmVuZGVyaW5nIGEgdmlzaWJsZSB0cmVlLlxuICAgIHZhciBfc3VidHJlZVJlbmRlckxhbmVzO1xuXG4gICAgaWYgKHByZXZTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgLy8gV2UncmUgZ29pbmcgZnJvbSBoaWRkZW4gLT4gdmlzaWJsZS5cbiAgICAgIF9zdWJ0cmVlUmVuZGVyTGFuZXMgPSBtZXJnZUxhbmVzKHByZXZTdGF0ZS5iYXNlTGFuZXMsIHJlbmRlckxhbmVzKTtcblxuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIHdlcmVuJ3QgcHJldmlvdXNseSBoaWRkZW4sIGFuZCB3ZSBzdGlsbCBhcmVuJ3QsIHNvIHRoZXJlJ3Mgbm90aGluZ1xuICAgICAgLy8gc3BlY2lhbCB0byBkby4gTmVlZCB0byBwdXNoIHRvIHRoZSBzdGFjayByZWdhcmRsZXNzLCB0aG91Z2gsIHRvIGF2b2lkXG4gICAgICAvLyBhIHB1c2gvcG9wIG1pc2FsaWdubWVudC5cbiAgICAgIF9zdWJ0cmVlUmVuZGVyTGFuZXMgPSByZW5kZXJMYW5lcztcbiAgICB9XG5cbiAgICBwdXNoUmVuZGVyTGFuZXMod29ya0luUHJvZ3Jlc3MsIF9zdWJ0cmVlUmVuZGVyTGFuZXMpO1xuICB9XG5cbiAge1xuICAgIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlRnJhZ21lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVNb2RlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICB2YXIgbmV4dENoaWxkcmVuID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzLmNoaWxkcmVuO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlUHJvZmlsZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG5cbiAgICB7XG4gICAgICAvLyBSZXNldCBlZmZlY3QgZHVyYXRpb25zIGZvciB0aGUgbmV4dCBldmVudHVhbCBlZmZlY3QgcGhhc2UuXG4gICAgICAvLyBUaGVzZSBhcmUgcmVzZXQgZHVyaW5nIHJlbmRlciB0byBhbGxvdyB0aGUgRGV2VG9vbHMgY29tbWl0IGhvb2sgYSBjaGFuY2UgdG8gcmVhZCB0aGVtLFxuICAgICAgdmFyIHN0YXRlTm9kZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgICAgIHN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbiA9IDA7XG4gICAgICBzdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uID0gMDtcbiAgICB9XG4gIH1cblxuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgbmV4dENoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gbWFya1JlZiQxKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIHZhciByZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwgJiYgcmVmICE9PSBudWxsIHx8IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5yZWYgIT09IHJlZikge1xuICAgIC8vIFNjaGVkdWxlIGEgUmVmIGVmZmVjdFxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZjtcblxuICAgIHtcbiAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZlN0YXRpYztcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICB7XG4gICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAvLyBMYXp5IGNvbXBvbmVudCBwcm9wcyBjYW4ndCBiZSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudFxuICAgICAgLy8gYmVjYXVzZSB0aGV5J3JlIG9ubHkgZ3VhcmFudGVlZCB0byBiZSByZXNvbHZlZCBoZXJlLlxuICAgICAgdmFyIGlubmVyUHJvcFR5cGVzID0gQ29tcG9uZW50LnByb3BUeXBlcztcblxuICAgICAgaWYgKGlubmVyUHJvcFR5cGVzKSB7XG4gICAgICAgIGNoZWNrUHJvcFR5cGVzKGlubmVyUHJvcFR5cGVzLCBuZXh0UHJvcHMsIC8vIFJlc29sdmVkIHByb3BzXG4gICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBjb250ZXh0O1xuXG4gIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHRydWUpO1xuICAgIGNvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpO1xuICB9XG5cbiAgdmFyIG5leHRDaGlsZHJlbjtcbiAgdmFyIGhhc0lkO1xuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cblxuICB7XG4gICAgUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50ID0gd29ya0luUHJvZ3Jlc3M7XG4gICAgc2V0SXNSZW5kZXJpbmcodHJ1ZSk7XG4gICAgbmV4dENoaWxkcmVuID0gcmVuZGVyV2l0aEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgY29udGV4dCwgcmVuZGVyTGFuZXMpO1xuICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBuZXh0Q2hpbGRyZW4gPSByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCBjb250ZXh0LCByZW5kZXJMYW5lcyk7XG4gICAgICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRJc1JlbmRlcmluZyhmYWxzZSk7XG4gIH1cblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQoKTtcbiAgfVxuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsICYmICFkaWRSZWNlaXZlVXBkYXRlKSB7XG4gICAgYmFpbG91dEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgcmV0dXJuIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIGhhc0lkKSB7XG4gICAgcHVzaE1hdGVyaWFsaXplZFRyZWVJZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNsYXNzQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIC8vIFRoaXMgaXMgdXNlZCBieSBEZXZUb29scyB0byBmb3JjZSBhIGJvdW5kYXJ5IHRvIGVycm9yLlxuICAgIHN3aXRjaCAoc2hvdWxkRXJyb3Iod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICBjYXNlIGZhbHNlOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIF9pbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgICAgICAgICB2YXIgY3RvciA9IHdvcmtJblByb2dyZXNzLnR5cGU7IC8vIFRPRE8gVGhpcyB3YXkgb2YgcmVzZXR0aW5nIHRoZSBlcnJvciBib3VuZGFyeSBzdGF0ZSBpcyBhIGhhY2suXG4gICAgICAgICAgLy8gSXMgdGhlcmUgYSBiZXR0ZXIgd2F5IHRvIGRvIHRoaXM/XG5cbiAgICAgICAgICB2YXIgdGVtcEluc3RhbmNlID0gbmV3IGN0b3Iod29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcywgX2luc3RhbmNlLmNvbnRleHQpO1xuICAgICAgICAgIHZhciBzdGF0ZSA9IHRlbXBJbnN0YW5jZS5zdGF0ZTtcblxuICAgICAgICAgIF9pbnN0YW5jZS51cGRhdGVyLmVucXVldWVTZXRTdGF0ZShfaW5zdGFuY2UsIHN0YXRlLCBudWxsKTtcblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgdHJ1ZTpcbiAgICAgICAge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcblxuICAgICAgICAgIHZhciBlcnJvciQxID0gbmV3IEVycm9yKCdTaW11bGF0ZWQgZXJyb3IgY29taW5nIGZyb20gRGV2VG9vbHMnKTtcbiAgICAgICAgICB2YXIgbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJlbmRlckxhbmVzKTtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMsIGxhbmUpOyAvLyBTY2hlZHVsZSB0aGUgZXJyb3IgYm91bmRhcnkgdG8gcmUtcmVuZGVyIHVzaW5nIHVwZGF0ZWQgc3RhdGVcblxuICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVDbGFzc0Vycm9yVXBkYXRlKHdvcmtJblByb2dyZXNzLCBjcmVhdGVDYXB0dXJlZFZhbHVlKGVycm9yJDEsIHdvcmtJblByb2dyZXNzKSwgbGFuZSk7XG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCB1cGRhdGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAvLyBMYXp5IGNvbXBvbmVudCBwcm9wcyBjYW4ndCBiZSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudFxuICAgICAgLy8gYmVjYXVzZSB0aGV5J3JlIG9ubHkgZ3VhcmFudGVlZCB0byBiZSByZXNvbHZlZCBoZXJlLlxuICAgICAgdmFyIGlubmVyUHJvcFR5cGVzID0gQ29tcG9uZW50LnByb3BUeXBlcztcblxuICAgICAgaWYgKGlubmVyUHJvcFR5cGVzKSB7XG4gICAgICAgIGNoZWNrUHJvcFR5cGVzKGlubmVyUHJvcFR5cGVzLCBuZXh0UHJvcHMsIC8vIFJlc29sdmVkIHByb3BzXG4gICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkpO1xuICAgICAgfVxuICAgIH1cbiAgfSAvLyBQdXNoIGNvbnRleHQgcHJvdmlkZXJzIGVhcmx5IHRvIHByZXZlbnQgY29udGV4dCBzdGFjayBtaXNtYXRjaGVzLlxuICAvLyBEdXJpbmcgbW91bnRpbmcgd2UgZG9uJ3Qga25vdyB0aGUgY2hpbGQgY29udGV4dCB5ZXQgYXMgdGhlIGluc3RhbmNlIGRvZXNuJ3QgZXhpc3QuXG4gIC8vIFdlIHdpbGwgaW52YWxpZGF0ZSB0aGUgY2hpbGQgY29udGV4dCBpbiBmaW5pc2hDbGFzc0NvbXBvbmVudCgpIHJpZ2h0IGFmdGVyIHJlbmRlcmluZy5cblxuXG4gIHZhciBoYXNDb250ZXh0O1xuXG4gIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgaGFzQ29udGV4dCA9IHRydWU7XG4gICAgcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgaGFzQ29udGV4dCA9IGZhbHNlO1xuICB9XG5cbiAgcHJlcGFyZVRvUmVhZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICB2YXIgc2hvdWxkVXBkYXRlO1xuXG4gIGlmIChpbnN0YW5jZSA9PT0gbnVsbCkge1xuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICAvLyBBIGNsYXNzIGNvbXBvbmVudCB3aXRob3V0IGFuIGluc3RhbmNlIG9ubHkgbW91bnRzIGlmIGl0IHN1c3BlbmRlZFxuICAgICAgLy8gaW5zaWRlIGEgbm9uLWNvbmN1cnJlbnQgdHJlZSwgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBXZSB3YW50IHRvXG4gICAgICAvLyB0cmVhdCBpdCBsaWtlIGEgbmV3IG1vdW50LCBldmVuIHRob3VnaCBhbiBlbXB0eSB2ZXJzaW9uIG9mIGl0IGFscmVhZHlcbiAgICAgIC8vIGNvbW1pdHRlZC4gRGlzY29ubmVjdCB0aGUgYWx0ZXJuYXRlIHBvaW50ZXJzLlxuICAgICAgY3VycmVudC5hbHRlcm5hdGUgPSBudWxsO1xuICAgICAgd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlID0gbnVsbDsgLy8gU2luY2UgdGhpcyBpcyBjb25jZXB0dWFsbHkgYSBuZXcgZmliZXIsIHNjaGVkdWxlIGEgUGxhY2VtZW50IGVmZmVjdFxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gICAgfSAvLyBJbiB0aGUgaW5pdGlhbCBwYXNzIHdlIG1pZ2h0IG5lZWQgdG8gY29uc3RydWN0IHRoZSBpbnN0YW5jZS5cblxuXG4gICAgY29uc3RydWN0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMpO1xuICAgIG1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICBzaG91bGRVcGRhdGUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAvLyBJbiBhIHJlc3VtZSwgd2UnbGwgYWxyZWFkeSBoYXZlIGFuIGluc3RhbmNlIHdlIGNhbiByZXVzZS5cbiAgICBzaG91bGRVcGRhdGUgPSByZXN1bWVNb3VudENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcyk7XG4gIH0gZWxzZSB7XG4gICAgc2hvdWxkVXBkYXRlID0gdXBkYXRlQ2xhc3NJbnN0YW5jZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHZhciBuZXh0VW5pdE9mV29yayA9IGZpbmlzaENsYXNzQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHNob3VsZFVwZGF0ZSwgaGFzQ29udGV4dCwgcmVuZGVyTGFuZXMpO1xuXG4gIHtcbiAgICB2YXIgaW5zdCA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcblxuICAgIGlmIChzaG91bGRVcGRhdGUgJiYgaW5zdC5wcm9wcyAhPT0gbmV4dFByb3BzKSB7XG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgZXJyb3IoJ0l0IGxvb2tzIGxpa2UgJXMgaXMgcmVhc3NpZ25pbmcgaXRzIG93biBgdGhpcy5wcm9wc2Agd2hpbGUgcmVuZGVyaW5nLiAnICsgJ1RoaXMgaXMgbm90IHN1cHBvcnRlZCBhbmQgY2FuIGxlYWQgdG8gY29uZnVzaW5nIGJ1Z3MuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ2EgY29tcG9uZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXh0VW5pdE9mV29yaztcbn1cblxuZnVuY3Rpb24gZmluaXNoQ2xhc3NDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgc2hvdWxkVXBkYXRlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcykge1xuICAvLyBSZWZzIHNob3VsZCB1cGRhdGUgZXZlbiBpZiBzaG91bGRDb21wb25lbnRVcGRhdGUgcmV0dXJucyBmYWxzZVxuICBtYXJrUmVmJDEoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgZGlkQ2FwdHVyZUVycm9yID0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3M7XG5cbiAgaWYgKCFzaG91bGRVcGRhdGUgJiYgIWRpZENhcHR1cmVFcnJvcikge1xuICAgIC8vIENvbnRleHQgcHJvdmlkZXJzIHNob3VsZCBkZWZlciB0byBzQ1UgZm9yIHJlbmRlcmluZ1xuICAgIGlmIChoYXNDb250ZXh0KSB7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIGZhbHNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlOyAvLyBSZXJlbmRlclxuXG4gIFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCA9IHdvcmtJblByb2dyZXNzO1xuICB2YXIgbmV4dENoaWxkcmVuO1xuXG4gIGlmIChkaWRDYXB0dXJlRXJyb3IgJiYgdHlwZW9mIENvbXBvbmVudC5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBJZiB3ZSBjYXB0dXJlZCBhbiBlcnJvciwgYnV0IGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciBpcyBub3QgZGVmaW5lZCxcbiAgICAvLyB1bm1vdW50IGFsbCB0aGUgY2hpbGRyZW4uIGNvbXBvbmVudERpZENhdGNoIHdpbGwgc2NoZWR1bGUgYW4gdXBkYXRlIHRvXG4gICAgLy8gcmUtcmVuZGVyIGEgZmFsbGJhY2suIFRoaXMgaXMgdGVtcG9yYXJ5IHVudGlsIHdlIG1pZ3JhdGUgZXZlcnlvbmUgdG9cbiAgICAvLyB0aGUgbmV3IEFQSS5cbiAgICAvLyBUT0RPOiBXYXJuIGluIGEgZnV0dXJlIHJlbGVhc2UuXG4gICAgbmV4dENoaWxkcmVuID0gbnVsbDtcblxuICAgIHtcbiAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nKCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHtcbiAgICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkKHdvcmtJblByb2dyZXNzKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBzZXRJc1JlbmRlcmluZyh0cnVlKTtcbiAgICAgIG5leHRDaGlsZHJlbiA9IGluc3RhbmNlLnJlbmRlcigpO1xuXG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaW5zdGFuY2UucmVuZGVyKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHNldElzUmVuZGVyaW5nKGZhbHNlKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpO1xuICAgIH1cbiAgfSAvLyBSZWFjdCBEZXZUb29scyByZWFkcyB0aGlzIGZsYWcuXG5cblxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQZXJmb3JtZWRXb3JrO1xuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsICYmIGRpZENhcHR1cmVFcnJvcikge1xuICAgIC8vIElmIHdlJ3JlIHJlY292ZXJpbmcgZnJvbSBhbiBlcnJvciwgcmVjb25jaWxlIHdpdGhvdXQgcmV1c2luZyBhbnkgb2ZcbiAgICAvLyB0aGUgZXhpc3RpbmcgY2hpbGRyZW4uIENvbmNlcHR1YWxseSwgdGhlIG5vcm1hbCBjaGlsZHJlbiBhbmQgdGhlIGNoaWxkcmVuXG4gICAgLy8gdGhhdCBhcmUgc2hvd24gb24gZXJyb3IgYXJlIHR3byBkaWZmZXJlbnQgc2V0cywgc28gd2Ugc2hvdWxkbid0IHJldXNlXG4gICAgLy8gbm9ybWFsIGNoaWxkcmVuIGV2ZW4gaWYgdGhlaXIgaWRlbnRpdGllcyBtYXRjaC5cbiAgICBmb3JjZVVubW91bnRDdXJyZW50QW5kUmVjb25jaWxlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH0gLy8gTWVtb2l6ZSBzdGF0ZSB1c2luZyB0aGUgdmFsdWVzIHdlIGp1c3QgdXNlZCB0byByZW5kZXIuXG4gIC8vIFRPRE86IFJlc3RydWN0dXJlIHNvIHdlIG5ldmVyIHJlYWQgdmFsdWVzIGZyb20gdGhlIGluc3RhbmNlLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IGluc3RhbmNlLnN0YXRlOyAvLyBUaGUgY29udGV4dCBtaWdodCBoYXZlIGNoYW5nZWQgc28gd2UgbmVlZCB0byByZWNhbGN1bGF0ZSBpdC5cblxuICBpZiAoaGFzQ29udGV4dCkge1xuICAgIGludmFsaWRhdGVDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgdHJ1ZSk7XG4gIH1cblxuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpIHtcbiAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAgaWYgKHJvb3QucGVuZGluZ0NvbnRleHQpIHtcbiAgICBwdXNoVG9wTGV2ZWxDb250ZXh0T2JqZWN0KHdvcmtJblByb2dyZXNzLCByb290LnBlbmRpbmdDb250ZXh0LCByb290LnBlbmRpbmdDb250ZXh0ICE9PSByb290LmNvbnRleHQpO1xuICB9IGVsc2UgaWYgKHJvb3QuY29udGV4dCkge1xuICAgIC8vIFNob3VsZCBhbHdheXMgYmUgc2V0XG4gICAgcHVzaFRvcExldmVsQ29udGV4dE9iamVjdCh3b3JrSW5Qcm9ncmVzcywgcm9vdC5jb250ZXh0LCBmYWxzZSk7XG4gIH1cblxuICBwdXNoSG9zdENvbnRhaW5lcih3b3JrSW5Qcm9ncmVzcywgcm9vdC5jb250YWluZXJJbmZvKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlSG9zdFJvb3QoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgaGF2ZSBhIGN1cnJlbnQgZmliZXIuIFRoaXMgaXMgYSBidWcgaW4gUmVhY3QuJyk7XG4gIH1cblxuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJldlN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHByZXZDaGlsZHJlbiA9IHByZXZTdGF0ZS5lbGVtZW50O1xuICBjbG9uZVVwZGF0ZVF1ZXVlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXh0UHJvcHMsIG51bGwsIHJlbmRlckxhbmVzKTtcbiAgdmFyIG5leHRTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIHZhciByb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAvLyBiZWluZyBjYWxsZWQgXCJlbGVtZW50XCIuXG5cblxuICB2YXIgbmV4dENoaWxkcmVuID0gbmV4dFN0YXRlLmVsZW1lbnQ7XG5cbiAgaWYgKCBwcmV2U3RhdGUuaXNEZWh5ZHJhdGVkKSB7XG4gICAgLy8gVGhpcyBpcyBhIGh5ZHJhdGlvbiByb290IHdob3NlIHNoZWxsIGhhcyBub3QgeWV0IGh5ZHJhdGVkLiBXZSBzaG91bGRcbiAgICAvLyBhdHRlbXB0IHRvIGh5ZHJhdGUuXG4gICAgLy8gRmxpcCBpc0RlaHlkcmF0ZWQgdG8gZmFsc2UgdG8gaW5kaWNhdGUgdGhhdCB3aGVuIHRoaXMgcmVuZGVyXG4gICAgLy8gZmluaXNoZXMsIHRoZSByb290IHdpbGwgbm8gbG9uZ2VyIGJlIGRlaHlkcmF0ZWQuXG4gICAgdmFyIG92ZXJyaWRlU3RhdGUgPSB7XG4gICAgICBlbGVtZW50OiBuZXh0Q2hpbGRyZW4sXG4gICAgICBpc0RlaHlkcmF0ZWQ6IGZhbHNlLFxuICAgICAgY2FjaGU6IG5leHRTdGF0ZS5jYWNoZSxcbiAgICAgIHBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXM6IG5leHRTdGF0ZS5wZW5kaW5nU3VzcGVuc2VCb3VuZGFyaWVzLFxuICAgICAgdHJhbnNpdGlvbnM6IG5leHRTdGF0ZS50cmFuc2l0aW9uc1xuICAgIH07XG4gICAgdmFyIHVwZGF0ZVF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7IC8vIGBiYXNlU3RhdGVgIGNhbiBhbHdheXMgYmUgdGhlIGxhc3Qgc3RhdGUgYmVjYXVzZSB0aGUgcm9vdCBkb2Vzbid0XG4gICAgLy8gaGF2ZSByZWR1Y2VyIGZ1bmN0aW9ucyBzbyBpdCBkb2Vzbid0IG5lZWQgcmViYXNpbmcuXG5cbiAgICB1cGRhdGVRdWV1ZS5iYXNlU3RhdGUgPSBvdmVycmlkZVN0YXRlO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBvdmVycmlkZVN0YXRlO1xuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRm9yY2VDbGllbnRSZW5kZXIpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBlcnJvcmVkIGR1cmluZyBhIHByZXZpb3VzIGF0dGVtcHQgdG8gaHlkcmF0ZSB0aGUgc2hlbGwsIHNvIHdlXG4gICAgICAvLyBmb3JjZWQgYSBjbGllbnQgcmVuZGVyLlxuICAgICAgdmFyIHJlY292ZXJhYmxlRXJyb3IgPSBuZXcgRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBoeWRyYXRpbmcuIEJlY2F1c2UgdGhlIGVycm9yIGhhcHBlbmVkIG91dHNpZGUgJyArICdvZiBhIFN1c3BlbnNlIGJvdW5kYXJ5LCB0aGUgZW50aXJlIHJvb3Qgd2lsbCBzd2l0Y2ggdG8gJyArICdjbGllbnQgcmVuZGVyaW5nLicpO1xuICAgICAgcmV0dXJuIG1vdW50SG9zdFJvb3RXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzLCByZWNvdmVyYWJsZUVycm9yKTtcbiAgICB9IGVsc2UgaWYgKG5leHRDaGlsZHJlbiAhPT0gcHJldkNoaWxkcmVuKSB7XG4gICAgICB2YXIgX3JlY292ZXJhYmxlRXJyb3IgPSBuZXcgRXJyb3IoJ1RoaXMgcm9vdCByZWNlaXZlZCBhbiBlYXJseSB1cGRhdGUsIGJlZm9yZSBhbnl0aGluZyB3YXMgYWJsZSAnICsgJ2h5ZHJhdGUuIFN3aXRjaGVkIHRoZSBlbnRpcmUgcm9vdCB0byBjbGllbnQgcmVuZGVyaW5nLicpO1xuXG4gICAgICByZXR1cm4gbW91bnRIb3N0Um9vdFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMsIF9yZWNvdmVyYWJsZUVycm9yKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIG91dGVybW9zdCBzaGVsbCBoYXMgbm90IGh5ZHJhdGVkIHlldC4gU3RhcnQgaHlkcmF0aW5nLlxuICAgICAgZW50ZXJIeWRyYXRpb25TdGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgIHZhciBjaGlsZCA9IG1vdW50Q2hpbGRGaWJlcnMod29ya0luUHJvZ3Jlc3MsIG51bGwsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBjaGlsZDtcbiAgICAgIHZhciBub2RlID0gY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChub2RlKSB7XG4gICAgICAgIC8vIE1hcmsgZWFjaCBjaGlsZCBhcyBoeWRyYXRpbmcuIFRoaXMgaXMgYSBmYXN0IHBhdGggdG8ga25vdyB3aGV0aGVyIHRoaXNcbiAgICAgICAgLy8gdHJlZSBpcyBwYXJ0IG9mIGEgaHlkcmF0aW5nIHRyZWUuIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBjaGlsZFxuICAgICAgICAvLyBub2RlIGhhcyBmdWxseSBtb3VudGVkIHlldCwgYW5kIGZvciBzY2hlZHVsaW5nIGV2ZW50IHJlcGxheWluZy5cbiAgICAgICAgLy8gQ29uY2VwdHVhbGx5IHRoaXMgaXMgc2ltaWxhciB0byBQbGFjZW1lbnQgaW4gdGhhdCBhIG5ldyBzdWJ0cmVlIGlzXG4gICAgICAgIC8vIGluc2VydGVkIGludG8gdGhlIFJlYWN0IHRyZWUgaGVyZS4gSXQganVzdCBoYXBwZW5zIHRvIG5vdCBuZWVkIERPTVxuICAgICAgICAvLyBtdXRhdGlvbnMgYmVjYXVzZSBpdCBhbHJlYWR5IGV4aXN0cy5cbiAgICAgICAgbm9kZS5mbGFncyA9IG5vZGUuZmxhZ3MgJiB+UGxhY2VtZW50IHwgSHlkcmF0aW5nO1xuICAgICAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBSb290IGlzIG5vdCBkZWh5ZHJhdGVkLiBFaXRoZXIgdGhpcyBpcyBhIGNsaWVudC1vbmx5IHJvb3QsIG9yIGl0XG4gICAgLy8gYWxyZWFkeSBoeWRyYXRlZC5cbiAgICByZXNldEh5ZHJhdGlvblN0YXRlKCk7XG5cbiAgICBpZiAobmV4dENoaWxkcmVuID09PSBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgIHJldHVybiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgfVxuXG4gICAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiBtb3VudEhvc3RSb290V2l0aG91dEh5ZHJhdGluZyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcywgcmVjb3ZlcmFibGVFcnJvcikge1xuICAvLyBSZXZlcnQgdG8gY2xpZW50IHJlbmRlcmluZy5cbiAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuICBxdWV1ZUh5ZHJhdGlvbkVycm9yKHJlY292ZXJhYmxlRXJyb3IpO1xuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBGb3JjZUNsaWVudFJlbmRlcjtcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUhvc3RDb21wb25lbnQkMShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgcHVzaEhvc3RDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcblxuICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgIHRyeVRvQ2xhaW1OZXh0SHlkcmF0YWJsZUluc3RhbmNlKHdvcmtJblByb2dyZXNzKTtcbiAgfVxuXG4gIHZhciB0eXBlID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgdmFyIG5leHRQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcbiAgdmFyIHByZXZQcm9wcyA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Lm1lbW9pemVkUHJvcHMgOiBudWxsO1xuICB2YXIgbmV4dENoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICB2YXIgaXNEaXJlY3RUZXh0Q2hpbGQgPSBzaG91bGRTZXRUZXh0Q29udGVudCh0eXBlLCBuZXh0UHJvcHMpO1xuXG4gIGlmIChpc0RpcmVjdFRleHRDaGlsZCkge1xuICAgIC8vIFdlIHNwZWNpYWwgY2FzZSBhIGRpcmVjdCB0ZXh0IGNoaWxkIG9mIGEgaG9zdCBub2RlLiBUaGlzIGlzIGEgY29tbW9uXG4gICAgLy8gY2FzZS4gV2Ugd29uJ3QgaGFuZGxlIGl0IGFzIGEgcmVpZmllZCBjaGlsZC4gV2Ugd2lsbCBpbnN0ZWFkIGhhbmRsZVxuICAgIC8vIHRoaXMgaW4gdGhlIGhvc3QgZW52aXJvbm1lbnQgdGhhdCBhbHNvIGhhcyBhY2Nlc3MgdG8gdGhpcyBwcm9wLiBUaGF0XG4gICAgLy8gYXZvaWRzIGFsbG9jYXRpbmcgYW5vdGhlciBIb3N0VGV4dCBmaWJlciBhbmQgdHJhdmVyc2luZyBpdC5cbiAgICBuZXh0Q2hpbGRyZW4gPSBudWxsO1xuICB9IGVsc2UgaWYgKHByZXZQcm9wcyAhPT0gbnVsbCAmJiBzaG91bGRTZXRUZXh0Q29udGVudCh0eXBlLCBwcmV2UHJvcHMpKSB7XG4gICAgLy8gSWYgd2UncmUgc3dpdGNoaW5nIGZyb20gYSBkaXJlY3QgdGV4dCBjaGlsZCB0byBhIG5vcm1hbCBjaGlsZCwgb3IgdG9cbiAgICAvLyBlbXB0eSwgd2UgbmVlZCB0byBzY2hlZHVsZSB0aGUgdGV4dCBjb250ZW50IHRvIGJlIHJlc2V0LlxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IENvbnRlbnRSZXNldDtcbiAgfVxuXG4gIG1hcmtSZWYkMShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcyk7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVIb3N0VGV4dCQxKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdHJ5VG9DbGFpbU5leHRIeWRyYXRhYmxlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MpO1xuICB9IC8vIE5vdGhpbmcgdG8gZG8gaGVyZS4gVGhpcyBpcyB0ZXJtaW5hbC4gV2UnbGwgZG8gdGhlIGNvbXBsZXRpb24gc3RlcFxuICAvLyBpbW1lZGlhdGVseSBhZnRlci5cblxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBtb3VudExhenlDb21wb25lbnQoX2N1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBlbGVtZW50VHlwZSwgcmVuZGVyTGFuZXMpIHtcbiAgaWYgKF9jdXJyZW50ICE9PSBudWxsKSB7XG4gICAgLy8gQSBsYXp5IGNvbXBvbmVudCBvbmx5IG1vdW50cyBpZiBpdCBzdXNwZW5kZWQgaW5zaWRlIGEgbm9uLVxuICAgIC8vIGNvbmN1cnJlbnQgdHJlZSwgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBXZSB3YW50IHRvIHRyZWF0IGl0IGxpa2VcbiAgICAvLyBhIG5ldyBtb3VudCwgZXZlbiB0aG91Z2ggYW4gZW1wdHkgdmVyc2lvbiBvZiBpdCBhbHJlYWR5IGNvbW1pdHRlZC5cbiAgICAvLyBEaXNjb25uZWN0IHRoZSBhbHRlcm5hdGUgcG9pbnRlcnMuXG4gICAgX2N1cnJlbnQuYWx0ZXJuYXRlID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPSBudWxsOyAvLyBTaW5jZSB0aGlzIGlzIGNvbmNlcHR1YWxseSBhIG5ldyBmaWJlciwgc2NoZWR1bGUgYSBQbGFjZW1lbnQgZWZmZWN0XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gIH1cblxuICB2YXIgcHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBsYXp5Q29tcG9uZW50ID0gZWxlbWVudFR5cGU7XG4gIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgdmFyIGluaXQgPSBsYXp5Q29tcG9uZW50Ll9pbml0O1xuICB2YXIgQ29tcG9uZW50ID0gaW5pdChwYXlsb2FkKTsgLy8gU3RvcmUgdGhlIHVud3JhcHBlZCBjb21wb25lbnQgaW4gdGhlIHR5cGUuXG5cbiAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IENvbXBvbmVudDtcbiAgdmFyIHJlc29sdmVkVGFnID0gd29ya0luUHJvZ3Jlc3MudGFnID0gcmVzb2x2ZUxhenlDb21wb25lbnRUYWcoQ29tcG9uZW50KTtcbiAgdmFyIHJlc29sdmVkUHJvcHMgPSByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudCwgcHJvcHMpO1xuICB2YXIgY2hpbGQ7XG5cbiAgc3dpdGNoIChyZXNvbHZlZFRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHtcbiAgICAgICAgICB2YWxpZGF0ZUZ1bmN0aW9uQ29tcG9uZW50SW5EZXYod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCk7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IENvbXBvbmVudCA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyhDb21wb25lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSB1cGRhdGVGdW5jdGlvbkNvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCByZXNvbHZlZFByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gQ29tcG9uZW50ID0gcmVzb2x2ZUNsYXNzRm9ySG90UmVsb2FkaW5nKENvbXBvbmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjaGlsZCA9IHVwZGF0ZUNsYXNzQ29tcG9uZW50KG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHJlc29sdmVkUHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuXG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IENvbXBvbmVudCA9IHJlc29sdmVGb3J3YXJkUmVmRm9ySG90UmVsb2FkaW5nKENvbXBvbmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjaGlsZCA9IHVwZGF0ZUZvcndhcmRSZWYobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVzb2x2ZWRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICB9XG5cbiAgICBjYXNlIE1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAod29ya0luUHJvZ3Jlc3MudHlwZSAhPT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUpIHtcbiAgICAgICAgICAgIHZhciBvdXRlclByb3BUeXBlcyA9IENvbXBvbmVudC5wcm9wVHlwZXM7XG5cbiAgICAgICAgICAgIGlmIChvdXRlclByb3BUeXBlcykge1xuICAgICAgICAgICAgICBjaGVja1Byb3BUeXBlcyhvdXRlclByb3BUeXBlcywgcmVzb2x2ZWRQcm9wcywgLy8gUmVzb2x2ZWQgZm9yIG91dGVyIG9ubHlcbiAgICAgICAgICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSB1cGRhdGVNZW1vQ29tcG9uZW50KG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHJlc29sdmVEZWZhdWx0UHJvcHMoQ29tcG9uZW50LnR5cGUsIHJlc29sdmVkUHJvcHMpLCAvLyBUaGUgaW5uZXIgdHlwZSBjYW4gaGF2ZSBkZWZhdWx0cyB0b29cbiAgICAgICAgcmVuZGVyTGFuZXMpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICB9XG4gIH1cblxuICB2YXIgaGludCA9ICcnO1xuXG4gIHtcbiAgICBpZiAoQ29tcG9uZW50ICE9PSBudWxsICYmIHR5cGVvZiBDb21wb25lbnQgPT09ICdvYmplY3QnICYmIENvbXBvbmVudC4kJHR5cGVvZiA9PT0gUkVBQ1RfTEFaWV9UWVBFKSB7XG4gICAgICBoaW50ID0gJyBEaWQgeW91IHdyYXAgYSBjb21wb25lbnQgaW4gUmVhY3QubGF6eSgpIG1vcmUgdGhhbiBvbmNlPyc7XG4gICAgfVxuICB9IC8vIFRoaXMgbWVzc2FnZSBpbnRlbnRpb25hbGx5IGRvZXNuJ3QgbWVudGlvbiBGb3J3YXJkUmVmIG9yIE1lbW9Db21wb25lbnRcbiAgLy8gYmVjYXVzZSB0aGUgZmFjdCB0aGF0IGl0J3MgYSBzZXBhcmF0ZSB0eXBlIG9mIHdvcmsgaXMgYW5cbiAgLy8gaW1wbGVtZW50YXRpb24gZGV0YWlsLlxuXG5cbiAgdGhyb3cgbmV3IEVycm9yKFwiRWxlbWVudCB0eXBlIGlzIGludmFsaWQuIFJlY2VpdmVkIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvOiBcIiArIENvbXBvbmVudCArIFwiLiBcIiArIChcIkxhenkgZWxlbWVudCB0eXBlIG11c3QgcmVzb2x2ZSB0byBhIGNsYXNzIG9yIGZ1bmN0aW9uLlwiICsgaGludCkpO1xufVxuXG5mdW5jdGlvbiBtb3VudEluY29tcGxldGVDbGFzc0NvbXBvbmVudChfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICBpZiAoX2N1cnJlbnQgIT09IG51bGwpIHtcbiAgICAvLyBBbiBpbmNvbXBsZXRlIGNvbXBvbmVudCBvbmx5IG1vdW50cyBpZiBpdCBzdXNwZW5kZWQgaW5zaWRlIGEgbm9uLVxuICAgIC8vIGNvbmN1cnJlbnQgdHJlZSwgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBXZSB3YW50IHRvIHRyZWF0IGl0IGxpa2VcbiAgICAvLyBhIG5ldyBtb3VudCwgZXZlbiB0aG91Z2ggYW4gZW1wdHkgdmVyc2lvbiBvZiBpdCBhbHJlYWR5IGNvbW1pdHRlZC5cbiAgICAvLyBEaXNjb25uZWN0IHRoZSBhbHRlcm5hdGUgcG9pbnRlcnMuXG4gICAgX2N1cnJlbnQuYWx0ZXJuYXRlID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPSBudWxsOyAvLyBTaW5jZSB0aGlzIGlzIGNvbmNlcHR1YWxseSBhIG5ldyBmaWJlciwgc2NoZWR1bGUgYSBQbGFjZW1lbnQgZWZmZWN0XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gIH0gLy8gUHJvbW90ZSB0aGUgZmliZXIgdG8gYSBjbGFzcyBhbmQgdHJ5IHJlbmRlcmluZyBhZ2Fpbi5cblxuXG4gIHdvcmtJblByb2dyZXNzLnRhZyA9IENsYXNzQ29tcG9uZW50OyAvLyBUaGUgcmVzdCBvZiB0aGlzIGZ1bmN0aW9uIGlzIGEgZm9yayBvZiBgdXBkYXRlQ2xhc3NDb21wb25lbnRgXG4gIC8vIFB1c2ggY29udGV4dCBwcm92aWRlcnMgZWFybHkgdG8gcHJldmVudCBjb250ZXh0IHN0YWNrIG1pc21hdGNoZXMuXG4gIC8vIER1cmluZyBtb3VudGluZyB3ZSBkb24ndCBrbm93IHRoZSBjaGlsZCBjb250ZXh0IHlldCBhcyB0aGUgaW5zdGFuY2UgZG9lc24ndCBleGlzdC5cbiAgLy8gV2Ugd2lsbCBpbnZhbGlkYXRlIHRoZSBjaGlsZCBjb250ZXh0IGluIGZpbmlzaENsYXNzQ29tcG9uZW50KCkgcmlnaHQgYWZ0ZXIgcmVuZGVyaW5nLlxuXG4gIHZhciBoYXNDb250ZXh0O1xuXG4gIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgaGFzQ29udGV4dCA9IHRydWU7XG4gICAgcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgaGFzQ29udGV4dCA9IGZhbHNlO1xuICB9XG5cbiAgcHJlcGFyZVRvUmVhZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgY29uc3RydWN0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMpO1xuICBtb3VudENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiBmaW5pc2hDbGFzc0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCB0cnVlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIG1vdW50SW5kZXRlcm1pbmF0ZUNvbXBvbmVudChfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVuZGVyTGFuZXMpIHtcbiAgaWYgKF9jdXJyZW50ICE9PSBudWxsKSB7XG4gICAgLy8gQW4gaW5kZXRlcm1pbmF0ZSBjb21wb25lbnQgb25seSBtb3VudHMgaWYgaXQgc3VzcGVuZGVkIGluc2lkZSBhIG5vbi1cbiAgICAvLyBjb25jdXJyZW50IHRyZWUsIGluIGFuIGluY29uc2lzdGVudCBzdGF0ZS4gV2Ugd2FudCB0byB0cmVhdCBpdCBsaWtlXG4gICAgLy8gYSBuZXcgbW91bnQsIGV2ZW4gdGhvdWdoIGFuIGVtcHR5IHZlcnNpb24gb2YgaXQgYWxyZWFkeSBjb21taXR0ZWQuXG4gICAgLy8gRGlzY29ubmVjdCB0aGUgYWx0ZXJuYXRlIHBvaW50ZXJzLlxuICAgIF9jdXJyZW50LmFsdGVybmF0ZSA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlID0gbnVsbDsgLy8gU2luY2UgdGhpcyBpcyBjb25jZXB0dWFsbHkgYSBuZXcgZmliZXIsIHNjaGVkdWxlIGEgUGxhY2VtZW50IGVmZmVjdFxuXG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGxhY2VtZW50O1xuICB9XG5cbiAgdmFyIHByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgY29udGV4dDtcblxuICB7XG4gICAgdmFyIHVubWFza2VkQ29udGV4dCA9IGdldFVubWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBmYWxzZSk7XG4gICAgY29udGV4dCA9IGdldE1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHVubWFza2VkQ29udGV4dCk7XG4gIH1cblxuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB2YXIgdmFsdWU7XG4gIHZhciBoYXNJZDtcblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAge1xuICAgIGlmIChDb21wb25lbnQucHJvdG90eXBlICYmIHR5cGVvZiBDb21wb25lbnQucHJvdG90eXBlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSB8fCAnVW5rbm93bic7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0QmFkQ2xhc3NbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZXJyb3IoXCJUaGUgPCVzIC8+IGNvbXBvbmVudCBhcHBlYXJzIHRvIGhhdmUgYSByZW5kZXIgbWV0aG9kLCBidXQgZG9lc24ndCBleHRlbmQgUmVhY3QuQ29tcG9uZW50LiBcIiArICdUaGlzIGlzIGxpa2VseSB0byBjYXVzZSBlcnJvcnMuIENoYW5nZSAlcyB0byBleHRlbmQgUmVhY3QuQ29tcG9uZW50IGluc3RlYWQuJywgY29tcG9uZW50TmFtZSwgY29tcG9uZW50TmFtZSk7XG5cbiAgICAgICAgZGlkV2FybkFib3V0QmFkQ2xhc3NbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MucmVjb3JkTGVnYWN5Q29udGV4dFdhcm5pbmcod29ya0luUHJvZ3Jlc3MsIG51bGwpO1xuICAgIH1cblxuICAgIHNldElzUmVuZGVyaW5nKHRydWUpO1xuICAgIFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCA9IHdvcmtJblByb2dyZXNzO1xuICAgIHZhbHVlID0gcmVuZGVyV2l0aEhvb2tzKG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHByb3BzLCBjb250ZXh0LCByZW5kZXJMYW5lcyk7XG4gICAgaGFzSWQgPSBjaGVja0RpZFJlbmRlcklkSG9vaygpO1xuICAgIHNldElzUmVuZGVyaW5nKGZhbHNlKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpO1xuICB9IC8vIFJlYWN0IERldlRvb2xzIHJlYWRzIHRoaXMgZmxhZy5cblxuXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFBlcmZvcm1lZFdvcms7XG5cbiAge1xuICAgIC8vIFN1cHBvcnQgZm9yIG1vZHVsZSBjb21wb25lbnRzIGlzIGRlcHJlY2F0ZWQgYW5kIGlzIHJlbW92ZWQgYmVoaW5kIGEgZmxhZy5cbiAgICAvLyBXaGV0aGVyIG9yIG5vdCBpdCB3b3VsZCBjcmFzaCBsYXRlciwgd2Ugd2FudCB0byBzaG93IGEgZ29vZCBtZXNzYWdlIGluIERFViBmaXJzdC5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUucmVuZGVyID09PSAnZnVuY3Rpb24nICYmIHZhbHVlLiQkdHlwZW9mID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBfY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50W19jb21wb25lbnROYW1lXSkge1xuICAgICAgICBlcnJvcignVGhlIDwlcyAvPiBjb21wb25lbnQgYXBwZWFycyB0byBiZSBhIGZ1bmN0aW9uIGNvbXBvbmVudCB0aGF0IHJldHVybnMgYSBjbGFzcyBpbnN0YW5jZS4gJyArICdDaGFuZ2UgJXMgdG8gYSBjbGFzcyB0aGF0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IGluc3RlYWQuICcgKyBcIklmIHlvdSBjYW4ndCB1c2UgYSBjbGFzcyB0cnkgYXNzaWduaW5nIHRoZSBwcm90b3R5cGUgb24gdGhlIGZ1bmN0aW9uIGFzIGEgd29ya2Fyb3VuZC4gXCIgKyBcImAlcy5wcm90b3R5cGUgPSBSZWFjdC5Db21wb25lbnQucHJvdG90eXBlYC4gRG9uJ3QgdXNlIGFuIGFycm93IGZ1bmN0aW9uIHNpbmNlIGl0IFwiICsgJ2Nhbm5vdCBiZSBjYWxsZWQgd2l0aCBgbmV3YCBieSBSZWFjdC4nLCBfY29tcG9uZW50TmFtZSwgX2NvbXBvbmVudE5hbWUsIF9jb21wb25lbnROYW1lKTtcblxuICAgICAgICBkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50W19jb21wb25lbnROYW1lXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKCAvLyBSdW4gdGhlc2UgY2hlY2tzIGluIHByb2R1Y3Rpb24gb25seSBpZiB0aGUgZmxhZyBpcyBvZmYuXG4gIC8vIEV2ZW50dWFsbHkgd2UnbGwgZGVsZXRlIHRoaXMgYnJhbmNoIGFsdG9nZXRoZXIuXG4gICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZS5yZW5kZXIgPT09ICdmdW5jdGlvbicgJiYgdmFsdWUuJCR0eXBlb2YgPT09IHVuZGVmaW5lZCkge1xuICAgIHtcbiAgICAgIHZhciBfY29tcG9uZW50TmFtZTIgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSB8fCAnVW5rbm93bic7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0TW9kdWxlUGF0dGVybkNvbXBvbmVudFtfY29tcG9uZW50TmFtZTJdKSB7XG4gICAgICAgIGVycm9yKCdUaGUgPCVzIC8+IGNvbXBvbmVudCBhcHBlYXJzIHRvIGJlIGEgZnVuY3Rpb24gY29tcG9uZW50IHRoYXQgcmV0dXJucyBhIGNsYXNzIGluc3RhbmNlLiAnICsgJ0NoYW5nZSAlcyB0byBhIGNsYXNzIHRoYXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQgaW5zdGVhZC4gJyArIFwiSWYgeW91IGNhbid0IHVzZSBhIGNsYXNzIHRyeSBhc3NpZ25pbmcgdGhlIHByb3RvdHlwZSBvbiB0aGUgZnVuY3Rpb24gYXMgYSB3b3JrYXJvdW5kLiBcIiArIFwiYCVzLnByb3RvdHlwZSA9IFJlYWN0LkNvbXBvbmVudC5wcm90b3R5cGVgLiBEb24ndCB1c2UgYW4gYXJyb3cgZnVuY3Rpb24gc2luY2UgaXQgXCIgKyAnY2Fubm90IGJlIGNhbGxlZCB3aXRoIGBuZXdgIGJ5IFJlYWN0LicsIF9jb21wb25lbnROYW1lMiwgX2NvbXBvbmVudE5hbWUyLCBfY29tcG9uZW50TmFtZTIpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dE1vZHVsZVBhdHRlcm5Db21wb25lbnRbX2NvbXBvbmVudE5hbWUyXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSAvLyBQcm9jZWVkIHVuZGVyIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhpcyBpcyBhIGNsYXNzIGluc3RhbmNlXG5cblxuICAgIHdvcmtJblByb2dyZXNzLnRhZyA9IENsYXNzQ29tcG9uZW50OyAvLyBUaHJvdyBvdXQgYW55IGhvb2tzIHRoYXQgd2VyZSB1c2VkLlxuXG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBudWxsOyAvLyBQdXNoIGNvbnRleHQgcHJvdmlkZXJzIGVhcmx5IHRvIHByZXZlbnQgY29udGV4dCBzdGFjayBtaXNtYXRjaGVzLlxuICAgIC8vIER1cmluZyBtb3VudGluZyB3ZSBkb24ndCBrbm93IHRoZSBjaGlsZCBjb250ZXh0IHlldCBhcyB0aGUgaW5zdGFuY2UgZG9lc24ndCBleGlzdC5cbiAgICAvLyBXZSB3aWxsIGludmFsaWRhdGUgdGhlIGNoaWxkIGNvbnRleHQgaW4gZmluaXNoQ2xhc3NDb21wb25lbnQoKSByaWdodCBhZnRlciByZW5kZXJpbmcuXG5cbiAgICB2YXIgaGFzQ29udGV4dCA9IGZhbHNlO1xuXG4gICAgaWYgKGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgIGhhc0NvbnRleHQgPSB0cnVlO1xuICAgICAgcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhhc0NvbnRleHQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gdmFsdWUuc3RhdGUgIT09IG51bGwgJiYgdmFsdWUuc3RhdGUgIT09IHVuZGVmaW5lZCA/IHZhbHVlLnN0YXRlIDogbnVsbDtcbiAgICBpbml0aWFsaXplVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MpO1xuICAgIGFkb3B0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgdmFsdWUpO1xuICAgIG1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBwcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgIHJldHVybiBmaW5pc2hDbGFzc0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCB0cnVlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gUHJvY2VlZCB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoaXMgaXMgYSBmdW5jdGlvbiBjb21wb25lbnRcbiAgICB3b3JrSW5Qcm9ncmVzcy50YWcgPSBGdW5jdGlvbkNvbXBvbmVudDtcblxuICAgIHtcblxuICAgICAgaWYgKCB3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyh0cnVlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHZhbHVlID0gcmVuZGVyV2l0aEhvb2tzKG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHByb3BzLCBjb250ZXh0LCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgaGFzSWQgPSBjaGVja0RpZFJlbmRlcklkSG9vaygpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIGhhc0lkKSB7XG4gICAgICBwdXNoTWF0ZXJpYWxpemVkVHJlZUlkKHdvcmtJblByb2dyZXNzKTtcbiAgICB9XG5cbiAgICByZWNvbmNpbGVDaGlsZHJlbihudWxsLCB3b3JrSW5Qcm9ncmVzcywgdmFsdWUsIHJlbmRlckxhbmVzKTtcblxuICAgIHtcbiAgICAgIHZhbGlkYXRlRnVuY3Rpb25Db21wb25lbnRJbkRldih3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVGdW5jdGlvbkNvbXBvbmVudEluRGV2KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQpIHtcbiAge1xuICAgIGlmIChDb21wb25lbnQpIHtcbiAgICAgIGlmIChDb21wb25lbnQuY2hpbGRDb250ZXh0VHlwZXMpIHtcbiAgICAgICAgZXJyb3IoJyVzKC4uLik6IGNoaWxkQ29udGV4dFR5cGVzIGNhbm5vdCBiZSBkZWZpbmVkIG9uIGEgZnVuY3Rpb24gY29tcG9uZW50LicsIENvbXBvbmVudC5kaXNwbGF5TmFtZSB8fCBDb21wb25lbnQubmFtZSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLnJlZiAhPT0gbnVsbCkge1xuICAgICAgdmFyIGluZm8gPSAnJztcbiAgICAgIHZhciBvd25lck5hbWUgPSBnZXRDdXJyZW50RmliZXJPd25lck5hbWVJbkRldk9yTnVsbCgpO1xuXG4gICAgICBpZiAob3duZXJOYW1lKSB7XG4gICAgICAgIGluZm8gKz0gJ1xcblxcbkNoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgb3duZXJOYW1lICsgJ2AuJztcbiAgICAgIH1cblxuICAgICAgdmFyIHdhcm5pbmdLZXkgPSBvd25lck5hbWUgfHwgJyc7XG4gICAgICB2YXIgZGVidWdTb3VyY2UgPSB3b3JrSW5Qcm9ncmVzcy5fZGVidWdTb3VyY2U7XG5cbiAgICAgIGlmIChkZWJ1Z1NvdXJjZSkge1xuICAgICAgICB3YXJuaW5nS2V5ID0gZGVidWdTb3VyY2UuZmlsZU5hbWUgKyAnOicgKyBkZWJ1Z1NvdXJjZS5saW5lTnVtYmVyO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dEZ1bmN0aW9uUmVmc1t3YXJuaW5nS2V5XSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRGdW5jdGlvblJlZnNbd2FybmluZ0tleV0gPSB0cnVlO1xuXG4gICAgICAgIGVycm9yKCdGdW5jdGlvbiBjb21wb25lbnRzIGNhbm5vdCBiZSBnaXZlbiByZWZzLiAnICsgJ0F0dGVtcHRzIHRvIGFjY2VzcyB0aGlzIHJlZiB3aWxsIGZhaWwuICcgKyAnRGlkIHlvdSBtZWFuIHRvIHVzZSBSZWFjdC5mb3J3YXJkUmVmKCk/JXMnLCBpbmZvKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIENvbXBvbmVudC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBfY29tcG9uZW50TmFtZTMgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSB8fCAnVW5rbm93bic7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0R2V0RGVyaXZlZFN0YXRlT25GdW5jdGlvbkNvbXBvbmVudFtfY29tcG9uZW50TmFtZTNdKSB7XG4gICAgICAgIGVycm9yKCclczogRnVuY3Rpb24gY29tcG9uZW50cyBkbyBub3Qgc3VwcG9ydCBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuJywgX2NvbXBvbmVudE5hbWUzKTtcblxuICAgICAgICBkaWRXYXJuQWJvdXRHZXREZXJpdmVkU3RhdGVPbkZ1bmN0aW9uQ29tcG9uZW50W19jb21wb25lbnROYW1lM10gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgQ29tcG9uZW50LmNvbnRleHRUeXBlID09PSAnb2JqZWN0JyAmJiBDb21wb25lbnQuY29udGV4dFR5cGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBfY29tcG9uZW50TmFtZTQgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSB8fCAnVW5rbm93bic7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0Q29udGV4dFR5cGVPbkZ1bmN0aW9uQ29tcG9uZW50W19jb21wb25lbnROYW1lNF0pIHtcbiAgICAgICAgZXJyb3IoJyVzOiBGdW5jdGlvbiBjb21wb25lbnRzIGRvIG5vdCBzdXBwb3J0IGNvbnRleHRUeXBlLicsIF9jb21wb25lbnROYW1lNCk7XG5cbiAgICAgICAgZGlkV2FybkFib3V0Q29udGV4dFR5cGVPbkZ1bmN0aW9uQ29tcG9uZW50W19jb21wb25lbnROYW1lNF0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgU1VTUEVOREVEX01BUktFUiA9IHtcbiAgZGVoeWRyYXRlZDogbnVsbCxcbiAgdHJlZUNvbnRleHQ6IG51bGwsXG4gIHJldHJ5TGFuZTogTm9MYW5lXG59O1xuXG5mdW5jdGlvbiBtb3VudFN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocmVuZGVyTGFuZXMpIHtcbiAgcmV0dXJuIHtcbiAgICBiYXNlTGFuZXM6IHJlbmRlckxhbmVzLFxuICAgIGNhY2hlUG9vbDogZ2V0U3VzcGVuZGVkQ2FjaGUoKSxcbiAgICB0cmFuc2l0aW9uczogbnVsbFxuICB9O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdXNwZW5zZU9mZnNjcmVlblN0YXRlKHByZXZPZmZzY3JlZW5TdGF0ZSwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIGNhY2hlUG9vbCA9IG51bGw7XG5cbiAgcmV0dXJuIHtcbiAgICBiYXNlTGFuZXM6IG1lcmdlTGFuZXMocHJldk9mZnNjcmVlblN0YXRlLmJhc2VMYW5lcywgcmVuZGVyTGFuZXMpLFxuICAgIGNhY2hlUG9vbDogY2FjaGVQb29sLFxuICAgIHRyYW5zaXRpb25zOiBwcmV2T2Zmc2NyZWVuU3RhdGUudHJhbnNpdGlvbnNcbiAgfTtcbn0gLy8gVE9ETzogUHJvYmFibHkgc2hvdWxkIGlubGluZSB0aGlzIGJhY2tcblxuXG5mdW5jdGlvbiBzaG91bGRSZW1haW5PbkZhbGxiYWNrKHN1c3BlbnNlQ29udGV4dCwgY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIC8vIElmIHdlJ3JlIGFscmVhZHkgc2hvd2luZyBhIGZhbGxiYWNrLCB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgd2UgbmVlZCB0b1xuICAvLyByZW1haW4gb24gdGhhdCBmYWxsYmFjayByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIGNvbnRlbnQgaGFzIHJlc29sdmVkLlxuICAvLyBGb3IgZXhhbXBsZSwgU3VzcGVuc2VMaXN0IGNvb3JkaW5hdGVzIHdoZW4gbmVzdGVkIGNvbnRlbnQgYXBwZWFycy5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICB2YXIgc3VzcGVuc2VTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgIGlmIChzdXNwZW5zZVN0YXRlID09PSBudWxsKSB7XG4gICAgICAvLyBDdXJyZW50bHkgc2hvd2luZyBjb250ZW50LiBEb24ndCBoaWRlIGl0LCBldmVuIGlmIEZvcmNlU3VzcGVuc2VGYWxsYmFja1xuICAgICAgLy8gaXMgdHJ1ZS4gTW9yZSBwcmVjaXNlIG5hbWUgbWlnaHQgYmUgXCJGb3JjZVJlbWFpblN1c3BlbnNlRmFsbGJhY2tcIi5cbiAgICAgIC8vIE5vdGU6IFRoaXMgaXMgYSBmYWN0b3Jpbmcgc21lbGwuIENhbid0IHJlbWFpbiBvbiBhIGZhbGxiYWNrIGlmIHRoZXJlJ3NcbiAgICAgIC8vIG5vIGZhbGxiYWNrIHRvIHJlbWFpbiBvbi5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0gLy8gTm90IGN1cnJlbnRseSBzaG93aW5nIGNvbnRlbnQuIENvbnN1bHQgdGhlIFN1c3BlbnNlIGNvbnRleHQuXG5cblxuICByZXR1cm4gaGFzU3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlQ29udGV4dCwgRm9yY2VTdXNwZW5zZUZhbGxiYWNrKTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVtYWluaW5nV29ya0luUHJpbWFyeVRyZWUoY3VycmVudCwgcmVuZGVyTGFuZXMpIHtcbiAgLy8gVE9ETzogU2hvdWxkIG5vdCByZW1vdmUgcmVuZGVyIGxhbmVzIHRoYXQgd2VyZSBwaW5nZWQgZHVyaW5nIHRoaXMgcmVuZGVyXG4gIHJldHVybiByZW1vdmVMYW5lcyhjdXJyZW50LmNoaWxkTGFuZXMsIHJlbmRlckxhbmVzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU3VzcGVuc2VDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7IC8vIFRoaXMgaXMgdXNlZCBieSBEZXZUb29scyB0byBmb3JjZSBhIGJvdW5kYXJ5IHRvIHN1c3BlbmQuXG5cbiAge1xuICAgIGlmIChzaG91bGRTdXNwZW5kKHdvcmtJblByb2dyZXNzKSkge1xuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICB9XG4gIH1cblxuICB2YXIgc3VzcGVuc2VDb250ZXh0ID0gc3VzcGVuc2VTdGFja0N1cnNvci5jdXJyZW50O1xuICB2YXIgc2hvd0ZhbGxiYWNrID0gZmFsc2U7XG4gIHZhciBkaWRTdXNwZW5kID0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3M7XG5cbiAgaWYgKGRpZFN1c3BlbmQgfHwgc2hvdWxkUmVtYWluT25GYWxsYmFjayhzdXNwZW5zZUNvbnRleHQsIGN1cnJlbnQpKSB7XG4gICAgLy8gU29tZXRoaW5nIGluIHRoaXMgYm91bmRhcnkncyBzdWJ0cmVlIGFscmVhZHkgc3VzcGVuZGVkLiBTd2l0Y2ggdG9cbiAgICAvLyByZW5kZXJpbmcgdGhlIGZhbGxiYWNrIGNoaWxkcmVuLlxuICAgIHNob3dGYWxsYmFjayA9IHRydWU7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJj0gfkRpZENhcHR1cmU7XG4gIH0gZWxzZSB7XG4gICAgLy8gQXR0ZW1wdGluZyB0aGUgbWFpbiBjb250ZW50XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwgfHwgY3VycmVudC5tZW1vaXplZFN0YXRlICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIGEgbmV3IG1vdW50IG9yIHRoaXMgYm91bmRhcnkgaXMgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2sgc3RhdGUuXG4gICAgICAvLyBNYXJrIHRoaXMgc3VidHJlZSBjb250ZXh0IGFzIGhhdmluZyBhdCBsZWFzdCBvbmUgaW52aXNpYmxlIHBhcmVudCB0aGF0IGNvdWxkXG4gICAgICAvLyBoYW5kbGUgdGhlIGZhbGxiYWNrIHN0YXRlLlxuICAgICAgLy8gQXZvaWRlZCBib3VuZGFyaWVzIGFyZSBub3QgY29uc2lkZXJlZCBzaW5jZSB0aGV5IGNhbm5vdCBoYW5kbGUgcHJlZmVycmVkIGZhbGxiYWNrIHN0YXRlcy5cbiAgICAgIHtcbiAgICAgICAgc3VzcGVuc2VDb250ZXh0ID0gYWRkU3VidHJlZVN1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQsIEludmlzaWJsZVBhcmVudFN1c3BlbnNlQ29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3VzcGVuc2VDb250ZXh0ID0gc2V0RGVmYXVsdFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0KTtcbiAgcHVzaFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuc2VDb250ZXh0KTsgLy8gT0ssIHRoZSBuZXh0IHBhcnQgaXMgY29uZnVzaW5nLiBXZSdyZSBhYm91dCB0byByZWNvbmNpbGUgdGhlIFN1c3BlbnNlXG4gIC8vIGJvdW5kYXJ5J3MgY2hpbGRyZW4uIFRoaXMgaW52b2x2ZXMgc29tZSBjdXN0b20gcmVjb25jaWxpYXRpb24gbG9naWMuIFR3b1xuICAvLyBtYWluIHJlYXNvbnMgdGhpcyBpcyBzbyBjb21wbGljYXRlZC5cbiAgLy9cbiAgLy8gRmlyc3QsIExlZ2FjeSBNb2RlIGhhcyBkaWZmZXJlbnQgc2VtYW50aWNzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4gVGhlXG4gIC8vIHByaW1hcnkgdHJlZSB3aWxsIGNvbW1pdCBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUsIHNvIHdoZW4gd2UgZG8gdGhlXG4gIC8vIHNlY29uZCBwYXNzIHRvIHJlbmRlciB0aGUgZmFsbGJhY2ssIHdlIGRvIHNvbWUgZXhjZWVkaW5nbHksIHVoLCBjbGV2ZXJcbiAgLy8gaGFja3MgdG8gbWFrZSB0aGF0IG5vdCB0b3RhbGx5IGJyZWFrLiBMaWtlIHRyYW5zZmVycmluZyBlZmZlY3RzIGFuZFxuICAvLyBkZWxldGlvbnMgZnJvbSBoaWRkZW4gdHJlZS4gSW4gQ29uY3VycmVudCBNb2RlLCBpdCdzIG11Y2ggc2ltcGxlcixcbiAgLy8gYmVjYXVzZSB3ZSBiYWlsb3V0IG9uIHRoZSBwcmltYXJ5IHRyZWUgY29tcGxldGVseSBhbmQgbGVhdmUgaXQgaW4gaXRzIG9sZFxuICAvLyBzdGF0ZSwgbm8gZWZmZWN0cy4gU2FtZSBhcyB3aGF0IHdlIGRvIGZvciBPZmZzY3JlZW4gKGV4Y2VwdCB0aGF0XG4gIC8vIE9mZnNjcmVlbiBkb2Vzbid0IGhhdmUgdGhlIGZpcnN0IHJlbmRlciBwYXNzKS5cbiAgLy9cbiAgLy8gU2Vjb25kIGlzIGh5ZHJhdGlvbi4gRHVyaW5nIGh5ZHJhdGlvbiwgdGhlIFN1c3BlbnNlIGZpYmVyIGhhcyBhIHNsaWdodGx5XG4gIC8vIGRpZmZlcmVudCBsYXlvdXQsIHdoZXJlIHRoZSBjaGlsZCBwb2ludHMgdG8gYSBkZWh5ZHJhdGVkIGZyYWdtZW50LCB3aGljaFxuICAvLyBjb250YWlucyB0aGUgRE9NIHJlbmRlcmVkIGJ5IHRoZSBzZXJ2ZXIuXG4gIC8vXG4gIC8vIFRoaXJkLCBldmVuIGlmIHlvdSBzZXQgYWxsIHRoYXQgYXNpZGUsIFN1c3BlbnNlIGlzIGxpa2UgZXJyb3IgYm91bmRhcmllcyBpblxuICAvLyB0aGF0IHdlIGZpcnN0IHdlIHRyeSB0byByZW5kZXIgb25lIHRyZWUsIGFuZCBpZiB0aGF0IGZhaWxzLCB3ZSByZW5kZXIgYWdhaW5cbiAgLy8gYW5kIHN3aXRjaCB0byBhIGRpZmZlcmVudCB0cmVlLiBMaWtlIGEgdHJ5L2NhdGNoIGJsb2NrLiBTbyB3ZSBoYXZlIHRvIHRyYWNrXG4gIC8vIHdoaWNoIGJyYW5jaCB3ZSdyZSBjdXJyZW50bHkgcmVuZGVyaW5nLiBJZGVhbGx5IHdlIHdvdWxkIG1vZGVsIHRoaXMgdXNpbmdcbiAgLy8gYSBzdGFjay5cblxuICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgIC8vIEluaXRpYWwgbW91bnRcbiAgICAvLyBJZiB3ZSdyZSBjdXJyZW50bHkgaHlkcmF0aW5nLCB0cnkgdG8gaHlkcmF0ZSB0aGlzIGJvdW5kYXJ5LlxuICAgIHRyeVRvQ2xhaW1OZXh0SHlkcmF0YWJsZUluc3RhbmNlKHdvcmtJblByb2dyZXNzKTsgLy8gVGhpcyBjb3VsZCd2ZSBiZWVuIGEgZGVoeWRyYXRlZCBzdXNwZW5zZSBjb21wb25lbnQuXG5cbiAgICB2YXIgc3VzcGVuc2VTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIGRlaHlkcmF0ZWQgPSBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQ7XG5cbiAgICAgIGlmIChkZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtb3VudERlaHlkcmF0ZWRTdXNwZW5zZUNvbXBvbmVudCh3b3JrSW5Qcm9ncmVzcywgZGVoeWRyYXRlZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG5leHRQcmltYXJ5Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gICAgdmFyIG5leHRGYWxsYmFja0NoaWxkcmVuID0gbmV4dFByb3BzLmZhbGxiYWNrO1xuXG4gICAgaWYgKHNob3dGYWxsYmFjaykge1xuICAgICAgdmFyIGZhbGxiYWNrRnJhZ21lbnQgPSBtb3VudFN1c3BlbnNlRmFsbGJhY2tDaGlsZHJlbih3b3JrSW5Qcm9ncmVzcywgbmV4dFByaW1hcnlDaGlsZHJlbiwgbmV4dEZhbGxiYWNrQ2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQubWVtb2l6ZWRTdGF0ZSA9IG1vdW50U3VzcGVuc2VPZmZzY3JlZW5TdGF0ZShyZW5kZXJMYW5lcyk7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gU1VTUEVOREVEX01BUktFUjtcblxuICAgICAgcmV0dXJuIGZhbGxiYWNrRnJhZ21lbnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBtb3VudFN1c3BlbnNlUHJpbWFyeUNoaWxkcmVuKHdvcmtJblByb2dyZXNzLCBuZXh0UHJpbWFyeUNoaWxkcmVuKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBhbiB1cGRhdGUuXG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgZmliZXIgaGFzIGEgU3VzcGVuc2VTdGF0ZSwgdGhhdCBtZWFucyBpdCdzIGFscmVhZHkgc2hvd2luZ1xuICAgIC8vIGEgZmFsbGJhY2suXG4gICAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoZSBjdXJyZW50IHRyZWUgaXMgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2tcbiAgICAgIC8vIFNwZWNpYWwgcGF0aCBmb3IgaHlkcmF0aW9uXG4gICAgICB2YXIgX2RlaHlkcmF0ZWQgPSBwcmV2U3RhdGUuZGVoeWRyYXRlZDtcblxuICAgICAgaWYgKF9kZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgICAgIGlmICghZGlkU3VzcGVuZCkge1xuICAgICAgICAgIHJldHVybiB1cGRhdGVEZWh5ZHJhdGVkU3VzcGVuc2VDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIF9kZWh5ZHJhdGVkLCBwcmV2U3RhdGUsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgfSBlbHNlIGlmICh3b3JrSW5Qcm9ncmVzcy5mbGFncyAmIEZvcmNlQ2xpZW50UmVuZGVyKSB7XG4gICAgICAgICAgLy8gU29tZXRoaW5nIGVycm9yZWQgZHVyaW5nIGh5ZHJhdGlvbi4gVHJ5IGFnYWluIHdpdGhvdXQgaHlkcmF0aW5nLlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzICY9IH5Gb3JjZUNsaWVudFJlbmRlcjtcbiAgICAgICAgICByZXR1cm4gcmV0cnlTdXNwZW5zZUNvbXBvbmVudFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzLCBuZXcgRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBoeWRyYXRpbmcgdGhpcyBTdXNwZW5zZSBib3VuZGFyeS4gJyArICdTd2l0Y2hlZCB0byBjbGllbnQgcmVuZGVyaW5nLicpKTtcbiAgICAgICAgfSBlbHNlIGlmICh3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gU29tZXRoaW5nIHN1c3BlbmRlZCBhbmQgd2Ugc2hvdWxkIHN0aWxsIGJlIGluIGRlaHlkcmF0ZWQgbW9kZS5cbiAgICAgICAgICAvLyBMZWF2ZSB0aGUgZXhpc3RpbmcgY2hpbGQgaW4gcGxhY2UuXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBjdXJyZW50LmNoaWxkOyAvLyBUaGUgZGVoeWRyYXRlZCBjb21wbGV0aW9uIHBhc3MgZXhwZWN0cyB0aGlzIGZsYWcgdG8gYmUgdGhlcmVcbiAgICAgICAgICAvLyBidXQgdGhlIG5vcm1hbCBzdXNwZW5zZSBwYXNzIGRvZXNuJ3QuXG5cbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFN1c3BlbmRlZCBidXQgd2Ugc2hvdWxkIG5vIGxvbmdlciBiZSBpbiBkZWh5ZHJhdGVkIG1vZGUuXG4gICAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5vdyBoYXZlIHRvIHJlbmRlciB0aGUgZmFsbGJhY2suXG4gICAgICAgICAgdmFyIF9uZXh0UHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICAgICAgICAgIHZhciBfbmV4dEZhbGxiYWNrQ2hpbGRyZW4gPSBuZXh0UHJvcHMuZmFsbGJhY2s7XG4gICAgICAgICAgdmFyIGZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IG1vdW50U3VzcGVuc2VGYWxsYmFja0FmdGVyUmV0cnlXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBfbmV4dFByaW1hcnlDaGlsZHJlbiwgX25leHRGYWxsYmFja0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDIgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgICBfcHJpbWFyeUNoaWxkRnJhZ21lbnQyLm1lbW9pemVkU3RhdGUgPSBtb3VudFN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocmVuZGVyTGFuZXMpO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBTVVNQRU5ERURfTUFSS0VSO1xuICAgICAgICAgIHJldHVybiBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHNob3dGYWxsYmFjaykge1xuICAgICAgICB2YXIgX25leHRGYWxsYmFja0NoaWxkcmVuMiA9IG5leHRQcm9wcy5mYWxsYmFjaztcbiAgICAgICAgdmFyIF9uZXh0UHJpbWFyeUNoaWxkcmVuMiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcblxuICAgICAgICB2YXIgX2ZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IHVwZGF0ZVN1c3BlbnNlRmFsbGJhY2tDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX25leHRQcmltYXJ5Q2hpbGRyZW4yLCBfbmV4dEZhbGxiYWNrQ2hpbGRyZW4yLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDMgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgdmFyIHByZXZPZmZzY3JlZW5TdGF0ZSA9IGN1cnJlbnQuY2hpbGQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgX3ByaW1hcnlDaGlsZEZyYWdtZW50My5tZW1vaXplZFN0YXRlID0gcHJldk9mZnNjcmVlblN0YXRlID09PSBudWxsID8gbW91bnRTdXNwZW5zZU9mZnNjcmVlblN0YXRlKHJlbmRlckxhbmVzKSA6IHVwZGF0ZVN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocHJldk9mZnNjcmVlblN0YXRlLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgICAgX3ByaW1hcnlDaGlsZEZyYWdtZW50My5jaGlsZExhbmVzID0gZ2V0UmVtYWluaW5nV29ya0luUHJpbWFyeVRyZWUoY3VycmVudCwgcmVuZGVyTGFuZXMpO1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gU1VTUEVOREVEX01BUktFUjtcbiAgICAgICAgcmV0dXJuIF9mYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgX25leHRQcmltYXJ5Q2hpbGRyZW4zID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuXG4gICAgICAgIHZhciBfcHJpbWFyeUNoaWxkRnJhZ21lbnQ0ID0gdXBkYXRlU3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIF9uZXh0UHJpbWFyeUNoaWxkcmVuMywgcmVuZGVyTGFuZXMpO1xuXG4gICAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgICByZXR1cm4gX3ByaW1hcnlDaGlsZEZyYWdtZW50NDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIGN1cnJlbnQgdHJlZSBpcyBub3QgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2suXG4gICAgICBpZiAoc2hvd0ZhbGxiYWNrKSB7XG4gICAgICAgIC8vIFRpbWVkIG91dC5cbiAgICAgICAgdmFyIF9uZXh0RmFsbGJhY2tDaGlsZHJlbjMgPSBuZXh0UHJvcHMuZmFsbGJhY2s7XG4gICAgICAgIHZhciBfbmV4dFByaW1hcnlDaGlsZHJlbjQgPSBuZXh0UHJvcHMuY2hpbGRyZW47XG5cbiAgICAgICAgdmFyIF9mYWxsYmFja0NoaWxkRnJhZ21lbnQyID0gdXBkYXRlU3VzcGVuc2VGYWxsYmFja0NoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBfbmV4dFByaW1hcnlDaGlsZHJlbjQsIF9uZXh0RmFsbGJhY2tDaGlsZHJlbjMsIHJlbmRlckxhbmVzKTtcblxuICAgICAgICB2YXIgX3ByaW1hcnlDaGlsZEZyYWdtZW50NSA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICB2YXIgX3ByZXZPZmZzY3JlZW5TdGF0ZSA9IGN1cnJlbnQuY2hpbGQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgX3ByaW1hcnlDaGlsZEZyYWdtZW50NS5tZW1vaXplZFN0YXRlID0gX3ByZXZPZmZzY3JlZW5TdGF0ZSA9PT0gbnVsbCA/IG1vdW50U3VzcGVuc2VPZmZzY3JlZW5TdGF0ZShyZW5kZXJMYW5lcykgOiB1cGRhdGVTdXNwZW5zZU9mZnNjcmVlblN0YXRlKF9wcmV2T2Zmc2NyZWVuU3RhdGUsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgX3ByaW1hcnlDaGlsZEZyYWdtZW50NS5jaGlsZExhbmVzID0gZ2V0UmVtYWluaW5nV29ya0luUHJpbWFyeVRyZWUoY3VycmVudCwgcmVuZGVyTGFuZXMpO1xuICAgICAgICAvLyBmYWxsYmFjayBjaGlsZHJlbi5cblxuXG4gICAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBTVVNQRU5ERURfTUFSS0VSO1xuICAgICAgICByZXR1cm4gX2ZhbGxiYWNrQ2hpbGRGcmFnbWVudDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTdGlsbCBoYXZlbid0IHRpbWVkIG91dC4gQ29udGludWUgcmVuZGVyaW5nIHRoZSBjaGlsZHJlbiwgbGlrZSB3ZVxuICAgICAgICAvLyBub3JtYWxseSBkby5cbiAgICAgICAgdmFyIF9uZXh0UHJpbWFyeUNoaWxkcmVuNSA9IG5leHRQcm9wcy5jaGlsZHJlbjtcblxuICAgICAgICB2YXIgX3ByaW1hcnlDaGlsZEZyYWdtZW50NiA9IHVwZGF0ZVN1c3BlbnNlUHJpbWFyeUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBfbmV4dFByaW1hcnlDaGlsZHJlbjUsIHJlbmRlckxhbmVzKTtcblxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDY7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfTtcbiAgdmFyIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBtb2RlKTtcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHJldHVybiBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gbW91bnRTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgZmFsbGJhY2tDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ2hpZGRlbicsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKChtb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgIC8vIEluIGxlZ2FjeSBtb2RlLCB3ZSBjb21taXQgdGhlIHByaW1hcnkgdHJlZSBhcyBpZiBpdCBzdWNjZXNzZnVsbHlcbiAgICAvLyBjb21wbGV0ZWQsIGV2ZW4gdGhvdWdoIGl0J3MgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLlxuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudDtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5wZW5kaW5nUHJvcHMgPSBwcmltYXJ5Q2hpbGRQcm9wcztcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAvLyBSZXNldCB0aGUgZHVyYXRpb25zIGZyb20gdGhlIGZpcnN0IHBhc3Mgc28gdGhleSBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlXG4gICAgICAvLyBmaW5hbCBhbW91bnRzLiBUaGlzIHNlZW1zIGNvdW50ZXJpbnR1aXRpdmUsIHNpbmNlIHdlJ3JlIGludGVudGlvbmFsbHlcbiAgICAgIC8vIG5vdCBtZWFzdXJpbmcgcGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLCBidXQgdGhpcyBtYWtlcyBpdCBtYXRjaCB3aGF0IHdlXG4gICAgICAvLyBkbyBpbiBDb25jdXJyZW50IE1vZGUuXG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnNlbGZCYXNlRHVyYXRpb24gPSAwO1xuICAgICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgbW9kZSwgcmVuZGVyTGFuZXMsIG51bGwpO1xuICB9IGVsc2Uge1xuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBtb2RlKTtcbiAgICBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmYWxsYmFja0NoaWxkcmVuLCBtb2RlLCByZW5kZXJMYW5lcywgbnVsbCk7XG4gIH1cblxuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5zaWJsaW5nID0gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICByZXR1cm4gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xufVxuXG5mdW5jdGlvbiBtb3VudFdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIob2Zmc2NyZWVuUHJvcHMsIG1vZGUsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoZSBwcm9wcyBhcmd1bWVudCB0byBgY3JlYXRlRmliZXJGcm9tT2Zmc2NyZWVuYCBpcyBgYW55YCB0eXBlZCwgc28gd2UgdXNlXG4gIC8vIHRoaXMgd3JhcHBlciBmdW5jdGlvbiB0byBjb25zdHJhaW4gaXQuXG4gIHJldHVybiBjcmVhdGVGaWJlckZyb21PZmZzY3JlZW4ob2Zmc2NyZWVuUHJvcHMsIG1vZGUsIE5vTGFuZXMsIG51bGwpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKGN1cnJlbnQsIG9mZnNjcmVlblByb3BzKSB7XG4gIC8vIFRoZSBwcm9wcyBhcmd1bWVudCB0byBgY3JlYXRlV29ya0luUHJvZ3Jlc3NgIGlzIGBhbnlgIHR5cGVkLCBzbyB3ZSB1c2UgdGhpc1xuICAvLyB3cmFwcGVyIGZ1bmN0aW9uIHRvIGNvbnN0cmFpbiBpdC5cbiAgcmV0dXJuIGNyZWF0ZVdvcmtJblByb2dyZXNzKGN1cnJlbnQsIG9mZnNjcmVlblByb3BzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudCA9IGN1cnJlbnQuY2hpbGQ7XG4gIHZhciBjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmc7XG4gIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHVwZGF0ZVdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIoY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LCB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfSk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5sYW5lcyA9IHJlbmRlckxhbmVzO1xuICB9XG5cbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBudWxsO1xuXG4gIGlmIChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgLy8gRGVsZXRlIHRoZSBmYWxsYmFjayBjaGlsZCBmcmFnbWVudFxuICAgIHZhciBkZWxldGlvbnMgPSB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnM7XG5cbiAgICBpZiAoZGVsZXRpb25zID09PSBudWxsKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnMgPSBbY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudF07XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGlvbnMucHVzaChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50KTtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICByZXR1cm4gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1c3BlbnNlRmFsbGJhY2tDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcHJpbWFyeUNoaWxkcmVuLCBmYWxsYmFja0NoaWxkcmVuLCByZW5kZXJMYW5lcykge1xuICB2YXIgbW9kZSA9IHdvcmtJblByb2dyZXNzLm1vZGU7XG4gIHZhciBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBjdXJyZW50LmNoaWxkO1xuICB2YXIgY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudC5zaWJsaW5nO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ2hpZGRlbicsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKCAvLyBJbiBsZWdhY3kgbW9kZSwgd2UgY29tbWl0IHRoZSBwcmltYXJ5IHRyZWUgYXMgaWYgaXQgc3VjY2Vzc2Z1bGx5XG4gIC8vIGNvbXBsZXRlZCwgZXZlbiB0aG91Z2ggaXQncyBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUuXG4gIChtb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgLy8gTWFrZSBzdXJlIHdlJ3JlIG9uIHRoZSBzZWNvbmQgcGFzcywgaS5lLiB0aGUgcHJpbWFyeSBjaGlsZCBmcmFnbWVudCB3YXNcbiAgLy8gYWxyZWFkeSBjbG9uZWQuIEluIGxlZ2FjeSBtb2RlLCB0aGUgb25seSBjYXNlIHdoZXJlIHRoaXMgaXNuJ3QgdHJ1ZSBpc1xuICAvLyB3aGVuIERldlRvb2xzIGZvcmNlcyB1cyB0byBkaXNwbGF5IGEgZmFsbGJhY2s7IHdlIHNraXAgdGhlIGZpcnN0IHJlbmRlclxuICAvLyBwYXNzIGVudGlyZWx5IGFuZCBnbyBzdHJhaWdodCB0byByZW5kZXJpbmcgdGhlIGZhbGxiYWNrLiAoSW4gQ29uY3VycmVudFxuICAvLyBNb2RlLCBTdXNwZW5zZUxpc3QgY2FuIGFsc28gdHJpZ2dlciB0aGlzIHNjZW5hcmlvLCBidXQgdGhpcyBpcyBhIGxlZ2FjeS1cbiAgLy8gb25seSBjb2RlcGF0aC4pXG4gIHdvcmtJblByb2dyZXNzLmNoaWxkICE9PSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQpIHtcbiAgICB2YXIgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudDtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5wZW5kaW5nUHJvcHMgPSBwcmltYXJ5Q2hpbGRQcm9wcztcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAvLyBSZXNldCB0aGUgZHVyYXRpb25zIGZyb20gdGhlIGZpcnN0IHBhc3Mgc28gdGhleSBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlXG4gICAgICAvLyBmaW5hbCBhbW91bnRzLiBUaGlzIHNlZW1zIGNvdW50ZXJpbnR1aXRpdmUsIHNpbmNlIHdlJ3JlIGludGVudGlvbmFsbHlcbiAgICAgIC8vIG5vdCBtZWFzdXJpbmcgcGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLCBidXQgdGhpcyBtYWtlcyBpdCBtYXRjaCB3aGF0IHdlXG4gICAgICAvLyBkbyBpbiBDb25jdXJyZW50IE1vZGUuXG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnNlbGZCYXNlRHVyYXRpb24gPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnRyZWVCYXNlRHVyYXRpb24gPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbjtcbiAgICB9XG4gICAgLy8gSG93ZXZlciwgc2luY2Ugd2UncmUgZ29pbmcgdG8gcmVtYWluIG9uIHRoZSBmYWxsYmFjaywgd2Ugbm8gbG9uZ2VyIHdhbnRcbiAgICAvLyB0byBkZWxldGUgaXQuXG5cblxuICAgIHdvcmtJblByb2dyZXNzLmRlbGV0aW9ucyA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudCwgcHJpbWFyeUNoaWxkUHJvcHMpO1xuICAgIC8vIChXZSBkb24ndCBkbyB0aGlzIGluIGxlZ2FjeSBtb2RlLCBiZWNhdXNlIGluIGxlZ2FjeSBtb2RlIHdlIGRvbid0IHJlLXVzZVxuICAgIC8vIHRoZSBjdXJyZW50IHRyZWU7IHNlZSBwcmV2aW91cyBicmFuY2guKVxuXG5cbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5zdWJ0cmVlRmxhZ3MgPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQuc3VidHJlZUZsYWdzICYgU3RhdGljTWFzaztcbiAgfVxuXG4gIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKGN1cnJlbnRGYWxsYmFja0NoaWxkRnJhZ21lbnQgIT09IG51bGwpIHtcbiAgICBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50LCBmYWxsYmFja0NoaWxkcmVuKTtcbiAgfSBlbHNlIHtcbiAgICBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmYWxsYmFja0NoaWxkcmVuLCBtb2RlLCByZW5kZXJMYW5lcywgbnVsbCk7IC8vIE5lZWRzIGEgcGxhY2VtZW50IGVmZmVjdCBiZWNhdXNlIHRoZSBwYXJlbnQgKHRoZSBTdXNwZW5zZSBib3VuZGFyeSkgYWxyZWFkeVxuICAgIC8vIG1vdW50ZWQgYnV0IHRoaXMgaXMgYSBuZXcgZmliZXIuXG5cbiAgICBmYWxsYmFja0NoaWxkRnJhZ21lbnQuZmxhZ3MgfD0gUGxhY2VtZW50O1xuICB9XG5cbiAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQuc2libGluZyA9IGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbiAgcmV0dXJuIGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gcmV0cnlTdXNwZW5zZUNvbXBvbmVudFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzLCByZWNvdmVyYWJsZUVycm9yKSB7XG4gIC8vIEZhbGxpbmcgYmFjayB0byBjbGllbnQgcmVuZGVyaW5nLiBCZWNhdXNlIHRoaXMgaGFzIHBlcmZvcm1hbmNlXG4gIC8vIGltcGxpY2F0aW9ucywgaXQncyBjb25zaWRlcmVkIGEgcmVjb3ZlcmFibGUgZXJyb3IsIGV2ZW4gdGhvdWdoIHRoZSB1c2VyXG4gIC8vIGxpa2VseSB3b24ndCBvYnNlcnZlIGFueXRoaW5nIHdyb25nIHdpdGggdGhlIFVJLlxuICAvL1xuICAvLyBUaGUgZXJyb3IgaXMgcGFzc2VkIGluIGFzIGFuIGFyZ3VtZW50IHRvIGVuZm9yY2UgdGhhdCBldmVyeSBjYWxsZXIgcHJvdmlkZVxuICAvLyBhIGN1c3RvbSBtZXNzYWdlLCBvciBleHBsaWNpdGx5IG9wdCBvdXQgKGN1cnJlbnRseSB0aGUgb25seSBwYXRoIHRoYXQgb3B0c1xuICAvLyBvdXQgaXMgbGVnYWN5IG1vZGU7IGV2ZXJ5IGNvbmN1cnJlbnQgcGF0aCBwcm92aWRlcyBhbiBlcnJvcikuXG4gIGlmIChyZWNvdmVyYWJsZUVycm9yICE9PSBudWxsKSB7XG4gICAgcXVldWVIeWRyYXRpb25FcnJvcihyZWNvdmVyYWJsZUVycm9yKTtcbiAgfSAvLyBUaGlzIHdpbGwgYWRkIHRoZSBvbGQgZmliZXIgdG8gdGhlIGRlbGV0aW9uIGxpc3RcblxuXG4gIHJlY29uY2lsZUNoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBjdXJyZW50LmNoaWxkLCBudWxsLCByZW5kZXJMYW5lcyk7IC8vIFdlJ3JlIG5vdyBub3Qgc3VzcGVuZGVkIG5vciBkZWh5ZHJhdGVkLlxuXG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBwcmltYXJ5Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IG1vdW50U3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbik7IC8vIE5lZWRzIGEgcGxhY2VtZW50IGVmZmVjdCBiZWNhdXNlIHRoZSBwYXJlbnQgKHRoZSBTdXNwZW5zZSBib3VuZGFyeSkgYWxyZWFkeVxuICAvLyBtb3VudGVkIGJ1dCB0aGlzIGlzIGEgbmV3IGZpYmVyLlxuXG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG51bGw7XG4gIHJldHVybiBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gbW91bnRTdXNwZW5zZUZhbGxiYWNrQWZ0ZXJSZXRyeVdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgZmFsbGJhY2tDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIGZpYmVyTW9kZSA9IHdvcmtJblByb2dyZXNzLm1vZGU7XG4gIHZhciBwcmltYXJ5Q2hpbGRQcm9wcyA9IHtcbiAgICBtb2RlOiAndmlzaWJsZScsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBtb3VudFdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIocHJpbWFyeUNoaWxkUHJvcHMsIGZpYmVyTW9kZSk7XG4gIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmYWxsYmFja0NoaWxkcmVuLCBmaWJlck1vZGUsIHJlbmRlckxhbmVzLCBudWxsKTsgLy8gTmVlZHMgYSBwbGFjZW1lbnQgZWZmZWN0IGJlY2F1c2UgdGhlIHBhcmVudCAodGhlIFN1c3BlbnNlXG4gIC8vIGJvdW5kYXJ5KSBhbHJlYWR5IG1vdW50ZWQgYnV0IHRoaXMgaXMgYSBuZXcgZmliZXIuXG5cbiAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIGZhbGxiYWNrQ2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQuc2libGluZyA9IGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcblxuICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSkge1xuICAgIC8vIFdlIHdpbGwgaGF2ZSBkcm9wcGVkIHRoZSBlZmZlY3QgbGlzdCB3aGljaCBjb250YWlucyB0aGVcbiAgICAvLyBkZWxldGlvbi4gV2UgbmVlZCB0byByZWNvbmNpbGUgdG8gZGVsZXRlIHRoZSBjdXJyZW50IGNoaWxkLlxuICAgIHJlY29uY2lsZUNoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBjdXJyZW50LmNoaWxkLCBudWxsLCByZW5kZXJMYW5lcyk7XG4gIH1cblxuICByZXR1cm4gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xufVxuXG5mdW5jdGlvbiBtb3VudERlaHlkcmF0ZWRTdXNwZW5zZUNvbXBvbmVudCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuc2VJbnN0YW5jZSwgcmVuZGVyTGFuZXMpIHtcbiAgLy8gRHVyaW5nIHRoZSBmaXJzdCBwYXNzLCB3ZSdsbCBiYWlsIG91dCBhbmQgbm90IGRyaWxsIGludG8gdGhlIGNoaWxkcmVuLlxuICAvLyBJbnN0ZWFkLCB3ZSdsbCBsZWF2ZSB0aGUgY29udGVudCBpbiBwbGFjZSBhbmQgdHJ5IHRvIGh5ZHJhdGUgaXQgbGF0ZXIuXG4gIGlmICgod29ya0luUHJvZ3Jlc3MubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAge1xuICAgICAgZXJyb3IoJ0Nhbm5vdCBoeWRyYXRlIFN1c3BlbnNlIGluIGxlZ2FjeSBtb2RlLiBTd2l0Y2ggZnJvbSAnICsgJ1JlYWN0RE9NLmh5ZHJhdGUoZWxlbWVudCwgY29udGFpbmVyKSB0byAnICsgJ1JlYWN0RE9NQ2xpZW50Lmh5ZHJhdGVSb290KGNvbnRhaW5lciwgPEFwcCAvPiknICsgJy5yZW5kZXIoZWxlbWVudCkgb3IgcmVtb3ZlIHRoZSBTdXNwZW5zZSBjb21wb25lbnRzIGZyb20gJyArICd0aGUgc2VydmVyIHJlbmRlcmVkIGNvbXBvbmVudHMuJyk7XG4gICAgfVxuXG4gICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBsYW5lVG9MYW5lcyhTeW5jTGFuZSk7XG4gIH0gZWxzZSBpZiAoaXNTdXNwZW5zZUluc3RhbmNlRmFsbGJhY2soc3VzcGVuc2VJbnN0YW5jZSkpIHtcbiAgICAvLyBUaGlzIGlzIGEgY2xpZW50LW9ubHkgYm91bmRhcnkuIFNpbmNlIHdlIHdvbid0IGdldCBhbnkgY29udGVudCBmcm9tIHRoZSBzZXJ2ZXJcbiAgICAvLyBmb3IgdGhpcywgd2UgbmVlZCB0byBzY2hlZHVsZSB0aGF0IGF0IGEgaGlnaGVyIHByaW9yaXR5IGJhc2VkIG9uIHdoZW4gaXQgd291bGRcbiAgICAvLyBoYXZlIHRpbWVkIG91dC4gSW4gdGhlb3J5IHdlIGNvdWxkIHJlbmRlciBpdCBpbiB0aGlzIHBhc3MgYnV0IGl0IHdvdWxkIGhhdmUgdGhlXG4gICAgLy8gd3JvbmcgcHJpb3JpdHkgYXNzb2NpYXRlZCB3aXRoIGl0IGFuZCB3aWxsIHByZXZlbnQgaHlkcmF0aW9uIG9mIHBhcmVudCBwYXRoLlxuICAgIC8vIEluc3RlYWQsIHdlJ2xsIGxlYXZlIHdvcmsgbGVmdCBvbiBpdCB0byByZW5kZXIgaXQgaW4gYSBzZXBhcmF0ZSBjb21taXQuXG4gICAgLy8gVE9ETyBUaGlzIHRpbWUgc2hvdWxkIGJlIHRoZSB0aW1lIGF0IHdoaWNoIHRoZSBzZXJ2ZXIgcmVuZGVyZWQgcmVzcG9uc2UgdGhhdCBpc1xuICAgIC8vIGEgcGFyZW50IHRvIHRoaXMgYm91bmRhcnkgd2FzIGRpc3BsYXllZC4gSG93ZXZlciwgc2luY2Ugd2UgY3VycmVudGx5IGRvbid0IGhhdmVcbiAgICAvLyBhIHByb3RvY29sIHRvIHRyYW5zZmVyIHRoYXQgdGltZSwgd2UnbGwganVzdCBlc3RpbWF0ZSBpdCBieSB1c2luZyB0aGUgY3VycmVudFxuICAgIC8vIHRpbWUuIFRoaXMgd2lsbCBtZWFuIHRoYXQgU3VzcGVuc2UgdGltZW91dHMgYXJlIHNsaWdodGx5IHNoaWZ0ZWQgdG8gbGF0ZXIgdGhhblxuICAgIC8vIHRoZXkgc2hvdWxkIGJlLlxuICAgIC8vIFNjaGVkdWxlIGEgbm9ybWFsIHByaSB1cGRhdGUgdG8gcmVuZGVyIHRoaXMgY29udGVudC5cbiAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IGxhbmVUb0xhbmVzKERlZmF1bHRIeWRyYXRpb25MYW5lKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBXZSdsbCBjb250aW51ZSBoeWRyYXRpbmcgdGhlIHJlc3QgYXQgb2Zmc2NyZWVuIHByaW9yaXR5IHNpbmNlIHdlJ2xsIGFscmVhZHlcbiAgICAvLyBiZSBzaG93aW5nIHRoZSByaWdodCBjb250ZW50IGNvbWluZyBmcm9tIHRoZSBzZXJ2ZXIsIGl0IGlzIG5vIHJ1c2guXG4gICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBsYW5lVG9MYW5lcyhPZmZzY3JlZW5MYW5lKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVEZWh5ZHJhdGVkU3VzcGVuc2VDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlSW5zdGFuY2UsIHN1c3BlbnNlU3RhdGUsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFdlIHNob3VsZCBuZXZlciBiZSBoeWRyYXRpbmcgYXQgdGhpcyBwb2ludCBiZWNhdXNlIGl0IGlzIHRoZSBmaXJzdCBwYXNzLFxuICAvLyBidXQgYWZ0ZXIgd2UndmUgYWxyZWFkeSBjb21taXR0ZWQgb25jZS5cbiAgd2FybklmSHlkcmF0aW5nKCk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICByZXR1cm4gcmV0cnlTdXNwZW5zZUNvbXBvbmVudFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzLCAvLyBUT0RPOiBXaGVuIHdlIGRlbGV0ZSBsZWdhY3kgbW9kZSwgd2Ugc2hvdWxkIG1ha2UgdGhpcyBlcnJvciBhcmd1bWVudFxuICAgIC8vIHJlcXVpcmVkIFx1MjAxNCBldmVyeSBjb25jdXJyZW50IG1vZGUgcGF0aCB0aGF0IGNhdXNlcyBoeWRyYXRpb24gdG9cbiAgICAvLyBkZS1vcHQgdG8gY2xpZW50IHJlbmRlcmluZyBzaG91bGQgaGF2ZSBhbiBlcnJvciBtZXNzYWdlLlxuICAgIG51bGwpO1xuICB9XG5cbiAgaWYgKGlzU3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrKHN1c3BlbnNlSW5zdGFuY2UpKSB7XG4gICAgLy8gVGhpcyBib3VuZGFyeSBpcyBpbiBhIHBlcm1hbmVudCBmYWxsYmFjayBzdGF0ZS4gSW4gdGhpcyBjYXNlLCB3ZSdsbCBuZXZlclxuICAgIC8vIGdldCBhbiB1cGRhdGUgYW5kIHdlJ2xsIG5ldmVyIGJlIGFibGUgdG8gaHlkcmF0ZSB0aGUgZmluYWwgY29udGVudC4gTGV0J3MganVzdCB0cnkgdGhlXG4gICAgLy8gY2xpZW50IHNpZGUgcmVuZGVyIGluc3RlYWQuXG4gICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgLy8gVE9ETzogVGhlIHNlcnZlciBzaG91bGQgc2VyaWFsaXplIHRoZSBlcnJvciBtZXNzYWdlIHNvIHdlIGNhbiBsb2cgaXRcbiAgICAvLyBoZXJlIG9uIHRoZSBjbGllbnQuIE9yLCBpbiBwcm9kdWN0aW9uLCBhIGhhc2gvaWQgdGhhdCBjb3JyZXNwb25kcyB0b1xuICAgIC8vIHRoZSBlcnJvci5cbiAgICBuZXcgRXJyb3IoJ1RoZSBzZXJ2ZXIgY291bGQgbm90IGZpbmlzaCB0aGlzIFN1c3BlbnNlIGJvdW5kYXJ5LCBsaWtlbHkgJyArICdkdWUgdG8gYW4gZXJyb3IgZHVyaW5nIHNlcnZlciByZW5kZXJpbmcuIFN3aXRjaGVkIHRvICcgKyAnY2xpZW50IHJlbmRlcmluZy4nKSk7XG4gIH1cbiAgLy8gYW55IGNvbnRleHQgaGFzIGNoYW5nZWQsIHdlIG5lZWQgdG8gdHJlYXQgaXMgYXMgaWYgdGhlIGlucHV0IG1pZ2h0IGhhdmUgY2hhbmdlZC5cblxuXG4gIHZhciBoYXNDb250ZXh0Q2hhbmdlZCA9IGluY2x1ZGVzU29tZUxhbmUocmVuZGVyTGFuZXMsIGN1cnJlbnQuY2hpbGRMYW5lcyk7XG5cbiAgaWYgKGRpZFJlY2VpdmVVcGRhdGUgfHwgaGFzQ29udGV4dENoYW5nZWQpIHtcbiAgICAvLyBUaGlzIGJvdW5kYXJ5IGhhcyBjaGFuZ2VkIHNpbmNlIHRoZSBmaXJzdCByZW5kZXIuIFRoaXMgbWVhbnMgdGhhdCB3ZSBhcmUgbm93IHVuYWJsZSB0b1xuICAgIC8vIGh5ZHJhdGUgaXQuIFdlIG1pZ2h0IHN0aWxsIGJlIGFibGUgdG8gaHlkcmF0ZSBpdCB1c2luZyBhIGhpZ2hlciBwcmlvcml0eSBsYW5lLlxuICAgIHZhciByb290ID0gZ2V0V29ya0luUHJvZ3Jlc3NSb290KCk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgdmFyIGF0dGVtcHRIeWRyYXRpb25BdExhbmUgPSBnZXRCdW1wZWRMYW5lRm9ySHlkcmF0aW9uKHJvb3QsIHJlbmRlckxhbmVzKTtcblxuICAgICAgaWYgKGF0dGVtcHRIeWRyYXRpb25BdExhbmUgIT09IE5vTGFuZSAmJiBhdHRlbXB0SHlkcmF0aW9uQXRMYW5lICE9PSBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSkge1xuICAgICAgICAvLyBJbnRlbnRpb25hbGx5IG11dGF0aW5nIHNpbmNlIHRoaXMgcmVuZGVyIHdpbGwgZ2V0IGludGVycnVwdGVkLiBUaGlzXG4gICAgICAgIC8vIGlzIG9uZSBvZiB0aGUgdmVyeSByYXJlIHRpbWVzIHdoZXJlIHdlIG11dGF0ZSB0aGUgY3VycmVudCB0cmVlXG4gICAgICAgIC8vIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlLlxuICAgICAgICBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSA9IGF0dGVtcHRIeWRyYXRpb25BdExhbmU7IC8vIFRPRE86IElkZWFsbHkgdGhpcyB3b3VsZCBpbmhlcml0IHRoZSBldmVudCB0aW1lIG9mIHRoZSBjdXJyZW50IHJlbmRlclxuXG4gICAgICAgIHZhciBldmVudFRpbWUgPSBOb1RpbWVzdGFtcDtcbiAgICAgICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGN1cnJlbnQsIGF0dGVtcHRIeWRyYXRpb25BdExhbmUsIGV2ZW50VGltZSk7XG4gICAgICB9XG4gICAgfSAvLyBJZiB3ZSBoYXZlIHNjaGVkdWxlZCBoaWdoZXIgcHJpIHdvcmsgYWJvdmUsIHRoaXMgd2lsbCBwcm9iYWJseSBqdXN0IGFib3J0IHRoZSByZW5kZXJcbiAgICAvLyBzaW5jZSB3ZSBub3cgaGF2ZSBoaWdoZXIgcHJpb3JpdHkgd29yaywgYnV0IGluIGNhc2UgaXQgZG9lc24ndCwgd2UgbmVlZCB0byBwcmVwYXJlIHRvXG4gICAgLy8gcmVuZGVyIHNvbWV0aGluZywgaWYgd2UgdGltZSBvdXQuIEV2ZW4gaWYgdGhhdCByZXF1aXJlcyB1cyB0byBkZWxldGUgZXZlcnl0aGluZyBhbmRcbiAgICAvLyBza2lwIGh5ZHJhdGlvbi5cbiAgICAvLyBEZWxheSBoYXZpbmcgdG8gZG8gdGhpcyBhcyBsb25nIGFzIHRoZSBzdXNwZW5zZSB0aW1lb3V0IGFsbG93cyB1cy5cblxuXG4gICAgcmVuZGVyRGlkU3VzcGVuZERlbGF5SWZQb3NzaWJsZSgpO1xuICAgIHJldHVybiByZXRyeVN1c3BlbnNlQ29tcG9uZW50V2l0aG91dEh5ZHJhdGluZyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMsIG5ldyBFcnJvcignVGhpcyBTdXNwZW5zZSBib3VuZGFyeSByZWNlaXZlZCBhbiB1cGRhdGUgYmVmb3JlIGl0IGZpbmlzaGVkICcgKyAnaHlkcmF0aW5nLiBUaGlzIGNhdXNlZCB0aGUgYm91bmRhcnkgdG8gc3dpdGNoIHRvIGNsaWVudCByZW5kZXJpbmcuICcgKyAnVGhlIHVzdWFsIHdheSB0byBmaXggdGhpcyBpcyB0byB3cmFwIHRoZSBvcmlnaW5hbCB1cGRhdGUgJyArICdpbiBzdGFydFRyYW5zaXRpb24uJykpO1xuICB9IGVsc2UgaWYgKGlzU3VzcGVuc2VJbnN0YW5jZVBlbmRpbmcoc3VzcGVuc2VJbnN0YW5jZSkpIHtcbiAgICAvLyBUaGlzIGNvbXBvbmVudCBpcyBzdGlsbCBwZW5kaW5nIG1vcmUgZGF0YSBmcm9tIHRoZSBzZXJ2ZXIsIHNvIHdlIGNhbid0IGh5ZHJhdGUgaXRzXG4gICAgLy8gY29udGVudC4gV2UgdHJlYXQgaXQgYXMgaWYgdGhpcyBjb21wb25lbnQgc3VzcGVuZGVkIGl0c2VsZi4gSXQgbWlnaHQgc2VlbSBhcyBpZlxuICAgIC8vIHdlIGNvdWxkIGp1c3QgdHJ5IHRvIHJlbmRlciBpdCBjbGllbnQtc2lkZSBpbnN0ZWFkLiBIb3dldmVyLCB0aGlzIHdpbGwgcGVyZm9ybSBhXG4gICAgLy8gbG90IG9mIHVubmVjZXNzYXJ5IHdvcmsgYW5kIGlzIHVubGlrZWx5IHRvIGNvbXBsZXRlIHNpbmNlIGl0IG9mdGVuIHdpbGwgc3VzcGVuZFxuICAgIC8vIG9uIG1pc3NpbmcgZGF0YSBhbnl3YXkuIEFkZGl0aW9uYWxseSwgdGhlIHNlcnZlciBtaWdodCBiZSBhYmxlIHRvIHJlbmRlciBtb3JlXG4gICAgLy8gdGhhbiB3ZSBjYW4gb24gdGhlIGNsaWVudCB5ZXQuIEluIHRoYXQgY2FzZSB3ZSdkIGVuZCB1cCB3aXRoIG1vcmUgZmFsbGJhY2sgc3RhdGVzXG4gICAgLy8gb24gdGhlIGNsaWVudCB0aGFuIGlmIHdlIGp1c3QgbGVhdmUgaXQgYWxvbmUuIElmIHRoZSBzZXJ2ZXIgdGltZXMgb3V0IG9yIGVycm9yc1xuICAgIC8vIHRoZXNlIHNob3VsZCB1cGRhdGUgdGhpcyBib3VuZGFyeSB0byB0aGUgcGVybWFuZW50IEZhbGxiYWNrIHN0YXRlIGluc3RlYWQuXG4gICAgLy8gTWFyayBpdCBhcyBoYXZpbmcgY2FwdHVyZWQgKGkuZS4gc3VzcGVuZGVkKS5cbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlOyAvLyBMZWF2ZSB0aGUgY2hpbGQgaW4gcGxhY2UuIEkuZS4gdGhlIGRlaHlkcmF0ZWQgZnJhZ21lbnQuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcmV0cnkgdGhpcyBib3VuZGFyeSBvbmNlIHRoZSBzZXJ2ZXIgaGFzIHNlbnQgdGhlIHJlc3VsdC5cblxuICAgIHZhciByZXRyeSA9IHJldHJ5RGVoeWRyYXRlZFN1c3BlbnNlQm91bmRhcnkuYmluZChudWxsLCBjdXJyZW50KTtcbiAgICByZWdpc3RlclN1c3BlbnNlSW5zdGFuY2VSZXRyeShzdXNwZW5zZUluc3RhbmNlLCByZXRyeSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgYXR0ZW1wdC5cbiAgICByZWVudGVySHlkcmF0aW9uU3RhdGVGcm9tRGVoeWRyYXRlZFN1c3BlbnNlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlSW5zdGFuY2UsIHN1c3BlbnNlU3RhdGUudHJlZUNvbnRleHQpO1xuICAgIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gICAgdmFyIHByaW1hcnlDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBtb3VudFN1c3BlbnNlUHJpbWFyeUNoaWxkcmVuKHdvcmtJblByb2dyZXNzLCBwcmltYXJ5Q2hpbGRyZW4pOyAvLyBNYXJrIHRoZSBjaGlsZHJlbiBhcyBoeWRyYXRpbmcuIFRoaXMgaXMgYSBmYXN0IHBhdGggdG8ga25vdyB3aGV0aGVyIHRoaXNcbiAgICAvLyB0cmVlIGlzIHBhcnQgb2YgYSBoeWRyYXRpbmcgdHJlZS4gVGhpcyBpcyB1c2VkIHRvIGRldGVybWluZSBpZiBhIGNoaWxkXG4gICAgLy8gbm9kZSBoYXMgZnVsbHkgbW91bnRlZCB5ZXQsIGFuZCBmb3Igc2NoZWR1bGluZyBldmVudCByZXBsYXlpbmcuXG4gICAgLy8gQ29uY2VwdHVhbGx5IHRoaXMgaXMgc2ltaWxhciB0byBQbGFjZW1lbnQgaW4gdGhhdCBhIG5ldyBzdWJ0cmVlIGlzXG4gICAgLy8gaW5zZXJ0ZWQgaW50byB0aGUgUmVhY3QgdHJlZSBoZXJlLiBJdCBqdXN0IGhhcHBlbnMgdG8gbm90IG5lZWQgRE9NXG4gICAgLy8gbXV0YXRpb25zIGJlY2F1c2UgaXQgYWxyZWFkeSBleGlzdHMuXG5cbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5mbGFncyB8PSBIeWRyYXRpbmc7XG4gICAgcmV0dXJuIHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIHNjaGVkdWxlU3VzcGVuc2VXb3JrT25GaWJlcihmaWJlciwgcmVuZGVyTGFuZXMsIHByb3BhZ2F0aW9uUm9vdCkge1xuICBmaWJlci5sYW5lcyA9IG1lcmdlTGFuZXMoZmliZXIubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhhbHRlcm5hdGUubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHNjaGVkdWxlQ29udGV4dFdvcmtPblBhcmVudFBhdGgoZmliZXIucmV0dXJuLCByZW5kZXJMYW5lcywgcHJvcGFnYXRpb25Sb290KTtcbn1cblxuZnVuY3Rpb24gcHJvcGFnYXRlU3VzcGVuc2VDb250ZXh0Q2hhbmdlKHdvcmtJblByb2dyZXNzLCBmaXJzdENoaWxkLCByZW5kZXJMYW5lcykge1xuICAvLyBNYXJrIGFueSBTdXNwZW5zZSBib3VuZGFyaWVzIHdpdGggZmFsbGJhY2tzIGFzIGhhdmluZyB3b3JrIHRvIGRvLlxuICAvLyBJZiB0aGV5IHdlcmUgcHJldmlvdXNseSBmb3JjZWQgaW50byBmYWxsYmFja3MsIHRoZXkgbWF5IG5vdyBiZSBhYmxlXG4gIC8vIHRvIHVuYmxvY2suXG4gIHZhciBub2RlID0gZmlyc3RDaGlsZDtcblxuICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgIGlmIChub2RlLnRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAgIHZhciBzdGF0ZSA9IG5vZGUubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgaWYgKHN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlU3VzcGVuc2VXb3JrT25GaWJlcihub2RlLCByZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlTGlzdENvbXBvbmVudCkge1xuICAgICAgLy8gSWYgdGhlIHRhaWwgaXMgaGlkZGVuIHRoZXJlIG1pZ2h0IG5vdCBiZSBhbiBTdXNwZW5zZSBib3VuZGFyaWVzXG4gICAgICAvLyB0byBzY2hlZHVsZSB3b3JrIG9uLiBJbiB0aGlzIGNhc2Ugd2UgaGF2ZSB0byBzY2hlZHVsZSBpdCBvbiB0aGVcbiAgICAgIC8vIGxpc3QgaXRzZWxmLlxuICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSB0byB0cmF2ZXJzZSB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIGxpc3Qgc2luY2VcbiAgICAgIC8vIHRoZSBsaXN0IHdpbGwgcHJvcGFnYXRlIHRoZSBjaGFuZ2Ugd2hlbiBpdCByZXJlbmRlcnMuXG4gICAgICBzY2hlZHVsZVN1c3BlbnNlV29ya09uRmliZXIobm9kZSwgcmVuZGVyTGFuZXMsIHdvcmtJblByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgPT09IHdvcmtJblByb2dyZXNzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSB3b3JrSW5Qcm9ncmVzcykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kTGFzdENvbnRlbnRSb3coZmlyc3RDaGlsZCkge1xuICAvLyBUaGlzIGlzIGdvaW5nIHRvIGZpbmQgdGhlIGxhc3Qgcm93IGFtb25nIHRoZXNlIGNoaWxkcmVuIHRoYXQgaXMgYWxyZWFkeVxuICAvLyBzaG93aW5nIGNvbnRlbnQgb24gdGhlIHNjcmVlbiwgYXMgb3Bwb3NlZCB0byBiZWluZyBpbiBmYWxsYmFjayBzdGF0ZSBvclxuICAvLyBuZXcuIElmIGEgcm93IGhhcyBtdWx0aXBsZSBTdXNwZW5zZSBib3VuZGFyaWVzLCBhbnkgb2YgdGhlbSBiZWluZyBpbiB0aGVcbiAgLy8gZmFsbGJhY2sgc3RhdGUsIGNvdW50cyBhcyB0aGUgd2hvbGUgcm93IGJlaW5nIGluIGEgZmFsbGJhY2sgc3RhdGUuXG4gIC8vIE5vdGUgdGhhdCB0aGUgXCJyb3dzXCIgd2lsbCBiZSB3b3JrSW5Qcm9ncmVzcywgYnV0IGFueSBuZXN0ZWQgY2hpbGRyZW5cbiAgLy8gd2lsbCBzdGlsbCBiZSBjdXJyZW50IHNpbmNlIHdlIGhhdmVuJ3QgcmVuZGVyZWQgdGhlbSB5ZXQuIFRoZSBtb3VudGVkXG4gIC8vIG9yZGVyIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhlIG5ldyBvcmRlci4gV2UgdXNlIHRoZSBuZXcgb3JkZXIuXG4gIHZhciByb3cgPSBmaXJzdENoaWxkO1xuICB2YXIgbGFzdENvbnRlbnRSb3cgPSBudWxsO1xuXG4gIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICB2YXIgY3VycmVudFJvdyA9IHJvdy5hbHRlcm5hdGU7IC8vIE5ldyByb3dzIGNhbid0IGJlIGNvbnRlbnQgcm93cy5cblxuICAgIGlmIChjdXJyZW50Um93ICE9PSBudWxsICYmIGZpbmRGaXJzdFN1c3BlbmRlZChjdXJyZW50Um93KSA9PT0gbnVsbCkge1xuICAgICAgbGFzdENvbnRlbnRSb3cgPSByb3c7XG4gICAgfVxuXG4gICAgcm93ID0gcm93LnNpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbGFzdENvbnRlbnRSb3c7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmV2ZWFsT3JkZXIocmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmIChyZXZlYWxPcmRlciAhPT0gdW5kZWZpbmVkICYmIHJldmVhbE9yZGVyICE9PSAnZm9yd2FyZHMnICYmIHJldmVhbE9yZGVyICE9PSAnYmFja3dhcmRzJyAmJiByZXZlYWxPcmRlciAhPT0gJ3RvZ2V0aGVyJyAmJiAhZGlkV2FybkFib3V0UmV2ZWFsT3JkZXJbcmV2ZWFsT3JkZXJdKSB7XG4gICAgICBkaWRXYXJuQWJvdXRSZXZlYWxPcmRlcltyZXZlYWxPcmRlcl0gPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIHJldmVhbE9yZGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBzd2l0Y2ggKHJldmVhbE9yZGVyLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICBjYXNlICd0b2dldGhlcic6XG4gICAgICAgICAgY2FzZSAnZm9yd2FyZHMnOlxuICAgICAgICAgIGNhc2UgJ2JhY2t3YXJkcyc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yKCdcIiVzXCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHJldmVhbE9yZGVyIG9uIDxTdXNwZW5zZUxpc3QgLz4uICcgKyAnVXNlIGxvd2VyY2FzZSBcIiVzXCIgaW5zdGVhZC4nLCByZXZlYWxPcmRlciwgcmV2ZWFsT3JkZXIudG9Mb3dlckNhc2UoKSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICdmb3J3YXJkJzpcbiAgICAgICAgICBjYXNlICdiYWNrd2FyZCc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yKCdcIiVzXCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHJldmVhbE9yZGVyIG9uIDxTdXNwZW5zZUxpc3QgLz4uICcgKyAnUmVhY3QgdXNlcyB0aGUgLXMgc3VmZml4IGluIHRoZSBzcGVsbGluZy4gVXNlIFwiJXNzXCIgaW5zdGVhZC4nLCByZXZlYWxPcmRlciwgcmV2ZWFsT3JkZXIudG9Mb3dlckNhc2UoKSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgZXJyb3IoJ1wiJXNcIiBpcyBub3QgYSBzdXBwb3J0ZWQgcmV2ZWFsT3JkZXIgb24gPFN1c3BlbnNlTGlzdCAvPi4gJyArICdEaWQgeW91IG1lYW4gXCJ0b2dldGhlclwiLCBcImZvcndhcmRzXCIgb3IgXCJiYWNrd2FyZHNcIj8nLCByZXZlYWxPcmRlcik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcignJXMgaXMgbm90IGEgc3VwcG9ydGVkIHZhbHVlIGZvciByZXZlYWxPcmRlciBvbiA8U3VzcGVuc2VMaXN0IC8+LiAnICsgJ0RpZCB5b3UgbWVhbiBcInRvZ2V0aGVyXCIsIFwiZm9yd2FyZHNcIiBvciBcImJhY2t3YXJkc1wiPycsIHJldmVhbE9yZGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVUYWlsT3B0aW9ucyh0YWlsTW9kZSwgcmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmICh0YWlsTW9kZSAhPT0gdW5kZWZpbmVkICYmICFkaWRXYXJuQWJvdXRUYWlsT3B0aW9uc1t0YWlsTW9kZV0pIHtcbiAgICAgIGlmICh0YWlsTW9kZSAhPT0gJ2NvbGxhcHNlZCcgJiYgdGFpbE1vZGUgIT09ICdoaWRkZW4nKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zW3RhaWxNb2RlXSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1wiJXNcIiBpcyBub3QgYSBzdXBwb3J0ZWQgdmFsdWUgZm9yIHRhaWwgb24gPFN1c3BlbnNlTGlzdCAvPi4gJyArICdEaWQgeW91IG1lYW4gXCJjb2xsYXBzZWRcIiBvciBcImhpZGRlblwiPycsIHRhaWxNb2RlKTtcbiAgICAgIH0gZWxzZSBpZiAocmV2ZWFsT3JkZXIgIT09ICdmb3J3YXJkcycgJiYgcmV2ZWFsT3JkZXIgIT09ICdiYWNrd2FyZHMnKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zW3RhaWxNb2RlXSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJzxTdXNwZW5zZUxpc3QgdGFpbD1cIiVzXCIgLz4gaXMgb25seSB2YWxpZCBpZiByZXZlYWxPcmRlciBpcyAnICsgJ1wiZm9yd2FyZHNcIiBvciBcImJhY2t3YXJkc1wiLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBzcGVjaWZ5IHJldmVhbE9yZGVyPVwiZm9yd2FyZHNcIj8nLCB0YWlsTW9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoY2hpbGRTbG90LCBpbmRleCkge1xuICB7XG4gICAgdmFyIGlzQW5BcnJheSA9IGlzQXJyYXkoY2hpbGRTbG90KTtcbiAgICB2YXIgaXNJdGVyYWJsZSA9ICFpc0FuQXJyYXkgJiYgdHlwZW9mIGdldEl0ZXJhdG9yRm4oY2hpbGRTbG90KSA9PT0gJ2Z1bmN0aW9uJztcblxuICAgIGlmIChpc0FuQXJyYXkgfHwgaXNJdGVyYWJsZSkge1xuICAgICAgdmFyIHR5cGUgPSBpc0FuQXJyYXkgPyAnYXJyYXknIDogJ2l0ZXJhYmxlJztcblxuICAgICAgZXJyb3IoJ0EgbmVzdGVkICVzIHdhcyBwYXNzZWQgdG8gcm93ICMlcyBpbiA8U3VzcGVuc2VMaXN0IC8+LiBXcmFwIGl0IGluICcgKyAnYW4gYWRkaXRpb25hbCBTdXNwZW5zZUxpc3QgdG8gY29uZmlndXJlIGl0cyByZXZlYWxPcmRlcjogJyArICc8U3VzcGVuc2VMaXN0IHJldmVhbE9yZGVyPS4uLj4gLi4uICcgKyAnPFN1c3BlbnNlTGlzdCByZXZlYWxPcmRlcj0uLi4+eyVzfTwvU3VzcGVuc2VMaXN0PiAuLi4gJyArICc8L1N1c3BlbnNlTGlzdD4nLCB0eXBlLCBpbmRleCwgdHlwZSk7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVTdXNwZW5zZUxpc3RDaGlsZHJlbihjaGlsZHJlbiwgcmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmICgocmV2ZWFsT3JkZXIgPT09ICdmb3J3YXJkcycgfHwgcmV2ZWFsT3JkZXIgPT09ICdiYWNrd2FyZHMnKSAmJiBjaGlsZHJlbiAhPT0gdW5kZWZpbmVkICYmIGNoaWxkcmVuICE9PSBudWxsICYmIGNoaWxkcmVuICE9PSBmYWxzZSkge1xuICAgICAgaWYgKGlzQXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoIXZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoY2hpbGRyZW5baV0sIGkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4oY2hpbGRyZW4pO1xuXG4gICAgICAgIGlmICh0eXBlb2YgaXRlcmF0b3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHZhciBjaGlsZHJlbkl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKGNoaWxkcmVuKTtcblxuICAgICAgICAgIGlmIChjaGlsZHJlbkl0ZXJhdG9yKSB7XG4gICAgICAgICAgICB2YXIgc3RlcCA9IGNoaWxkcmVuSXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgdmFyIF9pID0gMDtcblxuICAgICAgICAgICAgZm9yICg7ICFzdGVwLmRvbmU7IHN0ZXAgPSBjaGlsZHJlbkl0ZXJhdG9yLm5leHQoKSkge1xuICAgICAgICAgICAgICBpZiAoIXZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoc3RlcC52YWx1ZSwgX2kpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgX2krKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXJyb3IoJ0Egc2luZ2xlIHJvdyB3YXMgcGFzc2VkIHRvIGEgPFN1c3BlbnNlTGlzdCByZXZlYWxPcmRlcj1cIiVzXCIgLz4uICcgKyAnVGhpcyBpcyBub3QgdXNlZnVsIHNpbmNlIGl0IG5lZWRzIG11bHRpcGxlIHJvd3MuICcgKyAnRGlkIHlvdSBtZWFuIHRvIHBhc3MgbXVsdGlwbGUgY2hpbGRyZW4gb3IgYW4gYXJyYXk/JywgcmV2ZWFsT3JkZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRTdXNwZW5zZUxpc3RSZW5kZXJTdGF0ZSh3b3JrSW5Qcm9ncmVzcywgaXNCYWNrd2FyZHMsIHRhaWwsIGxhc3RDb250ZW50Um93LCB0YWlsTW9kZSkge1xuICB2YXIgcmVuZGVyU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChyZW5kZXJTdGF0ZSA9PT0gbnVsbCkge1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSB7XG4gICAgICBpc0JhY2t3YXJkczogaXNCYWNrd2FyZHMsXG4gICAgICByZW5kZXJpbmc6IG51bGwsXG4gICAgICByZW5kZXJpbmdTdGFydFRpbWU6IDAsXG4gICAgICBsYXN0OiBsYXN0Q29udGVudFJvdyxcbiAgICAgIHRhaWw6IHRhaWwsXG4gICAgICB0YWlsTW9kZTogdGFpbE1vZGVcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIFdlIGNhbiByZXVzZSB0aGUgZXhpc3Rpbmcgb2JqZWN0IGZyb20gcHJldmlvdXMgcmVuZGVycy5cbiAgICByZW5kZXJTdGF0ZS5pc0JhY2t3YXJkcyA9IGlzQmFja3dhcmRzO1xuICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZyA9IG51bGw7XG4gICAgcmVuZGVyU3RhdGUucmVuZGVyaW5nU3RhcnRUaW1lID0gMDtcbiAgICByZW5kZXJTdGF0ZS5sYXN0ID0gbGFzdENvbnRlbnRSb3c7XG4gICAgcmVuZGVyU3RhdGUudGFpbCA9IHRhaWw7XG4gICAgcmVuZGVyU3RhdGUudGFpbE1vZGUgPSB0YWlsTW9kZTtcbiAgfVxufSAvLyBUaGlzIGNhbiBlbmQgdXAgcmVuZGVyaW5nIHRoaXMgY29tcG9uZW50IG11bHRpcGxlIHBhc3Nlcy5cbi8vIFRoZSBmaXJzdCBwYXNzIHNwbGl0cyB0aGUgY2hpbGRyZW4gZmliZXJzIGludG8gdHdvIHNldHMuIEEgaGVhZCBhbmQgdGFpbC5cbi8vIFdlIGZpcnN0IHJlbmRlciB0aGUgaGVhZC4gSWYgYW55dGhpbmcgaXMgaW4gZmFsbGJhY2sgc3RhdGUsIHdlIGRvIGFub3RoZXJcbi8vIHBhc3MgdGhyb3VnaCBiZWdpbldvcmsgdG8gcmVyZW5kZXIgYWxsIGNoaWxkcmVuIChpbmNsdWRpbmcgdGhlIHRhaWwpIHdpdGhcbi8vIHRoZSBmb3JjZSBzdXNwZW5kIGNvbnRleHQuIElmIHRoZSBmaXJzdCByZW5kZXIgZGlkbid0IGhhdmUgYW55dGhpbmcgaW5cbi8vIGluIGZhbGxiYWNrIHN0YXRlLiBUaGVuIHdlIHJlbmRlciBlYWNoIHJvdyBpbiB0aGUgdGFpbCBvbmUtYnktb25lLlxuLy8gVGhhdCBoYXBwZW5zIGluIHRoZSBjb21wbGV0ZVdvcmsgcGhhc2Ugd2l0aG91dCBnb2luZyBiYWNrIHRvIGJlZ2luV29yay5cblxuXG5mdW5jdGlvbiB1cGRhdGVTdXNwZW5zZUxpc3RDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciByZXZlYWxPcmRlciA9IG5leHRQcm9wcy5yZXZlYWxPcmRlcjtcbiAgdmFyIHRhaWxNb2RlID0gbmV4dFByb3BzLnRhaWw7XG4gIHZhciBuZXdDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgdmFsaWRhdGVSZXZlYWxPcmRlcihyZXZlYWxPcmRlcik7XG4gIHZhbGlkYXRlVGFpbE9wdGlvbnModGFpbE1vZGUsIHJldmVhbE9yZGVyKTtcbiAgdmFsaWRhdGVTdXNwZW5zZUxpc3RDaGlsZHJlbihuZXdDaGlsZHJlbiwgcmV2ZWFsT3JkZXIpO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV3Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgdmFyIHN1c3BlbnNlQ29udGV4dCA9IHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudDtcbiAgdmFyIHNob3VsZEZvcmNlRmFsbGJhY2sgPSBoYXNTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spO1xuXG4gIGlmIChzaG91bGRGb3JjZUZhbGxiYWNrKSB7XG4gICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQsIEZvcmNlU3VzcGVuc2VGYWxsYmFjayk7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGlkU3VzcGVuZEJlZm9yZSA9IGN1cnJlbnQgIT09IG51bGwgJiYgKGN1cnJlbnQuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICAgIGlmIChkaWRTdXNwZW5kQmVmb3JlKSB7XG4gICAgICAvLyBJZiB3ZSBwcmV2aW91c2x5IGZvcmNlZCBhIGZhbGxiYWNrLCB3ZSBuZWVkIHRvIHNjaGVkdWxlIHdvcmtcbiAgICAgIC8vIG9uIGFueSBuZXN0ZWQgYm91bmRhcmllcyB0byBsZXQgdGhlbSBrbm93IHRvIHRyeSB0byByZW5kZXJcbiAgICAgIC8vIGFnYWluLiBUaGlzIGlzIHRoZSBzYW1lIGFzIGNvbnRleHQgdXBkYXRpbmcuXG4gICAgICBwcm9wYWdhdGVTdXNwZW5zZUNvbnRleHRDaGFuZ2Uod29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLmNoaWxkLCByZW5kZXJMYW5lcyk7XG4gICAgfVxuXG4gICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0RGVmYXVsdFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0KTtcbiAgfVxuXG4gIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlQ29udGV4dCk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICAvLyBJbiBsZWdhY3kgbW9kZSwgU3VzcGVuc2VMaXN0IGRvZXNuJ3Qgd29yayBzbyB3ZSBqdXN0XG4gICAgLy8gdXNlIG1ha2UgaXQgYSBub29wIGJ5IHRyZWF0aW5nIGl0IGFzIHRoZSBkZWZhdWx0IHJldmVhbE9yZGVyLlxuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHN3aXRjaCAocmV2ZWFsT3JkZXIpIHtcbiAgICAgIGNhc2UgJ2ZvcndhcmRzJzpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBsYXN0Q29udGVudFJvdyA9IGZpbmRMYXN0Q29udGVudFJvdyh3b3JrSW5Qcm9ncmVzcy5jaGlsZCk7XG4gICAgICAgICAgdmFyIHRhaWw7XG5cbiAgICAgICAgICBpZiAobGFzdENvbnRlbnRSb3cgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFRoZSB3aG9sZSBsaXN0IGlzIHBhcnQgb2YgdGhlIHRhaWwuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBjb3VsZCBmYXN0IHBhdGggYnkganVzdCByZW5kZXJpbmcgdGhlIHRhaWwgbm93LlxuICAgICAgICAgICAgdGFpbCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBudWxsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBEaXNjb25uZWN0IHRoZSB0YWlsIHJvd3MgYWZ0ZXIgdGhlIGNvbnRlbnQgcm93LlxuICAgICAgICAgICAgLy8gV2UncmUgZ29pbmcgdG8gcmVuZGVyIHRoZW0gc2VwYXJhdGVseSBsYXRlci5cbiAgICAgICAgICAgIHRhaWwgPSBsYXN0Q29udGVudFJvdy5zaWJsaW5nO1xuICAgICAgICAgICAgbGFzdENvbnRlbnRSb3cuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW5pdFN1c3BlbnNlTGlzdFJlbmRlclN0YXRlKHdvcmtJblByb2dyZXNzLCBmYWxzZSwgLy8gaXNCYWNrd2FyZHNcbiAgICAgICAgICB0YWlsLCBsYXN0Q29udGVudFJvdywgdGFpbE1vZGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgJ2JhY2t3YXJkcyc6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBXZSdyZSBnb2luZyB0byBmaW5kIHRoZSBmaXJzdCByb3cgdGhhdCBoYXMgZXhpc3RpbmcgY29udGVudC5cbiAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lIHdlJ3JlIGdvaW5nIHRvIHJldmVyc2UgdGhlIGxpc3Qgb2YgZXZlcnl0aGluZ1xuICAgICAgICAgIC8vIHdlIHBhc3MgaW4gdGhlIG1lYW50aW1lLiBUaGF0J3MgZ29pbmcgdG8gYmUgb3VyIHRhaWwgaW4gcmV2ZXJzZVxuICAgICAgICAgIC8vIG9yZGVyLlxuICAgICAgICAgIHZhciBfdGFpbCA9IG51bGw7XG4gICAgICAgICAgdmFyIHJvdyA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbnVsbDtcblxuICAgICAgICAgIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50Um93ID0gcm93LmFsdGVybmF0ZTsgLy8gTmV3IHJvd3MgY2FuJ3QgYmUgY29udGVudCByb3dzLlxuXG4gICAgICAgICAgICBpZiAoY3VycmVudFJvdyAhPT0gbnVsbCAmJiBmaW5kRmlyc3RTdXNwZW5kZWQoY3VycmVudFJvdykgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBtYWluIGNvbnRlbnQuXG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcm93O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIG5leHRSb3cgPSByb3cuc2libGluZztcbiAgICAgICAgICAgIHJvdy5zaWJsaW5nID0gX3RhaWw7XG4gICAgICAgICAgICBfdGFpbCA9IHJvdztcbiAgICAgICAgICAgIHJvdyA9IG5leHRSb3c7XG4gICAgICAgICAgfSAvLyBUT0RPOiBJZiB3b3JrSW5Qcm9ncmVzcy5jaGlsZCBpcyBudWxsLCB3ZSBjYW4gY29udGludWUgb24gdGhlIHRhaWwgaW1tZWRpYXRlbHkuXG5cblxuICAgICAgICAgIGluaXRTdXNwZW5zZUxpc3RSZW5kZXJTdGF0ZSh3b3JrSW5Qcm9ncmVzcywgdHJ1ZSwgLy8gaXNCYWNrd2FyZHNcbiAgICAgICAgICBfdGFpbCwgbnVsbCwgLy8gbGFzdFxuICAgICAgICAgIHRhaWxNb2RlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlICd0b2dldGhlcic6XG4gICAgICAgIHtcbiAgICAgICAgICBpbml0U3VzcGVuc2VMaXN0UmVuZGVyU3RhdGUod29ya0luUHJvZ3Jlc3MsIGZhbHNlLCAvLyBpc0JhY2t3YXJkc1xuICAgICAgICAgIG51bGwsIC8vIHRhaWxcbiAgICAgICAgICBudWxsLCAvLyBsYXN0XG4gICAgICAgICAgdW5kZWZpbmVkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVGhlIGRlZmF1bHQgcmV2ZWFsIG9yZGVyIGlzIHRoZSBzYW1lIGFzIG5vdCBoYXZpbmdcbiAgICAgICAgICAvLyBhIGJvdW5kYXJ5LlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVQb3J0YWxDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHB1c2hIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyk7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAvLyBQb3J0YWxzIGFyZSBzcGVjaWFsIGJlY2F1c2Ugd2UgZG9uJ3QgYXBwZW5kIHRoZSBjaGlsZHJlbiBkdXJpbmcgbW91bnRcbiAgICAvLyBidXQgYXQgY29tbWl0LiBUaGVyZWZvcmUgd2UgbmVlZCB0byB0cmFjayBpbnNlcnRpb25zIHdoaWNoIHRoZSBub3JtYWxcbiAgICAvLyBmbG93IGRvZXNuJ3QgZG8gZHVyaW5nIG1vdW50LiBUaGlzIGRvZXNuJ3QgaGFwcGVuIGF0IHRoZSByb290IGJlY2F1c2VcbiAgICAvLyB0aGUgcm9vdCBhbHdheXMgc3RhcnRzIHdpdGggYSBcImN1cnJlbnRcIiB3aXRoIGEgbnVsbCBjaGlsZC5cbiAgICAvLyBUT0RPOiBDb25zaWRlciB1bmlmeWluZyB0aGlzIHdpdGggaG93IHRoZSByb290IHdvcmtzLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVjb25jaWxlQ2hpbGRGaWJlcnMod29ya0luUHJvZ3Jlc3MsIG51bGwsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxudmFyIGhhc1dhcm5lZEFib3V0VXNpbmdOb1ZhbHVlUHJvcE9uQ29udGV4dFByb3ZpZGVyID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRleHRQcm92aWRlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIHByb3ZpZGVyVHlwZSA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gIHZhciBjb250ZXh0ID0gcHJvdmlkZXJUeXBlLl9jb250ZXh0O1xuICB2YXIgbmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBvbGRQcm9wcyA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHM7XG4gIHZhciBuZXdWYWx1ZSA9IG5ld1Byb3BzLnZhbHVlO1xuXG4gIHtcbiAgICBpZiAoISgndmFsdWUnIGluIG5ld1Byb3BzKSkge1xuICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nTm9WYWx1ZVByb3BPbkNvbnRleHRQcm92aWRlcikge1xuICAgICAgICBoYXNXYXJuZWRBYm91dFVzaW5nTm9WYWx1ZVByb3BPbkNvbnRleHRQcm92aWRlciA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1RoZSBgdmFsdWVgIHByb3AgaXMgcmVxdWlyZWQgZm9yIHRoZSBgPENvbnRleHQuUHJvdmlkZXI+YC4gRGlkIHlvdSBtaXNzcGVsbCBpdCBvciBmb3JnZXQgdG8gcGFzcyBpdD8nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvdmlkZXJQcm9wVHlwZXMgPSB3b3JrSW5Qcm9ncmVzcy50eXBlLnByb3BUeXBlcztcblxuICAgIGlmIChwcm92aWRlclByb3BUeXBlcykge1xuICAgICAgY2hlY2tQcm9wVHlwZXMocHJvdmlkZXJQcm9wVHlwZXMsIG5ld1Byb3BzLCAncHJvcCcsICdDb250ZXh0LlByb3ZpZGVyJyk7XG4gICAgfVxuICB9XG5cbiAgcHVzaFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCBuZXdWYWx1ZSk7XG5cbiAge1xuICAgIGlmIChvbGRQcm9wcyAhPT0gbnVsbCkge1xuICAgICAgdmFyIG9sZFZhbHVlID0gb2xkUHJvcHMudmFsdWU7XG5cbiAgICAgIGlmIChvYmplY3RJcyhvbGRWYWx1ZSwgbmV3VmFsdWUpKSB7XG4gICAgICAgIC8vIE5vIGNoYW5nZS4gQmFpbG91dCBlYXJseSBpZiBjaGlsZHJlbiBhcmUgdGhlIHNhbWUuXG4gICAgICAgIGlmIChvbGRQcm9wcy5jaGlsZHJlbiA9PT0gbmV3UHJvcHMuY2hpbGRyZW4gJiYgIWhhc0NvbnRleHRDaGFuZ2VkKCkpIHtcbiAgICAgICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGUgY29udGV4dCB2YWx1ZSBjaGFuZ2VkLiBTZWFyY2ggZm9yIG1hdGNoaW5nIGNvbnN1bWVycyBhbmQgc2NoZWR1bGVcbiAgICAgICAgLy8gdGhlbSB0byB1cGRhdGUuXG4gICAgICAgIHByb3BhZ2F0ZUNvbnRleHRDaGFuZ2Uod29ya0luUHJvZ3Jlc3MsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbmV3Q2hpbGRyZW4gPSBuZXdQcm9wcy5jaGlsZHJlbjtcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5ld0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxudmFyIGhhc1dhcm5lZEFib3V0VXNpbmdDb250ZXh0QXNDb25zdW1lciA9IGZhbHNlO1xuXG5mdW5jdGlvbiB1cGRhdGVDb250ZXh0Q29uc3VtZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZTsgLy8gVGhlIGxvZ2ljIGJlbG93IGZvciBDb250ZXh0IGRpZmZlcnMgZGVwZW5kaW5nIG9uIFBST0Qgb3IgREVWIG1vZGUuIEluXG4gIC8vIERFViBtb2RlLCB3ZSBjcmVhdGUgYSBzZXBhcmF0ZSBvYmplY3QgZm9yIENvbnRleHQuQ29uc3VtZXIgdGhhdCBhY3RzXG4gIC8vIGxpa2UgYSBwcm94eSB0byBDb250ZXh0LiBUaGlzIHByb3h5IG9iamVjdCBhZGRzIHVubmVjZXNzYXJ5IGNvZGUgaW4gUFJPRFxuICAvLyBzbyB3ZSB1c2UgdGhlIG9sZCBiZWhhdmlvdXIgKENvbnRleHQuQ29uc3VtZXIgcmVmZXJlbmNlcyBDb250ZXh0KSB0b1xuICAvLyByZWR1Y2Ugc2l6ZSBhbmQgb3ZlcmhlYWQuIFRoZSBzZXBhcmF0ZSBvYmplY3QgcmVmZXJlbmNlcyBjb250ZXh0IHZpYVxuICAvLyBhIHByb3BlcnR5IGNhbGxlZCBcIl9jb250ZXh0XCIsIHdoaWNoIGFsc28gZ2l2ZXMgdXMgdGhlIGFiaWxpdHkgdG8gY2hlY2tcbiAgLy8gaW4gREVWIG1vZGUgaWYgdGhpcyBwcm9wZXJ0eSBleGlzdHMgb3Igbm90IGFuZCB3YXJuIGlmIGl0IGRvZXMgbm90LlxuXG4gIHtcbiAgICBpZiAoY29udGV4dC5fY29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBUaGlzIG1heSBiZSBiZWNhdXNlIGl0J3MgYSBDb250ZXh0IChyYXRoZXIgdGhhbiBhIENvbnN1bWVyKS5cbiAgICAgIC8vIE9yIGl0IG1heSBiZSBiZWNhdXNlIGl0J3Mgb2xkZXIgUmVhY3Qgd2hlcmUgdGhleSdyZSB0aGUgc2FtZSB0aGluZy5cbiAgICAgIC8vIFdlIG9ubHkgd2FudCB0byB3YXJuIGlmIHdlJ3JlIHN1cmUgaXQncyBhIG5ldyBSZWFjdC5cbiAgICAgIGlmIChjb250ZXh0ICE9PSBjb250ZXh0LkNvbnN1bWVyKSB7XG4gICAgICAgIGlmICghaGFzV2FybmVkQWJvdXRVc2luZ0NvbnRleHRBc0NvbnN1bWVyKSB7XG4gICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnRleHRBc0NvbnN1bWVyID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCdSZW5kZXJpbmcgPENvbnRleHQ+IGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAnICsgJ2EgZnV0dXJlIG1ham9yIHJlbGVhc2UuIERpZCB5b3UgbWVhbiB0byByZW5kZXIgPENvbnRleHQuQ29uc3VtZXI+IGluc3RlYWQ/Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dCA9IGNvbnRleHQuX2NvbnRleHQ7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5ld1Byb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcmVuZGVyID0gbmV3UHJvcHMuY2hpbGRyZW47XG5cbiAge1xuICAgIGlmICh0eXBlb2YgcmVuZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignQSBjb250ZXh0IGNvbnN1bWVyIHdhcyByZW5kZXJlZCB3aXRoIG11bHRpcGxlIGNoaWxkcmVuLCBvciBhIGNoaWxkICcgKyBcInRoYXQgaXNuJ3QgYSBmdW5jdGlvbi4gQSBjb250ZXh0IGNvbnN1bWVyIGV4cGVjdHMgYSBzaW5nbGUgY2hpbGQgXCIgKyAndGhhdCBpcyBhIGZ1bmN0aW9uLiBJZiB5b3UgZGlkIHBhc3MgYSBmdW5jdGlvbiwgbWFrZSBzdXJlIHRoZXJlICcgKyAnaXMgbm8gdHJhaWxpbmcgb3IgbGVhZGluZyB3aGl0ZXNwYWNlIGFyb3VuZCBpdC4nKTtcbiAgICB9XG4gIH1cblxuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB2YXIgbmV3VmFsdWUgPSByZWFkQ29udGV4dChjb250ZXh0KTtcblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAgdmFyIG5ld0NoaWxkcmVuO1xuXG4gIHtcbiAgICBSZWFjdEN1cnJlbnRPd25lciQxLmN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcztcbiAgICBzZXRJc1JlbmRlcmluZyh0cnVlKTtcbiAgICBuZXdDaGlsZHJlbiA9IHJlbmRlcihuZXdWYWx1ZSk7XG4gICAgc2V0SXNSZW5kZXJpbmcoZmFsc2UpO1xuICB9XG5cbiAge1xuICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5ld0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKSB7XG4gIGRpZFJlY2VpdmVVcGRhdGUgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgIC8vIFJldXNlIHByZXZpb3VzIGRlcGVuZGVuY2llc1xuICAgIHdvcmtJblByb2dyZXNzLmRlcGVuZGVuY2llcyA9IGN1cnJlbnQuZGVwZW5kZW5jaWVzO1xuICB9XG5cbiAge1xuICAgIC8vIERvbid0IHVwZGF0ZSBcImJhc2VcIiByZW5kZXIgdGltZXMgZm9yIGJhaWxvdXRzLlxuICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nKCk7XG4gIH1cblxuICBtYXJrU2tpcHBlZFVwZGF0ZUxhbmVzKHdvcmtJblByb2dyZXNzLmxhbmVzKTsgLy8gQ2hlY2sgaWYgdGhlIGNoaWxkcmVuIGhhdmUgYW55IHBlbmRpbmcgd29yay5cblxuICBpZiAoIWluY2x1ZGVzU29tZUxhbmUocmVuZGVyTGFuZXMsIHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMpKSB7XG4gICAgLy8gVGhlIGNoaWxkcmVuIGRvbid0IGhhdmUgYW55IHdvcmsgZWl0aGVyLiBXZSBjYW4gc2tpcCB0aGVtLlxuICAgIC8vIFRPRE86IE9uY2Ugd2UgYWRkIGJhY2sgcmVzdW1pbmcsIHdlIHNob3VsZCBjaGVjayBpZiB0aGUgY2hpbGRyZW4gYXJlXG4gICAgLy8gYSB3b3JrLWluLXByb2dyZXNzIHNldC4gSWYgc28sIHdlIG5lZWQgdG8gdHJhbnNmZXIgdGhlaXIgZWZmZWN0cy5cbiAgICB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH0gLy8gVGhpcyBmaWJlciBkb2Vzbid0IGhhdmUgd29yaywgYnV0IGl0cyBzdWJ0cmVlIGRvZXMuIENsb25lIHRoZSBjaGlsZFxuICAvLyBmaWJlcnMgYW5kIGNvbnRpbnVlLlxuXG5cbiAgY2xvbmVDaGlsZEZpYmVycyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gcmVtb3VudEZpYmVyKGN1cnJlbnQsIG9sZFdvcmtJblByb2dyZXNzLCBuZXdXb3JrSW5Qcm9ncmVzcykge1xuICB7XG4gICAgdmFyIHJldHVybkZpYmVyID0gb2xkV29ya0luUHJvZ3Jlc3MucmV0dXJuO1xuXG4gICAgaWYgKHJldHVybkZpYmVyID09PSBudWxsKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3Qgc3dhcCB0aGUgcm9vdCBmaWJlci4nKTtcbiAgICB9IC8vIERpc2Nvbm5lY3QgZnJvbSB0aGUgb2xkIGN1cnJlbnQuXG4gICAgLy8gSXQgd2lsbCBnZXQgZGVsZXRlZC5cblxuXG4gICAgY3VycmVudC5hbHRlcm5hdGUgPSBudWxsO1xuICAgIG9sZFdvcmtJblByb2dyZXNzLmFsdGVybmF0ZSA9IG51bGw7IC8vIENvbm5lY3QgdG8gdGhlIG5ldyB0cmVlLlxuXG4gICAgbmV3V29ya0luUHJvZ3Jlc3MuaW5kZXggPSBvbGRXb3JrSW5Qcm9ncmVzcy5pbmRleDtcbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5zaWJsaW5nID0gb2xkV29ya0luUHJvZ3Jlc3Muc2libGluZztcbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5yZXR1cm4gPSBvbGRXb3JrSW5Qcm9ncmVzcy5yZXR1cm47XG4gICAgbmV3V29ya0luUHJvZ3Jlc3MucmVmID0gb2xkV29ya0luUHJvZ3Jlc3MucmVmOyAvLyBSZXBsYWNlIHRoZSBjaGlsZC9zaWJsaW5nIHBvaW50ZXJzIGFib3ZlIGl0LlxuXG4gICAgaWYgKG9sZFdvcmtJblByb2dyZXNzID09PSByZXR1cm5GaWJlci5jaGlsZCkge1xuICAgICAgcmV0dXJuRmliZXIuY2hpbGQgPSBuZXdXb3JrSW5Qcm9ncmVzcztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHByZXZTaWJsaW5nID0gcmV0dXJuRmliZXIuY2hpbGQ7XG5cbiAgICAgIGlmIChwcmV2U2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHBhcmVudCB0byBoYXZlIGEgY2hpbGQuJyk7XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChwcmV2U2libGluZy5zaWJsaW5nICE9PSBvbGRXb3JrSW5Qcm9ncmVzcykge1xuICAgICAgICBwcmV2U2libGluZyA9IHByZXZTaWJsaW5nLnNpYmxpbmc7XG5cbiAgICAgICAgaWYgKHByZXZTaWJsaW5nID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgdGhlIHByZXZpb3VzIHNpYmxpbmcuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcHJldlNpYmxpbmcuc2libGluZyA9IG5ld1dvcmtJblByb2dyZXNzO1xuICAgIH0gLy8gRGVsZXRlIHRoZSBvbGQgZmliZXIgYW5kIHBsYWNlIHRoZSBuZXcgb25lLlxuICAgIC8vIFNpbmNlIHRoZSBvbGQgZmliZXIgaXMgZGlzY29ubmVjdGVkLCB3ZSBoYXZlIHRvIHNjaGVkdWxlIGl0IG1hbnVhbGx5LlxuXG5cbiAgICB2YXIgZGVsZXRpb25zID0gcmV0dXJuRmliZXIuZGVsZXRpb25zO1xuXG4gICAgaWYgKGRlbGV0aW9ucyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuRmliZXIuZGVsZXRpb25zID0gW2N1cnJlbnRdO1xuICAgICAgcmV0dXJuRmliZXIuZmxhZ3MgfD0gQ2hpbGREZWxldGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRpb25zLnB1c2goY3VycmVudCk7XG4gICAgfVxuXG4gICAgbmV3V29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGxhY2VtZW50OyAvLyBSZXN0YXJ0IHdvcmsgZnJvbSB0aGUgbmV3IGZpYmVyLlxuXG4gICAgcmV0dXJuIG5ld1dvcmtJblByb2dyZXNzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0KGN1cnJlbnQsIHJlbmRlckxhbmVzKSB7XG4gIC8vIEJlZm9yZSBwZXJmb3JtaW5nIGFuIGVhcmx5IGJhaWxvdXQsIHdlIG11c3QgY2hlY2sgaWYgdGhlcmUgYXJlIHBlbmRpbmdcbiAgLy8gdXBkYXRlcyBvciBjb250ZXh0LlxuICB2YXIgdXBkYXRlTGFuZXMgPSBjdXJyZW50LmxhbmVzO1xuXG4gIGlmIChpbmNsdWRlc1NvbWVMYW5lKHVwZGF0ZUxhbmVzLCByZW5kZXJMYW5lcykpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSAvLyBObyBwZW5kaW5nIHVwZGF0ZSwgYnV0IGJlY2F1c2UgY29udGV4dCBpcyBwcm9wYWdhdGVkIGxhemlseSwgd2UgbmVlZFxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gYXR0ZW1wdEVhcmx5QmFpbG91dElmTm9TY2hlZHVsZWRVcGRhdGUoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoaXMgZmliZXIgZG9lcyBub3QgaGF2ZSBhbnkgcGVuZGluZyB3b3JrLiBCYWlsb3V0IHdpdGhvdXQgZW50ZXJpbmdcbiAgLy8gdGhlIGJlZ2luIHBoYXNlLiBUaGVyZSdzIHN0aWxsIHNvbWUgYm9va2tlZXBpbmcgd2UgdGhhdCBuZWVkcyB0byBiZSBkb25lXG4gIC8vIGluIHRoaXMgb3B0aW1pemVkIHBhdGgsIG1vc3RseSBwdXNoaW5nIHN0dWZmIG9udG8gdGhlIHN0YWNrLlxuICBzd2l0Y2ggKHdvcmtJblByb2dyZXNzLnRhZykge1xuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICBwdXNoSG9zdFJvb3RDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHZhciByb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgICByZXNldEh5ZHJhdGlvblN0YXRlKCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHB1c2hIb3N0Q29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBDb21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgICAgICAgcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHB1c2hIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgQ29udGV4dFByb3ZpZGVyOlxuICAgICAge1xuICAgICAgICB2YXIgbmV3VmFsdWUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzLnZhbHVlO1xuICAgICAgICB2YXIgY29udGV4dCA9IHdvcmtJblByb2dyZXNzLnR5cGUuX2NvbnRleHQ7XG4gICAgICAgIHB1c2hQcm92aWRlcih3b3JrSW5Qcm9ncmVzcywgY29udGV4dCwgbmV3VmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgUHJvZmlsZXI6XG4gICAgICB7XG4gICAgICAgIC8vIFByb2ZpbGVyIHNob3VsZCBvbmx5IGNhbGwgb25SZW5kZXIgd2hlbiBvbmUgb2YgaXRzIGRlc2NlbmRhbnRzIGFjdHVhbGx5IHJlbmRlcmVkLlxuICAgICAgICB2YXIgaGFzQ2hpbGRXb3JrID0gaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MuY2hpbGRMYW5lcyk7XG5cbiAgICAgICAgaWYgKGhhc0NoaWxkV29yaykge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBSZXNldCBlZmZlY3QgZHVyYXRpb25zIGZvciB0aGUgbmV4dCBldmVudHVhbCBlZmZlY3QgcGhhc2UuXG4gICAgICAgICAgLy8gVGhlc2UgYXJlIHJlc2V0IGR1cmluZyByZW5kZXIgdG8gYWxsb3cgdGhlIERldlRvb2xzIGNvbW1pdCBob29rIGEgY2hhbmNlIHRvIHJlYWQgdGhlbSxcbiAgICAgICAgICB2YXIgc3RhdGVOb2RlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgICAgICAgIHN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbiA9IDA7XG4gICAgICAgICAgc3RhdGVOb2RlLnBhc3NpdmVFZmZlY3REdXJhdGlvbiA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB2YXIgc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgIGlmIChzdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChzdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgICAgICAgICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzZXREZWZhdWx0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQpKTsgLy8gV2Uga25vdyB0aGF0IHRoaXMgY29tcG9uZW50IHdpbGwgc3VzcGVuZCBhZ2FpbiBiZWNhdXNlIGlmIGl0IGhhc1xuICAgICAgICAgICAgLy8gYmVlbiB1bnN1c3BlbmRlZCBpdCBoYXMgY29tbWl0dGVkIGFzIGEgcmVzb2x2ZWQgU3VzcGVuc2UgY29tcG9uZW50LlxuICAgICAgICAgICAgLy8gSWYgaXQgbmVlZHMgdG8gYmUgcmV0cmllZCwgaXQgc2hvdWxkIGhhdmUgd29yayBzY2hlZHVsZWQgb24gaXQuXG5cbiAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7IC8vIFdlIHNob3VsZCBuZXZlciByZW5kZXIgdGhlIGNoaWxkcmVuIG9mIGEgZGVoeWRyYXRlZCBib3VuZGFyeSB1bnRpbCB3ZVxuICAgICAgICAgICAgLy8gdXBncmFkZSBpdC4gV2UgcmV0dXJuIG51bGwgaW5zdGVhZCBvZiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrLlxuXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9IC8vIElmIHRoaXMgYm91bmRhcnkgaXMgY3VycmVudGx5IHRpbWVkIG91dCwgd2UgbmVlZCB0byBkZWNpZGVcbiAgICAgICAgICAvLyB3aGV0aGVyIHRvIHJldHJ5IHRoZSBwcmltYXJ5IGNoaWxkcmVuLCBvciB0byBza2lwIG92ZXIgaXQgYW5kXG4gICAgICAgICAgLy8gZ28gc3RyYWlnaHQgdG8gdGhlIGZhbGxiYWNrLiBDaGVjayB0aGUgcHJpb3JpdHkgb2YgdGhlIHByaW1hcnlcbiAgICAgICAgICAvLyBjaGlsZCBmcmFnbWVudC5cblxuXG4gICAgICAgICAgdmFyIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gICAgICAgICAgdmFyIHByaW1hcnlDaGlsZExhbmVzID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQuY2hpbGRMYW5lcztcblxuICAgICAgICAgIGlmIChpbmNsdWRlc1NvbWVMYW5lKHJlbmRlckxhbmVzLCBwcmltYXJ5Q2hpbGRMYW5lcykpIHtcbiAgICAgICAgICAgIC8vIFRoZSBwcmltYXJ5IGNoaWxkcmVuIGhhdmUgcGVuZGluZyB3b3JrLiBVc2UgdGhlIG5vcm1hbCBwYXRoXG4gICAgICAgICAgICAvLyB0byBhdHRlbXB0IHRvIHJlbmRlciB0aGUgcHJpbWFyeSBjaGlsZHJlbiBhZ2Fpbi5cbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVTdXNwZW5zZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGUgcHJpbWFyeSBjaGlsZCBmcmFnbWVudCBkb2VzIG5vdCBoYXZlIHBlbmRpbmcgd29yayBtYXJrZWRcbiAgICAgICAgICAgIC8vIG9uIGl0XG4gICAgICAgICAgICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzZXREZWZhdWx0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQpKTsgLy8gVGhlIHByaW1hcnkgY2hpbGRyZW4gZG8gbm90IGhhdmUgcGVuZGluZyB3b3JrIHdpdGggc3VmZmljaWVudFxuICAgICAgICAgICAgLy8gcHJpb3JpdHkuIEJhaWxvdXQuXG5cbiAgICAgICAgICAgIHZhciBjaGlsZCA9IGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgICAgICAgICAgaWYgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIFRoZSBmYWxsYmFjayBjaGlsZHJlbiBoYXZlIHBlbmRpbmcgd29yay4gU2tpcCBvdmVyIHRoZVxuICAgICAgICAgICAgICAvLyBwcmltYXJ5IGNoaWxkcmVuIGFuZCB3b3JrIG9uIHRoZSBmYWxsYmFjay5cbiAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLnNpYmxpbmc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBOb3RlOiBXZSBjYW4gcmV0dXJuIGBudWxsYCBoZXJlIGJlY2F1c2Ugd2UgYWxyZWFkeSBjaGVja2VkXG4gICAgICAgICAgICAgIC8vIHdoZXRoZXIgdGhlcmUgd2VyZSBuZXN0ZWQgY29udGV4dCBjb25zdW1lcnMsIHZpYSB0aGUgY2FsbCB0b1xuICAgICAgICAgICAgICAvLyBgYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29ya2AgYWJvdmUuXG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzZXREZWZhdWx0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBkaWRTdXNwZW5kQmVmb3JlID0gKGN1cnJlbnQuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICAgICAgICB2YXIgX2hhc0NoaWxkV29yayA9IGluY2x1ZGVzU29tZUxhbmUocmVuZGVyTGFuZXMsIHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMpO1xuXG4gICAgICAgIGlmIChkaWRTdXNwZW5kQmVmb3JlKSB7XG4gICAgICAgICAgaWYgKF9oYXNDaGlsZFdvcmspIHtcbiAgICAgICAgICAgIC8vIElmIHNvbWV0aGluZyB3YXMgaW4gZmFsbGJhY2sgc3RhdGUgbGFzdCB0aW1lLCBhbmQgd2UgaGF2ZSBhbGwgdGhlXG4gICAgICAgICAgICAvLyBzYW1lIGNoaWxkcmVuIHRoZW4gd2UncmUgc3RpbGwgaW4gcHJvZ3Jlc3NpdmUgbG9hZGluZyBzdGF0ZS5cbiAgICAgICAgICAgIC8vIFNvbWV0aGluZyBtaWdodCBnZXQgdW5ibG9ja2VkIGJ5IHN0YXRlIHVwZGF0ZXMgb3IgcmV0cmllcyBpbiB0aGVcbiAgICAgICAgICAgIC8vIHRyZWUgd2hpY2ggd2lsbCBhZmZlY3QgdGhlIHRhaWwuIFNvIHdlIG5lZWQgdG8gdXNlIHRoZSBub3JtYWxcbiAgICAgICAgICAgIC8vIHBhdGggdG8gY29tcHV0ZSB0aGUgY29ycmVjdCB0YWlsLlxuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVN1c3BlbnNlTGlzdENvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICAgIH0gLy8gSWYgbm9uZSBvZiB0aGUgY2hpbGRyZW4gaGFkIGFueSB3b3JrLCB0aGF0IG1lYW5zIHRoYXQgbm9uZSBvZlxuICAgICAgICAgIC8vIHRoZW0gZ290IHJldHJpZWQgc28gdGhleSdsbCBzdGlsbCBiZSBibG9ja2VkIGluIHRoZSBzYW1lIHdheVxuICAgICAgICAgIC8vIGFzIGJlZm9yZS4gV2UgY2FuIGZhc3QgYmFpbCBvdXQuXG5cblxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgIH0gLy8gSWYgbm90aGluZyBzdXNwZW5kZWQgYmVmb3JlIGFuZCB3ZSdyZSByZW5kZXJpbmcgdGhlIHNhbWUgY2hpbGRyZW4sXG4gICAgICAgIC8vIHRoZW4gdGhlIHRhaWwgZG9lc24ndCBtYXR0ZXIuIEFueXRoaW5nIG5ldyB0aGF0IHN1c3BlbmRzIHdpbGwgd29ya1xuICAgICAgICAvLyBpbiB0aGUgXCJ0b2dldGhlclwiIG1vZGUsIHNvIHdlIGNhbiBjb250aW51ZSBmcm9tIHRoZSBzdGF0ZSB3ZSBoYWQuXG5cblxuICAgICAgICB2YXIgcmVuZGVyU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgIGlmIChyZW5kZXJTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vIFJlc2V0IHRvIHRoZSBcInRvZ2V0aGVyXCIgbW9kZSBpbiBjYXNlIHdlJ3ZlIHN0YXJ0ZWQgYSBkaWZmZXJlbnRcbiAgICAgICAgICAvLyB1cGRhdGUgaW4gdGhlIHBhc3QgYnV0IGRpZG4ndCBjb21wbGV0ZSBpdC5cbiAgICAgICAgICByZW5kZXJTdGF0ZS5yZW5kZXJpbmcgPSBudWxsO1xuICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICAgIHJlbmRlclN0YXRlLmxhc3RFZmZlY3QgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcHVzaFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuc2VTdGFja0N1cnNvci5jdXJyZW50KTtcblxuICAgICAgICBpZiAoX2hhc0NoaWxkV29yaykge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIElmIG5vbmUgb2YgdGhlIGNoaWxkcmVuIGhhZCBhbnkgd29yaywgdGhhdCBtZWFucyB0aGF0IG5vbmUgb2ZcbiAgICAgICAgICAvLyB0aGVtIGdvdCByZXRyaWVkIHNvIHRoZXknbGwgc3RpbGwgYmUgYmxvY2tlZCBpbiB0aGUgc2FtZSB3YXlcbiAgICAgICAgICAvLyBhcyBiZWZvcmUuIFdlIGNhbiBmYXN0IGJhaWwgb3V0LlxuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICBjYXNlIE9mZnNjcmVlbkNvbXBvbmVudDpcbiAgICBjYXNlIExlZ2FjeUhpZGRlbkNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgLy8gTmVlZCB0byBjaGVjayBpZiB0aGUgdHJlZSBzdGlsbCBuZWVkcyB0byBiZSBkZWZlcnJlZC4gVGhpcyBpc1xuICAgICAgICAvLyBhbG1vc3QgaWRlbnRpY2FsIHRvIHRoZSBsb2dpYyB1c2VkIGluIHRoZSBub3JtYWwgdXBkYXRlIHBhdGgsXG4gICAgICAgIC8vIHNvIHdlJ2xsIGp1c3QgZW50ZXIgdGhhdC4gVGhlIG9ubHkgZGlmZmVyZW5jZSBpcyB3ZSdsbCBiYWlsIG91dFxuICAgICAgICAvLyBhdCB0aGUgbmV4dCBsZXZlbCBpbnN0ZWFkIG9mIHRoaXMgb25lLCBiZWNhdXNlIHRoZSBjaGlsZCBwcm9wc1xuICAgICAgICAvLyBoYXZlIG5vdCBjaGFuZ2VkLiBXaGljaCBpcyBmaW5lLlxuICAgICAgICAvLyBUT0RPOiBQcm9iYWJseSBzaG91bGQgcmVmYWN0b3IgYGJlZ2luV29ya2AgdG8gc3BsaXQgdGhlIGJhaWxvdXRcbiAgICAgICAgLy8gcGF0aCBmcm9tIHRoZSBub3JtYWwgcGF0aC4gSSdtIHRlbXB0ZWQgdG8gZG8gYSBsYWJlbGVkIGJyZWFrIGhlcmVcbiAgICAgICAgLy8gYnV0IEkgd29uJ3QgOilcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBOb0xhbmVzO1xuICAgICAgICByZXR1cm4gdXBkYXRlT2Zmc2NyZWVuQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xufVxuXG5mdW5jdGlvbiBiZWdpbldvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHtcbiAgICBpZiAod29ya0luUHJvZ3Jlc3MuX2RlYnVnTmVlZHNSZW1vdW50ICYmIGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgd2lsbCByZXN0YXJ0IHRoZSBiZWdpbiBwaGFzZSB3aXRoIGEgbmV3IGZpYmVyLlxuICAgICAgcmV0dXJuIHJlbW91bnRGaWJlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgY3JlYXRlRmliZXJGcm9tVHlwZUFuZFByb3BzKHdvcmtJblByb2dyZXNzLnR5cGUsIHdvcmtJblByb2dyZXNzLmtleSwgd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzLCB3b3JrSW5Qcm9ncmVzcy5fZGVidWdPd25lciB8fCBudWxsLCB3b3JrSW5Qcm9ncmVzcy5tb2RlLCB3b3JrSW5Qcm9ncmVzcy5sYW5lcykpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgdmFyIG9sZFByb3BzID0gY3VycmVudC5tZW1vaXplZFByb3BzO1xuICAgIHZhciBuZXdQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcblxuICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMgfHwgaGFzQ29udGV4dENoYW5nZWQoKSB8fCAoIC8vIEZvcmNlIGEgcmUtcmVuZGVyIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VkIGR1ZSB0byBob3QgcmVsb2FkOlxuICAgICB3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSBjdXJyZW50LnR5cGUgKSkge1xuICAgICAgLy8gSWYgcHJvcHMgb3IgY29udGV4dCBjaGFuZ2VkLCBtYXJrIHRoZSBmaWJlciBhcyBoYXZpbmcgcGVyZm9ybWVkIHdvcmsuXG4gICAgICAvLyBUaGlzIG1heSBiZSB1bnNldCBpZiB0aGUgcHJvcHMgYXJlIGRldGVybWluZWQgdG8gYmUgZXF1YWwgbGF0ZXIgKG1lbW8pLlxuICAgICAgZGlkUmVjZWl2ZVVwZGF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5laXRoZXIgcHJvcHMgbm9yIGxlZ2FjeSBjb250ZXh0IGNoYW5nZXMuIENoZWNrIGlmIHRoZXJlJ3MgYSBwZW5kaW5nXG4gICAgICAvLyB1cGRhdGUgb3IgY29udGV4dCBjaGFuZ2UuXG4gICAgICB2YXIgaGFzU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0ID0gY2hlY2tTY2hlZHVsZWRVcGRhdGVPckNvbnRleHQoY3VycmVudCwgcmVuZGVyTGFuZXMpO1xuXG4gICAgICBpZiAoIWhhc1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dCAmJiAvLyBJZiB0aGlzIGlzIHRoZSBzZWNvbmQgcGFzcyBvZiBhbiBlcnJvciBvciBzdXNwZW5zZSBib3VuZGFyeSwgdGhlcmVcbiAgICAgIC8vIG1heSBub3QgYmUgd29yayBzY2hlZHVsZWQgb24gYGN1cnJlbnRgLCBzbyB3ZSBjaGVjayBmb3IgdGhpcyBmbGFnLlxuICAgICAgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gTm8gcGVuZGluZyB1cGRhdGVzIG9yIGNvbnRleHQuIEJhaWwgb3V0IG5vdy5cbiAgICAgICAgZGlkUmVjZWl2ZVVwZGF0ZSA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gYXR0ZW1wdEVhcmx5QmFpbG91dElmTm9TY2hlZHVsZWRVcGRhdGUoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChjdXJyZW50LmZsYWdzICYgRm9yY2VVcGRhdGVGb3JMZWdhY3lTdXNwZW5zZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSB0aGF0IG9ubHkgZXhpc3RzIGZvciBsZWdhY3kgbW9kZS5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzE5MjE2LlxuICAgICAgICBkaWRSZWNlaXZlVXBkYXRlID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEFuIHVwZGF0ZSB3YXMgc2NoZWR1bGVkIG9uIHRoaXMgZmliZXIsIGJ1dCB0aGVyZSBhcmUgbm8gbmV3IHByb3BzXG4gICAgICAgIC8vIG5vciBsZWdhY3kgY29udGV4dC4gU2V0IHRoaXMgdG8gZmFsc2UuIElmIGFuIHVwZGF0ZSBxdWV1ZSBvciBjb250ZXh0XG4gICAgICAgIC8vIGNvbnN1bWVyIHByb2R1Y2VzIGEgY2hhbmdlZCB2YWx1ZSwgaXQgd2lsbCBzZXQgdGhpcyB0byB0cnVlLiBPdGhlcndpc2UsXG4gICAgICAgIC8vIHRoZSBjb21wb25lbnQgd2lsbCBhc3N1bWUgdGhlIGNoaWxkcmVuIGhhdmUgbm90IGNoYW5nZWQgYW5kIGJhaWwgb3V0LlxuICAgICAgICBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRpZFJlY2VpdmVVcGRhdGUgPSBmYWxzZTtcblxuICAgIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIGlzRm9ya2VkQ2hpbGQod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGNoaWxkIGJlbG9uZ3MgdG8gYSBsaXN0IG9mIG11bGlwbGUgY2hpbGRyZW4gaW5cbiAgICAgIC8vIGl0cyBwYXJlbnQuXG4gICAgICAvL1xuICAgICAgLy8gSW4gYSB0cnVlIG11bHRpLXRocmVhZGVkIGltcGxlbWVudGF0aW9uLCB3ZSB3b3VsZCByZW5kZXIgY2hpbGRyZW4gb25cbiAgICAgIC8vIHBhcmFsbGVsIHRocmVhZHMuIFRoaXMgd291bGQgcmVwcmVzZW50IHRoZSBiZWdpbm5pbmcgb2YgYSBuZXcgcmVuZGVyXG4gICAgICAvLyB0aHJlYWQgZm9yIHRoaXMgc3VidHJlZS5cbiAgICAgIC8vXG4gICAgICAvLyBXZSBvbmx5IHVzZSB0aGlzIGZvciBpZCBnZW5lcmF0aW9uIGR1cmluZyBoeWRyYXRpb24sIHdoaWNoIGlzIHdoeSB0aGVcbiAgICAgIC8vIGxvZ2ljIGlzIGxvY2F0ZWQgaW4gdGhpcyBzcGVjaWFsIGJyYW5jaC5cbiAgICAgIHZhciBzbG90SW5kZXggPSB3b3JrSW5Qcm9ncmVzcy5pbmRleDtcbiAgICAgIHZhciBudW1iZXJPZkZvcmtzID0gZ2V0Rm9ya3NBdExldmVsKCk7XG4gICAgICBwdXNoVHJlZUlkKHdvcmtJblByb2dyZXNzLCBudW1iZXJPZkZvcmtzLCBzbG90SW5kZXgpO1xuICAgIH1cbiAgfSAvLyBCZWZvcmUgZW50ZXJpbmcgdGhlIGJlZ2luIHBoYXNlLCBjbGVhciBwZW5kaW5nIHVwZGF0ZSBwcmlvcml0eS5cbiAgLy8gVE9ETzogVGhpcyBhc3N1bWVzIHRoYXQgd2UncmUgYWJvdXQgdG8gZXZhbHVhdGUgdGhlIGNvbXBvbmVudCBhbmQgcHJvY2Vzc1xuICAvLyB0aGUgdXBkYXRlIHF1ZXVlLiBIb3dldmVyLCB0aGVyZSdzIGFuIGV4Y2VwdGlvbjogU2ltcGxlTWVtb0NvbXBvbmVudFxuICAvLyBzb21ldGltZXMgYmFpbHMgb3V0IGxhdGVyIGluIHRoZSBiZWdpbiBwaGFzZS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB3ZSBzaG91bGRcbiAgLy8gbW92ZSB0aGlzIGFzc2lnbm1lbnQgb3V0IG9mIHRoZSBjb21tb24gcGF0aCBhbmQgaW50byBlYWNoIGJyYW5jaC5cblxuXG4gIHdvcmtJblByb2dyZXNzLmxhbmVzID0gTm9MYW5lcztcblxuICBzd2l0Y2ggKHdvcmtJblByb2dyZXNzLnRhZykge1xuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIG1vdW50SW5kZXRlcm1pbmF0ZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgd29ya0luUHJvZ3Jlc3MudHlwZSwgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBMYXp5Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB2YXIgZWxlbWVudFR5cGUgPSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZTtcbiAgICAgICAgcmV0dXJuIG1vdW50TGF6eUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgZWxlbWVudFR5cGUsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBDb21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICAgICAgICB2YXIgdW5yZXNvbHZlZFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICAgICAgICB2YXIgcmVzb2x2ZWRQcm9wcyA9IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlID09PSBDb21wb25lbnQgPyB1bnJlc29sdmVkUHJvcHMgOiByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudCwgdW5yZXNvbHZlZFByb3BzKTtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZUZ1bmN0aW9uQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHJlc29sdmVkUHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBfQ29tcG9uZW50ID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICAgICAgdmFyIF91bnJlc29sdmVkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG5cbiAgICAgICAgdmFyIF9yZXNvbHZlZFByb3BzID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPT09IF9Db21wb25lbnQgPyBfdW5yZXNvbHZlZFByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhfQ29tcG9uZW50LCBfdW5yZXNvbHZlZFByb3BzKTtcblxuICAgICAgICByZXR1cm4gdXBkYXRlQ2xhc3NDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIF9Db21wb25lbnQsIF9yZXNvbHZlZFByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAgcmV0dXJuIHVwZGF0ZUhvc3RSb290KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gdXBkYXRlSG9zdENvbXBvbmVudCQxKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgcmV0dXJuIHVwZGF0ZUhvc3RUZXh0JDEoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHJldHVybiB1cGRhdGVTdXNwZW5zZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgcmV0dXJuIHVwZGF0ZVBvcnRhbENvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAge1xuICAgICAgICB2YXIgdHlwZSA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciBfdW5yZXNvbHZlZFByb3BzMiA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcblxuICAgICAgICB2YXIgX3Jlc29sdmVkUHJvcHMyID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPT09IHR5cGUgPyBfdW5yZXNvbHZlZFByb3BzMiA6IHJlc29sdmVEZWZhdWx0UHJvcHModHlwZSwgX3VucmVzb2x2ZWRQcm9wczIpO1xuXG4gICAgICAgIHJldHVybiB1cGRhdGVGb3J3YXJkUmVmKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB0eXBlLCBfcmVzb2x2ZWRQcm9wczIsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgRnJhZ21lbnQ6XG4gICAgICByZXR1cm4gdXBkYXRlRnJhZ21lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgTW9kZTpcbiAgICAgIHJldHVybiB1cGRhdGVNb2RlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgcmV0dXJuIHVwZGF0ZVByb2ZpbGVyKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIENvbnRleHRQcm92aWRlcjpcbiAgICAgIHJldHVybiB1cGRhdGVDb250ZXh0UHJvdmlkZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgQ29udGV4dENvbnN1bWVyOlxuICAgICAgcmV0dXJuIHVwZGF0ZUNvbnRleHRDb25zdW1lcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB2YXIgX3R5cGUyID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICAgICAgdmFyIF91bnJlc29sdmVkUHJvcHMzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzOyAvLyBSZXNvbHZlIG91dGVyIHByb3BzIGZpcnN0LCB0aGVuIHJlc29sdmUgaW5uZXIgcHJvcHMuXG5cbiAgICAgICAgdmFyIF9yZXNvbHZlZFByb3BzMyA9IHJlc29sdmVEZWZhdWx0UHJvcHMoX3R5cGUyLCBfdW5yZXNvbHZlZFByb3BzMyk7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSkge1xuICAgICAgICAgICAgdmFyIG91dGVyUHJvcFR5cGVzID0gX3R5cGUyLnByb3BUeXBlcztcblxuICAgICAgICAgICAgaWYgKG91dGVyUHJvcFR5cGVzKSB7XG4gICAgICAgICAgICAgIGNoZWNrUHJvcFR5cGVzKG91dGVyUHJvcFR5cGVzLCBfcmVzb2x2ZWRQcm9wczMsIC8vIFJlc29sdmVkIGZvciBvdXRlciBvbmx5XG4gICAgICAgICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKF90eXBlMikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIF9yZXNvbHZlZFByb3BzMyA9IHJlc29sdmVEZWZhdWx0UHJvcHMoX3R5cGUyLnR5cGUsIF9yZXNvbHZlZFByb3BzMyk7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBfdHlwZTIsIF9yZXNvbHZlZFByb3BzMywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZXR1cm4gdXBkYXRlU2ltcGxlTWVtb0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgd29ya0luUHJvZ3Jlc3MudHlwZSwgd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIF9Db21wb25lbnQyID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICAgICAgdmFyIF91bnJlc29sdmVkUHJvcHM0ID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuXG4gICAgICAgIHZhciBfcmVzb2x2ZWRQcm9wczQgPSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSA9PT0gX0NvbXBvbmVudDIgPyBfdW5yZXNvbHZlZFByb3BzNCA6IHJlc29sdmVEZWZhdWx0UHJvcHMoX0NvbXBvbmVudDIsIF91bnJlc29sdmVkUHJvcHM0KTtcblxuICAgICAgICByZXR1cm4gbW91bnRJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIF9Db21wb25lbnQyLCBfcmVzb2x2ZWRQcm9wczQsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VMaXN0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZXR1cm4gdXBkYXRlU3VzcGVuc2VMaXN0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAge1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJldHVybiB1cGRhdGVPZmZzY3JlZW5Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdW5pdCBvZiB3b3JrIHRhZyAoXCIgKyB3b3JrSW5Qcm9ncmVzcy50YWcgKyBcIikuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBcIiArICdSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG59XG5cbmZ1bmN0aW9uIHVud2luZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuICBwb3BUcmVlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB2YXIgQ29tcG9uZW50ID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcblxuICAgICAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgICAgIHBvcENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZsYWdzID0gd29ya0luUHJvZ3Jlc3MuZmxhZ3M7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgU2hvdWxkQ2FwdHVyZSkge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gZmxhZ3MgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7XG5cbiAgICAgICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgIHRyYW5zZmVyQWN0dWFsRHVyYXRpb24od29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHtcbiAgICAgICAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICBwb3BUb3BMZXZlbENvbnRleHRPYmplY3Qod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICByZXNldFdvcmtJblByb2dyZXNzVmVyc2lvbnMoKTtcbiAgICAgICAgdmFyIF9mbGFncyA9IHdvcmtJblByb2dyZXNzLmZsYWdzO1xuXG4gICAgICAgIGlmICgoX2ZsYWdzICYgU2hvdWxkQ2FwdHVyZSkgIT09IE5vRmxhZ3MgJiYgKF9mbGFncyAmIERpZENhcHR1cmUpID09PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgLy8gVGhlcmUgd2FzIGFuIGVycm9yIGR1cmluZyByZW5kZXIgdGhhdCB3YXNuJ3QgY2FwdHVyZWQgYnkgYSBzdXNwZW5zZVxuICAgICAgICAgIC8vIGJvdW5kYXJ5LiBEbyBhIHNlY29uZCBwYXNzIG9uIHRoZSByb290IHRvIHVubW91bnQgdGhlIGNoaWxkcmVuLlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gX2ZsYWdzICYgflNob3VsZENhcHR1cmUgfCBEaWRDYXB0dXJlO1xuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfSAvLyBXZSB1bndvdW5kIHRvIHRoZSByb290IHdpdGhvdXQgY29tcGxldGluZyBpdC4gRXhpdC5cblxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICAvLyBUT0RPOiBwb3BIeWRyYXRpb25TdGF0ZVxuICAgICAgICBwb3BIb3N0Q29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgdmFyIHN1c3BlbnNlU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsICYmIHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhyZXcgaW4gbmV3bHkgbW91bnRlZCBkZWh5ZHJhdGVkIGNvbXBvbmVudC4gVGhpcyBpcyBsaWtlbHkgYSBidWcgaW4gJyArICdSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9mbGFnczIgPSB3b3JrSW5Qcm9ncmVzcy5mbGFncztcblxuICAgICAgICBpZiAoX2ZsYWdzMiAmIFNob3VsZENhcHR1cmUpIHtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyA9IF9mbGFnczIgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7IC8vIENhcHR1cmVkIGEgc3VzcGVuc2UgZWZmZWN0LiBSZS1yZW5kZXIgdGhlIGJvdW5kYXJ5LlxuXG4gICAgICAgICAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICB0cmFuc2ZlckFjdHVhbER1cmF0aW9uKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3M7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VMaXN0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBwb3BTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MpOyAvLyBTdXNwZW5zZUxpc3QgZG9lc24ndCBhY3R1YWxseSBjYXRjaCBhbnl0aGluZy4gSXQgc2hvdWxkJ3ZlIGJlZW5cbiAgICAgICAgLy8gY2F1Z2h0IGJ5IGEgbmVzdGVkIGJvdW5kYXJ5LiBJZiBub3QsIGl0IHNob3VsZCBidWJibGUgdGhyb3VnaC5cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjYXNlIENvbnRleHRQcm92aWRlcjpcbiAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgIHBvcFByb3ZpZGVyKGNvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICBwb3BSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgQ2FjaGVDb21wb25lbnQ6XG5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVud2luZEludGVycnVwdGVkV29yayhjdXJyZW50LCBpbnRlcnJ1cHRlZFdvcmssIHJlbmRlckxhbmVzKSB7XG4gIC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuICBwb3BUcmVlQ29udGV4dChpbnRlcnJ1cHRlZFdvcmspO1xuXG4gIHN3aXRjaCAoaW50ZXJydXB0ZWRXb3JrLnRhZykge1xuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBjaGlsZENvbnRleHRUeXBlcyA9IGludGVycnVwdGVkV29yay50eXBlLmNoaWxkQ29udGV4dFR5cGVzO1xuXG4gICAgICAgIGlmIChjaGlsZENvbnRleHRUeXBlcyAhPT0gbnVsbCAmJiBjaGlsZENvbnRleHRUeXBlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcG9wQ29udGV4dChpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAge1xuICAgICAgICB2YXIgcm9vdCA9IGludGVycnVwdGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgIHBvcEhvc3RDb250YWluZXIoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgICAgcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGludGVycnVwdGVkV29yayk7XG4gICAgICAgIHJlc2V0V29ya0luUHJvZ3Jlc3NWZXJzaW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wSG9zdENvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBwb3BIb3N0Q29udGFpbmVyKGludGVycnVwdGVkV29yayk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICBwb3BTdXNwZW5zZUNvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICBwb3BTdXNwZW5zZUNvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB2YXIgY29udGV4dCA9IGludGVycnVwdGVkV29yay50eXBlLl9jb250ZXh0O1xuICAgICAgcG9wUHJvdmlkZXIoY29udGV4dCwgaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICBwb3BSZW5kZXJMYW5lcyhpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgYnJlYWs7XG4gIH1cbn1cblxudmFyIGRpZFdhcm5BYm91dFVuZGVmaW5lZFNuYXBzaG90QmVmb3JlVXBkYXRlID0gbnVsbDtcblxue1xuICBkaWRXYXJuQWJvdXRVbmRlZmluZWRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9IG5ldyBTZXQoKTtcbn0gLy8gVXNlZCBkdXJpbmcgdGhlIGNvbW1pdCBwaGFzZSB0byB0cmFjayB0aGUgc3RhdGUgb2YgdGhlIE9mZnNjcmVlbiBjb21wb25lbnQgc3RhY2suXG4vLyBBbGxvd3MgdXMgdG8gYXZvaWQgdHJhdmVyc2luZyB0aGUgcmV0dXJuIHBhdGggdG8gZmluZCB0aGUgbmVhcmVzdCBPZmZzY3JlZW4gYW5jZXN0b3IuXG4vLyBPbmx5IHVzZWQgd2hlbiBlbmFibGVTdXNwZW5zZUxheW91dEVmZmVjdFNlbWFudGljcyBpcyBlbmFibGVkLlxuXG5cbnZhciBvZmZzY3JlZW5TdWJ0cmVlSXNIaWRkZW4gPSBmYWxzZTtcbnZhciBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gZmFsc2U7XG52YXIgUG9zc2libHlXZWFrU2V0ID0gdHlwZW9mIFdlYWtTZXQgPT09ICdmdW5jdGlvbicgPyBXZWFrU2V0IDogU2V0O1xudmFyIG5leHRFZmZlY3QgPSBudWxsOyAvLyBVc2VkIGZvciBQcm9maWxpbmcgYnVpbGRzIHRvIHRyYWNrIHVwZGF0ZXJzLlxuXG52YXIgaW5Qcm9ncmVzc0xhbmVzID0gbnVsbDtcbnZhciBpblByb2dyZXNzUm9vdCA9IG51bGw7XG5mdW5jdGlvbiByZXBvcnRVbmNhdWdodEVycm9ySW5ERVYoZXJyb3IpIHtcbiAgLy8gV3JhcHBpbmcgZWFjaCBzbWFsbCBwYXJ0IG9mIHRoZSBjb21taXQgcGhhc2UgaW50byBhIGd1YXJkZWRcbiAgLy8gY2FsbGJhY2sgaXMgYSBiaXQgdG9vIHNsb3cgKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIxNjY2KS5cbiAgLy8gQnV0IHdlIHJlbHkgb24gaXQgdG8gc3VyZmFjZSBlcnJvcnMgdG8gREVWIHRvb2xzIGxpa2Ugb3ZlcmxheXNcbiAgLy8gKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMjE3MTIpLlxuICAvLyBBcyBhIGNvbXByb21pc2UsIHJldGhyb3cgb25seSBjYXVnaHQgZXJyb3JzIGluIGEgZ3VhcmQuXG4gIHtcbiAgICBpbnZva2VHdWFyZGVkQ2FsbGJhY2sobnVsbCwgZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG4gICAgY2xlYXJDYXVnaHRFcnJvcigpO1xuICB9XG59XG5cbnZhciBjYWxsQ29tcG9uZW50V2lsbFVubW91bnRXaXRoVGltZXIgPSBmdW5jdGlvbiAoY3VycmVudCwgaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gIGluc3RhbmNlLnN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuXG4gIGlmICggY3VycmVudC5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICB0cnkge1xuICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVubW91bnQoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oY3VycmVudCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50KCk7XG4gIH1cbn07IC8vIENhcHR1cmUgZXJyb3JzIHNvIHRoZXkgZG9uJ3QgaW50ZXJydXB0IG1vdW50aW5nLlxuXG5cbmZ1bmN0aW9uIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpIHtcbiAgdHJ5IHtcbiAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCwgY3VycmVudCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IpO1xuICB9XG59IC8vIENhcHR1cmUgZXJyb3JzIHNvIHRoZXkgZG9uJ3QgaW50ZXJydXB0IHVubW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbENvbXBvbmVudFdpbGxVbm1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGluc3RhbmNlKSB7XG4gIHRyeSB7XG4gICAgY2FsbENvbXBvbmVudFdpbGxVbm1vdW50V2l0aFRpbWVyKGN1cnJlbnQsIGluc3RhbmNlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn0gLy8gQ2FwdHVyZSBlcnJvcnMgc28gdGhleSBkb24ndCBpbnRlcnJ1cHQgbW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbENvbXBvbmVudERpZE1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGluc3RhbmNlKSB7XG4gIHRyeSB7XG4gICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn0gLy8gQ2FwdHVyZSBlcnJvcnMgc28gdGhleSBkb24ndCBpbnRlcnJ1cHQgbW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5QXR0YWNoUmVmKGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpIHtcbiAgdHJ5IHtcbiAgICBjb21taXRBdHRhY2hSZWYoY3VycmVudCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNhZmVseURldGFjaFJlZihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yKSB7XG4gIHZhciByZWYgPSBjdXJyZW50LnJlZjtcblxuICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiByZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciByZXRWYWw7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyICYmIGVuYWJsZVByb2ZpbGVyQ29tbWl0SG9va3MgJiYgY3VycmVudC5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgICAgICAgcmV0VmFsID0gcmVmKG51bGwpO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihjdXJyZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0VmFsID0gcmVmKG51bGwpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXRWYWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBlcnJvcignVW5leHBlY3RlZCByZXR1cm4gdmFsdWUgZnJvbSBhIGNhbGxiYWNrIHJlZiBpbiAlcy4gJyArICdBIGNhbGxiYWNrIHJlZiBzaG91bGQgbm90IHJldHVybiBhIGZ1bmN0aW9uLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoY3VycmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbERlc3Ryb3koY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVzdHJveSkge1xuICB0cnkge1xuICAgIGRlc3Ryb3koKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn1cblxudmFyIGZvY3VzZWRJbnN0YW5jZUhhbmRsZSA9IG51bGw7XG52YXIgc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyID0gZmFsc2U7XG5mdW5jdGlvbiBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmlyc3RDaGlsZCkge1xuICBmb2N1c2VkSW5zdGFuY2VIYW5kbGUgPSBwcmVwYXJlRm9yQ29tbWl0KHJvb3QuY29udGFpbmVySW5mbyk7XG4gIG5leHRFZmZlY3QgPSBmaXJzdENoaWxkO1xuICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNfYmVnaW4oKTsgLy8gV2Ugbm8gbG9uZ2VyIG5lZWQgdG8gdHJhY2sgdGhlIGFjdGl2ZSBpbnN0YW5jZSBmaWJlclxuXG4gIHZhciBzaG91bGRGaXJlID0gc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyO1xuICBzaG91bGRGaXJlQWZ0ZXJBY3RpdmVJbnN0YW5jZUJsdXIgPSBmYWxzZTtcbiAgZm9jdXNlZEluc3RhbmNlSGFuZGxlID0gbnVsbDtcbiAgcmV0dXJuIHNob3VsZEZpcmU7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdEJlZm9yZU11dGF0aW9uRWZmZWN0c19iZWdpbigpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0OyAvLyBUaGlzIHBoYXNlIGlzIG9ubHkgdXNlZCBmb3IgYmVmb3JlQWN0aXZlSW5zdGFuY2VCbHVyLlxuXG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoKGZpYmVyLnN1YnRyZWVGbGFncyAmIEJlZm9yZU11dGF0aW9uTWFzaykgIT09IE5vRmxhZ3MgJiYgY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGNoaWxkLnJldHVybiA9IGZpYmVyO1xuICAgICAgbmV4dEVmZmVjdCA9IGNoaWxkO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNfY29tcGxldGUoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0QmVmb3JlTXV0YXRpb25FZmZlY3RzX2NvbXBsZXRlKCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgIHRyeSB7XG4gICAgICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNPbkZpYmVyKGZpYmVyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgIH1cblxuICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkV29yaykge1xuICB2YXIgY3VycmVudCA9IGZpbmlzaGVkV29yay5hbHRlcm5hdGU7XG4gIHZhciBmbGFncyA9IGZpbmlzaGVkV29yay5mbGFncztcblxuICBpZiAoKGZsYWdzICYgU25hcHNob3QpICE9PSBOb0ZsYWdzKSB7XG4gICAgc2V0Q3VycmVudEZpYmVyKGZpbmlzaGVkV29yayk7XG5cbiAgICBzd2l0Y2ggKGZpbmlzaGVkV29yay50YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBwcmV2UHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgICB2YXIgcHJldlN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZTsgLy8gV2UgY291bGQgdXBkYXRlIGluc3RhbmNlIHByb3BzIGFuZCBzdGF0ZSBoZXJlLFxuICAgICAgICAgICAgLy8gYnV0IGluc3RlYWQgd2UgcmVseSBvbiB0aGVtIGJlaW5nIHNldCBkdXJpbmcgbGFzdCByZW5kZXIuXG4gICAgICAgICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgd2hlbiB3ZSBpbXBsZW1lbnQgcmVzdW1pbmcuXG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgcHJvcHMgdG8gbWF0Y2ggbWVtb2l6ZWQgcHJvcHMgYmVmb3JlICcgKyAnZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnByb3BzYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnN0YXRlICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRTdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgZXJyb3IoJ0V4cGVjdGVkICVzIHN0YXRlIHRvIG1hdGNoIG1lbW9pemVkIHN0YXRlIGJlZm9yZSAnICsgJ2dldFNuYXBzaG90QmVmb3JlVXBkYXRlLiAnICsgJ1RoaXMgbWlnaHQgZWl0aGVyIGJlIGJlY2F1c2Ugb2YgYSBidWcgaW4gUmVhY3QsIG9yIGJlY2F1c2UgJyArICdhIGNvbXBvbmVudCByZWFzc2lnbnMgaXRzIG93biBgdGhpcy5zdGF0ZWAuICcgKyAnUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspIHx8ICdpbnN0YW5jZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc25hcHNob3QgPSBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZShmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgPT09IGZpbmlzaGVkV29yay50eXBlID8gcHJldlByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhmaW5pc2hlZFdvcmsudHlwZSwgcHJldlByb3BzKSwgcHJldlN0YXRlKTtcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgZGlkV2FyblNldCA9IGRpZFdhcm5BYm91dFVuZGVmaW5lZFNuYXBzaG90QmVmb3JlVXBkYXRlO1xuXG4gICAgICAgICAgICAgIGlmIChzbmFwc2hvdCA9PT0gdW5kZWZpbmVkICYmICFkaWRXYXJuU2V0LmhhcyhmaW5pc2hlZFdvcmsudHlwZSkpIHtcbiAgICAgICAgICAgICAgICBkaWRXYXJuU2V0LmFkZChmaW5pc2hlZFdvcmsudHlwZSk7XG5cbiAgICAgICAgICAgICAgICBlcnJvcignJXMuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKTogQSBzbmFwc2hvdCB2YWx1ZSAob3IgbnVsbCkgJyArICdtdXN0IGJlIHJldHVybmVkLiBZb3UgaGF2ZSByZXR1cm5lZCB1bmRlZmluZWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9IHNuYXBzaG90O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcm9vdCA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgICAgICBjbGVhckNvbnRhaW5lcihyb290LmNvbnRhaW5lckluZm8pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgLy8gTm90aGluZyB0byBkbyBmb3IgdGhlc2UgY29tcG9uZW50IHR5cGVzXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHVuaXQgb2Ygd29yayB0YWcgc2hvdWxkIG5vdCBoYXZlIHNpZGUtZWZmZWN0cy4gVGhpcyBlcnJvciBpcyAnICsgJ2xpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoZmxhZ3MsIGZpbmlzaGVkV29yaywgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICB2YXIgdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG4gIHZhciBsYXN0RWZmZWN0ID0gdXBkYXRlUXVldWUgIT09IG51bGwgPyB1cGRhdGVRdWV1ZS5sYXN0RWZmZWN0IDogbnVsbDtcblxuICBpZiAobGFzdEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaXJzdEVmZmVjdCA9IGxhc3RFZmZlY3QubmV4dDtcbiAgICB2YXIgZWZmZWN0ID0gZmlyc3RFZmZlY3Q7XG5cbiAgICBkbyB7XG4gICAgICBpZiAoKGVmZmVjdC50YWcgJiBmbGFncykgPT09IGZsYWdzKSB7XG4gICAgICAgIC8vIFVubW91bnRcbiAgICAgICAgdmFyIGRlc3Ryb3kgPSBlZmZlY3QuZGVzdHJveTtcbiAgICAgICAgZWZmZWN0LmRlc3Ryb3kgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKGRlc3Ryb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBQYXNzaXZlJDEpICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RhcnRlZChmaW5pc2hlZFdvcmspO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBMYXlvdXQpICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKChmbGFncyAmIEluc2VydGlvbikgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgICBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZmluaXNoZWRXb3JrLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoKGZsYWdzICYgUGFzc2l2ZSQxKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICAgIG1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgTGF5b3V0KSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICAgIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RvcHBlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlZmZlY3QgPSBlZmZlY3QubmV4dDtcbiAgICB9IHdoaWxlIChlZmZlY3QgIT09IGZpcnN0RWZmZWN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KGZsYWdzLCBmaW5pc2hlZFdvcmspIHtcbiAgdmFyIHVwZGF0ZVF1ZXVlID0gZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlO1xuICB2YXIgbGFzdEVmZmVjdCA9IHVwZGF0ZVF1ZXVlICE9PSBudWxsID8gdXBkYXRlUXVldWUubGFzdEVmZmVjdCA6IG51bGw7XG5cbiAgaWYgKGxhc3RFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmlyc3RFZmZlY3QgPSBsYXN0RWZmZWN0Lm5leHQ7XG4gICAgdmFyIGVmZmVjdCA9IGZpcnN0RWZmZWN0O1xuXG4gICAgZG8ge1xuICAgICAgaWYgKChlZmZlY3QudGFnICYgZmxhZ3MpID09PSBmbGFncykge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKChmbGFncyAmIFBhc3NpdmUkMSkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RNb3VudFN0YXJ0ZWQoZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKChmbGFncyAmIExheW91dCkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZChmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH1cbiAgICAgICAgfSAvLyBNb3VudFxuXG5cbiAgICAgICAgdmFyIGNyZWF0ZSA9IGVmZmVjdC5jcmVhdGU7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmICgoZmxhZ3MgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgIHNldElzUnVubmluZ0luc2VydGlvbkVmZmVjdCh0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBlZmZlY3QuZGVzdHJveSA9IGNyZWF0ZSgpO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoKGZsYWdzICYgSW5zZXJ0aW9uKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QoZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoKGZsYWdzICYgUGFzc2l2ZSQxKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgTGF5b3V0KSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIHZhciBkZXN0cm95ID0gZWZmZWN0LmRlc3Ryb3k7XG5cbiAgICAgICAgICBpZiAoZGVzdHJveSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBkZXN0cm95ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgaG9va05hbWUgPSB2b2lkIDA7XG5cbiAgICAgICAgICAgIGlmICgoZWZmZWN0LnRhZyAmIExheW91dCkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAgICAgaG9va05hbWUgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGVmZmVjdC50YWcgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgICAgIGhvb2tOYW1lID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBob29rTmFtZSA9ICd1c2VFZmZlY3QnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgYWRkZW5kdW0gPSB2b2lkIDA7XG5cbiAgICAgICAgICAgIGlmIChkZXN0cm95ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJyBZb3UgcmV0dXJuZWQgbnVsbC4gSWYgeW91ciBlZmZlY3QgZG9lcyBub3QgcmVxdWlyZSBjbGVhbiAnICsgJ3VwLCByZXR1cm4gdW5kZWZpbmVkIChvciBub3RoaW5nKS4nO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGVzdHJveS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJ1xcblxcbkl0IGxvb2tzIGxpa2UgeW91IHdyb3RlICcgKyBob29rTmFtZSArICcoYXN5bmMgKCkgPT4gLi4uKSBvciByZXR1cm5lZCBhIFByb21pc2UuICcgKyAnSW5zdGVhZCwgd3JpdGUgdGhlIGFzeW5jIGZ1bmN0aW9uIGluc2lkZSB5b3VyIGVmZmVjdCAnICsgJ2FuZCBjYWxsIGl0IGltbWVkaWF0ZWx5OlxcblxcbicgKyBob29rTmFtZSArICcoKCkgPT4ge1xcbicgKyAnICBhc3luYyBmdW5jdGlvbiBmZXRjaERhdGEoKSB7XFxuJyArICcgICAgLy8gWW91IGNhbiBhd2FpdCBoZXJlXFxuJyArICcgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBNeUFQSS5nZXREYXRhKHNvbWVJZCk7XFxuJyArICcgICAgLy8gLi4uXFxuJyArICcgIH1cXG4nICsgJyAgZmV0Y2hEYXRhKCk7XFxuJyArIFwifSwgW3NvbWVJZF0pOyAvLyBPciBbXSBpZiBlZmZlY3QgZG9lc24ndCBuZWVkIHByb3BzIG9yIHN0YXRlXFxuXFxuXCIgKyAnTGVhcm4gbW9yZSBhYm91dCBkYXRhIGZldGNoaW5nIHdpdGggSG9va3M6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9ob29rcy1kYXRhLWZldGNoaW5nJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJyBZb3UgcmV0dXJuZWQ6ICcgKyBkZXN0cm95O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlcnJvcignJXMgbXVzdCBub3QgcmV0dXJuIGFueXRoaW5nIGJlc2lkZXMgYSBmdW5jdGlvbiwgJyArICd3aGljaCBpcyB1c2VkIGZvciBjbGVhbi11cC4lcycsIGhvb2tOYW1lLCBhZGRlbmR1bSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGVmZmVjdCA9IGVmZmVjdC5uZXh0O1xuICAgIH0gd2hpbGUgKGVmZmVjdCAhPT0gZmlyc3RFZmZlY3QpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVFZmZlY3REdXJhdGlvbnMoZmluaXNoZWRSb290LCBmaW5pc2hlZFdvcmspIHtcbiAge1xuICAgIC8vIE9ubHkgUHJvZmlsZXJzIHdpdGggd29yayBpbiB0aGVpciBzdWJ0cmVlIHdpbGwgaGF2ZSBhbiBVcGRhdGUgZWZmZWN0IHNjaGVkdWxlZC5cbiAgICBpZiAoKGZpbmlzaGVkV29yay5mbGFncyAmIFVwZGF0ZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgICAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBwYXNzaXZlRWZmZWN0RHVyYXRpb24gPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlLnBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgIHZhciBfZmluaXNoZWRXb3JrJG1lbW9pemUgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcyxcbiAgICAgICAgICAgICAgICBpZCA9IF9maW5pc2hlZFdvcmskbWVtb2l6ZS5pZCxcbiAgICAgICAgICAgICAgICBvblBvc3RDb21taXQgPSBfZmluaXNoZWRXb3JrJG1lbW9pemUub25Qb3N0Q29tbWl0OyAvLyBUaGlzIHZhbHVlIHdpbGwgc3RpbGwgcmVmbGVjdCB0aGUgcHJldmlvdXMgY29tbWl0IHBoYXNlLlxuICAgICAgICAgICAgLy8gSXQgZG9lcyBub3QgZ2V0IHJlc2V0IHVudGlsIHRoZSBzdGFydCBvZiB0aGUgbmV4dCBjb21taXQgcGhhc2UuXG5cbiAgICAgICAgICAgIHZhciBjb21taXRUaW1lID0gZ2V0Q29tbWl0VGltZSgpO1xuICAgICAgICAgICAgdmFyIHBoYXNlID0gZmluaXNoZWRXb3JrLmFsdGVybmF0ZSA9PT0gbnVsbCA/ICdtb3VudCcgOiAndXBkYXRlJztcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZiAoaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBwaGFzZSA9ICduZXN0ZWQtdXBkYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uUG9zdENvbW1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBvblBvc3RDb21taXQoaWQsIHBoYXNlLCBwYXNzaXZlRWZmZWN0RHVyYXRpb24sIGNvbW1pdFRpbWUpO1xuICAgICAgICAgICAgfSAvLyBCdWJibGUgdGltZXMgdG8gdGhlIG5leHQgbmVhcmVzdCBhbmNlc3RvciBQcm9maWxlci5cbiAgICAgICAgICAgIC8vIEFmdGVyIHdlIHByb2Nlc3MgdGhhdCBQcm9maWxlciwgd2UnbGwgYnViYmxlIGZ1cnRoZXIgdXAuXG5cblxuICAgICAgICAgICAgdmFyIHBhcmVudEZpYmVyID0gZmluaXNoZWRXb3JrLnJldHVybjtcblxuICAgICAgICAgICAgb3V0ZXI6IHdoaWxlIChwYXJlbnRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgICAgICAgICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgICAgICAgICB2YXIgcm9vdCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICAgICAgICAgIHJvb3QucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IHBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuXG4gICAgICAgICAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRTdGF0ZU5vZGUgPSBwYXJlbnRGaWJlci5zdGF0ZU5vZGU7XG4gICAgICAgICAgICAgICAgICBwYXJlbnRTdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IHBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcGFyZW50RmliZXIgPSBwYXJlbnRGaWJlci5yZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0TGF5b3V0RWZmZWN0T25GaWJlcihmaW5pc2hlZFJvb3QsIGN1cnJlbnQsIGZpbmlzaGVkV29yaywgY29tbWl0dGVkTGFuZXMpIHtcbiAgaWYgKChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncykge1xuICAgIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICggIW9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4pIHtcbiAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgbGF5b3V0IGVmZmVjdHMgaGF2ZSBhbHJlYWR5IGJlZW4gZGVzdHJveWVkIChkdXJpbmcgbXV0YXRpb24gcGhhc2UpLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBkb25lIHRvIHByZXZlbnQgc2libGluZyBjb21wb25lbnQgZWZmZWN0cyBmcm9tIGludGVyZmVyaW5nIHdpdGggZWFjaCBvdGhlcixcbiAgICAgICAgICAgIC8vIGUuZy4gYSBkZXN0cm95IGZ1bmN0aW9uIGluIG9uZSBjb21wb25lbnQgc2hvdWxkIG5ldmVyIG92ZXJyaWRlIGEgcmVmIHNldFxuICAgICAgICAgICAgLy8gYnkgYSBjcmVhdGUgZnVuY3Rpb24gaW4gYW5vdGhlciBjb21wb25lbnQgZHVyaW5nIHRoZSBzYW1lIGNvbW1pdC5cbiAgICAgICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZTtcblxuICAgICAgICAgIGlmIChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGNvdWxkIHVwZGF0ZSBpbnN0YW5jZSBwcm9wcyBhbmQgc3RhdGUgaGVyZSxcbiAgICAgICAgICAgICAgICAvLyBidXQgaW5zdGVhZCB3ZSByZWx5IG9uIHRoZW0gYmVpbmcgc2V0IGR1cmluZyBsYXN0IHJlbmRlci5cbiAgICAgICAgICAgICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgd2hlbiB3ZSBpbXBsZW1lbnQgcmVzdW1pbmcuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcykge1xuICAgICAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBwcm9wcyB0byBtYXRjaCBtZW1vaXplZCBwcm9wcyBiZWZvcmUgJyArICdjb21wb25lbnREaWRNb3VudC4gJyArICdUaGlzIG1pZ2h0IGVpdGhlciBiZSBiZWNhdXNlIG9mIGEgYnVnIGluIFJlYWN0LCBvciBiZWNhdXNlICcgKyAnYSBjb21wb25lbnQgcmVhc3NpZ25zIGl0cyBvd24gYHRoaXMucHJvcHNgLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmluaXNoZWRXb3JrKSB8fCAnaW5zdGFuY2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSAhPT0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgc3RhdGUgdG8gbWF0Y2ggbWVtb2l6ZWQgc3RhdGUgYmVmb3JlICcgKyAnY29tcG9uZW50RGlkTW91bnQuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnN0YXRlYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIGZpbmlzaGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbXBvbmVudERpZE1vdW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBwcmV2UHJvcHMgPSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgPT09IGZpbmlzaGVkV29yay50eXBlID8gY3VycmVudC5tZW1vaXplZFByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhmaW5pc2hlZFdvcmsudHlwZSwgY3VycmVudC5tZW1vaXplZFByb3BzKTtcbiAgICAgICAgICAgICAgICB2YXIgcHJldlN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlOyAvLyBXZSBjb3VsZCB1cGRhdGUgaW5zdGFuY2UgcHJvcHMgYW5kIHN0YXRlIGhlcmUsXG4gICAgICAgICAgICAgICAgLy8gYnV0IGluc3RlYWQgd2UgcmVseSBvbiB0aGVtIGJlaW5nIHNldCBkdXJpbmcgbGFzdCByZW5kZXIuXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGlzIHdoZW4gd2UgaW1wbGVtZW50IHJlc3VtaW5nLlxuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcykge1xuICAgICAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBwcm9wcyB0byBtYXRjaCBtZW1vaXplZCBwcm9wcyBiZWZvcmUgJyArICdjb21wb25lbnREaWRVcGRhdGUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnByb3BzYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2Uuc3RhdGUgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZXJyb3IoJ0V4cGVjdGVkICVzIHN0YXRlIHRvIG1hdGNoIG1lbW9pemVkIHN0YXRlIGJlZm9yZSAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZS4gJyArICdUaGlzIG1pZ2h0IGVpdGhlciBiZSBiZWNhdXNlIG9mIGEgYnVnIGluIFJlYWN0LCBvciBiZWNhdXNlICcgKyAnYSBjb21wb25lbnQgcmVhc3NpZ25zIGl0cyBvd24gYHRoaXMuc3RhdGVgLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmluaXNoZWRXb3JrKSB8fCAnaW5zdGFuY2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUsIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbFNuYXBzaG90QmVmb3JlVXBkYXRlKTtcbiAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMsIHByZXZTdGF0ZSwgaW5zdGFuY2UuX19yZWFjdEludGVybmFsU25hcHNob3RCZWZvcmVVcGRhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8gVE9ETzogSSB0aGluayB0aGlzIGlzIG5vdyBhbHdheXMgbm9uLW51bGwgYnkgdGhlIHRpbWUgaXQgcmVhY2hlcyB0aGVcbiAgICAgICAgICAvLyBjb21taXQgcGhhc2UuIENvbnNpZGVyIHJlbW92aW5nIHRoZSB0eXBlIGNoZWNrLlxuXG5cbiAgICAgICAgICB2YXIgdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICBpZiAodXBkYXRlUXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgcHJvcHMgdG8gbWF0Y2ggbWVtb2l6ZWQgcHJvcHMgYmVmb3JlICcgKyAncHJvY2Vzc2luZyB0aGUgdXBkYXRlIHF1ZXVlLiAnICsgJ1RoaXMgbWlnaHQgZWl0aGVyIGJlIGJlY2F1c2Ugb2YgYSBidWcgaW4gUmVhY3QsIG9yIGJlY2F1c2UgJyArICdhIGNvbXBvbmVudCByZWFzc2lnbnMgaXRzIG93biBgdGhpcy5wcm9wc2AuICcgKyAnUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspIHx8ICdpbnN0YW5jZScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSAhPT0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBzdGF0ZSB0byBtYXRjaCBtZW1vaXplZCBzdGF0ZSBiZWZvcmUgJyArICdwcm9jZXNzaW5nIHRoZSB1cGRhdGUgcXVldWUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnN0YXRlYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IC8vIFdlIGNvdWxkIHVwZGF0ZSBpbnN0YW5jZSBwcm9wcyBhbmQgc3RhdGUgaGVyZSxcbiAgICAgICAgICAgIC8vIGJ1dCBpbnN0ZWFkIHdlIHJlbHkgb24gdGhlbSBiZWluZyBzZXQgZHVyaW5nIGxhc3QgcmVuZGVyLlxuICAgICAgICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGlzIHdoZW4gd2UgaW1wbGVtZW50IHJlc3VtaW5nLlxuXG5cbiAgICAgICAgICAgIGNvbW1pdFVwZGF0ZVF1ZXVlKGZpbmlzaGVkV29yaywgdXBkYXRlUXVldWUsIGluc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RSb290OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVE9ETzogSSB0aGluayB0aGlzIGlzIG5vdyBhbHdheXMgbm9uLW51bGwgYnkgdGhlIHRpbWUgaXQgcmVhY2hlcyB0aGVcbiAgICAgICAgICAvLyBjb21taXQgcGhhc2UuIENvbnNpZGVyIHJlbW92aW5nIHRoZSB0eXBlIGNoZWNrLlxuICAgICAgICAgIHZhciBfdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICBpZiAoX3VwZGF0ZVF1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgX2luc3RhbmNlID0gbnVsbDtcblxuICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBzd2l0Y2ggKGZpbmlzaGVkV29yay5jaGlsZC50YWcpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgICAgICAgICAgICBfaW5zdGFuY2UgPSBnZXRQdWJsaWNJbnN0YW5jZShmaW5pc2hlZFdvcmsuY2hpbGQuc3RhdGVOb2RlKTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgICAgICAgICAgIF9pbnN0YW5jZSA9IGZpbmlzaGVkV29yay5jaGlsZC5zdGF0ZU5vZGU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb21taXRVcGRhdGVRdWV1ZShmaW5pc2hlZFdvcmssIF91cGRhdGVRdWV1ZSwgX2luc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgX2luc3RhbmNlMiA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7IC8vIFJlbmRlcmVycyBtYXkgc2NoZWR1bGUgd29yayB0byBiZSBkb25lIGFmdGVyIGhvc3QgY29tcG9uZW50cyBhcmUgbW91bnRlZFxuICAgICAgICAgIC8vIChlZyBET00gcmVuZGVyZXIgbWF5IHNjaGVkdWxlIGF1dG8tZm9jdXMgZm9yIGlucHV0cyBhbmQgZm9ybSBjb250cm9scykuXG4gICAgICAgICAgLy8gVGhlc2UgZWZmZWN0cyBzaG91bGQgb25seSBiZSBjb21taXR0ZWQgd2hlbiBjb21wb25lbnRzIGFyZSBmaXJzdCBtb3VudGVkLFxuICAgICAgICAgIC8vIGFrYSB3aGVuIHRoZXJlIGlzIG5vIGN1cnJlbnQvYWx0ZXJuYXRlLlxuXG4gICAgICAgICAgaWYgKGN1cnJlbnQgPT09IG51bGwgJiYgZmluaXNoZWRXb3JrLmZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGZpbmlzaGVkV29yay50eXBlO1xuICAgICAgICAgICAgdmFyIHByb3BzID0gZmluaXNoZWRXb3JrLm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgICBjb21taXRNb3VudChfaW5zdGFuY2UyLCB0eXBlLCBwcm9wcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgICAge1xuICAgICAgICAgIC8vIFdlIGhhdmUgbm8gbGlmZS1jeWNsZXMgYXNzb2NpYXRlZCB3aXRoIHRleHQuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgICB7XG4gICAgICAgICAgLy8gV2UgaGF2ZSBubyBsaWZlLWN5Y2xlcyBhc3NvY2lhdGVkIHdpdGggcG9ydGFscy5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgICB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIF9maW5pc2hlZFdvcmskbWVtb2l6ZTIgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcyxcbiAgICAgICAgICAgICAgICBvbkNvbW1pdCA9IF9maW5pc2hlZFdvcmskbWVtb2l6ZTIub25Db21taXQsXG4gICAgICAgICAgICAgICAgb25SZW5kZXIgPSBfZmluaXNoZWRXb3JrJG1lbW9pemUyLm9uUmVuZGVyO1xuICAgICAgICAgICAgdmFyIGVmZmVjdER1cmF0aW9uID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgIHZhciBjb21taXRUaW1lID0gZ2V0Q29tbWl0VGltZSgpO1xuICAgICAgICAgICAgdmFyIHBoYXNlID0gY3VycmVudCA9PT0gbnVsbCA/ICdtb3VudCcgOiAndXBkYXRlJztcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZiAoaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBwaGFzZSA9ICduZXN0ZWQtdXBkYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uUmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIG9uUmVuZGVyKGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzLmlkLCBwaGFzZSwgZmluaXNoZWRXb3JrLmFjdHVhbER1cmF0aW9uLCBmaW5pc2hlZFdvcmsudHJlZUJhc2VEdXJhdGlvbiwgZmluaXNoZWRXb3JrLmFjdHVhbFN0YXJ0VGltZSwgY29tbWl0VGltZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbkNvbW1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIG9uQ29tbWl0KGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzLmlkLCBwaGFzZSwgZWZmZWN0RHVyYXRpb24sIGNvbW1pdFRpbWUpO1xuICAgICAgICAgICAgICB9IC8vIFNjaGVkdWxlIGEgcGFzc2l2ZSBlZmZlY3QgZm9yIHRoaXMgUHJvZmlsZXIgdG8gY2FsbCBvblBvc3RDb21taXQgaG9va3MuXG4gICAgICAgICAgICAgIC8vIFRoaXMgZWZmZWN0IHNob3VsZCBiZSBzY2hlZHVsZWQgZXZlbiBpZiB0aGVyZSBpcyBubyBvblBvc3RDb21taXQgY2FsbGJhY2sgZm9yIHRoaXMgUHJvZmlsZXIsXG4gICAgICAgICAgICAgIC8vIGJlY2F1c2UgdGhlIGVmZmVjdCBpcyBhbHNvIHdoZXJlIHRpbWVzIGJ1YmJsZSB0byBwYXJlbnQgUHJvZmlsZXJzLlxuXG5cbiAgICAgICAgICAgICAgZW5xdWV1ZVBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3QoZmluaXNoZWRXb3JrKTsgLy8gUHJvcGFnYXRlIGxheW91dCBlZmZlY3QgZHVyYXRpb25zIHRvIHRoZSBuZXh0IG5lYXJlc3QgUHJvZmlsZXIgYW5jZXN0b3IuXG4gICAgICAgICAgICAgIC8vIERvIG5vdCByZXNldCB0aGVzZSB2YWx1ZXMgdW50aWwgdGhlIG5leHQgcmVuZGVyIHNvIERldlRvb2xzIGhhcyBhIGNoYW5jZSB0byByZWFkIHRoZW0gZmlyc3QuXG5cbiAgICAgICAgICAgICAgdmFyIHBhcmVudEZpYmVyID0gZmluaXNoZWRXb3JrLnJldHVybjtcblxuICAgICAgICAgICAgICBvdXRlcjogd2hpbGUgKHBhcmVudEZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChwYXJlbnRGaWJlci50YWcpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgICAgICAgICAgIHZhciByb290ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuICAgICAgICAgICAgICAgICAgICByb290LmVmZmVjdER1cmF0aW9uICs9IGVmZmVjdER1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcblxuICAgICAgICAgICAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudFN0YXRlTm9kZSA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50U3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uICs9IGVmZmVjdER1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXJlbnRGaWJlciA9IHBhcmVudEZpYmVyLnJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBjb21taXRTdXNwZW5zZUh5ZHJhdGlvbkNhbGxiYWNrcyhmaW5pc2hlZFJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgIGNhc2UgU2NvcGVDb21wb25lbnQ6XG4gICAgICBjYXNlIE9mZnNjcmVlbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHVuaXQgb2Ygd29yayB0YWcgc2hvdWxkIG5vdCBoYXZlIHNpZGUtZWZmZWN0cy4gVGhpcyBlcnJvciBpcyAnICsgJ2xpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmICggIW9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4pIHtcbiAgICB7XG4gICAgICBpZiAoZmluaXNoZWRXb3JrLmZsYWdzICYgUmVmKSB7XG4gICAgICAgIGNvbW1pdEF0dGFjaFJlZihmaW5pc2hlZFdvcmspO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWFwcGVhckxheW91dEVmZmVjdHNPbkZpYmVyKG5vZGUpIHtcbiAgLy8gVHVybiBvbiBsYXlvdXQgZWZmZWN0cyBpbiBhIHRyZWUgdGhhdCBwcmV2aW91c2x5IGRpc2FwcGVhcmVkLlxuICAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBmbGFncyAmIExheW91dFN0YXRpY1xuICBzd2l0Y2ggKG5vZGUudGFnKSB7XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIG5vZGUubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24obm9kZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gbm9kZS5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHNhZmVseUNhbGxDb21wb25lbnREaWRNb3VudChub2RlLCBub2RlLnJldHVybiwgaW5zdGFuY2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2FmZWx5QXR0YWNoUmVmKG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHNhZmVseUF0dGFjaFJlZihub2RlLCBub2RlLnJldHVybik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGhpZGVPclVuaGlkZUFsbENoaWxkcmVuKGZpbmlzaGVkV29yaywgaXNIaWRkZW4pIHtcbiAgLy8gT25seSBoaWRlIG9yIHVuaGlkZSB0aGUgdG9wLW1vc3QgaG9zdCBub2Rlcy5cbiAgdmFyIGhvc3RTdWJ0cmVlUm9vdCA9IG51bGw7XG5cbiAge1xuICAgIC8vIFdlIG9ubHkgaGF2ZSB0aGUgdG9wIEZpYmVyIHRoYXQgd2FzIGluc2VydGVkIGJ1dCB3ZSBuZWVkIHRvIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgdmFyIG5vZGUgPSBmaW5pc2hlZFdvcms7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50KSB7XG4gICAgICAgIGlmIChob3N0U3VidHJlZVJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICBob3N0U3VidHJlZVJvb3QgPSBub2RlO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IG5vZGUuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICBpZiAoaXNIaWRkZW4pIHtcbiAgICAgICAgICAgICAgaGlkZUluc3RhbmNlKGluc3RhbmNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHVuaGlkZUluc3RhbmNlKG5vZGUuc3RhdGVOb2RlLCBub2RlLm1lbW9pemVkUHJvcHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IEhvc3RUZXh0KSB7XG4gICAgICAgIGlmIChob3N0U3VidHJlZVJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIF9pbnN0YW5jZTMgPSBub2RlLnN0YXRlTm9kZTtcblxuICAgICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICAgIGhpZGVUZXh0SW5zdGFuY2UoX2luc3RhbmNlMyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB1bmhpZGVUZXh0SW5zdGFuY2UoX2luc3RhbmNlMywgbm9kZS5tZW1vaXplZFByb3BzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKChub2RlLnRhZyA9PT0gT2Zmc2NyZWVuQ29tcG9uZW50IHx8IG5vZGUudGFnID09PSBMZWdhY3lIaWRkZW5Db21wb25lbnQpICYmIG5vZGUubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCAmJiBub2RlICE9PSBmaW5pc2hlZFdvcmspIDsgZWxzZSBpZiAobm9kZS5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICBub2RlLmNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUgPT09IGZpbmlzaGVkV29yaykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSBmaW5pc2hlZFdvcmspIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaG9zdFN1YnRyZWVSb290ID09PSBub2RlKSB7XG4gICAgICAgICAgaG9zdFN1YnRyZWVSb290ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGhvc3RTdWJ0cmVlUm9vdCA9PT0gbm9kZSkge1xuICAgICAgICBob3N0U3VidHJlZVJvb3QgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRBdHRhY2hSZWYoZmluaXNoZWRXb3JrKSB7XG4gIHZhciByZWYgPSBmaW5pc2hlZFdvcmsucmVmO1xuXG4gIGlmIChyZWYgIT09IG51bGwpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuICAgIHZhciBpbnN0YW5jZVRvVXNlO1xuXG4gICAgc3dpdGNoIChmaW5pc2hlZFdvcmsudGFnKSB7XG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIGluc3RhbmNlVG9Vc2UgPSBnZXRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpbnN0YW5jZVRvVXNlID0gaW5zdGFuY2U7XG4gICAgfSAvLyBNb3ZlZCBvdXRzaWRlIHRvIGVuc3VyZSBEQ0Ugd29ya3Mgd2l0aCB0aGlzIGZsYWdcblxuICAgIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgcmV0VmFsO1xuXG4gICAgICBpZiAoIGZpbmlzaGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgcmV0VmFsID0gcmVmKGluc3RhbmNlVG9Vc2UpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldFZhbCA9IHJlZihpbnN0YW5jZVRvVXNlKTtcbiAgICAgIH1cblxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHJldFZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGVycm9yKCdVbmV4cGVjdGVkIHJldHVybiB2YWx1ZSBmcm9tIGEgY2FsbGJhY2sgcmVmIGluICVzLiAnICsgJ0EgY2FsbGJhY2sgcmVmIHNob3VsZCBub3QgcmV0dXJuIGEgZnVuY3Rpb24uJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIGlmICghcmVmLmhhc093blByb3BlcnR5KCdjdXJyZW50JykpIHtcbiAgICAgICAgICBlcnJvcignVW5leHBlY3RlZCByZWYgb2JqZWN0IHByb3ZpZGVkIGZvciAlcy4gJyArICdVc2UgZWl0aGVyIGEgcmVmLXNldHRlciBmdW5jdGlvbiBvciBSZWFjdC5jcmVhdGVSZWYoKS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlZi5jdXJyZW50ID0gaW5zdGFuY2VUb1VzZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZGV0YWNoRmliZXJNdXRhdGlvbihmaWJlcikge1xuICAvLyBDdXQgb2ZmIHRoZSByZXR1cm4gcG9pbnRlciB0byBkaXNjb25uZWN0IGl0IGZyb20gdGhlIHRyZWUuXG4gIC8vIFRoaXMgZW5hYmxlcyB1cyB0byBkZXRlY3QgYW5kIHdhcm4gYWdhaW5zdCBzdGF0ZSB1cGRhdGVzIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuXG4gIC8vIEl0IGFsc28gcHJldmVudHMgZXZlbnRzIGZyb20gYnViYmxpbmcgZnJvbSB3aXRoaW4gZGlzY29ubmVjdGVkIGNvbXBvbmVudHMuXG4gIC8vXG4gIC8vIElkZWFsbHksIHdlIHNob3VsZCBhbHNvIGNsZWFyIHRoZSBjaGlsZCBwb2ludGVyIG9mIHRoZSBwYXJlbnQgYWx0ZXJuYXRlIHRvIGxldCB0aGlzXG4gIC8vIGdldCBHQzplZCBidXQgd2UgZG9uJ3Qga25vdyB3aGljaCBmb3Igc3VyZSB3aGljaCBwYXJlbnQgaXMgdGhlIGN1cnJlbnRcbiAgLy8gb25lIHNvIHdlJ2xsIHNldHRsZSBmb3IgR0M6aW5nIHRoZSBzdWJ0cmVlIG9mIHRoaXMgY2hpbGQuXG4gIC8vIFRoaXMgY2hpbGQgaXRzZWxmIHdpbGwgYmUgR0M6ZWQgd2hlbiB0aGUgcGFyZW50IHVwZGF0ZXMgdGhlIG5leHQgdGltZS5cbiAgLy9cbiAgLy8gTm90ZSB0aGF0IHdlIGNhbid0IGNsZWFyIGNoaWxkIG9yIHNpYmxpbmcgcG9pbnRlcnMgeWV0LlxuICAvLyBUaGV5J3JlIG5lZWRlZCBmb3IgcGFzc2l2ZSBlZmZlY3RzIGFuZCBmb3IgZmluZERPTU5vZGUuXG4gIC8vIFdlIGRlZmVyIHRob3NlIGZpZWxkcywgYW5kIGFsbCBvdGhlciBjbGVhbnVwLCB0byB0aGUgcGFzc2l2ZSBwaGFzZSAoc2VlIGRldGFjaEZpYmVyQWZ0ZXJFZmZlY3RzKS5cbiAgLy9cbiAgLy8gRG9uJ3QgcmVzZXQgdGhlIGFsdGVybmF0ZSB5ZXQsIGVpdGhlci4gV2UgbmVlZCB0aGF0IHNvIHdlIGNhbiBkZXRhY2ggdGhlXG4gIC8vIGFsdGVybmF0ZSdzIGZpZWxkcyBpbiB0aGUgcGFzc2l2ZSBwaGFzZS4gQ2xlYXJpbmcgdGhlIHJldHVybiBwb2ludGVyIGlzXG4gIC8vIHN1ZmZpY2llbnQgZm9yIGZpbmRET01Ob2RlIHNlbWFudGljcy5cbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLnJldHVybiA9IG51bGw7XG4gIH1cblxuICBmaWJlci5yZXR1cm4gPSBudWxsO1xufVxuXG5mdW5jdGlvbiBkZXRhY2hGaWJlckFmdGVyRWZmZWN0cyhmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICBmaWJlci5hbHRlcm5hdGUgPSBudWxsO1xuICAgIGRldGFjaEZpYmVyQWZ0ZXJFZmZlY3RzKGFsdGVybmF0ZSk7XG4gIH0gLy8gTm90ZTogRGVmZW5zaXZlbHkgdXNpbmcgbmVnYXRpb24gaW5zdGVhZCBvZiA8IGluIGNhc2VcbiAgLy8gYGRlbGV0ZWRUcmVlQ2xlYW5VcExldmVsYCBpcyB1bmRlZmluZWQuXG5cblxuICB7XG4gICAgLy8gQ2xlYXIgY3ljbGljYWwgRmliZXIgZmllbGRzLiBUaGlzIGxldmVsIGFsb25lIGlzIGRlc2lnbmVkIHRvIHJvdWdobHlcbiAgICAvLyBhcHByb3hpbWF0ZSB0aGUgcGxhbm5lZCBGaWJlciByZWZhY3Rvci4gSW4gdGhhdCB3b3JsZCwgYHNldFN0YXRlYCB3aWxsIGJlXG4gICAgLy8gYm91bmQgdG8gYSBzcGVjaWFsIFwiaW5zdGFuY2VcIiBvYmplY3QgaW5zdGVhZCBvZiBhIEZpYmVyLiBUaGUgSW5zdGFuY2VcbiAgICAvLyBvYmplY3Qgd2lsbCBub3QgaGF2ZSBhbnkgb2YgdGhlc2UgZmllbGRzLiBJdCB3aWxsIG9ubHkgYmUgY29ubmVjdGVkIHRvXG4gICAgLy8gdGhlIGZpYmVyIHRyZWUgdmlhIGEgc2luZ2xlIGxpbmsgYXQgdGhlIHJvb3QuIFNvIGlmIHRoaXMgbGV2ZWwgYWxvbmUgaXNcbiAgICAvLyBzdWZmaWNpZW50IHRvIGZpeCBtZW1vcnkgaXNzdWVzLCB0aGF0IGJvZGVzIHdlbGwgZm9yIG91ciBwbGFucy5cbiAgICBmaWJlci5jaGlsZCA9IG51bGw7XG4gICAgZmliZXIuZGVsZXRpb25zID0gbnVsbDtcbiAgICBmaWJlci5zaWJsaW5nID0gbnVsbDsgLy8gVGhlIGBzdGF0ZU5vZGVgIGlzIGN5Y2xpY2FsIGJlY2F1c2Ugb24gaG9zdCBub2RlcyBpdCBwb2ludHMgdG8gdGhlIGhvc3RcbiAgICAvLyB0cmVlLCB3aGljaCBoYXMgaXRzIG93biBwb2ludGVycyB0byBjaGlsZHJlbiwgcGFyZW50cywgYW5kIHNpYmxpbmdzLlxuICAgIC8vIFRoZSBvdGhlciBob3N0IG5vZGVzIGFsc28gcG9pbnQgYmFjayB0byBmaWJlcnMsIHNvIHdlIHNob3VsZCBkZXRhY2ggdGhhdFxuICAgIC8vIG9uZSwgdG9vLlxuXG4gICAgaWYgKGZpYmVyLnRhZyA9PT0gSG9zdENvbXBvbmVudCkge1xuICAgICAgdmFyIGhvc3RJbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgaWYgKGhvc3RJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICBkZXRhY2hEZWxldGVkSW5zdGFuY2UoaG9zdEluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaWJlci5zdGF0ZU5vZGUgPSBudWxsOyAvLyBJJ20gaW50ZW50aW9uYWxseSBub3QgY2xlYXJpbmcgdGhlIGByZXR1cm5gIGZpZWxkIGluIHRoaXMgbGV2ZWwuIFdlXG4gICAgLy8gYWxyZWFkeSBkaXNjb25uZWN0IHRoZSBgcmV0dXJuYCBwb2ludGVyIGF0IHRoZSByb290IG9mIHRoZSBkZWxldGVkXG4gICAgLy8gc3VidHJlZSAoaW4gYGRldGFjaEZpYmVyTXV0YXRpb25gKS4gQmVzaWRlcywgYHJldHVybmAgYnkgaXRzZWxmIGlzIG5vdFxuICAgIC8vIGN5Y2xpY2FsIFx1MjAxNCBpdCdzIG9ubHkgY3ljbGljYWwgd2hlbiBjb21iaW5lZCB3aXRoIGBjaGlsZGAsIGBzaWJsaW5nYCwgYW5kXG4gICAgLy8gYGFsdGVybmF0ZWAuIEJ1dCB3ZSdsbCBjbGVhciBpdCBpbiB0aGUgbmV4dCBsZXZlbCBhbnl3YXksIGp1c3QgaW4gY2FzZS5cblxuICAgIHtcbiAgICAgIGZpYmVyLl9kZWJ1Z093bmVyID0gbnVsbDtcbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBUaGVvcmV0aWNhbGx5LCBub3RoaW5nIGluIGhlcmUgc2hvdWxkIGJlIG5lY2Vzc2FyeSwgYmVjYXVzZSB3ZSBhbHJlYWR5XG4gICAgICAvLyBkaXNjb25uZWN0ZWQgdGhlIGZpYmVyIGZyb20gdGhlIHRyZWUuIFNvIGV2ZW4gaWYgc29tZXRoaW5nIGxlYWtzIHRoaXNcbiAgICAgIC8vIHBhcnRpY3VsYXIgZmliZXIsIGl0IHdvbid0IGxlYWsgYW55dGhpbmcgZWxzZVxuICAgICAgLy9cbiAgICAgIC8vIFRoZSBwdXJwb3NlIG9mIHRoaXMgYnJhbmNoIGlzIHRvIGJlIHN1cGVyIGFnZ3Jlc3NpdmUgc28gd2UgY2FuIG1lYXN1cmVcbiAgICAgIC8vIGlmIHRoZXJlJ3MgYW55IGRpZmZlcmVuY2UgaW4gbWVtb3J5IGltcGFjdC4gSWYgdGhlcmUgaXMsIHRoYXQgY291bGRcbiAgICAgIC8vIGluZGljYXRlIGEgUmVhY3QgbGVhayB3ZSBkb24ndCBrbm93IGFib3V0LlxuICAgICAgZmliZXIucmV0dXJuID0gbnVsbDtcbiAgICAgIGZpYmVyLmRlcGVuZGVuY2llcyA9IG51bGw7XG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gbnVsbDtcbiAgICAgIGZpYmVyLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgZmliZXIucGVuZGluZ1Byb3BzID0gbnVsbDtcbiAgICAgIGZpYmVyLnN0YXRlTm9kZSA9IG51bGw7IC8vIFRPRE86IE1vdmUgdG8gYGNvbW1pdFBhc3NpdmVVbm1vdW50SW5zaWRlRGVsZXRlZFRyZWVPbkZpYmVyYCBpbnN0ZWFkLlxuXG4gICAgICBmaWJlci51cGRhdGVRdWV1ZSA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEhvc3RQYXJlbnRGaWJlcihmaWJlcikge1xuICB2YXIgcGFyZW50ID0gZmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICBpZiAoaXNIb3N0UGFyZW50KHBhcmVudCkpIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuXG4gICAgcGFyZW50ID0gcGFyZW50LnJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gZmluZCBhIGhvc3QgcGFyZW50LiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgJyArICdpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG59XG5cbmZ1bmN0aW9uIGlzSG9zdFBhcmVudChmaWJlcikge1xuICByZXR1cm4gZmliZXIudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IGZpYmVyLnRhZyA9PT0gSG9zdFJvb3QgfHwgZmliZXIudGFnID09PSBIb3N0UG9ydGFsO1xufVxuXG5mdW5jdGlvbiBnZXRIb3N0U2libGluZyhmaWJlcikge1xuICAvLyBXZSdyZSBnb2luZyB0byBzZWFyY2ggZm9yd2FyZCBpbnRvIHRoZSB0cmVlIHVudGlsIHdlIGZpbmQgYSBzaWJsaW5nIGhvc3RcbiAgLy8gbm9kZS4gVW5mb3J0dW5hdGVseSwgaWYgbXVsdGlwbGUgaW5zZXJ0aW9ucyBhcmUgZG9uZSBpbiBhIHJvdyB3ZSBoYXZlIHRvXG4gIC8vIHNlYXJjaCBwYXN0IHRoZW0uIFRoaXMgbGVhZHMgdG8gZXhwb25lbnRpYWwgc2VhcmNoIGZvciB0aGUgbmV4dCBzaWJsaW5nLlxuICAvLyBUT0RPOiBGaW5kIGEgbW9yZSBlZmZpY2llbnQgd2F5IHRvIGRvIHRoaXMuXG4gIHZhciBub2RlID0gZmliZXI7XG5cbiAgc2libGluZ3M6IHdoaWxlICh0cnVlKSB7XG4gICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgYW55dGhpbmcsIGxldCdzIHRyeSB0aGUgbmV4dCBzaWJsaW5nLlxuICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBpc0hvc3RQYXJlbnQobm9kZS5yZXR1cm4pKSB7XG4gICAgICAgIC8vIElmIHdlIHBvcCBvdXQgb2YgdGhlIHJvb3Qgb3IgaGl0IHRoZSBwYXJlbnQgdGhlIGZpYmVyIHdlIGFyZSB0aGVcbiAgICAgICAgLy8gbGFzdCBzaWJsaW5nLlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuXG4gICAgd2hpbGUgKG5vZGUudGFnICE9PSBIb3N0Q29tcG9uZW50ICYmIG5vZGUudGFnICE9PSBIb3N0VGV4dCAmJiBub2RlLnRhZyAhPT0gRGVoeWRyYXRlZEZyYWdtZW50KSB7XG4gICAgICAvLyBJZiBpdCBpcyBub3QgaG9zdCBub2RlIGFuZCwgd2UgbWlnaHQgaGF2ZSBhIGhvc3Qgbm9kZSBpbnNpZGUgaXQuXG4gICAgICAvLyBUcnkgdG8gc2VhcmNoIGRvd24gdW50aWwgd2UgZmluZCBvbmUuXG4gICAgICBpZiAobm9kZS5mbGFncyAmIFBsYWNlbWVudCkge1xuICAgICAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGEgY2hpbGQsIHRyeSB0aGUgc2libGluZ3MgaW5zdGVhZC5cbiAgICAgICAgY29udGludWUgc2libGluZ3M7XG4gICAgICB9IC8vIElmIHdlIGRvbid0IGhhdmUgYSBjaGlsZCwgdHJ5IHRoZSBzaWJsaW5ncyBpbnN0ZWFkLlxuICAgICAgLy8gV2UgYWxzbyBza2lwIHBvcnRhbHMgYmVjYXVzZSB0aGV5IGFyZSBub3QgcGFydCBvZiB0aGlzIGhvc3QgdHJlZS5cblxuXG4gICAgICBpZiAobm9kZS5jaGlsZCA9PT0gbnVsbCB8fCBub2RlLnRhZyA9PT0gSG9zdFBvcnRhbCkge1xuICAgICAgICBjb250aW51ZSBzaWJsaW5ncztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICB9XG4gICAgfSAvLyBDaGVjayBpZiB0aGlzIGhvc3Qgbm9kZSBpcyBzdGFibGUgb3IgYWJvdXQgdG8gYmUgcGxhY2VkLlxuXG5cbiAgICBpZiAoIShub2RlLmZsYWdzICYgUGxhY2VtZW50KSkge1xuICAgICAgLy8gRm91bmQgaXQhXG4gICAgICByZXR1cm4gbm9kZS5zdGF0ZU5vZGU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBsYWNlbWVudChmaW5pc2hlZFdvcmspIHtcblxuXG4gIHZhciBwYXJlbnRGaWJlciA9IGdldEhvc3RQYXJlbnRGaWJlcihmaW5pc2hlZFdvcmspOyAvLyBOb3RlOiB0aGVzZSB0d28gdmFyaWFibGVzICptdXN0KiBhbHdheXMgYmUgdXBkYXRlZCB0b2dldGhlci5cblxuICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgICBpZiAocGFyZW50RmliZXIuZmxhZ3MgJiBDb250ZW50UmVzZXQpIHtcbiAgICAgICAgICAvLyBSZXNldCB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBwYXJlbnQgYmVmb3JlIGRvaW5nIGFueSBpbnNlcnRpb25zXG4gICAgICAgICAgcmVzZXRUZXh0Q29udGVudChwYXJlbnQpOyAvLyBDbGVhciBDb250ZW50UmVzZXQgZnJvbSB0aGUgZWZmZWN0IHRhZ1xuXG4gICAgICAgICAgcGFyZW50RmliZXIuZmxhZ3MgJj0gfkNvbnRlbnRSZXNldDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBiZWZvcmUgPSBnZXRIb3N0U2libGluZyhmaW5pc2hlZFdvcmspOyAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBpbnNlcnRlZCBidXQgd2UgbmVlZCB0byByZWN1cnNlIGRvd24gaXRzXG4gICAgICAgIC8vIGNoaWxkcmVuIHRvIGZpbmQgYWxsIHRoZSB0ZXJtaW5hbCBub2Rlcy5cblxuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGUoZmluaXNoZWRXb3JrLCBiZWZvcmUsIHBhcmVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICB7XG4gICAgICAgIHZhciBfcGFyZW50ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG5cbiAgICAgICAgdmFyIF9iZWZvcmUgPSBnZXRIb3N0U2libGluZyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGluc2VydE9yQXBwZW5kUGxhY2VtZW50Tm9kZUludG9Db250YWluZXIoZmluaXNoZWRXb3JrLCBfYmVmb3JlLCBfcGFyZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lLW5vLWZhbGx0aHJvdWdoXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhvc3QgcGFyZW50IGZpYmVyLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgJyArICdpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlSW50b0NvbnRhaW5lcihub2RlLCBiZWZvcmUsIHBhcmVudCkge1xuICB2YXIgdGFnID0gbm9kZS50YWc7XG4gIHZhciBpc0hvc3QgPSB0YWcgPT09IEhvc3RDb21wb25lbnQgfHwgdGFnID09PSBIb3N0VGV4dDtcblxuICBpZiAoaXNIb3N0KSB7XG4gICAgdmFyIHN0YXRlTm9kZSA9IG5vZGUuc3RhdGVOb2RlO1xuXG4gICAgaWYgKGJlZm9yZSkge1xuICAgICAgaW5zZXJ0SW5Db250YWluZXJCZWZvcmUocGFyZW50LCBzdGF0ZU5vZGUsIGJlZm9yZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZENoaWxkVG9Db250YWluZXIocGFyZW50LCBzdGF0ZU5vZGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0YWcgPT09IEhvc3RQb3J0YWwpIDsgZWxzZSB7XG4gICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICAgIGlmIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlSW50b0NvbnRhaW5lcihjaGlsZCwgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgdmFyIHNpYmxpbmcgPSBjaGlsZC5zaWJsaW5nO1xuXG4gICAgICB3aGlsZSAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGVJbnRvQ29udGFpbmVyKHNpYmxpbmcsIGJlZm9yZSwgcGFyZW50KTtcbiAgICAgICAgc2libGluZyA9IHNpYmxpbmcuc2libGluZztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlKG5vZGUsIGJlZm9yZSwgcGFyZW50KSB7XG4gIHZhciB0YWcgPSBub2RlLnRhZztcbiAgdmFyIGlzSG9zdCA9IHRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCB0YWcgPT09IEhvc3RUZXh0O1xuXG4gIGlmIChpc0hvc3QpIHtcbiAgICB2YXIgc3RhdGVOb2RlID0gbm9kZS5zdGF0ZU5vZGU7XG5cbiAgICBpZiAoYmVmb3JlKSB7XG4gICAgICBpbnNlcnRCZWZvcmUocGFyZW50LCBzdGF0ZU5vZGUsIGJlZm9yZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZENoaWxkKHBhcmVudCwgc3RhdGVOb2RlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGFnID09PSBIb3N0UG9ydGFsKSA7IGVsc2Uge1xuICAgIHZhciBjaGlsZCA9IG5vZGUuY2hpbGQ7XG5cbiAgICBpZiAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGluc2VydE9yQXBwZW5kUGxhY2VtZW50Tm9kZShjaGlsZCwgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgdmFyIHNpYmxpbmcgPSBjaGlsZC5zaWJsaW5nO1xuXG4gICAgICB3aGlsZSAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGUoc2libGluZywgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgICBzaWJsaW5nID0gc2libGluZy5zaWJsaW5nO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSAvLyBUaGVzZSBhcmUgdHJhY2tlZCBvbiB0aGUgc3RhY2sgYXMgd2UgcmVjdXJzaXZlbHkgdHJhdmVyc2UgYVxuLy8gZGVsZXRlZCBzdWJ0cmVlLlxuLy8gVE9ETzogVXBkYXRlIHRoZXNlIGR1cmluZyB0aGUgd2hvbGUgbXV0YXRpb24gcGhhc2UsIG5vdCBqdXN0IGR1cmluZ1xuLy8gYSBkZWxldGlvbi5cblxuXG52YXIgaG9zdFBhcmVudCA9IG51bGw7XG52YXIgaG9zdFBhcmVudElzQ29udGFpbmVyID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGNvbW1pdERlbGV0aW9uRWZmZWN0cyhyb290LCByZXR1cm5GaWJlciwgZGVsZXRlZEZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBkZWxldGVkIGJ1dCB3ZSBuZWVkIHRvIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgLy8gUmVjdXJzaXZlbHkgZGVsZXRlIGFsbCBob3N0IG5vZGVzIGZyb20gdGhlIHBhcmVudCwgZGV0YWNoIHJlZnMsIGNsZWFuXG4gICAgLy8gdXAgbW91bnRlZCBsYXlvdXQgZWZmZWN0cywgYW5kIGNhbGwgY29tcG9uZW50V2lsbFVubW91bnQuXG4gICAgLy8gV2Ugb25seSBuZWVkIHRvIHJlbW92ZSB0aGUgdG9wbW9zdCBob3N0IGNoaWxkIGluIGVhY2ggYnJhbmNoLiBCdXQgdGhlbiB3ZVxuICAgIC8vIHN0aWxsIG5lZWQgdG8ga2VlcCB0cmF2ZXJzaW5nIHRvIHVubW91bnQgZWZmZWN0cywgcmVmcywgYW5kIGNXVS4gVE9ETzogV2VcbiAgICAvLyBjb3VsZCBzcGxpdCB0aGlzIGludG8gdHdvIHNlcGFyYXRlIHRyYXZlcnNhbHMgZnVuY3Rpb25zLCB3aGVyZSB0aGUgc2Vjb25kXG4gICAgLy8gb25lIGRvZXNuJ3QgaW5jbHVkZSBhbnkgcmVtb3ZlQ2hpbGQgbG9naWMuIFRoaXMgaXMgbWF5YmUgdGhlIHNhbWVcbiAgICAvLyBmdW5jdGlvbiBhcyBcImRpc2FwcGVhckxheW91dEVmZmVjdHNcIiAob3Igd2hhdGV2ZXIgdGhhdCB0dXJucyBpbnRvIGFmdGVyXG4gICAgLy8gdGhlIGxheW91dCBwaGFzZSBpcyByZWZhY3RvcmVkIHRvIHVzZSByZWN1cnNpb24pLlxuICAgIC8vIEJlZm9yZSBzdGFydGluZywgZmluZCB0aGUgbmVhcmVzdCBob3N0IHBhcmVudCBvbiB0aGUgc3RhY2sgc28gd2Uga25vd1xuICAgIC8vIHdoaWNoIGluc3RhbmNlL2NvbnRhaW5lciB0byByZW1vdmUgdGhlIGNoaWxkcmVuIGZyb20uXG4gICAgLy8gVE9ETzogSW5zdGVhZCBvZiBzZWFyY2hpbmcgdXAgdGhlIGZpYmVyIHJldHVybiBwYXRoIG9uIGV2ZXJ5IGRlbGV0aW9uLCB3ZVxuICAgIC8vIGNhbiB0cmFjayB0aGUgbmVhcmVzdCBob3N0IGNvbXBvbmVudCBvbiB0aGUgSlMgc3RhY2sgYXMgd2UgdHJhdmVyc2UgdGhlXG4gICAgLy8gdHJlZSBkdXJpbmcgdGhlIGNvbW1pdCBwaGFzZS4gVGhpcyB3b3VsZCBtYWtlIGluc2VydGlvbnMgZmFzdGVyLCB0b28uXG4gICAgdmFyIHBhcmVudCA9IHJldHVybkZpYmVyO1xuXG4gICAgZmluZFBhcmVudDogd2hpbGUgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChwYXJlbnQudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZTtcbiAgICAgICAgICAgIGhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWsgZmluZFBhcmVudDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrIGZpbmRQYXJlbnQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrIGZpbmRQYXJlbnQ7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwYXJlbnQgPSBwYXJlbnQucmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChob3N0UGFyZW50ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgYSBob3N0IHBhcmVudC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5ICcgKyAnYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIGNvbW1pdERlbGV0aW9uRWZmZWN0c09uRmliZXIocm9vdCwgcmV0dXJuRmliZXIsIGRlbGV0ZWRGaWJlcik7XG4gICAgaG9zdFBhcmVudCA9IG51bGw7XG4gICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gZmFsc2U7XG4gIH1cblxuICBkZXRhY2hGaWJlck11dGF0aW9uKGRlbGV0ZWRGaWJlcik7XG59XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZWx5VHJhdmVyc2VEZWxldGlvbkVmZmVjdHMoZmluaXNoZWRSb290LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBwYXJlbnQpIHtcbiAgLy8gVE9ETzogVXNlIGEgc3RhdGljIGZsYWcgdG8gc2tpcCB0cmVlcyB0aGF0IGRvbid0IGhhdmUgdW5tb3VudCBlZmZlY3RzXG4gIHZhciBjaGlsZCA9IHBhcmVudC5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICBjb21taXREZWxldGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgY2hpbGQpO1xuICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXREZWxldGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKSB7XG4gIG9uQ29tbWl0VW5tb3VudChkZWxldGVkRmliZXIpOyAvLyBUaGUgY2FzZXMgaW4gdGhpcyBvdXRlciBzd2l0Y2ggbW9kaWZ5IHRoZSBzdGFjayBiZWZvcmUgdGhleSB0cmF2ZXJzZVxuICAvLyBpbnRvIHRoZWlyIHN1YnRyZWUuIFRoZXJlIGFyZSBzaW1wbGVyIGNhc2VzIGluIHRoZSBpbm5lciBzd2l0Y2hcbiAgLy8gdGhhdCBkb24ndCBtb2RpZnkgdGhlIHN0YWNrLlxuXG4gIHN3aXRjaCAoZGVsZXRlZEZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgaWYgKCFvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuKSB7XG4gICAgICAgICAgc2FmZWx5RGV0YWNoUmVmKGRlbGV0ZWRGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcik7XG4gICAgICAgIH0gLy8gSW50ZW50aW9uYWwgZmFsbHRocm91Z2ggdG8gbmV4dCBicmFuY2hcblxuICAgICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZS1uby1mYWxsdGhyb3VnaFxuXG4gICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgIHtcbiAgICAgICAgLy8gV2Ugb25seSBuZWVkIHRvIHJlbW92ZSB0aGUgbmVhcmVzdCBob3N0IGNoaWxkLiBTZXQgdGhlIGhvc3QgcGFyZW50XG4gICAgICAgIC8vIHRvIGBudWxsYCBvbiB0aGUgc3RhY2sgdG8gaW5kaWNhdGUgdGhhdCBuZXN0ZWQgY2hpbGRyZW4gZG9uJ3RcbiAgICAgICAgLy8gbmVlZCB0byBiZSByZW1vdmVkLlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHByZXZIb3N0UGFyZW50ID0gaG9zdFBhcmVudDtcbiAgICAgICAgICB2YXIgcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgICBob3N0UGFyZW50ID0gbnVsbDtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlRGVsZXRpb25FZmZlY3RzKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKTtcbiAgICAgICAgICBob3N0UGFyZW50ID0gcHJldkhvc3RQYXJlbnQ7XG4gICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcblxuICAgICAgICAgIGlmIChob3N0UGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBOb3cgdGhhdCBhbGwgdGhlIGNoaWxkIGVmZmVjdHMgaGF2ZSB1bm1vdW50ZWQsIHdlIGNhbiByZW1vdmUgdGhlXG4gICAgICAgICAgICAvLyBub2RlIGZyb20gdGhlIHRyZWUuXG4gICAgICAgICAgICBpZiAoaG9zdFBhcmVudElzQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgIHJlbW92ZUNoaWxkRnJvbUNvbnRhaW5lcihob3N0UGFyZW50LCBkZWxldGVkRmliZXIuc3RhdGVOb2RlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlbW92ZUNoaWxkKGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgRGVoeWRyYXRlZEZyYWdtZW50OlxuICAgICAge1xuICAgICAgICAvLyBEZWxldGUgdGhlIGRlaHlkcmF0ZWQgc3VzcGVuc2UgYm91bmRhcnkgYW5kIGFsbCBvZiBpdHMgY29udGVudC5cblxuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoaG9zdFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGhvc3RQYXJlbnRJc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICBjbGVhclN1c3BlbnNlQm91bmRhcnlGcm9tQ29udGFpbmVyKGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY2xlYXJTdXNwZW5zZUJvdW5kYXJ5KGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHtcbiAgICAgICAge1xuICAgICAgICAgIC8vIFdoZW4gd2UgZ28gaW50byBhIHBvcnRhbCwgaXQgYmVjb21lcyB0aGUgcGFyZW50IHRvIHJlbW92ZSBmcm9tLlxuICAgICAgICAgIHZhciBfcHJldkhvc3RQYXJlbnQgPSBob3N0UGFyZW50O1xuICAgICAgICAgIHZhciBfcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgICBob3N0UGFyZW50ID0gZGVsZXRlZEZpYmVyLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgIGhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IHRydWU7XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgICAgaG9zdFBhcmVudCA9IF9wcmV2SG9zdFBhcmVudDtcbiAgICAgICAgICBob3N0UGFyZW50SXNDb250YWluZXIgPSBfcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IGRlbGV0ZWRGaWJlci51cGRhdGVRdWV1ZTtcblxuICAgICAgICAgIGlmICh1cGRhdGVRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxhc3RFZmZlY3QgPSB1cGRhdGVRdWV1ZS5sYXN0RWZmZWN0O1xuXG4gICAgICAgICAgICBpZiAobGFzdEVmZmVjdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICB2YXIgZmlyc3RFZmZlY3QgPSBsYXN0RWZmZWN0Lm5leHQ7XG4gICAgICAgICAgICAgIHZhciBlZmZlY3QgPSBmaXJzdEVmZmVjdDtcblxuICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgdmFyIF9lZmZlY3QgPSBlZmZlY3QsXG4gICAgICAgICAgICAgICAgICAgIGRlc3Ryb3kgPSBfZWZmZWN0LmRlc3Ryb3ksXG4gICAgICAgICAgICAgICAgICAgIHRhZyA9IF9lZmZlY3QudGFnO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRlc3Ryb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHRhZyAmIExheW91dCkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkKGRlbGV0ZWRGaWJlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIGRlbGV0ZWRGaWJlci5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcbiAgICAgICAgICAgICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihkZWxldGVkRmliZXIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHNhZmVseUNhbGxEZXN0cm95KGRlbGV0ZWRGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVzdHJveSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBlZmZlY3QgPSBlZmZlY3QubmV4dDtcbiAgICAgICAgICAgICAgfSB3aGlsZSAoZWZmZWN0ICE9PSBmaXJzdEVmZmVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgIHNhZmVseURldGFjaFJlZihkZWxldGVkRmliZXIsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpO1xuICAgICAgICAgIHZhciBpbnN0YW5jZSA9IGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzYWZlbHlDYWxsQ29tcG9uZW50V2lsbFVubW91bnQoZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBpbnN0YW5jZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgU2NvcGVDb21wb25lbnQ6XG4gICAgICB7XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIC8vIFRPRE86IFJlbW92ZSB0aGlzIGRlYWQgZmxhZ1xuICAgICAgICAgZGVsZXRlZEZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgb2Zmc2NyZWVuIGNvbXBvbmVudCBpcyBoaWRkZW4sIHdlIGFscmVhZHkgdW5tb3VudGVkIGl0LiBCZWZvcmVcbiAgICAgICAgICAvLyBkZWxldGluZyB0aGUgY2hpbGRyZW4sIHRyYWNrIHRoYXQgaXQncyBhbHJlYWR5IHVubW91bnRlZCBzbyB0aGF0IHdlXG4gICAgICAgICAgLy8gZG9uJ3QgYXR0ZW1wdCB0byB1bm1vdW50IHRoZSBlZmZlY3RzIGFnYWluLlxuICAgICAgICAgIC8vIFRPRE86IElmIHRoZSB0cmVlIGlzIGhpZGRlbiwgaW4gbW9zdCBjYXNlcyB3ZSBzaG91bGQgYmUgYWJsZSB0byBza2lwXG4gICAgICAgICAgLy8gb3ZlciB0aGUgbmVzdGVkIGNoaWxkcmVuIGVudGlyZWx5LiBBbiBleGNlcHRpb24gaXMgd2UgaGF2ZW4ndCB5ZXQgZm91bmRcbiAgICAgICAgICAvLyB0aGUgdG9wbW9zdCBob3N0IG5vZGUgdG8gZGVsZXRlLCB3aGljaCB3ZSBhbHJlYWR5IHRyYWNrIG9uIHRoZSBzdGFjay5cbiAgICAgICAgICAvLyBCdXQgdGhlIG90aGVyIGNhc2UgaXMgcG9ydGFscywgd2hpY2ggbmVlZCB0byBiZSBkZXRhY2hlZCBubyBtYXR0ZXIgaG93XG4gICAgICAgICAgLy8gZGVlcGx5IHRoZXkgYXJlIG5lc3RlZC4gV2Ugc2hvdWxkIHVzZSBhIHN1YnRyZWUgZmxhZyB0byB0cmFjayB3aGV0aGVyIGFcbiAgICAgICAgICAvLyBzdWJ0cmVlIGluY2x1ZGVzIGEgbmVzdGVkIHBvcnRhbC5cbiAgICAgICAgICB2YXIgcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICAgIG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiB8fCBkZWxldGVkRmliZXIubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbDtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlRGVsZXRpb25FZmZlY3RzKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKTtcbiAgICAgICAgICBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VEZWxldGlvbkVmZmVjdHMoZmluaXNoZWRSb290LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZWxldGVkRmliZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0U3VzcGVuc2VDYWxsYmFjayhmaW5pc2hlZFdvcmspIHtcbiAgLy8gVE9ETzogTW92ZSB0aGlzIHRvIHBhc3NpdmUgcGhhc2VcbiAgdmFyIG5ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFN1c3BlbnNlSHlkcmF0aW9uQ2FsbGJhY2tzKGZpbmlzaGVkUm9vdCwgZmluaXNoZWRXb3JrKSB7XG5cbiAgdmFyIG5ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKG5ld1N0YXRlID09PSBudWxsKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBmaW5pc2hlZFdvcmsuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2U3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG5cbiAgICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBwcmV2U3RhdGUuZGVoeWRyYXRlZDtcblxuICAgICAgICBpZiAoc3VzcGVuc2VJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGNvbW1pdEh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yaykge1xuICAvLyBJZiB0aGlzIGJvdW5kYXJ5IGp1c3QgdGltZWQgb3V0LCB0aGVuIGl0IHdpbGwgaGF2ZSBhIHNldCBvZiB3YWtlYWJsZXMuXG4gIC8vIEZvciBlYWNoIHdha2VhYmxlLCBhdHRhY2ggYSBsaXN0ZW5lciBzbyB0aGF0IHdoZW4gaXQgcmVzb2x2ZXMsIFJlYWN0XG4gIC8vIGF0dGVtcHRzIHRvIHJlLXJlbmRlciB0aGUgYm91bmRhcnkgaW4gdGhlIHByaW1hcnkgKHByZS10aW1lb3V0KSBzdGF0ZS5cbiAgdmFyIHdha2VhYmxlcyA9IGZpbmlzaGVkV29yay51cGRhdGVRdWV1ZTtcblxuICBpZiAod2FrZWFibGVzICE9PSBudWxsKSB7XG4gICAgZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB2YXIgcmV0cnlDYWNoZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG5cbiAgICBpZiAocmV0cnlDYWNoZSA9PT0gbnVsbCkge1xuICAgICAgcmV0cnlDYWNoZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGUgPSBuZXcgUG9zc2libHlXZWFrU2V0KCk7XG4gICAgfVxuXG4gICAgd2FrZWFibGVzLmZvckVhY2goZnVuY3Rpb24gKHdha2VhYmxlKSB7XG4gICAgICAvLyBNZW1vaXplIHVzaW5nIHRoZSBib3VuZGFyeSBmaWJlciB0byBwcmV2ZW50IHJlZHVuZGFudCBsaXN0ZW5lcnMuXG4gICAgICB2YXIgcmV0cnkgPSByZXNvbHZlUmV0cnlXYWtlYWJsZS5iaW5kKG51bGwsIGZpbmlzaGVkV29yaywgd2FrZWFibGUpO1xuXG4gICAgICBpZiAoIXJldHJ5Q2FjaGUuaGFzKHdha2VhYmxlKSkge1xuICAgICAgICByZXRyeUNhY2hlLmFkZCh3YWtlYWJsZSk7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICAgICAgaWYgKGluUHJvZ3Jlc3NMYW5lcyAhPT0gbnVsbCAmJiBpblByb2dyZXNzUm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgd29yayBzdGlsbCwgYXNzb2NpYXRlIHRoZSBvcmlnaW5hbCB1cGRhdGVycyB3aXRoIGl0LlxuICAgICAgICAgICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKGluUHJvZ3Jlc3NSb290LCBpblByb2dyZXNzTGFuZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0V4cGVjdGVkIGZpbmlzaGVkIHJvb3QgYW5kIGxhbmVzIHRvIGJlIHNldC4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB3YWtlYWJsZS50aGVuKHJldHJ5LCByZXRyeSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0gLy8gVGhpcyBmdW5jdGlvbiBkZXRlY3RzIHdoZW4gYSBTdXNwZW5zZSBib3VuZGFyeSBnb2VzIGZyb20gdmlzaWJsZSB0byBoaWRkZW4uXG5mdW5jdGlvbiBjb21taXRNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrLCBjb21taXR0ZWRMYW5lcykge1xuICBpblByb2dyZXNzTGFuZXMgPSBjb21taXR0ZWRMYW5lcztcbiAgaW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICBzZXRDdXJyZW50RmliZXIoZmluaXNoZWRXb3JrKTtcbiAgY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihmaW5pc2hlZFdvcmssIHJvb3QpO1xuICBzZXRDdXJyZW50RmliZXIoZmluaXNoZWRXb3JrKTtcbiAgaW5Qcm9ncmVzc0xhbmVzID0gbnVsbDtcbiAgaW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xufVxuXG5mdW5jdGlvbiByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIHBhcmVudEZpYmVyLCBsYW5lcykge1xuICAvLyBEZWxldGlvbnMgZWZmZWN0cyBjYW4gYmUgc2NoZWR1bGVkIG9uIGFueSBmaWJlciB0eXBlLiBUaGV5IG5lZWQgdG8gaGFwcGVuXG4gIC8vIGJlZm9yZSB0aGUgY2hpbGRyZW4gZWZmZWN0cyBoYWUgZmlyZWQuXG4gIHZhciBkZWxldGlvbnMgPSBwYXJlbnRGaWJlci5kZWxldGlvbnM7XG5cbiAgaWYgKGRlbGV0aW9ucyAhPT0gbnVsbCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVsZXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGRUb0RlbGV0ZSA9IGRlbGV0aW9uc1tpXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbWl0RGVsZXRpb25FZmZlY3RzKHJvb3QsIHBhcmVudEZpYmVyLCBjaGlsZFRvRGVsZXRlKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGNoaWxkVG9EZWxldGUsIHBhcmVudEZpYmVyLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHByZXZEZWJ1Z0ZpYmVyID0gZ2V0Q3VycmVudEZpYmVyKCk7XG5cbiAgaWYgKHBhcmVudEZpYmVyLnN1YnRyZWVGbGFncyAmIE11dGF0aW9uTWFzaykge1xuICAgIHZhciBjaGlsZCA9IHBhcmVudEZpYmVyLmNoaWxkO1xuXG4gICAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoY2hpbGQpO1xuICAgICAgY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihjaGlsZCwgcm9vdCk7XG4gICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgfVxuICB9XG5cbiAgc2V0Q3VycmVudEZpYmVyKHByZXZEZWJ1Z0ZpYmVyKTtcbn1cblxuZnVuY3Rpb24gY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihmaW5pc2hlZFdvcmssIHJvb3QsIGxhbmVzKSB7XG4gIHZhciBjdXJyZW50ID0gZmluaXNoZWRXb3JrLmFsdGVybmF0ZTtcbiAgdmFyIGZsYWdzID0gZmluaXNoZWRXb3JrLmZsYWdzOyAvLyBUaGUgZWZmZWN0IGZsYWcgc2hvdWxkIGJlIGNoZWNrZWQgKmFmdGVyKiB3ZSByZWZpbmUgdGhlIHR5cGUgb2YgZmliZXIsXG4gIC8vIGJlY2F1c2UgdGhlIGZpYmVyIHRhZyBpcyBtb3JlIHNwZWNpZmljLiBBbiBleGNlcHRpb24gaXMgYW55IGZsYWcgcmVsYXRlZFxuICAvLyB0byByZWNvbmNpbGF0aW9uLCBiZWNhdXNlIHRob3NlIGNhbiBiZSBzZXQgb24gYWxsIGZpYmVyIHR5cGVzLlxuXG4gIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChJbnNlcnRpb24gfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KEluc2VydGlvbiB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfSAvLyBMYXlvdXQgZWZmZWN0cyBhcmUgZGVzdHJveWVkIGR1cmluZyB0aGUgbXV0YXRpb24gcGhhc2Ugc28gdGhhdCBhbGxcbiAgICAgICAgICAvLyBkZXN0cm95IGZ1bmN0aW9ucyBmb3IgYWxsIGZpYmVycyBhcmUgY2FsbGVkIGJlZm9yZSBhbnkgY3JlYXRlIGZ1bmN0aW9ucy5cbiAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIHNpYmxpbmcgY29tcG9uZW50IGVmZmVjdHMgZnJvbSBpbnRlcmZlcmluZyB3aXRoIGVhY2ggb3RoZXIsXG4gICAgICAgICAgLy8gZS5nLiBhIGRlc3Ryb3kgZnVuY3Rpb24gaW4gb25lIGNvbXBvbmVudCBzaG91bGQgbmV2ZXIgb3ZlcnJpZGUgYSByZWYgc2V0XG4gICAgICAgICAgLy8gYnkgYSBjcmVhdGUgZnVuY3Rpb24gaW4gYW5vdGhlciBjb21wb25lbnQgZHVyaW5nIHRoZSBzYW1lIGNvbW1pdC5cblxuXG4gICAgICAgICAgaWYgKCBmaW5pc2hlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChMYXlvdXQgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RVbm1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgUmVmKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHNhZmVseURldGFjaFJlZihjdXJyZW50LCBjdXJyZW50LnJldHVybik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGlmIChmbGFncyAmIFJlZikge1xuICAgICAgICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoY3VycmVudCwgY3VycmVudC5yZXR1cm4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBUT0RPOiBDb250ZW50UmVzZXQgZ2V0cyBjbGVhcmVkIGJ5IHRoZSBjaGlsZHJlbiBkdXJpbmcgdGhlIGNvbW1pdFxuICAgICAgICAgIC8vIHBoYXNlLiBUaGlzIGlzIGEgcmVmYWN0b3IgaGF6YXJkIGJlY2F1c2UgaXQgbWVhbnMgd2UgbXVzdCByZWFkXG4gICAgICAgICAgLy8gZmxhZ3MgdGhlIGZsYWdzIGFmdGVyIGBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHNgIGhhcyBhbHJlYWR5IHJ1bjtcbiAgICAgICAgICAvLyB0aGUgb3JkZXIgbWF0dGVycy4gV2Ugc2hvdWxkIHJlZmFjdG9yIHNvIHRoYXQgQ29udGVudFJlc2V0IGRvZXMgbm90XG4gICAgICAgICAgLy8gcmVseSBvbiBtdXRhdGluZyB0aGUgZmxhZyBkdXJpbmcgY29tbWl0LiBMaWtlIGJ5IHNldHRpbmcgYSBmbGFnXG4gICAgICAgICAgLy8gZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UgaW5zdGVhZC5cbiAgICAgICAgICBpZiAoZmluaXNoZWRXb3JrLmZsYWdzICYgQ29udGVudFJlc2V0KSB7XG4gICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICByZXNldFRleHRDb250ZW50KGluc3RhbmNlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmbGFncyAmIFVwZGF0ZSkge1xuICAgICAgICAgICAgdmFyIF9pbnN0YW5jZTQgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICBpZiAoX2luc3RhbmNlNCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIENvbW1pdCB0aGUgd29yayBwcmVwYXJlZCBlYXJsaWVyLlxuICAgICAgICAgICAgICB2YXIgbmV3UHJvcHMgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wczsgLy8gRm9yIGh5ZHJhdGlvbiB3ZSByZXVzZSB0aGUgdXBkYXRlIHBhdGggYnV0IHdlIHRyZWF0IHRoZSBvbGRQcm9wc1xuICAgICAgICAgICAgICAvLyBhcyB0aGUgbmV3UHJvcHMuIFRoZSB1cGRhdGVQYXlsb2FkIHdpbGwgY29udGFpbiB0aGUgcmVhbCBjaGFuZ2UgaW5cbiAgICAgICAgICAgICAgLy8gdGhpcyBjYXNlLlxuXG4gICAgICAgICAgICAgIHZhciBvbGRQcm9wcyA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Lm1lbW9pemVkUHJvcHMgOiBuZXdQcm9wcztcbiAgICAgICAgICAgICAgdmFyIHR5cGUgPSBmaW5pc2hlZFdvcmsudHlwZTsgLy8gVE9ETzogVHlwZSB0aGUgdXBkYXRlUXVldWUgdG8gYmUgc3BlY2lmaWMgdG8gaG9zdCBjb21wb25lbnRzLlxuXG4gICAgICAgICAgICAgIHZhciB1cGRhdGVQYXlsb2FkID0gZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlO1xuICAgICAgICAgICAgICBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWUgPSBudWxsO1xuXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVQYXlsb2FkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbW1pdFVwZGF0ZShfaW5zdGFuY2U0LCB1cGRhdGVQYXlsb2FkLCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay5zdGF0ZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHNob3VsZCBoYXZlIGEgdGV4dCBub2RlIGluaXRpYWxpemVkLiBUaGlzIGVycm9yIGlzIGxpa2VseSAnICsgJ2NhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB0ZXh0SW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuICAgICAgICAgICAgdmFyIG5ld1RleHQgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wczsgLy8gRm9yIGh5ZHJhdGlvbiB3ZSByZXVzZSB0aGUgdXBkYXRlIHBhdGggYnV0IHdlIHRyZWF0IHRoZSBvbGRQcm9wc1xuICAgICAgICAgICAgLy8gYXMgdGhlIG5ld1Byb3BzLiBUaGUgdXBkYXRlUGF5bG9hZCB3aWxsIGNvbnRhaW4gdGhlIHJlYWwgY2hhbmdlIGluXG4gICAgICAgICAgICAvLyB0aGlzIGNhc2UuXG5cbiAgICAgICAgICAgIHZhciBvbGRUZXh0ID0gY3VycmVudCAhPT0gbnVsbCA/IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyA6IG5ld1RleHQ7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbW1pdFRleHRVcGRhdGUodGV4dEluc3RhbmNlLCBvbGRUZXh0LCBuZXdUZXh0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIHByZXZSb290U3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgICAgICAgaWYgKHByZXZSb290U3RhdGUuaXNEZWh5ZHJhdGVkKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbW1pdEh5ZHJhdGVkQ29udGFpbmVyKHJvb3QuY29udGFpbmVySW5mbyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHtcbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuICAgICAgICB2YXIgb2Zmc2NyZWVuRmliZXIgPSBmaW5pc2hlZFdvcmsuY2hpbGQ7XG5cbiAgICAgICAgaWYgKG9mZnNjcmVlbkZpYmVyLmZsYWdzICYgVmlzaWJpbGl0eSkge1xuICAgICAgICAgIHZhciBuZXdTdGF0ZSA9IG9mZnNjcmVlbkZpYmVyLm1lbW9pemVkU3RhdGU7XG4gICAgICAgICAgdmFyIGlzSGlkZGVuID0gbmV3U3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgICBpZiAoaXNIaWRkZW4pIHtcbiAgICAgICAgICAgIHZhciB3YXNIaWRkZW4gPSBvZmZzY3JlZW5GaWJlci5hbHRlcm5hdGUgIT09IG51bGwgJiYgb2Zmc2NyZWVuRmliZXIuYWx0ZXJuYXRlLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgICAgIGlmICghd2FzSGlkZGVuKSB7XG4gICAgICAgICAgICAgIC8vIFRPRE86IE1vdmUgdG8gcGFzc2l2ZSBwaGFzZVxuICAgICAgICAgICAgICBtYXJrQ29tbWl0VGltZU9mRmFsbGJhY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0U3VzcGVuc2VDYWxsYmFjayhmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIE9mZnNjcmVlbkNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIF93YXNIaWRkZW4gPSBjdXJyZW50ICE9PSBudWxsICYmIGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICBpZiAoIC8vIFRPRE86IFJlbW92ZSB0aGlzIGRlYWQgZmxhZ1xuICAgICAgICAgZmluaXNoZWRXb3JrLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICAgIC8vIEJlZm9yZSBjb21taXR0aW5nIHRoZSBjaGlsZHJlbiwgdHJhY2sgb24gdGhlIHN0YWNrIHdoZXRoZXIgdGhpc1xuICAgICAgICAgIC8vIG9mZnNjcmVlbiBzdWJ0cmVlIHdhcyBhbHJlYWR5IGhpZGRlbiwgc28gdGhhdCB3ZSBkb24ndCB1bm1vdW50IHRoZVxuICAgICAgICAgIC8vIGVmZmVjdHMgYWdhaW4uXG4gICAgICAgICAgdmFyIHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbjtcbiAgICAgICAgICBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gfHwgX3dhc0hpZGRlbjtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGlmIChmbGFncyAmIFZpc2liaWxpdHkpIHtcbiAgICAgICAgICB2YXIgX25ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgICB2YXIgX2lzSGlkZGVuID0gX25ld1N0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgdmFyIG9mZnNjcmVlbkJvdW5kYXJ5ID0gZmluaXNoZWRXb3JrO1xuXG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gVE9ETzogVGhpcyBuZWVkcyB0byBydW4gd2hlbmV2ZXIgdGhlcmUncyBhbiBpbnNlcnRpb24gb3IgdXBkYXRlXG4gICAgICAgICAgICAvLyBpbnNpZGUgYSBoaWRkZW4gT2Zmc2NyZWVuIHRyZWUuXG4gICAgICAgICAgICBoaWRlT3JVbmhpZGVBbGxDaGlsZHJlbihvZmZzY3JlZW5Cb3VuZGFyeSwgX2lzSGlkZGVuKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoX2lzSGlkZGVuKSB7XG4gICAgICAgICAgICAgIGlmICghX3dhc0hpZGRlbikge1xuICAgICAgICAgICAgICAgIGlmICgob2Zmc2NyZWVuQm91bmRhcnkubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICAgICAgICBuZXh0RWZmZWN0ID0gb2Zmc2NyZWVuQm91bmRhcnk7XG4gICAgICAgICAgICAgICAgICB2YXIgb2Zmc2NyZWVuQ2hpbGQgPSBvZmZzY3JlZW5Cb3VuZGFyeS5jaGlsZDtcblxuICAgICAgICAgICAgICAgICAgd2hpbGUgKG9mZnNjcmVlbkNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFZmZlY3QgPSBvZmZzY3JlZW5DaGlsZDtcbiAgICAgICAgICAgICAgICAgICAgZGlzYXBwZWFyTGF5b3V0RWZmZWN0c19iZWdpbihvZmZzY3JlZW5DaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNjcmVlbkNoaWxkID0gb2Zmc2NyZWVuQ2hpbGQuc2libGluZztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICBpZiAoZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKSB7XG4gIC8vIFBsYWNlbWVudCBlZmZlY3RzIChpbnNlcnRpb25zLCByZW9yZGVycykgY2FuIGJlIHNjaGVkdWxlZCBvbiBhbnkgZmliZXJcbiAgLy8gdHlwZS4gVGhleSBuZWVkcyB0byBoYXBwZW4gYWZ0ZXIgdGhlIGNoaWxkcmVuIGVmZmVjdHMgaGF2ZSBmaXJlZCwgYnV0XG4gIC8vIGJlZm9yZSB0aGUgZWZmZWN0cyBvbiB0aGlzIGZpYmVyIGhhdmUgZmlyZWQuXG4gIHZhciBmbGFncyA9IGZpbmlzaGVkV29yay5mbGFncztcblxuICBpZiAoZmxhZ3MgJiBQbGFjZW1lbnQpIHtcbiAgICB0cnkge1xuICAgICAgY29tbWl0UGxhY2VtZW50KGZpbmlzaGVkV29yayk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgIH0gLy8gQ2xlYXIgdGhlIFwicGxhY2VtZW50XCIgZnJvbSBlZmZlY3QgdGFnIHNvIHRoYXQgd2Uga25vdyB0aGF0IHRoaXMgaXNcbiAgICAvLyBpbnNlcnRlZCwgYmVmb3JlIGFueSBsaWZlLWN5Y2xlcyBsaWtlIGNvbXBvbmVudERpZE1vdW50IGdldHMgY2FsbGVkLlxuICAgIC8vIFRPRE86IGZpbmRET01Ob2RlIGRvZXNuJ3QgcmVseSBvbiB0aGlzIGFueSBtb3JlIGJ1dCBpc01vdW50ZWQgZG9lc1xuICAgIC8vIGFuZCBpc01vdW50ZWQgaXMgZGVwcmVjYXRlZCBhbnl3YXkgc28gd2Ugc2hvdWxkIGJlIGFibGUgdG8ga2lsbCB0aGlzLlxuXG5cbiAgICBmaW5pc2hlZFdvcmsuZmxhZ3MgJj0gflBsYWNlbWVudDtcbiAgfVxuXG4gIGlmIChmbGFncyAmIEh5ZHJhdGluZykge1xuICAgIGZpbmlzaGVkV29yay5mbGFncyAmPSB+SHlkcmF0aW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdExheW91dEVmZmVjdHMoZmluaXNoZWRXb3JrLCByb290LCBjb21taXR0ZWRMYW5lcykge1xuICBpblByb2dyZXNzTGFuZXMgPSBjb21taXR0ZWRMYW5lcztcbiAgaW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICBuZXh0RWZmZWN0ID0gZmluaXNoZWRXb3JrO1xuICBjb21taXRMYXlvdXRFZmZlY3RzX2JlZ2luKGZpbmlzaGVkV29yaywgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICBpblByb2dyZXNzTGFuZXMgPSBudWxsO1xuICBpblByb2dyZXNzUm9vdCA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdExheW91dEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKSB7XG4gIC8vIFN1c3BlbnNlIGxheW91dCBlZmZlY3RzIHNlbWFudGljcyBkb24ndCBjaGFuZ2UgZm9yIGxlZ2FjeSByb290cy5cbiAgdmFyIGlzTW9kZXJuUm9vdCA9IChzdWJ0cmVlUm9vdC5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG5cbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuICAgIHZhciBmaXJzdENoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoIGZpYmVyLnRhZyA9PT0gT2Zmc2NyZWVuQ29tcG9uZW50ICYmIGlzTW9kZXJuUm9vdCkge1xuICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgY3VycmVudCBPZmZzY3JlZW4gc3RhY2sncyBzdGF0ZS5cbiAgICAgIHZhciBpc0hpZGRlbiA9IGZpYmVyLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG4gICAgICB2YXIgbmV3T2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuID0gaXNIaWRkZW4gfHwgb2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuO1xuXG4gICAgICBpZiAobmV3T2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuKSB7XG4gICAgICAgIC8vIFRoZSBPZmZzY3JlZW4gdHJlZSBpcyBoaWRkZW4uIFNraXAgb3ZlciBpdHMgbGF5b3V0IGVmZmVjdHMuXG4gICAgICAgIGNvbW1pdExheW91dE1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE8gKE9mZnNjcmVlbikgQWxzbyBjaGVjazogc3VidHJlZUZsYWdzICYgTGF5b3V0TWFza1xuICAgICAgICB2YXIgY3VycmVudCA9IGZpYmVyLmFsdGVybmF0ZTtcbiAgICAgICAgdmFyIHdhc0hpZGRlbiA9IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuICAgICAgICB2YXIgbmV3T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHdhc0hpZGRlbiB8fCBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICB2YXIgcHJldk9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbiA9IG9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgdmFyIHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbjsgLy8gVHJhdmVyc2UgdGhlIE9mZnNjcmVlbiBzdWJ0cmVlIHdpdGggdGhlIGN1cnJlbnQgT2Zmc2NyZWVuIGFzIHRoZSByb290LlxuXG4gICAgICAgIG9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbiA9IG5ld09mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IG5ld09mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG5cbiAgICAgICAgaWYgKG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gJiYgIXByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyB0aGUgcm9vdCBvZiBhIHJlYXBwZWFyaW5nIGJvdW5kYXJ5LiBUdXJuIGl0cyBsYXlvdXQgZWZmZWN0c1xuICAgICAgICAgIC8vIGJhY2sgb24uXG4gICAgICAgICAgbmV4dEVmZmVjdCA9IGZpYmVyO1xuICAgICAgICAgIHJlYXBwZWFyTGF5b3V0RWZmZWN0c19iZWdpbihmaWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGQgPSBmaXJzdENoaWxkO1xuXG4gICAgICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICAgICAgICBjb21taXRMYXlvdXRFZmZlY3RzX2JlZ2luKGNoaWxkLCAvLyBOZXcgcm9vdDsgYnViYmxlIGJhY2sgdXAgdG8gaGVyZSBhbmQgc3RvcC5cbiAgICAgICAgICByb290LCBjb21taXR0ZWRMYW5lcyk7XG4gICAgICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgICAgICB9IC8vIFJlc3RvcmUgT2Zmc2NyZWVuIHN0YXRlIGFuZCByZXN1bWUgaW4gb3VyLXByb2dyZXNzIHRyYXZlcnNhbC5cblxuXG4gICAgICAgIG5leHRFZmZlY3QgPSBmaWJlcjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICBjb21taXRMYXlvdXRNb3VudEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKChmaWJlci5zdWJ0cmVlRmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncyAmJiBmaXJzdENoaWxkICE9PSBudWxsKSB7XG4gICAgICBmaXJzdENoaWxkLnJldHVybiA9IGZpYmVyO1xuICAgICAgbmV4dEVmZmVjdCA9IGZpcnN0Q2hpbGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1pdExheW91dE1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRMYXlvdXRNb3VudEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcblxuICAgIGlmICgoZmliZXIuZmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncykge1xuICAgICAgdmFyIGN1cnJlbnQgPSBmaWJlci5hbHRlcm5hdGU7XG4gICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb21taXRMYXlvdXRFZmZlY3RPbkZpYmVyKHJvb3QsIGN1cnJlbnQsIGZpYmVyLCBjb21taXR0ZWRMYW5lcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgfVxuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNhcHBlYXJMYXlvdXRFZmZlY3RzX2JlZ2luKHN1YnRyZWVSb290KSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcbiAgICB2YXIgZmlyc3RDaGlsZCA9IGZpYmVyLmNoaWxkOyAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBmbGFncyAmIChSZWZTdGF0aWMgfCBMYXlvdXRTdGF0aWMpXG5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICggZmliZXIubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChMYXlvdXQsIGZpYmVyLCBmaWJlci5yZXR1cm4pO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oZmliZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoTGF5b3V0LCBmaWJlciwgZmliZXIucmV0dXJuKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogZmxhZ3MgJiBSZWZTdGF0aWNcbiAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoZmliZXIsIGZpYmVyLnJldHVybik7XG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVW5tb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgc2FmZWx5Q2FsbENvbXBvbmVudFdpbGxVbm1vdW50KGZpYmVyLCBmaWJlci5yZXR1cm4sIGluc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoZmliZXIsIGZpYmVyLnJldHVybik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFcbiAgICAgICAgICB2YXIgaXNIaWRkZW4gPSBmaWJlci5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICAvLyBOZXN0ZWQgT2Zmc2NyZWVuIHRyZWUgaXMgYWxyZWFkeSBoaWRkZW4uIERvbid0IGRpc2FwcGVhclxuICAgICAgICAgICAgLy8gaXRzIGVmZmVjdHMuXG4gICAgICAgICAgICBkaXNhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBzdWJ0cmVlRmxhZ3MgJiBMYXlvdXRTdGF0aWNcblxuXG4gICAgaWYgKGZpcnN0Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlzYXBwZWFyTGF5b3V0RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRpc2FwcGVhckxheW91dEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWFwcGVhckxheW91dEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuICAgIHZhciBmaXJzdENoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoZmliZXIudGFnID09PSBPZmZzY3JlZW5Db21wb25lbnQpIHtcbiAgICAgIHZhciBpc0hpZGRlbiA9IGZpYmVyLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG5cbiAgICAgIGlmIChpc0hpZGRlbikge1xuICAgICAgICAvLyBOZXN0ZWQgT2Zmc2NyZWVuIHRyZWUgaXMgc3RpbGwgaGlkZGVuLiBEb24ndCByZS1hcHBlYXIgaXRzIGVmZmVjdHMuXG4gICAgICAgIHJlYXBwZWFyTGF5b3V0RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH0gLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogc3VidHJlZUZsYWdzICYgTGF5b3V0U3RhdGljXG5cblxuICAgIGlmIChmaXJzdENoaWxkICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIG5vZGUgbWF5IGhhdmUgYmVlbiByZXVzZWQgZnJvbSBhIHByZXZpb3VzIHJlbmRlciwgc28gd2UgY2FuJ3RcbiAgICAgIC8vIGFzc3VtZSBpdHMgcmV0dXJuIHBvaW50ZXIgaXMgY29ycmVjdC5cbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDsgLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogZmxhZ3MgJiBMYXlvdXRTdGF0aWNcblxuICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG5cbiAgICB0cnkge1xuICAgICAgcmVhcHBlYXJMYXlvdXRFZmZlY3RzT25GaWJlcihmaWJlcik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpYmVyLCBmaWJlci5yZXR1cm4sIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgbm9kZSBtYXkgaGF2ZSBiZWVuIHJldXNlZCBmcm9tIGEgcHJldmlvdXMgcmVuZGVyLCBzbyB3ZSBjYW4ndFxuICAgICAgLy8gYXNzdW1lIGl0cyByZXR1cm4gcG9pbnRlciBpcyBjb3JyZWN0LlxuICAgICAgc2libGluZy5yZXR1cm4gPSBmaWJlci5yZXR1cm47XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gZmliZXIucmV0dXJuO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrLCBjb21taXR0ZWRMYW5lcywgY29tbWl0dGVkVHJhbnNpdGlvbnMpIHtcbiAgbmV4dEVmZmVjdCA9IGZpbmlzaGVkV29yaztcbiAgY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19iZWdpbihmaW5pc2hlZFdvcmssIHJvb3QsIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucykge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIGZpcnN0Q2hpbGQgPSBmaWJlci5jaGlsZDtcblxuICAgIGlmICgoZmliZXIuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzICYmIGZpcnN0Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcblxuICAgIGlmICgoZmliZXIuZmxhZ3MgJiBQYXNzaXZlKSAhPT0gTm9GbGFncykge1xuICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbWl0UGFzc2l2ZU1vdW50T25GaWJlcihyb290LCBmaWJlciwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpYmVyLCBmaWJlci5yZXR1cm4sIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIgPT09IHN1YnRyZWVSb290KSB7XG4gICAgICBuZXh0RWZmZWN0ID0gbnVsbDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc2libGluZyA9IGZpYmVyLnNpYmxpbmc7XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgc2libGluZy5yZXR1cm4gPSBmaWJlci5yZXR1cm47XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gZmliZXIucmV0dXJuO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudE9uRmliZXIoZmluaXNoZWRSb290LCBmaW5pc2hlZFdvcmssIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucykge1xuICBzd2l0Y2ggKGZpbmlzaGVkV29yay50YWcpIHtcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgIHN0YXJ0UGFzc2l2ZUVmZmVjdFRpbWVyKCk7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RNb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHJlY29yZFBhc3NpdmVFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KFBhc3NpdmUkMSB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0cyhmaXJzdENoaWxkKSB7XG4gIG5leHRFZmZlY3QgPSBmaXJzdENoaWxkO1xuICBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNfYmVnaW4oKTtcbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzX2JlZ2luKCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoKG5leHRFZmZlY3QuZmxhZ3MgJiBDaGlsZERlbGV0aW9uKSAhPT0gTm9GbGFncykge1xuICAgICAgdmFyIGRlbGV0aW9ucyA9IGZpYmVyLmRlbGV0aW9ucztcblxuICAgICAgaWYgKGRlbGV0aW9ucyAhPT0gbnVsbCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGV0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBmaWJlclRvRGVsZXRlID0gZGVsZXRpb25zW2ldO1xuICAgICAgICAgIG5leHRFZmZlY3QgPSBmaWJlclRvRGVsZXRlO1xuICAgICAgICAgIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0c0luc2lkZU9mRGVsZXRlZFRyZWVfYmVnaW4oZmliZXJUb0RlbGV0ZSwgZmliZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIC8vIEEgZmliZXIgd2FzIGRlbGV0ZWQgZnJvbSB0aGlzIHBhcmVudCBmaWJlciwgYnV0IGl0J3Mgc3RpbGwgcGFydCBvZlxuICAgICAgICAgIC8vIHRoZSBwcmV2aW91cyAoYWx0ZXJuYXRlKSBwYXJlbnQgZmliZXIncyBsaXN0IG9mIGNoaWxkcmVuLiBCZWNhdXNlXG4gICAgICAgICAgLy8gY2hpbGRyZW4gYXJlIGEgbGlua2VkIGxpc3QsIGFuIGVhcmxpZXIgc2libGluZyB0aGF0J3Mgc3RpbGwgYWxpdmVcbiAgICAgICAgICAvLyB3aWxsIGJlIGNvbm5lY3RlZCB0byB0aGUgZGVsZXRlZCBmaWJlciB2aWEgaXRzIGBhbHRlcm5hdGVgOlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gICBsaXZlIGZpYmVyXG4gICAgICAgICAgLy8gICAtLWFsdGVybmF0ZS0tPiBwcmV2aW91cyBsaXZlIGZpYmVyXG4gICAgICAgICAgLy8gICAtLXNpYmxpbmctLT4gZGVsZXRlZCBmaWJlclxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2UgY2FuJ3QgZGlzY29ubmVjdCBgYWx0ZXJuYXRlYCBvbiBub2RlcyB0aGF0IGhhdmVuJ3QgYmVlbiBkZWxldGVkXG4gICAgICAgICAgLy8geWV0LCBidXQgd2UgY2FuIGRpc2Nvbm5lY3QgdGhlIGBzaWJsaW5nYCBhbmQgYGNoaWxkYCBwb2ludGVycy5cbiAgICAgICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICAgIGlmIChwcmV2aW91c0ZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZGV0YWNoZWRDaGlsZCA9IHByZXZpb3VzRmliZXIuY2hpbGQ7XG5cbiAgICAgICAgICAgIGlmIChkZXRhY2hlZENoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHByZXZpb3VzRmliZXIuY2hpbGQgPSBudWxsO1xuXG4gICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICB2YXIgZGV0YWNoZWRTaWJsaW5nID0gZGV0YWNoZWRDaGlsZC5zaWJsaW5nO1xuICAgICAgICAgICAgICAgIGRldGFjaGVkQ2hpbGQuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGV0YWNoZWRDaGlsZCA9IGRldGFjaGVkU2libGluZztcbiAgICAgICAgICAgICAgfSB3aGlsZSAoZGV0YWNoZWRDaGlsZCAhPT0gbnVsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbmV4dEVmZmVjdCA9IGZpYmVyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICgoZmliZXIuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzICYmIGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBjaGlsZC5yZXR1cm4gPSBmaWJlcjtcbiAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzX2NvbXBsZXRlKCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0c19jb21wbGV0ZSgpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuXG4gICAgaWYgKChmaWJlci5mbGFncyAmIFBhc3NpdmUpICE9PSBOb0ZsYWdzKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRPbkZpYmVyKGZpYmVyKTtcbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudE9uRmliZXIoZmluaXNoZWRXb3JrKSB7XG4gIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgaWYgKCBmaW5pc2hlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKTtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoUGFzc2l2ZSQxIHwgSGFzRWZmZWN0LCBmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4pO1xuICAgICAgICAgIHJlY29yZFBhc3NpdmVFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNJbnNpZGVPZkRlbGV0ZWRUcmVlX2JlZ2luKGRlbGV0ZWRTdWJ0cmVlUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7IC8vIERlbGV0aW9uIGVmZmVjdHMgZmlyZSBpbiBwYXJlbnQgLT4gY2hpbGQgb3JkZXJcbiAgICAvLyBUT0RPOiBDaGVjayBpZiBmaWJlciBoYXMgYSBQYXNzaXZlU3RhdGljIGZsYWdcblxuICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG4gICAgY29tbWl0UGFzc2l2ZVVubW91bnRJbnNpZGVEZWxldGVkVHJlZU9uRmliZXIoZmliZXIsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpO1xuICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7IC8vIFRPRE86IE9ubHkgdHJhdmVyc2Ugc3VidHJlZSBpZiBpdCBoYXMgYSBQYXNzaXZlU3RhdGljIGZsYWcuIChCdXQsIGlmIHdlXG4gICAgLy8gZG8gdGhpcywgc3RpbGwgbmVlZCB0byBoYW5kbGUgYGRlbGV0ZWRUcmVlQ2xlYW5VcExldmVsYCBjb3JyZWN0bHkuKVxuXG4gICAgaWYgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBjaGlsZC5yZXR1cm4gPSBmaWJlcjtcbiAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzSW5zaWRlT2ZEZWxldGVkVHJlZV9jb21wbGV0ZShkZWxldGVkU3VidHJlZVJvb3QpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNJbnNpZGVPZkRlbGV0ZWRUcmVlX2NvbXBsZXRlKGRlbGV0ZWRTdWJ0cmVlUm9vdCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuICAgIHZhciByZXR1cm5GaWJlciA9IGZpYmVyLnJldHVybjtcblxuICAgIHtcbiAgICAgIC8vIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIHRoZSBlbnRpcmUgZGVsZXRlZCB0cmVlIGFuZCBjbGVhbiB1cCBmaWJlciBmaWVsZHMuXG4gICAgICAvLyBUaGlzIGlzIG1vcmUgYWdncmVzc2l2ZSB0aGFuIGlkZWFsLCBhbmQgdGhlIGxvbmcgdGVybSBnb2FsIGlzIHRvIG9ubHlcbiAgICAgIC8vIGhhdmUgdG8gZGV0YWNoIHRoZSBkZWxldGVkIHRyZWUgYXQgdGhlIHJvb3QuXG4gICAgICBkZXRhY2hGaWJlckFmdGVyRWZmZWN0cyhmaWJlcik7XG5cbiAgICAgIGlmIChmaWJlciA9PT0gZGVsZXRlZFN1YnRyZWVSb290KSB7XG4gICAgICAgIG5leHRFZmZlY3QgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gcmV0dXJuRmliZXI7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZVVubW91bnRJbnNpZGVEZWxldGVkVHJlZU9uRmliZXIoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICBzd2l0Y2ggKGN1cnJlbnQudGFnKSB7XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIGN1cnJlbnQubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKTtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoUGFzc2l2ZSQxLCBjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yKTtcbiAgICAgICAgICByZWNvcmRQYXNzaXZlRWZmZWN0RHVyYXRpb24oY3VycmVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RVbm1vdW50KFBhc3NpdmUkMSwgY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufSAvLyBUT0RPOiBSZXVzZSByZWFwcGVhckxheW91dEVmZmVjdHMgdHJhdmVyc2FsIGhlcmU/XG5cblxuZnVuY3Rpb24gaW52b2tlTGF5b3V0RWZmZWN0TW91bnRJbkRFVihmaWJlcikge1xuICB7XG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZS1jaGVjayBTdHJpY3RFZmZlY3RzTW9kZSBoZXJlLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgaWYgdGhhdCBjaGVjayBoYXMgYWxyZWFkeSBwYXNzZWQuXG4gICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RNb3VudChMYXlvdXQgfCBIYXNFZmZlY3QsIGZpYmVyKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZVBhc3NpdmVFZmZlY3RNb3VudEluREVWKGZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlLWNoZWNrIFN0cmljdEVmZmVjdHNNb2RlIGhlcmUuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBpZiB0aGF0IGNoZWNrIGhhcyBhbHJlYWR5IHBhc3NlZC5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KFBhc3NpdmUkMSB8IEhhc0VmZmVjdCwgZmliZXIpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW52b2tlTGF5b3V0RWZmZWN0VW5tb3VudEluREVWKGZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlLWNoZWNrIFN0cmljdEVmZmVjdHNNb2RlIGhlcmUuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBpZiB0aGF0IGNoZWNrIGhhcyBhbHJlYWR5IHBhc3NlZC5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoTGF5b3V0IHwgSGFzRWZmZWN0LCBmaWJlciwgZmliZXIucmV0dXJuKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzYWZlbHlDYWxsQ29tcG9uZW50V2lsbFVubW91bnQoZmliZXIsIGZpYmVyLnJldHVybiwgaW5zdGFuY2UpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZVBhc3NpdmVFZmZlY3RVbm1vdW50SW5ERVYoZmliZXIpIHtcbiAge1xuICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gcmUtY2hlY2sgU3RyaWN0RWZmZWN0c01vZGUgaGVyZS5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG9ubHkgY2FsbGVkIGlmIHRoYXQgY2hlY2sgaGFzIGFscmVhZHkgcGFzc2VkLlxuICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpYmVyLCBmaWJlci5yZXR1cm4pO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBDT01QT05FTlRfVFlQRSA9IDA7XG52YXIgSEFTX1BTRVVET19DTEFTU19UWVBFID0gMTtcbnZhciBST0xFX1RZUEUgPSAyO1xudmFyIFRFU1RfTkFNRV9UWVBFID0gMztcbnZhciBURVhUX1RZUEUgPSA0O1xuXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuZm9yKSB7XG4gIHZhciBzeW1ib2xGb3IgPSBTeW1ib2wuZm9yO1xuICBDT01QT05FTlRfVFlQRSA9IHN5bWJvbEZvcignc2VsZWN0b3IuY29tcG9uZW50Jyk7XG4gIEhBU19QU0VVRE9fQ0xBU1NfVFlQRSA9IHN5bWJvbEZvcignc2VsZWN0b3IuaGFzX3BzZXVkb19jbGFzcycpO1xuICBST0xFX1RZUEUgPSBzeW1ib2xGb3IoJ3NlbGVjdG9yLnJvbGUnKTtcbiAgVEVTVF9OQU1FX1RZUEUgPSBzeW1ib2xGb3IoJ3NlbGVjdG9yLnRlc3RfaWQnKTtcbiAgVEVYVF9UWVBFID0gc3ltYm9sRm9yKCdzZWxlY3Rvci50ZXh0Jyk7XG59XG52YXIgY29tbWl0SG9va3MgPSBbXTtcbmZ1bmN0aW9uIG9uQ29tbWl0Um9vdCQxKCkge1xuICB7XG4gICAgY29tbWl0SG9va3MuZm9yRWFjaChmdW5jdGlvbiAoY29tbWl0SG9vaykge1xuICAgICAgcmV0dXJuIGNvbW1pdEhvb2soKTtcbiAgICB9KTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50QWN0UXVldWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZTtcbmZ1bmN0aW9uIGlzTGVnYWN5QWN0RW52aXJvbm1lbnQoZmliZXIpIHtcbiAge1xuICAgIC8vIExlZ2FjeSBtb2RlLiBXZSBwcmVzZXJ2ZSB0aGUgYmVoYXZpb3Igb2YgUmVhY3QgMTcncyBhY3QuIEl0IGFzc3VtZXMgYW5cbiAgICAvLyBhY3QgZW52aXJvbm1lbnQgd2hlbmV2ZXIgYGplc3RgIGlzIGRlZmluZWQsIGJ1dCB5b3UgY2FuIHN0aWxsIHR1cm4gb2ZmXG4gICAgLy8gc3B1cmlvdXMgd2FybmluZ3MgYnkgc2V0dGluZyBJU19SRUFDVF9BQ1RfRU5WSVJPTk1FTlQgZXhwbGljaXRseVxuICAgIC8vIHRvIGZhbHNlLlxuICAgIHZhciBpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWwgPSAvLyAkRmxvd0V4cGVjdGVkRXJyb3IgXHUyMDEzIEZsb3cgZG9lc24ndCBrbm93IGFib3V0IElTX1JFQUNUX0FDVF9FTlZJUk9OTUVOVCBnbG9iYWxcbiAgICB0eXBlb2YgSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UICE9PSAndW5kZWZpbmVkJyA/IElTX1JFQUNUX0FDVF9FTlZJUk9OTUVOVCA6IHVuZGVmaW5lZDsgLy8gJEZsb3dFeHBlY3RlZEVycm9yIC0gRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgamVzdFxuXG4gICAgdmFyIGplc3RJc0RlZmluZWQgPSB0eXBlb2YgamVzdCAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgcmV0dXJuICBqZXN0SXNEZWZpbmVkICYmIGlzUmVhY3RBY3RFbnZpcm9ubWVudEdsb2JhbCAhPT0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkge1xuICB7XG4gICAgdmFyIGlzUmVhY3RBY3RFbnZpcm9ubWVudEdsb2JhbCA9IC8vICRGbG93RXhwZWN0ZWRFcnJvciBcdTIwMTMgRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UIGdsb2JhbFxuICAgIHR5cGVvZiBJU19SRUFDVF9BQ1RfRU5WSVJPTk1FTlQgIT09ICd1bmRlZmluZWQnID8gSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWwgJiYgUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSW5jbHVkZSBsaW5rIHRvIHJlbGV2YW50IGRvY3VtZW50YXRpb24gcGFnZS5cbiAgICAgIGVycm9yKCdUaGUgY3VycmVudCB0ZXN0aW5nIGVudmlyb25tZW50IGlzIG5vdCBjb25maWd1cmVkIHRvIHN1cHBvcnQgJyArICdhY3QoLi4uKScpO1xuICAgIH1cblxuICAgIHJldHVybiBpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWw7XG4gIH1cbn1cblxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixcbiAgICBSZWFjdEN1cnJlbnRPd25lciQyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50T3duZXIsXG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMyA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFxuICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZTtcbnZhciBOb0NvbnRleHQgPVxuLyogICAgICAgICAgICAgKi9cbjA7XG52YXIgQmF0Y2hlZENvbnRleHQgPVxuLyogICAgICAgICAgICAgICAqL1xuMTtcbnZhciBSZW5kZXJDb250ZXh0ID1cbi8qICAgICAgICAgICAgICAgICovXG4yO1xudmFyIENvbW1pdENvbnRleHQgPVxuLyogICAgICAgICAgICAgICAgKi9cbjQ7XG52YXIgUm9vdEluUHJvZ3Jlc3MgPSAwO1xudmFyIFJvb3RGYXRhbEVycm9yZWQgPSAxO1xudmFyIFJvb3RFcnJvcmVkID0gMjtcbnZhciBSb290U3VzcGVuZGVkID0gMztcbnZhciBSb290U3VzcGVuZGVkV2l0aERlbGF5ID0gNDtcbnZhciBSb290Q29tcGxldGVkID0gNTtcbnZhciBSb290RGlkTm90Q29tcGxldGUgPSA2OyAvLyBEZXNjcmliZXMgd2hlcmUgd2UgYXJlIGluIHRoZSBSZWFjdCBleGVjdXRpb24gc3RhY2tcblxudmFyIGV4ZWN1dGlvbkNvbnRleHQgPSBOb0NvbnRleHQ7IC8vIFRoZSByb290IHdlJ3JlIHdvcmtpbmcgb25cblxudmFyIHdvcmtJblByb2dyZXNzUm9vdCA9IG51bGw7IC8vIFRoZSBmaWJlciB3ZSdyZSB3b3JraW5nIG9uXG5cbnZhciB3b3JrSW5Qcm9ncmVzcyA9IG51bGw7IC8vIFRoZSBsYW5lcyB3ZSdyZSByZW5kZXJpbmdcblxudmFyIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lczsgLy8gU3RhY2sgdGhhdCBhbGxvd3MgY29tcG9uZW50cyB0byBjaGFuZ2UgdGhlIHJlbmRlciBsYW5lcyBmb3IgaXRzIHN1YnRyZWVcbi8vIFRoaXMgaXMgYSBzdXBlcnNldCBvZiB0aGUgbGFuZXMgd2Ugc3RhcnRlZCB3b3JraW5nIG9uIGF0IHRoZSByb290LiBUaGUgb25seVxuLy8gY2FzZSB3aGVyZSBpdCdzIGRpZmZlcmVudCBmcm9tIGB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lc2AgaXMgd2hlbiB3ZVxuLy8gZW50ZXIgYSBzdWJ0cmVlIHRoYXQgaXMgaGlkZGVuIGFuZCBuZWVkcyB0byBiZSB1bmhpZGRlbjogU3VzcGVuc2UgYW5kXG4vLyBPZmZzY3JlZW4gY29tcG9uZW50LlxuLy9cbi8vIE1vc3QgdGhpbmdzIGluIHRoZSB3b3JrIGxvb3Agc2hvdWxkIGRlYWwgd2l0aCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcy5cbi8vIE1vc3QgdGhpbmdzIGluIGJlZ2luL2NvbXBsZXRlIHBoYXNlcyBzaG91bGQgZGVhbCB3aXRoIHN1YnRyZWVSZW5kZXJMYW5lcy5cblxudmFyIHN1YnRyZWVSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG52YXIgc3VidHJlZVJlbmRlckxhbmVzQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKE5vTGFuZXMpOyAvLyBXaGV0aGVyIHRvIHJvb3QgY29tcGxldGVkLCBlcnJvcmVkLCBzdXNwZW5kZWQsIGV0Yy5cblxudmFyIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290SW5Qcm9ncmVzczsgLy8gQSBmYXRhbCBlcnJvciwgaWYgb25lIGlzIHRocm93blxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvciA9IG51bGw7IC8vIFwiSW5jbHVkZWRcIiBsYW5lcyByZWZlciB0byBsYW5lcyB0aGF0IHdlcmUgd29ya2VkIG9uIGR1cmluZyB0aGlzIHJlbmRlci4gSXQnc1xuLy8gc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gYHJlbmRlckxhbmVzYCBiZWNhdXNlIGByZW5kZXJMYW5lc2AgY2FuIGNoYW5nZSBhcyB5b3Vcbi8vIGVudGVyIGFuZCBleGl0IGFuIE9mZnNjcmVlbiB0cmVlLiBUaGlzIHZhbHVlIGlzIHRoZSBjb21iaW5hdGlvbiBvZiBhbGwgcmVuZGVyXG4vLyBsYW5lcyBmb3IgdGhlIGVudGlyZSByZW5kZXIgcGhhc2UuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzID0gTm9MYW5lczsgLy8gVGhlIHdvcmsgbGVmdCBvdmVyIGJ5IGNvbXBvbmVudHMgdGhhdCB3ZXJlIHZpc2l0ZWQgZHVyaW5nIHRoaXMgcmVuZGVyLiBPbmx5XG4vLyBpbmNsdWRlcyB1bnByb2Nlc3NlZCB1cGRhdGVzLCBub3Qgd29yayBpbiBiYWlsZWQgb3V0IGNoaWxkcmVuLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzID0gTm9MYW5lczsgLy8gTGFuZXMgdGhhdCB3ZXJlIHVwZGF0ZWQgKGluIGFuIGludGVybGVhdmVkIGV2ZW50KSBkdXJpbmcgdGhpcyByZW5kZXIuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IE5vTGFuZXM7IC8vIExhbmVzIHRoYXQgd2VyZSB1cGRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlICgqbm90KiBhbiBpbnRlcmxlYXZlZCBldmVudCkuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcyA9IE5vTGFuZXM7IC8vIEVycm9ycyB0aGF0IGFyZSB0aHJvd24gZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzID0gbnVsbDsgLy8gVGhlc2UgYXJlIGVycm9ycyB0aGF0IHdlIHJlY292ZXJlZCBmcm9tIHdpdGhvdXQgc3VyZmFjaW5nIHRoZW0gdG8gdGhlIFVJLlxuLy8gV2Ugd2lsbCBsb2cgdGhlbSBvbmNlIHRoZSB0cmVlIGNvbW1pdHMuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycyA9IG51bGw7IC8vIFRoZSBtb3N0IHJlY2VudCB0aW1lIHdlIGNvbW1pdHRlZCBhIGZhbGxiYWNrLiBUaGlzIGxldHMgdXMgZW5zdXJlIGEgdHJhaW5cbi8vIG1vZGVsIHdoZXJlIHdlIGRvbid0IGNvbW1pdCBuZXcgbG9hZGluZyBzdGF0ZXMgaW4gdG9vIHF1aWNrIHN1Y2Nlc3Npb24uXG5cbnZhciBnbG9iYWxNb3N0UmVjZW50RmFsbGJhY2tUaW1lID0gMDtcbnZhciBGQUxMQkFDS19USFJPVFRMRV9NUyA9IDUwMDsgLy8gVGhlIGFic29sdXRlIHRpbWUgZm9yIHdoZW4gd2Ugc2hvdWxkIHN0YXJ0IGdpdmluZyB1cCBvbiByZW5kZXJpbmdcbi8vIG1vcmUgYW5kIHByZWZlciBDUFUgc3VzcGVuc2UgaGV1cmlzdGljcyBpbnN0ZWFkLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyVGFyZ2V0VGltZSA9IEluZmluaXR5OyAvLyBIb3cgbG9uZyBhIHJlbmRlciBpcyBzdXBwb3NlZCB0byB0YWtlIGJlZm9yZSB3ZSBzdGFydCBmb2xsb3dpbmcgQ1BVXG4vLyBzdXNwZW5zZSBoZXVyaXN0aWNzIGFuZCBvcHQgb3V0IG9mIHJlbmRlcmluZyBtb3JlIGNvbnRlbnQuXG5cbnZhciBSRU5ERVJfVElNRU9VVF9NUyA9IDUwMDtcbnZhciB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zID0gbnVsbDtcblxuZnVuY3Rpb24gcmVzZXRSZW5kZXJUaW1lcigpIHtcbiAgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyVGFyZ2V0VGltZSA9IG5vdygpICsgUkVOREVSX1RJTUVPVVRfTVM7XG59XG5cbmZ1bmN0aW9uIGdldFJlbmRlclRhcmdldFRpbWUoKSB7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJUYXJnZXRUaW1lO1xufVxudmFyIGhhc1VuY2F1Z2h0RXJyb3IgPSBmYWxzZTtcbnZhciBmaXJzdFVuY2F1Z2h0RXJyb3IgPSBudWxsO1xudmFyIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID0gbnVsbDsgLy8gT25seSB1c2VkIHdoZW4gZW5hYmxlUHJvZmlsZXJOZXN0ZWRVcGRhdGVTY2hlZHVsZWRIb29rIGlzIHRydWU7XG52YXIgcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbnZhciByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyA9IG51bGw7XG52YXIgcGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMgPSBOb0xhbmVzO1xudmFyIHBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3RzID0gW107XG52YXIgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IG51bGw7IC8vIFVzZSB0aGVzZSB0byBwcmV2ZW50IGFuIGluZmluaXRlIGxvb3Agb2YgbmVzdGVkIHVwZGF0ZXNcblxudmFyIE5FU1RFRF9VUERBVEVfTElNSVQgPSA1MDtcbnZhciBuZXN0ZWRVcGRhdGVDb3VudCA9IDA7XG52YXIgcm9vdFdpdGhOZXN0ZWRVcGRhdGVzID0gbnVsbDtcbnZhciBpc0ZsdXNoaW5nUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbnZhciBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG52YXIgTkVTVEVEX1BBU1NJVkVfVVBEQVRFX0xJTUlUID0gNTA7XG52YXIgbmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID0gMDtcbnZhciByb290V2l0aFBhc3NpdmVOZXN0ZWRVcGRhdGVzID0gbnVsbDsgLy8gSWYgdHdvIHVwZGF0ZXMgYXJlIHNjaGVkdWxlZCB3aXRoaW4gdGhlIHNhbWUgZXZlbnQsIHdlIHNob3VsZCB0cmVhdCB0aGVpclxuLy8gZXZlbnQgdGltZXMgYXMgc2ltdWx0YW5lb3VzLCBldmVuIGlmIHRoZSBhY3R1YWwgY2xvY2sgdGltZSBoYXMgYWR2YW5jZWRcbi8vIGJldHdlZW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgY2FsbC5cblxudmFyIGN1cnJlbnRFdmVudFRpbWUgPSBOb1RpbWVzdGFtcDtcbnZhciBjdXJyZW50RXZlbnRUcmFuc2l0aW9uTGFuZSA9IE5vTGFuZXM7XG52YXIgaXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0ID0gZmFsc2U7XG5mdW5jdGlvbiBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKSB7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3Q7XG59XG5mdW5jdGlvbiByZXF1ZXN0RXZlbnRUaW1lKCkge1xuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgLy8gV2UncmUgaW5zaWRlIFJlYWN0LCBzbyBpdCdzIGZpbmUgdG8gcmVhZCB0aGUgYWN0dWFsIHRpbWUuXG4gICAgcmV0dXJuIG5vdygpO1xuICB9IC8vIFdlJ3JlIG5vdCBpbnNpZGUgUmVhY3QsIHNvIHdlIG1heSBiZSBpbiB0aGUgbWlkZGxlIG9mIGEgYnJvd3NlciBldmVudC5cblxuXG4gIGlmIChjdXJyZW50RXZlbnRUaW1lICE9PSBOb1RpbWVzdGFtcCkge1xuICAgIC8vIFVzZSB0aGUgc2FtZSBzdGFydCB0aW1lIGZvciBhbGwgdXBkYXRlcyB1bnRpbCB3ZSBlbnRlciBSZWFjdCBhZ2Fpbi5cbiAgICByZXR1cm4gY3VycmVudEV2ZW50VGltZTtcbiAgfSAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUgc2luY2UgUmVhY3QgeWllbGRlZC4gQ29tcHV0ZSBhIG5ldyBzdGFydCB0aW1lLlxuXG5cbiAgY3VycmVudEV2ZW50VGltZSA9IG5vdygpO1xuICByZXR1cm4gY3VycmVudEV2ZW50VGltZTtcbn1cbmZ1bmN0aW9uIHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKSB7XG4gIC8vIFNwZWNpYWwgY2FzZXNcbiAgdmFyIG1vZGUgPSBmaWJlci5tb2RlO1xuXG4gIGlmICgobW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIFN5bmNMYW5lO1xuICB9IGVsc2UgaWYgKCAoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHQgJiYgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICAvLyBUaGlzIGlzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gVGhlc2UgYXJlIG5vdCBvZmZpY2lhbGx5IHN1cHBvcnRlZC4gVGhlXG4gICAgLy8gb2xkIGJlaGF2aW9yIGlzIHRvIGdpdmUgdGhpcyB0aGUgc2FtZSBcInRocmVhZFwiIChsYW5lcykgYXNcbiAgICAvLyB3aGF0ZXZlciBpcyBjdXJyZW50bHkgcmVuZGVyaW5nLiBTbyBpZiB5b3UgY2FsbCBgc2V0U3RhdGVgIG9uIGEgY29tcG9uZW50XG4gICAgLy8gdGhhdCBoYXBwZW5zIGxhdGVyIGluIHRoZSBzYW1lIHJlbmRlciwgaXQgd2lsbCBmbHVzaC4gSWRlYWxseSwgd2Ugd2FudCB0b1xuICAgIC8vIHJlbW92ZSB0aGUgc3BlY2lhbCBjYXNlIGFuZCB0cmVhdCB0aGVtIGFzIGlmIHRoZXkgY2FtZSBmcm9tIGFuXG4gICAgLy8gaW50ZXJsZWF2ZWQgZXZlbnQuIFJlZ2FyZGxlc3MsIHRoaXMgcGF0dGVybiBpcyBub3Qgb2ZmaWNpYWxseSBzdXBwb3J0ZWQuXG4gICAgLy8gVGhpcyBiZWhhdmlvciBpcyBvbmx5IGEgZmFsbGJhY2suIFRoZSBmbGFnIG9ubHkgZXhpc3RzIHVudGlsIHdlIGNhbiByb2xsXG4gICAgLy8gb3V0IHRoZSBzZXRTdGF0ZSB3YXJuaW5nLCBzaW5jZSBleGlzdGluZyBjb2RlIG1pZ2h0IGFjY2lkZW50YWxseSByZWx5IG9uXG4gICAgLy8gdGhlIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAgcmV0dXJuIHBpY2tBcmJpdHJhcnlMYW5lKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHZhciBpc1RyYW5zaXRpb24gPSByZXF1ZXN0Q3VycmVudFRyYW5zaXRpb24oKSAhPT0gTm9UcmFuc2l0aW9uO1xuXG4gIGlmIChpc1RyYW5zaXRpb24pIHtcbiAgICBpZiAoIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiAhPT0gbnVsbCkge1xuICAgICAgdmFyIHRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb247XG5cbiAgICAgIGlmICghdHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycykge1xuICAgICAgICB0cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzID0gbmV3IFNldCgpO1xuICAgICAgfVxuXG4gICAgICB0cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLmFkZChmaWJlcik7XG4gICAgfSAvLyBUaGUgYWxnb3JpdGhtIGZvciBhc3NpZ25pbmcgYW4gdXBkYXRlIHRvIGEgbGFuZSBzaG91bGQgYmUgc3RhYmxlIGZvciBhbGxcbiAgICAvLyB1cGRhdGVzIGF0IHRoZSBzYW1lIHByaW9yaXR5IHdpdGhpbiB0aGUgc2FtZSBldmVudC4gVG8gZG8gdGhpcywgdGhlXG4gICAgLy8gaW5wdXRzIHRvIHRoZSBhbGdvcml0aG0gbXVzdCBiZSB0aGUgc2FtZS5cbiAgICAvL1xuICAgIC8vIFRoZSB0cmljayB3ZSB1c2UgaXMgdG8gY2FjaGUgdGhlIGZpcnN0IG9mIGVhY2ggb2YgdGhlc2UgaW5wdXRzIHdpdGhpbiBhblxuICAgIC8vIGV2ZW50LiBUaGVuIHJlc2V0IHRoZSBjYWNoZWQgdmFsdWVzIG9uY2Ugd2UgY2FuIGJlIHN1cmUgdGhlIGV2ZW50IGlzXG4gICAgLy8gb3Zlci4gT3VyIGhldXJpc3RpYyBmb3IgdGhhdCBpcyB3aGVuZXZlciB3ZSBlbnRlciBhIGNvbmN1cnJlbnQgd29yayBsb29wLlxuXG5cbiAgICBpZiAoY3VycmVudEV2ZW50VHJhbnNpdGlvbkxhbmUgPT09IE5vTGFuZSkge1xuICAgICAgLy8gQWxsIHRyYW5zaXRpb25zIHdpdGhpbiB0aGUgc2FtZSBldmVudCBhcmUgYXNzaWduZWQgdGhlIHNhbWUgbGFuZS5cbiAgICAgIGN1cnJlbnRFdmVudFRyYW5zaXRpb25MYW5lID0gY2xhaW1OZXh0VHJhbnNpdGlvbkxhbmUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudEV2ZW50VHJhbnNpdGlvbkxhbmU7XG4gIH0gLy8gVXBkYXRlcyBvcmlnaW5hdGluZyBpbnNpZGUgY2VydGFpbiBSZWFjdCBtZXRob2RzLCBsaWtlIGZsdXNoU3luYywgaGF2ZVxuICAvLyB0aGVpciBwcmlvcml0eSBzZXQgYnkgdHJhY2tpbmcgaXQgd2l0aCBhIGNvbnRleHQgdmFyaWFibGUuXG4gIC8vXG4gIC8vIFRoZSBvcGFxdWUgdHlwZSByZXR1cm5lZCBieSB0aGUgaG9zdCBjb25maWcgaXMgaW50ZXJuYWxseSBhIGxhbmUsIHNvIHdlIGNhblxuICAvLyB1c2UgdGhhdCBkaXJlY3RseS5cbiAgLy8gVE9ETzogTW92ZSB0aGlzIHR5cGUgY29udmVyc2lvbiB0byB0aGUgZXZlbnQgcHJpb3JpdHkgbW9kdWxlLlxuXG5cbiAgdmFyIHVwZGF0ZUxhbmUgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcblxuICBpZiAodXBkYXRlTGFuZSAhPT0gTm9MYW5lKSB7XG4gICAgcmV0dXJuIHVwZGF0ZUxhbmU7XG4gIH0gLy8gVGhpcyB1cGRhdGUgb3JpZ2luYXRlZCBvdXRzaWRlIFJlYWN0LiBBc2sgdGhlIGhvc3QgZW52aXJvbm1lbnQgZm9yIGFuXG4gIC8vIGFwcHJvcHJpYXRlIHByaW9yaXR5LCBiYXNlZCBvbiB0aGUgdHlwZSBvZiBldmVudC5cbiAgLy9cbiAgLy8gVGhlIG9wYXF1ZSB0eXBlIHJldHVybmVkIGJ5IHRoZSBob3N0IGNvbmZpZyBpcyBpbnRlcm5hbGx5IGEgbGFuZSwgc28gd2UgY2FuXG4gIC8vIHVzZSB0aGF0IGRpcmVjdGx5LlxuICAvLyBUT0RPOiBNb3ZlIHRoaXMgdHlwZSBjb252ZXJzaW9uIHRvIHRoZSBldmVudCBwcmlvcml0eSBtb2R1bGUuXG5cblxuICB2YXIgZXZlbnRMYW5lID0gZ2V0Q3VycmVudEV2ZW50UHJpb3JpdHkoKTtcbiAgcmV0dXJuIGV2ZW50TGFuZTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFJldHJ5TGFuZShmaWJlcikge1xuICAvLyBUaGlzIGlzIGEgZm9yayBvZiBgcmVxdWVzdFVwZGF0ZUxhbmVgIGRlc2lnbmVkIHNwZWNpZmljYWxseSBmb3IgU3VzcGVuc2VcbiAgLy8gXCJyZXRyaWVzXCIgXHUyMDE0IGEgc3BlY2lhbCB1cGRhdGUgdGhhdCBhdHRlbXB0cyB0byBmbGlwIGEgU3VzcGVuc2UgYm91bmRhcnlcbiAgLy8gZnJvbSBpdHMgcGxhY2Vob2xkZXIgc3RhdGUgdG8gaXRzIHByaW1hcnkvcmVzb2x2ZWQgc3RhdGUuXG4gIC8vIFNwZWNpYWwgY2FzZXNcbiAgdmFyIG1vZGUgPSBmaWJlci5tb2RlO1xuXG4gIGlmICgobW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIFN5bmNMYW5lO1xuICB9XG5cbiAgcmV0dXJuIGNsYWltTmV4dFJldHJ5TGFuZSgpO1xufVxuXG5mdW5jdGlvbiBzY2hlZHVsZVVwZGF0ZU9uRmliZXIoZmliZXIsIGxhbmUsIGV2ZW50VGltZSkge1xuICBjaGVja0Zvck5lc3RlZFVwZGF0ZXMoKTtcblxuICB7XG4gICAgaWYgKGlzUnVubmluZ0luc2VydGlvbkVmZmVjdCkge1xuICAgICAgZXJyb3IoJ3VzZUluc2VydGlvbkVmZmVjdCBtdXN0IG5vdCBzY2hlZHVsZSB1cGRhdGVzLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3QoZmliZXIsIGxhbmUpO1xuXG4gIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB7XG4gICAgaWYgKGlzRmx1c2hpbmdQYXNzaXZlRWZmZWN0cykge1xuICAgICAgZGlkU2NoZWR1bGVVcGRhdGVEdXJpbmdQYXNzaXZlRWZmZWN0cyA9IHRydWU7XG4gICAgfVxuICB9IC8vIE1hcmsgdGhhdCB0aGUgcm9vdCBoYXMgYSBwZW5kaW5nIHVwZGF0ZS5cblxuXG4gIG1hcmtSb290VXBkYXRlZChyb290LCBsYW5lLCBldmVudFRpbWUpO1xuXG4gIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0xhbmVzICYmIHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCkge1xuICAgIC8vIFRoaXMgdXBkYXRlIHdhcyBkaXNwYXRjaGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlLiBUaGlzIGlzIGEgbWlzdGFrZVxuICAgIC8vIGlmIHRoZSB1cGRhdGUgb3JpZ2luYXRlcyBmcm9tIHVzZXIgc3BhY2UgKHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBsb2NhbFxuICAgIC8vIGhvb2sgdXBkYXRlcywgd2hpY2ggYXJlIGhhbmRsZWQgZGlmZmVyZW50bHkgYW5kIGRvbid0IHJlYWNoIHRoaXNcbiAgICAvLyBmdW5jdGlvbiksIGJ1dCB0aGVyZSBhcmUgc29tZSBpbnRlcm5hbCBSZWFjdCBmZWF0dXJlcyB0aGF0IHVzZSB0aGlzIGFzXG4gICAgLy8gYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLCBsaWtlIHNlbGVjdGl2ZSBoeWRyYXRpb24uXG4gICAgd2FybkFib3V0UmVuZGVyUGhhc2VVcGRhdGVzSW5ERVYoZmliZXIpOyAvLyBUcmFjayBsYW5lcyB0aGF0IHdlcmUgdXBkYXRlZCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZVxuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSBub3JtYWwgdXBkYXRlLCBzY2hlZHVsZWQgZnJvbSBvdXRzaWRlIHRoZSByZW5kZXIgcGhhc2UuIEZvclxuICAgIC8vIGV4YW1wbGUsIGR1cmluZyBhbiBpbnB1dCBldmVudC5cbiAgICB7XG4gICAgICBpZiAoaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICAgICAgYWRkRmliZXJUb0xhbmVzTWFwKHJvb3QsIGZpYmVyLCBsYW5lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3YXJuSWZVcGRhdGVzTm90V3JhcHBlZFdpdGhBY3RERVYoZmliZXIpO1xuXG4gICAgaWYgKHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCkge1xuICAgICAgLy8gVE9ETzogQ29uc29saWRhdGUgd2l0aCBgaXNJbnRlcmxlYXZlZFVwZGF0ZWAgY2hlY2tcbiAgICAgIC8vIFJlY2VpdmVkIGFuIHVwZGF0ZSB0byBhIHRyZWUgdGhhdCdzIGluIHRoZSBtaWRkbGUgb2YgcmVuZGVyaW5nLiBNYXJrXG4gICAgICAvLyB0aGF0IHRoZXJlIHdhcyBhbiBpbnRlcmxlYXZlZCB1cGRhdGUgd29yayBvbiB0aGlzIHJvb3QuIFVubGVzcyB0aGVcbiAgICAgIC8vIGBkZWZlclJlbmRlclBoYXNlVXBkYXRlVG9OZXh0QmF0Y2hgIGZsYWcgaXMgb2ZmIGFuZCB0aGlzIGlzIGEgcmVuZGVyXG4gICAgICAvLyBwaGFzZSB1cGRhdGUuIEluIHRoYXQgY2FzZSwgd2UgZG9uJ3QgdHJlYXQgcmVuZGVyIHBoYXNlIHVwZGF0ZXMgYXMgaWZcbiAgICAgIC8vIHRoZXkgd2VyZSBpbnRlcmxlYXZlZCwgZm9yIGJhY2t3YXJkcyBjb21wYXQgcmVhc29ucy5cbiAgICAgIGlmICggKGV4ZWN1dGlvbkNvbnRleHQgJiBSZW5kZXJDb250ZXh0KSA9PT0gTm9Db250ZXh0KSB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzUm9vdEludGVybGVhdmVkVXBkYXRlZExhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcywgbGFuZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290U3VzcGVuZGVkV2l0aERlbGF5KSB7XG4gICAgICAgIC8vIFRoZSByb290IGFscmVhZHkgc3VzcGVuZGVkIHdpdGggYSBkZWxheSwgd2hpY2ggbWVhbnMgdGhpcyByZW5kZXJcbiAgICAgICAgLy8gZGVmaW5pdGVseSB3b24ndCBmaW5pc2guIFNpbmNlIHdlIGhhdmUgYSBuZXcgdXBkYXRlLCBsZXQncyBtYXJrIGl0IGFzXG4gICAgICAgIC8vIHN1c3BlbmRlZCBub3csIHJpZ2h0IGJlZm9yZSBtYXJraW5nIHRoZSBpbmNvbWluZyB1cGRhdGUuIFRoaXMgaGFzIHRoZVxuICAgICAgICAvLyBlZmZlY3Qgb2YgaW50ZXJydXB0aW5nIHRoZSBjdXJyZW50IHJlbmRlciBhbmQgc3dpdGNoaW5nIHRvIHRoZSB1cGRhdGUuXG4gICAgICAgIC8vIFRPRE86IE1ha2Ugc3VyZSB0aGlzIGRvZXNuJ3Qgb3ZlcnJpZGUgcGluZ3MgdGhhdCBoYXBwZW4gd2hpbGUgd2UndmVcbiAgICAgICAgLy8gYWxyZWFkeSBzdGFydGVkIHJlbmRlcmluZy5cbiAgICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIGV2ZW50VGltZSk7XG5cbiAgICBpZiAobGFuZSA9PT0gU3luY0xhbmUgJiYgZXhlY3V0aW9uQ29udGV4dCA9PT0gTm9Db250ZXh0ICYmIChmaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgLy8gVHJlYXQgYGFjdGAgYXMgaWYgaXQncyBpbnNpZGUgYGJhdGNoZWRVcGRhdGVzYCwgZXZlbiBpbiBsZWdhY3kgbW9kZS5cbiAgICAhKCBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmlzQmF0Y2hpbmdMZWdhY3kpKSB7XG4gICAgICAvLyBGbHVzaCB0aGUgc3luY2hyb25vdXMgd29yayBub3csIHVubGVzcyB3ZSdyZSBhbHJlYWR5IHdvcmtpbmcgb3IgaW5zaWRlXG4gICAgICAvLyBhIGJhdGNoLiBUaGlzIGlzIGludGVudGlvbmFsbHkgaW5zaWRlIHNjaGVkdWxlVXBkYXRlT25GaWJlciBpbnN0ZWFkIG9mXG4gICAgICAvLyBzY2hlZHVsZUNhbGxiYWNrRm9yRmliZXIgdG8gcHJlc2VydmUgdGhlIGFiaWxpdHkgdG8gc2NoZWR1bGUgYSBjYWxsYmFja1xuICAgICAgLy8gd2l0aG91dCBpbW1lZGlhdGVseSBmbHVzaGluZyBpdC4gV2Ugb25seSBkbyB0aGlzIGZvciB1c2VyLWluaXRpYXRlZFxuICAgICAgLy8gdXBkYXRlcywgdG8gcHJlc2VydmUgaGlzdG9yaWNhbCBiZWhhdmlvciBvZiBsZWdhY3kgbW9kZS5cbiAgICAgIHJlc2V0UmVuZGVyVGltZXIoKTtcbiAgICAgIGZsdXNoU3luY0NhbGxiYWNrc09ubHlJbkxlZ2FjeU1vZGUoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcm9vdDtcbn1cbmZ1bmN0aW9uIHNjaGVkdWxlSW5pdGlhbEh5ZHJhdGlvbk9uUm9vdChyb290LCBsYW5lLCBldmVudFRpbWUpIHtcbiAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgZm9yayBvZiBzY2hlZHVsZVVwZGF0ZU9uRmliZXIgdGhhdCBpcyBvbmx5IHVzZWQgdG9cbiAgLy8gc2NoZWR1bGUgdGhlIGluaXRpYWwgaHlkcmF0aW9uIG9mIGEgcm9vdCB0aGF0IGhhcyBqdXN0IGJlZW4gY3JlYXRlZC4gTW9zdFxuICAvLyBvZiB0aGUgc3R1ZmYgaW4gc2NoZWR1bGVVcGRhdGVPbkZpYmVyIGNhbiBiZSBza2lwcGVkLlxuICAvL1xuICAvLyBUaGUgbWFpbiByZWFzb24gZm9yIHRoaXMgc2VwYXJhdGUgcGF0aCwgdGhvdWdoLCBpcyB0byBkaXN0aW5ndWlzaCB0aGVcbiAgLy8gaW5pdGlhbCBjaGlsZHJlbiBmcm9tIHN1YnNlcXVlbnQgdXBkYXRlcy4gSW4gZnVsbHkgY2xpZW50LXJlbmRlcmVkIHJvb3RzXG4gIC8vIChjcmVhdGVSb290IGluc3RlYWQgb2YgaHlkcmF0ZVJvb3QpLCBhbGwgdG9wLWxldmVsIHJlbmRlcnMgYXJlIG1vZGVsZWQgYXNcbiAgLy8gdXBkYXRlcywgYnV0IGh5ZHJhdGlvbiByb290cyBhcmUgc3BlY2lhbCBiZWNhdXNlIHRoZSBpbml0aWFsIHJlbmRlciBtdXN0XG4gIC8vIG1hdGNoIHdoYXQgd2FzIHJlbmRlcmVkIG9uIHRoZSBzZXJ2ZXIuXG4gIHZhciBjdXJyZW50ID0gcm9vdC5jdXJyZW50O1xuICBjdXJyZW50LmxhbmVzID0gbGFuZTtcbiAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIGxhbmUsIGV2ZW50VGltZSk7XG4gIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xufSAvLyBUaGlzIGlzIHNwbGl0IGludG8gYSBzZXBhcmF0ZSBmdW5jdGlvbiBzbyB3ZSBjYW4gbWFyayBhIGZpYmVyIHdpdGggcGVuZGluZ1xuLy8gd29yayB3aXRob3V0IHRyZWF0aW5nIGl0IGFzIGEgdHlwaWNhbCB1cGRhdGUgdGhhdCBvcmlnaW5hdGVzIGZyb20gYW4gZXZlbnQ7XG4vLyBlLmcuIHJldHJ5aW5nIGEgU3VzcGVuc2UgYm91bmRhcnkgaXNuJ3QgYW4gdXBkYXRlLCBidXQgaXQgZG9lcyBzY2hlZHVsZSB3b3JrXG4vLyBvbiBhIGZpYmVyLlxuXG5mdW5jdGlvbiBtYXJrVXBkYXRlTGFuZUZyb21GaWJlclRvUm9vdChzb3VyY2VGaWJlciwgbGFuZSkge1xuICAvLyBVcGRhdGUgdGhlIHNvdXJjZSBmaWJlcidzIGxhbmVzXG4gIHNvdXJjZUZpYmVyLmxhbmVzID0gbWVyZ2VMYW5lcyhzb3VyY2VGaWJlci5sYW5lcywgbGFuZSk7XG4gIHZhciBhbHRlcm5hdGUgPSBzb3VyY2VGaWJlci5hbHRlcm5hdGU7XG5cbiAgaWYgKGFsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgIGFsdGVybmF0ZS5sYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmxhbmVzLCBsYW5lKTtcbiAgfVxuXG4gIHtcbiAgICBpZiAoYWx0ZXJuYXRlID09PSBudWxsICYmIChzb3VyY2VGaWJlci5mbGFncyAmIChQbGFjZW1lbnQgfCBIeWRyYXRpbmcpKSAhPT0gTm9GbGFncykge1xuICAgICAgd2FybkFib3V0VXBkYXRlT25Ob3RZZXRNb3VudGVkRmliZXJJbkRFVihzb3VyY2VGaWJlcik7XG4gICAgfVxuICB9IC8vIFdhbGsgdGhlIHBhcmVudCBwYXRoIHRvIHRoZSByb290IGFuZCB1cGRhdGUgdGhlIGNoaWxkIGxhbmVzLlxuXG5cbiAgdmFyIG5vZGUgPSBzb3VyY2VGaWJlcjtcbiAgdmFyIHBhcmVudCA9IHNvdXJjZUZpYmVyLnJldHVybjtcblxuICB3aGlsZSAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgcGFyZW50LmNoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKHBhcmVudC5jaGlsZExhbmVzLCBsYW5lKTtcbiAgICBhbHRlcm5hdGUgPSBwYXJlbnQuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGFsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgYWx0ZXJuYXRlLmNoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKGFsdGVybmF0ZS5jaGlsZExhbmVzLCBsYW5lKTtcbiAgICB9IGVsc2Uge1xuICAgICAge1xuICAgICAgICBpZiAoKHBhcmVudC5mbGFncyAmIChQbGFjZW1lbnQgfCBIeWRyYXRpbmcpKSAhPT0gTm9GbGFncykge1xuICAgICAgICAgIHdhcm5BYm91dFVwZGF0ZU9uTm90WWV0TW91bnRlZEZpYmVySW5ERVYoc291cmNlRmliZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgbm9kZSA9IHBhcmVudDtcbiAgICBwYXJlbnQgPSBwYXJlbnQucmV0dXJuO1xuICB9XG5cbiAgaWYgKG5vZGUudGFnID09PSBIb3N0Um9vdCkge1xuICAgIHZhciByb290ID0gbm9kZS5zdGF0ZU5vZGU7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNJbnRlcmxlYXZlZFVwZGF0ZShmaWJlciwgbGFuZSkge1xuICByZXR1cm4gKC8vIFRPRE86IE9wdGltaXplIHNsaWdodGx5IGJ5IGNvbXBhcmluZyB0byByb290IHRoYXQgZmliZXIgYmVsb25ncyB0by5cbiAgICAvLyBSZXF1aXJlcyBzb21lIHJlZmFjdG9yaW5nLiBOb3QgYSBiaWcgZGVhbCB0aG91Z2ggc2luY2UgaXQncyByYXJlIGZvclxuICAgIC8vIGNvbmN1cnJlbnQgYXBwcyB0byBoYXZlIG1vcmUgdGhhbiBhIHNpbmdsZSByb290LlxuICAgICh3b3JrSW5Qcm9ncmVzc1Jvb3QgIT09IG51bGwgfHwgLy8gSWYgdGhlIGludGVybGVhdmVkIHVwZGF0ZXMgcXVldWUgaGFzbid0IGJlZW4gY2xlYXJlZCB5ZXQsIHRoZW5cbiAgICAvLyB3ZSBzaG91bGQgdHJlYXQgdGhpcyBhcyBhbiBpbnRlcmxlYXZlZCB1cGRhdGUsIHRvby4gVGhpcyBpcyBhbHNvIGFcbiAgICAvLyBkZWZlbnNpdmUgY29kaW5nIG1lYXN1cmUgaW4gY2FzZSBhIG5ldyB1cGRhdGUgY29tZXMgaW4gYmV0d2VlbiB3aGVuXG4gICAgLy8gcmVuZGVyaW5nIGhhcyBmaW5pc2hlZCBhbmQgd2hlbiB0aGUgaW50ZXJsZWF2ZWQgdXBkYXRlcyBhcmUgdHJhbnNmZXJyZWRcbiAgICAvLyB0byB0aGUgbWFpbiBxdWV1ZS5cbiAgICBoYXNJbnRlcmxlYXZlZFVwZGF0ZXMoKSkgJiYgKGZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSAmJiAoIC8vIElmIHRoaXMgaXMgYSByZW5kZXIgcGhhc2UgdXBkYXRlIChpLmUuIFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKSxcbiAgICAvLyB0aGVuIGRvbid0IHRyZWF0IHRoaXMgYXMgYW4gaW50ZXJsZWF2ZWQgdXBkYXRlLiBUaGlzIHBhdHRlcm4gaXNcbiAgICAvLyBhY2NvbXBhbmllZCBieSBhIHdhcm5pbmcgYnV0IHdlIGhhdmVuJ3QgZnVsbHkgZGVwcmVjYXRlZCBpdCB5ZXQuIFdlIGNhblxuICAgIC8vIHJlbW92ZSBvbmNlIHRoZSBkZWZlclJlbmRlclBoYXNlVXBkYXRlVG9OZXh0QmF0Y2ggZmxhZyBpcyBlbmFibGVkLlxuICAgICAoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpID09PSBOb0NvbnRleHQpXG4gICk7XG59IC8vIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIHNjaGVkdWxlIGEgdGFzayBmb3IgYSByb290LiBUaGVyZSdzIG9ubHkgb25lIHRhc2sgcGVyXG4vLyByb290OyBpZiBhIHRhc2sgd2FzIGFscmVhZHkgc2NoZWR1bGVkLCB3ZSdsbCBjaGVjayB0byBtYWtlIHN1cmUgdGhlIHByaW9yaXR5XG4vLyBvZiB0aGUgZXhpc3RpbmcgdGFzayBpcyB0aGUgc2FtZSBhcyB0aGUgcHJpb3JpdHkgb2YgdGhlIG5leHQgbGV2ZWwgdGhhdCB0aGVcbi8vIHJvb3QgaGFzIHdvcmsgb24uIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGV2ZXJ5IHVwZGF0ZSwgYW5kIHJpZ2h0IGJlZm9yZVxuLy8gZXhpdGluZyBhIHRhc2suXG5cbmZ1bmN0aW9uIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBjdXJyZW50VGltZSkge1xuICB2YXIgZXhpc3RpbmdDYWxsYmFja05vZGUgPSByb290LmNhbGxiYWNrTm9kZTsgLy8gQ2hlY2sgaWYgYW55IGxhbmVzIGFyZSBiZWluZyBzdGFydmVkIGJ5IG90aGVyIHdvcmsuIElmIHNvLCBtYXJrIHRoZW0gYXNcbiAgLy8gZXhwaXJlZCBzbyB3ZSBrbm93IHRvIHdvcmsgb24gdGhvc2UgbmV4dC5cblxuICBtYXJrU3RhcnZlZExhbmVzQXNFeHBpcmVkKHJvb3QsIGN1cnJlbnRUaW1lKTsgLy8gRGV0ZXJtaW5lIHRoZSBuZXh0IGxhbmVzIHRvIHdvcmsgb24sIGFuZCB0aGVpciBwcmlvcml0eS5cblxuICB2YXIgbmV4dExhbmVzID0gZ2V0TmV4dExhbmVzKHJvb3QsIHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCA/IHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzIDogTm9MYW5lcyk7XG5cbiAgaWYgKG5leHRMYW5lcyA9PT0gTm9MYW5lcykge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogVGhlcmUncyBub3RoaW5nIHRvIHdvcmsgb24uXG4gICAgaWYgKGV4aXN0aW5nQ2FsbGJhY2tOb2RlICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxDYWxsYmFjayQxKGV4aXN0aW5nQ2FsbGJhY2tOb2RlKTtcbiAgICB9XG5cbiAgICByb290LmNhbGxiYWNrTm9kZSA9IG51bGw7XG4gICAgcm9vdC5jYWxsYmFja1ByaW9yaXR5ID0gTm9MYW5lO1xuICAgIHJldHVybjtcbiAgfSAvLyBXZSB1c2UgdGhlIGhpZ2hlc3QgcHJpb3JpdHkgbGFuZSB0byByZXByZXNlbnQgdGhlIHByaW9yaXR5IG9mIHRoZSBjYWxsYmFjay5cblxuXG4gIHZhciBuZXdDYWxsYmFja1ByaW9yaXR5ID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShuZXh0TGFuZXMpOyAvLyBDaGVjayBpZiB0aGVyZSdzIGFuIGV4aXN0aW5nIHRhc2suIFdlIG1heSBiZSBhYmxlIHRvIHJldXNlIGl0LlxuXG4gIHZhciBleGlzdGluZ0NhbGxiYWNrUHJpb3JpdHkgPSByb290LmNhbGxiYWNrUHJpb3JpdHk7XG5cbiAgaWYgKGV4aXN0aW5nQ2FsbGJhY2tQcmlvcml0eSA9PT0gbmV3Q2FsbGJhY2tQcmlvcml0eSAmJiAvLyBTcGVjaWFsIGNhc2UgcmVsYXRlZCB0byBgYWN0YC4gSWYgdGhlIGN1cnJlbnRseSBzY2hlZHVsZWQgdGFzayBpcyBhXG4gIC8vIFNjaGVkdWxlciB0YXNrLCByYXRoZXIgdGhhbiBhbiBgYWN0YCB0YXNrLCBjYW5jZWwgaXQgYW5kIHJlLXNjaGVkdWxlZFxuICAvLyBvbiB0aGUgYGFjdGAgcXVldWUuXG4gICEoIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudCAhPT0gbnVsbCAmJiBleGlzdGluZ0NhbGxiYWNrTm9kZSAhPT0gZmFrZUFjdENhbGxiYWNrTm9kZSkpIHtcbiAgICB7XG4gICAgICAvLyBJZiB3ZSdyZSBnb2luZyB0byByZS11c2UgYW4gZXhpc3RpbmcgdGFzaywgaXQgbmVlZHMgdG8gZXhpc3QuXG4gICAgICAvLyBBc3N1bWUgdGhhdCBkaXNjcmV0ZSB1cGRhdGUgbWljcm90YXNrcyBhcmUgbm9uLWNhbmNlbGxhYmxlIGFuZCBudWxsLlxuICAgICAgLy8gVE9ETzogVGVtcG9yYXJ5IHVudGlsIHdlIGNvbmZpcm0gdGhpcyB3YXJuaW5nIGlzIG5vdCBmaXJlZC5cbiAgICAgIGlmIChleGlzdGluZ0NhbGxiYWNrTm9kZSA9PSBudWxsICYmIGV4aXN0aW5nQ2FsbGJhY2tQcmlvcml0eSAhPT0gU3luY0xhbmUpIHtcbiAgICAgICAgZXJyb3IoJ0V4cGVjdGVkIHNjaGVkdWxlZCBjYWxsYmFjayB0byBleGlzdC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICAgIH1cbiAgICB9IC8vIFRoZSBwcmlvcml0eSBoYXNuJ3QgY2hhbmdlZC4gV2UgY2FuIHJldXNlIHRoZSBleGlzdGluZyB0YXNrLiBFeGl0LlxuXG5cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZXhpc3RpbmdDYWxsYmFja05vZGUgIT0gbnVsbCkge1xuICAgIC8vIENhbmNlbCB0aGUgZXhpc3RpbmcgY2FsbGJhY2suIFdlJ2xsIHNjaGVkdWxlIGEgbmV3IG9uZSBiZWxvdy5cbiAgICBjYW5jZWxDYWxsYmFjayQxKGV4aXN0aW5nQ2FsbGJhY2tOb2RlKTtcbiAgfSAvLyBTY2hlZHVsZSBhIG5ldyBjYWxsYmFjay5cblxuXG4gIHZhciBuZXdDYWxsYmFja05vZGU7XG5cbiAgaWYgKG5ld0NhbGxiYWNrUHJpb3JpdHkgPT09IFN5bmNMYW5lKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBTeW5jIFJlYWN0IGNhbGxiYWNrcyBhcmUgc2NoZWR1bGVkIG9uIGEgc3BlY2lhbFxuICAgIC8vIGludGVybmFsIHF1ZXVlXG4gICAgaWYgKHJvb3QudGFnID09PSBMZWdhY3lSb290KSB7XG4gICAgICBpZiAoIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuaXNCYXRjaGluZ0xlZ2FjeSAhPT0gbnVsbCkge1xuICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmRpZFNjaGVkdWxlTGVnYWN5VXBkYXRlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgc2NoZWR1bGVMZWdhY3lTeW5jQ2FsbGJhY2socGVyZm9ybVN5bmNXb3JrT25Sb290LmJpbmQobnVsbCwgcm9vdCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2hlZHVsZVN5bmNDYWxsYmFjayhwZXJmb3JtU3luY1dvcmtPblJvb3QuYmluZChudWxsLCByb290KSk7XG4gICAgfVxuXG4gICAge1xuICAgICAgLy8gRmx1c2ggdGhlIHF1ZXVlIGluIGEgbWljcm90YXNrLlxuICAgICAgaWYgKCBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgLy8gSW5zaWRlIGBhY3RgLCB1c2Ugb3VyIGludGVybmFsIGBhY3RgIHF1ZXVlIHNvIHRoYXQgdGhlc2UgZ2V0IGZsdXNoZWRcbiAgICAgICAgLy8gYXQgdGhlIGVuZCBvZiB0aGUgY3VycmVudCBzY29wZSBldmVuIHdoZW4gdXNpbmcgdGhlIHN5bmMgdmVyc2lvblxuICAgICAgICAvLyBvZiBgYWN0YC5cbiAgICAgICAgUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50LnB1c2goZmx1c2hTeW5jQ2FsbGJhY2tzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNjaGVkdWxlTWljcm90YXNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAvLyBJbiBTYWZhcmksIGFwcGVuZGluZyBhbiBpZnJhbWUgZm9yY2VzIG1pY3JvdGFza3MgdG8gcnVuLlxuICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMjI0NTlcbiAgICAgICAgICAvLyBXZSBkb24ndCBzdXBwb3J0IHJ1bm5pbmcgY2FsbGJhY2tzIGluIHRoZSBtaWRkbGUgb2YgcmVuZGVyXG4gICAgICAgICAgLy8gb3IgY29tbWl0IHNvIHdlIG5lZWQgdG8gY2hlY2sgYWdhaW5zdCB0aGF0LlxuICAgICAgICAgIGlmIChleGVjdXRpb25Db250ZXh0ID09PSBOb0NvbnRleHQpIHtcbiAgICAgICAgICAgIC8vIEl0J3Mgb25seSBzYWZlIHRvIGRvIHRoaXMgY29uZGl0aW9uYWxseSBiZWNhdXNlIHdlIGFsd2F5c1xuICAgICAgICAgICAgLy8gY2hlY2sgZm9yIHBlbmRpbmcgd29yayBiZWZvcmUgd2UgZXhpdCB0aGUgdGFzay5cbiAgICAgICAgICAgIGZsdXNoU3luY0NhbGxiYWNrcygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbmV3Q2FsbGJhY2tOb2RlID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2NoZWR1bGVyUHJpb3JpdHlMZXZlbDtcblxuICAgIHN3aXRjaCAobGFuZXNUb0V2ZW50UHJpb3JpdHkobmV4dExhbmVzKSkge1xuICAgICAgY2FzZSBEaXNjcmV0ZUV2ZW50UHJpb3JpdHk6XG4gICAgICAgIHNjaGVkdWxlclByaW9yaXR5TGV2ZWwgPSBJbW1lZGlhdGVQcmlvcml0eTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgQ29udGludW91c0V2ZW50UHJpb3JpdHk6XG4gICAgICAgIHNjaGVkdWxlclByaW9yaXR5TGV2ZWwgPSBVc2VyQmxvY2tpbmdQcmlvcml0eTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRGVmYXVsdEV2ZW50UHJpb3JpdHk6XG4gICAgICAgIHNjaGVkdWxlclByaW9yaXR5TGV2ZWwgPSBOb3JtYWxQcmlvcml0eTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgSWRsZUV2ZW50UHJpb3JpdHk6XG4gICAgICAgIHNjaGVkdWxlclByaW9yaXR5TGV2ZWwgPSBJZGxlUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIG5ld0NhbGxiYWNrTm9kZSA9IHNjaGVkdWxlQ2FsbGJhY2skMShzY2hlZHVsZXJQcmlvcml0eUxldmVsLCBwZXJmb3JtQ29uY3VycmVudFdvcmtPblJvb3QuYmluZChudWxsLCByb290KSk7XG4gIH1cblxuICByb290LmNhbGxiYWNrUHJpb3JpdHkgPSBuZXdDYWxsYmFja1ByaW9yaXR5O1xuICByb290LmNhbGxiYWNrTm9kZSA9IG5ld0NhbGxiYWNrTm9kZTtcbn0gLy8gVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIGV2ZXJ5IGNvbmN1cnJlbnQgdGFzaywgaS5lLiBhbnl0aGluZyB0aGF0XG4vLyBnb2VzIHRocm91Z2ggU2NoZWR1bGVyLlxuXG5cbmZ1bmN0aW9uIHBlcmZvcm1Db25jdXJyZW50V29ya09uUm9vdChyb290LCBkaWRUaW1lb3V0KSB7XG4gIHtcbiAgICByZXNldE5lc3RlZFVwZGF0ZUZsYWcoKTtcbiAgfSAvLyBTaW5jZSB3ZSBrbm93IHdlJ3JlIGluIGEgUmVhY3QgZXZlbnQsIHdlIGNhbiBjbGVhciB0aGUgY3VycmVudFxuICAvLyBldmVudCB0aW1lLiBUaGUgbmV4dCB1cGRhdGUgd2lsbCBjb21wdXRlIGEgbmV3IGV2ZW50IHRpbWUuXG5cblxuICBjdXJyZW50RXZlbnRUaW1lID0gTm9UaW1lc3RhbXA7XG4gIGN1cnJlbnRFdmVudFRyYW5zaXRpb25MYW5lID0gTm9MYW5lcztcblxuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgbm90IGFscmVhZHkgYmUgd29ya2luZy4nKTtcbiAgfSAvLyBGbHVzaCBhbnkgcGVuZGluZyBwYXNzaXZlIGVmZmVjdHMgYmVmb3JlIGRlY2lkaW5nIHdoaWNoIGxhbmVzIHRvIHdvcmsgb24sXG4gIC8vIGluIGNhc2UgdGhleSBzY2hlZHVsZSBhZGRpdGlvbmFsIHdvcmsuXG5cblxuICB2YXIgb3JpZ2luYWxDYWxsYmFja05vZGUgPSByb290LmNhbGxiYWNrTm9kZTtcbiAgdmFyIGRpZEZsdXNoUGFzc2l2ZUVmZmVjdHMgPSBmbHVzaFBhc3NpdmVFZmZlY3RzKCk7XG5cbiAgaWYgKGRpZEZsdXNoUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAvLyBTb21ldGhpbmcgaW4gdGhlIHBhc3NpdmUgZWZmZWN0IHBoYXNlIG1heSBoYXZlIGNhbmNlbGVkIHRoZSBjdXJyZW50IHRhc2suXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHRhc2sgbm9kZSBmb3IgdGhpcyByb290IHdhcyBjaGFuZ2VkLlxuICAgIGlmIChyb290LmNhbGxiYWNrTm9kZSAhPT0gb3JpZ2luYWxDYWxsYmFja05vZGUpIHtcbiAgICAgIC8vIFRoZSBjdXJyZW50IHRhc2sgd2FzIGNhbmNlbGVkLiBFeGl0LiBXZSBkb24ndCBuZWVkIHRvIGNhbGxcbiAgICAgIC8vIGBlbnN1cmVSb290SXNTY2hlZHVsZWRgIGJlY2F1c2UgdGhlIGNoZWNrIGFib3ZlIGltcGxpZXMgZWl0aGVyIHRoYXRcbiAgICAgIC8vIHRoZXJlJ3MgYSBuZXcgdGFzaywgb3IgdGhhdCB0aGVyZSdzIG5vIHJlbWFpbmluZyB3b3JrIG9uIHRoaXMgcm9vdC5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSAvLyBEZXRlcm1pbmUgdGhlIG5leHQgbGFuZXMgdG8gd29yayBvbiwgdXNpbmcgdGhlIGZpZWxkcyBzdG9yZWRcbiAgLy8gb24gdGhlIHJvb3QuXG5cblxuICB2YXIgbGFuZXMgPSBnZXROZXh0TGFuZXMocm9vdCwgcm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290ID8gd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgOiBOb0xhbmVzKTtcblxuICBpZiAobGFuZXMgPT09IE5vTGFuZXMpIHtcbiAgICAvLyBEZWZlbnNpdmUgY29kaW5nLiBUaGlzIGlzIG5ldmVyIGV4cGVjdGVkIHRvIGhhcHBlbi5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSAvLyBXZSBkaXNhYmxlIHRpbWUtc2xpY2luZyBpbiBzb21lIGNhc2VzOiBpZiB0aGUgd29yayBoYXMgYmVlbiBDUFUtYm91bmRcbiAgLy8gZm9yIHRvbyBsb25nIChcImV4cGlyZWRcIiB3b3JrLCB0byBwcmV2ZW50IHN0YXJ2YXRpb24pLCBvciB3ZSdyZSBpblxuICAvLyBzeW5jLXVwZGF0ZXMtYnktZGVmYXVsdCBtb2RlLlxuICAvLyBUT0RPOiBXZSBvbmx5IGNoZWNrIGBkaWRUaW1lb3V0YCBkZWZlbnNpdmVseSwgdG8gYWNjb3VudCBmb3IgYSBTY2hlZHVsZXJcbiAgLy8gYnVnIHdlJ3JlIHN0aWxsIGludmVzdGlnYXRpbmcuIE9uY2UgdGhlIGJ1ZyBpbiBTY2hlZHVsZXIgaXMgZml4ZWQsXG4gIC8vIHdlIGNhbiByZW1vdmUgdGhpcywgc2luY2Ugd2UgdHJhY2sgZXhwaXJhdGlvbiBvdXJzZWx2ZXMuXG5cblxuICB2YXIgc2hvdWxkVGltZVNsaWNlID0gIWluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIGxhbmVzKSAmJiAhaW5jbHVkZXNFeHBpcmVkTGFuZShyb290LCBsYW5lcykgJiYgKCAhZGlkVGltZW91dCk7XG4gIHZhciBleGl0U3RhdHVzID0gc2hvdWxkVGltZVNsaWNlID8gcmVuZGVyUm9vdENvbmN1cnJlbnQocm9vdCwgbGFuZXMpIDogcmVuZGVyUm9vdFN5bmMocm9vdCwgbGFuZXMpO1xuXG4gIGlmIChleGl0U3RhdHVzICE9PSBSb290SW5Qcm9ncmVzcykge1xuICAgIGlmIChleGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgICAgLy8gSWYgc29tZXRoaW5nIHRocmV3IGFuIGVycm9yLCB0cnkgcmVuZGVyaW5nIG9uZSBtb3JlIHRpbWUuIFdlJ2xsXG4gICAgICAvLyByZW5kZXIgc3luY2hyb25vdXNseSB0byBibG9jayBjb25jdXJyZW50IGRhdGEgbXV0YXRpb25zLCBhbmQgd2UnbGxcbiAgICAgIC8vIGluY2x1ZGVzIGFsbCBwZW5kaW5nIHVwZGF0ZXMgYXJlIGluY2x1ZGVkLiBJZiBpdCBzdGlsbCBmYWlscyBhZnRlclxuICAgICAgLy8gdGhlIHNlY29uZCBhdHRlbXB0LCB3ZSdsbCBnaXZlIHVwIGFuZCBjb21taXQgdGhlIHJlc3VsdGluZyB0cmVlLlxuICAgICAgdmFyIGVycm9yUmV0cnlMYW5lcyA9IGdldExhbmVzVG9SZXRyeVN5bmNocm9ub3VzbHlPbkVycm9yKHJvb3QpO1xuXG4gICAgICBpZiAoZXJyb3JSZXRyeUxhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICAgIGxhbmVzID0gZXJyb3JSZXRyeUxhbmVzO1xuICAgICAgICBleGl0U3RhdHVzID0gcmVjb3ZlckZyb21Db25jdXJyZW50RXJyb3Iocm9vdCwgZXJyb3JSZXRyeUxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdEZhdGFsRXJyb3JlZCkge1xuICAgICAgdmFyIGZhdGFsRXJyb3IgPSB3b3JrSW5Qcm9ncmVzc1Jvb3RGYXRhbEVycm9yO1xuICAgICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgTm9MYW5lcyk7XG4gICAgICBtYXJrUm9vdFN1c3BlbmRlZCQxKHJvb3QsIGxhbmVzKTtcbiAgICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG4gICAgICB0aHJvdyBmYXRhbEVycm9yO1xuICAgIH1cblxuICAgIGlmIChleGl0U3RhdHVzID09PSBSb290RGlkTm90Q29tcGxldGUpIHtcbiAgICAgIC8vIFRoZSByZW5kZXIgdW53b3VuZCB3aXRob3V0IGNvbXBsZXRpbmcgdGhlIHRyZWUuIFRoaXMgaGFwcGVucyBpbiBzcGVjaWFsXG4gICAgICAvLyBjYXNlcyB3aGVyZSBuZWVkIHRvIGV4aXQgdGhlIGN1cnJlbnQgcmVuZGVyIHdpdGhvdXQgcHJvZHVjaW5nIGFcbiAgICAgIC8vIGNvbnNpc3RlbnQgdHJlZSBvciBjb21taXR0aW5nLlxuICAgICAgLy9cbiAgICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgaGFwcGVuIGR1cmluZyBhIGNvbmN1cnJlbnQgcmVuZGVyLCBub3QgYSBkaXNjcmV0ZSBvclxuICAgICAgLy8gc3luY2hyb25vdXMgdXBkYXRlLiBXZSBzaG91bGQgaGF2ZSBhbHJlYWR5IGNoZWNrZWQgZm9yIHRoaXMgd2hlbiB3ZVxuICAgICAgLy8gdW53b3VuZCB0aGUgc3RhY2suXG4gICAgICBtYXJrUm9vdFN1c3BlbmRlZCQxKHJvb3QsIGxhbmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHJlbmRlciBjb21wbGV0ZWQuXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIHJlbmRlciBtYXkgaGF2ZSB5aWVsZGVkIHRvIGEgY29uY3VycmVudCBldmVudCwgYW5kIGlmIHNvLFxuICAgICAgLy8gY29uZmlybSB0aGF0IGFueSBuZXdseSByZW5kZXJlZCBzdG9yZXMgYXJlIGNvbnNpc3RlbnQuXG4gICAgICAvLyBUT0RPOiBJdCdzIHBvc3NpYmxlIHRoYXQgZXZlbiBhIGNvbmN1cnJlbnQgcmVuZGVyIG1heSBuZXZlciBoYXZlIHlpZWxkZWRcbiAgICAgIC8vIHRvIHRoZSBtYWluIHRocmVhZCwgaWYgaXQgd2FzIGZhc3QgZW5vdWdoLCBvciBpZiBpdCBleHBpcmVkLiBXZSBjb3VsZFxuICAgICAgLy8gc2tpcCB0aGUgY29uc2lzdGVuY3kgY2hlY2sgaW4gdGhhdCBjYXNlLCB0b28uXG4gICAgICB2YXIgcmVuZGVyV2FzQ29uY3VycmVudCA9ICFpbmNsdWRlc0Jsb2NraW5nTGFuZShyb290LCBsYW5lcyk7XG4gICAgICB2YXIgZmluaXNoZWRXb3JrID0gcm9vdC5jdXJyZW50LmFsdGVybmF0ZTtcblxuICAgICAgaWYgKHJlbmRlcldhc0NvbmN1cnJlbnQgJiYgIWlzUmVuZGVyQ29uc2lzdGVudFdpdGhFeHRlcm5hbFN0b3JlcyhmaW5pc2hlZFdvcmspKSB7XG4gICAgICAgIC8vIEEgc3RvcmUgd2FzIG11dGF0ZWQgaW4gYW4gaW50ZXJsZWF2ZWQgZXZlbnQuIFJlbmRlciBhZ2FpbixcbiAgICAgICAgLy8gc3luY2hyb25vdXNseSwgdG8gYmxvY2sgZnVydGhlciBtdXRhdGlvbnMuXG4gICAgICAgIGV4aXRTdGF0dXMgPSByZW5kZXJSb290U3luYyhyb290LCBsYW5lcyk7IC8vIFdlIG5lZWQgdG8gY2hlY2sgYWdhaW4gaWYgc29tZXRoaW5nIHRocmV3XG5cbiAgICAgICAgaWYgKGV4aXRTdGF0dXMgPT09IFJvb3RFcnJvcmVkKSB7XG4gICAgICAgICAgdmFyIF9lcnJvclJldHJ5TGFuZXMgPSBnZXRMYW5lc1RvUmV0cnlTeW5jaHJvbm91c2x5T25FcnJvcihyb290KTtcblxuICAgICAgICAgIGlmIChfZXJyb3JSZXRyeUxhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICAgICAgICBsYW5lcyA9IF9lcnJvclJldHJ5TGFuZXM7XG4gICAgICAgICAgICBleGl0U3RhdHVzID0gcmVjb3ZlckZyb21Db25jdXJyZW50RXJyb3Iocm9vdCwgX2Vycm9yUmV0cnlMYW5lcyk7IC8vIFdlIGFzc3VtZSB0aGUgdHJlZSBpcyBub3cgY29uc2lzdGVudCBiZWNhdXNlIHdlIGRpZG4ndCB5aWVsZCB0byBhbnlcbiAgICAgICAgICAgIC8vIGNvbmN1cnJlbnQgZXZlbnRzLlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChleGl0U3RhdHVzID09PSBSb290RmF0YWxFcnJvcmVkKSB7XG4gICAgICAgICAgdmFyIF9mYXRhbEVycm9yID0gd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvcjtcbiAgICAgICAgICBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBOb0xhbmVzKTtcbiAgICAgICAgICBtYXJrUm9vdFN1c3BlbmRlZCQxKHJvb3QsIGxhbmVzKTtcbiAgICAgICAgICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgbm93KCkpO1xuICAgICAgICAgIHRocm93IF9mYXRhbEVycm9yO1xuICAgICAgICB9XG4gICAgICB9IC8vIFdlIG5vdyBoYXZlIGEgY29uc2lzdGVudCB0cmVlLiBUaGUgbmV4dCBzdGVwIGlzIGVpdGhlciB0byBjb21taXQgaXQsXG4gICAgICAvLyBvciwgaWYgc29tZXRoaW5nIHN1c3BlbmRlZCwgd2FpdCB0byBjb21taXQgaXQgYWZ0ZXIgYSB0aW1lb3V0LlxuXG5cbiAgICAgIHJvb3QuZmluaXNoZWRXb3JrID0gZmluaXNoZWRXb3JrO1xuICAgICAgcm9vdC5maW5pc2hlZExhbmVzID0gbGFuZXM7XG4gICAgICBmaW5pc2hDb25jdXJyZW50UmVuZGVyKHJvb3QsIGV4aXRTdGF0dXMsIGxhbmVzKTtcbiAgICB9XG4gIH1cblxuICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgbm93KCkpO1xuXG4gIGlmIChyb290LmNhbGxiYWNrTm9kZSA9PT0gb3JpZ2luYWxDYWxsYmFja05vZGUpIHtcbiAgICAvLyBUaGUgdGFzayBub2RlIHNjaGVkdWxlZCBmb3IgdGhpcyByb290IGlzIHRoZSBzYW1lIG9uZSB0aGF0J3NcbiAgICAvLyBjdXJyZW50bHkgZXhlY3V0ZWQuIE5lZWQgdG8gcmV0dXJuIGEgY29udGludWF0aW9uLlxuICAgIHJldHVybiBwZXJmb3JtQ29uY3VycmVudFdvcmtPblJvb3QuYmluZChudWxsLCByb290KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiByZWNvdmVyRnJvbUNvbmN1cnJlbnRFcnJvcihyb290LCBlcnJvclJldHJ5TGFuZXMpIHtcbiAgLy8gSWYgYW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIGh5ZHJhdGlvbiwgZGlzY2FyZCBzZXJ2ZXIgcmVzcG9uc2UgYW5kIGZhbGxcbiAgLy8gYmFjayB0byBjbGllbnQgc2lkZSByZW5kZXIuXG4gIC8vIEJlZm9yZSByZW5kZXJpbmcgYWdhaW4sIHNhdmUgdGhlIGVycm9ycyBmcm9tIHRoZSBwcmV2aW91cyBhdHRlbXB0LlxuICB2YXIgZXJyb3JzRnJvbUZpcnN0QXR0ZW1wdCA9IHdvcmtJblByb2dyZXNzUm9vdENvbmN1cnJlbnRFcnJvcnM7XG5cbiAgaWYgKGlzUm9vdERlaHlkcmF0ZWQocm9vdCkpIHtcbiAgICAvLyBUaGUgc2hlbGwgZmFpbGVkIHRvIGh5ZHJhdGUuIFNldCBhIGZsYWcgdG8gZm9yY2UgYSBjbGllbnQgcmVuZGVyaW5nXG4gICAgLy8gZHVyaW5nIHRoZSBuZXh0IGF0dGVtcHQuIFRvIGRvIHRoaXMsIHdlIGNhbGwgcHJlcGFyZUZyZXNoU3RhY2sgbm93XG4gICAgLy8gdG8gY3JlYXRlIHRoZSByb290IHdvcmstaW4tcHJvZ3Jlc3MgZmliZXIuIFRoaXMgaXMgYSBiaXQgd2VpcmQgaW4gdGVybXNcbiAgICAvLyBvZiBmYWN0b3JpbmcsIGJlY2F1c2UgaXQgcmVsaWVzIG9uIHJlbmRlclJvb3RTeW5jIG5vdCBjYWxsaW5nXG4gICAgLy8gcHJlcGFyZUZyZXNoU3RhY2sgYWdhaW4gaW4gdGhlIGNhbGwgYmVsb3csIHdoaWNoIGhhcHBlbnMgYmVjYXVzZSB0aGVcbiAgICAvLyByb290IGFuZCBsYW5lcyBoYXZlbid0IGNoYW5nZWQuXG4gICAgLy9cbiAgICAvLyBUT0RPOiBJIHRoaW5rIHdoYXQgd2Ugc2hvdWxkIGRvIGlzIHNldCBGb3JjZUNsaWVudFJlbmRlciBpbnNpZGVcbiAgICAvLyB0aHJvd0V4Y2VwdGlvbiwgbGlrZSB3ZSBkbyBmb3IgbmVzdGVkIFN1c3BlbnNlIGJvdW5kYXJpZXMuIFRoZSByZWFzb25cbiAgICAvLyBpdCdzIGhlcmUgaW5zdGVhZCBpcyBzbyB3ZSBjYW4gc3dpdGNoIHRvIHRoZSBzeW5jaHJvbm91cyB3b3JrIGxvb3AsIHRvby5cbiAgICAvLyBTb21ldGhpbmcgdG8gY29uc2lkZXIgZm9yIGEgZnV0dXJlIHJlZmFjdG9yLlxuICAgIHZhciByb290V29ya0luUHJvZ3Jlc3MgPSBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBlcnJvclJldHJ5TGFuZXMpO1xuICAgIHJvb3RXb3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBGb3JjZUNsaWVudFJlbmRlcjtcblxuICAgIHtcbiAgICAgIGVycm9ySHlkcmF0aW5nQ29udGFpbmVyKHJvb3QuY29udGFpbmVySW5mbyk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGV4aXRTdGF0dXMgPSByZW5kZXJSb290U3luYyhyb290LCBlcnJvclJldHJ5TGFuZXMpO1xuXG4gIGlmIChleGl0U3RhdHVzICE9PSBSb290RXJyb3JlZCkge1xuICAgIC8vIFN1Y2Nlc3NmdWxseSBmaW5pc2hlZCByZW5kZXJpbmcgb24gcmV0cnlcbiAgICAvLyBUaGUgZXJyb3JzIGZyb20gdGhlIGZhaWxlZCBmaXJzdCBhdHRlbXB0IGhhdmUgYmVlbiByZWNvdmVyZWQuIEFkZFxuICAgIC8vIHRoZW0gdG8gdGhlIGNvbGxlY3Rpb24gb2YgcmVjb3ZlcmFibGUgZXJyb3JzLiBXZSdsbCBsb2cgdGhlbSBpbiB0aGVcbiAgICAvLyBjb21taXQgcGhhc2UuXG4gICAgdmFyIGVycm9yc0Zyb21TZWNvbmRBdHRlbXB0ID0gd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnM7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMgPSBlcnJvcnNGcm9tRmlyc3RBdHRlbXB0OyAvLyBUaGUgZXJyb3JzIGZyb20gdGhlIHNlY29uZCBhdHRlbXB0IHNob3VsZCBiZSBxdWV1ZWQgYWZ0ZXIgdGhlIGVycm9yc1xuICAgIC8vIGZyb20gdGhlIGZpcnN0IGF0dGVtcHQsIHRvIHByZXNlcnZlIHRoZSBjYXVzYWwgc2VxdWVuY2UuXG5cbiAgICBpZiAoZXJyb3JzRnJvbVNlY29uZEF0dGVtcHQgIT09IG51bGwpIHtcbiAgICAgIHF1ZXVlUmVjb3ZlcmFibGVFcnJvcnMoZXJyb3JzRnJvbVNlY29uZEF0dGVtcHQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleGl0U3RhdHVzO1xufVxuXG5mdW5jdGlvbiBxdWV1ZVJlY292ZXJhYmxlRXJyb3JzKGVycm9ycykge1xuICBpZiAod29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMgPT09IG51bGwpIHtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycyA9IGVycm9ycztcbiAgfSBlbHNlIHtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycy5wdXNoLmFwcGx5KHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCBlcnJvcnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmlzaENvbmN1cnJlbnRSZW5kZXIocm9vdCwgZXhpdFN0YXR1cywgbGFuZXMpIHtcbiAgc3dpdGNoIChleGl0U3RhdHVzKSB7XG4gICAgY2FzZSBSb290SW5Qcm9ncmVzczpcbiAgICBjYXNlIFJvb3RGYXRhbEVycm9yZWQ6XG4gICAgICB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUm9vdCBkaWQgbm90IGNvbXBsZXRlLiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgfVxuICAgIC8vIEZsb3cga25vd3MgYWJvdXQgaW52YXJpYW50LCBzbyBpdCBjb21wbGFpbnMgaWYgSSBhZGQgYSBicmVha1xuICAgIC8vIHN0YXRlbWVudCwgYnV0IGVzbGludCBkb2Vzbid0IGtub3cgYWJvdXQgaW52YXJpYW50LCBzbyBpdCBjb21wbGFpbnNcbiAgICAvLyBpZiBJIGRvLiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgIGNhc2UgUm9vdEVycm9yZWQ6XG4gICAgICB7XG4gICAgICAgIC8vIFdlIHNob3VsZCBoYXZlIGFscmVhZHkgYXR0ZW1wdGVkIHRvIHJldHJ5IHRoaXMgdHJlZS4gSWYgd2UgcmVhY2hlZFxuICAgICAgICAvLyB0aGlzIHBvaW50LCBpdCBlcnJvcmVkIGFnYWluLiBDb21taXQgaXQuXG4gICAgICAgIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgUm9vdFN1c3BlbmRlZDpcbiAgICAgIHtcbiAgICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7IC8vIFdlIGhhdmUgYW4gYWNjZXB0YWJsZSBsb2FkaW5nIHN0YXRlLiBXZSBuZWVkIHRvIGZpZ3VyZSBvdXQgaWYgd2VcbiAgICAgICAgLy8gc2hvdWxkIGltbWVkaWF0ZWx5IGNvbW1pdCBpdCBvciB3YWl0IGEgYml0LlxuXG4gICAgICAgIGlmIChpbmNsdWRlc09ubHlSZXRyaWVzKGxhbmVzKSAmJiAvLyBkbyBub3QgZGVsYXkgaWYgd2UncmUgaW5zaWRlIGFuIGFjdCgpIHNjb3BlXG4gICAgICAgICFzaG91bGRGb3JjZUZsdXNoRmFsbGJhY2tzSW5ERVYoKSkge1xuICAgICAgICAgIC8vIFRoaXMgcmVuZGVyIG9ubHkgaW5jbHVkZWQgcmV0cmllcywgbm8gdXBkYXRlcy4gVGhyb3R0bGUgY29tbWl0dGluZ1xuICAgICAgICAgIC8vIHJldHJpZXMgc28gdGhhdCB3ZSBkb24ndCBzaG93IHRvbyBtYW55IGxvYWRpbmcgc3RhdGVzIHRvbyBxdWlja2x5LlxuICAgICAgICAgIHZhciBtc1VudGlsVGltZW91dCA9IGdsb2JhbE1vc3RSZWNlbnRGYWxsYmFja1RpbWUgKyBGQUxMQkFDS19USFJPVFRMRV9NUyAtIG5vdygpOyAvLyBEb24ndCBib3RoZXIgd2l0aCBhIHZlcnkgc2hvcnQgc3VzcGVuc2UgdGltZS5cblxuICAgICAgICAgIGlmIChtc1VudGlsVGltZW91dCA+IDEwKSB7XG4gICAgICAgICAgICB2YXIgbmV4dExhbmVzID0gZ2V0TmV4dExhbmVzKHJvb3QsIE5vTGFuZXMpO1xuXG4gICAgICAgICAgICBpZiAobmV4dExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICAgICAgICAgIC8vIFRoZXJlJ3MgYWRkaXRpb25hbCB3b3JrIG9uIHRoaXMgcm9vdC5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBzdXNwZW5kZWRMYW5lcyA9IHJvb3Quc3VzcGVuZGVkTGFuZXM7XG5cbiAgICAgICAgICAgIGlmICghaXNTdWJzZXRPZkxhbmVzKHN1c3BlbmRlZExhbmVzLCBsYW5lcykpIHtcbiAgICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIHByZWZlciB0byByZW5kZXIgdGhlIGZhbGxiYWNrIG9mIGF0IHRoZSBsYXN0XG4gICAgICAgICAgICAgIC8vIHN1c3BlbmRlZCBsZXZlbC4gUGluZyB0aGUgbGFzdCBzdXNwZW5kZWQgbGV2ZWwgdG8gdHJ5XG4gICAgICAgICAgICAgIC8vIHJlbmRlcmluZyBpdCBhZ2Fpbi5cbiAgICAgICAgICAgICAgLy8gRklYTUU6IFdoYXQgaWYgdGhlIHN1c3BlbmRlZCBsYW5lcyBhcmUgSWRsZT8gU2hvdWxkIG5vdCByZXN0YXJ0LlxuICAgICAgICAgICAgICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICAgICAgICAgICAgICBtYXJrUm9vdFBpbmdlZChyb290LCBzdXNwZW5kZWRMYW5lcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSAvLyBUaGUgcmVuZGVyIGlzIHN1c3BlbmRlZCwgaXQgaGFzbid0IHRpbWVkIG91dCwgYW5kIHRoZXJlJ3Mgbm9cbiAgICAgICAgICAgIC8vIGxvd2VyIHByaW9yaXR5IHdvcmsgdG8gZG8uIEluc3RlYWQgb2YgY29tbWl0dGluZyB0aGUgZmFsbGJhY2tcbiAgICAgICAgICAgIC8vIGltbWVkaWF0ZWx5LCB3YWl0IGZvciBtb3JlIGRhdGEgdG8gYXJyaXZlLlxuXG5cbiAgICAgICAgICAgIHJvb3QudGltZW91dEhhbmRsZSA9IHNjaGVkdWxlVGltZW91dChjb21taXRSb290LmJpbmQobnVsbCwgcm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpLCBtc1VudGlsVGltZW91dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gVGhlIHdvcmsgZXhwaXJlZC4gQ29tbWl0IGltbWVkaWF0ZWx5LlxuXG5cbiAgICAgICAgY29tbWl0Um9vdChyb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycywgd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBSb290U3VzcGVuZGVkV2l0aERlbGF5OlxuICAgICAge1xuICAgICAgICBtYXJrUm9vdFN1c3BlbmRlZCQxKHJvb3QsIGxhbmVzKTtcblxuICAgICAgICBpZiAoaW5jbHVkZXNPbmx5VHJhbnNpdGlvbnMobGFuZXMpKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBhIHRyYW5zaXRpb24sIHNvIHdlIHNob3VsZCBleGl0IHdpdGhvdXQgY29tbWl0dGluZyBhXG4gICAgICAgICAgLy8gcGxhY2Vob2xkZXIgYW5kIHdpdGhvdXQgc2NoZWR1bGluZyBhIHRpbWVvdXQuIERlbGF5IGluZGVmaW5pdGVseVxuICAgICAgICAgIC8vIHVudGlsIHdlIHJlY2VpdmUgbW9yZSBkYXRhLlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzaG91bGRGb3JjZUZsdXNoRmFsbGJhY2tzSW5ERVYoKSkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgbm90IGEgdHJhbnNpdGlvbiwgYnV0IHdlIGRpZCB0cmlnZ2VyIGFuIGF2b2lkZWQgc3RhdGUuXG4gICAgICAgICAgLy8gU2NoZWR1bGUgYSBwbGFjZWhvbGRlciB0byBkaXNwbGF5IGFmdGVyIGEgc2hvcnQgZGVsYXksIHVzaW5nIHRoZSBKdXN0XG4gICAgICAgICAgLy8gTm90aWNlYWJsZSBEaWZmZXJlbmNlLlxuICAgICAgICAgIC8vIFRPRE86IElzIHRoZSBKTkQgb3B0aW1pemF0aW9uIHdvcnRoIHRoZSBhZGRlZCBjb21wbGV4aXR5PyBJZiB0aGlzIGlzXG4gICAgICAgICAgLy8gdGhlIG9ubHkgcmVhc29uIHdlIHRyYWNrIHRoZSBldmVudCB0aW1lLCB0aGVuIHByb2JhYmx5IG5vdC5cbiAgICAgICAgICAvLyBDb25zaWRlciByZW1vdmluZy5cbiAgICAgICAgICB2YXIgbW9zdFJlY2VudEV2ZW50VGltZSA9IGdldE1vc3RSZWNlbnRFdmVudFRpbWUocm9vdCwgbGFuZXMpO1xuICAgICAgICAgIHZhciBldmVudFRpbWVNcyA9IG1vc3RSZWNlbnRFdmVudFRpbWU7XG4gICAgICAgICAgdmFyIHRpbWVFbGFwc2VkTXMgPSBub3coKSAtIGV2ZW50VGltZU1zO1xuXG4gICAgICAgICAgdmFyIF9tc1VudGlsVGltZW91dCA9IGpuZCh0aW1lRWxhcHNlZE1zKSAtIHRpbWVFbGFwc2VkTXM7IC8vIERvbid0IGJvdGhlciB3aXRoIGEgdmVyeSBzaG9ydCBzdXNwZW5zZSB0aW1lLlxuXG5cbiAgICAgICAgICBpZiAoX21zVW50aWxUaW1lb3V0ID4gMTApIHtcbiAgICAgICAgICAgIC8vIEluc3RlYWQgb2YgY29tbWl0dGluZyB0aGUgZmFsbGJhY2sgaW1tZWRpYXRlbHksIHdhaXQgZm9yIG1vcmUgZGF0YVxuICAgICAgICAgICAgLy8gdG8gYXJyaXZlLlxuICAgICAgICAgICAgcm9vdC50aW1lb3V0SGFuZGxlID0gc2NoZWR1bGVUaW1lb3V0KGNvbW1pdFJvb3QuYmluZChudWxsLCByb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycywgd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyksIF9tc1VudGlsVGltZW91dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gQ29tbWl0IHRoZSBwbGFjZWhvbGRlci5cblxuXG4gICAgICAgIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgUm9vdENvbXBsZXRlZDpcbiAgICAgIHtcbiAgICAgICAgLy8gVGhlIHdvcmsgY29tcGxldGVkLiBSZWFkeSB0byBjb21taXQuXG4gICAgICAgIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biByb290IGV4aXQgc3RhdHVzLicpO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzUmVuZGVyQ29uc2lzdGVudFdpdGhFeHRlcm5hbFN0b3JlcyhmaW5pc2hlZFdvcmspIHtcbiAgLy8gU2VhcmNoIHRoZSByZW5kZXJlZCB0cmVlIGZvciBleHRlcm5hbCBzdG9yZSByZWFkcywgYW5kIGNoZWNrIHdoZXRoZXIgdGhlXG4gIC8vIHN0b3JlcyB3ZXJlIG11dGF0ZWQgaW4gYSBjb25jdXJyZW50IGV2ZW50LiBJbnRlbnRpb25hbGx5IHVzaW5nIGFuIGl0ZXJhdGl2ZVxuICAvLyBsb29wIGluc3RlYWQgb2YgcmVjdXJzaW9uIHNvIHdlIGNhbiBleGl0IGVhcmx5LlxuICB2YXIgbm9kZSA9IGZpbmlzaGVkV29yaztcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGlmIChub2RlLmZsYWdzICYgU3RvcmVDb25zaXN0ZW5jeSkge1xuICAgICAgdmFyIHVwZGF0ZVF1ZXVlID0gbm9kZS51cGRhdGVRdWV1ZTtcblxuICAgICAgaWYgKHVwZGF0ZVF1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBjaGVja3MgPSB1cGRhdGVRdWV1ZS5zdG9yZXM7XG5cbiAgICAgICAgaWYgKGNoZWNrcyAhPT0gbnVsbCkge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hlY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgY2hlY2sgPSBjaGVja3NbaV07XG4gICAgICAgICAgICB2YXIgZ2V0U25hcHNob3QgPSBjaGVjay5nZXRTbmFwc2hvdDtcbiAgICAgICAgICAgIHZhciByZW5kZXJlZFZhbHVlID0gY2hlY2sudmFsdWU7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGlmICghb2JqZWN0SXMoZ2V0U25hcHNob3QoKSwgcmVuZGVyZWRWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBGb3VuZCBhbiBpbmNvbnNpc3RlbnQgc3RvcmUuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAvLyBJZiBgZ2V0U25hcHNob3RgIHRocm93cywgcmV0dXJuIGBmYWxzZWAuIFRoaXMgd2lsbCBzY2hlZHVsZVxuICAgICAgICAgICAgICAvLyBhIHJlLXJlbmRlciwgYW5kIHRoZSBlcnJvciB3aWxsIGJlIHJldGhyb3duIGR1cmluZyByZW5kZXIuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkO1xuXG4gICAgaWYgKG5vZGUuc3VidHJlZUZsYWdzICYgU3RvcmVDb25zaXN0ZW5jeSAmJiBjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgIG5vZGUgPSBjaGlsZDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChub2RlID09PSBmaW5pc2hlZFdvcmspIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBub2RlLnJldHVybiA9PT0gZmluaXNoZWRXb3JrKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5zaWJsaW5nLnJldHVybiA9IG5vZGUucmV0dXJuO1xuICAgIG5vZGUgPSBub2RlLnNpYmxpbmc7XG4gIH0gLy8gRmxvdyBkb2Vzbid0IGtub3cgdGhpcyBpcyB1bnJlYWNoYWJsZSwgYnV0IGVzbGludCBkb2VzXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnJlYWNoYWJsZVxuXG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgc3VzcGVuZGVkTGFuZXMpIHtcbiAgLy8gV2hlbiBzdXNwZW5kaW5nLCB3ZSBzaG91bGQgYWx3YXlzIGV4Y2x1ZGUgbGFuZXMgdGhhdCB3ZXJlIHBpbmdlZCBvciAobW9yZVxuICAvLyByYXJlbHksIHNpbmNlIHdlIHRyeSB0byBhdm9pZCBpdCkgdXBkYXRlZCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS5cbiAgLy8gVE9ETzogTG9sIG1heWJlIHRoZXJlJ3MgYSBiZXR0ZXIgd2F5IHRvIGZhY3RvciB0aGlzIGJlc2lkZXMgdGhpc1xuICAvLyBvYm5veGlvdXNseSBuYW1lZCBmdW5jdGlvbiA6KVxuICBzdXNwZW5kZWRMYW5lcyA9IHJlbW92ZUxhbmVzKHN1c3BlbmRlZExhbmVzLCB3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcyk7XG4gIHN1c3BlbmRlZExhbmVzID0gcmVtb3ZlTGFuZXMoc3VzcGVuZGVkTGFuZXMsIHdvcmtJblByb2dyZXNzUm9vdEludGVybGVhdmVkVXBkYXRlZExhbmVzKTtcbiAgbWFya1Jvb3RTdXNwZW5kZWQocm9vdCwgc3VzcGVuZGVkTGFuZXMpO1xufSAvLyBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCBmb3Igc3luY2hyb25vdXMgdGFza3MgdGhhdCBkb24ndCBnb1xuLy8gdGhyb3VnaCBTY2hlZHVsZXJcblxuXG5mdW5jdGlvbiBwZXJmb3JtU3luY1dvcmtPblJvb3Qocm9vdCkge1xuICB7XG4gICAgc3luY05lc3RlZFVwZGF0ZUZsYWcoKTtcbiAgfVxuXG4gIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIChSZW5kZXJDb250ZXh0IHwgQ29tbWl0Q29udGV4dCkpICE9PSBOb0NvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Nob3VsZCBub3QgYWxyZWFkeSBiZSB3b3JraW5nLicpO1xuICB9XG5cbiAgZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuICB2YXIgbGFuZXMgPSBnZXROZXh0TGFuZXMocm9vdCwgTm9MYW5lcyk7XG5cbiAgaWYgKCFpbmNsdWRlc1NvbWVMYW5lKGxhbmVzLCBTeW5jTGFuZSkpIHtcbiAgICAvLyBUaGVyZSdzIG5vIHJlbWFpbmluZyBzeW5jIHdvcmsgbGVmdC5cbiAgICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgbm93KCkpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGV4aXRTdGF0dXMgPSByZW5kZXJSb290U3luYyhyb290LCBsYW5lcyk7XG5cbiAgaWYgKHJvb3QudGFnICE9PSBMZWdhY3lSb290ICYmIGV4aXRTdGF0dXMgPT09IFJvb3RFcnJvcmVkKSB7XG4gICAgLy8gSWYgc29tZXRoaW5nIHRocmV3IGFuIGVycm9yLCB0cnkgcmVuZGVyaW5nIG9uZSBtb3JlIHRpbWUuIFdlJ2xsIHJlbmRlclxuICAgIC8vIHN5bmNocm9ub3VzbHkgdG8gYmxvY2sgY29uY3VycmVudCBkYXRhIG11dGF0aW9ucywgYW5kIHdlJ2xsIGluY2x1ZGVzXG4gICAgLy8gYWxsIHBlbmRpbmcgdXBkYXRlcyBhcmUgaW5jbHVkZWQuIElmIGl0IHN0aWxsIGZhaWxzIGFmdGVyIHRoZSBzZWNvbmRcbiAgICAvLyBhdHRlbXB0LCB3ZSdsbCBnaXZlIHVwIGFuZCBjb21taXQgdGhlIHJlc3VsdGluZyB0cmVlLlxuICAgIHZhciBlcnJvclJldHJ5TGFuZXMgPSBnZXRMYW5lc1RvUmV0cnlTeW5jaHJvbm91c2x5T25FcnJvcihyb290KTtcblxuICAgIGlmIChlcnJvclJldHJ5TGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICAgIGxhbmVzID0gZXJyb3JSZXRyeUxhbmVzO1xuICAgICAgZXhpdFN0YXR1cyA9IHJlY292ZXJGcm9tQ29uY3VycmVudEVycm9yKHJvb3QsIGVycm9yUmV0cnlMYW5lcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGV4aXRTdGF0dXMgPT09IFJvb3RGYXRhbEVycm9yZWQpIHtcbiAgICB2YXIgZmF0YWxFcnJvciA9IHdvcmtJblByb2dyZXNzUm9vdEZhdGFsRXJyb3I7XG4gICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgTm9MYW5lcyk7XG4gICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgICB0aHJvdyBmYXRhbEVycm9yO1xuICB9XG5cbiAgaWYgKGV4aXRTdGF0dXMgPT09IFJvb3REaWROb3RDb21wbGV0ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUm9vdCBkaWQgbm90IGNvbXBsZXRlLiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICB9IC8vIFdlIG5vdyBoYXZlIGEgY29uc2lzdGVudCB0cmVlLiBCZWNhdXNlIHRoaXMgaXMgYSBzeW5jIHJlbmRlciwgd2VcbiAgLy8gd2lsbCBjb21taXQgaXQgZXZlbiBpZiBzb21ldGhpbmcgc3VzcGVuZGVkLlxuXG5cbiAgdmFyIGZpbmlzaGVkV29yayA9IHJvb3QuY3VycmVudC5hbHRlcm5hdGU7XG4gIHJvb3QuZmluaXNoZWRXb3JrID0gZmluaXNoZWRXb3JrO1xuICByb290LmZpbmlzaGVkTGFuZXMgPSBsYW5lcztcbiAgY29tbWl0Um9vdChyb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycywgd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyk7IC8vIEJlZm9yZSBleGl0aW5nLCBtYWtlIHN1cmUgdGhlcmUncyBhIGNhbGxiYWNrIHNjaGVkdWxlZCBmb3IgdGhlIG5leHRcbiAgLy8gcGVuZGluZyBsZXZlbC5cblxuICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgbm93KCkpO1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZmx1c2hSb290KHJvb3QsIGxhbmVzKSB7XG4gIGlmIChsYW5lcyAhPT0gTm9MYW5lcykge1xuICAgIG1hcmtSb290RW50YW5nbGVkKHJvb3QsIG1lcmdlTGFuZXMobGFuZXMsIFN5bmNMYW5lKSk7XG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcblxuICAgIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIChSZW5kZXJDb250ZXh0IHwgQ29tbWl0Q29udGV4dCkpID09PSBOb0NvbnRleHQpIHtcbiAgICAgIHJlc2V0UmVuZGVyVGltZXIoKTtcbiAgICAgIGZsdXNoU3luY0NhbGxiYWNrcygpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gYmF0Y2hlZFVwZGF0ZXMkMShmbiwgYSkge1xuICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICBleGVjdXRpb25Db250ZXh0IHw9IEJhdGNoZWRDb250ZXh0O1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGZuKGEpO1xuICB9IGZpbmFsbHkge1xuICAgIGV4ZWN1dGlvbkNvbnRleHQgPSBwcmV2RXhlY3V0aW9uQ29udGV4dDsgLy8gSWYgdGhlcmUgd2VyZSBsZWdhY3kgc3luYyB1cGRhdGVzLCBmbHVzaCB0aGVtIGF0IHRoZSBlbmQgb2YgdGhlIG91dGVyXG4gICAgLy8gbW9zdCBiYXRjaGVkVXBkYXRlcy1saWtlIG1ldGhvZC5cblxuICAgIGlmIChleGVjdXRpb25Db250ZXh0ID09PSBOb0NvbnRleHQgJiYgLy8gVHJlYXQgYGFjdGAgYXMgaWYgaXQncyBpbnNpZGUgYGJhdGNoZWRVcGRhdGVzYCwgZXZlbiBpbiBsZWdhY3kgbW9kZS5cbiAgICAhKCBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmlzQmF0Y2hpbmdMZWdhY3kpKSB7XG4gICAgICByZXNldFJlbmRlclRpbWVyKCk7XG4gICAgICBmbHVzaFN5bmNDYWxsYmFja3NPbmx5SW5MZWdhY3lNb2RlKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBkaXNjcmV0ZVVwZGF0ZXMoZm4sIGEsIGIsIGMsIGQpIHtcbiAgdmFyIHByZXZpb3VzUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcbiAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uO1xuXG4gIHRyeSB7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gbnVsbDtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoRGlzY3JldGVFdmVudFByaW9yaXR5KTtcbiAgICByZXR1cm4gZm4oYSwgYiwgYywgZCk7XG4gIH0gZmluYWxseSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IHByZXZUcmFuc2l0aW9uO1xuXG4gICAgaWYgKGV4ZWN1dGlvbkNvbnRleHQgPT09IE5vQ29udGV4dCkge1xuICAgICAgcmVzZXRSZW5kZXJUaW1lcigpO1xuICAgIH1cbiAgfVxufSAvLyBPdmVybG9hZCB0aGUgZGVmaW5pdGlvbiB0byB0aGUgdHdvIHZhbGlkIHNpZ25hdHVyZXMuXG4vLyBXYXJuaW5nLCB0aGlzIG9wdHMtb3V0IG9mIGNoZWNraW5nIHRoZSBmdW5jdGlvbiBib2R5LlxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG5mdW5jdGlvbiBmbHVzaFN5bmMoZm4pIHtcbiAgLy8gSW4gbGVnYWN5IG1vZGUsIHdlIGZsdXNoIHBlbmRpbmcgcGFzc2l2ZSBlZmZlY3RzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlXG4gIC8vIG5leHQgZXZlbnQsIG5vdCBhdCB0aGUgZW5kIG9mIHRoZSBwcmV2aW91cyBvbmUuXG4gIGlmIChyb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyAhPT0gbnVsbCAmJiByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cy50YWcgPT09IExlZ2FjeVJvb3QgJiYgKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSA9PT0gTm9Db250ZXh0KSB7XG4gICAgZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuICB9XG5cbiAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgZXhlY3V0aW9uQ29udGV4dCB8PSBCYXRjaGVkQ29udGV4dDtcbiAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uO1xuICB2YXIgcHJldmlvdXNQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuXG4gIHRyeSB7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gbnVsbDtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoRGlzY3JldGVFdmVudFByaW9yaXR5KTtcblxuICAgIGlmIChmbikge1xuICAgICAgcmV0dXJuIGZuKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcbiAgICBleGVjdXRpb25Db250ZXh0ID0gcHJldkV4ZWN1dGlvbkNvbnRleHQ7IC8vIEZsdXNoIHRoZSBpbW1lZGlhdGUgY2FsbGJhY2tzIHRoYXQgd2VyZSBzY2hlZHVsZWQgZHVyaW5nIHRoaXMgYmF0Y2guXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgd2lsbCBoYXBwZW4gZXZlbiBpZiBiYXRjaGVkVXBkYXRlcyBpcyBoaWdoZXIgdXBcbiAgICAvLyB0aGUgc3RhY2suXG5cbiAgICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSA9PT0gTm9Db250ZXh0KSB7XG4gICAgICBmbHVzaFN5bmNDYWxsYmFja3MoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGlzQWxyZWFkeVJlbmRlcmluZygpIHtcbiAgLy8gVXNlZCBieSB0aGUgcmVuZGVyZXIgdG8gcHJpbnQgYSB3YXJuaW5nIGlmIGNlcnRhaW4gQVBJcyBhcmUgY2FsbGVkIGZyb21cbiAgLy8gdGhlIHdyb25nIGNvbnRleHQuXG4gIHJldHVybiAgKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0O1xufVxuZnVuY3Rpb24gcHVzaFJlbmRlckxhbmVzKGZpYmVyLCBsYW5lcykge1xuICBwdXNoKHN1YnRyZWVSZW5kZXJMYW5lc0N1cnNvciwgc3VidHJlZVJlbmRlckxhbmVzLCBmaWJlcik7XG4gIHN1YnRyZWVSZW5kZXJMYW5lcyA9IG1lcmdlTGFuZXMoc3VidHJlZVJlbmRlckxhbmVzLCBsYW5lcyk7XG4gIHdvcmtJblByb2dyZXNzUm9vdEluY2x1ZGVkTGFuZXMgPSBtZXJnZUxhbmVzKHdvcmtJblByb2dyZXNzUm9vdEluY2x1ZGVkTGFuZXMsIGxhbmVzKTtcbn1cbmZ1bmN0aW9uIHBvcFJlbmRlckxhbmVzKGZpYmVyKSB7XG4gIHN1YnRyZWVSZW5kZXJMYW5lcyA9IHN1YnRyZWVSZW5kZXJMYW5lc0N1cnNvci5jdXJyZW50O1xuICBwb3Aoc3VidHJlZVJlbmRlckxhbmVzQ3Vyc29yLCBmaWJlcik7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIGxhbmVzKSB7XG4gIHJvb3QuZmluaXNoZWRXb3JrID0gbnVsbDtcbiAgcm9vdC5maW5pc2hlZExhbmVzID0gTm9MYW5lcztcbiAgdmFyIHRpbWVvdXRIYW5kbGUgPSByb290LnRpbWVvdXRIYW5kbGU7XG5cbiAgaWYgKHRpbWVvdXRIYW5kbGUgIT09IG5vVGltZW91dCkge1xuICAgIC8vIFRoZSByb290IHByZXZpb3VzIHN1c3BlbmRlZCBhbmQgc2NoZWR1bGVkIGEgdGltZW91dCB0byBjb21taXQgYSBmYWxsYmFja1xuICAgIC8vIHN0YXRlLiBOb3cgdGhhdCB3ZSBoYXZlIGFkZGl0aW9uYWwgd29yaywgY2FuY2VsIHRoZSB0aW1lb3V0LlxuICAgIHJvb3QudGltZW91dEhhbmRsZSA9IG5vVGltZW91dDsgLy8gJEZsb3dGaXhNZSBDb21wbGFpbnMgbm9UaW1lb3V0IGlzIG5vdCBhIFRpbWVvdXRJRCwgZGVzcGl0ZSB0aGUgY2hlY2sgYWJvdmVcblxuICAgIGNhbmNlbFRpbWVvdXQodGltZW91dEhhbmRsZSk7XG4gIH1cblxuICBpZiAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpIHtcbiAgICB2YXIgaW50ZXJydXB0ZWRXb3JrID0gd29ya0luUHJvZ3Jlc3MucmV0dXJuO1xuXG4gICAgd2hpbGUgKGludGVycnVwdGVkV29yayAhPT0gbnVsbCkge1xuICAgICAgdmFyIGN1cnJlbnQgPSBpbnRlcnJ1cHRlZFdvcmsuYWx0ZXJuYXRlO1xuICAgICAgdW53aW5kSW50ZXJydXB0ZWRXb3JrKGN1cnJlbnQsIGludGVycnVwdGVkV29yayk7XG4gICAgICBpbnRlcnJ1cHRlZFdvcmsgPSBpbnRlcnJ1cHRlZFdvcmsucmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHdvcmtJblByb2dyZXNzUm9vdCA9IHJvb3Q7XG4gIHZhciByb290V29ya0luUHJvZ3Jlc3MgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhyb290LmN1cnJlbnQsIG51bGwpO1xuICB3b3JrSW5Qcm9ncmVzcyA9IHJvb3RXb3JrSW5Qcm9ncmVzcztcbiAgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgPSBzdWJ0cmVlUmVuZGVyTGFuZXMgPSB3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzID0gbGFuZXM7XG4gIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290SW5Qcm9ncmVzcztcbiAgd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvciA9IG51bGw7XG4gIHdvcmtJblByb2dyZXNzUm9vdFNraXBwZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHdvcmtJblByb2dyZXNzUm9vdEludGVybGVhdmVkVXBkYXRlZExhbmVzID0gTm9MYW5lcztcbiAgd29ya0luUHJvZ3Jlc3NSb290UGluZ2VkTGFuZXMgPSBOb0xhbmVzO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMgPSBudWxsO1xuICBlbnF1ZXVlSW50ZXJsZWF2ZWRVcGRhdGVzKCk7XG5cbiAge1xuICAgIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLmRpc2NhcmRQZW5kaW5nV2FybmluZ3MoKTtcbiAgfVxuXG4gIHJldHVybiByb290V29ya0luUHJvZ3Jlc3M7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUVycm9yKHJvb3QsIHRocm93blZhbHVlKSB7XG4gIGRvIHtcbiAgICB2YXIgZXJyb3JlZFdvcmsgPSB3b3JrSW5Qcm9ncmVzcztcblxuICAgIHRyeSB7XG4gICAgICAvLyBSZXNldCBtb2R1bGUtbGV2ZWwgc3RhdGUgdGhhdCB3YXMgc2V0IGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlLlxuICAgICAgcmVzZXRDb250ZXh0RGVwZW5kZW5jaWVzKCk7XG4gICAgICByZXNldEhvb2tzQWZ0ZXJUaHJvdygpO1xuICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTsgLy8gVE9ETzogSSBmb3VuZCBhbmQgYWRkZWQgdGhpcyBtaXNzaW5nIGxpbmUgd2hpbGUgaW52ZXN0aWdhdGluZyBhXG4gICAgICAvLyBzZXBhcmF0ZSBpc3N1ZS4gV3JpdGUgYSByZWdyZXNzaW9uIHRlc3QgdXNpbmcgc3RyaW5nIHJlZnMuXG5cbiAgICAgIFJlYWN0Q3VycmVudE93bmVyJDIuY3VycmVudCA9IG51bGw7XG5cbiAgICAgIGlmIChlcnJvcmVkV29yayA9PT0gbnVsbCB8fCBlcnJvcmVkV29yay5yZXR1cm4gPT09IG51bGwpIHtcbiAgICAgICAgLy8gRXhwZWN0ZWQgdG8gYmUgd29ya2luZyBvbiBhIG5vbi1yb290IGZpYmVyLiBUaGlzIGlzIGEgZmF0YWwgZXJyb3JcbiAgICAgICAgLy8gYmVjYXVzZSB0aGVyZSdzIG5vIGFuY2VzdG9yIHRoYXQgY2FuIGhhbmRsZSBpdDsgdGhlIHJvb3QgaXNcbiAgICAgICAgLy8gc3VwcG9zZWQgdG8gY2FwdHVyZSBhbGwgZXJyb3JzIHRoYXQgd2VyZW4ndCBjYXVnaHQgYnkgYW4gZXJyb3JcbiAgICAgICAgLy8gYm91bmRhcnkuXG4gICAgICAgIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290RmF0YWxFcnJvcmVkO1xuICAgICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RGYXRhbEVycm9yID0gdGhyb3duVmFsdWU7IC8vIFNldCBgd29ya0luUHJvZ3Jlc3NgIHRvIG51bGwuIFRoaXMgcmVwcmVzZW50cyBhZHZhbmNpbmcgdG8gdGhlIG5leHRcbiAgICAgICAgLy8gc2libGluZywgb3IgdGhlIHBhcmVudCBpZiB0aGVyZSBhcmUgbm8gc2libGluZ3MuIEJ1dCBzaW5jZSB0aGUgcm9vdFxuICAgICAgICAvLyBoYXMgbm8gc2libGluZ3Mgbm9yIGEgcGFyZW50LCB3ZSBzZXQgaXQgdG8gbnVsbC4gVXN1YWxseSB0aGlzIGlzXG4gICAgICAgIC8vIGhhbmRsZWQgYnkgYGNvbXBsZXRlVW5pdE9mV29ya2Agb3IgYHVud2luZFdvcmtgLCBidXQgc2luY2Ugd2UncmVcbiAgICAgICAgLy8gaW50ZW50aW9uYWxseSBub3QgY2FsbGluZyB0aG9zZSwgd2UgbmVlZCBzZXQgaXQgaGVyZS5cbiAgICAgICAgLy8gVE9ETzogQ29uc2lkZXIgY2FsbGluZyBgdW53aW5kV29ya2AgdG8gcG9wIHRoZSBjb250ZXh0cy5cblxuICAgICAgICB3b3JrSW5Qcm9ncmVzcyA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGVuYWJsZVByb2ZpbGVyVGltZXIgJiYgZXJyb3JlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgIC8vIFJlY29yZCB0aGUgdGltZSBzcGVudCByZW5kZXJpbmcgYmVmb3JlIGFuIGVycm9yIHdhcyB0aHJvd24uIFRoaXNcbiAgICAgICAgLy8gYXZvaWRzIGluYWNjdXJhdGUgUHJvZmlsZXIgZHVyYXRpb25zIGluIHRoZSBjYXNlIG9mIGFcbiAgICAgICAgLy8gc3VzcGVuZGVkIHJlbmRlci5cbiAgICAgICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YShlcnJvcmVkV29yaywgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbmFibGVTY2hlZHVsaW5nUHJvZmlsZXIpIHtcbiAgICAgICAgbWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQoKTtcblxuICAgICAgICBpZiAodGhyb3duVmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHRocm93blZhbHVlID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgdGhyb3duVmFsdWUudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHZhciB3YWtlYWJsZSA9IHRocm93blZhbHVlO1xuICAgICAgICAgIG1hcmtDb21wb25lbnRTdXNwZW5kZWQoZXJyb3JlZFdvcmssIHdha2VhYmxlLCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWFya0NvbXBvbmVudEVycm9yZWQoZXJyb3JlZFdvcmssIHRocm93blZhbHVlLCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhyb3dFeGNlcHRpb24ocm9vdCwgZXJyb3JlZFdvcmsucmV0dXJuLCBlcnJvcmVkV29yaywgdGhyb3duVmFsdWUsIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgICAgIGNvbXBsZXRlVW5pdE9mV29yayhlcnJvcmVkV29yayk7XG4gICAgfSBjYXRjaCAoeWV0QW5vdGhlclRocm93blZhbHVlKSB7XG4gICAgICAvLyBTb21ldGhpbmcgaW4gdGhlIHJldHVybiBwYXRoIGFsc28gdGhyZXcuXG4gICAgICB0aHJvd25WYWx1ZSA9IHlldEFub3RoZXJUaHJvd25WYWx1ZTtcblxuICAgICAgaWYgKHdvcmtJblByb2dyZXNzID09PSBlcnJvcmVkV29yayAmJiBlcnJvcmVkV29yayAhPT0gbnVsbCkge1xuICAgICAgICAvLyBJZiB0aGlzIGJvdW5kYXJ5IGhhcyBhbHJlYWR5IGVycm9yZWQsIHRoZW4gd2UgaGFkIHRyb3VibGUgcHJvY2Vzc2luZ1xuICAgICAgICAvLyB0aGUgZXJyb3IuIEJ1YmJsZSBpdCB0byB0aGUgbmV4dCBib3VuZGFyeS5cbiAgICAgICAgZXJyb3JlZFdvcmsgPSBlcnJvcmVkV29yay5yZXR1cm47XG4gICAgICAgIHdvcmtJblByb2dyZXNzID0gZXJyb3JlZFdvcms7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcmVkV29yayA9IHdvcmtJblByb2dyZXNzO1xuICAgICAgfVxuXG4gICAgICBjb250aW51ZTtcbiAgICB9IC8vIFJldHVybiB0byB0aGUgbm9ybWFsIHdvcmsgbG9vcC5cblxuXG4gICAgcmV0dXJuO1xuICB9IHdoaWxlICh0cnVlKTtcbn1cblxuZnVuY3Rpb24gcHVzaERpc3BhdGNoZXIoKSB7XG4gIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMi5jdXJyZW50O1xuICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDIuY3VycmVudCA9IENvbnRleHRPbmx5RGlzcGF0Y2hlcjtcblxuICBpZiAocHJldkRpc3BhdGNoZXIgPT09IG51bGwpIHtcbiAgICAvLyBUaGUgUmVhY3QgaXNvbW9ycGhpYyBwYWNrYWdlIGRvZXMgbm90IGluY2x1ZGUgYSBkZWZhdWx0IGRpc3BhdGNoZXIuXG4gICAgLy8gSW5zdGVhZCB0aGUgZmlyc3QgcmVuZGVyZXIgd2lsbCBsYXppbHkgYXR0YWNoIG9uZSwgaW4gb3JkZXIgdG8gZ2l2ZVxuICAgIC8vIG5pY2VyIGVycm9yIG1lc3NhZ2VzLlxuICAgIHJldHVybiBDb250ZXh0T25seURpc3BhdGNoZXI7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHByZXZEaXNwYXRjaGVyO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBvcERpc3BhdGNoZXIocHJldkRpc3BhdGNoZXIpIHtcbiAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQyLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbn1cblxuZnVuY3Rpb24gbWFya0NvbW1pdFRpbWVPZkZhbGxiYWNrKCkge1xuICBnbG9iYWxNb3N0UmVjZW50RmFsbGJhY2tUaW1lID0gbm93KCk7XG59XG5mdW5jdGlvbiBtYXJrU2tpcHBlZFVwZGF0ZUxhbmVzKGxhbmUpIHtcbiAgd29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzID0gbWVyZ2VMYW5lcyhsYW5lLCB3b3JrSW5Qcm9ncmVzc1Jvb3RTa2lwcGVkTGFuZXMpO1xufVxuZnVuY3Rpb24gcmVuZGVyRGlkU3VzcGVuZCgpIHtcbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RJblByb2dyZXNzKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9IFJvb3RTdXNwZW5kZWQ7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlbmRlckRpZFN1c3BlbmREZWxheUlmUG9zc2libGUoKSB7XG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290SW5Qcm9ncmVzcyB8fCB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290U3VzcGVuZGVkIHx8IHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RFcnJvcmVkKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9IFJvb3RTdXNwZW5kZWRXaXRoRGVsYXk7XG4gIH0gLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIHVwZGF0ZXMgdGhhdCB3ZSBza2lwcGVkIHRyZWUgdGhhdCBtaWdodCBoYXZlIHVuYmxvY2tlZFxuICAvLyB0aGlzIHJlbmRlci5cblxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3QgIT09IG51bGwgJiYgKGluY2x1ZGVzTm9uSWRsZVdvcmsod29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzKSB8fCBpbmNsdWRlc05vbklkbGVXb3JrKHdvcmtJblByb2dyZXNzUm9vdEludGVybGVhdmVkVXBkYXRlZExhbmVzKSkpIHtcbiAgICAvLyBNYXJrIHRoZSBjdXJyZW50IHJlbmRlciBhcyBzdXNwZW5kZWQgc28gdGhhdCB3ZSBzd2l0Y2ggdG8gd29ya2luZyBvblxuICAgIC8vIHRoZSB1cGRhdGVzIHRoYXQgd2VyZSBza2lwcGVkLiBVc3VhbGx5IHdlIG9ubHkgc3VzcGVuZCBhdCB0aGUgZW5kIG9mXG4gICAgLy8gdGhlIHJlbmRlciBwaGFzZS5cbiAgICAvLyBUT0RPOiBXZSBzaG91bGQgcHJvYmFibHkgYWx3YXlzIG1hcmsgdGhlIHJvb3QgYXMgc3VzcGVuZGVkIGltbWVkaWF0ZWx5XG4gICAgLy8gKGluc2lkZSB0aGlzIGZ1bmN0aW9uKSwgc2luY2UgYnkgc3VzcGVuZGluZyBhdCB0aGUgZW5kIG9mIHRoZSByZW5kZXJcbiAgICAvLyBwaGFzZSBpbnRyb2R1Y2VzIGEgcG90ZW50aWFsIG1pc3Rha2Ugd2hlcmUgd2Ugc3VzcGVuZCBsYW5lcyB0aGF0IHdlcmVcbiAgICAvLyBwaW5nZWQgb3IgdXBkYXRlZCB3aGlsZSB3ZSB3ZXJlIHJlbmRlcmluZy5cbiAgICBtYXJrUm9vdFN1c3BlbmRlZCQxKHdvcmtJblByb2dyZXNzUm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICB9XG59XG5mdW5jdGlvbiByZW5kZXJEaWRFcnJvcihlcnJvcikge1xuICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyAhPT0gUm9vdFN1c3BlbmRlZFdpdGhEZWxheSkge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290RXJyb3JlZDtcbiAgfVxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzID09PSBudWxsKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290Q29uY3VycmVudEVycm9ycyA9IFtlcnJvcl07XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290Q29uY3VycmVudEVycm9ycy5wdXNoKGVycm9yKTtcbiAgfVxufSAvLyBDYWxsZWQgZHVyaW5nIHJlbmRlciB0byBkZXRlcm1pbmUgaWYgYW55dGhpbmcgaGFzIHN1c3BlbmRlZC5cbi8vIFJldHVybnMgZmFsc2UgaWYgd2UncmUgbm90IHN1cmUuXG5cbmZ1bmN0aW9uIHJlbmRlckhhc05vdFN1c3BlbmRlZFlldCgpIHtcbiAgLy8gSWYgc29tZXRoaW5nIGVycm9yZWQgb3IgY29tcGxldGVkLCB3ZSBjYW4ndCByZWFsbHkgYmUgc3VyZSxcbiAgLy8gc28gdGhvc2UgYXJlIGZhbHNlLlxuICByZXR1cm4gd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdEluUHJvZ3Jlc3M7XG59XG5cbmZ1bmN0aW9uIHJlbmRlclJvb3RTeW5jKHJvb3QsIGxhbmVzKSB7XG4gIHZhciBwcmV2RXhlY3V0aW9uQ29udGV4dCA9IGV4ZWN1dGlvbkNvbnRleHQ7XG4gIGV4ZWN1dGlvbkNvbnRleHQgfD0gUmVuZGVyQ29udGV4dDtcbiAgdmFyIHByZXZEaXNwYXRjaGVyID0gcHVzaERpc3BhdGNoZXIoKTsgLy8gSWYgdGhlIHJvb3Qgb3IgbGFuZXMgaGF2ZSBjaGFuZ2VkLCB0aHJvdyBvdXQgdGhlIGV4aXN0aW5nIHN0YWNrXG4gIC8vIGFuZCBwcmVwYXJlIGEgZnJlc2ggb25lLiBPdGhlcndpc2Ugd2UnbGwgY29udGludWUgd2hlcmUgd2UgbGVmdCBvZmYuXG5cbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdCAhPT0gcm9vdCB8fCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyAhPT0gbGFuZXMpIHtcbiAgICB7XG4gICAgICBpZiAoaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICAgICAgdmFyIG1lbW9pemVkVXBkYXRlcnMgPSByb290Lm1lbW9pemVkVXBkYXRlcnM7XG5cbiAgICAgICAgaWYgKG1lbW9pemVkVXBkYXRlcnMuc2l6ZSA+IDApIHtcbiAgICAgICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgICAgICAgICBtZW1vaXplZFVwZGF0ZXJzLmNsZWFyKCk7XG4gICAgICAgIH0gLy8gQXQgdGhpcyBwb2ludCwgbW92ZSBGaWJlcnMgdGhhdCBzY2hlZHVsZWQgdGhlIHVwY29taW5nIHdvcmsgZnJvbSB0aGUgTWFwIHRvIHRoZSBTZXQuXG4gICAgICAgIC8vIElmIHdlIGJhaWxvdXQgb24gdGhpcyB3b3JrLCB3ZSdsbCBtb3ZlIHRoZW0gYmFjayAobGlrZSBhYm92ZSkuXG4gICAgICAgIC8vIEl0J3MgaW1wb3J0YW50IHRvIG1vdmUgdGhlbSBub3cgaW4gY2FzZSB0aGUgd29yayBzcGF3bnMgbW9yZSB3b3JrIGF0IHRoZSBzYW1lIHByaW9yaXR5IHdpdGggZGlmZmVyZW50IHVwZGF0ZXJzLlxuICAgICAgICAvLyBUaGF0IHdheSB3ZSBjYW4ga2VlcCB0aGUgY3VycmVudCB1cGRhdGUgYW5kIGZ1dHVyZSB1cGRhdGVzIHNlcGFyYXRlLlxuXG5cbiAgICAgICAgbW92ZVBlbmRpbmdGaWJlcnNUb01lbW9pemVkKHJvb3QsIGxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zID0gZ2V0VHJhbnNpdGlvbnNGb3JMYW5lcygpO1xuICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIGxhbmVzKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrUmVuZGVyU3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICBkbyB7XG4gICAgdHJ5IHtcbiAgICAgIHdvcmtMb29wU3luYygpO1xuICAgICAgYnJlYWs7XG4gICAgfSBjYXRjaCAodGhyb3duVmFsdWUpIHtcbiAgICAgIGhhbmRsZUVycm9yKHJvb3QsIHRocm93blZhbHVlKTtcbiAgICB9XG4gIH0gd2hpbGUgKHRydWUpO1xuXG4gIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICBleGVjdXRpb25Db250ZXh0ID0gcHJldkV4ZWN1dGlvbkNvbnRleHQ7XG4gIHBvcERpc3BhdGNoZXIocHJldkRpc3BhdGNoZXIpO1xuXG4gIGlmICh3b3JrSW5Qcm9ncmVzcyAhPT0gbnVsbCkge1xuICAgIC8vIFRoaXMgaXMgYSBzeW5jIHJlbmRlciwgc28gd2Ugc2hvdWxkIGhhdmUgZmluaXNoZWQgdGhlIHdob2xlIHRyZWUuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29tbWl0IGFuIGluY29tcGxldGUgcm9vdC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgJyArICdidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAge1xuICAgIG1hcmtSZW5kZXJTdG9wcGVkKCk7XG4gIH0gLy8gU2V0IHRoaXMgdG8gbnVsbCB0byBpbmRpY2F0ZSB0aGVyZSdzIG5vIGluLXByb2dyZXNzIHJlbmRlci5cblxuXG4gIHdvcmtJblByb2dyZXNzUm9vdCA9IG51bGw7XG4gIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lcztcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXM7XG59IC8vIFRoZSB3b3JrIGxvb3AgaXMgYW4gZXh0cmVtZWx5IGhvdCBwYXRoLiBUZWxsIENsb3N1cmUgbm90IHRvIGlubGluZSBpdC5cblxuLyoqIEBub2lubGluZSAqL1xuXG5cbmZ1bmN0aW9uIHdvcmtMb29wU3luYygpIHtcbiAgLy8gQWxyZWFkeSB0aW1lZCBvdXQsIHNvIHBlcmZvcm0gd29yayB3aXRob3V0IGNoZWNraW5nIGlmIHdlIG5lZWQgdG8geWllbGQuXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyAhPT0gbnVsbCkge1xuICAgIHBlcmZvcm1Vbml0T2ZXb3JrKHdvcmtJblByb2dyZXNzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSb290Q29uY3VycmVudChyb290LCBsYW5lcykge1xuICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICBleGVjdXRpb25Db250ZXh0IHw9IFJlbmRlckNvbnRleHQ7XG4gIHZhciBwcmV2RGlzcGF0Y2hlciA9IHB1c2hEaXNwYXRjaGVyKCk7IC8vIElmIHRoZSByb290IG9yIGxhbmVzIGhhdmUgY2hhbmdlZCwgdGhyb3cgb3V0IHRoZSBleGlzdGluZyBzdGFja1xuICAvLyBhbmQgcHJlcGFyZSBhIGZyZXNoIG9uZS4gT3RoZXJ3aXNlIHdlJ2xsIGNvbnRpbnVlIHdoZXJlIHdlIGxlZnQgb2ZmLlxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3QgIT09IHJvb3QgfHwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgIT09IGxhbmVzKSB7XG4gICAge1xuICAgICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICAgIHZhciBtZW1vaXplZFVwZGF0ZXJzID0gcm9vdC5tZW1vaXplZFVwZGF0ZXJzO1xuXG4gICAgICAgIGlmIChtZW1vaXplZFVwZGF0ZXJzLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmVzdG9yZVBlbmRpbmdVcGRhdGVycyhyb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICAgICAgbWVtb2l6ZWRVcGRhdGVycy5jbGVhcigpO1xuICAgICAgICB9IC8vIEF0IHRoaXMgcG9pbnQsIG1vdmUgRmliZXJzIHRoYXQgc2NoZWR1bGVkIHRoZSB1cGNvbWluZyB3b3JrIGZyb20gdGhlIE1hcCB0byB0aGUgU2V0LlxuICAgICAgICAvLyBJZiB3ZSBiYWlsb3V0IG9uIHRoaXMgd29yaywgd2UnbGwgbW92ZSB0aGVtIGJhY2sgKGxpa2UgYWJvdmUpLlxuICAgICAgICAvLyBJdCdzIGltcG9ydGFudCB0byBtb3ZlIHRoZW0gbm93IGluIGNhc2UgdGhlIHdvcmsgc3Bhd25zIG1vcmUgd29yayBhdCB0aGUgc2FtZSBwcmlvcml0eSB3aXRoIGRpZmZlcmVudCB1cGRhdGVycy5cbiAgICAgICAgLy8gVGhhdCB3YXkgd2UgY2FuIGtlZXAgdGhlIGN1cnJlbnQgdXBkYXRlIGFuZCBmdXR1cmUgdXBkYXRlcyBzZXBhcmF0ZS5cblxuXG4gICAgICAgIG1vdmVQZW5kaW5nRmliZXJzVG9NZW1vaXplZChyb290LCBsYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyA9IGdldFRyYW5zaXRpb25zRm9yTGFuZXMoKTtcbiAgICByZXNldFJlbmRlclRpbWVyKCk7XG4gICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgbGFuZXMpO1xuICB9XG5cbiAge1xuICAgIG1hcmtSZW5kZXJTdGFydGVkKGxhbmVzKTtcbiAgfVxuXG4gIGRvIHtcbiAgICB0cnkge1xuICAgICAgd29ya0xvb3BDb25jdXJyZW50KCk7XG4gICAgICBicmVhaztcbiAgICB9IGNhdGNoICh0aHJvd25WYWx1ZSkge1xuICAgICAgaGFuZGxlRXJyb3Iocm9vdCwgdGhyb3duVmFsdWUpO1xuICAgIH1cbiAgfSB3aGlsZSAodHJ1ZSk7XG5cbiAgcmVzZXRDb250ZXh0RGVwZW5kZW5jaWVzKCk7XG4gIHBvcERpc3BhdGNoZXIocHJldkRpc3BhdGNoZXIpO1xuICBleGVjdXRpb25Db250ZXh0ID0gcHJldkV4ZWN1dGlvbkNvbnRleHQ7XG5cblxuICBpZiAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpIHtcbiAgICAvLyBTdGlsbCB3b3JrIHJlbWFpbmluZy5cbiAgICB7XG4gICAgICBtYXJrUmVuZGVyWWllbGRlZCgpO1xuICAgIH1cblxuICAgIHJldHVybiBSb290SW5Qcm9ncmVzcztcbiAgfSBlbHNlIHtcbiAgICAvLyBDb21wbGV0ZWQgdGhlIHRyZWUuXG4gICAge1xuICAgICAgbWFya1JlbmRlclN0b3BwZWQoKTtcbiAgICB9IC8vIFNldCB0aGlzIHRvIG51bGwgdG8gaW5kaWNhdGUgdGhlcmUncyBubyBpbi1wcm9ncmVzcyByZW5kZXIuXG5cblxuICAgIHdvcmtJblByb2dyZXNzUm9vdCA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgPSBOb0xhbmVzOyAvLyBSZXR1cm4gdGhlIGZpbmFsIGV4aXQgc3RhdHVzLlxuXG4gICAgcmV0dXJuIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXM7XG4gIH1cbn1cbi8qKiBAbm9pbmxpbmUgKi9cblxuXG5mdW5jdGlvbiB3b3JrTG9vcENvbmN1cnJlbnQoKSB7XG4gIC8vIFBlcmZvcm0gd29yayB1bnRpbCBTY2hlZHVsZXIgYXNrcyB1cyB0byB5aWVsZFxuICB3aGlsZSAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwgJiYgIXNob3VsZFlpZWxkKCkpIHtcbiAgICBwZXJmb3JtVW5pdE9mV29yayh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGVyZm9ybVVuaXRPZldvcmsodW5pdE9mV29yaykge1xuICAvLyBUaGUgY3VycmVudCwgZmx1c2hlZCwgc3RhdGUgb2YgdGhpcyBmaWJlciBpcyB0aGUgYWx0ZXJuYXRlLiBJZGVhbGx5XG4gIC8vIG5vdGhpbmcgc2hvdWxkIHJlbHkgb24gdGhpcywgYnV0IHJlbHlpbmcgb24gaXQgaGVyZSBtZWFucyB0aGF0IHdlIGRvbid0XG4gIC8vIG5lZWQgYW4gYWRkaXRpb25hbCBmaWVsZCBvbiB0aGUgd29yayBpbiBwcm9ncmVzcy5cbiAgdmFyIGN1cnJlbnQgPSB1bml0T2ZXb3JrLmFsdGVybmF0ZTtcbiAgc2V0Q3VycmVudEZpYmVyKHVuaXRPZldvcmspO1xuICB2YXIgbmV4dDtcblxuICBpZiAoICh1bml0T2ZXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkgIT09IE5vTW9kZSkge1xuICAgIHN0YXJ0UHJvZmlsZXJUaW1lcih1bml0T2ZXb3JrKTtcbiAgICBuZXh0ID0gYmVnaW5Xb3JrJDEoY3VycmVudCwgdW5pdE9mV29yaywgc3VidHJlZVJlbmRlckxhbmVzKTtcbiAgICBzdG9wUHJvZmlsZXJUaW1lcklmUnVubmluZ0FuZFJlY29yZERlbHRhKHVuaXRPZldvcmssIHRydWUpO1xuICB9IGVsc2Uge1xuICAgIG5leHQgPSBiZWdpbldvcmskMShjdXJyZW50LCB1bml0T2ZXb3JrLCBzdWJ0cmVlUmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgdW5pdE9mV29yay5tZW1vaXplZFByb3BzID0gdW5pdE9mV29yay5wZW5kaW5nUHJvcHM7XG5cbiAgaWYgKG5leHQgPT09IG51bGwpIHtcbiAgICAvLyBJZiB0aGlzIGRvZXNuJ3Qgc3Bhd24gbmV3IHdvcmssIGNvbXBsZXRlIHRoZSBjdXJyZW50IHdvcmsuXG4gICAgY29tcGxldGVVbml0T2ZXb3JrKHVuaXRPZldvcmspO1xuICB9IGVsc2Uge1xuICAgIHdvcmtJblByb2dyZXNzID0gbmV4dDtcbiAgfVxuXG4gIFJlYWN0Q3VycmVudE93bmVyJDIuY3VycmVudCA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGNvbXBsZXRlVW5pdE9mV29yayh1bml0T2ZXb3JrKSB7XG4gIC8vIEF0dGVtcHQgdG8gY29tcGxldGUgdGhlIGN1cnJlbnQgdW5pdCBvZiB3b3JrLCB0aGVuIG1vdmUgdG8gdGhlIG5leHRcbiAgLy8gc2libGluZy4gSWYgdGhlcmUgYXJlIG5vIG1vcmUgc2libGluZ3MsIHJldHVybiB0byB0aGUgcGFyZW50IGZpYmVyLlxuICB2YXIgY29tcGxldGVkV29yayA9IHVuaXRPZldvcms7XG5cbiAgZG8ge1xuICAgIC8vIFRoZSBjdXJyZW50LCBmbHVzaGVkLCBzdGF0ZSBvZiB0aGlzIGZpYmVyIGlzIHRoZSBhbHRlcm5hdGUuIElkZWFsbHlcbiAgICAvLyBub3RoaW5nIHNob3VsZCByZWx5IG9uIHRoaXMsIGJ1dCByZWx5aW5nIG9uIGl0IGhlcmUgbWVhbnMgdGhhdCB3ZSBkb24ndFxuICAgIC8vIG5lZWQgYW4gYWRkaXRpb25hbCBmaWVsZCBvbiB0aGUgd29yayBpbiBwcm9ncmVzcy5cbiAgICB2YXIgY3VycmVudCA9IGNvbXBsZXRlZFdvcmsuYWx0ZXJuYXRlO1xuICAgIHZhciByZXR1cm5GaWJlciA9IGNvbXBsZXRlZFdvcmsucmV0dXJuOyAvLyBDaGVjayBpZiB0aGUgd29yayBjb21wbGV0ZWQgb3IgaWYgc29tZXRoaW5nIHRocmV3LlxuXG4gICAgaWYgKChjb21wbGV0ZWRXb3JrLmZsYWdzICYgSW5jb21wbGV0ZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgIHNldEN1cnJlbnRGaWJlcihjb21wbGV0ZWRXb3JrKTtcbiAgICAgIHZhciBuZXh0ID0gdm9pZCAwO1xuXG4gICAgICBpZiAoIChjb21wbGV0ZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkgPT09IE5vTW9kZSkge1xuICAgICAgICBuZXh0ID0gY29tcGxldGVXb3JrKGN1cnJlbnQsIGNvbXBsZXRlZFdvcmssIHN1YnRyZWVSZW5kZXJMYW5lcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGFydFByb2ZpbGVyVGltZXIoY29tcGxldGVkV29yayk7XG4gICAgICAgIG5leHQgPSBjb21wbGV0ZVdvcmsoY3VycmVudCwgY29tcGxldGVkV29yaywgc3VidHJlZVJlbmRlckxhbmVzKTsgLy8gVXBkYXRlIHJlbmRlciBkdXJhdGlvbiBhc3N1bWluZyB3ZSBkaWRuJ3QgZXJyb3IuXG5cbiAgICAgICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YShjb21wbGV0ZWRXb3JrLCBmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG5cbiAgICAgIGlmIChuZXh0ICE9PSBudWxsKSB7XG4gICAgICAgIC8vIENvbXBsZXRpbmcgdGhpcyBmaWJlciBzcGF3bmVkIG5ldyB3b3JrLiBXb3JrIG9uIHRoYXQgbmV4dC5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3MgPSBuZXh0O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoaXMgZmliZXIgZGlkIG5vdCBjb21wbGV0ZSBiZWNhdXNlIHNvbWV0aGluZyB0aHJldy4gUG9wIHZhbHVlcyBvZmZcbiAgICAgIC8vIHRoZSBzdGFjayB3aXRob3V0IGVudGVyaW5nIHRoZSBjb21wbGV0ZSBwaGFzZS4gSWYgdGhpcyBpcyBhIGJvdW5kYXJ5LFxuICAgICAgLy8gY2FwdHVyZSB2YWx1ZXMgaWYgcG9zc2libGUuXG4gICAgICB2YXIgX25leHQgPSB1bndpbmRXb3JrKGN1cnJlbnQsIGNvbXBsZXRlZFdvcmspOyAvLyBCZWNhdXNlIHRoaXMgZmliZXIgZGlkIG5vdCBjb21wbGV0ZSwgZG9uJ3QgcmVzZXQgaXRzIGxhbmVzLlxuXG5cbiAgICAgIGlmIChfbmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBJZiBjb21wbGV0aW5nIHRoaXMgd29yayBzcGF3bmVkIG5ldyB3b3JrLCBkbyB0aGF0IG5leHQuIFdlJ2xsIGNvbWVcbiAgICAgICAgLy8gYmFjayBoZXJlIGFnYWluLlxuICAgICAgICAvLyBTaW5jZSB3ZSdyZSByZXN0YXJ0aW5nLCByZW1vdmUgYW55dGhpbmcgdGhhdCBpcyBub3QgYSBob3N0IGVmZmVjdFxuICAgICAgICAvLyBmcm9tIHRoZSBlZmZlY3QgdGFnLlxuICAgICAgICBfbmV4dC5mbGFncyAmPSBIb3N0RWZmZWN0TWFzaztcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MgPSBfbmV4dDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIChjb21wbGV0ZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAvLyBSZWNvcmQgdGhlIHJlbmRlciBkdXJhdGlvbiBmb3IgdGhlIGZpYmVyIHRoYXQgZXJyb3JlZC5cbiAgICAgICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YShjb21wbGV0ZWRXb3JrLCBmYWxzZSk7IC8vIEluY2x1ZGUgdGhlIHRpbWUgc3BlbnQgd29ya2luZyBvbiBmYWlsZWQgY2hpbGRyZW4gYmVmb3JlIGNvbnRpbnVpbmcuXG5cbiAgICAgICAgdmFyIGFjdHVhbER1cmF0aW9uID0gY29tcGxldGVkV29yay5hY3R1YWxEdXJhdGlvbjtcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcGxldGVkV29yay5jaGlsZDtcblxuICAgICAgICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgICBhY3R1YWxEdXJhdGlvbiArPSBjaGlsZC5hY3R1YWxEdXJhdGlvbjtcbiAgICAgICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgICAgIH1cblxuICAgICAgICBjb21wbGV0ZWRXb3JrLmFjdHVhbER1cmF0aW9uID0gYWN0dWFsRHVyYXRpb247XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXR1cm5GaWJlciAhPT0gbnVsbCkge1xuICAgICAgICAvLyBNYXJrIHRoZSBwYXJlbnQgZmliZXIgYXMgaW5jb21wbGV0ZSBhbmQgY2xlYXIgaXRzIHN1YnRyZWUgZmxhZ3MuXG4gICAgICAgIHJldHVybkZpYmVyLmZsYWdzIHw9IEluY29tcGxldGU7XG4gICAgICAgIHJldHVybkZpYmVyLnN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG4gICAgICAgIHJldHVybkZpYmVyLmRlbGV0aW9ucyA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXZSd2ZSB1bndvdW5kIGFsbCB0aGUgd2F5IHRvIHRoZSByb290LlxuICAgICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdERpZE5vdENvbXBsZXRlO1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcyA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc2libGluZ0ZpYmVyID0gY29tcGxldGVkV29yay5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmdGaWJlciAhPT0gbnVsbCkge1xuICAgICAgLy8gSWYgdGhlcmUgaXMgbW9yZSB3b3JrIHRvIGRvIGluIHRoaXMgcmV0dXJuRmliZXIsIGRvIHRoYXQgbmV4dC5cbiAgICAgIHdvcmtJblByb2dyZXNzID0gc2libGluZ0ZpYmVyO1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gT3RoZXJ3aXNlLCByZXR1cm4gdG8gdGhlIHBhcmVudFxuXG5cbiAgICBjb21wbGV0ZWRXb3JrID0gcmV0dXJuRmliZXI7IC8vIFVwZGF0ZSB0aGUgbmV4dCB0aGluZyB3ZSdyZSB3b3JraW5nIG9uIGluIGNhc2Ugc29tZXRoaW5nIHRocm93cy5cblxuICAgIHdvcmtJblByb2dyZXNzID0gY29tcGxldGVkV29yaztcbiAgfSB3aGlsZSAoY29tcGxldGVkV29yayAhPT0gbnVsbCk7IC8vIFdlJ3ZlIHJlYWNoZWQgdGhlIHJvb3QuXG5cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdEluUHJvZ3Jlc3MpIHtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdENvbXBsZXRlZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRSb290KHJvb3QsIHJlY292ZXJhYmxlRXJyb3JzLCB0cmFuc2l0aW9ucykge1xuICAvLyBUT0RPOiBUaGlzIG5vIGxvbmdlciBtYWtlcyBhbnkgc2Vuc2UuIFdlIGFscmVhZHkgd3JhcCB0aGUgbXV0YXRpb24gYW5kXG4gIC8vIGxheW91dCBwaGFzZXMuIFNob3VsZCBiZSBhYmxlIHRvIHJlbW92ZS5cbiAgdmFyIHByZXZpb3VzVXBkYXRlTGFuZVByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcblxuICB0cnkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IG51bGw7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgY29tbWl0Um9vdEltcGwocm9vdCwgcmVjb3ZlcmFibGVFcnJvcnMsIHRyYW5zaXRpb25zLCBwcmV2aW91c1VwZGF0ZUxhbmVQcmlvcml0eSk7XG4gIH0gZmluYWxseSB7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzVXBkYXRlTGFuZVByaW9yaXR5KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBjb21taXRSb290SW1wbChyb290LCByZWNvdmVyYWJsZUVycm9ycywgdHJhbnNpdGlvbnMsIHJlbmRlclByaW9yaXR5TGV2ZWwpIHtcbiAgZG8ge1xuICAgIC8vIGBmbHVzaFBhc3NpdmVFZmZlY3RzYCB3aWxsIGNhbGwgYGZsdXNoU3luY1VwZGF0ZVF1ZXVlYCBhdCB0aGUgZW5kLCB3aGljaFxuICAgIC8vIG1lYW5zIGBmbHVzaFBhc3NpdmVFZmZlY3RzYCB3aWxsIHNvbWV0aW1lcyByZXN1bHQgaW4gYWRkaXRpb25hbFxuICAgIC8vIHBhc3NpdmUgZWZmZWN0cy4gU28gd2UgbmVlZCB0byBrZWVwIGZsdXNoaW5nIGluIGEgbG9vcCB1bnRpbCB0aGVyZSBhcmVcbiAgICAvLyBubyBtb3JlIHBlbmRpbmcgZWZmZWN0cy5cbiAgICAvLyBUT0RPOiBNaWdodCBiZSBiZXR0ZXIgaWYgYGZsdXNoUGFzc2l2ZUVmZmVjdHNgIGRpZCBub3QgYXV0b21hdGljYWxseVxuICAgIC8vIGZsdXNoIHN5bmNocm9ub3VzIHdvcmsgYXQgdGhlIGVuZCwgdG8gYXZvaWQgZmFjdG9yaW5nIGhhemFyZHMgbGlrZSB0aGlzLlxuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgfSB3aGlsZSAocm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgIT09IG51bGwpO1xuXG4gIGZsdXNoUmVuZGVyUGhhc2VTdHJpY3RNb2RlV2FybmluZ3NJbkRFVigpO1xuXG4gIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIChSZW5kZXJDb250ZXh0IHwgQ29tbWl0Q29udGV4dCkpICE9PSBOb0NvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Nob3VsZCBub3QgYWxyZWFkeSBiZSB3b3JraW5nLicpO1xuICB9XG5cbiAgdmFyIGZpbmlzaGVkV29yayA9IHJvb3QuZmluaXNoZWRXb3JrO1xuICB2YXIgbGFuZXMgPSByb290LmZpbmlzaGVkTGFuZXM7XG5cbiAge1xuICAgIG1hcmtDb21taXRTdGFydGVkKGxhbmVzKTtcbiAgfVxuXG4gIGlmIChmaW5pc2hlZFdvcmsgPT09IG51bGwpIHtcblxuICAgIHtcbiAgICAgIG1hcmtDb21taXRTdG9wcGVkKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZWxzZSB7XG4gICAge1xuICAgICAgaWYgKGxhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgICAgIGVycm9yKCdyb290LmZpbmlzaGVkTGFuZXMgc2hvdWxkIG5vdCBiZSBlbXB0eSBkdXJpbmcgYSBjb21taXQuIFRoaXMgaXMgYSAnICsgJ2J1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByb290LmZpbmlzaGVkV29yayA9IG51bGw7XG4gIHJvb3QuZmluaXNoZWRMYW5lcyA9IE5vTGFuZXM7XG5cbiAgaWYgKGZpbmlzaGVkV29yayA9PT0gcm9vdC5jdXJyZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29tbWl0IHRoZSBzYW1lIHRyZWUgYXMgYmVmb3JlLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgJyArICdhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH0gLy8gY29tbWl0Um9vdCBuZXZlciByZXR1cm5zIGEgY29udGludWF0aW9uOyBpdCBhbHdheXMgZmluaXNoZXMgc3luY2hyb25vdXNseS5cbiAgLy8gU28gd2UgY2FuIGNsZWFyIHRoZXNlIG5vdyB0byBhbGxvdyBhIG5ldyBjYWxsYmFjayB0byBiZSBzY2hlZHVsZWQuXG5cblxuICByb290LmNhbGxiYWNrTm9kZSA9IG51bGw7XG4gIHJvb3QuY2FsbGJhY2tQcmlvcml0eSA9IE5vTGFuZTsgLy8gVXBkYXRlIHRoZSBmaXJzdCBhbmQgbGFzdCBwZW5kaW5nIHRpbWVzIG9uIHRoaXMgcm9vdC4gVGhlIG5ldyBmaXJzdFxuICAvLyBwZW5kaW5nIHRpbWUgaXMgd2hhdGV2ZXIgaXMgbGVmdCBvbiB0aGUgcm9vdCBmaWJlci5cblxuICB2YXIgcmVtYWluaW5nTGFuZXMgPSBtZXJnZUxhbmVzKGZpbmlzaGVkV29yay5sYW5lcywgZmluaXNoZWRXb3JrLmNoaWxkTGFuZXMpO1xuICBtYXJrUm9vdEZpbmlzaGVkKHJvb3QsIHJlbWFpbmluZ0xhbmVzKTtcblxuICBpZiAocm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290KSB7XG4gICAgLy8gV2UgY2FuIHJlc2V0IHRoZXNlIG5vdyB0aGF0IHRoZXkgYXJlIGZpbmlzaGVkLlxuICAgIHdvcmtJblByb2dyZXNzUm9vdCA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3MgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lcztcbiAgfSAvLyBJZiB0aGVyZSBhcmUgcGVuZGluZyBwYXNzaXZlIGVmZmVjdHMsIHNjaGVkdWxlIGEgY2FsbGJhY2sgdG8gcHJvY2VzcyB0aGVtLlxuICAvLyBEbyB0aGlzIGFzIGVhcmx5IGFzIHBvc3NpYmxlLCBzbyBpdCBpcyBxdWV1ZWQgYmVmb3JlIGFueXRoaW5nIGVsc2UgdGhhdFxuICAvLyBtaWdodCBnZXQgc2NoZWR1bGVkIGluIHRoZSBjb21taXQgcGhhc2UuIChTZWUgIzE2NzE0LilcbiAgLy8gVE9ETzogRGVsZXRlIGFsbCBvdGhlciBwbGFjZXMgdGhhdCBzY2hlZHVsZSB0aGUgcGFzc2l2ZSBlZmZlY3QgY2FsbGJhY2tcbiAgLy8gVGhleSdyZSByZWR1bmRhbnQuXG5cblxuICBpZiAoKGZpbmlzaGVkV29yay5zdWJ0cmVlRmxhZ3MgJiBQYXNzaXZlTWFzaykgIT09IE5vRmxhZ3MgfHwgKGZpbmlzaGVkV29yay5mbGFncyAmIFBhc3NpdmVNYXNrKSAhPT0gTm9GbGFncykge1xuICAgIGlmICghcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIHJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzID0gdHJ1ZTtcbiAgICAgIC8vIHRvIHN0b3JlIGl0IGluIHBlbmRpbmdQYXNzaXZlVHJhbnNpdGlvbnMgdW50aWwgdGhleSBnZXQgcHJvY2Vzc2VkXG4gICAgICAvLyBXZSBuZWVkIHRvIHBhc3MgdGhpcyB0aHJvdWdoIGFzIGFuIGFyZ3VtZW50IHRvIGNvbW1pdFJvb3RcbiAgICAgIC8vIGJlY2F1c2Ugd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyBtaWdodCBoYXZlIGNoYW5nZWQgYmV0d2VlblxuICAgICAgLy8gdGhlIHByZXZpb3VzIHJlbmRlciBhbmQgY29tbWl0IGlmIHdlIHRocm90dGxlIHRoZSBjb21taXRcbiAgICAgIC8vIHdpdGggc2V0VGltZW91dFxuXG4gICAgICBwZW5kaW5nUGFzc2l2ZVRyYW5zaXRpb25zID0gdHJhbnNpdGlvbnM7XG4gICAgICBzY2hlZHVsZUNhbGxiYWNrJDEoTm9ybWFsUHJpb3JpdHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZmx1c2hQYXNzaXZlRWZmZWN0cygpOyAvLyBUaGlzIHJlbmRlciB0cmlnZ2VyZWQgcGFzc2l2ZSBlZmZlY3RzOiByZWxlYXNlIHRoZSByb290IGNhY2hlIHBvb2xcbiAgICAgICAgLy8gKmFmdGVyKiBwYXNzaXZlIGVmZmVjdHMgZmlyZSB0byBhdm9pZCBmcmVlaW5nIGEgY2FjaGUgcG9vbCB0aGF0IG1heVxuICAgICAgICAvLyBiZSByZWZlcmVuY2VkIGJ5IGEgbm9kZSBpbiB0aGUgdHJlZSAoSG9zdFJvb3QsIENhY2hlIGJvdW5kYXJ5IGV0YylcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSAvLyBDaGVjayBpZiB0aGVyZSBhcmUgYW55IGVmZmVjdHMgaW4gdGhlIHdob2xlIHRyZWUuXG4gIC8vIFRPRE86IFRoaXMgaXMgbGVmdCBvdmVyIGZyb20gdGhlIGVmZmVjdCBsaXN0IGltcGxlbWVudGF0aW9uLCB3aGVyZSB3ZSBoYWRcbiAgLy8gdG8gY2hlY2sgZm9yIHRoZSBleGlzdGVuY2Ugb2YgYGZpcnN0RWZmZWN0YCB0byBzYXRpc2Z5IEZsb3cuIEkgdGhpbmsgdGhlXG4gIC8vIG9ubHkgb3RoZXIgcmVhc29uIHRoaXMgb3B0aW1pemF0aW9uIGV4aXN0cyBpcyBiZWNhdXNlIGl0IGFmZmVjdHMgcHJvZmlsaW5nLlxuICAvLyBSZWNvbnNpZGVyIHdoZXRoZXIgdGhpcyBpcyBuZWNlc3NhcnkuXG5cblxuICB2YXIgc3VidHJlZUhhc0VmZmVjdHMgPSAoZmluaXNoZWRXb3JrLnN1YnRyZWVGbGFncyAmIChCZWZvcmVNdXRhdGlvbk1hc2sgfCBNdXRhdGlvbk1hc2sgfCBMYXlvdXRNYXNrIHwgUGFzc2l2ZU1hc2spKSAhPT0gTm9GbGFncztcbiAgdmFyIHJvb3RIYXNFZmZlY3QgPSAoZmluaXNoZWRXb3JrLmZsYWdzICYgKEJlZm9yZU11dGF0aW9uTWFzayB8IE11dGF0aW9uTWFzayB8IExheW91dE1hc2sgfCBQYXNzaXZlTWFzaykpICE9PSBOb0ZsYWdzO1xuXG4gIGlmIChzdWJ0cmVlSGFzRWZmZWN0cyB8fCByb290SGFzRWZmZWN0KSB7XG4gICAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uO1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IG51bGw7XG4gICAgdmFyIHByZXZpb3VzUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoRGlzY3JldGVFdmVudFByaW9yaXR5KTtcbiAgICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICAgIGV4ZWN1dGlvbkNvbnRleHQgfD0gQ29tbWl0Q29udGV4dDsgLy8gUmVzZXQgdGhpcyB0byBudWxsIGJlZm9yZSBjYWxsaW5nIGxpZmVjeWNsZXNcblxuICAgIFJlYWN0Q3VycmVudE93bmVyJDIuY3VycmVudCA9IG51bGw7IC8vIFRoZSBjb21taXQgcGhhc2UgaXMgYnJva2VuIGludG8gc2V2ZXJhbCBzdWItcGhhc2VzLiBXZSBkbyBhIHNlcGFyYXRlIHBhc3NcbiAgICAvLyBvZiB0aGUgZWZmZWN0IGxpc3QgZm9yIGVhY2ggcGhhc2U6IGFsbCBtdXRhdGlvbiBlZmZlY3RzIGNvbWUgYmVmb3JlIGFsbFxuICAgIC8vIGxheW91dCBlZmZlY3RzLCBhbmQgc28gb24uXG4gICAgLy8gVGhlIGZpcnN0IHBoYXNlIGEgXCJiZWZvcmUgbXV0YXRpb25cIiBwaGFzZS4gV2UgdXNlIHRoaXMgcGhhc2UgdG8gcmVhZCB0aGVcbiAgICAvLyBzdGF0ZSBvZiB0aGUgaG9zdCB0cmVlIHJpZ2h0IGJlZm9yZSB3ZSBtdXRhdGUgaXQuIFRoaXMgaXMgd2hlcmVcbiAgICAvLyBnZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSBpcyBjYWxsZWQuXG5cbiAgICB2YXIgc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyID0gY29tbWl0QmVmb3JlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG5cbiAgICB7XG4gICAgICAvLyBNYXJrIHRoZSBjdXJyZW50IGNvbW1pdCB0aW1lIHRvIGJlIHNoYXJlZCBieSBhbGwgUHJvZmlsZXJzIGluIHRoaXNcbiAgICAgIC8vIGJhdGNoLiBUaGlzIGVuYWJsZXMgdGhlbSB0byBiZSBncm91cGVkIGxhdGVyLlxuICAgICAgcmVjb3JkQ29tbWl0VGltZSgpO1xuICAgIH1cblxuXG4gICAgY29tbWl0TXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yaywgbGFuZXMpO1xuXG4gICAgcmVzZXRBZnRlckNvbW1pdChyb290LmNvbnRhaW5lckluZm8pOyAvLyBUaGUgd29yay1pbi1wcm9ncmVzcyB0cmVlIGlzIG5vdyB0aGUgY3VycmVudCB0cmVlLiBUaGlzIG11c3QgY29tZSBhZnRlclxuICAgIC8vIHRoZSBtdXRhdGlvbiBwaGFzZSwgc28gdGhhdCB0aGUgcHJldmlvdXMgdHJlZSBpcyBzdGlsbCBjdXJyZW50IGR1cmluZ1xuICAgIC8vIGNvbXBvbmVudFdpbGxVbm1vdW50LCBidXQgYmVmb3JlIHRoZSBsYXlvdXQgcGhhc2UsIHNvIHRoYXQgdGhlIGZpbmlzaGVkXG4gICAgLy8gd29yayBpcyBjdXJyZW50IGR1cmluZyBjb21wb25lbnREaWRNb3VudC9VcGRhdGUuXG5cbiAgICByb290LmN1cnJlbnQgPSBmaW5pc2hlZFdvcms7IC8vIFRoZSBuZXh0IHBoYXNlIGlzIHRoZSBsYXlvdXQgcGhhc2UsIHdoZXJlIHdlIGNhbGwgZWZmZWN0cyB0aGF0IHJlYWRcblxuICAgIHtcbiAgICAgIG1hcmtMYXlvdXRFZmZlY3RzU3RhcnRlZChsYW5lcyk7XG4gICAgfVxuXG4gICAgY29tbWl0TGF5b3V0RWZmZWN0cyhmaW5pc2hlZFdvcmssIHJvb3QsIGxhbmVzKTtcblxuICAgIHtcbiAgICAgIG1hcmtMYXlvdXRFZmZlY3RzU3RvcHBlZCgpO1xuICAgIH1cbiAgICAvLyBvcHBvcnR1bml0eSB0byBwYWludC5cblxuXG4gICAgcmVxdWVzdFBhaW50KCk7XG4gICAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0OyAvLyBSZXNldCB0aGUgcHJpb3JpdHkgdG8gdGhlIHByZXZpb3VzIG5vbi1zeW5jIHZhbHVlLlxuXG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IHByZXZUcmFuc2l0aW9uO1xuICB9IGVsc2Uge1xuICAgIC8vIE5vIGVmZmVjdHMuXG4gICAgcm9vdC5jdXJyZW50ID0gZmluaXNoZWRXb3JrOyAvLyBNZWFzdXJlIHRoZXNlIGFueXdheSBzbyB0aGUgZmxhbWVncmFwaCBleHBsaWNpdGx5IHNob3dzIHRoYXQgdGhlcmUgd2VyZVxuICAgIC8vIG5vIGVmZmVjdHMuXG4gICAgLy8gVE9ETzogTWF5YmUgdGhlcmUncyBhIGJldHRlciB3YXkgdG8gcmVwb3J0IHRoaXMuXG5cbiAgICB7XG4gICAgICByZWNvcmRDb21taXRUaW1lKCk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHJvb3REaWRIYXZlUGFzc2l2ZUVmZmVjdHMgPSByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cztcblxuICBpZiAocm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAvLyBUaGlzIGNvbW1pdCBoYXMgcGFzc2l2ZSBlZmZlY3RzLiBTdGFzaCBhIHJlZmVyZW5jZSB0byB0aGVtLiBCdXQgZG9uJ3RcbiAgICAvLyBzY2hlZHVsZSBhIGNhbGxiYWNrIHVudGlsIGFmdGVyIGZsdXNoaW5nIGxheW91dCB3b3JrLlxuICAgIHJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG4gICAgcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgPSByb290O1xuICAgIHBlbmRpbmdQYXNzaXZlRWZmZWN0c0xhbmVzID0gbGFuZXM7XG4gIH0gZWxzZSB7XG5cbiAgICB7XG4gICAgICBuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQgPSAwO1xuICAgICAgcm9vdFdpdGhQYXNzaXZlTmVzdGVkVXBkYXRlcyA9IG51bGw7XG4gICAgfVxuICB9IC8vIFJlYWQgdGhpcyBhZ2Fpbiwgc2luY2UgYW4gZWZmZWN0IG1pZ2h0IGhhdmUgdXBkYXRlZCBpdFxuXG5cbiAgcmVtYWluaW5nTGFuZXMgPSByb290LnBlbmRpbmdMYW5lczsgLy8gQ2hlY2sgaWYgdGhlcmUncyByZW1haW5pbmcgd29yayBvbiB0aGlzIHJvb3RcbiAgLy8gVE9ETzogVGhpcyBpcyBwYXJ0IG9mIHRoZSBgY29tcG9uZW50RGlkQ2F0Y2hgIGltcGxlbWVudGF0aW9uLiBJdHMgcHVycG9zZVxuICAvLyBpcyB0byBkZXRlY3Qgd2hldGhlciBzb21ldGhpbmcgbWlnaHQgaGF2ZSBjYWxsZWQgc2V0U3RhdGUgaW5zaWRlXG4gIC8vIGBjb21wb25lbnREaWRDYXRjaGAuIFRoZSBtZWNoYW5pc20gaXMga25vd24gdG8gYmUgZmxhd2VkIGJlY2F1c2UgYHNldFN0YXRlYFxuICAvLyBpbnNpZGUgYGNvbXBvbmVudERpZENhdGNoYCBpcyBpdHNlbGYgZmxhd2VkIFx1MjAxNCB0aGF0J3Mgd2h5IHdlIHJlY29tbWVuZFxuICAvLyBgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yYCBpbnN0ZWFkLiBIb3dldmVyLCBpdCBjb3VsZCBiZSBpbXByb3ZlZCBieVxuICAvLyBjaGVja2luZyBpZiByZW1haW5pbmdMYW5lcyBpbmNsdWRlcyBTeW5jIHdvcmssIGluc3RlYWQgb2Ygd2hldGhlciB0aGVyZSdzXG4gIC8vIGFueSB3b3JrIHJlbWFpbmluZyBhdCBhbGwgKHdoaWNoIHdvdWxkIGFsc28gaW5jbHVkZSBzdHVmZiBsaWtlIFN1c3BlbnNlXG4gIC8vIHJldHJpZXMgb3IgdHJhbnNpdGlvbnMpLiBJdCdzIGJlZW4gbGlrZSB0aGlzIGZvciBhIHdoaWxlLCB0aG91Z2gsIHNvIGZpeGluZ1xuICAvLyBpdCBwcm9iYWJseSBpc24ndCB0aGF0IHVyZ2VudC5cblxuICBpZiAocmVtYWluaW5nTGFuZXMgPT09IE5vTGFuZXMpIHtcbiAgICAvLyBJZiB0aGVyZSdzIG5vIHJlbWFpbmluZyB3b3JrLCB3ZSBjYW4gY2xlYXIgdGhlIHNldCBvZiBhbHJlYWR5IGZhaWxlZFxuICAgIC8vIGVycm9yIGJvdW5kYXJpZXMuXG4gICAgbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQgPSBudWxsO1xuICB9XG5cbiAge1xuICAgIGlmICghcm9vdERpZEhhdmVQYXNzaXZlRWZmZWN0cykge1xuICAgICAgY29tbWl0RG91YmxlSW52b2tlRWZmZWN0c0luREVWKHJvb3QuY3VycmVudCwgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIG9uQ29tbWl0Um9vdChmaW5pc2hlZFdvcmsuc3RhdGVOb2RlLCByZW5kZXJQcmlvcml0eUxldmVsKTtcblxuICB7XG4gICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICByb290Lm1lbW9pemVkVXBkYXRlcnMuY2xlYXIoKTtcbiAgICB9XG4gIH1cblxuICB7XG4gICAgb25Db21taXRSb290JDEoKTtcbiAgfSAvLyBBbHdheXMgY2FsbCB0aGlzIGJlZm9yZSBleGl0aW5nIGBjb21taXRSb290YCwgdG8gZW5zdXJlIHRoYXQgYW55XG4gIC8vIGFkZGl0aW9uYWwgd29yayBvbiB0aGlzIHJvb3QgaXMgc2NoZWR1bGVkLlxuXG5cbiAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcblxuICBpZiAocmVjb3ZlcmFibGVFcnJvcnMgIT09IG51bGwpIHtcbiAgICAvLyBUaGVyZSB3ZXJlIGVycm9ycyBkdXJpbmcgdGhpcyByZW5kZXIsIGJ1dCByZWNvdmVyZWQgZnJvbSB0aGVtIHdpdGhvdXRcbiAgICAvLyBuZWVkaW5nIHRvIHN1cmZhY2UgaXQgdG8gdGhlIFVJLiBXZSBsb2cgdGhlbSBoZXJlLlxuICAgIHZhciBvblJlY292ZXJhYmxlRXJyb3IgPSByb290Lm9uUmVjb3ZlcmFibGVFcnJvcjtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVjb3ZlcmFibGVFcnJvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByZWNvdmVyYWJsZUVycm9yID0gcmVjb3ZlcmFibGVFcnJvcnNbaV07XG4gICAgICBvblJlY292ZXJhYmxlRXJyb3IocmVjb3ZlcmFibGVFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKGhhc1VuY2F1Z2h0RXJyb3IpIHtcbiAgICBoYXNVbmNhdWdodEVycm9yID0gZmFsc2U7XG4gICAgdmFyIGVycm9yJDEgPSBmaXJzdFVuY2F1Z2h0RXJyb3I7XG4gICAgZmlyc3RVbmNhdWdodEVycm9yID0gbnVsbDtcbiAgICB0aHJvdyBlcnJvciQxO1xuICB9IC8vIElmIHRoZSBwYXNzaXZlIGVmZmVjdHMgYXJlIHRoZSByZXN1bHQgb2YgYSBkaXNjcmV0ZSByZW5kZXIsIGZsdXNoIHRoZW1cbiAgLy8gc3luY2hyb25vdXNseSBhdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHRhc2sgc28gdGhhdCB0aGUgcmVzdWx0IGlzXG4gIC8vIGltbWVkaWF0ZWx5IG9ic2VydmFibGUuIE90aGVyd2lzZSwgd2UgYXNzdW1lIHRoYXQgdGhleSBhcmUgbm90XG4gIC8vIG9yZGVyLWRlcGVuZGVudCBhbmQgZG8gbm90IG5lZWQgdG8gYmUgb2JzZXJ2ZWQgYnkgZXh0ZXJuYWwgc3lzdGVtcywgc28gd2VcbiAgLy8gY2FuIHdhaXQgdW50aWwgYWZ0ZXIgcGFpbnQuXG4gIC8vIFRPRE86IFdlIGNhbiBvcHRpbWl6ZSB0aGlzIGJ5IG5vdCBzY2hlZHVsaW5nIHRoZSBjYWxsYmFjayBlYXJsaWVyLiBTaW5jZSB3ZVxuICAvLyBjdXJyZW50bHkgc2NoZWR1bGUgdGhlIGNhbGxiYWNrIGluIG11bHRpcGxlIHBsYWNlcywgd2lsbCB3YWl0IHVudGlsIHRob3NlXG4gIC8vIGFyZSBjb25zb2xpZGF0ZWQuXG5cblxuICBpZiAoaW5jbHVkZXNTb21lTGFuZShwZW5kaW5nUGFzc2l2ZUVmZmVjdHNMYW5lcywgU3luY0xhbmUpICYmIHJvb3QudGFnICE9PSBMZWdhY3lSb290KSB7XG4gICAgZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuICB9IC8vIFJlYWQgdGhpcyBhZ2Fpbiwgc2luY2UgYSBwYXNzaXZlIGVmZmVjdCBtaWdodCBoYXZlIHVwZGF0ZWQgaXRcblxuXG4gIHJlbWFpbmluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXM7XG5cbiAgaWYgKGluY2x1ZGVzU29tZUxhbmUocmVtYWluaW5nTGFuZXMsIFN5bmNMYW5lKSkge1xuICAgIHtcbiAgICAgIG1hcmtOZXN0ZWRVcGRhdGVTY2hlZHVsZWQoKTtcbiAgICB9IC8vIENvdW50IHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIHJvb3Qgc3luY2hyb25vdXNseSByZS1yZW5kZXJzIHdpdGhvdXRcbiAgICAvLyBmaW5pc2hpbmcuIElmIHRoZXJlIGFyZSB0b28gbWFueSwgaXQgaW5kaWNhdGVzIGFuIGluZmluaXRlIHVwZGF0ZSBsb29wLlxuXG5cbiAgICBpZiAocm9vdCA9PT0gcm9vdFdpdGhOZXN0ZWRVcGRhdGVzKSB7XG4gICAgICBuZXN0ZWRVcGRhdGVDb3VudCsrO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXN0ZWRVcGRhdGVDb3VudCA9IDA7XG4gICAgICByb290V2l0aE5lc3RlZFVwZGF0ZXMgPSByb290O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBuZXN0ZWRVcGRhdGVDb3VudCA9IDA7XG4gIH0gLy8gSWYgbGF5b3V0IHdvcmsgd2FzIHNjaGVkdWxlZCwgZmx1c2ggaXQgbm93LlxuXG5cbiAgZmx1c2hTeW5jQ2FsbGJhY2tzKCk7XG5cbiAge1xuICAgIG1hcmtDb21taXRTdG9wcGVkKCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZmx1c2hQYXNzaXZlRWZmZWN0cygpIHtcbiAgLy8gUmV0dXJucyB3aGV0aGVyIHBhc3NpdmUgZWZmZWN0cyB3ZXJlIGZsdXNoZWQuXG4gIC8vIFRPRE86IENvbWJpbmUgdGhpcyBjaGVjayB3aXRoIHRoZSBvbmUgaW4gZmx1c2hQYXNzaXZlRUZmZWN0c0ltcGwuIFdlIHNob3VsZFxuICAvLyBwcm9iYWJseSBqdXN0IGNvbWJpbmUgdGhlIHR3byBmdW5jdGlvbnMuIEkgYmVsaWV2ZSB0aGV5IHdlcmUgb25seSBzZXBhcmF0ZVxuICAvLyBpbiB0aGUgZmlyc3QgcGxhY2UgYmVjYXVzZSB3ZSB1c2VkIHRvIHdyYXAgaXQgd2l0aFxuICAvLyBgU2NoZWR1bGVyLnJ1bldpdGhQcmlvcml0eWAsIHdoaWNoIGFjY2VwdHMgYSBmdW5jdGlvbi4gQnV0IG5vdyB3ZSB0cmFjayB0aGVcbiAgLy8gcHJpb3JpdHkgd2l0aGluIFJlYWN0IGl0c2VsZiwgc28gd2UgY2FuIG11dGF0ZSB0aGUgdmFyaWFibGUgZGlyZWN0bHkuXG4gIGlmIChyb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyAhPT0gbnVsbCkge1xuICAgIHZhciByZW5kZXJQcmlvcml0eSA9IGxhbmVzVG9FdmVudFByaW9yaXR5KHBlbmRpbmdQYXNzaXZlRWZmZWN0c0xhbmVzKTtcbiAgICB2YXIgcHJpb3JpdHkgPSBsb3dlckV2ZW50UHJpb3JpdHkoRGVmYXVsdEV2ZW50UHJpb3JpdHksIHJlbmRlclByaW9yaXR5KTtcbiAgICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb247XG4gICAgdmFyIHByZXZpb3VzUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcblxuICAgIHRyeSB7XG4gICAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBudWxsO1xuICAgICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByaW9yaXR5KTtcbiAgICAgIHJldHVybiBmbHVzaFBhc3NpdmVFZmZlY3RzSW1wbCgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSk7XG4gICAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjsgLy8gT25jZSBwYXNzaXZlIGVmZmVjdHMgaGF2ZSBydW4gZm9yIHRoZSB0cmVlIC0gZ2l2aW5nIGNvbXBvbmVudHMgYVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGVucXVldWVQZW5kaW5nUGFzc2l2ZVByb2ZpbGVyRWZmZWN0KGZpYmVyKSB7XG4gIHtcbiAgICBwZW5kaW5nUGFzc2l2ZVByb2ZpbGVyRWZmZWN0cy5wdXNoKGZpYmVyKTtcblxuICAgIGlmICghcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIHJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzID0gdHJ1ZTtcbiAgICAgIHNjaGVkdWxlQ2FsbGJhY2skMShOb3JtYWxQcmlvcml0eSwgZnVuY3Rpb24gKCkge1xuICAgICAgICBmbHVzaFBhc3NpdmVFZmZlY3RzKCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZsdXNoUGFzc2l2ZUVmZmVjdHNJbXBsKCkge1xuICBpZiAocm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gLy8gQ2FjaGUgYW5kIGNsZWFyIHRoZSB0cmFuc2l0aW9ucyBmbGFnXG5cblxuICB2YXIgdHJhbnNpdGlvbnMgPSBwZW5kaW5nUGFzc2l2ZVRyYW5zaXRpb25zO1xuICBwZW5kaW5nUGFzc2l2ZVRyYW5zaXRpb25zID0gbnVsbDtcbiAgdmFyIHJvb3QgPSByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cztcbiAgdmFyIGxhbmVzID0gcGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXM7XG4gIHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzID0gbnVsbDsgLy8gVE9ETzogVGhpcyBpcyBzb21ldGltZXMgb3V0IG9mIHN5bmMgd2l0aCByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cy5cbiAgLy8gRmlndXJlIG91dCB3aHkgYW5kIGZpeCBpdC4gSXQncyBub3QgY2F1c2luZyBhbnkga25vd24gaXNzdWVzIChwcm9iYWJseVxuICAvLyBiZWNhdXNlIGl0J3Mgb25seSB1c2VkIGZvciBwcm9maWxpbmcpLCBidXQgaXQncyBhIHJlZmFjdG9yIGhhemFyZC5cblxuICBwZW5kaW5nUGFzc2l2ZUVmZmVjdHNMYW5lcyA9IE5vTGFuZXM7XG5cbiAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgIT09IE5vQ29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZsdXNoIHBhc3NpdmUgZWZmZWN0cyB3aGlsZSBhbHJlYWR5IHJlbmRlcmluZy4nKTtcbiAgfVxuXG4gIHtcbiAgICBpc0ZsdXNoaW5nUGFzc2l2ZUVmZmVjdHMgPSB0cnVlO1xuICAgIGRpZFNjaGVkdWxlVXBkYXRlRHVyaW5nUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrUGFzc2l2ZUVmZmVjdHNTdGFydGVkKGxhbmVzKTtcbiAgfVxuXG4gIHZhciBwcmV2RXhlY3V0aW9uQ29udGV4dCA9IGV4ZWN1dGlvbkNvbnRleHQ7XG4gIGV4ZWN1dGlvbkNvbnRleHQgfD0gQ29tbWl0Q29udGV4dDtcbiAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzKHJvb3QuY3VycmVudCk7XG4gIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHMocm9vdCwgcm9vdC5jdXJyZW50LCBsYW5lcywgdHJhbnNpdGlvbnMpOyAvLyBUT0RPOiBNb3ZlIHRvIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHNcblxuICB7XG4gICAgdmFyIHByb2ZpbGVyRWZmZWN0cyA9IHBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3RzO1xuICAgIHBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3RzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb2ZpbGVyRWZmZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIF9maWJlciA9IHByb2ZpbGVyRWZmZWN0c1tpXTtcbiAgICAgIGNvbW1pdFBhc3NpdmVFZmZlY3REdXJhdGlvbnMocm9vdCwgX2ZpYmVyKTtcbiAgICB9XG4gIH1cblxuICB7XG4gICAgbWFya1Bhc3NpdmVFZmZlY3RzU3RvcHBlZCgpO1xuICB9XG5cbiAge1xuICAgIGNvbW1pdERvdWJsZUludm9rZUVmZmVjdHNJbkRFVihyb290LmN1cnJlbnQsIHRydWUpO1xuICB9XG5cbiAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0O1xuICBmbHVzaFN5bmNDYWxsYmFja3MoKTtcblxuICB7XG4gICAgLy8gSWYgYWRkaXRpb25hbCBwYXNzaXZlIGVmZmVjdHMgd2VyZSBzY2hlZHVsZWQsIGluY3JlbWVudCBhIGNvdW50ZXIuIElmIHRoaXNcbiAgICAvLyBleGNlZWRzIHRoZSBsaW1pdCwgd2UnbGwgZmlyZSBhIHdhcm5pbmcuXG4gICAgaWYgKGRpZFNjaGVkdWxlVXBkYXRlRHVyaW5nUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIGlmIChyb290ID09PSByb290V2l0aFBhc3NpdmVOZXN0ZWRVcGRhdGVzKSB7XG4gICAgICAgIG5lc3RlZFBhc3NpdmVVcGRhdGVDb3VudCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID0gMDtcbiAgICAgICAgcm9vdFdpdGhQYXNzaXZlTmVzdGVkVXBkYXRlcyA9IHJvb3Q7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG5lc3RlZFBhc3NpdmVVcGRhdGVDb3VudCA9IDA7XG4gICAgfVxuXG4gICAgaXNGbHVzaGluZ1Bhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG4gICAgZGlkU2NoZWR1bGVVcGRhdGVEdXJpbmdQYXNzaXZlRWZmZWN0cyA9IGZhbHNlO1xuICB9IC8vIFRPRE86IE1vdmUgdG8gY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c1xuXG5cbiAgb25Qb3N0Q29tbWl0Um9vdChyb290KTtcblxuICB7XG4gICAgdmFyIHN0YXRlTm9kZSA9IHJvb3QuY3VycmVudC5zdGF0ZU5vZGU7XG4gICAgc3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uID0gMDtcbiAgICBzdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uID0gMDtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc0FscmVhZHlGYWlsZWRMZWdhY3lFcnJvckJvdW5kYXJ5KGluc3RhbmNlKSB7XG4gIHJldHVybiBsZWdhY3lFcnJvckJvdW5kYXJpZXNUaGF0QWxyZWFkeUZhaWxlZCAhPT0gbnVsbCAmJiBsZWdhY3lFcnJvckJvdW5kYXJpZXNUaGF0QWxyZWFkeUZhaWxlZC5oYXMoaW5zdGFuY2UpO1xufVxuZnVuY3Rpb24gbWFya0xlZ2FjeUVycm9yQm91bmRhcnlBc0ZhaWxlZChpbnN0YW5jZSkge1xuICBpZiAobGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQgPT09IG51bGwpIHtcbiAgICBsZWdhY3lFcnJvckJvdW5kYXJpZXNUaGF0QWxyZWFkeUZhaWxlZCA9IG5ldyBTZXQoW2luc3RhbmNlXSk7XG4gIH0gZWxzZSB7XG4gICAgbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQuYWRkKGluc3RhbmNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcmVwYXJlVG9UaHJvd1VuY2F1Z2h0RXJyb3IoZXJyb3IpIHtcbiAgaWYgKCFoYXNVbmNhdWdodEVycm9yKSB7XG4gICAgaGFzVW5jYXVnaHRFcnJvciA9IHRydWU7XG4gICAgZmlyc3RVbmNhdWdodEVycm9yID0gZXJyb3I7XG4gIH1cbn1cblxudmFyIG9uVW5jYXVnaHRFcnJvciA9IHByZXBhcmVUb1Rocm93VW5jYXVnaHRFcnJvcjtcblxuZnVuY3Rpb24gY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3JPblJvb3Qocm9vdEZpYmVyLCBzb3VyY2VGaWJlciwgZXJyb3IpIHtcbiAgdmFyIGVycm9ySW5mbyA9IGNyZWF0ZUNhcHR1cmVkVmFsdWUoZXJyb3IsIHNvdXJjZUZpYmVyKTtcbiAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVJvb3RFcnJvclVwZGF0ZShyb290RmliZXIsIGVycm9ySW5mbywgU3luY0xhbmUpO1xuICBlbnF1ZXVlVXBkYXRlKHJvb3RGaWJlciwgdXBkYXRlKTtcbiAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgdmFyIHJvb3QgPSBtYXJrVXBkYXRlTGFuZUZyb21GaWJlclRvUm9vdChyb290RmliZXIsIFN5bmNMYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIG1hcmtSb290VXBkYXRlZChyb290LCBTeW5jTGFuZSwgZXZlbnRUaW1lKTtcbiAgICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgZXZlbnRUaW1lKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihzb3VyY2VGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IkMSkge1xuICB7XG4gICAgcmVwb3J0VW5jYXVnaHRFcnJvckluREVWKGVycm9yJDEpO1xuICAgIHNldElzUnVubmluZ0luc2VydGlvbkVmZmVjdChmYWxzZSk7XG4gIH1cblxuICBpZiAoc291cmNlRmliZXIudGFnID09PSBIb3N0Um9vdCkge1xuICAgIC8vIEVycm9yIHdhcyB0aHJvd24gYXQgdGhlIHJvb3QuIFRoZXJlIGlzIG5vIHBhcmVudCwgc28gdGhlIHJvb3RcbiAgICAvLyBpdHNlbGYgc2hvdWxkIGNhcHR1cmUgaXQuXG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3JPblJvb3Qoc291cmNlRmliZXIsIHNvdXJjZUZpYmVyLCBlcnJvciQxKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZmliZXIgPSBudWxsO1xuXG4gIHtcbiAgICBmaWJlciA9IG5lYXJlc3RNb3VudGVkQW5jZXN0b3I7XG4gIH1cblxuICB3aGlsZSAoZmliZXIgIT09IG51bGwpIHtcbiAgICBpZiAoZmliZXIudGFnID09PSBIb3N0Um9vdCkge1xuICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3JPblJvb3QoZmliZXIsIHNvdXJjZUZpYmVyLCBlcnJvciQxKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKGZpYmVyLnRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgIHZhciBjdG9yID0gZmliZXIudHlwZTtcbiAgICAgIHZhciBpbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgaWYgKHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvciA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkQ2F0Y2ggPT09ICdmdW5jdGlvbicgJiYgIWlzQWxyZWFkeUZhaWxlZExlZ2FjeUVycm9yQm91bmRhcnkoaW5zdGFuY2UpKSB7XG4gICAgICAgIHZhciBlcnJvckluZm8gPSBjcmVhdGVDYXB0dXJlZFZhbHVlKGVycm9yJDEsIHNvdXJjZUZpYmVyKTtcbiAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUoZmliZXIsIGVycm9ySW5mbywgU3luY0xhbmUpO1xuICAgICAgICBlbnF1ZXVlVXBkYXRlKGZpYmVyLCB1cGRhdGUpO1xuICAgICAgICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICAgICAgICB2YXIgcm9vdCA9IG1hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICBtYXJrUm9vdFVwZGF0ZWQocm9vdCwgU3luY0xhbmUsIGV2ZW50VGltZSk7XG4gICAgICAgICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIGV2ZW50VGltZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmliZXIgPSBmaWJlci5yZXR1cm47XG4gIH1cblxuICB7XG4gICAgLy8gVE9ETzogVW50aWwgd2UgcmUtbGFuZCBza2lwVW5tb3VudGVkQm91bmRhcmllcyAoc2VlICMyMDE0NyksIHRoaXMgd2FybmluZ1xuICAgIC8vIHdpbGwgZmlyZSBmb3IgZXJyb3JzIHRoYXQgYXJlIHRocm93biBieSBkZXN0cm95IGZ1bmN0aW9ucyBpbnNpZGUgZGVsZXRlZFxuICAgIC8vIHRyZWVzLiBXaGF0IGl0IHNob3VsZCBpbnN0ZWFkIGRvIGlzIHByb3BhZ2F0ZSB0aGUgZXJyb3IgdG8gdGhlIHBhcmVudCBvZlxuICAgIC8vIHRoZSBkZWxldGVkIHRyZWUuIEluIHRoZSBtZWFudGltZSwgZG8gbm90IGFkZCB0aGlzIHdhcm5pbmcgdG8gdGhlXG4gICAgLy8gYWxsb3dsaXN0OyB0aGlzIGlzIG9ubHkgZm9yIG91ciBpbnRlcm5hbCB1c2UuXG4gICAgZXJyb3IoJ0ludGVybmFsIFJlYWN0IGVycm9yOiBBdHRlbXB0ZWQgdG8gY2FwdHVyZSBhIGNvbW1pdCBwaGFzZSBlcnJvciAnICsgJ2luc2lkZSBhIGRldGFjaGVkIHRyZWUuIFRoaXMgaW5kaWNhdGVzIGEgYnVnIGluIFJlYWN0LiBMaWtlbHkgJyArICdjYXVzZXMgaW5jbHVkZSBkZWxldGluZyB0aGUgc2FtZSBmaWJlciBtb3JlIHRoYW4gb25jZSwgY29tbWl0dGluZyBhbiAnICsgJ2FscmVhZHktZmluaXNoZWQgdHJlZSwgb3IgYW4gaW5jb25zaXN0ZW50IHJldHVybiBwb2ludGVyLlxcblxcbicgKyAnRXJyb3IgbWVzc2FnZTpcXG5cXG4lcycsIGVycm9yJDEpO1xuICB9XG59XG5mdW5jdGlvbiBwaW5nU3VzcGVuZGVkUm9vdChyb290LCB3YWtlYWJsZSwgcGluZ2VkTGFuZXMpIHtcbiAgdmFyIHBpbmdDYWNoZSA9IHJvb3QucGluZ0NhY2hlO1xuXG4gIGlmIChwaW5nQ2FjaGUgIT09IG51bGwpIHtcbiAgICAvLyBUaGUgd2FrZWFibGUgcmVzb2x2ZWQsIHNvIHdlIG5vIGxvbmdlciBuZWVkIHRvIG1lbW9pemUsIGJlY2F1c2UgaXQgd2lsbFxuICAgIC8vIG5ldmVyIGJlIHRocm93biBhZ2Fpbi5cbiAgICBwaW5nQ2FjaGUuZGVsZXRlKHdha2VhYmxlKTtcbiAgfVxuXG4gIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gIG1hcmtSb290UGluZ2VkKHJvb3QsIHBpbmdlZExhbmVzKTtcbiAgd2FybklmU3VzcGVuc2VSZXNvbHV0aW9uTm90V3JhcHBlZFdpdGhBY3RERVYocm9vdCk7XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdCA9PT0gcm9vdCAmJiBpc1N1YnNldE9mTGFuZXMod29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMsIHBpbmdlZExhbmVzKSkge1xuICAgIC8vIFJlY2VpdmVkIGEgcGluZyBhdCB0aGUgc2FtZSBwcmlvcml0eSBsZXZlbCBhdCB3aGljaCB3ZSdyZSBjdXJyZW50bHlcbiAgICAvLyByZW5kZXJpbmcuIFdlIG1pZ2h0IHdhbnQgdG8gcmVzdGFydCB0aGlzIHJlbmRlci4gVGhpcyBzaG91bGQgbWlycm9yXG4gICAgLy8gdGhlIGxvZ2ljIG9mIHdoZXRoZXIgb3Igbm90IGEgcm9vdCBzdXNwZW5kcyBvbmNlIGl0IGNvbXBsZXRlcy5cbiAgICAvLyBUT0RPOiBJZiB3ZSdyZSByZW5kZXJpbmcgc3luYyBlaXRoZXIgZHVlIHRvIFN5bmMsIEJhdGNoZWQgb3IgZXhwaXJlZCxcbiAgICAvLyB3ZSBzaG91bGQgcHJvYmFibHkgbmV2ZXIgcmVzdGFydC5cbiAgICAvLyBJZiB3ZSdyZSBzdXNwZW5kZWQgd2l0aCBkZWxheSwgb3IgaWYgaXQncyBhIHJldHJ5LCB3ZSdsbCBhbHdheXMgc3VzcGVuZFxuICAgIC8vIHNvIHdlIGNhbiBhbHdheXMgcmVzdGFydC5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZFdpdGhEZWxheSB8fCB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290U3VzcGVuZGVkICYmIGluY2x1ZGVzT25seVJldHJpZXMod29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpICYmIG5vdygpIC0gZ2xvYmFsTW9zdFJlY2VudEZhbGxiYWNrVGltZSA8IEZBTExCQUNLX1RIUk9UVExFX01TKSB7XG4gICAgICAvLyBSZXN0YXJ0IGZyb20gdGhlIHJvb3QuXG4gICAgICBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBOb0xhbmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRXZlbiB0aG91Z2ggd2UgY2FuJ3QgcmVzdGFydCByaWdodCBub3csIHdlIG1pZ2h0IGdldCBhblxuICAgICAgLy8gb3Bwb3J0dW5pdHkgbGF0ZXIuIFNvIHdlIG1hcmsgdGhpcyByZW5kZXIgYXMgaGF2aW5nIGEgcGluZy5cbiAgICAgIHdvcmtJblByb2dyZXNzUm9vdFBpbmdlZExhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcywgcGluZ2VkTGFuZXMpO1xuICAgIH1cbiAgfVxuXG4gIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xufVxuXG5mdW5jdGlvbiByZXRyeVRpbWVkT3V0Qm91bmRhcnkoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKSB7XG4gIC8vIFRoZSBib3VuZGFyeSBmaWJlciAoYSBTdXNwZW5zZSBjb21wb25lbnQgb3IgU3VzcGVuc2VMaXN0IGNvbXBvbmVudClcbiAgLy8gcHJldmlvdXNseSB3YXMgcmVuZGVyZWQgaW4gaXRzIGZhbGxiYWNrIHN0YXRlLiBPbmUgb2YgdGhlIHByb21pc2VzIHRoYXRcbiAgLy8gc3VzcGVuZGVkIGl0IGhhcyByZXNvbHZlZCwgd2hpY2ggbWVhbnMgYXQgbGVhc3QgcGFydCBvZiB0aGUgdHJlZSB3YXNcbiAgLy8gbGlrZWx5IHVuYmxvY2tlZC4gVHJ5IHJlbmRlcmluZyBhZ2FpbiwgYXQgYSBuZXcgbGFuZXMuXG4gIGlmIChyZXRyeUxhbmUgPT09IE5vTGFuZSkge1xuICAgIC8vIFRPRE86IEFzc2lnbiB0aGlzIHRvIGBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZWA/IHRvIGF2b2lkXG4gICAgLy8gdW5uZWNlc3NhcnkgZW50YW5nbGVtZW50P1xuICAgIHJldHJ5TGFuZSA9IHJlcXVlc3RSZXRyeUxhbmUoYm91bmRhcnlGaWJlcik7XG4gIH0gLy8gVE9ETzogU3BlY2lhbCBjYXNlIGlkbGUgcHJpb3JpdHk/XG5cblxuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICB2YXIgcm9vdCA9IG1hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KGJvdW5kYXJ5RmliZXIsIHJldHJ5TGFuZSk7XG5cbiAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICBtYXJrUm9vdFVwZGF0ZWQocm9vdCwgcmV0cnlMYW5lLCBldmVudFRpbWUpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJldHJ5RGVoeWRyYXRlZFN1c3BlbnNlQm91bmRhcnkoYm91bmRhcnlGaWJlcikge1xuICB2YXIgc3VzcGVuc2VTdGF0ZSA9IGJvdW5kYXJ5RmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHJldHJ5TGFuZSA9IE5vTGFuZTtcblxuICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCkge1xuICAgIHJldHJ5TGFuZSA9IHN1c3BlbnNlU3RhdGUucmV0cnlMYW5lO1xuICB9XG5cbiAgcmV0cnlUaW1lZE91dEJvdW5kYXJ5KGJvdW5kYXJ5RmliZXIsIHJldHJ5TGFuZSk7XG59XG5mdW5jdGlvbiByZXNvbHZlUmV0cnlXYWtlYWJsZShib3VuZGFyeUZpYmVyLCB3YWtlYWJsZSkge1xuICB2YXIgcmV0cnlMYW5lID0gTm9MYW5lOyAvLyBEZWZhdWx0XG5cbiAgdmFyIHJldHJ5Q2FjaGU7XG5cbiAgc3dpdGNoIChib3VuZGFyeUZpYmVyLnRhZykge1xuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICByZXRyeUNhY2hlID0gYm91bmRhcnlGaWJlci5zdGF0ZU5vZGU7XG4gICAgICB2YXIgc3VzcGVuc2VTdGF0ZSA9IGJvdW5kYXJ5RmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgaWYgKHN1c3BlbnNlU3RhdGUgIT09IG51bGwpIHtcbiAgICAgICAgcmV0cnlMYW5lID0gc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmU7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICByZXRyeUNhY2hlID0gYm91bmRhcnlGaWJlci5zdGF0ZU5vZGU7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BpbmdlZCB1bmtub3duIHN1c3BlbnNlIGJvdW5kYXJ5IHR5cGUuICcgKyAnVGhpcyBpcyBwcm9iYWJseSBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgfVxuXG4gIGlmIChyZXRyeUNhY2hlICE9PSBudWxsKSB7XG4gICAgLy8gVGhlIHdha2VhYmxlIHJlc29sdmVkLCBzbyB3ZSBubyBsb25nZXIgbmVlZCB0byBtZW1vaXplLCBiZWNhdXNlIGl0IHdpbGxcbiAgICAvLyBuZXZlciBiZSB0aHJvd24gYWdhaW4uXG4gICAgcmV0cnlDYWNoZS5kZWxldGUod2FrZWFibGUpO1xuICB9XG5cbiAgcmV0cnlUaW1lZE91dEJvdW5kYXJ5KGJvdW5kYXJ5RmliZXIsIHJldHJ5TGFuZSk7XG59IC8vIENvbXB1dGVzIHRoZSBuZXh0IEp1c3QgTm90aWNlYWJsZSBEaWZmZXJlbmNlIChKTkQpIGJvdW5kYXJ5LlxuLy8gVGhlIHRoZW9yeSBpcyB0aGF0IGEgcGVyc29uIGNhbid0IHRlbGwgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBzbWFsbCBkaWZmZXJlbmNlcyBpbiB0aW1lLlxuLy8gVGhlcmVmb3JlLCBpZiB3ZSB3YWl0IGEgYml0IGxvbmdlciB0aGFuIG5lY2Vzc2FyeSB0aGF0IHdvbid0IHRyYW5zbGF0ZSB0byBhIG5vdGljZWFibGVcbi8vIGRpZmZlcmVuY2UgaW4gdGhlIGV4cGVyaWVuY2UuIEhvd2V2ZXIsIHdhaXRpbmcgZm9yIGxvbmdlciBtaWdodCBtZWFuIHRoYXQgd2UgY2FuIGF2b2lkXG4vLyBzaG93aW5nIGFuIGludGVybWVkaWF0ZSBsb2FkaW5nIHN0YXRlLiBUaGUgbG9uZ2VyIHdlIGhhdmUgYWxyZWFkeSB3YWl0ZWQsIHRoZSBoYXJkZXIgaXRcbi8vIGlzIHRvIHRlbGwgc21hbGwgZGlmZmVyZW5jZXMgaW4gdGltZS4gVGhlcmVmb3JlLCB0aGUgbG9uZ2VyIHdlJ3ZlIGFscmVhZHkgd2FpdGVkLFxuLy8gdGhlIGxvbmdlciB3ZSBjYW4gd2FpdCBhZGRpdGlvbmFsbHkuIEF0IHNvbWUgcG9pbnQgd2UgaGF2ZSB0byBnaXZlIHVwIHRob3VnaC5cbi8vIFdlIHBpY2sgYSB0cmFpbiBtb2RlbCB3aGVyZSB0aGUgbmV4dCBib3VuZGFyeSBjb21taXRzIGF0IGEgY29uc2lzdGVudCBzY2hlZHVsZS5cbi8vIFRoZXNlIHBhcnRpY3VsYXIgbnVtYmVycyBhcmUgdmFndWUgZXN0aW1hdGVzLiBXZSBleHBlY3QgdG8gYWRqdXN0IHRoZW0gYmFzZWQgb24gcmVzZWFyY2guXG5cbmZ1bmN0aW9uIGpuZCh0aW1lRWxhcHNlZCkge1xuICByZXR1cm4gdGltZUVsYXBzZWQgPCAxMjAgPyAxMjAgOiB0aW1lRWxhcHNlZCA8IDQ4MCA/IDQ4MCA6IHRpbWVFbGFwc2VkIDwgMTA4MCA/IDEwODAgOiB0aW1lRWxhcHNlZCA8IDE5MjAgPyAxOTIwIDogdGltZUVsYXBzZWQgPCAzMDAwID8gMzAwMCA6IHRpbWVFbGFwc2VkIDwgNDMyMCA/IDQzMjAgOiBjZWlsKHRpbWVFbGFwc2VkIC8gMTk2MCkgKiAxOTYwO1xufVxuXG5mdW5jdGlvbiBjaGVja0Zvck5lc3RlZFVwZGF0ZXMoKSB7XG4gIGlmIChuZXN0ZWRVcGRhdGVDb3VudCA+IE5FU1RFRF9VUERBVEVfTElNSVQpIHtcbiAgICBuZXN0ZWRVcGRhdGVDb3VudCA9IDA7XG4gICAgcm9vdFdpdGhOZXN0ZWRVcGRhdGVzID0gbnVsbDtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01heGltdW0gdXBkYXRlIGRlcHRoIGV4Y2VlZGVkLiBUaGlzIGNhbiBoYXBwZW4gd2hlbiBhIGNvbXBvbmVudCAnICsgJ3JlcGVhdGVkbHkgY2FsbHMgc2V0U3RhdGUgaW5zaWRlIGNvbXBvbmVudFdpbGxVcGRhdGUgb3IgJyArICdjb21wb25lbnREaWRVcGRhdGUuIFJlYWN0IGxpbWl0cyB0aGUgbnVtYmVyIG9mIG5lc3RlZCB1cGRhdGVzIHRvICcgKyAncHJldmVudCBpbmZpbml0ZSBsb29wcy4nKTtcbiAgfVxuXG4gIHtcbiAgICBpZiAobmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID4gTkVTVEVEX1BBU1NJVkVfVVBEQVRFX0xJTUlUKSB7XG4gICAgICBuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQgPSAwO1xuICAgICAgcm9vdFdpdGhQYXNzaXZlTmVzdGVkVXBkYXRlcyA9IG51bGw7XG5cbiAgICAgIGVycm9yKCdNYXhpbXVtIHVwZGF0ZSBkZXB0aCBleGNlZWRlZC4gVGhpcyBjYW4gaGFwcGVuIHdoZW4gYSBjb21wb25lbnQgJyArIFwiY2FsbHMgc2V0U3RhdGUgaW5zaWRlIHVzZUVmZmVjdCwgYnV0IHVzZUVmZmVjdCBlaXRoZXIgZG9lc24ndCBcIiArICdoYXZlIGEgZGVwZW5kZW5jeSBhcnJheSwgb3Igb25lIG9mIHRoZSBkZXBlbmRlbmNpZXMgY2hhbmdlcyBvbiAnICsgJ2V2ZXJ5IHJlbmRlci4nKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmx1c2hSZW5kZXJQaGFzZVN0cmljdE1vZGVXYXJuaW5nc0luREVWKCkge1xuICB7XG4gICAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZygpO1xuXG4gICAge1xuICAgICAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZmx1c2hQZW5kaW5nVW5zYWZlTGlmZWN5Y2xlV2FybmluZ3MoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0RG91YmxlSW52b2tlRWZmZWN0c0luREVWKGZpYmVyLCBoYXNQYXNzaXZlRWZmZWN0cykge1xuICB7XG4gICAgLy8gVE9ETyAoU3RyaWN0RWZmZWN0cykgU2hvdWxkIHdlIHNldCBhIG1hcmtlciBvbiB0aGUgcm9vdCBpZiBpdCBjb250YWlucyBzdHJpY3QgZWZmZWN0c1xuICAgIC8vIHNvIHdlIGRvbid0IHRyYXZlcnNlIHVubmVjZXNzYXJpbHk/IHNpbWlsYXIgdG8gc3VidHJlZUZsYWdzIGJ1dCBqdXN0IGF0IHRoZSByb290IGxldmVsLlxuICAgIC8vIE1heWJlIG5vdCBhIGJpZyBkZWFsIHNpbmNlIHRoaXMgaXMgREVWIG9ubHkgYmVoYXZpb3IuXG4gICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcbiAgICBpbnZva2VFZmZlY3RzSW5EZXYoZmliZXIsIE1vdW50TGF5b3V0RGV2LCBpbnZva2VMYXlvdXRFZmZlY3RVbm1vdW50SW5ERVYpO1xuXG4gICAgaWYgKGhhc1Bhc3NpdmVFZmZlY3RzKSB7XG4gICAgICBpbnZva2VFZmZlY3RzSW5EZXYoZmliZXIsIE1vdW50UGFzc2l2ZURldiwgaW52b2tlUGFzc2l2ZUVmZmVjdFVubW91bnRJbkRFVik7XG4gICAgfVxuXG4gICAgaW52b2tlRWZmZWN0c0luRGV2KGZpYmVyLCBNb3VudExheW91dERldiwgaW52b2tlTGF5b3V0RWZmZWN0TW91bnRJbkRFVik7XG5cbiAgICBpZiAoaGFzUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIGludm9rZUVmZmVjdHNJbkRldihmaWJlciwgTW91bnRQYXNzaXZlRGV2LCBpbnZva2VQYXNzaXZlRWZmZWN0TW91bnRJbkRFVik7XG4gICAgfVxuXG4gICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZva2VFZmZlY3RzSW5EZXYoZmlyc3RDaGlsZCwgZmliZXJGbGFncywgaW52b2tlRWZmZWN0Rm4pIHtcbiAge1xuICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gcmUtY2hlY2sgU3RyaWN0RWZmZWN0c01vZGUgaGVyZS5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG9ubHkgY2FsbGVkIGlmIHRoYXQgY2hlY2sgaGFzIGFscmVhZHkgcGFzc2VkLlxuICAgIHZhciBjdXJyZW50ID0gZmlyc3RDaGlsZDtcbiAgICB2YXIgc3VidHJlZVJvb3QgPSBudWxsO1xuXG4gICAgd2hpbGUgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmltYXJ5U3VidHJlZUZsYWcgPSBjdXJyZW50LnN1YnRyZWVGbGFncyAmIGZpYmVyRmxhZ3M7XG5cbiAgICAgIGlmIChjdXJyZW50ICE9PSBzdWJ0cmVlUm9vdCAmJiBjdXJyZW50LmNoaWxkICE9PSBudWxsICYmIHByaW1hcnlTdWJ0cmVlRmxhZyAhPT0gTm9GbGFncykge1xuICAgICAgICBjdXJyZW50ID0gY3VycmVudC5jaGlsZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICgoY3VycmVudC5mbGFncyAmIGZpYmVyRmxhZ3MpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgaW52b2tlRWZmZWN0Rm4oY3VycmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudC5zaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuc2libGluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50ID0gc3VidHJlZVJvb3QgPSBjdXJyZW50LnJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudCA9IG51bGw7XG5cbmZ1bmN0aW9uIHdhcm5BYm91dFVwZGF0ZU9uTm90WWV0TW91bnRlZEZpYmVySW5ERVYoZmliZXIpIHtcbiAge1xuICAgIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHQpIHtcbiAgICAgIC8vIFdlIGxldCB0aGUgb3RoZXIgd2FybmluZyBhYm91dCByZW5kZXIgcGhhc2UgdXBkYXRlcyBkZWFsIHdpdGggdGhpcyBvbmUuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCEoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0YWcgPSBmaWJlci50YWc7XG5cbiAgICBpZiAodGFnICE9PSBJbmRldGVybWluYXRlQ29tcG9uZW50ICYmIHRhZyAhPT0gSG9zdFJvb3QgJiYgdGFnICE9PSBDbGFzc0NvbXBvbmVudCAmJiB0YWcgIT09IEZ1bmN0aW9uQ29tcG9uZW50ICYmIHRhZyAhPT0gRm9yd2FyZFJlZiAmJiB0YWcgIT09IE1lbW9Db21wb25lbnQgJiYgdGFnICE9PSBTaW1wbGVNZW1vQ29tcG9uZW50KSB7XG4gICAgICAvLyBPbmx5IHdhcm4gZm9yIHVzZXItZGVmaW5lZCBjb21wb25lbnRzLCBub3QgaW50ZXJuYWwgb25lcyBsaWtlIFN1c3BlbnNlLlxuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gV2Ugc2hvdyB0aGUgd2hvbGUgc3RhY2sgYnV0IGRlZHVwZSBvbiB0aGUgdG9wIGNvbXBvbmVudCdzIG5hbWUgYmVjYXVzZVxuICAgIC8vIHRoZSBwcm9ibGVtYXRpYyBjb2RlIGFsbW9zdCBhbHdheXMgbGllcyBpbnNpZGUgdGhhdCBjb21wb25lbnQuXG5cblxuICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1JlYWN0Q29tcG9uZW50JztcblxuICAgIGlmIChkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50ICE9PSBudWxsKSB7XG4gICAgICBpZiAoZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudC5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50LmFkZChjb21wb25lbnROYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudCA9IG5ldyBTZXQoW2NvbXBvbmVudE5hbWVdKTtcbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICB0cnkge1xuICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgZXJyb3IoXCJDYW4ndCBwZXJmb3JtIGEgUmVhY3Qgc3RhdGUgdXBkYXRlIG9uIGEgY29tcG9uZW50IHRoYXQgaGFzbid0IG1vdW50ZWQgeWV0LiBcIiArICdUaGlzIGluZGljYXRlcyB0aGF0IHlvdSBoYXZlIGEgc2lkZS1lZmZlY3QgaW4geW91ciByZW5kZXIgZnVuY3Rpb24gdGhhdCAnICsgJ2FzeW5jaHJvbm91c2x5IGxhdGVyIGNhbGxzIHRyaWVzIHRvIHVwZGF0ZSB0aGUgY29tcG9uZW50LiBNb3ZlIHRoaXMgd29yayB0byAnICsgJ3VzZUVmZmVjdCBpbnN0ZWFkLicpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAocHJldmlvdXNGaWJlcikge1xuICAgICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIGJlZ2luV29yayQxO1xuXG57XG4gIHZhciBkdW1teUZpYmVyID0gbnVsbDtcblxuICBiZWdpbldvcmskMSA9IGZ1bmN0aW9uIChjdXJyZW50LCB1bml0T2ZXb3JrLCBsYW5lcykge1xuICAgIC8vIElmIGEgY29tcG9uZW50IHRocm93cyBhbiBlcnJvciwgd2UgcmVwbGF5IGl0IGFnYWluIGluIGEgc3luY2hyb25vdXNseVxuICAgIC8vIGRpc3BhdGNoZWQgZXZlbnQsIHNvIHRoYXQgdGhlIGRlYnVnZ2VyIHdpbGwgdHJlYXQgaXQgYXMgYW4gdW5jYXVnaHRcbiAgICAvLyBlcnJvciBTZWUgUmVhY3RFcnJvclV0aWxzIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgIC8vIEJlZm9yZSBlbnRlcmluZyB0aGUgYmVnaW4gcGhhc2UsIGNvcHkgdGhlIHdvcmstaW4tcHJvZ3Jlc3Mgb250byBhIGR1bW15XG4gICAgLy8gZmliZXIuIElmIGJlZ2luV29yayB0aHJvd3MsIHdlJ2xsIHVzZSB0aGlzIHRvIHJlc2V0IHRoZSBzdGF0ZS5cbiAgICB2YXIgb3JpZ2luYWxXb3JrSW5Qcm9ncmVzc0NvcHkgPSBhc3NpZ25GaWJlclByb3BlcnRpZXNJbkRFVihkdW1teUZpYmVyLCB1bml0T2ZXb3JrKTtcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYmVnaW5Xb3JrKGN1cnJlbnQsIHVuaXRPZldvcmssIGxhbmVzKTtcbiAgICB9IGNhdGNoIChvcmlnaW5hbEVycm9yKSB7XG4gICAgICBpZiAob3JpZ2luYWxFcnJvciAhPT0gbnVsbCAmJiB0eXBlb2Ygb3JpZ2luYWxFcnJvciA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG9yaWdpbmFsRXJyb3IudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBEb24ndCByZXBsYXkgcHJvbWlzZXMuIFRyZWF0IGV2ZXJ5dGhpbmcgZWxzZSBsaWtlIGFuIGVycm9yLlxuICAgICAgICB0aHJvdyBvcmlnaW5hbEVycm9yO1xuICAgICAgfSAvLyBLZWVwIHRoaXMgY29kZSBpbiBzeW5jIHdpdGggaGFuZGxlRXJyb3I7IGFueSBjaGFuZ2VzIGhlcmUgbXVzdCBoYXZlXG4gICAgICAvLyBjb3JyZXNwb25kaW5nIGNoYW5nZXMgdGhlcmUuXG5cblxuICAgICAgcmVzZXRDb250ZXh0RGVwZW5kZW5jaWVzKCk7XG4gICAgICByZXNldEhvb2tzQWZ0ZXJUaHJvdygpOyAvLyBEb24ndCByZXNldCBjdXJyZW50IGRlYnVnIGZpYmVyLCBzaW5jZSB3ZSdyZSBhYm91dCB0byB3b3JrIG9uIHRoZVxuICAgICAgLy8gc2FtZSBmaWJlciBhZ2Fpbi5cbiAgICAgIC8vIFVud2luZCB0aGUgZmFpbGVkIHN0YWNrIGZyYW1lXG5cbiAgICAgIHVud2luZEludGVycnVwdGVkV29yayhjdXJyZW50LCB1bml0T2ZXb3JrKTsgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgcHJvcGVydGllcyBvZiB0aGUgZmliZXIuXG5cbiAgICAgIGFzc2lnbkZpYmVyUHJvcGVydGllc0luREVWKHVuaXRPZldvcmssIG9yaWdpbmFsV29ya0luUHJvZ3Jlc3NDb3B5KTtcblxuICAgICAgaWYgKCB1bml0T2ZXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAvLyBSZXNldCB0aGUgcHJvZmlsZXIgdGltZXIuXG4gICAgICAgIHN0YXJ0UHJvZmlsZXJUaW1lcih1bml0T2ZXb3JrKTtcbiAgICAgIH0gLy8gUnVuIGJlZ2luV29yayBhZ2Fpbi5cblxuXG4gICAgICBpbnZva2VHdWFyZGVkQ2FsbGJhY2sobnVsbCwgYmVnaW5Xb3JrLCBudWxsLCBjdXJyZW50LCB1bml0T2ZXb3JrLCBsYW5lcyk7XG5cbiAgICAgIGlmIChoYXNDYXVnaHRFcnJvcigpKSB7XG4gICAgICAgIHZhciByZXBsYXlFcnJvciA9IGNsZWFyQ2F1Z2h0RXJyb3IoKTtcblxuICAgICAgICBpZiAodHlwZW9mIHJlcGxheUVycm9yID09PSAnb2JqZWN0JyAmJiByZXBsYXlFcnJvciAhPT0gbnVsbCAmJiByZXBsYXlFcnJvci5fc3VwcHJlc3NMb2dnaW5nICYmIHR5cGVvZiBvcmlnaW5hbEVycm9yID09PSAnb2JqZWN0JyAmJiBvcmlnaW5hbEVycm9yICE9PSBudWxsICYmICFvcmlnaW5hbEVycm9yLl9zdXBwcmVzc0xvZ2dpbmcpIHtcbiAgICAgICAgICAvLyBJZiBzdXBwcmVzc2VkLCBsZXQgdGhlIGZsYWcgY2Fycnkgb3ZlciB0byB0aGUgb3JpZ2luYWwgZXJyb3Igd2hpY2ggaXMgdGhlIG9uZSB3ZSdsbCByZXRocm93LlxuICAgICAgICAgIG9yaWdpbmFsRXJyb3IuX3N1cHByZXNzTG9nZ2luZyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gV2UgYWx3YXlzIHRocm93IHRoZSBvcmlnaW5hbCBlcnJvciBpbiBjYXNlIHRoZSBzZWNvbmQgcmVuZGVyIHBhc3MgaXMgbm90IGlkZW1wb3RlbnQuXG4gICAgICAvLyBUaGlzIGNhbiBoYXBwZW4gaWYgYSBtZW1vaXplZCBmdW5jdGlvbiBvciBDb21tb25KUyBtb2R1bGUgZG9lc24ndCB0aHJvdyBhZnRlciBmaXJzdCBpbnZvY2F0aW9uLlxuXG5cbiAgICAgIHRocm93IG9yaWdpbmFsRXJyb3I7XG4gICAgfVxuICB9O1xufVxuXG52YXIgZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXIgPSBmYWxzZTtcbnZhciBkaWRXYXJuQWJvdXRVcGRhdGVJblJlbmRlckZvckFub3RoZXJDb21wb25lbnQ7XG5cbntcbiAgZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXJGb3JBbm90aGVyQ29tcG9uZW50ID0gbmV3IFNldCgpO1xufVxuXG5mdW5jdGlvbiB3YXJuQWJvdXRSZW5kZXJQaGFzZVVwZGF0ZXNJbkRFVihmaWJlcikge1xuICB7XG4gICAgaWYgKGlzUmVuZGVyaW5nICYmICFnZXRJc1VwZGF0aW5nT3BhcXVlVmFsdWVJblJlbmRlclBoYXNlSW5ERVYoKSkge1xuICAgICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIHJlbmRlcmluZ0NvbXBvbmVudE5hbWUgPSB3b3JrSW5Qcm9ncmVzcyAmJiBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHdvcmtJblByb2dyZXNzKSB8fCAnVW5rbm93bic7IC8vIERlZHVwZSBieSB0aGUgcmVuZGVyaW5nIGNvbXBvbmVudCBiZWNhdXNlIGl0J3MgdGhlIG9uZSB0aGF0IG5lZWRzIHRvIGJlIGZpeGVkLlxuXG4gICAgICAgICAgICB2YXIgZGVkdXBlS2V5ID0gcmVuZGVyaW5nQ29tcG9uZW50TmFtZTtcblxuICAgICAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRVcGRhdGVJblJlbmRlckZvckFub3RoZXJDb21wb25lbnQuaGFzKGRlZHVwZUtleSkpIHtcbiAgICAgICAgICAgICAgZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXJGb3JBbm90aGVyQ29tcG9uZW50LmFkZChkZWR1cGVLZXkpO1xuICAgICAgICAgICAgICB2YXIgc2V0U3RhdGVDb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1Vua25vd24nO1xuXG4gICAgICAgICAgICAgIGVycm9yKCdDYW5ub3QgdXBkYXRlIGEgY29tcG9uZW50IChgJXNgKSB3aGlsZSByZW5kZXJpbmcgYSAnICsgJ2RpZmZlcmVudCBjb21wb25lbnQgKGAlc2ApLiBUbyBsb2NhdGUgdGhlIGJhZCBzZXRTdGF0ZSgpIGNhbGwgaW5zaWRlIGAlc2AsICcgKyAnZm9sbG93IHRoZSBzdGFjayB0cmFjZSBhcyBkZXNjcmliZWQgaW4gaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3NldHN0YXRlLWluLXJlbmRlcicsIHNldFN0YXRlQ29tcG9uZW50TmFtZSwgcmVuZGVyaW5nQ29tcG9uZW50TmFtZSwgcmVuZGVyaW5nQ29tcG9uZW50TmFtZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICghZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXIpIHtcbiAgICAgICAgICAgICAgZXJyb3IoJ0Nhbm5vdCB1cGRhdGUgZHVyaW5nIGFuIGV4aXN0aW5nIHN0YXRlIHRyYW5zaXRpb24gKHN1Y2ggYXMgJyArICd3aXRoaW4gYHJlbmRlcmApLiBSZW5kZXIgbWV0aG9kcyBzaG91bGQgYmUgYSBwdXJlICcgKyAnZnVuY3Rpb24gb2YgcHJvcHMgYW5kIHN0YXRlLicpO1xuXG4gICAgICAgICAgICAgIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIGxhbmVzKSB7XG4gIHtcbiAgICBpZiAoaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICAgIHZhciBtZW1vaXplZFVwZGF0ZXJzID0gcm9vdC5tZW1vaXplZFVwZGF0ZXJzO1xuICAgICAgbWVtb2l6ZWRVcGRhdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChzY2hlZHVsaW5nRmliZXIpIHtcbiAgICAgICAgYWRkRmliZXJUb0xhbmVzTWFwKHJvb3QsIHNjaGVkdWxpbmdGaWJlciwgbGFuZXMpO1xuICAgICAgfSk7IC8vIFRoaXMgZnVuY3Rpb24gaW50ZW50aW9uYWxseSBkb2VzIG5vdCBjbGVhciBtZW1vaXplZCB1cGRhdGVycy5cbiAgICAgIC8vIFRob3NlIG1heSBzdGlsbCBiZSByZWxldmFudCB0byB0aGUgY3VycmVudCBjb21taXRcbiAgICAgIC8vIGFuZCBhIGZ1dHVyZSBvbmUgKGUuZy4gU3VzcGVuc2UpLlxuICAgIH1cbiAgfVxufVxudmFyIGZha2VBY3RDYWxsYmFja05vZGUgPSB7fTtcblxuZnVuY3Rpb24gc2NoZWR1bGVDYWxsYmFjayQxKHByaW9yaXR5TGV2ZWwsIGNhbGxiYWNrKSB7XG4gIHtcbiAgICAvLyBJZiB3ZSdyZSBjdXJyZW50bHkgaW5zaWRlIGFuIGBhY3RgIHNjb3BlLCBieXBhc3MgU2NoZWR1bGVyIGFuZCBwdXNoIHRvXG4gICAgLy8gdGhlIGBhY3RgIHF1ZXVlIGluc3RlYWQuXG4gICAgdmFyIGFjdFF1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50O1xuXG4gICAgaWYgKGFjdFF1ZXVlICE9PSBudWxsKSB7XG4gICAgICBhY3RRdWV1ZS5wdXNoKGNhbGxiYWNrKTtcbiAgICAgIHJldHVybiBmYWtlQWN0Q2FsbGJhY2tOb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2NoZWR1bGVDYWxsYmFjayhwcmlvcml0eUxldmVsLCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNhbmNlbENhbGxiYWNrJDEoY2FsbGJhY2tOb2RlKSB7XG4gIGlmICggY2FsbGJhY2tOb2RlID09PSBmYWtlQWN0Q2FsbGJhY2tOb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIEluIHByb2R1Y3Rpb24sIGFsd2F5cyBjYWxsIFNjaGVkdWxlci4gVGhpcyBmdW5jdGlvbiB3aWxsIGJlIHN0cmlwcGVkIG91dC5cblxuXG4gIHJldHVybiBjYW5jZWxDYWxsYmFjayhjYWxsYmFja05vZGUpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRGb3JjZUZsdXNoRmFsbGJhY2tzSW5ERVYoKSB7XG4gIC8vIE5ldmVyIGZvcmNlIGZsdXNoIGluIHByb2R1Y3Rpb24uIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGdldCBzdHJpcHBlZCBvdXQuXG4gIHJldHVybiAgUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiB3YXJuSWZVcGRhdGVzTm90V3JhcHBlZFdpdGhBY3RERVYoZmliZXIpIHtcbiAge1xuICAgIGlmIChmaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpIHtcbiAgICAgIGlmICghaXNDb25jdXJyZW50QWN0RW52aXJvbm1lbnQoKSkge1xuICAgICAgICAvLyBOb3QgaW4gYW4gYWN0IGVudmlyb25tZW50LiBObyBuZWVkIHRvIHdhcm4uXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTGVnYWN5IG1vZGUgaGFzIGFkZGl0aW9uYWwgY2FzZXMgd2hlcmUgd2Ugc3VwcHJlc3MgYSB3YXJuaW5nLlxuICAgICAgaWYgKCFpc0xlZ2FjeUFjdEVudmlyb25tZW50KCkpIHtcbiAgICAgICAgLy8gTm90IGluIGFuIGFjdCBlbnZpcm9ubWVudC4gTm8gbmVlZCB0byB3YXJuLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChleGVjdXRpb25Db250ZXh0ICE9PSBOb0NvbnRleHQpIHtcbiAgICAgICAgLy8gTGVnYWN5IG1vZGUgZG9lc24ndCB3YXJuIGlmIHRoZSB1cGRhdGUgaXMgYmF0Y2hlZCwgaS5lLlxuICAgICAgICAvLyBiYXRjaGVkVXBkYXRlcyBvciBmbHVzaFN5bmMuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGZpYmVyLnRhZyAhPT0gRnVuY3Rpb25Db21wb25lbnQgJiYgZmliZXIudGFnICE9PSBGb3J3YXJkUmVmICYmIGZpYmVyLnRhZyAhPT0gU2ltcGxlTWVtb0NvbXBvbmVudCkge1xuICAgICAgICAvLyBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2l0aCBwcmUtaG9va3MgY29kZSwgbGVnYWN5IG1vZGUgb25seVxuICAgICAgICAvLyB3YXJucyBmb3IgdXBkYXRlcyB0aGF0IG9yaWdpbmF0ZSBmcm9tIGEgaG9vay5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2aW91c0ZpYmVyID0gY3VycmVudDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgICBlcnJvcignQW4gdXBkYXRlIHRvICVzIGluc2lkZSBhIHRlc3Qgd2FzIG5vdCB3cmFwcGVkIGluIGFjdCguLi4pLlxcblxcbicgKyAnV2hlbiB0ZXN0aW5nLCBjb2RlIHRoYXQgY2F1c2VzIFJlYWN0IHN0YXRlIHVwZGF0ZXMgc2hvdWxkIGJlICcgKyAnd3JhcHBlZCBpbnRvIGFjdCguLi4pOlxcblxcbicgKyAnYWN0KCgpID0+IHtcXG4nICsgJyAgLyogZmlyZSBldmVudHMgdGhhdCB1cGRhdGUgc3RhdGUgKi9cXG4nICsgJ30pO1xcbicgKyAnLyogYXNzZXJ0IG9uIHRoZSBvdXRwdXQgKi9cXG5cXG4nICsgXCJUaGlzIGVuc3VyZXMgdGhhdCB5b3UncmUgdGVzdGluZyB0aGUgYmVoYXZpb3IgdGhlIHVzZXIgd291bGQgc2VlIFwiICsgJ2luIHRoZSBicm93c2VyLicgKyAnIExlYXJuIG1vcmUgYXQgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3dyYXAtdGVzdHMtd2l0aC1hY3QnLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAocHJldmlvdXNGaWJlcikge1xuICAgICAgICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB3YXJuSWZTdXNwZW5zZVJlc29sdXRpb25Ob3RXcmFwcGVkV2l0aEFjdERFVihyb290KSB7XG4gIHtcbiAgICBpZiAocm9vdC50YWcgIT09IExlZ2FjeVJvb3QgJiYgaXNDb25jdXJyZW50QWN0RW52aXJvbm1lbnQoKSAmJiBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdBIHN1c3BlbmRlZCByZXNvdXJjZSBmaW5pc2hlZCBsb2FkaW5nIGluc2lkZSBhIHRlc3QsIGJ1dCB0aGUgZXZlbnQgJyArICd3YXMgbm90IHdyYXBwZWQgaW4gYWN0KC4uLikuXFxuXFxuJyArICdXaGVuIHRlc3RpbmcsIGNvZGUgdGhhdCByZXNvbHZlcyBzdXNwZW5kZWQgZGF0YSBzaG91bGQgYmUgd3JhcHBlZCAnICsgJ2ludG8gYWN0KC4uLik6XFxuXFxuJyArICdhY3QoKCkgPT4ge1xcbicgKyAnICAvKiBmaW5pc2ggbG9hZGluZyBzdXNwZW5kZWQgZGF0YSAqL1xcbicgKyAnfSk7XFxuJyArICcvKiBhc3NlcnQgb24gdGhlIG91dHB1dCAqL1xcblxcbicgKyBcIlRoaXMgZW5zdXJlcyB0aGF0IHlvdSdyZSB0ZXN0aW5nIHRoZSBiZWhhdmlvciB0aGUgdXNlciB3b3VsZCBzZWUgXCIgKyAnaW4gdGhlIGJyb3dzZXIuJyArICcgTGVhcm4gbW9yZSBhdCBodHRwczovL3JlYWN0anMub3JnL2xpbmsvd3JhcC10ZXN0cy13aXRoLWFjdCcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QoaXNSdW5uaW5nKSB7XG4gIHtcbiAgICBpc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QgPSBpc1J1bm5pbmc7XG4gIH1cbn1cblxuLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2RlcyAqL1xudmFyIHJlc29sdmVGYW1pbHkgPSBudWxsOyAvLyAkRmxvd0ZpeE1lIEZsb3cgZ2V0cyBjb25mdXNlZCBieSBhIFdlYWtTZXQgZmVhdHVyZSBjaGVjayBiZWxvdy5cblxudmFyIGZhaWxlZEJvdW5kYXJpZXMgPSBudWxsO1xudmFyIHNldFJlZnJlc2hIYW5kbGVyID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAge1xuICAgIHJlc29sdmVGYW1pbHkgPSBoYW5kbGVyO1xuICB9XG59O1xuZnVuY3Rpb24gcmVzb2x2ZUZ1bmN0aW9uRm9ySG90UmVsb2FkaW5nKHR5cGUpIHtcbiAge1xuICAgIGlmIChyZXNvbHZlRmFtaWx5ID09PSBudWxsKSB7XG4gICAgICAvLyBIb3QgcmVsb2FkaW5nIGlzIGRpc2FibGVkLlxuICAgICAgcmV0dXJuIHR5cGU7XG4gICAgfVxuXG4gICAgdmFyIGZhbWlseSA9IHJlc29sdmVGYW1pbHkodHlwZSk7XG5cbiAgICBpZiAoZmFtaWx5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH0gLy8gVXNlIHRoZSBsYXRlc3Qga25vd24gaW1wbGVtZW50YXRpb24uXG5cblxuICAgIHJldHVybiBmYW1pbHkuY3VycmVudDtcbiAgfVxufVxuZnVuY3Rpb24gcmVzb2x2ZUNsYXNzRm9ySG90UmVsb2FkaW5nKHR5cGUpIHtcbiAgLy8gTm8gaW1wbGVtZW50YXRpb24gZGlmZmVyZW5jZXMuXG4gIHJldHVybiByZXNvbHZlRnVuY3Rpb25Gb3JIb3RSZWxvYWRpbmcodHlwZSk7XG59XG5mdW5jdGlvbiByZXNvbHZlRm9yd2FyZFJlZkZvckhvdFJlbG9hZGluZyh0eXBlKSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH1cblxuICAgIHZhciBmYW1pbHkgPSByZXNvbHZlRmFtaWx5KHR5cGUpO1xuXG4gICAgaWYgKGZhbWlseSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSByZWFsIGZvcndhcmRSZWYuIERvbid0IHdhbnQgdG8gY3Jhc2ggZWFybHkuXG4gICAgICBpZiAodHlwZSAhPT0gbnVsbCAmJiB0eXBlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHR5cGUucmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIEZvcndhcmRSZWYgaXMgc3BlY2lhbCBiZWNhdXNlIGl0cyByZXNvbHZlZCAudHlwZSBpcyBhbiBvYmplY3QsXG4gICAgICAgIC8vIGJ1dCBpdCdzIHBvc3NpYmxlIHRoYXQgd2Ugb25seSBoYXZlIGl0cyBpbm5lciByZW5kZXIgZnVuY3Rpb24gaW4gdGhlIG1hcC5cbiAgICAgICAgLy8gSWYgdGhhdCBpbm5lciByZW5kZXIgZnVuY3Rpb24gaXMgZGlmZmVyZW50LCB3ZSdsbCBidWlsZCBhIG5ldyBmb3J3YXJkUmVmIHR5cGUuXG4gICAgICAgIHZhciBjdXJyZW50UmVuZGVyID0gcmVzb2x2ZUZ1bmN0aW9uRm9ySG90UmVsb2FkaW5nKHR5cGUucmVuZGVyKTtcblxuICAgICAgICBpZiAodHlwZS5yZW5kZXIgIT09IGN1cnJlbnRSZW5kZXIpIHtcbiAgICAgICAgICB2YXIgc3ludGhldGljVHlwZSA9IHtcbiAgICAgICAgICAgICQkdHlwZW9mOiBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFLFxuICAgICAgICAgICAgcmVuZGVyOiBjdXJyZW50UmVuZGVyXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmICh0eXBlLmRpc3BsYXlOYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN5bnRoZXRpY1R5cGUuZGlzcGxheU5hbWUgPSB0eXBlLmRpc3BsYXlOYW1lO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBzeW50aGV0aWNUeXBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH0gLy8gVXNlIHRoZSBsYXRlc3Qga25vd24gaW1wbGVtZW50YXRpb24uXG5cblxuICAgIHJldHVybiBmYW1pbHkuY3VycmVudDtcbiAgfVxufVxuZnVuY3Rpb24gaXNDb21wYXRpYmxlRmFtaWx5Rm9ySG90UmVsb2FkaW5nKGZpYmVyLCBlbGVtZW50KSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgcHJldlR5cGUgPSBmaWJlci5lbGVtZW50VHlwZTtcbiAgICB2YXIgbmV4dFR5cGUgPSBlbGVtZW50LnR5cGU7IC8vIElmIHdlIGdvdCBoZXJlLCB3ZSBrbm93IHR5cGVzIGFyZW4ndCA9PT0gZXF1YWwuXG5cbiAgICB2YXIgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSBmYWxzZTtcbiAgICB2YXIgJCR0eXBlb2ZOZXh0VHlwZSA9IHR5cGVvZiBuZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgbmV4dFR5cGUgIT09IG51bGwgPyBuZXh0VHlwZS4kJHR5cGVvZiA6IG51bGw7XG5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmV4dFR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBuZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfTEFaWV9UWVBFKSB7XG4gICAgICAgICAgICAvLyBXZSBkb24ndCBrbm93IHRoZSBpbm5lciB0eXBlIHlldC5cbiAgICAgICAgICAgIC8vIFdlJ3JlIGdvaW5nIHRvIGFzc3VtZSB0aGF0IHRoZSBsYXp5IGlubmVyIHR5cGUgaXMgc3RhYmxlLFxuICAgICAgICAgICAgLy8gYW5kIHNvIGl0IGlzIHN1ZmZpY2llbnQgdG8gYXZvaWQgcmVjb25jaWxpbmcgaXQgYXdheS5cbiAgICAgICAgICAgIC8vIFdlJ3JlIG5vdCBnb2luZyB0byB1bndyYXAgb3IgYWN0dWFsbHkgdXNlIHRoZSBuZXcgbGF6eSB0eXBlLlxuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAge1xuICAgICAgICAgIGlmICgkJHR5cGVvZk5leHRUeXBlID09PSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFKSB7XG4gICAgICAgICAgICBuZWVkc0NvbXBhcmVGYW1pbGllcyA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIGlmICgkJHR5cGVvZk5leHRUeXBlID09PSBSRUFDVF9MQVpZX1RZUEUpIHtcbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIE1lbW9Db21wb25lbnQ6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfTUVNT19UWVBFKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBpZiBpdCB3YXMgYnV0IGNhbiBubyBsb25nZXIgYmUgc2ltcGxlLFxuICAgICAgICAgICAgLy8gd2Ugc2hvdWxkbid0IHNldCB0aGlzLlxuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfTEFaWV9UWVBFKSB7XG4gICAgICAgICAgICBuZWVkc0NvbXBhcmVGYW1pbGllcyA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gLy8gQ2hlY2sgaWYgYm90aCB0eXBlcyBoYXZlIGEgZmFtaWx5IGFuZCBpdCdzIHRoZSBzYW1lIG9uZS5cblxuXG4gICAgaWYgKG5lZWRzQ29tcGFyZUZhbWlsaWVzKSB7XG4gICAgICAvLyBOb3RlOiBtZW1vKCkgYW5kIGZvcndhcmRSZWYoKSB3ZSdsbCBjb21wYXJlIG91dGVyIHJhdGhlciB0aGFuIGlubmVyIHR5cGUuXG4gICAgICAvLyBUaGlzIG1lYW5zIGJvdGggb2YgdGhlbSBuZWVkIHRvIGJlIHJlZ2lzdGVyZWQgdG8gcHJlc2VydmUgc3RhdGUuXG4gICAgICAvLyBJZiB3ZSB1bndyYXBwZWQgYW5kIGNvbXBhcmVkIHRoZSBpbm5lciB0eXBlcyBmb3Igd3JhcHBlcnMgaW5zdGVhZCxcbiAgICAgIC8vIHRoZW4gd2Ugd291bGQgcmlzayBmYWxzZWx5IHNheWluZyB0d28gc2VwYXJhdGUgbWVtbyhGb28pXG4gICAgICAvLyBjYWxscyBhcmUgZXF1aXZhbGVudCBiZWNhdXNlIHRoZXkgd3JhcCB0aGUgc2FtZSBGb28gZnVuY3Rpb24uXG4gICAgICB2YXIgcHJldkZhbWlseSA9IHJlc29sdmVGYW1pbHkocHJldlR5cGUpO1xuXG4gICAgICBpZiAocHJldkZhbWlseSAhPT0gdW5kZWZpbmVkICYmIHByZXZGYW1pbHkgPT09IHJlc29sdmVGYW1pbHkobmV4dFR5cGUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gbWFya0ZhaWxlZEVycm9yQm91bmRhcnlGb3JIb3RSZWxvYWRpbmcoZmliZXIpIHtcbiAge1xuICAgIGlmIChyZXNvbHZlRmFtaWx5ID09PSBudWxsKSB7XG4gICAgICAvLyBIb3QgcmVsb2FkaW5nIGlzIGRpc2FibGVkLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgV2Vha1NldCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChmYWlsZWRCb3VuZGFyaWVzID09PSBudWxsKSB7XG4gICAgICBmYWlsZWRCb3VuZGFyaWVzID0gbmV3IFdlYWtTZXQoKTtcbiAgICB9XG5cbiAgICBmYWlsZWRCb3VuZGFyaWVzLmFkZChmaWJlcik7XG4gIH1cbn1cbnZhciBzY2hlZHVsZVJlZnJlc2ggPSBmdW5jdGlvbiAocm9vdCwgdXBkYXRlKSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc3RhbGVGYW1pbGllcyA9IHVwZGF0ZS5zdGFsZUZhbWlsaWVzLFxuICAgICAgICB1cGRhdGVkRmFtaWxpZXMgPSB1cGRhdGUudXBkYXRlZEZhbWlsaWVzO1xuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgICBmbHVzaFN5bmMoZnVuY3Rpb24gKCkge1xuICAgICAgc2NoZWR1bGVGaWJlcnNXaXRoRmFtaWxpZXNSZWN1cnNpdmVseShyb290LmN1cnJlbnQsIHVwZGF0ZWRGYW1pbGllcywgc3RhbGVGYW1pbGllcyk7XG4gICAgfSk7XG4gIH1cbn07XG52YXIgc2NoZWR1bGVSb290ID0gZnVuY3Rpb24gKHJvb3QsIGVsZW1lbnQpIHtcbiAge1xuICAgIGlmIChyb290LmNvbnRleHQgIT09IGVtcHR5Q29udGV4dE9iamVjdCkge1xuICAgICAgLy8gU3VwZXIgZWRnZSBjYXNlOiByb290IGhhcyBhIGxlZ2FjeSBfcmVuZGVyU3VidHJlZSBjb250ZXh0XG4gICAgICAvLyBidXQgd2UgZG9uJ3Qga25vdyB0aGUgcGFyZW50Q29tcG9uZW50IHNvIHdlIGNhbid0IHBhc3MgaXQuXG4gICAgICAvLyBKdXN0IGlnbm9yZS4gV2UnbGwgZGVsZXRlIHRoaXMgd2l0aCBfcmVuZGVyU3VidHJlZSBjb2RlIHBhdGggbGF0ZXIuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuICAgIGZsdXNoU3luYyhmdW5jdGlvbiAoKSB7XG4gICAgICB1cGRhdGVDb250YWluZXIoZWxlbWVudCwgcm9vdCwgbnVsbCwgbnVsbCk7XG4gICAgfSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHNjaGVkdWxlRmliZXJzV2l0aEZhbWlsaWVzUmVjdXJzaXZlbHkoZmliZXIsIHVwZGF0ZWRGYW1pbGllcywgc3RhbGVGYW1pbGllcykge1xuICB7XG4gICAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZSxcbiAgICAgICAgY2hpbGQgPSBmaWJlci5jaGlsZCxcbiAgICAgICAgc2libGluZyA9IGZpYmVyLnNpYmxpbmcsXG4gICAgICAgIHRhZyA9IGZpYmVyLnRhZyxcbiAgICAgICAgdHlwZSA9IGZpYmVyLnR5cGU7XG4gICAgdmFyIGNhbmRpZGF0ZVR5cGUgPSBudWxsO1xuXG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICBjYW5kaWRhdGVUeXBlID0gdHlwZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAgY2FuZGlkYXRlVHlwZSA9IHR5cGUucmVuZGVyO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCByZXNvbHZlRmFtaWx5IHRvIGJlIHNldCBkdXJpbmcgaG90IHJlbG9hZC4nKTtcbiAgICB9XG5cbiAgICB2YXIgbmVlZHNSZW5kZXIgPSBmYWxzZTtcbiAgICB2YXIgbmVlZHNSZW1vdW50ID0gZmFsc2U7XG5cbiAgICBpZiAoY2FuZGlkYXRlVHlwZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIGZhbWlseSA9IHJlc29sdmVGYW1pbHkoY2FuZGlkYXRlVHlwZSk7XG5cbiAgICAgIGlmIChmYW1pbHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoc3RhbGVGYW1pbGllcy5oYXMoZmFtaWx5KSkge1xuICAgICAgICAgIG5lZWRzUmVtb3VudCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAodXBkYXRlZEZhbWlsaWVzLmhhcyhmYW1pbHkpKSB7XG4gICAgICAgICAgaWYgKHRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgICAgICAgIG5lZWRzUmVtb3VudCA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5lZWRzUmVuZGVyID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmFpbGVkQm91bmRhcmllcyAhPT0gbnVsbCkge1xuICAgICAgaWYgKGZhaWxlZEJvdW5kYXJpZXMuaGFzKGZpYmVyKSB8fCBhbHRlcm5hdGUgIT09IG51bGwgJiYgZmFpbGVkQm91bmRhcmllcy5oYXMoYWx0ZXJuYXRlKSkge1xuICAgICAgICBuZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuZWVkc1JlbW91bnQpIHtcbiAgICAgIGZpYmVyLl9kZWJ1Z05lZWRzUmVtb3VudCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKG5lZWRzUmVtb3VudCB8fCBuZWVkc1JlbmRlcikge1xuICAgICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGZpYmVyLCBTeW5jTGFuZSwgTm9UaW1lc3RhbXApO1xuICAgIH1cblxuICAgIGlmIChjaGlsZCAhPT0gbnVsbCAmJiAhbmVlZHNSZW1vdW50KSB7XG4gICAgICBzY2hlZHVsZUZpYmVyc1dpdGhGYW1pbGllc1JlY3Vyc2l2ZWx5KGNoaWxkLCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpO1xuICAgIH1cblxuICAgIGlmIChzaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZUZpYmVyc1dpdGhGYW1pbGllc1JlY3Vyc2l2ZWx5KHNpYmxpbmcsIHVwZGF0ZWRGYW1pbGllcywgc3RhbGVGYW1pbGllcyk7XG4gICAgfVxuICB9XG59XG5cbnZhciBmaW5kSG9zdEluc3RhbmNlc0ZvclJlZnJlc2ggPSBmdW5jdGlvbiAocm9vdCwgZmFtaWxpZXMpIHtcbiAge1xuICAgIHZhciBob3N0SW5zdGFuY2VzID0gbmV3IFNldCgpO1xuICAgIHZhciB0eXBlcyA9IG5ldyBTZXQoZmFtaWxpZXMubWFwKGZ1bmN0aW9uIChmYW1pbHkpIHtcbiAgICAgIHJldHVybiBmYW1pbHkuY3VycmVudDtcbiAgICB9KSk7XG4gICAgZmluZEhvc3RJbnN0YW5jZXNGb3JNYXRjaGluZ0ZpYmVyc1JlY3Vyc2l2ZWx5KHJvb3QuY3VycmVudCwgdHlwZXMsIGhvc3RJbnN0YW5jZXMpO1xuICAgIHJldHVybiBob3N0SW5zdGFuY2VzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBmaW5kSG9zdEluc3RhbmNlc0Zvck1hdGNoaW5nRmliZXJzUmVjdXJzaXZlbHkoZmliZXIsIHR5cGVzLCBob3N0SW5zdGFuY2VzKSB7XG4gIHtcbiAgICB2YXIgY2hpbGQgPSBmaWJlci5jaGlsZCxcbiAgICAgICAgc2libGluZyA9IGZpYmVyLnNpYmxpbmcsXG4gICAgICAgIHRhZyA9IGZpYmVyLnRhZyxcbiAgICAgICAgdHlwZSA9IGZpYmVyLnR5cGU7XG4gICAgdmFyIGNhbmRpZGF0ZVR5cGUgPSBudWxsO1xuXG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICBjYW5kaWRhdGVUeXBlID0gdHlwZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAgY2FuZGlkYXRlVHlwZSA9IHR5cGUucmVuZGVyO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZGlkTWF0Y2ggPSBmYWxzZTtcblxuICAgIGlmIChjYW5kaWRhdGVUeXBlICE9PSBudWxsKSB7XG4gICAgICBpZiAodHlwZXMuaGFzKGNhbmRpZGF0ZVR5cGUpKSB7XG4gICAgICAgIGRpZE1hdGNoID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGlkTWF0Y2gpIHtcbiAgICAgIC8vIFdlIGhhdmUgYSBtYXRjaC4gVGhpcyBvbmx5IGRyaWxscyBkb3duIHRvIHRoZSBjbG9zZXN0IGhvc3QgY29tcG9uZW50cy5cbiAgICAgIC8vIFRoZXJlJ3Mgbm8gbmVlZCB0byBzZWFyY2ggZGVlcGVyIGJlY2F1c2UgZm9yIHRoZSBwdXJwb3NlIG9mIGdpdmluZ1xuICAgICAgLy8gdmlzdWFsIGZlZWRiYWNrLCBcImZsYXNoaW5nXCIgb3V0ZXJtb3N0IHBhcmVudCByZWN0YW5nbGVzIGlzIHN1ZmZpY2llbnQuXG4gICAgICBmaW5kSG9zdEluc3RhbmNlc0ZvckZpYmVyU2hhbGxvd2x5KGZpYmVyLCBob3N0SW5zdGFuY2VzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgdGhlcmUncyBubyBtYXRjaCwgbWF5YmUgdGhlcmUgd2lsbCBiZSBvbmUgZnVydGhlciBkb3duIGluIHRoZSBjaGlsZCB0cmVlLlxuICAgICAgaWYgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgIGZpbmRIb3N0SW5zdGFuY2VzRm9yTWF0Y2hpbmdGaWJlcnNSZWN1cnNpdmVseShjaGlsZCwgdHlwZXMsIGhvc3RJbnN0YW5jZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICBmaW5kSG9zdEluc3RhbmNlc0Zvck1hdGNoaW5nRmliZXJzUmVjdXJzaXZlbHkoc2libGluZywgdHlwZXMsIGhvc3RJbnN0YW5jZXMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kSG9zdEluc3RhbmNlc0ZvckZpYmVyU2hhbGxvd2x5KGZpYmVyLCBob3N0SW5zdGFuY2VzKSB7XG4gIHtcbiAgICB2YXIgZm91bmRIb3N0SW5zdGFuY2VzID0gZmluZENoaWxkSG9zdEluc3RhbmNlc0ZvckZpYmVyU2hhbGxvd2x5KGZpYmVyLCBob3N0SW5zdGFuY2VzKTtcblxuICAgIGlmIChmb3VuZEhvc3RJbnN0YW5jZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIElmIHdlIGRpZG4ndCBmaW5kIGFueSBob3N0IGNoaWxkcmVuLCBmYWxsYmFjayB0byBjbG9zZXN0IGhvc3QgcGFyZW50LlxuXG5cbiAgICB2YXIgbm9kZSA9IGZpYmVyO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHN3aXRjaCAobm9kZS50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICAgIGhvc3RJbnN0YW5jZXMuYWRkKG5vZGUuc3RhdGVOb2RlKTtcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgICAgIGhvc3RJbnN0YW5jZXMuYWRkKG5vZGUuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8pO1xuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjYXNlIEhvc3RSb290OlxuICAgICAgICAgIGhvc3RJbnN0YW5jZXMuYWRkKG5vZGUuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gcmVhY2ggcm9vdCBmaXJzdC4nKTtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kQ2hpbGRIb3N0SW5zdGFuY2VzRm9yRmliZXJTaGFsbG93bHkoZmliZXIsIGhvc3RJbnN0YW5jZXMpIHtcbiAge1xuICAgIHZhciBub2RlID0gZmliZXI7XG4gICAgdmFyIGZvdW5kSG9zdEluc3RhbmNlcyA9IGZhbHNlO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChub2RlLnRhZyA9PT0gSG9zdENvbXBvbmVudCkge1xuICAgICAgICAvLyBXZSBnb3QgYSBtYXRjaC5cbiAgICAgICAgZm91bmRIb3N0SW5zdGFuY2VzID0gdHJ1ZTtcbiAgICAgICAgaG9zdEluc3RhbmNlcy5hZGQobm9kZS5zdGF0ZU5vZGUpOyAvLyBUaGVyZSBtYXkgc3RpbGwgYmUgbW9yZSwgc28ga2VlcCBzZWFyY2hpbmcuXG4gICAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbm9kZS5jaGlsZC5yZXR1cm4gPSBub2RlO1xuICAgICAgICBub2RlID0gbm9kZS5jaGlsZDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlID09PSBmaWJlcikge1xuICAgICAgICByZXR1cm4gZm91bmRIb3N0SW5zdGFuY2VzO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAobm9kZS5zaWJsaW5nID09PSBudWxsKSB7XG4gICAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBub2RlLnJldHVybiA9PT0gZmliZXIpIHtcbiAgICAgICAgICByZXR1cm4gZm91bmRIb3N0SW5zdGFuY2VzO1xuICAgICAgICB9XG5cbiAgICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxudmFyIGhhc0JhZE1hcFBvbHlmaWxsO1xuXG57XG4gIGhhc0JhZE1hcFBvbHlmaWxsID0gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgbm9uRXh0ZW5zaWJsZU9iamVjdCA9IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7fSk7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tbmV3ICovXG5cbiAgICBuZXcgTWFwKFtbbm9uRXh0ZW5zaWJsZU9iamVjdCwgbnVsbF1dKTtcbiAgICBuZXcgU2V0KFtub25FeHRlbnNpYmxlT2JqZWN0XSk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1uZXcgKi9cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIFRPRE86IENvbnNpZGVyIHdhcm5pbmcgYWJvdXQgYmFkIHBvbHlmaWxsc1xuICAgIGhhc0JhZE1hcFBvbHlmaWxsID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBGaWJlck5vZGUodGFnLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSkge1xuICAvLyBJbnN0YW5jZVxuICB0aGlzLnRhZyA9IHRhZztcbiAgdGhpcy5rZXkgPSBrZXk7XG4gIHRoaXMuZWxlbWVudFR5cGUgPSBudWxsO1xuICB0aGlzLnR5cGUgPSBudWxsO1xuICB0aGlzLnN0YXRlTm9kZSA9IG51bGw7IC8vIEZpYmVyXG5cbiAgdGhpcy5yZXR1cm4gPSBudWxsO1xuICB0aGlzLmNoaWxkID0gbnVsbDtcbiAgdGhpcy5zaWJsaW5nID0gbnVsbDtcbiAgdGhpcy5pbmRleCA9IDA7XG4gIHRoaXMucmVmID0gbnVsbDtcbiAgdGhpcy5wZW5kaW5nUHJvcHMgPSBwZW5kaW5nUHJvcHM7XG4gIHRoaXMubWVtb2l6ZWRQcm9wcyA9IG51bGw7XG4gIHRoaXMudXBkYXRlUXVldWUgPSBudWxsO1xuICB0aGlzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICB0aGlzLmRlcGVuZGVuY2llcyA9IG51bGw7XG4gIHRoaXMubW9kZSA9IG1vZGU7IC8vIEVmZmVjdHNcblxuICB0aGlzLmZsYWdzID0gTm9GbGFncztcbiAgdGhpcy5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICB0aGlzLmRlbGV0aW9ucyA9IG51bGw7XG4gIHRoaXMubGFuZXMgPSBOb0xhbmVzO1xuICB0aGlzLmNoaWxkTGFuZXMgPSBOb0xhbmVzO1xuICB0aGlzLmFsdGVybmF0ZSA9IG51bGw7XG5cbiAge1xuICAgIC8vIE5vdGU6IFRoZSBmb2xsb3dpbmcgaXMgZG9uZSB0byBhdm9pZCBhIHY4IHBlcmZvcm1hbmNlIGNsaWZmLlxuICAgIC8vXG4gICAgLy8gSW5pdGlhbGl6aW5nIHRoZSBmaWVsZHMgYmVsb3cgdG8gc21pcyBhbmQgbGF0ZXIgdXBkYXRpbmcgdGhlbSB3aXRoXG4gICAgLy8gZG91YmxlIHZhbHVlcyB3aWxsIGNhdXNlIEZpYmVycyB0byBlbmQgdXAgaGF2aW5nIHNlcGFyYXRlIHNoYXBlcy5cbiAgICAvLyBUaGlzIGJlaGF2aW9yL2J1ZyBoYXMgc29tZXRoaW5nIHRvIGRvIHdpdGggT2JqZWN0LnByZXZlbnRFeHRlbnNpb24oKS5cbiAgICAvLyBGb3J0dW5hdGVseSB0aGlzIG9ubHkgaW1wYWN0cyBERVYgYnVpbGRzLlxuICAgIC8vIFVuZm9ydHVuYXRlbHkgaXQgbWFrZXMgUmVhY3QgdW51c2FibHkgc2xvdyBmb3Igc29tZSBhcHBsaWNhdGlvbnMuXG4gICAgLy8gVG8gd29yayBhcm91bmQgdGhpcywgaW5pdGlhbGl6ZSB0aGUgZmllbGRzIGJlbG93IHdpdGggZG91Ymxlcy5cbiAgICAvL1xuICAgIC8vIExlYXJuIG1vcmUgYWJvdXQgdGhpcyBoZXJlOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTQzNjVcbiAgICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD04NTM4XG4gICAgdGhpcy5hY3R1YWxEdXJhdGlvbiA9IE51bWJlci5OYU47XG4gICAgdGhpcy5hY3R1YWxTdGFydFRpbWUgPSBOdW1iZXIuTmFOO1xuICAgIHRoaXMuc2VsZkJhc2VEdXJhdGlvbiA9IE51bWJlci5OYU47XG4gICAgdGhpcy50cmVlQmFzZUR1cmF0aW9uID0gTnVtYmVyLk5hTjsgLy8gSXQncyBva2F5IHRvIHJlcGxhY2UgdGhlIGluaXRpYWwgZG91YmxlcyB3aXRoIHNtaXMgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXG4gICAgLy8gVGhpcyB3b24ndCB0cmlnZ2VyIHRoZSBwZXJmb3JtYW5jZSBjbGlmZiBtZW50aW9uZWQgYWJvdmUsXG4gICAgLy8gYW5kIGl0IHNpbXBsaWZpZXMgb3RoZXIgcHJvZmlsZXIgY29kZSAoaW5jbHVkaW5nIERldlRvb2xzKS5cblxuICAgIHRoaXMuYWN0dWFsRHVyYXRpb24gPSAwO1xuICAgIHRoaXMuYWN0dWFsU3RhcnRUaW1lID0gLTE7XG4gICAgdGhpcy5zZWxmQmFzZUR1cmF0aW9uID0gMDtcbiAgICB0aGlzLnRyZWVCYXNlRHVyYXRpb24gPSAwO1xuICB9XG5cbiAge1xuICAgIC8vIFRoaXMgaXNuJ3QgZGlyZWN0bHkgdXNlZCBidXQgaXMgaGFuZHkgZm9yIGRlYnVnZ2luZyBpbnRlcm5hbHM6XG4gICAgdGhpcy5fZGVidWdTb3VyY2UgPSBudWxsO1xuICAgIHRoaXMuX2RlYnVnT3duZXIgPSBudWxsO1xuICAgIHRoaXMuX2RlYnVnTmVlZHNSZW1vdW50ID0gZmFsc2U7XG4gICAgdGhpcy5fZGVidWdIb29rVHlwZXMgPSBudWxsO1xuXG4gICAgaWYgKCFoYXNCYWRNYXBQb2x5ZmlsbCAmJiB0eXBlb2YgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBPYmplY3QucHJldmVudEV4dGVuc2lvbnModGhpcyk7XG4gICAgfVxuICB9XG59IC8vIFRoaXMgaXMgYSBjb25zdHJ1Y3RvciBmdW5jdGlvbiwgcmF0aGVyIHRoYW4gYSBQT0pPIGNvbnN0cnVjdG9yLCBzdGlsbFxuLy8gcGxlYXNlIGVuc3VyZSB3ZSBkbyB0aGUgZm9sbG93aW5nOlxuLy8gMSkgTm9ib2R5IHNob3VsZCBhZGQgYW55IGluc3RhbmNlIG1ldGhvZHMgb24gdGhpcy4gSW5zdGFuY2UgbWV0aG9kcyBjYW4gYmVcbi8vICAgIG1vcmUgZGlmZmljdWx0IHRvIHByZWRpY3Qgd2hlbiB0aGV5IGdldCBvcHRpbWl6ZWQgYW5kIHRoZXkgYXJlIGFsbW9zdFxuLy8gICAgbmV2ZXIgaW5saW5lZCBwcm9wZXJseSBpbiBzdGF0aWMgY29tcGlsZXJzLlxuLy8gMikgTm9ib2R5IHNob3VsZCByZWx5IG9uIGBpbnN0YW5jZW9mIEZpYmVyYCBmb3IgdHlwZSB0ZXN0aW5nLiBXZSBzaG91bGRcbi8vICAgIGFsd2F5cyBrbm93IHdoZW4gaXQgaXMgYSBmaWJlci5cbi8vIDMpIFdlIG1pZ2h0IHdhbnQgdG8gZXhwZXJpbWVudCB3aXRoIHVzaW5nIG51bWVyaWMga2V5cyBzaW5jZSB0aGV5IGFyZSBlYXNpZXJcbi8vICAgIHRvIG9wdGltaXplIGluIGEgbm9uLUpJVCBlbnZpcm9ubWVudC5cbi8vIDQpIFdlIGNhbiBlYXNpbHkgZ28gZnJvbSBhIGNvbnN0cnVjdG9yIHRvIGEgY3JlYXRlRmliZXIgb2JqZWN0IGxpdGVyYWwgaWYgdGhhdFxuLy8gICAgaXMgZmFzdGVyLlxuLy8gNSkgSXQgc2hvdWxkIGJlIGVhc3kgdG8gcG9ydCB0aGlzIHRvIGEgQyBzdHJ1Y3QgYW5kIGtlZXAgYSBDIGltcGxlbWVudGF0aW9uXG4vLyAgICBjb21wYXRpYmxlLlxuXG5cbnZhciBjcmVhdGVGaWJlciA9IGZ1bmN0aW9uICh0YWcsIHBlbmRpbmdQcm9wcywga2V5LCBtb2RlKSB7XG4gIC8vICRGbG93Rml4TWU6IHRoZSBzaGFwZXMgYXJlIGV4YWN0IGhlcmUgYnV0IEZsb3cgZG9lc24ndCBsaWtlIGNvbnN0cnVjdG9yc1xuICByZXR1cm4gbmV3IEZpYmVyTm9kZSh0YWcsIHBlbmRpbmdQcm9wcywga2V5LCBtb2RlKTtcbn07XG5cbmZ1bmN0aW9uIHNob3VsZENvbnN0cnVjdCQxKENvbXBvbmVudCkge1xuICB2YXIgcHJvdG90eXBlID0gQ29tcG9uZW50LnByb3RvdHlwZTtcbiAgcmV0dXJuICEhKHByb3RvdHlwZSAmJiBwcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudCk7XG59XG5cbmZ1bmN0aW9uIGlzU2ltcGxlRnVuY3Rpb25Db21wb25lbnQodHlwZSkge1xuICByZXR1cm4gdHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicgJiYgIXNob3VsZENvbnN0cnVjdCQxKHR5cGUpICYmIHR5cGUuZGVmYXVsdFByb3BzID09PSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiByZXNvbHZlTGF6eUNvbXBvbmVudFRhZyhDb21wb25lbnQpIHtcbiAgaWYgKHR5cGVvZiBDb21wb25lbnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gc2hvdWxkQ29uc3RydWN0JDEoQ29tcG9uZW50KSA/IENsYXNzQ29tcG9uZW50IDogRnVuY3Rpb25Db21wb25lbnQ7XG4gIH0gZWxzZSBpZiAoQ29tcG9uZW50ICE9PSB1bmRlZmluZWQgJiYgQ29tcG9uZW50ICE9PSBudWxsKSB7XG4gICAgdmFyICQkdHlwZW9mID0gQ29tcG9uZW50LiQkdHlwZW9mO1xuXG4gICAgaWYgKCQkdHlwZW9mID09PSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFKSB7XG4gICAgICByZXR1cm4gRm9yd2FyZFJlZjtcbiAgICB9XG5cbiAgICBpZiAoJCR0eXBlb2YgPT09IFJFQUNUX01FTU9fVFlQRSkge1xuICAgICAgcmV0dXJuIE1lbW9Db21wb25lbnQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEluZGV0ZXJtaW5hdGVDb21wb25lbnQ7XG59IC8vIFRoaXMgaXMgdXNlZCB0byBjcmVhdGUgYW4gYWx0ZXJuYXRlIGZpYmVyIHRvIGRvIHdvcmsgb24uXG5cbmZ1bmN0aW9uIGNyZWF0ZVdvcmtJblByb2dyZXNzKGN1cnJlbnQsIHBlbmRpbmdQcm9wcykge1xuICB2YXIgd29ya0luUHJvZ3Jlc3MgPSBjdXJyZW50LmFsdGVybmF0ZTtcblxuICBpZiAod29ya0luUHJvZ3Jlc3MgPT09IG51bGwpIHtcbiAgICAvLyBXZSB1c2UgYSBkb3VibGUgYnVmZmVyaW5nIHBvb2xpbmcgdGVjaG5pcXVlIGJlY2F1c2Ugd2Uga25vdyB0aGF0IHdlJ2xsXG4gICAgLy8gb25seSBldmVyIG5lZWQgYXQgbW9zdCB0d28gdmVyc2lvbnMgb2YgYSB0cmVlLiBXZSBwb29sIHRoZSBcIm90aGVyXCIgdW51c2VkXG4gICAgLy8gbm9kZSB0aGF0IHdlJ3JlIGZyZWUgdG8gcmV1c2UuIFRoaXMgaXMgbGF6aWx5IGNyZWF0ZWQgdG8gYXZvaWQgYWxsb2NhdGluZ1xuICAgIC8vIGV4dHJhIG9iamVjdHMgZm9yIHRoaW5ncyB0aGF0IGFyZSBuZXZlciB1cGRhdGVkLiBJdCBhbHNvIGFsbG93IHVzIHRvXG4gICAgLy8gcmVjbGFpbSB0aGUgZXh0cmEgbWVtb3J5IGlmIG5lZWRlZC5cbiAgICB3b3JrSW5Qcm9ncmVzcyA9IGNyZWF0ZUZpYmVyKGN1cnJlbnQudGFnLCBwZW5kaW5nUHJvcHMsIGN1cnJlbnQua2V5LCBjdXJyZW50Lm1vZGUpO1xuICAgIHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlID0gY3VycmVudC5lbGVtZW50VHlwZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gY3VycmVudC50eXBlO1xuICAgIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSA9IGN1cnJlbnQuc3RhdGVOb2RlO1xuXG4gICAge1xuICAgICAgLy8gREVWLW9ubHkgZmllbGRzXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5fZGVidWdTb3VyY2UgPSBjdXJyZW50Ll9kZWJ1Z1NvdXJjZTtcbiAgICAgIHdvcmtJblByb2dyZXNzLl9kZWJ1Z093bmVyID0gY3VycmVudC5fZGVidWdPd25lcjtcbiAgICAgIHdvcmtJblByb2dyZXNzLl9kZWJ1Z0hvb2tUeXBlcyA9IGN1cnJlbnQuX2RlYnVnSG9va1R5cGVzO1xuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzLmFsdGVybmF0ZSA9IGN1cnJlbnQ7XG4gICAgY3VycmVudC5hbHRlcm5hdGUgPSB3b3JrSW5Qcm9ncmVzcztcbiAgfSBlbHNlIHtcbiAgICB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHMgPSBwZW5kaW5nUHJvcHM7IC8vIE5lZWRlZCBiZWNhdXNlIEJsb2NrcyBzdG9yZSBkYXRhIG9uIHR5cGUuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gY3VycmVudC50eXBlOyAvLyBXZSBhbHJlYWR5IGhhdmUgYW4gYWx0ZXJuYXRlLlxuICAgIC8vIFJlc2V0IHRoZSBlZmZlY3QgdGFnLlxuXG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgPSBOb0ZsYWdzOyAvLyBUaGUgZWZmZWN0cyBhcmUgbm8gbG9uZ2VyIHZhbGlkLlxuXG4gICAgd29ya0luUHJvZ3Jlc3Muc3VidHJlZUZsYWdzID0gTm9GbGFncztcbiAgICB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnMgPSBudWxsO1xuXG4gICAge1xuICAgICAgLy8gV2UgaW50ZW50aW9uYWxseSByZXNldCwgcmF0aGVyIHRoYW4gY29weSwgYWN0dWFsRHVyYXRpb24gJiBhY3R1YWxTdGFydFRpbWUuXG4gICAgICAvLyBUaGlzIHByZXZlbnRzIHRpbWUgZnJvbSBlbmRsZXNzbHkgYWNjdW11bGF0aW5nIGluIG5ldyBjb21taXRzLlxuICAgICAgLy8gVGhpcyBoYXMgdGhlIGRvd25zaWRlIG9mIHJlc2V0dGluZyB2YWx1ZXMgZm9yIGRpZmZlcmVudCBwcmlvcml0eSByZW5kZXJzLFxuICAgICAgLy8gQnV0IHdvcmtzIGZvciB5aWVsZGluZyAodGhlIGNvbW1vbiBjYXNlKSBhbmQgc2hvdWxkIHN1cHBvcnQgcmVzdW1pbmcuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICB9XG4gIH0gLy8gUmVzZXQgYWxsIGVmZmVjdHMgZXhjZXB0IHN0YXRpYyBvbmVzLlxuICAvLyBTdGF0aWMgZWZmZWN0cyBhcmUgbm90IHNwZWNpZmljIHRvIGEgcmVuZGVyLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgPSBjdXJyZW50LmZsYWdzICYgU3RhdGljTWFzaztcbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGRMYW5lcyA9IGN1cnJlbnQuY2hpbGRMYW5lcztcbiAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBjdXJyZW50LmxhbmVzO1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7XG4gIHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG4gIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTsgLy8gQ2xvbmUgdGhlIGRlcGVuZGVuY2llcyBvYmplY3QuIFRoaXMgaXMgbXV0YXRlZCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZSwgc29cbiAgLy8gaXQgY2Fubm90IGJlIHNoYXJlZCB3aXRoIHRoZSBjdXJyZW50IGZpYmVyLlxuXG4gIHZhciBjdXJyZW50RGVwZW5kZW5jaWVzID0gY3VycmVudC5kZXBlbmRlbmNpZXM7XG4gIHdvcmtJblByb2dyZXNzLmRlcGVuZGVuY2llcyA9IGN1cnJlbnREZXBlbmRlbmNpZXMgPT09IG51bGwgPyBudWxsIDoge1xuICAgIGxhbmVzOiBjdXJyZW50RGVwZW5kZW5jaWVzLmxhbmVzLFxuICAgIGZpcnN0Q29udGV4dDogY3VycmVudERlcGVuZGVuY2llcy5maXJzdENvbnRleHRcbiAgfTsgLy8gVGhlc2Ugd2lsbCBiZSBvdmVycmlkZGVuIGR1cmluZyB0aGUgcGFyZW50J3MgcmVjb25jaWxpYXRpb25cblxuICB3b3JrSW5Qcm9ncmVzcy5zaWJsaW5nID0gY3VycmVudC5zaWJsaW5nO1xuICB3b3JrSW5Qcm9ncmVzcy5pbmRleCA9IGN1cnJlbnQuaW5kZXg7XG4gIHdvcmtJblByb2dyZXNzLnJlZiA9IGN1cnJlbnQucmVmO1xuXG4gIHtcbiAgICB3b3JrSW5Qcm9ncmVzcy5zZWxmQmFzZUR1cmF0aW9uID0gY3VycmVudC5zZWxmQmFzZUR1cmF0aW9uO1xuICAgIHdvcmtJblByb2dyZXNzLnRyZWVCYXNlRHVyYXRpb24gPSBjdXJyZW50LnRyZWVCYXNlRHVyYXRpb247XG4gIH1cblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3MuX2RlYnVnTmVlZHNSZW1vdW50ID0gY3VycmVudC5fZGVidWdOZWVkc1JlbW91bnQ7XG5cbiAgICBzd2l0Y2ggKHdvcmtJblByb2dyZXNzLnRhZykge1xuICAgICAgY2FzZSBJbmRldGVybWluYXRlQ29tcG9uZW50OlxuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyhjdXJyZW50LnR5cGUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyhjdXJyZW50LnR5cGUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gcmVzb2x2ZUZvcndhcmRSZWZGb3JIb3RSZWxvYWRpbmcoY3VycmVudC50eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzO1xufSAvLyBVc2VkIHRvIHJldXNlIGEgRmliZXIgZm9yIGEgc2Vjb25kIHBhc3MuXG5cbmZ1bmN0aW9uIHJlc2V0V29ya0luUHJvZ3Jlc3Mod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoaXMgcmVzZXRzIHRoZSBGaWJlciB0byB3aGF0IGNyZWF0ZUZpYmVyIG9yIGNyZWF0ZVdvcmtJblByb2dyZXNzIHdvdWxkXG4gIC8vIGhhdmUgc2V0IHRoZSB2YWx1ZXMgdG8gYmVmb3JlIGR1cmluZyB0aGUgZmlyc3QgcGFzcy4gSWRlYWxseSB0aGlzIHdvdWxkbid0XG4gIC8vIGJlIG5lY2Vzc2FyeSBidXQgdW5mb3J0dW5hdGVseSBtYW55IGNvZGUgcGF0aHMgcmVhZHMgZnJvbSB0aGUgd29ya0luUHJvZ3Jlc3NcbiAgLy8gd2hlbiB0aGV5IHNob3VsZCBiZSByZWFkaW5nIGZyb20gY3VycmVudCBhbmQgd3JpdGluZyB0byB3b3JrSW5Qcm9ncmVzcy5cbiAgLy8gV2UgYXNzdW1lIHBlbmRpbmdQcm9wcywgaW5kZXgsIGtleSwgcmVmLCByZXR1cm4gYXJlIHN0aWxsIHVudG91Y2hlZCB0b1xuICAvLyBhdm9pZCBkb2luZyBhbm90aGVyIHJlY29uY2lsaWF0aW9uLlxuICAvLyBSZXNldCB0aGUgZWZmZWN0IGZsYWdzIGJ1dCBrZWVwIGFueSBQbGFjZW1lbnQgdGFncywgc2luY2UgdGhhdCdzIHNvbWV0aGluZ1xuICAvLyB0aGF0IGNoaWxkIGZpYmVyIGlzIHNldHRpbmcsIG5vdCB0aGUgcmVjb25jaWxpYXRpb24uXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzICY9IFN0YXRpY01hc2sgfCBQbGFjZW1lbnQ7IC8vIFRoZSBlZmZlY3RzIGFyZSBubyBsb25nZXIgdmFsaWQuXG5cbiAgdmFyIGN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGU7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAvLyBSZXNldCB0byBjcmVhdGVGaWJlcidzIGluaXRpYWwgdmFsdWVzLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMgPSBOb0xhbmVzO1xuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gcmVuZGVyTGFuZXM7XG4gICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLnN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcyA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLmRlcGVuZGVuY2llcyA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID0gbnVsbDtcblxuICAgIHtcbiAgICAgIC8vIE5vdGU6IFdlIGRvbid0IHJlc2V0IHRoZSBhY3R1YWxUaW1lIGNvdW50cy4gSXQncyB1c2VmdWwgdG8gYWNjdW11bGF0ZVxuICAgICAgLy8gYWN0dWFsIHRpbWUgYWNyb3NzIG11bHRpcGxlIHJlbmRlciBwYXNzZXMuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5zZWxmQmFzZUR1cmF0aW9uID0gMDtcbiAgICAgIHdvcmtJblByb2dyZXNzLnRyZWVCYXNlRHVyYXRpb24gPSAwO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBSZXNldCB0byB0aGUgY2xvbmVkIHZhbHVlcyB0aGF0IGNyZWF0ZVdvcmtJblByb2dyZXNzIHdvdWxkJ3ZlLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMgPSBjdXJyZW50LmNoaWxkTGFuZXM7XG4gICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBjdXJyZW50LmxhbmVzO1xuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gY3VycmVudC5jaGlsZDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgIHdvcmtJblByb2dyZXNzLmRlbGV0aW9ucyA9IG51bGw7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcyA9IGN1cnJlbnQubWVtb2l6ZWRQcm9wcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTsgLy8gTmVlZGVkIGJlY2F1c2UgQmxvY2tzIHN0b3JlIGRhdGEgb24gdHlwZS5cblxuICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSBjdXJyZW50LnR5cGU7IC8vIENsb25lIHRoZSBkZXBlbmRlbmNpZXMgb2JqZWN0LiBUaGlzIGlzIG11dGF0ZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UsIHNvXG4gICAgLy8gaXQgY2Fubm90IGJlIHNoYXJlZCB3aXRoIHRoZSBjdXJyZW50IGZpYmVyLlxuXG4gICAgdmFyIGN1cnJlbnREZXBlbmRlbmNpZXMgPSBjdXJyZW50LmRlcGVuZGVuY2llcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5kZXBlbmRlbmNpZXMgPSBjdXJyZW50RGVwZW5kZW5jaWVzID09PSBudWxsID8gbnVsbCA6IHtcbiAgICAgIGxhbmVzOiBjdXJyZW50RGVwZW5kZW5jaWVzLmxhbmVzLFxuICAgICAgZmlyc3RDb250ZXh0OiBjdXJyZW50RGVwZW5kZW5jaWVzLmZpcnN0Q29udGV4dFxuICAgIH07XG5cbiAgICB7XG4gICAgICAvLyBOb3RlOiBXZSBkb24ndCByZXNldCB0aGUgYWN0dWFsVGltZSBjb3VudHMuIEl0J3MgdXNlZnVsIHRvIGFjY3VtdWxhdGVcbiAgICAgIC8vIGFjdHVhbCB0aW1lIGFjcm9zcyBtdWx0aXBsZSByZW5kZXIgcGFzc2VzLlxuICAgICAgd29ya0luUHJvZ3Jlc3Muc2VsZkJhc2VEdXJhdGlvbiA9IGN1cnJlbnQuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICAgIHdvcmtJblByb2dyZXNzLnRyZWVCYXNlRHVyYXRpb24gPSBjdXJyZW50LnRyZWVCYXNlRHVyYXRpb247XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzO1xufVxuZnVuY3Rpb24gY3JlYXRlSG9zdFJvb3RGaWJlcih0YWcsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSkge1xuICB2YXIgbW9kZTtcblxuICBpZiAodGFnID09PSBDb25jdXJyZW50Um9vdCkge1xuICAgIG1vZGUgPSBDb25jdXJyZW50TW9kZTtcblxuICAgIGlmIChpc1N0cmljdE1vZGUgPT09IHRydWUpIHtcbiAgICAgIG1vZGUgfD0gU3RyaWN0TGVnYWN5TW9kZTtcblxuICAgICAge1xuICAgICAgICBtb2RlIHw9IFN0cmljdEVmZmVjdHNNb2RlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBtb2RlID0gTm9Nb2RlO1xuICB9XG5cbiAgaWYgKCBpc0RldlRvb2xzUHJlc2VudCkge1xuICAgIC8vIEFsd2F5cyBjb2xsZWN0IHByb2ZpbGUgdGltaW5ncyB3aGVuIERldlRvb2xzIGFyZSBwcmVzZW50LlxuICAgIC8vIFRoaXMgZW5hYmxlcyBEZXZUb29scyB0byBzdGFydCBjYXB0dXJpbmcgdGltaW5nIGF0IGFueSBwb2ludFx1MjAxM1xuICAgIC8vIFdpdGhvdXQgc29tZSBub2RlcyBpbiB0aGUgdHJlZSBoYXZpbmcgZW1wdHkgYmFzZSB0aW1lcy5cbiAgICBtb2RlIHw9IFByb2ZpbGVNb2RlO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUZpYmVyKEhvc3RSb290LCBudWxsLCBudWxsLCBtb2RlKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVR5cGVBbmRQcm9wcyh0eXBlLCAvLyBSZWFjdCRFbGVtZW50VHlwZVxua2V5LCBwZW5kaW5nUHJvcHMsIG93bmVyLCBtb2RlLCBsYW5lcykge1xuICB2YXIgZmliZXJUYWcgPSBJbmRldGVybWluYXRlQ29tcG9uZW50OyAvLyBUaGUgcmVzb2x2ZWQgdHlwZSBpcyBzZXQgaWYgd2Uga25vdyB3aGF0IHRoZSBmaW5hbCB0eXBlIHdpbGwgYmUuIEkuZS4gaXQncyBub3QgbGF6eS5cblxuICB2YXIgcmVzb2x2ZWRUeXBlID0gdHlwZTtcblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoc2hvdWxkQ29uc3RydWN0JDEodHlwZSkpIHtcbiAgICAgIGZpYmVyVGFnID0gQ2xhc3NDb21wb25lbnQ7XG5cbiAgICAgIHtcbiAgICAgICAgcmVzb2x2ZWRUeXBlID0gcmVzb2x2ZUNsYXNzRm9ySG90UmVsb2FkaW5nKHJlc29sdmVkVHlwZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHtcbiAgICAgICAgcmVzb2x2ZWRUeXBlID0gcmVzb2x2ZUZ1bmN0aW9uRm9ySG90UmVsb2FkaW5nKHJlc29sdmVkVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIGZpYmVyVGFnID0gSG9zdENvbXBvbmVudDtcbiAgfSBlbHNlIHtcbiAgICBnZXRUYWc6IHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBSRUFDVF9GUkFHTUVOVF9UWVBFOlxuICAgICAgICByZXR1cm4gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQocGVuZGluZ1Byb3BzLmNoaWxkcmVuLCBtb2RlLCBsYW5lcywga2V5KTtcblxuICAgICAgY2FzZSBSRUFDVF9TVFJJQ1RfTU9ERV9UWVBFOlxuICAgICAgICBmaWJlclRhZyA9IE1vZGU7XG4gICAgICAgIG1vZGUgfD0gU3RyaWN0TGVnYWN5TW9kZTtcblxuICAgICAgICBpZiAoIChtb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAvLyBTdHJpY3QgZWZmZWN0cyBzaG91bGQgbmV2ZXIgcnVuIG9uIGxlZ2FjeSByb290c1xuICAgICAgICAgIG1vZGUgfD0gU3RyaWN0RWZmZWN0c01vZGU7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBSRUFDVF9QUk9GSUxFUl9UWVBFOlxuICAgICAgICByZXR1cm4gY3JlYXRlRmliZXJGcm9tUHJvZmlsZXIocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KTtcblxuICAgICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9UWVBFOlxuICAgICAgICByZXR1cm4gY3JlYXRlRmliZXJGcm9tU3VzcGVuc2UocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KTtcblxuICAgICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEU6XG4gICAgICAgIHJldHVybiBjcmVhdGVGaWJlckZyb21TdXNwZW5zZUxpc3QocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KTtcblxuICAgICAgY2FzZSBSRUFDVF9PRkZTQ1JFRU5fVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbU9mZnNjcmVlbihwZW5kaW5nUHJvcHMsIG1vZGUsIGxhbmVzLCBrZXkpO1xuXG4gICAgICBjYXNlIFJFQUNUX0xFR0FDWV9ISURERU5fVFlQRTpcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICAgIGNhc2UgUkVBQ1RfU0NPUEVfVFlQRTpcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICAgIGNhc2UgUkVBQ1RfQ0FDSEVfVFlQRTpcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICAgIGNhc2UgUkVBQ1RfVFJBQ0lOR19NQVJLRVJfVFlQRTpcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICAgIGNhc2UgUkVBQ1RfREVCVUdfVFJBQ0lOR19NT0RFX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgICAgICAgICAgY2FzZSBSRUFDVF9QUk9WSURFUl9UWVBFOlxuICAgICAgICAgICAgICAgIGZpYmVyVGFnID0gQ29udGV4dFByb3ZpZGVyO1xuICAgICAgICAgICAgICAgIGJyZWFrIGdldFRhZztcblxuICAgICAgICAgICAgICBjYXNlIFJFQUNUX0NPTlRFWFRfVFlQRTpcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgY29uc3VtZXJcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IENvbnRleHRDb25zdW1lcjtcbiAgICAgICAgICAgICAgICBicmVhayBnZXRUYWc7XG5cbiAgICAgICAgICAgICAgY2FzZSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFOlxuICAgICAgICAgICAgICAgIGZpYmVyVGFnID0gRm9yd2FyZFJlZjtcblxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVGb3J3YXJkUmVmRm9ySG90UmVsb2FkaW5nKHJlc29sdmVkVHlwZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWsgZ2V0VGFnO1xuXG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICAgICAgICAgIGZpYmVyVGFnID0gTWVtb0NvbXBvbmVudDtcbiAgICAgICAgICAgICAgICBicmVhayBnZXRUYWc7XG5cbiAgICAgICAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAgICAgICAgZmliZXJUYWcgPSBMYXp5Q29tcG9uZW50O1xuICAgICAgICAgICAgICAgIHJlc29sdmVkVHlwZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgYnJlYWsgZ2V0VGFnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBpbmZvID0gJyc7XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsICYmIE9iamVjdC5rZXlzKHR5cGUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICBpbmZvICs9ICcgWW91IGxpa2VseSBmb3Jnb3QgdG8gZXhwb3J0IHlvdXIgY29tcG9uZW50IGZyb20gdGhlIGZpbGUgJyArIFwiaXQncyBkZWZpbmVkIGluLCBvciB5b3UgbWlnaHQgaGF2ZSBtaXhlZCB1cCBkZWZhdWx0IGFuZCBcIiArICduYW1lZCBpbXBvcnRzLic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBvd25lck5hbWUgPSBvd25lciA/IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIob3duZXIpIDogbnVsbDtcblxuICAgICAgICAgICAgaWYgKG93bmVyTmFtZSkge1xuICAgICAgICAgICAgICBpbmZvICs9ICdcXG5cXG5DaGVjayB0aGUgcmVuZGVyIG1ldGhvZCBvZiBgJyArIG93bmVyTmFtZSArICdgLic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbGVtZW50IHR5cGUgaXMgaW52YWxpZDogZXhwZWN0ZWQgYSBzdHJpbmcgKGZvciBidWlsdC1pbiAnICsgJ2NvbXBvbmVudHMpIG9yIGEgY2xhc3MvZnVuY3Rpb24gKGZvciBjb21wb3NpdGUgY29tcG9uZW50cykgJyArIChcImJ1dCBnb3Q6IFwiICsgKHR5cGUgPT0gbnVsbCA/IHR5cGUgOiB0eXBlb2YgdHlwZSkgKyBcIi5cIiArIGluZm8pKTtcbiAgICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKGZpYmVyVGFnLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSk7XG4gIGZpYmVyLmVsZW1lbnRUeXBlID0gdHlwZTtcbiAgZmliZXIudHlwZSA9IHJlc29sdmVkVHlwZTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcblxuICB7XG4gICAgZmliZXIuX2RlYnVnT3duZXIgPSBvd25lcjtcbiAgfVxuXG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbUVsZW1lbnQoZWxlbWVudCwgbW9kZSwgbGFuZXMpIHtcbiAgdmFyIG93bmVyID0gbnVsbDtcblxuICB7XG4gICAgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgfVxuXG4gIHZhciB0eXBlID0gZWxlbWVudC50eXBlO1xuICB2YXIga2V5ID0gZWxlbWVudC5rZXk7XG4gIHZhciBwZW5kaW5nUHJvcHMgPSBlbGVtZW50LnByb3BzO1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlckZyb21UeXBlQW5kUHJvcHModHlwZSwga2V5LCBwZW5kaW5nUHJvcHMsIG93bmVyLCBtb2RlLCBsYW5lcyk7XG5cbiAge1xuICAgIGZpYmVyLl9kZWJ1Z1NvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcbiAgICBmaWJlci5fZGVidWdPd25lciA9IGVsZW1lbnQuX293bmVyO1xuICB9XG5cbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZWxlbWVudHMsIG1vZGUsIGxhbmVzLCBrZXkpIHtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoRnJhZ21lbnQsIGVsZW1lbnRzLCBrZXksIG1vZGUpO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuICByZXR1cm4gZmliZXI7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVByb2ZpbGVyKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSkge1xuICB7XG4gICAgaWYgKHR5cGVvZiBwZW5kaW5nUHJvcHMuaWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnJvcignUHJvZmlsZXIgbXVzdCBzcGVjaWZ5IGFuIFwiaWRcIiBvZiB0eXBlIGBzdHJpbmdgIGFzIGEgcHJvcC4gUmVjZWl2ZWQgdGhlIHR5cGUgYCVzYCBpbnN0ZWFkLicsIHR5cGVvZiBwZW5kaW5nUHJvcHMuaWQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKFByb2ZpbGVyLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSB8IFByb2ZpbGVNb2RlKTtcbiAgZmliZXIuZWxlbWVudFR5cGUgPSBSRUFDVF9QUk9GSUxFUl9UWVBFO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuXG4gIHtcbiAgICBmaWJlci5zdGF0ZU5vZGUgPSB7XG4gICAgICBlZmZlY3REdXJhdGlvbjogMCxcbiAgICAgIHBhc3NpdmVFZmZlY3REdXJhdGlvbjogMFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gZmliZXI7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVN1c3BlbnNlKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSkge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihTdXNwZW5zZUNvbXBvbmVudCwgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9IFJFQUNUX1NVU1BFTlNFX1RZUEU7XG4gIGZpYmVyLmxhbmVzID0gbGFuZXM7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVN1c3BlbnNlTGlzdChwZW5kaW5nUHJvcHMsIG1vZGUsIGxhbmVzLCBrZXkpIHtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoU3VzcGVuc2VMaXN0Q29tcG9uZW50LCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSk7XG4gIGZpYmVyLmVsZW1lbnRUeXBlID0gUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21PZmZzY3JlZW4ocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKE9mZnNjcmVlbkNvbXBvbmVudCwgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9IFJFQUNUX09GRlNDUkVFTl9UWVBFO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuICB2YXIgcHJpbWFyeUNoaWxkSW5zdGFuY2UgPSB7fTtcbiAgZmliZXIuc3RhdGVOb2RlID0gcHJpbWFyeUNoaWxkSW5zdGFuY2U7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVRleHQoY29udGVudCwgbW9kZSwgbGFuZXMpIHtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoSG9zdFRleHQsIGNvbnRlbnQsIG51bGwsIG1vZGUpO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21Ib3N0SW5zdGFuY2VGb3JEZWxldGlvbigpIHtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoSG9zdENvbXBvbmVudCwgbnVsbCwgbnVsbCwgTm9Nb2RlKTtcbiAgZmliZXIuZWxlbWVudFR5cGUgPSAnREVMRVRFRCc7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbURlaHlkcmF0ZWRGcmFnbWVudChkZWh5ZHJhdGVkTm9kZSkge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihEZWh5ZHJhdGVkRnJhZ21lbnQsIG51bGwsIG51bGwsIE5vTW9kZSk7XG4gIGZpYmVyLnN0YXRlTm9kZSA9IGRlaHlkcmF0ZWROb2RlO1xuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21Qb3J0YWwocG9ydGFsLCBtb2RlLCBsYW5lcykge1xuICB2YXIgcGVuZGluZ1Byb3BzID0gcG9ydGFsLmNoaWxkcmVuICE9PSBudWxsID8gcG9ydGFsLmNoaWxkcmVuIDogW107XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKEhvc3RQb3J0YWwsIHBlbmRpbmdQcm9wcywgcG9ydGFsLmtleSwgbW9kZSk7XG4gIGZpYmVyLmxhbmVzID0gbGFuZXM7XG4gIGZpYmVyLnN0YXRlTm9kZSA9IHtcbiAgICBjb250YWluZXJJbmZvOiBwb3J0YWwuY29udGFpbmVySW5mbyxcbiAgICBwZW5kaW5nQ2hpbGRyZW46IG51bGwsXG4gICAgLy8gVXNlZCBieSBwZXJzaXN0ZW50IHVwZGF0ZXNcbiAgICBpbXBsZW1lbnRhdGlvbjogcG9ydGFsLmltcGxlbWVudGF0aW9uXG4gIH07XG4gIHJldHVybiBmaWJlcjtcbn0gLy8gVXNlZCBmb3Igc3Rhc2hpbmcgV0lQIHByb3BlcnRpZXMgdG8gcmVwbGF5IGZhaWxlZCB3b3JrIGluIERFVi5cblxuZnVuY3Rpb24gYXNzaWduRmliZXJQcm9wZXJ0aWVzSW5ERVYodGFyZ2V0LCBzb3VyY2UpIHtcbiAgaWYgKHRhcmdldCA9PT0gbnVsbCkge1xuICAgIC8vIFRoaXMgRmliZXIncyBpbml0aWFsIHByb3BlcnRpZXMgd2lsbCBhbHdheXMgYmUgb3ZlcndyaXR0ZW4uXG4gICAgLy8gV2Ugb25seSB1c2UgYSBGaWJlciB0byBlbnN1cmUgdGhlIHNhbWUgaGlkZGVuIGNsYXNzIHNvIERFViBpc24ndCBzbG93LlxuICAgIHRhcmdldCA9IGNyZWF0ZUZpYmVyKEluZGV0ZXJtaW5hdGVDb21wb25lbnQsIG51bGwsIG51bGwsIE5vTW9kZSk7XG4gIH0gLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IHdyaXR0ZW4gYXMgYSBsaXN0IG9mIGFsbCBwcm9wZXJ0aWVzLlxuICAvLyBXZSB0cmllZCB0byB1c2UgT2JqZWN0LmFzc2lnbigpIGluc3RlYWQgYnV0IHRoaXMgaXMgY2FsbGVkIGluXG4gIC8vIHRoZSBob3R0ZXN0IHBhdGgsIGFuZCBPYmplY3QuYXNzaWduKCkgd2FzIHRvbyBzbG93OlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEyNTAyXG4gIC8vIFRoaXMgY29kZSBpcyBERVYtb25seSBzbyBzaXplIGlzIG5vdCBhIGNvbmNlcm4uXG5cblxuICB0YXJnZXQudGFnID0gc291cmNlLnRhZztcbiAgdGFyZ2V0LmtleSA9IHNvdXJjZS5rZXk7XG4gIHRhcmdldC5lbGVtZW50VHlwZSA9IHNvdXJjZS5lbGVtZW50VHlwZTtcbiAgdGFyZ2V0LnR5cGUgPSBzb3VyY2UudHlwZTtcbiAgdGFyZ2V0LnN0YXRlTm9kZSA9IHNvdXJjZS5zdGF0ZU5vZGU7XG4gIHRhcmdldC5yZXR1cm4gPSBzb3VyY2UucmV0dXJuO1xuICB0YXJnZXQuY2hpbGQgPSBzb3VyY2UuY2hpbGQ7XG4gIHRhcmdldC5zaWJsaW5nID0gc291cmNlLnNpYmxpbmc7XG4gIHRhcmdldC5pbmRleCA9IHNvdXJjZS5pbmRleDtcbiAgdGFyZ2V0LnJlZiA9IHNvdXJjZS5yZWY7XG4gIHRhcmdldC5wZW5kaW5nUHJvcHMgPSBzb3VyY2UucGVuZGluZ1Byb3BzO1xuICB0YXJnZXQubWVtb2l6ZWRQcm9wcyA9IHNvdXJjZS5tZW1vaXplZFByb3BzO1xuICB0YXJnZXQudXBkYXRlUXVldWUgPSBzb3VyY2UudXBkYXRlUXVldWU7XG4gIHRhcmdldC5tZW1vaXplZFN0YXRlID0gc291cmNlLm1lbW9pemVkU3RhdGU7XG4gIHRhcmdldC5kZXBlbmRlbmNpZXMgPSBzb3VyY2UuZGVwZW5kZW5jaWVzO1xuICB0YXJnZXQubW9kZSA9IHNvdXJjZS5tb2RlO1xuICB0YXJnZXQuZmxhZ3MgPSBzb3VyY2UuZmxhZ3M7XG4gIHRhcmdldC5zdWJ0cmVlRmxhZ3MgPSBzb3VyY2Uuc3VidHJlZUZsYWdzO1xuICB0YXJnZXQuZGVsZXRpb25zID0gc291cmNlLmRlbGV0aW9ucztcbiAgdGFyZ2V0LmxhbmVzID0gc291cmNlLmxhbmVzO1xuICB0YXJnZXQuY2hpbGRMYW5lcyA9IHNvdXJjZS5jaGlsZExhbmVzO1xuICB0YXJnZXQuYWx0ZXJuYXRlID0gc291cmNlLmFsdGVybmF0ZTtcblxuICB7XG4gICAgdGFyZ2V0LmFjdHVhbER1cmF0aW9uID0gc291cmNlLmFjdHVhbER1cmF0aW9uO1xuICAgIHRhcmdldC5hY3R1YWxTdGFydFRpbWUgPSBzb3VyY2UuYWN0dWFsU3RhcnRUaW1lO1xuICAgIHRhcmdldC5zZWxmQmFzZUR1cmF0aW9uID0gc291cmNlLnNlbGZCYXNlRHVyYXRpb247XG4gICAgdGFyZ2V0LnRyZWVCYXNlRHVyYXRpb24gPSBzb3VyY2UudHJlZUJhc2VEdXJhdGlvbjtcbiAgfVxuXG4gIHRhcmdldC5fZGVidWdTb3VyY2UgPSBzb3VyY2UuX2RlYnVnU291cmNlO1xuICB0YXJnZXQuX2RlYnVnT3duZXIgPSBzb3VyY2UuX2RlYnVnT3duZXI7XG4gIHRhcmdldC5fZGVidWdOZWVkc1JlbW91bnQgPSBzb3VyY2UuX2RlYnVnTmVlZHNSZW1vdW50O1xuICB0YXJnZXQuX2RlYnVnSG9va1R5cGVzID0gc291cmNlLl9kZWJ1Z0hvb2tUeXBlcztcbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuZnVuY3Rpb24gRmliZXJSb290Tm9kZShjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvcikge1xuICB0aGlzLnRhZyA9IHRhZztcbiAgdGhpcy5jb250YWluZXJJbmZvID0gY29udGFpbmVySW5mbztcbiAgdGhpcy5wZW5kaW5nQ2hpbGRyZW4gPSBudWxsO1xuICB0aGlzLmN1cnJlbnQgPSBudWxsO1xuICB0aGlzLnBpbmdDYWNoZSA9IG51bGw7XG4gIHRoaXMuZmluaXNoZWRXb3JrID0gbnVsbDtcbiAgdGhpcy50aW1lb3V0SGFuZGxlID0gbm9UaW1lb3V0O1xuICB0aGlzLmNvbnRleHQgPSBudWxsO1xuICB0aGlzLnBlbmRpbmdDb250ZXh0ID0gbnVsbDtcbiAgdGhpcy5jYWxsYmFja05vZGUgPSBudWxsO1xuICB0aGlzLmNhbGxiYWNrUHJpb3JpdHkgPSBOb0xhbmU7XG4gIHRoaXMuZXZlbnRUaW1lcyA9IGNyZWF0ZUxhbmVNYXAoTm9MYW5lcyk7XG4gIHRoaXMuZXhwaXJhdGlvblRpbWVzID0gY3JlYXRlTGFuZU1hcChOb1RpbWVzdGFtcCk7XG4gIHRoaXMucGVuZGluZ0xhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5zdXNwZW5kZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMucGluZ2VkTGFuZXMgPSBOb0xhbmVzO1xuICB0aGlzLmV4cGlyZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMubXV0YWJsZVJlYWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMuZmluaXNoZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMuZW50YW5nbGVkTGFuZXMgPSBOb0xhbmVzO1xuICB0aGlzLmVudGFuZ2xlbWVudHMgPSBjcmVhdGVMYW5lTWFwKE5vTGFuZXMpO1xuICB0aGlzLmlkZW50aWZpZXJQcmVmaXggPSBpZGVudGlmaWVyUHJlZml4O1xuICB0aGlzLm9uUmVjb3ZlcmFibGVFcnJvciA9IG9uUmVjb3ZlcmFibGVFcnJvcjtcblxuICB7XG4gICAgdGhpcy5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhID0gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICB0aGlzLmVmZmVjdER1cmF0aW9uID0gMDtcbiAgICB0aGlzLnBhc3NpdmVFZmZlY3REdXJhdGlvbiA9IDA7XG4gIH1cblxuICB7XG4gICAgdGhpcy5tZW1vaXplZFVwZGF0ZXJzID0gbmV3IFNldCgpO1xuICAgIHZhciBwZW5kaW5nVXBkYXRlcnNMYW5lTWFwID0gdGhpcy5wZW5kaW5nVXBkYXRlcnNMYW5lTWFwID0gW107XG5cbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgVG90YWxMYW5lczsgX2krKykge1xuICAgICAgcGVuZGluZ1VwZGF0ZXJzTGFuZU1hcC5wdXNoKG5ldyBTZXQoKSk7XG4gICAgfVxuICB9XG5cbiAge1xuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlIENvbmN1cnJlbnRSb290OlxuICAgICAgICB0aGlzLl9kZWJ1Z1Jvb3RUeXBlID0gaHlkcmF0ZSA/ICdoeWRyYXRlUm9vdCgpJyA6ICdjcmVhdGVSb290KCknO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBMZWdhY3lSb290OlxuICAgICAgICB0aGlzLl9kZWJ1Z1Jvb3RUeXBlID0gaHlkcmF0ZSA/ICdoeWRyYXRlKCknIDogJ3JlbmRlcigpJztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyUm9vdChjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGUsIGluaXRpYWxDaGlsZHJlbiwgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIC8vIFRPRE86IFdlIGhhdmUgc2V2ZXJhbCBvZiB0aGVzZSBhcmd1bWVudHMgdGhhdCBhcmUgY29uY2VwdHVhbGx5IHBhcnQgb2YgdGhlXG4vLyBob3N0IGNvbmZpZywgYnV0IGJlY2F1c2UgdGhleSBhcmUgcGFzc2VkIGluIGF0IHJ1bnRpbWUsIHdlIGhhdmUgdG8gdGhyZWFkXG4vLyB0aGVtIHRocm91Z2ggdGhlIHJvb3QgY29uc3RydWN0b3IuIFBlcmhhcHMgd2Ugc2hvdWxkIHB1dCB0aGVtIGFsbCBpbnRvIGFcbi8vIHNpbmdsZSB0eXBlLCBsaWtlIGEgRHluYW1pY0hvc3RDb25maWcgdGhhdCBpcyBkZWZpbmVkIGJ5IHRoZSByZW5kZXJlci5cbmlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvciwgdHJhbnNpdGlvbkNhbGxiYWNrcykge1xuICB2YXIgcm9vdCA9IG5ldyBGaWJlclJvb3ROb2RlKGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0ZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgLy8gc3RhdGVOb2RlIGlzIGFueS5cblxuXG4gIHZhciB1bmluaXRpYWxpemVkRmliZXIgPSBjcmVhdGVIb3N0Um9vdEZpYmVyKHRhZywgaXNTdHJpY3RNb2RlKTtcbiAgcm9vdC5jdXJyZW50ID0gdW5pbml0aWFsaXplZEZpYmVyO1xuICB1bmluaXRpYWxpemVkRmliZXIuc3RhdGVOb2RlID0gcm9vdDtcblxuICB7XG4gICAgdmFyIF9pbml0aWFsU3RhdGUgPSB7XG4gICAgICBlbGVtZW50OiBpbml0aWFsQ2hpbGRyZW4sXG4gICAgICBpc0RlaHlkcmF0ZWQ6IGh5ZHJhdGUsXG4gICAgICBjYWNoZTogbnVsbCxcbiAgICAgIC8vIG5vdCBlbmFibGVkIHlldFxuICAgICAgdHJhbnNpdGlvbnM6IG51bGwsXG4gICAgICBwZW5kaW5nU3VzcGVuc2VCb3VuZGFyaWVzOiBudWxsXG4gICAgfTtcbiAgICB1bmluaXRpYWxpemVkRmliZXIubWVtb2l6ZWRTdGF0ZSA9IF9pbml0aWFsU3RhdGU7XG4gIH1cblxuICBpbml0aWFsaXplVXBkYXRlUXVldWUodW5pbml0aWFsaXplZEZpYmVyKTtcbiAgcmV0dXJuIHJvb3Q7XG59XG5cbnZhciBSZWFjdFZlcnNpb24gPSAnMTguMS4wJztcblxuZnVuY3Rpb24gY3JlYXRlUG9ydGFsKGNoaWxkcmVuLCBjb250YWluZXJJbmZvLCAvLyBUT0RPOiBmaWd1cmUgb3V0IHRoZSBBUEkgZm9yIGNyb3NzLXJlbmRlcmVyIGltcGxlbWVudGF0aW9uLlxuaW1wbGVtZW50YXRpb24pIHtcbiAgdmFyIGtleSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogbnVsbDtcblxuICB7XG4gICAgY2hlY2tLZXlTdHJpbmdDb2VyY2lvbihrZXkpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAvLyBUaGlzIHRhZyBhbGxvdyB1cyB0byB1bmlxdWVseSBpZGVudGlmeSB0aGlzIGFzIGEgUmVhY3QgUG9ydGFsXG4gICAgJCR0eXBlb2Y6IFJFQUNUX1BPUlRBTF9UWVBFLFxuICAgIGtleToga2V5ID09IG51bGwgPyBudWxsIDogJycgKyBrZXksXG4gICAgY2hpbGRyZW46IGNoaWxkcmVuLFxuICAgIGNvbnRhaW5lckluZm86IGNvbnRhaW5lckluZm8sXG4gICAgaW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uXG4gIH07XG59XG5cbnZhciBkaWRXYXJuQWJvdXROZXN0ZWRVcGRhdGVzO1xudmFyIGRpZFdhcm5BYm91dEZpbmROb2RlSW5TdHJpY3RNb2RlO1xuXG57XG4gIGRpZFdhcm5BYm91dE5lc3RlZFVwZGF0ZXMgPSBmYWxzZTtcbiAgZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGUgPSB7fTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29udGV4dEZvclN1YnRyZWUocGFyZW50Q29tcG9uZW50KSB7XG4gIGlmICghcGFyZW50Q29tcG9uZW50KSB7XG4gICAgcmV0dXJuIGVtcHR5Q29udGV4dE9iamVjdDtcbiAgfVxuXG4gIHZhciBmaWJlciA9IGdldChwYXJlbnRDb21wb25lbnQpO1xuICB2YXIgcGFyZW50Q29udGV4dCA9IGZpbmRDdXJyZW50VW5tYXNrZWRDb250ZXh0KGZpYmVyKTtcblxuICBpZiAoZmliZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgIHZhciBDb21wb25lbnQgPSBmaWJlci50eXBlO1xuXG4gICAgaWYgKGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgIHJldHVybiBwcm9jZXNzQ2hpbGRDb250ZXh0KGZpYmVyLCBDb21wb25lbnQsIHBhcmVudENvbnRleHQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJlbnRDb250ZXh0O1xufVxuXG5mdW5jdGlvbiBmaW5kSG9zdEluc3RhbmNlV2l0aFdhcm5pbmcoY29tcG9uZW50LCBtZXRob2ROYW1lKSB7XG4gIHtcbiAgICB2YXIgZmliZXIgPSBnZXQoY29tcG9uZW50KTtcblxuICAgIGlmIChmaWJlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGNvbXBvbmVudC5yZW5kZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGNvbXBvbmVudCkuam9pbignLCcpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBcmd1bWVudCBhcHBlYXJzIHRvIG5vdCBiZSBhIFJlYWN0Q29tcG9uZW50LiBLZXlzOiBcIiArIGtleXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBob3N0RmliZXIgPSBmaW5kQ3VycmVudEhvc3RGaWJlcihmaWJlcik7XG5cbiAgICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoaG9zdEZpYmVyLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dEZpbmROb2RlSW5TdHJpY3RNb2RlW2NvbXBvbmVudE5hbWVdKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dEZpbmROb2RlSW5TdHJpY3RNb2RlW2NvbXBvbmVudE5hbWVdID0gdHJ1ZTtcbiAgICAgICAgdmFyIHByZXZpb3VzRmliZXIgPSBjdXJyZW50O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgc2V0Q3VycmVudEZpYmVyKGhvc3RGaWJlcik7XG5cbiAgICAgICAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgICAgIGVycm9yKCclcyBpcyBkZXByZWNhdGVkIGluIFN0cmljdE1vZGUuICcgKyAnJXMgd2FzIHBhc3NlZCBhbiBpbnN0YW5jZSBvZiAlcyB3aGljaCBpcyBpbnNpZGUgU3RyaWN0TW9kZS4gJyArICdJbnN0ZWFkLCBhZGQgYSByZWYgZGlyZWN0bHkgdG8gdGhlIGVsZW1lbnQgeW91IHdhbnQgdG8gcmVmZXJlbmNlLiAnICsgJ0xlYXJuIG1vcmUgYWJvdXQgdXNpbmcgcmVmcyBzYWZlbHkgaGVyZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3RyaWN0LW1vZGUtZmluZC1ub2RlJywgbWV0aG9kTmFtZSwgbWV0aG9kTmFtZSwgY29tcG9uZW50TmFtZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVycm9yKCclcyBpcyBkZXByZWNhdGVkIGluIFN0cmljdE1vZGUuICcgKyAnJXMgd2FzIHBhc3NlZCBhbiBpbnN0YW5jZSBvZiAlcyB3aGljaCByZW5kZXJzIFN0cmljdE1vZGUgY2hpbGRyZW4uICcgKyAnSW5zdGVhZCwgYWRkIGEgcmVmIGRpcmVjdGx5IHRvIHRoZSBlbGVtZW50IHlvdSB3YW50IHRvIHJlZmVyZW5jZS4gJyArICdMZWFybiBtb3JlIGFib3V0IHVzaW5nIHJlZnMgc2FmZWx5IGhlcmU6ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3N0cmljdC1tb2RlLWZpbmQtbm9kZScsIG1ldGhvZE5hbWUsIG1ldGhvZE5hbWUsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAvLyBJZGVhbGx5IHRoaXMgc2hvdWxkIHJlc2V0IHRvIHByZXZpb3VzIGJ1dCB0aGlzIHNob3VsZG4ndCBiZSBjYWxsZWQgaW5cbiAgICAgICAgICAvLyByZW5kZXIgYW5kIHRoZXJlJ3MgYW5vdGhlciB3YXJuaW5nIGZvciB0aGF0IGFueXdheS5cbiAgICAgICAgICBpZiAocHJldmlvdXNGaWJlcikge1xuICAgICAgICAgICAgc2V0Q3VycmVudEZpYmVyKHByZXZpb3VzRmliZXIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBob3N0RmliZXIuc3RhdGVOb2RlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbnRhaW5lcihjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGlvbkNhbGxiYWNrcywgaXNTdHJpY3RNb2RlLCBjb25jdXJyZW50VXBkYXRlc0J5RGVmYXVsdE92ZXJyaWRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IsIHRyYW5zaXRpb25DYWxsYmFja3MpIHtcbiAgdmFyIGh5ZHJhdGUgPSBmYWxzZTtcbiAgdmFyIGluaXRpYWxDaGlsZHJlbiA9IG51bGw7XG4gIHJldHVybiBjcmVhdGVGaWJlclJvb3QoY29udGFpbmVySW5mbywgdGFnLCBoeWRyYXRlLCBpbml0aWFsQ2hpbGRyZW4sIGh5ZHJhdGlvbkNhbGxiYWNrcywgaXNTdHJpY3RNb2RlLCBjb25jdXJyZW50VXBkYXRlc0J5RGVmYXVsdE92ZXJyaWRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IpO1xufVxuZnVuY3Rpb24gY3JlYXRlSHlkcmF0aW9uQ29udGFpbmVyKGluaXRpYWxDaGlsZHJlbiwgLy8gVE9ETzogUmVtb3ZlIGBjYWxsYmFja2Agd2hlbiB3ZSBkZWxldGUgbGVnYWN5IG1vZGUuXG5jYWxsYmFjaywgY29udGFpbmVySW5mbywgdGFnLCBoeWRyYXRpb25DYWxsYmFja3MsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yLCB0cmFuc2l0aW9uQ2FsbGJhY2tzKSB7XG4gIHZhciBoeWRyYXRlID0gdHJ1ZTtcbiAgdmFyIHJvb3QgPSBjcmVhdGVGaWJlclJvb3QoY29udGFpbmVySW5mbywgdGFnLCBoeWRyYXRlLCBpbml0aWFsQ2hpbGRyZW4sIGh5ZHJhdGlvbkNhbGxiYWNrcywgaXNTdHJpY3RNb2RlLCBjb25jdXJyZW50VXBkYXRlc0J5RGVmYXVsdE92ZXJyaWRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IpOyAvLyBUT0RPOiBNb3ZlIHRoaXMgdG8gRmliZXJSb290IGNvbnN0cnVjdG9yXG5cbiAgcm9vdC5jb250ZXh0ID0gZ2V0Q29udGV4dEZvclN1YnRyZWUobnVsbCk7IC8vIFNjaGVkdWxlIHRoZSBpbml0aWFsIHJlbmRlci4gSW4gYSBoeWRyYXRpb24gcm9vdCwgdGhpcyBpcyBkaWZmZXJlbnQgZnJvbVxuICAvLyBhIHJlZ3VsYXIgdXBkYXRlIGJlY2F1c2UgdGhlIGluaXRpYWwgcmVuZGVyIG11c3QgbWF0Y2ggd2FzIHdhcyByZW5kZXJlZFxuICAvLyBvbiB0aGUgc2VydmVyLlxuICAvLyBOT1RFOiBUaGlzIHVwZGF0ZSBpbnRlbnRpb25hbGx5IGRvZXNuJ3QgaGF2ZSBhIHBheWxvYWQuIFdlJ3JlIG9ubHkgdXNpbmdcbiAgLy8gdGhlIHVwZGF0ZSB0byBzY2hlZHVsZSB3b3JrIG9uIHRoZSByb290IGZpYmVyIChhbmQsIGZvciBsZWdhY3kgcm9vdHMsIHRvXG4gIC8vIGVucXVldWUgdGhlIGNhbGxiYWNrIGlmIG9uZSBpcyBwcm92aWRlZCkuXG5cbiAgdmFyIGN1cnJlbnQgPSByb290LmN1cnJlbnQ7XG4gIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gIHZhciBsYW5lID0gcmVxdWVzdFVwZGF0ZUxhbmUoY3VycmVudCk7XG4gIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoZXZlbnRUaW1lLCBsYW5lKTtcbiAgdXBkYXRlLmNhbGxiYWNrID0gY2FsbGJhY2sgIT09IHVuZGVmaW5lZCAmJiBjYWxsYmFjayAhPT0gbnVsbCA/IGNhbGxiYWNrIDogbnVsbDtcbiAgZW5xdWV1ZVVwZGF0ZShjdXJyZW50LCB1cGRhdGUpO1xuICBzY2hlZHVsZUluaXRpYWxIeWRyYXRpb25PblJvb3Qocm9vdCwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgcmV0dXJuIHJvb3Q7XG59XG5mdW5jdGlvbiB1cGRhdGVDb250YWluZXIoZWxlbWVudCwgY29udGFpbmVyLCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrKSB7XG4gIHtcbiAgICBvblNjaGVkdWxlUm9vdChjb250YWluZXIsIGVsZW1lbnQpO1xuICB9XG5cbiAgdmFyIGN1cnJlbnQkMSA9IGNvbnRhaW5lci5jdXJyZW50O1xuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGN1cnJlbnQkMSk7XG5cbiAge1xuICAgIG1hcmtSZW5kZXJTY2hlZHVsZWQobGFuZSk7XG4gIH1cblxuICB2YXIgY29udGV4dCA9IGdldENvbnRleHRGb3JTdWJ0cmVlKHBhcmVudENvbXBvbmVudCk7XG5cbiAgaWYgKGNvbnRhaW5lci5jb250ZXh0ID09PSBudWxsKSB7XG4gICAgY29udGFpbmVyLmNvbnRleHQgPSBjb250ZXh0O1xuICB9IGVsc2Uge1xuICAgIGNvbnRhaW5lci5wZW5kaW5nQ29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICB7XG4gICAgaWYgKGlzUmVuZGVyaW5nICYmIGN1cnJlbnQgIT09IG51bGwgJiYgIWRpZFdhcm5BYm91dE5lc3RlZFVwZGF0ZXMpIHtcbiAgICAgIGRpZFdhcm5BYm91dE5lc3RlZFVwZGF0ZXMgPSB0cnVlO1xuXG4gICAgICBlcnJvcignUmVuZGVyIG1ldGhvZHMgc2hvdWxkIGJlIGEgcHVyZSBmdW5jdGlvbiBvZiBwcm9wcyBhbmQgc3RhdGU7ICcgKyAndHJpZ2dlcmluZyBuZXN0ZWQgY29tcG9uZW50IHVwZGF0ZXMgZnJvbSByZW5kZXIgaXMgbm90IGFsbG93ZWQuICcgKyAnSWYgbmVjZXNzYXJ5LCB0cmlnZ2VyIG5lc3RlZCB1cGRhdGVzIGluIGNvbXBvbmVudERpZFVwZGF0ZS5cXG5cXG4nICsgJ0NoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mICVzLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoY3VycmVudCkgfHwgJ1Vua25vd24nKTtcbiAgICB9XG4gIH1cblxuICB2YXIgdXBkYXRlID0gY3JlYXRlVXBkYXRlKGV2ZW50VGltZSwgbGFuZSk7IC8vIENhdXRpb246IFJlYWN0IERldlRvb2xzIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJvcGVydHlcbiAgLy8gYmVpbmcgY2FsbGVkIFwiZWxlbWVudFwiLlxuXG4gIHVwZGF0ZS5wYXlsb2FkID0ge1xuICAgIGVsZW1lbnQ6IGVsZW1lbnRcbiAgfTtcbiAgY2FsbGJhY2sgPSBjYWxsYmFjayA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGNhbGxiYWNrO1xuXG4gIGlmIChjYWxsYmFjayAhPT0gbnVsbCkge1xuICAgIHtcbiAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZXJyb3IoJ3JlbmRlciguLi4pOiBFeHBlY3RlZCB0aGUgbGFzdCBvcHRpb25hbCBgY2FsbGJhY2tgIGFyZ3VtZW50IHRvIGJlIGEgJyArICdmdW5jdGlvbi4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICB9XG5cbiAgZW5xdWV1ZVVwZGF0ZShjdXJyZW50JDEsIHVwZGF0ZSk7XG4gIHZhciByb290ID0gc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGN1cnJlbnQkMSwgbGFuZSwgZXZlbnRUaW1lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIGVudGFuZ2xlVHJhbnNpdGlvbnMocm9vdCwgY3VycmVudCQxLCBsYW5lKTtcbiAgfVxuXG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gZ2V0UHVibGljUm9vdEluc3RhbmNlKGNvbnRhaW5lcikge1xuICB2YXIgY29udGFpbmVyRmliZXIgPSBjb250YWluZXIuY3VycmVudDtcblxuICBpZiAoIWNvbnRhaW5lckZpYmVyLmNoaWxkKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzd2l0Y2ggKGNvbnRhaW5lckZpYmVyLmNoaWxkLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHJldHVybiBnZXRQdWJsaWNJbnN0YW5jZShjb250YWluZXJGaWJlci5jaGlsZC5zdGF0ZU5vZGUpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBjb250YWluZXJGaWJlci5jaGlsZC5zdGF0ZU5vZGU7XG4gIH1cbn1cbmZ1bmN0aW9uIGF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbiQxKGZpYmVyKSB7XG4gIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHZhciByb290ID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICBpZiAoaXNSb290RGVoeWRyYXRlZChyb290KSkge1xuICAgICAgICAvLyBGbHVzaCB0aGUgZmlyc3Qgc2NoZWR1bGVkIFwidXBkYXRlXCIuXG4gICAgICAgIHZhciBsYW5lcyA9IGdldEhpZ2hlc3RQcmlvcml0eVBlbmRpbmdMYW5lcyhyb290KTtcbiAgICAgICAgZmx1c2hSb290KHJvb3QsIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgIGZsdXNoU3luYyhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzY2hlZHVsZVVwZGF0ZU9uRmliZXIoZmliZXIsIFN5bmNMYW5lLCBldmVudFRpbWUpO1xuICAgICAgfSk7IC8vIElmIHdlJ3JlIHN0aWxsIGJsb2NrZWQgYWZ0ZXIgdGhpcywgd2UgbmVlZCB0byBpbmNyZWFzZVxuICAgICAgLy8gdGhlIHByaW9yaXR5IG9mIGFueSBwcm9taXNlcyByZXNvbHZpbmcgd2l0aGluIHRoaXNcbiAgICAgIC8vIGJvdW5kYXJ5IHNvIHRoYXQgdGhleSBuZXh0IGF0dGVtcHQgYWxzbyBoYXMgaGlnaGVyIHByaS5cblxuICAgICAgdmFyIHJldHJ5TGFuZSA9IFN5bmNMYW5lO1xuICAgICAgbWFya1JldHJ5TGFuZUlmTm90SHlkcmF0ZWQoZmliZXIsIHJldHJ5TGFuZSk7XG4gICAgICBicmVhaztcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrUmV0cnlMYW5lSW1wbChmaWJlciwgcmV0cnlMYW5lKSB7XG4gIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCAmJiBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSA9IGhpZ2hlclByaW9yaXR5TGFuZShzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSwgcmV0cnlMYW5lKTtcbiAgfVxufSAvLyBJbmNyZWFzZXMgdGhlIHByaW9yaXR5IG9mIHRoZW5hYmxlcyB3aGVuIHRoZXkgcmVzb2x2ZSB3aXRoaW4gdGhpcyBib3VuZGFyeS5cblxuXG5mdW5jdGlvbiBtYXJrUmV0cnlMYW5lSWZOb3RIeWRyYXRlZChmaWJlciwgcmV0cnlMYW5lKSB7XG4gIG1hcmtSZXRyeUxhbmVJbXBsKGZpYmVyLCByZXRyeUxhbmUpO1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmIChhbHRlcm5hdGUpIHtcbiAgICBtYXJrUmV0cnlMYW5lSW1wbChhbHRlcm5hdGUsIHJldHJ5TGFuZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uJDEoZmliZXIpIHtcbiAgaWYgKGZpYmVyLnRhZyAhPT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAvLyBXZSBpZ25vcmUgSG9zdFJvb3RzIGhlcmUgYmVjYXVzZSB3ZSBjYW4ndCBpbmNyZWFzZVxuICAgIC8vIHRoZWlyIHByaW9yaXR5IGFuZCB0aGV5IHNob3VsZCBub3Qgc3VzcGVuZCBvbiBJL08sXG4gICAgLy8gc2luY2UgeW91IGhhdmUgdG8gd3JhcCBhbnl0aGluZyB0aGF0IG1pZ2h0IHN1c3BlbmQgaW5cbiAgICAvLyBTdXNwZW5zZS5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICB2YXIgbGFuZSA9IFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmU7XG4gIHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgbWFya1JldHJ5TGFuZUlmTm90SHlkcmF0ZWQoZmliZXIsIGxhbmUpO1xufVxuZnVuY3Rpb24gYXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5JDEoZmliZXIpIHtcbiAgaWYgKGZpYmVyLnRhZyAhPT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAvLyBXZSBpZ25vcmUgSG9zdFJvb3RzIGhlcmUgYmVjYXVzZSB3ZSBjYW4ndCBpbmNyZWFzZVxuICAgIC8vIHRoZWlyIHByaW9yaXR5IG90aGVyIHRoYW4gc3luY2hyb25vdXNseSBmbHVzaCBpdC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGZpYmVyLCBsYW5lLCBldmVudFRpbWUpO1xuICBtYXJrUmV0cnlMYW5lSWZOb3RIeWRyYXRlZChmaWJlciwgbGFuZSk7XG59XG5mdW5jdGlvbiBmaW5kSG9zdEluc3RhbmNlV2l0aE5vUG9ydGFscyhmaWJlcikge1xuICB2YXIgaG9zdEZpYmVyID0gZmluZEN1cnJlbnRIb3N0RmliZXJXaXRoTm9Qb3J0YWxzKGZpYmVyKTtcblxuICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9zdEZpYmVyLnN0YXRlTm9kZTtcbn1cblxudmFyIHNob3VsZEVycm9ySW1wbCA9IGZ1bmN0aW9uIChmaWJlcikge1xuICByZXR1cm4gbnVsbDtcbn07XG5cbmZ1bmN0aW9uIHNob3VsZEVycm9yKGZpYmVyKSB7XG4gIHJldHVybiBzaG91bGRFcnJvckltcGwoZmliZXIpO1xufVxuXG52YXIgc2hvdWxkU3VzcGVuZEltcGwgPSBmdW5jdGlvbiAoZmliZXIpIHtcbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gc2hvdWxkU3VzcGVuZChmaWJlcikge1xuICByZXR1cm4gc2hvdWxkU3VzcGVuZEltcGwoZmliZXIpO1xufVxudmFyIG92ZXJyaWRlSG9va1N0YXRlID0gbnVsbDtcbnZhciBvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGggPSBudWxsO1xudmFyIG92ZXJyaWRlSG9va1N0YXRlUmVuYW1lUGF0aCA9IG51bGw7XG52YXIgb3ZlcnJpZGVQcm9wcyA9IG51bGw7XG52YXIgb3ZlcnJpZGVQcm9wc0RlbGV0ZVBhdGggPSBudWxsO1xudmFyIG92ZXJyaWRlUHJvcHNSZW5hbWVQYXRoID0gbnVsbDtcbnZhciBzY2hlZHVsZVVwZGF0ZSA9IG51bGw7XG52YXIgc2V0RXJyb3JIYW5kbGVyID0gbnVsbDtcbnZhciBzZXRTdXNwZW5zZUhhbmRsZXIgPSBudWxsO1xuXG57XG4gIHZhciBjb3B5V2l0aERlbGV0ZUltcGwgPSBmdW5jdGlvbiAob2JqLCBwYXRoLCBpbmRleCkge1xuICAgIHZhciBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICB2YXIgdXBkYXRlZCA9IGlzQXJyYXkob2JqKSA/IG9iai5zbGljZSgpIDogYXNzaWduKHt9LCBvYmopO1xuXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gcGF0aC5sZW5ndGgpIHtcbiAgICAgIGlmIChpc0FycmF5KHVwZGF0ZWQpKSB7XG4gICAgICAgIHVwZGF0ZWQuc3BsaWNlKGtleSwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgdXBkYXRlZFtrZXldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICB9IC8vICRGbG93Rml4TWUgbnVtYmVyIG9yIHN0cmluZyBpcyBmaW5lIGhlcmVcblxuXG4gICAgdXBkYXRlZFtrZXldID0gY29weVdpdGhEZWxldGVJbXBsKG9ialtrZXldLCBwYXRoLCBpbmRleCArIDEpO1xuICAgIHJldHVybiB1cGRhdGVkO1xuICB9O1xuXG4gIHZhciBjb3B5V2l0aERlbGV0ZSA9IGZ1bmN0aW9uIChvYmosIHBhdGgpIHtcbiAgICByZXR1cm4gY29weVdpdGhEZWxldGVJbXBsKG9iaiwgcGF0aCwgMCk7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoUmVuYW1lSW1wbCA9IGZ1bmN0aW9uIChvYmosIG9sZFBhdGgsIG5ld1BhdGgsIGluZGV4KSB7XG4gICAgdmFyIG9sZEtleSA9IG9sZFBhdGhbaW5kZXhdO1xuICAgIHZhciB1cGRhdGVkID0gaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBhc3NpZ24oe30sIG9iaik7XG5cbiAgICBpZiAoaW5kZXggKyAxID09PSBvbGRQYXRoLmxlbmd0aCkge1xuICAgICAgdmFyIG5ld0tleSA9IG5ld1BhdGhbaW5kZXhdOyAvLyAkRmxvd0ZpeE1lIG51bWJlciBvciBzdHJpbmcgaXMgZmluZSBoZXJlXG5cbiAgICAgIHVwZGF0ZWRbbmV3S2V5XSA9IHVwZGF0ZWRbb2xkS2V5XTtcblxuICAgICAgaWYgKGlzQXJyYXkodXBkYXRlZCkpIHtcbiAgICAgICAgdXBkYXRlZC5zcGxpY2Uob2xkS2V5LCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVkW29sZEtleV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vICRGbG93Rml4TWUgbnVtYmVyIG9yIHN0cmluZyBpcyBmaW5lIGhlcmVcbiAgICAgIHVwZGF0ZWRbb2xkS2V5XSA9IGNvcHlXaXRoUmVuYW1lSW1wbCggLy8gJEZsb3dGaXhNZSBudW1iZXIgb3Igc3RyaW5nIGlzIGZpbmUgaGVyZVxuICAgICAgb2JqW29sZEtleV0sIG9sZFBhdGgsIG5ld1BhdGgsIGluZGV4ICsgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVwZGF0ZWQ7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoUmVuYW1lID0gZnVuY3Rpb24gKG9iaiwgb2xkUGF0aCwgbmV3UGF0aCkge1xuICAgIGlmIChvbGRQYXRoLmxlbmd0aCAhPT0gbmV3UGF0aC5sZW5ndGgpIHtcbiAgICAgIHdhcm4oJ2NvcHlXaXRoUmVuYW1lKCkgZXhwZWN0cyBwYXRocyBvZiB0aGUgc2FtZSBsZW5ndGgnKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld1BhdGgubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGlmIChvbGRQYXRoW2ldICE9PSBuZXdQYXRoW2ldKSB7XG4gICAgICAgICAgd2FybignY29weVdpdGhSZW5hbWUoKSBleHBlY3RzIHBhdGhzIHRvIGJlIHRoZSBzYW1lIGV4Y2VwdCBmb3IgdGhlIGRlZXBlc3Qga2V5Jyk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29weVdpdGhSZW5hbWVJbXBsKG9iaiwgb2xkUGF0aCwgbmV3UGF0aCwgMCk7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoU2V0SW1wbCA9IGZ1bmN0aW9uIChvYmosIHBhdGgsIGluZGV4LCB2YWx1ZSkge1xuICAgIGlmIChpbmRleCA+PSBwYXRoLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICB2YXIgdXBkYXRlZCA9IGlzQXJyYXkob2JqKSA/IG9iai5zbGljZSgpIDogYXNzaWduKHt9LCBvYmopOyAvLyAkRmxvd0ZpeE1lIG51bWJlciBvciBzdHJpbmcgaXMgZmluZSBoZXJlXG5cbiAgICB1cGRhdGVkW2tleV0gPSBjb3B5V2l0aFNldEltcGwob2JqW2tleV0sIHBhdGgsIGluZGV4ICsgMSwgdmFsdWUpO1xuICAgIHJldHVybiB1cGRhdGVkO1xuICB9O1xuXG4gIHZhciBjb3B5V2l0aFNldCA9IGZ1bmN0aW9uIChvYmosIHBhdGgsIHZhbHVlKSB7XG4gICAgcmV0dXJuIGNvcHlXaXRoU2V0SW1wbChvYmosIHBhdGgsIDAsIHZhbHVlKTtcbiAgfTtcblxuICB2YXIgZmluZEhvb2sgPSBmdW5jdGlvbiAoZmliZXIsIGlkKSB7XG4gICAgLy8gRm9yIG5vdywgdGhlIFwiaWRcIiBvZiBzdGF0ZWZ1bCBob29rcyBpcyBqdXN0IHRoZSBzdGF0ZWZ1bCBob29rIGluZGV4LlxuICAgIC8vIFRoaXMgbWF5IGNoYW5nZSBpbiB0aGUgZnV0dXJlIHdpdGggZS5nLiBuZXN0ZWQgaG9va3MuXG4gICAgdmFyIGN1cnJlbnRIb29rID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICAgIHdoaWxlIChjdXJyZW50SG9vayAhPT0gbnVsbCAmJiBpZCA+IDApIHtcbiAgICAgIGN1cnJlbnRIb29rID0gY3VycmVudEhvb2submV4dDtcbiAgICAgIGlkLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRIb29rO1xuICB9OyAvLyBTdXBwb3J0IERldlRvb2xzIGVkaXRhYmxlIHZhbHVlcyBmb3IgdXNlU3RhdGUgYW5kIHVzZVJlZHVjZXIuXG5cblxuICBvdmVycmlkZUhvb2tTdGF0ZSA9IGZ1bmN0aW9uIChmaWJlciwgaWQsIHBhdGgsIHZhbHVlKSB7XG4gICAgdmFyIGhvb2sgPSBmaW5kSG9vayhmaWJlciwgaWQpO1xuXG4gICAgaWYgKGhvb2sgIT09IG51bGwpIHtcbiAgICAgIHZhciBuZXdTdGF0ZSA9IGNvcHlXaXRoU2V0KGhvb2subWVtb2l6ZWRTdGF0ZSwgcGF0aCwgdmFsdWUpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVIb29rU3RhdGVEZWxldGVQYXRoID0gZnVuY3Rpb24gKGZpYmVyLCBpZCwgcGF0aCkge1xuICAgIHZhciBob29rID0gZmluZEhvb2soZmliZXIsIGlkKTtcblxuICAgIGlmIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgbmV3U3RhdGUgPSBjb3B5V2l0aERlbGV0ZShob29rLm1lbW9pemVkU3RhdGUsIHBhdGgpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVIb29rU3RhdGVSZW5hbWVQYXRoID0gZnVuY3Rpb24gKGZpYmVyLCBpZCwgb2xkUGF0aCwgbmV3UGF0aCkge1xuICAgIHZhciBob29rID0gZmluZEhvb2soZmliZXIsIGlkKTtcblxuICAgIGlmIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgbmV3U3RhdGUgPSBjb3B5V2l0aFJlbmFtZShob29rLm1lbW9pemVkU3RhdGUsIG9sZFBhdGgsIG5ld1BhdGgpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICB9XG4gIH07IC8vIFN1cHBvcnQgRGV2VG9vbHMgcHJvcHMgZm9yIGZ1bmN0aW9uIGNvbXBvbmVudHMsIGZvcndhcmRSZWYsIG1lbW8sIGhvc3QgY29tcG9uZW50cywgZXRjLlxuXG5cbiAgb3ZlcnJpZGVQcm9wcyA9IGZ1bmN0aW9uIChmaWJlciwgcGF0aCwgdmFsdWUpIHtcbiAgICBmaWJlci5wZW5kaW5nUHJvcHMgPSBjb3B5V2l0aFNldChmaWJlci5tZW1vaXplZFByb3BzLCBwYXRoLCB2YWx1ZSk7XG5cbiAgICBpZiAoZmliZXIuYWx0ZXJuYXRlKSB7XG4gICAgICBmaWJlci5hbHRlcm5hdGUucGVuZGluZ1Byb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgIH1cblxuICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgfTtcblxuICBvdmVycmlkZVByb3BzRGVsZXRlUGF0aCA9IGZ1bmN0aW9uIChmaWJlciwgcGF0aCkge1xuICAgIGZpYmVyLnBlbmRpbmdQcm9wcyA9IGNvcHlXaXRoRGVsZXRlKGZpYmVyLm1lbW9pemVkUHJvcHMsIHBhdGgpO1xuXG4gICAgaWYgKGZpYmVyLmFsdGVybmF0ZSkge1xuICAgICAgZmliZXIuYWx0ZXJuYXRlLnBlbmRpbmdQcm9wcyA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICB9XG5cbiAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIoZmliZXIsIFN5bmNMYW5lLCBOb1RpbWVzdGFtcCk7XG4gIH07XG5cbiAgb3ZlcnJpZGVQcm9wc1JlbmFtZVBhdGggPSBmdW5jdGlvbiAoZmliZXIsIG9sZFBhdGgsIG5ld1BhdGgpIHtcbiAgICBmaWJlci5wZW5kaW5nUHJvcHMgPSBjb3B5V2l0aFJlbmFtZShmaWJlci5tZW1vaXplZFByb3BzLCBvbGRQYXRoLCBuZXdQYXRoKTtcblxuICAgIGlmIChmaWJlci5hbHRlcm5hdGUpIHtcbiAgICAgIGZpYmVyLmFsdGVybmF0ZS5wZW5kaW5nUHJvcHMgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgfVxuXG4gICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGZpYmVyLCBTeW5jTGFuZSwgTm9UaW1lc3RhbXApO1xuICB9O1xuXG4gIHNjaGVkdWxlVXBkYXRlID0gZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKGZpYmVyLCBTeW5jTGFuZSwgTm9UaW1lc3RhbXApO1xuICB9O1xuXG4gIHNldEVycm9ySGFuZGxlciA9IGZ1bmN0aW9uIChuZXdTaG91bGRFcnJvckltcGwpIHtcbiAgICBzaG91bGRFcnJvckltcGwgPSBuZXdTaG91bGRFcnJvckltcGw7XG4gIH07XG5cbiAgc2V0U3VzcGVuc2VIYW5kbGVyID0gZnVuY3Rpb24gKG5ld1Nob3VsZFN1c3BlbmRJbXBsKSB7XG4gICAgc2hvdWxkU3VzcGVuZEltcGwgPSBuZXdTaG91bGRTdXNwZW5kSW1wbDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZUJ5RmliZXIoZmliZXIpIHtcbiAgdmFyIGhvc3RGaWJlciA9IGZpbmRDdXJyZW50SG9zdEZpYmVyKGZpYmVyKTtcblxuICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9zdEZpYmVyLnN0YXRlTm9kZTtcbn1cblxuZnVuY3Rpb24gZW1wdHlGaW5kRmliZXJCeUhvc3RJbnN0YW5jZShpbnN0YW5jZSkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyRm9yRGV2VG9vbHMoKSB7XG4gIHJldHVybiBjdXJyZW50O1xufVxuXG5mdW5jdGlvbiBpbmplY3RJbnRvRGV2VG9vbHMoZGV2VG9vbHNDb25maWcpIHtcbiAgdmFyIGZpbmRGaWJlckJ5SG9zdEluc3RhbmNlID0gZGV2VG9vbHNDb25maWcuZmluZEZpYmVyQnlIb3N0SW5zdGFuY2U7XG4gIHZhciBSZWFjdEN1cnJlbnREaXNwYXRjaGVyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcjtcbiAgcmV0dXJuIGluamVjdEludGVybmFscyh7XG4gICAgYnVuZGxlVHlwZTogZGV2VG9vbHNDb25maWcuYnVuZGxlVHlwZSxcbiAgICB2ZXJzaW9uOiBkZXZUb29sc0NvbmZpZy52ZXJzaW9uLFxuICAgIHJlbmRlcmVyUGFja2FnZU5hbWU6IGRldlRvb2xzQ29uZmlnLnJlbmRlcmVyUGFja2FnZU5hbWUsXG4gICAgcmVuZGVyZXJDb25maWc6IGRldlRvb2xzQ29uZmlnLnJlbmRlcmVyQ29uZmlnLFxuICAgIG92ZXJyaWRlSG9va1N0YXRlOiBvdmVycmlkZUhvb2tTdGF0ZSxcbiAgICBvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGg6IG92ZXJyaWRlSG9va1N0YXRlRGVsZXRlUGF0aCxcbiAgICBvdmVycmlkZUhvb2tTdGF0ZVJlbmFtZVBhdGg6IG92ZXJyaWRlSG9va1N0YXRlUmVuYW1lUGF0aCxcbiAgICBvdmVycmlkZVByb3BzOiBvdmVycmlkZVByb3BzLFxuICAgIG92ZXJyaWRlUHJvcHNEZWxldGVQYXRoOiBvdmVycmlkZVByb3BzRGVsZXRlUGF0aCxcbiAgICBvdmVycmlkZVByb3BzUmVuYW1lUGF0aDogb3ZlcnJpZGVQcm9wc1JlbmFtZVBhdGgsXG4gICAgc2V0RXJyb3JIYW5kbGVyOiBzZXRFcnJvckhhbmRsZXIsXG4gICAgc2V0U3VzcGVuc2VIYW5kbGVyOiBzZXRTdXNwZW5zZUhhbmRsZXIsXG4gICAgc2NoZWR1bGVVcGRhdGU6IHNjaGVkdWxlVXBkYXRlLFxuICAgIGN1cnJlbnREaXNwYXRjaGVyUmVmOiBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLFxuICAgIGZpbmRIb3N0SW5zdGFuY2VCeUZpYmVyOiBmaW5kSG9zdEluc3RhbmNlQnlGaWJlcixcbiAgICBmaW5kRmliZXJCeUhvc3RJbnN0YW5jZTogZmluZEZpYmVyQnlIb3N0SW5zdGFuY2UgfHwgZW1wdHlGaW5kRmliZXJCeUhvc3RJbnN0YW5jZSxcbiAgICAvLyBSZWFjdCBSZWZyZXNoXG4gICAgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoOiAgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoICxcbiAgICBzY2hlZHVsZVJlZnJlc2g6ICBzY2hlZHVsZVJlZnJlc2ggLFxuICAgIHNjaGVkdWxlUm9vdDogIHNjaGVkdWxlUm9vdCAsXG4gICAgc2V0UmVmcmVzaEhhbmRsZXI6ICBzZXRSZWZyZXNoSGFuZGxlciAsXG4gICAgLy8gRW5hYmxlcyBEZXZUb29scyB0byBhcHBlbmQgb3duZXIgc3RhY2tzIHRvIGVycm9yIG1lc3NhZ2VzIGluIERFViBtb2RlLlxuICAgIGdldEN1cnJlbnRGaWJlcjogIGdldEN1cnJlbnRGaWJlckZvckRldlRvb2xzICxcbiAgICAvLyBFbmFibGVzIERldlRvb2xzIHRvIGRldGVjdCByZWNvbmNpbGVyIHZlcnNpb24gcmF0aGVyIHRoYW4gcmVuZGVyZXIgdmVyc2lvblxuICAgIC8vIHdoaWNoIG1heSBub3QgbWF0Y2ggZm9yIHRoaXJkIHBhcnR5IHJlbmRlcmVycy5cbiAgICByZWNvbmNpbGVyVmVyc2lvbjogUmVhY3RWZXJzaW9uXG4gIH0pO1xufVxuXG4vKiBnbG9iYWwgcmVwb3J0RXJyb3IgKi9cblxudmFyIGRlZmF1bHRPblJlY292ZXJhYmxlRXJyb3IgPSB0eXBlb2YgcmVwb3J0RXJyb3IgPT09ICdmdW5jdGlvbicgPyAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMsIHJlcG9ydEVycm9yIHdpbGwgZGlzcGF0Y2ggYW4gZXJyb3IgZXZlbnQsXG4vLyBlbXVsYXRpbmcgYW4gdW5jYXVnaHQgSmF2YVNjcmlwdCBlcnJvci5cbnJlcG9ydEVycm9yIDogZnVuY3Rpb24gKGVycm9yKSB7XG4gIC8vIEluIG9sZGVyIGJyb3dzZXJzIGFuZCB0ZXN0IGVudmlyb25tZW50cywgZmFsbGJhY2sgdG8gY29uc29sZS5lcnJvci5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuICBjb25zb2xlWydlcnJvciddKGVycm9yKTtcbn07XG5cbmZ1bmN0aW9uIFJlYWN0RE9NUm9vdChpbnRlcm5hbFJvb3QpIHtcbiAgdGhpcy5faW50ZXJuYWxSb290ID0gaW50ZXJuYWxSb290O1xufVxuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnJlbmRlciA9IFJlYWN0RE9NUm9vdC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gIHZhciByb290ID0gdGhpcy5faW50ZXJuYWxSb290O1xuXG4gIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdXBkYXRlIGFuIHVubW91bnRlZCByb290LicpO1xuICB9XG5cbiAge1xuICAgIGlmICh0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcigncmVuZGVyKC4uLik6IGRvZXMgbm90IHN1cHBvcnQgdGhlIHNlY29uZCBjYWxsYmFjayBhcmd1bWVudC4gJyArICdUbyBleGVjdXRlIGEgc2lkZSBlZmZlY3QgYWZ0ZXIgcmVuZGVyaW5nLCBkZWNsYXJlIGl0IGluIGEgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9IGVsc2UgaWYgKGlzVmFsaWRDb250YWluZXIoYXJndW1lbnRzWzFdKSkge1xuICAgICAgZXJyb3IoJ1lvdSBwYXNzZWQgYSBjb250YWluZXIgdG8gdGhlIHNlY29uZCBhcmd1bWVudCBvZiByb290LnJlbmRlciguLi4pLiAnICsgXCJZb3UgZG9uJ3QgbmVlZCB0byBwYXNzIGl0IGFnYWluIHNpbmNlIHlvdSBhbHJlYWR5IHBhc3NlZCBpdCB0byBjcmVhdGUgdGhlIHJvb3QuXCIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZ3VtZW50c1sxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGVycm9yKCdZb3UgcGFzc2VkIGEgc2Vjb25kIGFyZ3VtZW50IHRvIHJvb3QucmVuZGVyKC4uLikgYnV0IGl0IG9ubHkgYWNjZXB0cyAnICsgJ29uZSBhcmd1bWVudC4nKTtcbiAgICB9XG5cbiAgICB2YXIgY29udGFpbmVyID0gcm9vdC5jb250YWluZXJJbmZvO1xuXG4gICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgaG9zdEluc3RhbmNlID0gZmluZEhvc3RJbnN0YW5jZVdpdGhOb1BvcnRhbHMocm9vdC5jdXJyZW50KTtcblxuICAgICAgaWYgKGhvc3RJbnN0YW5jZSkge1xuICAgICAgICBpZiAoaG9zdEluc3RhbmNlLnBhcmVudE5vZGUgIT09IGNvbnRhaW5lcikge1xuICAgICAgICAgIGVycm9yKCdyZW5kZXIoLi4uKTogSXQgbG9va3MgbGlrZSB0aGUgUmVhY3QtcmVuZGVyZWQgY29udGVudCBvZiB0aGUgJyArICdyb290IGNvbnRhaW5lciB3YXMgcmVtb3ZlZCB3aXRob3V0IHVzaW5nIFJlYWN0LiBUaGlzIGlzIG5vdCAnICsgJ3N1cHBvcnRlZCBhbmQgd2lsbCBjYXVzZSBlcnJvcnMuIEluc3RlYWQsIGNhbGwgJyArIFwicm9vdC51bm1vdW50KCkgdG8gZW1wdHkgYSByb290J3MgY29udGFpbmVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNvbnRhaW5lcihjaGlsZHJlbiwgcm9vdCwgbnVsbCwgbnVsbCk7XG59O1xuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnVubW91bnQgPSBSZWFjdERPTVJvb3QucHJvdG90eXBlLnVubW91bnQgPSBmdW5jdGlvbiAoKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ3VubW91bnQoLi4uKTogZG9lcyBub3Qgc3VwcG9ydCBhIGNhbGxiYWNrIGFyZ3VtZW50LiAnICsgJ1RvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciByZW5kZXJpbmcsIGRlY2xhcmUgaXQgaW4gYSBjb21wb25lbnQgYm9keSB3aXRoIHVzZUVmZmVjdCgpLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gdGhpcy5faW50ZXJuYWxSb290O1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgdGhpcy5faW50ZXJuYWxSb290ID0gbnVsbDtcbiAgICB2YXIgY29udGFpbmVyID0gcm9vdC5jb250YWluZXJJbmZvO1xuXG4gICAge1xuICAgICAgaWYgKGlzQWxyZWFkeVJlbmRlcmluZygpKSB7XG4gICAgICAgIGVycm9yKCdBdHRlbXB0ZWQgdG8gc3luY2hyb25vdXNseSB1bm1vdW50IGEgcm9vdCB3aGlsZSBSZWFjdCB3YXMgYWxyZWFkeSAnICsgJ3JlbmRlcmluZy4gUmVhY3QgY2Fubm90IGZpbmlzaCB1bm1vdW50aW5nIHRoZSByb290IHVudGlsIHRoZSAnICsgJ2N1cnJlbnQgcmVuZGVyIGhhcyBjb21wbGV0ZWQsIHdoaWNoIG1heSBsZWFkIHRvIGEgcmFjZSBjb25kaXRpb24uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHVwZGF0ZUNvbnRhaW5lcihudWxsLCByb290LCBudWxsLCBudWxsKTtcbiAgICB9KTtcbiAgICB1bm1hcmtDb250YWluZXJBc1Jvb3QoY29udGFpbmVyKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlUm9vdChjb250YWluZXIsIG9wdGlvbnMpIHtcbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyKGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyZWF0ZVJvb3QoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHdhcm5JZlJlYWN0RE9NQ29udGFpbmVySW5ERVYoY29udGFpbmVyKTtcbiAgdmFyIGlzU3RyaWN0TW9kZSA9IGZhbHNlO1xuICB2YXIgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSA9IGZhbHNlO1xuICB2YXIgaWRlbnRpZmllclByZWZpeCA9ICcnO1xuICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gZGVmYXVsdE9uUmVjb3ZlcmFibGVFcnJvcjtcbiAgdmFyIHRyYW5zaXRpb25DYWxsYmFja3MgPSBudWxsO1xuXG4gIGlmIChvcHRpb25zICE9PSBudWxsICYmIG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgIHtcbiAgICAgIGlmIChvcHRpb25zLmh5ZHJhdGUpIHtcbiAgICAgICAgd2FybignaHlkcmF0ZSB0aHJvdWdoIGNyZWF0ZVJvb3QgaXMgZGVwcmVjYXRlZC4gVXNlIFJlYWN0RE9NQ2xpZW50Lmh5ZHJhdGVSb290KGNvbnRhaW5lciwgPEFwcCAvPikgaW5zdGVhZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCAmJiBvcHRpb25zLiQkdHlwZW9mID09PSBSRUFDVF9FTEVNRU5UX1RZUEUpIHtcbiAgICAgICAgICBlcnJvcignWW91IHBhc3NlZCBhIEpTWCBlbGVtZW50IHRvIGNyZWF0ZVJvb3QuIFlvdSBwcm9iYWJseSBtZWFudCB0byAnICsgJ2NhbGwgcm9vdC5yZW5kZXIgaW5zdGVhZC4gJyArICdFeGFtcGxlIHVzYWdlOlxcblxcbicgKyAnICBsZXQgcm9vdCA9IGNyZWF0ZVJvb3QoZG9tQ29udGFpbmVyKTtcXG4nICsgJyAgcm9vdC5yZW5kZXIoPEFwcCAvPik7Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy51bnN0YWJsZV9zdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBpc1N0cmljdE1vZGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmlkZW50aWZpZXJQcmVmaXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWRlbnRpZmllclByZWZpeCA9IG9wdGlvbnMuaWRlbnRpZmllclByZWZpeDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb25SZWNvdmVyYWJsZUVycm9yID0gb3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudHJhbnNpdGlvbkNhbGxiYWNrcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0cmFuc2l0aW9uQ2FsbGJhY2tzID0gb3B0aW9ucy50cmFuc2l0aW9uQ2FsbGJhY2tzO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lciwgQ29uY3VycmVudFJvb3QsIG51bGwsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG4gIHZhciByb290Q29udGFpbmVyRWxlbWVudCA9IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFID8gY29udGFpbmVyLnBhcmVudE5vZGUgOiBjb250YWluZXI7XG4gIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHJvb3RDb250YWluZXJFbGVtZW50KTtcbiAgcmV0dXJuIG5ldyBSZWFjdERPTVJvb3Qocm9vdCk7XG59XG5cbmZ1bmN0aW9uIFJlYWN0RE9NSHlkcmF0aW9uUm9vdChpbnRlcm5hbFJvb3QpIHtcbiAgdGhpcy5faW50ZXJuYWxSb290ID0gaW50ZXJuYWxSb290O1xufVxuXG5mdW5jdGlvbiBzY2hlZHVsZUh5ZHJhdGlvbih0YXJnZXQpIHtcbiAgaWYgKHRhcmdldCkge1xuICAgIHF1ZXVlRXhwbGljaXRIeWRyYXRpb25UYXJnZXQodGFyZ2V0KTtcbiAgfVxufVxuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnVuc3RhYmxlX3NjaGVkdWxlSHlkcmF0aW9uID0gc2NoZWR1bGVIeWRyYXRpb247XG5mdW5jdGlvbiBoeWRyYXRlUm9vdChjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgb3B0aW9ucykge1xuICBpZiAoIWlzVmFsaWRDb250YWluZXIoY29udGFpbmVyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaHlkcmF0ZVJvb3QoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHdhcm5JZlJlYWN0RE9NQ29udGFpbmVySW5ERVYoY29udGFpbmVyKTtcblxuICB7XG4gICAgaWYgKGluaXRpYWxDaGlsZHJlbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvcignTXVzdCBwcm92aWRlIGluaXRpYWwgY2hpbGRyZW4gYXMgc2Vjb25kIGFyZ3VtZW50IHRvIGh5ZHJhdGVSb290LiAnICsgJ0V4YW1wbGUgdXNhZ2U6IGh5ZHJhdGVSb290KGRvbUNvbnRhaW5lciwgPEFwcCAvPiknKTtcbiAgICB9XG4gIH0gLy8gRm9yIG5vdyB3ZSByZXVzZSB0aGUgd2hvbGUgYmFnIG9mIG9wdGlvbnMgc2luY2UgdGhleSBjb250YWluXG4gIC8vIHRoZSBoeWRyYXRpb24gY2FsbGJhY2tzLlxuXG5cbiAgdmFyIGh5ZHJhdGlvbkNhbGxiYWNrcyA9IG9wdGlvbnMgIT0gbnVsbCA/IG9wdGlvbnMgOiBudWxsOyAvLyBUT0RPOiBEZWxldGUgdGhpcyBvcHRpb25cblxuICB2YXIgbXV0YWJsZVNvdXJjZXMgPSBvcHRpb25zICE9IG51bGwgJiYgb3B0aW9ucy5oeWRyYXRlZFNvdXJjZXMgfHwgbnVsbDtcbiAgdmFyIGlzU3RyaWN0TW9kZSA9IGZhbHNlO1xuICB2YXIgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSA9IGZhbHNlO1xuICB2YXIgaWRlbnRpZmllclByZWZpeCA9ICcnO1xuICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gZGVmYXVsdE9uUmVjb3ZlcmFibGVFcnJvcjtcblxuICBpZiAob3B0aW9ucyAhPT0gbnVsbCAmJiBvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAob3B0aW9ucy51bnN0YWJsZV9zdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBpc1N0cmljdE1vZGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmlkZW50aWZpZXJQcmVmaXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWRlbnRpZmllclByZWZpeCA9IG9wdGlvbnMuaWRlbnRpZmllclByZWZpeDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb25SZWNvdmVyYWJsZUVycm9yID0gb3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3I7XG4gICAgfVxuICB9XG5cbiAgdmFyIHJvb3QgPSBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCBudWxsLCBjb250YWluZXIsIENvbmN1cnJlbnRSb290LCBoeWRyYXRpb25DYWxsYmFja3MsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7IC8vIFRoaXMgY2FuJ3QgYmUgYSBjb21tZW50IG5vZGUgc2luY2UgaHlkcmF0aW9uIGRvZXNuJ3Qgd29yayBvbiBjb21tZW50IG5vZGVzIGFueXdheS5cblxuICBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhjb250YWluZXIpO1xuXG4gIGlmIChtdXRhYmxlU291cmNlcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXV0YWJsZVNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBtdXRhYmxlU291cmNlID0gbXV0YWJsZVNvdXJjZXNbaV07XG4gICAgICByZWdpc3Rlck11dGFibGVTb3VyY2VGb3JIeWRyYXRpb24ocm9vdCwgbXV0YWJsZVNvdXJjZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWFjdERPTUh5ZHJhdGlvblJvb3Qocm9vdCk7XG59XG5mdW5jdGlvbiBpc1ZhbGlkQ29udGFpbmVyKG5vZGUpIHtcbiAgcmV0dXJuICEhKG5vZGUgJiYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgIWRpc2FibGVDb21tZW50c0FzRE9NQ29udGFpbmVycyAgKSk7XG59IC8vIFRPRE86IFJlbW92ZSB0aGlzIGZ1bmN0aW9uIHdoaWNoIGFsc28gaW5jbHVkZXMgY29tbWVudCBub2Rlcy5cbi8vIFdlIG9ubHkgdXNlIGl0IGluIHBsYWNlcyB0aGF0IGFyZSBjdXJyZW50bHkgbW9yZSByZWxheGVkLlxuXG5mdW5jdGlvbiBpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KG5vZGUpIHtcbiAgcmV0dXJuICEhKG5vZGUgJiYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgbm9kZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFICYmIG5vZGUubm9kZVZhbHVlID09PSAnIHJlYWN0LW1vdW50LXBvaW50LXVuc3RhYmxlICcpKTtcbn1cblxuZnVuY3Rpb24gd2FybklmUmVhY3RET01Db250YWluZXJJbkRFVihjb250YWluZXIpIHtcbiAge1xuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSAmJiBjb250YWluZXIudGFnTmFtZSAmJiBjb250YWluZXIudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSAnQk9EWScpIHtcbiAgICAgIGVycm9yKCdjcmVhdGVSb290KCk6IENyZWF0aW5nIHJvb3RzIGRpcmVjdGx5IHdpdGggZG9jdW1lbnQuYm9keSBpcyAnICsgJ2Rpc2NvdXJhZ2VkLCBzaW5jZSBpdHMgY2hpbGRyZW4gYXJlIG9mdGVuIG1hbmlwdWxhdGVkIGJ5IHRoaXJkLXBhcnR5ICcgKyAnc2NyaXB0cyBhbmQgYnJvd3NlciBleHRlbnNpb25zLiBUaGlzIG1heSBsZWFkIHRvIHN1YnRsZSAnICsgJ3JlY29uY2lsaWF0aW9uIGlzc3Vlcy4gVHJ5IHVzaW5nIGEgY29udGFpbmVyIGVsZW1lbnQgY3JlYXRlZCAnICsgJ2ZvciB5b3VyIGFwcC4nKTtcbiAgICB9XG5cbiAgICBpZiAoaXNDb250YWluZXJNYXJrZWRBc1Jvb3QoY29udGFpbmVyKSkge1xuICAgICAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyKSB7XG4gICAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpIG9uIGEgY29udGFpbmVyIHRoYXQgd2FzIHByZXZpb3VzbHkgJyArICdwYXNzZWQgdG8gUmVhY3RET00ucmVuZGVyKCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpIG9uIGEgY29udGFpbmVyIHRoYXQgJyArICdoYXMgYWxyZWFkeSBiZWVuIHBhc3NlZCB0byBjcmVhdGVSb290KCkgYmVmb3JlLiBJbnN0ZWFkLCBjYWxsICcgKyAncm9vdC5yZW5kZXIoKSBvbiB0aGUgZXhpc3Rpbmcgcm9vdCBpbnN0ZWFkIGlmIHlvdSB3YW50IHRvIHVwZGF0ZSBpdC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudE93bmVyJDMgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciB0b3BMZXZlbFVwZGF0ZVdhcm5pbmdzO1xuXG57XG4gIHRvcExldmVsVXBkYXRlV2FybmluZ3MgPSBmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyICYmIGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgaG9zdEluc3RhbmNlID0gZmluZEhvc3RJbnN0YW5jZVdpdGhOb1BvcnRhbHMoY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIuY3VycmVudCk7XG5cbiAgICAgIGlmIChob3N0SW5zdGFuY2UpIHtcbiAgICAgICAgaWYgKGhvc3RJbnN0YW5jZS5wYXJlbnROb2RlICE9PSBjb250YWluZXIpIHtcbiAgICAgICAgICBlcnJvcigncmVuZGVyKC4uLik6IEl0IGxvb2tzIGxpa2UgdGhlIFJlYWN0LXJlbmRlcmVkIGNvbnRlbnQgb2YgdGhpcyAnICsgJ2NvbnRhaW5lciB3YXMgcmVtb3ZlZCB3aXRob3V0IHVzaW5nIFJlYWN0LiBUaGlzIGlzIG5vdCAnICsgJ3N1cHBvcnRlZCBhbmQgd2lsbCBjYXVzZSBlcnJvcnMuIEluc3RlYWQsIGNhbGwgJyArICdSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlIHRvIGVtcHR5IGEgY29udGFpbmVyLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGlzUm9vdFJlbmRlcmVkQnlTb21lUmVhY3QgPSAhIWNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyO1xuICAgIHZhciByb290RWwgPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcbiAgICB2YXIgaGFzTm9uUm9vdFJlYWN0Q2hpbGQgPSAhIShyb290RWwgJiYgZ2V0SW5zdGFuY2VGcm9tTm9kZShyb290RWwpKTtcblxuICAgIGlmIChoYXNOb25Sb290UmVhY3RDaGlsZCAmJiAhaXNSb290UmVuZGVyZWRCeVNvbWVSZWFjdCkge1xuICAgICAgZXJyb3IoJ3JlbmRlciguLi4pOiBSZXBsYWNpbmcgUmVhY3QtcmVuZGVyZWQgY2hpbGRyZW4gd2l0aCBhIG5ldyByb290ICcgKyAnY29tcG9uZW50LiBJZiB5b3UgaW50ZW5kZWQgdG8gdXBkYXRlIHRoZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUsICcgKyAneW91IHNob3VsZCBpbnN0ZWFkIGhhdmUgdGhlIGV4aXN0aW5nIGNoaWxkcmVuIHVwZGF0ZSB0aGVpciBzdGF0ZSAnICsgJ2FuZCByZW5kZXIgdGhlIG5ldyBjb21wb25lbnRzIGluc3RlYWQgb2YgY2FsbGluZyBSZWFjdERPTS5yZW5kZXIuJyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFICYmIGNvbnRhaW5lci50YWdOYW1lICYmIGNvbnRhaW5lci50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdCT0RZJykge1xuICAgICAgZXJyb3IoJ3JlbmRlcigpOiBSZW5kZXJpbmcgY29tcG9uZW50cyBkaXJlY3RseSBpbnRvIGRvY3VtZW50LmJvZHkgaXMgJyArICdkaXNjb3VyYWdlZCwgc2luY2UgaXRzIGNoaWxkcmVuIGFyZSBvZnRlbiBtYW5pcHVsYXRlZCBieSB0aGlyZC1wYXJ0eSAnICsgJ3NjcmlwdHMgYW5kIGJyb3dzZXIgZXh0ZW5zaW9ucy4gVGhpcyBtYXkgbGVhZCB0byBzdWJ0bGUgJyArICdyZWNvbmNpbGlhdGlvbiBpc3N1ZXMuIFRyeSByZW5kZXJpbmcgaW50byBhIGNvbnRhaW5lciBlbGVtZW50IGNyZWF0ZWQgJyArICdmb3IgeW91ciBhcHAuJyk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKSB7XG4gIGlmICghY29udGFpbmVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5kb2N1bWVudEVsZW1lbnQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5maXJzdENoaWxkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vb3BPblJlY292ZXJhYmxlRXJyb3IoKSB7Ly8gVGhpcyBpc24ndCByZWFjaGFibGUgYmVjYXVzZSBvblJlY292ZXJhYmxlRXJyb3IgaXNuJ3QgY2FsbGVkIGluIHRoZVxuICAvLyBsZWdhY3kgQVBJLlxufVxuXG5mdW5jdGlvbiBsZWdhY3lDcmVhdGVSb290RnJvbURPTUNvbnRhaW5lcihjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBjYWxsYmFjaywgaXNIeWRyYXRpb25Db250YWluZXIpIHtcbiAgaWYgKGlzSHlkcmF0aW9uQ29udGFpbmVyKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIG9yaWdpbmFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFB1YmxpY1Jvb3RJbnN0YW5jZShyb290KTtcbiAgICAgICAgb3JpZ2luYWxDYWxsYmFjay5jYWxsKGluc3RhbmNlKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCBjYWxsYmFjaywgY29udGFpbmVyLCBMZWdhY3lSb290LCBudWxsLCAvLyBoeWRyYXRpb25DYWxsYmFja3NcbiAgICBmYWxzZSwgLy8gaXNTdHJpY3RNb2RlXG4gICAgZmFsc2UsIC8vIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsXG4gICAgJycsIC8vIGlkZW50aWZpZXJQcmVmaXhcbiAgICBub29wT25SZWNvdmVyYWJsZUVycm9yKTtcbiAgICBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lciA9IHJvb3Q7XG4gICAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG4gICAgdmFyIHJvb3RDb250YWluZXJFbGVtZW50ID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lcjtcbiAgICBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhyb290Q29udGFpbmVyRWxlbWVudCk7XG4gICAgZmx1c2hTeW5jKCk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH0gZWxzZSB7XG4gICAgLy8gRmlyc3QgY2xlYXIgYW55IGV4aXN0aW5nIGNvbnRlbnQuXG4gICAgdmFyIHJvb3RTaWJsaW5nO1xuXG4gICAgd2hpbGUgKHJvb3RTaWJsaW5nID0gY29udGFpbmVyLmxhc3RDaGlsZCkge1xuICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHJvb3RTaWJsaW5nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgX29yaWdpbmFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFB1YmxpY1Jvb3RJbnN0YW5jZShfcm9vdCk7XG5cbiAgICAgICAgX29yaWdpbmFsQ2FsbGJhY2suY2FsbChpbnN0YW5jZSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBfcm9vdCA9IGNyZWF0ZUNvbnRhaW5lcihjb250YWluZXIsIExlZ2FjeVJvb3QsIG51bGwsIC8vIGh5ZHJhdGlvbkNhbGxiYWNrc1xuICAgIGZhbHNlLCAvLyBpc1N0cmljdE1vZGVcbiAgICBmYWxzZSwgLy8gY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSxcbiAgICAnJywgLy8gaWRlbnRpZmllclByZWZpeFxuICAgIG5vb3BPblJlY292ZXJhYmxlRXJyb3IpO1xuXG4gICAgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPSBfcm9vdDtcbiAgICBtYXJrQ29udGFpbmVyQXNSb290KF9yb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG5cbiAgICB2YXIgX3Jvb3RDb250YWluZXJFbGVtZW50ID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lcjtcblxuICAgIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKF9yb290Q29udGFpbmVyRWxlbWVudCk7IC8vIEluaXRpYWwgbW91bnQgc2hvdWxkIG5vdCBiZSBiYXRjaGVkLlxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHVwZGF0ZUNvbnRhaW5lcihpbml0aWFsQ2hpbGRyZW4sIF9yb290LCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgICByZXR1cm4gX3Jvb3Q7XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybk9uSW52YWxpZENhbGxiYWNrJDEoY2FsbGJhY2ssIGNhbGxlck5hbWUpIHtcbiAge1xuICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCAmJiB0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclcyguLi4pOiBFeHBlY3RlZCB0aGUgbGFzdCBvcHRpb25hbCBgY2FsbGJhY2tgIGFyZ3VtZW50IHRvIGJlIGEgJyArICdmdW5jdGlvbi4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY2FsbGVyTmFtZSwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBsZWdhY3lSZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcihwYXJlbnRDb21wb25lbnQsIGNoaWxkcmVuLCBjb250YWluZXIsIGZvcmNlSHlkcmF0ZSwgY2FsbGJhY2spIHtcbiAge1xuICAgIHRvcExldmVsVXBkYXRlV2FybmluZ3MoY29udGFpbmVyKTtcbiAgICB3YXJuT25JbnZhbGlkQ2FsbGJhY2skMShjYWxsYmFjayA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGNhbGxiYWNrLCAncmVuZGVyJyk7XG4gIH1cblxuICB2YXIgbWF5YmVSb290ID0gY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXI7XG4gIHZhciByb290O1xuXG4gIGlmICghbWF5YmVSb290KSB7XG4gICAgLy8gSW5pdGlhbCBtb3VudFxuICAgIHJvb3QgPSBsZWdhY3lDcmVhdGVSb290RnJvbURPTUNvbnRhaW5lcihjb250YWluZXIsIGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrLCBmb3JjZUh5ZHJhdGUpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QgPSBtYXliZVJvb3Q7XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgb3JpZ2luYWxDYWxsYmFjayA9IGNhbGxiYWNrO1xuXG4gICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gZ2V0UHVibGljUm9vdEluc3RhbmNlKHJvb3QpO1xuICAgICAgICBvcmlnaW5hbENhbGxiYWNrLmNhbGwoaW5zdGFuY2UpO1xuICAgICAgfTtcbiAgICB9IC8vIFVwZGF0ZVxuXG5cbiAgICB1cGRhdGVDb250YWluZXIoY2hpbGRyZW4sIHJvb3QsIHBhcmVudENvbXBvbmVudCwgY2FsbGJhY2spO1xuICB9XG5cbiAgcmV0dXJuIGdldFB1YmxpY1Jvb3RJbnN0YW5jZShyb290KTtcbn1cblxuZnVuY3Rpb24gZmluZERPTU5vZGUoY29tcG9uZW50T3JFbGVtZW50KSB7XG4gIHtcbiAgICB2YXIgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lciQzLmN1cnJlbnQ7XG5cbiAgICBpZiAob3duZXIgIT09IG51bGwgJiYgb3duZXIuc3RhdGVOb2RlICE9PSBudWxsKSB7XG4gICAgICB2YXIgd2FybmVkQWJvdXRSZWZzSW5SZW5kZXIgPSBvd25lci5zdGF0ZU5vZGUuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyO1xuXG4gICAgICBpZiAoIXdhcm5lZEFib3V0UmVmc0luUmVuZGVyKSB7XG4gICAgICAgIGVycm9yKCclcyBpcyBhY2Nlc3NpbmcgZmluZERPTU5vZGUgaW5zaWRlIGl0cyByZW5kZXIoKS4gJyArICdyZW5kZXIoKSBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4gSXQgc2hvdWxkICcgKyAnbmV2ZXIgYWNjZXNzIHNvbWV0aGluZyB0aGF0IHJlcXVpcmVzIHN0YWxlIGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgJyArICdyZW5kZXIsIHN1Y2ggYXMgcmVmcy4gTW92ZSB0aGlzIGxvZ2ljIHRvIGNvbXBvbmVudERpZE1vdW50IGFuZCAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZSBpbnN0ZWFkLicsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShvd25lci50eXBlKSB8fCAnQSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgb3duZXIuc3RhdGVOb2RlLl93YXJuZWRBYm91dFJlZnNJblJlbmRlciA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbXBvbmVudE9yRWxlbWVudCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoY29tcG9uZW50T3JFbGVtZW50Lm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gY29tcG9uZW50T3JFbGVtZW50O1xuICB9XG5cbiAge1xuICAgIHJldHVybiBmaW5kSG9zdEluc3RhbmNlV2l0aFdhcm5pbmcoY29tcG9uZW50T3JFbGVtZW50LCAnZmluZERPTU5vZGUnKTtcbiAgfVxufVxuZnVuY3Rpb24gaHlkcmF0ZShlbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gIHtcbiAgICBlcnJvcignUmVhY3RET00uaHlkcmF0ZSBpcyBubyBsb25nZXIgc3VwcG9ydGVkIGluIFJlYWN0IDE4LiBVc2UgaHlkcmF0ZVJvb3QgJyArICdpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvIHRoZSBuZXcgQVBJLCB5b3VyIGFwcCB3aWxsIGJlaGF2ZSBhcyAnICsgXCJpZiBpdCdzIHJ1bm5pbmcgUmVhY3QgMTcuIExlYXJuIFwiICsgJ21vcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zd2l0Y2gtdG8tY3JlYXRlcm9vdCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJyk7XG4gIH1cblxuICB7XG4gICAgdmFyIGlzTW9kZXJuUm9vdCA9IGlzQ29udGFpbmVyTWFya2VkQXNSb290KGNvbnRhaW5lcikgJiYgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc01vZGVyblJvb3QpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET00uaHlkcmF0ZSgpIG9uIGEgY29udGFpbmVyIHRoYXQgd2FzIHByZXZpb3VzbHkgJyArICdwYXNzZWQgdG8gUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpLiBUaGlzIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnRGlkIHlvdSBtZWFuIHRvIGNhbGwgaHlkcmF0ZVJvb3QoY29udGFpbmVyLCBlbGVtZW50KT8nKTtcbiAgICB9XG4gIH0gLy8gVE9ETzogdGhyb3cgb3Igd2FybiBpZiB3ZSBjb3VsZG4ndCBoeWRyYXRlP1xuXG5cbiAgcmV0dXJuIGxlZ2FjeVJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIGVsZW1lbnQsIGNvbnRhaW5lciwgdHJ1ZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gcmVuZGVyKGVsZW1lbnQsIGNvbnRhaW5lciwgY2FsbGJhY2spIHtcbiAge1xuICAgIGVycm9yKCdSZWFjdERPTS5yZW5kZXIgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCBpbiBSZWFjdCAxOC4gVXNlIGNyZWF0ZVJvb3QgJyArICdpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvIHRoZSBuZXcgQVBJLCB5b3VyIGFwcCB3aWxsIGJlaGF2ZSBhcyAnICsgXCJpZiBpdCdzIHJ1bm5pbmcgUmVhY3QgMTcuIExlYXJuIFwiICsgJ21vcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zd2l0Y2gtdG8tY3JlYXRlcm9vdCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJyk7XG4gIH1cblxuICB7XG4gICAgdmFyIGlzTW9kZXJuUm9vdCA9IGlzQ29udGFpbmVyTWFya2VkQXNSb290KGNvbnRhaW5lcikgJiYgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc01vZGVyblJvb3QpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET00ucmVuZGVyKCkgb24gYSBjb250YWluZXIgdGhhdCB3YXMgcHJldmlvdXNseSAnICsgJ3Bhc3NlZCB0byBSZWFjdERPTUNsaWVudC5jcmVhdGVSb290KCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4gJyArICdEaWQgeW91IG1lYW4gdG8gY2FsbCByb290LnJlbmRlcihlbGVtZW50KT8nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbGVnYWN5UmVuZGVyU3VidHJlZUludG9Db250YWluZXIobnVsbCwgZWxlbWVudCwgY29udGFpbmVyLCBmYWxzZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gdW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjaykge1xuICB7XG4gICAgZXJyb3IoJ1JlYWN0RE9NLnVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKCkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCAnICsgJ2luIFJlYWN0IDE4LiBDb25zaWRlciB1c2luZyBhIHBvcnRhbCBpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvICcgKyBcInRoZSBjcmVhdGVSb290IEFQSSwgeW91ciBhcHAgd2lsbCBiZWhhdmUgYXMgaWYgaXQncyBydW5uaW5nIFJlYWN0IFwiICsgJzE3LiBMZWFybiBtb3JlOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3dpdGNoLXRvLWNyZWF0ZXJvb3QnKTtcbiAgfVxuXG4gIGlmICghaXNWYWxpZENvbnRhaW5lckxlZ2FjeShjb250YWluZXJOb2RlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIGlmIChwYXJlbnRDb21wb25lbnQgPT0gbnVsbCB8fCAhaGFzKHBhcmVudENvbXBvbmVudCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcmVudENvbXBvbmVudCBtdXN0IGJlIGEgdmFsaWQgUmVhY3QgQ29tcG9uZW50Jyk7XG4gIH1cblxuICByZXR1cm4gbGVnYWN5UmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBmYWxzZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gdW5tb3VudENvbXBvbmVudEF0Tm9kZShjb250YWluZXIpIHtcbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VubW91bnRDb21wb25lbnRBdE5vZGUoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHtcbiAgICB2YXIgaXNNb2Rlcm5Sb290ID0gaXNDb250YWluZXJNYXJrZWRBc1Jvb3QoY29udGFpbmVyKSAmJiBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lciA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGlzTW9kZXJuUm9vdCkge1xuICAgICAgZXJyb3IoJ1lvdSBhcmUgY2FsbGluZyBSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlKCkgb24gYSBjb250YWluZXIgdGhhdCB3YXMgcHJldmlvdXNseSAnICsgJ3Bhc3NlZCB0byBSZWFjdERPTUNsaWVudC5jcmVhdGVSb290KCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4gRGlkIHlvdSBtZWFuIHRvIGNhbGwgcm9vdC51bm1vdW50KCk/Jyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyKSB7XG4gICAge1xuICAgICAgdmFyIHJvb3RFbCA9IGdldFJlYWN0Um9vdEVsZW1lbnRJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgICAgdmFyIHJlbmRlcmVkQnlEaWZmZXJlbnRSZWFjdCA9IHJvb3RFbCAmJiAhZ2V0SW5zdGFuY2VGcm9tTm9kZShyb290RWwpO1xuXG4gICAgICBpZiAocmVuZGVyZWRCeURpZmZlcmVudFJlYWN0KSB7XG4gICAgICAgIGVycm9yKFwidW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBUaGUgbm9kZSB5b3UncmUgYXR0ZW1wdGluZyB0byB1bm1vdW50IFwiICsgJ3dhcyByZW5kZXJlZCBieSBhbm90aGVyIGNvcHkgb2YgUmVhY3QuJyk7XG4gICAgICB9XG4gICAgfSAvLyBVbm1vdW50IHNob3VsZCBub3QgYmUgYmF0Y2hlZC5cblxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIGxlZ2FjeVJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIG51bGwsIGNvbnRhaW5lciwgZmFsc2UsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZSBUaGlzIHNob3VsZCBwcm9iYWJseSB1c2UgYGRlbGV0ZSBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lcmBcbiAgICAgICAgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPSBudWxsO1xuICAgICAgICB1bm1hcmtDb250YWluZXJBc1Jvb3QoY29udGFpbmVyKTtcbiAgICAgIH0pO1xuICAgIH0pOyAvLyBJZiB5b3UgY2FsbCB1bm1vdW50Q29tcG9uZW50QXROb2RlIHR3aWNlIGluIHF1aWNrIHN1Y2Nlc3Npb24sIHlvdSdsbFxuICAgIC8vIGdldCBgdHJ1ZWAgdHdpY2UuIFRoYXQncyBwcm9iYWJseSBmaW5lP1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAge1xuICAgICAgdmFyIF9yb290RWwgPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcblxuICAgICAgdmFyIGhhc05vblJvb3RSZWFjdENoaWxkID0gISEoX3Jvb3RFbCAmJiBnZXRJbnN0YW5jZUZyb21Ob2RlKF9yb290RWwpKTsgLy8gQ2hlY2sgaWYgdGhlIGNvbnRhaW5lciBpdHNlbGYgaXMgYSBSZWFjdCByb290IG5vZGUuXG5cbiAgICAgIHZhciBpc0NvbnRhaW5lclJlYWN0Um9vdCA9IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFICYmIGlzVmFsaWRDb250YWluZXJMZWdhY3koY29udGFpbmVyLnBhcmVudE5vZGUpICYmICEhY29udGFpbmVyLnBhcmVudE5vZGUuX3JlYWN0Um9vdENvbnRhaW5lcjtcblxuICAgICAgaWYgKGhhc05vblJvb3RSZWFjdENoaWxkKSB7XG4gICAgICAgIGVycm9yKFwidW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBUaGUgbm9kZSB5b3UncmUgYXR0ZW1wdGluZyB0byB1bm1vdW50IFwiICsgJ3dhcyByZW5kZXJlZCBieSBSZWFjdCBhbmQgaXMgbm90IGEgdG9wLWxldmVsIGNvbnRhaW5lci4gJXMnLCBpc0NvbnRhaW5lclJlYWN0Um9vdCA/ICdZb3UgbWF5IGhhdmUgYWNjaWRlbnRhbGx5IHBhc3NlZCBpbiBhIFJlYWN0IHJvb3Qgbm9kZSBpbnN0ZWFkICcgKyAnb2YgaXRzIGNvbnRhaW5lci4nIDogJ0luc3RlYWQsIGhhdmUgdGhlIHBhcmVudCBjb21wb25lbnQgdXBkYXRlIGl0cyBzdGF0ZSBhbmQgJyArICdyZXJlbmRlciBpbiBvcmRlciB0byByZW1vdmUgdGhpcyBjb21wb25lbnQuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbnNldEF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihhdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24kMSk7XG5zZXRBdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbihhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbiQxKTtcbnNldEF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eShhdHRlbXB0SHlkcmF0aW9uQXRDdXJyZW50UHJpb3JpdHkkMSk7XG5zZXRHZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KTtcbnNldEF0dGVtcHRIeWRyYXRpb25BdFByaW9yaXR5KHJ1bldpdGhQcmlvcml0eSk7XG5cbntcbiAgaWYgKHR5cGVvZiBNYXAgIT09ICdmdW5jdGlvbicgfHwgLy8gJEZsb3dJc3N1ZSBGbG93IGluY29ycmVjdGx5IHRoaW5rcyBNYXAgaGFzIG5vIHByb3RvdHlwZVxuICBNYXAucHJvdG90eXBlID09IG51bGwgfHwgdHlwZW9mIE1hcC5wcm90b3R5cGUuZm9yRWFjaCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgU2V0ICE9PSAnZnVuY3Rpb24nIHx8IC8vICRGbG93SXNzdWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgU2V0IGhhcyBubyBwcm90b3R5cGVcbiAgU2V0LnByb3RvdHlwZSA9PSBudWxsIHx8IHR5cGVvZiBTZXQucHJvdG90eXBlLmNsZWFyICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBTZXQucHJvdG90eXBlLmZvckVhY2ggIT09ICdmdW5jdGlvbicpIHtcbiAgICBlcnJvcignUmVhY3QgZGVwZW5kcyBvbiBNYXAgYW5kIFNldCBidWlsdC1pbiB0eXBlcy4gTWFrZSBzdXJlIHRoYXQgeW91IGxvYWQgYSAnICsgJ3BvbHlmaWxsIGluIG9sZGVyIGJyb3dzZXJzLiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVhY3QtcG9seWZpbGxzJyk7XG4gIH1cbn1cblxuc2V0UmVzdG9yZUltcGxlbWVudGF0aW9uKHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMyk7XG5zZXRCYXRjaGluZ0ltcGxlbWVudGF0aW9uKGJhdGNoZWRVcGRhdGVzJDEsIGRpc2NyZXRlVXBkYXRlcywgZmx1c2hTeW5jKTtcblxuZnVuY3Rpb24gY3JlYXRlUG9ydGFsJDEoY2hpbGRyZW4sIGNvbnRhaW5lcikge1xuICB2YXIga2V5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBudWxsO1xuXG4gIGlmICghaXNWYWxpZENvbnRhaW5lcihjb250YWluZXIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUYXJnZXQgY29udGFpbmVyIGlzIG5vdCBhIERPTSBlbGVtZW50LicpO1xuICB9IC8vIFRPRE86IHBhc3MgUmVhY3RET00gcG9ydGFsIGltcGxlbWVudGF0aW9uIGFzIHRoaXJkIGFyZ3VtZW50XG4gIC8vICRGbG93Rml4TWUgVGhlIEZsb3cgdHlwZSBpcyBvcGFxdWUgYnV0IHRoZXJlJ3Mgbm8gd2F5IHRvIGFjdHVhbGx5IGNyZWF0ZSBpdC5cblxuXG4gIHJldHVybiBjcmVhdGVQb3J0YWwoY2hpbGRyZW4sIGNvbnRhaW5lciwgbnVsbCwga2V5KTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjayk7XG59XG5cbnZhciBJbnRlcm5hbHMgPSB7XG4gIHVzaW5nQ2xpZW50RW50cnlQb2ludDogZmFsc2UsXG4gIC8vIEtlZXAgaW4gc3luYyB3aXRoIFJlYWN0VGVzdFV0aWxzLmpzLlxuICAvLyBUaGlzIGlzIGFuIGFycmF5IGZvciBiZXR0ZXIgbWluaWZpY2F0aW9uLlxuICBFdmVudHM6IFtnZXRJbnN0YW5jZUZyb21Ob2RlLCBnZXROb2RlRnJvbUluc3RhbmNlLCBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlLCBlbnF1ZXVlU3RhdGVSZXN0b3JlLCByZXN0b3JlU3RhdGVJZk5lZWRlZCwgYmF0Y2hlZFVwZGF0ZXMkMV1cbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVJvb3QkMShjb250YWluZXIsIG9wdGlvbnMpIHtcbiAge1xuICAgIGlmICghSW50ZXJuYWxzLnVzaW5nQ2xpZW50RW50cnlQb2ludCAmJiAhZmFsc2UpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGltcG9ydGluZyBjcmVhdGVSb290IGZyb20gXCJyZWFjdC1kb21cIiB3aGljaCBpcyBub3Qgc3VwcG9ydGVkLiAnICsgJ1lvdSBzaG91bGQgaW5zdGVhZCBpbXBvcnQgaXQgZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIi4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3JlYXRlUm9vdChjb250YWluZXIsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBoeWRyYXRlUm9vdCQxKGNvbnRhaW5lciwgaW5pdGlhbENoaWxkcmVuLCBvcHRpb25zKSB7XG4gIHtcbiAgICBpZiAoIUludGVybmFscy51c2luZ0NsaWVudEVudHJ5UG9pbnQgJiYgIWZhbHNlKSB7XG4gICAgICBlcnJvcignWW91IGFyZSBpbXBvcnRpbmcgaHlkcmF0ZVJvb3QgZnJvbSBcInJlYWN0LWRvbVwiIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnWW91IHNob3VsZCBpbnN0ZWFkIGltcG9ydCBpdCBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoeWRyYXRlUm9vdChjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgb3B0aW9ucyk7XG59IC8vIE92ZXJsb2FkIHRoZSBkZWZpbml0aW9uIHRvIHRoZSB0d28gdmFsaWQgc2lnbmF0dXJlcy5cbi8vIFdhcm5pbmcsIHRoaXMgb3B0cy1vdXQgb2YgY2hlY2tpbmcgdGhlIGZ1bmN0aW9uIGJvZHkuXG5cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuZnVuY3Rpb24gZmx1c2hTeW5jJDEoZm4pIHtcbiAge1xuICAgIGlmIChpc0FscmVhZHlSZW5kZXJpbmcoKSkge1xuICAgICAgZXJyb3IoJ2ZsdXNoU3luYyB3YXMgY2FsbGVkIGZyb20gaW5zaWRlIGEgbGlmZWN5Y2xlIG1ldGhvZC4gUmVhY3QgY2Fubm90ICcgKyAnZmx1c2ggd2hlbiBSZWFjdCBpcyBhbHJlYWR5IHJlbmRlcmluZy4gQ29uc2lkZXIgbW92aW5nIHRoaXMgY2FsbCB0byAnICsgJ2Egc2NoZWR1bGVyIHRhc2sgb3IgbWljcm8gdGFzay4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmx1c2hTeW5jKGZuKTtcbn1cbnZhciBmb3VuZERldlRvb2xzID0gaW5qZWN0SW50b0RldlRvb2xzKHtcbiAgZmluZEZpYmVyQnlIb3N0SW5zdGFuY2U6IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlLFxuICBidW5kbGVUeXBlOiAgMSAsXG4gIHZlcnNpb246IFJlYWN0VmVyc2lvbixcbiAgcmVuZGVyZXJQYWNrYWdlTmFtZTogJ3JlYWN0LWRvbSdcbn0pO1xuXG57XG4gIGlmICghZm91bmREZXZUb29scyAmJiBjYW5Vc2VET00gJiYgd2luZG93LnRvcCA9PT0gd2luZG93LnNlbGYpIHtcbiAgICAvLyBJZiB3ZSdyZSBpbiBDaHJvbWUgb3IgRmlyZWZveCwgcHJvdmlkZSBhIGRvd25sb2FkIGxpbmsgaWYgbm90IGluc3RhbGxlZC5cbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdDaHJvbWUnKSA+IC0xICYmIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpID09PSAtMSB8fCBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0ZpcmVmb3gnKSA+IC0xKSB7XG4gICAgICB2YXIgcHJvdG9jb2wgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2w7IC8vIERvbid0IHdhcm4gaW4gZXhvdGljIGNhc2VzIGxpa2UgY2hyb21lLWV4dGVuc2lvbjovLy5cblxuICAgICAgaWYgKC9eKGh0dHBzP3xmaWxlKTokLy50ZXN0KHByb3RvY29sKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG4gICAgICAgIGNvbnNvbGUuaW5mbygnJWNEb3dubG9hZCB0aGUgUmVhY3QgRGV2VG9vbHMgJyArICdmb3IgYSBiZXR0ZXIgZGV2ZWxvcG1lbnQgZXhwZXJpZW5jZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVhY3QtZGV2dG9vbHMnICsgKHByb3RvY29sID09PSAnZmlsZTonID8gJ1xcbllvdSBtaWdodCBuZWVkIHRvIHVzZSBhIGxvY2FsIEhUVFAgc2VydmVyIChpbnN0ZWFkIG9mIGZpbGU6Ly8pOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9yZWFjdC1kZXZ0b29scy1mYXEnIDogJycpLCAnZm9udC13ZWlnaHQ6Ym9sZCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnRzLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEID0gSW50ZXJuYWxzO1xuZXhwb3J0cy5jcmVhdGVQb3J0YWwgPSBjcmVhdGVQb3J0YWwkMTtcbmV4cG9ydHMuY3JlYXRlUm9vdCA9IGNyZWF0ZVJvb3QkMTtcbmV4cG9ydHMuZmluZERPTU5vZGUgPSBmaW5kRE9NTm9kZTtcbmV4cG9ydHMuZmx1c2hTeW5jID0gZmx1c2hTeW5jJDE7XG5leHBvcnRzLmh5ZHJhdGUgPSBoeWRyYXRlO1xuZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGh5ZHJhdGVSb290JDE7XG5leHBvcnRzLnJlbmRlciA9IHJlbmRlcjtcbmV4cG9ydHMudW5tb3VudENvbXBvbmVudEF0Tm9kZSA9IHVubW91bnRDb21wb25lbnRBdE5vZGU7XG5leHBvcnRzLnVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzID0gYmF0Y2hlZFVwZGF0ZXMkMTtcbmV4cG9ydHMudW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIgPSByZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcjtcbmV4cG9ydHMudmVyc2lvbiA9IFJlYWN0VmVyc2lvbjtcbiAgICAgICAgICAvKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0b3AgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcChuZXcgRXJyb3IoKSk7XG59XG4gICAgICAgIFxuICB9KSgpO1xufVxuIiwgIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gY2hlY2tEQ0UoKSB7XG4gIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbiAgaWYgKFxuICAgIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gPT09ICd1bmRlZmluZWQnIHx8XG4gICAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRSAhPT0gJ2Z1bmN0aW9uJ1xuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBUaGlzIGJyYW5jaCBpcyB1bnJlYWNoYWJsZSBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWRcbiAgICAvLyBpbiBwcm9kdWN0aW9uLCBidXQgdGhlIGNvbmRpdGlvbiBpcyB0cnVlIG9ubHkgaW4gZGV2ZWxvcG1lbnQuXG4gICAgLy8gVGhlcmVmb3JlIGlmIHRoZSBicmFuY2ggaXMgc3RpbGwgaGVyZSwgZGVhZCBjb2RlIGVsaW1pbmF0aW9uIHdhc24ndFxuICAgIC8vIHByb3Blcmx5IGFwcGxpZWQuXG4gICAgLy8gRG9uJ3QgY2hhbmdlIHRoZSBtZXNzYWdlLiBSZWFjdCBEZXZUb29scyByZWxpZXMgb24gaXQuIEFsc28gbWFrZSBzdXJlXG4gICAgLy8gdGhpcyBtZXNzYWdlIGRvZXNuJ3Qgb2NjdXIgZWxzZXdoZXJlIGluIHRoaXMgZnVuY3Rpb24sIG9yIGl0IHdpbGwgY2F1c2VcbiAgICAvLyBhIGZhbHNlIHBvc2l0aXZlLlxuICAgIHRocm93IG5ldyBFcnJvcignXl9eJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29kZSBhYm92ZSBoYXMgYmVlbiBkZWFkIGNvZGUgZWxpbWluYXRlZCAoRENFJ2QpLlxuICAgIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRShjaGVja0RDRSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIERldlRvb2xzIHNob3VsZG4ndCBjcmFzaCBSZWFjdCwgbm8gbWF0dGVyIHdoYXQuXG4gICAgLy8gV2Ugc2hvdWxkIHN0aWxsIHJlcG9ydCBpbiBjYXNlIHdlIGJyZWFrIHRoaXMgY29kZS5cbiAgICBjb25zb2xlLmVycm9yKGVycik7XG4gIH1cbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgLy8gRENFIGNoZWNrIHNob3VsZCBoYXBwZW4gYmVmb3JlIFJlYWN0RE9NIGJ1bmRsZSBleGVjdXRlcyBzbyB0aGF0XG4gIC8vIERldlRvb2xzIGNhbiByZXBvcnQgYmFkIG1pbmlmaWNhdGlvbiBkdXJpbmcgaW5qZWN0aW9uLlxuICBjaGVja0RDRSgpO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3JlYWN0LWRvbS5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20uZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbnZhciBtID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBtLmNyZWF0ZVJvb3Q7XG4gIGV4cG9ydHMuaHlkcmF0ZVJvb3QgPSBtLmh5ZHJhdGVSb290O1xufSBlbHNlIHtcbiAgdmFyIGkgPSBtLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBmdW5jdGlvbihjLCBvKSB7XG4gICAgaS51c2luZ0NsaWVudEVudHJ5UG9pbnQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbS5jcmVhdGVSb290KGMsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbiAgZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGZ1bmN0aW9uKGMsIGgsIG8pIHtcbiAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtLmh5ZHJhdGVSb290KGMsIGgsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbn1cbiIsICJpbXBvcnQgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgUmVhY3RET00gZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIjtcbmltcG9ydCB7IEJyb3dzZXJSb3V0ZXIsIFJvdXRlcywgUm91dGUgfSBmcm9tIFwicmVhY3Qtcm91dGVyLWRvbVwiO1xuaW1wb3J0IFwiLi4vY3NzL2FwcC5jc3NcIjtcblxuaW1wb3J0IEhvbWUgZnJvbSBcIi4vaG9tZVwiO1xuaW1wb3J0IEJvb2ttYXJrcyBmcm9tIFwiLi9ib29rbWFya3NcIjtcblxuLy8gUmVuZGVyIHRoZSByb290IGNvbXBvbmVudFxuY29uc3Qgcm9vdCA9IFJlYWN0RE9NLmNyZWF0ZVJvb3QoXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJyb290XCIpXG4pO1xuXG5yb290LnJlbmRlcihcbiAgICA8QnJvd3NlclJvdXRlcj5cbiAgICAgICAgPFJvdXRlcz5cbiAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwiL1wiIGVsZW1lbnQgPSB7IDxIb21lIC8+IH0gLz5cbiAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwidS86aWRcIiBlbGVtZW50ID0geyA8Qm9va21hcmtzIC8+IH0gLz5cbiAgICAgICAgPC9Sb3V0ZXM+XG4gICAgPC9Ccm93c2VyUm91dGVyPlxuKTtcbiIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfZXh0ZW5kcygpIHtcbiAgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduID8gT2JqZWN0LmFzc2lnbi5iaW5kKCkgOiBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcbiAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59IiwgImltcG9ydCBfZXh0ZW5kcyBmcm9tICdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzJztcblxuLyoqXHJcbiAqIEFjdGlvbnMgcmVwcmVzZW50IHRoZSB0eXBlIG9mIGNoYW5nZSB0byBhIGxvY2F0aW9uIHZhbHVlLlxyXG4gKlxyXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZW1peC1ydW4vaGlzdG9yeS90cmVlL21haW4vZG9jcy9hcGktcmVmZXJlbmNlLm1kI2FjdGlvblxyXG4gKi9cbnZhciBBY3Rpb247XG5cbihmdW5jdGlvbiAoQWN0aW9uKSB7XG4gIC8qKlxyXG4gICAqIEEgUE9QIGluZGljYXRlcyBhIGNoYW5nZSB0byBhbiBhcmJpdHJhcnkgaW5kZXggaW4gdGhlIGhpc3Rvcnkgc3RhY2ssIHN1Y2hcclxuICAgKiBhcyBhIGJhY2sgb3IgZm9yd2FyZCBuYXZpZ2F0aW9uLiBJdCBkb2VzIG5vdCBkZXNjcmliZSB0aGUgZGlyZWN0aW9uIG9mIHRoZVxyXG4gICAqIG5hdmlnYXRpb24sIG9ubHkgdGhhdCB0aGUgY3VycmVudCBpbmRleCBjaGFuZ2VkLlxyXG4gICAqXHJcbiAgICogTm90ZTogVGhpcyBpcyB0aGUgZGVmYXVsdCBhY3Rpb24gZm9yIG5ld2x5IGNyZWF0ZWQgaGlzdG9yeSBvYmplY3RzLlxyXG4gICAqL1xuICBBY3Rpb25bXCJQb3BcIl0gPSBcIlBPUFwiO1xuICAvKipcclxuICAgKiBBIFBVU0ggaW5kaWNhdGVzIGEgbmV3IGVudHJ5IGJlaW5nIGFkZGVkIHRvIHRoZSBoaXN0b3J5IHN0YWNrLCBzdWNoIGFzIHdoZW5cclxuICAgKiBhIGxpbmsgaXMgY2xpY2tlZCBhbmQgYSBuZXcgcGFnZSBsb2Fkcy4gV2hlbiB0aGlzIGhhcHBlbnMsIGFsbCBzdWJzZXF1ZW50XHJcbiAgICogZW50cmllcyBpbiB0aGUgc3RhY2sgYXJlIGxvc3QuXHJcbiAgICovXG5cbiAgQWN0aW9uW1wiUHVzaFwiXSA9IFwiUFVTSFwiO1xuICAvKipcclxuICAgKiBBIFJFUExBQ0UgaW5kaWNhdGVzIHRoZSBlbnRyeSBhdCB0aGUgY3VycmVudCBpbmRleCBpbiB0aGUgaGlzdG9yeSBzdGFja1xyXG4gICAqIGJlaW5nIHJlcGxhY2VkIGJ5IGEgbmV3IG9uZS5cclxuICAgKi9cblxuICBBY3Rpb25bXCJSZXBsYWNlXCJdID0gXCJSRVBMQUNFXCI7XG59KShBY3Rpb24gfHwgKEFjdGlvbiA9IHt9KSk7XG5cbnZhciByZWFkT25seSA9IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIiA/IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUob2JqKTtcbn0gOiBmdW5jdGlvbiAob2JqKSB7XG4gIHJldHVybiBvYmo7XG59O1xuXG5mdW5jdGlvbiB3YXJuaW5nKGNvbmQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFjb25kKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSBjb25zb2xlLndhcm4obWVzc2FnZSk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gV2VsY29tZSB0byBkZWJ1Z2dpbmcgaGlzdG9yeSFcbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIGVycm9yIGlzIHRocm93biBhcyBhIGNvbnZlbmllbmNlIHNvIHlvdSBjYW4gbW9yZSBlYXNpbHlcbiAgICAgIC8vIGZpbmQgdGhlIHNvdXJjZSBmb3IgYSB3YXJuaW5nIHRoYXQgYXBwZWFycyBpbiB0aGUgY29uc29sZSBieVxuICAgICAgLy8gZW5hYmxpbmcgXCJwYXVzZSBvbiBleGNlcHRpb25zXCIgaW4geW91ciBKYXZhU2NyaXB0IGRlYnVnZ2VyLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgICB9IGNhdGNoIChlKSB7fVxuICB9XG59XG5cbnZhciBCZWZvcmVVbmxvYWRFdmVudFR5cGUgPSAnYmVmb3JldW5sb2FkJztcbnZhciBIYXNoQ2hhbmdlRXZlbnRUeXBlID0gJ2hhc2hjaGFuZ2UnO1xudmFyIFBvcFN0YXRlRXZlbnRUeXBlID0gJ3BvcHN0YXRlJztcbi8qKlxyXG4gKiBCcm93c2VyIGhpc3Rvcnkgc3RvcmVzIHRoZSBsb2NhdGlvbiBpbiByZWd1bGFyIFVSTHMuIFRoaXMgaXMgdGhlIHN0YW5kYXJkIGZvclxyXG4gKiBtb3N0IHdlYiBhcHBzLCBidXQgaXQgcmVxdWlyZXMgc29tZSBjb25maWd1cmF0aW9uIG9uIHRoZSBzZXJ2ZXIgdG8gZW5zdXJlIHlvdVxyXG4gKiBzZXJ2ZSB0aGUgc2FtZSBhcHAgYXQgbXVsdGlwbGUgVVJMcy5cclxuICpcclxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVtaXgtcnVuL2hpc3RvcnkvdHJlZS9tYWluL2RvY3MvYXBpLXJlZmVyZW5jZS5tZCNjcmVhdGVicm93c2VyaGlzdG9yeVxyXG4gKi9cblxuZnVuY3Rpb24gY3JlYXRlQnJvd3Nlckhpc3Rvcnkob3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG5cbiAgdmFyIF9vcHRpb25zID0gb3B0aW9ucyxcbiAgICAgIF9vcHRpb25zJHdpbmRvdyA9IF9vcHRpb25zLndpbmRvdyxcbiAgICAgIHdpbmRvdyA9IF9vcHRpb25zJHdpbmRvdyA9PT0gdm9pZCAwID8gZG9jdW1lbnQuZGVmYXVsdFZpZXcgOiBfb3B0aW9ucyR3aW5kb3c7XG4gIHZhciBnbG9iYWxIaXN0b3J5ID0gd2luZG93Lmhpc3Rvcnk7XG5cbiAgZnVuY3Rpb24gZ2V0SW5kZXhBbmRMb2NhdGlvbigpIHtcbiAgICB2YXIgX3dpbmRvdyRsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbixcbiAgICAgICAgcGF0aG5hbWUgPSBfd2luZG93JGxvY2F0aW9uLnBhdGhuYW1lLFxuICAgICAgICBzZWFyY2ggPSBfd2luZG93JGxvY2F0aW9uLnNlYXJjaCxcbiAgICAgICAgaGFzaCA9IF93aW5kb3ckbG9jYXRpb24uaGFzaDtcbiAgICB2YXIgc3RhdGUgPSBnbG9iYWxIaXN0b3J5LnN0YXRlIHx8IHt9O1xuICAgIHJldHVybiBbc3RhdGUuaWR4LCByZWFkT25seSh7XG4gICAgICBwYXRobmFtZTogcGF0aG5hbWUsXG4gICAgICBzZWFyY2g6IHNlYXJjaCxcbiAgICAgIGhhc2g6IGhhc2gsXG4gICAgICBzdGF0ZTogc3RhdGUudXNyIHx8IG51bGwsXG4gICAgICBrZXk6IHN0YXRlLmtleSB8fCAnZGVmYXVsdCdcbiAgICB9KV07XG4gIH1cblxuICB2YXIgYmxvY2tlZFBvcFR4ID0gbnVsbDtcblxuICBmdW5jdGlvbiBoYW5kbGVQb3AoKSB7XG4gICAgaWYgKGJsb2NrZWRQb3BUeCkge1xuICAgICAgYmxvY2tlcnMuY2FsbChibG9ja2VkUG9wVHgpO1xuICAgICAgYmxvY2tlZFBvcFR4ID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG5leHRBY3Rpb24gPSBBY3Rpb24uUG9wO1xuXG4gICAgICB2YXIgX2dldEluZGV4QW5kTG9jYXRpb24gPSBnZXRJbmRleEFuZExvY2F0aW9uKCksXG4gICAgICAgICAgbmV4dEluZGV4ID0gX2dldEluZGV4QW5kTG9jYXRpb25bMF0sXG4gICAgICAgICAgbmV4dExvY2F0aW9uID0gX2dldEluZGV4QW5kTG9jYXRpb25bMV07XG5cbiAgICAgIGlmIChibG9ja2Vycy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKG5leHRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIGRlbHRhID0gaW5kZXggLSBuZXh0SW5kZXg7XG5cbiAgICAgICAgICBpZiAoZGVsdGEpIHtcbiAgICAgICAgICAgIC8vIFJldmVydCB0aGUgUE9QXG4gICAgICAgICAgICBibG9ja2VkUG9wVHggPSB7XG4gICAgICAgICAgICAgIGFjdGlvbjogbmV4dEFjdGlvbixcbiAgICAgICAgICAgICAgbG9jYXRpb246IG5leHRMb2NhdGlvbixcbiAgICAgICAgICAgICAgcmV0cnk6IGZ1bmN0aW9uIHJldHJ5KCkge1xuICAgICAgICAgICAgICAgIGdvKGRlbHRhICogLTEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ28oZGVsdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBUcnlpbmcgdG8gUE9QIHRvIGEgbG9jYXRpb24gd2l0aCBubyBpbmRleC4gV2UgZGlkIG5vdCBjcmVhdGVcbiAgICAgICAgICAvLyB0aGlzIGxvY2F0aW9uLCBzbyB3ZSBjYW4ndCBlZmZlY3RpdmVseSBibG9jayB0aGUgbmF2aWdhdGlvbi5cbiAgICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIgPyB3YXJuaW5nKGZhbHNlLCAvLyBUT0RPOiBXcml0ZSB1cCBhIGRvYyB0aGF0IGV4cGxhaW5zIG91ciBibG9ja2luZyBzdHJhdGVneSBpblxuICAgICAgICAgIC8vIGRldGFpbCBhbmQgbGluayB0byBpdCBoZXJlIHNvIHBlb3BsZSBjYW4gdW5kZXJzdGFuZCBiZXR0ZXIgd2hhdFxuICAgICAgICAgIC8vIGlzIGdvaW5nIG9uIGFuZCBob3cgdG8gYXZvaWQgaXQuXG4gICAgICAgICAgXCJZb3UgYXJlIHRyeWluZyB0byBibG9jayBhIFBPUCBuYXZpZ2F0aW9uIHRvIGEgbG9jYXRpb24gdGhhdCB3YXMgbm90IFwiICsgXCJjcmVhdGVkIGJ5IHRoZSBoaXN0b3J5IGxpYnJhcnkuIFRoZSBibG9jayB3aWxsIGZhaWwgc2lsZW50bHkgaW4gXCIgKyBcInByb2R1Y3Rpb24sIGJ1dCBpbiBnZW5lcmFsIHlvdSBzaG91bGQgZG8gYWxsIG5hdmlnYXRpb24gd2l0aCB0aGUgXCIgKyBcImhpc3RvcnkgbGlicmFyeSAoaW5zdGVhZCBvZiB1c2luZyB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUgZGlyZWN0bHkpIFwiICsgXCJ0byBhdm9pZCB0aGlzIHNpdHVhdGlvbi5cIikgOiB2b2lkIDA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFwcGx5VHgobmV4dEFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoUG9wU3RhdGVFdmVudFR5cGUsIGhhbmRsZVBvcCk7XG4gIHZhciBhY3Rpb24gPSBBY3Rpb24uUG9wO1xuXG4gIHZhciBfZ2V0SW5kZXhBbmRMb2NhdGlvbjIgPSBnZXRJbmRleEFuZExvY2F0aW9uKCksXG4gICAgICBpbmRleCA9IF9nZXRJbmRleEFuZExvY2F0aW9uMlswXSxcbiAgICAgIGxvY2F0aW9uID0gX2dldEluZGV4QW5kTG9jYXRpb24yWzFdO1xuXG4gIHZhciBsaXN0ZW5lcnMgPSBjcmVhdGVFdmVudHMoKTtcbiAgdmFyIGJsb2NrZXJzID0gY3JlYXRlRXZlbnRzKCk7XG5cbiAgaWYgKGluZGV4ID09IG51bGwpIHtcbiAgICBpbmRleCA9IDA7XG4gICAgZ2xvYmFsSGlzdG9yeS5yZXBsYWNlU3RhdGUoX2V4dGVuZHMoe30sIGdsb2JhbEhpc3Rvcnkuc3RhdGUsIHtcbiAgICAgIGlkeDogaW5kZXhcbiAgICB9KSwgJycpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlSHJlZih0bykge1xuICAgIHJldHVybiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnID8gdG8gOiBjcmVhdGVQYXRoKHRvKTtcbiAgfSAvLyBzdGF0ZSBkZWZhdWx0cyB0byBgbnVsbGAgYmVjYXVzZSBgd2luZG93Lmhpc3Rvcnkuc3RhdGVgIGRvZXNcblxuXG4gIGZ1bmN0aW9uIGdldE5leHRMb2NhdGlvbih0bywgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUgPT09IHZvaWQgMCkge1xuICAgICAgc3RhdGUgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiByZWFkT25seShfZXh0ZW5kcyh7XG4gICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBoYXNoOiAnJyxcbiAgICAgIHNlYXJjaDogJydcbiAgICB9LCB0eXBlb2YgdG8gPT09ICdzdHJpbmcnID8gcGFyc2VQYXRoKHRvKSA6IHRvLCB7XG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICBrZXk6IGNyZWF0ZUtleSgpXG4gICAgfSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0SGlzdG9yeVN0YXRlQW5kVXJsKG5leHRMb2NhdGlvbiwgaW5kZXgpIHtcbiAgICByZXR1cm4gW3tcbiAgICAgIHVzcjogbmV4dExvY2F0aW9uLnN0YXRlLFxuICAgICAga2V5OiBuZXh0TG9jYXRpb24ua2V5LFxuICAgICAgaWR4OiBpbmRleFxuICAgIH0sIGNyZWF0ZUhyZWYobmV4dExvY2F0aW9uKV07XG4gIH1cblxuICBmdW5jdGlvbiBhbGxvd1R4KGFjdGlvbiwgbG9jYXRpb24sIHJldHJ5KSB7XG4gICAgcmV0dXJuICFibG9ja2Vycy5sZW5ndGggfHwgKGJsb2NrZXJzLmNhbGwoe1xuICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb24sXG4gICAgICByZXRyeTogcmV0cnlcbiAgICB9KSwgZmFsc2UpO1xuICB9XG5cbiAgZnVuY3Rpb24gYXBwbHlUeChuZXh0QWN0aW9uKSB7XG4gICAgYWN0aW9uID0gbmV4dEFjdGlvbjtcblxuICAgIHZhciBfZ2V0SW5kZXhBbmRMb2NhdGlvbjMgPSBnZXRJbmRleEFuZExvY2F0aW9uKCk7XG5cbiAgICBpbmRleCA9IF9nZXRJbmRleEFuZExvY2F0aW9uM1swXTtcbiAgICBsb2NhdGlvbiA9IF9nZXRJbmRleEFuZExvY2F0aW9uM1sxXTtcbiAgICBsaXN0ZW5lcnMuY2FsbCh7XG4gICAgICBhY3Rpb246IGFjdGlvbixcbiAgICAgIGxvY2F0aW9uOiBsb2NhdGlvblxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gcHVzaCh0bywgc3RhdGUpIHtcbiAgICB2YXIgbmV4dEFjdGlvbiA9IEFjdGlvbi5QdXNoO1xuICAgIHZhciBuZXh0TG9jYXRpb24gPSBnZXROZXh0TG9jYXRpb24odG8sIHN0YXRlKTtcblxuICAgIGZ1bmN0aW9uIHJldHJ5KCkge1xuICAgICAgcHVzaCh0bywgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChhbGxvd1R4KG5leHRBY3Rpb24sIG5leHRMb2NhdGlvbiwgcmV0cnkpKSB7XG4gICAgICB2YXIgX2dldEhpc3RvcnlTdGF0ZUFuZFVyID0gZ2V0SGlzdG9yeVN0YXRlQW5kVXJsKG5leHRMb2NhdGlvbiwgaW5kZXggKyAxKSxcbiAgICAgICAgICBoaXN0b3J5U3RhdGUgPSBfZ2V0SGlzdG9yeVN0YXRlQW5kVXJbMF0sXG4gICAgICAgICAgdXJsID0gX2dldEhpc3RvcnlTdGF0ZUFuZFVyWzFdOyAvLyBUT0RPOiBTdXBwb3J0IGZvcmNlZCByZWxvYWRpbmdcbiAgICAgIC8vIHRyeS4uLmNhdGNoIGJlY2F1c2UgaU9TIGxpbWl0cyB1cyB0byAxMDAgcHVzaFN0YXRlIGNhbGxzIDovXG5cblxuICAgICAgdHJ5IHtcbiAgICAgICAgZ2xvYmFsSGlzdG9yeS5wdXNoU3RhdGUoaGlzdG9yeVN0YXRlLCAnJywgdXJsKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFRoZXkgYXJlIGdvaW5nIHRvIGxvc2Ugc3RhdGUgaGVyZSwgYnV0IHRoZXJlIGlzIG5vIHJlYWxcbiAgICAgICAgLy8gd2F5IHRvIHdhcm4gdGhlbSBhYm91dCBpdCBzaW5jZSB0aGUgcGFnZSB3aWxsIHJlZnJlc2guLi5cbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmFzc2lnbih1cmwpO1xuICAgICAgfVxuXG4gICAgICBhcHBseVR4KG5leHRBY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcGxhY2UodG8sIHN0YXRlKSB7XG4gICAgdmFyIG5leHRBY3Rpb24gPSBBY3Rpb24uUmVwbGFjZTtcbiAgICB2YXIgbmV4dExvY2F0aW9uID0gZ2V0TmV4dExvY2F0aW9uKHRvLCBzdGF0ZSk7XG5cbiAgICBmdW5jdGlvbiByZXRyeSgpIHtcbiAgICAgIHJlcGxhY2UodG8sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAoYWxsb3dUeChuZXh0QWN0aW9uLCBuZXh0TG9jYXRpb24sIHJldHJ5KSkge1xuICAgICAgdmFyIF9nZXRIaXN0b3J5U3RhdGVBbmRVcjIgPSBnZXRIaXN0b3J5U3RhdGVBbmRVcmwobmV4dExvY2F0aW9uLCBpbmRleCksXG4gICAgICAgICAgaGlzdG9yeVN0YXRlID0gX2dldEhpc3RvcnlTdGF0ZUFuZFVyMlswXSxcbiAgICAgICAgICB1cmwgPSBfZ2V0SGlzdG9yeVN0YXRlQW5kVXIyWzFdOyAvLyBUT0RPOiBTdXBwb3J0IGZvcmNlZCByZWxvYWRpbmdcblxuXG4gICAgICBnbG9iYWxIaXN0b3J5LnJlcGxhY2VTdGF0ZShoaXN0b3J5U3RhdGUsICcnLCB1cmwpO1xuICAgICAgYXBwbHlUeChuZXh0QWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnbyhkZWx0YSkge1xuICAgIGdsb2JhbEhpc3RvcnkuZ28oZGVsdGEpO1xuICB9XG5cbiAgdmFyIGhpc3RvcnkgPSB7XG4gICAgZ2V0IGFjdGlvbigpIHtcbiAgICAgIHJldHVybiBhY3Rpb247XG4gICAgfSxcblxuICAgIGdldCBsb2NhdGlvbigpIHtcbiAgICAgIHJldHVybiBsb2NhdGlvbjtcbiAgICB9LFxuXG4gICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZixcbiAgICBwdXNoOiBwdXNoLFxuICAgIHJlcGxhY2U6IHJlcGxhY2UsXG4gICAgZ286IGdvLFxuICAgIGJhY2s6IGZ1bmN0aW9uIGJhY2soKSB7XG4gICAgICBnbygtMSk7XG4gICAgfSxcbiAgICBmb3J3YXJkOiBmdW5jdGlvbiBmb3J3YXJkKCkge1xuICAgICAgZ28oMSk7XG4gICAgfSxcbiAgICBsaXN0ZW46IGZ1bmN0aW9uIGxpc3RlbihsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9LFxuICAgIGJsb2NrOiBmdW5jdGlvbiBibG9jayhibG9ja2VyKSB7XG4gICAgICB2YXIgdW5ibG9jayA9IGJsb2NrZXJzLnB1c2goYmxvY2tlcik7XG5cbiAgICAgIGlmIChibG9ja2Vycy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoQmVmb3JlVW5sb2FkRXZlbnRUeXBlLCBwcm9tcHRCZWZvcmVVbmxvYWQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB1bmJsb2NrKCk7IC8vIFJlbW92ZSB0aGUgYmVmb3JldW5sb2FkIGxpc3RlbmVyIHNvIHRoZSBkb2N1bWVudCBtYXlcbiAgICAgICAgLy8gc3RpbGwgYmUgc2FsdmFnZWFibGUgaW4gdGhlIHBhZ2VoaWRlIGV2ZW50LlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jdW5sb2FkaW5nLWRvY3VtZW50c1xuXG4gICAgICAgIGlmICghYmxvY2tlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoQmVmb3JlVW5sb2FkRXZlbnRUeXBlLCBwcm9tcHRCZWZvcmVVbmxvYWQpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIGhpc3Rvcnk7XG59XG4vKipcclxuICogSGFzaCBoaXN0b3J5IHN0b3JlcyB0aGUgbG9jYXRpb24gaW4gd2luZG93LmxvY2F0aW9uLmhhc2guIFRoaXMgbWFrZXMgaXQgaWRlYWxcclxuICogZm9yIHNpdHVhdGlvbnMgd2hlcmUgeW91IGRvbid0IHdhbnQgdG8gc2VuZCB0aGUgbG9jYXRpb24gdG8gdGhlIHNlcnZlciBmb3JcclxuICogc29tZSByZWFzb24sIGVpdGhlciBiZWNhdXNlIHlvdSBkbyBjYW5ub3QgY29uZmlndXJlIGl0IG9yIHRoZSBVUkwgc3BhY2UgaXNcclxuICogcmVzZXJ2ZWQgZm9yIHNvbWV0aGluZyBlbHNlLlxyXG4gKlxyXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZW1peC1ydW4vaGlzdG9yeS90cmVlL21haW4vZG9jcy9hcGktcmVmZXJlbmNlLm1kI2NyZWF0ZWhhc2hoaXN0b3J5XHJcbiAqL1xuXG5mdW5jdGlvbiBjcmVhdGVIYXNoSGlzdG9yeShvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zID09PSB2b2lkIDApIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cblxuICB2YXIgX29wdGlvbnMyID0gb3B0aW9ucyxcbiAgICAgIF9vcHRpb25zMiR3aW5kb3cgPSBfb3B0aW9uczIud2luZG93LFxuICAgICAgd2luZG93ID0gX29wdGlvbnMyJHdpbmRvdyA9PT0gdm9pZCAwID8gZG9jdW1lbnQuZGVmYXVsdFZpZXcgOiBfb3B0aW9uczIkd2luZG93O1xuICB2YXIgZ2xvYmFsSGlzdG9yeSA9IHdpbmRvdy5oaXN0b3J5O1xuXG4gIGZ1bmN0aW9uIGdldEluZGV4QW5kTG9jYXRpb24oKSB7XG4gICAgdmFyIF9wYXJzZVBhdGggPSBwYXJzZVBhdGgod2luZG93LmxvY2F0aW9uLmhhc2guc3Vic3RyKDEpKSxcbiAgICAgICAgX3BhcnNlUGF0aCRwYXRobmFtZSA9IF9wYXJzZVBhdGgucGF0aG5hbWUsXG4gICAgICAgIHBhdGhuYW1lID0gX3BhcnNlUGF0aCRwYXRobmFtZSA9PT0gdm9pZCAwID8gJy8nIDogX3BhcnNlUGF0aCRwYXRobmFtZSxcbiAgICAgICAgX3BhcnNlUGF0aCRzZWFyY2ggPSBfcGFyc2VQYXRoLnNlYXJjaCxcbiAgICAgICAgc2VhcmNoID0gX3BhcnNlUGF0aCRzZWFyY2ggPT09IHZvaWQgMCA/ICcnIDogX3BhcnNlUGF0aCRzZWFyY2gsXG4gICAgICAgIF9wYXJzZVBhdGgkaGFzaCA9IF9wYXJzZVBhdGguaGFzaCxcbiAgICAgICAgaGFzaCA9IF9wYXJzZVBhdGgkaGFzaCA9PT0gdm9pZCAwID8gJycgOiBfcGFyc2VQYXRoJGhhc2g7XG5cbiAgICB2YXIgc3RhdGUgPSBnbG9iYWxIaXN0b3J5LnN0YXRlIHx8IHt9O1xuICAgIHJldHVybiBbc3RhdGUuaWR4LCByZWFkT25seSh7XG4gICAgICBwYXRobmFtZTogcGF0aG5hbWUsXG4gICAgICBzZWFyY2g6IHNlYXJjaCxcbiAgICAgIGhhc2g6IGhhc2gsXG4gICAgICBzdGF0ZTogc3RhdGUudXNyIHx8IG51bGwsXG4gICAgICBrZXk6IHN0YXRlLmtleSB8fCAnZGVmYXVsdCdcbiAgICB9KV07XG4gIH1cblxuICB2YXIgYmxvY2tlZFBvcFR4ID0gbnVsbDtcblxuICBmdW5jdGlvbiBoYW5kbGVQb3AoKSB7XG4gICAgaWYgKGJsb2NrZWRQb3BUeCkge1xuICAgICAgYmxvY2tlcnMuY2FsbChibG9ja2VkUG9wVHgpO1xuICAgICAgYmxvY2tlZFBvcFR4ID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG5leHRBY3Rpb24gPSBBY3Rpb24uUG9wO1xuXG4gICAgICB2YXIgX2dldEluZGV4QW5kTG9jYXRpb240ID0gZ2V0SW5kZXhBbmRMb2NhdGlvbigpLFxuICAgICAgICAgIG5leHRJbmRleCA9IF9nZXRJbmRleEFuZExvY2F0aW9uNFswXSxcbiAgICAgICAgICBuZXh0TG9jYXRpb24gPSBfZ2V0SW5kZXhBbmRMb2NhdGlvbjRbMV07XG5cbiAgICAgIGlmIChibG9ja2Vycy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKG5leHRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIGRlbHRhID0gaW5kZXggLSBuZXh0SW5kZXg7XG5cbiAgICAgICAgICBpZiAoZGVsdGEpIHtcbiAgICAgICAgICAgIC8vIFJldmVydCB0aGUgUE9QXG4gICAgICAgICAgICBibG9ja2VkUG9wVHggPSB7XG4gICAgICAgICAgICAgIGFjdGlvbjogbmV4dEFjdGlvbixcbiAgICAgICAgICAgICAgbG9jYXRpb246IG5leHRMb2NhdGlvbixcbiAgICAgICAgICAgICAgcmV0cnk6IGZ1bmN0aW9uIHJldHJ5KCkge1xuICAgICAgICAgICAgICAgIGdvKGRlbHRhICogLTEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ28oZGVsdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBUcnlpbmcgdG8gUE9QIHRvIGEgbG9jYXRpb24gd2l0aCBubyBpbmRleC4gV2UgZGlkIG5vdCBjcmVhdGVcbiAgICAgICAgICAvLyB0aGlzIGxvY2F0aW9uLCBzbyB3ZSBjYW4ndCBlZmZlY3RpdmVseSBibG9jayB0aGUgbmF2aWdhdGlvbi5cbiAgICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIgPyB3YXJuaW5nKGZhbHNlLCAvLyBUT0RPOiBXcml0ZSB1cCBhIGRvYyB0aGF0IGV4cGxhaW5zIG91ciBibG9ja2luZyBzdHJhdGVneSBpblxuICAgICAgICAgIC8vIGRldGFpbCBhbmQgbGluayB0byBpdCBoZXJlIHNvIHBlb3BsZSBjYW4gdW5kZXJzdGFuZCBiZXR0ZXJcbiAgICAgICAgICAvLyB3aGF0IGlzIGdvaW5nIG9uIGFuZCBob3cgdG8gYXZvaWQgaXQuXG4gICAgICAgICAgXCJZb3UgYXJlIHRyeWluZyB0byBibG9jayBhIFBPUCBuYXZpZ2F0aW9uIHRvIGEgbG9jYXRpb24gdGhhdCB3YXMgbm90IFwiICsgXCJjcmVhdGVkIGJ5IHRoZSBoaXN0b3J5IGxpYnJhcnkuIFRoZSBibG9jayB3aWxsIGZhaWwgc2lsZW50bHkgaW4gXCIgKyBcInByb2R1Y3Rpb24sIGJ1dCBpbiBnZW5lcmFsIHlvdSBzaG91bGQgZG8gYWxsIG5hdmlnYXRpb24gd2l0aCB0aGUgXCIgKyBcImhpc3RvcnkgbGlicmFyeSAoaW5zdGVhZCBvZiB1c2luZyB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUgZGlyZWN0bHkpIFwiICsgXCJ0byBhdm9pZCB0aGlzIHNpdHVhdGlvbi5cIikgOiB2b2lkIDA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFwcGx5VHgobmV4dEFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoUG9wU3RhdGVFdmVudFR5cGUsIGhhbmRsZVBvcCk7IC8vIHBvcHN0YXRlIGRvZXMgbm90IGZpcmUgb24gaGFzaGNoYW5nZSBpbiBJRSAxMSBhbmQgb2xkICh0cmlkZW50KSBFZGdlXG4gIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0FQSS9XaW5kb3cvcG9wc3RhdGVfZXZlbnRcblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihIYXNoQ2hhbmdlRXZlbnRUeXBlLCBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9nZXRJbmRleEFuZExvY2F0aW9uNSA9IGdldEluZGV4QW5kTG9jYXRpb24oKSxcbiAgICAgICAgbmV4dExvY2F0aW9uID0gX2dldEluZGV4QW5kTG9jYXRpb241WzFdOyAvLyBJZ25vcmUgZXh0cmFuZW91cyBoYXNoY2hhbmdlIGV2ZW50cy5cblxuXG4gICAgaWYgKGNyZWF0ZVBhdGgobmV4dExvY2F0aW9uKSAhPT0gY3JlYXRlUGF0aChsb2NhdGlvbikpIHtcbiAgICAgIGhhbmRsZVBvcCgpO1xuICAgIH1cbiAgfSk7XG4gIHZhciBhY3Rpb24gPSBBY3Rpb24uUG9wO1xuXG4gIHZhciBfZ2V0SW5kZXhBbmRMb2NhdGlvbjYgPSBnZXRJbmRleEFuZExvY2F0aW9uKCksXG4gICAgICBpbmRleCA9IF9nZXRJbmRleEFuZExvY2F0aW9uNlswXSxcbiAgICAgIGxvY2F0aW9uID0gX2dldEluZGV4QW5kTG9jYXRpb242WzFdO1xuXG4gIHZhciBsaXN0ZW5lcnMgPSBjcmVhdGVFdmVudHMoKTtcbiAgdmFyIGJsb2NrZXJzID0gY3JlYXRlRXZlbnRzKCk7XG5cbiAgaWYgKGluZGV4ID09IG51bGwpIHtcbiAgICBpbmRleCA9IDA7XG4gICAgZ2xvYmFsSGlzdG9yeS5yZXBsYWNlU3RhdGUoX2V4dGVuZHMoe30sIGdsb2JhbEhpc3Rvcnkuc3RhdGUsIHtcbiAgICAgIGlkeDogaW5kZXhcbiAgICB9KSwgJycpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0QmFzZUhyZWYoKSB7XG4gICAgdmFyIGJhc2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdiYXNlJyk7XG4gICAgdmFyIGhyZWYgPSAnJztcblxuICAgIGlmIChiYXNlICYmIGJhc2UuZ2V0QXR0cmlidXRlKCdocmVmJykpIHtcbiAgICAgIHZhciB1cmwgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcbiAgICAgIHZhciBoYXNoSW5kZXggPSB1cmwuaW5kZXhPZignIycpO1xuICAgICAgaHJlZiA9IGhhc2hJbmRleCA9PT0gLTEgPyB1cmwgOiB1cmwuc2xpY2UoMCwgaGFzaEluZGV4KTtcbiAgICB9XG5cbiAgICByZXR1cm4gaHJlZjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUhyZWYodG8pIHtcbiAgICByZXR1cm4gZ2V0QmFzZUhyZWYoKSArICcjJyArICh0eXBlb2YgdG8gPT09ICdzdHJpbmcnID8gdG8gOiBjcmVhdGVQYXRoKHRvKSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXROZXh0TG9jYXRpb24odG8sIHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlID09PSB2b2lkIDApIHtcbiAgICAgIHN0YXRlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVhZE9ubHkoX2V4dGVuZHMoe1xuICAgICAgcGF0aG5hbWU6IGxvY2F0aW9uLnBhdGhuYW1lLFxuICAgICAgaGFzaDogJycsXG4gICAgICBzZWFyY2g6ICcnXG4gICAgfSwgdHlwZW9mIHRvID09PSAnc3RyaW5nJyA/IHBhcnNlUGF0aCh0bykgOiB0bywge1xuICAgICAgc3RhdGU6IHN0YXRlLFxuICAgICAga2V5OiBjcmVhdGVLZXkoKVxuICAgIH0pKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEhpc3RvcnlTdGF0ZUFuZFVybChuZXh0TG9jYXRpb24sIGluZGV4KSB7XG4gICAgcmV0dXJuIFt7XG4gICAgICB1c3I6IG5leHRMb2NhdGlvbi5zdGF0ZSxcbiAgICAgIGtleTogbmV4dExvY2F0aW9uLmtleSxcbiAgICAgIGlkeDogaW5kZXhcbiAgICB9LCBjcmVhdGVIcmVmKG5leHRMb2NhdGlvbildO1xuICB9XG5cbiAgZnVuY3Rpb24gYWxsb3dUeChhY3Rpb24sIGxvY2F0aW9uLCByZXRyeSkge1xuICAgIHJldHVybiAhYmxvY2tlcnMubGVuZ3RoIHx8IChibG9ja2Vycy5jYWxsKHtcbiAgICAgIGFjdGlvbjogYWN0aW9uLFxuICAgICAgbG9jYXRpb246IGxvY2F0aW9uLFxuICAgICAgcmV0cnk6IHJldHJ5XG4gICAgfSksIGZhbHNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGx5VHgobmV4dEFjdGlvbikge1xuICAgIGFjdGlvbiA9IG5leHRBY3Rpb247XG5cbiAgICB2YXIgX2dldEluZGV4QW5kTG9jYXRpb243ID0gZ2V0SW5kZXhBbmRMb2NhdGlvbigpO1xuXG4gICAgaW5kZXggPSBfZ2V0SW5kZXhBbmRMb2NhdGlvbjdbMF07XG4gICAgbG9jYXRpb24gPSBfZ2V0SW5kZXhBbmRMb2NhdGlvbjdbMV07XG4gICAgbGlzdGVuZXJzLmNhbGwoe1xuICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb25cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHB1c2godG8sIHN0YXRlKSB7XG4gICAgdmFyIG5leHRBY3Rpb24gPSBBY3Rpb24uUHVzaDtcbiAgICB2YXIgbmV4dExvY2F0aW9uID0gZ2V0TmV4dExvY2F0aW9uKHRvLCBzdGF0ZSk7XG5cbiAgICBmdW5jdGlvbiByZXRyeSgpIHtcbiAgICAgIHB1c2godG8sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIgPyB3YXJuaW5nKG5leHRMb2NhdGlvbi5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJywgXCJSZWxhdGl2ZSBwYXRobmFtZXMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gaGFzaCBoaXN0b3J5LnB1c2goXCIgKyBKU09OLnN0cmluZ2lmeSh0bykgKyBcIilcIikgOiB2b2lkIDA7XG5cbiAgICBpZiAoYWxsb3dUeChuZXh0QWN0aW9uLCBuZXh0TG9jYXRpb24sIHJldHJ5KSkge1xuICAgICAgdmFyIF9nZXRIaXN0b3J5U3RhdGVBbmRVcjMgPSBnZXRIaXN0b3J5U3RhdGVBbmRVcmwobmV4dExvY2F0aW9uLCBpbmRleCArIDEpLFxuICAgICAgICAgIGhpc3RvcnlTdGF0ZSA9IF9nZXRIaXN0b3J5U3RhdGVBbmRVcjNbMF0sXG4gICAgICAgICAgdXJsID0gX2dldEhpc3RvcnlTdGF0ZUFuZFVyM1sxXTsgLy8gVE9ETzogU3VwcG9ydCBmb3JjZWQgcmVsb2FkaW5nXG4gICAgICAvLyB0cnkuLi5jYXRjaCBiZWNhdXNlIGlPUyBsaW1pdHMgdXMgdG8gMTAwIHB1c2hTdGF0ZSBjYWxscyA6L1xuXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGdsb2JhbEhpc3RvcnkucHVzaFN0YXRlKGhpc3RvcnlTdGF0ZSwgJycsIHVybCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBUaGV5IGFyZSBnb2luZyB0byBsb3NlIHN0YXRlIGhlcmUsIGJ1dCB0aGVyZSBpcyBubyByZWFsXG4gICAgICAgIC8vIHdheSB0byB3YXJuIHRoZW0gYWJvdXQgaXQgc2luY2UgdGhlIHBhZ2Ugd2lsbCByZWZyZXNoLi4uXG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5hc3NpZ24odXJsKTtcbiAgICAgIH1cblxuICAgICAgYXBwbHlUeChuZXh0QWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXBsYWNlKHRvLCBzdGF0ZSkge1xuICAgIHZhciBuZXh0QWN0aW9uID0gQWN0aW9uLlJlcGxhY2U7XG4gICAgdmFyIG5leHRMb2NhdGlvbiA9IGdldE5leHRMb2NhdGlvbih0bywgc3RhdGUpO1xuXG4gICAgZnVuY3Rpb24gcmV0cnkoKSB7XG4gICAgICByZXBsYWNlKHRvLCBzdGF0ZSk7XG4gICAgfVxuXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiID8gd2FybmluZyhuZXh0TG9jYXRpb24ucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycsIFwiUmVsYXRpdmUgcGF0aG5hbWVzIGFyZSBub3Qgc3VwcG9ydGVkIGluIGhhc2ggaGlzdG9yeS5yZXBsYWNlKFwiICsgSlNPTi5zdHJpbmdpZnkodG8pICsgXCIpXCIpIDogdm9pZCAwO1xuXG4gICAgaWYgKGFsbG93VHgobmV4dEFjdGlvbiwgbmV4dExvY2F0aW9uLCByZXRyeSkpIHtcbiAgICAgIHZhciBfZ2V0SGlzdG9yeVN0YXRlQW5kVXI0ID0gZ2V0SGlzdG9yeVN0YXRlQW5kVXJsKG5leHRMb2NhdGlvbiwgaW5kZXgpLFxuICAgICAgICAgIGhpc3RvcnlTdGF0ZSA9IF9nZXRIaXN0b3J5U3RhdGVBbmRVcjRbMF0sXG4gICAgICAgICAgdXJsID0gX2dldEhpc3RvcnlTdGF0ZUFuZFVyNFsxXTsgLy8gVE9ETzogU3VwcG9ydCBmb3JjZWQgcmVsb2FkaW5nXG5cblxuICAgICAgZ2xvYmFsSGlzdG9yeS5yZXBsYWNlU3RhdGUoaGlzdG9yeVN0YXRlLCAnJywgdXJsKTtcbiAgICAgIGFwcGx5VHgobmV4dEFjdGlvbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ28oZGVsdGEpIHtcbiAgICBnbG9iYWxIaXN0b3J5LmdvKGRlbHRhKTtcbiAgfVxuXG4gIHZhciBoaXN0b3J5ID0ge1xuICAgIGdldCBhY3Rpb24oKSB7XG4gICAgICByZXR1cm4gYWN0aW9uO1xuICAgIH0sXG5cbiAgICBnZXQgbG9jYXRpb24oKSB7XG4gICAgICByZXR1cm4gbG9jYXRpb247XG4gICAgfSxcblxuICAgIGNyZWF0ZUhyZWY6IGNyZWF0ZUhyZWYsXG4gICAgcHVzaDogcHVzaCxcbiAgICByZXBsYWNlOiByZXBsYWNlLFxuICAgIGdvOiBnbyxcbiAgICBiYWNrOiBmdW5jdGlvbiBiYWNrKCkge1xuICAgICAgZ28oLTEpO1xuICAgIH0sXG4gICAgZm9yd2FyZDogZnVuY3Rpb24gZm9yd2FyZCgpIHtcbiAgICAgIGdvKDEpO1xuICAgIH0sXG4gICAgbGlzdGVuOiBmdW5jdGlvbiBsaXN0ZW4obGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBsaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgfSxcbiAgICBibG9jazogZnVuY3Rpb24gYmxvY2soYmxvY2tlcikge1xuICAgICAgdmFyIHVuYmxvY2sgPSBibG9ja2Vycy5wdXNoKGJsb2NrZXIpO1xuXG4gICAgICBpZiAoYmxvY2tlcnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEJlZm9yZVVubG9hZEV2ZW50VHlwZSwgcHJvbXB0QmVmb3JlVW5sb2FkKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdW5ibG9jaygpOyAvLyBSZW1vdmUgdGhlIGJlZm9yZXVubG9hZCBsaXN0ZW5lciBzbyB0aGUgZG9jdW1lbnQgbWF5XG4gICAgICAgIC8vIHN0aWxsIGJlIHNhbHZhZ2VhYmxlIGluIHRoZSBwYWdlaGlkZSBldmVudC5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI3VubG9hZGluZy1kb2N1bWVudHNcblxuICAgICAgICBpZiAoIWJsb2NrZXJzLmxlbmd0aCkge1xuICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEJlZm9yZVVubG9hZEV2ZW50VHlwZSwgcHJvbXB0QmVmb3JlVW5sb2FkKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBoaXN0b3J5O1xufVxuLyoqXHJcbiAqIE1lbW9yeSBoaXN0b3J5IHN0b3JlcyB0aGUgY3VycmVudCBsb2NhdGlvbiBpbiBtZW1vcnkuIEl0IGlzIGRlc2lnbmVkIGZvciB1c2VcclxuICogaW4gc3RhdGVmdWwgbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRzIGxpa2UgdGVzdHMgYW5kIFJlYWN0IE5hdGl2ZS5cclxuICpcclxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVtaXgtcnVuL2hpc3RvcnkvdHJlZS9tYWluL2RvY3MvYXBpLXJlZmVyZW5jZS5tZCNjcmVhdGVtZW1vcnloaXN0b3J5XHJcbiAqL1xuXG5mdW5jdGlvbiBjcmVhdGVNZW1vcnlIaXN0b3J5KG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9uczMgPSBvcHRpb25zLFxuICAgICAgX29wdGlvbnMzJGluaXRpYWxFbnRyID0gX29wdGlvbnMzLmluaXRpYWxFbnRyaWVzLFxuICAgICAgaW5pdGlhbEVudHJpZXMgPSBfb3B0aW9uczMkaW5pdGlhbEVudHIgPT09IHZvaWQgMCA/IFsnLyddIDogX29wdGlvbnMzJGluaXRpYWxFbnRyLFxuICAgICAgaW5pdGlhbEluZGV4ID0gX29wdGlvbnMzLmluaXRpYWxJbmRleDtcbiAgdmFyIGVudHJpZXMgPSBpbml0aWFsRW50cmllcy5tYXAoZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgdmFyIGxvY2F0aW9uID0gcmVhZE9ubHkoX2V4dGVuZHMoe1xuICAgICAgcGF0aG5hbWU6ICcvJyxcbiAgICAgIHNlYXJjaDogJycsXG4gICAgICBoYXNoOiAnJyxcbiAgICAgIHN0YXRlOiBudWxsLFxuICAgICAga2V5OiBjcmVhdGVLZXkoKVxuICAgIH0sIHR5cGVvZiBlbnRyeSA9PT0gJ3N0cmluZycgPyBwYXJzZVBhdGgoZW50cnkpIDogZW50cnkpKTtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIgPyB3YXJuaW5nKGxvY2F0aW9uLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nLCBcIlJlbGF0aXZlIHBhdGhuYW1lcyBhcmUgbm90IHN1cHBvcnRlZCBpbiBjcmVhdGVNZW1vcnlIaXN0b3J5KHsgaW5pdGlhbEVudHJpZXMgfSkgKGludmFsaWQgZW50cnk6IFwiICsgSlNPTi5zdHJpbmdpZnkoZW50cnkpICsgXCIpXCIpIDogdm9pZCAwO1xuICAgIHJldHVybiBsb2NhdGlvbjtcbiAgfSk7XG4gIHZhciBpbmRleCA9IGNsYW1wKGluaXRpYWxJbmRleCA9PSBudWxsID8gZW50cmllcy5sZW5ndGggLSAxIDogaW5pdGlhbEluZGV4LCAwLCBlbnRyaWVzLmxlbmd0aCAtIDEpO1xuICB2YXIgYWN0aW9uID0gQWN0aW9uLlBvcDtcbiAgdmFyIGxvY2F0aW9uID0gZW50cmllc1tpbmRleF07XG4gIHZhciBsaXN0ZW5lcnMgPSBjcmVhdGVFdmVudHMoKTtcbiAgdmFyIGJsb2NrZXJzID0gY3JlYXRlRXZlbnRzKCk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlSHJlZih0bykge1xuICAgIHJldHVybiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnID8gdG8gOiBjcmVhdGVQYXRoKHRvKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE5leHRMb2NhdGlvbih0bywgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUgPT09IHZvaWQgMCkge1xuICAgICAgc3RhdGUgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiByZWFkT25seShfZXh0ZW5kcyh7XG4gICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBzZWFyY2g6ICcnLFxuICAgICAgaGFzaDogJydcbiAgICB9LCB0eXBlb2YgdG8gPT09ICdzdHJpbmcnID8gcGFyc2VQYXRoKHRvKSA6IHRvLCB7XG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICBrZXk6IGNyZWF0ZUtleSgpXG4gICAgfSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gYWxsb3dUeChhY3Rpb24sIGxvY2F0aW9uLCByZXRyeSkge1xuICAgIHJldHVybiAhYmxvY2tlcnMubGVuZ3RoIHx8IChibG9ja2Vycy5jYWxsKHtcbiAgICAgIGFjdGlvbjogYWN0aW9uLFxuICAgICAgbG9jYXRpb246IGxvY2F0aW9uLFxuICAgICAgcmV0cnk6IHJldHJ5XG4gICAgfSksIGZhbHNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGx5VHgobmV4dEFjdGlvbiwgbmV4dExvY2F0aW9uKSB7XG4gICAgYWN0aW9uID0gbmV4dEFjdGlvbjtcbiAgICBsb2NhdGlvbiA9IG5leHRMb2NhdGlvbjtcbiAgICBsaXN0ZW5lcnMuY2FsbCh7XG4gICAgICBhY3Rpb246IGFjdGlvbixcbiAgICAgIGxvY2F0aW9uOiBsb2NhdGlvblxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gcHVzaCh0bywgc3RhdGUpIHtcbiAgICB2YXIgbmV4dEFjdGlvbiA9IEFjdGlvbi5QdXNoO1xuICAgIHZhciBuZXh0TG9jYXRpb24gPSBnZXROZXh0TG9jYXRpb24odG8sIHN0YXRlKTtcblxuICAgIGZ1bmN0aW9uIHJldHJ5KCkge1xuICAgICAgcHVzaCh0bywgc3RhdGUpO1xuICAgIH1cblxuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIiA/IHdhcm5pbmcobG9jYXRpb24ucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycsIFwiUmVsYXRpdmUgcGF0aG5hbWVzIGFyZSBub3Qgc3VwcG9ydGVkIGluIG1lbW9yeSBoaXN0b3J5LnB1c2goXCIgKyBKU09OLnN0cmluZ2lmeSh0bykgKyBcIilcIikgOiB2b2lkIDA7XG5cbiAgICBpZiAoYWxsb3dUeChuZXh0QWN0aW9uLCBuZXh0TG9jYXRpb24sIHJldHJ5KSkge1xuICAgICAgaW5kZXggKz0gMTtcbiAgICAgIGVudHJpZXMuc3BsaWNlKGluZGV4LCBlbnRyaWVzLmxlbmd0aCwgbmV4dExvY2F0aW9uKTtcbiAgICAgIGFwcGx5VHgobmV4dEFjdGlvbiwgbmV4dExvY2F0aW9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXBsYWNlKHRvLCBzdGF0ZSkge1xuICAgIHZhciBuZXh0QWN0aW9uID0gQWN0aW9uLlJlcGxhY2U7XG4gICAgdmFyIG5leHRMb2NhdGlvbiA9IGdldE5leHRMb2NhdGlvbih0bywgc3RhdGUpO1xuXG4gICAgZnVuY3Rpb24gcmV0cnkoKSB7XG4gICAgICByZXBsYWNlKHRvLCBzdGF0ZSk7XG4gICAgfVxuXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiID8gd2FybmluZyhsb2NhdGlvbi5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJywgXCJSZWxhdGl2ZSBwYXRobmFtZXMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gbWVtb3J5IGhpc3RvcnkucmVwbGFjZShcIiArIEpTT04uc3RyaW5naWZ5KHRvKSArIFwiKVwiKSA6IHZvaWQgMDtcblxuICAgIGlmIChhbGxvd1R4KG5leHRBY3Rpb24sIG5leHRMb2NhdGlvbiwgcmV0cnkpKSB7XG4gICAgICBlbnRyaWVzW2luZGV4XSA9IG5leHRMb2NhdGlvbjtcbiAgICAgIGFwcGx5VHgobmV4dEFjdGlvbiwgbmV4dExvY2F0aW9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnbyhkZWx0YSkge1xuICAgIHZhciBuZXh0SW5kZXggPSBjbGFtcChpbmRleCArIGRlbHRhLCAwLCBlbnRyaWVzLmxlbmd0aCAtIDEpO1xuICAgIHZhciBuZXh0QWN0aW9uID0gQWN0aW9uLlBvcDtcbiAgICB2YXIgbmV4dExvY2F0aW9uID0gZW50cmllc1tuZXh0SW5kZXhdO1xuXG4gICAgZnVuY3Rpb24gcmV0cnkoKSB7XG4gICAgICBnbyhkZWx0YSk7XG4gICAgfVxuXG4gICAgaWYgKGFsbG93VHgobmV4dEFjdGlvbiwgbmV4dExvY2F0aW9uLCByZXRyeSkpIHtcbiAgICAgIGluZGV4ID0gbmV4dEluZGV4O1xuICAgICAgYXBwbHlUeChuZXh0QWN0aW9uLCBuZXh0TG9jYXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIHZhciBoaXN0b3J5ID0ge1xuICAgIGdldCBpbmRleCgpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9LFxuXG4gICAgZ2V0IGFjdGlvbigpIHtcbiAgICAgIHJldHVybiBhY3Rpb247XG4gICAgfSxcblxuICAgIGdldCBsb2NhdGlvbigpIHtcbiAgICAgIHJldHVybiBsb2NhdGlvbjtcbiAgICB9LFxuXG4gICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZixcbiAgICBwdXNoOiBwdXNoLFxuICAgIHJlcGxhY2U6IHJlcGxhY2UsXG4gICAgZ286IGdvLFxuICAgIGJhY2s6IGZ1bmN0aW9uIGJhY2soKSB7XG4gICAgICBnbygtMSk7XG4gICAgfSxcbiAgICBmb3J3YXJkOiBmdW5jdGlvbiBmb3J3YXJkKCkge1xuICAgICAgZ28oMSk7XG4gICAgfSxcbiAgICBsaXN0ZW46IGZ1bmN0aW9uIGxpc3RlbihsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9LFxuICAgIGJsb2NrOiBmdW5jdGlvbiBibG9jayhibG9ja2VyKSB7XG4gICAgICByZXR1cm4gYmxvY2tlcnMucHVzaChibG9ja2VyKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBoaXN0b3J5O1xufSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gVVRJTFNcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNsYW1wKG4sIGxvd2VyQm91bmQsIHVwcGVyQm91bmQpIHtcbiAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG4sIGxvd2VyQm91bmQpLCB1cHBlckJvdW5kKTtcbn1cblxuZnVuY3Rpb24gcHJvbXB0QmVmb3JlVW5sb2FkKGV2ZW50KSB7XG4gIC8vIENhbmNlbCB0aGUgZXZlbnQuXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIENocm9tZSAoYW5kIGxlZ2FjeSBJRSkgcmVxdWlyZXMgcmV0dXJuVmFsdWUgdG8gYmUgc2V0LlxuXG4gIGV2ZW50LnJldHVyblZhbHVlID0gJyc7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUV2ZW50cygpIHtcbiAgdmFyIGhhbmRsZXJzID0gW107XG4gIHJldHVybiB7XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgIHJldHVybiBoYW5kbGVycy5sZW5ndGg7XG4gICAgfSxcblxuICAgIHB1c2g6IGZ1bmN0aW9uIHB1c2goZm4pIHtcbiAgICAgIGhhbmRsZXJzLnB1c2goZm4pO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaGFuZGxlcnMgPSBoYW5kbGVycy5maWx0ZXIoZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlciAhPT0gZm47XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9LFxuICAgIGNhbGw6IGZ1bmN0aW9uIGNhbGwoYXJnKSB7XG4gICAgICBoYW5kbGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZm4gJiYgZm4oYXJnKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlS2V5KCkge1xuICByZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDgpO1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBzdHJpbmcgVVJMIHBhdGggZnJvbSB0aGUgZ2l2ZW4gcGF0aG5hbWUsIHNlYXJjaCwgYW5kIGhhc2ggY29tcG9uZW50cy5cclxuICpcclxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVtaXgtcnVuL2hpc3RvcnkvdHJlZS9tYWluL2RvY3MvYXBpLXJlZmVyZW5jZS5tZCNjcmVhdGVwYXRoXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNyZWF0ZVBhdGgoX3JlZikge1xuICB2YXIgX3JlZiRwYXRobmFtZSA9IF9yZWYucGF0aG5hbWUsXG4gICAgICBwYXRobmFtZSA9IF9yZWYkcGF0aG5hbWUgPT09IHZvaWQgMCA/ICcvJyA6IF9yZWYkcGF0aG5hbWUsXG4gICAgICBfcmVmJHNlYXJjaCA9IF9yZWYuc2VhcmNoLFxuICAgICAgc2VhcmNoID0gX3JlZiRzZWFyY2ggPT09IHZvaWQgMCA/ICcnIDogX3JlZiRzZWFyY2gsXG4gICAgICBfcmVmJGhhc2ggPSBfcmVmLmhhc2gsXG4gICAgICBoYXNoID0gX3JlZiRoYXNoID09PSB2b2lkIDAgPyAnJyA6IF9yZWYkaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2ggIT09ICc/JykgcGF0aG5hbWUgKz0gc2VhcmNoLmNoYXJBdCgwKSA9PT0gJz8nID8gc2VhcmNoIDogJz8nICsgc2VhcmNoO1xuICBpZiAoaGFzaCAmJiBoYXNoICE9PSAnIycpIHBhdGhuYW1lICs9IGhhc2guY2hhckF0KDApID09PSAnIycgPyBoYXNoIDogJyMnICsgaGFzaDtcbiAgcmV0dXJuIHBhdGhuYW1lO1xufVxuLyoqXHJcbiAqIFBhcnNlcyBhIHN0cmluZyBVUkwgcGF0aCBpbnRvIGl0cyBzZXBhcmF0ZSBwYXRobmFtZSwgc2VhcmNoLCBhbmQgaGFzaCBjb21wb25lbnRzLlxyXG4gKlxyXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZW1peC1ydW4vaGlzdG9yeS90cmVlL21haW4vZG9jcy9hcGktcmVmZXJlbmNlLm1kI3BhcnNlcGF0aFxyXG4gKi9cblxuZnVuY3Rpb24gcGFyc2VQYXRoKHBhdGgpIHtcbiAgdmFyIHBhcnNlZFBhdGggPSB7fTtcblxuICBpZiAocGF0aCkge1xuICAgIHZhciBoYXNoSW5kZXggPSBwYXRoLmluZGV4T2YoJyMnKTtcblxuICAgIGlmIChoYXNoSW5kZXggPj0gMCkge1xuICAgICAgcGFyc2VkUGF0aC5oYXNoID0gcGF0aC5zdWJzdHIoaGFzaEluZGV4KTtcbiAgICAgIHBhdGggPSBwYXRoLnN1YnN0cigwLCBoYXNoSW5kZXgpO1xuICAgIH1cblxuICAgIHZhciBzZWFyY2hJbmRleCA9IHBhdGguaW5kZXhPZignPycpO1xuXG4gICAgaWYgKHNlYXJjaEluZGV4ID49IDApIHtcbiAgICAgIHBhcnNlZFBhdGguc2VhcmNoID0gcGF0aC5zdWJzdHIoc2VhcmNoSW5kZXgpO1xuICAgICAgcGF0aCA9IHBhdGguc3Vic3RyKDAsIHNlYXJjaEluZGV4KTtcbiAgICB9XG5cbiAgICBpZiAocGF0aCkge1xuICAgICAgcGFyc2VkUGF0aC5wYXRobmFtZSA9IHBhdGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcnNlZFBhdGg7XG59XG5cbmV4cG9ydCB7IEFjdGlvbiwgY3JlYXRlQnJvd3Nlckhpc3RvcnksIGNyZWF0ZUhhc2hIaXN0b3J5LCBjcmVhdGVNZW1vcnlIaXN0b3J5LCBjcmVhdGVQYXRoLCBwYXJzZVBhdGggfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcFxuIiwgImltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHR5cGUgeyBIaXN0b3J5LCBMb2NhdGlvbiB9IGZyb20gXCJoaXN0b3J5XCI7XG5pbXBvcnQgeyBBY3Rpb24gYXMgTmF2aWdhdGlvblR5cGUgfSBmcm9tIFwiaGlzdG9yeVwiO1xuXG5pbXBvcnQgdHlwZSB7IFJvdXRlTWF0Y2ggfSBmcm9tIFwiLi9yb3V0ZXJcIjtcblxuLyoqXG4gKiBBIE5hdmlnYXRvciBpcyBhIFwibG9jYXRpb24gY2hhbmdlclwiOyBpdCdzIGhvdyB5b3UgZ2V0IHRvIGRpZmZlcmVudCBsb2NhdGlvbnMuXG4gKlxuICogRXZlcnkgaGlzdG9yeSBpbnN0YW5jZSBjb25mb3JtcyB0byB0aGUgTmF2aWdhdG9yIGludGVyZmFjZSwgYnV0IHRoZVxuICogZGlzdGluY3Rpb24gaXMgdXNlZnVsIHByaW1hcmlseSB3aGVuIGl0IGNvbWVzIHRvIHRoZSBsb3ctbGV2ZWwgPFJvdXRlcj4gQVBJXG4gKiB3aGVyZSBib3RoIHRoZSBsb2NhdGlvbiBhbmQgYSBuYXZpZ2F0b3IgbXVzdCBiZSBwcm92aWRlZCBzZXBhcmF0ZWx5IGluIG9yZGVyXG4gKiB0byBhdm9pZCBcInRlYXJpbmdcIiB0aGF0IG1heSBvY2N1ciBpbiBhIHN1c3BlbnNlLWVuYWJsZWQgYXBwIGlmIHRoZSBhY3Rpb25cbiAqIGFuZC9vciBsb2NhdGlvbiB3ZXJlIHRvIGJlIHJlYWQgZGlyZWN0bHkgZnJvbSB0aGUgaGlzdG9yeSBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IHR5cGUgTmF2aWdhdG9yID0gUGljazxIaXN0b3J5LCBcImdvXCIgfCBcInB1c2hcIiB8IFwicmVwbGFjZVwiIHwgXCJjcmVhdGVIcmVmXCI+O1xuXG5pbnRlcmZhY2UgTmF2aWdhdGlvbkNvbnRleHRPYmplY3Qge1xuICBiYXNlbmFtZTogc3RyaW5nO1xuICBuYXZpZ2F0b3I6IE5hdmlnYXRvcjtcbiAgc3RhdGljOiBib29sZWFuO1xufVxuXG5leHBvcnQgY29uc3QgTmF2aWdhdGlvbkNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PE5hdmlnYXRpb25Db250ZXh0T2JqZWN0PihcbiAgbnVsbCFcbik7XG5cbmlmIChfX0RFVl9fKSB7XG4gIE5hdmlnYXRpb25Db250ZXh0LmRpc3BsYXlOYW1lID0gXCJOYXZpZ2F0aW9uXCI7XG59XG5cbmludGVyZmFjZSBMb2NhdGlvbkNvbnRleHRPYmplY3Qge1xuICBsb2NhdGlvbjogTG9jYXRpb247XG4gIG5hdmlnYXRpb25UeXBlOiBOYXZpZ2F0aW9uVHlwZTtcbn1cblxuZXhwb3J0IGNvbnN0IExvY2F0aW9uQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8TG9jYXRpb25Db250ZXh0T2JqZWN0PihcbiAgbnVsbCFcbik7XG5cbmlmIChfX0RFVl9fKSB7XG4gIExvY2F0aW9uQ29udGV4dC5kaXNwbGF5TmFtZSA9IFwiTG9jYXRpb25cIjtcbn1cblxuaW50ZXJmYWNlIFJvdXRlQ29udGV4dE9iamVjdCB7XG4gIG91dGxldDogUmVhY3QuUmVhY3RFbGVtZW50IHwgbnVsbDtcbiAgbWF0Y2hlczogUm91dGVNYXRjaFtdO1xufVxuXG5leHBvcnQgY29uc3QgUm91dGVDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxSb3V0ZUNvbnRleHRPYmplY3Q+KHtcbiAgb3V0bGV0OiBudWxsLFxuICBtYXRjaGVzOiBbXSxcbn0pO1xuXG5pZiAoX19ERVZfXykge1xuICBSb3V0ZUNvbnRleHQuZGlzcGxheU5hbWUgPSBcIlJvdXRlXCI7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBMb2NhdGlvbiwgUGF0aCwgVG8gfSBmcm9tIFwiaGlzdG9yeVwiO1xuaW1wb3J0IHsgcGFyc2VQYXRoIH0gZnJvbSBcImhpc3RvcnlcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGludmFyaWFudChjb25kOiBhbnksIG1lc3NhZ2U6IHN0cmluZyk6IGFzc2VydHMgY29uZCB7XG4gIGlmICghY29uZCkgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2FybmluZyhjb25kOiBhbnksIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICBpZiAoIWNvbmQpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIikgY29uc29sZS53YXJuKG1lc3NhZ2UpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFdlbGNvbWUgdG8gZGVidWdnaW5nIFJlYWN0IFJvdXRlciFcbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIGVycm9yIGlzIHRocm93biBhcyBhIGNvbnZlbmllbmNlIHNvIHlvdSBjYW4gbW9yZSBlYXNpbHlcbiAgICAgIC8vIGZpbmQgdGhlIHNvdXJjZSBmb3IgYSB3YXJuaW5nIHRoYXQgYXBwZWFycyBpbiB0aGUgY29uc29sZSBieVxuICAgICAgLy8gZW5hYmxpbmcgXCJwYXVzZSBvbiBleGNlcHRpb25zXCIgaW4geW91ciBKYXZhU2NyaXB0IGRlYnVnZ2VyLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxufVxuXG5jb25zdCBhbHJlYWR5V2FybmVkOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiA9IHt9O1xuZXhwb3J0IGZ1bmN0aW9uIHdhcm5pbmdPbmNlKGtleTogc3RyaW5nLCBjb25kOiBib29sZWFuLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgaWYgKCFjb25kICYmICFhbHJlYWR5V2FybmVkW2tleV0pIHtcbiAgICBhbHJlYWR5V2FybmVkW2tleV0gPSB0cnVlO1xuICAgIHdhcm5pbmcoZmFsc2UsIG1lc3NhZ2UpO1xuICB9XG59XG5cbnR5cGUgUGFyYW1QYXJzZUZhaWxlZCA9IHsgZmFpbGVkOiB0cnVlIH07XG5cbnR5cGUgUGFyYW1QYXJzZVNlZ21lbnQ8U2VnbWVudCBleHRlbmRzIHN0cmluZz4gPVxuICAvLyBDaGVjayBoZXJlIGlmIHRoZXJlIGV4aXN0cyBhIGZvcndhcmQgc2xhc2ggaW4gdGhlIHN0cmluZy5cbiAgU2VnbWVudCBleHRlbmRzIGAke2luZmVyIExlZnRTZWdtZW50fS8ke2luZmVyIFJpZ2h0U2VnbWVudH1gXG4gICAgPyAvLyBJZiB0aGVyZSBpcyBhIGZvcndhcmQgc2xhc2gsIHRoZW4gYXR0ZW1wdCB0byBwYXJzZSBlYWNoIHNpZGUgb2YgdGhlXG4gICAgICAvLyBmb3J3YXJkIHNsYXNoLlxuICAgICAgUGFyYW1QYXJzZVNlZ21lbnQ8TGVmdFNlZ21lbnQ+IGV4dGVuZHMgaW5mZXIgTGVmdFJlc3VsdFxuICAgICAgPyBQYXJhbVBhcnNlU2VnbWVudDxSaWdodFNlZ21lbnQ+IGV4dGVuZHMgaW5mZXIgUmlnaHRSZXN1bHRcbiAgICAgICAgPyBMZWZ0UmVzdWx0IGV4dGVuZHMgc3RyaW5nXG4gICAgICAgICAgPyAvLyBJZiB0aGUgbGVmdCBzaWRlIGlzIHN1Y2Nlc3NmdWxseSBwYXJzZWQgYXMgYSBwYXJhbSwgdGhlbiBjaGVjayBpZlxuICAgICAgICAgICAgLy8gdGhlIHJpZ2h0IHNpZGUgY2FuIGJlIHN1Y2Nlc3NmdWxseSBwYXJzZWQgYXMgd2VsbC4gSWYgYm90aCBzaWRlc1xuICAgICAgICAgICAgLy8gY2FuIGJlIHBhcnNlZCwgdGhlbiB0aGUgcmVzdWx0IGlzIGEgdW5pb24gb2YgdGhlIHR3byBzaWRlc1xuICAgICAgICAgICAgLy8gKHJlYWQ6IFwiZm9vXCIgfCBcImJhclwiKS5cbiAgICAgICAgICAgIFJpZ2h0UmVzdWx0IGV4dGVuZHMgc3RyaW5nXG4gICAgICAgICAgICA/IExlZnRSZXN1bHQgfCBSaWdodFJlc3VsdFxuICAgICAgICAgICAgOiBMZWZ0UmVzdWx0XG4gICAgICAgICAgOiAvLyBJZiB0aGUgbGVmdCBzaWRlIGlzIG5vdCBzdWNjZXNzZnVsbHkgcGFyc2VkIGFzIGEgcGFyYW0sIHRoZW4gY2hlY2tcbiAgICAgICAgICAvLyBpZiBvbmx5IHRoZSByaWdodCBzaWRlIGNhbiBiZSBzdWNjZXNzZnVsbHkgcGFyc2UgYXMgYSBwYXJhbS4gSWYgaXRcbiAgICAgICAgICAvLyBjYW4sIHRoZW4gdGhlIHJlc3VsdCBpcyBqdXN0IHJpZ2h0LCBlbHNlIGl0J3MgYSBmYWlsdXJlLlxuICAgICAgICAgIFJpZ2h0UmVzdWx0IGV4dGVuZHMgc3RyaW5nXG4gICAgICAgICAgPyBSaWdodFJlc3VsdFxuICAgICAgICAgIDogUGFyYW1QYXJzZUZhaWxlZFxuICAgICAgICA6IFBhcmFtUGFyc2VGYWlsZWRcbiAgICAgIDogLy8gSWYgdGhlIGxlZnQgc2lkZSBkaWRuJ3QgcGFyc2UgaW50byBhIHBhcmFtLCB0aGVuIGp1c3QgY2hlY2sgdGhlIHJpZ2h0XG4gICAgICAvLyBzaWRlLlxuICAgICAgUGFyYW1QYXJzZVNlZ21lbnQ8UmlnaHRTZWdtZW50PiBleHRlbmRzIGluZmVyIFJpZ2h0UmVzdWx0XG4gICAgICA/IFJpZ2h0UmVzdWx0IGV4dGVuZHMgc3RyaW5nXG4gICAgICAgID8gUmlnaHRSZXN1bHRcbiAgICAgICAgOiBQYXJhbVBhcnNlRmFpbGVkXG4gICAgICA6IFBhcmFtUGFyc2VGYWlsZWRcbiAgICA6IC8vIElmIHRoZXJlJ3Mgbm8gZm9yd2FyZCBzbGFzaCwgdGhlbiBjaGVjayBpZiB0aGlzIHNlZ21lbnQgc3RhcnRzIHdpdGggYVxuICAgIC8vIGNvbG9uLiBJZiBpdCBkb2VzLCB0aGVuIHRoaXMgaXMgYSBkeW5hbWljIHNlZ21lbnQsIHNvIHRoZSByZXN1bHQgaXNcbiAgICAvLyBqdXN0IHRoZSByZW1haW5kZXIgb2YgdGhlIHN0cmluZy4gT3RoZXJ3aXNlLCBpdCdzIGEgZmFpbHVyZS5cbiAgICBTZWdtZW50IGV4dGVuZHMgYDoke2luZmVyIFJlbWFpbmluZ31gXG4gICAgPyBSZW1haW5pbmdcbiAgICA6IFBhcmFtUGFyc2VGYWlsZWQ7XG5cbi8vIEF0dGVtcHQgdG8gcGFyc2UgdGhlIGdpdmVuIHN0cmluZyBzZWdtZW50LiBJZiBpdCBmYWlscywgdGhlbiBqdXN0IHJldHVybiB0aGVcbi8vIHBsYWluIHN0cmluZyB0eXBlIGFzIGEgZGVmYXVsdCBmYWxsYmFjay4gT3RoZXJ3aXNlIHJldHVybiB0aGUgdW5pb24gb2YgdGhlXG4vLyBwYXJzZWQgc3RyaW5nIGxpdGVyYWxzIHRoYXQgd2VyZSByZWZlcmVuY2VkIGFzIGR5bmFtaWMgc2VnbWVudHMgaW4gdGhlIHJvdXRlLlxuZXhwb3J0IHR5cGUgUGFyYW1QYXJzZUtleTxTZWdtZW50IGV4dGVuZHMgc3RyaW5nPiA9XG4gIFBhcmFtUGFyc2VTZWdtZW50PFNlZ21lbnQ+IGV4dGVuZHMgc3RyaW5nXG4gICAgPyBQYXJhbVBhcnNlU2VnbWVudDxTZWdtZW50PlxuICAgIDogc3RyaW5nO1xuXG4vKipcbiAqIFRoZSBwYXJhbWV0ZXJzIHRoYXQgd2VyZSBwYXJzZWQgZnJvbSB0aGUgVVJMIHBhdGguXG4gKi9cbmV4cG9ydCB0eXBlIFBhcmFtczxLZXkgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0ge1xuICByZWFkb25seSBba2V5IGluIEtleV06IHN0cmluZyB8IHVuZGVmaW5lZDtcbn07XG5cbi8qKlxuICogQSByb3V0ZSBvYmplY3QgcmVwcmVzZW50cyBhIGxvZ2ljYWwgcm91dGUsIHdpdGggKG9wdGlvbmFsbHkpIGl0cyBjaGlsZFxuICogcm91dGVzIG9yZ2FuaXplZCBpbiBhIHRyZWUtbGlrZSBzdHJ1Y3R1cmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGVPYmplY3Qge1xuICBjYXNlU2Vuc2l0aXZlPzogYm9vbGVhbjtcbiAgY2hpbGRyZW4/OiBSb3V0ZU9iamVjdFtdO1xuICBlbGVtZW50PzogUmVhY3QuUmVhY3ROb2RlO1xuICBpbmRleD86IGJvb2xlYW47XG4gIHBhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHBhdGggd2l0aCBwYXJhbXMgaW50ZXJwb2xhdGVkLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vZG9jcy9lbi92Ni9hcGkjZ2VuZXJhdGVwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVBhdGgocGF0aDogc3RyaW5nLCBwYXJhbXM6IFBhcmFtcyA9IHt9KTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGhcbiAgICAucmVwbGFjZSgvOihcXHcrKS9nLCAoXywga2V5KSA9PiB7XG4gICAgICBpbnZhcmlhbnQocGFyYW1zW2tleV0gIT0gbnVsbCwgYE1pc3NpbmcgXCI6JHtrZXl9XCIgcGFyYW1gKTtcbiAgICAgIHJldHVybiBwYXJhbXNba2V5XSE7XG4gICAgfSlcbiAgICAucmVwbGFjZSgvXFwvKlxcKiQvLCAoXykgPT5cbiAgICAgIHBhcmFtc1tcIipcIl0gPT0gbnVsbCA/IFwiXCIgOiBwYXJhbXNbXCIqXCJdLnJlcGxhY2UoL15cXC8qLywgXCIvXCIpXG4gICAgKTtcbn1cblxuLyoqXG4gKiBBIFJvdXRlTWF0Y2ggY29udGFpbnMgaW5mbyBhYm91dCBob3cgYSByb3V0ZSBtYXRjaGVkIGEgVVJMLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlTWF0Y2g8UGFyYW1LZXkgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lcyBhbmQgdmFsdWVzIG9mIGR5bmFtaWMgcGFyYW1ldGVycyBpbiB0aGUgVVJMLlxuICAgKi9cbiAgcGFyYW1zOiBQYXJhbXM8UGFyYW1LZXk+O1xuICAvKipcbiAgICogVGhlIHBvcnRpb24gb2YgdGhlIFVSTCBwYXRobmFtZSB0aGF0IHdhcyBtYXRjaGVkLlxuICAgKi9cbiAgcGF0aG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBwb3J0aW9uIG9mIHRoZSBVUkwgcGF0aG5hbWUgdGhhdCB3YXMgbWF0Y2hlZCBiZWZvcmUgY2hpbGQgcm91dGVzLlxuICAgKi9cbiAgcGF0aG5hbWVCYXNlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgcm91dGUgb2JqZWN0IHRoYXQgd2FzIHVzZWQgdG8gbWF0Y2guXG4gICAqL1xuICByb3V0ZTogUm91dGVPYmplY3Q7XG59XG5cbi8qKlxuICogTWF0Y2hlcyB0aGUgZ2l2ZW4gcm91dGVzIHRvIGEgbG9jYXRpb24gYW5kIHJldHVybnMgdGhlIG1hdGNoIGRhdGEuXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSNtYXRjaHJvdXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hSb3V0ZXMoXG4gIHJvdXRlczogUm91dGVPYmplY3RbXSxcbiAgbG9jYXRpb25Bcmc6IFBhcnRpYWw8TG9jYXRpb24+IHwgc3RyaW5nLFxuICBiYXNlbmFtZSA9IFwiL1wiXG4pOiBSb3V0ZU1hdGNoW10gfCBudWxsIHtcbiAgbGV0IGxvY2F0aW9uID1cbiAgICB0eXBlb2YgbG9jYXRpb25BcmcgPT09IFwic3RyaW5nXCIgPyBwYXJzZVBhdGgobG9jYXRpb25BcmcpIDogbG9jYXRpb25Bcmc7XG5cbiAgbGV0IHBhdGhuYW1lID0gc3RyaXBCYXNlbmFtZShsb2NhdGlvbi5wYXRobmFtZSB8fCBcIi9cIiwgYmFzZW5hbWUpO1xuXG4gIGlmIChwYXRobmFtZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBsZXQgYnJhbmNoZXMgPSBmbGF0dGVuUm91dGVzKHJvdXRlcyk7XG4gIHJhbmtSb3V0ZUJyYW5jaGVzKGJyYW5jaGVzKTtcblxuICBsZXQgbWF0Y2hlcyA9IG51bGw7XG4gIGZvciAobGV0IGkgPSAwOyBtYXRjaGVzID09IG51bGwgJiYgaSA8IGJyYW5jaGVzLmxlbmd0aDsgKytpKSB7XG4gICAgbWF0Y2hlcyA9IG1hdGNoUm91dGVCcmFuY2goYnJhbmNoZXNbaV0sIHBhdGhuYW1lKTtcbiAgfVxuXG4gIHJldHVybiBtYXRjaGVzO1xufVxuXG5pbnRlcmZhY2UgUm91dGVNZXRhIHtcbiAgcmVsYXRpdmVQYXRoOiBzdHJpbmc7XG4gIGNhc2VTZW5zaXRpdmU6IGJvb2xlYW47XG4gIGNoaWxkcmVuSW5kZXg6IG51bWJlcjtcbiAgcm91dGU6IFJvdXRlT2JqZWN0O1xufVxuXG5pbnRlcmZhY2UgUm91dGVCcmFuY2gge1xuICBwYXRoOiBzdHJpbmc7XG4gIHNjb3JlOiBudW1iZXI7XG4gIHJvdXRlc01ldGE6IFJvdXRlTWV0YVtdO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuUm91dGVzKFxuICByb3V0ZXM6IFJvdXRlT2JqZWN0W10sXG4gIGJyYW5jaGVzOiBSb3V0ZUJyYW5jaFtdID0gW10sXG4gIHBhcmVudHNNZXRhOiBSb3V0ZU1ldGFbXSA9IFtdLFxuICBwYXJlbnRQYXRoID0gXCJcIlxuKTogUm91dGVCcmFuY2hbXSB7XG4gIHJvdXRlcy5mb3JFYWNoKChyb3V0ZSwgaW5kZXgpID0+IHtcbiAgICBsZXQgbWV0YTogUm91dGVNZXRhID0ge1xuICAgICAgcmVsYXRpdmVQYXRoOiByb3V0ZS5wYXRoIHx8IFwiXCIsXG4gICAgICBjYXNlU2Vuc2l0aXZlOiByb3V0ZS5jYXNlU2Vuc2l0aXZlID09PSB0cnVlLFxuICAgICAgY2hpbGRyZW5JbmRleDogaW5kZXgsXG4gICAgICByb3V0ZSxcbiAgICB9O1xuXG4gICAgaWYgKG1ldGEucmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgICBpbnZhcmlhbnQoXG4gICAgICAgIG1ldGEucmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgocGFyZW50UGF0aCksXG4gICAgICAgIGBBYnNvbHV0ZSByb3V0ZSBwYXRoIFwiJHttZXRhLnJlbGF0aXZlUGF0aH1cIiBuZXN0ZWQgdW5kZXIgcGF0aCBgICtcbiAgICAgICAgICBgXCIke3BhcmVudFBhdGh9XCIgaXMgbm90IHZhbGlkLiBBbiBhYnNvbHV0ZSBjaGlsZCByb3V0ZSBwYXRoIGAgK1xuICAgICAgICAgIGBtdXN0IHN0YXJ0IHdpdGggdGhlIGNvbWJpbmVkIHBhdGggb2YgYWxsIGl0cyBwYXJlbnQgcm91dGVzLmBcbiAgICAgICk7XG5cbiAgICAgIG1ldGEucmVsYXRpdmVQYXRoID0gbWV0YS5yZWxhdGl2ZVBhdGguc2xpY2UocGFyZW50UGF0aC5sZW5ndGgpO1xuICAgIH1cblxuICAgIGxldCBwYXRoID0gam9pblBhdGhzKFtwYXJlbnRQYXRoLCBtZXRhLnJlbGF0aXZlUGF0aF0pO1xuICAgIGxldCByb3V0ZXNNZXRhID0gcGFyZW50c01ldGEuY29uY2F0KG1ldGEpO1xuXG4gICAgLy8gQWRkIHRoZSBjaGlsZHJlbiBiZWZvcmUgYWRkaW5nIHRoaXMgcm91dGUgdG8gdGhlIGFycmF5IHNvIHdlIHRyYXZlcnNlIHRoZVxuICAgIC8vIHJvdXRlIHRyZWUgZGVwdGgtZmlyc3QgYW5kIGNoaWxkIHJvdXRlcyBhcHBlYXIgYmVmb3JlIHRoZWlyIHBhcmVudHMgaW5cbiAgICAvLyB0aGUgXCJmbGF0dGVuZWRcIiB2ZXJzaW9uLlxuICAgIGlmIChyb3V0ZS5jaGlsZHJlbiAmJiByb3V0ZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICBpbnZhcmlhbnQoXG4gICAgICAgIHJvdXRlLmluZGV4ICE9PSB0cnVlLFxuICAgICAgICBgSW5kZXggcm91dGVzIG11c3Qgbm90IGhhdmUgY2hpbGQgcm91dGVzLiBQbGVhc2UgcmVtb3ZlIGAgK1xuICAgICAgICAgIGBhbGwgY2hpbGQgcm91dGVzIGZyb20gcm91dGUgcGF0aCBcIiR7cGF0aH1cIi5gXG4gICAgICApO1xuXG4gICAgICBmbGF0dGVuUm91dGVzKHJvdXRlLmNoaWxkcmVuLCBicmFuY2hlcywgcm91dGVzTWV0YSwgcGF0aCk7XG4gICAgfVxuXG4gICAgLy8gUm91dGVzIHdpdGhvdXQgYSBwYXRoIHNob3VsZG4ndCBldmVyIG1hdGNoIGJ5IHRoZW1zZWx2ZXMgdW5sZXNzIHRoZXkgYXJlXG4gICAgLy8gaW5kZXggcm91dGVzLCBzbyBkb24ndCBhZGQgdGhlbSB0byB0aGUgbGlzdCBvZiBwb3NzaWJsZSBicmFuY2hlcy5cbiAgICBpZiAocm91dGUucGF0aCA9PSBudWxsICYmICFyb3V0ZS5pbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGJyYW5jaGVzLnB1c2goeyBwYXRoLCBzY29yZTogY29tcHV0ZVNjb3JlKHBhdGgsIHJvdXRlLmluZGV4KSwgcm91dGVzTWV0YSB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIGJyYW5jaGVzO1xufVxuXG5mdW5jdGlvbiByYW5rUm91dGVCcmFuY2hlcyhicmFuY2hlczogUm91dGVCcmFuY2hbXSk6IHZvaWQge1xuICBicmFuY2hlcy5zb3J0KChhLCBiKSA9PlxuICAgIGEuc2NvcmUgIT09IGIuc2NvcmVcbiAgICAgID8gYi5zY29yZSAtIGEuc2NvcmUgLy8gSGlnaGVyIHNjb3JlIGZpcnN0XG4gICAgICA6IGNvbXBhcmVJbmRleGVzKFxuICAgICAgICAgIGEucm91dGVzTWV0YS5tYXAoKG1ldGEpID0+IG1ldGEuY2hpbGRyZW5JbmRleCksXG4gICAgICAgICAgYi5yb3V0ZXNNZXRhLm1hcCgobWV0YSkgPT4gbWV0YS5jaGlsZHJlbkluZGV4KVxuICAgICAgICApXG4gICk7XG59XG5cbmNvbnN0IHBhcmFtUmUgPSAvXjpcXHcrJC87XG5jb25zdCBkeW5hbWljU2VnbWVudFZhbHVlID0gMztcbmNvbnN0IGluZGV4Um91dGVWYWx1ZSA9IDI7XG5jb25zdCBlbXB0eVNlZ21lbnRWYWx1ZSA9IDE7XG5jb25zdCBzdGF0aWNTZWdtZW50VmFsdWUgPSAxMDtcbmNvbnN0IHNwbGF0UGVuYWx0eSA9IC0yO1xuY29uc3QgaXNTcGxhdCA9IChzOiBzdHJpbmcpID0+IHMgPT09IFwiKlwiO1xuXG5mdW5jdGlvbiBjb21wdXRlU2NvcmUocGF0aDogc3RyaW5nLCBpbmRleDogYm9vbGVhbiB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gIGxldCBzZWdtZW50cyA9IHBhdGguc3BsaXQoXCIvXCIpO1xuICBsZXQgaW5pdGlhbFNjb3JlID0gc2VnbWVudHMubGVuZ3RoO1xuICBpZiAoc2VnbWVudHMuc29tZShpc1NwbGF0KSkge1xuICAgIGluaXRpYWxTY29yZSArPSBzcGxhdFBlbmFsdHk7XG4gIH1cblxuICBpZiAoaW5kZXgpIHtcbiAgICBpbml0aWFsU2NvcmUgKz0gaW5kZXhSb3V0ZVZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHNlZ21lbnRzXG4gICAgLmZpbHRlcigocykgPT4gIWlzU3BsYXQocykpXG4gICAgLnJlZHVjZShcbiAgICAgIChzY29yZSwgc2VnbWVudCkgPT5cbiAgICAgICAgc2NvcmUgK1xuICAgICAgICAocGFyYW1SZS50ZXN0KHNlZ21lbnQpXG4gICAgICAgICAgPyBkeW5hbWljU2VnbWVudFZhbHVlXG4gICAgICAgICAgOiBzZWdtZW50ID09PSBcIlwiXG4gICAgICAgICAgPyBlbXB0eVNlZ21lbnRWYWx1ZVxuICAgICAgICAgIDogc3RhdGljU2VnbWVudFZhbHVlKSxcbiAgICAgIGluaXRpYWxTY29yZVxuICAgICk7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmVJbmRleGVzKGE6IG51bWJlcltdLCBiOiBudW1iZXJbXSk6IG51bWJlciB7XG4gIGxldCBzaWJsaW5ncyA9XG4gICAgYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuc2xpY2UoMCwgLTEpLmV2ZXJ5KChuLCBpKSA9PiBuID09PSBiW2ldKTtcblxuICByZXR1cm4gc2libGluZ3NcbiAgICA/IC8vIElmIHR3byByb3V0ZXMgYXJlIHNpYmxpbmdzLCB3ZSBzaG91bGQgdHJ5IHRvIG1hdGNoIHRoZSBlYXJsaWVyIHNpYmxpbmdcbiAgICAgIC8vIGZpcnN0LiBUaGlzIGFsbG93cyBwZW9wbGUgdG8gaGF2ZSBmaW5lLWdyYWluZWQgY29udHJvbCBvdmVyIHRoZSBtYXRjaGluZ1xuICAgICAgLy8gYmVoYXZpb3IgYnkgc2ltcGx5IHB1dHRpbmcgcm91dGVzIHdpdGggaWRlbnRpY2FsIHBhdGhzIGluIHRoZSBvcmRlciB0aGV5XG4gICAgICAvLyB3YW50IHRoZW0gdHJpZWQuXG4gICAgICBhW2EubGVuZ3RoIC0gMV0gLSBiW2IubGVuZ3RoIC0gMV1cbiAgICA6IC8vIE90aGVyd2lzZSwgaXQgZG9lc24ndCByZWFsbHkgbWFrZSBzZW5zZSB0byByYW5rIG5vbi1zaWJsaW5ncyBieSBpbmRleCxcbiAgICAgIC8vIHNvIHRoZXkgc29ydCBlcXVhbGx5LlxuICAgICAgMDtcbn1cblxuZnVuY3Rpb24gbWF0Y2hSb3V0ZUJyYW5jaDxQYXJhbUtleSBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gIGJyYW5jaDogUm91dGVCcmFuY2gsXG4gIHBhdGhuYW1lOiBzdHJpbmdcbik6IFJvdXRlTWF0Y2g8UGFyYW1LZXk+W10gfCBudWxsIHtcbiAgbGV0IHsgcm91dGVzTWV0YSB9ID0gYnJhbmNoO1xuXG4gIGxldCBtYXRjaGVkUGFyYW1zID0ge307XG4gIGxldCBtYXRjaGVkUGF0aG5hbWUgPSBcIi9cIjtcbiAgbGV0IG1hdGNoZXM6IFJvdXRlTWF0Y2hbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJvdXRlc01ldGEubGVuZ3RoOyArK2kpIHtcbiAgICBsZXQgbWV0YSA9IHJvdXRlc01ldGFbaV07XG4gICAgbGV0IGVuZCA9IGkgPT09IHJvdXRlc01ldGEubGVuZ3RoIC0gMTtcbiAgICBsZXQgcmVtYWluaW5nUGF0aG5hbWUgPVxuICAgICAgbWF0Y2hlZFBhdGhuYW1lID09PSBcIi9cIlxuICAgICAgICA/IHBhdGhuYW1lXG4gICAgICAgIDogcGF0aG5hbWUuc2xpY2UobWF0Y2hlZFBhdGhuYW1lLmxlbmd0aCkgfHwgXCIvXCI7XG4gICAgbGV0IG1hdGNoID0gbWF0Y2hQYXRoKFxuICAgICAgeyBwYXRoOiBtZXRhLnJlbGF0aXZlUGF0aCwgY2FzZVNlbnNpdGl2ZTogbWV0YS5jYXNlU2Vuc2l0aXZlLCBlbmQgfSxcbiAgICAgIHJlbWFpbmluZ1BhdGhuYW1lXG4gICAgKTtcblxuICAgIGlmICghbWF0Y2gpIHJldHVybiBudWxsO1xuXG4gICAgT2JqZWN0LmFzc2lnbihtYXRjaGVkUGFyYW1zLCBtYXRjaC5wYXJhbXMpO1xuXG4gICAgbGV0IHJvdXRlID0gbWV0YS5yb3V0ZTtcblxuICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICBwYXJhbXM6IG1hdGNoZWRQYXJhbXMsXG4gICAgICBwYXRobmFtZTogam9pblBhdGhzKFttYXRjaGVkUGF0aG5hbWUsIG1hdGNoLnBhdGhuYW1lXSksXG4gICAgICBwYXRobmFtZUJhc2U6IG5vcm1hbGl6ZVBhdGhuYW1lKFxuICAgICAgICBqb2luUGF0aHMoW21hdGNoZWRQYXRobmFtZSwgbWF0Y2gucGF0aG5hbWVCYXNlXSlcbiAgICAgICksXG4gICAgICByb3V0ZSxcbiAgICB9KTtcblxuICAgIGlmIChtYXRjaC5wYXRobmFtZUJhc2UgIT09IFwiL1wiKSB7XG4gICAgICBtYXRjaGVkUGF0aG5hbWUgPSBqb2luUGF0aHMoW21hdGNoZWRQYXRobmFtZSwgbWF0Y2gucGF0aG5hbWVCYXNlXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1hdGNoZXM7XG59XG5cbi8qKlxuICogQSBQYXRoUGF0dGVybiBpcyB1c2VkIHRvIG1hdGNoIG9uIHNvbWUgcG9ydGlvbiBvZiBhIFVSTCBwYXRobmFtZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXRoUGF0dGVybjxQYXRoIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG4gIC8qKlxuICAgKiBBIHN0cmluZyB0byBtYXRjaCBhZ2FpbnN0IGEgVVJMIHBhdGhuYW1lLiBNYXkgY29udGFpbiBgOmlkYC1zdHlsZSBzZWdtZW50c1xuICAgKiB0byBpbmRpY2F0ZSBwbGFjZWhvbGRlcnMgZm9yIGR5bmFtaWMgcGFyYW1ldGVycy4gTWF5IGFsc28gZW5kIHdpdGggYC8qYCB0b1xuICAgKiBpbmRpY2F0ZSBtYXRjaGluZyB0aGUgcmVzdCBvZiB0aGUgVVJMIHBhdGhuYW1lLlxuICAgKi9cbiAgcGF0aDogUGF0aDtcbiAgLyoqXG4gICAqIFNob3VsZCBiZSBgdHJ1ZWAgaWYgdGhlIHN0YXRpYyBwb3J0aW9ucyBvZiB0aGUgYHBhdGhgIHNob3VsZCBiZSBtYXRjaGVkIGluXG4gICAqIHRoZSBzYW1lIGNhc2UuXG4gICAqL1xuICBjYXNlU2Vuc2l0aXZlPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFNob3VsZCBiZSBgdHJ1ZWAgaWYgdGhpcyBwYXR0ZXJuIHNob3VsZCBtYXRjaCB0aGUgZW50aXJlIFVSTCBwYXRobmFtZS5cbiAgICovXG4gIGVuZD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSBQYXRoTWF0Y2ggY29udGFpbnMgaW5mbyBhYm91dCBob3cgYSBQYXRoUGF0dGVybiBtYXRjaGVkIG9uIGEgVVJMIHBhdGhuYW1lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhdGhNYXRjaDxQYXJhbUtleSBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4ge1xuICAvKipcbiAgICogVGhlIG5hbWVzIGFuZCB2YWx1ZXMgb2YgZHluYW1pYyBwYXJhbWV0ZXJzIGluIHRoZSBVUkwuXG4gICAqL1xuICBwYXJhbXM6IFBhcmFtczxQYXJhbUtleT47XG4gIC8qKlxuICAgKiBUaGUgcG9ydGlvbiBvZiB0aGUgVVJMIHBhdGhuYW1lIHRoYXQgd2FzIG1hdGNoZWQuXG4gICAqL1xuICBwYXRobmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHBvcnRpb24gb2YgdGhlIFVSTCBwYXRobmFtZSB0aGF0IHdhcyBtYXRjaGVkIGJlZm9yZSBjaGlsZCByb3V0ZXMuXG4gICAqL1xuICBwYXRobmFtZUJhc2U6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBwYXR0ZXJuIHRoYXQgd2FzIHVzZWQgdG8gbWF0Y2guXG4gICAqL1xuICBwYXR0ZXJuOiBQYXRoUGF0dGVybjtcbn1cblxudHlwZSBNdXRhYmxlPFQ+ID0ge1xuICAtcmVhZG9ubHkgW1AgaW4ga2V5b2YgVF06IFRbUF07XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIHBhdHRlcm4gbWF0Y2hpbmcgb24gYSBVUkwgcGF0aG5hbWUgYW5kIHJldHVybnMgaW5mb3JtYXRpb24gYWJvdXRcbiAqIHRoZSBtYXRjaC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI21hdGNocGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hQYXRoPFxuICBQYXJhbUtleSBleHRlbmRzIFBhcmFtUGFyc2VLZXk8UGF0aD4sXG4gIFBhdGggZXh0ZW5kcyBzdHJpbmdcbj4oXG4gIHBhdHRlcm46IFBhdGhQYXR0ZXJuPFBhdGg+IHwgUGF0aCxcbiAgcGF0aG5hbWU6IHN0cmluZ1xuKTogUGF0aE1hdGNoPFBhcmFtS2V5PiB8IG51bGwge1xuICBpZiAodHlwZW9mIHBhdHRlcm4gPT09IFwic3RyaW5nXCIpIHtcbiAgICBwYXR0ZXJuID0geyBwYXRoOiBwYXR0ZXJuLCBjYXNlU2Vuc2l0aXZlOiBmYWxzZSwgZW5kOiB0cnVlIH07XG4gIH1cblxuICBsZXQgW21hdGNoZXIsIHBhcmFtTmFtZXNdID0gY29tcGlsZVBhdGgoXG4gICAgcGF0dGVybi5wYXRoLFxuICAgIHBhdHRlcm4uY2FzZVNlbnNpdGl2ZSxcbiAgICBwYXR0ZXJuLmVuZFxuICApO1xuXG4gIGxldCBtYXRjaCA9IHBhdGhuYW1lLm1hdGNoKG1hdGNoZXIpO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gbnVsbDtcblxuICBsZXQgbWF0Y2hlZFBhdGhuYW1lID0gbWF0Y2hbMF07XG4gIGxldCBwYXRobmFtZUJhc2UgPSBtYXRjaGVkUGF0aG5hbWUucmVwbGFjZSgvKC4pXFwvKyQvLCBcIiQxXCIpO1xuICBsZXQgY2FwdHVyZUdyb3VwcyA9IG1hdGNoLnNsaWNlKDEpO1xuICBsZXQgcGFyYW1zOiBQYXJhbXMgPSBwYXJhbU5hbWVzLnJlZHVjZTxNdXRhYmxlPFBhcmFtcz4+KFxuICAgIChtZW1vLCBwYXJhbU5hbWUsIGluZGV4KSA9PiB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHBhdGhuYW1lQmFzZSBoZXJlIHVzaW5nIHRoZSByYXcgc3BsYXQgdmFsdWVcbiAgICAgIC8vIGluc3RlYWQgb2YgdXNpbmcgcGFyYW1zW1wiKlwiXSBsYXRlciBiZWNhdXNlIGl0IHdpbGwgYmUgZGVjb2RlZCB0aGVuXG4gICAgICBpZiAocGFyYW1OYW1lID09PSBcIipcIikge1xuICAgICAgICBsZXQgc3BsYXRWYWx1ZSA9IGNhcHR1cmVHcm91cHNbaW5kZXhdIHx8IFwiXCI7XG4gICAgICAgIHBhdGhuYW1lQmFzZSA9IG1hdGNoZWRQYXRobmFtZVxuICAgICAgICAgIC5zbGljZSgwLCBtYXRjaGVkUGF0aG5hbWUubGVuZ3RoIC0gc3BsYXRWYWx1ZS5sZW5ndGgpXG4gICAgICAgICAgLnJlcGxhY2UoLyguKVxcLyskLywgXCIkMVwiKTtcbiAgICAgIH1cblxuICAgICAgbWVtb1twYXJhbU5hbWVdID0gc2FmZWx5RGVjb2RlVVJJQ29tcG9uZW50KFxuICAgICAgICBjYXB0dXJlR3JvdXBzW2luZGV4XSB8fCBcIlwiLFxuICAgICAgICBwYXJhbU5hbWVcbiAgICAgICk7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9LFxuICAgIHt9XG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICBwYXJhbXMsXG4gICAgcGF0aG5hbWU6IG1hdGNoZWRQYXRobmFtZSxcbiAgICBwYXRobmFtZUJhc2UsXG4gICAgcGF0dGVybixcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29tcGlsZVBhdGgoXG4gIHBhdGg6IHN0cmluZyxcbiAgY2FzZVNlbnNpdGl2ZSA9IGZhbHNlLFxuICBlbmQgPSB0cnVlXG4pOiBbUmVnRXhwLCBzdHJpbmdbXV0ge1xuICB3YXJuaW5nKFxuICAgIHBhdGggPT09IFwiKlwiIHx8ICFwYXRoLmVuZHNXaXRoKFwiKlwiKSB8fCBwYXRoLmVuZHNXaXRoKFwiLypcIiksXG4gICAgYFJvdXRlIHBhdGggXCIke3BhdGh9XCIgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdlcmUgYCArXG4gICAgICBgXCIke3BhdGgucmVwbGFjZSgvXFwqJC8sIFwiLypcIil9XCIgYmVjYXVzZSB0aGUgXFxgKlxcYCBjaGFyYWN0ZXIgbXVzdCBgICtcbiAgICAgIGBhbHdheXMgZm9sbG93IGEgXFxgL1xcYCBpbiB0aGUgcGF0dGVybi4gVG8gZ2V0IHJpZCBvZiB0aGlzIHdhcm5pbmcsIGAgK1xuICAgICAgYHBsZWFzZSBjaGFuZ2UgdGhlIHJvdXRlIHBhdGggdG8gXCIke3BhdGgucmVwbGFjZSgvXFwqJC8sIFwiLypcIil9XCIuYFxuICApO1xuXG4gIGxldCBwYXJhbU5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgcmVnZXhwU291cmNlID1cbiAgICBcIl5cIiArXG4gICAgcGF0aFxuICAgICAgLnJlcGxhY2UoL1xcLypcXCo/JC8sIFwiXCIpIC8vIElnbm9yZSB0cmFpbGluZyAvIGFuZCAvKiwgd2UnbGwgaGFuZGxlIGl0IGJlbG93XG4gICAgICAucmVwbGFjZSgvXlxcLyovLCBcIi9cIikgLy8gTWFrZSBzdXJlIGl0IGhhcyBhIGxlYWRpbmcgL1xuICAgICAgLnJlcGxhY2UoL1tcXFxcLiorXiQ/e318KClbXFxdXS9nLCBcIlxcXFwkJlwiKSAvLyBFc2NhcGUgc3BlY2lhbCByZWdleCBjaGFyc1xuICAgICAgLnJlcGxhY2UoLzooXFx3KykvZywgKF86IHN0cmluZywgcGFyYW1OYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgcGFyYW1OYW1lcy5wdXNoKHBhcmFtTmFtZSk7XG4gICAgICAgIHJldHVybiBcIihbXlxcXFwvXSspXCI7XG4gICAgICB9KTtcblxuICBpZiAocGF0aC5lbmRzV2l0aChcIipcIikpIHtcbiAgICBwYXJhbU5hbWVzLnB1c2goXCIqXCIpO1xuICAgIHJlZ2V4cFNvdXJjZSArPVxuICAgICAgcGF0aCA9PT0gXCIqXCIgfHwgcGF0aCA9PT0gXCIvKlwiXG4gICAgICAgID8gXCIoLiopJFwiIC8vIEFscmVhZHkgbWF0Y2hlZCB0aGUgaW5pdGlhbCAvLCBqdXN0IG1hdGNoIHRoZSByZXN0XG4gICAgICAgIDogXCIoPzpcXFxcLyguKyl8XFxcXC8qKSRcIjsgLy8gRG9uJ3QgaW5jbHVkZSB0aGUgLyBpbiBwYXJhbXNbXCIqXCJdXG4gIH0gZWxzZSB7XG4gICAgcmVnZXhwU291cmNlICs9IGVuZFxuICAgICAgPyBcIlxcXFwvKiRcIiAvLyBXaGVuIG1hdGNoaW5nIHRvIHRoZSBlbmQsIGlnbm9yZSB0cmFpbGluZyBzbGFzaGVzXG4gICAgICA6IC8vIE90aGVyd2lzZSwgbWF0Y2ggYSB3b3JkIGJvdW5kYXJ5IG9yIGEgcHJvY2VlZGluZyAvLiBUaGUgd29yZCBib3VuZGFyeSByZXN0cmljdHNcbiAgICAgICAgLy8gcGFyZW50IHJvdXRlcyB0byBtYXRjaGluZyBvbmx5IHRoZWlyIG93biB3b3JkcyBhbmQgbm90aGluZyBtb3JlLCBlLmcuIHBhcmVudFxuICAgICAgICAvLyByb3V0ZSBcIi9ob21lXCIgc2hvdWxkIG5vdCBtYXRjaCBcIi9ob21lMlwiLlxuICAgICAgICAvLyBBZGRpdGlvbmFsbHksIGFsbG93IHBhdGhzIHN0YXJ0aW5nIHdpdGggYC5gLCBgLWAsIGB+YCwgYW5kIHVybC1lbmNvZGVkIGVudGl0aWVzLFxuICAgICAgICAvLyBidXQgZG8gbm90IGNvbnN1bWUgdGhlIGNoYXJhY3RlciBpbiB0aGUgbWF0Y2hlZCBwYXRoIHNvIHRoZXkgY2FuIG1hdGNoIGFnYWluc3RcbiAgICAgICAgLy8gbmVzdGVkIHBhdGhzLlxuICAgICAgICBcIig/Oig/PVsufi1dfCVbMC05QS1GXXsyfSl8XFxcXGJ8XFxcXC98JClcIjtcbiAgfVxuXG4gIGxldCBtYXRjaGVyID0gbmV3IFJlZ0V4cChyZWdleHBTb3VyY2UsIGNhc2VTZW5zaXRpdmUgPyB1bmRlZmluZWQgOiBcImlcIik7XG5cbiAgcmV0dXJuIFttYXRjaGVyLCBwYXJhbU5hbWVzXTtcbn1cblxuZnVuY3Rpb24gc2FmZWx5RGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlOiBzdHJpbmcsIHBhcmFtTmFtZTogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgd2FybmluZyhcbiAgICAgIGZhbHNlLFxuICAgICAgYFRoZSB2YWx1ZSBmb3IgdGhlIFVSTCBwYXJhbSBcIiR7cGFyYW1OYW1lfVwiIHdpbGwgbm90IGJlIGRlY29kZWQgYmVjYXVzZWAgK1xuICAgICAgICBgIHRoZSBzdHJpbmcgXCIke3ZhbHVlfVwiIGlzIGEgbWFsZm9ybWVkIFVSTCBzZWdtZW50LiBUaGlzIGlzIHByb2JhYmx5YCArXG4gICAgICAgIGAgZHVlIHRvIGEgYmFkIHBlcmNlbnQgZW5jb2RpbmcgKCR7ZXJyb3J9KS5gXG4gICAgKTtcblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSByZXNvbHZlZCBwYXRoIG9iamVjdCByZWxhdGl2ZSB0byB0aGUgZ2l2ZW4gcGF0aG5hbWUuXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSNyZXNvbHZlcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVBhdGgodG86IFRvLCBmcm9tUGF0aG5hbWUgPSBcIi9cIik6IFBhdGgge1xuICBsZXQge1xuICAgIHBhdGhuYW1lOiB0b1BhdGhuYW1lLFxuICAgIHNlYXJjaCA9IFwiXCIsXG4gICAgaGFzaCA9IFwiXCIsXG4gIH0gPSB0eXBlb2YgdG8gPT09IFwic3RyaW5nXCIgPyBwYXJzZVBhdGgodG8pIDogdG87XG5cbiAgbGV0IHBhdGhuYW1lID0gdG9QYXRobmFtZVxuICAgID8gdG9QYXRobmFtZS5zdGFydHNXaXRoKFwiL1wiKVxuICAgICAgPyB0b1BhdGhuYW1lXG4gICAgICA6IHJlc29sdmVQYXRobmFtZSh0b1BhdGhuYW1lLCBmcm9tUGF0aG5hbWUpXG4gICAgOiBmcm9tUGF0aG5hbWU7XG5cbiAgcmV0dXJuIHtcbiAgICBwYXRobmFtZSxcbiAgICBzZWFyY2g6IG5vcm1hbGl6ZVNlYXJjaChzZWFyY2gpLFxuICAgIGhhc2g6IG5vcm1hbGl6ZUhhc2goaGFzaCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVQYXRobmFtZShyZWxhdGl2ZVBhdGg6IHN0cmluZywgZnJvbVBhdGhuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICBsZXQgc2VnbWVudHMgPSBmcm9tUGF0aG5hbWUucmVwbGFjZSgvXFwvKyQvLCBcIlwiKS5zcGxpdChcIi9cIik7XG4gIGxldCByZWxhdGl2ZVNlZ21lbnRzID0gcmVsYXRpdmVQYXRoLnNwbGl0KFwiL1wiKTtcblxuICByZWxhdGl2ZVNlZ21lbnRzLmZvckVhY2goKHNlZ21lbnQpID0+IHtcbiAgICBpZiAoc2VnbWVudCA9PT0gXCIuLlwiKSB7XG4gICAgICAvLyBLZWVwIHRoZSByb290IFwiXCIgc2VnbWVudCBzbyB0aGUgcGF0aG5hbWUgc3RhcnRzIGF0IC9cbiAgICAgIGlmIChzZWdtZW50cy5sZW5ndGggPiAxKSBzZWdtZW50cy5wb3AoKTtcbiAgICB9IGVsc2UgaWYgKHNlZ21lbnQgIT09IFwiLlwiKSB7XG4gICAgICBzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHNlZ21lbnRzLmxlbmd0aCA+IDEgPyBzZWdtZW50cy5qb2luKFwiL1wiKSA6IFwiL1wiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVRvKFxuICB0b0FyZzogVG8sXG4gIHJvdXRlUGF0aG5hbWVzOiBzdHJpbmdbXSxcbiAgbG9jYXRpb25QYXRobmFtZTogc3RyaW5nXG4pOiBQYXRoIHtcbiAgbGV0IHRvID0gdHlwZW9mIHRvQXJnID09PSBcInN0cmluZ1wiID8gcGFyc2VQYXRoKHRvQXJnKSA6IHRvQXJnO1xuICBsZXQgdG9QYXRobmFtZSA9IHRvQXJnID09PSBcIlwiIHx8IHRvLnBhdGhuYW1lID09PSBcIlwiID8gXCIvXCIgOiB0by5wYXRobmFtZTtcblxuICAvLyBJZiBhIHBhdGhuYW1lIGlzIGV4cGxpY2l0bHkgcHJvdmlkZWQgaW4gYHRvYCwgaXQgc2hvdWxkIGJlIHJlbGF0aXZlIHRvIHRoZVxuICAvLyByb3V0ZSBjb250ZXh0LiBUaGlzIGlzIGV4cGxhaW5lZCBpbiBgTm90ZSBvbiBgPExpbmsgdG8+YCB2YWx1ZXNgIGluIG91clxuICAvLyBtaWdyYXRpb24gZ3VpZGUgZnJvbSB2NSBhcyBhIG1lYW5zIG9mIGRpc2FtYmlndWF0aW9uIGJldHdlZW4gYHRvYCB2YWx1ZXNcbiAgLy8gdGhhdCBiZWdpbiB3aXRoIGAvYCBhbmQgdGhvc2UgdGhhdCBkbyBub3QuIEhvd2V2ZXIsIHRoaXMgaXMgcHJvYmxlbWF0aWMgZm9yXG4gIC8vIGB0b2AgdmFsdWVzIHRoYXQgZG8gbm90IHByb3ZpZGUgYSBwYXRobmFtZS4gYHRvYCBjYW4gc2ltcGx5IGJlIGEgc2VhcmNoIG9yXG4gIC8vIGhhc2ggc3RyaW5nLCBpbiB3aGljaCBjYXNlIHdlIHNob3VsZCBhc3N1bWUgdGhhdCB0aGUgbmF2aWdhdGlvbiBpcyByZWxhdGl2ZVxuICAvLyB0byB0aGUgY3VycmVudCBsb2NhdGlvbidzIHBhdGhuYW1lIGFuZCAqbm90KiB0aGUgcm91dGUgcGF0aG5hbWUuXG4gIGxldCBmcm9tOiBzdHJpbmc7XG4gIGlmICh0b1BhdGhuYW1lID09IG51bGwpIHtcbiAgICBmcm9tID0gbG9jYXRpb25QYXRobmFtZTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgcm91dGVQYXRobmFtZUluZGV4ID0gcm91dGVQYXRobmFtZXMubGVuZ3RoIC0gMTtcblxuICAgIGlmICh0b1BhdGhuYW1lLnN0YXJ0c1dpdGgoXCIuLlwiKSkge1xuICAgICAgbGV0IHRvU2VnbWVudHMgPSB0b1BhdGhuYW1lLnNwbGl0KFwiL1wiKTtcblxuICAgICAgLy8gRWFjaCBsZWFkaW5nIC4uIHNlZ21lbnQgbWVhbnMgXCJnbyB1cCBvbmUgcm91dGVcIiBpbnN0ZWFkIG9mIFwiZ28gdXAgb25lXG4gICAgICAvLyBVUkwgc2VnbWVudFwiLiAgVGhpcyBpcyBhIGtleSBkaWZmZXJlbmNlIGZyb20gaG93IDxhIGhyZWY+IHdvcmtzIGFuZCBhXG4gICAgICAvLyBtYWpvciByZWFzb24gd2UgY2FsbCB0aGlzIGEgXCJ0b1wiIHZhbHVlIGluc3RlYWQgb2YgYSBcImhyZWZcIi5cbiAgICAgIHdoaWxlICh0b1NlZ21lbnRzWzBdID09PSBcIi4uXCIpIHtcbiAgICAgICAgdG9TZWdtZW50cy5zaGlmdCgpO1xuICAgICAgICByb3V0ZVBhdGhuYW1lSW5kZXggLT0gMTtcbiAgICAgIH1cblxuICAgICAgdG8ucGF0aG5hbWUgPSB0b1NlZ21lbnRzLmpvaW4oXCIvXCIpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGFyZSBtb3JlIFwiLi5cIiBzZWdtZW50cyB0aGFuIHBhcmVudCByb3V0ZXMsIHJlc29sdmUgcmVsYXRpdmUgdG9cbiAgICAvLyB0aGUgcm9vdCAvIFVSTC5cbiAgICBmcm9tID0gcm91dGVQYXRobmFtZUluZGV4ID49IDAgPyByb3V0ZVBhdGhuYW1lc1tyb3V0ZVBhdGhuYW1lSW5kZXhdIDogXCIvXCI7XG4gIH1cblxuICBsZXQgcGF0aCA9IHJlc29sdmVQYXRoKHRvLCBmcm9tKTtcblxuICAvLyBFbnN1cmUgdGhlIHBhdGhuYW1lIGhhcyBhIHRyYWlsaW5nIHNsYXNoIGlmIHRoZSBvcmlnaW5hbCB0byB2YWx1ZSBoYWQgb25lLlxuICBpZiAoXG4gICAgdG9QYXRobmFtZSAmJlxuICAgIHRvUGF0aG5hbWUgIT09IFwiL1wiICYmXG4gICAgdG9QYXRobmFtZS5lbmRzV2l0aChcIi9cIikgJiZcbiAgICAhcGF0aC5wYXRobmFtZS5lbmRzV2l0aChcIi9cIilcbiAgKSB7XG4gICAgcGF0aC5wYXRobmFtZSArPSBcIi9cIjtcbiAgfVxuXG4gIHJldHVybiBwYXRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG9QYXRobmFtZSh0bzogVG8pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAvLyBFbXB0eSBzdHJpbmdzIHNob3VsZCBiZSB0cmVhdGVkIHRoZSBzYW1lIGFzIC8gcGF0aHNcbiAgcmV0dXJuIHRvID09PSBcIlwiIHx8ICh0byBhcyBQYXRoKS5wYXRobmFtZSA9PT0gXCJcIlxuICAgID8gXCIvXCJcbiAgICA6IHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIlxuICAgID8gcGFyc2VQYXRoKHRvKS5wYXRobmFtZVxuICAgIDogdG8ucGF0aG5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJpcEJhc2VuYW1lKFxuICBwYXRobmFtZTogc3RyaW5nLFxuICBiYXNlbmFtZTogc3RyaW5nXG4pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKGJhc2VuYW1lID09PSBcIi9cIikgcmV0dXJuIHBhdGhuYW1lO1xuXG4gIGlmICghcGF0aG5hbWUudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKGJhc2VuYW1lLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBsZXQgbmV4dENoYXIgPSBwYXRobmFtZS5jaGFyQXQoYmFzZW5hbWUubGVuZ3RoKTtcbiAgaWYgKG5leHRDaGFyICYmIG5leHRDaGFyICE9PSBcIi9cIikge1xuICAgIC8vIHBhdGhuYW1lIGRvZXMgbm90IHN0YXJ0IHdpdGggYmFzZW5hbWUvXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gcGF0aG5hbWUuc2xpY2UoYmFzZW5hbWUubGVuZ3RoKSB8fCBcIi9cIjtcbn1cblxuZXhwb3J0IGNvbnN0IGpvaW5QYXRocyA9IChwYXRoczogc3RyaW5nW10pOiBzdHJpbmcgPT5cbiAgcGF0aHMuam9pbihcIi9cIikucmVwbGFjZSgvXFwvXFwvKy9nLCBcIi9cIik7XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemVQYXRobmFtZSA9IChwYXRobmFtZTogc3RyaW5nKTogc3RyaW5nID0+XG4gIHBhdGhuYW1lLnJlcGxhY2UoL1xcLyskLywgXCJcIikucmVwbGFjZSgvXlxcLyovLCBcIi9cIik7XG5cbmNvbnN0IG5vcm1hbGl6ZVNlYXJjaCA9IChzZWFyY2g6IHN0cmluZyk6IHN0cmluZyA9PlxuICAhc2VhcmNoIHx8IHNlYXJjaCA9PT0gXCI/XCJcbiAgICA/IFwiXCJcbiAgICA6IHNlYXJjaC5zdGFydHNXaXRoKFwiP1wiKVxuICAgID8gc2VhcmNoXG4gICAgOiBcIj9cIiArIHNlYXJjaDtcblxuY29uc3Qgbm9ybWFsaXplSGFzaCA9IChoYXNoOiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgIWhhc2ggfHwgaGFzaCA9PT0gXCIjXCIgPyBcIlwiIDogaGFzaC5zdGFydHNXaXRoKFwiI1wiKSA/IGhhc2ggOiBcIiNcIiArIGhhc2g7XG4iLCAiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgdHlwZSB7IExvY2F0aW9uLCBQYXRoLCBUbyB9IGZyb20gXCJoaXN0b3J5XCI7XG5pbXBvcnQgeyBBY3Rpb24gYXMgTmF2aWdhdGlvblR5cGUsIHBhcnNlUGF0aCB9IGZyb20gXCJoaXN0b3J5XCI7XG5cbmltcG9ydCB7IExvY2F0aW9uQ29udGV4dCwgTmF2aWdhdGlvbkNvbnRleHQsIFJvdXRlQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB0eXBlIHtcbiAgUGFyYW1QYXJzZUtleSxcbiAgUGFyYW1zLFxuICBQYXRoTWF0Y2gsXG4gIFBhdGhQYXR0ZXJuLFxuICBSb3V0ZU1hdGNoLFxuICBSb3V0ZU9iamVjdCxcbn0gZnJvbSBcIi4vcm91dGVyXCI7XG5pbXBvcnQge1xuICBnZXRUb1BhdGhuYW1lLFxuICBpbnZhcmlhbnQsXG4gIGpvaW5QYXRocyxcbiAgbWF0Y2hQYXRoLFxuICBtYXRjaFJvdXRlcyxcbiAgcmVzb2x2ZVRvLFxuICB3YXJuaW5nLFxuICB3YXJuaW5nT25jZSxcbn0gZnJvbSBcIi4vcm91dGVyXCI7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZnVsbCBocmVmIGZvciB0aGUgZ2l2ZW4gXCJ0b1wiIHZhbHVlLiBUaGlzIGlzIHVzZWZ1bCBmb3IgYnVpbGRpbmdcbiAqIGN1c3RvbSBsaW5rcyB0aGF0IGFyZSBhbHNvIGFjY2Vzc2libGUgYW5kIHByZXNlcnZlIHJpZ2h0LWNsaWNrIGJlaGF2aW9yLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vZG9jcy9lbi92Ni9hcGkjdXNlaHJlZlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlSHJlZih0bzogVG8pOiBzdHJpbmcge1xuICBpbnZhcmlhbnQoXG4gICAgdXNlSW5Sb3V0ZXJDb250ZXh0KCksXG4gICAgLy8gVE9ETzogVGhpcyBlcnJvciBpcyBwcm9iYWJseSBiZWNhdXNlIHRoZXkgc29tZWhvdyBoYXZlIDIgdmVyc2lvbnMgb2YgdGhlXG4gICAgLy8gcm91dGVyIGxvYWRlZC4gV2UgY2FuIGhlbHAgdGhlbSB1bmRlcnN0YW5kIGhvdyB0byBhdm9pZCB0aGF0LlxuICAgIGB1c2VIcmVmKCkgbWF5IGJlIHVzZWQgb25seSBpbiB0aGUgY29udGV4dCBvZiBhIDxSb3V0ZXI+IGNvbXBvbmVudC5gXG4gICk7XG5cbiAgbGV0IHsgYmFzZW5hbWUsIG5hdmlnYXRvciB9ID0gUmVhY3QudXNlQ29udGV4dChOYXZpZ2F0aW9uQ29udGV4dCk7XG4gIGxldCB7IGhhc2gsIHBhdGhuYW1lLCBzZWFyY2ggfSA9IHVzZVJlc29sdmVkUGF0aCh0byk7XG5cbiAgbGV0IGpvaW5lZFBhdGhuYW1lID0gcGF0aG5hbWU7XG4gIGlmIChiYXNlbmFtZSAhPT0gXCIvXCIpIHtcbiAgICBsZXQgdG9QYXRobmFtZSA9IGdldFRvUGF0aG5hbWUodG8pO1xuICAgIGxldCBlbmRzV2l0aFNsYXNoID0gdG9QYXRobmFtZSAhPSBudWxsICYmIHRvUGF0aG5hbWUuZW5kc1dpdGgoXCIvXCIpO1xuICAgIGpvaW5lZFBhdGhuYW1lID1cbiAgICAgIHBhdGhuYW1lID09PSBcIi9cIlxuICAgICAgICA/IGJhc2VuYW1lICsgKGVuZHNXaXRoU2xhc2ggPyBcIi9cIiA6IFwiXCIpXG4gICAgICAgIDogam9pblBhdGhzKFtiYXNlbmFtZSwgcGF0aG5hbWVdKTtcbiAgfVxuXG4gIHJldHVybiBuYXZpZ2F0b3IuY3JlYXRlSHJlZih7IHBhdGhuYW1lOiBqb2luZWRQYXRobmFtZSwgc2VhcmNoLCBoYXNoIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvbXBvbmVudCBpcyBhIGRlc2NlbmRhbnQgb2YgYSA8Um91dGVyPi5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI3VzZWlucm91dGVyY29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlSW5Sb3V0ZXJDb250ZXh0KCk6IGJvb2xlYW4ge1xuICByZXR1cm4gUmVhY3QudXNlQ29udGV4dChMb2NhdGlvbkNvbnRleHQpICE9IG51bGw7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCBsb2NhdGlvbiBvYmplY3QsIHdoaWNoIHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgVVJMIGluIHdlYlxuICogYnJvd3NlcnMuXG4gKlxuICogTm90ZTogSWYgeW91J3JlIHVzaW5nIHRoaXMgaXQgbWF5IG1lYW4geW91J3JlIGRvaW5nIHNvbWUgb2YgeW91ciBvd25cbiAqIFwicm91dGluZ1wiIGluIHlvdXIgYXBwLCBhbmQgd2UnZCBsaWtlIHRvIGtub3cgd2hhdCB5b3VyIHVzZSBjYXNlIGlzLiBXZSBtYXlcbiAqIGJlIGFibGUgdG8gcHJvdmlkZSBzb21ldGhpbmcgaGlnaGVyLWxldmVsIHRvIGJldHRlciBzdWl0IHlvdXIgbmVlZHMuXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSN1c2Vsb2NhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlTG9jYXRpb24oKTogTG9jYXRpb24ge1xuICBpbnZhcmlhbnQoXG4gICAgdXNlSW5Sb3V0ZXJDb250ZXh0KCksXG4gICAgLy8gVE9ETzogVGhpcyBlcnJvciBpcyBwcm9iYWJseSBiZWNhdXNlIHRoZXkgc29tZWhvdyBoYXZlIDIgdmVyc2lvbnMgb2YgdGhlXG4gICAgLy8gcm91dGVyIGxvYWRlZC4gV2UgY2FuIGhlbHAgdGhlbSB1bmRlcnN0YW5kIGhvdyB0byBhdm9pZCB0aGF0LlxuICAgIGB1c2VMb2NhdGlvbigpIG1heSBiZSB1c2VkIG9ubHkgaW4gdGhlIGNvbnRleHQgb2YgYSA8Um91dGVyPiBjb21wb25lbnQuYFxuICApO1xuXG4gIHJldHVybiBSZWFjdC51c2VDb250ZXh0KExvY2F0aW9uQ29udGV4dCkubG9jYXRpb247XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCBuYXZpZ2F0aW9uIGFjdGlvbiB3aGljaCBkZXNjcmliZXMgaG93IHRoZSByb3V0ZXIgY2FtZSB0b1xuICogdGhlIGN1cnJlbnQgbG9jYXRpb24sIGVpdGhlciBieSBhIHBvcCwgcHVzaCwgb3IgcmVwbGFjZSBvbiB0aGUgaGlzdG9yeSBzdGFjay5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI3VzZW5hdmlnYXRpb250eXBlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VOYXZpZ2F0aW9uVHlwZSgpOiBOYXZpZ2F0aW9uVHlwZSB7XG4gIHJldHVybiBSZWFjdC51c2VDb250ZXh0KExvY2F0aW9uQ29udGV4dCkubmF2aWdhdGlvblR5cGU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBcInRvXCIgdmFsdWUgbWF0Y2hlcyB0aGUgY3VycmVudCBVUkwuXG4gKiBUaGlzIGlzIHVzZWZ1bCBmb3IgY29tcG9uZW50cyB0aGF0IG5lZWQgdG8ga25vdyBcImFjdGl2ZVwiIHN0YXRlLCBlLmcuXG4gKiA8TmF2TGluaz4uXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSN1c2VtYXRjaFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlTWF0Y2g8XG4gIFBhcmFtS2V5IGV4dGVuZHMgUGFyYW1QYXJzZUtleTxQYXRoPixcbiAgUGF0aCBleHRlbmRzIHN0cmluZ1xuPihwYXR0ZXJuOiBQYXRoUGF0dGVybjxQYXRoPiB8IFBhdGgpOiBQYXRoTWF0Y2g8UGFyYW1LZXk+IHwgbnVsbCB7XG4gIGludmFyaWFudChcbiAgICB1c2VJblJvdXRlckNvbnRleHQoKSxcbiAgICAvLyBUT0RPOiBUaGlzIGVycm9yIGlzIHByb2JhYmx5IGJlY2F1c2UgdGhleSBzb21laG93IGhhdmUgMiB2ZXJzaW9ucyBvZiB0aGVcbiAgICAvLyByb3V0ZXIgbG9hZGVkLiBXZSBjYW4gaGVscCB0aGVtIHVuZGVyc3RhbmQgaG93IHRvIGF2b2lkIHRoYXQuXG4gICAgYHVzZU1hdGNoKCkgbWF5IGJlIHVzZWQgb25seSBpbiB0aGUgY29udGV4dCBvZiBhIDxSb3V0ZXI+IGNvbXBvbmVudC5gXG4gICk7XG5cbiAgbGV0IHsgcGF0aG5hbWUgfSA9IHVzZUxvY2F0aW9uKCk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKFxuICAgICgpID0+IG1hdGNoUGF0aDxQYXJhbUtleSwgUGF0aD4ocGF0dGVybiwgcGF0aG5hbWUpLFxuICAgIFtwYXRobmFtZSwgcGF0dGVybl1cbiAgKTtcbn1cblxuLyoqXG4gKiBUaGUgaW50ZXJmYWNlIGZvciB0aGUgbmF2aWdhdGUoKSBmdW5jdGlvbiByZXR1cm5lZCBmcm9tIHVzZU5hdmlnYXRlKCkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGVGdW5jdGlvbiB7XG4gICh0bzogVG8sIG9wdGlvbnM/OiBOYXZpZ2F0ZU9wdGlvbnMpOiB2b2lkO1xuICAoZGVsdGE6IG51bWJlcik6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGVPcHRpb25zIHtcbiAgcmVwbGFjZT86IGJvb2xlYW47XG4gIHN0YXRlPzogYW55O1xufVxuXG4vKipcbiAqIFJldHVybnMgYW4gaW1wZXJhdGl2ZSBtZXRob2QgZm9yIGNoYW5naW5nIHRoZSBsb2NhdGlvbi4gVXNlZCBieSA8TGluaz5zLCBidXRcbiAqIG1heSBhbHNvIGJlIHVzZWQgYnkgb3RoZXIgZWxlbWVudHMgdG8gY2hhbmdlIHRoZSBsb2NhdGlvbi5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI3VzZW5hdmlnYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VOYXZpZ2F0ZSgpOiBOYXZpZ2F0ZUZ1bmN0aW9uIHtcbiAgaW52YXJpYW50KFxuICAgIHVzZUluUm91dGVyQ29udGV4dCgpLFxuICAgIC8vIFRPRE86IFRoaXMgZXJyb3IgaXMgcHJvYmFibHkgYmVjYXVzZSB0aGV5IHNvbWVob3cgaGF2ZSAyIHZlcnNpb25zIG9mIHRoZVxuICAgIC8vIHJvdXRlciBsb2FkZWQuIFdlIGNhbiBoZWxwIHRoZW0gdW5kZXJzdGFuZCBob3cgdG8gYXZvaWQgdGhhdC5cbiAgICBgdXNlTmF2aWdhdGUoKSBtYXkgYmUgdXNlZCBvbmx5IGluIHRoZSBjb250ZXh0IG9mIGEgPFJvdXRlcj4gY29tcG9uZW50LmBcbiAgKTtcblxuICBsZXQgeyBiYXNlbmFtZSwgbmF2aWdhdG9yIH0gPSBSZWFjdC51c2VDb250ZXh0KE5hdmlnYXRpb25Db250ZXh0KTtcbiAgbGV0IHsgbWF0Y2hlcyB9ID0gUmVhY3QudXNlQ29udGV4dChSb3V0ZUNvbnRleHQpO1xuICBsZXQgeyBwYXRobmFtZTogbG9jYXRpb25QYXRobmFtZSB9ID0gdXNlTG9jYXRpb24oKTtcblxuICBsZXQgcm91dGVQYXRobmFtZXNKc29uID0gSlNPTi5zdHJpbmdpZnkoXG4gICAgbWF0Y2hlcy5tYXAoKG1hdGNoKSA9PiBtYXRjaC5wYXRobmFtZUJhc2UpXG4gICk7XG5cbiAgbGV0IGFjdGl2ZVJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgYWN0aXZlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICB9KTtcblxuICBsZXQgbmF2aWdhdGU6IE5hdmlnYXRlRnVuY3Rpb24gPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAodG86IFRvIHwgbnVtYmVyLCBvcHRpb25zOiBOYXZpZ2F0ZU9wdGlvbnMgPSB7fSkgPT4ge1xuICAgICAgd2FybmluZyhcbiAgICAgICAgYWN0aXZlUmVmLmN1cnJlbnQsXG4gICAgICAgIGBZb3Ugc2hvdWxkIGNhbGwgbmF2aWdhdGUoKSBpbiBhIFJlYWN0LnVzZUVmZmVjdCgpLCBub3Qgd2hlbiBgICtcbiAgICAgICAgICBgeW91ciBjb21wb25lbnQgaXMgZmlyc3QgcmVuZGVyZWQuYFxuICAgICAgKTtcblxuICAgICAgaWYgKCFhY3RpdmVSZWYuY3VycmVudCkgcmV0dXJuO1xuXG4gICAgICBpZiAodHlwZW9mIHRvID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIG5hdmlnYXRvci5nbyh0byk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IHBhdGggPSByZXNvbHZlVG8oXG4gICAgICAgIHRvLFxuICAgICAgICBKU09OLnBhcnNlKHJvdXRlUGF0aG5hbWVzSnNvbiksXG4gICAgICAgIGxvY2F0aW9uUGF0aG5hbWVcbiAgICAgICk7XG5cbiAgICAgIGlmIChiYXNlbmFtZSAhPT0gXCIvXCIpIHtcbiAgICAgICAgcGF0aC5wYXRobmFtZSA9IGpvaW5QYXRocyhbYmFzZW5hbWUsIHBhdGgucGF0aG5hbWVdKTtcbiAgICAgIH1cblxuICAgICAgKCEhb3B0aW9ucy5yZXBsYWNlID8gbmF2aWdhdG9yLnJlcGxhY2UgOiBuYXZpZ2F0b3IucHVzaCkoXG4gICAgICAgIHBhdGgsXG4gICAgICAgIG9wdGlvbnMuc3RhdGVcbiAgICAgICk7XG4gICAgfSxcbiAgICBbYmFzZW5hbWUsIG5hdmlnYXRvciwgcm91dGVQYXRobmFtZXNKc29uLCBsb2NhdGlvblBhdGhuYW1lXVxuICApO1xuXG4gIHJldHVybiBuYXZpZ2F0ZTtcbn1cblxuY29uc3QgT3V0bGV0Q29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8dW5rbm93bj4obnVsbCk7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29udGV4dCAoaWYgcHJvdmlkZWQpIGZvciB0aGUgY2hpbGQgcm91dGUgYXQgdGhpcyBsZXZlbCBvZiB0aGUgcm91dGVcbiAqIGhpZXJhcmNoeS5cbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vZG9jcy9lbi92Ni9hcGkjdXNlb3V0bGV0Y29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlT3V0bGV0Q29udGV4dDxDb250ZXh0ID0gdW5rbm93bj4oKTogQ29udGV4dCB7XG4gIHJldHVybiBSZWFjdC51c2VDb250ZXh0KE91dGxldENvbnRleHQpIGFzIENvbnRleHQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZWxlbWVudCBmb3IgdGhlIGNoaWxkIHJvdXRlIGF0IHRoaXMgbGV2ZWwgb2YgdGhlIHJvdXRlXG4gKiBoaWVyYXJjaHkuIFVzZWQgaW50ZXJuYWxseSBieSA8T3V0bGV0PiB0byByZW5kZXIgY2hpbGQgcm91dGVzLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vZG9jcy9lbi92Ni9hcGkjdXNlb3V0bGV0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VPdXRsZXQoY29udGV4dD86IHVua25vd24pOiBSZWFjdC5SZWFjdEVsZW1lbnQgfCBudWxsIHtcbiAgbGV0IG91dGxldCA9IFJlYWN0LnVzZUNvbnRleHQoUm91dGVDb250ZXh0KS5vdXRsZXQ7XG4gIGlmIChvdXRsZXQpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPE91dGxldENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e2NvbnRleHR9PntvdXRsZXR9PC9PdXRsZXRDb250ZXh0LlByb3ZpZGVyPlxuICAgICk7XG4gIH1cbiAgcmV0dXJuIG91dGxldDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9iamVjdCBvZiBrZXkvdmFsdWUgcGFpcnMgb2YgdGhlIGR5bmFtaWMgcGFyYW1zIGZyb20gdGhlIGN1cnJlbnRcbiAqIFVSTCB0aGF0IHdlcmUgbWF0Y2hlZCBieSB0aGUgcm91dGUgcGF0aC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI3VzZXBhcmFtc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlUGFyYW1zPFxuICBQYXJhbXNPcktleSBleHRlbmRzIHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gPSBzdHJpbmdcbj4oKTogUmVhZG9ubHk8XG4gIFtQYXJhbXNPcktleV0gZXh0ZW5kcyBbc3RyaW5nXSA/IFBhcmFtczxQYXJhbXNPcktleT4gOiBQYXJ0aWFsPFBhcmFtc09yS2V5PlxuPiB7XG4gIGxldCB7IG1hdGNoZXMgfSA9IFJlYWN0LnVzZUNvbnRleHQoUm91dGVDb250ZXh0KTtcbiAgbGV0IHJvdXRlTWF0Y2ggPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV07XG4gIHJldHVybiByb3V0ZU1hdGNoID8gKHJvdXRlTWF0Y2gucGFyYW1zIGFzIGFueSkgOiB7fTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgcGF0aG5hbWUgb2YgdGhlIGdpdmVuIGB0b2AgdmFsdWUgYWdhaW5zdCB0aGUgY3VycmVudCBsb2NhdGlvbi5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI3VzZXJlc29sdmVkcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlUmVzb2x2ZWRQYXRoKHRvOiBUbyk6IFBhdGgge1xuICBsZXQgeyBtYXRjaGVzIH0gPSBSZWFjdC51c2VDb250ZXh0KFJvdXRlQ29udGV4dCk7XG4gIGxldCB7IHBhdGhuYW1lOiBsb2NhdGlvblBhdGhuYW1lIH0gPSB1c2VMb2NhdGlvbigpO1xuXG4gIGxldCByb3V0ZVBhdGhuYW1lc0pzb24gPSBKU09OLnN0cmluZ2lmeShcbiAgICBtYXRjaGVzLm1hcCgobWF0Y2gpID0+IG1hdGNoLnBhdGhuYW1lQmFzZSlcbiAgKTtcblxuICByZXR1cm4gUmVhY3QudXNlTWVtbyhcbiAgICAoKSA9PiByZXNvbHZlVG8odG8sIEpTT04ucGFyc2Uocm91dGVQYXRobmFtZXNKc29uKSwgbG9jYXRpb25QYXRobmFtZSksXG4gICAgW3RvLCByb3V0ZVBhdGhuYW1lc0pzb24sIGxvY2F0aW9uUGF0aG5hbWVdXG4gICk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZWxlbWVudCBvZiB0aGUgcm91dGUgdGhhdCBtYXRjaGVkIHRoZSBjdXJyZW50IGxvY2F0aW9uLCBwcmVwYXJlZFxuICogd2l0aCB0aGUgY29ycmVjdCBjb250ZXh0IHRvIHJlbmRlciB0aGUgcmVtYWluZGVyIG9mIHRoZSByb3V0ZSB0cmVlLiBSb3V0ZVxuICogZWxlbWVudHMgaW4gdGhlIHRyZWUgbXVzdCByZW5kZXIgYW4gPE91dGxldD4gdG8gcmVuZGVyIHRoZWlyIGNoaWxkIHJvdXRlJ3NcbiAqIGVsZW1lbnQuXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSN1c2Vyb3V0ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVJvdXRlcyhcbiAgcm91dGVzOiBSb3V0ZU9iamVjdFtdLFxuICBsb2NhdGlvbkFyZz86IFBhcnRpYWw8TG9jYXRpb24+IHwgc3RyaW5nXG4pOiBSZWFjdC5SZWFjdEVsZW1lbnQgfCBudWxsIHtcbiAgaW52YXJpYW50KFxuICAgIHVzZUluUm91dGVyQ29udGV4dCgpLFxuICAgIC8vIFRPRE86IFRoaXMgZXJyb3IgaXMgcHJvYmFibHkgYmVjYXVzZSB0aGV5IHNvbWVob3cgaGF2ZSAyIHZlcnNpb25zIG9mIHRoZVxuICAgIC8vIHJvdXRlciBsb2FkZWQuIFdlIGNhbiBoZWxwIHRoZW0gdW5kZXJzdGFuZCBob3cgdG8gYXZvaWQgdGhhdC5cbiAgICBgdXNlUm91dGVzKCkgbWF5IGJlIHVzZWQgb25seSBpbiB0aGUgY29udGV4dCBvZiBhIDxSb3V0ZXI+IGNvbXBvbmVudC5gXG4gICk7XG5cbiAgbGV0IHsgbWF0Y2hlczogcGFyZW50TWF0Y2hlcyB9ID0gUmVhY3QudXNlQ29udGV4dChSb3V0ZUNvbnRleHQpO1xuICBsZXQgcm91dGVNYXRjaCA9IHBhcmVudE1hdGNoZXNbcGFyZW50TWF0Y2hlcy5sZW5ndGggLSAxXTtcbiAgbGV0IHBhcmVudFBhcmFtcyA9IHJvdXRlTWF0Y2ggPyByb3V0ZU1hdGNoLnBhcmFtcyA6IHt9O1xuICBsZXQgcGFyZW50UGF0aG5hbWUgPSByb3V0ZU1hdGNoID8gcm91dGVNYXRjaC5wYXRobmFtZSA6IFwiL1wiO1xuICBsZXQgcGFyZW50UGF0aG5hbWVCYXNlID0gcm91dGVNYXRjaCA/IHJvdXRlTWF0Y2gucGF0aG5hbWVCYXNlIDogXCIvXCI7XG4gIGxldCBwYXJlbnRSb3V0ZSA9IHJvdXRlTWF0Y2ggJiYgcm91dGVNYXRjaC5yb3V0ZTtcblxuICBpZiAoX19ERVZfXykge1xuICAgIC8vIFlvdSB3b24ndCBnZXQgYSB3YXJuaW5nIGFib3V0IDIgZGlmZmVyZW50IDxSb3V0ZXM+IHVuZGVyIGEgPFJvdXRlPlxuICAgIC8vIHdpdGhvdXQgYSB0cmFpbGluZyAqLCBidXQgdGhpcyBpcyBhIGJlc3QtZWZmb3J0IHdhcm5pbmcgYW55d2F5IHNpbmNlIHdlXG4gICAgLy8gY2Fubm90IGV2ZW4gZ2l2ZSB0aGUgd2FybmluZyB1bmxlc3MgdGhleSBsYW5kIGF0IHRoZSBwYXJlbnQgcm91dGUuXG4gICAgLy9cbiAgICAvLyBFeGFtcGxlOlxuICAgIC8vXG4gICAgLy8gPFJvdXRlcz5cbiAgICAvLyAgIHsvKiBUaGlzIHJvdXRlIHBhdGggTVVTVCBlbmQgd2l0aCAvKiBiZWNhdXNlIG90aGVyd2lzZVxuICAgIC8vICAgICAgIGl0IHdpbGwgbmV2ZXIgbWF0Y2ggL2Jsb2cvcG9zdC8xMjMgKi99XG4gICAgLy8gICA8Um91dGUgcGF0aD1cImJsb2dcIiBlbGVtZW50PXs8QmxvZyAvPn0gLz5cbiAgICAvLyAgIDxSb3V0ZSBwYXRoPVwiYmxvZy9mZWVkXCIgZWxlbWVudD17PEJsb2dGZWVkIC8+fSAvPlxuICAgIC8vIDwvUm91dGVzPlxuICAgIC8vXG4gICAgLy8gZnVuY3Rpb24gQmxvZygpIHtcbiAgICAvLyAgIHJldHVybiAoXG4gICAgLy8gICAgIDxSb3V0ZXM+XG4gICAgLy8gICAgICAgPFJvdXRlIHBhdGg9XCJwb3N0LzppZFwiIGVsZW1lbnQ9ezxQb3N0IC8+fSAvPlxuICAgIC8vICAgICA8L1JvdXRlcz5cbiAgICAvLyAgICk7XG4gICAgLy8gfVxuICAgIGxldCBwYXJlbnRQYXRoID0gKHBhcmVudFJvdXRlICYmIHBhcmVudFJvdXRlLnBhdGgpIHx8IFwiXCI7XG4gICAgd2FybmluZ09uY2UoXG4gICAgICBwYXJlbnRQYXRobmFtZSxcbiAgICAgICFwYXJlbnRSb3V0ZSB8fCBwYXJlbnRQYXRoLmVuZHNXaXRoKFwiKlwiKSxcbiAgICAgIGBZb3UgcmVuZGVyZWQgZGVzY2VuZGFudCA8Um91dGVzPiAob3IgY2FsbGVkIFxcYHVzZVJvdXRlcygpXFxgKSBhdCBgICtcbiAgICAgICAgYFwiJHtwYXJlbnRQYXRobmFtZX1cIiAodW5kZXIgPFJvdXRlIHBhdGg9XCIke3BhcmVudFBhdGh9XCI+KSBidXQgdGhlIGAgK1xuICAgICAgICBgcGFyZW50IHJvdXRlIHBhdGggaGFzIG5vIHRyYWlsaW5nIFwiKlwiLiBUaGlzIG1lYW5zIGlmIHlvdSBuYXZpZ2F0ZSBgICtcbiAgICAgICAgYGRlZXBlciwgdGhlIHBhcmVudCB3b24ndCBtYXRjaCBhbnltb3JlIGFuZCB0aGVyZWZvcmUgdGhlIGNoaWxkIGAgK1xuICAgICAgICBgcm91dGVzIHdpbGwgbmV2ZXIgcmVuZGVyLlxcblxcbmAgK1xuICAgICAgICBgUGxlYXNlIGNoYW5nZSB0aGUgcGFyZW50IDxSb3V0ZSBwYXRoPVwiJHtwYXJlbnRQYXRofVwiPiB0byA8Um91dGUgYCArXG4gICAgICAgIGBwYXRoPVwiJHtwYXJlbnRQYXRoID09PSBcIi9cIiA/IFwiKlwiIDogYCR7cGFyZW50UGF0aH0vKmB9XCI+LmBcbiAgICApO1xuICB9XG5cbiAgbGV0IGxvY2F0aW9uRnJvbUNvbnRleHQgPSB1c2VMb2NhdGlvbigpO1xuXG4gIGxldCBsb2NhdGlvbjtcbiAgaWYgKGxvY2F0aW9uQXJnKSB7XG4gICAgbGV0IHBhcnNlZExvY2F0aW9uQXJnID1cbiAgICAgIHR5cGVvZiBsb2NhdGlvbkFyZyA9PT0gXCJzdHJpbmdcIiA/IHBhcnNlUGF0aChsb2NhdGlvbkFyZykgOiBsb2NhdGlvbkFyZztcblxuICAgIGludmFyaWFudChcbiAgICAgIHBhcmVudFBhdGhuYW1lQmFzZSA9PT0gXCIvXCIgfHxcbiAgICAgICAgcGFyc2VkTG9jYXRpb25BcmcucGF0aG5hbWU/LnN0YXJ0c1dpdGgocGFyZW50UGF0aG5hbWVCYXNlKSxcbiAgICAgIGBXaGVuIG92ZXJyaWRpbmcgdGhlIGxvY2F0aW9uIHVzaW5nIFxcYDxSb3V0ZXMgbG9jYXRpb24+XFxgIG9yIFxcYHVzZVJvdXRlcyhyb3V0ZXMsIGxvY2F0aW9uKVxcYCwgYCArXG4gICAgICAgIGB0aGUgbG9jYXRpb24gcGF0aG5hbWUgbXVzdCBiZWdpbiB3aXRoIHRoZSBwb3J0aW9uIG9mIHRoZSBVUkwgcGF0aG5hbWUgdGhhdCB3YXMgYCArXG4gICAgICAgIGBtYXRjaGVkIGJ5IGFsbCBwYXJlbnQgcm91dGVzLiBUaGUgY3VycmVudCBwYXRobmFtZSBiYXNlIGlzIFwiJHtwYXJlbnRQYXRobmFtZUJhc2V9XCIgYCArXG4gICAgICAgIGBidXQgcGF0aG5hbWUgXCIke3BhcnNlZExvY2F0aW9uQXJnLnBhdGhuYW1lfVwiIHdhcyBnaXZlbiBpbiB0aGUgXFxgbG9jYXRpb25cXGAgcHJvcC5gXG4gICAgKTtcblxuICAgIGxvY2F0aW9uID0gcGFyc2VkTG9jYXRpb25Bcmc7XG4gIH0gZWxzZSB7XG4gICAgbG9jYXRpb24gPSBsb2NhdGlvbkZyb21Db250ZXh0O1xuICB9XG5cbiAgbGV0IHBhdGhuYW1lID0gbG9jYXRpb24ucGF0aG5hbWUgfHwgXCIvXCI7XG4gIGxldCByZW1haW5pbmdQYXRobmFtZSA9XG4gICAgcGFyZW50UGF0aG5hbWVCYXNlID09PSBcIi9cIlxuICAgICAgPyBwYXRobmFtZVxuICAgICAgOiBwYXRobmFtZS5zbGljZShwYXJlbnRQYXRobmFtZUJhc2UubGVuZ3RoKSB8fCBcIi9cIjtcbiAgbGV0IG1hdGNoZXMgPSBtYXRjaFJvdXRlcyhyb3V0ZXMsIHsgcGF0aG5hbWU6IHJlbWFpbmluZ1BhdGhuYW1lIH0pO1xuXG4gIGlmIChfX0RFVl9fKSB7XG4gICAgd2FybmluZyhcbiAgICAgIHBhcmVudFJvdXRlIHx8IG1hdGNoZXMgIT0gbnVsbCxcbiAgICAgIGBObyByb3V0ZXMgbWF0Y2hlZCBsb2NhdGlvbiBcIiR7bG9jYXRpb24ucGF0aG5hbWV9JHtsb2NhdGlvbi5zZWFyY2h9JHtsb2NhdGlvbi5oYXNofVwiIGBcbiAgICApO1xuXG4gICAgd2FybmluZyhcbiAgICAgIG1hdGNoZXMgPT0gbnVsbCB8fFxuICAgICAgICBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0ucm91dGUuZWxlbWVudCAhPT0gdW5kZWZpbmVkLFxuICAgICAgYE1hdGNoZWQgbGVhZiByb3V0ZSBhdCBsb2NhdGlvbiBcIiR7bG9jYXRpb24ucGF0aG5hbWV9JHtsb2NhdGlvbi5zZWFyY2h9JHtsb2NhdGlvbi5oYXNofVwiIGRvZXMgbm90IGhhdmUgYW4gZWxlbWVudC4gYCArXG4gICAgICAgIGBUaGlzIG1lYW5zIGl0IHdpbGwgcmVuZGVyIGFuIDxPdXRsZXQgLz4gd2l0aCBhIG51bGwgdmFsdWUgYnkgZGVmYXVsdCByZXN1bHRpbmcgaW4gYW4gXCJlbXB0eVwiIHBhZ2UuYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gX3JlbmRlck1hdGNoZXMoXG4gICAgbWF0Y2hlcyAmJlxuICAgICAgbWF0Y2hlcy5tYXAoKG1hdGNoKSA9PlxuICAgICAgICBPYmplY3QuYXNzaWduKHt9LCBtYXRjaCwge1xuICAgICAgICAgIHBhcmFtczogT2JqZWN0LmFzc2lnbih7fSwgcGFyZW50UGFyYW1zLCBtYXRjaC5wYXJhbXMpLFxuICAgICAgICAgIHBhdGhuYW1lOiBqb2luUGF0aHMoW3BhcmVudFBhdGhuYW1lQmFzZSwgbWF0Y2gucGF0aG5hbWVdKSxcbiAgICAgICAgICBwYXRobmFtZUJhc2U6XG4gICAgICAgICAgICBtYXRjaC5wYXRobmFtZUJhc2UgPT09IFwiL1wiXG4gICAgICAgICAgICAgID8gcGFyZW50UGF0aG5hbWVCYXNlXG4gICAgICAgICAgICAgIDogam9pblBhdGhzKFtwYXJlbnRQYXRobmFtZUJhc2UsIG1hdGNoLnBhdGhuYW1lQmFzZV0pLFxuICAgICAgICB9KVxuICAgICAgKSxcbiAgICBwYXJlbnRNYXRjaGVzXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfcmVuZGVyTWF0Y2hlcyhcbiAgbWF0Y2hlczogUm91dGVNYXRjaFtdIHwgbnVsbCxcbiAgcGFyZW50TWF0Y2hlczogUm91dGVNYXRjaFtdID0gW11cbik6IFJlYWN0LlJlYWN0RWxlbWVudCB8IG51bGwge1xuICBpZiAobWF0Y2hlcyA9PSBudWxsKSByZXR1cm4gbnVsbDtcblxuICByZXR1cm4gbWF0Y2hlcy5yZWR1Y2VSaWdodCgob3V0bGV0LCBtYXRjaCwgaW5kZXgpID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgPFJvdXRlQ29udGV4dC5Qcm92aWRlclxuICAgICAgICBjaGlsZHJlbj17XG4gICAgICAgICAgbWF0Y2gucm91dGUuZWxlbWVudCAhPT0gdW5kZWZpbmVkID8gbWF0Y2gucm91dGUuZWxlbWVudCA6IG91dGxldFxuICAgICAgICB9XG4gICAgICAgIHZhbHVlPXt7XG4gICAgICAgICAgb3V0bGV0LFxuICAgICAgICAgIG1hdGNoZXM6IHBhcmVudE1hdGNoZXMuY29uY2F0KG1hdGNoZXMuc2xpY2UoMCwgaW5kZXggKyAxKSksXG4gICAgICAgIH19XG4gICAgICAvPlxuICAgICk7XG4gIH0sIG51bGwgYXMgUmVhY3QuUmVhY3RFbGVtZW50IHwgbnVsbCk7XG59XG4iLCAiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgdHlwZSB7IEluaXRpYWxFbnRyeSwgTG9jYXRpb24sIE1lbW9yeUhpc3RvcnksIFRvIH0gZnJvbSBcImhpc3RvcnlcIjtcbmltcG9ydCB7XG4gIEFjdGlvbiBhcyBOYXZpZ2F0aW9uVHlwZSxcbiAgY3JlYXRlTWVtb3J5SGlzdG9yeSxcbiAgcGFyc2VQYXRoLFxufSBmcm9tIFwiaGlzdG9yeVwiO1xuXG5pbXBvcnQgeyBMb2NhdGlvbkNvbnRleHQsIE5hdmlnYXRpb25Db250ZXh0LCBOYXZpZ2F0b3IgfSBmcm9tIFwiLi9jb250ZXh0XCI7XG5pbXBvcnQge1xuICB1c2VJblJvdXRlckNvbnRleHQsXG4gIHVzZU5hdmlnYXRlLFxuICB1c2VPdXRsZXQsXG4gIHVzZVJvdXRlcyxcbiAgX3JlbmRlck1hdGNoZXMsXG59IGZyb20gXCIuL2hvb2tzXCI7XG5pbXBvcnQgdHlwZSB7IFJvdXRlTWF0Y2gsIFJvdXRlT2JqZWN0IH0gZnJvbSBcIi4vcm91dGVyXCI7XG5pbXBvcnQgeyBpbnZhcmlhbnQsIG5vcm1hbGl6ZVBhdGhuYW1lLCBzdHJpcEJhc2VuYW1lLCB3YXJuaW5nIH0gZnJvbSBcIi4vcm91dGVyXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVtb3J5Um91dGVyUHJvcHMge1xuICBiYXNlbmFtZT86IHN0cmluZztcbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGU7XG4gIGluaXRpYWxFbnRyaWVzPzogSW5pdGlhbEVudHJ5W107XG4gIGluaXRpYWxJbmRleD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBBIDxSb3V0ZXI+IHRoYXQgc3RvcmVzIGFsbCBlbnRyaWVzIGluIG1lbW9yeS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI21lbW9yeXJvdXRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gTWVtb3J5Um91dGVyKHtcbiAgYmFzZW5hbWUsXG4gIGNoaWxkcmVuLFxuICBpbml0aWFsRW50cmllcyxcbiAgaW5pdGlhbEluZGV4LFxufTogTWVtb3J5Um91dGVyUHJvcHMpOiBSZWFjdC5SZWFjdEVsZW1lbnQge1xuICBsZXQgaGlzdG9yeVJlZiA9IFJlYWN0LnVzZVJlZjxNZW1vcnlIaXN0b3J5PigpO1xuICBpZiAoaGlzdG9yeVJlZi5jdXJyZW50ID09IG51bGwpIHtcbiAgICBoaXN0b3J5UmVmLmN1cnJlbnQgPSBjcmVhdGVNZW1vcnlIaXN0b3J5KHsgaW5pdGlhbEVudHJpZXMsIGluaXRpYWxJbmRleCB9KTtcbiAgfVxuXG4gIGxldCBoaXN0b3J5ID0gaGlzdG9yeVJlZi5jdXJyZW50O1xuICBsZXQgW3N0YXRlLCBzZXRTdGF0ZV0gPSBSZWFjdC51c2VTdGF0ZSh7XG4gICAgYWN0aW9uOiBoaXN0b3J5LmFjdGlvbixcbiAgICBsb2NhdGlvbjogaGlzdG9yeS5sb2NhdGlvbixcbiAgfSk7XG5cbiAgUmVhY3QudXNlTGF5b3V0RWZmZWN0KCgpID0+IGhpc3RvcnkubGlzdGVuKHNldFN0YXRlKSwgW2hpc3RvcnldKTtcblxuICByZXR1cm4gKFxuICAgIDxSb3V0ZXJcbiAgICAgIGJhc2VuYW1lPXtiYXNlbmFtZX1cbiAgICAgIGNoaWxkcmVuPXtjaGlsZHJlbn1cbiAgICAgIGxvY2F0aW9uPXtzdGF0ZS5sb2NhdGlvbn1cbiAgICAgIG5hdmlnYXRpb25UeXBlPXtzdGF0ZS5hY3Rpb259XG4gICAgICBuYXZpZ2F0b3I9e2hpc3Rvcnl9XG4gICAgLz5cbiAgKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOYXZpZ2F0ZVByb3BzIHtcbiAgdG86IFRvO1xuICByZXBsYWNlPzogYm9vbGVhbjtcbiAgc3RhdGU/OiBhbnk7XG59XG5cbi8qKlxuICogQ2hhbmdlcyB0aGUgY3VycmVudCBsb2NhdGlvbi5cbiAqXG4gKiBOb3RlOiBUaGlzIEFQSSBpcyBtb3N0bHkgdXNlZnVsIGluIFJlYWN0LkNvbXBvbmVudCBzdWJjbGFzc2VzIHRoYXQgYXJlIG5vdFxuICogYWJsZSB0byB1c2UgaG9va3MuIEluIGZ1bmN0aW9uYWwgY29tcG9uZW50cywgd2UgcmVjb21tZW5kIHlvdSB1c2UgdGhlXG4gKiBgdXNlTmF2aWdhdGVgIGhvb2sgaW5zdGVhZC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI25hdmlnYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBOYXZpZ2F0ZSh7IHRvLCByZXBsYWNlLCBzdGF0ZSB9OiBOYXZpZ2F0ZVByb3BzKTogbnVsbCB7XG4gIGludmFyaWFudChcbiAgICB1c2VJblJvdXRlckNvbnRleHQoKSxcbiAgICAvLyBUT0RPOiBUaGlzIGVycm9yIGlzIHByb2JhYmx5IGJlY2F1c2UgdGhleSBzb21laG93IGhhdmUgMiB2ZXJzaW9ucyBvZlxuICAgIC8vIHRoZSByb3V0ZXIgbG9hZGVkLiBXZSBjYW4gaGVscCB0aGVtIHVuZGVyc3RhbmQgaG93IHRvIGF2b2lkIHRoYXQuXG4gICAgYDxOYXZpZ2F0ZT4gbWF5IGJlIHVzZWQgb25seSBpbiB0aGUgY29udGV4dCBvZiBhIDxSb3V0ZXI+IGNvbXBvbmVudC5gXG4gICk7XG5cbiAgd2FybmluZyhcbiAgICAhUmVhY3QudXNlQ29udGV4dChOYXZpZ2F0aW9uQ29udGV4dCkuc3RhdGljLFxuICAgIGA8TmF2aWdhdGU+IG11c3Qgbm90IGJlIHVzZWQgb24gdGhlIGluaXRpYWwgcmVuZGVyIGluIGEgPFN0YXRpY1JvdXRlcj4uIGAgK1xuICAgICAgYFRoaXMgaXMgYSBuby1vcCwgYnV0IHlvdSBzaG91bGQgbW9kaWZ5IHlvdXIgY29kZSBzbyB0aGUgPE5hdmlnYXRlPiBpcyBgICtcbiAgICAgIGBvbmx5IGV2ZXIgcmVuZGVyZWQgaW4gcmVzcG9uc2UgdG8gc29tZSB1c2VyIGludGVyYWN0aW9uIG9yIHN0YXRlIGNoYW5nZS5gXG4gICk7XG5cbiAgbGV0IG5hdmlnYXRlID0gdXNlTmF2aWdhdGUoKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBuYXZpZ2F0ZSh0bywgeyByZXBsYWNlLCBzdGF0ZSB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3V0bGV0UHJvcHMge1xuICBjb250ZXh0PzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBjaGlsZCByb3V0ZSdzIGVsZW1lbnQsIGlmIHRoZXJlIGlzIG9uZS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL2RvY3MvZW4vdjYvYXBpI291dGxldFxuICovXG5leHBvcnQgZnVuY3Rpb24gT3V0bGV0KHByb3BzOiBPdXRsZXRQcm9wcyk6IFJlYWN0LlJlYWN0RWxlbWVudCB8IG51bGwge1xuICByZXR1cm4gdXNlT3V0bGV0KHByb3BzLmNvbnRleHQpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlUHJvcHMge1xuICBjYXNlU2Vuc2l0aXZlPzogYm9vbGVhbjtcbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGU7XG4gIGVsZW1lbnQ/OiBSZWFjdC5SZWFjdE5vZGUgfCBudWxsO1xuICBpbmRleD86IGJvb2xlYW47XG4gIHBhdGg/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGF0aFJvdXRlUHJvcHMge1xuICBjYXNlU2Vuc2l0aXZlPzogYm9vbGVhbjtcbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGU7XG4gIGVsZW1lbnQ/OiBSZWFjdC5SZWFjdE5vZGUgfCBudWxsO1xuICBpbmRleD86IGZhbHNlO1xuICBwYXRoOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGF5b3V0Um91dGVQcm9wcyB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3ROb2RlO1xuICBlbGVtZW50PzogUmVhY3QuUmVhY3ROb2RlIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmRleFJvdXRlUHJvcHMge1xuICBlbGVtZW50PzogUmVhY3QuUmVhY3ROb2RlIHwgbnVsbDtcbiAgaW5kZXg6IHRydWU7XG59XG5cbi8qKlxuICogRGVjbGFyZXMgYW4gZWxlbWVudCB0aGF0IHNob3VsZCBiZSByZW5kZXJlZCBhdCBhIGNlcnRhaW4gVVJMIHBhdGguXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSNyb3V0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gUm91dGUoXG4gIF9wcm9wczogUGF0aFJvdXRlUHJvcHMgfCBMYXlvdXRSb3V0ZVByb3BzIHwgSW5kZXhSb3V0ZVByb3BzXG4pOiBSZWFjdC5SZWFjdEVsZW1lbnQgfCBudWxsIHtcbiAgaW52YXJpYW50KFxuICAgIGZhbHNlLFxuICAgIGBBIDxSb3V0ZT4gaXMgb25seSBldmVyIHRvIGJlIHVzZWQgYXMgdGhlIGNoaWxkIG9mIDxSb3V0ZXM+IGVsZW1lbnQsIGAgK1xuICAgICAgYG5ldmVyIHJlbmRlcmVkIGRpcmVjdGx5LiBQbGVhc2Ugd3JhcCB5b3VyIDxSb3V0ZT4gaW4gYSA8Um91dGVzPi5gXG4gICk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGVyUHJvcHMge1xuICBiYXNlbmFtZT86IHN0cmluZztcbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGU7XG4gIGxvY2F0aW9uOiBQYXJ0aWFsPExvY2F0aW9uPiB8IHN0cmluZztcbiAgbmF2aWdhdGlvblR5cGU/OiBOYXZpZ2F0aW9uVHlwZTtcbiAgbmF2aWdhdG9yOiBOYXZpZ2F0b3I7XG4gIHN0YXRpYz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUHJvdmlkZXMgbG9jYXRpb24gY29udGV4dCBmb3IgdGhlIHJlc3Qgb2YgdGhlIGFwcC5cbiAqXG4gKiBOb3RlOiBZb3UgdXN1YWxseSB3b24ndCByZW5kZXIgYSA8Um91dGVyPiBkaXJlY3RseS4gSW5zdGVhZCwgeW91J2xsIHJlbmRlciBhXG4gKiByb3V0ZXIgdGhhdCBpcyBtb3JlIHNwZWNpZmljIHRvIHlvdXIgZW52aXJvbm1lbnQgc3VjaCBhcyBhIDxCcm93c2VyUm91dGVyPlxuICogaW4gd2ViIGJyb3dzZXJzIG9yIGEgPFN0YXRpY1JvdXRlcj4gZm9yIHNlcnZlciByZW5kZXJpbmcuXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS9kb2NzL2VuL3Y2L2FwaSNyb3V0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFJvdXRlcih7XG4gIGJhc2VuYW1lOiBiYXNlbmFtZVByb3AgPSBcIi9cIixcbiAgY2hpbGRyZW4gPSBudWxsLFxuICBsb2NhdGlvbjogbG9jYXRpb25Qcm9wLFxuICBuYXZpZ2F0aW9uVHlwZSA9IE5hdmlnYXRpb25UeXBlLlBvcCxcbiAgbmF2aWdhdG9yLFxuICBzdGF0aWM6IHN0YXRpY1Byb3AgPSBmYWxzZSxcbn06IFJvdXRlclByb3BzKTogUmVhY3QuUmVhY3RFbGVtZW50IHwgbnVsbCB7XG4gIGludmFyaWFudChcbiAgICAhdXNlSW5Sb3V0ZXJDb250ZXh0KCksXG4gICAgYFlvdSBjYW5ub3QgcmVuZGVyIGEgPFJvdXRlcj4gaW5zaWRlIGFub3RoZXIgPFJvdXRlcj4uYCArXG4gICAgICBgIFlvdSBzaG91bGQgbmV2ZXIgaGF2ZSBtb3JlIHRoYW4gb25lIGluIHlvdXIgYXBwLmBcbiAgKTtcblxuICBsZXQgYmFzZW5hbWUgPSBub3JtYWxpemVQYXRobmFtZShiYXNlbmFtZVByb3ApO1xuICBsZXQgbmF2aWdhdGlvbkNvbnRleHQgPSBSZWFjdC51c2VNZW1vKFxuICAgICgpID0+ICh7IGJhc2VuYW1lLCBuYXZpZ2F0b3IsIHN0YXRpYzogc3RhdGljUHJvcCB9KSxcbiAgICBbYmFzZW5hbWUsIG5hdmlnYXRvciwgc3RhdGljUHJvcF1cbiAgKTtcblxuICBpZiAodHlwZW9mIGxvY2F0aW9uUHJvcCA9PT0gXCJzdHJpbmdcIikge1xuICAgIGxvY2F0aW9uUHJvcCA9IHBhcnNlUGF0aChsb2NhdGlvblByb3ApO1xuICB9XG5cbiAgbGV0IHtcbiAgICBwYXRobmFtZSA9IFwiL1wiLFxuICAgIHNlYXJjaCA9IFwiXCIsXG4gICAgaGFzaCA9IFwiXCIsXG4gICAgc3RhdGUgPSBudWxsLFxuICAgIGtleSA9IFwiZGVmYXVsdFwiLFxuICB9ID0gbG9jYXRpb25Qcm9wO1xuXG4gIGxldCBsb2NhdGlvbiA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGxldCB0cmFpbGluZ1BhdGhuYW1lID0gc3RyaXBCYXNlbmFtZShwYXRobmFtZSwgYmFzZW5hbWUpO1xuXG4gICAgaWYgKHRyYWlsaW5nUGF0aG5hbWUgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBhdGhuYW1lOiB0cmFpbGluZ1BhdGhuYW1lLFxuICAgICAgc2VhcmNoLFxuICAgICAgaGFzaCxcbiAgICAgIHN0YXRlLFxuICAgICAga2V5LFxuICAgIH07XG4gIH0sIFtiYXNlbmFtZSwgcGF0aG5hbWUsIHNlYXJjaCwgaGFzaCwgc3RhdGUsIGtleV0pO1xuXG4gIHdhcm5pbmcoXG4gICAgbG9jYXRpb24gIT0gbnVsbCxcbiAgICBgPFJvdXRlciBiYXNlbmFtZT1cIiR7YmFzZW5hbWV9XCI+IGlzIG5vdCBhYmxlIHRvIG1hdGNoIHRoZSBVUkwgYCArXG4gICAgICBgXCIke3BhdGhuYW1lfSR7c2VhcmNofSR7aGFzaH1cIiBiZWNhdXNlIGl0IGRvZXMgbm90IHN0YXJ0IHdpdGggdGhlIGAgK1xuICAgICAgYGJhc2VuYW1lLCBzbyB0aGUgPFJvdXRlcj4gd29uJ3QgcmVuZGVyIGFueXRoaW5nLmBcbiAgKTtcblxuICBpZiAobG9jYXRpb24gPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8TmF2aWdhdGlvbkNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e25hdmlnYXRpb25Db250ZXh0fT5cbiAgICAgIDxMb2NhdGlvbkNvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgY2hpbGRyZW49e2NoaWxkcmVufVxuICAgICAgICB2YWx1ZT17eyBsb2NhdGlvbiwgbmF2aWdhdGlvblR5cGUgfX1cbiAgICAgIC8+XG4gICAgPC9OYXZpZ2F0aW9uQ29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSb3V0ZXNQcm9wcyB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3ROb2RlO1xuICBsb2NhdGlvbj86IFBhcnRpYWw8TG9jYXRpb24+IHwgc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgY29udGFpbmVyIGZvciBhIG5lc3RlZCB0cmVlIG9mIDxSb3V0ZT4gZWxlbWVudHMgdGhhdCByZW5kZXJzIHRoZSBicmFuY2hcbiAqIHRoYXQgYmVzdCBtYXRjaGVzIHRoZSBjdXJyZW50IGxvY2F0aW9uLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vZG9jcy9lbi92Ni9hcGkjcm91dGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBSb3V0ZXMoe1xuICBjaGlsZHJlbixcbiAgbG9jYXRpb24sXG59OiBSb3V0ZXNQcm9wcyk6IFJlYWN0LlJlYWN0RWxlbWVudCB8IG51bGwge1xuICByZXR1cm4gdXNlUm91dGVzKGNyZWF0ZVJvdXRlc0Zyb21DaGlsZHJlbihjaGlsZHJlbiksIGxvY2F0aW9uKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gVVRJTFNcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDcmVhdGVzIGEgcm91dGUgY29uZmlnIGZyb20gYSBSZWFjdCBcImNoaWxkcmVuXCIgb2JqZWN0LCB3aGljaCBpcyB1c3VhbGx5XG4gKiBlaXRoZXIgYSBgPFJvdXRlPmAgZWxlbWVudCBvciBhbiBhcnJheSBvZiB0aGVtLiBVc2VkIGludGVybmFsbHkgYnlcbiAqIGA8Um91dGVzPmAgdG8gY3JlYXRlIGEgcm91dGUgY29uZmlnIGZyb20gaXRzIGNoaWxkcmVuLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vZG9jcy9lbi92Ni9hcGkjY3JlYXRlcm91dGVzZnJvbWNoaWxkcmVuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSb3V0ZXNGcm9tQ2hpbGRyZW4oXG4gIGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGVcbik6IFJvdXRlT2JqZWN0W10ge1xuICBsZXQgcm91dGVzOiBSb3V0ZU9iamVjdFtdID0gW107XG5cbiAgUmVhY3QuQ2hpbGRyZW4uZm9yRWFjaChjaGlsZHJlbiwgKGVsZW1lbnQpID0+IHtcbiAgICBpZiAoIVJlYWN0LmlzVmFsaWRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAvLyBJZ25vcmUgbm9uLWVsZW1lbnRzLiBUaGlzIGFsbG93cyBwZW9wbGUgdG8gbW9yZSBlYXNpbHkgaW5saW5lXG4gICAgICAvLyBjb25kaXRpb25hbHMgaW4gdGhlaXIgcm91dGUgY29uZmlnLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFJlYWN0LkZyYWdtZW50KSB7XG4gICAgICAvLyBUcmFuc3BhcmVudGx5IHN1cHBvcnQgUmVhY3QuRnJhZ21lbnQgYW5kIGl0cyBjaGlsZHJlbi5cbiAgICAgIHJvdXRlcy5wdXNoLmFwcGx5KFxuICAgICAgICByb3V0ZXMsXG4gICAgICAgIGNyZWF0ZVJvdXRlc0Zyb21DaGlsZHJlbihlbGVtZW50LnByb3BzLmNoaWxkcmVuKVxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpbnZhcmlhbnQoXG4gICAgICBlbGVtZW50LnR5cGUgPT09IFJvdXRlLFxuICAgICAgYFske1xuICAgICAgICB0eXBlb2YgZWxlbWVudC50eXBlID09PSBcInN0cmluZ1wiID8gZWxlbWVudC50eXBlIDogZWxlbWVudC50eXBlLm5hbWVcbiAgICAgIH1dIGlzIG5vdCBhIDxSb3V0ZT4gY29tcG9uZW50LiBBbGwgY29tcG9uZW50IGNoaWxkcmVuIG9mIDxSb3V0ZXM+IG11c3QgYmUgYSA8Um91dGU+IG9yIDxSZWFjdC5GcmFnbWVudD5gXG4gICAgKTtcblxuICAgIGxldCByb3V0ZTogUm91dGVPYmplY3QgPSB7XG4gICAgICBjYXNlU2Vuc2l0aXZlOiBlbGVtZW50LnByb3BzLmNhc2VTZW5zaXRpdmUsXG4gICAgICBlbGVtZW50OiBlbGVtZW50LnByb3BzLmVsZW1lbnQsXG4gICAgICBpbmRleDogZWxlbWVudC5wcm9wcy5pbmRleCxcbiAgICAgIHBhdGg6IGVsZW1lbnQucHJvcHMucGF0aCxcbiAgICB9O1xuXG4gICAgaWYgKGVsZW1lbnQucHJvcHMuY2hpbGRyZW4pIHtcbiAgICAgIHJvdXRlLmNoaWxkcmVuID0gY3JlYXRlUm91dGVzRnJvbUNoaWxkcmVuKGVsZW1lbnQucHJvcHMuY2hpbGRyZW4pO1xuICAgIH1cblxuICAgIHJvdXRlcy5wdXNoKHJvdXRlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJvdXRlcztcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSByZXN1bHQgb2YgYG1hdGNoUm91dGVzKClgIGludG8gYSBSZWFjdCBlbGVtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyTWF0Y2hlcyhcbiAgbWF0Y2hlczogUm91dGVNYXRjaFtdIHwgbnVsbFxuKTogUmVhY3QuUmVhY3RFbGVtZW50IHwgbnVsbCB7XG4gIHJldHVybiBfcmVuZGVyTWF0Y2hlcyhtYXRjaGVzKTtcbn1cbiIsICIvKipcbiAqIE5PVEU6IElmIHlvdSByZWZhY3RvciB0aGlzIHRvIHNwbGl0IHVwIHRoZSBtb2R1bGVzIGludG8gc2VwYXJhdGUgZmlsZXMsXG4gKiB5b3UnbGwgbmVlZCB0byB1cGRhdGUgdGhlIHJvbGx1cCBjb25maWcgZm9yIHJlYWN0LXJvdXRlci1kb20tdjUtY29tcGF0LlxuICovXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB0eXBlIHsgQnJvd3Nlckhpc3RvcnksIEhhc2hIaXN0b3J5LCBIaXN0b3J5IH0gZnJvbSBcImhpc3RvcnlcIjtcbmltcG9ydCB7IGNyZWF0ZUJyb3dzZXJIaXN0b3J5LCBjcmVhdGVIYXNoSGlzdG9yeSB9IGZyb20gXCJoaXN0b3J5XCI7XG5pbXBvcnQge1xuICBNZW1vcnlSb3V0ZXIsXG4gIE5hdmlnYXRlLFxuICBPdXRsZXQsXG4gIFJvdXRlLFxuICBSb3V0ZXIsXG4gIFJvdXRlcyxcbiAgY3JlYXRlUm91dGVzRnJvbUNoaWxkcmVuLFxuICBnZW5lcmF0ZVBhdGgsXG4gIG1hdGNoUm91dGVzLFxuICBtYXRjaFBhdGgsXG4gIGNyZWF0ZVBhdGgsXG4gIHBhcnNlUGF0aCxcbiAgcmVzb2x2ZVBhdGgsXG4gIHJlbmRlck1hdGNoZXMsXG4gIHVzZUhyZWYsXG4gIHVzZUluUm91dGVyQ29udGV4dCxcbiAgdXNlTG9jYXRpb24sXG4gIHVzZU1hdGNoLFxuICB1c2VOYXZpZ2F0ZSxcbiAgdXNlTmF2aWdhdGlvblR5cGUsXG4gIHVzZU91dGxldCxcbiAgdXNlUGFyYW1zLFxuICB1c2VSZXNvbHZlZFBhdGgsXG4gIHVzZVJvdXRlcyxcbiAgdXNlT3V0bGV0Q29udGV4dCxcbn0gZnJvbSBcInJlYWN0LXJvdXRlclwiO1xuaW1wb3J0IHR5cGUgeyBUbyB9IGZyb20gXCJyZWFjdC1yb3V0ZXJcIjtcblxuZnVuY3Rpb24gd2FybmluZyhjb25kOiBib29sZWFuLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKCFjb25kKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIpIGNvbnNvbGUud2FybihtZXNzYWdlKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBXZWxjb21lIHRvIGRlYnVnZ2luZyBSZWFjdCBSb3V0ZXIhXG4gICAgICAvL1xuICAgICAgLy8gVGhpcyBlcnJvciBpcyB0aHJvd24gYXMgYSBjb252ZW5pZW5jZSBzbyB5b3UgY2FuIG1vcmUgZWFzaWx5XG4gICAgICAvLyBmaW5kIHRoZSBzb3VyY2UgZm9yIGEgd2FybmluZyB0aGF0IGFwcGVhcnMgaW4gdGhlIGNvbnNvbGUgYnlcbiAgICAgIC8vIGVuYWJsaW5nIFwicGF1c2Ugb24gZXhjZXB0aW9uc1wiIGluIHlvdXIgSmF2YVNjcmlwdCBkZWJ1Z2dlci5cbiAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lbXB0eVxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFJFLUVYUE9SVFNcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8vIE5vdGU6IEtlZXAgaW4gc3luYyB3aXRoIHJlYWN0LXJvdXRlciBleHBvcnRzIVxuZXhwb3J0IHtcbiAgTWVtb3J5Um91dGVyLFxuICBOYXZpZ2F0ZSxcbiAgT3V0bGV0LFxuICBSb3V0ZSxcbiAgUm91dGVyLFxuICBSb3V0ZXMsXG4gIGNyZWF0ZVJvdXRlc0Zyb21DaGlsZHJlbixcbiAgZ2VuZXJhdGVQYXRoLFxuICBtYXRjaFJvdXRlcyxcbiAgbWF0Y2hQYXRoLFxuICBjcmVhdGVQYXRoLFxuICBwYXJzZVBhdGgsXG4gIHJlbmRlck1hdGNoZXMsXG4gIHJlc29sdmVQYXRoLFxuICB1c2VIcmVmLFxuICB1c2VJblJvdXRlckNvbnRleHQsXG4gIHVzZUxvY2F0aW9uLFxuICB1c2VNYXRjaCxcbiAgdXNlTmF2aWdhdGUsXG4gIHVzZU5hdmlnYXRpb25UeXBlLFxuICB1c2VPdXRsZXQsXG4gIHVzZVBhcmFtcyxcbiAgdXNlUmVzb2x2ZWRQYXRoLFxuICB1c2VSb3V0ZXMsXG4gIHVzZU91dGxldENvbnRleHQsXG59O1xuXG5leHBvcnQgeyBOYXZpZ2F0aW9uVHlwZSB9IGZyb20gXCJyZWFjdC1yb3V0ZXJcIjtcbmV4cG9ydCB0eXBlIHtcbiAgSGFzaCxcbiAgTG9jYXRpb24sXG4gIFBhdGgsXG4gIFRvLFxuICBNZW1vcnlSb3V0ZXJQcm9wcyxcbiAgTmF2aWdhdGVGdW5jdGlvbixcbiAgTmF2aWdhdGVPcHRpb25zLFxuICBOYXZpZ2F0ZVByb3BzLFxuICBOYXZpZ2F0b3IsXG4gIE91dGxldFByb3BzLFxuICBQYXJhbXMsXG4gIFBhdGhNYXRjaCxcbiAgUm91dGVNYXRjaCxcbiAgUm91dGVPYmplY3QsXG4gIFJvdXRlUHJvcHMsXG4gIFBhdGhSb3V0ZVByb3BzLFxuICBMYXlvdXRSb3V0ZVByb3BzLFxuICBJbmRleFJvdXRlUHJvcHMsXG4gIFJvdXRlclByb3BzLFxuICBQYXRobmFtZSxcbiAgU2VhcmNoLFxuICBSb3V0ZXNQcm9wcyxcbn0gZnJvbSBcInJlYWN0LXJvdXRlclwiO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBEQU5HRVIhIFBMRUFTRSBSRUFEIE1FIVxuLy8gV2UgcHJvdmlkZSB0aGVzZSBleHBvcnRzIGFzIGFuIGVzY2FwZSBoYXRjaCBpbiB0aGUgZXZlbnQgdGhhdCB5b3UgbmVlZCBhbnlcbi8vIHJvdXRpbmcgZGF0YSB0aGF0IHdlIGRvbid0IHByb3ZpZGUgYW4gZXhwbGljaXQgQVBJIGZvci4gV2l0aCB0aGF0IHNhaWQsIHdlXG4vLyB3YW50IHRvIGNvdmVyIHlvdXIgdXNlIGNhc2UgaWYgd2UgY2FuLCBzbyBpZiB5b3UgZmVlbCB0aGUgbmVlZCB0byB1c2UgdGhlc2Vcbi8vIHdlIHdhbnQgdG8gaGVhciBmcm9tIHlvdS4gTGV0IHVzIGtub3cgd2hhdCB5b3UncmUgYnVpbGRpbmcgYW5kIHdlJ2xsIGRvIG91clxuLy8gYmVzdCB0byBtYWtlIHN1cmUgd2UgY2FuIHN1cHBvcnQgeW91IVxuLy9cbi8vIFdlIGNvbnNpZGVyIHRoZXNlIGV4cG9ydHMgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsIGFuZCBkbyBub3QgZ3VhcmFudGVlXG4vLyBhZ2FpbnN0IGFueSBicmVha2luZyBjaGFuZ2VzLCByZWdhcmRsZXNzIG9mIHRoZSBzZW12ZXIgcmVsZWFzZS4gVXNlIHdpdGhcbi8vIGV4dHJlbWUgY2F1dGlvbiBhbmQgb25seSBpZiB5b3UgdW5kZXJzdGFuZCB0aGUgY29uc2VxdWVuY2VzLiBHb2RzcGVlZC5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IHtcbiAgVU5TQUZFX05hdmlnYXRpb25Db250ZXh0LFxuICBVTlNBRkVfTG9jYXRpb25Db250ZXh0LFxuICBVTlNBRkVfUm91dGVDb250ZXh0LFxufSBmcm9tIFwicmVhY3Qtcm91dGVyXCI7XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBDT01QT05FTlRTXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5leHBvcnQgaW50ZXJmYWNlIEJyb3dzZXJSb3V0ZXJQcm9wcyB7XG4gIGJhc2VuYW1lPzogc3RyaW5nO1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbiAgd2luZG93PzogV2luZG93O1xufVxuXG4vKipcbiAqIEEgYDxSb3V0ZXI+YCBmb3IgdXNlIGluIHdlYiBicm93c2Vycy4gUHJvdmlkZXMgdGhlIGNsZWFuZXN0IFVSTHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBCcm93c2VyUm91dGVyKHtcbiAgYmFzZW5hbWUsXG4gIGNoaWxkcmVuLFxuICB3aW5kb3csXG59OiBCcm93c2VyUm91dGVyUHJvcHMpIHtcbiAgbGV0IGhpc3RvcnlSZWYgPSBSZWFjdC51c2VSZWY8QnJvd3Nlckhpc3Rvcnk+KCk7XG4gIGlmIChoaXN0b3J5UmVmLmN1cnJlbnQgPT0gbnVsbCkge1xuICAgIGhpc3RvcnlSZWYuY3VycmVudCA9IGNyZWF0ZUJyb3dzZXJIaXN0b3J5KHsgd2luZG93IH0pO1xuICB9XG5cbiAgbGV0IGhpc3RvcnkgPSBoaXN0b3J5UmVmLmN1cnJlbnQ7XG4gIGxldCBbc3RhdGUsIHNldFN0YXRlXSA9IFJlYWN0LnVzZVN0YXRlKHtcbiAgICBhY3Rpb246IGhpc3RvcnkuYWN0aW9uLFxuICAgIGxvY2F0aW9uOiBoaXN0b3J5LmxvY2F0aW9uLFxuICB9KTtcblxuICBSZWFjdC51c2VMYXlvdXRFZmZlY3QoKCkgPT4gaGlzdG9yeS5saXN0ZW4oc2V0U3RhdGUpLCBbaGlzdG9yeV0pO1xuXG4gIHJldHVybiAoXG4gICAgPFJvdXRlclxuICAgICAgYmFzZW5hbWU9e2Jhc2VuYW1lfVxuICAgICAgY2hpbGRyZW49e2NoaWxkcmVufVxuICAgICAgbG9jYXRpb249e3N0YXRlLmxvY2F0aW9ufVxuICAgICAgbmF2aWdhdGlvblR5cGU9e3N0YXRlLmFjdGlvbn1cbiAgICAgIG5hdmlnYXRvcj17aGlzdG9yeX1cbiAgICAvPlxuICApO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhhc2hSb3V0ZXJQcm9wcyB7XG4gIGJhc2VuYW1lPzogc3RyaW5nO1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbiAgd2luZG93PzogV2luZG93O1xufVxuXG4vKipcbiAqIEEgYDxSb3V0ZXI+YCBmb3IgdXNlIGluIHdlYiBicm93c2Vycy4gU3RvcmVzIHRoZSBsb2NhdGlvbiBpbiB0aGUgaGFzaFxuICogcG9ydGlvbiBvZiB0aGUgVVJMIHNvIGl0IGlzIG5vdCBzZW50IHRvIHRoZSBzZXJ2ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBIYXNoUm91dGVyKHsgYmFzZW5hbWUsIGNoaWxkcmVuLCB3aW5kb3cgfTogSGFzaFJvdXRlclByb3BzKSB7XG4gIGxldCBoaXN0b3J5UmVmID0gUmVhY3QudXNlUmVmPEhhc2hIaXN0b3J5PigpO1xuICBpZiAoaGlzdG9yeVJlZi5jdXJyZW50ID09IG51bGwpIHtcbiAgICBoaXN0b3J5UmVmLmN1cnJlbnQgPSBjcmVhdGVIYXNoSGlzdG9yeSh7IHdpbmRvdyB9KTtcbiAgfVxuXG4gIGxldCBoaXN0b3J5ID0gaGlzdG9yeVJlZi5jdXJyZW50O1xuICBsZXQgW3N0YXRlLCBzZXRTdGF0ZV0gPSBSZWFjdC51c2VTdGF0ZSh7XG4gICAgYWN0aW9uOiBoaXN0b3J5LmFjdGlvbixcbiAgICBsb2NhdGlvbjogaGlzdG9yeS5sb2NhdGlvbixcbiAgfSk7XG5cbiAgUmVhY3QudXNlTGF5b3V0RWZmZWN0KCgpID0+IGhpc3RvcnkubGlzdGVuKHNldFN0YXRlKSwgW2hpc3RvcnldKTtcblxuICByZXR1cm4gKFxuICAgIDxSb3V0ZXJcbiAgICAgIGJhc2VuYW1lPXtiYXNlbmFtZX1cbiAgICAgIGNoaWxkcmVuPXtjaGlsZHJlbn1cbiAgICAgIGxvY2F0aW9uPXtzdGF0ZS5sb2NhdGlvbn1cbiAgICAgIG5hdmlnYXRpb25UeXBlPXtzdGF0ZS5hY3Rpb259XG4gICAgICBuYXZpZ2F0b3I9e2hpc3Rvcnl9XG4gICAgLz5cbiAgKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIaXN0b3J5Um91dGVyUHJvcHMge1xuICBiYXNlbmFtZT86IHN0cmluZztcbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGU7XG4gIGhpc3Rvcnk6IEhpc3Rvcnk7XG59XG5cbi8qKlxuICogQSBgPFJvdXRlcj5gIHRoYXQgYWNjZXB0cyBhIHByZS1pbnN0YW50aWF0ZWQgaGlzdG9yeSBvYmplY3QuIEl0J3MgaW1wb3J0YW50XG4gKiB0byBub3RlIHRoYXQgdXNpbmcgeW91ciBvd24gaGlzdG9yeSBvYmplY3QgaXMgaGlnaGx5IGRpc2NvdXJhZ2VkIGFuZCBtYXkgYWRkXG4gKiB0d28gdmVyc2lvbnMgb2YgdGhlIGhpc3RvcnkgbGlicmFyeSB0byB5b3VyIGJ1bmRsZXMgdW5sZXNzIHlvdSB1c2UgdGhlIHNhbWVcbiAqIHZlcnNpb24gb2YgdGhlIGhpc3RvcnkgbGlicmFyeSB0aGF0IFJlYWN0IFJvdXRlciB1c2VzIGludGVybmFsbHkuXG4gKi9cbmZ1bmN0aW9uIEhpc3RvcnlSb3V0ZXIoeyBiYXNlbmFtZSwgY2hpbGRyZW4sIGhpc3RvcnkgfTogSGlzdG9yeVJvdXRlclByb3BzKSB7XG4gIGNvbnN0IFtzdGF0ZSwgc2V0U3RhdGVdID0gUmVhY3QudXNlU3RhdGUoe1xuICAgIGFjdGlvbjogaGlzdG9yeS5hY3Rpb24sXG4gICAgbG9jYXRpb246IGhpc3RvcnkubG9jYXRpb24sXG4gIH0pO1xuXG4gIFJlYWN0LnVzZUxheW91dEVmZmVjdCgoKSA9PiBoaXN0b3J5Lmxpc3RlbihzZXRTdGF0ZSksIFtoaXN0b3J5XSk7XG5cbiAgcmV0dXJuIChcbiAgICA8Um91dGVyXG4gICAgICBiYXNlbmFtZT17YmFzZW5hbWV9XG4gICAgICBjaGlsZHJlbj17Y2hpbGRyZW59XG4gICAgICBsb2NhdGlvbj17c3RhdGUubG9jYXRpb259XG4gICAgICBuYXZpZ2F0aW9uVHlwZT17c3RhdGUuYWN0aW9ufVxuICAgICAgbmF2aWdhdG9yPXtoaXN0b3J5fVxuICAgIC8+XG4gICk7XG59XG5cbmlmIChfX0RFVl9fKSB7XG4gIEhpc3RvcnlSb3V0ZXIuZGlzcGxheU5hbWUgPSBcInVuc3RhYmxlX0hpc3RvcnlSb3V0ZXJcIjtcbn1cblxuZXhwb3J0IHsgSGlzdG9yeVJvdXRlciBhcyB1bnN0YWJsZV9IaXN0b3J5Um91dGVyIH07XG5cbmZ1bmN0aW9uIGlzTW9kaWZpZWRFdmVudChldmVudDogUmVhY3QuTW91c2VFdmVudCkge1xuICByZXR1cm4gISEoZXZlbnQubWV0YUtleSB8fCBldmVudC5hbHRLZXkgfHwgZXZlbnQuY3RybEtleSB8fCBldmVudC5zaGlmdEtleSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlua1Byb3BzXG4gIGV4dGVuZHMgT21pdDxSZWFjdC5BbmNob3JIVE1MQXR0cmlidXRlczxIVE1MQW5jaG9yRWxlbWVudD4sIFwiaHJlZlwiPiB7XG4gIHJlbG9hZERvY3VtZW50PzogYm9vbGVhbjtcbiAgcmVwbGFjZT86IGJvb2xlYW47XG4gIHN0YXRlPzogYW55O1xuICB0bzogVG87XG59XG5cbi8qKlxuICogVGhlIHB1YmxpYyBBUEkgZm9yIHJlbmRlcmluZyBhIGhpc3RvcnktYXdhcmUgPGE+LlxuICovXG5leHBvcnQgY29uc3QgTGluayA9IFJlYWN0LmZvcndhcmRSZWY8SFRNTEFuY2hvckVsZW1lbnQsIExpbmtQcm9wcz4oXG4gIGZ1bmN0aW9uIExpbmtXaXRoUmVmKFxuICAgIHsgb25DbGljaywgcmVsb2FkRG9jdW1lbnQsIHJlcGxhY2UgPSBmYWxzZSwgc3RhdGUsIHRhcmdldCwgdG8sIC4uLnJlc3QgfSxcbiAgICByZWZcbiAgKSB7XG4gICAgbGV0IGhyZWYgPSB1c2VIcmVmKHRvKTtcbiAgICBsZXQgaW50ZXJuYWxPbkNsaWNrID0gdXNlTGlua0NsaWNrSGFuZGxlcih0bywgeyByZXBsYWNlLCBzdGF0ZSwgdGFyZ2V0IH0pO1xuICAgIGZ1bmN0aW9uIGhhbmRsZUNsaWNrKFxuICAgICAgZXZlbnQ6IFJlYWN0Lk1vdXNlRXZlbnQ8SFRNTEFuY2hvckVsZW1lbnQsIE1vdXNlRXZlbnQ+XG4gICAgKSB7XG4gICAgICBpZiAob25DbGljaykgb25DbGljayhldmVudCk7XG4gICAgICBpZiAoIWV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgJiYgIXJlbG9hZERvY3VtZW50KSB7XG4gICAgICAgIGludGVybmFsT25DbGljayhldmVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc3gtYTExeS9hbmNob3ItaGFzLWNvbnRlbnRcbiAgICAgIDxhXG4gICAgICAgIHsuLi5yZXN0fVxuICAgICAgICBocmVmPXtocmVmfVxuICAgICAgICBvbkNsaWNrPXtoYW5kbGVDbGlja31cbiAgICAgICAgcmVmPXtyZWZ9XG4gICAgICAgIHRhcmdldD17dGFyZ2V0fVxuICAgICAgLz5cbiAgICApO1xuICB9XG4pO1xuXG5pZiAoX19ERVZfXykge1xuICBMaW5rLmRpc3BsYXlOYW1lID0gXCJMaW5rXCI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmF2TGlua1Byb3BzXG4gIGV4dGVuZHMgT21pdDxMaW5rUHJvcHMsIFwiY2xhc3NOYW1lXCIgfCBcInN0eWxlXCIgfCBcImNoaWxkcmVuXCI+IHtcbiAgY2hpbGRyZW4/OlxuICAgIHwgUmVhY3QuUmVhY3ROb2RlXG4gICAgfCAoKHByb3BzOiB7IGlzQWN0aXZlOiBib29sZWFuIH0pID0+IFJlYWN0LlJlYWN0Tm9kZSk7XG4gIGNhc2VTZW5zaXRpdmU/OiBib29sZWFuO1xuICBjbGFzc05hbWU/OiBzdHJpbmcgfCAoKHByb3BzOiB7IGlzQWN0aXZlOiBib29sZWFuIH0pID0+IHN0cmluZyB8IHVuZGVmaW5lZCk7XG4gIGVuZD86IGJvb2xlYW47XG4gIHN0eWxlPzpcbiAgICB8IFJlYWN0LkNTU1Byb3BlcnRpZXNcbiAgICB8ICgocHJvcHM6IHsgaXNBY3RpdmU6IGJvb2xlYW4gfSkgPT4gUmVhY3QuQ1NTUHJvcGVydGllcyk7XG59XG5cbi8qKlxuICogQSA8TGluaz4gd3JhcHBlciB0aGF0IGtub3dzIGlmIGl0J3MgXCJhY3RpdmVcIiBvciBub3QuXG4gKi9cbmV4cG9ydCBjb25zdCBOYXZMaW5rID0gUmVhY3QuZm9yd2FyZFJlZjxIVE1MQW5jaG9yRWxlbWVudCwgTmF2TGlua1Byb3BzPihcbiAgZnVuY3Rpb24gTmF2TGlua1dpdGhSZWYoXG4gICAge1xuICAgICAgXCJhcmlhLWN1cnJlbnRcIjogYXJpYUN1cnJlbnRQcm9wID0gXCJwYWdlXCIsXG4gICAgICBjYXNlU2Vuc2l0aXZlID0gZmFsc2UsXG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZVByb3AgPSBcIlwiLFxuICAgICAgZW5kID0gZmFsc2UsXG4gICAgICBzdHlsZTogc3R5bGVQcm9wLFxuICAgICAgdG8sXG4gICAgICBjaGlsZHJlbixcbiAgICAgIC4uLnJlc3RcbiAgICB9LFxuICAgIHJlZlxuICApIHtcbiAgICBsZXQgbG9jYXRpb24gPSB1c2VMb2NhdGlvbigpO1xuICAgIGxldCBwYXRoID0gdXNlUmVzb2x2ZWRQYXRoKHRvKTtcblxuICAgIGxldCBsb2NhdGlvblBhdGhuYW1lID0gbG9jYXRpb24ucGF0aG5hbWU7XG4gICAgbGV0IHRvUGF0aG5hbWUgPSBwYXRoLnBhdGhuYW1lO1xuICAgIGlmICghY2FzZVNlbnNpdGl2ZSkge1xuICAgICAgbG9jYXRpb25QYXRobmFtZSA9IGxvY2F0aW9uUGF0aG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIHRvUGF0aG5hbWUgPSB0b1BhdGhuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgbGV0IGlzQWN0aXZlID1cbiAgICAgIGxvY2F0aW9uUGF0aG5hbWUgPT09IHRvUGF0aG5hbWUgfHxcbiAgICAgICghZW5kICYmXG4gICAgICAgIGxvY2F0aW9uUGF0aG5hbWUuc3RhcnRzV2l0aCh0b1BhdGhuYW1lKSAmJlxuICAgICAgICBsb2NhdGlvblBhdGhuYW1lLmNoYXJBdCh0b1BhdGhuYW1lLmxlbmd0aCkgPT09IFwiL1wiKTtcblxuICAgIGxldCBhcmlhQ3VycmVudCA9IGlzQWN0aXZlID8gYXJpYUN1cnJlbnRQcm9wIDogdW5kZWZpbmVkO1xuXG4gICAgbGV0IGNsYXNzTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0eXBlb2YgY2xhc3NOYW1lUHJvcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBjbGFzc05hbWUgPSBjbGFzc05hbWVQcm9wKHsgaXNBY3RpdmUgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZSBjbGFzc05hbWUgcHJvcCBpcyBub3QgYSBmdW5jdGlvbiwgd2UgdXNlIGEgZGVmYXVsdCBgYWN0aXZlYFxuICAgICAgLy8gY2xhc3MgZm9yIDxOYXZMaW5rIC8+cyB0aGF0IGFyZSBhY3RpdmUuIEluIHY1IGBhY3RpdmVgIHdhcyB0aGUgZGVmYXVsdFxuICAgICAgLy8gdmFsdWUgZm9yIGBhY3RpdmVDbGFzc05hbWVgLCBidXQgd2UgYXJlIHJlbW92aW5nIHRoYXQgQVBJIGFuZCBjYW4gc3RpbGxcbiAgICAgIC8vIHVzZSB0aGUgb2xkIGRlZmF1bHQgYmVoYXZpb3IgZm9yIGEgY2xlYW5lciB1cGdyYWRlIHBhdGggYW5kIGtlZXAgdGhlXG4gICAgICAvLyBzaW1wbGUgc3R5bGluZyBydWxlcyB3b3JraW5nIGFzIHRoZXkgY3VycmVudGx5IGRvLlxuICAgICAgY2xhc3NOYW1lID0gW2NsYXNzTmFtZVByb3AsIGlzQWN0aXZlID8gXCJhY3RpdmVcIiA6IG51bGxdXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgLmpvaW4oXCIgXCIpO1xuICAgIH1cblxuICAgIGxldCBzdHlsZSA9XG4gICAgICB0eXBlb2Ygc3R5bGVQcm9wID09PSBcImZ1bmN0aW9uXCIgPyBzdHlsZVByb3AoeyBpc0FjdGl2ZSB9KSA6IHN0eWxlUHJvcDtcblxuICAgIHJldHVybiAoXG4gICAgICA8TGlua1xuICAgICAgICB7Li4ucmVzdH1cbiAgICAgICAgYXJpYS1jdXJyZW50PXthcmlhQ3VycmVudH1cbiAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWV9XG4gICAgICAgIHJlZj17cmVmfVxuICAgICAgICBzdHlsZT17c3R5bGV9XG4gICAgICAgIHRvPXt0b31cbiAgICAgID5cbiAgICAgICAge3R5cGVvZiBjaGlsZHJlbiA9PT0gXCJmdW5jdGlvblwiID8gY2hpbGRyZW4oeyBpc0FjdGl2ZSB9KSA6IGNoaWxkcmVufVxuICAgICAgPC9MaW5rPlxuICAgICk7XG4gIH1cbik7XG5cbmlmIChfX0RFVl9fKSB7XG4gIE5hdkxpbmsuZGlzcGxheU5hbWUgPSBcIk5hdkxpbmtcIjtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEhPT0tTXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIEhhbmRsZXMgdGhlIGNsaWNrIGJlaGF2aW9yIGZvciByb3V0ZXIgYDxMaW5rPmAgY29tcG9uZW50cy4gVGhpcyBpcyB1c2VmdWwgaWZcbiAqIHlvdSBuZWVkIHRvIGNyZWF0ZSBjdXN0b20gYDxMaW5rPmAgY29tcG9uZW50cyB3aXRoIHRoZSBzYW1lIGNsaWNrIGJlaGF2aW9yIHdlXG4gKiB1c2UgaW4gb3VyIGV4cG9ydGVkIGA8TGluaz5gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlTGlua0NsaWNrSGFuZGxlcjxFIGV4dGVuZHMgRWxlbWVudCA9IEhUTUxBbmNob3JFbGVtZW50PihcbiAgdG86IFRvLFxuICB7XG4gICAgdGFyZ2V0LFxuICAgIHJlcGxhY2U6IHJlcGxhY2VQcm9wLFxuICAgIHN0YXRlLFxuICB9OiB7XG4gICAgdGFyZ2V0PzogUmVhY3QuSFRNTEF0dHJpYnV0ZUFuY2hvclRhcmdldDtcbiAgICByZXBsYWNlPzogYm9vbGVhbjtcbiAgICBzdGF0ZT86IGFueTtcbiAgfSA9IHt9XG4pOiAoZXZlbnQ6IFJlYWN0Lk1vdXNlRXZlbnQ8RSwgTW91c2VFdmVudD4pID0+IHZvaWQge1xuICBsZXQgbmF2aWdhdGUgPSB1c2VOYXZpZ2F0ZSgpO1xuICBsZXQgbG9jYXRpb24gPSB1c2VMb2NhdGlvbigpO1xuICBsZXQgcGF0aCA9IHVzZVJlc29sdmVkUGF0aCh0byk7XG5cbiAgcmV0dXJuIFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgIChldmVudDogUmVhY3QuTW91c2VFdmVudDxFLCBNb3VzZUV2ZW50PikgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBldmVudC5idXR0b24gPT09IDAgJiYgLy8gSWdub3JlIGV2ZXJ5dGhpbmcgYnV0IGxlZnQgY2xpY2tzXG4gICAgICAgICghdGFyZ2V0IHx8IHRhcmdldCA9PT0gXCJfc2VsZlwiKSAmJiAvLyBMZXQgYnJvd3NlciBoYW5kbGUgXCJ0YXJnZXQ9X2JsYW5rXCIgZXRjLlxuICAgICAgICAhaXNNb2RpZmllZEV2ZW50KGV2ZW50KSAvLyBJZ25vcmUgY2xpY2tzIHdpdGggbW9kaWZpZXIga2V5c1xuICAgICAgKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgLy8gSWYgdGhlIFVSTCBoYXNuJ3QgY2hhbmdlZCwgYSByZWd1bGFyIDxhPiB3aWxsIGRvIGEgcmVwbGFjZSBpbnN0ZWFkIG9mXG4gICAgICAgIC8vIGEgcHVzaCwgc28gZG8gdGhlIHNhbWUgaGVyZS5cbiAgICAgICAgbGV0IHJlcGxhY2UgPVxuICAgICAgICAgICEhcmVwbGFjZVByb3AgfHwgY3JlYXRlUGF0aChsb2NhdGlvbikgPT09IGNyZWF0ZVBhdGgocGF0aCk7XG5cbiAgICAgICAgbmF2aWdhdGUodG8sIHsgcmVwbGFjZSwgc3RhdGUgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbbG9jYXRpb24sIG5hdmlnYXRlLCBwYXRoLCByZXBsYWNlUHJvcCwgc3RhdGUsIHRhcmdldCwgdG9dXG4gICk7XG59XG5cbi8qKlxuICogQSBjb252ZW5pZW50IHdyYXBwZXIgZm9yIHJlYWRpbmcgYW5kIHdyaXRpbmcgc2VhcmNoIHBhcmFtZXRlcnMgdmlhIHRoZVxuICogVVJMU2VhcmNoUGFyYW1zIGludGVyZmFjZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVNlYXJjaFBhcmFtcyhkZWZhdWx0SW5pdD86IFVSTFNlYXJjaFBhcmFtc0luaXQpIHtcbiAgd2FybmluZyhcbiAgICB0eXBlb2YgVVJMU2VhcmNoUGFyYW1zICE9PSBcInVuZGVmaW5lZFwiLFxuICAgIGBZb3UgY2Fubm90IHVzZSB0aGUgXFxgdXNlU2VhcmNoUGFyYW1zXFxgIGhvb2sgaW4gYSBicm93c2VyIHRoYXQgZG9lcyBub3QgYCArXG4gICAgICBgc3VwcG9ydCB0aGUgVVJMU2VhcmNoUGFyYW1zIEFQSS4gSWYgeW91IG5lZWQgdG8gc3VwcG9ydCBJbnRlcm5ldCBgICtcbiAgICAgIGBFeHBsb3JlciAxMSwgd2UgcmVjb21tZW5kIHlvdSBsb2FkIGEgcG9seWZpbGwgc3VjaCBhcyBgICtcbiAgICAgIGBodHRwczovL2dpdGh1Yi5jb20vdW5nYXAvdXJsLXNlYXJjaC1wYXJhbXNcXG5cXG5gICtcbiAgICAgIGBJZiB5b3UncmUgdW5zdXJlIGhvdyB0byBsb2FkIHBvbHlmaWxscywgd2UgcmVjb21tZW5kIHlvdSBjaGVjayBvdXQgYCArXG4gICAgICBgaHR0cHM6Ly9wb2x5ZmlsbC5pby92My8gd2hpY2ggcHJvdmlkZXMgc29tZSByZWNvbW1lbmRhdGlvbnMgYWJvdXQgaG93IGAgK1xuICAgICAgYHRvIGxvYWQgcG9seWZpbGxzIG9ubHkgZm9yIHVzZXJzIHRoYXQgbmVlZCB0aGVtLCBpbnN0ZWFkIG9mIGZvciBldmVyeSBgICtcbiAgICAgIGB1c2VyLmBcbiAgKTtcblxuICBsZXQgZGVmYXVsdFNlYXJjaFBhcmFtc1JlZiA9IFJlYWN0LnVzZVJlZihjcmVhdGVTZWFyY2hQYXJhbXMoZGVmYXVsdEluaXQpKTtcblxuICBsZXQgbG9jYXRpb24gPSB1c2VMb2NhdGlvbigpO1xuICBsZXQgc2VhcmNoUGFyYW1zID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgbGV0IHNlYXJjaFBhcmFtcyA9IGNyZWF0ZVNlYXJjaFBhcmFtcyhsb2NhdGlvbi5zZWFyY2gpO1xuXG4gICAgZm9yIChsZXQga2V5IG9mIGRlZmF1bHRTZWFyY2hQYXJhbXNSZWYuY3VycmVudC5rZXlzKCkpIHtcbiAgICAgIGlmICghc2VhcmNoUGFyYW1zLmhhcyhrZXkpKSB7XG4gICAgICAgIGRlZmF1bHRTZWFyY2hQYXJhbXNSZWYuY3VycmVudC5nZXRBbGwoa2V5KS5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHNlYXJjaFBhcmFtcy5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzZWFyY2hQYXJhbXM7XG4gIH0sIFtsb2NhdGlvbi5zZWFyY2hdKTtcblxuICBsZXQgbmF2aWdhdGUgPSB1c2VOYXZpZ2F0ZSgpO1xuICBsZXQgc2V0U2VhcmNoUGFyYW1zID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKFxuICAgICAgbmV4dEluaXQ6IFVSTFNlYXJjaFBhcmFtc0luaXQsXG4gICAgICBuYXZpZ2F0ZU9wdGlvbnM/OiB7IHJlcGxhY2U/OiBib29sZWFuOyBzdGF0ZT86IGFueSB9XG4gICAgKSA9PiB7XG4gICAgICBuYXZpZ2F0ZShcIj9cIiArIGNyZWF0ZVNlYXJjaFBhcmFtcyhuZXh0SW5pdCksIG5hdmlnYXRlT3B0aW9ucyk7XG4gICAgfSxcbiAgICBbbmF2aWdhdGVdXG4gICk7XG5cbiAgcmV0dXJuIFtzZWFyY2hQYXJhbXMsIHNldFNlYXJjaFBhcmFtc10gYXMgY29uc3Q7XG59XG5cbmV4cG9ydCB0eXBlIFBhcmFtS2V5VmFsdWVQYWlyID0gW3N0cmluZywgc3RyaW5nXTtcblxuZXhwb3J0IHR5cGUgVVJMU2VhcmNoUGFyYW1zSW5pdCA9XG4gIHwgc3RyaW5nXG4gIHwgUGFyYW1LZXlWYWx1ZVBhaXJbXVxuICB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdPlxuICB8IFVSTFNlYXJjaFBhcmFtcztcblxuLyoqXG4gKiBDcmVhdGVzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdCB1c2luZyB0aGUgZ2l2ZW4gaW5pdGlhbGl6ZXIuXG4gKlxuICogVGhpcyBpcyBpZGVudGljYWwgdG8gYG5ldyBVUkxTZWFyY2hQYXJhbXMoaW5pdClgIGV4Y2VwdCBpdCBhbHNvXG4gKiBzdXBwb3J0cyBhcnJheXMgYXMgdmFsdWVzIGluIHRoZSBvYmplY3QgZm9ybSBvZiB0aGUgaW5pdGlhbGl6ZXJcbiAqIGluc3RlYWQgb2YganVzdCBzdHJpbmdzLiBUaGlzIGlzIGNvbnZlbmllbnQgd2hlbiB5b3UgbmVlZCBtdWx0aXBsZVxuICogdmFsdWVzIGZvciBhIGdpdmVuIGtleSwgYnV0IGRvbid0IHdhbnQgdG8gdXNlIGFuIGFycmF5IGluaXRpYWxpemVyLlxuICpcbiAqIEZvciBleGFtcGxlLCBpbnN0ZWFkIG9mOlxuICpcbiAqICAgbGV0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoW1xuICogICAgIFsnc29ydCcsICduYW1lJ10sXG4gKiAgICAgWydzb3J0JywgJ3ByaWNlJ11cbiAqICAgXSk7XG4gKlxuICogeW91IGNhbiBkbzpcbiAqXG4gKiAgIGxldCBzZWFyY2hQYXJhbXMgPSBjcmVhdGVTZWFyY2hQYXJhbXMoe1xuICogICAgIHNvcnQ6IFsnbmFtZScsICdwcmljZSddXG4gKiAgIH0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2VhcmNoUGFyYW1zKFxuICBpbml0OiBVUkxTZWFyY2hQYXJhbXNJbml0ID0gXCJcIlxuKTogVVJMU2VhcmNoUGFyYW1zIHtcbiAgcmV0dXJuIG5ldyBVUkxTZWFyY2hQYXJhbXMoXG4gICAgdHlwZW9mIGluaXQgPT09IFwic3RyaW5nXCIgfHxcbiAgICBBcnJheS5pc0FycmF5KGluaXQpIHx8XG4gICAgaW5pdCBpbnN0YW5jZW9mIFVSTFNlYXJjaFBhcmFtc1xuICAgICAgPyBpbml0XG4gICAgICA6IE9iamVjdC5rZXlzKGluaXQpLnJlZHVjZSgobWVtbywga2V5KSA9PiB7XG4gICAgICAgICAgbGV0IHZhbHVlID0gaW5pdFtrZXldO1xuICAgICAgICAgIHJldHVybiBtZW1vLmNvbmNhdChcbiAgICAgICAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKCh2KSA9PiBba2V5LCB2XSkgOiBbW2tleSwgdmFsdWVdXVxuICAgICAgICAgICk7XG4gICAgICAgIH0sIFtdIGFzIFBhcmFtS2V5VmFsdWVQYWlyW10pXG4gICk7XG59XG4iLCAiaW1wb3J0IFJlYWN0LCB7IHVzZVN0YXRlLCB1c2VFZmZlY3QgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IExpbmssIHVzZU5hdmlnYXRlIH0gZnJvbSBcInJlYWN0LXJvdXRlci1kb21cIjtcblxuY29uc3QgSG9tZSA9IChwcm9wcykgPT4ge1xuICAgIC8vIFRoZSByYW5kb21seSBnZW5lcmF0ZWQgVVJMIGlzIGEgc2lkZSBlZmZlY3QgYW5kIGFzIHN1Y2gsIHdlJ2xsIG5lZWRcbiAgICAvLyB0byBnZW5lcmF0ZSBpdCBpbiBhIHVzZUVmZmVjdCBob29rIGFuZCB1cGRhdGUgdGhpcyBzdGF0ZSB0byBoYXZlIGl0XG4gICAgLy8gcHJvcGVybHkgcmVuZGVyZWQgaW4gb3VyIGNvbXBvbmVudFxuICAgIGNvbnN0IFtyYW5kb21VUkwsIHNldFJhbmRvbVVSTF0gPSB1c2VTdGF0ZShudWxsKTtcblxuICAgIC8vIFVzZWQgdG8gcHJvZ3JhbWF0aWNhbGx5IG5hdmlnYXRlIHdpdGggUmVhY3QgUm91dGVyXG4gICAgY29uc3QgbmF2aWdhdGUgPSB1c2VOYXZpZ2F0ZSgpO1xuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgLyogSWYgdGhlIHVzZXIgbmF2aWdhdGVzIHRvIFwiLz91PVtpZF1cIiwgdGhleSBzaG91bGQgYmUgcm91dGVkIHRvXG4gICAgICAgICAqIHRoZSBCb29rbWFya3MgcGFnZS4gV2UgZG8gdGhpcyBiZWNhdXNlIHRoaXMgaXMgYSBzaW5nbGUtcGFnZVxuICAgICAgICAgKiBhcHAgYW5kIGlmIHRoZSB1c2VyIHRyaWVzIHRvIGFjY2VzcyAvdS9baWRdIGRpcmVjdGx5LCB0aGV5J2xsXG4gICAgICAgICAqIGdldCBhIDQwNCByZXBvbnNlLlxuICAgICAgICAgKi9cblxuICAgICAgICAvLyBBY2Nlc3MgdGhlIHF1ZXJ5IHBhcmFtZXRlcnNcbiAgICAgICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcbiAgICAgICAgY29uc3QgaWQgPSBwYXJhbXMuZ2V0KFwidVwiKTtcblxuICAgICAgICBpZiAoaWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gTmF2aWdhdGUgdG8gdGhlIHJlc3BlY3RpdmUgcGFnZVxuICAgICAgICAgICAgbmF2aWdhdGUoXCIvdS9cIiArIGlkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdlbmVyYXRlIHRoZSByYW5kb20gSURcbiAgICAgICAgY29uc3QgcmFuZG9tSUQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwMDAwKTtcblxuICAgICAgICAvLyBTdG9yZSB0aGUgZnVsbCByYW5kb20gVVJMIHNvIGl0IGNhbiBiZSBuYXZpZ2F0ZWQgdG9cbiAgICAgICAgc2V0UmFuZG9tVVJMKFwiL3UvXCIgKyByYW5kb21JRCk7XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPGRpdiBjbGFzc05hbWUgPSBcIm1haW4tY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8aDE+IFdlbGNvbWUgdG8gQ2F0IEJvb2ttYXJrZXIgPC9oMT5cbiAgICAgICAgICAgIDxwPlxuICAgICAgICAgICAgICAgIENhdCBCb29rbWFya2VyIGlzIGEgdG9vbCB0aGF0IHNlcnZlcyByYW5kb20gY2F0IGltYWdlcyBmcm9tXG4gICAgICAgICAgICAgICAgdGhlIDxhIGhyZWY9XCJodHRwczovL2NhdGFhcy5jb21cIj5DYXRhYXM8L2E+IChDYXQgQXMgQSBTZXJ2aWNlKVxuICAgICAgICAgICAgICAgIEFQSSBhbmQgaW52aXRlcyB5b3UgdG8gYm9va21hcmsgdGhlIG9uZXMgeW91IGxpa2Ugc28gdGhhdCB5b3VcbiAgICAgICAgICAgICAgICBjYW4gY29tZSBiYWNrIHRvIHRoZW0gbGF0ZXIuIFlvdSBjYW4gY2F0ZWdvcml6ZSB5b3VyIGNhdCBwaG90b3NcbiAgICAgICAgICAgICAgICB3aXRoIHVzZXItZ2VuZXJhdGVkIHRhZ3MgYW5kIHlvdSBjYW4gbGVhdmUgYSBub3RlIHRvIHJlbWluZFxuICAgICAgICAgICAgICAgIHlvdXJzZWxmIHdoeSB5b3UgbGlrZWQgdGhlIGNhdCBzbyBtdWNoIGluIHRoZSBmaXJzdCBwbGFjZS5cbiAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgQ2F0IEJvb2ttYXJrZXIgZmVhdHVyZXMgYSB2ZXJ5IHJ1ZGltZW50YXJ5IHVzZXIgYXV0aGVudGljYXRpb25cbiAgICAgICAgICAgICAgICBzeXN0ZW0gdXNpbmcgcmFuZG9tbHkgZ2VuZXJhdGVkIHVzZXIgSURzIGFuZCBIVFRQIEF1dGhvcml6YXRpb25cbiAgICAgICAgICAgICAgICBoZWFkZXJzLiBFdmVyeSBudW1iZXIgdGhhdCB3b24ndCBjYXVzZSBhbiBpbnRlZ2VyIG92ZXJmbG93IGlzXG4gICAgICAgICAgICAgICAgYSB2YWxpZCB1c2VyIHRoYXQgaGFzIGl0cyBvd24gYm9va21hcmtzIGFuZCBjYXRlZ29yaWVzLlxuICAgICAgICAgICAgPC9wPlxuXG4gICAgICAgICAgICB7IC8qIE9ubHkgcmVuZGVyIHRoZSBuZXcgVVJMIG9uY2UgaXQncyBnZW5lcmF0ZWQgKi8gfVxuICAgICAgICAgICAgeyByYW5kb21VUkwgIT0gbnVsbFxuICAgICAgICAgICAgICAgID8gPHA+XG4gICAgICAgICAgICAgICAgICAgIERvbid0IGFscmVhZHkgaGF2ZSBhbiBhY2NvdW50PyBUcnk6PGJyLz5cbiAgICAgICAgICAgICAgICAgICAgPExpbmsgdG89e3JhbmRvbVVSTH0+e3JhbmRvbVVSTH08L0xpbms+XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgIDogPD48Lz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEhvbWU7XG4iLCAiaW1wb3J0IFJlYWN0LCB7IHVzZVN0YXRlLCB1c2VFZmZlY3QgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHVzZVBhcmFtcyB9IGZyb20gXCJyZWFjdC1yb3V0ZXItZG9tXCI7XG5cbmNvbnN0IGNhdGFhcyA9IChlbmRwb2ludCkgPT4gXCJodHRwczovL2NhdGFhcy5jb21cIiArIGVuZHBvaW50O1xuY29uc3QgYm9va21hcmtlciA9IChlbmRwb2ludCkgPT4gXCJodHRwOi8vbG9jYWxob3N0OjQwMDAvYXBpL3YxXCIgKyBlbmRwb2ludDtcblxuY29uc3QgQm9va21hcmtzID0gKHByb3BzKSA9PiB7XG4gICAgLy8gVGhpcyBnaXZlcyB1cyBhY2Nlc3MgdG8gdGhlIDppZCBpbiAvdS86aWRcbiAgICBjb25zdCB7IGlkIH0gPSB1c2VQYXJhbXMoKTtcblxuICAgIC8vIEZvciBzdGFuZGFyZCBoZWFkZXJzIGluIGFsbCBCb29rbWFya2VyIHJlcXVlc3RzXG4gICAgY29uc3QgaGVhZGVycyA9IHtcbiAgICAgICAgXCJBdXRob3JpemF0aW9uXCI6IFwiQmFzaWMgXCIgKyBpZCxcbiAgICB9O1xuXG4gICAgLy8gVGhlIG9iamVjdCBkZXNjcmliaW5nIHRoZSByYW5kb21seSBmZXRjaGVkIGNhdCBpbWFnZVxuICAgIGNvbnN0IFtyYW5kb21DYXQsIHNldFJhbmRvbUNhdF0gPSB1c2VTdGF0ZShudWxsKTtcblxuICAgIC8vIFRoZSBzdGF0ZSBvZiB0aGUgQ3JlYXRlTmV3Qm9va21hcmsgZm9ybVxuICAgIGNvbnN0IFtmb3JtU3RhdGUsIHNldEZvcm1TdGF0ZV0gPSB1c2VTdGF0ZSh7XG4gICAgICAgIGNhdGVnb3J5OiBcIlwiLFxuICAgICAgICBub3RlczogXCJcIixcbiAgICB9KTtcblxuICAgIC8vIFRoZSBsaXN0IG9mIGFsbCBjYXRlZ29yaWVzIHRoYXQgZXhpc3QgaW4gdGhlIGRhdGFiYXNlXG4gICAgY29uc3QgW2NhdGVnb3JpZXMsIHNldENhdGVnb3JpZXNdID0gdXNlU3RhdGUoW10pO1xuXG4gICAgLy8gVGhlIGNvbGxlY3Rpb24gb2Ygd2hpY2ggcG9zdHMgYXJlIGJlaW5nIHNob3duXG4gICAgY29uc3QgW2FjdGl2ZUNhdGVnb3J5LCBzZXRBY3RpdmVDYXRlZ29yeV0gPSB1c2VTdGF0ZShudWxsKTtcbiAgICBjb25zdCBbY2F0ZWdvcnlDb2xsZWN0aW9uLCBzZXRDYXRlZ29yeUNvbGxlY3Rpb25dID0gdXNlU3RhdGUoW10pO1xuXG4gICAgLy8gVGhpcyBnZXRzIHJ1biBvbmNlIGFuZCB0aGVuIG5ldmVyIGFnYWluLCBkb2luZyBpbml0aWFsIHNldHVwIGZvciBvdXJcbiAgICAvLyBjb21wb25lbnRcbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICAvLyBGZXRjaCBhbmQgcmVuZGVyIGEgcmFuZG9tIGNhdCBwaWN0dXJlXG4gICAgICAgIHNob3dOZXdDYXQoKTtcblxuICAgICAgICAvLyBGZXRjaCB0aGUgbGlzdCBvZiBjYXRlZ29yaWVzIHdpdGggbW9yZSB0aGFuIG9uZSBib29rbWFya1xuICAgICAgICBnZXRBbGxDYXRlZ29yaWVzKCk7XG4gICAgfSwgW10pO1xuXG4gICAgLy8gV2hlbiB0aGUgYWN0aXZlIGNvbGxlY3Rpb24gaXMgY2hhbmdlZCwgZG8gdGhpc1xuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGJlIHJ1biBpZiBhbiBhY3RpdmVDYXRlZ29yeSBoYXMgYmVlbiBzZWxlY3RlZFxuICAgICAgICAgICAgaWYgKGFjdGl2ZUNhdGVnb3J5ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXEgPSBhd2FpdCBmZXRjaChcbiAgICAgICAgICAgICAgICAgICAgYm9va21hcmtlcihcIi9ib29rbWFyay9jYXRlZ29yeS9cIiArIGFjdGl2ZUNhdGVnb3J5KSxcbiAgICAgICAgICAgICAgICAgICAgeyBoZWFkZXJzIH1cbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBzdGF0ZSB3aXRoIHRoZSByZXN1bHRhbnQgSlNPTiBvYmplY3RcbiAgICAgICAgICAgICAgICBzZXRDYXRlZ29yeUNvbGxlY3Rpb24oYXdhaXQgcmVxLmpzb24oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG4gICAgfSwgW2FjdGl2ZUNhdGVnb3J5XSk7XG5cbiAgICBjb25zdCBzaG93TmV3Q2F0ID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBGaXJzdCwgcmVzZXQgdGhlIGNhdCBwaWN0dXJlLiBUaGlzIHdpbGwgYnJpZWZseSByZXJlbmRlciB0aGVcbiAgICAgICAgLy8gcGFyYWdyYXBoIHNheWluZyB0aGF0IHRoZSBpbWFnZSBpcyBsb2FkaW5nXG4gICAgICAgIHNldFJhbmRvbUNhdChudWxsKTtcblxuICAgICAgICBjb25zdCByZXEgPSBhd2FpdCBmZXRjaChjYXRhYXMoXCIvY2F0P2pzb249dHJ1ZVwiKSk7XG4gICAgICAgIHNldFJhbmRvbUNhdChhd2FpdCByZXEuanNvbigpKTtcbiAgICB9O1xuXG4gICAgY29uc3QgZ2V0QWxsQ2F0ZWdvcmllcyA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVxID0gYXdhaXQgZmV0Y2goXG4gICAgICAgICAgICBib29rbWFya2VyKFwiL2Jvb2ttYXJrL2NhdGVnb3JpZXNcIiksIHsgaGVhZGVycyB9KTtcbiAgICAgICAgc2V0Q2F0ZWdvcmllcyhhd2FpdCByZXEuanNvbigpKTtcbiAgICB9O1xuXG4gICAgY29uc3QgY2hvb3NlQ2F0ZWdvcnkgPSAoY2F0ZWdvcnkpID0+IHtcbiAgICAgICAgc2V0QWN0aXZlQ2F0ZWdvcnkoY2F0ZWdvcnkpO1xuICAgIH1cblxuICAgIGNvbnN0IGJvb2ttYXJrQ2F0ID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXEgPSBhd2FpdCBmZXRjaChib29rbWFya2VyKFwiL2Jvb2ttYXJrXCIpLCB7XG4gICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgaGVhZGVyczogey4uLmhlYWRlcnMsXG4gICAgICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IC4uLmZvcm1TdGF0ZSwgcmVtb3RlX2lkOiByYW5kb21DYXQuaWQgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVXBkYXRlIHRoZSBjYXRlZ29yeSBsaXN0IGluIGNhc2UgYSBuZXcgb25lIHdhcyBhZGRlZFxuICAgICAgICBhd2FpdCBnZXRBbGxDYXRlZ29yaWVzKCk7XG5cbiAgICAgICAgLy8gUmVzZXQgdGhlIGZvcm0gZmllbGRzXG4gICAgICAgIHNldEZvcm1TdGF0ZSh7XG4gICAgICAgICAgICBjYXRlZ29yeTogXCJcIixcbiAgICAgICAgICAgIG5vdGVzOiBcIlwiLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTaG93IGEgbmV3IGNhdFxuICAgICAgICBhd2FpdCBzaG93TmV3Q2F0KCk7XG4gICAgfTtcblxuICAgIGNvbnN0IHJlbW92ZUJvb2ttYXJrID0gYXN5bmMgKGlkKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlcSA9IGF3YWl0IGZldGNoKGJvb2ttYXJrZXIoXCIvYm9va21hcmsvXCIgKyBpZCksIHtcbiAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgICBtZXRob2Q6IFwiREVMRVRFXCIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZpbHRlciBvdXQgdGhlIGRlbGV0ZWQgYm9va21hcmsgYW5kIHRoZW4gcmVsb2FkIHRoZSBjb21wb25lbnRcbiAgICAgICAgc2V0Q2F0ZWdvcnlDb2xsZWN0aW9uKGNhdGVnb3J5Q29sbGVjdGlvbi5maWx0ZXIoYyA9PiBjLmlkICE9IGlkKSk7XG4gICAgfTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lID0gXCJtYWluLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPGgyIGNsYXNzTmFtZSA9IFwiY2VudGVyLXRleHRcIj4gUmFuZG9tIENhdCA8L2gyPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8aW1nIGNsYXNzTmFtZSA9IFwicmFuZG9tLWltYWdlIGNlbnRlci1ib3gtaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICBzcmMgPSB7IHJhbmRvbUNhdCAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGNhdGFhcyhyYW5kb21DYXQudXJsKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYWx0ID0geyByYW5kb21DYXQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgICAgPyByYW5kb21DYXQudGFncy5qb2luKFwiIFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBcIkxvYWRpbmcgY2F0Li4uXCJcbiAgICAgICAgICAgICAgICAgICAgfSAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lID0gXCJjZW50ZXItdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG9uQ2xpY2sgPSB7IHNob3dOZXdDYXQgfT5cbiAgICAgICAgICAgICAgICAgICAgICAgIFNob3cgTmV3IENhdFxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWUgPSBcImZvcm0tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZSA9IFwiY2VudGVyLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgTGlrZSB0aGlzIGNhdD8gQm9va21hcmsgdGhlbS5cbiAgICAgICAgICAgICAgICA8L2gzPlxuICAgICAgICAgICAgICAgIDxOZXdCb29rbWFya0Zvcm1cbiAgICAgICAgICAgICAgICAgICAgc3VibWl0Q2FsbGJhY2sgPSB7IGJvb2ttYXJrQ2F0IH1cbiAgICAgICAgICAgICAgICAgICAgc2V0dGVyID0geyBzZXRGb3JtU3RhdGUgfVxuICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IHsgZm9ybVN0YXRlIH0vPlxuICAgICAgICAgICAgPC9kaXY+IFxuICAgICAgICAgICAgPGgyPiBCcm93c2UgeW91ciBjb2xsZWN0aW9ucyA8L2gyPlxuICAgICAgICAgICAgPFNlbGVjdENhdGVnb3J5XG4gICAgICAgICAgICAgICAgY2F0ZWdvcmllcyA9IHsgY2F0ZWdvcmllcyB9XG4gICAgICAgICAgICAgICAgYWN0aXZlQ2F0ZWdvcnkgPSB7IGFjdGl2ZUNhdGVnb3J5IH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHsgY2hvb3NlQ2F0ZWdvcnkgfS8+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlID0ge3sgaGVpZ2h0OiA1MCB9fT48L2Rpdj5cbiAgICAgICAgICAgIHsgYWN0aXZlQ2F0ZWdvcnkgIT0gbnVsbCAmJiBjYXRlZ29yeUNvbGxlY3Rpb24ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gPEJvb2ttYXJrQ29sbGVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZW1vdmVDYWxsYmFjayA9IHsgcmVtb3ZlQm9va21hcmsgfVxuICAgICAgICAgICAgICAgICAgICBib29rbWFya3MgPSB7IGNhdGVnb3J5Q29sbGVjdGlvbiB9IC8+XG4gICAgICAgICAgICAgICAgOiA8PjwvPlxuICAgICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICApO1xufTtcblxuLy8gQSByZXVzYWJsZSBmb3JtIGNvbXBvbmVudCB0aGF0IHRha2VzIGEgbGlzdCBvZiBvYmplY3RzIHJlcHJlc2VudGluZ1xuLy8gaW5wdXQgcHJvcGVydGllcyBhbmQgdGhlbiByZW5kZXJzIHRoZW0gZHluYW1pY2FsbHlcbmNvbnN0IEZvcm0gPSAocHJvcHMpID0+IHtcbiAgICBjb25zdCB1cGRhdGVyRmFjdG9yeSA9IChrZXkpID0+IChlKSA9PiBwcm9wcy5zZXR0ZXIoe1xuICAgICAgICAuLi5wcm9wcy5zdGF0ZSxcbiAgICAgICAgW2tleV06IGUudGFyZ2V0LnZhbHVlLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPGZvcm0gb25TdWJtaXQ9eyBlID0+IGUucHJldmVudERlZmF1bHQoKSB9PlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb3BzLmlucHV0cy5tYXAoKGRhdGEsIGkpID0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYga2V5ID0geyBpIH0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWUgPSBcImZvcm0tbGFiZWxcIj4geyBkYXRhLmxhYmVsIH0gPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXIgPSB7IGRhdGEucGxhY2Vob2xkZXIgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0geyBwcm9wcy5zdGF0ZVtkYXRhLm5hbWVdIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZSA9IHsgdXBkYXRlckZhY3RvcnkoZGF0YS5uYW1lKSB9Lz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWUgPSBcImNlbnRlci10ZXh0XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWUgPSBcImZvcm0tc3VibWl0LWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrID0geyBwcm9wcy5zdWJtaXRDYWxsYmFjayB9PlxuICAgICAgICAgICAgICAgICAgICBTdWJtaXRcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvcm0+XG4gICAgKTtcbn07XG5cbi8vIFJlbmRlcnMgdGhlIEZvcm0gY29tcG9uZW50IGZvciBvdXIgc3BlY2lmaWMgbmVlZHMgaW4gdGhlIGNhc2Ugb2YgYm9va21hcmtpbmdcbi8vIGEgY2F0IHBob3RvXG5jb25zdCBOZXdCb29rbWFya0Zvcm0gPSAocHJvcHMpID0+IChcbiAgICA8Rm9ybVxuICAgICAgICB7IC4uLnByb3BzIH1cbiAgICAgICAgaW5wdXRzID0ge1tcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcImNhdGVnb3J5XCIsXG4gICAgICAgICAgICAgICAgbGFiZWw6IFwiQ2F0ZWdvcnkgbmFtZVwiLFxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiBcIiBTb21ldGhpbmcgcmVhbGx5IGNvb2wuLi5cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgbmFtZTogXCJub3Rlc1wiLCBsYWJlbDogXCJOb3Rlc1wiLCBwbGFjZWhvbGRlcjogXCJBbnkgb3RoZXIgbm90ZXNcIiB9XG4gICAgICAgIF19Lz5cbik7XG5cbi8vIFJlbmRlcnMgYSBsaXN0IG9mIGJ1dHRvbnMsIGVhY2ggcmVwcmVzZW50aW5nIGEgY2F0ZWdvcnkuIFdoZW4gdGhlIGJ1dHRvblxuLy8gaXMgcHJlc3NlZCwgdGhlIGFjdGl2ZUNhdGVnb3J5IHdpbGwgYmUgdXBkYXRlZCB0byByZWZsZWN0IHRoZSBjYXRlZ29yeSBpdFxuLy8gcmVwcmVzZW50c1xuY29uc3QgU2VsZWN0Q2F0ZWdvcnkgPSAoeyBjYXRlZ29yaWVzLCBhY3RpdmVDYXRlZ29yeSwgY2FsbGJhY2sgfSkgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICAgIDw+XG4gICAgICAgICAgICB7IGNhdGVnb3JpZXMubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gY2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5LCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5ID09IGFjdGl2ZUNhdGVnb3J5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBcImFjdGl2ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSB7IGkgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2sgPSB7ICgpID0+IGNhbGxiYWNrKGNhdGVnb3J5KSB9PlxuICAgICAgICAgICAgICAgICAgICAgICAgeyBjYXRlZ29yeSB9XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA6IDxwPk5vdGhpbmcgdG8gc2hvdzwvcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC8+XG4gICAgKTtcbn07XG5cbi8vIFJlbmRlcnMgYSBsaXN0IG9mIHBob3RvcyBmb2xsb3dlZCBieSB0aGVpciBub3Rlc1xuY29uc3QgQm9va21hcmtDb2xsZWN0aW9uID0gKHtcbiAgICBib29rbWFya3MsXG4gICAgcmVtb3ZlQ2FsbGJhY2tcbn0pID0+IGJvb2ttYXJrcy5tYXAoKGIsIGkpID0+XG4gICAgPGRpdiBrZXkgPSB7IGkgfT5cbiAgICAgICAgPGltZyBjbGFzc05hbWUgPSBcImNvbGxlY3Rpb24taW1hZ2VcIlxuICAgICAgICAgICAgc3JjID0geyBjYXRhYXMoXCIvY2F0L1wiICsgYi5yZW1vdGVfaWQpIH0gLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWUgPSBcImNvbGxlY3Rpb24taXRlbS1jYXB0aW9uXCI+XG4gICAgICAgICAgICA8YnV0dG9uIG9uQ2xpY2sgPSB7ICgpID0+IHJlbW92ZUNhbGxiYWNrKGIuaWQpIH0+XG4gICAgICAgICAgICAgICAgXHVEODNEXHVEREQxXHVGRTBGXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIHsgYi5ub3RlcyAhPSBudWxsICYmIGIubm90ZXMubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gPHAgY2xhc3NOYW1lID0gXCJjb2xsZWN0aW9uLW5vdGVcIj4geyBiLm5vdGVzIH0gPC9wPlxuICAgICAgICAgICAgICAgIDogPD48Lz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4pO1xuXG5leHBvcnQgZGVmYXVsdCBCb29rbWFya3M7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQVlBLFVBQUksTUFBdUM7QUFDekMsUUFBQyxZQUFXO0FBRUo7QUFHVixjQUNFLE9BQU8sbUNBQW1DLGVBQzFDLE9BQU8sK0JBQStCLGdDQUNwQyxZQUNGO0FBQ0EsMkNBQStCLDRCQUE0QixJQUFJLE1BQU0sQ0FBQztBQUFBLFVBQ3hFO0FBQ1UsY0FBSSxlQUFlO0FBSTdCLGNBQUksaUJBQWlCO0FBQ3JCLGNBQUkscUJBQXFCO0FBQ3pCLGNBQUksMEJBQTBCO0FBRTlCLGNBQUkscUJBQXFCO0FBSXpCLGNBQUkscUJBQXFCO0FBSXpCLGNBQUkscUJBQXNCLE9BQU8sSUFBSSxlQUFlO0FBQ3BELGNBQUksb0JBQXFCLE9BQU8sSUFBSSxjQUFjO0FBQ2xELGNBQUksc0JBQXVCLE9BQU8sSUFBSSxnQkFBZ0I7QUFDdEQsY0FBSSx5QkFBMEIsT0FBTyxJQUFJLG1CQUFtQjtBQUM1RCxjQUFJLHNCQUF1QixPQUFPLElBQUksZ0JBQWdCO0FBQ3RELGNBQUksc0JBQXVCLE9BQU8sSUFBSSxnQkFBZ0I7QUFDdEQsY0FBSSxxQkFBc0IsT0FBTyxJQUFJLGVBQWU7QUFDcEQsY0FBSSx5QkFBMEIsT0FBTyxJQUFJLG1CQUFtQjtBQUM1RCxjQUFJLHNCQUF1QixPQUFPLElBQUksZ0JBQWdCO0FBQ3RELGNBQUksMkJBQTRCLE9BQU8sSUFBSSxxQkFBcUI7QUFDaEUsY0FBSSxrQkFBbUIsT0FBTyxJQUFJ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QUNiLFNBQVM7QUFBQSxZQUNULFFBQVE7QUFBQSxZQUNSLFFBQVE7QUFBQSxZQUNSLE1BQU07QUFBQSxZQUNOLE1BQU07QUFBQSxZQUNOLFVBQVU7QUFBQSxZQUNWLFNBQVM7QUFBQSxZQUNULFdBQVc7QUFBQSxZQUNYLGNBQWM7QUFBQSxZQUNkLE1BQU07QUFBQSxZQUNOLElBQUk7QUFBQSxZQUNKLFlBQVk7QUFBQSxZQUNaLGFBQWE7QUFBQSxZQUNiLFdBQVc7QUFBQSxZQUNYLFdBQVc7QUFBQSxZQUNYLFdBQVc7QUFBQSxZQUNYLElBQUk7QUFBQSxZQUNKLFFBQVE7QUFBQSxZQUNSLFVBQVU7QUFBQSxZQUNWLFNBQVM7QUFBQSxZQUNULFdBQVc7QUFBQSxZQUNYLFVBQVU7QUFBQSxZQUNWLFdBQVc7QUFBQSxZQUNYLFNBQVM7QUFBQSxZQUNULE1BQU07QUFBQSxZQUNOLE9BQU87QUFBQSxZQUNQLE1BQU07QUFBQSxZQUNOLE1BQU07QUFBQSxZQUNOLE1BQU07QUFBQSxZQUNOLEtBQUs7QUFBQSxZQUNMLFVBQVU7QUFBQSxZQUNWLGFBQWE7QUFBQSxZQUNiLGNBQWM7QUFBQSxZQUNkLEtBQUs7QUFBQSxZQUNMLFdBQVc7QUFBQSxZQUNYLE9BQU87QUFBQSxZQUNQLFlBQVk7QUFBQSxZQUNaLFFBQVE7QUFBQSxZQUNSLEtBQUs7QUFBQSxZQUNMLFdBQVc7QUFBQSxZQUNYLFVBQVU7QUFBQSxZQUNWLE9BQU87QUFBQSxZQUNQLE1BQU07QUFBQSxZQUNOLFVBQVU7QUFBQSxZQUNWLE9BQU87QUFBQSxZQUNQLFlBQVk7QUFBQSxZQUNaLE1BQU07QUFBQSxZQUNOLFNBQVM7QUFBQSxZQUNULFNBQVM7QUFBQSxZQUNULGFBQWE7QUFBQSxZQUNiLGFBQWE7QUFBQSxZQUNiLFFBQVE7QUFBQSxZQUNSLFNBQVM7QUFBQSxZQUNULFNBQVM7QUFBQSxZQUNULFlBQVk7QUFBQSxZQUNaLFVBQVU7QUFBQSxZQUNWLGdCQUFnQjtBQUFBLFlBQ2hCLEtBQUs7QUFBQSxZQUNMLFVBQVU7QUFBQSxZQUNWLFVBQVU7QUFB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
|