UNPKG

@senx/warpview

Version:
381 lines 47.4 kB
/* * Copyright 2021 SenX S.A.S. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { DataModel } from '../model/dataModel'; import { Logger } from './logger'; import moment from 'moment-timezone'; import { JsonLib } from './jsonLib'; // @dynamic export class GTSLib { static cleanArray(actual) { return actual.filter((i) => !!i); } static unique(arr) { const u = {}; const a = []; for (let i = 0, l = arr.length; i < l; ++i) { if (!u.hasOwnProperty(arr[i])) { a.push(arr[i]); u[arr[i]] = 1; } } return a; } static isArray(value) { return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length')); } static formatElapsedTime(elapsed) { if (elapsed < 1000) { return elapsed.toFixed(3) + ' ns'; } if (elapsed < 1000000) { return (elapsed / 1000).toFixed(3) + ' μs'; } if (elapsed < 1000000000) { return (elapsed / 1000000).toFixed(3) + ' ms'; } if (elapsed < 1000000000000) { return (elapsed / 1000000000).toFixed(3) + ' s '; } // Max exec time for nice output: 999.999 minutes (should be OK, timeout should happen before that). return (elapsed / 60000000000).toFixed(3) + ' m '; } static isValidResponse(data) { let response; try { response = new JsonLib().parse(data); } catch (e) { this.LOG.error(['isValidResponse'], 'Response non JSON compliant', data); return false; } if (!GTSLib.isArray(response)) { this.LOG.error(['isValidResponse'], 'Response isn\'t an Array', response); return false; } return true; } static isEmbeddedImage(item) { return !(typeof item !== 'string' || !/^data:image/.test(item)); } static isEmbeddedImageObject(item) { return !((item === null) || (item.image === null) || (item.caption === null) || !GTSLib.isEmbeddedImage(item.image)); } static isPositionArray(item) { if (!item || !item.positions) { return false; } if (GTSLib.isPositionsArrayWithValues(item) || GTSLib.isPositionsArrayWithTwoValues(item)) { return true; } (item.positions || []).forEach(p => { if (p.length < 2 || p.length > 3) { return false; } for (const j in p) { if (typeof p[j] !== 'number') { return false; } } }); return true; } static isPositionsArrayWithValues(item) { if ((item === null) || (item.positions === null)) { return false; } (item.positions || []).forEach(p => { if (p.length !== 3) { return false; } for (const j in p) { if (typeof p[j] !== 'number') { return false; } } }); return true; } static isPositionsArrayWithTwoValues(item) { if ((item === null) || (item.positions === null)) { return false; } (item.positions || []).forEach(p => { if (p.length !== 4) { return false; } for (const j in p) { if (typeof p[j] !== 'number') { return false; } } }); return true; } static gtsFromJSON(json, id) { return { gts: { c: json.c, l: json.l, a: json.a, v: json.v, id } }; } static uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { // tslint:disable-next-line:no-bitwise const r = Math.random() * 16 | 0; // tslint:disable-next-line:no-bitwise const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } static gtsFromJSONList(jsonList, prefixId) { const gtsList = []; let id; (jsonList || []).forEach((item, i) => { let gts = item; if (item.gts) { gts = item.gts; } if ((prefixId !== undefined) && (prefixId !== '')) { id = prefixId + '-' + i; } else { id = i; } if (GTSLib.isArray(gts)) { gtsList.push(GTSLib.gtsFromJSONList(gts, id)); } if (GTSLib.isGts(gts)) { gtsList.push(GTSLib.gtsFromJSON(gts, id)); } if (GTSLib.isEmbeddedImage(gts)) { gtsList.push({ image: gts, caption: 'Image', id }); } if (GTSLib.isEmbeddedImageObject(gts)) { gtsList.push({ image: gts.image, caption: gts.caption, id }); } }); return { content: gtsList || [], }; } static flatDeep(arrays) { const result = []; if (!GTSLib.isArray(arrays)) { arrays = [arrays]; } GTSLib.flatten(arrays, result); return result; } static flatten(arr, result = []) { const size = arr.length; for (let i = 0; i < size; i++) { const value = arr[i]; if (Array.isArray(value)) { GTSLib.flatten(value, result); } else { result.push(value); } } return result; } static flattenGtsIdArray(a, r) { const res = []; if (GTSLib.isGts(a)) { a = [a]; } (a || []).forEach(d => { if (GTSLib.isArray(d)) { const walk = GTSLib.flattenGtsIdArray(d, r); res.push(walk.res); r = walk.r; } else if (d && d.v) { d.id = r; res.push(d); r++; } }); return { res, r }; } static sanitizeNames(input) { return (input || '').replace(/{/g, '&#123;') .replace(/}/g, '&#125;') .replace(/,/g, '&#44;') .replace(/>/g, '&#62;') .replace(/</g, '&#60;') .replace(/"/g, '&#34;') .replace(/'/g, '&#39;'); } static serializeGtsMetadata(gts) { const serializedLabels = []; const serializedAttributes = []; if (gts.l) { Object.keys(gts.l).forEach((key) => { serializedLabels.push(this.sanitizeNames(key + '=' + gts.l[key])); }); } if (gts.a) { Object.keys(gts.a).forEach((key) => { serializedAttributes.push(this.sanitizeNames(key + '=' + gts.a[key])); }); } // tslint:disable-next-line:max-line-length return `${this.sanitizeNames(gts.c)}{${serializedLabels.join(',')}${serializedAttributes.length > 0 ? ',' : ''}${serializedAttributes.join(',')}}`; } static isGts(item) { return !!item && (item.c === '' || !!item.c) && !!item.v && GTSLib.isArray(item.v); } static isGtsToPlot(gts) { if (!GTSLib.isGts(gts) || gts.v.length === 0) { return false; } // We look at the first non-null value, if it's a String or Boolean it's an annotation GTS, // if it's a number it's a GTS to plot return (gts.v || []).some(v => { // noinspection JSPotentiallyInvalidConstructorUsage return typeof v[v.length - 1] === 'number' || !!v[v.length - 1].constructor.prototype.toFixed; }); } static isGtsToPlotOnMap(gts) { if (!GTSLib.isGts(gts) || gts.v.length === 0) { return false; } // We look at the first non-null value, if it's a String or Boolean it's an annotation GTS, // if it's a number it's a GTS to plot return (gts.v || []).some(v => { return v.length >= 3; }); } static isSingletonGTS(gts) { if (!GTSLib.isGts(gts) || gts.v.length === 0) { return false; } return (gts.v || []).length === 1; } static isGtsToAnnotate(gts) { if (!GTSLib.isGts(gts) || gts.v.length === 0) { return false; } // We look at the first non-null value, if it's a String or Boolean it's an annotation GTS, // if it's a number it's a GTS to plot return (gts.v || []).some(v => { if (v[v.length - 1] !== null) { // noinspection JSPotentiallyInvalidConstructorUsage return typeof (v[v.length - 1]) !== 'number' && (!!v[v.length - 1].constructor && v[v.length - 1].constructor.name !== 'Big') && v[v.length - 1].constructor.prototype.toFixed === undefined; } }); } static gtsSort(gts) { if (gts.isSorted) { return; } gts.v = gts.v.sort((a, b) => a[0] - b[0]); gts.isSorted = true; } static getData(data) { if (typeof data === 'string') { if (data.startsWith('[') || data.startsWith('{')) { return GTSLib.getData(new JsonLib().parse(data)); } else { return { data: new JsonLib().parse(`[${data}]`) }; } } else if (data && data.hasOwnProperty('data')) { if (!GTSLib.isArray(data.data)) { data.data = [data.data]; } return data; } else if (GTSLib.isArray(data) && data.length > 0 && data[0].data) { return data[0]; } else if (GTSLib.isArray(data)) { return { data: data }; } return new DataModel(); } static getDivider(timeUnit) { let timestampDivider = 1000; // default for µs timeunit if (timeUnit === 'ms') { timestampDivider = 1; } if (timeUnit === 'ns') { timestampDivider = 1000000; } return timestampDivider; } static formatLabel(data) { const serializedGTS = data.split('{'); let display = `<span class="gtsInfo"><span class='gts-classname'>${serializedGTS[0]}</span>`; if (serializedGTS.length > 1) { display += `<span class='gts-separator'>{</span>`; const labels = serializedGTS[1].substr(0, serializedGTS[1].length - 1).split(','); if (labels.length > 0) { labels.forEach((l, i) => { const label = l.split('='); if (l.length > 1) { display += `<span><span class='gts-labelname'>${label[0]}</span> <span class='gts-separator'>=</span><span class='gts-labelvalue'>${label[1]}</span>`; if (i !== labels.length - 1) { display += `<span>, </span>`; } } }); } display += `<span class='gts-separator'>}</span>`; } if (serializedGTS.length > 2) { display += `<span class='gts-separator'>{</span>`; const labels = serializedGTS[2].substr(0, serializedGTS[2].length - 1).split(','); if (labels.length > 0) { labels.forEach((l, i) => { const label = l.split('='); if (l.length > 1) { display += `<span><span class='gts-attrname'>${label[0]}</span> <span class='gts-separator'>=</span><span class='gts-attrvalue'>${label[1]}</span>`; if (i !== labels.length - 1) { display += `<span>, </span>`; } } }); } display += `<span class='gts-separator'>}</span>`; } display += '</span>'; return display; } static toISOString(timestamp, divider, timeZone) { if (timeZone !== 'UTC') { return moment.tz(timestamp / divider, timeZone).format(); } else { return moment.utc(timestamp / divider).toISOString(); } } static toTimestamp(date, divider, timeZone) { if (timeZone !== 'UTC') { return moment.tz(date, timeZone).utc().valueOf() * divider; } else { return moment.utc(date).valueOf() * divider; } } } GTSLib.LOG = new Logger(GTSLib); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3RzLmxpYi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcnB2aWV3LW5nL3NyYy9saWIvdXRpbHMvZ3RzLmxpYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFFN0MsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUNyQyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBRWxDLFdBQVc7QUFDWCxNQUFNLE9BQU8sTUFBTTtJQUdqQixNQUFNLENBQUMsVUFBVSxDQUFDLE1BQWE7UUFDN0IsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRztRQUNmLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNiLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUU7WUFDMUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQzdCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2YsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNmO1NBQ0Y7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCxN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RTs0QkFDM0IsT0FBTyxJQUFJLGlCQUFpQixDQUFDO3lCQUM5QjtxQkFDRjtnQkFDSCxDQUFDLENBQUMsQ0FBQzthQUNKO1lBQ0QsT0FBTyxJQUFJLHNDQUFzQyxDQUFDO1NBQ25EO1FBQ0QsT0FBTyxJQUFJLFNBQVMsQ0FBQztRQUNyQixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFpQixFQUFFLE9BQWUsRUFBRSxRQUFnQjtRQUNyRSxJQUFJLFFBQVEsS0FBSyxLQUFLLEVBQUU7WUFDdEIsT0FBTyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsR0FBRyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDMUQ7YUFBTTtZQUNMLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDdEQ7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFZLEVBQUUsT0FBZSxFQUFFLFFBQWdCO1FBQ2hFLElBQUksUUFBUSxLQUFLLEtBQUssRUFBRTtZQUN0QixPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQztTQUM1RDthQUFNO1lBQ0wsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQztTQUM3QztJQUNILENBQUM7O0FBdlhjLFVBQUcsR0FBVyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiAgQ29weXJpZ2h0IDIwMjEgIFNlblggUy5BLlMuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHtEYXRhTW9kZWx9IGZyb20gJy4uL21vZGVsL2RhdGFNb2RlbCc7XG5pbXBvcnQge0dUU30gZnJvbSAnLi4vbW9kZWwvR1RTJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudC10aW1lem9uZSc7XG5pbXBvcnQge0pzb25MaWJ9IGZyb20gJy4vanNvbkxpYic7XG5cbi8vIEBkeW5hbWljXG5leHBvcnQgY2xhc3MgR1RTTGliIHtcbiAgcHJpdmF0ZSBzdGF0aWMgTE9HOiBMb2dnZXIgPSBuZXcgTG9nZ2VyKEdUU0xpYik7XG5cbiAgc3RhdGljIGNsZWFuQXJyYXkoYWN0dWFsOiBhbnlbXSkge1xuICAgIHJldHVybiBhY3R1YWwuZmlsdGVyKChpKSA9PiAhIWkpO1xuICB9XG5cbiAgc3RhdGljIHVuaXF1ZShhcnIpIHtcbiAgICBjb25zdCB1ID0ge307XG4gICAgY29uc3QgYSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwLCBsID0gYXJyLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgaWYgKCF1Lmhhc093blByb3BlcnR5KGFycltpXSkpIHtcbiAgICAgICAgYS5wdXNoKGFycltpXSk7XG4gICAgICAgIHVbYXJyW2ldXSA9IDE7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhO1xuICB9XG5cbiAgc3RhdGljIGlzQXJyYXkodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIHR5cGVvZiB2YWx1ZS5sZW5ndGggPT09ICdudW1iZXInXG4gICAgICAmJiB0eXBlb2YgdmFsdWUuc3BsaWNlID09PSAnZnVuY3Rpb24nICYmICEodmFsdWUucHJvcGVydHlJc0VudW1lcmFibGUoJ2xlbmd0aCcpKTtcbiAgfVxuXG4gIHN0YXRpYyBmb3JtYXRFbGFwc2VkVGltZShlbGFwc2VkOiBudW1iZXIpIHtcbiAgICBpZiAoZWxhcHNlZCA8IDEwMDApIHtcbiAgICAgIHJldHVybiBlbGFwc2VkLnRvRml4ZWQoMykgKyAnIG5zJztcbiAgICB9XG4gICAgaWYgKGVsYXBzZWQgPCAxMDAwMDAwKSB7XG4gICAgICByZXR1cm4gKGVsYXBzZWQgLyAxMDAwKS50b0ZpeGVkKDMpICsgJyDOvHMnO1xuICAgIH1cbiAgICBpZiAoZWxhcHNlZCA8IDEwMDAwMDAwMDApIHtcbiAgICAgIHJldHVybiAoZWxhcHNlZCAvIDEwMDAwMDApLnRvRml4ZWQoMykgKyAnIG1zJztcbiAgICB9XG4gICAgaWYgKGVsYXBzZWQgPCAxMDAwMDAwMDAwMDAwKSB7XG4gICAgICByZXR1cm4gKGVsYXBzZWQgLyAxMDAwMDAwMDAwKS50b0ZpeGVkKDMpICsgJyBzICc7XG4gICAgfVxuICAgIC8vIE1heCBleGVjIHRpbWUgZm9yIG5pY2Ugb3V0cHV0OiA5OTkuOTk5IG1pbnV0ZXMgKHNob3VsZCBiZSBPSywgdGltZW91dCBzaG91bGQgaGFwcGVuIGJlZm9yZSB0aGF0KS5cbiAgICByZXR1cm4gKGVsYXBzZWQgLyA2MDAwMDAwMDAwMCkudG9GaXhlZCgzKSArICcgbSAnO1xuICB9XG5cbiAgc3RhdGljIGlzVmFsaWRSZXNwb25zZShkYXRhKSB7XG4gICAgbGV0IHJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICByZXNwb25zZSA9IG5ldyBKc29uTGliKCkucGFyc2UoZGF0YSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5MT0cuZXJyb3IoWydpc1ZhbGlkUmVzcG9uc2UnXSwgJ1Jlc3BvbnNlIG5vbiBKU09OIGNvbXBsaWFudCcsIGRhdGEpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIUdUU0xpYi5pc0FycmF5KHJlc3BvbnNlKSkge1xuICAgICAgdGhpcy5MT0cuZXJyb3IoWydpc1ZhbGlkUmVzcG9uc2UnXSwgJ1Jlc3BvbnNlIGlzblxcJ3QgYW4gQXJyYXknLCByZXNwb25zZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3RhdGljIGlzRW1iZWRkZWRJbWFnZShpdGVtKSB7XG4gICAgcmV0dXJuICEodHlwZW9mIGl0ZW0gIT09ICdzdHJpbmcnIHx8ICEvXmRhdGE6aW1hZ2UvLnRlc3QoaXRlbSkpO1xuICB9XG5cbiAgc3RhdGljIGlzRW1iZWRkZWRJbWFnZU9iamVjdChpdGVtKSB7XG4gICAgcmV0dXJuICEoKGl0ZW0gPT09IG51bGwpIHx8IChpdGVtLmltYWdlID09PSBudWxsKSB8fFxuICAgICAgKGl0ZW0uY2FwdGlvbiA9PT0gbnVsbCkgfHwgIUdUU0xpYi5pc0VtYmVkZGVkSW1hZ2UoaXRlbS5pbWFnZSkpO1xuICB9XG5cbiAgc3RhdGljIGlzUG9zaXRpb25BcnJheShpdGVtKSB7XG4gICAgaWYgKCFpdGVtIHx8ICFpdGVtLnBvc2l0aW9ucykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoR1RTTGliLmlzUG9zaXRpb25zQXJyYXlXaXRoVmFsdWVzKGl0ZW0pIHx8IEdUU0xpYi5pc1Bvc2l0aW9uc0FycmF5V2l0aFR3b1ZhbHVlcyhpdGVtKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIChpdGVtLnBvc2l0aW9ucyB8fCBbXSkuZm9yRWFjaChwID0+IHtcbiAgICAgIGlmIChwLmxlbmd0aCA8IDIgfHwgcC5sZW5ndGggPiAzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgaiBpbiBwKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcFtqXSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBpc1Bvc2l0aW9uc0FycmF5V2l0aFZhbHVlcyhpdGVtKSB7XG4gICAgaWYgKChpdGVtID09PSBudWxsKSB8fCAoaXRlbS5wb3NpdGlvbnMgPT09IG51bGwpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIChpdGVtLnBvc2l0aW9ucyB8fCBbXSkuZm9yRWFjaChwID0+IHtcbiAgICAgIGlmIChwLmxlbmd0aCAhPT0gMykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGogaW4gcCkge1xuICAgICAgICBpZiAodHlwZW9mIHBbal0gIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0aWMgaXNQb3NpdGlvbnNBcnJheVdpdGhUd29WYWx1ZXMoaXRlbSkge1xuICAgIGlmICgoaXRlbSA9PT0gbnVsbCkgfHwgKGl0ZW0ucG9zaXRpb25zID09PSBudWxsKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAoaXRlbS5wb3NpdGlvbnMgfHwgW10pLmZvckVhY2gocCA9PiB7XG4gICAgICBpZiAocC5sZW5ndGggIT09IDQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBqIGluIHApIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwW2pdICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3RhdGljIGd0c0Zyb21KU09OKGpzb24sIGlkKSB7XG4gICAgcmV0dXJuIHtndHM6IHtjOiBqc29uLmMsIGw6IGpzb24ubCwgYToganNvbi5hLCB2OiBqc29uLnYsIGlkfX07XG4gIH1cblxuICBzdGF0aWMgdXVpZHY0KCkge1xuICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGMgPT4ge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgIGNvbnN0IHIgPSBNYXRoLnJhbmRvbSgpICogMTYgfCAwO1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgIGNvbnN0IHYgPSBjID09PSAneCcgPyByIDogKHIgJiAweDMgfCAweDgpO1xuICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGd0c0Zyb21KU09OTGlzdChqc29uTGlzdCwgcHJlZml4SWQpIHtcbiAgICBjb25zdCBndHNMaXN0ID0gW107XG4gICAgbGV0IGlkO1xuICAgIChqc29uTGlzdCB8fCBbXSkuZm9yRWFjaCgoaXRlbSwgaSkgPT4ge1xuICAgICAgbGV0IGd0cyA9IGl0ZW07XG4gICAgICBpZiAoaXRlbS5ndHMpIHtcbiAgICAgICAgZ3RzID0gaXRlbS5ndHM7XG4gICAgICB9XG4gICAgICBpZiAoKHByZWZpeElkICE9PSB1bmRlZmluZWQpICYmIChwcmVmaXhJZCAhPT0gJycpKSB7XG4gICAgICAgIGlkID0gcHJlZml4SWQgKyAnLScgKyBpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWQgPSBpO1xuICAgICAgfVxuICAgICAgaWYgKEdUU0xpYi5pc0FycmF5KGd0cykpIHtcbiAgICAgICAgZ3RzTGlzdC5wdXNoKEdUU0xpYi5ndHNGcm9tSlNPTkxpc3QoZ3RzLCBpZCkpO1xuICAgICAgfVxuICAgICAgaWYgKEdUU0xpYi5pc0d0cyhndHMpKSB7XG4gICAgICAgIGd0c0xpc3QucHVzaChHVFNMaWIuZ3RzRnJvbUpTT04oZ3RzLCBpZCkpO1xuICAgICAgfVxuICAgICAgaWYgKEdUU0xpYi5pc0VtYmVkZGVkSW1hZ2UoZ3RzKSkge1xuICAgICAgICBndHNMaXN0LnB1c2goe2ltYWdlOiBndHMsIGNhcHRpb246ICdJbWFnZScsIGlkfSk7XG4gICAgICB9XG4gICAgICBpZiAoR1RTTGliLmlzRW1iZWRkZWRJbWFnZU9iamVjdChndHMpKSB7XG4gICAgICAgIGd0c0xpc3QucHVzaCh7aW1hZ2U6IGd0cy5pbWFnZSwgY2FwdGlvbjogZ3RzLmNhcHRpb24sIGlkfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IGd0c0xpc3QgfHwgW10sXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBmbGF0RGVlcChhcnJheXM6IGFueVtdKTogYW55W10ge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGlmICghR1RTTGliLmlzQXJyYXkoYXJyYXlzKSkge1xuICAgICAgYXJyYXlzID0gW2FycmF5c107XG4gICAgfVxuICAgIEdUU0xpYi5mbGF0dGVuKGFycmF5cywgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIGZsYXR0ZW4oYXJyLCByZXN1bHQgPSBbXSkge1xuICAgIGNvbnN0IHNpemUgPSBhcnIubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGFycltpXTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBHVFNMaWIuZmxhdHRlbih2YWx1ZSwgcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHN0YXRpYyBmbGF0dGVuR3RzSWRBcnJheShhOiBhbnlbXSwgcjogbnVtYmVyKTogeyByZXM6IGFueVtdLCByOiBudW1iZXIgfSB7XG4gICAgY29uc3QgcmVzID0gW107XG4gICAgaWYgKEdUU0xpYi5pc0d0cyhhKSkge1xuICAgICAgYSA9IFthXTtcbiAgICB9XG4gICAgKGEgfHwgW10pLmZvckVhY2goZCA9PiB7XG4gICAgICBpZiAoR1RTTGliLmlzQXJyYXkoZCkpIHtcbiAgICAgICAgY29uc3Qgd2FsayA9IEdUU0xpYi5mbGF0dGVuR3RzSWRBcnJheShkLCByKTtcbiAgICAgICAgcmVzLnB1c2god2Fsay5yZXMpO1xuICAgICAgICByID0gd2Fsay5yO1xuICAgICAgfSBlbHNlIGlmIChkICYmIGQudikge1xuICAgICAgICBkLmlkID0gcjtcbiAgICAgICAgcmVzLnB1c2goZCk7XG4gICAgICAgIHIrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4ge3Jlcywgcn07XG4gIH1cblxuICBzdGF0aWMgc2FuaXRpemVOYW1lcyhpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gKGlucHV0IHx8ICcnKS5yZXBsYWNlKC97L2csICcmIzEyMzsnKVxuICAgICAgLnJlcGxhY2UoL30vZywgJyYjMTI1OycpXG4gICAgICAucmVwbGFjZSgvLC9nLCAnJiM0NDsnKVxuICAgICAgLnJlcGxhY2UoLz4vZywgJyYjNjI7JylcbiAgICAgIC5yZXBsYWNlKC88L2csICcmIzYwOycpXG4gICAgICAucmVwbGFjZSgvXCIvZywgJyYjMzQ7JylcbiAgICAgIC5yZXBsYWNlKC8nL2csICcmIzM5OycpO1xuICB9XG5cbiAgc3RhdGljIHNlcmlhbGl6ZUd0c01ldGFkYXRhKGd0cykge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRMYWJlbHMgPSBbXTtcbiAgICBjb25zdCBzZXJpYWxpemVkQXR0cmlidXRlcyA9IFtdO1xuICAgIGlmIChndHMubCkge1xuICAgICAgT2JqZWN0LmtleXMoZ3RzLmwpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICBzZXJpYWxpemVkTGFiZWxzLnB1c2godGhpcy5zYW5pdGl6ZU5hbWVzKGtleSArICc9JyArIGd0cy5sW2tleV0pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoZ3RzLmEpIHtcbiAgICAgIE9iamVjdC5rZXlzKGd0cy5hKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgc2VyaWFsaXplZEF0dHJpYnV0ZXMucHVzaCh0aGlzLnNhbml0aXplTmFtZXMoa2V5ICsgJz0nICsgZ3RzLmFba2V5XSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbiAgICByZXR1cm4gYCR7dGhpcy5zYW5pdGl6ZU5hbWVzKGd0cy5jKX17JHtzZXJpYWxpemVkTGFiZWxzLmpvaW4oJywnKX0ke3NlcmlhbGl6ZWRBdHRyaWJ1dGVzLmxlbmd0aCA+IDAgPyAnLCcgOiAnJ30ke3NlcmlhbGl6ZWRBdHRyaWJ1dGVzLmpvaW4oJywnKX19YDtcbiAgfVxuXG4gIHN0YXRpYyBpc0d0cyhpdGVtKSB7XG4gICAgcmV0dXJuICEhaXRlbSAmJiAoaXRlbS5jID09PSAnJyB8fCAhIWl0ZW0uYykgJiYgISFpdGVtLnYgJiYgR1RTTGliLmlzQXJyYXkoaXRlbS52KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0d0c1RvUGxvdChndHMpIHtcbiAgICBpZiAoIUdUU0xpYi5pc0d0cyhndHMpIHx8IGd0cy52Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBXZSBsb29rIGF0IHRoZSBmaXJzdCBub24tbnVsbCB2YWx1ZSwgaWYgaXQncyBhIFN0cmluZyBvciBCb29sZWFuIGl0J3MgYW4gYW5ub3RhdGlvbiBHVFMsXG4gICAgLy8gaWYgaXQncyBhIG51bWJlciBpdCdzIGEgR1RTIHRvIHBsb3RcbiAgICByZXR1cm4gKGd0cy52IHx8IFtdKS5zb21lKHYgPT4ge1xuICAgICAgLy8gbm9pbnNwZWN0aW9uIEpTUG90ZW50aWFsbHlJbnZhbGlkQ29uc3RydWN0b3JVc2FnZVxuICAgICAgcmV0dXJuIHR5cGVvZiB2W3YubGVuZ3RoIC0gMV0gPT09ICdudW1iZXInIHx8ICEhdlt2Lmxlbmd0aCAtIDFdLmNvbnN0cnVjdG9yLnByb3RvdHlwZS50b0ZpeGVkO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzR3RzVG9QbG90T25NYXAoZ3RzKSB7XG4gICAgaWYgKCFHVFNMaWIuaXNHdHMoZ3RzKSB8fCBndHMudi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gV2UgbG9vayBhdCB0aGUgZmlyc3Qgbm9uLW51bGwgdmFsdWUsIGlmIGl0J3MgYSBTdHJpbmcgb3IgQm9vbGVhbiBpdCdzIGFuIGFubm90YXRpb24gR1RTLFxuICAgIC8vIGlmIGl0J3MgYSBudW1iZXIgaXQncyBhIEdUUyB0byBwbG90XG4gICAgcmV0dXJuIChndHMudiB8fCBbXSkuc29tZSh2ID0+IHtcbiAgICAgIHJldHVybiB2Lmxlbmd0aCA+PSAzO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzU2luZ2xldG9uR1RTKGd0cykge1xuICAgIGlmICghR1RTTGliLmlzR3RzKGd0cykgfHwgZ3RzLnYubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiAoZ3RzLnYgfHwgW10pLmxlbmd0aCA9PT0gMTtcbiAgfVxuXG4gIHN0YXRpYyBpc0d0c1RvQW5ub3RhdGUoZ3RzKSB7XG4gICAgaWYgKCFHVFNMaWIuaXNHdHMoZ3RzKSB8fCBndHMudi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gV2UgbG9vayBhdCB0aGUgZmlyc3Qgbm9uLW51bGwgdmFsdWUsIGlmIGl0J3MgYSBTdHJpbmcgb3IgQm9vbGVhbiBpdCdzIGFuIGFubm90YXRpb24gR1RTLFxuICAgIC8vIGlmIGl0J3MgYSBudW1iZXIgaXQncyBhIEdUUyB0byBwbG90XG4gICAgcmV0dXJuIChndHMudiB8fCBbXSkuc29tZSh2ID0+IHtcbiAgICAgIGlmICh2W3YubGVuZ3RoIC0gMV0gIT09IG51bGwpIHtcbiAgICAgICAgLy8gbm9pbnNwZWN0aW9uIEpTUG90ZW50aWFsbHlJbnZhbGlkQ29uc3RydWN0b3JVc2FnZVxuICAgICAgICByZXR1cm4gdHlwZW9mICh2W3YubGVuZ3RoIC0gMV0pICE9PSAnbnVtYmVyJyAmJlxuICAgICAgICAgICghIXZbdi5sZW5ndGggLSAxXS5jb25zdHJ1Y3RvciAmJiB2W3YubGVuZ3RoIC0gMV0uY29uc3RydWN0b3IubmFtZSAhPT0gJ0JpZycpICYmXG4gICAgICAgICAgdlt2Lmxlbmd0aCAtIDFdLmNvbnN0cnVjdG9yLnByb3RvdHlwZS50b0ZpeGVkID09PSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ3RzU29ydChndHMpIHtcbiAgICBpZiAoZ3RzLmlzU29ydGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGd0cy52ID0gZ3RzLnYuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuICAgIGd0cy5pc1NvcnRlZCA9IHRydWU7XG4gIH1cblxuICBzdGF0aWMgZ2V0RGF0YShkYXRhOiBhbnkpOiBEYXRhTW9kZWwge1xuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChkYXRhLnN0YXJ0c1dpdGgoJ1snKSB8fCBkYXRhLnN0YXJ0c1dpdGgoJ3snKSkge1xuICAgICAgICByZXR1cm4gR1RTTGliLmdldERhdGEobmV3IEpzb25MaWIoKS5wYXJzZShkYXRhIGFzIHN0cmluZykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtkYXRhOiBuZXcgSnNvbkxpYigpLnBhcnNlKGBbJHtkYXRhfV1gKX07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkYXRhICYmIGRhdGEuaGFzT3duUHJvcGVydHkoJ2RhdGEnKSkge1xuICAgICAgaWYgKCFHVFNMaWIuaXNBcnJheShkYXRhLmRhdGEpKSB7XG4gICAgICAgIGRhdGEuZGF0YSA9IFtkYXRhLmRhdGFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGEgYXMgRGF0YU1vZGVsO1xuICAgIH0gZWxzZSBpZiAoR1RTTGliLmlzQXJyYXkoZGF0YSkgJiYgZGF0YS5sZW5ndGggPiAwICYmIGRhdGFbMF0uZGF0YSkge1xuICAgICAgcmV0dXJuIGRhdGFbMF0gYXMgRGF0YU1vZGVsO1xuICAgIH0gZWxzZSBpZiAoR1RTTGliLmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHJldHVybiB7ZGF0YTogZGF0YSBhcyBHVFNbXX0gYXMgRGF0YU1vZGVsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGFNb2RlbCgpO1xuICB9XG5cbiAgc3RhdGljIGdldERpdmlkZXIodGltZVVuaXQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgbGV0IHRpbWVzdGFtcERpdmlkZXIgPSAxMDAwOyAvLyBkZWZhdWx0IGZvciDCtXMgdGltZXVuaXRcbiAgICBpZiAodGltZVVuaXQgPT09ICdtcycpIHtcbiAgICAgIHRpbWVzdGFtcERpdmlkZXIgPSAxO1xuICAgIH1cbiAgICBpZiAodGltZVVuaXQgPT09ICducycpIHtcbiAgICAgIHRpbWVzdGFtcERpdmlkZXIgPSAxMDAwMDAwO1xuICAgIH1cbiAgICByZXR1cm4gdGltZXN0YW1wRGl2aWRlcjtcbiAgfVxuXG4gIHN0YXRpYyBmb3JtYXRMYWJlbChkYXRhOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRHVFMgPSBkYXRhLnNwbGl0KCd7Jyk7XG4gICAgbGV0IGRpc3BsYXkgPSBgPHNwYW4gY2xhc3M9XCJndHNJbmZvXCI+PHNwYW4gY2xhc3M9J2d0cy1jbGFzc25hbWUnPiR7c2VyaWFsaXplZEdUU1swXX08L3NwYW4+YDtcbiAgICBpZiAoc2VyaWFsaXplZEdUUy5sZW5ndGggPiAxKSB7XG4gICAgICBkaXNwbGF5ICs9IGA8c3BhbiBjbGFzcz0nZ3RzLXNlcGFyYXRvcic+ezwvc3Bhbj5gO1xuICAgICAgY29uc3QgbGFiZWxzID0gc2VyaWFsaXplZEdUU1sxXS5zdWJzdHIoMCwgc2VyaWFsaXplZEdUU1sxXS5sZW5ndGggLSAxKS5zcGxpdCgnLCcpO1xuICAgICAgaWYgKGxhYmVscy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxhYmVscy5mb3JFYWNoKChsLCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgbGFiZWwgPSBsLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYgKGwubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgZGlzcGxheSArPSBgPHNwYW4+PHNwYW4gY2xhc3M9J2d0cy1sYWJlbG5hbWUnPiR7bGFiZWxbMF19PC9zcGFuPlxuPHNwYW4gY2xhc3M9J2d0cy1zZXBhcmF0b3InPj08L3NwYW4+PHNwYW4gY2xhc3M9J2d0cy1sYWJlbHZhbHVlJz4ke2xhYmVsWzFdfTwvc3Bhbj5gO1xuICAgICAgICAgICAgaWYgKGkgIT09IGxhYmVscy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgIGRpc3BsYXkgKz0gYDxzcGFuPiwgPC9zcGFuPmA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGRpc3BsYXkgKz0gYDxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz59PC9zcGFuPmA7XG4gICAgfVxuICAgIGlmIChzZXJpYWxpemVkR1RTLmxlbmd0aCA+IDIpIHtcbiAgICAgIGRpc3BsYXkgKz0gYDxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz57PC9zcGFuPmA7XG4gICAgICBjb25zdCBsYWJlbHMgPSBzZXJpYWxpemVkR1RTWzJdLnN1YnN0cigwLCBzZXJpYWxpemVkR1RTWzJdLmxlbmd0aCAtIDEpLnNwbGl0KCcsJyk7XG4gICAgICBpZiAobGFiZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGFiZWxzLmZvckVhY2goKGwsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBsYWJlbCA9IGwuc3BsaXQoJz0nKTtcbiAgICAgICAgICBpZiAobC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBkaXNwbGF5ICs9IGA8c3Bhbj48c3BhbiBjbGFzcz0nZ3RzLWF0dHJuYW1lJz4ke2xhYmVsWzBdfTwvc3Bhbj5cbjxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz49PC9zcGFuPjxzcGFuIGNsYXNzPSdndHMtYXR0cnZhbHVlJz4ke2xhYmVsWzFdfTwvc3Bhbj5gO1xuICAgICAgICAgICAgaWYgKGkgIT09IGxhYmVscy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgIGRpc3BsYXkgKz0gYDxzcGFuPiwgPC9zcGFuPmA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGRpc3BsYXkgKz0gYDxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz59PC9zcGFuPmA7XG4gICAgfVxuICAgIGRpc3BsYXkgKz0gJzwvc3Bhbj4nO1xuICAgIHJldHVybiBkaXNwbGF5O1xuICB9XG5cbiAgc3RhdGljIHRvSVNPU3RyaW5nKHRpbWVzdGFtcDogbnVtYmVyLCBkaXZpZGVyOiBudW1iZXIsIHRpbWVab25lOiBzdHJpbmcpIHtcbiAgICBpZiAodGltZVpvbmUgIT09ICdVVEMnKSB7XG4gICAgICByZXR1cm4gbW9tZW50LnR6KHRpbWVzdGFtcCAvIGRpdmlkZXIsIHRpbWVab25lKS5mb3JtYXQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1vbWVudC51dGModGltZXN0YW1wIC8gZGl2aWRlcikudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdG9UaW1lc3RhbXAoZGF0ZTogc3RyaW5nLCBkaXZpZGVyOiBudW1iZXIsIHRpbWVab25lOiBzdHJpbmcpIHtcbiAgICBpZiAodGltZVpvbmUgIT09ICdVVEMnKSB7XG4gICAgICByZXR1cm4gbW9tZW50LnR6KGRhdGUsIHRpbWVab25lKS51dGMoKS52YWx1ZU9mKCkgKiBkaXZpZGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW9tZW50LnV0YyhkYXRlKS52YWx1ZU9mKCkgKiBkaXZpZGVyO1xuICAgIH1cbiAgfVxufVxuIl19