UNPKG

ngx-otp-code

Version:

Customizable OTP input component for Angular with Web OTP support.

181 lines 23.4 kB
import { NgClass, NgFor } from '@angular/common'; import { Component, EventEmitter, forwardRef, Input, Output, ViewChildren } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import * as i0 from "@angular/core"; export class NgxOtpCodeComponent { get length() { return this.config.length ?? 6; } get inputType() { return this.config.inputType ?? 'text'; } get placeholder() { return this.config.placeholder ?? ''; } get autoFocus() { return this.config.autoFocus ?? true; } get isAlpha() { return this.config.isAlpha ?? false; } get mask() { return this.config.mask ?? false; } get useWebOtp() { return this.config.useWebOtp ?? false; } get inputClass() { return this.config.inputClass ?? ''; } constructor(renderer) { this.renderer = renderer; this.config = {}; this.codeFilled = new EventEmitter(); this.error = new EventEmitter(); this.arrayValue = []; this.value = ''; this.nameItem = 'otp-'; this.onChange = () => { }; this.onTouched = () => { }; } ngAfterViewInit() { if (this.autoFocus) { this.focusInput(0); } if (this.useWebOtp && 'OTPCredential' in window) { this.initWebOtp(); } } initWebOtp() { const ac = new AbortController(); navigator.credentials.get({ otp: { transport: ['sms'] }, signal: ac.signal }).then((otp) => { if (otp?.code) { this.setOtpValue(otp.code); } }).catch((err) => { console.log(err); }); } onKey(event, index) { const input = event.target; const key = event.key; if (key === 'Backspace') { this.arrayValue[index] = ''; input.value = ''; if (index > 0) { this.focusInput(index - 1); } this.updateValue(); event.preventDefault(); return; } // Allow only a single char per box if (key.length === 1) { // Check validity based on input type if (this.inputType === 'number' && !/^\d$/.test(key)) { event.preventDefault(); return; } if (this.isAlpha && !/^[A-Za-z0-9]$/.test(key)) { event.preventDefault(); return; } // Assign value this.arrayValue[index] = key; input.value = key; // Move to next input if not last if (index < this.length - 1) { this.focusInput(index + 1); } else { input.blur(); // Optionally blur if finished } this.updateValue(); event.preventDefault(); } else { // Ignore other keys (arrows, etc.) event.preventDefault(); } } onPaste(event) { event.preventDefault(); const pasted = event.clipboardData?.getData('text') || ''; if (this.inputType === 'number' && /\D/.test(pasted)) { this.error.emit('El código solo debe contener números.'); return; } if (pasted.length < this.length) { this.error.emit(`La cantidad de caracteres no puede ser menor a ${this.length}.`); return; } this.setOtpValue(pasted); } setOtpValue(value) { this.arrayValue = value.split('').slice(0, this.length); this.otpInputs?.forEach((ref, i) => { ref.nativeElement.value = this.arrayValue[i] || ''; }); this.updateValue(); } focusInput(index) { const el = this.otpInputs?.get(index); if (el) { el.nativeElement.focus(); el.nativeElement.select(); } } updateValue() { this.value = this.arrayValue.join(''); this.onChange(this.value); if (this.value.length === this.length) { this.codeFilled.emit(this.value); } } writeValue(value) { this.value = value || ''; this.arrayValue = this.value.split(''); setTimeout(() => { this.otpInputs?.forEach((ref, i) => { ref.nativeElement.value = this.arrayValue[i] || ''; }); }); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxOtpCodeComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NgxOtpCodeComponent, isStandalone: true, selector: "ngx-otp-code", inputs: { config: "config" }, outputs: { codeFilled: "codeFilled", error: "error" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxOtpCodeComponent), multi: true } ], viewQueries: [{ propertyName: "otpInputs", predicate: ["otpInput"], descendants: true }], ngImport: i0, template: "<div class=\"otp-container\" [ngClass]=\"config?.containerClass\">\n <input\n *ngFor=\"let item of [].constructor(length); let i = index\"\n #otpInput\n [type]=\"config?.mask ? 'password' : config?.inputType || 'text'\"\n [attr.placeholder]=\"config?.placeholder\"\n maxlength=\"1\"\n (keydown)=\"onKey($event, i)\"\n (paste)=\"onPaste($event)\"\n autocomplete=\"one-time-code\"\n class=\"otp-input\"\n [ngClass]=\"inputClass\"\n [attr.aria-label]=\"'C\u00F3digo ' + (i + 1)\"\n />\n</div>\n", styles: [".otp-container{display:flex;gap:.5rem;justify-content:center;align-items:center}.otp-container input::-webkit-outer-spin-button,.otp-container input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.otp-container input[type=number]{-moz-appearance:textfield}.otp-container .otp-input{width:3rem;height:3rem;text-align:center;font-size:1.5rem;border:1px solid #ccc;border-radius:4px}.otp-container .otp-input:focus{border-color:#007bff;outline:none}\n"], dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxOtpCodeComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-otp-code', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxOtpCodeComponent), multi: true } ], standalone: true, imports: [NgFor, NgClass], template: "<div class=\"otp-container\" [ngClass]=\"config?.containerClass\">\n <input\n *ngFor=\"let item of [].constructor(length); let i = index\"\n #otpInput\n [type]=\"config?.mask ? 'password' : config?.inputType || 'text'\"\n [attr.placeholder]=\"config?.placeholder\"\n maxlength=\"1\"\n (keydown)=\"onKey($event, i)\"\n (paste)=\"onPaste($event)\"\n autocomplete=\"one-time-code\"\n class=\"otp-input\"\n [ngClass]=\"inputClass\"\n [attr.aria-label]=\"'C\u00F3digo ' + (i + 1)\"\n />\n</div>\n", styles: [".otp-container{display:flex;gap:.5rem;justify-content:center;align-items:center}.otp-container input::-webkit-outer-spin-button,.otp-container input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.otp-container input[type=number]{-moz-appearance:textfield}.otp-container .otp-input{width:3rem;height:3rem;text-align:center;font-size:1.5rem;border:1px solid #ccc;border-radius:4px}.otp-container .otp-input:focus{border-color:#007bff;outline:none}\n"] }] }], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { config: [{ type: Input }], codeFilled: [{ type: Output }], error: [{ type: Output }], otpInputs: [{ type: ViewChildren, args: ['otpInput'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW90cC1jb2RlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1vdHAvc3JjL2xpYi9uZ3gtb3RwLWNvZGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW90cC9zcmMvbGliL25neC1vdHAtY29kZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBaUIsU0FBUyxFQUFjLFlBQVksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBd0IsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xKLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFpQnpFLE1BQU0sT0FBTyxtQkFBbUI7SUFlOUIsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLElBQUksTUFBTSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUM7SUFDdkMsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDTixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQztJQUNuQyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7SUFDeEMsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDO0lBQ3RDLENBQUM7SUFFRCxZQUFvQixRQUFtQjtRQUFuQixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBOUM5QixXQUFNLEdBQWlCLEVBQUUsQ0FBQztRQUV6QixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUN4QyxVQUFLLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUk3QyxlQUFVLEdBQWEsRUFBRSxDQUFDO1FBQzFCLFVBQUssR0FBVyxFQUFFLENBQUM7UUFDbkIsYUFBUSxHQUFHLE1BQU0sQ0FBQztRQUVWLGFBQVEsR0FBUSxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDekIsY0FBUyxHQUFRLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQWtDUSxDQUFDO0lBRTNDLGVBQWU7UUFDYixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksZUFBZSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ2hELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNwQixDQUFDO0lBQ0gsQ0FBQztJQUVELFVBQVU7UUFDUixNQUFNLEVBQUUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ2hDLFNBQWlCLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQztZQUNqQyxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMzQixNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU07U0FDbEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO1lBQ25CLElBQUksR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUNkLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFPLEVBQUUsRUFBRTtZQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFvQixFQUFFLEtBQWE7UUFDdkMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQTBCLENBQUM7UUFDL0MsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQztRQUV0QixJQUFJLEdBQUcsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM1QixLQUFLLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNqQixJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDZCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztZQUM3QixDQUFDO1lBQ0QsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ25CLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixPQUFPO1FBQ1QsQ0FBQztRQUVELG1DQUFtQztRQUNuQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckIscUNBQXFDO1lBQ3JDLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQy9DLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsT0FBTztZQUNULENBQUM7WUFFRCxlQUFlO1lBQ2YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUM7WUFDN0IsS0FBSyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7WUFFbEIsaUNBQWlDO1lBQ2pDLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzVCLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzdCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyw4QkFBOEI7WUFDOUMsQ0FBQztZQUVELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNuQixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekIsQ0FBQzthQUFNLENBQUM7WUFDTixtQ0FBbUM7WUFDbkMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBR0QsT0FBTyxDQUFDLEtBQXFCO1FBQzNCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFMUQsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDckQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsdUNBQXVDLENBQUMsQ0FBQztZQUN6RCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsa0RBQWtELElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2xGLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRU8sV0FBVyxDQUFDLEtBQWE7UUFDL0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ2pDLEdBQUcsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxVQUFVLENBQUMsS0FBYTtRQUM5QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ1AsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6QixFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0lBRU8sV0FBVztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFVO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDakMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDckQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxFQUFPO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxFQUFPO1FBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ3RCLENBQUM7K0dBbExVLG1CQUFtQjttR0FBbkIsbUJBQW1CLGdKQVZuQjtZQUNUO2dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsbUJBQW1CLENBQUM7Z0JBQ2xELEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRixvSENmSCxnaEJBZUEsdWdCREVZLEtBQUssbUhBQUMsT0FBTzs7NEZBRVosbUJBQW1CO2tCQWQvQixTQUFTOytCQUNFLGNBQWMsYUFHYjt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxvQkFBb0IsQ0FBQzs0QkFDbEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0YsY0FDVyxJQUFJLFdBQ1AsQ0FBQyxLQUFLLEVBQUMsT0FBTyxDQUFDOzhFQUdmLE1BQU07c0JBQWQsS0FBSztnQkFFSSxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLEtBQUs7c0JBQWQsTUFBTTtnQkFFbUIsU0FBUztzQkFBbEMsWUFBWTt1QkFBQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdDbGFzcywgTmdGb3IgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIGZvcndhcmRSZWYsIElucHV0LCBPdXRwdXQsIFF1ZXJ5TGlzdCwgUmVuZGVyZXIyLCBWaWV3Q2hpbGRyZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE5neE90cENvbmZpZyB9IGZyb20gJy4vbmd4LW90cC1jb2RlLmludGVyZmFjZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1vdHAtY29kZScsXG4gIHRlbXBsYXRlVXJsOicuL25neC1vdHAtY29kZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9uZ3gtb3RwLWNvZGUuY29tcG9uZW50LnNjc3MnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neE90cENvZGVDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9XG4gIF0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtOZ0ZvcixOZ0NsYXNzXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hPdHBDb2RlQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBjb25maWc6IE5neE90cENvbmZpZyA9IHt9O1xuXG4gIEBPdXRwdXQoKSBjb2RlRmlsbGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSBlcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIEBWaWV3Q2hpbGRyZW4oJ290cElucHV0Jykgb3RwSW5wdXRzITogUXVlcnlMaXN0PEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD4+O1xuXG4gIGFycmF5VmFsdWU6IHN0cmluZ1tdID0gW107XG4gIHZhbHVlOiBzdHJpbmcgPSAnJztcbiAgbmFtZUl0ZW0gPSAnb3RwLSc7XG4gIFxuICBwcml2YXRlIG9uQ2hhbmdlOiBhbnkgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6IGFueSA9ICgpID0+IHt9O1xuXG4gIGdldCBsZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcubGVuZ3RoID8/IDY7XG4gIH1cblxuICBnZXQgaW5wdXRUeXBlKCk6ICd0ZXh0JyB8ICdudW1iZXInIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuaW5wdXRUeXBlID8/ICd0ZXh0JztcbiAgfVxuXG4gIGdldCBwbGFjZWhvbGRlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5wbGFjZWhvbGRlciA/PyAnJztcbiAgfVxuXG4gIGdldCBhdXRvRm9jdXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmF1dG9Gb2N1cyA/PyB0cnVlO1xuICB9XG5cbiAgZ2V0IGlzQWxwaGEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmlzQWxwaGEgPz8gZmFsc2U7XG4gIH1cblxuICBnZXQgbWFzaygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcubWFzayA/PyBmYWxzZTtcbiAgfVxuXG4gIGdldCB1c2VXZWJPdHAoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnVzZVdlYk90cCA/PyBmYWxzZTtcbiAgfVxuXG4gIGdldCBpbnB1dENsYXNzKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmlucHV0Q2xhc3MgPz8gJyc7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmF1dG9Gb2N1cykge1xuICAgICAgdGhpcy5mb2N1c0lucHV0KDApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnVzZVdlYk90cCAmJiAnT1RQQ3JlZGVudGlhbCcgaW4gd2luZG93KSB7XG4gICAgICB0aGlzLmluaXRXZWJPdHAoKTtcbiAgICB9XG4gIH1cblxuICBpbml0V2ViT3RwKCkge1xuICAgIGNvbnN0IGFjID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgIChuYXZpZ2F0b3IgYXMgYW55KS5jcmVkZW50aWFscy5nZXQoe1xuICAgICAgb3RwOiB7IHRyYW5zcG9ydDogWydzbXMnXSB9LFxuICAgICAgc2lnbmFsOiBhYy5zaWduYWxcbiAgICB9KS50aGVuKChvdHA6IGFueSkgPT4ge1xuICAgICAgaWYgKG90cD8uY29kZSkge1xuICAgICAgICB0aGlzLnNldE90cFZhbHVlKG90cC5jb2RlKTtcbiAgICAgIH1cbiAgICB9KS5jYXRjaCgoZXJyOmFueSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICB9KTtcbiAgfVxuXG4gIG9uS2V5KGV2ZW50OiBLZXlib2FyZEV2ZW50LCBpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCBrZXkgPSBldmVudC5rZXk7XG4gIFxuICAgIGlmIChrZXkgPT09ICdCYWNrc3BhY2UnKSB7XG4gICAgICB0aGlzLmFycmF5VmFsdWVbaW5kZXhdID0gJyc7XG4gICAgICBpbnB1dC52YWx1ZSA9ICcnO1xuICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICB0aGlzLmZvY3VzSW5wdXQoaW5kZXggLSAxKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlVmFsdWUoKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICBcbiAgICAvLyBBbGxvdyBvbmx5IGEgc2luZ2xlIGNoYXIgcGVyIGJveFxuICAgIGlmIChrZXkubGVuZ3RoID09PSAxKSB7XG4gICAgICAvLyBDaGVjayB2YWxpZGl0eSBiYXNlZCBvbiBpbnB1dCB0eXBlXG4gICAgICBpZiAodGhpcy5pbnB1dFR5cGUgPT09ICdudW1iZXInICYmICEvXlxcZCQvLnRlc3Qoa2V5KSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gIFxuICAgICAgaWYgKHRoaXMuaXNBbHBoYSAmJiAhL15bQS1aYS16MC05XSQvLnRlc3Qoa2V5KSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gIFxuICAgICAgLy8gQXNzaWduIHZhbHVlXG4gICAgICB0aGlzLmFycmF5VmFsdWVbaW5kZXhdID0ga2V5O1xuICAgICAgaW5wdXQudmFsdWUgPSBrZXk7XG4gIFxuICAgICAgLy8gTW92ZSB0byBuZXh0IGlucHV0IGlmIG5vdCBsYXN0XG4gICAgICBpZiAoaW5kZXggPCB0aGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy5mb2N1c0lucHV0KGluZGV4ICsgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnB1dC5ibHVyKCk7IC8vIE9wdGlvbmFsbHkgYmx1ciBpZiBmaW5pc2hlZFxuICAgICAgfVxuICBcbiAgICAgIHRoaXMudXBkYXRlVmFsdWUoKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElnbm9yZSBvdGhlciBrZXlzIChhcnJvd3MsIGV0Yy4pXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuICBcblxuICBvblBhc3RlKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgcGFzdGVkID0gZXZlbnQuY2xpcGJvYXJkRGF0YT8uZ2V0RGF0YSgndGV4dCcpIHx8ICcnO1xuXG4gICAgaWYgKHRoaXMuaW5wdXRUeXBlID09PSAnbnVtYmVyJyAmJiAvXFxELy50ZXN0KHBhc3RlZCkpIHtcbiAgICAgIHRoaXMuZXJyb3IuZW1pdCgnRWwgY8OzZGlnbyBzb2xvIGRlYmUgY29udGVuZXIgbsO6bWVyb3MuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHBhc3RlZC5sZW5ndGggPCB0aGlzLmxlbmd0aCkge1xuICAgICAgdGhpcy5lcnJvci5lbWl0KGBMYSBjYW50aWRhZCBkZSBjYXJhY3RlcmVzIG5vIHB1ZWRlIHNlciBtZW5vciBhICR7dGhpcy5sZW5ndGh9LmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0T3RwVmFsdWUocGFzdGVkKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0T3RwVmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuYXJyYXlWYWx1ZSA9IHZhbHVlLnNwbGl0KCcnKS5zbGljZSgwLCB0aGlzLmxlbmd0aCk7XG4gICAgdGhpcy5vdHBJbnB1dHM/LmZvckVhY2goKHJlZiwgaSkgPT4ge1xuICAgICAgcmVmLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSB0aGlzLmFycmF5VmFsdWVbaV0gfHwgJyc7XG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVWYWx1ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb2N1c0lucHV0KGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBlbCA9IHRoaXMub3RwSW5wdXRzPy5nZXQoaW5kZXgpO1xuICAgIGlmIChlbCkge1xuICAgICAgZWwubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgZWwubmF0aXZlRWxlbWVudC5zZWxlY3QoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVZhbHVlKCkge1xuICAgIHRoaXMudmFsdWUgPSB0aGlzLmFycmF5VmFsdWUuam9pbignJyk7XG4gICAgdGhpcy5vbkNoYW5nZSh0aGlzLnZhbHVlKTtcbiAgICBpZiAodGhpcy52YWx1ZS5sZW5ndGggPT09IHRoaXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmNvZGVGaWxsZWQuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgdGhpcy5hcnJheVZhbHVlID0gdGhpcy52YWx1ZS5zcGxpdCgnJyk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLm90cElucHV0cz8uZm9yRWFjaCgocmVmLCBpKSA9PiB7XG4gICAgICAgIHJlZi5uYXRpdmVFbGVtZW50LnZhbHVlID0gdGhpcy5hcnJheVZhbHVlW2ldIHx8ICcnO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm90cC1jb250YWluZXJcIiBbbmdDbGFzc109XCJjb25maWc/LmNvbnRhaW5lckNsYXNzXCI+XG4gIDxpbnB1dFxuICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIFtdLmNvbnN0cnVjdG9yKGxlbmd0aCk7IGxldCBpID0gaW5kZXhcIlxuICAgICNvdHBJbnB1dFxuICAgIFt0eXBlXT1cImNvbmZpZz8ubWFzayA/ICdwYXNzd29yZCcgOiBjb25maWc/LmlucHV0VHlwZSB8fCAndGV4dCdcIlxuICAgIFthdHRyLnBsYWNlaG9sZGVyXT1cImNvbmZpZz8ucGxhY2Vob2xkZXJcIlxuICAgIG1heGxlbmd0aD1cIjFcIlxuICAgIChrZXlkb3duKT1cIm9uS2V5KCRldmVudCwgaSlcIlxuICAgIChwYXN0ZSk9XCJvblBhc3RlKCRldmVudClcIlxuICAgIGF1dG9jb21wbGV0ZT1cIm9uZS10aW1lLWNvZGVcIlxuICAgIGNsYXNzPVwib3RwLWlucHV0XCJcbiAgICBbbmdDbGFzc109XCJpbnB1dENsYXNzXCJcbiAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidDw7NkaWdvICcgKyAoaSArIDEpXCJcbiAgLz5cbjwvZGl2PlxuIl19