UNPKG

@activejs/core

Version:

Pragmatic, Reactive State Management for JavaScript Apps

311 lines 32.2 kB
/** * @internal please do not use. */ export const NOOP = () => { }; /** * @internal please do not use. */ export const IteratorSymbol = (typeof Symbol === 'function' && Symbol.iterator) || /* istanbul ignore next */ '@@iterator'; /** * @internal please do not use. */ export function isValidId(id) { return typeof id === 'string' && !!id.trim().length; } /** * @internal please do not use. */ export function isDict(o) { return Object.prototype.toString.call(o) === '[object Object]'; } /** * @internal please do not use. */ export function isObject(o) { return o != null && typeof o === 'object'; } /** * @internal please do not use. */ export function isValidKey(key) { return typeof key === 'string' || typeof key === 'number'; } /** * @internal please do not use. */ export function isValidIndex(i) { const a = []; a[i] = 1; return !!a.length && a[i] === 1; } /** * @internal please do not use. */ export function normalizeIndex(index, arrLength) { return index < 0 ? (index < -arrLength ? 0 : arrLength + index) : index; } /** * @internal please do not use. */ export function sanitizeIndices(indices, arrLength) { const sanitizedIndices = []; indices.forEach(index => { index = normalizeIndex(index, arrLength); if (index < arrLength && isValidIndex(index)) { sanitizedIndices.push(index); } }); return deDuplicate(sanitizedIndices); } /** * @internal please do not use. */ export function isNumber(n) { return typeof n === 'number' && !isNaN(n); } /** * @internal please do not use. */ // tslint:disable-next-line:ban-types export function isFunction(fn) { return typeof fn === 'function'; } /** * @internal please do not use. */ /*export function isNativeFn(fn: any): fn is () => any { return /{\s*?\[native code]\s*?}/.test('' + fn); }*/ /** * Creates a clone of the provided value.\ * All the primitives are returned as is, since they are immutable.\ * Non-primitives that this function can clone are array and object-literal.\ * Other non-primitives are returned as is. * * This function is also used internally by ActiveJS. * * @param o The value to be cloned. * @returns A clone of the provided value. * * @category Global */ export function deepCopy(o) { if (o == null || typeof o !== 'object') { return o; } if (Array.isArray(o)) { return o.map(v => deepCopy(v)); } if (isDict(o)) { return Object.keys(o).reduce((newO, k) => { newO[k] = deepCopy(o[k]); return newO; }, {}); } return o; } /** * @internal please do not use. */ export function deepFreeze(o) { if (!isObject(o)) { return o; } if (Array.isArray(o)) { o.forEach(v => deepFreeze(v)); } else if (isDict(o)) { Object.keys(o).forEach(k => deepFreeze(o[k])); } try { return Object.freeze(o); } catch (e) { return o; } } /** * @internal please do not use. */ export function deDuplicate(arr) { if (typeof Set === 'function') { return [...new Set(arr)]; } else { return arr.filter((x, i) => arr.indexOf(x) === i); } } /** * @internal please do not use. */ export function isSerializable(o) { if (o == null || typeof o === 'string' || typeof o === 'boolean' || typeof o === 'number') { return [true]; } /*if (typeof o === 'number') { return o === Infinity || o === -Infinity ? [false, o] : [true]; }*/ if (Array.isArray(o)) { let foundPositive; o.find(v => { const testResult = isSerializable(v); if (testResult[0] === false) { foundPositive = testResult; return true; } }); return foundPositive || [true]; } else if (o.constructor === Object) { let foundPositive; Object.keys(o).find(k => { const testResult = isSerializable(o[k]); if (testResult[0] === false) { foundPositive = testResult; return true; } }); return foundPositive || [true]; } return [false, o]; } /** * @internal please do not use. */ export function findIndex(array, predicate, fromIndex) { let i = isValidIndex(fromIndex) ? Math.max(0, Math.min(fromIndex, array.length - 1)) : 0; while (i < array.length) { if (predicate(array[i], i, array)) { return i; } ++i; } return -1; } /** * @internal please do not use. */ export function findIndexBackwards(array, predicate, fromIndex) { let i = isValidIndex(fromIndex) ? Math.max(0, Math.min(fromIndex, array.length - 1)) : array.length - 1; while (i > -1) { if (predicate(array[i], i, array)) { return i; } --i; } return -1; } /** * @internal please do not use. */ export function debounce(func, waitTime, callMode) { if (!isNumber(waitTime)) { waitTime = 200; } if (!['START', 'END', 'BOTH'].includes(callMode)) { callMode = 'END'; } let timeout; return function (...args) { const context = this; const later = () => { timeout = null; if (callMode !== 'START') { return func.apply(context, args); } }; const callNow = callMode !== 'END' && !timeout; clearTimeout(timeout); timeout = setTimeout(later, waitTime); if (callNow) { return func.apply(context, args); } }; } /** * @internal please do not use. */ export function makeNonEnumerable(o) { if (o == null || typeof o !== 'object') { return; } Object.keys(o).forEach(key => { Object.defineProperty(o, key, { enumerable: false, }); }); } /** * @internal please do not use. */ export function generateAsyncSystemIds(systemId, queryConfig, dataConfig, errorConfig, pendingConfig) { var _a, _b, _c, _d; const ids = Object.assign(Object.assign(Object.assign(Object.assign({}, ((queryConfig === null || queryConfig === void 0 ? void 0 : queryConfig.hasOwnProperty('id')) && { queryUnitId: queryConfig.id })), ((dataConfig === null || dataConfig === void 0 ? void 0 : dataConfig.hasOwnProperty('id')) && { dataUnitId: dataConfig.id })), ((errorConfig === null || errorConfig === void 0 ? void 0 : errorConfig.hasOwnProperty('id')) && { errorUnitId: errorConfig.id })), ((pendingConfig === null || pendingConfig === void 0 ? void 0 : pendingConfig.hasOwnProperty('id')) && { pendingUnitId: pendingConfig.id })); if (isValidId(systemId)) { ids.queryUnitId = (_a = ids.queryUnitId) !== null && _a !== void 0 ? _a : systemId + '_QUERY'; ids.dataUnitId = (_b = ids.dataUnitId) !== null && _b !== void 0 ? _b : systemId + '_DATA'; ids.errorUnitId = (_c = ids.errorUnitId) !== null && _c !== void 0 ? _c : systemId + '_ERROR'; ids.pendingUnitId = (_d = ids.pendingUnitId) !== null && _d !== void 0 ? _d : systemId + '_PENDING'; } return ids; } /** * @internal please do not use. */ export function plucker(o, path) { const length = Array.isArray(path) ? path.length : 0; for (let i = 0; i < length; i++) { if (o == null) { return undefined; } o = Object.prototype.hasOwnProperty.call(o, path[i]) ? o[path[i]] : undefined; } return o; } /** * @internal please do not use. */ export function hashCode(str) { // tslint:disable:no-bitwise let hash = 0; const length = typeof str === 'string' ? str.length : 0; if (length === 0) { return String(hash); } for (let i = 0; i < length; i++) { hash = (hash << 5) - hash + str.charCodeAt(i); hash |= 0; // Convert to 32bit integer } hash = hash >>> 0; return Number(hash).toString(32).toUpperCase(); // tslint:enable:no-bitwise } /** * @internal please do not use. */ export function stackTrace() { try { throw new Error(); } catch (error) { return error.stacktrace || error.stack; } } /** * @internal please do not use. */ export function getLocationId(source) { if (source == null || typeof source !== 'object') { return ''; } source = source.constructor.name; const errorTrace = stackTrace(); const locationMatch = errorTrace.match(new RegExp( // get two lines beyond ActiveJS scope https://regexr.com/5eb9g `new ${source}\\b.+\\n(?:[\\s\\S]+new (?:AsyncSystem|Cluster)\\b.+\\n)?((?:.+\\n?){1,2})`)); return hashCode((locationMatch === null || locationMatch === void 0 ? void 0 : locationMatch[1]) || errorTrace); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3MuanMiLCJzb3VyY2VSb290IjoiL2hvbWUvcnVubmVyL3dvcmsvYWN0aXZlanMvYWN0aXZlanMvcGFja2FnZXMvY29yZS9zcmMvIiwic291cmNlcyI6WyJ1dGlscy9mdW5jcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLElBQUksR0FBRyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7QUFFN0I7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQ3pCLENBQUMsT0FBTyxNQUFNLEtBQUssVUFBVSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDakQsMEJBQTBCLENBQUUsWUFBb0IsQ0FBQztBQUVuRDs7R0FFRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsRUFBTztJQUMvQixPQUFPLE9BQU8sRUFBRSxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQztBQUN0RCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLENBQU07SUFDM0IsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssaUJBQWlCLENBQUM7QUFDakUsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxDQUFNO0lBQzdCLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUM7QUFDNUMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxHQUFRO0lBQ2pDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsQ0FBQztBQUM1RCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFDLENBQU07SUFDakMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lB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LEtBQUssQ0FBQztLQUN4QztBQUNILENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQUMsTUFBVztJQUN2QyxJQUFJLE1BQU0sSUFBSSxJQUFJLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFO1FBQ2hELE9BQU8sRUFBRSxDQUFDO0tBQ1g7SUFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7SUFDakMsTUFBTSxVQUFVLEdBQUcsVUFBVSxFQUFFLENBQUM7SUFDaEMsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FDcEMsSUFBSSxNQUFNO0lBQ1IsK0RBQStEO0lBQy9ELE9BQU8sTUFBTSw0RUFBNEUsQ0FDMUYsQ0FDRixDQUFDO0lBQ0YsT0FBTyxRQUFRLENBQUMsQ0FBQSxhQUFhLGFBQWIsYUFBYSx1QkFBYixhQUFhLENBQUcsQ0FBQyxNQUFLLFVBQVUsQ0FBQyxDQUFDO0FBQ3BELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1VuaXRDb25maWd9IGZyb20gJy4uL21vZGVscyc7XG5cbi8qKlxuICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICovXG5leHBvcnQgY29uc3QgTk9PUCA9ICgpID0+IHt9O1xuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IEl0ZXJhdG9yU3ltYm9sOiBzeW1ib2wgPVxuICAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaXRlcmF0b3IpIHx8XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovICgnQEBpdGVyYXRvcicgYXMgYW55KTtcblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkSWQoaWQ6IGFueSk6IGlkIGlzIHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmICEhaWQudHJpbSgpLmxlbmd0aDtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RpY3QobzogYW55KTogbyBpcyBvYmplY3Qge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pID09PSAnW29iamVjdCBPYmplY3RdJztcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdChvOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIG8gIT0gbnVsbCAmJiB0eXBlb2YgbyA9PT0gJ29iamVjdCc7XG59XG5cbi8qKlxuICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEtleShrZXk6IGFueSk6IGtleSBpcyBudW1iZXIgfCBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGtleSA9PT0gJ251bWJlcic7XG59XG5cbi8qKlxuICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEluZGV4KGk6IGFueSk6IGkgaXMgbnVtYmVyIHwgc3RyaW5nIHtcbiAgY29uc3QgYSA9IFtdO1xuICBhW2ldID0gMTtcbiAgcmV0dXJuICEhYS5sZW5ndGggJiYgYVtpXSA9PT0gMTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVJbmRleChpbmRleDogbnVtYmVyLCBhcnJMZW5ndGg6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBpbmRleCA8IDAgPyAoaW5kZXggPCAtYXJyTGVuZ3RoID8gMCA6IGFyckxlbmd0aCArIGluZGV4KSA6IGluZGV4O1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNhbml0aXplSW5kaWNlcyhpbmRpY2VzOiBudW1iZXJbXSwgYXJyTGVuZ3RoOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIGNvbnN0IHNhbml0aXplZEluZGljZXMgPSBbXTtcblxuICBpbmRpY2VzLmZvckVhY2goaW5kZXggPT4ge1xuICAgIGluZGV4ID0gbm9ybWFsaXplSW5kZXgoaW5kZXgsIGFyckxlbmd0aCk7XG5cbiAgICBpZiAoaW5kZXggPCBhcnJMZW5ndGggJiYgaXNWYWxpZEluZGV4KGluZGV4KSkge1xuICAgICAgc2FuaXRpemVkSW5kaWNlcy5wdXNoKGluZGV4KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBkZUR1cGxpY2F0ZShzYW5pdGl6ZWRJbmRpY2VzKTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihuOiBhbnkpOiBuIGlzIG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgbiA9PT0gJ251bWJlcicgJiYgIWlzTmFOKG4pO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmJhbi10eXBlc1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24oZm46IGFueSk6IGZuIGlzIEZ1bmN0aW9uIHtcbiAgcmV0dXJuIHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbi8qZXhwb3J0IGZ1bmN0aW9uIGlzTmF0aXZlRm4oZm46IGFueSk6IGZuIGlzICgpID0+IGFueSB7XG4gIHJldHVybiAve1xccyo/XFxbbmF0aXZlIGNvZGVdXFxzKj99Ly50ZXN0KCcnICsgZm4pO1xufSovXG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBwcm92aWRlZCB2YWx1ZS5cXFxuICogQWxsIHRoZSBwcmltaXRpdmVzIGFyZSByZXR1cm5lZCBhcyBpcywgc2luY2UgdGhleSBhcmUgaW1tdXRhYmxlLlxcXG4gKiBOb24tcHJpbWl0aXZlcyB0aGF0IHRoaXMgZnVuY3Rpb24gY2FuIGNsb25lIGFyZSBhcnJheSBhbmQgb2JqZWN0LWxpdGVyYWwuXFxcbiAqIE90aGVyIG5vbi1wcmltaXRpdmVzIGFyZSByZXR1cm5lZCBhcyBpcy5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGFsc28gdXNlZCBpbnRlcm5hbGx5IGJ5IEFjdGl2ZUpTLlxuICpcbiAqIEBwYXJhbSBvIFRoZSB2YWx1ZSB0byBiZSBjbG9uZWQuXG4gKiBAcmV0dXJucyBBIGNsb25lIG9mIHRoZSBwcm92aWRlZCB2YWx1ZS5cbiAqXG4gKiBAY2F0ZWdvcnkgR2xvYmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwQ29weTxUPihvOiBUKTogVCB7XG4gIGlmIChvID09IG51bGwgfHwgdHlwZW9mIG8gIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG87XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkobykpIHtcbiAgICByZXR1cm4gKG8gYXMgYW55KS5tYXAodiA9PiBkZWVwQ29weSh2KSk7XG4gIH1cbiAgaWYgKGlzRGljdChvKSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhvKS5yZWR1Y2UoKG5ld08sIGspID0+IHtcbiAgICAgIG5ld09ba10gPSBkZWVwQ29weShvW2tdKTtcbiAgICAgIHJldHVybiBuZXdPO1xuICAgIH0sIHt9IGFzIFQpO1xuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBGcmVlemU8VD4obzogVCk6IFQge1xuICBpZiAoIWlzT2JqZWN0KG8pKSB7XG4gICAgcmV0dXJuIG87XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShvKSkge1xuICAgIChvIGFzIGFueSkuZm9yRWFjaCh2ID0+IGRlZXBGcmVlemUodikpO1xuICB9IGVsc2UgaWYgKGlzRGljdChvKSkge1xuICAgIE9iamVjdC5rZXlzKG8pLmZvckVhY2goayA9PiBkZWVwRnJlZXplKG9ba10pKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIE9iamVjdC5mcmVlemUobyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbztcbiAgfVxufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlRHVwbGljYXRlPFQgZXh0ZW5kcyBhbnlbXT4oYXJyOiBUKTogVCB7XG4gIGlmICh0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIFsuLi5uZXcgU2V0KGFycildIGFzIFQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFyci5maWx0ZXIoKHgsIGkpID0+IGFyci5pbmRleE9mKHgpID09PSBpKSBhcyBUO1xuICB9XG59XG5cbi8qKlxuICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTZXJpYWxpemFibGU8VD4obzogVCk6IFt0cnVlXSB8IFtmYWxzZSwgYW55XSB7XG4gIGlmIChvID09IG51bGwgfHwgdHlwZW9mIG8gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBvID09PSAnYm9vbGVhbicgfHwgdHlwZW9mIG8gPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIFt0cnVlXTtcbiAgfVxuXG4gIC8qaWYgKHR5cGVvZiBvID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBvID09PSBJbmZpbml0eSB8fCBvID09PSAtSW5maW5pdHkgPyBbZmFsc2UsIG9dIDogW3RydWVdO1xuICB9Ki9cblxuICBpZiAoQXJyYXkuaXNBcnJheShvKSkge1xuICAgIGxldCBmb3VuZFBvc2l0aXZlOiBbZmFsc2UsIGFueV07XG5cbiAgICBvLmZpbmQodiA9PiB7XG4gICAgICBjb25zdCB0ZXN0UmVzdWx0ID0gaXNTZXJpYWxpemFibGUodik7XG4gICAgICBpZiAodGVzdFJlc3VsdFswXSA9PT0gZmFsc2UpIHtcbiAgICAgICAgZm91bmRQb3NpdGl2ZSA9IHRlc3RSZXN1bHQ7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZvdW5kUG9zaXRpdmUgfHwgW3RydWVdO1xuICB9IGVsc2UgaWYgKG8uY29uc3RydWN0b3IgPT09IE9iamVjdCkge1xuICAgIGxldCBmb3VuZFBvc2l0aXZlOiBbZmFsc2UsIGFueV07XG5cbiAgICBPYmplY3Qua2V5cyhvKS5maW5kKGsgPT4ge1xuICAgICAgY29uc3QgdGVzdFJlc3VsdCA9IGlzU2VyaWFsaXphYmxlKG9ba10pO1xuICAgICAgaWYgKHRlc3RSZXN1bHRbMF0gPT09IGZhbHNlKSB7XG4gICAgICAgIGZvdW5kUG9zaXRpdmUgPSB0ZXN0UmVzdWx0O1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBmb3VuZFBvc2l0aXZlIHx8IFt0cnVlXTtcbiAgfVxuXG4gIHJldHVybiBbZmFsc2UsIG9dO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRJbmRleDxUPihcbiAgYXJyYXk6IEFycmF5PFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlciwgb2JqOiBUW10pID0+IGJvb2xlYW4sXG4gIGZyb21JbmRleD86IG51bWJlclxuKTogbnVtYmVyIHtcbiAgbGV0IGkgPSBpc1ZhbGlkSW5kZXgoZnJvbUluZGV4KSA/IE1hdGgubWF4KDAsIE1hdGgubWluKGZyb21JbmRleCwgYXJyYXkubGVuZ3RoIC0gMSkpIDogMDtcbiAgd2hpbGUgKGkgPCBhcnJheS5sZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2ldLCBpLCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgICArK2k7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRJbmRleEJhY2t3YXJkczxUPihcbiAgYXJyYXk6IEFycmF5PFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlciwgb2JqOiBUW10pID0+IGJvb2xlYW4sXG4gIGZyb21JbmRleD86IG51bWJlclxuKTogbnVtYmVyIHtcbiAgbGV0IGkgPSBpc1ZhbGlkSW5kZXgoZnJvbUluZGV4KVxuICAgID8gTWF0aC5tYXgoMCwgTWF0aC5taW4oZnJvbUluZGV4LCBhcnJheS5sZW5ndGggLSAxKSlcbiAgICA6IGFycmF5Lmxlbmd0aCAtIDE7XG4gIHdoaWxlIChpID4gLTEpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2ldLCBpLCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgICAtLWk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlYm91bmNlKFxuICBmdW5jOiAoLi4uYXJncykgPT4gYW55LFxuICB3YWl0VGltZT8sXG4gIGNhbGxNb2RlPzogJ1NUQVJUJyB8ICdFTkQnIHwgJ0JPVEgnXG4pOiBhbnkge1xuICBpZiAoIWlzTnVtYmVyKHdhaXRUaW1lKSkge1xuICAgIHdhaXRUaW1lID0gMjAwO1xuICB9XG4gIGlmICghWydTVEFSVCcsICdFTkQnLCAnQk9USCddLmluY2x1ZGVzKGNhbGxNb2RlKSkge1xuICAgIGNhbGxNb2RlID0gJ0VORCc7XG4gIH1cbiAgbGV0IHRpbWVvdXQ7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXM7XG5cbiAgICBjb25zdCBsYXRlciA9ICgpID0+IHtcbiAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgaWYgKGNhbGxNb2RlICE9PSAnU1RBUlQnKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBjYWxsTm93ID0gY2FsbE1vZGUgIT09ICdFTkQnICYmICF0aW1lb3V0O1xuXG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0VGltZSk7XG5cbiAgICBpZiAoY2FsbE5vdykge1xuICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VOb25FbnVtZXJhYmxlPFQgZXh0ZW5kcyBvYmplY3Q+KG86IFQpOiB2b2lkIHtcbiAgaWYgKG8gPT0gbnVsbCB8fCB0eXBlb2YgbyAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgT2JqZWN0LmtleXMobykuZm9yRWFjaChrZXkgPT4ge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrZXksIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUFzeW5jU3lzdGVtSWRzKFxuICBzeXN0ZW1JZDogc3RyaW5nLFxuICBxdWVyeUNvbmZpZzogVW5pdENvbmZpZzxhbnk+LFxuICBkYXRhQ29uZmlnOiBVbml0Q29uZmlnPGFueT4sXG4gIGVycm9yQ29uZmlnOiBVbml0Q29uZmlnPGFueT4sXG4gIHBlbmRpbmdDb25maWc6IFVuaXRDb25maWc8Ym9vbGVhbj5cbikge1xuICBjb25zdCBpZHMgPSB7XG4gICAgLi4uKHF1ZXJ5Q29uZmlnPy5oYXNPd25Qcm9wZXJ0eSgnaWQnKSAmJiB7cXVlcnlVbml0SWQ6IHF1ZXJ5Q29uZmlnLmlkfSksXG4gICAgLi4uKGRhdGFDb25maWc/Lmhhc093blByb3BlcnR5KCdpZCcpICYmIHtkYXRhVW5pdElkOiBkYXRhQ29uZmlnLmlkfSksXG4gICAgLi4uKGVycm9yQ29uZmlnPy5oYXNPd25Qcm9wZXJ0eSgnaWQnKSAmJiB7ZXJyb3JVbml0SWQ6IGVycm9yQ29uZmlnLmlkfSksXG4gICAgLi4uKHBlbmRpbmdDb25maWc/Lmhhc093blByb3BlcnR5KCdpZCcpICYmIHtwZW5kaW5nVW5pdElkOiBwZW5kaW5nQ29uZmlnLmlkfSksXG4gIH07XG4gIGlmIChpc1ZhbGlkSWQoc3lzdGVtSWQpKSB7XG4gICAgaWRzLnF1ZXJ5VW5pdElkID0gaWRzLnF1ZXJ5VW5pdElkID8/IHN5c3RlbUlkICsgJ19RVUVSWSc7XG4gICAgaWRzLmRhdGFVbml0SWQgPSBpZHMuZGF0YVVuaXRJZCA/PyBzeXN0ZW1JZCArICdfREFUQSc7XG4gICAgaWRzLmVycm9yVW5pdElkID0gaWRzLmVycm9yVW5pdElkID8/IHN5c3RlbUlkICsgJ19FUlJPUic7XG4gICAgaWRzLnBlbmRpbmdVbml0SWQgPSBpZHMucGVuZGluZ1VuaXRJZCA/PyBzeXN0ZW1JZCArICdfUEVORElORyc7XG4gIH1cbiAgcmV0dXJuIGlkcztcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwbHVja2VyPFQ+KG86IFQsIHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10pOiBhbnkge1xuICBjb25zdCBsZW5ndGggPSBBcnJheS5pc0FycmF5KHBhdGgpID8gcGF0aC5sZW5ndGggOiAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG8gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgbyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwYXRoW2ldKSA/IG9bcGF0aFtpXV0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIG87XG59XG5cbi8qKlxuICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaENvZGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyB0c2xpbnQ6ZGlzYWJsZTpuby1iaXR3aXNlXG4gIGxldCBoYXNoID0gMDtcbiAgY29uc3QgbGVuZ3RoID0gdHlwZW9mIHN0ciA9PT0gJ3N0cmluZycgPyBzdHIubGVuZ3RoIDogMDtcbiAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBTdHJpbmcoaGFzaCk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGhhc2ggPSAoaGFzaCA8PCA1KSAtIGhhc2ggKyBzdHIuY2hhckNvZGVBdChpKTtcbiAgICBoYXNoIHw9IDA7IC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuICB9XG4gIGhhc2ggPSBoYXNoID4+PiAwO1xuICByZXR1cm4gTnVtYmVyKGhhc2gpLnRvU3RyaW5nKDMyKS50b1VwcGVyQ2FzZSgpO1xuICAvLyB0c2xpbnQ6ZW5hYmxlOm5vLWJpdHdpc2Vcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFja1RyYWNlKCk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yLnN0YWNrdHJhY2UgfHwgZXJyb3Iuc3RhY2s7XG4gIH1cbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2NhdGlvbklkKHNvdXJjZTogYW55KTogc3RyaW5nIHtcbiAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHR5cGVvZiBzb3VyY2UgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIHNvdXJjZSA9IHNvdXJjZS5jb25zdHJ1Y3Rvci5uYW1lO1xuICBjb25zdCBlcnJvclRyYWNlID0gc3RhY2tUcmFjZSgpO1xuICBjb25zdCBsb2NhdGlvbk1hdGNoID0gZXJyb3JUcmFjZS5tYXRjaChcbiAgICBuZXcgUmVnRXhwKFxuICAgICAgLy8gZ2V0IHR3byBsaW5lcyBiZXlvbmQgQWN0aXZlSlMgc2NvcGUgaHR0cHM6Ly9yZWdleHIuY29tLzVlYjlnXG4gICAgICBgbmV3ICR7c291cmNlfVxcXFxiLitcXFxcbig/OltcXFxcc1xcXFxTXStuZXcgKD86QXN5bmNTeXN0ZW18Q2x1c3RlcilcXFxcYi4rXFxcXG4pPygoPzouK1xcXFxuPyl7MSwyfSlgXG4gICAgKVxuICApO1xuICByZXR1cm4gaGFzaENvZGUobG9jYXRpb25NYXRjaD8uWzFdIHx8IGVycm9yVHJhY2UpO1xufVxuIl19