input-number.component.mjs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { ChangeDetectionStrategy, Component, HostListener, Input, Optional, forwardRef, inject, } from '@angular/core';
  2. import { AsyncPipe, DecimalPipe, NgClass } from '@angular/common';
  3. import { InputComponent } from '../input/input.component';
  4. import { provideControlContainer, provideValueAccessor } from '../utils/form.util';
  5. import { integerValidator } from '../utils/validators.util';
  6. import { LabelComponent } from '../label/label.component';
  7. import { IconComponent } from '../../components/atoms/icon/icon.component';
  8. import { FormErrorComponent } from '../error/error.component';
  9. import * as i0 from "@angular/core";
  10. import * as i1 from "@angular/forms";
  11. export class InputNumberComponent extends InputComponent {
  12. constructor(formGroupDirective) {
  13. super(formGroupDirective);
  14. this.formGroupDirective = formGroupDirective;
  15. this.decimalPipe = inject(DecimalPipe);
  16. this.validate = 'integer';
  17. }
  18. onFocusOut() {
  19. this.formatNumber();
  20. this.triggerTouched();
  21. }
  22. onFocusIn() {
  23. this.reverseFormatNumber();
  24. }
  25. ngOnInit() {
  26. if (this.formControl && this.validate === 'integer')
  27. this.formControl.addValidators(integerValidator());
  28. }
  29. ngAfterViewInit() {
  30. this.formatNumber();
  31. this.triggerChangeDetection();
  32. }
  33. formatNumber() {
  34. try {
  35. this.value = this.decimalPipe.transform(this.value, '1.0-2') || '';
  36. }
  37. catch (_error) {
  38. return;
  39. }
  40. }
  41. reverseFormatNumber() {
  42. this.value = !isNaN(parseFloat(this.value.replace(/[^0-9.-]/g, '')))
  43. ? parseFloat(this.value.replace(/[^0-9.-]/g, ''))
  44. : '';
  45. }
  46. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: InputNumberComponent, deps: [{ token: i1.FormGroupDirective, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
  47. static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.5", type: InputNumberComponent, isStandalone: true, selector: "ct-input-number", inputs: { validate: "validate" }, host: { listeners: { "focusout": "onFocusOut()", "focusin": "onFocusIn()" } }, providers: [provideValueAccessor(forwardRef(() => InputNumberComponent)), DecimalPipe], usesInheritance: true, ngImport: i0, template: "<div\n class=\"flex\"\n [ngClass]=\"{\n 'items-center gap-4': disposition === 'horizontal',\n 'flex-col gap-0.5': disposition === 'vertical'\n }\">\n @if (label) {\n <ct-form-label [text]=\"label\" [hasError]=\"hasErrors(formControl)\" [showError]=\"showError\" />\n }\n <div\n class=\"relative inline-block rounded-md text-on-surface dark:text-on-surface-dark\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\">\n <input\n tabindex=\"0\"\n [type]=\"type\"\n [min]=\"min\"\n [max]=\"max\"\n class=\"h-9 rounded-md border bg-surface font-primary text-sm outline-primary hover:border-neutral-600 dark:bg-surface-dark dark:outline-primary-dark focus:dark:border-primary-dark\"\n [class.px-4]=\"!icon || !symbol\"\n [ngClass]=\"{\n 'px-4': !icon,\n 'pr-4 pl-10': icon && iconPosition === 'left',\n 'pl-4 pr-10': (icon && iconPosition === 'right') || symbol || canDelete\n }\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\"\n [class.border-neutral-300]=\"!hasErrors(formControl) || !showError\"\n [class.border-error]=\"hasErrors(formControl) && showError\"\n [class.border-success]=\"formControl && formControl.valid && showError\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n (input)=\"input($event)\" />\n @if (icon) {\n <ct-icon\n class=\"absolute top-2\"\n [class.left-3]=\"iconPosition === 'left'\"\n [class.right-3]=\"iconPosition === 'right'\"\n [icon]=\"icon\" />\n }\n @if (symbol) {\n <span class=\"absolute right-3 top-2.5 text-xs text-neutral-600 dark:text-neutral-300\">{{ symbol }}</span>\n }\n @if (showDelete$ | async) {\n <ct-icon class=\"absolute right-3 top-2.5 cursor-pointer\" icon=\"x-mark\" size=\"sm\" (click)=\"clearValue()\" />\n }\n </div>\n @if (formControl) {\n <ct-form-alert\n [fullSize]=\"fullSize\"\n [hasErrors]=\"hasErrors(formControl)\"\n [helper]=\"helper\"\n [errors]=\"formControl.errors ?? {}\"\n size=\"xs\" />\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: LabelComponent, selector: "ct-form-label", inputs: ["text", "type", "formControlName", "hasError", "showError"] }, { kind: "component", type: IconComponent, selector: "ct-icon", inputs: ["icon", "fill", "strokeWidth", "strokeColor", "size", "variant"] }, { kind: "component", type: FormErrorComponent, selector: "ct-form-alert", inputs: ["errors", "size", "hasErrors", "fullSize", "helper", "errorMessages"] }], viewProviders: [provideControlContainer()], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
  48. }
  49. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: InputNumberComponent, decorators: [{
  50. type: Component,
  51. args: [{ selector: 'ct-input-number', standalone: true, imports: [NgClass, AsyncPipe, LabelComponent, IconComponent, FormErrorComponent], providers: [provideValueAccessor(forwardRef(() => InputNumberComponent)), DecimalPipe], viewProviders: [provideControlContainer()], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"flex\"\n [ngClass]=\"{\n 'items-center gap-4': disposition === 'horizontal',\n 'flex-col gap-0.5': disposition === 'vertical'\n }\">\n @if (label) {\n <ct-form-label [text]=\"label\" [hasError]=\"hasErrors(formControl)\" [showError]=\"showError\" />\n }\n <div\n class=\"relative inline-block rounded-md text-on-surface dark:text-on-surface-dark\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\">\n <input\n tabindex=\"0\"\n [type]=\"type\"\n [min]=\"min\"\n [max]=\"max\"\n class=\"h-9 rounded-md border bg-surface font-primary text-sm outline-primary hover:border-neutral-600 dark:bg-surface-dark dark:outline-primary-dark focus:dark:border-primary-dark\"\n [class.px-4]=\"!icon || !symbol\"\n [ngClass]=\"{\n 'px-4': !icon,\n 'pr-4 pl-10': icon && iconPosition === 'left',\n 'pl-4 pr-10': (icon && iconPosition === 'right') || symbol || canDelete\n }\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\"\n [class.border-neutral-300]=\"!hasErrors(formControl) || !showError\"\n [class.border-error]=\"hasErrors(formControl) && showError\"\n [class.border-success]=\"formControl && formControl.valid && showError\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n (input)=\"input($event)\" />\n @if (icon) {\n <ct-icon\n class=\"absolute top-2\"\n [class.left-3]=\"iconPosition === 'left'\"\n [class.right-3]=\"iconPosition === 'right'\"\n [icon]=\"icon\" />\n }\n @if (symbol) {\n <span class=\"absolute right-3 top-2.5 text-xs text-neutral-600 dark:text-neutral-300\">{{ symbol }}</span>\n }\n @if (showDelete$ | async) {\n <ct-icon class=\"absolute right-3 top-2.5 cursor-pointer\" icon=\"x-mark\" size=\"sm\" (click)=\"clearValue()\" />\n }\n </div>\n @if (formControl) {\n <ct-form-alert\n [fullSize]=\"fullSize\"\n [hasErrors]=\"hasErrors(formControl)\"\n [helper]=\"helper\"\n [errors]=\"formControl.errors ?? {}\"\n size=\"xs\" />\n }\n</div>\n" }]
  52. }], ctorParameters: () => [{ type: i1.FormGroupDirective, decorators: [{
  53. type: Optional
  54. }] }], propDecorators: { validate: [{
  55. type: Input
  56. }], onFocusOut: [{
  57. type: HostListener,
  58. args: ['focusout']
  59. }], onFocusIn: [{
  60. type: HostListener,
  61. args: ['focusin']
  62. }] } });
  63. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtbnVtYmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NpcmNsZXRvbmUvc3JjL2xpYi9mb3Jtcy9pbnB1dC1udW1iZXIvaW5wdXQtbnVtYmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NpcmNsZXRvbmUvc3JjL2xpYi9mb3Jtcy9pbnB1dC9pbnB1dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLFFBQVEsRUFDUixVQUFVLEVBQ1YsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7QUFXOUQsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGNBQWM7SUFLdEQsWUFBMkMsa0JBQXNDO1FBQy9FLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRGUsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUpoRSxnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUxQyxhQUFRLEdBQThCLFNBQVMsQ0FBQztJQUl6RCxDQUFDO0lBR1EsVUFBVTtRQUNqQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFHRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTO1lBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNyRSxDQUFDO1FBQUMsT0FBTyxNQUFNLEVBQUUsQ0FBQztZQUNoQixPQUFPO1FBQ1QsQ0FBQztJQUNILENBQUM7SUFFRCxtQkFBbUI7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbEUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDakQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNULENBQUM7OEdBekNVLG9CQUFvQjtrR0FBcEIsb0JBQW9CLCtLQUpwQixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLGlEQ3pCeEYsb2tFQXdEQSw0Q0RqQ1ksT0FBTywrRUFBRSxTQUFTLDhDQUFFLGNBQWMsZ0lBQUUsYUFBYSwrSEFBRSxrQkFBa0IsK0hBR2hFLENBQUMsdUJBQXVCLEVBQUUsQ0FBQzs7MkZBRy9CLG9CQUFvQjtrQkFUaEMsU0FBUzsrQkFDRSxpQkFBaUIsY0FDZixJQUFJLFdBQ1AsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLENBQUMsYUFFckUsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLHFCQUFxQixDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsaUJBQ3ZFLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxtQkFDekIsdUJBQXVCLENBQUMsTUFBTTs7MEJBT2xDLFFBQVE7eUNBRlosUUFBUTtzQkFBaEIsS0FBSztnQkFPRyxVQUFVO3NCQURsQixZQUFZO3VCQUFDLFVBQVU7Z0JBT3hCLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgZm9yd2FyZFJlZixcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFzeW5jUGlwZSwgRGVjaW1hbFBpcGUsIE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybUdyb3VwRGlyZWN0aXZlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSW5wdXRDb21wb25lbnQgfSBmcm9tICcuLi9pbnB1dC9pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgcHJvdmlkZUNvbnRyb2xDb250YWluZXIsIHByb3ZpZGVWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnLi4vdXRpbHMvZm9ybS51dGlsJztcbmltcG9ydCB7IGludGVnZXJWYWxpZGF0b3IgfSBmcm9tICcuLi91dGlscy92YWxpZGF0b3JzLnV0aWwnO1xuaW1wb3J0IHsgTGFiZWxDb21wb25lbnQgfSBmcm9tICcuLi9sYWJlbC9sYWJlbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWNvbkNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvYXRvbXMvaWNvbi9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBGb3JtRXJyb3JDb21wb25lbnQgfSBmcm9tICcuLi9lcnJvci9lcnJvci5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjdC1pbnB1dC1udW1iZXInLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbTmdDbGFzcywgQXN5bmNQaXBlLCBMYWJlbENvbXBvbmVudCwgSWNvbkNvbXBvbmVudCwgRm9ybUVycm9yQ29tcG9uZW50XSxcbiAgdGVtcGxhdGVVcmw6ICcuLi9pbnB1dC9pbnB1dC5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW3Byb3ZpZGVWYWx1ZUFjY2Vzc29yKGZvcndhcmRSZWYoKCkgPT4gSW5wdXROdW1iZXJDb21wb25lbnQpKSwgRGVjaW1hbFBpcGVdLFxuICB2aWV3UHJvdmlkZXJzOiBbcHJvdmlkZUNvbnRyb2xDb250YWluZXIoKV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBJbnB1dE51bWJlckNvbXBvbmVudCBleHRlbmRzIElucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWNpbWFsUGlwZSA9IGluamVjdChEZWNpbWFsUGlwZSk7XG4gIHByaXZhdGUgcmF3VmFsdWUhOiBudW1iZXI7XG4gIEBJbnB1dCgpIHZhbGlkYXRlOiAnaW50ZWdlcicgfCAnY3JlZGl0LWNhcmQnID0gJ2ludGVnZXInO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIHByb3RlY3RlZCBvdmVycmlkZSBmb3JtR3JvdXBEaXJlY3RpdmU6IEZvcm1Hcm91cERpcmVjdGl2ZSkge1xuICAgIHN1cGVyKGZvcm1Hcm91cERpcmVjdGl2ZSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdmb2N1c291dCcpXG4gIG92ZXJyaWRlIG9uRm9jdXNPdXQoKSB7XG4gICAgdGhpcy5mb3JtYXROdW1iZXIoKTtcbiAgICB0aGlzLnRyaWdnZXJUb3VjaGVkKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdmb2N1c2luJylcbiAgb25Gb2N1c0luKCkge1xuICAgIHRoaXMucmV2ZXJzZUZvcm1hdE51bWJlcigpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZm9ybUNvbnRyb2wgJiYgdGhpcy52YWxpZGF0ZSA9PT0gJ2ludGVnZXInKSB0aGlzLmZvcm1Db250cm9sLmFkZFZhbGlkYXRvcnMoaW50ZWdlclZhbGlkYXRvcigpKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1hdE51bWJlcigpO1xuICAgIHRoaXMudHJpZ2dlckNoYW5nZURldGVjdGlvbigpO1xuICB9XG5cbiAgZm9ybWF0TnVtYmVyKCkge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5kZWNpbWFsUGlwZS50cmFuc2Zvcm0odGhpcy52YWx1ZSwgJzEuMC0yJykgfHwgJyc7XG4gICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgcmV2ZXJzZUZvcm1hdE51bWJlcigpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gIWlzTmFOKHBhcnNlRmxvYXQodGhpcy52YWx1ZS5yZXBsYWNlKC9bXjAtOS4tXS9nLCAnJykpKVxuICAgICAgPyBwYXJzZUZsb2F0KHRoaXMudmFsdWUucmVwbGFjZSgvW14wLTkuLV0vZywgJycpKVxuICAgICAgOiAnJztcbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImZsZXhcIlxuICBbbmdDbGFzc109XCJ7XG4gICAgJ2l0ZW1zLWNlbnRlciBnYXAtNCc6IGRpc3Bvc2l0aW9uID09PSAnaG9yaXpvbnRhbCcsXG4gICAgJ2ZsZXgtY29sIGdhcC0wLjUnOiBkaXNwb3NpdGlvbiA9PT0gJ3ZlcnRpY2FsJ1xuICB9XCI+XG4gIEBpZiAobGFiZWwpIHtcbiAgICA8Y3QtZm9ybS1sYWJlbCBbdGV4dF09XCJsYWJlbFwiIFtoYXNFcnJvcl09XCJoYXNFcnJvcnMoZm9ybUNvbnRyb2wpXCIgW3Nob3dFcnJvcl09XCJzaG93RXJyb3JcIiAvPlxuICB9XG4gIDxkaXZcbiAgICBjbGFzcz1cInJlbGF0aXZlIGlubGluZS1ibG9jayByb3VuZGVkLW1kIHRleHQtb24tc3VyZmFjZSBkYXJrOnRleHQtb24tc3VyZmFjZS1kYXJrXCJcbiAgICBbY2xhc3Mudy1maXRdPVwiIWZ1bGxTaXplXCJcbiAgICBbY2xhc3Mudy1mdWxsXT1cImZ1bGxTaXplXCI+XG4gICAgPGlucHV0XG4gICAgICB0YWJpbmRleD1cIjBcIlxuICAgICAgW3R5cGVdPVwidHlwZVwiXG4gICAgICBbbWluXT1cIm1pblwiXG4gICAgICBbbWF4XT1cIm1heFwiXG4gICAgICBjbGFzcz1cImgtOSByb3VuZGVkLW1kIGJvcmRlciBiZy1zdXJmYWNlIGZvbnQtcHJpbWFyeSB0ZXh0LXNtIG91dGxpbmUtcHJpbWFyeSBob3Zlcjpib3JkZXItbmV1dHJhbC02MDAgZGFyazpiZy1zdXJmYWNlLWRhcmsgZGFyazpvdXRsaW5lLXByaW1hcnktZGFyayBmb2N1czpkYXJrOmJvcmRlci1wcmltYXJ5LWRhcmtcIlxuICAgICAgW2NsYXNzLnB4LTRdPVwiIWljb24gfHwgIXN5bWJvbFwiXG4gICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICdweC00JzogIWljb24sXG4gICAgICAgICdwci00IHBsLTEwJzogaWNvbiAmJiBpY29uUG9zaXRpb24gPT09ICdsZWZ0JyxcbiAgICAgICAgJ3BsLTQgcHItMTAnOiAoaWNvbiAmJiBpY29uUG9zaXRpb24gPT09ICdyaWdodCcpIHx8IHN5bWJvbCB8fCBjYW5EZWxldGVcbiAgICAgIH1cIlxuICAgICAgW2NsYXNzLnctZml0XT1cIiFmdWxsU2l6ZVwiXG4gICAgICBbY2xhc3Mudy1mdWxsXT1cImZ1bGxTaXplXCJcbiAgICAgIFtjbGFzcy5ib3JkZXItbmV1dHJhbC0zMDBdPVwiIWhhc0Vycm9ycyhmb3JtQ29udHJvbCkgfHwgIXNob3dFcnJvclwiXG4gICAgICBbY2xhc3MuYm9yZGVyLWVycm9yXT1cImhhc0Vycm9ycyhmb3JtQ29udHJvbCkgJiYgc2hvd0Vycm9yXCJcbiAgICAgIFtjbGFzcy5ib3JkZXItc3VjY2Vzc109XCJmb3JtQ29udHJvbCAmJiBmb3JtQ29udHJvbC52YWxpZCAmJiBzaG93RXJyb3JcIlxuICAgICAgW3ZhbHVlXT1cInZhbHVlXCJcbiAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAoaW5wdXQpPVwiaW5wdXQoJGV2ZW50KVwiIC8+XG4gICAgQGlmIChpY29uKSB7XG4gICAgICA8Y3QtaWNvblxuICAgICAgICBjbGFzcz1cImFic29sdXRlIHRvcC0yXCJcbiAgICAgICAgW2NsYXNzLmxlZnQtM109XCJpY29uUG9zaXRpb24gPT09ICdsZWZ0J1wiXG4gICAgICAgIFtjbGFzcy5yaWdodC0zXT1cImljb25Qb3NpdGlvbiA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgIFtpY29uXT1cImljb25cIiAvPlxuICAgIH1cbiAgICBAaWYgKHN5bWJvbCkge1xuICAgICAgPHNwYW4gY2xhc3M9XCJhYnNvbHV0ZSByaWdodC0zIHRvcC0yLjUgdGV4dC14cyB0ZXh0LW5ldXRyYWwtNjAwIGRhcms6dGV4dC1uZXV0cmFsLTMwMFwiPnt7IHN5bWJvbCB9fTwvc3Bhbj5cbiAgICB9XG4gICAgQGlmIChzaG93RGVsZXRlJCB8IGFzeW5jKSB7XG4gICAgICA8Y3QtaWNvbiBjbGFzcz1cImFic29sdXRlIHJpZ2h0LTMgdG9wLTIuNSBjdXJzb3ItcG9pbnRlclwiIGljb249XCJ4LW1hcmtcIiBzaXplPVwic21cIiAoY2xpY2spPVwiY2xlYXJWYWx1ZSgpXCIgLz5cbiAgICB9XG4gIDwvZGl2PlxuICBAaWYgKGZvcm1Db250cm9sKSB7XG4gICAgPGN0LWZvcm0tYWxlcnRcbiAgICAgIFtmdWxsU2l6ZV09XCJmdWxsU2l6ZVwiXG4gICAgICBbaGFzRXJyb3JzXT1cImhhc0Vycm9ycyhmb3JtQ29udHJvbClcIlxuICAgICAgW2hlbHBlcl09XCJoZWxwZXJcIlxuICAgICAgW2Vycm9yc109XCJmb3JtQ29udHJvbC5lcnJvcnMgPz8ge31cIlxuICAgICAgc2l6ZT1cInhzXCIgLz5cbiAgfVxuPC9kaXY+XG4iXX0=