asa-date-picker
Version:
An Angular date picker component supporting Gregorian and Persian (Jalali/Shamsi) calendars, powered by Asa Co.
224 lines • 30.7 kB
JavaScript
import { Directive, HostListener, Input } from '@angular/core';
import * as i0 from "@angular/core";
export class DateMaskDirective {
constructor(el) {
this.el = el;
this.dateFormat = 'yyyy/MM/dd';
this.disableInputMask = false;
this.delimiters = [];
this.parts = [];
this.lastValue = '';
}
ngOnInit() {
this.parseFormat();
}
parseFormat() {
if (this.disableInputMask)
return;
this.parts = [];
this.delimiters = [];
let currentPart = '';
for (let i = 0; i < this.dateFormat.length; i++) {
const char = this.dateFormat[i];
if (this.isFormatChar(char)) {
currentPart += char;
}
else {
if (currentPart) {
this.parts.push(currentPart);
currentPart = '';
}
this.delimiters.push(char);
}
}
if (currentPart) {
this.parts.push(currentPart);
}
}
isFormatChar(char) {
return /[yMdHhmsa]/i.test(char);
}
onInput(event) {
if (this.disableInputMask)
return;
const input = event.target;
const cursorPosition = input.selectionStart || 0;
let value = input.value.replace(/[^0-9APMapm\s:/\-\.]/g, '');
// Allow backspace/delete
if (value.length < this.lastValue.length) {
this.lastValue = value;
return;
}
let formattedParts = [];
let currentValue = value;
let shouldAddDelimiter = false;
let totalLength = 0;
let newCursorPosition = cursorPosition;
for (let i = 0; i < this.parts.length; i++) {
const part = this.extractPart(currentValue, this.parts[i]);
if (!part && part !== '0')
break;
const expectedLength = this.getPartLength(this.parts[i]);
let formattedPart = part;
if (formattedPart.length >= expectedLength) {
formattedPart = this.validatePart(formattedPart.slice(0, expectedLength), this.parts[i]);
shouldAddDelimiter = true;
}
formattedParts.push(formattedPart);
totalLength += formattedPart.length;
if (shouldAddDelimiter && i < this.parts.length - 1) {
formattedParts.push(this.delimiters[i] || '');
totalLength += 1;
shouldAddDelimiter = false;
if (cursorPosition === totalLength - 1) {
newCursorPosition = totalLength;
}
}
currentValue = this.removeProcessedPart(currentValue, part);
}
const formattedValue = formattedParts.join('');
input.value = formattedValue;
// Set cursor position
newCursorPosition = Math.min(newCursorPosition, totalLength);
input.setSelectionRange(newCursorPosition, newCursorPosition);
this.lastValue = formattedValue;
}
extractPart(value, format) {
if (!value)
return '';
if (format[0].toLowerCase() === 'a') {
// Handle AM/PM
const match = value.match(/^[AaPp][Mm]?/);
return match ? match[0].toUpperCase() : '';
}
// Handle numeric parts
const match = value.match(/^\d+/);
return match ? match[0] : '';
}
removeProcessedPart(value, part) {
if (!part)
return value;
// Remove part and following delimiter if exists
const remainingValue = value.slice(part.length);
return remainingValue.replace(/^[:/\s-]/, '');
}
onKeyDown(event) {
if (this.disableInputMask)
return;
const input = event.target;
const cursorPosition = input.selectionStart || 0;
// Allow control keys
if (event.key === 'Backspace' || event.key === 'Delete' ||
event.key === 'ArrowLeft' || event.key === 'ArrowRight' ||
event.key === 'Tab' || event.ctrlKey) {
return;
}
const currentPartIndex = this.getCurrentPartIndex(input.value, cursorPosition);
if (currentPartIndex === -1)
return;
const currentFormat = this.parts[currentPartIndex];
const isTimeDelimiter = event.key === ':' && cursorPosition > 0 &&
(this.parts[currentPartIndex - 1]?.includes('H') ||
this.parts[currentPartIndex - 1]?.includes('h'));
// Allow time delimiter after hours
if (isTimeDelimiter) {
if (this.delimiters[currentPartIndex - 1] === ':') {
const parts = input.value.split(/[:/\s-]/);
const currentPart = this.validatePart(parts[currentPartIndex - 1], this.parts[currentPartIndex - 1]);
parts[currentPartIndex - 1] = currentPart;
const newValue = parts.slice(0, currentPartIndex).join(this.delimiters[currentPartIndex - 1]) + ':';
input.value = newValue + parts.slice(currentPartIndex).join(this.delimiters[currentPartIndex]);
input.setSelectionRange(newValue.length, newValue.length);
event.preventDefault();
}
return;
}
// Handle AM/PM input
if (currentFormat[0].toLowerCase() === 'a') {
if (!/^[AaPpMm]$/.test(event.key)) {
event.preventDefault();
}
return;
}
// Allow only digits for other parts
if (!/^\d$/.test(event.key)) {
event.preventDefault();
}
}
validatePart(value, format) {
if (value === '')
return '';
const type = format[0].toLowerCase();
if (type === 'a') {
const upperValue = value.toUpperCase();
if (value.length === 1) {
return upperValue === 'A' || upperValue === 'P' ? upperValue : '';
}
return ['AM', 'PM'].includes(upperValue) ? upperValue : upperValue[0];
}
const numValue = parseInt(value, 10);
switch (type) {
case 'h': // 12-hour format
if (format[0] == 'H')
return Math.min(Math.max(numValue, 0), 23).toString().padStart(2, '0');
return Math.min(Math.max(numValue, 1), 12).toString().padStart(2, '0');
case 'm': // month or minute
if (format === 'MM') {
return Math.min(Math.max(numValue, 1), 12).toString().padStart(2, '0');
}
return Math.min(Math.max(numValue, 0), 59).toString().padStart(2, '0');
case 's': // seconds
return Math.min(Math.max(numValue, 0), 59).toString().padStart(2, '0');
case 'd': // day
return Math.min(Math.max(numValue, 1), 31).toString().padStart(2, '0');
case 'y': // year
if (format.length === 2)
return value.padStart(2, '0');
return value.padStart(4, '0');
default:
return value;
}
}
getPartLength(format) {
const type = format[0].toLowerCase();
switch (type) {
case 'y': return format.length === 2 ? 2 : 4;
case 'a': return format.length === 1 ? 1 : 2;
default: return 2;
}
}
getCurrentPartIndex(value, cursorPosition) {
const parts = value.split(/[:/\s-]/);
let currentIndex = 0;
let totalLength = 0;
for (let i = 0; i < parts.length; i++) {
totalLength += parts[i].length;
if (cursorPosition <= totalLength + i) {
return i;
}
totalLength += 1; // Add delimiter length
}
return parts.length - 1;
}
}
DateMaskDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DateMaskDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
DateMaskDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: DateMaskDirective, isStandalone: true, selector: "[asa-dateMask]", inputs: { dateFormat: ["asa-dateMask", "dateFormat"], disableInputMask: "disableInputMask" }, host: { listeners: { "input": "onInput($event)", "keydown": "onKeyDown($event)" } }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DateMaskDirective, decorators: [{
type: Directive,
args: [{
selector: '[asa-dateMask]',
standalone: true
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { dateFormat: [{
type: Input,
args: ['asa-dateMask']
}], disableInputMask: [{
type: Input
}], onInput: [{
type: HostListener,
args: ['input', ['$event']]
}], onKeyDown: [{
type: HostListener,
args: ['keydown', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtbWFzay5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc2EtZGF0ZS1waWNrZXIvc3JjL3V0aWxzL2lucHV0LW1hc2suZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFNM0UsTUFBTSxPQUFPLGlCQUFpQjtJQVE1QixZQUFtQixFQUFjO1FBQWQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQVBWLGVBQVUsR0FBVyxZQUFZLENBQUM7UUFDaEQscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBRWxDLGVBQVUsR0FBYSxFQUFFLENBQUM7UUFDMUIsVUFBSyxHQUFhLEVBQUUsQ0FBQztRQUNyQixjQUFTLEdBQVcsRUFBRSxDQUFDO0lBRWEsQ0FBQztJQUVyQyxRQUFRO1FBQ04sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsZ0JBQWdCO1lBQ3ZCLE9BQU87UUFFVCxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNyQixJQUFJLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQy9DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFaEMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMzQixXQUFXLElBQUksSUFBSSxDQUFDO2FBQ3JCO2lCQUFNO2dCQUNMLElBQUksV0FBVyxFQUFFO29CQUNmLElB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QjsyRkFBakIsaUJBQWlCO2tCQUo3QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjtpR0FFd0IsVUFBVTtzQkFBaEMsS0FBSzt1QkFBQyxjQUFjO2dCQUNaLGdCQUFnQjtzQkFBeEIsS0FBSztnQkE0Q04sT0FBTztzQkFETixZQUFZO3VCQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFrRmpDLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2FzYS1kYXRlTWFza10nLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIERhdGVNYXNrRGlyZWN0aXZlIHtcbiAgQElucHV0KCdhc2EtZGF0ZU1hc2snKSBkYXRlRm9ybWF0OiBzdHJpbmcgPSAneXl5eS9NTS9kZCc7XG4gIEBJbnB1dCgpIGRpc2FibGVJbnB1dE1hc2sgPSBmYWxzZTtcblxuICBkZWxpbWl0ZXJzOiBzdHJpbmdbXSA9IFtdO1xuICBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgbGFzdFZhbHVlOiBzdHJpbmcgPSAnJztcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZWw6IEVsZW1lbnRSZWYpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5wYXJzZUZvcm1hdCgpO1xuICB9XG5cbiAgcGFyc2VGb3JtYXQoKSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZUlucHV0TWFzaylcbiAgICAgIHJldHVybjtcblxuICAgIHRoaXMucGFydHMgPSBbXTtcbiAgICB0aGlzLmRlbGltaXRlcnMgPSBbXTtcbiAgICBsZXQgY3VycmVudFBhcnQgPSAnJztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kYXRlRm9ybWF0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjaGFyID0gdGhpcy5kYXRlRm9ybWF0W2ldO1xuXG4gICAgICBpZiAodGhpcy5pc0Zvcm1hdENoYXIoY2hhcikpIHtcbiAgICAgICAgY3VycmVudFBhcnQgKz0gY2hhcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjdXJyZW50UGFydCkge1xuICAgICAgICAgIHRoaXMucGFydHMucHVzaChjdXJyZW50UGFydCk7XG4gICAgICAgICAgY3VycmVudFBhcnQgPSAnJztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlbGltaXRlcnMucHVzaChjaGFyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFBhcnQpIHtcbiAgICAgIHRoaXMucGFydHMucHVzaChjdXJyZW50UGFydCk7XG4gICAgfVxuICB9XG5cbiAgaXNGb3JtYXRDaGFyKGNoYXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAvW3lNZEhobXNhXS9pLnRlc3QoY2hhcik7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdpbnB1dCcsIFsnJGV2ZW50J10pXG4gIG9uSW5wdXQoZXZlbnQ6IElucHV0RXZlbnQpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlSW5wdXRNYXNrKVxuICAgICAgcmV0dXJuO1xuXG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCBjdXJzb3JQb3NpdGlvbiA9IGlucHV0LnNlbGVjdGlvblN0YXJ0IHx8IDA7XG4gICAgbGV0IHZhbHVlID0gaW5wdXQudmFsdWUucmVwbGFjZSgvW14wLTlBUE1hcG1cXHM6L1xcLVxcLl0vZywgJycpO1xuXG4gICAgLy8gQWxsb3cgYmFja3NwYWNlL2RlbGV0ZVxuICAgIGlmICh2YWx1ZS5sZW5ndGggPCB0aGlzLmxhc3RWYWx1ZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMubGFzdFZhbHVlID0gdmFsdWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGZvcm1hdHRlZFBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBjdXJyZW50VmFsdWUgPSB2YWx1ZTtcbiAgICBsZXQgc2hvdWxkQWRkRGVsaW1pdGVyID0gZmFsc2U7XG4gICAgbGV0IHRvdGFsTGVuZ3RoID0gMDtcbiAgICBsZXQgbmV3Q3Vyc29yUG9zaXRpb24gPSBjdXJzb3JQb3NpdGlvbjtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGFydCA9IHRoaXMuZXh0cmFjdFBhcnQoY3VycmVudFZhbHVlLCB0aGlzLnBhcnRzW2ldKTtcbiAgICAgIGlmICghcGFydCAmJiBwYXJ0ICE9PSAnMCcpIGJyZWFrO1xuXG4gICAgICBjb25zdCBleHBlY3RlZExlbmd0aCA9IHRoaXMuZ2V0UGFydExlbmd0aCh0aGlzLnBhcnRzW2ldKTtcbiAgICAgIGxldCBmb3JtYXR0ZWRQYXJ0ID0gcGFydDtcblxuICAgICAgaWYgKGZvcm1hdHRlZFBhcnQubGVuZ3RoID49IGV4cGVjdGVkTGVuZ3RoKSB7XG4gICAgICAgIGZvcm1hdHRlZFBhcnQgPSB0aGlzLnZhbGlkYXRlUGFydChmb3JtYXR0ZWRQYXJ0LnNsaWNlKDAsIGV4cGVjdGVkTGVuZ3RoKSwgdGhpcy5wYXJ0c1tpXSk7XG4gICAgICAgIHNob3VsZEFkZERlbGltaXRlciA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGZvcm1hdHRlZFBhcnRzLnB1c2goZm9ybWF0dGVkUGFydCk7XG4gICAgICB0b3RhbExlbmd0aCArPSBmb3JtYXR0ZWRQYXJ0Lmxlbmd0aDtcblxuICAgICAgaWYgKHNob3VsZEFkZERlbGltaXRlciAmJiBpIDwgdGhpcy5wYXJ0cy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGZvcm1hdHRlZFBhcnRzLnB1c2godGhpcy5kZWxpbWl0ZXJzW2ldIHx8ICcnKTtcbiAgICAgICAgdG90YWxMZW5ndGggKz0gMTtcbiAgICAgICAgc2hvdWxkQWRkRGVsaW1pdGVyID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGN1cnNvclBvc2l0aW9uID09PSB0b3RhbExlbmd0aCAtIDEpIHtcbiAgICAgICAgICBuZXdDdXJzb3JQb3NpdGlvbiA9IHRvdGFsTGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRWYWx1ZSA9IHRoaXMucmVtb3ZlUHJvY2Vzc2VkUGFydChjdXJyZW50VmFsdWUsIHBhcnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gZm9ybWF0dGVkUGFydHMuam9pbignJyk7XG4gICAgaW5wdXQudmFsdWUgPSBmb3JtYXR0ZWRWYWx1ZTtcblxuICAgIC8vIFNldCBjdXJzb3IgcG9zaXRpb25cbiAgICBuZXdDdXJzb3JQb3NpdGlvbiA9IE1hdGgubWluKG5ld0N1cnNvclBvc2l0aW9uLCB0b3RhbExlbmd0aCk7XG4gICAgaW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3Q3Vyc29yUG9zaXRpb24sIG5ld0N1cnNvclBvc2l0aW9uKTtcblxuICAgIHRoaXMubGFzdFZhbHVlID0gZm9ybWF0dGVkVmFsdWU7XG4gIH1cblxuICBleHRyYWN0UGFydCh2YWx1ZTogc3RyaW5nLCBmb3JtYXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuICcnO1xuXG4gICAgaWYgKGZvcm1hdFswXS50b0xvd2VyQ2FzZSgpID09PSAnYScpIHtcbiAgICAgIC8vIEhhbmRsZSBBTS9QTVxuICAgICAgY29uc3QgbWF0Y2ggPSB2YWx1ZS5tYXRjaCgvXltBYVBwXVtNbV0/Lyk7XG4gICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFswXS50b1VwcGVyQ2FzZSgpIDogJyc7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIG51bWVyaWMgcGFydHNcbiAgICBjb25zdCBtYXRjaCA9IHZhbHVlLm1hdGNoKC9eXFxkKy8pO1xuICAgIHJldHVybiBtYXRjaCA/IG1hdGNoWzBdIDogJyc7XG4gIH1cblxuICByZW1vdmVQcm9jZXNzZWRQYXJ0KHZhbHVlOiBzdHJpbmcsIHBhcnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFwYXJ0KSByZXR1cm4gdmFsdWU7XG5cbiAgICAvLyBSZW1vdmUgcGFydCBhbmQgZm9sbG93aW5nIGRlbGltaXRlciBpZiBleGlzdHNcbiAgICBjb25zdCByZW1haW5pbmdWYWx1ZSA9IHZhbHVlLnNsaWNlKHBhcnQubGVuZ3RoKTtcbiAgICByZXR1cm4gcmVtYWluaW5nVmFsdWUucmVwbGFjZSgvXls6L1xccy1dLywgJycpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmICh0aGlzLmRpc2FibGVJbnB1dE1hc2spXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCBpbnB1dCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgIGNvbnN0IGN1cnNvclBvc2l0aW9uID0gaW5wdXQuc2VsZWN0aW9uU3RhcnQgfHwgMDtcblxuICAgIC8vIEFsbG93IGNvbnRyb2wga2V5c1xuICAgIGlmIChldmVudC5rZXkgPT09ICdCYWNrc3BhY2UnIHx8IGV2ZW50LmtleSA9PT0gJ0RlbGV0ZScgfHxcbiAgICAgICAgZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1JpZ2h0JyB8fFxuICAgICAgICBldmVudC5rZXkgPT09ICdUYWInIHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50UGFydEluZGV4ID0gdGhpcy5nZXRDdXJyZW50UGFydEluZGV4KGlucHV0LnZhbHVlLCBjdXJzb3JQb3NpdGlvbik7XG4gICAgaWYgKGN1cnJlbnRQYXJ0SW5kZXggPT09IC0xKSByZXR1cm47XG5cbiAgICBjb25zdCBjdXJyZW50Rm9ybWF0ID0gdGhpcy5wYXJ0c1tjdXJyZW50UGFydEluZGV4XTtcbiAgICBjb25zdCBpc1RpbWVEZWxpbWl0ZXIgPSBldmVudC5rZXkgPT09ICc6JyAmJiBjdXJzb3JQb3NpdGlvbiA+IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLnBhcnRzW2N1cnJlbnRQYXJ0SW5kZXggLSAxXT8uaW5jbHVkZXMoJ0gnKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFydHNbY3VycmVudFBhcnRJbmRleCAtIDFdPy5pbmNsdWRlcygnaCcpKTtcblxuICAgIC8vIEFsbG93IHRpbWUgZGVsaW1pdGVyIGFmdGVyIGhvdXJzXG4gICAgaWYgKGlzVGltZURlbGltaXRlcikge1xuICAgICAgaWYgKHRoaXMuZGVsaW1pdGVyc1tjdXJyZW50UGFydEluZGV4IC0gMV0gPT09ICc6Jykge1xuICAgICAgICBjb25zdCBwYXJ0cyA9IGlucHV0LnZhbHVlLnNwbGl0KC9bOi9cXHMtXS8pO1xuICAgICAgICBjb25zdCBjdXJyZW50UGFydCA9IHRoaXMudmFsaWRhdGVQYXJ0KHBhcnRzW2N1cnJlbnRQYXJ0SW5kZXggLSAxXSwgdGhpcy5wYXJ0c1tjdXJyZW50UGFydEluZGV4IC0gMV0pO1xuICAgICAgICBwYXJ0c1tjdXJyZW50UGFydEluZGV4IC0gMV0gPSBjdXJyZW50UGFydDtcblxuICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHBhcnRzLnNsaWNlKDAsIGN1cnJlbnRQYXJ0SW5kZXgpLmpvaW4odGhpcy5kZWxpbWl0ZXJzW2N1cnJlbnRQYXJ0SW5kZXggLSAxXSkgKyAnOic7XG4gICAgICAgIGlucHV0LnZhbHVlID0gbmV3VmFsdWUgKyBwYXJ0cy5zbGljZShjdXJyZW50UGFydEluZGV4KS5qb2luKHRoaXMuZGVsaW1pdGVyc1tjdXJyZW50UGFydEluZGV4XSk7XG5cbiAgICAgICAgaW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3VmFsdWUubGVuZ3RoLCBuZXdWYWx1ZS5sZW5ndGgpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBBTS9QTSBpbnB1dFxuICAgIGlmIChjdXJyZW50Rm9ybWF0WzBdLnRvTG93ZXJDYXNlKCkgPT09ICdhJykge1xuICAgICAgaWYgKCEvXltBYVBwTW1dJC8udGVzdChldmVudC5rZXkpKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgb25seSBkaWdpdHMgZm9yIG90aGVyIHBhcnRzXG4gICAgaWYgKCEvXlxcZCQvLnRlc3QoZXZlbnQua2V5KSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZVBhcnQodmFsdWU6IHN0cmluZywgZm9ybWF0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PT0gJycpIHJldHVybiAnJztcblxuICAgIGNvbnN0IHR5cGUgPSBmb3JtYXRbMF0udG9Mb3dlckNhc2UoKTtcbiAgICBpZiAodHlwZSA9PT0gJ2EnKSB7XG4gICAgICBjb25zdCB1cHBlclZhbHVlID0gdmFsdWUudG9VcHBlckNhc2UoKTtcbiAgICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHVwcGVyVmFsdWUgPT09ICdBJyB8fCB1cHBlclZhbHVlID09PSAnUCcgPyB1cHBlclZhbHVlIDogJyc7XG4gICAgICB9XG4gICAgICByZXR1cm4gWydBTScsICdQTSddLmluY2x1ZGVzKHVwcGVyVmFsdWUpID8gdXBwZXJWYWx1ZSA6IHVwcGVyVmFsdWVbMF07XG4gICAgfVxuXG4gICAgY29uc3QgbnVtVmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnaCc6IC8vIDEyLWhvdXIgZm9ybWF0XG4gICAgICAgIGlmIChmb3JtYXRbMF0gPT0gJ0gnKVxuICAgICAgICAgIHJldHVybiBNYXRoLm1pbihNYXRoLm1heChudW1WYWx1ZSwgMCksIDIzKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG5cbiAgICAgICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG51bVZhbHVlLCAxKSwgMTIpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcblxuICAgICAgY2FzZSAnbSc6IC8vIG1vbnRoIG9yIG1pbnV0ZVxuICAgICAgICBpZiAoZm9ybWF0ID09PSAnTU0nKSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG51bVZhbHVlLCAxKSwgMTIpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgobnVtVmFsdWUsIDApLCA1OSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuXG4gICAgICBjYXNlICdzJzogLy8gc2Vjb25kc1xuICAgICAgICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgobnVtVmFsdWUsIDApLCA1OSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuXG4gICAgICBjYXNlICdkJzogLy8gZGF5XG4gICAgICAgIHJldHVybiBNYXRoLm1pbihNYXRoLm1heChudW1WYWx1ZSwgMSksIDMxKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG5cbiAgICAgIGNhc2UgJ3knOiAvLyB5ZWFyXG4gICAgICAgIGlmIChmb3JtYXQubGVuZ3RoID09PSAyKSByZXR1cm4gdmFsdWUucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlLnBhZFN0YXJ0KDQsICcwJyk7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRQYXJ0TGVuZ3RoKGZvcm1hdDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCB0eXBlID0gZm9ybWF0WzBdLnRvTG93ZXJDYXNlKCk7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICd5JzogcmV0dXJuIGZvcm1hdC5sZW5ndGggPT09IDIgPyAyIDogNDtcbiAgICAgIGNhc2UgJ2EnOiByZXR1cm4gZm9ybWF0Lmxlbmd0aCA9PT0gMSA/IDEgOiAyO1xuICAgICAgZGVmYXVsdDogcmV0dXJuIDI7XG4gICAgfVxuICB9XG5cbiAgZ2V0Q3VycmVudFBhcnRJbmRleCh2YWx1ZTogc3RyaW5nLCBjdXJzb3JQb3NpdGlvbjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXJ0cyA9IHZhbHVlLnNwbGl0KC9bOi9cXHMtXS8pO1xuICAgIGxldCBjdXJyZW50SW5kZXggPSAwO1xuICAgIGxldCB0b3RhbExlbmd0aCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0b3RhbExlbmd0aCArPSBwYXJ0c1tpXS5sZW5ndGg7XG4gICAgICBpZiAoY3Vyc29yUG9zaXRpb24gPD0gdG90YWxMZW5ndGggKyBpKSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgICAgdG90YWxMZW5ndGggKz0gMTsgLy8gQWRkIGRlbGltaXRlciBsZW5ndGhcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMubGVuZ3RoIC0gMTtcbiAgfVxufVxuIl19