@angular/core
Version:
Angular - the core framework
485 lines • 60.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: packages/core/src/render3/view_engine_compatibility.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @license
* Copyright Google Inc. 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 { NgModuleRef as viewEngine_NgModuleRef } from '../linker/ng_module_factory';
import { addToArray, removeFromArray } from '../util/array_utils';
import { assertDefined, assertEqual, assertGreaterThan, assertLessThan } from '../util/assert';
import { assertLContainer } from './assert';
import { getParentInjectorLocation, NodeInjector } from './di';
import { addToViewTree, createLContainer, createLView, renderView } from './instructions/shared';
import { CONTAINER_HEADER_OFFSET, VIEW_REFS } from './interfaces/container';
import { isProceduralRenderer } from './interfaces/renderer';
import { isComponentHost, isLContainer, isLView, isRootView } from './interfaces/type_checks';
import { DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, PARENT, QUERIES, RENDERER, T_HOST, TVIEW } from './interfaces/view';
import { assertNodeOfPossibleTypes } from './node_assert';
import { addRemoveViewFromContainer, appendChild, detachView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView } from './node_manipulation';
import { getParentInjectorTNode } from './node_util';
import { getLView, getPreviousOrParentTNode } from './state';
import { getParentInjectorView, hasParentInjector } from './util/injector_utils';
import { getComponentLViewByIndex, getNativeByTNode, unwrapRNode, viewAttachedToContainer } from './util/view_utils';
import { ViewRef } from './view_ref';
/**
* Creates an ElementRef from the most recent node.
*
* @param {?} ElementRefToken
* @return {?} The ElementRef instance to use
*/
export function injectElementRef(ElementRefToken) {
return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getLView());
}
/** @type {?} */
let R3ElementRef;
/**
* Creates an ElementRef given a node.
*
* @param {?} ElementRefToken The ElementRef type
* @param {?} tNode The node for which you'd like an ElementRef
* @param {?} view The view to which the node belongs
* @return {?} The ElementRef instance to use
*/
export function createElementRef(ElementRefToken, tNode, view) {
if (!R3ElementRef) {
R3ElementRef = class ElementRef extends ElementRefToken {
};
}
return new R3ElementRef((/** @type {?} */ (getNativeByTNode(tNode, view))));
}
/** @type {?} */
let R3TemplateRef;
/**
* Creates a TemplateRef given a node.
*
* @template T
* @param {?} TemplateRefToken
* @param {?} ElementRefToken
* @return {?} The TemplateRef instance to use
*/
export function injectTemplateRef(TemplateRefToken, ElementRefToken) {
return createTemplateRef(TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getLView());
}
/**
* Creates a TemplateRef and stores it on the injector.
*
* @template T
* @param {?} TemplateRefToken The TemplateRef type
* @param {?} ElementRefToken The ElementRef type
* @param {?} hostTNode The node on which a TemplateRef is requested
* @param {?} hostView The view to which the node belongs
* @return {?} The TemplateRef instance or null if we can't create a TemplateRef on a given node type
*/
export function createTemplateRef(TemplateRefToken, ElementRefToken, hostTNode, hostView) {
if (!R3TemplateRef) {
R3TemplateRef = class TemplateRef extends TemplateRefToken {
/**
* @param {?} _declarationView
* @param {?} _declarationTContainer
* @param {?} elementRef
*/
constructor(_declarationView, _declarationTContainer, elementRef) {
super();
this._declarationView = _declarationView;
this._declarationTContainer = _declarationTContainer;
this.elementRef = elementRef;
}
/**
* @param {?} context
* @return {?}
*/
createEmbeddedView(context) {
/** @type {?} */
const embeddedTView = (/** @type {?} */ (this._declarationTContainer.tViews));
/** @type {?} */
const embeddedLView = createLView(this._declarationView, embeddedTView, context, 16 /* CheckAlways */, null, embeddedTView.node);
/** @type {?} */
const declarationLContainer = this._declarationView[this._declarationTContainer.index];
ngDevMode && assertLContainer(declarationLContainer);
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
/** @type {?} */
const declarationViewLQueries = this._declarationView[QUERIES];
if (declarationViewLQueries !== null) {
embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
}
renderView(embeddedTView, embeddedLView, context);
return new ViewRef(embeddedLView);
}
};
}
if (hostTNode.type === 0 /* Container */) {
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
return new R3TemplateRef(hostView, (/** @type {?} */ (hostTNode)), createElementRef(ElementRefToken, hostTNode, hostView));
}
else {
return null;
}
}
/** @type {?} */
let R3ViewContainerRef;
/**
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
* already exists, retrieves the existing ViewContainerRef.
*
* @param {?} ViewContainerRefToken
* @param {?} ElementRefToken
* @return {?} The ViewContainerRef instance to use
*/
export function injectViewContainerRef(ViewContainerRefToken, ElementRefToken) {
/** @type {?} */
const previousTNode = (/** @type {?} */ (getPreviousOrParentTNode()));
return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getLView());
}
/**
* Creates a ViewContainerRef and stores it on the injector.
*
* @param {?} ViewContainerRefToken The ViewContainerRef type
* @param {?} ElementRefToken The ElementRef type
* @param {?} hostTNode The node that is requesting a ViewContainerRef
* @param {?} hostView The view to which the node belongs
* @return {?} The ViewContainerRef instance to use
*/
export function createContainerRef(ViewContainerRefToken, ElementRefToken, hostTNode, hostView) {
if (!R3ViewContainerRef) {
R3ViewContainerRef = class ViewContainerRef extends ViewContainerRefToken {
/**
* @param {?} _lContainer
* @param {?} _hostTNode
* @param {?} _hostView
*/
constructor(_lContainer, _hostTNode, _hostView) {
super();
this._lContainer = _lContainer;
this._hostTNode = _hostTNode;
this._hostView = _hostView;
}
/**
* @return {?}
*/
get element() {
return createElementRef(ElementRefToken, this._hostTNode, this._hostView);
}
/**
* @return {?}
*/
get injector() {
return new NodeInjector(this._hostTNode, this._hostView);
}
/**
* @deprecated No replacement
* @return {?}
*/
get parentInjector() {
/** @type {?} */
const parentLocation = getParentInjectorLocation(this._hostTNode, this._hostView);
/** @type {?} */
const parentView = getParentInjectorView(parentLocation, this._hostView);
/** @type {?} */
const parentTNode = getParentInjectorTNode(parentLocation, this._hostView, this._hostTNode);
return !hasParentInjector(parentLocation) || parentTNode == null ?
new NodeInjector(null, this._hostView) :
new NodeInjector(parentTNode, parentView);
}
/**
* @return {?}
*/
clear() {
while (this.length > 0) {
this.remove(this.length - 1);
}
}
/**
* @param {?} index
* @return {?}
*/
get(index) {
return this._lContainer[VIEW_REFS] !== null && (/** @type {?} */ (this._lContainer[VIEW_REFS]))[index] || null;
}
/**
* @return {?}
*/
get length() {
return this._lContainer.length - CONTAINER_HEADER_OFFSET;
}
/**
* @template C
* @param {?} templateRef
* @param {?=} context
* @param {?=} index
* @return {?}
*/
createEmbeddedView(templateRef, context, index) {
/** @type {?} */
const viewRef = templateRef.createEmbeddedView(context || (/** @type {?} */ ({})));
this.insert(viewRef, index);
return viewRef;
}
/**
* @template C
* @param {?} componentFactory
* @param {?=} index
* @param {?=} injector
* @param {?=} projectableNodes
* @param {?=} ngModuleRef
* @return {?}
*/
createComponent(componentFactory, index, injector, projectableNodes, ngModuleRef) {
/** @type {?} */
const contextInjector = injector || this.parentInjector;
if (!ngModuleRef && ((/** @type {?} */ (componentFactory))).ngModule == null && contextInjector) {
// DO NOT REFACTOR. The code here used to have a `value || undefined` expression
// which seems to cause internal google apps to fail. This is documented in the
// following internal bug issue: go/b/142967802
/** @type {?} */
const result = contextInjector.get(viewEngine_NgModuleRef, null);
if (result) {
ngModuleRef = result;
}
}
/** @type {?} */
const componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
this.insert(componentRef.hostView, index);
return componentRef;
}
/**
* @param {?} viewRef
* @param {?=} index
* @return {?}
*/
insert(viewRef, index) {
/** @type {?} */
const lView = (/** @type {?} */ (((/** @type {?} */ (viewRef)))._lView));
/** @type {?} */
const tView = lView[TVIEW];
if (viewRef.destroyed) {
throw new Error('Cannot insert a destroyed View in a ViewContainer!');
}
this.allocateContainerIfNeeded();
if (viewAttachedToContainer(lView)) {
// If view is already attached, detach it first so we clean up references appropriately.
/** @type {?} */
const prevIdx = this.indexOf(viewRef);
// A view might be attached either to this or a different container. The `prevIdx` for
// those cases will be:
// equal to -1 for views attached to this ViewContainerRef
// >= 0 for views attached to a different ViewContainerRef
if (prevIdx !== -1) {
this.detach(prevIdx);
}
else {
/** @type {?} */
const prevLContainer = (/** @type {?} */ (lView[PARENT]));
ngDevMode &&
assertEqual(isLContainer(prevLContainer), true, 'An attached view should have its PARENT point to a container.');
// We need to re-create a R3ViewContainerRef instance since those are not stored on
// LView (nor anywhere else).
/** @type {?} */
const prevVCRef = new R3ViewContainerRef(prevLContainer, (/** @type {?} */ (prevLContainer[T_HOST])), prevLContainer[PARENT]);
prevVCRef.detach(prevVCRef.indexOf(viewRef));
}
}
/** @type {?} */
const adjustedIdx = this._adjustIndex(index);
insertView(tView, lView, this._lContainer, adjustedIdx);
/** @type {?} */
const beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer);
addRemoveViewFromContainer(tView, lView, true, beforeNode);
((/** @type {?} */ (viewRef))).attachToViewContainerRef(this);
addToArray((/** @type {?} */ (this._lContainer[VIEW_REFS])), adjustedIdx, viewRef);
return viewRef;
}
/**
* @param {?} viewRef
* @param {?} newIndex
* @return {?}
*/
move(viewRef, newIndex) {
if (viewRef.destroyed) {
throw new Error('Cannot move a destroyed View in a ViewContainer!');
}
return this.insert(viewRef, newIndex);
}
/**
* @param {?} viewRef
* @return {?}
*/
indexOf(viewRef) {
/** @type {?} */
const viewRefsArr = this._lContainer[VIEW_REFS];
return viewRefsArr !== null ? viewRefsArr.indexOf(viewRef) : -1;
}
/**
* @param {?=} index
* @return {?}
*/
remove(index) {
this.allocateContainerIfNeeded();
/** @type {?} */
const adjustedIdx = this._adjustIndex(index, -1);
removeView(this._lContainer, adjustedIdx);
removeFromArray((/** @type {?} */ (this._lContainer[VIEW_REFS])), adjustedIdx);
}
/**
* @param {?=} index
* @return {?}
*/
detach(index) {
this.allocateContainerIfNeeded();
/** @type {?} */
const adjustedIdx = this._adjustIndex(index, -1);
/** @type {?} */
const view = detachView(this._lContainer, adjustedIdx);
/** @type {?} */
const wasDetached = view && removeFromArray((/** @type {?} */ (this._lContainer[VIEW_REFS])), adjustedIdx) != null;
return wasDetached ? new ViewRef((/** @type {?} */ (view))) : null;
}
/**
* @private
* @param {?=} index
* @param {?=} shift
* @return {?}
*/
_adjustIndex(index, shift = 0) {
if (index == null) {
return this.length + shift;
}
if (ngDevMode) {
assertGreaterThan(index, -1, `ViewRef index must be positive, got ${index}`);
// +1 because it's legal to insert at the end.
assertLessThan(index, this.length + 1 + shift, 'index');
}
return index;
}
/**
* @private
* @return {?}
*/
allocateContainerIfNeeded() {
if (this._lContainer[VIEW_REFS] === null) {
this._lContainer[VIEW_REFS] = [];
}
}
};
}
ngDevMode &&
assertNodeOfPossibleTypes(hostTNode, 0 /* Container */, 3 /* Element */, 4 /* ElementContainer */);
/** @type {?} */
let lContainer;
/** @type {?} */
const slotValue = hostView[hostTNode.index];
if (isLContainer(slotValue)) {
// If the host is a container, we don't need to create a new LContainer
lContainer = slotValue;
}
else {
/** @type {?} */
let commentNode;
// If the host is an element container, the native host element is guaranteed to be a
// comment and we can reuse that comment as anchor element for the new LContainer.
// The comment node in question is already part of the DOM structure so we don't need to append
// it again.
if (hostTNode.type === 4 /* ElementContainer */) {
commentNode = (/** @type {?} */ (unwrapRNode(slotValue)));
}
else {
ngDevMode && ngDevMode.rendererCreateComment++;
commentNode = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
// A `ViewContainerRef` can be injected by the root (topmost / bootstrapped) component. In
// this case we can't use TView / TNode data structures to insert container's marker node
// (both a parent of a comment node and the comment node itself are not part of any view). In
// this specific case we use low-level DOM manipulation to insert container's marker (comment)
// node.
if (isRootView(hostView)) {
/** @type {?} */
const renderer = hostView[RENDERER];
/** @type {?} */
const hostNative = (/** @type {?} */ (getNativeByTNode(hostTNode, hostView)));
/** @type {?} */
const parentOfHostNative = nativeParentNode(renderer, hostNative);
nativeInsertBefore(renderer, (/** @type {?} */ (parentOfHostNative)), commentNode, nativeNextSibling(renderer, hostNative));
}
else {
appendChild(hostView[TVIEW], hostView, commentNode, hostTNode);
}
}
hostView[hostTNode.index] = lContainer =
createLContainer(slotValue, hostView, commentNode, hostTNode);
addToViewTree(hostView, lContainer);
}
return new R3ViewContainerRef(lContainer, hostTNode, hostView);
}
/**
* Returns a ChangeDetectorRef (a.k.a. a ViewRef)
* @param {?=} isPipe
* @return {?}
*/
export function injectChangeDetectorRef(isPipe = false) {
return createViewRef(getPreviousOrParentTNode(), getLView(), isPipe);
}
/**
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
*
* @param {?} tNode The node that is requesting a ChangeDetectorRef
* @param {?} lView The view to which the node belongs
* @param {?} isPipe Whether the view is being injected into a pipe.
* @return {?} The ChangeDetectorRef to use
*/
function createViewRef(tNode, lView, isPipe) {
// `isComponentView` will be true for Component and Directives (but not for Pipes).
// See https://github.com/angular/angular/pull/33072 for proper fix
/** @type {?} */
const isComponentView = !isPipe && isComponentHost(tNode);
if (isComponentView) {
// The LView represents the location where the component is declared.
// Instead we want the LView for the component View and so we need to look it up.
/** @type {?} */
const componentView = getComponentLViewByIndex(tNode.index, lView);
return new ViewRef(componentView, componentView);
}
else if (tNode.type === 3 /* Element */ || tNode.type === 0 /* Container */ ||
tNode.type === 4 /* ElementContainer */ || tNode.type === 5 /* IcuContainer */) {
// The LView represents the location where the injection is requested from.
// We need to locate the containing LView (in case where the `lView` is an embedded view)
/** @type {?} */
const hostComponentView = lView[DECLARATION_COMPONENT_VIEW];
return new ViewRef(hostComponentView, lView);
}
return (/** @type {?} */ (null));
}
/**
* Returns a Renderer2 (or throws when application was bootstrapped with Renderer3)
* @param {?} view
* @return {?}
*/
function getOrCreateRenderer2(view) {
/** @type {?} */
const renderer = view[RENDERER];
if (isProceduralRenderer(renderer)) {
return (/** @type {?} */ (renderer));
}
else {
throw new Error('Cannot inject Renderer2 when the application uses Renderer3!');
}
}
/**
* Injects a Renderer2 for the current component.
* @return {?}
*/
export function injectRenderer2() {
// We need the Renderer to be based on the component that it's being injected into, however since
// DI happens before we've entered its view, `getLView` will return the parent view instead.
/** @type {?} */
const lView = getLView();
/** @type {?} */
const tNode = getPreviousOrParentTNode();
/** @type {?} */
const nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
return getOrCreateRenderer2(isLView(nodeAtIndex) ? nodeAtIndex : lView);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld19lbmdpbmVfY29tcGF0aWJpbGl0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvdmlld19lbmdpbmVfY29tcGF0aWJpbGl0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFZQSxPQUFPLEVBQUMsV0FBVyxJQUFJLHNCQUFzQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFLbEYsT0FBTyxFQUFDLFVBQVUsRUFBRSxlQUFlLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRSxPQUFPLEVBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3RixPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDMUMsT0FBTyxFQUFDLHlCQUF5QixFQUFFLFlBQVksRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUM3RCxPQUFPLEVBQUMsYUFBYSxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUMvRixPQUFPLEVBQUMsdUJBQXVCLEVBQWMsU0FBUyxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFdEYsT0FBTyxFQUFDLG9CQUFvQixFQUFxQixNQUFNLHVCQUF1QixDQUFDO0FBQy9FLE9BQU8sRUFBQyxlQUFlLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RixPQUFPLEVBQUMsMEJBQTBCLEVBQUUsc0JBQXNCLEVBQXFCLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUN6SixPQUFPLEVBQUMseUJBQXlCLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDeEQsT0FBTyxFQUFDLDBCQUEwQixFQUFFLFdB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QyxRQUFRLENBQUMsRUFBRTtRQUNsQyxPQUFPLG1CQUFBLFFBQVEsRUFBYSxDQUFDO0tBQzlCO1NBQU07UUFDTCxNQUFNLElBQUksS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUM7S0FDakY7QUFDSCxDQUFDOzs7OztBQUdELE1BQU0sVUFBVSxlQUFlOzs7O1VBR3ZCLEtBQUssR0FBRyxRQUFRLEVBQUU7O1VBQ2xCLEtBQUssR0FBRyx3QkFBd0IsRUFBRTs7VUFDbEMsV0FBVyxHQUFHLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDO0lBQ2hFLE9BQU8sb0JBQW9CLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7Q2hhbmdlRGV0ZWN0b3JSZWYgYXMgVmlld0VuZ2luZV9DaGFuZ2VEZXRlY3RvclJlZn0gZnJvbSAnLi4vY2hhbmdlX2RldGVjdGlvbi9jaGFuZ2VfZGV0ZWN0b3JfcmVmJztcbmltcG9ydCB7SW5qZWN0b3J9IGZyb20gJy4uL2RpL2luamVjdG9yJztcbmltcG9ydCB7Q29tcG9uZW50RmFjdG9yeSBhcyB2aWV3RW5naW5lX0NvbXBvbmVudEZhY3RvcnksIENvbXBvbmVudFJlZiBhcyB2aWV3RW5naW5lX0NvbXBvbmVudFJlZn0gZnJvbSAnLi4vbGlua2VyL2NvbXBvbmVudF9mYWN0b3J5JztcbmltcG9ydCB7RWxlbWVudFJlZiBhcyBWaWV3RW5naW5lX0VsZW1lbnRSZWZ9IGZyb20gJy4uL2xpbmtlci9lbGVtZW50X3JlZic7XG5pbXBvcnQge05nTW9kdWxlUmVmIGFzIHZpZXdFbmdpbmVfTmdNb2R1bGVSZWZ9IGZyb20gJy4uL2xpbmtlci9uZ19tb2R1bGVfZmFjdG9yeSc7XG5pbXBvcnQge1RlbXBsYXRlUmVmIGFzIFZpZXdFbmdpbmVfVGVtcGxhdGVSZWZ9IGZyb20gJy4uL2xpbmtlci90ZW1wbGF0ZV9yZWYnO1xuaW1wb3J0IHtWaWV3Q29udGFpbmVyUmVmIGFzIFZpZXdFbmdpbmVfVmlld0NvbnRhaW5lclJlZn0gZnJvbSAnLi4vbGlua2VyL3ZpZXdfY29udGFpbmVyX3JlZic7XG5pbXBvcnQge0VtYmVkZGVkVmlld1JlZiBhcyB2aWV3RW5naW5lX0VtYmVkZGVkVmlld1JlZiwgVmlld1JlZiBhcyB2aWV3RW5naW5lX1ZpZXdSZWZ9IGZyb20gJy4uL2xpbmtlci92aWV3X3JlZic7XG5pbXBvcnQge1JlbmRlcmVyMn0gZnJvbSAnLi4vcmVuZGVyL2FwaSc7XG5pbXBvcnQge2FkZFRvQXJyYXksIHJlbW92ZUZyb21BcnJheX0gZnJvbSAnLi4vdXRpbC9hcnJheV91dGlscyc7XG5pbXBvcnQge2Fzc2VydERlZmluZWQsIGFzc2VydEVxdWFsLCBhc3NlcnRHcmVhdGVyVGhhbiwgYXNzZXJ0TGVzc1RoYW59IGZyb20gJy4uL3V0aWwvYXNzZXJ0JztcblxuaW1wb3J0IHthc3NlcnRMQ29udGFpbmVyfSBmcm9tICcuL2Fzc2VydCc7XG5pbXBvcnQge2dldFBhcmVudEluamVjdG9yTG9jYXRpb24sIE5vZGVJbmplY3Rvcn0gZnJvbSAnLi9kaSc7XG5pbXBvcnQge2FkZFRvVmlld1RyZWUsIGNyZWF0ZUxDb250YWluZXIsIGNyZWF0ZUxWaWV3LCByZW5kZXJWaWV3fSBmcm9tICcuL2luc3RydWN0aW9ucy9zaGFyZWQnO1xuaW1wb3J0IHtDT05UQUlORVJfSEVBREVSX09GRlNFVCwgTENvbnRhaW5lciwgVklFV19SRUZTfSBmcm9tICcuL2ludGVyZmFjZXMvY29udGFpbmVyJztcbmltcG9ydCB7VENvbnRhaW5lck5vZGUsIFREaXJlY3RpdmVIb3N0Tm9kZSwgVEVsZW1lbnRDb250YWluZXJOb2RlLCBURWxlbWVudE5vZGUsIFROb2RlLCBUTm9kZVR5cGUsIFRWaWV3Tm9kZX0gZnJvbSAnLi9pbnRlcmZhY2VzL25vZGUnO1xuaW1wb3J0IHtpc1Byb2NlZHVyYWxSZW5kZXJlciwgUkNvbW1lbnQsIFJFbGVtZW50fSBmcm9tICcuL2ludGVyZmFjZXMvcmVuZGVyZXInO1xuaW1wb3J0IHtpc0NvbXBvbmVudEhvc3QsIGlzTENvbnRhaW5lciwgaXNMVmlldywgaXNSb290Vmlld30gZnJvbSAnLi9pbnRlcmZhY2VzL3R5cGVfY2hlY2tzJztcbmltcG9ydCB7REVDTEFSQVRJT05fQ09NUE9ORU5UX1ZJRVcsIERFQ0xBUkFUSU9OX0xDT05UQUlORVIsIExWaWV3LCBMVmlld0ZsYWdzLCBQQVJFTlQsIFFVRVJJRVMsIFJFTkRFUkVSLCBUX0hPU1QsIFRWSUVXLCBUVmlld30gZnJvbSAnLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHthc3NlcnROb2RlT2ZQb3NzaWJsZVR5cGVzfSBmcm9tICcuL25vZGVfYXNzZXJ0JztcbmltcG9ydCB7YWRkUmVtb3ZlVmlld0Zyb21Db250YWluZXIsIGFwcGVuZENoaWxkLCBkZXRhY2hWaWV3LCBnZXRCZWZvcmVOb2RlRm9yVmlldywgaW5zZXJ0VmlldywgbmF0aXZlSW5zZXJ0QmVmb3JlLCBuYXRpdmVOZXh0U2libGluZywgbmF0aXZlUGFyZW50Tm9kZSwgcmVtb3ZlVmlld30gZnJvbSAnLi9ub2RlX21hbmlwdWxhdGlvbic7XG5pbXBvcnQge2dldFBhcmVudEluamVjdG9yVE5vZGV9IGZyb20gJy4vbm9kZV91dGlsJztcbmltcG9ydCB7Z2V0TFZpZXcsIGdldFByZXZpb3VzT3JQYXJlbnRUTm9kZX0gZnJvbSAnLi9zdGF0ZSc7XG5pbXBvcnQge2dldFBhcmVudEluamVjdG9yVmlldywgaGFzUGFyZW50SW5qZWN0b3J9IGZyb20gJy4vdXRpbC9pbmplY3Rvcl91dGlscyc7XG5pbXBvcnQge2dldENvbXBvbmVudExWaWV3QnlJbmRleCwgZ2V0TmF0aXZlQnlUTm9kZSwgdW53cmFwUk5vZGUsIHZpZXdBdHRhY2hlZFRvQ29udGFpbmVyfSBmcm9tICcuL3V0aWwvdmlld191dGlscyc7XG5pbXBvcnQge1ZpZXdSZWZ9IGZyb20gJy4vdmlld19yZWYnO1xuXG5cblxuLyoqXG4gKiBDcmVhdGVzIGFuIEVsZW1lbnRSZWYgZnJvbSB0aGUgbW9zdCByZWNlbnQgbm9kZS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgRWxlbWVudFJlZiBpbnN0YW5jZSB0byB1c2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdEVsZW1lbnRSZWYoRWxlbWVudFJlZlRva2VuOiB0eXBlb2YgVmlld0VuZ2luZV9FbGVtZW50UmVmKTpcbiAgICBWaWV3RW5naW5lX0VsZW1lbnRSZWYge1xuICByZXR1cm4gY3JlYXRlRWxlbWVudFJlZihFbGVtZW50UmVmVG9rZW4sIGdldFByZXZpb3VzT3JQYXJlbnRUTm9kZSgpLCBnZXRMVmlldygpKTtcbn1cblxubGV0IFIzRWxlbWVudFJlZjoge25ldyAobmF0aXZlOiBSRWxlbWVudHxSQ29tbWVudCk6IFZpZXdFbmdpbmVfRWxlbWVudFJlZn07XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBFbGVtZW50UmVmIGdpdmVuIGEgbm9kZS5cbiAqXG4gKiBAcGFyYW0gRWxlbWVudFJlZlRva2VuIFRoZSBFbGVtZW50UmVmIHR5cGVcbiAqIEBwYXJhbSB0Tm9kZSBUaGUgbm9kZSBmb3Igd2hpY2ggeW91J2QgbGlrZSBhbiBFbGVtZW50UmVmXG4gKiBAcGFyYW0gdmlldyBUaGUgdmlldyB0byB3aGljaCB0aGUgbm9kZSBiZWxvbmdzXG4gKiBAcmV0dXJucyBUaGUgRWxlbWVudFJlZiBpbnN0YW5jZSB0byB1c2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRSZWYoXG4gICAgRWxlbWVudFJlZlRva2VuOiB0eXBlb2YgVmlld0VuZ2luZV9FbGVtZW50UmVmLCB0Tm9kZTogVE5vZGUsXG4gICAgdmlldzogTFZpZXcpOiBWaWV3RW5naW5lX0VsZW1lbnRSZWYge1xuICBpZiAoIVIzRWxlbWVudFJlZikge1xuICAgIFIzRWxlbWVudFJlZiA9IGNsYXNzIEVsZW1lbnRSZWYgZXh0ZW5kcyBFbGVtZW50UmVmVG9rZW4ge307XG4gIH1cbiAgcmV0dXJuIG5ldyBSM0VsZW1lbnRSZWYoZ2V0TmF0aXZlQnlUTm9kZSh0Tm9kZSwgdmlldykgYXMgUkVsZW1lbnQpO1xufVxuXG5sZXQgUjNUZW1wbGF0ZVJlZjoge1xuICBuZXcgKF9kZWNsYXJhdGlvblBhcmVudFZpZXc6IExWaWV3LCBob3N0VE5vZGU6IFRDb250YWluZXJOb2RlLCBlbGVtZW50UmVmOiBWaWV3RW5naW5lX0VsZW1lbnRSZWYpOlxuICAgICAgVmlld0VuZ2luZV9UZW1wbGF0ZVJlZjxhbnk+XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBUZW1wbGF0ZVJlZiBnaXZlbiBhIG5vZGUuXG4gKlxuICogQHJldHVybnMgVGhlIFRlbXBsYXRlUmVmIGluc3RhbmNlIHRvIHVzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0VGVtcGxhdGVSZWY8VD4oXG4gICAgVGVtcGxhdGVSZWZUb2tlbjogdHlwZW9mIFZpZXdFbmdpbmVfVGVtcGxhdGVSZWYsXG4gICAgRWxlbWVudFJlZlRva2VuOiB0eXBlb2YgVmlld0VuZ2luZV9FbGVtZW50UmVmKTogVmlld0VuZ2luZV9UZW1wbGF0ZVJlZjxUPnxudWxsIHtcbiAgcmV0dXJuIGNyZWF0ZVRlbXBsYXRlUmVmPFQ+KFxuICAgICAgVGVtcGxhdGVSZWZUb2tlbiwgRWxlbWVudFJlZlRva2VuLCBnZXRQcmV2aW91c09yUGFyZW50VE5vZGUoKSwgZ2V0TFZpZXcoKSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIFRlbXBsYXRlUmVmIGFuZCBzdG9yZXMgaXQgb24gdGhlIGluamVjdG9yLlxuICpcbiAqIEBwYXJhbSBUZW1wbGF0ZVJlZlRva2VuIFRoZSBUZW1wbGF0ZVJlZiB0eXBlXG4gKiBAcGFyYW0gRWxlbWVudFJlZlRva2VuIFRoZSBFbGVtZW50UmVmIHR5cGVcbiAqIEBwYXJhbSBob3N0VE5vZGUgVGhlIG5vZGUgb24gd2hpY2ggYSBUZW1wbGF0ZVJlZiBpcyByZXF1ZXN0ZWRcbiAqIEBwYXJhbSBob3N0VmlldyBUaGUgdmlldyB0byB3aGljaCB0aGUgbm9kZSBiZWxvbmdzXG4gKiBAcmV0dXJucyBUaGUgVGVtcGxhdGVSZWYgaW5zdGFuY2Ugb3IgbnVsbCBpZiB3ZSBjYW4ndCBjcmVhdGUgYSBUZW1wbGF0ZVJlZiBvbiBhIGdpdmVuIG5vZGUgdHlwZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVGVtcGxhdGVSZWY8VD4oXG4gICAgVGVtcGxhdGVSZWZUb2tlbjogdHlwZW9mIFZpZXdFbmdpbmVfVGVtcGxhdGVSZWYsIEVsZW1lbnRSZWZUb2tlbjogdHlwZW9mIFZpZXdFbmdpbmVfRWxlbWVudFJlZixcbiAgICBob3N0VE5vZGU6IFROb2RlLCBob3N0VmlldzogTFZpZXcpOiBWaWV3RW5naW5lX1RlbXBsYXRlUmVmPFQ+fG51bGwge1xuICBpZiAoIVIzVGVtcGxhdGVSZWYpIHtcbiAgICBSM1RlbXBsYXRlUmVmID0gY2xhc3MgVGVtcGxhdGVSZWY8VD4gZXh0ZW5kcyBUZW1wbGF0ZVJlZlRva2VuPFQ+e1xuICAgICAgY29uc3RydWN0b3IoXG4gICAgICAgICAgcHJpdmF0ZSBfZGVjbGFyYXRpb25WaWV3OiBMVmlldywgcHJpdmF0ZSBfZGVjbGFyYXRpb25UQ29udGFpbmVyOiBUQ29udGFpbmVyTm9kZSxcbiAgICAgICAgICByZWFkb25seSBlbGVtZW50UmVmOiBWaWV3RW5naW5lX0VsZW1lbnRSZWYpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgIH1cblxuICAgICAgY3JlYXRlRW1iZWRkZWRWaWV3KGNvbnRleHQ6IFQpOiB2aWV3RW5naW5lX0VtYmVkZGVkVmlld1JlZjxUPiB7XG4gICAgICAgIGNvbnN0IGVtYmVkZGVkVFZpZXcgPSB0aGlzLl9kZWNsYXJhdGlvblRDb250YWluZXIudFZpZXdzIGFzIFRWaWV3O1xuICAgICAgICBjb25zdCBlbWJlZGRlZExWaWV3ID0gY3JlYXRlTFZpZXcoXG4gICAgICAgICAgICB0aGlzLl9kZWNsYXJhdGlvblZpZXcsIGVtYmVkZGVkVFZpZXcsIGNvbnRleHQsIExWaWV3RmxhZ3MuQ2hlY2tBbHdheXMsIG51bGwsXG4gICAgICAgICAgICBlbWJlZGRlZFRWaWV3Lm5vZGUpO1xuXG4gICAgICAgIGNvbnN0IGRlY2xhcmF0aW9uTENvbnRhaW5lciA9IHRoaXMuX2RlY2xhcmF0aW9uVmlld1t0aGlzLl9kZWNsYXJhdGlvblRDb250YWluZXIuaW5kZXhdO1xuICAgICAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TENvbnRhaW5lcihkZWNsYXJhdGlvbkxDb250YWluZXIpO1xuICAgICAgICBlbWJlZGRlZExWaWV3W0RFQ0xBUkFUSU9OX0xDT05UQUlORVJdID0gZGVjbGFyYXRpb25MQ29udGFpbmVyO1xuXG4gICAgICAgIGNvbnN0IGRlY2xhcmF0aW9uVmlld0xRdWVyaWVzID0gdGhpcy5fZGVjbGFyYXRpb25WaWV3W1FVRVJJRVNdO1xuICAgICAgICBpZiAoZGVjbGFyYXRpb25WaWV3TFF1ZXJpZXMgIT09IG51bGwpIHtcbiAgICAgICAgICBlbWJlZGRlZExWaWV3W1FVRVJJRVNdID0gZGVjbGFyYXRpb25WaWV3TFF1ZXJpZXMuY3JlYXRlRW1iZWRkZWRWaWV3KGVtYmVkZGVkVFZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVuZGVyVmlldyhlbWJlZGRlZFRWaWV3LCBlbWJlZGRlZExWaWV3LCBjb250ZXh0KTtcblxuICAgICAgICByZXR1cm4gbmV3IFZpZXdSZWY8VD4oZW1iZWRkZWRMVmlldyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGlmIChob3N0VE5vZGUudHlwZSA9PT0gVE5vZGVUeXBlLkNvbnRhaW5lcikge1xuICAgIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKGhvc3RUTm9kZS50Vmlld3MsICdUVmlldyBtdXN0IGJlIGFsbG9jYXRlZCcpO1xuICAgIHJldHVybiBuZXcgUjNUZW1wbGF0ZVJlZihcbiAgICAgICAgaG9zdFZpZXcsIGhvc3RUTm9kZSBhcyBUQ29udGFpbmVyTm9kZSxcbiAgICAgICAgY3JlYXRlRWxlbWVudFJlZihFbGVtZW50UmVmVG9rZW4sIGhvc3RUTm9kZSwgaG9zdFZpZXcpKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5sZXQgUjNWaWV3Q29udGFpbmVyUmVmOiB7XG4gIG5ldyAoXG4gICAgICBsQ29udGFpbmVyOiBMQ29udGFpbmVyLCBob3N0VE5vZGU6IFRFbGVtZW50Tm9kZXxUQ29udGFpbmVyTm9kZXxURWxlbWVudENvbnRhaW5lck5vZGUsXG4gICAgICBob3N0VmlldzogTFZpZXcpOiBWaWV3RW5naW5lX1ZpZXdDb250YWluZXJSZWZcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIFZpZXdDb250YWluZXJSZWYgYW5kIHN0b3JlcyBpdCBvbiB0aGUgaW5qZWN0b3IuIE9yLCBpZiB0aGUgVmlld0NvbnRhaW5lclJlZlxuICogYWxyZWFkeSBleGlzdHMsIHJldHJpZXZlcyB0aGUgZXhpc3RpbmcgVmlld0NvbnRhaW5lclJlZi5cbiAqXG4gKiBAcmV0dXJucyBUaGUgVmlld0NvbnRhaW5lclJlZiBpbnN0YW5jZSB0byB1c2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdFZpZXdDb250YWluZXJSZWYoXG4gICAgVmlld0NvbnRhaW5lclJlZlRva2VuOiB0eXBlb2YgVmlld0VuZ2luZV9WaWV3Q29udGFpbmVyUmVmLFxuICAgIEVsZW1lbnRSZWZUb2tlbjogdHlwZW9mIFZpZXdFbmdpbmVfRWxlbWVudFJlZik6IFZpZXdFbmdpbmVfVmlld0NvbnRhaW5lclJlZiB7XG4gIGNvbnN0IHByZXZpb3VzVE5vZGUgPVxuICAgICAgZ2V0UHJldmlvdXNPclBhcmVudFROb2RlKCkgYXMgVEVsZW1lbnROb2RlIHwgVEVsZW1lbnRDb250YWluZXJOb2RlIHwgVENvbnRhaW5lck5vZGU7XG4gIHJldHVybiBjcmVhdGVDb250YWluZXJSZWYoVmlld0NvbnRhaW5lclJlZlRva2VuLCBFbGVtZW50UmVmVG9rZW4sIHByZXZpb3VzVE5vZGUsIGdldExWaWV3KCkpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBWaWV3Q29udGFpbmVyUmVmIGFuZCBzdG9yZXMgaXQgb24gdGhlIGluamVjdG9yLlxuICpcbiAqIEBwYXJhbSBWaWV3Q29udGFpbmVyUmVmVG9rZW4gVGhlIFZpZXdDb250YWluZXJSZWYgdHlwZVxuICogQHBhcmFtIEVsZW1lbnRSZWZUb2tlbiBUaGUgRWxlbWVudFJlZiB0eXBlXG4gKiBAcGFyYW0gaG9zdFROb2RlIFRoZSBub2RlIHRoYXQgaXMgcmVxdWVzdGluZyBhIFZpZXdDb250YWluZXJSZWZcbiAqIEBwYXJhbSBob3N0VmlldyBUaGUgdmlldyB0byB3aGljaCB0aGUgbm9kZSBiZWxvbmdzXG4gKiBAcmV0dXJucyBUaGUgVmlld0NvbnRhaW5lclJlZiBpbnN0YW5jZSB0byB1c2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRhaW5lclJlZihcbiAgICBWaWV3Q29udGFpbmVyUmVmVG9rZW46IHR5cGVvZiBWaWV3RW5naW5lX1ZpZXdDb250YWluZXJSZWYsXG4gICAgRWxlbWVudFJlZlRva2VuOiB0eXBlb2YgVmlld0VuZ2luZV9FbGVtZW50UmVmLFxuICAgIGhvc3RUTm9kZTogVEVsZW1lbnROb2RlfFRDb250YWluZXJOb2RlfFRFbGVtZW50Q29udGFpbmVyTm9kZSxcbiAgICBob3N0VmlldzogTFZpZXcpOiBWaWV3RW5naW5lX1ZpZXdDb250YWluZXJSZWYge1xuICBpZiAoIVIzVmlld0NvbnRhaW5lclJlZikge1xuICAgIFIzVmlld0NvbnRhaW5lclJlZiA9IGNsYXNzIFZpZXdDb250YWluZXJSZWYgZXh0ZW5kcyBWaWV3Q29udGFpbmVyUmVmVG9rZW4ge1xuICAgICAgY29uc3RydWN0b3IoXG4gICAgICAgICAgcHJpdmF0ZSBfbENvbnRhaW5lcjogTENvbnRhaW5lcixcbiAgICAgICAgICBwcml2YXRlIF9ob3N0VE5vZGU6IFRFbGVtZW50Tm9kZXxUQ29udGFpbmVyTm9kZXxURWxlbWVudENvbnRhaW5lck5vZGUsXG4gICAgICAgICAgcHJpdmF0ZSBfaG9zdFZpZXc6IExWaWV3KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICB9XG5cbiAgICAgIGdldCBlbGVtZW50KCk6IFZpZXdFbmdpbmVfRWxlbWVudFJlZiB7XG4gICAgICAgIHJldHVybiBjcmVhdGVFbGVtZW50UmVmKEVsZW1lbnRSZWZUb2tlbiwgdGhpcy5faG9zdFROb2RlLCB0aGlzLl9ob3N0Vmlldyk7XG4gICAgICB9XG5cbiAgICAgIGdldCBpbmplY3RvcigpOiBJbmplY3RvciB7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZUluamVjdG9yKHRoaXMuX2hvc3RUTm9kZSwgdGhpcy5faG9zdFZpZXcpO1xuICAgICAgfVxuXG4gICAgICAvKiogQGRlcHJlY2F0ZWQgTm8gcmVwbGFjZW1lbnQgKi9cbiAgICAgIGdldCBwYXJlbnRJbmplY3RvcigpOiBJbmplY3RvciB7XG4gICAgICAgIGNvbnN0IHBhcmVudExvY2F0aW9uID0gZ2V0UGFyZW50SW5qZWN0b3JMb2NhdGlvbih0aGlzLl9ob3N0VE5vZGUsIHRoaXMuX2hvc3RWaWV3KTtcbiAgICAgICAgY29uc3QgcGFyZW50VmlldyA9IGdldFBhcmVudEluamVjdG9yVmlldyhwYXJlbnRMb2NhdGlvbiwgdGhpcy5faG9zdFZpZXcpO1xuICAgICAgICBjb25zdCBwYXJlbnRUTm9kZSA9IGdldFBhcmVudEluamVjdG9yVE5vZGUocGFyZW50TG9jYXRpb24sIHRoaXMuX2hvc3RWaWV3LCB0aGlzLl9ob3N0VE5vZGUpO1xuXG4gICAgICAgIHJldHVybiAhaGFzUGFyZW50SW5qZWN0b3IocGFyZW50TG9jYXRpb24pIHx8IHBhcmVudFROb2RlID09IG51bGwgP1xuICAgICAgICAgICAgbmV3IE5vZGVJbmplY3RvcihudWxsLCB0aGlzLl9ob3N0VmlldykgOlxuICAgICAgICAgICAgbmV3IE5vZGVJbmplY3RvcihwYXJlbnRUTm9kZSwgcGFyZW50Vmlldyk7XG4gICAgICB9XG5cbiAgICAgIGNsZWFyKCk6IHZvaWQge1xuICAgICAgICB3aGlsZSAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmUodGhpcy5sZW5ndGggLSAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBnZXQoaW5kZXg6IG51bWJlcik6IHZpZXdFbmdpbmVfVmlld1JlZnxudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xDb250YWluZXJbVklFV19SRUZTXSAhPT0gbnVsbCAmJiB0aGlzLl9sQ29udGFpbmVyW1ZJRVdfUkVGU10hW2luZGV4XSB8fCBudWxsO1xuICAgICAgfVxuXG4gICAgICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sQ29udGFpbmVyLmxlbmd0aCAtIENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUO1xuICAgICAgfVxuXG4gICAgICBjcmVhdGVFbWJlZGRlZFZpZXc8Qz4odGVtcGxhdGVSZWY6IFZpZXdFbmdpbmVfVGVtcGxhdGVSZWY8Qz4sIGNvbnRleHQ/OiBDLCBpbmRleD86IG51bWJlcik6XG4gICAgICAgICAgdmlld0VuZ2luZV9FbWJlZGRlZFZpZXdSZWY8Qz4ge1xuICAgICAgICBjb25zdCB2aWV3UmVmID0gdGVtcGxhdGVSZWYuY3JlYXRlRW1iZWRkZWRWaWV3KGNvbnRleHQgfHwgPGFueT57fSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0KHZpZXdSZWYsIGluZGV4KTtcbiAgICAgICAgcmV0dXJuIHZpZXdSZWY7XG4gICAgICB9XG5cbiAgICAgIGNyZWF0ZUNvbXBvbmVudDxDPihcbiAgICAgICAgICBjb21wb25lbnRGYWN0b3J5OiB2aWV3RW5naW5lX0NvbXBvbmVudEZhY3Rvcnk8Qz4sIGluZGV4PzogbnVtYmVyfHVuZGVmaW5lZCxcbiAgICAgICAgICBpbmplY3Rvcj86IEluamVjdG9yfHVuZGVmaW5lZCwgcHJvamVjdGFibGVOb2Rlcz86IGFueVtdW118dW5kZWZpbmVkLFxuICAgICAgICAgIG5nTW9kdWxlUmVmPzogdmlld0VuZ2luZV9OZ01vZHVsZVJlZjxhbnk+fHVuZGVmaW5lZCk6IHZpZXdFbmdpbmVfQ29tcG9uZW50UmVmPEM+IHtcbiAgICAgICAgY29uc3QgY29udGV4dEluamVjdG9yID0gaW5qZWN0b3IgfHwgdGhpcy5wYXJlbnRJbmplY3RvcjtcbiAgICAgICAgaWYgKCFuZ01vZHVsZVJlZiAmJiAoY29tcG9uZW50RmFjdG9yeSBhcyBhbnkpLm5nTW9kdWxlID09IG51bGwgJiYgY29udGV4dEluamVjdG9yKSB7XG4gICAgICAgICAgLy8gRE8gTk9UIFJFRkFDVE9SLiBUaGUgY29kZSBoZXJlIHVzZWQgdG8gaGF2ZSBhIGB2YWx1ZSB8fCB1bmRlZmluZWRgIGV4cHJlc3Npb25cbiAgICAgICAgICAvLyB3aGljaCBzZWVtcyB0byBjYXVzZSBpbnRlcm5hbCBnb29nbGUgYXBwcyB0byBmYWlsLiBUaGlzIGlzIGRvY3VtZW50ZWQgaW4gdGhlXG4gICAgICAgICAgLy8gZm9sbG93aW5nIGludGVybmFsIGJ1ZyBpc3N1ZTogZ28vYi8xNDI5Njc4MDJcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb250ZXh0SW5qZWN0b3IuZ2V0KHZpZXdFbmdpbmVfTmdNb2R1bGVSZWYsIG51bGwpO1xuICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIG5nTW9kdWxlUmVmID0gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9XG4gICAgICAgICAgICBjb21wb25lbnRGYWN0b3J5LmNyZWF0ZShjb250ZXh0SW5qZWN0b3IsIHByb2plY3RhYmxlTm9kZXMsIHVuZGVmaW5lZCwgbmdNb2R1bGVSZWYpO1xuICAgICAgICB0aGlzLmluc2VydChjb21wb25lbnRSZWYuaG9zdFZpZXcsIGluZGV4KTtcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudFJlZjtcbiAgICAgIH1cblxuICAgICAgaW5zZXJ0KHZpZXdSZWY6IHZpZXdFbmdpbmVfVmlld1JlZiwgaW5kZXg/OiBudW1iZXIpOiB2aWV3RW5naW5lX1ZpZXdSZWYge1xuICAgICAgICBjb25zdCBsVmlldyA9ICh2aWV3UmVmIGFzIFZpZXdSZWY8YW55PikuX2xWaWV3ITtcbiAgICAgICAgY29uc3QgdFZpZXcgPSBsVmlld1tUVklFV107XG5cbiAgICAgICAgaWYgKHZpZXdSZWYuZGVzdHJveWVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgaW5zZXJ0IGEgZGVzdHJveWVkIFZpZXcgaW4gYSBWaWV3Q29udGFpbmVyIScpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5hbGxvY2F0ZUNvbnRhaW5lcklmTmVlZGVkKCk7XG5cbiAgICAgICAgaWYgKHZpZXdBdHRhY2hlZFRvQ29udGFpbmVyKGxWaWV3KSkge1xuICAgICAgICAgIC8vIElmIHZpZXcgaXMgYWxyZWFkeSBhdHRhY2hlZCwgZGV0YWNoIGl0IGZpcnN0IHNvIHdlIGNsZWFuIHVwIHJlZmVyZW5jZXMgYXBwcm9wcmlhdGVseS5cblxuICAgICAgICAgIGNvbnN0IHByZXZJZHggPSB0aGlzLmluZGV4T2Yodmlld1JlZik7XG5cbiAgICAgICAgICAvLyBBIHZpZXcgbWlnaHQgYmUgYXR0YWNoZWQgZWl0aGVyIHRvIHRoaXMgb3IgYSBkaWZmZXJlbnQgY29udGFpbmVyLiBUaGUgYHByZXZJZHhgIGZvclxuICAgICAgICAgIC8vIHRob3NlIGNhc2VzIHdpbGwgYmU6XG4gICAgICAgICAgLy8gZXF1YWwgdG8gLTE