@angular/core
Version:
Angular - the core framework
483 lines • 48.1 kB
JavaScript
/**
* @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 { assertDefined } from '../util/assert';
import { assertLViewOrUndefined } from './assert';
import { executeHooks } from './hooks';
import { BINDING_INDEX, CONTEXT, DECLARATION_VIEW, FLAGS, TVIEW } from './interfaces/view';
import { setCachedStylingContext } from './styling/state';
import { resetPreOrderHookFlags } from './util/view_utils';
/**
* Store the element depth count. This is used to identify the root elements of the template
* so that we can than attach `LView` to only those elements.
*/
var elementDepthCount;
export function getElementDepthCount() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return elementDepthCount;
}
export function increaseElementDepthCount() {
elementDepthCount++;
}
export function decreaseElementDepthCount() {
elementDepthCount--;
}
var currentDirectiveDef = null;
export function getCurrentDirectiveDef() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return currentDirectiveDef;
}
export function setCurrentDirectiveDef(def) {
currentDirectiveDef = def;
}
/**
* Stores whether directives should be matched to elements.
*
* When template contains `ngNonBindable` than we need to prevent the runtime form matching
* directives on children of that element.
*
* Example:
* ```
* <my-comp my-directive>
* Should match component / directive.
* </my-comp>
* <div ngNonBindable>
* <my-comp my-directive>
* Should not match component / directive because we are in ngNonBindable.
* </my-comp>
* </div>
* ```
*/
var bindingsEnabled;
export function getBindingsEnabled() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return bindingsEnabled;
}
/**
* Enables directive matching on elements.
*
* * Example:
* ```
* <my-comp my-directive>
* Should match component / directive.
* </my-comp>
* <div ngNonBindable>
* <!-- ɵɵdisableBindings() -->
* <my-comp my-directive>
* Should not match component / directive because we are in ngNonBindable.
* </my-comp>
* <!-- ɵɵenableBindings() -->
* </div>
* ```
*
* @codeGenApi
*/
export function ɵɵenableBindings() {
bindingsEnabled = true;
}
/**
* Disables directive matching on element.
*
* * Example:
* ```
* <my-comp my-directive>
* Should match component / directive.
* </my-comp>
* <div ngNonBindable>
* <!-- ɵɵdisableBindings() -->
* <my-comp my-directive>
* Should not match component / directive because we are in ngNonBindable.
* </my-comp>
* <!-- ɵɵenableBindings() -->
* </div>
* ```
*
* @codeGenApi
*/
export function ɵɵdisableBindings() {
bindingsEnabled = false;
}
export function getLView() {
return lView;
}
/**
* Used as the starting directive id value.
*
* All subsequent directives are incremented from this value onwards.
* The reason why this value is `1` instead of `0` is because the `0`
* value is reserved for the template.
*/
var MIN_DIRECTIVE_ID = 1;
var activeDirectiveId = MIN_DIRECTIVE_ID;
/**
* Position depth (with respect from leaf to root) in a directive sub-class inheritance chain.
*/
var activeDirectiveSuperClassDepthPosition = 0;
/**
* Total count of how many directives are a part of an inheritance chain.
*
* When directives are sub-classed (extended) from one to another, Angular
* needs to keep track of exactly how many were encountered so it can accurately
* generate the next directive id (once the next directive id is visited).
* Normally the next directive id just a single incremented value from the
* previous one, however, if the previous directive is a part of an inheritance
* chain (a series of sub-classed directives) then the incremented value must
* also take into account the total amount of sub-classed values.
*
* Note that this value resets back to zero once the next directive is
* visited (when `incrementActiveDirectiveId` or `setActiveHostElement`
* is called).
*/
var activeDirectiveSuperClassHeight = 0;
/**
* Sets the active directive host element and resets the directive id value
* (when the provided elementIndex value has changed).
*
* @param elementIndex the element index value for the host element where
* the directive/component instance lives
*/
export function setActiveHostElement(elementIndex) {
if (elementIndex === void 0) { elementIndex = null; }
if (_selectedIndex !== elementIndex) {
setSelectedIndex(elementIndex == null ? -1 : elementIndex);
activeDirectiveId = elementIndex == null ? 0 : MIN_DIRECTIVE_ID;
activeDirectiveSuperClassDepthPosition = 0;
activeDirectiveSuperClassHeight = 0;
}
}
/**
* Returns the current id value of the current directive.
*
* For example we have an element that has two directives on it:
* <div dir-one dir-two></div>
*
* dirOne->hostBindings() (id == 1)
* dirTwo->hostBindings() (id == 2)
*
* Note that this is only active when `hostBinding` functions are being processed.
*
* Note that directive id values are specific to an element (this means that
* the same id value could be present on another element with a completely
* different set of directives).
*/
export function getActiveDirectiveId() {
return activeDirectiveId;
}
/**
* Increments the current directive id value.
*
* For example we have an element that has two directives on it:
* <div dir-one dir-two></div>
*
* dirOne->hostBindings() (index = 1)
* // increment
* dirTwo->hostBindings() (index = 2)
*
* Depending on whether or not a previous directive had any inherited
* directives present, that value will be incremented in addition
* to the id jumping up by one.
*
* Note that this is only active when `hostBinding` functions are being processed.
*
* Note that directive id values are specific to an element (this means that
* the same id value could be present on another element with a completely
* different set of directives).
*/
export function incrementActiveDirectiveId() {
activeDirectiveId += 1 + activeDirectiveSuperClassHeight;
// because we are dealing with a new directive this
// means we have exited out of the inheritance chain
activeDirectiveSuperClassDepthPosition = 0;
activeDirectiveSuperClassHeight = 0;
}
/**
* Set the current super class (reverse inheritance) position depth for a directive.
*
* For example we have two directives: Child and Other (but Child is a sub-class of Parent)
* <div child-dir other-dir></div>
*
* // increment
* parentInstance->hostBindings() (depth = 1)
* // decrement
* childInstance->hostBindings() (depth = 0)
* otherInstance->hostBindings() (depth = 0 b/c it's a different directive)
*
* Note that this is only active when `hostBinding` functions are being processed.
*/
export function adjustActiveDirectiveSuperClassDepthPosition(delta) {
activeDirectiveSuperClassDepthPosition += delta;
// we keep track of the height value so that when the next directive is visited
// then Angular knows to generate a new directive id value which has taken into
// account how many sub-class directives were a part of the previous directive.
activeDirectiveSuperClassHeight =
Math.max(activeDirectiveSuperClassHeight, activeDirectiveSuperClassDepthPosition);
}
/**
* Returns he current depth of the super/sub class inheritance chain.
*
* This will return how many inherited directive/component classes
* exist in the current chain.
*
* ```typescript
* @Directive({ selector: '[super-dir]' })
* class SuperDir {}
*
* @Directive({ selector: '[sub-dir]' })
* class SubDir extends SuperDir {}
*
* // if `<div sub-dir>` is used then the super class height is `1`
* // if `<div super-dir>` is used then the super class height is `0`
* ```
*/
export function getActiveDirectiveSuperClassHeight() {
return activeDirectiveSuperClassHeight;
}
/**
* Returns the current super class (reverse inheritance) depth for a directive.
*
* This is designed to help instruction code distinguish different hostBindings
* calls from each other when a directive has extended from another directive.
* Normally using the directive id value is enough, but with the case
* of parent/sub-class directive inheritance more information is required.
*
* Note that this is only active when `hostBinding` functions are being processed.
*/
export function getActiveDirectiveSuperClassDepth() {
return activeDirectiveSuperClassDepthPosition;
}
/**
* Restores `contextViewData` to the given OpaqueViewState instance.
*
* Used in conjunction with the getCurrentView() instruction to save a snapshot
* of the current view and restore it when listeners are invoked. This allows
* walking the declaration view tree in listeners to get vars from parent views.
*
* @param viewToRestore The OpaqueViewState instance to restore.
*
* @codeGenApi
*/
export function ɵɵrestoreView(viewToRestore) {
contextLView = viewToRestore;
}
/** Used to set the parent property when nodes are created and track query results. */
var previousOrParentTNode;
export function getPreviousOrParentTNode() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return previousOrParentTNode;
}
export function setPreviousOrParentTNode(tNode, _isParent) {
previousOrParentTNode = tNode;
isParent = _isParent;
}
export function setTNodeAndViewData(tNode, view) {
ngDevMode && assertLViewOrUndefined(view);
previousOrParentTNode = tNode;
lView = view;
}
/**
* If `isParent` is:
* - `true`: then `previousOrParentTNode` points to a parent node.
* - `false`: then `previousOrParentTNode` points to previous node (sibling).
*/
var isParent;
export function getIsParent() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return isParent;
}
export function setIsNotParent() {
isParent = false;
}
export function setIsParent() {
isParent = true;
}
/** Checks whether a given view is in creation mode */
export function isCreationMode(view) {
if (view === void 0) { view = lView; }
return (view[FLAGS] & 4 /* CreationMode */) === 4 /* CreationMode */;
}
/**
* State of the current view being processed.
*
* An array of nodes (text, element, container, etc), pipes, their bindings, and
* any local variables that need to be stored between invocations.
*/
var lView;
/**
* The last viewData retrieved by nextContext().
* Allows building nextContext() and reference() calls.
*
* e.g. const inner = x().$implicit; const outer = x().$implicit;
*/
var contextLView = null;
export function getContextLView() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return contextLView;
}
/**
* In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
*
* Necessary to support ChangeDetectorRef.checkNoChanges().
*/
var checkNoChangesMode = false;
export function getCheckNoChangesMode() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return checkNoChangesMode;
}
export function setCheckNoChangesMode(mode) {
checkNoChangesMode = mode;
}
/**
* The root index from which pure function instructions should calculate their binding
* indices. In component views, this is TView.bindingStartIndex. In a host binding
* context, this is the TView.expandoStartIndex + any dirs/hostVars before the given dir.
*/
var bindingRootIndex = -1;
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
export function getBindingRoot() {
return bindingRootIndex;
}
export function setBindingRoot(value) {
bindingRootIndex = value;
}
/**
* Current index of a View or Content Query which needs to be processed next.
* We iterate over the list of Queries and increment current query index at every step.
*/
var currentQueryIndex = 0;
export function getCurrentQueryIndex() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return currentQueryIndex;
}
export function setCurrentQueryIndex(value) {
currentQueryIndex = value;
}
/**
* Swap the current state with a new state.
*
* For performance reasons we store the state in the top level of the module.
* This way we minimize the number of properties to read. Whenever a new view
* is entered we have to store the state for later, and when the view is
* exited the state has to be restored
*
* @param newView New state to become active
* @param host Element to which the View is a child of
* @returns the previous state;
*/
export function enterView(newView, hostTNode) {
ngDevMode && assertLViewOrUndefined(newView);
var oldView = lView;
if (newView) {
var tView = newView[TVIEW];
bindingRootIndex = tView.bindingStartIndex;
}
previousOrParentTNode = hostTNode;
isParent = true;
lView = contextLView = newView;
return oldView;
}
export function nextContextImpl(level) {
if (level === void 0) { level = 1; }
contextLView = walkUpViews(level, contextLView);
return contextLView[CONTEXT];
}
function walkUpViews(nestingLevel, currentView) {
while (nestingLevel > 0) {
ngDevMode && assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.');
currentView = currentView[DECLARATION_VIEW];
nestingLevel--;
}
return currentView;
}
/**
* Resets the application state.
*/
export function resetComponentState() {
isParent = false;
previousOrParentTNode = null;
elementDepthCount = 0;
bindingsEnabled = true;
}
/**
* Used in lieu of enterView to make it clear when we are exiting a child view. This makes
* the direction of traversal (up or down the view tree) a bit clearer.
*
* @param newView New state to become active
* @param safeToRunHooks Whether the runtime is in a state where running lifecycle hooks is valid.
* This is not always the case (for example, the application may have crashed and `leaveView` is
* being executed while unwinding the call stack).
*/
export function leaveView(newView, safeToRunHooks) {
var tView = lView[TVIEW];
if (isCreationMode(lView)) {
lView[FLAGS] &= ~4 /* CreationMode */;
}
else {
try {
resetPreOrderHookFlags(lView);
safeToRunHooks && executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, checkNoChangesMode, 2 /* AfterViewInitHooksToBeRun */, undefined);
}
finally {
// Views are clean and in update mode after being checked, so these bits are cleared
lView[FLAGS] &= ~(64 /* Dirty */ | 8 /* FirstLViewPass */);
lView[BINDING_INDEX] = tView.bindingStartIndex;
}
}
setCachedStylingContext(null);
enterView(newView, null);
}
var _selectedIndex = -1;
/**
* Gets the most recent index passed to {@link select}
*
* Used with {@link property} instruction (and more in the future) to identify the index in the
* current `LView` to act on.
*/
export function getSelectedIndex() {
return _selectedIndex;
}
/**
* Sets the most recent index passed to {@link select}
*
* Used with {@link property} instruction (and more in the future) to identify the index in the
* current `LView` to act on.
*/
export function setSelectedIndex(index) {
_selectedIndex = index;
// remove the styling context from the cache
// because we are now on a different element
setCachedStylingContext(null);
}
var _currentNamespace = null;
/**
* Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state.
*
* @codeGenApi
*/
export function ɵɵnamespaceSVG() {
_currentNamespace = 'http://www.w3.org/2000/svg';
}
/**
* Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
*
* @codeGenApi
*/
export function ɵɵnamespaceMathML() {
_currentNamespace = 'http://www.w3.org/1998/MathML/';
}
/**
* Sets the namespace used to create elements no `null`, which forces element creation to use
* `createElement` rather than `createElementNS`.
*
* @codeGenApi
*/
export function ɵɵnamespaceHTML() {
_currentNamespace = null;
}
export function getNamespace() {
return _currentNamespace;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL3N0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxhQUFhLEVBQW9CLE1BQU0sZ0JBQWdCLENBQUM7QUFFaEUsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ2hELE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFHckMsT0FBTyxFQUFDLGFBQWEsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFzRCxLQUFLLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM3SSxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUl6RDs7O0dBR0c7QUFDSCxJQUFJLGlCQUEyQixDQUFDO0FBRWhDLE1BQU0sVUFBVSxvQkFBb0I7SUFDbEMscUZBQXFGO0lBQ3JGLE9BQU8saUJBQWlCLENBQUM7QUFDM0IsQ0FBQztBQUVELE1BQU0sVUFBVSx5QkFBeUI7SUFDdkMsaUJBQWlCLEVBQUUsQ0FBQztBQUN0QixDQUFDO0FBRUQsTUFBTSxVQUFVLHlCQUF5QjtJQUN2QyxpQkFBaUIsRUFBRSxDQUFDO0FBQ3RCLENBQUM7QUFFRCxJQUFJLG1CQUFtQixHQUE2QyxJQUFJLENBQUM7QUFFekUsTUFBTSxVQUFVLHNCQUFzQjtJQUNwQyxxRkFBcUY7SUFDckYsT0FBTyxtQkFBbUIsQ0FBQztBQUM3QixDQUFDO0FBRUQsTUFBTSxVQUFVLHNCQUFzQixDQUFDLEdBQStDO0lBQ3BGLG1CQUFtQixHQUFHLEdBQUcsQ0FBQztBQUM1QixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsSUFBSSxlQUEw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QUFnQjtJQUM5QixPQUFPLGNBQWMsQ0FBQztBQUN4QixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsS0FBYTtJQUM1QyxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBRXZCLDRDQUE0QztJQUM1Qyw0Q0FBNEM7SUFDNUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUdELElBQUksaUJBQWlCLEdBQWdCLElBQUksQ0FBQztBQUUxQzs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGNBQWM7SUFDNUIsaUJBQWlCLEdBQUcsNEJBQTRCLENBQUM7QUFDbkQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCO0lBQy9CLGlCQUFpQixHQUFHLGdDQUFnQyxDQUFDO0FBQ3ZELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxlQUFlO0lBQzdCLGlCQUFpQixHQUFHLElBQUksQ0FBQztBQUMzQixDQUFDO0FBRUQsTUFBTSxVQUFVLFlBQVk7SUFDMUIsT0FBTyxpQkFBaUIsQ0FBQztBQUMzQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge2Fzc2VydERlZmluZWQsIGFzc2VydEdyZWF0ZXJUaGFufSBmcm9tICcuLi91dGlsL2Fzc2VydCc7XG5cbmltcG9ydCB7YXNzZXJ0TFZpZXdPclVuZGVmaW5lZH0gZnJvbSAnLi9hc3NlcnQnO1xuaW1wb3J0IHtleGVjdXRlSG9va3N9IGZyb20gJy4vaG9va3MnO1xuaW1wb3J0IHtDb21wb25lbnREZWYsIERpcmVjdGl2ZURlZn0gZnJvbSAnLi9pbnRlcmZhY2VzL2RlZmluaXRpb24nO1xuaW1wb3J0IHtURWxlbWVudE5vZGUsIFROb2RlLCBUVmlld05vZGV9IGZyb20gJy4vaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7QklORElOR19JTkRFWCwgQ09OVEVYVCwgREVDTEFSQVRJT05fVklFVywgRkxBR1MsIEluaXRQaGFzZVN0YXRlLCBMVmlldywgTFZpZXdGbGFncywgT3BhcXVlVmlld1N0YXRlLCBUVklFV30gZnJvbSAnLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHtzZXRDYWNoZWRTdHlsaW5nQ29udGV4dH0gZnJvbSAnLi9zdHlsaW5nL3N0YXRlJztcbmltcG9ydCB7cmVzZXRQcmVPcmRlckhvb2tGbGFnc30gZnJvbSAnLi91dGlsL3ZpZXdfdXRpbHMnO1xuXG5cblxuLyoqXG4gKiBTdG9yZSB0aGUgZWxlbWVudCBkZXB0aCBjb3VudC4gVGhpcyBpcyB1c2VkIHRvIGlkZW50aWZ5IHRoZSByb290IGVsZW1lbnRzIG9mIHRoZSB0ZW1wbGF0ZVxuICogc28gdGhhdCB3ZSBjYW4gdGhhbiBhdHRhY2ggYExWaWV3YCB0byBvbmx5IHRob3NlIGVsZW1lbnRzLlxuICovXG5sZXQgZWxlbWVudERlcHRoQ291bnQgITogbnVtYmVyO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudERlcHRoQ291bnQoKSB7XG4gIC8vIHRvcCBsZXZlbCB2YXJpYWJsZXMgc2hvdWxkIG5vdCBiZSBleHBvcnRlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoUEVSRl9OT1RFUy5tZClcbiAgcmV0dXJuIGVsZW1lbnREZXB0aENvdW50O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVhc2VFbGVtZW50RGVwdGhDb3VudCgpIHtcbiAgZWxlbWVudERlcHRoQ291bnQrKztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY3JlYXNlRWxlbWVudERlcHRoQ291bnQoKSB7XG4gIGVsZW1lbnREZXB0aENvdW50LS07XG59XG5cbmxldCBjdXJyZW50RGlyZWN0aXZlRGVmOiBEaXJlY3RpdmVEZWY8YW55PnxDb21wb25lbnREZWY8YW55PnxudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnREaXJlY3RpdmVEZWYoKTogRGlyZWN0aXZlRGVmPGFueT58Q29tcG9uZW50RGVmPGFueT58bnVsbCB7XG4gIC8vIHRvcCBsZXZlbCB2YXJpYWJsZXMgc2hvdWxkIG5vdCBiZSBleHBvcnRlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoUEVSRl9OT1RFUy5tZClcbiAgcmV0dXJuIGN1cnJlbnREaXJlY3RpdmVEZWY7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDdXJyZW50RGlyZWN0aXZlRGVmKGRlZjogRGlyZWN0aXZlRGVmPGFueT58IENvbXBvbmVudERlZjxhbnk+fCBudWxsKTogdm9pZCB7XG4gIGN1cnJlbnREaXJlY3RpdmVEZWYgPSBkZWY7XG59XG5cbi8qKlxuICogU3RvcmVzIHdoZXRoZXIgZGlyZWN0aXZlcyBzaG91bGQgYmUgbWF0Y2hlZCB0byBlbGVtZW50cy5cbiAqXG4gKiBXaGVuIHRlbXBsYXRlIGNvbnRhaW5zIGBuZ05vbkJpbmRhYmxlYCB0aGFuIHdlIG5lZWQgdG8gcHJldmVudCB0aGUgcnVudGltZSBmb3JtIG1hdGNoaW5nXG4gKiBkaXJlY3RpdmVzIG9uIGNoaWxkcmVuIG9mIHRoYXQgZWxlbWVudC5cbiAqXG4gKiBFeGFtcGxlOlxuICogYGBgXG4gKiA8bXktY29tcCBteS1kaXJlY3RpdmU+XG4gKiAgIFNob3VsZCBtYXRjaCBjb21wb25lbnQgLyBkaXJlY3RpdmUuXG4gKiA8L215LWNvbXA+XG4gKiA8ZGl2IG5nTm9uQmluZGFibGU+XG4gKiAgIDxteS1jb21wIG15LWRpcmVjdGl2ZT5cbiAqICAgICBTaG91bGQgbm90IG1hdGNoIGNvbXBvbmVudCAvIGRpcmVjdGl2ZSBiZWNhdXNlIHdlIGFyZSBpbiBuZ05vbkJpbmRhYmxlLlxuICogICA8L215LWNvbXA+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICovXG5sZXQgYmluZGluZ3NFbmFibGVkICE6IGJvb2xlYW47XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCaW5kaW5nc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gIC8vIHRvcCBsZXZlbCB2YXJpYWJsZXMgc2hvdWxkIG5vdCBiZSBleHBvcnRlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoUEVSRl9OT1RFUy5tZClcbiAgcmV0dXJuIGJpbmRpbmdzRW5hYmxlZDtcbn1cblxuXG4vKipcbiAqIEVuYWJsZXMgZGlyZWN0aXZlIG1hdGNoaW5nIG9uIGVsZW1lbnRzLlxuICpcbiAqICAqIEV4YW1wbGU6XG4gKiBgYGBcbiAqIDxteS1jb21wIG15LWRpcmVjdGl2ZT5cbiAqICAgU2hvdWxkIG1hdGNoIGNvbXBvbmVudCAvIGRpcmVjdGl2ZS5cbiAqIDwvbXktY29tcD5cbiAqIDxkaXYgbmdOb25CaW5kYWJsZT5cbiAqICAgPCEtLSDJtcm1ZGlzYWJsZUJpbmRpbmdzKCkgLS0+XG4gKiAgIDxteS1jb21wIG15LWRpcmVjdGl2ZT5cbiAqICAgICBTaG91bGQgbm90IG1hdGNoIGNvbXBvbmVudCAvIGRpcmVjdGl2ZSBiZWNhdXNlIHdlIGFyZSBpbiBuZ05vbkJpbmRhYmxlLlxuICogICA8L215LWNvbXA+XG4gKiAgIDwhLS0gybXJtWVuYWJsZUJpbmRpbmdzKCkgLS0+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIEBjb2RlR2VuQXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiDJtcm1ZW5hYmxlQmluZGluZ3MoKTogdm9pZCB7XG4gIGJpbmRpbmdzRW5hYmxlZCA9IHRydWU7XG59XG5cbi8qKlxuICogRGlzYWJsZXMgZGlyZWN0aXZlIG1hdGNoaW5nIG9uIGVsZW1lbnQuXG4gKlxuICogICogRXhhbXBsZTpcbiAqIGBgYFxuICogPG15LWNvbXAgbXktZGlyZWN0aXZlPlxuICogICBTaG91bGQgbWF0Y2ggY29tcG9uZW50IC8gZGlyZWN0aXZlLlxuICogPC9teS1jb21wPlxuICogPGRpdiBuZ05vbkJpbmRhYmxlPlxuICogICA8IS0tIMm1ybVkaXNhYmxlQmluZGluZ3MoKSAtLT5cbiAqICAgPG15LWNvbXAgbXktZGlyZWN0aXZlPlxuICogICAgIFNob3VsZCBub3QgbWF0Y2ggY29tcG9uZW50IC8gZGlyZWN0aXZlIGJlY2F1c2Ugd2UgYXJlIGluIG5nTm9uQmluZGFibGUuXG4gKiAgIDwvbXktY29tcD5cbiAqICAgPCEtLSDJtcm1ZW5hYmxlQmluZGluZ3MoKSAtLT5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVkaXNhYmxlQmluZGluZ3MoKTogdm9pZCB7XG4gIGJpbmRpbmdzRW5hYmxlZCA9IGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TFZpZXcoKTogTFZpZXcge1xuICByZXR1cm4gbFZpZXc7XG59XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgc3RhcnRpbmcgZGlyZWN0aXZlIGlkIHZhbHVlLlxuICpcbiAqIEFsbCBzdWJzZXF1ZW50IGRpcmVjdGl2ZXMgYXJlIGluY3JlbWVudGVkIGZyb20gdGhpcyB2YWx1ZSBvbndhcmRzLlxuICogVGhlIHJlYXNvbiB3aHkgdGhpcyB2YWx1ZSBpcyBgMWAgaW5zdGVhZCBvZiBgMGAgaXMgYmVjYXVzZSB0aGUgYDBgXG4gKiB2YWx1ZSBpcyByZXNlcnZlZCBmb3IgdGhlIHRlbXBsYXRlLlxuICovXG5jb25zdCBNSU5fRElSRUNUSVZFX0lEID0gMTtcblxubGV0IGFjdGl2ZURpcmVjdGl2ZUlkID0gTUlOX0RJUkVDVElWRV9JRDtcblxuLyoqXG4gKiBQb3NpdGlvbiBkZXB0aCAod2l0aCByZXNwZWN0IGZyb20gbGVhZiB0byByb290KSBpbiBhIGRpcmVjdGl2ZSBzdWItY2xhc3MgaW5oZXJpdGFuY2UgY2hhaW4uXG4gKi9cbmxldCBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzRGVwdGhQb3NpdGlvbiA9IDA7XG5cbi8qKlxuICogVG90YWwgY291bnQgb2YgaG93IG1hbnkgZGlyZWN0aXZlcyBhcmUgYSBwYXJ0IG9mIGFuIGluaGVyaXRhbmNlIGNoYWluLlxuICpcbiAqIFdoZW4gZGlyZWN0aXZlcyBhcmUgc3ViLWNsYXNzZWQgKGV4dGVuZGVkKSBmcm9tIG9uZSB0byBhbm90aGVyLCBBbmd1bGFyXG4gKiBuZWVkcyB0byBrZWVwIHRyYWNrIG9mIGV4YWN0bHkgaG93IG1hbnkgd2VyZSBlbmNvdW50ZXJlZCBzbyBpdCBjYW4gYWNjdXJhdGVseVxuICogZ2VuZXJhdGUgdGhlIG5leHQgZGlyZWN0aXZlIGlkIChvbmNlIHRoZSBuZXh0IGRpcmVjdGl2ZSBpZCBpcyB2aXNpdGVkKS5cbiAqIE5vcm1hbGx5IHRoZSBuZXh0IGRpcmVjdGl2ZSBpZCBqdXN0IGEgc2luZ2xlIGluY3JlbWVudGVkIHZhbHVlIGZyb20gdGhlXG4gKiBwcmV2aW91cyBvbmUsIGhvd2V2ZXIsIGlmIHRoZSBwcmV2aW91cyBkaXJlY3RpdmUgaXMgYSBwYXJ0IG9mIGFuIGluaGVyaXRhbmNlXG4gKiBjaGFpbiAoYSBzZXJpZXMgb2Ygc3ViLWNsYXNzZWQgZGlyZWN0aXZlcykgdGhlbiB0aGUgaW5jcmVtZW50ZWQgdmFsdWUgbXVzdFxuICogYWxzbyB0YWtlIGludG8gYWNjb3VudCB0aGUgdG90YWwgYW1vdW50IG9mIHN1Yi1jbGFzc2VkIHZhbHVlcy5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyB2YWx1ZSByZXNldHMgYmFjayB0byB6ZXJvIG9uY2UgdGhlIG5leHQgZGlyZWN0aXZlIGlzXG4gKiB2aXNpdGVkICh3aGVuIGBpbmNyZW1lbnRBY3RpdmVEaXJlY3RpdmVJZGAgb3IgYHNldEFjdGl2ZUhvc3RFbGVtZW50YFxuICogaXMgY2FsbGVkKS5cbiAqL1xubGV0IGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NIZWlnaHQgPSAwO1xuXG4vKipcbiAqIFNldHMgdGhlIGFjdGl2ZSBkaXJlY3RpdmUgaG9zdCBlbGVtZW50IGFuZCByZXNldHMgdGhlIGRpcmVjdGl2ZSBpZCB2YWx1ZVxuICogKHdoZW4gdGhlIHByb3ZpZGVkIGVsZW1lbnRJbmRleCB2YWx1ZSBoYXMgY2hhbmdlZCkuXG4gKlxuICogQHBhcmFtIGVsZW1lbnRJbmRleCB0aGUgZWxlbWVudCBpbmRleCB2YWx1ZSBmb3IgdGhlIGhvc3QgZWxlbWVudCB3aGVyZVxuICogICAgICAgICAgICAgICAgICAgICB0aGUgZGlyZWN0aXZlL2NvbXBvbmVudCBpbnN0YW5jZSBsaXZlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0QWN0aXZlSG9zdEVsZW1lbnQoZWxlbWVudEluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbCkge1xuICBpZiAoX3NlbGVjdGVkSW5kZXggIT09IGVsZW1lbnRJbmRleCkge1xuICAgIHNldFNlbGVjdGVkSW5kZXgoZWxlbWVudEluZGV4ID09IG51bGwgPyAtMSA6IGVsZW1lbnRJbmRleCk7XG4gICAgYWN0aXZlRGlyZWN0aXZlSWQgPSBlbGVtZW50SW5kZXggPT0gbnVsbCA/IDAgOiBNSU5fRElSRUNUSVZFX0lEO1xuICAgIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NEZXB0aFBvc2l0aW9uID0gMDtcbiAgICBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzSGVpZ2h0ID0gMDtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGN1cnJlbnQgaWQgdmFsdWUgb2YgdGhlIGN1cnJlbnQgZGlyZWN0aXZlLlxuICpcbiAqIEZvciBleGFtcGxlIHdlIGhhdmUgYW4gZWxlbWVudCB0aGF0IGhhcyB0d28gZGlyZWN0aXZlcyBvbiBpdDpcbiAqIDxkaXYgZGlyLW9uZSBkaXItdHdvPjwvZGl2PlxuICpcbiAqIGRpck9uZS0+aG9zdEJpbmRpbmdzKCkgKGlkID09IDEpXG4gKiBkaXJUd28tPmhvc3RCaW5kaW5ncygpIChpZCA9PSAyKVxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGlzIG9ubHkgYWN0aXZlIHdoZW4gYGhvc3RCaW5kaW5nYCBmdW5jdGlvbnMgYXJlIGJlaW5nIHByb2Nlc3NlZC5cbiAqXG4gKiBOb3RlIHRoYXQgZGlyZWN0aXZlIGlkIHZhbHVlcyBhcmUgc3BlY2lmaWMgdG8gYW4gZWxlbWVudCAodGhpcyBtZWFucyB0aGF0XG4gKiB0aGUgc2FtZSBpZCB2YWx1ZSBjb3VsZCBiZSBwcmVzZW50IG9uIGFub3RoZXIgZWxlbWVudCB3aXRoIGEgY29tcGxldGVseVxuICogZGlmZmVyZW50IHNldCBvZiBkaXJlY3RpdmVzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2ZURpcmVjdGl2ZUlkKCkge1xuICByZXR1cm4gYWN0aXZlRGlyZWN0aXZlSWQ7XG59XG5cbi8qKlxuICogSW5jcmVtZW50cyB0aGUgY3VycmVudCBkaXJlY3RpdmUgaWQgdmFsdWUuXG4gKlxuICogRm9yIGV4YW1wbGUgd2UgaGF2ZSBhbiBlbGVtZW50IHRoYXQgaGFzIHR3byBkaXJlY3RpdmVzIG9uIGl0OlxuICogPGRpdiBkaXItb25lIGRpci10d28+PC9kaXY+XG4gKlxuICogZGlyT25lLT5ob3N0QmluZGluZ3MoKSAoaW5kZXggPSAxKVxuICogLy8gaW5jcmVtZW50XG4gKiBkaXJUd28tPmhvc3RCaW5kaW5ncygpIChpbmRleCA9IDIpXG4gKlxuICogRGVwZW5kaW5nIG9uIHdoZXRoZXIgb3Igbm90IGEgcHJldmlvdXMgZGlyZWN0aXZlIGhhZCBhbnkgaW5oZXJpdGVkXG4gKiBkaXJlY3RpdmVzIHByZXNlbnQsIHRoYXQgdmFsdWUgd2lsbCBiZSBpbmNyZW1lbnRlZCBpbiBhZGRpdGlvblxuICogdG8gdGhlIGlkIGp1bXBpbmcgdXAgYnkgb25lLlxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGlzIG9ubHkgYWN0aXZlIHdoZW4gYGhvc3RCaW5kaW5nYCBmdW5jdGlvbnMgYXJlIGJlaW5nIHByb2Nlc3NlZC5cbiAqXG4gKiBOb3RlIHRoYXQgZGlyZWN0aXZlIGlkIHZhbHVlcyBhcmUgc3BlY2lmaWMgdG8gYW4gZWxlbWVudCAodGhpcyBtZWFucyB0aGF0XG4gKiB0aGUgc2FtZSBpZCB2YWx1ZSBjb3VsZCBiZSBwcmVzZW50IG9uIGFub3RoZXIgZWxlbWVudCB3aXRoIGEgY29tcGxldGVseVxuICogZGlmZmVyZW50IHNldCBvZiBkaXJlY3RpdmVzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluY3JlbWVudEFjdGl2ZURpcmVjdGl2ZUlkKCkge1xuICBhY3RpdmVEaXJlY3RpdmVJZCArPSAxICsgYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0hlaWdodDtcblxuICAvLyBiZWNhdXNlIHdlIGFyZSBkZWFsaW5nIHdpdGggYSBuZXcgZGlyZWN0aXZlIHRoaXNcbiAgLy8gbWVhbnMgd2UgaGF2ZSBleGl0ZWQgb3V0IG9mIHRoZSBpbmhlcml0YW5jZSBjaGFpblxuICBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzRGVwdGhQb3NpdGlvbiA9IDA7XG4gIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NIZWlnaHQgPSAwO1xufVxuXG4vKipcbiAqIFNldCB0aGUgY3VycmVudCBzdXBlciBjbGFzcyAocmV2ZXJzZSBpbmhlcml0YW5jZSkgcG9zaXRpb24gZGVwdGggZm9yIGEgZGlyZWN0aXZlLlxuICpcbiAqIEZvciBleGFtcGxlIHdlIGhhdmUgdHdvIGRpcmVjdGl2ZXM6IENoaWxkIGFuZCBPdGhlciAoYnV0IENoaWxkIGlzIGEgc3ViLWNsYXNzIG9mIFBhcmVudClcbiAqIDxkaXYgY2hpbGQtZGlyIG90aGVyLWRpcj48L2Rpdj5cbiAqXG4gKiAvLyBpbmNyZW1lbnRcbiAqIHBhcmVudEluc3RhbmNlLT5ob3N0QmluZGluZ3MoKSAoZGVwdGggPSAxKVxuICogLy8gZGVjcmVtZW50XG4gKiBjaGlsZEluc3RhbmNlLT5ob3N0QmluZGluZ3MoKSAoZGVwdGggPSAwKVxuICogb3RoZXJJbnN0YW5jZS0+aG9zdEJpbmRpbmdzKCkgKGRlcHRoID0gMCBiL2MgaXQncyBhIGRpZmZlcmVudCBkaXJlY3RpdmUpXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhY3RpdmUgd2hlbiBgaG9zdEJpbmRpbmdgIGZ1bmN0aW9ucyBhcmUgYmVpbmcgcHJvY2Vzc2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRqdXN0QWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0RlcHRoUG9zaXRpb24oZGVsdGE6IG51bWJlcikge1xuICBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzRGVwdGhQb3NpdGlvbiArPSBkZWx0YTtcblxuICAvLyB3ZSBrZWVwIHRyYWNrIG9mIHRoZSBoZWlnaHQgdmFsdWUgc28gdGhhdCB3aGVuIHRoZSBuZXh0IGRpcmVjdGl2ZSBpcyB2aXNpdGVkXG4gIC8vIHRoZW4gQW5ndWxhciBrbm93cyB0byBnZW5lcmF0ZSBhIG5ldyBkaXJlY3RpdmUgaWQgdmFsdWUgd2hpY2ggaGFzIHRha2VuIGludG9cbiAgLy8gYWNjb3VudCBob3cgbWFueSBzdWItY2xhc3MgZGlyZWN0aXZlcyB3ZXJlIGEgcGFydCBvZiB0aGUgcHJldmlvdXMgZGlyZWN0aXZlLlxuICBhY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzSGVpZ2h0ID1cbiAgICAgIE1hdGgubWF4KGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NIZWlnaHQsIGFjdGl2ZURpcmVjdGl2ZVN1cGVyQ2xhc3NEZXB0aFBvc2l0aW9uKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGhlIGN1cnJlbnQgZGVwdGggb2YgdGhlIHN1cGVyL3N1YiBjbGFzcyBpbmhlcml0YW5jZSBjaGFpbi5cbiAqXG4gKiBUaGlzIHdpbGwgcmV0dXJuIGhvdyBtYW55IGluaGVyaXRlZCBkaXJlY3RpdmUvY29tcG9uZW50IGNsYXNzZXNcbiAqIGV4aXN0IGluIHRoZSBjdXJyZW50IGNoYWluLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tzdXBlci1kaXJdJyB9KVxuICogY2xhc3MgU3VwZXJEaXIge31cbiAqXG4gKiBARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbc3ViLWRpcl0nIH0pXG4gKiBjbGFzcyBTdWJEaXIgZXh0ZW5kcyBTdXBlckRpciB7fVxuICpcbiAqIC8vIGlmIGA8ZGl2IHN1Yi1kaXI+YCBpcyB1c2VkIHRoZW4gdGhlIHN1cGVyIGNsYXNzIGhlaWdodCBpcyBgMWBcbiAqIC8vIGlmIGA8ZGl2IHN1cGVyLWRpcj5gIGlzIHVzZWQgdGhlbiB0aGUgc3VwZXIgY2xhc3MgaGVpZ2h0IGlzIGAwYFxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmVEaXJlY3RpdmVTdXBlckNsYXNzSGVpZ2h0KCkge1xuICByZXR1cm4gYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0hlaWdodDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjdXJyZW50IHN1cGVyIGNsYXNzIChyZXZlcnNlIGluaGVyaXRhbmNlKSBkZXB0aCBmb3IgYSBkaXJlY3RpdmUuXG4gKlxuICogVGhpcyBpcyBkZXNpZ25lZCB0byBoZWxwIGluc3RydWN0aW9uIGNvZGUgZGlzdGluZ3Vpc2ggZGlmZmVyZW50IGhvc3RCaW5kaW5nc1xuICogY2FsbHMgZnJvbSBlYWNoIG90aGVyIHdoZW4gYSBkaXJlY3RpdmUgaGFzIGV4dGVuZGVkIGZyb20gYW5vdGhlciBkaXJlY3RpdmUuXG4gKiBOb3JtYWxseSB1c2luZyB0aGUgZGlyZWN0aXZlIGlkIHZhbHVlIGlzIGVub3VnaCwgYnV0IHdpdGggdGhlIGNhc2VcbiAqIG9mIHBhcmVudC9zdWItY2xhc3MgZGlyZWN0aXZlIGluaGVyaXRhbmNlIG1vcmUgaW5mb3JtYXRpb24gaXMgcmVxdWlyZWQuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhY3RpdmUgd2hlbiBgaG9zdEJpbmRpbmdgIGZ1bmN0aW9ucyBhcmUgYmVpbmcgcHJvY2Vzc2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0RlcHRoKCkge1xuICByZXR1cm4gYWN0aXZlRGlyZWN0aXZlU3VwZXJDbGFzc0RlcHRoUG9zaXRpb247XG59XG5cbi8qKlxuICogUmVzdG9yZXMgYGNvbnRleHRWaWV3RGF0YWAgdG8gdGhlIGdpdmVuIE9wYXF1ZVZpZXdTdGF0ZSBpbnN0YW5jZS5cbiAqXG4gKiBVc2VkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIGdldEN1cnJlbnRWaWV3KCkgaW5zdHJ1Y3Rpb24gdG8gc2F2ZSBhIHNuYXBzaG90XG4gKiBvZiB0aGUgY3VycmVudCB2aWV3IGFuZCByZXN0b3JlIGl0IHdoZW4gbGlzdGVuZXJzIGFyZSBpbnZva2VkLiBUaGlzIGFsbG93c1xuICogd2Fsa2luZyB0aGUgZGVjbGFyYXRpb24gdmlldyB0cmVlIGluIGxpc3RlbmVycyB0byBnZXQgdmFycyBmcm9tIHBhcmVudCB2aWV3cy5cbiAqXG4gKiBAcGFyYW0gdmlld1RvUmVzdG9yZSBUaGUgT3BhcXVlVmlld1N0YXRlIGluc3RhbmNlIHRvIHJlc3RvcmUuXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVyZXN0b3JlVmlldyh2aWV3VG9SZXN0b3JlOiBPcGFxdWVWaWV3U3RhdGUpIHtcbiAgY29udGV4dExWaWV3ID0gdmlld1RvUmVzdG9yZSBhcyBhbnkgYXMgTFZpZXc7XG59XG5cbi8qKiBVc2VkIHRvIHNldCB0aGUgcGFyZW50IHByb3BlcnR5IHdoZW4gbm9kZXMgYXJlIGNyZWF0ZWQgYW5kIHRyYWNrIHF1ZXJ5IHJlc3VsdHMuICovXG5sZXQgcHJldmlvdXNPclBhcmVudFROb2RlOiBUTm9kZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFByZXZpb3VzT3JQYXJlbnRUTm9kZSgpOiBUTm9kZSB7XG4gIC8vIHRvcCBsZXZlbCB2YXJpYWJsZXMgc2hvdWxkIG5vdCBiZSBleHBvcnRlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoUEVSRl9OT1RFUy5tZClcbiAgcmV0dXJuIHByZXZpb3VzT3JQYXJlbnRUTm9kZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFByZXZpb3VzT3JQYXJlbnRUTm9kZSh0Tm9kZTogVE5vZGUsIF9pc1BhcmVudDogYm9vbGVhbikge1xuICBwcmV2aW91c09yUGFyZW50VE5vZGUgPSB0Tm9kZTtcbiAgaXNQYXJlbnQgPSBfaXNQYXJlbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRUTm9kZUFuZFZpZXdEYXRhKHROb2RlOiBUTm9kZSwgdmlldzogTFZpZXcpIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydExWaWV3T3JVbmRlZmluZWQodmlldyk7XG4gIHByZXZpb3VzT3JQYXJlbnRUTm9kZSA9IHROb2RlO1xuICBsVmlldyA9IHZpZXc7XG59XG5cbi8qKlxuICogSWYgYGlzUGFyZW50YCBpczpcbiAqICAtIGB0cnVlYDogdGhlbiBgcHJldmlvdXNPclBhcmVudFROb2RlYCBwb2ludHMgdG8gYSBwYXJlbnQgbm9kZS5cbiAqICAtIGBmYWxzZWA6IHRoZW4gYHByZXZpb3VzT3JQYXJlbnRUTm9kZWAgcG9pbnRzIHRvIHByZXZpb3VzIG5vZGUgKHNpYmxpbmcpLlxuICovXG5sZXQgaXNQYXJlbnQ6IGJvb2xlYW47XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJc1BhcmVudCgpOiBib29sZWFuIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gaXNQYXJlbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRJc05vdFBhcmVudCgpOiB2b2lkIHtcbiAgaXNQYXJlbnQgPSBmYWxzZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXRJc1BhcmVudCgpOiB2b2lkIHtcbiAgaXNQYXJlbnQgPSB0cnVlO1xufVxuXG5cbi8qKiBDaGVja3Mgd2hldGhlciBhIGdpdmVuIHZpZXcgaXMgaW4gY3JlYXRpb24gbW9kZSAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ3JlYXRpb25Nb2RlKHZpZXc6IExWaWV3ID0gbFZpZXcpOiBib29sZWFuIHtcbiAgcmV0dXJuICh2aWV3W0ZMQUdTXSAmIExWaWV3RmxhZ3MuQ3JlYXRpb25Nb2RlKSA9PT0gTFZpZXdGbGFncy5DcmVhdGlvbk1vZGU7XG59XG5cbi8qKlxuICogU3RhdGUgb2YgdGhlIGN1cnJlbnQgdmlldyBiZWluZyBwcm9jZXNzZWQuXG4gKlxuICogQW4gYXJyYXkgb2Ygbm9kZXMgKHRleHQsIGVsZW1lbnQsIGNvbnRhaW5lciwgZXRjKSwgcGlwZXMsIHRoZWlyIGJpbmRpbmdzLCBhbmRcbiAqIGFueSBsb2NhbCB2YXJpYWJsZXMgdGhhdCBuZWVkIHRvIGJlIHN0b3JlZCBiZXR3ZWVuIGludm9jYXRpb25zLlxuICovXG5sZXQgbFZpZXc6IExWaWV3O1xuXG4vKipcbiAqIFRoZSBsYXN0IHZpZXdEYXRhIHJldHJpZXZlZCBieSBuZXh0Q29udGV4dCgpLlxuICogQWxsb3dzIGJ1aWxkaW5nIG5leHRDb250ZXh0KCkgYW5kIHJlZmVyZW5jZSgpIGNhbGxzLlxuICpcbiAqIGUuZy4gY29uc3QgaW5uZXIgPSB4KCkuJGltcGxpY2l0OyBjb25zdCBvdXRlciA9IHgoKS4kaW1wbGljaXQ7XG4gKi9cbmxldCBjb250ZXh0TFZpZXc6IExWaWV3ID0gbnVsbCAhO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29udGV4dExWaWV3KCk6IExWaWV3IHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gY29udGV4dExWaWV3O1xufVxuXG4vKipcbiAqIEluIHRoaXMgbW9kZSwgYW55IGNoYW5nZXMgaW4gYmluZGluZ3Mgd2lsbCB0aHJvdyBhbiBFeHByZXNzaW9uQ2hhbmdlZEFmdGVyQ2hlY2tlZCBlcnJvci5cbiAqXG4gKiBOZWNlc3NhcnkgdG8gc3VwcG9ydCBDaGFuZ2VEZXRlY3RvclJlZi5jaGVja05vQ2hhbmdlcygpLlxuICovXG5sZXQgY2hlY2tOb0NoYW5nZXNNb2RlID0gZmFsc2U7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGVja05vQ2hhbmdlc01vZGUoKTogYm9vbGVhbiB7XG4gIC8vIHRvcCBsZXZlbCB2YXJpYWJsZXMgc2hvdWxkIG5vdCBiZSBleHBvcnRlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoUEVSRl9OT1RFUy5tZClcbiAgcmV0dXJuIGNoZWNrTm9DaGFuZ2VzTW9kZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldENoZWNrTm9DaGFuZ2VzTW9kZShtb2RlOiBib29sZWFuKTogdm9pZCB7XG4gIGNoZWNrTm9DaGFuZ2VzTW9kZSA9IG1vZGU7XG59XG5cbi8qKlxuICogVGhlIHJvb3QgaW5kZXggZnJvbSB3aGljaCBwdXJlIGZ1bmN0aW9uIGluc3RydWN0aW9ucyBzaG91bGQgY2FsY3VsYXRlIHRoZWlyIGJpbmRpbmdcbiAqIGluZGljZXMuIEluIGNvbXBvbmVudCB2aWV3cywgdGhpcyBpcyBUVmlldy5iaW5kaW5nU3RhcnRJbmRleC4gSW4gYSBob3N0IGJpbmRpbmdcbiAqIGNvbnRleHQsIHRoaXMgaXMgdGhlIFRWaWV3LmV4cGFuZG9TdGFydEluZGV4ICsgYW55IGRpcnMvaG9zdFZhcnMgYmVmb3JlIHRoZSBnaXZlbiBkaXIuXG4gKi9cbmxldCBiaW5kaW5nUm9vdEluZGV4OiBudW1iZXIgPSAtMTtcblxuLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuZXhwb3J0IGZ1bmN0aW9uIGdldEJpbmRpbmdSb290KCkge1xuICByZXR1cm4gYmluZGluZ1Jvb3RJbmRleDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEJpbmRpbmdSb290KHZhbHVlOiBudW1iZXIpIHtcbiAgYmluZGluZ1Jvb3RJbmRleCA9IHZhbHVlO1xufVxuXG4vKipcbiAqIEN1cnJlbnQgaW5kZXggb2YgYSBWaWV3IG9yIENvbnRlbnQgUXVlcnkgd2hpY2ggbmVlZHMgdG8gYmUgcHJvY2Vzc2VkIG5leHQuXG4gKiBXZSBpdGVyYXRlIG92ZXIgdGhlIGxpc3Qgb2YgUXVlcmllcyBhbmQgaW5jcmVtZW50IGN1cnJlbnQgcXVlcnkgaW5kZXggYXQgZXZlcnkgc3RlcC5cbiAqL1xubGV0IGN1cnJlbnRRdWVyeUluZGV4OiBudW1iZXIgPSAwO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudFF1ZXJ5SW5kZXgoKTogbnVtYmVyIHtcbiAgLy8gdG9wIGxldmVsIHZhcmlhYmxlcyBzaG91bGQgbm90IGJlIGV4cG9ydGVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIChQRVJGX05PVEVTLm1kKVxuICByZXR1cm4gY3VycmVudFF1ZXJ5SW5kZXg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDdXJyZW50UXVlcnlJbmRleCh2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gIGN1cnJlbnRRdWVyeUluZGV4ID0gdmFsdWU7XG59XG5cbi8qKlxuICogU3dhcCB0aGUgY3VycmVudCBzdGF0ZSB3aXRoIGEgbmV3IHN0YXRlLlxuICpcbiAqIEZvciBwZXJmb3JtYW5jZSByZWFzb25zIHdlIHN0b3JlIHRoZSBzdGF0ZSBpbiB0aGUgdG9wIGxldmVsIG9mIHRoZSBtb2R1bGUuXG4gKiBUaGlzIHdheSB3ZSBtaW5pbWl6ZSB0aGUgbnVtYmVyIG9mIHByb3BlcnRpZXMgdG8gcmVhZC4gV2hlbmV2ZXIgYSBuZXcgdmlld1xuICogaXMgZW50ZXJlZCB3ZSBoYXZlIHRvIHN0b3JlIHRoZSBzdGF0ZSBmb3IgbGF0ZXIsIGFuZCB3aGVuIHRoZSB2aWV3IGlzXG4gKiBleGl0ZWQgdGhlIHN0YXRlIGhhcyB0byBiZSByZXN0b3JlZFxuICpcbiAqIEBwYXJhbSBuZXdWaWV3IE5ldyBzdGF0ZSB0byBiZWNvbWUgYWN0aXZlXG4gKiBAcGFyYW0gaG9zdCBFbGVtZW50IHRvIHdoaWNoIHRoZSBWaWV3IGlzIGEgY2hpbGQgb2ZcbiAqIEByZXR1cm5zIHRoZSBwcmV2aW91cyBzdGF0ZTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVudGVyVmlldyhuZXdWaWV3OiBMVmlldywgaG9zdFROb2RlOiBURWxlbWVudE5vZGUgfCBUVmlld05vZGUgfCBudWxsKTogTFZpZXcge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TFZpZXdPclVuZGVmaW5lZChuZXdWaWV3KTtcbiAgY29uc3Qgb2xkVmlldyA9IGxWaWV3O1xuICBpZiAobmV3Vmlldykge1xuICAgIGNvbnN0IHRWaWV3ID0gbmV3Vmlld1tUVklFV107XG4gICAgYmluZGluZ1Jvb3RJbmRleCA9IHRWaWV3LmJpbmRpbmdTdGFydEluZGV4O1xuICB9XG5cbiAgcHJldmlvdXNPclBhcmVudFROb2RlID0gaG9zdFROb2RlICE7XG4gIGlzUGFyZW50ID0gdHJ1ZTtcblxuICBsVmlldyA9IGNvbnRleHRMVmlldyA9IG5ld1ZpZXc7XG4gIHJldHVybiBvbGRWaWV3O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbmV4dENvbnRleHRJbXBsPFQgPSBhbnk+KGxldmVsOiBudW1iZXIgPSAxKTogVCB7XG4gIGNvbnRleHRMVmlldyA9IHdhbGtVcFZpZXdzKGxldmVsLCBjb250ZXh0TFZpZXcgISk7XG4gIHJldHVybiBjb250ZXh0TFZpZXdbQ09OVEVYVF0gYXMgVDtcbn1cblxuZnVuY3Rpb24gd2Fsa1VwVmlld3MobmVzdGluZ0xldmVsOiBudW1iZXIsIGN1cnJlbnRWaWV3OiBMVmlldyk6IExWaWV3IHtcbiAgd2hpbGUgKG5lc3RpbmdMZXZlbCA+IDApIHtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RGVmaW5lZChcbiAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRWaWV3W0RFQ0xBUkFUSU9OX1ZJRVddLFxuICAgICAgICAgICAgICAgICAgICAgJ0RlY2xhcmF0aW9uIHZpZXcgc2hvdWxkIGJlIGRlZmluZWQgaWYgbmVzdGluZyBsZXZlbCBpcyBncmVhdGVyIHRoYW4gMC4nKTtcbiAgICBjdXJyZW50VmlldyA9IGN1cnJlbnRWaWV3W0RFQ0xBUkFUSU9OX1ZJRVddICE7XG4gICAgbmVzdGluZ0xldmVsLS07XG4gIH1cbiAgcmV0dXJuIGN1cnJlbnRWaWV3O1xufVxuXG4vKipcbiAqIFJlc2V0cyB0aGUgYXBwbGljYXRpb24gc3RhdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldENvbXBvbmVudFN0YXRlKCkge1xuICBpc1BhcmVudCA9IGZhbHNlO1xuICBwcmV2aW91c09yUGFyZW50VE5vZGUgPSBudWxsICE7XG4gIGVsZW1lbnREZXB0aENvdW50ID0gMDtcbiAgYmluZGluZ3NFbmFibGVkID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBVc2VkIGluIGxpZXUgb2YgZW50ZXJWaWV3IHRvIG1ha2UgaXQgY2xlYXIgd2hlbiB3ZSBhcmUgZXhpdGluZyBhIGNoaWxkIHZpZXcuIFRoaXMgbWFrZXNcbiAqIHRoZSBkaXJlY3Rpb24gb2YgdHJhdmVyc2FsICh1cCBvciBkb3duIHRoZSB2aWV3IHRyZWUpIGEgYml0IGNsZWFyZXIuXG4gKlxuICogQHBhcmFtIG5ld1ZpZXcgTmV3IHN0YXRlIHRvIGJlY29tZSBhY3RpdmVcbiAqIEBwYXJhbSBzYWZlVG9SdW5Ib29rcyBXaGV0aGVyIHRoZSBydW50aW1lIGlzIGluIGEgc3RhdGUgd2hlcmUgcnVubmluZyBsaWZlY3ljbGUgaG9va3MgaXMgdmFsaWQuXG4gKiBUaGlzIGlzIG5vdCBhbHdheXMgdGhlIGNhc2UgKGZvciBleGFtcGxlLCB0aGUgYXBwbGljYXRpb24gbWF5IGhhdmUgY3Jhc2hlZCBhbmQgYGxlYXZlVmlld2AgaXNcbiAqIGJlaW5nIGV4ZWN1dGVkIHdoaWxlIHVud2luZGluZyB0aGUgY2FsbCBzdGFjaykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsZWF2ZVZpZXcobmV3VmlldzogTFZpZXcsIHNhZmVUb1J1bkhvb2tzOiBib29sZWFuKTogdm9pZCB7XG4gIGNvbnN0IHRWaWV3ID0gbFZpZXdbVFZJRVddO1xuICBpZiAoaXNDcmVhdGlvbk1vZGUobFZpZXcpKSB7XG4gICAgbFZpZXdbRkxBR1NdICY9IH5MVmlld0ZsYWdzLkNyZWF0aW9uTW9kZTtcbiAgfSBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgcmVzZXRQcmVPcmRlckhvb2tGbGFncyhsVmlldyk7XG4gICAgICBzYWZlVG9SdW5Ib29rcyAmJiBleGVjdXRlSG9va3MoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbFZpZXcsIHRWaWV3LnZpZXdIb29rcywgdFZpZXcudmlld0NoZWNrSG9va3MsIGNoZWNrTm9DaGFuZ2VzTW9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbml0UGhhc2VTdGF0ZS5BZnRlclZpZXdJbml0SG9va3NUb0JlUnVuLCB1bmRlZmluZWQpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBWaWV3cyBhcmUgY2xlYW4gYW5kIGluIHVwZGF0ZSBtb2RlIGFmdGVyIGJlaW5nIGNoZWNrZWQsIHNvIHRoZXNlIGJpdHMgYXJlIGNsZWFyZWRcbiAgICAgIGxWaWV3W0ZMQUdTXSAmPSB+KExWaWV3RmxhZ3MuRGlydHkgfCBMVmlld0ZsYWdzLkZpcnN0TFZpZXdQYXNzKTtcbiAgICAgIGxWaWV3W0JJTkRJTkdfSU5ERVhdID0gdFZpZXcuYmluZGluZ1N0YXJ0SW5kZXg7XG4gICAgfVxuICB9XG4gIHNldENhY2hlZFN0eWxpbmdDb250ZXh0KG51bGwpO1xuICBlbnRlclZpZXcobmV3VmlldywgbnVsbCk7XG59XG5cbmxldCBfc2VsZWN0ZWRJbmRleCA9IC0xO1xuXG4vKipcbiAqIEdldHMgdGhlIG1vc3QgcmVjZW50IGluZGV4IHBhc3NlZCB0byB7QGxpbmsgc2VsZWN0fVxuICpcbiAqIFVzZWQgd2l0aCB7QGxpbmsgcHJvcGVydHl9IGluc3RydWN0aW9uIChhbmQgbW9yZSBpbiB0aGUgZnV0dXJlKSB0byBpZGVudGlmeSB0aGUgaW5kZXggaW4gdGhlXG4gKiBjdXJyZW50IGBMVmlld2AgdG8gYWN0IG9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRJbmRleCgpIHtcbiAgcmV0dXJuIF9zZWxlY3RlZEluZGV4O1xufVxuXG4vKipcbiAqIFNldHMgdGhlIG1vc3QgcmVjZW50IGluZGV4IHBhc3NlZCB0byB7QGxpbmsgc2VsZWN0fVxuICpcbiAqIFVzZWQgd2l0aCB7QGxpbmsgcHJvcGVydHl9IGluc3RydWN0aW9uIChhbmQgbW9yZSBpbiB0aGUgZnV0dXJlKSB0byBpZGVudGlmeSB0aGUgaW5kZXggaW4gdGhlXG4gKiBjdXJyZW50IGBMVmlld2AgdG8gYWN0IG9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0U2VsZWN0ZWRJbmRleChpbmRleDogbnVtYmVyKSB7XG4gIF9zZWxlY3RlZEluZGV4ID0gaW5kZXg7XG5cbiAgLy8gcmVtb3ZlIHRoZSBzdHlsaW5nIGNvbnRleHQgZnJvbSB0aGUgY2FjaGVcbiAgLy8gYmVjYXVzZSB3ZSBhcmUgbm93IG9uIGEgZGlmZmVyZW50IGVsZW1lbnRcbiAgc2V0Q2FjaGVkU3R5bGluZ0NvbnRleHQobnVsbCk7XG59XG5cblxubGV0IF9jdXJyZW50TmFtZXNwYWNlOiBzdHJpbmd8bnVsbCA9IG51bGw7XG5cbi8qKlxuICogU2V0cyB0aGUgbmFtZXNwYWNlIHVzZWQgdG8gY3JlYXRlIGVsZW1lbnRzIHRvIGAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnYCBpbiBnbG9iYWwgc3RhdGUuXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVuYW1lc3BhY2VTVkcoKSB7XG4gIF9jdXJyZW50TmFtZXNwYWNlID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJztcbn1cblxuLyoqXG4gKiBTZXRzIHRoZSBuYW1lc3BhY2UgdXNlZCB0byBjcmVhdGUgZWxlbWVudHMgdG8gYCdodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGhNTC8nYCBpbiBnbG9iYWwgc3RhdGUuXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVuYW1lc3BhY2VNYXRoTUwoKSB7XG4gIF9jdXJyZW50TmFtZXNwYWNlID0gJ2h0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aE1MLyc7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgbmFtZXNwYWNlIHVzZWQgdG8gY3JlYXRlIGVsZW1lbnRzIG5vIGBudWxsYCwgd2hpY2ggZm9yY2VzIGVsZW1lbnQgY3JlYXRpb24gdG8gdXNlXG4gKiBgY3JlYXRlRWxlbWVudGAgcmF0aGVyIHRoYW4gYGNyZWF0ZUVsZW1lbnROU2AuXG4gKlxuICogQGNvZGVHZW5BcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIMm1ybVuYW1lc3BhY2VIVE1MKCkge1xuICBfY3VycmVudE5hbWVzcGFjZSA9IG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXROYW1lc3BhY2UoKTogc3RyaW5nfG51bGwge1xuICByZXR1cm4gX2N1cnJlbnROYW1lc3BhY2U7XG59XG4iXX0=