UNPKG

astx

Version:

super powerful structural search and replace for JavaScript and TypeScript to automate your refactoring

349 lines (308 loc) 35.7 kB
import CompilePathError from '../util/CompilePathError.mjs' import compileMatcher, { mergeCaptures } from './index.mjs' import indentDebug from './indentDebug.mjs' const defaultUnorderedFields = {} for (const [type, field] of [ ['ClassBody', 'body'], ['ClassDeclaration', 'implements'], ['DeclareClass', 'implements'], ['DeclareExportDeclaration', 'specifiers'], ['DeclareInterface', 'extends'], ['EnumDeclaration', 'body'], ['ExportNamedDeclaration', 'specifiers'], ['ImportDeclaration', 'specifiers'], ['InterfaceDeclaration', 'extends'], ['IntersectionTypeAnnotation', 'types'], ['JSXOpeningElement', 'attributes'], ['ObjectExpression', 'properties'], ['ObjectPattern', 'properties'], ['ObjectTypeAnnotation', 'properties'], ['TSEnumDeclaration', 'members'], ['TSInterfaceBody', 'body'], ['TSInterfaceDeclaration', 'extends'], ['TSIntersectionType', 'types'], ['TSTypeLiteral', 'members'], ['TSUnionType', 'types'], ['UnionTypeAnnotation', 'types'], ]) { const forType = defaultUnorderedFields[type] || (defaultUnorderedFields[type] = {}) forType[field] = true } function getDefaultUnordered(path) { var _defaultUnorderedFiel if (Array.isArray(path)) { var _path$ const parent = (_path$ = path[0]) === null || _path$ === void 0 ? void 0 : _path$.parentPath if (!parent) return false return getDefaultUnordered(parent) } if (!path.node || !path.name) return false return Boolean( (_defaultUnorderedFiel = defaultUnorderedFields[path.node.type]) === null || _defaultUnorderedFiel === void 0 ? void 0 : _defaultUnorderedFiel[path.name] ) } export default function compileGenericArrayMatcher( path, compileOptions, { compileElemMatcher = compileMatcher, defaultUnordered = getDefaultUnordered(path), skipElement = () => false, } = {} ) { const paths = Array.isArray(path) ? path : path.filter(() => true) const pattern = path.map((p) => p.node) const { debug } = compileOptions const elemOptions = { ...compileOptions, debug: indentDebug(debug, 2) } let matchers = pattern.map((value, i) => compileElemMatcher(paths[i], elemOptions) ) assertArrayMatchersValid(matchers) const unordered = matchers.some((m) => m.restPlaceholder || m.placeholder === '$Unordered') || (defaultUnordered && !matchers.some((m) => m.placeholder === '$Ordered' || m.arrayPlaceholder)) matchers = matchers.filter( (m) => m.placeholder !== '$Ordered' && m.placeholder !== '$Unordered' ) if (unordered) { return compileUnorderedArrayMatcher(paths, compileOptions, { matchers, }) } if (matchers.some((m) => m.placeholder || m.arrayPlaceholder)) { return compileOrderedArrayMatcher(paths, compileOptions, { matchers, skipElement, }) } return compileExactArrayMatcher(paths, compileOptions, { matchers, skipElement, }) } function assertArrayMatchersValid(matchers) { const otherMatchers = [] let arrayMatcherCount = 0 let restMatcher for (let i = 0; i < matchers.length; i++) { if (matchers[i].restPlaceholder) { if (restMatcher) { throw new CompilePathError( `can't have two or more rest matchers as siblings`, matchers[i].pattern ) } else if (arrayMatcherCount) { throw new CompilePathError( `can't mix array and rest matchers`, matchers[i].pattern ) } else { restMatcher = matchers[i] } } else if (matchers[i].arrayPlaceholder) { if (restMatcher) { throw new CompilePathError( `can't mix array and rest matchers`, matchers[i].pattern ) } arrayMatcherCount++ } else { otherMatchers.push(matchers[i]) } } } function compileOrderedArrayMatcher( paths, compileOptions, { matchers, skipElement = () => false } ) { const { debug } = compileOptions function remainingElements(matcherIndex) { let count = 0 for (let i = matcherIndex; i < matchers.length; i++) { if (!matchers[i].arrayPlaceholder) count++ } return count } function matchElem(paths, sliceStart, arrayIndex, matcherIndex, matchSoFar) { while (arrayIndex < paths.length && skipElement(paths[arrayIndex])) arrayIndex++ if (arrayIndex === paths.length) { return remainingElements(matcherIndex) === 0 ? matchSoFar || {} : null } if (matcherIndex === matchers.length) return null const matcher = matchers[matcherIndex] const { arrayPlaceholder } = matcher if (arrayPlaceholder) { if (matcherIndex === matchers.length - 1) { return mergeCaptures(matchSoFar, { arrayCaptures: { [arrayPlaceholder]: paths.slice(sliceStart), }, }) } return matchElem( paths, sliceStart, arrayIndex, matcherIndex + 1, matchSoFar ) } else { var _matchers const origMatchSoFar = matchSoFar const prevArrayPlaceholder = (_matchers = matchers[matcherIndex - 1]) === null || _matchers === void 0 ? void 0 : _matchers.arrayPlaceholder const end = prevArrayPlaceholder ? paths.length - remainingElements(matcherIndex + 1) : arrayIndex + 1 for (let i = arrayIndex; i < end; i++) { const elemPath = paths[i] if (skipElement(elemPath)) continue matchSoFar = matcher.match(elemPath, origMatchSoFar) if (!matchSoFar) continue if (prevArrayPlaceholder) { matchSoFar = mergeCaptures(matchSoFar, { arrayCaptures: { [prevArrayPlaceholder]: paths.slice(sliceStart, i), }, }) } const restMatch = matchElem( paths, i + 1, i + 1, matcherIndex + 1, matchSoFar ) if (restMatch) return restMatch } } return null } return { pattern: paths, match: (path, matchSoFar) => { debug('Array (ordered)') if (!Array.isArray(path.value)) return null const paths = path.filter(() => true) let result = matchElem(paths, 0, 0, 0, matchSoFar) if (!result) return result // make sure all * captures are present in results // (if there are more than one adjacent *, all captured paths will be in the // last one and the rest will be empty) for (const matcher of matchers) { var _result, _result$arrayCaptures const { arrayPlaceholder } = matcher if (!arrayPlaceholder) continue if ( !( (_result = result) !== null && _result !== void 0 && (_result$arrayCaptures = _result.arrayCaptures) !== null && _result$arrayCaptures !== void 0 && _result$arrayCaptures[arrayPlaceholder] ) ) result = mergeCaptures(result, { arrayCaptures: { [arrayPlaceholder]: [], }, }) } return result }, } } function compileUnorderedArrayMatcher( paths, compileOptions, { matchers, skipElement = () => false } ) { const { debug } = compileOptions const restMatcher = matchers.find((m) => m.restPlaceholder) matchers = matchers.filter((m) => !m.restPlaceholder) const restPlaceholder = restMatcher === null || restMatcher === void 0 ? void 0 : restMatcher.restPlaceholder return { pattern: paths, match: (path, result) => { debug('Array (unordered)') if (!Array.isArray(path.value)) return null const paths = path.filter(() => true) for (const m of matchers) { let i let found = false for (i = 0; i < paths.length; i++) { if (skipElement(paths[i])) { i++ continue } const match = m.match(paths[i], result) if (!match) continue result = match paths.splice(i, 1) found = true break } if (!found) { return null } } if (restPlaceholder) { return mergeCaptures(result, { arrayCaptures: { [restPlaceholder]: paths, }, }) } else { if (paths.length) { return null } return result || {} } }, } } function compileExactArrayMatcher( paths, compileOptions, { matchers, skipElement = () => false } ) { const { debug } = compileOptions return { pattern: paths, match: (path, matchSoFar) => { debug('Array (exact)') if (!Array.isArray(path.value)) return null const paths = path.filter((p) => !skipElement(p)) let m = 0, i = 0 while (i < paths.length || m < matchers.length) { debug(' [%d]', i) if (i >= paths.length || m >= matchers.length) { debug(' length mismatch') return null } matchSoFar = matchers[m].match(paths[i], matchSoFar) if (!matchSoFar) return null m++ i++ } return matchSoFar || {} }, } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDb21waWxlUGF0aEVycm9yIiwiY29tcGlsZU1hdGNoZXIiLCJtZXJnZUNhcHR1cmVzIiwiaW5kZW50RGVidWciLCJkZWZhdWx0VW5vcmRlcmVkRmllbGRzIiwidHlwZSIsImZpZWxkIiwiZm9yVHlwZSIsImdldERlZmF1bHRVbm9yZGVyZWQiLCJwYXRoIiwiQXJyYXkiLCJpc0FycmF5IiwicGFyZW50IiwicGFyZW50UGF0aCIsIm5vZGUiLCJuYW1lIiwiQm9vbGVhbiIsImNvbXBpbGVHZW5lcmljQXJyYXlNYXRjaGVyIiwiY29tcGlsZU9wdGlvbnMiLCJjb21waWxlRWxlbU1hdGNoZXIiLCJkZWZhdWx0VW5vcmRlcmVkIiwic2tpcEVsZW1lbnQiLCJwYXRocyIsImZpbHRlciIsInBhdHRlcm4iLCJtYXAiLCJwIiwiZGVidWciLCJlbGVtT3B0aW9ucyIsIm1hdGNoZXJzIiwidmFsdWUiLCJpIiwiYXNzZXJ0QXJyYXlNYXRjaGVyc1ZhbGlkIiwidW5vcmRlcmVkIiwic29tZSIsIm0iLCJyZXN0UGxhY2Vob2xkZXIiLCJwbGFjZWhvbGRlciIsImFycmF5UGxhY2Vob2xkZXIiLCJjb21waWxlVW5vcmRlcmVkQXJyYXlNYXRjaGVyIiwiY29tcGlsZU9yZGVyZWRBcnJheU1hdGNoZXIiLCJjb21waWxlRXhhY3RBcnJheU1hdGNoZXIiLCJvdGhlck1hdGNoZXJzIiwiYXJyYXlNYXRjaGVyQ291bnQiLCJyZXN0TWF0Y2hlciIsImxlbmd0aCIsInB1c2giLCJyZW1haW5pbmdFbGVtZW50cyIsIm1hdGNoZXJJbmRleCIsImNvdW50IiwibWF0Y2hFbGVtIiwic2xpY2VTdGFydCIsImFycmF5SW5kZXgiLCJtYXRjaFNvRmFyIiwibWF0Y2hlciIsImFycmF5Q2FwdHVyZXMiLCJzbGljZSIsIm9yaWdNYXRjaFNvRmFyIiwicHJldkFycmF5UGxhY2Vob2xkZXIiLCJlbmQiLCJlbGVtUGF0aCIsIm1hdGNoIiwicmVzdE1hdGNoIiwicmVzdWx0IiwiZmluZCIsImZvdW5kIiwic3BsaWNlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbXBpbGVNYXRjaGVyL0dlbmVyaWNBcnJheU1hdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTm9kZVBhdGgsIE5vZGUgfSBmcm9tICcuLi90eXBlcydcbmltcG9ydCBDb21waWxlUGF0aEVycm9yIGZyb20gJy4uL3V0aWwvQ29tcGlsZVBhdGhFcnJvcidcbmltcG9ydCBjb21waWxlTWF0Y2hlciwge1xuICBDb21waWxlZE1hdGNoZXIsXG4gIENvbXBpbGVPcHRpb25zLFxuICBNYXRjaFJlc3VsdCxcbiAgbWVyZ2VDYXB0dXJlcyxcbn0gZnJvbSAnLidcbmltcG9ydCBpbmRlbnREZWJ1ZyBmcm9tICcuL2luZGVudERlYnVnJ1xuXG5jb25zdCBkZWZhdWx0VW5vcmRlcmVkRmllbGRzOiB7IFtrIGluIHN0cmluZ10/OiB7IFtrIGluIHN0cmluZ10/OiB0cnVlIH0gfSA9IHt9XG5mb3IgKGNvbnN0IFt0eXBlLCBmaWVsZF0gb2YgW1xuICBbJ0NsYXNzQm9keScsICdib2R5J10sXG4gIFsnQ2xhc3NEZWNsYXJhdGlvbicsICdpbXBsZW1lbnRzJ10sXG4gIFsnRGVjbGFyZUNsYXNzJywgJ2ltcGxlbWVudHMnXSxcbiAgWydEZWNsYXJlRXhwb3J0RGVjbGFyYXRpb24nLCAnc3BlY2lmaWVycyddLFxuICBbJ0RlY2xhcmVJbnRlcmZhY2UnLCAnZXh0ZW5kcyddLFxuICBbJ0VudW1EZWNsYXJhdGlvbicsICdib2R5J10sXG4gIFsnRXhwb3J0TmFtZWREZWNsYXJhdGlvbicsICdzcGVjaWZpZXJzJ10sXG4gIFsnSW1wb3J0RGVjbGFyYXRpb24nLCAnc3BlY2lmaWVycyddLFxuICBbJ0ludGVyZmFjZURlY2xhcmF0aW9uJywgJ2V4dGVuZHMnXSxcbiAgWydJbnRlcnNlY3Rpb25UeXBlQW5ub3RhdGlvbicsICd0eXBlcyddLFxuICBbJ0pTWE9wZW5pbmdFbGVtZW50JywgJ2F0dHJpYnV0ZXMnXSxcbiAgWydPYmplY3RFeHByZXNzaW9uJywgJ3Byb3BlcnRpZXMnXSxcbiAgWydPYmplY3RQYXR0ZXJuJywgJ3Byb3BlcnRpZXMnXSxcbiAgWydPYmplY3RUeXBlQW5ub3RhdGlvbicsICdwcm9wZXJ0aWVzJ10sXG4gIFsnVFNFbnVtRGVjbGFyYXRpb24nLCAnbWVtYmVycyddLFxuICBbJ1RTSW50ZXJmYWNlQm9keScsICdib2R5J10sXG4gIFsnVFNJbnRlcmZhY2VEZWNsYXJhdGlvbicsICdleHRlbmRzJ10sXG4gIFsnVFNJbnRlcnNlY3Rpb25UeXBlJywgJ3R5cGVzJ10sXG4gIFsnVFNUeXBlTGl0ZXJhbCcsICdtZW1iZXJzJ10sXG4gIFsnVFNVbmlvblR5cGUnLCAndHlwZXMnXSxcbiAgWydVbmlvblR5cGVBbm5vdGF0aW9uJywgJ3R5cGVzJ10sXG5dKSB7XG4gIGNvbnN0IGZvclR5cGUgPVxuICAgIGRlZmF1bHRVbm9yZGVyZWRGaWVsZHNbdHlwZV0gfHwgKGRlZmF1bHRVbm9yZGVyZWRGaWVsZHNbdHlwZV0gPSB7fSlcbiAgZm9yVHlwZVtmaWVsZF0gPSB0cnVlXG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRVbm9yZGVyZWQoXG4gIHBhdGg6IE5vZGVQYXRoPE5vZGUsIE5vZGVbXT4gfCBOb2RlUGF0aDxOb2RlLCBOb2RlPltdXG4pOiBib29sZWFuIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocGF0aCkpIHtcbiAgICBjb25zdCBwYXJlbnQgPSBwYXRoWzBdPy5wYXJlbnRQYXRoXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiBmYWxzZVxuICAgIHJldHVybiBnZXREZWZhdWx0VW5vcmRlcmVkKHBhcmVudClcbiAgfVxuICBpZiAoIXBhdGgubm9kZSB8fCAhcGF0aC5uYW1lKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIEJvb2xlYW4oZGVmYXVsdFVub3JkZXJlZEZpZWxkc1twYXRoLm5vZGUudHlwZV0/LltwYXRoLm5hbWVdKVxufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21waWxlR2VuZXJpY0FycmF5TWF0Y2hlcihcbiAgcGF0aDogTm9kZVBhdGg8Tm9kZSwgTm9kZVtdPiB8IE5vZGVQYXRoPE5vZGUsIE5vZGU+W10sXG4gIGNvbXBpbGVPcHRpb25zOiBDb21waWxlT3B0aW9ucyxcbiAge1xuICAgIGNvbXBpbGVFbGVtTWF0Y2hlciA9IGNvbXBpbGVNYXRjaGVyLFxuICAgIGRlZmF1bHRVbm9yZGVyZWQgPSBnZXREZWZhdWx0VW5vcmRlcmVkKHBhdGgpLFxuICAgIHNraXBFbGVtZW50ID0gKCkgPT4gZmFsc2UsXG4gIH06IHtcbiAgICBjb21waWxlRWxlbU1hdGNoZXI/OiAoXG4gICAgICBwYXRoOiBOb2RlUGF0aCxcbiAgICAgIG9wdGlvbnM6IENvbXBpbGVPcHRpb25zXG4gICAgKSA9PiBDb21waWxlZE1hdGNoZXJcbiAgICBkZWZhdWx0VW5vcmRlcmVkPzogYm9vbGVhblxuICAgIHNraXBFbGVtZW50PzogKHBhdGg6IE5vZGVQYXRoKSA9PiBib29sZWFuXG4gIH0gPSB7fVxuKTogQ29tcGlsZWRNYXRjaGVyIHtcbiAgY29uc3QgcGF0aHMgPSBBcnJheS5pc0FycmF5KHBhdGgpID8gcGF0aCA6IHBhdGguZmlsdGVyKCgpID0+IHRydWUpXG4gIGNvbnN0IHBhdHRlcm46IE5vZGVbXSA9IHBhdGgubWFwKChwOiBOb2RlUGF0aCkgPT4gcC5ub2RlKVxuICBjb25zdCB7IGRlYnVnIH0gPSBjb21waWxlT3B0aW9uc1xuICBjb25zdCBlbGVtT3B0aW9ucyA9IHtcbiAgICAuLi5jb21waWxlT3B0aW9ucyxcbiAgICBkZWJ1ZzogaW5kZW50RGVidWcoZGVidWcsIDIpLFxuICB9XG4gIGxldCBtYXRjaGVyczogQ29tcGlsZWRNYXRjaGVyW10gPSBwYXR0ZXJuLm1hcCgodmFsdWUsIGkpID0+XG4gICAgY29tcGlsZUVsZW1NYXRjaGVyKHBhdGhzW2ldLCBlbGVtT3B0aW9ucylcbiAgKVxuXG4gIGFzc2VydEFycmF5TWF0Y2hlcnNWYWxpZChtYXRjaGVycylcblxuICBjb25zdCB1bm9yZGVyZWQgPVxuICAgIG1hdGNoZXJzLnNvbWUoKG0pID0+IG0ucmVzdFBsYWNlaG9sZGVyIHx8IG0ucGxhY2Vob2xkZXIgPT09ICckVW5vcmRlcmVkJykgfHxcbiAgICAoZGVmYXVsdFVub3JkZXJlZCAmJlxuICAgICAgIW1hdGNoZXJzLnNvbWUoKG0pID0+IG0ucGxhY2Vob2xkZXIgPT09ICckT3JkZXJlZCcgfHwgbS5hcnJheVBsYWNlaG9sZGVyKSlcblxuICBtYXRjaGVycyA9IG1hdGNoZXJzLmZpbHRlcihcbiAgICAobSkgPT4gbS5wbGFjZWhvbGRlciAhPT0gJyRPcmRlcmVkJyAmJiBtLnBsYWNlaG9sZGVyICE9PSAnJFVub3JkZXJlZCdcbiAgKVxuXG4gIGlmICh1bm9yZGVyZWQpIHtcbiAgICByZXR1cm4gY29tcGlsZVVub3JkZXJlZEFycmF5TWF0Y2hlcihwYXRocywgY29tcGlsZU9wdGlvbnMsIHtcbiAgICAgIG1hdGNoZXJzLFxuICAgIH0pXG4gIH1cblxuICBpZiAobWF0Y2hlcnMuc29tZSgobSkgPT4gbS5wbGFjZWhvbGRlciB8fCBtLmFycmF5UGxhY2Vob2xkZXIpKSB7XG4gICAgcmV0dXJuIGNvbXBpbGVPcmRlcmVkQXJyYXlNYXRjaGVyKHBhdGhzLCBjb21waWxlT3B0aW9ucywge1xuICAgICAgbWF0Y2hlcnMsXG4gICAgICBza2lwRWxlbWVudCxcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGNvbXBpbGVFeGFjdEFycmF5TWF0Y2hlcihwYXRocywgY29tcGlsZU9wdGlvbnMsIHtcbiAgICBtYXRjaGVycyxcbiAgICBza2lwRWxlbWVudCxcbiAgfSlcbn1cblxuZnVuY3Rpb24gYXNzZXJ0QXJyYXlNYXRjaGVyc1ZhbGlkKG1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXSkge1xuICBjb25zdCBvdGhlck1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXSA9IFtdXG4gIGxldCBhcnJheU1hdGNoZXJDb3VudCA9IDBcbiAgbGV0IHJlc3RNYXRjaGVyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobWF0Y2hlcnNbaV0ucmVzdFBsYWNlaG9sZGVyKSB7XG4gICAgICBpZiAocmVzdE1hdGNoZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IENvbXBpbGVQYXRoRXJyb3IoXG4gICAgICAgICAgYGNhbid0IGhhdmUgdHdvIG9yIG1vcmUgcmVzdCBtYXRjaGVycyBhcyBzaWJsaW5nc2AsXG4gICAgICAgICAgbWF0Y2hlcnNbaV0ucGF0dGVybiBhcyBOb2RlUGF0aFxuICAgICAgICApXG4gICAgICB9IGVsc2UgaWYgKGFycmF5TWF0Y2hlckNvdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBDb21waWxlUGF0aEVycm9yKFxuICAgICAgICAgIGBjYW4ndCBtaXggYXJyYXkgYW5kIHJlc3QgbWF0Y2hlcnNgLFxuICAgICAgICAgIG1hdGNoZXJzW2ldLnBhdHRlcm4gYXMgTm9kZVBhdGhcbiAgICAgICAgKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdE1hdGNoZXIgPSBtYXRjaGVyc1tpXVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobWF0Y2hlcnNbaV0uYXJyYXlQbGFjZWhvbGRlcikge1xuICAgICAgaWYgKHJlc3RNYXRjaGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBDb21waWxlUGF0aEVycm9yKFxuICAgICAgICAgIGBjYW4ndCBtaXggYXJyYXkgYW5kIHJlc3QgbWF0Y2hlcnNgLFxuICAgICAgICAgIG1hdGNoZXJzW2ldLnBhdHRlcm4gYXMgTm9kZVBhdGhcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgYXJyYXlNYXRjaGVyQ291bnQrK1xuICAgIH0gZWxzZSB7XG4gICAgICBvdGhlck1hdGNoZXJzLnB1c2gobWF0Y2hlcnNbaV0pXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVPcmRlcmVkQXJyYXlNYXRjaGVyKFxuICBwYXRoczogTm9kZVBhdGg8Tm9kZSwgTm9kZT5bXSxcbiAgY29tcGlsZU9wdGlvbnM6IENvbXBpbGVPcHRpb25zLFxuICB7XG4gICAgbWF0Y2hlcnMsXG4gICAgc2tpcEVsZW1lbnQgPSAoKSA9PiBmYWxzZSxcbiAgfToge1xuICAgIG1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXVxuICAgIHNraXBFbGVtZW50PzogKHBhdGg6IE5vZGVQYXRoKSA9PiBib29sZWFuXG4gIH1cbik6IENvbXBpbGVkTWF0Y2hlciB7XG4gIGNvbnN0IHsgZGVidWcgfSA9IGNvbXBpbGVPcHRpb25zXG5cbiAgZnVuY3Rpb24gcmVtYWluaW5nRWxlbWVudHMobWF0Y2hlckluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBjb3VudCA9IDBcbiAgICBmb3IgKGxldCBpID0gbWF0Y2hlckluZGV4OyBpIDwgbWF0Y2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghbWF0Y2hlcnNbaV0uYXJyYXlQbGFjZWhvbGRlcikgY291bnQrK1xuICAgIH1cbiAgICByZXR1cm4gY291bnRcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hdGNoRWxlbShcbiAgICBwYXRoczogTm9kZVBhdGhbXSxcbiAgICBzbGljZVN0YXJ0OiBudW1iZXIsXG4gICAgYXJyYXlJbmRleDogbnVtYmVyLFxuICAgIG1hdGNoZXJJbmRleDogbnVtYmVyLFxuICAgIG1hdGNoU29GYXI6IE1hdGNoUmVzdWx0XG4gICk6IE1hdGNoUmVzdWx0IHtcbiAgICB3aGlsZSAoYXJyYXlJbmRleCA8IHBhdGhzLmxlbmd0aCAmJiBza2lwRWxlbWVudChwYXRoc1thcnJheUluZGV4XSkpXG4gICAgICBhcnJheUluZGV4KytcblxuICAgIGlmIChhcnJheUluZGV4ID09PSBwYXRocy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiByZW1haW5pbmdFbGVtZW50cyhtYXRjaGVySW5kZXgpID09PSAwID8gbWF0Y2hTb0ZhciB8fCB7fSA6IG51bGxcbiAgICB9XG5cbiAgICBpZiAobWF0Y2hlckluZGV4ID09PSBtYXRjaGVycy5sZW5ndGgpIHJldHVybiBudWxsXG5cbiAgICBjb25zdCBtYXRjaGVyID0gbWF0Y2hlcnNbbWF0Y2hlckluZGV4XVxuXG4gICAgY29uc3QgeyBhcnJheVBsYWNlaG9sZGVyIH0gPSBtYXRjaGVyXG5cbiAgICBpZiAoYXJyYXlQbGFjZWhvbGRlcikge1xuICAgICAgaWYgKG1hdGNoZXJJbmRleCA9PT0gbWF0Y2hlcnMubGVuZ3RoIC0gMSkge1xuICAgICAgICByZXR1cm4gbWVyZ2VDYXB0dXJlcyhtYXRjaFNvRmFyLCB7XG4gICAgICAgICAgYXJyYXlDYXB0dXJlczoge1xuICAgICAgICAgICAgW2FycmF5UGxhY2Vob2xkZXJdOiBwYXRocy5zbGljZShzbGljZVN0YXJ0KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbWF0Y2hFbGVtKFxuICAgICAgICBwYXRocyxcbiAgICAgICAgc2xpY2VTdGFydCxcbiAgICAgICAgYXJyYXlJbmRleCxcbiAgICAgICAgbWF0Y2hlckluZGV4ICsgMSxcbiAgICAgICAgbWF0Y2hTb0ZhclxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBvcmlnTWF0Y2hTb0ZhciA9IG1hdGNoU29GYXJcbiAgICAgIGNvbnN0IHByZXZBcnJheVBsYWNlaG9sZGVyID0gbWF0Y2hlcnNbbWF0Y2hlckluZGV4IC0gMV0/LmFycmF5UGxhY2Vob2xkZXJcbiAgICAgIGNvbnN0IGVuZCA9IHByZXZBcnJheVBsYWNlaG9sZGVyXG4gICAgICAgID8gcGF0aHMubGVuZ3RoIC0gcmVtYWluaW5nRWxlbWVudHMobWF0Y2hlckluZGV4ICsgMSlcbiAgICAgICAgOiBhcnJheUluZGV4ICsgMVxuXG4gICAgICBmb3IgKGxldCBpID0gYXJyYXlJbmRleDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGVsZW1QYXRoID0gcGF0aHNbaV1cblxuICAgICAgICBpZiAoc2tpcEVsZW1lbnQoZWxlbVBhdGgpKSBjb250aW51ZVxuXG4gICAgICAgIG1hdGNoU29GYXIgPSBtYXRjaGVyLm1hdGNoKGVsZW1QYXRoLCBvcmlnTWF0Y2hTb0ZhcilcblxuICAgICAgICBpZiAoIW1hdGNoU29GYXIpIGNvbnRpbnVlXG5cbiAgICAgICAgaWYgKHByZXZBcnJheVBsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgbWF0Y2hTb0ZhciA9IG1lcmdlQ2FwdHVyZXMobWF0Y2hTb0Zhciwge1xuICAgICAgICAgICAgYXJyYXlDYXB0dXJlczoge1xuICAgICAgICAgICAgICBbcHJldkFycmF5UGxhY2Vob2xkZXJdOiBwYXRocy5zbGljZShzbGljZVN0YXJ0LCBpKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3RNYXRjaCA9IG1hdGNoRWxlbShcbiAgICAgICAgICBwYXRocyxcbiAgICAgICAgICBpICsgMSxcbiAgICAgICAgICBpICsgMSxcbiAgICAgICAgICBtYXRjaGVySW5kZXggKyAxLFxuICAgICAgICAgIG1hdGNoU29GYXJcbiAgICAgICAgKVxuXG4gICAgICAgIGlmIChyZXN0TWF0Y2gpIHJldHVybiByZXN0TWF0Y2hcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXR0ZXJuOiBwYXRocyxcbiAgICBtYXRjaDogKHBhdGg6IE5vZGVQYXRoLCBtYXRjaFNvRmFyOiBNYXRjaFJlc3VsdCk6IE1hdGNoUmVzdWx0ID0+IHtcbiAgICAgIGRlYnVnKCdBcnJheSAob3JkZXJlZCknKVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aC52YWx1ZSkpIHJldHVybiBudWxsXG4gICAgICBjb25zdCBwYXRocyA9IChwYXRoIGFzIE5vZGVQYXRoPE5vZGUsIE5vZGVbXT4pLmZpbHRlcigoKSA9PiB0cnVlKVxuXG4gICAgICBsZXQgcmVzdWx0ID0gbWF0Y2hFbGVtKHBhdGhzLCAwLCAwLCAwLCBtYXRjaFNvRmFyKVxuICAgICAgaWYgKCFyZXN1bHQpIHJldHVybiByZXN1bHRcblxuICAgICAgLy8gbWFrZSBzdXJlIGFsbCAqIGNhcHR1cmVzIGFyZSBwcmVzZW50IGluIHJlc3VsdHNcbiAgICAgIC8vIChpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSBhZGphY2VudCAqLCBhbGwgY2FwdHVyZWQgcGF0aHMgd2lsbCBiZSBpbiB0aGVcbiAgICAgIC8vIGxhc3Qgb25lIGFuZCB0aGUgcmVzdCB3aWxsIGJlIGVtcHR5KVxuICAgICAgZm9yIChjb25zdCBtYXRjaGVyIG9mIG1hdGNoZXJzKSB7XG4gICAgICAgIGNvbnN0IHsgYXJyYXlQbGFjZWhvbGRlciB9ID0gbWF0Y2hlclxuICAgICAgICBpZiAoIWFycmF5UGxhY2Vob2xkZXIpIGNvbnRpbnVlXG4gICAgICAgIGlmICghcmVzdWx0Py5hcnJheUNhcHR1cmVzPy5bYXJyYXlQbGFjZWhvbGRlcl0pXG4gICAgICAgICAgcmVzdWx0ID0gbWVyZ2VDYXB0dXJlcyhyZXN1bHQsIHtcbiAgICAgICAgICAgIGFycmF5Q2FwdHVyZXM6IHsgW2FycmF5UGxhY2Vob2xkZXJdOiBbXSB9LFxuICAgICAgICAgIH0pXG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSxcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21waWxlVW5vcmRlcmVkQXJyYXlNYXRjaGVyKFxuICBwYXRoczogTm9kZVBhdGg8Tm9kZSwgTm9kZT5bXSxcbiAgY29tcGlsZU9wdGlvbnM6IENvbXBpbGVPcHRpb25zLFxuICB7XG4gICAgbWF0Y2hlcnMsXG4gICAgc2tpcEVsZW1lbnQgPSAoKSA9PiBmYWxzZSxcbiAgfToge1xuICAgIG1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXVxuICAgIHNraXBFbGVtZW50PzogKHBhdGg6IE5vZGVQYXRoKSA9PiBib29sZWFuXG4gIH1cbik6IENvbXBpbGVkTWF0Y2hlciB7XG4gIGNvbnN0IHsgZGVidWcgfSA9IGNvbXBpbGVPcHRpb25zXG5cbiAgY29uc3QgcmVzdE1hdGNoZXIgPSBtYXRjaGVycy5maW5kKChtKSA9PiBtLnJlc3RQbGFjZWhvbGRlcilcbiAgbWF0Y2hlcnMgPSBtYXRjaGVycy5maWx0ZXIoKG0pID0+ICFtLnJlc3RQbGFjZWhvbGRlcilcbiAgY29uc3QgcmVzdFBsYWNlaG9sZGVyID0gcmVzdE1hdGNoZXI/LnJlc3RQbGFjZWhvbGRlclxuXG4gIHJldHVybiB7XG4gICAgcGF0dGVybjogcGF0aHMsXG4gICAgbWF0Y2g6IChwYXRoOiBOb2RlUGF0aCwgcmVzdWx0OiBNYXRjaFJlc3VsdCk6IE1hdGNoUmVzdWx0ID0+IHtcbiAgICAgIGRlYnVnKCdBcnJheSAodW5vcmRlcmVkKScpXG5cbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShwYXRoLnZhbHVlKSkgcmV0dXJuIG51bGxcblxuICAgICAgY29uc3QgcGF0aHMgPSAocGF0aCBhcyBOb2RlUGF0aDxOb2RlLCBOb2RlW10+KS5maWx0ZXIoKCkgPT4gdHJ1ZSlcblxuICAgICAgZm9yIChjb25zdCBtIG9mIG1hdGNoZXJzKSB7XG4gICAgICAgIGxldCBpXG4gICAgICAgIGxldCBmb3VuZCA9IGZhbHNlXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChza2lwRWxlbWVudChwYXRoc1tpXSkpIHtcbiAgICAgICAgICAgIGkrK1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgbWF0Y2ggPSBtLm1hdGNoKHBhdGhzW2ldLCByZXN1bHQpXG4gICAgICAgICAgaWYgKCFtYXRjaCkgY29udGludWVcbiAgICAgICAgICByZXN1bHQgPSBtYXRjaFxuICAgICAgICAgIHBhdGhzLnNwbGljZShpLCAxKVxuICAgICAgICAgIGZvdW5kID0gdHJ1ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChyZXN0UGxhY2Vob2xkZXIpIHtcbiAgICAgICAgcmV0dXJuIG1lcmdlQ2FwdHVyZXMocmVzdWx0LCB7XG4gICAgICAgICAgYXJyYXlDYXB0dXJlczogeyBbcmVzdFBsYWNlaG9sZGVyXTogcGF0aHMgfSxcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChwYXRocy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwge31cbiAgICAgIH1cbiAgICB9LFxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVFeGFjdEFycmF5TWF0Y2hlcihcbiAgcGF0aHM6IE5vZGVQYXRoPE5vZGUsIE5vZGU+W10sXG4gIGNvbXBpbGVPcHRpb25zOiBDb21waWxlT3B0aW9ucyxcbiAge1xuICAgIG1hdGNoZXJzLFxuICAgIHNraXBFbGVtZW50ID0gKCkgPT4gZmFsc2UsXG4gIH06IHtcbiAgICBtYXRjaGVyczogQ29tcGlsZWRNYXRjaGVyW11cbiAgICBza2lwRWxlbWVudD86IChwYXRoOiBOb2RlUGF0aCkgPT4gYm9vbGVhblxuICB9XG4pOiBDb21waWxlZE1hdGNoZXIge1xuICBjb25zdCB7IGRlYnVnIH0gPSBjb21waWxlT3B0aW9uc1xuICByZXR1cm4ge1xuICAgIHBhdHRlcm46IHBhdGhzLFxuICAgIG1hdGNoOiAocGF0aDogTm9kZVBhdGgsIG1hdGNoU29GYXI6IE1hdGNoUmVzdWx0KTogTWF0Y2hSZXN1bHQgPT4ge1xuICAgICAgZGVidWcoJ0FycmF5IChleGFjdCknKVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aC52YWx1ZSkpIHJldHVybiBudWxsXG5cbiAgICAgIGNvbnN0IHBhdGhzID0gcGF0aC5maWx0ZXIoKHApID0+ICFza2lwRWxlbWVudChwKSlcblxuICAgICAgbGV0IG0gPSAwLFxuICAgICAgICBpID0gMFxuICAgICAgd2hpbGUgKGkgPCBwYXRocy5sZW5ndGggfHwgbSA8IG1hdGNoZXJzLmxlbmd0aCkge1xuICAgICAgICBkZWJ1ZygnICBbJWRdJywgaSlcbiAgICAgICAgaWYgKGkgPj0gcGF0aHMubGVuZ3RoIHx8IG0gPj0gbWF0Y2hlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgZGVidWcoJyAgICBsZW5ndGggbWlzbWF0Y2gnKVxuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgbWF0Y2hTb0ZhciA9IG1hdGNoZXJzW21dLm1hdGNoKHBhdGhzW2ldLCBtYXRjaFNvRmFyKVxuICAgICAgICBpZiAoIW1hdGNoU29GYXIpIHJldHVybiBudWxsXG4gICAgICAgIG0rK1xuICAgICAgICBpKytcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYXRjaFNvRmFyIHx8IHt9XG4gICAgfSxcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBT0EsZ0JBQVAsTUFBNkIsMEJBQTdCO0FBQ0EsT0FBT0MsY0FBUDs7OztBQUlFQyxhQUpGO0FBS08sR0FMUDtBQU1BLE9BQU9DLFdBQVAsTUFBd0IsZUFBeEI7O0FBRUEsTUFBTUMsc0JBQW9FLEdBQUcsRUFBN0U7QUFDQSxLQUFLLE1BQU0sQ0FBQ0MsSUFBRCxFQUFPQyxLQUFQLENBQVgsSUFBNEI7QUFDMUIsQ0FBQyxXQUFELEVBQWMsTUFBZCxDQUQwQjtBQUUxQixDQUFDLGtCQUFELEVBQXFCLFlBQXJCLENBRjBCO0FBRzFCLENBQUMsY0FBRCxFQUFpQixZQUFqQixDQUgwQjtBQUkxQixDQUFDLDBCQUFELEVBQTZCLFlBQTdCLENBSjBCO0FBSzFCLENBQUMsa0JBQUQsRUFBcUIsU0FBckIsQ0FMMEI7QUFNMUIsQ0FBQyxpQkFBRCxFQUFvQixNQUFwQixDQU4wQjtBQU8xQixDQUFDLHdCQUFELEVBQTJCLFlBQTNCLENBUDBCO0FBUTFCLENBQUMsbUJBQUQsRUFBc0IsWUFBdEIsQ0FSMEI7QUFTMUIsQ0FBQyxzQkFBRCxFQUF5QixTQUF6QixDQVQwQjtBQVUxQixDQUFDLDRCQUFELEVBQStCLE9BQS9CLENBVjBCO0FBVzFCLENBQUMsbUJBQUQsRUFBc0IsWUFBdEIsQ0FYMEI7QUFZMUIsQ0FBQyxrQkFBRCxFQUFxQixZQUFyQixDQVowQjtBQWExQixDQUFDLGVBQUQsRUFBa0IsWUFBbEIsQ0FiMEI7QUFjMUIsQ0FBQyxzQkFBRCxFQUF5QixZQUF6QixDQWQwQjtBQWUxQixDQUFDLG1CQUFELEVBQXNCLFNBQXRCLENBZjBCO0FBZ0IxQixDQUFDLGlCQUFELEVBQW9CLE1BQXBCLENBaEIwQjtBQWlCMUIsQ0FBQyx3QkFBRCxFQUEyQixTQUEzQixDQWpCMEI7QUFrQjFCLENBQUMsb0JBQUQsRUFBdUIsT0FBdkIsQ0FsQjBCO0FBbUIxQixDQUFDLGVBQUQsRUFBa0IsU0FBbEIsQ0FuQjBCO0FBb0IxQixDQUFDLGFBQUQsRUFBZ0IsT0FBaEIsQ0FwQjBCO0FBcUIxQixDQUFDLHFCQUFELEVBQXdCLE9BQXhCLENBckIwQixDQUE1QjtBQXNCRztFQUNELE1BQU1DLE9BQU87RUFDWEgsc0JBQXNCLENBQUNDLElBQUQsQ0FBdEIsS0FBaUNELHNCQUFzQixDQUFDQyxJQUFELENBQXRCLEdBQStCLEVBQWhFLENBREY7RUFFQUUsT0FBTyxDQUFDRCxLQUFELENBQVAsR0FBaUIsSUFBakI7QUFDRDs7QUFFRCxTQUFTRSxtQkFBVDtBQUNFQyxJQURGO0FBRVc7RUFDVCxJQUFJQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0YsSUFBZCxDQUFKLEVBQXlCO0lBQ3ZCLE1BQU1HLE1BQU0sYUFBR0gsSUFBSSxDQUFDLENBQUQsQ0FBUCwyQ0FBRyxPQUFTSSxVQUF4QjtJQUNBLElBQUksQ0FBQ0QsTUFBTCxFQUFhLE9BQU8sS0FBUDtJQUNiLE9BQU9KLG1CQUFtQixDQUFDSSxNQUFELENBQTFCO0VBQ0Q7RUFDRCxJQUFJLENBQUNILElBQUksQ0FBQ0ssSUFBTixJQUFjLENBQUNMLElBQUksQ0FBQ00sSUFBeEIsRUFBOEIsT0FBTyxLQUFQO0VBQzlCLE9BQU9DLE9BQU8sMEJBQUNaLHNCQUFzQixDQUFDSyxJQUFJLENBQUNLLElBQUwsQ0FBVVQsSUFBWCxDQUF2QiwwREFBQyxzQkFBeUNJLElBQUksQ0FBQ00sSUFBOUMsQ0FBRCxDQUFkO0FBQ0Q7O0FBRUQsZUFBZSxTQUFTRSwwQkFBVDtBQUNiUixJQURhO0FBRWJTLGNBRmE7QUFHYjtFQUNFQyxrQkFBa0IsR0FBR2xCLGNBRHZCO0VBRUVtQixnQkFBZ0IsR0FBR1osbUJBQW1CLENBQUNDLElBQUQsQ0FGeEM7RUFHRVksV0FBVyxHQUFHLE1BQU0sS0FIdEI7Ozs7Ozs7O0FBV0ksRUFkUztBQWVJO0VBQ2pCLE1BQU1DLEtBQUssR0FBR1osS0FBSyxDQUFDQyxPQUFOLENBQWNGLElBQWQsSUFBc0JBLElBQXRCLEdBQTZCQSxJQUFJLENBQUNjLE1BQUwsQ0FBWSxNQUFNLElBQWxCLENBQTNDO0VBQ0EsTUFBTUMsT0FBZSxHQUFHZixJQUFJLENBQUNnQixHQUFMLENBQVMsQ0FBQ0MsQ0FBRCxLQUFpQkEsQ0FBQyxDQUFDWixJQUE1QixDQUF4QjtFQUNBLE1BQU0sRUFBRWEsS0FBRixLQUFZVCxjQUFsQjtFQUNBLE1BQU1VLFdBQVcsR0FBRztJQUNsQixHQUFHVixjQURlO0lBRWxCUyxLQUFLLEVBQUV4QixXQUFXLENBQUN3QixLQUFELEVBQVEsQ0FBUixDQUZBLEVBQXBCOztFQUlBLElBQUlFLFFBQTJCLEdBQUdMLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLENBQUNLLEtBQUQsRUFBUUMsQ0FBUjtFQUM1Q1osa0JBQWtCLENBQUNHLEtBQUssQ0FBQ1MsQ0FBRCxDQUFOLEVBQVdILFdBQVgsQ0FEYyxDQUFsQzs7O0VBSUFJLHdCQUF3QixDQUFDSCxRQUFELENBQXhCOztFQUVBLE1BQU1JLFNBQVM7RUFDYkosUUFBUSxDQUFDSyxJQUFULENBQWMsQ0FBQ0MsQ0FBRCxLQUFPQSxDQUFDLENBQUNDLGVBQUYsSUFBcUJELENBQUMsQ0FBQ0UsV0FBRixLQUFrQixZQUE1RDtFQUNDakIsZ0JBQWdCO0VBQ2YsQ0FBQ1MsUUFBUSxDQUFDSyxJQUFULENBQWMsQ0FBQ0MsQ0FBRCxLQUFPQSxDQUFDLENBQUNFLFdBQUYsS0FBa0IsVUFBbEIsSUFBZ0NGLENBQUMsQ0FBQ0csZ0JBQXZELENBSEw7O0VBS0FULFFBQVEsR0FBR0EsUUFBUSxDQUFDTixNQUFUO0VBQ1QsQ0FBQ1ksQ0FBRCxLQUFPQSxDQUFDLENBQUNFLFdBQUYsS0FBa0IsVUFBbEIsSUFBZ0NGLENBQUMsQ0FBQ0UsV0FBRixLQUFrQixZQURoRCxDQUFYOzs7RUFJQSxJQUFJSixTQUFKLEVBQWU7SUFDYixPQUFPTSw0QkFBNEIsQ0FBQ2pCLEtBQUQsRUFBUUosY0FBUixFQUF3QjtNQUN6RFcsUUFEeUQsRUFBeEIsQ0FBbkM7O0VBR0Q7O0VBRUQsSUFBSUEsUUFBUSxDQUFDSyxJQUFULENBQWMsQ0FBQ0MsQ0FBRCxLQUFPQSxDQUFDLENBQUNFLFdBQUYsSUFBaUJGLENBQUMsQ0FBQ0csZ0JBQXhDLENBQUosRUFBK0Q7SUFDN0QsT0FBT0UsMEJBQTBCLENBQUNsQixLQUFELEVBQVFKLGNBQVIsRUFBd0I7TUFDdkRXLFFBRHVEO01BRXZEUixXQUZ1RCxFQUF4QixDQUFqQzs7RUFJRDs7RUFFRCxPQUFPb0Isd0JBQXdCLENBQUNuQixLQUFELEVBQVFKLGNBQVIsRUFBd0I7SUFDckRXLFFBRHFEO0lBRXJEUixXQUZxRCxFQUF4QixDQUEvQjs7QUFJRDs7QUFFRCxTQUFTVyx3QkFBVCxDQUFrQ0gsUUFBbEMsRUFBK0Q7RUFDN0QsTUFBTWEsYUFBZ0MsR0FBRyxFQUF6QztFQUNBLElBQUlDLGlCQUFpQixHQUFHLENBQXhCO0VBQ0EsSUFBSUMsV0FBSjtFQUNBLEtBQUssSUFBSWIsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0YsUUFBUSxDQUFDZ0IsTUFBN0IsRUFBcUNkLENBQUMsRUFBdEMsRUFBMEM7SUFDeEMsSUFBSUYsUUFBUSxDQUFDRSxDQUFELENBQVIsQ0FBWUssZUFBaEIsRUFBaUM7TUFDL0IsSUFBSVEsV0FBSixFQUFpQjtRQUNmLE1BQU0sSUFBSTVDLGdCQUFKO1FBQ0gsa0RBREc7UUFFSjZCLFFBQVEsQ0FBQ0UsQ0FBRCxDQUFSLENBQVlQLE9BRlIsQ0FBTjs7TUFJRCxDQUxELE1BS08sSUFBSW1CLGlCQUFKLEVBQXVCO1FBQzVCLE1BQU0sSUFBSTNDLGdCQUFKO1FBQ0gsbUNBREc7UUFFSjZCLFFBQVEsQ0FBQ0UsQ0FBRCxDQUFSLENBQVlQLE9BRlIsQ0FBTjs7TUFJRCxDQUxNLE1BS0E7UUFDTG9CLFdBQVcsR0FBR2YsUUFBUSxDQUFDRSxDQUFELENBQXRCO01BQ0Q7SUFDRixDQWRELE1BY08sSUFBSUYsUUFBUSxDQUFDRSxDQUFELENBQVIsQ0FBWU8sZ0JBQWhCLEVBQWtDO01BQ3ZDLElBQUlNLFdBQUosRUFBaUI7UUFDZixNQUFNLElBQUk1QyxnQkFBSjtRQUNILG1DQURHO1FBRUo2QixRQUFRLENBQUNFLENBQUQsQ0FBUixDQUFZUCxPQUZSLENBQU47O01BSUQ7TUFDRG1CLGlCQUFpQjtJQUNsQixDQVJNLE1BUUE7TUFDTEQsYUFBYSxDQUFDSSxJQUFkLENBQW1CakIsUUFBUSxDQUFDRSxDQUFELENBQTNCO0lBQ0Q7RUFDRjtBQUNGOztBQUVELFNBQVNTLDBCQUFUO0FBQ0VsQixLQURGO0FBRUVKLGNBRkY7QUFHRTtFQUNFVyxRQURGO0VBRUVSLFdBQVcsR0FBRyxNQUFNLEtBRnRCLEVBSEY7Ozs7O0FBVW1CO0VBQ2pCLE1BQU0sRUFBRU0sS0FBRixLQUFZVCxjQUFsQjs7RUFFQSxTQUFTNkIsaUJBQVQsQ0FBMkJDLFlBQTNCLEVBQXlEO0lBQ3ZELElBQUlDLEtBQUssR0FBRyxDQUFaO0lBQ0EsS0FBSyxJQUFJbEIsQ0FBQyxHQUFHaUIsWUFBYixFQUEyQmpCLENBQUMsR0FBR0YsUUFBUSxDQUFDZ0IsTUFBeEMsRUFBZ0RkLENBQUMsRUFBakQsRUFBcUQ7TUFDbkQsSUFBSSxDQUFDRixRQUFRLENBQUNFLENBQUQsQ0FBUixDQUFZTyxnQkFBakIsRUFBbUNXLEtBQUs7SUFDekM7SUFDRCxPQUFPQSxLQUFQO0VBQ0Q7O0VBRUQsU0FBU0MsU0FBVDtFQUNFNUIsS0FERjtFQUVFNkIsVUFGRjtFQUdFQyxVQUhGO0VBSUVKLFlBSkY7RUFLRUssVUFMRjtFQU1lO0lBQ2IsT0FBT0QsVUFBVSxHQUFHOUIsS0FBSyxDQUFDdUIsTUFBbkIsSUFBNkJ4QixXQUFXLENBQUNDLEtBQUssQ0FBQzhCLFVBQUQsQ0FBTixDQUEvQztJQUNFQSxVQUFVOztJQUVaLElBQUlBLFVBQVUsS0FBSzlCLEtBQUssQ0FBQ3VCLE1BQXpCLEVBQWlDO01BQy9CLE9BQU9FLGlCQUFpQixDQUFDQyxZQUFELENBQWpCLEtBQW9DLENBQXBDLEdBQXdDSyxVQUFVLElBQUksRUFBdEQsR0FBMkQsSUFBbEU7SUFDRDs7SUFFRCxJQUFJTCxZQUFZLEtBQUtuQixRQUFRLENBQUNnQixNQUE5QixFQUFzQyxPQUFPLElBQVA7O0lBRXRDLE1BQU1TLE9BQU8sR0FBR3pCLFFBQVEsQ0FBQ21CLFlBQUQsQ0FBeEI7O0lBRUEsTUFBTSxFQUFFVixnQkFBRixLQUF1QmdCLE9BQTdCOztJQUVBLElBQUloQixnQkFBSixFQUFzQjtNQUNwQixJQUFJVSxZQUFZLEtBQUtuQixRQUFRLENBQUNnQixNQUFULEdBQWtCLENBQXZDLEVBQTBDO1FBQ3hDLE9BQU8zQyxhQUFhLENBQUNtRCxVQUFELEVBQWE7VUFDL0JFLGFBQWEsRUFBRTtZQUNiLENBQUNqQixnQkFBRCxHQUFvQmhCLEtBQUssQ0FBQ2tDLEtBQU4sQ0FBWUwsVUFBWixDQURQLEVBRGdCLEVBQWIsQ0FBcEI7OztNQUtEOztNQUVELE9BQU9ELFNBQVM7TUFDZDVCLEtBRGM7TUFFZDZCLFVBRmM7TUFHZEMsVUFIYztNQUlkSixZQUFZLEdBQUcsQ0FKRDtNQUtkSyxVQUxjLENBQWhCOztJQU9ELENBaEJELE1BZ0JPO01BQ0wsTUFBTUksY0FBYyxHQUFHSixVQUF2QjtNQUNBLE1BQU1LLG9CQUFvQixnQkFBRzdCLFFBQVEsQ0FBQ21CLFlBQVksR0FBRyxDQUFoQixDQUFYLDhDQUFHLFVBQTRCVixnQkFBekQ7TUFDQSxNQUFNcUIsR0FBRyxHQUFHRCxvQkFBb0I7TUFDNUJwQyxLQUFLLENBQUN1QixNQUFOLEdBQWVFLGlCQUFpQixDQUFDQyxZQUFZLEdBQUcsQ0FBaEIsQ0FESjtNQUU1QkksVUFBVSxHQUFHLENBRmpCOztNQUlBLEtBQUssSUFBSXJCLENBQUMsR0FBR3FCLFVBQWIsRUFBeUJyQixDQUFDLEdBQUc0QixHQUE3QixFQUFrQzVCLENBQUMsRUFBbkMsRUFBdUM7UUFDckMsTUFBTTZCLFFBQVEsR0FBR3RDLEtBQUssQ0FBQ1MsQ0FBRCxDQUF0Qjs7UUFFQSxJQUFJVixXQUFXLENBQUN1QyxRQUFELENBQWYsRUFBMkI7O1FBRTNCUCxVQUFVLEdBQUdDLE9BQU8sQ0FBQ08sS0FBUixDQUFjRCxRQUFkLEVBQXdCSCxjQUF4QixDQUFiOztRQUVBLElBQUksQ0FBQ0osVUFBTCxFQUFpQjs7UUFFakIsSUFBSUssb0JBQUosRUFBMEI7VUFDeEJMLFVBQVUsR0FBR25ELGFBQWEsQ0FBQ21ELFVBQUQsRUFBYTtZQUNyQ0UsYUFBYSxFQUFFO2NBQ2IsQ0FBQ0csb0JBQUQsR0FBd0JwQyxLQUFLLENBQUNrQyxLQUFOLENBQVlMLFVBQVosRUFBd0JwQixDQUF4QixDQURYLEVBRHNCLEVBQWIsQ0FBMUI7OztRQUtEOztRQUVELE1BQU0rQixTQUFTLEdBQUdaLFNBQVM7UUFDekI1QixLQUR5QjtRQUV6QlMsQ0FBQyxHQUFHLENBRnFCO1FBR3pCQSxDQUFDLEdBQUcsQ0FIcUI7UUFJekJpQixZQUFZLEdBQUcsQ0FKVTtRQUt6QkssVUFMeUIsQ0FBM0I7OztRQVFBLElBQUlTLFNBQUosRUFBZSxPQUFPQSxTQUFQO01BQ2hCO0lBQ0Y7O0lBRUQsT0FBTyxJQUFQO0VBQ0Q7O0VBRUQsT0FBTztJQUNMdEMsT0FBTyxFQUFFRixLQURKO0lBRUx1QyxLQUFLLEVBQUUsQ0FBQ3BELElBQUQsRUFBaUI0QyxVQUFqQixLQUEwRDtNQUMvRDFCLEtBQUssQ0FBQyxpQkFBRCxDQUFMOztNQUVBLElBQUksQ0FBQ2pCLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixJQUFJLENBQUNxQixLQUFuQixDQUFMLEVBQWdDLE9BQU8sSUFBUDtNQUNoQyxNQUFNUixLQUFLLEdBQUliLElBQUQsQ0FBaUNjLE1BQWpDLENBQXdDLE1BQU0sSUFBOUMsQ0FBZDs7TUFFQSxJQUFJd0MsTUFBTSxHQUFHYixTQUFTLENBQUM1QixLQUFELEVBQVEsQ0FBUixFQUFXLENBQVgsRUFBYyxDQUFkLEVBQWlCK0IsVUFBakIsQ0FBdEI7TUFDQSxJQUFJLENBQUNVLE1BQUwsRUFBYSxPQUFPQSxNQUFQOztNQUViO01BQ0E7TUFDQTtNQUNBLEtBQUssTUFBTVQsT0FBWCxJQUFzQnpCLFFBQXRCLEVBQWdDO1FBQzlCLE1BQU0sRUFBRVMsZ0JBQUYsS0FBdUJnQixPQUE3QjtRQUNBLElBQUksQ0FBQ2hCLGdCQUFMLEVBQXVCO1FBQ3ZCLElBQUksYUFBQ3lCLE1BQUQsNkRBQUMsUUFBUVIsYUFBVCxrREFBQyxzQkFBd0JqQixnQkFBeEIsQ0FBRCxDQUFKO1FBQ0V5QixNQUFNLEdBQUc3RCxhQUFhLENBQUM2RCxNQUFELEVBQVM7VUFDN0JSLGFBQWEsRUFBRSxFQUFFLENBQUNqQixnQkFBRCxHQUFvQixFQUF0QixFQURjLEVBQVQsQ0FBdEI7O01BR0g7TUFDRCxPQUFPeUIsTUFBUDtJQUNELENBdkJJLEVBQVA7O0FBeUJEOztBQUVELFNBQVN4Qiw0QkFBVDtBQUNFakIsS0FERjtBQUVFSixjQUZGO0FBR0U7RUFDRVcsUUFERjtFQUVFUixXQUFXLEdBQUcsTUFBTSxLQUZ0QixFQUhGOzs7OztBQVVtQjtFQUNqQixNQUFNLEVBQUVNLEtBQUYsS0FBWVQsY0FBbEI7O0VBRUEsTUFBTTBCLFdBQVcsR0FBR2YsUUFBUSxDQUFDbUMsSUFBVCxDQUFjLENBQUM3QixDQUFELEtBQU9BLENBQUMsQ0FBQ0MsZUFBdkIsQ0FBcEI7RUFDQVAsUUFBUSxHQUFHQSxRQUFRLENBQUNOLE1BQVQsQ0FBZ0IsQ0FBQ1ksQ0FBRCxLQUFPLENBQUNBLENBQUMsQ0FBQ0MsZUFBMUIsQ0FBWDtFQUNBLE1BQU1BLGVBQWUsR0FBR1EsV0FBSCxhQUFHQSxXQUFILHVCQUFHQSxXQUFXLENBQUVSLGVBQXJDOztFQUVBLE9BQU87SUFDTFosT0FBTyxFQUFFRixLQURKO0lBRUx1QyxLQUFLLEVBQUUsQ0FBQ3BELElBQUQsRUFBaUJzRCxNQUFqQixLQUFzRDtNQUMzRHBDLEtBQUssQ0FBQyxtQkFBRCxDQUFMOztNQUVBLElBQUksQ0FBQ2pCLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixJQUFJLENBQUNxQixLQUFuQixDQUFMLEVBQWdDLE9BQU8sSUFBUDs7TUFFaEMsTUFBTVIsS0FBSyxHQUFJYixJQUFELENBQWlDYyxNQUFqQyxDQUF3QyxNQUFNLElBQTlDLENBQWQ7O01BRUEsS0FBSyxNQUFNWSxDQUFYLElBQWdCTixRQUFoQixFQUEwQjtRQUN4QixJQUFJRSxDQUFKO1FBQ0EsSUFBSWtDLEtBQUssR0FBRyxLQUFaO1FBQ0EsS0FBS2xDLENBQUMsR0FBRyxDQUFULEVBQVlBLENBQUMsR0FBR1QsS0FBSyxDQUFDdUIsTUFBdEIsRUFBOEJkLENBQUMsRUFBL0IsRUFBbUM7VUFDakMsSUFBSVYsV0FBVyxDQUFDQyxLQUFLLENBQUNTLENBQUQsQ0FBTixDQUFmLEVBQTJCO1lBQ3pCQSxDQUFDO1lBQ0Q7VUFDRDtVQUNELE1BQU04QixLQUFLLEdBQUcxQixDQUFDLENBQUMwQixLQUFGLENBQVF2QyxLQUFLLENBQUNTLENBQUQsQ0FBYixFQUFrQmdDLE1BQWxCLENBQWQ7VUFDQSxJQUFJLENBQUNGLEtBQUwsRUFBWTtVQUNaRSxNQUFNLEdBQUdGLEtBQVQ7VUFDQXZDLEtBQUssQ0FBQzRDLE1BQU4sQ0FBYW5DLENBQWIsRUFBZ0IsQ0FBaEI7VUFDQWtDLEtBQUssR0FBRyxJQUFSO1VBQ0E7UUFDRDtRQUNELElBQUksQ0FBQ0EsS0FBTCxFQUFZO1VBQ1YsT0FBTyxJQUFQO1FBQ0Q7TUFDRjtNQUNELElBQUk3QixlQUFKLEVBQXFCO1FBQ25CLE9BQU9sQyxhQUFhLENBQUM2RCxNQUFELEVBQVM7VUFDM0JSLGFBQWEsRUFBRSxFQUFFLENBQUNuQixlQUFELEdBQW1CZCxLQUFyQixFQURZLEVBQVQsQ0FBcEI7O01BR0QsQ0FKRCxNQUlPO1FBQ0wsSUFBSUEsS0FBSyxDQUFDdUIsTUFBVixFQUFrQjtVQUNoQixPQUFPLElBQVA7UUFDRDtRQUNELE9BQU9rQixNQUFNLElBQUksRUFBakI7TUFDRDtJQUNGLENBdENJLEVBQVA7O0FBd0NEOztBQUVELFNBQVN0Qix3QkFBVDtBQUNFbkIsS0FERjtBQUVFSixjQUZGO0FBR0U7RUFDRVcsUUFERjtFQUVFUixXQUFXLEdBQUcsTUFBTSxLQUZ0QixFQUhGOzs7OztBQVVtQjtFQUNqQixNQUFNLEVBQUVNLEtBQUYsS0FBWVQsY0FBbEI7RUFDQSxPQUFPO0lBQ0xNLE9BQU8sRUFBRUYsS0FESjtJQUVMdUMsS0FBSyxFQUFFLENBQUNwRCxJQUFELEVBQWlCNEMsVUFBakIsS0FBMEQ7TUFDL0QxQixLQUFLLENBQUMsZUFBRCxDQUFMOztNQUVBLElBQUksQ0FBQ2pCLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixJQUFJLENBQUNxQixLQUFuQixDQUFMLEVBQWdDLE9BQU8sSUFBUDs7TUFFaEMsTUFBTVIsS0FBSyxHQUFHYixJQUFJLENBQUNjLE1BQUwsQ0FBWSxDQUFDRyxDQUFELEtBQU8sQ0FBQ0wsV0FBVyxDQUFDSyxDQUFELENBQS9CLENBQWQ7O01BRUEsSUFBSVMsQ0FBQyxHQUFHLENBQVI7TUFDRUosQ0FBQyxHQUFHLENBRE47TUFFQSxPQUFPQSxDQUFDLEdBQUdULEtBQUssQ0FBQ3VCLE1BQVYsSUFBb0JWLENBQUMsR0FBR04sUUFBUSxDQUFDZ0IsTUFBeEMsRUFBZ0Q7UUFDOUNsQixLQUFLLENBQUMsUUFBRCxFQUFXSSxDQUFYLENBQUw7UUFDQSxJQUFJQSxDQUFDLElBQUlULEtBQUssQ0FBQ3VCLE1BQVgsSUFBcUJWLENBQUMsSUFBSU4sUUFBUSxDQUFDZ0IsTUFBdkMsRUFBK0M7VUFDN0NsQixLQUFLLENBQUMscUJBQUQsQ0FBTDtVQUNBLE9BQU8sSUFBUDtRQUNEO1FBQ0QwQixVQUFVLEdBQUd4QixRQUFRLENBQUNNLENBQUQsQ0FBUixDQUFZMEIsS0FBWixDQUFrQnZDLEtBQUssQ0FBQ1MsQ0FBRCxDQUF2QixFQUE0QnNCLFVBQTVCLENBQWI7UUFDQSxJQUFJLENBQUNBLFVBQUwsRUFBaUIsT0FBTyxJQUFQO1FBQ2pCbEIsQ0FBQztRQUNESixDQUFDO01BQ0Y7TUFDRCxPQUFPc0IsVUFBVSxJQUFJLEVBQXJCO0lBQ0QsQ0F2QkksRUFBUDs7QUF5QkQifQ==