carbon-components-angular
Version:
Next generation components
372 lines (370 loc) • 28.1 kB
JavaScript
import { Component, Input, Output, HostListener, EventEmitter, TemplateRef, ViewChild } from "@angular/core";
import { NG_VALUE_ACCESSOR } from "@angular/forms";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "carbon-components-angular/icon";
/**
* `cds-select` provides a styled `select` component. Get started with importing the module:
*
* ```typescript
* import { SelectModule } from 'carbon-components-angular';
* ```
*
* ```html
* <cds-select [(ngModel)]="model">
* <option value="default" disabled selected hidden>Choose an option</option>
* <option value="option1">Option 1</option>
* <option value="option2">Option 2</option>
* <option value="option3">Option 3</option>
* </cds-select>
* ```
*
* [See demo](../../?path=/story/components-select--basic)
*/
export class Select {
constructor() {
/**
* `inline` or `default` select displays
*/
this.display = "default";
/**
* Set to `true` to show a warning (contents set by warningText)
*/
this.warn = false;
/**
* Sets the unique ID. Defaults to `select-${total count of selects instantiated}`
*/
this.id = `select-${Select.selectCount++}`;
/**
* Number input field render size
*/
this.size = "md";
/**
* Set to true to disable component.
*/
this.disabled = false;
/**
* Set to true for a loading select.
*/
this.skeleton = false;
/**
* Set to `true` for an invalid select component.
*/
this.invalid = false;
/**
* @deprecated since v5 - Use `cdsLayer` directive instead
* `light` or `dark` select theme
*/
this.theme = "dark";
this.valueChange = new EventEmitter();
/**
* placeholder declarations. Replaced by the functions provided to `registerOnChange` and `registerOnTouched`
*/
this.onChangeHandler = (_) => { };
this.onTouchedHandler = () => { };
}
set value(v) {
this._value = v;
if (this.select) {
this.select.nativeElement.value = this._value;
}
}
get value() {
return this._value;
}
ngAfterViewInit() {
if (this.value !== undefined &&
this.value !== null &&
this.select &&
this.select.nativeElement.value !== this.value) {
this.select.nativeElement.value = this.value;
}
}
/**
* Receives a value from the model.
*/
writeValue(obj) {
this.value = obj;
}
/**
* Registers a listener that notifies the model when the control updates
*/
registerOnChange(fn) {
this.onChangeHandler = fn;
}
/**
* Registers a listener that notifies the model when the control is blurred
*/
registerOnTouched(fn) {
this.onTouchedHandler = fn;
}
/**
* Sets the disabled state through the model
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* Handles the change event from the `select`.
* Sends events to the change handler and emits a `selected` event.
*/
onChange(event) {
this.value = event.target.value;
this.onChangeHandler(event.target.value);
this.valueChange.emit(event.target.value);
}
/**
* Listens for the host blurring, and notifies the model
*/
focusOut() {
this.onTouchedHandler();
}
isTemplate(value) {
return value instanceof TemplateRef;
}
}
/**
* Tracks the total number of selects instantiated. Used to generate unique IDs
*/
Select.selectCount = 0;
Select.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component });
Select.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Select, selector: "cds-select, ibm-select", inputs: { display: "display", label: "label", helperText: "helperText", invalidText: "invalidText", warn: "warn", warnText: "warnText", id: "id", size: "size", disabled: "disabled", skeleton: "skeleton", invalid: "invalid", theme: "theme", ariaLabel: "ariaLabel", value: "value" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "focusout": "focusOut()" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: Select,
multi: true
}
], viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true }], ngImport: i0, template: `
<div class="cds--form-item">
<ng-template [ngIf]="skeleton">
<div *ngIf="label" class="cds--label cds--skeleton"></div>
<div class="cds--select cds--skeleton"></div>
</ng-template>
<div
*ngIf="!skeleton"
class="cds--select"
[ngClass]="{
'cds--select--inline': display === 'inline',
'cds--select--light': theme === 'light',
'cds--select--invalid': invalid,
'cds--select--warning': warn,
'cds--select--disabled': disabled
}">
<label
*ngIf="label"
[for]="id"
class="cds--label"
[ngClass]="{'cds--label--disabled': disabled}">
<ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container>
<ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template>
</label>
<div *ngIf="display === 'inline'; else noInline" class="cds--select-input--inline__wrapper">
<ng-container *ngTemplateOutlet="noInline"></ng-container>
</div>
<div
*ngIf="helperText"
class="cds--form__helper-text"
[ngClass]="{
'cds--form__helper-text--disabled': disabled
}">
<ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container>
<ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
</div>
</div>
</div>
<!-- select element: dynamically projected based on 'display' variant -->
<ng-template #noInline>
<div class="cds--select-input__wrapper" [attr.data-invalid]="(invalid ? true : null)">
<select
#select
[attr.id]="id"
[attr.aria-label]="ariaLabel"
[disabled]="disabled"
(change)="onChange($event)"
[attr.aria-invalid]="invalid ? 'true' : null"
class="cds--select-input"
[ngClass]="{
'cds--select-input--sm': size === 'sm',
'cds--select-input--md': size === 'md',
'cds--select-input--lg': size === 'lg'
}">
<ng-content></ng-content>
</select>
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
style="will-change: transform;"
xmlns="http://www.w3.org/2000/svg"
class="cds--select__arrow"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M8 11L3 6 3.7 5.3 8 9.6 12.3 5.3 13 6z"></path>
</svg>
<svg
*ngIf="invalid"
cdsIcon="warning--filled"
size="16"
class="cds--select__invalid-icon">
</svg>
<svg
*ngIf="!invalid && warn"
cdsIcon="warning--alt--filled"
size="16"
class="cds--select__invalid-icon cds--select__invalid-icon--warning">
</svg>
</div>
<div
*ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite">
<ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
<div *ngIf="!invalid && warn" class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container>
<ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
</div>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Select, decorators: [{
type: Component,
args: [{
selector: "cds-select, ibm-select",
template: `
<div class="cds--form-item">
<ng-template [ngIf]="skeleton">
<div *ngIf="label" class="cds--label cds--skeleton"></div>
<div class="cds--select cds--skeleton"></div>
</ng-template>
<div
*ngIf="!skeleton"
class="cds--select"
[ngClass]="{
'cds--select--inline': display === 'inline',
'cds--select--light': theme === 'light',
'cds--select--invalid': invalid,
'cds--select--warning': warn,
'cds--select--disabled': disabled
}">
<label
*ngIf="label"
[for]="id"
class="cds--label"
[ngClass]="{'cds--label--disabled': disabled}">
<ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container>
<ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template>
</label>
<div *ngIf="display === 'inline'; else noInline" class="cds--select-input--inline__wrapper">
<ng-container *ngTemplateOutlet="noInline"></ng-container>
</div>
<div
*ngIf="helperText"
class="cds--form__helper-text"
[ngClass]="{
'cds--form__helper-text--disabled': disabled
}">
<ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container>
<ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
</div>
</div>
</div>
<!-- select element: dynamically projected based on 'display' variant -->
<ng-template #noInline>
<div class="cds--select-input__wrapper" [attr.data-invalid]="(invalid ? true : null)">
<select
#select
[attr.id]="id"
[attr.aria-label]="ariaLabel"
[disabled]="disabled"
(change)="onChange($event)"
[attr.aria-invalid]="invalid ? 'true' : null"
class="cds--select-input"
[ngClass]="{
'cds--select-input--sm': size === 'sm',
'cds--select-input--md': size === 'md',
'cds--select-input--lg': size === 'lg'
}">
<ng-content></ng-content>
</select>
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
style="will-change: transform;"
xmlns="http://www.w3.org/2000/svg"
class="cds--select__arrow"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M8 11L3 6 3.7 5.3 8 9.6 12.3 5.3 13 6z"></path>
</svg>
<svg
*ngIf="invalid"
cdsIcon="warning--filled"
size="16"
class="cds--select__invalid-icon">
</svg>
<svg
*ngIf="!invalid && warn"
cdsIcon="warning--alt--filled"
size="16"
class="cds--select__invalid-icon cds--select__invalid-icon--warning">
</svg>
</div>
<div
*ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite">
<ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
<div *ngIf="!invalid && warn" class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container>
<ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
</div>
</ng-template>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: Select,
multi: true
}
]
}]
}], propDecorators: { display: [{
type: Input
}], label: [{
type: Input
}], helperText: [{
type: Input
}], invalidText: [{
type: Input
}], warn: [{
type: Input
}], warnText: [{
type: Input
}], id: [{
type: Input
}], size: [{
type: Input
}], disabled: [{
type: Input
}], skeleton: [{
type: Input
}], invalid: [{
type: Input
}], theme: [{
type: Input
}], ariaLabel: [{
type: Input
}], valueChange: [{
type: Output
}], select: [{
type: ViewChild,
args: ["select"]
}], value: [{
type: Input
}], focusOut: [{
type: HostListener,
args: ["focusout"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRU4sU0FBUyxFQUVULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFlBQVksRUFDWixXQUFXLEVBQ1gsU0FBUyxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUV6RTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUF3R0gsTUFBTSxPQUFPLE1BQU07SUF2R25CO1FBNkdDOztXQUVHO1FBQ00sWUFBTyxHQUF5QixTQUFTLENBQUM7UUFhbkQ7O1lBRUk7UUFDSyxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBS3RCOztXQUVHO1FBQ00sT0FBRSxHQUFHLFVBQVUsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7UUFDL0M7O1dBRUc7UUFDTSxTQUFJLEdBQXVCLElBQUksQ0FBQztRQUN6Qzs7V0FFRztRQUNNLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDMUI7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00sWUFBTyxHQUFHLEtBQUssQ0FBQztRQUV6Qjs7O1dBR0c7UUFDTSxVQUFLLEdBQXFCLE1BQU0sQ0FBQztRQUdoQyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUE4RTNDOztXQUVHO1FBQ08sb0JBQWUsR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLHFCQUFnQixHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUN2QztJQS9FQSxJQUFhLEtBQUssQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLElBQUksSUFBSSxDQUFDLE1B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QkFBaEIsS0FBSztnQkFJRyxPQUFPO3NCQUFmLEtBQUs7Z0JBTUcsS0FBSztzQkFBYixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFFYyxNQUFNO3NCQUExQixTQUFTO3VCQUFDLFFBQVE7Z0JBRU4sS0FBSztzQkFBakIsS0FBSztnQkFrRU4sUUFBUTtzQkFEUCxZQUFZO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRBZnRlclZpZXdJbml0LFxuXHRDb21wb25lbnQsXG5cdEVsZW1lbnRSZWYsXG5cdElucHV0LFxuXHRPdXRwdXQsXG5cdEhvc3RMaXN0ZW5lcixcblx0RXZlbnRFbWl0dGVyLFxuXHRUZW1wbGF0ZVJlZixcblx0Vmlld0NoaWxkXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcblxuLyoqXG4gKiBgY2RzLXNlbGVjdGAgcHJvdmlkZXMgYSBzdHlsZWQgYHNlbGVjdGAgY29tcG9uZW50LiBHZXQgc3RhcnRlZCB3aXRoIGltcG9ydGluZyB0aGUgbW9kdWxlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFNlbGVjdE1vZHVsZSB9IGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXInO1xuICogYGBgXG4gKlxuICogYGBgaHRtbFxuICogPGNkcy1zZWxlY3QgWyhuZ01vZGVsKV09XCJtb2RlbFwiPlxuICogXHQ8b3B0aW9uIHZhbHVlPVwiZGVmYXVsdFwiIGRpc2FibGVkIHNlbGVjdGVkIGhpZGRlbj5DaG9vc2UgYW4gb3B0aW9uPC9vcHRpb24+XG4gKiBcdDxvcHRpb24gdmFsdWU9XCJvcHRpb24xXCI+T3B0aW9uIDE8L29wdGlvbj5cbiAqXHQ8b3B0aW9uIHZhbHVlPVwib3B0aW9uMlwiPk9wdGlvbiAyPC9vcHRpb24+XG4gKiBcdDxvcHRpb24gdmFsdWU9XCJvcHRpb24zXCI+T3B0aW9uIDM8L29wdGlvbj5cbiAqIDwvY2RzLXNlbGVjdD5cbiAqXHRgYGBcbiAqXG4gKiBbU2VlIGRlbW9dKC4uLy4uLz9wYXRoPS9zdG9yeS9jb21wb25lbnRzLXNlbGVjdC0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtc2VsZWN0LCBpYm0tc2VsZWN0XCIsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PGRpdiBjbGFzcz1cImNkcy0tZm9ybS1pdGVtXCI+XG5cdFx0XHQ8bmctdGVtcGxhdGUgW25nSWZdPVwic2tlbGV0b25cIj5cblx0XHRcdFx0PGRpdiAqbmdJZj1cImxhYmVsXCIgY2xhc3M9XCJjZHMtLWxhYmVsIGNkcy0tc2tlbGV0b25cIj48L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImNkcy0tc2VsZWN0IGNkcy0tc2tlbGV0b25cIj48L2Rpdj5cblx0XHRcdDwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8ZGl2XG5cdFx0XHRcdCpuZ0lmPVwiIXNrZWxldG9uXCJcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLXNlbGVjdFwiXG5cdFx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtLWlubGluZSc6IGRpc3BsYXkgPT09ICdpbmxpbmUnLFxuXHRcdFx0XHRcdCdjZHMtLXNlbGVjdC0tbGlnaHQnOiB0aGVtZSA9PT0gJ2xpZ2h0Jyxcblx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtLWludmFsaWQnOiBpbnZhbGlkLFxuXHRcdFx0XHRcdCdjZHMtLXNlbGVjdC0td2FybmluZyc6IHdhcm4sXG5cdFx0XHRcdFx0J2Nkcy0tc2VsZWN0LS1kaXNhYmxlZCc6IGRpc2FibGVkXG5cdFx0XHRcdH1cIj5cblx0XHRcdFx0PGxhYmVsXG5cdFx0XHRcdFx0Km5nSWY9XCJsYWJlbFwiXG5cdFx0XHRcdFx0W2Zvcl09XCJpZFwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLWxhYmVsXCJcblx0XHRcdFx0XHRbbmdDbGFzc109XCJ7J2Nkcy0tbGFiZWwtLWRpc2FibGVkJzogZGlzYWJsZWR9XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGxhYmVsKVwiPnt7bGFiZWx9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUobGFiZWwpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwibGFiZWxcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHQ8L2xhYmVsPlxuXHRcdFx0XHQ8ZGl2ICpuZ0lmPVwiZGlzcGxheSA9PT0gJ2lubGluZSc7IGVsc2Ugbm9JbmxpbmVcIiBjbGFzcz1cImNkcy0tc2VsZWN0LWlucHV0LS1pbmxpbmVfX3dyYXBwZXJcIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibm9JbmxpbmVcIj48L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxkaXZcblx0XHRcdFx0XHQqbmdJZj1cImhlbHBlclRleHRcIlxuXHRcdFx0XHRcdGNsYXNzPVwiY2RzLS1mb3JtX19oZWxwZXItdGV4dFwiXG5cdFx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdFx0J2Nkcy0tZm9ybV9faGVscGVyLXRleHQtLWRpc2FibGVkJzogZGlzYWJsZWRcblx0XHRcdFx0XHR9XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGhlbHBlclRleHQpXCI+e3toZWxwZXJUZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKGhlbHBlclRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaGVscGVyVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9kaXY+XG5cblx0XHQ8IS0tIHNlbGVjdCBlbGVtZW50OiBkeW5hbWljYWxseSBwcm9qZWN0ZWQgYmFzZWQgb24gJ2Rpc3BsYXknIHZhcmlhbnQgLS0+XG5cdFx0PG5nLXRlbXBsYXRlICNub0lubGluZT5cblx0XHRcdDxkaXYgY2xhc3M9XCJjZHMtLXNlbGVjdC1pbnB1dF9fd3JhcHBlclwiIFthdHRyLmRhdGEtaW52YWxpZF09XCIoaW52YWxpZCA/IHRydWUgOiBudWxsKVwiPlxuXHRcdFx0XHQ8c2VsZWN0XG5cdFx0XHRcdFx0I3NlbGVjdFxuXHRcdFx0XHRcdFthdHRyLmlkXT1cImlkXCJcblx0XHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbFwiXG5cdFx0XHRcdFx0W2Rpc2FibGVkXT1cImRpc2FibGVkXCJcblx0XHRcdFx0XHQoY2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudClcIlxuXHRcdFx0XHRcdFthdHRyLmFyaWEtaW52YWxpZF09XCJpbnZhbGlkID8gJ3RydWUnIDogbnVsbFwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXNlbGVjdC1pbnB1dFwiXG5cdFx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdFx0J2Nkcy0tc2VsZWN0LWlucHV0LS1zbSc6IHNpemUgPT09ICdzbScsXG5cdFx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtaW5wdXQtLW1kJzogc2l6ZSA9PT0gJ21kJyxcblx0XHRcdFx0XHRcdCdjZHMtLXNlbGVjdC1pbnB1dC0tbGcnOiBzaXplID09PSAnbGcnXG5cdFx0XHRcdFx0fVwiPlxuXHRcdFx0XHRcdDxuZy1jb250ZW50PjwvbmctY29udGVudD5cblx0XHRcdFx0PC9zZWxlY3Q+XG5cdFx0XHRcdDxzdmdcblx0XHRcdFx0XHRmb2N1c2FibGU9XCJmYWxzZVwiXG5cdFx0XHRcdFx0cHJlc2VydmVBc3BlY3RSYXRpbz1cInhNaWRZTWlkIG1lZXRcIlxuXHRcdFx0XHRcdHN0eWxlPVwid2lsbC1jaGFuZ2U6IHRyYW5zZm9ybTtcIlxuXHRcdFx0XHRcdHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuXHRcdFx0XHRcdGNsYXNzPVwiY2RzLS1zZWxlY3RfX2Fycm93XCJcblx0XHRcdFx0XHR3aWR0aD1cIjE2XCJcblx0XHRcdFx0XHRoZWlnaHQ9XCIxNlwiXG5cdFx0XHRcdFx0dmlld0JveD1cIjAgMCAxNiAxNlwiXG5cdFx0XHRcdFx0YXJpYS1oaWRkZW49XCJ0cnVlXCI+XG5cdFx0XHRcdFx0PHBhdGggZD1cIk04IDExTDMgNiAzLjcgNS4zIDggOS42IDEyLjMgNS4zIDEzIDZ6XCI+PC9wYXRoPlxuXHRcdFx0XHQ8L3N2Zz5cblx0XHRcdFx0PHN2Z1xuXHRcdFx0XHRcdCpuZ0lmPVwiaW52YWxpZFwiXG5cdFx0XHRcdFx0Y2RzSWNvbj1cIndhcm5pbmctLWZpbGxlZFwiXG5cdFx0XHRcdFx0c2l6ZT1cIjE2XCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tc2VsZWN0X19pbnZhbGlkLWljb25cIj5cblx0XHRcdFx0PC9zdmc+XG5cdFx0XHRcdDxzdmdcblx0XHRcdFx0XHQqbmdJZj1cIiFpbnZhbGlkICYmIHdhcm5cIlxuXHRcdFx0XHRcdGNkc0ljb249XCJ3YXJuaW5nLS1hbHQtLWZpbGxlZFwiXG5cdFx0XHRcdFx0c2l6ZT1cIjE2XCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tc2VsZWN0X19pbnZhbGlkLWljb24gY2RzLS1zZWxlY3RfX2ludmFsaWQtaWNvbi0td2FybmluZ1wiPlxuXHRcdFx0XHQ8L3N2Zz5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PGRpdlxuXHRcdFx0XHQqbmdJZj1cImludmFsaWQgJiYgaW52YWxpZFRleHRcIiByb2xlPVwiYWxlcnRcIiBjbGFzcz1cImNkcy0tZm9ybS1yZXF1aXJlbWVudFwiIGFyaWEtbGl2ZT1cInBvbGl0ZVwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCI+e3tpbnZhbGlkVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW52YWxpZFRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8ZGl2ICpuZ0lmPVwiIWludmFsaWQgJiYgd2FyblwiIGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZSh3YXJuVGV4dClcIj57e3dhcm5UZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0PG5nLXRlbXBsYXRlICpuZ0lmPVwiaXNUZW1wbGF0ZSh3YXJuVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJ3YXJuVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2Rpdj5cblx0XHQ8L25nLXRlbXBsYXRlPlxuXHRgLFxuXHRwcm92aWRlcnM6IFtcblx0XHR7XG5cdFx0XHRwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcblx0XHRcdHVzZUV4aXN0aW5nOiBTZWxlY3QsXG5cdFx0XHRtdWx0aTogdHJ1ZVxuXHRcdH1cblx0XVxufSlcbmV4cG9ydCBjbGFzcyBTZWxlY3QgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgQWZ0ZXJWaWV3SW5pdCB7XG5cdC8qKlxuXHQgKiBUcmFja3MgdGhlIHRvdGFsIG51bWJlciBvZiBzZWxlY3RzIGluc3RhbnRpYXRlZC4gVXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgSURzXG5cdCAqL1xuXHRzdGF0aWMgc2VsZWN0Q291bnQgPSAwO1xuXG5cdC8qKlxuXHQgKiBgaW5saW5lYCBvciBgZGVmYXVsdGAgc2VsZWN0IGRpc3BsYXlzXG5cdCAqL1xuXHRASW5wdXQoKSBkaXNwbGF5OiBcImlubGluZVwiIHwgXCJkZWZhdWx0XCIgPSBcImRlZmF1bHRcIjtcblx0LyoqXG5cdCAqIExhYmVsIGZvciB0aGUgc2VsZWN0LiBBcHBlYXJzIGFib3ZlIHRoZSBpbnB1dC5cblx0ICovXG5cdEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXHQvKipcblx0ICogT3B0aW9uYWwgaGVscGVyIHRleHQgdGhhdCBhcHBlYXJzIHVuZGVyIHRoZSBsYWJlbC5cblx0ICovXG5cdEBJbnB1dCgpIGhlbHBlclRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBpbnZhbGlkIHRleHQuXG5cdCAqL1xuXHRASW5wdXQoKSBpbnZhbGlkVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAgKiBTZXQgdG8gYHRydWVgIHRvIHNob3cgYSB3YXJuaW5nIChjb250ZW50cyBzZXQgYnkgd2FybmluZ1RleHQpXG5cdCAgKi9cblx0QElucHV0KCkgd2FybiA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0cyB0aGUgd2FybmluZyB0ZXh0XG5cdCAqL1xuXHRASW5wdXQoKSB3YXJuVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAqIFNldHMgdGhlIHVuaXF1ZSBJRC4gRGVmYXVsdHMgdG8gYHNlbGVjdC0ke3RvdGFsIGNvdW50IG9mIHNlbGVjdHMgaW5zdGFudGlhdGVkfWBcblx0ICovXG5cdEBJbnB1dCgpIGlkID0gYHNlbGVjdC0ke1NlbGVjdC5zZWxlY3RDb3VudCsrfWA7XG5cdC8qKlxuXHQgKiBOdW1iZXIgaW5wdXQgZmllbGQgcmVuZGVyIHNpemVcblx0ICovXG5cdEBJbnB1dCgpIHNpemU6IFwic21cIiB8IFwibWRcIiB8IFwibGdcIiA9IFwibWRcIjtcblx0LyoqXG5cdCAqIFNldCB0byB0cnVlIHRvIGRpc2FibGUgY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byB0cnVlIGZvciBhIGxvYWRpbmcgc2VsZWN0LlxuXHQgKi9cblx0QElucHV0KCkgc2tlbGV0b24gPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGFuIGludmFsaWQgc2VsZWN0IGNvbXBvbmVudC5cblx0ICovXG5cdEBJbnB1dCgpIGludmFsaWQgPSBmYWxzZTtcblxuXHQvKipcblx0ICogQGRlcHJlY2F0ZWQgc2luY2UgdjUgLSBVc2UgYGNkc0xheWVyYCBkaXJlY3RpdmUgaW5zdGVhZFxuXHQgKiBgbGlnaHRgIG9yIGBkYXJrYCBzZWxlY3QgdGhlbWVcblx0ICovXG5cdEBJbnB1dCgpIHRoZW1lOiBcImxpZ2h0XCIgfCBcImRhcmtcIiA9IFwiZGFya1wiO1xuXHRASW5wdXQoKSBhcmlhTGFiZWw6IHN0cmluZztcblxuXHRAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblx0QFZpZXdDaGlsZChcInNlbGVjdFwiKSBzZWxlY3Q6IEVsZW1lbnRSZWY7XG5cblx0QElucHV0KCkgc2V0IHZhbHVlKHYpIHtcblx0XHR0aGlzLl92YWx1ZSA9IHY7XG5cdFx0aWYgKHRoaXMuc2VsZWN0KSB7XG5cdFx0XHR0aGlzLnNlbGVjdC5uYXRpdmVFbGVtZW50LnZhbHVlID0gdGhpcy5fdmFsdWU7XG5cdFx0fVxuXHR9XG5cblx0Z2V0IHZhbHVlKCkge1xuXHRcdHJldHVybiB0aGlzLl92YWx1ZTtcblx0fVxuXG5cdHByb3RlY3RlZCBfdmFsdWU7XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdGlmIChcblx0XHRcdHRoaXMudmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuXHRcdFx0dGhpcy52YWx1ZSAhPT0gbnVsbCAmJlxuXHRcdFx0dGhpcy5zZWxlY3QgJiZcblx0XHRcdHRoaXMuc2VsZWN0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgIT09IHRoaXMudmFsdWVcblx0XHQpIHtcblx0XHRcdHRoaXMuc2VsZWN0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSB0aGlzLnZhbHVlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZWNlaXZlcyBhIHZhbHVlIGZyb20gdGhlIG1vZGVsLlxuXHQgKi9cblx0d3JpdGVWYWx1ZShvYmo6IGFueSkge1xuXHRcdHRoaXMudmFsdWUgPSBvYmo7XG5cdH1cblxuXHQvKipcblx0ICogUmVnaXN0ZXJzIGEgbGlzdGVuZXIgdGhhdCBub3RpZmllcyB0aGUgbW9kZWwgd2hlbiB0aGUgY29udHJvbCB1cGRhdGVzXG5cdCAqL1xuXHRyZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpIHtcblx0XHR0aGlzLm9uQ2hhbmdlSGFuZGxlciA9IGZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlZ2lzdGVycyBhIGxpc3RlbmVyIHRoYXQgbm90aWZpZXMgdGhlIG1vZGVsIHdoZW4gdGhlIGNvbnRyb2wgaXMgYmx1cnJlZFxuXHQgKi9cblx0cmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuXHRcdHRoaXMub25Ub3VjaGVkSGFuZGxlciA9IGZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGRpc2FibGVkIHN0YXRlIHRocm91Z2ggdGhlIG1vZGVsXG5cdCAqL1xuXHRzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcblx0XHR0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGVzIHRoZSBjaGFuZ2UgZXZlbnQgZnJvbSB0aGUgYHNlbGVjdGAuXG5cdCAqIFNlbmRzIGV2ZW50cyB0byB0aGUgY2hhbmdlIGhhbmRsZXIgYW5kIGVtaXRzIGEgYHNlbGVjdGVkYCBldmVudC5cblx0ICovXG5cdG9uQ2hhbmdlKGV2ZW50KSB7XG5cdFx0dGhpcy52YWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZTtcblx0XHR0aGlzLm9uQ2hhbmdlSGFuZGxlcihldmVudC50YXJnZXQudmFsdWUpO1xuXHRcdHRoaXMudmFsdWVDaGFuZ2UuZW1pdChldmVudC50YXJnZXQudmFsdWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIExpc3RlbnMgZm9yIHRoZSBob3N0IGJsdXJyaW5nLCBhbmQgbm90aWZpZXMgdGhlIG1vZGVsXG5cdCAqL1xuXHRASG9zdExpc3RlbmVyKFwiZm9jdXNvdXRcIilcblx0Zm9jdXNPdXQoKSB7XG5cdFx0dGhpcy5vblRvdWNoZWRIYW5kbGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgaXNUZW1wbGF0ZSh2YWx1ZSkge1xuXHRcdHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmO1xuXHR9XG5cblx0LyoqXG5cdCAqIHBsYWNlaG9sZGVyIGRlY2xhcmF0aW9ucy4gUmVwbGFjZWQgYnkgdGhlIGZ1bmN0aW9ucyBwcm92aWRlZCB0byBgcmVnaXN0ZXJPbkNoYW5nZWAgYW5kIGByZWdpc3Rlck9uVG91Y2hlZGBcblx0ICovXG5cdHByb3RlY3RlZCBvbkNoYW5nZUhhbmRsZXIgPSAoXzogYW55KSA9PiB7IH07XG5cdHByb3RlY3RlZCBvblRvdWNoZWRIYW5kbGVyID0gKCkgPT4geyB9O1xufVxuIl19