UNPKG

@taiga-ui/kit

Version:

Taiga UI Angular main components kit

153 lines 33.9 kB
import { __decorate } from "tslib"; import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, Input, signal, ViewChildren, } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { TuiControl } from '@taiga-ui/cdk/classes'; import { EMPTY_QUERY } from '@taiga-ui/cdk/constants'; import { tuiFallbackValueProvider } from '@taiga-ui/cdk/tokens'; import { tuiInjectElement } from '@taiga-ui/cdk/utils/dom'; import { tuiClamp, tuiQuantize } from '@taiga-ui/cdk/utils/math'; import { tuiPure } from '@taiga-ui/cdk/utils/miscellaneous'; import { TUI_SLIDER_OPTIONS, tuiKeyStepValueToPercentage, tuiPercentageToKeyStepValue, TuiSlider, TuiSliderComponent, } from '@taiga-ui/kit/components/slider'; import { TuiRangeChange } from './range-change.directive'; import * as i0 from "@angular/core"; import * as i1 from "./range-change.directive"; import * as i2 from "@angular/forms"; import * as i3 from "@taiga-ui/kit/components/slider"; class TuiRange extends TuiControl { constructor() { super(...arguments); // TODO: refactor to signal inputs after Angular update this.changes = signal(1); this.el = tuiInjectElement(); this.options = inject(TUI_SLIDER_OPTIONS); this.lastActiveThumb = 'end'; this.min = 0; this.max = 100; this.step = 1; this.size = this.options.size; this.segments = 1; this.keySteps = null; this.focusable = true; this.margin = 0; this.limit = Infinity; this.slidersRefs = EMPTY_QUERY; this.start = computed(() => this.toPercent(this.value()[0])); this.end = computed(() => 100 - this.toPercent(this.value()[1])); } ngOnChanges() { this.changes.update((x) => x + 1); } processValue(value, end) { if (end) { this.updateEnd(value); } else { this.updateStart(value); } this.lastActiveThumb = end ? 'end' : 'start'; } toValue(fraction) { return tuiPercentageToKeyStepValue(tuiClamp(tuiQuantize(fraction, this.fractionStep), 0, 1) * 100, this.computedKeySteps); } get fractionStep() { return this.step / (this.max - this.min); } get computedKeySteps() { return this.computePureKeySteps(this.keySteps, this.min, this.max); } get segmentWidthRatio() { return 1 / this.segments; } get rtl() { return this.el.matches('[dir="rtl"] :scope'); } changeByStep(coefficient, target) { const [startThumb, endThumb] = this.slidersRefs.map((x) => x?.nativeElement); const isEndThumb = target === this.el ? this.lastActiveThumb === 'end' : target === endThumb; const activeThumbElement = isEndThumb ? endThumb : startThumb; const previousValue = this.value()[isEndThumb ? 1 : 0]; /** @bad TODO think about a solution without twice conversion */ const previousFraction = this.toPercent(previousValue) / 100; const newFractionValue = previousFraction + coefficient * this.fractionStep; this.processValue(this.toValue(newFractionValue), isEndThumb); activeThumbElement?.focus(); } toPercent(value) { return (this.changes() && tuiKeyStepValueToPercentage(value, this.computedKeySteps)); } computePureKeySteps(keySteps, min, max) { return (keySteps || [ [0, min], [100, max], ]); } updateStart(value) { const newValue = Math.min(value, this.value()[1]); const distance = this.value()[1] - newValue; if (!this.checkDistance(distance)) { return; } this.onChange([newValue, this.value()[1]]); } updateEnd(value) { const newValue = Math.max(value, this.value()[0]); const distance = newValue - this.value()[0]; if (!this.checkDistance(distance)) { return; } this.onChange([this.value()[0], newValue]); } checkDistance(distance) { return tuiClamp(distance, this.margin, this.limit) === distance; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiRange, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TuiRange, isStandalone: true, selector: "tui-range", inputs: { min: "min", max: "max", step: "step", size: "size", segments: "segments", keySteps: "keySteps", focusable: "focusable", margin: "margin", limit: "limit" }, host: { listeners: { "focusout": "onTouched()", "keydown.arrowUp.prevent": "changeByStep(1, $event.target)", "keydown.arrowDown.prevent": "changeByStep(-1, $event.target)", "keydown.arrowRight.prevent": "changeByStep(rtl ? -1 : 1, $event.target)", "keydown.arrowLeft.prevent": "changeByStep(rtl ? 1 : -1, $event.target)" }, properties: { "attr.data-size": "size", "attr.tabindex": "-1", "attr.aria-disabled": "disabled()", "style.--t-start.%": "start()", "style.--t-end.%": "end()", "style.background": "options.trackColor", "class._disabled": "disabled()" } }, providers: [tuiFallbackValueProvider([0, 0])], viewQueries: [{ propertyName: "slidersRefs", predicate: TuiSliderComponent, descendants: true, read: ElementRef }], usesInheritance: true, usesOnChanges: true, hostDirectives: [{ directive: i1.TuiRangeChange, outputs: ["activeThumbChange", "activeThumbChange"] }], ngImport: i0, template: "<div\n class=\"t-track\"\n [style.--t-bg-size-ratio]=\"1 - segmentWidthRatio\"\n [style.--t-segment-width.%]=\"segmentWidthRatio * 100\"\n>\n <input\n automation-id=\"tui-range__left\"\n readonly\n step=\"any\"\n tuiSlider\n type=\"range\"\n class=\"t-thumb\"\n [disabled]=\"disabled()\"\n [keySteps]=\"computedKeySteps\"\n [max]=\"max\"\n [min]=\"min\"\n [ngModel]=\"value()[0]\"\n [ngModelOptions]=\"{standalone: true}\"\n [size]=\"size\"\n [tabIndex]=\"focusable ? 0 : -1\"\n />\n <input\n automation-id=\"tui-range__right\"\n readonly\n step=\"any\"\n tuiSlider\n type=\"range\"\n class=\"t-thumb\"\n [disabled]=\"disabled()\"\n [keySteps]=\"computedKeySteps\"\n [max]=\"max\"\n [min]=\"min\"\n [ngModel]=\"value()[1]\"\n [ngModelOptions]=\"{standalone: true}\"\n [size]=\"size\"\n [tabIndex]=\"focusable ? 0 : -1\"\n />\n</div>\n", styles: [":host{position:relative;display:block;block-size:.125rem;border-radius:var(--tui-radius-m);background:var(--tui-border-normal);cursor:pointer;outline:none;margin:.4375rem 0;touch-action:pan-x}:host:active{cursor:ew-resize}:host:after{content:\"\";position:absolute;top:-.4375rem;bottom:-.4375rem;inline-size:100%}:host._disabled{opacity:var(--tui-disabled-opacity);pointer-events:none}:host[data-size=s] .t-track{position:relative;margin:0 .25rem;block-size:100%}:host[data-size=s] .t-track:before{content:\"\";position:absolute;top:0;left:max(calc(var(--t-start) - 1px),1px);right:max(var(--t-end),1px);inset-inline-start:max(calc(var(--t-start) - 1px),1px);inset-inline-end:max(var(--t-end),1px);block-size:100%;background:var(--tui-background-accent-1);margin:0 -.25rem}:host[data-size=s] .t-track:after{position:absolute;top:0;left:0;bottom:0;right:0;content:\"\";left:.125rem;right:.375rem;inset-inline-start:.125rem;inset-inline-end:.375rem;background-image:repeating-linear-gradient(to var(--tui-inline-end),var(--tui-text-tertiary) 0 .25rem,transparent 0 calc(var(--t-segment-width) / var(--t-bg-size-ratio)));background-position-x:var(--tui-inline-end);background-repeat:no-repeat;background-size:calc(100% * var(--t-bg-size-ratio))}:host[data-size=m] .t-track{position:relative;margin:0 .375rem;block-size:100%}:host[data-size=m] .t-track:before{content:\"\";position:absolute;top:0;left:max(calc(var(--t-start) - 1px),1px);right:max(var(--t-end),1px);inset-inline-start:max(calc(var(--t-start) - 1px),1px);inset-inline-end:max(var(--t-end),1px);block-size:100%;background:var(--tui-background-accent-1);margin:0 -.375rem}:host[data-size=m] .t-track:after{position:absolute;top:0;left:0;bottom:0;right:0;content:\"\";left:.25rem;right:.5rem;inset-inline-start:.25rem;inset-inline-end:.5rem;background-image:repeating-linear-gradient(to var(--tui-inline-end),var(--tui-text-tertiary) 0 .25rem,transparent 0 calc(var(--t-segment-width) / var(--t-bg-size-ratio)));background-position-x:var(--tui-inline-end);background-repeat:no-repeat;background-size:calc(100% * var(--t-bg-size-ratio))}.t-thumb{pointer-events:none;position:absolute;top:.0625rem;left:0;right:0;z-index:1;transform:translateY(-50%)}.t-thumb::-webkit-slider-thumb{pointer-events:auto}.t-thumb::-moz-range-thumb{pointer-events:auto}:host._disabled .t-thumb::-webkit-slider-thumb{pointer-events:none}:host._disabled .t-thumb::-moz-range-thumb{pointer-events:none}input[type=range].t-thumb::-webkit-slider-runnable-track{background:transparent}input[type=range].t-thumb::-moz-range-track{background:transparent}input[type=range].t-thumb::-moz-range-progress{background:transparent}.t-thumb:first-of-type{--tui-slider-thumb-transform: translateX(calc(var(--tui-inline) * -50%)) translateX(calc(var(--tui-inline) * -1px))}.t-thumb:last-of-type{--tui-slider-thumb-transform: translateX(calc(var(--tui-inline) * 50%)) translateX(calc(var(--tui-inline) * 1px))}:host._disabled .t-thumb{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.TuiSliderComponent, selector: "input[type=range][tuiSlider]", inputs: ["size", "segments"] }, { kind: "directive", type: i3.TuiSliderKeyStepsBase, selector: "input[tuiSlider][keySteps]", inputs: ["step", "keySteps"] }, { kind: "directive", type: i3.TuiSliderKeySteps, selector: "input[tuiSlider][keySteps][ngModel],input[tuiSlider][keySteps][formControl],input[tuiSlider][keySteps][formControlName]", inputs: ["keySteps"] }, { kind: "directive", type: i3.TuiSliderReadonly, selector: "input[tuiSlider][readonly]", inputs: ["readonly"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } __decorate([ tuiPure ], TuiRange.prototype, "computePureKeySteps", null); export { TuiRange }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiRange, decorators: [{ type: Component, args: [{ standalone: true, selector: 'tui-range', imports: [FormsModule, TuiSlider], changeDetection: ChangeDetectionStrategy.OnPush, providers: [tuiFallbackValueProvider([0, 0])], hostDirectives: [ { directive: TuiRangeChange, outputs: ['activeThumbChange'], }, ], host: { '[attr.data-size]': 'size', '[attr.tabindex]': '-1', '[attr.aria-disabled]': 'disabled()', '[style.--t-start.%]': 'start()', '[style.--t-end.%]': 'end()', '[style.background]': 'options.trackColor', '[class._disabled]': 'disabled()', '(focusout)': 'onTouched()', '(keydown.arrowUp.prevent)': 'changeByStep(1, $event.target)', '(keydown.arrowDown.prevent)': 'changeByStep(-1, $event.target)', '(keydown.arrowRight.prevent)': 'changeByStep(rtl ? -1 : 1, $event.target)', '(keydown.arrowLeft.prevent)': 'changeByStep(rtl ? 1 : -1, $event.target)', }, template: "<div\n class=\"t-track\"\n [style.--t-bg-size-ratio]=\"1 - segmentWidthRatio\"\n [style.--t-segment-width.%]=\"segmentWidthRatio * 100\"\n>\n <input\n automation-id=\"tui-range__left\"\n readonly\n step=\"any\"\n tuiSlider\n type=\"range\"\n class=\"t-thumb\"\n [disabled]=\"disabled()\"\n [keySteps]=\"computedKeySteps\"\n [max]=\"max\"\n [min]=\"min\"\n [ngModel]=\"value()[0]\"\n [ngModelOptions]=\"{standalone: true}\"\n [size]=\"size\"\n [tabIndex]=\"focusable ? 0 : -1\"\n />\n <input\n automation-id=\"tui-range__right\"\n readonly\n step=\"any\"\n tuiSlider\n type=\"range\"\n class=\"t-thumb\"\n [disabled]=\"disabled()\"\n [keySteps]=\"computedKeySteps\"\n [max]=\"max\"\n [min]=\"min\"\n [ngModel]=\"value()[1]\"\n [ngModelOptions]=\"{standalone: true}\"\n [size]=\"size\"\n [tabIndex]=\"focusable ? 0 : -1\"\n />\n</div>\n", styles: [":host{position:relative;display:block;block-size:.125rem;border-radius:var(--tui-radius-m);background:var(--tui-border-normal);cursor:pointer;outline:none;margin:.4375rem 0;touch-action:pan-x}:host:active{cursor:ew-resize}:host:after{content:\"\";position:absolute;top:-.4375rem;bottom:-.4375rem;inline-size:100%}:host._disabled{opacity:var(--tui-disabled-opacity);pointer-events:none}:host[data-size=s] .t-track{position:relative;margin:0 .25rem;block-size:100%}:host[data-size=s] .t-track:before{content:\"\";position:absolute;top:0;left:max(calc(var(--t-start) - 1px),1px);right:max(var(--t-end),1px);inset-inline-start:max(calc(var(--t-start) - 1px),1px);inset-inline-end:max(var(--t-end),1px);block-size:100%;background:var(--tui-background-accent-1);margin:0 -.25rem}:host[data-size=s] .t-track:after{position:absolute;top:0;left:0;bottom:0;right:0;content:\"\";left:.125rem;right:.375rem;inset-inline-start:.125rem;inset-inline-end:.375rem;background-image:repeating-linear-gradient(to var(--tui-inline-end),var(--tui-text-tertiary) 0 .25rem,transparent 0 calc(var(--t-segment-width) / var(--t-bg-size-ratio)));background-position-x:var(--tui-inline-end);background-repeat:no-repeat;background-size:calc(100% * var(--t-bg-size-ratio))}:host[data-size=m] .t-track{position:relative;margin:0 .375rem;block-size:100%}:host[data-size=m] .t-track:before{content:\"\";position:absolute;top:0;left:max(calc(var(--t-start) - 1px),1px);right:max(var(--t-end),1px);inset-inline-start:max(calc(var(--t-start) - 1px),1px);inset-inline-end:max(var(--t-end),1px);block-size:100%;background:var(--tui-background-accent-1);margin:0 -.375rem}:host[data-size=m] .t-track:after{position:absolute;top:0;left:0;bottom:0;right:0;content:\"\";left:.25rem;right:.5rem;inset-inline-start:.25rem;inset-inline-end:.5rem;background-image:repeating-linear-gradient(to var(--tui-inline-end),var(--tui-text-tertiary) 0 .25rem,transparent 0 calc(var(--t-segment-width) / var(--t-bg-size-ratio)));background-position-x:var(--tui-inline-end);background-repeat:no-repeat;background-size:calc(100% * var(--t-bg-size-ratio))}.t-thumb{pointer-events:none;position:absolute;top:.0625rem;left:0;right:0;z-index:1;transform:translateY(-50%)}.t-thumb::-webkit-slider-thumb{pointer-events:auto}.t-thumb::-moz-range-thumb{pointer-events:auto}:host._disabled .t-thumb::-webkit-slider-thumb{pointer-events:none}:host._disabled .t-thumb::-moz-range-thumb{pointer-events:none}input[type=range].t-thumb::-webkit-slider-runnable-track{background:transparent}input[type=range].t-thumb::-moz-range-track{background:transparent}input[type=range].t-thumb::-moz-range-progress{background:transparent}.t-thumb:first-of-type{--tui-slider-thumb-transform: translateX(calc(var(--tui-inline) * -50%)) translateX(calc(var(--tui-inline) * -1px))}.t-thumb:last-of-type{--tui-slider-thumb-transform: translateX(calc(var(--tui-inline) * 50%)) translateX(calc(var(--tui-inline) * 1px))}:host._disabled .t-thumb{opacity:1}\n"] }] }], propDecorators: { min: [{ type: Input }], max: [{ type: Input }], step: [{ type: Input }], size: [{ type: Input }], segments: [{ type: Input }], keySteps: [{ type: Input }], focusable: [{ type: Input }], margin: [{ type: Input }], limit: [{ type: Input }], slidersRefs: [{ type: ViewChildren, args: [TuiSliderComponent, { read: ElementRef }] }], computePureKeySteps: [] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva2l0L2NvbXBvbmVudHMvcmFuZ2UvcmFuZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva2l0L2NvbXBvbmVudHMvcmFuZ2UvcmFuZ2UudGVtcGxhdGUuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUNSLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEdBQ2YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDOUQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFHMUQsT0FBTyxFQUNILGtCQUFrQixFQUNsQiwyQkFBMkIsRUFDM0IsMkJBQTJCLEVBQzNCLFNBQVMsRUFDVCxrQkFBa0IsR0FDckIsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7Ozs7O0FBRXhELE1BNkJhLFFBQVMsU0FBUSxVQUE0QjtJQTdCMUQ7O1FBOEJJLHVEQUF1RDtRQUN0QyxZQUFPLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLE9BQUUsR0FB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LGFBQ3BDLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFDN0I7d0JBQ1o7NEJBQ0ksU0FBUyxFQUFFLGNBQWM7NEJBQ3pCLE9BQU8sRUFBRSxDQUFDLG1CQUFtQixDQUFDO3lCQUNqQztxQkFDSixRQUNLO3dCQUNGLGtCQUFrQixFQUFFLE1BQU07d0JBQzFCLGlCQUFpQixFQUFFLElBQUk7d0JBQ3ZCLHNCQUFzQixFQUFFLFlBQVk7d0JBQ3BDLHFCQUFxQixFQUFFLFNBQVM7d0JBQ2hDLG1CQUFtQixFQUFFLE9BQU87d0JBQzVCLG9CQUFvQixFQUFFLG9CQUFvQjt3QkFDMUMsbUJBQW1CLEVBQUUsWUFBWTt3QkFDakMsWUFBWSxFQUFFLGFBQWE7d0JBQzNCLDJCQUEyQixFQUFFLGdDQUFnQzt3QkFDN0QsNkJBQTZCLEVBQUUsaUNBQWlDO3dCQUNoRSw4QkFBOEIsRUFBRSwyQ0FBMkM7d0JBQzNFLDZCQUE2QixFQUFFLDJDQUEyQztxQkFDN0U7OEJBV00sR0FBRztzQkFEVCxLQUFLO2dCQUlDLEdBQUc7c0JBRFQsS0FBSztnQkFJQyxJQUFJO3NCQURWLEtBQUs7Z0JBSUMsSUFBSTtzQkFEVixLQUFLO2dCQUlDLFFBQVE7c0JBRGQsS0FBSztnQkFJQyxRQUFRO3NCQURkLEtBQUs7Z0JBSUMsU0FBUztzQkFEZixLQUFLO2dCQUlDLE1BQU07c0JBRFosS0FBSztnQkFJQyxLQUFLO3NCQURYLEtBQUs7Z0JBSVUsV0FBVztzQkFEMUIsWUFBWTt1QkFBQyxrQkFBa0IsRUFBRSxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUM7Z0JBaUU1QyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7T25DaGFuZ2VzLCBRdWVyeUxpc3R9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgY29tcHV0ZWQsXG4gICAgRWxlbWVudFJlZixcbiAgICBpbmplY3QsXG4gICAgSW5wdXQsXG4gICAgc2lnbmFsLFxuICAgIFZpZXdDaGlsZHJlbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0Zvcm1zTW9kdWxlfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1R1aUNvbnRyb2x9IGZyb20gJ0B0YWlnYS11aS9jZGsvY2xhc3Nlcyc7XG5pbXBvcnQge0VNUFRZX1FVRVJZfSBmcm9tICdAdGFpZ2EtdWkvY2RrL2NvbnN0YW50cyc7XG5pbXBvcnQge3R1aUZhbGxiYWNrVmFsdWVQcm92aWRlcn0gZnJvbSAnQHRhaWdhLXVpL2Nkay90b2tlbnMnO1xuaW1wb3J0IHt0dWlJbmplY3RFbGVtZW50fSBmcm9tICdAdGFpZ2EtdWkvY2RrL3V0aWxzL2RvbSc7XG5pbXBvcnQge3R1aUNsYW1wLCB0dWlRdWFudGl6ZX0gZnJvbSAnQHRhaWdhLXVpL2Nkay91dGlscy9tYXRoJztcbmltcG9ydCB7dHVpUHVyZX0gZnJvbSAnQHRhaWdhLXVpL2Nkay91dGlscy9taXNjZWxsYW5lb3VzJztcbmltcG9ydCB0eXBlIHtUdWlTaXplU30gZnJvbSAnQHRhaWdhLXVpL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHR5cGUge1R1aUtleVN0ZXBzfSBmcm9tICdAdGFpZ2EtdWkva2l0L2NvbXBvbmVudHMvc2xpZGVyJztcbmltcG9ydCB7XG4gICAgVFVJX1NMSURFUl9PUFRJT05TLFxuICAgIHR1aUtleVN0ZXBWYWx1ZVRvUGVyY2VudGFnZSxcbiAgICB0dWlQZXJjZW50YWdlVG9LZXlTdGVwVmFsdWUsXG4gICAgVHVpU2xpZGVyLFxuICAgIFR1aVNsaWRlckNvbXBvbmVudCxcbn0gZnJvbSAnQHRhaWdhLXVpL2tpdC9jb21wb25lbnRzL3NsaWRlcic7XG5cbmltcG9ydCB7VHVpUmFuZ2VDaGFuZ2V9IGZyb20gJy4vcmFuZ2UtY2hhbmdlLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICd0dWktcmFuZ2UnLFxuICAgIGltcG9ydHM6IFtGb3Jtc01vZHVsZSwgVHVpU2xpZGVyXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vcmFuZ2UudGVtcGxhdGUuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vcmFuZ2Uuc3R5bGUubGVzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIHByb3ZpZGVyczogW3R1aUZhbGxiYWNrVmFsdWVQcm92aWRlcihbMCwgMF0pXSxcbiAgICBob3N0RGlyZWN0aXZlczogW1xuICAgICAgICB7XG4gICAgICAgICAgICBkaXJlY3RpdmU6IFR1aVJhbmdlQ2hhbmdlLFxuICAgICAgICAgICAgb3V0cHV0czogWydhY3RpdmVUaHVtYkNoYW5nZSddLFxuICAgICAgICB9LFxuICAgIF0sXG4gICAgaG9zdDoge1xuICAgICAgICAnW2F0dHIuZGF0YS1zaXplXSc6ICdzaXplJyxcbiAgICAgICAgJ1thdHRyLnRhYmluZGV4XSc6ICctMScsXG4gICAgICAgICdbYXR0ci5hcmlhLWRpc2FibGVkXSc6ICdkaXNhYmxlZCgpJyxcbiAgICAgICAgJ1tzdHlsZS4tLXQtc3RhcnQuJV0nOiAnc3RhcnQoKScsXG4gICAgICAgICdbc3R5bGUuLS10LWVuZC4lXSc6ICdlbmQoKScsXG4gICAgICAgICdbc3R5bGUuYmFja2dyb3VuZF0nOiAnb3B0aW9ucy50cmFja0NvbG9yJyxcbiAgICAgICAgJ1tjbGFzcy5fZGlzYWJsZWRdJzogJ2Rpc2FibGVkKCknLFxuICAgICAgICAnKGZvY3Vzb3V0KSc6ICdvblRvdWNoZWQoKScsXG4gICAgICAgICcoa2V5ZG93bi5hcnJvd1VwLnByZXZlbnQpJzogJ2NoYW5nZUJ5U3RlcCgxLCAkZXZlbnQudGFyZ2V0KScsXG4gICAgICAgICcoa2V5ZG93bi5hcnJvd0Rvd24ucHJldmVudCknOiAnY2hhbmdlQnlTdGVwKC0xLCAkZXZlbnQudGFyZ2V0KScsXG4gICAgICAgICcoa2V5ZG93bi5hcnJvd1JpZ2h0LnByZXZlbnQpJzogJ2NoYW5nZUJ5U3RlcChydGwgPyAtMSA6IDEsICRldmVudC50YXJnZXQpJyxcbiAgICAgICAgJyhrZXlkb3duLmFycm93TGVmdC5wcmV2ZW50KSc6ICdjaGFuZ2VCeVN0ZXAocnRsID8gMSA6IC0xLCAkZXZlbnQudGFyZ2V0KScsXG4gICAgfSxcbn0pXG5leHBvcnQgY2xhc3MgVHVpUmFuZ2UgZXh0ZW5kcyBUdWlDb250cm9sPFtudW1iZXIsIG51bWJlcl0+IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgICAvLyBUT0RPOiByZWZhY3RvciB0byBzaWduYWwgaW5wdXRzIGFmdGVyIEFuZ3VsYXIgdXBkYXRlXG4gICAgcHJpdmF0ZSByZWFkb25seSBjaGFuZ2VzID0gc2lnbmFsKDEpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZWwgPSB0dWlJbmplY3RFbGVtZW50KCk7XG5cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3B0aW9ucyA9IGluamVjdChUVUlfU0xJREVSX09QVElPTlMpO1xuICAgIHByb3RlY3RlZCBsYXN0QWN0aXZlVGh1bWI6ICdlbmQnIHwgJ3N0YXJ0JyA9ICdlbmQnO1xuXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgbWluID0gMDtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIG1heCA9IDEwMDtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHN0ZXAgPSAxO1xuXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc2l6ZTogVHVpU2l6ZVMgPSB0aGlzLm9wdGlvbnMuc2l6ZTtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNlZ21lbnRzID0gMTtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGtleVN0ZXBzOiBUdWlLZXlTdGVwcyB8IG51bGwgPSBudWxsO1xuXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZm9jdXNhYmxlID0gdHJ1ZTtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIG1hcmdpbiA9IDA7XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBsaW1pdCA9IEluZmluaXR5O1xuXG4gICAgQFZpZXdDaGlsZHJlbihUdWlTbGlkZXJDb21wb25lbnQsIHtyZWFkOiBFbGVtZW50UmVmfSlcbiAgICBwdWJsaWMgcmVhZG9ubHkgc2xpZGVyc1JlZnM6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+PiA9IEVNUFRZX1FVRVJZO1xuXG4gICAgcHVibGljIHJlYWRvbmx5IHN0YXJ0ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy50b1BlcmNlbnQodGhpcy52YWx1ZSgpWzBdKSk7XG4gICAgcHVibGljIHJlYWRvbmx5IGVuZCA9IGNvbXB1dGVkKCgpID0+IDEwMCAtIHRoaXMudG9QZXJjZW50KHRoaXMudmFsdWUoKVsxXSkpO1xuXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNoYW5nZXMudXBkYXRlKCh4KSA9PiB4ICsgMSk7XG4gICAgfVxuXG4gICAgcHVibGljIHByb2Nlc3NWYWx1ZSh2YWx1ZTogbnVtYmVyLCBlbmQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgaWYgKGVuZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVFbmQodmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVTdGFydCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxhc3RBY3RpdmVUaHVtYiA9IGVuZCA/ICdlbmQnIDogJ3N0YXJ0JztcbiAgICB9XG5cbiAgICBwdWJsaWMgdG9WYWx1ZShmcmFjdGlvbjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHR1aVBlcmNlbnRhZ2VUb0tleVN0ZXBWYWx1ZShcbiAgICAgICAgICAgIHR1aUNsYW1wKHR1aVF1YW50aXplKGZyYWN0aW9uLCB0aGlzLmZyYWN0aW9uU3RlcCksIDAsIDEpICogMTAwLFxuICAgICAgICAgICAgdGhpcy5jb21wdXRlZEtleVN0ZXBzLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgZnJhY3Rpb25TdGVwKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0ZXAgLyAodGhpcy5tYXggLSB0aGlzLm1pbik7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjb21wdXRlZEtleVN0ZXBzKCk6IFR1aUtleVN0ZXBzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZVB1cmVLZXlTdGVwcyh0aGlzLmtleVN0ZXBzLCB0aGlzLm1pbiwgdGhpcy5tYXgpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgc2VnbWVudFdpZHRoUmF0aW8oKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIDEgLyB0aGlzLnNlZ21lbnRzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgcnRsKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5lbC5tYXRjaGVzKCdbZGlyPVwicnRsXCJdIDpzY29wZScpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBjaGFuZ2VCeVN0ZXAoY29lZmZpY2llbnQ6IG51bWJlciwgdGFyZ2V0OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBbc3RhcnRUaHVtYiwgZW5kVGh1bWJdID0gdGhpcy5zbGlkZXJzUmVmcy5tYXAoKHgpID0+IHg/Lm5hdGl2ZUVsZW1lbnQpO1xuXG4gICAgICAgIGNvbnN0IGlzRW5kVGh1bWIgPVxuICAgICAgICAgICAgdGFyZ2V0ID09PSB0aGlzLmVsID8gdGhpcy5sYXN0QWN0aXZlVGh1bWIgPT09ICdlbmQnIDogdGFyZ2V0ID09PSBlbmRUaHVtYjtcbiAgICAgICAgY29uc3QgYWN0aXZlVGh1bWJFbGVtZW50ID0gaXNFbmRUaHVtYiA/IGVuZFRodW1iIDogc3RhcnRUaHVtYjtcbiAgICAgICAgY29uc3QgcHJldmlvdXNWYWx1ZSA9IHRoaXMudmFsdWUoKVtpc0VuZFRodW1iID8gMSA6IDBdO1xuICAgICAgICAvKiogQGJhZCBUT0RPIHRoaW5rIGFib3V0IGEgc29sdXRpb24gd2l0aG91dCB0d2ljZSBjb252ZXJzaW9uICovXG4gICAgICAgIGNvbnN0IHByZXZpb3VzRnJhY3Rpb24gPSB0aGlzLnRvUGVyY2VudChwcmV2aW91c1ZhbHVlKSAvIDEwMDtcbiAgICAgICAgY29uc3QgbmV3RnJhY3Rpb25WYWx1ZSA9IHByZXZpb3VzRnJhY3Rpb24gKyBjb2VmZmljaWVudCAqIHRoaXMuZnJhY3Rpb25TdGVwO1xuXG4gICAgICAgIHRoaXMucHJvY2Vzc1ZhbHVlKHRoaXMudG9WYWx1ZShuZXdGcmFjdGlvblZhbHVlKSwgaXNFbmRUaHVtYik7XG4gICAgICAgIGFjdGl2ZVRodW1iRWxlbWVudD8uZm9jdXMoKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgdG9QZXJjZW50KHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VzKCkgJiYgdHVpS2V5U3RlcFZhbHVlVG9QZXJjZW50YWdlKHZhbHVlLCB0aGlzLmNvbXB1dGVkS2V5U3RlcHMpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgQHR1aVB1cmVcbiAgICBwcml2YXRlIGNvbXB1dGVQdXJlS2V5U3RlcHMoXG4gICAgICAgIGtleVN0ZXBzOiBUdWlLZXlTdGVwcyB8IG51bGwsXG4gICAgICAgIG1pbjogbnVtYmVyLFxuICAgICAgICBtYXg6IG51bWJlcixcbiAgICApOiBUdWlLZXlTdGVwcyB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBrZXlTdGVwcyB8fCBbXG4gICAgICAgICAgICAgICAgWzAsIG1pbl0sXG4gICAgICAgICAgICAgICAgWzEwMCwgbWF4XSxcbiAgICAgICAgICAgIF1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVN0YXJ0KHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSBNYXRoLm1pbih2YWx1ZSwgdGhpcy52YWx1ZSgpWzFdKTtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSB0aGlzLnZhbHVlKClbMV0gLSBuZXdWYWx1ZTtcblxuICAgICAgICBpZiAoIXRoaXMuY2hlY2tEaXN0YW5jZShkaXN0YW5jZSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub25DaGFuZ2UoW25ld1ZhbHVlLCB0aGlzLnZhbHVlKClbMV1dKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUVuZCh2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gTWF0aC5tYXgodmFsdWUsIHRoaXMudmFsdWUoKVswXSk7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gbmV3VmFsdWUgLSB0aGlzLnZhbHVlKClbMF07XG5cbiAgICAgICAgaWYgKCF0aGlzLmNoZWNrRGlzdGFuY2UoZGlzdGFuY2UpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9uQ2hhbmdlKFt0aGlzLnZhbHVlKClbMF0sIG5ld1ZhbHVlXSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGVja0Rpc3RhbmNlKGRpc3RhbmNlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHR1aUNsYW1wKGRpc3RhbmNlLCB0aGlzLm1hcmdpbiwgdGhpcy5saW1pdCkgPT09IGRpc3RhbmNlO1xuICAgIH1cbn1cbiIsIjxkaXZcbiAgICBjbGFzcz1cInQtdHJhY2tcIlxuICAgIFtzdHlsZS4tLXQtYmctc2l6ZS1yYXRpb109XCIxIC0gc2VnbWVudFdpZHRoUmF0aW9cIlxuICAgIFtzdHlsZS4tLXQtc2VnbWVudC13aWR0aC4lXT1cInNlZ21lbnRXaWR0aFJhdGlvICogMTAwXCJcbj5cbiAgICA8aW5wdXRcbiAgICAgICAgYXV0b21hdGlvbi1pZD1cInR1aS1yYW5nZV9fbGVmdFwiXG4gICAgICAgIHJlYWRvbmx5XG4gICAgICAgIHN0ZXA9XCJhbnlcIlxuICAgICAgICB0dWlTbGlkZXJcbiAgICAgICAgdHlwZT1cInJhbmdlXCJcbiAgICAgICAgY2xhc3M9XCJ0LXRodW1iXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkKClcIlxuICAgICAgICBba2V5U3RlcHNdPVwiY29tcHV0ZWRLZXlTdGVwc1wiXG4gICAgICAgIFttYXhdPVwibWF4XCJcbiAgICAgICAgW21pbl09XCJtaW5cIlxuICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZSgpWzBdXCJcbiAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiXG4gICAgICAgIFtzaXplXT1cInNpemVcIlxuICAgICAgICBbdGFiSW5kZXhdPVwiZm9jdXNhYmxlID8gMCA6IC0xXCJcbiAgICAvPlxuICAgIDxpbnB1dFxuICAgICAgICBhdXRvbWF0aW9uLWlkPVwidHVpLXJhbmdlX19yaWdodFwiXG4gICAgICAgIHJlYWRvbmx5XG4gICAgICAgIHN0ZXA9XCJhbnlcIlxuICAgICAgICB0dWlTbGlkZXJcbiAgICAgICAgdHlwZT1cInJhbmdlXCJcbiAgICAgICAgY2xhc3M9XCJ0LXRodW1iXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkKClcIlxuICAgICAgICBba2V5U3RlcHNdPVwiY29tcHV0ZWRLZXlTdGVwc1wiXG4gICAgICAgIFttYXhdPVwibWF4XCJcbiAgICAgICAgW21pbl09XCJtaW5cIlxuICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZSgpWzFdXCJcbiAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiXG4gICAgICAgIFtzaXplXT1cInNpemVcIlxuICAgICAgICBbdGFiSW5kZXhdPVwiZm9jdXNhYmxlID8gMCA6IC0xXCJcbiAgICAvPlxuPC9kaXY+XG4iXX0=