@activejs/core
Version:
Pragmatic, Reactive State Management for JavaScript Apps
311 lines • 32.2 kB
JavaScript
/**
* @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