import { isNull, isNumber, isUndefined, noop } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29"; import { ensureError } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/core/helpers/error.js"; import { setInterval } from "/_nuxt/node_modules/nuxt/dist/app/compat/interval.js?v=e4f18c29"; export class TimeoutError extends Error { } export class WaitIntervalUntilCanceledError extends Error { } /** * Build promise that can be resolved/rejected manually outside of the promise's execution scope */ export const buildManualPromise = () => { let resolve; // eslint-disable-next-line @typescript-eslint/no-explicit-any let reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); const resolveWrapper = (...args) => resolve(...args); const rejectWrapper = (...args) => reject(...args); return { promise, resolve: resolveWrapper, reject: rejectWrapper }; }; export const isNullOrUndefined = (val) => isNull(val) || isUndefined(val); export const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); export const waitIntervalUntil = (ms, predicate) => { const { promise, resolve, reject } = buildManualPromise(); const interval = setInterval(() => { if (predicate()) { clearInterval(interval); resolve(); } }, ms); const ret = promise; ret.cancel = () => { clearInterval(interval); reject(new WaitIntervalUntilCanceledError()); }; return ret; }; /** * Not nullable type guard, useful in `.filter()` calls for proper TS typed * results */ export const isNonNullable = (v) => !!v; /** * Make the promise throw after enough time has passed. Useful for implementing timeout functionality in various flows. */ export const timeoutAt = (ms, optionalMessage) => { // create error beforehand, so we have a better stack trace const err = new TimeoutError(optionalMessage || 'timeoutAt() timed out'); return new Promise((_resolve, reject) => setTimeout(() => { reject(err); }, ms)); }; /** * Invoke and return fn(), but retry it up to n times if it throws */ export const retry = async (fn, n, delayMs) => { let lastError; for (let i = 0; i < n; i++) { try { const res = await Promise.resolve(fn()); return res; } catch (error) { lastError = ensureError(error); if (delayMs && i + 1 < n) { if (isNumber(delayMs)) { await wait(delayMs); } else { await wait(delayMs(i + 1, lastError)); } } } } throw lastError || new Error('Unexpected retry() failure'); }; /** * For quickly profiling a function */ export const profile = async (fn, label, extra) => { const start = performance.now(); const res = await Promise.resolve(fn()); const end = performance.now(); console.log(`[${label || 'profile'}] took ${end - start}ms`, ...(extra ? [extra] : [])); return res; }; /** * For quickly profiling a sync function */ export const profileSync = (fn, label, extra) => { const start = performance.now(); const res = fn(); const end = performance.now(); console.log(`[${label || 'profile'}] took ${end - start}ms`, ...(extra ? [extra] : [])); return res; }; export const removeNullOrUndefinedKeys = (obj) => { const ret = {}; for (const key in obj) { if (!isNullOrUndefined(obj[key])) { ret[key] = obj[key]; } } return ret; }; export const coerceUndefinedValuesToNull = (obj) => { const ret = {}; for (const [key, value] of Object.entries(obj)) { ret[key] = isUndefined(value) ? null : value; } return ret; }; export const isArrayOf = (arr, guard) => Array.isArray(arr) && arr.every(guard); export const waitForever = () => new Promise(noop); /** * Returns true if only one of the arguments is truthy */ export const xor = (a, b) => !!((a || b) && !(a && b)); /** * Shortcut for creating string key & value enums. Native TS Enums are problematic in many ways * (transform code, instead of just adding types; you cant put a string literal matching the enum value * in a variable typed as the enum, etc.) */ export const StringEnum = (args) => { const enumObj = Object.fromEntries(args.map((arg) => [arg, arg])); return Object.freeze(enumObj); }; /** * Get first non-undefined/null value, or undefined if none found */ export const firstDefinedValue = (...args) => { for (const arg of args) { if (!isNullOrUndefined(arg)) return arg; } return undefined; }; //# sourceMappingURL=data:application/json;base64,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RyxDQUFJLEdBQVksRUFBRSxLQUE2QixFQUFjLEVBQUUsQ0FDdEYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztBQUV4QyxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsR0FBbUIsRUFBRSxDQUFDLElBQUksT0FBTyxDQUFRLElBQUksQ0FBQztBQUV6RTs7O0FBR0EsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBVSxFQUFFLENBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUV4RTs7Ozs7QUFLQSxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBbUIsSUFBUyxFQUFFLEVBQUU7SUFDeEQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUUvRDtJQUNELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7QUFDL0IsQ0FBQztBQVNEOzs7QUFHQSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUMvQixHQUFHLElBQThCLEVBQ2xCLEVBQUU7SUFDakIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUU7UUFDdEIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQztZQUFFLE9BQU8sR0FBRztJQUN6QztJQUNBLE9BQU8sU0FBUztBQUNsQixDQUFDIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9oZWxwZXJzL3V0aWxpdHkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNOdWxsLCBpc051bWJlciwgaXNVbmRlZmluZWQsIG5vb3AgfSBmcm9tICcjbG9kYXNoJ1xyXG5pbXBvcnQgdHlwZSB7XHJcbiAgTWF5YmVBc3luYyxcclxuICBOb25OdWxsYWJsZVByb3BlcnRpZXMsXHJcbiAgTnVsbGFibGVLZXlzVG9PcHRpb25hbFxyXG59IGZyb20gJy4vdXRpbGl0eVR5cGVzLmpzJ1xyXG5pbXBvcnQgeyBlbnN1cmVFcnJvciB9IGZyb20gJy4vZXJyb3IuanMnXHJcblxyXG5leHBvcnQgY2xhc3MgVGltZW91dEVycm9yIGV4dGVuZHMgRXJyb3Ige31cclxuZXhwb3J0IGNsYXNzIFdhaXRJbnRlcnZhbFVudGlsQ2FuY2VsZWRFcnJvciBleHRlbmRzIEVycm9yIHt9XHJcblxyXG4vKipcclxuICogQnVpbGQgcHJvbWlzZSB0aGF0IGNhbiBiZSByZXNvbHZlZC9yZWplY3RlZCBtYW51YWxseSBvdXRzaWRlIG9mIHRoZSBwcm9taXNlJ3MgZXhlY3V0aW9uIHNjb3BlXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgYnVpbGRNYW51YWxQcm9taXNlID0gPFQ+KCkgPT4ge1xyXG4gIGxldCByZXNvbHZlOiAodmFsdWU6IFQpID0+IHZvaWRcclxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG4gIGxldCByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWRcclxuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8VD4oKHJlcywgcmVqKSA9PiB7XHJcbiAgICByZXNvbHZlID0gcmVzXHJcbiAgICByZWplY3QgPSByZWpcclxuICB9KVxyXG5cclxuICBjb25zdCByZXNvbHZlV3JhcHBlcjogdHlwZW9mIHJlc29sdmUgPSAoLi4uYXJncykgPT4gcmVzb2x2ZSguLi5hcmdzKVxyXG4gIGNvbnN0IHJlamVjdFdyYXBwZXI6IHR5cGVvZiByZWplY3QgPSAoLi4uYXJncykgPT4gcmVqZWN0KC4uLmFyZ3MpXHJcblxyXG4gIHJldHVybiB7IHByb21pc2UsIHJlc29sdmU6IHJlc29sdmVXcmFwcGVyLCByZWplY3Q6IHJlamVjdFdyYXBwZXIgfVxyXG59XHJcblxyXG5leHBvcnQgdHlwZSBNYW51YWxQcm9taXNlPFQ+ID0gUmV0dXJuVHlwZTx0eXBlb2YgYnVpbGRNYW51YWxQcm9taXNlPFQ+PlxyXG5cclxuZXhwb3J0IGNvbnN0IGlzTnVsbE9yVW5kZWZpbmVkID0gKHZhbDogdW5rbm93bik6IHZhbCBpcyBudWxsIHwgdW5kZWZpbmVkID0+XHJcbiAgaXNOdWxsKHZhbCkgfHwgaXNVbmRlZmluZWQodmFsKVxyXG5cclxuZXhwb3J0IGNvbnN0IHdhaXQgPSAobXM6IG51bWJlcikgPT4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKVxyXG5cclxuZXhwb3J0IGNvbnN0IHdhaXRJbnRlcnZhbFVudGlsID0gKG1zOiBudW1iZXIsIHByZWRpY2F0ZTogKCkgPT4gYm9vbGVhbikgPT4ge1xyXG4gIGNvbnN0IHsgcHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0IH0gPSBidWlsZE1hbnVhbFByb21pc2U8dm9pZD4oKVxyXG4gIGNvbnN0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG4gICAgaWYgKHByZWRpY2F0ZSgpKSB7XHJcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpXHJcbiAgICAgIHJlc29sdmUoKVxyXG4gICAgfVxyXG4gIH0sIG1zKVxyXG5cclxuICBjb25zdCByZXQgPSBwcm9taXNlIGFzIHR5cGVvZiBwcm9taXNlICYgeyBjYW5jZWw6ICgpID0+IHZvaWQgfVxyXG4gIHJldC5jYW5jZWwgPSAoKSA9PiB7XHJcbiAgICBjbGVhckludGVydmFsKGludGVydmFsKVxyXG4gICAgcmVqZWN0KG5ldyBXYWl0SW50ZXJ2YWxVbnRpbENhbmNlbGVkRXJyb3IoKSlcclxuICB9XHJcblxyXG4gIHJldHVybiByZXRcclxufVxyXG5cclxuLyoqXHJcbiAqIE5vdCBudWxsYWJsZSB0eXBlIGd1YXJkLCB1c2VmdWwgaW4gYC5maWx0ZXIoKWAgY2FsbHMgZm9yIHByb3BlciBUUyB0eXBlZFxyXG4gKiByZXN1bHRzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXNOb25OdWxsYWJsZSA9IDxWPih2OiBWKTogdiBpcyBOb25OdWxsYWJsZTx0eXBlb2Ygdj4gPT4gISF2XHJcblxyXG4vKipcclxuICogTWFrZSB0aGUgcHJvbWlzZSB0aHJvdyBhZnRlciBlbm91Z2ggdGltZSBoYXMgcGFzc2VkLiBVc2VmdWwgZm9yIGltcGxlbWVudGluZyB0aW1lb3V0IGZ1bmN0aW9uYWxpdHkgaW4gdmFyaW91cyBmbG93cy5cclxuICovXHJcbmV4cG9ydCBjb25zdCB0aW1lb3V0QXQgPSAobXM6IG51bWJlciwgb3B0aW9uYWxNZXNzYWdlPzogc3RyaW5nKSA9PiB7XHJcbiAgLy8gY3JlYXRlIGVycm9yIGJlZm9yZWhhbmQsIHNvIHdlIGhhdmUgYSBiZXR0ZXIgc3RhY2sgdHJhY2VcclxuICBjb25zdCBlcnIgPSBuZXcgVGltZW91dEVycm9yKG9wdGlvbmFsTWVzc2FnZSB8fCAndGltZW91dEF0KCkgdGltZWQgb3V0JylcclxuXHJcbiAgcmV0dXJuIG5ldyBQcm9taXNlPG5ldmVyPigoX3Jlc29sdmUsIHJlamVjdCkgPT5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICByZWplY3QoZXJyKVxyXG4gICAgfSwgbXMpXHJcbiAgKVxyXG59XHJcblxyXG4vKipcclxuICogSW52b2tlIGFuZCByZXR1cm4gZm4oKSwgYnV0IHJldHJ5IGl0IHVwIHRvIG4gdGltZXMgaWYgaXQgdGhyb3dzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgcmV0cnkgPSBhc3luYyA8ViA9IHVua25vd24+KFxyXG4gIGZuOiAoKSA9PiBNYXliZUFzeW5jPFY+LFxyXG4gIG46IG51bWJlcixcclxuICBkZWxheU1zPzogbnVtYmVyIHwgKChhdHRlbXB0OiBudW1iZXIsIGVycm9yOiBFcnJvcikgPT4gbnVtYmVyKVxyXG4pID0+IHtcclxuICBsZXQgbGFzdEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZFxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoZm4oKSlcclxuICAgICAgcmV0dXJuIHJlc1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgbGFzdEVycm9yID0gZW5zdXJlRXJyb3IoZXJyb3IpXHJcblxyXG4gICAgICBpZiAoZGVsYXlNcyAmJiBpICsgMSA8IG4pIHtcclxuICAgICAgICBpZiAoaXNOdW1iZXIoZGVsYXlNcykpIHtcclxuICAgICAgICAgIGF3YWl0IHdhaXQoZGVsYXlNcylcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgYXdhaXQgd2FpdChkZWxheU1zKGkgKyAxLCBsYXN0RXJyb3IpKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICB0aHJvdyBsYXN0RXJyb3IgfHwgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHJldHJ5KCkgZmFpbHVyZScpXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGb3IgcXVpY2tseSBwcm9maWxpbmcgYSBmdW5jdGlvblxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHByb2ZpbGUgPSBhc3luYyA8ViA9IHVua25vd24+KFxyXG4gIGZuOiAoKSA9PiBNYXliZUFzeW5jPFY+LFxyXG4gIGxhYmVsPzogc3RyaW5nLFxyXG4gIGV4dHJhPzogdW5rbm93blxyXG4pID0+IHtcclxuICBjb25zdCBzdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpXHJcbiAgY29uc3QgcmVzID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKGZuKCkpXHJcbiAgY29uc3QgZW5kID0gcGVyZm9ybWFuY2Uubm93KClcclxuICBjb25zb2xlLmxvZyhcclxuICAgIGBbJHtsYWJlbCB8fCAncHJvZmlsZSd9XSB0b29rICR7ZW5kIC0gc3RhcnR9bXNgLFxyXG4gICAgLi4uKGV4dHJhID8gW2V4dHJhXSA6IFtdKVxyXG4gIClcclxuICByZXR1cm4gcmVzXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGb3IgcXVpY2tseSBwcm9maWxpbmcgYSBzeW5jIGZ1bmN0aW9uXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgcHJvZmlsZVN5bmMgPSA8ViA9IHVua25vd24+KFxyXG4gIGZuOiAoKSA9PiBWLFxyXG4gIGxhYmVsPzogc3RyaW5nLFxyXG4gIGV4dHJhPzogdW5rbm93blxyXG4pID0+IHtcclxuICBjb25zdCBzdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpXHJcbiAgY29uc3QgcmVzID0gZm4oKVxyXG4gIGNvbnN0IGVuZCA9IHBlcmZvcm1hbmNlLm5vdygpXHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBgWyR7bGFiZWwgfHwgJ3Byb2ZpbGUnfV0gdG9vayAke2VuZCAtIHN0YXJ0fW1zYCxcclxuICAgIC4uLihleHRyYSA/IFtleHRyYV0gOiBbXSlcclxuICApXHJcbiAgcmV0dXJuIHJlc1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgcmVtb3ZlTnVsbE9yVW5kZWZpbmVkS2V5cyA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxyXG4gIG9iajogVFxyXG4pID0+IHtcclxuICBjb25zdCByZXQgPSB7fSBhcyBUXHJcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XHJcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKG9ialtrZXldKSkge1xyXG4gICAgICByZXRba2V5XSA9IG9ialtrZXldXHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiByZXQgYXMgTm9uTnVsbGFibGVQcm9wZXJ0aWVzPE51bGxhYmxlS2V5c1RvT3B0aW9uYWw8VD4+XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBjb2VyY2VVbmRlZmluZWRWYWx1ZXNUb051bGwgPSA8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcclxuICBvYmo6IFRcclxuKSA9PiB7XHJcbiAgY29uc3QgcmV0ID0ge30gYXMgUmVjb3JkPHN0cmluZywgRXhjbHVkZTxUW2tleW9mIFRdLCB1bmRlZmluZWQ+IHwgbnVsbD5cclxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhvYmopKSB7XHJcbiAgICByZXRba2V5XSA9IGlzVW5kZWZpbmVkKHZhbHVlKSA/IG51bGwgOiAodmFsdWUgYXMgRXhjbHVkZTxUW2tleW9mIFRdLCB1bmRlZmluZWQ+KVxyXG4gIH1cclxuICByZXR1cm4gcmV0XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBpc0FycmF5T2YgPSA8VD4oYXJyOiB1bmtub3duLCBndWFyZDogKHY6IHVua25vd24pID0+IHYgaXMgVCk6IGFyciBpcyBUW10gPT5cclxuICBBcnJheS5pc0FycmF5KGFycikgJiYgYXJyLmV2ZXJ5KGd1YXJkKVxyXG5cclxuZXhwb3J0IGNvbnN0IHdhaXRGb3JldmVyID0gKCk6IFByb21pc2U8bmV2ZXI+ID0+IG5ldyBQcm9taXNlPG5ldmVyPihub29wKVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdHJ1ZSBpZiBvbmx5IG9uZSBvZiB0aGUgYXJndW1lbnRzIGlzIHRydXRoeVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHhvciA9IChhOiB1bmtub3duLCBiOiB1bmtub3duKSA9PiAhISgoYSB8fCBiKSAmJiAhKGEgJiYgYikpXHJcblxyXG4vKipcclxuICogU2hvcnRjdXQgZm9yIGNyZWF0aW5nIHN0cmluZyBrZXkgJiB2YWx1ZSBlbnVtcy4gTmF0aXZlIFRTIEVudW1zIGFyZSBwcm9ibGVtYXRpYyBpbiBtYW55IHdheXNcclxuICogKHRyYW5zZm9ybSBjb2RlLCBpbnN0ZWFkIG9mIGp1c3QgYWRkaW5nIHR5cGVzOyB5b3UgY2FudCBwdXQgYSBzdHJpbmcgbGl0ZXJhbCBtYXRjaGluZyB0aGUgZW51bSB2YWx1ZVxyXG4gKiBpbiBhIHZhcmlhYmxlIHR5cGVkIGFzIHRoZSBlbnVtLCBldGMuKVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IFN0cmluZ0VudW0gPSA8VCBleHRlbmRzIHN0cmluZz4oYXJnczogVFtdKSA9PiB7XHJcbiAgY29uc3QgZW51bU9iaiA9IE9iamVjdC5mcm9tRW50cmllcyhhcmdzLm1hcCgoYXJnKSA9PiBbYXJnLCBhcmddKSkgYXMge1xyXG4gICAgW0sgaW4gVF06IEtcclxuICB9XHJcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoZW51bU9iailcclxufVxyXG5cclxuLyoqXHJcbiAqIFNob3J0Y3V0IGZvciAodHlwZW9mIFN0cmluZ0VudW0pW2tleW9mIHR5cGVvZiBTdHJpbmdFbnVtXVxyXG4gKi9cclxuZXhwb3J0IHR5cGUgU3RyaW5nRW51bVZhbHVlczxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgc3RyaW5nPj4gPSB7XHJcbiAgW0sgaW4ga2V5b2YgVF06IFRbS10gZXh0ZW5kcyBzdHJpbmcgPyBUW0tdIDogbmV2ZXJcclxufVtrZXlvZiBUXVxyXG5cclxuLyoqXHJcbiAqIEdldCBmaXJzdCBub24tdW5kZWZpbmVkL251bGwgdmFsdWUsIG9yIHVuZGVmaW5lZCBpZiBub25lIGZvdW5kXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZmlyc3REZWZpbmVkVmFsdWUgPSA8VD4oXHJcbiAgLi4uYXJnczogKFQgfCB1bmRlZmluZWQgfCBudWxsKVtdXHJcbik6IFQgfCB1bmRlZmluZWQgPT4ge1xyXG4gIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcclxuICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQoYXJnKSkgcmV0dXJuIGFyZ1xyXG4gIH1cclxuICByZXR1cm4gdW5kZWZpbmVkXHJcbn1cclxuIl0sImZpbGUiOiJEOi9zcGVja2xlLXNlcnZlci9wYWNrYWdlcy9zaGFyZWQvZGlzdC9lc20vY29yZS9oZWxwZXJzL3V0aWxpdHkuanMifQ==