ngx-extended-pdf-viewer
Version:
Embedding PDF files in your Angular application. Highly configurable viewer including the toolbar, sidebar, and all the features you're used to.
88 lines • 14.3 kB
JavaScript
export class PdfDocumentPropertiesExtractor {
constructor() {
this.pdfDateStringRegex = new RegExp('^D:' + // Prefix (required)
'(\\d{4})' + // Year (required)
'(\\d{2})?' + // Month (optional)
'(\\d{2})?' + // Day (optional)
'(\\d{2})?' + // Hour (optional)
'(\\d{2})?' + // Minute (optional)
'(\\d{2})?' + // Second (optional)
'([Z|+|-])?' + // Universal time relation (optional)
'(\\d{2})?' + // Offset hour (optional)
// tslint:disable-next-line: quotemark
"'?" + // Splitting apostrophe (optional)
'(\\d{2})?' + // Offset minute (optional)
// tslint:disable-next-line: quotemark
"'?" // Trailing apostrophe (optional)
);
}
async getDocumentProperties() {
const PDFViewerApplication = window.PDFViewerApplication;
const pdfDocument = PDFViewerApplication.pdfDocument;
const result = {};
return pdfDocument
.getMetadata()
.then(({ info, _metadata, contentDispositionFilename }) => {
result.author = info.Author;
result.creationDate = this.toDateObject(info.CreationDate);
result.creator = info.Creator;
result.keywords = info.Keywords;
result.linearized = info.IsLinearized;
result.modificationDate = this.toDateObject(info.ModDate);
result.pdfFormatVersion = info.PDFFormatVersion;
result.producer = info.Producer;
result.subject = info.Subject;
result.title = info.Title;
if (contentDispositionFilename) {
result.fileName = contentDispositionFilename;
}
return pdfDocument.getDownloadInfo();
})
.then(({ length }) => {
result.maybeFileSize = length;
return result;
});
}
/** shamelessly copied from pdf.js */
toDateObject(input) {
// Optional fields that don't satisfy the requirements from the regular
// expression (such as incorrect digit counts or numbers that are out of
// range) will fall back the defaults from the specification.
const matches = this.pdfDateStringRegex.exec(input);
if (!matches) {
return null;
}
// JavaScript's `Date` object expects the month to be between 0 and 11
// instead of 1 and 12, so we have to correct for that.
const year = parseInt(matches[1], 10);
let month = parseInt(matches[2], 10);
month = month >= 1 && month <= 12 ? month - 1 : 0;
let day = parseInt(matches[3], 10);
day = day >= 1 && day <= 31 ? day : 1;
let hour = parseInt(matches[4], 10);
hour = hour >= 0 && hour <= 23 ? hour : 0;
let minute = parseInt(matches[5], 10);
minute = minute >= 0 && minute <= 59 ? minute : 0;
let second = parseInt(matches[6], 10);
second = second >= 0 && second <= 59 ? second : 0;
const universalTimeRelation = matches[7] || 'Z';
let offsetHour = parseInt(matches[8], 10);
offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;
let offsetMinute = parseInt(matches[9], 10) || 0;
offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;
// Universal time relation 'Z' means that the local time is equal to the
// universal time, whereas the relations '+'/'-' indicate that the local
// time is later respectively earlier than the universal time. Every date
// is normalized to universal time.
if (universalTimeRelation === '-') {
hour += offsetHour;
minute += offsetMinute;
}
else if (universalTimeRelation === '+') {
hour -= offsetHour;
minute -= offsetMinute;
}
return new Date(Date.UTC(year, month, day, hour, minute, second));
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGRmLWRvY3VtZW50LXByb3BlcnRpZXMtZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIvc3JjL2xpYi9wZGYtZG9jdW1lbnQtcHJvcGVydGllcy1leHRyYWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBaUJBLE1BQU0sT0FBTyw4QkFBOEI7SUFBM0M7UUFDVSx1QkFBa0IsR0FBRyxJQUFJLE1BQU0sQ0FDckMsS0FBSyxHQUFHLG9CQUFvQjtZQUMxQixVQUFVLEdBQUcsa0JBQWtCO1lBQy9CLFdBQVcsR0FBRyxtQkFBbUI7WUFDakMsV0FBVyxHQUFHLGlCQUFpQjtZQUMvQixXQUFXLEdBQUcsa0JBQWtCO1lBQ2hDLFdBQVcsR0FBRyxvQkFBb0I7WUFDbEMsV0FBVyxHQUFHLG9CQUFvQjtZQUNsQyxZQUFZLEdBQUcscUNBQXFDO1lBQ3BELFdBQVcsR0FBRyx5QkFBeUI7WUFDdkMsc0NBQXNDO1lBQ3RDLElBQUksR0FBRyxrQ0FBa0M7WUFDekMsV0FBVyxHQUFHLDJCQUEyQjtZQUN6QyxzQ0FBc0M7WUFDdEMsSUFBSSxDQUFDLGlDQUFpQztTQUN6QyxDQUFDO0lBMEVKLENBQUM7SUF4RVEsS0FBSyxDQUFDLHFCQUFxQjtRQUNoQyxNQUFNLG9CQUFvQixHQUEyQixNQUFjLENBQUMsb0JBQW9CLENBQUM7UUFDekYsTUFBTSxXQUFXLEdBQUcsb0JBQW9CLENBQUMsV0FBVyxDQUFDO1FBRXJELE1BQU0sTUFBTSxHQUFRLEVBQUUsQ0FBQztRQUN2QixPQUFPLFdBQVc7YUFDZixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsMEJBQTBCLEVBQUUsRUFBRSxFQUFFO1lBQ3hELE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUM1QixNQUFNLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzNELE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUM5QixNQUFNLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDaEMsTUFBTSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQ3RDLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMxRCxNQUFNLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1lBQ2hELE1BQU0sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUNoQyxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDOUIsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQzFCLElBQUksMEJBQTBCLEVBQUU7Z0JBQzlCLE1BQU0sQ0FBQyxRQUFRLEdBQUcsMEJBQTBCLENBQUM7YUFDOUM7WUFDRCxPQUFPLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QyxDQUFDLENBQUM7YUFDRCxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUU7WUFDbkIsTUFBTSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUM7WUFDOUIsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQscUNBQXFDO0lBQzdCLFlBQVksQ0FBQyxLQUFtQjtRQUN0Qyx1RUFBdUU7UUFDdkUsd0VBQXdFO1FBQ3hFLDZEQUE2RDtRQUM3RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDWixPQUFPLElBQUksQ0FBQztTQUNiO1FBRUQsc0VBQXNFO1FBQ3RFLHVEQUF1RDtRQUN2RCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDckMsS0FBSyxHQUFHLEtBQUssSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbkMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEMsSUFBSSxJQUFJLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xELElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdEMsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEQsTUFBTSxxQkFBcUIsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDO1FBQ2hELElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDMUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxDQUFDLElBQUksVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEUsSUFBSSxZQUFZLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakQsWUFBWSxHQUFHLFlBQVksSUFBSSxDQUFDLElBQUksWUFBWSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFMUUsd0VBQXdFO1FBQ3hFLHdFQUF3RTtRQUN4RSx5RUFBeUU7UUFDekUsbUNBQW1DO1FBQ25DLElBQUkscUJBQXFCLEtBQUssR0FBRyxFQUFFO1lBQ2pDLElBQUksSUFBSSxVQUFVLENBQUM7WUFDbkIsTUFBTSxJQUFJLFlBQVksQ0FBQztTQUN4QjthQUFNLElBQUkscUJBQXFCLEtBQUssR0FBRyxFQUFFO1lBQ3hDLElBQUksSUFBSSxVQUFVLENBQUM7WUFDbkIsTUFBTSxJQUFJLFlBQVksQ0FBQztTQUN4QjtRQUVELE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSVBERlZpZXdlckFwcGxpY2F0aW9uIH0gZnJvbSAnLi9vcHRpb25zL3BkZi12aWV3ZXItYXBwbGljYXRpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBkZkRvY3VtZW50SW5mbyB7XG4gIGF1dGhvcj86IHN0cmluZztcbiAgY3JlYXRpb25EYXRlPzogRGF0ZTtcbiAgY3JlYXRvcj86IHN0cmluZztcblxuICBrZXl3b3Jkcz86IHN0cmluZztcbiAgbGluZWFyaXplZD86IGJvb2xlYW47XG4gIG1heWJlRmlsZVNpemU/OiBzdHJpbmc7XG4gIG1vZGlmaWNhdGlvbkRhdGU/OiBEYXRlO1xuICBwZGZGb3JtYXRWZXJzaW9uPzogc3RyaW5nO1xuICBwcm9kdWNlcj86IHN0cmluZztcbiAgc3ViamVjdD86IHN0cmluZztcbiAgdGl0bGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBQZGZEb2N1bWVudFByb3BlcnRpZXNFeHRyYWN0b3Ige1xuICBwcml2YXRlIHBkZkRhdGVTdHJpbmdSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgJ15EOicgKyAvLyBQcmVmaXggKHJlcXVpcmVkKVxuICAgICAgJyhcXFxcZHs0fSknICsgLy8gWWVhciAocmVxdWlyZWQpXG4gICAgICAnKFxcXFxkezJ9KT8nICsgLy8gTW9udGggKG9wdGlvbmFsKVxuICAgICAgJyhcXFxcZHsyfSk/JyArIC8vIERheSAob3B0aW9uYWwpXG4gICAgICAnKFxcXFxkezJ9KT8nICsgLy8gSG91ciAob3B0aW9uYWwpXG4gICAgICAnKFxcXFxkezJ9KT8nICsgLy8gTWludXRlIChvcHRpb25hbClcbiAgICAgICcoXFxcXGR7Mn0pPycgKyAvLyBTZWNvbmQgKG9wdGlvbmFsKVxuICAgICAgJyhbWnwrfC1dKT8nICsgLy8gVW5pdmVyc2FsIHRpbWUgcmVsYXRpb24gKG9wdGlvbmFsKVxuICAgICAgJyhcXFxcZHsyfSk/JyArIC8vIE9mZnNldCBob3VyIChvcHRpb25hbClcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogcXVvdGVtYXJrXG4gICAgICBcIic/XCIgKyAvLyBTcGxpdHRpbmcgYXBvc3Ryb3BoZSAob3B0aW9uYWwpXG4gICAgICAnKFxcXFxkezJ9KT8nICsgLy8gT2Zmc2V0IG1pbnV0ZSAob3B0aW9uYWwpXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IHF1b3RlbWFya1xuICAgICAgXCInP1wiIC8vIFRyYWlsaW5nIGFwb3N0cm9waGUgKG9wdGlvbmFsKVxuICApO1xuXG4gIHB1YmxpYyBhc3luYyBnZXREb2N1bWVudFByb3BlcnRpZXMoKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBkZkRvY3VtZW50ID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmRG9jdW1lbnQ7XG5cbiAgICBjb25zdCByZXN1bHQ6IGFueSA9IHt9O1xuICAgIHJldHVybiBwZGZEb2N1bWVudFxuICAgICAgLmdldE1ldGFkYXRhKClcbiAgICAgIC50aGVuKCh7IGluZm8sIF9tZXRhZGF0YSwgY29udGVudERpc3Bvc2l0aW9uRmlsZW5hbWUgfSkgPT4ge1xuICAgICAgICByZXN1bHQuYXV0aG9yID0gaW5mby5BdXRob3I7XG4gICAgICAgIHJlc3VsdC5jcmVhdGlvbkRhdGUgPSB0aGlzLnRvRGF0ZU9iamVjdChpbmZvLkNyZWF0aW9uRGF0ZSk7XG4gICAgICAgIHJlc3VsdC5jcmVhdG9yID0gaW5mby5DcmVhdG9yO1xuICAgICAgICByZXN1bHQua2V5d29yZHMgPSBpbmZvLktleXdvcmRzO1xuICAgICAgICByZXN1bHQubGluZWFyaXplZCA9IGluZm8uSXNMaW5lYXJpemVkO1xuICAgICAgICByZXN1bHQubW9kaWZpY2F0aW9uRGF0ZSA9IHRoaXMudG9EYXRlT2JqZWN0KGluZm8uTW9kRGF0ZSk7XG4gICAgICAgIHJlc3VsdC5wZGZGb3JtYXRWZXJzaW9uID0gaW5mby5QREZGb3JtYXRWZXJzaW9uO1xuICAgICAgICByZXN1bHQucHJvZHVjZXIgPSBpbmZvLlByb2R1Y2VyO1xuICAgICAgICByZXN1bHQuc3ViamVjdCA9IGluZm8uU3ViamVjdDtcbiAgICAgICAgcmVzdWx0LnRpdGxlID0gaW5mby5UaXRsZTtcbiAgICAgICAgaWYgKGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lKSB7XG4gICAgICAgICAgcmVzdWx0LmZpbGVOYW1lID0gY29udGVudERpc3Bvc2l0aW9uRmlsZW5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBkZkRvY3VtZW50LmdldERvd25sb2FkSW5mbygpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCh7IGxlbmd0aCB9KSA9PiB7XG4gICAgICAgIHJlc3VsdC5tYXliZUZpbGVTaXplID0gbGVuZ3RoO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gIH1cblxuICAvKiogc2hhbWVsZXNzbHkgY29waWVkIGZyb20gcGRmLmpzICovXG4gIHByaXZhdGUgdG9EYXRlT2JqZWN0KGlucHV0OiBzdHJpbmcgfCBhbnkpOiBEYXRlIHwgbnVsbCB7XG4gICAgLy8gT3B0aW9uYWwgZmllbGRzIHRoYXQgZG9uJ3Qgc2F0aXNmeSB0aGUgcmVxdWlyZW1lbnRzIGZyb20gdGhlIHJlZ3VsYXJcbiAgICAvLyBleHByZXNzaW9uIChzdWNoIGFzIGluY29ycmVjdCBkaWdpdCBjb3VudHMgb3IgbnVtYmVycyB0aGF0IGFyZSBvdXQgb2ZcbiAgICAvLyByYW5nZSkgd2lsbCBmYWxsIGJhY2sgdGhlIGRlZmF1bHRzIGZyb20gdGhlIHNwZWNpZmljYXRpb24uXG4gICAgY29uc3QgbWF0Y2hlcyA9IHRoaXMucGRmRGF0ZVN0cmluZ1JlZ2V4LmV4ZWMoaW5wdXQpO1xuICAgIGlmICghbWF0Y2hlcykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSmF2YVNjcmlwdCdzIGBEYXRlYCBvYmplY3QgZXhwZWN0cyB0aGUgbW9udGggdG8gYmUgYmV0d2VlbiAwIGFuZCAxMVxuICAgIC8vIGluc3RlYWQgb2YgMSBhbmQgMTIsIHNvIHdlIGhhdmUgdG8gY29ycmVjdCBmb3IgdGhhdC5cbiAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQobWF0Y2hlc1sxXSwgMTApO1xuICAgIGxldCBtb250aCA9IHBhcnNlSW50KG1hdGNoZXNbMl0sIDEwKTtcbiAgICBtb250aCA9IG1vbnRoID49IDEgJiYgbW9udGggPD0gMTIgPyBtb250aCAtIDEgOiAwO1xuICAgIGxldCBkYXkgPSBwYXJzZUludChtYXRjaGVzWzNdLCAxMCk7XG4gICAgZGF5ID0gZGF5ID49IDEgJiYgZGF5IDw9IDMxID8gZGF5IDogMTtcbiAgICBsZXQgaG91ciA9IHBhcnNlSW50KG1hdGNoZXNbNF0sIDEwKTtcbiAgICBob3VyID0gaG91ciA+PSAwICYmIGhvdXIgPD0gMjMgPyBob3VyIDogMDtcbiAgICBsZXQgbWludXRlID0gcGFyc2VJbnQobWF0Y2hlc1s1XSwgMTApO1xuICAgIG1pbnV0ZSA9IG1pbnV0ZSA+PSAwICYmIG1pbnV0ZSA8PSA1OSA/IG1pbnV0ZSA6IDA7XG4gICAgbGV0IHNlY29uZCA9IHBhcnNlSW50KG1hdGNoZXNbNl0sIDEwKTtcbiAgICBzZWNvbmQgPSBzZWNvbmQgPj0gMCAmJiBzZWNvbmQgPD0gNTkgPyBzZWNvbmQgOiAwO1xuICAgIGNvbnN0IHVuaXZlcnNhbFRpbWVSZWxhdGlvbiA9IG1hdGNoZXNbN10gfHwgJ1onO1xuICAgIGxldCBvZmZzZXRIb3VyID0gcGFyc2VJbnQobWF0Y2hlc1s4XSwgMTApO1xuICAgIG9mZnNldEhvdXIgPSBvZmZzZXRIb3VyID49IDAgJiYgb2Zmc2V0SG91ciA8PSAyMyA/IG9mZnNldEhvdXIgOiAwO1xuICAgIGxldCBvZmZzZXRNaW51dGUgPSBwYXJzZUludChtYXRjaGVzWzldLCAxMCkgfHwgMDtcbiAgICBvZmZzZXRNaW51dGUgPSBvZmZzZXRNaW51dGUgPj0gMCAmJiBvZmZzZXRNaW51dGUgPD0gNTkgPyBvZmZzZXRNaW51dGUgOiAwO1xuXG4gICAgLy8gVW5pdmVyc2FsIHRpbWUgcmVsYXRpb24gJ1onIG1lYW5zIHRoYXQgdGhlIGxvY2FsIHRpbWUgaXMgZXF1YWwgdG8gdGhlXG4gICAgLy8gdW5pdmVyc2FsIHRpbWUsIHdoZXJlYXMgdGhlIHJlbGF0aW9ucyAnKycvJy0nIGluZGljYXRlIHRoYXQgdGhlIGxvY2FsXG4gICAgLy8gdGltZSBpcyBsYXRlciByZXNwZWN0aXZlbHkgZWFybGllciB0aGFuIHRoZSB1bml2ZXJzYWwgdGltZS4gRXZlcnkgZGF0ZVxuICAgIC8vIGlzIG5vcm1hbGl6ZWQgdG8gdW5pdmVyc2FsIHRpbWUuXG4gICAgaWYgKHVuaXZlcnNhbFRpbWVSZWxhdGlvbiA9PT0gJy0nKSB7XG4gICAgICBob3VyICs9IG9mZnNldEhvdXI7XG4gICAgICBtaW51dGUgKz0gb2Zmc2V0TWludXRlO1xuICAgIH0gZWxzZSBpZiAodW5pdmVyc2FsVGltZVJlbGF0aW9uID09PSAnKycpIHtcbiAgICAgIGhvdXIgLT0gb2Zmc2V0SG91cjtcbiAgICAgIG1pbnV0ZSAtPSBvZmZzZXRNaW51dGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kKSk7XG4gIH1cbn1cbiJdfQ==