UNPKG

@angular/common

Version:

Angular - commonly needed directives and services

247 lines 25.2 kB
/** * @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, Input, TemplateRef, ViewContainerRef, ɵstringify as stringify } from '@angular/core'; import * as i0 from "@angular/core"; /** * A structural directive that conditionally includes a template based on the value of * an expression coerced to Boolean. * When the expression evaluates to true, Angular renders the template * provided in a `then` clause, and when false or null, * Angular renders the template provided in an optional `else` clause. The default * template for the `else` clause is blank. * * A [shorthand form](guide/structural-directives#asterisk) of the directive, * `*ngIf="condition"`, is generally used, provided * as an attribute of the anchor element for the inserted template. * Angular expands this into a more explicit version, in which the anchor element * is contained in an `<ng-template>` element. * * Simple form with shorthand syntax: * * ``` * <div *ngIf="condition">Content to render when condition is true.</div> * ``` * * Simple form with expanded syntax: * * ``` * <ng-template [ngIf]="condition"><div>Content to render when condition is * true.</div></ng-template> * ``` * * Form with an "else" block: * * ``` * <div *ngIf="condition; else elseBlock">Content to render when condition is true.</div> * <ng-template #elseBlock>Content to render when condition is false.</ng-template> * ``` * * Shorthand form with "then" and "else" blocks: * * ``` * <div *ngIf="condition; then thenBlock else elseBlock"></div> * <ng-template #thenBlock>Content to render when condition is true.</ng-template> * <ng-template #elseBlock>Content to render when condition is false.</ng-template> * ``` * * Form with storing the value locally: * * ``` * <div *ngIf="condition as value; else elseBlock">{{value}}</div> * <ng-template #elseBlock>Content to render when value is null.</ng-template> * ``` * * @usageNotes * * The `*ngIf` directive is most commonly used to conditionally show an inline template, * as seen in the following example. * The default `else` template is blank. * * {@example common/ngIf/ts/module.ts region='NgIfSimple'} * * ### Showing an alternative template using `else` * * To display a template when `expression` evaluates to false, use an `else` template * binding as shown in the following example. * The `else` binding points to an `<ng-template>` element labeled `#elseBlock`. * The template can be defined anywhere in the component view, but is typically placed right after * `ngIf` for readability. * * {@example common/ngIf/ts/module.ts region='NgIfElse'} * * ### Using an external `then` template * * In the previous example, the then-clause template is specified inline, as the content of the * tag that contains the `ngIf` directive. You can also specify a template that is defined * externally, by referencing a labeled `<ng-template>` element. When you do this, you can * change which template to use at runtime, as shown in the following example. * * {@example common/ngIf/ts/module.ts region='NgIfThenElse'} * * ### Storing a conditional result in a variable * * You might want to show a set of properties from the same object. If you are waiting * for asynchronous data, the object can be undefined. * In this case, you can use `ngIf` and store the result of the condition in a local * variable as shown in the following example. * * {@example common/ngIf/ts/module.ts region='NgIfAs'} * * This code uses only one `AsyncPipe`, so only one subscription is created. * The conditional statement stores the result of `userStream|async` in the local variable `user`. * You can then bind the local `user` repeatedly. * * The conditional displays the data only if `userStream` returns a value, * so you don't need to use the * safe-navigation-operator (`?.`) * to guard against null values when accessing properties. * You can display an alternative template while waiting for the data. * * ### Shorthand syntax * * The shorthand syntax `*ngIf` expands into two separate template specifications * for the "then" and "else" clauses. For example, consider the following shorthand statement, * that is meant to show a loading page while waiting for data to be loaded. * * ``` * <div class="hero-list" *ngIf="heroes else loading"> * ... * </div> * * <ng-template #loading> * <div>Loading...</div> * </ng-template> * ``` * * You can see that the "else" clause references the `<ng-template>` * with the `#loading` label, and the template for the "then" clause * is provided as the content of the anchor element. * * However, when Angular expands the shorthand syntax, it creates * another `<ng-template>` tag, with `ngIf` and `ngIfElse` directives. * The anchor element containing the template for the "then" clause becomes * the content of this unlabeled `<ng-template>` tag. * * ``` * <ng-template [ngIf]="heroes" [ngIfElse]="loading"> * <div class="hero-list"> * ... * </div> * </ng-template> * * <ng-template #loading> * <div>Loading...</div> * </ng-template> * ``` * * The presence of the implicit template object has implications for the nesting of * structural directives. For more on this subject, see * [Structural Directives](guide/structural-directives#one-per-element). * * @ngModule CommonModule * @publicApi */ class NgIf { constructor(_viewContainer, templateRef) { this._viewContainer = _viewContainer; this._context = new NgIfContext(); this._thenTemplateRef = null; this._elseTemplateRef = null; this._thenViewRef = null; this._elseViewRef = null; this._thenTemplateRef = templateRef; } /** * The Boolean expression to evaluate as the condition for showing a template. */ set ngIf(condition) { this._context.$implicit = this._context.ngIf = condition; this._updateView(); } /** * A template to show if the condition expression evaluates to true. */ set ngIfThen(templateRef) { assertTemplate('ngIfThen', templateRef); this._thenTemplateRef = templateRef; this._thenViewRef = null; // clear previous view if any. this._updateView(); } /** * A template to show if the condition expression evaluates to false. */ set ngIfElse(templateRef) { assertTemplate('ngIfElse', templateRef); this._elseTemplateRef = templateRef; this._elseViewRef = null; // clear previous view if any. this._updateView(); } _updateView() { if (this._context.$implicit) { if (!this._thenViewRef) { this._viewContainer.clear(); this._elseViewRef = null; if (this._thenTemplateRef) { this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context); } } } else { if (!this._elseViewRef) { this._viewContainer.clear(); this._thenViewRef = null; if (this._elseTemplateRef) { this._elseViewRef = this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context); } } } } /** * Asserts the correct type of the context for the template that `NgIf` will render. * * The presence of this method is a signal to the Ivy template type-check compiler that the * `NgIf` structural directive renders its template with a specific context type. */ static ngTemplateContextGuard(dir, ctx) { return true; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: NgIf, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.3", type: NgIf, isStandalone: true, selector: "[ngIf]", inputs: { ngIf: "ngIf", ngIfThen: "ngIfThen", ngIfElse: "ngIfElse" }, ngImport: i0 }); } } export { NgIf }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: NgIf, decorators: [{ type: Directive, args: [{ selector: '[ngIf]', standalone: true, }] }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { ngIf: [{ type: Input }], ngIfThen: [{ type: Input }], ngIfElse: [{ type: Input }] } }); /** * @publicApi */ export class NgIfContext { constructor() { this.$implicit = null; this.ngIf = null; } } function assertTemplate(property, templateRef) { const isTemplateRefOrNull = !!(!templateRef || templateRef.createEmbeddedView); if (!isTemplateRefOrNull) { throw new Error(`${property} must be a TemplateRef, but received '${stringify(templateRef)}'.`); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdfaWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21tb24vc3JjL2RpcmVjdGl2ZXMvbmdfaWYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBbUIsS0FBSyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLElBQUksU0FBUyxFQUFDLE1BQU0sZUFBZSxDQUFDOztBQUd4SDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMElHO0FBQ0gsTUFJYSxJQUFJO0lBT2YsWUFBb0IsY0FBZ0MsRUFBRSxXQUF3QztRQUExRSxtQkFBYyxHQUFkLGNBQWMsQ0FBa0I7UUFONUMsYUFBUSxHQUFtQixJQUFJLFdBQVcsRUFBSyxDQUFDO1FBQ2hELHFCQUFnQixHQUFxQyxJQUFJLENBQUM7UUFDMUQscUJBQWdCLEdBQXFDLElBQUksQ0FBQztRQUMxRCxpQkFBWSxHQUF5QyxJQUFJLENBQUM7UUFDMUQsaUJBQVksR0FBeUMsSUFBSSxDQUFDO1FBR2hFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7SUFDdEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFDSSxJQUFJLENBQUMsU0FBWTtRQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUM7UUFDekQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNILElBQ0ksUUFBUSxDQUFDLFdBQTZDO1FBQ3hELGNBQWMsQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztRQUNwQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxDQUFFLDhCQUE4QjtRQUN6RCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFDSSxRQUFRLENBQUMsV0FBNkM7UUFDeEQsY0FBYyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLENBQUUsOEJBQThCO1FBQ3pELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRU8sV0FBVztRQUNqQixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFO1lBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUN0QixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7b0JBQ3pCLElBQUksQ0FBQyxZQUFZO3dCQUNiLElBQUksQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztpQkFDbEY7YUFDRjtTQUNGO2FBQU07WUFDTCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDdEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7Z0JBQ3pCLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO29CQUN6QixJQUFJLENBQUMsWUFBWTt3QkFDYixJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ2xGO2FBQ0Y7U0FDRjtJQUNILENBQUM7SUFlRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxzQkFBc0IsQ0FBSSxHQUFZLEVBQUUsR0FBUTtRQUVyRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7eUhBdEZVLElBQUk7NkdBQUosSUFBSTs7U0FBSixJQUFJO3NHQUFKLElBQUk7a0JBSmhCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLFFBQVE7b0JBQ2xCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjtpSUFnQkssSUFBSTtzQkFEUCxLQUFLO2dCQVVGLFFBQVE7c0JBRFgsS0FBSztnQkFZRixRQUFRO3NCQURYLEtBQUs7O0FBdURSOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFBeEI7UUFDUyxjQUFTLEdBQU0sSUFBSyxDQUFDO1FBQ3JCLFNBQUksR0FBTSxJQUFLLENBQUM7SUFDekIsQ0FBQztDQUFBO0FBRUQsU0FBUyxjQUFjLENBQUMsUUFBZ0IsRUFBRSxXQUFrQztJQUMxRSxNQUFNLG1CQUFtQixHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQy9FLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtRQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsUUFBUSx5Q0FBeUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUNqRztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtEaXJlY3RpdmUsIEVtYmVkZGVkVmlld1JlZiwgSW5wdXQsIFRlbXBsYXRlUmVmLCBWaWV3Q29udGFpbmVyUmVmLCDJtXN0cmluZ2lmeSBhcyBzdHJpbmdpZnl9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5cbi8qKlxuICogQSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSB0aGF0IGNvbmRpdGlvbmFsbHkgaW5jbHVkZXMgYSB0ZW1wbGF0ZSBiYXNlZCBvbiB0aGUgdmFsdWUgb2ZcbiAqIGFuIGV4cHJlc3Npb24gY29lcmNlZCB0byBCb29sZWFuLlxuICogV2hlbiB0aGUgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZSwgQW5ndWxhciByZW5kZXJzIHRoZSB0ZW1wbGF0ZVxuICogcHJvdmlkZWQgaW4gYSBgdGhlbmAgY2xhdXNlLCBhbmQgd2hlbiAgZmFsc2Ugb3IgbnVsbCxcbiAqIEFuZ3VsYXIgcmVuZGVycyB0aGUgdGVtcGxhdGUgcHJvdmlkZWQgaW4gYW4gb3B0aW9uYWwgYGVsc2VgIGNsYXVzZS4gVGhlIGRlZmF1bHRcbiAqIHRlbXBsYXRlIGZvciB0aGUgYGVsc2VgIGNsYXVzZSBpcyBibGFuay5cbiAqXG4gKiBBIFtzaG9ydGhhbmQgZm9ybV0oZ3VpZGUvc3RydWN0dXJhbC1kaXJlY3RpdmVzI2FzdGVyaXNrKSBvZiB0aGUgZGlyZWN0aXZlLFxuICogYCpuZ0lmPVwiY29uZGl0aW9uXCJgLCBpcyBnZW5lcmFsbHkgdXNlZCwgcHJvdmlkZWRcbiAqIGFzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgYW5jaG9yIGVsZW1lbnQgZm9yIHRoZSBpbnNlcnRlZCB0ZW1wbGF0ZS5cbiAqIEFuZ3VsYXIgZXhwYW5kcyB0aGlzIGludG8gYSBtb3JlIGV4cGxpY2l0IHZlcnNpb24sIGluIHdoaWNoIHRoZSBhbmNob3IgZWxlbWVudFxuICogaXMgY29udGFpbmVkIGluIGFuIGA8bmctdGVtcGxhdGU+YCBlbGVtZW50LlxuICpcbiAqIFNpbXBsZSBmb3JtIHdpdGggc2hvcnRoYW5kIHN5bnRheDpcbiAqXG4gKiBgYGBcbiAqIDxkaXYgKm5nSWY9XCJjb25kaXRpb25cIj5Db250ZW50IHRvIHJlbmRlciB3aGVuIGNvbmRpdGlvbiBpcyB0cnVlLjwvZGl2PlxuICogYGBgXG4gKlxuICogU2ltcGxlIGZvcm0gd2l0aCBleHBhbmRlZCBzeW50YXg6XG4gKlxuICogYGBgXG4gKiA8bmctdGVtcGxhdGUgW25nSWZdPVwiY29uZGl0aW9uXCI+PGRpdj5Db250ZW50IHRvIHJlbmRlciB3aGVuIGNvbmRpdGlvbiBpc1xuICogdHJ1ZS48L2Rpdj48L25nLXRlbXBsYXRlPlxuICogYGBgXG4gKlxuICogRm9ybSB3aXRoIGFuIFwiZWxzZVwiIGJsb2NrOlxuICpcbiAqIGBgYFxuICogPGRpdiAqbmdJZj1cImNvbmRpdGlvbjsgZWxzZSBlbHNlQmxvY2tcIj5Db250ZW50IHRvIHJlbmRlciB3aGVuIGNvbmRpdGlvbiBpcyB0cnVlLjwvZGl2PlxuICogPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+Q29udGVudCB0byByZW5kZXIgd2hlbiBjb25kaXRpb24gaXMgZmFsc2UuPC9uZy10ZW1wbGF0ZT5cbiAqIGBgYFxuICpcbiAqIFNob3J0aGFuZCBmb3JtIHdpdGggXCJ0aGVuXCIgYW5kIFwiZWxzZVwiIGJsb2NrczpcbiAqXG4gKiBgYGBcbiAqIDxkaXYgKm5nSWY9XCJjb25kaXRpb247IHRoZW4gdGhlbkJsb2NrIGVsc2UgZWxzZUJsb2NrXCI+PC9kaXY+XG4gKiA8bmctdGVtcGxhdGUgI3RoZW5CbG9jaz5Db250ZW50IHRvIHJlbmRlciB3aGVuIGNvbmRpdGlvbiBpcyB0cnVlLjwvbmctdGVtcGxhdGU+XG4gKiA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5Db250ZW50IHRvIHJlbmRlciB3aGVuIGNvbmRpdGlvbiBpcyBmYWxzZS48L25nLXRlbXBsYXRlPlxuICogYGBgXG4gKlxuICogRm9ybSB3aXRoIHN0b3JpbmcgdGhlIHZhbHVlIGxvY2FsbHk6XG4gKlxuICogYGBgXG4gKiA8ZGl2ICpuZ0lmPVwiY29uZGl0aW9uIGFzIHZhbHVlOyBlbHNlIGVsc2VCbG9ja1wiPnt7dmFsdWV9fTwvZGl2PlxuICogPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+Q29udGVudCB0byByZW5kZXIgd2hlbiB2YWx1ZSBpcyBudWxsLjwvbmctdGVtcGxhdGU+XG4gKiBgYGBcbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqIFRoZSBgKm5nSWZgIGRpcmVjdGl2ZSBpcyBtb3N0IGNvbW1vbmx5IHVzZWQgdG8gY29uZGl0aW9uYWxseSBzaG93IGFuIGlubGluZSB0ZW1wbGF0ZSxcbiAqIGFzIHNlZW4gaW4gdGhlIGZvbGxvd2luZyAgZXhhbXBsZS5cbiAqIFRoZSBkZWZhdWx0IGBlbHNlYCB0ZW1wbGF0ZSBpcyBibGFuay5cbiAqXG4gKiB7QGV4YW1wbGUgY29tbW9uL25nSWYvdHMvbW9kdWxlLnRzIHJlZ2lvbj0nTmdJZlNpbXBsZSd9XG4gKlxuICogIyMjIFNob3dpbmcgYW4gYWx0ZXJuYXRpdmUgdGVtcGxhdGUgdXNpbmcgYGVsc2VgXG4gKlxuICogVG8gZGlzcGxheSBhIHRlbXBsYXRlIHdoZW4gYGV4cHJlc3Npb25gIGV2YWx1YXRlcyB0byBmYWxzZSwgdXNlIGFuIGBlbHNlYCB0ZW1wbGF0ZVxuICogYmluZGluZyBhcyBzaG93biBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGUuXG4gKiBUaGUgYGVsc2VgIGJpbmRpbmcgcG9pbnRzIHRvIGFuIGA8bmctdGVtcGxhdGU+YCAgZWxlbWVudCBsYWJlbGVkIGAjZWxzZUJsb2NrYC5cbiAqIFRoZSB0ZW1wbGF0ZSBjYW4gYmUgZGVmaW5lZCBhbnl3aGVyZSBpbiB0aGUgY29tcG9uZW50IHZpZXcsIGJ1dCBpcyB0eXBpY2FsbHkgcGxhY2VkIHJpZ2h0IGFmdGVyXG4gKiBgbmdJZmAgZm9yIHJlYWRhYmlsaXR5LlxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vbmdJZi90cy9tb2R1bGUudHMgcmVnaW9uPSdOZ0lmRWxzZSd9XG4gKlxuICogIyMjIFVzaW5nIGFuIGV4dGVybmFsIGB0aGVuYCB0ZW1wbGF0ZVxuICpcbiAqIEluIHRoZSBwcmV2aW91cyBleGFtcGxlLCB0aGUgdGhlbi1jbGF1c2UgdGVtcGxhdGUgaXMgc3BlY2lmaWVkIGlubGluZSwgYXMgdGhlIGNvbnRlbnQgb2YgdGhlXG4gKiB0YWcgdGhhdCBjb250YWlucyB0aGUgYG5nSWZgIGRpcmVjdGl2ZS4gWW91IGNhbiBhbHNvIHNwZWNpZnkgYSB0ZW1wbGF0ZSB0aGF0IGlzIGRlZmluZWRcbiAqIGV4dGVybmFsbHksIGJ5IHJlZmVyZW5jaW5nIGEgbGFiZWxlZCBgPG5nLXRlbXBsYXRlPmAgZWxlbWVudC4gV2hlbiB5b3UgZG8gdGhpcywgeW91IGNhblxuICogY2hhbmdlIHdoaWNoIHRlbXBsYXRlIHRvIHVzZSBhdCBydW50aW1lLCBhcyBzaG93biBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGUuXG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9uZ0lmL3RzL21vZHVsZS50cyByZWdpb249J05nSWZUaGVuRWxzZSd9XG4gKlxuICogIyMjIFN0b3JpbmcgYSBjb25kaXRpb25hbCByZXN1bHQgaW4gYSB2YXJpYWJsZVxuICpcbiAqIFlvdSBtaWdodCB3YW50IHRvIHNob3cgYSBzZXQgb2YgcHJvcGVydGllcyBmcm9tIHRoZSBzYW1lIG9iamVjdC4gSWYgeW91IGFyZSB3YWl0aW5nXG4gKiBmb3IgYXN5bmNocm9ub3VzIGRhdGEsIHRoZSBvYmplY3QgY2FuIGJlIHVuZGVmaW5lZC5cbiAqIEluIHRoaXMgY2FzZSwgeW91IGNhbiB1c2UgYG5nSWZgIGFuZCBzdG9yZSB0aGUgcmVzdWx0IG9mIHRoZSBjb25kaXRpb24gaW4gYSBsb2NhbFxuICogdmFyaWFibGUgYXMgc2hvd24gaW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLlxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vbmdJZi90cy9tb2R1bGUudHMgcmVnaW9uPSdOZ0lmQXMnfVxuICpcbiAqIFRoaXMgY29kZSB1c2VzIG9ubHkgb25lIGBBc3luY1BpcGVgLCBzbyBvbmx5IG9uZSBzdWJzY3JpcHRpb24gaXMgY3JlYXRlZC5cbiAqIFRoZSBjb25kaXRpb25hbCBzdGF0ZW1lbnQgc3RvcmVzIHRoZSByZXN1bHQgb2YgYHVzZXJTdHJlYW18YXN5bmNgIGluIHRoZSBsb2NhbCB2YXJpYWJsZSBgdXNlcmAuXG4gKiBZb3UgY2FuIHRoZW4gYmluZCB0aGUgbG9jYWwgYHVzZXJgIHJlcGVhdGVkbHkuXG4gKlxuICogVGhlIGNvbmRpdGlvbmFsIGRpc3BsYXlzIHRoZSBkYXRhIG9ubHkgaWYgYHVzZXJTdHJlYW1gIHJldHVybnMgYSB2YWx1ZSxcbiAqIHNvIHlvdSBkb24ndCBuZWVkIHRvIHVzZSB0aGVcbiAqIHNhZmUtbmF2aWdhdGlvbi1vcGVyYXRvciAoYD8uYClcbiAqIHRvIGd1YXJkIGFnYWluc3QgbnVsbCB2YWx1ZXMgd2hlbiBhY2Nlc3NpbmcgcHJvcGVydGllcy5cbiAqIFlvdSBjYW4gZGlzcGxheSBhbiBhbHRlcm5hdGl2ZSB0ZW1wbGF0ZSB3aGlsZSB3YWl0aW5nIGZvciB0aGUgZGF0YS5cbiAqXG4gKiAjIyMgU2hvcnRoYW5kIHN5bnRheFxuICpcbiAqIFRoZSBzaG9ydGhhbmQgc3ludGF4IGAqbmdJZmAgZXhwYW5kcyBpbnRvIHR3byBzZXBhcmF0ZSB0ZW1wbGF0ZSBzcGVjaWZpY2F0aW9uc1xuICogZm9yIHRoZSBcInRoZW5cIiBhbmQgXCJlbHNlXCIgY2xhdXNlcy4gRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgc2hvcnRoYW5kIHN0YXRlbWVudCxcbiAqIHRoYXQgaXMgbWVhbnQgdG8gc2hvdyBhIGxvYWRpbmcgcGFnZSB3aGlsZSB3YWl0aW5nIGZvciBkYXRhIHRvIGJlIGxvYWRlZC5cbiAqXG4gKiBgYGBcbiAqIDxkaXYgY2xhc3M9XCJoZXJvLWxpc3RcIiAqbmdJZj1cImhlcm9lcyBlbHNlIGxvYWRpbmdcIj5cbiAqICAuLi5cbiAqIDwvZGl2PlxuICpcbiAqIDxuZy10ZW1wbGF0ZSAjbG9hZGluZz5cbiAqICA8ZGl2PkxvYWRpbmcuLi48L2Rpdj5cbiAqIDwvbmctdGVtcGxhdGU+XG4gKiBgYGBcbiAqXG4gKiBZb3UgY2FuIHNlZSB0aGF0IHRoZSBcImVsc2VcIiBjbGF1c2UgcmVmZXJlbmNlcyB0aGUgYDxuZy10ZW1wbGF0ZT5gXG4gKiB3aXRoIHRoZSBgI2xvYWRpbmdgIGxhYmVsLCBhbmQgdGhlIHRlbXBsYXRlIGZvciB0aGUgXCJ0aGVuXCIgY2xhdXNlXG4gKiBpcyBwcm92aWRlZCBhcyB0aGUgY29udGVudCBvZiB0aGUgYW5jaG9yIGVsZW1lbnQuXG4gKlxuICogSG93ZXZlciwgd2hlbiBBbmd1bGFyIGV4cGFuZHMgdGhlIHNob3J0aGFuZCBzeW50YXgsIGl0IGNyZWF0ZXNcbiAqIGFub3RoZXIgYDxuZy10ZW1wbGF0ZT5gIHRhZywgd2l0aCBgbmdJZmAgYW5kIGBuZ0lmRWxzZWAgZGlyZWN0aXZlcy5cbiAqIFRoZSBhbmNob3IgZWxlbWVudCBjb250YWluaW5nIHRoZSB0ZW1wbGF0ZSBmb3IgdGhlIFwidGhlblwiIGNsYXVzZSBiZWNvbWVzXG4gKiB0aGUgY29udGVudCBvZiB0aGlzIHVubGFiZWxlZCBgPG5nLXRlbXBsYXRlPmAgdGFnLlxuICpcbiAqIGBgYFxuICogPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImhlcm9lc1wiIFtuZ0lmRWxzZV09XCJsb2FkaW5nXCI+XG4gKiAgPGRpdiBjbGFzcz1cImhlcm8tbGlzdFwiPlxuICogICAuLi5cbiAqICA8L2Rpdj5cbiAqIDwvbmctdGVtcGxhdGU+XG4gKlxuICogPG5nLXRlbXBsYXRlICNsb2FkaW5nPlxuICogIDxkaXY+TG9hZGluZy4uLjwvZGl2PlxuICogPC9uZy10ZW1wbGF0ZT5cbiAqIGBgYFxuICpcbiAqIFRoZSBwcmVzZW5jZSBvZiB0aGUgaW1wbGljaXQgdGVtcGxhdGUgb2JqZWN0IGhhcyBpbXBsaWNhdGlvbnMgZm9yIHRoZSBuZXN0aW5nIG9mXG4gKiBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZXMuIEZvciBtb3JlIG9uIHRoaXMgc3ViamVjdCwgc2VlXG4gKiBbU3RydWN0dXJhbCBEaXJlY3RpdmVzXShndWlkZS9zdHJ1Y3R1cmFsLWRpcmVjdGl2ZXMjb25lLXBlci1lbGVtZW50KS5cbiAqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAcHVibGljQXBpXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ0lmXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIE5nSWY8VCA9IHVua25vd24+IHtcbiAgcHJpdmF0ZSBfY29udGV4dDogTmdJZkNvbnRleHQ8VD4gPSBuZXcgTmdJZkNvbnRleHQ8VD4oKTtcbiAgcHJpdmF0ZSBfdGhlblRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxOZ0lmQ29udGV4dDxUPj58bnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2Vsc2VUZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8TmdJZkNvbnRleHQ8VD4+fG51bGwgPSBudWxsO1xuICBwcml2YXRlIF90aGVuVmlld1JlZjogRW1iZWRkZWRWaWV3UmVmPE5nSWZDb250ZXh0PFQ+PnxudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfZWxzZVZpZXdSZWY6IEVtYmVkZGVkVmlld1JlZjxOZ0lmQ29udGV4dDxUPj58bnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZiwgdGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPE5nSWZDb250ZXh0PFQ+Pikge1xuICAgIHRoaXMuX3RoZW5UZW1wbGF0ZVJlZiA9IHRlbXBsYXRlUmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBCb29sZWFuIGV4cHJlc3Npb24gdG8gZXZhbHVhdGUgYXMgdGhlIGNvbmRpdGlvbiBmb3Igc2hvd2luZyBhIHRlbXBsYXRlLlxuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IG5nSWYoY29uZGl0aW9uOiBUKSB7XG4gICAgdGhpcy5fY29udGV4dC4kaW1wbGljaXQgPSB0aGlzLl9jb250ZXh0Lm5nSWYgPSBjb25kaXRpb247XG4gICAgdGhpcy5fdXBkYXRlVmlldygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgdGVtcGxhdGUgdG8gc2hvdyBpZiB0aGUgY29uZGl0aW9uIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIHRydWUuXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgbmdJZlRoZW4odGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPE5nSWZDb250ZXh0PFQ+PnxudWxsKSB7XG4gICAgYXNzZXJ0VGVtcGxhdGUoJ25nSWZUaGVuJywgdGVtcGxhdGVSZWYpO1xuICAgIHRoaXMuX3RoZW5UZW1wbGF0ZVJlZiA9IHRlbXBsYXRlUmVmO1xuICAgIHRoaXMuX3RoZW5WaWV3UmVmID0gbnVsbDsgIC8vIGNsZWFyIHByZXZpb3VzIHZpZXcgaWYgYW55LlxuICAgIHRoaXMuX3VwZGF0ZVZpZXcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHRlbXBsYXRlIHRvIHNob3cgaWYgdGhlIGNvbmRpdGlvbiBleHByZXNzaW9uIGV2YWx1YXRlcyB0byBmYWxzZS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBuZ0lmRWxzZSh0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8TmdJZkNvbnRleHQ8VD4+fG51bGwpIHtcbiAgICBhc3NlcnRUZW1wbGF0ZSgnbmdJZkVsc2UnLCB0ZW1wbGF0ZVJlZik7XG4gICAgdGhpcy5fZWxzZVRlbXBsYXRlUmVmID0gdGVtcGxhdGVSZWY7XG4gICAgdGhpcy5fZWxzZVZpZXdSZWYgPSBudWxsOyAgLy8gY2xlYXIgcHJldmlvdXMgdmlldyBpZiBhbnkuXG4gICAgdGhpcy5fdXBkYXRlVmlldygpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlVmlldygpIHtcbiAgICBpZiAodGhpcy5fY29udGV4dC4kaW1wbGljaXQpIHtcbiAgICAgIGlmICghdGhpcy5fdGhlblZpZXdSZWYpIHtcbiAgICAgICAgdGhpcy5fdmlld0NvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB0aGlzLl9lbHNlVmlld1JlZiA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLl90aGVuVGVtcGxhdGVSZWYpIHtcbiAgICAgICAgICB0aGlzLl90aGVuVmlld1JlZiA9XG4gICAgICAgICAgICAgIHRoaXMuX3ZpZXdDb250YWluZXIuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMuX3RoZW5UZW1wbGF0ZVJlZiwgdGhpcy5fY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLl9lbHNlVmlld1JlZikge1xuICAgICAgICB0aGlzLl92aWV3Q29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX3RoZW5WaWV3UmVmID0gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMuX2Vsc2VUZW1wbGF0ZVJlZikge1xuICAgICAgICAgIHRoaXMuX2Vsc2VWaWV3UmVmID1cbiAgICAgICAgICAgICAgdGhpcy5fdmlld0NvbnRhaW5lci5jcmVhdGVFbWJlZGRlZFZpZXcodGhpcy5fZWxzZVRlbXBsYXRlUmVmLCB0aGlzLl9jb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHVibGljIHN0YXRpYyBuZ0lmVXNlSWZUeXBlR3VhcmQ6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEFzc2VydCB0aGUgY29ycmVjdCB0eXBlIG9mIHRoZSBleHByZXNzaW9uIGJvdW5kIHRvIHRoZSBgbmdJZmAgaW5wdXQgd2l0aGluIHRoZSB0ZW1wbGF0ZS5cbiAgICpcbiAgICogVGhlIHByZXNlbmNlIG9mIHRoaXMgc3RhdGljIGZpZWxkIGlzIGEgc2lnbmFsIHRvIHRoZSBJdnkgdGVtcGxhdGUgdHlwZSBjaGVjayBjb21waWxlciB0aGF0XG4gICAqIHdoZW4gdGhlIGBOZ0lmYCBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSByZW5kZXJzIGl0cyB0ZW1wbGF0ZSwgdGhlIHR5cGUgb2YgdGhlIGV4cHJlc3Npb24gYm91bmRcbiAgICogdG8gYG5nSWZgIHNob3VsZCBiZSBuYXJyb3dlZCBpbiBzb21lIHdheS4gRm9yIGBOZ0lmYCwgdGhlIGJpbmRpbmcgZXhwcmVzc2lvbiBpdHNlbGYgaXMgdXNlZCB0b1xuICAgKiBuYXJyb3cgaXRzIHR5cGUsIHdoaWNoIGFsbG93cyB0aGUgc3RyaWN0TnVsbENoZWNrcyBmZWF0dXJlIG9mIFR5cGVTY3JpcHQgdG8gd29yayB3aXRoIGBOZ0lmYC5cbiAgICovXG4gIHN0YXRpYyBuZ1RlbXBsYXRlR3VhcmRfbmdJZjogJ2JpbmRpbmcnO1xuXG4gIC8qKlxuICAgKiBBc3NlcnRzIHRoZSBjb3JyZWN0IHR5cGUgb2YgdGhlIGNvbnRleHQgZm9yIHRoZSB0ZW1wbGF0ZSB0aGF0IGBOZ0lmYCB3aWxsIHJlbmRlci5cbiAgICpcbiAgICogVGhlIHByZXNlbmNlIG9mIHRoaXMgbWV0aG9kIGlzIGEgc2lnbmFsIHRvIHRoZSBJdnkgdGVtcGxhdGUgdHlwZS1jaGVjayBjb21waWxlciB0aGF0IHRoZVxuICAgKiBgTmdJZmAgc3RydWN0dXJhbCBkaXJlY3RpdmUgcmVuZGVycyBpdHMgdGVtcGxhdGUgd2l0aCBhIHNwZWNpZmljIGNvbnRleHQgdHlwZS5cbiAgICovXG4gIHN0YXRpYyBuZ1RlbXBsYXRlQ29udGV4dEd1YXJkPFQ+KGRpcjogTmdJZjxUPiwgY3R4OiBhbnkpOlxuICAgICAgY3R4IGlzIE5nSWZDb250ZXh0PEV4Y2x1ZGU8VCwgZmFsc2V8MHwnJ3xudWxsfHVuZGVmaW5lZD4+IHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKipcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGNsYXNzIE5nSWZDb250ZXh0PFQgPSB1bmtub3duPiB7XG4gIHB1YmxpYyAkaW1wbGljaXQ6IFQgPSBudWxsITtcbiAgcHVibGljIG5nSWY6IFQgPSBudWxsITtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0VGVtcGxhdGUocHJvcGVydHk6IHN0cmluZywgdGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT58bnVsbCk6IHZvaWQge1xuICBjb25zdCBpc1RlbXBsYXRlUmVmT3JOdWxsID0gISEoIXRlbXBsYXRlUmVmIHx8IHRlbXBsYXRlUmVmLmNyZWF0ZUVtYmVkZGVkVmlldyk7XG4gIGlmICghaXNUZW1wbGF0ZVJlZk9yTnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtwcm9wZXJ0eX0gbXVzdCBiZSBhIFRlbXBsYXRlUmVmLCBidXQgcmVjZWl2ZWQgJyR7c3RyaW5naWZ5KHRlbXBsYXRlUmVmKX0nLmApO1xuICB9XG59XG4iXX0=