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.
92 lines • 14.7 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) {
// if (!input || typeof input !== "string")) {
// return null;
// }
// 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGRmLWRvY3VtZW50LXByb3BlcnRpZXMtZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIvc3JjL2xpYi9wZGYtZG9jdW1lbnQtcHJvcGVydGllcy1leHRyYWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBaUJBLE1BQU0sT0FBTyw4QkFBOEI7SUFBM0M7UUFDVSx1QkFBa0IsR0FBRyxJQUFJLE1BQU0sQ0FDckMsS0FBSyxHQUFHLG9CQUFvQjtZQUMxQixVQUFVLEdBQUcsa0JBQWtCO1lBQy9CLFdBQVcsR0FBRyxtQkFBbUI7WUFDakMsV0FBVyxHQUFHLGlCQUFpQjtZQUMvQixXQUFXLEdBQUcsa0JBQWtCO1lBQ2hDLFdBQVcsR0FBRyxvQkFBb0I7WUFDbEMsV0FBVyxHQUFHLG9CQUFvQjtZQUNsQyxZQUFZLEdBQUcscUNBQXFDO1lBQ3BELFdBQVcsR0FBRyx5QkFBeUI7WUFDdkMsc0NBQXNDO1lBQ3RDLElBQUksR0FBRyxrQ0FBa0M7WUFDekMsV0FBVyxHQUFHLDJCQUEyQjtZQUN6QyxzQ0FBc0M7WUFDdEMsSUFBSSxDQUFDLGlDQUFpQztTQUN6QyxDQUFDO0lBbUZKLENBQUM7SUFqRlEsS0FBSyxDQUFDLHFCQUFxQjtRQUNoQyxNQUFNLG9CQUFvQixHQUEyQixNQUFjO2FBQ2hFLG9CQUFvQixDQUFDO1FBQ3hCLE1BQU0sV0FBVyxHQUFHLG9CQUFvQixDQUFDLFdBQVcsQ0FBQztRQUVyRCxNQUFNLE1BQU0sR0FBUSxFQUFFLENBQUM7UUFDdkIsT0FBTyxXQUFXO2FBQ2YsV0FBVyxFQUFFO2FBQ2IsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLDBCQUEwQixFQUFFLEVBQUUsRUFBRTtZQUN2RCxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDNUIsTUFBTSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUNyQyxJQUFJLENBQUMsWUFBWSxDQUNsQixDQUFDO1lBQ0YsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUNoQyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDdEMsTUFBTSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQ3pDLElBQUksQ0FBQyxPQUFPLENBQ2IsQ0FBQztZQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7WUFDaEQsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUM1QixNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDMUIsSUFBSSwwQkFBMEIsRUFBRTtnQkFDOUIsTUFBTSxDQUFDLFFBQVEsR0FBRywwQkFBMEIsQ0FBQzthQUM5QztZQUNELE9BQU8sV0FBVyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRTtZQUNuQixNQUFNLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztZQUM5QixPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxxQ0FBcUM7SUFDN0IsWUFBWSxDQUFDLEtBQW1CO1FBQ3RDLCtDQUErQztRQUMvQyxnQkFBZ0I7UUFDaEIsS0FBSztRQUVMLHVFQUF1RTtRQUN2RSx3RUFBd0U7UUFDeEUsNkRBQTZEO1FBQzdELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNaLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFFRCxzRUFBc0U7UUFDdEUsdURBQXVEO1FBQ3ZELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdEMsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyQyxLQUFLLEdBQUcsS0FBSyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEQsSUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNuQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxJQUFJLElBQUksR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFDLElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdEMsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEQsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN0QyxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCxNQUFNLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUM7UUFDaEQsSUFBSSxVQUFVLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxQyxVQUFVLEdBQUcsVUFBVSxJQUFJLENBQUMsSUFBSSxVQUFVLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRSxJQUFJLFlBQVksR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxZQUFZLEdBQUcsWUFBWSxJQUFJLENBQUMsSUFBSSxZQUFZLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUxRSx3RUFBd0U7UUFDeEUsd0VBQXdFO1FBQ3hFLHlFQUF5RTtRQUN6RSxtQ0FBbUM7UUFDbkMsSUFBSSxxQkFBcUIsS0FBSyxHQUFHLEVBQUU7WUFDakMsSUFBSSxJQUFJLFVBQVUsQ0FBQztZQUNuQixNQUFNLElBQUksWUFBWSxDQUFDO1NBQ3hCO2FBQU0sSUFBSSxxQkFBcUIsS0FBSyxHQUFHLEVBQUU7WUFDeEMsSUFBSSxJQUFJLFVBQVUsQ0FBQztZQUNuQixNQUFNLElBQUksWUFBWSxDQUFDO1NBQ3hCO1FBRUQsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJUERGVmlld2VyQXBwbGljYXRpb24gfSBmcm9tICcuL29wdGlvbnMvcGRmLXZpZXdlci1hcHBsaWNhdGlvbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGRmRG9jdW1lbnRJbmZvIHtcbiAgYXV0aG9yPzogc3RyaW5nO1xuICBjcmVhdGlvbkRhdGU/OiBEYXRlO1xuICBjcmVhdG9yPzogc3RyaW5nO1xuXG4gIGtleXdvcmRzPzogc3RyaW5nO1xuICBsaW5lYXJpemVkPzogYm9vbGVhbjtcbiAgbWF5YmVGaWxlU2l6ZT86IHN0cmluZztcbiAgbW9kaWZpY2F0aW9uRGF0ZT86IERhdGU7XG4gIHBkZkZvcm1hdFZlcnNpb24/OiBzdHJpbmc7XG4gIHByb2R1Y2VyPzogc3RyaW5nO1xuICBzdWJqZWN0Pzogc3RyaW5nO1xuICB0aXRsZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFBkZkRvY3VtZW50UHJvcGVydGllc0V4dHJhY3RvciB7XG4gIHByaXZhdGUgcGRmRGF0ZVN0cmluZ1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAnXkQ6JyArIC8vIFByZWZpeCAocmVxdWlyZWQpXG4gICAgICAnKFxcXFxkezR9KScgKyAvLyBZZWFyIChyZXF1aXJlZClcbiAgICAgICcoXFxcXGR7Mn0pPycgKyAvLyBNb250aCAob3B0aW9uYWwpXG4gICAgICAnKFxcXFxkezJ9KT8nICsgLy8gRGF5IChvcHRpb25hbClcbiAgICAgICcoXFxcXGR7Mn0pPycgKyAvLyBIb3VyIChvcHRpb25hbClcbiAgICAgICcoXFxcXGR7Mn0pPycgKyAvLyBNaW51dGUgKG9wdGlvbmFsKVxuICAgICAgJyhcXFxcZHsyfSk/JyArIC8vIFNlY29uZCAob3B0aW9uYWwpXG4gICAgICAnKFtafCt8LV0pPycgKyAvLyBVbml2ZXJzYWwgdGltZSByZWxhdGlvbiAob3B0aW9uYWwpXG4gICAgICAnKFxcXFxkezJ9KT8nICsgLy8gT2Zmc2V0IGhvdXIgKG9wdGlvbmFsKVxuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBxdW90ZW1hcmtcbiAgICAgIFwiJz9cIiArIC8vIFNwbGl0dGluZyBhcG9zdHJvcGhlIChvcHRpb25hbClcbiAgICAgICcoXFxcXGR7Mn0pPycgKyAvLyBPZmZzZXQgbWludXRlIChvcHRpb25hbClcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogcXVvdGVtYXJrXG4gICAgICBcIic/XCIgLy8gVHJhaWxpbmcgYXBvc3Ryb3BoZSAob3B0aW9uYWwpXG4gICk7XG5cbiAgcHVibGljIGFzeW5jIGdldERvY3VtZW50UHJvcGVydGllcygpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSlcbiAgICAgIC5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBjb25zdCBwZGZEb2N1bWVudCA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZkRvY3VtZW50O1xuXG4gICAgY29uc3QgcmVzdWx0OiBhbnkgPSB7fTtcbiAgICByZXR1cm4gcGRmRG9jdW1lbnRcbiAgICAgIC5nZXRNZXRhZGF0YSgpXG4gICAgICAudGhlbigoeyBpbmZvLCBtZXRhZGF0YSwgY29udGVudERpc3Bvc2l0aW9uRmlsZW5hbWUgfSkgPT4ge1xuICAgICAgICByZXN1bHQuYXV0aG9yID0gaW5mby5BdXRob3I7XG4gICAgICAgIHJlc3VsdC5jcmVhdGlvbkRhdGUgPSB0aGlzLnRvRGF0ZU9iamVjdChcbiAgICAgICAgICBpbmZvLkNyZWF0aW9uRGF0ZVxuICAgICAgICApO1xuICAgICAgICByZXN1bHQuY3JlYXRvciA9IGluZm8uQ3JlYXRvcjtcbiAgICAgICAgcmVzdWx0LmtleXdvcmRzID0gaW5mby5LZXl3b3JkcztcbiAgICAgICAgcmVzdWx0LmxpbmVhcml6ZWQgPSBpbmZvLklzTGluZWFyaXplZDtcbiAgICAgICAgcmVzdWx0Lm1vZGlmaWNhdGlvbkRhdGUgPSB0aGlzLnRvRGF0ZU9iamVjdChcbiAgICAgICAgICBpbmZvLk1vZERhdGVcbiAgICAgICAgKTtcbiAgICAgICAgcmVzdWx0LnBkZkZvcm1hdFZlcnNpb24gPSBpbmZvLlBERkZvcm1hdFZlcnNpb247XG4gICAgICAgIHJlc3VsdC5wcm9kdWNlciA9IGluZm8uUHJvZHVjZXI7XG4gICAgICByZXN1bHQuc3ViamVjdCA9IGluZm8uU3ViamVjdDtcbiAgICAgICAgcmVzdWx0LnRpdGxlID0gaW5mby5UaXRsZTtcbiAgICAgICAgaWYgKGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lKSB7XG4gICAgICAgICAgcmVzdWx0LmZpbGVOYW1lID0gY29udGVudERpc3Bvc2l0aW9uRmlsZW5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBkZkRvY3VtZW50LmdldERvd25sb2FkSW5mbygpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCh7IGxlbmd0aCB9KSA9PiB7XG4gICAgICAgIHJlc3VsdC5tYXliZUZpbGVTaXplID0gbGVuZ3RoO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gIH1cblxuICAvKiogc2hhbWVsZXNzbHkgY29waWVkIGZyb20gcGRmLmpzICovXG4gIHByaXZhdGUgdG9EYXRlT2JqZWN0KGlucHV0OiBzdHJpbmcgfCBhbnkpOiBEYXRlIHwgbnVsbCB7XG4gICAgLy8gaWYgKCFpbnB1dCB8fCAgdHlwZW9mIGlucHV0ICE9PSBcInN0cmluZ1wiKSkge1xuICAgIC8vICByZXR1cm4gbnVsbDtcbiAgICAvLyAgfVxuXG4gICAgLy8gT3B0aW9uYWwgZmllbGRzIHRoYXQgZG9uJ3Qgc2F0aXNmeSB0aGUgcmVxdWlyZW1lbnRzIGZyb20gdGhlIHJlZ3VsYXJcbiAgICAvLyBleHByZXNzaW9uIChzdWNoIGFzIGluY29ycmVjdCBkaWdpdCBjb3VudHMgb3IgbnVtYmVycyB0aGF0IGFyZSBvdXQgb2ZcbiAgICAvLyByYW5nZSkgd2lsbCBmYWxsIGJhY2sgdGhlIGRlZmF1bHRzIGZyb20gdGhlIHNwZWNpZmljYXRpb24uXG4gICAgY29uc3QgbWF0Y2hlcyA9IHRoaXMucGRmRGF0ZVN0cmluZ1JlZ2V4LmV4ZWMoaW5wdXQpO1xuICAgIGlmICghbWF0Y2hlcykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSmF2YVNjcmlwdCdzIGBEYXRlYCBvYmplY3QgZXhwZWN0cyB0aGUgbW9udGggdG8gYmUgYmV0d2VlbiAwIGFuZCAxMVxuICAgIC8vIGluc3RlYWQgb2YgMSBhbmQgMTIsIHNvIHdlIGhhdmUgdG8gY29ycmVjdCBmb3IgdGhhdC5cbiAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQobWF0Y2hlc1sxXSwgMTApO1xuICAgIGxldCBtb250aCA9IHBhcnNlSW50KG1hdGNoZXNbMl0sIDEwKTtcbiAgICBtb250aCA9IG1vbnRoID49IDEgJiYgbW9udGggPD0gMTIgPyBtb250aCAtIDEgOiAwO1xuICAgIGxldCBkYXkgPSBwYXJzZUludChtYXRjaGVzWzNdLCAxMCk7XG4gICAgZGF5ID0gZGF5ID49IDEgJiYgZGF5IDw9IDMxID8gZGF5IDogMTtcbiAgICBsZXQgaG91ciA9IHBhcnNlSW50KG1hdGNoZXNbNF0sIDEwKTtcbiAgICBob3VyID0gaG91ciA+PSAwICYmIGhvdXIgPD0gMjMgPyBob3VyIDogMDtcbiAgICBsZXQgbWludXRlID0gcGFyc2VJbnQobWF0Y2hlc1s1XSwgMTApO1xuICAgIG1pbnV0ZSA9IG1pbnV0ZSA+PSAwICYmIG1pbnV0ZSA8PSA1OSA/IG1pbnV0ZSA6IDA7XG4gICAgbGV0IHNlY29uZCA9IHBhcnNlSW50KG1hdGNoZXNbNl0sIDEwKTtcbiAgICBzZWNvbmQgPSBzZWNvbmQgPj0gMCAmJiBzZWNvbmQgPD0gNTkgPyBzZWNvbmQgOiAwO1xuICAgIGNvbnN0IHVuaXZlcnNhbFRpbWVSZWxhdGlvbiA9IG1hdGNoZXNbN10gfHwgJ1onO1xuICAgIGxldCBvZmZzZXRIb3VyID0gcGFyc2VJbnQobWF0Y2hlc1s4XSwgMTApO1xuICAgIG9mZnNldEhvdXIgPSBvZmZzZXRIb3VyID49IDAgJiYgb2Zmc2V0SG91ciA8PSAyMyA/IG9mZnNldEhvdXIgOiAwO1xuICAgIGxldCBvZmZzZXRNaW51dGUgPSBwYXJzZUludChtYXRjaGVzWzldLCAxMCkgfHwgMDtcbiAgICBvZmZzZXRNaW51dGUgPSBvZmZzZXRNaW51dGUgPj0gMCAmJiBvZmZzZXRNaW51dGUgPD0gNTkgPyBvZmZzZXRNaW51dGUgOiAwO1xuXG4gICAgLy8gVW5pdmVyc2FsIHRpbWUgcmVsYXRpb24gJ1onIG1lYW5zIHRoYXQgdGhlIGxvY2FsIHRpbWUgaXMgZXF1YWwgdG8gdGhlXG4gICAgLy8gdW5pdmVyc2FsIHRpbWUsIHdoZXJlYXMgdGhlIHJlbGF0aW9ucyAnKycvJy0nIGluZGljYXRlIHRoYXQgdGhlIGxvY2FsXG4gICAgLy8gdGltZSBpcyBsYXRlciByZXNwZWN0aXZlbHkgZWFybGllciB0aGFuIHRoZSB1bml2ZXJzYWwgdGltZS4gRXZlcnkgZGF0ZVxuICAgIC8vIGlzIG5vcm1hbGl6ZWQgdG8gdW5pdmVyc2FsIHRpbWUuXG4gICAgaWYgKHVuaXZlcnNhbFRpbWVSZWxhdGlvbiA9PT0gJy0nKSB7XG4gICAgICBob3VyICs9IG9mZnNldEhvdXI7XG4gICAgICBtaW51dGUgKz0gb2Zmc2V0TWludXRlO1xuICAgIH0gZWxzZSBpZiAodW5pdmVyc2FsVGltZVJlbGF0aW9uID09PSAnKycpIHtcbiAgICAgIGhvdXIgLT0gb2Zmc2V0SG91cjtcbiAgICAgIG1pbnV0ZSAtPSBvZmZzZXRNaW51dGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kKSk7XG4gIH1cbn1cbiJdfQ==