@kushki/ng-suka
Version:
<p align="center"> <h1 align="center">Suka Components Angular</h1> <p align="center"> An Angular implementation of the Suka Design System </p> </p>
380 lines (377 loc) • 28.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, HostBinding, EventEmitter, Output, TemplateRef, ViewChild, ElementRef, ViewContainerRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Overlay } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
export class ColorInput {
/**
* Creates an instance of `ColorInput`.
* @param {?} _overlay
* @param {?} _viewContainerRef
*/
constructor(_overlay, _viewContainerRef) {
this._overlay = _overlay;
this._viewContainerRef = _viewContainerRef;
this.containerClass = true;
/**
* Set to `true` for a disabled color input.
*/
this.disabled = false;
/**
* Set to `true` for a loading color input component.
*/
this.skeleton = false;
/**
* Set to `true` for an invalid color input component.
*/
this.invalid = false;
/**
* Set to `true` for a valid color input component.
*/
this.valid = false;
/**
* The unique id for the color input component.
*/
this.id = `color-input-${ColorInput.colorInputCount}`;
/**
* Sets the value attribute on the `input` element.
*/
this.value = '';
/**
* Sets the placeholder on the `input` element.
*/
this.placeholder = '';
/**
* Emits event notifying other classes when a change in state occurs in the input.
*/
// tslint:disable-next-line: no-output-native
this.change = new EventEmitter();
/**
* Called when number input is blurred. Needed to properly implement `ControlValueAccessor`.
*/
this.onTouched = (/**
* @return {?}
*/
() => { });
/**
* Method set in `registerOnChange` to propagate changes back to the form.
*/
this.propagateChange = (/**
* @param {?} _
* @return {?}
*/
(_) => { });
ColorInput.colorInputCount++;
}
/**
* This is the initial value set to the component
* @param {?} value The input value.
* @return {?}
*/
writeValue(value) {
this.value = value;
}
/**
* Sets a method in order to propagate changes back to the form.
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.propagateChange = fn;
}
/**
* Registers a callback to be triggered when the control has been touched.
* @param {?} fn Callback to be triggered when the number input is touched.
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* Sets the disabled state through the model
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* Creates a class of `NumberChange` to emit the change in the `Number`.
* @return {?}
*/
emitChangeEvent() {
this.change.emit(this.value);
this.propagateChange(this.value);
}
/**
* @param {?} value
* @return {?}
*/
onColorChange(value) {
this.value = value;
this.emitChangeEvent();
}
/**
* @param {?} event
* @return {?}
*/
onColorInputChange(event) {
this.value = event.target.value;
this.emitChangeEvent();
}
/**
* Opens the color picker dialog
* @return {?}
*/
openColorDialog() {
if (!this._overlayRef) {
/** @type {?} */
const positionStrategy = this._overlay
.position()
.flexibleConnectedTo(this.origin)
.withPositions([{
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top',
offsetY: 8,
}]);
this._overlayRef = this._overlay.create({
hasBackdrop: true,
backdropClass: 'cdk-overlay-transparent-backdrop',
positionStrategy,
});
this._overlayRef.backdropClick().subscribe((/**
* @return {?}
*/
() => this._overlayRef.detach()));
this._portal = new TemplatePortal(this.dialog, this._viewContainerRef);
}
this._overlayRef.attach(this._portal);
}
/**
* Closes the color picker dialog
* @return {?}
*/
closeColorDialog() {
this._overlayRef.detach();
}
/**
* Checks if it is a template
* @param {?} value
* @return {?}
*/
isTemplate(value) {
return value instanceof TemplateRef;
}
}
/**
* Variable used for creating unique ids for color input components.
*/
ColorInput.colorInputCount = 0;
ColorInput.decorators = [
{ type: Component, args: [{
selector: 'suka-color-input',
template: `
<label *ngIf="skeleton && label" class="label skeleton"></label>
<label *ngIf="!skeleton && label" [for]="id" class="label">
<ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container>
<ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template>
</label>
<div *ngIf="!skeleton && helperText" class="form__helper-text">
<ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container>
<ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
</div>
<div
data-color-input
[attr.data-invalid]="(invalid ? true : null)"
[attr.data-valid]="(valid ? true : null)"
class="color-input"
[ngClass]="{
'color-input--nolabel': !label,
'color-input--helpertext': helperText,
'skeleton' : skeleton,
'color-input--disabled': disabled
}">
<div class="color-input__input-wrapper">
<div
class="color-input__color-preview"
*ngIf="value"
[ngStyle]="{'background-color': value || 'white'}"
(click)="openColorDialog()"
></div>
<svg
class="color-input__color-preview-icon"
*ngIf="!value"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
(click)="openColorDialog()"
>
<path d="M8 0C3.55556 0 0 3.55556 0 8C0 12.4444 3.55556 16 8 16C8.71111 16 9.33333 15.3778 9.33333 14.6667C9.33333 14.3111 9.24444 14.0444 8.97778 13.7778C8.8 13.5111 8.62222 13.2444 8.62222 12.8889C8.62222 12.1778 9.24448 11.5556 9.95556 11.5556H11.5556C14.0444 11.5556 16 9.6 16 7.11111C16 3.2 12.4444 0 8 0ZM3.11111 8C2.4 8 1.77778 7.37778 1.77778 6.66667C1.77778 5.95556 2.4 5.33333 3.11111 5.33333C3.82222 5.33333 4.44444 5.95556 4.44444 6.66667C4.44444 7.37778 3.82222 8 3.11111 8ZM5.77778 4.44444C5.06667 4.44444 4.44444 3.82222 4.44444 3.11111C4.44444 2.4 5.06667 1.77778 5.77778 1.77778C6.48889 1.77778 7.11111 2.4 7.11111 3.11111C7.11111 3.82222 6.48889 4.44444 5.77778 4.44444ZM10.2222 4.44444C9.51111 4.44444 8.88889 3.82222 8.88889 3.11111C8.88889 2.4 9.51111 1.77778 10.2222 1.77778C10.9333 1.77778 11.5556 2.4 11.5556 3.11111C11.5556 3.82222 10.9333 4.44444 10.2222 4.44444ZM12.8889 8C12.1778 8 11.5556 7.37778 11.5556 6.66667C11.5556 5.95556 12.1778 5.33333 12.8889 5.33333C13.6 5.33333 14.2222 5.95556 14.2222 6.66667C14.2222 7.37778 13.6 8 12.8889 8Z" fill="#677784"/>
</svg>
<input
#origin
type="text"
[id]="id"
[placeholder]="placeholder"
[value]="value"
[disabled]="disabled"
[required]="required"
(focus)="openColorDialog()"
(change)="onColorInputChange($event)"/>
<suka-icon *ngIf="!skeleton && invalid" icon="alert-circle" class="color-input__invalid"></suka-icon>
<suka-icon *ngIf="!skeleton && valid" icon="check" class="color-input__valid"></suka-icon>
</div>
<div *ngIf="invalid" class="form-requirement">
<ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
</div>
<ng-template #colorPickerDialog>
<div class="color-picker-dialog">
<suka-color-picker [color]="value" (colorChange)="onColorChange($event)">
</suka-color-picker>
</div>
</ng-template>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: ColorInput,
multi: true
}
]
}] }
];
/** @nocollapse */
ColorInput.ctorParameters = () => [
{ type: Overlay },
{ type: ViewContainerRef }
];
ColorInput.propDecorators = {
containerClass: [{ type: HostBinding, args: ['class.form-item',] }],
disabled: [{ type: Input }],
skeleton: [{ type: Input }],
invalid: [{ type: Input }],
valid: [{ type: Input }],
id: [{ type: Input }],
required: [{ type: Input }],
value: [{ type: Input }],
placeholder: [{ type: Input }],
label: [{ type: Input }],
helperText: [{ type: Input }],
invalidText: [{ type: Input }],
change: [{ type: Output }],
origin: [{ type: ViewChild, args: ['origin', { static: false },] }],
dialog: [{ type: ViewChild, args: ['colorPickerDialog', { static: false },] }]
};
if (false) {
/**
* Variable used for creating unique ids for color input components.
* @type {?}
*/
ColorInput.colorInputCount;
/**
* @type {?}
* @private
*/
ColorInput.prototype._overlayRef;
/**
* @type {?}
* @private
*/
ColorInput.prototype._portal;
/** @type {?} */
ColorInput.prototype.containerClass;
/**
* Set to `true` for a disabled color input.
* @type {?}
*/
ColorInput.prototype.disabled;
/**
* Set to `true` for a loading color input component.
* @type {?}
*/
ColorInput.prototype.skeleton;
/**
* Set to `true` for an invalid color input component.
* @type {?}
*/
ColorInput.prototype.invalid;
/**
* Set to `true` for a valid color input component.
* @type {?}
*/
ColorInput.prototype.valid;
/**
* The unique id for the color input component.
* @type {?}
*/
ColorInput.prototype.id;
/**
* Reflects the required attribute of the `input` element.
* @type {?}
*/
ColorInput.prototype.required;
/**
* Sets the value attribute on the `input` element.
* @type {?}
*/
ColorInput.prototype.value;
/**
* Sets the placeholder on the `input` element.
* @type {?}
*/
ColorInput.prototype.placeholder;
/**
* Sets the text inside the `label` tag.
* @type {?}
*/
ColorInput.prototype.label;
/**
* Sets the optional helper text.
* @type {?}
*/
ColorInput.prototype.helperText;
/**
* Sets the invalid text.
* @type {?}
*/
ColorInput.prototype.invalidText;
/**
* Emits event notifying other classes when a change in state occurs in the input.
* @type {?}
*/
ColorInput.prototype.change;
/** @type {?} */
ColorInput.prototype.origin;
/** @type {?} */
ColorInput.prototype.dialog;
/**
* Called when number input is blurred. Needed to properly implement `ControlValueAccessor`.
* @type {?}
*/
ColorInput.prototype.onTouched;
/**
* Method set in `registerOnChange` to propagate changes back to the form.
* @type {?}
*/
ColorInput.prototype.propagateChange;
/**
* @type {?}
* @private
*/
ColorInput.prototype._overlay;
/**
* @type {?}
* @private
*/
ColorInput.prototype._viewContainerRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItcGlja2VyLWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BrdXNoa2kvbmctc3VrYS8iLCJzb3VyY2VzIjpbImxpYi9jb2xvci1waWNrZXIvY29sb3ItcGlja2VyLWlucHV0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsV0FBVyxFQUNYLFlBQVksRUFDWixNQUFNLEVBQ04sV0FBVyxFQUNYLFNBQVMsRUFDVCxVQUFVLEVBQ1YsZ0JBQWdCLEVBQ2pCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBd0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBZ0ZyRCxNQUFNLE9BQU8sVUFBVTs7Ozs7O0lBaUVyQixZQUNVLFFBQWlCLEVBQ2pCLGlCQUFtQztRQURuQyxhQUFRLEdBQVIsUUFBUSxDQUFTO1FBQ2pCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBa0I7UUEzRGIsbUJBQWMsR0FBRyxJQUFJLENBQUM7Ozs7UUFJN0MsYUFBUSxHQUFHLEtBQUssQ0FBQzs7OztRQUlqQixhQUFRLEdBQUcsS0FBSyxDQUFDOzs7O1FBSWpCLFlBQU8sR0FBRyxLQUFLLENBQUM7Ozs7UUFJaEIsVUFBSyxHQUFHLEtBQUssQ0FBQzs7OztRQUlkLE9BQUUsR0FBRyxlQUFlLFVBQVUsQ0FBQyxlQUFlLEVBQUUsQ0FBQzs7OztRQVFqRCxVQUFLLEdBQUcsRUFBRSxDQUFDOzs7O1FBSVgsZ0JBQVcsR0FBRyxFQUFFLENBQUM7Ozs7O1FBaUJoQixXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQzs7OztRQWdEdEMsY0FBUzs7O1FBQWMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFDOzs7O1FBS2pDLG9C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dkIsS0FBSyxFQUFFLElBQUk7cUJBQ1o7aUJBQ0Y7YUFDRjs7OztZQWhGb0IsT0FBTztZQUgxQixnQkFBZ0I7Ozs2QkE0RmYsV0FBVyxTQUFDLGlCQUFpQjt1QkFJN0IsS0FBSzt1QkFJTCxLQUFLO3NCQUlMLEtBQUs7b0JBSUwsS0FBSztpQkFJTCxLQUFLO3VCQUlMLEtBQUs7b0JBSUwsS0FBSzswQkFJTCxLQUFLO29CQUlMLEtBQUs7eUJBSUwsS0FBSzswQkFJTCxLQUFLO3FCQUtMLE1BQU07cUJBRU4sU0FBUyxTQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7cUJBQ3JDLFNBQVMsU0FBQyxtQkFBbUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Ozs7Ozs7SUF4RGpELDJCQUEyQjs7Ozs7SUFDM0IsaUNBQWdDOzs7OztJQUNoQyw2QkFBcUM7O0lBRXJDLG9DQUFzRDs7Ozs7SUFJdEQsOEJBQTBCOzs7OztJQUkxQiw4QkFBMEI7Ozs7O0lBSTFCLDZCQUF5Qjs7Ozs7SUFJekIsMkJBQXVCOzs7OztJQUl2Qix3QkFBMEQ7Ozs7O0lBSTFELDhCQUEyQjs7Ozs7SUFJM0IsMkJBQW9COzs7OztJQUlwQixpQ0FBMEI7Ozs7O0lBSTFCLDJCQUEwQzs7Ozs7SUFJMUMsZ0NBQStDOzs7OztJQUkvQyxpQ0FBZ0Q7Ozs7O0lBS2hELDRCQUFzQzs7SUFFdEMsNEJBQTJEOztJQUMzRCw0QkFBNEU7Ozs7O0lBNkM1RSwrQkFBaUM7Ozs7O0lBS2pDLHFDQUFrQzs7Ozs7SUE1Q2hDLDhCQUF5Qjs7Ozs7SUFDekIsdUNBQTJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgSG9zdEJpbmRpbmcsXG4gIEV2ZW50RW1pdHRlcixcbiAgT3V0cHV0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBWaWV3Q29udGFpbmVyUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTkdfVkFMVUVfQUNDRVNTT1IsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgT3ZlcmxheVJlZiwgT3ZlcmxheSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IFRlbXBsYXRlUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3N1a2EtY29sb3ItaW5wdXQnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxsYWJlbCAqbmdJZj1cInNrZWxldG9uICYmIGxhYmVsXCIgY2xhc3M9XCJsYWJlbCBza2VsZXRvblwiPjwvbGFiZWw+XG4gICAgPGxhYmVsICpuZ0lmPVwiIXNrZWxldG9uICYmIGxhYmVsXCIgW2Zvcl09XCJpZFwiIGNsYXNzPVwibGFiZWxcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZShsYWJlbClcIj57e2xhYmVsfX08L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUobGFiZWwpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwibGFiZWxcIj48L25nLXRlbXBsYXRlPlxuICAgIDwvbGFiZWw+XG4gICAgPGRpdiAqbmdJZj1cIiFza2VsZXRvbiAmJiBoZWxwZXJUZXh0XCIgY2xhc3M9XCJmb3JtX19oZWxwZXItdGV4dFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGhlbHBlclRleHQpXCI+e3toZWxwZXJUZXh0fX08L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaGVscGVyVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWxwZXJUZXh0XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgICBkYXRhLWNvbG9yLWlucHV0XG4gICAgICBbYXR0ci5kYXRhLWludmFsaWRdPVwiKGludmFsaWQgPyB0cnVlIDogbnVsbClcIlxuICAgICAgW2F0dHIuZGF0YS12YWxpZF09XCIodmFsaWQgPyB0cnVlIDogbnVsbClcIlxuICAgICAgY2xhc3M9XCJjb2xvci1pbnB1dFwiXG4gICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICdjb2xvci1pbnB1dC0tbm9sYWJlbCc6ICFsYWJlbCxcbiAgICAgICAgJ2NvbG9yLWlucHV0LS1oZWxwZXJ0ZXh0JzogaGVscGVyVGV4dCxcbiAgICAgICAgJ3NrZWxldG9uJyA6IHNrZWxldG9uLFxuICAgICAgICAnY29sb3ItaW5wdXQtLWRpc2FibGVkJzogZGlzYWJsZWRcbiAgICAgIH1cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2xvci1pbnB1dF9faW5wdXQtd3JhcHBlclwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJjb2xvci1pbnB1dF9fY29sb3ItcHJldmlld1wiXG4gICAgICAgICAgKm5nSWY9XCJ2YWx1ZVwiXG4gICAgICAgICAgW25nU3R5bGVdPVwieydiYWNrZ3JvdW5kLWNvbG9yJzogdmFsdWUgfHwgJ3doaXRlJ31cIlxuICAgICAgICAgIChjbGljayk9XCJvcGVuQ29sb3JEaWFsb2coKVwiXG4gICAgICAgID48L2Rpdj5cbiAgICAgICAgPHN2Z1xuICAgICAgICAgIGNsYXNzPVwiY29sb3ItaW5wdXRfX2NvbG9yLXByZXZpZXctaWNvblwiXG4gICAgICAgICAgKm5nSWY9XCIhdmFsdWVcIlxuICAgICAgICAgIHdpZHRoPVwiMTZcIlxuICAgICAgICAgIGhlaWdodD1cIjE2XCJcbiAgICAgICAgICB2aWV3Qm94PVwiMCAwIDE2IDE2XCJcbiAgICAgICAgICBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgICAgKGNsaWNrKT1cIm9wZW5Db2xvckRpYWxvZygpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxwYXRoIGQ9XCJNOCAwQzMuNTU1NTYgMCAwIDMuNTU1NTYgMCA4QzAgMTIuNDQ0NCAzLjU1NTU2IDE2IDggMTZDOC43MTExMSAxNiA5LjMzMzMzIDE1LjM3NzggOS4zMzMzMyAxNC42NjY3QzkuMzMzMzMgMTQuMzExMSA5LjI0NDQ0IDE0LjA0NDQgOC45Nzc3OCAxMy43Nzc4QzguOCAxMy41MTExIDguNjIyMjIgMTMuMjQ0NCA4LjYyMjIyIDEyLjg4ODlDOC42MjIyMiAxMi4xNzc4IDkuMjQ0NDggMTEuNTU1NiA5Ljk1NTU2IDExLjU1NTZIMTEuNTU1NkMxNC4wNDQ0IDExLjU1NTYgMTYgOS42IDE2IDcuMTExMTFDMTYgMy4yIDEyLjQ0NDQgMCA4IDBaTTMuMTExMTEgOEMyLjQgOCAxLjc3Nzc4IDcuMzc3NzggMS43Nzc3OCA2LjY2NjY3QzEuNzc3NzggNS45NTU1NiAyLjQgNS4zMzMzMyAzLjExMTExIDUuMzMzMzNDMy44MjIyMiA1LjMzMzMzIDQuNDQ0NDQgNS45NTU1NiA0LjQ0NDQ0IDYuNjY2NjdDNC40NDQ0NCA3LjM3Nzc4IDMuODIyMjIgOCAzLjExMTExIDhaTTUuNzc3NzggNC40NDQ0NEM1LjA2NjY3IDQuNDQ0NDQgNC40NDQ0NCAzLjgyMjIyIDQuNDQ0NDQgMy4xMTExMUM0LjQ0NDQ0IDIuNCA1LjA2NjY3IDEuNzc3NzggNS43Nzc3OCAxLjc3Nzc4QzYuNDg4ODkgMS43Nzc3OCA3LjExMTExIDIuNCA3LjExMTExIDMuMTExMTFDNy4xMTExMSAzLjgyMjIyIDYuNDg4ODkgNC40NDQ0NCA1Ljc3Nzc4IDQuNDQ0NDRaTTEwLjIyMjIgNC40NDQ0NEM5LjUxMTExIDQuNDQ0NDQgOC44ODg4OSAzLjgyMjIyIDguODg4ODkgMy4xMTExMUM4Ljg4ODg5IDIuNCA5LjUxMTExIDEuNzc3NzggMTAuMjIyMiAxLjc3Nzc4QzEwLjkzMzMgMS43Nzc3OCAxMS41NTU2IDIuNCAxMS41NTU2IDMuMTExMTFDMTEuNTU1NiAzLjgyMjIyIDEwLjkzMzMgNC40NDQ0NCAxMC4yMjIyIDQuNDQ0NDRaTTEyLjg4ODkgOEMxMi4xNzc4IDggMTEuNTU1NiA3LjM3Nzc4IDExLjU1NTYgNi42NjY2N0MxMS41NTU2IDUuOTU1NTYgMTIuMTc3OCA1LjMzMzMzIDEyLjg4ODkgNS4zMzMzM0MxMy42IDUuMzMzMzMgMTQuMjIyMiA1Ljk1NTU2IDE0LjIyMjIgNi42NjY2N0MxNC4yMjIyIDcuMzc3NzggMTMuNiA4IDEyLjg4ODkgOFpcIiBmaWxsPVwiIzY3Nzc4NFwiLz5cbiAgICAgICAgPC9zdmc+XG5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgI29yaWdpblxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICBbaWRdPVwiaWRcIlxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAgICAgW3ZhbHVlXT1cInZhbHVlXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgIFtyZXF1aXJlZF09XCJyZXF1aXJlZFwiXG4gICAgICAgICAgKGZvY3VzKT1cIm9wZW5Db2xvckRpYWxvZygpXCJcbiAgICAgICAgICAoY2hhbmdlKT1cIm9uQ29sb3JJbnB1dENoYW5nZSgkZXZlbnQpXCIvPlxuXG4gICAgICAgIDxzdWthLWljb24gKm5nSWY9XCIhc2tlbGV0b24gJiYgaW52YWxpZFwiIGljb249XCJhbGVydC1jaXJjbGVcIiBjbGFzcz1cImNvbG9yLWlucHV0X19pbnZhbGlkXCI+PC9zdWthLWljb24+XG4gICAgICAgIDxzdWthLWljb24gKm5nSWY9XCIhc2tlbGV0b24gJiYgdmFsaWRcIiBpY29uPVwiY2hlY2tcIiBjbGFzcz1cImNvbG9yLWlucHV0X192YWxpZFwiPjwvc3VrYS1pY29uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiaW52YWxpZFwiIGNsYXNzPVwiZm9ybS1yZXF1aXJlbWVudFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCI+e3tpbnZhbGlkVGV4dH19PC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW52YWxpZFRleHRcIj48L25nLXRlbXBsYXRlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctdGVtcGxhdGUgI2NvbG9yUGlja2VyRGlhbG9nPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbG9yLXBpY2tlci1kaWFsb2dcIj5cbiAgICAgICAgPHN1a2EtY29sb3ItcGlja2VyIFtjb2xvcl09XCJ2YWx1ZVwiIChjb2xvckNoYW5nZSk9XCJvbkNvbG9yQ2hhbmdlKCRldmVudClcIj5cbiAgICAgICAgPC9zdWthLWNvbG9yLXBpY2tlcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIGAsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IENvbG9ySW5wdXQsXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBDb2xvcklucHV0IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICAvKipcbiAgICogVmFyaWFibGUgdXNlZCBmb3IgY3JlYXRpbmcgdW5pcXVlIGlkcyBmb3IgY29sb3IgaW5wdXQgY29tcG9uZW50cy5cbiAgICovXG4gIHN0YXRpYyBjb2xvcklucHV0Q291bnQgPSAwO1xuICBwcml2YXRlIF9vdmVybGF5UmVmOiBPdmVybGF5UmVmO1xuICBwcml2YXRlIF9wb3J0YWw6IFRlbXBsYXRlUG9ydGFsPGFueT47XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5mb3JtLWl0ZW0nKSBjb250YWluZXJDbGFzcyA9IHRydWU7XG4gIC8qKlxuICAgKiBTZXQgdG8gYHRydWVgIGZvciBhIGRpc2FibGVkIGNvbG9yIGlucHV0LlxuICAgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgLyoqXG4gICAqIFNldCB0byBgdHJ1ZWAgZm9yIGEgbG9hZGluZyBjb2xvciBpbnB1dCBjb21wb25lbnQuXG4gICAqL1xuICBASW5wdXQoKSBza2VsZXRvbiA9IGZhbHNlO1xuICAvKipcbiAgICogU2V0IHRvIGB0cnVlYCBmb3IgYW4gaW52YWxpZCBjb2xvciBpbnB1dCBjb21wb25lbnQuXG4gICAqL1xuICBASW5wdXQoKSBpbnZhbGlkID0gZmFsc2U7XG4gIC8qKlxuICAgKiBTZXQgdG8gYHRydWVgIGZvciBhIHZhbGlkIGNvbG9yIGlucHV0IGNvbXBvbmVudC5cbiAgICovXG4gIEBJbnB1dCgpIHZhbGlkID0gZmFsc2U7XG4gIC8qKlxuICAgKiBUaGUgdW5pcXVlIGlkIGZvciB0aGUgY29sb3IgaW5wdXQgY29tcG9uZW50LlxuICAgKi9cbiAgQElucHV0KCkgaWQgPSBgY29sb3ItaW5wdXQtJHtDb2xvcklucHV0LmNvbG9ySW5wdXRDb3VudH1gO1xuICAvKipcbiAgICogUmVmbGVjdHMgdGhlIHJlcXVpcmVkIGF0dHJpYnV0ZSBvZiB0aGUgYGlucHV0YCBlbGVtZW50LlxuICAgKi9cbiAgQElucHV0KCkgcmVxdWlyZWQ6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBTZXRzIHRoZSB2YWx1ZSBhdHRyaWJ1dGUgb24gdGhlIGBpbnB1dGAgZWxlbWVudC5cbiAgICovXG4gIEBJbnB1dCgpIHZhbHVlID0gJyc7XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBwbGFjZWhvbGRlciBvbiB0aGUgYGlucHV0YCBlbGVtZW50LlxuICAgKi9cbiAgQElucHV0KCkgcGxhY2Vob2xkZXIgPSAnJztcbiAgLyoqXG4gICAqIFNldHMgdGhlIHRleHQgaW5zaWRlIHRoZSBgbGFiZWxgIHRhZy5cbiAgICovXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuICAvKipcbiAgICogU2V0cyB0aGUgb3B0aW9uYWwgaGVscGVyIHRleHQuXG4gICAqL1xuICBASW5wdXQoKSBoZWxwZXJUZXh0OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuICAvKipcbiAgICogU2V0cyB0aGUgaW52YWxpZCB0ZXh0LlxuICAgKi9cbiAgQElucHV0KCkgaW52YWxpZFRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG4gIC8qKlxuICAgKiBFbWl0cyBldmVudCBub3RpZnlpbmcgb3RoZXIgY2xhc3NlcyB3aGVuIGEgY2hhbmdlIGluIHN0YXRlIG9jY3VycyBpbiB0aGUgaW5wdXQuXG4gICAqL1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLW91dHB1dC1uYXRpdmVcbiAgQE91dHB1dCgpIGNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAVmlld0NoaWxkKCdvcmlnaW4nLCB7IHN0YXRpYzogZmFsc2UgfSkgb3JpZ2luOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdjb2xvclBpY2tlckRpYWxvZycsIHsgc3RhdGljOiBmYWxzZSB9KSBkaWFsb2c6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYENvbG9ySW5wdXRgLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfb3ZlcmxheTogT3ZlcmxheSxcbiAgICBwcml2YXRlIF92aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmXG4gICkge1xuICAgIENvbG9ySW5wdXQuY29sb3JJbnB1dENvdW50Kys7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyB0aGUgaW5pdGlhbCB2YWx1ZSBzZXQgdG8gdGhlIGNvbXBvbmVudFxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIGlucHV0IHZhbHVlLlxuICAgKi9cbiAgcHVibGljIHdyaXRlVmFsdWUodmFsdWU6IGFueSkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGEgbWV0aG9kIGluIG9yZGVyIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzIGJhY2sgdG8gdGhlIGZvcm0uXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KSB7XG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBjYWxsYmFjayB0byBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgY29udHJvbCBoYXMgYmVlbiB0b3VjaGVkLlxuICAgKiBAcGFyYW0gZm4gQ2FsbGJhY2sgdG8gYmUgdHJpZ2dlcmVkIHdoZW4gdGhlIG51bWJlciBpbnB1dCBpcyB0b3VjaGVkLlxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGRpc2FibGVkIHN0YXRlIHRocm91Z2ggdGhlIG1vZGVsXG4gICAqL1xuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiBudW1iZXIgaW5wdXQgaXMgYmx1cnJlZC4gTmVlZGVkIHRvIHByb3Blcmx5IGltcGxlbWVudCBgQ29udHJvbFZhbHVlQWNjZXNzb3JgLlxuICAgKi9cbiAgb25Ub3VjaGVkOiAoKSA9PiBhbnkgPSAoKSA9PiB7IH07XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBzZXQgaW4gYHJlZ2lzdGVyT25DaGFuZ2VgIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzIGJhY2sgdG8gdGhlIGZvcm0uXG4gICAqL1xuICBwcm9wYWdhdGVDaGFuZ2UgPSAoXzogYW55KSA9PiB7IH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjbGFzcyBvZiBgTnVtYmVyQ2hhbmdlYCB0byBlbWl0IHRoZSBjaGFuZ2UgaW4gdGhlIGBOdW1iZXJgLlxuICAgKi9cbiAgZW1pdENoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgIHRoaXMuY2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7XG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy52YWx1ZSk7XG4gIH1cblxuICBvbkNvbG9yQ2hhbmdlKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMuZW1pdENoYW5nZUV2ZW50KCk7XG4gIH1cblxuICBvbkNvbG9ySW5wdXRDaGFuZ2UoZXZlbnQpIHtcbiAgICB0aGlzLnZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuZW1pdENoYW5nZUV2ZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgdGhlIGNvbG9yIHBpY2tlciBkaWFsb2dcbiAgICovXG4gIG9wZW5Db2xvckRpYWxvZygpIHtcbiAgICBpZiAoIXRoaXMuX292ZXJsYXlSZWYpIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3kgPSB0aGlzLl9vdmVybGF5XG4gICAgICAgIC5wb3NpdGlvbigpXG4gICAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMub3JpZ2luKVxuICAgICAgICAud2l0aFBvc2l0aW9ucyhbe1xuICAgICAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICAgICAgb3JpZ2luWTogJ2JvdHRvbScsXG4gICAgICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICAgICAgb3ZlcmxheVk6ICd0b3AnLFxuICAgICAgICAgIG9mZnNldFk6IDgsXG4gICAgICAgIH1dKTtcblxuICAgICAgdGhpcy5fb3ZlcmxheVJlZiA9IHRoaXMuX292ZXJsYXkuY3JlYXRlKHtcbiAgICAgICAgaGFzQmFja2Ryb3A6IHRydWUsXG4gICAgICAgIGJhY2tkcm9wQ2xhc3M6ICdjZGstb3ZlcmxheS10cmFuc3BhcmVudC1iYWNrZHJvcCcsXG4gICAgICAgIHBvc2l0aW9uU3RyYXRlZ3ksXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5fb3ZlcmxheVJlZi5iYWNrZHJvcENsaWNrKCkuc3Vic2NyaWJlKCgpID0+IHRoaXMuX292ZXJsYXlSZWYuZGV0YWNoKCkpO1xuICAgICAgdGhpcy5fcG9ydGFsID0gbmV3IFRlbXBsYXRlUG9ydGFsKHRoaXMuZGlhbG9nLCB0aGlzLl92aWV3Q29udGFpbmVyUmVmKTtcblxuICAgIH1cblxuICAgIHRoaXMuX292ZXJsYXlSZWYuYXR0YWNoKHRoaXMuX3BvcnRhbCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBjb2xvciBwaWNrZXIgZGlhbG9nXG4gICAqL1xuICBjbG9zZUNvbG9yRGlhbG9nKCkge1xuICAgIHRoaXMuX292ZXJsYXlSZWYuZGV0YWNoKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGl0IGlzIGEgdGVtcGxhdGVcbiAgICovXG4gIHB1YmxpYyBpc1RlbXBsYXRlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWY7XG4gIH1cbn1cbiJdfQ==