@true-directive/grid
Version:
Angular Data Grid from Yopsilon.
243 lines • 27 kB
JavaScript
import * as tslib_1 from "tslib";
/**
* Copyright (c) 2018-2019 Aleksey Melnikov, True Directive Company.
* @link https://truedirective.com/
* @license MIT
*/
import { Component, Output, EventEmitter, ViewChild, ElementRef, Renderer2 } from '@angular/core';
import { Keys } from '@true-directive/base';
import { Utils } from '@true-directive/base';
import { CalendarComponent } from '../controls/calendar.component';
import { PopupComponent } from '../controls/popup.component';
import { MaskDateDirective } from '../mask/mask-date.directive';
import { DOMUtils } from '../common/dom-utils.class';
let EditorTestComponent = class EditorTestComponent {
constructor(_renderer, _elementRef) {
this._renderer = _renderer;
this._elementRef = _elementRef;
this.ie = false;
this.valueTemp = false;
this.valueChanged = false;
this.height = 0;
this.datepickerInputClass = 'true-grid-input';
this._initialized = false;
this.commit = new EventEmitter();
this.change = new EventEmitter();
this.cancel = new EventEmitter();
}
get popupVisible() {
return this.popup.visible;
}
getIcon() {
return 'true-icon-calendar-empty';
}
datepickerChange(e) {
if (this._initialized) {
this.change.emit(this.purify(e));
}
}
dateClick(e) {
this.inputChange(e);
this.popup.closePopup();
}
togglePopup() {
this.popup.toggle(this._elementRef.nativeElement, '');
setTimeout(() => {
if (this.popupVisible) {
this.focusPopup();
}
});
}
btnClick(e) {
this.togglePopup();
}
popupClose(e) {
if (!Utils.detectMobile()) {
// We allow the user to set the focus on input.
this.input.nativeElement.focus();
setTimeout(() => {
const txt = this.input.nativeElement.value;
if (txt !== undefined && this._renderer) {
this._renderer.setProperty(this.input.nativeElement, 'selectionStart', 0);
this._renderer.setProperty(this.input.nativeElement, 'selectionEnd', txt.length);
}
});
}
}
init(value, valueChanged, height, ie = false, wasShown = false) {
if (this.state.touchMode) {
this.popup.position = 'MODAL';
}
else {
this.popup.position = 'RELATIVE';
}
this.valueTemp = value;
this.valueChanged = valueChanged;
this.height = height;
this.ie = ie;
if (this.state.iOS) {
DOMUtils.focusAndOpenKeyboard(this.input.nativeElement, 50);
}
}
// Останавливаем propagation, чтобы не влиять на grid
inputMouseDown(e) {
e.stopPropagation();
}
inputChange(e) {
this.change.emit(e);
}
inputKeyDown(e) {
if (e.defaultPrevented) {
return;
}
if (e.keyCode === Keys.DOWN && e.altKey && !this.popup.visible) {
this.togglePopup();
e.preventDefault();
e.stopPropagation();
return;
}
if (e.keyCode === Keys.UP ||
e.keyCode === Keys.DOWN ||
e.keyCode === Keys.PAGE_UP ||
e.keyCode === Keys.PAGE_DOWN ||
e.keyCode === Keys.TAB) {
// По идее просто их должен отработать грид
return;
}
e.stopPropagation();
if (e.keyCode === Keys.ESCAPE) {
this.cancel.emit();
return;
}
if (e.keyCode === Keys.ENTER) {
this.commit.emit(this.value);
return;
}
}
escape(e) {
this.popup.closePopup();
}
acceptKey(e) {
this.maskDateDirective.keyDown(Keys.generateEvent(this.input.nativeElement, -1, Keys.keyChar(e), e.shiftKey, e.ctrlKey));
}
ngAfterContentInit() {
if (!this.valueChanged) {
this.value = this.valueTemp;
// The pattern hasn't applied yet.
this.maskDateDirective.pattern = this.column.format;
this.maskDateDirective.writeValue(this.value);
setTimeout(() => {
if (!this.state.touchMode) {
// Select all if not mobile device
this.input.nativeElement.select();
}
this.input.nativeElement.focus();
});
this._initialized = true;
}
else {
this.input.nativeElement.focus();
const txt = this.valueTemp;
setTimeout(() => {
for (let i = 0; i < txt.length; i++) {
const e = Keys.generateEvent(null, 0, txt[i]);
this.acceptKey(e);
}
this._initialized = true;
});
}
}
focusPopup() {
this.calendar.setFocus();
}
// Если у нас есть информация о высоте строки - берем её и не
// назначаем никакого класса
getClass() {
if ((this.height !== null && this.height > 0)) {
return 'true-grid__input-container';
}
if (this.ie) {
return 'true-grid-editor-ie';
}
else {
return 'true-grid-editor-100p';
}
}
getH() {
if (this.height !== null && this.height > 0) {
return this.height + 'px';
}
return '100%';
}
purify(v) {
if (v === undefined || v === null || isNaN(v.getTime())) {
return null;
}
return v;
}
};
tslib_1.__decorate([
ViewChild('popup', { static: true }),
tslib_1.__metadata("design:type", PopupComponent)
], EditorTestComponent.prototype, "popup", void 0);
tslib_1.__decorate([
ViewChild('input', { static: true }),
tslib_1.__metadata("design:type", Object)
], EditorTestComponent.prototype, "input", void 0);
tslib_1.__decorate([
ViewChild('calendar', { static: true }),
tslib_1.__metadata("design:type", CalendarComponent)
], EditorTestComponent.prototype, "calendar", void 0);
tslib_1.__decorate([
ViewChild('input', { read: MaskDateDirective, static: true }),
tslib_1.__metadata("design:type", MaskDateDirective)
], EditorTestComponent.prototype, "maskDateDirective", void 0);
tslib_1.__decorate([
Output("commit"),
tslib_1.__metadata("design:type", EventEmitter)
], EditorTestComponent.prototype, "commit", void 0);
tslib_1.__decorate([
Output("change"),
tslib_1.__metadata("design:type", EventEmitter)
], EditorTestComponent.prototype, "change", void 0);
tslib_1.__decorate([
Output("cancel"),
tslib_1.__metadata("design:type", EventEmitter)
], EditorTestComponent.prototype, "cancel", void 0);
EditorTestComponent = tslib_1.__decorate([
Component({
selector: 'true-editor-test',
template: `<true-input-wrapper
class="true-datepicker__input"
(btnClick)="btnClick($event)"
[ngClass]="getClass()"
[style.height]="getH()"
[icon]="getIcon()"><input #input
class="true-grid-input"
[true-mask-date]="column.format"
[(ngModel)]="value"
(ngModelChange)="inputChange($event)"
[style.height]="getH()"
(mousedown)="inputMouseDown($event)"
(keydown)="inputKeyDown($event)" /></true-input-wrapper><true-popup #popup (close)="popupClose($event)">
<true-calendar #calendar
*ngIf="popupVisible"
[(ngModel)]="value"
(escape)="escape($event)"
(dateClick)="dateClick($event)">
</true-calendar>
</true-popup>`,
styles: [`
:host {
padding: 0;
}
.true-datepicker__input {
border: 0;
}
`]
}),
tslib_1.__metadata("design:paramtypes", [Renderer2,
ElementRef])
], EditorTestComponent);
export { EditorTestComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLXRlc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHRydWUtZGlyZWN0aXZlL2dyaWQvIiwic291cmNlcyI6WyJzcmMvZWRpdG9ycy9lZGl0b3ItdGVzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0VBSUU7QUFDRixPQUFPLEVBQUUsU0FBUyxFQUFTLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFDN0QsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRzFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFN0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFPLDZCQUE2QixDQUFDO0FBSWpFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQWlDckQsSUFBYSxtQkFBbUIsR0FBaEMsTUFBYSxtQkFBbUI7SUFzTjlCLFlBQXNCLFNBQW9CLEVBQ3BCLFdBQXVCO1FBRHZCLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFDcEIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFyTnJDLE9BQUUsR0FBWSxLQUFLLENBQUM7UUFDcEIsY0FBUyxHQUFRLEtBQUssQ0FBQztRQUN2QixpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUM5QixXQUFNLEdBQVcsQ0FBQyxDQUFDO1FBRzNCLHlCQUFvQixHQUFHLGlCQUFpQixDQUFDO1FBTWpDLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBZTdCLFdBQU0sR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUdsRCxXQUFNLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFHL0MsV0FBTSxH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LEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7c0NBQzVCLGNBQWM7a0RBQUM7QUFHdEI7SUFEQyxTQUFTLENBQUMsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQyxDQUFDOztrREFDeEI7QUFHWDtJQURDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7c0NBQzVCLGlCQUFpQjtxREFBQztBQUc1QjtJQURDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQyxDQUFDO3NDQUN6QyxpQkFBaUI7OERBQUM7QUFHckM7SUFEQyxNQUFNLENBQUMsUUFBUSxDQUFDO3NDQUNULFlBQVk7bURBQThCO0FBR2xEO0lBREMsTUFBTSxDQUFDLFFBQVEsQ0FBQztzQ0FDVCxZQUFZO21EQUEyQjtBQUcvQztJQURDLE1BQU0sQ0FBQyxRQUFRLENBQUM7c0NBQ1QsWUFBWTttREFBNEI7QUFuQ3JDLG1CQUFtQjtJQS9CL0IsU0FBUyxDQUFDO1FBQ1QsUUFBUSxFQUFFLGtCQUFrQjtRQUM1QixRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Z0NBbUJvQjtpQkFDckI7Ozs7Ozs7S0FPTjtLQUNGLENBQUM7NkNBdU4rQixTQUFTO1FBQ1AsVUFBVTtHQXZObEMsbUJBQW1CLENBd04vQjtTQXhOWSxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgQWxla3NleSBNZWxuaWtvdiwgVHJ1ZSBEaXJlY3RpdmUgQ29tcGFueS5cclxuICogQGxpbmsgaHR0cHM6Ly90cnVlZGlyZWN0aXZlLmNvbS9cclxuICogQGxpY2Vuc2UgTUlUXHJcbiovXHJcbmltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsXHJcbiAgICAgICAgIFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSAnQHRydWUtZGlyZWN0aXZlL2Jhc2UnO1xyXG5pbXBvcnQgeyBLZXlzIH0gZnJvbSAnQHRydWUtZGlyZWN0aXZlL2Jhc2UnO1xyXG5pbXBvcnQgeyBVdGlscyB9IGZyb20gJ0B0cnVlLWRpcmVjdGl2ZS9iYXNlJztcclxuXHJcbmltcG9ydCB7IENhbGVuZGFyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29udHJvbHMvY2FsZW5kYXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgUG9wdXBDb21wb25lbnQgfSBmcm9tICcuLi9jb250cm9scy9wb3B1cC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBNYXNrRGF0ZURpcmVjdGl2ZSB9IGZyb20gICcuLi9tYXNrL21hc2stZGF0ZS5kaXJlY3RpdmUnO1xyXG5cclxuaW1wb3J0IHsgR3JpZFN0YXRlU2VydmljZSB9IGZyb20gJy4uL2dyaWQtc3RhdGUuc2VydmljZSc7XHJcbmltcG9ydCB7IElFZGl0b3IgfSBmcm9tIFwiLi9lZGl0b3IuaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IERPTVV0aWxzIH0gZnJvbSAnLi4vY29tbW9uL2RvbS11dGlscy5jbGFzcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3RydWUtZWRpdG9yLXRlc3QnLFxyXG4gIHRlbXBsYXRlOiBgPHRydWUtaW5wdXQtd3JhcHBlclxyXG4gICAgY2xhc3M9XCJ0cnVlLWRhdGVwaWNrZXJfX2lucHV0XCJcclxuICAgIChidG5DbGljayk9XCJidG5DbGljaygkZXZlbnQpXCJcclxuICAgIFtuZ0NsYXNzXT1cImdldENsYXNzKClcIlxyXG4gICAgW3N0eWxlLmhlaWdodF09XCJnZXRIKClcIlxyXG4gICAgW2ljb25dPVwiZ2V0SWNvbigpXCI+PGlucHV0ICNpbnB1dFxyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRydWUtZ3JpZC1pbnB1dFwiXHJcbiAgICAgICAgICAgICAgICAgIFt0cnVlLW1hc2stZGF0ZV09XCJjb2x1bW4uZm9ybWF0XCJcclxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ2YWx1ZVwiXHJcbiAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImlucHV0Q2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cImdldEgoKVwiXHJcbiAgICAgICAgICAgICAgICAgIChtb3VzZWRvd24pPVwiaW5wdXRNb3VzZURvd24oJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgIChrZXlkb3duKT1cImlucHV0S2V5RG93bigkZXZlbnQpXCIgLz48L3RydWUtaW5wdXQtd3JhcHBlcj48dHJ1ZS1wb3B1cCAjcG9wdXAgKGNsb3NlKT1cInBvcHVwQ2xvc2UoJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0cnVlLWNhbGVuZGFyICNjYWxlbmRhclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInBvcHVwVmlzaWJsZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoZXNjYXBlKT1cImVzY2FwZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGRhdGVDbGljayk9XCJkYXRlQ2xpY2soJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdHJ1ZS1jYWxlbmRhcj5cclxuICAgICAgICAgICAgICAgICAgPC90cnVlLXBvcHVwPmAsXHJcbiAgc3R5bGVzOiBbYFxyXG4gICAgOmhvc3Qge1xyXG4gICAgICBwYWRkaW5nOiAwO1xyXG4gICAgfVxyXG4gICAgLnRydWUtZGF0ZXBpY2tlcl9faW5wdXQge1xyXG4gICAgICBib3JkZXI6IDA7XHJcbiAgICB9XHJcbiAgICBgXVxyXG4gIH0pXHJcbmV4cG9ydCBjbGFzcyBFZGl0b3JUZXN0Q29tcG9uZW50IGltcGxlbWVudHMgSUVkaXRvciB7XHJcblxyXG4gIHByaXZhdGUgaWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIHZhbHVlVGVtcDogYW55ID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSB2YWx1ZUNoYW5nZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIGhlaWdodDogbnVtYmVyID0gMDtcclxuXHJcbiAgcHVibGljIHZhbHVlOiBhbnk7XHJcbiAgZGF0ZXBpY2tlcklucHV0Q2xhc3MgPSAndHJ1ZS1ncmlkLWlucHV0JztcclxuXHJcbiAgc3RhdGU6IEdyaWRTdGF0ZVNlcnZpY2U7XHJcbiAgY29sdW1uOiBDb2x1bW47XHJcbiAgcm93OiBhbnk7XHJcblxyXG4gIHByaXZhdGUgX2luaXRpYWxpemVkID0gZmFsc2U7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3BvcHVwJywge3N0YXRpYzogdHJ1ZX0pXHJcbiAgcG9wdXA6IFBvcHVwQ29tcG9uZW50O1xyXG5cclxuICBAVmlld0NoaWxkKCdpbnB1dCcsIHtzdGF0aWM6IHRydWV9KVxyXG4gIGlucHV0OiBhbnk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2NhbGVuZGFyJywge3N0YXRpYzogdHJ1ZX0pXHJcbiAgY2FsZW5kYXI6IENhbGVuZGFyQ29tcG9uZW50O1xyXG5cclxuICBAVmlld0NoaWxkKCdpbnB1dCcsIHtyZWFkOiBNYXNrRGF0ZURpcmVjdGl2ZSwgc3RhdGljOiB0cnVlfSlcclxuICBtYXNrRGF0ZURpcmVjdGl2ZTogTWFza0RhdGVEaXJlY3RpdmU7XHJcblxyXG4gIEBPdXRwdXQoXCJjb21taXRcIilcclxuICBjb21taXQ6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICBAT3V0cHV0KFwiY2hhbmdlXCIpXHJcbiAgY2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgQE91dHB1dChcImNhbmNlbFwiKVxyXG4gIGNhbmNlbDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICBnZXQgcG9wdXBWaXNpYmxlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucG9wdXAudmlzaWJsZTtcclxuICB9XHJcblxyXG4gIGdldEljb24oKTogc3RyaW5nIHtcclxuICAgIHJldHVybiAndHJ1ZS1pY29uLWNhbGVuZGFyLWVtcHR5JztcclxuICB9XHJcblxyXG4gIGRhdGVwaWNrZXJDaGFuZ2UoZTogYW55KSB7XHJcbiAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcclxuICAgICAgdGhpcy5jaGFuZ2UuZW1pdCh0aGlzLnB1cmlmeShlKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBkYXRlQ2xpY2soZTogYW55KSB7XHJcbiAgICB0aGlzLmlucHV0Q2hhbmdlKGUpO1xyXG4gICAgdGhpcy5wb3B1cC5jbG9zZVBvcHVwKCk7XHJcbiAgfVxyXG5cclxuICB0b2dnbGVQb3B1cCgpIHtcclxuICAgIHRoaXMucG9wdXAudG9nZ2xlKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJycpO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnBvcHVwVmlzaWJsZSkge1xyXG4gICAgICAgIHRoaXMuZm9jdXNQb3B1cCgpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGJ0bkNsaWNrKGU6IGFueSkge1xyXG4gICAgdGhpcy50b2dnbGVQb3B1cCgpO1xyXG4gIH1cclxuXHJcbiAgcG9wdXBDbG9zZShlOiBhbnkpIHtcclxuXHJcbiAgICBpZiAoIVV0aWxzLmRldGVjdE1vYmlsZSgpKSB7XHJcbiAgICAgIC8vIFdlIGFsbG93IHRoZSB1c2VyIHRvIHNldCB0aGUgZm9jdXMgb24gaW5wdXQuXHJcbiAgICAgIHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICBjb25zdCB0eHQgPSB0aGlzLmlucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWU7XHJcbiAgICAgICAgaWYgKHR4dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX3JlbmRlcmVyKSB7XHJcbiAgICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLmlucHV0Lm5hdGl2ZUVsZW1lbnQsICdzZWxlY3Rpb25TdGFydCcsIDApO1xyXG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0UHJvcGVydHkodGhpcy5pbnB1dC5uYXRpdmVFbGVtZW50LCAnc2VsZWN0aW9uRW5kJywgdHh0Lmxlbmd0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGluaXQodmFsdWU6IGFueSwgdmFsdWVDaGFuZ2VkOiBib29sZWFuLCBoZWlnaHQ6IG51bWJlciwgaWU6IGJvb2xlYW4gPSBmYWxzZSwgd2FzU2hvd246IGJvb2xlYW4gPSBmYWxzZSkge1xyXG5cclxuICAgIGlmICh0aGlzLnN0YXRlLnRvdWNoTW9kZSkge1xyXG4gICAgICB0aGlzLnBvcHVwLnBvc2l0aW9uID0gJ01PREFMJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucG9wdXAucG9zaXRpb24gPSAnUkVMQVRJVkUnO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudmFsdWVUZW1wID0gdmFsdWU7XHJcbiAgICB0aGlzLnZhbHVlQ2hhbmdlZCA9IHZhbHVlQ2hhbmdlZDtcclxuICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG4gICAgdGhpcy5pZSA9IGllO1xyXG4gICAgaWYgKHRoaXMuc3RhdGUuaU9TKSB7XHJcbiAgICAgIERPTVV0aWxzLmZvY3VzQW5kT3BlbktleWJvYXJkKHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudCwgNTApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8g0J7RgdGC0LDQvdCw0LLQu9C40LLQsNC10LwgcHJvcGFnYXRpb24sINGH0YLQvtCx0Ysg0L3QtSDQstC70LjRj9GC0Ywg0L3QsCBncmlkXHJcbiAgaW5wdXRNb3VzZURvd24oZTogYW55KSB7XHJcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgaW5wdXRDaGFuZ2UoZTogYW55KSB7XHJcbiAgICB0aGlzLmNoYW5nZS5lbWl0KGUpO1xyXG4gIH1cclxuXHJcbiAgaW5wdXRLZXlEb3duKGU6IGFueSkge1xyXG5cclxuICAgIGlmIChlLmRlZmF1bHRQcmV2ZW50ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChlLmtleUNvZGUgPT09IEtleXMuRE9XTiAmJiBlLmFsdEtleSAmJiAhdGhpcy5wb3B1cC52aXNpYmxlKSB7XHJcbiAgICAgIHRoaXMudG9nZ2xlUG9wdXAoKTtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5cy5VUCB8fFxyXG4gICAgICAgIGUua2V5Q29kZSA9PT0gS2V5cy5ET1dOIHx8XHJcbiAgICAgICAgZS5rZXlDb2RlID09PSBLZXlzLlBBR0VfVVAgfHxcclxuICAgICAgICBlLmtleUNvZGUgPT09IEtleXMuUEFHRV9ET1dOIHx8XHJcbiAgICAgICAgZS5rZXlDb2RlID09PSBLZXlzLlRBQikge1xyXG4gICAgICAvLyDQn9C+INC40LTQtdC1INC/0YDQvtGB0YLQviDQuNGFINC00L7Qu9C20LXQvSDQvtGC0YDQsNCx0L7RgtCw0YLRjCDQs9GA0LjQtFxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICBpZiAoZS5rZXlDb2RlID09PSBLZXlzLkVTQ0FQRSkge1xyXG4gICAgICB0aGlzLmNhbmNlbC5lbWl0KCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZS5rZXlDb2RlID09PSBLZXlzLkVOVEVSKSB7XHJcbiAgICAgIHRoaXMuY29tbWl0LmVtaXQodGhpcy52YWx1ZSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGVzY2FwZShlOiBhbnkpIHtcclxuICAgIHRoaXMucG9wdXAuY2xvc2VQb3B1cCgpO1xyXG4gIH1cclxuXHJcbiAgYWNjZXB0S2V5KGU6IGFueSkge1xyXG4gICAgdGhpcy5tYXNrRGF0ZURpcmVjdGl2ZS5rZXlEb3duKFxyXG4gICAgICBLZXlzLmdlbmVyYXRlRXZlbnQodGhpcy5pbnB1dC5uYXRpdmVFbGVtZW50LCAtMSwgS2V5cy5rZXlDaGFyKGUpLCBlLnNoaWZ0S2V5LCBlLmN0cmxLZXkpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG5cclxuICAgIGlmKCF0aGlzLnZhbHVlQ2hhbmdlZCkge1xyXG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy52YWx1ZVRlbXA7XHJcbiAgICAgIC8vIFRoZSBwYXR0ZXJuIGhhc24ndCBhcHBsaWVkIHlldC5cclxuICAgICAgdGhpcy5tYXNrRGF0ZURpcmVjdGl2ZS5wYXR0ZXJuID0gdGhpcy5jb2x1bW4uZm9ybWF0O1xyXG4gICAgICB0aGlzLm1hc2tEYXRlRGlyZWN0aXZlLndyaXRlVmFsdWUodGhpcy52YWx1ZSk7XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy5zdGF0ZS50b3VjaE1vZGUpIHtcclxuICAgICAgICAgIC8vIFNlbGVjdCBhbGwgaWYgbm90IG1vYmlsZSBkZXZpY2VcclxuICAgICAgICAgIHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudC5zZWxlY3QoKVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmlucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gICAgICBjb25zdCB0eHQgPSB0aGlzLnZhbHVlVGVtcDtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eHQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIGNvbnN0IGUgPSBLZXlzLmdlbmVyYXRlRXZlbnQobnVsbCwgMCwgdHh0W2ldKTtcclxuICAgICAgICAgIHRoaXMuYWNjZXB0S2V5KGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZm9jdXNQb3B1cCgpIHtcclxuICAgIHRoaXMuY2FsZW5kYXIuc2V0Rm9jdXMoKTtcclxuICB9XHJcblxyXG4gIC8vINCV0YHQu9C4INGDINC90LDRgSDQtdGB0YLRjCDQuNC90YTQvtGA0LzQsNGG0LjRjyDQviDQstGL0YHQvtGC0LUg0YHRgtGA0L7QutC4IC0g0LHQtdGA0LXQvCDQtdGRINC4INC90LVcclxuICAvLyDQvdCw0LfQvdCw0YfQsNC10Lwg0L3QuNC60LDQutC+0LPQviDQutC70LDRgdGB0LBcclxuICBnZXRDbGFzcygpIHtcclxuICAgIGlmICgodGhpcy5oZWlnaHQgIT09IG51bGwgJiYgdGhpcy5oZWlnaHQgPiAwKSkge1xyXG4gICAgICByZXR1cm4gJ3RydWUtZ3JpZF9faW5wdXQtY29udGFpbmVyJztcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmllKSB7XHJcbiAgICAgIHJldHVybiAndHJ1ZS1ncmlkLWVkaXRvci1pZSc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gJ3RydWUtZ3JpZC1lZGl0b3ItMTAwcCc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRIKCkge1xyXG4gICAgaWYgKHRoaXMuaGVpZ2h0ICE9PSBudWxsICYmIHRoaXMuaGVpZ2h0ID4gMCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5oZWlnaHQgKyAncHgnO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuICcxMDAlJztcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBwdXJpZnkodjogYW55KTogYW55IHtcclxuICAgIGlmICh2ID09PSB1bmRlZmluZWQgfHwgdiA9PT0gbnVsbCB8fCBpc05hTih2LmdldFRpbWUoKSkpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHsgfVxyXG59XHJcbiJdfQ==