UNPKG

@true-directive/grid

Version:

Angular Data Grid from Yopsilon.

365 lines 48.1 kB
import * as tslib_1 from "tslib"; var MaskNumberDirective_1; /** * Copyright (c) 2018-2019 Aleksey Melnikov, True Directive Company. * @link https://truedirective.com/ * @license MIT */ import { Directive, ElementRef, Input, Output, HostListener, EventEmitter, Renderer2, forwardRef } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { InternationalizationService } from '../internationalization/internationalization.service'; import { Keys, KeyInfo } from '@true-directive/base'; import { MaskState } from '@true-directive/base'; import { MaskSectionAction, MaskResult } from '@true-directive/base'; import { NumberParserFormatter } from '@true-directive/base'; let MaskNumberDirective = MaskNumberDirective_1 = class MaskNumberDirective { constructor(_renderer, _elementRef, intl) { this._renderer = _renderer; this._elementRef = _elementRef; this.intl = intl; this.onChange = (_) => { }; this.onTouched = () => { }; this._undo = []; this._redo = []; // Текущее числовое значение this._numValue = null; // Текущее текстовое значение this._txtValue = ''; // Смена состояния this.stateChange = new EventEmitter(); // Состояние директивы this._state = null; this._separators = ['.', ',']; this._format = '{1.2}'; this.android_behavior = false; // Format change can follow locale change this._localeSubscription = this.intl.onLocaleChanged.subscribe(locale => this.setLocale(locale)); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } blur() { // Очищаем, если формат неверен let value = NumberParserFormatter.parse(this._txtValue, this.format, this._separators); if (value === null || isNaN(value)) { this.setText(''); } else { this.setText(NumberParserFormatter.format(value, this.format, this._separators)); } this.onTouched(); } get state() { return this._state; } set state(v) { if (this._state !== v) { this._state = v; this.stateChange.emit(this._state); // Излучаем событие } } // Обновляем состояние updateState() { if (this._numValue === null) { this.state = MaskState.EMPTY; // Пустое значение } else { if (isNaN(this._numValue)) { this.state = MaskState.TYPING; // Считаем, что пользователь не завершил ввод } else { this.state = MaskState.OK; } } } // Sending a value to model toModel() { // Retrieving value if (this._txtValue === '') { this._numValue = null; } else { this._numValue = NumberParserFormatter.parse(this._txtValue, this.format, this._separators); } // Sending to model this.onChange(this._numValue); // Updating the state this.updateState(); } processAndroid(txt) { // let res = this.currentRes(); // Теоретически положение курсора у нас есть.. let key = Keys.whichKeyHasBeenPressed(this.last_res.newValue, txt, this.last_res.selStart, res.selStart, this.last_res.selLength); let selStart = this.last_res.selStart; let selEnd = this.last_res.selStart; // Если текст вдруг стёрся if (this.last_res.newValue !== '' && txt.length <= 1) { if (txt === '') { key = new KeyInfo(Keys.DELETE); } else { key = new KeyInfo(0, txt); } selStart = 0; selEnd = this.last_res.newValue.length; } let r = this.processKey({ keyCode: -1, key: key.code, char: key.char, shiftKey: false, ctrlKey: false, target: { selectionStart: selStart, selectionEnd: selEnd }, preventDefault: (_) => { } }); if (!r) { this.setRes(this.last_res); // Не приняли, вернули всё назад } // Зачем это здесь?.. А вдруг.. this.android_behavior = false; return; } // Пользователь вносит значение. Parser: View --> Ctrl input(txt) { if (this.android_behavior) { this.processAndroid(txt); return; } // Поэтому пытаемся применить формат к введенному значению. let value = NumberParserFormatter.parse(txt, this.format, this._separators); if (value === null) { this.setText(''); } else { if (!isNaN(value)) { this.setText(NumberParserFormatter.format(value, this.format, this._separators), true); } } } // Formatter: Ctrl --> View writeValue(value) { this._numValue = value; let txt = ''; if (value !== null) { txt = NumberParserFormatter.format(value, this.format, this._separators); } if (txt !== this._txtValue) { this.setText(txt, false); } // No need to send to model, because this processor is called on model change // but state still needs to be updated this.updateState(); } set format(f) { if (this._txtValue !== '' && this._format !== f) { // По сложному пути let res = this.currentRes(); this._format = f; let state = NumberParserFormatter.reformat(this._txtValue, this.format, this._separators, res.selStart, res.selStart + res.selLength, true // Convert to format ); this.setRes(this.getRes(state.value, state.selStart, state.selEnd)); } else { this._format = f; } } get format() { if (this._format === 'currency') { return this.intl.locale.currency; } return this._format; } keyDown(e) { return this.processKey(e); } processKey(e) { if (e.keyCode === 229 || e.keyCode === 0 || e.keyCode === undefined) { // test: if (e.keyCode >= 0) ... // Android detected this.android_behavior = true; this.last_res = this.currentRes(); return; } const c = Keys.keyChar(e); let selStart = e.target.selectionStart; let selEnd = e.target.selectionEnd; let s = this._txtValue; const state0 = this.getRes(s, selStart, selEnd); if (Keys.isFunctional(e.keyCode)) { return true; } if (e.keyCode === Keys.TAB || e.keyCode === Keys.ESCAPE) { return true; } if (e.keyCode === Keys.HOME || e.keyCode === Keys.END) { return true; } if (e.shiftKey && (e.keyCode === Keys.DELETE || e.keyCode === Keys.INSERT)) { return true; } if (e.ctrlKey && e.keyCode === Keys.Z) { // UNDO let undoRes = this._undo.pop(); if (undoRes) { this._redo.push(this.getRes(s, selStart, selEnd)); this.setRes(undoRes); } e.preventDefault(); return false; } if (e.ctrlKey && e.keyCode === Keys.Y) { // REDO let redoRes = this._redo.pop(); if (redoRes) { this._undo.push(this.getRes(s, selStart, selEnd)); this.setRes(redoRes); } e.preventDefault(); return false; } if (e.ctrlKey) { return true; } if (selStart === 0 && selEnd === this._txtValue.length) { s = ''; selStart = 0; selEnd = 0; } let leadToFormat = false; let applied = false; if (e.keyCode === Keys.BACKSPACE || e.keyCode === Keys.DELETE) { let canAccept = NumberParserFormatter.canAcceptKey(s, e.keyCode, c, this.format, this._separators, selStart, selEnd); if (selStart === selEnd) { // Ничего не выделено if (e.keyCode === Keys.BACKSPACE && selStart > 0) { if (canAccept) s = s.substring(0, selStart - 1) + s.substring(selEnd); selStart--; selEnd--; } if (e.keyCode === Keys.DELETE) { if (canAccept) s = s.substring(0, selStart) + s.substring(selEnd + 1); else { selStart++; selEnd++; } } applied = true; } if (selStart < selEnd) { // Выделено один или более символов let fragmentToDelete = s.substring(selStart, selEnd); if (canAccept) { if (fragmentToDelete.indexOf(this._separators[0]) >= 0) { s = s.substring(0, selStart) + this._separators[0] + s.substring(selEnd); } else { s = s.substring(0, selStart) + s.substring(selEnd); } } selEnd = selStart; applied = true; } } if (c.length === 1) { s = s.substring(0, selStart) + s.substring(selEnd); if (NumberParserFormatter.canAcceptKey(s, e.keyCode, c, this.format, this._separators, selStart)) { s = s.substring(0, selStart) + c + s.substring(selStart); selStart++; selEnd = selStart; applied = true; } else { e.preventDefault(); return false; } } if (applied) { // При изменении значения внесем в стэк undo if (s !== state0.newValue) { this._undo.push(state0); this._redo = []; } const state3 = NumberParserFormatter.reformat(s, this.format, this._separators, selStart, selEnd, leadToFormat); this.setRes(this.getRes(state3.value, state3.selStart, state3.selEnd)); if (this.android_behavior) { return true; } e.preventDefault(); return false; } return true; } // Установить значение и положение курсора setRes(res) { if (this.android_behavior) res.selLength = 0; this.setText(res.newValue); this._renderer.setProperty(this._elementRef.nativeElement, 'selectionStart', res.selStart); this._renderer.setProperty(this._elementRef.nativeElement, 'selectionEnd', res.selStart + res.selLength); } currentRes() { let res = new MaskResult(this._txtValue, MaskSectionAction.APPLY, 0); res.selStart = this._elementRef.nativeElement.selectionStart; res.selLength = this._elementRef.nativeElement.selectionEnd - res.selStart; return res; } // Получить текущее значение маски и положение курсора getRes(s, selStart, selEnd) { let res = new MaskResult(s, MaskSectionAction.APPLY, 0); res.selStart = selStart; res.selLength = selEnd - selStart; return res; } // Записывает текст в контрол setText(displayedValue, toModel = true) { // Отображаем this._txtValue = displayedValue; this._renderer.setProperty(this._elementRef.nativeElement, 'value', this._txtValue); // Отправляем в модель if (toModel) { this.toModel(); } } setLocale(locale) { this._separators[0] = locale.separators[0]; this._separators[1] = locale.separators[1]; // Updating view this.writeValue(this._numValue); } ngOnDestroy() { // Unsubscribing this._localeSubscription.unsubscribe(); } }; tslib_1.__decorate([ Output('ynStateChange'), tslib_1.__metadata("design:type", Object) ], MaskNumberDirective.prototype, "stateChange", void 0); tslib_1.__decorate([ Input('true-mask-number'), tslib_1.__metadata("design:type", String), tslib_1.__metadata("design:paramtypes", [String]) ], MaskNumberDirective.prototype, "format", null); tslib_1.__decorate([ HostListener('keydown', ['$event']), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", void 0) ], MaskNumberDirective.prototype, "keyDown", null); MaskNumberDirective = MaskNumberDirective_1 = tslib_1.__decorate([ Directive({ selector: '[true-mask-number]', host: { '(input)': 'input($event.target.value)', '(blur)': 'blur()' }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MaskNumberDirective_1), multi: true }] }), tslib_1.__metadata("design:paramtypes", [Renderer2, ElementRef, InternationalizationService]) ], MaskNumberDirective); export { MaskNumberDirective }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzay1udW1iZXIuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHRydWUtZGlyZWN0aXZlL2dyaWQvIiwic291cmNlcyI6WyJzcmMvbWFzay9tYXNrLW51bWJlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7OztFQUlFO0FBQ0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEgsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHNEQUFzRCxDQUFDO0FBRW5HLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVyRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQVk3RCxJQUFhLG1CQUFtQiwyQkFBaEMsTUFBYSxtQkFBbUI7SUEwWTlCLFlBQXNCLFNBQW9CLEVBQzVCLFdBQXVCLEVBQ3ZCLElBQWlDO1FBRnpCLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsU0FBSSxHQUFKLElBQUksQ0FBNkI7UUF4WXZDLGFBQVEsR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBQzFCLGNBQVMsR0FBRyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFnQnJCLFVBQUssR0FBc0IsRUFBRSxDQUFDO1FBQzlCLFVBQUssR0FBc0IsRUFBRSxDQUFDO1FBRXRDLDRCQUE0QjtRQUNwQixj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LEVBQUMsU0FBUyxFQUFFLDRCQUE0QixFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUM7UUFDbkUsU0FBUyxFQUFFLENBQUM7Z0JBQ1IsT0FBTyxFQUFFLGlCQUFpQjtnQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBbUIsQ0FBQztnQkFDbEQsS0FBSyxFQUFFLElBQUk7YUFDWixDQUFDO0tBQ1AsQ0FBQzs2Q0EyWWlDLFNBQVM7UUFDZixVQUFVO1FBQ2pCLDJCQUEyQjtHQTVZcEMsbUJBQW1CLENBZ1ovQjtTQWhaWSxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgQWxla3NleSBNZWxuaWtvdiwgVHJ1ZSBEaXJlY3RpdmUgQ29tcGFueS5cclxuICogQGxpbmsgaHR0cHM6Ly90cnVlZGlyZWN0aXZlLmNvbS9cclxuICogQGxpY2Vuc2UgTUlUXHJcbiovXHJcbmltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQsIE91dHB1dCwgSG9zdExpc3RlbmVyLCBFdmVudEVtaXR0ZXIsIFJlbmRlcmVyMiwgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5pbXBvcnQgeyBJbnRlcm5hdGlvbmFsaXphdGlvblNlcnZpY2UgfSBmcm9tICcuLi9pbnRlcm5hdGlvbmFsaXphdGlvbi9pbnRlcm5hdGlvbmFsaXphdGlvbi5zZXJ2aWNlJztcclxuXHJcbmltcG9ydCB7IEtleXMsIEtleUluZm8gfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcblxyXG5pbXBvcnQgeyBNYXNrU3RhdGUgfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcbmltcG9ydCB7IE1hc2tTZXR0aW5ncyB9IGZyb20gJ0B0cnVlLWRpcmVjdGl2ZS9iYXNlJztcclxuaW1wb3J0IHsgTWFza1NlY3Rpb25BY3Rpb24sIE1hc2tSZXN1bHQgfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcblxyXG5pbXBvcnQgeyBOdW1iZXJQYXJzZXJGb3JtYXR0ZXIgfSBmcm9tICdAdHJ1ZS1kaXJlY3RpdmUvYmFzZSc7XHJcbmltcG9ydCB7IExvY2FsZSB9IGZyb20gJ0B0cnVlLWRpcmVjdGl2ZS9iYXNlJztcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gICAgc2VsZWN0b3I6ICdbdHJ1ZS1tYXNrLW51bWJlcl0nLFxyXG4gICAgaG9zdDogeycoaW5wdXQpJzogJ2lucHV0KCRldmVudC50YXJnZXQudmFsdWUpJywgJyhibHVyKSc6ICdibHVyKCknfSxcclxuICAgIHByb3ZpZGVyczogW3tcclxuICAgICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBNYXNrTnVtYmVyRGlyZWN0aXZlKSxcclxuICAgICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgICB9XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTWFza051bWJlckRpcmVjdGl2ZSB7XHJcblxyXG4gIF9sb2NhbGVTdWJzY3JpcHRpb246IGFueTtcclxuXHJcbiAgcHJpdmF0ZSBvbkNoYW5nZSA9IChfOiBhbnkpID0+IHt9O1xyXG4gIHByaXZhdGUgb25Ub3VjaGVkID0gKCkgPT4ge307XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IChfOiBhbnkpID0+IHZvaWQpOiB2b2lkIHsgdGhpcy5vbkNoYW5nZSA9IGZuOyB9XHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHsgdGhpcy5vblRvdWNoZWQgPSBmbjsgfVxyXG5cclxuICBibHVyKCkge1xyXG4gICAgLy8g0J7Rh9C40YnQsNC10LwsINC10YHQu9C4INGE0L7RgNC80LDRgiDQvdC10LLQtdGA0LXQvVxyXG4gICAgbGV0IHZhbHVlID0gTnVtYmVyUGFyc2VyRm9ybWF0dGVyLnBhcnNlKHRoaXMuX3R4dFZhbHVlLCB0aGlzLmZvcm1hdCwgdGhpcy5fc2VwYXJhdG9ycyk7XHJcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgaXNOYU4odmFsdWUpKSB7XHJcbiAgICAgIHRoaXMuc2V0VGV4dCgnJyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNldFRleHQoTnVtYmVyUGFyc2VyRm9ybWF0dGVyLmZvcm1hdCh2YWx1ZSwgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMpKTtcclxuICAgIH1cclxuICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF91bmRvOiBBcnJheTxNYXNrUmVzdWx0PiA9IFtdO1xyXG4gIHByaXZhdGUgX3JlZG86IEFycmF5PE1hc2tSZXN1bHQ+ID0gW107XHJcblxyXG4gIC8vINCi0LXQutGD0YnQtdC1INGH0LjRgdC70L7QstC+0LUg0LfQvdCw0YfQtdC90LjQtVxyXG4gIHByaXZhdGUgX251bVZhbHVlOiBudW1iZXIgPSBudWxsO1xyXG5cclxuICAvLyDQotC10LrRg9GJ0LXQtSDRgtC10LrRgdGC0L7QstC+0LUg0LfQvdCw0YfQtdC90LjQtVxyXG4gIHByb3RlY3RlZCBfdHh0VmFsdWU6IHN0cmluZyA9ICcnO1xyXG5cclxuICAvLyDQodC80LXQvdCwINGB0L7RgdGC0L7Rj9C90LjRj1xyXG4gIEBPdXRwdXQoJ3luU3RhdGVDaGFuZ2UnKVxyXG4gIHN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxNYXNrU3RhdGU+KCk7XHJcblxyXG4gIC8vINCh0L7RgdGC0L7Rj9C90LjQtSDQtNC40YDQtdC60YLQuNCy0YtcclxuICBwcml2YXRlIF9zdGF0ZTogTWFza1N0YXRlID0gbnVsbDtcclxuXHJcbiAgcHVibGljIGdldCBzdGF0ZSgpOiBNYXNrU3RhdGUge1xyXG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldCBzdGF0ZSh2OiBNYXNrU3RhdGUpIHtcclxuICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gdikge1xyXG4gICAgICB0aGlzLl9zdGF0ZSA9IHY7XHJcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2UuZW1pdCh0aGlzLl9zdGF0ZSk7IC8vINCY0LfQu9GD0YfQsNC10Lwg0YHQvtCx0YvRgtC40LVcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vINCe0LHQvdC+0LLQu9GP0LXQvCDRgdC+0YHRgtC+0Y/QvdC40LVcclxuICBwcm90ZWN0ZWQgdXBkYXRlU3RhdGUoKSB7XHJcbiAgICBpZiAodGhpcy5fbnVtVmFsdWUgPT09IG51bGwpIHtcclxuICAgICAgdGhpcy5zdGF0ZSA9IE1hc2tTdGF0ZS5FTVBUWTsgICAgICAgICAgIC8vINCf0YPRgdGC0L7QtSDQt9C90LDRh9C10L3QuNC1XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoaXNOYU4odGhpcy5fbnVtVmFsdWUpKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IE1hc2tTdGF0ZS5UWVBJTkc7ICAgICAgIC8vINCh0YfQuNGC0LDQtdC8LCDRh9GC0L4g0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GMINC90LUg0LfQsNCy0LXRgNGI0LjQuyDQstCy0L7QtFxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBNYXNrU3RhdGUuT0s7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFNlbmRpbmcgYSB2YWx1ZSB0byBtb2RlbFxyXG4gIHByb3RlY3RlZCB0b01vZGVsKCkge1xyXG4gICAgLy8gUmV0cmlldmluZyB2YWx1ZVxyXG4gICAgaWYgKHRoaXMuX3R4dFZhbHVlID09PSAnJykge1xyXG4gICAgICB0aGlzLl9udW1WYWx1ZSA9IG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9udW1WYWx1ZSA9IE51bWJlclBhcnNlckZvcm1hdHRlci5wYXJzZSh0aGlzLl90eHRWYWx1ZSwgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNlbmRpbmcgdG8gbW9kZWxcclxuICAgIHRoaXMub25DaGFuZ2UodGhpcy5fbnVtVmFsdWUpO1xyXG4gICAgLy8gVXBkYXRpbmcgdGhlIHN0YXRlXHJcbiAgICB0aGlzLnVwZGF0ZVN0YXRlKCk7XHJcbiAgfVxyXG5cclxuICBwcm9jZXNzQW5kcm9pZCh0eHQ6IGFueSkge1xyXG4gICAgLy9cclxuICAgIGxldCByZXMgPSB0aGlzLmN1cnJlbnRSZXMoKTtcclxuXHJcbiAgICAvLyDQotC10L7RgNC10YLQuNGH0LXRgdC60Lgg0L/QvtC70L7QttC10L3QuNC1INC60YPRgNGB0L7RgNCwINGDINC90LDRgSDQtdGB0YLRjC4uXHJcbiAgICBsZXQga2V5OiBLZXlJbmZvID0gS2V5cy53aGljaEtleUhhc0JlZW5QcmVzc2VkKHRoaXMubGFzdF9yZXMubmV3VmFsdWUsIHR4dCxcclxuICAgICAgICB0aGlzLmxhc3RfcmVzLnNlbFN0YXJ0LCByZXMuc2VsU3RhcnQsIHRoaXMubGFzdF9yZXMuc2VsTGVuZ3RoKTtcclxuXHJcbiAgICBsZXQgc2VsU3RhcnQgPSB0aGlzLmxhc3RfcmVzLnNlbFN0YXJ0O1xyXG4gICAgbGV0IHNlbEVuZCA9IHRoaXMubGFzdF9yZXMuc2VsU3RhcnQ7XHJcblxyXG4gICAgLy8g0JXRgdC70Lgg0YLQtdC60YHRgiDQstC00YDRg9CzINGB0YLRkdGA0YHRj1xyXG4gICAgaWYgKHRoaXMubGFzdF9yZXMubmV3VmFsdWUgIT09ICcnICYmIHR4dC5sZW5ndGggPD0gMSkge1xyXG5cclxuICAgICAgaWYgKHR4dCA9PT0gJycpIHtcclxuICAgICAgICBrZXkgPSBuZXcgS2V5SW5mbyhLZXlzLkRFTEVURSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAga2V5ID0gbmV3IEtleUluZm8oMCwgdHh0KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsU3RhcnQgPSAwO1xyXG4gICAgICBzZWxFbmQgPSB0aGlzLmxhc3RfcmVzLm5ld1ZhbHVlLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgciA9IHRoaXMucHJvY2Vzc0tleShcclxuICAgICAge1xyXG4gICAgICAgIGtleUNvZGU6IC0xLFxyXG4gICAgICAgIGtleToga2V5LmNvZGUsXHJcbiAgICAgICAgY2hhcjoga2V5LmNoYXIsXHJcbiAgICAgICAgc2hpZnRLZXk6IGZhbHNlLFxyXG4gICAgICAgIGN0cmxLZXk6IGZhbHNlLFxyXG4gICAgICAgIHRhcmdldDogeyBzZWxlY3Rpb25TdGFydDogc2VsU3RhcnQsIHNlbGVjdGlvbkVuZDogc2VsRW5kIH0sXHJcbiAgICAgICAgcHJldmVudERlZmF1bHQ6IChfOiBhbnkpID0+IHt9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIGlmICghcikge1xyXG4gICAgICB0aGlzLnNldFJlcyh0aGlzLmxhc3RfcmVzKTsgLy8g0J3QtSDQv9GA0LjQvdGP0LvQuCwg0LLQtdGA0L3Rg9C70Lgg0LLRgdGRINC90LDQt9Cw0LRcclxuICAgIH1cclxuXHJcbiAgICAvLyDQl9Cw0YfQtdC8INGN0YLQviDQt9C00LXRgdGMPy4uINCQINCy0LTRgNGD0LMuLlxyXG4gICAgdGhpcy5hbmRyb2lkX2JlaGF2aW9yID0gZmFsc2U7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyDQn9C+0LvRjNC30L7QstCw0YLQtdC70Ywg0LLQvdC+0YHQuNGCINC30L3QsNGH0LXQvdC40LUuIFBhcnNlcjogVmlldyAtLT4gQ3RybFxyXG4gIGlucHV0KHR4dDogYW55KSB7XHJcbiAgICBpZiAodGhpcy5hbmRyb2lkX2JlaGF2aW9yKSB7XHJcbiAgICAgIHRoaXMucHJvY2Vzc0FuZHJvaWQodHh0KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgLy8g0J/QvtGN0YLQvtC80YMg0L/Ri9GC0LDQtdC80YHRjyDQv9GA0LjQvNC10L3QuNGC0Ywg0YTQvtGA0LzQsNGCINC6INCy0LLQtdC00LXQvdC90L7QvNGDINC30L3QsNGH0LXQvdC40Y4uXHJcbiAgICBsZXQgdmFsdWUgPSBOdW1iZXJQYXJzZXJGb3JtYXR0ZXIucGFyc2UodHh0LCB0aGlzLmZvcm1hdCwgdGhpcy5fc2VwYXJhdG9ycyk7XHJcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcclxuICAgICAgdGhpcy5zZXRUZXh0KCcnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghaXNOYU4odmFsdWUpKSB7XHJcbiAgICAgICAgdGhpcy5zZXRUZXh0KE51bWJlclBhcnNlckZvcm1hdHRlci5mb3JtYXQodmFsdWUsIHRoaXMuZm9ybWF0LCB0aGlzLl9zZXBhcmF0b3JzKSwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIEZvcm1hdHRlcjogQ3RybCAtLT4gVmlld1xyXG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSkge1xyXG5cclxuICAgIHRoaXMuX251bVZhbHVlID0gdmFsdWU7XHJcbiAgICBsZXQgdHh0ID0gJyc7XHJcbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcclxuICAgICAgdHh0ID0gTnVtYmVyUGFyc2VyRm9ybWF0dGVyLmZvcm1hdCh2YWx1ZSwgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eHQgIT09IHRoaXMuX3R4dFZhbHVlKSB7XHJcbiAgICAgIHRoaXMuc2V0VGV4dCh0eHQsIGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBObyBuZWVkIHRvIHNlbmQgdG8gbW9kZWwsIGJlY2F1c2UgdGhpcyBwcm9jZXNzb3IgaXMgY2FsbGVkIG9uIG1vZGVsIGNoYW5nZVxyXG4gICAgLy8gYnV0IHN0YXRlIHN0aWxsIG5lZWRzIHRvIGJlIHVwZGF0ZWRcclxuICAgIHRoaXMudXBkYXRlU3RhdGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NlcGFyYXRvcnM6IEFycmF5PHN0cmluZz4gPSBbJy4nLCAnLCddO1xyXG4gIHByaXZhdGUgX2Zvcm1hdDogc3RyaW5nID0gJ3sxLjJ9JztcclxuXHJcbiAgQElucHV0KCd0cnVlLW1hc2stbnVtYmVyJylcclxuICBwdWJsaWMgc2V0IGZvcm1hdChmOiBzdHJpbmcpIHtcclxuXHJcbiAgICBpZiAodGhpcy5fdHh0VmFsdWUgIT09ICcnICYmIHRoaXMuX2Zvcm1hdCAhPT0gZikge1xyXG4gICAgICAvLyDQn9C+INGB0LvQvtC20L3QvtC80YMg0L/Rg9GC0LhcclxuICAgICAgbGV0IHJlcyA9IHRoaXMuY3VycmVudFJlcygpO1xyXG4gICAgICB0aGlzLl9mb3JtYXQgPSBmO1xyXG5cclxuICAgICAgbGV0IHN0YXRlID0gTnVtYmVyUGFyc2VyRm9ybWF0dGVyLnJlZm9ybWF0KHRoaXMuX3R4dFZhbHVlLFxyXG4gICAgICAgIHRoaXMuZm9ybWF0LCB0aGlzLl9zZXBhcmF0b3JzLFxyXG4gICAgICAgIHJlcy5zZWxTdGFydCwgcmVzLnNlbFN0YXJ0ICsgcmVzLnNlbExlbmd0aCxcclxuICAgICAgICB0cnVlIC8vIENvbnZlcnQgdG8gZm9ybWF0XHJcbiAgICAgICk7XHJcblxyXG4gICAgICB0aGlzLnNldFJlcyh0aGlzLmdldFJlcyhzdGF0ZS52YWx1ZSwgc3RhdGUuc2VsU3RhcnQsIHN0YXRlLnNlbEVuZCkpO1xyXG5cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2Zvcm1hdCA9IGY7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGZvcm1hdCgpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuX2Zvcm1hdCA9PT0gJ2N1cnJlbmN5Jykge1xyXG4gICAgICByZXR1cm4gdGhpcy5pbnRsLmxvY2FsZS5jdXJyZW5jeTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLl9mb3JtYXQ7XHJcbiAgfVxyXG5cclxuICBhbmRyb2lkX2JlaGF2aW9yOiBib29sZWFuID0gZmFsc2U7XHJcbiAgbGFzdF9yZXM6IE1hc2tSZXN1bHQ7XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24nLCBbJyRldmVudCddKVxyXG4gIGtleURvd24oZTogYW55KSB7XHJcbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzS2V5KGUpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHByb2Nlc3NLZXkoZTogYW55KTogYm9vbGVhbiB7XHJcblxyXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gMjI5IHx8IGUua2V5Q29kZSA9PT0gMCB8fCBlLmtleUNvZGUgPT09IHVuZGVmaW5lZCkgeyAvLyB0ZXN0OiBpZiAoZS5rZXlDb2RlID49IDApIC4uLlxyXG4gICAgICAvLyBBbmRyb2lkIGRldGVjdGVkXHJcbiAgICAgIHRoaXMuYW5kcm9pZF9iZWhhdmlvciA9IHRydWU7XHJcbiAgICAgIHRoaXMubGFzdF9yZXMgPSB0aGlzLmN1cnJlbnRSZXMoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGMgPSBLZXlzLmtleUNoYXIoZSk7XHJcblxyXG4gICAgbGV0IHNlbFN0YXJ0OiBudW1iZXIgPSBlLnRhcmdldC5zZWxlY3Rpb25TdGFydDtcclxuICAgIGxldCBzZWxFbmQ6IG51bWJlciA9IGUudGFyZ2V0LnNlbGVjdGlvbkVuZDtcclxuICAgIGxldCBzOiBzdHJpbmcgPSB0aGlzLl90eHRWYWx1ZTtcclxuXHJcbiAgICBjb25zdCBzdGF0ZTA6IGFueSA9IHRoaXMuZ2V0UmVzKHMsIHNlbFN0YXJ0LCBzZWxFbmQpO1xyXG5cclxuICAgIGlmIChLZXlzLmlzRnVuY3Rpb25hbChlLmtleUNvZGUpKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChlLmtleUNvZGUgPT09IEtleXMuVEFCIHx8IGUua2V5Q29kZSA9PT0gS2V5cy5FU0NBUEUpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5IT01FIHx8IGUua2V5Q29kZSA9PT0gS2V5cy5FTkQpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUuc2hpZnRLZXkgJiYgKGUua2V5Q29kZSA9PT0gS2V5cy5ERUxFVEUgfHwgZS5rZXlDb2RlID09PSBLZXlzLklOU0VSVCkpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUuY3RybEtleSAmJiBlLmtleUNvZGUgPT09IEtleXMuWikge1xyXG4gICAgICAvLyBVTkRPXHJcbiAgICAgIGxldCB1bmRvUmVzID0gdGhpcy5fdW5kby5wb3AoKTtcclxuICAgICAgaWYgKHVuZG9SZXMpIHtcclxuICAgICAgICB0aGlzLl9yZWRvLnB1c2godGhpcy5nZXRSZXMocywgc2VsU3RhcnQsIHNlbEVuZCkpO1xyXG4gICAgICAgIHRoaXMuc2V0UmVzKHVuZG9SZXMpO1xyXG4gICAgICB9XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChlLmN0cmxLZXkgJiYgZS5rZXlDb2RlID09PSBLZXlzLlkpIHtcclxuICAgICAgLy8gUkVET1xyXG4gICAgICBsZXQgcmVkb1JlcyA9IHRoaXMuX3JlZG8ucG9wKCk7XHJcbiAgICAgIGlmIChyZWRvUmVzKSB7XHJcbiAgICAgICAgdGhpcy5fdW5kby5wdXNoKHRoaXMuZ2V0UmVzKHMsIHNlbFN0YXJ0LCBzZWxFbmQpKTtcclxuICAgICAgICB0aGlzLnNldFJlcyhyZWRvUmVzKTtcclxuICAgICAgfVxyXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZS5jdHJsS2V5KSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzZWxTdGFydCA9PT0gMCAmJiBzZWxFbmQgPT09IHRoaXMuX3R4dFZhbHVlLmxlbmd0aCkge1xyXG4gICAgICBzID0gJyc7XHJcbiAgICAgIHNlbFN0YXJ0ID0gMDtcclxuICAgICAgc2VsRW5kID0gMDtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgbGVhZFRvRm9ybWF0ID0gZmFsc2U7XHJcbiAgICBsZXQgYXBwbGllZCA9IGZhbHNlO1xyXG5cclxuICAgIGlmIChlLmtleUNvZGUgPT09IEtleXMuQkFDS1NQQUNFIHx8IGUua2V5Q29kZSA9PT0gS2V5cy5ERUxFVEUpIHtcclxuXHJcbiAgICAgIGxldCBjYW5BY2NlcHQgPSBOdW1iZXJQYXJzZXJGb3JtYXR0ZXIuY2FuQWNjZXB0S2V5KHMsIGUua2V5Q29kZSwgYywgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMsIHNlbFN0YXJ0LCBzZWxFbmQpO1xyXG5cclxuICAgICAgaWYgKHNlbFN0YXJ0ID09PSBzZWxFbmQpIHtcclxuICAgICAgICAvLyDQndC40YfQtdCz0L4g0L3QtSDQstGL0LTQtdC70LXQvdC+XHJcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5CQUNLU1BBQ0UgJiYgc2VsU3RhcnQgPiAwKSB7XHJcbiAgICAgICAgICBpZiAoY2FuQWNjZXB0KVxyXG4gICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcoMCwgc2VsU3RhcnQgLSAxKSArIHMuc3Vic3RyaW5nKHNlbEVuZCk7XHJcblxyXG4gICAgICAgICAgc2VsU3RhcnQtLTtcclxuICAgICAgICAgIHNlbEVuZC0tO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5ERUxFVEUpIHtcclxuICAgICAgICAgIGlmIChjYW5BY2NlcHQpXHJcbiAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZygwLCBzZWxTdGFydCkgKyBzLnN1YnN0cmluZyhzZWxFbmQgKyAxKTtcclxuICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBzZWxTdGFydCsrO1xyXG4gICAgICAgICAgICBzZWxFbmQrKztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFwcGxpZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc2VsU3RhcnQgPCBzZWxFbmQpIHtcclxuICAgICAgICAvLyDQktGL0LTQtdC70LXQvdC+INC+0LTQuNC9INC40LvQuCDQsdC+0LvQtdC1INGB0LjQvNCy0L7Qu9C+0LJcclxuICAgICAgICBsZXQgZnJhZ21lbnRUb0RlbGV0ZSA9IHMuc3Vic3RyaW5nKHNlbFN0YXJ0LCBzZWxFbmQpO1xyXG5cclxuICAgICAgICBpZiAoY2FuQWNjZXB0KSB7XHJcbiAgICAgICAgICBpZiAoZnJhZ21lbnRUb0RlbGV0ZS5pbmRleE9mKHRoaXMuX3NlcGFyYXRvcnNbMF0pID49IDApIHtcclxuICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIHNlbFN0YXJ0KSArIHRoaXMuX3NlcGFyYXRvcnNbMF0gKyBzLnN1YnN0cmluZyhzZWxFbmQpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIHNlbFN0YXJ0KSArIHMuc3Vic3RyaW5nKHNlbEVuZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxFbmQgPSBzZWxTdGFydDtcclxuICAgICAgICBhcHBsaWVkID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChjLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICBzID0gcy5zdWJzdHJpbmcoMCwgc2VsU3RhcnQpICsgcy5zdWJzdHJpbmcoc2VsRW5kKTtcclxuXHJcbiAgICAgIGlmIChOdW1iZXJQYXJzZXJGb3JtYXR0ZXIuY2FuQWNjZXB0S2V5KHMsIGUua2V5Q29kZSwgYywgdGhpcy5mb3JtYXQsIHRoaXMuX3NlcGFyYXRvcnMsIHNlbFN0YXJ0KSkge1xyXG5cclxuICAgICAgICBzID0gcy5zdWJzdHJpbmcoMCwgc2VsU3RhcnQpICsgYyArIHMuc3Vic3RyaW5nKHNlbFN0YXJ0KTtcclxuICAgICAgICBzZWxTdGFydCsrO1xyXG4gICAgICAgIHNlbEVuZCA9IHNlbFN0YXJ0O1xyXG4gICAgICAgIGFwcGxpZWQgPSB0cnVlO1xyXG5cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGFwcGxpZWQpIHtcclxuICAgICAgLy8g0J/RgNC4INC40LfQvNC10L3QtdC90LjQuCDQt9C90LDRh9C10L3QuNGPINCy0L3QtdGB0LXQvCDQsiDRgdGC0Y3QuiB1bmRvXHJcbiAgICAgIGlmIChzICE9PSBzdGF0ZTAubmV3VmFsdWUpIHtcclxuICAgICAgICB0aGlzLl91bmRvLnB1c2goc3RhdGUwKTtcclxuICAgICAgICB0aGlzLl9yZWRvID0gW107XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHN0YXRlMyA9IE51bWJlclBhcnNlckZvcm1hdHRlci5yZWZvcm1hdChzLCB0aGlzLmZvcm1hdCwgdGhpcy5fc2VwYXJhdG9ycywgc2VsU3RhcnQsIHNlbEVuZCwgbGVhZFRvRm9ybWF0KTtcclxuICAgICAgdGhpcy5zZXRSZXModGhpcy5nZXRSZXMoc3RhdGUzLnZhbHVlLCBzdGF0ZTMuc2VsU3RhcnQsIHN0YXRlMy5zZWxFbmQpKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmFuZHJvaWRfYmVoYXZpb3IpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICAvLyDQo9GB0YLQsNC90L7QstC40YLRjCDQt9C90LDRh9C10L3QuNC1INC4INC/0L7Qu9C+0LbQtdC90LjQtSDQutGD0YDRgdC+0YDQsFxyXG4gIHByb3RlY3RlZCBzZXRSZXMocmVzOiBNYXNrUmVzdWx0KSB7XHJcblxyXG4gICAgaWYgKHRoaXMuYW5kcm9pZF9iZWhhdmlvcilcclxuICAgICAgcmVzLnNlbExlbmd0aCA9IDA7XHJcblxyXG4gICAgdGhpcy5zZXRUZXh0KHJlcy5uZXdWYWx1ZSk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdzZWxlY3Rpb25TdGFydCcsIHJlcy5zZWxTdGFydCk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdzZWxlY3Rpb25FbmQnLCByZXMuc2VsU3RhcnQgKyByZXMuc2VsTGVuZ3RoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjdXJyZW50UmVzKCkge1xyXG4gICAgbGV0IHJlcyA9IG5ldyBNYXNrUmVzdWx0KHRoaXMuX3R4dFZhbHVlLCBNYXNrU2VjdGlvbkFjdGlvbi5BUFBMWSwgMCk7XHJcbiAgICByZXMuc2VsU3RhcnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XHJcbiAgICByZXMuc2VsTGVuZ3RoID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNlbGVjdGlvbkVuZCAtIHJlcy5zZWxTdGFydDtcclxuICAgIHJldHVybiByZXM7XHJcbiAgfVxyXG5cclxuICAvLyDQn9C+0LvRg9GH0LjRgtGMINGC0LXQutGD0YnQtdC1INC30L3QsNGH0LXQvdC40LUg0LzQsNGB0LrQuCDQuCDQv9C+0LvQvtC20LXQvdC40LUg0LrRg9GA0YHQvtGA0LBcclxuICBwcm90ZWN0ZWQgZ2V0UmVzKHM6IHN0cmluZywgc2VsU3RhcnQ6IG51bWJlciwgc2VsRW5kOiBudW1iZXIpOiBNYXNrUmVzdWx0IHtcclxuICAgIGxldCByZXMgPSBuZXcgTWFza1Jlc3VsdChzLCBNYXNrU2VjdGlvbkFjdGlvbi5BUFBMWSwgMCk7XHJcbiAgICByZXMuc2VsU3RhcnQgPSBzZWxTdGFydDtcclxuICAgIHJlcy5zZWxMZW5ndGggPSBzZWxFbmQgLSBzZWxTdGFydDtcclxuICAgIHJldHVybiByZXM7XHJcbiAgfVxyXG5cclxuICAvLyDQl9Cw0L/QuNGB0YvQstCw0LXRgiDRgtC10LrRgdGCINCyINC60L7QvdGC0YDQvtC7XHJcbiAgcHJvdGVjdGVkIHNldFRleHQoZGlzcGxheWVkVmFsdWU6IHN0cmluZywgdG9Nb2RlbDogYm9vbGVhbiA9IHRydWUpIHtcclxuXHJcbiAgICAvLyDQntGC0L7QsdGA0LDQttCw0LXQvFxyXG4gICAgdGhpcy5fdHh0VmFsdWUgPSBkaXNwbGF5ZWRWYWx1ZTtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3ZhbHVlJywgdGhpcy5fdHh0VmFsdWUpO1xyXG5cclxuICAgIC8vINCe0YLQv9GA0LDQstC70Y/QtdC8INCyINC80L7QtNC10LvRjFxyXG4gICAgaWYgKHRvTW9kZWwpIHtcclxuICAgICAgdGhpcy50b01vZGVsKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZXRMb2NhbGUobG9jYWxlOiBMb2NhbGUpIHtcclxuICAgIHRoaXMuX3NlcGFyYXRvcnNbMF0gPSBsb2NhbGUuc2VwYXJhdG9yc1swXTtcclxuICAgIHRoaXMuX3NlcGFyYXRvcnNbMV0gPSBsb2NhbGUuc2VwYXJhdG9yc1sxXTtcclxuXHJcbiAgICAvLyBVcGRhdGluZyB2aWV3XHJcbiAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5fbnVtVmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAvLyBVbnN1YnNjcmliaW5nXHJcbiAgICB0aGlzLl9sb2NhbGVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuICAgICAgcHJvdGVjdGVkIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxyXG4gICAgICBwcm90ZWN0ZWQgaW50bDogSW50ZXJuYXRpb25hbGl6YXRpb25TZXJ2aWNlKSB7XHJcbiAgICAvLyBGb3JtYXQgY2hhbmdlIGNhbiBmb2xsb3cgbG9jYWxlIGNoYW5nZVxyXG4gICAgdGhpcy5fbG9jYWxlU3Vic2NyaXB0aW9uID0gdGhpcy5pbnRsLm9uTG9jYWxlQ2hhbmdlZC5zdWJzY3JpYmUobG9jYWxlID0+IHRoaXMuc2V0TG9jYWxlKGxvY2FsZSkpO1xyXG4gIH1cclxufVxyXG4iXX0=