/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { assertDefined } from '../../util/assert';
import { createNamedArrayType } from '../../util/named_array_type';
import { assertNodeInjector } from '../assert';
import { getInjectorIndex, getParentInjectorLocation } from '../di';
import { CONTAINER_HEADER_OFFSET, HAS_TRANSPLANTED_VIEWS, MOVED_VIEWS, NATIVE } from '../interfaces/container';
import { NO_PARENT_INJECTOR } from '../interfaces/injector';
import { toTNodeTypeAsString } from '../interfaces/node';
import { getTStylingRangeNext, getTStylingRangeNextDuplicate, getTStylingRangePrev, getTStylingRangePrevDuplicate } from '../interfaces/styling';
import { CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, ID, INJECTOR, NEXT, PARENT, QUERIES, RENDERER, RENDERER_FACTORY, SANITIZER, T_HOST, TVIEW, TViewTypeAsString } from '../interfaces/view';
import { attachDebugObject } from '../util/debug_utils';
import { getParentInjectorIndex, getParentInjectorView } from '../util/injector_utils';
import { unwrapRNode } from '../util/view_utils';
/*
* This file contains conditionally attached classes which provide human readable (debug) level
* information for `LView`, `LContainer` and other internal data structures. These data structures
* are stored internally as array which makes it very difficult during debugging to reason about the
* current state of the system.
*
* Patching the array with extra property does change the array's hidden class' but it does not
* change the cost of access, therefore this patching should not have significant if any impact in
* `ngDevMode` mode. (see: https://jsperf.com/array-vs-monkey-patch-array)
*
* So instead of seeing:
* ```
* Array(30) [Object, 659, null, …]
* ```
*
* You get to see:
* ```
* LViewDebug {
* views: [...],
* flags: {attached: true, ...}
* nodes: [
* {html: '
', ..., nodes: [
* {html: '', ..., nodes: null}
* ]}
* ]
* }
* ```
*/
let LVIEW_COMPONENT_CACHE;
let LVIEW_EMBEDDED_CACHE;
let LVIEW_ROOT;
let LVIEW_COMPONENT;
let LVIEW_EMBEDDED;
/**
* This function clones a blueprint and creates LView.
*
* Simple slice will keep the same type, and we need it to be LView
*/
export function cloneToLViewFromTViewBlueprint(tView) {
const debugTView = tView;
const lView = getLViewToClone(debugTView.type, tView.template && tView.template.name);
return lView.concat(tView.blueprint);
}
class LRootView extends Array {
}
class LComponentView extends Array {
}
class LEmbeddedView extends Array {
}
function getLViewToClone(type, name) {
switch (type) {
case 0 /* TViewType.Root */:
if (LVIEW_ROOT === undefined)
LVIEW_ROOT = new LRootView();
return LVIEW_ROOT;
case 1 /* TViewType.Component */:
if (!ngDevMode || !ngDevMode.namedConstructors) {
if (LVIEW_COMPONENT === undefined)
LVIEW_COMPONENT = new LComponentView();
return LVIEW_COMPONENT;
}
if (LVIEW_COMPONENT_CACHE === undefined)
LVIEW_COMPONENT_CACHE = new Map();
let componentArray = LVIEW_COMPONENT_CACHE.get(name);
if (componentArray === undefined) {
componentArray = new (createNamedArrayType('LComponentView' + nameSuffix(name)))();
LVIEW_COMPONENT_CACHE.set(name, componentArray);
}
return componentArray;
case 2 /* TViewType.Embedded */:
if (!ngDevMode || !ngDevMode.namedConstructors) {
if (LVIEW_EMBEDDED === undefined)
LVIEW_EMBEDDED = new LEmbeddedView();
return LVIEW_EMBEDDED;
}
if (LVIEW_EMBEDDED_CACHE === undefined)
LVIEW_EMBEDDED_CACHE = new Map();
let embeddedArray = LVIEW_EMBEDDED_CACHE.get(name);
if (embeddedArray === undefined) {
embeddedArray = new (createNamedArrayType('LEmbeddedView' + nameSuffix(name)))();
LVIEW_EMBEDDED_CACHE.set(name, embeddedArray);
}
return embeddedArray;
}
}
function nameSuffix(text) {
if (text == null)
return '';
const index = text.lastIndexOf('_Template');
return '_' + (index === -1 ? text : text.slice(0, index));
}
/**
* This class is a debug version of Object literal so that we can have constructor name show up
* in
* debug tools in ngDevMode.
*/
export const TViewConstructor = class TView {
constructor(type, blueprint, template, queries, viewQuery, declTNode, data, bindingStartIndex, expandoStartIndex, hostBindingOpCodes, firstCreatePass, firstUpdatePass, staticViewQueries, staticContentQueries, preOrderHooks, preOrderCheckHooks, contentHooks, contentCheckHooks, viewHooks, viewCheckHooks, destroyHooks, cleanup, contentQueries, components, directiveRegistry, pipeRegistry, firstChild, schemas, consts, incompleteFirstPass, _decls, _vars) {
this.type = type;
this.blueprint = blueprint;
this.template = template;
this.queries = queries;
this.viewQuery = viewQuery;
this.declTNode = declTNode;
this.data = data;
this.bindingStartIndex = bindingStartIndex;
this.expandoStartIndex = expandoStartIndex;
this.hostBindingOpCodes = hostBindingOpCodes;
this.firstCreatePass = firstCreatePass;
this.firstUpdatePass = firstUpdatePass;
this.staticViewQueries = staticViewQueries;
this.staticContentQueries = staticContentQueries;
this.preOrderHooks = preOrderHooks;
this.preOrderCheckHooks = preOrderCheckHooks;
this.contentHooks = contentHooks;
this.contentCheckHooks = contentCheckHooks;
this.viewHooks = viewHooks;
this.viewCheckHooks = viewCheckHooks;
this.destroyHooks = destroyHooks;
this.cleanup = cleanup;
this.contentQueries = contentQueries;
this.components = components;
this.directiveRegistry = directiveRegistry;
this.pipeRegistry = pipeRegistry;
this.firstChild = firstChild;
this.schemas = schemas;
this.consts = consts;
this.incompleteFirstPass = incompleteFirstPass;
this._decls = _decls;
this._vars = _vars;
}
get template_() {
const buf = [];
processTNodeChildren(this.firstChild, buf);
return buf.join('');
}
get type_() {
return TViewTypeAsString[this.type] || `TViewType.?${this.type}?`;
}
};
class TNode {
constructor(tView_, //
type, //
index, //
insertBeforeIndex, //
injectorIndex, //
directiveStart, //
directiveEnd, //
directiveStylingLast, //
propertyBindings, //
flags, //
providerIndexes, //
value, //
attrs, //
mergedAttrs, //
localNames, //
initialInputs, //
inputs, //
outputs, //
tViews, //
next, //
projectionNext, //
child, //
parent, //
projection, //
styles, //
stylesWithoutHost, //
residualStyles, //
classes, //
classesWithoutHost, //
residualClasses, //
classBindings, //
styleBindings) {
this.tView_ = tView_;
this.type = type;
this.index = index;
this.insertBeforeIndex = insertBeforeIndex;
this.injectorIndex = injectorIndex;
this.directiveStart = directiveStart;
this.directiveEnd = directiveEnd;
this.directiveStylingLast = directiveStylingLast;
this.propertyBindings = propertyBindings;
this.flags = flags;
this.providerIndexes = providerIndexes;
this.value = value;
this.attrs = attrs;
this.mergedAttrs = mergedAttrs;
this.localNames = localNames;
this.initialInputs = initialInputs;
this.inputs = inputs;
this.outputs = outputs;
this.tViews = tViews;
this.next = next;
this.projectionNext = projectionNext;
this.child = child;
this.parent = parent;
this.projection = projection;
this.styles = styles;
this.stylesWithoutHost = stylesWithoutHost;
this.residualStyles = residualStyles;
this.classes = classes;
this.classesWithoutHost = classesWithoutHost;
this.residualClasses = residualClasses;
this.classBindings = classBindings;
this.styleBindings = styleBindings;
}
/**
* Return a human debug version of the set of `NodeInjector`s which will be consulted when
* resolving tokens from this `TNode`.
*
* When debugging applications, it is often difficult to determine which `NodeInjector`s will be
* consulted. This method shows a list of `DebugNode`s representing the `TNode`s which will be
* consulted in order when resolving a token starting at this `TNode`.
*
* The original data is stored in `LView` and `TView` with a lot of offset indexes, and so it is
* difficult to reason about.
*
* @param lView The `LView` instance for this `TNode`.
*/
debugNodeInjectorPath(lView) {
const path = [];
let injectorIndex = getInjectorIndex(this, lView);
if (injectorIndex === -1) {
// Looks like the current `TNode` does not have `NodeInjector` associated with it => look for
// parent NodeInjector.
const parentLocation = getParentInjectorLocation(this, lView);
if (parentLocation !== NO_PARENT_INJECTOR) {
// We found a parent, so start searching from the parent location.
injectorIndex = getParentInjectorIndex(parentLocation);
lView = getParentInjectorView(parentLocation, lView);
}
else {
// No parents have been found, so there are no `NodeInjector`s to consult.
}
}
while (injectorIndex !== -1) {
ngDevMode && assertNodeInjector(lView, injectorIndex);
const tNode = lView[TVIEW].data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */];
path.push(buildDebugNode(tNode, lView));
const parentLocation = lView[injectorIndex + 8 /* NodeInjectorOffset.PARENT */];
if (parentLocation === NO_PARENT_INJECTOR) {
injectorIndex = -1;
}
else {
injectorIndex = getParentInjectorIndex(parentLocation);
lView = getParentInjectorView(parentLocation, lView);
}
}
return path;
}
get type_() {
return toTNodeTypeAsString(this.type) || `TNodeType.?${this.type}?`;
}
get flags_() {
const flags = [];
if (this.flags & 16 /* TNodeFlags.hasClassInput */)
flags.push('TNodeFlags.hasClassInput');
if (this.flags & 8 /* TNodeFlags.hasContentQuery */)
flags.push('TNodeFlags.hasContentQuery');
if (this.flags & 32 /* TNodeFlags.hasStyleInput */)
flags.push('TNodeFlags.hasStyleInput');
if (this.flags & 128 /* TNodeFlags.hasHostBindings */)
flags.push('TNodeFlags.hasHostBindings');
if (this.flags & 2 /* TNodeFlags.isComponentHost */)
flags.push('TNodeFlags.isComponentHost');
if (this.flags & 1 /* TNodeFlags.isDirectiveHost */)
flags.push('TNodeFlags.isDirectiveHost');
if (this.flags & 64 /* TNodeFlags.isDetached */)
flags.push('TNodeFlags.isDetached');
if (this.flags & 4 /* TNodeFlags.isProjected */)
flags.push('TNodeFlags.isProjected');
return flags.join('|');
}
get template_() {
if (this.type & 1 /* TNodeType.Text */)
return this.value;
const buf = [];
const tagName = typeof this.value === 'string' && this.value || this.type_;
buf.push('<', tagName);
if (this.flags) {
buf.push(' ', this.flags_);
}
if (this.attrs) {
for (let i = 0; i < this.attrs.length;) {
const attrName = this.attrs[i++];
if (typeof attrName == 'number') {
break;
}
const attrValue = this.attrs[i++];
buf.push(' ', attrName, '="', attrValue, '"');
}
}
buf.push('>');
processTNodeChildren(this.child, buf);
buf.push('', tagName, '>');
return buf.join('');
}
get styleBindings_() {
return toDebugStyleBinding(this, false);
}
get classBindings_() {
return toDebugStyleBinding(this, true);
}
get providerIndexStart_() {
return this.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
}
get providerIndexEnd_() {
return this.providerIndexStart_ +
(this.providerIndexes >>> 20 /* TNodeProviderIndexes.CptViewProvidersCountShift */);
}
}
export const TNodeDebug = TNode;
function toDebugStyleBinding(tNode, isClassBased) {
const tData = tNode.tView_.data;
const bindings = [];
const range = isClassBased ? tNode.classBindings : tNode.styleBindings;
const prev = getTStylingRangePrev(range);
const next = getTStylingRangeNext(range);
let isTemplate = next !== 0;
let cursor = isTemplate ? next : prev;
while (cursor !== 0) {
const itemKey = tData[cursor];
const itemRange = tData[cursor + 1];
bindings.unshift({
key: itemKey,
index: cursor,
isTemplate: isTemplate,
prevDuplicate: getTStylingRangePrevDuplicate(itemRange),
nextDuplicate: getTStylingRangeNextDuplicate(itemRange),
nextIndex: getTStylingRangeNext(itemRange),
prevIndex: getTStylingRangePrev(itemRange),
});
if (cursor === prev)
isTemplate = false;
cursor = getTStylingRangePrev(itemRange);
}
bindings.push((isClassBased ? tNode.residualClasses : tNode.residualStyles) || null);
return bindings;
}
function processTNodeChildren(tNode, buf) {
while (tNode) {
buf.push(tNode.template_);
tNode = tNode.next;
}
}
class TViewData extends Array {
}
let TVIEWDATA_EMPTY; // can't initialize here or it will not be tree shaken, because
// `LView` constructor could have side-effects.
/**
* This function clones a blueprint and creates TData.
*
* Simple slice will keep the same type, and we need it to be TData
*/
export function cloneToTViewData(list) {
if (TVIEWDATA_EMPTY === undefined)
TVIEWDATA_EMPTY = new TViewData();
return TVIEWDATA_EMPTY.concat(list);
}
export class LViewBlueprint extends Array {
}
export class MatchesArray extends Array {
}
export class TViewComponents extends Array {
}
export class TNodeLocalNames extends Array {
}
export class TNodeInitialInputs extends Array {
}
export class LCleanup extends Array {
}
export class TCleanup extends Array {
}
export function attachLViewDebug(lView) {
attachDebugObject(lView, new LViewDebug(lView));
}
export function attachLContainerDebug(lContainer) {
attachDebugObject(lContainer, new LContainerDebug(lContainer));
}
export function toDebug(obj) {
if (obj) {
const debug = obj.debug;
assertDefined(debug, 'Object does not have a debug representation.');
return debug;
}
else {
return obj;
}
}
/**
* Use this method to unwrap a native element in `LView` and convert it into HTML for easier
* reading.
*
* @param value possibly wrapped native DOM node.
* @param includeChildren If `true` then the serialized HTML form will include child elements
* (same
* as `outerHTML`). If `false` then the serialized HTML form will only contain the element
* itself
* (will not serialize child elements).
*/
function toHtml(value, includeChildren = false) {
const node = unwrapRNode(value);
if (node) {
switch (node.nodeType) {
case Node.TEXT_NODE:
return node.textContent;
case Node.COMMENT_NODE:
return ``;
case Node.ELEMENT_NODE:
const outerHTML = node.outerHTML;
if (includeChildren) {
return outerHTML;
}
else {
const innerHTML = '>' + node.innerHTML + '<';
return (outerHTML.split(innerHTML)[0]) + '>';
}
}
}
return null;
}
export class LViewDebug {
constructor(_raw_lView) {
this._raw_lView = _raw_lView;
}
/**
* Flags associated with the `LView` unpacked into a more readable state.
*/
get flags() {
const flags = this._raw_lView[FLAGS];
return {
__raw__flags__: flags,
initPhaseState: flags & 3 /* LViewFlags.InitPhaseStateMask */,
creationMode: !!(flags & 4 /* LViewFlags.CreationMode */),
firstViewPass: !!(flags & 8 /* LViewFlags.FirstLViewPass */),
checkAlways: !!(flags & 16 /* LViewFlags.CheckAlways */),
dirty: !!(flags & 32 /* LViewFlags.Dirty */),
attached: !!(flags & 64 /* LViewFlags.Attached */),
destroyed: !!(flags & 128 /* LViewFlags.Destroyed */),
isRoot: !!(flags & 256 /* LViewFlags.IsRoot */),
indexWithinInitPhase: flags >> 11 /* LViewFlags.IndexWithinInitPhaseShift */,
};
}
get parent() {
return toDebug(this._raw_lView[PARENT]);
}
get hostHTML() {
return toHtml(this._raw_lView[HOST], true);
}
get html() {
return (this.nodes || []).map(mapToHTML).join('');
}
get context() {
return this._raw_lView[CONTEXT];
}
/**
* The tree of nodes associated with the current `LView`. The nodes have been normalized into
* a tree structure with relevant details pulled out for readability.
*/
get nodes() {
const lView = this._raw_lView;
const tNode = lView[TVIEW].firstChild;
return toDebugNodes(tNode, lView);
}
get template() {
return this.tView.template_;
}
get tView() {
return this._raw_lView[TVIEW];
}
get cleanup() {
return this._raw_lView[CLEANUP];
}
get injector() {
return this._raw_lView[INJECTOR];
}
get rendererFactory() {
return this._raw_lView[RENDERER_FACTORY];
}
get renderer() {
return this._raw_lView[RENDERER];
}
get sanitizer() {
return this._raw_lView[SANITIZER];
}
get childHead() {
return toDebug(this._raw_lView[CHILD_HEAD]);
}
get next() {
return toDebug(this._raw_lView[NEXT]);
}
get childTail() {
return toDebug(this._raw_lView[CHILD_TAIL]);
}
get declarationView() {
return toDebug(this._raw_lView[DECLARATION_VIEW]);
}
get queries() {
return this._raw_lView[QUERIES];
}
get tHost() {
return this._raw_lView[T_HOST];
}
get id() {
return this._raw_lView[ID];
}
get decls() {
return toLViewRange(this.tView, this._raw_lView, HEADER_OFFSET, this.tView.bindingStartIndex);
}
get vars() {
return toLViewRange(this.tView, this._raw_lView, this.tView.bindingStartIndex, this.tView.expandoStartIndex);
}
get expando() {
return toLViewRange(this.tView, this._raw_lView, this.tView.expandoStartIndex, this._raw_lView.length);
}
/**
* Normalized view of child views (and containers) attached at this location.
*/
get childViews() {
const childViews = [];
let child = this.childHead;
while (child) {
childViews.push(child);
child = child.next;
}
return childViews;
}
}
function mapToHTML(node) {
if (node.type === 'ElementContainer') {
return (node.children || []).map(mapToHTML).join('');
}
else if (node.type === 'IcuContainer') {
throw new Error('Not implemented');
}
else {
return toHtml(node.native, true) || '';
}
}
function toLViewRange(tView, lView, start, end) {
let content = [];
for (let index = start; index < end; index++) {
content.push({ index: index, t: tView.data[index], l: lView[index] });
}
return { start: start, end: end, length: end - start, content: content };
}
/**
* Turns a flat list of nodes into a tree by walking the associated `TNode` tree.
*
* @param tNode
* @param lView
*/
export function toDebugNodes(tNode, lView) {
if (tNode) {
const debugNodes = [];
let tNodeCursor = tNode;
while (tNodeCursor) {
debugNodes.push(buildDebugNode(tNodeCursor, lView));
tNodeCursor = tNodeCursor.next;
}
return debugNodes;
}
else {
return [];
}
}
export function buildDebugNode(tNode, lView) {
const rawValue = lView[tNode.index];
const native = unwrapRNode(rawValue);
const factories = [];
const instances = [];
const tView = lView[TVIEW];
for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
const def = tView.data[i];
factories.push(def.type);
instances.push(lView[i]);
}
return {
html: toHtml(native),
type: toTNodeTypeAsString(tNode.type),
tNode,
native: native,
children: toDebugNodes(tNode.child, lView),
factories,
instances,
injector: buildNodeInjectorDebug(tNode, tView, lView),
get injectorResolutionPath() {
return tNode.debugNodeInjectorPath(lView);
},
};
}
function buildNodeInjectorDebug(tNode, tView, lView) {
const viewProviders = [];
for (let i = tNode.providerIndexStart_; i < tNode.providerIndexEnd_; i++) {
viewProviders.push(tView.data[i]);
}
const providers = [];
for (let i = tNode.providerIndexEnd_; i < tNode.directiveEnd; i++) {
providers.push(tView.data[i]);
}
const nodeInjectorDebug = {
bloom: toBloom(lView, tNode.injectorIndex),
cumulativeBloom: toBloom(tView.data, tNode.injectorIndex),
providers,
viewProviders,
parentInjectorIndex: lView[tNode.providerIndexStart_ - 1],
};
return nodeInjectorDebug;
}
/**
* Convert a number at `idx` location in `array` into binary representation.
*
* @param array
* @param idx
*/
function binary(array, idx) {
const value = array[idx];
// If not a number we print 8 `?` to retain alignment but let user know that it was called on
// wrong type.
if (typeof value !== 'number')
return '????????';
// We prefix 0s so that we have constant length number
const text = '00000000' + value.toString(2);
return text.substring(text.length - 8);
}
/**
* Convert a bloom filter at location `idx` in `array` into binary representation.
*
* @param array
* @param idx
*/
function toBloom(array, idx) {
if (idx < 0) {
return 'NO_NODE_INJECTOR';
}
return `${binary(array, idx + 7)}_${binary(array, idx + 6)}_${binary(array, idx + 5)}_${binary(array, idx + 4)}_${binary(array, idx + 3)}_${binary(array, idx + 2)}_${binary(array, idx + 1)}_${binary(array, idx + 0)}`;
}
export class LContainerDebug {
constructor(_raw_lContainer) {
this._raw_lContainer = _raw_lContainer;
}
get hasTransplantedViews() {
return this._raw_lContainer[HAS_TRANSPLANTED_VIEWS];
}
get views() {
return this._raw_lContainer.slice(CONTAINER_HEADER_OFFSET)
.map(toDebug);
}
get parent() {
return toDebug(this._raw_lContainer[PARENT]);
}
get movedViews() {
return this._raw_lContainer[MOVED_VIEWS];
}
get host() {
return this._raw_lContainer[HOST];
}
get native() {
return this._raw_lContainer[NATIVE];
}
get next() {
return toDebug(this._raw_lContainer[NEXT]);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibHZpZXdfZGVidWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL2luc3RydWN0aW9ucy9sdmlld19kZWJ1Zy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFPSCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFDakUsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSx5QkFBeUIsRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUNsRSxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsc0JBQXNCLEVBQWMsV0FBVyxFQUFFLE1BQU0sRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBRXpILE9BQU8sRUFBQyxrQkFBa0IsRUFBcUIsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RSxPQUFPLEVBQThKLG1CQUFtQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFLcE4sT0FBTyxFQUFDLG9CQUFvQixFQUFFLDZCQUE2QixFQUFFLG9CQUFvQixFQUFFLDZCQUE2QixFQUE2QixNQUFNLHVCQUF1QixDQUFDO0FBQzNLLE9BQU8sRUFBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQWEsZ0JBQWdCLEVBQW1CLEtBQUssRUFBRSxhQUFhLEVBQVksSUFBSSxFQUFzQixFQUFFLEVBQUUsUUFBUSxFQUE4SCxJQUFJLEVBQXFCLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQTBCLEtBQUssRUFBb0IsaUJBQWlCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUMzZCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztB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LENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0MsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7SW5qZWN0b3J9IGZyb20gJy4uLy4uL2RpL2luamVjdG9yJztcbmltcG9ydCB7VHlwZX0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlL3R5cGUnO1xuaW1wb3J0IHtTY2hlbWFNZXRhZGF0YX0gZnJvbSAnLi4vLi4vbWV0YWRhdGEvc2NoZW1hJztcbmltcG9ydCB7U2FuaXRpemVyfSBmcm9tICcuLi8uLi9zYW5pdGl6YXRpb24vc2FuaXRpemVyJztcbmltcG9ydCB7S2V5VmFsdWVBcnJheX0gZnJvbSAnLi4vLi4vdXRpbC9hcnJheV91dGlscyc7XG5pbXBvcnQge2Fzc2VydERlZmluZWR9IGZyb20gJy4uLy4uL3V0aWwvYXNzZXJ0JztcbmltcG9ydCB7Y3JlYXRlTmFtZWRBcnJheVR5cGV9IGZyb20gJy4uLy4uL3V0aWwvbmFtZWRfYXJyYXlfdHlwZSc7XG5pbXBvcnQge2Fzc2VydE5vZGVJbmplY3Rvcn0gZnJvbSAnLi4vYXNzZXJ0JztcbmltcG9ydCB7Z2V0SW5qZWN0b3JJbmRleCwgZ2V0UGFyZW50SW5qZWN0b3JMb2NhdGlvbn0gZnJvbSAnLi4vZGknO1xuaW1wb3J0IHtDT05UQUlORVJfSEVBREVSX09GRlNFVCwgSEFTX1RSQU5TUExBTlRFRF9WSUVXUywgTENvbnRhaW5lciwgTU9WRURfVklFV1MsIE5BVElWRX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9jb250YWluZXInO1xuaW1wb3J0IHtDb21wb25lbnRUZW1wbGF0ZSwgRGlyZWN0aXZlRGVmLCBEaXJlY3RpdmVEZWZMaXN0LCBQaXBlRGVmTGlzdCwgVmlld1F1ZXJpZXNGdW5jdGlvbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9kZWZpbml0aW9uJztcbmltcG9ydCB7Tk9fUEFSRU5UX0lOSkVDVE9SLCBOb2RlSW5qZWN0b3JPZmZzZXR9IGZyb20gJy4uL2ludGVyZmFjZXMvaW5qZWN0b3InO1xuaW1wb3J0IHtBdHRyaWJ1dGVNYXJrZXIsIEluc2VydEJlZm9yZUluZGV4LCBQcm9wZXJ0eUFsaWFzZXMsIFRDb25zdGFudHMsIFRDb250YWluZXJOb2RlLCBURWxlbWVudE5vZGUsIFROb2RlIGFzIElUTm9kZSwgVE5vZGVGbGFncywgVE5vZGVQcm92aWRlckluZGV4ZXMsIFROb2RlVHlwZSwgdG9UTm9kZVR5cGVBc1N0cmluZ30gZnJvbSAnLi4vaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7U2VsZWN0b3JGbGFnc30gZnJvbSAnLi4vaW50ZXJmYWNlcy9wcm9qZWN0aW9uJztcbmltcG9ydCB7TFF1ZXJpZXMsIFRRdWVyaWVzfSBmcm9tICcuLi9pbnRlcmZhY2VzL3F1ZXJ5JztcbmltcG9ydCB7UmVuZGVyZXIsIFJlbmRlcmVyRmFjdG9yeX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZW5kZXJlcic7XG5pbXBvcnQge1JDb21tZW50LCBSRWxlbWVudCwgUk5vZGV9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVuZGVyZXJfZG9tJztcbmltcG9ydCB7Z2V0VFN0eWxpbmdSYW5nZU5leHQsIGdldFRTdHlsaW5nUmFuZ2VOZXh0RHVwbGljYXRlLCBnZXRUU3R5bGluZ1JhbmdlUHJldiwgZ2V0VFN0eWxpbmdSYW5nZVByZXZEdXBsaWNhdGUsIFRTdHlsaW5nS2V5LCBUU3R5bGluZ1JhbmdlfSBmcm9tICcuLi9pbnRlcmZhY2VzL3N0eWxpbmcnO1xuaW1wb3J0IHtDSElMRF9IRUFELCBDSElMRF9UQUlMLCBDTEVBTlVQLCBDT05URVhULCBEZWJ1Z05vZGUsIERFQ0xBUkFUSU9OX1ZJRVcsIERlc3Ryb3lIb29rRGF0YSwgRkxBR1MsIEhFQURFUl9PRkZTRVQsIEhvb2tEYXRhLCBIT1NULCBIb3N0QmluZGluZ09wQ29kZXMsIElELCBJTkpFQ1RPUiwgTENvbnRhaW5lckRlYnVnIGFzIElMQ29udGFpbmVyRGVidWcsIExWaWV3LCBMVmlld0RlYnVnIGFzIElMVmlld0RlYnVnLCBMVmlld0RlYnVnUmFuZ2UsIExWaWV3RGVidWdSYW5nZUNvbnRlbnQsIExWaWV3RmxhZ3MsIE5FWFQsIE5vZGVJbmplY3RvckRlYnVnLCBQQVJFTlQsIFFVRVJJRVMsIFJFTkRFUkVSLCBSRU5ERVJFUl9GQUNUT1JZLCBTQU5JVElaRVIsIFRfSE9TVCwgVERhdGEsIFRWaWV3IGFzIElUVmlldywgVFZJRVcsIFRWaWV3LCBUVmlld1R5cGUsIFRWaWV3VHlwZUFzU3RyaW5nfSBmcm9tICcuLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHthdHRhY2hEZWJ1Z09iamVjdH0gZnJvbSAnLi4vdXRpbC9kZWJ1Z191dGlscyc7XG5pbXBvcnQge2dldFBhcmVudEluamVjdG9ySW5kZXgsIGdldFBhcmVudEluamVjdG9yVmlld30gZnJvbSAnLi4vdXRpbC9pbmplY3Rvcl91dGlscyc7XG5pbXBvcnQge3Vud3JhcFJOb2RlfSBmcm9tICcuLi91dGlsL3ZpZXdfdXRpbHMnO1xuXG4vKlxuICogVGhpcyBmaWxlIGNvbnRhaW5zIGNvbmRpdGlvbmFsbHkgYXR0YWNoZWQgY2xhc3NlcyB3aGljaCBwcm92aWRlIGh1bWFuIHJlYWRhYmxlIChkZWJ1ZykgbGV2ZWxcbiAqIGluZm9ybWF0aW9uIGZvciBgTFZpZXdgLCBgTENvbnRhaW5lcmAgYW5kIG90aGVyIGludGVybmFsIGRhdGEgc3RydWN0dXJlcy4gVGhlc2UgZGF0YSBzdHJ1Y3R1cmVzXG4gKiBhcmUgc3RvcmVkIGludGVybmFsbHkgYXMgYXJyYXkgd2hpY2ggbWFrZXMgaXQgdmVyeSBkaWZmaWN1bHQgZHVyaW5nIGRlYnVnZ2luZyB0byByZWFzb24gYWJvdXQgdGhlXG4gKiBjdXJyZW50IHN0YXRlIG9mIHRoZSBzeXN0ZW0uXG4gKlxuICogUGF0Y2hpbmcgdGhlIGFycmF5IHdpdGggZXh0cmEgcHJvcGVydHkgZG9lcyBjaGFuZ2UgdGhlIGFycmF5J3MgaGlkZGVuIGNsYXNzJyBidXQgaXQgZG9lcyBub3RcbiAqIGNoYW5nZSB0aGUgY29zdCBvZiBhY2Nlc3MsIHRoZXJlZm9yZSB0aGlzIHBhdGNoaW5nIHNob3VsZCBub3QgaGF2ZSBzaWduaWZpY2FudCBpZiBhbnkgaW1wYWN0IGluXG4gKiBgbmdEZXZNb2RlYCBtb2RlLiAoc2VlOiBodHRwczovL2pzcGVyZi5jb20vYXJyYXktdnMtbW9ua2V5LXBhdGNoLWFycmF5KVxuICpcbiAqIFNvIGluc3RlYWQgb2Ygc2VlaW5nOlxuICogYGBgXG4gKiBBcnJheSgzMCkgW09iamVjdCwgNjU5LCBudWxsLCDigKZdXG4gKiBgYGBcbiAqXG4gKiBZb3UgZ2V0IHRvIHNlZTpcbiAqIGBgYFxuICogTFZpZXdEZWJ1ZyB7XG4gKiAgIHZpZXdzOiBbLi4uXSxcbiAqICAgZmxhZ3M6IHthdHRhY2hlZDogdHJ1ZSwgLi4ufVxuICogICBub2RlczogW1xuICogICAgIHtodG1sOiAnPGRpdiBpZD1cIjEyM1wiPicsIC4uLiwgbm9kZXM6IFtcbiAqICAgICAgIHtodG1sOiAnPHNwYW4+JywgLi4uLCBub2RlczogbnVsbH1cbiAqICAgICBdfVxuICogICBdXG4gKiB9XG4gKiBgYGBcbiAqL1xuXG5sZXQgTFZJRVdfQ09NUE9ORU5UX0NBQ0hFOiBNYXA8c3RyaW5nfG51bGwsIEFycmF5PGFueT4+fHVuZGVmaW5lZDtcbmxldCBMVklFV19FTUJFRERFRF9DQUNIRTogTWFwPHN0cmluZ3xudWxsLCBBcnJheTxhbnk+Pnx1bmRlZmluZWQ7XG5sZXQgTFZJRVdfUk9PVDogQXJyYXk8YW55Pnx1bmRlZmluZWQ7XG5sZXQgTFZJRVdfQ09NUE9ORU5UOiBBcnJheTxhbnk+fHVuZGVmaW5lZDtcbmxldCBMVklFV19FTUJFRERFRDogQXJyYXk8YW55Pnx1bmRlZmluZWQ7XG5cbmludGVyZmFjZSBUVmlld0RlYnVnIGV4dGVuZHMgSVRWaWV3IHtcbiAgdHlwZTogVFZpZXdUeXBlO1xufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gY2xvbmVzIGEgYmx1ZXByaW50IGFuZCBjcmVhdGVzIExWaWV3LlxuICpcbiAqIFNpbXBsZSBzbGljZSB3aWxsIGtlZXAgdGhlIHNhbWUgdHlwZSwgYW5kIHdlIG5lZWQgaXQgdG8gYmUgTFZpZXdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lVG9MVmlld0Zyb21UVmlld0JsdWVwcmludDxUPih0VmlldzogVFZpZXcpOiBMVmlldzxUPiB7XG4gIGNvbnN0IGRlYnVnVFZpZXcgPSB0VmlldyBhcyBUVmlld0RlYnVnO1xuICBjb25zdCBsVmlldyA9IGdldExWaWV3VG9DbG9uZShkZWJ1Z1RWaWV3LnR5cGUsIHRWaWV3LnRlbXBsYXRlICYmIHRWaWV3LnRlbXBsYXRlLm5hbWUpO1xuICByZXR1cm4gbFZpZXcuY29uY2F0KHRWaWV3LmJsdWVwcmludCkgYXMgYW55O1xufVxuXG5jbGFzcyBMUm9vdFZpZXcgZXh0ZW5kcyBBcnJheSB7fVxuY2xhc3MgTENvbXBvbmVudFZpZXcgZXh0ZW5kcyBBcnJheSB7fVxuY2xhc3MgTEVtYmVkZGVkVmlldyBleHRlbmRzIEFycmF5IHt9XG5cbmZ1bmN0aW9uIGdldExWaWV3VG9DbG9uZSh0eXBlOiBUVmlld1R5cGUsIG5hbWU6IHN0cmluZ3xudWxsKTogQXJyYXk8YW55PiB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgVFZpZXdUeXBlLlJvb3Q6XG4gICAgICBpZiAoTFZJRVdfUk9PVCA9PT0gdW5kZWZpbmVkKSBMVklFV19ST09UID0gbmV3IExSb290VmlldygpO1xuICAgICAgcmV0dXJuIExWSUVXX1JPT1Q7XG4gICAgY2FzZSBUVmlld1R5cGUuQ29tcG9uZW50OlxuICAgICAgaWYgKCFuZ0Rldk1vZGUgfHwgIW5nRGV2TW9kZS5uYW1lZENvbnN0cnVjdG9ycykge1xuICAgICAgICBpZiAoTFZJRVdfQ09NUE9ORU5UID09PSB1bmRlZmluZWQpIExWSUVXX0NPTVBPTkVOVCA9IG5ldyBMQ29tcG9uZW50VmlldygpO1xuICAgICAgICByZXR1cm4gTFZJRVdfQ09NUE9ORU5UO1xuICAgICAgfVxuICAgICAgaWYgKExWSUVXX0NPTVBPTkVOVF9DQUNIRSA9PT0gdW5kZWZpbmVkKSBMVklFV19DT01QT05FTlRfQ0FDSEUgPSBuZXcgTWFwKCk7XG4gICAgICBsZXQgY29tcG9uZW50QXJyYXkgPSBMVklFV19DT01QT05FTlRfQ0FDSEUuZ2V0KG5hbWUpO1xuICAgICAgaWYgKGNvbXBvbmVudEFycmF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29tcG9uZW50QXJyYXkgPSBuZXcgKGNyZWF0ZU5hbWVkQXJyYXlUeXBlKCdMQ29tcG9uZW50VmlldycgKyBuYW1lU3VmZml4KG5hbWUpKSkoKTtcbiAgICAgICAgTFZJRVdfQ09NUE9ORU5UX0NBQ0hFLnNldChuYW1lLCBjb21wb25lbnRBcnJheSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29tcG9uZW50QXJyYXk7XG4gICAgY2FzZSBUVmlld1R5cGUuRW1iZWRkZWQ6XG4gICAgICBpZiAoIW5nRGV2TW9kZSB8fCAhbmdEZXZNb2RlLm5hbWVkQ29uc3RydWN0b3JzKSB7XG4gICAgICAgIGlmIChMVklFV19FTUJFRERFRCA9PT0gdW5kZWZpbmVkKSBMVklFV19FTUJFRERFRCA9IG5ldyBMRW1iZWRkZWRWaWV3KCk7XG4gICAgICAgIHJldHVybiBMVklFV19FTUJFRERFRDtcbiAgICAgIH1cbiAgICAgIGlmIChMVklFV19FTUJFRERFRF9DQUNIRSA9PT0gdW5kZWZpbmVkKSBMVklFV19FTUJFRERFRF9DQUNIRSA9IG5ldyBNYXAoKTtcbiAgICAgIGxldCBlbWJlZGRlZEFycmF5ID0gTFZJRVdfRU1CRURERURfQ0FDSEUuZ2V0KG5hbWUpO1xuICAgICAgaWYgKGVtYmVkZGVkQXJyYXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbWJlZGRlZEFycmF5ID0gbmV3IChjcmVhdGVOYW1lZEFycmF5VHlwZSgnTEVtYmVkZGVkVmlldycgKyBuYW1lU3VmZml4KG5hbWUpKSkoKTtcbiAgICAgICAgTFZJRVdfRU1CRURERURfQ0FDSEUuc2V0KG5hbWUsIGVtYmVkZGVkQXJyYXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVtYmVkZGVkQXJyYXk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbmFtZVN1ZmZpeCh0ZXh0OiBzdHJpbmd8bnVsbHx1bmRlZmluZWQpOiBzdHJpbmcge1xuICBpZiAodGV4dCA9PSBudWxsKSByZXR1cm4gJyc7XG4gIGNvbnN0IGluZGV4ID0gdGV4dC5sYXN0SW5kZXhPZignX1RlbXBsYXRlJyk7XG4gIHJldHVybiAnXycgKyAoaW5kZXggPT09IC0xID8gdGV4dCA6IHRleHQuc2xpY2UoMCwgaW5kZXgpKTtcbn1cblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIGEgZGVidWcgdmVyc2lvbiBvZiBPYmplY3QgbGl0ZXJhbCBzbyB0aGF0IHdlIGNhbiBoYXZlIGNvbnN0cnVjdG9yIG5hbWUgc2hvdyB1cFxuICogaW5cbiAqIGRlYnVnIHRvb2xzIGluIG5nRGV2TW9kZS5cbiAqL1xuZXhwb3J0IGNvbnN0IFRWaWV3Q29uc3RydWN0b3IgPSBjbGFzcyBUVmlldyBpbXBsZW1lbnRzIElUVmlldyB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHVibGljIHR5cGU6IFRWaWV3VHlwZSxcbiAgICAgIHB1YmxpYyBibHVlcHJpbnQ6IExWaWV3LFxuICAgICAgcHVibGljIHRlbXBsYXRlOiBDb21wb25lbnRUZW1wbGF0ZTx7fT58bnVsbCxcbiAgICAgIHB1YmxpYyBxdWVyaWVzOiBUUXVlcmllc3xudWxsLFxuICAgICAgcHVibGljIHZpZXdRdWVyeTogVmlld1F1ZXJpZXNGdW5jdGlvbjx7fT58bnVsbCxcbiAgICAgIHB1YmxpYyBkZWNsVE5vZGU6IElUTm9kZXxudWxsLFxuICAgICAgcHVibGljIGRhdGE6IFREYXRhLFxuICAgICAgcHVibGljIGJpbmRpbmdTdGFydEluZGV4OiBudW1iZXIsXG4gICAgICBwdWJsaWMgZXhwYW5kb1N0YXJ0SW5kZXg6IG51bWJlcixcbiAgICAgIHB1YmxpYyBob3N0QmluZGluZ09wQ29kZXM6IEhvc3RCaW5kaW5nT3BDb2Rlc3xudWxsLFxuICAgICAgcHVibGljIGZpcnN0Q3JlYXRlUGFzczogYm9vbGVhbixcbiAgICAgIHB1YmxpYyBmaXJzdFVwZGF0ZVBhc3M6IGJvb2xlYW4sXG4gICAgICBwdWJsaWMgc3RhdGljVmlld1F1ZXJpZXM6IGJvb2xlYW4sXG4gICAgICBwdWJsaWMgc3RhdGljQ29udGVudFF1ZXJpZXM6IGJvb2xlYW4sXG4gICAgICBwdWJsaWMgcHJlT3JkZXJIb29rczogSG9va0RhdGF8bnVsbCxcbiAgICAgIHB1YmxpYyBwcmVPcmRlckNoZWNrSG9va3M6IEhvb2tEYXRhfG51bGwsXG4gICAgICBwdWJsaWMgY29udGVudEhvb2tzOiBIb29rRGF0YXxudWxsLFxuICAgICAgcHVibGljIGNvbnRlbnRDaGVja0hvb2tzOiBIb29rRGF0YXxudWxsLFxuICAgICAgcHVibGljIHZpZXdIb29rczogSG9va0RhdGF8bnVsbCxcbiAgICAgIHB1YmxpYyB2aWV3Q2hlY2tIb29rczogSG9va0RhdGF8bnVsbCxcbiAgICAgIHB1YmxpYyBkZXN0cm95SG9va3M6IERlc3Ryb3lIb29rRGF0YXxudWxsLFxuICAgICAgcHVibGljIGNsZWFudXA6IGFueVtdfG51bGwsXG4gICAgICBwdWJsaWMgY29udGVudFF1ZXJpZXM6IG51bWJlcltdfG51bGwsXG4gICAgICBwdWJsaWMgY29tcG9uZW50czogbnVtYmVyW118bnVsbCxcbiAgICAgIHB1YmxpYyBkaXJlY3RpdmVSZWdpc3RyeTogRGlyZWN0aXZlRGVmTGlzdHxudWxsLFxuICAgICAgcHVibGljIHBpcGVSZWdpc3RyeTogUGlwZURlZkxpc3R8bnVsbCxcbiAgICAgIHB1YmxpYyBmaXJzdENoaWxkOiBJVE5vZGV8bnVsbCxcbiAgICAgIHB1YmxpYyBzY2hlbWFzOiBTY2hlbWFNZXRhZGF0YVtdfG51bGwsXG4gICAgICBwdWJsaWMgY29uc3RzOiBUQ29uc3RhbnRzfG51bGwsXG4gICAgICBwdWJsaWMgaW5jb21wbGV0ZUZpcnN0UGFzczogYm9vbGVhbixcbiAgICAgIHB1YmxpYyBfZGVjbHM6IG51bWJlcixcbiAgICAgIHB1YmxpYyBfdmFyczogbnVtYmVyLFxuXG4gICkge31cblxuICBnZXQgdGVtcGxhdGVfKCk6IHN0cmluZyB7XG4gICAgY29uc3QgYnVmOiBzdHJpbmdbXSA9IFtdO1xuICAgIHByb2Nlc3NUTm9kZUNoaWxkcmVuKHRoaXMuZmlyc3RDaGlsZCwgYnVmKTtcbiAgICByZXR1cm4gYnVmLmpvaW4oJycpO1xuICB9XG5cbiAgZ2V0IHR5cGVfKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFRWaWV3VHlwZUFzU3RyaW5nW3RoaXMudHlwZV0gfHwgYFRWaWV3VHlwZS4/JHt0aGlzLnR5cGV9P2A7XG4gIH1cbn07XG5cbmNsYXNzIFROb2RlIGltcGxlbWVudHMgSVROb2RlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgdFZpZXdfOiBUVmlldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyB0eXBlOiBUTm9kZVR5cGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIGluZGV4OiBudW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgaW5zZXJ0QmVmb3JlSW5kZXg6IEluc2VydEJlZm9yZUluZGV4LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBpbmplY3RvckluZGV4OiBudW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIGRpcmVjdGl2ZVN0YXJ0OiBudW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgZGlyZWN0aXZlRW5kOiBudW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBkaXJlY3RpdmVTdHlsaW5nTGFzdDogbnVtYmVyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIHByb3BlcnR5QmluZGluZ3M6IG51bWJlcltdfG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgZmxhZ3M6IFROb2RlRmxhZ3MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBwcm92aWRlckluZGV4ZXM6IFROb2RlUHJvdmlkZXJJbmRleGVzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIHZhbHVlOiBzdHJpbmd8bnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgYXR0cnM6IChzdHJpbmd8QXR0cmlidXRlTWFya2VyfChzdHJpbmd8U2VsZWN0b3JGbGFncylbXSlbXXxudWxsLCAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBtZXJnZWRBdHRyczogKHN0cmluZ3xBdHRyaWJ1dGVNYXJrZXJ8KHN0cmluZ3xTZWxlY3RvckZsYWdzKVtdKVtdfG51bGwsICAvL1xuICAgICAgcHVibGljIGxvY2FsTmFtZXM6IChzdHJpbmd8bnVtYmVyKVtdfG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgaW5pdGlhbElucHV0czogKHN0cmluZ1tdfG51bGwpW118bnVsbHx1bmRlZmluZWQsICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBpbnB1dHM6IFByb3BlcnR5QWxpYXNlc3xudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIG91dHB1dHM6IFByb3BlcnR5QWxpYXNlc3xudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgdFZpZXdzOiBJVFZpZXd8SVRWaWV3W118bnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBuZXh0OiBJVE5vZGV8bnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIHByb2plY3Rpb25OZXh0OiBJVE5vZGV8bnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgY2hpbGQ6IElUTm9kZXxudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBwYXJlbnQ6IFRFbGVtZW50Tm9kZXxUQ29udGFpbmVyTm9kZXxudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIHByb2plY3Rpb246IG51bWJlcnwoSVROb2RlfFJOb2RlW10pW118bnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgc3R5bGVzOiBzdHJpbmd8bnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBzdHlsZXNXaXRob3V0SG9zdDogc3RyaW5nfG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIHJlc2lkdWFsU3R5bGVzOiBLZXlWYWx1ZUFycmF5PGFueT58dW5kZWZpbmVkfG51bGwsICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgY2xhc3Nlczogc3RyaW5nfG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBjbGFzc2VzV2l0aG91dEhvc3Q6IHN0cmluZ3xudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgcHVibGljIHJlc2lkdWFsQ2xhc3NlczogS2V5VmFsdWVBcnJheTxhbnk+fHVuZGVmaW5lZHxudWxsLCAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICBwdWJsaWMgY2xhc3NCaW5kaW5nczogVFN0eWxpbmdSYW5nZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgIHB1YmxpYyBzdHlsZUJpbmRpbmdzOiBUU3R5bGluZ1JhbmdlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICApIHt9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGh1bWFuIGRlYnVnIHZlcnNpb24gb2YgdGhlIHNldCBvZiBgTm9kZUluamVjdG9yYHMgd2hpY2ggd2lsbCBiZSBjb25zdWx0ZWQgd2hlblxuICAgKiByZXNvbHZpbmcgdG9rZW5zIGZyb20gdGhpcyBgVE5vZGVgLlxuICAgKlxuICAgKiBXaGVuIGRlYnVnZ2luZyBhcHBsaWNhdGlvbnMsIGl0IGlzIG9mdGVuIGRpZmZpY3VsdCB0byBkZXRlcm1pbmUgd2hpY2ggYE5vZGVJbmplY3RvcmBzIHdpbGwgYmVcbiAgICogY29uc3VsdGVkLiBUaGlzIG1ldGhvZCBzaG93cyBhIGxpc3Qgb2YgYERlYnVnTm9kZWBzIHJlcHJlc2VudGluZyB0aGUgYFROb2RlYHMgd2hpY2ggd2lsbCBiZVxuICAgKiBjb25zdWx0ZWQgaW4gb3JkZXIgd2hlbiByZXNvbHZpbmcgYSB0b2tlbiBzdGFydGluZyBhdCB0aGlzIGBUTm9kZWAuXG4gICAqXG4gICAqIFRoZSBvcmlnaW5hbCBkYXRhIGlzIHN0b3JlZCBpbiBgTFZpZXdgIGFuZCBgVFZpZXdgIHdpdGggYSBsb3Qgb2Ygb2Zmc2V0IGluZGV4ZXMsIGFuZCBzbyBpdCBpc1xuICAgKiBkaWZmaWN1bHQgdG8gcmVhc29uIGFib3V0LlxuICAgKlxuICAgKiBAcGFyYW0gbFZpZXcgVGhlIGBMVmlld2AgaW5zdGFuY2UgZm9yIHRoaXMgYFROb2RlYC5cbiAgICovXG4gIGRlYnVnTm9kZUluamVjdG9yUGF0aChsVmlldzogTFZpZXcpOiBEZWJ1Z05vZGVbXSB7XG4gICAgY29uc3QgcGF0aDogRGVidWdOb2RlW10gPSBbXTtcbiAgICBsZXQgaW5qZWN0b3JJbmRleCA9IGdldEluamVjdG9ySW5kZXgodGhpcywgbFZpZXcpO1xuICAgIGlmIChpbmplY3RvckluZGV4ID09PSAtMSkge1xuICAgICAgLy8gTG9va3MgbGlrZSB0aGUgY3VycmVudCBgVE5vZGVgIGRvZXMgbm90IGhhdmUgYE5vZGVJbmplY3RvcmAgYXNzb2NpYXRlZCB3aXRoIGl0ID0+IGxvb2sgZm9yXG4gICAgICAvLyBwYXJlbnQgTm9kZUluamVjdG9yLlxuICAgICAgY29uc3QgcGFyZW50TG9jYXRpb24gPSBnZXRQYXJlbnRJbmplY3RvckxvY2F0aW9uKHRoaXMsIGxWaWV3KTtcbiAgICAgIGlmIChwYXJlbnRMb2NhdGlvbiAhPT0gTk9fUEFSRU5UX0lOSkVDVE9SKSB7XG4gICAgICAgIC8vIFdlIGZvdW5kIGEgcGFyZW50LCBzbyBzdGFydCBzZWFyY2hpbmcgZnJvbSB0aGUgcGFyZW50IGxvY2F0aW9uLlxuICAgICAgICBpbmplY3RvckluZGV4ID0gZ2V0UGFyZW50SW5qZWN0b3JJbmRleChwYXJlbnRMb2NhdGlvbik7XG4gICAgICAgIGxWaWV3ID0gZ2V0UGFyZW50SW5qZWN0b3JWaWV3KHBhcmVudExvY2F0aW9uLCBsVmlldyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBObyBwYXJlbnRzIGhhdmUgYmVlbiBmb3VuZCwgc28gdGhlcmUgYXJlIG5vIGBOb2RlSW5qZWN0b3JgcyB0byBjb25zdWx0LlxuICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoaW5qZWN0b3JJbmRleCAhPT0gLTEpIHtcbiAgICAgIG5nRGV2TW9kZSAmJiBhc3NlcnROb2RlSW5qZWN0b3IobFZpZXcsIGluamVjdG9ySW5kZXgpO1xuICAgICAgY29uc3QgdE5vZGUgPSBsVmlld1tUVklFV10uZGF0YVtpbmplY3RvckluZGV4ICsgTm9kZUluamVjdG9yT2Zmc2V0LlROT0RFXSBhcyBUTm9kZTtcbiAgICAgIHBhdGgucHVzaChidWlsZERlYnVnTm9kZSh0Tm9kZSwgbFZpZXcpKTtcbiAgICAgIGNvbnN0IHBhcmVudExvY2F0aW9uID0gbFZpZXdbaW5qZWN0b3JJbmRleCArIE5vZGVJbmplY3Rvck9mZnNldC5QQVJFTlRdO1xuICAgICAgaWYgKHBhcmVudExvY2F0aW9uID09PSBOT19QQVJFTlRfSU5KRUNUT1IpIHtcbiAgICAgICAgaW5qZWN0b3JJbmRleCA9IC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5qZWN0b3JJbmRleCA9IGdldFBhcmVudEluamVjdG9ySW5kZXgocGFyZW50TG9jYXRpb24pO1xuICAgICAgICBsVmlldyA9IGdldFBhcmVudEluamVjdG9yVmlldyhwYXJlbnRMb2NhdGlvbiwgbFZpZXcpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIGdldCB0eXBlXygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0b1ROb2RlVHlwZUFzU3RyaW5nKHRoaXMudHlwZSkgfHwgYFROb2RlVHlwZS4/JHt0aGlzLnR5cGV9P2A7XG4gIH1cblxuICBnZXQgZmxhZ3NfKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZmxhZ3M6IHN0cmluZ1tdID0gW107XG4gICAgaWYgKHRoaXMuZmxhZ3MgJiBUTm9kZUZsYWdzLmhhc0NsYXNzSW5wdXQpIGZsYWdzLnB1c2goJ1ROb2RlRmxhZ3MuaGFzQ2xhc3NJbnB1dCcpO1xuICAgIGlmICh0aGlzLmZsYWdzICYgVE5vZGVGbGFncy5oYXNDb250ZW50UXVlcnkpIGZsYWdzLnB1c2goJ1ROb2RlRmxhZ3MuaGFzQ29udGVudFF1ZXJ5Jyk7XG4gICAgaWYgKHRoaXMuZmxhZ3MgJiBUTm9kZUZsYWdzLmhhc1N0eWxlSW5wdXQpIGZsYWdzLnB1c2goJ1ROb2RlRmxhZ3MuaGFzU3R5bGVJbnB1dCcpO1xuICAgIGlmICh0aGlzLmZsYWdzICYgVE5vZGVGbGFncy5oYXNIb3N0QmluZGluZ3MpIGZsYWdzLnB1c2goJ1ROb2RlRmxhZ3MuaGFzSG9zdEJpbmRpbmdzJyk7XG4gICAgaWYgKHRoaXMuZmxhZ3MgJiBUTm9kZUZsYWdzLmlzQ29tcG9uZW50SG9zdCkgZmxhZ3MucHVzaCgnVE5vZGVGbGFncy5pc0NvbXBvbmVudEhvc3QnKTtcbiAgICBpZiAodGhpcy5mbGFncyAmIFROb2RlRmxhZ3MuaXNEaXJlY3RpdmVIb3N0KSBmbGFncy5wdXNoKCdUTm9kZUZsYWdzLmlzRGlyZWN0aXZlSG9zdCcpO1xuICAgIGlmICh0aGlzLmZsYWdzICYgVE5vZGVGbGFncy5pc0RldGFjaGVkKSBmbGFncy5wdXNoKCdUTm9kZUZsYWdzLmlzRGV0YWNoZWQnKTtcbiAgICBpZiAodGhpcy5mbGFncyAmIFROb2RlRmxhZ3MuaXNQcm9qZWN0ZWQpIGZsYWdzLnB1c2goJ1ROb2RlRmxhZ3MuaXNQcm9qZWN0ZWQnKTtcbiAgICByZXR1cm4gZmxhZ3Muam9pbignfCcpO1xuICB9XG5cbiAgZ2V0IHRlbXBsYXRlXygpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnR5cGUgJiBUTm9kZVR5cGUuVGV4dCkgcmV0dXJuIHRoaXMudmFsdWUhO1xuICAgIGNvbnN0IGJ1Zjogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCB0YWdOYW1lID0gdHlwZW9mIHRoaXMudmFsdWUgPT09ICdzdHJpbmcnICYmIHRoaXMudmFsdWUgfHwgdGhpcy50eXBlXztcbiAgICBidWYucHVzaCgnPCcsIHRhZ05hbWUpO1xuICAgIGlmICh0aGlzLmZsYWdzKSB7XG4gICAgICBidWYucHVzaCgnICcsIHRoaXMuZmxhZ3NfKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuYXR0cnMpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hdHRycy5sZW5ndGg7KSB7XG4gICAgICAgIGNvbnN0IGF0dHJOYW1lID0gdGhpcy5hdHRyc1tpKytdO1xuICAgICAgICBpZiAodHlwZW9mIGF0dHJOYW1lID09ICdudW1iZXInKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0clZhbHVlID0gdGhpcy5hdHRyc1tpKytdO1xuICAgICAgICBidWYucHVzaCgnICcsIGF0dHJOYW1lIGFzIHN0cmluZywgJz1cIicsIGF0dHJWYWx1ZSBhcyBzdHJpbmcsICdcIicpO1xuICAgICAgfVxuICAgIH1cbiAgICBidWYucHVzaCgnPicpO1xuICAgIHByb2Nlc3NUTm9kZUNoaWxkcmVuKHRoaXMuY2hpbGQsIGJ1Zik7XG4gICAgYnVmLnB1c2goJzwvJywgdGFnTmFtZSwgJz4nKTtcbiAgICByZXR1cm4gYnVmLmpvaW4oJycpO1xuICB9XG5cbiAgZ2V0IHN0eWxlQmluZGluZ3NfKCk6IERlYnVnU3R5bGVCaW5kaW5ncyB7XG4gICAgcmV0dXJuIHRvRGVidWdTdHlsZUJpbmRpbmcodGhpcywgZmFsc2UpO1xuICB9XG4gIGdldCBjbGFzc0JpbmRpbmdzXygpOiBEZWJ1Z1N0eWxlQmluZGluZ3Mge1xuICAgIHJldHVybiB0b0RlYnVnU3R5bGVCaW5kaW5nKHRoaXMsIHRydWUpO1xuICB9XG5cbiAgZ2V0IHByb3ZpZGVySW5kZXhTdGFydF8oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wcm92aWRlckluZGV4ZXMgJiBUTm9kZVByb3ZpZGVySW5kZXhlcy5Qcm92aWRlcnNTdGFydEluZGV4TWFzaztcbiAgfVxuICBnZXQgcHJvdmlkZXJJbmRleEVuZF8oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wcm92aWRlckluZGV4U3RhcnRfICtcbiAgICAgICAgKHRoaXMucHJvdmlkZXJJbmRleGVzID4+PiBUTm9kZVByb3ZpZGVySW5kZXhlcy5DcHRWaWV3UHJvdmlkZXJzQ291bnRTaGlmdCk7XG4gIH1cbn1cbmV4cG9ydCBjb25zdCBUTm9kZURlYnVnID0gVE5vZGU7XG5leHBvcnQgdHlwZSBUTm9kZURlYnVnID0gVE5vZGU7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVidWdTdHlsZUJpbmRpbmdzIGV4dGVuZHNcbiAgICBBcnJheTxLZXlWYWx1ZUFycmF5PGFueT58RGVidWdTdHlsZUJpbmRpbmd8c3RyaW5nfG51bGw+IHt9XG5leHBvcnQgaW50ZXJmYWNlIERlYnVnU3R5bGVCaW5kaW5nIHtcbiAga2V5OiBUU3R5bGluZ0tleTtcbiAgaW5kZXg6IG51bWJlcjtcbiAgaXNUZW1wbGF0ZTogYm9vbGVhbjtcbiAgcHJldkR1cGxpY2F0ZTogYm9vbGVhbjtcbiAgbmV4dER1cGxpY2F0ZTogYm9vbGVhbjtcbiAgcHJldkluZGV4OiBudW1iZXI7XG4gIG5leHRJbmRleDogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiB0b0RlYnVnU3R5bGVCaW5kaW5nKHROb2RlOiBUTm9kZSwgaXNDbGFzc0Jhc2VkOiBib29sZWFuKTogRGVidWdTdHlsZUJpbmRpbmdzIHtcbiAgY29uc3QgdERhdGEgPSB0Tm9kZS50Vmlld18uZGF0YTtcbiAgY29uc3QgYmluZGluZ3M6IERlYnVnU3R5bGVCaW5kaW5ncyA9IFtdIGFzIGFueTtcbiAgY29uc3QgcmFuZ2UgPSBpc0NsYXNzQmFzZWQgPyB0Tm9kZS5jbGFzc0JpbmRpbmdzIDogdE5vZGUuc3R5bGVCaW5kaW5ncztcbiAgY29uc3QgcHJldiA9IGdldFRTdHlsaW5nUmFuZ2VQcmV2KHJhbmdlKTtcbiAgY29uc3QgbmV4dCA9IGdldFRTdHlsaW5nUmFuZ2VOZXh0KHJhbmdlKTtcbiAgbGV0IGlzVGVtcGxhdGUgPSBuZXh0ICE9PSAwO1xuICBsZXQgY3Vyc29yID0gaXNUZW1wbGF0ZSA/IG5leHQgOiBwcmV2O1xuICB3aGlsZSAoY3Vyc29yICE9PSAwKSB7XG4gICAgY29uc3QgaXRlbUtleSA9IHREYXRhW2N1cnNvcl0gYXMgVFN0eWxpbmdLZXk7XG4gICAgY29uc3QgaXRlbVJhbmdlID0gdERhdGFbY3Vyc29yICsgMV0gYXMgVFN0eWxpbmdSYW5nZTtcbiAgICBiaW5kaW5ncy51bnNoaWZ0KHtcbiAgICAgIGtleTogaXRlbUtleSxcbiAgICAgIGluZGV4OiBjdXJzb3IsXG4gICAgICBpc1RlbXBsYXRlOiBpc1RlbXBsYXRlLFxuICAgICAgcHJldkR1cGxpY2F0ZTogZ2V0VFN0eWxpbmdSYW5nZVByZXZEdXBsaWNhdGUoaXRlbVJhbmdlKSxcbiAgICAgIG5leHREdXBsaWNhdGU6IGdldFRTdHlsaW5nUmFuZ2VOZXh0RHVwbGljYXRlKGl0ZW1SYW5nZSksXG4gICAgICBuZXh0SW5kZXg6IGdldFRTdHlsaW5nUmFuZ2VOZXh0KGl0ZW1SYW5nZSksXG4gICAgICBwcmV2SW5kZXg6IGdldFRTdHlsaW5nUmFuZ2VQcmV2KGl0ZW1SYW5nZSksXG4gICAgfSk7XG4gICAgaWYgKGN1cnNvciA9PT0gcHJldikgaXNUZW1wbGF0ZSA9IGZhbHNlO1xuICAgIGN1cnNvciA9IGdldFRTdHlsaW5nUmFuZ2VQcmV2KGl0ZW1SYW5nZSk7XG4gIH1cbiAgYmluZGluZ3MucHVzaCgoaXNDbGFzc0Jhc2VkID8gdE5vZGUucmVzaWR1YWxDbGFzc2VzIDogdE5vZGUucmVzaWR1YWxTdHlsZXMpIHx8IG51bGwpO1xuICByZXR1cm4gYmluZGluZ3M7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NUTm9kZUNoaWxkcmVuKHROb2RlOiBJVE5vZGV8bnVsbCwgYnVmOiBzdHJpbmdbXSkge1xuICB3aGlsZSAodE5vZGUpIHtcbiAgICBidWYucHVzaCgodE5vZGUgYXMgYW55IGFzIHt0ZW1wbGF0ZV86IHN0cmluZ30pLnRlbXBsYXRlXyk7XG4gICAgdE5vZGUgPSB0Tm9kZS5uZXh0O1xuICB9XG59XG5cbmNsYXNzIFRWaWV3RGF0YSBleHRlbmRzIEFycmF5IHt9XG5sZXQgVFZJRVdEQVRBX0VNUFRZOiB1bmtub3duW107ICAvLyBjYW4ndCBpbml0aWFsaXplIGhlcmUgb3IgaXQgd2lsbCBub3QgYmUgdHJlZSBzaGFrZW4sIGJlY2F1c2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGBMVmlld2AgY29uc3RydWN0b3IgY291bGQgaGF2ZSBzaWRlLWVmZmVjdHMuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gY2xvbmVzIGEgYmx1ZXByaW50IGFuZCBjcmVhdGVzIFREYXRhLlxuICpcbiAqIFNpbXBsZSBzbGljZSB3aWxsIGtlZXAgdGhlIHNhbWUgdHlwZSwgYW5kIHdlIG5lZWQgaXQgdG8gYmUgVERhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lVG9UVmlld0RhdGEobGlzdDogYW55W10pOiBURGF0YSB7XG4gIGlmIChUVklFV0RBVEFfRU1QVFkgPT09IHVuZGVmaW5lZCkgVFZJRVdEQVRBX0VNUFRZID0gbmV3IFRWaWV3RGF0YSgpO1xuICByZXR1cm4gVFZJRVdEQVRBX0VNUFRZLmNvbmNhdChsaXN0KSBhcyBhbnk7XG59XG5cbmV4cG9ydCBjbGFzcyBMVmlld0JsdWVwcmludCBleHRlbmRzIEFycmF5IHt9XG5leHBvcnQgY2xhc3MgTWF0Y2hlc0FycmF5IGV4dGVuZHMgQXJyYXkge31cbmV4cG9ydCBjbGFzcyBUVmlld0NvbXBvbmVudHMgZXh0ZW5kcyBBcnJheSB7fVxuZXhwb3J0IGNsYXNzIFROb2RlTG9jYWxOYW1lcyBleHRlbmRzIEFycmF5IHt9XG5leHBvcnQgY2xhc3MgVE5vZGVJbml0aWFsSW5wdXRzIGV4dGVuZHMgQXJyYXkge31cbmV4cG9ydCBjbGFzcyBMQ2xlYW51cCBleHRlbmRzIEFycmF5IHt9XG5leHBvcnQgY2xhc3MgVENsZWFudXAgZXh0ZW5kcyBBcnJheSB7fVxuXG5leHBvcnQgZnVuY3Rpb24gYXR0YWNoTFZpZXdEZWJ1ZyhsVmlldzogTFZpZXcpIHtcbiAgYXR0YWNoRGVidWdPYmplY3QobFZpZXcsIG5ldyBMVmlld0RlYnVnKGxWaWV3KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdHRhY2hMQ29udGFpbmVyRGVidWcobENvbnRhaW5lcjogTENvbnRhaW5lcikge1xuICBhdHRhY2hEZWJ1Z09iamVjdChsQ29udGFpbmVyLCBuZXcgTENvbnRhaW5lckRlYnVnKGxDb250YWluZXIpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRGVidWc8VD4ob2JqOiBMVmlldzxUPik6IElMVmlld0RlYnVnPFQ+O1xuZXhwb3J0IGZ1bmN0aW9uIHRvRGVidWc8VD4ob2JqOiBMVmlldzxUPnxudWxsKTogSUxWaWV3RGVidWc8VD58bnVsbDtcbmV4cG9ydCBmdW5jdGlvbiB0b0RlYnVnPFQ+KG9iajogTFZpZXc8VD58TENvbnRhaW5lcnxudWxsKTogSUxWaWV3RGVidWc8VD58SUxDb250YWluZXJEZWJ1Z3xudWxsO1xuZXhwb3J0IGZ1bmN0aW9uIHRvRGVidWcob2JqOiBhbnkpOiBhbnkge1xuICBpZiAob2JqKSB7XG4gICAgY29uc3QgZGVidWcgPSAob2JqIGFzIGFueSkuZGVidWc7XG4gICAgYXNzZXJ0RGVmaW5lZChkZWJ1ZywgJ09iamVjdCBkb2VzIG5vdCBoYXZlIGEgZGVidWcgcmVwcmVzZW50YXRpb24uJyk7XG4gICAgcmV0dXJuIGRlYnVnO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmo7XG4gIH1cbn1cblxuLyoqXG4gKiBVc2UgdGhpcyBtZXRob2QgdG8gdW53cmFwIGEgbmF0aXZlIGVsZW1lbnQgaW4gYExWaWV3YCBhbmQgY29udmVydCBpdCBpbnRvIEhUTUwgZm9yIGVhc2llclxuICogcmVhZGluZy5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgcG9zc2libHkgd3JhcHBlZCBuYXRpdmUgRE9NIG5vZGUuXG4gKiBAcGFyYW0gaW5jbHVkZUNoaWxkcmVuIElmIGB0cnVlYCB0aGVuIHRoZSBzZXJpYWxpemVkIEhUTUwgZm9ybSB3aWxsIGluY2x1ZGUgY2hpbGQgZWxlbWVudHNcbiAqIChzYW1lXG4gKiBhcyBgb3V0ZXJIVE1MYCkuIElmIGBmYWxzZWAgdGhlbiB0aGUgc2VyaWFsaXplZCBIVE1MIGZvcm0gd2lsbCBvbmx5IGNvbnRhaW4gdGhlIGVsZW1lbnRcbiAqIGl0c2VsZlxuICogKHdpbGwgbm90IHNlcmlhbGl6ZSBjaGlsZCBlbGVtZW50cykuXG4gKi9cbmZ1bmN0aW9uIHRvSHRtbCh2YWx1ZTogYW55LCBpbmNsdWRlQ2hpbGRyZW46IGJvb2xlYW4gPSBmYWxzZSk6IHN0cmluZ3xudWxsIHtcbiAgY29uc3Qgbm9kZTogTm9kZXxudWxsID0gdW53cmFwUk5vZGUodmFsdWUpIGFzIGFueTtcbiAgaWYgKG5vZGUpIHtcbiAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAgIHJldHVybiBub2RlLnRleHRDb250ZW50O1xuICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERTpcbiAgICAgICAgcmV0dXJuIGA8IS0tJHsobm9kZSBhcyBDb21tZW50KS50ZXh0Q29udGVudH0tLT5gO1xuICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTpcbiAgICAgICAgY29uc3Qgb3V0ZXJIVE1MID0gKG5vZGUgYXMgRWxlbWVudCkub3V0ZXJIVE1MO1xuICAgICAgICBpZiAoaW5jbHVkZUNoaWxkcmVuKSB7XG4gICAgICAgICAgcmV0dXJuIG91dGVySFRNTDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBpbm5lckhUTUwgPSAnPicgKyAobm9kZSBhcyBFbGVtZW50KS5pbm5lckhUTUwgKyAnPCc7XG4gICAgICAgICAgcmV0dXJuIChvdXRlckhUTUwuc3BsaXQoaW5uZXJIVE1MKVswXSkgKyAnPic7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBjbGFzcyBMVmlld0RlYnVnPFQgPSB1bmtub3duPiBpbXBsZW1lbnRzIElMVmlld0RlYnVnPFQ+IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBfcmF3X2xWaWV3OiBMVmlldzxUPikge31cblxuICAvKipcbiAgICogRmxhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZSBgTFZpZXdgIHVucGFja2VkIGludG8gYSBtb3JlIHJlYWRhYmxlIHN0YXRlLlxuICAgKi9cbiAgZ2V0IGZsYWdzKCkge1xuICAgIGNvbnN0IGZsYWdzID0gdGhpcy5fcmF3X2xWaWV3W0ZMQUdTXTtcbiAgICByZXR1cm4ge1xuICAgICAgX19yYXdfX2ZsYWdzX186IGZsYWdzLFxuICAgICAgaW5pdFBoYXNlU3RhdGU6IGZsYWdzICYgTFZpZXdGbGFncy5Jbml0UGhhc2VTdGF0ZU1hc2ssXG4gICAgICBjcmVhdGlvbk1vZGU6ICEhKGZsYWdzICYgTFZpZXdGbGFncy5DcmVhdGlvbk1vZGUpLFxuICAgICAgZmlyc3RWaWV3UGFzczogISEoZmxhZ3MgJiBMVmlld0ZsYWdzLkZpcnN0TFZpZXdQYXNzKSxcbiAgICAgIGNoZWNrQWx3YXlzOiAhIShmbGFncyAmIExWaWV3RmxhZ3MuQ2hlY2tBbHdheXMpLFxuICAgICAgZGlydHk6ICEhKGZsYWdzICYgTFZpZXdGbGFncy5EaXJ0eSksXG4gICAgICBhdHRhY2hlZDogISEoZmxhZ3MgJiBMVmlld0ZsYWdzLkF0dGFjaGVkKSxcbiAgICAgIGRlc3Ryb3llZDogISEoZmxhZ3MgJiBMVmlld0ZsYWdzLkRlc3Ryb3llZCksXG4gICAgICBpc1Jvb3Q6ICEhKGZsYWdzICYgTFZpZXdGbGFncy5Jc1Jvb3QpLFxuICAgICAgaW5kZXhXaXRoaW5Jbml0UGhhc2U6IGZsYWdzID4+IExWaWV3RmxhZ3MuSW5kZXhXaXRoaW5Jbml0UGhhc2VTaGlmdCxcbiAgICB9O1xuICB9XG4gIGdldCBwYXJlbnQoKTogSUxWaWV3RGVidWc8VD58SUxDb250YWluZXJEZWJ1Z3xudWxsIHtcbiAgICByZXR1cm4gdG9EZWJ1ZzxUPih0aGlzLl9yYXdfbFZpZXdbUEFSRU5UXSBhcyBMVmlldzxUPnwgTENvbnRhaW5lciB8IG51bGwpO1xuICB9XG4gIGdldCBob3N0SFRNTCgpOiBzdHJpbmd8bnVsbCB7XG4gICAgcmV0dXJuIHRvSHRtbCh0aGlzLl9yYXdfbFZpZXdbSE9TVF0sIHRydWUpO1xuICB9XG4gIGdldCBodG1sKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICh0aGlzLm5vZGVzIHx8IFtdKS5tYXAobWFwVG9IVE1MKS5qb2luKCcnKTtcbiAgfVxuICBnZXQgY29udGV4dCgpOiBUIHtcbiAgICByZXR1cm4gdGhpcy5fcmF3X2xWaWV3W0NPTlRFWFRdO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgdHJlZSBvZiBub2RlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGN1cnJlbnQgYExWaWV3YC4gVGhlIG5vZGVzIGhhdmUgYmVlbiBub3JtYWxpemVkIGludG9cbiAgICogYSB0cmVlIHN0cnVjdHVyZSB3aXRoIHJlbGV2YW50IGRldGFpbHMgcHVsbGVkIG91dCBmb3IgcmVhZGFiaWxpdHkuXG4gICAqL1xuICBnZXQgbm9kZXMoKTogRGVidWdOb2RlW10ge1xuICAgIGNvbnN0IGxWaWV3ID0gdGhpcy5fcmF3X2xWaWV3O1xuICAgIGNvbnN0IHROb2RlID0gbFZpZXdbVFZJRVddLmZpcnN0Q2hpbGQ7XG4gICAgcmV0dXJuIHRvRGVidWdOb2Rlcyh0Tm9kZSwgbFZpZXcpO1xuICB9XG4gIGdldCB0ZW1wbGF0ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAodGhpcy50VmlldyBhcyBhbnkgYXMge3RlbXBsYXRlXzogc3RyaW5nfSkudGVtcGxhdGVfO1xuICB9XG4gIGdldCB0VmlldygpOiBJVFZpZXcge1xuICAgIHJldHVybiB0aGlzLl9yYXdfbFZpZXdbVFZJRVddO1xuICB9XG4gIGdldCBjbGVhbnVwKCk6IGFueVtdfG51bGwge1xuICAgIHJldHVybiB0aGlzLl9yYXdfbFZpZXdbQ0xFQU5VUF07XG4gIH1cbiAgZ2V0IGluamVjdG9yKCk6IEluamVjdG9yfG51bGwge1xuICAgIHJldHVybiB0aGlzLl9yYXdfbFZpZXdbSU5KRUNUT1JdO1xuICB9XG4gIGdldCByZW5kZXJlckZhY3RvcnkoKTogUmVuZGVyZXJGYWN0b3J5IHtcbiAgICByZXR1cm4gdGhpcy5fcmF3X2xWaWV3W1JFTkRFUkVSX0ZBQ1RPUlldO1xuICB9XG4gIGdldCByZW5kZXJlcigpOiBSZW5kZXJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3Jhd19sVmlld1tSRU5ERVJFUl07XG4gIH1cbiAgZ2V0IHNhbml0aXplcigpOiBTYW5pdGl6ZXJ8bnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3Jhd19sVmlld1tTQU5JVElaRVJdO1xuICB9XG4gIGdldCBjaGlsZEhlYWQoKTogSUxWaWV3RGVidWd8SUxDb250YWluZXJEZWJ1Z3xudWxsIHtcbiAgICByZXR1cm4gdG9EZWJ1Zyh0aGlzLl9yYXdfbFZpZXdbQ0hJTERfSEVBRF0pO1xuICB9XG4gIGdldCBuZXh0KCk6IElMVmlld0RlYnVnPFQ+fElMQ29udGFpbmVyRGVidWd8bnVsbCB7XG4gICAgcmV0dXJuIHRvRGVidWc8VD4odGhpcy5fcmF3X2xWaWV3W05FWFRdIGFzIExWaWV3PFQ+fCBMQ29udGFpbmVyIHwgbnVsbCk7XG4gIH1cbiAgZ2V0IGNoaWxkVGFpbCgpOiBJTFZpZXdEZWJ1Z3xJTENvbnRhaW5lckRlYnVnfG51bGwge1xuICAgIHJldHVybiB0b0RlYnVnKHRoaXMuX3Jhd19sVmlld1tDSElMRF9UQUlMXSk7XG4gIH1cbiAgZ2V0IGRlY2xhcmF0aW9uVmlldygpOiBJTFZpZXdEZWJ1Z3xudWxsIHtcbiAgICByZXR1cm4gdG9EZWJ1Zyh0aGlzLl9yYXdfbFZpZXdbREVDTEFSQVRJT05fVklFV10pO1xuICB9XG4gIGdldCBxdWVyaWVzKCk6IExRdWVyaWVzfG51bGwge1xuICAgIHJldHVybiB0aGlzLl9yYXdfbFZpZXdbUVVFUklFU107XG4gIH1cbiAgZ2V0IHRIb3N0KCk6IElUTm9kZXxudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fcmF3X2xWaWV3W1RfSE9TVF07XG4gIH1cbiAgZ2V0IGlkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3Jhd19sVmlld1tJRF07XG4gIH1cblxuICBnZXQgZGVjbHMoKTogTFZpZXdEZWJ1Z1JhbmdlIHtcbiAgICByZXR1cm4gdG9MVmlld1JhbmdlKHRoaXMudFZpZXcsIHRoaXMuX3Jhd19sVmlldywgSEVBREVSX09GRlNFVCwgdGhpcy50Vmlldy5iaW5kaW5nU3RhcnRJbmRleCk7XG4gIH1cblxuICBnZXQgdmFycygpOiBMVmlld0RlYnVnUmFuZ2Uge1xuICAgIHJldHVybiB0b0xWaWV3UmFuZ2UoXG4gICAgICAgIHRoaXMudFZpZXcsIHRoaXMuX3Jhd19sVmlldywgdGhpcy50Vmlldy5iaW5kaW5nU3RhcnRJbmRleCwgdGhpcy50Vmlldy5leHBhbmRvU3RhcnRJbmRleCk7XG4gIH1cblxuICBnZXQgZXhwYW5kbygpOiBMVmlld0RlYnVnUmFuZ2Uge1xuICAgIHJldHVybiB0b0xWaWV3UmFuZ2UoXG4gICAgICAgIHRoaXMudFZpZXcsIHRoaXMuX3Jhd19sVmlldywgdGhpcy50Vmlldy5leHBhbmRvU3RhcnRJbmRleCwgdGhpcy5fcmF3X2xWaWV3Lmxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplZCB2aWV3IG9mIGNoaWxkIHZpZXdzIChhbmQgY29udGFpbmVycykgYXR0YWNoZWQgYXQgdGhpcyBsb2NhdGlvbi5cbiAgICovXG4gIGdldCBjaGlsZFZpZXdzKCk6IEFycmF5PElMVmlld0RlYnVnPFQ+fElMQ29udGFpbmVyRGVidWc+IHtcbiAgICBjb25zdCBjaGlsZFZpZXdzOiBBcnJheTxJTFZpZXdEZWJ1ZzxUPnxJTENvbnRhaW5lckRlYnVnPiA9IFtdO1xuICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRIZWFkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgY2hpbGRWaWV3cy5wdXNoKGNoaWxkIGFzIElMVmlld0RlYnVnPFQ+fCBJTENvbnRhaW5lckRlYnVnKTtcbiAgICAgIGNoaWxkID0gY2hpbGQubmV4dDtcbiAgICB9XG4gICAgcmV0dXJuIGNoaWxkVmlld3M7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFwVG9IVE1MKG5vZGU6IERlYnVnTm9kZSk6IHN0cmluZyB7XG4gIGlmIChub2RlLnR5cGUgPT09ICdFbGVtZW50Q29udGFpbmVyJykge1xuICAgIHJldHVybiAobm9kZS5jaGlsZHJlbiB8fCBbXSkubWFwKG1hcFRvSFRNTCkuam9pbignJyk7XG4gIH0gZWxzZSBpZiAobm9kZS50eXBlID09PSAnSWN1Q29udGFpbmVyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRvSHRtbChub2RlLm5hdGl2ZSwgdHJ1ZSkgfHwgJyc7XG4gIH1cbn1cblxuZnVuY3Rpb24gdG9MVmlld1JhbmdlKHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IExWaWV3RGVidWdSYW5nZSB7XG4gIGxldCBjb250ZW50OiBMVmlld0RlYnVnUmFuZ2VDb250ZW50W10gPSBbXTtcbiAgZm9yIChsZXQgaW5kZXggPSBzdGFydDsgaW5kZXggPCBlbmQ7IGluZGV4KyspIHtcbiAgICBjb250ZW50LnB1c2goe2luZGV4OiBpbmRleCwgdDogdFZpZXcuZGF0YVtpbmRleF0sIGw6IGxWaWV3W2luZGV4XX0pO1xuICB9XG4gIHJldHVybiB7c3RhcnQ6IHN0YXJ0LCBlbmQ6IGVuZCwgbGVuZ3RoOiBlbmQgLSBzdGFydCwgY29udGVudDogY29udGVudH07XG59XG5cbi8qKlxuICogVHVybnMgYSBmbGF0IGxpc3Qgb2Ygbm9kZXMgaW50byBhIHRyZWUgYnkgd2Fsa2luZyB0aGUgYXNzb2NpYXRlZCBgVE5vZGVgIHRyZWUuXG4gKlxuICogQHBhcmFtIHROb2RlXG4gKiBAcGFyYW0gbFZpZXdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRGVidWdOb2Rlcyh0Tm9kZTogSVROb2RlfG51bGwsIGxWaWV3OiBMVmlldyk6IERlYnVnTm9kZVtdIHtcbiAgaWYgKHROb2RlKSB7XG4gICAgY29uc3QgZGVidWdOb2RlczogRGVidWdOb2RlW10gPSBbXTtcbiAgICBsZXQgdE5vZGVDdXJzb3I6IElUTm9kZXxudWxsID0gdE5vZGU7XG4gICAgd2hpbGUgKHROb2RlQ3Vyc29yKSB7XG4gICAgICBkZWJ1Z05vZGVzLnB1c2goYnVpbGREZWJ1Z05vZGUodE5vZGVDdXJzb3IsIGxWaWV3KSk7XG4gICAgICB0Tm9kZUN1cnNvciA9IHROb2RlQ3Vyc29yLm5leHQ7XG4gICAgfVxuICAgIHJldHVybiBkZWJ1Z05vZGVzO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbXTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREZWJ1Z05vZGUodE5vZGU6IElUTm9kZSwgbFZpZXc6IExWaWV3KTogRGVidWdOb2RlIHtcbiAgY29uc3QgcmF3VmFsdWUgPSBsVmlld1t0Tm9kZS5pbmRleF07XG4gIGNvbnN0IG5hdGl2ZSA9IHVud3JhcFJOb2RlKHJhd1ZhbHVlKTtcbiAgY29uc3QgZmFjdG9yaWVzOiBUeXBlPGFueT5bXSA9IFtdO1xuICBjb25zdCBpbnN0YW5jZXM6IGFueVtdID0gW107XG4gIGNvbnN0IHRWaWV3ID0gbFZpZXdbVFZJRVddO1xuICBmb3IgKGxldCBpID0gdE5vZGUuZGlyZWN0aXZlU3RhcnQ7IGkgPCB0Tm9kZS5kaXJlY3RpdmVFbmQ7IGkrKykge1xuICAgIGNvbnN0IGRlZiA9IHRWaWV3LmRhdGFbaV0gYXMgRGlyZWN0aXZlRGVmPGFueT47XG4gICAgZmFjdG9yaWVzLnB1c2goZGVmLnR5cGUpO1xuICAgIGluc3RhbmNlcy5wdXNoKGxWaWV3W2ldKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGh0bWw6IHRvSHRtbChuYXRpdmUpLFxuICAgIHR5cGU6IHRvVE5vZGVUeXBlQXNTdHJpbmcodE5vZGUudHlwZSksXG4gICAgdE5vZGUsXG4gICAgbmF0aXZlOiBuYXRpdmUgYXMgYW55LFxuICAgIGNoaWxkcmVuOiB0b0RlYnVnTm9kZXModE5vZGUuY2hpbGQsIGxWaWV3KSxcbiAgICBmYWN0b3JpZXMsXG4gICAgaW5zdGFuY2VzLFxuICAgIGluamVjdG9yOiBidWlsZE5vZGVJbmplY3RvckRlYnVnKHROb2RlLCB0VmlldywgbFZpZXcpLFxuICAgIGdldCBpbmplY3RvclJlc29sdXRpb25QYXRoKCkge1xuICAgICAgcmV0dXJuICh0Tm9kZSBhcyBUTm9kZSkuZGVidWdOb2RlSW5qZWN0b3JQYXRoKGxWaWV3KTtcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZE5vZGVJbmplY3RvckRlYnVnKHROb2RlOiBJVE5vZGUsIHRWaWV3OiBJVFZpZXcsIGxWaWV3OiBMVmlldyk6IE5vZGVJbmplY3RvckRlYnVnIHtcbiAgY29uc3Qgdmlld1Byb3ZpZGVyczogVHlwZTxhbnk+W10gPSBbXTtcbiAgZm9yIChsZXQgaSA9ICh0Tm9kZSBhcyBUTm9kZSkucHJvdmlkZXJJbmRleFN0YXJ0XzsgaSA8ICh0Tm9kZSBhcyBUTm9kZSkucHJvdmlkZXJJbmRleEVuZF87IGkrKykge1xuICAgIHZpZXdQcm92aWRlcnMucHVzaCh0Vmlldy5kYXRhW2ldIGFzIFR5cGU8YW55Pik7XG4gIH1cbiAgY29uc3QgcHJvdmlkZXJzOiBUeXBlPGFueT5bXSA9IFtdO1xuICBmb3IgKGxldCBpID0gKHROb2RlIGFzIFROb2RlKS5wcm92aWRlckluZGV4RW5kXzsgaSA8ICh0Tm9kZSBhcyBUTm9kZSkuZGlyZWN0aXZlRW5kOyBpKyspIHtcbiAgICBwcm92aWRlcnMucHVzaCh0Vmlldy5kYXRhW2ldIGFzIFR5cGU8YW55Pik7XG4gIH1cbiAgY29uc3Qgbm9kZUluamVjdG9yRGVidWcgPSB7XG4gICAgYmxvb206IHRvQmxvb20obFZpZXcsIHROb2RlLmluamVjdG9ySW5kZXgpLFxuICAgIGN1bXVsYXRpdmVCbG9vbTogdG9CbG9vbSh0Vmlldy5kYXRhLCB0Tm9kZS5pbmplY3RvckluZGV4KSxcbiAgICBwcm92aWRlcnMsXG4gICAgdmlld1Byb3ZpZGVycyxcbiAgICBwYXJlbnRJbmplY3RvckluZGV4OiBsVmlld1sodE5vZGUgYXMgVE5vZGUpLnByb3ZpZGVySW5kZXhTdGFydF8gLSAxXSxcbiAgfTtcbiAgcmV0dXJuIG5vZGVJbmplY3RvckRlYnVnO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYSBudW1iZXIgYXQgYGlkeGAgbG9jYXRpb24gaW4gYGFycmF5YCBpbnRvIGJpbmFyeSByZXByZXNlbnRhdGlvbi5cbiAqXG4gKiBAcGFyYW0gYXJyYXlcbiAqIEBwYXJhbSBpZHhcbiAqL1xuZnVuY3Rpb24gYmluYXJ5KGFycmF5OiBhbnlbXSwgaWR4OiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCB2YWx1ZSA9IGFycmF5W2lkeF07XG4gIC8vIElmIG5vdCBhIG51bWJlciB3ZSBwcmludCA4IGA/YCB0byByZXRhaW4gYWxpZ25tZW50IGJ1dCBsZXQgdXNlciBrbm93IHRoYXQgaXQgd2FzIGNhbGxlZCBvblxuICAvLyB3cm9uZyB0eXBlLlxuICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJykgcmV0dXJuICc/Pz8/Pz8/Pyc7XG4gIC8vIFdlIHByZWZpeCAwcyBzbyB0aGF0IHdlIGhhdmUgY29uc3RhbnQgbGVuZ3RoIG51bWJlclxuICBjb25zdCB0ZXh0ID0gJzAwMDAwMDAwJyArIHZhbHVlLnRvU3RyaW5nKDIpO1xuICByZXR1cm4gdGV4dC5zdWJzdHJpbmcodGV4dC5sZW5ndGggLSA4KTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgYmxvb20gZmlsdGVyIGF0IGxvY2F0aW9uIGBpZHhgIGluIGBhcnJheWAgaW50byBiaW5hcnkgcmVwcmVzZW50YXRpb24uXG4gKlxuICogQHBhcmFtIGFycmF5XG4gKiBAcGFyYW0gaWR4XG4gKi9cbmZ1bmN0aW9uIHRvQmxvb20oYXJyYXk6IGFueVtdLCBpZHg6IG51bWJlcik6IHN0cmluZyB7XG4gIGlmIChpZHggPCAwKSB7XG4gICAgcmV0dXJuICdOT19OT0RFX0lOSkVDVE9SJztcbiAgfVxuICByZXR1cm4gYCR7YmluYXJ5KGFycmF5LCBpZHggKyA3KX1fJHtiaW5hcnkoYXJyYXksIGlkeCArIDYpfV8ke2JpbmFyeShhcnJheSwgaWR4ICsgNSl9XyR7XG4gICAgICBiaW5hcnkoYXJyYXksIGlkeCArIDQpfV8ke2JpbmFyeShhcnJheSwgaWR4ICsgMyl9XyR7YmluYXJ5KGFycmF5LCBpZHggKyAyKX1fJHtcbiAgICAgIGJpbmFyeShhcnJheSwgaWR4ICsgMSl9XyR7YmluYXJ5KGFycmF5LCBpZHggKyAwKX1gO1xufVxuXG5leHBvcnQgY2xhc3MgTENvbnRhaW5lckRlYnVnIGltcGxlbWVudHMgSUxDb250YWluZXJEZWJ1ZyB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgX3Jhd19sQ29udGFpbmVyOiBMQ29udGFpbmVyKSB7fVxuXG4gIGdldCBoYXNUcmFuc3BsYW50ZWRWaWV3cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fcmF3X2xDb250YWluZXJbSEFTX1RSQU5TUExBTlRFRF9WSUVXU107XG4gIH1cbiAgZ2V0IHZpZXdzKCk6IElMVmlld0RlYnVnW10ge1xuICAgIHJldHVybiB0aGlzLl9yYXdfbENvbnRhaW5lci5zbGljZShDT05UQUlORVJfSEVBREVSX09GRlNFVClcbiAgICAgICAgLm1hcCh0b0RlYnVnIGFzIChsOiBMVmlldykgPT4gSUxWaWV3RGVidWcpO1xuICB9XG4gIGdldCBwYXJlbnQoKTogSUxWaWV3RGVidWd8bnVsbCB7XG4gICAgcmV0dXJuIHRvRGVidWcodGhpcy5fcmF3X2xDb250YWluZXJbUEFSRU5UXSk7XG4gIH1cbiAgZ2V0IG1vdmVkVmlld3MoKTogTFZpZXdbXXxudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fcmF3X2xDb250YWluZXJbTU9WRURfVklFV1NdO1xuICB9XG4gIGdldCBob3N0KCk6IFJFbGVtZW50fFJDb21tZW50fExWaWV3IHtcbiAgICByZXR1cm4gdGhpcy5fcmF3X2xDb250YWluZXJbSE9TVF07XG4gIH1cbiAgZ2V0IG5hdGl2ZSgpOiBSQ29tbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX3Jhd19sQ29udGFpbmVyW05BVElWRV07XG4gIH1cbiAgZ2V0IG5leHQoKSB7XG4gICAgcmV0dXJuIHRvRGVidWcodGhpcy5fcmF3X2xDb250YWluZXJbTkVYVF0pO1xuICB9XG59XG4iXX0=