@angular/common
Version:
Angular - commonly needed directives and services
269 lines • 29.5 kB
JavaScript
/**
* @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 { Directive, Host, Input, Optional, TemplateRef, ViewContainerRef, ɵformatRuntimeError as formatRuntimeError, ɵRuntimeError as RuntimeError, } from '@angular/core';
import { NG_SWITCH_USE_STRICT_EQUALS } from './ng_switch_equality';
import * as i0 from "@angular/core";
export class SwitchView {
constructor(_viewContainerRef, _templateRef) {
this._viewContainerRef = _viewContainerRef;
this._templateRef = _templateRef;
this._created = false;
}
create() {
this._created = true;
this._viewContainerRef.createEmbeddedView(this._templateRef);
}
destroy() {
this._created = false;
this._viewContainerRef.clear();
}
enforceState(created) {
if (created && !this._created) {
this.create();
}
else if (!created && this._created) {
this.destroy();
}
}
}
/**
* @ngModule CommonModule
*
* @description
* The `[ngSwitch]` directive on a container specifies an expression to match against.
* The expressions to match are provided by `ngSwitchCase` directives on views within the container.
* - Every view that matches is rendered.
* - If there are no matches, a view with the `ngSwitchDefault` directive is rendered.
* - Elements within the `[NgSwitch]` statement but outside of any `NgSwitchCase`
* or `ngSwitchDefault` directive are preserved at the location.
*
* @usageNotes
* Define a container element for the directive, and specify the switch expression
* to match against as an attribute:
*
* ```
* <container-element [ngSwitch]="switch_expression">
* ```
*
* Within the container, `*ngSwitchCase` statements specify the match expressions
* as attributes. Include `*ngSwitchDefault` as the final case.
*
* ```
* <container-element [ngSwitch]="switch_expression">
* <some-element *ngSwitchCase="match_expression_1">...</some-element>
* ...
* <some-element *ngSwitchDefault>...</some-element>
* </container-element>
* ```
*
* ### Usage Examples
*
* The following example shows how to use more than one case to display the same view:
*
* ```
* <container-element [ngSwitch]="switch_expression">
* <!-- the same view can be shown in more than one case -->
* <some-element *ngSwitchCase="match_expression_1">...</some-element>
* <some-element *ngSwitchCase="match_expression_2">...</some-element>
* <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
* <!--default case when there are no matches -->
* <some-element *ngSwitchDefault>...</some-element>
* </container-element>
* ```
*
* The following example shows how cases can be nested:
* ```
* <container-element [ngSwitch]="switch_expression">
* <some-element *ngSwitchCase="match_expression_1">...</some-element>
* <some-element *ngSwitchCase="match_expression_2">...</some-element>
* <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
* <ng-container *ngSwitchCase="match_expression_3">
* <!-- use a ng-container to group multiple root nodes -->
* <inner-element></inner-element>
* <inner-other-element></inner-other-element>
* </ng-container>
* <some-element *ngSwitchDefault>...</some-element>
* </container-element>
* ```
*
* @publicApi
* @see {@link NgSwitchCase}
* @see {@link NgSwitchDefault}
* @see [Structural Directives](guide/directives/structural-directives)
*
*/
export class NgSwitch {
constructor() {
this._defaultViews = [];
this._defaultUsed = false;
this._caseCount = 0;
this._lastCaseCheckIndex = 0;
this._lastCasesMatched = false;
}
set ngSwitch(newValue) {
this._ngSwitch = newValue;
if (this._caseCount === 0) {
this._updateDefaultCases(true);
}
}
/** @internal */
_addCase() {
return this._caseCount++;
}
/** @internal */
_addDefault(view) {
this._defaultViews.push(view);
}
/** @internal */
_matchCase(value) {
const matched = NG_SWITCH_USE_STRICT_EQUALS
? value === this._ngSwitch
: value == this._ngSwitch;
if ((typeof ngDevMode === 'undefined' || ngDevMode) && matched !== (value == this._ngSwitch)) {
console.warn(formatRuntimeError(2001 /* RuntimeErrorCode.EQUALITY_NG_SWITCH_DIFFERENCE */, 'As of Angular v17 the NgSwitch directive uses strict equality comparison === instead of == to match different cases. ' +
`Previously the case value "${stringifyValue(value)}" matched switch expression value "${stringifyValue(this._ngSwitch)}", but this is no longer the case with the stricter equality check. ` +
'Your comparison results return different results using === vs. == and you should adjust your ngSwitch expression and / or values to conform with the strict equality requirements.'));
}
this._lastCasesMatched ||= matched;
this._lastCaseCheckIndex++;
if (this._lastCaseCheckIndex === this._caseCount) {
this._updateDefaultCases(!this._lastCasesMatched);
this._lastCaseCheckIndex = 0;
this._lastCasesMatched = false;
}
return matched;
}
_updateDefaultCases(useDefault) {
if (this._defaultViews.length > 0 && useDefault !== this._defaultUsed) {
this._defaultUsed = useDefault;
for (const defaultView of this._defaultViews) {
defaultView.enforceState(useDefault);
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgSwitch, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.0", type: NgSwitch, isStandalone: true, selector: "[ngSwitch]", inputs: { ngSwitch: "ngSwitch" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgSwitch, decorators: [{
type: Directive,
args: [{
selector: '[ngSwitch]',
standalone: true,
}]
}], propDecorators: { ngSwitch: [{
type: Input
}] } });
/**
* @ngModule CommonModule
*
* @description
* Provides a switch case expression to match against an enclosing `ngSwitch` expression.
* When the expressions match, the given `NgSwitchCase` template is rendered.
* If multiple match expressions match the switch expression value, all of them are displayed.
*
* @usageNotes
*
* Within a switch container, `*ngSwitchCase` statements specify the match expressions
* as attributes. Include `*ngSwitchDefault` as the final case.
*
* ```
* <container-element [ngSwitch]="switch_expression">
* <some-element *ngSwitchCase="match_expression_1">...</some-element>
* ...
* <some-element *ngSwitchDefault>...</some-element>
* </container-element>
* ```
*
* Each switch-case statement contains an in-line HTML template or template reference
* that defines the subtree to be selected if the value of the match expression
* matches the value of the switch expression.
*
* As of Angular v17 the NgSwitch directive uses strict equality comparison (`===`) instead of
* loose equality (`==`) to match different cases.
*
* @publicApi
* @see {@link NgSwitch}
* @see {@link NgSwitchDefault}
*
*/
export class NgSwitchCase {
constructor(viewContainer, templateRef, ngSwitch) {
this.ngSwitch = ngSwitch;
if ((typeof ngDevMode === 'undefined' || ngDevMode) && !ngSwitch) {
throwNgSwitchProviderNotFoundError('ngSwitchCase', 'NgSwitchCase');
}
ngSwitch._addCase();
this._view = new SwitchView(viewContainer, templateRef);
}
/**
* Performs case matching. For internal use only.
* @nodoc
*/
ngDoCheck() {
this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgSwitchCase, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }, { token: NgSwitch, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.0", type: NgSwitchCase, isStandalone: true, selector: "[ngSwitchCase]", inputs: { ngSwitchCase: "ngSwitchCase" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgSwitchCase, decorators: [{
type: Directive,
args: [{
selector: '[ngSwitchCase]',
standalone: true,
}]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }, { type: NgSwitch, decorators: [{
type: Optional
}, {
type: Host
}] }], propDecorators: { ngSwitchCase: [{
type: Input
}] } });
/**
* @ngModule CommonModule
*
* @description
*
* Creates a view that is rendered when no `NgSwitchCase` expressions
* match the `NgSwitch` expression.
* This statement should be the final case in an `NgSwitch`.
*
* @publicApi
* @see {@link NgSwitch}
* @see {@link NgSwitchCase}
*
*/
export class NgSwitchDefault {
constructor(viewContainer, templateRef, ngSwitch) {
if ((typeof ngDevMode === 'undefined' || ngDevMode) && !ngSwitch) {
throwNgSwitchProviderNotFoundError('ngSwitchDefault', 'NgSwitchDefault');
}
ngSwitch._addDefault(new SwitchView(viewContainer, templateRef));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgSwitchDefault, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }, { token: NgSwitch, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.0", type: NgSwitchDefault, isStandalone: true, selector: "[ngSwitchDefault]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgSwitchDefault, decorators: [{
type: Directive,
args: [{
selector: '[ngSwitchDefault]',
standalone: true,
}]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }, { type: NgSwitch, decorators: [{
type: Optional
}, {
type: Host
}] }] });
function throwNgSwitchProviderNotFoundError(attrName, directiveName) {
throw new RuntimeError(2000 /* RuntimeErrorCode.PARENT_NG_SWITCH_NOT_FOUND */, `An element with the "${attrName}" attribute ` +
`(matching the "${directiveName}" directive) must be located inside an element with the "ngSwitch" attribute ` +
`(matching "NgSwitch" directive)`);
}
function stringifyValue(value) {
return typeof value === 'string' ? `'${value}'` : String(value);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdfc3dpdGNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tbW9uL3NyYy9kaXJlY3RpdmVzL25nX3N3aXRjaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQ0wsU0FBUyxFQUVULElBQUksRUFDSixLQUFLLEVBQ0wsUUFBUSxFQUNSLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsbUJBQW1CLElBQUksa0JBQWtCLEVBQ3pDLGFBQWEsSUFBSSxZQUFZLEdBQzlCLE1BQU0sZUFBZSxDQUFDO0FBSXZCLE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLHNCQUFzQixDQUFDOztBQUVqRSxNQUFNLE9BQU8sVUFBVTtJQUdyQixZQUNVLGlCQUFtQyxFQUNuQyxZQUFpQztRQURqQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQWtCO1FBQ25DLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQUpuQyxhQUFRLEdBQUcsS0FBSyxDQUFDO0lBS3RCLENBQUM7SUFFSixNQUFNO1FBQ0osSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsWUFBWSxDQUFDLE9BQWdCO1FBQzNCLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQixDQUFDO2FBQU0sSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFD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ZUFBZTs2R0FBZixlQUFlOztzR0FBZixlQUFlO2tCQUozQixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjs7MEJBS0ksUUFBUTs7MEJBQUksSUFBSTs7QUFVckIsU0FBUyxrQ0FBa0MsQ0FBQyxRQUFnQixFQUFFLGFBQXFCO0lBQ2pGLE1BQU0sSUFBSSxZQUFZLHlEQUVwQix3QkFBd0IsUUFBUSxjQUFjO1FBQzVDLGtCQUFrQixhQUFhLCtFQUErRTtRQUM5RyxpQ0FBaUMsQ0FDcEMsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxLQUFjO0lBQ3BDLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbEUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge1xuICBEaXJlY3RpdmUsXG4gIERvQ2hlY2ssXG4gIEhvc3QsXG4gIElucHV0LFxuICBPcHRpb25hbCxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIMm1Zm9ybWF0UnVudGltZUVycm9yIGFzIGZvcm1hdFJ1bnRpbWVFcnJvcixcbiAgybVSdW50aW1lRXJyb3IgYXMgUnVudGltZUVycm9yLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtSdW50aW1lRXJyb3JDb2RlfSBmcm9tICcuLi9lcnJvcnMnO1xuXG5pbXBvcnQge05HX1NXSVRDSF9VU0VfU1RSSUNUX0VRVUFMU30gZnJvbSAnLi9uZ19zd2l0Y2hfZXF1YWxpdHknO1xuXG5leHBvcnQgY2xhc3MgU3dpdGNoVmlldyB7XG4gIHByaXZhdGUgX2NyZWF0ZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF92aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHByaXZhdGUgX3RlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxPYmplY3Q+LFxuICApIHt9XG5cbiAgY3JlYXRlKCk6IHZvaWQge1xuICAgIHRoaXMuX2NyZWF0ZWQgPSB0cnVlO1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMuX3RlbXBsYXRlUmVmKTtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fY3JlYXRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYuY2xlYXIoKTtcbiAgfVxuXG4gIGVuZm9yY2VTdGF0ZShjcmVhdGVkOiBib29sZWFuKSB7XG4gICAgaWYgKGNyZWF0ZWQgJiYgIXRoaXMuX2NyZWF0ZWQpIHtcbiAgICAgIHRoaXMuY3JlYXRlKCk7XG4gICAgfSBlbHNlIGlmICghY3JlYXRlZCAmJiB0aGlzLl9jcmVhdGVkKSB7XG4gICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBUaGUgYFtuZ1N3aXRjaF1gIGRpcmVjdGl2ZSBvbiBhIGNvbnRhaW5lciBzcGVjaWZpZXMgYW4gZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0LlxuICogVGhlIGV4cHJlc3Npb25zIHRvIG1hdGNoIGFyZSBwcm92aWRlZCBieSBgbmdTd2l0Y2hDYXNlYCBkaXJlY3RpdmVzIG9uIHZpZXdzIHdpdGhpbiB0aGUgY29udGFpbmVyLlxuICogLSBFdmVyeSB2aWV3IHRoYXQgbWF0Y2hlcyBpcyByZW5kZXJlZC5cbiAqIC0gSWYgdGhlcmUgYXJlIG5vIG1hdGNoZXMsIGEgdmlldyB3aXRoIHRoZSBgbmdTd2l0Y2hEZWZhdWx0YCBkaXJlY3RpdmUgaXMgcmVuZGVyZWQuXG4gKiAtIEVsZW1lbnRzIHdpdGhpbiB0aGUgYFtOZ1N3aXRjaF1gIHN0YXRlbWVudCBidXQgb3V0c2lkZSBvZiBhbnkgYE5nU3dpdGNoQ2FzZWBcbiAqIG9yIGBuZ1N3aXRjaERlZmF1bHRgIGRpcmVjdGl2ZSBhcmUgcHJlc2VydmVkIGF0IHRoZSBsb2NhdGlvbi5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogRGVmaW5lIGEgY29udGFpbmVyIGVsZW1lbnQgZm9yIHRoZSBkaXJlY3RpdmUsIGFuZCBzcGVjaWZ5IHRoZSBzd2l0Y2ggZXhwcmVzc2lvblxuICogdG8gbWF0Y2ggYWdhaW5zdCBhcyBhbiBhdHRyaWJ1dGU6XG4gKlxuICogYGBgXG4gKiA8Y29udGFpbmVyLWVsZW1lbnQgW25nU3dpdGNoXT1cInN3aXRjaF9leHByZXNzaW9uXCI+XG4gKiBgYGBcbiAqXG4gKiBXaXRoaW4gdGhlIGNvbnRhaW5lciwgYCpuZ1N3aXRjaENhc2VgIHN0YXRlbWVudHMgc3BlY2lmeSB0aGUgbWF0Y2ggZXhwcmVzc2lvbnNcbiAqIGFzIGF0dHJpYnV0ZXMuIEluY2x1ZGUgYCpuZ1N3aXRjaERlZmF1bHRgIGFzIHRoZSBmaW5hbCBjYXNlLlxuICpcbiAqIGBgYFxuICogPGNvbnRhaW5lci1lbGVtZW50IFtuZ1N3aXRjaF09XCJzd2l0Y2hfZXhwcmVzc2lvblwiPlxuICogICAgPHNvbWUtZWxlbWVudCAqbmdTd2l0Y2hDYXNlPVwibWF0Y2hfZXhwcmVzc2lvbl8xXCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiAuLi5cbiAqICAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoRGVmYXVsdD4uLi48L3NvbWUtZWxlbWVudD5cbiAqIDwvY29udGFpbmVyLWVsZW1lbnQ+XG4gKiBgYGBcbiAqXG4gKiAjIyMgVXNhZ2UgRXhhbXBsZXNcbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIHVzZSBtb3JlIHRoYW4gb25lIGNhc2UgdG8gZGlzcGxheSB0aGUgc2FtZSB2aWV3OlxuICpcbiAqIGBgYFxuICogPGNvbnRhaW5lci1lbGVtZW50IFtuZ1N3aXRjaF09XCJzd2l0Y2hfZXhwcmVzc2lvblwiPlxuICogICA8IS0tIHRoZSBzYW1lIHZpZXcgY2FuIGJlIHNob3duIGluIG1vcmUgdGhhbiBvbmUgY2FzZSAtLT5cbiAqICAgPHNvbWUtZWxlbWVudCAqbmdTd2l0Y2hDYXNlPVwibWF0Y2hfZXhwcmVzc2lvbl8xXCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoQ2FzZT1cIm1hdGNoX2V4cHJlc3Npb25fMlwiPi4uLjwvc29tZS1lbGVtZW50PlxuICogICA8c29tZS1vdGhlci1lbGVtZW50ICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzNcIj4uLi48L3NvbWUtb3RoZXItZWxlbWVudD5cbiAqICAgPCEtLWRlZmF1bHQgY2FzZSB3aGVuIHRoZXJlIGFyZSBubyBtYXRjaGVzIC0tPlxuICogICA8c29tZS1lbGVtZW50ICpuZ1N3aXRjaERlZmF1bHQ+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiA8L2NvbnRhaW5lci1lbGVtZW50PlxuICogYGBgXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyBjYXNlcyBjYW4gYmUgbmVzdGVkOlxuICogYGBgXG4gKiA8Y29udGFpbmVyLWVsZW1lbnQgW25nU3dpdGNoXT1cInN3aXRjaF9leHByZXNzaW9uXCI+XG4gKiAgICAgICA8c29tZS1lbGVtZW50ICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzFcIj4uLi48L3NvbWUtZWxlbWVudD5cbiAqICAgICAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoQ2FzZT1cIm1hdGNoX2V4cHJlc3Npb25fMlwiPi4uLjwvc29tZS1lbGVtZW50PlxuICogICAgICAgPHNvbWUtb3RoZXItZWxlbWVudCAqbmdTd2l0Y2hDYXNlPVwibWF0Y2hfZXhwcmVzc2lvbl8zXCI+Li4uPC9zb21lLW90aGVyLWVsZW1lbnQ+XG4gKiAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzNcIj5cbiAqICAgICAgICAgPCEtLSB1c2UgYSBuZy1jb250YWluZXIgdG8gZ3JvdXAgbXVsdGlwbGUgcm9vdCBub2RlcyAtLT5cbiAqICAgICAgICAgPGlubmVyLWVsZW1lbnQ+PC9pbm5lci1lbGVtZW50PlxuICogICAgICAgICA8aW5uZXItb3RoZXItZWxlbWVudD48L2lubmVyLW90aGVyLWVsZW1lbnQ+XG4gKiAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAqICAgICAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoRGVmYXVsdD4uLi48L3NvbWUtZWxlbWVudD5cbiAqICAgICA8L2NvbnRhaW5lci1lbGVtZW50PlxuICogYGBgXG4gKlxuICogQHB1YmxpY0FwaVxuICogQHNlZSB7QGxpbmsgTmdTd2l0Y2hDYXNlfVxuICogQHNlZSB7QGxpbmsgTmdTd2l0Y2hEZWZhdWx0fVxuICogQHNlZSBbU3RydWN0dXJhbCBEaXJlY3RpdmVzXShndWlkZS9kaXJlY3RpdmVzL3N0cnVjdHVyYWwtZGlyZWN0aXZlcylcbiAqXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ1N3aXRjaF0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBOZ1N3aXRjaCB7XG4gIHByaXZhdGUgX2RlZmF1bHRWaWV3czogU3dpdGNoVmlld1tdID0gW107XG4gIHByaXZhdGUgX2RlZmF1bHRVc2VkID0gZmFsc2U7XG4gIHByaXZhdGUgX2Nhc2VDb3VudCA9IDA7XG4gIHByaXZhdGUgX2xhc3RDYXNlQ2hlY2tJbmRleCA9IDA7XG4gIHByaXZhdGUgX2xhc3RDYXNlc01hdGNoZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfbmdTd2l0Y2g6IGFueTtcblxuICBASW5wdXQoKVxuICBzZXQgbmdTd2l0Y2gobmV3VmFsdWU6IGFueSkge1xuICAgIHRoaXMuX25nU3dpdGNoID0gbmV3VmFsdWU7XG4gICAgaWYgKHRoaXMuX2Nhc2VDb3VudCA9PT0gMCkge1xuICAgICAgdGhpcy5fdXBkYXRlRGVmYXVsdENhc2VzKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2FkZENhc2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fY2FzZUNvdW50Kys7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF9hZGREZWZhdWx0KHZpZXc6IFN3aXRjaFZpZXcpIHtcbiAgICB0aGlzLl9kZWZhdWx0Vmlld3MucHVzaCh2aWV3KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX21hdGNoQ2FzZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgY29uc3QgbWF0Y2hlZCA9IE5HX1NXSVRDSF9VU0VfU1RSSUNUX0VRVUFMU1xuICAgICAgPyB2YWx1ZSA9PT0gdGhpcy5fbmdTd2l0Y2hcbiAgICAgIDogdmFsdWUgPT0gdGhpcy5fbmdTd2l0Y2g7XG4gICAgaWYgKCh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpICYmIG1hdGNoZWQgIT09ICh2YWx1ZSA9PSB0aGlzLl9uZ1N3aXRjaCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgZm9ybWF0UnVudGltZUVycm9yKFxuICAgICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuRVFVQUxJVFlfTkdfU1dJVENIX0RJRkZFUkVOQ0UsXG4gICAgICAgICAgJ0FzIG9mIEFuZ3VsYXIgdjE3IHRoZSBOZ1N3aXRjaCBkaXJlY3RpdmUgdXNlcyBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbiA9PT0gaW5zdGVhZCBvZiA9PSB0byBtYXRjaCBkaWZmZXJlbnQgY2FzZXMuICcgK1xuICAgICAgICAgICAgYFByZXZpb3VzbHkgdGhlIGNhc2UgdmFsdWUgXCIke3N0cmluZ2lmeVZhbHVlKFxuICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICl9XCIgbWF0Y2hlZCBzd2l0Y2ggZXhwcmVzc2lvbiB2YWx1ZSBcIiR7c3RyaW5naWZ5VmFsdWUoXG4gICAgICAgICAgICAgIHRoaXMuX25nU3dpdGNoLFxuICAgICAgICAgICAgKX1cIiwgYnV0IHRoaXMgaXMgbm8gbG9uZ2VyIHRoZSBjYXNlIHdpdGggdGhlIHN0cmljdGVyIGVxdWFsaXR5IGNoZWNrLiBgICtcbiAgICAgICAgICAgICdZb3VyIGNvbXBhcmlzb24gcmVzdWx0cyByZXR1cm4gZGlmZmVyZW50IHJlc3VsdHMgdXNpbmcgPT09IHZzLiA9PSBhbmQgeW91IHNob3VsZCBhZGp1c3QgeW91ciBuZ1N3aXRjaCBleHByZXNzaW9uIGFuZCAvIG9yIHZhbHVlcyB0byBjb25mb3JtIHdpdGggdGhlIHN0cmljdCBlcXVhbGl0eSByZXF1aXJlbWVudHMuJyxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuX2xhc3RDYXNlc01hdGNoZWQgfHw9IG1hdGNoZWQ7XG4gICAgdGhpcy5fbGFzdENhc2VDaGVja0luZGV4Kys7XG4gICAgaWYgKHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCA9PT0gdGhpcy5fY2FzZUNvdW50KSB7XG4gICAgICB0aGlzLl91cGRhdGVEZWZhdWx0Q2FzZXMoIXRoaXMuX2xhc3RDYXNlc01hdGNoZWQpO1xuICAgICAgdGhpcy5fbGFzdENhc2VDaGVja0luZGV4ID0gMDtcbiAgICAgIHRoaXMuX2xhc3RDYXNlc01hdGNoZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZWQ7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVEZWZhdWx0Q2FzZXModXNlRGVmYXVsdDogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLl9kZWZhdWx0Vmlld3MubGVuZ3RoID4gMCAmJiB1c2VEZWZhdWx0ICE9PSB0aGlzLl9kZWZhdWx0VXNlZCkge1xuICAgICAgdGhpcy5fZGVmYXVsdFVzZWQgPSB1c2VEZWZhdWx0O1xuICAgICAgZm9yIChjb25zdCBkZWZhdWx0VmlldyBvZiB0aGlzLl9kZWZhdWx0Vmlld3MpIHtcbiAgICAgICAgZGVmYXVsdFZpZXcuZW5mb3JjZVN0YXRlKHVzZURlZmF1bHQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFByb3ZpZGVzIGEgc3dpdGNoIGNhc2UgZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0IGFuIGVuY2xvc2luZyBgbmdTd2l0Y2hgIGV4cHJlc3Npb24uXG4gKiBXaGVuIHRoZSBleHByZXNzaW9ucyBtYXRjaCwgdGhlIGdpdmVuIGBOZ1N3aXRjaENhc2VgIHRlbXBsYXRlIGlzIHJlbmRlcmVkLlxuICogSWYgbXVsdGlwbGUgbWF0Y2ggZXhwcmVzc2lvbnMgbWF0Y2ggdGhlIHN3aXRjaCBleHByZXNzaW9uIHZhbHVlLCBhbGwgb2YgdGhlbSBhcmUgZGlzcGxheWVkLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogV2l0aGluIGEgc3dpdGNoIGNvbnRhaW5lciwgYCpuZ1N3aXRjaENhc2VgIHN0YXRlbWVudHMgc3BlY2lmeSB0aGUgbWF0Y2ggZXhwcmVzc2lvbnNcbiAqIGFzIGF0dHJpYnV0ZXMuIEluY2x1ZGUgYCpuZ1N3aXRjaERlZmF1bHRgIGFzIHRoZSBmaW5hbCBjYXNlLlxuICpcbiAqIGBgYFxuICogPGNvbnRhaW5lci1lbGVtZW50IFtuZ1N3aXRjaF09XCJzd2l0Y2hfZXhwcmVzc2lvblwiPlxuICogICA8c29tZS1lbGVtZW50ICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzFcIj4uLi48L3NvbWUtZWxlbWVudD5cbiAqICAgLi4uXG4gKiAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoRGVmYXVsdD4uLi48L3NvbWUtZWxlbWVudD5cbiAqIDwvY29udGFpbmVyLWVsZW1lbnQ+XG4gKiBgYGBcbiAqXG4gKiBFYWNoIHN3aXRjaC1jYXNlIHN0YXRlbWVudCBjb250YWlucyBhbiBpbi1saW5lIEhUTUwgdGVtcGxhdGUgb3IgdGVtcGxhdGUgcmVmZXJlbmNlXG4gKiB0aGF0IGRlZmluZXMgdGhlIHN1YnRyZWUgdG8gYmUgc2VsZWN0ZWQgaWYgdGhlIHZhbHVlIG9mIHRoZSBtYXRjaCBleHByZXNzaW9uXG4gKiBtYXRjaGVzIHRoZSB2YWx1ZSBvZiB0aGUgc3dpdGNoIGV4cHJlc3Npb24uXG4gKlxuICogQXMgb2YgQW5ndWxhciB2MTcgdGhlIE5nU3dpdGNoIGRpcmVjdGl2ZSB1c2VzIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29uIChgPT09YCkgaW5zdGVhZCBvZlxuICogbG9vc2UgZXF1YWxpdHkgKGA9PWApIHRvIG1hdGNoIGRpZmZlcmVudCBjYXNlcy5cbiAqXG4gKiBAcHVibGljQXBpXG4gKiBAc2VlIHtAbGluayBOZ1N3aXRjaH1cbiAqIEBzZWUge0BsaW5rIE5nU3dpdGNoRGVmYXVsdH1cbiAqXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ1N3aXRjaENhc2VdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgTmdTd2l0Y2hDYXNlIGltcGxlbWVudHMgRG9DaGVjayB7XG4gIHByaXZhdGUgX3ZpZXc6IFN3aXRjaFZpZXc7XG4gIC8qKlxuICAgKiBTdG9yZXMgdGhlIEhUTUwgdGVtcGxhdGUgdG8gYmUgc2VsZWN0ZWQgb24gbWF0Y2guXG4gICAqL1xuICBASW5wdXQoKSBuZ1N3aXRjaENhc2U6IGFueTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB2aWV3Q29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxPYmplY3Q+LFxuICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgcHJpdmF0ZSBuZ1N3aXRjaDogTmdTd2l0Y2gsXG4gICkge1xuICAgIGlmICgodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSAmJiAhbmdTd2l0Y2gpIHtcbiAgICAgIHRocm93TmdTd2l0Y2hQcm92aWRlck5vdEZvdW5kRXJyb3IoJ25nU3dpdGNoQ2FzZScsICdOZ1N3aXRjaENhc2UnKTtcbiAgICB9XG5cbiAgICBuZ1N3aXRjaC5fYWRkQ2FzZSgpO1xuICAgIHRoaXMuX3ZpZXcgPSBuZXcgU3dpdGNoVmlldyh2aWV3Q29udGFpbmVyLCB0ZW1wbGF0ZVJlZik7XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybXMgY2FzZSBtYXRjaGluZy4gRm9yIGludGVybmFsIHVzZSBvbmx5LlxuICAgKiBAbm9kb2NcbiAgICovXG4gIG5nRG9DaGVjaygpIHtcbiAgICB0aGlzLl92aWV3LmVuZm9yY2VTdGF0ZSh0aGlzLm5nU3dpdGNoLl9tYXRjaENhc2UodGhpcy5uZ1N3aXRjaENhc2UpKTtcbiAgfVxufVxuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBDcmVhdGVzIGEgdmlldyB0aGF0IGlzIHJlbmRlcmVkIHdoZW4gbm8gYE5nU3dpdGNoQ2FzZWAgZXhwcmVzc2lvbnNcbiAqIG1hdGNoIHRoZSBgTmdTd2l0Y2hgIGV4cHJlc3Npb24uXG4gKiBUaGlzIHN0YXRlbWVudCBzaG91bGQgYmUgdGhlIGZpbmFsIGNhc2UgaW4gYW4gYE5nU3dpdGNoYC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKiBAc2VlIHtAbGluayBOZ1N3aXRjaH1cbiAqIEBzZWUge0BsaW5rIE5nU3dpdGNoQ2FzZX1cbiAqXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ1N3aXRjaERlZmF1bHRdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgTmdTd2l0Y2hEZWZhdWx0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZixcbiAgICB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8T2JqZWN0PixcbiAgICBAT3B0aW9uYWwoKSBASG9zdCgpIG5nU3dpdGNoOiBOZ1N3aXRjaCxcbiAgKSB7XG4gICAgaWYgKCh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpICYmICFuZ1N3aXRjaCkge1xuICAgICAgdGhyb3dOZ1N3aXRjaFByb3ZpZGVyTm90Rm91bmRFcnJvcignbmdTd2l0Y2hEZWZhdWx0JywgJ05nU3dpdGNoRGVmYXVsdCcpO1xuICAgIH1cblxuICAgIG5nU3dpdGNoLl9hZGREZWZhdWx0KG5ldyBTd2l0Y2hWaWV3KHZpZXdDb250YWluZXIsIHRlbXBsYXRlUmVmKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdGhyb3dOZ1N3aXRjaFByb3ZpZGVyTm90Rm91bmRFcnJvcihhdHRyTmFtZTogc3RyaW5nLCBkaXJlY3RpdmVOYW1lOiBzdHJpbmcpOiBuZXZlciB7XG4gIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgUnVudGltZUVycm9yQ29kZS5QQVJFTlRfTkdfU1dJVENIX05PVF9GT1VORCxcbiAgICBgQW4gZWxlbWVudCB3aXRoIHRoZSBcIiR7YXR0ck5hbWV9XCIgYXR0cmlidXRlIGAgK1xuICAgICAgYChtYXRjaGluZyB0aGUgXCIke2RpcmVjdGl2ZU5hbWV9XCIgZGlyZWN0aXZlKSBtdXN0IGJlIGxvY2F0ZWQgaW5zaWRlIGFuIGVsZW1lbnQgd2l0aCB0aGUgXCJuZ1N3aXRjaFwiIGF0dHJpYnV0ZSBgICtcbiAgICAgIGAobWF0Y2hpbmcgXCJOZ1N3aXRjaFwiIGRpcmVjdGl2ZSlgLFxuICApO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnlWYWx1ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gYCcke3ZhbHVlfSdgIDogU3RyaW5nKHZhbHVlKTtcbn1cbiJdfQ==