open-codebase-index 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +10 -0
- package/dist/cbi.cjs +14792 -0
- package/dist/cbi.cjs.map +1 -0
- package/dist/cbi.js +14786 -0
- package/dist/cbi.js.map +1 -0
- package/dist/cli.cjs +101 -3
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +101 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +97 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +97 -3
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +93 -1
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +93 -1
- package/dist/pi-extension.js.map +1 -1
- package/native/codebase-index-native.darwin-arm64.node +0 -0
- package/native/codebase-index-native.darwin-x64.node +0 -0
- package/native/codebase-index-native.win32-x64-msvc.node +0 -0
- package/package.json +3 -2
package/dist/cbi.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../node_modules/ignore/index.js","../node_modules/eventemitter3/index.js","../src/cbi.ts","../src/adapters/cbi.ts","../src/config/host.ts","../src/config/merger.ts","../src/config/paths.ts","../src/git/index.ts","../src/git/refs.ts","../src/utils/canonical-path.ts","../node_modules/unicode-case-folding/index.js","../src/config/rebase.ts","../src/utils/paths.ts","../src/config/constants.ts","../src/config/defaults.ts","../src/config/env-substitution.ts","../src/config/validators.ts","../src/config/schema.ts","../src/tools/operations.ts","../src/tools/knowledge-base-paths.ts","../src/tools/context-pack.ts","../src/indexer/intent-aware-ranking.ts","../src/tools/utils.ts","../src/utils/auto-index.ts","../src/indexer/index-lock.ts","../src/utils/files.ts","../src/utils/power-source.ts","../src/tools/config-state.ts","../src/indexer/index.ts","../node_modules/eventemitter3/index.mjs","../node_modules/p-timeout/index.js","../node_modules/p-queue/dist/lower-bound.js","../node_modules/p-queue/dist/priority-queue.js","../node_modules/p-queue/dist/index.js","../node_modules/is-network-error/index.js","../node_modules/p-retry/index.js","../src/embeddings/detector.ts","../src/embeddings/provider-types.ts","../src/utils/url-validation.ts","../src/embeddings/providers/custom.ts","../src/embeddings/providers/google.ts","../src/embeddings/providers/ollama.ts","../src/embeddings/providers/openai.ts","../src/embeddings/provider.ts","../src/utils/cost.ts","../src/utils/logger.ts","../src/native/embedding.ts","../src/native/binding.ts","../src/identity-catalog.json","../src/identity-catalog.ts","../src/native/parsing.ts","../src/native/vector-store.ts","../src/native/inverted-index.ts","../src/native/database.ts","../src/git/branch-materialization.ts","../src/git/branch-resolution.ts","../src/tools/changed-files.ts","../src/indexer/git-blame.ts","../src/indexer/search-ranking.ts","../src/tools/symbol-inference.ts","../src/indexer/call-graph-constants.ts","../src/indexer/definition-ranking.ts","../src/indexer/embedding-batches.ts","../src/indexer/failed-state-persistence.ts","../src/indexer/file-batches.ts","../src/tools/operation-runtime.ts","../src/tools/execute-common.ts","../src/adapters/mcp/cli.ts","../src/eval/reports.ts","../src/eval/runner.ts","../src/eval/runner-config.ts","../src/eval/schema.ts","../src/eval/cli.ts","../src/eval/cli-parser.ts","../src/adapters/mcp/server.ts","../src/package-metadata.ts","../src/adapters/mcp/register-prompts.ts","../src/adapters/mcp/register-tools.ts","../src/tools/tool-names.ts","../src/watcher/file-watcher.ts","../src/watcher/native-recursive-watcher.ts","../src/watcher/snapshot.ts","../src/watcher/git-head-watcher.ts","../src/tools/visualize/activity.ts","../src/tools/visualize/transform.ts"],"sourcesContent":["// A simple implementation of make-array\nfunction makeArray (subject) {\n return Array.isArray(subject)\n ? subject\n : [subject]\n}\n\nconst UNDEFINED = undefined\nconst EMPTY = ''\nconst SPACE = ' '\nconst ESCAPE = '\\\\'\nconst REGEX_TEST_BLANK_LINE = /^\\s+$/\nconst REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\\\]|^)\\\\$/\nconst REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\\\!/\nconst REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\\\#/\nconst REGEX_SPLITALL_CRLF = /\\r?\\n/g\n\n// Invalid:\n// - /foo,\n// - ./foo,\n// - ../foo,\n// - .\n// - ..\n// Valid:\n// - .foo\nconst REGEX_TEST_INVALID_PATH = /^\\.{0,2}\\/|^\\.{1,2}$/\n\nconst REGEX_TEST_TRAILING_SLASH = /\\/$/\n\nconst SLASH = '/'\n\n// Do not use ternary expression here, since \"istanbul ignore next\" is buggy\nlet TMP_KEY_IGNORE = 'node-ignore'\n/* istanbul ignore else */\nif (typeof Symbol !== 'undefined') {\n TMP_KEY_IGNORE = Symbol.for('node-ignore')\n}\nconst KEY_IGNORE = TMP_KEY_IGNORE\n\nconst define = (object, key, value) => {\n Object.defineProperty(object, key, {value})\n return value\n}\n\nconst REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g\n\nconst RETURN_FALSE = () => false\n\n// Sanitize the range of a regular expression\n// The cases are complicated, see test cases for details\nconst sanitizeRange = range => range.replace(\n REGEX_REGEXP_RANGE,\n (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)\n ? match\n // Invalid range (out of order) which is ok for gitignore rules but\n // fatal for JavaScript regular expression, so eliminate it.\n : EMPTY\n)\n\n// See fixtures #59\nconst cleanRangeBackSlash = slashes => {\n const {length} = slashes\n return slashes.slice(0, length - length % 2)\n}\n\n// > If the pattern ends with a slash,\n// > it is removed for the purpose of the following description,\n// > but it would only find a match with a directory.\n// > In other words, foo/ will match a directory foo and paths underneath it,\n// > but will not match a regular file or a symbolic link foo\n// > (this is consistent with the way how pathspec works in general in Git).\n// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'\n// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call\n// you could use option `mark: true` with `glob`\n\n// '`foo/`' should not continue with the '`..`'\nconst REPLACERS = [\n\n [\n // Remove BOM\n // TODO:\n // Other similar zero-width characters?\n /^\\uFEFF/,\n () => EMPTY\n ],\n\n // > Trailing spaces are ignored unless they are quoted with backslash (\"\\\")\n [\n // (a\\ ) -> (a )\n // (a ) -> (a)\n // (a ) -> (a)\n // (a \\ ) -> (a )\n /((?:\\\\\\\\)*?)(\\\\?\\s+)$/,\n (_, m1, m2) => m1 + (\n m2.indexOf('\\\\') === 0\n ? SPACE\n : EMPTY\n )\n ],\n\n // Replace (\\ ) with ' '\n // (\\ ) -> ' '\n // (\\\\ ) -> '\\\\ '\n // (\\\\\\ ) -> '\\\\ '\n [\n /(\\\\+?)\\s/g,\n (_, m1) => {\n const {length} = m1\n return m1.slice(0, length - length % 2) + SPACE\n }\n ],\n\n // Escape metacharacters\n // which is written down by users but means special for regular expressions.\n\n // > There are 12 characters with special meanings:\n // > - the backslash \\,\n // > - the caret ^,\n // > - the dollar sign $,\n // > - the period or dot .,\n // > - the vertical bar or pipe symbol |,\n // > - the question mark ?,\n // > - the asterisk or star *,\n // > - the plus sign +,\n // > - the opening parenthesis (,\n // > - the closing parenthesis ),\n // > - and the opening square bracket [,\n // > - the opening curly brace {,\n // > These special characters are often called \"metacharacters\".\n [\n /[\\\\$.|*+(){^]/g,\n match => `\\\\${match}`\n ],\n\n [\n // > a question mark (?) matches a single character\n /(?!\\\\)\\?/g,\n () => '[^/]'\n ],\n\n // leading slash\n [\n\n // > A leading slash matches the beginning of the pathname.\n // > For example, \"/*.c\" matches \"cat-file.c\" but not \"mozilla-sha1/sha1.c\".\n // A leading slash matches the beginning of the pathname\n /^\\//,\n () => '^'\n ],\n\n // replace special metacharacter slash after the leading slash\n [\n /\\//g,\n () => '\\\\/'\n ],\n\n [\n // > A leading \"**\" followed by a slash means match in all directories.\n // > For example, \"**/foo\" matches file or directory \"foo\" anywhere,\n // > the same as pattern \"foo\".\n // > \"**/foo/bar\" matches file or directory \"bar\" anywhere that is directly\n // > under directory \"foo\".\n // Notice that the '*'s have been replaced as '\\\\*'\n /^\\^*\\\\\\*\\\\\\*\\\\\\//,\n\n // '**/foo' <-> 'foo'\n () => '^(?:.*\\\\/)?'\n ],\n\n // starting\n [\n // there will be no leading '/'\n // (which has been replaced by section \"leading slash\")\n // If starts with '**', adding a '^' to the regular expression also works\n /^(?=[^^])/,\n function startingReplacer () {\n // If has a slash `/` at the beginning or middle\n return !/\\/(?!$)/.test(this)\n // > Prior to 2.22.1\n // > If the pattern does not contain a slash /,\n // > Git treats it as a shell glob pattern\n // Actually, if there is only a trailing slash,\n // git also treats it as a shell glob pattern\n\n // After 2.22.1 (compatible but clearer)\n // > If there is a separator at the beginning or middle (or both)\n // > of the pattern, then the pattern is relative to the directory\n // > level of the particular .gitignore file itself.\n // > Otherwise the pattern may also match at any level below\n // > the .gitignore level.\n ? '(?:^|\\\\/)'\n\n // > Otherwise, Git treats the pattern as a shell glob suitable for\n // > consumption by fnmatch(3)\n : '^'\n }\n ],\n\n // two globstars\n [\n // Use lookahead assertions so that we could match more than one `'/**'`\n /\\\\\\/\\\\\\*\\\\\\*(?=\\\\\\/|$)/g,\n\n // Zero, one or several directories\n // should not use '*', or it will be replaced by the next replacer\n\n // Check if it is not the last `'/**'`\n (_, index, str) => index + 6 < str.length\n\n // case: /**/\n // > A slash followed by two consecutive asterisks then a slash matches\n // > zero or more directories.\n // > For example, \"a/**/b\" matches \"a/b\", \"a/x/b\", \"a/x/y/b\" and so on.\n // '/**/'\n ? '(?:\\\\/[^\\\\/]+)*'\n\n // case: /**\n // > A trailing `\"/**\"` matches everything inside.\n\n // #21: everything inside but it should not include the current folder\n : '\\\\/.+'\n ],\n\n // normal intermediate wildcards\n [\n // Never replace escaped '*'\n // ignore rule '\\*' will match the path '*'\n\n // 'abc.*/' -> go\n // 'abc.*' -> skip this rule,\n // coz trailing single wildcard will be handed by [trailing wildcard]\n /(^|[^\\\\]+)(\\\\\\*)+(?=.+)/g,\n\n // '*.js' matches '.js'\n // '*.js' doesn't match 'abc'\n (_, p1, p2) => {\n // 1.\n // > An asterisk \"*\" matches anything except a slash.\n // 2.\n // > Other consecutive asterisks are considered regular asterisks\n // > and will match according to the previous rules.\n const unescaped = p2.replace(/\\\\\\*/g, '[^\\\\/]*')\n return p1 + unescaped\n }\n ],\n\n [\n // unescape, revert step 3 except for back slash\n // For example, if a user escape a '\\\\*',\n // after step 3, the result will be '\\\\\\\\\\\\*'\n /\\\\\\\\\\\\(?=[$.|*+(){^])/g,\n () => ESCAPE\n ],\n\n [\n // '\\\\\\\\' -> '\\\\'\n /\\\\\\\\/g,\n () => ESCAPE\n ],\n\n [\n // > The range notation, e.g. [a-zA-Z],\n // > can be used to match one of the characters in a range.\n\n // `\\` is escaped by step 3\n /(\\\\)?\\[([^\\]/]*?)(\\\\*)($|\\])/g,\n (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE\n // '\\\\[bar]' -> '\\\\\\\\[bar\\\\]'\n ? `\\\\[${range}${cleanRangeBackSlash(endEscape)}${close}`\n : close === ']'\n ? endEscape.length % 2 === 0\n // A normal case, and it is a range notation\n // '[bar]'\n // '[bar\\\\\\\\]'\n ? `[${sanitizeRange(range)}${endEscape}]`\n // Invalid range notaton\n // '[bar\\\\]' -> '[bar\\\\\\\\]'\n : '[]'\n : '[]'\n ],\n\n // ending\n [\n // 'js' will not match 'js.'\n // 'ab' will not match 'abc'\n /(?:[^*])$/,\n\n // WTF!\n // https://git-scm.com/docs/gitignore\n // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)\n // which re-fixes #24, #38\n\n // > If there is a separator at the end of the pattern then the pattern\n // > will only match directories, otherwise the pattern can match both\n // > files and directories.\n\n // 'js*' will not match 'a.js'\n // 'js/' will not match 'a.js'\n // 'js' will match 'a.js' and 'a.js/'\n match => /\\/$/.test(match)\n // foo/ will not match 'foo'\n ? `${match}$`\n // foo matches 'foo' and 'foo/'\n : `${match}(?=$|\\\\/$)`\n ]\n]\n\nconst REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\\\\/)?\\\\\\*$/\nconst MODE_IGNORE = 'regex'\nconst MODE_CHECK_IGNORE = 'checkRegex'\nconst UNDERSCORE = '_'\n\nconst TRAILING_WILD_CARD_REPLACERS = {\n [MODE_IGNORE] (_, p1) {\n const prefix = p1\n // '\\^':\n // '/*' does not match EMPTY\n // '/*' does not match everything\n\n // '\\\\\\/':\n // 'abc/*' does not match 'abc/'\n ? `${p1}[^/]+`\n\n // 'a*' matches 'a'\n // 'a*' matches 'aa'\n : '[^/]*'\n\n return `${prefix}(?=$|\\\\/$)`\n },\n\n [MODE_CHECK_IGNORE] (_, p1) {\n // When doing `git check-ignore`\n const prefix = p1\n // '\\\\\\/':\n // 'abc/*' DOES match 'abc/' !\n ? `${p1}[^/]*`\n\n // 'a*' matches 'a'\n // 'a*' matches 'aa'\n : '[^/]*'\n\n return `${prefix}(?=$|\\\\/$)`\n }\n}\n\n// @param {pattern}\nconst makeRegexPrefix = pattern => REPLACERS.reduce(\n (prev, [matcher, replacer]) =>\n prev.replace(matcher, replacer.bind(pattern)),\n pattern\n)\n\nconst isString = subject => typeof subject === 'string'\n\n// > A blank line matches no files, so it can serve as a separator for readability.\nconst checkPattern = pattern => pattern\n && isString(pattern)\n && !REGEX_TEST_BLANK_LINE.test(pattern)\n && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)\n\n // > A line starting with # serves as a comment.\n && pattern.indexOf('#') !== 0\n\nconst splitPattern = pattern => pattern\n.split(REGEX_SPLITALL_CRLF)\n.filter(Boolean)\n\nclass IgnoreRule {\n constructor (\n pattern,\n mark,\n body,\n ignoreCase,\n negative,\n prefix\n ) {\n this.pattern = pattern\n this.mark = mark\n this.negative = negative\n\n define(this, 'body', body)\n define(this, 'ignoreCase', ignoreCase)\n define(this, 'regexPrefix', prefix)\n }\n\n get regex () {\n const key = UNDERSCORE + MODE_IGNORE\n\n if (this[key]) {\n return this[key]\n }\n\n return this._make(MODE_IGNORE, key)\n }\n\n get checkRegex () {\n const key = UNDERSCORE + MODE_CHECK_IGNORE\n\n if (this[key]) {\n return this[key]\n }\n\n return this._make(MODE_CHECK_IGNORE, key)\n }\n\n _make (mode, key) {\n const str = this.regexPrefix.replace(\n REGEX_REPLACE_TRAILING_WILDCARD,\n\n // It does not need to bind pattern\n TRAILING_WILD_CARD_REPLACERS[mode]\n )\n\n const regex = this.ignoreCase\n ? new RegExp(str, 'i')\n : new RegExp(str)\n\n return define(this, key, regex)\n }\n}\n\nconst createRule = ({\n pattern,\n mark\n}, ignoreCase) => {\n let negative = false\n let body = pattern\n\n // > An optional prefix \"!\" which negates the pattern;\n if (body.indexOf('!') === 0) {\n negative = true\n body = body.substr(1)\n }\n\n body = body\n // > Put a backslash (\"\\\") in front of the first \"!\" for patterns that\n // > begin with a literal \"!\", for example, `\"\\!important!.txt\"`.\n .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')\n // > Put a backslash (\"\\\") in front of the first hash for patterns that\n // > begin with a hash.\n .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#')\n\n const regexPrefix = makeRegexPrefix(body)\n\n return new IgnoreRule(\n pattern,\n mark,\n body,\n ignoreCase,\n negative,\n regexPrefix\n )\n}\n\nclass RuleManager {\n constructor (ignoreCase) {\n this._ignoreCase = ignoreCase\n this._rules = []\n }\n\n _add (pattern) {\n // #32\n if (pattern && pattern[KEY_IGNORE]) {\n this._rules = this._rules.concat(pattern._rules._rules)\n this._added = true\n return\n }\n\n if (isString(pattern)) {\n pattern = {\n pattern\n }\n }\n\n if (checkPattern(pattern.pattern)) {\n const rule = createRule(pattern, this._ignoreCase)\n this._added = true\n this._rules.push(rule)\n }\n }\n\n // @param {Array<string> | string | Ignore} pattern\n add (pattern) {\n this._added = false\n\n makeArray(\n isString(pattern)\n ? splitPattern(pattern)\n : pattern\n ).forEach(this._add, this)\n\n return this._added\n }\n\n // Test one single path without recursively checking parent directories\n //\n // - checkUnignored `boolean` whether should check if the path is unignored,\n // setting `checkUnignored` to `false` could reduce additional\n // path matching.\n // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`\n\n // @returns {TestResult} true if a file is ignored\n test (path, checkUnignored, mode) {\n let ignored = false\n let unignored = false\n let matchedRule\n\n this._rules.forEach(rule => {\n const {negative} = rule\n\n // | ignored : unignored\n // -------- | ---------------------------------------\n // negative | 0:0 | 0:1 | 1:0 | 1:1\n // -------- | ------- | ------- | ------- | --------\n // 0 | TEST | TEST | SKIP | X\n // 1 | TESTIF | SKIP | TEST | X\n\n // - SKIP: always skip\n // - TEST: always test\n // - TESTIF: only test if checkUnignored\n // - X: that never happen\n if (\n unignored === negative && ignored !== unignored\n || negative && !ignored && !unignored && !checkUnignored\n ) {\n return\n }\n\n const matched = rule[mode].test(path)\n\n if (!matched) {\n return\n }\n\n ignored = !negative\n unignored = negative\n\n matchedRule = negative\n ? UNDEFINED\n : rule\n })\n\n const ret = {\n ignored,\n unignored\n }\n\n if (matchedRule) {\n ret.rule = matchedRule\n }\n\n return ret\n }\n}\n\nconst throwError = (message, Ctor) => {\n throw new Ctor(message)\n}\n\nconst checkPath = (path, originalPath, doThrow) => {\n if (!isString(path)) {\n return doThrow(\n `path must be a string, but got \\`${originalPath}\\``,\n TypeError\n )\n }\n\n // We don't know if we should ignore EMPTY, so throw\n if (!path) {\n return doThrow(`path must not be empty`, TypeError)\n }\n\n // Check if it is a relative path\n if (checkPath.isNotRelative(path)) {\n const r = '`path.relative()`d'\n return doThrow(\n `path should be a ${r} string, but got \"${originalPath}\"`,\n RangeError\n )\n }\n\n return true\n}\n\nconst isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path)\n\ncheckPath.isNotRelative = isNotRelative\n\n// On windows, the following function will be replaced\n/* istanbul ignore next */\ncheckPath.convert = p => p\n\n\nclass Ignore {\n constructor ({\n ignorecase = true,\n ignoreCase = ignorecase,\n allowRelativePaths = false\n } = {}) {\n define(this, KEY_IGNORE, true)\n\n this._rules = new RuleManager(ignoreCase)\n this._strictPathCheck = !allowRelativePaths\n this._initCache()\n }\n\n _initCache () {\n // A cache for the result of `.ignores()`\n this._ignoreCache = Object.create(null)\n\n // A cache for the result of `.test()`\n this._testCache = Object.create(null)\n }\n\n add (pattern) {\n if (this._rules.add(pattern)) {\n // Some rules have just added to the ignore,\n // making the behavior changed,\n // so we need to re-initialize the result cache\n this._initCache()\n }\n\n return this\n }\n\n // legacy\n addPattern (pattern) {\n return this.add(pattern)\n }\n\n // @returns {TestResult}\n _test (originalPath, cache, checkUnignored, slices) {\n const path = originalPath\n // Supports nullable path\n && checkPath.convert(originalPath)\n\n checkPath(\n path,\n originalPath,\n this._strictPathCheck\n ? throwError\n : RETURN_FALSE\n )\n\n return this._t(path, cache, checkUnignored, slices)\n }\n\n checkIgnore (path) {\n // If the path doest not end with a slash, `.ignores()` is much equivalent\n // to `git check-ignore`\n if (!REGEX_TEST_TRAILING_SLASH.test(path)) {\n return this.test(path)\n }\n\n const slices = path.split(SLASH).filter(Boolean)\n slices.pop()\n\n if (slices.length) {\n const parent = this._t(\n slices.join(SLASH) + SLASH,\n this._testCache,\n true,\n slices\n )\n\n if (parent.ignored) {\n return parent\n }\n }\n\n return this._rules.test(path, false, MODE_CHECK_IGNORE)\n }\n\n _t (\n // The path to be tested\n path,\n\n // The cache for the result of a certain checking\n cache,\n\n // Whether should check if the path is unignored\n checkUnignored,\n\n // The path slices\n slices\n ) {\n if (path in cache) {\n return cache[path]\n }\n\n if (!slices) {\n // path/to/a.js\n // ['path', 'to', 'a.js']\n slices = path.split(SLASH).filter(Boolean)\n }\n\n slices.pop()\n\n // If the path has no parent directory, just test it\n if (!slices.length) {\n return cache[path] = this._rules.test(path, checkUnignored, MODE_IGNORE)\n }\n\n const parent = this._t(\n slices.join(SLASH) + SLASH,\n cache,\n checkUnignored,\n slices\n )\n\n // If the path contains a parent directory, check the parent first\n return cache[path] = parent.ignored\n // > It is not possible to re-include a file if a parent directory of\n // > that file is excluded.\n ? parent\n : this._rules.test(path, checkUnignored, MODE_IGNORE)\n }\n\n ignores (path) {\n return this._test(path, this._ignoreCache, false).ignored\n }\n\n createFilter () {\n return path => !this.ignores(path)\n }\n\n filter (paths) {\n return makeArray(paths).filter(this.createFilter())\n }\n\n // @returns {TestResult}\n test (path) {\n return this._test(path, this._testCache, true)\n }\n}\n\nconst factory = options => new Ignore(options)\n\nconst isPathValid = path =>\n checkPath(path && checkPath.convert(path), path, RETURN_FALSE)\n\n/* istanbul ignore next */\nconst setupWindows = () => {\n /* eslint no-control-regex: \"off\" */\n const makePosix = str => /^\\\\\\\\\\?\\\\/.test(str)\n || /[\"<>|\\u0000-\\u001F]+/u.test(str)\n ? str\n : str.replace(/\\\\/g, '/')\n\n checkPath.convert = makePosix\n\n // 'C:\\\\foo' <- 'C:\\\\foo' has been converted to 'C:/'\n // 'd:\\\\foo'\n const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\\//i\n checkPath.isNotRelative = path =>\n REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path)\n || isNotRelative(path)\n}\n\n\n// Windows\n// --------------------------------------------------------------\n/* istanbul ignore next */\nif (\n // Detect `process` so that it can run in browsers.\n typeof process !== 'undefined'\n && process.platform === 'win32'\n) {\n setupWindows()\n}\n\n// COMMONJS_EXPORTS ////////////////////////////////////////////////////////////\n\nmodule.exports = factory\n\n// Although it is an anti-pattern,\n// it is still widely misused by a lot of libraries in github\n// Ref: https://github.com/search?q=ignore.default%28%29&type=code\nfactory.default = factory\n\nmodule.exports.isPathValid = isPathValid\n\n// For testing purposes\ndefine(module.exports, Symbol.for('setupWindows'), setupWindows)\n","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","#!/usr/bin/env node\n\nexport { isCbiEntrypoint, runCbiCli } from \"./adapters/cbi.js\";\n\nimport { isCbiEntrypoint, runCbiCli } from \"./adapters/cbi.js\";\n\nfunction handleCbiMainError(error: unknown): never {\n const message = error instanceof Error ? error.message : String(error);\n if (message.startsWith(\"Invalid host mode\")) {\n console.error(message);\n process.exit(1);\n }\n\n console.error(\"Failed to start CBI CLI. Check your command and configuration.\");\n if (message) {\n console.error(message);\n }\n process.exit(1);\n}\n\nif (isCbiEntrypoint(import.meta.url, process.argv[1])) {\n runCbiCli(process.argv, process.cwd()).then((exitCode) => {\n process.exitCode = exitCode;\n }).catch(handleCbiMainError);\n}\n","import { realpathSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { HostMode } from \"../config/host.js\";\n\nimport { parseHostMode } from \"../config/host.js\";\nimport { loadConfigFile } from \"../config/merger.js\";\nimport { parseConfig } from \"../config/schema.js\";\nimport {\n executeCallGraph,\n executeImplementationLookup,\n executeIndexStatus,\n} from \"../tools/execute-common.js\";\nimport { initializeTools } from \"../tools/operation-runtime.js\";\nimport { searchCodebase } from \"../tools/operations.js\";\nimport { formatSearchResults } from \"../tools/utils.js\";\nimport { handleIndexCommand, redactSensitiveText } from \"./mcp/cli.js\";\n\ntype TextSink = (text: string) => void;\ntype Result = { text: string; isError?: boolean };\ntype GraphDirection = \"callers\" | \"callees\";\n\nexport interface CbiDeps {\n runIndex?: typeof handleIndexCommand;\n runStatus?: (projectRoot: string | undefined, host: HostMode) => Promise<Result>;\n runDefinition?: (projectRoot: string | undefined, host: HostMode, query: string) => Promise<Result>;\n runSearch?: (projectRoot: string | undefined, host: HostMode, query: string, limit: number) => Promise<Result>;\n runCallGraph?: (\n projectRoot: string | undefined,\n host: HostMode,\n symbol: string,\n direction: GraphDirection,\n filePath?: string,\n ) => Promise<Result>;\n initializeRuntimeForConfig?: (projectRoot: string, config: ReturnType<typeof parseConfig>, host: HostMode) => void;\n readConfigFile?: (filePath: string) => unknown;\n printStdout?: TextSink;\n printStderr?: TextSink;\n}\n\nexport interface CbiCommandArgs {\n project: string;\n host: HostMode;\n config?: string;\n limit: number;\n filePath?: string;\n positionals: string[];\n}\n\nfunction printUsage(output: TextSink): void {\n output(`Usage: cbi <command> [options]\n\nCommands:\n status Show index status\n index [options] Create or refresh the index\n search <query> [--limit <n>] Full-content semantic search\n definition <symbol> Find authoritative definitions\n graph <callers|callees> <symbol> Inspect direct call-graph edges\n\nGlobal options:\n --project <path> Project root, default: current directory\n --host <mode> opencode, codex, claude, pi, or jcode\n --config <path> Explicit JSON config path\n --help Show this message\n`);\n}\n\nfunction printCommandUsage(output: TextSink, command: string): void {\n const usage: Record<string, string> = {\n status: \"Usage: cbi status [--project <path>] [--host <mode>] [--config <path>]\",\n index: \"Usage: cbi index [--project <path>] [--host <mode>] [--config <path>] [--force] [--estimate-only] [--dry-run] [--verbose]\",\n search: \"Usage: cbi search <query> [--limit <n>] [--project <path>] [--host <mode>] [--config <path>]\",\n definition: \"Usage: cbi definition <symbol> [--project <path>] [--host <mode>] [--config <path>]\",\n graph: \"Usage: cbi graph <callers|callees> <symbol> [--file <path>] [--project <path>] [--host <mode>] [--config <path>]\",\n };\n output(usage[command] ?? \"Usage: cbi <command> [options]\");\n}\n\nfunction optionValue(args: string[], index: number, name: string): { value: string; consumed: number } {\n const arg = args[index];\n const equalsPrefix = `--${name}=`;\n if (arg.startsWith(equalsPrefix)) return { value: arg.slice(equalsPrefix.length), consumed: 0 };\n const value = args[index + 1];\n if (!value || value.startsWith(\"--\")) throw new Error(`--${name} requires a value.`);\n return { value, consumed: 1 };\n}\n\nexport function parseCbiCommandArgs(command: string, args: string[], cwd: string): CbiCommandArgs {\n let project = cwd;\n let host: HostMode = \"opencode\";\n let config: string | undefined;\n let limit = 5;\n let filePath: string | undefined;\n const positionals: string[] = [];\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg === \"--help\" || arg === \"-h\") throw new Error(\"help-requested\");\n\n if (arg === \"--project\" || arg.startsWith(\"--project=\")) {\n const parsed = optionValue(args, index, \"project\");\n project = path.resolve(cwd, parsed.value);\n index += parsed.consumed;\n continue;\n }\n if (arg === \"--host\" || arg.startsWith(\"--host=\")) {\n const parsed = optionValue(args, index, \"host\");\n host = parseHostMode(parsed.value);\n index += parsed.consumed;\n continue;\n }\n if (arg === \"--config\" || arg.startsWith(\"--config=\")) {\n const parsed = optionValue(args, index, \"config\");\n config = path.resolve(cwd, parsed.value);\n index += parsed.consumed;\n continue;\n }\n if (command === \"search\" && (arg === \"--limit\" || arg.startsWith(\"--limit=\"))) {\n const parsed = optionValue(args, index, \"limit\");\n limit = Number(parsed.value);\n if (!Number.isInteger(limit) || limit < 1) throw new Error(\"--limit must be a positive integer.\");\n index += parsed.consumed;\n continue;\n }\n if (command === \"graph\" && (arg === \"--file\" || arg.startsWith(\"--file=\"))) {\n const parsed = optionValue(args, index, \"file\");\n filePath = path.resolve(cwd, parsed.value);\n index += parsed.consumed;\n continue;\n }\n if (arg.startsWith(\"--\")) throw new Error(`Unknown option: ${arg}`);\n positionals.push(arg);\n }\n\n return { project, host, config, limit, filePath, positionals };\n}\n\nasync function initializeFromConfig(args: CbiCommandArgs, deps: CbiDeps): Promise<void> {\n if (!args.config) return;\n const rawConfig = (deps.readConfigFile ?? loadConfigFile)(args.config);\n if (rawConfig === null) throw new Error(`Config file not found: ${args.config}`);\n (deps.initializeRuntimeForConfig ?? initializeTools)(args.project, parseConfig(rawConfig), args.host);\n}\n\nconst defaultSearch = async (projectRoot: string | undefined, host: HostMode, query: string, limit: number): Promise<Result> => {\n const results = await searchCodebase(projectRoot, host, query, { limit });\n return results.length === 0\n ? { text: \"No matching code found. Try a different query or run `cbi index` first.\" }\n : { text: `Found ${results.length} results for \"${query}\":\\n\\n${formatSearchResults(results, \"score\")}` };\n};\n\nfunction requirePositionals(args: CbiCommandArgs, command: string, count: number): string[] {\n if (args.positionals.length !== count) {\n throw new Error(`${command} requires ${count === 1 ? \"exactly one argument\" : \"a direction and a symbol\"}.`);\n }\n return args.positionals;\n}\n\nexport async function runCbiCli(argv: string[], cwd: string, deps: CbiDeps = {}): Promise<number> {\n const stdout = deps.printStdout ?? ((text) => console.log(text));\n const stderr = deps.printStderr ?? ((text) => console.error(redactSensitiveText(text)));\n const command = argv[2];\n\n if (!command || command === \"help\" || command === \"--help\" || command === \"-h\") {\n printUsage(stdout);\n return 0;\n }\n\n if (![\"status\", \"index\", \"search\", \"definition\", \"graph\"].includes(command)) {\n stderr(`Unknown command: ${command}`);\n printUsage(stderr);\n return 1;\n }\n\n try {\n if (command === \"index\") {\n return await (deps.runIndex ?? handleIndexCommand)(argv.slice(3), cwd, {\n printStdout: stdout,\n printStderr: stderr,\n });\n }\n\n const args = parseCbiCommandArgs(command, argv.slice(3), cwd);\n await initializeFromConfig(args, deps);\n\n if (command === \"status\") {\n requirePositionals(args, command, 0);\n const result = await (deps.runStatus ?? executeIndexStatus)(args.project, args.host);\n if (result.isError) { stderr(result.text); return 1; }\n stdout(result.text);\n return 0;\n }\n if (command === \"search\") {\n const [query] = requirePositionals(args, command, 1);\n const result = await (deps.runSearch ?? defaultSearch)(args.project, args.host, query, args.limit);\n if (result.isError) { stderr(result.text); return 1; }\n stdout(result.text);\n return 0;\n }\n if (command === \"definition\") {\n const [query] = requirePositionals(args, command, 1);\n const result = await (deps.runDefinition ?? ((root, hostMode, symbol) =>\n executeImplementationLookup(root, hostMode, { query: symbol, limit: 5 })))(args.project, args.host, query);\n if (result.isError) { stderr(result.text); return 1; }\n stdout(result.text);\n return 0;\n }\n\n const [direction, symbol] = requirePositionals(args, command, 2);\n if (direction !== \"callers\" && direction !== \"callees\") throw new Error(\"graph direction must be callers or callees.\");\n const result = await (deps.runCallGraph ?? ((root, hostMode, name, graphDirection, file) =>\n executeCallGraph(root, hostMode, { name, direction: graphDirection, filePath: file })))(args.project, args.host, symbol, direction, args.filePath);\n if (result.isError) { stderr(result.text); return 1; }\n stdout(result.text);\n return 0;\n } catch (error) {\n if (error instanceof Error && error.message === \"help-requested\") {\n printCommandUsage(stderr, command);\n return 0;\n }\n stderr(error instanceof Error ? error.message : String(error));\n printCommandUsage(stderr, command);\n return 1;\n }\n}\n\nexport function isCbiEntrypoint(moduleUrl: string, argvPath: string | undefined): boolean {\n return argvPath !== undefined && realpathSync(fileURLToPath(moduleUrl)) === realpathSync(argvPath);\n}\n","export type HostMode = \"opencode\" | \"codex\" | \"claude\" | \"pi\" | \"jcode\";\n\nexport const HOST_MODES: ReadonlyArray<HostMode> = [\"opencode\", \"codex\", \"claude\", \"pi\", \"jcode\"];\n\nexport function isSupportedHostMode(value: string): value is HostMode {\n return (HOST_MODES as ReadonlyArray<string>).includes(value);\n}\n\nexport function parseHostMode(value: string | undefined): HostMode {\n const normalized = (value ?? \"\").toLowerCase();\n\n if (isSupportedHostMode(normalized)) {\n return normalized;\n }\n\n throw new Error(`Invalid host mode: ${value ?? \"(none)\"}. Allowed values: ${HOST_MODES.join(\", \")}.`);\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport * as path from \"path\";\n\nimport { resolveGlobalConfigPath, resolveProjectConfigPath } from \"./paths.js\";\nimport type { HostMode } from \"./host.js\";\nimport { resolveInheritedKnowledgeBaseEntries } from \"./rebase.js\";\n\nconst PROJECT_OVERRIDE_KEYS = [\n \"embeddingProvider\",\n \"customProvider\",\n \"embeddingModel\",\n \"reranker\",\n \"include\",\n \"exclude\",\n \"indexing\",\n \"search\",\n \"debug\",\n \"effectivenessMetrics\",\n \"scope\",\n] as const;\n\nconst MERGE_ARRAY_KEYS = [\"knowledgeBases\", \"additionalInclude\"] as const;\n\ntype ProjectOverrideKey = (typeof PROJECT_OVERRIDE_KEYS)[number];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction applyProjectOverride(\n merged: Record<string, unknown>,\n normalizedProjectConfig: Record<string, unknown>,\n globalConfig: Record<string, unknown>,\n key: ProjectOverrideKey,\n): void {\n if (key in normalizedProjectConfig) {\n merged[key] = normalizedProjectConfig[key];\n return;\n }\n\n if (key in globalConfig) {\n merged[key] = globalConfig[key];\n }\n}\n\nfunction mergeUniqueStringArray(values: unknown[]): string[] {\n return [...new Set(values.map((value) => String(value).trim()))];\n}\n\nfunction normalizeKnowledgeBasePath(value: unknown): string {\n let normalized = path.normalize(String(value).trim());\n const root = path.parse(normalized).root;\n\n while (normalized.length > root.length && /[\\\\/]$/.test(normalized)) {\n normalized = normalized.slice(0, -1);\n }\n\n return normalized;\n}\n\nfunction mergeKnowledgeBasePaths(values: unknown[]): string[] {\n return [...new Set(values.map((value) => normalizeKnowledgeBasePath(value)).filter((value) => value.length > 0))];\n}\n\nfunction validateConfigLayerShape(rawConfig: unknown, filePath: string): Record<string, unknown> {\n if (!isRecord(rawConfig)) {\n throw new Error(`Config file ${filePath} must contain a JSON object at the root.`);\n }\n\n if (rawConfig.knowledgeBases !== undefined && !isStringArray(rawConfig.knowledgeBases)) {\n throw new Error(`Config file ${filePath} field 'knowledgeBases' must be an array of strings.`);\n }\n if (rawConfig.additionalInclude !== undefined && !isStringArray(rawConfig.additionalInclude)) {\n throw new Error(`Config file ${filePath} field 'additionalInclude' must be an array of strings.`);\n }\n if (rawConfig.include !== undefined && !isStringArray(rawConfig.include)) {\n throw new Error(`Config file ${filePath} field 'include' must be an array of strings.`);\n }\n if (rawConfig.exclude !== undefined && !isStringArray(rawConfig.exclude)) {\n throw new Error(`Config file ${filePath} field 'exclude' must be an array of strings.`);\n }\n\n for (const section of [\"customProvider\", \"indexing\", \"search\", \"debug\", \"effectivenessMetrics\", \"reranker\"] as const) {\n const value = rawConfig[section];\n if (value !== undefined && !isRecord(value)) {\n throw new Error(`Config file ${filePath} field '${section}' must be an object.`);\n }\n }\n\n return rawConfig;\n}\n\nfunction loadJsonFile(filePath: string): unknown {\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return validateConfigLayerShape(JSON.parse(content), filePath);\n } catch (error: unknown) {\n if (error instanceof Error && error.message.startsWith(\"Config file \")) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load config file ${filePath}: ${message}`);\n }\n\n}\n\nexport function loadConfigFile(filePath: string): unknown {\n return loadJsonFile(filePath);\n}\n\nexport function loadProjectConfigLayer(projectRoot: string, host: HostMode): Record<string, unknown> {\n const projectConfigPath = resolveProjectConfigPath(projectRoot, host);\n const projectConfig = loadJsonFile(projectConfigPath) as Record<string, unknown> | null;\n\n if (!projectConfig) {\n return {};\n }\n\n const normalizedConfig: Record<string, unknown> = { ...projectConfig };\n const projectConfigBaseDir = path.dirname(path.dirname(projectConfigPath));\n\n if (Array.isArray(normalizedConfig.knowledgeBases)) {\n normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(\n normalizedConfig.knowledgeBases,\n projectConfigBaseDir,\n projectRoot,\n );\n }\n\n return normalizedConfig;\n}\n\n/**\n * Loads and merges global and project configs.\n * \n * Merge rules:\n * - Global config is the base\n * - For most fields: project overrides global if set, otherwise load global (fallback)\n * - For knowledgeBases: merge arrays (union, deduplicated)\n * - For additionalInclude: merge arrays (union, deduplicated)\n * - For include/exclude: project overrides global if set, otherwise load global\n */\nexport function loadMergedConfig(projectRoot: string, host: HostMode): unknown {\n const globalConfigPath = resolveGlobalConfigPath(host);\n const projectConfigPath = resolveProjectConfigPath(projectRoot, host);\n let globalConfig: Record<string, unknown> | null = null;\n let globalConfigError: Error | null = null;\n\n try {\n globalConfig = loadJsonFile(globalConfigPath) as Record<string, unknown> | null;\n } catch (error: unknown) {\n globalConfigError = error instanceof Error ? error : new Error(String(error));\n }\n\n const projectConfig = loadJsonFile(projectConfigPath) as Record<string, unknown> | null;\n const normalizedProjectConfig = loadProjectConfigLayer(projectRoot, host);\n\n if (globalConfigError) {\n if (!projectConfig) {\n throw globalConfigError;\n }\n globalConfig = null;\n }\n\n if (!globalConfig && !projectConfig) {\n return {};\n }\n\n if (!projectConfig && globalConfig) {\n return globalConfig;\n }\n\n if (!globalConfig && projectConfig) {\n return normalizedProjectConfig;\n }\n\n if (!globalConfig || !projectConfig) {\n return globalConfig ?? normalizedProjectConfig;\n }\n\n\n const merged: Record<string, unknown> = { ...globalConfig };\n\n for (const key of PROJECT_OVERRIDE_KEYS) {\n applyProjectOverride(merged, normalizedProjectConfig, globalConfig, key);\n }\n\n // For other config sections: project overrides if set, otherwise use global\n if (projectConfig) {\n for (const key of Object.keys(projectConfig)) {\n if (\n PROJECT_OVERRIDE_KEYS.includes(key as ProjectOverrideKey) ||\n MERGE_ARRAY_KEYS.includes(key as (typeof MERGE_ARRAY_KEYS)[number])\n ) {\n continue; // Already handled above\n }\n merged[key] = normalizedProjectConfig[key];\n }\n }\n\n // For knowledgeBases: merge arrays (union, deduplicated)\n const globalKbs = globalConfig && Array.isArray(globalConfig.knowledgeBases) ? globalConfig.knowledgeBases : [];\n const projectKbs = projectConfig\n ? (Array.isArray(normalizedProjectConfig.knowledgeBases) ? normalizedProjectConfig.knowledgeBases as string[] : [])\n : [];\n const allKbs = [...globalKbs, ...projectKbs];\n merged.knowledgeBases = mergeKnowledgeBasePaths(allKbs);\n\n // For additionalInclude: merge arrays (union, deduplicated)\n const globalAdditional = globalConfig && Array.isArray(globalConfig.additionalInclude) ? globalConfig.additionalInclude : [];\n const projectAdditional = projectConfig && Array.isArray(projectConfig.additionalInclude) ? projectConfig.additionalInclude : [];\n const allAdditional = [...globalAdditional, ...projectAdditional];\n merged.additionalInclude = mergeUniqueStringArray(allAdditional);\n\n return merged;\n}\n","import { existsSync } from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport type { HostMode } from \"./host.js\";\nimport { resolveWorktreeMainRepoRoot } from \"../git/index.js\";\nimport { canonicalizePathForComparison } from \"../utils/canonical-path.js\";\n\nconst OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path.join(\".opencode\", \"codebase-index.json\");\nconst OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path.join(\".opencode\", \"index\");\nconst CODEBASE_INDEX_DIR = \".codebase-index\";\nconst CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path.join(CODEBASE_INDEX_DIR, \"config.json\");\nconst CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path.join(CODEBASE_INDEX_DIR, \"index\");\nconst CLAUDE_DIR = \".claude\";\nconst CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path.join(CLAUDE_DIR, \"codebase-index.json\");\nconst CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path.join(CLAUDE_DIR, \"index\");\n\nfunction getProjectConfigRelativePath(host: HostMode): string {\n switch (host) {\n case \"opencode\":\n return OPENCODE_PROJECT_CONFIG_RELATIVE_PATH;\n case \"claude\":\n return CLAUDE_PROJECT_CONFIG_RELATIVE_PATH;\n default:\n // Codex, Pi, and Jcode share host-neutral project storage.\n return CODEBASE_PROJECT_CONFIG_RELATIVE_PATH;\n }\n}\n\nfunction getProjectIndexRelativePath(host: HostMode): string {\n switch (host) {\n case \"opencode\":\n return OPENCODE_PROJECT_INDEX_RELATIVE_PATH;\n case \"claude\":\n return CLAUDE_PROJECT_INDEX_RELATIVE_PATH;\n default:\n // Codex, Pi, and Jcode share host-neutral project storage.\n return CODEBASE_PROJECT_INDEX_RELATIVE_PATH;\n }\n}\n\nfunction resolveWorktreeFallbackPath(projectRoot: string, relativePath: string): string | null {\n const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);\n if (!mainRepoRoot) {\n return null;\n }\n\n const fallbackPath = path.join(mainRepoRoot, relativePath);\n return existsSync(fallbackPath) ? fallbackPath : null;\n}\n\nexport function getHostProjectConfigRelativePath(host: HostMode): string {\n return getProjectConfigRelativePath(host);\n}\n\nexport function getHostProjectIndexRelativePath(host: HostMode): string {\n return getProjectIndexRelativePath(host);\n}\n\nexport function getProjectConfigCandidatePaths(\n projectRoot: string,\n host: HostMode,\n): string[] {\n const candidates = [path.join(projectRoot, getProjectConfigRelativePath(host))];\n if (host !== \"opencode\") {\n candidates.push(path.join(projectRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));\n }\n\n const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);\n if (mainRepoRoot) {\n candidates.push(path.join(mainRepoRoot, getProjectConfigRelativePath(host)));\n if (host !== \"opencode\") {\n candidates.push(path.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));\n }\n }\n\n return [...new Set(candidates)];\n}\n\nexport function isProjectIndexPathOwnedByProject(\n projectRoot: string,\n indexPath: string,\n host: HostMode,\n): boolean {\n const projectRoots = [projectRoot];\n const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);\n if (mainRepoRoot) {\n projectRoots.push(mainRepoRoot);\n }\n\n const ownedIndexPaths = projectRoots.flatMap((root) => {\n const indexPaths = [path.join(root, getProjectIndexRelativePath(host))];\n if (host !== \"opencode\") {\n indexPaths.push(path.join(root, OPENCODE_PROJECT_INDEX_RELATIVE_PATH));\n }\n return indexPaths;\n });\n\n const canonicalIndexPath = canonicalizePathForComparison(indexPath);\n return ownedIndexPaths.some(\n (ownedPath) => canonicalizePathForComparison(ownedPath) === canonicalIndexPath,\n );\n}\n\nfunction hasHostProjectConfig(projectRoot: string, host: HostMode): boolean {\n return existsSync(path.join(projectRoot, getProjectConfigRelativePath(host)));\n}\n\nfunction hasHostGlobalConfig(host: HostMode): boolean {\n return existsSync(getGlobalConfigPath(host));\n}\n\nexport function getGlobalIndexPath(host: HostMode): string {\n switch (host) {\n case \"opencode\":\n return path.join(os.homedir(), \".opencode\", \"global-index\");\n case \"claude\":\n return path.join(os.homedir(), \".claude\", \"global-index\");\n default:\n // Codex, Pi, and Jcode share host-neutral global storage.\n return path.join(os.homedir(), \".codebase-index\", \"global-index\");\n }\n}\n\nexport function getGlobalConfigPath(host: HostMode): string {\n switch (host) {\n case \"opencode\":\n return path.join(os.homedir(), \".config\", \"opencode\", \"codebase-index.json\");\n case \"claude\":\n return path.join(os.homedir(), \".claude\", \"codebase-index.json\");\n default:\n // Codex, Pi, and Jcode share host-neutral global storage.\n return path.join(os.homedir(), \".config\", \"codebase-index\", \"config.json\");\n }\n}\n\nexport function resolveGlobalConfigPath(host: HostMode): string {\n const hostConfigPath = getGlobalConfigPath(host);\n if (existsSync(hostConfigPath)) {\n return hostConfigPath;\n }\n\n if (host !== \"opencode\") {\n const legacyConfigPath = getGlobalConfigPath(\"opencode\");\n if (existsSync(legacyConfigPath)) {\n return legacyConfigPath;\n }\n }\n\n return hostConfigPath;\n}\n\nexport function resolveGlobalIndexPath(host: HostMode): string {\n const hostIndexPath = getGlobalIndexPath(host);\n if (existsSync(hostIndexPath)) {\n return hostIndexPath;\n }\n\n if (host !== \"opencode\") {\n if (hasHostGlobalConfig(host)) {\n return hostIndexPath;\n }\n\n const legacyIndexPath = getGlobalIndexPath(\"opencode\");\n if (existsSync(legacyIndexPath)) {\n return legacyIndexPath;\n }\n }\n\n return hostIndexPath;\n}\n\nexport function resolveProjectConfigPath(projectRoot: string, host: HostMode): string {\n const candidates = getProjectConfigCandidatePaths(projectRoot, host);\n return candidates.find((candidate) => existsSync(candidate))\n ?? path.join(projectRoot, getProjectConfigRelativePath(host));\n}\n\nexport function resolveWritableProjectConfigPath(projectRoot: string, host: HostMode): string {\n return path.join(projectRoot, getProjectConfigRelativePath(host));\n}\n\nexport function resolveProjectIndexPath(\n projectRoot: string,\n scope: \"project\" | \"global\",\n host: HostMode,\n): string {\n if (scope === \"global\") {\n return resolveGlobalIndexPath(host);\n }\n\n const localIndexPath = path.join(projectRoot, getProjectIndexRelativePath(host));\n const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);\n if (mainRepoRoot) {\n if (hasHostProjectConfig(projectRoot, host)) {\n return localIndexPath;\n }\n\n if (host !== \"opencode\") {\n const localLegacyConfigPath = path.join(projectRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);\n if (existsSync(localLegacyConfigPath)) {\n return path.join(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);\n }\n\n const mainHostConfigPath = path.join(mainRepoRoot, getProjectConfigRelativePath(host));\n const mainHostIndexPath = path.join(mainRepoRoot, getProjectIndexRelativePath(host));\n const mainLegacyConfigPath = path.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);\n const mainLegacyIndexPath = path.join(mainRepoRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);\n if (\n !existsSync(mainHostConfigPath)\n && !existsSync(mainHostIndexPath)\n && (existsSync(mainLegacyConfigPath) || existsSync(mainLegacyIndexPath))\n ) {\n return mainLegacyIndexPath;\n }\n }\n\n // Project indexes use root-relative paths and are serialized by the shared\n // index lease, so inherited worktrees can safely reuse the main checkout.\n // A stale worktree-local index is ignored unless a local config opts out.\n return path.join(mainRepoRoot, getProjectIndexRelativePath(host));\n }\n\n if (existsSync(localIndexPath)) {\n return localIndexPath;\n }\n\n if (host !== \"opencode\") {\n const legacyIndexPath = path.join(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);\n if (existsSync(legacyIndexPath) && !hasHostProjectConfig(projectRoot, host)) {\n return legacyIndexPath;\n }\n }\n\n if (hasHostProjectConfig(projectRoot, host)) {\n return localIndexPath;\n }\n\n const hostFallback = resolveWorktreeFallbackPath(projectRoot, getProjectIndexRelativePath(host));\n if (hostFallback) {\n return hostFallback;\n }\n\n if (host !== \"opencode\") {\n const legacyFallback = resolveWorktreeFallbackPath(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);\n if (legacyFallback) {\n return legacyFallback;\n }\n }\n\n return localIndexPath;\n}\n","import { existsSync, readFileSync, statSync } from \"fs\";\nimport * as path from \"path\";\nimport { collectBranchRefs, readPackedRefs, resolveCommonGitDir, tryResolveRefCommit } from \"./refs.js\";\n\nexport function resolveWorktreeMainRepoRoot(repoRoot: string): string | null {\n const gitDir = resolveGitDir(repoRoot);\n if (!gitDir) {\n return null;\n }\n\n const commonGitDir = resolveCommonGitDir(gitDir);\n if (commonGitDir === gitDir || path.basename(commonGitDir) !== \".git\") {\n return null;\n }\n\n const mainRepoRoot = path.dirname(commonGitDir);\n if (!existsSync(mainRepoRoot)) {\n return null;\n }\n\n return path.resolve(mainRepoRoot) === path.resolve(repoRoot) ? null : mainRepoRoot;\n}\n\n/**\n * Resolves the actual git directory path.\n * \n * In a normal repo, `.git` is a directory containing HEAD, refs, etc.\n * In a worktree, `.git` is a file containing `gitdir: /path/to/actual/git/dir`.\n * \n * @returns The resolved git directory path, or null if not a git repo\n */\nexport function resolveGitDir(repoRoot: string): string | null {\n const gitPath = path.join(repoRoot, \".git\");\n \n if (!existsSync(gitPath)) {\n return null;\n }\n \n try {\n const stat = statSync(gitPath);\n \n if (stat.isDirectory()) {\n return gitPath;\n }\n \n if (stat.isFile()) {\n const content = readFileSync(gitPath, \"utf-8\").trim();\n const match = content.match(/^gitdir:\\s*(.+)$/);\n if (match) {\n const gitdir = match[1];\n // Handle relative paths\n const resolvedPath = path.isAbsolute(gitdir)\n ? gitdir\n : path.resolve(repoRoot, gitdir);\n \n if (existsSync(resolvedPath)) {\n return resolvedPath;\n }\n }\n }\n } catch {\n // Ignore errors (permission issues, etc.)\n }\n \n return null;\n}\n\nexport function isGitRepo(dir: string): boolean {\n return resolveGitDir(dir) !== null;\n}\n\nexport function getCurrentBranch(repoRoot: string): string | null {\n const gitDir = resolveGitDir(repoRoot);\n if (!gitDir) {\n return null;\n }\n \n const headPath = path.join(gitDir, \"HEAD\");\n \n if (!existsSync(headPath)) {\n return null;\n }\n\n try {\n const headContent = readFileSync(headPath, \"utf-8\").trim();\n \n const match = headContent.match(/^ref: refs\\/heads\\/(.+)$/);\n if (match) {\n return match[1];\n }\n\n if (/^[0-9a-f]{40}$/i.test(headContent)) {\n return headContent.slice(0, 7);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nexport function getCurrentCommit(repoRoot: string): string | null {\n const gitDir = resolveGitDir(repoRoot);\n if (!gitDir) {\n return null;\n }\n const refStoreDir = resolveCommonGitDir(gitDir);\n\n const headPath = path.join(gitDir, \"HEAD\");\n if (!existsSync(headPath)) {\n return null;\n }\n\n try {\n const headContent = readFileSync(headPath, \"utf-8\").trim();\n\n if (/^[0-9a-f]{40}$/i.test(headContent)) {\n return headContent;\n }\n\n const refMatch = headContent.match(/^ref:\\s*(.+)$/);\n if (!refMatch) {\n return null;\n }\n\n return tryResolveRefCommit(refStoreDir, refMatch[1]);\n } catch {\n return null;\n }\n}\n\nexport function getBaseBranch(repoRoot: string): string {\n const gitDir = resolveGitDir(repoRoot);\n const refStoreDir = gitDir ? resolveCommonGitDir(gitDir) : null;\n const candidates = [\"main\", \"master\", \"develop\", \"trunk\"];\n \n if (refStoreDir) {\n for (const candidate of candidates) {\n const refPath = path.join(refStoreDir, \"refs\", \"heads\", candidate);\n if (existsSync(refPath)) {\n return candidate;\n }\n\n const packedRefs = readPackedRefs(refStoreDir);\n if (packedRefs.some((line) => line.endsWith(` refs/heads/${candidate}`))) {\n return candidate;\n }\n }\n }\n\n return getCurrentBranch(repoRoot) ?? \"main\";\n}\n\nexport function getAllBranches(repoRoot: string): string[] {\n const branchSet = new Set<string>();\n const gitDir = resolveGitDir(repoRoot);\n const refStoreDir = gitDir ? resolveCommonGitDir(gitDir) : null;\n \n if (!refStoreDir) {\n return [];\n }\n \n const refsPath = path.join(refStoreDir, \"refs\", \"heads\");\n \n if (!existsSync(refsPath)) {\n return [];\n }\n\n const looseBranches: string[] = [];\n collectBranchRefs(looseBranches, refsPath);\n for (const branch of looseBranches) {\n branchSet.add(branch);\n }\n\n const packedRefs = readPackedRefs(refStoreDir);\n for (const line of packedRefs) {\n const splitIndex = line.indexOf(\" \");\n if (splitIndex <= 0) {\n continue;\n }\n\n const ref = line.slice(splitIndex + 1).trim();\n const prefix = \"refs/heads/\";\n if (ref.startsWith(prefix)) {\n branchSet.add(ref.slice(prefix.length));\n }\n }\n\n return Array.from(branchSet).sort();\n}\n\nexport function getBranchOrDefault(repoRoot: string): string {\n if (!isGitRepo(repoRoot)) {\n return \"default\";\n }\n \n return getCurrentBranch(repoRoot) ?? \"default\";\n}\n\nexport function getHeadPath(repoRoot: string): string {\n const gitDir = resolveGitDir(repoRoot);\n if (gitDir) {\n return path.join(gitDir, \"HEAD\");\n }\n return path.join(repoRoot, \".git\", \"HEAD\");\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from \"fs\";\nimport * as path from \"path\";\n\nexport function readPackedRefs(gitDir: string): string[] {\n const packedRefsPath = path.join(gitDir, \"packed-refs\");\n if (!existsSync(packedRefsPath)) {\n return [];\n }\n\n try {\n return readFileSync(packedRefsPath, \"utf-8\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\") && !line.startsWith(\"^\"));\n } catch {\n return [];\n }\n}\n\nexport function resolveCommonGitDir(gitDir: string): string {\n const commonDirPath = path.join(gitDir, \"commondir\");\n if (!existsSync(commonDirPath)) {\n return gitDir;\n }\n\n try {\n const raw = readFileSync(commonDirPath, \"utf-8\").trim();\n if (!raw) {\n return gitDir;\n }\n\n const resolved = path.isAbsolute(raw) ? raw : path.resolve(gitDir, raw);\n if (existsSync(resolved)) {\n return resolved;\n }\n } catch {\n return gitDir;\n }\n\n return gitDir;\n}\n\nexport function tryResolveRefCommit(gitDir: string, refPath: string): string | null {\n const looseRefPath = path.join(gitDir, refPath);\n if (existsSync(looseRefPath)) {\n try {\n const value = readFileSync(looseRefPath, \"utf-8\").trim();\n if (/^[0-9a-f]{40}$/i.test(value)) {\n return value;\n }\n } catch {\n return null;\n }\n }\n\n const packedRefs = readPackedRefs(gitDir);\n for (const line of packedRefs) {\n const splitIndex = line.indexOf(\" \");\n if (splitIndex <= 0) {\n continue;\n }\n\n const commit = line.slice(0, splitIndex).trim();\n const packedRef = line.slice(splitIndex + 1).trim();\n if (packedRef === refPath && /^[0-9a-f]{40}$/i.test(commit)) {\n return commit;\n }\n }\n\n return null;\n}\n\nexport function collectBranchRefs(branches: string[], baseDir: string, prefix = \"\"): void {\n if (!existsSync(baseDir)) {\n return;\n }\n\n try {\n const entries = readdirSync(baseDir);\n for (const entry of entries) {\n const nextPath = path.join(baseDir, entry);\n const nextPrefix = prefix ? `${prefix}/${entry}` : entry;\n const stat = statSync(nextPath);\n if (stat.isDirectory()) {\n collectBranchRefs(branches, nextPath, nextPrefix);\n } else if (stat.isFile()) {\n branches.push(nextPrefix);\n }\n }\n } catch {\n return;\n }\n}\n","import * as crypto from \"crypto\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\nimport { caseFold } from \"unicode-case-folding\";\n\nexport interface CanonicalPathComparisonOptions {\n isCaseInsensitive?: (existingAncestor: string) => boolean | undefined;\n}\n\nfunction alternateAsciiCase(value: string): string | null {\n const index = value.search(/[A-Za-z]/);\n if (index === -1) return null;\n\n const character = value[index];\n const alternate = character === character.toLowerCase()\n ? character.toUpperCase()\n : character.toLowerCase();\n return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;\n}\n\nfunction probeEntryCaseSensitivity(entryPath: string): boolean | undefined {\n const alternateName = alternateAsciiCase(path.basename(entryPath));\n if (!alternateName) return undefined;\n\n try {\n const canonicalPath = fs.realpathSync.native(entryPath);\n const alternatePath = fs.realpathSync.native(path.join(path.dirname(entryPath), alternateName));\n return canonicalPath === alternatePath;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\" || code === \"ENOTDIR\") return false;\n return undefined;\n }\n}\n\nfunction probeEmptyWindowsDirectory(existingAncestor: string): boolean | undefined {\n const probePath = path.join(\n existingAncestor,\n `.codebase-index-case-probe-${crypto.randomBytes(8).toString(\"hex\")}`,\n );\n let created = false;\n\n try {\n const descriptor = fs.openSync(probePath, \"wx\", 0o600);\n created = true;\n fs.closeSync(descriptor);\n return probeEntryCaseSensitivity(probePath);\n } catch {\n return undefined;\n } finally {\n if (created) fs.unlinkSync(probePath);\n }\n}\n\nfunction detectCaseInsensitiveFileSystem(existingAncestor: string): boolean | undefined {\n try {\n if (fs.statSync(existingAncestor).isDirectory()) {\n const directory = fs.opendirSync(existingAncestor);\n try {\n let entry = directory.readSync();\n while (entry) {\n if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {\n const result = probeEntryCaseSensitivity(path.join(existingAncestor, entry.name));\n if (result !== undefined) return result;\n }\n entry = directory.readSync();\n }\n } finally {\n directory.closeSync();\n }\n }\n } catch {\n return undefined;\n }\n\n if (process.platform === \"darwin\") {\n return probeEntryCaseSensitivity(existingAncestor);\n }\n\n if (process.platform === \"win32\") {\n return probeEmptyWindowsDirectory(existingAncestor);\n }\n\n return undefined;\n}\n\nfunction foldMissingPathComponent(component: string): string {\n return caseFold(component);\n}\n\nexport function canonicalizePathForComparison(\n targetPath: string,\n options: CanonicalPathComparisonOptions = {},\n): string {\n const resolved = path.resolve(targetPath);\n const missingParts: string[] = [];\n let candidate = resolved;\n\n while (true) {\n try {\n const existingAncestor = fs.realpathSync.native(candidate);\n const isCaseInsensitive = missingParts.length > 0\n ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor)\n : false;\n const suffix = isCaseInsensitive === true\n ? missingParts.map(foldMissingPathComponent)\n : missingParts;\n return path.join(existingAncestor, ...suffix);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\" && code !== \"ENOTDIR\") throw error;\n\n const parent = path.dirname(candidate);\n if (parent === candidate) return resolved;\n missingParts.unshift(path.basename(candidate));\n candidate = parent;\n }\n }\n}\n","/**\n * Unicode Case Folding\n * Generated from Unicode Character Database\n * Source: https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt\n */\n\n// Mapping of code points to their case-folded equivalents\nconst FOLDING_MAP = new Map([[65,[97]],[66,[98]],[67,[99]],[68,[100]],[69,[101]],[70,[102]],[71,[103]],[72,[104]],[73,[105]],[74,[106]],[75,[107]],[76,[108]],[77,[109]],[78,[110]],[79,[111]],[80,[112]],[81,[113]],[82,[114]],[83,[115]],[84,[116]],[85,[117]],[86,[118]],[87,[119]],[88,[120]],[89,[121]],[90,[122]],[181,[956]],[192,[224]],[193,[225]],[194,[226]],[195,[227]],[196,[228]],[197,[229]],[198,[230]],[199,[231]],[200,[232]],[201,[233]],[202,[234]],[203,[235]],[204,[236]],[205,[237]],[206,[238]],[207,[239]],[208,[240]],[209,[241]],[210,[242]],[211,[243]],[212,[244]],[213,[245]],[214,[246]],[216,[248]],[217,[249]],[218,[250]],[219,[251]],[220,[252]],[221,[253]],[222,[254]],[223,[115,115]],[256,[257]],[258,[259]],[260,[261]],[262,[263]],[264,[265]],[266,[267]],[268,[269]],[270,[271]],[272,[273]],[274,[275]],[276,[277]],[278,[279]],[280,[281]],[282,[283]],[284,[285]],[286,[287]],[288,[289]],[290,[291]],[292,[293]],[294,[295]],[296,[297]],[298,[299]],[300,[301]],[302,[303]],[304,[105,775]],[306,[307]],[308,[309]],[310,[311]],[313,[314]],[315,[316]],[317,[318]],[319,[320]],[321,[322]],[323,[324]],[325,[326]],[327,[328]],[329,[700,110]],[330,[331]],[332,[333]],[334,[335]],[336,[337]],[338,[339]],[340,[341]],[342,[343]],[344,[345]],[346,[347]],[348,[349]],[350,[351]],[352,[353]],[354,[355]],[356,[357]],[358,[359]],[360,[361]],[362,[363]],[364,[365]],[366,[367]],[368,[369]],[370,[371]],[372,[373]],[374,[375]],[376,[255]],[377,[378]],[379,[380]],[381,[382]],[383,[115]],[385,[595]],[386,[387]],[388,[389]],[390,[596]],[391,[392]],[393,[598]],[394,[599]],[395,[396]],[398,[477]],[399,[601]],[400,[603]],[401,[402]],[403,[608]],[404,[611]],[406,[617]],[407,[616]],[408,[409]],[412,[623]],[413,[626]],[415,[629]],[416,[417]],[418,[419]],[420,[421]],[422,[640]],[423,[424]],[425,[643]],[428,[429]],[430,[648]],[431,[432]],[433,[650]],[434,[651]],[435,[436]],[437,[438]],[439,[658]],[440,[441]],[444,[445]],[452,[454]],[453,[454]],[455,[457]],[456,[457]],[458,[460]],[459,[460]],[461,[462]],[463,[464]],[465,[466]],[467,[468]],[469,[470]],[471,[472]],[473,[474]],[475,[476]],[478,[479]],[480,[481]],[482,[483]],[484,[485]],[486,[487]],[488,[489]],[490,[491]],[492,[493]],[494,[495]],[496,[106,780]],[497,[499]],[498,[499]],[500,[501]],[502,[405]],[503,[447]],[504,[505]],[506,[507]],[508,[509]],[510,[511]],[512,[513]],[514,[515]],[516,[517]],[518,[519]],[520,[521]],[522,[523]],[524,[525]],[526,[527]],[528,[529]],[530,[531]],[532,[533]],[534,[535]],[536,[537]],[538,[539]],[540,[541]],[542,[543]],[544,[414]],[546,[547]],[548,[549]],[550,[551]],[552,[553]],[554,[555]],[556,[557]],[558,[559]],[560,[561]],[562,[563]],[570,[11365]],[571,[572]],[573,[410]],[574,[11366]],[577,[578]],[579,[384]],[580,[649]],[581,[652]],[582,[583]],[584,[585]],[586,[587]],[588,[589]],[590,[591]],[837,[953]],[880,[881]],[882,[883]],[886,[887]],[895,[1011]],[902,[940]],[904,[941]],[905,[942]],[906,[943]],[908,[972]],[910,[973]],[911,[974]],[912,[953,776,769]],[913,[945]],[914,[946]],[915,[947]],[916,[948]],[917,[949]],[918,[950]],[919,[951]],[920,[952]],[921,[953]],[922,[954]],[923,[955]],[924,[956]],[925,[957]],[926,[958]],[927,[959]],[928,[960]],[929,[961]],[931,[963]],[932,[964]],[933,[965]],[934,[966]],[935,[967]],[936,[968]],[937,[969]],[938,[970]],[939,[971]],[944,[965,776,769]],[962,[963]],[975,[983]],[976,[946]],[977,[952]],[981,[966]],[982,[960]],[984,[985]],[986,[987]],[988,[989]],[990,[991]],[992,[993]],[994,[995]],[996,[997]],[998,[999]],[1000,[1001]],[1002,[1003]],[1004,[1005]],[1006,[1007]],[1008,[954]],[1009,[961]],[1012,[952]],[1013,[949]],[1015,[1016]],[1017,[1010]],[1018,[1019]],[1021,[891]],[1022,[892]],[1023,[893]],[1024,[1104]],[1025,[1105]],[1026,[1106]],[1027,[1107]],[1028,[1108]],[1029,[1109]],[1030,[1110]],[1031,[1111]],[1032,[1112]],[1033,[1113]],[1034,[1114]],[1035,[1115]],[1036,[1116]],[1037,[1117]],[1038,[1118]],[1039,[1119]],[1040,[1072]],[1041,[1073]],[1042,[1074]],[1043,[1075]],[1044,[1076]],[1045,[1077]],[1046,[1078]],[1047,[1079]],[1048,[1080]],[1049,[1081]],[1050,[1082]],[1051,[1083]],[1052,[1084]],[1053,[1085]],[1054,[1086]],[1055,[1087]],[1056,[1088]],[1057,[1089]],[1058,[1090]],[1059,[1091]],[1060,[1092]],[1061,[1093]],[1062,[1094]],[1063,[1095]],[1064,[1096]],[1065,[1097]],[1066,[1098]],[1067,[1099]],[1068,[1100]],[1069,[1101]],[1070,[1102]],[1071,[1103]],[1120,[1121]],[1122,[1123]],[1124,[1125]],[1126,[1127]],[1128,[1129]],[1130,[1131]],[1132,[1133]],[1134,[1135]],[1136,[1137]],[1138,[1139]],[1140,[1141]],[1142,[1143]],[1144,[1145]],[1146,[1147]],[1148,[1149]],[1150,[1151]],[1152,[1153]],[1162,[1163]],[1164,[1165]],[1166,[1167]],[1168,[1169]],[1170,[1171]],[1172,[1173]],[1174,[1175]],[1176,[1177]],[1178,[1179]],[1180,[1181]],[1182,[1183]],[1184,[1185]],[1186,[1187]],[1188,[1189]],[1190,[1191]],[1192,[1193]],[1194,[1195]],[1196,[1197]],[1198,[1199]],[1200,[1201]],[1202,[1203]],[1204,[1205]],[1206,[1207]],[1208,[1209]],[1210,[1211]],[1212,[1213]],[1214,[1215]],[1216,[1231]],[1217,[1218]],[1219,[1220]],[1221,[1222]],[1223,[1224]],[1225,[1226]],[1227,[1228]],[1229,[1230]],[1232,[1233]],[1234,[1235]],[1236,[1237]],[1238,[1239]],[1240,[1241]],[1242,[1243]],[1244,[1245]],[1246,[1247]],[1248,[1249]],[1250,[1251]],[1252,[1253]],[1254,[1255]],[1256,[1257]],[1258,[1259]],[1260,[1261]],[1262,[1263]],[1264,[1265]],[1266,[1267]],[1268,[1269]],[1270,[1271]],[1272,[1273]],[1274,[1275]],[1276,[1277]],[1278,[1279]],[1280,[1281]],[1282,[1283]],[1284,[1285]],[1286,[1287]],[1288,[1289]],[1290,[1291]],[1292,[1293]],[1294,[1295]],[1296,[1297]],[1298,[1299]],[1300,[1301]],[1302,[1303]],[1304,[1305]],[1306,[1307]],[1308,[1309]],[1310,[1311]],[1312,[1313]],[1314,[1315]],[1316,[1317]],[1318,[1319]],[1320,[1321]],[1322,[1323]],[1324,[1325]],[1326,[1327]],[1329,[1377]],[1330,[1378]],[1331,[1379]],[1332,[1380]],[1333,[1381]],[1334,[1382]],[1335,[1383]],[1336,[1384]],[1337,[1385]],[1338,[1386]],[1339,[1387]],[1340,[1388]],[1341,[1389]],[1342,[1390]],[1343,[1391]],[1344,[1392]],[1345,[1393]],[1346,[1394]],[1347,[1395]],[1348,[1396]],[1349,[1397]],[1350,[1398]],[1351,[1399]],[1352,[1400]],[1353,[1401]],[1354,[1402]],[1355,[1403]],[1356,[1404]],[1357,[1405]],[1358,[1406]],[1359,[1407]],[1360,[1408]],[1361,[1409]],[1362,[1410]],[1363,[1411]],[1364,[1412]],[1365,[1413]],[1366,[1414]],[1415,[1381,1410]],[4256,[11520]],[4257,[11521]],[4258,[11522]],[4259,[11523]],[4260,[11524]],[4261,[11525]],[4262,[11526]],[4263,[11527]],[4264,[11528]],[4265,[11529]],[4266,[11530]],[4267,[11531]],[4268,[11532]],[4269,[11533]],[4270,[11534]],[4271,[11535]],[4272,[11536]],[4273,[11537]],[4274,[11538]],[4275,[11539]],[4276,[11540]],[4277,[11541]],[4278,[11542]],[4279,[11543]],[4280,[11544]],[4281,[11545]],[4282,[11546]],[4283,[11547]],[4284,[11548]],[4285,[11549]],[4286,[11550]],[4287,[11551]],[4288,[11552]],[4289,[11553]],[4290,[11554]],[4291,[11555]],[4292,[11556]],[4293,[11557]],[4295,[11559]],[4301,[11565]],[5112,[5104]],[5113,[5105]],[5114,[5106]],[5115,[5107]],[5116,[5108]],[5117,[5109]],[7296,[1074]],[7297,[1076]],[7298,[1086]],[7299,[1089]],[7300,[1090]],[7301,[1090]],[7302,[1098]],[7303,[1123]],[7304,[42571]],[7305,[7306]],[7312,[4304]],[7313,[4305]],[7314,[4306]],[7315,[4307]],[7316,[4308]],[7317,[4309]],[7318,[4310]],[7319,[4311]],[7320,[4312]],[7321,[4313]],[7322,[4314]],[7323,[4315]],[7324,[4316]],[7325,[4317]],[7326,[4318]],[7327,[4319]],[7328,[4320]],[7329,[4321]],[7330,[4322]],[7331,[4323]],[7332,[4324]],[7333,[4325]],[7334,[4326]],[7335,[4327]],[7336,[4328]],[7337,[4329]],[7338,[4330]],[7339,[4331]],[7340,[4332]],[7341,[4333]],[7342,[4334]],[7343,[4335]],[7344,[4336]],[7345,[4337]],[7346,[4338]],[7347,[4339]],[7348,[4340]],[7349,[4341]],[7350,[4342]],[7351,[4343]],[7352,[4344]],[7353,[4345]],[7354,[4346]],[7357,[4349]],[7358,[4350]],[7359,[4351]],[7680,[7681]],[7682,[7683]],[7684,[7685]],[7686,[7687]],[7688,[7689]],[7690,[7691]],[7692,[7693]],[7694,[7695]],[7696,[7697]],[7698,[7699]],[7700,[7701]],[7702,[7703]],[7704,[7705]],[7706,[7707]],[7708,[7709]],[7710,[7711]],[7712,[7713]],[7714,[7715]],[7716,[7717]],[7718,[7719]],[7720,[7721]],[7722,[7723]],[7724,[7725]],[7726,[7727]],[7728,[7729]],[7730,[7731]],[7732,[7733]],[7734,[7735]],[7736,[7737]],[7738,[7739]],[7740,[7741]],[7742,[7743]],[7744,[7745]],[7746,[7747]],[7748,[7749]],[7750,[7751]],[7752,[7753]],[7754,[7755]],[7756,[7757]],[7758,[7759]],[7760,[7761]],[7762,[7763]],[7764,[7765]],[7766,[7767]],[7768,[7769]],[7770,[7771]],[7772,[7773]],[7774,[7775]],[7776,[7777]],[7778,[7779]],[7780,[7781]],[7782,[7783]],[7784,[7785]],[7786,[7787]],[7788,[7789]],[7790,[7791]],[7792,[7793]],[7794,[7795]],[7796,[7797]],[7798,[7799]],[7800,[7801]],[7802,[7803]],[7804,[7805]],[7806,[7807]],[7808,[7809]],[7810,[7811]],[7812,[7813]],[7814,[7815]],[7816,[7817]],[7818,[7819]],[7820,[7821]],[7822,[7823]],[7824,[7825]],[7826,[7827]],[7828,[7829]],[7830,[104,817]],[7831,[116,776]],[7832,[119,778]],[7833,[121,778]],[7834,[97,702]],[7835,[7777]],[7838,[115,115]],[7840,[7841]],[7842,[7843]],[7844,[7845]],[7846,[7847]],[7848,[7849]],[7850,[7851]],[7852,[7853]],[7854,[7855]],[7856,[7857]],[7858,[7859]],[7860,[7861]],[7862,[7863]],[7864,[7865]],[7866,[7867]],[7868,[7869]],[7870,[7871]],[7872,[7873]],[7874,[7875]],[7876,[7877]],[7878,[7879]],[7880,[7881]],[7882,[7883]],[7884,[7885]],[7886,[7887]],[7888,[7889]],[7890,[7891]],[7892,[7893]],[7894,[7895]],[7896,[7897]],[7898,[7899]],[7900,[7901]],[7902,[7903]],[7904,[7905]],[7906,[7907]],[7908,[7909]],[7910,[7911]],[7912,[7913]],[7914,[7915]],[7916,[7917]],[7918,[7919]],[7920,[7921]],[7922,[7923]],[7924,[7925]],[7926,[7927]],[7928,[7929]],[7930,[7931]],[7932,[7933]],[7934,[7935]],[7944,[7936]],[7945,[7937]],[7946,[7938]],[7947,[7939]],[7948,[7940]],[7949,[7941]],[7950,[7942]],[7951,[7943]],[7960,[7952]],[7961,[7953]],[7962,[7954]],[7963,[7955]],[7964,[7956]],[7965,[7957]],[7976,[7968]],[7977,[7969]],[7978,[7970]],[7979,[7971]],[7980,[7972]],[7981,[7973]],[7982,[7974]],[7983,[7975]],[7992,[7984]],[7993,[7985]],[7994,[7986]],[7995,[7987]],[7996,[7988]],[7997,[7989]],[7998,[7990]],[7999,[7991]],[8008,[8000]],[8009,[8001]],[8010,[8002]],[8011,[8003]],[8012,[8004]],[8013,[8005]],[8016,[965,787]],[8018,[965,787,768]],[8020,[965,787,769]],[8022,[965,787,834]],[8025,[8017]],[8027,[8019]],[8029,[8021]],[8031,[8023]],[8040,[8032]],[8041,[8033]],[8042,[8034]],[8043,[8035]],[8044,[8036]],[8045,[8037]],[8046,[8038]],[8047,[8039]],[8064,[7936,953]],[8065,[7937,953]],[8066,[7938,953]],[8067,[7939,953]],[8068,[7940,953]],[8069,[7941,953]],[8070,[7942,953]],[8071,[7943,953]],[8072,[7936,953]],[8073,[7937,953]],[8074,[7938,953]],[8075,[7939,953]],[8076,[7940,953]],[8077,[7941,953]],[8078,[7942,953]],[8079,[7943,953]],[8080,[7968,953]],[8081,[7969,953]],[8082,[7970,953]],[8083,[7971,953]],[8084,[7972,953]],[8085,[7973,953]],[8086,[7974,953]],[8087,[7975,953]],[8088,[7968,953]],[8089,[7969,953]],[8090,[7970,953]],[8091,[7971,953]],[8092,[7972,953]],[8093,[7973,953]],[8094,[7974,953]],[8095,[7975,953]],[8096,[8032,953]],[8097,[8033,953]],[8098,[8034,953]],[8099,[8035,953]],[8100,[8036,953]],[8101,[8037,953]],[8102,[8038,953]],[8103,[8039,953]],[8104,[8032,953]],[8105,[8033,953]],[8106,[8034,953]],[8107,[8035,953]],[8108,[8036,953]],[8109,[8037,953]],[8110,[8038,953]],[8111,[8039,953]],[8114,[8048,953]],[8115,[945,953]],[8116,[940,953]],[8118,[945,834]],[8119,[945,834,953]],[8120,[8112]],[8121,[8113]],[8122,[8048]],[8123,[8049]],[8124,[945,953]],[8126,[953]],[8130,[8052,953]],[8131,[951,953]],[8132,[942,953]],[8134,[951,834]],[8135,[951,834,953]],[8136,[8050]],[8137,[8051]],[8138,[8052]],[8139,[8053]],[8140,[951,953]],[8146,[953,776,768]],[8147,[953,776,769]],[8150,[953,834]],[8151,[953,776,834]],[8152,[8144]],[8153,[8145]],[8154,[8054]],[8155,[8055]],[8162,[965,776,768]],[8163,[965,776,769]],[8164,[961,787]],[8166,[965,834]],[8167,[965,776,834]],[8168,[8160]],[8169,[8161]],[8170,[8058]],[8171,[8059]],[8172,[8165]],[8178,[8060,953]],[8179,[969,953]],[8180,[974,953]],[8182,[969,834]],[8183,[969,834,953]],[8184,[8056]],[8185,[8057]],[8186,[8060]],[8187,[8061]],[8188,[969,953]],[8486,[969]],[8490,[107]],[8491,[229]],[8498,[8526]],[8544,[8560]],[8545,[8561]],[8546,[8562]],[8547,[8563]],[8548,[8564]],[8549,[8565]],[8550,[8566]],[8551,[8567]],[8552,[8568]],[8553,[8569]],[8554,[8570]],[8555,[8571]],[8556,[8572]],[8557,[8573]],[8558,[8574]],[8559,[8575]],[8579,[8580]],[9398,[9424]],[9399,[9425]],[9400,[9426]],[9401,[9427]],[9402,[9428]],[9403,[9429]],[9404,[9430]],[9405,[9431]],[9406,[9432]],[9407,[9433]],[9408,[9434]],[9409,[9435]],[9410,[9436]],[9411,[9437]],[9412,[9438]],[9413,[9439]],[9414,[9440]],[9415,[9441]],[9416,[9442]],[9417,[9443]],[9418,[9444]],[9419,[9445]],[9420,[9446]],[9421,[9447]],[9422,[9448]],[9423,[9449]],[11264,[11312]],[11265,[11313]],[11266,[11314]],[11267,[11315]],[11268,[11316]],[11269,[11317]],[11270,[11318]],[11271,[11319]],[11272,[11320]],[11273,[11321]],[11274,[11322]],[11275,[11323]],[11276,[11324]],[11277,[11325]],[11278,[11326]],[11279,[11327]],[11280,[11328]],[11281,[11329]],[11282,[11330]],[11283,[11331]],[11284,[11332]],[11285,[11333]],[11286,[11334]],[11287,[11335]],[11288,[11336]],[11289,[11337]],[11290,[11338]],[11291,[11339]],[11292,[11340]],[11293,[11341]],[11294,[11342]],[11295,[11343]],[11296,[11344]],[11297,[11345]],[11298,[11346]],[11299,[11347]],[11300,[11348]],[11301,[11349]],[11302,[11350]],[11303,[11351]],[11304,[11352]],[11305,[11353]],[11306,[11354]],[11307,[11355]],[11308,[11356]],[11309,[11357]],[11310,[11358]],[11311,[11359]],[11360,[11361]],[11362,[619]],[11363,[7549]],[11364,[637]],[11367,[11368]],[11369,[11370]],[11371,[11372]],[11373,[593]],[11374,[625]],[11375,[592]],[11376,[594]],[11378,[11379]],[11381,[11382]],[11390,[575]],[11391,[576]],[11392,[11393]],[11394,[11395]],[11396,[11397]],[11398,[11399]],[11400,[11401]],[11402,[11403]],[11404,[11405]],[11406,[11407]],[11408,[11409]],[11410,[11411]],[11412,[11413]],[11414,[11415]],[11416,[11417]],[11418,[11419]],[11420,[11421]],[11422,[11423]],[11424,[11425]],[11426,[11427]],[11428,[11429]],[11430,[11431]],[11432,[11433]],[11434,[11435]],[11436,[11437]],[11438,[11439]],[11440,[11441]],[11442,[11443]],[11444,[11445]],[11446,[11447]],[11448,[11449]],[11450,[11451]],[11452,[11453]],[11454,[11455]],[11456,[11457]],[11458,[11459]],[11460,[11461]],[11462,[11463]],[11464,[11465]],[11466,[11467]],[11468,[11469]],[11470,[11471]],[11472,[11473]],[11474,[11475]],[11476,[11477]],[11478,[11479]],[11480,[11481]],[11482,[11483]],[11484,[11485]],[11486,[11487]],[11488,[11489]],[11490,[11491]],[11499,[11500]],[11501,[11502]],[11506,[11507]],[42560,[42561]],[42562,[42563]],[42564,[42565]],[42566,[42567]],[42568,[42569]],[42570,[42571]],[42572,[42573]],[42574,[42575]],[42576,[42577]],[42578,[42579]],[42580,[42581]],[42582,[42583]],[42584,[42585]],[42586,[42587]],[42588,[42589]],[42590,[42591]],[42592,[42593]],[42594,[42595]],[42596,[42597]],[42598,[42599]],[42600,[42601]],[42602,[42603]],[42604,[42605]],[42624,[42625]],[42626,[42627]],[42628,[42629]],[42630,[42631]],[42632,[42633]],[42634,[42635]],[42636,[42637]],[42638,[42639]],[42640,[42641]],[42642,[42643]],[42644,[42645]],[42646,[42647]],[42648,[42649]],[42650,[42651]],[42786,[42787]],[42788,[42789]],[42790,[42791]],[42792,[42793]],[42794,[42795]],[42796,[42797]],[42798,[42799]],[42802,[42803]],[42804,[42805]],[42806,[42807]],[42808,[42809]],[42810,[42811]],[42812,[42813]],[42814,[42815]],[42816,[42817]],[42818,[42819]],[42820,[42821]],[42822,[42823]],[42824,[42825]],[42826,[42827]],[42828,[42829]],[42830,[42831]],[42832,[42833]],[42834,[42835]],[42836,[42837]],[42838,[42839]],[42840,[42841]],[42842,[42843]],[42844,[42845]],[42846,[42847]],[42848,[42849]],[42850,[42851]],[42852,[42853]],[42854,[42855]],[42856,[42857]],[42858,[42859]],[42860,[42861]],[42862,[42863]],[42873,[42874]],[42875,[42876]],[42877,[7545]],[42878,[42879]],[42880,[42881]],[42882,[42883]],[42884,[42885]],[42886,[42887]],[42891,[42892]],[42893,[613]],[42896,[42897]],[42898,[42899]],[42902,[42903]],[42904,[42905]],[42906,[42907]],[42908,[42909]],[42910,[42911]],[42912,[42913]],[42914,[42915]],[42916,[42917]],[42918,[42919]],[42920,[42921]],[42922,[614]],[42923,[604]],[42924,[609]],[42925,[620]],[42926,[618]],[42928,[670]],[42929,[647]],[42930,[669]],[42931,[43859]],[42932,[42933]],[42934,[42935]],[42936,[42937]],[42938,[42939]],[42940,[42941]],[42942,[42943]],[42944,[42945]],[42946,[42947]],[42948,[42900]],[42949,[642]],[42950,[7566]],[42951,[42952]],[42953,[42954]],[42955,[612]],[42956,[42957]],[42958,[42959]],[42960,[42961]],[42962,[42963]],[42964,[42965]],[42966,[42967]],[42968,[42969]],[42970,[42971]],[42972,[411]],[42997,[42998]],[43888,[5024]],[43889,[5025]],[43890,[5026]],[43891,[5027]],[43892,[5028]],[43893,[5029]],[43894,[5030]],[43895,[5031]],[43896,[5032]],[43897,[5033]],[43898,[5034]],[43899,[5035]],[43900,[5036]],[43901,[5037]],[43902,[5038]],[43903,[5039]],[43904,[5040]],[43905,[5041]],[43906,[5042]],[43907,[5043]],[43908,[5044]],[43909,[5045]],[43910,[5046]],[43911,[5047]],[43912,[5048]],[43913,[5049]],[43914,[5050]],[43915,[5051]],[43916,[5052]],[43917,[5053]],[43918,[5054]],[43919,[5055]],[43920,[5056]],[43921,[5057]],[43922,[5058]],[43923,[5059]],[43924,[5060]],[43925,[5061]],[43926,[5062]],[43927,[5063]],[43928,[5064]],[43929,[5065]],[43930,[5066]],[43931,[5067]],[43932,[5068]],[43933,[5069]],[43934,[5070]],[43935,[5071]],[43936,[5072]],[43937,[5073]],[43938,[5074]],[43939,[5075]],[43940,[5076]],[43941,[5077]],[43942,[5078]],[43943,[5079]],[43944,[5080]],[43945,[5081]],[43946,[5082]],[43947,[5083]],[43948,[5084]],[43949,[5085]],[43950,[5086]],[43951,[5087]],[43952,[5088]],[43953,[5089]],[43954,[5090]],[43955,[5091]],[43956,[5092]],[43957,[5093]],[43958,[5094]],[43959,[5095]],[43960,[5096]],[43961,[5097]],[43962,[5098]],[43963,[5099]],[43964,[5100]],[43965,[5101]],[43966,[5102]],[43967,[5103]],[64256,[102,102]],[64257,[102,105]],[64258,[102,108]],[64259,[102,102,105]],[64260,[102,102,108]],[64261,[115,116]],[64262,[115,116]],[64275,[1396,1398]],[64276,[1396,1381]],[64277,[1396,1387]],[64278,[1406,1398]],[64279,[1396,1389]],[65313,[65345]],[65314,[65346]],[65315,[65347]],[65316,[65348]],[65317,[65349]],[65318,[65350]],[65319,[65351]],[65320,[65352]],[65321,[65353]],[65322,[65354]],[65323,[65355]],[65324,[65356]],[65325,[65357]],[65326,[65358]],[65327,[65359]],[65328,[65360]],[65329,[65361]],[65330,[65362]],[65331,[65363]],[65332,[65364]],[65333,[65365]],[65334,[65366]],[65335,[65367]],[65336,[65368]],[65337,[65369]],[65338,[65370]],[66560,[66600]],[66561,[66601]],[66562,[66602]],[66563,[66603]],[66564,[66604]],[66565,[66605]],[66566,[66606]],[66567,[66607]],[66568,[66608]],[66569,[66609]],[66570,[66610]],[66571,[66611]],[66572,[66612]],[66573,[66613]],[66574,[66614]],[66575,[66615]],[66576,[66616]],[66577,[66617]],[66578,[66618]],[66579,[66619]],[66580,[66620]],[66581,[66621]],[66582,[66622]],[66583,[66623]],[66584,[66624]],[66585,[66625]],[66586,[66626]],[66587,[66627]],[66588,[66628]],[66589,[66629]],[66590,[66630]],[66591,[66631]],[66592,[66632]],[66593,[66633]],[66594,[66634]],[66595,[66635]],[66596,[66636]],[66597,[66637]],[66598,[66638]],[66599,[66639]],[66736,[66776]],[66737,[66777]],[66738,[66778]],[66739,[66779]],[66740,[66780]],[66741,[66781]],[66742,[66782]],[66743,[66783]],[66744,[66784]],[66745,[66785]],[66746,[66786]],[66747,[66787]],[66748,[66788]],[66749,[66789]],[66750,[66790]],[66751,[66791]],[66752,[66792]],[66753,[66793]],[66754,[66794]],[66755,[66795]],[66756,[66796]],[66757,[66797]],[66758,[66798]],[66759,[66799]],[66760,[66800]],[66761,[66801]],[66762,[66802]],[66763,[66803]],[66764,[66804]],[66765,[66805]],[66766,[66806]],[66767,[66807]],[66768,[66808]],[66769,[66809]],[66770,[66810]],[66771,[66811]],[66928,[66967]],[66929,[66968]],[66930,[66969]],[66931,[66970]],[66932,[66971]],[66933,[66972]],[66934,[66973]],[66935,[66974]],[66936,[66975]],[66937,[66976]],[66938,[66977]],[66940,[66979]],[66941,[66980]],[66942,[66981]],[66943,[66982]],[66944,[66983]],[66945,[66984]],[66946,[66985]],[66947,[66986]],[66948,[66987]],[66949,[66988]],[66950,[66989]],[66951,[66990]],[66952,[66991]],[66953,[66992]],[66954,[66993]],[66956,[66995]],[66957,[66996]],[66958,[66997]],[66959,[66998]],[66960,[66999]],[66961,[67000]],[66962,[67001]],[66964,[67003]],[66965,[67004]],[68736,[68800]],[68737,[68801]],[68738,[68802]],[68739,[68803]],[68740,[68804]],[68741,[68805]],[68742,[68806]],[68743,[68807]],[68744,[68808]],[68745,[68809]],[68746,[68810]],[68747,[68811]],[68748,[68812]],[68749,[68813]],[68750,[68814]],[68751,[68815]],[68752,[68816]],[68753,[68817]],[68754,[68818]],[68755,[68819]],[68756,[68820]],[68757,[68821]],[68758,[68822]],[68759,[68823]],[68760,[68824]],[68761,[68825]],[68762,[68826]],[68763,[68827]],[68764,[68828]],[68765,[68829]],[68766,[68830]],[68767,[68831]],[68768,[68832]],[68769,[68833]],[68770,[68834]],[68771,[68835]],[68772,[68836]],[68773,[68837]],[68774,[68838]],[68775,[68839]],[68776,[68840]],[68777,[68841]],[68778,[68842]],[68779,[68843]],[68780,[68844]],[68781,[68845]],[68782,[68846]],[68783,[68847]],[68784,[68848]],[68785,[68849]],[68786,[68850]],[68944,[68976]],[68945,[68977]],[68946,[68978]],[68947,[68979]],[68948,[68980]],[68949,[68981]],[68950,[68982]],[68951,[68983]],[68952,[68984]],[68953,[68985]],[68954,[68986]],[68955,[68987]],[68956,[68988]],[68957,[68989]],[68958,[68990]],[68959,[68991]],[68960,[68992]],[68961,[68993]],[68962,[68994]],[68963,[68995]],[68964,[68996]],[68965,[68997]],[71840,[71872]],[71841,[71873]],[71842,[71874]],[71843,[71875]],[71844,[71876]],[71845,[71877]],[71846,[71878]],[71847,[71879]],[71848,[71880]],[71849,[71881]],[71850,[71882]],[71851,[71883]],[71852,[71884]],[71853,[71885]],[71854,[71886]],[71855,[71887]],[71856,[71888]],[71857,[71889]],[71858,[71890]],[71859,[71891]],[71860,[71892]],[71861,[71893]],[71862,[71894]],[71863,[71895]],[71864,[71896]],[71865,[71897]],[71866,[71898]],[71867,[71899]],[71868,[71900]],[71869,[71901]],[71870,[71902]],[71871,[71903]],[93760,[93792]],[93761,[93793]],[93762,[93794]],[93763,[93795]],[93764,[93796]],[93765,[93797]],[93766,[93798]],[93767,[93799]],[93768,[93800]],[93769,[93801]],[93770,[93802]],[93771,[93803]],[93772,[93804]],[93773,[93805]],[93774,[93806]],[93775,[93807]],[93776,[93808]],[93777,[93809]],[93778,[93810]],[93779,[93811]],[93780,[93812]],[93781,[93813]],[93782,[93814]],[93783,[93815]],[93784,[93816]],[93785,[93817]],[93786,[93818]],[93787,[93819]],[93788,[93820]],[93789,[93821]],[93790,[93822]],[93791,[93823]],[93856,[93883]],[93857,[93884]],[93858,[93885]],[93859,[93886]],[93860,[93887]],[93861,[93888]],[93862,[93889]],[93863,[93890]],[93864,[93891]],[93865,[93892]],[93866,[93893]],[93867,[93894]],[93868,[93895]],[93869,[93896]],[93870,[93897]],[93871,[93898]],[93872,[93899]],[93873,[93900]],[93874,[93901]],[93875,[93902]],[93876,[93903]],[93877,[93904]],[93878,[93905]],[93879,[93906]],[93880,[93907]],[125184,[125218]],[125185,[125219]],[125186,[125220]],[125187,[125221]],[125188,[125222]],[125189,[125223]],[125190,[125224]],[125191,[125225]],[125192,[125226]],[125193,[125227]],[125194,[125228]],[125195,[125229]],[125196,[125230]],[125197,[125231]],[125198,[125232]],[125199,[125233]],[125200,[125234]],[125201,[125235]],[125202,[125236]],[125203,[125237]],[125204,[125238]],[125205,[125239]],[125206,[125240]],[125207,[125241]],[125208,[125242]],[125209,[125243]],[125210,[125244]],[125211,[125245]],[125212,[125246]],[125213,[125247]],[125214,[125248]],[125215,[125249]],[125216,[125250]],[125217,[125251]]]);\n\n/**\n * Applies Unicode case folding to a string\n * @param {string} input - The string to case fold\n * @returns {string} The case-folded string\n */\nexport function caseFold(input) {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n\n let result = [];\n\n for (const char of input) {\n const codePoint = char.codePointAt(0);\n\n const mapping = FOLDING_MAP.get(codePoint);\n\n result.push(mapping ? String.fromCodePoint(...mapping) : char);\n }\n\n return result.join(\"\");\n}\n\n/**\n * Compares two strings using Unicode case folding\n * @param {string} str1 - First string to compare\n * @param {string} str2 - Second string to compare\n * @returns {boolean} True if the strings are case-fold equivalent\n */\nexport function caseFoldEquals(str1, str2) {\n return caseFold(str1) === caseFold(str2);\n}\n\n/**\n * Returns the full case folding mapping for a code point\n * @param {number} codePoint - The Unicode code point to look up\n * @returns {number[] | undefined} Array of code points this folds to, or undefined\n */\nexport function lookupFolding(codePoint) {\n if (typeof codePoint !== \"number\") {\n throw new TypeError(\"Code point must be a number\");\n }\n\n return FOLDING_MAP.get(codePoint);\n}\n\n// Named exports\nexport default {\n caseFold,\n caseFoldEquals,\n lookupFolding,\n};\n","import * as path from \"path\";\n\nimport { normalizePathSeparators } from \"../utils/paths.js\";\n\n\nfunction isWithinRoot(rootDir: string, targetPath: string): boolean {\n const relativePath = path.relative(rootDir, targetPath);\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath));\n}\n\nexport function rebasePathEntries(\n values: unknown,\n fromDir: string,\n toDir: string,\n): string[] {\n if (!Array.isArray(values)) {\n return [];\n }\n\n return values\n .filter((value): value is string => typeof value === \"string\")\n .map((value) => {\n const trimmed = value.trim();\n if (!trimmed || path.isAbsolute(trimmed)) {\n return trimmed;\n }\n\n return normalizePathSeparators(path.normalize(path.relative(toDir, path.resolve(fromDir, trimmed))));\n })\n .filter(Boolean);\n}\n\nexport function resolveInheritedKnowledgeBaseEntries(\n values: unknown,\n sourceRoot: string,\n targetRoot: string,\n): string[] {\n if (!Array.isArray(values)) {\n return [];\n }\n\n return values\n .filter((value): value is string => typeof value === \"string\")\n .map((value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return trimmed;\n }\n\n if (path.isAbsolute(trimmed)) {\n if (isWithinRoot(sourceRoot, trimmed)) {\n return normalizePathSeparators(path.normalize(path.relative(sourceRoot, trimmed) || \".\"));\n }\n\n return path.normalize(trimmed);\n }\n\n const resolvedFromSource = path.resolve(sourceRoot, trimmed);\n if (isWithinRoot(sourceRoot, resolvedFromSource)) {\n return normalizePathSeparators(path.normalize(trimmed));\n }\n\n return normalizePathSeparators(path.normalize(path.relative(targetRoot, resolvedFromSource)));\n })\n .filter(Boolean);\n}\n","import * as path from \"path\";\n\nexport function normalizePathSeparators(value: string): string {\n return value.replace(/\\\\/g, \"/\");\n}\n\nexport function isHiddenPathSegment(part: string): boolean {\n return part.startsWith(\".\") && part !== \".\" && part !== \"..\";\n}\n\nexport function isBuildPathSegment(part: string): boolean {\n return part.toLowerCase().includes(\"build\");\n}\n\nexport function hasFilteredPathSegment(relativePath: string, separator: string = path.sep): boolean {\n return relativePath.split(separator).some(\n (part) => isHiddenPathSegment(part) || isBuildPathSegment(part)\n );\n}\n\n/**\n * Directories that should never be watched when they appear as a top-level\n * segment of a relative path. These are OS-level directories that are either\n * permission-restricted or irrelevant to source code projects.\n *\n * macOS: Library, Applications, System, Volumes, private, cores\n * Linux: proc, sys, dev, run, snap\n * Windows: Windows, ProgramData, Program Files, $Recycle.Bin\n */\nconst RESTRICTED_DIRECTORIES = new Set([\n // macOS\n \"library\",\n \"applications\",\n \"system\",\n \"volumes\",\n \"private\",\n \"cores\",\n // Linux\n \"proc\",\n \"sys\",\n \"dev\",\n \"run\",\n \"snap\",\n // Windows\n \"windows\",\n \"programdata\",\n \"program files\",\n \"program files (x86)\",\n \"$recycle.bin\",\n]);\n\n/**\n * Returns true if the first path segment is a known OS-restricted directory.\n * This prevents the watcher from descending into paths like ~/Library/ on macOS.\n */\nexport function isRestrictedDirectory(relativePath: string, separator: string = path.sep): boolean {\n const firstSegment = relativePath.split(separator)[0];\n if (!firstSegment) return false;\n return RESTRICTED_DIRECTORIES.has(firstSegment.toLowerCase());\n}\n","export const DEFAULT_INCLUDE = [\n \"**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}\",\n \"**/*.{py,pyi}\",\n \"**/*.{go,rs,java,cs,kt,scala}\",\n \"**/*.{c,cpp,cc,cxx,h,hpp,hxx}\",\n \"**/*.{rb,php,inc,swift}\",\n \"**/*.{cls,trigger}\",\n \"**/*.{vue,svelte,astro}\",\n \"**/*.{sql,graphql,proto}\",\n \"**/*.{yaml,yml,toml}\",\n \"**/*.{md,mdx}\",\n \"**/*.{sh,bash,zsh}\",\n \"**/*.{txt,html,htm}\",\n \"**/*.zig\",\n \"**/*.gd\",\n \"**/*.metal\",\n];\n\nexport const DEFAULT_EXCLUDE = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/*build*/**\",\n \"**/*.min.js\",\n \"**/*.bundle.js\",\n \"**/vendor/**\",\n \"**/__pycache__/**\",\n \"**/target/**\",\n \"**/coverage/**\",\n \"**/.next/**\",\n \"**/.nuxt/**\",\n \"**/.opencode/**\",\n \"**/.*\",\n \"**/.*/**\",\n];\n\nexport const EMBEDDING_MODELS = {\n \"google\": {\n // `text-embedding-004` is DEPRECATED - https://ai.google.dev/gemini-api/docs/deprecations\n \"text-embedding-005\": {\n provider: \"google\",\n model: \"text-embedding-005\",\n dimensions: 768,\n maxTokens: 2048,\n costPer1MTokens: 0.025,\n taskAble: false,\n // Note: on reality, this model allows for task-specific embeddings. See: https://docs.cloud.google.com/vertex-ai/generative-ai/docs/embeddings/task-types\n },\n \"gemini-embedding-001\": {\n provider: \"google\",\n model: \"gemini-embedding-001\",\n // Native output is 3072D, but we use Matryoshka truncation via outputDimensionality\n // to reduce to 1536D for better storage/search efficiency with minimal quality loss.\n // Google recommends 768, 1536, or 3072. See: https://ai.google.dev/gemini-api/docs/embeddings\n dimensions: 1536,\n maxTokens: 2048,\n costPer1MTokens: 0.15,\n taskAble: true,\n },\n \"gemini-embedding-2\": {\n provider: \"google\",\n model: \"gemini-embedding-2\",\n // Keep a conservative, testable default embedding dimension. Gemini Embedding 2 supports\n // flexible dimensions via outputDimensionality.\n dimensions: 1536,\n maxTokens: 8192,\n costPer1MTokens: 0.15,\n taskAble: false,\n promptStyle: \"embedding-2\",\n },\n },\n \"openai\": {\n \"text-embedding-3-small\": {\n provider: \"openai\",\n model: \"text-embedding-3-small\",\n dimensions: 1536,\n maxTokens: 8191,\n costPer1MTokens: 0.02,\n },\n \"text-embedding-3-large\": {\n provider: \"openai\",\n model: \"text-embedding-3-large\",\n dimensions: 3072,\n maxTokens: 8191,\n costPer1MTokens: 0.13,\n },\n },\n \"ollama\": {\n \"nomic-embed-text\": {\n provider: \"ollama\",\n model: \"nomic-embed-text\",\n dimensions: 768,\n maxTokens: 2048,\n costPer1MTokens: 0.00,\n },\n \"mxbai-embed-large\": {\n provider: \"ollama\",\n model: \"mxbai-embed-large\",\n dimensions: 1024,\n maxTokens: 512,\n costPer1MTokens: 0.00,\n },\n },\n} as const;\n\nexport const DEFAULT_PROVIDER_MODELS = {\n \"openai\": \"text-embedding-3-small\",\n \"google\": \"gemini-embedding-001\",\n \"ollama\": \"nomic-embed-text\",\n} as const;\n\nexport const AUTO_DETECT_PROVIDER_ORDER = [\n \"ollama\",\n \"openai\",\n \"google\",\n] as const;\n","import type {\n DebugConfig,\n IndexingConfig,\n RerankerProvider,\n SearchConfig,\n} from \"./schema.js\";\n\nexport function getDefaultIndexingConfig(): IndexingConfig {\n return {\n autoIndex: false,\n autoIndexWaitMs: 10_000,\n autoIndexMaxRetries: 5,\n autoIndexRetryDelayMs: 100,\n watchFiles: true,\n pauseBackgroundIndexingOnBattery: false,\n maxFileSize: 1048576,\n maxChunksPerFile: 100,\n semanticOnly: false,\n retries: 3,\n retryDelayMs: 1000,\n autoGc: true,\n gcIntervalDays: 7,\n gcOrphanThreshold: 100,\n requireProjectMarker: true,\n maxDepth: 5,\n maxFilesPerDirectory: 100,\n fallbackToTextOnMaxChunks: true,\n // Must stay in sync with DEFAULT_LINES_PER_CHUNK in native/src/lib.rs (the napi\n // fallback used when a native caller omits the argument).\n linesPerChunk: 30,\n gitBlame: { enabled: false },\n };\n}\n\nexport function getDefaultSearchConfig(): SearchConfig {\n return {\n maxResults: 20,\n minScore: 0.1,\n includeContext: true,\n hybridWeight: 0.5,\n fusionStrategy: \"rrf\",\n rrfK: 60,\n rerankTopN: 20,\n contextLines: 0,\n routingHints: true,\n routingGraphHandoffHints: false,\n routingHintRole: \"system\",\n communityBoost: 0,\n };\n}\n\nexport function getDefaultRerankerBaseUrl(provider: RerankerProvider): string {\n switch (provider) {\n case \"cohere\":\n return \"https://api.cohere.ai/v1\";\n case \"jina\":\n return \"https://api.jina.ai/v1\";\n case \"custom\":\n return \"\";\n }\n}\n\nexport function getDefaultDebugConfig(): DebugConfig {\n return {\n enabled: false,\n logLevel: \"info\",\n logSearch: true,\n logEmbedding: true,\n logCache: true,\n logGc: true,\n logBranch: true,\n metrics: true,\n };\n}\n","const ENV_REFERENCE_PATTERN = /^\\{env:([A-Z_][A-Z0-9_]*)\\}$/;\nconst ENV_REFERENCE_LIKE_PATTERN = /\\{env:[^}]+\\}/;\n\nexport function substituteEnvString(value: string, keyPath: string): string {\n const match = value.match(ENV_REFERENCE_PATTERN);\n\n if (!match) {\n if (ENV_REFERENCE_LIKE_PATTERN.test(value)) {\n throw new Error(\n `Invalid environment variable reference at '${keyPath}'. ` +\n \"Expected the entire string to match '{env:VAR_NAME}' with VAR_NAME matching [A-Z_][A-Z0-9_]*.\"\n );\n }\n\n return value;\n }\n\n const variableName = match[1];\n const envValue = process.env[variableName];\n\n if (envValue === undefined) {\n throw new Error(`Missing environment variable '${variableName}' referenced by config at '${keyPath}'.`);\n }\n\n return envValue;\n}\n\nexport function substituteEnvReferences(raw: unknown, keyPath = \"$root\"): unknown {\n if (typeof raw === \"string\") {\n return substituteEnvString(raw, keyPath);\n }\n\n if (Array.isArray(raw)) {\n return raw.map((item, index) => substituteEnvReferences(item, `${keyPath}[${index}]`));\n }\n\n if (raw && typeof raw === \"object\") {\n return Object.fromEntries(\n Object.entries(raw).map(([key, value]) => [key, substituteEnvReferences(value, `${keyPath}.${key}`)])\n );\n }\n\n return raw;\n}\n","import type {\n EmbeddingProvider,\n IndexScope,\n LogLevel,\n ProviderModels,\n RerankerProvider,\n SearchConfig,\n} from \"./schema.js\";\n\nimport { EMBEDDING_MODELS } from \"./constants.js\";\nimport { substituteEnvString } from \"./env-substitution.js\";\n\nconst VALID_SCOPES: IndexScope[] = [\"project\", \"global\"];\nconst VALID_LOG_LEVELS: LogLevel[] = [\"error\", \"warn\", \"info\", \"debug\"];\n\nexport function isValidFusionStrategy(value: unknown): value is SearchConfig[\"fusionStrategy\"] {\n return value === \"weighted\" || value === \"rrf\";\n}\n\nexport function isValidRerankerProvider(value: unknown): value is RerankerProvider {\n return value === \"cohere\" || value === \"jina\" || value === \"custom\";\n}\n\nexport function isValidProvider(value: unknown): value is EmbeddingProvider {\n return typeof value === \"string\" && Object.keys(EMBEDDING_MODELS).includes(value);\n}\n\nexport function isValidModel<P extends EmbeddingProvider>(\n value: unknown,\n provider: P\n): value is ProviderModels[P] {\n // Ollama exposes model metadata at runtime, so its local model names are not\n // restricted to the built-in catalog.\n if (typeof value === \"string\" && provider === \"ollama\" && value.trim().length > 0) {\n return true;\n }\n return typeof value === \"string\" && Object.keys(EMBEDDING_MODELS[provider]).includes(value);\n}\n\nexport function isValidScope(value: unknown): value is IndexScope {\n return typeof value === \"string\" && VALID_SCOPES.includes(value as IndexScope);\n}\n\nexport function isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(item => typeof item === \"string\");\n}\n\nexport function getResolvedString(value: unknown, keyPath: string): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return substituteEnvString(value, keyPath);\n}\n\nexport function getResolvedStringArray(value: unknown, keyPath: string): string[] | undefined {\n if (!isStringArray(value)) {\n return undefined;\n }\n\n return value.map((item, index) => substituteEnvString(item, `${keyPath}[${index}]`));\n}\n\nexport function isValidLogLevel(value: unknown): value is LogLevel {\n return typeof value === \"string\" && VALID_LOG_LEVELS.includes(value as LogLevel);\n}\n","// Config schema without zod dependency to avoid version conflicts with OpenCode SDK\n\nimport { AUTO_DETECT_PROVIDER_ORDER, DEFAULT_INCLUDE, DEFAULT_EXCLUDE, EMBEDDING_MODELS, DEFAULT_PROVIDER_MODELS } from \"./constants.js\";\nimport {\n getDefaultDebugConfig,\n getDefaultIndexingConfig,\n getDefaultRerankerBaseUrl,\n getDefaultSearchConfig,\n} from \"./defaults.js\";\nimport {\n getResolvedString,\n getResolvedStringArray,\n isStringArray,\n isValidFusionStrategy,\n isValidLogLevel,\n isValidModel,\n isValidProvider,\n isValidRerankerProvider,\n isValidScope,\n} from \"./validators.js\";\n\nexport { isValidModel } from \"./validators.js\";\n\nexport type IndexScope = \"project\" | \"global\";\n\nexport interface IndexingConfig {\n autoIndex: boolean;\n /** Maximum time retrieval tools wait for first-use auto-indexing. */\n autoIndexWaitMs: number;\n /** Maximum transient interprocess lock retries for auto-indexing. */\n autoIndexMaxRetries: number;\n /** Initial exponential retry delay after transient lock contention. */\n autoIndexRetryDelayMs: number;\n watchFiles: boolean;\n /**\n * On macOS, defer automatic indexing while the computer is using battery power.\n * Manual index requests are never blocked. Default: false\n */\n pauseBackgroundIndexingOnBattery: boolean;\n maxFileSize: number;\n maxChunksPerFile: number;\n semanticOnly: boolean;\n retries: number;\n retryDelayMs: number;\n autoGc: boolean;\n gcIntervalDays: number;\n gcOrphanThreshold: number;\n /**\n * When true (default), requires a project marker (.git, package.json, Cargo.toml, etc.)\n * to be present before enabling file watching and auto-indexing.\n */\n requireProjectMarker: boolean;\n /**\n * Max directory traversal depth. -1 = unlimited, 0 = only files in the root dir,\n * 1 = one level of subdirectories, etc. Default: 5\n */\n maxDepth: number;\n /**\n * Max number of files to index per directory. Always picks the smallest files first.\n * Default: 100\n */\n maxFilesPerDirectory: number;\n /**\n * When a file hits maxChunksPerFile, fallback to text-based (chunk_by_lines) parsing\n * instead of skipping the rest of the file. Default: true\n */\n fallbackToTextOnMaxChunks: boolean;\n /**\n * Max lines per chunk for line-based parsing (.jsonl, .txt, unknown extensions,\n * and the AST fallback path). Each chunk is a sliding window of this many lines.\n * Default: 30. Lower it for finer-grained retrieval on line-delimited files (for\n * example Claude .jsonl session transcripts, where one line is one message). The\n * overlap between neighboring chunks is auto-capped at one quarter of this value,\n * so smaller windows shrink the overlap too. Only the line-based path is affected;\n * AST-parsed languages are unchanged.\n */\n linesPerChunk: number;\n gitBlame: {\n enabled: boolean;\n };\n}\n\nexport interface SearchConfig {\n maxResults: number;\n minScore: number;\n includeContext: boolean;\n hybridWeight: number;\n fusionStrategy: \"weighted\" | \"rrf\";\n rrfK: number;\n rerankTopN: number;\n contextLines: number;\n routingHints: boolean;\n routingGraphHandoffHints: boolean;\n routingHintRole: \"system\" | \"developer\";\n /** Multiplicative boost for candidates in an exact query symbol's call-graph community. Default: 0 (disabled). */\n communityBoost: number;\n}\n\nexport type RerankerProvider = \"cohere\" | \"jina\" | \"custom\";\n\nexport interface RerankerConfig {\n /** Whether to enable reranking. Default: false */\n enabled: boolean;\n /** Provider shortcut for hosted rerank APIs. Use 'custom' to provide only baseUrl. */\n provider: RerankerProvider;\n /** Model name for reranking */\n model: string;\n /** Base URL of the rerank API endpoint */\n baseUrl: string;\n /** API key for the rerank service */\n apiKey?: string;\n /** Number of top documents to rerank */\n topN: number;\n /** Request timeout in milliseconds */\n timeoutMs: number;\n}\n\nexport type LogLevel = \"error\" | \"warn\" | \"info\" | \"debug\";\n\nexport interface DebugConfig {\n enabled: boolean;\n logLevel: LogLevel;\n logSearch: boolean;\n logEmbedding: boolean;\n logCache: boolean;\n logGc: boolean;\n logBranch: boolean;\n metrics: boolean;\n /** @deprecated Ignored. Use top-level effectivenessMetrics.enabled. */\n effectivenessMetrics?: boolean;\n}\n\nexport interface EffectivenessMetricsConfig {\n /** Opt in to process-lifetime, memory-only repository tool aggregates. */\n enabled: boolean;\n}\n\nexport interface CustomProviderConfig {\n /** Base URL of the OpenAI-compatible embeddings API. The path /embeddings is appended automatically (e.g. \"http://localhost:11434/v1\", \"https://api.example.com/v1\") */\n baseUrl: string;\n /** Model name to send in the API request (e.g. \"nomic-embed-text\") */\n model: string;\n /** Vector dimensions the model produces (e.g. 768 for nomic-embed-text) */\n dimensions: number;\n /** Optional API key for authenticated endpoints */\n apiKey?: string;\n /** Max tokens per input text (default: 8192) */\n maxTokens?: number;\n /** Request timeout in milliseconds (default: 30000) */\n timeoutMs?: number;\n /** Max concurrent embedding requests (default: 3). Increase for local servers like llama.cpp or vLLM. */\n concurrency?: number;\n /** Minimum delay between requests in milliseconds (default: 1000). Set to 0 for local servers. */\n requestIntervalMs?: number;\n maxBatchSize?: number;\n max_batch_size?: number;\n}\n\nexport interface EmbeddingBatchConfig {\n /** Max texts per embedding request. Default: provider-specific (ollama 16). */\n maxBatchItems?: number;\n /** Max total input tokens per embedding request. This is a request size/time guard,\n * not a model context limit: ollama encodes each input independently, so the per-batch\n * token sum is not bounded by the model context length. Default: provider-specific (ollama 65536).\n * Raise together with maxBatchItems to pack more texts per request; lower it if a single\n * request approaches the request timeout. */\n maxBatchTokens?: number;\n}\n\nexport interface EmbeddingConfig {\n /** Embedding request batching options. Currently applied to the ollama provider. */\n batch?: EmbeddingBatchConfig;\n}\n\nexport interface CodebaseIndexConfig {\n embeddingProvider: EmbeddingProvider | 'custom' | 'auto';\n embeddingModel?: EmbeddingModelName;\n /** Configuration for custom OpenAI-compatible embedding providers (required when embeddingProvider is 'custom') */\n customProvider?: CustomProviderConfig;\n /** Embedding request shape options (e.g. batch sizes). Currently applied to the ollama provider. */\n embedding?: EmbeddingConfig;\n scope: IndexScope;\n indexing?: Partial<IndexingConfig>;\n search?: Partial<SearchConfig>;\n debug?: Partial<DebugConfig>;\n /** Privacy-safe effectiveness aggregation, independent from debug logging. */\n effectivenessMetrics?: Partial<EffectivenessMetricsConfig>;\n /** Reranking configuration for improving search result quality */\n reranker?: Partial<RerankerConfig>;\n /** External directories to index as knowledge bases (absolute or relative paths) */\n knowledgeBases?: string[];\n /** Override the default include patterns (replaces defaults) */\n include: string[];\n /** Override the default exclude patterns (replaces defaults) */\n exclude: string[];\n /** Additional file patterns to include (extends defaults) */\n additionalInclude?: string[];\n}\n\nexport type ParsedCodebaseIndexConfig = CodebaseIndexConfig & {\n indexing: IndexingConfig;\n search: SearchConfig;\n debug: DebugConfig;\n effectivenessMetrics: EffectivenessMetricsConfig;\n reranker?: RerankerConfig;\n knowledgeBases: string[];\n additionalInclude: string[];\n embedding: EmbeddingConfig;\n};\n\nexport function parseConfig(raw: unknown): ParsedCodebaseIndexConfig {\n const input = (raw && typeof raw === \"object\" ? raw : {}) as Record<string, unknown>;\n const embeddingProviderValue = getResolvedString(input.embeddingProvider, \"$root.embeddingProvider\");\n const scopeValue = getResolvedString(input.scope, \"$root.scope\");\n const includeValue = getResolvedStringArray(input.include, \"$root.include\");\n const excludeValue = getResolvedStringArray(input.exclude, \"$root.exclude\");\n\n const defaultIndexing = getDefaultIndexingConfig();\n const defaultSearch = getDefaultSearchConfig();\n const defaultDebug = getDefaultDebugConfig();\n\n const rawIndexing = (input.indexing && typeof input.indexing === \"object\" ? input.indexing : {}) as Record<string, unknown>;\n const indexing: IndexingConfig = {\n autoIndex: typeof rawIndexing.autoIndex === \"boolean\" ? rawIndexing.autoIndex : defaultIndexing.autoIndex,\n autoIndexWaitMs: typeof rawIndexing.autoIndexWaitMs === \"number\"\n ? Math.min(60_000, Math.max(0, Math.floor(rawIndexing.autoIndexWaitMs)))\n : defaultIndexing.autoIndexWaitMs,\n autoIndexMaxRetries: typeof rawIndexing.autoIndexMaxRetries === \"number\"\n ? Math.min(10, Math.max(0, Math.floor(rawIndexing.autoIndexMaxRetries)))\n : defaultIndexing.autoIndexMaxRetries,\n autoIndexRetryDelayMs: typeof rawIndexing.autoIndexRetryDelayMs === \"number\"\n ? Math.min(10_000, Math.max(10, Math.floor(rawIndexing.autoIndexRetryDelayMs)))\n : defaultIndexing.autoIndexRetryDelayMs,\n watchFiles: typeof rawIndexing.watchFiles === \"boolean\" ? rawIndexing.watchFiles : defaultIndexing.watchFiles,\n pauseBackgroundIndexingOnBattery: typeof rawIndexing.pauseBackgroundIndexingOnBattery === \"boolean\"\n ? rawIndexing.pauseBackgroundIndexingOnBattery\n : defaultIndexing.pauseBackgroundIndexingOnBattery,\n maxFileSize: typeof rawIndexing.maxFileSize === \"number\" ? rawIndexing.maxFileSize : defaultIndexing.maxFileSize,\n maxChunksPerFile: typeof rawIndexing.maxChunksPerFile === \"number\" ? Math.max(1, rawIndexing.maxChunksPerFile) : defaultIndexing.maxChunksPerFile,\n semanticOnly: typeof rawIndexing.semanticOnly === \"boolean\" ? rawIndexing.semanticOnly : defaultIndexing.semanticOnly,\n retries: typeof rawIndexing.retries === \"number\" ? rawIndexing.retries : defaultIndexing.retries,\n retryDelayMs: typeof rawIndexing.retryDelayMs === \"number\" ? rawIndexing.retryDelayMs : defaultIndexing.retryDelayMs,\n autoGc: typeof rawIndexing.autoGc === \"boolean\" ? rawIndexing.autoGc : defaultIndexing.autoGc,\n gcIntervalDays: typeof rawIndexing.gcIntervalDays === \"number\" ? Math.max(1, rawIndexing.gcIntervalDays) : defaultIndexing.gcIntervalDays,\n gcOrphanThreshold: typeof rawIndexing.gcOrphanThreshold === \"number\" ? Math.max(0, rawIndexing.gcOrphanThreshold) : defaultIndexing.gcOrphanThreshold,\n requireProjectMarker: typeof rawIndexing.requireProjectMarker === \"boolean\" ? rawIndexing.requireProjectMarker : defaultIndexing.requireProjectMarker,\n maxDepth: typeof rawIndexing.maxDepth === \"number\" ? (rawIndexing.maxDepth < -1 ? -1 : rawIndexing.maxDepth) : defaultIndexing.maxDepth,\n maxFilesPerDirectory: typeof rawIndexing.maxFilesPerDirectory === \"number\" ? Math.max(1, rawIndexing.maxFilesPerDirectory) : defaultIndexing.maxFilesPerDirectory,\n fallbackToTextOnMaxChunks: typeof rawIndexing.fallbackToTextOnMaxChunks === \"boolean\" ? rawIndexing.fallbackToTextOnMaxChunks : defaultIndexing.fallbackToTextOnMaxChunks,\n linesPerChunk: typeof rawIndexing.linesPerChunk === \"number\" && Number.isFinite(rawIndexing.linesPerChunk) ? Math.min(Math.max(1, Math.floor(rawIndexing.linesPerChunk)), 4294967295) : defaultIndexing.linesPerChunk,\n gitBlame: {\n enabled: rawIndexing.gitBlame && typeof rawIndexing.gitBlame === \"object\" && typeof (rawIndexing.gitBlame as Record<string, unknown>).enabled === \"boolean\"\n ? (rawIndexing.gitBlame as { enabled: boolean }).enabled\n : defaultIndexing.gitBlame.enabled,\n },\n };\n\n const rawSearch = (input.search && typeof input.search === \"object\" ? input.search : {}) as Record<string, unknown>;\n const search: SearchConfig = {\n maxResults: typeof rawSearch.maxResults === \"number\" ? rawSearch.maxResults : defaultSearch.maxResults,\n minScore: typeof rawSearch.minScore === \"number\" ? rawSearch.minScore : defaultSearch.minScore,\n includeContext: typeof rawSearch.includeContext === \"boolean\" ? rawSearch.includeContext : defaultSearch.includeContext,\n hybridWeight: typeof rawSearch.hybridWeight === \"number\" ? Math.min(1, Math.max(0, rawSearch.hybridWeight)) : defaultSearch.hybridWeight,\n fusionStrategy: isValidFusionStrategy(rawSearch.fusionStrategy) ? rawSearch.fusionStrategy : defaultSearch.fusionStrategy,\n rrfK: typeof rawSearch.rrfK === \"number\" ? Math.max(1, Math.floor(rawSearch.rrfK)) : defaultSearch.rrfK,\n rerankTopN: typeof rawSearch.rerankTopN === \"number\" ? Math.min(200, Math.max(0, Math.floor(rawSearch.rerankTopN))) : defaultSearch.rerankTopN,\n contextLines: typeof rawSearch.contextLines === \"number\" ? Math.min(50, Math.max(0, rawSearch.contextLines)) : defaultSearch.contextLines,\n routingHints: typeof rawSearch.routingHints === \"boolean\" ? rawSearch.routingHints : defaultSearch.routingHints,\n routingGraphHandoffHints: typeof rawSearch.routingGraphHandoffHints === \"boolean\" ? rawSearch.routingGraphHandoffHints : defaultSearch.routingGraphHandoffHints,\n routingHintRole: rawSearch.routingHintRole === \"developer\" || rawSearch.routingHintRole === \"system\"\n ? rawSearch.routingHintRole\n : defaultSearch.routingHintRole,\n communityBoost: typeof rawSearch.communityBoost === \"number\" && Number.isFinite(rawSearch.communityBoost)\n ? Math.min(1, Math.max(0, rawSearch.communityBoost))\n : defaultSearch.communityBoost,\n };\n\n const rawDebug = (input.debug && typeof input.debug === \"object\" ? input.debug : {}) as Record<string, unknown>;\n const debug: DebugConfig = {\n enabled: typeof rawDebug.enabled === \"boolean\" ? rawDebug.enabled : defaultDebug.enabled,\n logLevel: isValidLogLevel(rawDebug.logLevel) ? rawDebug.logLevel : defaultDebug.logLevel,\n logSearch: typeof rawDebug.logSearch === \"boolean\" ? rawDebug.logSearch : defaultDebug.logSearch,\n logEmbedding: typeof rawDebug.logEmbedding === \"boolean\" ? rawDebug.logEmbedding : defaultDebug.logEmbedding,\n logCache: typeof rawDebug.logCache === \"boolean\" ? rawDebug.logCache : defaultDebug.logCache,\n logGc: typeof rawDebug.logGc === \"boolean\" ? rawDebug.logGc : defaultDebug.logGc,\n logBranch: typeof rawDebug.logBranch === \"boolean\" ? rawDebug.logBranch : defaultDebug.logBranch,\n metrics: typeof rawDebug.metrics === \"boolean\" ? rawDebug.metrics : defaultDebug.metrics,\n };\n\n const rawEffectivenessMetrics = (\n input.effectivenessMetrics && typeof input.effectivenessMetrics === \"object\"\n ? input.effectivenessMetrics\n : {}\n ) as Record<string, unknown>;\n const effectivenessMetrics: EffectivenessMetricsConfig = {\n enabled: rawEffectivenessMetrics.enabled === true,\n };\n\n const rawKnowledgeBases = input.knowledgeBases;\n const knowledgeBases: string[] = isStringArray(rawKnowledgeBases)\n ? rawKnowledgeBases.filter(p => typeof p === \"string\" && p.trim().length > 0).map(p => p.trim())\n : [];\n\n const rawAdditionalInclude = input.additionalInclude;\n const additionalInclude: string[] = isStringArray(rawAdditionalInclude)\n ? rawAdditionalInclude\n .filter(p => typeof p === \"string\" && p.trim().length > 0)\n .map(p => p.trim())\n : [];\n\n let embeddingProvider: EmbeddingProvider | 'custom' | 'auto';\n let embeddingModel: EmbeddingModelName | undefined;\n let customProvider: CustomProviderConfig | undefined;\n let reranker: RerankerConfig | undefined;\n\n const githubCopilotDeprecationMessage =\n \"`embeddingProvider: \\\"github-copilot\\\"` is deprecated and no longer available. \" +\n \"Migrate existing configs to `embeddingProvider: \\\"google\\\"` and select an explicit Google model. \" +\n \"For existing indexes, run `index_codebase` with `force: true` after changing to `gemini-embedding-001` \" +\n \"or `gemini-embedding-2` to rebuild embeddings. See docs/configuration.md for details.\";\n\n if (embeddingProviderValue === 'custom') {\n embeddingProvider = 'custom';\n const rawCustom = (input.customProvider && typeof input.customProvider === 'object' ? input.customProvider : null) as Record<string, unknown> | null;\n const baseUrlValue = getResolvedString(rawCustom?.baseUrl, \"$root.customProvider.baseUrl\");\n const modelValue = getResolvedString(rawCustom?.model, \"$root.customProvider.model\");\n const apiKeyValue = getResolvedString(rawCustom?.apiKey, \"$root.customProvider.apiKey\");\n if (rawCustom && typeof baseUrlValue === 'string' && baseUrlValue.trim().length > 0 && typeof modelValue === 'string' && modelValue.trim().length > 0 && typeof rawCustom.dimensions === 'number' && Number.isInteger(rawCustom.dimensions) && rawCustom.dimensions > 0) {\n customProvider = {\n baseUrl: baseUrlValue.trim().replace(/\\/+$/, ''),\n model: modelValue,\n dimensions: rawCustom.dimensions,\n apiKey: apiKeyValue,\n maxTokens: typeof rawCustom.maxTokens === 'number' ? rawCustom.maxTokens : undefined,\n timeoutMs: typeof rawCustom.timeoutMs === 'number' ? Math.max(1000, rawCustom.timeoutMs) : undefined,\n concurrency: typeof rawCustom.concurrency === 'number' ? Math.max(1, Math.floor(rawCustom.concurrency)) : undefined,\n requestIntervalMs: typeof rawCustom.requestIntervalMs === 'number' ? Math.max(0, Math.floor(rawCustom.requestIntervalMs)) : undefined,\n maxBatchSize: typeof rawCustom.maxBatchSize === 'number'\n ? Math.max(1, Math.floor(rawCustom.maxBatchSize))\n : typeof rawCustom.max_batch_size === 'number'\n ? Math.max(1, Math.floor(rawCustom.max_batch_size))\n : undefined,\n };\n // Warn if baseUrl doesn't end with an API version path like /v1.\n // Note: using console.warn here because Logger isn't initialized yet at config parse time.\n if (!/\\/v\\d+\\/?$/.test(customProvider.baseUrl)) {\n console.warn(\n `[codebase-index] Warning: customProvider.baseUrl (\"${customProvider.baseUrl}\") does not end with an API version path like /v1. ` +\n `The plugin appends /embeddings automatically, so the full URL will be \"${customProvider.baseUrl}/embeddings\". ` +\n `If your provider expects /v1/embeddings, set baseUrl to \"${customProvider.baseUrl}/v1\".`\n );\n }\n } else {\n throw new Error(\n \"embeddingProvider is 'custom' but customProvider config is missing or invalid. \" +\n \"Required fields: baseUrl (string), model (string), dimensions (positive integer).\"\n );\n }\n } else if (isValidProvider(embeddingProviderValue)) {\n embeddingProvider = embeddingProviderValue;\n const rawEmbeddingModel = input.embeddingModel;\n if (typeof rawEmbeddingModel === \"string\") {\n const embeddingModelValue = getResolvedString(rawEmbeddingModel, \"$root.embeddingModel\");\n if (embeddingModelValue) {\n embeddingModel = isValidModel(embeddingModelValue, embeddingProvider) ? embeddingModelValue : DEFAULT_PROVIDER_MODELS[embeddingProvider];\n }\n } else if (rawEmbeddingModel) {\n embeddingModel = DEFAULT_PROVIDER_MODELS[embeddingProvider];\n }\n } else if (embeddingProviderValue === 'github-copilot') {\n throw new Error(githubCopilotDeprecationMessage);\n } else {\n embeddingProvider = 'auto';\n }\n\n const rawReranker = (input.reranker && typeof input.reranker === \"object\"\n ? input.reranker\n : {}) as Record<string, unknown>;\n const rerankerEnabled = typeof rawReranker.enabled === \"boolean\" ? rawReranker.enabled : false;\n if (rerankerEnabled) {\n const provider = isValidRerankerProvider(rawReranker.provider) ? rawReranker.provider : \"custom\";\n const model = getResolvedString(rawReranker.model, \"$root.reranker.model\");\n if (!model || model.trim().length === 0) {\n throw new Error(\"reranker is enabled but reranker.model is missing or invalid.\");\n }\n\n const configuredBaseUrl = getResolvedString(rawReranker.baseUrl, \"$root.reranker.baseUrl\");\n const baseUrl = configuredBaseUrl?.trim() || getDefaultRerankerBaseUrl(provider);\n if (baseUrl.length === 0) {\n throw new Error(\"reranker is enabled but reranker.baseUrl is missing or invalid for provider 'custom'.\");\n }\n\n const apiKey = getResolvedString(rawReranker.apiKey, \"$root.reranker.apiKey\");\n if ((provider === \"cohere\" || provider === \"jina\") && (!apiKey || apiKey.trim().length === 0)) {\n throw new Error(`reranker provider '${provider}' requires reranker.apiKey when enabled.`);\n }\n\n reranker = {\n enabled: true,\n provider,\n model: model.trim(),\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n apiKey: apiKey?.trim() || undefined,\n topN: typeof rawReranker.topN === \"number\" ? Math.min(50, Math.max(1, Math.floor(rawReranker.topN))) : 15,\n timeoutMs: typeof rawReranker.timeoutMs === \"number\" ? Math.max(1000, Math.floor(rawReranker.timeoutMs)) : 10000,\n };\n }\n\n const rawEmbedding = (input.embedding && typeof input.embedding === \"object\" ? input.embedding : {}) as Record<string, unknown>;\n const rawEmbeddingBatch = (rawEmbedding.batch && typeof rawEmbedding.batch === \"object\" ? rawEmbedding.batch : null) as Record<string, unknown> | null;\n const embeddingMaxBatchItems = typeof rawEmbeddingBatch?.maxBatchItems === \"number\"\n && Number.isFinite(rawEmbeddingBatch.maxBatchItems)\n ? Math.max(1, Math.floor(rawEmbeddingBatch.maxBatchItems))\n : undefined;\n const embeddingMaxBatchTokens = typeof rawEmbeddingBatch?.maxBatchTokens === \"number\"\n && Number.isFinite(rawEmbeddingBatch.maxBatchTokens)\n ? Math.max(1, Math.floor(rawEmbeddingBatch.maxBatchTokens))\n : undefined;\n const embedding: EmbeddingConfig = (embeddingMaxBatchItems !== undefined || embeddingMaxBatchTokens !== undefined)\n ? {\n batch: {\n ...(embeddingMaxBatchItems !== undefined ? { maxBatchItems: embeddingMaxBatchItems } : {}),\n ...(embeddingMaxBatchTokens !== undefined ? { maxBatchTokens: embeddingMaxBatchTokens } : {}),\n },\n }\n : {};\n\n return {\n embeddingProvider,\n embeddingModel,\n customProvider,\n embedding,\n scope: isValidScope(scopeValue) ? scopeValue : \"project\",\n include: includeValue ?? DEFAULT_INCLUDE,\n exclude: excludeValue ?? DEFAULT_EXCLUDE,\n additionalInclude,\n indexing,\n search,\n debug,\n effectivenessMetrics,\n reranker,\n knowledgeBases,\n };\n}\n\nexport function getDefaultModelForProvider(provider: EmbeddingProvider): EmbeddingModelInfo {\n const models = EMBEDDING_MODELS[provider];\n const providerDefault = DEFAULT_PROVIDER_MODELS[provider];\n return models[providerDefault as keyof typeof models];\n}\n\n/**\n * Built-in embedding providers derived from the static EMBEDDING_MODELS catalog.\n * 'custom' is intentionally excluded from this union because it has no static model\n * catalog — its model/dimensions/config are entirely user-defined at runtime via\n * CustomProviderConfig. Code that handles all providers uses `EmbeddingProvider | 'custom'`.\n */\nexport type EmbeddingProvider = keyof typeof EMBEDDING_MODELS;\n\nexport const availableProviders: EmbeddingProvider[] = Object.keys(EMBEDDING_MODELS) as EmbeddingProvider[];\n\nexport const autoDetectProviders: EmbeddingProvider[] = AUTO_DETECT_PROVIDER_ORDER.filter(\n (provider): provider is EmbeddingProvider => provider in EMBEDDING_MODELS,\n);\n\nexport type ProviderModels = {\n [P in keyof typeof EMBEDDING_MODELS]: P extends \"ollama\"\n ? string\n : keyof (typeof EMBEDDING_MODELS)[P]\n}\n\nexport type EmbeddingModelName = ProviderModels[keyof ProviderModels];\n\n/** Shared fields across all embedding model types (built-in and custom) */\nexport interface BaseModelInfo {\n model: string;\n dimensions: number;\n maxTokens: number;\n costPer1MTokens: number;\n}\n\nexport interface GoogleEmbeddingModelInfo extends BaseModelInfo {\n provider: \"google\";\n taskAble: boolean;\n promptStyle?: \"embedding-2\";\n}\n\nexport type EmbeddingProviderModelInfo = {\n [P in EmbeddingProvider]: P extends \"ollama\"\n ? BaseModelInfo & { provider: \"ollama\" }\n : P extends \"google\"\n ? GoogleEmbeddingModelInfo\n : (typeof EMBEDDING_MODELS)[P][keyof (typeof EMBEDDING_MODELS)[P]]\n}\n\nexport type EmbeddingModelInfo = EmbeddingProviderModelInfo[EmbeddingProvider];\n","import { existsSync, realpathSync, statSync } from \"fs\";\nimport * as path from \"path\";\nimport { parseConfig } from \"../config/schema.js\";\nimport { getHostProjectConfigRelativePath } from \"../config/paths.js\";\nimport type { HostMode } from \"../config/host.js\";\nimport type { CallEdgeData, PathHopData, SymbolData } from \"../native/index.js\";\nimport { Indexer } from \"../indexer/index.js\";\nimport { findKnowledgeBasePathIndex, hasMatchingKnowledgeBasePath, resolveKnowledgeBasePath } from \"./knowledge-base-paths.js\";\nimport { buildCodeCommunitiesResult } from \"./format-communities.js\";\nimport {\n CODE_COMMUNITIES_DEFAULT_COUPLING_LIMIT,\n CODE_COMMUNITIES_DEFAULT_HUB_THRESHOLD,\n CODE_COMMUNITIES_DEFAULT_LIMIT,\n CODE_COMMUNITIES_MAX_COUPLING_LIMIT,\n CODE_COMMUNITIES_MAX_LIMIT,\n CODE_COMMUNITIES_MIN_COUPLING,\n CODE_COMMUNITIES_MIN_SIZE,\n} from \"./contracts.js\";\nimport type { SharedCodeCommunitiesArgs } from \"./contracts.js\";\nimport { calculatePercentage, formatProgressTitle, formatStatus } from \"./utils.js\";\nimport type { LogLevel } from \"../config/schema.js\";\nimport type { LogEntry } from \"../utils/logger.js\";\nimport type { CostEstimate, DryRunEstimate } from \"../utils/cost.js\";\nimport type { AutoIndexStatusSnapshot } from \"../utils/auto-index.js\";\nimport type { SearchTrace } from \"../indexer/index.js\";\nimport {\n formatEffectivenessMetrics,\n getProcessEffectivenessMetrics,\n resetProcessEffectivenessMetrics,\n} from \"../utils/effectiveness-metrics.js\";\nimport {\n getAutoIndexStatus,\n runCoordinatedIndex,\n} from \"../utils/auto-index.js\";\nimport { getConfigPath, loadEditableConfig, loadRuntimeConfig, saveConfig } from \"./config-state.js\";\nimport {\n AutoIndexRetrievalUnavailableError,\n ensureAutoIndexReadyForRetrieval,\n configCache,\n getIndexBusyResult,\n getIndexerCacheKey,\n getIndexerForProject,\n indexerCache,\n getProjectRoot,\n getSharedIndexer,\n initializeTools,\n isToolEffectivenessEnabled,\n rawEffectivenessMetricsEnabled,\n recordToolEffectiveness,\n refreshIndexerForDirectory,\n safelyCountReturnedTokens,\n safelyRecordToolEffectiveness,\n type IndexBusyResult,\n} from \"./operation-runtime.js\";\n\n\ntype SearchResult = Awaited<ReturnType<Indexer[\"search\"]>>[number];\ntype IndexStats = Awaited<ReturnType<Indexer[\"index\"]>>;\ntype StatusResult = Awaited<ReturnType<Indexer[\"getStatus\"]>>;\nexport type IndexStatusResult = StatusResult & { autoIndex: AutoIndexStatusSnapshot };\ntype HealthCheckResult = Awaited<ReturnType<Indexer[\"healthCheck\"]>>;\ntype PrImpactResult = Awaited<ReturnType<Indexer[\"getPrImpact\"]>>;\ntype IndexMessageResult = { kind: \"message\"; text: string };\n\ntype ProgressCb = (title: string, metadata: Record<string, unknown>) => void | Promise<void>;\nconst MAX_CALL_GRAPH_CANDIDATES = 5;\n\nexport interface CallGraphSymbolCandidate {\n filePath: string;\n startLine: number;\n kind: string;\n}\n\nexport type CallGraphSymbolResolution =\n | {\n status: \"resolved\";\n name: string;\n symbolId: string;\n filePath: string;\n startLine: number;\n kind: string;\n matchedBy: \"name\" | \"symbolId\";\n }\n | {\n status: \"ambiguous\" | \"not_found\";\n name: string;\n filePath?: string;\n candidates: CallGraphSymbolCandidate[];\n totalCandidates: number;\n invalidSymbolId?: boolean;\n };\n\nexport interface CallGraphDataResult {\n direction: \"callers\" | \"callees\";\n resolution: CallGraphSymbolResolution;\n callers: CallEdgeData[];\n callees: CallEdgeData[];\n relationshipType?: string;\n}\n\nexport interface CallGraphPathResult {\n from: CallGraphSymbolResolution;\n to: CallGraphSymbolResolution;\n path: PathHopData[];\n}\n\nfunction trimOrUndefined(value: string | undefined): string | undefined {\n const normalized = value?.trim();\n return normalized || undefined;\n}\n\nfunction normalizeCallGraphPath(value: string): string {\n let normalized = path.posix.normalize(value.trim().replaceAll(\"\\\\\", \"/\"));\n if (normalized.startsWith(\"./\")) {\n normalized = normalized.slice(2);\n }\n while (normalized.length > 1 && normalized.endsWith(\"/\")) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n\nfunction isAbsoluteCallGraphPath(value: string): boolean {\n return value.startsWith(\"/\") || /^[A-Za-z]:\\//.test(value);\n}\n\nfunction filePathMatches(candidatePath: string, requestedPath: string): boolean {\n const candidate = normalizeCallGraphPath(candidatePath);\n const requested = normalizeCallGraphPath(requestedPath);\n if (isAbsoluteCallGraphPath(requested)) {\n return candidate === requested;\n }\n return candidate === requested || candidate.endsWith(`/${requested}`);\n}\n\nfunction displayCallGraphPath(filePath: string, projectRoot: string): string {\n const normalizedFilePath = normalizeCallGraphPath(filePath);\n const normalizedRoot = normalizeCallGraphPath(projectRoot);\n if (normalizedFilePath === normalizedRoot) return \".\";\n if (normalizedFilePath.startsWith(`${normalizedRoot}/`)) {\n return normalizedFilePath.slice(normalizedRoot.length + 1);\n }\n return normalizedFilePath;\n}\n\nfunction symbolNameMatches(symbol: SymbolData, requestedName: string): boolean {\n return symbol.language === \"apex\" || symbol.language === \"php\"\n ? symbol.name.toLowerCase() === requestedName.toLowerCase()\n : symbol.name === requestedName;\n}\n\nfunction toCandidate(symbol: SymbolData, projectRoot: string): CallGraphSymbolCandidate {\n return {\n filePath: displayCallGraphPath(symbol.filePath, projectRoot),\n startLine: symbol.startLine,\n kind: symbol.kind,\n };\n}\n\nfunction resolvedSymbol(symbol: SymbolData, projectRoot: string, matchedBy: \"name\" | \"symbolId\"): CallGraphSymbolResolution {\n return {\n status: \"resolved\",\n name: symbol.name,\n symbolId: symbol.id,\n filePath: displayCallGraphPath(symbol.filePath, projectRoot),\n startLine: symbol.startLine,\n kind: symbol.kind,\n matchedBy,\n };\n}\n\nfunction resolveCallGraphSymbol(\n symbols: SymbolData[],\n projectRoot: string,\n requestedName: string,\n requestedFilePath?: string,\n requestedSymbolId?: string,\n): CallGraphSymbolResolution {\n const name = requestedName.trim();\n const filePath = trimOrUndefined(requestedFilePath);\n const symbolId = trimOrUndefined(requestedSymbolId);\n\n if (symbolId) {\n const symbol = symbols.find((candidate) => candidate.id === symbolId);\n if (symbol) {\n return resolvedSymbol(symbol, projectRoot, \"symbolId\");\n }\n return {\n status: \"not_found\",\n name,\n filePath,\n candidates: [],\n totalCandidates: 0,\n invalidSymbolId: true,\n };\n }\n\n const nameCandidates = symbols.filter((symbol) => symbolNameMatches(symbol, name));\n const matchingCandidates = filePath\n ? nameCandidates.filter((symbol) => filePathMatches(symbol.filePath, filePath))\n : nameCandidates;\n\n if (matchingCandidates.length === 1) {\n return resolvedSymbol(matchingCandidates[0], projectRoot, \"name\");\n }\n\n const candidates = (matchingCandidates.length > 0 ? matchingCandidates : nameCandidates)\n .sort((left, right) => left.filePath.localeCompare(right.filePath) || left.startLine - right.startLine);\n return {\n status: matchingCandidates.length > 1 ? \"ambiguous\" : \"not_found\",\n name,\n filePath: filePath ? normalizeCallGraphPath(filePath) : undefined,\n candidates: candidates.slice(0, MAX_CALL_GRAPH_CANDIDATES).map((symbol) => toCandidate(symbol, projectRoot)),\n totalCandidates: candidates.length,\n };\n}\n\n\n\nexport async function searchCodebase(\n projectRoot: string | undefined,\n host: HostMode,\n query: string,\n options: {\n limit?: number;\n fileType?: string;\n directory?: string;\n chunkType?: string;\n contextLines?: number;\n metadataOnly?: boolean;\n definitionIntent?: boolean;\n prioritizeSourcePaths?: boolean;\n blameAuthor?: string;\n blameSha?: string;\n blameSince?: string;\n blameUntil?: string;\n trace?: (trace: SearchTrace) => void;\n } = {},\n): Promise<SearchResult[]> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const indexer = getIndexerForProject(projectRoot, host);\n return indexer.search(query, options.limit, {\n fileType: options.fileType,\n directory: options.directory,\n chunkType: options.chunkType,\n contextLines: options.contextLines,\n metadataOnly: options.metadataOnly,\n definitionIntent: options.definitionIntent,\n prioritizeSourcePaths: options.prioritizeSourcePaths,\n blameAuthor: options.blameAuthor,\n blameSha: options.blameSha,\n blameSince: options.blameSince,\n blameUntil: options.blameUntil,\n trace: options.trace,\n });\n}\n\nexport async function searchCodebaseWithEffectiveness<T>(\n projectRoot: string | undefined,\n host: HostMode,\n route: \"peek\" | \"search\",\n query: string,\n options: Parameters<typeof searchCodebase>[3],\n render: (results: SearchResult[]) => { output: T; text: string },\n): Promise<T> {\n const metricsEnabled = isToolEffectivenessEnabled(projectRoot, host);\n const startedAt = metricsEnabled ? performance.now() : 0;\n try {\n const results = await searchCodebase(projectRoot, host, query, options);\n const rendered = render(results);\n if (metricsEnabled) {\n safelyRecordToolEffectiveness({\n route,\n host,\n outcome: results.length > 0 ? \"success\" : \"no-result\",\n resultCount: results.length,\n latencyMs: performance.now() - startedAt,\n returnedTokenEstimate: safelyCountReturnedTokens(rendered.text),\n exactHandoffEmitted: rendered.text.includes(\"Exact-search handoff:\"),\n scopeRelaxation: \"none\",\n });\n }\n return rendered.output;\n } catch (error) {\n if (metricsEnabled) {\n safelyRecordToolEffectiveness({\n route,\n host,\n outcome: \"error\",\n resultCount: 0,\n latencyMs: performance.now() - startedAt,\n returnedTokenEstimate: 0,\n exactHandoffEmitted: false,\n scopeRelaxation: \"none\",\n });\n }\n throw error;\n }\n}\n\nexport async function findSimilarCode(\n projectRoot: string | undefined,\n host: HostMode,\n code: string,\n options: {\n limit?: number;\n fileType?: string;\n directory?: string;\n chunkType?: string;\n excludeFile?: string;\n blameSince?: string;\n blameUntil?: string;\n } = {},\n): Promise<Awaited<ReturnType<Indexer[\"findSimilar\"]>>> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const indexer = getIndexerForProject(projectRoot, host);\n return indexer.findSimilar(code, options.limit, {\n fileType: options.fileType,\n directory: options.directory,\n chunkType: options.chunkType,\n excludeFile: options.excludeFile,\n blameSince: options.blameSince,\n blameUntil: options.blameUntil,\n });\n}\n\nexport async function implementationLookup(\n projectRoot: string | undefined,\n host: HostMode,\n query: string,\n options: {\n limit?: number;\n fileType?: string;\n directory?: string;\n trace?: (trace: SearchTrace) => void;\n } = {},\n): Promise<SearchResult[]> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const indexer = getIndexerForProject(projectRoot, host);\n return indexer.search(query, options.limit, {\n fileType: options.fileType,\n directory: options.directory,\n definitionIntent: true,\n trace: options.trace,\n });\n}\n\nexport async function getCallGraphData(\n projectRoot: string | undefined,\n host: HostMode,\n params: {\n name: string;\n direction?: \"callers\" | \"callees\";\n symbolId?: string;\n filePath?: string;\n relationshipType?: \"Call\" | \"MethodCall\" | \"Constructor\" | \"Import\" | \"Inherits\" | \"Implements\";\n },\n): Promise<CallGraphDataResult> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const root = getProjectRoot(projectRoot, host);\n const indexer = getIndexerForProject(root, host);\n return getCallGraphDataForIndexer(indexer, root, params);\n}\n\nexport async function getCallGraphDataForIndexer(\n indexer: Indexer,\n projectRoot: string,\n params: {\n name: string;\n direction?: \"callers\" | \"callees\";\n symbolId?: string;\n filePath?: string;\n relationshipType?: \"Call\" | \"MethodCall\" | \"Constructor\" | \"Import\" | \"Inherits\" | \"Implements\";\n },\n): Promise<CallGraphDataResult> {\n const symbols = await indexer.getCallGraphSymbols();\n const resolution = resolveCallGraphSymbol(symbols, projectRoot, params.name, params.filePath, params.symbolId);\n const direction = params.direction === \"callees\" ? \"callees\" : \"callers\";\n if (resolution.status !== \"resolved\") {\n return { direction, resolution, callers: [], callees: [], relationshipType: params.relationshipType };\n }\n\n if (params.direction === \"callees\") {\n const callees = await indexer.getCallees(resolution.symbolId, params.relationshipType);\n return { direction: \"callees\", resolution, callees, callers: [], relationshipType: params.relationshipType };\n }\n\n const includeUnresolved = symbols.filter((symbol) => symbolNameMatches(symbol, resolution.name)).length === 1;\n const callers = await indexer.getCallersForSymbol(\n resolution.symbolId,\n resolution.name,\n includeUnresolved,\n params.relationshipType,\n );\n return { direction: \"callers\", resolution, callers, callees: [], relationshipType: params.relationshipType };\n}\n\nexport async function getCallGraphPath(\n projectRoot: string | undefined,\n host: HostMode,\n from: string,\n to: string,\n maxDepth?: number,\n fromFilePath?: string,\n toFilePath?: string,\n): Promise<CallGraphPathResult> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const root = getProjectRoot(projectRoot, host);\n const indexer = getIndexerForProject(root, host);\n const symbols = await indexer.getCallGraphSymbols();\n const fromResolution = resolveCallGraphSymbol(symbols, root, from, fromFilePath);\n const toResolution = resolveCallGraphSymbol(symbols, root, to, toFilePath);\n if (fromResolution.status !== \"resolved\" || toResolution.status !== \"resolved\") {\n return { from: fromResolution, to: toResolution, path: [] };\n }\n\n const path = await indexer.findCallPathBySymbolIds(\n fromResolution.symbolId,\n toResolution.symbolId,\n maxDepth,\n );\n return { from: fromResolution, to: toResolution, path };\n}\n\nexport async function runIndexCodebase(\n projectRoot: string | undefined,\n host: HostMode,\n args: { force?: boolean; estimateOnly?: boolean; dryRun?: boolean; verbose?: boolean },\n onProgress?: ProgressCb,\n): Promise<\n | { kind: \"estimate\"; estimate: CostEstimate }\n | { kind: \"dryrun\"; dryrun: DryRunEstimate }\n | { kind: \"stats\"; stats: IndexStats }\n | IndexMessageResult\n | IndexBusyResult\n> {\n const root = getProjectRoot(projectRoot, host);\n const indexer = getIndexerForProject(root, host);\n\n try {\n if (args.estimateOnly) {\n return { kind: \"estimate\", estimate: await indexer.estimateCost() };\n }\n\n if (args.dryRun) {\n return { kind: \"dryrun\", dryrun: await indexer.dryRunCost() };\n }\n\n const coordinated = runCoordinatedIndex(root, host, args.force ?? false, (progress) => {\n if (onProgress) {\n void onProgress(formatProgressTitle(progress), {\n phase: progress.phase,\n filesProcessed: progress.filesProcessed,\n totalFiles: progress.totalFiles,\n chunksProcessed: progress.chunksProcessed,\n totalChunks: progress.totalChunks,\n percentage: calculatePercentage(progress),\n });\n }\n });\n if (!coordinated) {\n const operation = args.force ? indexer.forceIndex.bind(indexer) : indexer.index.bind(indexer);\n return { kind: \"stats\", stats: await operation() };\n }\n const result = await coordinated;\n if (result.outcome === \"ready\" && result.stats) {\n return { kind: \"stats\", stats: result.stats };\n }\n if (result.outcome === \"ready\" && result.skipped) {\n return { kind: \"message\", text: \"The existing index is healthy and current; no indexing was needed.\" };\n }\n if (result.outcome === \"stopped\") {\n return { kind: \"message\", text: \"Indexing was stopped or superseded by another coordinated index request. Check index_status and retry if needed.\" };\n }\n if (result.error) throw result.error;\n throw new Error(\"Indexing failed without an error result\");\n } catch (error) {\n const busyResult = getIndexBusyResult(error);\n if (!busyResult) throw error;\n return busyResult;\n }\n}\n\nexport async function getIndexStatus(projectRoot: string | undefined, host: HostMode): Promise<IndexStatusResult> {\n const root = getProjectRoot(projectRoot, host);\n const indexer = getIndexerForProject(root, host);\n return {\n ...await indexer.getStatus(),\n autoIndex: getAutoIndexStatus(root, host),\n };\n}\n\nexport async function getIndexHealthCheck(projectRoot: string | undefined, host: HostMode): Promise<HealthCheckResult> {\n const indexer = getIndexerForProject(projectRoot, host);\n return indexer.healthCheck();\n}\n\nexport async function runIndexHealthCheck(\n projectRoot: string | undefined,\n host: HostMode,\n): Promise<{ kind: \"health\"; health: HealthCheckResult } | IndexBusyResult> {\n try {\n return { kind: \"health\", health: await getIndexHealthCheck(projectRoot, host) };\n } catch (error) {\n const busyResult = getIndexBusyResult(error);\n if (!busyResult) throw error;\n return busyResult;\n }\n}\n\nexport async function getPrImpact(\n projectRoot: string | undefined,\n host: HostMode,\n params: {\n pr?: number;\n branch?: string;\n maxDepth?: number;\n hubThreshold?: number;\n checkConflicts?: boolean;\n direction?: \"callers\" | \"callees\" | \"both\";\n },\n): Promise<PrImpactResult> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const indexer = getIndexerForProject(projectRoot, host);\n return indexer.getPrImpact({\n pr: params.pr,\n branch: params.branch,\n maxDepth: params.maxDepth,\n hubThreshold: params.hubThreshold,\n checkConflicts: params.checkConflicts,\n direction: params.direction,\n });\n}\n\nexport async function getCodeCommunities(\n projectRoot: string | undefined,\n host: HostMode,\n params: SharedCodeCommunitiesArgs,\n): Promise<import(\"./format-communities.js\").CodeCommunitiesResult> {\n await ensureAutoIndexReadyForRetrieval(projectRoot, host);\n const indexer = getIndexerForProject(projectRoot, host);\n const [communities, centrality, couplings] = await Promise.all([\n indexer.detectCommunities(params.branch),\n indexer.computeCentrality(params.branch),\n indexer.detectCommunityCouplings(params.branch),\n ]);\n return buildCodeCommunitiesResult(communities, centrality, couplings, {\n minSize: Math.max(CODE_COMMUNITIES_MIN_SIZE, Math.floor(params.minSize ?? CODE_COMMUNITIES_MIN_SIZE)),\n limit: Math.min(\n CODE_COMMUNITIES_MAX_LIMIT,\n Math.max(1, Math.floor(params.limit ?? CODE_COMMUNITIES_DEFAULT_LIMIT)),\n ),\n hubThreshold: Math.max(\n 0,\n Math.floor(params.hubThreshold ?? CODE_COMMUNITIES_DEFAULT_HUB_THRESHOLD),\n ),\n minCoupling: Math.max(\n CODE_COMMUNITIES_MIN_COUPLING,\n Math.floor(params.minCoupling ?? CODE_COMMUNITIES_MIN_COUPLING),\n ),\n couplingLimit: Math.min(\n CODE_COMMUNITIES_MAX_COUPLING_LIMIT,\n Math.max(1, Math.floor(params.couplingLimit ?? CODE_COMMUNITIES_DEFAULT_COUPLING_LIMIT)),\n ),\n });\n}\n\nexport async function getIndexMetrics(\n projectRoot: string | undefined,\n host: HostMode,\n args: { reset?: boolean } = {},\n): Promise<{ enabled: boolean; metricsEnabled: boolean; effectivenessMetricsEnabled: boolean; text: string }> {\n const root = getProjectRoot(projectRoot, host);\n const key = getIndexerCacheKey(root, host);\n const cachedIndexer = indexerCache.get(key);\n let config = configCache.get(key);\n let rawEffectivenessEnabled = false;\n\n if (args.reset === true) {\n resetProcessEffectivenessMetrics();\n try {\n cachedIndexer?.getLogger().resetMetrics();\n } catch {\n // Effectiveness reset must succeed independently from operational metrics.\n }\n }\n\n try {\n const rawConfig = loadRuntimeConfig(root, host);\n rawEffectivenessEnabled = rawEffectivenessMetricsEnabled(rawConfig);\n config ??= parseConfig(rawConfig);\n configCache.set(key, config);\n } catch {\n // An explicitly enabled process collector remains viewable and resettable\n // even when unrelated configuration is invalid.\n }\n\n const resetNotice = args.reset === true ? \"Metrics reset.\\n\\n\" : \"\";\n const effectivenessMetricsEnabled = config?.effectivenessMetrics.enabled ?? rawEffectivenessEnabled;\n const debugEnabled = config?.debug.enabled === true;\n const operationalMetricsEnabled = debugEnabled && config?.debug.metrics === true;\n\n if (!operationalMetricsEnabled && !effectivenessMetricsEnabled) {\n return {\n enabled: debugEnabled,\n metricsEnabled: false,\n effectivenessMetricsEnabled: false,\n text: `${resetNotice}Metrics collection is disabled. Enable privacy-safe aggregate telemetry without debug logs:\\n\\n\\`\\`\\`json\\n{\\n \"effectivenessMetrics\": {\\n \"enabled\": true\\n }\\n}\\n\\`\\`\\``,\n };\n }\n\n const sections: string[] = [];\n if (operationalMetricsEnabled) {\n try {\n const logger = cachedIndexer?.getLogger() ?? getIndexerForProject(root, host).getLogger();\n sections.push(logger.formatMetrics());\n } catch {\n sections.push(\"Operational metrics are unavailable.\");\n }\n }\n if (effectivenessMetricsEnabled) {\n sections.push(formatEffectivenessMetrics(getProcessEffectivenessMetrics()));\n }\n\n return {\n enabled: debugEnabled,\n metricsEnabled: operationalMetricsEnabled,\n effectivenessMetricsEnabled,\n text: `${resetNotice}${sections.join(\"\\n\\n\")}`,\n };\n}\n\nexport async function getIndexLogs(\n projectRoot: string | undefined,\n host: HostMode,\n args: { limit?: number; category?: string; level?: LogLevel },\n): Promise<{ kind: \"disabled\"; text: string } | { kind: \"entries\"; text: string }> {\n const indexer = getIndexerForProject(projectRoot, host);\n const logger = indexer.getLogger();\n\n if (!logger.isEnabled()) {\n return {\n kind: \"disabled\",\n text: \"Debug mode is disabled. Enable it in your config:\\n\\n```json\\n{\\n \\\"debug\\\": {\\n \\\"enabled\\\": true\\n }\\n}\\n```\",\n };\n }\n\n let logs: LogEntry[];\n if (args.category) {\n logs = logger.getLogsByCategory(args.category, args.limit);\n } else if (args.level) {\n logs = logger.getLogsByLevel(args.level, args.limit);\n } else {\n logs = logger.getLogs(args.limit);\n }\n\n if (logs.length === 0) {\n return {\n kind: \"entries\",\n text: \"No logs recorded yet. Logs are captured during indexing and search operations.\",\n };\n }\n\n const text = logs.map((entry) => {\n const dataStr = entry.data ? ` ${JSON.stringify(entry.data)}` : \"\";\n return `[${entry.timestamp}] [${entry.level.toUpperCase()}] [${entry.category}] ${entry.message}${dataStr}`;\n }).join(\"\\n\");\n\n return { kind: \"entries\", text };\n}\n\nexport function addKnowledgeBase(\n projectRoot: string | undefined,\n host: HostMode,\n knowledgeBasePath: string,\n): string {\n const root = getProjectRoot(projectRoot, host);\n const inputPath = knowledgeBasePath.trim();\n const normalizedPath = path.resolve(\n path.isAbsolute(inputPath)\n ? inputPath\n : resolveKnowledgeBasePath(inputPath, root),\n );\n\n if (!existsSync(normalizedPath)) {\n return `Error: Directory does not exist: ${normalizedPath}`;\n }\n\n let realPath: string;\n try {\n realPath = realpathSync(normalizedPath);\n } catch {\n return `Error: Cannot resolve path: ${normalizedPath}`;\n }\n\n const blockedPrefixes = [\n \"/etc\",\n \"/proc\",\n \"/sys\",\n \"/dev\",\n \"/boot\",\n \"/root\",\n \"/var/run\",\n \"/var/log\",\n ];\n const homeDir = process.platform === \"win32\" ? process.env.USERPROFILE ?? \"\" : process.env.HOME ?? \"\";\n const sensitiveDotDirs = [\n \".ssh\",\n \".gnupg\",\n \".aws\",\n \".config/gcloud\",\n \".docker\",\n \".kube\",\n ];\n\n for (const prefix of blockedPrefixes) {\n if (realPath === prefix || realPath.startsWith(`${prefix}/`)) {\n return `Error: Adding sensitive directory as knowledge base is not allowed: ${normalizedPath}`;\n }\n }\n\n for (const dotDir of sensitiveDotDirs) {\n const sensitiveDir = path.join(homeDir, dotDir);\n if (sensitiveDir && (realPath === sensitiveDir || realPath.startsWith(`${sensitiveDir}/`))) {\n return `Error: Adding sensitive directory as knowledge base is not allowed: ${normalizedPath}`;\n }\n }\n\n try {\n const stat = statSync(normalizedPath);\n if (!stat.isDirectory()) {\n return `Error: Path is not a directory: ${normalizedPath}`;\n }\n } catch (error: unknown) {\n return `Error: Cannot access directory: ${normalizedPath} - ${error instanceof Error ? error.message : String(error)}`;\n }\n\n const config = loadEditableConfig(root, host);\n const knowledgeBases: string[] = Array.isArray(config.knowledgeBases) ? (config.knowledgeBases as string[]) : [];\n const alreadyExists = hasMatchingKnowledgeBasePath(knowledgeBases, normalizedPath, root);\n\n if (alreadyExists) {\n return `Knowledge base already configured: ${normalizedPath}`;\n }\n\n knowledgeBases.push(normalizedPath);\n config.knowledgeBases = knowledgeBases;\n saveConfig(root, config, host);\n refreshIndexerForDirectory(root, host);\n\n let result = `${normalizedPath}\\n`;\n result += `Total knowledge bases: ${knowledgeBases.length}\\n`;\n result += `Config path: ${getConfigPath(root, host)}\\n`;\n result += `\\nRun /index to rebuild the index with the new knowledge base.`;\n return result;\n}\n\nexport function listKnowledgeBases(projectRoot: string | undefined, host: HostMode): string {\n const root = getProjectRoot(projectRoot, host);\n const config = loadRuntimeConfig(root, host);\n const knowledgeBases: string[] = Array.isArray(config.knowledgeBases) ? (config.knowledgeBases as string[]) : [];\n\n if (knowledgeBases.length === 0) {\n return \"No knowledge bases configured. Use add_knowledge_base to add folders.\";\n }\n\n let result = `Knowledge Bases (${knowledgeBases.length}):\\n\\n`;\n\n for (let i = 0; i < knowledgeBases.length; i++) {\n const kb = knowledgeBases[i];\n const resolvedPath = resolveKnowledgeBasePath(kb, root);\n const exists = existsSync(resolvedPath);\n\n result += `[${i + 1}] ${kb}\\n`;\n result += ` Resolved: ${resolvedPath}\\n`;\n result += ` Status: ${exists ? \"Exists\" : \"NOT FOUND\"}\\n`;\n\n if (exists) {\n try {\n const stat = statSync(resolvedPath);\n result += ` Type: ${stat.isDirectory() ? \"Directory\" : \"File\"}\\n`;\n } catch {\n // ignore\n }\n }\n\n result += \"\\n\";\n }\n\n const hasHostConfig = existsSync(path.join(root, getHostProjectConfigRelativePath(host)));\n if (hasHostConfig) {\n result += `\nConfig sources: 1 file(s).`;\n }\n\n result += `\\nConfig file: ${getConfigPath(root, host)}`;\n return result;\n}\n\nexport function removeKnowledgeBase(\n projectRoot: string | undefined,\n host: HostMode,\n knowledgeBasePath: string,\n): string {\n const root = getProjectRoot(projectRoot, host);\n const config = loadEditableConfig(root, host);\n const knowledgeBases: string[] = Array.isArray(config.knowledgeBases) ? (config.knowledgeBases as string[]) : [];\n const index = findKnowledgeBasePathIndex(knowledgeBases, knowledgeBasePath, root);\n\n if (index === -1) {\n return `Knowledge base not found: ${knowledgeBasePath}`;\n }\n\n const removed = knowledgeBases.splice(index, 1)[0];\n config.knowledgeBases = knowledgeBases;\n saveConfig(root, config, host);\n refreshIndexerForDirectory(root, host);\n\n let result = `Removed: ${removed}\\n\\n`;\n result += `Remaining knowledge bases: ${knowledgeBases.length}\\n`;\n result += `Config saved to: ${getConfigPath(root, host)}\\n`;\n result += `\\nRun /index to rebuild the index without the removed knowledge base.`;\n\n return result;\n}\n\nexport {\n AutoIndexRetrievalUnavailableError,\n getIndexerForProject,\n initializeTools,\n isToolEffectivenessEnabled,\n recordToolEffectiveness,\n refreshIndexerForDirectory,\n getSharedIndexer,\n formatStatus,\n};\n","import * as path from \"path\";\n\nimport { normalizePathSeparators } from \"../utils/paths.js\";\n\nexport function resolveConfigPathValue(value: string, baseDir: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return trimmed;\n }\n\n const absolutePath = path.isAbsolute(trimmed) ? trimmed : path.resolve(baseDir, trimmed);\n return path.normalize(absolutePath);\n}\n\nexport function serializeConfigPathValue(value: string, baseDir: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return trimmed;\n }\n\n if (!path.isAbsolute(trimmed)) {\n return normalizePathSeparators(path.normalize(trimmed));\n }\n\n const relativePath = path.relative(baseDir, trimmed);\n if (!relativePath || (!relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath))) {\n return normalizePathSeparators(path.normalize(relativePath || \".\"));\n }\n\n return path.normalize(trimmed);\n}\n\nexport function resolveKnowledgeBasePath(value: string, projectRoot: string): string {\n return path.isAbsolute(value) ? value : path.resolve(projectRoot, value);\n}\n\nexport function normalizeKnowledgeBasePath(value: string, projectRoot: string): string {\n return path.normalize(resolveKnowledgeBasePath(value, projectRoot));\n}\n\nexport function hasMatchingKnowledgeBasePath(\n knowledgeBases: string[],\n inputPath: string,\n projectRoot: string,\n): boolean {\n const normalizedInput = path.normalize(inputPath);\n return knowledgeBases.some((kb) => normalizeKnowledgeBasePath(kb, projectRoot) === normalizedInput);\n}\n\nexport function findKnowledgeBasePathIndex(\n knowledgeBases: string[],\n inputPath: string,\n projectRoot: string,\n): number {\n const normalizedInput = path.normalize(inputPath);\n return knowledgeBases.findIndex(\n (kb) => path.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath(kb, projectRoot) === normalizedInput\n );\n}\n","import type { SearchResult } from \"../indexer/index.js\";\n\nimport { get_encoding } from \"tiktoken\";\n\nimport { isLikelyImplementationPath } from \"../indexer/intent-aware-ranking.js\";\n\nexport const MIN_CONTEXT_PACK_TOKEN_BUDGET = 128;\nexport const MAX_CONTEXT_PACK_TOKEN_BUDGET = 4000;\nexport const DEFAULT_CONTEXT_PACK_TOKEN_BUDGET = 1200;\nconst CONTEXT_TOKENIZER = get_encoding(\"cl100k_base\");\n\ninterface RankedSearchResult {\n result: SearchResult;\n originalIndex: number;\n}\n\nexport interface ContextPackOptions {\n tokenBudget?: number;\n heading?: string;\n maxResults?: number;\n includeExactSearchHandoff?: boolean;\n preferImplementationPaths?: boolean;\n preserveInputOrder?: boolean;\n trace?: (trace: ContextPackTrace) => void;\n}\n\nexport interface ContextPackTrace {\n inputCandidates: Array<{\n filePath: string;\n startLine: number;\n endLine: number;\n score: number;\n chunkType: string;\n name?: string;\n }>;\n rankedCandidates: Array<{\n filePath: string;\n startLine: number;\n endLine: number;\n score: number;\n chunkType: string;\n name?: string;\n }>;\n deduplicatedCandidates: Array<{\n filePath: string;\n startLine: number;\n endLine: number;\n score: number;\n chunkType: string;\n name?: string;\n }>;\n diversifiedCandidates: Array<{\n filePath: string;\n startLine: number;\n endLine: number;\n score: number;\n chunkType: string;\n name?: string;\n }>;\n selectedCandidates: Array<{\n filePath: string;\n startLine: number;\n endLine: number;\n score: number;\n chunkType: string;\n name?: string;\n }>;\n}\n\nexport interface ContextPackResult {\n requestedTokenBudget: number;\n tokenBudget: number;\n text: string;\n tokenEstimate: number;\n results: SearchResult[];\n candidateCount: number;\n deduplicatedCount: number;\n selectedCount: number;\n omittedCount: number;\n duplicateCount: number;\n limitOmittedCount: number;\n budgetOmittedCount: number;\n}\n\nexport interface BudgetedTextResult {\n text: string;\n tokenBudget: number;\n tokenEstimate: number;\n truncated: boolean;\n}\n\nexport function clampContextPackTokenBudget(tokenBudget?: number): number {\n if (tokenBudget === undefined || !Number.isFinite(tokenBudget)) {\n return DEFAULT_CONTEXT_PACK_TOKEN_BUDGET;\n }\n return Math.min(\n MAX_CONTEXT_PACK_TOKEN_BUDGET,\n Math.max(MIN_CONTEXT_PACK_TOKEN_BUDGET, Math.floor(tokenBudget)),\n );\n}\n\nexport function countContextTokens(text: string): number {\n return CONTEXT_TOKENIZER.encode(text).length;\n}\n\nexport function fitTextToContextBudget(text: string, tokenBudget?: number): BudgetedTextResult {\n const normalizedBudget = clampContextPackTokenBudget(tokenBudget);\n const tokenEstimate = countContextTokens(text);\n if (tokenEstimate <= normalizedBudget) {\n return {\n text,\n tokenBudget: normalizedBudget,\n tokenEstimate,\n truncated: false,\n };\n }\n\n const suffix = \"\\n...[truncated to context token budget]\";\n const codePoints = Array.from(text);\n let low = 0;\n let high = codePoints.length;\n while (low < high) {\n const middle = Math.ceil((low + high) / 2);\n const candidate = `${codePoints.slice(0, middle).join(\"\").trimEnd()}${suffix}`;\n if (countContextTokens(candidate) <= normalizedBudget) low = middle;\n else high = middle - 1;\n }\n const fitted = `${codePoints.slice(0, low).join(\"\").trimEnd()}${suffix}`;\n return {\n text: fitted,\n tokenBudget: normalizedBudget,\n tokenEstimate: countContextTokens(fitted),\n truncated: true,\n };\n}\n\nfunction normalizedLineRange(result: SearchResult): { start: number; end: number } {\n return result.startLine <= result.endLine\n ? { start: result.startLine, end: result.endLine }\n : { start: result.endLine, end: result.startLine };\n}\n\nfunction rankContextCandidates(\n results: SearchResult[],\n preferImplementationPaths: boolean,\n): RankedSearchResult[] {\n return results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .sort((left, right) => {\n if (preferImplementationPaths) {\n const leftIsImplementation = isLikelyImplementationPath(left.result.filePath);\n const rightIsImplementation = isLikelyImplementationPath(right.result.filePath);\n if (leftIsImplementation !== rightIsImplementation) {\n return leftIsImplementation ? -1 : 1;\n }\n }\n return right.result.score - left.result.score || left.originalIndex - right.originalIndex;\n });\n}\n\nfunction deduplicateContextCandidates(candidates: RankedSearchResult[]): SearchResult[] {\n const acceptedByFile = new Map<string, Array<{ start: number; end: number }>>();\n const deduplicated: SearchResult[] = [];\n\n for (const { result } of candidates) {\n const range = normalizedLineRange(result);\n const accepted = acceptedByFile.get(result.filePath) ?? [];\n if (accepted.some((item) => item.start <= range.end && range.start <= item.end)) {\n continue;\n }\n accepted.push(range);\n acceptedByFile.set(result.filePath, accepted);\n deduplicated.push(result);\n }\n\n return deduplicated;\n}\n\nfunction diversifyContextCandidates(results: SearchResult[]): SearchResult[] {\n const byFile = new Map<string, SearchResult[]>();\n for (const result of results) {\n const bucket = byFile.get(result.filePath) ?? [];\n bucket.push(result);\n byFile.set(result.filePath, bucket);\n }\n\n const files = [...byFile.keys()];\n const diversified: SearchResult[] = [];\n for (let depth = 0; diversified.length < results.length; depth += 1) {\n for (const file of files) {\n const result = byFile.get(file)?.[depth];\n if (result) diversified.push(result);\n }\n }\n return diversified;\n}\n\nfunction compactEvidenceValue(value: string, maxChars: number): string {\n const characters = [...value];\n if (characters.length <= maxChars) return value;\n return `…${characters.slice(-(maxChars - 1)).join(\"\")}`;\n}\n\nconst MAX_EXACT_SEARCH_HANDOFF_NAMES = 3;\nconst MAX_EXACT_SEARCH_HANDOFF_NAME_CHARS = 64;\n\nfunction toContextPackTraceCandidate(result: SearchResult): ContextPackTrace[\"inputCandidates\"][number] {\n return {\n filePath: result.filePath,\n startLine: result.startLine,\n endLine: result.endLine,\n score: result.score,\n chunkType: result.chunkType,\n name: result.name,\n };\n}\n\nexport function formatExactSearchHandoff(results: SearchResult[]): string | null {\n const suggestedNames: string[] = [];\n const seen = new Set<string>();\n\n for (const result of results) {\n const rawName = result.name?.trim();\n if (!rawName) {\n continue;\n }\n\n if (Array.from(rawName).length > MAX_EXACT_SEARCH_HANDOFF_NAME_CHARS) {\n continue;\n }\n\n if (seen.has(rawName)) {\n continue;\n }\n\n seen.add(rawName);\n suggestedNames.push(rawName);\n\n if (suggestedNames.length >= MAX_EXACT_SEARCH_HANDOFF_NAMES) {\n break;\n }\n }\n\n if (suggestedNames.length === 0) {\n return null;\n }\n\n const quotedNames = suggestedNames.map((name) => JSON.stringify(name)).join(\", \");\n return `Exact-search handoff: use exact grep/search for ${quotedNames} to find usages or exhaustive matches.`;\n}\n\nfunction formatContextEvidence(result: SearchResult, index: number): string {\n const symbol = result.name ? ` ${JSON.stringify(compactEvidenceValue(result.name, 80))}` : \"\";\n const path = compactEvidenceValue(result.filePath, 120);\n return `[${index}] ${result.chunkType}${symbol} in ${path}:${result.startLine}-${result.endLine} (score ${result.score.toFixed(2)})`;\n}\n\nfunction formatContextPack(\n heading: string,\n selected: SearchResult[],\n candidateCount: number,\n duplicateCount: number,\n limitOmittedCount: number,\n budgetOmittedCount: number,\n includeExactSearchHandoff: boolean,\n): string {\n const lines = selected.map((result, index) => formatContextEvidence(result, index + 1));\n const notes: string[] = [];\n if (duplicateCount > 0) notes.push(`${duplicateCount} overlapping duplicate${duplicateCount === 1 ? \"\" : \"s\"} removed`);\n if (limitOmittedCount > 0) notes.push(`${limitOmittedCount} additional result${limitOmittedCount === 1 ? \"\" : \"s\"} excluded by result limit`);\n if (budgetOmittedCount > 0) notes.push(`${budgetOmittedCount} additional result${budgetOmittedCount === 1 ? \"\" : \"s\"} omitted by token budget`);\n const footer = notes.length > 0\n ? `Selected ${selected.length} of ${candidateCount} candidates; ${notes.join(\"; \")}.`\n : `Selected ${selected.length} of ${candidateCount} candidates.`;\n const handoff = includeExactSearchHandoff ? formatExactSearchHandoff(selected) : null;\n return [heading, lines.join(\"\\n\"), footer, handoff].filter(Boolean).join(\"\\n\\n\");\n}\n\nexport function buildContextPack(results: SearchResult[], options: ContextPackOptions = {}): ContextPackResult {\n const requestedTokenBudget = options.tokenBudget ?? DEFAULT_CONTEXT_PACK_TOKEN_BUDGET;\n const tokenBudget = clampContextPackTokenBudget(options.tokenBudget);\n const heading = compactEvidenceValue(options.heading?.trim() || \"Codebase evidence\", 160);\n const maxResults = Math.max(0, Math.floor(options.maxResults ?? results.length));\n const includeExactSearchHandoff = options.includeExactSearchHandoff ?? false;\n const candidateCount = results.length;\n const preserveInputOrder = options.preserveInputOrder ?? false;\n const ranked = preserveInputOrder\n ? results.map((result, originalIndex) => ({ result, originalIndex }))\n : rankContextCandidates(results, options.preferImplementationPaths ?? false);\n const rankedCandidates = ranked.map((entry) => toContextPackTraceCandidate(entry.result));\n const deduplicated = deduplicateContextCandidates(ranked);\n const deduplicatedCandidates = deduplicated.map((result) => toContextPackTraceCandidate(result));\n const diversified = preserveInputOrder ? deduplicated : diversifyContextCandidates(deduplicated);\n const diversifiedCandidates = diversified.map((result) => toContextPackTraceCandidate(result));\n const duplicateCount = candidateCount - deduplicated.length;\n const selectable = diversified.slice(0, maxResults);\n const limitOmittedCount = deduplicated.length - selectable.length;\n let selected: SearchResult[] = [];\n let text = formatContextPack(\n heading,\n selected,\n candidateCount,\n duplicateCount,\n limitOmittedCount,\n selectable.length,\n includeExactSearchHandoff,\n );\n\n for (let count = 1; count <= selectable.length; count += 1) {\n const candidateSelection = selectable.slice(0, count);\n const budgetOmittedCount = selectable.length - candidateSelection.length;\n const candidateText = formatContextPack(\n heading,\n candidateSelection,\n candidateCount,\n duplicateCount,\n limitOmittedCount,\n budgetOmittedCount,\n includeExactSearchHandoff,\n );\n if (countContextTokens(candidateText) > tokenBudget) break;\n selected = candidateSelection;\n text = candidateText;\n }\n\n const fitted = fitTextToContextBudget(text, tokenBudget);\n const budgetOmittedCount = selectable.length - selected.length;\n const omittedCount = candidateCount - selected.length;\n if (options.trace) {\n options.trace({\n inputCandidates: results.map(toContextPackTraceCandidate),\n rankedCandidates,\n deduplicatedCandidates,\n diversifiedCandidates,\n selectedCandidates: selected.map(toContextPackTraceCandidate),\n });\n }\n return {\n requestedTokenBudget,\n tokenBudget,\n text: fitted.text,\n tokenEstimate: fitted.tokenEstimate,\n results: selected,\n candidateCount,\n deduplicatedCount: deduplicated.length,\n selectedCount: selected.length,\n omittedCount,\n duplicateCount,\n limitOmittedCount,\n budgetOmittedCount,\n };\n}\n","import type { ChunkMetadata } from \"../native/index.js\";\n\nexport type RankedCandidate = { id: string; score: number; metadata: ChunkMetadata };\n\nexport type PrimaryQueryIntent =\n | \"definition\"\n | \"implementation\"\n | \"test\"\n | \"docs\"\n | \"config\"\n | \"call-flow\"\n | \"conceptual\"\n | \"neutral\";\n\nexport interface QueryIntentProfile {\n primary: PrimaryQueryIntent;\n identifierHints: string[];\n primaryIdentifier?: string;\n preferSourcePaths: boolean;\n explicitArtifactIntent: boolean;\n}\n\nconst STOPWORDS = new Set([\n \"a\", \"an\", \"and\", \"are\", \"as\", \"at\", \"be\", \"been\", \"being\", \"by\", \"code\",\n \"find\", \"for\", \"from\", \"get\", \"how\", \"in\", \"into\", \"is\", \"of\", \"on\", \"or\",\n \"result\", \"results\", \"retrieve\", \"run\", \"search\", \"show\", \"that\", \"the\", \"this\",\n \"to\", \"top\", \"use\", \"using\", \"was\", \"were\", \"what\", \"when\", \"where\", \"which\",\n \"who\", \"why\", \"with\",\n]);\n\nconst INTENT_WORDS = new Set([\n \"benchmark\", \"benchmarks\", \"body\", \"call\", \"called\", \"callee\", \"callees\", \"caller\",\n \"callers\", \"calls\", \"class\", \"config\", \"configuration\", \"declaration\", \"defined\",\n \"definition\", \"dependency\", \"docs\", \"documentation\", \"example\", \"examples\", \"fixture\",\n \"fixtures\", \"function\", \"guide\", \"implement\", \"implementation\", \"implemented\", \"implements\",\n \"invoked\", \"logic\", \"manifest\", \"method\", \"readme\", \"reference\", \"references\", \"settings\",\n \"source\", \"spec\", \"specs\", \"symbol\", \"test\", \"tests\", \"usage\",\n]);\n\nconst AUTHORITATIVE_CHUNK_TYPES = new Set([\n \"actor_declaration\",\n \"arrow_function\",\n \"class\",\n \"class_declaration\",\n \"class_definition\",\n \"class_name_statement\",\n \"class_specifier\",\n \"constructor_definition\",\n \"deinit_declaration\",\n \"enum\",\n \"enum_declaration\",\n \"enum_definition\",\n \"enum_item\",\n \"extension_declaration\",\n \"function\",\n \"function_declaration\",\n \"function_definition\",\n \"function_item\",\n \"impl\",\n \"impl_item\",\n \"init_declaration\",\n \"interface\",\n \"interface_declaration\",\n \"method\",\n \"method_declaration\",\n \"method_definition\",\n \"mod_item\",\n \"module\",\n \"namespace_definition\",\n \"protocol_declaration\",\n \"protocol_function_declaration\",\n \"signal_statement\",\n \"struct\",\n \"struct_declaration\",\n \"struct_item\",\n \"struct_specifier\",\n \"subscript_declaration\",\n \"trait\",\n \"trait_declaration\",\n \"trait_item\",\n \"trigger_declaration\",\n \"type\",\n \"type_alias_declaration\",\n \"type_declaration\",\n \"type_spec\",\n \"union_declaration\",\n]);\n\nconst IMPORT_CHUNK_TYPES = new Set([\n \"import\",\n \"import_declaration\",\n \"import_statement\",\n \"include_directive\",\n \"use_declaration\",\n \"use_statement\",\n]);\n\nconst WEAK_CONTAINER_CHUNK_TYPES = new Set([\n \"block\",\n \"export_statement\",\n \"lexical_declaration\",\n \"other\",\n \"program\",\n \"source_file\",\n \"statement_block\",\n]);\n\nconst TEST_CHUNK_TYPES = new Set([\"test\", \"test_declaration\"]);\n\nconst IMPLEMENTATION_FILE_EXTENSIONS = new Set([\n \"apex\", \"bash\", \"c\", \"cc\", \"cls\", \"cpp\", \"cs\", \"cts\", \"cxx\", \"gd\", \"go\", \"h\",\n \"hpp\", \"hxx\", \"inc\", \"java\", \"js\", \"jsx\", \"kt\", \"kts\", \"lua\", \"m\", \"metal\",\n \"mjs\", \"mts\", \"php\", \"py\", \"rb\", \"rs\", \"scala\", \"sh\", \"swift\", \"trigger\", \"ts\",\n \"tsx\", \"zig\", \"zsh\",\n]);\n\nfunction normalizePath(filePath: string): string {\n return normalizeRankingText(filePath).replace(/\\\\/g, \"/\");\n}\n\nexport function normalizeRankingText(value: string): string {\n return value.normalize(\"NFKC\").toLowerCase();\n}\n\nfunction compactIdentifier(value: string): string {\n return normalizeRankingText(value).replace(/[^\\p{L}\\p{N}$]+/gu, \"\");\n}\n\nfunction identifierTokens(value: string): string[] {\n const normalized = value\n .normalize(\"NFKC\")\n .replace(/([\\p{Ll}\\p{N}])([\\p{Lu}])/gu, \"$1 $2\")\n .replace(/[^\\p{L}\\p{N}$]+/gu, \" \")\n .toLowerCase();\n return normalized.split(/\\s+/).filter((token) => token.length > 1);\n}\n\nfunction queryWords(query: string): string[] {\n return query.normalize(\"NFKC\").match(/[\\p{L}_$][\\p{L}\\p{N}_$-]*/gu) ?? [];\n}\n\nfunction hasCodeShape(value: string): boolean {\n return /[_$]/u.test(value) || /[\\p{Ll}\\p{N}][\\p{Lu}]/u.test(value);\n}\n\nexport function extractIntentIdentifierHints(query: string): string[] {\n const quoted = Array.from(query.matchAll(/[`'\"]([\\p{L}_$][\\p{L}\\p{N}_$-]*)[`'\"]/gu))\n .map((match) => match[1]);\n const words = queryWords(query);\n const normalizedWords = words.map((word) => normalizeRankingText(word));\n const contentWords = words.filter((_word, index) => {\n const normalized = normalizedWords[index] ?? \"\";\n return normalized.length >= 2 && !STOPWORDS.has(normalized) && !INTENT_WORDS.has(normalized);\n });\n\n const explicitlyCodeShaped = contentWords.filter(hasCodeShape);\n const hasDefinitionWording = /\\b(?:defined|definition|declaration|implemented|implementation|symbol)\\b/iu.test(query) ||\n /\\bwhere\\s+is\\b/iu.test(query);\n const singleContentHint = contentWords.length === 1 ? contentWords : [];\n const intentAnchoredHints = hasDefinitionWording ? contentWords.slice(0, 3) : [];\n const candidates = [...quoted, ...explicitlyCodeShaped, ...singleContentHint, ...intentAnchoredHints];\n\n const seen = new Set<string>();\n const hints: string[] = [];\n for (const candidate of candidates) {\n const normalized = normalizeRankingText(candidate);\n if (normalized.length < 2 || seen.has(normalized)) continue;\n seen.add(normalized);\n hints.push(normalized);\n }\n return hints.slice(0, 8);\n}\n\nexport function analyzeQueryIntent(query: string): QueryIntentProfile {\n const normalized = normalizeRankingText(query);\n const identifierHints = extractIntentIdentifierHints(query);\n const primaryIdentifier = identifierHints[0];\n const testIntent = /\\b(?:tests?|specs?|fixtures?|benchmarks?|coverage)\\b/u.test(normalized);\n const docsIntent = /\\b(?:docs?|documentation|readme|guides?|usage|examples?)\\b/u.test(normalized);\n const configIntent = /\\b(?:config|configuration|settings|manifest|tsconfig|package\\.json|ya?ml|toml)\\b/u.test(normalized);\n const callFlowIntent = /\\b(?:callers?|callees?|call\\s+(?:flow|graph|path|chain)|called\\s+by|invoked\\s+by|references?\\s+to|dependency\\s+path)\\b/u.test(normalized) ||\n /\\bwho\\s+calls\\b/u.test(normalized);\n const definitionIntent = /\\b(?:defined|definition|declaration|symbol)\\b/u.test(normalized) ||\n /\\bwhere\\s+is\\b/u.test(normalized);\n const implementationIntent = /\\b(?:implement|implementation|implemented|implements|source|logic|body)\\b/u.test(normalized);\n const conceptual = identifierHints.length === 0 && queryWords(query).filter((word) => {\n const wordNormalized = normalizeRankingText(word);\n return !STOPWORDS.has(wordNormalized) && !INTENT_WORDS.has(wordNormalized);\n }).length >= 3;\n\n let primary: PrimaryQueryIntent;\n if (testIntent) primary = \"test\";\n else if (docsIntent) primary = \"docs\";\n else if (configIntent) primary = \"config\";\n else if (callFlowIntent) primary = \"call-flow\";\n else if (definitionIntent) primary = \"definition\";\n else if (implementationIntent) primary = \"implementation\";\n else if (conceptual) primary = \"conceptual\";\n else primary = \"neutral\";\n\n const explicitArtifactIntent = primary === \"test\" || primary === \"docs\" || primary === \"config\" || primary === \"call-flow\";\n const preferSourcePaths = primary === \"definition\" || primary === \"implementation\" || primary === \"call-flow\" ||\n (primary === \"neutral\" && identifierHints.length > 0);\n\n return {\n primary,\n identifierHints,\n primaryIdentifier,\n preferSourcePaths,\n explicitArtifactIntent,\n };\n}\n\nexport function isTestPath(filePath: string): boolean {\n const normalized = normalizePath(filePath);\n return /(?:^|\\/)(?:test|tests|__tests__|spec|specs)(?:\\/|$)/u.test(normalized) ||\n /(?:\\.(?:test|spec)|_(?:test|spec))\\.[^/]+$/u.test(normalized) ||\n /(?:^|\\/)(?:test|spec)_[^/]+\\.[^/]+$/u.test(normalized);\n}\n\nexport function isFixturePath(filePath: string): boolean {\n const normalized = normalizePath(filePath);\n return /(?:^|\\/)(?:fixture|fixtures|testdata|snapshots?)(?:\\/|$)/u.test(normalized) || normalized.endsWith(\".snap\");\n}\n\nexport function isDocumentationPath(filePath: string): boolean {\n const normalized = normalizePath(filePath);\n return /(?:^|\\/)docs?(?:\\/|$)/u.test(normalized) || /(?:^|\\/)readme(?:\\.|$)/u.test(normalized) ||\n /\\.(?:md|mdx|rst|adoc|txt)$/u.test(normalized);\n}\n\nexport function isGeneratedOrVendorPath(filePath: string): boolean {\n const normalized = normalizePath(filePath);\n return /(?:^|\\/)(?:node_modules|vendor|vendors|generated|dist|build|coverage|\\.next|target)(?:\\/|$)/u.test(normalized) ||\n /(?:\\.min\\.[^/]+|\\.generated\\.[^/]+|(?:^|\\/)package-lock\\.json|(?:^|\\/)yarn\\.lock|(?:^|\\/)pnpm-lock\\.yaml)$/u.test(normalized);\n}\n\nexport function isConfigPath(filePath: string): boolean {\n const normalized = normalizePath(filePath);\n const baseName = normalized.split(\"/\").pop() ?? normalized;\n return /(?:^|\\/)(?:config|configs|\\.github)(?:\\/|$)/u.test(normalized) ||\n /^(?:package\\.json|tsconfig(?:\\.[^.]+)?\\.json|pyproject\\.toml|cargo\\.toml|go\\.mod)$/u.test(baseName) ||\n /(?:^|\\.)(?:config|settings|rc)\\.[^/]+$/u.test(baseName) ||\n /\\.(?:yaml|yml|toml|ini)$/u.test(baseName);\n}\n\nexport function isAuthoritativeChunkType(chunkType: string): boolean {\n return AUTHORITATIVE_CHUNK_TYPES.has(normalizeRankingText(chunkType));\n}\n\nexport function isImportChunkType(chunkType: string): boolean {\n return IMPORT_CHUNK_TYPES.has(normalizeRankingText(chunkType));\n}\n\nfunction isWeakContainer(metadata: ChunkMetadata): boolean {\n const chunkType = normalizeRankingText(metadata.chunkType);\n const lineSpan = Math.max(1, metadata.endLine - metadata.startLine + 1);\n if (chunkType === \"export_statement\") return true;\n return WEAK_CONTAINER_CHUNK_TYPES.has(chunkType) && (lineSpan <= 2 || !metadata.name);\n}\n\nexport function isLikelyImplementationPath(filePath: string): boolean {\n if (isTestPath(filePath) || isFixturePath(filePath) || isDocumentationPath(filePath) || isGeneratedOrVendorPath(filePath)) {\n return false;\n }\n if (!isConfigPath(filePath)) return true;\n const extension = normalizePath(filePath).split(\".\").pop() ?? \"\";\n return IMPLEMENTATION_FILE_EXTENSIONS.has(extension);\n}\n\nfunction nameMatchStrength(name: string | undefined, hints: string[]): number {\n if (!name || hints.length === 0) return 0;\n const normalizedName = normalizeRankingText(name);\n const compactName = compactIdentifier(name);\n const nameTokens = new Set(identifierTokens(name));\n let best = 0;\n\n for (const hint of hints) {\n const normalizedHint = normalizeRankingText(hint);\n const compactHint = compactIdentifier(hint);\n if (normalizedName === normalizedHint) {\n best = Math.max(best, 4);\n } else if (compactName.length > 0 && compactName === compactHint) {\n best = Math.max(best, 3.6);\n } else if (normalizedName.startsWith(normalizedHint) || normalizedHint.startsWith(normalizedName)) {\n best = Math.max(best, 1.6);\n } else if (normalizedName.includes(normalizedHint)) {\n best = Math.max(best, 1.2);\n } else {\n const hintTokens = identifierTokens(hint);\n if (hintTokens.length > 0 && hintTokens.every((token) => nameTokens.has(token))) {\n best = Math.max(best, 1);\n }\n }\n }\n\n return best;\n}\n\nfunction tokenOverlap(query: string, metadata: ChunkMetadata): number {\n const queryTokens = new Set(queryWords(query).flatMap(identifierTokens).filter((token) => !STOPWORDS.has(token)));\n if (queryTokens.size === 0) return 0;\n const candidateTokens = new Set([\n ...identifierTokens(metadata.name ?? \"\"),\n ...identifierTokens(metadata.chunkType),\n ...identifierTokens(normalizePath(metadata.filePath).split(\"/\").slice(-3).join(\" \")),\n ]);\n let hits = 0;\n for (const token of queryTokens) {\n if (candidateTokens.has(token)) hits += 1;\n }\n return hits / queryTokens.size;\n}\n\nfunction callFlowAffinity(metadata: ChunkMetadata): number {\n const tokens = new Set([\n ...identifierTokens(metadata.name ?? \"\"),\n ...identifierTokens(normalizePath(metadata.filePath)),\n ]);\n return [\"call\", \"caller\", \"callee\", \"graph\", \"reference\", \"dependency\", \"edge\", \"path\"]\n .filter((token) => tokens.has(token)).length;\n}\n\ninterface ScoredCandidate {\n candidate: RankedCandidate;\n adjustedScore: number;\n originalIndex: number;\n nameMatch: number;\n}\n\nfunction scoreCandidate(query: string, intent: QueryIntentProfile, candidate: RankedCandidate, originalIndex: number): ScoredCandidate {\n const metadata = candidate.metadata;\n const nameMatch = nameMatchStrength(metadata.name, intent.identifierHints);\n const authoritative = isAuthoritativeChunkType(metadata.chunkType);\n const importChunk = isImportChunkType(metadata.chunkType);\n const weakContainer = isWeakContainer(metadata);\n const testPath = isTestPath(metadata.filePath) || TEST_CHUNK_TYPES.has(normalizeRankingText(metadata.chunkType));\n const fixturePath = isFixturePath(metadata.filePath);\n const docsPath = isDocumentationPath(metadata.filePath);\n const generatedOrVendor = isGeneratedOrVendorPath(metadata.filePath);\n const configPath = isConfigPath(metadata.filePath);\n const implementationPath = isLikelyImplementationPath(metadata.filePath);\n const overlap = tokenOverlap(query, metadata);\n let boost = 0;\n\n if (intent.primary === \"conceptual\") {\n boost += Math.min(0.14, overlap * 0.14);\n if (intent.preferSourcePaths) {\n boost += implementationPath ? 0.32 : 0;\n if (testPath || fixturePath || docsPath) boost -= 0.35;\n }\n if (generatedOrVendor) boost -= 0.18;\n if (importChunk || weakContainer) boost -= 0.04;\n } else if (intent.primary === \"test\") {\n boost += testPath ? 1.25 : 0;\n boost += fixturePath ? 0.7 : 0;\n boost += /\\b(?:test|spec|fixture)\\b/u.test(normalizeRankingText(metadata.name ?? \"\")) ? 0.35 : 0;\n boost += nameMatch * 0.28;\n if (docsPath) boost -= 0.2;\n if (generatedOrVendor) boost -= 0.7;\n } else if (intent.primary === \"docs\") {\n boost += docsPath ? 1.25 : 0;\n boost += normalizePath(metadata.filePath).includes(\"readme\") ? 0.25 : 0;\n boost += nameMatch * 0.25;\n if (testPath || fixturePath) boost -= 0.25;\n if (generatedOrVendor) boost -= 0.7;\n } else if (intent.primary === \"config\") {\n boost += configPath ? 1.3 : 0;\n boost += nameMatch * 0.35;\n boost += Math.min(0.3, overlap * 0.3);\n if (testPath || fixturePath || docsPath) boost -= 0.35;\n if (generatedOrVendor) boost -= 0.7;\n } else if (intent.primary === \"call-flow\") {\n boost += Math.min(1.2, callFlowAffinity(metadata) * 0.35);\n boost += authoritative && implementationPath ? 0.3 : 0;\n boost += nameMatch * 0.12;\n if (testPath || fixturePath || docsPath) boost -= 0.55;\n if (importChunk || weakContainer) boost -= 0.25;\n if (generatedOrVendor) boost -= 0.8;\n } else {\n const identifierDriven = intent.identifierHints.length > 0;\n boost += nameMatch;\n boost += authoritative ? (identifierDriven ? 0.65 : 0.18) : 0;\n boost += implementationPath && intent.preferSourcePaths ? 0.22 : 0;\n boost += Math.min(identifierDriven ? 0.25 : 0.12, overlap * (identifierDriven ? 0.25 : 0.12));\n if (importChunk) boost -= identifierDriven ? 1.05 : 0.08;\n if (weakContainer) boost -= identifierDriven ? 0.9 : 0.06;\n if (testPath) boost -= intent.preferSourcePaths ? 0.85 : 0;\n if (fixturePath) boost -= intent.preferSourcePaths ? 1 : 0;\n if (docsPath) boost -= intent.preferSourcePaths ? 0.8 : 0;\n if (generatedOrVendor) boost -= intent.preferSourcePaths ? 1.1 : 0.2;\n }\n\n return {\n candidate,\n adjustedScore: candidate.score + boost,\n originalIndex,\n nameMatch,\n };\n}\n\nfunction rangesOverlap(a: ChunkMetadata, b: ChunkMetadata): boolean {\n return a.startLine <= b.endLine && b.startLine <= a.endLine;\n}\n\nfunction containsRange(outer: ChunkMetadata, inner: ChunkMetadata): boolean {\n return outer.startLine <= inner.startLine && outer.endLine >= inner.endLine;\n}\n\nfunction areDuplicateEvidence(a: RankedCandidate, b: RankedCandidate): boolean {\n if (normalizePath(a.metadata.filePath) !== normalizePath(b.metadata.filePath)) return false;\n const aName = normalizeRankingText(a.metadata.name ?? \"\");\n const bName = normalizeRankingText(b.metadata.name ?? \"\");\n const sameNamedSymbol = aName.length > 0 && aName === bName;\n const eitherUnnamed = aName.length === 0 || bName.length === 0;\n const eitherWeakContainer = isWeakContainer(a.metadata) || isWeakContainer(b.metadata);\n const sameRange = a.metadata.startLine === b.metadata.startLine && a.metadata.endLine === b.metadata.endLine;\n if (sameRange) return sameNamedSymbol || eitherUnnamed || eitherWeakContainer;\n if (a.metadata.hash && b.metadata.hash && a.metadata.hash === b.metadata.hash) {\n return sameNamedSymbol || eitherUnnamed || eitherWeakContainer;\n }\n if (!rangesOverlap(a.metadata, b.metadata)) return false;\n\n const nested = containsRange(a.metadata, b.metadata) || containsRange(b.metadata, a.metadata);\n return nested && (sameNamedSymbol || eitherWeakContainer);\n}\n\nfunction deduplicateEvidence(entries: ScoredCandidate[]): ScoredCandidate[] {\n const selected: ScoredCandidate[] = [];\n for (const entry of entries) {\n if (selected.some((existing) => areDuplicateEvidence(existing.candidate, entry.candidate))) continue;\n selected.push(entry);\n }\n return selected;\n}\n\nfunction diversify(entries: ScoredCandidate[], preserveExactMatches: boolean): ScoredCandidate[] {\n if (entries.length <= 2) return entries;\n const exact = preserveExactMatches ? entries.filter((entry) => entry.nameMatch >= 3.6) : [];\n const exactIds = new Set(exact.map((entry) => entry.candidate.id));\n const remainder = entries.filter((entry) => !exactIds.has(entry.candidate.id));\n const groups = new Map<string, ScoredCandidate[]>();\n const order: string[] = [];\n\n for (const entry of remainder) {\n const filePath = normalizePath(entry.candidate.metadata.filePath);\n if (!groups.has(filePath)) {\n groups.set(filePath, []);\n order.push(filePath);\n }\n groups.get(filePath)?.push(entry);\n }\n\n const diversified: ScoredCandidate[] = [];\n let round = 0;\n let added = true;\n while (added) {\n added = false;\n for (const filePath of order) {\n const entry = groups.get(filePath)?.[round];\n if (!entry) continue;\n diversified.push(entry);\n added = true;\n }\n round += 1;\n }\n\n return [...exact, ...diversified];\n}\n\nexport function rankIntentAwareCandidates(\n query: string,\n candidates: RankedCandidate[],\n rerankTopN: number,\n options?: { prioritizeSourcePaths?: boolean },\n): RankedCandidate[] {\n if (rerankTopN <= 0 || candidates.length <= 1) return candidates;\n const intent = analyzeQueryIntent(query);\n if (options?.prioritizeSourcePaths !== undefined && options.prioritizeSourcePaths !== intent.preferSourcePaths) {\n intent.preferSourcePaths = options.prioritizeSourcePaths;\n }\n\n const topN = Math.min(rerankTopN, candidates.length);\n const scoredHead = candidates.slice(0, topN).map((candidate, index) => scoreCandidate(query, intent, candidate, index));\n scoredHead.sort((a, b) => {\n if (b.adjustedScore !== a.adjustedScore) return b.adjustedScore - a.adjustedScore;\n if (b.candidate.score !== a.candidate.score) return b.candidate.score - a.candidate.score;\n if (a.originalIndex !== b.originalIndex) return a.originalIndex - b.originalIndex;\n return a.candidate.id.localeCompare(b.candidate.id);\n });\n\n const scoredTail = candidates.slice(topN).map((candidate, index) => ({\n candidate,\n adjustedScore: candidate.score,\n originalIndex: topN + index,\n nameMatch: nameMatchStrength(candidate.metadata.name, intent.identifierHints),\n }));\n const deduplicated = deduplicateEvidence([...scoredHead, ...scoredTail]);\n const shouldDiversify = intent.primary !== \"definition\" && intent.primary !== \"implementation\" || intent.identifierHints.length === 0;\n const preserveExactMatches = intent.identifierHints.length > 0 &&\n (intent.primary === \"definition\" || intent.primary === \"implementation\" || intent.primary === \"neutral\");\n const ordered = shouldDiversify\n ? diversify(deduplicated, preserveExactMatches)\n : deduplicated;\n return ordered.map((entry) => entry.candidate);\n}\n","import type { IndexStats, IndexProgress, SearchResult, HealthCheckResult, StatusResult } from \"../indexer/index.js\";\nimport type { CallGraphDataResult, CallGraphPathResult, CallGraphSymbolResolution, IndexStatusResult } from \"./operations.js\";\nimport type { LogEntry } from \"../utils/logger.js\";\nimport { formatExactSearchHandoff } from \"./context-pack.js\";\n\nexport {\n clampContextPackTokenBudget,\n countContextTokens,\n fitTextToContextBudget,\n buildContextPack,\n MIN_CONTEXT_PACK_TOKEN_BUDGET,\n MAX_CONTEXT_PACK_TOKEN_BUDGET,\n DEFAULT_CONTEXT_PACK_TOKEN_BUDGET,\n} from \"./context-pack.js\";\nexport type {\n ContextPackOptions,\n ContextPackResult,\n BudgetedTextResult,\n} from \"./context-pack.js\";\n\nconst MAX_CONTENT_LINES = 30;\n\nfunction truncateContent(content: string): string {\n const lines = content.split(\"\\n\");\n if (lines.length <= MAX_CONTENT_LINES) return content;\n return (\n lines.slice(0, MAX_CONTENT_LINES).join(\"\\n\") +\n `\\n// ... (${lines.length - MAX_CONTENT_LINES} more lines)`\n );\n}\n\nexport function formatIndexStats(stats: IndexStats, verbose: boolean = false): string {\n if (stats.resetCorruptedIndex) {\n return stats.warning ?? \"Detected a corrupted local index and reset it during indexing. Run index_codebase again to rebuild search data.\";\n }\n\n const lines: string[] = [];\n\n if (stats.failedChunks > 0) {\n lines.push(`INDEXING WARNING: ${stats.failedChunks} chunks failed to embed.`);\n if (stats.failedBatchesPath) {\n lines.push(`Inspect failed batches at: ${stats.failedBatchesPath}`);\n }\n lines.push(\"\");\n }\n \n if (stats.indexedChunks === 0 && stats.removedChunks === 0) {\n lines.push(`${stats.totalFiles} files processed, ${stats.existingChunks} code chunks already up to date.`);\n } else if (stats.indexedChunks === 0) {\n lines.push(`${stats.totalFiles} files, removed ${stats.removedChunks} stale chunks, ${stats.existingChunks} chunks remain.`);\n } else {\n let main = `${stats.totalFiles} files processed, ${stats.indexedChunks} new chunks embedded.`;\n if (stats.existingChunks > 0) {\n main += ` ${stats.existingChunks} unchanged chunks skipped.`;\n }\n lines.push(main);\n\n if (stats.removedChunks > 0) {\n lines.push(`Removed ${stats.removedChunks} stale chunks.`);\n }\n\n if (stats.failedChunks > 0) {\n lines.push(`Failed: ${stats.failedChunks} chunks.`);\n }\n\n lines.push(`Tokens: ${stats.tokensUsed.toLocaleString()}, Duration: ${(stats.durationMs / 1000).toFixed(1)}s`);\n }\n\n if (verbose) {\n if (stats.skippedFiles.length > 0) {\n const tooLarge = stats.skippedFiles.filter(f => f.reason === \"too_large\");\n const excluded = stats.skippedFiles.filter(f => f.reason === \"excluded\");\n const gitignored = stats.skippedFiles.filter(f => f.reason === \"gitignore\");\n \n lines.push(\"\");\n lines.push(`Skipped files: ${stats.skippedFiles.length}`);\n if (tooLarge.length > 0) {\n lines.push(` Too large (${tooLarge.length}): ${tooLarge.slice(0, 5).map(f => f.path).join(\", \")}${tooLarge.length > 5 ? \"...\" : \"\"}`);\n }\n if (excluded.length > 0) {\n lines.push(` Excluded (${excluded.length}): ${excluded.slice(0, 5).map(f => f.path).join(\", \")}${excluded.length > 5 ? \"...\" : \"\"}`);\n }\n if (gitignored.length > 0) {\n lines.push(` Gitignored (${gitignored.length}): ${gitignored.slice(0, 5).map(f => f.path).join(\", \")}${gitignored.length > 5 ? \"...\" : \"\"}`);\n }\n }\n\n if (stats.parseFailures.length > 0) {\n lines.push(\"\");\n lines.push(`Files with no extractable chunks (${stats.parseFailures.length}): ${stats.parseFailures.slice(0, 10).join(\", \")}${stats.parseFailures.length > 10 ? \"...\" : \"\"}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatStatus(status: StatusResult | IndexStatusResult): string {\n const autoIndex = \"autoIndex\" in status ? status.autoIndex : undefined;\n const autoIndexLines = autoIndex ? formatAutoIndexStatus(autoIndex) : [];\n if (!status.indexed) {\n if (status.warning) {\n return [...autoIndexLines, status.warning].join(\"\\n\");\n }\n\n if (status.failedBatchesCount > 0) {\n const lines = [\n \"Codebase is not indexed. The last indexing run left failed embedding batches.\",\n \"Fix the provider/model configuration, then rerun index_codebase normally to retry the saved failed batches. Use force=true only for a full rebuild or compatibility reset.\",\n ];\n\n if (status.failedBatchesPath) {\n lines.push(`Failed batches: ${status.failedBatchesPath}`);\n }\n\n return [...autoIndexLines, ...lines].join(\"\\n\");\n }\n\n return [...autoIndexLines, \"Codebase is not indexed. Run index_codebase to create an index.\"].join(\"\\n\");\n }\n\n const lines = [\n ...autoIndexLines,\n `Indexed chunks: ${status.vectorCount.toLocaleString()}`,\n `Provider: ${status.provider}`,\n `Model: ${status.model}`,\n `Location: ${status.indexPath}`,\n ];\n\n if (status.currentBranch !== \"default\") {\n lines.push(`Current branch: ${status.currentBranch}`);\n lines.push(`Base branch: ${status.baseBranch}`);\n }\n\n if (status.failedBatchesCount > 0) {\n lines.push(\"\");\n lines.push(`INDEXING WARNING: ${status.failedBatchesCount} failed embedding batch${status.failedBatchesCount === 1 ? \" remains\" : \"es remain\"}.`);\n if (status.failedBatchesPath) {\n lines.push(`Failed batches: ${status.failedBatchesPath}`);\n }\n }\n\n if (status.warning) {\n lines.push(\"\");\n lines.push(`INDEX WARNING: ${status.warning}`);\n }\n\n if (status.compatibility && !status.compatibility.compatible) {\n lines.push(\"\");\n lines.push(`COMPATIBILITY WARNING: ${status.compatibility.reason}`);\n if (status.compatibility.storedMetadata) {\n const stored = status.compatibility.storedMetadata;\n lines.push(`Index was built with: ${stored.embeddingProvider}/${stored.embeddingModel} (${stored.embeddingDimensions}D)`);\n lines.push(`Current config: ${status.provider}/${status.model}`);\n }\n } else if (!status.compatibility) {\n lines.push(`Compatibility: No compatibility information found. Maybe the index is not initialized yet, try running index_codebase.`);\n } else {\n lines.push(`Compatibility: Index is compatible with the current provider and model.`);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatAutoIndexStatus(status: IndexStatusResult[\"autoIndex\"]): string[] {\n const enabled = status.enabled ? \"enabled\" : \"disabled\";\n const lines = [`Auto-index: ${enabled} (state: ${status.state})`];\n if (status.source) lines.push(`Auto-index source: ${status.source}`);\n if (status.progress) {\n const progress = status.progress;\n lines.push(\n `Auto-index progress: ${progress.phase} ${progress.percentage}% `\n + `(${progress.filesProcessed}/${progress.totalFiles} files, `\n + `${progress.chunksProcessed}/${progress.totalChunks} chunks)`,\n );\n }\n if (status.retryAttempt !== undefined) {\n lines.push(`Auto-index lock retry: ${status.retryAttempt}/${status.maxRetries ?? status.retryAttempt}`);\n }\n if (status.nextRetryAt) lines.push(`Auto-index next retry: ${status.nextRetryAt}`);\n if (status.startedAt) lines.push(`Auto-index started: ${status.startedAt}`);\n if (status.completedAt) lines.push(`Auto-index completed: ${status.completedAt}`);\n if (status.errorAt) lines.push(`Auto-index error time: ${status.errorAt}`);\n if (status.lastError) lines.push(`Auto-index error: ${status.lastError}`);\n if (status.blockedReason === \"home-directory\") {\n lines.push(\"Auto-index safety: blocked for the home directory.\");\n } else if (status.blockedReason === \"project-marker-missing\") {\n lines.push(\"Auto-index safety: blocked because no project marker was found.\");\n }\n lines.push(\"\");\n return lines;\n}\n\nexport function formatProgressTitle(progress: IndexProgress): string {\n switch (progress.phase) {\n case \"scanning\":\n return \"Scanning files...\";\n case \"parsing\":\n return `Parsing: ${progress.filesProcessed}/${progress.totalFiles} files`;\n case \"embedding\":\n return `Embedding: ${progress.chunksProcessed}/${progress.totalChunks} chunks`;\n case \"storing\":\n return \"Storing index...\";\n case \"complete\":\n return \"Indexing complete\";\n default:\n return \"Indexing...\";\n }\n}\n\nexport function calculatePercentage(progress: IndexProgress): number {\n if (progress.phase === \"scanning\") return 0;\n if (progress.phase === \"complete\") return 100;\n \n if (progress.phase === \"parsing\") {\n if (progress.totalFiles === 0) return 5;\n return Math.round(5 + (progress.filesProcessed / progress.totalFiles) * 15);\n }\n \n if (progress.phase === \"embedding\") {\n if (progress.totalChunks === 0) return 20;\n return Math.round(20 + (progress.chunksProcessed / progress.totalChunks) * 70);\n }\n \n if (progress.phase === \"storing\") return 95;\n \n return 0;\n}\n\nexport function formatCodebasePeek(results: SearchResult[]): string {\n if (results.length === 0) {\n return \"No matching code found. Try a different query or run index_codebase first.\";\n }\n\n const formatted = results.map((r, idx) => {\n const location = `${r.filePath}:${r.startLine}-${r.endLine}`;\n const name = r.name ? `\"${r.name}\"` : \"(anonymous)\";\n return `[${idx + 1}] ${r.chunkType} ${name} at ${location} (score: ${r.score.toFixed(2)})${formatBlame(r)}`;\n });\n\n const handoff = formatExactSearchHandoff(results);\n return handoff ? `${formatted.join(\"\\n\")}\\n\\n${handoff}` : formatted.join(\"\\n\");\n}\n\nexport function formatHealthCheck(result: HealthCheckResult): string {\n if (result.resetCorruptedIndex) {\n return result.warning ?? \"Detected a corrupted local index and reset it. Run index_codebase to rebuild search data.\";\n }\n\n if (result.removed === 0 && result.gcOrphanEmbeddings === 0 && result.gcOrphanChunks === 0 && result.gcOrphanSymbols === 0 && result.gcOrphanCallEdges === 0) {\n return \"Index is healthy. No stale entries found.\";\n }\n\n const lines: string[] = [];\n \n if (result.removed > 0) {\n lines.push(`Removed stale entries: ${result.removed}`);\n }\n \n if (result.gcOrphanEmbeddings > 0) {\n lines.push(`Garbage collected orphan embeddings: ${result.gcOrphanEmbeddings}`);\n }\n \n if (result.gcOrphanChunks > 0) {\n lines.push(`Garbage collected orphan chunks: ${result.gcOrphanChunks}`);\n }\n\n if (result.gcOrphanSymbols > 0) {\n lines.push(`Garbage collected orphan symbols: ${result.gcOrphanSymbols}`);\n }\n\n if (result.gcOrphanCallEdges > 0) {\n lines.push(`Garbage collected orphan call edges: ${result.gcOrphanCallEdges}`);\n }\n\n if (result.filePaths.length > 0) {\n lines.push(`Cleaned paths: ${result.filePaths.join(\", \")}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatLogs(logs: LogEntry[]): string {\n if (logs.length === 0) {\n return \"No logs recorded yet. Logs are captured during indexing and search operations.\";\n }\n\n return logs.map(l => {\n const dataStr = l.data ? ` ${JSON.stringify(l.data)}` : \"\";\n return `[${l.timestamp}] [${l.level.toUpperCase()}] [${l.category}] ${l.message}${dataStr}`;\n }).join(\"\\n\");\n}\n\nfunction formatCallGraphCandidates(resolution: Exclude<CallGraphSymbolResolution, { status: \"resolved\" }>): string {\n if (resolution.candidates.length === 0) return \"\";\n const lines = resolution.candidates.map((candidate) =>\n `- ${candidate.filePath}:${candidate.startLine} (${candidate.kind})`);\n if (resolution.totalCandidates > resolution.candidates.length) {\n lines.push(`- ...and ${resolution.totalCandidates - resolution.candidates.length} more`);\n }\n return `\\nCandidates:\\n${lines.join(\"\\n\")}`;\n}\n\nfunction formatCallGraphResolution(\n resolution: CallGraphSymbolResolution,\n label: \"symbol\" | \"source symbol\" | \"target symbol\",\n filePathParameter: \"filePath\" | \"fromFilePath\" | \"toFilePath\",\n): string | null {\n if (resolution.status === \"resolved\") return null;\n if (resolution.invalidSymbolId) {\n return `No active ${label} matched the supplied symbolId. Omit symbolId and retry with name${resolution.filePath ? ` and ${filePathParameter}` : \"\"}.`;\n }\n\n const candidates = formatCallGraphCandidates(resolution);\n if (resolution.status === \"ambiguous\") {\n return `Ambiguous ${label} \"${resolution.name}\". Pass ${filePathParameter} to choose one location.${candidates}`;\n }\n if (resolution.filePath && resolution.totalCandidates > 0) {\n return `No ${label} named \"${resolution.name}\" matched ${filePathParameter}=\"${resolution.filePath}\". Choose one of the available locations.${candidates}`;\n }\n return `No indexed ${label} named \"${resolution.name}\" was found. Check the spelling or refresh the index.`;\n}\n\nexport function formatCallGraphResult(result: CallGraphDataResult): string {\n const resolutionFailure = formatCallGraphResolution(result.resolution, \"symbol\", \"filePath\");\n if (resolutionFailure) return resolutionFailure;\n if (result.resolution.status !== \"resolved\") return \"Unable to resolve the requested symbol.\";\n\n const resolution = result.resolution;\n const relationship = result.relationshipType ? ` with type ${result.relationshipType}` : \"\";\n const location = `${resolution.filePath}:${resolution.startLine}`;\n if (result.direction === \"callers\") {\n if (result.callers.length === 0) {\n return `No callers found for \"${resolution.name}\" at ${location}${relationship}. It may not be called by any tracked function, or the index needs updating.`;\n }\n const formatted = result.callers.map((edge, index) => {\n const confidence = edge.confidence !== \"Direct\" ? ` [${edge.confidence.toLowerCase()}]` : \"\";\n return `[${index + 1}] \\u2190 from ${edge.fromSymbolName ?? \"<unknown>\"} in ${edge.fromSymbolFilePath ?? \"<unknown file>\"} (${edge.callType})${confidence} at line ${edge.line}${edge.isResolved ? \" [resolved]\" : \" [unresolved]\"}`;\n });\n return `\"${resolution.name}\" at ${location} is called by ${result.callers.length} function(s):\\n\\n${formatted.join(\"\\n\")}`;\n }\n\n if (result.callees.length === 0) {\n return `No callees found for \"${resolution.name}\" at ${location}${relationship}. The function may not call any other tracked functions.`;\n }\n const formatted = result.callees.map((edge, index) => {\n const confidence = edge.confidence !== \"Direct\" ? ` [${edge.confidence.toLowerCase()}]` : \"\";\n return `[${index + 1}] \\u2192 ${edge.targetName} (${edge.callType})${confidence} at line ${edge.line}${edge.isResolved ? \" [resolved]\" : \" [unresolved]\"}`;\n });\n return `\"${resolution.name}\" at ${location} calls ${result.callees.length} function(s):\\n\\n${formatted.join(\"\\n\")}`;\n}\n\nexport function formatCallGraphPathResult(result: CallGraphPathResult): string {\n const failures = [\n formatCallGraphResolution(result.from, \"source symbol\", \"fromFilePath\"),\n formatCallGraphResolution(result.to, \"target symbol\", \"toFilePath\"),\n ].filter((failure): failure is string => failure !== null);\n if (failures.length > 0) return failures.join(\"\\n\\n\");\n\n if (result.path.length === 0) {\n return `No path found between \"${result.from.name}\" and \"${result.to.name}\". They may be in disconnected components, or the call graph index needs updating.`;\n }\n\n const formatted = result.path.map((hop, index) => {\n const prefix = index === 0 ? \"[start]\" : `--${hop.callType}-->`;\n const location = hop.filePath ? ` (${hop.filePath}:${hop.line})` : \"\";\n return `${prefix} ${hop.symbolName}${location}`;\n });\n\n return `Path (${result.path.length} hops):\\n${formatted.join(\"\\n\")}`;\n}\n\nfunction formatResultHeader(result: SearchResult, index: number): string {\n return result.name\n ? `[${index + 1}] ${result.chunkType} \"${result.name}\" in ${result.filePath}:${result.startLine}-${result.endLine}`\n : `[${index + 1}] ${result.chunkType} in ${result.filePath}:${result.startLine}-${result.endLine}`;\n}\n\nfunction formatBlame(result: SearchResult): string {\n if (!result.blame) {\n return \"\";\n }\n\n const date = new Date(result.blame.committedAt * 1000).toISOString().slice(0, 10);\n return `\\n ${result.blame.sha.slice(0, 7)} | ${result.blame.author} | ${date} | ${result.blame.summary}`;\n}\n\nexport function formatDefinitionLookup(results: SearchResult[], query: string): string {\n if (results.length === 0) {\n return `No definition found for \"${query}\". Try codebase_search for broader discovery, or verify the symbol name.`;\n }\n\n const formatted = results.map((r, idx) => {\n const header = formatResultHeader(r, idx);\n return `${header} (score: ${r.score.toFixed(2)})${formatBlame(r)}\\n\\`\\`\\`\\n${truncateContent(r.content)}\\n\\`\\`\\``;\n });\n\n return formatted.join(\"\\n\\n\");\n}\n\nexport type ScoreFormat = \"score\" | \"similarity\";\n\nexport function formatSearchResults(results: SearchResult[], scoreFormat: ScoreFormat = \"similarity\"): string {\n const formatted = results.map((r, idx) => {\n const header = formatResultHeader(r, idx);\n\n const scoreLabel = scoreFormat === \"similarity\"\n ? `(similarity: ${(r.score * 100).toFixed(1)}%)`\n : `(score: ${r.score.toFixed(2)})`;\n\n return `${header} ${scoreLabel}${formatBlame(r)}\\n\\`\\`\\`\\n${truncateContent(r.content)}\\n\\`\\`\\``;\n });\n\n return formatted.join(\"\\n\\n\");\n}\n","import type { ParsedCodebaseIndexConfig } from \"../config/schema.js\";\nimport type { HostMode } from \"../config/host.js\";\nimport type { Indexer, IndexProgress, IndexStats } from \"../indexer/index.js\";\nimport type { BackgroundIndexingPolicy } from \"./power-source.js\";\nimport { existsSync, realpathSync } from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { resolveProjectIndexPath } from \"../config/paths.js\";\nimport { isTransientIndexLockContention } from \"../indexer/index-lock.js\";\nimport { hasProjectMarker } from \"./files.js\";\nimport { createBackgroundIndexingPolicy } from \"./power-source.js\";\n\nexport type AutoIndexCoordinatorState =\n | \"idle\"\n | \"checking\"\n | \"indexing\"\n | \"ready\"\n | \"busy-retrying\"\n | \"failed\"\n | \"stopped\";\n\nexport type AutoIndexSource = \"startup\" | \"retrieval\" | \"watcher\" | \"manual\";\n\nexport interface AutoIndexProgressSnapshot {\n phase: IndexProgress[\"phase\"];\n filesProcessed: number;\n totalFiles: number;\n chunksProcessed: number;\n totalChunks: number;\n percentage: number;\n}\n\nexport interface AutoIndexStatusSnapshot {\n enabled: boolean;\n state: AutoIndexCoordinatorState;\n source?: AutoIndexSource;\n startedAt?: string;\n updatedAt: string;\n completedAt?: string;\n errorAt?: string;\n lastError?: string;\n retryAttempt?: number;\n maxRetries?: number;\n nextRetryAt?: string;\n progress?: AutoIndexProgressSnapshot;\n blockedReason?: \"home-directory\" | \"project-marker-missing\";\n}\n\nexport interface CoordinatedIndexResult {\n outcome: \"ready\" | \"failed\" | \"stopped\";\n stats?: IndexStats;\n skipped?: boolean;\n error?: unknown;\n}\n\nexport interface AutoIndexRetrievalResult {\n ready: boolean;\n text?: string;\n}\n\ntype CoordinatedIndexer = Pick<\n Indexer,\n \"forceIndex\" | \"getStatus\" | \"index\"\n> & Partial<Pick<Indexer, \"getIndexFreshness\">>;\n\ninterface AutoIndexRegistration {\n backgroundIndexingPolicy: BackgroundIndexingPolicy | null;\n config: ParsedCodebaseIndexConfig;\n getIndexer: () => CoordinatedIndexer;\n projectRoot: string;\n safeToRun: boolean;\n blockedReason?: AutoIndexStatusSnapshot[\"blockedReason\"];\n}\n\ninterface IndexRequest {\n checkFreshness: boolean;\n force: boolean;\n onProgress?: (progress: IndexProgress) => void;\n source: AutoIndexSource;\n}\n\nconst MAX_RETRY_DELAY_MS = 10_000;\nconst SHUTDOWN_WAIT_MS = 2_000;\nconst coordinators = new Map<string, AutoIndexCoordinator>();\nconst coordinatorKeysByProject = new Map<string, string>();\nconst coordinatorReplacementBarriers = new Map<string, Promise<void>>();\n\nclass AutoIndexCancelledError extends Error {\n constructor() {\n super(\"Auto-index coordination was cancelled\");\n this.name = \"AutoIndexCancelledError\";\n }\n}\n\nfunction now(): string {\n return new Date().toISOString();\n}\n\nfunction canonicalizePath(targetPath: string): string {\n const resolved = path.resolve(targetPath);\n if (existsSync(resolved)) {\n try {\n return realpathSync.native(resolved);\n } catch {\n return resolved;\n }\n }\n\n const parent = path.dirname(resolved);\n if (parent === resolved) return resolved;\n return path.join(canonicalizePath(parent), path.basename(resolved));\n}\n\nexport function isHomeDirectory(projectRoot: string): boolean {\n return canonicalizePath(projectRoot) === canonicalizePath(os.homedir());\n}\n\nfunction projectLookupKey(projectRoot: string, host: HostMode): string {\n return `${host}::${canonicalizePath(projectRoot)}`;\n}\n\nfunction coordinatorKey(\n projectRoot: string,\n config: ParsedCodebaseIndexConfig,\n host: HostMode,\n): string {\n const canonicalProjectRoot = canonicalizePath(projectRoot);\n const indexPath = resolveProjectIndexPath(projectRoot, config.scope, host);\n return `${canonicalizePath(indexPath)}::${canonicalProjectRoot}`;\n}\n\nfunction getProjectSafety(\n projectRoot: string,\n config: ParsedCodebaseIndexConfig,\n): Pick<AutoIndexRegistration, \"blockedReason\" | \"safeToRun\"> {\n if (isHomeDirectory(projectRoot)) {\n return { safeToRun: false, blockedReason: \"home-directory\" };\n }\n if (config.indexing.requireProjectMarker && !hasProjectMarker(projectRoot)) {\n return { safeToRun: false, blockedReason: \"project-marker-missing\" };\n }\n return { safeToRun: true };\n}\n\nfunction calculatePercentage(progress: IndexProgress): number {\n if (progress.phase === \"scanning\") return 0;\n if (progress.phase === \"complete\") return 100;\n if (progress.phase === \"parsing\") {\n return progress.totalFiles === 0\n ? 5\n : Math.round(5 + (progress.filesProcessed / progress.totalFiles) * 15);\n }\n if (progress.phase === \"embedding\") {\n return progress.totalChunks === 0\n ? 20\n : Math.round(20 + (progress.chunksProcessed / progress.totalChunks) * 70);\n }\n if (progress.phase === \"storing\") return 95;\n return 0;\n}\n\nfunction safeFailureMessage(error: unknown): string {\n if (isTransientIndexLockContention(error)) {\n return \"Another index process remained busy after the configured retries.\";\n }\n return \"Automatic indexing failed. Check the embedding provider configuration, then run index_codebase.\";\n}\n\nfunction cancellableDelay(delayMs: number, signal: AbortSignal): Promise<void> {\n if (signal.aborted) return Promise.reject(new AutoIndexCancelledError());\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, delayMs);\n timer.unref?.();\n const onAbort = () => {\n clearTimeout(timer);\n reject(new AutoIndexCancelledError());\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T | undefined> {\n if (timeoutMs <= 0) return Promise.resolve(undefined);\n return new Promise<T | undefined>((resolve) => {\n const timer = setTimeout(() => resolve(undefined), timeoutMs);\n timer.unref?.();\n void promise.then((value) => {\n clearTimeout(timer);\n resolve(value);\n }, () => {\n clearTimeout(timer);\n resolve(undefined);\n });\n });\n}\n\nfunction requestPriority(request: IndexRequest): number {\n if (request.force) return 4;\n if (request.source === \"manual\") return 3;\n if (request.source === \"watcher\") return 2;\n return 1;\n}\n\nfunction mergeRequests(current: IndexRequest | null, next: IndexRequest): IndexRequest {\n if (!current) return next;\n const preferred = requestPriority(next) > requestPriority(current) ? next : current;\n return {\n checkFreshness: current.checkFreshness && next.checkFreshness,\n force: current.force || next.force,\n onProgress: next.onProgress ?? current.onProgress,\n source: preferred.source,\n };\n}\n\nclass AutoIndexCoordinator {\n private registration: AutoIndexRegistration;\n private status: AutoIndexStatusSnapshot;\n private activation: Promise<void> = Promise.resolve();\n private inFlight: Promise<CoordinatedIndexResult> | null = null;\n private activeRequest: IndexRequest | null = null;\n private batteryCheck: Promise<CoordinatedIndexResult> | null = null;\n private batteryIndexJob: Promise<CoordinatedIndexResult> | null = null;\n private batteryDeferredRequest: IndexRequest | null = null;\n private batteryRetryTimer: ReturnType<typeof setTimeout> | null = null;\n private resolveBatteryRetry: (() => void) | null = null;\n private pendingRequest: IndexRequest | null = null;\n private pendingFollowUp: Promise<CoordinatedIndexResult> | null = null;\n private abortController: AbortController | null = null;\n private stopped = false;\n\n constructor(registration: AutoIndexRegistration) {\n this.registration = registration;\n this.status = {\n enabled: registration.config.indexing.autoIndex,\n state: \"idle\",\n updatedAt: now(),\n blockedReason: registration.blockedReason,\n };\n }\n\n update(registration: AutoIndexRegistration): void {\n const pauseOnBatteryChanged = registration.config.indexing.pauseBackgroundIndexingOnBattery\n !== this.registration.config.indexing.pauseBackgroundIndexingOnBattery;\n this.registration = registration;\n this.status.enabled = registration.config.indexing.autoIndex;\n this.status.blockedReason = registration.blockedReason;\n this.status.updatedAt = now();\n if (this.stopped) {\n this.stopped = false;\n this.status.state = \"idle\";\n }\n if (!registration.config.indexing.autoIndex && this.activeRequest?.source !== \"manual\") {\n this.pendingRequest = null;\n this.abortController?.abort();\n if (!this.inFlight) {\n this.setState(\"idle\", { source: undefined });\n }\n }\n if (pauseOnBatteryChanged) {\n this.cancelBatteryRetry();\n }\n }\n\n activateAfter(activation: Promise<void>): void {\n this.activation = activation;\n }\n\n snapshot(): AutoIndexStatusSnapshot {\n this.refreshSafety();\n return {\n ...this.status,\n progress: this.status.progress ? { ...this.status.progress } : undefined,\n };\n }\n\n start(source: \"startup\" | \"retrieval\"): Promise<CoordinatedIndexResult> | null {\n this.refreshSafety();\n if (!this.registration.config.indexing.autoIndex || !this.registration.safeToRun) return null;\n if (this.status.state === \"failed\") return this.inFlight;\n return this.request({ checkFreshness: true, force: false, source });\n }\n\n request(request: IndexRequest): Promise<CoordinatedIndexResult> {\n if (this.stopped) {\n return Promise.resolve({ outcome: \"stopped\" });\n }\n return this.activation.then(() => this.enqueueBatteryAwareRequest(request));\n }\n\n private enqueueBatteryAwareRequest(request: IndexRequest): Promise<CoordinatedIndexResult> {\n if (!this.shouldDeferForBattery(request)) {\n return this.enqueueRequest(request);\n }\n\n if (this.batteryCheck && this.batteryIndexJob !== null && this.batteryIndexJob === this.inFlight) {\n return this.enqueueRequest(request);\n }\n\n this.batteryDeferredRequest = mergeRequests(this.batteryDeferredRequest, request);\n if (this.batteryCheck) {\n return this.batteryCheck;\n }\n\n const batteryCheck = this.waitForACPower();\n this.batteryCheck = batteryCheck;\n void batteryCheck.then(\n () => this.finishBatteryCheck(batteryCheck),\n () => this.finishBatteryCheck(batteryCheck),\n );\n return batteryCheck;\n }\n\n private enqueueRequest(request: IndexRequest): Promise<CoordinatedIndexResult> {\n if (this.stopped || !this.canRun(request)) {\n return Promise.resolve({ outcome: \"stopped\" });\n }\n if (this.inFlight) {\n if (request.force && !this.activeRequest?.force) {\n this.pendingRequest = mergeRequests(this.pendingRequest, request);\n this.abortController?.abort();\n const active = this.inFlight;\n return active.then(() => {\n if (this.stopped) return { outcome: \"stopped\" };\n return this.inFlight ?? this.startRequest(request);\n });\n }\n if (request.source === \"watcher\") {\n this.pendingRequest = mergeRequests(this.pendingRequest, request);\n const active = this.inFlight;\n return active.then(() => {\n if (this.stopped) return { outcome: \"stopped\" };\n return this.pendingFollowUp ?? { outcome: \"stopped\" };\n });\n }\n return this.inFlight;\n }\n return this.startRequest(request);\n }\n\n currentJob(): Promise<CoordinatedIndexResult> | null {\n return this.inFlight;\n }\n\n getIndexer(): CoordinatedIndexer {\n return this.registration.getIndexer();\n }\n\n getWaitMs(): number {\n return this.registration.config.indexing.autoIndexWaitMs;\n }\n\n async stop(waitForCompletion = false): Promise<void> {\n this.stopped = true;\n this.batteryDeferredRequest = null;\n this.cancelBatteryRetry();\n this.pendingRequest = null;\n this.abortController?.abort();\n this.setState(\"stopped\", {\n completedAt: now(),\n nextRetryAt: undefined,\n progress: undefined,\n retryAttempt: undefined,\n });\n const inFlight = this.inFlight;\n if (inFlight) {\n if (waitForCompletion) {\n await inFlight;\n } else {\n await withTimeout(inFlight, SHUTDOWN_WAIT_MS);\n }\n }\n }\n\n private startRequest(request: IndexRequest): Promise<CoordinatedIndexResult> {\n if (this.stopped || !this.canRun(request)) {\n return Promise.resolve({ outcome: \"stopped\" });\n }\n this.activeRequest = request;\n const job = this.run(request);\n this.inFlight = job;\n void job.then(() => {\n if (this.inFlight !== job) return;\n this.inFlight = null;\n this.activeRequest = null;\n this.abortController = null;\n if (this.batteryIndexJob === job) {\n this.batteryIndexJob = null;\n this.batteryCheck = null;\n }\n const pending = this.pendingRequest;\n this.pendingRequest = null;\n if (pending && !this.stopped) {\n const followUp = this.request(pending);\n this.pendingFollowUp = followUp;\n void followUp.then(() => {\n if (this.pendingFollowUp === followUp) {\n this.pendingFollowUp = null;\n }\n });\n }\n });\n return job;\n }\n\n private async run(request: IndexRequest): Promise<CoordinatedIndexResult> {\n const controller = new AbortController();\n this.abortController = controller;\n const startedAt = now();\n this.setState(\"checking\", {\n completedAt: undefined,\n errorAt: undefined,\n lastError: undefined,\n nextRetryAt: undefined,\n progress: undefined,\n retryAttempt: undefined,\n source: request.source,\n startedAt,\n });\n\n const maxRetries = request.source === \"manual\"\n ? 0\n : this.registration.config.indexing.autoIndexMaxRetries;\n let retryAttempt = 0;\n while (true) {\n try {\n this.throwIfCancelled(controller.signal);\n const indexer = this.registration.getIndexer();\n if (request.checkFreshness && !request.force) {\n if (indexer.getIndexFreshness) {\n const freshness = await indexer.getIndexFreshness();\n this.throwIfCancelled(controller.signal);\n if (freshness.readable && freshness.current) {\n this.setState(\"ready\", {\n completedAt: now(),\n progress: undefined,\n retryAttempt: undefined,\n });\n return { outcome: \"ready\", skipped: true };\n }\n }\n }\n\n this.setState(\"indexing\", {\n nextRetryAt: undefined,\n retryAttempt: retryAttempt > 0 ? retryAttempt : undefined,\n });\n const operation = request.force ? indexer.forceIndex.bind(indexer) : indexer.index.bind(indexer);\n const stats = await operation((progress) => {\n this.throwIfCancelled(controller.signal);\n request.onProgress?.(progress);\n this.status.progress = {\n phase: progress.phase,\n filesProcessed: progress.filesProcessed,\n totalFiles: progress.totalFiles,\n chunksProcessed: progress.chunksProcessed,\n totalChunks: progress.totalChunks,\n percentage: calculatePercentage(progress),\n };\n this.status.updatedAt = now();\n });\n this.throwIfCancelled(controller.signal);\n if (request.source === \"startup\" || request.source === \"retrieval\") {\n const latestStatus = await this.registration.getIndexer().getStatus();\n if (!latestStatus.indexed) {\n const error = new Error(\"Indexing completed without producing a readable index\");\n this.setState(\"failed\", {\n completedAt: now(),\n errorAt: now(),\n lastError: \"Automatic indexing completed but no readable index was produced. Check include and exclude patterns.\",\n progress: undefined,\n });\n return { outcome: \"failed\", error, stats };\n }\n }\n this.setState(\"ready\", {\n completedAt: now(),\n progress: this.status.progress\n ? { ...this.status.progress, phase: \"complete\", percentage: 100 }\n : undefined,\n retryAttempt: undefined,\n });\n return { outcome: \"ready\", stats };\n } catch (error) {\n if (error instanceof AutoIndexCancelledError || controller.signal.aborted) {\n if (this.stopped) {\n this.setState(\"stopped\", { completedAt: now(), progress: undefined });\n return { outcome: \"stopped\" };\n }\n if (!this.registration.config.indexing.autoIndex && request.source !== \"manual\") {\n this.setState(\"idle\", {\n completedAt: now(),\n progress: undefined,\n source: undefined,\n });\n return { outcome: \"stopped\" };\n }\n return { outcome: \"stopped\" };\n }\n\n if (isTransientIndexLockContention(error) && retryAttempt < maxRetries) {\n retryAttempt += 1;\n const delayMs = Math.min(\n this.registration.config.indexing.autoIndexRetryDelayMs * (2 ** (retryAttempt - 1)),\n MAX_RETRY_DELAY_MS,\n );\n const nextRetryAt = new Date(Date.now() + delayMs).toISOString();\n this.setState(\"busy-retrying\", {\n maxRetries,\n nextRetryAt,\n progress: undefined,\n retryAttempt,\n });\n try {\n await cancellableDelay(delayMs, controller.signal);\n } catch (delayError) {\n if (delayError instanceof AutoIndexCancelledError) {\n if (this.stopped) {\n this.setState(\"stopped\", { completedAt: now(), progress: undefined });\n }\n return { outcome: \"stopped\" };\n }\n throw delayError;\n }\n this.setState(\"checking\", { nextRetryAt: undefined });\n continue;\n }\n\n const errorAt = now();\n this.setState(\"failed\", {\n completedAt: errorAt,\n errorAt,\n lastError: safeFailureMessage(error),\n nextRetryAt: undefined,\n progress: undefined,\n retryAttempt: retryAttempt > 0 ? retryAttempt : undefined,\n });\n return { outcome: \"failed\", error };\n }\n }\n }\n\n private setState(\n state: AutoIndexCoordinatorState,\n updates: Partial<AutoIndexStatusSnapshot> = {},\n ): void {\n if (this.stopped && state !== \"stopped\") return;\n this.status = {\n ...this.status,\n ...updates,\n enabled: this.registration.config.indexing.autoIndex,\n state,\n updatedAt: now(),\n blockedReason: this.registration.blockedReason,\n };\n }\n\n private throwIfCancelled(signal: AbortSignal): void {\n if (signal.aborted) throw new AutoIndexCancelledError();\n }\n\n private refreshSafety(): void {\n const previousBlockedReason = this.registration.blockedReason;\n const safety = getProjectSafety(this.registration.projectRoot, this.registration.config);\n this.registration.safeToRun = safety.safeToRun;\n this.registration.blockedReason = safety.blockedReason;\n this.status.blockedReason = safety.blockedReason;\n if (previousBlockedReason !== safety.blockedReason) {\n this.status.updatedAt = now();\n }\n }\n\n private canRun(request: IndexRequest): boolean {\n this.refreshSafety();\n if (request.source === \"manual\" || request.source === \"watcher\") {\n return true;\n }\n\n return this.registration.safeToRun && this.registration.config.indexing.autoIndex;\n }\n\n private shouldDeferForBattery(request: IndexRequest): boolean {\n return this.registration.backgroundIndexingPolicy !== null\n && (request.source === \"startup\" || request.source === \"watcher\");\n }\n\n private async waitForACPower(): Promise<CoordinatedIndexResult> {\n while (!this.stopped) {\n const policy = this.registration.backgroundIndexingPolicy;\n if (!policy || !await this.isBatteryPauseActive(policy)) {\n const request = this.batteryDeferredRequest;\n this.batteryDeferredRequest = null;\n if (!request) return { outcome: \"stopped\" };\n const job = this.enqueueRequest(request);\n if (this.inFlight === job) {\n this.batteryIndexJob = job;\n }\n return job;\n }\n await this.waitForBatteryRetry(policy.recheckDelayMs);\n }\n return { outcome: \"stopped\" };\n }\n\n private async isBatteryPauseActive(policy: BackgroundIndexingPolicy): Promise<boolean> {\n try {\n return await policy.isPaused();\n } catch (error) {\n console.error(\n `[codebase-index] Failed to apply the background indexing power policy; background indexing will continue: ${safeFailureMessage(error)}`,\n );\n return false;\n }\n }\n\n private waitForBatteryRetry(delayMs: number): Promise<void> {\n return new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n if (this.batteryRetryTimer === timer) {\n this.batteryRetryTimer = null;\n this.resolveBatteryRetry = null;\n }\n resolve();\n }, delayMs);\n timer.unref?.();\n this.batteryRetryTimer = timer;\n this.resolveBatteryRetry = resolve;\n });\n }\n\n private cancelBatteryRetry(): void {\n if (this.batteryRetryTimer) {\n clearTimeout(this.batteryRetryTimer);\n this.batteryRetryTimer = null;\n }\n const resolve = this.resolveBatteryRetry;\n this.resolveBatteryRetry = null;\n resolve?.();\n }\n\n private finishBatteryCheck(batteryCheck: Promise<CoordinatedIndexResult>): void {\n if (this.batteryCheck !== batteryCheck) return;\n this.batteryCheck = null;\n const deferredRequest = this.batteryDeferredRequest;\n this.batteryDeferredRequest = null;\n if (deferredRequest && !this.stopped) {\n void this.request(deferredRequest);\n }\n }\n}\n\nfunction getCoordinator(projectRoot: string, host: HostMode): AutoIndexCoordinator | null {\n const key = coordinatorKeysByProject.get(projectLookupKey(projectRoot, host));\n return key ? coordinators.get(key) ?? null : null;\n}\n\nexport function configureAutoIndex(\n projectRoot: string,\n host: HostMode,\n config: ParsedCodebaseIndexConfig,\n getIndexer: () => CoordinatedIndexer,\n): void {\n const projectKey = projectLookupKey(projectRoot, host);\n const safety = getProjectSafety(projectRoot, config);\n const registration: AutoIndexRegistration = {\n backgroundIndexingPolicy: createBackgroundIndexingPolicy(\n config.indexing.pauseBackgroundIndexingOnBattery,\n ),\n config,\n getIndexer,\n projectRoot,\n ...safety,\n };\n const key = coordinatorKey(projectRoot, config, host);\n const previousKey = coordinatorKeysByProject.get(projectKey);\n if (previousKey && previousKey !== key) {\n const previousCoordinator = coordinators.get(previousKey);\n const previousBarrier = coordinatorReplacementBarriers.get(projectKey) ?? Promise.resolve();\n const stopPrevious = previousCoordinator?.stop(true) ?? Promise.resolve();\n const activation = Promise.all([previousBarrier, stopPrevious]).then(() => undefined);\n coordinatorReplacementBarriers.set(projectKey, activation);\n coordinators.delete(previousKey);\n\n const coordinator = new AutoIndexCoordinator(registration);\n coordinator.activateAfter(activation);\n coordinators.set(key, coordinator);\n coordinatorKeysByProject.set(projectKey, key);\n return;\n }\n\n let coordinator = coordinators.get(key);\n if (!coordinator) {\n coordinator = new AutoIndexCoordinator(registration);\n coordinators.set(key, coordinator);\n } else {\n coordinator.update(registration);\n }\n coordinatorKeysByProject.set(projectKey, key);\n}\n\nexport function startAutoIndex(\n projectRoot: string,\n host: HostMode,\n source: \"startup\" | \"retrieval\" = \"startup\",\n): Promise<CoordinatedIndexResult> | null {\n return getCoordinator(projectRoot, host)?.start(source) ?? null;\n}\n\nexport function requestBackgroundIndex(\n projectRoot: string,\n host: HostMode,\n): Promise<CoordinatedIndexResult> | null {\n return getCoordinator(projectRoot, host)?.request({\n checkFreshness: false,\n force: false,\n source: \"watcher\",\n }) ?? null;\n}\n\nexport function runCoordinatedIndex(\n projectRoot: string,\n host: HostMode,\n force: boolean,\n onProgress?: (progress: IndexProgress) => void,\n): Promise<CoordinatedIndexResult> | null {\n return getCoordinator(projectRoot, host)?.request({\n checkFreshness: !force,\n force,\n onProgress,\n source: \"manual\",\n }) ?? null;\n}\n\nexport function getAutoIndexStatus(\n projectRoot: string,\n host: HostMode,\n): AutoIndexStatusSnapshot {\n return getCoordinator(projectRoot, host)?.snapshot() ?? {\n enabled: false,\n state: \"idle\",\n updatedAt: now(),\n };\n}\n\nexport async function waitForAutoIndexForRetrieval(\n projectRoot: string,\n host: HostMode,\n): Promise<AutoIndexRetrievalResult> {\n const coordinator = getCoordinator(projectRoot, host);\n if (!coordinator) return { ready: true };\n const initial = coordinator.snapshot();\n if (!initial.enabled) return { ready: true };\n if (initial.blockedReason === \"home-directory\") {\n return {\n ready: false,\n text: \"Automatic indexing is disabled for the home directory. Open a specific project and retry.\",\n };\n }\n if (initial.blockedReason === \"project-marker-missing\") {\n return {\n ready: false,\n text: \"Automatic indexing is waiting for a recognized project marker. Add a project marker or set indexing.requireProjectMarker=false, then retry.\",\n };\n }\n\n try {\n if (await hasReadableCurrentIndex(coordinator)) return { ready: true };\n } catch {\n // The coordinator reports a sanitized actionable failure below.\n }\n\n const job = coordinator.start(\"retrieval\") ?? coordinator.currentJob();\n if (job) {\n await withTimeout(job, coordinator.getWaitMs());\n }\n\n try {\n if (await hasReadableCurrentIndex(coordinator)) return { ready: true };\n } catch {\n // The coordinator reports a sanitized actionable failure below.\n }\n\n const status = coordinator.snapshot();\n if (status.state === \"failed\") {\n return {\n ready: false,\n text: `Automatic indexing failed${status.errorAt ? ` at ${status.errorAt}` : \"\"}. ${status.lastError ?? \"Check index_status, then run index_codebase.\"}`,\n };\n }\n if (status.state === \"stopped\") {\n return {\n ready: false,\n text: \"Automatic indexing stopped before a readable index was ready. Restart the MCP server or run index_codebase.\",\n };\n }\n return {\n ready: false,\n text: `Automatic indexing is ${status.state}. Retry shortly or call index_status for progress. You can also run index_codebase explicitly.`,\n };\n}\n\nexport async function stopAutoIndex(\n projectRoot: string,\n host: HostMode,\n): Promise<void> {\n await getCoordinator(projectRoot, host)?.stop();\n}\n\nexport async function stopAllAutoIndexes(): Promise<void> {\n await Promise.all(Array.from(coordinators.values(), (coordinator) => coordinator.stop()));\n}\n\nexport async function resetAutoIndexCoordinatorsForTests(): Promise<void> {\n await stopAllAutoIndexes();\n await Promise.all(coordinatorReplacementBarriers.values());\n coordinators.clear();\n coordinatorKeysByProject.clear();\n coordinatorReplacementBarriers.clear();\n}\n\nasync function hasReadableCurrentIndex(coordinator: AutoIndexCoordinator): Promise<boolean> {\n const indexer = coordinator.getIndexer();\n if (indexer.getIndexFreshness) {\n const freshness = await indexer.getIndexFreshness();\n return freshness.readable && freshness.current;\n }\n return (await indexer.getStatus()).indexed;\n}\n","import { randomUUID } from \"crypto\";\nimport {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n realpathSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nexport type IndexMutationOperation =\n | \"initialize\"\n | \"index\"\n | \"force-index\"\n | \"clear\"\n | \"health-check\"\n | \"retry-failed-batches\"\n | \"recovery\";\n\nexport interface IndexLockOwner {\n pid: number;\n hostname: string;\n startedAt: string;\n operation: IndexMutationOperation;\n token: string;\n /** Recovery protocol written by owners that persist destructive phase state. */\n recoveryProtocolVersion?: 1;\n /** Originating project root for interrupted global clears (recovery scope). */\n projectRoot?: string;\n /** Originating scoped roots for interrupted global clears (recovery scope). */\n scopedRoots?: string[];\n /** Destructive clear state, present only while a clear is in progress. */\n clearRecovery?: IndexLockClearRecoveryState;\n}\n\nexport interface IndexLockClearRecoveryState {\n phase: \"clearing\";\n embeddingProvider: string;\n embeddingModel: string;\n embeddingDimensions: number;\n embeddingStrategyVersion: string;\n compatibilityDecision: \"compatible\" | \"embedding-strategy-mismatch\" | \"incompatible\";\n}\n\nexport interface IndexLockRecovery {\n owner: IndexLockOwner;\n markerPath: string;\n}\n\nexport interface IndexLockLease {\n canonicalIndexPath: string;\n lockPath: string;\n owner: IndexLockOwner;\n recoveries: IndexLockRecovery[];\n}\n\ntype OwnerLiveness = \"alive\" | \"dead\" | \"unknown\";\n\ninterface ReclaimOwner {\n pid: number;\n hostname: string;\n startedAt: string;\n token: string;\n expectedOwnerToken: string;\n}\n\nconst OWNER_FILE_NAME = \"owner.json\";\nconst RECLAIM_DIRECTORY_NAME = \"reclaiming\";\nconst RECOVERY_MARKER_PREFIX = \"indexing.lock.recovery.\";\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst VALID_OPERATIONS = new Set<IndexMutationOperation>([\n \"initialize\",\n \"index\",\n \"force-index\",\n \"clear\",\n \"health-check\",\n \"retry-failed-batches\",\n \"recovery\",\n]);\n\nlet temporaryCounter = 0;\n\nfunction getErrorCode(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : undefined;\n}\n\nfunction retryTransientFilesystemOperation(operation: () => void): void {\n let lastError: unknown;\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n operation();\n return;\n } catch (error) {\n lastError = error;\n const code = getErrorCode(error);\n if (code !== \"EBUSY\" && code !== \"EPERM\") throw error;\n if (attempt < 2) {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, (attempt + 1) * 10);\n }\n }\n }\n throw lastError;\n}\n\nfunction parseOwner(value: unknown): IndexLockOwner | null {\n if (typeof value !== \"object\" || value === null) return null;\n const candidate = value as Partial<IndexLockOwner>;\n if (!Number.isInteger(candidate.pid) || (candidate.pid ?? 0) <= 0) return null;\n if (typeof candidate.hostname !== \"string\" || candidate.hostname.length === 0) return null;\n if (typeof candidate.startedAt !== \"string\" || Number.isNaN(Date.parse(candidate.startedAt))) return null;\n if (typeof candidate.operation !== \"string\" || !VALID_OPERATIONS.has(candidate.operation as IndexMutationOperation)) return null;\n if (typeof candidate.token !== \"string\" || !UUID_PATTERN.test(candidate.token)) return null;\n if (candidate.recoveryProtocolVersion !== undefined && candidate.recoveryProtocolVersion !== 1) return null;\n if (candidate.projectRoot !== undefined && typeof candidate.projectRoot !== \"string\") return null;\n if (candidate.scopedRoots !== undefined) {\n if (!Array.isArray(candidate.scopedRoots) || candidate.scopedRoots.some((root) => typeof root !== \"string\")) {\n return null;\n }\n }\n if (candidate.clearRecovery !== undefined) {\n const recovery = candidate.clearRecovery as Partial<IndexLockClearRecoveryState>;\n if (\n typeof recovery !== \"object\"\n || recovery === null\n || recovery.phase !== \"clearing\"\n || typeof recovery.embeddingProvider !== \"string\"\n || recovery.embeddingProvider.length === 0\n || typeof recovery.embeddingModel !== \"string\"\n || recovery.embeddingModel.length === 0\n || !Number.isInteger(recovery.embeddingDimensions)\n || (recovery.embeddingDimensions ?? 0) <= 0\n || typeof recovery.embeddingStrategyVersion !== \"string\"\n || recovery.embeddingStrategyVersion.length === 0\n || (\n recovery.compatibilityDecision !== \"compatible\"\n && recovery.compatibilityDecision !== \"embedding-strategy-mismatch\"\n && recovery.compatibilityDecision !== \"incompatible\"\n )\n || (candidate.operation !== \"clear\" && candidate.operation !== \"force-index\")\n ) {\n return null;\n }\n }\n return candidate as IndexLockOwner;\n}\n\nfunction parseReclaimOwner(value: unknown): ReclaimOwner | null {\n if (typeof value !== \"object\" || value === null) return null;\n const candidate = value as Partial<ReclaimOwner>;\n if (!Number.isInteger(candidate.pid) || (candidate.pid ?? 0) <= 0) return null;\n if (typeof candidate.hostname !== \"string\" || candidate.hostname.length === 0) return null;\n if (typeof candidate.startedAt !== \"string\" || Number.isNaN(Date.parse(candidate.startedAt))) return null;\n if (typeof candidate.token !== \"string\" || !UUID_PATTERN.test(candidate.token)) return null;\n if (typeof candidate.expectedOwnerToken !== \"string\" || !UUID_PATTERN.test(candidate.expectedOwnerToken)) return null;\n return candidate as ReclaimOwner;\n}\n\nfunction readJsonDirectory<T>(directoryPath: string, parser: (value: unknown) => T | null): T | null {\n try {\n return parser(JSON.parse(readFileSync(path.join(directoryPath, OWNER_FILE_NAME), \"utf-8\")));\n } catch {\n return null;\n }\n}\n\nfunction readDirectoryOwner(lockPath: string): IndexLockOwner | null {\n return readJsonDirectory(lockPath, parseOwner);\n}\n\nfunction readReclaimOwner(markerPath: string): ReclaimOwner | null {\n return readJsonDirectory(markerPath, parseReclaimOwner);\n}\n\nfunction readRecoveryOwner(markerPath: string): IndexLockOwner | null {\n return readDirectoryOwner(markerPath);\n}\n\nfunction readLegacyOwner(lockPath: string): IndexLockOwner | null {\n try {\n const parsed = JSON.parse(readFileSync(lockPath, \"utf-8\")) as {\n pid?: unknown;\n startedAt?: unknown;\n hostname?: unknown;\n operation?: unknown;\n token?: unknown;\n };\n if (!Number.isInteger(parsed.pid) || Number(parsed.pid) <= 0) return null;\n if (typeof parsed.startedAt !== \"string\" || Number.isNaN(Date.parse(parsed.startedAt))) return null;\n return {\n pid: Number(parsed.pid),\n hostname: typeof parsed.hostname === \"string\" ? parsed.hostname : os.hostname(),\n startedAt: parsed.startedAt,\n operation: typeof parsed.operation === \"string\" && VALID_OPERATIONS.has(parsed.operation as IndexMutationOperation)\n ? parsed.operation as IndexMutationOperation\n : \"index\",\n token: typeof parsed.token === \"string\" ? parsed.token : \"legacy-v0.14.0\",\n };\n } catch {\n return null;\n }\n}\n\nfunction getOwnerLiveness(owner: Pick<IndexLockOwner, \"pid\" | \"hostname\">): OwnerLiveness {\n if (owner.hostname !== os.hostname()) return \"unknown\";\n try {\n process.kill(owner.pid, 0);\n return \"alive\";\n } catch (error) {\n const code = getErrorCode(error);\n if (code === \"ESRCH\") return \"dead\";\n if (code === \"EPERM\") return \"alive\";\n return \"unknown\";\n }\n}\n\nfunction sameOwner(left: IndexLockOwner, right: IndexLockOwner): boolean {\n return left.pid === right.pid && left.hostname === right.hostname && left.token === right.token;\n}\n\nfunction sameReclaimOwner(left: ReclaimOwner, right: ReclaimOwner): boolean {\n return left.pid === right.pid\n && left.hostname === right.hostname\n && left.token === right.token\n && left.expectedOwnerToken === right.expectedOwnerToken;\n}\n\nfunction publishJsonDirectory(finalPath: string, value: IndexLockOwner | ReclaimOwner): boolean {\n const candidatePath = `${finalPath}.candidate.${process.pid}.${randomUUID()}`;\n try {\n mkdirSync(candidatePath, { mode: 0o700 });\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") return false;\n throw error;\n }\n try {\n writeFileSync(path.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {\n encoding: \"utf-8\",\n flag: \"wx\",\n mode: 0o600,\n });\n if (existsSync(finalPath)) return false;\n try {\n renameSync(candidatePath, finalPath);\n return true;\n } catch (error) {\n if (existsSync(finalPath)) return false;\n if (getErrorCode(error) === \"ENOENT\") return false;\n throw error;\n }\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") return false;\n throw error;\n } finally {\n if (existsSync(candidatePath)) rmSync(candidatePath, { recursive: true, force: true });\n }\n}\n\nfunction createOwner(operation: IndexMutationOperation): IndexLockOwner {\n return {\n pid: process.pid,\n hostname: os.hostname(),\n startedAt: new Date().toISOString(),\n operation,\n token: randomUUID(),\n };\n}\n\nexport interface IndexLockRecoveryScope {\n projectRoot: string;\n scopedRoots: string[];\n}\n\nfunction recoveryMarkerPath(indexPath: string, owner: IndexLockOwner): string {\n return path.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);\n}\n\nfunction publishRecoveryMarker(indexPath: string, owner: IndexLockOwner): string {\n const markerPath = recoveryMarkerPath(indexPath, owner);\n if (!publishJsonDirectory(markerPath, owner)) {\n const markerOwner = readRecoveryOwner(markerPath);\n if (!markerOwner || !sameOwner(markerOwner, owner)) {\n throw new IndexLockContentionError(markerPath, markerOwner, \"unknown-owner\");\n }\n }\n return markerPath;\n}\n\nfunction getPendingRecoveries(indexPath: string): IndexLockRecovery[] {\n const recoveries: IndexLockRecovery[] = [];\n const markerNames = readdirSync(indexPath).filter((name) => {\n if (!name.startsWith(RECOVERY_MARKER_PREFIX)) return false;\n return UUID_PATTERN.test(name.slice(RECOVERY_MARKER_PREFIX.length));\n }).sort();\n for (const markerName of markerNames) {\n const markerPath = path.join(indexPath, markerName);\n const markerToken = markerName.slice(RECOVERY_MARKER_PREFIX.length);\n let markerStats;\n try {\n markerStats = lstatSync(markerPath);\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") continue;\n throw error;\n }\n if (!markerStats.isDirectory()) {\n throw new IndexLockContentionError(markerPath, null, \"unknown-owner\");\n }\n const owner = readRecoveryOwner(markerPath);\n if (!owner || owner.token !== markerToken || getOwnerLiveness(owner) !== \"dead\") {\n throw new IndexLockContentionError(markerPath, owner, \"unknown-owner\");\n }\n recoveries.push({ owner, markerPath });\n }\n recoveries.sort((left, right) => {\n const byTimestamp = left.owner.startedAt.localeCompare(right.owner.startedAt);\n return byTimestamp !== 0 ? byTimestamp : left.markerPath.localeCompare(right.markerPath);\n });\n return recoveries;\n}\n\nfunction cleanupDeadPublicationCandidates(indexPath: string): void {\n const candidatePattern = /^indexing\\.lock(?:\\.recovery\\.[0-9a-f-]{36})?\\.candidate\\.(\\d+)\\.[0-9a-f-]{36}$/i;\n for (const entry of readdirSync(indexPath)) {\n const match = candidatePattern.exec(entry);\n if (!match) continue;\n const pid = Number(match[1]);\n if (!Number.isInteger(pid) || pid <= 0) continue;\n if (getOwnerLiveness({ pid, hostname: os.hostname() }) !== \"dead\") continue;\n rmSync(path.join(indexPath, entry), { recursive: true, force: true });\n }\n}\n\nfunction removeDeadReclaimMarker(lockPath: string, expectedOwner: IndexLockOwner): boolean {\n const markerPath = path.join(lockPath, RECLAIM_DIRECTORY_NAME);\n const marker = readReclaimOwner(markerPath);\n if (!marker || marker.expectedOwnerToken !== expectedOwner.token || getOwnerLiveness(marker) !== \"dead\") {\n return false;\n }\n\n const currentOwner = readDirectoryOwner(lockPath);\n if (!currentOwner || !sameOwner(currentOwner, expectedOwner) || getOwnerLiveness(currentOwner) !== \"dead\") {\n return false;\n }\n\n const claimedMarkerPath = `${markerPath}.stale.${marker.pid}.${marker.token}.${randomUUID()}`;\n try {\n renameSync(markerPath, claimedMarkerPath);\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") return false;\n throw error;\n }\n\n const claimedMarker = readReclaimOwner(claimedMarkerPath);\n const ownerAfterClaim = readDirectoryOwner(lockPath);\n if (!claimedMarker\n || !sameReclaimOwner(claimedMarker, marker)\n || !ownerAfterClaim\n || !sameOwner(ownerAfterClaim, expectedOwner)\n || getOwnerLiveness(ownerAfterClaim) !== \"dead\") {\n if (!existsSync(markerPath) && existsSync(claimedMarkerPath)) {\n renameSync(claimedMarkerPath, markerPath);\n }\n return false;\n }\n\n rmSync(claimedMarkerPath, { recursive: true, force: true });\n return true;\n}\n\nfunction reclaimDeadOwner(indexPath: string, lockPath: string, expectedOwner: IndexLockOwner): boolean {\n const reclaimPath = path.join(lockPath, RECLAIM_DIRECTORY_NAME);\n const reclaimOwner: ReclaimOwner = {\n pid: process.pid,\n hostname: os.hostname(),\n startedAt: new Date().toISOString(),\n token: randomUUID(),\n expectedOwnerToken: expectedOwner.token,\n };\n\n for (let attempt = 0; attempt < 2; attempt += 1) {\n if (publishJsonDirectory(reclaimPath, reclaimOwner)) break;\n if (attempt === 0 && removeDeadReclaimMarker(lockPath, expectedOwner)) continue;\n return false;\n }\n\n try {\n const currentReclaimer = readReclaimOwner(reclaimPath);\n const currentOwner = readDirectoryOwner(lockPath);\n if (!currentReclaimer\n || !sameReclaimOwner(currentReclaimer, reclaimOwner)\n || !currentOwner\n || !sameOwner(currentOwner, expectedOwner)\n || getOwnerLiveness(currentOwner) !== \"dead\") {\n return false;\n }\n\n publishRecoveryMarker(indexPath, expectedOwner);\n\n const ownerBeforeQuarantine = readDirectoryOwner(lockPath);\n const reclaimerBeforeQuarantine = readReclaimOwner(reclaimPath);\n if (!ownerBeforeQuarantine\n || !sameOwner(ownerBeforeQuarantine, expectedOwner)\n || getOwnerLiveness(ownerBeforeQuarantine) !== \"dead\"\n || !reclaimerBeforeQuarantine\n || !sameReclaimOwner(reclaimerBeforeQuarantine, reclaimOwner)) {\n return false;\n }\n\n const quarantinePath = `${lockPath}.stale.${expectedOwner.token}.${reclaimOwner.token}`;\n renameSync(lockPath, quarantinePath);\n rmSync(quarantinePath, { recursive: true, force: true });\n return true;\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") return false;\n throw error;\n }\n}\n\nexport class IndexLockContentionError extends Error {\n readonly code = \"INDEX_BUSY\";\n\n constructor(\n readonly lockPath: string,\n readonly owner: IndexLockOwner | null,\n readonly reason: \"active\" | \"unknown-owner\" | \"legacy-lock\" | \"reclaiming\",\n ) {\n const ownerDescription = owner\n ? `PID ${owner.pid} on ${owner.hostname}, operation ${owner.operation}, since ${owner.startedAt}`\n : \"an unreadable owner\";\n super(`Index mutation already in progress: ${ownerDescription}`);\n this.name = \"IndexLockContentionError\";\n }\n}\n\nexport function isIndexLockContentionError(error: unknown): error is IndexLockContentionError {\n return error instanceof IndexLockContentionError\n || (typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: unknown }).code === \"INDEX_BUSY\");\n}\n\nexport function isTransientIndexLockContention(error: unknown): boolean {\n if (!isIndexLockContentionError(error) || !(\"reason\" in error)) return false;\n return error.reason === \"active\" || error.reason === \"reclaiming\";\n}\n\nexport function acquireIndexLock(\n indexPath: string,\n operation: IndexMutationOperation,\n recoveryScope?: IndexLockRecoveryScope,\n): IndexLockLease {\n mkdirSync(indexPath, { recursive: true });\n const canonicalIndexPath = realpathSync.native(indexPath);\n const lockPath = path.join(canonicalIndexPath, \"indexing.lock\");\n cleanupDeadPublicationCandidates(canonicalIndexPath);\n\n for (let attempt = 0; attempt < 6; attempt += 1) {\n const owner = recoveryScope === undefined\n ? createOwner(operation)\n : {\n ...createOwner(operation),\n recoveryProtocolVersion: 1 as const,\n projectRoot: recoveryScope.projectRoot,\n scopedRoots: recoveryScope.scopedRoots,\n };\n if (publishJsonDirectory(lockPath, owner)) {\n const lease: IndexLockLease = {\n canonicalIndexPath,\n lockPath,\n owner,\n recoveries: [],\n };\n try {\n lease.recoveries = getPendingRecoveries(canonicalIndexPath);\n return lease;\n } catch (error) {\n releaseIndexLock(lease);\n throw error;\n }\n }\n\n let stats;\n try {\n stats = lstatSync(lockPath);\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") continue;\n throw error;\n }\n\n if (!stats.isDirectory()) {\n const legacyOwner = readLegacyOwner(lockPath);\n throw new IndexLockContentionError(lockPath, legacyOwner, \"legacy-lock\");\n }\n\n const existingOwner = readDirectoryOwner(lockPath);\n if (!existingOwner) {\n throw new IndexLockContentionError(lockPath, null, \"unknown-owner\");\n }\n\n const liveness = getOwnerLiveness(existingOwner);\n if (liveness !== \"dead\") {\n throw new IndexLockContentionError(lockPath, existingOwner, liveness === \"alive\" ? \"active\" : \"unknown-owner\");\n }\n\n if (!reclaimDeadOwner(canonicalIndexPath, lockPath, existingOwner)) {\n throw new IndexLockContentionError(lockPath, existingOwner, \"reclaiming\");\n }\n }\n\n throw new IndexLockContentionError(lockPath, null, \"reclaiming\");\n}\n\nexport function releaseIndexLock(lease: IndexLockLease): boolean {\n const currentOwner = readDirectoryOwner(lease.lockPath);\n if (!currentOwner || !sameOwner(currentOwner, lease.owner)) return false;\n\n const releasePath = `${lease.lockPath}.release.${lease.owner.pid}.${lease.owner.token}`;\n try {\n retryTransientFilesystemOperation(() => renameSync(lease.lockPath, releasePath));\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") return false;\n throw error;\n }\n\n const claimedOwner = readDirectoryOwner(releasePath);\n if (!claimedOwner || !sameOwner(claimedOwner, lease.owner)) {\n if (!existsSync(lease.lockPath) && existsSync(releasePath)) {\n renameSync(releasePath, lease.lockPath);\n }\n return false;\n }\n\n try {\n retryTransientFilesystemOperation(() => rmSync(releasePath, { recursive: true, force: true }));\n } catch (error) {\n console.error(`[codebase-index] Lease released but tombstone cleanup failed: ${releasePath}`, error);\n }\n return true;\n}\n\nexport function setIndexLockClearRecoveryState(\n lease: IndexLockLease,\n clearRecovery: IndexLockClearRecoveryState | null,\n): void {\n const currentOwner = readDirectoryOwner(lease.lockPath);\n if (!currentOwner || !sameOwner(currentOwner, lease.owner)) {\n throw new Error(`Lost ownership of index mutation lease ${lease.owner.token}`);\n }\n\n const nextOwner: IndexLockOwner = { ...currentOwner };\n if (clearRecovery === null) {\n delete nextOwner.clearRecovery;\n } else {\n nextOwner.clearRecovery = clearRecovery;\n }\n\n const ownerPath = path.join(lease.lockPath, OWNER_FILE_NAME);\n const temporaryPath = path.join(\n lease.lockPath,\n `${OWNER_FILE_NAME}.tmp.${lease.owner.pid}.${lease.owner.token}.${randomUUID()}`,\n );\n try {\n writeFileSync(temporaryPath, JSON.stringify(nextOwner), {\n encoding: \"utf-8\",\n flag: \"wx\",\n mode: 0o600,\n });\n retryTransientFilesystemOperation(() => renameSync(temporaryPath, ownerPath));\n } finally {\n if (existsSync(temporaryPath)) rmSync(temporaryPath, { force: true });\n }\n}\n\nexport async function withIndexLock<T>(\n indexPath: string,\n operation: IndexMutationOperation,\n callback: (lease: IndexLockLease) => Promise<T> | T,\n options: { completeRecoveries?: boolean; recoveryScope?: IndexLockRecoveryScope } = {},\n): Promise<T> {\n const lease = acquireIndexLock(indexPath, operation, options.recoveryScope);\n let result: T | undefined;\n let callbackError: unknown;\n let callbackFailed = false;\n try {\n result = await callback(lease);\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n if (!callbackFailed && options.completeRecoveries !== false) {\n try {\n completeLeaseRecovery(lease);\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n }\n\n let releaseError: unknown;\n try {\n if (!releaseIndexLock(lease)) {\n releaseError = new Error(`Lost ownership of index mutation lease ${lease.owner.token}`);\n }\n } catch (error) {\n releaseError = error;\n }\n if (releaseError !== undefined) {\n if (callbackFailed) throw new AggregateError([callbackError, releaseError], \"Index mutation and lease release both failed\");\n throw releaseError;\n }\n if (callbackFailed) throw callbackError;\n return result as T;\n}\n\nexport function createLeaseTemporaryPath(\n targetPath: string,\n owner: IndexLockOwner,\n kind: \"tmp\" | \"bak\" = \"tmp\",\n): string {\n if (kind === \"bak\") return `${targetPath}.bak.${owner.pid}.${owner.token}`;\n temporaryCounter += 1;\n return `${targetPath}.tmp.${owner.pid}.${owner.token}.${temporaryCounter}`;\n}\n\nexport function removeLeaseTemporaryPath(temporaryPath: string): void {\n if (existsSync(temporaryPath)) rmSync(temporaryPath, { recursive: true, force: true });\n}\n\nexport function recoverLeaseArtifacts(\n indexPath: string,\n owner: IndexLockOwner,\n backupTargets: string[],\n): void {\n for (const targetPath of backupTargets) {\n const backupPath = createLeaseTemporaryPath(targetPath, owner, \"bak\");\n if (!existsSync(backupPath)) continue;\n if (existsSync(targetPath)) rmSync(targetPath, { recursive: true, force: true });\n renameSync(backupPath, targetPath);\n }\n\n const temporaryOwnerMarker = `.tmp.${owner.pid}.${owner.token}.`;\n for (const entry of readdirSync(indexPath)) {\n if (!entry.includes(temporaryOwnerMarker)) continue;\n rmSync(path.join(indexPath, entry), { recursive: true, force: true });\n }\n}\n\nexport function completeLeaseRecovery(lease: IndexLockLease): void {\n for (const recovery of lease.recoveries) {\n const markerOwner = readRecoveryOwner(recovery.markerPath);\n if (!markerOwner || !sameOwner(markerOwner, recovery.owner)) {\n throw new Error(`Recovery marker ownership changed: ${recovery.markerPath}`);\n }\n }\n for (const recovery of lease.recoveries) {\n rmSync(recovery.markerPath, { recursive: true, force: true });\n }\n}\n","import ignore, { Ignore } from \"ignore\";\nimport { existsSync, readFileSync, promises as fsPromises } from \"fs\";\nimport * as path from \"path\";\n\nimport { hasFilteredPathSegment, isBuildPathSegment, isHiddenPathSegment } from \"./paths.js\";\n\nconst PROJECT_MARKERS = [\n \".git\",\n \"package.json\",\n \"Cargo.toml\",\n \"go.mod\",\n \"pyproject.toml\",\n \"setup.py\",\n \"requirements.txt\",\n \"Gemfile\",\n \"composer.json\",\n \"pom.xml\",\n \"build.gradle\",\n \"CMakeLists.txt\",\n \"Makefile\",\n];\n\nexport function hasProjectMarker(projectRoot: string): boolean {\n for (const marker of PROJECT_MARKERS) {\n if (existsSync(path.join(projectRoot, marker))) {\n return true;\n }\n }\n return false;\n}\n\nexport interface SkippedFile {\n path: string;\n reason: \"too_large\" | \"excluded\" | \"gitignore\" | \"no_match\" | \"unreadable\";\n}\n\nexport interface CollectFilesResult {\n files: Array<{ path: string; size: number }>;\n skipped: SkippedFile[];\n}\n\nexport function createIgnoreFilter(projectRoot: string): Ignore {\n const ig = ignore();\n\n const defaultIgnores = [\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \".next\",\n \".nuxt\",\n \"coverage\",\n \"__pycache__\",\n \"target\",\n \"vendor\",\n \".opencode\",\n \".codebase-index\",\n \".*\",\n \"**/.*\",\n \"**/.*/**\",\n \"**/*build*/**\",\n ];\n\n ig.add(defaultIgnores);\n\n const gitignorePath = path.join(projectRoot, \".gitignore\");\n if (existsSync(gitignorePath)) {\n const gitignoreContent = readFileSync(gitignorePath, \"utf-8\");\n ig.add(gitignoreContent);\n }\n\n return ig;\n}\n\nexport function shouldIncludeFile(\n filePath: string,\n projectRoot: string,\n includePatterns: string[],\n excludePatterns: string[],\n ignoreFilter: Ignore\n): boolean {\n const relativePath = path.relative(projectRoot, filePath);\n\n if (hasFilteredPathSegment(relativePath, path.sep)) {\n return false;\n }\n\n if (ignoreFilter.ignores(relativePath)) {\n return false;\n }\n\n for (const pattern of excludePatterns) {\n if (matchGlob(relativePath, pattern)) {\n return false;\n }\n }\n\n for (const pattern of includePatterns) {\n if (matchGlob(relativePath, pattern)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction matchGlob(filePath: string, pattern: string): boolean {\n if (pattern.startsWith(\"**/\")) {\n const withoutPrefix = pattern.slice(3);\n if (withoutPrefix && matchGlob(filePath, withoutPrefix)) {\n return true;\n }\n }\n\n const escapedPattern = pattern.replace(/[.+^$()|[\\]\\\\]/g, \"\\\\$&\");\n\n let regexPattern = escapedPattern\n .replace(/\\*\\*/g, \"<<<DOUBLESTAR>>>\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/<<<DOUBLESTAR>>>/g, \".*\")\n .replace(/\\?/g, \".\")\n .replace(/\\{([^}]+)\\}/g, (_, p1) => `(${p1.split(\",\").join(\"|\")})`);\n\n // **/*.js → matches both root \"file.js\" and nested \"dir/file.js\"\n if (regexPattern.startsWith(\".*/\")) {\n regexPattern = `(.*\\\\/)?${regexPattern.slice(3)}`;\n }\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(filePath);\n}\n\nexport interface WalkOptions {\n maxDepth: number;\n maxFilesPerDirectory: number;\n}\n\nexport async function* walkDirectory(\n dir: string,\n projectRoot: string,\n includePatterns: string[],\n excludePatterns: string[],\n ignoreFilter: Ignore,\n maxFileSize: number,\n skipped: SkippedFile[],\n options: WalkOptions,\n currentDepth: number = 0\n): AsyncGenerator<{ path: string; size: number }> {\n const entries = await fsPromises.readdir(dir, { withFileTypes: true });\n\n const filesInDir: Array<{ path: string; size: number }> = [];\n const subdirs: Array<{ fullPath: string; relativePath: string }> = [];\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relativePath = path.relative(projectRoot, fullPath);\n\n if (isHiddenPathSegment(entry.name)) {\n if (entry.isDirectory()) {\n skipped.push({ path: relativePath, reason: \"excluded\" });\n }\n continue;\n }\n\n if (entry.isDirectory() && isBuildPathSegment(entry.name)) {\n skipped.push({ path: relativePath, reason: \"excluded\" });\n continue;\n }\n\n if (ignoreFilter.ignores(relativePath)) {\n if (entry.isFile()) {\n skipped.push({ path: relativePath, reason: \"gitignore\" });\n }\n continue;\n }\n\n if (entry.isDirectory()) {\n subdirs.push({ fullPath, relativePath });\n } else if (entry.isFile()) {\n const stat = await fsPromises.stat(fullPath);\n\n if (stat.size > maxFileSize) {\n skipped.push({ path: relativePath, reason: \"too_large\" });\n continue;\n }\n\n for (const pattern of excludePatterns) {\n if (matchGlob(relativePath, pattern)) {\n skipped.push({ path: relativePath, reason: \"excluded\" });\n continue;\n }\n }\n\n let matched = false;\n for (const pattern of includePatterns) {\n if (matchGlob(relativePath, pattern)) {\n matched = true;\n break;\n }\n }\n\n if (matched) {\n filesInDir.push({ path: fullPath, size: stat.size });\n }\n }\n }\n\n filesInDir.sort((a, b) => a.size - b.size);\n const limitedFiles = filesInDir.slice(0, options.maxFilesPerDirectory);\n for (const f of limitedFiles) {\n yield f;\n }\n for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {\n skipped.push({ path: path.relative(projectRoot, filesInDir[i].path), reason: \"excluded\" });\n }\n\n const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;\n if (canRecurse) {\n for (const sub of subdirs) {\n yield* walkDirectory(\n sub.fullPath,\n projectRoot,\n includePatterns,\n excludePatterns,\n ignoreFilter,\n maxFileSize,\n skipped,\n options,\n currentDepth + 1\n );\n }\n }\n}\n\nexport async function collectFiles(\n projectRoot: string,\n includePatterns: string[],\n excludePatterns: string[],\n maxFileSize: number,\n additionalRoots?: string[],\n walkOptions?: WalkOptions\n): Promise<CollectFilesResult> {\n const opts: WalkOptions = walkOptions ?? { maxDepth: 5, maxFilesPerDirectory: 100 };\n const ignoreFilter = createIgnoreFilter(projectRoot);\n const files: Array<{ path: string; size: number }> = [];\n const skipped: SkippedFile[] = [];\n\n for await (const file of walkDirectory(\n projectRoot,\n projectRoot,\n includePatterns,\n excludePatterns,\n ignoreFilter,\n maxFileSize,\n skipped,\n opts,\n 0\n )) {\n files.push(file);\n }\n\n if (additionalRoots && additionalRoots.length > 0) {\n const normalizedRoots = new Set<string>();\n for (const kbRoot of additionalRoots) {\n const resolved = path.normalize(\n path.isAbsolute(kbRoot) ? kbRoot : path.resolve(projectRoot, kbRoot)\n );\n normalizedRoots.add(resolved);\n }\n\n for (const resolvedKbRoot of normalizedRoots) {\n try {\n const stat = await fsPromises.stat(resolvedKbRoot);\n if (!stat.isDirectory()) {\n skipped.push({ path: resolvedKbRoot, reason: \"excluded\" });\n continue;\n }\n const kbIgnoreFilter = createIgnoreFilter(resolvedKbRoot);\n for await (const file of walkDirectory(\n resolvedKbRoot,\n resolvedKbRoot,\n includePatterns,\n excludePatterns,\n kbIgnoreFilter,\n maxFileSize,\n skipped,\n opts,\n 0\n )) {\n files.push(file);\n }\n } catch {\n skipped.push({ path: resolvedKbRoot, reason: \"excluded\" });\n }\n }\n }\n\n return { files, skipped };\n}\n","import * as childProcess from \"child_process\";\n\nexport type MacOsPowerSource = \"ac\" | \"battery\" | \"unknown\";\n\nexport interface BackgroundIndexingPolicy {\n readonly recheckDelayMs: number;\n isPaused(): Promise<boolean>;\n}\n\ntype PowerSourceReader = () => Promise<MacOsPowerSource>;\ntype CommandRunner = (\n file: string,\n args: string[],\n options: { timeoutMs: number },\n) => Promise<string>;\n\ninterface BackgroundIndexingPolicyOptions {\n platform?: NodeJS.Platform;\n readPowerSource?: PowerSourceReader;\n recheckDelayMs?: number;\n}\n\nconst POWER_SOURCE_RECHECK_DELAY_MS = 60_000;\nconst PMSET_TIMEOUT_MS = 5_000;\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction runCommand(\n file: string,\n args: string[],\n options: { timeoutMs: number },\n): Promise<string> {\n return new Promise((resolve, reject) => {\n childProcess.execFile(\n file,\n args,\n { encoding: \"utf8\", timeout: options.timeoutMs },\n (error, stdout) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nexport function parseMacOsPowerSource(output: string): MacOsPowerSource {\n const match = output.match(/Now drawing from '([^']+)'/i);\n if (!match) {\n return \"unknown\";\n }\n\n const source = match[1].toLowerCase();\n if (source === \"battery power\") {\n return \"battery\";\n }\n if (source === \"ac power\") {\n return \"ac\";\n }\n return \"unknown\";\n}\n\nexport async function readMacOsPowerSource(\n commandRunner: CommandRunner = runCommand,\n): Promise<MacOsPowerSource> {\n const output = await commandRunner(\n \"/usr/bin/pmset\",\n [\"-g\", \"batt\"],\n { timeoutMs: PMSET_TIMEOUT_MS },\n );\n return parseMacOsPowerSource(output);\n}\n\nclass MacOsBackgroundIndexingPolicy implements BackgroundIndexingPolicy {\n private lastPaused: boolean | null = null;\n private reportedFailure = false;\n\n constructor(\n private readonly readPowerSource: PowerSourceReader,\n readonly recheckDelayMs: number,\n ) {}\n\n isPaused(): Promise<boolean> {\n return this.checkPowerSource();\n }\n\n private async checkPowerSource(): Promise<boolean> {\n try {\n const source = await this.readPowerSource();\n if (source === \"unknown\") {\n throw new Error(\"pmset returned an unrecognized power source\");\n }\n\n this.reportedFailure = false;\n const paused = source === \"battery\";\n if (paused && this.lastPaused !== true) {\n console.warn(\"[codebase-index] Background indexing paused while macOS is using battery power.\");\n } else if (!paused && this.lastPaused === true) {\n console.warn(\"[codebase-index] AC power detected; resuming pending background indexing.\");\n }\n this.lastPaused = paused;\n return paused;\n } catch (error) {\n if (!this.reportedFailure) {\n console.error(\n `[codebase-index] Failed to determine the macOS power source; background indexing will continue: ${getErrorMessage(error)}`,\n );\n this.reportedFailure = true;\n }\n this.lastPaused = false;\n return false;\n }\n }\n}\n\nexport function createBackgroundIndexingPolicy(\n pauseOnBattery: boolean,\n options: BackgroundIndexingPolicyOptions = {},\n): BackgroundIndexingPolicy | null {\n const platform = options.platform ?? process.platform;\n if (!pauseOnBattery || platform !== \"darwin\") {\n return null;\n }\n\n return new MacOsBackgroundIndexingPolicy(\n options.readPowerSource ?? readMacOsPowerSource,\n options.recheckDelayMs ?? POWER_SOURCE_RECHECK_DELAY_MS,\n );\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"fs\";\nimport * as path from \"path\";\n\nimport { loadMergedConfig, loadProjectConfigLayer } from \"../config/merger.js\";\nimport { resolveWritableProjectConfigPath } from \"../config/paths.js\";\nimport { resolveConfigPathValue, serializeConfigPathValue } from \"./knowledge-base-paths.js\";\nimport type { HostMode } from \"../config/host.js\";\n\nfunction normalizeKnowledgeBasePaths(\n config: Record<string, unknown>,\n projectRoot: string,\n): Record<string, unknown> {\n const normalized = { ...config };\n\n if (Array.isArray(normalized.knowledgeBases)) {\n normalized.knowledgeBases = (normalized.knowledgeBases as string[]).map((kb) =>\n resolveConfigPathValue(kb, projectRoot)\n );\n }\n\n return normalized;\n}\n\nfunction toConfigRecord(rawConfig: unknown): Record<string, unknown> {\n if (!rawConfig || typeof rawConfig !== \"object\") {\n return {};\n }\n\n return { ...(rawConfig as Record<string, unknown>) };\n}\n\nexport function getConfigPath(projectRoot: string, host: HostMode): string {\n return resolveWritableProjectConfigPath(projectRoot, host);\n}\n\nexport function loadRuntimeConfig(projectRoot: string, host: HostMode): Record<string, unknown> {\n return normalizeKnowledgeBasePaths(toConfigRecord(loadMergedConfig(projectRoot, host)), projectRoot);\n}\n\nexport function loadEditableConfig(projectRoot: string, host: HostMode): Record<string, unknown> {\n return normalizeKnowledgeBasePaths(toConfigRecord(loadProjectConfigLayer(projectRoot, host)), projectRoot);\n}\n\nexport function saveConfig(projectRoot: string, config: Record<string, unknown>, host: HostMode): void {\n const configPath = getConfigPath(projectRoot, host);\n const configDir = path.dirname(configPath);\n const configBaseDir = path.dirname(configDir);\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n\n const serializableConfig: Record<string, unknown> = { ...config };\n\n if (Array.isArray(serializableConfig.knowledgeBases)) {\n serializableConfig.knowledgeBases = (serializableConfig.knowledgeBases as string[]).map((kb) =>\n serializeConfigPathValue(kb, configBaseDir)\n );\n }\n\n writeFileSync(configPath, JSON.stringify(serializableConfig, null, 2) + \"\\n\", \"utf-8\");\n}\n","import { existsSync, readFileSync, statSync, writeFileSync, renameSync, unlinkSync, mkdirSync, promises as fsPromises } from \"fs\";\nimport * as path from \"path\";\nimport { performance } from \"perf_hooks\";\nimport { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport PQueue from \"p-queue\";\nimport pRetry from \"p-retry\";\n\nimport { type EmbeddingBatchConfig, ParsedCodebaseIndexConfig, type RerankerConfig } from \"../config/schema.js\";\nimport { detectEmbeddingProvider, ConfiguredProviderInfo, tryDetectProvider, createCustomProviderInfo } from \"../embeddings/detector.js\";\nimport {\n createEmbeddingProvider,\n EmbeddingProviderInterface,\n CustomProviderNonRetryableError,\n} from \"../embeddings/provider.js\";\nimport { collectFiles, SkippedFile } from \"../utils/files.js\";\nimport { createCostEstimate, CostEstimate, DryRunEstimate } from \"../utils/cost.js\";\nimport { Logger, initializeLogger } from \"../utils/logger.js\";\nimport {\n VectorStore,\n InvertedIndex,\n Database,\n parseFiles,\n createEmbeddingTexts,\n generateChunkId,\n generateChunkHash,\n ChunkMetadata,\n ChunkData,\n hashFile,\n hashContent,\n extractCalls,\n parseFileAsText,\n estimateTokens,\n} from \"../native/index.js\";\nimport type { SymbolData, CallEdgeData, PathHopData, ReachabilityData, CommunityData, CommunityCouplingData, CentralityData } from \"../native/index.js\";\nimport { getBranchOrDefault, getBaseBranch, isGitRepo } from \"../git/index.js\";\nimport { isFullGitCommit, resolveLocalGitCommit, withMaterializedBranch } from \"../git/branch-materialization.js\";\nimport type { HostMode } from \"../config/host.js\";\nimport { isProjectIndexPathOwnedByProject, resolveProjectIndexPath } from \"../config/paths.js\";\nimport { getChangedFiles } from \"../tools/changed-files.js\";\nimport type { PrImpactResult } from \"./pr-impact-types.js\";\nimport { getChunkGitBlame, type GitBlameMetadata } from \"./git-blame.js\";\nimport { analyzeQueryIntent } from \"./intent-aware-ranking.js\";\nimport {\n applyCommunityBoost,\n classifyQueryIntentRaw,\n diversifyCandidatesByFile,\n rankHybridResults,\n rankSemanticOnlyResults,\n type RankedCandidate,\n} from \"./search-ranking.js\";\nexport {\n applyCommunityBoost,\n fuseResultsRrf,\n fuseResultsWeighted,\n rankHybridResults,\n rankSemanticOnlyResults,\n rerankResults,\n} from \"./search-ranking.js\";\nimport { inferExactSymbolFromQuery } from \"../tools/symbol-inference.js\";\nimport { CALL_GRAPH_SYMBOL_CHUNK_TYPES } from \"./call-graph-constants.js\";\nexport { CALL_GRAPH_SYMBOL_CHUNK_TYPES } from \"./call-graph-constants.js\";\nimport {\n buildDeterministicIdentifierPass,\n buildIdentifierDefinitionLane,\n classifyExternalRerankBand,\n extractCodeTermHints,\n extractFilePathHint,\n extractIdentifierHints,\n extractPrimaryIdentifierQueryHint,\n isImplementationChunkType,\n isLikelyImplementationPath,\n pathMatchesHint,\n splitPathTokens,\n stripFilePathHint,\n tokenizeTextForRanking,\n type ExternalRerankBand,\n} from \"./definition-ranking.js\";\nexport { extractFilePathHint, stripFilePathHint } from \"./definition-ranking.js\";\nimport {\n acquireIndexLock,\n completeLeaseRecovery,\n createLeaseTemporaryPath,\n recoverLeaseArtifacts,\n releaseIndexLock,\n removeLeaseTemporaryPath,\n setIndexLockClearRecoveryState,\n type IndexLockClearRecoveryState,\n type IndexLockLease,\n type IndexLockOwner,\n type IndexMutationOperation,\n} from \"./index-lock.js\";\nimport {\n type PendingChunk,\n type SerializedFailedBatch,\n createPendingChunkStorageText,\n createPendingEmbeddingRequestBatches,\n getPendingChunkFilePath,\n getUniquePendingChunksFromRequests,\n hasAllEmbeddingParts,\n normalizeFailedBatch,\n poolEmbeddingVectors,\n} from \"./embedding-batches.js\";\nimport {\n createFailedBatchWriter,\n readFailedBatchRecords,\n writeFailedBatchRecords,\n type FailedBatchRecordInput,\n type FailedBatchWriter,\n} from \"./failed-state-persistence.js\";\nimport { iterateOrderedFileBatches, type FileBatchLimits } from \"./file-batches.js\";\nimport { canonicalizePathForComparison } from \"../utils/canonical-path.js\";\n\nexport const CALL_GRAPH_LANGUAGES = new Set([\"typescript\", \"tsx\", \"javascript\", \"jsx\", \"python\", \"go\", \"rust\", \"swift\", \"php\", \"apex\", \"zig\", \"gdscript\", \"matlab\", \"bash\", \"c\", \"cpp\", \"metal\"]);\n// Languages whose identifiers are case-insensitive at the language level.\n// The Rust call_extractor lowercases callee names for these languages (except\n// constructors and imports), so same-file resolution in this file must use\n// the same normalization when looking up symbols by name. Keep this set in\n// sync with the matching branch in native/src/call_extractor.rs.\nexport const CASE_INSENSITIVE_LANGUAGES = new Set([\"apex\", \"php\"]);\n\nfunction candidateOverlapsSymbol(candidate: RankedCandidate, symbol: SymbolData): boolean {\n return candidate.metadata.filePath === symbol.filePath &&\n candidate.metadata.startLine <= symbol.endLine &&\n candidate.metadata.endLine >= symbol.startLine;\n}\n\nfunction resolveSameCommunityCandidateIds(\n query: string,\n candidates: RankedCandidate[],\n database: Database,\n branchCatalogKeys: string[],\n): Set<string> {\n const anchorName = inferExactSymbolFromQuery(query);\n if (!anchorName || candidates.length === 0) {\n return new Set();\n }\n\n const catalogs = branchCatalogKeys.map((branchKey) => ({\n branchKey,\n symbols: database.getSymbolsForBranch(branchKey),\n }));\n const exactAnchors = catalogs.flatMap(({ branchKey, symbols }) => symbols\n .filter((symbol) => symbol.name === anchorName)\n .map((symbol) => ({ branchKey, symbol })));\n const anchors = exactAnchors.length > 0\n ? exactAnchors\n : catalogs.flatMap(({ branchKey, symbols }) => symbols\n .filter((symbol) => symbol.name.toLowerCase() === anchorName.toLowerCase())\n .map((symbol) => ({ branchKey, symbol })));\n\n const uniqueAnchors = new Map(anchors.map((anchor) => [anchor.symbol.id, anchor]));\n if (uniqueAnchors.size !== 1) {\n return new Set();\n }\n\n const anchor = uniqueAnchors.values().next().value as { branchKey: string; symbol: SymbolData };\n const branchSymbols = catalogs.find((catalog) => catalog.branchKey === anchor.branchKey)?.symbols ?? [];\n const candidateSymbols = branchSymbols.filter((symbol) =>\n candidates.some((candidate) => candidateOverlapsSymbol(candidate, symbol))\n );\n const assignments = database.detectCommunities(\n anchor.branchKey,\n [anchor.symbol.id, ...candidateSymbols.map((symbol) => symbol.id)],\n );\n const anchorCommunity = assignments.find((assignment) => assignment.symbolId === anchor.symbol.id)?.communityId;\n if (anchorCommunity === undefined) {\n return new Set();\n }\n\n const sameCommunitySymbolIds = new Set(assignments\n .filter((assignment) => assignment.communityId === anchorCommunity)\n .map((assignment) => assignment.symbolId));\n\n return new Set(candidates\n .filter((candidate) => candidateSymbols.some((symbol) =>\n sameCommunitySymbolIds.has(symbol.id) && candidateOverlapsSymbol(candidate, symbol)\n ))\n .map((candidate) => candidate.id));\n}\n// Existing indexes without this metadata are the implicit version 1.\nconst CALL_GRAPH_RESOLUTION_VERSION = \"4\";\nconst PHP_FUNCTION_SYMBOL_CHUNK_TYPES = new Set([\n \"function_declaration\",\n \"function\",\n \"function_definition\",\n]);\nconst PHP_CLASS_SYMBOL_CHUNK_TYPES = new Set([\n \"class_declaration\",\n \"class_definition\",\n]);\nconst C_FAMILY_TYPE_SYMBOL_CHUNK_TYPES = new Set([\"class_specifier\", \"struct_specifier\"]);\n\nfunction isCompatibleCFamilyCallTarget(\n language: string,\n callType: string,\n symbolKind: string,\n): boolean {\n if (language !== \"c\" && language !== \"cpp\") return true;\n if (symbolKind === \"namespace_definition\") return callType === \"Import\";\n const isTypeSymbol = C_FAMILY_TYPE_SYMBOL_CHUNK_TYPES.has(symbolKind);\n if (callType === \"Constructor\" || callType === \"Inherits\" || callType === \"Implements\") {\n return isTypeSymbol;\n }\n return !isTypeSymbol;\n}\n\nconst EXECUTABLE_SYMBOL_CHUNK_TYPES = new Set([\n \"function_declaration\",\n \"function\",\n \"arrow_function\",\n \"method_definition\",\n \"function_definition\",\n \"method_declaration\",\n \"function_item\",\n \"protocol_function_declaration\",\n \"init_declaration\",\n \"deinit_declaration\",\n \"subscript_declaration\",\n \"constructor_definition\",\n \"trigger_declaration\",\n \"test_declaration\",\n]);\n\n// A type and its methods often cover the same lines. The shortest range is the\n// most precise symbol to own an edge. For equal ranges, executable symbols are\n// more specific than container types.\nexport function findEnclosingSymbol(\n symbols: readonly SymbolData[],\n line: number,\n column?: number,\n): SymbolData | undefined {\n let best: SymbolData | undefined;\n\n for (const symbol of symbols) {\n if (line < symbol.startLine || line > symbol.endLine) continue;\n if (\n column !== undefined &&\n ((line === symbol.startLine && column < symbol.startCol) ||\n (line === symbol.endLine && column >= symbol.endCol))\n ) {\n continue;\n }\n if (!best) {\n best = symbol;\n continue;\n }\n\n const span = symbol.endLine - symbol.startLine;\n const bestSpan = best.endLine - best.startLine;\n const isNarrowerPositionRange = column !== undefined &&\n span === bestSpan &&\n symbol.startLine === best.startLine &&\n symbol.endLine === best.endLine &&\n symbol.startCol >= best.startCol &&\n symbol.endCol <= best.endCol &&\n (symbol.startCol > best.startCol || symbol.endCol < best.endCol);\n const isMoreSpecificTie = span === bestSpan &&\n symbol.startLine === best.startLine &&\n EXECUTABLE_SYMBOL_CHUNK_TYPES.has(symbol.kind) &&\n !EXECUTABLE_SYMBOL_CHUNK_TYPES.has(best.kind);\n if (\n span < bestSpan ||\n (span === bestSpan && symbol.startLine > best.startLine) ||\n isNarrowerPositionRange ||\n isMoreSpecificTie\n ) {\n best = symbol;\n }\n }\n\n return best;\n}\n\nfunction float32ArrayToBuffer(arr: number[]): Buffer {\n const float32 = new Float32Array(arr);\n return Buffer.from(float32.buffer);\n}\n\nfunction bufferToFloat32Array(buf: Buffer): Float32Array {\n return new Float32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4);\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\nfunction isRateLimitError(error: unknown): boolean {\n const message = getErrorMessage(error);\n return message.includes(\"429\") || message.toLowerCase().includes(\"rate limit\") || message.toLowerCase().includes(\"too many requests\");\n}\n\nfunction getSafeEmbeddingChunkTokenLimit(provider: ConfiguredProviderInfo): number {\n const providerMaxTokens = provider.modelInfo.maxTokens;\n const maxChunkTokens = Math.max(256, Math.floor(providerMaxTokens * 0.75));\n return Math.min(2000, maxChunkTokens);\n}\n\n// Ollama default batch caps. maxBatchItems is the count limiter; maxBatchTokens is a\n// request size/time guard (ollama encodes each input independently, so the per-batch\n// token sum is not bounded by the model context). 65536 allows the default 16 items\n// (each input is split to <= ~1536 tokens) and is overridable via embedding.batch.\n// 16 (not 32) bounds the in-flight workload: ollama concurrency is fixed at 5, so the\n// worst case is 5 concurrent batches * 16 inputs (~80 texts) rather than 160.\nconst DEFAULT_OLLAMA_MAX_BATCH_ITEMS = 16;\nconst DEFAULT_OLLAMA_MAX_BATCH_TOKENS = 65_536;\n\nexport function getDynamicBatchOptions(\n provider: ConfiguredProviderInfo,\n embeddingBatch?: EmbeddingBatchConfig,\n): { maxBatchTokens?: number; maxBatchItems?: number } {\n // embedding.batch.* is documented as ollama-only. Non-ollama providers keep\n // their existing (unbatched-by-this-layer) behavior, so return an empty\n // options object regardless of any user-supplied batch config.\n if (provider.provider !== \"ollama\") {\n return {};\n }\n const base = { maxBatchTokens: DEFAULT_OLLAMA_MAX_BATCH_TOKENS, maxBatchItems: DEFAULT_OLLAMA_MAX_BATCH_ITEMS };\n return {\n ...base,\n ...(typeof embeddingBatch?.maxBatchTokens === \"number\" && Number.isFinite(embeddingBatch.maxBatchTokens) ? { maxBatchTokens: embeddingBatch.maxBatchTokens } : {}),\n ...(typeof embeddingBatch?.maxBatchItems === \"number\" && Number.isFinite(embeddingBatch.maxBatchItems) ? { maxBatchItems: embeddingBatch.maxBatchItems } : {}),\n };\n}\n\nfunction isSqliteCorruptionError(error: unknown): boolean {\n const message = getErrorMessage(error).toLowerCase();\n return message.includes(\"database disk image is malformed\")\n || message.includes(\"file is not a database\")\n || message.includes(\"database schema is corrupt\")\n || message.includes(\"sqlite_corrupt\");\n}\n\nexport interface IndexStats {\n totalFiles: number;\n totalChunks: number;\n indexedChunks: number;\n failedChunks: number;\n tokensUsed: number;\n durationMs: number;\n existingChunks: number;\n removedChunks: number;\n skippedFiles: SkippedFile[];\n parseFailures: string[];\n failedBatchesPath?: string;\n warning?: string;\n resetCorruptedIndex?: boolean;\n}\n\nexport interface IndexerRuntimeOptions {\n materializedProjectRoot?: string;\n branchName?: string;\n catalogIdentity?: string;\n expectedCommit?: string;\n indexPath?: string;\n /** Internal test and benchmark override. Production uses the fixed limits. */\n fileBatchLimits?: FileBatchLimits;\n /** Internal test and benchmark override. Production uses a fixed default. */\n checkpointIntervalChunks?: number;\n}\n\nexport interface BranchIndexResult {\n prepared: boolean;\n stats?: IndexStats;\n}\n\ninterface CorruptedIndexResetResult {\n warning: string;\n resetCorruptedIndex: true;\n}\n\nexport interface SearchResult {\n filePath: string;\n startLine: number;\n endLine: number;\n content: string;\n score: number;\n chunkType: string;\n name?: string;\n blame?: GitBlameMetadata;\n}\n\ninterface CandidateSnapshot {\n id: string;\n filePath: string;\n startLine: number;\n endLine: number;\n score: number;\n chunkType: string;\n name?: string;\n}\n\nexport interface SearchTrace {\n semanticCandidates: CandidateSnapshot[];\n keywordCandidates: CandidateSnapshot[];\n hybridCandidates: CandidateSnapshot[];\n postExternalRerankCandidates: CandidateSnapshot[];\n tieredCandidates: CandidateSnapshot[];\n finalCandidates: CandidateSnapshot[];\n}\n\ninterface SearchOptions {\n hybridWeight?: number;\n fileType?: string;\n directory?: string;\n chunkType?: string;\n contextLines?: number;\n filterByBranch?: boolean;\n metadataOnly?: boolean;\n definitionIntent?: boolean;\n /** Soft ranking preference for context retrieval. Unlike definitionIntent, this never filters candidates. */\n prioritizeSourcePaths?: boolean;\n blameAuthor?: string;\n blameSha?: string;\n blameSince?: string;\n blameUntil?: string;\n trace?: (trace: SearchTrace) => void;\n}\n\nexport interface HealthCheckResult {\n removed: number;\n filePaths: string[];\n gcOrphanEmbeddings: number;\n gcOrphanChunks: number;\n gcOrphanSymbols: number;\n gcOrphanCallEdges: number;\n warning?: string;\n resetCorruptedIndex?: boolean;\n}\n\nexport interface StatusResult {\n indexed: boolean;\n vectorCount: number;\n provider: string;\n model: string;\n indexPath: string;\n currentBranch: string;\n baseBranch: string;\n compatibility: IndexCompatibility | null;\n failedBatchesCount: number;\n failedBatchesPath?: string;\n warning?: string;\n}\n\nexport type IndexFreshnessReason =\n | \"current\"\n | \"missing\"\n | \"unreadable\"\n | \"incompatible\"\n | \"failed-batches\"\n | \"files-changed\"\n | \"branch-changed\"\n | \"migration-required\";\n\nexport interface IndexFreshnessResult {\n readable: boolean;\n current: boolean;\n reason: IndexFreshnessReason;\n}\n\ntype InitializationMode = \"none\" | \"reader\" | \"writer\";\n\ninterface IndexReadIssue {\n component: \"vectors\" | \"keyword\" | \"database\";\n message: string;\n blocking: boolean;\n}\n\ninterface ReaderArtifactFingerprint {\n vectors: string;\n keyword: string;\n database: string;\n databaseIdentity: string;\n}\n\nconst STARTUP_WARNING_METADATA_KEY = \"index.startupWarning\";\nconst READER_ARTIFACT_RETRY_INTERVAL_MS = 1_000;\n\nexport interface IndexProgress {\n phase: \"scanning\" | \"parsing\" | \"embedding\" | \"storing\" | \"complete\";\n filesProcessed: number;\n totalFiles: number;\n chunksProcessed: number;\n totalChunks: number;\n currentFile?: string;\n}\n\nexport type ProgressCallback = (progress: IndexProgress) => void;\n\ninterface ChangedFileDescriptor {\n storedPath: string;\n materializedPath: string;\n hash: string;\n sourceBytes: number;\n}\n\ninterface RetryableFailedChunkRecord {\n chunk: PendingChunk;\n attemptCount: number;\n}\n\ninterface FailedChunkRecordMetadata {\n attemptCount: number;\n error: string;\n lastAttempt: string;\n chunks: unknown[];\n}\n\ninterface FailedBatchWriteState {\n writer: FailedBatchWriter<unknown>;\n recordsWritten: number;\n}\n\ninterface FailedBatchProcessingState {\n state: FailedBatchWriteState;\n latestById: Map<string, FailedChunkRecordMetadata>;\n materializedRetryIds: Set<string>;\n discardedExistingRecords: boolean;\n}\n\ninterface EmbeddingRateLimitState {\n backoffMs: number;\n}\n\ninterface PendingChunkBatchResult {\n indexedChunks: number;\n failedChunks: number;\n tokensUsed: number;\n failedChunkIds: Set<string>;\n}\n\nfunction getFailedBatchGroupKey(record: Pick<SerializedFailedBatch, \"error\" | \"attemptCount\" | \"lastAttempt\">): string {\n return `${record.attemptCount}:${record.lastAttempt}:${record.error}`;\n}\n\nfunction getPendingChunkId(rawChunk: unknown): string | null {\n if (!rawChunk || typeof rawChunk !== \"object\") {\n return null;\n }\n const id = (rawChunk as { id?: unknown }).id;\n return typeof id === \"string\" ? id : null;\n}\n\ntype SearchFilterOptions = {\n fileType?: string;\n directory?: string;\n chunkType?: string;\n blameAuthor?: string;\n blameSha?: string;\n blameSince?: string;\n blameUntil?: string;\n};\n\nfunction parseBlameTimestamp(value: string, endOfDay: boolean): number | null {\n let timestampMs = Date.parse(value);\n if (Number.isNaN(timestampMs)) return null;\n if (endOfDay && /^\\d{4}-\\d{2}-\\d{2}$/.test(value.trim())) {\n timestampMs += 24 * 60 * 60 * 1000 - 1;\n }\n return Math.floor(timestampMs / 1000);\n}\n\nfunction metadataFromBlame(blame: GitBlameMetadata | undefined): Partial<ChunkMetadata> {\n if (!blame) {\n return {};\n }\n\n return {\n blameSha: blame.sha,\n blameAuthor: blame.author,\n blameAuthorEmail: blame.authorEmail,\n blameCommittedAt: blame.committedAt,\n blameSummary: blame.summary,\n };\n}\n\nfunction blameFromChunkData(chunk: ChunkData | null): GitBlameMetadata | undefined {\n if (!chunk?.blameSha || !chunk.blameAuthor || !chunk.blameAuthorEmail || chunk.blameCommittedAt === undefined || !chunk.blameSummary) {\n return undefined;\n }\n\n return {\n sha: chunk.blameSha,\n author: chunk.blameAuthor,\n authorEmail: chunk.blameAuthorEmail,\n committedAt: chunk.blameCommittedAt,\n summary: chunk.blameSummary,\n };\n}\n\nfunction blameFromMetadata(metadata: ChunkMetadata): GitBlameMetadata | undefined {\n if (!metadata.blameSha || !metadata.blameAuthor || !metadata.blameAuthorEmail || metadata.blameCommittedAt === undefined || !metadata.blameSummary) {\n return undefined;\n }\n\n return {\n sha: metadata.blameSha,\n author: metadata.blameAuthor,\n authorEmail: metadata.blameAuthorEmail,\n committedAt: metadata.blameCommittedAt,\n summary: metadata.blameSummary,\n };\n}\n\nfunction hasBlameMetadata(metadata: ChunkMetadata): boolean {\n return blameFromMetadata(metadata) !== undefined;\n}\n\ninterface RerankDocumentPayload {\n id: string;\n text: string;\n}\n\ninterface IndexMetadata {\n indexVersion: string;\n pathStorageVersion: string;\n embeddingProvider: string;\n embeddingModel: string;\n embeddingDimensions: number;\n embeddingStrategyVersion: string;\n createdAt: string;\n updatedAt: string;\n}\n\nenum IncompatibilityCode {\n DIMENSION_MISMATCH = \"DIMENSION_MISMATCH\",\n MODEL_MISMATCH = \"MODEL_MISMATCH\",\n EMBEDDING_STRATEGY_MISMATCH = \"EMBEDDING_STRATEGY_MISMATCH\",\n PATH_STORAGE_MISMATCH = \"PATH_STORAGE_MISMATCH\",\n}\n\ninterface IndexCompatibility {\n compatible: boolean;\n code?: IncompatibilityCode;\n reason?: string;\n storedMetadata?: IndexMetadata;\n}\n\nconst INDEX_METADATA_VERSION = \"1\";\nconst PROJECT_PATH_STORAGE_VERSION = \"2\";\nconst GLOBAL_PATH_STORAGE_VERSION = \"1\";\nconst EMBEDDING_STRATEGY_VERSION = \"2\";\nconst SWIFT_PARSER_VERSION = \"1\";\nconst METAL_PARSER_VERSION = \"1\";\nconst SYMBOL_EXTRACTOR_VERSION = \"1\";\n\nfunction isPathWithinRoot(filePath: string, rootPath: string): boolean {\n const normalizedFilePath = path.resolve(filePath);\n const normalizedRoot = path.resolve(rootPath);\n return normalizedFilePath === normalizedRoot || normalizedFilePath.startsWith(`${normalizedRoot}${path.sep}`);\n}\n\nfunction promoteIdentifierMatches(\n query: string,\n combined: RankedCandidate[],\n semanticCandidates: RankedCandidate[],\n keywordCandidates: RankedCandidate[],\n database?: Database,\n branchChunkIds?: Set<string> | null,\n prioritizeSourcePaths: boolean = classifyQueryIntentRaw(query) === \"source\"\n): RankedCandidate[] {\n if (combined.length === 0) {\n return combined;\n }\n\n if (!prioritizeSourcePaths) {\n return combined;\n }\n\n const identifierHints = extractIdentifierHints(query);\n if (identifierHints.length === 0) {\n return combined;\n }\n\n const combinedById = new Map(combined.map((candidate) => [candidate.id, candidate]));\n const candidateUnion = new Map<string, RankedCandidate>();\n for (const candidate of semanticCandidates) {\n candidateUnion.set(candidate.id, candidate);\n }\n for (const candidate of keywordCandidates) {\n if (!candidateUnion.has(candidate.id)) {\n candidateUnion.set(candidate.id, candidate);\n }\n }\n\n if (database) {\n for (const identifier of identifierHints) {\n const symbols = database.getSymbolsByName(identifier);\n for (const symbol of symbols) {\n const chunks = database.getChunksByFile(symbol.filePath);\n for (const chunk of chunks) {\n if (branchChunkIds && !branchChunkIds.has(chunk.chunkId)) {\n continue;\n }\n\n const chunkType = ((chunk.nodeType ?? \"other\") as ChunkMetadata[\"chunkType\"]);\n if (!isImplementationChunkType(chunkType)) {\n continue;\n }\n\n if (!isLikelyImplementationPath(chunk.filePath)) {\n continue;\n }\n\n if (chunk.startLine > symbol.startLine || chunk.endLine < symbol.endLine) {\n continue;\n }\n\n const existing = combinedById.get(chunk.chunkId) ?? candidateUnion.get(chunk.chunkId);\n const metadata: ChunkMetadata = existing?.metadata ?? {\n filePath: chunk.filePath,\n startLine: chunk.startLine,\n endLine: chunk.endLine,\n chunkType,\n name: chunk.name ?? undefined,\n language: chunk.language,\n hash: chunk.contentHash,\n ...metadataFromBlame(blameFromChunkData(chunk)),\n };\n\n const baselineScore = existing?.score ?? 0.5;\n candidateUnion.set(chunk.chunkId, {\n id: chunk.chunkId,\n score: Math.min(1, baselineScore + 0.5),\n metadata,\n });\n }\n }\n }\n }\n\n const promoted: RankedCandidate[] = [];\n for (const candidate of candidateUnion.values()) {\n const filePathLower = candidate.metadata.filePath.toLowerCase();\n const nameLower = (candidate.metadata.name ?? \"\").toLowerCase();\n const exactIdentifierMatch = identifierHints.some((hint) => nameLower === hint);\n const hasIdentifierMatch = exactIdentifierMatch || identifierHints.some((hint) =>\n nameLower.includes(hint) ||\n filePathLower.includes(hint)\n );\n\n if (!hasIdentifierMatch) {\n continue;\n }\n\n if (!isImplementationChunkType(candidate.metadata.chunkType)) {\n continue;\n }\n\n if (!isLikelyImplementationPath(candidate.metadata.filePath)) {\n continue;\n }\n\n const existing = combinedById.get(candidate.id) ?? candidate;\n const rescueBoost = exactIdentifierMatch ? 0.45 : 0.25;\n const boostedScore = Math.min(1, Math.max(existing.score, candidate.score) + rescueBoost);\n promoted.push({\n id: existing.id,\n score: boostedScore,\n metadata: existing.metadata,\n });\n }\n\n if (promoted.length === 0) {\n return combined;\n }\n\n promoted.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));\n\n const promotedIds = new Set(promoted.map((candidate) => candidate.id));\n const remainder = combined.filter((candidate) => !promotedIds.has(candidate.id));\n return [...promoted, ...remainder];\n}\n\nexport function buildSymbolDefinitionLane(\n query: string,\n database: Database,\n branchChunkIds: Set<string> | null,\n branchSymbolIds: Set<string> | null,\n limit: number,\n fallbackCandidates: RankedCandidate[],\n prioritizeSourcePaths: boolean = classifyQueryIntentRaw(query) === \"source\",\n allowNonSourcePaths: boolean = false,\n): RankedCandidate[] {\n if (!prioritizeSourcePaths) {\n return [];\n }\n\n const identifierHints = extractIdentifierHints(query);\n const codeTermHints = extractCodeTermHints(query);\n if (identifierHints.length === 0 && codeTermHints.length === 0) {\n return [];\n }\n\n const symbolCandidates = new Map<string, RankedCandidate>();\n const filePathHint = extractFilePathHint(query);\n const primaryHint = extractPrimaryIdentifierQueryHint(query);\n\n const upsertChunkCandidate = (\n chunk: ReturnType<Database[\"getChunksByName\"]>[number],\n identifier: string,\n normalizedIdentifier: string,\n baseScore?: number\n ): boolean => {\n if (branchChunkIds && !branchChunkIds.has(chunk.chunkId)) {\n return false;\n }\n\n const chunkType = (chunk.nodeType ?? \"other\") as ChunkMetadata[\"chunkType\"];\n if (!isImplementationChunkType(chunkType)) {\n return false;\n }\n\n if (!allowNonSourcePaths && !isLikelyImplementationPath(chunk.filePath)) {\n return false;\n }\n\n const nameLower = (chunk.name ?? \"\").toLowerCase();\n const exactName =\n nameLower === identifier ||\n nameLower.replace(/_/g, \"\") === normalizedIdentifier;\n const base = baseScore ?? (exactName ? 0.99 : 0.88);\n\n const existing = symbolCandidates.get(chunk.chunkId);\n if (!existing || base > existing.score) {\n symbolCandidates.set(chunk.chunkId, {\n id: chunk.chunkId,\n score: base,\n metadata: {\n filePath: chunk.filePath,\n startLine: chunk.startLine,\n endLine: chunk.endLine,\n chunkType,\n name: chunk.name ?? undefined,\n language: chunk.language,\n hash: chunk.contentHash,\n ...metadataFromBlame(blameFromChunkData(chunk)),\n },\n });\n }\n return true;\n };\n\n const normalizedHints = identifierHints\n .flatMap((hint) => [\n hint,\n hint.replace(/_/g, \"\"),\n hint.replace(/_/g, \"-\")\n ])\n .filter((hint, idx, arr) => hint.length >= 3 && arr.indexOf(hint) === idx)\n .slice(0, 6);\n\n for (const identifier of normalizedHints) {\n const symbols = [\n ...database.getSymbolsByName(identifier),\n ...database.getSymbolsByNameCi(identifier),\n ];\n\n const chunksByName = [\n ...database.getChunksByName(identifier),\n ...database.getChunksByNameCi(identifier),\n ];\n\n const normalizedIdentifier = identifier.replace(/_/g, \"\");\n\n const dedupSymbols = new Map<string, typeof symbols[number]>();\n for (const symbol of symbols) {\n dedupSymbols.set(symbol.id, symbol);\n }\n\n for (const symbol of dedupSymbols.values()) {\n if (branchSymbolIds && !branchSymbolIds.has(symbol.id)) {\n continue;\n }\n if (filePathHint && !pathMatchesHint(symbol.filePath, filePathHint)) {\n continue;\n }\n\n const chunks = database.getChunksByFile(symbol.filePath);\n let foundCoveringChunk = false;\n for (const chunk of chunks) {\n if (chunk.startLine > symbol.startLine || chunk.endLine < symbol.endLine) {\n continue;\n }\n\n const chunkName = (chunk.name ?? \"\").toLowerCase();\n const symbolName = symbol.name.toLowerCase();\n if (chunkName !== symbolName && chunkName.replace(/_/g, \"\") !== symbolName.replace(/_/g, \"\")) {\n continue;\n }\n\n foundCoveringChunk = upsertChunkCandidate(chunk, identifier, normalizedIdentifier) || foundCoveringChunk;\n }\n\n if (foundCoveringChunk || (!allowNonSourcePaths && !isLikelyImplementationPath(symbol.filePath))) {\n continue;\n }\n\n const symbolName = symbol.name.toLowerCase();\n const exactName =\n symbolName === identifier ||\n symbolName.replace(/_/g, \"\") === normalizedIdentifier;\n const score = exactName ? 0.99 : 0.88;\n const existing = symbolCandidates.get(symbol.id);\n if (!existing || score > existing.score) {\n symbolCandidates.set(symbol.id, {\n id: symbol.id,\n score,\n metadata: {\n filePath: symbol.filePath,\n startLine: symbol.startLine,\n endLine: symbol.endLine,\n chunkType: symbol.kind as ChunkMetadata[\"chunkType\"],\n name: symbol.name,\n language: symbol.language,\n hash: symbol.id,\n },\n });\n }\n }\n\n const dedupChunksByName = new Map<string, typeof chunksByName[number]>();\n for (const chunk of chunksByName) {\n dedupChunksByName.set(chunk.chunkId, chunk);\n }\n\n for (const chunk of dedupChunksByName.values()) {\n if (filePathHint && !pathMatchesHint(chunk.filePath, filePathHint)) {\n continue;\n }\n upsertChunkCandidate(chunk, identifier, normalizedIdentifier);\n }\n }\n\n if (filePathHint && primaryHint) {\n const primaryChunks = [\n ...database.getChunksByName(primaryHint),\n ...database.getChunksByNameCi(primaryHint),\n ];\n const dedupPrimaryChunks = new Map<string, typeof primaryChunks[number]>();\n for (const chunk of primaryChunks) {\n dedupPrimaryChunks.set(chunk.chunkId, chunk);\n }\n\n for (const chunk of dedupPrimaryChunks.values()) {\n if (!pathMatchesHint(chunk.filePath, filePathHint)) {\n continue;\n }\n const normalizedPrimary = primaryHint.replace(/_/g, \"\");\n upsertChunkCandidate(chunk, primaryHint, normalizedPrimary, 1.0);\n }\n }\n\n const ranked = Array.from(symbolCandidates.values()).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));\n if (ranked.length === 0) {\n const implementationFallback = fallbackCandidates.filter((candidate) =>\n isImplementationChunkType(candidate.metadata.chunkType) &&\n (allowNonSourcePaths || isLikelyImplementationPath(candidate.metadata.filePath))\n );\n\n for (const candidate of implementationFallback) {\n const nameLower = (candidate.metadata.name ?? \"\").toLowerCase();\n const pathLower = candidate.metadata.filePath.toLowerCase();\n\n const exactHintMatch = normalizedHints.some((hint) => nameLower === hint || nameLower.replace(/_/g, \"\") === hint.replace(/_/g, \"\"));\n const tokenizedName = tokenizeTextForRanking(nameLower);\n const tokenHits = codeTermHints.filter((term) => tokenizedName.has(term) || pathLower.includes(term)).length;\n\n if (!exactHintMatch && tokenHits === 0) {\n continue;\n }\n\n const laneScore = exactHintMatch\n ? Math.min(1, Math.max(candidate.score, 0.97))\n : Math.min(0.95, Math.max(candidate.score, 0.82 + tokenHits * 0.03));\n symbolCandidates.set(candidate.id, {\n id: candidate.id,\n score: laneScore,\n metadata: candidate.metadata,\n });\n }\n\n if (symbolCandidates.size === 0) {\n const queryTokenSet = tokenizeTextForRanking(query);\n const rankedFallback = implementationFallback\n .map((candidate) => {\n const nameTokens = tokenizeTextForRanking(candidate.metadata.name ?? \"\");\n const pathTokens = splitPathTokens(candidate.metadata.filePath);\n let overlap = 0;\n for (const token of queryTokenSet) {\n if (nameTokens.has(token) || pathTokens.has(token)) {\n overlap += 1;\n }\n }\n const overlapScore = queryTokenSet.size > 0 ? overlap / queryTokenSet.size : 0;\n return {\n candidate,\n overlapScore,\n };\n })\n .filter((entry) => entry.overlapScore > 0)\n .sort((a, b) => b.overlapScore - a.overlapScore || b.candidate.score - a.candidate.score)\n .slice(0, Math.max(limit, 3));\n\n for (const entry of rankedFallback) {\n symbolCandidates.set(entry.candidate.id, {\n id: entry.candidate.id,\n score: Math.min(0.94, Math.max(entry.candidate.score, 0.8 + entry.overlapScore * 0.1)),\n metadata: entry.candidate.metadata,\n });\n }\n }\n }\n\n const withFallback = Array.from(symbolCandidates.values()).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));\n return withFallback.slice(0, Math.max(limit * 2, limit));\n}\n\nexport function mergeTieredResults(\n symbolLane: RankedCandidate[],\n hybridLane: RankedCandidate[],\n limit: number\n): RankedCandidate[] {\n if (symbolLane.length === 0) {\n return hybridLane.slice(0, limit);\n }\n\n const out: RankedCandidate[] = [];\n const seen = new Set<string>();\n\n for (const candidate of symbolLane) {\n if (seen.has(candidate.id)) continue;\n out.push(candidate);\n seen.add(candidate.id);\n if (out.length >= limit) return out;\n }\n\n for (const candidate of hybridLane) {\n if (seen.has(candidate.id)) continue;\n out.push(candidate);\n seen.add(candidate.id);\n if (out.length >= limit) return out;\n }\n\n return out;\n}\n\nexport function selectChunksWithFileCoverage<T>(chunks: T[], limit: number): T[] {\n if (limit <= 0 || chunks.length === 0) {\n return [];\n }\n\n if (chunks.length <= limit) {\n return chunks;\n }\n\n if (limit === 1) {\n return [chunks[Math.floor((chunks.length - 1) / 2)]!];\n }\n\n const selected: T[] = [];\n for (let index = 0; index < limit; index++) {\n const sourceIndex = Math.round(index * (chunks.length - 1) / (limit - 1));\n selected.push(chunks[sourceIndex]!);\n }\n return selected;\n}\n\nexport function selectIndexableChunks<T extends { chunkType: string }>(\n chunks: T[],\n limit: number,\n semanticOnly: boolean,\n): T[] {\n const indexableChunks = semanticOnly\n ? chunks.filter((chunk) => chunk.chunkType !== \"other\")\n : chunks;\n return selectChunksWithFileCoverage(indexableChunks, limit);\n}\n\nfunction matchesHardSearchFilters(\n candidate: RankedCandidate,\n options: SearchFilterOptions | undefined,\n projectRoot: string,\n): boolean {\n if (options?.fileType) {\n const ext = candidate.metadata.filePath.split(\".\").pop()?.toLowerCase();\n const requestedExtension = options.fileType.trim().toLowerCase().replace(/^\\./, \"\");\n if (ext !== requestedExtension) return false;\n }\n\n if (options?.directory) {\n const candidatePath = canonicalizePathForComparison(\n path.resolve(projectRoot, candidate.metadata.filePath.replace(/\\\\/g, path.sep)),\n );\n const directoryPath = canonicalizePathForComparison(\n path.resolve(projectRoot, options.directory.trim().replace(/\\\\/g, path.sep)),\n );\n if (!isPathWithinRoot(candidatePath, directoryPath)) return false;\n }\n\n if (options?.chunkType && candidate.metadata.chunkType !== options.chunkType) {\n return false;\n }\n\n if (options?.blameAuthor) {\n const author = options.blameAuthor.toLowerCase();\n const candidateAuthor = candidate.metadata.blameAuthor?.toLowerCase();\n const candidateEmail = candidate.metadata.blameAuthorEmail?.toLowerCase();\n if (candidateAuthor !== author && candidateEmail !== author) return false;\n }\n\n if (options?.blameSha && !candidate.metadata.blameSha?.toLowerCase().startsWith(options.blameSha.toLowerCase())) {\n return false;\n }\n\n if (options?.blameSince) {\n const since = parseBlameTimestamp(options.blameSince, false);\n if (since === null) return false;\n const committedAt = candidate.metadata.blameCommittedAt;\n if (committedAt === undefined || committedAt < since) return false;\n }\n\n if (options?.blameUntil) {\n const until = parseBlameTimestamp(options.blameUntil, true);\n if (until === null) return false;\n const committedAt = candidate.metadata.blameCommittedAt;\n if (committedAt === undefined || committedAt > until) return false;\n }\n\n return true;\n}\n\nfunction matchesSearchFilters(\n candidate: RankedCandidate,\n options: SearchFilterOptions | undefined,\n minScore: number,\n projectRoot: string,\n): boolean {\n return candidate.score >= minScore && matchesHardSearchFilters(candidate, options, projectRoot);\n}\n\nfunction unionCandidates(\n semanticCandidates: RankedCandidate[],\n keywordCandidates: RankedCandidate[]\n): RankedCandidate[] {\n const byId = new Map<string, RankedCandidate>();\n for (const candidate of semanticCandidates) {\n byId.set(candidate.id, candidate);\n }\n for (const candidate of keywordCandidates) {\n const existing = byId.get(candidate.id);\n if (!existing || candidate.score > existing.score) {\n byId.set(candidate.id, candidate);\n }\n }\n return Array.from(byId.values());\n}\n\nexport class Indexer {\n private readonly host: HostMode;\n private config: ParsedCodebaseIndexConfig;\n private projectRoot: string;\n private readonly materializedProjectRoot: string;\n private readonly branchNameOverride: string | undefined;\n private readonly catalogIdentityOverride: string | undefined;\n private readonly expectedCommitOverride: string | undefined;\n private readonly indexPathOverride: string | undefined;\n private readonly projectIdentityHash: string;\n private indexPath: string;\n private store: VectorStore | null = null;\n private invertedIndex: InvertedIndex | null = null;\n private database: Database | null = null;\n private provider: EmbeddingProviderInterface | null = null;\n private configuredProviderInfo: ConfiguredProviderInfo | null = null;\n private fileHashCache: Map<string, string> = new Map();\n private fileHashCachePath: string = \"\";\n private failedBatchesPath: string = \"\";\n private currentBranch: string = \"default\";\n private baseBranch: string = \"main\";\n private logger: Logger;\n private queryEmbeddingCache: Map<string, { embedding: number[]; timestamp: number }> = new Map();\n private readonly maxQueryCacheSize = 100;\n private readonly queryCacheTtlMs = 5 * 60 * 1000;\n private readonly querySimilarityThreshold = 0.85;\n private indexCompatibility: IndexCompatibility | null = null;\n private activeIndexLease: IndexLockLease | null = null;\n private initializationPromise: Promise<void> | null = null;\n private initializationMode: InitializationMode = \"none\";\n private readIssues: IndexReadIssue[] = [];\n private retiredDatabases: Database[] = [];\n private readerArtifactFingerprint: ReaderArtifactFingerprint | null = null;\n private writerArtifactFingerprint: ReaderArtifactFingerprint | null = null;\n private readerArtifactRetryAfter = new Map<IndexReadIssue[\"component\"], number>();\n private readonly fileBatchLimits?: FileBatchLimits;\n private readonly checkpointIntervalChunks?: number;\n\n constructor(\n projectRoot: string,\n config: ParsedCodebaseIndexConfig,\n host: HostMode,\n runtimeOptions: IndexerRuntimeOptions = {},\n ) {\n this.projectRoot = projectRoot;\n this.projectIdentityHash = this.getProjectIdentityHash(projectRoot);\n this.materializedProjectRoot = runtimeOptions.materializedProjectRoot ?? projectRoot;\n this.branchNameOverride = runtimeOptions.branchName;\n this.catalogIdentityOverride = runtimeOptions.catalogIdentity;\n if (runtimeOptions.expectedCommit !== undefined && !isFullGitCommit(runtimeOptions.expectedCommit)) {\n throw new Error(`Expected Git commit is invalid: ${JSON.stringify(runtimeOptions.expectedCommit)}`);\n }\n this.expectedCommitOverride = runtimeOptions.expectedCommit?.toLowerCase();\n this.indexPathOverride = runtimeOptions.indexPath;\n this.fileBatchLimits = runtimeOptions.fileBatchLimits;\n this.checkpointIntervalChunks = runtimeOptions.checkpointIntervalChunks;\n this.config = config;\n this.host = host;\n if (isGitRepo(this.materializedProjectRoot)) {\n this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);\n this.baseBranch = getBaseBranch(this.materializedProjectRoot);\n } else {\n this.currentBranch = \"default\";\n this.baseBranch = \"default\";\n }\n this.indexPath = this.getIndexPath();\n this.refreshRuntimeArtifactPaths();\n this.logger = initializeLogger(config.debug);\n }\n\n private getIndexPath(): string {\n return this.indexPathOverride ?? resolveProjectIndexPath(this.projectRoot, this.config.scope, this.host);\n }\n\n private toCanonicalFilePath(filePath: string): string {\n if (!path.isAbsolute(filePath)) {\n return this.resolveStoredFilePath(filePath, this.projectRoot);\n }\n if (\n path.resolve(this.materializedProjectRoot) === path.resolve(this.projectRoot)\n || !isPathWithinRoot(filePath, this.materializedProjectRoot)\n ) {\n return filePath;\n }\n return path.resolve(this.projectRoot, path.relative(this.materializedProjectRoot, filePath));\n }\n\n private toStoredFilePath(filePath: string): string {\n const canonicalFilePath = this.toCanonicalFilePath(filePath);\n if (\n this.config.scope !== \"project\"\n || !isPathWithinRoot(canonicalFilePath, this.projectRoot)\n ) {\n return canonicalFilePath;\n }\n\n return path.relative(this.projectRoot, canonicalFilePath).split(path.sep).join(\"/\");\n }\n\n private resolveStoredFilePath(filePath: string, rootPath = this.projectRoot): string {\n if (path.isAbsolute(filePath)) {\n return filePath;\n }\n\n const resolvedPath = path.resolve(rootPath, ...filePath.split(\"/\"));\n if (!isPathWithinRoot(resolvedPath, rootPath)) {\n throw new Error(`Stored project path escapes project root: ${JSON.stringify(filePath)}`);\n }\n return resolvedPath;\n }\n\n private getCanonicalStoredFilePath(filePath: string): string {\n return this.getCanonicalPath(this.resolveStoredFilePath(filePath));\n }\n\n private resolveFilePathRecord<T extends { filePath: string }>(record: T): T {\n return {\n ...record,\n filePath: this.resolveStoredFilePath(record.filePath),\n };\n }\n\n private resolveCallEdgeFilePath(edge: CallEdgeData): CallEdgeData {\n if (!edge.fromSymbolFilePath) return edge;\n return {\n ...edge,\n fromSymbolFilePath: this.resolveStoredFilePath(edge.fromSymbolFilePath),\n };\n }\n\n private toMaterializedFilePath(filePath: string): string {\n const storedFilePath = this.toStoredFilePath(filePath);\n if (path.isAbsolute(storedFilePath)) {\n return storedFilePath;\n }\n return this.resolveStoredFilePath(storedFilePath, this.materializedProjectRoot);\n }\n\n private getPreparedBranchNamespace(): string | null {\n if (!this.branchNameOverride && !this.catalogIdentityOverride) return null;\n return hashContent(this.getBranchCatalogKey()).slice(0, 16);\n }\n\n private getRuntimeArtifactNamespace(): string | null {\n if (this.config.scope !== \"project\" || this.getBranchCatalogIdentity() === \"default\") {\n return this.getPreparedBranchNamespace();\n }\n return hashContent(this.getBranchCatalogKey()).slice(0, 16);\n }\n\n private getRuntimeArtifactPath(fileName: string): string {\n const namespace = this.getRuntimeArtifactNamespace();\n if (!namespace) return path.join(this.indexPath, fileName);\n const extension = path.extname(fileName);\n const baseName = fileName.slice(0, fileName.length - extension.length);\n return path.join(this.indexPath, `${baseName}.${namespace}${extension}`);\n }\n\n private refreshRuntimeArtifactPaths(): void {\n this.fileHashCachePath = this.getRuntimeArtifactPath(\"file-hashes.json\");\n this.failedBatchesPath = this.getRuntimeArtifactPath(\"failed-batches.json\");\n }\n\n private getPreparedChunkId(chunkId: string): string {\n const namespace = this.getPreparedBranchNamespace();\n return namespace ? `${chunkId}_${namespace}` : chunkId;\n }\n\n private getMaterializedKnowledgeBases(): string[] {\n const canonicalProjectRoot = this.getCanonicalPath(this.projectRoot);\n return this.config.knowledgeBases.map((knowledgeBase) => {\n const configuredPath = path.isAbsolute(knowledgeBase)\n ? knowledgeBase\n : path.resolve(this.projectRoot, knowledgeBase);\n const canonicalPath = this.getCanonicalPath(configuredPath);\n if (!isPathWithinRoot(canonicalPath, canonicalProjectRoot)) {\n return canonicalPath;\n }\n return path.resolve(\n this.materializedProjectRoot,\n path.relative(canonicalProjectRoot, canonicalPath),\n );\n });\n }\n\n private getCanonicalPath(targetPath: string): string {\n try {\n return canonicalizePathForComparison(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n }\n\n private getProjectIdentityHash(projectRoot: string): string {\n return hashContent(this.getCanonicalPath(projectRoot)).slice(0, 16);\n }\n\n private isProjectOwnedIndexPath(): boolean {\n return isProjectIndexPathOwnedByProject(this.projectRoot, this.indexPath, this.host);\n }\n\n private resetLoadedIndexState(retireDatabase = false): void {\n if (this.database) {\n if (retireDatabase) {\n this.retiredDatabases.push(this.database);\n } else {\n this.database.close();\n }\n }\n this.store = null;\n this.invertedIndex = null;\n this.database = null;\n this.provider = null;\n this.configuredProviderInfo = null;\n this.indexCompatibility = null;\n this.initializationMode = \"none\";\n this.readIssues = [];\n this.readerArtifactFingerprint = null;\n this.writerArtifactFingerprint = null;\n this.readerArtifactRetryAfter.clear();\n this.fileHashCache.clear();\n }\n\n private refreshLoadedIndexState(): void {\n if (!this.store || !this.invertedIndex || !this.configuredProviderInfo) return;\n this.store.load();\n this.invertedIndex.load();\n this.fileHashCache.clear();\n this.loadFileHashCache();\n this.indexCompatibility = this.validateIndexCompatibility(this.configuredProviderInfo);\n this.readIssues = [];\n this.readerArtifactRetryAfter.clear();\n }\n\n private async withIndexMutationLease<T>(\n operation: IndexMutationOperation,\n callback: (recoveredOwners: readonly IndexLockOwner[]) => Promise<T>,\n ): Promise<T> {\n this.refreshBranchInfo();\n const lease = acquireIndexLock(this.indexPath, operation, {\n projectRoot: this.projectRoot,\n scopedRoots: this.getScopedRoots(),\n });\n this.indexPath = lease.canonicalIndexPath;\n this.refreshRuntimeArtifactPaths();\n this.activeIndexLease = lease;\n\n let result: T | undefined;\n let callbackError: unknown;\n let callbackFailed = false;\n try {\n result = await callback(lease.recoveries.map(({ owner }) => owner));\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n if (!callbackFailed) {\n try {\n completeLeaseRecovery(lease);\n this.writerArtifactFingerprint = this.captureReaderArtifactFingerprint();\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n }\n let releaseError: unknown;\n try {\n if (!releaseIndexLock(lease)) {\n releaseError = new Error(`Lost ownership of index mutation lease ${lease.owner.token}`);\n this.writerArtifactFingerprint = null;\n if (this.activeIndexLease?.owner.token === lease.owner.token) {\n this.activeIndexLease = null;\n }\n } else if (this.activeIndexLease?.owner.token === lease.owner.token) {\n this.activeIndexLease = null;\n }\n } catch (error) {\n releaseError = error;\n this.writerArtifactFingerprint = null;\n if (!existsSync(lease.lockPath) && this.activeIndexLease?.owner.token === lease.owner.token) {\n this.activeIndexLease = null;\n }\n }\n if (releaseError !== undefined) {\n if (callbackFailed) throw new AggregateError([callbackError, releaseError], \"Index mutation and lease release both failed\");\n throw releaseError;\n }\n if (callbackFailed) throw callbackError;\n return result as T;\n }\n\n private requireActiveLease(): IndexLockLease {\n if (!this.activeIndexLease) {\n throw new Error(\"Index mutation attempted without an active interprocess lease\");\n }\n return this.activeIndexLease;\n }\n\n private loadFileHashCache(): void {\n if (!existsSync(this.fileHashCachePath)) {\n this.fileHashCache = new Map();\n return;\n }\n\n try {\n const data = readFileSync(this.fileHashCachePath, \"utf-8\");\n const parsed = JSON.parse(data);\n this.fileHashCache = new Map(Object.entries(parsed));\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n this.logger.warn(\"Failed to load file hash cache, resetting cache state\", {\n fileHashCachePath: this.fileHashCachePath,\n error: message,\n });\n this.fileHashCache = new Map();\n }\n }\n\n private saveFileHashCache(): void {\n const obj: Record<string, string> = {};\n for (const [k, v] of this.fileHashCache) {\n obj[k] = v;\n }\n this.atomicWriteSync(this.fileHashCachePath, JSON.stringify(obj));\n }\n\n private atomicWriteSync(targetPath: string, data: string): void {\n const lease = this.requireActiveLease();\n const tempPath = createLeaseTemporaryPath(targetPath, lease.owner, \"tmp\");\n mkdirSync(path.dirname(targetPath), { recursive: true });\n try {\n writeFileSync(tempPath, data);\n renameSync(tempPath, targetPath);\n } finally {\n removeLeaseTemporaryPath(tempPath);\n }\n }\n\n private saveInvertedIndex(invertedIndex: InvertedIndex): void {\n this.atomicWriteSync(\n path.join(this.indexPath, \"inverted-index.json\"),\n invertedIndex.serialize(),\n );\n }\n\n private getScopedRoots(projectRoot = this.projectRoot): string[] {\n const roots = new Set<string>([this.getCanonicalPath(projectRoot)]);\n\n for (const kbRoot of this.config.knowledgeBases) {\n roots.add(this.getCanonicalPath(path.resolve(projectRoot, kbRoot)));\n }\n\n return Array.from(roots);\n }\n\n private getBranchCatalogKey(): string {\n return this.getBranchCatalogKeyFor(this.getBranchCatalogIdentity());\n }\n\n private getBranchCatalogIdentity(): string {\n return (this.catalogIdentityOverride\n ?? this.branchNameOverride\n ?? this.currentBranch)\n || \"default\";\n }\n\n private getBranchCatalogKeyFor(branchName: string): string {\n if (this.config.scope !== \"global\") {\n return branchName;\n }\n\n return `${this.projectIdentityHash}:${branchName}`;\n }\n\n private resolveBranchCatalogKey(branchName?: string): string {\n return branchName === undefined\n ? this.getBranchCatalogKey()\n : this.getBranchCatalogKeyFor(branchName);\n }\n\n private getBranchCommitMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()): string {\n const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);\n return `index.branchCommit.${hashContent(branchKey).slice(0, 24)}`;\n }\n\n private getBranchCommitMetadataKeyForCatalogKey(branchKey: string): string {\n return `index.branchCommit.${hashContent(branchKey).slice(0, 24)}`;\n }\n\n private getStoredBranchCommit(database: Database, catalogIdentity = this.getBranchCatalogIdentity()): string | null {\n return database.getMetadata(this.getBranchCommitMetadataKey(catalogIdentity));\n }\n\n private saveBranchCommit(database: Database, commit: string | null): void {\n const metadataKey = this.getBranchCommitMetadataKey();\n if (commit) {\n database.setMetadata(metadataKey, commit);\n } else {\n database.deleteMetadata(metadataKey);\n }\n }\n\n private deleteBranchCommitMetadata(database: Database, branchKeys: readonly string[]): void {\n for (const branchKey of new Set(branchKeys)) {\n database.deleteMetadata(this.getBranchCommitMetadataKeyForCatalogKey(branchKey));\n }\n }\n\n private replaceBranchCatalog(\n store: VectorStore,\n invertedIndex: InvertedIndex,\n database: Database,\n branchCatalogKey: string,\n previousChunkIds: readonly string[],\n currentChunkIds: readonly string[],\n previousSymbolIds: readonly string[],\n currentSymbolIds: readonly string[],\n ): boolean {\n database.clearBranch(branchCatalogKey);\n database.addChunksToBranchBatch(branchCatalogKey, [...currentChunkIds]);\n database.clearBranchSymbols(branchCatalogKey);\n database.addSymbolsToBranchBatch(branchCatalogKey, [...currentSymbolIds]);\n\n const currentChunkIdSet = new Set(currentChunkIds);\n const removedChunkCandidates = previousChunkIds.filter((chunkId) => !currentChunkIdSet.has(chunkId));\n const referencedChunkIds = new Set(database.getReferencedChunkIds(removedChunkCandidates));\n const removableChunkIds = removedChunkCandidates.filter((chunkId) => !referencedChunkIds.has(chunkId));\n if (removableChunkIds.length > 0) {\n this.rebuildVectorStoreExcludingChunkIds(store, database, removableChunkIds);\n for (const chunkId of removableChunkIds) {\n invertedIndex.removeChunk(chunkId);\n }\n database.deleteChunksByIds(removableChunkIds);\n }\n\n const currentSymbolIdSet = new Set(currentSymbolIds);\n const removedSymbolCandidates = previousSymbolIds.filter((symbolId) => !currentSymbolIdSet.has(symbolId));\n const referencedSymbolIds = new Set(database.getReferencedSymbolIds(removedSymbolCandidates));\n const removableSymbolIds = removedSymbolCandidates.filter((symbolId) => !referencedSymbolIds.has(symbolId));\n database.clearCallEdgeTargetsForSymbols(removableSymbolIds);\n database.gcOrphanSymbols();\n database.gcOrphanCallEdges();\n database.gcOrphanEmbeddings();\n\n return removableChunkIds.length > 0;\n }\n\n private getLegacyBranchCatalogKey(): string {\n return this.currentBranch || \"default\";\n }\n\n private getLegacyMigrationMetadataKey(projectIdentityHash = this.projectIdentityHash): string {\n return `index.globalBranchMigration.${projectIdentityHash}`;\n }\n\n private getProjectEmbeddingStrategyMetadataKey(projectIdentityHash = this.projectIdentityHash): string {\n return `index.embeddingStrategyVersion.${projectIdentityHash}`;\n }\n\n private getProjectForceReembedMetadataKey(projectIdentityHash = this.projectIdentityHash): string {\n return `index.forceReembed.${projectIdentityHash}`;\n }\n\n private getProjectMigrationFinalizedMetadataKey(projectIdentityHash = this.projectIdentityHash): string {\n return `index.migrationFinalized.${projectIdentityHash}`;\n }\n\n private getBranchMigrationMetadataKey(\n prefix: string,\n catalogIdentity = this.getBranchCatalogIdentity(),\n ): string {\n const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);\n return `${prefix}.${hashContent(branchKey).slice(0, 24)}`;\n }\n\n private getCallGraphResolutionMetadataKey(\n catalogIdentity = this.getBranchCatalogIdentity(),\n ): string {\n return this.getBranchMigrationMetadataKey(\"index.callGraphResolutionVersion\", catalogIdentity);\n }\n\n private getSwiftParserVersionMetadataKey(\n catalogIdentity = this.getBranchCatalogIdentity(),\n ): string {\n return this.getBranchMigrationMetadataKey(\"index.parser.swiftVersion\", catalogIdentity);\n }\n\n private getMetalParserVersionMetadataKey(\n catalogIdentity = this.getBranchCatalogIdentity(),\n ): string {\n return this.getBranchMigrationMetadataKey(\"index.parser.metalVersion\", catalogIdentity);\n }\n\n private getSymbolExtractorVersionMetadataKey(\n catalogIdentity = this.getBranchCatalogIdentity(),\n ): string {\n return this.getBranchMigrationMetadataKey(\"index.symbolExtractorVersion\", catalogIdentity);\n }\n\n private areBranchMigrationVersionsCurrent(\n database: Database,\n catalogIdentity = this.getBranchCatalogIdentity(),\n ): boolean {\n return database.getMetadata(this.getCallGraphResolutionMetadataKey(catalogIdentity))\n === CALL_GRAPH_RESOLUTION_VERSION\n && database.getMetadata(this.getSwiftParserVersionMetadataKey(catalogIdentity))\n === SWIFT_PARSER_VERSION\n && database.getMetadata(this.getMetalParserVersionMetadataKey(catalogIdentity))\n === METAL_PARSER_VERSION\n && database.getMetadata(this.getSymbolExtractorVersionMetadataKey(catalogIdentity))\n === SYMBOL_EXTRACTOR_VERSION;\n }\n\n private hasProjectForceReembedPending(): boolean {\n return this.config.scope === \"global\" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === \"true\";\n }\n\n private hasScopedIndexedData(): boolean {\n if (!this.store || this.config.scope !== \"global\") {\n return false;\n }\n\n if (this.hasProjectForceReembedPending()) {\n return false;\n }\n\n const roots = this.getScopedRoots();\n\n if (Array.from(this.fileHashCache.keys()).some((filePath) => this.isFileInCurrentScope(filePath, roots))) {\n return true;\n }\n\n for (const batch of this.loadSerializedFailedBatches()) {\n if (batch.chunks.some((chunk) => {\n const filePath = getPendingChunkFilePath(chunk);\n return filePath !== null && this.isFileInCurrentScope(filePath, roots);\n })) {\n return true;\n }\n }\n\n if (!this.database) {\n return false;\n }\n\n if (this.getBranchCatalogKeys().some((branchKey) => {\n const branchChunkIds = this.database!.getBranchChunkIds(branchKey);\n if (branchChunkIds.length > 0) {\n return true;\n }\n\n return this.database!.getBranchSymbolIds(branchKey).length > 0;\n })) {\n return true;\n }\n\n const hasAnyBranchRows = this.database.getAllBranches().some((branchKey) => {\n const branchChunkIds = this.database!.getBranchChunkIds(branchKey);\n if (branchChunkIds.length > 0) {\n return true;\n }\n\n return this.database!.getBranchSymbolIds(branchKey).length > 0;\n });\n if (hasAnyBranchRows) {\n return false;\n }\n\n return this.store.getAllMetadata().some(({ metadata }) => this.isFileInCurrentScope(metadata.filePath, roots));\n }\n\n private loadStoredEmbeddingStrategyVersion(): string | null {\n if (!this.database) {\n return null;\n }\n\n if (this.hasProjectForceReembedPending()) {\n return null;\n }\n\n if (this.config.scope !== \"global\") {\n return this.database.getMetadata(\"index.embeddingStrategyVersion\") ?? \"1\";\n }\n\n const projectVersion = this.database.getMetadata(this.getProjectEmbeddingStrategyMetadataKey());\n if (projectVersion) {\n return projectVersion;\n }\n\n const legacySharedVersion = this.database.getMetadata(\"index.embeddingStrategyVersion\");\n if (legacySharedVersion && this.hasScopedIndexedData()) {\n return legacySharedVersion;\n }\n\n return null;\n }\n\n private getBranchCatalogKeys(): string[] {\n const primary = this.getBranchCatalogKey();\n if (this.config.scope !== \"global\") {\n return [primary];\n }\n\n if (this.database?.getMetadata(this.getLegacyMigrationMetadataKey()) === \"done\") {\n return [primary];\n }\n\n const legacy = this.getLegacyBranchCatalogKey();\n return primary === legacy ? [primary] : [primary, legacy];\n }\n\n private getBranchCatalogCleanupKeys(): string[] {\n const primary = this.getBranchCatalogKey();\n if (this.config.scope !== \"global\") {\n return [primary];\n }\n\n const legacy = this.getLegacyBranchCatalogKey();\n return primary === legacy ? [primary] : [primary, legacy];\n }\n\n private getProjectLocalScopedOwnershipIds(roots: string[], projectRoot = this.projectRoot): {\n chunkIds: Set<string>;\n symbolIds: Set<string>;\n } {\n const chunkIds = new Set<string>();\n const symbolIds = new Set<string>();\n if (!this.database) {\n return { chunkIds, symbolIds };\n }\n\n const projectLocalFilePaths = new Set<string>([\n ...Array.from(this.fileHashCache.keys()).filter(\n (filePath) => this.isFileInCurrentScope(filePath, roots) && this.isFileInProjectRoot(filePath, projectRoot)\n ),\n ...(this.store?.getAllMetadata() ?? [])\n .map(({ metadata }) => metadata.filePath)\n .filter(\n (filePath) => this.isFileInCurrentScope(filePath, roots) && this.isFileInProjectRoot(filePath, projectRoot)\n ),\n ]);\n\n for (const filePath of projectLocalFilePaths) {\n for (const chunk of this.database.getChunksByFile(filePath)) {\n chunkIds.add(chunk.chunkId);\n }\n\n for (const symbol of this.database.getSymbolsByFile(filePath)) {\n symbolIds.add(symbol.id);\n }\n }\n\n return { chunkIds, symbolIds };\n }\n\n private getProjectScopedBranchCatalogCleanupKeys(\n projectChunkIds: string[],\n projectSymbolIds: string[],\n projectRoot = this.projectRoot,\n ): string[] {\n if (this.config.scope !== \"global\") {\n return this.getBranchCatalogCleanupKeys();\n }\n\n const keys = new Set<string>();\n const projectChunkIdSet = new Set(projectChunkIds);\n const projectSymbolIdSet = new Set(projectSymbolIds);\n const projectIdentityHash = this.getProjectIdentityHash(projectRoot);\n\n for (const branchKey of this.database?.getAllBranches() ?? []) {\n if (branchKey.startsWith(`${projectIdentityHash}:`)) {\n keys.add(branchKey);\n continue;\n }\n\n const referencesProjectChunks = this.database?.getBranchChunkIds(branchKey).some((chunkId) => projectChunkIdSet.has(chunkId)) ?? false;\n const referencesProjectSymbols = this.database?.getBranchSymbolIds(branchKey).some((symbolId) => projectSymbolIdSet.has(symbolId)) ?? false;\n if (referencesProjectChunks || referencesProjectSymbols) {\n keys.add(branchKey);\n }\n }\n\n if (projectRoot === this.projectRoot) {\n for (const branchKey of this.getBranchCatalogCleanupKeys()) {\n keys.add(branchKey);\n }\n }\n\n return Array.from(keys);\n }\n\n private isFileInCurrentScope(filePath: string, roots: string[]): boolean {\n const canonicalFilePath = this.getCanonicalStoredFilePath(filePath);\n return roots.some((root) => isPathWithinRoot(canonicalFilePath, root));\n }\n\n private isFileInProjectRoot(filePath: string, projectRoot = this.projectRoot): boolean {\n return isPathWithinRoot(\n this.getCanonicalStoredFilePath(filePath),\n this.getCanonicalPath(projectRoot),\n );\n }\n\n private clearScopedFileHashCache(roots: string[]): void {\n for (const filePath of Array.from(this.fileHashCache.keys())) {\n if (this.isFileInCurrentScope(filePath, roots)) {\n this.fileHashCache.delete(filePath);\n }\n }\n this.saveFileHashCache();\n }\n\n private replaceScopedFileHashCache(currentFileHashes: Map<string, string>, roots: string[]): void {\n for (const filePath of Array.from(this.fileHashCache.keys())) {\n if (this.isFileInCurrentScope(filePath, roots)) {\n this.fileHashCache.delete(filePath);\n }\n }\n\n for (const [filePath, hash] of currentFileHashes) {\n this.fileHashCache.set(filePath, hash);\n }\n\n this.saveFileHashCache();\n }\n\n private clearScopedFailedBatches(roots: string[]): void {\n this.rewriteFailedBatchState((chunk) => {\n const filePath = getPendingChunkFilePath(chunk);\n return filePath === null || !this.isFileInCurrentScope(filePath, roots);\n });\n }\n\n private hasForeignScopedFileHashData(roots: string[]): boolean {\n return Array.from(this.fileHashCache.keys()).some((filePath) => !this.isFileInCurrentScope(filePath, roots));\n }\n\n private hasForeignScopedFailedBatches(roots: string[]): boolean {\n for (const batch of this.loadSerializedFailedBatches()) {\n if (batch.chunks.some((chunk) => {\n const filePath = getPendingChunkFilePath(chunk);\n return filePath === null || !this.isFileInCurrentScope(filePath, roots);\n })) {\n return true;\n }\n }\n return false;\n }\n\n private hasForeignScopedBranchData(\n projectRoot = this.projectRoot,\n roots = this.getScopedRoots(projectRoot),\n ): boolean {\n if (!this.database || this.config.scope !== \"global\") {\n return false;\n }\n\n const projectIdentityHash = this.getProjectIdentityHash(projectRoot);\n const { chunkIds: projectLocalChunkIds, symbolIds: projectLocalSymbolIds } = this.getProjectLocalScopedOwnershipIds(roots, projectRoot);\n\n return this.database.getAllBranches().some(\n (branchKey) => {\n const branchChunkIds = this.database!.getBranchChunkIds(branchKey);\n const branchSymbolIds = this.database!.getBranchSymbolIds(branchKey);\n const hasBranchData = branchChunkIds.length > 0 || branchSymbolIds.length > 0;\n if (!hasBranchData) {\n return false;\n }\n\n if (branchKey.startsWith(`${projectIdentityHash}:`)) {\n return false;\n }\n\n const referencesCurrentProjectChunks = branchChunkIds.some((chunkId) => projectLocalChunkIds.has(chunkId));\n const referencesCurrentProjectSymbols = branchSymbolIds.some((symbolId) => projectLocalSymbolIds.has(symbolId));\n return !(referencesCurrentProjectChunks || referencesCurrentProjectSymbols);\n }\n );\n }\n\n private clearSharedIndexProjectData(\n store: VectorStore,\n invertedIndex: InvertedIndex,\n database: Database,\n roots: string[],\n projectRoot = this.projectRoot,\n ): { removedChunkIds: string[]; hasForeignData: boolean } {\n const allMetadata = store.getAllMetadata();\n const scopedEntries = allMetadata.filter(({ metadata }) => this.isFileInCurrentScope(metadata.filePath, roots));\n const filePaths = new Set<string>([\n ...Array.from(this.fileHashCache.keys()).filter((filePath) => this.isFileInCurrentScope(filePath, roots)),\n ...scopedEntries.map(({ metadata }) => metadata.filePath),\n ]);\n\n const projectLocalFilePaths = new Set<string>(\n Array.from(filePaths).filter((filePath) => this.isFileInProjectRoot(filePath, projectRoot))\n );\n\n const removedChunkIds = new Set<string>(scopedEntries.map(({ key }) => key));\n for (const filePath of filePaths) {\n for (const chunk of database.getChunksByFile(filePath)) {\n removedChunkIds.add(chunk.chunkId);\n }\n }\n const removedChunkIdList = Array.from(removedChunkIds);\n\n const projectLocalChunkIds = new Set<string>(\n scopedEntries\n .filter(({ metadata }) => this.isFileInProjectRoot(metadata.filePath, projectRoot))\n .map(({ key }) => key)\n );\n for (const filePath of projectLocalFilePaths) {\n for (const chunk of database.getChunksByFile(filePath)) {\n projectLocalChunkIds.add(chunk.chunkId);\n }\n }\n\n const symbolIds: string[] = [];\n const projectLocalSymbolIds = new Set<string>();\n for (const filePath of filePaths) {\n for (const symbol of database.getSymbolsByFile(filePath)) {\n symbolIds.push(symbol.id);\n if (projectLocalFilePaths.has(filePath)) {\n projectLocalSymbolIds.add(symbol.id);\n }\n }\n }\n\n const branchCleanupKeys = this.getProjectScopedBranchCatalogCleanupKeys(\n Array.from(projectLocalChunkIds),\n Array.from(projectLocalSymbolIds),\n projectRoot,\n );\n for (const branchKey of branchCleanupKeys) {\n database.deleteBranchChunksForBranch(branchKey, removedChunkIdList);\n }\n const sharedChunkIds = new Set(database.getReferencedChunkIds(removedChunkIdList));\n const removableChunkIds = removedChunkIdList.filter((chunkId) => !sharedChunkIds.has(chunkId));\n\n if (removableChunkIds.length > 0) {\n this.rebuildVectorStoreExcludingChunkIds(store, database, removableChunkIds);\n for (const chunkId of removableChunkIds) {\n invertedIndex.removeChunk(chunkId);\n }\n }\n\n for (const branchKey of branchCleanupKeys) {\n database.deleteBranchSymbolsForBranch(branchKey, symbolIds);\n }\n this.deleteBranchCommitMetadata(database, branchCleanupKeys);\n const sharedSymbolIds = new Set(database.getReferencedSymbolIds(symbolIds));\n const removableSymbolIds = symbolIds.filter((symbolId) => !sharedSymbolIds.has(symbolId));\n\n database.clearCallEdgeTargetsForSymbols(removableSymbolIds);\n\n for (const filePath of filePaths) {\n const fileChunkIds = database.getChunksByFile(filePath).map((chunk) => chunk.chunkId);\n const fileSymbols = database.getSymbolsByFile(filePath);\n\n if (fileChunkIds.every((chunkId) => !sharedChunkIds.has(chunkId))) {\n database.deleteChunksByFile(filePath);\n }\n\n if (fileSymbols.every((symbol) => !sharedSymbolIds.has(symbol.id))) {\n database.deleteCallEdgesByFile(filePath);\n database.deleteSymbolsByFile(filePath);\n }\n }\n\n database.gcOrphanCallEdges();\n database.gcOrphanSymbols();\n database.gcOrphanEmbeddings();\n database.gcOrphanChunks();\n\n // Persist the keyword index before the vector store: a crash between the\n // two leaves the store as the conservative resume authority, so the next\n // run re-embeds and repopulates BM25 instead of skipping addChunk for\n // chunks whose vectors are already durable.\n this.saveInvertedIndex(invertedIndex);\n store.save();\n\n return {\n removedChunkIds: removedChunkIdList,\n hasForeignData: allMetadata.some(({ metadata }) => !this.isFileInCurrentScope(metadata.filePath, roots)),\n };\n }\n\n private getCurrentClearRecoveryState(): IndexLockClearRecoveryState {\n if (!this.configuredProviderInfo) {\n throw new Error(\"Cannot persist clear recovery state before the embedding provider is initialized\");\n }\n const compatibility = this.checkCompatibility();\n const compatibilityDecision = compatibility.compatible\n ? \"compatible\"\n : compatibility.code === IncompatibilityCode.EMBEDDING_STRATEGY_MISMATCH\n ? \"embedding-strategy-mismatch\"\n : \"incompatible\";\n return {\n phase: \"clearing\",\n embeddingProvider: this.configuredProviderInfo.provider,\n embeddingModel: this.configuredProviderInfo.modelInfo.model,\n embeddingDimensions: this.configuredProviderInfo.modelInfo.dimensions,\n embeddingStrategyVersion: EMBEDDING_STRATEGY_VERSION,\n compatibilityDecision,\n };\n }\n\n private beginClearRecoveryState(): IndexLockClearRecoveryState {\n const recovery = this.getCurrentClearRecoveryState();\n setIndexLockClearRecoveryState(this.requireActiveLease(), recovery);\n return recovery;\n }\n\n private finishClearRecoveryState(): void {\n setIndexLockClearRecoveryState(this.requireActiveLease(), null);\n }\n\n private matchesCurrentClearRecoveryConfiguration(recovery: IndexLockClearRecoveryState): boolean {\n const configuredProviderInfo = this.configuredProviderInfo;\n return configuredProviderInfo !== null\n && recovery.embeddingProvider === configuredProviderInfo.provider\n && recovery.embeddingModel === configuredProviderInfo.modelInfo.model\n && recovery.embeddingDimensions === configuredProviderInfo.modelInfo.dimensions\n && recovery.embeddingStrategyVersion === EMBEDDING_STRATEGY_VERSION;\n }\n\n private hasUnknownLegacyForceIndexClear(owner: IndexLockOwner): boolean {\n return owner.operation === \"force-index\"\n && owner.clearRecovery === undefined\n && owner.recoveryProtocolVersion !== 1\n && existsSync(path.join(this.indexPath, \"force-index-phase\"));\n }\n\n private async recoverFromInterruptedIndexingUnlocked(owners: readonly IndexLockOwner[]): Promise<void> {\n for (const owner of owners) {\n this.logger.warn(\"Detected interrupted indexing session, recovering...\", {\n pid: owner.pid,\n hostname: owner.hostname,\n operation: owner.operation,\n startedAt: owner.startedAt,\n projectRoot: owner.projectRoot,\n });\n }\n\n if (this.config.scope === \"global\") {\n const clearScopes: Array<{\n projectRoot: string;\n scopedRoots: string[];\n compatibilityDecision: IndexLockClearRecoveryState[\"compatibilityDecision\"];\n }> = [];\n for (const owner of owners) {\n if (this.hasUnknownLegacyForceIndexClear(owner)) {\n throw new Error(\n `Cannot automatically recover interrupted force-index ${owner.token}: ` +\n \"the legacy clearing phase ownership is unknown. The recovery marker was retained for manual inspection.\"\n );\n }\n if (\n owner.operation === \"clear\"\n && owner.clearRecovery === undefined\n && owner.recoveryProtocolVersion !== 1\n ) {\n throw new Error(\n `Cannot automatically recover interrupted global clear ${owner.token}: ` +\n \"the originating recovery state is unknown. The recovery marker was retained for manual inspection.\"\n );\n }\n if (owner.clearRecovery === undefined) continue;\n if (!owner.projectRoot || !owner.scopedRoots || owner.scopedRoots.length === 0) {\n throw new Error(\n `Cannot automatically recover interrupted global clear ${owner.token}: ` +\n \"the originating project scope is unknown. The recovery marker was retained for manual inspection.\"\n );\n }\n if (!this.matchesCurrentClearRecoveryConfiguration(owner.clearRecovery)) {\n throw new Error(\n `Cannot automatically recover interrupted global clear ${owner.token}: ` +\n \"the current embedding configuration does not match the originating lease. \" +\n \"The recovery marker was retained; retry from the originating project with matching settings.\"\n );\n }\n clearScopes.push({\n projectRoot: owner.projectRoot,\n scopedRoots: owner.scopedRoots,\n compatibilityDecision: owner.clearRecovery.compatibilityDecision,\n });\n }\n if (clearScopes.length > 0) {\n // The scoped clear purges the file-hash cache entries of the\n // originating project: load the persisted cache first so the purge\n // is written back instead of being lost on an empty in-memory map.\n this.loadFileHashCache();\n }\n for (const { projectRoot, scopedRoots, compatibilityDecision } of clearScopes) {\n // Re-apply the clear decision against the originating project scope:\n // a global clear only wipes the whole shared index when no foreign\n // project data is present, otherwise it stays scoped to the project\n // that started the clear.\n this.clearGlobalIndexUnlocked(projectRoot, scopedRoots, compatibilityDecision);\n }\n await this.healthCheckUnlocked();\n this.logger.info(\n clearScopes.length > 0\n ? \"Recovery complete, next index will rebuild all files\"\n : \"Recovery complete, next index will resume from the last checkpoint\",\n );\n return;\n }\n\n this.logger.info(\"Recovery complete, next index will resume from the last checkpoint\");\n }\n\n private *loadSerializedFailedBatches(): Generator<SerializedFailedBatch> {\n let warned = false;\n const warn = (error: unknown): void => {\n if (warned) return;\n warned = true;\n this.logger.warn(\"Failed to load failed batch state, skipping persisted retries\", {\n failedBatchesPath: this.failedBatchesPath,\n error: getErrorMessage(error),\n });\n };\n\n try {\n for (const record of readFailedBatchRecords<unknown>(this.failedBatchesPath, {\n malformedLineAction: \"skip\",\n onMalformedLine: (error) => warn(error),\n })) {\n yield {\n chunks: record.chunks,\n error: record.error,\n attemptCount: record.attemptCount,\n lastAttempt: record.lastAttempt,\n };\n }\n } catch (error) {\n warn(error);\n }\n }\n\n private createFailedBatchWriteState(): FailedBatchWriteState {\n return {\n writer: createFailedBatchWriter<unknown>(this.failedBatchesPath),\n recordsWritten: 0,\n };\n }\n\n private writeFailedBatchRecord(\n state: FailedBatchWriteState,\n record: FailedBatchRecordInput<unknown>,\n ): void {\n state.writer.write(record);\n state.recordsWritten += record.chunks.length;\n }\n\n private finalizeFailedBatchWriteState(\n state: FailedBatchWriteState,\n resolvedChunkIds: ReadonlySet<string> = new Set(),\n ): void {\n if (state.recordsWritten > 0) {\n // Deduplicate by chunk ID and drop resolved retries. Process in reverse\n // so the last-written record (highest attemptCount) wins; the\n // checkpoint reconstruction loop and the retry phase can both\n // materialize the same pending retry.\n const seenChunkIds = new Set<string>();\n const retained: FailedBatchRecordInput<unknown>[] = [];\n const records = Array.from(readFailedBatchRecords<unknown>(state.writer.temporaryPath));\n for (let i = records.length - 1; i >= 0; i--) {\n const chunks = records[i].chunks.filter((rawChunk) => {\n const chunkId = getPendingChunkId(rawChunk);\n if (chunkId !== null) {\n if (resolvedChunkIds.has(chunkId)) return false;\n if (seenChunkIds.has(chunkId)) return false;\n seenChunkIds.add(chunkId);\n }\n return true;\n });\n if (chunks.length > 0) {\n retained.unshift({ ...records[i], chunks });\n }\n }\n state.writer.cleanup();\n if (retained.length > 0) {\n writeFailedBatchRecords(this.failedBatchesPath, retained);\n } else {\n writeFailedBatchRecords(this.failedBatchesPath, []);\n this.clearFailedBatchState();\n }\n return;\n }\n\n state.writer.commit();\n this.clearFailedBatchState();\n }\n\n private getCheckpointIntervalChunks(totalChunks: number): number {\n return Math.max(\n this.checkpointIntervalChunks ?? 2000,\n Math.floor(totalChunks / 10),\n );\n }\n\n private checkpointIndexRun(\n database: Database,\n store: VectorStore,\n invertedIndex: InvertedIndex,\n failedProcessing: FailedBatchProcessingState,\n resolvedRetryChunkIds: ReadonlySet<string>,\n currentFileHashes: Map<string, string>,\n committedFilePaths: Set<string>,\n scopedRoots: string[] | null,\n configuredProviderInfo: ConfiguredProviderInfo,\n ): void {\n if (!this.hasProjectForceReembedPending()) {\n this.saveIndexMetadata(configuredProviderInfo);\n this.indexCompatibility = { compatible: true };\n }\n database.commitWriteTransaction();\n database.beginWriteTransaction();\n // Persist the keyword index before the vector store: a crash between the\n // two leaves the store as the conservative resume authority, so the next\n // run re-embeds and repopulates BM25 instead of skipping addChunk for\n // chunks whose vectors are already durable.\n this.saveInvertedIndex(invertedIndex);\n store.save();\n if (\n failedProcessing.state.recordsWritten > 0\n || failedProcessing.latestById.size > 0\n || failedProcessing.discardedExistingRecords\n ) {\n // Persist the pending retries alongside the written records so a crash\n // after this checkpoint cannot lose them.\n for (const metadata of failedProcessing.latestById.values()) {\n const alreadyMaterialized = metadata.chunks.some((rawChunk) => {\n const chunkId = getPendingChunkId(rawChunk);\n return chunkId !== null && failedProcessing.materializedRetryIds.has(chunkId);\n });\n if (alreadyMaterialized) continue;\n this.writeFailedBatchRecord(failedProcessing.state, {\n chunks: metadata.chunks,\n attemptCount: metadata.attemptCount,\n error: metadata.error,\n lastAttempt: metadata.lastAttempt,\n });\n for (const rawChunk of metadata.chunks) {\n const chunkId = getPendingChunkId(rawChunk);\n if (chunkId !== null) {\n failedProcessing.materializedRetryIds.add(chunkId);\n }\n }\n }\n this.finalizeFailedBatchWriteState(failedProcessing.state, resolvedRetryChunkIds);\n failedProcessing.state = this.createFailedBatchWriteState();\n failedProcessing.discardedExistingRecords = false;\n // Preserve the committed records (including out-of-scope projects'\n // failed batches) so finalization never deletes them.\n for (const record of this.loadSerializedFailedBatches()) {\n for (const rawChunk of record.chunks) {\n const chunkId = getPendingChunkId(rawChunk);\n this.writeFailedBatchRecord(failedProcessing.state, { ...record, chunks: [rawChunk] });\n if (chunkId !== null) {\n failedProcessing.materializedRetryIds.add(chunkId);\n }\n }\n }\n }\n const partialHashes = new Map<string, string>();\n for (const filePath of committedFilePaths) {\n const hash = currentFileHashes.get(filePath);\n if (hash !== undefined) {\n partialHashes.set(filePath, hash);\n }\n }\n if (scopedRoots) {\n this.replaceScopedFileHashCache(partialHashes, scopedRoots);\n } else {\n this.fileHashCache = partialHashes;\n this.saveFileHashCache();\n }\n }\n\n private clearFailedBatchState(): void {\n if (existsSync(this.failedBatchesPath)) {\n try {\n unlinkSync(this.failedBatchesPath);\n } catch {\n // Ignore cleanup failures; stale diagnostics are best-effort only.\n }\n }\n }\n\n private rewriteFailedBatchState(shouldRetain: (chunk: unknown) => boolean): void {\n const state = this.createFailedBatchWriteState();\n try {\n for (const batch of this.loadSerializedFailedBatches()) {\n const retainedChunks = batch.chunks.filter(shouldRetain);\n if (retainedChunks.length > 0) {\n this.writeFailedBatchRecord(state, { ...batch, chunks: retainedChunks });\n }\n }\n this.finalizeFailedBatchWriteState(state);\n } catch (error) {\n state.writer.cleanup();\n throw error;\n }\n }\n\n private prepareFailedBatchProcessing(\n roots: string[] | null,\n shouldProcess: (filePath: string | null) => boolean,\n ): FailedBatchProcessingState {\n const state = this.createFailedBatchWriteState();\n const latestById = new Map<string, FailedChunkRecordMetadata>();\n let discardedExistingRecords = false;\n\n try {\n for (const batch of this.loadSerializedFailedBatches()) {\n for (const rawChunk of batch.chunks) {\n const filePath = getPendingChunkFilePath(rawChunk);\n const inScope = roots === null || (filePath !== null && this.isFileInCurrentScope(filePath, roots));\n if (!inScope) {\n this.writeFailedBatchRecord(state, { ...batch, chunks: [rawChunk] });\n continue;\n }\n if (!shouldProcess(filePath)) {\n discardedExistingRecords = true;\n continue;\n }\n\n const chunkId = getPendingChunkId(rawChunk);\n if (!chunkId) {\n discardedExistingRecords = true;\n continue;\n }\n const existing = latestById.get(chunkId);\n if (!existing || batch.attemptCount >= existing.attemptCount) {\n latestById.set(chunkId, {\n attemptCount: batch.attemptCount,\n error: batch.error,\n lastAttempt: batch.lastAttempt,\n chunks: [rawChunk],\n });\n }\n }\n }\n return {\n state,\n latestById,\n materializedRetryIds: new Set(),\n discardedExistingRecords,\n };\n } catch (error) {\n state.writer.cleanup();\n throw error;\n }\n }\n\n private *iterateLatestFailedChunks(\n latestById: ReadonlyMap<string, FailedChunkRecordMetadata>,\n roots: string[] | null,\n shouldProcess: (filePath: string | null) => boolean,\n maxChunkTokens?: number,\n ): Generator<RetryableFailedChunkRecord> {\n const yielded = new Set<string>();\n for (const batch of this.loadSerializedFailedBatches()) {\n for (const rawChunk of batch.chunks) {\n const chunkId = getPendingChunkId(rawChunk);\n if (!chunkId || yielded.has(chunkId)) {\n continue;\n }\n const latest = latestById.get(chunkId);\n if (\n !latest ||\n latest.attemptCount !== batch.attemptCount ||\n latest.error !== batch.error ||\n latest.lastAttempt !== batch.lastAttempt\n ) {\n continue;\n }\n\n const filePath = getPendingChunkFilePath(rawChunk);\n const inScope = roots === null || (filePath !== null && this.isFileInCurrentScope(filePath, roots));\n if (!inScope || !shouldProcess(filePath)) {\n continue;\n }\n\n const normalized = normalizeFailedBatch({ ...batch, chunks: [rawChunk] }, maxChunkTokens);\n const chunk = normalized?.chunks[0];\n if (!chunk) {\n continue;\n }\n yielded.add(chunkId);\n yield {\n chunk,\n attemptCount: batch.attemptCount,\n };\n }\n }\n }\n\n private restoreMissingChunkRows(database: Database, chunks: readonly PendingChunk[]): void {\n const missing: ChunkData[] = [];\n for (const chunk of chunks) {\n if (database.getChunk(chunk.id)) {\n continue;\n }\n missing.push({\n chunkId: chunk.id,\n contentHash: chunk.contentHash,\n filePath: chunk.metadata.filePath,\n startLine: chunk.metadata.startLine,\n endLine: chunk.metadata.endLine,\n nodeType: chunk.metadata.chunkType,\n name: chunk.metadata.name,\n language: chunk.metadata.language,\n blameSha: chunk.metadata.blameSha,\n blameAuthor: chunk.metadata.blameAuthor,\n blameAuthorEmail: chunk.metadata.blameAuthorEmail,\n blameCommittedAt: chunk.metadata.blameCommittedAt,\n blameSummary: chunk.metadata.blameSummary,\n });\n }\n if (missing.length > 0) {\n database.upsertChunksBatch(missing);\n }\n }\n\n private getProviderRateLimits(provider: string): {\n concurrency: number;\n intervalMs: number;\n minRetryMs: number;\n maxRetryMs: number;\n } {\n switch (provider) {\n case \"openai\":\n return { concurrency: 3, intervalMs: 500, minRetryMs: 1000, maxRetryMs: 30000 };\n case \"google\":\n return { concurrency: 5, intervalMs: 200, minRetryMs: 1000, maxRetryMs: 30000 };\n case \"ollama\":\n return { concurrency: 5, intervalMs: 0, minRetryMs: 500, maxRetryMs: 5000 };\n case \"custom\": {\n // Custom providers allow user-configurable concurrency and request interval.\n // Defaults are conservative (3 concurrent, 1s interval) for cloud endpoints;\n // users running local servers should set concurrency higher and intervalMs to 0.\n const customConfig = this.config.customProvider;\n return {\n concurrency: customConfig?.concurrency ?? 3,\n intervalMs: customConfig?.requestIntervalMs ?? 1000,\n minRetryMs: 1000,\n maxRetryMs: 30000,\n };\n }\n default:\n return { concurrency: 3, intervalMs: 1000, minRetryMs: 1000, maxRetryMs: 30000 };\n }\n }\n\n private async processPendingChunkBatch(\n chunks: PendingChunk[],\n options: {\n store: VectorStore;\n provider: EmbeddingProviderInterface;\n invertedIndex: InvertedIndex;\n database: Database;\n configuredProviderInfo: ConfiguredProviderInfo;\n queue: PQueue;\n providerRateLimits: ReturnType<Indexer[\"getProviderRateLimits\"]>;\n rateLimitState: EmbeddingRateLimitState;\n failedState: FailedBatchWriteState;\n attemptCounts: Map<string, number>;\n forceReembed: boolean;\n reuseCachedEmbeddings: boolean;\n incrementRepeatedFailures: boolean;\n // When true (recovery path), embed previously-failed chunks one per request\n // so a permanently-failing chunk is isolated instead of failing its batch.\n forceSingleItemBatches?: boolean;\n onSucceeded?: (chunks: PendingChunk[]) => void;\n onProgress?: (progress: Readonly<PendingChunkBatchResult>) => void;\n },\n ): Promise<PendingChunkBatchResult> {\n const result: PendingChunkBatchResult = {\n indexedChunks: 0,\n failedChunks: 0,\n tokensUsed: 0,\n failedChunkIds: new Set<string>(),\n };\n if (chunks.length === 0) {\n return result;\n }\n\n const chunksNeedingEmbedding: PendingChunk[] = [];\n let cachedChunkCount = 0;\n if (options.reuseCachedEmbeddings && !options.forceReembed) {\n const missingHashes = new Set(options.database.getMissingEmbeddings(chunks.map((chunk) => chunk.contentHash)));\n for (const chunk of chunks) {\n if (missingHashes.has(chunk.contentHash)) {\n chunksNeedingEmbedding.push(chunk);\n continue;\n }\n\n const embeddingBuffer = options.database.getEmbedding(chunk.contentHash);\n if (!embeddingBuffer) {\n chunksNeedingEmbedding.push(chunk);\n continue;\n }\n\n options.store.add(chunk.id, Array.from(bufferToFloat32Array(embeddingBuffer)), chunk.metadata);\n options.invertedIndex.removeChunk(chunk.id);\n options.invertedIndex.addChunk(chunk.id, chunk.content);\n options.onSucceeded?.([chunk]);\n result.indexedChunks += 1;\n cachedChunkCount += 1;\n }\n } else {\n chunksNeedingEmbedding.push(...chunks);\n }\n\n this.logger.cache(\"info\", \"Embedding cache lookup\", {\n needsEmbedding: chunksNeedingEmbedding.length,\n fromCache: cachedChunkCount,\n });\n if (cachedChunkCount > 0) {\n this.logger.recordChunksFromCache(cachedChunkCount);\n options.onProgress?.(result);\n }\n\n if (chunksNeedingEmbedding.length === 0) {\n return result;\n }\n\n const pendingChunksById = new Map(chunksNeedingEmbedding.map((chunk) => [chunk.id, chunk]));\n const embeddingPartsByChunk = new Map<string, Array<{ vector: number[]; tokenCount: number } | undefined>>();\n const completedVectorsByChunkId = new Map<string, number[]>();\n const completedChunkIds = new Set<string>();\n const batchOptions = getDynamicBatchOptions(options.configuredProviderInfo, this.config.embedding?.batch);\n // On the recovery path, embed previously-failed chunks one per request so a\n // permanently-failing chunk is isolated instead of failing its whole batch.\n // Scoped to ollama (whose default batch size groups chunks); other providers\n // keep their existing recovery batching.\n if (options.forceSingleItemBatches && options.configuredProviderInfo.provider === \"ollama\") {\n batchOptions.maxBatchItems = 1;\n }\n const requestBatches = createPendingEmbeddingRequestBatches(chunksNeedingEmbedding, batchOptions);\n let fatalError: unknown;\n\n for (const requestBatch of requestBatches) {\n await options.queue.onSizeLessThan(Math.max(1, options.providerRateLimits.concurrency));\n const task = options.queue.add(async () => {\n if (options.rateLimitState.backoffMs > 0) {\n await new Promise(resolve => setTimeout(resolve, options.rateLimitState.backoffMs));\n }\n\n try {\n const embeddingResult = await pRetry(\n async () => {\n const texts = requestBatch.map((request) => request.text);\n return options.provider.embedBatch(texts);\n },\n {\n retries: this.config.indexing.retries,\n minTimeout: Math.max(this.config.indexing.retryDelayMs, options.providerRateLimits.minRetryMs),\n maxTimeout: options.providerRateLimits.maxRetryMs,\n factor: 2,\n shouldRetry: (error) => !((error as { error?: Error }).error instanceof CustomProviderNonRetryableError),\n onFailedAttempt: (error) => {\n const message = getErrorMessage(error);\n if (isRateLimitError(error)) {\n options.rateLimitState.backoffMs = Math.min(\n options.providerRateLimits.maxRetryMs,\n (options.rateLimitState.backoffMs || options.providerRateLimits.minRetryMs) * 2,\n );\n this.logger.embedding(\"warn\", \"Rate limited, backing off\", {\n attempt: error.attemptNumber,\n retriesLeft: error.retriesLeft,\n backoffMs: options.rateLimitState.backoffMs,\n });\n } else {\n this.logger.embedding(\"error\", \"Embedding batch failed\", {\n attempt: error.attemptNumber,\n error: message,\n });\n }\n },\n },\n );\n\n if (options.rateLimitState.backoffMs > 0) {\n options.rateLimitState.backoffMs = Math.max(0, options.rateLimitState.backoffMs - 2000);\n }\n\n const touchedChunkIds = new Set<string>();\n requestBatch.forEach((request, index) => {\n if (result.failedChunkIds.has(request.chunk.id) || completedChunkIds.has(request.chunk.id)) {\n return;\n }\n\n const vector = embeddingResult.embeddings[index];\n if (!vector) {\n throw new Error(`Embedding API returned too few vectors for chunk ${request.chunk.id}`);\n }\n\n const parts = embeddingPartsByChunk.get(request.chunk.id) ?? [];\n parts[request.partIndex] = {\n vector,\n tokenCount: request.tokenCount,\n };\n embeddingPartsByChunk.set(request.chunk.id, parts);\n touchedChunkIds.add(request.chunk.id);\n });\n\n const pooledResults: Array<{ chunk: PendingChunk; vector: number[] }> = [];\n for (const chunkId of touchedChunkIds) {\n if (result.failedChunkIds.has(chunkId) || completedChunkIds.has(chunkId)) {\n continue;\n }\n const chunk = pendingChunksById.get(chunkId);\n if (!chunk) {\n continue;\n }\n const parts = embeddingPartsByChunk.get(chunk.id) ?? [];\n if (!hasAllEmbeddingParts(parts, chunk.texts.length)) {\n continue;\n }\n\n const orderedParts = parts as Array<{ vector: number[]; tokenCount: number }>;\n pooledResults.push({\n chunk,\n vector: poolEmbeddingVectors(\n orderedParts.map((part) => part.vector),\n orderedParts.map((part) => part.tokenCount),\n ),\n });\n }\n\n if (pooledResults.length > 0) {\n options.database.upsertEmbeddingsBatch(pooledResults.map(({ chunk, vector }) => ({\n contentHash: chunk.contentHash,\n embedding: float32ArrayToBuffer(vector),\n chunkText: chunk.storageText,\n model: options.configuredProviderInfo.modelInfo.model,\n })));\n\n const succeededChunks = pooledResults.map(({ chunk }) => chunk);\n for (const { chunk, vector } of pooledResults) {\n completedVectorsByChunkId.set(chunk.id, vector);\n }\n for (const chunk of succeededChunks) {\n completedChunkIds.add(chunk.id);\n embeddingPartsByChunk.delete(chunk.id);\n }\n\n }\n\n result.tokensUsed += embeddingResult.totalTokensUsed;\n this.logger.recordEmbeddingApiCall(embeddingResult.totalTokensUsed);\n this.logger.embedding(\"debug\", \"Embedded batch\", {\n batchSize: pooledResults.length,\n requestCount: requestBatch.length,\n tokens: embeddingResult.totalTokensUsed,\n });\n } catch (error) {\n const failedChunks = getUniquePendingChunksFromRequests(requestBatch)\n .filter((chunk) => !completedChunkIds.has(chunk.id))\n .filter((chunk) => options.incrementRepeatedFailures || !result.failedChunkIds.has(chunk.id));\n const failureMessage = getErrorMessage(error);\n const failureTimestamp = new Date().toISOString();\n\n for (const chunk of failedChunks) {\n if (!result.failedChunkIds.has(chunk.id)) {\n result.failedChunkIds.add(chunk.id);\n result.failedChunks += 1;\n }\n embeddingPartsByChunk.delete(chunk.id);\n const attemptCount = (options.attemptCounts.get(chunk.id) ?? 0) + 1;\n options.attemptCounts.set(chunk.id, attemptCount);\n this.writeFailedBatchRecord(options.failedState, {\n chunks: [chunk],\n error: failureMessage,\n attemptCount,\n lastAttempt: failureTimestamp,\n });\n }\n\n this.logger.recordEmbeddingError();\n this.logger.embedding(\"error\", \"Failed to embed batch after retries\", {\n batchSize: failedChunks.length,\n requestCount: requestBatch.length,\n error: failureMessage,\n });\n }\n\n options.onProgress?.(result);\n });\n void task.catch((error: unknown) => {\n fatalError ??= error;\n });\n }\n\n await options.queue.onIdle();\n if (fatalError !== undefined) {\n throw fatalError;\n }\n\n const orderedSucceededChunks = chunksNeedingEmbedding.filter((chunk) => completedVectorsByChunkId.has(chunk.id));\n if (orderedSucceededChunks.length > 0) {\n try {\n options.store.addBatch(orderedSucceededChunks.map((chunk) => ({\n id: chunk.id,\n vector: completedVectorsByChunkId.get(chunk.id)!,\n metadata: chunk.metadata,\n })));\n for (const chunk of orderedSucceededChunks) {\n options.invertedIndex.removeChunk(chunk.id);\n options.invertedIndex.addChunk(chunk.id, chunk.content);\n }\n options.onSucceeded?.(orderedSucceededChunks);\n result.indexedChunks += orderedSucceededChunks.length;\n this.logger.recordChunksEmbedded(orderedSucceededChunks.length);\n } catch (error) {\n const failureMessage = getErrorMessage(error);\n const failureTimestamp = new Date().toISOString();\n for (const chunk of orderedSucceededChunks) {\n options.store.remove(chunk.id);\n options.invertedIndex.removeChunk(chunk.id);\n result.failedChunkIds.add(chunk.id);\n result.failedChunks += 1;\n const attemptCount = (options.attemptCounts.get(chunk.id) ?? 0) + 1;\n options.attemptCounts.set(chunk.id, attemptCount);\n this.writeFailedBatchRecord(options.failedState, {\n chunks: [chunk],\n error: failureMessage,\n attemptCount,\n lastAttempt: failureTimestamp,\n });\n }\n this.logger.recordEmbeddingError();\n this.logger.embedding(\"error\", \"Failed to publish embedded chunks\", {\n batchSize: orderedSucceededChunks.length,\n error: failureMessage,\n });\n }\n options.onProgress?.(result);\n }\n return result;\n }\n\n private async rerankCandidatesWithApi(\n query: string,\n candidates: RankedCandidate[],\n options?: {\n definitionIntent?: boolean;\n hasIdentifierHints?: boolean;\n }\n ): Promise<RankedCandidate[]> {\n const reranker = this.config.reranker;\n if (!reranker || !reranker.enabled || candidates.length <= 1) {\n return candidates;\n }\n\n const queryIntent = analyzeQueryIntent(query);\n const preferSourcePaths = queryIntent.preferSourcePaths;\n const docIntent = queryIntent.primary === \"docs\";\n\n if (options?.definitionIntent === true) {\n return candidates;\n }\n\n if (options?.hasIdentifierHints === true && preferSourcePaths && !docIntent) {\n return candidates;\n }\n\n const topN = Math.min(reranker.topN, candidates.length);\n const head = candidates.slice(0, topN);\n const tail = candidates.slice(topN);\n const grouped = new Map<ExternalRerankBand, RankedCandidate[]>([\n [\"implementation\", []],\n [\"documentation\", []],\n [\"test\", []],\n [\"config\", []],\n [\"other\", []],\n ]);\n\n for (const candidate of head) {\n const band = classifyExternalRerankBand(candidate, queryIntent);\n grouped.get(band)?.push(candidate);\n }\n\n const orderedBands: ExternalRerankBand[] = preferSourcePaths\n ? [\"implementation\", \"other\", \"config\", \"documentation\", \"test\"]\n : queryIntent.primary === \"docs\"\n ? [\"documentation\", \"implementation\", \"config\", \"other\", \"test\"]\n : queryIntent.primary === \"test\"\n ? [\"test\", \"implementation\", \"other\", \"documentation\", \"config\"]\n : queryIntent.primary === \"config\"\n ? [\"config\", \"implementation\", \"other\", \"documentation\", \"test\"]\n : [\"implementation\", \"other\", \"config\", \"documentation\", \"test\"];\n\n try {\n const rerankedHead: RankedCandidate[] = [];\n for (const band of orderedBands) {\n const bandCandidates = grouped.get(band) ?? [];\n if (bandCandidates.length <= 1) {\n rerankedHead.push(...bandCandidates);\n continue;\n }\n\n const documents = await Promise.all(\n bandCandidates.map(async (candidate) => ({\n id: candidate.id,\n text: await this.createRerankerDocumentText(candidate),\n }))\n );\n const rankedIds = await this.callExternalReranker(query, documents, reranker);\n if (rankedIds.length === 0) {\n rerankedHead.push(...bandCandidates);\n continue;\n }\n\n const order = new Map(rankedIds.map((id, index) => [id, index]));\n const bandReranked = [...bandCandidates].sort((a, b) => {\n const aRank = order.get(a.id) ?? Number.MAX_SAFE_INTEGER;\n const bRank = order.get(b.id) ?? Number.MAX_SAFE_INTEGER;\n if (aRank !== bRank) {\n return aRank - bRank;\n }\n if (b.score !== a.score) {\n return b.score - a.score;\n }\n return a.id.localeCompare(b.id);\n });\n const shouldDiversifyBand = !options?.hasIdentifierHints;\n rerankedHead.push(...diversifyCandidatesByFile(bandReranked, shouldDiversifyBand));\n }\n\n this.logger.search(\"debug\", \"Applied external reranker\", {\n provider: reranker.provider,\n model: reranker.model,\n candidateCount: head.length,\n bands: orderedBands,\n });\n\n return [...rerankedHead, ...tail];\n } catch (error) {\n this.logger.search(\"warn\", \"External reranker failed; using deterministic order\", {\n provider: reranker.provider,\n model: reranker.model,\n error: getErrorMessage(error),\n });\n return candidates;\n }\n }\n\n private async callExternalReranker(\n query: string,\n documents: RerankDocumentPayload[],\n reranker: RerankerConfig\n ): Promise<string[]> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (reranker.apiKey) {\n headers.Authorization = `Bearer ${reranker.apiKey}`;\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), reranker.timeoutMs);\n try {\n const response = await fetch(`${reranker.baseUrl}/rerank`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n model: reranker.model,\n query,\n documents: documents.map((document) => document.text),\n top_n: documents.length,\n return_documents: false,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Reranker API error: ${response.status} - ${await response.text()}`);\n }\n\n const body = await response.json() as {\n results?: Array<{ index?: number; relevance_score?: number }>;\n };\n if (!Array.isArray(body.results)) {\n throw new Error(\"Reranker API returned unexpected response format.\");\n }\n\n return body.results\n .map((result) => {\n const index = typeof result.index === \"number\" ? result.index : -1;\n return documents[index]?.id;\n })\n .filter((id): id is string => typeof id === \"string\");\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(`Reranker request timed out after ${reranker.timeoutMs}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private async createRerankerDocumentText(candidate: RankedCandidate): Promise<string> {\n const parts = [\n `path: ${candidate.metadata.filePath}`,\n `chunk_type: ${candidate.metadata.chunkType}`,\n `language: ${candidate.metadata.language}`,\n `lines: ${candidate.metadata.startLine}-${candidate.metadata.endLine}`,\n ];\n\n if (candidate.metadata.name) {\n parts.push(`name: ${candidate.metadata.name}`);\n }\n\n const intent = isLikelyImplementationPath(candidate.metadata.filePath) ? \"implementation\" : \"doc_or_test\";\n parts.push(`intent_hint: ${intent}`);\n\n try {\n const fileContent = await fsPromises.readFile(\n this.toMaterializedFilePath(candidate.metadata.filePath),\n \"utf-8\",\n );\n const lines = fileContent.split(\"\\n\");\n const snippetStartLine = Math.max(1, candidate.metadata.startLine);\n const snippetEndLine = Math.min(lines.length, candidate.metadata.endLine);\n const snippet = lines.slice(snippetStartLine - 1, snippetEndLine).join(\"\\n\").trim();\n parts.push(\"snippet:\");\n parts.push(snippet.length > 0 ? snippet : \"[empty]\");\n } catch {\n parts.push(\"snippet:\");\n parts.push(\"[unavailable]\");\n }\n\n return parts.join(\"\\n\");\n }\n\n async initialize(): Promise<void> {\n if (this.initializationPromise) {\n await this.initializationPromise;\n }\n if (this.isInitializedFor(\"reader\")) {\n return;\n }\n await this.initializeOnce(\"reader\", [], { skipAutoGc: true });\n }\n\n private async initializeOnce(\n mode: Exclude<InitializationMode, \"none\">,\n recoveredOwners: readonly IndexLockOwner[],\n options: { skipAutoGc?: boolean },\n ): Promise<void> {\n if (this.initializationPromise) {\n await this.initializationPromise;\n if (this.isInitializedFor(mode)) {\n return;\n }\n return this.initializeOnce(mode, recoveredOwners, options);\n }\n\n if (this.isInitializedFor(mode)) {\n return;\n }\n\n const initialization = this.initializeUnlocked(mode, recoveredOwners, options)\n .catch((error) => {\n this.resetLoadedIndexState();\n throw error;\n })\n .finally(() => {\n if (this.initializationPromise === initialization) {\n this.initializationPromise = null;\n }\n });\n this.initializationPromise = initialization;\n await initialization;\n }\n\n private isInitializedFor(mode: Exclude<InitializationMode, \"none\">): boolean {\n const hasState = Boolean(\n this.store &&\n this.provider &&\n this.invertedIndex &&\n this.configuredProviderInfo &&\n this.database,\n );\n if (!hasState) {\n return false;\n }\n return mode === \"reader\"\n ? this.initializationMode !== \"none\"\n : this.initializationMode === \"writer\";\n }\n\n private recordReadIssue(\n component: IndexReadIssue[\"component\"],\n message: string,\n error?: unknown,\n ): void {\n this.readIssues.push(this.createReadIssue(component, message));\n this.readerArtifactRetryAfter.set(component, Date.now() + READER_ARTIFACT_RETRY_INTERVAL_MS);\n this.logger.warn(message, error === undefined ? undefined : { error: getErrorMessage(error) });\n }\n\n private createReadIssue(\n component: IndexReadIssue[\"component\"],\n message: string,\n ): IndexReadIssue {\n return {\n component,\n message,\n blocking: component !== \"keyword\",\n };\n }\n\n private getVectorReadIssueMessage(): string {\n if (this.config.scope === \"global\") {\n return \"Shared vector index could not be read. Restore or repair the complete fingerprinted shared vector artifacts; automatic reset is disabled for global scope.\";\n }\n if (!this.isProjectOwnedIndexPath()) {\n return \"Vector index could not be read from an inherited project index. Restore or fingerprint it from the checkout that owns the index; do not remove or rebuild it from this worktree.\";\n }\n return \"Vector index could not be read. Run index_codebase after the active writer finishes to fingerprint a structurally valid legacy pair, or remove this checkout's local index directory and run index_codebase to rebuild it.\";\n }\n\n private getKeywordReadIssueMessage(): string {\n if (this.config.scope === \"global\") {\n return \"Shared keyword index could not be read; semantic search remains available. Restore or repair the shared keyword artifact; automatic reset is disabled for global scope.\";\n }\n if (!this.isProjectOwnedIndexPath()) {\n return \"Keyword index could not be read from an inherited project index; semantic search remains available. Restore or repair it from the checkout that owns the index; do not rebuild it from this worktree.\";\n }\n return \"Keyword index could not be read; semantic search remains available. Restore a readable published keyword index, or run index_codebase with force=true after the active writer finishes.\";\n }\n\n private getDatabaseReadIssueMessage(): string {\n if (this.config.scope === \"global\") {\n return \"Shared index database could not be read. Restore or repair the shared SQLite database; automatic reset is disabled for global scope.\";\n }\n if (!this.isProjectOwnedIndexPath()) {\n return \"Index database could not be read from an inherited project index. Restore or repair it from the checkout that owns the index; do not migrate or rebuild it from this worktree.\";\n }\n return \"Index database could not be read. Run index_codebase with force=true to rebuild a legacy absolute-path schema, or repair the database after the active writer finishes.\";\n }\n\n private getReaderFileFingerprint(filePath: string, identityOnly = false): string {\n try {\n const stats = statSync(filePath);\n if (identityOnly) {\n return `${stats.dev}:${stats.ino}`;\n }\n return `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeMs}:${stats.ctimeMs}`;\n } catch (error) {\n return `unavailable:${getErrorMessage(error)}`;\n }\n }\n\n private captureReaderArtifactFingerprint(): ReaderArtifactFingerprint {\n const storePath = path.join(this.indexPath, \"vectors\");\n return {\n vectors: `${this.getReaderFileFingerprint(storePath)}|${this.getReaderFileFingerprint(`${storePath}.meta.json`)}`,\n keyword: this.getReaderFileFingerprint(path.join(this.indexPath, \"inverted-index.json\")),\n database: this.getReaderFileFingerprint(path.join(this.indexPath, \"codebase.db\")),\n databaseIdentity: this.getReaderFileFingerprint(path.join(this.indexPath, \"codebase.db\"), true),\n };\n }\n\n private refreshReaderArtifacts(): void {\n if (this.initializationMode !== \"reader\" || !this.configuredProviderInfo) {\n return;\n }\n\n const previousFingerprint = this.readerArtifactFingerprint;\n const currentFingerprint = this.captureReaderArtifactFingerprint();\n const issues = new Map(this.readIssues.map((issue) => [issue.component, issue]));\n const retryDue = (component: IndexReadIssue[\"component\"]): boolean =>\n issues.has(component) && Date.now() >= (this.readerArtifactRetryAfter.get(component) ?? 0);\n const vectorsChanged = !previousFingerprint || currentFingerprint.vectors !== previousFingerprint.vectors;\n const keywordChanged = !previousFingerprint || currentFingerprint.keyword !== previousFingerprint.keyword;\n const databaseChanged = !previousFingerprint || currentFingerprint.database !== previousFingerprint.database;\n const databaseReplaced = !previousFingerprint || currentFingerprint.databaseIdentity !== previousFingerprint.databaseIdentity;\n if (\n previousFingerprint &&\n !vectorsChanged &&\n !keywordChanged &&\n !databaseChanged &&\n !Array.from(issues.keys()).some(retryDue)\n ) {\n return;\n }\n\n const setIssue = (\n component: IndexReadIssue[\"component\"],\n message: string,\n error?: unknown,\n ): void => {\n if (!issues.has(component)) {\n this.logger.warn(message, error === undefined ? undefined : { error: getErrorMessage(error) });\n }\n issues.set(component, this.createReadIssue(component, message));\n this.readerArtifactRetryAfter.set(component, Date.now() + READER_ARTIFACT_RETRY_INTERVAL_MS);\n };\n\n const storePath = path.join(this.indexPath, \"vectors\");\n const vectorMetadataPath = `${storePath}.meta.json`;\n const invertedIndexPath = path.join(this.indexPath, \"inverted-index.json\");\n const dbPath = path.join(this.indexPath, \"codebase.db\");\n\n if (\n vectorsChanged ||\n retryDue(\"vectors\")\n ) {\n const vectorStoreExists = existsSync(storePath);\n const vectorMetadataExists = existsSync(vectorMetadataPath);\n if (vectorStoreExists && vectorMetadataExists) {\n try {\n const store = new VectorStore(storePath, this.configuredProviderInfo.modelInfo.dimensions);\n store.loadStrict();\n this.store = store;\n issues.delete(\"vectors\");\n this.readerArtifactRetryAfter.delete(\"vectors\");\n } catch (error) {\n setIssue(\"vectors\", this.getVectorReadIssueMessage(), error);\n }\n } else if (vectorStoreExists !== vectorMetadataExists || issues.has(\"vectors\")) {\n setIssue(\"vectors\", this.getVectorReadIssueMessage());\n }\n }\n\n if (\n keywordChanged ||\n retryDue(\"keyword\") ||\n (!existsSync(invertedIndexPath) && (this.store?.count() ?? 0) > 0)\n ) {\n if (existsSync(invertedIndexPath)) {\n try {\n const invertedIndex = new InvertedIndex(invertedIndexPath);\n invertedIndex.load();\n this.invertedIndex = invertedIndex;\n issues.delete(\"keyword\");\n this.readerArtifactRetryAfter.delete(\"keyword\");\n } catch (error) {\n setIssue(\"keyword\", this.getKeywordReadIssueMessage(), error);\n }\n } else if ((this.store?.count() ?? 0) > 0 || issues.has(\"keyword\")) {\n setIssue(\"keyword\", this.getKeywordReadIssueMessage());\n }\n }\n\n if (\n databaseReplaced ||\n (databaseChanged && issues.has(\"database\")) ||\n retryDue(\"database\")\n ) {\n if (existsSync(dbPath)) {\n try {\n const database = Database.openReadOnly(dbPath);\n if (this.database) {\n this.retiredDatabases.push(this.database);\n }\n this.database = database;\n issues.delete(\"database\");\n this.readerArtifactRetryAfter.delete(\"database\");\n } catch (error) {\n setIssue(\"database\", this.getDatabaseReadIssueMessage(), error);\n }\n } else if ((this.store?.count() ?? 0) > 0 || issues.has(\"database\")) {\n setIssue(\"database\", this.getDatabaseReadIssueMessage());\n }\n }\n\n if (!issues.has(\"database\")) {\n try {\n this.indexCompatibility = this.validateIndexCompatibility(this.configuredProviderInfo);\n } catch (error) {\n setIssue(\"database\", this.getDatabaseReadIssueMessage(), error);\n }\n }\n\n this.readIssues = Array.from(issues.values());\n this.readerArtifactFingerprint = currentFingerprint;\n }\n\n private refreshInactiveWriterArtifacts(): boolean {\n if (this.initializationMode !== \"writer\" || this.activeIndexLease) {\n return true;\n }\n\n const previousFingerprint = this.writerArtifactFingerprint;\n const currentFingerprint = this.captureReaderArtifactFingerprint();\n const retryDue = this.readIssues.some((issue) =>\n Date.now() >= (this.readerArtifactRetryAfter.get(issue.component) ?? 0)\n );\n const artifactsChanged = !previousFingerprint ||\n currentFingerprint.vectors !== previousFingerprint.vectors ||\n currentFingerprint.keyword !== previousFingerprint.keyword ||\n currentFingerprint.database !== previousFingerprint.database ||\n currentFingerprint.databaseIdentity !== previousFingerprint.databaseIdentity;\n if (!artifactsChanged && !retryDue) {\n return true;\n }\n if (\n !previousFingerprint ||\n currentFingerprint.databaseIdentity !== previousFingerprint.databaseIdentity\n ) {\n return false;\n }\n\n this.initializationMode = \"reader\";\n this.readerArtifactFingerprint = previousFingerprint;\n try {\n this.refreshReaderArtifacts();\n this.writerArtifactFingerprint = this.readerArtifactFingerprint ?? currentFingerprint;\n } finally {\n this.readerArtifactFingerprint = null;\n this.initializationMode = \"writer\";\n }\n return true;\n }\n\n private async initializeUnlocked(\n mode: Exclude<InitializationMode, \"none\">,\n recoveredOwners: readonly IndexLockOwner[] = [],\n options: { skipAutoGc?: boolean } = {},\n ): Promise<void> {\n if (mode === \"writer\") {\n this.requireActiveLease();\n }\n this.readIssues = [];\n this.readerArtifactRetryAfter.clear();\n\n if (this.config.embeddingProvider === 'custom') {\n if (!this.config.customProvider) {\n throw new Error(\"embeddingProvider is 'custom' but customProvider config is missing.\");\n }\n this.configuredProviderInfo = createCustomProviderInfo(this.config.customProvider);\n } else if (this.config.embeddingProvider === 'auto') {\n this.configuredProviderInfo = await tryDetectProvider();\n } else {\n this.configuredProviderInfo = await detectEmbeddingProvider(this.config.embeddingProvider, this.config.embeddingModel);\n }\n\n if (!this.configuredProviderInfo) {\n throw new Error(\n \"No embedding provider available. Configure OpenAI, Google, Ollama, or a custom OpenAI-compatible endpoint.\"\n );\n }\n\n this.logger.info(\"Initializing indexer\", {\n provider: this.configuredProviderInfo.provider,\n model: this.configuredProviderInfo.modelInfo.model,\n scope: this.config.scope,\n rerankerEnabled: this.config.reranker?.enabled ?? false,\n });\n\n this.provider = createEmbeddingProvider(this.configuredProviderInfo);\n\n const dimensions = this.configuredProviderInfo.modelInfo.dimensions;\n const storePath = path.join(this.indexPath, \"vectors\");\n const vectorMetadataPath = `${storePath}.meta.json`;\n const invertedIndexPath = path.join(this.indexPath, \"inverted-index.json\");\n const dbPath = path.join(this.indexPath, \"codebase.db\");\n let dbIsNew = !existsSync(dbPath);\n const readerArtifactFingerprint = mode === \"reader\"\n ? this.captureReaderArtifactFingerprint()\n : null;\n\n if (mode === \"writer\") {\n await fsPromises.mkdir(this.indexPath, { recursive: true });\n\n // Interrupted recovery remains entirely under the writer lease.\n if (recoveredOwners.length > 0 && this.config.scope === \"project\" && !this.isProjectOwnedIndexPath()) {\n throw new Error(\n \"Interrupted indexing recovery is unsafe while using an inherited worktree index. \" +\n \"Run index_codebase with force=true to create a local project index boundary.\"\n );\n }\n for (const recoveredOwner of recoveredOwners) {\n recoverLeaseArtifacts(this.indexPath, recoveredOwner, [\n storePath,\n `${storePath}.meta.json`,\n ]);\n }\n if (recoveredOwners.length > 0 && this.config.scope === \"project\") {\n const unknownLegacyForceIndex = recoveredOwners.find(\n (owner) => this.hasUnknownLegacyForceIndexClear(owner),\n );\n if (unknownLegacyForceIndex) {\n throw new Error(\n `Cannot automatically recover interrupted force-index ${unknownLegacyForceIndex.token}: ` +\n \"the legacy clearing phase ownership is unknown. The recovery marker was retained for manual inspection.\"\n );\n }\n const shouldReset = recoveredOwners.some(\n (owner) => owner.clearRecovery !== undefined\n || (owner.operation === \"clear\" && owner.recoveryProtocolVersion !== 1),\n );\n if (shouldReset) {\n await this.resetLocalIndexArtifacts();\n }\n }\n\n this.store = new VectorStore(storePath, dimensions);\n if (existsSync(storePath) || existsSync(vectorMetadataPath)) {\n this.store.load();\n }\n\n this.invertedIndex = new InvertedIndex(invertedIndexPath);\n try {\n this.invertedIndex.load();\n } catch {\n if (existsSync(invertedIndexPath)) {\n await fsPromises.unlink(invertedIndexPath);\n }\n this.invertedIndex = new InvertedIndex(invertedIndexPath);\n }\n\n try {\n this.database = new Database(dbPath);\n } catch (error) {\n if (!(await this.tryResetCorruptedIndex(\"initializing index database\", error))) {\n throw error;\n }\n\n this.store = new VectorStore(storePath, dimensions);\n this.invertedIndex = new InvertedIndex(invertedIndexPath);\n this.database = new Database(dbPath);\n dbIsNew = true;\n }\n } else {\n this.store = new VectorStore(storePath, dimensions);\n const vectorStoreExists = existsSync(storePath);\n const vectorMetadataExists = existsSync(vectorMetadataPath);\n const vectorReadFailureMessage = this.getVectorReadIssueMessage();\n if (vectorStoreExists !== vectorMetadataExists) {\n this.recordReadIssue(\"vectors\", vectorReadFailureMessage);\n } else if (vectorStoreExists) {\n try {\n this.store.loadStrict();\n } catch (error) {\n this.recordReadIssue(\"vectors\", vectorReadFailureMessage, error);\n this.store = new VectorStore(storePath, dimensions);\n }\n }\n\n this.invertedIndex = new InvertedIndex(invertedIndexPath);\n if (existsSync(invertedIndexPath)) {\n try {\n this.invertedIndex.load();\n } catch (error) {\n this.recordReadIssue(\n \"keyword\",\n this.getKeywordReadIssueMessage(),\n error,\n );\n this.invertedIndex = new InvertedIndex(invertedIndexPath);\n }\n } else if (this.store.count() > 0) {\n this.recordReadIssue(\"keyword\", this.getKeywordReadIssueMessage());\n }\n\n if (existsSync(dbPath)) {\n try {\n this.database = Database.openReadOnly(dbPath);\n } catch (error) {\n this.recordReadIssue(\n \"database\",\n this.getDatabaseReadIssueMessage(),\n error,\n );\n this.database = Database.createEmptyReadOnly();\n }\n } else {\n this.database = Database.createEmptyReadOnly();\n if (this.store.count() > 0) {\n this.recordReadIssue(\n \"database\",\n `Index database is missing for the published vectors. ${this.getDatabaseReadIssueMessage()}`,\n );\n }\n }\n }\n\n if (isGitRepo(this.materializedProjectRoot)) {\n this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);\n this.baseBranch = getBaseBranch(this.materializedProjectRoot);\n this.logger.branch(\"info\", \"Detected git repository\", {\n currentBranch: this.currentBranch,\n baseBranch: this.baseBranch,\n });\n } else {\n this.currentBranch = \"default\";\n this.baseBranch = \"default\";\n this.logger.branch(\"debug\", \"Not a git repository, using default branch\");\n }\n this.refreshRuntimeArtifactPaths();\n\n if (mode === \"writer\" && recoveredOwners.length > 0) {\n await this.recoverFromInterruptedIndexingUnlocked(recoveredOwners);\n }\n\n if (mode === \"writer\" && dbIsNew && this.store.count() > 0) {\n this.migrateFromLegacyIndex();\n }\n\n this.loadFileHashCache();\n\n this.indexCompatibility = this.validateIndexCompatibility(this.configuredProviderInfo);\n if (!this.indexCompatibility.compatible) {\n this.logger.warn(\"Index compatibility issue detected\", {\n reason: this.indexCompatibility.reason,\n storedMetadata: this.indexCompatibility.storedMetadata,\n configuredProviderInfo: this.configuredProviderInfo,\n });\n }\n\n if (mode === \"writer\" && this.config.indexing.autoGc && !options.skipAutoGc) {\n await this.maybeRunAutoGc();\n }\n\n this.initializationMode = mode;\n this.readerArtifactFingerprint = readerArtifactFingerprint;\n }\n\n private async maybeRunAutoGc(): Promise<void> {\n if (!this.database) return;\n\n const lastGcTimestamp = this.database.getMetadata(\"lastGcTimestamp\");\n const now = Date.now();\n const intervalMs = this.config.indexing.gcIntervalDays * 24 * 60 * 60 * 1000;\n\n let shouldRunGc = false;\n if (!lastGcTimestamp) {\n // Never run GC before, run it now\n shouldRunGc = true;\n } else {\n const lastGcTime = parseInt(lastGcTimestamp, 10);\n if (!isNaN(lastGcTime) && now - lastGcTime > intervalMs) {\n shouldRunGc = true;\n }\n }\n\n if (shouldRunGc) {\n const result = await this.healthCheckUnlocked();\n if (result.warning) {\n this.database.setMetadata(STARTUP_WARNING_METADATA_KEY, result.warning);\n } else {\n this.database.deleteMetadata(STARTUP_WARNING_METADATA_KEY);\n }\n this.database.setMetadata(\"lastGcTimestamp\", now.toString());\n }\n }\n\n private async maybeRunOrphanGc(): Promise<CorruptedIndexResetResult | null> {\n if (!this.database) return null;\n\n const stats = this.database.getStats();\n if (!stats) return null;\n\n const orphanCount = stats.embeddingCount - stats.chunkCount;\n if (orphanCount > this.config.indexing.gcOrphanThreshold) {\n try {\n this.database.gcOrphanEmbeddings();\n this.database.gcOrphanChunks();\n } catch (error) {\n if (await this.tryResetCorruptedIndex(\"running automatic orphan garbage collection\", error)) {\n return {\n resetCorruptedIndex: true,\n warning: this.getCorruptedIndexWarning(path.join(this.indexPath, \"codebase.db\")),\n };\n }\n throw error;\n }\n this.database.setMetadata(\"lastGcTimestamp\", Date.now().toString());\n }\n\n return null;\n }\n\n private rebuildVectorStoreExcludingChunkIds(\n store: VectorStore,\n database: Database,\n excludedChunkIds: Iterable<string>\n ): void {\n const excludedSet = new Set(excludedChunkIds);\n if (excludedSet.size === 0) {\n return;\n }\n\n const retainedEntries = store\n .getAllMetadata()\n .filter(({ key }) => !excludedSet.has(key));\n\n const storeBasePath = path.join(this.indexPath, \"vectors\");\n const storeIndexPath = storeBasePath;\n const storeMetadataPath = `${storeBasePath}.meta.json`;\n const lease = this.requireActiveLease();\n const backupIndexPath = createLeaseTemporaryPath(storeIndexPath, lease.owner, \"bak\");\n const backupMetadataPath = createLeaseTemporaryPath(storeMetadataPath, lease.owner, \"bak\");\n\n let backedUpIndex = false;\n let backedUpMetadata = false;\n let rebuiltCount = 0;\n let skippedCount = 0;\n\n if (existsSync(backupIndexPath)) {\n unlinkSync(backupIndexPath);\n }\n if (existsSync(backupMetadataPath)) {\n unlinkSync(backupMetadataPath);\n }\n\n try {\n if (existsSync(storeIndexPath)) {\n renameSync(storeIndexPath, backupIndexPath);\n backedUpIndex = true;\n }\n if (existsSync(storeMetadataPath)) {\n renameSync(storeMetadataPath, backupMetadataPath);\n backedUpMetadata = true;\n }\n\n store.clear();\n\n for (const { key, metadata } of retainedEntries) {\n const chunk = database.getChunk(key);\n if (!chunk) {\n skippedCount += 1;\n continue;\n }\n\n const embeddingBuffer = database.getEmbedding(chunk.contentHash);\n if (!embeddingBuffer) {\n skippedCount += 1;\n continue;\n }\n\n const vector = bufferToFloat32Array(embeddingBuffer);\n store.add(key, Array.from(vector), metadata);\n rebuiltCount += 1;\n }\n\n store.save();\n\n if (backedUpIndex && existsSync(backupIndexPath)) {\n unlinkSync(backupIndexPath);\n }\n if (backedUpMetadata && existsSync(backupMetadataPath)) {\n unlinkSync(backupMetadataPath);\n }\n\n this.logger.gc(\"info\", \"Rebuilt vector store to avoid native remove\", {\n excludedChunks: excludedSet.size,\n rebuiltChunks: rebuiltCount,\n skippedChunks: skippedCount,\n });\n } catch (error) {\n try {\n store.clear();\n } catch {\n // Ignore best-effort cleanup before restore.\n }\n\n if (existsSync(storeIndexPath)) {\n unlinkSync(storeIndexPath);\n }\n if (existsSync(storeMetadataPath)) {\n unlinkSync(storeMetadataPath);\n }\n\n if (backedUpIndex && existsSync(backupIndexPath)) {\n renameSync(backupIndexPath, storeIndexPath);\n }\n if (backedUpMetadata && existsSync(backupMetadataPath)) {\n renameSync(backupMetadataPath, storeMetadataPath);\n }\n\n if (backedUpIndex || backedUpMetadata) {\n store.load();\n }\n\n throw error;\n }\n }\n\n private getCorruptedIndexWarning(dbPath: string): string {\n if (this.config.scope === \"global\") {\n return `Detected a corrupted shared global SQLite index at ${dbPath}. Automatic repair is disabled for global scope because it may delete other projects' index data. Remove or repair the shared index manually, then rerun index_codebase with force=true.`;\n }\n\n return `Detected a corrupted local SQLite index at ${dbPath} and reset the local index. Run index_codebase to rebuild search data.`;\n }\n\n private async removeProjectRuntimeStateArtifacts(): Promise<void> {\n if (!existsSync(this.indexPath)) return;\n\n const names = await fsPromises.readdir(this.indexPath);\n const runtimeStatePattern = /^(?:file-hashes|failed-batches)(?:\\.[a-f0-9]{16})?\\.json$/;\n await Promise.all(\n names\n .filter((name) => runtimeStatePattern.test(name))\n .map((name) => fsPromises.rm(path.join(this.indexPath, name), { force: true })),\n );\n }\n\n private async resetLocalIndexArtifacts(): Promise<void> {\n this.store = null;\n this.invertedIndex = null;\n this.database?.close();\n this.database = null;\n this.indexCompatibility = null;\n this.initializationMode = \"none\";\n this.readIssues = [];\n this.readerArtifactFingerprint = null;\n this.writerArtifactFingerprint = null;\n this.readerArtifactRetryAfter.clear();\n this.fileHashCache.clear();\n\n const resetPaths = [\n path.join(this.indexPath, \"codebase.db\"),\n path.join(this.indexPath, \"codebase.db-shm\"),\n path.join(this.indexPath, \"codebase.db-wal\"),\n path.join(this.indexPath, \"vectors\"),\n path.join(this.indexPath, \"vectors.usearch\"),\n path.join(this.indexPath, \"vectors.meta.json\"),\n path.join(this.indexPath, \"inverted-index.json\"),\n ];\n\n await Promise.all(resetPaths.map((targetPath) => fsPromises.rm(targetPath, { recursive: true, force: true })));\n await this.removeProjectRuntimeStateArtifacts();\n await fsPromises.mkdir(this.indexPath, { recursive: true });\n }\n\n private async tryResetCorruptedIndex(stage: string, error: unknown): Promise<boolean> {\n if (!isSqliteCorruptionError(error)) {\n return false;\n }\n\n const dbPath = path.join(this.indexPath, \"codebase.db\");\n const warning = this.getCorruptedIndexWarning(dbPath);\n const errorMessage = getErrorMessage(error);\n\n if (this.config.scope === \"global\") {\n this.logger.error(\"Detected corrupted shared global index database\", {\n stage,\n dbPath,\n error: errorMessage,\n });\n throw new Error(`${warning} Original SQLite error: ${errorMessage}`);\n }\n\n this.logger.warn(\"Detected corrupted local index database, resetting local index\", {\n stage,\n dbPath,\n error: errorMessage,\n });\n\n await this.resetLocalIndexArtifacts();\n return true;\n }\n\n private migrateFromLegacyIndex(): void {\n if (!this.store || !this.database) return;\n\n const allMetadata = this.store.getAllMetadata();\n const chunkIds: string[] = [];\n const chunkDataBatch: ChunkData[] = [];\n\n for (const { key, metadata } of allMetadata) {\n const chunkData: ChunkData = {\n chunkId: key,\n contentHash: metadata.hash,\n filePath: metadata.filePath,\n startLine: metadata.startLine,\n endLine: metadata.endLine,\n nodeType: metadata.chunkType,\n name: metadata.name,\n language: metadata.language,\n };\n chunkDataBatch.push(chunkData);\n chunkIds.push(key);\n }\n\n if (chunkDataBatch.length > 0) {\n this.database.upsertChunksBatch(chunkDataBatch);\n }\n this.database.addChunksToBranchBatch(this.getBranchCatalogKey(), chunkIds);\n }\n\n private getExpectedPathStorageVersion(): string {\n return this.config.scope === \"project\"\n ? PROJECT_PATH_STORAGE_VERSION\n : GLOBAL_PATH_STORAGE_VERSION;\n }\n\n private hasStoredIndexData(): boolean {\n const stats = this.database?.getStats();\n return (this.store?.count() ?? 0) > 0\n || (stats?.chunkCount ?? 0) > 0\n || (stats?.symbolCount ?? 0) > 0\n || this.fileHashCache.size > 0;\n }\n\n private loadIndexMetadata(): IndexMetadata | null {\n if (!this.database) return null;\n\n const version = this.database.getMetadata(\"index.version\");\n if (!version) return null;\n\n return {\n indexVersion: version,\n pathStorageVersion: this.database.getMetadata(\"index.pathStorageVersion\") ?? GLOBAL_PATH_STORAGE_VERSION,\n embeddingProvider: this.database.getMetadata(\"index.embeddingProvider\") ?? \"\",\n embeddingModel: this.database.getMetadata(\"index.embeddingModel\") ?? \"\",\n embeddingDimensions: parseInt(this.database.getMetadata(\"index.embeddingDimensions\") ?? \"0\", 10),\n embeddingStrategyVersion: this.loadStoredEmbeddingStrategyVersion() ?? EMBEDDING_STRATEGY_VERSION,\n createdAt: this.database.getMetadata(\"index.createdAt\") ?? \"\",\n updatedAt: this.database.getMetadata(\"index.updatedAt\") ?? \"\",\n };\n }\n\n private saveIndexMetadata(provider: ConfiguredProviderInfo): void {\n if (!this.database) return;\n\n const now = new Date().toISOString();\n const existingCreatedAt = this.database.getMetadata(\"index.createdAt\");\n const completeProjectEmbeddingStrategyReset = !this.hasProjectForceReembedPending();\n\n this.database.setMetadata(\"index.version\", INDEX_METADATA_VERSION);\n this.database.setMetadata(\"index.pathStorageVersion\", this.getExpectedPathStorageVersion());\n this.database.setMetadata(\"index.embeddingProvider\", provider.provider);\n this.database.setMetadata(\"index.embeddingModel\", provider.modelInfo.model);\n this.database.setMetadata(\"index.embeddingDimensions\", provider.modelInfo.dimensions.toString());\n this.database.setMetadata(this.getCallGraphResolutionMetadataKey(), CALL_GRAPH_RESOLUTION_VERSION);\n if (this.config.scope === \"global\") {\n if (completeProjectEmbeddingStrategyReset) {\n this.database.setMetadata(this.getProjectEmbeddingStrategyMetadataKey(), EMBEDDING_STRATEGY_VERSION);\n }\n this.database.setMetadata(this.getLegacyMigrationMetadataKey(), \"done\");\n if (completeProjectEmbeddingStrategyReset) {\n this.database.deleteMetadata(this.getProjectForceReembedMetadataKey());\n }\n } else {\n this.database.setMetadata(\"index.embeddingStrategyVersion\", EMBEDDING_STRATEGY_VERSION);\n }\n this.database.setMetadata(\"index.updatedAt\", now);\n\n if (!existingCreatedAt) {\n this.database.setMetadata(\"index.createdAt\", now);\n }\n }\n\n private validateIndexCompatibility(provider: ConfiguredProviderInfo): IndexCompatibility {\n const storedMetadata = this.loadIndexMetadata();\n\n const storedPathStorageVersion = this.database?.getMetadata(\"index.pathStorageVersion\")\n ?? GLOBAL_PATH_STORAGE_VERSION;\n const expectedPathStorageVersion = this.getExpectedPathStorageVersion();\n if (this.hasStoredIndexData() && storedPathStorageVersion !== expectedPathStorageVersion) {\n return {\n compatible: false,\n code: IncompatibilityCode.PATH_STORAGE_MISMATCH,\n reason: `Path storage format mismatch: index uses v${storedPathStorageVersion} checkout-absolute paths, but this project requires portable v${expectedPathStorageVersion} paths. Run index_codebase with force=true to rebuild the shared project index once.`,\n storedMetadata: storedMetadata ?? undefined,\n };\n }\n\n if (!storedMetadata) {\n return { compatible: true };\n }\n\n const currentProvider = provider.provider;\n const currentModel = provider.modelInfo.model;\n const currentDimensions = provider.modelInfo.dimensions;\n\n if (storedMetadata.embeddingDimensions !== currentDimensions) {\n return {\n compatible: false,\n code: IncompatibilityCode.DIMENSION_MISMATCH,\n reason: `Dimension mismatch: index has ${storedMetadata.embeddingDimensions}D vectors (${storedMetadata.embeddingProvider}/${storedMetadata.embeddingModel}), but current provider uses ${currentDimensions}D (${currentProvider}/${currentModel}). Run index_codebase with force=true to rebuild.`,\n storedMetadata,\n };\n }\n\n if (storedMetadata.embeddingModel !== currentModel) {\n return {\n compatible: false,\n code: IncompatibilityCode.MODEL_MISMATCH,\n reason: `Model mismatch: index was built with \"${storedMetadata.embeddingModel}\", but current model is \"${currentModel}\". Embeddings are incompatible. Run index_codebase with force=true to rebuild.`,\n storedMetadata,\n };\n }\n\n if (storedMetadata.embeddingStrategyVersion !== EMBEDDING_STRATEGY_VERSION) {\n return {\n compatible: false,\n code: IncompatibilityCode.EMBEDDING_STRATEGY_MISMATCH,\n reason: `Embedding strategy mismatch: index was built with embedding strategy v${storedMetadata.embeddingStrategyVersion}, but the current code requires v${EMBEDDING_STRATEGY_VERSION}. Run index_codebase with force=true to rebuild cached embeddings.`,\n storedMetadata,\n };\n }\n\n if (storedMetadata.embeddingProvider !== currentProvider) {\n this.logger.warn(\"Provider changed\", {\n storedProvider: storedMetadata.embeddingProvider,\n currentProvider,\n });\n }\n\n return {\n compatible: true,\n storedMetadata,\n };\n }\n\n checkCompatibility(): IndexCompatibility {\n if (!this.indexCompatibility) {\n if (!this.configuredProviderInfo) {\n throw new Error('No embedding provider info, you must initialize the indexer first.');\n }\n\n this.indexCompatibility = this.validateIndexCompatibility(this.configuredProviderInfo);\n }\n return this.indexCompatibility;\n }\n\n private async ensureInitialized(): Promise<{\n store: VectorStore;\n provider: EmbeddingProviderInterface;\n invertedIndex: InvertedIndex;\n configuredProviderInfo: ConfiguredProviderInfo;\n database: Database;\n readIssues: readonly IndexReadIssue[];\n compatibility: IndexCompatibility;\n }> {\n this.refreshBranchInfo();\n let initializedReader = false;\n while (true) {\n if (this.initializationPromise) {\n await this.initializationPromise;\n }\n if (!this.isInitializedFor(\"reader\")) {\n await this.initialize();\n initializedReader = true;\n continue;\n }\n if (\n this.initializationMode === \"writer\" &&\n !this.activeIndexLease &&\n !initializedReader\n ) {\n if (!this.refreshInactiveWriterArtifacts()) {\n this.resetLoadedIndexState(true);\n await this.initialize();\n initializedReader = true;\n continue;\n }\n }\n if (\n this.initializationMode === \"reader\" &&\n !initializedReader\n ) {\n this.refreshReaderArtifacts();\n }\n const state = this.requireLoadedIndexState();\n return {\n ...state,\n readIssues: [...this.readIssues],\n compatibility: this.indexCompatibility ?? this.validateIndexCompatibility(state.configuredProviderInfo),\n };\n }\n }\n\n private async ensureInitializedUnlocked(recoveredOwners: readonly IndexLockOwner[] = []): Promise<{\n store: VectorStore;\n provider: EmbeddingProviderInterface;\n invertedIndex: InvertedIndex;\n configuredProviderInfo: ConfiguredProviderInfo;\n database: Database;\n }> {\n this.requireActiveLease();\n\n if (this.initializationPromise) {\n await this.initializationPromise;\n }\n\n if (recoveredOwners.length > 0 || !this.isInitializedFor(\"writer\")) {\n const retireReaderDatabase = this.initializationMode === \"reader\";\n this.resetLoadedIndexState(retireReaderDatabase);\n await this.initializeOnce(\"writer\", recoveredOwners, { skipAutoGc: true });\n } else {\n this.refreshLoadedIndexState();\n }\n if (this.config.indexing.autoGc) {\n await this.maybeRunAutoGc();\n }\n return this.requireLoadedIndexState();\n }\n\n private requireReadableComponents(\n readIssues: readonly IndexReadIssue[],\n ...components: IndexReadIssue[\"component\"][]\n ): void {\n const componentSet = new Set(components);\n const issues = readIssues.filter((issue) => issue.blocking && componentSet.has(issue.component));\n if (issues.length > 0) {\n throw new Error(issues.map((issue) => issue.message).join(\" \"));\n }\n }\n\n private requireLoadedIndexState(): {\n store: VectorStore;\n provider: EmbeddingProviderInterface;\n invertedIndex: InvertedIndex;\n configuredProviderInfo: ConfiguredProviderInfo;\n database: Database;\n } {\n if (!this.store || !this.provider || !this.invertedIndex || !this.configuredProviderInfo || !this.database) {\n throw new Error(\"Index state is not initialized\");\n }\n return {\n store: this.store,\n provider: this.provider,\n invertedIndex: this.invertedIndex,\n configuredProviderInfo: this.configuredProviderInfo,\n database: this.database,\n };\n }\n\n async estimateCost(): Promise<CostEstimate> {\n const { configuredProviderInfo } = await this.ensureInitialized();\n\n const includePatterns = [...this.config.include, ...this.config.additionalInclude];\n const { files } = await collectFiles(\n this.materializedProjectRoot,\n includePatterns,\n this.config.exclude,\n this.config.indexing.maxFileSize,\n this.getMaterializedKnowledgeBases(),\n { maxDepth: this.config.indexing.maxDepth, maxFilesPerDirectory: this.config.indexing.maxFilesPerDirectory }\n );\n\n return createCostEstimate(files, configuredProviderInfo);\n }\n\n // Dry-run counterpart to index()/forceIndex(): parse the real file set and sum\n // estimateTokens over the embedding text of every indexable chunk, without\n // calling the embedding provider or writing to the index. Read-only and\n // lock-free (mirrors estimateCost). The token sum is the exact value \"Tokens\n // used\" climbs to for a force index (cache bypassed); for an incremental it is\n // an upper bound because cached chunks are counted here but not re-embedded.\n // Used by index_codebase(dryRun:true) to give a stable, monotonic progress\n // denominator that matches the live \"Tokens used\" basis.\n async dryRunCost(): Promise<DryRunEstimate> {\n const { configuredProviderInfo } = await this.ensureInitialized();\n const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);\n const includePatterns = [...this.config.include, ...this.config.additionalInclude];\n const { files } = await collectFiles(\n this.materializedProjectRoot,\n includePatterns,\n this.config.exclude,\n this.config.indexing.maxFileSize,\n this.getMaterializedKnowledgeBases(),\n { maxDepth: this.config.indexing.maxDepth, maxFilesPerDirectory: this.config.indexing.maxFilesPerDirectory },\n );\n\n let filesCount = 0;\n let chunksCount = 0;\n let tokensToEmbed = 0;\n // Parse in the same ordered batches as index() (fileBatchLimits) so the\n // memory profile matches a real run. For each file: read, parse, apply the\n // same fallback-to-text + maxChunksPerFile cap + selectIndexableChunks path,\n // then sum estimateTokens over the embedding text (createEmbeddingTexts)\n // — the identical basis the provider reports as \"Tokens used\".\n for (const batch of iterateOrderedFileBatches(files, (f) => f.size, this.fileBatchLimits)) {\n const loadedFiles = await Promise.all(batch.map(async (f) => {\n try {\n return {\n path: this.toStoredFilePath(f.path),\n content: await fsPromises.readFile(f.path, \"utf-8\"),\n };\n } catch {\n // Unreadable file: index() records a parse failure and skips it.\n return null;\n }\n }));\n const readable = loadedFiles.filter(\n (f): f is { path: string; content: string } => f !== null,\n );\n filesCount += readable.length;\n const contentByPath = new Map(readable.map((f) => [f.path, f.content]));\n const parsedFiles = parseFiles(readable, this.config.indexing.linesPerChunk);\n for (const parsed of parsedFiles) {\n let chunksToProcess = parsed.chunks;\n if (\n this.config.indexing.fallbackToTextOnMaxChunks &&\n chunksToProcess.length > this.config.indexing.maxChunksPerFile\n ) {\n const content = contentByPath.get(parsed.path);\n if (content !== undefined) {\n chunksToProcess = parseFileAsText(parsed.path, content, this.config.indexing.linesPerChunk);\n }\n }\n chunksToProcess = selectIndexableChunks(\n chunksToProcess,\n this.config.indexing.maxChunksPerFile,\n this.config.indexing.semanticOnly,\n );\n for (const chunk of chunksToProcess) {\n const texts = createEmbeddingTexts(chunk, parsed.path, maxChunkTokens);\n // Count one per source chunk (matches stats.indexedChunks); a chunk may\n // split into multiple embedding texts, which are summed into tokensToEmbed.\n chunksCount += 1;\n for (const text of texts) {\n tokensToEmbed += estimateTokens(text);\n }\n }\n }\n }\n\n return { filesCount, chunksCount, tokensToEmbed };\n }\n\n async index(onProgress?: ProgressCallback): Promise<IndexStats> {\n return this.withIndexMutationLease(\"index\", async (recoveredOwners) => {\n return this.indexUnlocked(onProgress, recoveredOwners);\n });\n }\n\n async indexBranchIfMissing(\n branch: string,\n commit: string,\n onProgress?: ProgressCallback,\n ): Promise<BranchIndexResult> {\n if (!isFullGitCommit(commit)) {\n throw new Error(`Branch commit is invalid: ${JSON.stringify(commit)}`);\n }\n const normalizedCommit = commit.toLowerCase();\n if (this.expectedCommitOverride && normalizedCommit !== this.expectedCommitOverride) {\n throw new Error(\n `Prepared branch commit ${normalizedCommit} does not match authoritative commit ${this.expectedCommitOverride}.`,\n );\n }\n if (branch !== this.currentBranch && this.initializationMode !== \"none\") {\n throw new Error(\n `Prepared Indexer branch mismatch: expected ${JSON.stringify(branch)}, got ${JSON.stringify(this.currentBranch)}.`,\n );\n }\n\n return this.withIndexMutationLease(\"index\", async (recoveredOwners) => {\n const { database } = await this.ensureInitializedUnlocked(recoveredOwners);\n if (branch !== this.currentBranch) {\n throw new Error(\n `Prepared Indexer branch mismatch: expected ${JSON.stringify(branch)}, got ${JSON.stringify(this.currentBranch)}.`,\n );\n }\n const branchKey = this.getBranchCatalogKey();\n const alreadyIndexed = database.getBranchChunkIds(branchKey).length > 0\n && database.getBranchSymbolIds(branchKey).length > 0;\n const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database);\n if (alreadyIndexed && migrationsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {\n return { prepared: false };\n }\n\n const stats = await this.indexUnlocked(onProgress, [], true);\n return { prepared: true, stats };\n });\n }\n\n private async indexUnlocked(\n onProgress?: ProgressCallback,\n recoveredOwners: readonly IndexLockOwner[] = [],\n stateReady = false,\n ): Promise<IndexStats> {\n const { store, provider, invertedIndex, database, configuredProviderInfo } = stateReady\n ? this.requireLoadedIndexState()\n : await this.ensureInitializedUnlocked(recoveredOwners);\n const materializedCommit = isGitRepo(this.materializedProjectRoot)\n ? await resolveLocalGitCommit(this.materializedProjectRoot, \"HEAD\")\n : null;\n if (this.expectedCommitOverride && materializedCommit !== this.expectedCommitOverride) {\n throw new Error(\n `Materialized repository HEAD ${materializedCommit ?? \"did not resolve\"}; expected ${this.expectedCommitOverride}.`,\n );\n }\n const indexedCommit = this.expectedCommitOverride ?? materializedCommit;\n const scopedRoots = this.config.scope === \"global\" ? this.getScopedRoots() : null;\n const branchCatalogKey = this.getBranchCatalogKey();\n const previousBranchChunkIds = database.getBranchChunkIds(branchCatalogKey);\n const previousBranchChunkIdSet = new Set(previousBranchChunkIds);\n const previousBranchSymbolIds = database.getBranchSymbolIds(branchCatalogKey);\n const previousBranchSymbolIdSet = new Set(previousBranchSymbolIds);\n const restrictExistingChunksToBranch = this.branchNameOverride !== undefined\n || previousBranchChunkIds.length > 0\n || database.getAllBranches().length > 0;\n const forceScopedReembed = scopedRoots !== null && database.getMetadata(this.getProjectForceReembedMetadataKey()) === \"true\";\n const failedForcedChunkIds = new Set<string>();\n\n if (!this.indexCompatibility?.compatible) {\n throw new Error(\n `${this.indexCompatibility?.reason} ` +\n `Run index_codebase with force=true to rebuild the index.`,\n );\n }\n\n this.logger.recordIndexingStart();\n this.logger.info(\"Starting indexing\", { projectRoot: this.projectRoot });\n\n const startTime = Date.now();\n const stats: IndexStats = {\n totalFiles: 0,\n totalChunks: 0,\n indexedChunks: 0,\n failedChunks: 0,\n tokensUsed: 0,\n durationMs: 0,\n existingChunks: 0,\n removedChunks: 0,\n skippedFiles: [],\n parseFailures: [],\n };\n\n onProgress?.({\n phase: \"scanning\",\n filesProcessed: 0,\n totalFiles: 0,\n chunksProcessed: 0,\n totalChunks: 0,\n });\n\n this.loadFileHashCache();\n\n const swiftParserMetadataKey = this.getSwiftParserVersionMetadataKey();\n const reparseCachedSwiftFiles = database.getMetadata(swiftParserMetadataKey) !== SWIFT_PARSER_VERSION;\n const metalParserMetadataKey = this.getMetalParserVersionMetadataKey();\n const reparseCachedMetalFiles = database.getMetadata(metalParserMetadataKey) !== METAL_PARSER_VERSION;\n const symbolExtractorMetadataKey = this.getSymbolExtractorVersionMetadataKey();\n const refreshCachedSymbols = database.getMetadata(symbolExtractorMetadataKey) !== SYMBOL_EXTRACTOR_VERSION;\n if (\n reparseCachedSwiftFiles &&\n Array.from(this.fileHashCache.keys()).some((filePath) => path.extname(filePath).toLowerCase() === \".swift\")\n ) {\n this.logger.info(\"Reindexing cached Swift files for parser support\");\n }\n if (\n reparseCachedMetalFiles &&\n Array.from(this.fileHashCache.keys()).some((filePath) => path.extname(filePath).toLowerCase() === \".metal\")\n ) {\n this.logger.info(\"Reindexing cached Metal files for parser support\");\n }\n\n const includePatterns = [...this.config.include, ...this.config.additionalInclude];\n const { files, skipped } = await collectFiles(\n this.materializedProjectRoot,\n includePatterns,\n this.config.exclude,\n this.config.indexing.maxFileSize,\n this.getMaterializedKnowledgeBases(),\n { maxDepth: this.config.indexing.maxDepth, maxFilesPerDirectory: this.config.indexing.maxFilesPerDirectory },\n );\n\n stats.totalFiles = files.length;\n stats.skippedFiles = skipped.map((entry) => ({\n ...entry,\n path: this.toCanonicalFilePath(entry.path),\n }));\n\n this.logger.recordFilesScanned(files.length);\n this.logger.cache(\"debug\", \"Scanning files for changes\", {\n totalFiles: files.length,\n skippedFiles: skipped.length,\n });\n\n const changedFileDescriptors: ChangedFileDescriptor[] = [];\n const unchangedFilePaths = new Set<string>();\n const currentFileHashes = new Map<string, string>();\n const needsCallGraphResolutionMigration =\n database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION;\n\n for (const file of files) {\n const storedPath = this.toStoredFilePath(file.path);\n let currentHash: string;\n try {\n currentHash = hashFile(file.path);\n } catch (error) {\n // A file that is unreadable at the OS level (e.g., an LSM denial that\n // returns EPERM despite readable mode bits, or a permissions error)\n // must not abort the whole index. The hash step opens the file; a bare\n // throw here previously tore down the entire run. Skip the file and\n // continue so the remaining files index.\n stats.skippedFiles.push({ path: this.toCanonicalFilePath(file.path), reason: \"unreadable\" });\n this.logger.warn(\"Skipped unreadable file during indexing\", {\n path: file.path,\n error: getErrorMessage(error),\n });\n continue;\n }\n currentFileHashes.set(storedPath, currentHash);\n\n const cachedHashMatches = this.fileHashCache.get(storedPath) === currentHash;\n const needsCallGraphRefresh = cachedHashMatches &&\n needsCallGraphResolutionMigration &&\n database.getChunksByFile(storedPath).some((chunk) =>\n chunk.language === \"php\" || chunk.language === \"c\" || chunk.language === \"cpp\"\n );\n const requiresSwiftParserUpgrade =\n reparseCachedSwiftFiles && path.extname(storedPath).toLowerCase() === \".swift\";\n const requiresMetalParserUpgrade =\n reparseCachedMetalFiles && path.extname(storedPath).toLowerCase() === \".metal\";\n const inMigrationScope =\n forceScopedReembed && scopedRoots !== null && this.isFileInCurrentScope(storedPath, scopedRoots);\n\n if (\n cachedHashMatches &&\n !inMigrationScope &&\n !needsCallGraphRefresh &&\n !requiresSwiftParserUpgrade &&\n !requiresMetalParserUpgrade &&\n !refreshCachedSymbols\n ) {\n unchangedFilePaths.add(storedPath);\n this.logger.recordCacheHit();\n } else {\n changedFileDescriptors.push({\n storedPath,\n materializedPath: file.path,\n hash: currentHash,\n sourceBytes: file.size,\n });\n this.logger.recordCacheMiss();\n }\n }\n\n this.logger.cache(\"info\", \"File hash cache results\", {\n unchanged: unchangedFilePaths.size,\n changed: changedFileDescriptors.length,\n });\n\n onProgress?.({\n phase: \"parsing\",\n filesProcessed: unchangedFilePaths.size,\n totalFiles: files.length,\n chunksProcessed: 0,\n totalChunks: 0,\n });\n\n const existingChunks = new Map<string, string>();\n const existingChunksByFile = new Map<string, Set<string>>();\n const existingMetadataById = new Map<string, ChunkMetadata>();\n for (const { key, metadata } of store.getAllMetadata()) {\n if (scopedRoots && !this.isFileInCurrentScope(metadata.filePath, scopedRoots)) {\n continue;\n }\n if (\n restrictExistingChunksToBranch &&\n this.isFileInProjectRoot(metadata.filePath) &&\n !previousBranchChunkIdSet.has(key)\n ) {\n continue;\n }\n if (forceScopedReembed && scopedRoots && this.isFileInCurrentScope(metadata.filePath, scopedRoots)) {\n continue;\n }\n existingChunks.set(key, metadata.hash);\n existingMetadataById.set(key, metadata);\n const fileChunks = existingChunksByFile.get(metadata.filePath) ?? new Set<string>();\n fileChunks.add(key);\n existingChunksByFile.set(metadata.filePath, fileChunks);\n }\n\n const currentChunkIds = new Set<string>();\n const allSymbolIds = new Set<string>();\n const failedChunkIds = new Set<string>();\n const retryableChunksWithExistingData = new Set<string>();\n const gitBlameEnabled = this.config.indexing.gitBlame.enabled && isGitRepo(this.materializedProjectRoot);\n let backfilledBlameMetadata = false;\n\n for (const filePath of unchangedFilePaths) {\n const fileChunks = existingChunksByFile.get(filePath);\n if (fileChunks) {\n for (const chunkId of fileChunks) {\n currentChunkIds.add(chunkId);\n }\n }\n }\n\n const shouldRetryFailedPath = (filePath: string | null): boolean =>\n filePath !== null && currentFileHashes.has(filePath) && unchangedFilePaths.has(filePath);\n const failedProcessing = this.prepareFailedBatchProcessing(scopedRoots, shouldRetryFailedPath);\n const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);\n const providerRateLimits = this.getProviderRateLimits(configuredProviderInfo.provider);\n const queue = new PQueue({\n concurrency: providerRateLimits.concurrency,\n interval: providerRateLimits.intervalMs,\n intervalCap: providerRateLimits.concurrency,\n });\n const rateLimitState: EmbeddingRateLimitState = { backoffMs: 0 };\n let writeTransactionActive = false;\n\n try {\n database.beginWriteTransaction();\n writeTransactionActive = true;\n\n const blameChunkDataBatch: ChunkData[] = [];\n if (gitBlameEnabled) {\n const backfillItems: Array<{ id: string; vector: number[]; metadata: ChunkMetadata }> = [];\n for (const chunkId of currentChunkIds) {\n const metadata = existingMetadataById.get(chunkId);\n if (!metadata || hasBlameMetadata(metadata)) {\n continue;\n }\n const chunk = database.getChunk(chunkId);\n if (!chunk) {\n continue;\n }\n\n const blame = await getChunkGitBlame(\n this.materializedProjectRoot,\n this.toMaterializedFilePath(chunk.filePath),\n chunk.startLine,\n chunk.endLine,\n );\n const blameMetadata = metadataFromBlame(blame);\n if (!blameMetadata.blameSha) {\n continue;\n }\n\n blameChunkDataBatch.push({\n ...chunk,\n blameSha: blameMetadata.blameSha,\n blameAuthor: blameMetadata.blameAuthor,\n blameAuthorEmail: blameMetadata.blameAuthorEmail,\n blameCommittedAt: blameMetadata.blameCommittedAt,\n blameSummary: blameMetadata.blameSummary,\n });\n const embeddingBuffer = database.getEmbedding(chunk.contentHash);\n if (embeddingBuffer) {\n backfillItems.push({\n id: chunkId,\n vector: Array.from(bufferToFloat32Array(embeddingBuffer)),\n metadata: { ...metadata, ...blameMetadata },\n });\n }\n }\n\n if (blameChunkDataBatch.length > 0) {\n database.upsertChunksBatch(blameChunkDataBatch);\n }\n if (backfillItems.length > 0) {\n store.addBatch(backfillItems);\n backfilledBlameMetadata = true;\n }\n }\n\n for (const filePath of unchangedFilePaths) {\n for (const symbol of database.getSymbolsByFile(filePath)) {\n if (!restrictExistingChunksToBranch || previousBranchSymbolIdSet.has(symbol.id)) {\n allSymbolIds.add(symbol.id);\n }\n }\n }\n\n let processedChangedFiles = 0;\n let lastCheckpointChunks = 0;\n const committedFilePaths = new Set<string>(unchangedFilePaths);\n const resolvedRetryChunkIds = new Set<string>();\n for (const descriptorBatch of iterateOrderedFileBatches(\n changedFileDescriptors,\n (descriptor) => descriptor.sourceBytes,\n this.fileBatchLimits,\n )) {\n const loadedFiles = await Promise.all(descriptorBatch.map(async (descriptor) => ({\n path: descriptor.storedPath,\n content: await fsPromises.readFile(descriptor.materializedPath, \"utf-8\"),\n hash: descriptor.hash,\n })));\n const loadedByPath = new Map(loadedFiles.map((file) => [file.path, file]));\n const descriptorByPath = new Map(descriptorBatch.map((descriptor) => [descriptor.storedPath, descriptor]));\n const parseStartTime = performance.now();\n const parsedFiles = parseFiles(loadedFiles, this.config.indexing.linesPerChunk);\n const parseMs = performance.now() - parseStartTime;\n this.logger.recordFilesParsed(parsedFiles.length);\n this.logger.recordParseDuration(parseMs);\n this.logger.debug(\"Parsed changed file batch\", {\n parsedCount: parsedFiles.length,\n parseMs: parseMs.toFixed(2),\n });\n\n const chunkDataBatch: ChunkData[] = [];\n const pendingChunks: PendingChunk[] = [];\n const symbolBatch: SymbolData[] = [];\n const edgeBatch: CallEdgeData[] = [];\n\n for (const parsed of parsedFiles) {\n const loadedFile = loadedByPath.get(parsed.path);\n const descriptor = descriptorByPath.get(parsed.path);\n if (!loadedFile || !descriptor) {\n throw new Error(`Parsed file was not present in its source batch: ${parsed.path}`);\n }\n\n if (parsed.chunks.length === 0) {\n stats.parseFailures.push(path.isAbsolute(parsed.path)\n ? path.relative(this.projectRoot, parsed.path)\n : parsed.path);\n }\n\n let chunksToProcess = parsed.chunks;\n if (\n this.config.indexing.fallbackToTextOnMaxChunks &&\n chunksToProcess.length > this.config.indexing.maxChunksPerFile\n ) {\n chunksToProcess = parseFileAsText(parsed.path, loadedFile.content, this.config.indexing.linesPerChunk);\n }\n chunksToProcess = selectIndexableChunks(\n chunksToProcess,\n this.config.indexing.maxChunksPerFile,\n this.config.indexing.semanticOnly,\n );\n\n for (const chunk of chunksToProcess) {\n const id = this.getPreparedChunkId(generateChunkId(parsed.path, chunk));\n const contentHash = generateChunkHash(chunk);\n const existingContentHash = existingChunks.get(id);\n const existingChunk = gitBlameEnabled ? database.getChunk(id) : null;\n const blame = gitBlameEnabled && existingContentHash !== contentHash\n ? await getChunkGitBlame(\n this.materializedProjectRoot,\n descriptor.materializedPath,\n chunk.startLine,\n chunk.endLine,\n )\n : blameFromChunkData(existingChunk);\n const blameMetadata = metadataFromBlame(blame);\n currentChunkIds.add(id);\n\n chunkDataBatch.push({\n chunkId: id,\n contentHash,\n filePath: parsed.path,\n startLine: chunk.startLine,\n endLine: chunk.endLine,\n nodeType: chunk.chunkType,\n name: chunk.name,\n language: chunk.language,\n blameSha: blameMetadata.blameSha,\n blameAuthor: blameMetadata.blameAuthor,\n blameAuthorEmail: blameMetadata.blameAuthorEmail,\n blameCommittedAt: blameMetadata.blameCommittedAt,\n blameSummary: blameMetadata.blameSummary,\n });\n\n if (existingContentHash === contentHash) {\n continue;\n }\n\n const texts = createEmbeddingTexts(chunk, parsed.path, maxChunkTokens).map((text) => ({\n text,\n tokenCount: estimateTokens(text),\n }));\n pendingChunks.push({\n id,\n texts,\n storageText: createPendingChunkStorageText(texts),\n content: chunk.content,\n contentHash,\n metadata: {\n filePath: parsed.path,\n startLine: chunk.startLine,\n endLine: chunk.endLine,\n chunkType: chunk.chunkType,\n name: chunk.name,\n language: chunk.language,\n hash: contentHash,\n ...blameMetadata,\n },\n });\n }\n\n const fileSymbols: SymbolData[] = [];\n for (const parsedSymbol of parsed.symbols) {\n if (!CALL_GRAPH_SYMBOL_CHUNK_TYPES.has(parsedSymbol.kind)) {\n continue;\n }\n const preparedNamespace = this.getPreparedBranchNamespace();\n const symbolId = `sym_${hashContent(\n (preparedNamespace ? `${preparedNamespace}:` : \"\") +\n parsed.path + \":\" + parsedSymbol.name + \":\" + parsedSymbol.kind + \":\" +\n parsedSymbol.startLine + \":\" + parsedSymbol.startCol + \":\" + descriptor.hash,\n ).slice(0, 16)}`;\n const symbol: SymbolData = {\n id: symbolId,\n filePath: parsed.path,\n name: parsedSymbol.name,\n kind: parsedSymbol.kind,\n startLine: parsedSymbol.startLine,\n startCol: parsedSymbol.startCol,\n endLine: parsedSymbol.endLine,\n endCol: parsedSymbol.endCol,\n language: parsedSymbol.language,\n };\n fileSymbols.push(symbol);\n symbolBatch.push(symbol);\n allSymbolIds.add(symbolId);\n }\n\n const fileLanguage = parsed.symbols[0]?.language ?? parsed.chunks[0]?.language;\n if (!fileLanguage || !CALL_GRAPH_LANGUAGES.has(fileLanguage)) {\n continue;\n }\n const isCaseInsensitiveLanguage = CASE_INSENSITIVE_LANGUAGES.has(fileLanguage);\n const normalizeSymbolKey = (name: string): string =>\n isCaseInsensitiveLanguage ? name.toLowerCase() : name;\n const symbolsByName = new Map<string, SymbolData[]>();\n for (const symbol of fileSymbols) {\n const key = normalizeSymbolKey(symbol.name);\n const symbols = symbolsByName.get(key) ?? [];\n symbols.push(symbol);\n symbolsByName.set(key, symbols);\n }\n\n for (const site of extractCalls(loadedFile.content, fileLanguage)) {\n const enclosingSymbol = findEnclosingSymbol(fileSymbols, site.line, site.column);\n if (!enclosingSymbol) {\n continue;\n }\n\n let candidates = symbolsByName.get(normalizeSymbolKey(site.calleeName));\n if (fileLanguage === \"php\" && candidates) {\n if (site.callType === \"Constructor\") {\n candidates = candidates.filter((candidate) => PHP_CLASS_SYMBOL_CHUNK_TYPES.has(candidate.kind));\n } else if (site.callType === \"Call\") {\n candidates = candidates.filter((candidate) => PHP_FUNCTION_SYMBOL_CHUNK_TYPES.has(candidate.kind));\n }\n }\n candidates = candidates?.filter((symbol) =>\n isCompatibleCFamilyCallTarget(fileLanguage, site.callType, symbol.kind)\n );\n const resolvedTarget = candidates?.length === 1 ? candidates[0] : undefined;\n edgeBatch.push({\n id: `edge_${hashContent(\n enclosingSymbol.id + \":\" + site.calleeName + \":\" + site.line + \":\" + site.column,\n ).slice(0, 16)}`,\n fromSymbolId: enclosingSymbol.id,\n targetName: site.calleeName,\n toSymbolId: resolvedTarget?.id,\n callType: site.callType,\n confidence: site.confidence,\n line: site.line,\n col: site.column,\n isResolved: resolvedTarget !== undefined,\n });\n }\n }\n\n if (chunkDataBatch.length > 0) {\n database.upsertChunksBatch(chunkDataBatch);\n }\n if (symbolBatch.length > 0) {\n database.upsertSymbolsBatch(symbolBatch);\n database.addSymbolsToBranchBatch(\n this.getBranchCatalogKey(),\n symbolBatch.map((symbol) => symbol.id),\n );\n }\n if (edgeBatch.length > 0) {\n database.upsertCallEdgesBatch(edgeBatch);\n }\n\n processedChangedFiles += descriptorBatch.length;\n stats.totalChunks += pendingChunks.length;\n onProgress?.({\n phase: \"parsing\",\n filesProcessed: unchangedFilePaths.size + processedChangedFiles,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks,\n totalChunks: stats.totalChunks,\n });\n\n if (pendingChunks.length > 0) {\n onProgress?.({\n phase: \"embedding\",\n filesProcessed: unchangedFilePaths.size + processedChangedFiles,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks,\n totalChunks: stats.totalChunks,\n });\n const batchResult = await this.processPendingChunkBatch(pendingChunks, {\n store,\n provider,\n invertedIndex,\n database,\n configuredProviderInfo,\n queue,\n providerRateLimits,\n rateLimitState,\n failedState: failedProcessing.state,\n attemptCounts: new Map<string, number>(),\n forceReembed: forceScopedReembed,\n reuseCachedEmbeddings: true,\n incrementRepeatedFailures: true,\n onSucceeded: (succeededChunks) => {\n database.addChunksToBranchBatch(\n this.getBranchCatalogKey(),\n succeededChunks.map((chunk) => chunk.id),\n );\n },\n onProgress: (batchProgress) => onProgress?.({\n phase: \"embedding\",\n filesProcessed: unchangedFilePaths.size + processedChangedFiles,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks + batchProgress.indexedChunks,\n totalChunks: stats.totalChunks,\n }),\n });\n stats.indexedChunks += batchResult.indexedChunks;\n stats.failedChunks += batchResult.failedChunks;\n stats.tokensUsed += batchResult.tokensUsed;\n for (const chunkId of batchResult.failedChunkIds) {\n failedChunkIds.add(chunkId);\n if (forceScopedReembed) {\n failedForcedChunkIds.add(chunkId);\n }\n }\n }\n\n for (const descriptor of descriptorBatch) {\n const existingFileChunks = existingChunksByFile.get(descriptor.storedPath);\n if (!existingFileChunks || existingFileChunks.size === 0) {\n committedFilePaths.add(descriptor.storedPath);\n }\n }\n const checkpointInterval = this.getCheckpointIntervalChunks(stats.totalChunks);\n if (stats.totalChunks - lastCheckpointChunks >= checkpointInterval) {\n lastCheckpointChunks = stats.totalChunks;\n this.checkpointIndexRun(\n database,\n store,\n invertedIndex,\n failedProcessing,\n resolvedRetryChunkIds,\n currentFileHashes,\n committedFilePaths,\n scopedRoots,\n configuredProviderInfo,\n );\n }\n }\n\n const retryableFailedChunks = this.iterateLatestFailedChunks(\n failedProcessing.latestById,\n scopedRoots,\n shouldRetryFailedPath,\n maxChunkTokens,\n );\n for (const retryBatch of iterateOrderedFileBatches(\n retryableFailedChunks,\n ({ chunk }) => Buffer.byteLength(chunk.content, \"utf-8\"),\n this.fileBatchLimits,\n )) {\n const pendingChunks = retryBatch.map(({ chunk }) => chunk);\n const attemptCounts = new Map(retryBatch.map(({ chunk, attemptCount }) => [chunk.id, attemptCount]));\n for (const chunk of pendingChunks) {\n currentChunkIds.add(chunk.id);\n if (existingChunks.has(chunk.id)) {\n retryableChunksWithExistingData.add(chunk.id);\n }\n }\n // A failed chunk checkpointed before its embedding attempt has a\n // committed SQLite row only when the parsing phase upserted it; a\n // crash before that checkpoint can leave the row missing while the\n // failed-batches record survives. Restore the row so the retry does\n // not leave a branch reference without chunk metadata.\n this.restoreMissingChunkRows(database, pendingChunks);\n stats.totalChunks += pendingChunks.length;\n onProgress?.({\n phase: \"embedding\",\n filesProcessed: files.length,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks,\n totalChunks: stats.totalChunks,\n });\n const batchResult = await this.processPendingChunkBatch(pendingChunks, {\n store,\n provider,\n invertedIndex,\n database,\n configuredProviderInfo,\n queue,\n providerRateLimits,\n rateLimitState,\n failedState: failedProcessing.state,\n attemptCounts,\n forceReembed: forceScopedReembed,\n reuseCachedEmbeddings: true,\n incrementRepeatedFailures: true,\n forceSingleItemBatches: true,\n onSucceeded: (succeededChunks) => {\n database.addChunksToBranchBatch(\n this.getBranchCatalogKey(),\n succeededChunks.map((chunk) => chunk.id),\n );\n for (const chunk of succeededChunks) {\n failedProcessing.latestById.delete(chunk.id);\n resolvedRetryChunkIds.add(chunk.id);\n }\n },\n onProgress: (batchProgress) => onProgress?.({\n phase: \"embedding\",\n filesProcessed: files.length,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks + batchProgress.indexedChunks,\n totalChunks: stats.totalChunks,\n }),\n });\n stats.indexedChunks += batchResult.indexedChunks;\n stats.failedChunks += batchResult.failedChunks;\n stats.tokensUsed += batchResult.tokensUsed;\n for (const chunkId of batchResult.failedChunkIds) {\n failedChunkIds.add(chunkId);\n if (forceScopedReembed) {\n failedForcedChunkIds.add(chunkId);\n }\n }\n if (stats.totalChunks - lastCheckpointChunks >= this.getCheckpointIntervalChunks(stats.totalChunks)) {\n lastCheckpointChunks = stats.totalChunks;\n this.checkpointIndexRun(\n database,\n store,\n invertedIndex,\n failedProcessing,\n resolvedRetryChunkIds,\n currentFileHashes,\n committedFilePaths,\n scopedRoots,\n configuredProviderInfo,\n );\n }\n }\n\n const removedChunkIds: string[] = [];\n for (const [chunkId] of existingChunks) {\n if (!currentChunkIds.has(chunkId)) {\n removedChunkIds.push(chunkId);\n }\n }\n const removedCount = removedChunkIds.length;\n stats.existingChunks = currentChunkIds.size - stats.totalChunks;\n stats.removedChunks = removedCount;\n\n this.logger.recordChunksProcessed(currentChunkIds.size);\n this.logger.recordChunksRemoved(removedCount);\n this.logger.info(\"Chunk analysis complete\", {\n pending: stats.totalChunks,\n existing: stats.existingChunks,\n removed: removedCount,\n });\n\n if (stats.totalChunks === 0 && removedCount === 0) {\n const removedStoredChunks = this.replaceBranchCatalog(\n store,\n invertedIndex,\n database,\n branchCatalogKey,\n previousBranchChunkIds,\n Array.from(currentChunkIds),\n previousBranchSymbolIds,\n Array.from(allSymbolIds),\n );\n const vectorPath = path.join(this.indexPath, \"vectors\");\n const shouldFingerprintLegacyPair = !store.hasFingerprint() &&\n existsSync(vectorPath) &&\n existsSync(`${vectorPath}.meta.json`);\n if (backfilledBlameMetadata || shouldFingerprintLegacyPair || removedStoredChunks) {\n store.save();\n }\n if (removedStoredChunks) {\n this.saveInvertedIndex(invertedIndex);\n }\n database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);\n database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);\n database.setMetadata(symbolExtractorMetadataKey, SYMBOL_EXTRACTOR_VERSION);\n this.saveBranchCommit(database, indexedCommit);\n this.saveIndexMetadata(configuredProviderInfo);\n this.indexCompatibility = { compatible: true };\n database.commitWriteTransaction();\n writeTransactionActive = false;\n this.finalizeFailedBatchWriteState(failedProcessing.state, resolvedRetryChunkIds);\n if (scopedRoots) {\n this.replaceScopedFileHashCache(currentFileHashes, scopedRoots);\n } else {\n this.fileHashCache = currentFileHashes;\n this.saveFileHashCache();\n }\n stats.durationMs = Date.now() - startTime;\n onProgress?.({\n phase: \"complete\",\n filesProcessed: files.length,\n totalFiles: files.length,\n chunksProcessed: 0,\n totalChunks: 0,\n });\n return stats;\n }\n\n if (stats.totalChunks === 0) {\n this.replaceBranchCatalog(\n store,\n invertedIndex,\n database,\n branchCatalogKey,\n previousBranchChunkIds,\n Array.from(currentChunkIds),\n previousBranchSymbolIds,\n Array.from(allSymbolIds),\n );\n store.save();\n this.saveInvertedIndex(invertedIndex);\n database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);\n database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);\n database.setMetadata(symbolExtractorMetadataKey, SYMBOL_EXTRACTOR_VERSION);\n this.saveBranchCommit(database, indexedCommit);\n this.saveIndexMetadata(configuredProviderInfo);\n this.indexCompatibility = { compatible: true };\n database.commitWriteTransaction();\n writeTransactionActive = false;\n this.finalizeFailedBatchWriteState(failedProcessing.state, resolvedRetryChunkIds);\n if (scopedRoots) {\n this.replaceScopedFileHashCache(currentFileHashes, scopedRoots);\n } else {\n this.fileHashCache = currentFileHashes;\n this.saveFileHashCache();\n }\n stats.durationMs = Date.now() - startTime;\n onProgress?.({\n phase: \"complete\",\n filesProcessed: files.length,\n totalFiles: files.length,\n chunksProcessed: 0,\n totalChunks: 0,\n });\n return stats;\n }\n\n onProgress?.({\n phase: \"storing\",\n filesProcessed: files.length,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks,\n totalChunks: stats.totalChunks,\n });\n\n const branchChunkIds = Array.from(currentChunkIds).filter((chunkId) => {\n const isNewlyFailed = failedChunkIds.has(chunkId) && !retryableChunksWithExistingData.has(chunkId);\n const isForcedFailed = forceScopedReembed && failedForcedChunkIds.has(chunkId);\n return !isNewlyFailed && !isForcedFailed;\n });\n this.replaceBranchCatalog(\n store,\n invertedIndex,\n database,\n branchCatalogKey,\n previousBranchChunkIds,\n branchChunkIds,\n previousBranchSymbolIds,\n Array.from(allSymbolIds),\n );\n\n store.save();\n this.saveInvertedIndex(invertedIndex);\n database.commitWriteTransaction();\n writeTransactionActive = false;\n this.finalizeFailedBatchWriteState(failedProcessing.state, resolvedRetryChunkIds);\n if (scopedRoots) {\n this.replaceScopedFileHashCache(currentFileHashes, scopedRoots);\n } else {\n this.fileHashCache = currentFileHashes;\n this.saveFileHashCache();\n }\n\n if (this.config.indexing.autoGc && stats.removedChunks > 0) {\n const gcReset = await this.maybeRunOrphanGc();\n if (gcReset) {\n stats.durationMs = Date.now() - startTime;\n stats.warning = gcReset.warning;\n stats.resetCorruptedIndex = true;\n this.logger.recordIndexingEnd();\n this.logger.warn(\"Indexing ended after resetting corrupted local index during automatic GC\", {\n files: stats.totalFiles,\n indexed: stats.indexedChunks,\n existing: stats.existingChunks,\n removed: stats.removedChunks,\n failed: stats.failedChunks,\n tokens: stats.tokensUsed,\n durationMs: stats.durationMs,\n });\n return stats;\n }\n }\n\n stats.durationMs = Date.now() - startTime;\n if (forceScopedReembed && failedForcedChunkIds.size === 0) {\n database.deleteMetadata(this.getProjectForceReembedMetadataKey());\n }\n if (forceScopedReembed) {\n database.setMetadata(this.getProjectMigrationFinalizedMetadataKey(), \"true\");\n }\n database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);\n database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);\n database.setMetadata(symbolExtractorMetadataKey, SYMBOL_EXTRACTOR_VERSION);\n this.saveBranchCommit(database, indexedCommit);\n this.saveIndexMetadata(configuredProviderInfo);\n this.indexCompatibility = { compatible: true };\n\n this.logger.recordIndexingEnd();\n this.logger.info(\"Indexing complete\", {\n files: stats.totalFiles,\n indexed: stats.indexedChunks,\n existing: stats.existingChunks,\n removed: stats.removedChunks,\n failed: stats.failedChunks,\n tokens: stats.tokensUsed,\n durationMs: stats.durationMs,\n });\n\n if (stats.failedChunks > 0) {\n stats.failedBatchesPath = this.failedBatchesPath;\n }\n onProgress?.({\n phase: \"complete\",\n filesProcessed: files.length,\n totalFiles: files.length,\n chunksProcessed: stats.indexedChunks,\n totalChunks: stats.totalChunks,\n });\n return stats;\n } catch (error) {\n failedProcessing.state.writer.cleanup();\n if (writeTransactionActive) {\n try {\n database.rollbackWriteTransaction();\n } catch (rollbackError) {\n this.logger.error(\"Failed to roll back indexing database transaction\", {\n error: getErrorMessage(rollbackError),\n });\n }\n }\n throw error;\n }\n }\n\n private async getQueryEmbedding(query: string, provider: EmbeddingProviderInterface): Promise<number[]> {\n const now = Date.now();\n const cached = this.queryEmbeddingCache.get(query);\n\n if (cached && (now - cached.timestamp) < this.queryCacheTtlMs) {\n this.logger.cache(\"debug\", \"Query embedding cache hit (exact)\", { query: query.slice(0, 50) });\n this.logger.recordQueryCacheHit();\n return cached.embedding;\n }\n\n const similarMatch = this.findSimilarCachedQuery(query, now);\n if (similarMatch) {\n this.logger.cache(\"debug\", \"Query embedding cache hit (similar)\", {\n query: query.slice(0, 50),\n similarTo: similarMatch.key.slice(0, 50),\n similarity: similarMatch.similarity.toFixed(3),\n });\n this.logger.recordQueryCacheSimilarHit();\n return similarMatch.embedding;\n }\n\n this.logger.cache(\"debug\", \"Query embedding cache miss\", { query: query.slice(0, 50) });\n this.logger.recordQueryCacheMiss();\n const { embedding, tokensUsed } = await provider.embedQuery(query);\n this.logger.recordEmbeddingApiCall(tokensUsed);\n\n if (this.queryEmbeddingCache.size >= this.maxQueryCacheSize) {\n const oldestKey = this.queryEmbeddingCache.keys().next().value;\n if (oldestKey) {\n this.queryEmbeddingCache.delete(oldestKey);\n }\n }\n\n this.queryEmbeddingCache.set(query, { embedding, timestamp: now });\n return embedding;\n }\n\n private findSimilarCachedQuery(\n query: string,\n now: number\n ): { key: string; embedding: number[]; similarity: number } | null {\n const queryTokens = this.tokenize(query);\n if (queryTokens.size === 0) return null;\n\n let bestMatch: { key: string; embedding: number[]; similarity: number } | null = null;\n\n for (const [cachedQuery, { embedding, timestamp }] of this.queryEmbeddingCache) {\n if ((now - timestamp) >= this.queryCacheTtlMs) continue;\n\n const cachedTokens = this.tokenize(cachedQuery);\n const similarity = this.jaccardSimilarity(queryTokens, cachedTokens);\n\n if (similarity >= this.querySimilarityThreshold) {\n if (!bestMatch || similarity > bestMatch.similarity) {\n bestMatch = { key: cachedQuery, embedding, similarity };\n }\n }\n }\n\n return bestMatch;\n }\n\n private tokenize(text: string): Set<string> {\n return new Set(\n text\n .toLowerCase()\n .replace(/[^\\w\\s]/g, \" \")\n .split(/\\s+/)\n .filter(t => t.length > 1)\n );\n }\n\n private jaccardSimilarity(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 1;\n if (a.size === 0 || b.size === 0) return 0;\n\n let intersection = 0;\n for (const token of a) {\n if (b.has(token)) intersection++;\n }\n\n const union = a.size + b.size - intersection;\n return intersection / union;\n }\n\n private getBranchPrefilterState(\n database: Database,\n branchChunkIds: Set<string> | null,\n ): {\n hasInitializedBranchCatalog: boolean;\n shouldPrefilterByBranch: boolean;\n } {\n const hasInitializedBranchCatalog = branchChunkIds !== null\n && database.getAllBranches().length > 0;\n return {\n hasInitializedBranchCatalog,\n shouldPrefilterByBranch: branchChunkIds !== null\n && (this.config.scope === \"global\" || hasInitializedBranchCatalog),\n };\n }\n\n private searchCandidatesWithAllowedIds<T>(\n initialLimit: number,\n totalCount: number,\n allowedChunkIds: Set<string> | null,\n shouldPrefilter: boolean,\n search: (limit: number) => T[],\n getChunkId: (candidate: T) => string,\n ): T[] {\n const normalizedLimit = Math.max(0, Math.floor(initialLimit));\n if (normalizedLimit === 0) return [];\n if (!shouldPrefilter || !allowedChunkIds) {\n return search(normalizedLimit);\n }\n\n const targetCount = Math.min(normalizedLimit, allowedChunkIds.size);\n if (targetCount === 0 || totalCount === 0) return [];\n\n let requestedLimit = Math.min(normalizedLimit, totalCount);\n while (true) {\n const results = search(requestedLimit);\n const allowedResults = results.filter((candidate) => allowedChunkIds.has(getChunkId(candidate)));\n if (\n allowedResults.length >= targetCount\n || results.length < requestedLimit\n || requestedLimit >= totalCount\n ) {\n return allowedResults;\n }\n\n const nextLimit = Math.min(totalCount, Math.max(requestedLimit + 1, requestedLimit * 2));\n if (nextLimit === requestedLimit) return allowedResults;\n requestedLimit = nextLimit;\n }\n }\n\n private getTemporalChunkIds(\n database: Database,\n options: Pick<SearchFilterOptions, \"blameSince\" | \"blameUntil\"> | undefined,\n ): Set<string> | null {\n if (!options?.blameSince && !options?.blameUntil) return null;\n\n const since = options.blameSince ? parseBlameTimestamp(options.blameSince, false) : undefined;\n const until = options.blameUntil ? parseBlameTimestamp(options.blameUntil, true) : undefined;\n if (since === null || until === null) {\n return new Set();\n }\n\n return new Set(database.getChunkIdsByBlameDate(since, until));\n }\n\n private intersectChunkIdSets(\n first: Set<string> | null,\n second: Set<string> | null,\n ): Set<string> | null {\n if (first === null) return second;\n if (second === null) return first;\n const [smaller, larger] = first.size <= second.size ? [first, second] : [second, first];\n return new Set(Array.from(smaller).filter((chunkId) => larger.has(chunkId)));\n }\n\n private buildCandidateSnapshot(candidate: RankedCandidate): CandidateSnapshot {\n return {\n id: candidate.id,\n filePath: candidate.metadata.filePath,\n startLine: candidate.metadata.startLine,\n endLine: candidate.metadata.endLine,\n score: candidate.score,\n chunkType: candidate.metadata.chunkType,\n name: candidate.metadata.name,\n };\n }\n\n private buildCandidateSnapshotList(candidates: RankedCandidate[]): CandidateSnapshot[] {\n return candidates.map((candidate) => this.buildCandidateSnapshot(candidate));\n }\n\n private searchSemanticCandidates(\n store: VectorStore,\n embedding: number[],\n initialLimit: number,\n branchChunkIds: Set<string> | null,\n shouldPrefilterByBranch: boolean,\n temporalChunkIds: Set<string> | null,\n ): RankedCandidate[] {\n const availableCount = temporalChunkIds?.size ?? store.count();\n if (availableCount === 0) return [];\n const allowedIds = temporalChunkIds === null ? undefined : Array.from(temporalChunkIds);\n return this.searchCandidatesWithAllowedIds(\n Math.min(initialLimit, availableCount),\n availableCount,\n branchChunkIds,\n shouldPrefilterByBranch,\n (requestedLimit) => store.search(embedding, requestedLimit, allowedIds),\n (candidate) => candidate.id,\n );\n }\n\n async search(\n query: string,\n limit?: number,\n options?: SearchOptions\n ): Promise<SearchResult[]> {\n const { store, provider, invertedIndex, database, readIssues, compatibility } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"vectors\", \"database\");\n\n if (!compatibility.compatible) {\n throw new Error(\n `${compatibility.reason ?? \"Index is incompatible with current embedding provider.\"} ` +\n `A possible solution is to run index_codebase with force=true to rebuild the index.`\n );\n }\n\n const searchStartTime = performance.now();\n\n if (store.count() === 0) {\n this.logger.search(\"debug\", \"Search on empty index\", { query });\n return [];\n }\n\n const maxResults = limit ?? this.config.search.maxResults;\n const hybridWeight = options?.hybridWeight ?? this.config.search.hybridWeight;\n const fusionStrategy = this.config.search.fusionStrategy;\n const effectiveHybridWeight = fusionStrategy === \"weighted\" &&\n readIssues.some((issue) => issue.component === \"keyword\")\n ? 0\n : hybridWeight;\n const rrfK = this.config.search.rrfK;\n const rerankTopN = this.config.search.rerankTopN;\n const filterByBranch = options?.filterByBranch ?? true;\n const sourceIntent = options?.definitionIntent === true || classifyQueryIntentRaw(query) === \"source\";\n const prioritizeSourcePaths = sourceIntent || options?.prioritizeSourcePaths === true;\n const identifierHints = extractIdentifierHints(query);\n const candidateLimit = maxResults * (prioritizeSourcePaths ? 12 : 4);\n\n this.logger.search(\"debug\", \"Starting search\", {\n query,\n maxResults,\n hybridWeight: effectiveHybridWeight,\n fusionStrategy,\n rrfK,\n rerankTopN,\n filterByBranch,\n });\n\n const embeddingStartTime = performance.now();\n const embeddingQuery = stripFilePathHint(query);\n let embedding: number[] | undefined;\n try {\n embedding = await this.getQueryEmbedding(embeddingQuery, provider);\n } catch (error) {\n this.logger.warn(\"Query embedding failed; falling back to keyword-only search\", {\n query,\n error: getErrorMessage(error),\n action: \"Check the embedding provider configuration and retry search after restoring provider health.\",\n });\n }\n const embeddingMs = performance.now() - embeddingStartTime;\n\n const prefilterStartTime = performance.now();\n let branchChunkIds: Set<string> | null = null;\n let branchSymbolIds: Set<string> | null = null;\n if (filterByBranch && (this.config.scope === \"global\" || this.currentBranch !== \"default\")) {\n const branchCatalogKeys = this.getBranchCatalogKeys();\n branchChunkIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchChunkIds(branchKey)));\n branchSymbolIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchSymbolIds(branchKey)));\n }\n const temporalChunkIds = this.getTemporalChunkIds(database, options);\n const { hasInitializedBranchCatalog, shouldPrefilterByBranch } =\n this.getBranchPrefilterState(database, branchChunkIds);\n const prefilterMs = performance.now() - prefilterStartTime;\n\n const vectorStartTime = performance.now();\n const semanticCandidates = embedding\n ? this.searchSemanticCandidates(\n store,\n embedding,\n candidateLimit,\n branchChunkIds,\n shouldPrefilterByBranch,\n temporalChunkIds,\n )\n : [];\n const vectorMs = performance.now() - vectorStartTime;\n\n const keywordStartTime = performance.now();\n const keywordCandidates = await this.keywordSearch(\n query,\n candidateLimit,\n store,\n invertedIndex,\n branchChunkIds,\n shouldPrefilterByBranch,\n temporalChunkIds,\n );\n const keywordMs = performance.now() - keywordStartTime;\n\n const scopedSemanticCandidates = semanticCandidates.filter((candidate) =>\n matchesHardSearchFilters(candidate, options, this.projectRoot)\n );\n const scopedKeywordCandidates = keywordCandidates.filter((candidate) =>\n matchesHardSearchFilters(candidate, options, this.projectRoot)\n );\n\n if (this.config.scope !== \"global\" && branchChunkIds && !hasInitializedBranchCatalog) {\n this.logger.search(\"warn\", \"Branch prefilter skipped because branch catalog is empty\", {\n branch: this.currentBranch,\n });\n }\n\n const fusionStartTime = performance.now();\n const rankingHybridWeight = embedding === undefined && fusionStrategy === \"weighted\"\n ? 1\n : effectiveHybridWeight;\n const combined = rankHybridResults(query, scopedSemanticCandidates, scopedKeywordCandidates, {\n fusionStrategy,\n rrfK,\n rerankTopN,\n limit: maxResults,\n hybridWeight: rankingHybridWeight,\n prioritizeSourcePaths,\n });\n const rerankedCombined = await this.rerankCandidatesWithApi(query, combined, {\n definitionIntent: options?.definitionIntent === true,\n hasIdentifierHints: identifierHints.length > 0,\n });\n const fusionMs = performance.now() - fusionStartTime;\n\n const rescued = promoteIdentifierMatches(\n query,\n rerankedCombined,\n scopedSemanticCandidates,\n scopedKeywordCandidates,\n database,\n branchChunkIds,\n sourceIntent\n );\n\n const union = unionCandidates(scopedSemanticCandidates, scopedKeywordCandidates);\n\n const deterministicIdentifierLane = buildDeterministicIdentifierPass(\n query,\n union,\n maxResults,\n sourceIntent\n );\n\n const identifierLane = buildIdentifierDefinitionLane(\n query,\n union,\n maxResults,\n sourceIntent\n );\n\n const symbolLane = buildSymbolDefinitionLane(\n query,\n database,\n branchChunkIds,\n branchSymbolIds,\n maxResults,\n union,\n sourceIntent,\n options?.definitionIntent === true && (\n (options.directory?.trim().length ?? 0) > 0 ||\n (options.fileType?.trim().length ?? 0) > 0\n ),\n );\n\n const prePrimaryLane = mergeTieredResults(deterministicIdentifierLane, identifierLane, maxResults * 4);\n // An explicit definition lookup can resolve to a symbol whose declaration\n // spans more lines than any indexable chunk. Keep that exact symbol ahead\n // of prefix and semantic matches so it is not pushed beyond maxResults.\n const primaryLane = options?.definitionIntent === true\n ? mergeTieredResults(symbolLane, prePrimaryLane, maxResults * 4)\n : mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);\n const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);\n const hasCodeHints = extractCodeTermHints(query).length > 0 || identifierHints.length > 0;\n\n const baseFiltered = tiered.filter((r) =>\n matchesSearchFilters(r, options, this.config.search.minScore, this.projectRoot)\n );\n\n let communityRanked = baseFiltered;\n if (this.config.search.communityBoost > 0) {\n try {\n const sameCommunityCandidateIds = resolveSameCommunityCandidateIds(\n query,\n baseFiltered,\n database,\n this.getBranchCatalogKeys(),\n );\n communityRanked = applyCommunityBoost(\n baseFiltered,\n sameCommunityCandidateIds,\n this.config.search.communityBoost,\n );\n } catch (error) {\n this.logger.search(\"debug\", \"Community-aware ranking unavailable; using existing ranking\", {\n query,\n error: getErrorMessage(error),\n });\n }\n }\n\n const implementationOnly = communityRanked.filter((r) =>\n isLikelyImplementationPath(r.metadata.filePath) &&\n isImplementationChunkType(r.metadata.chunkType)\n );\n\n const filtered = (sourceIntent && hasCodeHints && implementationOnly.length > 0\n ? implementationOnly\n : communityRanked\n ).slice(0, maxResults);\n\n const identifierFallback = (!options?.definitionIntent && filtered.length === 0 && identifierHints.length > 0)\n ? buildSymbolDefinitionLane(query, database, branchChunkIds, branchSymbolIds, maxResults, union, true)\n .filter((r) => matchesSearchFilters(r, options, this.config.search.minScore, this.projectRoot))\n .slice(0, maxResults)\n : [];\n\n const finalResults = filtered.length > 0 ? filtered : identifierFallback;\n\n const totalSearchMs = performance.now() - searchStartTime;\n this.logger.recordSearch(totalSearchMs, {\n embeddingMs,\n vectorMs,\n keywordMs,\n fusionMs,\n });\n this.logger.search(\"info\", \"Search complete\", {\n query,\n results: finalResults.length,\n totalMs: Math.round(totalSearchMs * 100) / 100,\n embeddingMs: Math.round(embeddingMs * 100) / 100,\n vectorMs: Math.round(vectorMs * 100) / 100,\n keywordMs: Math.round(keywordMs * 100) / 100,\n prefilterMs: Math.round(prefilterMs * 100) / 100,\n fusionMs: Math.round(fusionMs * 100) / 100,\n });\n\n if (options?.trace) {\n options.trace({\n semanticCandidates: this.buildCandidateSnapshotList(scopedSemanticCandidates),\n keywordCandidates: this.buildCandidateSnapshotList(scopedKeywordCandidates),\n hybridCandidates: this.buildCandidateSnapshotList(combined),\n postExternalRerankCandidates: this.buildCandidateSnapshotList(rerankedCombined),\n tieredCandidates: this.buildCandidateSnapshotList(tiered),\n finalCandidates: this.buildCandidateSnapshotList(finalResults),\n });\n }\n\n const metadataOnly = options?.metadataOnly ?? false;\n\n return Promise.all(\n finalResults.map(async (r) => {\n let content = \"\";\n let contextStartLine = r.metadata.startLine;\n let contextEndLine = r.metadata.endLine;\n const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);\n\n if (!metadataOnly && this.config.search.includeContext) {\n try {\n const fileContent = await fsPromises.readFile(\n resolvedFilePath,\n \"utf-8\"\n );\n const lines = fileContent.split(\"\\n\");\n const contextLines = options?.contextLines ?? this.config.search.contextLines;\n\n contextStartLine = Math.max(1, r.metadata.startLine - contextLines);\n contextEndLine = Math.min(lines.length, r.metadata.endLine + contextLines);\n\n content = lines\n .slice(contextStartLine - 1, contextEndLine)\n .join(\"\\n\");\n } catch {\n content = \"[File not accessible]\";\n }\n }\n\n return {\n filePath: resolvedFilePath,\n startLine: contextStartLine,\n endLine: contextEndLine,\n content,\n score: r.score,\n chunkType: r.metadata.chunkType,\n name: r.metadata.name,\n blame: blameFromMetadata(r.metadata),\n };\n })\n );\n }\n\n private async keywordSearch(\n query: string,\n limit: number,\n store: VectorStore,\n invertedIndex: InvertedIndex,\n branchChunkIds: Set<string> | null = null,\n shouldPrefilterByBranch = false,\n temporalChunkIds: Set<string> | null = null,\n ): Promise<Array<{ id: string; score: number; metadata: ChunkMetadata }>> {\n const normalizedLimit = Math.max(0, Math.floor(limit));\n if (normalizedLimit === 0) return [];\n\n const allowedChunkIds = this.intersectChunkIdSets(\n shouldPrefilterByBranch ? branchChunkIds : null,\n temporalChunkIds,\n );\n const scoreEntries = this.searchCandidatesWithAllowedIds(\n normalizedLimit,\n invertedIndex.getDocumentCount(),\n allowedChunkIds,\n allowedChunkIds !== null,\n (requestedLimit) => Array.from(invertedIndex.search(query, requestedLimit)),\n ([chunkId]) => chunkId,\n );\n const scores = new Map(scoreEntries);\n\n if (scores.size === 0) {\n return [];\n }\n\n // Only fetch metadata for chunks returned by BM25 (O(n) where n = result count)\n // instead of getAllMetadata() which fetches ALL chunks in the index\n const chunkIds = Array.from(scores.keys());\n const metadataMap = store.getMetadataBatch(chunkIds);\n\n const results: Array<{ id: string; score: number; metadata: ChunkMetadata }> = [];\n for (const [chunkId, score] of scores) {\n const metadata = metadataMap.get(chunkId);\n if (metadata && score > 0) {\n results.push({ id: chunkId, score, metadata });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, normalizedLimit);\n }\n\n async getStatus(): Promise<StatusResult> {\n const { store, configuredProviderInfo, database, readIssues, compatibility } = await this.ensureInitialized();\n const failedBatchesCount = this.getFailedBatchesCount();\n const vectorCount = store.count();\n const statusReadIssues = [...readIssues];\n let startupWarning = \"\";\n if (!statusReadIssues.some((issue) => issue.component === \"database\")) {\n try {\n startupWarning = database.getMetadata(STARTUP_WARNING_METADATA_KEY) ?? \"\";\n } catch (error) {\n const message = this.getDatabaseReadIssueMessage();\n statusReadIssues.push(this.createReadIssue(\"database\", message));\n if (!this.readIssues.some((issue) => issue.component === \"database\")) {\n this.recordReadIssue(\"database\", message, error);\n }\n }\n }\n const readWarning = statusReadIssues.map((issue) => issue.message).join(\" \");\n const warning = [readWarning, startupWarning].filter((message) => message.length > 0).join(\" \");\n const hasBlockingReadIssue = statusReadIssues.some((issue) => issue.blocking);\n\n return {\n indexed: vectorCount > 0 && !hasBlockingReadIssue,\n vectorCount,\n provider: configuredProviderInfo.provider,\n model: configuredProviderInfo.modelInfo.model,\n indexPath: this.indexPath,\n currentBranch: this.currentBranch,\n baseBranch: this.baseBranch,\n compatibility,\n failedBatchesCount,\n failedBatchesPath: failedBatchesCount > 0 ? this.failedBatchesPath : undefined,\n warning: warning || undefined,\n };\n }\n\n async getIndexFreshness(): Promise<IndexFreshnessResult> {\n const { store, database, readIssues, compatibility } = await this.ensureInitialized();\n const blockingReadIssue = readIssues.some((issue) => issue.blocking);\n if (blockingReadIssue) {\n return { readable: false, current: false, reason: \"unreadable\" };\n }\n if (store.count() === 0) {\n return { readable: false, current: false, reason: \"missing\" };\n }\n if (compatibility && !compatibility.compatible) {\n return { readable: true, current: false, reason: \"incompatible\" };\n }\n if (this.getFailedBatchesCount() > 0) {\n return { readable: true, current: false, reason: \"failed-batches\" };\n }\n\n this.fileHashCache.clear();\n this.loadFileHashCache();\n const includePatterns = [...this.config.include, ...this.config.additionalInclude];\n const { files } = await collectFiles(\n this.materializedProjectRoot,\n includePatterns,\n this.config.exclude,\n this.config.indexing.maxFileSize,\n this.getMaterializedKnowledgeBases(),\n {\n maxDepth: this.config.indexing.maxDepth,\n maxFilesPerDirectory: this.config.indexing.maxFilesPerDirectory,\n },\n );\n const currentFileHashes = new Map<string, string>();\n for (const file of files) {\n let hash: string;\n try {\n hash = hashFile(file.path);\n } catch (error) {\n // An unreadable file (OS-level EPERM/EACCES) makes freshness unknowable;\n // treat the index as not-current so the next index_codebase run rebuilds\n // (which skips unreadable files) instead of aborting here.\n this.logger.warn(\"Skipped unreadable file during freshness check\", {\n path: file.path,\n error: getErrorMessage(error),\n });\n return { readable: false, current: false, reason: \"unreadable\" };\n }\n currentFileHashes.set(this.toStoredFilePath(file.path), hash);\n }\n\n const scopedRoots = this.config.scope === \"global\" ? this.getScopedRoots() : null;\n const cachedFileHashes = scopedRoots\n ? new Map(Array.from(this.fileHashCache).filter(([filePath]) => this.isFileInCurrentScope(filePath, scopedRoots)))\n : this.fileHashCache;\n if (cachedFileHashes.size !== currentFileHashes.size) {\n return { readable: true, current: false, reason: \"files-changed\" };\n }\n for (const [filePath, currentHash] of currentFileHashes) {\n if (cachedFileHashes.get(filePath) !== currentHash) {\n return { readable: true, current: false, reason: \"files-changed\" };\n }\n }\n\n if (!this.areBranchMigrationVersionsCurrent(database)) {\n return { readable: true, current: false, reason: \"migration-required\" };\n }\n\n if (isGitRepo(this.materializedProjectRoot)) {\n const currentCommit = await resolveLocalGitCommit(this.materializedProjectRoot, \"HEAD\");\n if (this.getStoredBranchCommit(database) !== currentCommit) {\n return { readable: true, current: false, reason: \"branch-changed\" };\n }\n }\n\n return { readable: true, current: true, reason: \"current\" };\n }\n\n async forceIndex(onProgress?: ProgressCallback): Promise<IndexStats> {\n return this.withIndexMutationLease(\"force-index\", async (recoveredOwners) => {\n await this.ensureInitializedUnlocked(recoveredOwners);\n const recovery = this.beginClearRecoveryState();\n await this.clearIndexUnlocked(recovery.compatibilityDecision);\n this.finishClearRecoveryState();\n return this.indexUnlocked(onProgress, [], true);\n });\n }\n\n async clearIndex(): Promise<void> {\n await this.withIndexMutationLease(\"clear\", async (recoveredOwners) => {\n await this.ensureInitializedUnlocked(recoveredOwners);\n const recovery = this.beginClearRecoveryState();\n await this.clearIndexUnlocked(recovery.compatibilityDecision);\n });\n }\n\n private clearGlobalIndexDataUnlocked(projectRoot = this.projectRoot): void {\n const { store, invertedIndex, database } = this.requireLoadedIndexState();\n const clearedBranchKeys = database.getAllBranches();\n store.clear();\n store.save();\n invertedIndex.clear();\n this.saveInvertedIndex(invertedIndex);\n\n this.fileHashCache.clear();\n this.saveFileHashCache();\n\n database.clearAllIndexedData();\n this.deleteBranchCommitMetadata(database, clearedBranchKeys);\n this.clearFailedBatchState();\n\n database.deleteMetadata(\"index.version\");\n database.deleteMetadata(\"index.pathStorageVersion\");\n database.deleteMetadata(\"index.embeddingProvider\");\n database.deleteMetadata(\"index.embeddingModel\");\n database.deleteMetadata(\"index.embeddingDimensions\");\n database.deleteMetadata(\"index.embeddingStrategyVersion\");\n const projectIdentityHash = this.getProjectIdentityHash(projectRoot);\n database.deleteMetadata(this.getProjectEmbeddingStrategyMetadataKey(projectIdentityHash));\n database.deleteMetadata(this.getProjectForceReembedMetadataKey(projectIdentityHash));\n database.deleteMetadata(this.getLegacyMigrationMetadataKey(projectIdentityHash));\n database.deleteMetadata(\"index.createdAt\");\n database.deleteMetadata(\"index.updatedAt\");\n\n this.indexCompatibility = this.validateIndexCompatibility(this.configuredProviderInfo!);\n }\n\n private clearGlobalIndexUnlocked(\n projectRoot = this.projectRoot,\n roots = this.getScopedRoots(),\n recoveryDecision?: IndexLockClearRecoveryState[\"compatibilityDecision\"],\n ): void {\n const { store, invertedIndex, database } = this.requireLoadedIndexState();\n store.load();\n invertedIndex.load();\n this.loadFileHashCache();\n const compatibility = this.checkCompatibility();\n const compatibilityDecision = recoveryDecision ?? (\n compatibility.compatible\n ? \"compatible\"\n : compatibility.code === IncompatibilityCode.EMBEDDING_STRATEGY_MISMATCH\n ? \"embedding-strategy-mismatch\"\n : \"incompatible\"\n );\n const allMetadata = store.getAllMetadata();\n const hasForeignData =\n allMetadata.some(({ metadata }) => !this.isFileInCurrentScope(metadata.filePath, roots)) ||\n this.hasForeignScopedBranchData(projectRoot, roots) ||\n this.hasForeignScopedFileHashData(roots) ||\n this.hasForeignScopedFailedBatches(roots);\n\n if (compatibilityDecision !== \"compatible\" && hasForeignData) {\n if (compatibilityDecision === \"embedding-strategy-mismatch\") {\n this.clearSharedIndexProjectData(store, invertedIndex, database, roots, projectRoot);\n this.clearScopedFileHashCache(roots);\n this.clearScopedFailedBatches(roots);\n const projectIdentityHash = this.getProjectIdentityHash(projectRoot);\n database.setMetadata(this.getProjectForceReembedMetadataKey(projectIdentityHash), \"true\");\n database.deleteMetadata(this.getProjectEmbeddingStrategyMetadataKey(projectIdentityHash));\n database.deleteMetadata(this.getProjectMigrationFinalizedMetadataKey(projectIdentityHash));\n if (projectRoot === this.projectRoot) {\n this.indexCompatibility = { compatible: true };\n }\n return;\n }\n\n throw new Error(\n `Global index compatibility reset is unsafe because the shared index contains files from other projects. ` +\n `The current global index cannot be force-rebuilt for ${projectRoot} without deleting other repositories' indexed data. ` +\n `Use scope=\"project\" for isolated rebuilds, or manually delete the shared global index if you intend to rebuild all projects.`\n );\n }\n\n if (!hasForeignData) {\n this.clearGlobalIndexDataUnlocked(projectRoot);\n return;\n }\n\n this.clearSharedIndexProjectData(store, invertedIndex, database, roots, projectRoot);\n this.clearScopedFileHashCache(roots);\n this.clearScopedFailedBatches(roots);\n if (projectRoot === this.projectRoot) {\n this.indexCompatibility = compatibility;\n }\n }\n\n private async clearIndexUnlocked(\n recoveryDecision?: IndexLockClearRecoveryState[\"compatibilityDecision\"],\n ): Promise<void> {\n const { store, invertedIndex, database } = this.requireLoadedIndexState();\n\n if (this.config.scope === \"global\") {\n this.clearGlobalIndexUnlocked(this.projectRoot, this.getScopedRoots(), recoveryDecision);\n return;\n }\n\n if (!this.isProjectOwnedIndexPath()) {\n throw new Error(\n \"Project-scoped force rebuild is unsafe while using an inherited worktree index. \" +\n \"Create a local project config boundary before clearing the index.\"\n );\n }\n\n const clearedBranchKeys = database.getAllBranches();\n store.clear();\n store.save();\n invertedIndex.clear();\n this.saveInvertedIndex(invertedIndex);\n\n this.fileHashCache.clear();\n await this.removeProjectRuntimeStateArtifacts();\n\n // cannot reuse stale chunks, symbols, or embeddings from a prior provider.\n database.clearAllIndexedData();\n this.deleteBranchCommitMetadata(database, clearedBranchKeys);\n\n database.deleteMetadata(\"index.version\");\n database.deleteMetadata(\"index.pathStorageVersion\");\n database.deleteMetadata(\"index.embeddingProvider\");\n database.deleteMetadata(\"index.embeddingModel\");\n database.deleteMetadata(\"index.embeddingDimensions\");\n database.deleteMetadata(\"index.embeddingStrategyVersion\");\n database.deleteMetadata(this.getProjectEmbeddingStrategyMetadataKey());\n database.deleteMetadata(this.getProjectForceReembedMetadataKey());\n database.deleteMetadata(this.getLegacyMigrationMetadataKey());\n database.deleteMetadata(\"index.createdAt\");\n database.deleteMetadata(\"index.updatedAt\");\n\n this.indexCompatibility = this.validateIndexCompatibility(this.configuredProviderInfo!);\n }\n\n async healthCheck(): Promise<HealthCheckResult> {\n return this.withIndexMutationLease(\"health-check\", async (recoveredOwners) => {\n await this.ensureInitializedUnlocked(recoveredOwners);\n return this.healthCheckUnlocked();\n });\n }\n\n private async healthCheckUnlocked(): Promise<HealthCheckResult> {\n const { store, invertedIndex, database } = this.requireLoadedIndexState();\n\n this.logger.gc(\"info\", \"Starting health check\");\n\n const allMetadata = store.getAllMetadata();\n const filePathsToChunkKeys = new Map<string, string[]>();\n\n for (const { key, metadata } of allMetadata) {\n const existing = filePathsToChunkKeys.get(metadata.filePath) || [];\n existing.push(key);\n filePathsToChunkKeys.set(metadata.filePath, existing);\n }\n\n const missingStoredFilePaths: string[] = [];\n const missingChunkKeys: string[] = [];\n const chunkKeysByRemovedFile = new Map<string, string[]>();\n\n for (const [filePath, chunkKeys] of filePathsToChunkKeys) {\n if (!existsSync(this.toMaterializedFilePath(filePath))) {\n chunkKeysByRemovedFile.set(filePath, chunkKeys);\n for (const key of chunkKeys) {\n missingChunkKeys.push(key);\n }\n missingStoredFilePaths.push(filePath);\n }\n }\n\n const branchCatalogKeys = this.getBranchCatalogKeys();\n for (const branchKey of branchCatalogKeys) {\n database.deleteBranchChunksForBranch(branchKey, missingChunkKeys);\n }\n const referencedChunkKeys = new Set(database.getReferencedChunkIds(missingChunkKeys));\n const removedChunkKeys = missingChunkKeys.filter((key) => !referencedChunkKeys.has(key));\n\n if (removedChunkKeys.length > 0) {\n this.rebuildVectorStoreExcludingChunkIds(store, database, removedChunkKeys);\n for (const key of removedChunkKeys) {\n invertedIndex.removeChunk(key);\n }\n database.deleteChunksByIds(removedChunkKeys);\n }\n\n const missingSymbolIds = Array.from(new Set(\n missingStoredFilePaths.flatMap((filePath) =>\n database.getSymbolsByFile(filePath).map((symbol) => symbol.id)\n )\n ));\n for (const branchKey of branchCatalogKeys) {\n database.deleteBranchSymbolsForBranch(branchKey, missingSymbolIds);\n }\n const referencedSymbolIds = new Set(database.getReferencedSymbolIds(missingSymbolIds));\n const removedSymbolIds = missingSymbolIds.filter((symbolId) => !referencedSymbolIds.has(symbolId));\n database.clearCallEdgeTargetsForSymbols(removedSymbolIds);\n\n const removedChunkKeySet = new Set(removedChunkKeys);\n const removedStoredFilePaths = missingStoredFilePaths.filter((filePath) =>\n (chunkKeysByRemovedFile.get(filePath) ?? []).some((key) => removedChunkKeySet.has(key))\n );\n\n const removedCount = removedChunkKeys.length;\n\n if (removedCount > 0) {\n store.save();\n this.saveInvertedIndex(invertedIndex);\n }\n\n let gcOrphanEmbeddings: number;\n let gcOrphanChunks: number;\n let gcOrphanSymbols: number;\n let gcOrphanCallEdges: number;\n\n try {\n gcOrphanEmbeddings = database.gcOrphanEmbeddings();\n gcOrphanChunks = database.gcOrphanChunks();\n gcOrphanSymbols = database.gcOrphanSymbols();\n gcOrphanCallEdges = database.gcOrphanCallEdges();\n } catch (error) {\n if (!(await this.tryResetCorruptedIndex(\"running index health check\", error))) {\n throw error;\n }\n\n await this.initializeUnlocked(\"writer\", [], { skipAutoGc: true });\n\n return {\n removed: 0,\n filePaths: [],\n gcOrphanEmbeddings: 0,\n gcOrphanChunks: 0,\n gcOrphanSymbols: 0,\n gcOrphanCallEdges: 0,\n resetCorruptedIndex: true,\n warning: this.getCorruptedIndexWarning(path.join(this.indexPath, \"codebase.db\")),\n };\n }\n\n this.logger.recordGc(removedCount, gcOrphanChunks, gcOrphanEmbeddings);\n this.logger.gc(\"info\", \"Health check complete\", {\n removedStale: removedCount,\n orphanEmbeddings: gcOrphanEmbeddings,\n orphanChunks: gcOrphanChunks,\n removedFiles: removedStoredFilePaths.length,\n });\n\n return {\n removed: removedCount,\n filePaths: removedStoredFilePaths.map((filePath) => this.resolveStoredFilePath(filePath)),\n gcOrphanEmbeddings,\n gcOrphanChunks,\n gcOrphanSymbols,\n gcOrphanCallEdges,\n };\n }\n\n async retryFailedBatches(): Promise<{ succeeded: number; failed: number; remaining: number }> {\n return this.withIndexMutationLease(\"retry-failed-batches\", async (recoveredOwners) => {\n await this.ensureInitializedUnlocked(recoveredOwners);\n return this.retryFailedBatchesUnlocked();\n });\n }\n\n private async retryFailedBatchesUnlocked(): Promise<{ succeeded: number; failed: number; remaining: number }> {\n const { store, provider, invertedIndex, database, configuredProviderInfo } = this.requireLoadedIndexState();\n const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);\n const providerRateLimits = this.getProviderRateLimits(configuredProviderInfo.provider);\n const roots = this.config.scope === \"global\" ? this.getScopedRoots() : null;\n const failedProcessing = this.prepareFailedBatchProcessing(roots, () => true);\n\n if (failedProcessing.latestById.size === 0) {\n this.finalizeFailedBatchWriteState(failedProcessing.state);\n return { succeeded: 0, failed: 0, remaining: 0 };\n }\n\n const queue = new PQueue({ concurrency: 1 });\n const rateLimitState: EmbeddingRateLimitState = { backoffMs: 0 };\n let succeeded = 0;\n let failed = 0;\n\n try {\n const retryableChunks = this.iterateLatestFailedChunks(\n failedProcessing.latestById,\n roots,\n () => true,\n maxChunkTokens,\n );\n for (const retryBatch of iterateOrderedFileBatches(\n retryableChunks,\n ({ chunk }) => Buffer.byteLength(chunk.content, \"utf-8\"),\n this.fileBatchLimits,\n )) {\n const chunks = retryBatch.map(({ chunk }) => chunk);\n const attemptCounts = new Map(retryBatch.map(({ chunk, attemptCount }) => [chunk.id, attemptCount]));\n // Restore chunk rows that a recovery health check may have collected\n // as orphans: a failed chunk checkpointed before its embedding has a\n // committed SQLite row but no branch association until it succeeds.\n this.restoreMissingChunkRows(database, chunks);\n const batchResult = await this.processPendingChunkBatch(chunks, {\n store,\n provider,\n invertedIndex,\n database,\n configuredProviderInfo,\n queue,\n providerRateLimits,\n rateLimitState,\n failedState: failedProcessing.state,\n attemptCounts,\n forceReembed: false,\n reuseCachedEmbeddings: false,\n incrementRepeatedFailures: false,\n forceSingleItemBatches: true,\n onSucceeded: (succeededChunks) => {\n database.addChunksToBranchBatch(\n this.getBranchCatalogKey(),\n succeededChunks.map((chunk) => chunk.id),\n );\n },\n });\n succeeded += batchResult.indexedChunks;\n failed += batchResult.failedChunks;\n }\n\n this.finalizeFailedBatchWriteState(failedProcessing.state);\n } catch (error) {\n failedProcessing.state.writer.cleanup();\n throw error;\n }\n\n const remaining = this.getFailedBatchesCount();\n if (succeeded > 0) {\n store.save();\n this.saveInvertedIndex(invertedIndex);\n }\n\n if (roots && succeeded > 0 && remaining === 0 && this.hasProjectForceReembedPending()) {\n const migrationFinalized =\n database.getMetadata(this.getProjectMigrationFinalizedMetadataKey()) === \"true\";\n if (migrationFinalized) {\n database.deleteMetadata(this.getProjectForceReembedMetadataKey());\n this.saveIndexMetadata(configuredProviderInfo);\n this.indexCompatibility = { compatible: true };\n }\n }\n\n return { succeeded, failed, remaining };\n }\n\n getFailedBatchesCount(): number {\n const roots = this.config.scope === \"global\" ? this.getScopedRoots() : null;\n const latestById = new Map<string, FailedChunkRecordMetadata>();\n for (const batch of this.loadSerializedFailedBatches()) {\n for (const rawChunk of batch.chunks) {\n const filePath = getPendingChunkFilePath(rawChunk);\n if (roots && (filePath === null || !this.isFileInCurrentScope(filePath, roots))) {\n continue;\n }\n const chunkId = getPendingChunkId(rawChunk);\n if (!chunkId) {\n continue;\n }\n const existing = latestById.get(chunkId);\n if (!existing || batch.attemptCount >= existing.attemptCount) {\n latestById.set(chunkId, {\n attemptCount: batch.attemptCount,\n error: batch.error,\n lastAttempt: batch.lastAttempt,\n chunks: [rawChunk],\n });\n }\n }\n }\n return new Set(Array.from(latestById.values(), getFailedBatchGroupKey)).size;\n }\n\n getCurrentBranch(): string {\n return this.currentBranch;\n }\n\n getBaseBranch(): string {\n return this.baseBranch;\n }\n\n refreshBranchInfo(): void {\n const previousBranch = this.currentBranch;\n if (isGitRepo(this.materializedProjectRoot)) {\n this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);\n this.baseBranch = getBaseBranch(this.materializedProjectRoot);\n } else {\n this.currentBranch = \"default\";\n this.baseBranch = \"default\";\n }\n\n if (this.currentBranch !== previousBranch) {\n this.refreshRuntimeArtifactPaths();\n this.fileHashCache.clear();\n this.loadFileHashCache();\n }\n }\n\n async getDatabaseStats(): Promise<{ embeddingCount: number; chunkCount: number; branchChunkCount: number; branchCount: number } | null> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n return database.getStats();\n }\n\n getLogger(): Logger {\n return this.logger;\n }\n\n async findSimilar(\n code: string,\n limit: number = this.config.search.maxResults,\n options?: {\n fileType?: string;\n directory?: string;\n chunkType?: string;\n excludeFile?: string;\n filterByBranch?: boolean;\n blameSince?: string;\n blameUntil?: string;\n }\n ): Promise<SearchResult[]> {\n const { store, provider, database, readIssues, compatibility } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"vectors\", \"database\");\n\n if (!compatibility.compatible) {\n throw new Error(\n `${compatibility.reason ?? \"Index is incompatible with current embedding provider.\"} ` +\n `Run index_codebase with force=true to rebuild the index.`\n );\n }\n\n const searchStartTime = performance.now();\n\n if (store.count() === 0) {\n this.logger.search(\"debug\", \"Find similar on empty index\");\n return [];\n }\n\n const filterByBranch = options?.filterByBranch ?? true;\n const excludedStoredFile = options?.excludeFile\n ? this.toStoredFilePath(options.excludeFile)\n : undefined;\n\n this.logger.search(\"debug\", \"Starting find similar\", {\n codeLength: code.length,\n limit,\n filterByBranch,\n });\n\n const embeddingStartTime = performance.now();\n const { embedding, tokensUsed } = await provider.embedDocument(code);\n const embeddingMs = performance.now() - embeddingStartTime;\n this.logger.recordEmbeddingApiCall(tokensUsed);\n\n const prefilterStartTime = performance.now();\n let branchChunkIds: Set<string> | null = null;\n if (filterByBranch && (this.config.scope === \"global\" || this.currentBranch !== \"default\")) {\n branchChunkIds = new Set(\n this.getBranchCatalogKeys().flatMap((branchKey) => database.getBranchChunkIds(branchKey))\n );\n }\n const temporalChunkIds = this.getTemporalChunkIds(database, options);\n const { hasInitializedBranchCatalog, shouldPrefilterByBranch } =\n this.getBranchPrefilterState(database, branchChunkIds);\n const prefilterMs = performance.now() - prefilterStartTime;\n\n const vectorStartTime = performance.now();\n const semanticCandidates = this.searchSemanticCandidates(\n store,\n embedding,\n limit * 2,\n branchChunkIds,\n shouldPrefilterByBranch,\n temporalChunkIds,\n );\n const vectorMs = performance.now() - vectorStartTime;\n\n if (this.config.scope !== \"global\" && branchChunkIds && !hasInitializedBranchCatalog) {\n this.logger.search(\"warn\", \"Branch prefilter skipped because branch catalog is empty\", {\n branch: this.currentBranch,\n });\n }\n\n const rerankTopN = this.config.search.rerankTopN;\n\n const ranked = rankSemanticOnlyResults(code, semanticCandidates, {\n rerankTopN,\n limit,\n prioritizeSourcePaths: false,\n });\n\n const filtered = ranked.filter((r) => {\n if (r.score < this.config.search.minScore) return false;\n\n if (excludedStoredFile) {\n if (r.metadata.filePath === excludedStoredFile) return false;\n }\n\n return matchesHardSearchFilters(r, options, this.projectRoot);\n }).slice(0, limit);\n\n const totalSearchMs = performance.now() - searchStartTime;\n this.logger.recordSearch(totalSearchMs, {\n embeddingMs,\n vectorMs,\n keywordMs: 0,\n fusionMs: 0,\n });\n this.logger.search(\"info\", \"Find similar complete\", {\n codeLength: code.length,\n results: filtered.length,\n totalMs: Math.round(totalSearchMs * 100) / 100,\n embeddingMs: Math.round(embeddingMs * 100) / 100,\n vectorMs: Math.round(vectorMs * 100) / 100,\n prefilterMs: Math.round(prefilterMs * 100) / 100,\n });\n\n return Promise.all(\n filtered.map(async (r) => {\n let content = \"\";\n const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);\n\n if (this.config.search.includeContext) {\n try {\n const fileContent = await fsPromises.readFile(\n resolvedFilePath,\n \"utf-8\"\n );\n const lines = fileContent.split(\"\\n\");\n content = lines\n .slice(r.metadata.startLine - 1, r.metadata.endLine)\n .join(\"\\n\");\n } catch {\n content = \"[File not accessible]\";\n }\n }\n\n return {\n filePath: resolvedFilePath,\n startLine: r.metadata.startLine,\n endLine: r.metadata.endLine,\n content,\n score: r.score,\n chunkType: r.metadata.chunkType,\n name: r.metadata.name,\n blame: blameFromMetadata(r.metadata),\n };\n })\n );\n }\n\n async getCallers(targetName: string, callTypeFilter?: string): Promise<CallEdgeData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const seen = new Set<string>();\n const results: CallEdgeData[] = [];\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n for (const edge of database.getCallersWithContext(targetName, branchKey, callTypeFilter)) {\n if (!seen.has(edge.id)) {\n seen.add(edge.id);\n results.push(this.resolveCallEdgeFilePath(edge));\n }\n }\n }\n\n return results;\n }\n\n async getCallersForSymbol(\n symbolId: string,\n targetName: string,\n includeUnresolved: boolean,\n callTypeFilter?: string,\n ): Promise<CallEdgeData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const seen = new Set<string>();\n const results: CallEdgeData[] = [];\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n const branchSymbolIds = new Set(database.getBranchSymbolIds(branchKey));\n if (!branchSymbolIds.has(symbolId)) continue;\n\n for (const edge of database.getCallersWithContext(targetName, branchKey, callTypeFilter)) {\n const matchesResolvedSymbol = edge.toSymbolId === symbolId;\n const safelyMatchesUnresolvedSymbol = includeUnresolved && !edge.toSymbolId;\n if ((!matchesResolvedSymbol && !safelyMatchesUnresolvedSymbol) || seen.has(edge.id)) continue;\n\n seen.add(edge.id);\n results.push(this.resolveCallEdgeFilePath(edge));\n }\n }\n\n return results;\n }\n\n async getCallees(symbolId: string, callTypeFilter?: string): Promise<CallEdgeData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const seen = new Set<string>();\n const results: CallEdgeData[] = [];\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n for (const edge of database.getCallees(symbolId, branchKey, callTypeFilter)) {\n if (!seen.has(edge.id)) {\n seen.add(edge.id);\n results.push(this.resolveCallEdgeFilePath(edge));\n }\n }\n }\n\n return results;\n }\n\n async findCallPath(fromName: string, toName: string, maxDepth?: number): Promise<PathHopData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n let shortest: PathHopData[] = [];\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n const path = database.findShortestPath(fromName, toName, branchKey, maxDepth);\n if (path.length > 0 && (shortest.length === 0 || path.length < shortest.length)) {\n shortest = path;\n }\n }\n\n return shortest.map((hop) => this.resolveFilePathRecord(hop));\n }\n\n async findCallPathBySymbolIds(\n fromSymbolId: string,\n toSymbolId: string,\n maxDepth = 10,\n ): Promise<PathHopData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n let shortest: PathHopData[] = [];\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n const symbols = database.getSymbolsForBranch(branchKey);\n const symbolsById = new Map(symbols.map((symbol) => [symbol.id, symbol]));\n if (!symbolsById.has(fromSymbolId) || !symbolsById.has(toSymbolId)) continue;\n\n const parentBySymbolId = new Map<string, { parentId: string; callType: string }>();\n const visited = new Set([fromSymbolId]);\n const queue: Array<{ symbolId: string; depth: number }> = [{ symbolId: fromSymbolId, depth: 0 }];\n let queueIndex = 0;\n let found = fromSymbolId === toSymbolId;\n\n while (!found && queueIndex < queue.length) {\n const current = queue[queueIndex++];\n if (current.depth >= maxDepth) continue;\n\n const currentSymbol = symbolsById.get(current.symbolId);\n if (!currentSymbol) continue;\n for (const edge of database.getCallees(current.symbolId, branchKey)) {\n let nextSymbolId: string | undefined;\n\n if (edge.toSymbolId && symbolsById.has(edge.toSymbolId)) {\n nextSymbolId = edge.toSymbolId;\n } else if (edge.toSymbolId === undefined) {\n const caseInsensitive = CASE_INSENSITIVE_LANGUAGES.has(currentSymbol.language);\n const matchingTargets = symbols.filter((candidate) => caseInsensitive\n ? candidate.name.toLowerCase() === edge.targetName.toLowerCase()\n : candidate.name === edge.targetName);\n if (matchingTargets.length === 1) {\n nextSymbolId = matchingTargets[0].id;\n }\n }\n\n if (!nextSymbolId || visited.has(nextSymbolId)) continue;\n visited.add(nextSymbolId);\n parentBySymbolId.set(nextSymbolId, {\n parentId: current.symbolId,\n callType: edge.callType,\n });\n\n if (nextSymbolId === toSymbolId) {\n found = true;\n break;\n }\n\n queue.push({ symbolId: nextSymbolId, depth: current.depth + 1 });\n }\n }\n\n if (!found) continue;\n\n const path: PathHopData[] = [];\n let currentSymbolId = toSymbolId;\n while (true) {\n const symbol = symbolsById.get(currentSymbolId);\n if (!symbol) break;\n const parent = parentBySymbolId.get(currentSymbolId);\n path.push({\n symbolId: symbol.id,\n symbolName: symbol.name,\n filePath: symbol.filePath,\n line: symbol.startLine,\n callType: parent?.callType ?? \"source\",\n });\n if (!parent) break;\n currentSymbolId = parent.parentId;\n }\n path.reverse();\n\n if (path.length > 0 && (shortest.length === 0 || path.length < shortest.length)) {\n shortest = path;\n }\n }\n\n return shortest.map((hop) => this.resolveFilePathRecord(hop));\n }\n\n async getCallGraphSymbols(): Promise<SymbolData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const symbols = new Map<string, SymbolData>();\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n for (const symbol of database.getSymbolsForBranch(branchKey)) {\n symbols.set(symbol.id, this.resolveFilePathRecord(symbol));\n }\n }\n\n return [...symbols.values()];\n }\n\n async getSymbolsForBranch(branch?: string): Promise<SymbolData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const resolvedBranch = this.resolveBranchCatalogKey(branch);\n return database.getSymbolsForBranch(resolvedBranch)\n .map((symbol) => this.resolveFilePathRecord(symbol));\n }\n\n async getSymbolsForFiles(filePaths: string[], branch?: string): Promise<SymbolData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const resolvedBranch = this.resolveBranchCatalogKey(branch);\n const storedFilePaths = filePaths.map((filePath) => this.toStoredFilePath(filePath));\n return database.getSymbolsForFiles(storedFilePaths, resolvedBranch)\n .map((symbol) => this.resolveFilePathRecord(symbol));\n }\n\n async getTransitiveReachability(\n rootSymbolIds: string[],\n direction: \"callers\" | \"callees\",\n maxDepth?: number\n ): Promise<ReachabilityData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const branch = this.getBranchCatalogKey();\n return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth)\n .map((entry) => this.resolveFilePathRecord(entry));\n }\n\n async detectCommunities(branch?: string, symbolIds?: string[]): Promise<CommunityData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const resolvedBranch = this.resolveBranchCatalogKey(branch);\n return database.detectCommunities(resolvedBranch, symbolIds)\n .map((entry) => this.resolveFilePathRecord(entry));\n }\n\n async detectCommunityCouplings(branch?: string): Promise<CommunityCouplingData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const resolvedBranch = this.resolveBranchCatalogKey(branch);\n return database.detectCommunityCouplings(resolvedBranch).map((entry) => ({\n ...entry,\n relationships: (entry.relationships ?? entry.representativeRelationships ?? []).map((relationship) => ({\n ...relationship,\n fromFilePath: this.resolveStoredFilePath(relationship.fromFilePath),\n toFilePath: this.resolveStoredFilePath(relationship.toFilePath),\n })),\n }));\n }\n\n async computeCentrality(branch?: string): Promise<CentralityData[]> {\n const { database, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"database\");\n const resolvedBranch = this.resolveBranchCatalogKey(branch);\n return database.computeCentrality(resolvedBranch)\n .map((entry) => this.resolveFilePathRecord(entry));\n }\n\n async getPrImpact(opts: {\n pr?: number;\n branch?: string;\n maxDepth?: number;\n hubThreshold?: number;\n checkConflicts?: boolean;\n direction?: \"callers\" | \"callees\" | \"both\";\n }, onPreparationProgress?: ProgressCallback): Promise<PrImpactResult> {\n const initialState = await this.ensureInitialized();\n let database = initialState.database;\n const { readIssues } = initialState;\n this.requireReadableComponents(readIssues, \"database\");\n const execFileAsync = promisify(execFile);\n\n const changedFilesResult = await getChangedFiles({\n pr: opts.pr,\n branch: opts.branch,\n projectRoot: this.projectRoot,\n baseBranch: this.baseBranch,\n });\n const changedFiles = changedFilesResult.files;\n const headRefName = changedFilesResult.headRefName;\n const expectedCommit = changedFilesResult.headRef;\n\n if (opts.pr !== undefined && headRefName === undefined) {\n throw new Error(\n `Could not resolve head branch for PR #${opts.pr}. Run index_codebase on the PR branch first.`,\n );\n }\n if (!expectedCommit || !isFullGitCommit(expectedCommit)) {\n throw new Error(\"Could not resolve an authoritative full commit OID for impact analysis.\");\n }\n\n const resolvedBranch = opts.pr !== undefined\n ? headRefName\n : opts.branch || this.currentBranch;\n const catalogIdentity = changedFilesResult.catalogIdentity;\n const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);\n\n let branchSymbols = database.getSymbolsForBranch(branchKey);\n let indexPreparation: NonNullable<PrImpactResult[\"indexPreparation\"]> = {\n prepared: false,\n branch: resolvedBranch || \"default\",\n };\n const requestedRef = opts.pr !== undefined\n ? expectedCommit\n : headRefName ?? resolvedBranch;\n const storedCommit = this.getStoredBranchCommit(database, catalogIdentity);\n const catalogIdentityMatches = storedCommit === expectedCommit;\n\n const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database, catalogIdentity);\n\n if (branchSymbols.length === 0 || !catalogIdentityMatches || !migrationsCurrent) {\n if (!resolvedBranch || resolvedBranch === \"default\") {\n throw new Error(\"Run index_codebase first to build the call graph and symbol index for this project.\");\n }\n\n onPreparationProgress?.({\n phase: \"scanning\",\n filesProcessed: 0,\n totalFiles: 0,\n chunksProcessed: 0,\n totalChunks: 0,\n });\n this.resetLoadedIndexState();\n const materialized = await withMaterializedBranch(\n {\n projectRoot: this.projectRoot,\n branch: resolvedBranch,\n ref: requestedRef,\n expectedCommit,\n pr: opts.pr,\n repository: changedFilesResult.baseRepository,\n },\n async (worktreePath, info) => {\n const branchIndexer = new Indexer(this.projectRoot, this.config, this.host, {\n materializedProjectRoot: worktreePath,\n branchName: resolvedBranch,\n catalogIdentity,\n expectedCommit,\n indexPath: this.indexPath,\n });\n try {\n return await branchIndexer.indexBranchIfMissing(\n resolvedBranch,\n info.commit,\n onPreparationProgress,\n );\n } finally {\n await branchIndexer.close();\n }\n },\n );\n\n indexPreparation = {\n prepared: materialized.value.prepared,\n branch: resolvedBranch,\n commit: materialized.info.commit,\n source: materialized.info.source,\n };\n\n const refreshedState = await this.ensureInitialized();\n this.requireReadableComponents(refreshedState.readIssues, \"database\");\n database = refreshedState.database;\n branchSymbols = database.getSymbolsForBranch(branchKey);\n if (branchSymbols.length === 0) {\n throw new Error(\n `Branch ${JSON.stringify(resolvedBranch)} (catalog ${JSON.stringify(catalogIdentity)}) was indexed but produced no call-graph symbols. `\n + `Available branch catalogs: ${database.getAllBranches().join(\", \") || \"none\"}; `\n + `${database.getBranchChunkIds(branchKey).length} chunks, ${database.getBranchSymbolIds(branchKey).length} symbol IDs. `\n + \"Ensure the branch contains a supported source language and is included by the index configuration.\",\n );\n }\n }\n\n const toStoredChangedFiles = (filePaths: readonly string[]): string[] =>\n filePaths.map((filePath) => this.toStoredFilePath(path.resolve(this.projectRoot, filePath)));\n const storedChangedFiles = toStoredChangedFiles(changedFiles);\n const directSymbols = database.getSymbolsForFiles(storedChangedFiles, branchKey);\n const directIds = directSymbols.map((s) => s.id);\n\n const direction = opts.direction ?? \"both\";\n const maxDepth = opts.maxDepth ?? 5;\n const transitiveCallers = database.getTransitiveReachability(\n directIds,\n branchKey,\n direction,\n maxDepth\n );\n\n const affectedIdsSet = new Set<string>(directIds);\n for (const caller of transitiveCallers) {\n affectedIdsSet.add(caller.symbolId);\n }\n const allAffectedIds = Array.from(affectedIdsSet);\n\n const communitiesData = database.detectCommunities(branchKey, allAffectedIds);\n const communityMap = new Map<string, { label: string; symbolCount: number; directSymbols: Set<string> }>();\n for (const c of communitiesData) {\n if (!communityMap.has(c.communityLabel)) {\n communityMap.set(c.communityLabel, {\n label: c.communityLabel,\n symbolCount: 0,\n directSymbols: new Set(),\n });\n }\n const entry = communityMap.get(c.communityLabel)!;\n entry.symbolCount++;\n if (directIds.includes(c.symbolId)) {\n entry.directSymbols.add(c.symbolId);\n }\n }\n const communities = Array.from(communityMap.values()).map((c) => ({\n label: c.label,\n symbolCount: c.symbolCount,\n directSymbols: Array.from(c.directSymbols),\n }));\n\n const centralityData = database.computeCentrality(branchKey);\n const hubThreshold = opts.hubThreshold ?? 10;\n const hubNodes = centralityData\n .filter((c) => directIds.includes(c.symbolId) && c.callerCount >= hubThreshold)\n .map((c) => ({\n id: c.symbolId,\n name: c.symbolName,\n callerCount: c.callerCount,\n filePath: this.resolveStoredFilePath(c.filePath),\n }));\n\n const totalAffected = allAffectedIds.length;\n let riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\";\n let riskReason: string;\n\n if (totalAffected < 5 && hubNodes.length === 0) {\n riskLevel = \"LOW\";\n riskReason = `Small impact: ${totalAffected} affected symbols, no hub nodes touched.`;\n } else if (totalAffected > 20 || hubNodes.length > 1) {\n riskLevel = \"HIGH\";\n riskReason = `Large impact: ${totalAffected} affected symbols${hubNodes.length > 0 ? `, ${hubNodes.length} hub nodes touched` : \"\"}.`;\n } else {\n riskLevel = \"MEDIUM\";\n riskReason = `Moderate impact: ${totalAffected} affected symbols${hubNodes.length === 1 ? \", 1 hub node touched\" : \"\"}.`;\n }\n\n let conflictingPRs: PrImpactResult[\"conflictingPRs\"];\n if (opts.checkConflicts) {\n conflictingPRs = [];\n try {\n const { stdout } = await execFileAsync(\n \"gh\",\n [\"pr\", \"list\", \"--state\", \"open\", \"--json\", \"number,headRefName\", \"--limit\", \"10000\"],\n { cwd: this.projectRoot, timeout: 30000 }\n );\n const openPRs = JSON.parse(stdout) as Array<{ number: number; headRefName: string }>;\n\n const currentCommunityLabels = new Set(communities.map((c) => c.label));\n const allCommunitiesData = database.detectCommunities(branchKey);\n const symbolToCommunity = new Map<string, string>();\n const structuralKey = (filePath: string, name: string): string =>\n `${filePath.toLowerCase()}:${name.toLowerCase()}`;\n for (const c of allCommunitiesData) {\n symbolToCommunity.set(structuralKey(c.filePath, c.symbolName), c.communityLabel);\n }\n\n for (const openPr of openPRs) {\n if (openPr.number === opts.pr) continue;\n\n try {\n const otherChanged = await getChangedFiles({\n pr: openPr.number,\n projectRoot: this.projectRoot,\n baseBranch: this.baseBranch,\n });\n const otherStored = toStoredChangedFiles(otherChanged.files);\n const prBranchKey = this.getBranchCatalogKeyFor(otherChanged.catalogIdentity);\n const otherSymbols = database.getSymbolsForFiles(otherStored, prBranchKey);\n const otherLabels = new Set<string>();\n for (const sym of otherSymbols) {\n const label = symbolToCommunity.get(structuralKey(sym.filePath, sym.name));\n if (label) {\n otherLabels.add(label);\n }\n }\n const overlapping = Array.from(otherLabels).filter((l) =>\n currentCommunityLabels.has(l)\n );\n if (overlapping.length > 0) {\n conflictingPRs.push({\n pr: openPr.number,\n branch: openPr.headRefName,\n overlappingCommunities: overlapping,\n });\n }\n } catch {\n /* skip PRs we can't analyze */\n }\n }\n } catch {\n /* gh CLI not available or failed; skip conflict detection */\n }\n }\n\n return {\n indexPreparation,\n changedFiles,\n directSymbols: directSymbols.map((s) => ({\n id: s.id,\n name: s.name,\n kind: s.kind,\n filePath: this.resolveStoredFilePath(s.filePath),\n })),\n transitiveCallers: transitiveCallers.map((c) => ({\n id: c.symbolId,\n name: c.symbolName,\n filePath: this.resolveStoredFilePath(c.filePath),\n depth: c.depth,\n })),\n totalAffected,\n communities,\n hubNodes,\n riskLevel,\n riskReason,\n direction,\n conflictingPRs,\n };\n }\n\n async getVisualizationData(options?: { directory?: string }): Promise<{\n symbols: SymbolData[];\n edges: CallEdgeData[];\n }> {\n const { database, store, readIssues } = await this.ensureInitialized();\n this.requireReadableComponents(readIssues, \"vectors\", \"database\");\n const seenSymbols = new Map<string, SymbolData>();\n const seenEdges = new Map<string, CallEdgeData>();\n\n for (const branchKey of this.getBranchCatalogKeys()) {\n // Get all symbol IDs on this branch\n const symbolIds = database.getBranchSymbolIds(branchKey);\n const symbolIdSet = new Set(symbolIds);\n\n // Get unique file paths from branch chunks' metadata\n const chunkIds = database.getBranchChunkIds(branchKey);\n const metadataMap = chunkIds.length > 0 ? store.getMetadataBatch(chunkIds) : new Map<string, import(\"../native/index.js\").ChunkMetadata>();\n const filePaths = new Set<string>();\n for (const [, meta] of metadataMap) {\n if (meta.filePath) filePaths.add(meta.filePath);\n }\n\n const directory = options?.directory?.replace(/\\/$/, \"\");\n const absoluteDirectoryFilter = directory\n ? path.resolve(this.projectRoot, directory)\n : undefined;\n\n // Gather symbols from each file\n for (const filePath of filePaths) {\n if (directory) {\n const absoluteFilePath = this.resolveStoredFilePath(filePath);\n const matchesRelative = filePath === directory || filePath.startsWith(directory + \"/\");\n const matchesProjectRelative = absoluteDirectoryFilter !== undefined && (\n absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path.sep)\n );\n if (!matchesRelative && !matchesProjectRelative) {\n continue;\n }\n }\n for (const sym of database.getSymbolsByFile(filePath)) {\n if (symbolIdSet.has(sym.id) && !seenSymbols.has(sym.id)) {\n seenSymbols.set(sym.id, this.resolveFilePathRecord(sym));\n }\n }\n }\n\n // Gather edges from each symbol\n for (const symbolId of seenSymbols.keys()) {\n for (const edge of database.getCallees(symbolId, branchKey)) {\n if (!seenEdges.has(edge.id)) {\n seenEdges.set(edge.id, this.resolveCallEdgeFilePath(edge));\n }\n }\n }\n }\n\n return { symbols: [...seenSymbols.values()], edges: [...seenEdges.values()] };\n }\n\n async close(): Promise<void> {\n this.database?.close();\n for (const database of this.retiredDatabases) {\n database.close();\n }\n this.retiredDatabases = [];\n this.database = null;\n this.store = null;\n this.invertedIndex = null;\n this.provider = null;\n this.configuredProviderInfo = null;\n this.indexCompatibility = null;\n this.initializationMode = \"none\";\n this.readIssues = [];\n this.readerArtifactFingerprint = null;\n this.writerArtifactFingerprint = null;\n this.readerArtifactRetryAfter.clear();\n }\n}\n","import EventEmitter from './index.js'\n\nexport { EventEmitter }\nexport default EventEmitter\n","export class TimeoutError extends Error {\n\tname = 'TimeoutError';\n\n\tconstructor(message, options) {\n\t\tsuper(message, options);\n\t\tError.captureStackTrace?.(this, TimeoutError);\n\t}\n}\n\nconst getAbortedReason = signal => signal.reason ?? new DOMException('This operation was aborted.', 'AbortError');\n\nexport default function pTimeout(promise, options) {\n\tconst {\n\t\tmilliseconds,\n\t\tfallback,\n\t\tmessage,\n\t\tcustomTimers = {setTimeout, clearTimeout},\n\t\tsignal,\n\t} = options;\n\n\tlet timer;\n\tlet abortHandler;\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tif (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {\n\t\t\tthrow new TypeError(`Expected \\`milliseconds\\` to be a positive number, got \\`${milliseconds}\\``);\n\t\t}\n\n\t\tif (signal?.aborted) {\n\t\t\treject(getAbortedReason(signal));\n\t\t\treturn;\n\t\t}\n\n\t\tif (signal) {\n\t\t\tabortHandler = () => {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t};\n\n\t\t\tsignal.addEventListener('abort', abortHandler, {once: true});\n\t\t}\n\n\t\t// Use .then() instead of async IIFE to preserve stack traces\n\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/prefer-catch\n\t\tpromise.then(resolve, reject);\n\n\t\tif (milliseconds === Number.POSITIVE_INFINITY) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We create the error outside of `setTimeout` to preserve the stack trace.\n\t\tconst timeoutError = new TimeoutError();\n\n\t\t// `.call(undefined, ...)` is needed for custom timers to avoid context issues\n\t\ttimer = customTimers.setTimeout.call(undefined, () => {\n\t\t\tif (fallback) {\n\t\t\t\ttry {\n\t\t\t\t\tresolve(fallback());\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof promise.cancel === 'function') {\n\t\t\t\tpromise.cancel();\n\t\t\t}\n\n\t\t\tif (message === false) {\n\t\t\t\tresolve();\n\t\t\t} else if (message instanceof Error) {\n\t\t\t\treject(message);\n\t\t\t} else {\n\t\t\t\ttimeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;\n\t\t\t\treject(timeoutError);\n\t\t\t}\n\t\t}, milliseconds);\n\t});\n\n\t// eslint-disable-next-line promise/prefer-await-to-then\n\tconst cancelablePromise = wrappedPromise.finally(() => {\n\t\tcancelablePromise.clear();\n\t\tif (abortHandler && signal) {\n\t\t\tsignal.removeEventListener('abort', abortHandler);\n\t\t}\n\t});\n\n\tcancelablePromise.clear = () => {\n\t\t// `.call(undefined, ...)` is needed for custom timers to avoid context issues\n\t\tcustomTimers.clearTimeout.call(undefined, timer);\n\t\ttimer = undefined;\n\t};\n\n\treturn cancelablePromise;\n}\n","// Port of lower_bound from https://en.cppreference.com/w/cpp/algorithm/lower_bound\n// Used to compute insertion index to keep queue sorted after insertion\nexport default function lowerBound(array, value, comparator) {\n let first = 0;\n let count = array.length;\n while (count > 0) {\n const step = Math.trunc(count / 2);\n let it = first + step;\n if (comparator(array[it], value) <= 0) {\n first = ++it;\n count -= step + 1;\n }\n else {\n count = step;\n }\n }\n return first;\n}\n","import lowerBound from './lower-bound.js';\nexport default class PriorityQueue {\n #queue = [];\n enqueue(run, options) {\n const { priority = 0, id, } = options ?? {};\n const element = {\n priority,\n id,\n run,\n };\n if (this.size === 0 || this.#queue[this.size - 1].priority >= priority) {\n this.#queue.push(element);\n return;\n }\n const index = lowerBound(this.#queue, element, (a, b) => b.priority - a.priority);\n this.#queue.splice(index, 0, element);\n }\n setPriority(id, priority) {\n const index = this.#queue.findIndex((element) => element.id === id);\n if (index === -1) {\n throw new ReferenceError(`No promise function with the id \"${id}\" exists in the queue.`);\n }\n const [item] = this.#queue.splice(index, 1);\n this.enqueue(item.run, { priority, id });\n }\n remove(idOrRun) {\n const index = this.#queue.findIndex((element) => {\n if (typeof idOrRun === 'string') {\n return element.id === idOrRun;\n }\n return element.run === idOrRun;\n });\n if (index !== -1) {\n this.#queue.splice(index, 1);\n }\n }\n dequeue() {\n const item = this.#queue.shift();\n return item?.run;\n }\n filter(options) {\n return this.#queue.filter((element) => element.priority === options.priority).map((element) => element.run);\n }\n get size() {\n return this.#queue.length;\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport pTimeout from 'p-timeout';\nimport PriorityQueue from './priority-queue.js';\n/**\nPromise queue with concurrency control.\n*/\nexport default class PQueue extends EventEmitter {\n #carryoverIntervalCount;\n #isIntervalIgnored;\n #intervalCount = 0;\n #intervalCap;\n #rateLimitedInInterval = false;\n #rateLimitFlushScheduled = false;\n #interval;\n #intervalEnd = 0;\n #lastExecutionTime = 0;\n #intervalId;\n #timeoutId;\n #strict;\n // Circular buffer implementation for better performance\n #strictTicks = [];\n #strictTicksStartIndex = 0;\n #queue;\n #queueClass;\n #pending = 0;\n // The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194\n #concurrency;\n #isPaused;\n // Use to assign a unique identifier to a promise function, if not explicitly specified\n #idAssigner = 1n;\n // Track currently running tasks for debugging\n #runningTasks = new Map();\n #queueAbortListenerCleanupFunctions = new Set();\n /**\n Get or set the default timeout for all tasks. Can be changed at runtime.\n\n Operations will throw a `TimeoutError` if they don't complete within the specified time.\n\n The timeout begins when the operation is dequeued and starts execution, not while it's waiting in the queue.\n\n @example\n ```\n const queue = new PQueue({timeout: 5000});\n\n // Change timeout for all future tasks\n queue.timeout = 10000;\n ```\n */\n timeout;\n constructor(options) {\n super();\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n options = {\n carryoverIntervalCount: false,\n intervalCap: Number.POSITIVE_INFINITY,\n interval: 0,\n concurrency: Number.POSITIVE_INFINITY,\n autoStart: true,\n queueClass: PriorityQueue,\n strict: false,\n ...options,\n };\n if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) {\n throw new TypeError(`Expected \\`intervalCap\\` to be a number from 1 and up, got \\`${options.intervalCap?.toString() ?? ''}\\` (${typeof options.intervalCap})`);\n }\n if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) {\n throw new TypeError(`Expected \\`interval\\` to be a finite number >= 0, got \\`${options.interval?.toString() ?? ''}\\` (${typeof options.interval})`);\n }\n if (options.strict && options.interval === 0) {\n throw new TypeError('The `strict` option requires a non-zero `interval`');\n }\n if (options.strict && options.intervalCap === Number.POSITIVE_INFINITY) {\n throw new TypeError('The `strict` option requires a finite `intervalCap`');\n }\n // TODO: Remove this fallback in the next major version\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n this.#carryoverIntervalCount = options.carryoverIntervalCount ?? options.carryoverConcurrencyCount ?? false;\n this.#isIntervalIgnored = options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0;\n this.#intervalCap = options.intervalCap;\n this.#interval = options.interval;\n this.#strict = options.strict;\n this.#queue = new options.queueClass();\n this.#queueClass = options.queueClass;\n this.concurrency = options.concurrency;\n if (options.timeout !== undefined && !(Number.isFinite(options.timeout) && options.timeout > 0)) {\n throw new TypeError(`Expected \\`timeout\\` to be a positive finite number, got \\`${options.timeout}\\` (${typeof options.timeout})`);\n }\n this.timeout = options.timeout;\n this.#isPaused = options.autoStart === false;\n this.#setupRateLimitTracking();\n }\n #cleanupStrictTicks(now) {\n // Remove ticks outside the current interval window using circular buffer approach\n while (this.#strictTicksStartIndex < this.#strictTicks.length) {\n const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];\n if (oldestTick !== undefined && now - oldestTick >= this.#interval) {\n this.#strictTicksStartIndex++;\n }\n else {\n break;\n }\n }\n // Compact the array when it becomes inefficient or fully consumed\n // Compact when: (start index is large AND more than half wasted) OR all ticks expired\n const shouldCompact = (this.#strictTicksStartIndex > 100 && this.#strictTicksStartIndex > this.#strictTicks.length / 2)\n || this.#strictTicksStartIndex === this.#strictTicks.length;\n if (shouldCompact) {\n this.#strictTicks = this.#strictTicks.slice(this.#strictTicksStartIndex);\n this.#strictTicksStartIndex = 0;\n }\n }\n // Helper methods for interval consumption\n #consumeIntervalSlot(now) {\n if (this.#strict) {\n this.#strictTicks.push(now);\n }\n else {\n this.#intervalCount++;\n }\n }\n #rollbackIntervalSlot() {\n if (this.#strict) {\n // Pop from the end of the actual data (not from start index)\n if (this.#strictTicks.length > this.#strictTicksStartIndex) {\n this.#strictTicks.pop();\n }\n }\n else if (this.#intervalCount > 0) {\n this.#intervalCount--;\n }\n }\n #getActiveTicksCount() {\n return this.#strictTicks.length - this.#strictTicksStartIndex;\n }\n get #doesIntervalAllowAnother() {\n if (this.#isIntervalIgnored) {\n return true;\n }\n if (this.#strict) {\n // Cleanup already done by #isIntervalPausedAt before this is called\n return this.#getActiveTicksCount() < this.#intervalCap;\n }\n return this.#intervalCount < this.#intervalCap;\n }\n get #doesConcurrentAllowAnother() {\n return this.#pending < this.#concurrency;\n }\n #next() {\n this.#pending--;\n if (this.#pending === 0) {\n this.emit('pendingZero');\n }\n this.#tryToStartAnother();\n this.emit('next');\n }\n #onResumeInterval() {\n // Clear timeout ID before processing to prevent race condition\n // Must clear before #onInterval to allow new timeouts to be scheduled\n this.#timeoutId = undefined;\n this.#onInterval();\n this.#initializeIntervalIfNeeded();\n }\n #isIntervalPausedAt(now) {\n // Strict mode: check if we need to wait for oldest tick to age out\n if (this.#strict) {\n this.#cleanupStrictTicks(now);\n // If at capacity, need to wait for oldest tick to age out\n const activeTicksCount = this.#getActiveTicksCount();\n if (activeTicksCount >= this.#intervalCap) {\n const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];\n // After cleanup, remaining ticks are within interval, so delay is always > 0\n const delay = this.#interval - (now - oldestTick);\n this.#createIntervalTimeout(delay);\n return true;\n }\n return false;\n }\n // Fixed window mode (original logic)\n if (this.#intervalId === undefined) {\n const delay = this.#intervalEnd - now;\n if (delay < 0) {\n // If the interval has expired while idle, check if we should enforce the interval\n // from the last task execution. This ensures proper spacing between tasks even\n // when the queue becomes empty and then new tasks are added.\n if (this.#lastExecutionTime > 0) {\n const timeSinceLastExecution = now - this.#lastExecutionTime;\n if (timeSinceLastExecution < this.#interval) {\n // Not enough time has passed since the last task execution\n this.#createIntervalTimeout(this.#interval - timeSinceLastExecution);\n return true;\n }\n }\n // Enough time has passed or no previous execution, allow execution\n this.#intervalCount = (this.#carryoverIntervalCount) ? this.#pending : 0;\n }\n else {\n // Act as the interval is pending\n this.#createIntervalTimeout(delay);\n return true;\n }\n }\n return false;\n }\n #createIntervalTimeout(delay) {\n if (this.#timeoutId !== undefined) {\n return;\n }\n this.#timeoutId = setTimeout(() => {\n this.#onResumeInterval();\n }, delay);\n }\n #clearIntervalTimer() {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n }\n }\n #clearTimeoutTimer() {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n this.#timeoutId = undefined;\n }\n }\n #tryToStartAnother() {\n if (this.#queue.size === 0) {\n // We can clear the interval (\"pause\")\n // Because we can redo it later (\"resume\")\n this.#clearIntervalTimer();\n this.emit('empty');\n if (this.#pending === 0) {\n // Clear timeout as well when completely idle\n this.#clearTimeoutTimer();\n // Compact strict ticks when idle to free memory\n if (this.#strict && this.#strictTicksStartIndex > 0) {\n const now = Date.now();\n this.#cleanupStrictTicks(now);\n }\n this.emit('idle');\n }\n return false;\n }\n let taskStarted = false;\n if (!this.#isPaused) {\n const now = Date.now();\n const canInitializeInterval = !this.#isIntervalPausedAt(now);\n if (this.#doesIntervalAllowAnother && this.#doesConcurrentAllowAnother) {\n const job = this.#queue.dequeue();\n if (!this.#isIntervalIgnored) {\n this.#consumeIntervalSlot(now);\n this.#scheduleRateLimitUpdate();\n }\n this.emit('active');\n job();\n if (canInitializeInterval) {\n this.#initializeIntervalIfNeeded();\n }\n taskStarted = true;\n }\n }\n return taskStarted;\n }\n #initializeIntervalIfNeeded() {\n if (this.#isIntervalIgnored || this.#intervalId !== undefined) {\n return;\n }\n // Strict mode uses timeouts instead of interval timers\n if (this.#strict) {\n return;\n }\n this.#intervalId = setInterval(() => {\n this.#onInterval();\n }, this.#interval);\n this.#intervalEnd = Date.now() + this.#interval;\n }\n #onInterval() {\n // Non-strict mode uses interval timers and intervalCount\n if (!this.#strict) {\n if (this.#intervalCount === 0 && this.#pending === 0 && this.#intervalId) {\n this.#clearIntervalTimer();\n }\n this.#intervalCount = this.#carryoverIntervalCount ? this.#pending : 0;\n }\n this.#processQueue();\n this.#scheduleRateLimitUpdate();\n }\n /**\n Executes all queued functions until it reaches the limit.\n */\n #processQueue() {\n // eslint-disable-next-line no-empty\n while (this.#tryToStartAnother()) { }\n }\n get concurrency() {\n return this.#concurrency;\n }\n set concurrency(newConcurrency) {\n if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) {\n throw new TypeError(`Expected \\`concurrency\\` to be a number from 1 and up, got \\`${newConcurrency}\\` (${typeof newConcurrency})`);\n }\n this.#concurrency = newConcurrency;\n this.#processQueue();\n }\n /**\n Updates the priority of a promise function by its id, affecting its execution order. Requires a defined concurrency limit to take effect.\n\n For example, this can be used to prioritize a promise function to run earlier.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 1});\n\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦀', {priority: 0, id: '🦀'});\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦄', {priority: 1});\n\n queue.setPriority('🦀', 2);\n ```\n\n In this case, the promise function with `id: '🦀'` runs second.\n\n You can also deprioritize a promise function to delay its execution:\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 1});\n\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦀', {priority: 1, id: '🦀'});\n queue.add(async () => '🦄');\n queue.add(async () => '🦄', {priority: 0});\n\n queue.setPriority('🦀', -1);\n ```\n Here, the promise function with `id: '🦀'` executes last.\n */\n setPriority(id, priority) {\n if (typeof priority !== 'number' || !Number.isFinite(priority)) {\n throw new TypeError(`Expected \\`priority\\` to be a finite number, got \\`${priority}\\` (${typeof priority})`);\n }\n this.#queue.setPriority(id, priority);\n }\n async add(function_, options = {}) {\n // Create a copy to avoid mutating the original options object\n options = {\n timeout: this.timeout,\n ...options,\n // Assign unique ID if not provided\n id: options.id ?? (this.#idAssigner++).toString(),\n };\n return new Promise((resolve, reject) => {\n // Create a unique symbol for tracking this task\n const taskSymbol = Symbol(`task-${options.id}`);\n let cleanupQueueAbortHandler = () => undefined;\n const run = async () => {\n // Task is now running — remove the queued-state abort listener\n cleanupQueueAbortHandler();\n this.#pending++;\n // Track this running task\n this.#runningTasks.set(taskSymbol, {\n id: options.id,\n priority: options.priority ?? 0, // Match priority-queue default\n startTime: Date.now(),\n timeout: options.timeout,\n });\n let eventListener;\n try {\n // Check abort signal - if aborted, need to decrement the counter\n // that was incremented in tryToStartAnother\n try {\n options.signal?.throwIfAborted();\n }\n catch (error) {\n this.#rollbackIntervalConsumption();\n // Clean up tracking before throwing\n this.#runningTasks.delete(taskSymbol);\n throw error;\n }\n this.#lastExecutionTime = Date.now();\n let operation = function_({ signal: options.signal });\n if (options.timeout) {\n operation = pTimeout(Promise.resolve(operation), {\n milliseconds: options.timeout,\n message: `Task timed out after ${options.timeout}ms (queue has ${this.#pending} running, ${this.#queue.size} waiting)`,\n });\n }\n if (options.signal) {\n const { signal } = options;\n operation = Promise.race([operation, new Promise((_resolve, reject) => {\n eventListener = () => {\n reject(signal.reason);\n };\n signal.addEventListener('abort', eventListener, { once: true });\n })]);\n }\n const result = await operation;\n resolve(result);\n this.emit('completed', result);\n }\n catch (error) {\n reject(error);\n this.emit('error', error);\n }\n finally {\n // Clean up abort event listener\n if (eventListener) {\n options.signal?.removeEventListener('abort', eventListener);\n }\n // Remove from running tasks\n this.#runningTasks.delete(taskSymbol);\n // Use queueMicrotask to prevent deep recursion while maintaining timing\n queueMicrotask(() => {\n this.#next();\n });\n }\n };\n this.#queue.enqueue(run, options);\n const removeQueuedTask = () => {\n if (this.#queue instanceof PriorityQueue) {\n this.#queue.remove(run);\n return;\n }\n this.#queue.remove?.(options.id); // Intentionally best-effort: queued abort removal is only supported for queue classes that implement `.remove()`.\n };\n // Handle abort while task is waiting in the queue\n if (options.signal) {\n const { signal } = options;\n const queueAbortHandler = () => {\n cleanupQueueAbortHandler();\n removeQueuedTask();\n reject(signal.reason);\n this.#tryToStartAnother();\n this.emit('next');\n };\n cleanupQueueAbortHandler = () => {\n signal.removeEventListener('abort', queueAbortHandler);\n this.#queueAbortListenerCleanupFunctions.delete(cleanupQueueAbortHandler);\n };\n if (signal.aborted) {\n queueAbortHandler();\n return;\n }\n signal.addEventListener('abort', queueAbortHandler, { once: true });\n this.#queueAbortListenerCleanupFunctions.add(cleanupQueueAbortHandler);\n }\n this.emit('add');\n this.#tryToStartAnother();\n });\n }\n async addAll(functions, options) {\n return Promise.all(functions.map(async (function_) => this.add(function_, options)));\n }\n /**\n Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.)\n */\n start() {\n if (!this.#isPaused) {\n return this;\n }\n this.#isPaused = false;\n this.#processQueue();\n return this;\n }\n /**\n Put queue execution on hold.\n */\n pause() {\n this.#isPaused = true;\n }\n /**\n Clear the queue.\n */\n clear() {\n for (const cleanupQueueAbortHandler of this.#queueAbortListenerCleanupFunctions) {\n cleanupQueueAbortHandler();\n }\n this.#queue = new this.#queueClass();\n // Clear interval timer since queue is now empty (consistent with #tryToStartAnother)\n this.#clearIntervalTimer();\n // Note: We preserve strict mode rate-limiting state (ticks and timeout)\n // because clear() only clears queued tasks, not rate limit history.\n // This ensures that rate limits are still enforced after clearing the queue.\n // Note: We don't clear #runningTasks as those tasks are still running\n // They will be removed when they complete in the finally block\n // Force synchronous update since clear() should have immediate effect\n this.#updateRateLimitState();\n // Emit events so waiters (onEmpty, onIdle, onSizeLessThan) can resolve\n this.emit('empty');\n if (this.#pending === 0) {\n this.#clearTimeoutTimer();\n this.emit('idle');\n }\n this.emit('next');\n }\n /**\n Can be called multiple times. Useful if you for example add additional items at a later time.\n\n @returns A promise that settles when the queue becomes empty.\n */\n async onEmpty() {\n // Instantly resolve if the queue is empty\n if (this.#queue.size === 0) {\n return;\n }\n await this.#onEvent('empty');\n }\n /**\n @returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`.\n\n If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.\n\n Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation.\n */\n async onSizeLessThan(limit) {\n // Instantly resolve if the queue is empty.\n if (this.#queue.size < limit) {\n return;\n }\n await this.#onEvent('next', () => this.#queue.size < limit);\n }\n /**\n The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.\n\n @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`.\n */\n async onIdle() {\n // Instantly resolve if none pending and if nothing else is queued\n if (this.#pending === 0 && this.#queue.size === 0) {\n return;\n }\n await this.#onEvent('idle');\n }\n /**\n The difference with `.onIdle` is that `.onPendingZero` only waits for currently running tasks to finish, ignoring queued tasks.\n\n @returns A promise that settles when all currently running tasks have completed; `queue.pending === 0`.\n */\n async onPendingZero() {\n if (this.#pending === 0) {\n return;\n }\n await this.#onEvent('pendingZero');\n }\n /**\n @returns A promise that settles when the queue becomes rate-limited due to intervalCap.\n */\n async onRateLimit() {\n if (this.isRateLimited) {\n return;\n }\n await this.#onEvent('rateLimit');\n }\n /**\n @returns A promise that settles when the queue is no longer rate-limited.\n */\n async onRateLimitCleared() {\n if (!this.isRateLimited) {\n return;\n }\n await this.#onEvent('rateLimitCleared');\n }\n /**\n @returns A promise that rejects when any task in the queue errors.\n\n Use with `Promise.race([queue.onError(), queue.onIdle()])` to fail fast on the first error while still resolving normally when the queue goes idle.\n\n Important: The promise returned by `add()` still rejects. You must handle each `add()` promise (for example, `.catch(() => {})`) to avoid unhandled rejections.\n\n @example\n ```\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n queue.add(() => fetchData(1)).catch(() => {});\n queue.add(() => fetchData(2)).catch(() => {});\n queue.add(() => fetchData(3)).catch(() => {});\n\n // Stop processing on first error\n try {\n await Promise.race([\n queue.onError(),\n queue.onIdle()\n ]);\n } catch (error) {\n queue.pause(); // Stop processing remaining tasks\n console.error('Queue failed:', error);\n }\n ```\n */\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n onError() {\n return new Promise((_resolve, reject) => {\n const handleError = (error) => {\n this.off('error', handleError);\n reject(error);\n };\n this.on('error', handleError);\n });\n }\n async #onEvent(event, filter) {\n return new Promise(resolve => {\n const listener = () => {\n if (filter && !filter()) {\n return;\n }\n this.off(event, listener);\n resolve();\n };\n this.on(event, listener);\n });\n }\n /**\n Size of the queue, the number of queued items waiting to run.\n */\n get size() {\n return this.#queue.size;\n }\n /**\n Size of the queue, filtered by the given options.\n\n For example, this can be used to find the number of items remaining in the queue with a specific priority level.\n */\n sizeBy(options) {\n // eslint-disable-next-line unicorn/no-array-callback-reference\n return this.#queue.filter(options).length;\n }\n /**\n Number of running items (no longer in the queue).\n */\n get pending() {\n return this.#pending;\n }\n /**\n Whether the queue is currently paused.\n */\n get isPaused() {\n return this.#isPaused;\n }\n #setupRateLimitTracking() {\n // Only schedule updates when rate limiting is enabled\n if (this.#isIntervalIgnored) {\n return;\n }\n // Wire up to lifecycle events that affect rate limit state\n // Only 'add' and 'next' can actually change rate limit state\n this.on('add', () => {\n if (this.#queue.size > 0) {\n this.#scheduleRateLimitUpdate();\n }\n });\n this.on('next', () => {\n this.#scheduleRateLimitUpdate();\n });\n }\n #scheduleRateLimitUpdate() {\n // Skip if rate limiting is not enabled or already scheduled\n if (this.#isIntervalIgnored || this.#rateLimitFlushScheduled) {\n return;\n }\n this.#rateLimitFlushScheduled = true;\n queueMicrotask(() => {\n this.#rateLimitFlushScheduled = false;\n this.#updateRateLimitState();\n });\n }\n #rollbackIntervalConsumption() {\n if (this.#isIntervalIgnored) {\n return;\n }\n this.#rollbackIntervalSlot();\n this.#scheduleRateLimitUpdate();\n }\n #updateRateLimitState() {\n const previous = this.#rateLimitedInInterval;\n // Early exit if rate limiting is disabled or queue is empty\n if (this.#isIntervalIgnored || this.#queue.size === 0) {\n if (previous) {\n this.#rateLimitedInInterval = false;\n this.emit('rateLimitCleared');\n }\n return;\n }\n // Get the current count based on mode\n let count;\n if (this.#strict) {\n const now = Date.now();\n this.#cleanupStrictTicks(now);\n count = this.#getActiveTicksCount();\n }\n else {\n count = this.#intervalCount;\n }\n const shouldBeRateLimited = count >= this.#intervalCap;\n if (shouldBeRateLimited !== previous) {\n this.#rateLimitedInInterval = shouldBeRateLimited;\n this.emit(shouldBeRateLimited ? 'rateLimit' : 'rateLimitCleared');\n }\n }\n /**\n Whether the queue is currently rate-limited due to intervalCap.\n */\n get isRateLimited() {\n return this.#rateLimitedInInterval;\n }\n /**\n Whether the queue is saturated. Returns `true` when:\n - All concurrency slots are occupied and tasks are waiting, OR\n - The queue is rate-limited and tasks are waiting\n\n Useful for detecting backpressure and potential hanging tasks.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n // Backpressure handling\n if (queue.isSaturated) {\n console.log('Queue is saturated, waiting for capacity...');\n await queue.onSizeLessThan(queue.concurrency);\n }\n\n // Monitoring for stuck tasks\n setInterval(() => {\n if (queue.isSaturated) {\n console.warn(`Queue saturated: ${queue.pending} running, ${queue.size} waiting`);\n }\n }, 60000);\n ```\n */\n get isSaturated() {\n return (this.#pending === this.#concurrency && this.#queue.size > 0)\n || (this.isRateLimited && this.#queue.size > 0);\n }\n /**\n The tasks currently being executed. Each task includes its `id`, `priority`, `startTime`, and `timeout` (if set).\n\n Returns an array of task info objects.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n // Add tasks with IDs for better debugging\n queue.add(() => fetchUser(123), {id: 'user-123'});\n queue.add(() => fetchPosts(456), {id: 'posts-456', priority: 1});\n\n // Check what's running\n console.log(queue.runningTasks);\n // => [{\n // id: 'user-123',\n // priority: 0,\n // startTime: 1759253001716,\n // timeout: undefined\n // }, {\n // id: 'posts-456',\n // priority: 1,\n // startTime: 1759253001916,\n // timeout: undefined\n // }]\n ```\n */\n get runningTasks() {\n // Return fresh array with fresh objects to prevent mutations\n return [...this.#runningTasks.values()].map(task => ({ ...task }));\n }\n}\n/**\nError thrown when a task times out.\n\n@example\n```\nimport PQueue, {TimeoutError} from 'p-queue';\n\nconst queue = new PQueue({timeout: 1000});\n\ntry {\n await queue.add(() => someTask());\n} catch (error) {\n if (error instanceof TimeoutError) {\n console.log('Task timed out');\n }\n}\n```\n*/\nexport { TimeoutError } from 'p-timeout';\n","const objectToString = Object.prototype.toString;\n\nconst isError = value => objectToString.call(value) === '[object Error]';\n\nconst errorMessages = new Set([\n\t'network error', // Chrome\n\t'NetworkError when attempting to fetch resource.', // Firefox\n\t'The Internet connection appears to be offline.', // Safari 16\n\t'Network request failed', // `cross-fetch`\n\t'fetch failed', // Undici (Node.js)\n\t'terminated', // Undici (Node.js)\n\t' A network error occurred.', // Bun (WebKit)\n\t'Network connection lost', // Cloudflare Workers (fetch)\n]);\n\nexport default function isNetworkError(error) {\n\tconst isValid = error\n\t\t&& isError(error)\n\t\t&& error.name === 'TypeError'\n\t\t&& typeof error.message === 'string';\n\n\tif (!isValid) {\n\t\treturn false;\n\t}\n\n\tconst {message, stack} = error;\n\n\t// Safari 17+ has generic message but no stack for network errors\n\tif (message === 'Load failed') {\n\t\treturn stack === undefined\n\t\t\t// Sentry adds its own stack trace to the fetch error, so also check for that\n\t\t\t|| '__sentry_captured__' in error;\n\t}\n\n\t// Deno network errors start with specific text\n\tif (message.startsWith('error sending request for url')) {\n\t\treturn true;\n\t}\n\n\t// Chrome: exact \"Failed to fetch\" or with hostname: \"Failed to fetch (example.com)\"\n\tif (message === 'Failed to fetch' || (message.startsWith('Failed to fetch (') && message.endsWith(')'))) {\n\t\treturn true;\n\t}\n\n\t// Standard network error messages\n\treturn errorMessages.has(message);\n}\n","import isNetworkError from 'is-network-error';\n\nfunction validateRetries(retries) {\n\tif (typeof retries === 'number') {\n\t\tif (retries < 0) {\n\t\t\tthrow new TypeError('Expected `retries` to be a non-negative number.');\n\t\t}\n\n\t\tif (Number.isNaN(retries)) {\n\t\t\tthrow new TypeError('Expected `retries` to be a valid number or Infinity, got NaN.');\n\t\t}\n\t} else if (retries !== undefined) {\n\t\tthrow new TypeError('Expected `retries` to be a number or Infinity.');\n\t}\n}\n\nfunction validateNumberOption(name, value, {min = 0, allowInfinity = false} = {}) {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'number' || Number.isNaN(value)) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a number${allowInfinity ? ' or Infinity' : ''}.`);\n\t}\n\n\tif (!allowInfinity && !Number.isFinite(value)) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a finite number.`);\n\t}\n\n\tif (value < min) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be \\u2265 ${min}.`);\n\t}\n}\n\nexport class AbortError extends Error {\n\tconstructor(message) {\n\t\tsuper();\n\n\t\tif (message instanceof Error) {\n\t\t\tthis.originalError = message;\n\t\t\t({message} = message);\n\t\t} else {\n\t\t\tthis.originalError = new Error(message);\n\t\t\tthis.originalError.stack = this.stack;\n\t\t}\n\n\t\tthis.name = 'AbortError';\n\t\tthis.message = message;\n\t}\n}\n\nfunction calculateDelay(retriesConsumed, options) {\n\tconst attempt = Math.max(1, retriesConsumed + 1);\n\tconst random = options.randomize ? (Math.random() + 1) : 1;\n\n\tlet timeout = Math.round(random * options.minTimeout * (options.factor ** (attempt - 1)));\n\ttimeout = Math.min(timeout, options.maxTimeout);\n\n\treturn timeout;\n}\n\nfunction calculateRemainingTime(start, max) {\n\tif (!Number.isFinite(max)) {\n\t\treturn max;\n\t}\n\n\treturn max - (performance.now() - start);\n}\n\nasync function onAttemptFailure({error, attemptNumber, retriesConsumed, startTime, options}) {\n\tconst normalizedError = error instanceof Error\n\t\t? error\n\t\t: new TypeError(`Non-error was thrown: \"${error}\". You should only throw errors.`);\n\n\tif (normalizedError instanceof AbortError) {\n\t\tthrow normalizedError.originalError;\n\t}\n\n\tconst retriesLeft = Number.isFinite(options.retries)\n\t\t? Math.max(0, options.retries - retriesConsumed)\n\t\t: options.retries;\n\n\tconst maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;\n\n\tconst context = Object.freeze({\n\t\terror: normalizedError,\n\t\tattemptNumber,\n\t\tretriesLeft,\n\t\tretriesConsumed,\n\t});\n\n\tawait options.onFailedAttempt(context);\n\n\tif (calculateRemainingTime(startTime, maxRetryTime) <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tconst consumeRetry = await options.shouldConsumeRetry(context);\n\n\tconst remainingTime = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTime <= 0 || retriesLeft <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) {\n\t\tif (consumeRetry) {\n\t\t\tthrow normalizedError;\n\t\t}\n\n\t\toptions.signal?.throwIfAborted();\n\t\treturn false;\n\t}\n\n\tif (!await options.shouldRetry(context)) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (!consumeRetry) {\n\t\toptions.signal?.throwIfAborted();\n\t\treturn false;\n\t}\n\n\tconst delayTime = calculateDelay(retriesConsumed, options);\n\tconst finalDelay = Math.min(delayTime, remainingTime);\n\n\toptions.signal?.throwIfAborted();\n\n\tif (finalDelay > 0) {\n\t\tawait new Promise((resolve, reject) => {\n\t\t\tconst onAbort = () => {\n\t\t\t\tclearTimeout(timeoutToken);\n\t\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t\t\treject(options.signal.reason);\n\t\t\t};\n\n\t\t\tconst timeoutToken = setTimeout(() => {\n\t\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t\t\tresolve();\n\t\t\t}, finalDelay);\n\n\t\t\tif (options.unref) {\n\t\t\t\ttimeoutToken.unref?.();\n\t\t\t}\n\n\t\t\toptions.signal?.addEventListener('abort', onAbort, {once: true});\n\t\t});\n\t}\n\n\toptions.signal?.throwIfAborted();\n\n\treturn true;\n}\n\nexport default async function pRetry(input, options = {}) {\n\toptions = {...options};\n\n\tvalidateRetries(options.retries);\n\n\tif (Object.hasOwn(options, 'forever')) {\n\t\tthrow new Error('The `forever` option is no longer supported. For many use-cases, you can set `retries: Infinity` instead.');\n\t}\n\n\toptions.retries ??= 10;\n\toptions.factor ??= 2;\n\toptions.minTimeout ??= 1000;\n\toptions.maxTimeout ??= Number.POSITIVE_INFINITY;\n\toptions.maxRetryTime ??= Number.POSITIVE_INFINITY;\n\toptions.randomize ??= false;\n\toptions.onFailedAttempt ??= () => {};\n\toptions.shouldRetry ??= () => true;\n\toptions.shouldConsumeRetry ??= () => true;\n\n\t// Validate numeric options and normalize edge cases\n\tvalidateNumberOption('factor', options.factor, {min: 0, allowInfinity: false});\n\tvalidateNumberOption('minTimeout', options.minTimeout, {min: 0, allowInfinity: false});\n\tvalidateNumberOption('maxTimeout', options.maxTimeout, {min: 0, allowInfinity: true});\n\tvalidateNumberOption('maxRetryTime', options.maxRetryTime, {min: 0, allowInfinity: true});\n\n\t// Treat non-positive factor as 1 to avoid zero backoff or negative behavior\n\tif (!(options.factor > 0)) {\n\t\toptions.factor = 1;\n\t}\n\n\toptions.signal?.throwIfAborted();\n\n\tlet attemptNumber = 0;\n\tlet retriesConsumed = 0;\n\tconst startTime = performance.now();\n\n\twhile (Number.isFinite(options.retries) ? retriesConsumed <= options.retries : true) {\n\t\tattemptNumber++;\n\n\t\ttry {\n\t\t\toptions.signal?.throwIfAborted();\n\n\t\t\tconst result = await input(attemptNumber);\n\n\t\t\toptions.signal?.throwIfAborted();\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (await onAttemptFailure({\n\t\t\t\terror,\n\t\t\t\tattemptNumber,\n\t\t\t\tretriesConsumed,\n\t\t\t\tstartTime,\n\t\t\t\toptions,\n\t\t\t})) {\n\t\t\t\tretriesConsumed++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Should not reach here, but in case it does, throw an error\n\tthrow new Error('Retry attempts exhausted without throwing an error.');\n}\n\nexport function makeRetriable(function_, options) {\n\treturn function (...arguments_) {\n\t\treturn pRetry(() => function_.apply(this, arguments_), options);\n\t};\n}\n","import { type EmbeddingProvider, type CustomProviderConfig, type BaseModelInfo, type EmbeddingProviderModelInfo, getDefaultModelForProvider, isValidModel, autoDetectProviders, EmbeddingModelName, EMBEDDING_MODELS } from \"../config\";\nimport { existsSync, readFileSync } from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\n\nexport interface ProviderCredentials {\n provider: EmbeddingProvider | 'custom';\n apiKey?: string;\n baseUrl?: string;\n refreshToken?: string;\n accessToken?: string;\n tokenExpires?: number;\n}\n\nexport interface CustomModelInfo extends BaseModelInfo {\n provider: 'custom';\n timeoutMs: number;\n maxBatchSize?: number;\n}\n\nexport type ConfiguredProviderInfo = {\n [P in EmbeddingProvider]: {\n provider: P;\n credentials: ProviderCredentials;\n modelInfo: EmbeddingProviderModelInfo[P];\n }\n}[EmbeddingProvider] | {\n provider: 'custom';\n credentials: ProviderCredentials;\n modelInfo: CustomModelInfo;\n}\n\ninterface OpenCodeAuthAPI {\n type: \"api\";\n key: string;\n}\n\ntype OpenCodeAuth = OpenCodeAuthAPI;\n\nfunction getOpenCodeAuthPath(): string {\n return path.join(os.homedir(), \".local\", \"share\", \"opencode\", \"auth.json\");\n}\n\nfunction loadOpenCodeAuth(): Record<string, OpenCodeAuth> {\n const authPath = getOpenCodeAuthPath();\n try {\n if (existsSync(authPath)) {\n return JSON.parse(readFileSync(authPath, \"utf-8\"));\n }\n } catch {\n // Ignore auth file read errors\n }\n return {};\n}\n\nexport async function detectEmbeddingProvider(\n preferredProvider: EmbeddingProvider, model?: EmbeddingModelName\n): Promise<ConfiguredProviderInfo> {\n if (preferredProvider === \"ollama\") {\n return detectOllamaProvider(model);\n }\n\n const credentials = await getProviderCredentials(preferredProvider);\n if (credentials) {\n if (!model) {\n return {\n provider: preferredProvider,\n credentials,\n modelInfo: getDefaultModelForProvider(preferredProvider),\n } as ConfiguredProviderInfo;\n }\n if (!isValidModel(model, preferredProvider)) {\n throw new Error(\n `Model '${model}' is not supported by provider '${preferredProvider}'`\n );\n }\n const providerModels = EMBEDDING_MODELS[preferredProvider];\n const modelInfo = Object.values(providerModels).find((candidate) => candidate.model === model);\n if (!modelInfo) {\n throw new Error(\n `Model '${model}' is not supported by provider '${preferredProvider}'`\n );\n }\n return {\n provider: preferredProvider,\n credentials,\n modelInfo,\n } as ConfiguredProviderInfo;\n }\n throw new Error(\n `Preferred provider '${preferredProvider}' is not configured or authenticated`\n );\n}\n\nexport async function tryDetectProvider(): Promise<ConfiguredProviderInfo> {\n for (const provider of autoDetectProviders) {\n if (provider === \"ollama\") {\n const ollamaProvider = await tryDetectOllamaProvider();\n if (ollamaProvider) {\n return ollamaProvider;\n }\n continue;\n }\n\n const credentials = await getProviderCredentials(provider);\n if (credentials) {\n return {\n provider,\n credentials,\n modelInfo: getDefaultModelForProvider(provider),\n } as ConfiguredProviderInfo;\n }\n }\n\n throw new Error(\n `No embedding-capable provider found. Please authenticate with OpenCode using one of: ${autoDetectProviders.join(\", \")}.`\n );\n}\n\nasync function getProviderCredentials(\n provider: EmbeddingProvider\n): Promise<ProviderCredentials | null> {\n switch (provider) {\n case \"openai\":\n return getOpenAICredentials();\n case \"google\":\n return getGoogleCredentials();\n case \"ollama\":\n return getOllamaCredentials();\n default:\n return null;\n }\n}\n\n\nfunction getOpenAICredentials(): ProviderCredentials | null {\n const authData = loadOpenCodeAuth();\n const openaiAuth = authData[\"openai\"];\n\n if (openaiAuth?.type === \"api\") {\n return {\n provider: \"openai\",\n apiKey: openaiAuth.key,\n baseUrl: \"https://api.openai.com/v1\",\n };\n }\n\n return null;\n}\n\nfunction getGoogleCredentials(): ProviderCredentials | null {\n const authData = loadOpenCodeAuth();\n const googleAuth = authData[\"google\"] || authData[\"google-generative-ai\"];\n\n if (googleAuth?.type === \"api\") {\n return {\n provider: \"google\",\n apiKey: googleAuth.key,\n baseUrl: \"https://generativelanguage.googleapis.com/v1beta\",\n };\n }\n\n return null;\n}\n\nasync function fetchOllama(url: string, init?: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 2000);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\nasync function getOllamaCredentials(): Promise<ProviderCredentials | null> {\n const baseUrl = (process.env.OLLAMA_HOST || \"http://localhost:11434\").replace(/\\/+$/, \"\");\n\n try {\n const response = await fetchOllama(`${baseUrl}/api/tags`);\n\n if (response.ok) {\n return {\n provider: \"ollama\",\n baseUrl,\n };\n }\n } catch {\n return null;\n }\n\n return null;\n}\n\ninterface OllamaTagsResponse {\n models?: Array<{ name?: string; model?: string }>;\n}\n\ninterface OllamaShowResponse {\n capabilities?: string[];\n model_info?: Record<string, unknown>;\n}\n\nfunction findCatalogOllamaModel(\n model: string,\n): EmbeddingProviderModelInfo[\"ollama\"] | null {\n const stableName = model.endsWith(\":latest\")\n ? model.slice(0, -\":latest\".length)\n : model;\n return Object.values(EMBEDDING_MODELS.ollama)\n .find((candidate) => candidate.model === stableName) ?? null;\n}\n\nfunction getPositiveIntegerMetadata(\n modelInfo: Record<string, unknown>,\n suffix: string,\n): number | null {\n const values = Object.entries(modelInfo)\n .filter(([key]) => key.endsWith(suffix))\n .map(([, value]) => value)\n .filter((value): value is number => typeof value === \"number\" && Number.isInteger(value) && value > 0);\n\n return values.length === 1 ? values[0] : null;\n}\n\nasync function fetchOllamaModelInfo(\n credentials: ProviderCredentials,\n model: string,\n): Promise<EmbeddingProviderModelInfo[\"ollama\"] | null> {\n const response = await fetchOllama(`${credentials.baseUrl}/api/show`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ model }),\n });\n if (!response.ok) {\n return null;\n }\n\n const data = await response.json() as OllamaShowResponse;\n if (!data.capabilities?.includes(\"embedding\") || !data.model_info) {\n return null;\n }\n\n const dimensions = getPositiveIntegerMetadata(data.model_info, \".embedding_length\");\n const maxTokens = getPositiveIntegerMetadata(data.model_info, \".context_length\");\n if (!dimensions || !maxTokens) {\n return null;\n }\n\n return {\n provider: \"ollama\",\n model,\n dimensions,\n maxTokens,\n costPer1MTokens: 0,\n };\n}\n\nasync function listOllamaModels(credentials: ProviderCredentials): Promise<string[]> {\n const response = await fetchOllama(`${credentials.baseUrl}/api/tags`);\n if (!response.ok) {\n return [];\n }\n\n const data = await response.json() as OllamaTagsResponse;\n return [...new Set((data.models ?? [])\n .map((entry) => entry.name ?? entry.model)\n .filter((name): name is string => typeof name === \"string\" && name.trim().length > 0))];\n}\n\nasync function detectOllamaProvider(model?: string): Promise<ConfiguredProviderInfo> {\n const credentials = await getOllamaCredentials();\n if (!credentials) {\n throw new Error(\"Preferred provider 'ollama' is not configured or authenticated\");\n }\n\n const requestedModel = model?.trim();\n if (requestedModel) {\n const catalogModel = findCatalogOllamaModel(requestedModel);\n if (catalogModel) {\n return { provider: \"ollama\", credentials, modelInfo: catalogModel };\n }\n }\n\n const candidates = requestedModel\n ? [requestedModel]\n : await listOllamaModels(credentials);\n for (const candidate of candidates) {\n const modelInfo = await fetchOllamaModelInfo(credentials, candidate);\n if (modelInfo) {\n return {\n provider: \"ollama\",\n credentials,\n modelInfo: findCatalogOllamaModel(candidate) ?? modelInfo,\n };\n }\n }\n\n const detail = model\n ? `Model '${model}' is not installed or is not embedding-capable`\n : \"No installed embedding-capable Ollama model was found\";\n throw new Error(detail);\n}\n\nasync function tryDetectOllamaProvider(): Promise<ConfiguredProviderInfo | null> {\n try {\n return await detectOllamaProvider();\n } catch {\n return null;\n }\n}\n\nexport function getProviderDisplayName(provider: EmbeddingProvider | 'custom'): string {\n switch (provider) {\n case \"openai\":\n return \"OpenAI\";\n case \"google\":\n return \"Google (Gemini)\";\n case \"ollama\":\n return \"Ollama (Local)\";\n case \"custom\":\n return \"Custom (OpenAI-compatible)\";\n default:\n return provider;\n }\n}\n\nexport function createCustomProviderInfo(config: CustomProviderConfig): ConfiguredProviderInfo {\n // Normalize baseUrl defensively — parseConfig() already strips trailing slashes,\n // but direct callers (e.g. tests) may pass unnormalized URLs.\n const baseUrl = config.baseUrl.replace(/\\/+$/, '');\n return {\n provider: 'custom',\n credentials: {\n provider: 'custom',\n baseUrl,\n apiKey: config.apiKey,\n },\n modelInfo: {\n provider: 'custom',\n model: config.model,\n dimensions: config.dimensions,\n maxTokens: config.maxTokens ?? 8192,\n costPer1MTokens: 0,\n timeoutMs: config.timeoutMs ?? 30_000,\n maxBatchSize: config.maxBatchSize,\n },\n };\n}\n","import { type BaseModelInfo } from \"../config/schema.js\";\n\nimport { type ProviderCredentials } from \"./detector.js\";\n\nexport interface EmbeddingResult {\n embedding: number[];\n tokensUsed: number;\n}\n\nexport interface EmbeddingBatchResult {\n embeddings: number[][];\n totalTokensUsed: number;\n}\n\nexport interface EmbeddingProviderInterface {\n embedQuery(query: string): Promise<EmbeddingResult>;\n embedDocument(document: string): Promise<EmbeddingResult>;\n embedBatch(texts: string[]): Promise<EmbeddingBatchResult>;\n getModelInfo(): BaseModelInfo;\n}\n\nexport abstract class BaseEmbeddingProvider<TModelInfo extends BaseModelInfo>\n implements EmbeddingProviderInterface {\n public constructor(\n protected readonly credentials: ProviderCredentials,\n protected readonly modelInfo: TModelInfo\n ) { }\n\n public async embedQuery(query: string): Promise<EmbeddingResult> {\n const result = await this.embedBatch([query]);\n return {\n embedding: result.embeddings[0],\n tokensUsed: result.totalTokensUsed,\n };\n }\n\n public async embedDocument(document: string): Promise<EmbeddingResult> {\n const result = await this.embedBatch([document]);\n return {\n embedding: result.embeddings[0],\n tokensUsed: result.totalTokensUsed,\n };\n }\n\n public getModelInfo(): TModelInfo {\n return this.modelInfo;\n }\n\n public abstract embedBatch(texts: string[]): Promise<EmbeddingBatchResult>;\n}\n\n/**\n * Thrown by CustomEmbeddingProvider for HTTP 4xx errors (except 429 rate limit).\n * The Indexer's pRetry config uses instanceof to bail immediately on these errors\n * instead of retrying — preventing long retry loops on bad API keys or invalid models.\n */\nexport class CustomProviderNonRetryableError extends Error {\n public constructor(message: string) {\n super(message);\n this.name = \"CustomProviderNonRetryableError\";\n }\n}\n","/**\n * URL validation utilities to prevent SSRF attacks against cloud metadata services.\n *\n * IMPORTANT: This intentionally allows localhost and private IPs because the custom\n * embedding provider is commonly used with local servers (Ollama, llama.cpp, vLLM,\n * text-embeddings-inference). The threat model is a malicious committed config file\n * targeting cloud metadata endpoints, not blocking legitimate local usage.\n *\n * KNOWN LIMITATION: This validates the hostname string only, not the resolved IP.\n * A DNS rebinding attack (hostname that resolves to 169.254.169.254) bypasses this\n * check. Full mitigation would require DNS resolution pinning (resolve → check IP →\n * connect), which needs a custom HTTP agent. Acceptable for now given the local-only\n * threat model and the low likelihood of DNS rebinding in committed config files.\n */\n\n/** Cloud metadata service IPs and hostnames that should never be contacted. */\nconst BLOCKED_METADATA_IPS = [\n /^169\\.254\\.169\\.254$/, // AWS/Azure/GCP metadata\n /^169\\.254\\.170\\.2$/, // AWS ECS task metadata\n /^fd00:ec2::254$/, // AWS IMDSv2 IPv6\n];\n\nconst BLOCKED_HOSTNAMES = new Set([\n \"metadata.google.internal\",\n \"metadata.google\",\n \"metadata.goog\",\n \"kubernetes.default.svc\",\n]);\n\nexport interface UrlValidationResult {\n valid: boolean;\n reason?: string;\n}\n\n/**\n * Validates that a URL does not point to cloud metadata services or use dangerous protocols.\n * Allows localhost and private IPs for local embedding servers.\n * Returns { valid: true } if the URL is safe, or { valid: false, reason } if blocked.\n */\nexport function validateExternalUrl(urlString: string): UrlValidationResult {\n let parsed: URL;\n try {\n parsed = new URL(urlString);\n } catch {\n return { valid: false, reason: `Invalid URL: ${sanitizeUrlForError(urlString)}` };\n }\n\n // Block non-HTTP protocols (file://, gopher://, ftp://, etc.)\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return { valid: false, reason: `Blocked protocol: ${parsed.protocol}` };\n }\n\n const hostname = parsed.hostname.toLowerCase();\n\n // Block known cloud metadata hostnames\n if (BLOCKED_HOSTNAMES.has(hostname)) {\n return { valid: false, reason: `Blocked: cloud metadata service (${hostname})` };\n }\n\n // Block cloud metadata IPs\n for (const pattern of BLOCKED_METADATA_IPS) {\n if (pattern.test(hostname)) {\n return { valid: false, reason: `Blocked: cloud metadata IP (${hostname})` };\n }\n }\n\n // Block link-local range (169.254.x.x) — used exclusively for metadata/APIPA, not user servers\n if (/^169\\.254\\./.test(hostname)) {\n return { valid: false, reason: `Blocked: link-local address (${hostname})` };\n }\n\n return { valid: true };\n}\n\n/**\n * Strips credentials and sensitive parts from a URL for safe inclusion in error messages.\n */\nexport function sanitizeUrlForError(url: string): string {\n try {\n const parsed = new URL(url);\n // Remove username:password from URL\n parsed.username = \"\";\n parsed.password = \"\";\n return parsed.toString();\n } catch {\n // If URL can't be parsed, truncate and mask\n const maxLen = 80;\n if (url.length > maxLen) {\n return url.slice(0, maxLen) + \"...\";\n }\n return url;\n }\n}\n","import { type CustomModelInfo, type ProviderCredentials } from \"../detector.js\";\nimport {\n BaseEmbeddingProvider,\n CustomProviderNonRetryableError,\n type EmbeddingBatchResult,\n} from \"../provider-types.js\";\nimport { sanitizeUrlForError, validateExternalUrl } from \"../../utils/url-validation.js\";\n\nexport class CustomEmbeddingProvider extends BaseEmbeddingProvider<CustomModelInfo> {\n public constructor(credentials: ProviderCredentials, modelInfo: CustomModelInfo) {\n super(credentials, modelInfo);\n }\n\n private splitIntoRequestBatches(texts: string[]): string[][] {\n const maxBatchSize = this.modelInfo.maxBatchSize;\n\n if (!maxBatchSize || texts.length <= maxBatchSize) {\n return [texts];\n }\n\n const batches: string[][] = [];\n for (let i = 0; i < texts.length; i += maxBatchSize) {\n batches.push(texts.slice(i, i + maxBatchSize));\n }\n return batches;\n }\n\n private async embedRequest(texts: string[]): Promise<EmbeddingBatchResult> {\n if (texts.length === 0) {\n return {\n embeddings: [],\n totalTokensUsed: 0,\n };\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.credentials.apiKey) {\n headers.Authorization = `Bearer ${this.credentials.apiKey}`;\n }\n\n const baseUrl = this.credentials.baseUrl ?? \"\";\n const fullUrl = `${baseUrl}/embeddings`;\n\n const urlCheck = validateExternalUrl(fullUrl);\n if (!urlCheck.valid) {\n throw new CustomProviderNonRetryableError(\n `Custom embedding provider URL blocked (SSRF protection): ${urlCheck.reason}`\n );\n }\n\n const timeoutMs = this.modelInfo.timeoutMs;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n let response: Response;\n try {\n response = await fetch(fullUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n model: this.modelInfo.model,\n input: texts,\n }),\n signal: controller.signal,\n });\n } catch (error: unknown) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(`Custom embedding API request timed out after ${timeoutMs}ms for ${sanitizeUrlForError(fullUrl)}`);\n }\n throw error;\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n const errorText = (await response.text()).slice(0, 500);\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n throw new CustomProviderNonRetryableError(`Custom embedding API error (non-retryable): ${response.status} - ${errorText}`);\n }\n throw new Error(`Custom embedding API error: ${response.status} - ${errorText}`);\n }\n\n const data = await response.json() as {\n data?: Array<{ embedding: number[] }>;\n usage?: { total_tokens: number };\n };\n\n if (data.data && Array.isArray(data.data)) {\n if (data.data.length > 0) {\n const actualDims = data.data[0].embedding.length;\n if (actualDims !== this.modelInfo.dimensions) {\n throw new Error(\n `Dimension mismatch: customProvider.dimensions is ${this.modelInfo.dimensions}, ` +\n `but the API returned vectors with ${actualDims} dimensions. ` +\n `Update your config to match the model's actual output dimensions.`\n );\n }\n }\n\n if (data.data.length !== texts.length) {\n throw new Error(\n `Embedding count mismatch: sent ${texts.length} texts but received ${data.data.length} embeddings. ` +\n `The custom embedding server may not support batch input.`\n );\n }\n\n return {\n embeddings: data.data.map((d) => d.embedding),\n totalTokensUsed: data.usage?.total_tokens ?? texts.reduce((sum, t) => sum + Math.ceil(t.length / 4), 0),\n };\n }\n\n throw new Error(\"Custom embedding API returned unexpected response format. Expected OpenAI-compatible format with data[].embedding.\");\n }\n\n public async embedBatch(texts: string[]): Promise<EmbeddingBatchResult> {\n const requestBatches = this.splitIntoRequestBatches(texts);\n const embeddings: number[][] = [];\n let totalTokensUsed = 0;\n\n for (const batch of requestBatches) {\n const result = await this.embedRequest(batch);\n embeddings.push(...result.embeddings);\n totalTokensUsed += result.totalTokensUsed;\n }\n\n return {\n embeddings,\n totalTokensUsed,\n };\n }\n}\n","import { type EmbeddingProviderModelInfo } from \"../../config/schema.js\";\n\nimport { type ProviderCredentials } from \"../detector.js\";\nimport {\n BaseEmbeddingProvider,\n type EmbeddingBatchResult,\n type EmbeddingResult,\n} from \"../provider-types.js\";\n\nexport class GoogleEmbeddingProvider extends BaseEmbeddingProvider<EmbeddingProviderModelInfo[\"google\"]> {\n private static readonly BATCH_SIZE = 20;\n\n public constructor(\n credentials: ProviderCredentials,\n modelInfo: EmbeddingProviderModelInfo[\"google\"]\n ) {\n super(credentials, modelInfo);\n }\n\n public async embedQuery(query: string): Promise<EmbeddingResult> {\n const taskType = this.modelInfo.model === \"gemini-embedding-001\" && this.modelInfo.taskAble\n ? \"CODE_RETRIEVAL_QUERY\"\n : undefined;\n const texts = [\n this.modelInfo.model === \"gemini-embedding-2\"\n ? `task: code retrieval | query: ${query}`\n : query,\n ];\n const result = await this.embedWithTaskType(texts, taskType);\n return {\n embedding: result.embeddings[0],\n tokensUsed: result.totalTokensUsed,\n };\n }\n\n public async embedDocument(document: string): Promise<EmbeddingResult> {\n const taskType = this.modelInfo.model === \"gemini-embedding-001\" && this.modelInfo.taskAble\n ? \"RETRIEVAL_DOCUMENT\"\n : undefined;\n const result = await this.embedWithTaskType([\n this.modelInfo.model === \"gemini-embedding-2\" ? `title: none | text: ${document}` : document,\n ], taskType);\n return {\n embedding: result.embeddings[0],\n tokensUsed: result.totalTokensUsed,\n };\n }\n\n public async embedBatch(texts: string[]): Promise<EmbeddingBatchResult> {\n const taskType = this.modelInfo.model === \"gemini-embedding-001\" && this.modelInfo.taskAble\n ? \"RETRIEVAL_DOCUMENT\"\n : undefined;\n const formattedTexts = this.modelInfo.model === \"gemini-embedding-2\"\n ? texts.map((text) => `title: none | text: ${text}`)\n : texts;\n\n return this.embedWithTaskType(formattedTexts, taskType);\n }\n\n private async embedWithTaskType(\n texts: string[],\n taskType?: string\n ): Promise<EmbeddingBatchResult> {\n const batches: string[][] = [];\n for (let i = 0; i < texts.length; i += GoogleEmbeddingProvider.BATCH_SIZE) {\n batches.push(texts.slice(i, i + GoogleEmbeddingProvider.BATCH_SIZE));\n }\n\n const batchResults = await Promise.all(\n batches.map(async (batch) => {\n const requests = batch.map((text) => ({\n model: `models/${this.modelInfo.model}`,\n content: {\n parts: [{ text }],\n },\n taskType,\n outputDimensionality: this.modelInfo.dimensions,\n }));\n\n const response = await fetch(\n `${this.credentials.baseUrl}/models/${this.modelInfo.model}:batchEmbedContents`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(this.credentials.apiKey && { \"x-goog-api-key\": this.credentials.apiKey }),\n },\n body: JSON.stringify({ requests }),\n }\n );\n\n if (!response.ok) {\n const error = (await response.text()).slice(0, 500);\n throw new Error(`Google embedding API error: ${response.status} - ${error}`);\n }\n\n const data = (await response.json()) as {\n embeddings: Array<{ values: number[] }>;\n };\n\n return {\n embeddings: data.embeddings.map((e) => e.values),\n tokensUsed: batch.reduce((sum, text) => sum + Math.ceil(text.length / 4), 0),\n };\n })\n );\n\n return {\n embeddings: batchResults.flatMap((r) => r.embeddings),\n totalTokensUsed: batchResults.reduce((sum, r) => sum + r.tokensUsed, 0),\n };\n }\n}\n","import { type EmbeddingProviderModelInfo } from \"../../config/schema.js\";\n\nimport { type ProviderCredentials } from \"../detector.js\";\nimport { BaseEmbeddingProvider, type EmbeddingBatchResult } from \"../provider-types.js\";\n\nexport class OllamaEmbeddingProvider extends BaseEmbeddingProvider<EmbeddingProviderModelInfo[\"ollama\"]> {\n private static readonly MIN_TRUNCATION_CHARS = 512;\n private static readonly REQUEST_TIMEOUT_MS = 120_000;\n\n // Set when /api/embed returns 404 so subsequent multi-text batches skip the\n // batched endpoint and go straight to the legacy per-text path (one probe per\n // old ollama install, not one probe per batch).\n private batchEndpointUnavailable = false;\n\n public constructor(\n credentials: ProviderCredentials,\n modelInfo: EmbeddingProviderModelInfo[\"ollama\"]\n ) {\n super(credentials, modelInfo);\n }\n\n private estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n }\n\n private truncateToCharLimit(text: string, maxChars: number): string {\n if (text.length <= maxChars) {\n return text;\n }\n\n return `${text.slice(0, Math.max(0, maxChars - 17))}\\n... [truncated]`;\n }\n\n private isContextLengthError(error: unknown): boolean {\n const message = (error instanceof Error ? error.message : String(error)).toLowerCase();\n return (message.includes(\"context length\") && (message.includes(\"exceed\") || message.includes(\"exceeded\") || message.includes(\"too long\")))\n || message.includes(\"input length exceeds the context length\")\n || message.includes(\"context length exceeded\");\n }\n\n // True for a 404 from the newer /api/embed endpoint, i.e. an ollama version that\n // does not provide it. embedBatch uses this to fall back to the legacy per-text\n // /api/embeddings path so old ollama installs do not regress.\n private isBatchEndpointUnavailableError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"Ollama /api/embed not available\");\n }\n\n // True for a malformed /api/embed response (wrong vector count or a bad vector).\n // embedBatch falls back to the per-text path on this so a bad batch response\n // re-embeds each text cleanly. A text that then fails per-text is not isolated\n // here; it is isolated on the recovery run, which re-embeds one text per request.\n private isBatchValidationError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"invalid embedding batch\");\n }\n\n private buildTruncationCandidates(text: string): string[] {\n const baseMaxChars = Math.max(1, this.modelInfo.maxTokens * 4);\n const candidateLimits = new Set<number>();\n const baselineLimit = text.length > baseMaxChars\n ? baseMaxChars\n : Math.max(\n OllamaEmbeddingProvider.MIN_TRUNCATION_CHARS,\n Math.floor(text.length * 0.9)\n );\n\n if (baselineLimit < text.length) {\n candidateLimits.add(baselineLimit);\n }\n\n for (const factor of [0.75, 0.6, 0.45, 0.35, 0.25]) {\n const scaledLimit = Math.max(\n OllamaEmbeddingProvider.MIN_TRUNCATION_CHARS,\n Math.floor(baselineLimit * factor)\n );\n if (scaledLimit < text.length) {\n candidateLimits.add(scaledLimit);\n }\n }\n\n candidateLimits.add(Math.min(text.length - 1, OllamaEmbeddingProvider.MIN_TRUNCATION_CHARS));\n\n const candidates: string[] = [];\n const seen = new Set<string>();\n for (const limit of [...candidateLimits].sort((a, b) => b - a)) {\n if (limit <= 0 || limit >= text.length) {\n continue;\n }\n\n const truncated = this.truncateToCharLimit(text, limit);\n if (truncated === text || seen.has(truncated)) {\n continue;\n }\n\n seen.add(truncated);\n candidates.push(truncated);\n }\n\n return candidates;\n }\n\n private async embedSingleWithFallback(text: string): Promise<{ embedding: number[]; tokensUsed: number }> {\n try {\n return await this.embedSingle(text);\n } catch (error) {\n if (!this.isContextLengthError(error)) {\n throw error;\n }\n\n let lastError: unknown = error;\n for (const truncated of this.buildTruncationCandidates(text)) {\n try {\n return await this.embedSingle(truncated);\n } catch (retryError) {\n if (!this.isContextLengthError(retryError)) {\n throw retryError;\n }\n lastError = retryError;\n }\n }\n\n throw lastError;\n }\n }\n\n private async embedSingle(text: string): Promise<{ embedding: number[]; tokensUsed: number }> {\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS,\n );\n let response: Response;\n try {\n response = await fetch(`${this.credentials.baseUrl}/api/embeddings`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n model: this.modelInfo.model,\n prompt: text,\n truncate: false,\n }),\n signal: controller.signal,\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(\n `Ollama embedding request timed out after ${OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS}ms`,\n );\n }\n throw error;\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n const error = (await response.text()).slice(0, 500);\n throw new Error(`Ollama embedding API error: ${response.status} - ${error}`);\n }\n\n const data = (await response.json()) as { embedding?: unknown };\n if (\n !Array.isArray(data.embedding)\n || data.embedding.length !== this.modelInfo.dimensions\n || data.embedding.some((value) => typeof value !== \"number\" || !Number.isFinite(value))\n ) {\n throw new Error(\n `Ollama returned an invalid embedding; expected ${this.modelInfo.dimensions} finite dimensions`,\n );\n }\n\n return {\n embedding: data.embedding,\n tokensUsed: this.estimateTokens(text),\n };\n }\n\n // Embeds many texts in one POST /api/embed request (input: string[]). Ollama\n // encodes each input independently, so the model context length applies per input\n // (the upstream splitter already bounds each input), not over the batch. This\n // amortizes N HTTP round-trips into one.\n private async embedMany(texts: string[]): Promise<EmbeddingBatchResult> {\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS,\n );\n let response: Response;\n try {\n response = await fetch(`${this.credentials.baseUrl}/api/embed`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n model: this.modelInfo.model,\n input: texts,\n truncate: false,\n }),\n signal: controller.signal,\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(\n `Ollama embedding request timed out after ${OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS}ms`,\n );\n }\n throw error;\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n const error = (await response.text()).slice(0, 500);\n if (response.status === 404) {\n throw new Error(`Ollama /api/embed not available: ${response.status} - ${error}`);\n }\n throw new Error(`Ollama embedding API error: ${response.status} - ${error}`);\n }\n\n let parsed: unknown;\n try {\n parsed = await response.json();\n } catch {\n // Invalid JSON (e.g. an empty or truncated 200 body) -> treat as a malformed\n // batch so embedBatch falls back to the per-text path instead of propagating\n // a parse error that skips the fallback.\n throw new Error(\n `Ollama returned an invalid embedding batch; expected ${texts.length} vectors of ${this.modelInfo.dimensions} finite dimensions`,\n );\n }\n const data = (parsed && typeof parsed === \"object\" ? parsed : {}) as { embeddings?: unknown };\n if (\n !Array.isArray(data.embeddings)\n || data.embeddings.length !== texts.length\n || data.embeddings.some(\n (value) =>\n !Array.isArray(value)\n || value.length !== this.modelInfo.dimensions\n || value.some((v) => typeof v !== \"number\" || !Number.isFinite(v)),\n )\n ) {\n throw new Error(\n `Ollama returned an invalid embedding batch; expected ${texts.length} vectors of ${this.modelInfo.dimensions} finite dimensions`,\n );\n }\n\n return {\n embeddings: data.embeddings,\n totalTokensUsed: texts.reduce((sum, text) => sum + this.estimateTokens(text), 0),\n };\n }\n\n // Per-text /api/embeddings path shared by the single-text fast path and the\n // batch fallback. Uses the legacy endpoint one text at a time, so each text gets\n // its own truncation safety net and a vector validated on its own. A text that\n // hard-fails per-text throws here and fails the whole request batch; the recovery\n // run re-embeds one text per request to isolate it.\n private async embedOneByOne(texts: string[]): Promise<EmbeddingBatchResult> {\n const results: Array<{ embedding: number[]; tokensUsed: number }> = [];\n for (const text of texts) {\n results.push(await this.embedSingleWithFallback(text));\n }\n\n return {\n embeddings: results.map((r) => r.embedding),\n totalTokensUsed: results.reduce((sum, r) => sum + r.tokensUsed, 0),\n };\n }\n\n public async embedBatch(texts: string[]): Promise<EmbeddingBatchResult> {\n if (texts.length === 0) {\n return { embeddings: [], totalTokensUsed: 0 };\n }\n\n // A single-text batch gets no batching benefit; send it to the legacy per-text\n // path directly so its truncation/timeout/error behavior stays unchanged and no\n // /api/embed probe runs. Once /api/embed is known unavailable, multi-text batches\n // also skip the probe (see batchEndpointUnavailable).\n if (texts.length === 1 || this.batchEndpointUnavailable) {\n return this.embedOneByOne(texts);\n }\n\n try {\n return await this.embedMany(texts);\n } catch (error) {\n // Fall back to the per-text /api/embeddings path when the batched endpoint is\n // unavailable (old ollama, 404), a single input overflowed the model context\n // length (per-text truncation net), or the batch response was malformed (so a\n // bad batch response re-embeds each text cleanly). This is not in-run per-text\n // isolation: a text that hard-fails per-text throws and fails the whole request\n // batch, and is isolated only on the recovery run, which re-embeds one text per\n // request. Other errors propagate for the indexer's pRetry to handle.\n if (this.isBatchEndpointUnavailableError(error)) {\n // Old ollama without /api/embed: cache the result so later batches skip the probe.\n this.batchEndpointUnavailable = true;\n return this.embedOneByOne(texts);\n }\n\n if (\n !this.isContextLengthError(error)\n && !this.isBatchValidationError(error)\n ) {\n throw error;\n }\n\n return this.embedOneByOne(texts);\n }\n }\n}\n","import { type EmbeddingProviderModelInfo } from \"../../config/schema.js\";\n\nimport { type ProviderCredentials } from \"../detector.js\";\nimport { BaseEmbeddingProvider, type EmbeddingBatchResult } from \"../provider-types.js\";\n\nexport class OpenAIEmbeddingProvider extends BaseEmbeddingProvider<EmbeddingProviderModelInfo[\"openai\"]> {\n public constructor(\n credentials: ProviderCredentials,\n modelInfo: EmbeddingProviderModelInfo[\"openai\"]\n ) {\n super(credentials, modelInfo);\n }\n\n public async embedBatch(texts: string[]): Promise<EmbeddingBatchResult> {\n const response = await fetch(`${this.credentials.baseUrl}/embeddings`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.credentials.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n model: this.modelInfo.model,\n input: texts,\n }),\n });\n\n if (!response.ok) {\n const error = (await response.text()).slice(0, 500);\n throw new Error(`OpenAI embedding API error: ${response.status} - ${error}`);\n }\n\n const data = await response.json() as {\n data: Array<{ embedding: number[] }>;\n usage: { total_tokens: number };\n };\n\n return {\n embeddings: data.data.map((d) => d.embedding),\n totalTokensUsed: data.usage.total_tokens,\n };\n }\n}\n","import { type ConfiguredProviderInfo } from \"./detector.js\";\nimport { CustomEmbeddingProvider } from \"./providers/custom.js\";\nimport { GoogleEmbeddingProvider } from \"./providers/google.js\";\nimport { OllamaEmbeddingProvider } from \"./providers/ollama.js\";\nimport { OpenAIEmbeddingProvider } from \"./providers/openai.js\";\n\nexport {\n BaseEmbeddingProvider,\n CustomProviderNonRetryableError,\n type EmbeddingBatchResult,\n type EmbeddingProviderInterface,\n type EmbeddingResult,\n} from \"./provider-types.js\";\n\nexport function createEmbeddingProvider(\n configuredProviderInfo: ConfiguredProviderInfo,\n): import(\"./provider-types.js\").EmbeddingProviderInterface {\n switch (configuredProviderInfo.provider) {\n case \"openai\":\n return new OpenAIEmbeddingProvider(configuredProviderInfo.credentials, configuredProviderInfo.modelInfo);\n case \"google\":\n return new GoogleEmbeddingProvider(configuredProviderInfo.credentials, configuredProviderInfo.modelInfo);\n case \"ollama\":\n return new OllamaEmbeddingProvider(configuredProviderInfo.credentials, configuredProviderInfo.modelInfo);\n case \"custom\":\n return new CustomEmbeddingProvider(configuredProviderInfo.credentials, configuredProviderInfo.modelInfo);\n default: {\n const _exhaustive: never = configuredProviderInfo;\n throw new Error(`Unsupported embedding provider: ${(_exhaustive as ConfiguredProviderInfo).provider}`);\n }\n }\n}\n","import { BaseModelInfo } from \"../config/schema.js\";\nimport { getProviderDisplayName, ConfiguredProviderInfo } from \"../embeddings/detector.js\";\n\nexport interface CostEstimate {\n filesCount: number;\n totalSizeBytes: number;\n estimatedChunks: number;\n estimatedTokens: number;\n estimatedCost: number;\n provider: string;\n model: string;\n isFree: boolean;\n}\n\n// Result of a dry-run index_codebase pass: parse the real file set, build the\n// embedding text for every indexable chunk, and sum estimateTokens over those\n// texts without requesting embeddings or writing to the index. Provider\n// detection may still run as part of normal initialization (for ollama this\n// contacts /api/tags and /api/show); no embeddings are requested and no writes\n// occur.\n//\n// The token sum uses the local estimate (estimateTokens = ceil(len/4)). It\n// equals the live \"Tokens used\" counter only for providers that report usage\n// on the same basis (ollama counts ceil(len/4)); for providers that report a\n// server tokenizer count (OpenAI, Gemini, custom) it is only an estimate.\n//\n// For a matching provider and a project-scoped force index, the force pass\n// clears its own cached embeddings, so the live counter climbs to this sum. A\n// force index on a shared global index can reuse cached embeddings from other\n// projects, and an incremental index counts cached chunks that are not\n// re-embedded; in both cases the dry-run value is an upper bound.\nexport interface DryRunEstimate {\n filesCount: number;\n chunksCount: number;\n tokensToEmbed: number;\n}\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nexport function estimateChunksFromFiles(\n files: Array<{ path: string; size: number }>\n): number {\n let totalChunks = 0;\n\n for (const file of files) {\n const avgChunkSize = 400;\n const chunksPerFile = Math.max(1, Math.ceil(file.size / avgChunkSize));\n totalChunks += chunksPerFile;\n }\n\n return totalChunks;\n}\n\nexport function estimateCost(\n estimatedTokens: number,\n modelInfo: BaseModelInfo\n): number {\n return (estimatedTokens / 1_000_000) * modelInfo.costPer1MTokens;\n}\n\nexport function createCostEstimate(\n files: Array<{ path: string; size: number }>,\n provider: ConfiguredProviderInfo\n): CostEstimate {\n const filesCount = files.length;\n const totalSizeBytes = files.reduce((sum, f) => sum + f.size, 0);\n const estimatedChunks = estimateChunksFromFiles(files);\n const avgTokensPerChunk = 150;\n const estimatedTokens = estimatedChunks * avgTokensPerChunk;\n const estimatedCost = estimateCost(estimatedTokens, provider.modelInfo);\n\n return {\n filesCount,\n totalSizeBytes,\n estimatedChunks,\n estimatedTokens,\n estimatedCost,\n provider: getProviderDisplayName(provider.provider),\n model: provider.modelInfo.model,\n isFree: provider.modelInfo.costPer1MTokens === 0,\n };\n}\n\nexport function formatCostEstimate(estimate: CostEstimate): string {\n const sizeFormatted = formatBytes(estimate.totalSizeBytes);\n const filesFormatted = `${estimate.filesCount.toLocaleString()} files`;\n const costFormatted = estimate.isFree\n ? \"Free\"\n : `~$${estimate.estimatedCost.toFixed(4)}`;\n\n return `\n┌─────────────────────────────────────────────────────────────────┐\n│ 📊 Indexing Estimate │\n├─────────────────────────────────────────────────────────────────┤\n│ │\n│ Files to index: ${filesFormatted.padEnd(40)}│\n│ Total size: ${sizeFormatted.padEnd(40)}│\n│ Estimated chunks: ${(\"~\" + estimate.estimatedChunks.toLocaleString() + \" chunks\").padEnd(40)}│\n│ Estimated tokens: ${(\"~\" + estimate.estimatedTokens.toLocaleString() + \" tokens\").padEnd(40)}│\n│ │\n│ Provider: ${estimate.provider.padEnd(52)}│\n│ Model: ${estimate.model.padEnd(52)}│\n│ Cost: ${costFormatted.padEnd(52)}│\n│ │\n└─────────────────────────────────────────────────────────────────┘\n`;\n}\n\nexport function formatDryRunEstimate(estimate: DryRunEstimate): string {\n return `Dry run: parsed the file set to measure the embedding workload. No embedding requests were made and the index was not changed.\n\n Files to embed: ${estimate.filesCount.toLocaleString()}\n Chunks to embed: ${estimate.chunksCount.toLocaleString()}\n Tokens to embed: ${estimate.tokensToEmbed.toLocaleString()}\n\nThe \"Tokens to embed\" value uses the local estimateTokens(text) = ceil(len/4). It\nmatches the live \"Tokens used\" counter only for providers that report usage on the\nsame basis (ollama); for providers that report a server tokenizer count (OpenAI,\nGemini, custom) it is only an estimate.\n\nFor a matching provider and a project-scoped force index, the force pass clears its\nown cached embeddings, so the live counter climbs to this number. A force index on a\nshared global index can reuse cached embeddings from other projects, and an\nincremental index counts cached chunks that are not re-embedded; in both cases this\nnumber is an upper bound on the live counter, so a progress percent against this\ntotal tops out below 100%.\n`;\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + sizes[i];\n}\n\n\nexport interface ConfirmationResult {\n confirmed: boolean;\n rememberChoice: boolean;\n}\n\nexport function formatConfirmationPrompt(): string {\n return `\nProceed with indexing? [Y/n/always]\n\n Y - Index now\n n - Cancel\n always - Index now and don't ask again for this project\n`;\n}\n\nexport function parseConfirmationResponse(response: string): ConfirmationResult {\n const normalized = response.toLowerCase().trim();\n\n if (normalized === \"\" || normalized === \"y\" || normalized === \"yes\") {\n return { confirmed: true, rememberChoice: false };\n }\n\n if (normalized === \"always\" || normalized === \"a\") {\n return { confirmed: true, rememberChoice: true };\n }\n\n return { confirmed: false, rememberChoice: false };\n}\n","import type { DebugConfig, LogLevel } from \"../config/schema.js\";\n\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n};\n\nexport interface Metrics {\n indexingStartTime?: number;\n indexingEndTime?: number;\n filesScanned: number;\n filesParsed: number;\n parseMs: number;\n chunksProcessed: number;\n chunksEmbedded: number;\n chunksFromCache: number;\n chunksRemoved: number;\n embeddingApiCalls: number;\n embeddingTokensUsed: number;\n embeddingErrors: number;\n \n searchCount: number;\n searchTotalMs: number;\n searchAvgMs: number;\n searchLastMs: number;\n embeddingCallMs: number;\n vectorSearchMs: number;\n keywordSearchMs: number;\n fusionMs: number;\n \n cacheHits: number;\n cacheMisses: number;\n \n queryCacheHits: number;\n queryCacheSimilarHits: number;\n queryCacheMisses: number;\n \n gcRuns: number;\n gcOrphansRemoved: number;\n gcChunksRemoved: number;\n gcEmbeddingsRemoved: number;\n}\n\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n category: string;\n message: string;\n data?: Record<string, unknown>;\n}\n\nfunction createEmptyMetrics(): Metrics {\n return {\n filesScanned: 0,\n filesParsed: 0,\n parseMs: 0,\n chunksProcessed: 0,\n chunksEmbedded: 0,\n chunksFromCache: 0,\n chunksRemoved: 0,\n embeddingApiCalls: 0,\n embeddingTokensUsed: 0,\n embeddingErrors: 0,\n searchCount: 0,\n searchTotalMs: 0,\n searchAvgMs: 0,\n searchLastMs: 0,\n embeddingCallMs: 0,\n vectorSearchMs: 0,\n keywordSearchMs: 0,\n fusionMs: 0,\n cacheHits: 0,\n cacheMisses: 0,\n queryCacheHits: 0,\n queryCacheSimilarHits: 0,\n queryCacheMisses: 0,\n gcRuns: 0,\n gcOrphansRemoved: 0,\n gcChunksRemoved: 0,\n gcEmbeddingsRemoved: 0,\n };\n}\n\nexport class Logger {\n private config: DebugConfig;\n private metrics: Metrics;\n private logs: LogEntry[] = [];\n private maxLogs = 1000;\n\n constructor(config: DebugConfig) {\n this.config = config;\n this.metrics = createEmptyMetrics();\n }\n\n private shouldLog(level: LogLevel): boolean {\n if (!this.config.enabled) return false;\n return LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[this.config.logLevel];\n }\n\n private log(level: LogLevel, category: string, message: string, data?: Record<string, unknown>): void {\n if (!this.shouldLog(level)) return;\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n category,\n message,\n data,\n };\n\n this.logs.push(entry);\n if (this.logs.length > this.maxLogs) {\n this.logs.shift();\n }\n }\n\n private withMetrics(fn: () => void): void {\n if (!this.config.metrics) return;\n fn();\n }\n\n search(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (this.config.logSearch) {\n this.log(level, \"search\", message, data);\n }\n }\n\n embedding(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (this.config.logEmbedding) {\n this.log(level, \"embedding\", message, data);\n }\n }\n\n cache(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (this.config.logCache) {\n this.log(level, \"cache\", message, data);\n }\n }\n\n gc(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (this.config.logGc) {\n this.log(level, \"gc\", message, data);\n }\n }\n\n branch(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (this.config.logBranch) {\n this.log(level, \"branch\", message, data);\n }\n }\n\n info(message: string, data?: Record<string, unknown>): void {\n this.log(\"info\", \"general\", message, data);\n }\n\n warn(message: string, data?: Record<string, unknown>): void {\n this.log(\"warn\", \"general\", message, data);\n }\n\n error(message: string, data?: Record<string, unknown>): void {\n this.log(\"error\", \"general\", message, data);\n }\n\n debug(message: string, data?: Record<string, unknown>): void {\n this.log(\"debug\", \"general\", message, data);\n }\n\n recordIndexingStart(): void {\n this.withMetrics(() => {\n this.metrics.indexingStartTime = Date.now();\n });\n }\n\n recordIndexingEnd(): void {\n this.withMetrics(() => {\n this.metrics.indexingEndTime = Date.now();\n });\n }\n\n recordFilesScanned(count: number): void {\n this.withMetrics(() => {\n this.metrics.filesScanned = count;\n });\n }\n\n recordFilesParsed(count: number): void {\n this.withMetrics(() => {\n this.metrics.filesParsed = count;\n });\n }\n\n recordParseDuration(durationMs: number): void {\n this.withMetrics(() => {\n this.metrics.parseMs = durationMs;\n });\n }\n\n recordChunksProcessed(count: number): void {\n this.withMetrics(() => {\n this.metrics.chunksProcessed += count;\n });\n }\n\n recordChunksEmbedded(count: number): void {\n this.withMetrics(() => {\n this.metrics.chunksEmbedded += count;\n });\n }\n\n recordChunksFromCache(count: number): void {\n this.withMetrics(() => {\n this.metrics.chunksFromCache += count;\n });\n }\n\n recordChunksRemoved(count: number): void {\n this.withMetrics(() => {\n this.metrics.chunksRemoved += count;\n });\n }\n\n recordEmbeddingApiCall(tokens: number): void {\n this.withMetrics(() => {\n this.metrics.embeddingApiCalls++;\n this.metrics.embeddingTokensUsed += tokens;\n });\n }\n\n recordEmbeddingError(): void {\n this.withMetrics(() => {\n this.metrics.embeddingErrors++;\n });\n }\n\n recordSearch(durationMs: number, breakdown?: { embeddingMs: number; vectorMs: number; keywordMs: number; fusionMs: number }): void {\n this.withMetrics(() => {\n this.metrics.searchCount++;\n this.metrics.searchTotalMs += durationMs;\n this.metrics.searchLastMs = durationMs;\n this.metrics.searchAvgMs = this.metrics.searchTotalMs / this.metrics.searchCount;\n\n if (breakdown) {\n this.metrics.embeddingCallMs = breakdown.embeddingMs;\n this.metrics.vectorSearchMs = breakdown.vectorMs;\n this.metrics.keywordSearchMs = breakdown.keywordMs;\n this.metrics.fusionMs = breakdown.fusionMs;\n }\n });\n }\n\n recordCacheHit(): void {\n this.withMetrics(() => {\n this.metrics.cacheHits++;\n });\n }\n\n recordCacheMiss(): void {\n this.withMetrics(() => {\n this.metrics.cacheMisses++;\n });\n }\n\n recordQueryCacheHit(): void {\n this.withMetrics(() => {\n this.metrics.queryCacheHits++;\n });\n }\n\n recordQueryCacheSimilarHit(): void {\n this.withMetrics(() => {\n this.metrics.queryCacheSimilarHits++;\n });\n }\n\n recordQueryCacheMiss(): void {\n this.withMetrics(() => {\n this.metrics.queryCacheMisses++;\n });\n }\n\n recordGc(orphans: number, chunks: number, embeddings: number): void {\n this.withMetrics(() => {\n this.metrics.gcRuns++;\n this.metrics.gcOrphansRemoved += orphans;\n this.metrics.gcChunksRemoved += chunks;\n this.metrics.gcEmbeddingsRemoved += embeddings;\n });\n }\n\n getMetrics(): Metrics {\n return { ...this.metrics };\n }\n\n getLogs(limit?: number): LogEntry[] {\n const logs = [...this.logs];\n if (limit) {\n return logs.slice(-limit);\n }\n return logs;\n }\n\n getLogsByCategory(category: string, limit?: number): LogEntry[] {\n const filtered = this.logs.filter(l => l.category === category);\n if (limit) {\n return filtered.slice(-limit);\n }\n return filtered;\n }\n\n getLogsByLevel(level: LogLevel, limit?: number): LogEntry[] {\n const filtered = this.logs.filter(l => l.level === level);\n if (limit) {\n return filtered.slice(-limit);\n }\n return filtered;\n }\n\n resetMetrics(): void {\n this.metrics = createEmptyMetrics();\n }\n\n clearLogs(): void {\n this.logs = [];\n }\n\n formatMetrics(): string {\n const m = this.metrics;\n const lines: string[] = [];\n \n if (m.indexingStartTime && m.indexingEndTime) {\n const duration = m.indexingEndTime - m.indexingStartTime;\n lines.push(`Indexing duration: ${(duration / 1000).toFixed(2)}s`);\n }\n \n lines.push(\"\");\n lines.push(\"Indexing:\");\n lines.push(` Files scanned: ${m.filesScanned}`);\n lines.push(` Files parsed: ${m.filesParsed}`);\n lines.push(` Chunks processed: ${m.chunksProcessed}`);\n lines.push(` Chunks embedded: ${m.chunksEmbedded}`);\n lines.push(` Chunks from cache: ${m.chunksFromCache}`);\n lines.push(` Chunks removed: ${m.chunksRemoved}`);\n \n lines.push(\"\");\n lines.push(\"Embedding API:\");\n lines.push(` API calls: ${m.embeddingApiCalls}`);\n lines.push(` Tokens used: ${m.embeddingTokensUsed.toLocaleString()}`);\n lines.push(` Errors: ${m.embeddingErrors}`);\n \n if (m.searchCount > 0) {\n lines.push(\"\");\n lines.push(\"Search:\");\n lines.push(` Total searches: ${m.searchCount}`);\n lines.push(` Average time: ${m.searchAvgMs.toFixed(2)}ms`);\n lines.push(` Last search: ${m.searchLastMs.toFixed(2)}ms`);\n if (m.embeddingCallMs > 0) {\n lines.push(` - Embedding: ${m.embeddingCallMs.toFixed(2)}ms`);\n lines.push(` - Vector search: ${m.vectorSearchMs.toFixed(2)}ms`);\n lines.push(` - Keyword search: ${m.keywordSearchMs.toFixed(2)}ms`);\n lines.push(` - Fusion: ${m.fusionMs.toFixed(2)}ms`);\n }\n }\n \n const totalCacheOps = m.cacheHits + m.cacheMisses;\n if (totalCacheOps > 0) {\n lines.push(\"\");\n lines.push(\"Cache:\");\n lines.push(` Hits: ${m.cacheHits}`);\n lines.push(` Misses: ${m.cacheMisses}`);\n lines.push(` Hit rate: ${((m.cacheHits / totalCacheOps) * 100).toFixed(1)}%`);\n }\n \n if (m.gcRuns > 0) {\n lines.push(\"\");\n lines.push(\"Garbage Collection:\");\n lines.push(` GC runs: ${m.gcRuns}`);\n lines.push(` Orphans removed: ${m.gcOrphansRemoved}`);\n lines.push(` Chunks removed: ${m.gcChunksRemoved}`);\n lines.push(` Embeddings removed: ${m.gcEmbeddingsRemoved}`);\n }\n \n return lines.join(\"\\n\");\n }\n\n formatRecentLogs(limit = 20): string {\n const logs = this.getLogs(limit);\n if (logs.length === 0) {\n return \"No logs recorded.\";\n }\n \n return logs.map(l => {\n const dataStr = l.data ? ` ${JSON.stringify(l.data)}` : \"\";\n return `[${l.timestamp}] [${l.level.toUpperCase()}] [${l.category}] ${l.message}${dataStr}`;\n }).join(\"\\n\");\n }\n\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n isMetricsEnabled(): boolean {\n return this.config.enabled && this.config.metrics;\n }\n}\n\nlet globalLogger: Logger | null = null;\n\nexport function initializeLogger(config: DebugConfig): Logger {\n globalLogger = new Logger(config);\n return globalLogger;\n}\n\nexport function getLogger(): Logger | null {\n return globalLogger;\n}\n","import type { CodeChunk, DynamicBatchOptions } from \"./types.js\";\n\n// Token estimation: ~4 chars per token for code (conservative)\nconst CHARS_PER_TOKEN = 4;\nconst MAX_BATCH_TOKENS = 7500; // Leave buffer under 8192 API limit\nconst MAX_SINGLE_CHUNK_TOKENS = 2000; // Default truncation cap for individual chunks\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nfunction getEmbeddingHeaderParts(chunk: CodeChunk, filePath: string): string[] {\n const parts: string[] = [];\n\n const fileName = filePath.split(\"/\").pop() || filePath;\n const dirPath = filePath.split(\"/\").slice(-3, -1).join(\"/\");\n\n const langDescriptors: Record<string, string> = {\n typescript: \"TypeScript\",\n javascript: \"JavaScript\",\n python: \"Python\",\n rust: \"Rust\",\n swift: \"Swift\",\n go: \"Go\",\n java: \"Java\",\n };\n\n const typeDescriptors: Record<string, string> = {\n function_declaration: \"function\",\n function: \"function\",\n arrow_function: \"arrow function\",\n method_definition: \"method\",\n method_declaration: \"method\",\n protocol_function_declaration: \"protocol requirement\",\n init_declaration: \"initializer\",\n deinit_declaration: \"deinitializer\",\n subscript_declaration: \"subscript\",\n class_declaration: \"class\",\n actor_declaration: \"actor\",\n extension_declaration: \"extension\",\n protocol_declaration: \"protocol\",\n struct_declaration: \"struct\",\n interface_declaration: \"interface\",\n type_alias_declaration: \"type alias\",\n enum_declaration: \"enum\",\n export_statement: \"export\",\n lexical_declaration: \"variable declaration\",\n function_definition: \"function\",\n class_definition: \"class\",\n function_item: \"function\",\n impl_item: \"implementation\",\n struct_item: \"struct\",\n enum_item: \"enum\",\n trait_item: \"trait\",\n };\n\n const lang = langDescriptors[chunk.language] || chunk.language;\n const typeDesc = typeDescriptors[chunk.chunkType] || chunk.chunkType;\n\n if (chunk.name) {\n parts.push(`${lang} ${typeDesc} \"${chunk.name}\"`);\n } else {\n parts.push(`${lang} ${typeDesc}`);\n }\n\n if (dirPath) {\n parts.push(`in ${dirPath}/${fileName}`);\n } else {\n parts.push(`in ${fileName}`);\n }\n\n const semanticHints = extractSemanticHints(chunk.name || \"\", chunk.content);\n if (semanticHints.length > 0) {\n parts.push(`Purpose: ${semanticHints.join(\", \")}`);\n }\n\n return parts;\n}\n\nfunction buildEmbeddingText(\n headerParts: string[],\n content: string,\n partIndex?: number,\n partCount?: number,\n): string {\n const parts = [...headerParts];\n if (partCount && partCount > 1 && partIndex) {\n parts.push(`Part ${partIndex}/${partCount}`);\n }\n parts.push(\"\");\n parts.push(content);\n return parts.join(\"\\n\");\n}\n\nfunction splitOversizedContent(content: string, maxContentChars: number): string[] {\n if (content.length <= maxContentChars) {\n return [content];\n }\n\n const overlapChars = Math.max(\n CHARS_PER_TOKEN * 32,\n Math.min(Math.floor(maxContentChars * 0.15), CHARS_PER_TOKEN * 128),\n );\n const stepChars = Math.max(1, maxContentChars - overlapChars);\n const segments: string[] = [];\n\n for (let start = 0; start < content.length; start += stepChars) {\n const end = Math.min(content.length, start + maxContentChars);\n segments.push(content.slice(start, end));\n if (end >= content.length) {\n break;\n }\n }\n\n return segments;\n}\n\nexport function createEmbeddingTexts(\n chunk: CodeChunk,\n filePath: string,\n maxChunkTokens = MAX_SINGLE_CHUNK_TOKENS,\n): string[] {\n const headerParts = getEmbeddingHeaderParts(chunk, filePath);\n const headerLength = buildEmbeddingText(headerParts, \"\", 1, 9).length;\n const maxContentChars = Math.max(1, maxChunkTokens * CHARS_PER_TOKEN - headerLength);\n const segments = splitOversizedContent(chunk.content, maxContentChars);\n\n if (segments.length === 1) {\n return [buildEmbeddingText(headerParts, segments[0])];\n }\n\n return segments.map((segment, index) =>\n buildEmbeddingText(headerParts, segment, index + 1, segments.length),\n );\n}\n\nexport function createEmbeddingText(\n chunk: CodeChunk,\n filePath: string,\n maxChunkTokens = MAX_SINGLE_CHUNK_TOKENS,\n): string {\n const text = createEmbeddingTexts(chunk, filePath, maxChunkTokens)[0];\n if (!text) {\n return \"\";\n }\n\n const maxChars = maxChunkTokens * CHARS_PER_TOKEN;\n if (text.length <= maxChars) {\n return text;\n }\n\n return text.slice(0, Math.max(0, maxChars - 17)) + \"\\n... [truncated]\";\n}\n\nexport function createDynamicBatches<T extends { text: string; tokenCount?: number }>(\n chunks: T[],\n options: DynamicBatchOptions = {},\n): T[][] {\n const batches: T[][] = [];\n let currentBatch: T[] = [];\n let currentTokens = 0;\n const maxBatchTokens = Math.max(1, options.maxBatchTokens ?? MAX_BATCH_TOKENS);\n const maxBatchItems = Math.max(1, options.maxBatchItems ?? Number.MAX_SAFE_INTEGER);\n\n for (const chunk of chunks) {\n const chunkTokens = chunk.tokenCount ?? estimateTokens(chunk.text);\n\n if (\n currentBatch.length > 0\n && (currentTokens + chunkTokens > maxBatchTokens || currentBatch.length >= maxBatchItems)\n ) {\n batches.push(currentBatch);\n currentBatch = [];\n currentTokens = 0;\n }\n\n currentBatch.push(chunk);\n currentTokens += chunkTokens;\n }\n\n if (currentBatch.length > 0) {\n batches.push(currentBatch);\n }\n\n return batches;\n}\n\nfunction extractSemanticHints(name: string, content: string): string[] {\n const hints: string[] = [];\n const combined = `${name} ${content}`.toLowerCase();\n\n const signature = extractFunctionSignature(content);\n if (signature) {\n hints.push(signature);\n }\n\n const patterns: Array<[RegExp, string]> = [\n [/auth|login|logout|signin|signout|credential/i, \"authentication\"],\n [/password|hash|bcrypt|argon/i, \"password handling\"],\n [/token|jwt|bearer|oauth/i, \"token management\"],\n [/user|account|profile|member/i, \"user management\"],\n [/permission|role|access|authorize/i, \"authorization\"],\n [/validate|verify|check|assert/i, \"validation\"],\n [/error|exception|throw|catch/i, \"error handling\"],\n [/log|debug|trace|info|warn/i, \"logging\"],\n [/cache|memoize|store/i, \"caching\"],\n [/fetch|request|response|api|http/i, \"HTTP/API\"],\n [/database|db|query|sql|mongo/i, \"database\"],\n [/file|read|write|stream|path/i, \"file operations\"],\n [/parse|serialize|json|xml/i, \"data parsing\"],\n [/encrypt|decrypt|crypto|secret|cipher|cryptographic/i, \"encryption/cryptography\"],\n [/test|spec|mock|stub|expect/i, \"testing\"],\n [/config|setting|option|env/i, \"configuration\"],\n [/route|endpoint|handler|controller|middleware/i, \"routing/middleware\"],\n [/render|component|view|template/i, \"UI rendering\"],\n [/state|redux|store|dispatch/i, \"state management\"],\n [/hook|effect|memo|callback/i, \"React hooks\"],\n ];\n\n for (const [pattern, hint] of patterns) {\n if (pattern.test(combined) && !hints.includes(hint)) {\n hints.push(hint);\n }\n }\n\n return hints.slice(0, 6);\n}\n\nfunction extractFunctionSignature(content: string): string | null {\n const tsJsPatterns = [\n /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*(?:<[^>]+>)?\\s*\\(([^)]*)\\)\\s*(?::\\s*([^{]+))?/,\n /(?:export\\s+)?const\\s+(\\w+)\\s*(?::\\s*[^=]+)?\\s*=\\s*(?:async\\s+)?\\(([^)]*)\\)\\s*(?::\\s*([^=>{]+))?\\s*=>/,\n /(?:export\\s+)?const\\s+(\\w+)\\s*(?::\\s*[^=]+)?\\s*=\\s*(?:async\\s+)?function\\s*\\(([^)]*)\\)/,\n ];\n\n const pyPatterns = [\n /def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(?:->\\s*([^:]+))?:/,\n /async\\s+def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(?:->\\s*([^:]+))?:/,\n ];\n\n const goPatterns = [/func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\(([^)]*)\\)\\s*(?:\\(([^)]+)\\)|([^{\\n]+))?/];\n\n const rustPatterns = [/(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)\\s*(?:<[^>]+>)?\\s*\\(([^)]*)\\)\\s*(?:->\\s*([^{]+))?/];\n\n for (const pattern of [...tsJsPatterns, ...pyPatterns, ...goPatterns, ...rustPatterns]) {\n const match = content.match(pattern);\n if (match) {\n const funcName = match[1];\n const params = match[2]?.trim() || \"\";\n const returnType = (match[3] || match[4])?.trim();\n\n const paramNames = extractParamNames(params);\n\n let sig = `${funcName}(${paramNames.join(\", \")})`;\n if (returnType && returnType.length < 50) {\n sig += ` -> ${returnType.replace(/\\s+/g, \" \").trim()}`;\n }\n\n if (sig.length < 100) {\n return sig;\n }\n }\n }\n\n return null;\n}\n\nfunction extractParamNames(params: string): string[] {\n if (!params.trim()) return [];\n\n const names: string[] = [];\n const parts = params.split(\",\");\n\n for (const part of parts) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n\n const tsMatch = trimmed.match(/^(\\w+)\\s*[?:]?/);\n const pyMatch = trimmed.match(/^(\\w+)\\s*(?::|=)/);\n const goMatch = trimmed.match(/^(\\w+)\\s+\\w/);\n const rustMatch = trimmed.match(/^(\\w+)\\s*:/);\n\n const match = tsMatch || pyMatch || goMatch || rustMatch;\n if (match && match[1] !== \"self\" && match[1] !== \"this\") {\n names.push(match[1]);\n }\n }\n\n return names.slice(0, 5);\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as module from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { STABLE_NATIVE_BINARY_NAME } from \"../identity-catalog.js\";\n\nexport function getNativeBindingFilename(\n platform: NodeJS.Platform = os.platform(),\n arch: NodeJS.Architecture = os.arch(),\n): string {\n if (platform === \"darwin\" && arch === \"arm64\") {\n return `${STABLE_NATIVE_BINARY_NAME}.darwin-arm64.node`;\n }\n if (platform === \"darwin\" && arch === \"x64\") {\n return `${STABLE_NATIVE_BINARY_NAME}.darwin-x64.node`;\n }\n if (platform === \"linux\" && arch === \"x64\") {\n return `${STABLE_NATIVE_BINARY_NAME}.linux-x64-gnu.node`;\n }\n if (platform === \"linux\" && arch === \"arm64\") {\n return `${STABLE_NATIVE_BINARY_NAME}.linux-arm64-gnu.node`;\n }\n if (platform === \"win32\" && arch === \"x64\") {\n return `${STABLE_NATIVE_BINARY_NAME}.win32-x64-msvc.node`;\n }\n\n throw new Error(`Unsupported platform: ${platform}-${arch}`);\n}\n\nexport function resolveNativeBindingPath(\n packageRoot: string,\n platform: NodeJS.Platform = os.platform(),\n arch: NodeJS.Architecture = os.arch(),\n): string {\n return path.join(packageRoot, \"native\", getNativeBindingFilename(platform, arch));\n}\n\nfunction getNativeBinding() {\n // Determine the current directory - handle ESM, CJS, and bundled contexts\n let currentDir: string;\n let requireTarget: string;\n\n // Check for ESM context with valid import.meta.url\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n currentDir = path.dirname(fileURLToPath(import.meta.url));\n requireTarget = import.meta.url;\n }\n // Fallback to __dirname for CJS/bundled contexts\n else if (typeof __dirname !== \"undefined\") {\n currentDir = __dirname;\n requireTarget = __filename;\n }\n // Last resort: use process.cwd() - shouldn't normally hit this\n else {\n currentDir = process.cwd();\n requireTarget = path.join(currentDir, \"index.js\");\n }\n\n // The native module is in the 'native' folder at package root\n // From dist/index.js, we go up one level to package root, then into native/\n // From src/native/index.ts (dev/test), we go up two levels to package root\n const normalizedDir = currentDir.replace(/\\\\/g, \"/\");\n const isDevMode = normalizedDir.includes(\"/src/native\") || currentDir.includes(path.join(\"src\", \"native\"));\n const packageRoot = isDevMode\n ? path.resolve(currentDir, \"../..\")\n : path.resolve(currentDir, \"..\");\n const nativePath = resolveNativeBindingPath(packageRoot);\n\n // Load the native module - use standard require for .node files\n const require = module.createRequire(requireTarget);\n return require(nativePath);\n}\n\nfunction createMockNativeBinding() {\n const error = new Error(\"Native module not available. Please rebuild with 'npm run build:native'.\");\n\n return {\n parseFile: () => {\n throw error;\n },\n parseFiles: () => {\n throw error;\n },\n hashContent: () => {\n throw error;\n },\n hashFile: () => {\n throw error;\n },\n extractCalls: () => {\n throw error;\n },\n VectorStore: class {\n constructor() {\n throw error;\n }\n },\n InvertedIndex: class {\n constructor() {\n throw error;\n }\n serialize() {\n throw error;\n }\n deserialize() {\n throw error;\n }\n },\n Database: class {\n constructor() {\n throw error;\n }\n static openReadOnly() {\n throw error;\n }\n static createEmptyReadOnly() {\n throw error;\n }\n close() {\n throw error;\n }\n getTransitiveReachability() {\n throw error;\n }\n detectCommunities() {\n throw error;\n }\n detectCommunityCouplings() {\n throw error;\n }\n computeCentrality() {\n throw error;\n }\n },\n };\n}\n\nlet native: any;\ntry {\n native = getNativeBinding();\n} catch (e) {\n console.error(\"[codebase-index] Failed to load native module:\", e);\n native = createMockNativeBinding();\n}\n\nexport { native };\n","{\n \"product\": {\n \"current\": {\n \"productName\": \"opencode-codebase-index\",\n \"packageName\": \"opencode-codebase-index\",\n \"repository\": \"https://github.com/Helweg/open-codebase-index\",\n \"mcpBinary\": \"opencode-codebase-index-mcp\",\n \"mcpServerName\": \"opencode-codebase-index\"\n },\n \"future\": {\n \"productName\": \"open-codebase-index\",\n \"packageName\": \"open-codebase-index\",\n \"repository\": \"https://github.com/Helweg/open-codebase-index\",\n \"mcpBinary\": \"open-codebase-index-mcp\",\n \"mcpServerName\": \"open-codebase-index\"\n }\n },\n \"native\": {\n \"binaryName\": \"codebase-index-native\"\n }\n}\n","import identityCatalogJson from \"./identity-catalog.json\";\n\nexport interface ProductIdentity {\n productName: string;\n packageName: string;\n repository: string;\n mcpBinary: string;\n mcpServerName: string;\n}\n\nexport interface ProductIdentityCollection {\n current: ProductIdentity;\n future: ProductIdentity;\n}\n\nexport interface NativeIdentity {\n binaryName: string;\n}\n\nexport interface IdentityCatalog {\n product: ProductIdentityCollection;\n native: NativeIdentity;\n}\n\nexport const IDENTITY_CATALOG = identityCatalogJson as IdentityCatalog;\n\nexport const CURRENT_PRODUCT = IDENTITY_CATALOG.product.current;\nexport const FUTURE_PRODUCT = IDENTITY_CATALOG.product.future;\n\nexport const MCP_SERVER_CURRENT_NAME = CURRENT_PRODUCT.mcpServerName;\nexport const MCP_BINARY_CURRENT_NAME = CURRENT_PRODUCT.mcpBinary;\nexport const STABLE_NATIVE_BINARY_NAME = IDENTITY_CATALOG.native.binaryName;\n","import type { CallSiteData, CodeChunk, FileInput, ParsedFile, ParsedSymbol, ChunkType } from \"./types.js\";\nimport { native } from \"./binding.js\";\n\nexport function parseFile(filePath: string, content: string, linesPerChunk?: number): CodeChunk[] {\n const result = native.parseFile(filePath, content, linesPerChunk);\n return result.map(mapChunk);\n}\n\nexport function parseFileAsText(filePath: string, content: string, linesPerChunk?: number): CodeChunk[] {\n const result = native.parseFileAsText(filePath, content, linesPerChunk);\n return result.map(mapChunk);\n}\n\nexport function parseFiles(files: FileInput[], linesPerChunk?: number): ParsedFile[] {\n const result = native.parseFiles(files, linesPerChunk);\n return result.map((f: any) => ({\n path: f.path,\n chunks: f.chunks.map(mapChunk),\n symbols: (f.symbols ?? []).map(mapParsedSymbol),\n hash: f.hash,\n }));\n}\n\nfunction mapParsedSymbol(symbol: any): ParsedSymbol {\n return {\n name: symbol.name,\n kind: symbol.kind,\n startLine: symbol.startLine ?? symbol.start_line,\n startCol: symbol.startCol ?? symbol.start_col,\n endLine: symbol.endLine ?? symbol.end_line,\n endCol: symbol.endCol ?? symbol.end_col,\n language: symbol.language,\n };\n}\n\nfunction mapChunk(c: any): CodeChunk {\n return {\n content: c.content,\n startLine: c.startLine ?? c.start_line,\n startCol: c.startCol ?? c.start_col,\n endLine: c.endLine ?? c.end_line,\n endCol: c.endCol ?? c.end_col,\n chunkType: (c.chunkType ?? c.chunk_type) as ChunkType,\n name: c.name ?? undefined,\n language: c.language,\n };\n}\n\nexport function hashContent(content: string): string {\n return native.hashContent(content);\n}\n\nexport function hashFile(filePath: string): string {\n return native.hashFile(filePath);\n}\n\nexport function extractCalls(content: string, language: string): CallSiteData[] {\n return native.extractCalls(content, language);\n}\n\nexport function generateChunkId(filePath: string, chunk: CodeChunk): string {\n const hash = hashContent(`${filePath}:${chunk.startLine}:${chunk.endLine}:${chunk.content}`);\n return `chunk_${hash.slice(0, 16)}`;\n}\n\nexport function generateChunkHash(chunk: CodeChunk): string {\n return hashContent(chunk.content);\n}\n","import type { ChunkMetadata, SearchResult } from \"./types.js\";\nimport { native } from \"./binding.js\";\n\nexport class VectorStore {\n private inner: any;\n private dimensions: number;\n\n constructor(indexPath: string, dimensions: number) {\n this.inner = new native.VectorStore(indexPath, dimensions);\n this.dimensions = dimensions;\n }\n\n add(id: string, vector: number[], metadata: ChunkMetadata): void {\n if (vector.length !== this.dimensions) {\n throw new Error(\n `Vector dimension mismatch: expected ${this.dimensions}, got ${vector.length}`\n );\n }\n this.inner.add(id, vector, JSON.stringify(metadata));\n }\n\n addBatch(\n items: Array<{ id: string; vector: number[]; metadata: ChunkMetadata }>\n ): void {\n const ids = items.map((i) => i.id);\n const vectors = items.map((i) => {\n if (i.vector.length !== this.dimensions) {\n throw new Error(\n `Vector dimension mismatch for ${i.id}: expected ${this.dimensions}, got ${i.vector.length}`\n );\n }\n return i.vector;\n });\n const metadata = items.map((i) => JSON.stringify(i.metadata));\n this.inner.addBatch(ids, vectors, metadata);\n }\n\n search(queryVector: number[], limit: number = 10, allowedIds?: string[]): SearchResult[] {\n if (queryVector.length !== this.dimensions) {\n throw new Error(\n `Query vector dimension mismatch: expected ${this.dimensions}, got ${queryVector.length}`\n );\n }\n const results = allowedIds === undefined\n ? this.inner.search(queryVector, limit)\n : this.inner.searchFiltered(queryVector, limit, allowedIds);\n return results.map((r: any) => ({\n id: r.id,\n score: r.score,\n metadata: JSON.parse(r.metadata) as ChunkMetadata,\n }));\n }\n\n remove(id: string): boolean {\n return this.inner.remove(id);\n }\n\n save(): void {\n this.inner.save();\n }\n\n load(): void {\n this.inner.load();\n }\n\n loadStrict(): void {\n this.inner.loadStrict();\n }\n\n hasFingerprint(): boolean {\n return this.inner.hasFingerprint();\n }\n\n count(): number {\n return this.inner.count();\n }\n\n clear(): void {\n this.inner.clear();\n }\n\n getDimensions(): number {\n return this.dimensions;\n }\n\n getAllKeys(): string[] {\n return this.inner.getAllKeys();\n }\n\n getAllMetadata(): Array<{ key: string; metadata: ChunkMetadata }> {\n const results = this.inner.getAllMetadata();\n return results.map((r: { key: string; metadata: string }) => ({\n key: r.key,\n metadata: JSON.parse(r.metadata) as ChunkMetadata,\n }));\n }\n\n getMetadata(id: string): ChunkMetadata | undefined {\n const result = this.inner.getMetadata(id);\n if (result === null || result === undefined) {\n return undefined;\n }\n return JSON.parse(result) as ChunkMetadata;\n }\n\n getMetadataBatch(ids: string[]): Map<string, ChunkMetadata> {\n const results = this.inner.getMetadataBatch(ids);\n const map = new Map<string, ChunkMetadata>();\n for (const { key, metadata } of results) {\n map.set(key, JSON.parse(metadata) as ChunkMetadata);\n }\n return map;\n }\n}\n","import { native } from \"./binding.js\";\n\nexport class InvertedIndex {\n private inner: any;\n\n constructor(indexPath: string) {\n this.inner = new native.InvertedIndex(indexPath);\n }\n\n load(): void {\n this.inner.load();\n }\n\n save(): void {\n this.inner.save();\n }\n\n serialize(): string {\n return this.inner.serialize();\n }\n\n deserialize(json: string): void {\n this.inner.deserialize(json);\n }\n\n addChunk(chunkId: string, content: string): void {\n this.inner.addChunk(chunkId, content);\n }\n\n removeChunk(chunkId: string): boolean {\n return this.inner.removeChunk(chunkId);\n }\n\n search(query: string, limit?: number): Map<string, number> {\n const results = this.inner.search(query, limit ?? 100);\n const map = new Map<string, number>();\n for (const r of results) {\n map.set(r.chunkId, r.score);\n }\n return map;\n }\n\n hasChunk(chunkId: string): boolean {\n return this.inner.hasChunk(chunkId);\n }\n\n clear(): void {\n this.inner.clear();\n }\n\n getDocumentCount(): number {\n return this.inner.documentCount();\n }\n}\n","import type {\n BranchDelta,\n CallEdgeData,\n CentralityData,\n ChunkData,\n CommunityCouplingData,\n CommunityData,\n DatabaseStats,\n PathHopData,\n ReachabilityData,\n SymbolData,\n} from \"./types.js\";\nimport { native } from \"./binding.js\";\n\nexport class Database {\n private inner: any;\n private closed = false;\n\n constructor(dbPath: string) {\n this.inner = new native.Database(dbPath);\n }\n\n private static fromNative(inner: any): Database {\n const database = Object.create(Database.prototype) as Database;\n database.inner = inner;\n database.closed = false;\n return database;\n }\n\n static openReadOnly(dbPath: string): Database {\n return Database.fromNative(native.Database.openReadOnly(dbPath));\n }\n\n static createEmptyReadOnly(): Database {\n return Database.fromNative(native.Database.createEmptyReadOnly());\n }\n\n private throwIfClosed(): void {\n if (this.closed) {\n throw new Error(\"Database is closed\");\n }\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n\n if (typeof this.inner.close === \"function\") {\n this.inner.close();\n }\n\n this.closed = true;\n }\n\n beginWriteTransaction(): void {\n this.throwIfClosed();\n this.inner.beginWriteTransaction();\n }\n\n commitWriteTransaction(): void {\n this.throwIfClosed();\n this.inner.commitWriteTransaction();\n }\n\n rollbackWriteTransaction(): void {\n this.throwIfClosed();\n this.inner.rollbackWriteTransaction();\n }\n\n embeddingExists(contentHash: string): boolean {\n this.throwIfClosed();\n return this.inner.embeddingExists(contentHash);\n }\n\n getEmbedding(contentHash: string): Buffer | null {\n this.throwIfClosed();\n return this.inner.getEmbedding(contentHash) ?? null;\n }\n\n upsertEmbedding(\n contentHash: string,\n embedding: Buffer,\n chunkText: string,\n model: string\n ): void {\n this.throwIfClosed();\n this.inner.upsertEmbedding(contentHash, embedding, chunkText, model);\n }\n\n upsertEmbeddingsBatch(\n items: Array<{\n contentHash: string;\n embedding: Buffer;\n chunkText: string;\n model: string;\n }>\n ): void {\n this.throwIfClosed();\n if (items.length === 0) return;\n this.inner.upsertEmbeddingsBatch(items);\n }\n\n getMissingEmbeddings(contentHashes: string[]): string[] {\n this.throwIfClosed();\n return this.inner.getMissingEmbeddings(contentHashes);\n }\n\n upsertChunk(chunk: ChunkData): void {\n this.throwIfClosed();\n this.inner.upsertChunk(chunk);\n }\n\n upsertChunksBatch(chunks: ChunkData[]): void {\n this.throwIfClosed();\n if (chunks.length === 0) return;\n this.inner.upsertChunksBatch(chunks);\n }\n\n getChunk(chunkId: string): ChunkData | null {\n this.throwIfClosed();\n return this.inner.getChunk(chunkId) ?? null;\n }\n\n getChunksByFile(filePath: string): ChunkData[] {\n this.throwIfClosed();\n return this.inner.getChunksByFile(filePath);\n }\n\n getChunksByName(name: string): ChunkData[] {\n this.throwIfClosed();\n return this.inner.getChunksByName(name);\n }\n\n getChunksByNameCi(name: string): ChunkData[] {\n this.throwIfClosed();\n return this.inner.getChunksByNameCi(name);\n }\n\n deleteChunksByFile(filePath: string): number {\n this.throwIfClosed();\n return this.inner.deleteChunksByFile(filePath);\n }\n\n deleteChunksByIds(chunkIds: string[]): number {\n this.throwIfClosed();\n if (chunkIds.length === 0) return 0;\n return this.inner.deleteChunksByIds(chunkIds);\n }\n\n addChunksToBranch(branch: string, chunkIds: string[]): void {\n this.throwIfClosed();\n this.inner.addChunksToBranch(branch, chunkIds);\n }\n\n addChunksToBranchBatch(branch: string, chunkIds: string[]): void {\n this.throwIfClosed();\n if (chunkIds.length === 0) return;\n this.inner.addChunksToBranchBatch(branch, chunkIds);\n }\n\n clearBranch(branch: string): number {\n this.throwIfClosed();\n return this.inner.clearBranch(branch);\n }\n\n deleteBranchChunksByChunkIds(chunkIds: string[]): number {\n this.throwIfClosed();\n if (chunkIds.length === 0) return 0;\n return this.inner.deleteBranchChunksByChunkIds(chunkIds);\n }\n\n deleteBranchChunksForBranch(branch: string, chunkIds: string[]): number {\n this.throwIfClosed();\n if (chunkIds.length === 0) return 0;\n return this.inner.deleteBranchChunksForBranch(branch, chunkIds);\n }\n\n getBranchChunkIds(branch: string): string[] {\n this.throwIfClosed();\n return this.inner.getBranchChunkIds(branch);\n }\n\n getChunkIdsByBlameDate(since?: number, until?: number): string[] {\n this.throwIfClosed();\n return this.inner.getChunkIdsByBlameDate(since, until);\n }\n\n getBranchDelta(branch: string, baseBranch: string): BranchDelta {\n this.throwIfClosed();\n return this.inner.getBranchDelta(branch, baseBranch);\n }\n\n getReferencedChunkIds(chunkIds: string[]): string[] {\n this.throwIfClosed();\n if (chunkIds.length === 0) return [];\n return this.inner.getReferencedChunkIds(chunkIds);\n }\n\n chunkExistsOnBranch(branch: string, chunkId: string): boolean {\n this.throwIfClosed();\n return this.inner.chunkExistsOnBranch(branch, chunkId);\n }\n\n getAllBranches(): string[] {\n this.throwIfClosed();\n return this.inner.getAllBranches();\n }\n\n getMetadata(key: string): string | null {\n this.throwIfClosed();\n return this.inner.getMetadata(key) ?? null;\n }\n\n setMetadata(key: string, value: string): void {\n this.throwIfClosed();\n this.inner.setMetadata(key, value);\n }\n\n deleteMetadata(key: string): boolean {\n this.throwIfClosed();\n return this.inner.deleteMetadata(key);\n }\n\n clearAllIndexedData(): void {\n this.throwIfClosed();\n this.inner.clearAllIndexedData();\n }\n\n clearCallEdgeTargetsForSymbols(symbolIds: string[]): number {\n this.throwIfClosed();\n if (symbolIds.length === 0) return 0;\n return this.inner.clearCallEdgeTargetsForSymbols(symbolIds);\n }\n\n gcOrphanEmbeddings(): number {\n this.throwIfClosed();\n return this.inner.gcOrphanEmbeddings();\n }\n\n gcOrphanChunks(): number {\n this.throwIfClosed();\n return this.inner.gcOrphanChunks();\n }\n\n getStats(): DatabaseStats {\n this.throwIfClosed();\n return this.inner.getStats();\n }\n\n upsertSymbol(symbol: SymbolData): void {\n this.throwIfClosed();\n this.inner.upsertSymbol(symbol);\n }\n\n upsertSymbolsBatch(symbols: SymbolData[]): void {\n this.throwIfClosed();\n if (symbols.length === 0) return;\n this.inner.upsertSymbolsBatch(symbols);\n }\n\n getSymbolsByFile(filePath: string): SymbolData[] {\n this.throwIfClosed();\n return this.inner.getSymbolsByFile(filePath);\n }\n\n getSymbolByName(name: string, filePath: string): SymbolData | null {\n this.throwIfClosed();\n return this.inner.getSymbolByName(name, filePath) ?? null;\n }\n\n getSymbolsByName(name: string): SymbolData[] {\n this.throwIfClosed();\n return this.inner.getSymbolsByName(name);\n }\n\n getSymbolsByNameCi(name: string): SymbolData[] {\n this.throwIfClosed();\n return this.inner.getSymbolsByNameCi(name);\n }\n getSymbolsForBranch(branch: string): SymbolData[] {\n this.throwIfClosed();\n return this.inner.getSymbolsForBranch(branch);\n }\n\n getSymbolsForFiles(filePaths: string[], branch: string): SymbolData[] {\n this.throwIfClosed();\n return this.inner.getSymbolsForFiles(filePaths, branch);\n }\n\n deleteSymbolsByFile(filePath: string): number {\n this.throwIfClosed();\n return this.inner.deleteSymbolsByFile(filePath);\n }\n\n upsertCallEdge(edge: CallEdgeData): void {\n this.throwIfClosed();\n this.inner.upsertCallEdge(edge);\n }\n\n upsertCallEdgesBatch(edges: CallEdgeData[]): void {\n this.throwIfClosed();\n if (edges.length === 0) return;\n this.inner.upsertCallEdgesBatch(edges);\n }\n\n getCallers(targetName: string, branch: string, callTypeFilter?: string): CallEdgeData[] {\n this.throwIfClosed();\n return this.inner.getCallers(targetName, branch, callTypeFilter ?? null);\n }\n\n getCallersWithContext(\n targetName: string,\n branch: string,\n callTypeFilter?: string\n ): CallEdgeData[] {\n this.throwIfClosed();\n return this.inner.getCallersWithContext(targetName, branch, callTypeFilter ?? null);\n }\n\n getCallees(symbolId: string, branch: string, callTypeFilter?: string): CallEdgeData[] {\n this.throwIfClosed();\n return this.inner.getCallees(symbolId, branch, callTypeFilter ?? null);\n }\n\n deleteCallEdgesByFile(filePath: string): number {\n this.throwIfClosed();\n return this.inner.deleteCallEdgesByFile(filePath);\n }\n\n resolveCallEdge(edgeId: string, toSymbolId: string): void {\n this.throwIfClosed();\n this.inner.resolveCallEdge(edgeId, toSymbolId);\n }\n\n findShortestPath(\n fromName: string,\n toName: string,\n branch: string,\n maxDepth?: number\n ): PathHopData[] {\n this.throwIfClosed();\n return this.inner.findShortestPath(fromName, toName, branch, maxDepth ?? null);\n }\n\n addSymbolsToBranch(branch: string, symbolIds: string[]): void {\n this.throwIfClosed();\n this.inner.addSymbolsToBranch(branch, symbolIds);\n }\n\n addSymbolsToBranchBatch(branch: string, symbolIds: string[]): void {\n this.throwIfClosed();\n if (symbolIds.length === 0) return;\n this.inner.addSymbolsToBranchBatch(branch, symbolIds);\n }\n\n getBranchSymbolIds(branch: string): string[] {\n this.throwIfClosed();\n return this.inner.getBranchSymbolIds(branch);\n }\n\n clearBranchSymbols(branch: string): number {\n this.throwIfClosed();\n return this.inner.clearBranchSymbols(branch);\n }\n\n getReferencedSymbolIds(symbolIds: string[]): string[] {\n this.throwIfClosed();\n if (symbolIds.length === 0) return [];\n return this.inner.getReferencedSymbolIds(symbolIds);\n }\n\n deleteBranchSymbolsBySymbolIds(symbolIds: string[]): number {\n this.throwIfClosed();\n if (symbolIds.length === 0) return 0;\n return this.inner.deleteBranchSymbolsBySymbolIds(symbolIds);\n }\n\n deleteBranchSymbolsForBranch(branch: string, symbolIds: string[]): number {\n this.throwIfClosed();\n if (symbolIds.length === 0) return 0;\n return this.inner.deleteBranchSymbolsForBranch(branch, symbolIds);\n }\n\n gcOrphanSymbols(): number {\n this.throwIfClosed();\n return this.inner.gcOrphanSymbols();\n }\n\n gcOrphanCallEdges(): number {\n this.throwIfClosed();\n return this.inner.gcOrphanCallEdges();\n }\n\n getTransitiveReachability(\n rootSymbolIds: string[],\n branch: string,\n direction: string,\n maxDepth?: number\n ): ReachabilityData[] {\n this.throwIfClosed();\n return this.inner.getTransitiveReachability(\n rootSymbolIds,\n branch,\n direction,\n maxDepth ?? null\n );\n }\n\n detectCommunities(\n branch: string,\n symbolIds?: string[]\n ): CommunityData[] {\n this.throwIfClosed();\n return this.inner.detectCommunities(branch, symbolIds ?? null);\n }\n\n computeCentrality(branch: string): CentralityData[] {\n this.throwIfClosed();\n return this.inner.computeCentrality(branch);\n }\n\n detectCommunityCouplings(branch: string): CommunityCouplingData[] {\n this.throwIfClosed();\n return this.inner.detectCommunityCouplings(branch).map((entry: CommunityCouplingData) => ({\n ...entry,\n relationships: entry.representativeRelationships ?? [],\n }));\n }\n}\n","import { promises as fsPromises } from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { canonicalizePathForComparison } from \"../utils/canonical-path.js\";\n\nimport type {\n BranchMaterializationInfo,\n BranchMaterializationRequest,\n BranchMaterializationSource,\n LocalPullRequestRefs,\n} from \"./branch-resolution.js\";\nimport {\n asError,\n assertValidGitRefName,\n getErrorMessage,\n isValidGitRefName,\n isFullGitCommit,\n isValidGitRemoteName,\n resolveGitCommit,\n resolveLocalGitCommit,\n resolveLocalPullRequestRefs,\n resolveCommit,\n runGit,\n runGitRaw,\n tryResolveCommit,\n} from \"./branch-resolution.js\";\n\nexport type {\n BranchMaterializationSource,\n BranchMaterializationRequest,\n BranchMaterializationInfo,\n LocalPullRequestRefs,\n};\n\nexport {\n isFullGitCommit,\n isValidGitRefName,\n assertValidGitRefName,\n isValidGitRemoteName,\n resolveLocalGitCommit,\n resolveLocalPullRequestRefs,\n resolveGitCommit,\n};\nasync function pathExists(targetPath: string): Promise<boolean> {\n return fsPromises.stat(targetPath).then(() => true, () => false);\n}\n\nasync function isWorktreeRegistered(projectRoot: string, worktreePath: string): Promise<boolean> {\n const output = await runGitRaw(projectRoot, [\"worktree\", \"list\", \"--porcelain\", \"-z\"]);\n const target = canonicalizePathForComparison(worktreePath);\n const worktreePaths = output\n .split(\"\\0\")\n .filter((entry) => entry.startsWith(\"worktree \"))\n .map((entry) => entry.slice(\"worktree \".length));\n\n for (const registeredPath of worktreePaths) {\n if (canonicalizePathForComparison(registeredPath) === target) return true;\n }\n return false;\n}\n\nfunction isPathWithinRoot(filePath: string, rootPath: string): boolean {\n const relative = path.relative(path.resolve(rootPath), path.resolve(filePath));\n return relative === \"\" || (!relative.startsWith(`..${path.sep}`) && relative !== \"..\" && !path.isAbsolute(relative));\n}\n\nasync function pruneExactMissingWorktreeRegistration(\n projectRoot: string,\n worktreePath: string,\n): Promise<boolean> {\n if (await pathExists(worktreePath)) return false;\n\n const commonDir = await runGit(projectRoot, [\"rev-parse\", \"--path-format=absolute\", \"--git-common-dir\"]);\n const registrationsRoot = path.join(commonDir, \"worktrees\");\n let entries;\n try {\n entries = await fsPromises.readdir(registrationsRoot, { withFileTypes: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n\n const target = canonicalizePathForComparison(worktreePath);\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const registrationPath = path.join(registrationsRoot, entry.name);\n if (!isPathWithinRoot(registrationPath, registrationsRoot)) continue;\n\n let gitdirPath: string;\n try {\n gitdirPath = (await fsPromises.readFile(path.join(registrationPath, \"gitdir\"), \"utf8\")).trim();\n } catch {\n continue;\n }\n\n const resolvedGitdirPath = path.isAbsolute(gitdirPath)\n ? gitdirPath\n : path.resolve(registrationPath, gitdirPath);\n if (canonicalizePathForComparison(path.dirname(resolvedGitdirPath)) !== target) continue;\n await fsPromises.rm(registrationPath, { recursive: true, force: true });\n return true;\n }\n\n return false;\n}\n\nasync function removeWorktree(projectRoot: string, worktreePath: string): Promise<void> {\n const errors: Error[] = [];\n try {\n await runGit(projectRoot, [\"worktree\", \"remove\", \"--force\", \"--\", worktreePath]);\n } catch (error) {\n errors.push(asError(error));\n }\n\n let registered: boolean;\n try {\n registered = await isWorktreeRegistered(projectRoot, worktreePath);\n } catch (error) {\n errors.push(asError(error));\n throw new AggregateError(errors, `Could not verify temporary worktree deregistration; preserved ${path.dirname(worktreePath)}`);\n }\n\n if (registered) {\n try {\n await runGit(projectRoot, [\"worktree\", \"unlock\", \"--\", worktreePath]);\n } catch {\n // An unlocked or missing worktree does not need an unlock step.\n }\n try {\n await runGit(projectRoot, [\"worktree\", \"remove\", \"--force\", \"--force\", \"--\", worktreePath]);\n } catch (error) {\n errors.push(asError(error));\n }\n\n try {\n registered = await isWorktreeRegistered(projectRoot, worktreePath);\n } catch (error) {\n errors.push(asError(error));\n throw new AggregateError(errors, `Could not verify temporary worktree deregistration; preserved ${path.dirname(worktreePath)}`);\n }\n }\n\n if (registered && !(await pathExists(worktreePath))) {\n try {\n await pruneExactMissingWorktreeRegistration(projectRoot, worktreePath);\n registered = await isWorktreeRegistered(projectRoot, worktreePath);\n } catch (error) {\n errors.push(asError(error));\n }\n }\n\n if (registered) {\n errors.push(new Error(`Temporary worktree remains registered: ${worktreePath}`));\n throw new AggregateError(errors, `Failed to deregister temporary worktree; preserved ${path.dirname(worktreePath)}`);\n }\n\n try {\n await fsPromises.rm(path.dirname(worktreePath), { recursive: true, force: true });\n } catch (error) {\n errors.push(asError(error));\n throw new AggregateError(errors, `Deregistered the temporary worktree but could not remove ${path.dirname(worktreePath)}`);\n }\n}\n\nasync function cleanupTemporaryWorktree(\n projectRoot: string,\n worktreePath: string,\n temporaryRoot: string,\n): Promise<void> {\n let registered: boolean;\n try {\n registered = await isWorktreeRegistered(projectRoot, worktreePath);\n } catch (error) {\n throw new AggregateError(\n [asError(error)],\n `Could not verify temporary worktree registration; preserved ${temporaryRoot}`,\n );\n }\n\n if (registered) {\n await removeWorktree(projectRoot, worktreePath);\n return;\n }\n\n await fsPromises.rm(temporaryRoot, { recursive: true, force: true });\n}\n\nexport async function withMaterializedBranch<T>(\n request: BranchMaterializationRequest,\n callback: (worktreePath: string, info: BranchMaterializationInfo) => Promise<T>,\n): Promise<{ value: T; info: BranchMaterializationInfo }> {\n assertValidGitRefName(request.branch, \"Branch name\");\n if (request.ref !== undefined) {\n assertValidGitRefName(request.ref, \"Git ref\");\n }\n if (request.expectedCommit !== undefined && !isFullGitCommit(request.expectedCommit)) {\n throw new Error(`Expected Git commit is invalid: ${JSON.stringify(request.expectedCommit)}`);\n }\n if (request.pr !== undefined && (!Number.isInteger(request.pr) || request.pr <= 0)) {\n throw new Error(`Pull request number must be a positive integer: ${request.pr}`);\n }\n\n const resolved = await resolveCommit(request);\n if (!resolved) {\n throw new Error(\n `Git ref ${JSON.stringify(request.ref ?? request.branch)} is not available locally. `\n + \"For an unfetched branch, pass a remote-qualified name such as origin/feature.\",\n );\n }\n\n const temporaryRoot = await fsPromises.mkdtemp(path.join(os.tmpdir(), \"codebase-index-branch-\"));\n const worktreePath = path.join(temporaryRoot, \"worktree\");\n const hooksPath = path.join(temporaryRoot, \"hooks\");\n await fsPromises.mkdir(hooksPath);\n const info: BranchMaterializationInfo = {\n branch: request.branch,\n commit: resolved.commit,\n source: resolved.source,\n fetched: resolved.fetched,\n };\n\n let result: { value: T; info: BranchMaterializationInfo } | undefined;\n let operationError: unknown;\n try {\n await runGit(request.projectRoot, [\n \"-c\",\n `core.hooksPath=${hooksPath}`,\n \"worktree\",\n \"add\",\n \"--detach\",\n \"--\",\n worktreePath,\n resolved.commit,\n ]);\n\n const materializedHead = await tryResolveCommit(worktreePath, \"HEAD\");\n if (materializedHead !== resolved.commit) {\n throw new Error(\n `Materialized worktree HEAD ${materializedHead ?? \"did not resolve\"}; expected ${resolved.commit}.`,\n );\n }\n\n const value = await callback(worktreePath, info);\n result = { value, info };\n } catch (error) {\n operationError = error;\n }\n\n let cleanupError: unknown;\n try {\n await cleanupTemporaryWorktree(request.projectRoot, worktreePath, temporaryRoot);\n } catch (error) {\n cleanupError = error;\n }\n\n if (operationError !== undefined && cleanupError !== undefined) {\n throw new AggregateError(\n [asError(operationError), asError(cleanupError)],\n `${getErrorMessage(operationError)} Cleanup also failed: ${getErrorMessage(cleanupError)}`,\n );\n }\n if (operationError !== undefined) throw operationError;\n if (cleanupError !== undefined) throw cleanupError;\n return result!;\n}\n","import { execFile } from \"child_process\";\nimport { randomBytes } from \"crypto\";\nimport { promisify } from \"util\";\n\nconst execFileAsync = promisify(execFile);\nconst FULL_COMMIT_RE = /^[0-9a-f]{40}$/i;\nconst SAFE_REMOTE_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,255}$/;\nconst FORBIDDEN_REF_CHARS = new Set([\"~\", \"^\", \":\", \"?\", \"*\", \"\\\\\", \"[\", \"]\"]);\n\nexport type BranchMaterializationSource =\n | \"local\"\n | \"remote-fetch\"\n | \"pull-ref\"\n | \"gh\";\n\nexport interface BranchMaterializationRequest {\n projectRoot: string;\n branch: string;\n ref?: string;\n expectedCommit?: string;\n pr?: number;\n repository?: string;\n}\n\nexport interface BranchMaterializationInfo {\n branch: string;\n commit: string;\n source: BranchMaterializationSource;\n fetched: boolean;\n}\n\nexport interface LocalPullRequestRefs {\n headCommit: string;\n baseCommit?: string;\n}\n\ninterface ResolvedCommit {\n commit: string;\n source: Exclude<BranchMaterializationSource, \"gh\">;\n fetched: boolean;\n}\n\nexport function getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction contextualizeError(prefix: string, error: unknown): Error {\n if (error instanceof AggregateError) {\n return new AggregateError(\n Array.from(error.errors, asError),\n `${prefix}: ${error.message}`,\n );\n }\n return new Error(`${prefix}: ${getErrorMessage(error)}`);\n}\n\nexport function isFullGitCommit(value: string): boolean {\n return FULL_COMMIT_RE.test(value);\n}\n\nexport function isValidGitRefName(value: string): boolean {\n if (value === \"HEAD\" || isFullGitCommit(value)) return true;\n if (!value || value.length > 1024 || value.startsWith(\"-\") || value.startsWith(\"/\") || value.endsWith(\"/\")) {\n return false;\n }\n if (\n Array.from(value).some((character) => {\n const code = character.charCodeAt(0);\n return code <= 0x20 || code === 0x7f || FORBIDDEN_REF_CHARS.has(character);\n })\n || value.includes(\"..\")\n || value.includes(\"@{\")\n || value.includes(\"//\")\n || value.endsWith(\".\")\n ) {\n return false;\n }\n\n return value.split(\"/\").every((component) =>\n component.length > 0\n && !component.startsWith(\".\")\n && !component.endsWith(\".\")\n && !component.endsWith(\".lock\")\n );\n}\n\nexport function assertValidGitRefName(value: string, label = \"Git ref\"): void {\n if (!isValidGitRefName(value)) {\n throw new Error(`${label} is invalid: ${JSON.stringify(value)}`);\n }\n}\n\nexport function isValidGitRemoteName(value: string): boolean {\n return SAFE_REMOTE_NAME_RE.test(value);\n}\n\nfunction assertValidGitRemoteName(value: string): void {\n if (!isValidGitRemoteName(value)) {\n throw new Error(`Git remote name is unsafe: ${JSON.stringify(value)}`);\n }\n}\n\nexport async function runGitRaw(\n projectRoot: string,\n args: string[],\n options: { timeout?: number } = {},\n): Promise<string> {\n const { stdout } = await execFileAsync(\"git\", args, {\n cwd: projectRoot,\n timeout: options.timeout ?? 30000,\n encoding: \"utf8\",\n maxBuffer: 10 * 1024 * 1024,\n env: {\n ...process.env,\n GIT_TERMINAL_PROMPT: \"0\",\n LC_ALL: \"C\",\n },\n });\n return stdout;\n}\n\nexport async function runGit(\n projectRoot: string,\n args: string[],\n options: { timeout?: number } = {},\n): Promise<string> {\n return (await runGitRaw(projectRoot, args, options)).trim();\n}\n\nexport async function tryResolveCommit(projectRoot: string, ref: string): Promise<string | null> {\n try {\n const commit = await runGit(projectRoot, [\n \"rev-parse\",\n \"--verify\",\n \"--quiet\",\n \"--end-of-options\",\n `${ref}^{commit}`,\n ]);\n return isFullGitCommit(commit) ? commit.toLowerCase() : null;\n } catch {\n return null;\n }\n}\n\nexport async function resolveLocalGitCommit(projectRoot: string, ref: string): Promise<string | null> {\n assertValidGitRefName(ref);\n return tryResolveCommit(projectRoot, ref);\n}\n\nexport async function resolveLocalPullRequestRefs(\n projectRoot: string,\n pr: number,\n): Promise<LocalPullRequestRefs | null> {\n if (!Number.isInteger(pr) || pr <= 0) {\n throw new Error(`Pull request number must be a positive integer: ${pr}`);\n }\n\n const headRef = `refs/pull/${pr}/head`;\n const mergeRef = `refs/pull/${pr}/merge`;\n const headCommit = await tryResolveCommit(projectRoot, headRef);\n const mergeHeadCommit = await tryResolveCommit(projectRoot, `${mergeRef}^2`);\n const resolvedHeadCommit = headCommit ?? mergeHeadCommit;\n if (!resolvedHeadCommit) return null;\n\n const baseCommit = mergeHeadCommit === resolvedHeadCommit\n ? await tryResolveCommit(projectRoot, `${mergeRef}^1`)\n : null;\n return {\n headCommit: resolvedHeadCommit,\n baseCommit: baseCommit ?? undefined,\n };\n}\n\nfunction localCandidates(ref: string): string[] {\n if (ref === \"HEAD\" || isFullGitCommit(ref) || ref.startsWith(\"refs/\")) {\n return [ref];\n }\n return [`refs/heads/${ref}`];\n}\n\nasync function resolveFirstLocalCommit(projectRoot: string, refs: string[]): Promise<string | null> {\n for (const ref of refs) {\n const commit = await tryResolveCommit(projectRoot, ref);\n if (commit) return commit;\n }\n return null;\n}\n\nfunction parseRemoteBranch(ref: string): { remote: string; branch: string; explicit: boolean } | null {\n const remoteRefMatch = ref.match(/^refs\\/remotes\\/([^/]+)\\/(.+)$/);\n if (remoteRefMatch) {\n return { remote: remoteRefMatch[1], branch: remoteRefMatch[2], explicit: true };\n }\n\n if (ref.startsWith(\"refs/\") || ref === \"HEAD\" || isFullGitCommit(ref)) {\n return null;\n }\n\n const slash = ref.indexOf(\"/\");\n if (slash <= 0 || slash === ref.length - 1) return null;\n return { remote: ref.slice(0, slash), branch: ref.slice(slash + 1), explicit: false };\n}\n\nasync function getRemoteNames(projectRoot: string): Promise<string[]> {\n const output = await runGitRaw(projectRoot, [\"remote\"]);\n return output.split(\"\\n\").filter(Boolean);\n}\n\nasync function getConfiguredRemote(projectRoot: string, remote: string): Promise<string | null> {\n assertValidGitRemoteName(remote);\n const remotes = await getRemoteNames(projectRoot);\n return remotes.includes(remote) ? remote : null;\n}\n\nfunction normalizeRepository(value: string): string | null {\n if (!value || value.startsWith(\"-\") || /[\\0\\r\\n]/.test(value)) return null;\n const trimmed = value.trim().replace(/\\/$/, \"\").replace(/\\.git$/i, \"\");\n const scpMatch = trimmed.match(/^(?:[^@]+@)?([^:]+):(.+)$/);\n const urlValue = scpMatch ? `ssh://${scpMatch[1]}/${scpMatch[2]}` : trimmed;\n try {\n const url = new URL(urlValue);\n const repositoryPath = url.pathname.replace(/^\\/+|\\/+$/g, \"\");\n if (!url.hostname || !repositoryPath) return null;\n return `${url.hostname.toLowerCase()}/${repositoryPath.toLowerCase()}`;\n } catch {\n return null;\n }\n}\n\nasync function resolvePullRequestRepository(\n projectRoot: string,\n repository?: string,\n): Promise<string> {\n const remotes = (await getRemoteNames(projectRoot)).filter(isValidGitRemoteName);\n if (repository) {\n const expectedRepository = normalizeRepository(repository);\n if (!expectedRepository) {\n throw new Error(`PR repository URL is invalid: ${JSON.stringify(repository)}`);\n }\n\n for (const remote of remotes) {\n const remoteUrl = await runGit(projectRoot, [\"remote\", \"get-url\", \"--\", remote]);\n if (normalizeRepository(remoteUrl) === expectedRepository) {\n return remote;\n }\n }\n\n return repository;\n }\n\n if (remotes.length === 1) return remotes[0];\n throw new Error(\n remotes.length === 0\n ? \"Cannot fetch the PR head because this repository has no safe Git remotes.\"\n : \"Cannot safely choose a PR remote because multiple Git remotes are configured.\",\n );\n}\n\nasync function deleteTemporaryRef(\n projectRoot: string,\n temporaryRef: string,\n expectedCommit: string,\n): Promise<void> {\n await runGit(projectRoot, [\"update-ref\", \"-d\", temporaryRef, expectedCommit]);\n const remaining = await tryResolveCommit(projectRoot, temporaryRef);\n if (remaining) {\n throw new Error(`Temporary Git ref ${temporaryRef} remains at ${remaining}.`);\n }\n}\n\nasync function fetchCommitThroughTemporaryRef(\n projectRoot: string,\n repository: string,\n sourceRef: string,\n expectedCommit?: string,\n): Promise<string> {\n assertValidGitRefName(sourceRef, \"Fetch source ref\");\n if (isValidGitRemoteName(repository)) {\n const configuredRemote = await getConfiguredRemote(projectRoot, repository);\n if (!configuredRemote) {\n throw new Error(`Git remote is not configured: ${JSON.stringify(repository)}`);\n }\n } else if (!normalizeRepository(repository)) {\n throw new Error(`Git fetch repository is invalid: ${JSON.stringify(repository)}`);\n }\n\n const temporaryRef = `refs/codebase-index/fetch-${process.pid}-${randomBytes(12).toString(\"hex\")}`;\n assertValidGitRefName(temporaryRef, \"Temporary Git ref\");\n let commit: string | null = null;\n let fetchError: unknown;\n\n try {\n await runGit(projectRoot, [\n \"fetch\",\n \"--no-tags\",\n \"--no-write-fetch-head\",\n \"--\",\n repository,\n `+${sourceRef}:${temporaryRef}`,\n ]);\n commit = await tryResolveCommit(projectRoot, temporaryRef);\n if (!commit) {\n throw new Error(`Fetched ref ${JSON.stringify(sourceRef)} did not resolve to a commit.`);\n }\n if (expectedCommit && commit !== expectedCommit.toLowerCase()) {\n throw new Error(\n `Fetched ref ${JSON.stringify(sourceRef)} resolved to ${commit}, but authoritative metadata requires ${expectedCommit}.`,\n );\n }\n } catch (error) {\n fetchError = error;\n }\n\n let cleanupError: unknown;\n try {\n const temporaryCommit = commit ?? await tryResolveCommit(projectRoot, temporaryRef);\n if (temporaryCommit) {\n await deleteTemporaryRef(projectRoot, temporaryRef, temporaryCommit);\n }\n } catch (error) {\n cleanupError = error;\n }\n\n if (fetchError !== undefined && cleanupError !== undefined) {\n throw new AggregateError(\n [asError(fetchError), asError(cleanupError)],\n `${getErrorMessage(fetchError)} Temporary ref cleanup also failed: ${getErrorMessage(cleanupError)}`,\n );\n }\n if (fetchError !== undefined) throw fetchError;\n if (cleanupError !== undefined) throw cleanupError;\n return commit!;\n}\n\nexport async function resolveCommit(\n request: BranchMaterializationRequest,\n): Promise<ResolvedCommit | null> {\n const requestedRef = request.ref ?? request.branch;\n const authoritativeCommit = request.expectedCommit?.toLowerCase();\n\n if (request.pr !== undefined) {\n const expectedCommit = authoritativeCommit\n ?? (isFullGitCommit(requestedRef) ? requestedRef.toLowerCase() : undefined);\n const localPullCommit = await tryResolveCommit(request.projectRoot, `refs/pull/${request.pr}/head`);\n if (localPullCommit && (!expectedCommit || localPullCommit === expectedCommit)) {\n return { commit: localPullCommit, source: \"pull-ref\", fetched: false };\n }\n\n if (expectedCommit && await tryResolveCommit(request.projectRoot, expectedCommit)) {\n return { commit: expectedCommit, source: \"local\", fetched: false };\n }\n\n const repository = await resolvePullRequestRepository(request.projectRoot, request.repository);\n try {\n const commit = await fetchCommitThroughTemporaryRef(\n request.projectRoot,\n repository,\n `refs/pull/${request.pr}/head`,\n expectedCommit,\n );\n return { commit, source: \"pull-ref\", fetched: true };\n } catch (error) {\n throw contextualizeError(\n `Could not fetch PR #${request.pr} from ${JSON.stringify(repository)}`,\n error,\n );\n }\n }\n\n const remoteBranch = parseRemoteBranch(requestedRef);\n if (remoteBranch) {\n if (!isValidGitRemoteName(remoteBranch.remote)) {\n throw new Error(`Git remote name is unsafe: ${JSON.stringify(remoteBranch.remote)}`);\n }\n const remote = await getConfiguredRemote(request.projectRoot, remoteBranch.remote);\n if (remote) {\n try {\n const commit = await fetchCommitThroughTemporaryRef(\n request.projectRoot,\n remote,\n `refs/heads/${remoteBranch.branch}`,\n authoritativeCommit,\n );\n return { commit, source: \"remote-fetch\", fetched: true };\n } catch (error) {\n throw contextualizeError(\n `Could not fetch branch ${JSON.stringify(requestedRef)} from remote ${JSON.stringify(remote)}`,\n error,\n );\n }\n }\n if (remoteBranch.explicit) {\n throw new Error(`Git remote is not configured: ${JSON.stringify(remoteBranch.remote)}`);\n }\n }\n\n const localCommit = await resolveFirstLocalCommit(request.projectRoot, localCandidates(requestedRef));\n if (!localCommit) return null;\n if (authoritativeCommit && localCommit !== authoritativeCommit) {\n throw new Error(\n `Git ref ${JSON.stringify(requestedRef)} resolved to ${localCommit}, but authoritative metadata requires ${authoritativeCommit}.`,\n );\n }\n return { commit: localCommit, source: \"local\", fetched: false };\n}\n\nexport async function resolveGitCommit(projectRoot: string, ref: string): Promise<string | null> {\n assertValidGitRefName(ref);\n const resolved = await resolveCommit({ projectRoot, branch: ref, ref });\n return resolved?.commit ?? null;\n}\n","import { execFile } from \"child_process\";\nimport { realpathSync } from \"fs\";\nimport * as path from \"path\";\nimport { promisify } from \"util\";\n\nimport {\n assertValidGitRefName,\n isFullGitCommit,\n resolveGitCommit,\n resolveLocalPullRequestRefs,\n} from \"../git/branch-materialization.js\";\n\nconst execFileAsync = promisify(execFile);\nconst GH_PR_VIEW_FIELDS = [\n \"number\",\n \"headRefName\",\n \"headRefOid\",\n \"headRepository\",\n \"headRepositoryOwner\",\n \"baseRefName\",\n \"url\",\n \"files\",\n].join(\",\");\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error);\n}\n\nexport interface ChangedFilesResult {\n files: string[];\n baseBranch: string;\n source: \"gh\" | \"git\";\n catalogIdentity: string;\n headRefName?: string;\n headRef?: string;\n baseRepository?: string;\n baseRepositoryIdentity?: string;\n headRepositoryIdentity?: string;\n}\n\nexport interface GetChangedFilesOptions {\n pr?: number;\n branch?: string;\n projectRoot: string;\n baseBranch?: string;\n}\n\ninterface GhRepositoryOwner {\n login?: string;\n name?: string;\n}\n\ninterface GhRepository {\n name?: string;\n nameWithOwner?: string;\n owner?: GhRepositoryOwner;\n}\n\ninterface GhPrViewResponse {\n number?: number;\n headRefName?: string;\n headRefOid?: string;\n headRepository?: GhRepository;\n headRepositoryOwner?: GhRepositoryOwner;\n baseRefName?: string;\n url?: string;\n files?: Array<{ path?: string }>;\n}\n\ninterface RepositoryFromPrUrl {\n url: string;\n identity: string;\n host: string;\n}\n\nexport function createPullRequestCatalogIdentity(\n baseRepositoryIdentity: string,\n pr: number,\n headRepositoryIdentity: string,\n): string {\n if (!baseRepositoryIdentity || !headRepositoryIdentity) {\n throw new Error(\"Pull request catalog identity requires base and head repository identities.\");\n }\n if (!Number.isInteger(pr) || pr <= 0) {\n throw new Error(`Pull request number must be a positive integer: ${pr}`);\n }\n return `pull-request:${encodeURIComponent(baseRepositoryIdentity)}:${pr}:${encodeURIComponent(headRepositoryIdentity)}`;\n}\n\nexport async function getChangedFiles(\n opts: GetChangedFilesOptions,\n): Promise<ChangedFilesResult> {\n const { pr, branch, projectRoot, baseBranch = \"main\" } = opts;\n\n if (pr !== undefined) {\n return getChangedFilesForPr(pr, projectRoot);\n }\n\n return getChangedFilesForBranch(branch, projectRoot, baseBranch);\n}\n\nasync function getChangedFilesForPr(\n pr: number,\n projectRoot: string,\n): Promise<ChangedFilesResult> {\n if (!Number.isInteger(pr) || pr <= 0) {\n throw new Error(`Pull request number must be a positive integer: ${pr}`);\n }\n\n let ghError: unknown;\n try {\n const { stdout } = await execFileAsync(\n \"gh\",\n [\"pr\", \"view\", String(pr), \"--json\", GH_PR_VIEW_FIELDS],\n { cwd: projectRoot, timeout: 30000, encoding: \"utf8\" },\n );\n\n const data = JSON.parse(stdout) as GhPrViewResponse;\n const baseRepository = getRepositoryFromPrUrl(data.url, pr);\n const headRepositoryIdentity = getHeadRepositoryIdentity(data, baseRepository.host);\n if (data.number !== pr) {\n throw new Error(`gh returned PR #${String(data.number)} while PR #${pr} was requested.`);\n }\n if (!data.headRefName) throw new Error(\"gh did not return headRefName.\");\n if (!data.baseRefName) throw new Error(\"gh did not return baseRefName.\");\n const headRefOid = data.headRefOid;\n if (!headRefOid || !isFullGitCommit(headRefOid)) {\n throw new Error(\"gh did not return a full authoritative headRefOid.\");\n }\n if (!Array.isArray(data.files) || data.files.some((file) => typeof file.path !== \"string\")) {\n throw new Error(\"gh returned invalid changed-file metadata.\");\n }\n\n assertValidGitRefName(data.headRefName, \"PR head branch\");\n assertValidGitRefName(data.baseRefName, \"PR base branch\");\n const headRef = headRefOid.toLowerCase();\n return {\n files: normalizeFiles(data.files.map((file) => file.path!), projectRoot),\n baseBranch: data.baseRefName,\n source: \"gh\",\n catalogIdentity: createPullRequestCatalogIdentity(\n baseRepository.identity,\n pr,\n headRepositoryIdentity,\n ),\n headRefName: data.headRefName,\n headRef,\n baseRepository: baseRepository.url,\n baseRepositoryIdentity: baseRepository.identity,\n headRepositoryIdentity,\n };\n } catch (error) {\n ghError = error;\n }\n\n const localRefs = await resolveLocalPullRequestRefs(projectRoot, pr);\n if (!localRefs?.baseCommit) {\n const ghFailure = ghError === undefined\n ? \"gh returned incomplete PR head/base metadata\"\n : getErrorMessage(ghError);\n throw new Error(\n `Failed to retrieve an authoritative base for PR #${pr}: ${ghFailure}. `\n + `The safe local fallback requires refs/pull/${pr}/merge with parents matching refs/pull/${pr}/head.`,\n );\n }\n\n const localRepositoryIdentity = getLocalRepositoryIdentity(projectRoot);\n const headRepositoryIdentity = `${localRepositoryIdentity}/refs/pull/${pr}/head`;\n return {\n files: await getDiffFiles(projectRoot, localRefs.baseCommit, localRefs.headCommit),\n baseBranch: localRefs.baseCommit,\n source: \"git\",\n catalogIdentity: createPullRequestCatalogIdentity(\n localRepositoryIdentity,\n pr,\n headRepositoryIdentity,\n ),\n headRefName: `pr/${pr}`,\n headRef: localRefs.headCommit,\n baseRepositoryIdentity: localRepositoryIdentity,\n headRepositoryIdentity,\n };\n}\n\nfunction getRepositoryFromPrUrl(prUrl: string | undefined, expectedPr: number): RepositoryFromPrUrl {\n if (!prUrl) throw new Error(\"gh did not return the PR URL.\");\n let url: URL;\n try {\n url = new URL(prUrl);\n } catch {\n throw new Error(`gh returned an invalid PR URL: ${JSON.stringify(prUrl)}`);\n }\n\n const match = url.pathname.match(/^\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)\\/?$/);\n if (!match || Number(match[3]) !== expectedPr) {\n throw new Error(`gh returned a PR URL that does not identify PR #${expectedPr}: ${JSON.stringify(prUrl)}`);\n }\n\n const owner = match[1].toLowerCase();\n const repository = match[2].replace(/\\.git$/i, \"\").toLowerCase();\n const host = url.hostname.toLowerCase();\n if (!host || !owner || !repository) {\n throw new Error(`gh returned an invalid PR repository URL: ${JSON.stringify(prUrl)}`);\n }\n return {\n url: `${url.protocol}//${url.host}/${match[1]}/${match[2].replace(/\\.git$/i, \"\")}`,\n identity: `${host}/${owner}/${repository}`,\n host,\n };\n}\n\nfunction getHeadRepositoryIdentity(data: GhPrViewResponse, host: string): string {\n const nameWithOwner = data.headRepository?.nameWithOwner;\n if (nameWithOwner) {\n const match = nameWithOwner.match(/^([^/]+)\\/([^/]+)$/);\n if (match) return `${host}/${match[1].toLowerCase()}/${match[2].replace(/\\.git$/i, \"\").toLowerCase()}`;\n }\n\n const owner = data.headRepositoryOwner?.login\n ?? data.headRepositoryOwner?.name\n ?? data.headRepository?.owner?.login\n ?? data.headRepository?.owner?.name;\n const repository = data.headRepository?.name;\n if (!owner || !repository || owner.includes(\"/\") || repository.includes(\"/\")) {\n throw new Error(\"gh did not return an authoritative head repository identity.\");\n }\n return `${host}/${owner.toLowerCase()}/${repository.replace(/\\.git$/i, \"\").toLowerCase()}`;\n}\n\nfunction getLocalRepositoryIdentity(projectRoot: string): string {\n let canonicalRoot = path.resolve(projectRoot);\n try {\n canonicalRoot = realpathSync.native(canonicalRoot);\n } catch {\n // A missing realpath will be diagnosed by the subsequent Git operation.\n }\n return `local:${canonicalRoot}`;\n}\n\nasync function getChangedFilesForBranch(\n branch: string | undefined,\n projectRoot: string,\n baseBranch: string,\n): Promise<ChangedFilesResult> {\n const targetBranch = branch || (await getCurrentBranch(projectRoot));\n assertValidGitRefName(baseBranch, \"Base branch\");\n assertValidGitRefName(targetBranch, \"Branch name\");\n\n const resolvedBase = await resolveGitCommit(projectRoot, baseBranch);\n if (!resolvedBase) {\n throw new Error(`Could not resolve base branch ${JSON.stringify(baseBranch)} to a commit.`);\n }\n const resolvedHead = await resolveGitCommit(projectRoot, targetBranch);\n if (!resolvedHead) {\n throw new Error(`Could not resolve branch ${JSON.stringify(targetBranch)} to a commit.`);\n }\n const mergeBase = await getMergeBase(projectRoot, resolvedBase, resolvedHead);\n\n return {\n files: await getDiffFiles(projectRoot, mergeBase, resolvedHead),\n baseBranch,\n source: \"git\",\n catalogIdentity: targetBranch,\n headRefName: targetBranch,\n headRef: resolvedHead,\n };\n}\n\nasync function getDiffFiles(\n projectRoot: string,\n baseRef: string,\n headRef: string,\n): Promise<string[]> {\n if (!isFullGitCommit(baseRef) || !isFullGitCommit(headRef)) {\n throw new Error(\"Changed-file diff requires fully resolved commit OIDs.\");\n }\n const { stdout } = await execFileAsync(\n \"git\",\n [\"diff\", \"--name-only\", \"-z\", `${baseRef}...${headRef}`, \"--\"],\n { cwd: projectRoot, timeout: 30000, encoding: \"utf8\" },\n );\n return normalizeFiles(stdout.split(\"\\0\"), projectRoot);\n}\n\nasync function getCurrentBranch(projectRoot: string): Promise<string> {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"branch\", \"--show-current\"],\n { cwd: projectRoot, timeout: 30000, encoding: \"utf8\" },\n );\n return stdout.trim() || \"HEAD\";\n}\n\nasync function getMergeBase(\n projectRoot: string,\n baseCommit: string,\n headCommit: string,\n): Promise<string> {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"merge-base\", \"--\", baseCommit, headCommit],\n { cwd: projectRoot, timeout: 30000, encoding: \"utf8\" },\n );\n const commit = stdout.trim().toLowerCase();\n if (!isFullGitCommit(commit)) {\n throw new Error(\"git merge-base did not return a full commit OID.\");\n }\n return commit;\n}\n\nfunction normalizeFiles(rawFiles: string[], projectRoot: string): string[] {\n const root = path.resolve(projectRoot);\n const seen = new Set<string>();\n const result: string[] = [];\n\n for (const raw of rawFiles) {\n if (raw.length === 0) continue;\n\n const absolute = path.resolve(root, raw);\n const relative = path.relative(root, absolute);\n if (path.isAbsolute(raw) || relative === \"..\" || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {\n throw new Error(`Changed file escapes the project root: ${JSON.stringify(raw)}`);\n }\n\n const cleaned = relative.startsWith(`.${path.sep}`)\n ? relative.slice(2)\n : relative;\n if (!seen.has(cleaned)) {\n seen.add(cleaned);\n result.push(cleaned);\n }\n }\n\n return result;\n}\n","import { execFile } from \"child_process\";\nimport * as path from \"path\";\nimport { promisify } from \"util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface GitBlameMetadata {\n readonly sha: string;\n readonly author: string;\n readonly authorEmail: string;\n readonly committedAt: number;\n readonly summary: string;\n}\n\ninterface MutableBlameMetadata {\n sha: string;\n author: string;\n authorEmail: string;\n committedAt: number;\n summary: string;\n lines: number;\n}\n\nexport function parseGitBlamePorcelain(output: string): GitBlameMetadata | undefined {\n const commits = new Map<string, MutableBlameMetadata>();\n let current: MutableBlameMetadata | undefined;\n\n for (const line of output.split(\"\\n\")) {\n if (/^[0-9a-f]{40} /.test(line)) {\n const sha = line.slice(0, 40);\n current = commits.get(sha) ?? {\n sha,\n author: \"\",\n authorEmail: \"\",\n committedAt: 0,\n summary: \"\",\n lines: 0,\n };\n commits.set(sha, current);\n continue;\n }\n\n if (!current) {\n continue;\n }\n\n if (line.startsWith(\"author \")) {\n current.author = line.slice(\"author \".length);\n } else if (line.startsWith(\"author-mail \")) {\n current.authorEmail = line.slice(\"author-mail \".length).replace(/^<|>$/g, \"\");\n } else if (line.startsWith(\"author-time \")) {\n current.committedAt = Number.parseInt(line.slice(\"author-time \".length), 10);\n } else if (line.startsWith(\"summary \")) {\n current.summary = line.slice(\"summary \".length);\n } else if (line.startsWith(\"\\t\")) {\n current.lines += 1;\n }\n }\n\n return Array.from(commits.values())\n .filter((commit) => commit.lines > 0)\n .sort((a, b) => b.lines - a.lines || b.committedAt - a.committedAt)[0];\n}\n\nexport async function getChunkGitBlame(\n projectRoot: string,\n filePath: string,\n startLine: number,\n endLine: number\n): Promise<GitBlameMetadata | undefined> {\n const relativePath = path.relative(projectRoot, filePath);\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"blame\", \"--line-porcelain\", \"-L\", `${startLine},${endLine}`, \"--\", relativePath],\n { cwd: projectRoot, timeout: 30000 }\n );\n return parseGitBlamePorcelain(stdout);\n } catch {\n return undefined;\n }\n}\n","import type { ChunkMetadata } from \"../native/index.js\";\nimport { analyzeQueryIntent, rankIntentAwareCandidates } from \"./intent-aware-ranking.js\";\n\nexport type RankedCandidate = { id: string; score: number; metadata: ChunkMetadata };\n\nexport function applyCommunityBoost(\n candidates: RankedCandidate[],\n sameCommunityCandidateIds: ReadonlySet<string>,\n boost: number,\n): RankedCandidate[] {\n if (boost <= 0 || sameCommunityCandidateIds.size === 0 || candidates.length <= 1) {\n return candidates;\n }\n\n const result = candidates.map((candidate) => sameCommunityCandidateIds.has(candidate.id)\n ? { ...candidate, score: candidate.score * (1 + boost) }\n : candidate);\n\n for (let index = 1; index < result.length; index += 1) {\n const candidate = result[index];\n const previous = result[index - 1];\n if (\n candidate && previous &&\n sameCommunityCandidateIds.has(candidate.id) &&\n !sameCommunityCandidateIds.has(previous.id) &&\n candidate.score > previous.score\n ) {\n result[index - 1] = candidate;\n result[index] = previous;\n }\n }\n\n return result;\n}\n\ninterface HybridRankOptions {\n fusionStrategy: \"weighted\" | \"rrf\";\n rrfK: number;\n rerankTopN: number;\n limit: number;\n hybridWeight: number;\n}\n\ninterface SemanticRankOptions {\n rerankTopN: number;\n limit: number;\n prioritizeSourcePaths?: boolean;\n}\n\nconst RANK_HYBRID_CACHE_LIMIT = 256;\nconst rankHybridResultsCache = new WeakMap<RankedCandidate[], WeakMap<RankedCandidate[], Map<string, RankedCandidate[]>>>();\n\nexport function classifyQueryIntentRaw(query: string): \"source\" | \"doc_test\" | \"neutral\" {\n const intent = analyzeQueryIntent(query);\n if (intent.primary === \"test\" || intent.primary === \"docs\") return \"doc_test\";\n if (intent.preferSourcePaths) return \"source\";\n return \"neutral\";\n}\n\nexport function fuseResultsWeighted(\n semanticResults: RankedCandidate[],\n keywordResults: RankedCandidate[],\n keywordWeight: number,\n limit: number\n): RankedCandidate[] {\n const semanticWeight = 1 - keywordWeight;\n const fusedScores = new Map<string, { score: number; metadata: ChunkMetadata }>();\n\n for (const r of semanticResults) {\n fusedScores.set(r.id, {\n score: r.score * semanticWeight,\n metadata: r.metadata,\n });\n }\n\n for (const r of keywordResults) {\n const existing = fusedScores.get(r.id);\n if (existing) {\n existing.score += r.score * keywordWeight;\n } else {\n fusedScores.set(r.id, {\n score: r.score * keywordWeight,\n metadata: r.metadata,\n });\n }\n }\n\n const results = Array.from(fusedScores.entries()).map(([id, data]) => ({\n id,\n score: data.score,\n metadata: data.metadata,\n }));\n\n results.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));\n return results.slice(0, limit);\n}\n\nexport function fuseResultsRrf(\n semanticResults: RankedCandidate[],\n keywordResults: RankedCandidate[],\n rrfK: number,\n limit: number\n): RankedCandidate[] {\n const maxPossibleRaw = 2 / (rrfK + 1);\n const rankByIdSemantic = new Map<string, number>();\n const rankByIdKeyword = new Map<string, number>();\n const metadataById = new Map<string, ChunkMetadata>();\n\n semanticResults.forEach((result, index) => {\n rankByIdSemantic.set(result.id, index + 1);\n metadataById.set(result.id, result.metadata);\n });\n\n keywordResults.forEach((result, index) => {\n rankByIdKeyword.set(result.id, index + 1);\n if (!metadataById.has(result.id)) {\n metadataById.set(result.id, result.metadata);\n }\n });\n\n const allIds = new Set<string>([...rankByIdSemantic.keys(), ...rankByIdKeyword.keys()]);\n const fused: RankedCandidate[] = [];\n\n for (const id of allIds) {\n const semanticRank = rankByIdSemantic.get(id);\n const keywordRank = rankByIdKeyword.get(id);\n\n const semanticScore = semanticRank ? 1 / (rrfK + semanticRank) : 0;\n const keywordScore = keywordRank ? 1 / (rrfK + keywordRank) : 0;\n\n const metadata = metadataById.get(id);\n if (!metadata) continue;\n\n fused.push({\n id,\n score: maxPossibleRaw > 0 ? (semanticScore + keywordScore) / maxPossibleRaw : 0,\n metadata,\n });\n }\n\n fused.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));\n return fused.slice(0, limit);\n}\n\nexport function rerankResults(\n query: string,\n candidates: RankedCandidate[],\n rerankTopN: number,\n options?: { prioritizeSourcePaths?: boolean }\n): RankedCandidate[] {\n return rankIntentAwareCandidates(query, candidates, rerankTopN, options);\n}\n\nfunction diversifyEntriesByFileAndSymbol<T>(\n entries: T[],\n getCandidate: (entry: T) => RankedCandidate,\n enabled: boolean\n): T[] {\n if (!enabled || entries.length <= 2) {\n return entries;\n }\n\n const groups = new Map<string, T[]>();\n const groupOrder: string[] = [];\n\n for (const entry of entries) {\n const candidate = getCandidate(entry);\n const filePath = candidate.metadata.filePath;\n if (!groups.has(filePath)) {\n groups.set(filePath, []);\n groupOrder.push(filePath);\n }\n groups.get(filePath)?.push(entry);\n }\n\n const diversifiedGroups = groupOrder.map((filePath) => {\n const group = groups.get(filePath) ?? [];\n return diversifyGroupBySymbol(group, getCandidate);\n });\n\n const result: T[] = [];\n let added = true;\n let round = 0;\n while (added) {\n added = false;\n for (const group of diversifiedGroups) {\n const entry = group[round];\n if (entry !== undefined) {\n result.push(entry);\n added = true;\n }\n }\n round += 1;\n }\n\n return result;\n}\n\nexport function diversifyCandidatesByFile(candidates: RankedCandidate[], enabled: boolean): RankedCandidate[] {\n return diversifyEntriesByFileAndSymbol(candidates, (candidate) => candidate, enabled);\n}\n\nfunction diversifyGroupBySymbol<T>(\n entries: T[],\n getCandidate: (entry: T) => RankedCandidate\n): T[] {\n if (entries.length <= 2) {\n return entries;\n }\n\n const seenKeys = new Set<string>();\n const primary: T[] = [];\n const remainder: T[] = [];\n\n for (const entry of entries) {\n const key = buildDiversityKey(getCandidate(entry).metadata);\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n primary.push(entry);\n } else {\n remainder.push(entry);\n }\n }\n\n return [...primary, ...remainder];\n}\n\nfunction buildDiversityKey(metadata: ChunkMetadata): string {\n const normalizedPath = metadata.filePath.toLowerCase();\n const normalizedName = (metadata.name ?? \"\").trim().toLowerCase();\n if (normalizedName.length > 0) {\n return `${normalizedPath}#${normalizedName}`;\n }\n return normalizedPath;\n}\n\nexport function rankHybridResults(\n query: string,\n semanticResults: RankedCandidate[],\n keywordResults: RankedCandidate[],\n options: HybridRankOptions & { prioritizeSourcePaths?: boolean }\n): RankedCandidate[] {\n const prioritizeSourcePaths = options.prioritizeSourcePaths ?? classifyQueryIntentRaw(query) === \"source\";\n const cacheKey = `${query}\\u0001${options.fusionStrategy}|${options.rrfK}|${options.hybridWeight}|${options.rerankTopN}|${options.limit}|${prioritizeSourcePaths ? 1 : 0}`;\n\n let byKeyword = rankHybridResultsCache.get(semanticResults);\n if (!byKeyword) {\n byKeyword = new WeakMap<RankedCandidate[], Map<string, RankedCandidate[]>>();\n rankHybridResultsCache.set(semanticResults, byKeyword);\n }\n\n let bucket = byKeyword.get(keywordResults);\n if (!bucket) {\n bucket = new Map<string, RankedCandidate[]>();\n byKeyword.set(keywordResults, bucket);\n } else {\n const cached = bucket.get(cacheKey);\n if (cached) {\n return cached;\n }\n }\n\n // Identifier-rich source queries often match many test assertions before their\n // implementation declarations. Keep a wider fused pool so intent-aware\n // reranking can prefer the production evidence rather than losing it early.\n const overfetchFactor = prioritizeSourcePaths ? 12 : 4;\n const overfetchLimit = Math.max(options.limit * overfetchFactor, options.limit);\n const fused = options.fusionStrategy === \"rrf\"\n ? fuseResultsRrf(semanticResults, keywordResults, options.rrfK, overfetchLimit)\n : fuseResultsWeighted(semanticResults, keywordResults, options.hybridWeight, overfetchLimit);\n\n const rerankPoolLimit = Math.max(overfetchLimit, options.rerankTopN * 3, options.limit * 6);\n const rerankPool = fused.slice(0, rerankPoolLimit);\n const ranked = rerankResults(query, rerankPool, options.rerankTopN, {\n prioritizeSourcePaths,\n });\n\n if (bucket.size >= RANK_HYBRID_CACHE_LIMIT) {\n const oldest = bucket.keys().next().value;\n if (oldest !== undefined) {\n bucket.delete(oldest);\n }\n }\n bucket.set(cacheKey, ranked);\n\n return ranked;\n}\n\nexport function rankSemanticOnlyResults(\n query: string,\n semanticResults: RankedCandidate[],\n options: SemanticRankOptions\n): RankedCandidate[] {\n const overfetchLimit = Math.max(options.limit * 4, options.limit);\n const bounded = semanticResults.slice(0, overfetchLimit);\n return rerankResults(query, bounded, options.rerankTopN, {\n prioritizeSourcePaths: options.prioritizeSourcePaths ?? false,\n });\n}\n","import { analyzeQueryIntent } from \"../indexer/intent-aware-ranking.js\";\n\nconst IDENTIFIER_RE = /[A-Za-z_$][A-Za-z0-9_$]*/g;\nconst QUOTED_BACKTICK_RE = /`([^`]+)`/g;\nconst QUOTED_SINGLE_RE = /'([^'\\\\]+)'/g;\nconst QUOTED_DOUBLE_RE = /\"([^\"]+)\"/g;\n\nconst SYMBOL_LIKE_RE = /^(?:[A-Za-z_$][A-Za-z0-9_$]*)$/;\nconst CAMEL_CASE_RE = /^[a-z_][A-Za-z0-9_$]*[A-Z][A-Za-z0-9_$]*$/;\nconst PASCAL_CASE_RE = /^[A-Z][A-Za-z0-9_$]*$/;\nconst SNAKE_CASE_RE = /^[a-z][a-z0-9_]*_[a-z0-9_]+$/;\n\nconst DEFINITION_INTENT_RE = /\\b(where|defined|definition|define|declaration|symbol|function|method|class|interface|type)\\b/i;\nconst STOP_WORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"at\",\n \"for\",\n \"find\",\n \"how\",\n \"i\",\n \"in\",\n \"is\",\n \"it\",\n \"of\",\n \"on\",\n \"that\",\n \"the\",\n \"definition\",\n \"show\",\n \"to\",\n \"where\",\n \"which\",\n \"what\",\n \"you\",\n \"your\",\n \"with\",\n]);\n\nfunction stripCallSuffix(token: string): string {\n return token.replace(/\\(\\s*\\)$/, \"\");\n}\n\nfunction isLikelySymbolName(token: string): boolean {\n if (!SYMBOL_LIKE_RE.test(token)) {\n return false;\n }\n\n if (STOP_WORDS.has(token.toLowerCase())) {\n return false;\n }\n\n return CAMEL_CASE_RE.test(token) || PASCAL_CASE_RE.test(token) || SNAKE_CASE_RE.test(token);\n}\n\nfunction extractQuotedIdentifiers(query: string): string[] {\n const identifiers = new Set<string>();\n\n for (const match of query.matchAll(QUOTED_BACKTICK_RE)) {\n const candidate = stripCallSuffix(match[1]!.trim());\n if (candidate && isLikelySymbolName(candidate)) {\n identifiers.add(candidate);\n }\n }\n\n for (const match of query.matchAll(QUOTED_SINGLE_RE)) {\n const candidate = stripCallSuffix(match[1]!.trim());\n if (candidate && isLikelySymbolName(candidate)) {\n identifiers.add(candidate);\n }\n }\n\n for (const match of query.matchAll(QUOTED_DOUBLE_RE)) {\n const candidate = stripCallSuffix(match[1]!.trim());\n if (candidate && isLikelySymbolName(candidate)) {\n identifiers.add(candidate);\n }\n }\n\n return [...identifiers];\n}\n\nfunction extractBareIdentifiers(query: string): string[] {\n const unquoted = query\n .replace(QUOTED_BACKTICK_RE, \" \")\n .replace(QUOTED_SINGLE_RE, \" \")\n .replace(QUOTED_DOUBLE_RE, \" \");\n\n const identifiers = new Set<string>();\n for (const match of unquoted.matchAll(IDENTIFIER_RE)) {\n const candidate = stripCallSuffix(match[0]);\n if (isLikelySymbolName(candidate)) {\n identifiers.add(candidate);\n }\n }\n\n return [...identifiers];\n}\n\nfunction isSingleMeaningfulToken(query: string, symbol: string): boolean {\n const tokens = query\n .replace(/[`'\"()]/g, \" \")\n .split(/[^A-Za-z0-9_$]+/)\n .map((token) => token.trim().toLowerCase())\n .filter((token) => token.length > 0)\n .filter((token) => !STOP_WORDS.has(token));\n\n return tokens.length === 1 && tokens[0] === symbol.toLowerCase();\n}\n\nexport function inferExactSymbolFromQuery(query: string): string | undefined {\n if (analyzeQueryIntent(query).explicitArtifactIntent) {\n return undefined;\n }\n\n const quoted = extractQuotedIdentifiers(query);\n if (quoted.length === 1) {\n return quoted[0];\n }\n if (quoted.length > 1) {\n return undefined;\n }\n\n const candidates = extractBareIdentifiers(query);\n if (candidates.length !== 1) {\n return undefined;\n }\n\n const candidate = candidates[0];\n if (DEFINITION_INTENT_RE.test(query)) {\n return candidate;\n }\n\n if (isSingleMeaningfulToken(query, candidate)) {\n return candidate;\n }\n\n return undefined;\n}\n","export const CALL_GRAPH_SYMBOL_CHUNK_TYPES = new Set([\n \"function_declaration\",\n \"function\",\n \"arrow_function\",\n \"export_statement\",\n \"method_definition\",\n \"class_declaration\",\n \"interface_declaration\",\n \"type_alias_declaration\",\n \"enum_declaration\",\n \"function_definition\",\n \"class_definition\",\n // Ruby module/class symbols that are declaration-bearing and navigable.\n \"class\",\n \"module\",\n \"class_specifier\",\n \"struct_specifier\",\n \"namespace_definition\",\n \"decorated_definition\",\n \"method_declaration\",\n \"type_declaration\",\n \"type_spec\",\n \"function_item\",\n \"impl_item\",\n \"struct_item\",\n \"enum_item\",\n \"trait_item\",\n \"mod_item\",\n \"trait_declaration\",\n \"trigger_declaration\",\n \"test_declaration\",\n \"struct_declaration\",\n \"union_declaration\",\n // Synthetic Swift declarations or declarations specific to tree-sitter-swift.\n \"actor_declaration\",\n \"extension_declaration\",\n \"protocol_declaration\",\n \"protocol_function_declaration\",\n \"init_declaration\",\n \"deinit_declaration\",\n \"subscript_declaration\",\n // GDScript declarations whose names participate in the call graph.\n // `function_definition` and `class_definition` are already in the set\n // above (shared with Python/C/Bash and Python, respectively).\n \"constructor_definition\",\n \"enum_definition\",\n \"signal_statement\",\n \"const_statement\",\n \"class_name_statement\",\n]);\n","import {\n analyzeQueryIntent,\n extractIntentIdentifierHints,\n isConfigPath,\n isDocumentationPath as isIntentDocumentationPath,\n isFixturePath,\n isLikelyImplementationPath as isIntentImplementationPath,\n isTestPath,\n normalizeRankingText,\n} from \"./intent-aware-ranking.js\";\nimport { classifyQueryIntentRaw, type RankedCandidate } from \"./search-ranking.js\";\nimport { CALL_GRAPH_SYMBOL_CHUNK_TYPES } from \"./call-graph-constants.js\";\n\nexport type ExternalRerankBand = \"implementation\" | \"documentation\" | \"test\" | \"config\" | \"other\";\n\nconst RANKING_TOKEN_CACHE_LIMIT = 4096;\n\nconst rankingQueryTokenCache = new Map<string, Set<string>>();\nconst rankingPathTokenCache = new Map<string, Set<string>>();\nconst rankingTextTokenCache = new Map<string, Set<string>>();\n\nconst STOPWORDS = new Set([\n \"the\", \"and\", \"for\", \"with\", \"from\", \"that\", \"this\", \"into\", \"using\", \"where\",\n \"what\", \"when\", \"why\", \"how\", \"are\", \"was\", \"were\", \"be\", \"been\", \"being\",\n \"find\", \"show\", \"get\", \"run\", \"use\", \"code\", \"function\", \"implementation\",\n \"retrieve\", \"results\", \"result\", \"search\", \"pipeline\", \"top\", \"in\", \"on\", \"of\",\n \"to\", \"by\", \"as\", \"or\", \"an\", \"a\",\n]);\n\nfunction setBoundedCache(\n cache: Map<string, Set<string>>,\n key: string,\n value: Set<string>\n): void {\n if (cache.size >= RANKING_TOKEN_CACHE_LIMIT) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) {\n cache.delete(oldest);\n }\n }\n cache.set(key, value);\n}\n\nexport function tokenizeTextForRanking(text: string): Set<string> {\n if (!text) {\n return new Set<string>();\n }\n\n const lowered = normalizeRankingText(text);\n const cache = rankingQueryTokenCache.get(lowered) ?? rankingTextTokenCache.get(lowered);\n if (cache) {\n return cache;\n }\n\n const tokens = new Set(\n lowered\n .replace(/[^\\p{L}\\p{N}_$\\s]/gu, \" \")\n .split(/\\s+/)\n .filter((token) => token.length > 1 && !STOPWORDS.has(token))\n );\n\n setBoundedCache(rankingQueryTokenCache, lowered, tokens);\n setBoundedCache(rankingTextTokenCache, lowered, tokens);\n return tokens;\n}\n\nexport function splitPathTokens(filePath: string): Set<string> {\n const lowered = normalizeRankingText(filePath);\n const cache = rankingPathTokenCache.get(lowered);\n if (cache) {\n return cache;\n }\n\n const normalized = lowered\n .replace(/[^\\p{L}\\p{N}/._-]/gu, \" \")\n .split(/[/._-]+/)\n .filter((token) => token.length > 1);\n const tokens = new Set(normalized);\n setBoundedCache(rankingPathTokenCache, lowered, tokens);\n return tokens;\n}\n\nexport function isTestOrDocPath(filePath: string): boolean {\n return isTestPath(filePath) || isFixturePath(filePath) || isIntentDocumentationPath(filePath);\n}\n\nexport function isLikelyImplementationPath(filePath: string): boolean {\n return isIntentImplementationPath(filePath);\n}\n\nexport function isDocumentationPath(filePath: string): boolean {\n return isIntentDocumentationPath(filePath);\n}\n\nexport function classifyExternalRerankBand(\n candidate: RankedCandidate,\n intent: ReturnType<typeof analyzeQueryIntent>\n): ExternalRerankBand {\n const isDocOrTest = isTestOrDocPath(candidate.metadata.filePath);\n const isDocumentation = isDocumentationPath(candidate.metadata.filePath);\n const isTest = isTestPath(candidate.metadata.filePath) || isFixturePath(candidate.metadata.filePath);\n const isConfig = isConfigPath(candidate.metadata.filePath);\n const isImplementation = isLikelyImplementationPath(candidate.metadata.filePath) &&\n isImplementationChunkType(candidate.metadata.chunkType);\n\n if (intent.preferSourcePaths) {\n if (isImplementation) return \"implementation\";\n if (isConfig) return \"config\";\n if (isDocumentation) return \"documentation\";\n if (isTest || isDocOrTest) return \"test\";\n return \"other\";\n }\n\n if (intent.primary === \"docs\") {\n if (isDocumentation) return \"documentation\";\n if (isConfig) return \"config\";\n if (isImplementation) return \"implementation\";\n if (isTest || isDocOrTest) return \"test\";\n return \"other\";\n }\n\n if (intent.primary === \"test\") {\n if (isTest || isDocOrTest) return \"test\";\n if (isDocumentation) return \"documentation\";\n if (isConfig) return \"config\";\n if (isImplementation) return \"implementation\";\n return \"other\";\n }\n\n if (intent.primary === \"config\") {\n if (isConfig) return \"config\";\n if (isImplementation) return \"implementation\";\n if (isDocumentation) return \"documentation\";\n if (isTest || isDocOrTest) return \"test\";\n return \"other\";\n }\n\n if (isImplementation) return \"implementation\";\n if (isConfig) return \"config\";\n if (isDocumentation) return \"documentation\";\n if (isTest || isDocOrTest) return \"test\";\n return \"other\";\n}\n\nexport function isImplementationChunkType(chunkType: string): boolean {\n return CALL_GRAPH_SYMBOL_CHUNK_TYPES.has(chunkType) || [\n \"export_statement\",\n \"function\",\n \"function_declaration\",\n \"method\",\n \"method_definition\",\n \"method_declaration\",\n \"protocol_function_declaration\",\n \"init_declaration\",\n \"deinit_declaration\",\n \"subscript_declaration\",\n \"class\",\n \"class_declaration\",\n \"actor_declaration\",\n \"extension_declaration\",\n \"interface\",\n \"protocol_declaration\",\n \"type\",\n \"enum\",\n \"enum_declaration\",\n \"struct_declaration\",\n \"module\",\n ].includes(chunkType);\n}\n\nexport function extractIdentifierHints(query: string): string[] {\n return extractIntentIdentifierHints(query);\n}\n\nexport function extractCodeTermHints(query: string): string[] {\n const terms = query.match(/[A-Za-z_][A-Za-z0-9_]*/g) ?? [];\n return terms\n .map((term) => term.toLowerCase())\n .filter((term) => term.length >= 3)\n .filter((term) => !STOPWORDS.has(term));\n}\n\nexport function normalizeIdentifierVariants(identifier: string): string[] {\n const lower = normalizeRankingText(identifier);\n const compact = lower.replace(/[^\\p{L}\\p{N}]/gu, \"\");\n const snake = identifier\n .normalize(\"NFKC\")\n .replace(/([\\p{Ll}\\p{N}])([\\p{Lu}])/gu, \"$1_$2\")\n .toLowerCase();\n const kebab = snake.replace(/_/g, \"-\");\n const variants = [lower, compact, snake, kebab].filter((value) => value.length > 0);\n return Array.from(new Set(variants));\n}\n\nfunction scoreIdentifierMatch(name: string | undefined, filePath: string, hints: string[]): number {\n const nameLower = (name ?? \"\").toLowerCase();\n const pathLower = filePath.toLowerCase();\n\n let best = 0;\n for (const hint of hints) {\n const variants = normalizeIdentifierVariants(hint);\n for (const variant of variants) {\n if (nameLower === variant) {\n best = Math.max(best, 1);\n } else if (nameLower.includes(variant)) {\n best = Math.max(best, 0.8);\n } else if (pathLower.includes(variant)) {\n best = Math.max(best, 0.6);\n }\n }\n }\n\n return best;\n}\n\nexport function extractPrimaryIdentifierQueryHint(query: string): string | null {\n const identifiers = extractIdentifierHints(query);\n if (identifiers.length > 0) {\n return identifiers[0] ?? null;\n }\n\n const codeTerms = extractCodeTermHints(query);\n const best = codeTerms.find((term) => term.length >= 6);\n return best ?? null;\n}\n\nfunction pathSegmentsForAffinityMatch(filePath: string): string[] {\n const normalizedPath = normalizeRankingText(filePath).replace(/\\\\/g, \"/\");\n const segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0);\n if (segments.length === 0) {\n return [];\n }\n\n const basename = segments[segments.length - 1] ?? \"\";\n const basenameWithoutExt = basename.replace(/\\.[^/.]+$/u, \"\");\n const normalizedSegments = segments.map((segment) => segment.toLowerCase());\n\n return Array.from(new Set([\n ...normalizedSegments,\n basenameWithoutExt.toLowerCase(),\n ]));\n}\n\nfunction hasModuleAffinity(filePath: string, exactIdentifierVariants: string[]): boolean {\n const haystack = pathSegmentsForAffinityMatch(filePath);\n return exactIdentifierVariants.some((variant) => {\n if (!variant || variant.length < 2) {\n return false;\n }\n return haystack.includes(variant);\n });\n}\n\nconst FILE_PATH_HINT_EXTENSIONS = [\n \"ts\", \"tsx\", \"js\", \"jsx\", \"mjs\", \"cjs\", \"mts\", \"cts\",\n \"py\", \"rs\", \"go\", \"java\", \"kt\", \"kts\", \"swift\", \"rb\", \"php\",\n \"c\", \"h\", \"cc\", \"cpp\", \"cxx\", \"hpp\", \"cs\", \"scala\", \"lua\",\n \"sh\", \"bash\", \"zsh\", \"json\", \"yaml\", \"yml\", \"toml\",\n];\n\nconst FILE_PATH_HINT_SUFFIX_REGEX = new RegExp(\n \"\\\\s+\\\\bin\\\\s+[\\\"'`]?((?:\\\\.\\\\/)?(?:[A-Za-z0-9._-]+\\\\/)+[A-Za-z0-9._-]+\\\\.(?:\" +\n FILE_PATH_HINT_EXTENSIONS.join(\"|\") +\n \"))[\\\"'`]?[\\\\])}>.,;!?]*\\\\s*$\",\n \"i\"\n);\n\nfunction normalizeFilePathForHintMatch(filePath: string): string {\n return filePath.replace(/\\\\/g, \"/\").toLowerCase().replace(/^\\.\\//, \"\");\n}\n\nexport function pathMatchesHint(filePath: string, hint: string): boolean {\n const normalizedPath = normalizeFilePathForHintMatch(filePath);\n const normalizedHint = normalizeFilePathForHintMatch(hint);\n\n return normalizedPath.endsWith(normalizedHint) ||\n normalizedPath.includes(`/${normalizedHint}`) ||\n normalizedPath.includes(normalizedHint);\n}\n\nexport function extractFilePathHint(query: string): string | null {\n const match = query.match(FILE_PATH_HINT_SUFFIX_REGEX);\n const rawPath = match?.[1];\n if (!rawPath) {\n return null;\n }\n\n return rawPath.replace(/^\\.\\//, \"\");\n}\n\nexport function stripFilePathHint(query: string): string {\n const stripped = query.replace(FILE_PATH_HINT_SUFFIX_REGEX, \"\").trim();\n return stripped.length > 0 ? stripped : query;\n}\n\nexport function buildDeterministicIdentifierPass(\n query: string,\n candidates: RankedCandidate[],\n limit: number,\n prioritizeSourcePaths: boolean = classifyQueryIntentRaw(query) === \"source\"\n): RankedCandidate[] {\n if (!prioritizeSourcePaths) {\n return [];\n }\n\n const primary = extractPrimaryIdentifierQueryHint(query);\n if (!primary) {\n return [];\n }\n const filePathHint = extractFilePathHint(query);\n const primaryVariants = normalizeIdentifierVariants(primary);\n\n const hints = [primary, ...extractIdentifierHints(query), ...extractCodeTermHints(query)]\n .map((value) => value.toLowerCase())\n .filter((value, idx, arr) => value.length >= 3 && arr.indexOf(value) === idx)\n .slice(0, 8);\n\n const deterministic = candidates\n .filter((candidate) =>\n isLikelyImplementationPath(candidate.metadata.filePath) &&\n isImplementationChunkType(candidate.metadata.chunkType)\n )\n .map((candidate) => {\n const nameLower = (candidate.metadata.name ?? \"\").toLowerCase();\n const pathLower = candidate.metadata.filePath.toLowerCase();\n\n const exactIdentifierVariants = primaryVariants.filter((value) => value.length >= 2);\n const exactMatch = exactIdentifierVariants.some((variant) =>\n nameLower === variant ||\n nameLower.replace(/[^a-z0-9]/g, \"\") === variant.replace(/[^a-z0-9]/g, \"\")\n );\n let maxMatch = 0;\n const nameMatchesPrimary = exactMatch;\n const pathAffinity = exactMatch ? hasModuleAffinity(candidate.metadata.filePath, exactIdentifierVariants) : false;\n const pathMatchesFileHint = filePathHint ? pathMatchesHint(candidate.metadata.filePath, filePathHint) : false;\n\n for (const hint of hints) {\n const variants = normalizeIdentifierVariants(hint);\n for (const variant of variants) {\n if (nameLower === variant) {\n maxMatch = Math.max(maxMatch, 1);\n } else if (nameLower.includes(variant)) {\n maxMatch = Math.max(maxMatch, 0.85);\n } else if (pathLower.includes(variant)) {\n maxMatch = Math.max(maxMatch, 0.7);\n }\n }\n }\n\n if (pathMatchesFileHint && nameMatchesPrimary) {\n maxMatch = Math.max(maxMatch, 1);\n }\n\n return {\n candidate,\n maxMatch,\n pathMatchesFileHint,\n nameMatchesPrimary,\n pathAffinity,\n };\n })\n .filter((entry) => entry.maxMatch >= 0.7)\n .sort((a, b) => {\n const aAnchored = a.pathMatchesFileHint && a.nameMatchesPrimary ? 1 : 0;\n const bAnchored = b.pathMatchesFileHint && b.nameMatchesPrimary ? 1 : 0;\n if (aAnchored !== bAnchored) return bAnchored - aAnchored;\n\n if (a.nameMatchesPrimary !== b.nameMatchesPrimary) {\n return b.nameMatchesPrimary ? 1 : -1;\n }\n if (a.pathAffinity !== b.pathAffinity) return b.pathAffinity ? 1 : -1;\n if (b.maxMatch !== a.maxMatch) return b.maxMatch - a.maxMatch;\n if (b.candidate.score !== a.candidate.score) return b.candidate.score - a.candidate.score;\n return a.candidate.id.localeCompare(b.candidate.id);\n })\n .slice(0, Math.max(limit * 2, 12));\n\n return deterministic.map((entry) => ({\n id: entry.candidate.id,\n score: entry.pathMatchesFileHint && entry.nameMatchesPrimary\n ? 0.995\n : Math.min(1, 0.9 + entry.maxMatch * 0.09),\n metadata: entry.candidate.metadata,\n }));\n}\n\n\nexport function buildIdentifierDefinitionLane(\n query: string,\n candidates: RankedCandidate[],\n limit: number,\n prioritizeSourcePaths: boolean = classifyQueryIntentRaw(query) === \"source\"\n): RankedCandidate[] {\n if (!prioritizeSourcePaths) {\n return [];\n }\n\n const primaryHint = extractPrimaryIdentifierQueryHint(query);\n if (!primaryHint) {\n return [];\n }\n\n const hints = [primaryHint, ...extractIdentifierHints(query), ...extractCodeTermHints(query)].slice(0, 8);\n const scored = candidates\n .filter((candidate) =>\n isLikelyImplementationPath(candidate.metadata.filePath) &&\n isImplementationChunkType(candidate.metadata.chunkType)\n )\n .map((candidate) => {\n const matchScore = scoreIdentifierMatch(candidate.metadata.name, candidate.metadata.filePath, hints);\n return {\n candidate,\n matchScore,\n };\n })\n .filter((entry) => entry.matchScore > 0)\n .sort((a, b) => {\n if (b.matchScore !== a.matchScore) return b.matchScore - a.matchScore;\n if (b.candidate.score !== a.candidate.score) return b.candidate.score - a.candidate.score;\n return a.candidate.id.localeCompare(b.candidate.id);\n })\n .slice(0, Math.max(limit * 2, 10));\n\n return scored.map((entry) => ({\n id: entry.candidate.id,\n score: Math.min(1, 0.9 + entry.matchScore * 0.09),\n metadata: entry.candidate.metadata,\n }));\n}\n","import type { ChunkMetadata } from \"../native/index.js\";\nimport { createEmbeddingTexts, createDynamicBatches, estimateTokens } from \"../native/index.js\";\n\nexport interface PendingChunk {\n id: string;\n texts: Array<{\n text: string;\n tokenCount: number;\n }>;\n storageText: string;\n content: string;\n contentHash: string;\n metadata: ChunkMetadata;\n}\n\nexport interface PendingEmbeddingRequest {\n chunk: PendingChunk;\n partIndex: number;\n text: string;\n tokenCount: number;\n}\n\nexport interface FailedBatch {\n chunks: PendingChunk[];\n error: string;\n attemptCount: number;\n lastAttempt: string;\n}\n\nexport interface RetryableFailedChunk {\n chunk: PendingChunk;\n attemptCount: number;\n}\n\nexport interface SerializedFailedBatch {\n chunks: unknown[];\n error: string;\n attemptCount: number;\n lastAttempt: string;\n}\n\nexport function createPendingChunkStorageText(texts: PendingChunk[\"texts\"]): string {\n const primaryText = texts[0]?.text ?? \"\";\n if (texts.length <= 1) {\n return primaryText;\n }\n\n return `${primaryText}\\n\\n... [split into ${texts.length} parts for embedding]`;\n}\n\nexport function normalizePendingChunk(rawChunk: unknown, maxChunkTokens?: number): PendingChunk | null {\n if (!rawChunk || typeof rawChunk !== \"object\") {\n return null;\n }\n\n const chunk = rawChunk as {\n id?: unknown;\n text?: unknown;\n texts?: Array<{ text?: unknown; tokenCount?: unknown }>;\n storageText?: unknown;\n content?: unknown;\n contentHash?: unknown;\n metadata?: unknown;\n };\n\n if (typeof chunk.id !== \"string\" || typeof chunk.contentHash !== \"string\" || !chunk.metadata || typeof chunk.metadata !== \"object\") {\n return null;\n }\n\n const texts = Array.isArray(chunk.texts)\n ? chunk.texts\n .map((entry) => {\n if (!entry || typeof entry.text !== \"string\") {\n return null;\n }\n\n return {\n text: entry.text,\n tokenCount: typeof entry.tokenCount === \"number\" && Number.isFinite(entry.tokenCount)\n ? entry.tokenCount\n : estimateTokens(entry.text),\n };\n })\n .filter((entry): entry is PendingChunk[\"texts\"][number] => entry !== null)\n : [];\n\n if (texts.length === 0 && typeof chunk.text === \"string\") {\n if (typeof chunk.content === \"string\" && chunk.content.length > 0 && chunk.metadata && typeof chunk.metadata === \"object\") {\n const metadata = chunk.metadata as Partial<ChunkMetadata>;\n const rebuiltChunk = {\n content: chunk.content,\n startLine: typeof metadata.startLine === \"number\" ? metadata.startLine : 1,\n endLine: typeof metadata.endLine === \"number\" ? metadata.endLine : 1,\n chunkType: typeof metadata.chunkType === \"string\" ? metadata.chunkType : \"other\",\n name: typeof metadata.name === \"string\" ? metadata.name : undefined,\n language: typeof metadata.language === \"string\" ? metadata.language : \"text\",\n };\n const filePath = typeof metadata.filePath === \"string\" ? metadata.filePath : \"unknown\";\n texts.push(\n ...createEmbeddingTexts(rebuiltChunk, filePath, maxChunkTokens).map((text) => ({\n text,\n tokenCount: estimateTokens(text),\n }))\n );\n } else {\n texts.push({\n text: chunk.text,\n tokenCount: estimateTokens(chunk.text),\n });\n }\n }\n\n if (texts.length === 0) {\n return null;\n }\n\n return {\n id: chunk.id,\n texts,\n storageText: typeof chunk.storageText === \"string\" ? chunk.storageText : createPendingChunkStorageText(texts),\n content: typeof chunk.content === \"string\" ? chunk.content : \"\",\n contentHash: chunk.contentHash,\n metadata: chunk.metadata as ChunkMetadata,\n };\n}\n\nexport function getPendingChunkFilePath(rawChunk: unknown): string | null {\n if (!rawChunk || typeof rawChunk !== \"object\") {\n return null;\n }\n\n const chunk = rawChunk as { metadata?: unknown };\n if (!chunk.metadata || typeof chunk.metadata !== \"object\") {\n return null;\n }\n\n const metadata = chunk.metadata as { filePath?: unknown };\n return typeof metadata.filePath === \"string\" ? metadata.filePath : null;\n}\n\nexport function normalizeFailedBatch(batch: SerializedFailedBatch, maxChunkTokens?: number): FailedBatch | null {\n const chunks = batch.chunks\n .map((chunk) => normalizePendingChunk(chunk, maxChunkTokens))\n .filter((chunk): chunk is PendingChunk => chunk !== null);\n\n if (chunks.length === 0) {\n return null;\n }\n\n return {\n chunks,\n error: batch.error,\n attemptCount: batch.attemptCount,\n lastAttempt: batch.lastAttempt,\n } satisfies FailedBatch;\n}\n\nexport function createPendingEmbeddingRequests(chunks: PendingChunk[]): PendingEmbeddingRequest[] {\n return chunks.flatMap((chunk) =>\n chunk.texts.map((textPart, partIndex) => ({\n chunk,\n partIndex,\n text: textPart.text,\n tokenCount: textPart.tokenCount,\n }))\n );\n}\n\nexport function createPendingEmbeddingRequestBatches(\n chunks: PendingChunk[],\n options: { maxBatchTokens?: number; maxBatchItems?: number } = {}\n): PendingEmbeddingRequest[][] {\n return createDynamicBatches(createPendingEmbeddingRequests(chunks), options);\n}\n\nexport function getUniquePendingChunksFromRequests(requests: PendingEmbeddingRequest[]): PendingChunk[] {\n const uniqueChunks = new Map<string, PendingChunk>();\n for (const request of requests) {\n uniqueChunks.set(request.chunk.id, request.chunk);\n }\n return Array.from(uniqueChunks.values());\n}\n\nexport function coalesceFailedBatches(batches: FailedBatch[]): FailedBatch[] {\n const grouped = new Map<string, FailedBatch>();\n\n for (const batch of batches) {\n const key = `${batch.attemptCount}:${batch.lastAttempt}:${batch.error}`;\n const existing = grouped.get(key);\n if (!existing) {\n grouped.set(key, {\n ...batch,\n chunks: [...batch.chunks],\n });\n continue;\n }\n\n existing.chunks.push(...batch.chunks);\n }\n\n return Array.from(grouped.values());\n}\n\nexport function poolEmbeddingVectors(vectors: number[][], weights: number[]): number[] {\n const firstVector = vectors[0];\n if (!firstVector) {\n return [];\n }\n\n const pooled = new Array<number>(firstVector.length).fill(0);\n let totalWeight = 0;\n\n for (let index = 0; index < vectors.length; index++) {\n const vector = vectors[index];\n const weight = Math.max(1, weights[index] ?? 1);\n totalWeight += weight;\n\n for (let dimension = 0; dimension < vector.length; dimension++) {\n pooled[dimension] += vector[dimension] * weight;\n }\n }\n\n if (totalWeight === 0) {\n return firstVector;\n }\n\n return pooled.map((value) => value / totalWeight);\n}\n\nexport function hasAllEmbeddingParts(\n parts: Array<{ vector: number[]; tokenCount: number } | undefined>,\n expectedPartCount: number\n): boolean {\n if (parts.length !== expectedPartCount) {\n return false;\n }\n\n for (let index = 0; index < expectedPartCount; index++) {\n if (parts[index] === undefined) {\n return false;\n }\n }\n\n return true;\n}\n","import * as fs from \"node:fs\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport * as path from \"node:path\";\nimport { StringDecoder } from \"node:string_decoder\";\n\nconst CURRENT_FAILED_BATCH_VERSION = 1;\nconst DEFAULT_MALFORMED_LINE_ACTION = \"skip\" as const;\n\nexport type MalformedLineAction = \"skip\" | \"fail\";\n\nexport interface FailedBatchRecordInput<TChunk = unknown> {\n readonly chunks: TChunk[];\n readonly error: string;\n readonly attemptCount: number;\n readonly lastAttempt: string;\n}\n\nexport interface FailedBatchRecord<TChunk = unknown> extends FailedBatchRecordInput<TChunk> {\n readonly version: number;\n}\n\nexport interface FailedBatchReadOptions {\n readonly malformedLineAction?: MalformedLineAction;\n readonly onMalformedLine?: (error: Error, line: string, lineNumber: number, filePath: string) => void;\n}\n\nexport interface FailedBatchWriter<TChunk = unknown> {\n write: (record: FailedBatchRecordInput<TChunk>) => void;\n commit: () => void;\n cleanup: () => void;\n readonly temporaryPath: string;\n}\n\nexport function* readFailedBatchRecords<TChunk = unknown>(\n filePath: string,\n options: FailedBatchReadOptions = {},\n): Generator<FailedBatchRecord<TChunk>, void, void> {\n if (!fs.existsSync(filePath)) {\n return;\n }\n\n const fileFormat = detectFailedBatchFileFormat(filePath);\n if (fileFormat === \"legacy\") {\n yield* readLegacyFailedBatchRecords(filePath, options);\n return;\n }\n\n yield* readJsonlFailedBatchRecords(filePath, options);\n}\n\nexport function createFailedBatchWriter<TChunk = unknown>(targetPath: string): FailedBatchWriter<TChunk> {\n const temporaryPath = createTemporaryPath(targetPath);\n let finalized = false;\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.closeSync(fs.openSync(temporaryPath, \"w\"));\n\n const write = (record: FailedBatchRecordInput<TChunk>): void => {\n if (finalized) {\n throw new Error(\"Failed batch writer has been finalized\");\n }\n\n const lines = record.chunks.map((chunk) => {\n const lineRecord: FailedBatchRecord<TChunk> = {\n version: CURRENT_FAILED_BATCH_VERSION,\n chunks: [chunk],\n error: record.error,\n attemptCount: record.attemptCount,\n lastAttempt: record.lastAttempt,\n };\n return JSON.stringify(lineRecord);\n });\n\n if (lines.length === 0) {\n return;\n }\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.appendFileSync(temporaryPath, `${lines.join(\"\\n\")}\\n`, \"utf-8\");\n };\n\n const commit = (): void => {\n if (finalized) {\n return;\n }\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.renameSync(temporaryPath, targetPath);\n finalized = true;\n };\n\n const cleanup = (): void => {\n if (finalized) {\n return;\n }\n fs.rmSync(temporaryPath, { force: true });\n };\n\n return {\n write,\n commit,\n cleanup,\n temporaryPath,\n };\n}\n\nexport function writeFailedBatchRecords<TChunk = unknown>(\n targetPath: string,\n records: Iterable<FailedBatchRecordInput<TChunk>>,\n): void {\n const writer = createFailedBatchWriter<TChunk>(targetPath);\n try {\n for (const record of records) {\n writer.write(record);\n }\n writer.commit();\n } catch (error) {\n writer.cleanup();\n throw error;\n }\n}\n\nfunction* readLegacyFailedBatchRecords<TChunk = unknown>(\n filePath: string,\n options: FailedBatchReadOptions,\n): Generator<FailedBatchRecord<TChunk>, void, void> {\n const rawData = fs.readFileSync(filePath, \"utf-8\");\n const trimmed = stripLeadingBomAndWhitespace(rawData).trim();\n if (trimmed.length === 0) {\n return;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch (error) {\n handleMalformedLine(filePath, 1, trimmed, error, options);\n return;\n }\n\n if (!Array.isArray(parsed)) {\n handleMalformedLine(filePath, 1, trimmed, new Error(\"Expected legacy failed-batch file to contain a JSON array\"), options);\n return;\n }\n\n for (const entry of parsed) {\n const normalized = normalizeFailedBatchRecord<TChunk>(entry);\n if (normalized) {\n yield normalized;\n }\n }\n}\n\nfunction* readJsonlFailedBatchRecords<TChunk = unknown>(\n filePath: string,\n options: FailedBatchReadOptions,\n): Generator<FailedBatchRecord<TChunk>, void, void> {\n const handle = fs.openSync(filePath, \"r\");\n const decoder = new StringDecoder(\"utf8\");\n const readBuffer = Buffer.allocUnsafe(64 * 1024);\n let buffer = \"\";\n let lineNumber = 0;\n\n try {\n let bytesRead = 0;\n do {\n bytesRead = fs.readSync(handle, readBuffer, 0, readBuffer.length, null);\n buffer += decoder.write(readBuffer.subarray(0, bytesRead));\n\n let newlineIndex = buffer.indexOf(\"\\n\");\n while (newlineIndex >= 0) {\n const rawLine = buffer.slice(0, newlineIndex);\n buffer = buffer.slice(newlineIndex + 1);\n lineNumber += 1;\n\n const normalized = parseFailedBatchLine<TChunk>(rawLine, filePath, lineNumber, options);\n if (normalized) {\n yield normalized;\n }\n\n newlineIndex = buffer.indexOf(\"\\n\");\n }\n } while (bytesRead > 0);\n\n buffer += decoder.end();\n\n const finalLine = buffer.trimEnd();\n if (finalLine.length > 0) {\n lineNumber += 1;\n const normalized = parseFailedBatchLine<TChunk>(finalLine, filePath, lineNumber, options);\n if (normalized) {\n yield normalized;\n }\n }\n } finally {\n fs.closeSync(handle);\n }\n}\n\nfunction parseFailedBatchLine<TChunk = unknown>(\n rawLine: string,\n filePath: string,\n lineNumber: number,\n options: FailedBatchReadOptions,\n): FailedBatchRecord<TChunk> | null {\n const line = rawLine.trimEnd();\n if (line.length === 0) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(line);\n const normalized = normalizeFailedBatchRecord<TChunk>(parsed);\n if (!normalized) {\n handleMalformedLine(filePath, lineNumber, line, new Error(\"Malformed failed-batch record\"), options);\n return null;\n }\n return normalized;\n } catch (error) {\n handleMalformedLine(filePath, lineNumber, line, error, options);\n return null;\n }\n}\n\nfunction normalizeFailedBatchRecord<TChunk = unknown>(rawRecord: unknown): FailedBatchRecord<TChunk> | null {\n if (!rawRecord || typeof rawRecord !== \"object\" || Array.isArray(rawRecord)) {\n return null;\n }\n\n const typed = rawRecord as {\n chunks?: unknown;\n error?: unknown;\n attemptCount?: unknown;\n lastAttempt?: unknown;\n version?: unknown;\n };\n\n const chunks = Array.isArray(typed.chunks) ? typed.chunks : null;\n if (!chunks || chunks.length === 0) {\n return null;\n }\n\n return {\n version: typeof typed.version === \"number\" && Number.isFinite(typed.version) ? typed.version : CURRENT_FAILED_BATCH_VERSION,\n chunks: chunks as TChunk[],\n error: typeof typed.error === \"string\" ? typed.error : \"Unknown embedding error\",\n attemptCount: typeof typed.attemptCount === \"number\" && Number.isFinite(typed.attemptCount) ? typed.attemptCount : 1,\n lastAttempt: typeof typed.lastAttempt === \"string\" ? typed.lastAttempt : new Date().toISOString(),\n };\n}\n\ntype FailedBatchFileFormat = \"legacy\" | \"jsonl\";\n\nfunction detectFailedBatchFileFormat(filePath: string): FailedBatchFileFormat {\n const handle = fs.openSync(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(4096);\n const bytesRead = fs.readSync(handle, buffer, 0, buffer.length, 0);\n if (bytesRead <= 0) {\n return \"jsonl\";\n }\n\n const prefix = stripLeadingBomAndWhitespace(buffer.subarray(0, bytesRead).toString(\"utf-8\"));\n return prefix.startsWith(\"[\") ? \"legacy\" : \"jsonl\";\n } finally {\n fs.closeSync(handle);\n }\n}\n\nfunction stripLeadingBomAndWhitespace(value: string): string {\n let result = value.trimStart();\n if (result.charCodeAt(0) === 0xfeff) {\n result = result.slice(1);\n }\n return result;\n}\n\nfunction createTemporaryPath(targetPath: string): string {\n const randomId = createHash(\"sha1\")\n .update(`${Date.now()}:${randomBytes(8).toString(\"hex\")}`)\n .digest(\"hex\");\n const targetDir = path.dirname(targetPath);\n const baseName = path.basename(targetPath);\n return path.join(targetDir, `.${baseName}.${randomId}.tmp`);\n}\n\nfunction handleMalformedLine(\n filePath: string,\n lineNumber: number,\n line: string,\n error: unknown,\n options: FailedBatchReadOptions,\n): void {\n const action = options.malformedLineAction ?? DEFAULT_MALFORMED_LINE_ACTION;\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n\n if (options.onMalformedLine) {\n options.onMalformedLine(normalizedError, line, lineNumber, filePath);\n }\n\n if (action === \"fail\") {\n throw normalizedError;\n }\n}\n","export interface FileBatchLimits {\n maxFiles: number;\n maxBytes: number;\n}\n\nexport const INDEX_FILE_BATCH_LIMITS: Readonly<FileBatchLimits> = Object.freeze({\n maxFiles: 64,\n maxBytes: 8 * 1024 * 1024,\n});\n\nexport function* iterateOrderedFileBatches<T>(\n items: Iterable<T>,\n getBytes: (item: T) => number,\n limits: FileBatchLimits = INDEX_FILE_BATCH_LIMITS,\n): Generator<T[]> {\n const maxFiles = Math.max(1, Math.floor(limits.maxFiles));\n const maxBytes = Math.max(1, Math.floor(limits.maxBytes));\n let batch: T[] = [];\n let batchBytes = 0;\n\n for (const item of items) {\n const itemBytes = Math.max(0, Math.floor(getBytes(item)));\n if (batch.length > 0 && (batch.length >= maxFiles || batchBytes + itemBytes > maxBytes)) {\n yield batch;\n batch = [];\n batchBytes = 0;\n }\n\n batch.push(item);\n batchBytes += itemBytes;\n }\n\n if (batch.length > 0) {\n yield batch;\n }\n}\n","import type { HostMode } from \"../config/host.js\";\nimport type { ParsedCodebaseIndexConfig } from \"../config/schema.js\";\nimport { parseConfig } from \"../config/schema.js\";\nimport { configureAutoIndex, waitForAutoIndexForRetrieval } from \"../utils/auto-index.js\";\nimport { Indexer } from \"../indexer/index.js\";\nimport { isIndexLockContentionError } from \"../indexer/index-lock.js\";\nimport {\n recordProcessEffectiveness,\n type EffectivenessMetricEvent,\n} from \"../utils/effectiveness-metrics.js\";\nimport { countContextTokens } from \"./utils.js\";\nimport { loadRuntimeConfig } from \"./config-state.js\";\n\nexport type IndexerCacheKey = `${HostMode}::${string}`;\n\nexport const indexerCache = new Map<IndexerCacheKey, Indexer>();\nexport const configCache = new Map<IndexerCacheKey, ParsedCodebaseIndexConfig>();\nexport const defaultProjectRoots = new Map<HostMode, string>();\n\nexport type IndexBusyResult = { kind: \"busy\"; text: string };\n\nexport function getIndexBusyResult(error: unknown): IndexBusyResult | null {\n if (!isIndexLockContentionError(error)) return null;\n\n const owner = error.owner;\n const ownerText = owner\n ? `PID ${owner.pid}, operation ${owner.operation}, since ${owner.startedAt}`\n : \"unreadable owner\";\n if (error.reason === \"legacy-lock\") {\n return {\n kind: \"busy\",\n text: `INDEX_BUSY: legacy lock format detected (${ownerText}). Verify the PID and remove this lock manually only if it is stale.`,\n };\n }\n if (error.reason === \"unknown-owner\") {\n return {\n kind: \"busy\",\n text: `INDEX_BUSY: unreadable or remote lock owner (${ownerText}). Automatic recovery was refused; manual verification is required.`,\n };\n }\n return { kind: \"busy\", text: `INDEX_BUSY: another index operation is already in progress (${ownerText}).` };\n}\n\nexport function getProjectRoot(projectRoot: string | undefined, host: HostMode): string {\n if (projectRoot) {\n return projectRoot;\n }\n\n const root = defaultProjectRoots.get(host);\n if (!root) {\n throw new Error(\"Codebase index tools not initialized. Plugin may not be loaded correctly.\");\n }\n\n return root;\n}\n\nexport function getIndexerCacheKey(projectRoot: string, host: HostMode): IndexerCacheKey {\n return `${host}::${projectRoot}`;\n}\n\nexport function rawEffectivenessMetricsEnabled(rawConfig: unknown): boolean {\n if (!rawConfig || typeof rawConfig !== \"object\") return false;\n const value = (rawConfig as Record<string, unknown>).effectivenessMetrics;\n return Boolean(value && typeof value === \"object\" && (value as Record<string, unknown>).enabled === true);\n}\n\nexport function isToolEffectivenessEnabled(\n projectRoot: string | undefined,\n host: HostMode,\n): boolean {\n try {\n const root = getProjectRoot(projectRoot, host);\n const cached = configCache.get(getIndexerCacheKey(root, host));\n if (cached) return cached.effectivenessMetrics.enabled;\n return rawEffectivenessMetricsEnabled(loadRuntimeConfig(root, host));\n } catch {\n // Metrics are best-effort and must never alter repository tool behavior.\n return false;\n }\n}\n\nexport function safelyRecordToolEffectiveness(event: EffectivenessMetricEvent): void {\n try {\n recordProcessEffectiveness(event);\n } catch {\n // Metrics are best-effort and must never alter repository tool behavior.\n }\n}\n\nexport function safelyCountReturnedTokens(text: string): number {\n try {\n return countContextTokens(text);\n } catch {\n return 0;\n }\n}\n\nexport function getOrCreateIndexer(projectRoot: string, host: HostMode): Indexer {\n const key = getIndexerCacheKey(projectRoot, host);\n const cached = indexerCache.get(key);\n if (cached) {\n return cached;\n }\n\n let config = configCache.get(key);\n if (!config) {\n config = parseConfig(loadRuntimeConfig(projectRoot, host));\n configCache.set(key, config);\n }\n const indexer = new Indexer(projectRoot, config, host);\n indexerCache.set(key, indexer);\n configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host));\n return indexer;\n}\n\nexport function initializeTools(projectRoot: string, config: ParsedCodebaseIndexConfig, host: HostMode): void {\n defaultProjectRoots.set(host, projectRoot);\n const key = getIndexerCacheKey(projectRoot, host);\n configCache.set(key, config);\n indexerCache.set(key, new Indexer(projectRoot, config, host));\n configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host));\n}\n\nexport function getSharedIndexer(host: HostMode): Indexer {\n return getIndexerForProject(undefined, host);\n}\n\nexport function getIndexerForProject(projectRoot: string | undefined, host: HostMode): Indexer {\n const root = getProjectRoot(projectRoot, host);\n return getOrCreateIndexer(root, host);\n}\n\nexport function recordToolEffectiveness(\n projectRoot: string | undefined,\n host: HostMode,\n event: EffectivenessMetricEvent,\n): void {\n if (!isToolEffectivenessEnabled(projectRoot, host)) return;\n safelyRecordToolEffectiveness(event);\n}\n\nexport function refreshIndexerForDirectory(\n projectRoot: string,\n host: HostMode,\n config: ParsedCodebaseIndexConfig = parseConfig(loadRuntimeConfig(projectRoot, host)),\n): ParsedCodebaseIndexConfig {\n const key = getIndexerCacheKey(projectRoot, host);\n configCache.set(key, config);\n indexerCache.set(key, new Indexer(projectRoot, config, host));\n configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host));\n return config;\n}\n\nexport class AutoIndexRetrievalUnavailableError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AutoIndexRetrievalUnavailableError\";\n }\n}\n\nexport async function ensureAutoIndexReadyForRetrieval(\n projectRoot: string | undefined,\n host: HostMode,\n): Promise<void> {\n const root = getProjectRoot(projectRoot, host);\n getIndexerForProject(root, host);\n const result = await waitForAutoIndexForRetrieval(root, host);\n if (!result.ready) {\n throw new AutoIndexRetrievalUnavailableError(\n result.text ?? \"Automatic indexing has not produced a readable index yet. Call index_status and retry.\",\n );\n }\n}\n","import type { HostMode } from \"../config/host.js\";\nimport type {\n SharedCallGraphArgs,\n SharedCallGraphPathArgs,\n SharedCodebaseContextArgs,\n SharedCodebaseEditContextArgs,\n SharedCodeCommunitiesArgs,\n SharedIndexCodebaseArgs,\n SharedIndexLogsArgs,\n SharedIndexMetricsArgs,\n SharedImplementationLookupArgs,\n} from \"./contracts.js\";\nimport {\n getCallGraphData,\n getCallGraphPath,\n getCodeCommunities,\n getIndexLogs,\n getIndexMetrics,\n getIndexStatus,\n implementationLookup,\n runIndexCodebase,\n runIndexHealthCheck,\n} from \"./operations.js\";\nimport { formatCostEstimate, formatDryRunEstimate } from \"../utils/cost.js\";\nimport { resolveCodebaseEditContext } from \"./edit-context.js\";\nimport { resolveCodebaseContext } from \"./context.js\";\nimport {\n formatCallGraphPathResult,\n formatCallGraphResult,\n formatDefinitionLookup,\n formatHealthCheck,\n formatIndexStats,\n formatStatus,\n} from \"./utils.js\";\nimport { formatCodeCommunities } from \"./format-communities.js\";\n\nexport interface ExecutionResult {\n text: string;\n details?: Record<string, unknown>;\n isError?: boolean;\n}\n\nexport type IndexProgressCallback = (title: string, metadata: Record<string, unknown>) => void | Promise<void>;\n\nexport async function executeCodebaseContext(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedCodebaseContextArgs,\n): Promise<ExecutionResult> {\n const result = await resolveCodebaseContext(projectRoot, host, args);\n return { text: result.text, details: result.details };\n}\n\nexport async function executeCodebaseEditContext(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedCodebaseEditContextArgs,\n): Promise<ExecutionResult> {\n return { text: (await resolveCodebaseEditContext(projectRoot, host, args)).text };\n}\n\nexport async function executeIndexCodebase(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedIndexCodebaseArgs,\n onProgress?: IndexProgressCallback,\n): Promise<ExecutionResult> {\n const result = await runIndexCodebase(projectRoot, host, args, onProgress);\n if (result.kind === \"estimate\") return { text: formatCostEstimate(result.estimate) };\n if (result.kind === \"dryrun\") return { text: formatDryRunEstimate(result.dryrun) };\n if (result.kind === \"busy\") return { text: result.text, isError: true };\n if (result.kind === \"message\") return { text: result.text };\n return { text: formatIndexStats(result.stats, args.verbose ?? false) };\n}\n\nexport async function executeIndexStatus(\n projectRoot: string | undefined,\n host: HostMode,\n): Promise<ExecutionResult> {\n return { text: formatStatus(await getIndexStatus(projectRoot, host)) };\n}\n\nexport async function executeIndexHealthCheck(\n projectRoot: string | undefined,\n host: HostMode,\n): Promise<ExecutionResult> {\n const result = await runIndexHealthCheck(projectRoot, host);\n if (result.kind === \"busy\") return { text: result.text, isError: true };\n return { text: formatHealthCheck(result.health) };\n}\n\nexport async function executeIndexMetrics(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedIndexMetricsArgs,\n): Promise<ExecutionResult> {\n return { text: (await getIndexMetrics(projectRoot, host, args)).text };\n}\n\nexport async function executeIndexLogs(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedIndexLogsArgs,\n): Promise<ExecutionResult> {\n return {\n text: (await getIndexLogs(projectRoot, host, {\n limit: args.limit,\n category: args.category ?? undefined,\n level: args.level ?? undefined,\n })).text,\n };\n}\n\nexport async function executeImplementationLookup(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedImplementationLookupArgs,\n): Promise<ExecutionResult> {\n const results = await implementationLookup(projectRoot, host, args.query, {\n limit: args.limit,\n fileType: args.fileType,\n directory: args.directory,\n });\n return { text: formatDefinitionLookup(results, args.query) };\n}\n\nexport async function executeCallGraph(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedCallGraphArgs,\n): Promise<ExecutionResult> {\n return { text: formatCallGraphResult(await getCallGraphData(projectRoot, host, args)) };\n}\n\nexport async function executeCallGraphPath(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedCallGraphPathArgs,\n): Promise<ExecutionResult> {\n const path = await getCallGraphPath(\n projectRoot,\n host,\n args.from,\n args.to,\n args.maxDepth,\n args.fromFilePath,\n args.toFilePath,\n );\n return { text: formatCallGraphPathResult(path) };\n}\n\nexport async function executeCodeCommunities(\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedCodeCommunitiesArgs,\n): Promise<ExecutionResult> {\n const result = await getCodeCommunities(projectRoot, host, args);\n return { text: formatCodeCommunities(result) };\n}\n","import type { SharedIndexCodebaseArgs } from \"../../tools/contracts.js\";\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { realpathSync, writeFileSync } from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport { parseConfig } from \"../../config/schema.js\";\nimport { parseHostMode, HOST_MODES, type HostMode } from \"../../config/host.js\";\nimport { handleEvalCommand } from \"../../eval/cli.js\";\nimport { Indexer } from \"../../indexer/index.js\";\nimport { createMcpServer } from \"../../mcp-server.js\";\nimport { loadConfigFile, loadMergedConfig } from \"../../config/merger.js\";\nimport { getIndexerForProject } from \"../../tools/operations.js\";\nimport { initializeTools } from \"../../tools/operation-runtime.js\";\nimport { executeIndexCodebase } from \"../../tools/execute-common.js\";\nimport { hasProjectMarker } from \"../../utils/files.js\";\nimport { isHomeDirectory, stopAutoIndex } from \"../../utils/auto-index.js\";\nimport { createWatcherWithIndexer, type CombinedWatcher } from \"../../watcher/index.js\";\nimport { attachRecentActivity } from \"../../tools/visualize/activity.js\";\nimport { generateVisualizationHtml, transformForVisualization } from \"../../tools/visualize/index.js\";\n\nexport interface CliArgs {\n project: string;\n config?: string;\n host: HostMode;\n}\n\nexport interface CliIndexArgs {\n project: string;\n host: HostMode;\n config?: string;\n force: boolean;\n estimateOnly: boolean;\n dryRun: boolean;\n verbose: boolean;\n}\n\ninterface VisualizeArgs {\n directory?: string;\n includeOrphans: boolean;\n maxNodes: number;\n project: string;\n}\n\nexport function parseArgs(argv: string[]): CliArgs {\n let project = process.cwd();\n let config: string | undefined;\n let host: HostMode = \"opencode\";\n\n for (let i = 2; i < argv.length; i++) {\n if (argv[i] === \"--project\" && argv[i + 1]) {\n project = path.resolve(argv[++i]);\n } else if (argv[i] === \"--config\" && argv[i + 1]) {\n config = path.resolve(argv[++i]);\n } else if (argv[i] === \"--host\" && argv[i + 1]) {\n host = parseHostMode(argv[++i]);\n } else if (argv[i] === \"--host\") {\n host = parseHostMode(undefined);\n }\n }\n\n return { project, config, host };\n}\n\nexport function parseIndexArgs(argv: string[], cwd: string): CliIndexArgs {\n let project = cwd;\n let host: HostMode = \"opencode\";\n let config: string | undefined;\n let force = false;\n let estimateOnly = false;\n let dryRun = false;\n let verbose = false;\n\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n const next = argv[i + 1];\n\n if (arg === \"--project\" || arg.startsWith(\"--project=\")) {\n const value = arg.startsWith(\"--project=\") ? arg.slice(\"--project=\".length) : next;\n if (!value || (!arg.includes(\"=\") && value.startsWith(\"--\"))) {\n throw new Error(\"--project requires a value.\");\n }\n if (!arg.startsWith(\"--project=\")) {\n i += 1;\n }\n project = path.resolve(cwd, value);\n continue;\n }\n\n if (arg === \"--config\" || arg.startsWith(\"--config=\")) {\n const value = arg.startsWith(\"--config=\") ? arg.slice(\"--config=\".length) : next;\n if (!value || (!arg.includes(\"=\") && value.startsWith(\"--\"))) {\n throw new Error(\"--config requires a value.\");\n }\n if (!arg.startsWith(\"--config=\")) {\n i += 1;\n }\n config = path.resolve(cwd, value);\n continue;\n }\n\n if (arg === \"--host\" || arg.startsWith(\"--host=\")) {\n const value = arg.startsWith(\"--host=\") ? arg.slice(\"--host=\".length) : next;\n if (!value || (!arg.includes(\"=\") && value.startsWith(\"--\"))) {\n throw new Error(\"--host requires a value.\");\n }\n if (!arg.startsWith(\"--host=\")) {\n i += 1;\n }\n host = parseHostMode(value);\n continue;\n }\n\n if (arg === \"--force\" || arg === \"--estimate-only\" || arg === \"--dry-run\" || arg === \"--verbose\") {\n if (arg === \"--force\") {\n force = true;\n }\n if (arg === \"--estimate-only\") {\n estimateOnly = true;\n }\n if (arg === \"--dry-run\") {\n dryRun = true;\n }\n if (arg === \"--verbose\") {\n verbose = true;\n }\n continue;\n }\n\n if (arg === \"--help\" || arg === \"-h\") {\n throw new Error(\"help-requested\");\n }\n\n throw new Error(`Unknown index option: ${arg}`);\n }\n\n return { project, host, config, force, estimateOnly, dryRun, verbose };\n}\n\nexport function loadCliRawConfig(args: CliArgs): unknown {\n return args.config ? loadConfigFile(args.config) : loadMergedConfig(args.project, args.host);\n}\n\nexport function printUsage(output: (text: string) => void = (text) => console.error(text)): void {\n output(`\nUsage:\n ${process.argv[1]} index [options]\n\nOptions:\n --project <path> Project root (default: cwd)\n --host <mode> opencode, codex, claude, pi, or jcode\n --config <path> Explicit JSON config path\n --force Rebuild index even if already up to date\n --estimate-only Estimate indexing cost only\n --dry-run Parse only; report the exact embedding token total without indexing\n --verbose Include detailed final index statistics\n --help Show this message\n\nRun '${process.argv[1]} eval' and '${process.argv[1]} visualize' for existing behavior.\nProgress and diagnostics are written to stderr. Final index output is written to stdout.`\n );\n}\n\nexport function isCliEntrypoint(moduleUrl: string, argvPath: string | undefined): boolean {\n return argvPath !== undefined && realpathSync(fileURLToPath(moduleUrl)) === realpathSync(argvPath);\n}\n\nfunction parseVisualizeArgs(argv: string[], cwd: string): VisualizeArgs {\n let project = cwd;\n let directory: string | undefined;\n let includeOrphans = false;\n let maxNodes = 5000;\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--project\" && argv[i + 1]) {\n project = path.resolve(argv[++i]);\n } else if (arg === \"--max\" && argv[i + 1]) {\n maxNodes = Number(argv[++i]);\n } else if (arg.startsWith(\"--max=\") || arg.startsWith(\"max=\")) {\n maxNodes = Number(arg.split(\"=\")[1]);\n } else if (arg === \"--orphans\" || arg === \"orphans\" || arg === \"--include-orphans\" || arg === \"include-orphans\") {\n includeOrphans = true;\n } else if (!arg.startsWith(\"-\") && directory === undefined) {\n directory = arg;\n }\n }\n\n if (!Number.isFinite(maxNodes) || maxNodes < 1) {\n throw new Error(\"max must be a positive number\");\n }\n\n return { directory, includeOrphans, maxNodes, project };\n}\n\nasync function handleVisualizeCommand(argv: string[], cwd: string): Promise<number> {\n try {\n const args = parseVisualizeArgs(argv, cwd);\n const config = parseConfig(loadMergedConfig(args.project, \"opencode\"));\n const indexer = new Indexer(args.project, config, \"opencode\");\n const rawData = await indexer.getVisualizationData({\n directory: args.directory,\n });\n\n if (rawData.symbols.length === 0) {\n console.error(\"No call graph data found. Run /index in OpenCode first, then retry npm run visualize.\");\n return 1;\n }\n\n const vizData = attachRecentActivity(transformForVisualization(rawData.symbols, rawData.edges, {\n includeOrphans: args.includeOrphans,\n directory: args.directory,\n maxNodes: args.maxNodes,\n }), args.project);\n\n if (vizData.nodes.length === 0) {\n console.error(\"No connected symbols found. Retry with: npm run visualize -- orphans\");\n return 1;\n }\n\n const outputPath = path.join(os.tmpdir(), `call-graph-${Date.now()}.html`);\n writeFileSync(outputPath, generateVisualizationHtml(vizData), \"utf-8\");\n console.log(`Temporal call graph visualization generated: ${outputPath}`);\n console.log(`Nodes: ${vizData.nodes.length} | Edges: ${vizData.edges.length}`);\n console.log(`Recent change lenses: ${vizData.changes?.length ?? 0}`);\n if (vizData.metadata.truncated) {\n console.log(`Graph truncated to ${args.maxNodes} most-connected nodes.`);\n }\n return 0;\n } catch {\n console.error(\"Failed to generate visualization. Check the project, config, and arguments, then retry.\");\n return 1;\n }\n}\n\nexport async function runMcpCli(argv: string[]): Promise<void> {\n if (argv[2] === \"index\") {\n const exitCode = await handleIndexCommand(argv.slice(3), process.cwd());\n process.exit(exitCode);\n }\n if (argv[2] === \"eval\") {\n const exitCode = await handleEvalCommand(argv.slice(3), process.cwd());\n process.exit(exitCode);\n }\n if (argv[2] === \"visualize\") {\n const exitCode = await handleVisualizeCommand(argv.slice(3), process.cwd());\n process.exit(exitCode);\n }\n\n const args = parseArgs(argv);\n const rawConfig = loadCliRawConfig(args);\n const config = parseConfig(rawConfig);\n\n const server = createMcpServer(args.project, config, args.host);\n const transport = new StdioServerTransport();\n let watcher: CombinedWatcher | null = null;\n let shutdownPromise: Promise<void> | undefined;\n const onServerClose = server.server.onclose;\n\n const shutdown = (): Promise<void> => {\n if (shutdownPromise) return shutdownPromise;\n process.stdin.removeListener(\"end\", requestShutdown);\n process.stdin.removeListener(\"close\", requestShutdown);\n process.removeListener(\"SIGHUP\", requestShutdown);\n process.removeListener(\"SIGINT\", requestShutdown);\n process.removeListener(\"SIGTERM\", requestShutdown);\n server.server.onclose = onServerClose;\n shutdownPromise = (async (): Promise<void> => {\n let exitCode = 0;\n try {\n await watcher?.stop();\n } catch (error) {\n exitCode = 1;\n console.error(\"Failed to stop MCP file watcher cleanly:\", error);\n }\n try {\n await stopAutoIndex(args.project, args.host);\n } catch (error) {\n exitCode = 1;\n console.error(\"Failed to stop automatic indexing cleanly:\", error);\n }\n try {\n await server.close();\n } catch (error) {\n exitCode = 1;\n console.error(\"Failed to close MCP server cleanly:\", error);\n }\n process.exit(exitCode);\n })();\n return shutdownPromise;\n };\n\n const requestShutdown = (): void => {\n void shutdown();\n };\n\n server.server.onclose = () => {\n try {\n onServerClose?.();\n } finally {\n requestShutdown();\n }\n };\n\n process.stdin.once(\"end\", requestShutdown);\n process.stdin.once(\"close\", requestShutdown);\n process.once(\"SIGINT\", requestShutdown);\n if (process.platform !== \"win32\") {\n process.once(\"SIGHUP\", requestShutdown);\n process.once(\"SIGTERM\", requestShutdown);\n }\n\n await server.connect(transport);\n if (shutdownPromise) return;\n\n const isHomeDir = isHomeDirectory(args.project);\n const isValidProject = !isHomeDir && (!config.indexing.requireProjectMarker || hasProjectMarker(args.project));\n\n if (config.indexing.watchFiles && isValidProject) {\n watcher = createWatcherWithIndexer(\n () => getIndexerForProject(args.project, args.host),\n args.project,\n config,\n args.host,\n args.config ? { configPath: args.config } : {},\n );\n }\n}\n\ninterface CliIndexCommandDeps {\n runIndex?: (\n projectRoot: string | undefined,\n host: HostMode,\n args: SharedIndexCodebaseArgs,\n onProgress?: (title: string, metadata: Record<string, unknown>) => void,\n ) => Promise<{ text: string; isError?: boolean }>;\n initializeRuntimeForConfig?: (projectRoot: string, parsedConfig: ReturnType<typeof parseConfig>, host: HostMode) => void;\n readCliConfigFile?: (filePath: string) => unknown;\n printStdout?: (text: string) => void;\n printStderr?: (text: string) => void;\n}\n\nfunction printIndexProgress(onProgress: (text: string) => void, title: string, metadata: Record<string, unknown>): void {\n const details = Object.entries(metadata)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => `${key}=${isSensitiveKey(key) ? \"[REDACTED]\" : String(value)}`)\n .join(\" \");\n onProgress(details.length === 0 ? title : `${title} ${details}`);\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return /(?:api[-_]?key|token|password|secret|authorization)/i.test(key);\n}\n\nexport function redactSensitiveText(text: string): string {\n return text.replace(\n /((?:api[-_]?key|token|password|secret|authorization)\\s*[=:]\\s*)([^\\s,;]+)/gi,\n \"$1[REDACTED]\",\n );\n}\n\nexport async function handleIndexCommand(\n argv: string[],\n cwd: string,\n deps: CliIndexCommandDeps = {},\n): Promise<number> {\n const runIndex = deps.runIndex ?? executeIndexCodebase;\n const initializeRuntimeForConfig = deps.initializeRuntimeForConfig ?? initializeTools;\n const readCliConfigFile = deps.readCliConfigFile ?? loadConfigFile;\n const printStdout = deps.printStdout ?? ((text) => console.log(text));\n const printStderr = deps.printStderr ?? ((text) => console.error(redactSensitiveText(text)));\n\n let parsedArgs: CliIndexArgs;\n try {\n parsedArgs = parseIndexArgs(argv, cwd);\n } catch (error) {\n if (error instanceof Error && error.message === \"help-requested\") {\n printUsage(printStderr);\n return 0;\n }\n printStderr(error instanceof Error ? error.message : String(error));\n printUsage(printStderr);\n return 1;\n }\n\n try {\n if (parsedArgs.config !== undefined) {\n const rawConfig = readCliConfigFile(parsedArgs.config);\n if (rawConfig === null) {\n throw new Error(`Config file not found: ${parsedArgs.config}`);\n }\n initializeRuntimeForConfig(parsedArgs.project, parseConfig(rawConfig), parsedArgs.host);\n }\n\n const indexArgs: SharedIndexCodebaseArgs = {\n force: parsedArgs.force,\n estimateOnly: parsedArgs.estimateOnly,\n dryRun: parsedArgs.dryRun,\n verbose: parsedArgs.verbose,\n };\n\n const result = await runIndex(parsedArgs.project, parsedArgs.host, indexArgs, (title, metadata) => {\n printIndexProgress(printStderr, title, metadata);\n });\n\n if (result.isError) {\n printStderr(result.text);\n return 1;\n }\n\n printStdout(result.text);\n return 0;\n } catch (error) {\n printStderr(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n\nexport function handleMainError(error: unknown): never {\n if (error instanceof Error && error.message.startsWith(\"Invalid host mode\")) {\n console.error(`Invalid host mode. Allowed values: ${HOST_MODES.join(\", \")}.`);\n process.exit(1);\n }\n\n if (error instanceof Error) {\n console.error(\"Failed to start MCP server. Check config and network.\");\n process.exit(1);\n }\n\n console.error(\"Fatal: failed to start MCP server\");\n process.exit(1);\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport * as path from \"path\";\n\nimport {\n formatMs,\n formatPct,\n formatUsd,\n signed,\n type LoadSummaryOptions,\n validateSummary,\n} from \"./report-formatters.js\";\nimport type {\n EvalComparison,\n EvalGateResult,\n EvalSummary,\n PerQueryEvalResult,\n SweepAggregateReport,\n} from \"./types.js\";\n\nexport function loadSummary(summaryPath: string, options?: LoadSummaryOptions): EvalSummary {\n try {\n const raw = readFileSync(summaryPath, \"utf-8\");\n const parsed = JSON.parse(raw) as EvalSummary;\n return validateSummary(parsed, summaryPath, options);\n } catch (error: unknown) {\n if (error instanceof SyntaxError) {\n const message = error.message;\n throw new Error(`Failed to parse eval summary JSON at ${summaryPath}: ${message}`);\n }\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new Error(`Failed to load eval summary at ${summaryPath}: ${String(error)}`);\n }\n}\n\nexport function createRunDirectory(outputRoot: string, timestampOverride?: string): string {\n const timestamp = (timestampOverride ?? new Date().toISOString()).replace(/[:.]/g, \"-\");\n const dir = path.join(outputRoot, timestamp);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nexport function writeJson(filePath: string, value: unknown): void {\n writeFileSync(filePath, JSON.stringify(value, null, 2), \"utf-8\");\n}\n\nexport function writeText(filePath: string, value: string): void {\n writeFileSync(filePath, value, \"utf-8\");\n}\n\nexport function createSummaryMarkdown(\n summary: EvalSummary,\n comparison?: EvalComparison,\n gate?: EvalGateResult,\n sweep?: SweepAggregateReport\n): string {\n const lines: string[] = [];\n\n lines.push(\"# Evaluation Summary\");\n lines.push(\"\");\n lines.push(`- Generated: ${summary.generatedAt}`);\n lines.push(`- Dataset: ${summary.datasetName} (v${summary.datasetVersion})`);\n lines.push(`- Query count: ${summary.queryCount}`);\n lines.push(\n `- Search config: fusion=${summary.searchConfig.fusionStrategy}, hybridWeight=${summary.searchConfig.hybridWeight}, rrfK=${summary.searchConfig.rrfK}, rerankTopN=${summary.searchConfig.rerankTopN}`\n );\n lines.push(\"\");\n\n lines.push(\"## Metrics\");\n lines.push(\"\");\n lines.push(\"| Metric | Value |\");\n lines.push(\"|---|---:|\");\n lines.push(`| Hit@1 | ${formatPct(summary.metrics.hitAt1)} |`);\n lines.push(`| Hit@3 | ${formatPct(summary.metrics.hitAt3)} |`);\n lines.push(`| Hit@5 | ${formatPct(summary.metrics.hitAt5)} |`);\n lines.push(`| Hit@10 | ${formatPct(summary.metrics.hitAt10)} |`);\n lines.push(`| MRR@10 | ${summary.metrics.mrrAt10.toFixed(4)} |`);\n lines.push(`| nDCG@10 | ${summary.metrics.ndcgAt10.toFixed(4)} |`);\n lines.push(`| Graph-neighbor recall | ${(summary.metrics.graphNeighborRecall ?? 0).toFixed(4)} |`);\n lines.push(`| Distinct Top@3 | ${formatPct(summary.metrics.distinctTop3Ratio)} |`);\n lines.push(`| Raw Distinct Top@3 | ${formatPct(summary.metrics.rawDistinctTop3Ratio)} |`);\n lines.push(`| Latency p50 | ${formatMs(summary.metrics.latencyMs.p50)} |`);\n lines.push(`| Latency p95 | ${formatMs(summary.metrics.latencyMs.p95)} |`);\n lines.push(`| Latency p99 | ${formatMs(summary.metrics.latencyMs.p99)} |`);\n lines.push(`| Embedding calls | ${summary.metrics.embedding.callCount} |`);\n lines.push(`| Embedding tokens | ${summary.metrics.tokenEstimate.embeddingTokensUsed} |`);\n lines.push(`| Estimated embedding cost | ${formatUsd(summary.metrics.embedding.estimatedCostUsd)} |`);\n lines.push(`| Context queries | ${summary.metrics.contextEfficiency.queryCount} |`);\n lines.push(`| Context response tokens total | ${summary.metrics.contextEfficiency.responseTokens.total} |`);\n lines.push(`| Context response tokens avg | ${summary.metrics.contextEfficiency.responseTokens.average.toFixed(1)} |`);\n lines.push(`| Context response tokens p95 | ${summary.metrics.contextEfficiency.responseTokens.p95.toFixed(1)} |`);\n lines.push(`| Context response tokens max | ${summary.metrics.contextEfficiency.responseTokens.max.toFixed(1)} |`);\n lines.push(`| Context duplicate candidate ratio | ${formatPct(summary.metrics.contextEfficiency.duplicateCandidateRatio)} |`);\n lines.push(`| Context selected-file ratio | ${formatPct(summary.metrics.contextEfficiency.selectedFileRatio)} |`);\n lines.push(`| Context Hit@5 / 1k response tokens | ${summary.metrics.contextEfficiency.hitAt5Per1kResponseTokens.toFixed(4)} |`);\n lines.push(`| Context MRR@10 / 1k response tokens | ${summary.metrics.contextEfficiency.mrrAt10Per1kResponseTokens.toFixed(4)} |`);\n lines.push(\"\");\n\n lines.push(\"## Failure Buckets\");\n lines.push(\"\");\n lines.push(\"| Bucket | Count |\");\n lines.push(\"|---|---:|\");\n lines.push(\n `| wrong-file | ${summary.metrics.failureBuckets[\"wrong-file\"]} |`\n );\n lines.push(\n `| wrong-symbol | ${summary.metrics.failureBuckets[\"wrong-symbol\"]} |`\n );\n lines.push(\n `| docs/tests outranking source | ${summary.metrics.failureBuckets[\"docs-tests-outranking-source\"]} |`\n );\n lines.push(\n `| no relevant hit in top-k | ${summary.metrics.failureBuckets[\"no-relevant-hit-top-k\"]} |`\n );\n lines.push(\"\");\n\n if (comparison) {\n lines.push(\"## Comparison vs Baseline\");\n lines.push(\"\");\n lines.push(`- Against: ${comparison.againstPath}`);\n lines.push(\"\");\n lines.push(\"| Metric | Baseline | Current | Delta |\");\n lines.push(\"|---|---:|---:|---:|\");\n lines.push(\n `| Hit@5 | ${formatPct(comparison.deltas.hitAt5.baseline)} | ${formatPct(comparison.deltas.hitAt5.current)} | ${signed(comparison.deltas.hitAt5.absolute)} |`\n );\n lines.push(\n `| MRR@10 | ${comparison.deltas.mrrAt10.baseline.toFixed(4)} | ${comparison.deltas.mrrAt10.current.toFixed(4)} | ${signed(comparison.deltas.mrrAt10.absolute)} |`\n );\n lines.push(\n `| nDCG@10 | ${comparison.deltas.ndcgAt10.baseline.toFixed(4)} | ${comparison.deltas.ndcgAt10.current.toFixed(4)} | ${signed(comparison.deltas.ndcgAt10.absolute)} |`\n );\n lines.push(\n `| Distinct Top@3 | ${formatPct(comparison.deltas.distinctTop3Ratio.baseline)} | ${formatPct(comparison.deltas.distinctTop3Ratio.current)} | ${signed(comparison.deltas.distinctTop3Ratio.absolute)} |`\n );\n lines.push(\n `| Raw Distinct Top@3 | ${formatPct(comparison.deltas.rawDistinctTop3Ratio.baseline)} | ${formatPct(comparison.deltas.rawDistinctTop3Ratio.current)} | ${signed(comparison.deltas.rawDistinctTop3Ratio.absolute)} |`\n );\n lines.push(\n `| p95 latency (ms) | ${comparison.deltas.latencyP95Ms.baseline.toFixed(3)} | ${comparison.deltas.latencyP95Ms.current.toFixed(3)} | ${signed(comparison.deltas.latencyP95Ms.absolute, 3)} |`\n );\n lines.push(\n `| Context response tokens avg | ${comparison.deltas.contextResponseTokensAverage.baseline.toFixed(1)} | ${comparison.deltas.contextResponseTokensAverage.current.toFixed(1)} | ${signed(comparison.deltas.contextResponseTokensAverage.absolute, 1)} |`\n );\n lines.push(\n `| Context response tokens p95 | ${comparison.deltas.contextResponseTokensP95.baseline.toFixed(1)} | ${comparison.deltas.contextResponseTokensP95.current.toFixed(1)} | ${signed(comparison.deltas.contextResponseTokensP95.absolute, 1)} |`\n );\n lines.push(\n `| Context response tokens max | ${comparison.deltas.contextResponseTokensMax.baseline.toFixed(1)} | ${comparison.deltas.contextResponseTokensMax.current.toFixed(1)} | ${signed(comparison.deltas.contextResponseTokensMax.absolute, 1)} |`\n );\n lines.push(\n `| Context duplicate candidate ratio | ${formatPct(comparison.deltas.contextDuplicateCandidateRatio.baseline)} | ${formatPct(comparison.deltas.contextDuplicateCandidateRatio.current)} | ${signed(comparison.deltas.contextDuplicateCandidateRatio.absolute)} |`\n );\n lines.push(\n `| Context selected-file ratio | ${formatPct(comparison.deltas.contextSelectedFileRatio.baseline)} | ${formatPct(comparison.deltas.contextSelectedFileRatio.current)} | ${signed(comparison.deltas.contextSelectedFileRatio.absolute)} |`\n );\n lines.push(\n `| Context Hit@5 / 1k response tokens | ${comparison.deltas.contextHitAt5Per1kResponseTokens.baseline.toFixed(4)} | ${comparison.deltas.contextHitAt5Per1kResponseTokens.current.toFixed(4)} | ${signed(comparison.deltas.contextHitAt5Per1kResponseTokens.absolute)} |`\n );\n lines.push(\n `| Context MRR@10 / 1k response tokens | ${comparison.deltas.contextMrrAt10Per1kResponseTokens.baseline.toFixed(4)} | ${comparison.deltas.contextMrrAt10Per1kResponseTokens.current.toFixed(4)} | ${signed(comparison.deltas.contextMrrAt10Per1kResponseTokens.absolute)} |`\n );\n lines.push(\"\");\n }\n\n if (gate) {\n lines.push(\"## CI Gate\");\n lines.push(\"\");\n lines.push(`- Result: ${gate.passed ? \"PASS ✅\" : \"FAIL ❌\"}`);\n if (gate.violations.length > 0) {\n lines.push(\"- Violations:\");\n for (const violation of gate.violations) {\n lines.push(` - ${violation.metric}: ${violation.message}`);\n }\n }\n lines.push(\"\");\n }\n\n if (sweep) {\n lines.push(\"## Parameter Sweep\");\n lines.push(\"\");\n lines.push(`- Run count: ${sweep.runCount}`);\n if (sweep.bestByHitAt5) {\n lines.push(\n `- Best Hit@5: ${formatPct(sweep.bestByHitAt5.summary.metrics.hitAt5)} with fusion=${sweep.bestByHitAt5.searchConfig.fusionStrategy}, hybridWeight=${sweep.bestByHitAt5.searchConfig.hybridWeight}, rrfK=${sweep.bestByHitAt5.searchConfig.rrfK}, rerankTopN=${sweep.bestByHitAt5.searchConfig.rerankTopN}`\n );\n }\n if (sweep.bestByMrrAt10) {\n lines.push(\n `- Best MRR@10: ${sweep.bestByMrrAt10.summary.metrics.mrrAt10.toFixed(4)} with fusion=${sweep.bestByMrrAt10.searchConfig.fusionStrategy}, hybridWeight=${sweep.bestByMrrAt10.searchConfig.hybridWeight}, rrfK=${sweep.bestByMrrAt10.searchConfig.rrfK}, rerankTopN=${sweep.bestByMrrAt10.searchConfig.rerankTopN}`\n );\n }\n if (sweep.bestByP95Latency) {\n lines.push(\n `- Best p95 latency: ${formatMs(sweep.bestByP95Latency.summary.metrics.latencyMs.p95)} with fusion=${sweep.bestByP95Latency.searchConfig.fusionStrategy}, hybridWeight=${sweep.bestByP95Latency.searchConfig.hybridWeight}, rrfK=${sweep.bestByP95Latency.searchConfig.rrfK}, rerankTopN=${sweep.bestByP95Latency.searchConfig.rerankTopN}`\n );\n }\n lines.push(\"\");\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport function buildPerQueryArtifact(perQuery: PerQueryEvalResult[]): {\n queryCount: number;\n queries: PerQueryEvalResult[];\n} {\n return {\n queryCount: perQuery.length,\n queries: [...perQuery].sort((a, b) => a.id.localeCompare(b.id)),\n };\n}\n","import * as crypto from \"node:crypto\";\nimport { existsSync } from \"fs\";\nimport * as path from \"path\";\nimport { performance } from \"perf_hooks\";\n\nimport { Indexer, type SearchResult } from \"../indexer/index.js\";\nimport type { CallEdgeData, SymbolData } from \"../native/index.js\";\nimport { DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT } from \"../tools/contracts.js\";\nimport { resolveSearchContext } from \"../tools/context.js\";\nimport { resolveCodebaseEditContextWithDependencies } from \"../tools/edit-context.js\";\nimport {\n getCallGraphDataForIndexer,\n type CallGraphDataResult,\n type CallGraphSymbolResolution,\n} from \"../tools/operations.js\";\nimport { DEFAULT_CONTEXT_PACK_TOKEN_BUDGET } from \"../tools/utils.js\";\n\nimport { evaluateBudgetGate } from \"./budget.js\";\nimport { compareSummaries } from \"./compare.js\";\nimport { buildPerQueryResult, computeEvalMetrics } from \"./metrics.js\";\nimport {\n clearIndexRoot,\n ensureLocalEvalProjectConfig,\n getEmbeddingCostPer1MTokens,\n loadParsedConfig,\n resolveSearchConfig,\n toAbsolute,\n} from \"./runner-config.js\";\nimport {\n createSummaryMarkdown,\n createRunDirectory,\n loadSummary,\n writeJson,\n writeText,\n buildPerQueryArtifact,\n} from \"./reports.js\";\nimport { loadBudget, loadGoldenDataset } from \"./schema.js\";\nimport type {\n EvalComparison,\n EvalGateResult,\n EvalRunOptions,\n EvalSearchResult,\n GoldenDataset,\n GoldenQuery,\n EvalSummary,\n PerQueryEvalResult,\n SweepAggregateReport,\n SweepDefinition,\n SweepRunSummary,\n} from \"./types.js\";\n\nfunction normalizeForFingerprint(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => normalizeForFingerprint(entry));\n }\n\n if (value && typeof value === \"object\") {\n const normalized: Record<string, unknown> = {};\n for (const key of Object.keys(value).sort()) {\n const normalizedValue = normalizeForFingerprint((value as Record<string, unknown>)[key]);\n if (normalizedValue !== undefined) {\n normalized[key] = normalizedValue;\n }\n }\n\n return normalized;\n }\n\n return value;\n}\n\nfunction buildDatasetFingerprint(dataset: GoldenDataset): string {\n const canonical = JSON.stringify(normalizeForFingerprint(dataset));\n return crypto.createHash(\"sha256\").update(canonical).digest(\"hex\");\n}\n\nfunction normalizedPath(value: string): string {\n return value.replaceAll(\"\\\\\", \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction pathsMatch(left: string, right: string): boolean {\n const normalizedLeft = normalizedPath(left);\n const normalizedRight = normalizedPath(right);\n return normalizedLeft === normalizedRight\n || normalizedLeft.endsWith(`/${normalizedRight}`)\n || normalizedRight.endsWith(`/${normalizedLeft}`);\n}\n\nfunction toEvalSearchResult(result: SearchResult): EvalSearchResult {\n return {\n filePath: result.filePath,\n startLine: result.startLine,\n endLine: result.endLine,\n score: result.score,\n chunkType: result.chunkType,\n name: result.name,\n };\n}\n\nfunction selectResolvedTarget(\n definitions: SearchResult[],\n resolution: CallGraphSymbolResolution | undefined,\n): SearchResult | undefined {\n if (resolution?.status !== \"resolved\") return definitions[0];\n return definitions.find((result) => pathsMatch(result.filePath, resolution.filePath)\n && result.startLine <= resolution.startLine\n && result.endLine >= resolution.startLine)\n ?? definitions.find((result) => pathsMatch(result.filePath, resolution.filePath)\n && result.name === resolution.name)\n ?? definitions[0];\n}\n\nfunction callerResult(edge: CallEdgeData): EvalSearchResult | undefined {\n if (!edge.fromSymbolFilePath) return undefined;\n return {\n filePath: edge.fromSymbolFilePath,\n startLine: edge.line,\n endLine: edge.line,\n score: 0,\n chunkType: \"graph-caller\",\n name: edge.fromSymbolName,\n graphDirection: \"caller\",\n };\n}\n\nfunction calleeResult(edge: CallEdgeData, symbols: SymbolData[]): EvalSearchResult | undefined {\n const symbol = edge.toSymbolId\n ? symbols.find((candidate) => candidate.id === edge.toSymbolId)\n : symbols.filter((candidate) => candidate.name === edge.targetName).length === 1\n ? symbols.find((candidate) => candidate.name === edge.targetName)\n : undefined;\n if (!symbol) return undefined;\n return {\n filePath: symbol.filePath,\n startLine: symbol.startLine,\n endLine: symbol.endLine,\n score: 0,\n chunkType: \"graph-callee\",\n name: symbol.name,\n graphDirection: \"callee\",\n };\n}\n\nasync function runEditContextQuery(\n indexer: Indexer,\n projectRoot: string,\n query: GoldenQuery,\n): Promise<{\n results: EvalSearchResult[];\n resolvedRoute: \"search\" | \"definition\";\n routedQuery: string;\n context: {\n tokenBudget: number;\n responseTokens: number;\n candidateCount: number;\n deduplicatedCount: number;\n omittedCount: number;\n };\n}> {\n let definitions: SearchResult[] = [];\n let conceptual: SearchResult[] = [];\n let callers: CallGraphDataResult | undefined;\n let callees: CallGraphDataResult | undefined;\n\n const editContext = await resolveCodebaseEditContextWithDependencies({\n query: query.query,\n symbol: query.args?.symbol,\n filePath: query.args?.filePath ?? query.expected.filePath,\n callerLimit: query.args?.callerLimit,\n calleeLimit: query.args?.calleeLimit,\n tokenBudget: query.args?.tokenBudget,\n }, {\n searchCodebase: async (searchQuery, options) => {\n conceptual = await indexer.search(searchQuery, options?.limit, {\n filterByBranch: !!query.expected.branch,\n });\n return conceptual;\n },\n implementationLookup: async (symbol, options) => {\n definitions = await indexer.search(symbol, options?.limit, {\n filterByBranch: !!query.expected.branch,\n definitionIntent: true,\n });\n return definitions;\n },\n getCallGraphData: async (params) => {\n const result = await getCallGraphDataForIndexer(indexer, projectRoot, params);\n if (params.direction === \"callers\") callers = result;\n else callees = result;\n return result;\n },\n });\n\n const resolution = callers?.resolution;\n const target = selectResolvedTarget(definitions, resolution);\n const targetCandidates = target ? [target] : [...definitions, ...conceptual];\n const results = targetCandidates\n .filter((candidate) => (\n resolution?.status !== \"resolved\" || editContext.details.sourceIncluded\n ) && editContext.text.includes(\n `${candidate.filePath}:${candidate.startLine}-${candidate.endLine}`,\n ))\n .map(toEvalSearchResult);\n\n if (query.expected.graphNeighbor) {\n const symbols = await indexer.getCallGraphSymbols();\n const callerLimit = query.args?.callerLimit ?? DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT;\n const calleeLimit = query.args?.calleeLimit ?? DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT;\n const publishedCallers = (callers?.callers ?? []).slice(0, callerLimit).filter((edge) =>\n editContext.text.includes(\n `${edge.fromSymbolName ?? \"<unknown>\"} at ${edge.fromSymbolFilePath ?? \"<unknown file>\"}:${edge.line} (${edge.callType}, ${edge.isResolved ? \"resolved\" : \"unresolved\"})`,\n ));\n const publishedCallees = (callees?.callees ?? []).slice(0, calleeLimit).filter((edge) =>\n resolution?.status === \"resolved\"\n && editContext.text.includes(\n `${edge.targetName} from ${resolution.filePath}:${edge.line} (${edge.callType}, ${edge.isResolved ? \"resolved\" : \"unresolved\"})`,\n ));\n results.push(\n ...publishedCallers.map(callerResult).filter((item): item is EvalSearchResult => item !== undefined),\n ...publishedCallees.map((edge) => calleeResult(edge, symbols)).filter((item): item is EvalSearchResult => item !== undefined),\n );\n }\n\n return {\n results,\n resolvedRoute: resolution?.status === \"resolved\" ? \"definition\" : \"search\",\n routedQuery: query.args?.symbol ?? query.query,\n context: {\n tokenBudget: editContext.details.tokenBudget,\n responseTokens: editContext.details.tokenEstimate,\n candidateCount: results.length,\n deduplicatedCount: results.length,\n omittedCount: 0,\n },\n };\n}\n\nexport interface EvalRunResult {\n outputDir: string;\n summary: EvalSummary;\n perQuery: PerQueryEvalResult[];\n comparison?: EvalComparison;\n gate?: EvalGateResult;\n}\n\nexport async function runEvaluation(options: EvalRunOptions): Promise<EvalRunResult> {\n const datasetPath = toAbsolute(options.projectRoot, options.datasetPath);\n const againstPath = options.againstPath ? toAbsolute(options.projectRoot, options.againstPath) : undefined;\n const budgetPath = options.budgetPath ? toAbsolute(options.projectRoot, options.budgetPath) : undefined;\n\n const dataset = loadGoldenDataset(datasetPath);\n\n const resolvedEvalConfigPath = options.reindex\n ? ensureLocalEvalProjectConfig(options.projectRoot, options.configPath)\n : options.configPath;\n\n const parsedConfig = loadParsedConfig(options.projectRoot, resolvedEvalConfigPath);\n const effectiveConfig = resolveSearchConfig(parsedConfig, options.searchOverrides);\n\n if (options.reindex) {\n clearIndexRoot(options.projectRoot, effectiveConfig.scope);\n }\n\n const indexer = new Indexer(options.projectRoot, effectiveConfig, \"opencode\");\n\n try {\n await indexer.index();\n\n if (options.ciMode) {\n const indexStatus = await indexer.getStatus();\n if (!indexStatus.indexed || indexStatus.vectorCount === 0) {\n const failedBatchDetails = indexStatus.failedBatchesCount > 0\n ? ` ${indexStatus.failedBatchesCount} embedding batch(es) failed; diagnostics: ${indexStatus.failedBatchesPath ?? \"unavailable\"}.`\n : \"\";\n throw new Error(\n `Evaluation reindex produced no searchable vectors.${failedBatchDetails} Check the embedding provider and indexing diagnostics before evaluating retrieval quality.`\n );\n }\n }\n\n const perQuery: PerQueryEvalResult[] = [];\n\n for (const query of dataset.queries) {\n if (query.expected.branch && query.expected.branch !== indexer.getCurrentBranch()) {\n throw new Error(\n `Query '${query.id}' expects branch '${query.expected.branch}', but current branch is '${indexer.getCurrentBranch()}'. Switch branch before running this dataset.`\n );\n }\n\n const start = performance.now();\n const editContextResult = query.retrievalMode === \"edit-context\"\n ? await runEditContextQuery(indexer, options.projectRoot, query)\n : undefined;\n const contextResult = query.retrievalMode === \"context\"\n ? await resolveSearchContext({\n query: query.query,\n symbol: query.args?.symbol,\n fileType: query.args?.fileType,\n directory: query.args?.directory,\n limit: 10,\n tokenBudget: DEFAULT_CONTEXT_PACK_TOKEN_BUDGET,\n }, {\n lookup: (symbol, limit, scope) => indexer.search(symbol, limit, {\n metadataOnly: true,\n filterByBranch: !!query.expected.branch,\n definitionIntent: true,\n fileType: scope.fileType,\n directory: scope.directory,\n }),\n search: (searchQuery, limit, scope, _trace, searchOptions) => indexer.search(searchQuery, limit, {\n metadataOnly: true,\n filterByBranch: !!query.expected.branch,\n definitionIntent: false,\n fileType: scope.fileType,\n directory: scope.directory,\n prioritizeSourcePaths: searchOptions?.prioritizeSourcePaths,\n }),\n })\n : undefined;\n const result = editContextResult?.results\n ?? contextResult?.details?.results\n ?? await indexer.search(query.query, 10, {\n metadataOnly: true,\n filterByBranch: !!query.expected.branch,\n fileType: query.args?.fileType,\n directory: query.args?.directory,\n });\n const elapsed = performance.now() - start;\n const resolvedRoute = editContextResult?.resolvedRoute\n ?? (contextResult?.details?.route === \"definition\" ? \"definition\" : \"search\");\n const routedQuery = editContextResult?.routedQuery\n ?? contextResult?.details?.routedQuery\n ?? query.query;\n const successfulRecoveryAttempt = contextResult?.details?.recovery?.successfulAttemptIndex;\n const recoveryAttempts = contextResult?.details?.recovery?.attempts ?? [];\n const recoveryRelaxed = successfulRecoveryAttempt === undefined\n ? false\n : (recoveryAttempts[successfulRecoveryAttempt]?.relaxedFields.length ?? 0) > 0;\n const recoveryUsed = recoveryAttempts.length > 1\n || recoveryAttempts.some((attempt) => attempt.relaxedFields.length > 0);\n\n const materialized: EvalSearchResult[] = result.map((item) => {\n const graphDirection: EvalSearchResult[\"graphDirection\"] = \"graphDirection\" in item\n && (item.graphDirection === \"caller\" || item.graphDirection === \"callee\")\n ? item.graphDirection\n : undefined;\n return {\n filePath: item.filePath,\n startLine: item.startLine,\n endLine: item.endLine,\n score: item.score,\n chunkType: item.chunkType,\n name: item.name,\n graphDirection,\n };\n });\n\n const contextMeasurement = editContextResult?.context ?? (contextResult?.details ? {\n tokenBudget: contextResult.details.tokenBudget,\n responseTokens: contextResult.details.tokenEstimate,\n candidateCount: contextResult.details.candidateCount ?? 0,\n deduplicatedCount: contextResult.details.deduplicatedCount ?? 0,\n omittedCount: contextResult.details.omittedCount ?? 0,\n recoveryUsed,\n recoveryRelaxed,\n } : undefined);\n\n perQuery.push(buildPerQueryResult(query, materialized, elapsed, 10, {\n resolvedRoute,\n routedQuery,\n }, contextMeasurement));\n }\n\n const logger = indexer.getLogger();\n const metricSnapshot = logger.getMetrics();\n\n const costPer1MTokensUsd = getEmbeddingCostPer1MTokens(effectiveConfig.embeddingProvider);\n\n const summary: EvalSummary = {\n generatedAt: new Date().toISOString(),\n projectRoot: options.projectRoot,\n datasetPath,\n datasetName: dataset.name,\n datasetVersion: dataset.version,\n datasetFingerprint: buildDatasetFingerprint(dataset),\n queryCount: dataset.queries.length,\n topK: 10,\n searchConfig: {\n fusionStrategy: effectiveConfig.search.fusionStrategy,\n hybridWeight: effectiveConfig.search.hybridWeight,\n rrfK: effectiveConfig.search.rrfK,\n rerankTopN: effectiveConfig.search.rerankTopN,\n },\n metrics: computeEvalMetrics(\n dataset.queries,\n perQuery,\n metricSnapshot.embeddingApiCalls,\n metricSnapshot.embeddingTokensUsed,\n costPer1MTokensUsd\n ),\n };\n\n const outputDir = createRunDirectory(toAbsolute(options.projectRoot, options.outputRoot));\n const perQueryArtifact = buildPerQueryArtifact(perQuery);\n\n writeJson(path.join(outputDir, \"summary.json\"), summary);\n writeJson(path.join(outputDir, \"per-query.json\"), perQueryArtifact);\n\n let comparison: EvalComparison | undefined;\n if (againstPath) {\n const baseline = loadSummary(againstPath);\n comparison = compareSummaries(summary, baseline, againstPath);\n writeJson(path.join(outputDir, \"compare.json\"), comparison);\n }\n\n let gate: EvalGateResult | undefined;\n if (options.ciMode) {\n if (!budgetPath) {\n throw new Error(\"CI mode requires --budget path\");\n }\n const budget = loadBudget(budgetPath);\n\n if (!comparison && budget.baselinePath) {\n const resolvedBaseline = toAbsolute(options.projectRoot, budget.baselinePath);\n if (existsSync(resolvedBaseline)) {\n const baselineSummary = loadSummary(resolvedBaseline);\n comparison = compareSummaries(summary, baselineSummary, resolvedBaseline);\n writeJson(path.join(outputDir, \"compare.json\"), comparison);\n } else if (budget.failOnMissingBaseline) {\n throw new Error(\n `Budget baseline is missing: ${resolvedBaseline}. Set failOnMissingBaseline=false to allow CI run without baseline.`\n );\n }\n }\n\n gate = evaluateBudgetGate(budget, summary, comparison);\n }\n\n const markdown = createSummaryMarkdown(summary, comparison, gate);\n writeText(path.join(outputDir, \"summary.md\"), markdown);\n\n return { outputDir, summary, perQuery, comparison, gate };\n } finally {\n await indexer.close();\n }\n}\n\nexport async function runSweep(\n options: EvalRunOptions,\n sweep: SweepDefinition\n): Promise<{ outputDir: string; aggregate: SweepAggregateReport }> {\n const fusionValues: Array<\"rrf\" | \"weighted\" | undefined> =\n sweep.fusionStrategy && sweep.fusionStrategy.length > 0\n ? [...sweep.fusionStrategy]\n : [undefined];\n const weightValues: Array<number | undefined> =\n sweep.hybridWeight && sweep.hybridWeight.length > 0 ? [...sweep.hybridWeight] : [undefined];\n const rrfValues: Array<number | undefined> =\n sweep.rrfK && sweep.rrfK.length > 0 ? [...sweep.rrfK] : [undefined];\n const rerankValues: Array<number | undefined> =\n sweep.rerankTopN && sweep.rerankTopN.length > 0 ? [...sweep.rerankTopN] : [undefined];\n\n const runs: SweepRunSummary[] = [];\n\n for (const fusion of fusionValues) {\n for (const hybridWeight of weightValues) {\n for (const rrfK of rrfValues) {\n for (const rerankTopN of rerankValues) {\n const run = await runEvaluation({\n ...options,\n searchOverrides: {\n ...(fusion !== undefined ? { fusionStrategy: fusion } : {}),\n ...(hybridWeight !== undefined ? { hybridWeight } : {}),\n ...(rrfK !== undefined ? { rrfK } : {}),\n ...(rerankTopN !== undefined ? { rerankTopN } : {}),\n },\n });\n\n runs.push({\n searchConfig: run.summary.searchConfig,\n summary: run.summary,\n comparison: run.comparison,\n gate: run.gate,\n });\n }\n }\n }\n }\n\n const bestByHitAt5 = [...runs].sort(\n (a, b) => b.summary.metrics.hitAt5 - a.summary.metrics.hitAt5\n )[0];\n const bestByMrrAt10 = [...runs].sort(\n (a, b) => b.summary.metrics.mrrAt10 - a.summary.metrics.mrrAt10\n )[0];\n const bestByP95Latency = [...runs].sort(\n (a, b) => a.summary.metrics.latencyMs.p95 - b.summary.metrics.latencyMs.p95\n )[0];\n\n const outputDir = createRunDirectory(toAbsolute(options.projectRoot, options.outputRoot));\n const failedGateRuns = runs.filter((run) => run.gate && !run.gate.passed).length;\n const gatePassed = failedGateRuns === 0;\n const aggregate: SweepAggregateReport = {\n generatedAt: new Date().toISOString(),\n againstPath: options.againstPath,\n runCount: runs.length,\n runs,\n gatePassed,\n failedGateRuns,\n bestByHitAt5,\n bestByMrrAt10,\n bestByP95Latency,\n };\n\n writeJson(path.join(outputDir, \"compare.json\"), aggregate);\n const md = createSummaryMarkdown(\n bestByHitAt5?.summary ?? runs[0].summary,\n bestByHitAt5?.comparison,\n undefined,\n aggregate\n );\n writeText(path.join(outputDir, \"summary.md\"), md);\n writeJson(path.join(outputDir, \"summary.json\"), bestByHitAt5?.summary ?? runs[0].summary);\n\n return { outputDir, aggregate };\n}\n","import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport { getDefaultModelForProvider } from \"../config/index.js\";\nimport { getGlobalIndexPath, resolveProjectConfigPath, resolveProjectIndexPath } from \"../config/paths.js\";\nimport { rebasePathEntries, resolveInheritedKnowledgeBaseEntries } from \"../config/rebase.js\";\nimport { parseConfig, type SearchConfig as ConfigSearchConfig } from \"../config/schema.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction validateEvalConfigShape(rawConfig: unknown, filePath: string): Record<string, unknown> {\n if (!isRecord(rawConfig)) {\n throw new Error(`Eval config at ${filePath} must contain a JSON object at the root.`);\n }\n\n const config = rawConfig;\n\n if (config.knowledgeBases !== undefined && !isStringArray(config.knowledgeBases)) {\n throw new Error(`Eval config at ${filePath} field 'knowledgeBases' must be an array of strings.`);\n }\n if (config.additionalInclude !== undefined && !isStringArray(config.additionalInclude)) {\n throw new Error(`Eval config at ${filePath} field 'additionalInclude' must be an array of strings.`);\n }\n if (config.include !== undefined && !isStringArray(config.include)) {\n throw new Error(`Eval config at ${filePath} field 'include' must be an array of strings.`);\n }\n if (config.exclude !== undefined && !isStringArray(config.exclude)) {\n throw new Error(`Eval config at ${filePath} field 'exclude' must be an array of strings.`);\n }\n\n for (const section of [\"customProvider\", \"indexing\", \"search\", \"debug\", \"reranker\"] as const) {\n const value = config[section];\n if (value !== undefined && !isRecord(value)) {\n throw new Error(`Eval config at ${filePath} field '${section}' must be an object.`);\n }\n }\n\n return config;\n}\n\nfunction parseJsonConfigFile(filePath: string): unknown {\n try {\n return validateEvalConfigShape(JSON.parse(readFileSync(filePath, \"utf-8\")), filePath);\n } catch (error: unknown) {\n if (error instanceof Error && error.message.startsWith(\"Eval config at \")) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse eval config JSON at ${filePath}: ${message}`);\n }\n}\n\nexport function toAbsolute(projectRoot: string, maybeRelative: string): string {\n return path.isAbsolute(maybeRelative) ? maybeRelative : path.join(projectRoot, maybeRelative);\n}\n\nfunction isProjectScopedConfigPath(configPath: string): boolean {\n return path.basename(configPath) === \"codebase-index.json\"\n && path.basename(path.dirname(configPath)) === \".opencode\";\n}\n\nfunction normalizeEvalConfigKnowledgeBases(\n rawConfig: unknown,\n projectRoot: string,\n resolvedConfigPath: string,\n): Record<string, unknown> {\n const config = rawConfig && typeof rawConfig === \"object\"\n ? { ...(rawConfig as Record<string, unknown>) }\n : {};\n\n const rebaseEntries = (values: unknown): string[] => isProjectScopedConfigPath(resolvedConfigPath)\n ? resolveInheritedKnowledgeBaseEntries(\n values,\n path.dirname(path.dirname(resolvedConfigPath)),\n projectRoot,\n )\n : rebasePathEntries(\n values,\n path.dirname(resolvedConfigPath),\n projectRoot,\n );\n\n if (Array.isArray(config.knowledgeBases)) {\n config.knowledgeBases = rebaseEntries(config.knowledgeBases);\n }\n\n if (Array.isArray(config.additionalInclude)) {\n config.additionalInclude = rebaseEntries(config.additionalInclude);\n }\n\n return config;\n}\n\nfunction loadRawConfig(projectRoot: string, configPath?: string): unknown {\n const fromPath = configPath ? toAbsolute(projectRoot, configPath) : null;\n if (fromPath && existsSync(fromPath)) {\n return normalizeEvalConfigKnowledgeBases(\n parseJsonConfigFile(fromPath),\n projectRoot,\n fromPath,\n );\n }\n\n const projectConfig = resolveProjectConfigPath(projectRoot, \"opencode\");\n if (existsSync(projectConfig)) {\n return normalizeEvalConfigKnowledgeBases(\n parseJsonConfigFile(projectConfig),\n projectRoot,\n projectConfig,\n );\n }\n\n const globalConfig = path.join(os.homedir(), \".config\", \"opencode\", \"codebase-index.json\");\n if (existsSync(globalConfig)) {\n return parseJsonConfigFile(globalConfig);\n }\n\n return {};\n}\n\nfunction getIndexRootPath(projectRoot: string, scope: \"project\" | \"global\"): string {\n return scope === \"global\"\n ? getGlobalIndexPath(\"opencode\")\n : resolveProjectIndexPath(projectRoot, scope, \"opencode\");\n}\n\nfunction getLocalProjectIndexRoot(projectRoot: string): string {\n return path.join(projectRoot, \".opencode\", \"index\");\n}\n\nfunction getLocalProjectConfigPath(projectRoot: string): string {\n return path.join(projectRoot, \".opencode\", \"codebase-index.json\");\n}\n\nexport function clearIndexRoot(projectRoot: string, scope: \"project\" | \"global\"): void {\n const indexRoot = scope === \"global\"\n ? getIndexRootPath(projectRoot, scope)\n : getLocalProjectIndexRoot(projectRoot);\n if (existsSync(indexRoot)) {\n rmSync(indexRoot, { recursive: true, force: true });\n }\n}\n\nexport function ensureLocalEvalProjectConfig(projectRoot: string, configPath?: string): string | undefined {\n const localConfigPath = getLocalProjectConfigPath(projectRoot);\n const resolvedConfigPath = configPath\n ? toAbsolute(projectRoot, configPath)\n : resolveProjectConfigPath(projectRoot, \"opencode\");\n\n if (!configPath && existsSync(localConfigPath)) {\n return localConfigPath;\n }\n\n if (!existsSync(resolvedConfigPath) || resolvedConfigPath === localConfigPath) {\n return resolvedConfigPath;\n }\n\n const sourceConfig = normalizeEvalConfigKnowledgeBases(\n parseJsonConfigFile(resolvedConfigPath),\n projectRoot,\n resolvedConfigPath,\n );\n\n mkdirSync(path.dirname(localConfigPath), { recursive: true });\n writeFileSync(localConfigPath, JSON.stringify(sourceConfig, null, 2), \"utf-8\");\n return localConfigPath;\n}\n\nexport function loadParsedConfig(projectRoot: string, configPath?: string): ReturnType<typeof parseConfig> {\n const raw = loadRawConfig(projectRoot, configPath);\n return parseConfig(raw);\n}\n\nexport function resolveSearchConfig(\n parsedConfig: ReturnType<typeof parseConfig>,\n overrides?: Partial<Pick<ConfigSearchConfig, \"fusionStrategy\" | \"hybridWeight\" | \"rrfK\" | \"rerankTopN\">>\n): ReturnType<typeof parseConfig> {\n const nextSearch: ConfigSearchConfig = {\n ...parsedConfig.search,\n };\n\n if (overrides?.fusionStrategy !== undefined) {\n nextSearch.fusionStrategy = overrides.fusionStrategy;\n }\n if (overrides?.hybridWeight !== undefined) {\n nextSearch.hybridWeight = overrides.hybridWeight;\n }\n if (overrides?.rrfK !== undefined) {\n nextSearch.rrfK = overrides.rrfK;\n }\n if (overrides?.rerankTopN !== undefined) {\n nextSearch.rerankTopN = overrides.rerankTopN;\n }\n\n return {\n ...parsedConfig,\n search: nextSearch,\n };\n}\n\nexport function getEmbeddingCostPer1MTokens(\n embeddingProvider: ReturnType<typeof parseConfig>[\"embeddingProvider\"],\n): number {\n return embeddingProvider === \"custom\" || embeddingProvider === \"auto\"\n ? 0\n : getDefaultModelForProvider(embeddingProvider).costPer1MTokens;\n}\n","import { readFileSync } from \"fs\";\n\nimport type {\n EvalBudget,\n GoldenDataset,\n GoldenExpectedGraphNeighbor,\n GoldenExpected,\n GoldenGradedEvidence,\n GoldenQuery,\n GoldenQueryArgs,\n GoldenQueryDifficulty,\n GoldenQueryExpectedOutcome,\n GoldenQueryRecoveryExpectation,\n GoldenRetrievalMode,\n GoldenQueryType,\n} from \"./types.js\";\n\nfunction parseJsonFile(filePath: string): unknown {\n const content = readFileSync(filePath, \"utf-8\");\n\n try {\n return JSON.parse(content);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse JSON from ${filePath}: ${message}`);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction asPositiveNumber(value: unknown, path: string): number {\n if (typeof value !== \"number\" || Number.isNaN(value) || value < 0) {\n throw new Error(`${path} must be a non-negative number`);\n }\n return value;\n}\n\nfunction parseQueryType(value: unknown, path: string): GoldenQueryType {\n if (\n value === \"definition\" ||\n value === \"implementation-intent\" ||\n value === \"similarity\" ||\n value === \"keyword-heavy\" ||\n value === \"conceptual\"\n ) {\n return value;\n }\n throw new Error(\n `${path} must be one of: definition, implementation-intent, similarity, keyword-heavy, conceptual`\n );\n}\n\nfunction parseExpectedRoute(\n value: unknown,\n path: string,\n): \"search\" | \"definition\" | undefined {\n if (value === undefined) return undefined;\n if (value === \"search\" || value === \"definition\") return value;\n throw new Error(`${path} must be one of: search, definition`);\n}\n\nfunction parseExpectedOutcome(\n value: unknown,\n path: string,\n): GoldenQueryExpectedOutcome | undefined {\n if (value === undefined) return undefined;\n if (value === \"results\" || value === \"no-results\") {\n return value;\n }\n throw new Error(`${path} must be one of: results, no-results`);\n}\n\nfunction parseRecoveryExpectation(\n value: unknown,\n path: string,\n): GoldenQueryRecoveryExpectation | undefined {\n if (value === undefined) return undefined;\n if (value === \"none\" || value === \"filter-relaxed\") {\n return value;\n }\n throw new Error(`${path} must be one of: none, filter-relaxed`);\n}\n\nfunction parseQueryDifficulty(\n value: unknown,\n path: string,\n): GoldenQueryDifficulty | undefined {\n if (value === undefined) return undefined;\n if (value === \"easy\" || value === \"medium\" || value === \"hard\") {\n return value;\n }\n throw new Error(`${path} must be one of: easy, medium, hard`);\n}\n\nfunction parseQueryTags(value: unknown, path: string): string[] | undefined {\n if (value === undefined) return undefined;\n if (!isStringArray(value) || value.some((tag) => tag.trim().length === 0)) {\n throw new Error(`${path} must be an array of non-empty strings`);\n }\n if (value.length > 16) {\n throw new Error(`${path} must contain at most 16 tags`);\n }\n\n return value;\n}\n\nfunction parseQueryArgs(value: unknown, path: string): GoldenQueryArgs | undefined {\n if (value === undefined) return undefined;\n if (!isRecord(value)) {\n throw new Error(`${path} must be an object`);\n }\n\n const symbol = parseStringOrUndefined(value.symbol, `${path}.symbol`);\n const filePath = parseStringOrUndefined(value.filePath, `${path}.filePath`);\n const fileType = parseStringOrUndefined(value.fileType, `${path}.fileType`);\n const directory = parseStringOrUndefined(value.directory, `${path}.directory`);\n const callerLimit = parsePositiveIntegerOrUndefined(value.callerLimit, `${path}.callerLimit`);\n const calleeLimit = parsePositiveIntegerOrUndefined(value.calleeLimit, `${path}.calleeLimit`);\n const tokenBudget = parsePositiveIntegerOrUndefined(value.tokenBudget, `${path}.tokenBudget`);\n return {\n ...(symbol !== undefined ? { symbol } : {}),\n ...(filePath !== undefined ? { filePath } : {}),\n ...(fileType !== undefined ? { fileType } : {}),\n ...(directory !== undefined ? { directory } : {}),\n ...(callerLimit !== undefined ? { callerLimit } : {}),\n ...(calleeLimit !== undefined ? { calleeLimit } : {}),\n ...(tokenBudget !== undefined ? { tokenBudget } : {}),\n };\n}\n\nfunction parsePositiveIntegerOrUndefined(value: unknown, path: string): number | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"number\" || !Number.isInteger(value) || value <= 0) {\n throw new Error(`${path} must be a positive integer`);\n }\n return value;\n}\n\nconst SEMVER_VERSION_PATTERN =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\n\nfunction parseSemanticVersion(value: unknown, path: string): string {\n if (!isNonEmptyString(value)) {\n throw new Error(`${path} must be a non-empty string`);\n }\n if (!SEMVER_VERSION_PATTERN.test(value)) {\n throw new Error(`${path} must be a valid semantic version (MAJOR.MINOR.PATCH)`);\n }\n\n return value;\n}\n\nfunction parseRetrievalMode(value: unknown, path: string): GoldenRetrievalMode {\n if (value === undefined || value === \"search\") return \"search\";\n if (value === \"context\" || value === \"edit-context\") return value;\n throw new Error(`${path} must be one of: search, context, edit-context`);\n}\n\nfunction parseStringOrUndefined(value: unknown, path: string): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (!isNonEmptyString(value)) {\n throw new Error(`${path} must be a non-empty string`);\n }\n\n return value;\n}\n\nfunction parseGradedEvidence(value: unknown, path: string): GoldenGradedEvidence[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) {\n throw new Error(`${path} must be an array`);\n }\n\n return value.map((entry, index) => {\n if (!isRecord(entry)) {\n throw new Error(`${path}[${index}] must be an object`);\n }\n\n const evidencePath = parseStringOrUndefined(entry.path, `${path}[${index}].path`);\n if (evidencePath === undefined) {\n throw new Error(`${path}[${index}].path is required`);\n }\n\n const symbol = parseStringOrUndefined(entry.symbol, `${path}[${index}].symbol`);\n const relevance = parseEvidenceRelevance(entry.relevance, `${path}[${index}].relevance`);\n\n return {\n path: evidencePath,\n ...(symbol !== undefined ? { symbol } : {}),\n relevance,\n };\n });\n}\n\nfunction parseEvidenceRelevance(\n value: unknown,\n path: string,\n): 1 | 2 | 3 {\n if (value === undefined) {\n throw new Error(`${path} is required`);\n }\n if (value !== 1 && value !== 2 && value !== 3) {\n throw new Error(`${path} must be 1, 2, or 3`);\n }\n\n return value;\n}\n\nfunction parseExpectedGraphNeighbor(\n value: unknown,\n path: string,\n): GoldenExpectedGraphNeighbor | undefined {\n if (value === undefined) return undefined;\n if (!isRecord(value)) {\n throw new Error(`${path} must be an object`);\n }\n\n if (value.direction !== \"caller\" && value.direction !== \"callee\") {\n throw new Error(`${path}.direction must be one of: caller, callee`);\n }\n const filePath = parseStringOrUndefined(value.filePath, `${path}.filePath`);\n const symbol = parseStringOrUndefined(value.symbol, `${path}.symbol`);\n if (filePath === undefined && symbol === undefined) {\n throw new Error(`${path} must include filePath or symbol`);\n }\n\n return {\n direction: value.direction,\n ...(filePath !== undefined ? { filePath } : {}),\n ...(symbol !== undefined ? { symbol } : {}),\n };\n}\n\nfunction parseExpected(input: unknown, path: string): GoldenExpected {\n if (!isRecord(input)) {\n throw new Error(`${path} must be an object`);\n }\n\n const filePathRaw = input.filePath;\n const acceptableFilesRaw = input.acceptableFiles;\n const symbolRaw = input.symbol;\n const branchRaw = input.branch;\n const expectedRouteRaw = input.expectedRoute;\n const expectedOutcomeRaw = input.expectedOutcome;\n const recoveryExpectationRaw = input.recoveryExpectation;\n const gradedEvidenceRaw = input.gradedEvidence;\n const graphNeighborRaw = input.graphNeighbor;\n\n const filePath = parseStringOrUndefined(filePathRaw, `${path}.filePath`);\n const acceptableFiles = isStringArray(acceptableFilesRaw) ? acceptableFilesRaw : undefined;\n const gradedEvidence = parseGradedEvidence(gradedEvidenceRaw, `${path}.gradedEvidence`);\n const graphNeighbor = parseExpectedGraphNeighbor(graphNeighborRaw, `${path}.graphNeighbor`);\n\n const expectedOutcome = parseExpectedOutcome(expectedOutcomeRaw, `${path}.expectedOutcome`);\n if (\n expectedOutcome !== \"no-results\" &&\n !filePath &&\n (!acceptableFiles || acceptableFiles.length === 0) &&\n gradedEvidence.length === 0\n ) {\n throw new Error(\n `${path} must include expected.filePath, expected.acceptableFiles, or expected.gradedEvidence`\n );\n }\n\n if (acceptableFilesRaw !== undefined && !isStringArray(acceptableFilesRaw)) {\n throw new Error(`${path}.acceptableFiles must be an array of strings`);\n }\n\n if (symbolRaw !== undefined && typeof symbolRaw !== \"string\") {\n throw new Error(`${path}.symbol must be a string when provided`);\n }\n\n if (branchRaw !== undefined && typeof branchRaw !== \"string\") {\n throw new Error(`${path}.branch must be a string when provided`);\n }\n\n const expectedRoute = parseExpectedRoute(expectedRouteRaw, `${path}.expectedRoute`);\n const recoveryExpectation = parseRecoveryExpectation(\n recoveryExpectationRaw,\n `${path}.recoveryExpectation`\n );\n\n return {\n filePath,\n acceptableFiles,\n symbol: typeof symbolRaw === \"string\" ? symbolRaw : undefined,\n branch: typeof branchRaw === \"string\" ? branchRaw : undefined,\n expectedRoute,\n expectedOutcome,\n recoveryExpectation,\n ...(gradedEvidence.length > 0 ? { gradedEvidence } : {}),\n ...(graphNeighbor !== undefined ? { graphNeighbor } : {}),\n };\n}\n\nfunction parseQueryLanguage(value: unknown, path: string): string | undefined {\n return parseStringOrUndefined(value, path);\n}\n\nfunction parseQuery(input: unknown, index: number): GoldenQuery {\n const path = `queries[${index}]`;\n if (!isRecord(input)) {\n throw new Error(`${path} must be an object`);\n }\n\n const id = input.id;\n const query = input.query;\n const queryType = input.queryType;\n const retrievalMode = input.retrievalMode;\n const expected = input.expected;\n const language = input.language;\n const difficulty = input.difficulty;\n const tags = input.tags;\n const args = input.args;\n\n if (typeof id !== \"string\" || id.trim().length === 0) {\n throw new Error(`${path}.id must be a non-empty string`);\n }\n\n if (typeof query !== \"string\" || query.trim().length === 0) {\n throw new Error(`${path}.query must be a non-empty string`);\n }\n\n return {\n id,\n query,\n queryType: parseQueryType(queryType, `${path}.queryType`),\n retrievalMode: parseRetrievalMode(retrievalMode, `${path}.retrievalMode`),\n language: parseQueryLanguage(language, `${path}.language`),\n difficulty: parseQueryDifficulty(difficulty, `${path}.difficulty`),\n args: parseQueryArgs(args, `${path}.args`),\n tags: parseQueryTags(tags, `${path}.tags`),\n expected: parseExpected(expected, `${path}.expected`),\n };\n }\n\nexport function parseGoldenDataset(raw: unknown, sourceLabel: string): GoldenDataset {\n if (!isRecord(raw)) {\n throw new Error(`${sourceLabel} must be a JSON object`);\n }\n\n const version = raw.version;\n const name = raw.name;\n const description = raw.description;\n const queriesRaw = raw.queries;\n\n const validatedVersion = parseSemanticVersion(version, `${sourceLabel}.version`);\n\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw new Error(`${sourceLabel}.name must be a non-empty string`);\n }\n\n if (description !== undefined && typeof description !== \"string\") {\n throw new Error(`${sourceLabel}.description must be a string when provided`);\n }\n\n if (!Array.isArray(queriesRaw)) {\n throw new Error(`${sourceLabel}.queries must be an array`);\n }\n\n if (queriesRaw.length === 0) {\n throw new Error(`${sourceLabel}.queries must contain at least one query`);\n }\n\n const queries = queriesRaw.map((query, idx) => parseQuery(query, idx));\n const idSet = new Set<string>();\n\n for (const query of queries) {\n if (idSet.has(query.id)) {\n throw new Error(`${sourceLabel}.queries has duplicate id: ${query.id}`);\n }\n idSet.add(query.id);\n }\n\n return {\n version: validatedVersion,\n name,\n description: typeof description === \"string\" ? description : undefined,\n queries,\n };\n}\n\nexport function loadGoldenDataset(datasetPath: string): GoldenDataset {\n const parsed = parseJsonFile(datasetPath);\n return parseGoldenDataset(parsed, datasetPath);\n}\n\nfunction parseThresholdValue(\n value: unknown,\n fieldName: string,\n sourceLabel: string\n): number | undefined {\n return value === undefined\n ? undefined\n : asPositiveNumber(value, `${sourceLabel}.thresholds.${fieldName}`);\n}\n\nexport function parseBudget(raw: unknown, sourceLabel: string): EvalBudget {\n if (!isRecord(raw)) {\n throw new Error(`${sourceLabel} must be a JSON object`);\n }\n\n const name = raw.name;\n const baselinePath = raw.baselinePath;\n const failOnMissingBaseline = raw.failOnMissingBaseline;\n const thresholds = raw.thresholds;\n\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw new Error(`${sourceLabel}.name must be a non-empty string`);\n }\n\n if (baselinePath !== undefined && typeof baselinePath !== \"string\") {\n throw new Error(`${sourceLabel}.baselinePath must be a string when provided`);\n }\n\n if (!isRecord(thresholds)) {\n throw new Error(`${sourceLabel}.thresholds must be an object`);\n }\n\n return {\n name,\n baselinePath: typeof baselinePath === \"string\" ? baselinePath : undefined,\n failOnMissingBaseline:\n typeof failOnMissingBaseline === \"boolean\" ? failOnMissingBaseline : true,\n thresholds: {\n hitAt5MaxDrop: parseThresholdValue(\n thresholds.hitAt5MaxDrop,\n \"hitAt5MaxDrop\",\n sourceLabel\n ),\n mrrAt10MaxDrop: parseThresholdValue(\n thresholds.mrrAt10MaxDrop,\n \"mrrAt10MaxDrop\",\n sourceLabel\n ),\n rawDistinctTop3RatioMaxDrop: parseThresholdValue(\n thresholds.rawDistinctTop3RatioMaxDrop,\n \"rawDistinctTop3RatioMaxDrop\",\n sourceLabel\n ),\n p95LatencyMaxMultiplier: parseThresholdValue(\n thresholds.p95LatencyMaxMultiplier,\n \"p95LatencyMaxMultiplier\",\n sourceLabel\n ),\n p95LatencyMaxAbsoluteMs: parseThresholdValue(\n thresholds.p95LatencyMaxAbsoluteMs,\n \"p95LatencyMaxAbsoluteMs\",\n sourceLabel\n ),\n minHitAt5: parseThresholdValue(thresholds.minHitAt5, \"minHitAt5\", sourceLabel),\n minMrrAt10: parseThresholdValue(thresholds.minMrrAt10, \"minMrrAt10\", sourceLabel),\n minRawDistinctTop3Ratio: parseThresholdValue(\n thresholds.minRawDistinctTop3Ratio,\n \"minRawDistinctTop3Ratio\",\n sourceLabel\n ),\n minGraphNeighborRecall: parseThresholdValue(\n thresholds.minGraphNeighborRecall,\n \"minGraphNeighborRecall\",\n sourceLabel\n ),\n minRouteAccuracy: parseThresholdValue(\n thresholds.minRouteAccuracy,\n \"minRouteAccuracy\",\n sourceLabel\n ),\n minOutcomeAccuracy: parseThresholdValue(\n thresholds.minOutcomeAccuracy,\n \"minOutcomeAccuracy\",\n sourceLabel\n ),\n maxContextResponseTokensAverage: parseThresholdValue(\n thresholds.maxContextResponseTokensAverage,\n \"maxContextResponseTokensAverage\",\n sourceLabel\n ),\n maxContextResponseTokensP95: parseThresholdValue(\n thresholds.maxContextResponseTokensP95,\n \"maxContextResponseTokensP95\",\n sourceLabel\n ),\n maxContextResponseTokensMax: parseThresholdValue(\n thresholds.maxContextResponseTokensMax,\n \"maxContextResponseTokensMax\",\n sourceLabel\n ),\n maxContextDuplicateCandidateRatio: parseThresholdValue(\n thresholds.maxContextDuplicateCandidateRatio,\n \"maxContextDuplicateCandidateRatio\",\n sourceLabel\n ),\n minContextSelectedFileRatio: parseThresholdValue(\n thresholds.minContextSelectedFileRatio,\n \"minContextSelectedFileRatio\",\n sourceLabel\n ),\n minContextHitAt5Per1kResponseTokens: parseThresholdValue(\n thresholds.minContextHitAt5Per1kResponseTokens,\n \"minContextHitAt5Per1kResponseTokens\",\n sourceLabel\n ),\n minContextMrrAt10Per1kResponseTokens: parseThresholdValue(\n thresholds.minContextMrrAt10Per1kResponseTokens,\n \"minContextMrrAt10Per1kResponseTokens\",\n sourceLabel\n ),\n },\n };\n}\n\nexport function loadBudget(budgetPath: string): EvalBudget {\n const parsed = parseJsonFile(budgetPath);\n return parseBudget(parsed, budgetPath);\n}\n","import { compareSummaries } from \"./compare.js\";\nimport { createSummaryMarkdown, createRunDirectory, loadSummary, writeJson, writeText } from \"./reports.js\";\nimport { runEvaluation, runSweep } from \"./runner.js\";\nimport * as path from \"path\";\n\nimport {\n hasSweepOptions,\n parseEvalSubcommandOptions,\n printUsage,\n toRunOptions,\n} from \"./cli-parser.js\";\n\nexport async function handleEvalCommand(args: string[], cwd: string): Promise<number> {\n const subcommand = args[0];\n\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\") {\n printUsage();\n return 0;\n }\n\n if (subcommand === \"run\") {\n const { parsed, explicitAgainst } = parseEvalSubcommandOptions(args.slice(1), cwd);\n if (explicitAgainst) {\n parsed.againstPath = explicitAgainst;\n }\n const runOptions = toRunOptions(parsed);\n\n if (hasSweepOptions(parsed.sweep)) {\n const sweep = await runSweep(runOptions, parsed.sweep);\n console.log(`Eval sweep complete. Artifacts: ${sweep.outputDir}`);\n console.log(`Sweep runs: ${sweep.aggregate.runCount}`);\n if (parsed.ciMode && sweep.aggregate.gatePassed === false) {\n console.error(\n `[CI-GATE] Sweep failed: ${sweep.aggregate.failedGateRuns ?? 0} run(s) violated budget/baseline gates`\n );\n return 1;\n }\n return 0;\n }\n\n const result = await runEvaluation(runOptions);\n console.log(`Eval run complete. Artifacts: ${result.outputDir}`);\n console.log(\n `Hit@5=${(result.summary.metrics.hitAt5 * 100).toFixed(2)}% MRR@10=${result.summary.metrics.mrrAt10.toFixed(4)} p95=${result.summary.metrics.latencyMs.p95.toFixed(3)}ms`\n );\n\n if (result.gate && !result.gate.passed) {\n for (const violation of result.gate.violations) {\n console.error(`[CI-GATE] ${violation.metric}: ${violation.message}`);\n }\n return 1;\n }\n\n return 0;\n }\n\n if (subcommand === \"compare\") {\n const { parsed, explicitAgainst } = parseEvalSubcommandOptions(args.slice(1), cwd);\n\n if (!explicitAgainst) {\n throw new Error(\"eval compare requires --against <baseline summary.json>\");\n }\n parsed.againstPath = explicitAgainst;\n\n const runOptions = toRunOptions(parsed);\n\n if (hasSweepOptions(parsed.sweep)) {\n const sweep = await runSweep(runOptions, parsed.sweep);\n console.log(`Eval compare sweep complete. Artifacts: ${sweep.outputDir}`);\n if (parsed.ciMode && sweep.aggregate.gatePassed === false) {\n console.error(\n `[CI-GATE] Sweep failed: ${sweep.aggregate.failedGateRuns ?? 0} run(s) violated budget/baseline gates`\n );\n return 1;\n }\n return 0;\n }\n\n const result = await runEvaluation(runOptions);\n console.log(`Eval compare complete. Artifacts: ${result.outputDir}`);\n return 0;\n }\n\n if (subcommand === \"diff\") {\n const { parsed, explicitAgainst } = parseEvalSubcommandOptions(args.slice(1), cwd);\n if (!explicitAgainst) {\n throw new Error(\"eval diff requires --against <baseline summary.json>\");\n }\n if (!parsed.currentPath) {\n throw new Error(\"eval diff requires --current <current summary.json>\");\n }\n parsed.againstPath = explicitAgainst;\n\n const currentPath = parsed.currentPath;\n if (!currentPath.endsWith(\".json\")) {\n throw new Error(\"eval diff --current must point to a summary JSON file\");\n }\n if (!parsed.againstPath.endsWith(\".json\")) {\n throw new Error(\"eval diff --against must point to a summary JSON file\");\n }\n const currentSummary = loadSummary(path.resolve(parsed.projectRoot, currentPath), {\n allowLegacyDiversityMetrics: true,\n });\n const baselineSummary = loadSummary(path.resolve(parsed.projectRoot, parsed.againstPath), {\n allowLegacyDiversityMetrics: true,\n });\n const comparison = compareSummaries(\n currentSummary,\n baselineSummary,\n path.resolve(parsed.projectRoot, parsed.againstPath)\n );\n\n const outputDir = createRunDirectory(path.resolve(parsed.projectRoot, parsed.outputRoot));\n const summaryMd = createSummaryMarkdown(currentSummary, comparison);\n writeJson(path.join(outputDir, \"compare.json\"), comparison);\n writeText(path.join(outputDir, \"summary.md\"), summaryMd);\n writeJson(path.join(outputDir, \"summary.json\"), currentSummary);\n console.log(`Eval diff complete. Artifacts: ${outputDir}`);\n return 0;\n }\n\n throw new Error(`Unknown eval subcommand: ${subcommand}`);\n}\n","import * as path from \"path\";\n\nimport { MCP_BINARY_CURRENT_NAME } from \"../identity-catalog.js\";\nimport type { EvalRunOptions, SweepDefinition } from \"./types.js\";\n\nexport interface ParsedArgs {\n projectRoot: string;\n configPath?: string;\n datasetPath: string;\n currentPath?: string;\n outputRoot: string;\n againstPath?: string;\n budgetPath?: string;\n ciMode: boolean;\n reindex: boolean;\n fusionStrategy?: \"rrf\" | \"weighted\";\n hybridWeight?: number;\n rrfK?: number;\n rerankTopN?: number;\n sweep: SweepDefinition;\n}\n\nexport interface EvalSubcommandOptions {\n parsed: ParsedArgs;\n explicitAgainst?: string;\n}\n\nexport function printUsage(): void {\n console.log(`\nUsage:\n ${MCP_BINARY_CURRENT_NAME} eval run [options]\n ${MCP_BINARY_CURRENT_NAME} eval compare --against <summary.json> [options]\n ${MCP_BINARY_CURRENT_NAME} eval diff --current <summary.json> --against <summary.json> [options]\n\nOptions:\n --project <path> Project root (default: cwd)\n --config <path> Config JSON path\n --dataset <path> Golden dataset path (default: benchmarks/golden/small.json)\n --current <path> Current summary.json path (required for eval diff)\n --output <path> Output root dir (default: benchmarks/results)\n --against <path> Baseline summary.json to compare against\n --budget <path> Budget file for CI mode (default: benchmarks/budgets/default.json)\n --ci Enable CI gate mode\n --reindex Force reindex before eval\n\nSearch overrides:\n --fusionStrategy <rrf|weighted>\n --hybridWeight <0-1>\n --rrfK <number>\n --rerankTopN <number>\n\nSweep options (comma-separated values):\n --sweepFusionStrategy <rrf,weighted>\n --sweepHybridWeight <0.3,0.5,0.7>\n --sweepRrfK <30,60,90>\n --sweepRerankTopN <10,20,40>\n`);\n}\n\nfunction parseNumber(value: string, flag: string): number {\n const parsed = Number(value);\n if (Number.isNaN(parsed)) {\n throw new Error(`${flag} must be a number`);\n }\n return parsed;\n}\n\nfunction parseCsvNumbers(value: string, flag: string): number[] {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0)\n .map((item) => parseNumber(item, flag));\n}\n\nfunction parseCsvFusion(value: string): Array<\"rrf\" | \"weighted\"> {\n const values = value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n\n const parsed: Array<\"rrf\" | \"weighted\"> = [];\n for (const candidate of values) {\n if (candidate !== \"rrf\" && candidate !== \"weighted\") {\n throw new Error(\"--sweepFusionStrategy accepts only rrf,weighted\");\n }\n parsed.push(candidate);\n }\n return parsed;\n}\n\nexport function hasSweepOptions(sweep: SweepDefinition): boolean {\n return Boolean(\n (sweep.fusionStrategy && sweep.fusionStrategy.length > 0) ||\n (sweep.hybridWeight && sweep.hybridWeight.length > 0) ||\n (sweep.rrfK && sweep.rrfK.length > 0) ||\n (sweep.rerankTopN && sweep.rerankTopN.length > 0)\n );\n}\n\nexport function parseEvalArgs(argv: string[], cwd: string): ParsedArgs {\n const parsed: ParsedArgs = {\n projectRoot: cwd,\n datasetPath: \"benchmarks/golden/small.json\",\n outputRoot: \"benchmarks/results\",\n budgetPath: \"benchmarks/budgets/default.json\",\n ciMode: false,\n reindex: false,\n sweep: {},\n };\n\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n const next = argv[i + 1];\n\n if (arg === \"--project\" && next) {\n parsed.projectRoot = path.resolve(cwd, next);\n i += 1;\n continue;\n }\n if (arg === \"--config\" && next) {\n parsed.configPath = path.resolve(cwd, next);\n i += 1;\n continue;\n }\n if (arg === \"--dataset\" && next) {\n parsed.datasetPath = next;\n i += 1;\n continue;\n }\n if (arg === \"--current\" && next) {\n parsed.currentPath = next;\n i += 1;\n continue;\n }\n if (arg === \"--output\" && next) {\n parsed.outputRoot = next;\n i += 1;\n continue;\n }\n if (arg === \"--against\" && next) {\n parsed.againstPath = next;\n i += 1;\n continue;\n }\n if (arg === \"--budget\" && next) {\n parsed.budgetPath = next;\n i += 1;\n continue;\n }\n if (arg === \"--ci\") {\n parsed.ciMode = true;\n continue;\n }\n if (arg === \"--reindex\") {\n parsed.reindex = true;\n continue;\n }\n if (arg === \"--fusionStrategy\" && next) {\n if (next !== \"rrf\" && next !== \"weighted\") {\n throw new Error(\"--fusionStrategy must be rrf or weighted\");\n }\n parsed.fusionStrategy = next;\n i += 1;\n continue;\n }\n if (arg === \"--hybridWeight\" && next) {\n parsed.hybridWeight = parseNumber(next, \"--hybridWeight\");\n i += 1;\n continue;\n }\n if (arg === \"--rrfK\" && next) {\n parsed.rrfK = parseNumber(next, \"--rrfK\");\n i += 1;\n continue;\n }\n if (arg === \"--rerankTopN\" && next) {\n parsed.rerankTopN = parseNumber(next, \"--rerankTopN\");\n i += 1;\n continue;\n }\n if (arg === \"--sweepFusionStrategy\" && next) {\n parsed.sweep.fusionStrategy = parseCsvFusion(next);\n i += 1;\n continue;\n }\n if (arg === \"--sweepHybridWeight\" && next) {\n parsed.sweep.hybridWeight = parseCsvNumbers(next, \"--sweepHybridWeight\");\n i += 1;\n continue;\n }\n if (arg === \"--sweepRrfK\" && next) {\n parsed.sweep.rrfK = parseCsvNumbers(next, \"--sweepRrfK\");\n i += 1;\n continue;\n }\n if (arg === \"--sweepRerankTopN\" && next) {\n parsed.sweep.rerankTopN = parseCsvNumbers(next, \"--sweepRerankTopN\");\n i += 1;\n continue;\n }\n }\n\n return parsed;\n}\n\nexport function parseEvalSubcommandOptions(argv: string[], cwd: string): EvalSubcommandOptions {\n let explicitAgainst: string | undefined;\n const filtered: string[] = [];\n\n for (let i = 0; i < argv.length; i += 1) {\n const current = argv[i];\n const next = argv[i + 1];\n\n if (current === \"--against\" && next) {\n explicitAgainst = next;\n i += 1;\n continue;\n }\n\n filtered.push(current);\n }\n\n return {\n parsed: parseEvalArgs(filtered, cwd),\n explicitAgainst,\n };\n}\n\nexport function toRunOptions(parsed: ParsedArgs): EvalRunOptions {\n return {\n projectRoot: parsed.projectRoot,\n configPath: parsed.configPath,\n datasetPath: parsed.datasetPath,\n outputRoot: parsed.outputRoot,\n againstPath: parsed.againstPath,\n budgetPath: parsed.budgetPath,\n ciMode: parsed.ciMode,\n reindex: parsed.reindex,\n searchOverrides: {\n ...(parsed.fusionStrategy !== undefined ? { fusionStrategy: parsed.fusionStrategy } : {}),\n ...(parsed.hybridWeight !== undefined ? { hybridWeight: parsed.hybridWeight } : {}),\n ...(parsed.rrfK !== undefined ? { rrfK: parsed.rrfK } : {}),\n ...(parsed.rerankTopN !== undefined ? { rerankTopN: parsed.rerankTopN } : {}),\n },\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport type { ParsedCodebaseIndexConfig } from \"../../config/schema.js\";\nimport type { HostMode } from \"../../config/host.js\";\nimport { MCP_SERVER_CURRENT_NAME } from \"../../identity-catalog.js\";\nimport { getPackageVersion } from \"../../package-metadata.js\";\nimport { registerMcpPrompts } from \"./register-prompts.js\";\nimport { registerMcpTools } from \"./register-tools.js\";\nimport { initializeTools } from \"../../tools/operations.js\";\nimport { startAutoIndex, stopAutoIndex } from \"../../utils/auto-index.js\";\n\nfunction getServerInstructions(host: string): string {\n const hostText = `host ${host}`;\n return `This MCP server is the preferred codebase-understanding path for ${hostText}. Start a repository task with index_status when index readiness or freshness is unknown. Use codebase_context as the preferred first entry point because it returns a token-budgeted location pack and routes to definitions or call-graph helpers when symbol intent is present. For code changes with a known or suspected symbol target, optionally call codebase_edit_context as a compact pre-edit step for bounded source plus direct callers and callees before broad file reads. Keep the default tokenBudget for normal discovery, then use implementation_lookup, codebase_search, or a targeted file read only for selected locations that need source content. Use codebase_peek for direct conceptual location lookup. For exact identifiers or exhaustive matches, use grep. After identifying symbols, use call_graph or call_graph_path to trace dependencies. If the index is unavailable, run index_codebase, then retry the retrieval tool.`;\n}\n\nexport function createMcpServer(\n projectRoot: string,\n config: ParsedCodebaseIndexConfig,\n host: HostMode,\n): McpServer {\n const server = new McpServer({\n name: MCP_SERVER_CURRENT_NAME,\n version: getPackageVersion(),\n }, {\n instructions: getServerInstructions(host),\n });\n\n initializeTools(projectRoot, config, host);\n startAutoIndex(projectRoot, host, \"startup\");\n\n let stopCoordinationPromise: Promise<void> | null = null;\n const stopCoordination = (): Promise<void> => {\n stopCoordinationPromise ??= stopAutoIndex(projectRoot, host);\n return stopCoordinationPromise;\n };\n const closeProtocol = server.server.close.bind(server.server);\n server.server.close = async (): Promise<void> => {\n await stopCoordination();\n await closeProtocol();\n };\n const closeServer = server.close.bind(server);\n server.close = async (): Promise<void> => {\n await stopCoordination();\n await closeServer();\n };\n const onServerClose = server.server.onclose;\n server.server.onclose = () => {\n onServerClose?.();\n void stopCoordination();\n };\n\n registerMcpTools(server, {\n projectRoot,\n host,\n });\n\n registerMcpPrompts(server);\n\n return server;\n}\n","import { readFileSync } from \"fs\";\n\nexport function getPackageVersion(): string {\n const raw = JSON.parse(readFileSync(new URL(\"../package.json\", import.meta.url), \"utf-8\")) as unknown;\n if (raw && typeof raw === \"object\" && \"version\" in raw && typeof raw.version === \"string\") {\n return raw.version;\n }\n\n return \"0.0.0\";\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nexport function registerMcpPrompts(server: McpServer): void {\n server.prompt(\n \"search\",\n \"Search codebase by meaning using semantic search\",\n { query: z.string().describe(\"What to search for in the codebase\") },\n (args) => ({\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Search the codebase for: \"${args.query}\"\\n\\nUse the codebase_search tool with this query. If you need just locations first, use codebase_peek instead to save tokens.`,\n },\n }],\n }),\n );\n\n server.prompt(\n \"find\",\n \"Find code using hybrid approach (semantic + grep)\",\n { query: z.string().describe(\"What to find in the codebase\") },\n (args) => ({\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Find code related to: \"${args.query}\"\\n\\nUse a hybrid approach:\\n1. First use codebase_peek to find semantic matches by meaning\\n2. Then use grep for exact identifier matches\\n3. Combine results for comprehensive coverage`,\n },\n }],\n }),\n );\n\n server.prompt(\n \"index\",\n \"Index the codebase for semantic search\",\n { options: z.string().optional().describe(\"Options: 'force' to rebuild, 'estimate' to check costs\") },\n (args) => {\n const opts = args.options?.toLowerCase() ?? \"\";\n let instruction = \"Use the index_codebase tool to index the codebase for semantic search.\";\n if (opts.includes(\"force\")) {\n instruction = \"Use the index_codebase tool with force=true to rebuild the entire index from scratch.\";\n } else if (opts.includes(\"estimate\")) {\n instruction = \"Use the index_codebase tool with estimateOnly=true to check the cost estimate before indexing.\";\n }\n return {\n messages: [{\n role: \"user\",\n content: { type: \"text\", text: instruction },\n }],\n };\n },\n );\n\n server.prompt(\n \"status\",\n \"Check if the codebase is indexed and ready\",\n {},\n () => ({\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: \"Use the index_status tool to check if the codebase index is ready and show its current state.\",\n },\n }],\n }),\n );\n\n server.prompt(\n \"definition\",\n \"Find where a symbol is defined in the codebase\",\n { query: z.string().describe(\"Symbol name or description to find the definition of\") },\n (args) => ({\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Find the definition of: \"${args.query}\"\\n\\nUse the implementation_lookup tool to find where this symbol is defined. This prioritizes real implementation files over tests, docs, and examples. If no definition is found, fall back to codebase_search for broader discovery.`,\n },\n }],\n }),\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nimport {\n DEFAULT_CONTEXT_PACK_TOKEN_BUDGET,\n formatCodebasePeek,\n formatSearchResults,\n MAX_CONTEXT_PACK_TOKEN_BUDGET,\n MIN_CONTEXT_PACK_TOKEN_BUDGET,\n} from \"../../tools/utils.js\";\nimport {\n MAX_CONTEXT_PATH_DEPTH,\n MAX_CONTEXT_RESULT_LIMIT,\n MIN_CONTEXT_PATH_DEPTH,\n MIN_CONTEXT_RESULT_LIMIT,\n} from \"../../tools/context.js\";\nimport {\n CALL_GRAPH_DIRECTIONS,\n CHUNK_TYPES,\n INDEX_LOG_CATEGORIES,\n INDEX_LOG_LEVELS,\n RELATIONSHIP_TYPES,\n CODE_COMMUNITIES_DEFAULT_HUB_THRESHOLD,\n CODE_COMMUNITIES_DEFAULT_LIMIT,\n CODE_COMMUNITIES_MAX_LIMIT,\n CODE_COMMUNITIES_MIN_SIZE,\n CODE_COMMUNITIES_MIN_COUPLING,\n CODE_COMMUNITIES_DEFAULT_COUPLING_LIMIT,\n CODE_COMMUNITIES_MAX_COUPLING_LIMIT,\n DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT,\n MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT,\n MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT,\n} from \"../../tools/contracts.js\";\nimport {\n executeCallGraph,\n executeCallGraphPath,\n executeCodebaseContext,\n executeCodebaseEditContext,\n executeCodeCommunities,\n executeIndexCodebase,\n executeIndexHealthCheck,\n executeIndexLogs,\n executeIndexMetrics,\n executeIndexStatus,\n executeImplementationLookup,\n} from \"../../tools/execute-common.js\";\nimport { formatPrImpact } from \"../../tools/format-pr-impact.js\";\nimport {\n addKnowledgeBase,\n findSimilarCode,\n getPrImpact,\n listKnowledgeBases,\n removeKnowledgeBase,\n searchCodebaseWithEffectiveness,\n} from \"../../tools/operations.js\";\nimport type { McpServerRuntime } from \"./shared.js\";\nimport { TOOL_NAME } from \"../../tools/tool-names.js\";\n\nfunction allowNullAsUndefined<T extends z.ZodTypeAny>(schema: T): T {\n return z.preprocess((value) => (value === null ? undefined : value), schema) as unknown as T;\n}\n\n// Knowledge-base operations report failures as plain strings prefixed with \"Error: \" (for\n// example a missing directory or a blocked sensitive directory) instead of throwing. Surface\n// those to MCP clients as isError so they can distinguish a refusal from success. Informational\n// results such as \"Knowledge base already configured\" or \"Knowledge base not found\" do not use\n// the prefix and remain successful results.\nfunction knowledgeBaseResult(text: string): { content: Array<{ type: \"text\"; text: string }>; isError?: true } {\n const content = [{ type: \"text\" as const, text }];\n return text.startsWith(\"Error: \") ? { content, isError: true } : { content };\n}\n\nexport function registerMcpTools(server: McpServer, runtime: McpServerRuntime): void {\n server.tool(\n TOOL_NAME.CODEBASE_CONTEXT,\n \"PREFERRED FIRST TOOL for any question about this repository. Returns a deduplicated, file-diverse evidence pack within tokenBudget. Use before built-in code search, grep, shell search, or broad file reads. Provide from+to for a dependency path, with optional fromFilePath/toFilePath when names are ambiguous; provide symbol for a definition; or provide only query for low-token conceptual discovery. Use call_graph directly for callers or callees.\",\n {\n query: z.string().describe(\"The codebase question or behavior to locate. Always provide the user's repository question here.\"),\n from: allowNullAsUndefined(z.string().optional()).describe(\"Source symbol. For dependency-path questions, extract the first endpoint and provide it here.\"),\n to: allowNullAsUndefined(z.string().optional()).describe(\"Target symbol. For dependency-path questions, extract the second endpoint and provide it here.\"),\n fromFilePath: allowNullAsUndefined(z.string().optional()).describe(\"Optional source file path used only to disambiguate duplicate source names.\"),\n toFilePath: allowNullAsUndefined(z.string().optional()).describe(\"Optional target file path used only to disambiguate duplicate target names.\"),\n symbol: allowNullAsUndefined(z.string().optional()).describe(\"Exact symbol for an authoritative definition lookup. Omit when from and to are supplied.\"),\n limit: allowNullAsUndefined(\n z.number().int().min(MIN_CONTEXT_RESULT_LIMIT).max(MAX_CONTEXT_RESULT_LIMIT).optional().default(10),\n ).describe(`Maximum number of search or definition results (${MIN_CONTEXT_RESULT_LIMIT}-${MAX_CONTEXT_RESULT_LIMIT})`),\n maxDepth: allowNullAsUndefined(\n z.number().int().min(MIN_CONTEXT_PATH_DEPTH).max(MAX_CONTEXT_PATH_DEPTH).optional().default(10),\n ).describe(`Maximum call-graph traversal depth for from/to path lookup (${MIN_CONTEXT_PATH_DEPTH}-${MAX_CONTEXT_PATH_DEPTH})`),\n fileType: allowNullAsUndefined(z.string().optional()).describe(\"Filter by file extension (e.g., 'ts', 'py', 'rs')\"),\n directory: allowNullAsUndefined(z.string().optional()).describe(\"Filter by directory path (e.g., 'src/utils', 'lib')\"),\n tokenBudget: allowNullAsUndefined(\n z.number().int().min(MIN_CONTEXT_PACK_TOKEN_BUDGET).max(MAX_CONTEXT_PACK_TOKEN_BUDGET).optional()\n .default(DEFAULT_CONTEXT_PACK_TOKEN_BUDGET),\n ).describe(`Maximum response tokens for this context pack (${MIN_CONTEXT_PACK_TOKEN_BUDGET}-${MAX_CONTEXT_PACK_TOKEN_BUDGET})`),\n diagnostic: z.boolean().optional().describe(\"Collect diagnostic routing and search traces without changing normal text output.\"),\n },\n async (args) => {\n const result = await executeCodebaseContext(runtime.projectRoot, runtime.host, args);\n return {\n content: [{ type: \"text\", text: result.text }],\n ...(args.diagnostic ? { structuredContent: result.details } : {}),\n };\n },\n );\n\n server.tool(\n TOOL_NAME.CODEBASE_EDIT_CONTEXT,\n \"PRE-EDIT TOOL for a known or suspected symbol. Returns token-bounded target source, direct callers and callees, or a risk-marked conceptual fallback when resolution is unsafe.\",\n {\n query: z.string().describe(\"The requested change or target behavior.\"),\n symbol: allowNullAsUndefined(z.string().optional()).describe(\"Authoritative target symbol when known.\"),\n filePath: allowNullAsUndefined(z.string().optional()).describe(\"Optional file path used to disambiguate duplicate symbol names.\"),\n callerLimit: allowNullAsUndefined(z.number().int().min(MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT).max(MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT).optional()\n .default(DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT)),\n calleeLimit: allowNullAsUndefined(z.number().int().min(MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT).max(MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT).optional()\n .default(DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT)),\n tokenBudget: allowNullAsUndefined(z.number().int().min(MIN_CONTEXT_PACK_TOKEN_BUDGET).max(MAX_CONTEXT_PACK_TOKEN_BUDGET).optional()\n .default(DEFAULT_CONTEXT_PACK_TOKEN_BUDGET)),\n },\n async (args) => {\n const result = await executeCodebaseEditContext(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n\n server.tool(\n TOOL_NAME.CODEBASE_SEARCH,\n \"FULL-CONTENT semantic retrieval. Use after codebase_peek when you need implementation text, not as the default first step. For exact identifiers or exhaustive matches use grep instead.\",\n {\n query: z.string().describe(\"Natural language description of what code you're looking for. Describe behavior, not syntax.\"),\n limit: allowNullAsUndefined(z.number().optional().default(5)).describe(\"Maximum number of results to return\"),\n fileType: allowNullAsUndefined(z.string().optional()).describe(\"Filter by file extension (e.g., 'ts', 'py', 'rs')\"),\n directory: allowNullAsUndefined(z.string().optional()).describe(\"Filter by directory path (e.g., 'src/utils', 'lib')\"),\n chunkType: allowNullAsUndefined(z.enum(CHUNK_TYPES).optional()).describe(\"Filter by code chunk type\"),\n contextLines: allowNullAsUndefined(z.number().optional()).describe(\"Number of extra lines to include before/after each match (default: 0)\"),\n blameAuthor: allowNullAsUndefined(z.string().optional()).describe(\"Filter by git blame author name or email\"),\n blameSha: allowNullAsUndefined(z.string().optional()).describe(\"Filter by git blame commit SHA or prefix\"),\n blameSince: allowNullAsUndefined(z.string().optional()).describe(\"Filter to chunks last changed on or after this date\"),\n blameUntil: allowNullAsUndefined(z.string().optional()).describe(\"Filter to chunks last changed on or before this date\"),\n },\n async (args) => {\n return searchCodebaseWithEffectiveness(runtime.projectRoot, runtime.host, \"search\", args.query, {\n limit: args.limit ?? 5,\n fileType: args.fileType,\n directory: args.directory,\n chunkType: args.chunkType,\n contextLines: args.contextLines,\n blameAuthor: args.blameAuthor,\n blameSha: args.blameSha,\n blameSince: args.blameSince,\n blameUntil: args.blameUntil,\n }, (results) => {\n const text = results.length === 0\n ? \"No matching code found. Try a different query or run index_codebase first.\"\n : `Found ${results.length} results for \"${args.query}\":\\n\\n${formatSearchResults(results, \"score\")}`;\n return { output: { content: [{ type: \"text\" as const, text }] }, text };\n });\n },\n );\n\n server.tool(\n TOOL_NAME.CODEBASE_PEEK,\n \"DIRECT LOW-TOKEN semantic location lookup for unfamiliar-code discovery. Prefer codebase_context when the request may involve definitions or graph navigation; use this specialized tool when you only need conceptual locations.\",\n {\n query: z.string().describe(\"Natural language description of what code you're looking for.\"),\n limit: allowNullAsUndefined(z.number().optional().default(10)).describe(\"Maximum number of results to return\"),\n fileType: allowNullAsUndefined(z.string().optional()).describe(\"Filter by file extension (e.g., 'ts', 'py', 'rs')\"),\n directory: allowNullAsUndefined(z.string().optional()).describe(\"Filter by directory path (e.g., 'src/utils', 'lib')\"),\n chunkType: allowNullAsUndefined(z.enum(CHUNK_TYPES).optional()).describe(\"Filter by code chunk type\"),\n blameAuthor: allowNullAsUndefined(z.string().optional()).describe(\"Filter by git blame author name or email\"),\n blameSha: allowNullAsUndefined(z.string().optional()).describe(\"Filter by git blame commit SHA or prefix\"),\n blameSince: allowNullAsUndefined(z.string().optional()).describe(\"Filter to chunks last changed on or after this date\"),\n blameUntil: allowNullAsUndefined(z.string().optional()).describe(\"Filter to chunks last changed on or before this date\"),\n },\n async (args) => {\n return searchCodebaseWithEffectiveness(runtime.projectRoot, runtime.host, \"peek\", args.query, {\n limit: args.limit ?? 10,\n fileType: args.fileType,\n directory: args.directory,\n chunkType: args.chunkType,\n metadataOnly: true,\n blameAuthor: args.blameAuthor,\n blameSha: args.blameSha,\n blameSince: args.blameSince,\n blameUntil: args.blameUntil,\n }, (results) => {\n const text = results.length === 0\n ? \"No matching code found. Try a different query or run index_codebase first.\"\n : `Found ${results.length} locations for \"${args.query}\":\\n\\n${formatCodebasePeek(results)}`;\n return { output: { content: [{ type: \"text\" as const, text }] }, text };\n });\n },\n );\n\n server.tool(\n TOOL_NAME.INDEX_CODEBASE,\n \"Create or refresh the semantic index. Call index_status first when readiness is unknown, then use this tool only if the index is missing, stale, or incompatible. Incremental by default; force=true rebuilds everything.\",\n {\n force: allowNullAsUndefined(z.boolean().optional().default(false)).describe(\"Force reindex even if already indexed\"),\n estimateOnly: allowNullAsUndefined(z.boolean().optional().default(false)).describe(\"Only show cost estimate without indexing\"),\n dryRun: allowNullAsUndefined(z.boolean().optional().default(false)).describe(\"Parse the file set and report the exact embedding token total without indexing. Read-only; the index is not changed. The total is the value 'Tokens used' climbs to for a force index (and an upper bound for an incremental).\"),\n verbose: allowNullAsUndefined(z.boolean().optional().default(false)).describe(\"Show detailed info about skipped files and parsing failures\"),\n },\n async (args) => {\n const result = await executeIndexCodebase(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }], ...(result.isError ? { isError: true } : {}) };\n },\n );\n\n server.tool(\n TOOL_NAME.INDEX_STATUS,\n \"START HERE once per repository task when index readiness or freshness is unknown. Reports whether semantic retrieval is ready, chunk counts, compatibility, and the embedding provider. If ready, continue with codebase_peek or implementation_lookup; otherwise run index_codebase.\",\n {},\n async () => {\n const result = await executeIndexStatus(runtime.projectRoot, runtime.host);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n server.tool(\n TOOL_NAME.INDEX_HEALTH_CHECK,\n \"Check index health and remove stale entries from deleted files. Run this to clean up the index after files have been deleted.\",\n {},\n async () => {\n const result = await executeIndexHealthCheck(runtime.projectRoot, runtime.host);\n return { content: [{ type: \"text\" as const, text: result.text }], ...(result.isError ? { isError: true } : {}) };\n },\n );\n\n server.tool(\n TOOL_NAME.INDEX_METRICS,\n \"Get operational metrics plus opt-in privacy-safe repository-tool effectiveness counters. Metrics are memory-only. Set reset=true to clear them before reading. Operational metrics require debug.enabled=true and debug.metrics=true. Privacy-safe aggregates require only effectivenessMetrics.enabled=true.\",\n {\n reset: z.boolean().optional().default(false).describe(\"Reset in-memory operational and effectiveness metrics before returning the snapshot\"),\n },\n async (args) => {\n const result = await executeIndexMetrics(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n server.tool(\n TOOL_NAME.INDEX_LOGS,\n \"Get recent debug logs from the codebase indexer. Requires debug.enabled=true in config.\",\n {\n limit: allowNullAsUndefined(z.number().optional().default(20)).describe(\"Maximum number of log entries to return\"),\n category: allowNullAsUndefined(\n z.enum(INDEX_LOG_CATEGORIES).optional(),\n ).describe(\"Filter by log category\"),\n level: allowNullAsUndefined(\n z.enum(INDEX_LOG_LEVELS).optional(),\n ).describe(\"Filter by minimum log level\"),\n },\n async (args) => {\n const result = await executeIndexLogs(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n server.tool(\n TOOL_NAME.FIND_SIMILAR,\n \"Use when you already have a code snippet and need analogous implementations, duplicates, patterns, or refactoring candidates. For a natural-language concept without example code, start with codebase_peek instead.\",\n {\n code: z.string().describe(\"The code snippet to find similar code for\"),\n limit: allowNullAsUndefined(z.number().optional().default(10)).describe(\"Maximum number of results to return\"),\n fileType: allowNullAsUndefined(z.string().optional()).describe(\"Filter by file extension (e.g., 'ts', 'py', 'rs')\"),\n directory: allowNullAsUndefined(z.string().optional()).describe(\"Filter by directory path (e.g., 'src/utils', 'lib')\"),\n chunkType: allowNullAsUndefined(z.enum(CHUNK_TYPES).optional()).describe(\"Filter by code chunk type\"),\n excludeFile: allowNullAsUndefined(z.string().optional()).describe(\"Exclude results from this file path\"),\n blameSince: allowNullAsUndefined(z.string().optional()).describe(\"Filter to chunks last changed on or after this date\"),\n blameUntil: allowNullAsUndefined(z.string().optional()).describe(\"Filter to chunks last changed on or before this date\"),\n },\n async (args) => {\n const results = await findSimilarCode(runtime.projectRoot, runtime.host, args.code, {\n limit: args.limit ?? 10,\n fileType: args.fileType,\n directory: args.directory,\n chunkType: args.chunkType,\n excludeFile: args.excludeFile,\n blameSince: args.blameSince,\n blameUntil: args.blameUntil,\n });\n\n if (results.length === 0) {\n return { content: [{ type: \"text\", text: \"No similar code found. Try a different snippet or run index_codebase first.\" }] };\n }\n\n return { content: [{ type: \"text\", text: `Found ${results.length} similar code blocks:\\n\\n${formatSearchResults(results)}` }] };\n },\n );\n\n server.tool(\n TOOL_NAME.IMPLEMENTATION_LOOKUP,\n \"FIRST TOOL only for known-symbol definition questions. Returns authoritative source locations and prefers implementations over tests, docs, examples, and fixtures. Do not use for callers, callees, dependency paths, or code flow; use codebase_context with direction or from/to for those questions.\",\n {\n query: z.string().describe(\"Symbol name or natural language description (e.g., 'validateToken', 'where is the payment handler defined')\"),\n limit: allowNullAsUndefined(z.number().optional().default(5)).describe(\"Maximum number of results\"),\n fileType: allowNullAsUndefined(z.string().optional()).describe(\"Filter by file extension (e.g., 'ts', 'py')\"),\n directory: allowNullAsUndefined(z.string().optional()).describe(\"Filter by directory path (e.g., 'src/utils')\"),\n },\n async (args) => {\n const result = await executeImplementationLookup(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n server.tool(\n TOOL_NAME.CALL_GRAPH,\n \"Find direct callers or callees by function or method name. Unique names resolve automatically; when duplicate names are reported, retry with filePath.\"\n + \" Supports relationship types: Call, MethodCall, Constructor, Import, Inherits, Implements.\",\n {\n name: z.string().describe(\"Function or method name to query\"),\n direction: allowNullAsUndefined(\n z.enum(CALL_GRAPH_DIRECTIONS).default(\"callers\"),\n ).describe(\"Direction: 'callers' finds who calls this function, 'callees' finds what this function calls\"),\n filePath: allowNullAsUndefined(z.string().optional()).describe(\"Optional file path used to disambiguate duplicate symbol names\"),\n symbolId: allowNullAsUndefined(z.string().optional()).describe(\"Optional backward-compatible symbol ID escape hatch\"),\n relationshipType: allowNullAsUndefined(\n z.enum(RELATIONSHIP_TYPES).optional(),\n ).describe(\"Filter by relationship type. Omit to show all.\"),\n },\n async (args) => {\n const result = await executeCallGraph(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n server.tool(\n TOOL_NAME.CALL_GRAPH_PATH,\n \"Find the shortest known call path between two named functions or methods. Unique names resolve automatically; when duplicate endpoints are reported, retry with fromFilePath or toFilePath.\",\n {\n from: z.string().describe(\"Source function/method name (starting point)\"),\n to: z.string().describe(\"Target function/method name (destination)\"),\n fromFilePath: allowNullAsUndefined(z.string().optional()).describe(\"Optional source file path used to disambiguate duplicate source names\"),\n toFilePath: allowNullAsUndefined(z.string().optional()).describe(\"Optional target file path used to disambiguate duplicate target names\"),\n maxDepth: allowNullAsUndefined(z.number().optional().default(10)).describe(\"Maximum traversal depth (default: 10)\"),\n },\n async (args) => {\n const result = await executeCallGraphPath(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n server.tool(\n TOOL_NAME.PR_IMPACT,\n \"FIRST TOOL for pull-request or branch blast-radius questions. Analyzes changed files, affected symbols, transitive dependencies, communities, hub nodes, conflicts, and risk before merging.\",\n {\n pr: allowNullAsUndefined(z.number().optional()).describe(\"Pull request number to analyze\"),\n branch: allowNullAsUndefined(z.string().optional()).describe(\"Branch name to analyze (defaults to current branch)\"),\n maxDepth: allowNullAsUndefined(z.number().optional().default(5)).describe(\"Maximum traversal depth for transitive callers (default: 5)\"),\n hubThreshold: allowNullAsUndefined(z.number().optional().default(10)).describe(\"Minimum caller count to flag a symbol as a hub node (default: 10)\"),\n checkConflicts: allowNullAsUndefined(z.boolean().optional().default(false)).describe(\"Check for conflicting open PRs touching the same communities (default: false)\"),\n direction: allowNullAsUndefined(\n z.enum([\"callers\", \"callees\", \"both\"]).optional().default(\"both\"),\n ).describe(\"Call-graph traversal direction: 'callers' for upstream, 'callees' for downstream, 'both' for union (default: both)\"),\n },\n async (args) => {\n try {\n const result = await getPrImpact(runtime.projectRoot, runtime.host, {\n pr: args.pr,\n branch: args.branch,\n maxDepth: args.maxDepth,\n hubThreshold: args.hubThreshold,\n checkConflicts: args.checkConflicts,\n direction: args.direction,\n });\n return { content: [{ type: \"text\", text: formatPrImpact(result) }] };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { content: [{ type: \"text\", text: `Error analyzing PR impact: ${message}` }] };\n }\n },\n );\n\n server.tool(\n TOOL_NAME.CODE_COMMUNITIES,\n \"Discover natural module boundaries and hub symbols using graph community detection. \" +\n \"Clusters symbols by call-graph connectivity, reports community memberships, identifies \" +\n \"hub nodes with cross-community connections, and summarizes coupling relationships between communities.\",\n {\n branch: allowNullAsUndefined(z.string().optional()).describe(\"Branch name to analyze (defaults to current branch)\"),\n minSize: allowNullAsUndefined(z.number().int().min(CODE_COMMUNITIES_MIN_SIZE).optional().default(CODE_COMMUNITIES_MIN_SIZE)).describe(\"Minimum community size to include (default: 1)\"),\n limit: allowNullAsUndefined(z.number().int().min(1).max(CODE_COMMUNITIES_MAX_LIMIT).optional().default(CODE_COMMUNITIES_DEFAULT_LIMIT)).describe(\"Maximum number of communities and hub nodes to return (default: 20)\"),\n hubThreshold: allowNullAsUndefined(z.number().int().min(0).optional().default(CODE_COMMUNITIES_DEFAULT_HUB_THRESHOLD)).describe(\"Minimum distinct cross-community neighbors to flag a hub node (default: 5)\"),\n minCoupling: allowNullAsUndefined(z.number().int().min(CODE_COMMUNITIES_MIN_COUPLING).optional().default(CODE_COMMUNITIES_MIN_COUPLING)).describe(\"Minimum distinct cross-community connection count to report a coupling (default: 1)\"),\n couplingLimit: allowNullAsUndefined(z.number().int().min(1).max(CODE_COMMUNITIES_MAX_COUPLING_LIMIT).optional().default(CODE_COMMUNITIES_DEFAULT_COUPLING_LIMIT)).describe(\"Maximum number of couplings to return (default: 20)\"),\n },\n async (args) => {\n const result = await executeCodeCommunities(runtime.projectRoot, runtime.host, args);\n return { content: [{ type: \"text\", text: result.text }] };\n },\n );\n\n server.tool(\n TOOL_NAME.ADD_KNOWLEDGE_BASE,\n \"Add a folder as a knowledge base to the semantic search index. The folder is indexed \"\n + \"alongside the project code on the next index run. Provide an absolute path or a path \"\n + \"relative to the project root. The path is written to the project-local host config of \"\n + \"this MCP server (under the server project root), not to a user-global config, and the \"\n + \"index is refreshed. Git blame metadata is collected only for files in the project git \"\n + \"repo; knowledge-base files outside the repo remain searchable by content but have no \"\n + \"blame. A knowledge base that appears in list_knowledge_bases but was inherited from a \"\n + \"global config cannot be removed by this tool.\",\n {\n path: z.string().describe(\"Path to the folder to add as a knowledge base (absolute or relative to the project root)\"),\n },\n async (args) => {\n const result = addKnowledgeBase(runtime.projectRoot, runtime.host, args.path);\n return knowledgeBaseResult(result);\n },\n );\n\n server.tool(\n TOOL_NAME.LIST_KNOWLEDGE_BASES,\n \"List the configured knowledge base folders that the index includes alongside the project \"\n + \"code. The list is the union of project-local and user-global knowledge bases; each entry \"\n + \"shows the resolved path and whether it exists.\",\n {},\n async () => {\n const result = listKnowledgeBases(runtime.projectRoot, runtime.host);\n return knowledgeBaseResult(result);\n },\n );\n\n server.tool(\n TOOL_NAME.REMOVE_KNOWLEDGE_BASE,\n \"Remove a knowledge base folder from the semantic search index and refresh the index. The \"\n + \"path must match a project-local configured path exactly. Knowledge bases inherited from \"\n + \"a user-global config are not removable by this tool.\",\n {\n path: z.string().describe(\"Path of the knowledge base to remove (must match a project-local configured path exactly)\"),\n },\n async (args) => {\n const result = removeKnowledgeBase(runtime.projectRoot, runtime.host, args.path.trim());\n return knowledgeBaseResult(result);\n },\n );\n}\n","export const TOOL_NAME = {\n CODEBASE_CONTEXT: \"codebase_context\",\n CODEBASE_EDIT_CONTEXT: \"codebase_edit_context\",\n CODEBASE_SEARCH: \"codebase_search\",\n CODEBASE_PEEK: \"codebase_peek\",\n FIND_SIMILAR: \"find_similar\",\n IMPLEMENTATION_LOOKUP: \"implementation_lookup\",\n INDEX_CODEBASE: \"index_codebase\",\n INDEX_STATUS: \"index_status\",\n INDEX_HEALTH_CHECK: \"index_health_check\",\n INDEX_METRICS: \"index_metrics\",\n INDEX_LOGS: \"index_logs\",\n CALL_GRAPH: \"call_graph\",\n CALL_GRAPH_PATH: \"call_graph_path\",\n PR_IMPACT: \"pr_impact\",\n CODE_COMMUNITIES: \"code_communities\",\n ADD_KNOWLEDGE_BASE: \"add_knowledge_base\",\n LIST_KNOWLEDGE_BASES: \"list_knowledge_bases\",\n REMOVE_KNOWLEDGE_BASE: \"remove_knowledge_base\",\n PI_KNOWLEDGE_BASE_ADD: \"knowledge_base_add\",\n PI_KNOWLEDGE_BASE_LIST: \"knowledge_base_list\",\n PI_KNOWLEDGE_BASE_REMOVE: \"knowledge_base_remove\",\n INDEX_VISUALIZE: \"index_visualize\",\n} as const;\n\nexport type ToolName = (typeof TOOL_NAME)[keyof typeof TOOL_NAME];\n\nexport const PORTABLE_TOOL_NAMES = [\n TOOL_NAME.CODEBASE_CONTEXT,\n TOOL_NAME.CODEBASE_EDIT_CONTEXT,\n TOOL_NAME.CODEBASE_SEARCH,\n TOOL_NAME.CODEBASE_PEEK,\n TOOL_NAME.INDEX_CODEBASE,\n TOOL_NAME.INDEX_STATUS,\n TOOL_NAME.INDEX_HEALTH_CHECK,\n TOOL_NAME.INDEX_METRICS,\n TOOL_NAME.INDEX_LOGS,\n TOOL_NAME.FIND_SIMILAR,\n TOOL_NAME.IMPLEMENTATION_LOOKUP,\n TOOL_NAME.CALL_GRAPH,\n TOOL_NAME.CALL_GRAPH_PATH,\n TOOL_NAME.PR_IMPACT,\n TOOL_NAME.CODE_COMMUNITIES,\n] as const;\n\nexport const OPENCODE_TOOL_NAMES = [\n TOOL_NAME.CODEBASE_CONTEXT,\n TOOL_NAME.CODEBASE_EDIT_CONTEXT,\n TOOL_NAME.CODEBASE_SEARCH,\n TOOL_NAME.CODEBASE_PEEK,\n TOOL_NAME.INDEX_CODEBASE,\n TOOL_NAME.INDEX_STATUS,\n TOOL_NAME.INDEX_HEALTH_CHECK,\n TOOL_NAME.INDEX_METRICS,\n TOOL_NAME.INDEX_LOGS,\n TOOL_NAME.FIND_SIMILAR,\n TOOL_NAME.CALL_GRAPH,\n TOOL_NAME.CALL_GRAPH_PATH,\n TOOL_NAME.IMPLEMENTATION_LOOKUP,\n TOOL_NAME.ADD_KNOWLEDGE_BASE,\n TOOL_NAME.LIST_KNOWLEDGE_BASES,\n TOOL_NAME.REMOVE_KNOWLEDGE_BASE,\n TOOL_NAME.PR_IMPACT,\n TOOL_NAME.CODE_COMMUNITIES,\n TOOL_NAME.INDEX_VISUALIZE,\n] as const;\n\nexport const PI_TOOL_NAMES = [\n TOOL_NAME.CODEBASE_CONTEXT,\n TOOL_NAME.CODEBASE_EDIT_CONTEXT,\n TOOL_NAME.CODEBASE_SEARCH,\n TOOL_NAME.CODEBASE_PEEK,\n TOOL_NAME.FIND_SIMILAR,\n TOOL_NAME.IMPLEMENTATION_LOOKUP,\n TOOL_NAME.INDEX_CODEBASE,\n TOOL_NAME.INDEX_STATUS,\n TOOL_NAME.INDEX_HEALTH_CHECK,\n TOOL_NAME.INDEX_METRICS,\n TOOL_NAME.INDEX_LOGS,\n TOOL_NAME.CALL_GRAPH,\n TOOL_NAME.CALL_GRAPH_PATH,\n TOOL_NAME.PR_IMPACT,\n TOOL_NAME.CODE_COMMUNITIES,\n TOOL_NAME.PI_KNOWLEDGE_BASE_LIST,\n TOOL_NAME.PI_KNOWLEDGE_BASE_ADD,\n TOOL_NAME.PI_KNOWLEDGE_BASE_REMOVE,\n] as const;\n\n// MCP clients expose the portable retrieval core plus the knowledge-base management tools.\n// Knowledge-base tools are intentionally NOT part of PORTABLE_TOOL_NAMES: that set is a Pi\n// contract (tests/pi-package.test.ts asserts Pi exposes every portable name), and Pi exposes\n// the knowledge-base tools under its own host-specific aliases (PI_KNOWLEDGE_BASE_*).\nexport const MCP_TOOL_NAMES = [\n ...PORTABLE_TOOL_NAMES,\n TOOL_NAME.ADD_KNOWLEDGE_BASE,\n TOOL_NAME.LIST_KNOWLEDGE_BASES,\n TOOL_NAME.REMOVE_KNOWLEDGE_BASE,\n] as const;\n","import { existsSync, statSync } from \"fs\";\nimport { FSWatcher } from \"chokidar\";\nimport * as path from \"path\";\n\nimport type { HostMode } from \"../config/host.js\";\nimport type { CodebaseIndexConfig } from \"../config/schema.js\";\nimport { getProjectConfigCandidatePaths } from \"../config/paths.js\";\nimport { createIgnoreFilter, shouldIncludeFile } from \"../utils/files.js\";\nimport { hasFilteredPathSegment, isRestrictedDirectory } from \"../utils/paths.js\";\nimport { NativeRecursiveWatcher } from \"./native-recursive-watcher.js\";\nimport { FileSnapshotReconciler, type SnapshotInvalidation } from \"./snapshot-reconciler.js\";\n\nexport type FileChangeType = \"add\" | \"change\" | \"unlink\";\n\nexport interface FileChange {\n type: FileChangeType;\n path: string;\n}\n\nexport type ChangeHandler = (changes: FileChange[]) => Promise<void>;\nexport type FileWatcherBackend = \"auto\" | \"chokidar\" | \"native\";\n\nexport interface FileWatcherOptions {\n backend?: FileWatcherBackend;\n configPath?: string;\n}\n\ninterface ConfigPathState {\n mtimeMs: number;\n size: number;\n}\n\nexport class FileWatcher {\n private watcher: FSWatcher | null = null;\n private projectRoot: string;\n private config: CodebaseIndexConfig;\n private configPath: string | undefined;\n private backend: FileWatcherBackend;\n private projectConfigPaths: string[];\n private pendingChanges: Map<string, FileChangeType> = new Map();\n private debounceTimer: NodeJS.Timeout | null = null;\n private debounceMs = 1000;\n private onChanges: ChangeHandler | null = null;\n private readyPromise: Promise<void> | null = null;\n private resolveReady: (() => void) | null = null;\n private pollingFallbackAttempted = false;\n private pendingClose: Promise<void> | null = null;\n private startupReadySignals = 1;\n private nativeWatcher: NativeRecursiveWatcher | null = null;\n private nativeReconciler: FileSnapshotReconciler | null = null;\n private nativeSetupGeneration = 0;\n private nativeStarting = false;\n private nativeInitializing = false;\n private nativeReconcileTimer: NodeJS.Timeout | null = null;\n private nativeInvalidatedPaths: Map<string | null, boolean> = new Map();\n private configPathStates: Map<string, ConfigPathState> = new Map();\n\n constructor(projectRoot: string, config: CodebaseIndexConfig, host: HostMode, options: FileWatcherOptions = {}) {\n this.projectRoot = projectRoot;\n this.config = config;\n this.backend = options.backend ?? \"auto\";\n this.configPath = options.configPath;\n this.projectConfigPaths = options.configPath\n ? [options.configPath]\n : getProjectConfigCandidatePaths(projectRoot, host);\n }\n\n start(handler: ChangeHandler): void {\n if (this.watcher || this.nativeWatcher || this.nativeStarting) {\n return;\n }\n\n this.onChanges = handler;\n this.pollingFallbackAttempted = false;\n this.resetReady();\n if (this.shouldUseNativeWatcher()) {\n if (this.hasExternalConfigWatchTarget()) {\n this.setStartupReadySignals(2);\n this.startExternalConfigWatcher();\n }\n this.nativeStarting = true;\n void this.createNativeWatcher();\n return;\n }\n this.createWatcher();\n }\n\n private resetReady(): void {\n this.readyPromise = new Promise<void>((resolve) => {\n this.resolveReady = resolve;\n });\n this.startupReadySignals = 1;\n }\n\n private setStartupReadySignals(expectedSignals: number): void {\n if (!this.readyPromise) {\n return;\n }\n\n this.startupReadySignals = Math.max(0, expectedSignals);\n }\n\n private reportStartupReadySignal(): void {\n if (!this.readyPromise || !this.resolveReady) {\n return;\n }\n\n if (this.startupReadySignals <= 0) {\n return;\n }\n\n this.startupReadySignals -= 1;\n if (this.startupReadySignals !== 0) {\n return;\n }\n\n this.resolveReady();\n this.resolveReady = null;\n }\n\n private createWatcher(\n watchTargets?: string | string[],\n usePolling = false,\n reportsStartupReady = true,\n ): void {\n let reportedStartupReady = false;\n this.configPathStates = this.getConfigPathStates();\n const ignoreFilter = createIgnoreFilter(this.projectRoot);\n const resolvedWatchTargets = watchTargets ?? this.getFullChokidarWatchTargets();\n\n const watcherOptions = {\n ignored: (filePath: string) => {\n const relativePath = path.relative(this.projectRoot, filePath);\n if (!relativePath) return false;\n\n if (this.isProjectConfigPathOrAncestor(relativePath)) {\n return false;\n }\n\n if (this.isOutsideProjectPath(relativePath)) {\n return true;\n }\n\n if (hasFilteredPathSegment(relativePath, path.sep)) {\n return true;\n }\n\n if (isRestrictedDirectory(relativePath, path.sep)) {\n return true;\n }\n\n if (ignoreFilter.ignores(relativePath)) {\n return true;\n }\n\n return false;\n },\n persistent: true,\n ignoreInitial: true,\n ...(usePolling ? { usePolling: true } : {}),\n awaitWriteFinish: {\n stabilityThreshold: 300,\n pollInterval: 100,\n },\n };\n let watcher: FSWatcher;\n if (usePolling) {\n const previousUsePolling = process.env.CHOKIDAR_USEPOLLING;\n process.env.CHOKIDAR_USEPOLLING = \"true\";\n try {\n watcher = new FSWatcher(watcherOptions);\n } finally {\n if (previousUsePolling === undefined) {\n delete process.env.CHOKIDAR_USEPOLLING;\n } else {\n process.env.CHOKIDAR_USEPOLLING = previousUsePolling;\n }\n }\n } else {\n watcher = new FSWatcher(watcherOptions);\n }\n this.watcher = watcher;\n watcher.on(\"ready\", () => {\n if (this.watcher !== watcher) return;\n this.reconcileConfigPathStates();\n if (reportsStartupReady) {\n this.reportStartupReadySignal();\n reportedStartupReady = true;\n }\n });\n\n watcher.on(\"error\", (error: unknown) => {\n const err = error instanceof Error ? (error as NodeJS.ErrnoException) : null;\n if (err?.code === \"EPERM\" || err?.code === \"EACCES\") {\n // Silently ignore permission errors — common on macOS restricted paths\n return;\n }\n\n if (\n err?.code === \"EMFILE\"\n && !watcher.options.usePolling\n && !this.pollingFallbackAttempted\n && this.watcher === watcher\n ) {\n this.pollingFallbackAttempted = true;\n console.warn(\"[codebase-index] File watcher exhausted open file handles; retrying with polling.\");\n this.pendingClose = watcher.close().catch((closeError: unknown) => {\n console.error(\"[codebase-index] Failed to close exhausted file watcher:\", closeError);\n });\n if (this.onChanges) {\n const replacementReportsStartupReady = reportsStartupReady || reportedStartupReady;\n if (!this.resolveReady) {\n this.resetReady();\n } else if (reportedStartupReady) {\n this.startupReadySignals += 1;\n }\n this.createWatcher(resolvedWatchTargets, true, replacementReportsStartupReady);\n } else {\n this.watcher = null;\n }\n return;\n }\n\n console.error(\"[codebase-index] Watcher error:\", err?.message ?? error);\n });\n\n watcher.on(\"add\", (filePath) => this.handleChange(watcher, \"add\", filePath));\n watcher.on(\"change\", (filePath) => this.handleChange(watcher, \"change\", filePath));\n watcher.on(\"unlink\", (filePath) => this.handleChange(watcher, \"unlink\", filePath));\n watcher.add(resolvedWatchTargets);\n }\n\n private shouldUseNativeWatcher(): boolean {\n if (this.backend === \"chokidar\") {\n return false;\n }\n\n return true;\n }\n\n private getFullChokidarWatchTargets(): string | string[] {\n if (this.configPath) {\n return [this.projectRoot, this.configPath];\n }\n\n const externalConfigTargets = this.getExternalConfigWatchTargets();\n if (externalConfigTargets.length === 0) {\n return this.projectRoot;\n }\n\n return [this.projectRoot, ...externalConfigTargets];\n }\n\n private getExternalConfigWatchTargets(): string[] {\n return [...new Set(this.projectConfigPaths\n .filter((projectConfigPath) => {\n const relativeConfigPath = path.relative(this.projectRoot, projectConfigPath);\n return this.isOutsideProjectPath(relativeConfigPath);\n })\n .map((projectConfigPath) => {\n if (existsSync(projectConfigPath)) {\n return projectConfigPath;\n }\n\n return this.getNearestExistingDirectory(path.dirname(projectConfigPath));\n }),\n )];\n }\n\n private hasExternalConfigWatchTarget(): boolean {\n return this.getExternalConfigWatchTargets().length > 0;\n }\n\n private startExternalConfigWatcher(usePolling = false): void {\n const externalTargets = this.getExternalConfigWatchTargets();\n if (externalTargets.length === 0) {\n return;\n }\n\n this.createWatcher(externalTargets, usePolling);\n }\n\n private async createNativeWatcher(): Promise<void> {\n const generation = ++this.nativeSetupGeneration;\n const reconciler = new FileSnapshotReconciler(this.projectRoot, this.config, this.projectConfigPaths);\n const watcher = new NativeRecursiveWatcher(\n this.projectRoot,\n (filePath) => this.scheduleNativeReconciliation(generation, filePath),\n { onError: (error) => void this.fallbackFromNativeWatcher(generation, error) },\n );\n\n this.nativeReconciler = reconciler;\n this.nativeWatcher = watcher;\n this.nativeInitializing = true;\n\n try {\n watcher.start();\n if (!this.isCurrentNativeSetup(generation)) {\n await watcher.stop();\n return;\n }\n\n await reconciler.initialize();\n if (!this.isCurrentNativeSetup(generation) || this.nativeWatcher !== watcher) {\n await watcher.stop();\n return;\n }\n\n this.nativeStarting = false;\n this.nativeInitializing = false;\n await this.reconcileNativeWatcherWithPendingInvalidations(generation);\n this.reportStartupReadySignal();\n } catch (error) {\n if (!this.isCurrentNativeSetup(generation)) return;\n this.nativeInitializing = false;\n if (this.nativeWatcher) {\n await this.fallbackFromNativeWatcher(generation, error);\n return;\n }\n\n this.nativeStarting = false;\n const externalWatcher = this.watcher;\n this.watcher = null;\n this.nativeReconciler = null;\n await externalWatcher?.close();\n console.warn(\"[codebase-index] Native recursive watcher unavailable; using Chokidar fallback.\", error);\n this.setStartupReadySignals(1);\n this.createWatcher();\n }\n }\n\n private isCurrentNativeSetup(generation: number): boolean {\n return this.nativeSetupGeneration === generation && this.onChanges !== null;\n }\n\n private scheduleNativeReconciliation(generation: number, filePath: string | null): void {\n if (!this.isCurrentNativeSetup(generation)) return;\n\n const requiresFullReconciliation = filePath === path.join(this.projectRoot, \".gitignore\");\n const invalidatedPath = requiresFullReconciliation ? null : filePath;\n this.nativeInvalidatedPaths.set(invalidatedPath, invalidatedPath !== null);\n\n if (this.nativeReconcileTimer) {\n clearTimeout(this.nativeReconcileTimer);\n }\n this.nativeReconcileTimer = setTimeout(() => {\n this.nativeReconcileTimer = null;\n void this.reconcileNativeWatcherFromQueue(generation);\n }, 100);\n }\n\n private reconcileNativeWatcherFromQueue(generation: number): void {\n if (!this.isCurrentNativeSetup(generation) || this.nativeInitializing) return;\n\n const invalidatedPaths = this.popNativeInvalidations();\n if (invalidatedPaths.length === 0) return;\n\n void this.reconcileNativeWatcher(generation, invalidatedPaths);\n }\n\n private async reconcileNativeWatcher(generation: number, invalidatedPaths: readonly SnapshotInvalidation[]): Promise<void> {\n if (!this.isCurrentNativeSetup(generation) || !this.nativeReconciler) return;\n\n try {\n const reconciler = this.nativeReconciler;\n const changes = await reconciler.reconcile(invalidatedPaths);\n if (!this.isCurrentNativeSetup(generation) || this.nativeReconciler !== reconciler) return;\n\n this.recordChanges(changes);\n } catch (error) {\n await this.fallbackFromNativeWatcher(generation, error);\n }\n }\n\n private async reconcileNativeWatcherWithPendingInvalidations(generation: number): Promise<void> {\n const invalidatedPaths = this.popNativeInvalidations();\n if (invalidatedPaths.length === 0) return;\n\n await this.reconcileNativeWatcher(generation, invalidatedPaths);\n }\n\n private popNativeInvalidations(): SnapshotInvalidation[] {\n if (this.nativeInvalidatedPaths.size === 0) return [];\n\n const invalidations = [...this.nativeInvalidatedPaths].map(([invalidatedPath, forceChange]) => ({\n path: invalidatedPath,\n forceChange,\n }));\n this.nativeInvalidatedPaths.clear();\n return invalidations;\n }\n\n private async fallbackFromNativeWatcher(generation: number, error: unknown): Promise<void> {\n if (!this.isCurrentNativeSetup(generation)) return;\n\n const watcher = this.nativeWatcher;\n const externalWatcher = this.watcher;\n this.nativeWatcher = null;\n this.watcher = null;\n this.nativeReconciler = null;\n this.nativeStarting = false;\n this.nativeInitializing = false;\n this.nativeSetupGeneration += 1;\n if (this.nativeReconcileTimer) {\n clearTimeout(this.nativeReconcileTimer);\n this.nativeReconcileTimer = null;\n }\n this.nativeInvalidatedPaths.clear();\n this.setStartupReadySignals(1);\n\n console.warn(\"[codebase-index] Native recursive watcher failed; using Chokidar fallback.\", error);\n await watcher?.stop();\n await externalWatcher?.close();\n if (this.onChanges) {\n this.createWatcher();\n }\n }\n\n private handleChange(watcher: FSWatcher, type: FileChangeType, filePath: string): void {\n if (this.watcher !== watcher) {\n return;\n }\n\n if (this.isProjectConfigPath(filePath)) {\n this.updateConfigPathState(filePath);\n this.pendingChanges.set(filePath, type);\n this.scheduleFlush();\n return;\n }\n\n const includePatterns = [...this.config.include, ...(this.config.additionalInclude ?? [])];\n if (\n !shouldIncludeFile(\n filePath,\n this.projectRoot,\n includePatterns,\n this.config.exclude,\n createIgnoreFilter(this.projectRoot)\n )\n ) {\n return;\n }\n\n this.recordChanges([{ path: filePath, type }]);\n }\n\n private recordChanges(changes: FileChange[]): void {\n if (changes.length === 0) return;\n\n for (const change of changes) {\n this.pendingChanges.set(change.path, change.type);\n }\n this.scheduleFlush();\n }\n\n private isProjectConfigPath(filePath: string): boolean {\n const relativePath = path.relative(this.projectRoot, filePath);\n const normalizedRelativePath = path.normalize(relativePath);\n return this.getProjectConfigRelativePaths().some((configPath) => configPath === normalizedRelativePath);\n }\n\n private isProjectConfigPathOrAncestor(relativePath: string): boolean {\n const normalizedRelativePath = path.normalize(relativePath);\n return this.getProjectConfigRelativePaths().some(\n (configPath) => configPath === normalizedRelativePath || configPath.startsWith(`${normalizedRelativePath}${path.sep}`),\n );\n }\n\n private isOutsideProjectPath(relativePath: string): boolean {\n return relativePath === \"..\"\n || relativePath.startsWith(`..${path.sep}`)\n || path.isAbsolute(relativePath);\n }\n\n private getNearestExistingDirectory(directoryPath: string): string {\n let candidate = directoryPath;\n while (!existsSync(candidate)) {\n const parent = path.dirname(candidate);\n if (parent === candidate) break;\n candidate = parent;\n }\n return candidate;\n }\n\n private getProjectConfigRelativePaths(): string[] {\n return this.projectConfigPaths.map(\n (configPath) => path.normalize(path.relative(this.projectRoot, configPath)),\n );\n }\n\n private getConfigPathStates(): Map<string, ConfigPathState> {\n const states = new Map<string, ConfigPathState>();\n for (const configPath of this.projectConfigPaths) {\n const state = this.getConfigPathState(configPath);\n if (state) states.set(configPath, state);\n }\n return states;\n }\n\n private getConfigPathState(configPath: string): ConfigPathState | undefined {\n try {\n const stats = statSync(configPath);\n return stats.isFile() ? { mtimeMs: stats.mtimeMs, size: stats.size } : undefined;\n } catch (error: unknown) {\n // A config file may disappear between the watch event and this stat.\n void error;\n return undefined;\n }\n }\n\n private updateConfigPathState(configPath: string): void {\n const state = this.getConfigPathState(configPath);\n if (state) {\n this.configPathStates.set(configPath, state);\n } else {\n this.configPathStates.delete(configPath);\n }\n }\n\n private reconcileConfigPathStates(): void {\n const nextStates = this.getConfigPathStates();\n const changes: FileChange[] = [];\n for (const configPath of this.projectConfigPaths) {\n const previous = this.configPathStates.get(configPath);\n const next = nextStates.get(configPath);\n if (!previous && next) {\n changes.push({ path: configPath, type: \"add\" });\n } else if (previous && !next) {\n changes.push({ path: configPath, type: \"unlink\" });\n } else if (previous && next && (previous.size !== next.size || previous.mtimeMs !== next.mtimeMs)) {\n changes.push({ path: configPath, type: \"change\" });\n }\n }\n this.configPathStates = nextStates;\n this.recordChanges(changes);\n }\n\n private scheduleFlush(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n this.debounceTimer = setTimeout(() => {\n this.flush();\n }, this.debounceMs);\n }\n\n private async flush(): Promise<void> {\n if (this.pendingChanges.size === 0 || !this.onChanges) {\n return;\n }\n\n const changes: FileChange[] = Array.from(this.pendingChanges.entries()).map(\n ([path, type]) => ({ path, type })\n );\n\n this.pendingChanges.clear();\n\n try {\n await this.onChanges(changes);\n } catch (error) {\n console.error(\"Error handling file changes:\", error);\n }\n }\n\n async stop(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.nativeReconcileTimer) {\n clearTimeout(this.nativeReconcileTimer);\n this.nativeReconcileTimer = null;\n }\n this.nativeInvalidatedPaths.clear();\n\n const watcher = this.watcher;\n const nativeWatcher = this.nativeWatcher;\n const pendingClose = this.pendingClose;\n const resolveReady = this.resolveReady;\n this.watcher = null;\n this.nativeWatcher = null;\n this.nativeReconciler = null;\n this.nativeStarting = false;\n this.nativeInitializing = false;\n this.nativeSetupGeneration += 1;\n this.pendingClose = null;\n this.resolveReady = null;\n this.readyPromise = null;\n this.pendingChanges.clear();\n this.onChanges = null;\n await Promise.all([watcher?.close(), nativeWatcher?.stop(), pendingClose]);\n\n resolveReady?.();\n }\n\n isRunning(): boolean {\n return this.watcher !== null || this.nativeWatcher !== null || this.nativeStarting;\n }\n\n async waitUntilReady(): Promise<void> {\n await (this.readyPromise ?? Promise.resolve());\n }\n}\n","import { watch, type WatchEventType, type WatchOptions } from \"node:fs\";\nimport * as path from \"node:path\";\n\nexport type NativeRecursiveWatcherChangeHandler = (absolutePath: string | null) => void | Promise<void>;\n\nexport type NativeFsWatchListener = (\n eventType: WatchEventType,\n filename: string | Buffer | null | undefined,\n) => void;\n\ntype NativeFsWatcherHandle = {\n close(): void | Promise<void>;\n on?(event: \"error\", listener: (error: Error) => void): void;\n};\n\nexport type NativeRecursiveWatcherFactory = (\n root: string,\n listener: NativeFsWatchListener,\n options: WatchOptions,\n) => NativeFsWatcherHandle;\n\nexport interface NativeRecursiveWatcherOptions {\n onError?: (error: Error) => void;\n watchFactory?: NativeRecursiveWatcherFactory;\n}\n\nexport class NativeRecursiveWatcher {\n private watcher: NativeFsWatcherHandle | null = null;\n private listenerToken = 0;\n\n private readonly watchFactory: NativeRecursiveWatcherFactory;\n private readonly onError: ((error: Error) => void) | undefined;\n\n constructor(\n private readonly root: string,\n private readonly onChange: NativeRecursiveWatcherChangeHandler,\n options: NativeRecursiveWatcherOptions = {},\n ) {\n this.watchFactory = options.watchFactory ?? this.defaultWatchFactory;\n this.onError = options.onError;\n }\n\n start(): void {\n if (this.watcher) return;\n\n const token = ++this.listenerToken;\n const listener: NativeFsWatchListener = (_eventType, filename) => {\n if (this.watcher === null || this.listenerToken !== token) return;\n\n const absolutePath = this.toAbsolutePath(filename);\n const nextResult = this.onChange(absolutePath);\n\n if (nextResult instanceof Promise) {\n void nextResult.catch((error: unknown) => {\n console.error(\"[codebase-index] Error handling native watcher event:\", error);\n });\n }\n };\n\n const watcher = this.watchFactory(this.root, listener, {\n persistent: true,\n recursive: true,\n });\n watcher.on?.(\"error\", (error) => {\n if (this.watcher === watcher && this.listenerToken === token) {\n this.onError?.(error);\n }\n });\n this.watcher = watcher;\n }\n\n async stop(): Promise<void> {\n const watcher = this.watcher;\n this.watcher = null;\n this.listenerToken += 1;\n\n if (!watcher) return;\n\n await watcher.close();\n }\n\n private toAbsolutePath(filename: string | Buffer | null | undefined): string | null {\n if (filename == null) return null;\n\n const normalizedFilename = typeof filename === \"string\" ? filename : filename.toString();\n const absolutePath = path.resolve(this.root, normalizedFilename);\n const relativePath = path.relative(this.root, absolutePath);\n const outsideRoot = relativePath === \"..\"\n || relativePath.startsWith(`..${path.sep}`)\n || path.isAbsolute(relativePath);\n return outsideRoot ? null : absolutePath;\n }\n\n private defaultWatchFactory: NativeRecursiveWatcherFactory = (\n root,\n listener,\n options,\n ) => watch(root, options, listener);\n}\n","import type { Dirent, Stats } from \"node:fs\";\nimport type { CodebaseIndexConfig } from \"../config/schema.js\";\nimport type { FileChange, FileChangeType } from \"./file-watcher.js\";\n\nimport * as fsPromises from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nimport { createIgnoreFilter, shouldIncludeFile } from \"../utils/files.js\";\nimport { hasFilteredPathSegment, isRestrictedDirectory } from \"../utils/paths.js\";\n\nexport interface FileSnapshotEntry {\n readonly size: number;\n readonly mtimeMs: number;\n}\n\nexport type FileSnapshotMap = ReadonlyMap<string, FileSnapshotEntry>;\nexport type SnapshotFilterConfig = Pick<CodebaseIndexConfig, \"include\" | \"additionalInclude\" | \"exclude\"> & {\n indexing?: { maxDepth?: number };\n};\n\nexport interface FileSnapshotScan {\n readonly entries: FileSnapshotMap;\n readonly unreadablePrefixes: ReadonlySet<string>;\n}\n\nexport async function buildFileSnapshot(\n projectRoot: string,\n config: SnapshotFilterConfig,\n configPaths: string[] = [],\n): Promise<FileSnapshotMap> {\n return (await buildFileSnapshotScan(projectRoot, config, configPaths)).entries;\n}\n\nexport async function buildFileSnapshotScan(\n projectRoot: string,\n config: SnapshotFilterConfig,\n configPaths: string[] = [],\n): Promise<FileSnapshotScan> {\n const normalizedProjectRoot = path.resolve(projectRoot);\n const ignoreFilter = createIgnoreFilter(normalizedProjectRoot);\n const includePatterns = [...config.include, ...(config.additionalInclude ?? [])];\n const maxDepth = config.indexing?.maxDepth ?? -1;\n const snapshot = new Map<string, FileSnapshotEntry>();\n const unreadablePrefixes = new Set<string>();\n\n const includeFile = async (filePath: string): Promise<void> => {\n const normalizedPath = path.resolve(filePath);\n if (!shouldIncludeFile(normalizedPath, normalizedProjectRoot, includePatterns, config.exclude, ignoreFilter)) return;\n\n const stat = await readStatIfFile(normalizedPath, unreadablePrefixes);\n if (stat) snapshot.set(normalizedPath, { size: stat.size, mtimeMs: stat.mtimeMs });\n };\n\n const walk = async (directoryPath: string, depth: number): Promise<void> => {\n let entries: Dirent[];\n try {\n entries = await fsPromises.readdir(directoryPath, { withFileTypes: true });\n } catch (error) {\n if (isMissingFsError(error)) return;\n if (isPermissionFsError(error)) {\n unreadablePrefixes.add(path.resolve(directoryPath));\n return;\n }\n throw error;\n }\n\n for (const entry of entries) {\n const fullPath = path.join(directoryPath, entry.name);\n const relativePath = path.relative(normalizedProjectRoot, fullPath);\n if (entry.isDirectory()) {\n if (hasFilteredPathSegment(relativePath, path.sep) || isRestrictedDirectory(relativePath, path.sep)) continue;\n if (ignoreFilter.ignores(relativePath)) continue;\n if (maxDepth === -1 || depth < maxDepth) await walk(fullPath, depth + 1);\n } else if (entry.isFile()) {\n await includeFile(fullPath);\n }\n }\n };\n\n await walk(normalizedProjectRoot, 0);\n await includeExplicitConfigPaths(snapshot, unreadablePrefixes, configPaths);\n return { entries: snapshot, unreadablePrefixes };\n}\n\nexport async function buildFileSnapshotForPath(\n projectRoot: string,\n config: SnapshotFilterConfig,\n configPaths: string[],\n targetPath: string,\n): Promise<FileSnapshotMap> {\n return (await buildFileSnapshotForPathScan(projectRoot, config, configPaths, targetPath)).entries;\n}\n\nexport async function buildFileSnapshotForPathScan(\n projectRoot: string,\n config: SnapshotFilterConfig,\n configPaths: string[],\n targetPath: string,\n): Promise<FileSnapshotScan> {\n const normalizedProjectRoot = path.resolve(projectRoot);\n const normalizedTargetPath = path.resolve(targetPath);\n if (!isWithinPath(normalizedProjectRoot, normalizedTargetPath)) {\n return { entries: new Map(), unreadablePrefixes: new Set() };\n }\n\n const ignoreFilter = createIgnoreFilter(normalizedProjectRoot);\n const includePatterns = [...config.include, ...(config.additionalInclude ?? [])];\n const maxDepth = config.indexing?.maxDepth ?? -1;\n const explicitConfigPaths = new Set(configPaths.map((configPath) => path.resolve(configPath)));\n const snapshot = new Map<string, FileSnapshotEntry>();\n const unreadablePrefixes = new Set<string>();\n\n const includeFile = async (filePath: string): Promise<void> => {\n const normalizedPath = path.resolve(filePath);\n if (!explicitConfigPaths.has(normalizedPath) && !shouldIncludeFile(\n normalizedPath, normalizedProjectRoot, includePatterns, config.exclude, ignoreFilter,\n )) return;\n const stat = await readStatIfFile(normalizedPath, unreadablePrefixes);\n if (stat) snapshot.set(normalizedPath, { size: stat.size, mtimeMs: stat.mtimeMs });\n };\n\n const walk = async (directoryPath: string, depth: number): Promise<void> => {\n let entries: Dirent[];\n try {\n entries = await fsPromises.readdir(directoryPath, { withFileTypes: true });\n } catch (error) {\n if (isMissingFsError(error)) return;\n if (isPermissionFsError(error)) {\n unreadablePrefixes.add(path.resolve(directoryPath));\n return;\n }\n throw error;\n }\n for (const entry of entries) {\n const fullPath = path.join(directoryPath, entry.name);\n const relativePath = path.relative(normalizedProjectRoot, fullPath);\n if (entry.isDirectory()) {\n if (hasFilteredPathSegment(relativePath, path.sep) || isRestrictedDirectory(relativePath, path.sep)) continue;\n if (ignoreFilter.ignores(relativePath)) continue;\n if (maxDepth === -1 || depth < maxDepth) await walk(fullPath, depth + 1);\n } else if (entry.isFile()) {\n await includeFile(fullPath);\n }\n }\n };\n\n const targetStat = await readStatIfFile(normalizedTargetPath, unreadablePrefixes);\n if (targetStat) await includeFile(normalizedTargetPath);\n else await walk(normalizedTargetPath, 0);\n await includeExplicitConfigPathsInPath(snapshot, unreadablePrefixes, configPaths, normalizedTargetPath);\n return { entries: snapshot, unreadablePrefixes };\n}\n\nexport function completeFileSnapshot(previous: FileSnapshotMap, scan: FileSnapshotScan): FileSnapshotMap {\n const completed = new Map(scan.entries);\n for (const unreadablePrefix of scan.unreadablePrefixes) {\n for (const [entryPath, entry] of previous) {\n if (isWithinPath(unreadablePrefix, entryPath) && !completed.has(entryPath)) completed.set(entryPath, entry);\n }\n }\n return completed;\n}\n\nasync function includeExplicitConfigPaths(\n snapshot: Map<string, FileSnapshotEntry>,\n unreadablePrefixes: Set<string>,\n configPaths: string[],\n): Promise<void> {\n for (const configPath of [...new Set(configPaths.map((value) => path.resolve(value)))]) {\n if (snapshot.has(configPath)) continue;\n const stat = await readStatIfFile(configPath, unreadablePrefixes);\n if (stat) snapshot.set(configPath, { size: stat.size, mtimeMs: stat.mtimeMs });\n }\n}\n\nasync function includeExplicitConfigPathsInPath(\n snapshot: Map<string, FileSnapshotEntry>,\n unreadablePrefixes: Set<string>,\n configPaths: string[],\n targetPath: string,\n): Promise<void> {\n await includeExplicitConfigPaths(\n snapshot,\n unreadablePrefixes,\n configPaths.filter((configPath) => isWithinPath(targetPath, path.resolve(configPath))),\n );\n}\n\nexport function isWithinPath(parentPath: string, childPath: string): boolean {\n const relativePath = path.relative(parentPath, childPath);\n return relativePath === \"\" || (!relativePath.startsWith(`..${path.sep}`) && relativePath !== \"..\" && !path.isAbsolute(relativePath));\n}\n\nasync function readStatIfFile(filePath: string, unreadablePrefixes: Set<string>): Promise<Stats | null> {\n try {\n const stat = await fsPromises.stat(filePath);\n return stat.isFile() ? stat : null;\n } catch (error) {\n if (isMissingFsError(error)) return null;\n if (isPermissionFsError(error)) {\n unreadablePrefixes.add(path.resolve(filePath));\n return null;\n }\n throw error;\n }\n}\n\nfunction isMissingFsError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && [\"ENOENT\", \"ENOTDIR\"].includes((error as NodeJS.ErrnoException).code ?? \"\");\n}\n\nfunction isPermissionFsError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && [\"EACCES\", \"EPERM\"].includes((error as NodeJS.ErrnoException).code ?? \"\");\n}\n\nconst diffTypeOrder: Record<FileChangeType, number> = { add: 0, change: 1, unlink: 2 };\n\nexport function diffFileSnapshots(\n previous: FileSnapshotMap,\n current: FileSnapshotMap,\n forcedChanges: ReadonlySet<string> = new Set(),\n): FileChange[] {\n const changes: FileChange[] = [];\n for (const [filePath, previousEntry] of previous) {\n const currentEntry = current.get(filePath);\n if (!currentEntry) changes.push({ type: \"unlink\", path: filePath });\n else if (\n forcedChanges.has(filePath)\n || currentEntry.size !== previousEntry.size\n || currentEntry.mtimeMs !== previousEntry.mtimeMs\n ) {\n changes.push({ type: \"change\", path: filePath });\n }\n }\n for (const [filePath] of current) {\n if (!previous.has(filePath)) changes.push({ type: \"add\", path: filePath });\n }\n return changes.sort((left, right) => left.path.localeCompare(right.path) || diffTypeOrder[left.type] - diffTypeOrder[right.type]);\n}\n","import chokidar, { FSWatcher } from \"chokidar\";\nimport * as path from \"path\";\n\nimport { getCurrentBranch, getHeadPath, isGitRepo } from \"../git/index.js\";\n\nexport type BranchChangeHandler = (oldBranch: string | null, newBranch: string) => Promise<void>;\n\n/**\n * Watches .git/HEAD for branch changes.\n * When HEAD changes (branch switch, checkout), triggers callback with old and new branch.\n */\nexport class GitHeadWatcher {\n private watcher: FSWatcher | null = null;\n private projectRoot: string;\n private currentBranch: string | null = null;\n private onBranchChange: BranchChangeHandler | null = null;\n private debounceTimer: NodeJS.Timeout | null = null;\n private debounceMs = 100; // Short debounce for git operations\n private readyPromise: Promise<void> = Promise.resolve();\n private resolveReady: (() => void) | null = null;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n }\n\n start(handler: BranchChangeHandler): void {\n if (this.watcher) {\n return;\n }\n\n if (!isGitRepo(this.projectRoot)) {\n this.readyPromise = Promise.resolve();\n return; // Not a git repo, nothing to watch\n }\n\n this.readyPromise = new Promise<void>((resolve) => {\n this.resolveReady = resolve;\n });\n\n this.onBranchChange = handler;\n this.currentBranch = getCurrentBranch(this.projectRoot);\n\n const headPath = getHeadPath(this.projectRoot);\n\n // Also watch refs/heads for when branches are updated\n const refsPath = path.join(this.projectRoot, \".git\", \"refs\", \"heads\");\n\n this.watcher = chokidar.watch([headPath, refsPath], {\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 50,\n pollInterval: 10,\n },\n });\n\n this.watcher.on(\"change\", () => this.handleHeadChange());\n this.watcher.on(\"add\", () => this.handleHeadChange());\n this.watcher.once(\"ready\", () => {\n this.resolveReady?.();\n this.resolveReady = null;\n });\n }\n\n private handleHeadChange(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n this.debounceTimer = setTimeout(() => {\n this.checkBranchChange();\n }, this.debounceMs);\n }\n\n private async checkBranchChange(): Promise<void> {\n const newBranch = getCurrentBranch(this.projectRoot);\n\n if (newBranch && newBranch !== this.currentBranch && this.onBranchChange) {\n const oldBranch = this.currentBranch;\n this.currentBranch = newBranch;\n\n try {\n await this.onBranchChange(oldBranch, newBranch);\n } catch (error) {\n console.error(\"Error handling branch change:\", error);\n }\n } else if (newBranch) {\n this.currentBranch = newBranch;\n }\n }\n\n getCurrentBranch(): string | null {\n return this.currentBranch;\n }\n\n async stop(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n if (this.watcher) {\n const watcher = this.watcher;\n this.watcher = null;\n await watcher.close();\n }\n\n this.onBranchChange = null;\n this.resolveReady?.();\n this.resolveReady = null;\n this.readyPromise = Promise.resolve();\n }\n\n isRunning(): boolean {\n return this.watcher !== null;\n }\n\n async waitUntilReady(): Promise<void> {\n await this.readyPromise;\n }\n}\n","import { execFileSync } from \"child_process\";\nimport * as path from \"path\";\n\nimport type { VisualizationChange, VisualizationData, VisualizationNode } from \"./types.js\";\n\ninterface FileActivity {\n churn: number;\n commits: number;\n latestDate: string;\n latestHash: string;\n latestSubject: string;\n}\n\ninterface ModuleActivity {\n moduleId: string;\n filePaths: Set<string>;\n churn: number;\n commits: number;\n latestDate: string;\n latestHash: string;\n latestSubject: string;\n}\n\nexport function attachRecentActivity(data: VisualizationData, projectRoot: string): VisualizationData {\n const activity = readGitActivity(projectRoot);\n const changes = activity.size > 0\n ? buildGitChanges(data, activity, projectRoot)\n : buildGraphChanges(data);\n\n return {\n ...data,\n changes,\n };\n}\n\nfunction readGitActivity(projectRoot: string): Map<string, FileActivity> {\n try {\n const output = execFileSync(\n \"git\",\n [\"-C\", projectRoot, \"log\", \"--since=90.days\", \"--numstat\", \"--date=short\", \"--pretty=format:__COMMIT__%x09%h%x09%ad%x09%s\"],\n { encoding: \"utf8\", maxBuffer: 8 * 1024 * 1024, stdio: [\"ignore\", \"pipe\", \"ignore\"] },\n );\n return parseGitActivity(output);\n } catch {\n return new Map();\n }\n}\n\nfunction parseGitActivity(output: string): Map<string, FileActivity> {\n const activity = new Map<string, FileActivity>();\n let latestHash = \"\";\n let latestDate = \"\";\n let latestSubject = \"\";\n\n for (const line of output.split(/\\r?\\n/)) {\n if (!line) continue;\n if (line.startsWith(\"__COMMIT__\\t\")) {\n const [, hash = \"\", date = \"\", subject = \"\"] = line.split(\"\\t\");\n latestHash = hash;\n latestDate = date;\n latestSubject = subject;\n continue;\n }\n\n const [addedRaw, deletedRaw, filePath] = line.split(\"\\t\");\n if (!filePath || addedRaw === \"-\" || deletedRaw === \"-\") continue;\n\n const churn = Number(addedRaw) + Number(deletedRaw);\n if (!Number.isFinite(churn) || churn <= 0) continue;\n\n const normalizedPath = normalizePath(filePath);\n const previous = activity.get(normalizedPath);\n activity.set(normalizedPath, {\n churn: (previous?.churn ?? 0) + churn,\n commits: (previous?.commits ?? 0) + 1,\n latestDate: previous?.latestDate ?? latestDate,\n latestHash: previous?.latestHash ?? latestHash,\n latestSubject: previous?.latestSubject ?? latestSubject,\n });\n }\n\n return activity;\n}\n\nfunction buildGitChanges(data: VisualizationData, activity: Map<string, FileActivity>, projectRoot: string): VisualizationChange[] {\n const byModule = new Map<string, ModuleActivity>();\n\n for (const node of data.nodes) {\n const fileActivity = activity.get(toGitRelativePath(projectRoot, node.filePath));\n if (!fileActivity) continue;\n\n const current = byModule.get(node.moduleId) ?? {\n moduleId: node.moduleId,\n filePaths: new Set<string>(),\n churn: 0,\n commits: 0,\n latestDate: fileActivity.latestDate,\n latestHash: fileActivity.latestHash,\n latestSubject: fileActivity.latestSubject,\n };\n if (!current.filePaths.has(node.filePath)) {\n current.filePaths.add(node.filePath);\n current.churn += fileActivity.churn;\n current.commits += fileActivity.commits;\n }\n if (fileActivity.latestDate > current.latestDate) {\n current.latestDate = fileActivity.latestDate;\n current.latestHash = fileActivity.latestHash;\n current.latestSubject = fileActivity.latestSubject;\n }\n byModule.set(node.moduleId, current);\n }\n\n return [...byModule.values()]\n .sort((a, b) => scoreModule(data, b.moduleId, b.churn) - scoreModule(data, a.moduleId, a.churn))\n .slice(0, 12)\n .map((item, index) => toGitChange(data, item, index));\n}\n\nfunction buildGraphChanges(data: VisualizationData): VisualizationChange[] {\n return data.modules\n .map((module) => {\n const calls = moduleCallCount(data, module.id);\n const focusNode = strongestNode(data, module.id);\n const risk = riskFor(calls, module.symbolCount);\n return {\n id: `graph-${module.id}`,\n title: `${module.label} is structurally important`,\n kind: risk === \"high\" ? \"risk\" : \"hot\",\n when: \"graph-derived\",\n source: \"call graph\",\n intent: \"load-bearing path\",\n summary: `${module.symbolCount} symbols with ${calls} cross-module calls in this slice.`,\n why: \"No recent Git history was available, so this highlights modules whose call relationships make them expensive to misunderstand during onboarding.\",\n calls,\n churn: 0,\n risk,\n moduleId: module.id,\n focusNodeId: focusNode?.id,\n filePaths: [...new Set(data.nodes.filter((node) => node.moduleId === module.id).map((node) => node.filePath))].slice(0, 6),\n } satisfies VisualizationChange;\n })\n .sort((a, b) => b.calls - a.calls)\n .slice(0, 8);\n}\n\nfunction toGitChange(data: VisualizationData, item: ModuleActivity, index: number): VisualizationChange {\n const module = data.modules.find((candidate) => candidate.id === item.moduleId);\n const label = module?.label ?? item.moduleId;\n const calls = moduleCallCount(data, item.moduleId);\n const focusNode = strongestNode(data, item.moduleId);\n const risk = riskFor(calls, item.churn);\n const intent = inferIntent(item.latestSubject);\n\n return {\n id: `git-${item.moduleId}-${index}`,\n title: `${label} moved recently`,\n kind: risk === \"high\" ? \"risk\" : \"hot\",\n when: item.latestDate || \"recently\",\n source: item.latestHash ? `commit ${item.latestHash}` : \"git history\",\n intent,\n summary: `${item.churn} changed lines across ${item.filePaths.size} indexed files. Latest: ${item.latestSubject || \"no commit subject\"}.`,\n why: `${label} is both changing and connected to ${calls} call edges. Start here to understand whether the current graph is new work, load-bearing behavior, or legacy surface area.`,\n calls,\n churn: item.churn,\n risk,\n moduleId: item.moduleId,\n focusNodeId: focusNode?.id,\n filePaths: [...item.filePaths].slice(0, 8),\n };\n}\n\nfunction scoreModule(data: VisualizationData, moduleId: string, churn: number): number {\n return churn + moduleCallCount(data, moduleId) * 4;\n}\n\nfunction moduleCallCount(data: VisualizationData, moduleId: string): number {\n const moduleEdgeCount = data.moduleEdges\n .filter((edge) => edge.source === moduleId || edge.target === moduleId)\n .reduce((total, edge) => total + edge.weight, 0);\n if (moduleEdgeCount > 0) return moduleEdgeCount;\n\n const nodeModules = new Map(data.nodes.map((node) => [node.id, node.moduleId]));\n return data.edges.filter((edge) => nodeModules.get(edge.source) === moduleId || nodeModules.get(edge.target) === moduleId).length;\n}\n\nfunction strongestNode(data: VisualizationData, moduleId: string): VisualizationNode | undefined {\n const degree = new Map<string, number>();\n for (const edge of data.edges) {\n degree.set(edge.source, (degree.get(edge.source) ?? 0) + 1);\n degree.set(edge.target, (degree.get(edge.target) ?? 0) + 1);\n }\n\n return data.nodes\n .filter((node) => node.moduleId === moduleId)\n .sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0))[0];\n}\n\nfunction riskFor(calls: number, churnOrSymbols: number): \"low\" | \"medium\" | \"high\" {\n if (calls >= 20 || churnOrSymbols >= 250) return \"high\";\n if (calls >= 8 || churnOrSymbols >= 80) return \"medium\";\n return \"low\";\n}\n\nfunction inferIntent(subject: string): string {\n const normalized = subject.toLowerCase();\n if (normalized.includes(\"fix\")) return \"stability\";\n if (normalized.includes(\"test\")) return \"verification\";\n if (normalized.includes(\"refactor\")) return \"refactor\";\n if (normalized.includes(\"visual\")) return \"visualization\";\n if (normalized.includes(\"call\") || normalized.includes(\"graph\")) return \"call graph\";\n if (normalized.includes(\"config\")) return \"configuration\";\n return \"recent work\";\n}\n\nfunction normalizePath(filePath: string): string {\n return filePath.replace(/\\\\/g, \"/\");\n}\n\nfunction toGitRelativePath(projectRoot: string, filePath: string): string {\n const relativePath = path.isAbsolute(filePath) ? path.relative(projectRoot, filePath) : filePath;\n return normalizePath(relativePath);\n}\n","import * as path from \"path\";\n\nimport type { SymbolData, CallEdgeData } from \"../../native/index.js\";\nimport type { VisualizationData, VisualizationNode, VisualizationEdge } from \"./types.js\";\nimport { deriveModuleEdges, deriveModules } from \"./modules.js\";\n\nexport interface TransformOptions {\n includeOrphans?: boolean;\n directory?: string;\n maxNodes?: number;\n}\n\nexport function transformForVisualization(\n symbols: SymbolData[],\n edges: CallEdgeData[],\n options: TransformOptions = {},\n): VisualizationData {\n const { includeOrphans = false, directory, maxNodes = 5000 } = options;\n\n // Filter symbols by directory if specified\n let filteredSymbols = symbols;\n if (directory) {\n const normalizedDir = directory.replace(/\\/$/, \"\");\n const normalizedDirWithSlash = `${normalizedDir}/`;\n const normalizedAbsoluteSuffix = `/${normalizedDirWithSlash}`;\n filteredSymbols = symbols.filter(\n (s) => {\n const normalizedPath = s.filePath.replace(/\\\\/g, \"/\");\n return normalizedPath === normalizedDir\n || normalizedPath.startsWith(normalizedDirWithSlash)\n || normalizedPath.endsWith(`/${normalizedDir}`)\n || normalizedPath.includes(normalizedAbsoluteSuffix);\n },\n );\n }\n\n // Build symbol ID set for filtering edges\n const symbolIdSet = new Set(filteredSymbols.map((s) => s.id));\n\n // Filter to resolved edges where both source and target are in our symbol set\n const filteredEdges: VisualizationEdge[] = [];\n for (const edge of edges) {\n if (!edge.isResolved || !edge.toSymbolId) continue;\n if (!symbolIdSet.has(edge.fromSymbolId)) continue;\n if (!symbolIdSet.has(edge.toSymbolId)) continue;\n\n filteredEdges.push({\n source: edge.fromSymbolId,\n target: edge.toSymbolId,\n callType: edge.callType,\n confidence: edge.confidence,\n line: edge.line,\n });\n }\n\n // Filter orphan nodes if requested\n let finalSymbols = filteredSymbols;\n if (!includeOrphans) {\n const connectedIds = new Set<string>();\n for (const edge of filteredEdges) {\n connectedIds.add(edge.source);\n connectedIds.add(edge.target);\n }\n finalSymbols = filteredSymbols.filter((s) => connectedIds.has(s.id));\n }\n\n // Check truncation\n const truncated = finalSymbols.length > maxNodes;\n if (truncated) {\n // Keep nodes with most connections\n const connectionCount = new Map<string, number>();\n for (const edge of filteredEdges) {\n connectionCount.set(edge.source, (connectionCount.get(edge.source) ?? 0) + 1);\n connectionCount.set(edge.target, (connectionCount.get(edge.target) ?? 0) + 1);\n }\n finalSymbols = finalSymbols\n .sort((a, b) => (connectionCount.get(b.id) ?? 0) - (connectionCount.get(a.id) ?? 0))\n .slice(0, maxNodes);\n\n // Re-filter edges to only include remaining nodes\n const remainingIds = new Set(finalSymbols.map((s) => s.id));\n filteredEdges.splice(\n 0,\n filteredEdges.length,\n ...filteredEdges.filter((e) => remainingIds.has(e.source) && remainingIds.has(e.target)),\n );\n }\n\n // Map to visualization nodes\n const nodes: VisualizationNode[] = finalSymbols.map((s) => ({\n id: s.id,\n name: s.name,\n filePath: s.filePath,\n kind: s.kind,\n line: s.startLine,\n directory: path.dirname(s.filePath),\n moduleId: \"\",\n moduleLabel: \"\",\n }));\n\n const modules = deriveModules(nodes);\n const moduleEdges = deriveModuleEdges(nodes, filteredEdges);\n\n return {\n nodes,\n edges: filteredEdges,\n modules,\n moduleEdges,\n metadata: {\n totalSymbols: symbols.length,\n totalEdges: edges.length,\n truncated,\n directory,\n moduleCount: modules.length,\n },\n };\n}\n"],"mappings":"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E,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAK,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAK,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,IAAI,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAI,CAAC,GAAG,CAAC,GAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAK,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAG,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,GAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,MAAK,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,GAAG,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,MAAK,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,KAAI,GAAG,CAAC,GAAE,CAAC,OAAM,CAAC,MAAK,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,MAAK,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,MAAK,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,MAAK,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,MAAK,IAAI,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,IAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,OAAM,CAAC,KAAK,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,GAAE,CAAC,QAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAOv0tB,SAAS,SAAS,OAAO;AAC9B,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AAEA,MAAI,SAAS,CAAC;AAEd,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,KAAK,YAAY,CAAC;AAEpC,UAAM,UAAU,YAAY,IAAI,SAAS;AAEzC,WAAO,KAAK,UAAU,OAAO,cAAc,GAAG,OAAO,IAAI,IAAI;AAAA,EAC/D;AAEA,SAAO,OAAO,KAAK,EAAE;AACvB;;;ADpBA,SAAS,mBAAmB,OAA8B;AACxD,QAAM,QAAQ,MAAM,OAAO,UAAU;AACrC,MAAI,UAAU,GAAI,QAAO;AAEzB,QAAM,YAAY,MAAM,KAAK;AAC7B,QAAM,YAAY,cAAc,UAAU,YAAY,IAClD,UAAU,YAAY,IACtB,UAAU,YAAY;AAC1B,SAAO,GAAG,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,SAAS,GAAG,MAAM,MAAM,QAAQ,CAAC,CAAC;AACtE;AAEA,SAAS,0BAA0B,WAAwC;AACzE,QAAM,gBAAgB,mBAAwB,eAAS,SAAS,CAAC;AACjE,MAAI,CAAC,cAAe,QAAO;AAE3B,MAAI;AACF,UAAM,gBAAmB,gBAAa,OAAO,SAAS;AACtD,UAAM,gBAAmB,gBAAa,OAAY,WAAU,cAAQ,SAAS,GAAG,aAAa,CAAC;AAC9F,WAAO,kBAAkB;AAAA,EAC3B,SAAS,OAAO;AACd,UAAM,OAAQ,MAAgC;AAC9C,QAAI,SAAS,YAAY,SAAS,UAAW,QAAO;AACpD,WAAO;AAAA,EACT;AACF;AAEA,SAAS,2BAA2B,kBAA+C;AACjF,QAAM,YAAiB;AAAA,IACrB;AAAA,IACA,8BAAqC,mBAAY,CAAC,EAAE,SAAS,KAAK,CAAC;AAAA,EACrE;AACA,MAAI,UAAU;AAEd,MAAI;AACF,UAAM,aAAgB,YAAS,WAAW,MAAM,GAAK;AACrD,cAAU;AACV,IAAG,aAAU,UAAU;AACvB,WAAO,0BAA0B,SAAS;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,QAAI,QAAS,CAAG,cAAW,SAAS;AAAA,EACtC;AACF;AAEA,SAAS,gCAAgC,kBAA+C;AACtF,MAAI;AACF,QAAO,YAAS,gBAAgB,EAAE,YAAY,GAAG;AAC/C,YAAM,YAAe,eAAY,gBAAgB;AACjD,UAAI;AACF,YAAI,QAAQ,UAAU,SAAS;AAC/B,eAAO,OAAO;AACZ,cAAI,CAAC,MAAM,eAAe,KAAK,mBAAmB,MAAM,IAAI,GAAG;AAC7D,kBAAM,SAAS,0BAA+B,WAAK,kBAAkB,MAAM,IAAI,CAAC;AAChF,gBAAI,WAAW,OAAW,QAAO;AAAA,UACnC;AACA,kBAAQ,UAAU,SAAS;AAAA,QAC7B;AAAA,MACF,UAAE;AACA,kBAAU,UAAU;AAAA,MACtB;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,aAAa,UAAU;AACjC,WAAO,0BAA0B,gBAAgB;AAAA,EACnD;AAEA,MAAI,QAAQ,aAAa,SAAS;AAChC,WAAO,2BAA2B,gBAAgB;AAAA,EACpD;AAEA,SAAO;AACT;AAEA,SAAS,yBAAyB,WAA2B;AAC3D,SAAO,SAAS,SAAS;AAC3B;AAEO,SAAS,8BACd,YACA,UAA0C,CAAC,GACnC;AACR,QAAM,WAAgB,cAAQ,UAAU;AACxC,QAAM,eAAyB,CAAC;AAChC,MAAI,YAAY;AAEhB,SAAO,MAAM;AACX,QAAI;AACF,YAAM,mBAAsB,gBAAa,OAAO,SAAS;AACzD,YAAM,oBAAoB,aAAa,SAAS,KAC3C,QAAQ,qBAAqB,iCAAiC,gBAAgB,IAC/E;AACJ,YAAM,SAAS,sBAAsB,OACjC,aAAa,IAAI,wBAAwB,IACzC;AACJ,aAAY,WAAK,kBAAkB,GAAG,MAAM;AAAA,IAC9C,SAAS,OAAO;AACd,YAAM,OAAQ,MAAgC;AAC9C,UAAI,SAAS,YAAY,SAAS,UAAW,OAAM;AAEnD,YAAM,SAAc,cAAQ,SAAS;AACrC,UAAI,WAAW,UAAW,QAAO;AACjC,mBAAa,QAAa,eAAS,SAAS,CAAC;AAC7C,kBAAY;AAAA,IACd;AAAA,EACF;AACF;;;AH/GA,IAAM,wCAA6C,WAAK,aAAa,qBAAqB;AAC1F,IAAM,uCAA4C,WAAK,aAAa,OAAO;AAC3E,IAAM,qBAAqB;AAC3B,IAAM,wCAA6C,WAAK,oBAAoB,aAAa;AACzF,IAAM,uCAA4C,WAAK,oBAAoB,OAAO;AAClF,IAAM,aAAa;AACnB,IAAM,sCAA2C,WAAK,YAAY,qBAAqB;AACvF,IAAM,qCAA0C,WAAK,YAAY,OAAO;AAExE,SAAS,6BAA6B,MAAwB;AAC5D,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AAEE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,4BAA4B,MAAwB;AAC3D,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AAEE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,4BAA4B,aAAqB,cAAqC;AAC7F,QAAM,eAAe,4BAA4B,WAAW;AAC5D,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,eAAoB,WAAK,cAAc,YAAY;AACzD,aAAO,uBAAW,YAAY,IAAI,eAAe;AACnD;AAUO,SAAS,+BACd,aACA,MACU;AACV,QAAM,aAAa,CAAM,WAAK,aAAa,6BAA6B,IAAI,CAAC,CAAC;AAC9E,MAAI,SAAS,YAAY;AACvB,eAAW,KAAU,WAAK,aAAa,qCAAqC,CAAC;AAAA,EAC/E;AAEA,QAAM,eAAe,4BAA4B,WAAW;AAC5D,MAAI,cAAc;AAChB,eAAW,KAAU,WAAK,cAAc,6BAA6B,IAAI,CAAC,CAAC;AAC3E,QAAI,SAAS,YAAY;AACvB,iBAAW,KAAU,WAAK,cAAc,qCAAqC,CAAC;AAAA,IAChF;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC;AAChC;AAEO,SAAS,iCACd,aACA,WACA,MACS;AACT,QAAM,eAAe,CAAC,WAAW;AACjC,QAAM,eAAe,4BAA4B,WAAW;AAC5D,MAAI,cAAc;AAChB,iBAAa,KAAK,YAAY;AAAA,EAChC;AAEA,QAAM,kBAAkB,aAAa,QAAQ,CAAC,SAAS;AACrD,UAAM,aAAa,CAAM,WAAK,MAAM,4BAA4B,IAAI,CAAC,CAAC;AACtE,QAAI,SAAS,YAAY;AACvB,iBAAW,KAAU,WAAK,MAAM,oCAAoC,CAAC;AAAA,IACvE;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,qBAAqB,8BAA8B,SAAS;AAClE,SAAO,gBAAgB;AAAA,IACrB,CAAC,cAAc,8BAA8B,SAAS,MAAM;AAAA,EAC9D;AACF;AAEA,SAAS,qBAAqB,aAAqB,MAAyB;AAC1E,aAAO,uBAAgB,WAAK,aAAa,6BAA6B,IAAI,CAAC,CAAC;AAC9E;AAEA,SAAS,oBAAoB,MAAyB;AACpD,aAAO,uBAAW,oBAAoB,IAAI,CAAC;AAC7C;AAEO,SAAS,mBAAmB,MAAwB;AACzD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAY,WAAQ,WAAQ,GAAG,aAAa,cAAc;AAAA,IAC5D,KAAK;AACH,aAAY,WAAQ,WAAQ,GAAG,WAAW,cAAc;AAAA,IAC1D;AAEE,aAAY,WAAQ,WAAQ,GAAG,mBAAmB,cAAc;AAAA,EACpE;AACF;AAEO,SAAS,oBAAoB,MAAwB;AAC1D,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAY,WAAQ,WAAQ,GAAG,WAAW,YAAY,qBAAqB;AAAA,IAC7E,KAAK;AACH,aAAY,WAAQ,WAAQ,GAAG,WAAW,qBAAqB;AAAA,IACjE;AAEE,aAAY,WAAQ,WAAQ,GAAG,WAAW,kBAAkB,aAAa;AAAA,EAC7E;AACF;AAEO,SAAS,wBAAwB,MAAwB;AAC9D,QAAM,iBAAiB,oBAAoB,IAAI;AAC/C,UAAI,uBAAW,cAAc,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,mBAAmB,oBAAoB,UAAU;AACvD,YAAI,uBAAW,gBAAgB,GAAG;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,uBAAuB,MAAwB;AAC7D,QAAM,gBAAgB,mBAAmB,IAAI;AAC7C,UAAI,uBAAW,aAAa,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY;AACvB,QAAI,oBAAoB,IAAI,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,mBAAmB,UAAU;AACrD,YAAI,uBAAW,eAAe,GAAG;AAC/B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,yBAAyB,aAAqB,MAAwB;AACpF,QAAM,aAAa,+BAA+B,aAAa,IAAI;AACnE,SAAO,WAAW,KAAK,CAAC,kBAAc,uBAAW,SAAS,CAAC,KACjD,WAAK,aAAa,6BAA6B,IAAI,CAAC;AAChE;AAMO,SAAS,wBACd,aACA,OACA,MACQ;AACR,MAAI,UAAU,UAAU;AACtB,WAAO,uBAAuB,IAAI;AAAA,EACpC;AAEA,QAAM,iBAAsB,WAAK,aAAa,4BAA4B,IAAI,CAAC;AAC/E,QAAM,eAAe,4BAA4B,WAAW;AAC5D,MAAI,cAAc;AAChB,QAAI,qBAAqB,aAAa,IAAI,GAAG;AAC3C,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,YAAY;AACvB,YAAM,wBAA6B,WAAK,aAAa,qCAAqC;AAC1F,cAAI,uBAAW,qBAAqB,GAAG;AACrC,eAAY,WAAK,aAAa,oCAAoC;AAAA,MACpE;AAEA,YAAM,qBAA0B,WAAK,cAAc,6BAA6B,IAAI,CAAC;AACrF,YAAM,oBAAyB,WAAK,cAAc,4BAA4B,IAAI,CAAC;AACnF,YAAM,uBAA4B,WAAK,cAAc,qCAAqC;AAC1F,YAAM,sBAA2B,WAAK,cAAc,oCAAoC;AACxF,UACE,KAAC,uBAAW,kBAAkB,KAC3B,KAAC,uBAAW,iBAAiB,UAC5B,uBAAW,oBAAoB,SAAK,uBAAW,mBAAmB,IACtE;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAKA,WAAY,WAAK,cAAc,4BAA4B,IAAI,CAAC;AAAA,EAClE;AAEA,UAAI,uBAAW,cAAc,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,kBAAuB,WAAK,aAAa,oCAAoC;AACnF,YAAI,uBAAW,eAAe,KAAK,CAAC,qBAAqB,aAAa,IAAI,GAAG;AAC3E,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,qBAAqB,aAAa,IAAI,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,4BAA4B,aAAa,4BAA4B,IAAI,CAAC;AAC/F,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,iBAAiB,4BAA4B,aAAa,oCAAoC;AACpG,QAAI,gBAAgB;AAClB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;AK3PA,IAAAC,QAAsB;;;ACAtB,IAAAC,QAAsB;AAEf,SAAS,wBAAwB,OAAuB;AAC7D,SAAO,MAAM,QAAQ,OAAO,GAAG;AACjC;AAEO,SAAS,oBAAoB,MAAuB;AACzD,SAAO,KAAK,WAAW,GAAG,KAAK,SAAS,OAAO,SAAS;AAC1D;AAEO,SAAS,mBAAmB,MAAuB;AACxD,SAAO,KAAK,YAAY,EAAE,SAAS,OAAO;AAC5C;;;ADPA,SAAS,aAAa,SAAiB,YAA6B;AAClE,QAAM,eAAoB,eAAS,SAAS,UAAU;AACtD,SAAO,iBAAiB,MAAO,CAAC,aAAa,WAAW,IAAI,KAAK,CAAM,iBAAW,YAAY;AAChG;AAwBO,SAAS,qCACd,QACA,YACA,YACU;AACV,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,OACJ,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,EAC5D,IAAI,CAAC,UAAU;AACd,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,QAAS,iBAAW,OAAO,GAAG;AAC5B,UAAI,aAAa,YAAY,OAAO,GAAG;AACrC,eAAO,wBAA6B,gBAAe,eAAS,YAAY,OAAO,KAAK,GAAG,CAAC;AAAA,MAC1F;AAEA,aAAY,gBAAU,OAAO;AAAA,IAC/B;AAEA,UAAM,qBAA0B,cAAQ,YAAY,OAAO;AAC3D,QAAI,aAAa,YAAY,kBAAkB,GAAG;AAChD,aAAO,wBAA6B,gBAAU,OAAO,CAAC;AAAA,IACxD;AAEA,WAAO,wBAA6B,gBAAe,eAAS,YAAY,kBAAkB,CAAC,CAAC;AAAA,EAC9F,CAAC,EACA,OAAO,OAAO;AACnB;;;AN1DA,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,mBAAmB,CAAC,kBAAkB,mBAAmB;AAI/D,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,cAAc,OAAmC;AACxD,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ;AAC/E;AAEA,SAAS,qBACP,QACA,yBACA,cACA,KACM;AACN,MAAI,OAAO,yBAAyB;AAClC,WAAO,GAAG,IAAI,wBAAwB,GAAG;AACzC;AAAA,EACF;AAEA,MAAI,OAAO,cAAc;AACvB,WAAO,GAAG,IAAI,aAAa,GAAG;AAAA,EAChC;AACF;AAEA,SAAS,uBAAuB,QAA6B;AAC3D,SAAO,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACjE;AAEA,SAAS,2BAA2B,OAAwB;AAC1D,MAAI,aAAkB,gBAAU,OAAO,KAAK,EAAE,KAAK,CAAC;AACpD,QAAM,OAAY,YAAM,UAAU,EAAE;AAEpC,SAAO,WAAW,SAAS,KAAK,UAAU,SAAS,KAAK,UAAU,GAAG;AACnE,iBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,EACrC;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,QAA6B;AAC5D,SAAO,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,2BAA2B,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC,CAAC;AAClH;AAEA,SAAS,yBAAyB,WAAoB,UAA2C;AAC/F,MAAI,CAAC,SAAS,SAAS,GAAG;AACxB,UAAM,IAAI,MAAM,eAAe,QAAQ,0CAA0C;AAAA,EACnF;AAEA,MAAI,UAAU,mBAAmB,UAAa,CAAC,cAAc,UAAU,cAAc,GAAG;AACtF,UAAM,IAAI,MAAM,eAAe,QAAQ,sDAAsD;AAAA,EAC/F;AACA,MAAI,UAAU,sBAAsB,UAAa,CAAC,cAAc,UAAU,iBAAiB,GAAG;AAC5F,UAAM,IAAI,MAAM,eAAe,QAAQ,yDAAyD;AAAA,EAClG;AACA,MAAI,UAAU,YAAY,UAAa,CAAC,cAAc,UAAU,OAAO,GAAG;AACxE,UAAM,IAAI,MAAM,eAAe,QAAQ,+CAA+C;AAAA,EACxF;AACA,MAAI,UAAU,YAAY,UAAa,CAAC,cAAc,UAAU,OAAO,GAAG;AACxE,UAAM,IAAI,MAAM,eAAe,QAAQ,+CAA+C;AAAA,EACxF;AAEA,aAAW,WAAW,CAAC,kBAAkB,YAAY,UAAU,SAAS,wBAAwB,UAAU,GAAY;AACpH,UAAM,QAAQ,UAAU,OAAO;AAC/B,QAAI,UAAU,UAAa,CAAC,SAAS,KAAK,GAAG;AAC3C,YAAM,IAAI,MAAM,eAAe,QAAQ,WAAW,OAAO,sBAAsB;AAAA,IACjF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,UAA2B;AAC/C,MAAI,KAAC,uBAAW,QAAQ,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,cAAU,yBAAa,UAAU,OAAO;AAC9C,WAAO,yBAAyB,KAAK,MAAM,OAAO,GAAG,QAAQ;AAAA,EAC/D,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,cAAc,GAAG;AACtE,YAAM;AAAA,IACR;AACA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAM,IAAI,MAAM,8BAA8B,QAAQ,KAAK,OAAO,EAAE;AAAA,EACtE;AAEF;AAEO,SAAS,eAAe,UAA2B;AACxD,SAAO,aAAa,QAAQ;AAC9B;AAEO,SAAS,uBAAuB,aAAqB,MAAyC;AACnG,QAAM,oBAAoB,yBAAyB,aAAa,IAAI;AACpE,QAAM,gBAAgB,aAAa,iBAAiB;AAEpD,MAAI,CAAC,eAAe;AAClB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,mBAA4C,EAAE,GAAG,cAAc;AACrE,QAAM,uBAA4B,cAAa,cAAQ,iBAAiB,CAAC;AAEzE,MAAI,MAAM,QAAQ,iBAAiB,cAAc,GAAG;AAClD,qBAAiB,iBAAiB;AAAA,MAChC,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAYO,SAAS,iBAAiB,aAAqB,MAAyB;AAC7E,QAAM,mBAAmB,wBAAwB,IAAI;AACrD,QAAM,oBAAoB,yBAAyB,aAAa,IAAI;AACpE,MAAI,eAA+C;AACnD,MAAI,oBAAkC;AAEtC,MAAI;AACF,mBAAe,aAAa,gBAAgB;AAAA,EAC9C,SAAS,OAAgB;AACvB,wBAAoB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,EAC9E;AAEA,QAAM,gBAAgB,aAAa,iBAAiB;AACpD,QAAM,0BAA0B,uBAAuB,aAAa,IAAI;AAExE,MAAI,mBAAmB;AACrB,QAAI,CAAC,eAAe;AAClB,YAAM;AAAA,IACR;AACA,mBAAe;AAAA,EACjB;AAEA,MAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,CAAC,iBAAiB,cAAc;AAClC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,gBAAgB,eAAe;AAClC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,WAAO,gBAAgB;AAAA,EACzB;AAGA,QAAM,SAAkC,EAAE,GAAG,aAAa;AAE1D,aAAW,OAAO,uBAAuB;AACvC,yBAAqB,QAAQ,yBAAyB,cAAc,GAAG;AAAA,EACzE;AAGA,MAAI,eAAe;AACjB,eAAW,OAAO,OAAO,KAAK,aAAa,GAAG;AAC5C,UACE,sBAAsB,SAAS,GAAyB,KACxD,iBAAiB,SAAS,GAAwC,GAClE;AACA;AAAA,MACF;AACA,aAAO,GAAG,IAAI,wBAAwB,GAAG;AAAA,IAC3C;AAAA,EACF;AAGA,QAAM,YAAY,gBAAgB,MAAM,QAAQ,aAAa,cAAc,IAAI,aAAa,iBAAiB,CAAC;AAC9G,QAAM,aAAa,gBACd,MAAM,QAAQ,wBAAwB,cAAc,IAAI,wBAAwB,iBAA6B,CAAC,IAC/G,CAAC;AACL,QAAM,SAAS,CAAC,GAAG,WAAW,GAAG,UAAU;AAC3C,SAAO,iBAAiB,wBAAwB,MAAM;AAGtD,QAAM,mBAAmB,gBAAgB,MAAM,QAAQ,aAAa,iBAAiB,IAAI,aAAa,oBAAoB,CAAC;AAC3H,QAAM,oBAAoB,iBAAiB,MAAM,QAAQ,cAAc,iBAAiB,IAAI,cAAc,oBAAoB,CAAC;AAC/H,QAAM,gBAAgB,CAAC,GAAG,kBAAkB,GAAG,iBAAiB;AAChE,SAAO,oBAAoB,uBAAuB,aAAa;AAE/D,SAAO;AACT;;;AQ/NO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA;AAAA,IAER,sBAAsB;AAAA,MACpB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,UAAU;AAAA;AAAA,IAEZ;AAAA,IACA,wBAAwB;AAAA,MACtB,UAAU;AAAA,MACV,OAAO;AAAA;AAAA;AAAA;AAAA,MAIP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,UAAU;AAAA,IACZ;AAAA,IACA,sBAAsB;AAAA,MACpB,UAAU;AAAA,MACV,OAAO;AAAA;AAAA;AAAA,MAGP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,UAAU;AAAA,MACV,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,0BAA0B;AAAA,MACxB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,IACnB;AAAA,IACA,0BAA0B;AAAA,MACxB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,oBAAoB;AAAA,MAClB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,IACnB;AAAA,IACA,qBAAqB;AAAA,MACnB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF;AAEO,IAAM,0BAA0B;AAAA,EACrC,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AACZ;AAEO,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACF;;;AC7GO,SAAS,2BAA2C;AACzD,SAAO;AAAA,IACL,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,YAAY;AAAA,IACZ,kCAAkC;AAAA,IAClC,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,SAAS;AAAA,IACT,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,UAAU;AAAA,IACV,sBAAsB;AAAA,IACtB,2BAA2B;AAAA;AAAA;AAAA,IAG3B,eAAe;AAAA,IACf,UAAU,EAAE,SAAS,MAAM;AAAA,EAC7B;AACF;AAEO,SAAS,yBAAuC;AACrD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,cAAc;AAAA,IACd,0BAA0B;AAAA,IAC1B,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EAClB;AACF;AAEO,SAAS,0BAA0B,UAAoC;AAC5E,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,wBAAqC;AACnD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU;AAAA,IACV,WAAW;AAAA,IACX,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF;;;ACzEA,IAAM,wBAAwB;AAC9B,IAAM,6BAA6B;AAE5B,SAAS,oBAAoB,OAAe,SAAyB;AAC1E,QAAM,QAAQ,MAAM,MAAM,qBAAqB;AAE/C,MAAI,CAAC,OAAO;AACV,QAAI,2BAA2B,KAAK,KAAK,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR,8CAA8C,OAAO;AAAA,MAEvD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM,CAAC;AAC5B,QAAM,WAAW,QAAQ,IAAI,YAAY;AAEzC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,MAAM,iCAAiC,YAAY,8BAA8B,OAAO,IAAI;AAAA,EACxG;AAEA,SAAO;AACT;;;ACbA,IAAM,eAA6B,CAAC,WAAW,QAAQ;AACvD,IAAM,mBAA+B,CAAC,SAAS,QAAQ,QAAQ,OAAO;AAE/D,SAAS,sBAAsB,OAAyD;AAC7F,SAAO,UAAU,cAAc,UAAU;AAC3C;AAEO,SAAS,wBAAwB,OAA2C;AACjF,SAAO,UAAU,YAAY,UAAU,UAAU,UAAU;AAC7D;AAEO,SAAS,gBAAgB,OAA4C;AAC1E,SAAO,OAAO,UAAU,YAAY,OAAO,KAAK,gBAAgB,EAAE,SAAS,KAAK;AAClF;AAEO,SAAS,aACd,OACA,UAC4B;AAG5B,MAAI,OAAO,UAAU,YAAY,aAAa,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACjF,WAAO;AAAA,EACT;AACA,SAAO,OAAO,UAAU,YAAY,OAAO,KAAK,iBAAiB,QAAQ,CAAC,EAAE,SAAS,KAAK;AAC5F;AAEO,SAAS,aAAa,OAAqC;AAChE,SAAO,OAAO,UAAU,YAAY,aAAa,SAAS,KAAmB;AAC/E;AAEO,SAASC,eAAc,OAAmC;AAC/D,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,UAAQ,OAAO,SAAS,QAAQ;AAC7E;AAEO,SAAS,kBAAkB,OAAgB,SAAqC;AACrF,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,OAAO,OAAO;AAC3C;AAEO,SAAS,uBAAuB,OAAgB,SAAuC;AAC5F,MAAI,CAACA,eAAc,KAAK,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,IAAI,CAAC,MAAM,UAAU,oBAAoB,MAAM,GAAG,OAAO,IAAI,KAAK,GAAG,CAAC;AACrF;AAEO,SAAS,gBAAgB,OAAmC;AACjE,SAAO,OAAO,UAAU,YAAY,iBAAiB,SAAS,KAAiB;AACjF;;;ACiJO,SAAS,YAAY,KAAyC;AACnE,QAAM,QAAS,OAAO,OAAO,QAAQ,WAAW,MAAM,CAAC;AACvD,QAAM,yBAAyB,kBAAkB,MAAM,mBAAmB,yBAAyB;AACnG,QAAM,aAAa,kBAAkB,MAAM,OAAO,aAAa;AAC/D,QAAM,eAAe,uBAAuB,MAAM,SAAS,eAAe;AAC1E,QAAM,eAAe,uBAAuB,MAAM,SAAS,eAAe;AAE1E,QAAM,kBAAkB,yBAAyB;AACjD,QAAMC,iBAAgB,uBAAuB;AAC7C,QAAM,eAAe,sBAAsB;AAE3C,QAAM,cAAe,MAAM,YAAY,OAAO,MAAM,aAAa,WAAW,MAAM,WAAW,CAAC;AAC9F,QAAM,WAA2B;AAAA,IAC/B,WAAW,OAAO,YAAY,cAAc,YAAY,YAAY,YAAY,gBAAgB;AAAA,IAChG,iBAAiB,OAAO,YAAY,oBAAoB,WACpD,KAAK,IAAI,KAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,eAAe,CAAC,CAAC,IACrE,gBAAgB;AAAA,IACpB,qBAAqB,OAAO,YAAY,wBAAwB,WAC5D,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,mBAAmB,CAAC,CAAC,IACrE,gBAAgB;AAAA,IACpB,uBAAuB,OAAO,YAAY,0BAA0B,WAChE,KAAK,IAAI,KAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,YAAY,qBAAqB,CAAC,CAAC,IAC5E,gBAAgB;AAAA,IACpB,YAAY,OAAO,YAAY,eAAe,YAAY,YAAY,aAAa,gBAAgB;AAAA,IACnG,kCAAkC,OAAO,YAAY,qCAAqC,YACtF,YAAY,mCACZ,gBAAgB;AAAA,IACpB,aAAa,OAAO,YAAY,gBAAgB,WAAW,YAAY,cAAc,gBAAgB;AAAA,IACrG,kBAAkB,OAAO,YAAY,qBAAqB,WAAW,KAAK,IAAI,GAAG,YAAY,gBAAgB,IAAI,gBAAgB;AAAA,IACjI,cAAc,OAAO,YAAY,iBAAiB,YAAY,YAAY,eAAe,gBAAgB;AAAA,IACzG,SAAS,OAAO,YAAY,YAAY,WAAW,YAAY,UAAU,gBAAgB;AAAA,IACzF,cAAc,OAAO,YAAY,iBAAiB,WAAW,YAAY,eAAe,gBAAgB;AAAA,IACxG,QAAQ,OAAO,YAAY,WAAW,YAAY,YAAY,SAAS,gBAAgB;AAAA,IACvF,gBAAgB,OAAO,YAAY,mBAAmB,WAAW,KAAK,IAAI,GAAG,YAAY,cAAc,IAAI,gBAAgB;AAAA,IAC3H,mBAAmB,OAAO,YAAY,sBAAsB,WAAW,KAAK,IAAI,GAAG,YAAY,iBAAiB,IAAI,gBAAgB;AAAA,IACpI,sBAAsB,OAAO,YAAY,yBAAyB,YAAY,YAAY,uBAAuB,gBAAgB;AAAA,IACjI,UAAU,OAAO,YAAY,aAAa,WAAY,YAAY,WAAW,KAAK,KAAK,YAAY,WAAY,gBAAgB;AAAA,IAC/H,sBAAsB,OAAO,YAAY,yBAAyB,WAAW,KAAK,IAAI,GAAG,YAAY,oBAAoB,IAAI,gBAAgB;AAAA,IAC7I,2BAA2B,OAAO,YAAY,8BAA8B,YAAY,YAAY,4BAA4B,gBAAgB;AAAA,IAChJ,eAAe,OAAO,YAAY,kBAAkB,YAAY,OAAO,SAAS,YAAY,aAAa,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,aAAa,CAAC,GAAG,UAAU,IAAI,gBAAgB;AAAA,IACxM,UAAU;AAAA,MACR,SAAS,YAAY,YAAY,OAAO,YAAY,aAAa,YAAY,OAAQ,YAAY,SAAqC,YAAY,YAC7I,YAAY,SAAkC,UAC/C,gBAAgB,SAAS;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,YAAa,MAAM,UAAU,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS,CAAC;AACtF,QAAM,SAAuB;AAAA,IAC3B,YAAY,OAAO,UAAU,eAAe,WAAW,UAAU,aAAaA,eAAc;AAAA,IAC5F,UAAU,OAAO,UAAU,aAAa,WAAW,UAAU,WAAWA,eAAc;AAAA,IACtF,gBAAgB,OAAO,UAAU,mBAAmB,YAAY,UAAU,iBAAiBA,eAAc;AAAA,IACzG,cAAc,OAAO,UAAU,iBAAiB,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,YAAY,CAAC,IAAIA,eAAc;AAAA,IAC5H,gBAAgB,sBAAsB,UAAU,cAAc,IAAI,UAAU,iBAAiBA,eAAc;AAAA,IAC3G,MAAM,OAAO,UAAU,SAAS,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,IAAI,CAAC,IAAIA,eAAc;AAAA,IACnG,YAAY,OAAO,UAAU,eAAe,WAAW,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,UAAU,CAAC,CAAC,IAAIA,eAAc;AAAA,IACpI,cAAc,OAAO,UAAU,iBAAiB,WAAW,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,UAAU,YAAY,CAAC,IAAIA,eAAc;AAAA,IAC7H,cAAc,OAAO,UAAU,iBAAiB,YAAY,UAAU,eAAeA,eAAc;AAAA,IACnG,0BAA0B,OAAO,UAAU,6BAA6B,YAAY,UAAU,2BAA2BA,eAAc;AAAA,IACvI,iBAAiB,UAAU,oBAAoB,eAAe,UAAU,oBAAoB,WACxF,UAAU,kBACVA,eAAc;AAAA,IAClB,gBAAgB,OAAO,UAAU,mBAAmB,YAAY,OAAO,SAAS,UAAU,cAAc,IACpG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,cAAc,CAAC,IACjDA,eAAc;AAAA,EACpB;AAEA,QAAM,WAAY,MAAM,SAAS,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,CAAC;AAClF,QAAM,QAAqB;AAAA,IACzB,SAAS,OAAO,SAAS,YAAY,YAAY,SAAS,UAAU,aAAa;AAAA,IACjF,UAAU,gBAAgB,SAAS,QAAQ,IAAI,SAAS,WAAW,aAAa;AAAA,IAChF,WAAW,OAAO,SAAS,cAAc,YAAY,SAAS,YAAY,aAAa;AAAA,IACvF,cAAc,OAAO,SAAS,iBAAiB,YAAY,SAAS,eAAe,aAAa;AAAA,IAChG,UAAU,OAAO,SAAS,aAAa,YAAY,SAAS,WAAW,aAAa;AAAA,IACpF,OAAO,OAAO,SAAS,UAAU,YAAY,SAAS,QAAQ,aAAa;AAAA,IAC3E,WAAW,OAAO,SAAS,cAAc,YAAY,SAAS,YAAY,aAAa;AAAA,IACvF,SAAS,OAAO,SAAS,YAAY,YAAY,SAAS,UAAU,aAAa;AAAA,EACnF;AAEA,QAAM,0BACJ,MAAM,wBAAwB,OAAO,MAAM,yBAAyB,WAChE,MAAM,uBACN,CAAC;AAEP,QAAM,uBAAmD;AAAA,IACvD,SAAS,wBAAwB,YAAY;AAAA,EAC/C;AAEA,QAAM,oBAAoB,MAAM;AAChC,QAAM,iBAA2BC,eAAc,iBAAiB,IAC5D,kBAAkB,OAAO,OAAK,OAAO,MAAM,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,IAC7F,CAAC;AAEL,QAAM,uBAAuB,MAAM;AACnC,QAAM,oBAA8BA,eAAc,oBAAoB,IAClE,qBACC,OAAO,OAAK,OAAO,MAAM,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,EACxD,IAAI,OAAK,EAAE,KAAK,CAAC,IAClB,CAAC;AAEL,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,QAAM,kCACJ;AAKF,MAAI,2BAA2B,UAAU;AACvC,wBAAoB;AACpB,UAAM,YAAa,MAAM,kBAAkB,OAAO,MAAM,mBAAmB,WAAW,MAAM,iBAAiB;AAC7G,UAAM,eAAe,kBAAkB,WAAW,SAAS,8BAA8B;AACzF,UAAM,aAAa,kBAAkB,WAAW,OAAO,4BAA4B;AACnF,UAAM,cAAc,kBAAkB,WAAW,QAAQ,6BAA6B;AACtF,QAAI,aAAa,OAAO,iBAAiB,YAAY,aAAa,KAAK,EAAE,SAAS,KAAK,OAAO,eAAe,YAAY,WAAW,KAAK,EAAE,SAAS,KAAK,OAAO,UAAU,eAAe,YAAY,OAAO,UAAU,UAAU,UAAU,KAAK,UAAU,aAAa,GAAG;AACvQ,uBAAiB;AAAA,QACf,SAAS,aAAa,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAAA,QAC/C,OAAO;AAAA,QACP,YAAY,UAAU;AAAA,QACtB,QAAQ;AAAA,QACR,WAAW,OAAO,UAAU,cAAc,WAAW,UAAU,YAAY;AAAA,QAC3E,WAAW,OAAO,UAAU,cAAc,WAAW,KAAK,IAAI,KAAM,UAAU,SAAS,IAAI;AAAA,QAC3F,aAAa,OAAO,UAAU,gBAAgB,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,WAAW,CAAC,IAAI;AAAA,QAC1G,mBAAmB,OAAO,UAAU,sBAAsB,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,iBAAiB,CAAC,IAAI;AAAA,QAC5H,cAAc,OAAO,UAAU,iBAAiB,WAC5C,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,YAAY,CAAC,IAC9C,OAAO,UAAU,mBAAmB,WAClC,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,cAAc,CAAC,IAChD;AAAA,MACR;AAGA,UAAI,CAAC,aAAa,KAAK,eAAe,OAAO,GAAG;AAC9C,gBAAQ;AAAA,UACN,sDAAsD,eAAe,OAAO,6HACF,eAAe,OAAO,0EACpC,eAAe,OAAO;AAAA,QACpF;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAAA,EACF,WAAW,gBAAgB,sBAAsB,GAAG;AAClD,wBAAoB;AACpB,UAAM,oBAAoB,MAAM;AAChC,QAAI,OAAO,sBAAsB,UAAU;AACzC,YAAM,sBAAsB,kBAAkB,mBAAmB,sBAAsB;AACvF,UAAI,qBAAqB;AACvB,yBAAiB,aAAa,qBAAqB,iBAAiB,IAAI,sBAAsB,wBAAwB,iBAAiB;AAAA,MACzI;AAAA,IACF,WAAW,mBAAmB;AAC5B,uBAAiB,wBAAwB,iBAAiB;AAAA,IAC5D;AAAA,EACF,WAAW,2BAA2B,kBAAkB;AACtD,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD,OAAO;AACL,wBAAoB;AAAA,EACtB;AAEA,QAAM,cAAe,MAAM,YAAY,OAAO,MAAM,aAAa,WAC7D,MAAM,WACN,CAAC;AACL,QAAM,kBAAkB,OAAO,YAAY,YAAY,YAAY,YAAY,UAAU;AACzF,MAAI,iBAAiB;AACnB,UAAM,WAAW,wBAAwB,YAAY,QAAQ,IAAI,YAAY,WAAW;AACxF,UAAM,QAAQ,kBAAkB,YAAY,OAAO,sBAAsB;AACzE,QAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,GAAG;AACvC,YAAM,IAAI,MAAM,+DAA+D;AAAA,IACjF;AAEA,UAAM,oBAAoB,kBAAkB,YAAY,SAAS,wBAAwB;AACzF,UAAM,UAAU,mBAAmB,KAAK,KAAK,0BAA0B,QAAQ;AAC/E,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,IAAI,MAAM,uFAAuF;AAAA,IACzG;AAEA,UAAM,SAAS,kBAAkB,YAAY,QAAQ,uBAAuB;AAC5E,SAAK,aAAa,YAAY,aAAa,YAAY,CAAC,UAAU,OAAO,KAAK,EAAE,WAAW,IAAI;AAC7F,YAAM,IAAI,MAAM,sBAAsB,QAAQ,0CAA0C;AAAA,IAC1F;AAEA,eAAW;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA,OAAO,MAAM,KAAK;AAAA,MAClB,SAAS,QAAQ,QAAQ,QAAQ,EAAE;AAAA,MACnC,QAAQ,QAAQ,KAAK,KAAK;AAAA,MAC1B,MAAM,OAAO,YAAY,SAAS,WAAW,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,IAAI,CAAC,CAAC,IAAI;AAAA,MACvG,WAAW,OAAO,YAAY,cAAc,WAAW,KAAK,IAAI,KAAM,KAAK,MAAM,YAAY,SAAS,CAAC,IAAI;AAAA,IAC7G;AAAA,EACF;AAEA,QAAM,eAAgB,MAAM,aAAa,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY,CAAC;AAClG,QAAM,oBAAqB,aAAa,SAAS,OAAO,aAAa,UAAU,WAAW,aAAa,QAAQ;AAC/G,QAAM,yBAAyB,OAAO,mBAAmB,kBAAkB,YACtE,OAAO,SAAS,kBAAkB,aAAa,IAChD,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,aAAa,CAAC,IACvD;AACJ,QAAM,0BAA0B,OAAO,mBAAmB,mBAAmB,YACxE,OAAO,SAAS,kBAAkB,cAAc,IACjD,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,cAAc,CAAC,IACxD;AACJ,QAAM,YAA8B,2BAA2B,UAAa,4BAA4B,SACpG;AAAA,IACE,OAAO;AAAA,MACL,GAAI,2BAA2B,SAAY,EAAE,eAAe,uBAAuB,IAAI,CAAC;AAAA,MACxF,GAAI,4BAA4B,SAAY,EAAE,gBAAgB,wBAAwB,IAAI,CAAC;AAAA,IAC7F;AAAA,EACF,IACA,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,aAAa,UAAU,IAAI,aAAa;AAAA,IAC/C,SAAS,gBAAgB;AAAA,IACzB,SAAS,gBAAgB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,2BAA2B,UAAiD;AAC1F,QAAM,SAAS,iBAAiB,QAAQ;AACxC,QAAM,kBAAkB,wBAAwB,QAAQ;AACxD,SAAO,OAAO,eAAsC;AACtD;AAUO,IAAM,qBAA0C,OAAO,KAAK,gBAAgB;AAE5E,IAAM,sBAA2C,2BAA2B;AAAA,EACjF,CAAC,aAA4C,YAAY;AAC3D;;;AC/cA,IAAAC,cAAmD;AACnD,IAAAC,SAAsB;;;ACDtB,IAAAC,QAAsB;AAIf,SAAS,uBAAuB,OAAe,SAAyB;AAC7E,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,eAAoB,iBAAW,OAAO,IAAI,UAAe,cAAQ,SAAS,OAAO;AACvF,SAAY,gBAAU,YAAY;AACpC;;;ACVA,sBAA6B;;;ACoB7B,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EAAK;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAM;AAAA,EAClE;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EACrE;AAAA,EAAU;AAAA,EAAW;AAAA,EAAY;AAAA,EAAO;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EACzE;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EACrE;AAAA,EAAO;AAAA,EAAO;AAChB,CAAC;AAED,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EAAa;AAAA,EAAc;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EAC1E;AAAA,EAAW;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAiB;AAAA,EAAe;AAAA,EACvE;AAAA,EAAc;AAAA,EAAc;AAAA,EAAQ;AAAA,EAAiB;AAAA,EAAW;AAAA,EAAY;AAAA,EAC5E;AAAA,EAAY;AAAA,EAAY;AAAA,EAAS;AAAA,EAAa;AAAA,EAAkB;AAAA,EAAe;AAAA,EAC/E;AAAA,EAAW;AAAA,EAAS;AAAA,EAAY;AAAA,EAAU;AAAA,EAAU;AAAA,EAAa;AAAA,EAAc;AAAA,EAC/E;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAS;AACxD,CAAC;AAED,IAAM,4BAA4B,oBAAI,IAAI;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,6BAA6B,oBAAI,IAAI;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,mBAAmB,oBAAI,IAAI,CAAC,QAAQ,kBAAkB,CAAC;AAE7D,IAAM,iCAAiC,oBAAI,IAAI;AAAA,EAC7C;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAK;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EACzE;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAK;AAAA,EACnE;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAS;AAAA,EAAM;AAAA,EAAS;AAAA,EAAW;AAAA,EAC1E;AAAA,EAAO;AAAA,EAAO;AAChB,CAAC;AAED,SAAS,cAAc,UAA0B;AAC/C,SAAO,qBAAqB,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAC1D;AAEO,SAAS,qBAAqB,OAAuB;AAC1D,SAAO,MAAM,UAAU,MAAM,EAAE,YAAY;AAC7C;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,qBAAqB,KAAK,EAAE,QAAQ,qBAAqB,EAAE;AACpE;AAEA,SAAS,iBAAiB,OAAyB;AACjD,QAAM,aAAa,MAChB,UAAU,MAAM,EAChB,QAAQ,+BAA+B,OAAO,EAC9C,QAAQ,qBAAqB,GAAG,EAChC,YAAY;AACf,SAAO,WAAW,MAAM,KAAK,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACnE;AAEA,SAAS,WAAW,OAAyB;AAC3C,SAAO,MAAM,UAAU,MAAM,EAAE,MAAM,6BAA6B,KAAK,CAAC;AAC1E;AAEA,SAAS,aAAa,OAAwB;AAC5C,SAAO,QAAQ,KAAK,KAAK,KAAK,yBAAyB,KAAK,KAAK;AACnE;AAEO,SAAS,6BAA6B,OAAyB;AACpE,QAAM,SAAS,MAAM,KAAK,MAAM,SAAS,yCAAyC,CAAC,EAChF,IAAI,CAAC,UAAU,MAAM,CAAC,CAAC;AAC1B,QAAM,QAAQ,WAAW,KAAK;AAC9B,QAAM,kBAAkB,MAAM,IAAI,CAAC,SAAS,qBAAqB,IAAI,CAAC;AACtE,QAAM,eAAe,MAAM,OAAO,CAAC,OAAO,UAAU;AAClD,UAAM,aAAa,gBAAgB,KAAK,KAAK;AAC7C,WAAO,WAAW,UAAU,KAAK,CAAC,UAAU,IAAI,UAAU,KAAK,CAAC,aAAa,IAAI,UAAU;AAAA,EAC7F,CAAC;AAED,QAAM,uBAAuB,aAAa,OAAO,YAAY;AAC7D,QAAM,uBAAuB,6EAA6E,KAAK,KAAK,KAClH,mBAAmB,KAAK,KAAK;AAC/B,QAAM,oBAAoB,aAAa,WAAW,IAAI,eAAe,CAAC;AACtE,QAAM,sBAAsB,uBAAuB,aAAa,MAAM,GAAG,CAAC,IAAI,CAAC;AAC/E,QAAM,aAAa,CAAC,GAAG,QAAQ,GAAG,sBAAsB,GAAG,mBAAmB,GAAG,mBAAmB;AAEpG,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,QAAkB,CAAC;AACzB,aAAW,aAAa,YAAY;AAClC,UAAM,aAAa,qBAAqB,SAAS;AACjD,QAAI,WAAW,SAAS,KAAK,KAAK,IAAI,UAAU,EAAG;AACnD,SAAK,IAAI,UAAU;AACnB,UAAM,KAAK,UAAU;AAAA,EACvB;AACA,SAAO,MAAM,MAAM,GAAG,CAAC;AACzB;AAEO,SAAS,mBAAmB,OAAmC;AACpE,QAAM,aAAa,qBAAqB,KAAK;AAC7C,QAAM,kBAAkB,6BAA6B,KAAK;AAC1D,QAAM,oBAAoB,gBAAgB,CAAC;AAC3C,QAAM,aAAa,wDAAwD,KAAK,UAAU;AAC1F,QAAM,aAAa,8DAA8D,KAAK,UAAU;AAChG,QAAM,eAAe,oFAAoF,KAAK,UAAU;AACxH,QAAM,iBAAiB,0HAA0H,KAAK,UAAU,KAC9J,mBAAmB,KAAK,UAAU;AACpC,QAAM,mBAAmB,iDAAiD,KAAK,UAAU,KACvF,kBAAkB,KAAK,UAAU;AACnC,QAAM,uBAAuB,6EAA6E,KAAK,UAAU;AACzH,QAAM,aAAa,gBAAgB,WAAW,KAAK,WAAW,KAAK,EAAE,OAAO,CAAC,SAAS;AACpF,UAAM,iBAAiB,qBAAqB,IAAI;AAChD,WAAO,CAAC,UAAU,IAAI,cAAc,KAAK,CAAC,aAAa,IAAI,cAAc;AAAA,EAC3E,CAAC,EAAE,UAAU;AAEb,MAAI;AACJ,MAAI,WAAY,WAAU;AAAA,WACjB,WAAY,WAAU;AAAA,WACtB,aAAc,WAAU;AAAA,WACxB,eAAgB,WAAU;AAAA,WAC1B,iBAAkB,WAAU;AAAA,WAC5B,qBAAsB,WAAU;AAAA,WAChC,WAAY,WAAU;AAAA,MAC1B,WAAU;AAEf,QAAM,yBAAyB,YAAY,UAAU,YAAY,UAAU,YAAY,YAAY,YAAY;AAC/G,QAAM,oBAAoB,YAAY,gBAAgB,YAAY,oBAAoB,YAAY,eAC/F,YAAY,aAAa,gBAAgB,SAAS;AAErD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,WAAW,UAA2B;AACpD,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO,uDAAuD,KAAK,UAAU,KAC3E,8CAA8C,KAAK,UAAU,KAC7D,uCAAuC,KAAK,UAAU;AAC1D;AAEO,SAAS,cAAc,UAA2B;AACvD,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO,4DAA4D,KAAK,UAAU,KAAK,WAAW,SAAS,OAAO;AACpH;AAEO,SAAS,oBAAoB,UAA2B;AAC7D,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO,yBAAyB,KAAK,UAAU,KAAK,0BAA0B,KAAK,UAAU,KAC3F,8BAA8B,KAAK,UAAU;AACjD;AAEO,SAAS,wBAAwB,UAA2B;AACjE,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO,+FAA+F,KAAK,UAAU,KACnH,8GAA8G,KAAK,UAAU;AACjI;AAEO,SAAS,aAAa,UAA2B;AACtD,QAAM,aAAa,cAAc,QAAQ;AACzC,QAAM,WAAW,WAAW,MAAM,GAAG,EAAE,IAAI,KAAK;AAChD,SAAO,+CAA+C,KAAK,UAAU,KACnE,sFAAsF,KAAK,QAAQ,KACnG,0CAA0C,KAAK,QAAQ,KACvD,4BAA4B,KAAK,QAAQ;AAC7C;AAEO,SAAS,yBAAyB,WAA4B;AACnE,SAAO,0BAA0B,IAAI,qBAAqB,SAAS,CAAC;AACtE;AAEO,SAAS,kBAAkB,WAA4B;AAC5D,SAAO,mBAAmB,IAAI,qBAAqB,SAAS,CAAC;AAC/D;AAEA,SAAS,gBAAgB,UAAkC;AACzD,QAAM,YAAY,qBAAqB,SAAS,SAAS;AACzD,QAAM,WAAW,KAAK,IAAI,GAAG,SAAS,UAAU,SAAS,YAAY,CAAC;AACtE,MAAI,cAAc,mBAAoB,QAAO;AAC7C,SAAO,2BAA2B,IAAI,SAAS,MAAM,YAAY,KAAK,CAAC,SAAS;AAClF;AAEO,SAAS,2BAA2B,UAA2B;AACpE,MAAI,WAAW,QAAQ,KAAK,cAAc,QAAQ,KAAK,oBAAoB,QAAQ,KAAK,wBAAwB,QAAQ,GAAG;AACzH,WAAO;AAAA,EACT;AACA,MAAI,CAAC,aAAa,QAAQ,EAAG,QAAO;AACpC,QAAM,YAAY,cAAc,QAAQ,EAAE,MAAM,GAAG,EAAE,IAAI,KAAK;AAC9D,SAAO,+BAA+B,IAAI,SAAS;AACrD;AAEA,SAAS,kBAAkB,MAA0B,OAAyB;AAC5E,MAAI,CAAC,QAAQ,MAAM,WAAW,EAAG,QAAO;AACxC,QAAM,iBAAiB,qBAAqB,IAAI;AAChD,QAAM,cAAc,kBAAkB,IAAI;AAC1C,QAAM,aAAa,IAAI,IAAI,iBAAiB,IAAI,CAAC;AACjD,MAAI,OAAO;AAEX,aAAW,QAAQ,OAAO;AACxB,UAAM,iBAAiB,qBAAqB,IAAI;AAChD,UAAM,cAAc,kBAAkB,IAAI;AAC1C,QAAI,mBAAmB,gBAAgB;AACrC,aAAO,KAAK,IAAI,MAAM,CAAC;AAAA,IACzB,WAAW,YAAY,SAAS,KAAK,gBAAgB,aAAa;AAChE,aAAO,KAAK,IAAI,MAAM,GAAG;AAAA,IAC3B,WAAW,eAAe,WAAW,cAAc,KAAK,eAAe,WAAW,cAAc,GAAG;AACjG,aAAO,KAAK,IAAI,MAAM,GAAG;AAAA,IAC3B,WAAW,eAAe,SAAS,cAAc,GAAG;AAClD,aAAO,KAAK,IAAI,MAAM,GAAG;AAAA,IAC3B,OAAO;AACL,YAAM,aAAa,iBAAiB,IAAI;AACxC,UAAI,WAAW,SAAS,KAAK,WAAW,MAAM,CAAC,UAAU,WAAW,IAAI,KAAK,CAAC,GAAG;AAC/E,eAAO,KAAK,IAAI,MAAM,CAAC;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,OAAe,UAAiC;AACpE,QAAM,cAAc,IAAI,IAAI,WAAW,KAAK,EAAE,QAAQ,gBAAgB,EAAE,OAAO,CAAC,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;AAChH,MAAI,YAAY,SAAS,EAAG,QAAO;AACnC,QAAM,kBAAkB,oBAAI,IAAI;AAAA,IAC9B,GAAG,iBAAiB,SAAS,QAAQ,EAAE;AAAA,IACvC,GAAG,iBAAiB,SAAS,SAAS;AAAA,IACtC,GAAG,iBAAiB,cAAc,SAAS,QAAQ,EAAE,MAAM,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,EACrF,CAAC;AACD,MAAI,OAAO;AACX,aAAW,SAAS,aAAa;AAC/B,QAAI,gBAAgB,IAAI,KAAK,EAAG,SAAQ;AAAA,EAC1C;AACA,SAAO,OAAO,YAAY;AAC5B;AAEA,SAAS,iBAAiB,UAAiC;AACzD,QAAM,SAAS,oBAAI,IAAI;AAAA,IACrB,GAAG,iBAAiB,SAAS,QAAQ,EAAE;AAAA,IACvC,GAAG,iBAAiB,cAAc,SAAS,QAAQ,CAAC;AAAA,EACtD,CAAC;AACD,SAAO,CAAC,QAAQ,UAAU,UAAU,SAAS,aAAa,cAAc,QAAQ,MAAM,EACnF,OAAO,CAAC,UAAU,OAAO,IAAI,KAAK,CAAC,EAAE;AAC1C;AASA,SAAS,eAAe,OAAe,QAA4B,WAA4B,eAAwC;AACrI,QAAM,WAAW,UAAU;AAC3B,QAAM,YAAY,kBAAkB,SAAS,MAAM,OAAO,eAAe;AACzE,QAAM,gBAAgB,yBAAyB,SAAS,SAAS;AACjE,QAAM,cAAc,kBAAkB,SAAS,SAAS;AACxD,QAAM,gBAAgB,gBAAgB,QAAQ;AAC9C,QAAM,WAAW,WAAW,SAAS,QAAQ,KAAK,iBAAiB,IAAI,qBAAqB,SAAS,SAAS,CAAC;AAC/G,QAAM,cAAc,cAAc,SAAS,QAAQ;AACnD,QAAM,WAAW,oBAAoB,SAAS,QAAQ;AACtD,QAAM,oBAAoB,wBAAwB,SAAS,QAAQ;AACnE,QAAM,aAAa,aAAa,SAAS,QAAQ;AACjD,QAAM,qBAAqB,2BAA2B,SAAS,QAAQ;AACvE,QAAM,UAAU,aAAa,OAAO,QAAQ;AAC5C,MAAI,QAAQ;AAEZ,MAAI,OAAO,YAAY,cAAc;AACnC,aAAS,KAAK,IAAI,MAAM,UAAU,IAAI;AACtC,QAAI,OAAO,mBAAmB;AAC5B,eAAS,qBAAqB,OAAO;AACrC,UAAI,YAAY,eAAe,SAAU,UAAS;AAAA,IACpD;AACA,QAAI,kBAAmB,UAAS;AAChC,QAAI,eAAe,cAAe,UAAS;AAAA,EAC7C,WAAW,OAAO,YAAY,QAAQ;AACpC,aAAS,WAAW,OAAO;AAC3B,aAAS,cAAc,MAAM;AAC7B,aAAS,6BAA6B,KAAK,qBAAqB,SAAS,QAAQ,EAAE,CAAC,IAAI,OAAO;AAC/F,aAAS,YAAY;AACrB,QAAI,SAAU,UAAS;AACvB,QAAI,kBAAmB,UAAS;AAAA,EAClC,WAAW,OAAO,YAAY,QAAQ;AACpC,aAAS,WAAW,OAAO;AAC3B,aAAS,cAAc,SAAS,QAAQ,EAAE,SAAS,QAAQ,IAAI,OAAO;AACtE,aAAS,YAAY;AACrB,QAAI,YAAY,YAAa,UAAS;AACtC,QAAI,kBAAmB,UAAS;AAAA,EAClC,WAAW,OAAO,YAAY,UAAU;AACtC,aAAS,aAAa,MAAM;AAC5B,aAAS,YAAY;AACrB,aAAS,KAAK,IAAI,KAAK,UAAU,GAAG;AACpC,QAAI,YAAY,eAAe,SAAU,UAAS;AAClD,QAAI,kBAAmB,UAAS;AAAA,EAClC,WAAW,OAAO,YAAY,aAAa;AACzC,aAAS,KAAK,IAAI,KAAK,iBAAiB,QAAQ,IAAI,IAAI;AACxD,aAAS,iBAAiB,qBAAqB,MAAM;AACrD,aAAS,YAAY;AACrB,QAAI,YAAY,eAAe,SAAU,UAAS;AAClD,QAAI,eAAe,cAAe,UAAS;AAC3C,QAAI,kBAAmB,UAAS;AAAA,EAClC,OAAO;AACL,UAAM,mBAAmB,OAAO,gBAAgB,SAAS;AACzD,aAAS;AACT,aAAS,gBAAiB,mBAAmB,OAAO,OAAQ;AAC5D,aAAS,sBAAsB,OAAO,oBAAoB,OAAO;AACjE,aAAS,KAAK,IAAI,mBAAmB,OAAO,MAAM,WAAW,mBAAmB,OAAO,KAAK;AAC5F,QAAI,YAAa,UAAS,mBAAmB,OAAO;AACpD,QAAI,cAAe,UAAS,mBAAmB,MAAM;AACrD,QAAI,SAAU,UAAS,OAAO,oBAAoB,OAAO;AACzD,QAAI,YAAa,UAAS,OAAO,oBAAoB,IAAI;AACzD,QAAI,SAAU,UAAS,OAAO,oBAAoB,MAAM;AACxD,QAAI,kBAAmB,UAAS,OAAO,oBAAoB,MAAM;AAAA,EACnE;AAEA,SAAO;AAAA,IACL;AAAA,IACA,eAAe,UAAU,QAAQ;AAAA,IACjC;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,cAAc,GAAkB,GAA2B;AAClE,SAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE;AACtD;AAEA,SAAS,cAAc,OAAsB,OAA+B;AAC1E,SAAO,MAAM,aAAa,MAAM,aAAa,MAAM,WAAW,MAAM;AACtE;AAEA,SAAS,qBAAqB,GAAoB,GAA6B;AAC7E,MAAI,cAAc,EAAE,SAAS,QAAQ,MAAM,cAAc,EAAE,SAAS,QAAQ,EAAG,QAAO;AACtF,QAAM,QAAQ,qBAAqB,EAAE,SAAS,QAAQ,EAAE;AACxD,QAAM,QAAQ,qBAAqB,EAAE,SAAS,QAAQ,EAAE;AACxD,QAAM,kBAAkB,MAAM,SAAS,KAAK,UAAU;AACtD,QAAM,gBAAgB,MAAM,WAAW,KAAK,MAAM,WAAW;AAC7D,QAAM,sBAAsB,gBAAgB,EAAE,QAAQ,KAAK,gBAAgB,EAAE,QAAQ;AACrF,QAAM,YAAY,EAAE,SAAS,cAAc,EAAE,SAAS,aAAa,EAAE,SAAS,YAAY,EAAE,SAAS;AACrG,MAAI,UAAW,QAAO,mBAAmB,iBAAiB;AAC1D,MAAI,EAAE,SAAS,QAAQ,EAAE,SAAS,QAAQ,EAAE,SAAS,SAAS,EAAE,SAAS,MAAM;AAC7E,WAAO,mBAAmB,iBAAiB;AAAA,EAC7C;AACA,MAAI,CAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAG,QAAO;AAEnD,QAAM,SAAS,cAAc,EAAE,UAAU,EAAE,QAAQ,KAAK,cAAc,EAAE,UAAU,EAAE,QAAQ;AAC5F,SAAO,WAAW,mBAAmB;AACvC;AAEA,SAAS,oBAAoB,SAA+C;AAC1E,QAAM,WAA8B,CAAC;AACrC,aAAW,SAAS,SAAS;AAC3B,QAAI,SAAS,KAAK,CAAC,aAAa,qBAAqB,SAAS,WAAW,MAAM,SAAS,CAAC,EAAG;AAC5F,aAAS,KAAK,KAAK;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,UAAU,SAA4B,sBAAkD;AAC/F,MAAI,QAAQ,UAAU,EAAG,QAAO;AAChC,QAAM,QAAQ,uBAAuB,QAAQ,OAAO,CAAC,UAAU,MAAM,aAAa,GAAG,IAAI,CAAC;AAC1F,QAAM,WAAW,IAAI,IAAI,MAAM,IAAI,CAAC,UAAU,MAAM,UAAU,EAAE,CAAC;AACjE,QAAM,YAAY,QAAQ,OAAO,CAAC,UAAU,CAAC,SAAS,IAAI,MAAM,UAAU,EAAE,CAAC;AAC7E,QAAM,SAAS,oBAAI,IAA+B;AAClD,QAAM,QAAkB,CAAC;AAEzB,aAAW,SAAS,WAAW;AAC7B,UAAM,WAAW,cAAc,MAAM,UAAU,SAAS,QAAQ;AAChE,QAAI,CAAC,OAAO,IAAI,QAAQ,GAAG;AACzB,aAAO,IAAI,UAAU,CAAC,CAAC;AACvB,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,WAAO,IAAI,QAAQ,GAAG,KAAK,KAAK;AAAA,EAClC;AAEA,QAAM,cAAiC,CAAC;AACxC,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,SAAO,OAAO;AACZ,YAAQ;AACR,eAAW,YAAY,OAAO;AAC5B,YAAM,QAAQ,OAAO,IAAI,QAAQ,IAAI,KAAK;AAC1C,UAAI,CAAC,MAAO;AACZ,kBAAY,KAAK,KAAK;AACtB,cAAQ;AAAA,IACV;AACA,aAAS;AAAA,EACX;AAEA,SAAO,CAAC,GAAG,OAAO,GAAG,WAAW;AAClC;AAEO,SAAS,0BACd,OACA,YACA,YACA,SACmB;AACnB,MAAI,cAAc,KAAK,WAAW,UAAU,EAAG,QAAO;AACtD,QAAM,SAAS,mBAAmB,KAAK;AACvC,MAAI,SAAS,0BAA0B,UAAa,QAAQ,0BAA0B,OAAO,mBAAmB;AAC9G,WAAO,oBAAoB,QAAQ;AAAA,EACrC;AAEA,QAAM,OAAO,KAAK,IAAI,YAAY,WAAW,MAAM;AACnD,QAAM,aAAa,WAAW,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,WAAW,UAAU,eAAe,OAAO,QAAQ,WAAW,KAAK,CAAC;AACtH,aAAW,KAAK,CAAC,GAAG,MAAM;AACxB,QAAI,EAAE,kBAAkB,EAAE,cAAe,QAAO,EAAE,gBAAgB,EAAE;AACpE,QAAI,EAAE,UAAU,UAAU,EAAE,UAAU,MAAO,QAAO,EAAE,UAAU,QAAQ,EAAE,UAAU;AACpF,QAAI,EAAE,kBAAkB,EAAE,cAAe,QAAO,EAAE,gBAAgB,EAAE;AACpE,WAAO,EAAE,UAAU,GAAG,cAAc,EAAE,UAAU,EAAE;AAAA,EACpD,CAAC;AAED,QAAM,aAAa,WAAW,MAAM,IAAI,EAAE,IAAI,CAAC,WAAW,WAAW;AAAA,IACnE;AAAA,IACA,eAAe,UAAU;AAAA,IACzB,eAAe,OAAO;AAAA,IACtB,WAAW,kBAAkB,UAAU,SAAS,MAAM,OAAO,eAAe;AAAA,EAC9E,EAAE;AACF,QAAM,eAAe,oBAAoB,CAAC,GAAG,YAAY,GAAG,UAAU,CAAC;AACvE,QAAM,kBAAkB,OAAO,YAAY,gBAAgB,OAAO,YAAY,oBAAoB,OAAO,gBAAgB,WAAW;AACpI,QAAM,uBAAuB,OAAO,gBAAgB,SAAS,MAC1D,OAAO,YAAY,gBAAgB,OAAO,YAAY,oBAAoB,OAAO,YAAY;AAChG,QAAM,UAAU,kBACZ,UAAU,cAAc,oBAAoB,IAC5C;AACJ,SAAO,QAAQ,IAAI,CAAC,UAAU,MAAM,SAAS;AAC/C;;;ADhfA,IAAM,wBAAoB,8BAAa,aAAa;;;AEWpD,IAAM,oBAAoB;AAE1B,SAAS,gBAAgB,SAAyB;AAChD,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,MAAI,MAAM,UAAU,kBAAmB,QAAO;AAC9C,SACE,MAAM,MAAM,GAAG,iBAAiB,EAAE,KAAK,IAAI,IAC3C;AAAA,UAAa,MAAM,SAAS,iBAAiB;AAEjD;AAEO,SAAS,iBAAiB,OAAmB,UAAmB,OAAe;AACpF,MAAI,MAAM,qBAAqB;AAC7B,WAAO,MAAM,WAAW;AAAA,EAC1B;AAEA,QAAM,QAAkB,CAAC;AAEzB,MAAI,MAAM,eAAe,GAAG;AAC1B,UAAM,KAAK,qBAAqB,MAAM,YAAY,0BAA0B;AAC5E,QAAI,MAAM,mBAAmB;AAC3B,YAAM,KAAK,8BAA8B,MAAM,iBAAiB,EAAE;AAAA,IACpE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,MAAM,kBAAkB,KAAK,MAAM,kBAAkB,GAAG;AAC1D,UAAM,KAAK,GAAG,MAAM,UAAU,qBAAqB,MAAM,cAAc,kCAAkC;AAAA,EAC3G,WAAW,MAAM,kBAAkB,GAAG;AACpC,UAAM,KAAK,GAAG,MAAM,UAAU,mBAAmB,MAAM,aAAa,kBAAkB,MAAM,cAAc,iBAAiB;AAAA,EAC7H,OAAO;AACL,QAAI,OAAO,GAAG,MAAM,UAAU,qBAAqB,MAAM,aAAa;AACtE,QAAI,MAAM,iBAAiB,GAAG;AAC5B,cAAQ,IAAI,MAAM,cAAc;AAAA,IAClC;AACA,UAAM,KAAK,IAAI;AAEf,QAAI,MAAM,gBAAgB,GAAG;AAC3B,YAAM,KAAK,WAAW,MAAM,aAAa,gBAAgB;AAAA,IAC3D;AAEA,QAAI,MAAM,eAAe,GAAG;AAC1B,YAAM,KAAK,WAAW,MAAM,YAAY,UAAU;AAAA,IACpD;AAEA,UAAM,KAAK,WAAW,MAAM,WAAW,eAAe,CAAC,gBAAgB,MAAM,aAAa,KAAM,QAAQ,CAAC,CAAC,GAAG;AAAA,EAC/G;AAEA,MAAI,SAAS;AACX,QAAI,MAAM,aAAa,SAAS,GAAG;AACjC,YAAM,WAAW,MAAM,aAAa,OAAO,OAAK,EAAE,WAAW,WAAW;AACxE,YAAM,WAAW,MAAM,aAAa,OAAO,OAAK,EAAE,WAAW,UAAU;AACvE,YAAM,aAAa,MAAM,aAAa,OAAO,OAAK,EAAE,WAAW,WAAW;AAE1E,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,kBAAkB,MAAM,aAAa,MAAM,EAAE;AACxD,UAAI,SAAS,SAAS,GAAG;AACvB,cAAM,KAAK,gBAAgB,SAAS,MAAM,MAAM,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,SAAS,IAAI,QAAQ,EAAE,EAAE;AAAA,MACvI;AACA,UAAI,SAAS,SAAS,GAAG;AACvB,cAAM,KAAK,eAAe,SAAS,MAAM,MAAM,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,SAAS,IAAI,QAAQ,EAAE,EAAE;AAAA,MACtI;AACA,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,KAAK,iBAAiB,WAAW,MAAM,MAAM,WAAW,MAAM,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,GAAG,WAAW,SAAS,IAAI,QAAQ,EAAE,EAAE;AAAA,MAC9I;AAAA,IACF;AAEA,QAAI,MAAM,cAAc,SAAS,GAAG;AAClC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,qCAAqC,MAAM,cAAc,MAAM,MAAM,MAAM,cAAc,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,cAAc,SAAS,KAAK,QAAQ,EAAE,EAAE;AAAA,IAC9K;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,aAAa,QAAkD;AAC7E,QAAM,YAAY,eAAe,SAAS,OAAO,YAAY;AAC7D,QAAM,iBAAiB,YAAY,sBAAsB,SAAS,IAAI,CAAC;AACvE,MAAI,CAAC,OAAO,SAAS;AACnB,QAAI,OAAO,SAAS;AAClB,aAAO,CAAC,GAAG,gBAAgB,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,IACtD;AAEA,QAAI,OAAO,qBAAqB,GAAG;AACjC,YAAMC,SAAQ;AAAA,QACZ;AAAA,QACA;AAAA,MACF;AAEA,UAAI,OAAO,mBAAmB;AAC5B,QAAAA,OAAM,KAAK,mBAAmB,OAAO,iBAAiB,EAAE;AAAA,MAC1D;AAEA,aAAO,CAAC,GAAG,gBAAgB,GAAGA,MAAK,EAAE,KAAK,IAAI;AAAA,IAChD;AAEA,WAAO,CAAC,GAAG,gBAAgB,iEAAiE,EAAE,KAAK,IAAI;AAAA,EACzG;AAEA,QAAM,QAAQ;AAAA,IACZ,GAAG;AAAA,IACH,mBAAmB,OAAO,YAAY,eAAe,CAAC;AAAA,IACtD,aAAa,OAAO,QAAQ;AAAA,IAC5B,UAAU,OAAO,KAAK;AAAA,IACtB,aAAa,OAAO,SAAS;AAAA,EAC/B;AAEA,MAAI,OAAO,kBAAkB,WAAW;AACtC,UAAM,KAAK,mBAAmB,OAAO,aAAa,EAAE;AACpD,UAAM,KAAK,gBAAgB,OAAO,UAAU,EAAE;AAAA,EAChD;AAEA,MAAI,OAAO,qBAAqB,GAAG;AACjC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,qBAAqB,OAAO,kBAAkB,0BAA0B,OAAO,uBAAuB,IAAI,aAAa,WAAW,GAAG;AAChJ,QAAI,OAAO,mBAAmB;AAC5B,YAAM,KAAK,mBAAmB,OAAO,iBAAiB,EAAE;AAAA,IAC1D;AAAA,EACF;AAEA,MAAI,OAAO,SAAS;AAClB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,kBAAkB,OAAO,OAAO,EAAE;AAAA,EAC/C;AAEA,MAAI,OAAO,iBAAiB,CAAC,OAAO,cAAc,YAAY;AAC5D,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,0BAA0B,OAAO,cAAc,MAAM,EAAE;AAClE,QAAI,OAAO,cAAc,gBAAgB;AACvC,YAAM,SAAS,OAAO,cAAc;AACpC,YAAM,KAAK,yBAAyB,OAAO,iBAAiB,IAAI,OAAO,cAAc,KAAK,OAAO,mBAAmB,IAAI;AACxH,YAAM,KAAK,yBAAyB,OAAO,QAAQ,IAAI,OAAO,KAAK,EAAE;AAAA,IACvE;AAAA,EACF,WAAW,CAAC,OAAO,eAAe;AAChC,UAAM,KAAK,wHAAwH;AAAA,EACrI,OAAO;AACL,UAAM,KAAK,yEAAyE;AAAA,EACtF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,sBAAsB,QAAkD;AAC/E,QAAM,UAAU,OAAO,UAAU,YAAY;AAC7C,QAAM,QAAQ,CAAC,eAAe,OAAO,YAAY,OAAO,KAAK,GAAG;AAChE,MAAI,OAAO,OAAQ,OAAM,KAAK,sBAAsB,OAAO,MAAM,EAAE;AACnE,MAAI,OAAO,UAAU;AACnB,UAAM,WAAW,OAAO;AACxB,UAAM;AAAA,MACJ,wBAAwB,SAAS,KAAK,IAAI,SAAS,UAAU,MACvD,SAAS,cAAc,IAAI,SAAS,UAAU,WAC/C,SAAS,eAAe,IAAI,SAAS,WAAW;AAAA,IACvD;AAAA,EACF;AACA,MAAI,OAAO,iBAAiB,QAAW;AACrC,UAAM,KAAK,0BAA0B,OAAO,YAAY,IAAI,OAAO,cAAc,OAAO,YAAY,EAAE;AAAA,EACxG;AACA,MAAI,OAAO,YAAa,OAAM,KAAK,0BAA0B,OAAO,WAAW,EAAE;AACjF,MAAI,OAAO,UAAW,OAAM,KAAK,uBAAuB,OAAO,SAAS,EAAE;AAC1E,MAAI,OAAO,YAAa,OAAM,KAAK,yBAAyB,OAAO,WAAW,EAAE;AAChF,MAAI,OAAO,QAAS,OAAM,KAAK,0BAA0B,OAAO,OAAO,EAAE;AACzE,MAAI,OAAO,UAAW,OAAM,KAAK,qBAAqB,OAAO,SAAS,EAAE;AACxE,MAAI,OAAO,kBAAkB,kBAAkB;AAC7C,UAAM,KAAK,oDAAoD;AAAA,EACjE,WAAW,OAAO,kBAAkB,0BAA0B;AAC5D,UAAM,KAAK,iEAAiE;AAAA,EAC9E;AACA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AAEO,SAAS,oBAAoB,UAAiC;AACnE,UAAQ,SAAS,OAAO;AAAA,IACtB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,YAAY,SAAS,cAAc,IAAI,SAAS,UAAU;AAAA,IACnE,KAAK;AACH,aAAO,cAAc,SAAS,eAAe,IAAI,SAAS,WAAW;AAAA,IACvE,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,oBAAoB,UAAiC;AACnE,MAAI,SAAS,UAAU,WAAY,QAAO;AAC1C,MAAI,SAAS,UAAU,WAAY,QAAO;AAE1C,MAAI,SAAS,UAAU,WAAW;AAChC,QAAI,SAAS,eAAe,EAAG,QAAO;AACtC,WAAO,KAAK,MAAM,IAAK,SAAS,iBAAiB,SAAS,aAAc,EAAE;AAAA,EAC5E;AAEA,MAAI,SAAS,UAAU,aAAa;AAClC,QAAI,SAAS,gBAAgB,EAAG,QAAO;AACvC,WAAO,KAAK,MAAM,KAAM,SAAS,kBAAkB,SAAS,cAAe,EAAE;AAAA,EAC/E;AAEA,MAAI,SAAS,UAAU,UAAW,QAAO;AAEzC,SAAO;AACT;AAkEA,SAAS,0BAA0B,YAAgF;AACjH,MAAI,WAAW,WAAW,WAAW,EAAG,QAAO;AAC/C,QAAM,QAAQ,WAAW,WAAW,IAAI,CAAC,cACvC,KAAK,UAAU,QAAQ,IAAI,UAAU,SAAS,KAAK,UAAU,IAAI,GAAG;AACtE,MAAI,WAAW,kBAAkB,WAAW,WAAW,QAAQ;AAC7D,UAAM,KAAK,YAAY,WAAW,kBAAkB,WAAW,WAAW,MAAM,OAAO;AAAA,EACzF;AACA,SAAO;AAAA;AAAA,EAAkB,MAAM,KAAK,IAAI,CAAC;AAC3C;AAEA,SAAS,0BACP,YACA,OACA,mBACe;AACf,MAAI,WAAW,WAAW,WAAY,QAAO;AAC7C,MAAI,WAAW,iBAAiB;AAC9B,WAAO,aAAa,KAAK,oEAAoE,WAAW,WAAW,QAAQ,iBAAiB,KAAK,EAAE;AAAA,EACrJ;AAEA,QAAM,aAAa,0BAA0B,UAAU;AACvD,MAAI,WAAW,WAAW,aAAa;AACrC,WAAO,aAAa,KAAK,KAAK,WAAW,IAAI,WAAW,iBAAiB,2BAA2B,UAAU;AAAA,EAChH;AACA,MAAI,WAAW,YAAY,WAAW,kBAAkB,GAAG;AACzD,WAAO,MAAM,KAAK,WAAW,WAAW,IAAI,aAAa,iBAAiB,KAAK,WAAW,QAAQ,4CAA4C,UAAU;AAAA,EAC1J;AACA,SAAO,cAAc,KAAK,WAAW,WAAW,IAAI;AACtD;AAEO,SAAS,sBAAsB,QAAqC;AACzE,QAAM,oBAAoB,0BAA0B,OAAO,YAAY,UAAU,UAAU;AAC3F,MAAI,kBAAmB,QAAO;AAC9B,MAAI,OAAO,WAAW,WAAW,WAAY,QAAO;AAEpD,QAAM,aAAa,OAAO;AAC1B,QAAM,eAAe,OAAO,mBAAmB,cAAc,OAAO,gBAAgB,KAAK;AACzF,QAAM,WAAW,GAAG,WAAW,QAAQ,IAAI,WAAW,SAAS;AAC/D,MAAI,OAAO,cAAc,WAAW;AAClC,QAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,aAAO,yBAAyB,WAAW,IAAI,QAAQ,QAAQ,GAAG,YAAY;AAAA,IAChF;AACA,UAAMC,aAAY,OAAO,QAAQ,IAAI,CAAC,MAAM,UAAU;AACpD,YAAM,aAAa,KAAK,eAAe,WAAW,KAAK,KAAK,WAAW,YAAY,CAAC,MAAM;AAC1F,aAAO,IAAI,QAAQ,CAAC,iBAAiB,KAAK,kBAAkB,WAAW,OAAO,KAAK,sBAAsB,gBAAgB,KAAK,KAAK,QAAQ,IAAI,UAAU,YAAY,KAAK,IAAI,GAAG,KAAK,aAAa,gBAAgB,eAAe;AAAA,IACpO,CAAC;AACD,WAAO,IAAI,WAAW,IAAI,QAAQ,QAAQ,iBAAiB,OAAO,QAAQ,MAAM;AAAA;AAAA,EAAoBA,WAAU,KAAK,IAAI,CAAC;AAAA,EAC1H;AAEA,MAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,WAAO,yBAAyB,WAAW,IAAI,QAAQ,QAAQ,GAAG,YAAY;AAAA,EAChF;AACA,QAAM,YAAY,OAAO,QAAQ,IAAI,CAAC,MAAM,UAAU;AACpD,UAAM,aAAa,KAAK,eAAe,WAAW,KAAK,KAAK,WAAW,YAAY,CAAC,MAAM;AAC1F,WAAO,IAAI,QAAQ,CAAC,YAAY,KAAK,UAAU,KAAK,KAAK,QAAQ,IAAI,UAAU,YAAY,KAAK,IAAI,GAAG,KAAK,aAAa,gBAAgB,eAAe;AAAA,EAC1J,CAAC;AACD,SAAO,IAAI,WAAW,IAAI,QAAQ,QAAQ,UAAU,OAAO,QAAQ,MAAM;AAAA;AAAA,EAAoB,UAAU,KAAK,IAAI,CAAC;AACnH;AAsBA,SAAS,mBAAmB,QAAsB,OAAuB;AACvE,SAAO,OAAO,OACV,IAAI,QAAQ,CAAC,KAAK,OAAO,SAAS,KAAK,OAAO,IAAI,QAAQ,OAAO,QAAQ,IAAI,OAAO,SAAS,IAAI,OAAO,OAAO,KAC/G,IAAI,QAAQ,CAAC,KAAK,OAAO,SAAS,OAAO,OAAO,QAAQ,IAAI,OAAO,SAAS,IAAI,OAAO,OAAO;AACpG;AAEA,SAAS,YAAY,QAA8B;AACjD,MAAI,CAAC,OAAO,OAAO;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,IAAI,KAAK,OAAO,MAAM,cAAc,GAAI,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAChF,SAAO;AAAA,MAAS,OAAO,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,OAAO,MAAM,MAAM,MAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AAC3G;AAEO,SAAS,uBAAuB,SAAyB,OAAuB;AACrF,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,4BAA4B,KAAK;AAAA,EAC1C;AAEA,QAAM,YAAY,QAAQ,IAAI,CAAC,GAAG,QAAQ;AACxC,UAAM,SAAS,mBAAmB,GAAG,GAAG;AACxC,WAAO,GAAG,MAAM,YAAY,EAAE,MAAM,QAAQ,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC;AAAA;AAAA,EAAa,gBAAgB,EAAE,OAAO,CAAC;AAAA;AAAA,EACzG,CAAC;AAED,SAAO,UAAU,KAAK,MAAM;AAC9B;AAIO,SAAS,oBAAoB,SAAyB,cAA2B,cAAsB;AAC5G,QAAM,YAAY,QAAQ,IAAI,CAAC,GAAG,QAAQ;AACxC,UAAM,SAAS,mBAAmB,GAAG,GAAG;AAExC,UAAM,aAAa,gBAAgB,eAC/B,iBAAiB,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,OAC1C,WAAW,EAAE,MAAM,QAAQ,CAAC,CAAC;AAEjC,WAAO,GAAG,MAAM,IAAI,UAAU,GAAG,YAAY,CAAC,CAAC;AAAA;AAAA,EAAa,gBAAgB,EAAE,OAAO,CAAC;AAAA;AAAA,EACxF,CAAC;AAED,SAAO,UAAU,KAAK,MAAM;AAC9B;;;ACzZA,IAAAC,aAAyC;AACzC,IAAAC,MAAoB;AACpB,IAAAC,SAAsB;;;ACNtB,oBAA2B;AAC3B,IAAAC,aAUO;AACP,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AA0DtB,IAAM,kBAAkB;AACxB,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAC/B,IAAM,eAAe;AACrB,IAAM,mBAAmB,oBAAI,IAA4B;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAI,mBAAmB;AAEvB,SAAS,aAAa,OAAoC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,QAC5D,OAAQ,MAA6B,IAAI,IACzC;AACN;AAEA,SAAS,kCAAkC,WAA6B;AACtE,MAAI;AACJ,WAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,QAAI;AACF,gBAAU;AACV;AAAA,IACF,SAAS,OAAO;AACd,kBAAY;AACZ,YAAM,OAAO,aAAa,KAAK;AAC/B,UAAI,SAAS,WAAW,SAAS,QAAS,OAAM;AAChD,UAAI,UAAU,GAAG;AACf,gBAAQ,KAAK,IAAI,WAAW,IAAI,kBAAkB,CAAC,CAAC,GAAG,GAAG,IAAI,UAAU,KAAK,EAAE;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AACA,QAAM;AACR;AAEA,SAAS,WAAW,OAAuC;AACzD,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,YAAY;AAClB,MAAI,CAAC,OAAO,UAAU,UAAU,GAAG,MAAM,UAAU,OAAO,MAAM,EAAG,QAAO;AAC1E,MAAI,OAAO,UAAU,aAAa,YAAY,UAAU,SAAS,WAAW,EAAG,QAAO;AACtF,MAAI,OAAO,UAAU,cAAc,YAAY,OAAO,MAAM,KAAK,MAAM,UAAU,SAAS,CAAC,EAAG,QAAO;AACrG,MAAI,OAAO,UAAU,cAAc,YAAY,CAAC,iBAAiB,IAAI,UAAU,SAAmC,EAAG,QAAO;AAC5H,MAAI,OAAO,UAAU,UAAU,YAAY,CAAC,aAAa,KAAK,UAAU,KAAK,EAAG,QAAO;AACvF,MAAI,UAAU,4BAA4B,UAAa,UAAU,4BAA4B,EAAG,QAAO;AACvG,MAAI,UAAU,gBAAgB,UAAa,OAAO,UAAU,gBAAgB,SAAU,QAAO;AAC7F,MAAI,UAAU,gBAAgB,QAAW;AACvC,QAAI,CAAC,MAAM,QAAQ,UAAU,WAAW,KAAK,UAAU,YAAY,KAAK,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AAC3G,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,UAAU,kBAAkB,QAAW;AACzC,UAAM,WAAW,UAAU;AAC3B,QACE,OAAO,aAAa,YACjB,aAAa,QACb,SAAS,UAAU,cACnB,OAAO,SAAS,sBAAsB,YACtC,SAAS,kBAAkB,WAAW,KACtC,OAAO,SAAS,mBAAmB,YACnC,SAAS,eAAe,WAAW,KACnC,CAAC,OAAO,UAAU,SAAS,mBAAmB,MAC7C,SAAS,uBAAuB,MAAM,KACvC,OAAO,SAAS,6BAA6B,YAC7C,SAAS,yBAAyB,WAAW,KAE9C,SAAS,0BAA0B,gBAChC,SAAS,0BAA0B,iCACnC,SAAS,0BAA0B,kBAEpC,UAAU,cAAc,WAAW,UAAU,cAAc,eAC/D;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAqC;AAC9D,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,YAAY;AAClB,MAAI,CAAC,OAAO,UAAU,UAAU,GAAG,MAAM,UAAU,OAAO,MAAM,EAAG,QAAO;AAC1E,MAAI,OAAO,UAAU,aAAa,YAAY,UAAU,SAAS,WAAW,EAAG,QAAO;AACtF,MAAI,OAAO,UAAU,cAAc,YAAY,OAAO,MAAM,KAAK,MAAM,UAAU,SAAS,CAAC,EAAG,QAAO;AACrG,MAAI,OAAO,UAAU,UAAU,YAAY,CAAC,aAAa,KAAK,UAAU,KAAK,EAAG,QAAO;AACvF,MAAI,OAAO,UAAU,uBAAuB,YAAY,CAAC,aAAa,KAAK,UAAU,kBAAkB,EAAG,QAAO;AACjH,SAAO;AACT;AAEA,SAAS,kBAAqB,eAAuB,QAAgD;AACnG,MAAI;AACF,WAAO,OAAO,KAAK,UAAM,yBAAkB,WAAK,eAAe,eAAe,GAAG,OAAO,CAAC,CAAC;AAAA,EAC5F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,mBAAmB,UAAyC;AACnE,SAAO,kBAAkB,UAAU,UAAU;AAC/C;AAEA,SAAS,iBAAiB,YAAyC;AACjE,SAAO,kBAAkB,YAAY,iBAAiB;AACxD;AAEA,SAAS,kBAAkB,YAA2C;AACpE,SAAO,mBAAmB,UAAU;AACtC;AAEA,SAAS,gBAAgB,UAAyC;AAChE,MAAI;AACF,UAAM,SAAS,KAAK,UAAM,yBAAa,UAAU,OAAO,CAAC;AAOzD,QAAI,CAAC,OAAO,UAAU,OAAO,GAAG,KAAK,OAAO,OAAO,GAAG,KAAK,EAAG,QAAO;AACrE,QAAI,OAAO,OAAO,cAAc,YAAY,OAAO,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC,EAAG,QAAO;AAC/F,WAAO;AAAA,MACL,KAAK,OAAO,OAAO,GAAG;AAAA,MACtB,UAAU,OAAO,OAAO,aAAa,WAAW,OAAO,WAAc,aAAS;AAAA,MAC9E,WAAW,OAAO;AAAA,MAClB,WAAW,OAAO,OAAO,cAAc,YAAY,iBAAiB,IAAI,OAAO,SAAmC,IAC9G,OAAO,YACP;AAAA,MACJ,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAAA,IAC3D;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,OAAgE;AACxF,MAAI,MAAM,aAAgB,aAAS,EAAG,QAAO;AAC7C,MAAI;AACF,YAAQ,KAAK,MAAM,KAAK,CAAC;AACzB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,OAAO,aAAa,KAAK;AAC/B,QAAI,SAAS,QAAS,QAAO;AAC7B,QAAI,SAAS,QAAS,QAAO;AAC7B,WAAO;AAAA,EACT;AACF;AAEA,SAAS,UAAU,MAAsB,OAAgC;AACvE,SAAO,KAAK,QAAQ,MAAM,OAAO,KAAK,aAAa,MAAM,YAAY,KAAK,UAAU,MAAM;AAC5F;AAEA,SAAS,iBAAiB,MAAoB,OAA8B;AAC1E,SAAO,KAAK,QAAQ,MAAM,OACrB,KAAK,aAAa,MAAM,YACxB,KAAK,UAAU,MAAM,SACrB,KAAK,uBAAuB,MAAM;AACzC;AAEA,SAAS,qBAAqB,WAAmB,OAA+C;AAC9F,QAAM,gBAAgB,GAAG,SAAS,cAAc,QAAQ,GAAG,QAAI,0BAAW,CAAC;AAC3E,MAAI;AACF,8BAAU,eAAe,EAAE,MAAM,IAAM,CAAC;AAAA,EAC1C,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,MAAM,SAAU,QAAO;AAC7C,UAAM;AAAA,EACR;AACA,MAAI;AACF,kCAAmB,WAAK,eAAe,eAAe,GAAG,KAAK,UAAU,KAAK,GAAG;AAAA,MAC9E,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AACD,YAAI,uBAAW,SAAS,EAAG,QAAO;AAClC,QAAI;AACF,iCAAW,eAAe,SAAS;AACnC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAI,uBAAW,SAAS,EAAG,QAAO;AAClC,UAAI,aAAa,KAAK,MAAM,SAAU,QAAO;AAC7C,YAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,MAAM,SAAU,QAAO;AAC7C,UAAM;AAAA,EACR,UAAE;AACA,YAAI,uBAAW,aAAa,EAAG,wBAAO,eAAe,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACvF;AACF;AAEA,SAAS,YAAY,WAAmD;AACtE,SAAO;AAAA,IACL,KAAK,QAAQ;AAAA,IACb,UAAa,aAAS;AAAA,IACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC;AAAA,IACA,WAAO,0BAAW;AAAA,EACpB;AACF;AAOA,SAAS,mBAAmB,WAAmB,OAA+B;AAC5E,SAAY,WAAK,WAAW,GAAG,sBAAsB,GAAG,MAAM,KAAK,EAAE;AACvE;AAEA,SAAS,sBAAsB,WAAmB,OAA+B;AAC/E,QAAM,aAAa,mBAAmB,WAAW,KAAK;AACtD,MAAI,CAAC,qBAAqB,YAAY,KAAK,GAAG;AAC5C,UAAM,cAAc,kBAAkB,UAAU;AAChD,QAAI,CAAC,eAAe,CAAC,UAAU,aAAa,KAAK,GAAG;AAClD,YAAM,IAAI,yBAAyB,YAAY,aAAa,eAAe;AAAA,IAC7E;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,WAAwC;AACpE,QAAM,aAAkC,CAAC;AACzC,QAAM,kBAAc,wBAAY,SAAS,EAAE,OAAO,CAAC,SAAS;AAC1D,QAAI,CAAC,KAAK,WAAW,sBAAsB,EAAG,QAAO;AACrD,WAAO,aAAa,KAAK,KAAK,MAAM,uBAAuB,MAAM,CAAC;AAAA,EACpE,CAAC,EAAE,KAAK;AACR,aAAW,cAAc,aAAa;AACpC,UAAM,aAAkB,WAAK,WAAW,UAAU;AAClD,UAAM,cAAc,WAAW,MAAM,uBAAuB,MAAM;AAClE,QAAI;AACJ,QAAI;AACF,wBAAc,sBAAU,UAAU;AAAA,IACpC,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,MAAM,SAAU;AACtC,YAAM;AAAA,IACR;AACA,QAAI,CAAC,YAAY,YAAY,GAAG;AAC9B,YAAM,IAAI,yBAAyB,YAAY,MAAM,eAAe;AAAA,IACtE;AACA,UAAM,QAAQ,kBAAkB,UAAU;AAC1C,QAAI,CAAC,SAAS,MAAM,UAAU,eAAe,iBAAiB,KAAK,MAAM,QAAQ;AAC/E,YAAM,IAAI,yBAAyB,YAAY,OAAO,eAAe;AAAA,IACvE;AACA,eAAW,KAAK,EAAE,OAAO,WAAW,CAAC;AAAA,EACvC;AACA,aAAW,KAAK,CAAC,MAAM,UAAU;AAC/B,UAAM,cAAc,KAAK,MAAM,UAAU,cAAc,MAAM,MAAM,SAAS;AAC5E,WAAO,gBAAgB,IAAI,cAAc,KAAK,WAAW,cAAc,MAAM,UAAU;AAAA,EACzF,CAAC;AACD,SAAO;AACT;AAEA,SAAS,iCAAiC,WAAyB;AACjE,QAAM,mBAAmB;AACzB,aAAW,aAAS,wBAAY,SAAS,GAAG;AAC1C,UAAM,QAAQ,iBAAiB,KAAK,KAAK;AACzC,QAAI,CAAC,MAAO;AACZ,UAAM,MAAM,OAAO,MAAM,CAAC,CAAC;AAC3B,QAAI,CAAC,OAAO,UAAU,GAAG,KAAK,OAAO,EAAG;AACxC,QAAI,iBAAiB,EAAE,KAAK,UAAa,aAAS,EAAE,CAAC,MAAM,OAAQ;AACnE,2BAAY,WAAK,WAAW,KAAK,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACtE;AACF;AAEA,SAAS,wBAAwB,UAAkB,eAAwC;AACzF,QAAM,aAAkB,WAAK,UAAU,sBAAsB;AAC7D,QAAM,SAAS,iBAAiB,UAAU;AAC1C,MAAI,CAAC,UAAU,OAAO,uBAAuB,cAAc,SAAS,iBAAiB,MAAM,MAAM,QAAQ;AACvG,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,mBAAmB,QAAQ;AAChD,MAAI,CAAC,gBAAgB,CAAC,UAAU,cAAc,aAAa,KAAK,iBAAiB,YAAY,MAAM,QAAQ;AACzG,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,GAAG,UAAU,UAAU,OAAO,GAAG,IAAI,OAAO,KAAK,QAAI,0BAAW,CAAC;AAC3F,MAAI;AACF,+BAAW,YAAY,iBAAiB;AAAA,EAC1C,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,MAAM,SAAU,QAAO;AAC7C,UAAM;AAAA,EACR;AAEA,QAAM,gBAAgB,iBAAiB,iBAAiB;AACxD,QAAM,kBAAkB,mBAAmB,QAAQ;AACnD,MAAI,CAAC,iBACA,CAAC,iBAAiB,eAAe,MAAM,KACvC,CAAC,mBACD,CAAC,UAAU,iBAAiB,aAAa,KACzC,iBAAiB,eAAe,MAAM,QAAQ;AACjD,QAAI,KAAC,uBAAW,UAAU,SAAK,uBAAW,iBAAiB,GAAG;AAC5D,iCAAW,mBAAmB,UAAU;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAEA,yBAAO,mBAAmB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC1D,SAAO;AACT;AAEA,SAAS,iBAAiB,WAAmB,UAAkB,eAAwC;AACrG,QAAM,cAAmB,WAAK,UAAU,sBAAsB;AAC9D,QAAM,eAA6B;AAAA,IACjC,KAAK,QAAQ;AAAA,IACb,UAAa,aAAS;AAAA,IACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,WAAO,0BAAW;AAAA,IAClB,oBAAoB,cAAc;AAAA,EACpC;AAEA,WAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,QAAI,qBAAqB,aAAa,YAAY,EAAG;AACrD,QAAI,YAAY,KAAK,wBAAwB,UAAU,aAAa,EAAG;AACvE,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,mBAAmB,iBAAiB,WAAW;AACrD,UAAM,eAAe,mBAAmB,QAAQ;AAChD,QAAI,CAAC,oBACA,CAAC,iBAAiB,kBAAkB,YAAY,KAChD,CAAC,gBACD,CAAC,UAAU,cAAc,aAAa,KACtC,iBAAiB,YAAY,MAAM,QAAQ;AAC9C,aAAO;AAAA,IACT;AAEA,0BAAsB,WAAW,aAAa;AAE9C,UAAM,wBAAwB,mBAAmB,QAAQ;AACzD,UAAM,4BAA4B,iBAAiB,WAAW;AAC9D,QAAI,CAAC,yBACA,CAAC,UAAU,uBAAuB,aAAa,KAC/C,iBAAiB,qBAAqB,MAAM,UAC5C,CAAC,6BACD,CAAC,iBAAiB,2BAA2B,YAAY,GAAG;AAC/D,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,GAAG,QAAQ,UAAU,cAAc,KAAK,IAAI,aAAa,KAAK;AACrF,+BAAW,UAAU,cAAc;AACnC,2BAAO,gBAAgB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACvD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,MAAM,SAAU,QAAO;AAC7C,UAAM;AAAA,EACR;AACF;AAEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAGlD,YACW,UACA,OACA,QACT;AACA,UAAM,mBAAmB,QACrB,OAAO,MAAM,GAAG,OAAO,MAAM,QAAQ,eAAe,MAAM,SAAS,WAAW,MAAM,SAAS,KAC7F;AACJ,UAAM,uCAAuC,gBAAgB,EAAE;AAPtD;AACA;AACA;AAMT,SAAK,OAAO;AAAA,EACd;AAAA,EATW;AAAA,EACA;AAAA,EACA;AAAA,EALF,OAAO;AAalB;AAEO,SAAS,2BAA2B,OAAmD;AAC5F,SAAO,iBAAiB,4BAClB,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAU,MAA6B,SAAS;AACjH;AAEO,SAAS,+BAA+B,OAAyB;AACtE,MAAI,CAAC,2BAA2B,KAAK,KAAK,EAAE,YAAY,OAAQ,QAAO;AACvE,SAAO,MAAM,WAAW,YAAY,MAAM,WAAW;AACvD;AAEO,SAAS,iBACd,WACA,WACA,eACgB;AAChB,4BAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,QAAM,qBAAqB,wBAAa,OAAO,SAAS;AACxD,QAAM,WAAgB,WAAK,oBAAoB,eAAe;AAC9D,mCAAiC,kBAAkB;AAEnD,WAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,UAAM,QAAQ,kBAAkB,SAC5B,YAAY,SAAS,IACrB;AAAA,MACE,GAAG,YAAY,SAAS;AAAA,MACxB,yBAAyB;AAAA,MACzB,aAAa,cAAc;AAAA,MAC3B,aAAa,cAAc;AAAA,IAC7B;AACJ,QAAI,qBAAqB,UAAU,KAAK,GAAG;AACzC,YAAM,QAAwB;AAAA,QAC5B;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY,CAAC;AAAA,MACf;AACA,UAAI;AACF,cAAM,aAAa,qBAAqB,kBAAkB;AAC1D,eAAO;AAAA,MACT,SAAS,OAAO;AACd,yBAAiB,KAAK;AACtB,cAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,kBAAQ,sBAAU,QAAQ;AAAA,IAC5B,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,MAAM,SAAU;AACtC,YAAM;AAAA,IACR;AAEA,QAAI,CAAC,MAAM,YAAY,GAAG;AACxB,YAAM,cAAc,gBAAgB,QAAQ;AAC5C,YAAM,IAAI,yBAAyB,UAAU,aAAa,aAAa;AAAA,IACzE;AAEA,UAAM,gBAAgB,mBAAmB,QAAQ;AACjD,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,yBAAyB,UAAU,MAAM,eAAe;AAAA,IACpE;AAEA,UAAM,WAAW,iBAAiB,aAAa;AAC/C,QAAI,aAAa,QAAQ;AACvB,YAAM,IAAI,yBAAyB,UAAU,eAAe,aAAa,UAAU,WAAW,eAAe;AAAA,IAC/G;AAEA,QAAI,CAAC,iBAAiB,oBAAoB,UAAU,aAAa,GAAG;AAClE,YAAM,IAAI,yBAAyB,UAAU,eAAe,YAAY;AAAA,IAC1E;AAAA,EACF;AAEA,QAAM,IAAI,yBAAyB,UAAU,MAAM,YAAY;AACjE;AAEO,SAAS,iBAAiB,OAAgC;AAC/D,QAAM,eAAe,mBAAmB,MAAM,QAAQ;AACtD,MAAI,CAAC,gBAAgB,CAAC,UAAU,cAAc,MAAM,KAAK,EAAG,QAAO;AAEnE,QAAM,cAAc,GAAG,MAAM,QAAQ,YAAY,MAAM,MAAM,GAAG,IAAI,MAAM,MAAM,KAAK;AACrF,MAAI;AACF,sCAAkC,UAAM,uBAAW,MAAM,UAAU,WAAW,CAAC;AAAA,EACjF,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,MAAM,SAAU,QAAO;AAC7C,UAAM;AAAA,EACR;AAEA,QAAM,eAAe,mBAAmB,WAAW;AACnD,MAAI,CAAC,gBAAgB,CAAC,UAAU,cAAc,MAAM,KAAK,GAAG;AAC1D,QAAI,KAAC,uBAAW,MAAM,QAAQ,SAAK,uBAAW,WAAW,GAAG;AAC1D,iCAAW,aAAa,MAAM,QAAQ;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,sCAAkC,UAAM,mBAAO,aAAa,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,EAC/F,SAAS,OAAO;AACd,YAAQ,MAAM,iEAAiE,WAAW,IAAI,KAAK;AAAA,EACrG;AACA,SAAO;AACT;AAEO,SAAS,+BACd,OACA,eACM;AACN,QAAM,eAAe,mBAAmB,MAAM,QAAQ;AACtD,MAAI,CAAC,gBAAgB,CAAC,UAAU,cAAc,MAAM,KAAK,GAAG;AAC1D,UAAM,IAAI,MAAM,0CAA0C,MAAM,MAAM,KAAK,EAAE;AAAA,EAC/E;AAEA,QAAM,YAA4B,EAAE,GAAG,aAAa;AACpD,MAAI,kBAAkB,MAAM;AAC1B,WAAO,UAAU;AAAA,EACnB,OAAO;AACL,cAAU,gBAAgB;AAAA,EAC5B;AAEA,QAAM,YAAiB,WAAK,MAAM,UAAU,eAAe;AAC3D,QAAM,gBAAqB;AAAA,IACzB,MAAM;AAAA,IACN,GAAG,eAAe,QAAQ,MAAM,MAAM,GAAG,IAAI,MAAM,MAAM,KAAK,QAAI,0BAAW,CAAC;AAAA,EAChF;AACA,MAAI;AACF,kCAAc,eAAe,KAAK,UAAU,SAAS,GAAG;AAAA,MACtD,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AACD,sCAAkC,UAAM,uBAAW,eAAe,SAAS,CAAC;AAAA,EAC9E,UAAE;AACA,YAAI,uBAAW,aAAa,EAAG,wBAAO,eAAe,EAAE,OAAO,KAAK,CAAC;AAAA,EACtE;AACF;AA2CO,SAAS,yBACd,YACA,OACA,OAAsB,OACd;AACR,MAAI,SAAS,MAAO,QAAO,GAAG,UAAU,QAAQ,MAAM,GAAG,IAAI,MAAM,KAAK;AACxE,sBAAoB;AACpB,SAAO,GAAG,UAAU,QAAQ,MAAM,GAAG,IAAI,MAAM,KAAK,IAAI,gBAAgB;AAC1E;AAEO,SAAS,yBAAyB,eAA6B;AACpE,UAAI,uBAAW,aAAa,EAAG,wBAAO,eAAe,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACvF;AAEO,SAAS,sBACd,WACA,OACA,eACM;AACN,aAAW,cAAc,eAAe;AACtC,UAAM,aAAa,yBAAyB,YAAY,OAAO,KAAK;AACpE,QAAI,KAAC,uBAAW,UAAU,EAAG;AAC7B,YAAI,uBAAW,UAAU,EAAG,wBAAO,YAAY,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC/E,+BAAW,YAAY,UAAU;AAAA,EACnC;AAEA,QAAM,uBAAuB,QAAQ,MAAM,GAAG,IAAI,MAAM,KAAK;AAC7D,aAAW,aAAS,wBAAY,SAAS,GAAG;AAC1C,QAAI,CAAC,MAAM,SAAS,oBAAoB,EAAG;AAC3C,2BAAY,WAAK,WAAW,KAAK,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACtE;AACF;AAEO,SAAS,sBAAsB,OAA6B;AACjE,aAAW,YAAY,MAAM,YAAY;AACvC,UAAM,cAAc,kBAAkB,SAAS,UAAU;AACzD,QAAI,CAAC,eAAe,CAAC,UAAU,aAAa,SAAS,KAAK,GAAG;AAC3D,YAAM,IAAI,MAAM,sCAAsC,SAAS,UAAU,EAAE;AAAA,IAC7E;AAAA,EACF;AACA,aAAW,YAAY,MAAM,YAAY;AACvC,2BAAO,SAAS,YAAY,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAC9D;AACF;;;ACrpBA,oBAA+B;AAC/B,IAAAC,aAAiE;AACjE,IAAAC,SAAsB;AAItB,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,iBAAiB,aAA8B;AAC7D,aAAW,UAAU,iBAAiB;AACpC,YAAI,uBAAgB,YAAK,aAAa,MAAM,CAAC,GAAG;AAC9C,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAYO,SAAS,mBAAmB,aAA6B;AAC9D,QAAM,SAAK,cAAAC,SAAO;AAElB,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,KAAG,IAAI,cAAc;AAErB,QAAM,gBAAqB,YAAK,aAAa,YAAY;AACzD,UAAI,uBAAW,aAAa,GAAG;AAC7B,UAAM,uBAAmB,yBAAa,eAAe,OAAO;AAC5D,OAAG,IAAI,gBAAgB;AAAA,EACzB;AAEA,SAAO;AACT;AAkCA,SAAS,UAAU,UAAkB,SAA0B;AAC7D,MAAI,QAAQ,WAAW,KAAK,GAAG;AAC7B,UAAM,gBAAgB,QAAQ,MAAM,CAAC;AACrC,QAAI,iBAAiB,UAAU,UAAU,aAAa,GAAG;AACvD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,iBAAiB,QAAQ,QAAQ,mBAAmB,MAAM;AAEhE,MAAI,eAAe,eAChB,QAAQ,SAAS,kBAAkB,EACnC,QAAQ,OAAO,OAAO,EACtB,QAAQ,qBAAqB,IAAI,EACjC,QAAQ,OAAO,GAAG,EAClB,QAAQ,gBAAgB,CAAC,GAAG,OAAO,IAAI,GAAG,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG;AAGpE,MAAI,aAAa,WAAW,KAAK,GAAG;AAClC,mBAAe,WAAW,aAAa,MAAM,CAAC,CAAC;AAAA,EACjD;AAEA,QAAM,QAAQ,IAAI,OAAO,IAAI,YAAY,GAAG;AAC5C,SAAO,MAAM,KAAK,QAAQ;AAC5B;AAOA,gBAAuB,cACrB,KACA,aACA,iBACA,iBACA,cACA,aACA,SACA,SACA,eAAuB,GACyB;AAChD,QAAM,UAAU,MAAM,WAAAC,SAAW,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAErE,QAAM,aAAoD,CAAC;AAC3D,QAAM,UAA6D,CAAC;AAEpE,aAAW,SAAS,SAAS;AAC3B,UAAM,WAAgB,YAAK,KAAK,MAAM,IAAI;AAC1C,UAAM,eAAoB,gBAAS,aAAa,QAAQ;AAExD,QAAI,oBAAoB,MAAM,IAAI,GAAG;AACnC,UAAI,MAAM,YAAY,GAAG;AACvB,gBAAQ,KAAK,EAAE,MAAM,cAAc,QAAQ,WAAW,CAAC;AAAA,MACzD;AACA;AAAA,IACF;AAEA,QAAI,MAAM,YAAY,KAAK,mBAAmB,MAAM,IAAI,GAAG;AACzD,cAAQ,KAAK,EAAE,MAAM,cAAc,QAAQ,WAAW,CAAC;AACvD;AAAA,IACF;AAEA,QAAI,aAAa,QAAQ,YAAY,GAAG;AACtC,UAAI,MAAM,OAAO,GAAG;AAClB,gBAAQ,KAAK,EAAE,MAAM,cAAc,QAAQ,YAAY,CAAC;AAAA,MAC1D;AACA;AAAA,IACF;AAEA,QAAI,MAAM,YAAY,GAAG;AACvB,cAAQ,KAAK,EAAE,UAAU,aAAa,CAAC;AAAA,IACzC,WAAW,MAAM,OAAO,GAAG;AACzB,YAAMC,QAAO,MAAM,WAAAD,SAAW,KAAK,QAAQ;AAE3C,UAAIC,MAAK,OAAO,aAAa;AAC3B,gBAAQ,KAAK,EAAE,MAAM,cAAc,QAAQ,YAAY,CAAC;AACxD;AAAA,MACF;AAEA,iBAAW,WAAW,iBAAiB;AACrC,YAAI,UAAU,cAAc,OAAO,GAAG;AACpC,kBAAQ,KAAK,EAAE,MAAM,cAAc,QAAQ,WAAW,CAAC;AACvD;AAAA,QACF;AAAA,MACF;AAEA,UAAI,UAAU;AACd,iBAAW,WAAW,iBAAiB;AACrC,YAAI,UAAU,cAAc,OAAO,GAAG;AACpC,oBAAU;AACV;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS;AACX,mBAAW,KAAK,EAAE,MAAM,UAAU,MAAMA,MAAK,KAAK,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,aAAW,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI;AACzC,QAAM,eAAe,WAAW,MAAM,GAAG,QAAQ,oBAAoB;AACrE,aAAW,KAAK,cAAc;AAC5B,UAAM;AAAA,EACR;AACA,WAAS,IAAI,QAAQ,sBAAsB,IAAI,WAAW,QAAQ,KAAK;AACrE,YAAQ,KAAK,EAAE,MAAW,gBAAS,aAAa,WAAW,CAAC,EAAE,IAAI,GAAG,QAAQ,WAAW,CAAC;AAAA,EAC3F;AAEA,QAAM,aAAa,QAAQ,aAAa,MAAM,eAAe,QAAQ;AACrE,MAAI,YAAY;AACd,eAAW,OAAO,SAAS;AACzB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,aACpB,aACA,iBACA,iBACA,aACA,iBACA,aAC6B;AAC7B,QAAM,OAAoB,eAAe,EAAE,UAAU,GAAG,sBAAsB,IAAI;AAClF,QAAM,eAAe,mBAAmB,WAAW;AACnD,QAAM,QAA+C,CAAC;AACtD,QAAM,UAAyB,CAAC;AAEhC,mBAAiB,QAAQ;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAG;AACD,UAAM,KAAK,IAAI;AAAA,EACjB;AAEA,MAAI,mBAAmB,gBAAgB,SAAS,GAAG;AACjD,UAAM,kBAAkB,oBAAI,IAAY;AACxC,eAAW,UAAU,iBAAiB;AACpC,YAAM,WAAgB;AAAA,QACf,kBAAW,MAAM,IAAI,SAAc,eAAQ,aAAa,MAAM;AAAA,MACrE;AACA,sBAAgB,IAAI,QAAQ;AAAA,IAC9B;AAEA,eAAW,kBAAkB,iBAAiB;AAC5C,UAAI;AACF,cAAMA,QAAO,MAAM,WAAAD,SAAW,KAAK,cAAc;AACjD,YAAI,CAACC,MAAK,YAAY,GAAG;AACvB,kBAAQ,KAAK,EAAE,MAAM,gBAAgB,QAAQ,WAAW,CAAC;AACzD;AAAA,QACF;AACA,cAAM,iBAAiB,mBAAmB,cAAc;AACxD,yBAAiB,QAAQ;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,GAAG;AACD,gBAAM,KAAK,IAAI;AAAA,QACjB;AAAA,MACF,QAAQ;AACN,gBAAQ,KAAK,EAAE,MAAM,gBAAgB,QAAQ,WAAW,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,QAAQ;AAC1B;;;AC1SA,mBAA8B;AAsB9B,IAAM,gCAAgC;AACtC,IAAM,mBAAmB;AAEzB,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,WACP,MACA,MACA,SACiB;AACjB,SAAO,IAAI,QAAQ,CAACC,WAAS,WAAW;AACtC,IAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA,EAAE,UAAU,QAAQ,SAAS,QAAQ,UAAU;AAAA,MAC/C,CAAC,OAAO,WAAW;AACjB,YAAI,OAAO;AACT,iBAAO,KAAK;AACZ;AAAA,QACF;AACA,QAAAA,UAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,sBAAsB,QAAkC;AACtE,QAAM,QAAQ,OAAO,MAAM,6BAA6B;AACxD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,CAAC,EAAE,YAAY;AACpC,MAAI,WAAW,iBAAiB;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,WAAW,YAAY;AACzB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,eAAsB,qBACpB,gBAA+B,YACJ;AAC3B,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,CAAC,MAAM,MAAM;AAAA,IACb,EAAE,WAAW,iBAAiB;AAAA,EAChC;AACA,SAAO,sBAAsB,MAAM;AACrC;AAEA,IAAM,gCAAN,MAAwE;AAAA,EAItE,YACmB,iBACR,gBACT;AAFiB;AACR;AAAA,EACR;AAAA,EAFgB;AAAA,EACR;AAAA,EALH,aAA6B;AAAA,EAC7B,kBAAkB;AAAA,EAO1B,WAA6B;AAC3B,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEA,MAAc,mBAAqC;AACjD,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,gBAAgB;AAC1C,UAAI,WAAW,WAAW;AACxB,cAAM,IAAI,MAAM,6CAA6C;AAAA,MAC/D;AAEA,WAAK,kBAAkB;AACvB,YAAM,SAAS,WAAW;AAC1B,UAAI,UAAU,KAAK,eAAe,MAAM;AACtC,gBAAQ,KAAK,iFAAiF;AAAA,MAChG,WAAW,CAAC,UAAU,KAAK,eAAe,MAAM;AAC9C,gBAAQ,KAAK,2EAA2E;AAAA,MAC1F;AACA,WAAK,aAAa;AAClB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,CAAC,KAAK,iBAAiB;AACzB,gBAAQ;AAAA,UACN,mGAAmG,gBAAgB,KAAK,CAAC;AAAA,QAC3H;AACA,aAAK,kBAAkB;AAAA,MACzB;AACA,WAAK,aAAa;AAClB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEO,SAAS,+BACd,gBACA,UAA2C,CAAC,GACX;AACjC,QAAMC,YAAW,QAAQ,YAAY,QAAQ;AAC7C,MAAI,CAAC,kBAAkBA,cAAa,UAAU;AAC5C,WAAO;AAAA,EACT;AAEA,SAAO,IAAI;AAAA,IACT,QAAQ,mBAAmB;AAAA,IAC3B,QAAQ,kBAAkB;AAAA,EAC5B;AACF;;;AHlDA,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AACzB,IAAM,eAAe,oBAAI,IAAkC;AAC3D,IAAM,2BAA2B,oBAAI,IAAoB;AACzD,IAAM,iCAAiC,oBAAI,IAA2B;AAEtE,IAAM,0BAAN,cAAsC,MAAM;AAAA,EAC1C,cAAc;AACZ,UAAM,uCAAuC;AAC7C,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,MAAc;AACrB,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAEA,SAAS,iBAAiB,YAA4B;AACpD,QAAM,WAAgB,eAAQ,UAAU;AACxC,UAAI,uBAAW,QAAQ,GAAG;AACxB,QAAI;AACF,aAAO,wBAAa,OAAO,QAAQ;AAAA,IACrC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,SAAc,eAAQ,QAAQ;AACpC,MAAI,WAAW,SAAU,QAAO;AAChC,SAAY,YAAK,iBAAiB,MAAM,GAAQ,gBAAS,QAAQ,CAAC;AACpE;AAEO,SAAS,gBAAgB,aAA8B;AAC5D,SAAO,iBAAiB,WAAW,MAAM,iBAAoB,YAAQ,CAAC;AACxE;AAEA,SAAS,iBAAiB,aAAqB,MAAwB;AACrE,SAAO,GAAG,IAAI,KAAK,iBAAiB,WAAW,CAAC;AAClD;AAEA,SAAS,eACP,aACA,QACA,MACQ;AACR,QAAM,uBAAuB,iBAAiB,WAAW;AACzD,QAAM,YAAY,wBAAwB,aAAa,OAAO,OAAO,IAAI;AACzE,SAAO,GAAG,iBAAiB,SAAS,CAAC,KAAK,oBAAoB;AAChE;AAEA,SAAS,iBACP,aACA,QAC4D;AAC5D,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO,EAAE,WAAW,OAAO,eAAe,iBAAiB;AAAA,EAC7D;AACA,MAAI,OAAO,SAAS,wBAAwB,CAAC,iBAAiB,WAAW,GAAG;AAC1E,WAAO,EAAE,WAAW,OAAO,eAAe,yBAAyB;AAAA,EACrE;AACA,SAAO,EAAE,WAAW,KAAK;AAC3B;AAEA,SAASC,qBAAoB,UAAiC;AAC5D,MAAI,SAAS,UAAU,WAAY,QAAO;AAC1C,MAAI,SAAS,UAAU,WAAY,QAAO;AAC1C,MAAI,SAAS,UAAU,WAAW;AAChC,WAAO,SAAS,eAAe,IAC3B,IACA,KAAK,MAAM,IAAK,SAAS,iBAAiB,SAAS,aAAc,EAAE;AAAA,EACzE;AACA,MAAI,SAAS,UAAU,aAAa;AAClC,WAAO,SAAS,gBAAgB,IAC5B,KACA,KAAK,MAAM,KAAM,SAAS,kBAAkB,SAAS,cAAe,EAAE;AAAA,EAC5E;AACA,MAAI,SAAS,UAAU,UAAW,QAAO;AACzC,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAwB;AAClD,MAAI,+BAA+B,KAAK,GAAG;AACzC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAAiB,QAAoC;AAC7E,MAAI,OAAO,QAAS,QAAO,QAAQ,OAAO,IAAI,wBAAwB,CAAC;AACvE,SAAO,IAAI,QAAc,CAACC,WAAS,WAAW;AAC5C,UAAM,QAAQ,WAAW,MAAM;AAC7B,aAAO,oBAAoB,SAAS,OAAO;AAC3C,MAAAA,UAAQ;AAAA,IACV,GAAG,OAAO;AACV,UAAM,QAAQ;AACd,UAAM,UAAU,MAAM;AACpB,mBAAa,KAAK;AAClB,aAAO,IAAI,wBAAwB,CAAC;AAAA,IACtC;AACA,WAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EAC1D,CAAC;AACH;AAEA,SAAS,YAAe,SAAqB,WAA2C;AACtF,MAAI,aAAa,EAAG,QAAO,QAAQ,QAAQ,MAAS;AACpD,SAAO,IAAI,QAAuB,CAACA,cAAY;AAC7C,UAAM,QAAQ,WAAW,MAAMA,UAAQ,MAAS,GAAG,SAAS;AAC5D,UAAM,QAAQ;AACd,SAAK,QAAQ,KAAK,CAAC,UAAU;AAC3B,mBAAa,KAAK;AAClB,MAAAA,UAAQ,KAAK;AAAA,IACf,GAAG,MAAM;AACP,mBAAa,KAAK;AAClB,MAAAA,UAAQ,MAAS;AAAA,IACnB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,gBAAgB,SAA+B;AACtD,MAAI,QAAQ,MAAO,QAAO;AAC1B,MAAI,QAAQ,WAAW,SAAU,QAAO;AACxC,MAAI,QAAQ,WAAW,UAAW,QAAO;AACzC,SAAO;AACT;AAEA,SAAS,cAAc,SAA8B,MAAkC;AACrF,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,YAAY,gBAAgB,IAAI,IAAI,gBAAgB,OAAO,IAAI,OAAO;AAC5E,SAAO;AAAA,IACL,gBAAgB,QAAQ,kBAAkB,KAAK;AAAA,IAC/C,OAAO,QAAQ,SAAS,KAAK;AAAA,IAC7B,YAAY,KAAK,cAAc,QAAQ;AAAA,IACvC,QAAQ,UAAU;AAAA,EACpB;AACF;AAEA,IAAM,uBAAN,MAA2B;AAAA,EACjB;AAAA,EACA;AAAA,EACA,aAA4B,QAAQ,QAAQ;AAAA,EAC5C,WAAmD;AAAA,EACnD,gBAAqC;AAAA,EACrC,eAAuD;AAAA,EACvD,kBAA0D;AAAA,EAC1D,yBAA8C;AAAA,EAC9C,oBAA0D;AAAA,EAC1D,sBAA2C;AAAA,EAC3C,iBAAsC;AAAA,EACtC,kBAA0D;AAAA,EAC1D,kBAA0C;AAAA,EAC1C,UAAU;AAAA,EAElB,YAAY,cAAqC;AAC/C,SAAK,eAAe;AACpB,SAAK,SAAS;AAAA,MACZ,SAAS,aAAa,OAAO,SAAS;AAAA,MACtC,OAAO;AAAA,MACP,WAAW,IAAI;AAAA,MACf,eAAe,aAAa;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,OAAO,cAA2C;AAChD,UAAM,wBAAwB,aAAa,OAAO,SAAS,qCACrD,KAAK,aAAa,OAAO,SAAS;AACxC,SAAK,eAAe;AACpB,SAAK,OAAO,UAAU,aAAa,OAAO,SAAS;AACnD,SAAK,OAAO,gBAAgB,aAAa;AACzC,SAAK,OAAO,YAAY,IAAI;AAC5B,QAAI,KAAK,SAAS;AAChB,WAAK,UAAU;AACf,WAAK,OAAO,QAAQ;AAAA,IACtB;AACA,QAAI,CAAC,aAAa,OAAO,SAAS,aAAa,KAAK,eAAe,WAAW,UAAU;AACtF,WAAK,iBAAiB;AACtB,WAAK,iBAAiB,MAAM;AAC5B,UAAI,CAAC,KAAK,UAAU;AAClB,aAAK,SAAS,QAAQ,EAAE,QAAQ,OAAU,CAAC;AAAA,MAC7C;AAAA,IACF;AACA,QAAI,uBAAuB;AACzB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,cAAc,YAAiC;AAC7C,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,WAAoC;AAClC,SAAK,cAAc;AACnB,WAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR,UAAU,KAAK,OAAO,WAAW,EAAE,GAAG,KAAK,OAAO,SAAS,IAAI;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,QAAyE;AAC7E,SAAK,cAAc;AACnB,QAAI,CAAC,KAAK,aAAa,OAAO,SAAS,aAAa,CAAC,KAAK,aAAa,UAAW,QAAO;AACzF,QAAI,KAAK,OAAO,UAAU,SAAU,QAAO,KAAK;AAChD,WAAO,KAAK,QAAQ,EAAE,gBAAgB,MAAM,OAAO,OAAO,OAAO,CAAC;AAAA,EACpE;AAAA,EAEA,QAAQ,SAAwD;AAC9D,QAAI,KAAK,SAAS;AAChB,aAAO,QAAQ,QAAQ,EAAE,SAAS,UAAU,CAAC;AAAA,IAC/C;AACA,WAAO,KAAK,WAAW,KAAK,MAAM,KAAK,2BAA2B,OAAO,CAAC;AAAA,EAC5E;AAAA,EAEQ,2BAA2B,SAAwD;AACzF,QAAI,CAAC,KAAK,sBAAsB,OAAO,GAAG;AACxC,aAAO,KAAK,eAAe,OAAO;AAAA,IACpC;AAEA,QAAI,KAAK,gBAAgB,KAAK,oBAAoB,QAAQ,KAAK,oBAAoB,KAAK,UAAU;AAChG,aAAO,KAAK,eAAe,OAAO;AAAA,IACpC;AAEA,SAAK,yBAAyB,cAAc,KAAK,wBAAwB,OAAO;AAChF,QAAI,KAAK,cAAc;AACrB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,eAAe,KAAK,eAAe;AACzC,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,MAChB,MAAM,KAAK,mBAAmB,YAAY;AAAA,MAC1C,MAAM,KAAK,mBAAmB,YAAY;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,SAAwD;AAC7E,QAAI,KAAK,WAAW,CAAC,KAAK,OAAO,OAAO,GAAG;AACzC,aAAO,QAAQ,QAAQ,EAAE,SAAS,UAAU,CAAC;AAAA,IAC/C;AACA,QAAI,KAAK,UAAU;AACjB,UAAI,QAAQ,SAAS,CAAC,KAAK,eAAe,OAAO;AAC/C,aAAK,iBAAiB,cAAc,KAAK,gBAAgB,OAAO;AAChE,aAAK,iBAAiB,MAAM;AAC5B,cAAM,SAAS,KAAK;AACpB,eAAO,OAAO,KAAK,MAAM;AACvB,cAAI,KAAK,QAAS,QAAO,EAAE,SAAS,UAAU;AAC9C,iBAAO,KAAK,YAAY,KAAK,aAAa,OAAO;AAAA,QACnD,CAAC;AAAA,MACH;AACA,UAAI,QAAQ,WAAW,WAAW;AAChC,aAAK,iBAAiB,cAAc,KAAK,gBAAgB,OAAO;AAChE,cAAM,SAAS,KAAK;AACpB,eAAO,OAAO,KAAK,MAAM;AACvB,cAAI,KAAK,QAAS,QAAO,EAAE,SAAS,UAAU;AAC9C,iBAAO,KAAK,mBAAmB,EAAE,SAAS,UAAU;AAAA,QACtD,CAAC;AAAA,MACH;AACA,aAAO,KAAK;AAAA,IACd;AACA,WAAO,KAAK,aAAa,OAAO;AAAA,EAClC;AAAA,EAEA,aAAqD;AACnD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAiC;AAC/B,WAAO,KAAK,aAAa,WAAW;AAAA,EACtC;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK,aAAa,OAAO,SAAS;AAAA,EAC3C;AAAA,EAEA,MAAM,KAAK,oBAAoB,OAAsB;AACnD,SAAK,UAAU;AACf,SAAK,yBAAyB;AAC9B,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AACtB,SAAK,iBAAiB,MAAM;AAC5B,SAAK,SAAS,WAAW;AAAA,MACvB,aAAa,IAAI;AAAA,MACjB,aAAa;AAAA,MACb,UAAU;AAAA,MACV,cAAc;AAAA,IAChB,CAAC;AACD,UAAM,WAAW,KAAK;AACtB,QAAI,UAAU;AACZ,UAAI,mBAAmB;AACrB,cAAM;AAAA,MACR,OAAO;AACL,cAAM,YAAY,UAAU,gBAAgB;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,aAAa,SAAwD;AAC3E,QAAI,KAAK,WAAW,CAAC,KAAK,OAAO,OAAO,GAAG;AACzC,aAAO,QAAQ,QAAQ,EAAE,SAAS,UAAU,CAAC;AAAA,IAC/C;AACA,SAAK,gBAAgB;AACrB,UAAM,MAAM,KAAK,IAAI,OAAO;AAC5B,SAAK,WAAW;AAChB,SAAK,IAAI,KAAK,MAAM;AAClB,UAAI,KAAK,aAAa,IAAK;AAC3B,WAAK,WAAW;AAChB,WAAK,gBAAgB;AACrB,WAAK,kBAAkB;AACvB,UAAI,KAAK,oBAAoB,KAAK;AAChC,aAAK,kBAAkB;AACvB,aAAK,eAAe;AAAA,MACtB;AACA,YAAM,UAAU,KAAK;AACrB,WAAK,iBAAiB;AACtB,UAAI,WAAW,CAAC,KAAK,SAAS;AAC5B,cAAM,WAAW,KAAK,QAAQ,OAAO;AACrC,aAAK,kBAAkB;AACvB,aAAK,SAAS,KAAK,MAAM;AACvB,cAAI,KAAK,oBAAoB,UAAU;AACrC,iBAAK,kBAAkB;AAAA,UACzB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,IAAI,SAAwD;AACxE,UAAM,aAAa,IAAI,gBAAgB;AACvC,SAAK,kBAAkB;AACvB,UAAM,YAAY,IAAI;AACtB,SAAK,SAAS,YAAY;AAAA,MACxB,aAAa;AAAA,MACb,SAAS;AAAA,MACT,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU;AAAA,MACV,cAAc;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB;AAAA,IACF,CAAC;AAED,UAAM,aAAa,QAAQ,WAAW,WAClC,IACA,KAAK,aAAa,OAAO,SAAS;AACtC,QAAI,eAAe;AACnB,WAAO,MAAM;AACX,UAAI;AACF,aAAK,iBAAiB,WAAW,MAAM;AACvC,cAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,YAAI,QAAQ,kBAAkB,CAAC,QAAQ,OAAO;AAC5C,cAAI,QAAQ,mBAAmB;AAC7B,kBAAM,YAAY,MAAM,QAAQ,kBAAkB;AAClD,iBAAK,iBAAiB,WAAW,MAAM;AACvC,gBAAI,UAAU,YAAY,UAAU,SAAS;AAC3C,mBAAK,SAAS,SAAS;AAAA,gBACrB,aAAa,IAAI;AAAA,gBACjB,UAAU;AAAA,gBACV,cAAc;AAAA,cAChB,CAAC;AACD,qBAAO,EAAE,SAAS,SAAS,SAAS,KAAK;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AAEA,aAAK,SAAS,YAAY;AAAA,UACxB,aAAa;AAAA,UACb,cAAc,eAAe,IAAI,eAAe;AAAA,QAClD,CAAC;AACD,cAAM,YAAY,QAAQ,QAAQ,QAAQ,WAAW,KAAK,OAAO,IAAI,QAAQ,MAAM,KAAK,OAAO;AAC/F,cAAM,QAAQ,MAAM,UAAU,CAAC,aAAa;AAC1C,eAAK,iBAAiB,WAAW,MAAM;AACvC,kBAAQ,aAAa,QAAQ;AAC7B,eAAK,OAAO,WAAW;AAAA,YACrB,OAAO,SAAS;AAAA,YAChB,gBAAgB,SAAS;AAAA,YACzB,YAAY,SAAS;AAAA,YACrB,iBAAiB,SAAS;AAAA,YAC1B,aAAa,SAAS;AAAA,YACtB,YAAYD,qBAAoB,QAAQ;AAAA,UAC1C;AACA,eAAK,OAAO,YAAY,IAAI;AAAA,QAC9B,CAAC;AACD,aAAK,iBAAiB,WAAW,MAAM;AACvC,YAAI,QAAQ,WAAW,aAAa,QAAQ,WAAW,aAAa;AAClE,gBAAM,eAAe,MAAM,KAAK,aAAa,WAAW,EAAE,UAAU;AACpE,cAAI,CAAC,aAAa,SAAS;AACzB,kBAAM,QAAQ,IAAI,MAAM,uDAAuD;AAC/E,iBAAK,SAAS,UAAU;AAAA,cACtB,aAAa,IAAI;AAAA,cACjB,SAAS,IAAI;AAAA,cACb,WAAW;AAAA,cACX,UAAU;AAAA,YACZ,CAAC;AACD,mBAAO,EAAE,SAAS,UAAU,OAAO,MAAM;AAAA,UAC3C;AAAA,QACF;AACA,aAAK,SAAS,SAAS;AAAA,UACrB,aAAa,IAAI;AAAA,UACjB,UAAU,KAAK,OAAO,WAClB,EAAE,GAAG,KAAK,OAAO,UAAU,OAAO,YAAY,YAAY,IAAI,IAC9D;AAAA,UACJ,cAAc;AAAA,QAChB,CAAC;AACD,eAAO,EAAE,SAAS,SAAS,MAAM;AAAA,MACnC,SAAS,OAAO;AACd,YAAI,iBAAiB,2BAA2B,WAAW,OAAO,SAAS;AACzE,cAAI,KAAK,SAAS;AAChB,iBAAK,SAAS,WAAW,EAAE,aAAa,IAAI,GAAG,UAAU,OAAU,CAAC;AACpE,mBAAO,EAAE,SAAS,UAAU;AAAA,UAC9B;AACA,cAAI,CAAC,KAAK,aAAa,OAAO,SAAS,aAAa,QAAQ,WAAW,UAAU;AAC/E,iBAAK,SAAS,QAAQ;AAAA,cACpB,aAAa,IAAI;AAAA,cACjB,UAAU;AAAA,cACV,QAAQ;AAAA,YACV,CAAC;AACD,mBAAO,EAAE,SAAS,UAAU;AAAA,UAC9B;AACA,iBAAO,EAAE,SAAS,UAAU;AAAA,QAC9B;AAEA,YAAI,+BAA+B,KAAK,KAAK,eAAe,YAAY;AACtE,0BAAgB;AAChB,gBAAM,UAAU,KAAK;AAAA,YACnB,KAAK,aAAa,OAAO,SAAS,wBAAyB,MAAM,eAAe;AAAA,YAChF;AAAA,UACF;AACA,gBAAM,cAAc,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,EAAE,YAAY;AAC/D,eAAK,SAAS,iBAAiB;AAAA,YAC7B;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV;AAAA,UACF,CAAC;AACD,cAAI;AACF,kBAAM,iBAAiB,SAAS,WAAW,MAAM;AAAA,UACnD,SAAS,YAAY;AACnB,gBAAI,sBAAsB,yBAAyB;AACjD,kBAAI,KAAK,SAAS;AAChB,qBAAK,SAAS,WAAW,EAAE,aAAa,IAAI,GAAG,UAAU,OAAU,CAAC;AAAA,cACtE;AACA,qBAAO,EAAE,SAAS,UAAU;AAAA,YAC9B;AACA,kBAAM;AAAA,UACR;AACA,eAAK,SAAS,YAAY,EAAE,aAAa,OAAU,CAAC;AACpD;AAAA,QACF;AAEA,cAAM,UAAU,IAAI;AACpB,aAAK,SAAS,UAAU;AAAA,UACtB,aAAa;AAAA,UACb;AAAA,UACA,WAAW,mBAAmB,KAAK;AAAA,UACnC,aAAa;AAAA,UACb,UAAU;AAAA,UACV,cAAc,eAAe,IAAI,eAAe;AAAA,QAClD,CAAC;AACD,eAAO,EAAE,SAAS,UAAU,MAAM;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,SACN,OACA,UAA4C,CAAC,GACvC;AACN,QAAI,KAAK,WAAW,UAAU,UAAW;AACzC,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,MACH,SAAS,KAAK,aAAa,OAAO,SAAS;AAAA,MAC3C;AAAA,MACA,WAAW,IAAI;AAAA,MACf,eAAe,KAAK,aAAa;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,iBAAiB,QAA2B;AAClD,QAAI,OAAO,QAAS,OAAM,IAAI,wBAAwB;AAAA,EACxD;AAAA,EAEQ,gBAAsB;AAC5B,UAAM,wBAAwB,KAAK,aAAa;AAChD,UAAM,SAAS,iBAAiB,KAAK,aAAa,aAAa,KAAK,aAAa,MAAM;AACvF,SAAK,aAAa,YAAY,OAAO;AACrC,SAAK,aAAa,gBAAgB,OAAO;AACzC,SAAK,OAAO,gBAAgB,OAAO;AACnC,QAAI,0BAA0B,OAAO,eAAe;AAClD,WAAK,OAAO,YAAY,IAAI;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,OAAO,SAAgC;AAC7C,SAAK,cAAc;AACnB,QAAI,QAAQ,WAAW,YAAY,QAAQ,WAAW,WAAW;AAC/D,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,aAAa,aAAa,KAAK,aAAa,OAAO,SAAS;AAAA,EAC1E;AAAA,EAEQ,sBAAsB,SAAgC;AAC5D,WAAO,KAAK,aAAa,6BAA6B,SAChD,QAAQ,WAAW,aAAa,QAAQ,WAAW;AAAA,EAC3D;AAAA,EAEA,MAAc,iBAAkD;AAC9D,WAAO,CAAC,KAAK,SAAS;AACpB,YAAM,SAAS,KAAK,aAAa;AACjC,UAAI,CAAC,UAAU,CAAC,MAAM,KAAK,qBAAqB,MAAM,GAAG;AACvD,cAAM,UAAU,KAAK;AACrB,aAAK,yBAAyB;AAC9B,YAAI,CAAC,QAAS,QAAO,EAAE,SAAS,UAAU;AAC1C,cAAM,MAAM,KAAK,eAAe,OAAO;AACvC,YAAI,KAAK,aAAa,KAAK;AACzB,eAAK,kBAAkB;AAAA,QACzB;AACA,eAAO;AAAA,MACT;AACA,YAAM,KAAK,oBAAoB,OAAO,cAAc;AAAA,IACtD;AACA,WAAO,EAAE,SAAS,UAAU;AAAA,EAC9B;AAAA,EAEA,MAAc,qBAAqB,QAAoD;AACrF,QAAI;AACF,aAAO,MAAM,OAAO,SAAS;AAAA,IAC/B,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,6GAA6G,mBAAmB,KAAK,CAAC;AAAA,MACxI;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,oBAAoB,SAAgC;AAC1D,WAAO,IAAI,QAAc,CAACC,cAAY;AACpC,YAAM,QAAQ,WAAW,MAAM;AAC7B,YAAI,KAAK,sBAAsB,OAAO;AACpC,eAAK,oBAAoB;AACzB,eAAK,sBAAsB;AAAA,QAC7B;AACA,QAAAA,UAAQ;AAAA,MACV,GAAG,OAAO;AACV,YAAM,QAAQ;AACd,WAAK,oBAAoB;AACzB,WAAK,sBAAsBA;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEQ,qBAA2B;AACjC,QAAI,KAAK,mBAAmB;AAC1B,mBAAa,KAAK,iBAAiB;AACnC,WAAK,oBAAoB;AAAA,IAC3B;AACA,UAAMA,YAAU,KAAK;AACrB,SAAK,sBAAsB;AAC3B,IAAAA,YAAU;AAAA,EACZ;AAAA,EAEQ,mBAAmB,cAAqD;AAC9E,QAAI,KAAK,iBAAiB,aAAc;AACxC,SAAK,eAAe;AACpB,UAAM,kBAAkB,KAAK;AAC7B,SAAK,yBAAyB;AAC9B,QAAI,mBAAmB,CAAC,KAAK,SAAS;AACpC,WAAK,KAAK,QAAQ,eAAe;AAAA,IACnC;AAAA,EACF;AACF;AAEA,SAAS,eAAe,aAAqB,MAA6C;AACxF,QAAM,MAAM,yBAAyB,IAAI,iBAAiB,aAAa,IAAI,CAAC;AAC5E,SAAO,MAAM,aAAa,IAAI,GAAG,KAAK,OAAO;AAC/C;AAEO,SAAS,mBACd,aACA,MACA,QACA,YACM;AACN,QAAM,aAAa,iBAAiB,aAAa,IAAI;AACrD,QAAM,SAAS,iBAAiB,aAAa,MAAM;AACnD,QAAM,eAAsC;AAAA,IAC1C,0BAA0B;AAAA,MACxB,OAAO,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AACA,QAAM,MAAM,eAAe,aAAa,QAAQ,IAAI;AACpD,QAAM,cAAc,yBAAyB,IAAI,UAAU;AAC3D,MAAI,eAAe,gBAAgB,KAAK;AACtC,UAAM,sBAAsB,aAAa,IAAI,WAAW;AACxD,UAAM,kBAAkB,+BAA+B,IAAI,UAAU,KAAK,QAAQ,QAAQ;AAC1F,UAAM,eAAe,qBAAqB,KAAK,IAAI,KAAK,QAAQ,QAAQ;AACxE,UAAM,aAAa,QAAQ,IAAI,CAAC,iBAAiB,YAAY,CAAC,EAAE,KAAK,MAAM,MAAS;AACpF,mCAA+B,IAAI,YAAY,UAAU;AACzD,iBAAa,OAAO,WAAW;AAE/B,UAAMC,eAAc,IAAI,qBAAqB,YAAY;AACzD,IAAAA,aAAY,cAAc,UAAU;AACpC,iBAAa,IAAI,KAAKA,YAAW;AACjC,6BAAyB,IAAI,YAAY,GAAG;AAC5C;AAAA,EACF;AAEA,MAAI,cAAc,aAAa,IAAI,GAAG;AACtC,MAAI,CAAC,aAAa;AAChB,kBAAc,IAAI,qBAAqB,YAAY;AACnD,iBAAa,IAAI,KAAK,WAAW;AAAA,EACnC,OAAO;AACL,gBAAY,OAAO,YAAY;AAAA,EACjC;AACA,2BAAyB,IAAI,YAAY,GAAG;AAC9C;AAqBO,SAAS,oBACd,aACA,MACA,OACA,YACwC;AACxC,SAAO,eAAe,aAAa,IAAI,GAAG,QAAQ;AAAA,IAChD,gBAAgB,CAAC;AAAA,IACjB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,CAAC,KAAK;AACR;AAEO,SAAS,mBACd,aACA,MACyB;AACzB,SAAO,eAAe,aAAa,IAAI,GAAG,SAAS,KAAK;AAAA,IACtD,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW,IAAI;AAAA,EACjB;AACF;AAEA,eAAsB,6BACpB,aACA,MACmC;AACnC,QAAM,cAAc,eAAe,aAAa,IAAI;AACpD,MAAI,CAAC,YAAa,QAAO,EAAE,OAAO,KAAK;AACvC,QAAM,UAAU,YAAY,SAAS;AACrC,MAAI,CAAC,QAAQ,QAAS,QAAO,EAAE,OAAO,KAAK;AAC3C,MAAI,QAAQ,kBAAkB,kBAAkB;AAC9C,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AACA,MAAI,QAAQ,kBAAkB,0BAA0B;AACtD,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI;AACF,QAAI,MAAM,wBAAwB,WAAW,EAAG,QAAO,EAAE,OAAO,KAAK;AAAA,EACvE,QAAQ;AAAA,EAER;AAEA,QAAM,MAAM,YAAY,MAAM,WAAW,KAAK,YAAY,WAAW;AACrE,MAAI,KAAK;AACP,UAAM,YAAY,KAAK,YAAY,UAAU,CAAC;AAAA,EAChD;AAEA,MAAI;AACF,QAAI,MAAM,wBAAwB,WAAW,EAAG,QAAO,EAAE,OAAO,KAAK;AAAA,EACvE,QAAQ;AAAA,EAER;AAEA,QAAM,SAAS,YAAY,SAAS;AACpC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM,4BAA4B,OAAO,UAAU,OAAO,OAAO,OAAO,KAAK,EAAE,KAAK,OAAO,aAAa,8CAA8C;AAAA,IACxJ;AAAA,EACF;AACA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,yBAAyB,OAAO,KAAK;AAAA,EAC7C;AACF;AAqBA,eAAe,wBAAwB,aAAqD;AAC1F,QAAM,UAAU,YAAY,WAAW;AACvC,MAAI,QAAQ,mBAAmB;AAC7B,UAAM,YAAY,MAAM,QAAQ,kBAAkB;AAClD,WAAO,UAAU,YAAY,UAAU;AAAA,EACzC;AACA,UAAQ,MAAM,QAAQ,UAAU,GAAG;AACrC;;;AI9zBA,IAAAC,aAAqD;AACrD,IAAAC,SAAsB;AAOtB,SAAS,4BACP,QACA,aACyB;AACzB,QAAM,aAAa,EAAE,GAAG,OAAO;AAE/B,MAAI,MAAM,QAAQ,WAAW,cAAc,GAAG;AAC5C,eAAW,iBAAkB,WAAW,eAA4B;AAAA,MAAI,CAAC,OACvE,uBAAuB,IAAI,WAAW;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,WAA6C;AACnE,MAAI,CAAC,aAAa,OAAO,cAAc,UAAU;AAC/C,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,EAAE,GAAI,UAAsC;AACrD;AAMO,SAAS,kBAAkB,aAAqB,MAAyC;AAC9F,SAAO,4BAA4B,eAAe,iBAAiB,aAAa,IAAI,CAAC,GAAG,WAAW;AACrG;;;ACrCA,IAAAC,cAA6H;AAC7H,IAAAC,SAAsB;AACtB,wBAA4B;AAC5B,IAAAC,wBAAyB;AACzB,IAAAC,eAA0B;;;ACJ1B,mBAAyB;;;ACAlB,IAAM,eAAN,MAAM,sBAAqB,MAAM;AAAA,EACvC,OAAO;AAAA,EAEP,YAAY,SAAS,SAAS;AAC7B,UAAM,SAAS,OAAO;AACtB,UAAM,oBAAoB,MAAM,aAAY;AAAA,EAC7C;AACD;AAEA,IAAM,mBAAmB,YAAU,OAAO,UAAU,IAAI,aAAa,+BAA+B,YAAY;AAEjG,SAAR,SAA0B,SAAS,SAAS;AAClD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,EAAC,YAAY,aAAY;AAAA,IACxC;AAAA,EACD,IAAI;AAEJ,MAAI;AACJ,MAAI;AAEJ,QAAM,iBAAiB,IAAI,QAAQ,CAACC,WAAS,WAAW;AACvD,QAAI,OAAO,iBAAiB,YAAY,KAAK,KAAK,YAAY,MAAM,GAAG;AACtE,YAAM,IAAI,UAAU,4DAA4D,YAAY,IAAI;AAAA,IACjG;AAEA,QAAI,QAAQ,SAAS;AACpB,aAAO,iBAAiB,MAAM,CAAC;AAC/B;AAAA,IACD;AAEA,QAAI,QAAQ;AACX,qBAAe,MAAM;AACpB,eAAO,iBAAiB,MAAM,CAAC;AAAA,MAChC;AAEA,aAAO,iBAAiB,SAAS,cAAc,EAAC,MAAM,KAAI,CAAC;AAAA,IAC5D;AAIA,YAAQ,KAAKA,WAAS,MAAM;AAE5B,QAAI,iBAAiB,OAAO,mBAAmB;AAC9C;AAAA,IACD;AAGA,UAAM,eAAe,IAAI,aAAa;AAGtC,YAAQ,aAAa,WAAW,KAAK,QAAW,MAAM;AACrD,UAAI,UAAU;AACb,YAAI;AACH,UAAAA,UAAQ,SAAS,CAAC;AAAA,QACnB,SAAS,OAAO;AACf,iBAAO,KAAK;AAAA,QACb;AAEA;AAAA,MACD;AAEA,UAAI,OAAO,QAAQ,WAAW,YAAY;AACzC,gBAAQ,OAAO;AAAA,MAChB;AAEA,UAAI,YAAY,OAAO;AACtB,QAAAA,UAAQ;AAAA,MACT,WAAW,mBAAmB,OAAO;AACpC,eAAO,OAAO;AAAA,MACf,OAAO;AACN,qBAAa,UAAU,WAAW,2BAA2B,YAAY;AACzE,eAAO,YAAY;AAAA,MACpB;AAAA,IACD,GAAG,YAAY;AAAA,EAChB,CAAC;AAGD,QAAM,oBAAoB,eAAe,QAAQ,MAAM;AACtD,sBAAkB,MAAM;AACxB,QAAI,gBAAgB,QAAQ;AAC3B,aAAO,oBAAoB,SAAS,YAAY;AAAA,IACjD;AAAA,EACD,CAAC;AAED,oBAAkB,QAAQ,MAAM;AAE/B,iBAAa,aAAa,KAAK,QAAW,KAAK;AAC/C,YAAQ;AAAA,EACT;AAEA,SAAO;AACR;;;AC5Fe,SAAR,WAA4B,OAAO,OAAO,YAAY;AACzD,MAAI,QAAQ;AACZ,MAAI,QAAQ,MAAM;AAClB,SAAO,QAAQ,GAAG;AACd,UAAM,OAAO,KAAK,MAAM,QAAQ,CAAC;AACjC,QAAI,KAAK,QAAQ;AACjB,QAAI,WAAW,MAAM,EAAE,GAAG,KAAK,KAAK,GAAG;AACnC,cAAQ,EAAE;AACV,eAAS,OAAO;AAAA,IACpB,OACK;AACD,cAAQ;AAAA,IACZ;AAAA,EACJ;AACA,SAAO;AACX;;;AChBA,IAAqB,gBAArB,MAAmC;AAAA,EAC/B,SAAS,CAAC;AAAA,EACV,QAAQ,KAAK,SAAS;AAClB,UAAM,EAAE,WAAW,GAAG,GAAI,IAAI,WAAW,CAAC;AAC1C,UAAM,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,IACJ;AACA,QAAI,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK,OAAO,CAAC,EAAE,YAAY,UAAU;AACpE,WAAK,OAAO,KAAK,OAAO;AACxB;AAAA,IACJ;AACA,UAAM,QAAQ,WAAW,KAAK,QAAQ,SAAS,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAChF,SAAK,OAAO,OAAO,OAAO,GAAG,OAAO;AAAA,EACxC;AAAA,EACA,YAAY,IAAI,UAAU;AACtB,UAAM,QAAQ,KAAK,OAAO,UAAU,CAAC,YAAY,QAAQ,OAAO,EAAE;AAClE,QAAI,UAAU,IAAI;AACd,YAAM,IAAI,eAAe,oCAAoC,EAAE,wBAAwB;AAAA,IAC3F;AACA,UAAM,CAAC,IAAI,IAAI,KAAK,OAAO,OAAO,OAAO,CAAC;AAC1C,SAAK,QAAQ,KAAK,KAAK,EAAE,UAAU,GAAG,CAAC;AAAA,EAC3C;AAAA,EACA,OAAO,SAAS;AACZ,UAAM,QAAQ,KAAK,OAAO,UAAU,CAAC,YAAY;AAC7C,UAAI,OAAO,YAAY,UAAU;AAC7B,eAAO,QAAQ,OAAO;AAAA,MAC1B;AACA,aAAO,QAAQ,QAAQ;AAAA,IAC3B,CAAC;AACD,QAAI,UAAU,IAAI;AACd,WAAK,OAAO,OAAO,OAAO,CAAC;AAAA,IAC/B;AAAA,EACJ;AAAA,EACA,UAAU;AACN,UAAM,OAAO,KAAK,OAAO,MAAM;AAC/B,WAAO,MAAM;AAAA,EACjB;AAAA,EACA,OAAO,SAAS;AACZ,WAAO,KAAK,OAAO,OAAO,CAAC,YAAY,QAAQ,aAAa,QAAQ,QAAQ,EAAE,IAAI,CAAC,YAAY,QAAQ,GAAG;AAAA,EAC9G;AAAA,EACA,IAAI,OAAO;AACP,WAAO,KAAK,OAAO;AAAA,EACvB;AACJ;;;ACxCA,IAAqB,SAArB,cAAoC,aAAAC,QAAa;AAAA,EAC7C;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B;AAAA,EACA,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA,eAAe,CAAC;AAAA,EAChB,yBAAyB;AAAA,EACzB;AAAA,EACA;AAAA,EACA,WAAW;AAAA;AAAA,EAEX;AAAA,EACA;AAAA;AAAA,EAEA,cAAc;AAAA;AAAA,EAEd,gBAAgB,oBAAI,IAAI;AAAA,EACxB,sCAAsC,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB9C;AAAA,EACA,YAAY,SAAS;AACjB,UAAM;AAEN,cAAU;AAAA,MACN,wBAAwB;AAAA,MACxB,aAAa,OAAO;AAAA,MACpB,UAAU;AAAA,MACV,aAAa,OAAO;AAAA,MACpB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,GAAG;AAAA,IACP;AACA,QAAI,EAAE,OAAO,QAAQ,gBAAgB,YAAY,QAAQ,eAAe,IAAI;AACxE,YAAM,IAAI,UAAU,gEAAgE,QAAQ,aAAa,SAAS,KAAK,EAAE,OAAO,OAAO,QAAQ,WAAW,GAAG;AAAA,IACjK;AACA,QAAI,QAAQ,aAAa,UAAa,EAAE,OAAO,SAAS,QAAQ,QAAQ,KAAK,QAAQ,YAAY,IAAI;AACjG,YAAM,IAAI,UAAU,2DAA2D,QAAQ,UAAU,SAAS,KAAK,EAAE,OAAO,OAAO,QAAQ,QAAQ,GAAG;AAAA,IACtJ;AACA,QAAI,QAAQ,UAAU,QAAQ,aAAa,GAAG;AAC1C,YAAM,IAAI,UAAU,oDAAoD;AAAA,IAC5E;AACA,QAAI,QAAQ,UAAU,QAAQ,gBAAgB,OAAO,mBAAmB;AACpE,YAAM,IAAI,UAAU,qDAAqD;AAAA,IAC7E;AAGA,SAAK,0BAA0B,QAAQ,0BAA0B,QAAQ,6BAA6B;AACtG,SAAK,qBAAqB,QAAQ,gBAAgB,OAAO,qBAAqB,QAAQ,aAAa;AACnG,SAAK,eAAe,QAAQ;AAC5B,SAAK,YAAY,QAAQ;AACzB,SAAK,UAAU,QAAQ;AACvB,SAAK,SAAS,IAAI,QAAQ,WAAW;AACrC,SAAK,cAAc,QAAQ;AAC3B,SAAK,cAAc,QAAQ;AAC3B,QAAI,QAAQ,YAAY,UAAa,EAAE,OAAO,SAAS,QAAQ,OAAO,KAAK,QAAQ,UAAU,IAAI;AAC7F,YAAM,IAAI,UAAU,8DAA8D,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,GAAG;AAAA,IACrI;AACA,SAAK,UAAU,QAAQ;AACvB,SAAK,YAAY,QAAQ,cAAc;AACvC,SAAK,wBAAwB;AAAA,EACjC;AAAA,EACA,oBAAoBC,MAAK;AAErB,WAAO,KAAK,yBAAyB,KAAK,aAAa,QAAQ;AAC3D,YAAM,aAAa,KAAK,aAAa,KAAK,sBAAsB;AAChE,UAAI,eAAe,UAAaA,OAAM,cAAc,KAAK,WAAW;AAChE,aAAK;AAAA,MACT,OACK;AACD;AAAA,MACJ;AAAA,IACJ;AAGA,UAAM,gBAAiB,KAAK,yBAAyB,OAAO,KAAK,yBAAyB,KAAK,aAAa,SAAS,KAC9G,KAAK,2BAA2B,KAAK,aAAa;AACzD,QAAI,eAAe;AACf,WAAK,eAAe,KAAK,aAAa,MAAM,KAAK,sBAAsB;AACvE,WAAK,yBAAyB;AAAA,IAClC;AAAA,EACJ;AAAA;AAAA,EAEA,qBAAqBA,MAAK;AACtB,QAAI,KAAK,SAAS;AACd,WAAK,aAAa,KAAKA,IAAG;AAAA,IAC9B,OACK;AACD,WAAK;AAAA,IACT;AAAA,EACJ;AAAA,EACA,wBAAwB;AACpB,QAAI,KAAK,SAAS;AAEd,UAAI,KAAK,aAAa,SAAS,KAAK,wBAAwB;AACxD,aAAK,aAAa,IAAI;AAAA,MAC1B;AAAA,IACJ,WACS,KAAK,iBAAiB,GAAG;AAC9B,WAAK;AAAA,IACT;AAAA,EACJ;AAAA,EACA,uBAAuB;AACnB,WAAO,KAAK,aAAa,SAAS,KAAK;AAAA,EAC3C;AAAA,EACA,IAAI,4BAA4B;AAC5B,QAAI,KAAK,oBAAoB;AACzB,aAAO;AAAA,IACX;AACA,QAAI,KAAK,SAAS;AAEd,aAAO,KAAK,qBAAqB,IAAI,KAAK;AAAA,IAC9C;AACA,WAAO,KAAK,iBAAiB,KAAK;AAAA,EACtC;AAAA,EACA,IAAI,8BAA8B;AAC9B,WAAO,KAAK,WAAW,KAAK;AAAA,EAChC;AAAA,EACA,QAAQ;AACJ,SAAK;AACL,QAAI,KAAK,aAAa,GAAG;AACrB,WAAK,KAAK,aAAa;AAAA,IAC3B;AACA,SAAK,mBAAmB;AACxB,SAAK,KAAK,MAAM;AAAA,EACpB;AAAA,EACA,oBAAoB;AAGhB,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,4BAA4B;AAAA,EACrC;AAAA,EACA,oBAAoBA,MAAK;AAErB,QAAI,KAAK,SAAS;AACd,WAAK,oBAAoBA,IAAG;AAE5B,YAAM,mBAAmB,KAAK,qBAAqB;AACnD,UAAI,oBAAoB,KAAK,cAAc;AACvC,cAAM,aAAa,KAAK,aAAa,KAAK,sBAAsB;AAEhE,cAAM,QAAQ,KAAK,aAAaA,OAAM;AACtC,aAAK,uBAAuB,KAAK;AACjC,eAAO;AAAA,MACX;AACA,aAAO;AAAA,IACX;AAEA,QAAI,KAAK,gBAAgB,QAAW;AAChC,YAAM,QAAQ,KAAK,eAAeA;AAClC,UAAI,QAAQ,GAAG;AAIX,YAAI,KAAK,qBAAqB,GAAG;AAC7B,gBAAM,yBAAyBA,OAAM,KAAK;AAC1C,cAAI,yBAAyB,KAAK,WAAW;AAEzC,iBAAK,uBAAuB,KAAK,YAAY,sBAAsB;AACnE,mBAAO;AAAA,UACX;AAAA,QACJ;AAEA,aAAK,iBAAkB,KAAK,0BAA2B,KAAK,WAAW;AAAA,MAC3E,OACK;AAED,aAAK,uBAAuB,KAAK;AACjC,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EACA,uBAAuB,OAAO;AAC1B,QAAI,KAAK,eAAe,QAAW;AAC/B;AAAA,IACJ;AACA,SAAK,aAAa,WAAW,MAAM;AAC/B,WAAK,kBAAkB;AAAA,IAC3B,GAAG,KAAK;AAAA,EACZ;AAAA,EACA,sBAAsB;AAClB,QAAI,KAAK,aAAa;AAClB,oBAAc,KAAK,WAAW;AAC9B,WAAK,cAAc;AAAA,IACvB;AAAA,EACJ;AAAA,EACA,qBAAqB;AACjB,QAAI,KAAK,YAAY;AACjB,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACtB;AAAA,EACJ;AAAA,EACA,qBAAqB;AACjB,QAAI,KAAK,OAAO,SAAS,GAAG;AAGxB,WAAK,oBAAoB;AACzB,WAAK,KAAK,OAAO;AACjB,UAAI,KAAK,aAAa,GAAG;AAErB,aAAK,mBAAmB;AAExB,YAAI,KAAK,WAAW,KAAK,yBAAyB,GAAG;AACjD,gBAAMA,OAAM,KAAK,IAAI;AACrB,eAAK,oBAAoBA,IAAG;AAAA,QAChC;AACA,aAAK,KAAK,MAAM;AAAA,MACpB;AACA,aAAO;AAAA,IACX;AACA,QAAI,cAAc;AAClB,QAAI,CAAC,KAAK,WAAW;AACjB,YAAMA,OAAM,KAAK,IAAI;AACrB,YAAM,wBAAwB,CAAC,KAAK,oBAAoBA,IAAG;AAC3D,UAAI,KAAK,6BAA6B,KAAK,6BAA6B;AACpE,cAAM,MAAM,KAAK,OAAO,QAAQ;AAChC,YAAI,CAAC,KAAK,oBAAoB;AAC1B,eAAK,qBAAqBA,IAAG;AAC7B,eAAK,yBAAyB;AAAA,QAClC;AACA,aAAK,KAAK,QAAQ;AAClB,YAAI;AACJ,YAAI,uBAAuB;AACvB,eAAK,4BAA4B;AAAA,QACrC;AACA,sBAAc;AAAA,MAClB;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EACA,8BAA8B;AAC1B,QAAI,KAAK,sBAAsB,KAAK,gBAAgB,QAAW;AAC3D;AAAA,IACJ;AAEA,QAAI,KAAK,SAAS;AACd;AAAA,IACJ;AACA,SAAK,cAAc,YAAY,MAAM;AACjC,WAAK,YAAY;AAAA,IACrB,GAAG,KAAK,SAAS;AACjB,SAAK,eAAe,KAAK,IAAI,IAAI,KAAK;AAAA,EAC1C;AAAA,EACA,cAAc;AAEV,QAAI,CAAC,KAAK,SAAS;AACf,UAAI,KAAK,mBAAmB,KAAK,KAAK,aAAa,KAAK,KAAK,aAAa;AACtE,aAAK,oBAAoB;AAAA,MAC7B;AACA,WAAK,iBAAiB,KAAK,0BAA0B,KAAK,WAAW;AAAA,IACzE;AACA,SAAK,cAAc;AACnB,SAAK,yBAAyB;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAIA,gBAAgB;AAEZ,WAAO,KAAK,mBAAmB,GAAG;AAAA,IAAE;AAAA,EACxC;AAAA,EACA,IAAI,cAAc;AACd,WAAO,KAAK;AAAA,EAChB;AAAA,EACA,IAAI,YAAY,gBAAgB;AAC5B,QAAI,EAAE,OAAO,mBAAmB,YAAY,kBAAkB,IAAI;AAC9D,YAAM,IAAI,UAAU,gEAAgE,cAAc,OAAO,OAAO,cAAc,GAAG;AAAA,IACrI;AACA,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCA,YAAY,IAAI,UAAU;AACtB,QAAI,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,QAAQ,GAAG;AAC5D,YAAM,IAAI,UAAU,sDAAsD,QAAQ,OAAO,OAAO,QAAQ,GAAG;AAAA,IAC/G;AACA,SAAK,OAAO,YAAY,IAAI,QAAQ;AAAA,EACxC;AAAA,EACA,MAAM,IAAI,WAAW,UAAU,CAAC,GAAG;AAE/B,cAAU;AAAA,MACN,SAAS,KAAK;AAAA,MACd,GAAG;AAAA;AAAA,MAEH,IAAI,QAAQ,OAAO,KAAK,eAAe,SAAS;AAAA,IACpD;AACA,WAAO,IAAI,QAAQ,CAACC,WAAS,WAAW;AAEpC,YAAM,aAAa,uBAAO,QAAQ,QAAQ,EAAE,EAAE;AAC9C,UAAI,2BAA2B,MAAM;AACrC,YAAM,MAAM,YAAY;AAEpB,iCAAyB;AACzB,aAAK;AAEL,aAAK,cAAc,IAAI,YAAY;AAAA,UAC/B,IAAI,QAAQ;AAAA,UACZ,UAAU,QAAQ,YAAY;AAAA;AAAA,UAC9B,WAAW,KAAK,IAAI;AAAA,UACpB,SAAS,QAAQ;AAAA,QACrB,CAAC;AACD,YAAI;AACJ,YAAI;AAGA,cAAI;AACA,oBAAQ,QAAQ,eAAe;AAAA,UACnC,SACO,OAAO;AACV,iBAAK,6BAA6B;AAElC,iBAAK,cAAc,OAAO,UAAU;AACpC,kBAAM;AAAA,UACV;AACA,eAAK,qBAAqB,KAAK,IAAI;AACnC,cAAI,YAAY,UAAU,EAAE,QAAQ,QAAQ,OAAO,CAAC;AACpD,cAAI,QAAQ,SAAS;AACjB,wBAAY,SAAS,QAAQ,QAAQ,SAAS,GAAG;AAAA,cAC7C,cAAc,QAAQ;AAAA,cACtB,SAAS,wBAAwB,QAAQ,OAAO,iBAAiB,KAAK,QAAQ,aAAa,KAAK,OAAO,IAAI;AAAA,YAC/G,CAAC;AAAA,UACL;AACA,cAAI,QAAQ,QAAQ;AAChB,kBAAM,EAAE,OAAO,IAAI;AACnB,wBAAY,QAAQ,KAAK,CAAC,WAAW,IAAI,QAAQ,CAAC,UAAUC,YAAW;AAC/D,8BAAgB,MAAM;AAClB,gBAAAA,QAAO,OAAO,MAAM;AAAA,cACxB;AACA,qBAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;AAAA,YAClE,CAAC,CAAC,CAAC;AAAA,UACX;AACA,gBAAM,SAAS,MAAM;AACrB,UAAAD,UAAQ,MAAM;AACd,eAAK,KAAK,aAAa,MAAM;AAAA,QACjC,SACO,OAAO;AACV,iBAAO,KAAK;AACZ,eAAK,KAAK,SAAS,KAAK;AAAA,QAC5B,UACA;AAEI,cAAI,eAAe;AACf,oBAAQ,QAAQ,oBAAoB,SAAS,aAAa;AAAA,UAC9D;AAEA,eAAK,cAAc,OAAO,UAAU;AAEpC,yBAAe,MAAM;AACjB,iBAAK,MAAM;AAAA,UACf,CAAC;AAAA,QACL;AAAA,MACJ;AACA,WAAK,OAAO,QAAQ,KAAK,OAAO;AAChC,YAAM,mBAAmB,MAAM;AAC3B,YAAI,KAAK,kBAAkB,eAAe;AACtC,eAAK,OAAO,OAAO,GAAG;AACtB;AAAA,QACJ;AACA,aAAK,OAAO,SAAS,QAAQ,EAAE;AAAA,MACnC;AAEA,UAAI,QAAQ,QAAQ;AAChB,cAAM,EAAE,OAAO,IAAI;AACnB,cAAM,oBAAoB,MAAM;AAC5B,mCAAyB;AACzB,2BAAiB;AACjB,iBAAO,OAAO,MAAM;AACpB,eAAK,mBAAmB;AACxB,eAAK,KAAK,MAAM;AAAA,QACpB;AACA,mCAA2B,MAAM;AAC7B,iBAAO,oBAAoB,SAAS,iBAAiB;AACrD,eAAK,oCAAoC,OAAO,wBAAwB;AAAA,QAC5E;AACA,YAAI,OAAO,SAAS;AAChB,4BAAkB;AAClB;AAAA,QACJ;AACA,eAAO,iBAAiB,SAAS,mBAAmB,EAAE,MAAM,KAAK,CAAC;AAClE,aAAK,oCAAoC,IAAI,wBAAwB;AAAA,MACzE;AACA,WAAK,KAAK,KAAK;AACf,WAAK,mBAAmB;AAAA,IAC5B,CAAC;AAAA,EACL;AAAA,EACA,MAAM,OAAO,WAAW,SAAS;AAC7B,WAAO,QAAQ,IAAI,UAAU,IAAI,OAAO,cAAc,KAAK,IAAI,WAAW,OAAO,CAAC,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA,EAIA,QAAQ;AACJ,QAAI,CAAC,KAAK,WAAW;AACjB,aAAO;AAAA,IACX;AACA,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAIA,QAAQ;AACJ,SAAK,YAAY;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAIA,QAAQ;AACJ,eAAW,4BAA4B,KAAK,qCAAqC;AAC7E,+BAAyB;AAAA,IAC7B;AACA,SAAK,SAAS,IAAI,KAAK,YAAY;AAEnC,SAAK,oBAAoB;AAOzB,SAAK,sBAAsB;AAE3B,SAAK,KAAK,OAAO;AACjB,QAAI,KAAK,aAAa,GAAG;AACrB,WAAK,mBAAmB;AACxB,WAAK,KAAK,MAAM;AAAA,IACpB;AACA,SAAK,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU;AAEZ,QAAI,KAAK,OAAO,SAAS,GAAG;AACxB;AAAA,IACJ;AACA,UAAM,KAAK,SAAS,OAAO;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,OAAO;AAExB,QAAI,KAAK,OAAO,OAAO,OAAO;AAC1B;AAAA,IACJ;AACA,UAAM,KAAK,SAAS,QAAQ,MAAM,KAAK,OAAO,OAAO,KAAK;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS;AAEX,QAAI,KAAK,aAAa,KAAK,KAAK,OAAO,SAAS,GAAG;AAC/C;AAAA,IACJ;AACA,UAAM,KAAK,SAAS,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB;AAClB,QAAI,KAAK,aAAa,GAAG;AACrB;AAAA,IACJ;AACA,UAAM,KAAK,SAAS,aAAa;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAIA,MAAM,cAAc;AAChB,QAAI,KAAK,eAAe;AACpB;AAAA,IACJ;AACA,UAAM,KAAK,SAAS,WAAW;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAIA,MAAM,qBAAqB;AACvB,QAAI,CAAC,KAAK,eAAe;AACrB;AAAA,IACJ;AACA,UAAM,KAAK,SAAS,kBAAkB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BA,UAAU;AACN,WAAO,IAAI,QAAQ,CAAC,UAAU,WAAW;AACrC,YAAM,cAAc,CAAC,UAAU;AAC3B,aAAK,IAAI,SAAS,WAAW;AAC7B,eAAO,KAAK;AAAA,MAChB;AACA,WAAK,GAAG,SAAS,WAAW;AAAA,IAChC,CAAC;AAAA,EACL;AAAA,EACA,MAAM,SAAS,OAAO,QAAQ;AAC1B,WAAO,IAAI,QAAQ,CAAAA,cAAW;AAC1B,YAAM,WAAW,MAAM;AACnB,YAAI,UAAU,CAAC,OAAO,GAAG;AACrB;AAAA,QACJ;AACA,aAAK,IAAI,OAAO,QAAQ;AACxB,QAAAA,UAAQ;AAAA,MACZ;AACA,WAAK,GAAG,OAAO,QAAQ;AAAA,IAC3B,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAIA,IAAI,OAAO;AACP,WAAO,KAAK,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,SAAS;AAEZ,WAAO,KAAK,OAAO,OAAO,OAAO,EAAE;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAIA,IAAI,UAAU;AACV,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAIA,IAAI,WAAW;AACX,WAAO,KAAK;AAAA,EAChB;AAAA,EACA,0BAA0B;AAEtB,QAAI,KAAK,oBAAoB;AACzB;AAAA,IACJ;AAGA,SAAK,GAAG,OAAO,MAAM;AACjB,UAAI,KAAK,OAAO,OAAO,GAAG;AACtB,aAAK,yBAAyB;AAAA,MAClC;AAAA,IACJ,CAAC;AACD,SAAK,GAAG,QAAQ,MAAM;AAClB,WAAK,yBAAyB;AAAA,IAClC,CAAC;AAAA,EACL;AAAA,EACA,2BAA2B;AAEvB,QAAI,KAAK,sBAAsB,KAAK,0BAA0B;AAC1D;AAAA,IACJ;AACA,SAAK,2BAA2B;AAChC,mBAAe,MAAM;AACjB,WAAK,2BAA2B;AAChC,WAAK,sBAAsB;AAAA,IAC/B,CAAC;AAAA,EACL;AAAA,EACA,+BAA+B;AAC3B,QAAI,KAAK,oBAAoB;AACzB;AAAA,IACJ;AACA,SAAK,sBAAsB;AAC3B,SAAK,yBAAyB;AAAA,EAClC;AAAA,EACA,wBAAwB;AACpB,UAAM,WAAW,KAAK;AAEtB,QAAI,KAAK,sBAAsB,KAAK,OAAO,SAAS,GAAG;AACnD,UAAI,UAAU;AACV,aAAK,yBAAyB;AAC9B,aAAK,KAAK,kBAAkB;AAAA,MAChC;AACA;AAAA,IACJ;AAEA,QAAI;AACJ,QAAI,KAAK,SAAS;AACd,YAAMD,OAAM,KAAK,IAAI;AACrB,WAAK,oBAAoBA,IAAG;AAC5B,cAAQ,KAAK,qBAAqB;AAAA,IACtC,OACK;AACD,cAAQ,KAAK;AAAA,IACjB;AACA,UAAM,sBAAsB,SAAS,KAAK;AAC1C,QAAI,wBAAwB,UAAU;AAClC,WAAK,yBAAyB;AAC9B,WAAK,KAAK,sBAAsB,cAAc,kBAAkB;AAAA,IACpE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAIA,IAAI,gBAAgB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,IAAI,cAAc;AACd,WAAQ,KAAK,aAAa,KAAK,gBAAgB,KAAK,OAAO,OAAO,KAC1D,KAAK,iBAAiB,KAAK,OAAO,OAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,IAAI,eAAe;AAEf,WAAO,CAAC,GAAG,KAAK,cAAc,OAAO,CAAC,EAAE,IAAI,WAAS,EAAE,GAAG,KAAK,EAAE;AAAA,EACrE;AACJ;;;AClwBA,IAAM,iBAAiB,OAAO,UAAU;AAExC,IAAM,UAAU,WAAS,eAAe,KAAK,KAAK,MAAM;AAExD,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC7B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACD,CAAC;AAEc,SAAR,eAAgC,OAAO;AAC7C,QAAM,UAAU,SACZ,QAAQ,KAAK,KACb,MAAM,SAAS,eACf,OAAO,MAAM,YAAY;AAE7B,MAAI,CAAC,SAAS;AACb,WAAO;AAAA,EACR;AAEA,QAAM,EAAC,SAAS,MAAK,IAAI;AAGzB,MAAI,YAAY,eAAe;AAC9B,WAAO,UAAU,UAEb,yBAAyB;AAAA,EAC9B;AAGA,MAAI,QAAQ,WAAW,+BAA+B,GAAG;AACxD,WAAO;AAAA,EACR;AAGA,MAAI,YAAY,qBAAsB,QAAQ,WAAW,mBAAmB,KAAK,QAAQ,SAAS,GAAG,GAAI;AACxG,WAAO;AAAA,EACR;AAGA,SAAO,cAAc,IAAI,OAAO;AACjC;;;AC5CA,SAAS,gBAAgB,SAAS;AACjC,MAAI,OAAO,YAAY,UAAU;AAChC,QAAI,UAAU,GAAG;AAChB,YAAM,IAAI,UAAU,iDAAiD;AAAA,IACtE;AAEA,QAAI,OAAO,MAAM,OAAO,GAAG;AAC1B,YAAM,IAAI,UAAU,+DAA+D;AAAA,IACpF;AAAA,EACD,WAAW,YAAY,QAAW;AACjC,UAAM,IAAI,UAAU,gDAAgD;AAAA,EACrE;AACD;AAEA,SAAS,qBAAqB,MAAM,OAAO,EAAC,MAAM,GAAG,gBAAgB,MAAK,IAAI,CAAC,GAAG;AACjF,MAAI,UAAU,QAAW;AACxB;AAAA,EACD;AAEA,MAAI,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK,GAAG;AACrD,UAAM,IAAI,UAAU,cAAc,IAAI,oBAAoB,gBAAgB,iBAAiB,EAAE,GAAG;AAAA,EACjG;AAEA,MAAI,CAAC,iBAAiB,CAAC,OAAO,SAAS,KAAK,GAAG;AAC9C,UAAM,IAAI,UAAU,cAAc,IAAI,2BAA2B;AAAA,EAClE;AAEA,MAAI,QAAQ,KAAK;AAChB,UAAM,IAAI,UAAU,cAAc,IAAI,mBAAmB,GAAG,GAAG;AAAA,EAChE;AACD;AAEO,IAAM,aAAN,cAAyB,MAAM;AAAA,EACrC,YAAY,SAAS;AACpB,UAAM;AAEN,QAAI,mBAAmB,OAAO;AAC7B,WAAK,gBAAgB;AACrB,OAAC,EAAC,QAAO,IAAI;AAAA,IACd,OAAO;AACN,WAAK,gBAAgB,IAAI,MAAM,OAAO;AACtC,WAAK,cAAc,QAAQ,KAAK;AAAA,IACjC;AAEA,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EAChB;AACD;AAEA,SAAS,eAAe,iBAAiB,SAAS;AACjD,QAAM,UAAU,KAAK,IAAI,GAAG,kBAAkB,CAAC;AAC/C,QAAM,SAAS,QAAQ,YAAa,KAAK,OAAO,IAAI,IAAK;AAEzD,MAAI,UAAU,KAAK,MAAM,SAAS,QAAQ,aAAc,QAAQ,WAAW,UAAU,EAAG;AACxF,YAAU,KAAK,IAAI,SAAS,QAAQ,UAAU;AAE9C,SAAO;AACR;AAEA,SAAS,uBAAuB,OAAO,KAAK;AAC3C,MAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAC1B,WAAO;AAAA,EACR;AAEA,SAAO,OAAO,YAAY,IAAI,IAAI;AACnC;AAEA,eAAe,iBAAiB,EAAC,OAAO,eAAe,iBAAiB,WAAW,QAAO,GAAG;AAC5F,QAAM,kBAAkB,iBAAiB,QACtC,QACA,IAAI,UAAU,0BAA0B,KAAK,kCAAkC;AAElF,MAAI,2BAA2B,YAAY;AAC1C,UAAM,gBAAgB;AAAA,EACvB;AAEA,QAAM,cAAc,OAAO,SAAS,QAAQ,OAAO,IAChD,KAAK,IAAI,GAAG,QAAQ,UAAU,eAAe,IAC7C,QAAQ;AAEX,QAAM,eAAe,QAAQ,gBAAgB,OAAO;AAEpD,QAAM,UAAU,OAAO,OAAO;AAAA,IAC7B,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAC;AAED,QAAM,QAAQ,gBAAgB,OAAO;AAErC,MAAI,uBAAuB,WAAW,YAAY,KAAK,GAAG;AACzD,UAAM;AAAA,EACP;AAEA,QAAM,eAAe,MAAM,QAAQ,mBAAmB,OAAO;AAE7D,QAAM,gBAAgB,uBAAuB,WAAW,YAAY;AAEpE,MAAI,iBAAiB,KAAK,eAAe,GAAG;AAC3C,UAAM;AAAA,EACP;AAEA,MAAI,2BAA2B,aAAa,CAAC,eAAe,eAAe,GAAG;AAC7E,QAAI,cAAc;AACjB,YAAM;AAAA,IACP;AAEA,YAAQ,QAAQ,eAAe;AAC/B,WAAO;AAAA,EACR;AAEA,MAAI,CAAC,MAAM,QAAQ,YAAY,OAAO,GAAG;AACxC,UAAM;AAAA,EACP;AAEA,MAAI,CAAC,cAAc;AAClB,YAAQ,QAAQ,eAAe;AAC/B,WAAO;AAAA,EACR;AAEA,QAAM,YAAY,eAAe,iBAAiB,OAAO;AACzD,QAAM,aAAa,KAAK,IAAI,WAAW,aAAa;AAEpD,UAAQ,QAAQ,eAAe;AAE/B,MAAI,aAAa,GAAG;AACnB,UAAM,IAAI,QAAQ,CAACG,WAAS,WAAW;AACtC,YAAM,UAAU,MAAM;AACrB,qBAAa,YAAY;AACzB,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AACpD,eAAO,QAAQ,OAAO,MAAM;AAAA,MAC7B;AAEA,YAAM,eAAe,WAAW,MAAM;AACrC,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AACpD,QAAAA,UAAQ;AAAA,MACT,GAAG,UAAU;AAEb,UAAI,QAAQ,OAAO;AAClB,qBAAa,QAAQ;AAAA,MACtB;AAEA,cAAQ,QAAQ,iBAAiB,SAAS,SAAS,EAAC,MAAM,KAAI,CAAC;AAAA,IAChE,CAAC;AAAA,EACF;AAEA,UAAQ,QAAQ,eAAe;AAE/B,SAAO;AACR;AAEA,eAAO,OAA8B,OAAO,UAAU,CAAC,GAAG;AACzD,YAAU,EAAC,GAAG,QAAO;AAErB,kBAAgB,QAAQ,OAAO;AAE/B,MAAI,OAAO,OAAO,SAAS,SAAS,GAAG;AACtC,UAAM,IAAI,MAAM,2GAA2G;AAAA,EAC5H;AAEA,UAAQ,YAAY;AACpB,UAAQ,WAAW;AACnB,UAAQ,eAAe;AACvB,UAAQ,eAAe,OAAO;AAC9B,UAAQ,iBAAiB,OAAO;AAChC,UAAQ,cAAc;AACtB,UAAQ,oBAAoB,MAAM;AAAA,EAAC;AACnC,UAAQ,gBAAgB,MAAM;AAC9B,UAAQ,uBAAuB,MAAM;AAGrC,uBAAqB,UAAU,QAAQ,QAAQ,EAAC,KAAK,GAAG,eAAe,MAAK,CAAC;AAC7E,uBAAqB,cAAc,QAAQ,YAAY,EAAC,KAAK,GAAG,eAAe,MAAK,CAAC;AACrF,uBAAqB,cAAc,QAAQ,YAAY,EAAC,KAAK,GAAG,eAAe,KAAI,CAAC;AACpF,uBAAqB,gBAAgB,QAAQ,cAAc,EAAC,KAAK,GAAG,eAAe,KAAI,CAAC;AAGxF,MAAI,EAAE,QAAQ,SAAS,IAAI;AAC1B,YAAQ,SAAS;AAAA,EAClB;AAEA,UAAQ,QAAQ,eAAe;AAE/B,MAAI,gBAAgB;AACpB,MAAI,kBAAkB;AACtB,QAAM,YAAY,YAAY,IAAI;AAElC,SAAO,OAAO,SAAS,QAAQ,OAAO,IAAI,mBAAmB,QAAQ,UAAU,MAAM;AACpF;AAEA,QAAI;AACH,cAAQ,QAAQ,eAAe;AAE/B,YAAM,SAAS,MAAM,MAAM,aAAa;AAExC,cAAQ,QAAQ,eAAe;AAE/B,aAAO;AAAA,IACR,SAAS,OAAO;AACf,UAAI,MAAM,iBAAiB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC,GAAG;AACH;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAGA,QAAM,IAAI,MAAM,qDAAqD;AACtE;;;ACvNA,IAAAC,aAAyC;AACzC,IAAAC,SAAsB;AACtB,IAAAC,MAAoB;AAoCpB,SAAS,sBAA8B;AACrC,SAAY,YAAQ,YAAQ,GAAG,UAAU,SAAS,YAAY,WAAW;AAC3E;AAEA,SAAS,mBAAiD;AACxD,QAAM,WAAW,oBAAoB;AACrC,MAAI;AACF,YAAI,uBAAW,QAAQ,GAAG;AACxB,aAAO,KAAK,UAAM,yBAAa,UAAU,OAAO,CAAC;AAAA,IACnD;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO,CAAC;AACV;AAEA,eAAsB,wBACpB,mBAAsC,OACL;AACjC,MAAI,sBAAsB,UAAU;AAClC,WAAO,qBAAqB,KAAK;AAAA,EACnC;AAEA,QAAM,cAAc,MAAM,uBAAuB,iBAAiB;AAClE,MAAI,aAAa;AACf,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,QACA,WAAW,2BAA2B,iBAAiB;AAAA,MACzD;AAAA,IACF;AACA,QAAI,CAAC,aAAa,OAAO,iBAAiB,GAAG;AAC3C,YAAM,IAAI;AAAA,QACR,UAAU,KAAK,mCAAmC,iBAAiB;AAAA,MACrE;AAAA,IACF;AACA,UAAM,iBAAiB,iBAAiB,iBAAiB;AACzD,UAAM,YAAY,OAAO,OAAO,cAAc,EAAE,KAAK,CAAC,cAAc,UAAU,UAAU,KAAK;AAC7F,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR,UAAU,KAAK,mCAAmC,iBAAiB;AAAA,MACrE;AAAA,IACF;AACA,WAAO;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR,uBAAuB,iBAAiB;AAAA,EAC1C;AACF;AAEA,eAAsB,oBAAqD;AACzE,aAAW,YAAY,qBAAqB;AAC1C,QAAI,aAAa,UAAU;AACzB,YAAM,iBAAiB,MAAM,wBAAwB;AACrD,UAAI,gBAAgB;AAClB,eAAO;AAAA,MACT;AACA;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,uBAAuB,QAAQ;AACzD,QAAI,aAAa;AACf,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,WAAW,2BAA2B,QAAQ;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,wFAAwF,oBAAoB,KAAK,IAAI,CAAC;AAAA,EACxH;AACF;AAEA,eAAe,uBACb,UACqC;AACrC,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,qBAAqB;AAAA,IAC9B,KAAK;AACH,aAAO,qBAAqB;AAAA,IAC9B,KAAK;AACH,aAAO,qBAAqB;AAAA,IAC9B;AACE,aAAO;AAAA,EACX;AACF;AAGA,SAAS,uBAAmD;AAC1D,QAAM,WAAW,iBAAiB;AAClC,QAAM,aAAa,SAAS,QAAQ;AAEpC,MAAI,YAAY,SAAS,OAAO;AAC9B,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,WAAW;AAAA,MACnB,SAAS;AAAA,IACX;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBAAmD;AAC1D,QAAM,WAAW,iBAAiB;AAClC,QAAM,aAAa,SAAS,QAAQ,KAAK,SAAS,sBAAsB;AAExE,MAAI,YAAY,SAAS,OAAO;AAC9B,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,WAAW;AAAA,MACnB,SAAS;AAAA,IACX;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,YAAY,KAAa,MAAuC;AAC7E,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,GAAI;AAC3D,MAAI;AACF,WAAO,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EAChE,UAAE;AACA,iBAAa,SAAS;AAAA,EACxB;AACF;AAEA,eAAe,uBAA4D;AACzE,QAAM,WAAW,QAAQ,IAAI,eAAe,0BAA0B,QAAQ,QAAQ,EAAE;AAExF,MAAI;AACF,UAAM,WAAW,MAAM,YAAY,GAAG,OAAO,WAAW;AAExD,QAAI,SAAS,IAAI;AACf,aAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAWA,SAAS,uBACP,OAC6C;AAC7C,QAAM,aAAa,MAAM,SAAS,SAAS,IACvC,MAAM,MAAM,GAAG,CAAC,UAAU,MAAM,IAChC;AACJ,SAAO,OAAO,OAAO,iBAAiB,MAAM,EACzC,KAAK,CAAC,cAAc,UAAU,UAAU,UAAU,KAAK;AAC5D;AAEA,SAAS,2BACP,WACA,QACe;AACf,QAAM,SAAS,OAAO,QAAQ,SAAS,EACpC,OAAO,CAAC,CAAC,GAAG,MAAM,IAAI,SAAS,MAAM,CAAC,EACtC,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,KAAK,EACxB,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,QAAQ,CAAC;AAEvG,SAAO,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI;AAC3C;AAEA,eAAe,qBACb,aACA,OACsD;AACtD,QAAM,WAAW,MAAM,YAAY,GAAG,YAAY,OAAO,aAAa;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,EAChC,CAAC;AACD,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,MAAI,CAAC,KAAK,cAAc,SAAS,WAAW,KAAK,CAAC,KAAK,YAAY;AACjE,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,2BAA2B,KAAK,YAAY,mBAAmB;AAClF,QAAM,YAAY,2BAA2B,KAAK,YAAY,iBAAiB;AAC/E,MAAI,CAAC,cAAc,CAAC,WAAW;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,EACnB;AACF;AAEA,eAAe,iBAAiB,aAAqD;AACnF,QAAM,WAAW,MAAM,YAAY,GAAG,YAAY,OAAO,WAAW;AACpE,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,CAAC,GAAG,IAAI,KAAK,KAAK,UAAU,CAAC,GACjC,IAAI,CAAC,UAAU,MAAM,QAAQ,MAAM,KAAK,EACxC,OAAO,CAAC,SAAyB,OAAO,SAAS,YAAY,KAAK,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAC1F;AAEA,eAAe,qBAAqB,OAAiD;AACnF,QAAM,cAAc,MAAM,qBAAqB;AAC/C,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AAEA,QAAM,iBAAiB,OAAO,KAAK;AACnC,MAAI,gBAAgB;AAClB,UAAM,eAAe,uBAAuB,cAAc;AAC1D,QAAI,cAAc;AAChB,aAAO,EAAE,UAAU,UAAU,aAAa,WAAW,aAAa;AAAA,IACpE;AAAA,EACF;AAEA,QAAM,aAAa,iBACf,CAAC,cAAc,IACf,MAAM,iBAAiB,WAAW;AACtC,aAAW,aAAa,YAAY;AAClC,UAAM,YAAY,MAAM,qBAAqB,aAAa,SAAS;AACnE,QAAI,WAAW;AACb,aAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,QACA,WAAW,uBAAuB,SAAS,KAAK;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QACX,UAAU,KAAK,mDACf;AACJ,QAAM,IAAI,MAAM,MAAM;AACxB;AAEA,eAAe,0BAAkE;AAC/E,MAAI;AACF,WAAO,MAAM,qBAAqB;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,UAAgD;AACrF,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,yBAAyB,QAAsD;AAG7F,QAAM,UAAU,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AACjD,SAAO;AAAA,IACL,UAAU;AAAA,IACV,aAAa;AAAA,MACX,UAAU;AAAA,MACV;AAAA,MACA,QAAQ,OAAO;AAAA,IACjB;AAAA,IACA,WAAW;AAAA,MACT,UAAU;AAAA,MACV,OAAO,OAAO;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,WAAW,OAAO,aAAa;AAAA,MAC/B,iBAAiB;AAAA,MACjB,WAAW,OAAO,aAAa;AAAA,MAC/B,cAAc,OAAO;AAAA,IACvB;AAAA,EACF;AACF;;;ACvUO,IAAe,wBAAf,MACiC;AAAA,EAC/B,YACc,aACA,WACnB;AAFmB;AACA;AAAA,EACjB;AAAA,EAFiB;AAAA,EACA;AAAA,EAGrB,MAAa,WAAW,OAAyC;AAC/D,UAAM,SAAS,MAAM,KAAK,WAAW,CAAC,KAAK,CAAC;AAC5C,WAAO;AAAA,MACL,WAAW,OAAO,WAAW,CAAC;AAAA,MAC9B,YAAY,OAAO;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAa,cAAc,UAA4C;AACrE,UAAM,SAAS,MAAM,KAAK,WAAW,CAAC,QAAQ,CAAC;AAC/C,WAAO;AAAA,MACL,WAAW,OAAO,WAAW,CAAC;AAAA,MAC9B,YAAY,OAAO;AAAA,IACrB;AAAA,EACF;AAAA,EAEO,eAA2B;AAChC,WAAO,KAAK;AAAA,EACd;AAGF;AAOO,IAAM,kCAAN,cAA8C,MAAM;AAAA,EAClD,YAAY,SAAiB;AAClC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;AC7CA,IAAM,uBAAuB;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAEA,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAYM,SAAS,oBAAoB,WAAwC;AAC1E,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,SAAS;AAAA,EAC5B,QAAQ;AACN,WAAO,EAAE,OAAO,OAAO,QAAQ,gBAAgB,oBAAoB,SAAS,CAAC,GAAG;AAAA,EAClF;AAGA,MAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UAAU;AAC/D,WAAO,EAAE,OAAO,OAAO,QAAQ,qBAAqB,OAAO,QAAQ,GAAG;AAAA,EACxE;AAEA,QAAMC,YAAW,OAAO,SAAS,YAAY;AAG7C,MAAI,kBAAkB,IAAIA,SAAQ,GAAG;AACnC,WAAO,EAAE,OAAO,OAAO,QAAQ,oCAAoCA,SAAQ,IAAI;AAAA,EACjF;AAGA,aAAW,WAAW,sBAAsB;AAC1C,QAAI,QAAQ,KAAKA,SAAQ,GAAG;AAC1B,aAAO,EAAE,OAAO,OAAO,QAAQ,+BAA+BA,SAAQ,IAAI;AAAA,IAC5E;AAAA,EACF;AAGA,MAAI,cAAc,KAAKA,SAAQ,GAAG;AAChC,WAAO,EAAE,OAAO,OAAO,QAAQ,gCAAgCA,SAAQ,IAAI;AAAA,EAC7E;AAEA,SAAO,EAAE,OAAO,KAAK;AACvB;AAKO,SAAS,oBAAoB,KAAqB;AACvD,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAE1B,WAAO,WAAW;AAClB,WAAO,WAAW;AAClB,WAAO,OAAO,SAAS;AAAA,EACzB,QAAQ;AAEN,UAAM,SAAS;AACf,QAAI,IAAI,SAAS,QAAQ;AACvB,aAAO,IAAI,MAAM,GAAG,MAAM,IAAI;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AACF;;;ACpFO,IAAM,0BAAN,cAAsC,sBAAuC;AAAA,EAC3E,YAAY,aAAkC,WAA4B;AAC/E,UAAM,aAAa,SAAS;AAAA,EAC9B;AAAA,EAEQ,wBAAwB,OAA6B;AAC3D,UAAM,eAAe,KAAK,UAAU;AAEpC,QAAI,CAAC,gBAAgB,MAAM,UAAU,cAAc;AACjD,aAAO,CAAC,KAAK;AAAA,IACf;AAEA,UAAM,UAAsB,CAAC;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,cAAc;AACnD,cAAQ,KAAK,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,aAAa,OAAgD;AACzE,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,QACL,YAAY,CAAC;AAAA,QACb,iBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,IAClB;AACA,QAAI,KAAK,YAAY,QAAQ;AAC3B,cAAQ,gBAAgB,UAAU,KAAK,YAAY,MAAM;AAAA,IAC3D;AAEA,UAAM,UAAU,KAAK,YAAY,WAAW;AAC5C,UAAM,UAAU,GAAG,OAAO;AAE1B,UAAM,WAAW,oBAAoB,OAAO;AAC5C,QAAI,CAAC,SAAS,OAAO;AACnB,YAAM,IAAI;AAAA,QACR,4DAA4D,SAAS,MAAM;AAAA,MAC7E;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,UAAU;AACjC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAE9D,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,SAAS;AAAA,QAC9B,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK,UAAU;AAAA,UACtB,OAAO;AAAA,QACT,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,cAAM,IAAI,MAAM,gDAAgD,SAAS,UAAU,oBAAoB,OAAO,CAAC,EAAE;AAAA,MACnH;AACA,YAAM;AAAA,IACR,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,MAAM,SAAS,KAAK,GAAG,MAAM,GAAG,GAAG;AACtD,UAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,cAAM,IAAI,gCAAgC,+CAA+C,SAAS,MAAM,MAAM,SAAS,EAAE;AAAA,MAC3H;AACA,YAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,MAAM,SAAS,EAAE;AAAA,IACjF;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAKjC,QAAI,KAAK,QAAQ,MAAM,QAAQ,KAAK,IAAI,GAAG;AACzC,UAAI,KAAK,KAAK,SAAS,GAAG;AACxB,cAAM,aAAa,KAAK,KAAK,CAAC,EAAE,UAAU;AAC1C,YAAI,eAAe,KAAK,UAAU,YAAY;AAC5C,gBAAM,IAAI;AAAA,YACR,oDAAoD,KAAK,UAAU,UAAU,uCACxC,UAAU;AAAA,UAEjD;AAAA,QACF;AAAA,MACF;AAEA,UAAI,KAAK,KAAK,WAAW,MAAM,QAAQ;AACrC,cAAM,IAAI;AAAA,UACR,kCAAkC,MAAM,MAAM,uBAAuB,KAAK,KAAK,MAAM;AAAA,QAEvF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,YAAY,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,QAC5C,iBAAiB,KAAK,OAAO,gBAAgB,MAAM,OAAO,CAAC,KAAK,MAAM,MAAM,KAAK,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC;AAAA,MACxG;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,oHAAoH;AAAA,EACtI;AAAA,EAEA,MAAa,WAAW,OAAgD;AACtE,UAAM,iBAAiB,KAAK,wBAAwB,KAAK;AACzD,UAAM,aAAyB,CAAC;AAChC,QAAI,kBAAkB;AAEtB,eAAW,SAAS,gBAAgB;AAClC,YAAM,SAAS,MAAM,KAAK,aAAa,KAAK;AAC5C,iBAAW,KAAK,GAAG,OAAO,UAAU;AACpC,yBAAmB,OAAO;AAAA,IAC5B;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AC5HO,IAAM,0BAAN,MAAM,iCAAgC,sBAA4D;AAAA,EACvG,OAAwB,aAAa;AAAA,EAE9B,YACL,aACA,WACA;AACA,UAAM,aAAa,SAAS;AAAA,EAC9B;AAAA,EAEA,MAAa,WAAW,OAAyC;AAC/D,UAAM,WAAW,KAAK,UAAU,UAAU,0BAA0B,KAAK,UAAU,WAC/E,yBACA;AACJ,UAAM,QAAQ;AAAA,MACZ,KAAK,UAAU,UAAU,uBACrB,iCAAiC,KAAK,KACtC;AAAA,IACN;AACA,UAAM,SAAS,MAAM,KAAK,kBAAkB,OAAO,QAAQ;AAC3D,WAAO;AAAA,MACL,WAAW,OAAO,WAAW,CAAC;AAAA,MAC9B,YAAY,OAAO;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAa,cAAc,UAA4C;AACrE,UAAM,WAAW,KAAK,UAAU,UAAU,0BAA0B,KAAK,UAAU,WAC/E,uBACA;AACJ,UAAM,SAAS,MAAM,KAAK,kBAAkB;AAAA,MAC1C,KAAK,UAAU,UAAU,uBAAuB,uBAAuB,QAAQ,KAAK;AAAA,IACtF,GAAG,QAAQ;AACX,WAAO;AAAA,MACL,WAAW,OAAO,WAAW,CAAC;AAAA,MAC9B,YAAY,OAAO;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAa,WAAW,OAAgD;AACtE,UAAM,WAAW,KAAK,UAAU,UAAU,0BAA0B,KAAK,UAAU,WAC/E,uBACA;AACJ,UAAM,iBAAiB,KAAK,UAAU,UAAU,uBAC5C,MAAM,IAAI,CAAC,SAAS,uBAAuB,IAAI,EAAE,IACjD;AAEJ,WAAO,KAAK,kBAAkB,gBAAgB,QAAQ;AAAA,EACxD;AAAA,EAEA,MAAc,kBACZ,OACA,UAC+B;AAC/B,UAAM,UAAsB,CAAC;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,yBAAwB,YAAY;AACzE,cAAQ,KAAK,MAAM,MAAM,GAAG,IAAI,yBAAwB,UAAU,CAAC;AAAA,IACrE;AAEA,UAAM,eAAe,MAAM,QAAQ;AAAA,MACjC,QAAQ,IAAI,OAAO,UAAU;AAC3B,cAAM,WAAW,MAAM,IAAI,CAAC,UAAU;AAAA,UACpC,OAAO,UAAU,KAAK,UAAU,KAAK;AAAA,UACrC,SAAS;AAAA,YACP,OAAO,CAAC,EAAE,KAAK,CAAC;AAAA,UAClB;AAAA,UACA;AAAA,UACA,sBAAsB,KAAK,UAAU;AAAA,QACvC,EAAE;AAEF,cAAM,WAAW,MAAM;AAAA,UACrB,GAAG,KAAK,YAAY,OAAO,WAAW,KAAK,UAAU,KAAK;AAAA,UAC1D;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,gBAAgB;AAAA,cAChB,GAAI,KAAK,YAAY,UAAU,EAAE,kBAAkB,KAAK,YAAY,OAAO;AAAA,YAC7E;AAAA,YACA,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,UACnC;AAAA,QACF;AAEA,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,SAAS,MAAM,SAAS,KAAK,GAAG,MAAM,GAAG,GAAG;AAClD,gBAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,MAAM,KAAK,EAAE;AAAA,QAC7E;AAEA,cAAM,OAAQ,MAAM,SAAS,KAAK;AAIlC,eAAO;AAAA,UACL,YAAY,KAAK,WAAW,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,UAC/C,YAAY,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,KAAK,KAAK,SAAS,CAAC,GAAG,CAAC;AAAA,QAC7E;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,YAAY,aAAa,QAAQ,CAAC,MAAM,EAAE,UAAU;AAAA,MACpD,iBAAiB,aAAa,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,YAAY,CAAC;AAAA,IACxE;AAAA,EACF;AACF;;;AC3GO,IAAM,0BAAN,MAAM,iCAAgC,sBAA4D;AAAA,EACvG,OAAwB,uBAAuB;AAAA,EAC/C,OAAwB,qBAAqB;AAAA;AAAA;AAAA;AAAA,EAKrC,2BAA2B;AAAA,EAE5B,YACL,aACA,WACA;AACA,UAAM,aAAa,SAAS;AAAA,EAC9B;AAAA,EAEQ,eAAe,MAAsB;AAC3C,WAAO,KAAK,KAAK,KAAK,SAAS,CAAC;AAAA,EAClC;AAAA,EAEQ,oBAAoB,MAAc,UAA0B;AAClE,QAAI,KAAK,UAAU,UAAU;AAC3B,aAAO;AAAA,IACT;AAEA,WAAO,GAAG,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC;AAAA;AAAA,EACrD;AAAA,EAEQ,qBAAqB,OAAyB;AACpD,UAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,YAAY;AACrF,WAAQ,QAAQ,SAAS,gBAAgB,MAAM,QAAQ,SAAS,QAAQ,KAAK,QAAQ,SAAS,UAAU,KAAK,QAAQ,SAAS,UAAU,MACnI,QAAQ,SAAS,yCAAyC,KAC1D,QAAQ,SAAS,yBAAyB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKQ,gCAAgC,OAAyB;AAC/D,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO,QAAQ,SAAS,iCAAiC;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,OAAyB;AACtD,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO,QAAQ,SAAS,yBAAyB;AAAA,EACnD;AAAA,EAEQ,0BAA0B,MAAwB;AACxD,UAAM,eAAe,KAAK,IAAI,GAAG,KAAK,UAAU,YAAY,CAAC;AAC7D,UAAM,kBAAkB,oBAAI,IAAY;AACxC,UAAM,gBAAgB,KAAK,SAAS,eAChC,eACA,KAAK;AAAA,MACH,yBAAwB;AAAA,MACxB,KAAK,MAAM,KAAK,SAAS,GAAG;AAAA,IAC9B;AAEJ,QAAI,gBAAgB,KAAK,QAAQ;AAC/B,sBAAgB,IAAI,aAAa;AAAA,IACnC;AAEA,eAAW,UAAU,CAAC,MAAM,KAAK,MAAM,MAAM,IAAI,GAAG;AAClD,YAAM,cAAc,KAAK;AAAA,QACvB,yBAAwB;AAAA,QACxB,KAAK,MAAM,gBAAgB,MAAM;AAAA,MACnC;AACA,UAAI,cAAc,KAAK,QAAQ;AAC7B,wBAAgB,IAAI,WAAW;AAAA,MACjC;AAAA,IACF;AAEA,oBAAgB,IAAI,KAAK,IAAI,KAAK,SAAS,GAAG,yBAAwB,oBAAoB,CAAC;AAE3F,UAAM,aAAuB,CAAC;AAC9B,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,SAAS,CAAC,GAAG,eAAe,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG;AAC9D,UAAI,SAAS,KAAK,SAAS,KAAK,QAAQ;AACtC;AAAA,MACF;AAEA,YAAM,YAAY,KAAK,oBAAoB,MAAM,KAAK;AACtD,UAAI,cAAc,QAAQ,KAAK,IAAI,SAAS,GAAG;AAC7C;AAAA,MACF;AAEA,WAAK,IAAI,SAAS;AAClB,iBAAW,KAAK,SAAS;AAAA,IAC3B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,wBAAwB,MAAoE;AACxG,QAAI;AACF,aAAO,MAAM,KAAK,YAAY,IAAI;AAAA,IACpC,SAAS,OAAO;AACd,UAAI,CAAC,KAAK,qBAAqB,KAAK,GAAG;AACrC,cAAM;AAAA,MACR;AAEA,UAAI,YAAqB;AACzB,iBAAW,aAAa,KAAK,0BAA0B,IAAI,GAAG;AAC5D,YAAI;AACF,iBAAO,MAAM,KAAK,YAAY,SAAS;AAAA,QACzC,SAAS,YAAY;AACnB,cAAI,CAAC,KAAK,qBAAqB,UAAU,GAAG;AAC1C,kBAAM;AAAA,UACR;AACA,sBAAY;AAAA,QACd;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,MAAoE;AAC5F,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU;AAAA,MACd,MAAM,WAAW,MAAM;AAAA,MACvB,yBAAwB;AAAA,IAC1B;AACA,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,GAAG,KAAK,YAAY,OAAO,mBAAmB;AAAA,QACnE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK,UAAU;AAAA,UACtB,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,cAAM,IAAI;AAAA,UACR,4CAA4C,yBAAwB,kBAAkB;AAAA,QACxF;AAAA,MACF;AACA,YAAM;AAAA,IACR,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,MAAM,SAAS,KAAK,GAAG,MAAM,GAAG,GAAG;AAClD,YAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,MAAM,KAAK,EAAE;AAAA,IAC7E;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,QACE,CAAC,MAAM,QAAQ,KAAK,SAAS,KAC1B,KAAK,UAAU,WAAW,KAAK,UAAU,cACzC,KAAK,UAAU,KAAK,CAAC,UAAU,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,CAAC,GACtF;AACA,YAAM,IAAI;AAAA,QACR,kDAAkD,KAAK,UAAU,UAAU;AAAA,MAC7E;AAAA,IACF;AAEA,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK,eAAe,IAAI;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,UAAU,OAAgD;AACtE,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU;AAAA,MACd,MAAM,WAAW,MAAM;AAAA,MACvB,yBAAwB;AAAA,IAC1B;AACA,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,GAAG,KAAK,YAAY,OAAO,cAAc;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK,UAAU;AAAA,UACtB,OAAO;AAAA,UACP,UAAU;AAAA,QACZ,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,cAAM,IAAI;AAAA,UACR,4CAA4C,yBAAwB,kBAAkB;AAAA,QACxF;AAAA,MACF;AACA,YAAM;AAAA,IACR,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,MAAM,SAAS,KAAK,GAAG,MAAM,GAAG,GAAG;AAClD,UAAI,SAAS,WAAW,KAAK;AAC3B,cAAM,IAAI,MAAM,oCAAoC,SAAS,MAAM,MAAM,KAAK,EAAE;AAAA,MAClF;AACA,YAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,MAAM,KAAK,EAAE;AAAA,IAC7E;AAEA,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,SAAS,KAAK;AAAA,IAC/B,QAAQ;AAIN,YAAM,IAAI;AAAA,QACR,wDAAwD,MAAM,MAAM,eAAe,KAAK,UAAU,UAAU;AAAA,MAC9G;AAAA,IACF;AACA,UAAM,OAAQ,UAAU,OAAO,WAAW,WAAW,SAAS,CAAC;AAC/D,QACE,CAAC,MAAM,QAAQ,KAAK,UAAU,KAC3B,KAAK,WAAW,WAAW,MAAM,UACjC,KAAK,WAAW;AAAA,MACjB,CAAC,UACC,CAAC,MAAM,QAAQ,KAAK,KACjB,MAAM,WAAW,KAAK,UAAU,cAChC,MAAM,KAAK,CAAC,MAAM,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC;AAAA,IACrE,GACA;AACA,YAAM,IAAI;AAAA,QACR,wDAAwD,MAAM,MAAM,eAAe,KAAK,UAAU,UAAU;AAAA,MAC9G;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY,KAAK;AAAA,MACjB,iBAAiB,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,eAAe,IAAI,GAAG,CAAC;AAAA,IACjF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,cAAc,OAAgD;AAC1E,UAAM,UAA8D,CAAC;AACrE,eAAW,QAAQ,OAAO;AACxB,cAAQ,KAAK,MAAM,KAAK,wBAAwB,IAAI,CAAC;AAAA,IACvD;AAEA,WAAO;AAAA,MACL,YAAY,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MAC1C,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,YAAY,CAAC;AAAA,IACnE;AAAA,EACF;AAAA,EAEA,MAAa,WAAW,OAAgD;AACtE,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,EAAE,YAAY,CAAC,GAAG,iBAAiB,EAAE;AAAA,IAC9C;AAMA,QAAI,MAAM,WAAW,KAAK,KAAK,0BAA0B;AACvD,aAAO,KAAK,cAAc,KAAK;AAAA,IACjC;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,UAAU,KAAK;AAAA,IACnC,SAAS,OAAO;AAQd,UAAI,KAAK,gCAAgC,KAAK,GAAG;AAE/C,aAAK,2BAA2B;AAChC,eAAO,KAAK,cAAc,KAAK;AAAA,MACjC;AAEA,UACE,CAAC,KAAK,qBAAqB,KAAK,KAC7B,CAAC,KAAK,uBAAuB,KAAK,GACrC;AACA,cAAM;AAAA,MACR;AAEA,aAAO,KAAK,cAAc,KAAK;AAAA,IACjC;AAAA,EACF;AACF;;;AClTO,IAAM,0BAAN,cAAsC,sBAA4D;AAAA,EAChG,YACL,aACA,WACA;AACA,UAAM,aAAa,SAAS;AAAA,EAC9B;AAAA,EAEA,MAAa,WAAW,OAAgD;AACtE,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,YAAY,OAAO,eAAe;AAAA,MACrE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK,YAAY,MAAM;AAAA,QAChD,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,OAAO,KAAK,UAAU;AAAA,QACtB,OAAO;AAAA,MACT,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,MAAM,SAAS,KAAK,GAAG,MAAM,GAAG,GAAG;AAClD,YAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,MAAM,KAAK,EAAE;AAAA,IAC7E;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAKjC,WAAO;AAAA,MACL,YAAY,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MAC5C,iBAAiB,KAAK,MAAM;AAAA,IAC9B;AAAA,EACF;AACF;;;AC3BO,SAAS,wBACd,wBAC0D;AAC1D,UAAQ,uBAAuB,UAAU;AAAA,IACvC,KAAK;AACH,aAAO,IAAI,wBAAwB,uBAAuB,aAAa,uBAAuB,SAAS;AAAA,IACzG,KAAK;AACH,aAAO,IAAI,wBAAwB,uBAAuB,aAAa,uBAAuB,SAAS;AAAA,IACzG,KAAK;AACH,aAAO,IAAI,wBAAwB,uBAAuB,aAAa,uBAAuB,SAAS;AAAA,IACzG,KAAK;AACH,aAAO,IAAI,wBAAwB,uBAAuB,aAAa,uBAAuB,SAAS;AAAA,IACzG,SAAS;AACP,YAAM,cAAqB;AAC3B,YAAM,IAAI,MAAM,mCAAoC,YAAuC,QAAQ,EAAE;AAAA,IACvG;AAAA,EACF;AACF;;;ACUO,SAAS,wBACd,OACQ;AACR,MAAI,cAAc;AAElB,aAAW,QAAQ,OAAO;AACxB,UAAM,eAAe;AACrB,UAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,OAAO,YAAY,CAAC;AACrE,mBAAe;AAAA,EACjB;AAEA,SAAO;AACT;AAEO,SAAS,aACd,iBACA,WACQ;AACR,SAAQ,kBAAkB,MAAa,UAAU;AACnD;AAEO,SAAS,mBACd,OACA,UACc;AACd,QAAM,aAAa,MAAM;AACzB,QAAM,iBAAiB,MAAM,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAC/D,QAAM,kBAAkB,wBAAwB,KAAK;AACrD,QAAM,oBAAoB;AAC1B,QAAM,kBAAkB,kBAAkB;AAC1C,QAAM,gBAAgB,aAAa,iBAAiB,SAAS,SAAS;AAEtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,uBAAuB,SAAS,QAAQ;AAAA,IAClD,OAAO,SAAS,UAAU;AAAA,IAC1B,QAAQ,SAAS,UAAU,oBAAoB;AAAA,EACjD;AACF;AAEO,SAAS,mBAAmB,UAAgC;AACjE,QAAM,gBAAgB,YAAY,SAAS,cAAc;AACzD,QAAM,iBAAiB,GAAG,SAAS,WAAW,eAAe,CAAC;AAC9D,QAAM,gBAAgB,SAAS,SAC3B,SACA,KAAK,SAAS,cAAc,QAAQ,CAAC,CAAC;AAE1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,8BAKgB,eAAe,OAAO,EAAE,CAAC;AAAA,8BACzB,cAAc,OAAO,EAAE,CAAC;AAAA,+BACvB,MAAM,SAAS,gBAAgB,eAAe,IAAI,WAAW,OAAO,EAAE,CAAC;AAAA,+BACvE,MAAM,SAAS,gBAAgB,eAAe,IAAI,WAAW,OAAO,EAAE,CAAC;AAAA;AAAA,oBAElF,SAAS,SAAS,OAAO,EAAE,CAAC;AAAA,oBAC5B,SAAS,MAAM,OAAO,EAAE,CAAC;AAAA,oBACzB,cAAc,OAAO,EAAE,CAAC;AAAA;AAAA;AAAA;AAIvC;AAEO,SAAS,qBAAqB,UAAkC;AACrE,SAAO;AAAA;AAAA,sBAEa,SAAS,WAAW,eAAe,CAAC;AAAA,sBACpC,SAAS,YAAY,eAAe,CAAC;AAAA,sBACrC,SAAS,cAAc,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc7D;AAEO,SAAS,YAAY,OAAuB;AACjD,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,IAAI;AACV,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AACpC,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAClD,SAAO,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC;AACxE;;;ACvIA,IAAM,qBAA+C;AAAA,EACnD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AA8CA,SAAS,qBAA8B;AACrC,SAAO;AAAA,IACL,cAAc;AAAA,IACd,aAAa;AAAA,IACb,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,EACvB;AACF;AAEO,IAAM,SAAN,MAAa;AAAA,EACV;AAAA,EACA;AAAA,EACA,OAAmB,CAAC;AAAA,EACpB,UAAU;AAAA,EAElB,YAAY,QAAqB;AAC/B,SAAK,SAAS;AACd,SAAK,UAAU,mBAAmB;AAAA,EACpC;AAAA,EAEQ,UAAU,OAA0B;AAC1C,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO;AACjC,WAAO,mBAAmB,KAAK,KAAK,mBAAmB,KAAK,OAAO,QAAQ;AAAA,EAC7E;AAAA,EAEQ,IAAI,OAAiB,UAAkB,SAAiB,MAAsC;AACpG,QAAI,CAAC,KAAK,UAAU,KAAK,EAAG;AAE5B,UAAM,QAAkB;AAAA,MACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,SAAK,KAAK,KAAK,KAAK;AACpB,QAAI,KAAK,KAAK,SAAS,KAAK,SAAS;AACnC,WAAK,KAAK,MAAM;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,YAAY,IAAsB;AACxC,QAAI,CAAC,KAAK,OAAO,QAAS;AAC1B,OAAG;AAAA,EACL;AAAA,EAEA,OAAO,OAAiB,SAAiB,MAAsC;AAC7E,QAAI,KAAK,OAAO,WAAW;AACzB,WAAK,IAAI,OAAO,UAAU,SAAS,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,UAAU,OAAiB,SAAiB,MAAsC;AAChF,QAAI,KAAK,OAAO,cAAc;AAC5B,WAAK,IAAI,OAAO,aAAa,SAAS,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,OAAiB,SAAiB,MAAsC;AAC5E,QAAI,KAAK,OAAO,UAAU;AACxB,WAAK,IAAI,OAAO,SAAS,SAAS,IAAI;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,GAAG,OAAiB,SAAiB,MAAsC;AACzE,QAAI,KAAK,OAAO,OAAO;AACrB,WAAK,IAAI,OAAO,MAAM,SAAS,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,OAAO,OAAiB,SAAiB,MAAsC;AAC7E,QAAI,KAAK,OAAO,WAAW;AACzB,WAAK,IAAI,OAAO,UAAU,SAAS,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,KAAK,SAAiB,MAAsC;AAC1D,SAAK,IAAI,QAAQ,WAAW,SAAS,IAAI;AAAA,EAC3C;AAAA,EAEA,KAAK,SAAiB,MAAsC;AAC1D,SAAK,IAAI,QAAQ,WAAW,SAAS,IAAI;AAAA,EAC3C;AAAA,EAEA,MAAM,SAAiB,MAAsC;AAC3D,SAAK,IAAI,SAAS,WAAW,SAAS,IAAI;AAAA,EAC5C;AAAA,EAEA,MAAM,SAAiB,MAAsC;AAC3D,SAAK,IAAI,SAAS,WAAW,SAAS,IAAI;AAAA,EAC5C;AAAA,EAEA,sBAA4B;AAC1B,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,oBAAoB,KAAK,IAAI;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA,EAEA,oBAA0B;AACxB,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,kBAAkB,KAAK,IAAI;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,mBAAmB,OAAqB;AACtC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,eAAe;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB,OAAqB;AACrC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,cAAc;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,oBAAoB,YAA0B;AAC5C,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,UAAU;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,sBAAsB,OAAqB;AACzC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,mBAAmB;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,qBAAqB,OAAqB;AACxC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,kBAAkB;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEA,sBAAsB,OAAqB;AACzC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,mBAAmB;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,oBAAoB,OAAqB;AACvC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ,iBAAiB;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EAEA,uBAAuB,QAAsB;AAC3C,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AACb,WAAK,QAAQ,uBAAuB;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,uBAA6B;AAC3B,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,YAAoB,WAAkG;AACjI,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AACb,WAAK,QAAQ,iBAAiB;AAC9B,WAAK,QAAQ,eAAe;AAC5B,WAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB,KAAK,QAAQ;AAErE,UAAI,WAAW;AACb,aAAK,QAAQ,kBAAkB,UAAU;AACzC,aAAK,QAAQ,iBAAiB,UAAU;AACxC,aAAK,QAAQ,kBAAkB,UAAU;AACzC,aAAK,QAAQ,WAAW,UAAU;AAAA,MACpC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,iBAAuB;AACrB,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,kBAAwB;AACtB,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,sBAA4B;AAC1B,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,6BAAmC;AACjC,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,uBAA6B;AAC3B,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,SAAS,SAAiB,QAAgB,YAA0B;AAClE,SAAK,YAAY,MAAM;AACrB,WAAK,QAAQ;AACb,WAAK,QAAQ,oBAAoB;AACjC,WAAK,QAAQ,mBAAmB;AAChC,WAAK,QAAQ,uBAAuB;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,aAAsB;AACpB,WAAO,EAAE,GAAG,KAAK,QAAQ;AAAA,EAC3B;AAAA,EAEA,QAAQ,OAA4B;AAClC,UAAM,OAAO,CAAC,GAAG,KAAK,IAAI;AAC1B,QAAI,OAAO;AACT,aAAO,KAAK,MAAM,CAAC,KAAK;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,kBAAkB,UAAkB,OAA4B;AAC9D,UAAM,WAAW,KAAK,KAAK,OAAO,OAAK,EAAE,aAAa,QAAQ;AAC9D,QAAI,OAAO;AACT,aAAO,SAAS,MAAM,CAAC,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,OAAiB,OAA4B;AAC1D,UAAM,WAAW,KAAK,KAAK,OAAO,OAAK,EAAE,UAAU,KAAK;AACxD,QAAI,OAAO;AACT,aAAO,SAAS,MAAM,CAAC,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAqB;AACnB,SAAK,UAAU,mBAAmB;AAAA,EACpC;AAAA,EAEA,YAAkB;AAChB,SAAK,OAAO,CAAC;AAAA,EACf;AAAA,EAEA,gBAAwB;AACtB,UAAM,IAAI,KAAK;AACf,UAAM,QAAkB,CAAC;AAEzB,QAAI,EAAE,qBAAqB,EAAE,iBAAiB;AAC5C,YAAM,WAAW,EAAE,kBAAkB,EAAE;AACvC,YAAM,KAAK,uBAAuB,WAAW,KAAM,QAAQ,CAAC,CAAC,GAAG;AAAA,IAClE;AAEA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,oBAAoB,EAAE,YAAY,EAAE;AAC/C,UAAM,KAAK,mBAAmB,EAAE,WAAW,EAAE;AAC7C,UAAM,KAAK,uBAAuB,EAAE,eAAe,EAAE;AACrD,UAAM,KAAK,sBAAsB,EAAE,cAAc,EAAE;AACnD,UAAM,KAAK,wBAAwB,EAAE,eAAe,EAAE;AACtD,UAAM,KAAK,qBAAqB,EAAE,aAAa,EAAE;AAEjD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,gBAAgB;AAC3B,UAAM,KAAK,gBAAgB,EAAE,iBAAiB,EAAE;AAChD,UAAM,KAAK,kBAAkB,EAAE,oBAAoB,eAAe,CAAC,EAAE;AACrE,UAAM,KAAK,aAAa,EAAE,eAAe,EAAE;AAE3C,QAAI,EAAE,cAAc,GAAG;AACrB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,SAAS;AACpB,YAAM,KAAK,qBAAqB,EAAE,WAAW,EAAE;AAC/C,YAAM,KAAK,mBAAmB,EAAE,YAAY,QAAQ,CAAC,CAAC,IAAI;AAC1D,YAAM,KAAK,kBAAkB,EAAE,aAAa,QAAQ,CAAC,CAAC,IAAI;AAC1D,UAAI,EAAE,kBAAkB,GAAG;AACzB,cAAM,KAAK,oBAAoB,EAAE,gBAAgB,QAAQ,CAAC,CAAC,IAAI;AAC/D,cAAM,KAAK,wBAAwB,EAAE,eAAe,QAAQ,CAAC,CAAC,IAAI;AAClE,cAAM,KAAK,yBAAyB,EAAE,gBAAgB,QAAQ,CAAC,CAAC,IAAI;AACpE,cAAM,KAAK,iBAAiB,EAAE,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,MACvD;AAAA,IACF;AAEA,UAAM,gBAAgB,EAAE,YAAY,EAAE;AACtC,QAAI,gBAAgB,GAAG;AACrB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,WAAW,EAAE,SAAS,EAAE;AACnC,YAAM,KAAK,aAAa,EAAE,WAAW,EAAE;AACvC,YAAM,KAAK,gBAAiB,EAAE,YAAY,gBAAiB,KAAK,QAAQ,CAAC,CAAC,GAAG;AAAA,IAC/E;AAEA,QAAI,EAAE,SAAS,GAAG;AAChB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,qBAAqB;AAChC,YAAM,KAAK,cAAc,EAAE,MAAM,EAAE;AACnC,YAAM,KAAK,sBAAsB,EAAE,gBAAgB,EAAE;AACrD,YAAM,KAAK,qBAAqB,EAAE,eAAe,EAAE;AACnD,YAAM,KAAK,yBAAyB,EAAE,mBAAmB,EAAE;AAAA,IAC7D;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,iBAAiB,QAAQ,IAAY;AACnC,UAAM,OAAO,KAAK,QAAQ,KAAK;AAC/B,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,IAAI,OAAK;AACnB,YAAM,UAAU,EAAE,OAAO,IAAI,KAAK,UAAU,EAAE,IAAI,CAAC,KAAK;AACxD,aAAO,IAAI,EAAE,SAAS,MAAM,EAAE,MAAM,YAAY,CAAC,MAAM,EAAE,QAAQ,KAAK,EAAE,OAAO,GAAG,OAAO;AAAA,IAC3F,CAAC,EAAE,KAAK,IAAI;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,mBAA4B;AAC1B,WAAO,KAAK,OAAO,WAAW,KAAK,OAAO;AAAA,EAC5C;AACF;AAEA,IAAI,eAA8B;AAE3B,SAAS,iBAAiB,QAA6B;AAC5D,iBAAe,IAAI,OAAO,MAAM;AAChC,SAAO;AACT;;;ACzZA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AACzB,IAAM,0BAA0B;AAEzB,SAAS,eAAe,MAAsB;AACnD,SAAO,KAAK,KAAK,KAAK,SAAS,eAAe;AAChD;AAEA,SAAS,wBAAwB,OAAkB,UAA4B;AAC7E,QAAM,QAAkB,CAAC;AAEzB,QAAM,WAAW,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAC9C,QAAM,UAAU,SAAS,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,KAAK,GAAG;AAE1D,QAAM,kBAA0C;AAAA,IAC9C,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,IAAI;AAAA,IACJ,MAAM;AAAA,EACR;AAEA,QAAM,kBAA0C;AAAA,IAC9C,sBAAsB;AAAA,IACtB,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,+BAA+B;AAAA,IAC/B,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,uBAAuB;AAAA,IACvB,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,wBAAwB;AAAA,IACxB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,WAAW;AAAA,IACX,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAEA,QAAM,OAAO,gBAAgB,MAAM,QAAQ,KAAK,MAAM;AACtD,QAAM,WAAW,gBAAgB,MAAM,SAAS,KAAK,MAAM;AAE3D,MAAI,MAAM,MAAM;AACd,UAAM,KAAK,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,IAAI,GAAG;AAAA,EAClD,OAAO;AACL,UAAM,KAAK,GAAG,IAAI,IAAI,QAAQ,EAAE;AAAA,EAClC;AAEA,MAAI,SAAS;AACX,UAAM,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;AAAA,EACxC,OAAO;AACL,UAAM,KAAK,MAAM,QAAQ,EAAE;AAAA,EAC7B;AAEA,QAAM,gBAAgB,qBAAqB,MAAM,QAAQ,IAAI,MAAM,OAAO;AAC1E,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,KAAK,YAAY,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,EACnD;AAEA,SAAO;AACT;AAEA,SAAS,mBACP,aACA,SACA,WACA,WACQ;AACR,QAAM,QAAQ,CAAC,GAAG,WAAW;AAC7B,MAAI,aAAa,YAAY,KAAK,WAAW;AAC3C,UAAM,KAAK,QAAQ,SAAS,IAAI,SAAS,EAAE;AAAA,EAC7C;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,OAAO;AAClB,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,sBAAsB,SAAiB,iBAAmC;AACjF,MAAI,QAAQ,UAAU,iBAAiB;AACrC,WAAO,CAAC,OAAO;AAAA,EACjB;AAEA,QAAM,eAAe,KAAK;AAAA,IACxB,kBAAkB;AAAA,IAClB,KAAK,IAAI,KAAK,MAAM,kBAAkB,IAAI,GAAG,kBAAkB,GAAG;AAAA,EACpE;AACA,QAAM,YAAY,KAAK,IAAI,GAAG,kBAAkB,YAAY;AAC5D,QAAM,WAAqB,CAAC;AAE5B,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,WAAW;AAC9D,UAAM,MAAM,KAAK,IAAI,QAAQ,QAAQ,QAAQ,eAAe;AAC5D,aAAS,KAAK,QAAQ,MAAM,OAAO,GAAG,CAAC;AACvC,QAAI,OAAO,QAAQ,QAAQ;AACzB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,qBACd,OACA,UACA,iBAAiB,yBACP;AACV,QAAM,cAAc,wBAAwB,OAAO,QAAQ;AAC3D,QAAM,eAAe,mBAAmB,aAAa,IAAI,GAAG,CAAC,EAAE;AAC/D,QAAM,kBAAkB,KAAK,IAAI,GAAG,iBAAiB,kBAAkB,YAAY;AACnF,QAAM,WAAW,sBAAsB,MAAM,SAAS,eAAe;AAErE,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,CAAC,mBAAmB,aAAa,SAAS,CAAC,CAAC,CAAC;AAAA,EACtD;AAEA,SAAO,SAAS;AAAA,IAAI,CAAC,SAAS,UAC5B,mBAAmB,aAAa,SAAS,QAAQ,GAAG,SAAS,MAAM;AAAA,EACrE;AACF;AAoBO,SAAS,qBACd,QACA,UAA+B,CAAC,GACzB;AACP,QAAM,UAAiB,CAAC;AACxB,MAAI,eAAoB,CAAC;AACzB,MAAI,gBAAgB;AACpB,QAAM,iBAAiB,KAAK,IAAI,GAAG,QAAQ,kBAAkB,gBAAgB;AAC7E,QAAM,gBAAgB,KAAK,IAAI,GAAG,QAAQ,iBAAiB,OAAO,gBAAgB;AAElF,aAAW,SAAS,QAAQ;AAC1B,UAAM,cAAc,MAAM,cAAc,eAAe,MAAM,IAAI;AAEjE,QACE,aAAa,SAAS,MAClB,gBAAgB,cAAc,kBAAkB,aAAa,UAAU,gBAC3E;AACA,cAAQ,KAAK,YAAY;AACzB,qBAAe,CAAC;AAChB,sBAAgB;AAAA,IAClB;AAEA,iBAAa,KAAK,KAAK;AACvB,qBAAiB;AAAA,EACnB;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,YAAQ,KAAK,YAAY;AAAA,EAC3B;AAEA,SAAO;AACT;AAEA,SAAS,qBAAqB,MAAc,SAA2B;AACrE,QAAM,QAAkB,CAAC;AACzB,QAAM,WAAW,GAAG,IAAI,IAAI,OAAO,GAAG,YAAY;AAElD,QAAM,YAAY,yBAAyB,OAAO;AAClD,MAAI,WAAW;AACb,UAAM,KAAK,SAAS;AAAA,EACtB;AAEA,QAAM,WAAoC;AAAA,IACxC,CAAC,gDAAgD,gBAAgB;AAAA,IACjE,CAAC,+BAA+B,mBAAmB;AAAA,IACnD,CAAC,2BAA2B,kBAAkB;AAAA,IAC9C,CAAC,gCAAgC,iBAAiB;AAAA,IAClD,CAAC,qCAAqC,eAAe;AAAA,IACrD,CAAC,iCAAiC,YAAY;AAAA,IAC9C,CAAC,gCAAgC,gBAAgB;AAAA,IACjD,CAAC,8BAA8B,SAAS;AAAA,IACxC,CAAC,wBAAwB,SAAS;AAAA,IAClC,CAAC,oCAAoC,UAAU;AAAA,IAC/C,CAAC,gCAAgC,UAAU;AAAA,IAC3C,CAAC,gCAAgC,iBAAiB;AAAA,IAClD,CAAC,6BAA6B,cAAc;AAAA,IAC5C,CAAC,uDAAuD,yBAAyB;AAAA,IACjF,CAAC,+BAA+B,SAAS;AAAA,IACzC,CAAC,8BAA8B,eAAe;AAAA,IAC9C,CAAC,iDAAiD,oBAAoB;AAAA,IACtE,CAAC,mCAAmC,cAAc;AAAA,IAClD,CAAC,+BAA+B,kBAAkB;AAAA,IAClD,CAAC,8BAA8B,aAAa;AAAA,EAC9C;AAEA,aAAW,CAAC,SAAS,IAAI,KAAK,UAAU;AACtC,QAAI,QAAQ,KAAK,QAAQ,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG;AACnD,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,SAAO,MAAM,MAAM,GAAG,CAAC;AACzB;AAEA,SAAS,yBAAyB,SAAgC;AAChE,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,aAAa,CAAC,0EAA0E;AAE9F,QAAM,eAAe,CAAC,qFAAqF;AAE3G,aAAW,WAAW,CAAC,GAAG,cAAc,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG;AACtF,UAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,QAAI,OAAO;AACT,YAAM,WAAW,MAAM,CAAC;AACxB,YAAM,SAAS,MAAM,CAAC,GAAG,KAAK,KAAK;AACnC,YAAM,cAAc,MAAM,CAAC,KAAK,MAAM,CAAC,IAAI,KAAK;AAEhD,YAAM,aAAa,kBAAkB,MAAM;AAE3C,UAAI,MAAM,GAAG,QAAQ,IAAI,WAAW,KAAK,IAAI,CAAC;AAC9C,UAAI,cAAc,WAAW,SAAS,IAAI;AACxC,eAAO,OAAO,WAAW,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC;AAAA,MACtD;AAEA,UAAI,IAAI,SAAS,KAAK;AACpB,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAA0B;AACnD,MAAI,CAAC,OAAO,KAAK,EAAG,QAAO,CAAC;AAE5B,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAQ,OAAO,MAAM,GAAG;AAE9B,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AAEd,UAAM,UAAU,QAAQ,MAAM,gBAAgB;AAC9C,UAAM,UAAU,QAAQ,MAAM,kBAAkB;AAChD,UAAM,UAAU,QAAQ,MAAM,aAAa;AAC3C,UAAM,YAAY,QAAQ,MAAM,YAAY;AAE5C,UAAM,QAAQ,WAAW,WAAW,WAAW;AAC/C,QAAI,SAAS,MAAM,CAAC,MAAM,UAAU,MAAM,CAAC,MAAM,QAAQ;AACvD,YAAM,KAAK,MAAM,CAAC,CAAC;AAAA,IACrB;AAAA,EACF;AAEA,SAAO,MAAM,MAAM,GAAG,CAAC;AACzB;;;ACjSA,IAAAC,MAAoB;AACpB,IAAAC,SAAsB;AACtB,IAAAC,UAAwB;AACxB,sBAA8B;;;ACH9B;AAAA,EACE,SAAW;AAAA,IACT,SAAW;AAAA,MACT,aAAe;AAAA,MACf,aAAe;AAAA,MACf,YAAc;AAAA,MACd,WAAa;AAAA,MACb,eAAiB;AAAA,IACnB;AAAA,IACA,QAAU;AAAA,MACR,aAAe;AAAA,MACf,aAAe;AAAA,MACf,YAAc;AAAA,MACd,WAAa;AAAA,MACb,eAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EACA,QAAU;AAAA,IACR,YAAc;AAAA,EAChB;AACF;;;ACIO,IAAM,mBAAmB;AAEzB,IAAM,kBAAkB,iBAAiB,QAAQ;AACjD,IAAM,iBAAiB,iBAAiB,QAAQ;AAEhD,IAAM,0BAA0B,gBAAgB;AAChD,IAAM,0BAA0B,gBAAgB;AAChD,IAAM,4BAA4B,iBAAiB,OAAO;;;AF/BjE;AAOO,SAAS,yBACdC,YAA+B,aAAS,GACxCC,QAA+B,SAAK,GAC5B;AACR,MAAID,cAAa,YAAYC,UAAS,SAAS;AAC7C,WAAO,GAAG,yBAAyB;AAAA,EACrC;AACA,MAAID,cAAa,YAAYC,UAAS,OAAO;AAC3C,WAAO,GAAG,yBAAyB;AAAA,EACrC;AACA,MAAID,cAAa,WAAWC,UAAS,OAAO;AAC1C,WAAO,GAAG,yBAAyB;AAAA,EACrC;AACA,MAAID,cAAa,WAAWC,UAAS,SAAS;AAC5C,WAAO,GAAG,yBAAyB;AAAA,EACrC;AACA,MAAID,cAAa,WAAWC,UAAS,OAAO;AAC1C,WAAO,GAAG,yBAAyB;AAAA,EACrC;AAEA,QAAM,IAAI,MAAM,yBAAyBD,SAAQ,IAAIC,KAAI,EAAE;AAC7D;AAEO,SAAS,yBACd,aACAD,YAA+B,aAAS,GACxCC,QAA+B,SAAK,GAC5B;AACR,SAAY,YAAK,aAAa,UAAU,yBAAyBD,WAAUC,KAAI,CAAC;AAClF;AAEA,SAAS,mBAAmB;AAE1B,MAAI;AACJ,MAAI;AAGJ,MAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,iBAAkB,mBAAQ,+BAAc,YAAY,GAAG,CAAC;AACxD,oBAAgB,YAAY;AAAA,EAC9B,WAES,OAAO,cAAc,aAAa;AACzC,iBAAa;AACb,oBAAgB;AAAA,EAClB,OAEK;AACH,iBAAa,QAAQ,IAAI;AACzB,oBAAqB,YAAK,YAAY,UAAU;AAAA,EAClD;AAKA,QAAM,gBAAgB,WAAW,QAAQ,OAAO,GAAG;AACnD,QAAM,YAAY,cAAc,SAAS,aAAa,KAAK,WAAW,SAAc,YAAK,OAAO,QAAQ,CAAC;AACzG,QAAM,cAAc,YACX,eAAQ,YAAY,OAAO,IAC3B,eAAQ,YAAY,IAAI;AACjC,QAAM,aAAa,yBAAyB,WAAW;AAGvD,QAAMC,WAAiB,sBAAc,aAAa;AAClD,SAAOA,SAAQ,UAAU;AAC3B;AAEA,SAAS,0BAA0B;AACjC,QAAM,QAAQ,IAAI,MAAM,0EAA0E;AAElG,SAAO;AAAA,IACL,WAAW,MAAM;AACf,YAAM;AAAA,IACR;AAAA,IACA,YAAY,MAAM;AAChB,YAAM;AAAA,IACR;AAAA,IACA,aAAa,MAAM;AACjB,YAAM;AAAA,IACR;AAAA,IACA,UAAU,MAAM;AACd,YAAM;AAAA,IACR;AAAA,IACA,cAAc,MAAM;AAClB,YAAM;AAAA,IACR;AAAA,IACA,aAAa,MAAM;AAAA,MACjB,cAAc;AACZ,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,eAAe,MAAM;AAAA,MACnB,cAAc;AACZ,cAAM;AAAA,MACR;AAAA,MACA,YAAY;AACV,cAAM;AAAA,MACR;AAAA,MACA,cAAc;AACZ,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,UAAU,MAAM;AAAA,MACd,cAAc;AACZ,cAAM;AAAA,MACR;AAAA,MACA,OAAO,eAAe;AACpB,cAAM;AAAA,MACR;AAAA,MACA,OAAO,sBAAsB;AAC3B,cAAM;AAAA,MACR;AAAA,MACA,QAAQ;AACN,cAAM;AAAA,MACR;AAAA,MACA,4BAA4B;AAC1B,cAAM;AAAA,MACR;AAAA,MACA,oBAAoB;AAClB,cAAM;AAAA,MACR;AAAA,MACA,2BAA2B;AACzB,cAAM;AAAA,MACR;AAAA,MACA,oBAAoB;AAClB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAI;AACJ,IAAI;AACF,WAAS,iBAAiB;AAC5B,SAAS,GAAG;AACV,UAAQ,MAAM,kDAAkD,CAAC;AACjE,WAAS,wBAAwB;AACnC;;;AGxIO,SAAS,gBAAgB,UAAkB,SAAiB,eAAqC;AACtG,QAAM,SAAS,OAAO,gBAAgB,UAAU,SAAS,aAAa;AACtE,SAAO,OAAO,IAAI,QAAQ;AAC5B;AAEO,SAAS,WAAW,OAAoB,eAAsC;AACnF,QAAM,SAAS,OAAO,WAAW,OAAO,aAAa;AACrD,SAAO,OAAO,IAAI,CAAC,OAAY;AAAA,IAC7B,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE,OAAO,IAAI,QAAQ;AAAA,IAC7B,UAAU,EAAE,WAAW,CAAC,GAAG,IAAI,eAAe;AAAA,IAC9C,MAAM,EAAE;AAAA,EACV,EAAE;AACJ;AAEA,SAAS,gBAAgB,QAA2B;AAClD,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,MAAM,OAAO;AAAA,IACb,WAAW,OAAO,aAAa,OAAO;AAAA,IACtC,UAAU,OAAO,YAAY,OAAO;AAAA,IACpC,SAAS,OAAO,WAAW,OAAO;AAAA,IAClC,QAAQ,OAAO,UAAU,OAAO;AAAA,IAChC,UAAU,OAAO;AAAA,EACnB;AACF;AAEA,SAAS,SAAS,GAAmB;AACnC,SAAO;AAAA,IACL,SAAS,EAAE;AAAA,IACX,WAAW,EAAE,aAAa,EAAE;AAAA,IAC5B,UAAU,EAAE,YAAY,EAAE;AAAA,IAC1B,SAAS,EAAE,WAAW,EAAE;AAAA,IACxB,QAAQ,EAAE,UAAU,EAAE;AAAA,IACtB,WAAY,EAAE,aAAa,EAAE;AAAA,IAC7B,MAAM,EAAE,QAAQ;AAAA,IAChB,UAAU,EAAE;AAAA,EACd;AACF;AAEO,SAAS,YAAY,SAAyB;AACnD,SAAO,OAAO,YAAY,OAAO;AACnC;AAEO,SAAS,SAAS,UAA0B;AACjD,SAAO,OAAO,SAAS,QAAQ;AACjC;AAEO,SAAS,aAAa,SAAiB,UAAkC;AAC9E,SAAO,OAAO,aAAa,SAAS,QAAQ;AAC9C;AAEO,SAAS,gBAAgB,UAAkB,OAA0B;AAC1E,QAAM,OAAO,YAAY,GAAG,QAAQ,IAAI,MAAM,SAAS,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO,EAAE;AAC3F,SAAO,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC;AACnC;AAEO,SAAS,kBAAkB,OAA0B;AAC1D,SAAO,YAAY,MAAM,OAAO;AAClC;;;AChEO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EAER,YAAY,WAAmB,YAAoB;AACjD,SAAK,QAAQ,IAAI,OAAO,YAAY,WAAW,UAAU;AACzD,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,IAAI,IAAY,QAAkB,UAA+B;AAC/D,QAAI,OAAO,WAAW,KAAK,YAAY;AACrC,YAAM,IAAI;AAAA,QACR,uCAAuC,KAAK,UAAU,SAAS,OAAO,MAAM;AAAA,MAC9E;AAAA,IACF;AACA,SAAK,MAAM,IAAI,IAAI,QAAQ,KAAK,UAAU,QAAQ,CAAC;AAAA,EACrD;AAAA,EAEA,SACE,OACM;AACN,UAAM,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;AACjC,UAAM,UAAU,MAAM,IAAI,CAAC,MAAM;AAC/B,UAAI,EAAE,OAAO,WAAW,KAAK,YAAY;AACvC,cAAM,IAAI;AAAA,UACR,iCAAiC,EAAE,EAAE,cAAc,KAAK,UAAU,SAAS,EAAE,OAAO,MAAM;AAAA,QAC5F;AAAA,MACF;AACA,aAAO,EAAE;AAAA,IACX,CAAC;AACD,UAAM,WAAW,MAAM,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAC5D,SAAK,MAAM,SAAS,KAAK,SAAS,QAAQ;AAAA,EAC5C;AAAA,EAEA,OAAO,aAAuB,QAAgB,IAAI,YAAuC;AACvF,QAAI,YAAY,WAAW,KAAK,YAAY;AAC1C,YAAM,IAAI;AAAA,QACR,6CAA6C,KAAK,UAAU,SAAS,YAAY,MAAM;AAAA,MACzF;AAAA,IACF;AACA,UAAM,UAAU,eAAe,SAC3B,KAAK,MAAM,OAAO,aAAa,KAAK,IACpC,KAAK,MAAM,eAAe,aAAa,OAAO,UAAU;AAC5D,WAAO,QAAQ,IAAI,CAAC,OAAY;AAAA,MAC9B,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,UAAU,KAAK,MAAM,EAAE,QAAQ;AAAA,IACjC,EAAE;AAAA,EACJ;AAAA,EAEA,OAAO,IAAqB;AAC1B,WAAO,KAAK,MAAM,OAAO,EAAE;AAAA,EAC7B;AAAA,EAEA,OAAa;AACX,SAAK,MAAM,KAAK;AAAA,EAClB;AAAA,EAEA,OAAa;AACX,SAAK,MAAM,KAAK;AAAA,EAClB;AAAA,EAEA,aAAmB;AACjB,SAAK,MAAM,WAAW;AAAA,EACxB;AAAA,EAEA,iBAA0B;AACxB,WAAO,KAAK,MAAM,eAAe;AAAA,EACnC;AAAA,EAEA,QAAgB;AACd,WAAO,KAAK,MAAM,MAAM;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAuB;AACrB,WAAO,KAAK,MAAM,WAAW;AAAA,EAC/B;AAAA,EAEA,iBAAkE;AAChE,UAAM,UAAU,KAAK,MAAM,eAAe;AAC1C,WAAO,QAAQ,IAAI,CAAC,OAA0C;AAAA,MAC5D,KAAK,EAAE;AAAA,MACP,UAAU,KAAK,MAAM,EAAE,QAAQ;AAAA,IACjC,EAAE;AAAA,EACJ;AAAA,EAEA,YAAY,IAAuC;AACjD,UAAM,SAAS,KAAK,MAAM,YAAY,EAAE;AACxC,QAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM,MAAM;AAAA,EAC1B;AAAA,EAEA,iBAAiB,KAA2C;AAC1D,UAAM,UAAU,KAAK,MAAM,iBAAiB,GAAG;AAC/C,UAAM,MAAM,oBAAI,IAA2B;AAC3C,eAAW,EAAE,KAAK,SAAS,KAAK,SAAS;AACvC,UAAI,IAAI,KAAK,KAAK,MAAM,QAAQ,CAAkB;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AACF;;;AC/GO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EAER,YAAY,WAAmB;AAC7B,SAAK,QAAQ,IAAI,OAAO,cAAc,SAAS;AAAA,EACjD;AAAA,EAEA,OAAa;AACX,SAAK,MAAM,KAAK;AAAA,EAClB;AAAA,EAEA,OAAa;AACX,SAAK,MAAM,KAAK;AAAA,EAClB;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK,MAAM,UAAU;AAAA,EAC9B;AAAA,EAEA,YAAY,MAAoB;AAC9B,SAAK,MAAM,YAAY,IAAI;AAAA,EAC7B;AAAA,EAEA,SAAS,SAAiB,SAAuB;AAC/C,SAAK,MAAM,SAAS,SAAS,OAAO;AAAA,EACtC;AAAA,EAEA,YAAY,SAA0B;AACpC,WAAO,KAAK,MAAM,YAAY,OAAO;AAAA,EACvC;AAAA,EAEA,OAAO,OAAe,OAAqC;AACzD,UAAM,UAAU,KAAK,MAAM,OAAO,OAAO,SAAS,GAAG;AACrD,UAAM,MAAM,oBAAI,IAAoB;AACpC,eAAW,KAAK,SAAS;AACvB,UAAI,IAAI,EAAE,SAAS,EAAE,KAAK;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,SAA0B;AACjC,WAAO,KAAK,MAAM,SAAS,OAAO;AAAA,EACpC;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,mBAA2B;AACzB,WAAO,KAAK,MAAM,cAAc;AAAA,EAClC;AACF;;;ACvCO,IAAM,WAAN,MAAM,UAAS;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,EAEjB,YAAY,QAAgB;AAC1B,SAAK,QAAQ,IAAI,OAAO,SAAS,MAAM;AAAA,EACzC;AAAA,EAEA,OAAe,WAAW,OAAsB;AAC9C,UAAM,WAAW,OAAO,OAAO,UAAS,SAAS;AACjD,aAAS,QAAQ;AACjB,aAAS,SAAS;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,aAAa,QAA0B;AAC5C,WAAO,UAAS,WAAW,OAAO,SAAS,aAAa,MAAM,CAAC;AAAA,EACjE;AAAA,EAEA,OAAO,sBAAgC;AACrC,WAAO,UAAS,WAAW,OAAO,SAAS,oBAAoB,CAAC;AAAA,EAClE;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,QAAQ;AACf,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,QAAQ;AACf;AAAA,IACF;AAEA,QAAI,OAAO,KAAK,MAAM,UAAU,YAAY;AAC1C,WAAK,MAAM,MAAM;AAAA,IACnB;AAEA,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,wBAA8B;AAC5B,SAAK,cAAc;AACnB,SAAK,MAAM,sBAAsB;AAAA,EACnC;AAAA,EAEA,yBAA+B;AAC7B,SAAK,cAAc;AACnB,SAAK,MAAM,uBAAuB;AAAA,EACpC;AAAA,EAEA,2BAAiC;AAC/B,SAAK,cAAc;AACnB,SAAK,MAAM,yBAAyB;AAAA,EACtC;AAAA,EAEA,gBAAgB,aAA8B;AAC5C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,gBAAgB,WAAW;AAAA,EAC/C;AAAA,EAEA,aAAa,aAAoC;AAC/C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,aAAa,WAAW,KAAK;AAAA,EACjD;AAAA,EAEA,gBACE,aACA,WACA,WACA,OACM;AACN,SAAK,cAAc;AACnB,SAAK,MAAM,gBAAgB,aAAa,WAAW,WAAW,KAAK;AAAA,EACrE;AAAA,EAEA,sBACE,OAMM;AACN,SAAK,cAAc;AACnB,QAAI,MAAM,WAAW,EAAG;AACxB,SAAK,MAAM,sBAAsB,KAAK;AAAA,EACxC;AAAA,EAEA,qBAAqB,eAAmC;AACtD,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,qBAAqB,aAAa;AAAA,EACtD;AAAA,EAEA,YAAY,OAAwB;AAClC,SAAK,cAAc;AACnB,SAAK,MAAM,YAAY,KAAK;AAAA,EAC9B;AAAA,EAEA,kBAAkB,QAA2B;AAC3C,SAAK,cAAc;AACnB,QAAI,OAAO,WAAW,EAAG;AACzB,SAAK,MAAM,kBAAkB,MAAM;AAAA,EACrC;AAAA,EAEA,SAAS,SAAmC;AAC1C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,SAAS,OAAO,KAAK;AAAA,EACzC;AAAA,EAEA,gBAAgB,UAA+B;AAC7C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,gBAAgB,QAAQ;AAAA,EAC5C;AAAA,EAEA,gBAAgB,MAA2B;AACzC,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,gBAAgB,IAAI;AAAA,EACxC;AAAA,EAEA,kBAAkB,MAA2B;AAC3C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,kBAAkB,IAAI;AAAA,EAC1C;AAAA,EAEA,mBAAmB,UAA0B;AAC3C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,mBAAmB,QAAQ;AAAA,EAC/C;AAAA,EAEA,kBAAkB,UAA4B;AAC5C,SAAK,cAAc;AACnB,QAAI,SAAS,WAAW,EAAG,QAAO;AAClC,WAAO,KAAK,MAAM,kBAAkB,QAAQ;AAAA,EAC9C;AAAA,EAEA,kBAAkB,QAAgB,UAA0B;AAC1D,SAAK,cAAc;AACnB,SAAK,MAAM,kBAAkB,QAAQ,QAAQ;AAAA,EAC/C;AAAA,EAEA,uBAAuB,QAAgB,UAA0B;AAC/D,SAAK,cAAc;AACnB,QAAI,SAAS,WAAW,EAAG;AAC3B,SAAK,MAAM,uBAAuB,QAAQ,QAAQ;AAAA,EACpD;AAAA,EAEA,YAAY,QAAwB;AAClC,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,YAAY,MAAM;AAAA,EACtC;AAAA,EAEA,6BAA6B,UAA4B;AACvD,SAAK,cAAc;AACnB,QAAI,SAAS,WAAW,EAAG,QAAO;AAClC,WAAO,KAAK,MAAM,6BAA6B,QAAQ;AAAA,EACzD;AAAA,EAEA,4BAA4B,QAAgB,UAA4B;AACtE,SAAK,cAAc;AACnB,QAAI,SAAS,WAAW,EAAG,QAAO;AAClC,WAAO,KAAK,MAAM,4BAA4B,QAAQ,QAAQ;AAAA,EAChE;AAAA,EAEA,kBAAkB,QAA0B;AAC1C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,kBAAkB,MAAM;AAAA,EAC5C;AAAA,EAEA,uBAAuB,OAAgB,OAA0B;AAC/D,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,uBAAuB,OAAO,KAAK;AAAA,EACvD;AAAA,EAEA,eAAe,QAAgB,YAAiC;AAC9D,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,eAAe,QAAQ,UAAU;AAAA,EACrD;AAAA,EAEA,sBAAsB,UAA8B;AAClD,SAAK,cAAc;AACnB,QAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AACnC,WAAO,KAAK,MAAM,sBAAsB,QAAQ;AAAA,EAClD;AAAA,EAEA,oBAAoB,QAAgB,SAA0B;AAC5D,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,oBAAoB,QAAQ,OAAO;AAAA,EACvD;AAAA,EAEA,iBAA2B;AACzB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,eAAe;AAAA,EACnC;AAAA,EAEA,YAAY,KAA4B;AACtC,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,YAAY,GAAG,KAAK;AAAA,EACxC;AAAA,EAEA,YAAY,KAAa,OAAqB;AAC5C,SAAK,cAAc;AACnB,SAAK,MAAM,YAAY,KAAK,KAAK;AAAA,EACnC;AAAA,EAEA,eAAe,KAAsB;AACnC,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,eAAe,GAAG;AAAA,EACtC;AAAA,EAEA,sBAA4B;AAC1B,SAAK,cAAc;AACnB,SAAK,MAAM,oBAAoB;AAAA,EACjC;AAAA,EAEA,+BAA+B,WAA6B;AAC1D,SAAK,cAAc;AACnB,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,WAAO,KAAK,MAAM,+BAA+B,SAAS;AAAA,EAC5D;AAAA,EAEA,qBAA6B;AAC3B,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,mBAAmB;AAAA,EACvC;AAAA,EAEA,iBAAyB;AACvB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,eAAe;AAAA,EACnC;AAAA,EAEA,WAA0B;AACxB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,SAAS;AAAA,EAC7B;AAAA,EAEA,aAAa,QAA0B;AACrC,SAAK,cAAc;AACnB,SAAK,MAAM,aAAa,MAAM;AAAA,EAChC;AAAA,EAEA,mBAAmB,SAA6B;AAC9C,SAAK,cAAc;AACnB,QAAI,QAAQ,WAAW,EAAG;AAC1B,SAAK,MAAM,mBAAmB,OAAO;AAAA,EACvC;AAAA,EAEA,iBAAiB,UAAgC;AAC/C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,iBAAiB,QAAQ;AAAA,EAC7C;AAAA,EAEA,gBAAgB,MAAc,UAAqC;AACjE,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,gBAAgB,MAAM,QAAQ,KAAK;AAAA,EACvD;AAAA,EAEA,iBAAiB,MAA4B;AAC3C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,iBAAiB,IAAI;AAAA,EACzC;AAAA,EAEA,mBAAmB,MAA4B;AAC7C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,mBAAmB,IAAI;AAAA,EAC3C;AAAA,EACA,oBAAoB,QAA8B;AAChD,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,oBAAoB,MAAM;AAAA,EAC9C;AAAA,EAEA,mBAAmB,WAAqB,QAA8B;AACpE,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,mBAAmB,WAAW,MAAM;AAAA,EACxD;AAAA,EAEA,oBAAoB,UAA0B;AAC5C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,oBAAoB,QAAQ;AAAA,EAChD;AAAA,EAEA,eAAe,MAA0B;AACvC,SAAK,cAAc;AACnB,SAAK,MAAM,eAAe,IAAI;AAAA,EAChC;AAAA,EAEA,qBAAqB,OAA6B;AAChD,SAAK,cAAc;AACnB,QAAI,MAAM,WAAW,EAAG;AACxB,SAAK,MAAM,qBAAqB,KAAK;AAAA,EACvC;AAAA,EAEA,WAAW,YAAoB,QAAgB,gBAAyC;AACtF,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,WAAW,YAAY,QAAQ,kBAAkB,IAAI;AAAA,EACzE;AAAA,EAEA,sBACE,YACA,QACA,gBACgB;AAChB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,sBAAsB,YAAY,QAAQ,kBAAkB,IAAI;AAAA,EACpF;AAAA,EAEA,WAAW,UAAkB,QAAgB,gBAAyC;AACpF,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,WAAW,UAAU,QAAQ,kBAAkB,IAAI;AAAA,EACvE;AAAA,EAEA,sBAAsB,UAA0B;AAC9C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,sBAAsB,QAAQ;AAAA,EAClD;AAAA,EAEA,gBAAgB,QAAgB,YAA0B;AACxD,SAAK,cAAc;AACnB,SAAK,MAAM,gBAAgB,QAAQ,UAAU;AAAA,EAC/C;AAAA,EAEA,iBACE,UACA,QACA,QACA,UACe;AACf,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,iBAAiB,UAAU,QAAQ,QAAQ,YAAY,IAAI;AAAA,EAC/E;AAAA,EAEA,mBAAmB,QAAgB,WAA2B;AAC5D,SAAK,cAAc;AACnB,SAAK,MAAM,mBAAmB,QAAQ,SAAS;AAAA,EACjD;AAAA,EAEA,wBAAwB,QAAgB,WAA2B;AACjE,SAAK,cAAc;AACnB,QAAI,UAAU,WAAW,EAAG;AAC5B,SAAK,MAAM,wBAAwB,QAAQ,SAAS;AAAA,EACtD;AAAA,EAEA,mBAAmB,QAA0B;AAC3C,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,mBAAmB,MAAM;AAAA,EAC7C;AAAA,EAEA,mBAAmB,QAAwB;AACzC,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,mBAAmB,MAAM;AAAA,EAC7C;AAAA,EAEA,uBAAuB,WAA+B;AACpD,SAAK,cAAc;AACnB,QAAI,UAAU,WAAW,EAAG,QAAO,CAAC;AACpC,WAAO,KAAK,MAAM,uBAAuB,SAAS;AAAA,EACpD;AAAA,EAEA,+BAA+B,WAA6B;AAC1D,SAAK,cAAc;AACnB,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,WAAO,KAAK,MAAM,+BAA+B,SAAS;AAAA,EAC5D;AAAA,EAEA,6BAA6B,QAAgB,WAA6B;AACxE,SAAK,cAAc;AACnB,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,WAAO,KAAK,MAAM,6BAA6B,QAAQ,SAAS;AAAA,EAClE;AAAA,EAEA,kBAA0B;AACxB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,gBAAgB;AAAA,EACpC;AAAA,EAEA,oBAA4B;AAC1B,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,kBAAkB;AAAA,EACtC;AAAA,EAEA,0BACE,eACA,QACA,WACA,UACoB;AACpB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EAEA,kBACE,QACA,WACiB;AACjB,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,kBAAkB,QAAQ,aAAa,IAAI;AAAA,EAC/D;AAAA,EAEA,kBAAkB,QAAkC;AAClD,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,kBAAkB,MAAM;AAAA,EAC5C;AAAA,EAEA,yBAAyB,QAAyC;AAChE,SAAK,cAAc;AACnB,WAAO,KAAK,MAAM,yBAAyB,MAAM,EAAE,IAAI,CAAC,WAAkC;AAAA,MACxF,GAAG;AAAA,MACH,eAAe,MAAM,+BAA+B,CAAC;AAAA,IACvD,EAAE;AAAA,EACJ;AACF;;;AC7aA,IAAAC,cAAuC;AACvC,IAAAC,MAAoB;AACpB,IAAAC,SAAsB;;;ACFtB,2BAAyB;AACzB,IAAAC,iBAA4B;AAC5B,kBAA0B;AAE1B,IAAM,oBAAgB,uBAAU,6BAAQ;AACxC,IAAM,iBAAiB;AACvB,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG,CAAC;AAmCtE,SAASC,iBAAgB,OAAwB;AACtD,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEO,SAAS,QAAQ,OAAuB;AAC7C,SAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACjE;AAEA,SAAS,mBAAmB,QAAgB,OAAuB;AACjE,MAAI,iBAAiB,gBAAgB;AACnC,WAAO,IAAI;AAAA,MACT,MAAM,KAAK,MAAM,QAAQ,OAAO;AAAA,MAChC,GAAG,MAAM,KAAK,MAAM,OAAO;AAAA,IAC7B;AAAA,EACF;AACA,SAAO,IAAI,MAAM,GAAG,MAAM,KAAKA,iBAAgB,KAAK,CAAC,EAAE;AACzD;AAEO,SAAS,gBAAgB,OAAwB;AACtD,SAAO,eAAe,KAAK,KAAK;AAClC;AAEO,SAAS,kBAAkB,OAAwB;AACxD,MAAI,UAAU,UAAU,gBAAgB,KAAK,EAAG,QAAO;AACvD,MAAI,CAAC,SAAS,MAAM,SAAS,QAAQ,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AAC1G,WAAO;AAAA,EACT;AACA,MACE,MAAM,KAAK,KAAK,EAAE,KAAK,CAAC,cAAc;AACpC,UAAM,OAAO,UAAU,WAAW,CAAC;AACnC,WAAO,QAAQ,MAAQ,SAAS,OAAQ,oBAAoB,IAAI,SAAS;AAAA,EAC3E,CAAC,KACE,MAAM,SAAS,IAAI,KACnB,MAAM,SAAS,IAAI,KACnB,MAAM,SAAS,IAAI,KACnB,MAAM,SAAS,GAAG,GACrB;AACA,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,MAAM,GAAG,EAAE;AAAA,IAAM,CAAC,cAC7B,UAAU,SAAS,KAChB,CAAC,UAAU,WAAW,GAAG,KACzB,CAAC,UAAU,SAAS,GAAG,KACvB,CAAC,UAAU,SAAS,OAAO;AAAA,EAChC;AACF;AAEO,SAAS,sBAAsB,OAAe,QAAQ,WAAiB;AAC5E,MAAI,CAAC,kBAAkB,KAAK,GAAG;AAC7B,UAAM,IAAI,MAAM,GAAG,KAAK,gBAAgB,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EACjE;AACF;AAEO,SAAS,qBAAqB,OAAwB;AAC3D,SAAO,oBAAoB,KAAK,KAAK;AACvC;AAEA,SAAS,yBAAyB,OAAqB;AACrD,MAAI,CAAC,qBAAqB,KAAK,GAAG;AAChC,UAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EACvE;AACF;AAEA,eAAsB,UACpB,aACA,MACA,UAAgC,CAAC,GAChB;AACjB,QAAM,EAAE,OAAO,IAAI,MAAM,cAAc,OAAO,MAAM;AAAA,IAClD,KAAK;AAAA,IACL,SAAS,QAAQ,WAAW;AAAA,IAC5B,UAAU;AAAA,IACV,WAAW,KAAK,OAAO;AAAA,IACvB,KAAK;AAAA,MACH,GAAG,QAAQ;AAAA,MACX,qBAAqB;AAAA,MACrB,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,eAAsB,OACpB,aACA,MACA,UAAgC,CAAC,GAChB;AACjB,UAAQ,MAAM,UAAU,aAAa,MAAM,OAAO,GAAG,KAAK;AAC5D;AAEA,eAAsB,iBAAiB,aAAqB,KAAqC;AAC/F,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,aAAa;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,GAAG;AAAA,IACR,CAAC;AACD,WAAO,gBAAgB,MAAM,IAAI,OAAO,YAAY,IAAI;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,sBAAsB,aAAqB,KAAqC;AACpG,wBAAsB,GAAG;AACzB,SAAO,iBAAiB,aAAa,GAAG;AAC1C;AAEA,eAAsB,4BACpB,aACA,IACsC;AACtC,MAAI,CAAC,OAAO,UAAU,EAAE,KAAK,MAAM,GAAG;AACpC,UAAM,IAAI,MAAM,mDAAmD,EAAE,EAAE;AAAA,EACzE;AAEA,QAAM,UAAU,aAAa,EAAE;AAC/B,QAAM,WAAW,aAAa,EAAE;AAChC,QAAM,aAAa,MAAM,iBAAiB,aAAa,OAAO;AAC9D,QAAM,kBAAkB,MAAM,iBAAiB,aAAa,GAAG,QAAQ,IAAI;AAC3E,QAAM,qBAAqB,cAAc;AACzC,MAAI,CAAC,mBAAoB,QAAO;AAEhC,QAAM,aAAa,oBAAoB,qBACnC,MAAM,iBAAiB,aAAa,GAAG,QAAQ,IAAI,IACnD;AACJ,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY,cAAc;AAAA,EAC5B;AACF;AAEA,SAAS,gBAAgB,KAAuB;AAC9C,MAAI,QAAQ,UAAU,gBAAgB,GAAG,KAAK,IAAI,WAAW,OAAO,GAAG;AACrE,WAAO,CAAC,GAAG;AAAA,EACb;AACA,SAAO,CAAC,cAAc,GAAG,EAAE;AAC7B;AAEA,eAAe,wBAAwB,aAAqB,MAAwC;AAClG,aAAW,OAAO,MAAM;AACtB,UAAM,SAAS,MAAM,iBAAiB,aAAa,GAAG;AACtD,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,KAA2E;AACpG,QAAM,iBAAiB,IAAI,MAAM,gCAAgC;AACjE,MAAI,gBAAgB;AAClB,WAAO,EAAE,QAAQ,eAAe,CAAC,GAAG,QAAQ,eAAe,CAAC,GAAG,UAAU,KAAK;AAAA,EAChF;AAEA,MAAI,IAAI,WAAW,OAAO,KAAK,QAAQ,UAAU,gBAAgB,GAAG,GAAG;AACrE,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,MAAI,SAAS,KAAK,UAAU,IAAI,SAAS,EAAG,QAAO;AACnD,SAAO,EAAE,QAAQ,IAAI,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,GAAG,UAAU,MAAM;AACtF;AAEA,eAAe,eAAe,aAAwC;AACpE,QAAM,SAAS,MAAM,UAAU,aAAa,CAAC,QAAQ,CAAC;AACtD,SAAO,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO;AAC1C;AAEA,eAAe,oBAAoB,aAAqB,QAAwC;AAC9F,2BAAyB,MAAM;AAC/B,QAAM,UAAU,MAAM,eAAe,WAAW;AAChD,SAAO,QAAQ,SAAS,MAAM,IAAI,SAAS;AAC7C;AAEA,SAAS,oBAAoB,OAA8B;AACzD,MAAI,CAAC,SAAS,MAAM,WAAW,GAAG,KAAK,WAAW,KAAK,KAAK,EAAG,QAAO;AACtE,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,WAAW,EAAE;AACrE,QAAM,WAAW,QAAQ,MAAM,2BAA2B;AAC1D,QAAM,WAAW,WAAW,SAAS,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,KAAK;AACpE,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,UAAM,iBAAiB,IAAI,SAAS,QAAQ,cAAc,EAAE;AAC5D,QAAI,CAAC,IAAI,YAAY,CAAC,eAAgB,QAAO;AAC7C,WAAO,GAAG,IAAI,SAAS,YAAY,CAAC,IAAI,eAAe,YAAY,CAAC;AAAA,EACtE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,6BACb,aACA,YACiB;AACjB,QAAM,WAAW,MAAM,eAAe,WAAW,GAAG,OAAO,oBAAoB;AAC/E,MAAI,YAAY;AACd,UAAM,qBAAqB,oBAAoB,UAAU;AACzD,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,IAC/E;AAEA,eAAW,UAAU,SAAS;AAC5B,YAAM,YAAY,MAAM,OAAO,aAAa,CAAC,UAAU,WAAW,MAAM,MAAM,CAAC;AAC/E,UAAI,oBAAoB,SAAS,MAAM,oBAAoB;AACzD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,QAAM,IAAI;AAAA,IACR,QAAQ,WAAW,IACf,8EACA;AAAA,EACN;AACF;AAEA,eAAe,mBACb,aACA,cACA,gBACe;AACf,QAAM,OAAO,aAAa,CAAC,cAAc,MAAM,cAAc,cAAc,CAAC;AAC5E,QAAM,YAAY,MAAM,iBAAiB,aAAa,YAAY;AAClE,MAAI,WAAW;AACb,UAAM,IAAI,MAAM,qBAAqB,YAAY,eAAe,SAAS,GAAG;AAAA,EAC9E;AACF;AAEA,eAAe,+BACb,aACA,YACA,WACA,gBACiB;AACjB,wBAAsB,WAAW,kBAAkB;AACnD,MAAI,qBAAqB,UAAU,GAAG;AACpC,UAAM,mBAAmB,MAAM,oBAAoB,aAAa,UAAU;AAC1E,QAAI,CAAC,kBAAkB;AACrB,YAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,IAC/E;AAAA,EACF,WAAW,CAAC,oBAAoB,UAAU,GAAG;AAC3C,UAAM,IAAI,MAAM,oCAAoC,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,EAClF;AAEA,QAAM,eAAe,6BAA6B,QAAQ,GAAG,QAAI,4BAAY,EAAE,EAAE,SAAS,KAAK,CAAC;AAChG,wBAAsB,cAAc,mBAAmB;AACvD,MAAI,SAAwB;AAC5B,MAAI;AAEJ,MAAI;AACF,UAAM,OAAO,aAAa;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,SAAS,IAAI,YAAY;AAAA,IAC/B,CAAC;AACD,aAAS,MAAM,iBAAiB,aAAa,YAAY;AACzD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,eAAe,KAAK,UAAU,SAAS,CAAC,+BAA+B;AAAA,IACzF;AACA,QAAI,kBAAkB,WAAW,eAAe,YAAY,GAAG;AAC7D,YAAM,IAAI;AAAA,QACR,eAAe,KAAK,UAAU,SAAS,CAAC,gBAAgB,MAAM,yCAAyC,cAAc;AAAA,MACvH;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,iBAAa;AAAA,EACf;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,kBAAkB,UAAU,MAAM,iBAAiB,aAAa,YAAY;AAClF,QAAI,iBAAiB;AACnB,YAAM,mBAAmB,aAAa,cAAc,eAAe;AAAA,IACrE;AAAA,EACF,SAAS,OAAO;AACd,mBAAe;AAAA,EACjB;AAEA,MAAI,eAAe,UAAa,iBAAiB,QAAW;AAC1D,UAAM,IAAI;AAAA,MACR,CAAC,QAAQ,UAAU,GAAG,QAAQ,YAAY,CAAC;AAAA,MAC3C,GAAGA,iBAAgB,UAAU,CAAC,uCAAuCA,iBAAgB,YAAY,CAAC;AAAA,IACpG;AAAA,EACF;AACA,MAAI,eAAe,OAAW,OAAM;AACpC,MAAI,iBAAiB,OAAW,OAAM;AACtC,SAAO;AACT;AAEA,eAAsB,cACpB,SACgC;AAChC,QAAM,eAAe,QAAQ,OAAO,QAAQ;AAC5C,QAAM,sBAAsB,QAAQ,gBAAgB,YAAY;AAEhE,MAAI,QAAQ,OAAO,QAAW;AAC5B,UAAM,iBAAiB,wBACjB,gBAAgB,YAAY,IAAI,aAAa,YAAY,IAAI;AACnE,UAAM,kBAAkB,MAAM,iBAAiB,QAAQ,aAAa,aAAa,QAAQ,EAAE,OAAO;AAClG,QAAI,oBAAoB,CAAC,kBAAkB,oBAAoB,iBAAiB;AAC9E,aAAO,EAAE,QAAQ,iBAAiB,QAAQ,YAAY,SAAS,MAAM;AAAA,IACvE;AAEA,QAAI,kBAAkB,MAAM,iBAAiB,QAAQ,aAAa,cAAc,GAAG;AACjF,aAAO,EAAE,QAAQ,gBAAgB,QAAQ,SAAS,SAAS,MAAM;AAAA,IACnE;AAEA,UAAM,aAAa,MAAM,6BAA6B,QAAQ,aAAa,QAAQ,UAAU;AAC7F,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QACnB,QAAQ;AAAA,QACR;AAAA,QACA,aAAa,QAAQ,EAAE;AAAA,QACvB;AAAA,MACF;AACA,aAAO,EAAE,QAAQ,QAAQ,YAAY,SAAS,KAAK;AAAA,IACrD,SAAS,OAAO;AACd,YAAM;AAAA,QACJ,uBAAuB,QAAQ,EAAE,SAAS,KAAK,UAAU,UAAU,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,kBAAkB,YAAY;AACnD,MAAI,cAAc;AAChB,QAAI,CAAC,qBAAqB,aAAa,MAAM,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU,aAAa,MAAM,CAAC,EAAE;AAAA,IACrF;AACA,UAAM,SAAS,MAAM,oBAAoB,QAAQ,aAAa,aAAa,MAAM;AACjF,QAAI,QAAQ;AACV,UAAI;AACF,cAAM,SAAS,MAAM;AAAA,UACnB,QAAQ;AAAA,UACR;AAAA,UACA,cAAc,aAAa,MAAM;AAAA,UACjC;AAAA,QACF;AACA,eAAO,EAAE,QAAQ,QAAQ,gBAAgB,SAAS,KAAK;AAAA,MACzD,SAAS,OAAO;AACd,cAAM;AAAA,UACJ,0BAA0B,KAAK,UAAU,YAAY,CAAC,gBAAgB,KAAK,UAAU,MAAM,CAAC;AAAA,UAC5F;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,aAAa,UAAU;AACzB,YAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,aAAa,MAAM,CAAC,EAAE;AAAA,IACxF;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,wBAAwB,QAAQ,aAAa,gBAAgB,YAAY,CAAC;AACpG,MAAI,CAAC,YAAa,QAAO;AACzB,MAAI,uBAAuB,gBAAgB,qBAAqB;AAC9D,UAAM,IAAI;AAAA,MACR,WAAW,KAAK,UAAU,YAAY,CAAC,gBAAgB,WAAW,yCAAyC,mBAAmB;AAAA,IAChI;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,aAAa,QAAQ,SAAS,SAAS,MAAM;AAChE;AAEA,eAAsB,iBAAiB,aAAqB,KAAqC;AAC/F,wBAAsB,GAAG;AACzB,QAAM,WAAW,MAAM,cAAc,EAAE,aAAa,QAAQ,KAAK,IAAI,CAAC;AACtE,SAAO,UAAU,UAAU;AAC7B;;;ADlXA,eAAe,WAAW,YAAsC;AAC9D,SAAO,YAAAC,SAAW,KAAK,UAAU,EAAE,KAAK,MAAM,MAAM,MAAM,KAAK;AACjE;AAEA,eAAe,qBAAqB,aAAqB,cAAwC;AAC/F,QAAM,SAAS,MAAM,UAAU,aAAa,CAAC,YAAY,QAAQ,eAAe,IAAI,CAAC;AACrF,QAAM,SAAS,8BAA8B,YAAY;AACzD,QAAM,gBAAgB,OACnB,MAAM,IAAI,EACV,OAAO,CAAC,UAAU,MAAM,WAAW,WAAW,CAAC,EAC/C,IAAI,CAAC,UAAU,MAAM,MAAM,YAAY,MAAM,CAAC;AAEjD,aAAW,kBAAkB,eAAe;AAC1C,QAAI,8BAA8B,cAAc,MAAM,OAAQ,QAAO;AAAA,EACvE;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAkB,UAA2B;AACrE,QAAMC,aAAgB,gBAAc,eAAQ,QAAQ,GAAQ,eAAQ,QAAQ,CAAC;AAC7E,SAAOA,eAAa,MAAO,CAACA,WAAS,WAAW,KAAU,UAAG,EAAE,KAAKA,eAAa,QAAQ,CAAM,kBAAWA,UAAQ;AACpH;AAEA,eAAe,sCACb,aACA,cACkB;AAClB,MAAI,MAAM,WAAW,YAAY,EAAG,QAAO;AAE3C,QAAM,YAAY,MAAM,OAAO,aAAa,CAAC,aAAa,0BAA0B,kBAAkB,CAAC;AACvG,QAAM,oBAAyB,YAAK,WAAW,WAAW;AAC1D,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,YAAAD,SAAW,QAAQ,mBAAmB,EAAE,eAAe,KAAK,CAAC;AAAA,EAC/E,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO;AAC/D,UAAM;AAAA,EACR;AAEA,QAAM,SAAS,8BAA8B,YAAY;AACzD,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,YAAY,EAAG;AAC1B,UAAM,mBAAwB,YAAK,mBAAmB,MAAM,IAAI;AAChE,QAAI,CAAC,iBAAiB,kBAAkB,iBAAiB,EAAG;AAE5D,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,YAAAA,SAAW,SAAc,YAAK,kBAAkB,QAAQ,GAAG,MAAM,GAAG,KAAK;AAAA,IAC/F,QAAQ;AACN;AAAA,IACF;AAEA,UAAM,qBAA0B,kBAAW,UAAU,IACjD,aACK,eAAQ,kBAAkB,UAAU;AAC7C,QAAI,8BAAmC,eAAQ,kBAAkB,CAAC,MAAM,OAAQ;AAChF,UAAM,YAAAA,SAAW,GAAG,kBAAkB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACtE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,eAAe,aAAqB,cAAqC;AACtF,QAAM,SAAkB,CAAC;AACzB,MAAI;AACF,UAAM,OAAO,aAAa,CAAC,YAAY,UAAU,WAAW,MAAM,YAAY,CAAC;AAAA,EACjF,SAAS,OAAO;AACd,WAAO,KAAK,QAAQ,KAAK,CAAC;AAAA,EAC5B;AAEA,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,qBAAqB,aAAa,YAAY;AAAA,EACnE,SAAS,OAAO;AACd,WAAO,KAAK,QAAQ,KAAK,CAAC;AAC1B,UAAM,IAAI,eAAe,QAAQ,iEAAsE,eAAQ,YAAY,CAAC,EAAE;AAAA,EAChI;AAEA,MAAI,YAAY;AACd,QAAI;AACF,YAAM,OAAO,aAAa,CAAC,YAAY,UAAU,MAAM,YAAY,CAAC;AAAA,IACtE,QAAQ;AAAA,IAER;AACA,QAAI;AACF,YAAM,OAAO,aAAa,CAAC,YAAY,UAAU,WAAW,WAAW,MAAM,YAAY,CAAC;AAAA,IAC5F,SAAS,OAAO;AACd,aAAO,KAAK,QAAQ,KAAK,CAAC;AAAA,IAC5B;AAEA,QAAI;AACF,mBAAa,MAAM,qBAAqB,aAAa,YAAY;AAAA,IACnE,SAAS,OAAO;AACd,aAAO,KAAK,QAAQ,KAAK,CAAC;AAC1B,YAAM,IAAI,eAAe,QAAQ,iEAAsE,eAAQ,YAAY,CAAC,EAAE;AAAA,IAChI;AAAA,EACF;AAEA,MAAI,cAAc,CAAE,MAAM,WAAW,YAAY,GAAI;AACnD,QAAI;AACF,YAAM,sCAAsC,aAAa,YAAY;AACrE,mBAAa,MAAM,qBAAqB,aAAa,YAAY;AAAA,IACnE,SAAS,OAAO;AACd,aAAO,KAAK,QAAQ,KAAK,CAAC;AAAA,IAC5B;AAAA,EACF;AAEA,MAAI,YAAY;AACd,WAAO,KAAK,IAAI,MAAM,0CAA0C,YAAY,EAAE,CAAC;AAC/E,UAAM,IAAI,eAAe,QAAQ,sDAA2D,eAAQ,YAAY,CAAC,EAAE;AAAA,EACrH;AAEA,MAAI;AACF,UAAM,YAAAA,SAAW,GAAQ,eAAQ,YAAY,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAClF,SAAS,OAAO;AACd,WAAO,KAAK,QAAQ,KAAK,CAAC;AAC1B,UAAM,IAAI,eAAe,QAAQ,4DAAiE,eAAQ,YAAY,CAAC,EAAE;AAAA,EAC3H;AACF;AAEA,eAAe,yBACb,aACA,cACA,eACe;AACf,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,qBAAqB,aAAa,YAAY;AAAA,EACnE,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,CAAC,QAAQ,KAAK,CAAC;AAAA,MACf,+DAA+D,aAAa;AAAA,IAC9E;AAAA,EACF;AAEA,MAAI,YAAY;AACd,UAAM,eAAe,aAAa,YAAY;AAC9C;AAAA,EACF;AAEA,QAAM,YAAAA,SAAW,GAAG,eAAe,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACrE;AAEA,eAAsB,uBACpB,SACA,UACwD;AACxD,wBAAsB,QAAQ,QAAQ,aAAa;AACnD,MAAI,QAAQ,QAAQ,QAAW;AAC7B,0BAAsB,QAAQ,KAAK,SAAS;AAAA,EAC9C;AACA,MAAI,QAAQ,mBAAmB,UAAa,CAAC,gBAAgB,QAAQ,cAAc,GAAG;AACpF,UAAM,IAAI,MAAM,mCAAmC,KAAK,UAAU,QAAQ,cAAc,CAAC,EAAE;AAAA,EAC7F;AACA,MAAI,QAAQ,OAAO,WAAc,CAAC,OAAO,UAAU,QAAQ,EAAE,KAAK,QAAQ,MAAM,IAAI;AAClF,UAAM,IAAI,MAAM,mDAAmD,QAAQ,EAAE,EAAE;AAAA,EACjF;AAEA,QAAM,WAAW,MAAM,cAAc,OAAO;AAC5C,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR,WAAW,KAAK,UAAU,QAAQ,OAAO,QAAQ,MAAM,CAAC;AAAA,IAE1D;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM,YAAAA,SAAW,QAAa,YAAQ,WAAO,GAAG,wBAAwB,CAAC;AAC/F,QAAM,eAAoB,YAAK,eAAe,UAAU;AACxD,QAAM,YAAiB,YAAK,eAAe,OAAO;AAClD,QAAM,YAAAA,SAAW,MAAM,SAAS;AAChC,QAAM,OAAkC;AAAA,IACtC,QAAQ,QAAQ;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,IACjB,SAAS,SAAS;AAAA,EACpB;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,UAAM,OAAO,QAAQ,aAAa;AAAA,MAChC;AAAA,MACA,kBAAkB,SAAS;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAED,UAAM,mBAAmB,MAAM,iBAAiB,cAAc,MAAM;AACpE,QAAI,qBAAqB,SAAS,QAAQ;AACxC,YAAM,IAAI;AAAA,QACR,8BAA8B,oBAAoB,iBAAiB,cAAc,SAAS,MAAM;AAAA,MAClG;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,SAAS,cAAc,IAAI;AAC/C,aAAS,EAAE,OAAO,KAAK;AAAA,EACzB,SAAS,OAAO;AACd,qBAAiB;AAAA,EACnB;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,yBAAyB,QAAQ,aAAa,cAAc,aAAa;AAAA,EACjF,SAAS,OAAO;AACd,mBAAe;AAAA,EACjB;AAEA,MAAI,mBAAmB,UAAa,iBAAiB,QAAW;AAC9D,UAAM,IAAI;AAAA,MACR,CAAC,QAAQ,cAAc,GAAG,QAAQ,YAAY,CAAC;AAAA,MAC/C,GAAGE,iBAAgB,cAAc,CAAC,yBAAyBA,iBAAgB,YAAY,CAAC;AAAA,IAC1F;AAAA,EACF;AACA,MAAI,mBAAmB,OAAW,OAAM;AACxC,MAAI,iBAAiB,OAAW,OAAM;AACtC,SAAO;AACT;;;AEzQA,IAAAC,wBAAyB;AACzB,IAAAC,cAA6B;AAC7B,IAAAC,SAAsB;AACtB,IAAAC,eAA0B;AAS1B,IAAMC,qBAAgB,wBAAU,8BAAQ;AACxC,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,SAASC,iBAAgB,OAAwB;AAC/C,MAAI,iBAAiB,MAAO,QAAO,MAAM;AACzC,SAAO,OAAO,KAAK;AACrB;AAiDO,SAAS,iCACd,wBACA,IACA,wBACQ;AACR,MAAI,CAAC,0BAA0B,CAAC,wBAAwB;AACtD,UAAM,IAAI,MAAM,6EAA6E;AAAA,EAC/F;AACA,MAAI,CAAC,OAAO,UAAU,EAAE,KAAK,MAAM,GAAG;AACpC,UAAM,IAAI,MAAM,mDAAmD,EAAE,EAAE;AAAA,EACzE;AACA,SAAO,gBAAgB,mBAAmB,sBAAsB,CAAC,IAAI,EAAE,IAAI,mBAAmB,sBAAsB,CAAC;AACvH;AAEA,eAAsB,gBACpB,MAC6B;AAC7B,QAAM,EAAE,IAAI,QAAQ,aAAa,aAAa,OAAO,IAAI;AAEzD,MAAI,OAAO,QAAW;AACpB,WAAO,qBAAqB,IAAI,WAAW;AAAA,EAC7C;AAEA,SAAO,yBAAyB,QAAQ,aAAa,UAAU;AACjE;AAEA,eAAe,qBACb,IACA,aAC6B;AAC7B,MAAI,CAAC,OAAO,UAAU,EAAE,KAAK,MAAM,GAAG;AACpC,UAAM,IAAI,MAAM,mDAAmD,EAAE,EAAE;AAAA,EACzE;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMD;AAAA,MACvB;AAAA,MACA,CAAC,MAAM,QAAQ,OAAO,EAAE,GAAG,UAAU,iBAAiB;AAAA,MACtD,EAAE,KAAK,aAAa,SAAS,KAAO,UAAU,OAAO;AAAA,IACvD;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,UAAM,iBAAiB,uBAAuB,KAAK,KAAK,EAAE;AAC1D,UAAME,0BAAyB,0BAA0B,MAAM,eAAe,IAAI;AAClF,QAAI,KAAK,WAAW,IAAI;AACtB,YAAM,IAAI,MAAM,mBAAmB,OAAO,KAAK,MAAM,CAAC,cAAc,EAAE,iBAAiB;AAAA,IACzF;AACA,QAAI,CAAC,KAAK,YAAa,OAAM,IAAI,MAAM,gCAAgC;AACvE,QAAI,CAAC,KAAK,YAAa,OAAM,IAAI,MAAM,gCAAgC;AACvE,UAAM,aAAa,KAAK;AACxB,QAAI,CAAC,cAAc,CAAC,gBAAgB,UAAU,GAAG;AAC/C,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,QAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,SAAS,OAAO,KAAK,SAAS,QAAQ,GAAG;AAC1F,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,0BAAsB,KAAK,aAAa,gBAAgB;AACxD,0BAAsB,KAAK,aAAa,gBAAgB;AACxD,UAAM,UAAU,WAAW,YAAY;AACvC,WAAO;AAAA,MACL,OAAO,eAAe,KAAK,MAAM,IAAI,CAAC,SAAS,KAAK,IAAK,GAAG,WAAW;AAAA,MACvE,YAAY,KAAK;AAAA,MACjB,QAAQ;AAAA,MACR,iBAAiB;AAAA,QACf,eAAe;AAAA,QACf;AAAA,QACAA;AAAA,MACF;AAAA,MACA,aAAa,KAAK;AAAA,MAClB;AAAA,MACA,gBAAgB,eAAe;AAAA,MAC/B,wBAAwB,eAAe;AAAA,MACvC,wBAAAA;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,cAAU;AAAA,EACZ;AAEA,QAAM,YAAY,MAAM,4BAA4B,aAAa,EAAE;AACnE,MAAI,CAAC,WAAW,YAAY;AAC1B,UAAM,YAAY,YAAY,SAC1B,iDACAD,iBAAgB,OAAO;AAC3B,UAAM,IAAI;AAAA,MACR,oDAAoD,EAAE,KAAK,SAAS,gDACpB,EAAE,0CAA0C,EAAE;AAAA,IAChG;AAAA,EACF;AAEA,QAAM,0BAA0B,2BAA2B,WAAW;AACtE,QAAM,yBAAyB,GAAG,uBAAuB,cAAc,EAAE;AACzE,SAAO;AAAA,IACL,OAAO,MAAM,aAAa,aAAa,UAAU,YAAY,UAAU,UAAU;AAAA,IACjF,YAAY,UAAU;AAAA,IACtB,QAAQ;AAAA,IACR,iBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,aAAa,MAAM,EAAE;AAAA,IACrB,SAAS,UAAU;AAAA,IACnB,wBAAwB;AAAA,IACxB;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,OAA2B,YAAyC;AAClG,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,+BAA+B;AAC3D,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,KAAK;AAAA,EACrB,QAAQ;AACN,UAAM,IAAI,MAAM,kCAAkC,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EAC3E;AAEA,QAAM,QAAQ,IAAI,SAAS,MAAM,sCAAsC;AACvE,MAAI,CAAC,SAAS,OAAO,MAAM,CAAC,CAAC,MAAM,YAAY;AAC7C,UAAM,IAAI,MAAM,mDAAmD,UAAU,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EAC3G;AAEA,QAAM,QAAQ,MAAM,CAAC,EAAE,YAAY;AACnC,QAAM,aAAa,MAAM,CAAC,EAAE,QAAQ,WAAW,EAAE,EAAE,YAAY;AAC/D,QAAM,OAAO,IAAI,SAAS,YAAY;AACtC,MAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY;AAClC,UAAM,IAAI,MAAM,6CAA6C,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EACtF;AACA,SAAO;AAAA,IACL,KAAK,GAAG,IAAI,QAAQ,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,EAAE,QAAQ,WAAW,EAAE,CAAC;AAAA,IAChF,UAAU,GAAG,IAAI,IAAI,KAAK,IAAI,UAAU;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,0BAA0B,MAAwB,MAAsB;AAC/E,QAAM,gBAAgB,KAAK,gBAAgB;AAC3C,MAAI,eAAe;AACjB,UAAM,QAAQ,cAAc,MAAM,oBAAoB;AACtD,QAAI,MAAO,QAAO,GAAG,IAAI,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,EAAE,QAAQ,WAAW,EAAE,EAAE,YAAY,CAAC;AAAA,EACtG;AAEA,QAAM,QAAQ,KAAK,qBAAqB,SACnC,KAAK,qBAAqB,QAC1B,KAAK,gBAAgB,OAAO,SAC5B,KAAK,gBAAgB,OAAO;AACjC,QAAM,aAAa,KAAK,gBAAgB;AACxC,MAAI,CAAC,SAAS,CAAC,cAAc,MAAM,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,GAAG;AAC5E,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,SAAO,GAAG,IAAI,IAAI,MAAM,YAAY,CAAC,IAAI,WAAW,QAAQ,WAAW,EAAE,EAAE,YAAY,CAAC;AAC1F;AAEA,SAAS,2BAA2B,aAA6B;AAC/D,MAAI,gBAAqB,eAAQ,WAAW;AAC5C,MAAI;AACF,oBAAgB,yBAAa,OAAO,aAAa;AAAA,EACnD,QAAQ;AAAA,EAER;AACA,SAAO,SAAS,aAAa;AAC/B;AAEA,eAAe,yBACb,QACA,aACA,YAC6B;AAC7B,QAAM,eAAe,UAAW,MAAME,kBAAiB,WAAW;AAClE,wBAAsB,YAAY,aAAa;AAC/C,wBAAsB,cAAc,aAAa;AAEjD,QAAM,eAAe,MAAM,iBAAiB,aAAa,UAAU;AACnE,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,UAAU,CAAC,eAAe;AAAA,EAC5F;AACA,QAAM,eAAe,MAAM,iBAAiB,aAAa,YAAY;AACrE,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,4BAA4B,KAAK,UAAU,YAAY,CAAC,eAAe;AAAA,EACzF;AACA,QAAM,YAAY,MAAM,aAAa,aAAa,cAAc,YAAY;AAE5E,SAAO;AAAA,IACL,OAAO,MAAM,aAAa,aAAa,WAAW,YAAY;AAAA,IAC9D;AAAA,IACA,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAEA,eAAe,aACb,aACA,SACA,SACmB;AACnB,MAAI,CAAC,gBAAgB,OAAO,KAAK,CAAC,gBAAgB,OAAO,GAAG;AAC1D,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,QAAM,EAAE,OAAO,IAAI,MAAMH;AAAA,IACvB;AAAA,IACA,CAAC,QAAQ,eAAe,MAAM,GAAG,OAAO,MAAM,OAAO,IAAI,IAAI;AAAA,IAC7D,EAAE,KAAK,aAAa,SAAS,KAAO,UAAU,OAAO;AAAA,EACvD;AACA,SAAO,eAAe,OAAO,MAAM,IAAI,GAAG,WAAW;AACvD;AAEA,eAAeG,kBAAiB,aAAsC;AACpE,QAAM,EAAE,OAAO,IAAI,MAAMH;AAAA,IACvB;AAAA,IACA,CAAC,UAAU,gBAAgB;AAAA,IAC3B,EAAE,KAAK,aAAa,SAAS,KAAO,UAAU,OAAO;AAAA,EACvD;AACA,SAAO,OAAO,KAAK,KAAK;AAC1B;AAEA,eAAe,aACb,aACA,YACA,YACiB;AACjB,QAAM,EAAE,OAAO,IAAI,MAAMA;AAAA,IACvB;AAAA,IACA,CAAC,cAAc,MAAM,YAAY,UAAU;AAAA,IAC3C,EAAE,KAAK,aAAa,SAAS,KAAO,UAAU,OAAO;AAAA,EACvD;AACA,QAAM,SAAS,OAAO,KAAK,EAAE,YAAY;AACzC,MAAI,CAAC,gBAAgB,MAAM,GAAG;AAC5B,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AACA,SAAO;AACT;AAEA,SAAS,eAAe,UAAoB,aAA+B;AACzE,QAAM,OAAY,eAAQ,WAAW;AACrC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAmB,CAAC;AAE1B,aAAW,OAAO,UAAU;AAC1B,QAAI,IAAI,WAAW,EAAG;AAEtB,UAAM,WAAgB,eAAQ,MAAM,GAAG;AACvC,UAAMI,aAAgB,gBAAS,MAAM,QAAQ;AAC7C,QAAS,kBAAW,GAAG,KAAKA,eAAa,QAAQA,WAAS,WAAW,KAAU,UAAG,EAAE,KAAU,kBAAWA,UAAQ,GAAG;AAClH,YAAM,IAAI,MAAM,0CAA0C,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,IACjF;AAEA,UAAM,UAAUA,WAAS,WAAW,IAAS,UAAG,EAAE,IAC9CA,WAAS,MAAM,CAAC,IAChBA;AACJ,QAAI,CAAC,KAAK,IAAI,OAAO,GAAG;AACtB,WAAK,IAAI,OAAO;AAChB,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;;;AC/UA,IAAAC,wBAAyB;AACzB,IAAAC,SAAsB;AACtB,IAAAC,eAA0B;AAE1B,IAAMC,qBAAgB,wBAAU,8BAAQ;AAmBjC,SAAS,uBAAuB,QAA8C;AACnF,QAAM,UAAU,oBAAI,IAAkC;AACtD,MAAI;AAEJ,aAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,QAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,YAAM,MAAM,KAAK,MAAM,GAAG,EAAE;AAC5B,gBAAU,QAAQ,IAAI,GAAG,KAAK;AAAA,QAC5B;AAAA,QACA,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,aAAa;AAAA,QACb,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AACA,cAAQ,IAAI,KAAK,OAAO;AACxB;AAAA,IACF;AAEA,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,cAAQ,SAAS,KAAK,MAAM,UAAU,MAAM;AAAA,IAC9C,WAAW,KAAK,WAAW,cAAc,GAAG;AAC1C,cAAQ,cAAc,KAAK,MAAM,eAAe,MAAM,EAAE,QAAQ,UAAU,EAAE;AAAA,IAC9E,WAAW,KAAK,WAAW,cAAc,GAAG;AAC1C,cAAQ,cAAc,OAAO,SAAS,KAAK,MAAM,eAAe,MAAM,GAAG,EAAE;AAAA,IAC7E,WAAW,KAAK,WAAW,UAAU,GAAG;AACtC,cAAQ,UAAU,KAAK,MAAM,WAAW,MAAM;AAAA,IAChD,WAAW,KAAK,WAAW,GAAI,GAAG;AAChC,cAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,QAAQ,OAAO,CAAC,EAC/B,OAAO,CAAC,WAAW,OAAO,QAAQ,CAAC,EACnC,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AACzE;AAEA,eAAsB,iBACpB,aACA,UACA,WACA,SACuC;AACvC,QAAM,eAAoB,gBAAS,aAAa,QAAQ;AACxD,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA;AAAA,MACvB;AAAA,MACA,CAAC,SAAS,oBAAoB,MAAM,GAAG,SAAS,IAAI,OAAO,IAAI,MAAM,YAAY;AAAA,MACjF,EAAE,KAAK,aAAa,SAAS,IAAM;AAAA,IACrC;AACA,WAAO,uBAAuB,MAAM;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC5EO,SAAS,oBACd,YACA,2BACA,OACmB;AACnB,MAAI,SAAS,KAAK,0BAA0B,SAAS,KAAK,WAAW,UAAU,GAAG;AAChF,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,WAAW,IAAI,CAAC,cAAc,0BAA0B,IAAI,UAAU,EAAE,IACnF,EAAE,GAAG,WAAW,OAAO,UAAU,SAAS,IAAI,OAAO,IACrD,SAAS;AAEb,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,UAAM,YAAY,OAAO,KAAK;AAC9B,UAAM,WAAW,OAAO,QAAQ,CAAC;AACjC,QACE,aAAa,YACb,0BAA0B,IAAI,UAAU,EAAE,KAC1C,CAAC,0BAA0B,IAAI,SAAS,EAAE,KAC1C,UAAU,QAAQ,SAAS,OAC3B;AACA,aAAO,QAAQ,CAAC,IAAI;AACpB,aAAO,KAAK,IAAI;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAgBA,IAAM,0BAA0B;AAChC,IAAM,yBAAyB,oBAAI,QAAuF;AAEnH,SAAS,uBAAuB,OAAkD;AACvF,QAAM,SAAS,mBAAmB,KAAK;AACvC,MAAI,OAAO,YAAY,UAAU,OAAO,YAAY,OAAQ,QAAO;AACnE,MAAI,OAAO,kBAAmB,QAAO;AACrC,SAAO;AACT;AAEO,SAAS,oBACd,iBACA,gBACA,eACA,OACmB;AACnB,QAAM,iBAAiB,IAAI;AAC3B,QAAM,cAAc,oBAAI,IAAwD;AAEhF,aAAW,KAAK,iBAAiB;AAC/B,gBAAY,IAAI,EAAE,IAAI;AAAA,MACpB,OAAO,EAAE,QAAQ;AAAA,MACjB,UAAU,EAAE;AAAA,IACd,CAAC;AAAA,EACH;AAEA,aAAW,KAAK,gBAAgB;AAC9B,UAAM,WAAW,YAAY,IAAI,EAAE,EAAE;AACrC,QAAI,UAAU;AACZ,eAAS,SAAS,EAAE,QAAQ;AAAA,IAC9B,OAAO;AACL,kBAAY,IAAI,EAAE,IAAI;AAAA,QACpB,OAAO,EAAE,QAAQ;AAAA,QACjB,UAAU,EAAE;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,KAAK,YAAY,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO;AAAA,IACrE;AAAA,IACA,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,EACjB,EAAE;AAEF,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AACpE,SAAO,QAAQ,MAAM,GAAG,KAAK;AAC/B;AAEO,SAAS,eACd,iBACA,gBACA,MACA,OACmB;AACnB,QAAM,iBAAiB,KAAK,OAAO;AACnC,QAAM,mBAAmB,oBAAI,IAAoB;AACjD,QAAM,kBAAkB,oBAAI,IAAoB;AAChD,QAAM,eAAe,oBAAI,IAA2B;AAEpD,kBAAgB,QAAQ,CAAC,QAAQ,UAAU;AACzC,qBAAiB,IAAI,OAAO,IAAI,QAAQ,CAAC;AACzC,iBAAa,IAAI,OAAO,IAAI,OAAO,QAAQ;AAAA,EAC7C,CAAC;AAED,iBAAe,QAAQ,CAAC,QAAQ,UAAU;AACxC,oBAAgB,IAAI,OAAO,IAAI,QAAQ,CAAC;AACxC,QAAI,CAAC,aAAa,IAAI,OAAO,EAAE,GAAG;AAChC,mBAAa,IAAI,OAAO,IAAI,OAAO,QAAQ;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,QAAM,SAAS,oBAAI,IAAY,CAAC,GAAG,iBAAiB,KAAK,GAAG,GAAG,gBAAgB,KAAK,CAAC,CAAC;AACtF,QAAM,QAA2B,CAAC;AAElC,aAAW,MAAM,QAAQ;AACvB,UAAM,eAAe,iBAAiB,IAAI,EAAE;AAC5C,UAAM,cAAc,gBAAgB,IAAI,EAAE;AAE1C,UAAM,gBAAgB,eAAe,KAAK,OAAO,gBAAgB;AACjE,UAAM,eAAe,cAAc,KAAK,OAAO,eAAe;AAE9D,UAAM,WAAW,aAAa,IAAI,EAAE;AACpC,QAAI,CAAC,SAAU;AAEf,UAAM,KAAK;AAAA,MACT;AAAA,MACA,OAAO,iBAAiB,KAAK,gBAAgB,gBAAgB,iBAAiB;AAAA,MAC9E;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AAClE,SAAO,MAAM,MAAM,GAAG,KAAK;AAC7B;AAEO,SAAS,cACd,OACA,YACA,YACA,SACmB;AACnB,SAAO,0BAA0B,OAAO,YAAY,YAAY,OAAO;AACzE;AAEA,SAAS,gCACP,SACA,cACA,SACK;AACL,MAAI,CAAC,WAAW,QAAQ,UAAU,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,oBAAI,IAAiB;AACpC,QAAM,aAAuB,CAAC;AAE9B,aAAW,SAAS,SAAS;AAC3B,UAAM,YAAY,aAAa,KAAK;AACpC,UAAM,WAAW,UAAU,SAAS;AACpC,QAAI,CAAC,OAAO,IAAI,QAAQ,GAAG;AACzB,aAAO,IAAI,UAAU,CAAC,CAAC;AACvB,iBAAW,KAAK,QAAQ;AAAA,IAC1B;AACA,WAAO,IAAI,QAAQ,GAAG,KAAK,KAAK;AAAA,EAClC;AAEA,QAAM,oBAAoB,WAAW,IAAI,CAAC,aAAa;AACrD,UAAM,QAAQ,OAAO,IAAI,QAAQ,KAAK,CAAC;AACvC,WAAO,uBAAuB,OAAO,YAAY;AAAA,EACnD,CAAC;AAED,QAAM,SAAc,CAAC;AACrB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,SAAO,OAAO;AACZ,YAAQ;AACR,eAAW,SAAS,mBAAmB;AACrC,YAAM,QAAQ,MAAM,KAAK;AACzB,UAAI,UAAU,QAAW;AACvB,eAAO,KAAK,KAAK;AACjB,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,aAAS;AAAA,EACX;AAEA,SAAO;AACT;AAEO,SAAS,0BAA0B,YAA+B,SAAqC;AAC5G,SAAO,gCAAgC,YAAY,CAAC,cAAc,WAAW,OAAO;AACtF;AAEA,SAAS,uBACP,SACA,cACK;AACL,MAAI,QAAQ,UAAU,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAe,CAAC;AACtB,QAAM,YAAiB,CAAC;AAExB,aAAW,SAAS,SAAS;AAC3B,UAAM,MAAM,kBAAkB,aAAa,KAAK,EAAE,QAAQ;AAC1D,QAAI,CAAC,SAAS,IAAI,GAAG,GAAG;AACtB,eAAS,IAAI,GAAG;AAChB,cAAQ,KAAK,KAAK;AAAA,IACpB,OAAO;AACL,gBAAU,KAAK,KAAK;AAAA,IACtB;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,SAAS,GAAG,SAAS;AAClC;AAEA,SAAS,kBAAkB,UAAiC;AAC1D,QAAM,iBAAiB,SAAS,SAAS,YAAY;AACrD,QAAM,kBAAkB,SAAS,QAAQ,IAAI,KAAK,EAAE,YAAY;AAChE,MAAI,eAAe,SAAS,GAAG;AAC7B,WAAO,GAAG,cAAc,IAAI,cAAc;AAAA,EAC5C;AACA,SAAO;AACT;AAEO,SAAS,kBACd,OACA,iBACA,gBACA,SACmB;AACnB,QAAM,wBAAwB,QAAQ,yBAAyB,uBAAuB,KAAK,MAAM;AACjG,QAAM,WAAW,GAAG,KAAK,IAAS,QAAQ,cAAc,IAAI,QAAQ,IAAI,IAAI,QAAQ,YAAY,IAAI,QAAQ,UAAU,IAAI,QAAQ,KAAK,IAAI,wBAAwB,IAAI,CAAC;AAExK,MAAI,YAAY,uBAAuB,IAAI,eAAe;AAC1D,MAAI,CAAC,WAAW;AACd,gBAAY,oBAAI,QAA2D;AAC3E,2BAAuB,IAAI,iBAAiB,SAAS;AAAA,EACvD;AAEA,MAAI,SAAS,UAAU,IAAI,cAAc;AACzC,MAAI,CAAC,QAAQ;AACX,aAAS,oBAAI,IAA+B;AAC5C,cAAU,IAAI,gBAAgB,MAAM;AAAA,EACtC,OAAO;AACL,UAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAKA,QAAM,kBAAkB,wBAAwB,KAAK;AACrD,QAAM,iBAAiB,KAAK,IAAI,QAAQ,QAAQ,iBAAiB,QAAQ,KAAK;AAC9E,QAAM,QAAQ,QAAQ,mBAAmB,QACrC,eAAe,iBAAiB,gBAAgB,QAAQ,MAAM,cAAc,IAC5E,oBAAoB,iBAAiB,gBAAgB,QAAQ,cAAc,cAAc;AAE7F,QAAM,kBAAkB,KAAK,IAAI,gBAAgB,QAAQ,aAAa,GAAG,QAAQ,QAAQ,CAAC;AAC1F,QAAM,aAAa,MAAM,MAAM,GAAG,eAAe;AACjD,QAAM,SAAS,cAAc,OAAO,YAAY,QAAQ,YAAY;AAAA,IAClE;AAAA,EACF,CAAC;AAED,MAAI,OAAO,QAAQ,yBAAyB;AAC1C,UAAM,SAAS,OAAO,KAAK,EAAE,KAAK,EAAE;AACpC,QAAI,WAAW,QAAW;AACxB,aAAO,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AACA,SAAO,IAAI,UAAU,MAAM;AAE3B,SAAO;AACT;AAEO,SAAS,wBACd,OACA,iBACA,SACmB;AACnB,QAAM,iBAAiB,KAAK,IAAI,QAAQ,QAAQ,GAAG,QAAQ,KAAK;AAChE,QAAM,UAAU,gBAAgB,MAAM,GAAG,cAAc;AACvD,SAAO,cAAc,OAAO,SAAS,QAAQ,YAAY;AAAA,IACvD,uBAAuB,QAAQ,yBAAyB;AAAA,EAC1D,CAAC;AACH;;;ACxSA,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AAEzB,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAEtB,IAAM,uBAAuB;AAC7B,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,gBAAgB,OAAuB;AAC9C,SAAO,MAAM,QAAQ,YAAY,EAAE;AACrC;AAEA,SAAS,mBAAmB,OAAwB;AAClD,MAAI,CAAC,eAAe,KAAK,KAAK,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,IAAI,MAAM,YAAY,CAAC,GAAG;AACvC,WAAO;AAAA,EACT;AAEA,SAAO,cAAc,KAAK,KAAK,KAAK,eAAe,KAAK,KAAK,KAAK,cAAc,KAAK,KAAK;AAC5F;AAEA,SAAS,yBAAyB,OAAyB;AACzD,QAAM,cAAc,oBAAI,IAAY;AAEpC,aAAW,SAAS,MAAM,SAAS,kBAAkB,GAAG;AACtD,UAAM,YAAY,gBAAgB,MAAM,CAAC,EAAG,KAAK,CAAC;AAClD,QAAI,aAAa,mBAAmB,SAAS,GAAG;AAC9C,kBAAY,IAAI,SAAS;AAAA,IAC3B;AAAA,EACF;AAEA,aAAW,SAAS,MAAM,SAAS,gBAAgB,GAAG;AACpD,UAAM,YAAY,gBAAgB,MAAM,CAAC,EAAG,KAAK,CAAC;AAClD,QAAI,aAAa,mBAAmB,SAAS,GAAG;AAC9C,kBAAY,IAAI,SAAS;AAAA,IAC3B;AAAA,EACF;AAEA,aAAW,SAAS,MAAM,SAAS,gBAAgB,GAAG;AACpD,UAAM,YAAY,gBAAgB,MAAM,CAAC,EAAG,KAAK,CAAC;AAClD,QAAI,aAAa,mBAAmB,SAAS,GAAG;AAC9C,kBAAY,IAAI,SAAS;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,WAAW;AACxB;AAEA,SAAS,uBAAuB,OAAyB;AACvD,QAAM,WAAW,MACd,QAAQ,oBAAoB,GAAG,EAC/B,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,kBAAkB,GAAG;AAEhC,QAAM,cAAc,oBAAI,IAAY;AACpC,aAAW,SAAS,SAAS,SAAS,aAAa,GAAG;AACpD,UAAM,YAAY,gBAAgB,MAAM,CAAC,CAAC;AAC1C,QAAI,mBAAmB,SAAS,GAAG;AACjC,kBAAY,IAAI,SAAS;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,WAAW;AACxB;AAEA,SAAS,wBAAwB,OAAe,QAAyB;AACvE,QAAM,SAAS,MACZ,QAAQ,YAAY,GAAG,EACvB,MAAM,iBAAiB,EACvB,IAAI,CAAC,UAAU,MAAM,KAAK,EAAE,YAAY,CAAC,EACzC,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC,EAClC,OAAO,CAAC,UAAU,CAAC,WAAW,IAAI,KAAK,CAAC;AAE3C,SAAO,OAAO,WAAW,KAAK,OAAO,CAAC,MAAM,OAAO,YAAY;AACjE;AAEO,SAAS,0BAA0B,OAAmC;AAC3E,MAAI,mBAAmB,KAAK,EAAE,wBAAwB;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,yBAAyB,KAAK;AAC7C,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,OAAO,CAAC;AAAA,EACjB;AACA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,uBAAuB,KAAK;AAC/C,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,WAAW,CAAC;AAC9B,MAAI,qBAAqB,KAAK,KAAK,GAAG;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,wBAAwB,OAAO,SAAS,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AC5IO,IAAM,gCAAgC,oBAAI,IAAI;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;AClCD,IAAM,4BAA4B;AAElC,IAAM,yBAAyB,oBAAI,IAAyB;AAC5D,IAAM,wBAAwB,oBAAI,IAAyB;AAC3D,IAAM,wBAAwB,oBAAI,IAAyB;AAE3D,IAAMC,aAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EACtE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAQ;AAAA,EAClE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAY;AAAA,EACzD;AAAA,EAAY;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU;AAAA,EAAY;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAC1E;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAChC,CAAC;AAED,SAAS,gBACP,OACA,KACA,OACM;AACN,MAAI,MAAM,QAAQ,2BAA2B;AAC3C,UAAM,SAAS,MAAM,KAAK,EAAE,KAAK,EAAE;AACnC,QAAI,WAAW,QAAW;AACxB,YAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF;AACA,QAAM,IAAI,KAAK,KAAK;AACtB;AAEO,SAAS,uBAAuB,MAA2B;AAChE,MAAI,CAAC,MAAM;AACT,WAAO,oBAAI,IAAY;AAAA,EACzB;AAEA,QAAM,UAAU,qBAAqB,IAAI;AACzC,QAAM,QAAQ,uBAAuB,IAAI,OAAO,KAAK,sBAAsB,IAAI,OAAO;AACtF,MAAI,OAAO;AACT,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,IAAI;AAAA,IACjB,QACG,QAAQ,uBAAuB,GAAG,EAClC,MAAM,KAAK,EACX,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK,CAACA,WAAU,IAAI,KAAK,CAAC;AAAA,EAChE;AAEA,kBAAgB,wBAAwB,SAAS,MAAM;AACvD,kBAAgB,uBAAuB,SAAS,MAAM;AACtD,SAAO;AACT;AAEO,SAAS,gBAAgB,UAA+B;AAC7D,QAAM,UAAU,qBAAqB,QAAQ;AAC7C,QAAM,QAAQ,sBAAsB,IAAI,OAAO;AAC/C,MAAI,OAAO;AACT,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,QAChB,QAAQ,uBAAuB,GAAG,EAClC,MAAM,SAAS,EACf,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,IAAI,IAAI,UAAU;AACjC,kBAAgB,uBAAuB,SAAS,MAAM;AACtD,SAAO;AACT;AAEO,SAAS,gBAAgB,UAA2B;AACzD,SAAO,WAAW,QAAQ,KAAK,cAAc,QAAQ,KAAK,oBAA0B,QAAQ;AAC9F;AAEO,SAASC,4BAA2B,UAA2B;AACpE,SAAO,2BAA2B,QAAQ;AAC5C;AAEO,SAASC,qBAAoB,UAA2B;AAC7D,SAAO,oBAA0B,QAAQ;AAC3C;AAEO,SAAS,2BACd,WACA,QACoB;AACpB,QAAM,cAAc,gBAAgB,UAAU,SAAS,QAAQ;AAC/D,QAAM,kBAAkBA,qBAAoB,UAAU,SAAS,QAAQ;AACvE,QAAM,SAAS,WAAW,UAAU,SAAS,QAAQ,KAAK,cAAc,UAAU,SAAS,QAAQ;AACnG,QAAM,WAAW,aAAa,UAAU,SAAS,QAAQ;AACzD,QAAM,mBAAmBD,4BAA2B,UAAU,SAAS,QAAQ,KAC7E,0BAA0B,UAAU,SAAS,SAAS;AAExD,MAAI,OAAO,mBAAmB;AAC5B,QAAI,iBAAkB,QAAO;AAC7B,QAAI,SAAU,QAAO;AACrB,QAAI,gBAAiB,QAAO;AAC5B,QAAI,UAAU,YAAa,QAAO;AAClC,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,QAAQ;AAC7B,QAAI,gBAAiB,QAAO;AAC5B,QAAI,SAAU,QAAO;AACrB,QAAI,iBAAkB,QAAO;AAC7B,QAAI,UAAU,YAAa,QAAO;AAClC,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,QAAQ;AAC7B,QAAI,UAAU,YAAa,QAAO;AAClC,QAAI,gBAAiB,QAAO;AAC5B,QAAI,SAAU,QAAO;AACrB,QAAI,iBAAkB,QAAO;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,UAAU;AAC/B,QAAI,SAAU,QAAO;AACrB,QAAI,iBAAkB,QAAO;AAC7B,QAAI,gBAAiB,QAAO;AAC5B,QAAI,UAAU,YAAa,QAAO;AAClC,WAAO;AAAA,EACT;AAEA,MAAI,iBAAkB,QAAO;AAC7B,MAAI,SAAU,QAAO;AACrB,MAAI,gBAAiB,QAAO;AAC5B,MAAI,UAAU,YAAa,QAAO;AAClC,SAAO;AACT;AAEO,SAAS,0BAA0B,WAA4B;AACpE,SAAO,8BAA8B,IAAI,SAAS,KAAK;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,SAAS;AACtB;AAEO,SAAS,uBAAuB,OAAyB;AAC9D,SAAO,6BAA6B,KAAK;AAC3C;AAEO,SAAS,qBAAqB,OAAyB;AAC5D,QAAM,QAAQ,MAAM,MAAM,yBAAyB,KAAK,CAAC;AACzD,SAAO,MACJ,IAAI,CAAC,SAAS,KAAK,YAAY,CAAC,EAChC,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,EACjC,OAAO,CAAC,SAAS,CAACD,WAAU,IAAI,IAAI,CAAC;AAC1C;AAEO,SAAS,4BAA4B,YAA8B;AACxE,QAAM,QAAQ,qBAAqB,UAAU;AAC7C,QAAM,UAAU,MAAM,QAAQ,mBAAmB,EAAE;AACnD,QAAM,QAAQ,WACX,UAAU,MAAM,EAChB,QAAQ,+BAA+B,OAAO,EAC9C,YAAY;AACf,QAAM,QAAQ,MAAM,QAAQ,MAAM,GAAG;AACrC,QAAM,WAAW,CAAC,OAAO,SAAS,OAAO,KAAK,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAClF,SAAO,MAAM,KAAK,IAAI,IAAI,QAAQ,CAAC;AACrC;AAEA,SAAS,qBAAqB,MAA0B,UAAkB,OAAyB;AACjG,QAAM,aAAa,QAAQ,IAAI,YAAY;AAC3C,QAAM,YAAY,SAAS,YAAY;AAEvC,MAAI,OAAO;AACX,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,4BAA4B,IAAI;AACjD,eAAW,WAAW,UAAU;AAC9B,UAAI,cAAc,SAAS;AACzB,eAAO,KAAK,IAAI,MAAM,CAAC;AAAA,MACzB,WAAW,UAAU,SAAS,OAAO,GAAG;AACtC,eAAO,KAAK,IAAI,MAAM,GAAG;AAAA,MAC3B,WAAW,UAAU,SAAS,OAAO,GAAG;AACtC,eAAO,KAAK,IAAI,MAAM,GAAG;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,kCAAkC,OAA8B;AAC9E,QAAM,cAAc,uBAAuB,KAAK;AAChD,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO,YAAY,CAAC,KAAK;AAAA,EAC3B;AAEA,QAAM,YAAY,qBAAqB,KAAK;AAC5C,QAAM,OAAO,UAAU,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC;AACtD,SAAO,QAAQ;AACjB;AAEA,SAAS,6BAA6B,UAA4B;AAChE,QAAM,iBAAiB,qBAAqB,QAAQ,EAAE,QAAQ,OAAO,GAAG;AACxE,QAAM,WAAW,eAAe,MAAM,GAAG,EAAE,OAAO,CAAC,YAAY,QAAQ,SAAS,CAAC;AACjF,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,CAAC;AAAA,EACV;AAEA,QAAMG,YAAW,SAAS,SAAS,SAAS,CAAC,KAAK;AAClD,QAAM,qBAAqBA,UAAS,QAAQ,cAAc,EAAE;AAC5D,QAAM,qBAAqB,SAAS,IAAI,CAAC,YAAY,QAAQ,YAAY,CAAC;AAE1E,SAAO,MAAM,KAAK,oBAAI,IAAI;AAAA,IACxB,GAAG;AAAA,IACH,mBAAmB,YAAY;AAAA,EACjC,CAAC,CAAC;AACJ;AAEA,SAAS,kBAAkB,UAAkB,yBAA4C;AACvF,QAAM,WAAW,6BAA6B,QAAQ;AACtD,SAAO,wBAAwB,KAAK,CAAC,YAAY;AAC/C,QAAI,CAAC,WAAW,QAAQ,SAAS,GAAG;AAClC,aAAO;AAAA,IACT;AACA,WAAO,SAAS,SAAS,OAAO;AAAA,EAClC,CAAC;AACH;AAEA,IAAM,4BAA4B;AAAA,EAChC;AAAA,EAAM;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAC/C;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAS;AAAA,EAAM;AAAA,EACtD;AAAA,EAAK;AAAA,EAAK;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAS;AAAA,EACpD;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAC9C;AAEA,IAAM,8BAA8B,IAAI;AAAA,EACtC,iFACA,0BAA0B,KAAK,GAAG,IAClC;AAAA,EACA;AACF;AAEA,SAAS,8BAA8B,UAA0B;AAC/D,SAAO,SAAS,QAAQ,OAAO,GAAG,EAAE,YAAY,EAAE,QAAQ,SAAS,EAAE;AACvE;AAEO,SAAS,gBAAgB,UAAkB,MAAuB;AACvE,QAAM,iBAAiB,8BAA8B,QAAQ;AAC7D,QAAM,iBAAiB,8BAA8B,IAAI;AAEzD,SAAO,eAAe,SAAS,cAAc,KAC3C,eAAe,SAAS,IAAI,cAAc,EAAE,KAC5C,eAAe,SAAS,cAAc;AAC1C;AAEO,SAAS,oBAAoB,OAA8B;AAChE,QAAM,QAAQ,MAAM,MAAM,2BAA2B;AACrD,QAAM,UAAU,QAAQ,CAAC;AACzB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,QAAQ,SAAS,EAAE;AACpC;AAEO,SAAS,kBAAkB,OAAuB;AACvD,QAAM,WAAW,MAAM,QAAQ,6BAA6B,EAAE,EAAE,KAAK;AACrE,SAAO,SAAS,SAAS,IAAI,WAAW;AAC1C;AAEO,SAAS,iCACd,OACA,YACA,OACA,wBAAiC,uBAAuB,KAAK,MAAM,UAChD;AACnB,MAAI,CAAC,uBAAuB;AAC1B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,kCAAkC,KAAK;AACvD,MAAI,CAAC,SAAS;AACZ,WAAO,CAAC;AAAA,EACV;AACA,QAAM,eAAe,oBAAoB,KAAK;AAC9C,QAAM,kBAAkB,4BAA4B,OAAO;AAE3D,QAAM,QAAQ,CAAC,SAAS,GAAG,uBAAuB,KAAK,GAAG,GAAG,qBAAqB,KAAK,CAAC,EACrF,IAAI,CAAC,UAAU,MAAM,YAAY,CAAC,EAClC,OAAO,CAAC,OAAO,KAAK,QAAQ,MAAM,UAAU,KAAK,IAAI,QAAQ,KAAK,MAAM,GAAG,EAC3E,MAAM,GAAG,CAAC;AAEb,QAAM,gBAAgB,WACnB;AAAA,IAAO,CAAC,cACPF,4BAA2B,UAAU,SAAS,QAAQ,KACtD,0BAA0B,UAAU,SAAS,SAAS;AAAA,EACxD,EACC,IAAI,CAAC,cAAc;AAClB,UAAM,aAAa,UAAU,SAAS,QAAQ,IAAI,YAAY;AAC9D,UAAM,YAAY,UAAU,SAAS,SAAS,YAAY;AAE1D,UAAM,0BAA0B,gBAAgB,OAAO,CAAC,UAAU,MAAM,UAAU,CAAC;AACnF,UAAM,aAAa,wBAAwB;AAAA,MAAK,CAAC,YAC/C,cAAc,WACd,UAAU,QAAQ,cAAc,EAAE,MAAM,QAAQ,QAAQ,cAAc,EAAE;AAAA,IAC1E;AACA,QAAI,WAAW;AACf,UAAM,qBAAqB;AAC3B,UAAM,eAAe,aAAa,kBAAkB,UAAU,SAAS,UAAU,uBAAuB,IAAI;AAC5G,UAAM,sBAAsB,eAAe,gBAAgB,UAAU,SAAS,UAAU,YAAY,IAAI;AAExG,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,4BAA4B,IAAI;AACjD,iBAAW,WAAW,UAAU;AAC9B,YAAI,cAAc,SAAS;AACzB,qBAAW,KAAK,IAAI,UAAU,CAAC;AAAA,QACjC,WAAW,UAAU,SAAS,OAAO,GAAG;AACtC,qBAAW,KAAK,IAAI,UAAU,IAAI;AAAA,QACpC,WAAW,UAAU,SAAS,OAAO,GAAG;AACtC,qBAAW,KAAK,IAAI,UAAU,GAAG;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,uBAAuB,oBAAoB;AAC7C,iBAAW,KAAK,IAAI,UAAU,CAAC;AAAA,IACjC;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EACA,OAAO,CAAC,UAAU,MAAM,YAAY,GAAG,EACvC,KAAK,CAAC,GAAG,MAAM;AACd,UAAM,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,IAAI;AACtE,UAAM,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,IAAI;AACtE,QAAI,cAAc,UAAW,QAAO,YAAY;AAEhD,QAAI,EAAE,uBAAuB,EAAE,oBAAoB;AACjD,aAAO,EAAE,qBAAqB,IAAI;AAAA,IACpC;AACA,QAAI,EAAE,iBAAiB,EAAE,aAAc,QAAO,EAAE,eAAe,IAAI;AACnE,QAAI,EAAE,aAAa,EAAE,SAAU,QAAO,EAAE,WAAW,EAAE;AACrD,QAAI,EAAE,UAAU,UAAU,EAAE,UAAU,MAAO,QAAO,EAAE,UAAU,QAAQ,EAAE,UAAU;AACpF,WAAO,EAAE,UAAU,GAAG,cAAc,EAAE,UAAU,EAAE;AAAA,EACpD,CAAC,EACA,MAAM,GAAG,KAAK,IAAI,QAAQ,GAAG,EAAE,CAAC;AAEnC,SAAO,cAAc,IAAI,CAAC,WAAW;AAAA,IACnC,IAAI,MAAM,UAAU;AAAA,IACpB,OAAO,MAAM,uBAAuB,MAAM,qBACtC,QACA,KAAK,IAAI,GAAG,MAAM,MAAM,WAAW,IAAI;AAAA,IAC3C,UAAU,MAAM,UAAU;AAAA,EAC5B,EAAE;AACJ;AAGO,SAAS,8BACd,OACA,YACA,OACA,wBAAiC,uBAAuB,KAAK,MAAM,UAChD;AACnB,MAAI,CAAC,uBAAuB;AAC1B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,cAAc,kCAAkC,KAAK;AAC3D,MAAI,CAAC,aAAa;AAChB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAQ,CAAC,aAAa,GAAG,uBAAuB,KAAK,GAAG,GAAG,qBAAqB,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC;AACxG,QAAM,SAAS,WACZ;AAAA,IAAO,CAAC,cACPA,4BAA2B,UAAU,SAAS,QAAQ,KACtD,0BAA0B,UAAU,SAAS,SAAS;AAAA,EACxD,EACC,IAAI,CAAC,cAAc;AAClB,UAAM,aAAa,qBAAqB,UAAU,SAAS,MAAM,UAAU,SAAS,UAAU,KAAK;AACnG,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EACA,OAAO,CAAC,UAAU,MAAM,aAAa,CAAC,EACtC,KAAK,CAAC,GAAG,MAAM;AACd,QAAI,EAAE,eAAe,EAAE,WAAY,QAAO,EAAE,aAAa,EAAE;AAC3D,QAAI,EAAE,UAAU,UAAU,EAAE,UAAU,MAAO,QAAO,EAAE,UAAU,QAAQ,EAAE,UAAU;AACpF,WAAO,EAAE,UAAU,GAAG,cAAc,EAAE,UAAU,EAAE;AAAA,EACpD,CAAC,EACA,MAAM,GAAG,KAAK,IAAI,QAAQ,GAAG,EAAE,CAAC;AAEnC,SAAO,OAAO,IAAI,CAAC,WAAW;AAAA,IAC5B,IAAI,MAAM,UAAU;AAAA,IACpB,OAAO,KAAK,IAAI,GAAG,MAAM,MAAM,aAAa,IAAI;AAAA,IAChD,UAAU,MAAM,UAAU;AAAA,EAC5B,EAAE;AACJ;;;ACnYO,SAAS,8BAA8B,OAAsC;AAClF,QAAM,cAAc,MAAM,CAAC,GAAG,QAAQ;AACtC,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,WAAW;AAAA;AAAA,kBAAuB,MAAM,MAAM;AAC1D;AAEO,SAAS,sBAAsB,UAAmB,gBAA8C;AACrG,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ;AAUd,MAAI,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,gBAAgB,YAAY,CAAC,MAAM,YAAY,OAAO,MAAM,aAAa,UAAU;AAClI,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,IACnC,MAAM,MACL,IAAI,CAAC,UAAU;AACd,QAAI,CAAC,SAAS,OAAO,MAAM,SAAS,UAAU;AAC5C,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,YAAY,OAAO,MAAM,eAAe,YAAY,OAAO,SAAS,MAAM,UAAU,IAChF,MAAM,aACN,eAAe,MAAM,IAAI;AAAA,IAC/B;AAAA,EACF,CAAC,EACA,OAAO,CAAC,UAAkD,UAAU,IAAI,IACzE,CAAC;AAEL,MAAI,MAAM,WAAW,KAAK,OAAO,MAAM,SAAS,UAAU;AACxD,QAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,SAAS,KAAK,MAAM,YAAY,OAAO,MAAM,aAAa,UAAU;AACzH,YAAM,WAAW,MAAM;AACvB,YAAM,eAAe;AAAA,QACnB,SAAS,MAAM;AAAA,QACf,WAAW,OAAO,SAAS,cAAc,WAAW,SAAS,YAAY;AAAA,QACzE,SAAS,OAAO,SAAS,YAAY,WAAW,SAAS,UAAU;AAAA,QACnE,WAAW,OAAO,SAAS,cAAc,WAAW,SAAS,YAAY;AAAA,QACzE,MAAM,OAAO,SAAS,SAAS,WAAW,SAAS,OAAO;AAAA,QAC1D,UAAU,OAAO,SAAS,aAAa,WAAW,SAAS,WAAW;AAAA,MACxE;AACA,YAAM,WAAW,OAAO,SAAS,aAAa,WAAW,SAAS,WAAW;AAC7E,YAAM;AAAA,QACJ,GAAG,qBAAqB,cAAc,UAAU,cAAc,EAAE,IAAI,CAAC,UAAU;AAAA,UAC7E;AAAA,UACA,YAAY,eAAe,IAAI;AAAA,QACjC,EAAE;AAAA,MACJ;AAAA,IACF,OAAO;AACL,YAAM,KAAK;AAAA,QACT,MAAM,MAAM;AAAA,QACZ,YAAY,eAAe,MAAM,IAAI;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV;AAAA,IACA,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,8BAA8B,KAAK;AAAA,IAC5G,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AAAA,IAC7D,aAAa,MAAM;AAAA,IACnB,UAAU,MAAM;AAAA,EAClB;AACF;AAEO,SAAS,wBAAwB,UAAkC;AACxE,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ;AACd,MAAI,CAAC,MAAM,YAAY,OAAO,MAAM,aAAa,UAAU;AACzD,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAM;AACvB,SAAO,OAAO,SAAS,aAAa,WAAW,SAAS,WAAW;AACrE;AAEO,SAAS,qBAAqB,OAA8B,gBAA6C;AAC9G,QAAM,SAAS,MAAM,OAClB,IAAI,CAAC,UAAU,sBAAsB,OAAO,cAAc,CAAC,EAC3D,OAAO,CAAC,UAAiC,UAAU,IAAI;AAE1D,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,MAAM;AAAA,IACb,cAAc,MAAM;AAAA,IACpB,aAAa,MAAM;AAAA,EACrB;AACF;AAEO,SAAS,+BAA+B,QAAmD;AAChG,SAAO,OAAO;AAAA,IAAQ,CAAC,UACrB,MAAM,MAAM,IAAI,CAAC,UAAU,eAAe;AAAA,MACxC;AAAA,MACA;AAAA,MACA,MAAM,SAAS;AAAA,MACf,YAAY,SAAS;AAAA,IACvB,EAAE;AAAA,EACJ;AACF;AAEO,SAAS,qCACd,QACA,UAA+D,CAAC,GACnC;AAC7B,SAAO,qBAAqB,+BAA+B,MAAM,GAAG,OAAO;AAC7E;AAEO,SAAS,mCAAmC,UAAqD;AACtG,QAAM,eAAe,oBAAI,IAA0B;AACnD,aAAW,WAAW,UAAU;AAC9B,iBAAa,IAAI,QAAQ,MAAM,IAAI,QAAQ,KAAK;AAAA,EAClD;AACA,SAAO,MAAM,KAAK,aAAa,OAAO,CAAC;AACzC;AAsBO,SAAS,qBAAqB,SAAqB,SAA6B;AACrF,QAAM,cAAc,QAAQ,CAAC;AAC7B,MAAI,CAAC,aAAa;AAChB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,IAAI,MAAc,YAAY,MAAM,EAAE,KAAK,CAAC;AAC3D,MAAI,cAAc;AAElB,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;AACnD,UAAM,SAAS,QAAQ,KAAK;AAC5B,UAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,KAAK,KAAK,CAAC;AAC9C,mBAAe;AAEf,aAAS,YAAY,GAAG,YAAY,OAAO,QAAQ,aAAa;AAC9D,aAAO,SAAS,KAAK,OAAO,SAAS,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,gBAAgB,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,IAAI,CAAC,UAAU,QAAQ,WAAW;AAClD;AAEO,SAAS,qBACd,OACA,mBACS;AACT,MAAI,MAAM,WAAW,mBAAmB;AACtC,WAAO;AAAA,EACT;AAEA,WAAS,QAAQ,GAAG,QAAQ,mBAAmB,SAAS;AACtD,QAAI,MAAM,KAAK,MAAM,QAAW;AAC9B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;ACpPA,IAAAG,MAAoB;AACpB,yBAAwC;AACxC,IAAAC,SAAsB;AACtB,iCAA8B;AAE9B,IAAM,+BAA+B;AACrC,IAAM,gCAAgC;AA2B/B,UAAU,uBACf,UACA,UAAkC,CAAC,GACe;AAClD,MAAI,CAAI,eAAW,QAAQ,GAAG;AAC5B;AAAA,EACF;AAEA,QAAM,aAAa,4BAA4B,QAAQ;AACvD,MAAI,eAAe,UAAU;AAC3B,WAAO,6BAA6B,UAAU,OAAO;AACrD;AAAA,EACF;AAEA,SAAO,4BAA4B,UAAU,OAAO;AACtD;AAEO,SAAS,wBAA0C,YAA+C;AACvG,QAAM,gBAAgB,oBAAoB,UAAU;AACpD,MAAI,YAAY;AAEhB,EAAG,cAAe,eAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,EAAG,cAAa,aAAS,eAAe,GAAG,CAAC;AAE5C,QAAM,QAAQ,CAAC,WAAiD;AAC9D,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAEA,UAAM,QAAQ,OAAO,OAAO,IAAI,CAAC,UAAU;AACzC,YAAM,aAAwC;AAAA,QAC5C,SAAS;AAAA,QACT,QAAQ,CAAC,KAAK;AAAA,QACd,OAAO,OAAO;AAAA,QACd,cAAc,OAAO;AAAA,QACrB,aAAa,OAAO;AAAA,MACtB;AACA,aAAO,KAAK,UAAU,UAAU;AAAA,IAClC,CAAC;AAED,QAAI,MAAM,WAAW,GAAG;AACtB;AAAA,IACF;AAEA,IAAG,cAAe,eAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,IAAG,mBAAe,eAAe,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA,GAAM,OAAO;AAAA,EACnE;AAEA,QAAM,SAAS,MAAY;AACzB,QAAI,WAAW;AACb;AAAA,IACF;AAEA,IAAG,cAAe,eAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,IAAG,eAAW,eAAe,UAAU;AACvC,gBAAY;AAAA,EACd;AAEA,QAAM,UAAU,MAAY;AAC1B,QAAI,WAAW;AACb;AAAA,IACF;AACA,IAAG,WAAO,eAAe,EAAE,OAAO,KAAK,CAAC;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,wBACd,YACA,SACM;AACN,QAAM,SAAS,wBAAgC,UAAU;AACzD,MAAI;AACF,eAAW,UAAU,SAAS;AAC5B,aAAO,MAAM,MAAM;AAAA,IACrB;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,WAAO,QAAQ;AACf,UAAM;AAAA,EACR;AACF;AAEA,UAAU,6BACR,UACA,SACkD;AAClD,QAAM,UAAa,iBAAa,UAAU,OAAO;AACjD,QAAM,UAAU,6BAA6B,OAAO,EAAE,KAAK;AAC3D,MAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,OAAO;AAAA,EAC7B,SAAS,OAAO;AACd,wBAAoB,UAAU,GAAG,SAAS,OAAO,OAAO;AACxD;AAAA,EACF;AAEA,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,wBAAoB,UAAU,GAAG,SAAS,IAAI,MAAM,2DAA2D,GAAG,OAAO;AACzH;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ;AAC1B,UAAM,aAAa,2BAAmC,KAAK;AAC3D,QAAI,YAAY;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,UAAU,4BACR,UACA,SACkD;AAClD,QAAM,SAAY,aAAS,UAAU,GAAG;AACxC,QAAM,UAAU,IAAI,yCAAc,MAAM;AACxC,QAAM,aAAa,OAAO,YAAY,KAAK,IAAI;AAC/C,MAAI,SAAS;AACb,MAAI,aAAa;AAEjB,MAAI;AACF,QAAI,YAAY;AAChB,OAAG;AACD,kBAAe,aAAS,QAAQ,YAAY,GAAG,WAAW,QAAQ,IAAI;AACtE,gBAAU,QAAQ,MAAM,WAAW,SAAS,GAAG,SAAS,CAAC;AAEzD,UAAI,eAAe,OAAO,QAAQ,IAAI;AACtC,aAAO,gBAAgB,GAAG;AACxB,cAAM,UAAU,OAAO,MAAM,GAAG,YAAY;AAC5C,iBAAS,OAAO,MAAM,eAAe,CAAC;AACtC,sBAAc;AAEd,cAAM,aAAa,qBAA6B,SAAS,UAAU,YAAY,OAAO;AACtF,YAAI,YAAY;AACd,gBAAM;AAAA,QACR;AAEA,uBAAe,OAAO,QAAQ,IAAI;AAAA,MACpC;AAAA,IACF,SAAS,YAAY;AAErB,cAAU,QAAQ,IAAI;AAEtB,UAAM,YAAY,OAAO,QAAQ;AACjC,QAAI,UAAU,SAAS,GAAG;AACxB,oBAAc;AACd,YAAM,aAAa,qBAA6B,WAAW,UAAU,YAAY,OAAO;AACxF,UAAI,YAAY;AACd,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,UAAE;AACA,IAAG,cAAU,MAAM;AAAA,EACrB;AACF;AAEA,SAAS,qBACP,SACA,UACA,YACA,SACkC;AAClC,QAAM,OAAO,QAAQ,QAAQ;AAC7B,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,UAAM,aAAa,2BAAmC,MAAM;AAC5D,QAAI,CAAC,YAAY;AACf,0BAAoB,UAAU,YAAY,MAAM,IAAI,MAAM,+BAA+B,GAAG,OAAO;AACnG,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,wBAAoB,UAAU,YAAY,MAAM,OAAO,OAAO;AAC9D,WAAO;AAAA,EACT;AACF;AAEA,SAAS,2BAA6C,WAAsD;AAC1G,MAAI,CAAC,aAAa,OAAO,cAAc,YAAY,MAAM,QAAQ,SAAS,GAAG;AAC3E,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ;AAQd,QAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,SAAS;AAC5D,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,SAAS,OAAO,MAAM,YAAY,YAAY,OAAO,SAAS,MAAM,OAAO,IAAI,MAAM,UAAU;AAAA,IAC/F;AAAA,IACA,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAAA,IACvD,cAAc,OAAO,MAAM,iBAAiB,YAAY,OAAO,SAAS,MAAM,YAAY,IAAI,MAAM,eAAe;AAAA,IACnH,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,EAClG;AACF;AAIA,SAAS,4BAA4B,UAAyC;AAC5E,QAAM,SAAY,aAAS,UAAU,GAAG;AACxC,MAAI;AACF,UAAM,SAAS,OAAO,MAAM,IAAI;AAChC,UAAM,YAAe,aAAS,QAAQ,QAAQ,GAAG,OAAO,QAAQ,CAAC;AACjE,QAAI,aAAa,GAAG;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,6BAA6B,OAAO,SAAS,GAAG,SAAS,EAAE,SAAS,OAAO,CAAC;AAC3F,WAAO,OAAO,WAAW,GAAG,IAAI,WAAW;AAAA,EAC7C,UAAE;AACA,IAAG,cAAU,MAAM;AAAA,EACrB;AACF;AAEA,SAAS,6BAA6B,OAAuB;AAC3D,MAAI,SAAS,MAAM,UAAU;AAC7B,MAAI,OAAO,WAAW,CAAC,MAAM,OAAQ;AACnC,aAAS,OAAO,MAAM,CAAC;AAAA,EACzB;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,YAA4B;AACvD,QAAM,eAAW,+BAAW,MAAM,EAC/B,OAAO,GAAG,KAAK,IAAI,CAAC,QAAI,gCAAY,CAAC,EAAE,SAAS,KAAK,CAAC,EAAE,EACxD,OAAO,KAAK;AACf,QAAM,YAAiB,eAAQ,UAAU;AACzC,QAAM,WAAgB,gBAAS,UAAU;AACzC,SAAY,YAAK,WAAW,IAAI,QAAQ,IAAI,QAAQ,MAAM;AAC5D;AAEA,SAAS,oBACP,UACA,YACA,MACA,OACA,SACM;AACN,QAAM,SAAS,QAAQ,uBAAuB;AAC9C,QAAM,kBAAkB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAEhF,MAAI,QAAQ,iBAAiB;AAC3B,YAAQ,gBAAgB,iBAAiB,MAAM,YAAY,QAAQ;AAAA,EACrE;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM;AAAA,EACR;AACF;;;AC1SO,IAAM,0BAAqD,OAAO,OAAO;AAAA,EAC9E,UAAU;AAAA,EACV,UAAU,IAAI,OAAO;AACvB,CAAC;AAEM,UAAU,0BACf,OACA,UACA,SAA0B,yBACV;AAChB,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,QAAQ,CAAC;AACxD,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,QAAQ,CAAC;AACxD,MAAI,QAAa,CAAC;AAClB,MAAI,aAAa;AAEjB,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC;AACxD,QAAI,MAAM,SAAS,MAAM,MAAM,UAAU,YAAY,aAAa,YAAY,WAAW;AACvF,YAAM;AACN,cAAQ,CAAC;AACT,mBAAa;AAAA,IACf;AAEA,UAAM,KAAK,IAAI;AACf,kBAAc;AAAA,EAChB;AAEA,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM;AAAA,EACR;AACF;;;ApC8EO,IAAM,uBAAuB,oBAAI,IAAI,CAAC,cAAc,OAAO,cAAc,OAAO,UAAU,MAAM,QAAQ,SAAS,OAAO,QAAQ,OAAO,YAAY,UAAU,QAAQ,KAAK,OAAO,OAAO,CAAC;AAMzL,IAAM,6BAA6B,oBAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;AAEjE,SAAS,wBAAwB,WAA4B,QAA6B;AACxF,SAAO,UAAU,SAAS,aAAa,OAAO,YAC5C,UAAU,SAAS,aAAa,OAAO,WACvC,UAAU,SAAS,WAAW,OAAO;AACzC;AAEA,SAAS,iCACP,OACA,YACA,UACA,mBACa;AACb,QAAM,aAAa,0BAA0B,KAAK;AAClD,MAAI,CAAC,cAAc,WAAW,WAAW,GAAG;AAC1C,WAAO,oBAAI,IAAI;AAAA,EACjB;AAEA,QAAM,WAAW,kBAAkB,IAAI,CAAC,eAAe;AAAA,IACrD;AAAA,IACA,SAAS,SAAS,oBAAoB,SAAS;AAAA,EACjD,EAAE;AACF,QAAM,eAAe,SAAS,QAAQ,CAAC,EAAE,WAAW,QAAQ,MAAM,QAC/D,OAAO,CAAC,WAAW,OAAO,SAAS,UAAU,EAC7C,IAAI,CAAC,YAAY,EAAE,WAAW,OAAO,EAAE,CAAC;AAC3C,QAAM,UAAU,aAAa,SAAS,IAClC,eACA,SAAS,QAAQ,CAAC,EAAE,WAAW,QAAQ,MAAM,QAC5C,OAAO,CAAC,WAAW,OAAO,KAAK,YAAY,MAAM,WAAW,YAAY,CAAC,EACzE,IAAI,CAAC,YAAY,EAAE,WAAW,OAAO,EAAE,CAAC;AAE7C,QAAM,gBAAgB,IAAI,IAAI,QAAQ,IAAI,CAACC,YAAW,CAACA,QAAO,OAAO,IAAIA,OAAM,CAAC,CAAC;AACjF,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO,oBAAI,IAAI;AAAA,EACjB;AAEA,QAAM,SAAS,cAAc,OAAO,EAAE,KAAK,EAAE;AAC7C,QAAM,gBAAgB,SAAS,KAAK,CAAC,YAAY,QAAQ,cAAc,OAAO,SAAS,GAAG,WAAW,CAAC;AACtG,QAAM,mBAAmB,cAAc;AAAA,IAAO,CAAC,WAC7C,WAAW,KAAK,CAAC,cAAc,wBAAwB,WAAW,MAAM,CAAC;AAAA,EAC3E;AACA,QAAM,cAAc,SAAS;AAAA,IAC3B,OAAO;AAAA,IACP,CAAC,OAAO,OAAO,IAAI,GAAG,iBAAiB,IAAI,CAAC,WAAW,OAAO,EAAE,CAAC;AAAA,EACnE;AACA,QAAM,kBAAkB,YAAY,KAAK,CAAC,eAAe,WAAW,aAAa,OAAO,OAAO,EAAE,GAAG;AACpG,MAAI,oBAAoB,QAAW;AACjC,WAAO,oBAAI,IAAI;AAAA,EACjB;AAEA,QAAM,yBAAyB,IAAI,IAAI,YACpC,OAAO,CAAC,eAAe,WAAW,gBAAgB,eAAe,EACjE,IAAI,CAAC,eAAe,WAAW,QAAQ,CAAC;AAE3C,SAAO,IAAI,IAAI,WACZ,OAAO,CAAC,cAAc,iBAAiB;AAAA,IAAK,CAAC,WAC5C,uBAAuB,IAAI,OAAO,EAAE,KAAK,wBAAwB,WAAW,MAAM;AAAA,EACpF,CAAC,EACA,IAAI,CAAC,cAAc,UAAU,EAAE,CAAC;AACrC;AAEA,IAAM,gCAAgC;AACtC,IAAM,kCAAkC,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,+BAA+B,oBAAI,IAAI;AAAA,EAC3C;AAAA,EACA;AACF,CAAC;AACD,IAAM,mCAAmC,oBAAI,IAAI,CAAC,mBAAmB,kBAAkB,CAAC;AAExF,SAAS,8BACP,UACA,UACA,YACS;AACT,MAAI,aAAa,OAAO,aAAa,MAAO,QAAO;AACnD,MAAI,eAAe,uBAAwB,QAAO,aAAa;AAC/D,QAAM,eAAe,iCAAiC,IAAI,UAAU;AACpE,MAAI,aAAa,iBAAiB,aAAa,cAAc,aAAa,cAAc;AACtF,WAAO;AAAA,EACT;AACA,SAAO,CAAC;AACV;AAEA,IAAM,gCAAgC,oBAAI,IAAI;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,SAAS,oBACd,SACA,MACA,QACwB;AACxB,MAAI;AAEJ,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,OAAO,aAAa,OAAO,OAAO,QAAS;AACtD,QACE,WAAW,WACT,SAAS,OAAO,aAAa,SAAS,OAAO,YAC5C,SAAS,OAAO,WAAW,UAAU,OAAO,SAC/C;AACA;AAAA,IACF;AACA,QAAI,CAAC,MAAM;AACT,aAAO;AACP;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,UAAU,OAAO;AACrC,UAAM,WAAW,KAAK,UAAU,KAAK;AACrC,UAAM,0BAA0B,WAAW,UACzC,SAAS,YACT,OAAO,cAAc,KAAK,aAC1B,OAAO,YAAY,KAAK,WACxB,OAAO,YAAY,KAAK,YACxB,OAAO,UAAU,KAAK,WACrB,OAAO,WAAW,KAAK,YAAY,OAAO,SAAS,KAAK;AAC3D,UAAM,oBAAoB,SAAS,YACjC,OAAO,cAAc,KAAK,aAC1B,8BAA8B,IAAI,OAAO,IAAI,KAC7C,CAAC,8BAA8B,IAAI,KAAK,IAAI;AAC9C,QACE,OAAO,YACN,SAAS,YAAY,OAAO,YAAY,KAAK,aAC9C,2BACA,mBACA;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,qBAAqB,KAAuB;AACnD,QAAM,UAAU,IAAI,aAAa,GAAG;AACpC,SAAO,OAAO,KAAK,QAAQ,MAAM;AACnC;AAEA,SAAS,qBAAqB,KAA2B;AACvD,SAAO,IAAI,aAAa,IAAI,QAAQ,IAAI,YAAY,IAAI,aAAa,CAAC;AACxE;AAEA,SAASC,iBAAgB,OAAwB;AAC/C,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,SAAS,OAAO,UAAU,YAAY,aAAa,OAAO;AAC5D,WAAO,OAAQ,MAA+B,OAAO;AAAA,EACvD;AACA,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,iBAAiB,OAAyB;AACjD,QAAM,UAAUA,iBAAgB,KAAK;AACrC,SAAO,QAAQ,SAAS,KAAK,KAAK,QAAQ,YAAY,EAAE,SAAS,YAAY,KAAK,QAAQ,YAAY,EAAE,SAAS,mBAAmB;AACtI;AAEA,SAAS,gCAAgC,UAA0C;AACjF,QAAM,oBAAoB,SAAS,UAAU;AAC7C,QAAM,iBAAiB,KAAK,IAAI,KAAK,KAAK,MAAM,oBAAoB,IAAI,CAAC;AACzE,SAAO,KAAK,IAAI,KAAM,cAAc;AACtC;AAQA,IAAM,iCAAiC;AACvC,IAAM,kCAAkC;AAEjC,SAAS,uBACd,UACA,gBACqD;AAIrD,MAAI,SAAS,aAAa,UAAU;AAClC,WAAO,CAAC;AAAA,EACV;AACA,QAAM,OAAO,EAAE,gBAAgB,iCAAiC,eAAe,+BAA+B;AAC9G,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,OAAO,gBAAgB,mBAAmB,YAAY,OAAO,SAAS,eAAe,cAAc,IAAI,EAAE,gBAAgB,eAAe,eAAe,IAAI,CAAC;AAAA,IAChK,GAAI,OAAO,gBAAgB,kBAAkB,YAAY,OAAO,SAAS,eAAe,aAAa,IAAI,EAAE,eAAe,eAAe,cAAc,IAAI,CAAC;AAAA,EAC9J;AACF;AAEA,SAAS,wBAAwB,OAAyB;AACxD,QAAM,UAAUA,iBAAgB,KAAK,EAAE,YAAY;AACnD,SAAO,QAAQ,SAAS,kCAAkC,KACrD,QAAQ,SAAS,wBAAwB,KACzC,QAAQ,SAAS,4BAA4B,KAC7C,QAAQ,SAAS,gBAAgB;AACxC;AAgJA,IAAM,+BAA+B;AACrC,IAAM,oCAAoC;AAuD1C,SAAS,uBAAuB,QAAuF;AACrH,SAAO,GAAG,OAAO,YAAY,IAAI,OAAO,WAAW,IAAI,OAAO,KAAK;AACrE;AAEA,SAAS,kBAAkB,UAAkC;AAC3D,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,WAAO;AAAA,EACT;AACA,QAAM,KAAM,SAA8B;AAC1C,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAYA,SAAS,oBAAoB,OAAe,UAAkC;AAC5E,MAAI,cAAc,KAAK,MAAM,KAAK;AAClC,MAAI,OAAO,MAAM,WAAW,EAAG,QAAO;AACtC,MAAI,YAAY,sBAAsB,KAAK,MAAM,KAAK,CAAC,GAAG;AACxD,mBAAe,KAAK,KAAK,KAAK,MAAO;AAAA,EACvC;AACA,SAAO,KAAK,MAAM,cAAc,GAAI;AACtC;AAEA,SAAS,kBAAkB,OAA6D;AACtF,MAAI,CAAC,OAAO;AACV,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,aAAa,MAAM;AAAA,IACnB,kBAAkB,MAAM;AAAA,IACxB,kBAAkB,MAAM;AAAA,IACxB,cAAc,MAAM;AAAA,EACtB;AACF;AAEA,SAAS,mBAAmB,OAAuD;AACjF,MAAI,CAAC,OAAO,YAAY,CAAC,MAAM,eAAe,CAAC,MAAM,oBAAoB,MAAM,qBAAqB,UAAa,CAAC,MAAM,cAAc;AACpI,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX,QAAQ,MAAM;AAAA,IACd,aAAa,MAAM;AAAA,IACnB,aAAa,MAAM;AAAA,IACnB,SAAS,MAAM;AAAA,EACjB;AACF;AAEA,SAAS,kBAAkB,UAAuD;AAChF,MAAI,CAAC,SAAS,YAAY,CAAC,SAAS,eAAe,CAAC,SAAS,oBAAoB,SAAS,qBAAqB,UAAa,CAAC,SAAS,cAAc;AAClJ,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,KAAK,SAAS;AAAA,IACd,QAAQ,SAAS;AAAA,IACjB,aAAa,SAAS;AAAA,IACtB,aAAa,SAAS;AAAA,IACtB,SAAS,SAAS;AAAA,EACpB;AACF;AAEA,SAAS,iBAAiB,UAAkC;AAC1D,SAAO,kBAAkB,QAAQ,MAAM;AACzC;AAgCA,IAAM,yBAAyB;AAC/B,IAAM,+BAA+B;AACrC,IAAM,8BAA8B;AACpC,IAAM,6BAA6B;AACnC,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;AAC7B,IAAM,2BAA2B;AAEjC,SAASC,kBAAiB,UAAkB,UAA2B;AACrE,QAAM,qBAA0B,eAAQ,QAAQ;AAChD,QAAM,iBAAsB,eAAQ,QAAQ;AAC5C,SAAO,uBAAuB,kBAAkB,mBAAmB,WAAW,GAAG,cAAc,GAAQ,UAAG,EAAE;AAC9G;AAEA,SAAS,yBACP,OACA,UACA,oBACA,mBACA,UACA,gBACA,wBAAiC,uBAAuB,KAAK,MAAM,UAChD;AACnB,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,uBAAuB;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,uBAAuB,KAAK;AACpD,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,IAAI,IAAI,SAAS,IAAI,CAAC,cAAc,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;AACnF,QAAM,iBAAiB,oBAAI,IAA6B;AACxD,aAAW,aAAa,oBAAoB;AAC1C,mBAAe,IAAI,UAAU,IAAI,SAAS;AAAA,EAC5C;AACA,aAAW,aAAa,mBAAmB;AACzC,QAAI,CAAC,eAAe,IAAI,UAAU,EAAE,GAAG;AACrC,qBAAe,IAAI,UAAU,IAAI,SAAS;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,UAAU;AACZ,eAAW,cAAc,iBAAiB;AACxC,YAAM,UAAU,SAAS,iBAAiB,UAAU;AACpD,iBAAW,UAAU,SAAS;AAC5B,cAAM,SAAS,SAAS,gBAAgB,OAAO,QAAQ;AACvD,mBAAW,SAAS,QAAQ;AAC1B,cAAI,kBAAkB,CAAC,eAAe,IAAI,MAAM,OAAO,GAAG;AACxD;AAAA,UACF;AAEA,gBAAM,YAAc,MAAM,YAAY;AACtC,cAAI,CAAC,0BAA0B,SAAS,GAAG;AACzC;AAAA,UACF;AAEA,cAAI,CAACC,4BAA2B,MAAM,QAAQ,GAAG;AAC/C;AAAA,UACF;AAEA,cAAI,MAAM,YAAY,OAAO,aAAa,MAAM,UAAU,OAAO,SAAS;AACxE;AAAA,UACF;AAEA,gBAAM,WAAW,aAAa,IAAI,MAAM,OAAO,KAAK,eAAe,IAAI,MAAM,OAAO;AACpF,gBAAM,WAA0B,UAAU,YAAY;AAAA,YACpD,UAAU,MAAM;AAAA,YAChB,WAAW,MAAM;AAAA,YACjB,SAAS,MAAM;AAAA,YACf;AAAA,YACA,MAAM,MAAM,QAAQ;AAAA,YACpB,UAAU,MAAM;AAAA,YAChB,MAAM,MAAM;AAAA,YACZ,GAAG,kBAAkB,mBAAmB,KAAK,CAAC;AAAA,UAChD;AAEA,gBAAM,gBAAgB,UAAU,SAAS;AACzC,yBAAe,IAAI,MAAM,SAAS;AAAA,YAChC,IAAI,MAAM;AAAA,YACV,OAAO,KAAK,IAAI,GAAG,gBAAgB,GAAG;AAAA,YACtC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAA8B,CAAC;AACrC,aAAW,aAAa,eAAe,OAAO,GAAG;AAC/C,UAAM,gBAAgB,UAAU,SAAS,SAAS,YAAY;AAC9D,UAAM,aAAa,UAAU,SAAS,QAAQ,IAAI,YAAY;AAC9D,UAAM,uBAAuB,gBAAgB,KAAK,CAAC,SAAS,cAAc,IAAI;AAC9E,UAAM,qBAAqB,wBAAwB,gBAAgB;AAAA,MAAK,CAAC,SACvE,UAAU,SAAS,IAAI,KACvB,cAAc,SAAS,IAAI;AAAA,IAC7B;AAEA,QAAI,CAAC,oBAAoB;AACvB;AAAA,IACF;AAEA,QAAI,CAAC,0BAA0B,UAAU,SAAS,SAAS,GAAG;AAC5D;AAAA,IACF;AAEA,QAAI,CAACA,4BAA2B,UAAU,SAAS,QAAQ,GAAG;AAC5D;AAAA,IACF;AAEA,UAAM,WAAW,aAAa,IAAI,UAAU,EAAE,KAAK;AACnD,UAAM,cAAc,uBAAuB,OAAO;AAClD,UAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,OAAO,UAAU,KAAK,IAAI,WAAW;AACxF,aAAS,KAAK;AAAA,MACZ,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,UAAU,SAAS;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,WAAS,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AAErE,QAAM,cAAc,IAAI,IAAI,SAAS,IAAI,CAAC,cAAc,UAAU,EAAE,CAAC;AACrE,QAAM,YAAY,SAAS,OAAO,CAAC,cAAc,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;AAC/E,SAAO,CAAC,GAAG,UAAU,GAAG,SAAS;AACnC;AAEO,SAAS,0BACd,OACA,UACA,gBACA,iBACA,OACA,oBACA,wBAAiC,uBAAuB,KAAK,MAAM,UACnE,sBAA+B,OACZ;AACnB,MAAI,CAAC,uBAAuB;AAC1B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,kBAAkB,uBAAuB,KAAK;AACpD,QAAM,gBAAgB,qBAAqB,KAAK;AAChD,MAAI,gBAAgB,WAAW,KAAK,cAAc,WAAW,GAAG;AAC9D,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,mBAAmB,oBAAI,IAA6B;AAC1D,QAAM,eAAe,oBAAoB,KAAK;AAC9C,QAAM,cAAc,kCAAkC,KAAK;AAE3D,QAAM,uBAAuB,CAC3B,OACA,YACA,sBACA,cACY;AACZ,QAAI,kBAAkB,CAAC,eAAe,IAAI,MAAM,OAAO,GAAG;AACxD,aAAO;AAAA,IACT;AAEA,UAAM,YAAa,MAAM,YAAY;AACrC,QAAI,CAAC,0BAA0B,SAAS,GAAG;AACzC,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,uBAAuB,CAACA,4BAA2B,MAAM,QAAQ,GAAG;AACvE,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,MAAM,QAAQ,IAAI,YAAY;AACjD,UAAM,YACJ,cAAc,cACd,UAAU,QAAQ,MAAM,EAAE,MAAM;AAClC,UAAM,OAAO,cAAc,YAAY,OAAO;AAE9C,UAAM,WAAW,iBAAiB,IAAI,MAAM,OAAO;AACnD,QAAI,CAAC,YAAY,OAAO,SAAS,OAAO;AACtC,uBAAiB,IAAI,MAAM,SAAS;AAAA,QAClC,IAAI,MAAM;AAAA,QACV,OAAO;AAAA,QACP,UAAU;AAAA,UACR,UAAU,MAAM;AAAA,UAChB,WAAW,MAAM;AAAA,UACjB,SAAS,MAAM;AAAA,UACf;AAAA,UACA,MAAM,MAAM,QAAQ;AAAA,UACpB,UAAU,MAAM;AAAA,UAChB,MAAM,MAAM;AAAA,UACZ,GAAG,kBAAkB,mBAAmB,KAAK,CAAC;AAAA,QAChD;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,gBACrB,QAAQ,CAAC,SAAS;AAAA,IACjB;AAAA,IACA,KAAK,QAAQ,MAAM,EAAE;AAAA,IACrB,KAAK,QAAQ,MAAM,GAAG;AAAA,EACxB,CAAC,EACA,OAAO,CAAC,MAAM,KAAK,QAAQ,KAAK,UAAU,KAAK,IAAI,QAAQ,IAAI,MAAM,GAAG,EACxE,MAAM,GAAG,CAAC;AAEb,aAAW,cAAc,iBAAiB;AACxC,UAAM,UAAU;AAAA,MACd,GAAG,SAAS,iBAAiB,UAAU;AAAA,MACvC,GAAG,SAAS,mBAAmB,UAAU;AAAA,IAC3C;AAEA,UAAM,eAAe;AAAA,MACnB,GAAG,SAAS,gBAAgB,UAAU;AAAA,MACtC,GAAG,SAAS,kBAAkB,UAAU;AAAA,IAC1C;AAEA,UAAM,uBAAuB,WAAW,QAAQ,MAAM,EAAE;AAExD,UAAM,eAAe,oBAAI,IAAoC;AAC7D,eAAW,UAAU,SAAS;AAC5B,mBAAa,IAAI,OAAO,IAAI,MAAM;AAAA,IACpC;AAEA,eAAW,UAAU,aAAa,OAAO,GAAG;AAC1C,UAAI,mBAAmB,CAAC,gBAAgB,IAAI,OAAO,EAAE,GAAG;AACtD;AAAA,MACF;AACA,UAAI,gBAAgB,CAAC,gBAAgB,OAAO,UAAU,YAAY,GAAG;AACnE;AAAA,MACF;AAEA,YAAM,SAAS,SAAS,gBAAgB,OAAO,QAAQ;AACvD,UAAI,qBAAqB;AACzB,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,YAAY,OAAO,aAAa,MAAM,UAAU,OAAO,SAAS;AACxE;AAAA,QACF;AAEA,cAAM,aAAa,MAAM,QAAQ,IAAI,YAAY;AACjD,cAAMC,cAAa,OAAO,KAAK,YAAY;AAC3C,YAAI,cAAcA,eAAc,UAAU,QAAQ,MAAM,EAAE,MAAMA,YAAW,QAAQ,MAAM,EAAE,GAAG;AAC5F;AAAA,QACF;AAEA,6BAAqB,qBAAqB,OAAO,YAAY,oBAAoB,KAAK;AAAA,MACxF;AAEA,UAAI,sBAAuB,CAAC,uBAAuB,CAACD,4BAA2B,OAAO,QAAQ,GAAI;AAChG;AAAA,MACF;AAEA,YAAM,aAAa,OAAO,KAAK,YAAY;AAC3C,YAAM,YACJ,eAAe,cACf,WAAW,QAAQ,MAAM,EAAE,MAAM;AACnC,YAAM,QAAQ,YAAY,OAAO;AACjC,YAAM,WAAW,iBAAiB,IAAI,OAAO,EAAE;AAC/C,UAAI,CAAC,YAAY,QAAQ,SAAS,OAAO;AACvC,yBAAiB,IAAI,OAAO,IAAI;AAAA,UAC9B,IAAI,OAAO;AAAA,UACX;AAAA,UACA,UAAU;AAAA,YACR,UAAU,OAAO;AAAA,YACjB,WAAW,OAAO;AAAA,YAClB,SAAS,OAAO;AAAA,YAChB,WAAW,OAAO;AAAA,YAClB,MAAM,OAAO;AAAA,YACb,UAAU,OAAO;AAAA,YACjB,MAAM,OAAO;AAAA,UACf;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,oBAAoB,oBAAI,IAAyC;AACvE,eAAW,SAAS,cAAc;AAChC,wBAAkB,IAAI,MAAM,SAAS,KAAK;AAAA,IAC5C;AAEA,eAAW,SAAS,kBAAkB,OAAO,GAAG;AAC9C,UAAI,gBAAgB,CAAC,gBAAgB,MAAM,UAAU,YAAY,GAAG;AAClE;AAAA,MACF;AACA,2BAAqB,OAAO,YAAY,oBAAoB;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,gBAAgB,aAAa;AAC/B,UAAM,gBAAgB;AAAA,MACpB,GAAG,SAAS,gBAAgB,WAAW;AAAA,MACvC,GAAG,SAAS,kBAAkB,WAAW;AAAA,IAC3C;AACA,UAAM,qBAAqB,oBAAI,IAA0C;AACzE,eAAW,SAAS,eAAe;AACjC,yBAAmB,IAAI,MAAM,SAAS,KAAK;AAAA,IAC7C;AAEA,eAAW,SAAS,mBAAmB,OAAO,GAAG;AAC/C,UAAI,CAAC,gBAAgB,MAAM,UAAU,YAAY,GAAG;AAClD;AAAA,MACF;AACA,YAAM,oBAAoB,YAAY,QAAQ,MAAM,EAAE;AACtD,2BAAqB,OAAO,aAAa,mBAAmB,CAAG;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,KAAK,iBAAiB,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AACjH,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,yBAAyB,mBAAmB;AAAA,MAAO,CAAC,cACxD,0BAA0B,UAAU,SAAS,SAAS,MACrD,uBAAuBA,4BAA2B,UAAU,SAAS,QAAQ;AAAA,IAChF;AAEA,eAAW,aAAa,wBAAwB;AAC9C,YAAM,aAAa,UAAU,SAAS,QAAQ,IAAI,YAAY;AAC9D,YAAM,YAAY,UAAU,SAAS,SAAS,YAAY;AAE1D,YAAM,iBAAiB,gBAAgB,KAAK,CAAC,SAAS,cAAc,QAAQ,UAAU,QAAQ,MAAM,EAAE,MAAM,KAAK,QAAQ,MAAM,EAAE,CAAC;AAClI,YAAM,gBAAgB,uBAAuB,SAAS;AACtD,YAAM,YAAY,cAAc,OAAO,CAAC,SAAS,cAAc,IAAI,IAAI,KAAK,UAAU,SAAS,IAAI,CAAC,EAAE;AAEtG,UAAI,CAAC,kBAAkB,cAAc,GAAG;AACtC;AAAA,MACF;AAEA,YAAM,YAAY,iBACd,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,OAAO,IAAI,CAAC,IAC3C,KAAK,IAAI,MAAM,KAAK,IAAI,UAAU,OAAO,OAAO,YAAY,IAAI,CAAC;AACrE,uBAAiB,IAAI,UAAU,IAAI;AAAA,QACjC,IAAI,UAAU;AAAA,QACd,OAAO;AAAA,QACP,UAAU,UAAU;AAAA,MACtB,CAAC;AAAA,IACH;AAEA,QAAI,iBAAiB,SAAS,GAAG;AAC/B,YAAM,gBAAgB,uBAAuB,KAAK;AAClD,YAAM,iBAAiB,uBACpB,IAAI,CAAC,cAAc;AAClB,cAAM,aAAa,uBAAuB,UAAU,SAAS,QAAQ,EAAE;AACvE,cAAM,aAAa,gBAAgB,UAAU,SAAS,QAAQ;AAC9D,YAAI,UAAU;AACd,mBAAW,SAAS,eAAe;AACjC,cAAI,WAAW,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,GAAG;AAClD,uBAAW;AAAA,UACb;AAAA,QACF;AACA,cAAM,eAAe,cAAc,OAAO,IAAI,UAAU,cAAc,OAAO;AAC7E,eAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC,EACA,OAAO,CAAC,UAAU,MAAM,eAAe,CAAC,EACxC,KAAK,CAAC,GAAG,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,QAAQ,EAAE,UAAU,KAAK,EACvF,MAAM,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC;AAE9B,iBAAW,SAAS,gBAAgB;AAClC,yBAAiB,IAAI,MAAM,UAAU,IAAI;AAAA,UACvC,IAAI,MAAM,UAAU;AAAA,UACpB,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,UAAU,OAAO,MAAM,MAAM,eAAe,GAAG,CAAC;AAAA,UACrF,UAAU,MAAM,UAAU;AAAA,QAC5B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,KAAK,iBAAiB,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AACvH,SAAO,aAAa,MAAM,GAAG,KAAK,IAAI,QAAQ,GAAG,KAAK,CAAC;AACzD;AAEO,SAAS,mBACd,YACA,YACA,OACmB;AACnB,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,WAAW,MAAM,GAAG,KAAK;AAAA,EAClC;AAEA,QAAM,MAAyB,CAAC;AAChC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,aAAa,YAAY;AAClC,QAAI,KAAK,IAAI,UAAU,EAAE,EAAG;AAC5B,QAAI,KAAK,SAAS;AAClB,SAAK,IAAI,UAAU,EAAE;AACrB,QAAI,IAAI,UAAU,MAAO,QAAO;AAAA,EAClC;AAEA,aAAW,aAAa,YAAY;AAClC,QAAI,KAAK,IAAI,UAAU,EAAE,EAAG;AAC5B,QAAI,KAAK,SAAS;AAClB,SAAK,IAAI,UAAU,EAAE;AACrB,QAAI,IAAI,UAAU,MAAO,QAAO;AAAA,EAClC;AAEA,SAAO;AACT;AAEO,SAAS,6BAAgC,QAAa,OAAoB;AAC/E,MAAI,SAAS,KAAK,OAAO,WAAW,GAAG;AACrC,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,OAAO,UAAU,OAAO;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,GAAG;AACf,WAAO,CAAC,OAAO,KAAK,OAAO,OAAO,SAAS,KAAK,CAAC,CAAC,CAAE;AAAA,EACtD;AAEA,QAAM,WAAgB,CAAC;AACvB,WAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,UAAM,cAAc,KAAK,MAAM,SAAS,OAAO,SAAS,MAAM,QAAQ,EAAE;AACxE,aAAS,KAAK,OAAO,WAAW,CAAE;AAAA,EACpC;AACA,SAAO;AACT;AAEO,SAAS,sBACd,QACA,OACA,cACK;AACL,QAAM,kBAAkB,eACpB,OAAO,OAAO,CAAC,UAAU,MAAM,cAAc,OAAO,IACpD;AACJ,SAAO,6BAA6B,iBAAiB,KAAK;AAC5D;AAEA,SAAS,yBACP,WACA,SACA,aACS;AACT,MAAI,SAAS,UAAU;AACrB,UAAM,MAAM,UAAU,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AACtE,UAAM,qBAAqB,QAAQ,SAAS,KAAK,EAAE,YAAY,EAAE,QAAQ,OAAO,EAAE;AAClF,QAAI,QAAQ,mBAAoB,QAAO;AAAA,EACzC;AAEA,MAAI,SAAS,WAAW;AACtB,UAAM,gBAAgB;AAAA,MACf,eAAQ,aAAa,UAAU,SAAS,SAAS,QAAQ,OAAY,UAAG,CAAC;AAAA,IAChF;AACA,UAAM,gBAAgB;AAAA,MACf,eAAQ,aAAa,QAAQ,UAAU,KAAK,EAAE,QAAQ,OAAY,UAAG,CAAC;AAAA,IAC7E;AACA,QAAI,CAACD,kBAAiB,eAAe,aAAa,EAAG,QAAO;AAAA,EAC9D;AAEA,MAAI,SAAS,aAAa,UAAU,SAAS,cAAc,QAAQ,WAAW;AAC5E,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,aAAa;AACxB,UAAM,SAAS,QAAQ,YAAY,YAAY;AAC/C,UAAM,kBAAkB,UAAU,SAAS,aAAa,YAAY;AACpE,UAAM,iBAAiB,UAAU,SAAS,kBAAkB,YAAY;AACxE,QAAI,oBAAoB,UAAU,mBAAmB,OAAQ,QAAO;AAAA,EACtE;AAEA,MAAI,SAAS,YAAY,CAAC,UAAU,SAAS,UAAU,YAAY,EAAE,WAAW,QAAQ,SAAS,YAAY,CAAC,GAAG;AAC/G,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,QAAQ,oBAAoB,QAAQ,YAAY,KAAK;AAC3D,QAAI,UAAU,KAAM,QAAO;AAC3B,UAAM,cAAc,UAAU,SAAS;AACvC,QAAI,gBAAgB,UAAa,cAAc,MAAO,QAAO;AAAA,EAC/D;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,QAAQ,oBAAoB,QAAQ,YAAY,IAAI;AAC1D,QAAI,UAAU,KAAM,QAAO;AAC3B,UAAM,cAAc,UAAU,SAAS;AACvC,QAAI,gBAAgB,UAAa,cAAc,MAAO,QAAO;AAAA,EAC/D;AAEA,SAAO;AACT;AAEA,SAAS,qBACP,WACA,SACA,UACA,aACS;AACT,SAAO,UAAU,SAAS,YAAY,yBAAyB,WAAW,SAAS,WAAW;AAChG;AAEA,SAAS,gBACP,oBACA,mBACmB;AACnB,QAAM,OAAO,oBAAI,IAA6B;AAC9C,aAAW,aAAa,oBAAoB;AAC1C,SAAK,IAAI,UAAU,IAAI,SAAS;AAAA,EAClC;AACA,aAAW,aAAa,mBAAmB;AACzC,UAAM,WAAW,KAAK,IAAI,UAAU,EAAE;AACtC,QAAI,CAAC,YAAY,UAAU,QAAQ,SAAS,OAAO;AACjD,WAAK,IAAI,UAAU,IAAI,SAAS;AAAA,IAClC;AAAA,EACF;AACA,SAAO,MAAM,KAAK,KAAK,OAAO,CAAC;AACjC;AAEO,IAAM,UAAN,MAAM,SAAQ;AAAA,EACF;AAAA,EACT;AAAA,EACA;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACA,QAA4B;AAAA,EAC5B,gBAAsC;AAAA,EACtC,WAA4B;AAAA,EAC5B,WAA8C;AAAA,EAC9C,yBAAwD;AAAA,EACxD,gBAAqC,oBAAI,IAAI;AAAA,EAC7C,oBAA4B;AAAA,EAC5B,oBAA4B;AAAA,EAC5B,gBAAwB;AAAA,EACxB,aAAqB;AAAA,EACrB;AAAA,EACA,sBAA+E,oBAAI,IAAI;AAAA,EAC9E,oBAAoB;AAAA,EACpB,kBAAkB,IAAI,KAAK;AAAA,EAC3B,2BAA2B;AAAA,EACpC,qBAAgD;AAAA,EAChD,mBAA0C;AAAA,EAC1C,wBAA8C;AAAA,EAC9C,qBAAyC;AAAA,EACzC,aAA+B,CAAC;AAAA,EAChC,mBAA+B,CAAC;AAAA,EAChC,4BAA8D;AAAA,EAC9D,4BAA8D;AAAA,EAC9D,2BAA2B,oBAAI,IAAyC;AAAA,EAC/D;AAAA,EACA;AAAA,EAEjB,YACE,aACA,QACA,MACA,iBAAwC,CAAC,GACzC;AACA,SAAK,cAAc;AACnB,SAAK,sBAAsB,KAAK,uBAAuB,WAAW;AAClE,SAAK,0BAA0B,eAAe,2BAA2B;AACzE,SAAK,qBAAqB,eAAe;AACzC,SAAK,0BAA0B,eAAe;AAC9C,QAAI,eAAe,mBAAmB,UAAa,CAAC,gBAAgB,eAAe,cAAc,GAAG;AAClG,YAAM,IAAI,MAAM,mCAAmC,KAAK,UAAU,eAAe,cAAc,CAAC,EAAE;AAAA,IACpG;AACA,SAAK,yBAAyB,eAAe,gBAAgB,YAAY;AACzE,SAAK,oBAAoB,eAAe;AACxC,SAAK,kBAAkB,eAAe;AACtC,SAAK,2BAA2B,eAAe;AAC/C,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,QAAI,UAAU,KAAK,uBAAuB,GAAG;AAC3C,WAAK,gBAAgB,KAAK,sBAAsB,mBAAmB,KAAK,uBAAuB;AAC/F,WAAK,aAAa,cAAc,KAAK,uBAAuB;AAAA,IAC9D,OAAO;AACL,WAAK,gBAAgB;AACrB,WAAK,aAAa;AAAA,IACpB;AACA,SAAK,YAAY,KAAK,aAAa;AACnC,SAAK,4BAA4B;AACjC,SAAK,SAAS,iBAAiB,OAAO,KAAK;AAAA,EAC7C;AAAA,EAEQ,eAAuB;AAC7B,WAAO,KAAK,qBAAqB,wBAAwB,KAAK,aAAa,KAAK,OAAO,OAAO,KAAK,IAAI;AAAA,EACzG;AAAA,EAEQ,oBAAoB,UAA0B;AACpD,QAAI,CAAM,kBAAW,QAAQ,GAAG;AAC9B,aAAO,KAAK,sBAAsB,UAAU,KAAK,WAAW;AAAA,IAC9D;AACA,QACO,eAAQ,KAAK,uBAAuB,MAAW,eAAQ,KAAK,WAAW,KACzE,CAACA,kBAAiB,UAAU,KAAK,uBAAuB,GAC3D;AACA,aAAO;AAAA,IACT;AACA,WAAY,eAAQ,KAAK,aAAkB,gBAAS,KAAK,yBAAyB,QAAQ,CAAC;AAAA,EAC7F;AAAA,EAEQ,iBAAiB,UAA0B;AACjD,UAAM,oBAAoB,KAAK,oBAAoB,QAAQ;AAC3D,QACE,KAAK,OAAO,UAAU,aACnB,CAACA,kBAAiB,mBAAmB,KAAK,WAAW,GACxD;AACA,aAAO;AAAA,IACT;AAEA,WAAY,gBAAS,KAAK,aAAa,iBAAiB,EAAE,MAAW,UAAG,EAAE,KAAK,GAAG;AAAA,EACpF;AAAA,EAEQ,sBAAsB,UAAkB,WAAW,KAAK,aAAqB;AACnF,QAAS,kBAAW,QAAQ,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,eAAoB,eAAQ,UAAU,GAAG,SAAS,MAAM,GAAG,CAAC;AAClE,QAAI,CAACA,kBAAiB,cAAc,QAAQ,GAAG;AAC7C,YAAM,IAAI,MAAM,6CAA6C,KAAK,UAAU,QAAQ,CAAC,EAAE;AAAA,IACzF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,2BAA2B,UAA0B;AAC3D,WAAO,KAAK,iBAAiB,KAAK,sBAAsB,QAAQ,CAAC;AAAA,EACnE;AAAA,EAEQ,sBAAsD,QAAc;AAC1E,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,KAAK,sBAAsB,OAAO,QAAQ;AAAA,IACtD;AAAA,EACF;AAAA,EAEQ,wBAAwB,MAAkC;AAChE,QAAI,CAAC,KAAK,mBAAoB,QAAO;AACrC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,oBAAoB,KAAK,sBAAsB,KAAK,kBAAkB;AAAA,IACxE;AAAA,EACF;AAAA,EAEQ,uBAAuB,UAA0B;AACvD,UAAM,iBAAiB,KAAK,iBAAiB,QAAQ;AACrD,QAAS,kBAAW,cAAc,GAAG;AACnC,aAAO;AAAA,IACT;AACA,WAAO,KAAK,sBAAsB,gBAAgB,KAAK,uBAAuB;AAAA,EAChF;AAAA,EAEQ,6BAA4C;AAClD,QAAI,CAAC,KAAK,sBAAsB,CAAC,KAAK,wBAAyB,QAAO;AACtE,WAAO,YAAY,KAAK,oBAAoB,CAAC,EAAE,MAAM,GAAG,EAAE;AAAA,EAC5D;AAAA,EAEQ,8BAA6C;AACnD,QAAI,KAAK,OAAO,UAAU,aAAa,KAAK,yBAAyB,MAAM,WAAW;AACpF,aAAO,KAAK,2BAA2B;AAAA,IACzC;AACA,WAAO,YAAY,KAAK,oBAAoB,CAAC,EAAE,MAAM,GAAG,EAAE;AAAA,EAC5D;AAAA,EAEQ,uBAAuB,UAA0B;AACvD,UAAM,YAAY,KAAK,4BAA4B;AACnD,QAAI,CAAC,UAAW,QAAY,YAAK,KAAK,WAAW,QAAQ;AACzD,UAAM,YAAiB,eAAQ,QAAQ;AACvC,UAAM,WAAW,SAAS,MAAM,GAAG,SAAS,SAAS,UAAU,MAAM;AACrE,WAAY,YAAK,KAAK,WAAW,GAAG,QAAQ,IAAI,SAAS,GAAG,SAAS,EAAE;AAAA,EACzE;AAAA,EAEQ,8BAAoC;AAC1C,SAAK,oBAAoB,KAAK,uBAAuB,kBAAkB;AACvE,SAAK,oBAAoB,KAAK,uBAAuB,qBAAqB;AAAA,EAC5E;AAAA,EAEQ,mBAAmB,SAAyB;AAClD,UAAM,YAAY,KAAK,2BAA2B;AAClD,WAAO,YAAY,GAAG,OAAO,IAAI,SAAS,KAAK;AAAA,EACjD;AAAA,EAEQ,gCAA0C;AAChD,UAAM,uBAAuB,KAAK,iBAAiB,KAAK,WAAW;AACnE,WAAO,KAAK,OAAO,eAAe,IAAI,CAAC,kBAAkB;AACvD,YAAM,iBAAsB,kBAAW,aAAa,IAChD,gBACK,eAAQ,KAAK,aAAa,aAAa;AAChD,YAAM,gBAAgB,KAAK,iBAAiB,cAAc;AAC1D,UAAI,CAACA,kBAAiB,eAAe,oBAAoB,GAAG;AAC1D,eAAO;AAAA,MACT;AACA,aAAY;AAAA,QACV,KAAK;AAAA,QACA,gBAAS,sBAAsB,aAAa;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,YAA4B;AACnD,QAAI;AACF,aAAO,8BAA8B,UAAU;AAAA,IACjD,QAAQ;AACN,aAAY,eAAQ,UAAU;AAAA,IAChC;AAAA,EACF;AAAA,EAEQ,uBAAuB,aAA6B;AAC1D,WAAO,YAAY,KAAK,iBAAiB,WAAW,CAAC,EAAE,MAAM,GAAG,EAAE;AAAA,EACpE;AAAA,EAEQ,0BAAmC;AACzC,WAAO,iCAAiC,KAAK,aAAa,KAAK,WAAW,KAAK,IAAI;AAAA,EACrF;AAAA,EAEQ,sBAAsB,iBAAiB,OAAa;AAC1D,QAAI,KAAK,UAAU;AACjB,UAAI,gBAAgB;AAClB,aAAK,iBAAiB,KAAK,KAAK,QAAQ;AAAA,MAC1C,OAAO;AACL,aAAK,SAAS,MAAM;AAAA,MACtB;AAAA,IACF;AACA,SAAK,QAAQ;AACb,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,yBAAyB;AAC9B,SAAK,qBAAqB;AAC1B,SAAK,qBAAqB;AAC1B,SAAK,aAAa,CAAC;AACnB,SAAK,4BAA4B;AACjC,SAAK,4BAA4B;AACjC,SAAK,yBAAyB,MAAM;AACpC,SAAK,cAAc,MAAM;AAAA,EAC3B;AAAA,EAEQ,0BAAgC;AACtC,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,iBAAiB,CAAC,KAAK,uBAAwB;AACxE,SAAK,MAAM,KAAK;AAChB,SAAK,cAAc,KAAK;AACxB,SAAK,cAAc,MAAM;AACzB,SAAK,kBAAkB;AACvB,SAAK,qBAAqB,KAAK,2BAA2B,KAAK,sBAAsB;AACrF,SAAK,aAAa,CAAC;AACnB,SAAK,yBAAyB,MAAM;AAAA,EACtC;AAAA,EAEA,MAAc,uBACZ,WACA,UACY;AACZ,SAAK,kBAAkB;AACvB,UAAM,QAAQ,iBAAiB,KAAK,WAAW,WAAW;AAAA,MACxD,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK,eAAe;AAAA,IACnC,CAAC;AACD,SAAK,YAAY,MAAM;AACvB,SAAK,4BAA4B;AACjC,SAAK,mBAAmB;AAExB,QAAI;AACJ,QAAI;AACJ,QAAI,iBAAiB;AACrB,QAAI;AACF,eAAS,MAAM,SAAS,MAAM,WAAW,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK,CAAC;AAAA,IACpE,SAAS,OAAO;AACd,uBAAiB;AACjB,sBAAgB;AAAA,IAClB;AACA,QAAI,CAAC,gBAAgB;AACnB,UAAI;AACF,8BAAsB,KAAK;AAC3B,aAAK,4BAA4B,KAAK,iCAAiC;AAAA,MACzE,SAAS,OAAO;AACd,yBAAiB;AACjB,wBAAgB;AAAA,MAClB;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,UAAI,CAAC,iBAAiB,KAAK,GAAG;AAC5B,uBAAe,IAAI,MAAM,0CAA0C,MAAM,MAAM,KAAK,EAAE;AACtF,aAAK,4BAA4B;AACjC,YAAI,KAAK,kBAAkB,MAAM,UAAU,MAAM,MAAM,OAAO;AAC5D,eAAK,mBAAmB;AAAA,QAC1B;AAAA,MACF,WAAW,KAAK,kBAAkB,MAAM,UAAU,MAAM,MAAM,OAAO;AACnE,aAAK,mBAAmB;AAAA,MAC1B;AAAA,IACF,SAAS,OAAO;AACd,qBAAe;AACf,WAAK,4BAA4B;AACjC,UAAI,KAAC,wBAAW,MAAM,QAAQ,KAAK,KAAK,kBAAkB,MAAM,UAAU,MAAM,MAAM,OAAO;AAC3F,aAAK,mBAAmB;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,iBAAiB,QAAW;AAC9B,UAAI,eAAgB,OAAM,IAAI,eAAe,CAAC,eAAe,YAAY,GAAG,8CAA8C;AAC1H,YAAM;AAAA,IACR;AACA,QAAI,eAAgB,OAAM;AAC1B,WAAO;AAAA,EACT;AAAA,EAEQ,qBAAqC;AAC3C,QAAI,CAAC,KAAK,kBAAkB;AAC1B,YAAM,IAAI,MAAM,+DAA+D;AAAA,IACjF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAC,wBAAW,KAAK,iBAAiB,GAAG;AACvC,WAAK,gBAAgB,oBAAI,IAAI;AAC7B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAO,0BAAa,KAAK,mBAAmB,OAAO;AACzD,YAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAK,gBAAgB,IAAI,IAAI,OAAO,QAAQ,MAAM,CAAC;AAAA,IACrD,SAAS,OAAgB;AACvB,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAK,OAAO,KAAK,yDAAyD;AAAA,QACxE,mBAAmB,KAAK;AAAA,QACxB,OAAO;AAAA,MACT,CAAC;AACD,WAAK,gBAAgB,oBAAI,IAAI;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,UAAM,MAA8B,CAAC;AACrC,eAAW,CAAC,GAAG,CAAC,KAAK,KAAK,eAAe;AACvC,UAAI,CAAC,IAAI;AAAA,IACX;AACA,SAAK,gBAAgB,KAAK,mBAAmB,KAAK,UAAU,GAAG,CAAC;AAAA,EAClE;AAAA,EAEQ,gBAAgB,YAAoB,MAAoB;AAC9D,UAAM,QAAQ,KAAK,mBAAmB;AACtC,UAAM,WAAW,yBAAyB,YAAY,MAAM,OAAO,KAAK;AACxE,+BAAe,eAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAI;AACF,qCAAc,UAAU,IAAI;AAC5B,kCAAW,UAAU,UAAU;AAAA,IACjC,UAAE;AACA,+BAAyB,QAAQ;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,kBAAkB,eAAoC;AAC5D,SAAK;AAAA,MACE,YAAK,KAAK,WAAW,qBAAqB;AAAA,MAC/C,cAAc,UAAU;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,eAAe,cAAc,KAAK,aAAuB;AAC/D,UAAM,QAAQ,oBAAI,IAAY,CAAC,KAAK,iBAAiB,WAAW,CAAC,CAAC;AAElE,eAAW,UAAU,KAAK,OAAO,gBAAgB;AAC/C,YAAM,IAAI,KAAK,iBAAsB,eAAQ,aAAa,MAAM,CAAC,CAAC;AAAA,IACpE;AAEA,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB;AAAA,EAEQ,sBAA8B;AACpC,WAAO,KAAK,uBAAuB,KAAK,yBAAyB,CAAC;AAAA,EACpE;AAAA,EAEQ,2BAAmC;AACzC,YAAQ,KAAK,2BACR,KAAK,sBACL,KAAK,kBACL;AAAA,EACP;AAAA,EAEQ,uBAAuB,YAA4B;AACzD,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO;AAAA,IACT;AAEA,WAAO,GAAG,KAAK,mBAAmB,IAAI,UAAU;AAAA,EAClD;AAAA,EAEQ,wBAAwB,YAA6B;AAC3D,WAAO,eAAe,SAClB,KAAK,oBAAoB,IACzB,KAAK,uBAAuB,UAAU;AAAA,EAC5C;AAAA,EAEQ,2BAA2B,kBAAkB,KAAK,yBAAyB,GAAW;AAC5F,UAAM,YAAY,KAAK,uBAAuB,eAAe;AAC7D,WAAO,sBAAsB,YAAY,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,EAClE;AAAA,EAEQ,wCAAwC,WAA2B;AACzE,WAAO,sBAAsB,YAAY,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,EAClE;AAAA,EAEQ,sBAAsB,UAAoB,kBAAkB,KAAK,yBAAyB,GAAkB;AAClH,WAAO,SAAS,YAAY,KAAK,2BAA2B,eAAe,CAAC;AAAA,EAC9E;AAAA,EAEQ,iBAAiB,UAAoB,QAA6B;AACxE,UAAM,cAAc,KAAK,2BAA2B;AACpD,QAAI,QAAQ;AACV,eAAS,YAAY,aAAa,MAAM;AAAA,IAC1C,OAAO;AACL,eAAS,eAAe,WAAW;AAAA,IACrC;AAAA,EACF;AAAA,EAEQ,2BAA2B,UAAoB,YAAqC;AAC1F,eAAW,aAAa,IAAI,IAAI,UAAU,GAAG;AAC3C,eAAS,eAAe,KAAK,wCAAwC,SAAS,CAAC;AAAA,IACjF;AAAA,EACF;AAAA,EAEQ,qBACN,OACA,eACA,UACA,kBACA,kBACA,iBACA,mBACA,kBACS;AACT,aAAS,YAAY,gBAAgB;AACrC,aAAS,uBAAuB,kBAAkB,CAAC,GAAG,eAAe,CAAC;AACtE,aAAS,mBAAmB,gBAAgB;AAC5C,aAAS,wBAAwB,kBAAkB,CAAC,GAAG,gBAAgB,CAAC;AAExE,UAAM,oBAAoB,IAAI,IAAI,eAAe;AACjD,UAAM,yBAAyB,iBAAiB,OAAO,CAAC,YAAY,CAAC,kBAAkB,IAAI,OAAO,CAAC;AACnG,UAAM,qBAAqB,IAAI,IAAI,SAAS,sBAAsB,sBAAsB,CAAC;AACzF,UAAM,oBAAoB,uBAAuB,OAAO,CAAC,YAAY,CAAC,mBAAmB,IAAI,OAAO,CAAC;AACrG,QAAI,kBAAkB,SAAS,GAAG;AAChC,WAAK,oCAAoC,OAAO,UAAU,iBAAiB;AAC3E,iBAAW,WAAW,mBAAmB;AACvC,sBAAc,YAAY,OAAO;AAAA,MACnC;AACA,eAAS,kBAAkB,iBAAiB;AAAA,IAC9C;AAEA,UAAM,qBAAqB,IAAI,IAAI,gBAAgB;AACnD,UAAM,0BAA0B,kBAAkB,OAAO,CAAC,aAAa,CAAC,mBAAmB,IAAI,QAAQ,CAAC;AACxG,UAAM,sBAAsB,IAAI,IAAI,SAAS,uBAAuB,uBAAuB,CAAC;AAC5F,UAAM,qBAAqB,wBAAwB,OAAO,CAAC,aAAa,CAAC,oBAAoB,IAAI,QAAQ,CAAC;AAC1G,aAAS,+BAA+B,kBAAkB;AAC1D,aAAS,gBAAgB;AACzB,aAAS,kBAAkB;AAC3B,aAAS,mBAAmB;AAE5B,WAAO,kBAAkB,SAAS;AAAA,EACpC;AAAA,EAEQ,4BAAoC;AAC1C,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEQ,8BAA8B,sBAAsB,KAAK,qBAA6B;AAC5F,WAAO,+BAA+B,mBAAmB;AAAA,EAC3D;AAAA,EAEQ,uCAAuC,sBAAsB,KAAK,qBAA6B;AACrG,WAAO,kCAAkC,mBAAmB;AAAA,EAC9D;AAAA,EAEQ,kCAAkC,sBAAsB,KAAK,qBAA6B;AAChG,WAAO,sBAAsB,mBAAmB;AAAA,EAClD;AAAA,EAEQ,wCAAwC,sBAAsB,KAAK,qBAA6B;AACtG,WAAO,4BAA4B,mBAAmB;AAAA,EACxD;AAAA,EAEQ,8BACN,QACA,kBAAkB,KAAK,yBAAyB,GACxC;AACR,UAAM,YAAY,KAAK,uBAAuB,eAAe;AAC7D,WAAO,GAAG,MAAM,IAAI,YAAY,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,EACzD;AAAA,EAEQ,kCACN,kBAAkB,KAAK,yBAAyB,GACxC;AACR,WAAO,KAAK,8BAA8B,oCAAoC,eAAe;AAAA,EAC/F;AAAA,EAEQ,iCACN,kBAAkB,KAAK,yBAAyB,GACxC;AACR,WAAO,KAAK,8BAA8B,6BAA6B,eAAe;AAAA,EACxF;AAAA,EAEQ,iCACN,kBAAkB,KAAK,yBAAyB,GACxC;AACR,WAAO,KAAK,8BAA8B,6BAA6B,eAAe;AAAA,EACxF;AAAA,EAEQ,qCACN,kBAAkB,KAAK,yBAAyB,GACxC;AACR,WAAO,KAAK,8BAA8B,gCAAgC,eAAe;AAAA,EAC3F;AAAA,EAEQ,kCACN,UACA,kBAAkB,KAAK,yBAAyB,GACvC;AACT,WAAO,SAAS,YAAY,KAAK,kCAAkC,eAAe,CAAC,MAC7E,iCACD,SAAS,YAAY,KAAK,iCAAiC,eAAe,CAAC,MAC1E,wBACD,SAAS,YAAY,KAAK,iCAAiC,eAAe,CAAC,MAC1E,wBACD,SAAS,YAAY,KAAK,qCAAqC,eAAe,CAAC,MAC9E;AAAA,EACR;AAAA,EAEQ,gCAAyC;AAC/C,WAAO,KAAK,OAAO,UAAU,YAAY,KAAK,UAAU,YAAY,KAAK,kCAAkC,CAAC,MAAM;AAAA,EACpH;AAAA,EAEQ,uBAAgC;AACtC,QAAI,CAAC,KAAK,SAAS,KAAK,OAAO,UAAU,UAAU;AACjD,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,8BAA8B,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,KAAK,eAAe;AAElC,QAAI,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,qBAAqB,UAAU,KAAK,CAAC,GAAG;AACxG,aAAO;AAAA,IACT;AAEA,eAAW,SAAS,KAAK,4BAA4B,GAAG;AACtD,UAAI,MAAM,OAAO,KAAK,CAAC,UAAU;AAC/B,cAAM,WAAW,wBAAwB,KAAK;AAC9C,eAAO,aAAa,QAAQ,KAAK,qBAAqB,UAAU,KAAK;AAAA,MACvE,CAAC,GAAG;AACF,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,UAAU;AAClB,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,qBAAqB,EAAE,KAAK,CAAC,cAAc;AAClD,YAAM,iBAAiB,KAAK,SAAU,kBAAkB,SAAS;AACjE,UAAI,eAAe,SAAS,GAAG;AAC7B,eAAO;AAAA,MACT;AAEA,aAAO,KAAK,SAAU,mBAAmB,SAAS,EAAE,SAAS;AAAA,IAC/D,CAAC,GAAG;AACF,aAAO;AAAA,IACT;AAEA,UAAM,mBAAmB,KAAK,SAAS,eAAe,EAAE,KAAK,CAAC,cAAc;AAC1E,YAAM,iBAAiB,KAAK,SAAU,kBAAkB,SAAS;AACjE,UAAI,eAAe,SAAS,GAAG;AAC7B,eAAO;AAAA,MACT;AAEA,aAAO,KAAK,SAAU,mBAAmB,SAAS,EAAE,SAAS;AAAA,IAC/D,CAAC;AACD,QAAI,kBAAkB;AACpB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,KAAK,qBAAqB,SAAS,UAAU,KAAK,CAAC;AAAA,EAC/G;AAAA,EAEQ,qCAAoD;AAC1D,QAAI,CAAC,KAAK,UAAU;AAClB,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,8BAA8B,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO,KAAK,SAAS,YAAY,gCAAgC,KAAK;AAAA,IACxE;AAEA,UAAM,iBAAiB,KAAK,SAAS,YAAY,KAAK,uCAAuC,CAAC;AAC9F,QAAI,gBAAgB;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,KAAK,SAAS,YAAY,gCAAgC;AACtF,QAAI,uBAAuB,KAAK,qBAAqB,GAAG;AACtD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAiC;AACvC,UAAM,UAAU,KAAK,oBAAoB;AACzC,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO,CAAC,OAAO;AAAA,IACjB;AAEA,QAAI,KAAK,UAAU,YAAY,KAAK,8BAA8B,CAAC,MAAM,QAAQ;AAC/E,aAAO,CAAC,OAAO;AAAA,IACjB;AAEA,UAAM,SAAS,KAAK,0BAA0B;AAC9C,WAAO,YAAY,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,MAAM;AAAA,EAC1D;AAAA,EAEQ,8BAAwC;AAC9C,UAAM,UAAU,KAAK,oBAAoB;AACzC,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO,CAAC,OAAO;AAAA,IACjB;AAEA,UAAM,SAAS,KAAK,0BAA0B;AAC9C,WAAO,YAAY,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,MAAM;AAAA,EAC1D;AAAA,EAEQ,kCAAkC,OAAiB,cAAc,KAAK,aAG5E;AACA,UAAM,WAAW,oBAAI,IAAY;AACjC,UAAM,YAAY,oBAAI,IAAY;AAClC,QAAI,CAAC,KAAK,UAAU;AAClB,aAAO,EAAE,UAAU,UAAU;AAAA,IAC/B;AAEA,UAAM,wBAAwB,oBAAI,IAAY;AAAA,MAC5C,GAAG,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,EAAE;AAAA,QACvC,CAAC,aAAa,KAAK,qBAAqB,UAAU,KAAK,KAAK,KAAK,oBAAoB,UAAU,WAAW;AAAA,MAC5G;AAAA,MACA,IAAI,KAAK,OAAO,eAAe,KAAK,CAAC,GAClC,IAAI,CAAC,EAAE,SAAS,MAAM,SAAS,QAAQ,EACvC;AAAA,QACC,CAAC,aAAa,KAAK,qBAAqB,UAAU,KAAK,KAAK,KAAK,oBAAoB,UAAU,WAAW;AAAA,MAC5G;AAAA,IACJ,CAAC;AAED,eAAW,YAAY,uBAAuB;AAC5C,iBAAW,SAAS,KAAK,SAAS,gBAAgB,QAAQ,GAAG;AAC3D,iBAAS,IAAI,MAAM,OAAO;AAAA,MAC5B;AAEA,iBAAW,UAAU,KAAK,SAAS,iBAAiB,QAAQ,GAAG;AAC7D,kBAAU,IAAI,OAAO,EAAE;AAAA,MACzB;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,UAAU;AAAA,EAC/B;AAAA,EAEQ,yCACN,iBACA,kBACA,cAAc,KAAK,aACT;AACV,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO,KAAK,4BAA4B;AAAA,IAC1C;AAEA,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,oBAAoB,IAAI,IAAI,eAAe;AACjD,UAAM,qBAAqB,IAAI,IAAI,gBAAgB;AACnD,UAAM,sBAAsB,KAAK,uBAAuB,WAAW;AAEnE,eAAW,aAAa,KAAK,UAAU,eAAe,KAAK,CAAC,GAAG;AAC7D,UAAI,UAAU,WAAW,GAAG,mBAAmB,GAAG,GAAG;AACnD,aAAK,IAAI,SAAS;AAClB;AAAA,MACF;AAEA,YAAM,0BAA0B,KAAK,UAAU,kBAAkB,SAAS,EAAE,KAAK,CAAC,YAAY,kBAAkB,IAAI,OAAO,CAAC,KAAK;AACjI,YAAM,2BAA2B,KAAK,UAAU,mBAAmB,SAAS,EAAE,KAAK,CAAC,aAAa,mBAAmB,IAAI,QAAQ,CAAC,KAAK;AACtI,UAAI,2BAA2B,0BAA0B;AACvD,aAAK,IAAI,SAAS;AAAA,MACpB;AAAA,IACF;AAEA,QAAI,gBAAgB,KAAK,aAAa;AACpC,iBAAW,aAAa,KAAK,4BAA4B,GAAG;AAC1D,aAAK,IAAI,SAAS;AAAA,MACpB;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEQ,qBAAqB,UAAkB,OAA0B;AACvE,UAAM,oBAAoB,KAAK,2BAA2B,QAAQ;AAClE,WAAO,MAAM,KAAK,CAAC,SAASA,kBAAiB,mBAAmB,IAAI,CAAC;AAAA,EACvE;AAAA,EAEQ,oBAAoB,UAAkB,cAAc,KAAK,aAAsB;AACrF,WAAOA;AAAA,MACL,KAAK,2BAA2B,QAAQ;AAAA,MACxC,KAAK,iBAAiB,WAAW;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,yBAAyB,OAAuB;AACtD,eAAW,YAAY,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,GAAG;AAC5D,UAAI,KAAK,qBAAqB,UAAU,KAAK,GAAG;AAC9C,aAAK,cAAc,OAAO,QAAQ;AAAA,MACpC;AAAA,IACF;AACA,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,2BAA2B,mBAAwC,OAAuB;AAChG,eAAW,YAAY,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,GAAG;AAC5D,UAAI,KAAK,qBAAqB,UAAU,KAAK,GAAG;AAC9C,aAAK,cAAc,OAAO,QAAQ;AAAA,MACpC;AAAA,IACF;AAEA,eAAW,CAAC,UAAU,IAAI,KAAK,mBAAmB;AAChD,WAAK,cAAc,IAAI,UAAU,IAAI;AAAA,IACvC;AAEA,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,yBAAyB,OAAuB;AACtD,SAAK,wBAAwB,CAAC,UAAU;AACtC,YAAM,WAAW,wBAAwB,KAAK;AAC9C,aAAO,aAAa,QAAQ,CAAC,KAAK,qBAAqB,UAAU,KAAK;AAAA,IACxE,CAAC;AAAA,EACH;AAAA,EAEQ,6BAA6B,OAA0B;AAC7D,WAAO,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,qBAAqB,UAAU,KAAK,CAAC;AAAA,EAC7G;AAAA,EAEQ,8BAA8B,OAA0B;AAC9D,eAAW,SAAS,KAAK,4BAA4B,GAAG;AACtD,UAAI,MAAM,OAAO,KAAK,CAAC,UAAU;AAC/B,cAAM,WAAW,wBAAwB,KAAK;AAC9C,eAAO,aAAa,QAAQ,CAAC,KAAK,qBAAqB,UAAU,KAAK;AAAA,MACxE,CAAC,GAAG;AACF,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,2BACN,cAAc,KAAK,aACnB,QAAQ,KAAK,eAAe,WAAW,GAC9B;AACT,QAAI,CAAC,KAAK,YAAY,KAAK,OAAO,UAAU,UAAU;AACpD,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,KAAK,uBAAuB,WAAW;AACnE,UAAM,EAAE,UAAU,sBAAsB,WAAW,sBAAsB,IAAI,KAAK,kCAAkC,OAAO,WAAW;AAEtI,WAAO,KAAK,SAAS,eAAe,EAAE;AAAA,MACpC,CAAC,cAAc;AACb,cAAM,iBAAiB,KAAK,SAAU,kBAAkB,SAAS;AACjE,cAAM,kBAAkB,KAAK,SAAU,mBAAmB,SAAS;AACnE,cAAM,gBAAgB,eAAe,SAAS,KAAK,gBAAgB,SAAS;AAC5E,YAAI,CAAC,eAAe;AAClB,iBAAO;AAAA,QACT;AAEA,YAAI,UAAU,WAAW,GAAG,mBAAmB,GAAG,GAAG;AACnD,iBAAO;AAAA,QACT;AAEA,cAAM,iCAAiC,eAAe,KAAK,CAAC,YAAY,qBAAqB,IAAI,OAAO,CAAC;AACzG,cAAM,kCAAkC,gBAAgB,KAAK,CAAC,aAAa,sBAAsB,IAAI,QAAQ,CAAC;AAC9G,eAAO,EAAE,kCAAkC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,4BACN,OACA,eACA,UACA,OACA,cAAc,KAAK,aACqC;AACxD,UAAM,cAAc,MAAM,eAAe;AACzC,UAAM,gBAAgB,YAAY,OAAO,CAAC,EAAE,SAAS,MAAM,KAAK,qBAAqB,SAAS,UAAU,KAAK,CAAC;AAC9G,UAAM,YAAY,oBAAI,IAAY;AAAA,MAChC,GAAG,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,EAAE,OAAO,CAAC,aAAa,KAAK,qBAAqB,UAAU,KAAK,CAAC;AAAA,MACxG,GAAG,cAAc,IAAI,CAAC,EAAE,SAAS,MAAM,SAAS,QAAQ;AAAA,IAC1D,CAAC;AAED,UAAM,wBAAwB,IAAI;AAAA,MAChC,MAAM,KAAK,SAAS,EAAE,OAAO,CAAC,aAAa,KAAK,oBAAoB,UAAU,WAAW,CAAC;AAAA,IAC5F;AAEA,UAAM,kBAAkB,IAAI,IAAY,cAAc,IAAI,CAAC,EAAE,IAAI,MAAM,GAAG,CAAC;AAC3E,eAAW,YAAY,WAAW;AAChC,iBAAW,SAAS,SAAS,gBAAgB,QAAQ,GAAG;AACtD,wBAAgB,IAAI,MAAM,OAAO;AAAA,MACnC;AAAA,IACF;AACA,UAAM,qBAAqB,MAAM,KAAK,eAAe;AAErD,UAAM,uBAAuB,IAAI;AAAA,MAC/B,cACG,OAAO,CAAC,EAAE,SAAS,MAAM,KAAK,oBAAoB,SAAS,UAAU,WAAW,CAAC,EACjF,IAAI,CAAC,EAAE,IAAI,MAAM,GAAG;AAAA,IACzB;AACA,eAAW,YAAY,uBAAuB;AAC5C,iBAAW,SAAS,SAAS,gBAAgB,QAAQ,GAAG;AACtD,6BAAqB,IAAI,MAAM,OAAO;AAAA,MACxC;AAAA,IACF;AAEA,UAAM,YAAsB,CAAC;AAC7B,UAAM,wBAAwB,oBAAI,IAAY;AAC9C,eAAW,YAAY,WAAW;AAChC,iBAAW,UAAU,SAAS,iBAAiB,QAAQ,GAAG;AACxD,kBAAU,KAAK,OAAO,EAAE;AACxB,YAAI,sBAAsB,IAAI,QAAQ,GAAG;AACvC,gCAAsB,IAAI,OAAO,EAAE;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,oBAAoB,KAAK;AAAA,MAC7B,MAAM,KAAK,oBAAoB;AAAA,MAC/B,MAAM,KAAK,qBAAqB;AAAA,MAChC;AAAA,IACF;AACA,eAAW,aAAa,mBAAmB;AACzC,eAAS,4BAA4B,WAAW,kBAAkB;AAAA,IACpE;AACA,UAAM,iBAAiB,IAAI,IAAI,SAAS,sBAAsB,kBAAkB,CAAC;AACjF,UAAM,oBAAoB,mBAAmB,OAAO,CAAC,YAAY,CAAC,eAAe,IAAI,OAAO,CAAC;AAE7F,QAAI,kBAAkB,SAAS,GAAG;AAChC,WAAK,oCAAoC,OAAO,UAAU,iBAAiB;AAC3E,iBAAW,WAAW,mBAAmB;AACvC,sBAAc,YAAY,OAAO;AAAA,MACnC;AAAA,IACF;AAEA,eAAW,aAAa,mBAAmB;AACzC,eAAS,6BAA6B,WAAW,SAAS;AAAA,IAC5D;AACA,SAAK,2BAA2B,UAAU,iBAAiB;AAC3D,UAAM,kBAAkB,IAAI,IAAI,SAAS,uBAAuB,SAAS,CAAC;AAC1E,UAAM,qBAAqB,UAAU,OAAO,CAAC,aAAa,CAAC,gBAAgB,IAAI,QAAQ,CAAC;AAExF,aAAS,+BAA+B,kBAAkB;AAE1D,eAAW,YAAY,WAAW;AAChC,YAAM,eAAe,SAAS,gBAAgB,QAAQ,EAAE,IAAI,CAAC,UAAU,MAAM,OAAO;AACpF,YAAM,cAAc,SAAS,iBAAiB,QAAQ;AAEtD,UAAI,aAAa,MAAM,CAAC,YAAY,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG;AACjE,iBAAS,mBAAmB,QAAQ;AAAA,MACtC;AAEA,UAAI,YAAY,MAAM,CAAC,WAAW,CAAC,gBAAgB,IAAI,OAAO,EAAE,CAAC,GAAG;AAClE,iBAAS,sBAAsB,QAAQ;AACvC,iBAAS,oBAAoB,QAAQ;AAAA,MACvC;AAAA,IACF;AAEA,aAAS,kBAAkB;AAC3B,aAAS,gBAAgB;AACzB,aAAS,mBAAmB;AAC5B,aAAS,eAAe;AAMxB,SAAK,kBAAkB,aAAa;AACpC,UAAM,KAAK;AAEX,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,gBAAgB,YAAY,KAAK,CAAC,EAAE,SAAS,MAAM,CAAC,KAAK,qBAAqB,SAAS,UAAU,KAAK,CAAC;AAAA,IACzG;AAAA,EACF;AAAA,EAEQ,+BAA4D;AAClE,QAAI,CAAC,KAAK,wBAAwB;AAChC,YAAM,IAAI,MAAM,kFAAkF;AAAA,IACpG;AACA,UAAM,gBAAgB,KAAK,mBAAmB;AAC9C,UAAM,wBAAwB,cAAc,aACxC,eACA,cAAc,SAAS,kEACrB,gCACA;AACN,WAAO;AAAA,MACL,OAAO;AAAA,MACP,mBAAmB,KAAK,uBAAuB;AAAA,MAC/C,gBAAgB,KAAK,uBAAuB,UAAU;AAAA,MACtD,qBAAqB,KAAK,uBAAuB,UAAU;AAAA,MAC3D,0BAA0B;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,0BAAuD;AAC7D,UAAM,WAAW,KAAK,6BAA6B;AACnD,mCAA+B,KAAK,mBAAmB,GAAG,QAAQ;AAClE,WAAO;AAAA,EACT;AAAA,EAEQ,2BAAiC;AACvC,mCAA+B,KAAK,mBAAmB,GAAG,IAAI;AAAA,EAChE;AAAA,EAEQ,yCAAyC,UAAgD;AAC/F,UAAM,yBAAyB,KAAK;AACpC,WAAO,2BAA2B,QAC7B,SAAS,sBAAsB,uBAAuB,YACtD,SAAS,mBAAmB,uBAAuB,UAAU,SAC7D,SAAS,wBAAwB,uBAAuB,UAAU,cAClE,SAAS,6BAA6B;AAAA,EAC7C;AAAA,EAEQ,gCAAgC,OAAgC;AACtE,WAAO,MAAM,cAAc,iBACtB,MAAM,kBAAkB,UACxB,MAAM,4BAA4B,SAClC,wBAAgB,YAAK,KAAK,WAAW,mBAAmB,CAAC;AAAA,EAChE;AAAA,EAEA,MAAc,uCAAuC,QAAkD;AACrG,eAAW,SAAS,QAAQ;AAC1B,WAAK,OAAO,KAAK,wDAAwD;AAAA,QACvE,KAAK,MAAM;AAAA,QACX,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,YAAM,cAID,CAAC;AACN,iBAAW,SAAS,QAAQ;AAC1B,YAAI,KAAK,gCAAgC,KAAK,GAAG;AAC/C,gBAAM,IAAI;AAAA,YACR,wDAAwD,MAAM,KAAK;AAAA,UAErE;AAAA,QACF;AACA,YACE,MAAM,cAAc,WACjB,MAAM,kBAAkB,UACxB,MAAM,4BAA4B,GACrC;AACA,gBAAM,IAAI;AAAA,YACR,yDAAyD,MAAM,KAAK;AAAA,UAEtE;AAAA,QACF;AACA,YAAI,MAAM,kBAAkB,OAAW;AACvC,YAAI,CAAC,MAAM,eAAe,CAAC,MAAM,eAAe,MAAM,YAAY,WAAW,GAAG;AAC9E,gBAAM,IAAI;AAAA,YACR,yDAAyD,MAAM,KAAK;AAAA,UAEtE;AAAA,QACF;AACA,YAAI,CAAC,KAAK,yCAAyC,MAAM,aAAa,GAAG;AACvE,gBAAM,IAAI;AAAA,YACR,yDAAyD,MAAM,KAAK;AAAA,UAGtE;AAAA,QACF;AACA,oBAAY,KAAK;AAAA,UACf,aAAa,MAAM;AAAA,UACnB,aAAa,MAAM;AAAA,UACnB,uBAAuB,MAAM,cAAc;AAAA,QAC7C,CAAC;AAAA,MACH;AACA,UAAI,YAAY,SAAS,GAAG;AAI1B,aAAK,kBAAkB;AAAA,MACzB;AACA,iBAAW,EAAE,aAAa,aAAa,sBAAsB,KAAK,aAAa;AAK7E,aAAK,yBAAyB,aAAa,aAAa,qBAAqB;AAAA,MAC/E;AACA,YAAM,KAAK,oBAAoB;AAC/B,WAAK,OAAO;AAAA,QACV,YAAY,SAAS,IACjB,yDACA;AAAA,MACN;AACA;AAAA,IACF;AAEA,SAAK,OAAO,KAAK,oEAAoE;AAAA,EACvF;AAAA,EAEA,CAAS,8BAAgE;AACvE,QAAI,SAAS;AACb,UAAM,OAAO,CAAC,UAAyB;AACrC,UAAI,OAAQ;AACZ,eAAS;AACT,WAAK,OAAO,KAAK,iEAAiE;AAAA,QAChF,mBAAmB,KAAK;AAAA,QACxB,OAAOG,iBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA,IACH;AAEA,QAAI;AACF,iBAAW,UAAU,uBAAgC,KAAK,mBAAmB;AAAA,QAC3E,qBAAqB;AAAA,QACrB,iBAAiB,CAAC,UAAU,KAAK,KAAK;AAAA,MACxC,CAAC,GAAG;AACF,cAAM;AAAA,UACJ,QAAQ,OAAO;AAAA,UACf,OAAO,OAAO;AAAA,UACd,cAAc,OAAO;AAAA,UACrB,aAAa,OAAO;AAAA,QACtB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEQ,8BAAqD;AAC3D,WAAO;AAAA,MACL,QAAQ,wBAAiC,KAAK,iBAAiB;AAAA,MAC/D,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,uBACN,OACA,QACM;AACN,UAAM,OAAO,MAAM,MAAM;AACzB,UAAM,kBAAkB,OAAO,OAAO;AAAA,EACxC;AAAA,EAEQ,8BACN,OACA,mBAAwC,oBAAI,IAAI,GAC1C;AACN,QAAI,MAAM,iBAAiB,GAAG;AAK5B,YAAM,eAAe,oBAAI,IAAY;AACrC,YAAM,WAA8C,CAAC;AACrD,YAAM,UAAU,MAAM,KAAK,uBAAgC,MAAM,OAAO,aAAa,CAAC;AACtF,eAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,cAAM,SAAS,QAAQ,CAAC,EAAE,OAAO,OAAO,CAAC,aAAa;AACpD,gBAAM,UAAU,kBAAkB,QAAQ;AAC1C,cAAI,YAAY,MAAM;AACpB,gBAAI,iBAAiB,IAAI,OAAO,EAAG,QAAO;AAC1C,gBAAI,aAAa,IAAI,OAAO,EAAG,QAAO;AACtC,yBAAa,IAAI,OAAO;AAAA,UAC1B;AACA,iBAAO;AAAA,QACT,CAAC;AACD,YAAI,OAAO,SAAS,GAAG;AACrB,mBAAS,QAAQ,EAAE,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC;AAAA,QAC5C;AAAA,MACF;AACA,YAAM,OAAO,QAAQ;AACrB,UAAI,SAAS,SAAS,GAAG;AACvB,gCAAwB,KAAK,mBAAmB,QAAQ;AAAA,MAC1D,OAAO;AACL,gCAAwB,KAAK,mBAAmB,CAAC,CAAC;AAClD,aAAK,sBAAsB;AAAA,MAC7B;AACA;AAAA,IACF;AAEA,UAAM,OAAO,OAAO;AACpB,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEQ,4BAA4B,aAA6B;AAC/D,WAAO,KAAK;AAAA,MACV,KAAK,4BAA4B;AAAA,MACjC,KAAK,MAAM,cAAc,EAAE;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,mBACN,UACA,OACA,eACA,kBACA,uBACA,mBACA,oBACA,aACA,wBACM;AACN,QAAI,CAAC,KAAK,8BAA8B,GAAG;AACzC,WAAK,kBAAkB,sBAAsB;AAC7C,WAAK,qBAAqB,EAAE,YAAY,KAAK;AAAA,IAC/C;AACA,aAAS,uBAAuB;AAChC,aAAS,sBAAsB;AAK/B,SAAK,kBAAkB,aAAa;AACpC,UAAM,KAAK;AACX,QACE,iBAAiB,MAAM,iBAAiB,KACrC,iBAAiB,WAAW,OAAO,KACnC,iBAAiB,0BACpB;AAGA,iBAAW,YAAY,iBAAiB,WAAW,OAAO,GAAG;AAC3D,cAAM,sBAAsB,SAAS,OAAO,KAAK,CAAC,aAAa;AAC7D,gBAAM,UAAU,kBAAkB,QAAQ;AAC1C,iBAAO,YAAY,QAAQ,iBAAiB,qBAAqB,IAAI,OAAO;AAAA,QAC9E,CAAC;AACD,YAAI,oBAAqB;AACzB,aAAK,uBAAuB,iBAAiB,OAAO;AAAA,UAClD,QAAQ,SAAS;AAAA,UACjB,cAAc,SAAS;AAAA,UACvB,OAAO,SAAS;AAAA,UAChB,aAAa,SAAS;AAAA,QACxB,CAAC;AACD,mBAAW,YAAY,SAAS,QAAQ;AACtC,gBAAM,UAAU,kBAAkB,QAAQ;AAC1C,cAAI,YAAY,MAAM;AACpB,6BAAiB,qBAAqB,IAAI,OAAO;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AACA,WAAK,8BAA8B,iBAAiB,OAAO,qBAAqB;AAChF,uBAAiB,QAAQ,KAAK,4BAA4B;AAC1D,uBAAiB,2BAA2B;AAG5C,iBAAW,UAAU,KAAK,4BAA4B,GAAG;AACvD,mBAAW,YAAY,OAAO,QAAQ;AACpC,gBAAM,UAAU,kBAAkB,QAAQ;AAC1C,eAAK,uBAAuB,iBAAiB,OAAO,EAAE,GAAG,QAAQ,QAAQ,CAAC,QAAQ,EAAE,CAAC;AACrF,cAAI,YAAY,MAAM;AACpB,6BAAiB,qBAAqB,IAAI,OAAO;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,eAAW,YAAY,oBAAoB;AACzC,YAAM,OAAO,kBAAkB,IAAI,QAAQ;AAC3C,UAAI,SAAS,QAAW;AACtB,sBAAc,IAAI,UAAU,IAAI;AAAA,MAClC;AAAA,IACF;AACA,QAAI,aAAa;AACf,WAAK,2BAA2B,eAAe,WAAW;AAAA,IAC5D,OAAO;AACL,WAAK,gBAAgB;AACrB,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,wBAA8B;AACpC,YAAI,wBAAW,KAAK,iBAAiB,GAAG;AACtC,UAAI;AACF,oCAAW,KAAK,iBAAiB;AAAA,MACnC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,wBAAwB,cAAiD;AAC/E,UAAM,QAAQ,KAAK,4BAA4B;AAC/C,QAAI;AACF,iBAAW,SAAS,KAAK,4BAA4B,GAAG;AACtD,cAAM,iBAAiB,MAAM,OAAO,OAAO,YAAY;AACvD,YAAI,eAAe,SAAS,GAAG;AAC7B,eAAK,uBAAuB,OAAO,EAAE,GAAG,OAAO,QAAQ,eAAe,CAAC;AAAA,QACzE;AAAA,MACF;AACA,WAAK,8BAA8B,KAAK;AAAA,IAC1C,SAAS,OAAO;AACd,YAAM,OAAO,QAAQ;AACrB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,6BACN,OACA,eAC4B;AAC5B,UAAM,QAAQ,KAAK,4BAA4B;AAC/C,UAAM,aAAa,oBAAI,IAAuC;AAC9D,QAAI,2BAA2B;AAE/B,QAAI;AACF,iBAAW,SAAS,KAAK,4BAA4B,GAAG;AACtD,mBAAW,YAAY,MAAM,QAAQ;AACnC,gBAAM,WAAW,wBAAwB,QAAQ;AACjD,gBAAM,UAAU,UAAU,QAAS,aAAa,QAAQ,KAAK,qBAAqB,UAAU,KAAK;AACjG,cAAI,CAAC,SAAS;AACZ,iBAAK,uBAAuB,OAAO,EAAE,GAAG,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAC;AACnE;AAAA,UACF;AACA,cAAI,CAAC,cAAc,QAAQ,GAAG;AAC5B,uCAA2B;AAC3B;AAAA,UACF;AAEA,gBAAM,UAAU,kBAAkB,QAAQ;AAC1C,cAAI,CAAC,SAAS;AACZ,uCAA2B;AAC3B;AAAA,UACF;AACA,gBAAM,WAAW,WAAW,IAAI,OAAO;AACvC,cAAI,CAAC,YAAY,MAAM,gBAAgB,SAAS,cAAc;AAC5D,uBAAW,IAAI,SAAS;AAAA,cACtB,cAAc,MAAM;AAAA,cACpB,OAAO,MAAM;AAAA,cACb,aAAa,MAAM;AAAA,cACnB,QAAQ,CAAC,QAAQ;AAAA,YACnB,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,sBAAsB,oBAAI,IAAI;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,OAAO,QAAQ;AACrB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,CAAS,0BACP,YACA,OACA,eACA,gBACuC;AACvC,UAAM,UAAU,oBAAI,IAAY;AAChC,eAAW,SAAS,KAAK,4BAA4B,GAAG;AACtD,iBAAW,YAAY,MAAM,QAAQ;AACnC,cAAM,UAAU,kBAAkB,QAAQ;AAC1C,YAAI,CAAC,WAAW,QAAQ,IAAI,OAAO,GAAG;AACpC;AAAA,QACF;AACA,cAAM,SAAS,WAAW,IAAI,OAAO;AACrC,YACE,CAAC,UACD,OAAO,iBAAiB,MAAM,gBAC9B,OAAO,UAAU,MAAM,SACvB,OAAO,gBAAgB,MAAM,aAC7B;AACA;AAAA,QACF;AAEA,cAAM,WAAW,wBAAwB,QAAQ;AACjD,cAAM,UAAU,UAAU,QAAS,aAAa,QAAQ,KAAK,qBAAqB,UAAU,KAAK;AACjG,YAAI,CAAC,WAAW,CAAC,cAAc,QAAQ,GAAG;AACxC;AAAA,QACF;AAEA,cAAM,aAAa,qBAAqB,EAAE,GAAG,OAAO,QAAQ,CAAC,QAAQ,EAAE,GAAG,cAAc;AACxF,cAAM,QAAQ,YAAY,OAAO,CAAC;AAClC,YAAI,CAAC,OAAO;AACV;AAAA,QACF;AACA,gBAAQ,IAAI,OAAO;AACnB,cAAM;AAAA,UACJ;AAAA,UACA,cAAc,MAAM;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,wBAAwB,UAAoB,QAAuC;AACzF,UAAM,UAAuB,CAAC;AAC9B,eAAW,SAAS,QAAQ;AAC1B,UAAI,SAAS,SAAS,MAAM,EAAE,GAAG;AAC/B;AAAA,MACF;AACA,cAAQ,KAAK;AAAA,QACX,SAAS,MAAM;AAAA,QACf,aAAa,MAAM;AAAA,QACnB,UAAU,MAAM,SAAS;AAAA,QACzB,WAAW,MAAM,SAAS;AAAA,QAC1B,SAAS,MAAM,SAAS;AAAA,QACxB,UAAU,MAAM,SAAS;AAAA,QACzB,MAAM,MAAM,SAAS;AAAA,QACrB,UAAU,MAAM,SAAS;AAAA,QACzB,UAAU,MAAM,SAAS;AAAA,QACzB,aAAa,MAAM,SAAS;AAAA,QAC5B,kBAAkB,MAAM,SAAS;AAAA,QACjC,kBAAkB,MAAM,SAAS;AAAA,QACjC,cAAc,MAAM,SAAS;AAAA,MAC/B,CAAC;AAAA,IACH;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,eAAS,kBAAkB,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEQ,sBAAsB,UAK5B;AACA,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,EAAE,aAAa,GAAG,YAAY,KAAK,YAAY,KAAM,YAAY,IAAM;AAAA,MAChF,KAAK;AACH,eAAO,EAAE,aAAa,GAAG,YAAY,KAAK,YAAY,KAAM,YAAY,IAAM;AAAA,MAChF,KAAK;AACH,eAAO,EAAE,aAAa,GAAG,YAAY,GAAG,YAAY,KAAK,YAAY,IAAK;AAAA,MAC5E,KAAK,UAAU;AAIb,cAAM,eAAe,KAAK,OAAO;AACjC,eAAO;AAAA,UACL,aAAa,cAAc,eAAe;AAAA,UAC1C,YAAY,cAAc,qBAAqB;AAAA,UAC/C,YAAY;AAAA,UACZ,YAAY;AAAA,QACd;AAAA,MACF;AAAA,MACA;AACE,eAAO,EAAE,aAAa,GAAG,YAAY,KAAM,YAAY,KAAM,YAAY,IAAM;AAAA,IACnF;AAAA,EACF;AAAA,EAEA,MAAc,yBACZ,QACA,SAoBkC;AAClC,UAAM,SAAkC;AAAA,MACtC,eAAe;AAAA,MACf,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,gBAAgB,oBAAI,IAAY;AAAA,IAClC;AACA,QAAI,OAAO,WAAW,GAAG;AACvB,aAAO;AAAA,IACT;AAEA,UAAM,yBAAyC,CAAC;AAChD,QAAI,mBAAmB;AACvB,QAAI,QAAQ,yBAAyB,CAAC,QAAQ,cAAc;AAC1D,YAAM,gBAAgB,IAAI,IAAI,QAAQ,SAAS,qBAAqB,OAAO,IAAI,CAAC,UAAU,MAAM,WAAW,CAAC,CAAC;AAC7G,iBAAW,SAAS,QAAQ;AAC1B,YAAI,cAAc,IAAI,MAAM,WAAW,GAAG;AACxC,iCAAuB,KAAK,KAAK;AACjC;AAAA,QACF;AAEA,cAAM,kBAAkB,QAAQ,SAAS,aAAa,MAAM,WAAW;AACvE,YAAI,CAAC,iBAAiB;AACpB,iCAAuB,KAAK,KAAK;AACjC;AAAA,QACF;AAEA,gBAAQ,MAAM,IAAI,MAAM,IAAI,MAAM,KAAK,qBAAqB,eAAe,CAAC,GAAG,MAAM,QAAQ;AAC7F,gBAAQ,cAAc,YAAY,MAAM,EAAE;AAC1C,gBAAQ,cAAc,SAAS,MAAM,IAAI,MAAM,OAAO;AACtD,gBAAQ,cAAc,CAAC,KAAK,CAAC;AAC7B,eAAO,iBAAiB;AACxB,4BAAoB;AAAA,MACtB;AAAA,IACF,OAAO;AACL,6BAAuB,KAAK,GAAG,MAAM;AAAA,IACvC;AAEA,SAAK,OAAO,MAAM,QAAQ,0BAA0B;AAAA,MAClD,gBAAgB,uBAAuB;AAAA,MACvC,WAAW;AAAA,IACb,CAAC;AACD,QAAI,mBAAmB,GAAG;AACxB,WAAK,OAAO,sBAAsB,gBAAgB;AAClD,cAAQ,aAAa,MAAM;AAAA,IAC7B;AAEA,QAAI,uBAAuB,WAAW,GAAG;AACvC,aAAO;AAAA,IACT;AAEA,UAAM,oBAAoB,IAAI,IAAI,uBAAuB,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC1F,UAAM,wBAAwB,oBAAI,IAAyE;AAC3G,UAAM,4BAA4B,oBAAI,IAAsB;AAC5D,UAAM,oBAAoB,oBAAI,IAAY;AAC1C,UAAM,eAAe,uBAAuB,QAAQ,wBAAwB,KAAK,OAAO,WAAW,KAAK;AAKxG,QAAI,QAAQ,0BAA0B,QAAQ,uBAAuB,aAAa,UAAU;AAC1F,mBAAa,gBAAgB;AAAA,IAC/B;AACA,UAAM,iBAAiB,qCAAqC,wBAAwB,YAAY;AAChG,QAAI;AAEJ,eAAW,gBAAgB,gBAAgB;AACzC,YAAM,QAAQ,MAAM,eAAe,KAAK,IAAI,GAAG,QAAQ,mBAAmB,WAAW,CAAC;AACtF,YAAM,OAAO,QAAQ,MAAM,IAAI,YAAY;AACzC,YAAI,QAAQ,eAAe,YAAY,GAAG;AACxC,gBAAM,IAAI,QAAQ,CAAAC,cAAW,WAAWA,WAAS,QAAQ,eAAe,SAAS,CAAC;AAAA,QACpF;AAEA,YAAI;AACF,gBAAM,kBAAkB,MAAM;AAAA,YAC5B,YAAY;AACV,oBAAM,QAAQ,aAAa,IAAI,CAAC,YAAY,QAAQ,IAAI;AACxD,qBAAO,QAAQ,SAAS,WAAW,KAAK;AAAA,YAC1C;AAAA,YACA;AAAA,cACE,SAAS,KAAK,OAAO,SAAS;AAAA,cAC9B,YAAY,KAAK,IAAI,KAAK,OAAO,SAAS,cAAc,QAAQ,mBAAmB,UAAU;AAAA,cAC7F,YAAY,QAAQ,mBAAmB;AAAA,cACvC,QAAQ;AAAA,cACR,aAAa,CAAC,UAAU,EAAG,MAA4B,iBAAiB;AAAA,cACxE,iBAAiB,CAAC,UAAU;AAC1B,sBAAM,UAAUD,iBAAgB,KAAK;AACrC,oBAAI,iBAAiB,KAAK,GAAG;AAC3B,0BAAQ,eAAe,YAAY,KAAK;AAAA,oBACtC,QAAQ,mBAAmB;AAAA,qBAC1B,QAAQ,eAAe,aAAa,QAAQ,mBAAmB,cAAc;AAAA,kBAChF;AACA,uBAAK,OAAO,UAAU,QAAQ,6BAA6B;AAAA,oBACzD,SAAS,MAAM;AAAA,oBACf,aAAa,MAAM;AAAA,oBACnB,WAAW,QAAQ,eAAe;AAAA,kBACpC,CAAC;AAAA,gBACH,OAAO;AACL,uBAAK,OAAO,UAAU,SAAS,0BAA0B;AAAA,oBACvD,SAAS,MAAM;AAAA,oBACf,OAAO;AAAA,kBACT,CAAC;AAAA,gBACH;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,cAAI,QAAQ,eAAe,YAAY,GAAG;AACxC,oBAAQ,eAAe,YAAY,KAAK,IAAI,GAAG,QAAQ,eAAe,YAAY,GAAI;AAAA,UACxF;AAEA,gBAAM,kBAAkB,oBAAI,IAAY;AACxC,uBAAa,QAAQ,CAAC,SAAS,UAAU;AACvC,gBAAI,OAAO,eAAe,IAAI,QAAQ,MAAM,EAAE,KAAK,kBAAkB,IAAI,QAAQ,MAAM,EAAE,GAAG;AAC1F;AAAA,YACF;AAEA,kBAAM,SAAS,gBAAgB,WAAW,KAAK;AAC/C,gBAAI,CAAC,QAAQ;AACX,oBAAM,IAAI,MAAM,oDAAoD,QAAQ,MAAM,EAAE,EAAE;AAAA,YACxF;AAEA,kBAAM,QAAQ,sBAAsB,IAAI,QAAQ,MAAM,EAAE,KAAK,CAAC;AAC9D,kBAAM,QAAQ,SAAS,IAAI;AAAA,cACzB;AAAA,cACA,YAAY,QAAQ;AAAA,YACtB;AACA,kCAAsB,IAAI,QAAQ,MAAM,IAAI,KAAK;AACjD,4BAAgB,IAAI,QAAQ,MAAM,EAAE;AAAA,UACtC,CAAC;AAED,gBAAM,gBAAkE,CAAC;AACzE,qBAAW,WAAW,iBAAiB;AACrC,gBAAI,OAAO,eAAe,IAAI,OAAO,KAAK,kBAAkB,IAAI,OAAO,GAAG;AACxE;AAAA,YACF;AACA,kBAAM,QAAQ,kBAAkB,IAAI,OAAO;AAC3C,gBAAI,CAAC,OAAO;AACV;AAAA,YACF;AACA,kBAAM,QAAQ,sBAAsB,IAAI,MAAM,EAAE,KAAK,CAAC;AACtD,gBAAI,CAAC,qBAAqB,OAAO,MAAM,MAAM,MAAM,GAAG;AACpD;AAAA,YACF;AAEA,kBAAM,eAAe;AACrB,0BAAc,KAAK;AAAA,cACjB;AAAA,cACA,QAAQ;AAAA,gBACN,aAAa,IAAI,CAAC,SAAS,KAAK,MAAM;AAAA,gBACtC,aAAa,IAAI,CAAC,SAAS,KAAK,UAAU;AAAA,cAC5C;AAAA,YACF,CAAC;AAAA,UACH;AAEA,cAAI,cAAc,SAAS,GAAG;AAC5B,oBAAQ,SAAS,sBAAsB,cAAc,IAAI,CAAC,EAAE,OAAO,OAAO,OAAO;AAAA,cAC/E,aAAa,MAAM;AAAA,cACnB,WAAW,qBAAqB,MAAM;AAAA,cACtC,WAAW,MAAM;AAAA,cACjB,OAAO,QAAQ,uBAAuB,UAAU;AAAA,YAClD,EAAE,CAAC;AAEH,kBAAM,kBAAkB,cAAc,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK;AAC9D,uBAAW,EAAE,OAAO,OAAO,KAAK,eAAe;AAC7C,wCAA0B,IAAI,MAAM,IAAI,MAAM;AAAA,YAChD;AACA,uBAAW,SAAS,iBAAiB;AACnC,gCAAkB,IAAI,MAAM,EAAE;AAC9B,oCAAsB,OAAO,MAAM,EAAE;AAAA,YACvC;AAAA,UAEF;AAEA,iBAAO,cAAc,gBAAgB;AACrC,eAAK,OAAO,uBAAuB,gBAAgB,eAAe;AAClE,eAAK,OAAO,UAAU,SAAS,kBAAkB;AAAA,YAC/C,WAAW,cAAc;AAAA,YACzB,cAAc,aAAa;AAAA,YAC3B,QAAQ,gBAAgB;AAAA,UAC1B,CAAC;AAAA,QACH,SAAS,OAAO;AACd,gBAAM,eAAe,mCAAmC,YAAY,EACjE,OAAO,CAAC,UAAU,CAAC,kBAAkB,IAAI,MAAM,EAAE,CAAC,EAClD,OAAO,CAAC,UAAU,QAAQ,6BAA6B,CAAC,OAAO,eAAe,IAAI,MAAM,EAAE,CAAC;AAC9F,gBAAM,iBAAiBA,iBAAgB,KAAK;AAC5C,gBAAM,oBAAmB,oBAAI,KAAK,GAAE,YAAY;AAEhD,qBAAW,SAAS,cAAc;AAChC,gBAAI,CAAC,OAAO,eAAe,IAAI,MAAM,EAAE,GAAG;AACxC,qBAAO,eAAe,IAAI,MAAM,EAAE;AAClC,qBAAO,gBAAgB;AAAA,YACzB;AACA,kCAAsB,OAAO,MAAM,EAAE;AACrC,kBAAM,gBAAgB,QAAQ,cAAc,IAAI,MAAM,EAAE,KAAK,KAAK;AAClE,oBAAQ,cAAc,IAAI,MAAM,IAAI,YAAY;AAChD,iBAAK,uBAAuB,QAAQ,aAAa;AAAA,cAC/C,QAAQ,CAAC,KAAK;AAAA,cACd,OAAO;AAAA,cACP;AAAA,cACA,aAAa;AAAA,YACf,CAAC;AAAA,UACH;AAEA,eAAK,OAAO,qBAAqB;AACjC,eAAK,OAAO,UAAU,SAAS,uCAAuC;AAAA,YACpE,WAAW,aAAa;AAAA,YACxB,cAAc,aAAa;AAAA,YAC3B,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAEA,gBAAQ,aAAa,MAAM;AAAA,MAC7B,CAAC;AACD,WAAK,KAAK,MAAM,CAAC,UAAmB;AAClC,uBAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,MAAM,OAAO;AAC3B,QAAI,eAAe,QAAW;AAC5B,YAAM;AAAA,IACR;AAEA,UAAM,yBAAyB,uBAAuB,OAAO,CAAC,UAAU,0BAA0B,IAAI,MAAM,EAAE,CAAC;AAC/G,QAAI,uBAAuB,SAAS,GAAG;AACrC,UAAI;AACF,gBAAQ,MAAM,SAAS,uBAAuB,IAAI,CAAC,WAAW;AAAA,UAC5D,IAAI,MAAM;AAAA,UACV,QAAQ,0BAA0B,IAAI,MAAM,EAAE;AAAA,UAC9C,UAAU,MAAM;AAAA,QAClB,EAAE,CAAC;AACH,mBAAW,SAAS,wBAAwB;AAC1C,kBAAQ,cAAc,YAAY,MAAM,EAAE;AAC1C,kBAAQ,cAAc,SAAS,MAAM,IAAI,MAAM,OAAO;AAAA,QACxD;AACA,gBAAQ,cAAc,sBAAsB;AAC5C,eAAO,iBAAiB,uBAAuB;AAC/C,aAAK,OAAO,qBAAqB,uBAAuB,MAAM;AAAA,MAChE,SAAS,OAAO;AACd,cAAM,iBAAiBA,iBAAgB,KAAK;AAC5C,cAAM,oBAAmB,oBAAI,KAAK,GAAE,YAAY;AAChD,mBAAW,SAAS,wBAAwB;AAC1C,kBAAQ,MAAM,OAAO,MAAM,EAAE;AAC7B,kBAAQ,cAAc,YAAY,MAAM,EAAE;AAC1C,iBAAO,eAAe,IAAI,MAAM,EAAE;AAClC,iBAAO,gBAAgB;AACvB,gBAAM,gBAAgB,QAAQ,cAAc,IAAI,MAAM,EAAE,KAAK,KAAK;AAClE,kBAAQ,cAAc,IAAI,MAAM,IAAI,YAAY;AAChD,eAAK,uBAAuB,QAAQ,aAAa;AAAA,YAC/C,QAAQ,CAAC,KAAK;AAAA,YACd,OAAO;AAAA,YACP;AAAA,YACA,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AACA,aAAK,OAAO,qBAAqB;AACjC,aAAK,OAAO,UAAU,SAAS,qCAAqC;AAAA,UAClE,WAAW,uBAAuB;AAAA,UAClC,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AACA,cAAQ,aAAa,MAAM;AAAA,IAC7B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,wBACZ,OACA,YACA,SAI4B;AAC5B,UAAM,WAAW,KAAK,OAAO;AAC7B,QAAI,CAAC,YAAY,CAAC,SAAS,WAAW,WAAW,UAAU,GAAG;AAC5D,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,mBAAmB,KAAK;AAC5C,UAAM,oBAAoB,YAAY;AACtC,UAAM,YAAY,YAAY,YAAY;AAE1C,QAAI,SAAS,qBAAqB,MAAM;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,uBAAuB,QAAQ,qBAAqB,CAAC,WAAW;AAC3E,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,KAAK,IAAI,SAAS,MAAM,WAAW,MAAM;AACtD,UAAM,OAAO,WAAW,MAAM,GAAG,IAAI;AACrC,UAAM,OAAO,WAAW,MAAM,IAAI;AAClC,UAAM,UAAU,oBAAI,IAA2C;AAAA,MAC7D,CAAC,kBAAkB,CAAC,CAAC;AAAA,MACrB,CAAC,iBAAiB,CAAC,CAAC;AAAA,MACpB,CAAC,QAAQ,CAAC,CAAC;AAAA,MACX,CAAC,UAAU,CAAC,CAAC;AAAA,MACb,CAAC,SAAS,CAAC,CAAC;AAAA,IACd,CAAC;AAED,eAAW,aAAa,MAAM;AAC5B,YAAM,OAAO,2BAA2B,WAAW,WAAW;AAC9D,cAAQ,IAAI,IAAI,GAAG,KAAK,SAAS;AAAA,IACnC;AAEA,UAAM,eAAqC,oBACvC,CAAC,kBAAkB,SAAS,UAAU,iBAAiB,MAAM,IAC7D,YAAY,YAAY,SACtB,CAAC,iBAAiB,kBAAkB,UAAU,SAAS,MAAM,IAC7D,YAAY,YAAY,SACtB,CAAC,QAAQ,kBAAkB,SAAS,iBAAiB,QAAQ,IAC7D,YAAY,YAAY,WACtB,CAAC,UAAU,kBAAkB,SAAS,iBAAiB,MAAM,IAC7D,CAAC,kBAAkB,SAAS,UAAU,iBAAiB,MAAM;AAEvE,QAAI;AACF,YAAM,eAAkC,CAAC;AACzC,iBAAW,QAAQ,cAAc;AAC/B,cAAM,iBAAiB,QAAQ,IAAI,IAAI,KAAK,CAAC;AAC7C,YAAI,eAAe,UAAU,GAAG;AAC9B,uBAAa,KAAK,GAAG,cAAc;AACnC;AAAA,QACF;AAEA,cAAM,YAAY,MAAM,QAAQ;AAAA,UAC9B,eAAe,IAAI,OAAO,eAAe;AAAA,YACvC,IAAI,UAAU;AAAA,YACd,MAAM,MAAM,KAAK,2BAA2B,SAAS;AAAA,UACvD,EAAE;AAAA,QACJ;AACA,cAAM,YAAY,MAAM,KAAK,qBAAqB,OAAO,WAAW,QAAQ;AAC5E,YAAI,UAAU,WAAW,GAAG;AAC1B,uBAAa,KAAK,GAAG,cAAc;AACnC;AAAA,QACF;AAEA,cAAM,QAAQ,IAAI,IAAI,UAAU,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC;AAC/D,cAAM,eAAe,CAAC,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,MAAM;AACtD,gBAAM,QAAQ,MAAM,IAAI,EAAE,EAAE,KAAK,OAAO;AACxC,gBAAM,QAAQ,MAAM,IAAI,EAAE,EAAE,KAAK,OAAO;AACxC,cAAI,UAAU,OAAO;AACnB,mBAAO,QAAQ;AAAA,UACjB;AACA,cAAI,EAAE,UAAU,EAAE,OAAO;AACvB,mBAAO,EAAE,QAAQ,EAAE;AAAA,UACrB;AACA,iBAAO,EAAE,GAAG,cAAc,EAAE,EAAE;AAAA,QAChC,CAAC;AACD,cAAM,sBAAsB,CAAC,SAAS;AACtC,qBAAa,KAAK,GAAG,0BAA0B,cAAc,mBAAmB,CAAC;AAAA,MACnF;AAEA,WAAK,OAAO,OAAO,SAAS,6BAA6B;AAAA,QACvD,UAAU,SAAS;AAAA,QACnB,OAAO,SAAS;AAAA,QAChB,gBAAgB,KAAK;AAAA,QACrB,OAAO;AAAA,MACT,CAAC;AAED,aAAO,CAAC,GAAG,cAAc,GAAG,IAAI;AAAA,IAClC,SAAS,OAAO;AACd,WAAK,OAAO,OAAO,QAAQ,uDAAuD;AAAA,QAChF,UAAU,SAAS;AAAA,QACnB,OAAO,SAAS;AAAA,QAChB,OAAOA,iBAAgB,KAAK;AAAA,MAC9B,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,qBACZ,OACA,WACA,UACmB;AACnB,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,IAClB;AACA,QAAI,SAAS,QAAQ;AACnB,cAAQ,gBAAgB,UAAU,SAAS,MAAM;AAAA,IACnD;AAEA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS,SAAS;AACvE,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,SAAS,OAAO,WAAW;AAAA,QACzD,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,SAAS;AAAA,UAChB;AAAA,UACA,WAAW,UAAU,IAAI,CAAC,aAAa,SAAS,IAAI;AAAA,UACpD,OAAO,UAAU;AAAA,UACjB,kBAAkB;AAAA,QACpB,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,MACrF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,UAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,GAAG;AAChC,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE;AAEA,aAAO,KAAK,QACT,IAAI,CAAC,WAAW;AACf,cAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,eAAO,UAAU,KAAK,GAAG;AAAA,MAC3B,CAAC,EACA,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ;AAAA,IACxD,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,cAAM,IAAI,MAAM,oCAAoC,SAAS,SAAS,IAAI;AAAA,MAC5E;AACA,YAAM;AAAA,IACR,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAc,2BAA2B,WAA6C;AACpF,UAAM,QAAQ;AAAA,MACZ,SAAS,UAAU,SAAS,QAAQ;AAAA,MACpC,eAAe,UAAU,SAAS,SAAS;AAAA,MAC3C,aAAa,UAAU,SAAS,QAAQ;AAAA,MACxC,UAAU,UAAU,SAAS,SAAS,IAAI,UAAU,SAAS,OAAO;AAAA,IACtE;AAEA,QAAI,UAAU,SAAS,MAAM;AAC3B,YAAM,KAAK,SAAS,UAAU,SAAS,IAAI,EAAE;AAAA,IAC/C;AAEA,UAAM,SAASF,4BAA2B,UAAU,SAAS,QAAQ,IAAI,mBAAmB;AAC5F,UAAM,KAAK,gBAAgB,MAAM,EAAE;AAEnC,QAAI;AACF,YAAM,cAAc,MAAM,YAAAI,SAAW;AAAA,QACnC,KAAK,uBAAuB,UAAU,SAAS,QAAQ;AAAA,QACvD;AAAA,MACF;AACA,YAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,YAAM,mBAAmB,KAAK,IAAI,GAAG,UAAU,SAAS,SAAS;AACjE,YAAM,iBAAiB,KAAK,IAAI,MAAM,QAAQ,UAAU,SAAS,OAAO;AACxE,YAAM,UAAU,MAAM,MAAM,mBAAmB,GAAG,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK;AAClF,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,QAAQ,SAAS,IAAI,UAAU,SAAS;AAAA,IACrD,QAAQ;AACN,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,eAAe;AAAA,IAC5B;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,aAA4B;AAChC,QAAI,KAAK,uBAAuB;AAC9B,YAAM,KAAK;AAAA,IACb;AACA,QAAI,KAAK,iBAAiB,QAAQ,GAAG;AACnC;AAAA,IACF;AACA,UAAM,KAAK,eAAe,UAAU,CAAC,GAAG,EAAE,YAAY,KAAK,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAc,eACZ,MACA,iBACA,SACe;AACf,QAAI,KAAK,uBAAuB;AAC9B,YAAM,KAAK;AACX,UAAI,KAAK,iBAAiB,IAAI,GAAG;AAC/B;AAAA,MACF;AACA,aAAO,KAAK,eAAe,MAAM,iBAAiB,OAAO;AAAA,IAC3D;AAEA,QAAI,KAAK,iBAAiB,IAAI,GAAG;AAC/B;AAAA,IACF;AAEA,UAAM,iBAAiB,KAAK,mBAAmB,MAAM,iBAAiB,OAAO,EAC1E,MAAM,CAAC,UAAU;AAChB,WAAK,sBAAsB;AAC3B,YAAM;AAAA,IACR,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,KAAK,0BAA0B,gBAAgB;AACjD,aAAK,wBAAwB;AAAA,MAC/B;AAAA,IACF,CAAC;AACH,SAAK,wBAAwB;AAC7B,UAAM;AAAA,EACR;AAAA,EAEQ,iBAAiB,MAAoD;AAC3E,UAAM,WAAW;AAAA,MACf,KAAK,SACL,KAAK,YACL,KAAK,iBACL,KAAK,0BACL,KAAK;AAAA,IACP;AACA,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AACA,WAAO,SAAS,WACZ,KAAK,uBAAuB,SAC5B,KAAK,uBAAuB;AAAA,EAClC;AAAA,EAEQ,gBACN,WACA,SACA,OACM;AACN,SAAK,WAAW,KAAK,KAAK,gBAAgB,WAAW,OAAO,CAAC;AAC7D,SAAK,yBAAyB,IAAI,WAAW,KAAK,IAAI,IAAI,iCAAiC;AAC3F,SAAK,OAAO,KAAK,SAAS,UAAU,SAAY,SAAY,EAAE,OAAOF,iBAAgB,KAAK,EAAE,CAAC;AAAA,EAC/F;AAAA,EAEQ,gBACN,WACA,SACgB;AAChB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,cAAc;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,4BAAoC;AAC1C,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO;AAAA,IACT;AACA,QAAI,CAAC,KAAK,wBAAwB,GAAG;AACnC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,6BAAqC;AAC3C,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO;AAAA,IACT;AACA,QAAI,CAAC,KAAK,wBAAwB,GAAG;AACnC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,8BAAsC;AAC5C,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO;AAAA,IACT;AACA,QAAI,CAAC,KAAK,wBAAwB,GAAG;AACnC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,yBAAyB,UAAkB,eAAe,OAAe;AAC/E,QAAI;AACF,YAAM,YAAQ,sBAAS,QAAQ;AAC/B,UAAI,cAAc;AAChB,eAAO,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG;AAAA,MAClC;AACA,aAAO,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO;AAAA,IAClF,SAAS,OAAO;AACd,aAAO,eAAeA,iBAAgB,KAAK,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EAEQ,mCAA8D;AACpE,UAAM,YAAiB,YAAK,KAAK,WAAW,SAAS;AACrD,WAAO;AAAA,MACL,SAAS,GAAG,KAAK,yBAAyB,SAAS,CAAC,IAAI,KAAK,yBAAyB,GAAG,SAAS,YAAY,CAAC;AAAA,MAC/G,SAAS,KAAK,yBAA8B,YAAK,KAAK,WAAW,qBAAqB,CAAC;AAAA,MACvF,UAAU,KAAK,yBAA8B,YAAK,KAAK,WAAW,aAAa,CAAC;AAAA,MAChF,kBAAkB,KAAK,yBAA8B,YAAK,KAAK,WAAW,aAAa,GAAG,IAAI;AAAA,IAChG;AAAA,EACF;AAAA,EAEQ,yBAA+B;AACrC,QAAI,KAAK,uBAAuB,YAAY,CAAC,KAAK,wBAAwB;AACxE;AAAA,IACF;AAEA,UAAM,sBAAsB,KAAK;AACjC,UAAM,qBAAqB,KAAK,iCAAiC;AACjE,UAAM,SAAS,IAAI,IAAI,KAAK,WAAW,IAAI,CAAC,UAAU,CAAC,MAAM,WAAW,KAAK,CAAC,CAAC;AAC/E,UAAM,WAAW,CAAC,cAChB,OAAO,IAAI,SAAS,KAAK,KAAK,IAAI,MAAM,KAAK,yBAAyB,IAAI,SAAS,KAAK;AAC1F,UAAM,iBAAiB,CAAC,uBAAuB,mBAAmB,YAAY,oBAAoB;AAClG,UAAM,iBAAiB,CAAC,uBAAuB,mBAAmB,YAAY,oBAAoB;AAClG,UAAM,kBAAkB,CAAC,uBAAuB,mBAAmB,aAAa,oBAAoB;AACpG,UAAM,mBAAmB,CAAC,uBAAuB,mBAAmB,qBAAqB,oBAAoB;AAC7G,QACE,uBACA,CAAC,kBACD,CAAC,kBACD,CAAC,mBACD,CAAC,MAAM,KAAK,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,GACxC;AACA;AAAA,IACF;AAEA,UAAM,WAAW,CACf,WACA,SACA,UACS;AACT,UAAI,CAAC,OAAO,IAAI,SAAS,GAAG;AAC1B,aAAK,OAAO,KAAK,SAAS,UAAU,SAAY,SAAY,EAAE,OAAOA,iBAAgB,KAAK,EAAE,CAAC;AAAA,MAC/F;AACA,aAAO,IAAI,WAAW,KAAK,gBAAgB,WAAW,OAAO,CAAC;AAC9D,WAAK,yBAAyB,IAAI,WAAW,KAAK,IAAI,IAAI,iCAAiC;AAAA,IAC7F;AAEA,UAAM,YAAiB,YAAK,KAAK,WAAW,SAAS;AACrD,UAAM,qBAAqB,GAAG,SAAS;AACvC,UAAM,oBAAyB,YAAK,KAAK,WAAW,qBAAqB;AACzE,UAAM,SAAc,YAAK,KAAK,WAAW,aAAa;AAEtD,QACE,kBACA,SAAS,SAAS,GAClB;AACA,YAAM,wBAAoB,wBAAW,SAAS;AAC9C,YAAM,2BAAuB,wBAAW,kBAAkB;AAC1D,UAAI,qBAAqB,sBAAsB;AAC7C,YAAI;AACF,gBAAM,QAAQ,IAAI,YAAY,WAAW,KAAK,uBAAuB,UAAU,UAAU;AACzF,gBAAM,WAAW;AACjB,eAAK,QAAQ;AACb,iBAAO,OAAO,SAAS;AACvB,eAAK,yBAAyB,OAAO,SAAS;AAAA,QAChD,SAAS,OAAO;AACd,mBAAS,WAAW,KAAK,0BAA0B,GAAG,KAAK;AAAA,QAC7D;AAAA,MACF,WAAW,sBAAsB,wBAAwB,OAAO,IAAI,SAAS,GAAG;AAC9E,iBAAS,WAAW,KAAK,0BAA0B,CAAC;AAAA,MACtD;AAAA,IACF;AAEA,QACE,kBACA,SAAS,SAAS,KACjB,KAAC,wBAAW,iBAAiB,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK,GAChE;AACA,cAAI,wBAAW,iBAAiB,GAAG;AACjC,YAAI;AACF,gBAAM,gBAAgB,IAAI,cAAc,iBAAiB;AACzD,wBAAc,KAAK;AACnB,eAAK,gBAAgB;AACrB,iBAAO,OAAO,SAAS;AACvB,eAAK,yBAAyB,OAAO,SAAS;AAAA,QAChD,SAAS,OAAO;AACd,mBAAS,WAAW,KAAK,2BAA2B,GAAG,KAAK;AAAA,QAC9D;AAAA,MACF,YAAY,KAAK,OAAO,MAAM,KAAK,KAAK,KAAK,OAAO,IAAI,SAAS,GAAG;AAClE,iBAAS,WAAW,KAAK,2BAA2B,CAAC;AAAA,MACvD;AAAA,IACF;AAEA,QACE,oBACC,mBAAmB,OAAO,IAAI,UAAU,KACzC,SAAS,UAAU,GACnB;AACA,cAAI,wBAAW,MAAM,GAAG;AACtB,YAAI;AACF,gBAAM,WAAW,SAAS,aAAa,MAAM;AAC7C,cAAI,KAAK,UAAU;AACjB,iBAAK,iBAAiB,KAAK,KAAK,QAAQ;AAAA,UAC1C;AACA,eAAK,WAAW;AAChB,iBAAO,OAAO,UAAU;AACxB,eAAK,yBAAyB,OAAO,UAAU;AAAA,QACjD,SAAS,OAAO;AACd,mBAAS,YAAY,KAAK,4BAA4B,GAAG,KAAK;AAAA,QAChE;AAAA,MACF,YAAY,KAAK,OAAO,MAAM,KAAK,KAAK,KAAK,OAAO,IAAI,UAAU,GAAG;AACnE,iBAAS,YAAY,KAAK,4BAA4B,CAAC;AAAA,MACzD;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,IAAI,UAAU,GAAG;AAC3B,UAAI;AACF,aAAK,qBAAqB,KAAK,2BAA2B,KAAK,sBAAsB;AAAA,MACvF,SAAS,OAAO;AACd,iBAAS,YAAY,KAAK,4BAA4B,GAAG,KAAK;AAAA,MAChE;AAAA,IACF;AAEA,SAAK,aAAa,MAAM,KAAK,OAAO,OAAO,CAAC;AAC5C,SAAK,4BAA4B;AAAA,EACnC;AAAA,EAEQ,iCAA0C;AAChD,QAAI,KAAK,uBAAuB,YAAY,KAAK,kBAAkB;AACjE,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,KAAK;AACjC,UAAM,qBAAqB,KAAK,iCAAiC;AACjE,UAAM,WAAW,KAAK,WAAW;AAAA,MAAK,CAAC,UACrC,KAAK,IAAI,MAAM,KAAK,yBAAyB,IAAI,MAAM,SAAS,KAAK;AAAA,IACvE;AACA,UAAM,mBAAmB,CAAC,uBACxB,mBAAmB,YAAY,oBAAoB,WACnD,mBAAmB,YAAY,oBAAoB,WACnD,mBAAmB,aAAa,oBAAoB,YACpD,mBAAmB,qBAAqB,oBAAoB;AAC9D,QAAI,CAAC,oBAAoB,CAAC,UAAU;AAClC,aAAO;AAAA,IACT;AACA,QACE,CAAC,uBACD,mBAAmB,qBAAqB,oBAAoB,kBAC5D;AACA,aAAO;AAAA,IACT;AAEA,SAAK,qBAAqB;AAC1B,SAAK,4BAA4B;AACjC,QAAI;AACF,WAAK,uBAAuB;AAC5B,WAAK,4BAA4B,KAAK,6BAA6B;AAAA,IACrE,UAAE;AACA,WAAK,4BAA4B;AACjC,WAAK,qBAAqB;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,mBACZ,MACA,kBAA6C,CAAC,GAC9C,UAAoC,CAAC,GACtB;AACf,QAAI,SAAS,UAAU;AACrB,WAAK,mBAAmB;AAAA,IAC1B;AACA,SAAK,aAAa,CAAC;AACnB,SAAK,yBAAyB,MAAM;AAEpC,QAAI,KAAK,OAAO,sBAAsB,UAAU;AAC9C,UAAI,CAAC,KAAK,OAAO,gBAAgB;AAC/B,cAAM,IAAI,MAAM,qEAAqE;AAAA,MACvF;AACA,WAAK,yBAAyB,yBAAyB,KAAK,OAAO,cAAc;AAAA,IACnF,WAAW,KAAK,OAAO,sBAAsB,QAAQ;AACnD,WAAK,yBAAyB,MAAM,kBAAkB;AAAA,IACxD,OAAO;AACL,WAAK,yBAAyB,MAAM,wBAAwB,KAAK,OAAO,mBAAmB,KAAK,OAAO,cAAc;AAAA,IACvH;AAEA,QAAI,CAAC,KAAK,wBAAwB;AAChC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,OAAO,KAAK,wBAAwB;AAAA,MACvC,UAAU,KAAK,uBAAuB;AAAA,MACtC,OAAO,KAAK,uBAAuB,UAAU;AAAA,MAC7C,OAAO,KAAK,OAAO;AAAA,MACnB,iBAAiB,KAAK,OAAO,UAAU,WAAW;AAAA,IACpD,CAAC;AAED,SAAK,WAAW,wBAAwB,KAAK,sBAAsB;AAEnE,UAAM,aAAa,KAAK,uBAAuB,UAAU;AACzD,UAAM,YAAiB,YAAK,KAAK,WAAW,SAAS;AACrD,UAAM,qBAAqB,GAAG,SAAS;AACvC,UAAM,oBAAyB,YAAK,KAAK,WAAW,qBAAqB;AACzE,UAAM,SAAc,YAAK,KAAK,WAAW,aAAa;AACtD,QAAI,UAAU,KAAC,wBAAW,MAAM;AAChC,UAAM,4BAA4B,SAAS,WACvC,KAAK,iCAAiC,IACtC;AAEJ,QAAI,SAAS,UAAU;AACrB,YAAM,YAAAE,SAAW,MAAM,KAAK,WAAW,EAAE,WAAW,KAAK,CAAC;AAG1D,UAAI,gBAAgB,SAAS,KAAK,KAAK,OAAO,UAAU,aAAa,CAAC,KAAK,wBAAwB,GAAG;AACpG,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AACA,iBAAW,kBAAkB,iBAAiB;AAC5C,8BAAsB,KAAK,WAAW,gBAAgB;AAAA,UACpD;AAAA,UACA,GAAG,SAAS;AAAA,QACd,CAAC;AAAA,MACH;AACA,UAAI,gBAAgB,SAAS,KAAK,KAAK,OAAO,UAAU,WAAW;AACjE,cAAM,0BAA0B,gBAAgB;AAAA,UAC9C,CAAC,UAAU,KAAK,gCAAgC,KAAK;AAAA,QACvD;AACA,YAAI,yBAAyB;AAC3B,gBAAM,IAAI;AAAA,YACR,wDAAwD,wBAAwB,KAAK;AAAA,UAEvF;AAAA,QACF;AACA,cAAM,cAAc,gBAAgB;AAAA,UAClC,CAAC,UAAU,MAAM,kBAAkB,UAC7B,MAAM,cAAc,WAAW,MAAM,4BAA4B;AAAA,QACzE;AACA,YAAI,aAAa;AACf,gBAAM,KAAK,yBAAyB;AAAA,QACtC;AAAA,MACF;AAEA,WAAK,QAAQ,IAAI,YAAY,WAAW,UAAU;AAClD,cAAI,wBAAW,SAAS,SAAK,wBAAW,kBAAkB,GAAG;AAC3D,aAAK,MAAM,KAAK;AAAA,MAClB;AAEA,WAAK,gBAAgB,IAAI,cAAc,iBAAiB;AACxD,UAAI;AACF,aAAK,cAAc,KAAK;AAAA,MAC1B,QAAQ;AACN,gBAAI,wBAAW,iBAAiB,GAAG;AACjC,gBAAM,YAAAA,SAAW,OAAO,iBAAiB;AAAA,QAC3C;AACA,aAAK,gBAAgB,IAAI,cAAc,iBAAiB;AAAA,MAC1D;AAEA,UAAI;AACF,aAAK,WAAW,IAAI,SAAS,MAAM;AAAA,MACrC,SAAS,OAAO;AACd,YAAI,CAAE,MAAM,KAAK,uBAAuB,+BAA+B,KAAK,GAAI;AAC9E,gBAAM;AAAA,QACR;AAEA,aAAK,QAAQ,IAAI,YAAY,WAAW,UAAU;AAClD,aAAK,gBAAgB,IAAI,cAAc,iBAAiB;AACxD,aAAK,WAAW,IAAI,SAAS,MAAM;AACnC,kBAAU;AAAA,MACZ;AAAA,IACF,OAAO;AACL,WAAK,QAAQ,IAAI,YAAY,WAAW,UAAU;AAClD,YAAM,wBAAoB,wBAAW,SAAS;AAC9C,YAAM,2BAAuB,wBAAW,kBAAkB;AAC1D,YAAM,2BAA2B,KAAK,0BAA0B;AAChE,UAAI,sBAAsB,sBAAsB;AAC9C,aAAK,gBAAgB,WAAW,wBAAwB;AAAA,MAC1D,WAAW,mBAAmB;AAC5B,YAAI;AACF,eAAK,MAAM,WAAW;AAAA,QACxB,SAAS,OAAO;AACd,eAAK,gBAAgB,WAAW,0BAA0B,KAAK;AAC/D,eAAK,QAAQ,IAAI,YAAY,WAAW,UAAU;AAAA,QACpD;AAAA,MACF;AAEA,WAAK,gBAAgB,IAAI,cAAc,iBAAiB;AACxD,cAAI,wBAAW,iBAAiB,GAAG;AACjC,YAAI;AACF,eAAK,cAAc,KAAK;AAAA,QAC1B,SAAS,OAAO;AACd,eAAK;AAAA,YACH;AAAA,YACA,KAAK,2BAA2B;AAAA,YAChC;AAAA,UACF;AACA,eAAK,gBAAgB,IAAI,cAAc,iBAAiB;AAAA,QAC1D;AAAA,MACF,WAAW,KAAK,MAAM,MAAM,IAAI,GAAG;AACjC,aAAK,gBAAgB,WAAW,KAAK,2BAA2B,CAAC;AAAA,MACnE;AAEA,cAAI,wBAAW,MAAM,GAAG;AACtB,YAAI;AACF,eAAK,WAAW,SAAS,aAAa,MAAM;AAAA,QAC9C,SAAS,OAAO;AACd,eAAK;AAAA,YACH;AAAA,YACA,KAAK,4BAA4B;AAAA,YACjC;AAAA,UACF;AACA,eAAK,WAAW,SAAS,oBAAoB;AAAA,QAC/C;AAAA,MACF,OAAO;AACL,aAAK,WAAW,SAAS,oBAAoB;AAC7C,YAAI,KAAK,MAAM,MAAM,IAAI,GAAG;AAC1B,eAAK;AAAA,YACH;AAAA,YACA,wDAAwD,KAAK,4BAA4B,CAAC;AAAA,UAC5F;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU,KAAK,uBAAuB,GAAG;AAC3C,WAAK,gBAAgB,KAAK,sBAAsB,mBAAmB,KAAK,uBAAuB;AAC/F,WAAK,aAAa,cAAc,KAAK,uBAAuB;AAC5D,WAAK,OAAO,OAAO,QAAQ,2BAA2B;AAAA,QACpD,eAAe,KAAK;AAAA,QACpB,YAAY,KAAK;AAAA,MACnB,CAAC;AAAA,IACH,OAAO;AACL,WAAK,gBAAgB;AACrB,WAAK,aAAa;AAClB,WAAK,OAAO,OAAO,SAAS,4CAA4C;AAAA,IAC1E;AACA,SAAK,4BAA4B;AAEjC,QAAI,SAAS,YAAY,gBAAgB,SAAS,GAAG;AACnD,YAAM,KAAK,uCAAuC,eAAe;AAAA,IACnE;AAEA,QAAI,SAAS,YAAY,WAAW,KAAK,MAAM,MAAM,IAAI,GAAG;AAC1D,WAAK,uBAAuB;AAAA,IAC9B;AAEA,SAAK,kBAAkB;AAEvB,SAAK,qBAAqB,KAAK,2BAA2B,KAAK,sBAAsB;AACrF,QAAI,CAAC,KAAK,mBAAmB,YAAY;AACvC,WAAK,OAAO,KAAK,sCAAsC;AAAA,QACrD,QAAQ,KAAK,mBAAmB;AAAA,QAChC,gBAAgB,KAAK,mBAAmB;AAAA,QACxC,wBAAwB,KAAK;AAAA,MAC/B,CAAC;AAAA,IACH;AAEA,QAAI,SAAS,YAAY,KAAK,OAAO,SAAS,UAAU,CAAC,QAAQ,YAAY;AAC3E,YAAM,KAAK,eAAe;AAAA,IAC5B;AAEA,SAAK,qBAAqB;AAC1B,SAAK,4BAA4B;AAAA,EACnC;AAAA,EAEA,MAAc,iBAAgC;AAC5C,QAAI,CAAC,KAAK,SAAU;AAEpB,UAAM,kBAAkB,KAAK,SAAS,YAAY,iBAAiB;AACnE,UAAMC,OAAM,KAAK,IAAI;AACrB,UAAM,aAAa,KAAK,OAAO,SAAS,iBAAiB,KAAK,KAAK,KAAK;AAExE,QAAI,cAAc;AAClB,QAAI,CAAC,iBAAiB;AAEpB,oBAAc;AAAA,IAChB,OAAO;AACL,YAAM,aAAa,SAAS,iBAAiB,EAAE;AAC/C,UAAI,CAAC,MAAM,UAAU,KAAKA,OAAM,aAAa,YAAY;AACvD,sBAAc;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,aAAa;AACf,YAAM,SAAS,MAAM,KAAK,oBAAoB;AAC9C,UAAI,OAAO,SAAS;AAClB,aAAK,SAAS,YAAY,8BAA8B,OAAO,OAAO;AAAA,MACxE,OAAO;AACL,aAAK,SAAS,eAAe,4BAA4B;AAAA,MAC3D;AACA,WAAK,SAAS,YAAY,mBAAmBA,KAAI,SAAS,CAAC;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAc,mBAA8D;AAC1E,QAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,UAAM,QAAQ,KAAK,SAAS,SAAS;AACrC,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,cAAc,MAAM,iBAAiB,MAAM;AACjD,QAAI,cAAc,KAAK,OAAO,SAAS,mBAAmB;AACxD,UAAI;AACF,aAAK,SAAS,mBAAmB;AACjC,aAAK,SAAS,eAAe;AAAA,MAC/B,SAAS,OAAO;AACd,YAAI,MAAM,KAAK,uBAAuB,+CAA+C,KAAK,GAAG;AAC3F,iBAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,SAAS,KAAK,yBAA8B,YAAK,KAAK,WAAW,aAAa,CAAC;AAAA,UACjF;AAAA,QACF;AACA,cAAM;AAAA,MACR;AACA,WAAK,SAAS,YAAY,mBAAmB,KAAK,IAAI,EAAE,SAAS,CAAC;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,oCACN,OACA,UACA,kBACM;AACN,UAAM,cAAc,IAAI,IAAI,gBAAgB;AAC5C,QAAI,YAAY,SAAS,GAAG;AAC1B;AAAA,IACF;AAEA,UAAM,kBAAkB,MACrB,eAAe,EACf,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC;AAE5C,UAAM,gBAAqB,YAAK,KAAK,WAAW,SAAS;AACzD,UAAM,iBAAiB;AACvB,UAAM,oBAAoB,GAAG,aAAa;AAC1C,UAAM,QAAQ,KAAK,mBAAmB;AACtC,UAAM,kBAAkB,yBAAyB,gBAAgB,MAAM,OAAO,KAAK;AACnF,UAAM,qBAAqB,yBAAyB,mBAAmB,MAAM,OAAO,KAAK;AAEzF,QAAI,gBAAgB;AACpB,QAAI,mBAAmB;AACvB,QAAI,eAAe;AACnB,QAAI,eAAe;AAEnB,YAAI,wBAAW,eAAe,GAAG;AAC/B,kCAAW,eAAe;AAAA,IAC5B;AACA,YAAI,wBAAW,kBAAkB,GAAG;AAClC,kCAAW,kBAAkB;AAAA,IAC/B;AAEA,QAAI;AACF,cAAI,wBAAW,cAAc,GAAG;AAC9B,oCAAW,gBAAgB,eAAe;AAC1C,wBAAgB;AAAA,MAClB;AACA,cAAI,wBAAW,iBAAiB,GAAG;AACjC,oCAAW,mBAAmB,kBAAkB;AAChD,2BAAmB;AAAA,MACrB;AAEA,YAAM,MAAM;AAEZ,iBAAW,EAAE,KAAK,SAAS,KAAK,iBAAiB;AAC/C,cAAM,QAAQ,SAAS,SAAS,GAAG;AACnC,YAAI,CAAC,OAAO;AACV,0BAAgB;AAChB;AAAA,QACF;AAEA,cAAM,kBAAkB,SAAS,aAAa,MAAM,WAAW;AAC/D,YAAI,CAAC,iBAAiB;AACpB,0BAAgB;AAChB;AAAA,QACF;AAEA,cAAM,SAAS,qBAAqB,eAAe;AACnD,cAAM,IAAI,KAAK,MAAM,KAAK,MAAM,GAAG,QAAQ;AAC3C,wBAAgB;AAAA,MAClB;AAEA,YAAM,KAAK;AAEX,UAAI,qBAAiB,wBAAW,eAAe,GAAG;AAChD,oCAAW,eAAe;AAAA,MAC5B;AACA,UAAI,wBAAoB,wBAAW,kBAAkB,GAAG;AACtD,oCAAW,kBAAkB;AAAA,MAC/B;AAEA,WAAK,OAAO,GAAG,QAAQ,+CAA+C;AAAA,QACpE,gBAAgB,YAAY;AAAA,QAC5B,eAAe;AAAA,QACf,eAAe;AAAA,MACjB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI;AACF,cAAM,MAAM;AAAA,MACd,QAAQ;AAAA,MAER;AAEA,cAAI,wBAAW,cAAc,GAAG;AAC9B,oCAAW,cAAc;AAAA,MAC3B;AACA,cAAI,wBAAW,iBAAiB,GAAG;AACjC,oCAAW,iBAAiB;AAAA,MAC9B;AAEA,UAAI,qBAAiB,wBAAW,eAAe,GAAG;AAChD,oCAAW,iBAAiB,cAAc;AAAA,MAC5C;AACA,UAAI,wBAAoB,wBAAW,kBAAkB,GAAG;AACtD,oCAAW,oBAAoB,iBAAiB;AAAA,MAClD;AAEA,UAAI,iBAAiB,kBAAkB;AACrC,cAAM,KAAK;AAAA,MACb;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,yBAAyB,QAAwB;AACvD,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,aAAO,sDAAsD,MAAM;AAAA,IACrE;AAEA,WAAO,8CAA8C,MAAM;AAAA,EAC7D;AAAA,EAEA,MAAc,qCAAoD;AAChE,QAAI,KAAC,wBAAW,KAAK,SAAS,EAAG;AAEjC,UAAM,QAAQ,MAAM,YAAAD,SAAW,QAAQ,KAAK,SAAS;AACrD,UAAM,sBAAsB;AAC5B,UAAM,QAAQ;AAAA,MACZ,MACG,OAAO,CAAC,SAAS,oBAAoB,KAAK,IAAI,CAAC,EAC/C,IAAI,CAAC,SAAS,YAAAA,SAAW,GAAQ,YAAK,KAAK,WAAW,IAAI,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC;AAAA,IAClF;AAAA,EACF;AAAA,EAEA,MAAc,2BAA0C;AACtD,SAAK,QAAQ;AACb,SAAK,gBAAgB;AACrB,SAAK,UAAU,MAAM;AACrB,SAAK,WAAW;AAChB,SAAK,qBAAqB;AAC1B,SAAK,qBAAqB;AAC1B,SAAK,aAAa,CAAC;AACnB,SAAK,4BAA4B;AACjC,SAAK,4BAA4B;AACjC,SAAK,yBAAyB,MAAM;AACpC,SAAK,cAAc,MAAM;AAEzB,UAAM,aAAa;AAAA,MACZ,YAAK,KAAK,WAAW,aAAa;AAAA,MAClC,YAAK,KAAK,WAAW,iBAAiB;AAAA,MACtC,YAAK,KAAK,WAAW,iBAAiB;AAAA,MACtC,YAAK,KAAK,WAAW,SAAS;AAAA,MAC9B,YAAK,KAAK,WAAW,iBAAiB;AAAA,MACtC,YAAK,KAAK,WAAW,mBAAmB;AAAA,MACxC,YAAK,KAAK,WAAW,qBAAqB;AAAA,IACjD;AAEA,UAAM,QAAQ,IAAI,WAAW,IAAI,CAAC,eAAe,YAAAA,SAAW,GAAG,YAAY,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC,CAAC,CAAC;AAC7G,UAAM,KAAK,mCAAmC;AAC9C,UAAM,YAAAA,SAAW,MAAM,KAAK,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5D;AAAA,EAEA,MAAc,uBAAuB,OAAe,OAAkC;AACpF,QAAI,CAAC,wBAAwB,KAAK,GAAG;AACnC,aAAO;AAAA,IACT;AAEA,UAAM,SAAc,YAAK,KAAK,WAAW,aAAa;AACtD,UAAM,UAAU,KAAK,yBAAyB,MAAM;AACpD,UAAM,eAAeF,iBAAgB,KAAK;AAE1C,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,WAAK,OAAO,MAAM,mDAAmD;AAAA,QACnE;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AACD,YAAM,IAAI,MAAM,GAAG,OAAO,2BAA2B,YAAY,EAAE;AAAA,IACrE;AAEA,SAAK,OAAO,KAAK,kEAAkE;AAAA,MACjF;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAED,UAAM,KAAK,yBAAyB;AACpC,WAAO;AAAA,EACT;AAAA,EAEQ,yBAA+B;AACrC,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,SAAU;AAEnC,UAAM,cAAc,KAAK,MAAM,eAAe;AAC9C,UAAM,WAAqB,CAAC;AAC5B,UAAM,iBAA8B,CAAC;AAErC,eAAW,EAAE,KAAK,SAAS,KAAK,aAAa;AAC3C,YAAM,YAAuB;AAAA,QAC3B,SAAS;AAAA,QACT,aAAa,SAAS;AAAA,QACtB,UAAU,SAAS;AAAA,QACnB,WAAW,SAAS;AAAA,QACpB,SAAS,SAAS;AAAA,QAClB,UAAU,SAAS;AAAA,QACnB,MAAM,SAAS;AAAA,QACf,UAAU,SAAS;AAAA,MACrB;AACA,qBAAe,KAAK,SAAS;AAC7B,eAAS,KAAK,GAAG;AAAA,IACnB;AAEA,QAAI,eAAe,SAAS,GAAG;AAC7B,WAAK,SAAS,kBAAkB,cAAc;AAAA,IAChD;AACA,SAAK,SAAS,uBAAuB,KAAK,oBAAoB,GAAG,QAAQ;AAAA,EAC3E;AAAA,EAEQ,gCAAwC;AAC9C,WAAO,KAAK,OAAO,UAAU,YACzB,+BACA;AAAA,EACN;AAAA,EAEQ,qBAA8B;AACpC,UAAM,QAAQ,KAAK,UAAU,SAAS;AACtC,YAAQ,KAAK,OAAO,MAAM,KAAK,KAAK,MAC9B,OAAO,cAAc,KAAK,MAC1B,OAAO,eAAe,KAAK,KAC5B,KAAK,cAAc,OAAO;AAAA,EACjC;AAAA,EAEQ,oBAA0C;AAChD,QAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,UAAM,UAAU,KAAK,SAAS,YAAY,eAAe;AACzD,QAAI,CAAC,QAAS,QAAO;AAErB,WAAO;AAAA,MACL,cAAc;AAAA,MACd,oBAAoB,KAAK,SAAS,YAAY,0BAA0B,KAAK;AAAA,MAC7E,mBAAmB,KAAK,SAAS,YAAY,yBAAyB,KAAK;AAAA,MAC3E,gBAAgB,KAAK,SAAS,YAAY,sBAAsB,KAAK;AAAA,MACrE,qBAAqB,SAAS,KAAK,SAAS,YAAY,2BAA2B,KAAK,KAAK,EAAE;AAAA,MAC/F,0BAA0B,KAAK,mCAAmC,KAAK;AAAA,MACvE,WAAW,KAAK,SAAS,YAAY,iBAAiB,KAAK;AAAA,MAC3D,WAAW,KAAK,SAAS,YAAY,iBAAiB,KAAK;AAAA,IAC7D;AAAA,EACF;AAAA,EAEQ,kBAAkB,UAAwC;AAChE,QAAI,CAAC,KAAK,SAAU;AAEpB,UAAMG,QAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,oBAAoB,KAAK,SAAS,YAAY,iBAAiB;AACrE,UAAM,wCAAwC,CAAC,KAAK,8BAA8B;AAElF,SAAK,SAAS,YAAY,iBAAiB,sBAAsB;AACjE,SAAK,SAAS,YAAY,4BAA4B,KAAK,8BAA8B,CAAC;AAC1F,SAAK,SAAS,YAAY,2BAA2B,SAAS,QAAQ;AACtE,SAAK,SAAS,YAAY,wBAAwB,SAAS,UAAU,KAAK;AAC1E,SAAK,SAAS,YAAY,6BAA6B,SAAS,UAAU,WAAW,SAAS,CAAC;AAC/F,SAAK,SAAS,YAAY,KAAK,kCAAkC,GAAG,6BAA6B;AACjG,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,UAAI,uCAAuC;AACzC,aAAK,SAAS,YAAY,KAAK,uCAAuC,GAAG,0BAA0B;AAAA,MACrG;AACA,WAAK,SAAS,YAAY,KAAK,8BAA8B,GAAG,MAAM;AACtE,UAAI,uCAAuC;AACzC,aAAK,SAAS,eAAe,KAAK,kCAAkC,CAAC;AAAA,MACvE;AAAA,IACF,OAAO;AACL,WAAK,SAAS,YAAY,kCAAkC,0BAA0B;AAAA,IACxF;AACA,SAAK,SAAS,YAAY,mBAAmBA,IAAG;AAEhD,QAAI,CAAC,mBAAmB;AACtB,WAAK,SAAS,YAAY,mBAAmBA,IAAG;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,2BAA2B,UAAsD;AACvF,UAAM,iBAAiB,KAAK,kBAAkB;AAE9C,UAAM,2BAA2B,KAAK,UAAU,YAAY,0BAA0B,KACjF;AACL,UAAM,6BAA6B,KAAK,8BAA8B;AACtE,QAAI,KAAK,mBAAmB,KAAK,6BAA6B,4BAA4B;AACxF,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,QAAQ,6CAA6C,wBAAwB,iEAAiE,0BAA0B;AAAA,QACxK,gBAAgB,kBAAkB;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,CAAC,gBAAgB;AACnB,aAAO,EAAE,YAAY,KAAK;AAAA,IAC5B;AAEA,UAAM,kBAAkB,SAAS;AACjC,UAAM,eAAe,SAAS,UAAU;AACxC,UAAM,oBAAoB,SAAS,UAAU;AAE7C,QAAI,eAAe,wBAAwB,mBAAmB;AAC5D,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,QAAQ,iCAAiC,eAAe,mBAAmB,cAAc,eAAe,iBAAiB,IAAI,eAAe,cAAc,gCAAgC,iBAAiB,MAAM,eAAe,IAAI,YAAY;AAAA,QAChP;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe,mBAAmB,cAAc;AAClD,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,QAAQ,yCAAyC,eAAe,cAAc,4BAA4B,YAAY;AAAA,QACtH;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe,6BAA6B,4BAA4B;AAC1E,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,QAAQ,yEAAyE,eAAe,wBAAwB,oCAAoC,0BAA0B;AAAA,QACtL;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe,sBAAsB,iBAAiB;AACxD,WAAK,OAAO,KAAK,oBAAoB;AAAA,QACnC,gBAAgB,eAAe;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,qBAAyC;AACvC,QAAI,CAAC,KAAK,oBAAoB;AAC5B,UAAI,CAAC,KAAK,wBAAwB;AAChC,cAAM,IAAI,MAAM,oEAAoE;AAAA,MACtF;AAEA,WAAK,qBAAqB,KAAK,2BAA2B,KAAK,sBAAsB;AAAA,IACvF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,oBAQX;AACD,SAAK,kBAAkB;AACvB,QAAI,oBAAoB;AACxB,WAAO,MAAM;AACX,UAAI,KAAK,uBAAuB;AAC9B,cAAM,KAAK;AAAA,MACb;AACA,UAAI,CAAC,KAAK,iBAAiB,QAAQ,GAAG;AACpC,cAAM,KAAK,WAAW;AACtB,4BAAoB;AACpB;AAAA,MACF;AACA,UACE,KAAK,uBAAuB,YAC5B,CAAC,KAAK,oBACN,CAAC,mBACD;AACA,YAAI,CAAC,KAAK,+BAA+B,GAAG;AAC1C,eAAK,sBAAsB,IAAI;AAC/B,gBAAM,KAAK,WAAW;AACtB,8BAAoB;AACpB;AAAA,QACF;AAAA,MACF;AACA,UACE,KAAK,uBAAuB,YAC5B,CAAC,mBACD;AACA,aAAK,uBAAuB;AAAA,MAC9B;AACA,YAAM,QAAQ,KAAK,wBAAwB;AAC3C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY,CAAC,GAAG,KAAK,UAAU;AAAA,QAC/B,eAAe,KAAK,sBAAsB,KAAK,2BAA2B,MAAM,sBAAsB;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,0BAA0B,kBAA6C,CAAC,GAMnF;AACD,SAAK,mBAAmB;AAExB,QAAI,KAAK,uBAAuB;AAC9B,YAAM,KAAK;AAAA,IACb;AAEA,QAAI,gBAAgB,SAAS,KAAK,CAAC,KAAK,iBAAiB,QAAQ,GAAG;AAClE,YAAM,uBAAuB,KAAK,uBAAuB;AACzD,WAAK,sBAAsB,oBAAoB;AAC/C,YAAM,KAAK,eAAe,UAAU,iBAAiB,EAAE,YAAY,KAAK,CAAC;AAAA,IAC3E,OAAO;AACL,WAAK,wBAAwB;AAAA,IAC/B;AACA,QAAI,KAAK,OAAO,SAAS,QAAQ;AAC/B,YAAM,KAAK,eAAe;AAAA,IAC5B;AACA,WAAO,KAAK,wBAAwB;AAAA,EACtC;AAAA,EAEQ,0BACN,eACG,YACG;AACN,UAAM,eAAe,IAAI,IAAI,UAAU;AACvC,UAAM,SAAS,WAAW,OAAO,CAAC,UAAU,MAAM,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC;AAC/F,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,IAAI,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK,GAAG,CAAC;AAAA,IAChE;AAAA,EACF;AAAA,EAEQ,0BAMN;AACA,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,YAAY,CAAC,KAAK,iBAAiB,CAAC,KAAK,0BAA0B,CAAC,KAAK,UAAU;AAC1G,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,eAAe,KAAK;AAAA,MACpB,wBAAwB,KAAK;AAAA,MAC7B,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,eAAsC;AAC1C,UAAM,EAAE,uBAAuB,IAAI,MAAM,KAAK,kBAAkB;AAEhE,UAAM,kBAAkB,CAAC,GAAG,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,iBAAiB;AACjF,UAAM,EAAE,MAAM,IAAI,MAAM;AAAA,MACtB,KAAK;AAAA,MACL;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,SAAS;AAAA,MACrB,KAAK,8BAA8B;AAAA,MACnC,EAAE,UAAU,KAAK,OAAO,SAAS,UAAU,sBAAsB,KAAK,OAAO,SAAS,qBAAqB;AAAA,IAC7G;AAEA,WAAO,mBAAmB,OAAO,sBAAsB;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAsC;AAC1C,UAAM,EAAE,uBAAuB,IAAI,MAAM,KAAK,kBAAkB;AAChE,UAAM,iBAAiB,gCAAgC,sBAAsB;AAC7E,UAAM,kBAAkB,CAAC,GAAG,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,iBAAiB;AACjF,UAAM,EAAE,MAAM,IAAI,MAAM;AAAA,MACtB,KAAK;AAAA,MACL;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,SAAS;AAAA,MACrB,KAAK,8BAA8B;AAAA,MACnC,EAAE,UAAU,KAAK,OAAO,SAAS,UAAU,sBAAsB,KAAK,OAAO,SAAS,qBAAqB;AAAA,IAC7G;AAEA,QAAI,aAAa;AACjB,QAAI,cAAc;AAClB,QAAI,gBAAgB;AAMpB,eAAW,SAAS,0BAA0B,OAAO,CAAC,MAAM,EAAE,MAAM,KAAK,eAAe,GAAG;AACzF,YAAM,cAAc,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,MAAM;AAC3D,YAAI;AACF,iBAAO;AAAA,YACL,MAAM,KAAK,iBAAiB,EAAE,IAAI;AAAA,YAClC,SAAS,MAAM,YAAAD,SAAW,SAAS,EAAE,MAAM,OAAO;AAAA,UACpD;AAAA,QACF,QAAQ;AAEN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC,CAAC;AACF,YAAM,WAAW,YAAY;AAAA,QAC3B,CAAC,MAA8C,MAAM;AAAA,MACvD;AACA,oBAAc,SAAS;AACvB,YAAM,gBAAgB,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACtE,YAAM,cAAc,WAAW,UAAU,KAAK,OAAO,SAAS,aAAa;AAC3E,iBAAW,UAAU,aAAa;AAChC,YAAI,kBAAkB,OAAO;AAC7B,YACE,KAAK,OAAO,SAAS,6BACrB,gBAAgB,SAAS,KAAK,OAAO,SAAS,kBAC9C;AACA,gBAAM,UAAU,cAAc,IAAI,OAAO,IAAI;AAC7C,cAAI,YAAY,QAAW;AACzB,8BAAkB,gBAAgB,OAAO,MAAM,SAAS,KAAK,OAAO,SAAS,aAAa;AAAA,UAC5F;AAAA,QACF;AACA,0BAAkB;AAAA,UAChB;AAAA,UACA,KAAK,OAAO,SAAS;AAAA,UACrB,KAAK,OAAO,SAAS;AAAA,QACvB;AACA,mBAAW,SAAS,iBAAiB;AACnC,gBAAM,QAAQ,qBAAqB,OAAO,OAAO,MAAM,cAAc;AAGrE,yBAAe;AACf,qBAAW,QAAQ,OAAO;AACxB,6BAAiB,eAAe,IAAI;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,YAAY,aAAa,cAAc;AAAA,EAClD;AAAA,EAEA,MAAM,MAAM,YAAoD;AAC9D,WAAO,KAAK,uBAAuB,SAAS,OAAO,oBAAoB;AACrE,aAAO,KAAK,cAAc,YAAY,eAAe;AAAA,IACvD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,qBACJ,QACA,QACA,YAC4B;AAC5B,QAAI,CAAC,gBAAgB,MAAM,GAAG;AAC5B,YAAM,IAAI,MAAM,6BAA6B,KAAK,UAAU,MAAM,CAAC,EAAE;AAAA,IACvE;AACA,UAAM,mBAAmB,OAAO,YAAY;AAC5C,QAAI,KAAK,0BAA0B,qBAAqB,KAAK,wBAAwB;AACnF,YAAM,IAAI;AAAA,QACR,0BAA0B,gBAAgB,wCAAwC,KAAK,sBAAsB;AAAA,MAC/G;AAAA,IACF;AACA,QAAI,WAAW,KAAK,iBAAiB,KAAK,uBAAuB,QAAQ;AACvE,YAAM,IAAI;AAAA,QACR,8CAA8C,KAAK,UAAU,MAAM,CAAC,SAAS,KAAK,UAAU,KAAK,aAAa,CAAC;AAAA,MACjH;AAAA,IACF;AAEA,WAAO,KAAK,uBAAuB,SAAS,OAAO,oBAAoB;AACrE,YAAM,EAAE,SAAS,IAAI,MAAM,KAAK,0BAA0B,eAAe;AACzE,UAAI,WAAW,KAAK,eAAe;AACjC,cAAM,IAAI;AAAA,UACR,8CAA8C,KAAK,UAAU,MAAM,CAAC,SAAS,KAAK,UAAU,KAAK,aAAa,CAAC;AAAA,QACjH;AAAA,MACF;AACA,YAAM,YAAY,KAAK,oBAAoB;AAC3C,YAAM,iBAAiB,SAAS,kBAAkB,SAAS,EAAE,SAAS,KACjE,SAAS,mBAAmB,SAAS,EAAE,SAAS;AACrD,YAAM,oBAAoB,KAAK,kCAAkC,QAAQ;AACzE,UAAI,kBAAkB,qBAAqB,KAAK,sBAAsB,QAAQ,MAAM,kBAAkB;AACpG,eAAO,EAAE,UAAU,MAAM;AAAA,MAC3B;AAEA,YAAM,QAAQ,MAAM,KAAK,cAAc,YAAY,CAAC,GAAG,IAAI;AAC3D,aAAO,EAAE,UAAU,MAAM,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cACZ,YACA,kBAA6C,CAAC,GAC9C,aAAa,OACQ;AACrB,UAAM,EAAE,OAAO,UAAU,eAAe,UAAU,uBAAuB,IAAI,aACzE,KAAK,wBAAwB,IAC7B,MAAM,KAAK,0BAA0B,eAAe;AACxD,UAAM,qBAAqB,UAAU,KAAK,uBAAuB,IAC7D,MAAM,sBAAsB,KAAK,yBAAyB,MAAM,IAChE;AACJ,QAAI,KAAK,0BAA0B,uBAAuB,KAAK,wBAAwB;AACrF,YAAM,IAAI;AAAA,QACR,gCAAgC,sBAAsB,iBAAiB,cAAc,KAAK,sBAAsB;AAAA,MAClH;AAAA,IACF;AACA,UAAM,gBAAgB,KAAK,0BAA0B;AACrD,UAAM,cAAc,KAAK,OAAO,UAAU,WAAW,KAAK,eAAe,IAAI;AAC7E,UAAM,mBAAmB,KAAK,oBAAoB;AAClD,UAAM,yBAAyB,SAAS,kBAAkB,gBAAgB;AAC1E,UAAM,2BAA2B,IAAI,IAAI,sBAAsB;AAC/D,UAAM,0BAA0B,SAAS,mBAAmB,gBAAgB;AAC5E,UAAM,4BAA4B,IAAI,IAAI,uBAAuB;AACjE,UAAM,iCAAiC,KAAK,uBAAuB,UAC9D,uBAAuB,SAAS,KAChC,SAAS,eAAe,EAAE,SAAS;AACxC,UAAM,qBAAqB,gBAAgB,QAAQ,SAAS,YAAY,KAAK,kCAAkC,CAAC,MAAM;AACtH,UAAM,uBAAuB,oBAAI,IAAY;AAE7C,QAAI,CAAC,KAAK,oBAAoB,YAAY;AACxC,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,oBAAoB,MAAM;AAAA,MAEpC;AAAA,IACF;AAEA,SAAK,OAAO,oBAAoB;AAChC,SAAK,OAAO,KAAK,qBAAqB,EAAE,aAAa,KAAK,YAAY,CAAC;AAEvE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,QAAoB;AAAA,MACxB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,eAAe;AAAA,MACf,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc,CAAC;AAAA,MACf,eAAe,CAAC;AAAA,IAClB;AAEA,iBAAa;AAAA,MACX,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf,CAAC;AAED,SAAK,kBAAkB;AAEvB,UAAM,yBAAyB,KAAK,iCAAiC;AACrE,UAAM,0BAA0B,SAAS,YAAY,sBAAsB,MAAM;AACjF,UAAM,yBAAyB,KAAK,iCAAiC;AACrE,UAAM,0BAA0B,SAAS,YAAY,sBAAsB,MAAM;AACjF,UAAM,6BAA6B,KAAK,qCAAqC;AAC7E,UAAM,uBAAuB,SAAS,YAAY,0BAA0B,MAAM;AAClF,QACE,2BACA,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,CAAC,aAAkB,eAAQ,QAAQ,EAAE,YAAY,MAAM,QAAQ,GAC1G;AACA,WAAK,OAAO,KAAK,kDAAkD;AAAA,IACrE;AACA,QACE,2BACA,MAAM,KAAK,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,CAAC,aAAkB,eAAQ,QAAQ,EAAE,YAAY,MAAM,QAAQ,GAC1G;AACA,WAAK,OAAO,KAAK,kDAAkD;AAAA,IACrE;AAEA,UAAM,kBAAkB,CAAC,GAAG,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,iBAAiB;AACjF,UAAM,EAAE,OAAO,QAAQ,IAAI,MAAM;AAAA,MAC/B,KAAK;AAAA,MACL;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,SAAS;AAAA,MACrB,KAAK,8BAA8B;AAAA,MACnC,EAAE,UAAU,KAAK,OAAO,SAAS,UAAU,sBAAsB,KAAK,OAAO,SAAS,qBAAqB;AAAA,IAC7G;AAEA,UAAM,aAAa,MAAM;AACzB,UAAM,eAAe,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC3C,GAAG;AAAA,MACH,MAAM,KAAK,oBAAoB,MAAM,IAAI;AAAA,IAC3C,EAAE;AAEF,SAAK,OAAO,mBAAmB,MAAM,MAAM;AAC3C,SAAK,OAAO,MAAM,SAAS,8BAA8B;AAAA,MACvD,YAAY,MAAM;AAAA,MAClB,cAAc,QAAQ;AAAA,IACxB,CAAC;AAED,UAAM,yBAAkD,CAAC;AACzD,UAAM,qBAAqB,oBAAI,IAAY;AAC3C,UAAM,oBAAoB,oBAAI,IAAoB;AAClD,UAAM,oCACJ,SAAS,YAAY,KAAK,kCAAkC,CAAC,MAAM;AAErE,eAAW,QAAQ,OAAO;AACxB,YAAM,aAAa,KAAK,iBAAiB,KAAK,IAAI;AAClD,UAAI;AACJ,UAAI;AACF,sBAAc,SAAS,KAAK,IAAI;AAAA,MAClC,SAAS,OAAO;AAMd,cAAM,aAAa,KAAK,EAAE,MAAM,KAAK,oBAAoB,KAAK,IAAI,GAAG,QAAQ,aAAa,CAAC;AAC3F,aAAK,OAAO,KAAK,2CAA2C;AAAA,UAC1D,MAAM,KAAK;AAAA,UACX,OAAOF,iBAAgB,KAAK;AAAA,QAC9B,CAAC;AACD;AAAA,MACF;AACA,wBAAkB,IAAI,YAAY,WAAW;AAE7C,YAAM,oBAAoB,KAAK,cAAc,IAAI,UAAU,MAAM;AACjE,YAAM,wBAAwB,qBAC5B,qCACA,SAAS,gBAAgB,UAAU,EAAE;AAAA,QAAK,CAAC,UACzC,MAAM,aAAa,SAAS,MAAM,aAAa,OAAO,MAAM,aAAa;AAAA,MAC3E;AACF,YAAM,6BACJ,2BAAgC,eAAQ,UAAU,EAAE,YAAY,MAAM;AACxE,YAAM,6BACJ,2BAAgC,eAAQ,UAAU,EAAE,YAAY,MAAM;AACxE,YAAM,mBACJ,sBAAsB,gBAAgB,QAAQ,KAAK,qBAAqB,YAAY,WAAW;AAEjG,UACE,qBACA,CAAC,oBACD,CAAC,yBACD,CAAC,8BACD,CAAC,8BACD,CAAC,sBACD;AACA,2BAAmB,IAAI,UAAU;AACjC,aAAK,OAAO,eAAe;AAAA,MAC7B,OAAO;AACL,+BAAuB,KAAK;AAAA,UAC1B;AAAA,UACA,kBAAkB,KAAK;AAAA,UACvB,MAAM;AAAA,UACN,aAAa,KAAK;AAAA,QACpB,CAAC;AACD,aAAK,OAAO,gBAAgB;AAAA,MAC9B;AAAA,IACF;AAEA,SAAK,OAAO,MAAM,QAAQ,2BAA2B;AAAA,MACnD,WAAW,mBAAmB;AAAA,MAC9B,SAAS,uBAAuB;AAAA,IAClC,CAAC;AAED,iBAAa;AAAA,MACX,OAAO;AAAA,MACP,gBAAgB,mBAAmB;AAAA,MACnC,YAAY,MAAM;AAAA,MAClB,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf,CAAC;AAED,UAAM,iBAAiB,oBAAI,IAAoB;AAC/C,UAAM,uBAAuB,oBAAI,IAAyB;AAC1D,UAAM,uBAAuB,oBAAI,IAA2B;AAC5D,eAAW,EAAE,KAAK,SAAS,KAAK,MAAM,eAAe,GAAG;AACtD,UAAI,eAAe,CAAC,KAAK,qBAAqB,SAAS,UAAU,WAAW,GAAG;AAC7E;AAAA,MACF;AACA,UACE,kCACA,KAAK,oBAAoB,SAAS,QAAQ,KAC1C,CAAC,yBAAyB,IAAI,GAAG,GACjC;AACA;AAAA,MACF;AACA,UAAI,sBAAsB,eAAe,KAAK,qBAAqB,SAAS,UAAU,WAAW,GAAG;AAClG;AAAA,MACF;AACA,qBAAe,IAAI,KAAK,SAAS,IAAI;AACrC,2BAAqB,IAAI,KAAK,QAAQ;AACtC,YAAM,aAAa,qBAAqB,IAAI,SAAS,QAAQ,KAAK,oBAAI,IAAY;AAClF,iBAAW,IAAI,GAAG;AAClB,2BAAqB,IAAI,SAAS,UAAU,UAAU;AAAA,IACxD;AAEA,UAAM,kBAAkB,oBAAI,IAAY;AACxC,UAAM,eAAe,oBAAI,IAAY;AACrC,UAAM,iBAAiB,oBAAI,IAAY;AACvC,UAAM,kCAAkC,oBAAI,IAAY;AACxD,UAAM,kBAAkB,KAAK,OAAO,SAAS,SAAS,WAAW,UAAU,KAAK,uBAAuB;AACvG,QAAI,0BAA0B;AAE9B,eAAW,YAAY,oBAAoB;AACzC,YAAM,aAAa,qBAAqB,IAAI,QAAQ;AACpD,UAAI,YAAY;AACd,mBAAW,WAAW,YAAY;AAChC,0BAAgB,IAAI,OAAO;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAEA,UAAM,wBAAwB,CAAC,aAC7B,aAAa,QAAQ,kBAAkB,IAAI,QAAQ,KAAK,mBAAmB,IAAI,QAAQ;AACzF,UAAM,mBAAmB,KAAK,6BAA6B,aAAa,qBAAqB;AAC7F,UAAM,iBAAiB,gCAAgC,sBAAsB;AAC7E,UAAM,qBAAqB,KAAK,sBAAsB,uBAAuB,QAAQ;AACrF,UAAM,QAAQ,IAAI,OAAO;AAAA,MACvB,aAAa,mBAAmB;AAAA,MAChC,UAAU,mBAAmB;AAAA,MAC7B,aAAa,mBAAmB;AAAA,IAClC,CAAC;AACD,UAAM,iBAA0C,EAAE,WAAW,EAAE;AAC/D,QAAI,yBAAyB;AAE7B,QAAI;AACF,eAAS,sBAAsB;AAC/B,+BAAyB;AAEzB,YAAM,sBAAmC,CAAC;AAC1C,UAAI,iBAAiB;AACnB,cAAM,gBAAkF,CAAC;AACzF,mBAAW,WAAW,iBAAiB;AACrC,gBAAM,WAAW,qBAAqB,IAAI,OAAO;AACjD,cAAI,CAAC,YAAY,iBAAiB,QAAQ,GAAG;AAC3C;AAAA,UACF;AACA,gBAAM,QAAQ,SAAS,SAAS,OAAO;AACvC,cAAI,CAAC,OAAO;AACV;AAAA,UACF;AAEA,gBAAM,QAAQ,MAAM;AAAA,YAClB,KAAK;AAAA,YACL,KAAK,uBAAuB,MAAM,QAAQ;AAAA,YAC1C,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AACA,gBAAM,gBAAgB,kBAAkB,KAAK;AAC7C,cAAI,CAAC,cAAc,UAAU;AAC3B;AAAA,UACF;AAEA,8BAAoB,KAAK;AAAA,YACvB,GAAG;AAAA,YACH,UAAU,cAAc;AAAA,YACxB,aAAa,cAAc;AAAA,YAC3B,kBAAkB,cAAc;AAAA,YAChC,kBAAkB,cAAc;AAAA,YAChC,cAAc,cAAc;AAAA,UAC9B,CAAC;AACD,gBAAM,kBAAkB,SAAS,aAAa,MAAM,WAAW;AAC/D,cAAI,iBAAiB;AACnB,0BAAc,KAAK;AAAA,cACjB,IAAI;AAAA,cACJ,QAAQ,MAAM,KAAK,qBAAqB,eAAe,CAAC;AAAA,cACxD,UAAU,EAAE,GAAG,UAAU,GAAG,cAAc;AAAA,YAC5C,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,oBAAoB,SAAS,GAAG;AAClC,mBAAS,kBAAkB,mBAAmB;AAAA,QAChD;AACA,YAAI,cAAc,SAAS,GAAG;AAC5B,gBAAM,SAAS,aAAa;AAC5B,oCAA0B;AAAA,QAC5B;AAAA,MACF;AAEA,iBAAW,YAAY,oBAAoB;AACzC,mBAAW,UAAU,SAAS,iBAAiB,QAAQ,GAAG;AACxD,cAAI,CAAC,kCAAkC,0BAA0B,IAAI,OAAO,EAAE,GAAG;AAC/E,yBAAa,IAAI,OAAO,EAAE;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAEA,UAAI,wBAAwB;AAC5B,UAAI,uBAAuB;AAC3B,YAAM,qBAAqB,IAAI,IAAY,kBAAkB;AAC7D,YAAM,wBAAwB,oBAAI,IAAY;AAC9C,iBAAW,mBAAmB;AAAA,QAC5B;AAAA,QACA,CAAC,eAAe,WAAW;AAAA,QAC3B,KAAK;AAAA,MACP,GAAG;AACD,cAAM,cAAc,MAAM,QAAQ,IAAI,gBAAgB,IAAI,OAAO,gBAAgB;AAAA,UAC/E,MAAM,WAAW;AAAA,UACjB,SAAS,MAAM,YAAAE,SAAW,SAAS,WAAW,kBAAkB,OAAO;AAAA,UACvE,MAAM,WAAW;AAAA,QACnB,EAAE,CAAC;AACH,cAAM,eAAe,IAAI,IAAI,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;AACzE,cAAM,mBAAmB,IAAI,IAAI,gBAAgB,IAAI,CAAC,eAAe,CAAC,WAAW,YAAY,UAAU,CAAC,CAAC;AACzG,cAAM,iBAAiB,8BAAY,IAAI;AACvC,cAAM,cAAc,WAAW,aAAa,KAAK,OAAO,SAAS,aAAa;AAC9E,cAAM,UAAU,8BAAY,IAAI,IAAI;AACpC,aAAK,OAAO,kBAAkB,YAAY,MAAM;AAChD,aAAK,OAAO,oBAAoB,OAAO;AACvC,aAAK,OAAO,MAAM,6BAA6B;AAAA,UAC7C,aAAa,YAAY;AAAA,UACzB,SAAS,QAAQ,QAAQ,CAAC;AAAA,QAC5B,CAAC;AAED,cAAM,iBAA8B,CAAC;AACrC,cAAM,gBAAgC,CAAC;AACvC,cAAM,cAA4B,CAAC;AACnC,cAAM,YAA4B,CAAC;AAEnC,mBAAW,UAAU,aAAa;AAChC,gBAAM,aAAa,aAAa,IAAI,OAAO,IAAI;AAC/C,gBAAM,aAAa,iBAAiB,IAAI,OAAO,IAAI;AACnD,cAAI,CAAC,cAAc,CAAC,YAAY;AAC9B,kBAAM,IAAI,MAAM,oDAAoD,OAAO,IAAI,EAAE;AAAA,UACnF;AAEA,cAAI,OAAO,OAAO,WAAW,GAAG;AAC9B,kBAAM,cAAc,KAAU,kBAAW,OAAO,IAAI,IAC3C,gBAAS,KAAK,aAAa,OAAO,IAAI,IAC3C,OAAO,IAAI;AAAA,UACjB;AAEA,cAAI,kBAAkB,OAAO;AAC7B,cACE,KAAK,OAAO,SAAS,6BACrB,gBAAgB,SAAS,KAAK,OAAO,SAAS,kBAC9C;AACA,8BAAkB,gBAAgB,OAAO,MAAM,WAAW,SAAS,KAAK,OAAO,SAAS,aAAa;AAAA,UACvG;AACA,4BAAkB;AAAA,YAChB;AAAA,YACA,KAAK,OAAO,SAAS;AAAA,YACrB,KAAK,OAAO,SAAS;AAAA,UACvB;AAEA,qBAAW,SAAS,iBAAiB;AACnC,kBAAM,KAAK,KAAK,mBAAmB,gBAAgB,OAAO,MAAM,KAAK,CAAC;AACtE,kBAAM,cAAc,kBAAkB,KAAK;AAC3C,kBAAM,sBAAsB,eAAe,IAAI,EAAE;AACjD,kBAAM,gBAAgB,kBAAkB,SAAS,SAAS,EAAE,IAAI;AAChE,kBAAM,QAAQ,mBAAmB,wBAAwB,cACrD,MAAM;AAAA,cACJ,KAAK;AAAA,cACL,WAAW;AAAA,cACX,MAAM;AAAA,cACN,MAAM;AAAA,YACR,IACA,mBAAmB,aAAa;AACpC,kBAAM,gBAAgB,kBAAkB,KAAK;AAC7C,4BAAgB,IAAI,EAAE;AAEtB,2BAAe,KAAK;AAAA,cAClB,SAAS;AAAA,cACT;AAAA,cACA,UAAU,OAAO;AAAA,cACjB,WAAW,MAAM;AAAA,cACjB,SAAS,MAAM;AAAA,cACf,UAAU,MAAM;AAAA,cAChB,MAAM,MAAM;AAAA,cACZ,UAAU,MAAM;AAAA,cAChB,UAAU,cAAc;AAAA,cACxB,aAAa,cAAc;AAAA,cAC3B,kBAAkB,cAAc;AAAA,cAChC,kBAAkB,cAAc;AAAA,cAChC,cAAc,cAAc;AAAA,YAC9B,CAAC;AAED,gBAAI,wBAAwB,aAAa;AACvC;AAAA,YACF;AAEA,kBAAM,QAAQ,qBAAqB,OAAO,OAAO,MAAM,cAAc,EAAE,IAAI,CAAC,UAAU;AAAA,cACpF;AAAA,cACA,YAAY,eAAe,IAAI;AAAA,YACjC,EAAE;AACF,0BAAc,KAAK;AAAA,cACjB;AAAA,cACA;AAAA,cACA,aAAa,8BAA8B,KAAK;AAAA,cAChD,SAAS,MAAM;AAAA,cACf;AAAA,cACA,UAAU;AAAA,gBACR,UAAU,OAAO;AAAA,gBACjB,WAAW,MAAM;AAAA,gBACjB,SAAS,MAAM;AAAA,gBACf,WAAW,MAAM;AAAA,gBACjB,MAAM,MAAM;AAAA,gBACZ,UAAU,MAAM;AAAA,gBAChB,MAAM;AAAA,gBACN,GAAG;AAAA,cACL;AAAA,YACF,CAAC;AAAA,UACH;AAEA,gBAAM,cAA4B,CAAC;AACnC,qBAAW,gBAAgB,OAAO,SAAS;AACzC,gBAAI,CAAC,8BAA8B,IAAI,aAAa,IAAI,GAAG;AACzD;AAAA,YACF;AACA,kBAAM,oBAAoB,KAAK,2BAA2B;AAC1D,kBAAM,WAAW,OAAO;AAAA,eACrB,oBAAoB,GAAG,iBAAiB,MAAM,MAC/C,OAAO,OAAO,MAAM,aAAa,OAAO,MAAM,aAAa,OAAO,MAClE,aAAa,YAAY,MAAM,aAAa,WAAW,MAAM,WAAW;AAAA,YAC1E,EAAE,MAAM,GAAG,EAAE,CAAC;AACd,kBAAM,SAAqB;AAAA,cACzB,IAAI;AAAA,cACJ,UAAU,OAAO;AAAA,cACjB,MAAM,aAAa;AAAA,cACnB,MAAM,aAAa;AAAA,cACnB,WAAW,aAAa;AAAA,cACxB,UAAU,aAAa;AAAA,cACvB,SAAS,aAAa;AAAA,cACtB,QAAQ,aAAa;AAAA,cACrB,UAAU,aAAa;AAAA,YACzB;AACA,wBAAY,KAAK,MAAM;AACvB,wBAAY,KAAK,MAAM;AACvB,yBAAa,IAAI,QAAQ;AAAA,UAC3B;AAEA,gBAAM,eAAe,OAAO,QAAQ,CAAC,GAAG,YAAY,OAAO,OAAO,CAAC,GAAG;AACtE,cAAI,CAAC,gBAAgB,CAAC,qBAAqB,IAAI,YAAY,GAAG;AAC5D;AAAA,UACF;AACA,gBAAM,4BAA4B,2BAA2B,IAAI,YAAY;AAC7E,gBAAM,qBAAqB,CAAC,SAC1B,4BAA4B,KAAK,YAAY,IAAI;AACnD,gBAAM,gBAAgB,oBAAI,IAA0B;AACpD,qBAAW,UAAU,aAAa;AAChC,kBAAM,MAAM,mBAAmB,OAAO,IAAI;AAC1C,kBAAM,UAAU,cAAc,IAAI,GAAG,KAAK,CAAC;AAC3C,oBAAQ,KAAK,MAAM;AACnB,0BAAc,IAAI,KAAK,OAAO;AAAA,UAChC;AAEA,qBAAW,QAAQ,aAAa,WAAW,SAAS,YAAY,GAAG;AACjE,kBAAM,kBAAkB,oBAAoB,aAAa,KAAK,MAAM,KAAK,MAAM;AAC/E,gBAAI,CAAC,iBAAiB;AACpB;AAAA,YACF;AAEA,gBAAI,aAAa,cAAc,IAAI,mBAAmB,KAAK,UAAU,CAAC;AACtE,gBAAI,iBAAiB,SAAS,YAAY;AACxC,kBAAI,KAAK,aAAa,eAAe;AACnC,6BAAa,WAAW,OAAO,CAAC,cAAc,6BAA6B,IAAI,UAAU,IAAI,CAAC;AAAA,cAChG,WAAW,KAAK,aAAa,QAAQ;AACnC,6BAAa,WAAW,OAAO,CAAC,cAAc,gCAAgC,IAAI,UAAU,IAAI,CAAC;AAAA,cACnG;AAAA,YACF;AACA,yBAAa,YAAY;AAAA,cAAO,CAAC,WAC/B,8BAA8B,cAAc,KAAK,UAAU,OAAO,IAAI;AAAA,YACxE;AACA,kBAAM,iBAAiB,YAAY,WAAW,IAAI,WAAW,CAAC,IAAI;AAClE,sBAAU,KAAK;AAAA,cACb,IAAI,QAAQ;AAAA,gBACV,gBAAgB,KAAK,MAAM,KAAK,aAAa,MAAM,KAAK,OAAO,MAAM,KAAK;AAAA,cAC5E,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,cACd,cAAc,gBAAgB;AAAA,cAC9B,YAAY,KAAK;AAAA,cACjB,YAAY,gBAAgB;AAAA,cAC5B,UAAU,KAAK;AAAA,cACf,YAAY,KAAK;AAAA,cACjB,MAAM,KAAK;AAAA,cACX,KAAK,KAAK;AAAA,cACV,YAAY,mBAAmB;AAAA,YACjC,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,eAAe,SAAS,GAAG;AAC7B,mBAAS,kBAAkB,cAAc;AAAA,QAC3C;AACA,YAAI,YAAY,SAAS,GAAG;AAC1B,mBAAS,mBAAmB,WAAW;AACvC,mBAAS;AAAA,YACP,KAAK,oBAAoB;AAAA,YACzB,YAAY,IAAI,CAAC,WAAW,OAAO,EAAE;AAAA,UACvC;AAAA,QACF;AACA,YAAI,UAAU,SAAS,GAAG;AACxB,mBAAS,qBAAqB,SAAS;AAAA,QACzC;AAEA,iCAAyB,gBAAgB;AACzC,cAAM,eAAe,cAAc;AACnC,qBAAa;AAAA,UACX,OAAO;AAAA,UACP,gBAAgB,mBAAmB,OAAO;AAAA,UAC1C,YAAY,MAAM;AAAA,UAClB,iBAAiB,MAAM;AAAA,UACvB,aAAa,MAAM;AAAA,QACrB,CAAC;AAED,YAAI,cAAc,SAAS,GAAG;AAC5B,uBAAa;AAAA,YACX,OAAO;AAAA,YACP,gBAAgB,mBAAmB,OAAO;AAAA,YAC1C,YAAY,MAAM;AAAA,YAClB,iBAAiB,MAAM;AAAA,YACvB,aAAa,MAAM;AAAA,UACrB,CAAC;AACD,gBAAM,cAAc,MAAM,KAAK,yBAAyB,eAAe;AAAA,YACrE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,aAAa,iBAAiB;AAAA,YAC9B,eAAe,oBAAI,IAAoB;AAAA,YACvC,cAAc;AAAA,YACd,uBAAuB;AAAA,YACvB,2BAA2B;AAAA,YAC3B,aAAa,CAAC,oBAAoB;AAChC,uBAAS;AAAA,gBACP,KAAK,oBAAoB;AAAA,gBACzB,gBAAgB,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,cACzC;AAAA,YACF;AAAA,YACA,YAAY,CAAC,kBAAkB,aAAa;AAAA,cAC1C,OAAO;AAAA,cACP,gBAAgB,mBAAmB,OAAO;AAAA,cAC1C,YAAY,MAAM;AAAA,cAClB,iBAAiB,MAAM,gBAAgB,cAAc;AAAA,cACrD,aAAa,MAAM;AAAA,YACrB,CAAC;AAAA,UACH,CAAC;AACD,gBAAM,iBAAiB,YAAY;AACnC,gBAAM,gBAAgB,YAAY;AAClC,gBAAM,cAAc,YAAY;AAChC,qBAAW,WAAW,YAAY,gBAAgB;AAChD,2BAAe,IAAI,OAAO;AAC1B,gBAAI,oBAAoB;AACtB,mCAAqB,IAAI,OAAO;AAAA,YAClC;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,cAAc,iBAAiB;AACxC,gBAAM,qBAAqB,qBAAqB,IAAI,WAAW,UAAU;AACzE,cAAI,CAAC,sBAAsB,mBAAmB,SAAS,GAAG;AACxD,+BAAmB,IAAI,WAAW,UAAU;AAAA,UAC9C;AAAA,QACF;AACA,cAAM,qBAAqB,KAAK,4BAA4B,MAAM,WAAW;AAC7E,YAAI,MAAM,cAAc,wBAAwB,oBAAoB;AAClE,iCAAuB,MAAM;AAC7B,eAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,wBAAwB,KAAK;AAAA,QACjC,iBAAiB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,iBAAW,cAAc;AAAA,QACvB;AAAA,QACA,CAAC,EAAE,MAAM,MAAM,OAAO,WAAW,MAAM,SAAS,OAAO;AAAA,QACvD,KAAK;AAAA,MACP,GAAG;AACD,cAAM,gBAAgB,WAAW,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK;AACzD,cAAM,gBAAgB,IAAI,IAAI,WAAW,IAAI,CAAC,EAAE,OAAO,aAAa,MAAM,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC;AACnG,mBAAW,SAAS,eAAe;AACjC,0BAAgB,IAAI,MAAM,EAAE;AAC5B,cAAI,eAAe,IAAI,MAAM,EAAE,GAAG;AAChC,4CAAgC,IAAI,MAAM,EAAE;AAAA,UAC9C;AAAA,QACF;AAMA,aAAK,wBAAwB,UAAU,aAAa;AACpD,cAAM,eAAe,cAAc;AACnC,qBAAa;AAAA,UACX,OAAO;AAAA,UACP,gBAAgB,MAAM;AAAA,UACtB,YAAY,MAAM;AAAA,UAClB,iBAAiB,MAAM;AAAA,UACvB,aAAa,MAAM;AAAA,QACrB,CAAC;AACD,cAAM,cAAc,MAAM,KAAK,yBAAyB,eAAe;AAAA,UACrE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAa,iBAAiB;AAAA,UAC9B;AAAA,UACA,cAAc;AAAA,UACd,uBAAuB;AAAA,UACvB,2BAA2B;AAAA,UAC3B,wBAAwB;AAAA,UACxB,aAAa,CAAC,oBAAoB;AAChC,qBAAS;AAAA,cACP,KAAK,oBAAoB;AAAA,cACzB,gBAAgB,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,YACzC;AACA,uBAAW,SAAS,iBAAiB;AACnC,+BAAiB,WAAW,OAAO,MAAM,EAAE;AAC3C,oCAAsB,IAAI,MAAM,EAAE;AAAA,YACpC;AAAA,UACF;AAAA,UACA,YAAY,CAAC,kBAAkB,aAAa;AAAA,YAC1C,OAAO;AAAA,YACP,gBAAgB,MAAM;AAAA,YACtB,YAAY,MAAM;AAAA,YAClB,iBAAiB,MAAM,gBAAgB,cAAc;AAAA,YACrD,aAAa,MAAM;AAAA,UACrB,CAAC;AAAA,QACH,CAAC;AACD,cAAM,iBAAiB,YAAY;AACnC,cAAM,gBAAgB,YAAY;AAClC,cAAM,cAAc,YAAY;AAChC,mBAAW,WAAW,YAAY,gBAAgB;AAChD,yBAAe,IAAI,OAAO;AAC1B,cAAI,oBAAoB;AACtB,iCAAqB,IAAI,OAAO;AAAA,UAClC;AAAA,QACF;AACA,YAAI,MAAM,cAAc,wBAAwB,KAAK,4BAA4B,MAAM,WAAW,GAAG;AACnG,iCAAuB,MAAM;AAC7B,eAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,kBAA4B,CAAC;AACnC,iBAAW,CAAC,OAAO,KAAK,gBAAgB;AACtC,YAAI,CAAC,gBAAgB,IAAI,OAAO,GAAG;AACjC,0BAAgB,KAAK,OAAO;AAAA,QAC9B;AAAA,MACF;AACA,YAAM,eAAe,gBAAgB;AACrC,YAAM,iBAAiB,gBAAgB,OAAO,MAAM;AACpD,YAAM,gBAAgB;AAEtB,WAAK,OAAO,sBAAsB,gBAAgB,IAAI;AACtD,WAAK,OAAO,oBAAoB,YAAY;AAC5C,WAAK,OAAO,KAAK,2BAA2B;AAAA,QAC1C,SAAS,MAAM;AAAA,QACf,UAAU,MAAM;AAAA,QAChB,SAAS;AAAA,MACX,CAAC;AAED,UAAI,MAAM,gBAAgB,KAAK,iBAAiB,GAAG;AACjD,cAAM,sBAAsB,KAAK;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM,KAAK,eAAe;AAAA,UAC1B;AAAA,UACA,MAAM,KAAK,YAAY;AAAA,QACzB;AACA,cAAM,aAAkB,YAAK,KAAK,WAAW,SAAS;AACtD,cAAM,8BAA8B,CAAC,MAAM,eAAe,SACxD,wBAAW,UAAU,SACrB,wBAAW,GAAG,UAAU,YAAY;AACtC,YAAI,2BAA2B,+BAA+B,qBAAqB;AACjF,gBAAM,KAAK;AAAA,QACb;AACA,YAAI,qBAAqB;AACvB,eAAK,kBAAkB,aAAa;AAAA,QACtC;AACA,iBAAS,YAAY,wBAAwB,oBAAoB;AACjE,iBAAS,YAAY,wBAAwB,oBAAoB;AACjE,iBAAS,YAAY,4BAA4B,wBAAwB;AACzE,aAAK,iBAAiB,UAAU,aAAa;AAC7C,aAAK,kBAAkB,sBAAsB;AAC7C,aAAK,qBAAqB,EAAE,YAAY,KAAK;AAC7C,iBAAS,uBAAuB;AAChC,iCAAyB;AACzB,aAAK,8BAA8B,iBAAiB,OAAO,qBAAqB;AAChF,YAAI,aAAa;AACf,eAAK,2BAA2B,mBAAmB,WAAW;AAAA,QAChE,OAAO;AACL,eAAK,gBAAgB;AACrB,eAAK,kBAAkB;AAAA,QACzB;AACA,cAAM,aAAa,KAAK,IAAI,IAAI;AAChC,qBAAa;AAAA,UACX,OAAO;AAAA,UACP,gBAAgB,MAAM;AAAA,UACtB,YAAY,MAAM;AAAA,UAClB,iBAAiB;AAAA,UACjB,aAAa;AAAA,QACf,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,MAAM,gBAAgB,GAAG;AAC3B,aAAK;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM,KAAK,eAAe;AAAA,UAC1B;AAAA,UACA,MAAM,KAAK,YAAY;AAAA,QACzB;AACA,cAAM,KAAK;AACX,aAAK,kBAAkB,aAAa;AACpC,iBAAS,YAAY,wBAAwB,oBAAoB;AACjE,iBAAS,YAAY,wBAAwB,oBAAoB;AACjE,iBAAS,YAAY,4BAA4B,wBAAwB;AACzE,aAAK,iBAAiB,UAAU,aAAa;AAC7C,aAAK,kBAAkB,sBAAsB;AAC7C,aAAK,qBAAqB,EAAE,YAAY,KAAK;AAC7C,iBAAS,uBAAuB;AAChC,iCAAyB;AACzB,aAAK,8BAA8B,iBAAiB,OAAO,qBAAqB;AAChF,YAAI,aAAa;AACf,eAAK,2BAA2B,mBAAmB,WAAW;AAAA,QAChE,OAAO;AACL,eAAK,gBAAgB;AACrB,eAAK,kBAAkB;AAAA,QACzB;AACA,cAAM,aAAa,KAAK,IAAI,IAAI;AAChC,qBAAa;AAAA,UACX,OAAO;AAAA,UACP,gBAAgB,MAAM;AAAA,UACtB,YAAY,MAAM;AAAA,UAClB,iBAAiB;AAAA,UACjB,aAAa;AAAA,QACf,CAAC;AACD,eAAO;AAAA,MACT;AAEA,mBAAa;AAAA,QACX,OAAO;AAAA,QACP,gBAAgB,MAAM;AAAA,QACtB,YAAY,MAAM;AAAA,QAClB,iBAAiB,MAAM;AAAA,QACvB,aAAa,MAAM;AAAA,MACrB,CAAC;AAED,YAAM,iBAAiB,MAAM,KAAK,eAAe,EAAE,OAAO,CAAC,YAAY;AACrE,cAAM,gBAAgB,eAAe,IAAI,OAAO,KAAK,CAAC,gCAAgC,IAAI,OAAO;AACjG,cAAM,iBAAiB,sBAAsB,qBAAqB,IAAI,OAAO;AAC7E,eAAO,CAAC,iBAAiB,CAAC;AAAA,MAC5B,CAAC;AACD,WAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,KAAK,YAAY;AAAA,MACzB;AAEA,YAAM,KAAK;AACX,WAAK,kBAAkB,aAAa;AACpC,eAAS,uBAAuB;AAChC,+BAAyB;AACzB,WAAK,8BAA8B,iBAAiB,OAAO,qBAAqB;AAChF,UAAI,aAAa;AACf,aAAK,2BAA2B,mBAAmB,WAAW;AAAA,MAChE,OAAO;AACL,aAAK,gBAAgB;AACrB,aAAK,kBAAkB;AAAA,MACzB;AAEA,UAAI,KAAK,OAAO,SAAS,UAAU,MAAM,gBAAgB,GAAG;AAC1D,cAAM,UAAU,MAAM,KAAK,iBAAiB;AAC5C,YAAI,SAAS;AACX,gBAAM,aAAa,KAAK,IAAI,IAAI;AAChC,gBAAM,UAAU,QAAQ;AACxB,gBAAM,sBAAsB;AAC5B,eAAK,OAAO,kBAAkB;AAC9B,eAAK,OAAO,KAAK,4EAA4E;AAAA,YAC3F,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,UAAU,MAAM;AAAA,YAChB,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,QAAQ,MAAM;AAAA,YACd,YAAY,MAAM;AAAA,UACpB,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,YAAM,aAAa,KAAK,IAAI,IAAI;AAChC,UAAI,sBAAsB,qBAAqB,SAAS,GAAG;AACzD,iBAAS,eAAe,KAAK,kCAAkC,CAAC;AAAA,MAClE;AACA,UAAI,oBAAoB;AACtB,iBAAS,YAAY,KAAK,wCAAwC,GAAG,MAAM;AAAA,MAC7E;AACA,eAAS,YAAY,wBAAwB,oBAAoB;AACjE,eAAS,YAAY,wBAAwB,oBAAoB;AACjE,eAAS,YAAY,4BAA4B,wBAAwB;AACzE,WAAK,iBAAiB,UAAU,aAAa;AAC7C,WAAK,kBAAkB,sBAAsB;AAC7C,WAAK,qBAAqB,EAAE,YAAY,KAAK;AAE7C,WAAK,OAAO,kBAAkB;AAC9B,WAAK,OAAO,KAAK,qBAAqB;AAAA,QACpC,OAAO,MAAM;AAAA,QACb,SAAS,MAAM;AAAA,QACf,UAAU,MAAM;AAAA,QAChB,SAAS,MAAM;AAAA,QACf,QAAQ,MAAM;AAAA,QACd,QAAQ,MAAM;AAAA,QACd,YAAY,MAAM;AAAA,MACpB,CAAC;AAED,UAAI,MAAM,eAAe,GAAG;AAC1B,cAAM,oBAAoB,KAAK;AAAA,MACjC;AACA,mBAAa;AAAA,QACX,OAAO;AAAA,QACP,gBAAgB,MAAM;AAAA,QACtB,YAAY,MAAM;AAAA,QAClB,iBAAiB,MAAM;AAAA,QACvB,aAAa,MAAM;AAAA,MACrB,CAAC;AACD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,uBAAiB,MAAM,OAAO,QAAQ;AACtC,UAAI,wBAAwB;AAC1B,YAAI;AACF,mBAAS,yBAAyB;AAAA,QACpC,SAAS,eAAe;AACtB,eAAK,OAAO,MAAM,qDAAqD;AAAA,YACrE,OAAOF,iBAAgB,aAAa;AAAA,UACtC,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,kBAAkB,OAAe,UAAyD;AACtG,UAAMG,OAAM,KAAK,IAAI;AACrB,UAAM,SAAS,KAAK,oBAAoB,IAAI,KAAK;AAEjD,QAAI,UAAWA,OAAM,OAAO,YAAa,KAAK,iBAAiB;AAC7D,WAAK,OAAO,MAAM,SAAS,qCAAqC,EAAE,OAAO,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;AAC7F,WAAK,OAAO,oBAAoB;AAChC,aAAO,OAAO;AAAA,IAChB;AAEA,UAAM,eAAe,KAAK,uBAAuB,OAAOA,IAAG;AAC3D,QAAI,cAAc;AAChB,WAAK,OAAO,MAAM,SAAS,uCAAuC;AAAA,QAChE,OAAO,MAAM,MAAM,GAAG,EAAE;AAAA,QACxB,WAAW,aAAa,IAAI,MAAM,GAAG,EAAE;AAAA,QACvC,YAAY,aAAa,WAAW,QAAQ,CAAC;AAAA,MAC/C,CAAC;AACD,WAAK,OAAO,2BAA2B;AACvC,aAAO,aAAa;AAAA,IACtB;AAEA,SAAK,OAAO,MAAM,SAAS,8BAA8B,EAAE,OAAO,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;AACtF,SAAK,OAAO,qBAAqB;AACjC,UAAM,EAAE,WAAW,WAAW,IAAI,MAAM,SAAS,WAAW,KAAK;AACjE,SAAK,OAAO,uBAAuB,UAAU;AAE7C,QAAI,KAAK,oBAAoB,QAAQ,KAAK,mBAAmB;AAC3D,YAAM,YAAY,KAAK,oBAAoB,KAAK,EAAE,KAAK,EAAE;AACzD,UAAI,WAAW;AACb,aAAK,oBAAoB,OAAO,SAAS;AAAA,MAC3C;AAAA,IACF;AAEA,SAAK,oBAAoB,IAAI,OAAO,EAAE,WAAW,WAAWA,KAAI,CAAC;AACjE,WAAO;AAAA,EACT;AAAA,EAEQ,uBACN,OACAA,MACiE;AACjE,UAAM,cAAc,KAAK,SAAS,KAAK;AACvC,QAAI,YAAY,SAAS,EAAG,QAAO;AAEnC,QAAI,YAA6E;AAEjF,eAAW,CAAC,aAAa,EAAE,WAAW,UAAU,CAAC,KAAK,KAAK,qBAAqB;AAC9E,UAAKA,OAAM,aAAc,KAAK,gBAAiB;AAE/C,YAAM,eAAe,KAAK,SAAS,WAAW;AAC9C,YAAM,aAAa,KAAK,kBAAkB,aAAa,YAAY;AAEnE,UAAI,cAAc,KAAK,0BAA0B;AAC/C,YAAI,CAAC,aAAa,aAAa,UAAU,YAAY;AACnD,sBAAY,EAAE,KAAK,aAAa,WAAW,WAAW;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,MAA2B;AAC1C,WAAO,IAAI;AAAA,MACT,KACG,YAAY,EACZ,QAAQ,YAAY,GAAG,EACvB,MAAM,KAAK,EACX,OAAO,OAAK,EAAE,SAAS,CAAC;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,kBAAkB,GAAgB,GAAwB;AAChE,QAAI,EAAE,SAAS,KAAK,EAAE,SAAS,EAAG,QAAO;AACzC,QAAI,EAAE,SAAS,KAAK,EAAE,SAAS,EAAG,QAAO;AAEzC,QAAI,eAAe;AACnB,eAAW,SAAS,GAAG;AACrB,UAAI,EAAE,IAAI,KAAK,EAAG;AAAA,IACpB;AAEA,UAAM,QAAQ,EAAE,OAAO,EAAE,OAAO;AAChC,WAAO,eAAe;AAAA,EACxB;AAAA,EAEQ,wBACN,UACA,gBAIA;AACA,UAAM,8BAA8B,mBAAmB,QAClD,SAAS,eAAe,EAAE,SAAS;AACxC,WAAO;AAAA,MACL;AAAA,MACA,yBAAyB,mBAAmB,SACtC,KAAK,OAAO,UAAU,YAAY;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,+BACN,cACA,YACA,iBACA,iBACA,QACA,YACK;AACL,UAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,CAAC;AAC5D,QAAI,oBAAoB,EAAG,QAAO,CAAC;AACnC,QAAI,CAAC,mBAAmB,CAAC,iBAAiB;AACxC,aAAO,OAAO,eAAe;AAAA,IAC/B;AAEA,UAAM,cAAc,KAAK,IAAI,iBAAiB,gBAAgB,IAAI;AAClE,QAAI,gBAAgB,KAAK,eAAe,EAAG,QAAO,CAAC;AAEnD,QAAI,iBAAiB,KAAK,IAAI,iBAAiB,UAAU;AACzD,WAAO,MAAM;AACX,YAAM,UAAU,OAAO,cAAc;AACrC,YAAM,iBAAiB,QAAQ,OAAO,CAAC,cAAc,gBAAgB,IAAI,WAAW,SAAS,CAAC,CAAC;AAC/F,UACE,eAAe,UAAU,eACtB,QAAQ,SAAS,kBACjB,kBAAkB,YACrB;AACA,eAAO;AAAA,MACT;AAEA,YAAM,YAAY,KAAK,IAAI,YAAY,KAAK,IAAI,iBAAiB,GAAG,iBAAiB,CAAC,CAAC;AACvF,UAAI,cAAc,eAAgB,QAAO;AACzC,uBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,oBACN,UACA,SACoB;AACpB,QAAI,CAAC,SAAS,cAAc,CAAC,SAAS,WAAY,QAAO;AAEzD,UAAM,QAAQ,QAAQ,aAAa,oBAAoB,QAAQ,YAAY,KAAK,IAAI;AACpF,UAAM,QAAQ,QAAQ,aAAa,oBAAoB,QAAQ,YAAY,IAAI,IAAI;AACnF,QAAI,UAAU,QAAQ,UAAU,MAAM;AACpC,aAAO,oBAAI,IAAI;AAAA,IACjB;AAEA,WAAO,IAAI,IAAI,SAAS,uBAAuB,OAAO,KAAK,CAAC;AAAA,EAC9D;AAAA,EAEQ,qBACN,OACA,QACoB;AACpB,QAAI,UAAU,KAAM,QAAO;AAC3B,QAAI,WAAW,KAAM,QAAO;AAC5B,UAAM,CAAC,SAAS,MAAM,IAAI,MAAM,QAAQ,OAAO,OAAO,CAAC,OAAO,MAAM,IAAI,CAAC,QAAQ,KAAK;AACtF,WAAO,IAAI,IAAI,MAAM,KAAK,OAAO,EAAE,OAAO,CAAC,YAAY,OAAO,IAAI,OAAO,CAAC,CAAC;AAAA,EAC7E;AAAA,EAEQ,uBAAuB,WAA+C;AAC5E,WAAO;AAAA,MACL,IAAI,UAAU;AAAA,MACd,UAAU,UAAU,SAAS;AAAA,MAC7B,WAAW,UAAU,SAAS;AAAA,MAC9B,SAAS,UAAU,SAAS;AAAA,MAC5B,OAAO,UAAU;AAAA,MACjB,WAAW,UAAU,SAAS;AAAA,MAC9B,MAAM,UAAU,SAAS;AAAA,IAC3B;AAAA,EACF;AAAA,EAEQ,2BAA2B,YAAoD;AACrF,WAAO,WAAW,IAAI,CAAC,cAAc,KAAK,uBAAuB,SAAS,CAAC;AAAA,EAC7E;AAAA,EAEQ,yBACN,OACA,WACA,cACA,gBACA,yBACA,kBACmB;AACnB,UAAM,iBAAiB,kBAAkB,QAAQ,MAAM,MAAM;AAC7D,QAAI,mBAAmB,EAAG,QAAO,CAAC;AAClC,UAAM,aAAa,qBAAqB,OAAO,SAAY,MAAM,KAAK,gBAAgB;AACtF,WAAO,KAAK;AAAA,MACV,KAAK,IAAI,cAAc,cAAc;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,mBAAmB,MAAM,OAAO,WAAW,gBAAgB,UAAU;AAAA,MACtE,CAAC,cAAc,UAAU;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,OACA,OACA,SACyB;AACzB,UAAM,EAAE,OAAO,UAAU,eAAe,UAAU,YAAY,cAAc,IAAI,MAAM,KAAK,kBAAkB;AAC7G,SAAK,0BAA0B,YAAY,WAAW,UAAU;AAEhE,QAAI,CAAC,cAAc,YAAY;AAC7B,YAAM,IAAI;AAAA,QACR,GAAG,cAAc,UAAU,wDAAwD;AAAA,MAErF;AAAA,IACF;AAEA,UAAM,kBAAkB,8BAAY,IAAI;AAExC,QAAI,MAAM,MAAM,MAAM,GAAG;AACvB,WAAK,OAAO,OAAO,SAAS,yBAAyB,EAAE,MAAM,CAAC;AAC9D,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,aAAa,SAAS,KAAK,OAAO,OAAO;AAC/C,UAAM,eAAe,SAAS,gBAAgB,KAAK,OAAO,OAAO;AACjE,UAAM,iBAAiB,KAAK,OAAO,OAAO;AAC1C,UAAM,wBAAwB,mBAAmB,cAC/C,WAAW,KAAK,CAAC,UAAU,MAAM,cAAc,SAAS,IACtD,IACA;AACJ,UAAM,OAAO,KAAK,OAAO,OAAO;AAChC,UAAM,aAAa,KAAK,OAAO,OAAO;AACtC,UAAM,iBAAiB,SAAS,kBAAkB;AAClD,UAAM,eAAe,SAAS,qBAAqB,QAAQ,uBAAuB,KAAK,MAAM;AAC7F,UAAM,wBAAwB,gBAAgB,SAAS,0BAA0B;AACjF,UAAM,kBAAkB,uBAAuB,KAAK;AACpD,UAAM,iBAAiB,cAAc,wBAAwB,KAAK;AAElE,SAAK,OAAO,OAAO,SAAS,mBAAmB;AAAA,MAC7C;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,qBAAqB,8BAAY,IAAI;AAC3C,UAAM,iBAAiB,kBAAkB,KAAK;AAC9C,QAAI;AACJ,QAAI;AACF,kBAAY,MAAM,KAAK,kBAAkB,gBAAgB,QAAQ;AAAA,IACnE,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,+DAA+D;AAAA,QAC9E;AAAA,QACA,OAAOH,iBAAgB,KAAK;AAAA,QAC5B,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA,UAAM,cAAc,8BAAY,IAAI,IAAI;AAExC,UAAM,qBAAqB,8BAAY,IAAI;AAC3C,QAAI,iBAAqC;AACzC,QAAI,kBAAsC;AAC1C,QAAI,mBAAmB,KAAK,OAAO,UAAU,YAAY,KAAK,kBAAkB,YAAY;AAC1F,YAAM,oBAAoB,KAAK,qBAAqB;AACpD,uBAAiB,IAAI,IAAI,kBAAkB,QAAQ,CAAC,cAAc,SAAS,kBAAkB,SAAS,CAAC,CAAC;AACxG,wBAAkB,IAAI,IAAI,kBAAkB,QAAQ,CAAC,cAAc,SAAS,mBAAmB,SAAS,CAAC,CAAC;AAAA,IAC5G;AACA,UAAM,mBAAmB,KAAK,oBAAoB,UAAU,OAAO;AACnE,UAAM,EAAE,6BAA6B,wBAAwB,IAC3D,KAAK,wBAAwB,UAAU,cAAc;AACvD,UAAM,cAAc,8BAAY,IAAI,IAAI;AAExC,UAAM,kBAAkB,8BAAY,IAAI;AACxC,UAAM,qBAAqB,YACvB,KAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IACA,CAAC;AACL,UAAM,WAAW,8BAAY,IAAI,IAAI;AAErC,UAAM,mBAAmB,8BAAY,IAAI;AACzC,UAAM,oBAAoB,MAAM,KAAK;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,YAAY,8BAAY,IAAI,IAAI;AAEtC,UAAM,2BAA2B,mBAAmB;AAAA,MAAO,CAAC,cAC1D,yBAAyB,WAAW,SAAS,KAAK,WAAW;AAAA,IAC/D;AACA,UAAM,0BAA0B,kBAAkB;AAAA,MAAO,CAAC,cACxD,yBAAyB,WAAW,SAAS,KAAK,WAAW;AAAA,IAC/D;AAEA,QAAI,KAAK,OAAO,UAAU,YAAY,kBAAkB,CAAC,6BAA6B;AACpF,WAAK,OAAO,OAAO,QAAQ,4DAA4D;AAAA,QACrF,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH;AAEA,UAAM,kBAAkB,8BAAY,IAAI;AACxC,UAAM,sBAAsB,cAAc,UAAa,mBAAmB,aACtE,IACA;AACJ,UAAM,WAAW,kBAAkB,OAAO,0BAA0B,yBAAyB;AAAA,MAC3F;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,cAAc;AAAA,MACd;AAAA,IACF,CAAC;AACD,UAAM,mBAAmB,MAAM,KAAK,wBAAwB,OAAO,UAAU;AAAA,MAC3E,kBAAkB,SAAS,qBAAqB;AAAA,MAChD,oBAAoB,gBAAgB,SAAS;AAAA,IAC/C,CAAC;AACD,UAAM,WAAW,8BAAY,IAAI,IAAI;AAErC,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,QAAQ,gBAAgB,0BAA0B,uBAAuB;AAE/E,UAAM,8BAA8B;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,qBAAqB,UAC3B,QAAQ,WAAW,KAAK,EAAE,UAAU,KAAK,MACzC,QAAQ,UAAU,KAAK,EAAE,UAAU,KAAK;AAAA,IAE7C;AAEA,UAAM,iBAAiB,mBAAmB,6BAA6B,gBAAgB,aAAa,CAAC;AAIrG,UAAM,cAAc,SAAS,qBAAqB,OAC9C,mBAAmB,YAAY,gBAAgB,aAAa,CAAC,IAC7D,mBAAmB,gBAAgB,YAAY,aAAa,CAAC;AACjE,UAAM,SAAS,mBAAmB,aAAa,SAAS,aAAa,CAAC;AACtE,UAAM,eAAe,qBAAqB,KAAK,EAAE,SAAS,KAAK,gBAAgB,SAAS;AAExF,UAAM,eAAe,OAAO;AAAA,MAAO,CAAC,MAClC,qBAAqB,GAAG,SAAS,KAAK,OAAO,OAAO,UAAU,KAAK,WAAW;AAAA,IAChF;AAEA,QAAI,kBAAkB;AACtB,QAAI,KAAK,OAAO,OAAO,iBAAiB,GAAG;AACzC,UAAI;AACF,cAAM,4BAA4B;AAAA,UAChC;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK,qBAAqB;AAAA,QAC5B;AACA,0BAAkB;AAAA,UAChB;AAAA,UACA;AAAA,UACA,KAAK,OAAO,OAAO;AAAA,QACrB;AAAA,MACF,SAAS,OAAO;AACd,aAAK,OAAO,OAAO,SAAS,+DAA+D;AAAA,UACzF;AAAA,UACA,OAAOA,iBAAgB,KAAK;AAAA,QAC9B,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,qBAAqB,gBAAgB;AAAA,MAAO,CAAC,MACjDF,4BAA2B,EAAE,SAAS,QAAQ,KAC9C,0BAA0B,EAAE,SAAS,SAAS;AAAA,IAChD;AAEA,UAAM,YAAY,gBAAgB,gBAAgB,mBAAmB,SAAS,IAC1E,qBACA,iBACF,MAAM,GAAG,UAAU;AAErB,UAAM,qBAAsB,CAAC,SAAS,oBAAoB,SAAS,WAAW,KAAK,gBAAgB,SAAS,IACxG,0BAA0B,OAAO,UAAU,gBAAgB,iBAAiB,YAAY,OAAO,IAAI,EAClG,OAAO,CAAC,MAAM,qBAAqB,GAAG,SAAS,KAAK,OAAO,OAAO,UAAU,KAAK,WAAW,CAAC,EAC7F,MAAM,GAAG,UAAU,IACpB,CAAC;AAEL,UAAM,eAAe,SAAS,SAAS,IAAI,WAAW;AAEtD,UAAM,gBAAgB,8BAAY,IAAI,IAAI;AAC1C,SAAK,OAAO,aAAa,eAAe;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO,OAAO,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,MACA,SAAS,aAAa;AAAA,MACtB,SAAS,KAAK,MAAM,gBAAgB,GAAG,IAAI;AAAA,MAC3C,aAAa,KAAK,MAAM,cAAc,GAAG,IAAI;AAAA,MAC7C,UAAU,KAAK,MAAM,WAAW,GAAG,IAAI;AAAA,MACvC,WAAW,KAAK,MAAM,YAAY,GAAG,IAAI;AAAA,MACzC,aAAa,KAAK,MAAM,cAAc,GAAG,IAAI;AAAA,MAC7C,UAAU,KAAK,MAAM,WAAW,GAAG,IAAI;AAAA,IACzC,CAAC;AAED,QAAI,SAAS,OAAO;AAClB,cAAQ,MAAM;AAAA,QACZ,oBAAoB,KAAK,2BAA2B,wBAAwB;AAAA,QAC5E,mBAAmB,KAAK,2BAA2B,uBAAuB;AAAA,QAC1E,kBAAkB,KAAK,2BAA2B,QAAQ;AAAA,QAC1D,8BAA8B,KAAK,2BAA2B,gBAAgB;AAAA,QAC9E,kBAAkB,KAAK,2BAA2B,MAAM;AAAA,QACxD,iBAAiB,KAAK,2BAA2B,YAAY;AAAA,MAC/D,CAAC;AAAA,IACH;AAEA,UAAM,eAAe,SAAS,gBAAgB;AAE9C,WAAO,QAAQ;AAAA,MACb,aAAa,IAAI,OAAO,MAAM;AAC5B,YAAI,UAAU;AACd,YAAI,mBAAmB,EAAE,SAAS;AAClC,YAAI,iBAAiB,EAAE,SAAS;AAChC,cAAM,mBAAmB,KAAK,sBAAsB,EAAE,SAAS,QAAQ;AAEvE,YAAI,CAAC,gBAAgB,KAAK,OAAO,OAAO,gBAAgB;AACtD,cAAI;AACF,kBAAM,cAAc,MAAM,YAAAI,SAAW;AAAA,cACnC;AAAA,cACA;AAAA,YACF;AACA,kBAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,kBAAM,eAAe,SAAS,gBAAgB,KAAK,OAAO,OAAO;AAEjE,+BAAmB,KAAK,IAAI,GAAG,EAAE,SAAS,YAAY,YAAY;AAClE,6BAAiB,KAAK,IAAI,MAAM,QAAQ,EAAE,SAAS,UAAU,YAAY;AAEzE,sBAAU,MACP,MAAM,mBAAmB,GAAG,cAAc,EAC1C,KAAK,IAAI;AAAA,UACd,QAAQ;AACN,sBAAU;AAAA,UACZ;AAAA,QACF;AAEA,eAAO;AAAA,UACL,UAAU;AAAA,UACV,WAAW;AAAA,UACX,SAAS;AAAA,UACT;AAAA,UACA,OAAO,EAAE;AAAA,UACT,WAAW,EAAE,SAAS;AAAA,UACtB,MAAM,EAAE,SAAS;AAAA,UACjB,OAAO,kBAAkB,EAAE,QAAQ;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,cACZ,OACA,OACA,OACA,eACA,iBAAqC,MACrC,0BAA0B,OAC1B,mBAAuC,MACiC;AACxE,UAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACrD,QAAI,oBAAoB,EAAG,QAAO,CAAC;AAEnC,UAAM,kBAAkB,KAAK;AAAA,MAC3B,0BAA0B,iBAAiB;AAAA,MAC3C;AAAA,IACF;AACA,UAAM,eAAe,KAAK;AAAA,MACxB;AAAA,MACA,cAAc,iBAAiB;AAAA,MAC/B;AAAA,MACA,oBAAoB;AAAA,MACpB,CAAC,mBAAmB,MAAM,KAAK,cAAc,OAAO,OAAO,cAAc,CAAC;AAAA,MAC1E,CAAC,CAAC,OAAO,MAAM;AAAA,IACjB;AACA,UAAM,SAAS,IAAI,IAAI,YAAY;AAEnC,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO,CAAC;AAAA,IACV;AAIA,UAAM,WAAW,MAAM,KAAK,OAAO,KAAK,CAAC;AACzC,UAAM,cAAc,MAAM,iBAAiB,QAAQ;AAEnD,UAAM,UAAyE,CAAC;AAChF,eAAW,CAAC,SAAS,KAAK,KAAK,QAAQ;AACrC,YAAM,WAAW,YAAY,IAAI,OAAO;AACxC,UAAI,YAAY,QAAQ,GAAG;AACzB,gBAAQ,KAAK,EAAE,IAAI,SAAS,OAAO,SAAS,CAAC;AAAA,MAC/C;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACxC,WAAO,QAAQ,MAAM,GAAG,eAAe;AAAA,EACzC;AAAA,EAEA,MAAM,YAAmC;AACvC,UAAM,EAAE,OAAO,wBAAwB,UAAU,YAAY,cAAc,IAAI,MAAM,KAAK,kBAAkB;AAC5G,UAAM,qBAAqB,KAAK,sBAAsB;AACtD,UAAM,cAAc,MAAM,MAAM;AAChC,UAAM,mBAAmB,CAAC,GAAG,UAAU;AACvC,QAAI,iBAAiB;AACrB,QAAI,CAAC,iBAAiB,KAAK,CAAC,UAAU,MAAM,cAAc,UAAU,GAAG;AACrE,UAAI;AACF,yBAAiB,SAAS,YAAY,4BAA4B,KAAK;AAAA,MACzE,SAAS,OAAO;AACd,cAAM,UAAU,KAAK,4BAA4B;AACjD,yBAAiB,KAAK,KAAK,gBAAgB,YAAY,OAAO,CAAC;AAC/D,YAAI,CAAC,KAAK,WAAW,KAAK,CAAC,UAAU,MAAM,cAAc,UAAU,GAAG;AACpE,eAAK,gBAAgB,YAAY,SAAS,KAAK;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,iBAAiB,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK,GAAG;AAC3E,UAAM,UAAU,CAAC,aAAa,cAAc,EAAE,OAAO,CAAC,YAAY,QAAQ,SAAS,CAAC,EAAE,KAAK,GAAG;AAC9F,UAAM,uBAAuB,iBAAiB,KAAK,CAAC,UAAU,MAAM,QAAQ;AAE5E,WAAO;AAAA,MACL,SAAS,cAAc,KAAK,CAAC;AAAA,MAC7B;AAAA,MACA,UAAU,uBAAuB;AAAA,MACjC,OAAO,uBAAuB,UAAU;AAAA,MACxC,WAAW,KAAK;AAAA,MAChB,eAAe,KAAK;AAAA,MACpB,YAAY,KAAK;AAAA,MACjB;AAAA,MACA;AAAA,MACA,mBAAmB,qBAAqB,IAAI,KAAK,oBAAoB;AAAA,MACrE,SAAS,WAAW;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,oBAAmD;AACvD,UAAM,EAAE,OAAO,UAAU,YAAY,cAAc,IAAI,MAAM,KAAK,kBAAkB;AACpF,UAAM,oBAAoB,WAAW,KAAK,CAAC,UAAU,MAAM,QAAQ;AACnE,QAAI,mBAAmB;AACrB,aAAO,EAAE,UAAU,OAAO,SAAS,OAAO,QAAQ,aAAa;AAAA,IACjE;AACA,QAAI,MAAM,MAAM,MAAM,GAAG;AACvB,aAAO,EAAE,UAAU,OAAO,SAAS,OAAO,QAAQ,UAAU;AAAA,IAC9D;AACA,QAAI,iBAAiB,CAAC,cAAc,YAAY;AAC9C,aAAO,EAAE,UAAU,MAAM,SAAS,OAAO,QAAQ,eAAe;AAAA,IAClE;AACA,QAAI,KAAK,sBAAsB,IAAI,GAAG;AACpC,aAAO,EAAE,UAAU,MAAM,SAAS,OAAO,QAAQ,iBAAiB;AAAA,IACpE;AAEA,SAAK,cAAc,MAAM;AACzB,SAAK,kBAAkB;AACvB,UAAM,kBAAkB,CAAC,GAAG,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,iBAAiB;AACjF,UAAM,EAAE,MAAM,IAAI,MAAM;AAAA,MACtB,KAAK;AAAA,MACL;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,SAAS;AAAA,MACrB,KAAK,8BAA8B;AAAA,MACnC;AAAA,QACE,UAAU,KAAK,OAAO,SAAS;AAAA,QAC/B,sBAAsB,KAAK,OAAO,SAAS;AAAA,MAC7C;AAAA,IACF;AACA,UAAM,oBAAoB,oBAAI,IAAoB;AAClD,eAAW,QAAQ,OAAO;AACxB,UAAI;AACJ,UAAI;AACF,eAAO,SAAS,KAAK,IAAI;AAAA,MAC3B,SAAS,OAAO;AAId,aAAK,OAAO,KAAK,kDAAkD;AAAA,UACjE,MAAM,KAAK;AAAA,UACX,OAAOF,iBAAgB,KAAK;AAAA,QAC9B,CAAC;AACD,eAAO,EAAE,UAAU,OAAO,SAAS,OAAO,QAAQ,aAAa;AAAA,MACjE;AACA,wBAAkB,IAAI,KAAK,iBAAiB,KAAK,IAAI,GAAG,IAAI;AAAA,IAC9D;AAEA,UAAM,cAAc,KAAK,OAAO,UAAU,WAAW,KAAK,eAAe,IAAI;AAC7E,UAAM,mBAAmB,cACrB,IAAI,IAAI,MAAM,KAAK,KAAK,aAAa,EAAE,OAAO,CAAC,CAAC,QAAQ,MAAM,KAAK,qBAAqB,UAAU,WAAW,CAAC,CAAC,IAC/G,KAAK;AACT,QAAI,iBAAiB,SAAS,kBAAkB,MAAM;AACpD,aAAO,EAAE,UAAU,MAAM,SAAS,OAAO,QAAQ,gBAAgB;AAAA,IACnE;AACA,eAAW,CAAC,UAAU,WAAW,KAAK,mBAAmB;AACvD,UAAI,iBAAiB,IAAI,QAAQ,MAAM,aAAa;AAClD,eAAO,EAAE,UAAU,MAAM,SAAS,OAAO,QAAQ,gBAAgB;AAAA,MACnE;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,kCAAkC,QAAQ,GAAG;AACrD,aAAO,EAAE,UAAU,MAAM,SAAS,OAAO,QAAQ,qBAAqB;AAAA,IACxE;AAEA,QAAI,UAAU,KAAK,uBAAuB,GAAG;AAC3C,YAAM,gBAAgB,MAAM,sBAAsB,KAAK,yBAAyB,MAAM;AACtF,UAAI,KAAK,sBAAsB,QAAQ,MAAM,eAAe;AAC1D,eAAO,EAAE,UAAU,MAAM,SAAS,OAAO,QAAQ,iBAAiB;AAAA,MACpE;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,MAAM,SAAS,MAAM,QAAQ,UAAU;AAAA,EAC5D;AAAA,EAEA,MAAM,WAAW,YAAoD;AACnE,WAAO,KAAK,uBAAuB,eAAe,OAAO,oBAAoB;AAC3E,YAAM,KAAK,0BAA0B,eAAe;AACpD,YAAM,WAAW,KAAK,wBAAwB;AAC9C,YAAM,KAAK,mBAAmB,SAAS,qBAAqB;AAC5D,WAAK,yBAAyB;AAC9B,aAAO,KAAK,cAAc,YAAY,CAAC,GAAG,IAAI;AAAA,IAChD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,KAAK,uBAAuB,SAAS,OAAO,oBAAoB;AACpE,YAAM,KAAK,0BAA0B,eAAe;AACpD,YAAM,WAAW,KAAK,wBAAwB;AAC9C,YAAM,KAAK,mBAAmB,SAAS,qBAAqB;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA,EAEQ,6BAA6B,cAAc,KAAK,aAAmB;AACzE,UAAM,EAAE,OAAO,eAAe,SAAS,IAAI,KAAK,wBAAwB;AACxE,UAAM,oBAAoB,SAAS,eAAe;AAClD,UAAM,MAAM;AACZ,UAAM,KAAK;AACX,kBAAc,MAAM;AACpB,SAAK,kBAAkB,aAAa;AAEpC,SAAK,cAAc,MAAM;AACzB,SAAK,kBAAkB;AAEvB,aAAS,oBAAoB;AAC7B,SAAK,2BAA2B,UAAU,iBAAiB;AAC3D,SAAK,sBAAsB;AAE3B,aAAS,eAAe,eAAe;AACvC,aAAS,eAAe,0BAA0B;AAClD,aAAS,eAAe,yBAAyB;AACjD,aAAS,eAAe,sBAAsB;AAC9C,aAAS,eAAe,2BAA2B;AACnD,aAAS,eAAe,gCAAgC;AACxD,UAAM,sBAAsB,KAAK,uBAAuB,WAAW;AACnE,aAAS,eAAe,KAAK,uCAAuC,mBAAmB,CAAC;AACxF,aAAS,eAAe,KAAK,kCAAkC,mBAAmB,CAAC;AACnF,aAAS,eAAe,KAAK,8BAA8B,mBAAmB,CAAC;AAC/E,aAAS,eAAe,iBAAiB;AACzC,aAAS,eAAe,iBAAiB;AAEzC,SAAK,qBAAqB,KAAK,2BAA2B,KAAK,sBAAuB;AAAA,EACxF;AAAA,EAEQ,yBACN,cAAc,KAAK,aACnB,QAAQ,KAAK,eAAe,GAC5B,kBACM;AACN,UAAM,EAAE,OAAO,eAAe,SAAS,IAAI,KAAK,wBAAwB;AACxE,UAAM,KAAK;AACX,kBAAc,KAAK;AACnB,SAAK,kBAAkB;AACvB,UAAM,gBAAgB,KAAK,mBAAmB;AAC9C,UAAM,wBAAwB,qBAC5B,cAAc,aACV,eACA,cAAc,SAAS,kEACrB,gCACA;AAER,UAAM,cAAc,MAAM,eAAe;AACzC,UAAM,iBACJ,YAAY,KAAK,CAAC,EAAE,SAAS,MAAM,CAAC,KAAK,qBAAqB,SAAS,UAAU,KAAK,CAAC,KACvF,KAAK,2BAA2B,aAAa,KAAK,KAClD,KAAK,6BAA6B,KAAK,KACvC,KAAK,8BAA8B,KAAK;AAE1C,QAAI,0BAA0B,gBAAgB,gBAAgB;AAC5D,UAAI,0BAA0B,+BAA+B;AAC3D,aAAK,4BAA4B,OAAO,eAAe,UAAU,OAAO,WAAW;AACnF,aAAK,yBAAyB,KAAK;AACnC,aAAK,yBAAyB,KAAK;AACnC,cAAM,sBAAsB,KAAK,uBAAuB,WAAW;AACnE,iBAAS,YAAY,KAAK,kCAAkC,mBAAmB,GAAG,MAAM;AACxF,iBAAS,eAAe,KAAK,uCAAuC,mBAAmB,CAAC;AACxF,iBAAS,eAAe,KAAK,wCAAwC,mBAAmB,CAAC;AACzF,YAAI,gBAAgB,KAAK,aAAa;AACpC,eAAK,qBAAqB,EAAE,YAAY,KAAK;AAAA,QAC/C;AACA;AAAA,MACF;AAEA,YAAM,IAAI;AAAA,QACR,gKACwD,WAAW;AAAA,MAErE;AAAA,IACF;AAEA,QAAI,CAAC,gBAAgB;AACnB,WAAK,6BAA6B,WAAW;AAC7C;AAAA,IACF;AAEA,SAAK,4BAA4B,OAAO,eAAe,UAAU,OAAO,WAAW;AACnF,SAAK,yBAAyB,KAAK;AACnC,SAAK,yBAAyB,KAAK;AACnC,QAAI,gBAAgB,KAAK,aAAa;AACpC,WAAK,qBAAqB;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,kBACe;AACf,UAAM,EAAE,OAAO,eAAe,SAAS,IAAI,KAAK,wBAAwB;AAExE,QAAI,KAAK,OAAO,UAAU,UAAU;AAClC,WAAK,yBAAyB,KAAK,aAAa,KAAK,eAAe,GAAG,gBAAgB;AACvF;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,wBAAwB,GAAG;AACnC,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAEA,UAAM,oBAAoB,SAAS,eAAe;AAClD,UAAM,MAAM;AACZ,UAAM,KAAK;AACX,kBAAc,MAAM;AACpB,SAAK,kBAAkB,aAAa;AAEpC,SAAK,cAAc,MAAM;AACzB,UAAM,KAAK,mCAAmC;AAG9C,aAAS,oBAAoB;AAC7B,SAAK,2BAA2B,UAAU,iBAAiB;AAE3D,aAAS,eAAe,eAAe;AACvC,aAAS,eAAe,0BAA0B;AAClD,aAAS,eAAe,yBAAyB;AACjD,aAAS,eAAe,sBAAsB;AAC9C,aAAS,eAAe,2BAA2B;AACnD,aAAS,eAAe,gCAAgC;AACxD,aAAS,eAAe,KAAK,uCAAuC,CAAC;AACrE,aAAS,eAAe,KAAK,kCAAkC,CAAC;AAChE,aAAS,eAAe,KAAK,8BAA8B,CAAC;AAC5D,aAAS,eAAe,iBAAiB;AACzC,aAAS,eAAe,iBAAiB;AAEzC,SAAK,qBAAqB,KAAK,2BAA2B,KAAK,sBAAuB;AAAA,EACxF;AAAA,EAEA,MAAM,cAA0C;AAC9C,WAAO,KAAK,uBAAuB,gBAAgB,OAAO,oBAAoB;AAC5E,YAAM,KAAK,0BAA0B,eAAe;AACpD,aAAO,KAAK,oBAAoB;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,sBAAkD;AAC9D,UAAM,EAAE,OAAO,eAAe,SAAS,IAAI,KAAK,wBAAwB;AAExE,SAAK,OAAO,GAAG,QAAQ,uBAAuB;AAE9C,UAAM,cAAc,MAAM,eAAe;AACzC,UAAM,uBAAuB,oBAAI,IAAsB;AAEvD,eAAW,EAAE,KAAK,SAAS,KAAK,aAAa;AAC3C,YAAM,WAAW,qBAAqB,IAAI,SAAS,QAAQ,KAAK,CAAC;AACjE,eAAS,KAAK,GAAG;AACjB,2BAAqB,IAAI,SAAS,UAAU,QAAQ;AAAA,IACtD;AAEA,UAAM,yBAAmC,CAAC;AAC1C,UAAM,mBAA6B,CAAC;AACpC,UAAM,yBAAyB,oBAAI,IAAsB;AAEzD,eAAW,CAAC,UAAU,SAAS,KAAK,sBAAsB;AACxD,UAAI,KAAC,wBAAW,KAAK,uBAAuB,QAAQ,CAAC,GAAG;AACtD,+BAAuB,IAAI,UAAU,SAAS;AAC9C,mBAAW,OAAO,WAAW;AAC3B,2BAAiB,KAAK,GAAG;AAAA,QAC3B;AACA,+BAAuB,KAAK,QAAQ;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,oBAAoB,KAAK,qBAAqB;AACpD,eAAW,aAAa,mBAAmB;AACzC,eAAS,4BAA4B,WAAW,gBAAgB;AAAA,IAClE;AACA,UAAM,sBAAsB,IAAI,IAAI,SAAS,sBAAsB,gBAAgB,CAAC;AACpF,UAAM,mBAAmB,iBAAiB,OAAO,CAAC,QAAQ,CAAC,oBAAoB,IAAI,GAAG,CAAC;AAEvF,QAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAK,oCAAoC,OAAO,UAAU,gBAAgB;AAC1E,iBAAW,OAAO,kBAAkB;AAClC,sBAAc,YAAY,GAAG;AAAA,MAC/B;AACA,eAAS,kBAAkB,gBAAgB;AAAA,IAC7C;AAEA,UAAM,mBAAmB,MAAM,KAAK,IAAI;AAAA,MACtC,uBAAuB;AAAA,QAAQ,CAAC,aAC9B,SAAS,iBAAiB,QAAQ,EAAE,IAAI,CAAC,WAAW,OAAO,EAAE;AAAA,MAC/D;AAAA,IACF,CAAC;AACD,eAAW,aAAa,mBAAmB;AACzC,eAAS,6BAA6B,WAAW,gBAAgB;AAAA,IACnE;AACA,UAAM,sBAAsB,IAAI,IAAI,SAAS,uBAAuB,gBAAgB,CAAC;AACrF,UAAM,mBAAmB,iBAAiB,OAAO,CAAC,aAAa,CAAC,oBAAoB,IAAI,QAAQ,CAAC;AACjG,aAAS,+BAA+B,gBAAgB;AAExD,UAAM,qBAAqB,IAAI,IAAI,gBAAgB;AACnD,UAAM,yBAAyB,uBAAuB;AAAA,MAAO,CAAC,cAC3D,uBAAuB,IAAI,QAAQ,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,mBAAmB,IAAI,GAAG,CAAC;AAAA,IACxF;AAEA,UAAM,eAAe,iBAAiB;AAEtC,QAAI,eAAe,GAAG;AACpB,YAAM,KAAK;AACX,WAAK,kBAAkB,aAAa;AAAA,IACtC;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI;AACF,2BAAqB,SAAS,mBAAmB;AACjD,uBAAiB,SAAS,eAAe;AACzC,wBAAkB,SAAS,gBAAgB;AAC3C,0BAAoB,SAAS,kBAAkB;AAAA,IACjD,SAAS,OAAO;AACd,UAAI,CAAE,MAAM,KAAK,uBAAuB,8BAA8B,KAAK,GAAI;AAC7E,cAAM;AAAA,MACR;AAEA,YAAM,KAAK,mBAAmB,UAAU,CAAC,GAAG,EAAE,YAAY,KAAK,CAAC;AAEhE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,CAAC;AAAA,QACZ,oBAAoB;AAAA,QACpB,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,mBAAmB;AAAA,QACnB,qBAAqB;AAAA,QACrB,SAAS,KAAK,yBAA8B,YAAK,KAAK,WAAW,aAAa,CAAC;AAAA,MACjF;AAAA,IACF;AAEA,SAAK,OAAO,SAAS,cAAc,gBAAgB,kBAAkB;AACrE,SAAK,OAAO,GAAG,QAAQ,yBAAyB;AAAA,MAC9C,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,cAAc,uBAAuB;AAAA,IACvC,CAAC;AAED,WAAO;AAAA,MACL,SAAS;AAAA,MACT,WAAW,uBAAuB,IAAI,CAAC,aAAa,KAAK,sBAAsB,QAAQ,CAAC;AAAA,MACxF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,qBAAwF;AAC5F,WAAO,KAAK,uBAAuB,wBAAwB,OAAO,oBAAoB;AACpF,YAAM,KAAK,0BAA0B,eAAe;AACpD,aAAO,KAAK,2BAA2B;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,6BAAgG;AAC5G,UAAM,EAAE,OAAO,UAAU,eAAe,UAAU,uBAAuB,IAAI,KAAK,wBAAwB;AAC1G,UAAM,iBAAiB,gCAAgC,sBAAsB;AAC7E,UAAM,qBAAqB,KAAK,sBAAsB,uBAAuB,QAAQ;AACrF,UAAM,QAAQ,KAAK,OAAO,UAAU,WAAW,KAAK,eAAe,IAAI;AACvE,UAAM,mBAAmB,KAAK,6BAA6B,OAAO,MAAM,IAAI;AAE5E,QAAI,iBAAiB,WAAW,SAAS,GAAG;AAC1C,WAAK,8BAA8B,iBAAiB,KAAK;AACzD,aAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,EAAE;AAAA,IACjD;AAEA,UAAM,QAAQ,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3C,UAAM,iBAA0C,EAAE,WAAW,EAAE;AAC/D,QAAI,YAAY;AAChB,QAAI,SAAS;AAEb,QAAI;AACF,YAAM,kBAAkB,KAAK;AAAA,QAC3B,iBAAiB;AAAA,QACjB;AAAA,QACA,MAAM;AAAA,QACN;AAAA,MACF;AACA,iBAAW,cAAc;AAAA,QACvB;AAAA,QACA,CAAC,EAAE,MAAM,MAAM,OAAO,WAAW,MAAM,SAAS,OAAO;AAAA,QACvD,KAAK;AAAA,MACP,GAAG;AACD,cAAM,SAAS,WAAW,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK;AAClD,cAAM,gBAAgB,IAAI,IAAI,WAAW,IAAI,CAAC,EAAE,OAAO,aAAa,MAAM,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC;AAInG,aAAK,wBAAwB,UAAU,MAAM;AAC7C,cAAM,cAAc,MAAM,KAAK,yBAAyB,QAAQ;AAAA,UAC9D;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAa,iBAAiB;AAAA,UAC9B;AAAA,UACA,cAAc;AAAA,UACd,uBAAuB;AAAA,UACvB,2BAA2B;AAAA,UAC3B,wBAAwB;AAAA,UACxB,aAAa,CAAC,oBAAoB;AAChC,qBAAS;AAAA,cACP,KAAK,oBAAoB;AAAA,cACzB,gBAAgB,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,YACzC;AAAA,UACF;AAAA,QACF,CAAC;AACD,qBAAa,YAAY;AACzB,kBAAU,YAAY;AAAA,MACxB;AAEA,WAAK,8BAA8B,iBAAiB,KAAK;AAAA,IAC3D,SAAS,OAAO;AACd,uBAAiB,MAAM,OAAO,QAAQ;AACtC,YAAM;AAAA,IACR;AAEA,UAAM,YAAY,KAAK,sBAAsB;AAC7C,QAAI,YAAY,GAAG;AACjB,YAAM,KAAK;AACX,WAAK,kBAAkB,aAAa;AAAA,IACtC;AAEA,QAAI,SAAS,YAAY,KAAK,cAAc,KAAK,KAAK,8BAA8B,GAAG;AACrF,YAAM,qBACJ,SAAS,YAAY,KAAK,wCAAwC,CAAC,MAAM;AAC3E,UAAI,oBAAoB;AACtB,iBAAS,eAAe,KAAK,kCAAkC,CAAC;AAChE,aAAK,kBAAkB,sBAAsB;AAC7C,aAAK,qBAAqB,EAAE,YAAY,KAAK;AAAA,MAC/C;AAAA,IACF;AAEA,WAAO,EAAE,WAAW,QAAQ,UAAU;AAAA,EACxC;AAAA,EAEA,wBAAgC;AAC9B,UAAM,QAAQ,KAAK,OAAO,UAAU,WAAW,KAAK,eAAe,IAAI;AACvE,UAAM,aAAa,oBAAI,IAAuC;AAC9D,eAAW,SAAS,KAAK,4BAA4B,GAAG;AACtD,iBAAW,YAAY,MAAM,QAAQ;AACnC,cAAM,WAAW,wBAAwB,QAAQ;AACjD,YAAI,UAAU,aAAa,QAAQ,CAAC,KAAK,qBAAqB,UAAU,KAAK,IAAI;AAC/E;AAAA,QACF;AACA,cAAM,UAAU,kBAAkB,QAAQ;AAC1C,YAAI,CAAC,SAAS;AACZ;AAAA,QACF;AACA,cAAM,WAAW,WAAW,IAAI,OAAO;AACvC,YAAI,CAAC,YAAY,MAAM,gBAAgB,SAAS,cAAc;AAC5D,qBAAW,IAAI,SAAS;AAAA,YACtB,cAAc,MAAM;AAAA,YACpB,OAAO,MAAM;AAAA,YACb,aAAa,MAAM;AAAA,YACnB,QAAQ,CAAC,QAAQ;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,IAAI,MAAM,KAAK,WAAW,OAAO,GAAG,sBAAsB,CAAC,EAAE;AAAA,EAC1E;AAAA,EAEA,mBAA2B;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,oBAA0B;AACxB,UAAM,iBAAiB,KAAK;AAC5B,QAAI,UAAU,KAAK,uBAAuB,GAAG;AAC3C,WAAK,gBAAgB,KAAK,sBAAsB,mBAAmB,KAAK,uBAAuB;AAC/F,WAAK,aAAa,cAAc,KAAK,uBAAuB;AAAA,IAC9D,OAAO;AACL,WAAK,gBAAgB;AACrB,WAAK,aAAa;AAAA,IACpB;AAEA,QAAI,KAAK,kBAAkB,gBAAgB;AACzC,WAAK,4BAA4B;AACjC,WAAK,cAAc,MAAM;AACzB,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAM,mBAAkI;AACtI,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,WAAO,SAAS,SAAS;AAAA,EAC3B;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YACJ,MACA,QAAgB,KAAK,OAAO,OAAO,YACnC,SASyB;AACzB,UAAM,EAAE,OAAO,UAAU,UAAU,YAAY,cAAc,IAAI,MAAM,KAAK,kBAAkB;AAC9F,SAAK,0BAA0B,YAAY,WAAW,UAAU;AAEhE,QAAI,CAAC,cAAc,YAAY;AAC7B,YAAM,IAAI;AAAA,QACR,GAAG,cAAc,UAAU,wDAAwD;AAAA,MAErF;AAAA,IACF;AAEA,UAAM,kBAAkB,8BAAY,IAAI;AAExC,QAAI,MAAM,MAAM,MAAM,GAAG;AACvB,WAAK,OAAO,OAAO,SAAS,6BAA6B;AACzD,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,iBAAiB,SAAS,kBAAkB;AAClD,UAAM,qBAAqB,SAAS,cAChC,KAAK,iBAAiB,QAAQ,WAAW,IACzC;AAEJ,SAAK,OAAO,OAAO,SAAS,yBAAyB;AAAA,MACnD,YAAY,KAAK;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,qBAAqB,8BAAY,IAAI;AAC3C,UAAM,EAAE,WAAW,WAAW,IAAI,MAAM,SAAS,cAAc,IAAI;AACnE,UAAM,cAAc,8BAAY,IAAI,IAAI;AACxC,SAAK,OAAO,uBAAuB,UAAU;AAE7C,UAAM,qBAAqB,8BAAY,IAAI;AAC3C,QAAI,iBAAqC;AACzC,QAAI,mBAAmB,KAAK,OAAO,UAAU,YAAY,KAAK,kBAAkB,YAAY;AAC1F,uBAAiB,IAAI;AAAA,QACnB,KAAK,qBAAqB,EAAE,QAAQ,CAAC,cAAc,SAAS,kBAAkB,SAAS,CAAC;AAAA,MAC1F;AAAA,IACF;AACA,UAAM,mBAAmB,KAAK,oBAAoB,UAAU,OAAO;AACnE,UAAM,EAAE,6BAA6B,wBAAwB,IAC3D,KAAK,wBAAwB,UAAU,cAAc;AACvD,UAAM,cAAc,8BAAY,IAAI,IAAI;AAExC,UAAM,kBAAkB,8BAAY,IAAI;AACxC,UAAM,qBAAqB,KAAK;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,WAAW,8BAAY,IAAI,IAAI;AAErC,QAAI,KAAK,OAAO,UAAU,YAAY,kBAAkB,CAAC,6BAA6B;AACpF,WAAK,OAAO,OAAO,QAAQ,4DAA4D;AAAA,QACrF,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH;AAEA,UAAM,aAAa,KAAK,OAAO,OAAO;AAEtC,UAAM,SAAS,wBAAwB,MAAM,oBAAoB;AAAA,MAC/D;AAAA,MACA;AAAA,MACA,uBAAuB;AAAA,IACzB,CAAC;AAED,UAAM,WAAW,OAAO,OAAO,CAAC,MAAM;AACpC,UAAI,EAAE,QAAQ,KAAK,OAAO,OAAO,SAAU,QAAO;AAElD,UAAI,oBAAoB;AACtB,YAAI,EAAE,SAAS,aAAa,mBAAoB,QAAO;AAAA,MACzD;AAEA,aAAO,yBAAyB,GAAG,SAAS,KAAK,WAAW;AAAA,IAC9D,CAAC,EAAE,MAAM,GAAG,KAAK;AAEjB,UAAM,gBAAgB,8BAAY,IAAI,IAAI;AAC1C,SAAK,OAAO,aAAa,eAAe;AAAA,MACtC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,UAAU;AAAA,IACZ,CAAC;AACD,SAAK,OAAO,OAAO,QAAQ,yBAAyB;AAAA,MAClD,YAAY,KAAK;AAAA,MACjB,SAAS,SAAS;AAAA,MAClB,SAAS,KAAK,MAAM,gBAAgB,GAAG,IAAI;AAAA,MAC3C,aAAa,KAAK,MAAM,cAAc,GAAG,IAAI;AAAA,MAC7C,UAAU,KAAK,MAAM,WAAW,GAAG,IAAI;AAAA,MACvC,aAAa,KAAK,MAAM,cAAc,GAAG,IAAI;AAAA,IAC/C,CAAC;AAED,WAAO,QAAQ;AAAA,MACb,SAAS,IAAI,OAAO,MAAM;AACxB,YAAI,UAAU;AACd,cAAM,mBAAmB,KAAK,sBAAsB,EAAE,SAAS,QAAQ;AAEvE,YAAI,KAAK,OAAO,OAAO,gBAAgB;AACrC,cAAI;AACF,kBAAM,cAAc,MAAM,YAAAE,SAAW;AAAA,cACnC;AAAA,cACA;AAAA,YACF;AACA,kBAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,sBAAU,MACP,MAAM,EAAE,SAAS,YAAY,GAAG,EAAE,SAAS,OAAO,EAClD,KAAK,IAAI;AAAA,UACd,QAAQ;AACN,sBAAU;AAAA,UACZ;AAAA,QACF;AAEA,eAAO;AAAA,UACL,UAAU;AAAA,UACV,WAAW,EAAE,SAAS;AAAA,UACtB,SAAS,EAAE,SAAS;AAAA,UACpB;AAAA,UACA,OAAO,EAAE;AAAA,UACT,WAAW,EAAE,SAAS;AAAA,UACtB,MAAM,EAAE,SAAS;AAAA,UACjB,OAAO,kBAAkB,EAAE,QAAQ;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,YAAoB,gBAAkD;AACrF,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAA0B,CAAC;AAEjC,eAAW,aAAa,KAAK,qBAAqB,GAAG;AACnD,iBAAW,QAAQ,SAAS,sBAAsB,YAAY,WAAW,cAAc,GAAG;AACxF,YAAI,CAAC,KAAK,IAAI,KAAK,EAAE,GAAG;AACtB,eAAK,IAAI,KAAK,EAAE;AAChB,kBAAQ,KAAK,KAAK,wBAAwB,IAAI,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBACJ,UACA,YACA,mBACA,gBACyB;AACzB,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAA0B,CAAC;AAEjC,eAAW,aAAa,KAAK,qBAAqB,GAAG;AACnD,YAAM,kBAAkB,IAAI,IAAI,SAAS,mBAAmB,SAAS,CAAC;AACtE,UAAI,CAAC,gBAAgB,IAAI,QAAQ,EAAG;AAEpC,iBAAW,QAAQ,SAAS,sBAAsB,YAAY,WAAW,cAAc,GAAG;AACxF,cAAM,wBAAwB,KAAK,eAAe;AAClD,cAAM,gCAAgC,qBAAqB,CAAC,KAAK;AACjE,YAAK,CAAC,yBAAyB,CAAC,iCAAkC,KAAK,IAAI,KAAK,EAAE,EAAG;AAErF,aAAK,IAAI,KAAK,EAAE;AAChB,gBAAQ,KAAK,KAAK,wBAAwB,IAAI,CAAC;AAAA,MACjD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,UAAkB,gBAAkD;AACnF,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAA0B,CAAC;AAEjC,eAAW,aAAa,KAAK,qBAAqB,GAAG;AACnD,iBAAW,QAAQ,SAAS,WAAW,UAAU,WAAW,cAAc,GAAG;AAC3E,YAAI,CAAC,KAAK,IAAI,KAAK,EAAE,GAAG;AACtB,eAAK,IAAI,KAAK,EAAE;AAChB,kBAAQ,KAAK,KAAK,wBAAwB,IAAI,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,UAAkB,QAAgB,UAA2C;AAC9F,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,QAAI,WAA0B,CAAC;AAE/B,eAAW,aAAa,KAAK,qBAAqB,GAAG;AACnD,YAAME,SAAO,SAAS,iBAAiB,UAAU,QAAQ,WAAW,QAAQ;AAC5E,UAAIA,OAAK,SAAS,MAAM,SAAS,WAAW,KAAKA,OAAK,SAAS,SAAS,SAAS;AAC/E,mBAAWA;AAAA,MACb;AAAA,IACF;AAEA,WAAO,SAAS,IAAI,CAAC,QAAQ,KAAK,sBAAsB,GAAG,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,wBACJ,cACA,YACA,WAAW,IACa;AACxB,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,QAAI,WAA0B,CAAC;AAE/B,eAAW,aAAa,KAAK,qBAAqB,GAAG;AACnD,YAAM,UAAU,SAAS,oBAAoB,SAAS;AACtD,YAAM,cAAc,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;AACxE,UAAI,CAAC,YAAY,IAAI,YAAY,KAAK,CAAC,YAAY,IAAI,UAAU,EAAG;AAEpE,YAAM,mBAAmB,oBAAI,IAAoD;AACjF,YAAM,UAAU,oBAAI,IAAI,CAAC,YAAY,CAAC;AACtC,YAAM,QAAoD,CAAC,EAAE,UAAU,cAAc,OAAO,EAAE,CAAC;AAC/F,UAAI,aAAa;AACjB,UAAI,QAAQ,iBAAiB;AAE7B,aAAO,CAAC,SAAS,aAAa,MAAM,QAAQ;AAC1C,cAAM,UAAU,MAAM,YAAY;AAClC,YAAI,QAAQ,SAAS,SAAU;AAE/B,cAAM,gBAAgB,YAAY,IAAI,QAAQ,QAAQ;AACtD,YAAI,CAAC,cAAe;AACpB,mBAAW,QAAQ,SAAS,WAAW,QAAQ,UAAU,SAAS,GAAG;AACnE,cAAI;AAEJ,cAAI,KAAK,cAAc,YAAY,IAAI,KAAK,UAAU,GAAG;AACvD,2BAAe,KAAK;AAAA,UACtB,WAAW,KAAK,eAAe,QAAW;AACxC,kBAAM,kBAAkB,2BAA2B,IAAI,cAAc,QAAQ;AAC7E,kBAAM,kBAAkB,QAAQ,OAAO,CAAC,cAAc,kBAClD,UAAU,KAAK,YAAY,MAAM,KAAK,WAAW,YAAY,IAC7D,UAAU,SAAS,KAAK,UAAU;AACtC,gBAAI,gBAAgB,WAAW,GAAG;AAChC,6BAAe,gBAAgB,CAAC,EAAE;AAAA,YACpC;AAAA,UACF;AAEA,cAAI,CAAC,gBAAgB,QAAQ,IAAI,YAAY,EAAG;AAChD,kBAAQ,IAAI,YAAY;AACxB,2BAAiB,IAAI,cAAc;AAAA,YACjC,UAAU,QAAQ;AAAA,YAClB,UAAU,KAAK;AAAA,UACjB,CAAC;AAED,cAAI,iBAAiB,YAAY;AAC/B,oBAAQ;AACR;AAAA,UACF;AAEA,gBAAM,KAAK,EAAE,UAAU,cAAc,OAAO,QAAQ,QAAQ,EAAE,CAAC;AAAA,QACjE;AAAA,MACF;AAEA,UAAI,CAAC,MAAO;AAEZ,YAAMA,SAAsB,CAAC;AAC7B,UAAI,kBAAkB;AACtB,aAAO,MAAM;AACX,cAAM,SAAS,YAAY,IAAI,eAAe;AAC9C,YAAI,CAAC,OAAQ;AACb,cAAM,SAAS,iBAAiB,IAAI,eAAe;AACnD,QAAAA,OAAK,KAAK;AAAA,UACR,UAAU,OAAO;AAAA,UACjB,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,UACjB,MAAM,OAAO;AAAA,UACb,UAAU,QAAQ,YAAY;AAAA,QAChC,CAAC;AACD,YAAI,CAAC,OAAQ;AACb,0BAAkB,OAAO;AAAA,MAC3B;AACA,MAAAA,OAAK,QAAQ;AAEb,UAAIA,OAAK,SAAS,MAAM,SAAS,WAAW,KAAKA,OAAK,SAAS,SAAS,SAAS;AAC/E,mBAAWA;AAAA,MACb;AAAA,IACF;AAEA,WAAO,SAAS,IAAI,CAAC,QAAQ,KAAK,sBAAsB,GAAG,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,sBAA6C;AACjD,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,UAAU,oBAAI,IAAwB;AAE5C,eAAW,aAAa,KAAK,qBAAqB,GAAG;AACnD,iBAAW,UAAU,SAAS,oBAAoB,SAAS,GAAG;AAC5D,gBAAQ,IAAI,OAAO,IAAI,KAAK,sBAAsB,MAAM,CAAC;AAAA,MAC3D;AAAA,IACF;AAEA,WAAO,CAAC,GAAG,QAAQ,OAAO,CAAC;AAAA,EAC7B;AAAA,EAEA,MAAM,oBAAoB,QAAwC;AAChE,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,iBAAiB,KAAK,wBAAwB,MAAM;AAC1D,WAAO,SAAS,oBAAoB,cAAc,EAC/C,IAAI,CAAC,WAAW,KAAK,sBAAsB,MAAM,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,mBAAmB,WAAqB,QAAwC;AACpF,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,iBAAiB,KAAK,wBAAwB,MAAM;AAC1D,UAAM,kBAAkB,UAAU,IAAI,CAAC,aAAa,KAAK,iBAAiB,QAAQ,CAAC;AACnF,WAAO,SAAS,mBAAmB,iBAAiB,cAAc,EAC/D,IAAI,CAAC,WAAW,KAAK,sBAAsB,MAAM,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,0BACJ,eACA,WACA,UAC6B;AAC7B,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,SAAS,KAAK,oBAAoB;AACxC,WAAO,SAAS,0BAA0B,eAAe,QAAQ,WAAW,QAAQ,EACjF,IAAI,CAAC,UAAU,KAAK,sBAAsB,KAAK,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,kBAAkB,QAAiB,WAAgD;AACvF,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,iBAAiB,KAAK,wBAAwB,MAAM;AAC1D,WAAO,SAAS,kBAAkB,gBAAgB,SAAS,EACxD,IAAI,CAAC,UAAU,KAAK,sBAAsB,KAAK,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,yBAAyB,QAAmD;AAChF,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,iBAAiB,KAAK,wBAAwB,MAAM;AAC1D,WAAO,SAAS,yBAAyB,cAAc,EAAE,IAAI,CAAC,WAAW;AAAA,MACvE,GAAG;AAAA,MACH,gBAAgB,MAAM,iBAAiB,MAAM,+BAA+B,CAAC,GAAG,IAAI,CAAC,kBAAkB;AAAA,QACrG,GAAG;AAAA,QACH,cAAc,KAAK,sBAAsB,aAAa,YAAY;AAAA,QAClE,YAAY,KAAK,sBAAsB,aAAa,UAAU;AAAA,MAChE,EAAE;AAAA,IACJ,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,kBAAkB,QAA4C;AAClE,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM,KAAK,kBAAkB;AAC9D,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAM,iBAAiB,KAAK,wBAAwB,MAAM;AAC1D,WAAO,SAAS,kBAAkB,cAAc,EAC7C,IAAI,CAAC,UAAU,KAAK,sBAAsB,KAAK,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,YAAY,MAOf,uBAAmE;AACpE,UAAM,eAAe,MAAM,KAAK,kBAAkB;AAClD,QAAI,WAAW,aAAa;AAC5B,UAAM,EAAE,WAAW,IAAI;AACvB,SAAK,0BAA0B,YAAY,UAAU;AACrD,UAAMC,qBAAgB,wBAAU,8BAAQ;AAExC,UAAM,qBAAqB,MAAM,gBAAgB;AAAA,MAC/C,IAAI,KAAK;AAAA,MACT,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,IACnB,CAAC;AACD,UAAM,eAAe,mBAAmB;AACxC,UAAM,cAAc,mBAAmB;AACvC,UAAM,iBAAiB,mBAAmB;AAE1C,QAAI,KAAK,OAAO,UAAa,gBAAgB,QAAW;AACtD,YAAM,IAAI;AAAA,QACR,yCAAyC,KAAK,EAAE;AAAA,MAClD;AAAA,IACF;AACA,QAAI,CAAC,kBAAkB,CAAC,gBAAgB,cAAc,GAAG;AACvD,YAAM,IAAI,MAAM,yEAAyE;AAAA,IAC3F;AAEA,UAAM,iBAAiB,KAAK,OAAO,SAC/B,cACA,KAAK,UAAU,KAAK;AACxB,UAAM,kBAAkB,mBAAmB;AAC3C,UAAM,YAAY,KAAK,uBAAuB,eAAe;AAE7D,QAAI,gBAAgB,SAAS,oBAAoB,SAAS;AAC1D,QAAI,mBAAoE;AAAA,MACtE,UAAU;AAAA,MACV,QAAQ,kBAAkB;AAAA,IAC5B;AACA,UAAM,eAAe,KAAK,OAAO,SAC7B,iBACA,eAAe;AACnB,UAAM,eAAe,KAAK,sBAAsB,UAAU,eAAe;AACzE,UAAM,yBAAyB,iBAAiB;AAEhD,UAAM,oBAAoB,KAAK,kCAAkC,UAAU,eAAe;AAE1F,QAAI,cAAc,WAAW,KAAK,CAAC,0BAA0B,CAAC,mBAAmB;AAC/E,UAAI,CAAC,kBAAkB,mBAAmB,WAAW;AACnD,cAAM,IAAI,MAAM,qFAAqF;AAAA,MACvG;AAEA,8BAAwB;AAAA,QACtB,OAAO;AAAA,QACP,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,iBAAiB;AAAA,QACjB,aAAa;AAAA,MACf,CAAC;AACD,WAAK,sBAAsB;AAC3B,YAAM,eAAe,MAAM;AAAA,QACzB;AAAA,UACE,aAAa,KAAK;AAAA,UAClB,QAAQ;AAAA,UACR,KAAK;AAAA,UACL;AAAA,UACA,IAAI,KAAK;AAAA,UACT,YAAY,mBAAmB;AAAA,QACjC;AAAA,QACA,OAAO,cAAc,SAAS;AAC5B,gBAAM,gBAAgB,IAAI,SAAQ,KAAK,aAAa,KAAK,QAAQ,KAAK,MAAM;AAAA,YAC1E,yBAAyB;AAAA,YACzB,YAAY;AAAA,YACZ;AAAA,YACA;AAAA,YACA,WAAW,KAAK;AAAA,UAClB,CAAC;AACD,cAAI;AACF,mBAAO,MAAM,cAAc;AAAA,cACzB;AAAA,cACA,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF,UAAE;AACA,kBAAM,cAAc,MAAM;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAEA,yBAAmB;AAAA,QACjB,UAAU,aAAa,MAAM;AAAA,QAC7B,QAAQ;AAAA,QACR,QAAQ,aAAa,KAAK;AAAA,QAC1B,QAAQ,aAAa,KAAK;AAAA,MAC5B;AAEA,YAAM,iBAAiB,MAAM,KAAK,kBAAkB;AACpD,WAAK,0BAA0B,eAAe,YAAY,UAAU;AACpE,iBAAW,eAAe;AAC1B,sBAAgB,SAAS,oBAAoB,SAAS;AACtD,UAAI,cAAc,WAAW,GAAG;AAC9B,cAAM,IAAI;AAAA,UACR,UAAU,KAAK,UAAU,cAAc,CAAC,aAAa,KAAK,UAAU,eAAe,CAAC,gFACpD,SAAS,eAAe,EAAE,KAAK,IAAI,KAAK,MAAM,KACzE,SAAS,kBAAkB,SAAS,EAAE,MAAM,YAAY,SAAS,mBAAmB,SAAS,EAAE,MAAM;AAAA,QAE5G;AAAA,MACF;AAAA,IACF;AAEA,UAAM,uBAAuB,CAAC,cAC5B,UAAU,IAAI,CAAC,aAAa,KAAK,iBAAsB,eAAQ,KAAK,aAAa,QAAQ,CAAC,CAAC;AAC7F,UAAM,qBAAqB,qBAAqB,YAAY;AAC5D,UAAM,gBAAgB,SAAS,mBAAmB,oBAAoB,SAAS;AAC/E,UAAM,YAAY,cAAc,IAAI,CAAC,MAAM,EAAE,EAAE;AAE/C,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,oBAAoB,SAAS;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,iBAAiB,IAAI,IAAY,SAAS;AAChD,eAAW,UAAU,mBAAmB;AACtC,qBAAe,IAAI,OAAO,QAAQ;AAAA,IACpC;AACA,UAAM,iBAAiB,MAAM,KAAK,cAAc;AAEhD,UAAM,kBAAkB,SAAS,kBAAkB,WAAW,cAAc;AAC5E,UAAM,eAAe,oBAAI,IAAgF;AACzG,eAAW,KAAK,iBAAiB;AAC/B,UAAI,CAAC,aAAa,IAAI,EAAE,cAAc,GAAG;AACvC,qBAAa,IAAI,EAAE,gBAAgB;AAAA,UACjC,OAAO,EAAE;AAAA,UACT,aAAa;AAAA,UACb,eAAe,oBAAI,IAAI;AAAA,QACzB,CAAC;AAAA,MACH;AACA,YAAM,QAAQ,aAAa,IAAI,EAAE,cAAc;AAC/C,YAAM;AACN,UAAI,UAAU,SAAS,EAAE,QAAQ,GAAG;AAClC,cAAM,cAAc,IAAI,EAAE,QAAQ;AAAA,MACpC;AAAA,IACF;AACA,UAAM,cAAc,MAAM,KAAK,aAAa,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO;AAAA,MAChE,OAAO,EAAE;AAAA,MACT,aAAa,EAAE;AAAA,MACf,eAAe,MAAM,KAAK,EAAE,aAAa;AAAA,IAC3C,EAAE;AAEF,UAAM,iBAAiB,SAAS,kBAAkB,SAAS;AAC3D,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,WAAW,eACd,OAAO,CAAC,MAAM,UAAU,SAAS,EAAE,QAAQ,KAAK,EAAE,eAAe,YAAY,EAC7E,IAAI,CAAC,OAAO;AAAA,MACX,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,UAAU,KAAK,sBAAsB,EAAE,QAAQ;AAAA,IACjD,EAAE;AAEJ,UAAM,gBAAgB,eAAe;AACrC,QAAI;AACJ,QAAI;AAEJ,QAAI,gBAAgB,KAAK,SAAS,WAAW,GAAG;AAC9C,kBAAY;AACZ,mBAAa,iBAAiB,aAAa;AAAA,IAC7C,WAAW,gBAAgB,MAAM,SAAS,SAAS,GAAG;AACpD,kBAAY;AACZ,mBAAa,iBAAiB,aAAa,oBAAoB,SAAS,SAAS,IAAI,KAAK,SAAS,MAAM,uBAAuB,EAAE;AAAA,IACpI,OAAO;AACL,kBAAY;AACZ,mBAAa,oBAAoB,aAAa,oBAAoB,SAAS,WAAW,IAAI,yBAAyB,EAAE;AAAA,IACvH;AAEA,QAAI;AACJ,QAAI,KAAK,gBAAgB;AACvB,uBAAiB,CAAC;AAClB,UAAI;AACF,cAAM,EAAE,OAAO,IAAI,MAAMA;AAAA,UACvB;AAAA,UACA,CAAC,MAAM,QAAQ,WAAW,QAAQ,UAAU,sBAAsB,WAAW,OAAO;AAAA,UACpF,EAAE,KAAK,KAAK,aAAa,SAAS,IAAM;AAAA,QAC1C;AACA,cAAM,UAAU,KAAK,MAAM,MAAM;AAEjC,cAAM,yBAAyB,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACtE,cAAM,qBAAqB,SAAS,kBAAkB,SAAS;AAC/D,cAAM,oBAAoB,oBAAI,IAAoB;AAClD,cAAM,gBAAgB,CAAC,UAAkB,SACvC,GAAG,SAAS,YAAY,CAAC,IAAI,KAAK,YAAY,CAAC;AACjD,mBAAW,KAAK,oBAAoB;AAClC,4BAAkB,IAAI,cAAc,EAAE,UAAU,EAAE,UAAU,GAAG,EAAE,cAAc;AAAA,QACjF;AAEA,mBAAW,UAAU,SAAS;AAC5B,cAAI,OAAO,WAAW,KAAK,GAAI;AAE/B,cAAI;AACF,kBAAM,eAAe,MAAM,gBAAgB;AAAA,cACzC,IAAI,OAAO;AAAA,cACX,aAAa,KAAK;AAAA,cAClB,YAAY,KAAK;AAAA,YACnB,CAAC;AACD,kBAAM,cAAc,qBAAqB,aAAa,KAAK;AAC3D,kBAAM,cAAc,KAAK,uBAAuB,aAAa,eAAe;AAC5E,kBAAM,eAAe,SAAS,mBAAmB,aAAa,WAAW;AACzE,kBAAM,cAAc,oBAAI,IAAY;AACpC,uBAAW,OAAO,cAAc;AAC9B,oBAAM,QAAQ,kBAAkB,IAAI,cAAc,IAAI,UAAU,IAAI,IAAI,CAAC;AACzE,kBAAI,OAAO;AACT,4BAAY,IAAI,KAAK;AAAA,cACvB;AAAA,YACF;AACA,kBAAM,cAAc,MAAM,KAAK,WAAW,EAAE;AAAA,cAAO,CAAC,MAClD,uBAAuB,IAAI,CAAC;AAAA,YAC9B;AACA,gBAAI,YAAY,SAAS,GAAG;AAC1B,6BAAe,KAAK;AAAA,gBAClB,IAAI,OAAO;AAAA,gBACX,QAAQ,OAAO;AAAA,gBACf,wBAAwB;AAAA,cAC1B,CAAC;AAAA,YACH;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,eAAe,cAAc,IAAI,CAAC,OAAO;AAAA,QACvC,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,UAAU,KAAK,sBAAsB,EAAE,QAAQ;AAAA,MACjD,EAAE;AAAA,MACF,mBAAmB,kBAAkB,IAAI,CAAC,OAAO;AAAA,QAC/C,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,UAAU,KAAK,sBAAsB,EAAE,QAAQ;AAAA,QAC/C,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,qBAAqB,SAGxB;AACD,UAAM,EAAE,UAAU,OAAO,WAAW,IAAI,MAAM,KAAK,kBAAkB;AACrE,SAAK,0BAA0B,YAAY,WAAW,UAAU;AAChE,UAAM,cAAc,oBAAI,IAAwB;AAChD,UAAM,YAAY,oBAAI,IAA0B;AAEhD,eAAW,aAAa,KAAK,qBAAqB,GAAG;AAEnD,YAAM,YAAY,SAAS,mBAAmB,SAAS;AACvD,YAAM,cAAc,IAAI,IAAI,SAAS;AAGrC,YAAM,WAAW,SAAS,kBAAkB,SAAS;AACrD,YAAM,cAAc,SAAS,SAAS,IAAI,MAAM,iBAAiB,QAAQ,IAAI,oBAAI,IAAwD;AACzI,YAAM,YAAY,oBAAI,IAAY;AAClC,iBAAW,CAAC,EAAE,IAAI,KAAK,aAAa;AAClC,YAAI,KAAK,SAAU,WAAU,IAAI,KAAK,QAAQ;AAAA,MAChD;AAEA,YAAM,YAAY,SAAS,WAAW,QAAQ,OAAO,EAAE;AACvD,YAAM,0BAA0B,YACvB,eAAQ,KAAK,aAAa,SAAS,IACxC;AAGJ,iBAAW,YAAY,WAAW;AAChC,YAAI,WAAW;AACb,gBAAM,mBAAmB,KAAK,sBAAsB,QAAQ;AAC5D,gBAAM,kBAAkB,aAAa,aAAa,SAAS,WAAW,YAAY,GAAG;AACrF,gBAAM,yBAAyB,4BAA4B,WACzD,qBAAqB,2BAA2B,iBAAiB,WAAW,0BAA+B,UAAG;AAEhH,cAAI,CAAC,mBAAmB,CAAC,wBAAwB;AAC/C;AAAA,UACF;AAAA,QACF;AACA,mBAAW,OAAO,SAAS,iBAAiB,QAAQ,GAAG;AACrD,cAAI,YAAY,IAAI,IAAI,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI,EAAE,GAAG;AACvD,wBAAY,IAAI,IAAI,IAAI,KAAK,sBAAsB,GAAG,CAAC;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AAGA,iBAAW,YAAY,YAAY,KAAK,GAAG;AACzC,mBAAW,QAAQ,SAAS,WAAW,UAAU,SAAS,GAAG;AAC3D,cAAI,CAAC,UAAU,IAAI,KAAK,EAAE,GAAG;AAC3B,sBAAU,IAAI,KAAK,IAAI,KAAK,wBAAwB,IAAI,CAAC;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,CAAC,GAAG,YAAY,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE;AAAA,EAC9E;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,UAAU,MAAM;AACrB,eAAW,YAAY,KAAK,kBAAkB;AAC5C,eAAS,MAAM;AAAA,IACjB;AACA,SAAK,mBAAmB,CAAC;AACzB,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,yBAAyB;AAC9B,SAAK,qBAAqB;AAC1B,SAAK,qBAAqB;AAC1B,SAAK,aAAa,CAAC;AACnB,SAAK,4BAA4B;AACjC,SAAK,4BAA4B;AACjC,SAAK,yBAAyB,MAAM;AAAA,EACtC;AACF;;;AqC3pNO,IAAM,eAAe,oBAAI,IAA8B;AACvD,IAAM,cAAc,oBAAI,IAAgD;AACxE,IAAM,sBAAsB,oBAAI,IAAsB;AAItD,SAAS,mBAAmB,OAAwC;AACzE,MAAI,CAAC,2BAA2B,KAAK,EAAG,QAAO;AAE/C,QAAM,QAAQ,MAAM;AACpB,QAAM,YAAY,QACd,OAAO,MAAM,GAAG,eAAe,MAAM,SAAS,WAAW,MAAM,SAAS,KACxE;AACJ,MAAI,MAAM,WAAW,eAAe;AAClC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,4CAA4C,SAAS;AAAA,IAC7D;AAAA,EACF;AACA,MAAI,MAAM,WAAW,iBAAiB;AACpC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,gDAAgD,SAAS;AAAA,IACjE;AAAA,EACF;AACA,SAAO,EAAE,MAAM,QAAQ,MAAM,+DAA+D,SAAS,KAAK;AAC5G;AAEO,SAAS,eAAe,aAAiC,MAAwB;AACtF,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,oBAAoB,IAAI,IAAI;AACzC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,2EAA2E;AAAA,EAC7F;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,aAAqB,MAAiC;AACvF,SAAO,GAAG,IAAI,KAAK,WAAW;AAChC;AAuCO,SAAS,mBAAmB,aAAqB,MAAyB;AAC/E,QAAM,MAAM,mBAAmB,aAAa,IAAI;AAChD,QAAM,SAAS,aAAa,IAAI,GAAG;AACnC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY,IAAI,GAAG;AAChC,MAAI,CAAC,QAAQ;AACX,aAAS,YAAY,kBAAkB,aAAa,IAAI,CAAC;AACzD,gBAAY,IAAI,KAAK,MAAM;AAAA,EAC7B;AACA,QAAM,UAAU,IAAI,QAAQ,aAAa,QAAQ,IAAI;AACrD,eAAa,IAAI,KAAK,OAAO;AAC7B,qBAAmB,aAAa,MAAM,QAAQ,MAAM,mBAAmB,aAAa,IAAI,CAAC;AACzF,SAAO;AACT;AAEO,SAAS,gBAAgB,aAAqB,QAAmC,MAAsB;AAC5G,sBAAoB,IAAI,MAAM,WAAW;AACzC,QAAM,MAAM,mBAAmB,aAAa,IAAI;AAChD,cAAY,IAAI,KAAK,MAAM;AAC3B,eAAa,IAAI,KAAK,IAAI,QAAQ,aAAa,QAAQ,IAAI,CAAC;AAC5D,qBAAmB,aAAa,MAAM,QAAQ,MAAM,mBAAmB,aAAa,IAAI,CAAC;AAC3F;AAMO,SAAS,qBAAqB,aAAiC,MAAyB;AAC7F,QAAM,OAAO,eAAe,aAAa,IAAI;AAC7C,SAAO,mBAAmB,MAAM,IAAI;AACtC;AAuBO,IAAM,qCAAN,cAAiD,MAAM;AAAA,EAC5D,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEA,eAAsB,iCACpB,aACA,MACe;AACf,QAAM,OAAO,eAAe,aAAa,IAAI;AAC7C,uBAAqB,MAAM,IAAI;AAC/B,QAAM,SAAS,MAAM,6BAA6B,MAAM,IAAI;AAC5D,MAAI,CAAC,OAAO,OAAO;AACjB,UAAM,IAAI;AAAA,MACR,OAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AACF;;;A/C3GA,IAAM,4BAA4B;AAyClC,SAAS,gBAAgB,OAA+C;AACtE,QAAM,aAAa,OAAO,KAAK;AAC/B,SAAO,cAAc;AACvB;AAEA,SAAS,uBAAuB,OAAuB;AACrD,MAAI,aAAkB,aAAM,UAAU,MAAM,KAAK,EAAE,WAAW,MAAM,GAAG,CAAC;AACxE,MAAI,WAAW,WAAW,IAAI,GAAG;AAC/B,iBAAa,WAAW,MAAM,CAAC;AAAA,EACjC;AACA,SAAO,WAAW,SAAS,KAAK,WAAW,SAAS,GAAG,GAAG;AACxD,iBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,OAAwB;AACvD,SAAO,MAAM,WAAW,GAAG,KAAK,eAAe,KAAK,KAAK;AAC3D;AAEA,SAAS,gBAAgB,eAAuB,eAAgC;AAC9E,QAAM,YAAY,uBAAuB,aAAa;AACtD,QAAM,YAAY,uBAAuB,aAAa;AACtD,MAAI,wBAAwB,SAAS,GAAG;AACtC,WAAO,cAAc;AAAA,EACvB;AACA,SAAO,cAAc,aAAa,UAAU,SAAS,IAAI,SAAS,EAAE;AACtE;AAEA,SAAS,qBAAqB,UAAkB,aAA6B;AAC3E,QAAM,qBAAqB,uBAAuB,QAAQ;AAC1D,QAAM,iBAAiB,uBAAuB,WAAW;AACzD,MAAI,uBAAuB,eAAgB,QAAO;AAClD,MAAI,mBAAmB,WAAW,GAAG,cAAc,GAAG,GAAG;AACvD,WAAO,mBAAmB,MAAM,eAAe,SAAS,CAAC;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAAoB,eAAgC;AAC7E,SAAO,OAAO,aAAa,UAAU,OAAO,aAAa,QACrD,OAAO,KAAK,YAAY,MAAM,cAAc,YAAY,IACxD,OAAO,SAAS;AACtB;AAEA,SAAS,YAAY,QAAoB,aAA+C;AACtF,SAAO;AAAA,IACL,UAAU,qBAAqB,OAAO,UAAU,WAAW;AAAA,IAC3D,WAAW,OAAO;AAAA,IAClB,MAAM,OAAO;AAAA,EACf;AACF;AAEA,SAAS,eAAe,QAAoB,aAAqB,WAA2D;AAC1H,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,UAAU,qBAAqB,OAAO,UAAU,WAAW;AAAA,IAC3D,WAAW,OAAO;AAAA,IAClB,MAAM,OAAO;AAAA,IACb;AAAA,EACF;AACF;AAEA,SAAS,uBACP,SACA,aACA,eACA,mBACA,mBAC2B;AAC3B,QAAM,OAAO,cAAc,KAAK;AAChC,QAAM,WAAW,gBAAgB,iBAAiB;AAClD,QAAM,WAAW,gBAAgB,iBAAiB;AAElD,MAAI,UAAU;AACZ,UAAM,SAAS,QAAQ,KAAK,CAAC,cAAc,UAAU,OAAO,QAAQ;AACpE,QAAI,QAAQ;AACV,aAAO,eAAe,QAAQ,aAAa,UAAU;AAAA,IACvD;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,YAAY,CAAC;AAAA,MACb,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,iBAAiB,QAAQ,OAAO,CAAC,WAAW,kBAAkB,QAAQ,IAAI,CAAC;AACjF,QAAM,qBAAqB,WACvB,eAAe,OAAO,CAAC,WAAW,gBAAgB,OAAO,UAAU,QAAQ,CAAC,IAC5E;AAEJ,MAAI,mBAAmB,WAAW,GAAG;AACnC,WAAO,eAAe,mBAAmB,CAAC,GAAG,aAAa,MAAM;AAAA,EAClE;AAEA,QAAM,cAAc,mBAAmB,SAAS,IAAI,qBAAqB,gBACtE,KAAK,CAAC,MAAM,UAAU,KAAK,SAAS,cAAc,MAAM,QAAQ,KAAK,KAAK,YAAY,MAAM,SAAS;AACxG,SAAO;AAAA,IACL,QAAQ,mBAAmB,SAAS,IAAI,cAAc;AAAA,IACtD;AAAA,IACA,UAAU,WAAW,uBAAuB,QAAQ,IAAI;AAAA,IACxD,YAAY,WAAW,MAAM,GAAG,yBAAyB,EAAE,IAAI,CAAC,WAAW,YAAY,QAAQ,WAAW,CAAC;AAAA,IAC3G,iBAAiB,WAAW;AAAA,EAC9B;AACF;AAIA,eAAsB,eACpB,aACA,MACA,OACA,UAcI,CAAC,GACoB;AACzB,QAAM,iCAAiC,aAAa,IAAI;AACxD,QAAM,UAAU,qBAAqB,aAAa,IAAI;AACtD,SAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO;AAAA,IAC1C,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,WAAW,QAAQ;AAAA,IACnB,cAAc,QAAQ;AAAA,IACtB,cAAc,QAAQ;AAAA,IACtB,kBAAkB,QAAQ;AAAA,IAC1B,uBAAuB,QAAQ;AAAA,IAC/B,aAAa,QAAQ;AAAA,IACrB,UAAU,QAAQ;AAAA,IAClB,YAAY,QAAQ;AAAA,IACpB,YAAY,QAAQ;AAAA,IACpB,OAAO,QAAQ;AAAA,EACjB,CAAC;AACH;AAuEA,eAAsB,qBACpB,aACA,MACA,OACA,UAKI,CAAC,GACoB;AACzB,QAAM,iCAAiC,aAAa,IAAI;AACxD,QAAM,UAAU,qBAAqB,aAAa,IAAI;AACtD,SAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO;AAAA,IAC1C,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,kBAAkB;AAAA,IAClB,OAAO,QAAQ;AAAA,EACjB,CAAC;AACH;AAEA,eAAsB,iBACpB,aACA,MACA,QAO8B;AAC9B,QAAM,iCAAiC,aAAa,IAAI;AACxD,QAAM,OAAO,eAAe,aAAa,IAAI;AAC7C,QAAM,UAAU,qBAAqB,MAAM,IAAI;AAC/C,SAAO,2BAA2B,SAAS,MAAM,MAAM;AACzD;AAEA,eAAsB,2BACpB,SACA,aACA,QAO8B;AAC9B,QAAM,UAAU,MAAM,QAAQ,oBAAoB;AAClD,QAAM,aAAa,uBAAuB,SAAS,aAAa,OAAO,MAAM,OAAO,UAAU,OAAO,QAAQ;AAC7G,QAAM,YAAY,OAAO,cAAc,YAAY,YAAY;AAC/D,MAAI,WAAW,WAAW,YAAY;AACpC,WAAO,EAAE,WAAW,YAAY,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,kBAAkB,OAAO,iBAAiB;AAAA,EACtG;AAEA,MAAI,OAAO,cAAc,WAAW;AAClC,UAAM,UAAU,MAAM,QAAQ,WAAW,WAAW,UAAU,OAAO,gBAAgB;AACrF,WAAO,EAAE,WAAW,WAAW,YAAY,SAAS,SAAS,CAAC,GAAG,kBAAkB,OAAO,iBAAiB;AAAA,EAC7G;AAEA,QAAM,oBAAoB,QAAQ,OAAO,CAAC,WAAW,kBAAkB,QAAQ,WAAW,IAAI,CAAC,EAAE,WAAW;AAC5G,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,IACA,OAAO;AAAA,EACT;AACA,SAAO,EAAE,WAAW,WAAW,YAAY,SAAS,SAAS,CAAC,GAAG,kBAAkB,OAAO,iBAAiB;AAC7G;AA6BA,eAAsB,iBACpB,aACA,MACA,MACA,YAOA;AACA,QAAM,OAAO,eAAe,aAAa,IAAI;AAC7C,QAAM,UAAU,qBAAqB,MAAM,IAAI;AAE/C,MAAI;AACF,QAAI,KAAK,cAAc;AACrB,aAAO,EAAE,MAAM,YAAY,UAAU,MAAM,QAAQ,aAAa,EAAE;AAAA,IACpE;AAEA,QAAI,KAAK,QAAQ;AACf,aAAO,EAAE,MAAM,UAAU,QAAQ,MAAM,QAAQ,WAAW,EAAE;AAAA,IAC9D;AAEA,UAAM,cAAc,oBAAoB,MAAM,MAAM,KAAK,SAAS,OAAO,CAAC,aAAa;AACrF,UAAI,YAAY;AACd,aAAK,WAAW,oBAAoB,QAAQ,GAAG;AAAA,UAC7C,OAAO,SAAS;AAAA,UAChB,gBAAgB,SAAS;AAAA,UACzB,YAAY,SAAS;AAAA,UACrB,iBAAiB,SAAS;AAAA,UAC1B,aAAa,SAAS;AAAA,UACtB,YAAY,oBAAoB,QAAQ;AAAA,QAC1C,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,QAAI,CAAC,aAAa;AAChB,YAAM,YAAY,KAAK,QAAQ,QAAQ,WAAW,KAAK,OAAO,IAAI,QAAQ,MAAM,KAAK,OAAO;AAC5F,aAAO,EAAE,MAAM,SAAS,OAAO,MAAM,UAAU,EAAE;AAAA,IACnD;AACA,UAAM,SAAS,MAAM;AACrB,QAAI,OAAO,YAAY,WAAW,OAAO,OAAO;AAC9C,aAAO,EAAE,MAAM,SAAS,OAAO,OAAO,MAAM;AAAA,IAC9C;AACA,QAAI,OAAO,YAAY,WAAW,OAAO,SAAS;AAChD,aAAO,EAAE,MAAM,WAAW,MAAM,qEAAqE;AAAA,IACvG;AACA,QAAI,OAAO,YAAY,WAAW;AAChC,aAAO,EAAE,MAAM,WAAW,MAAM,mHAAmH;AAAA,IACrJ;AACA,QAAI,OAAO,MAAO,OAAM,OAAO;AAC/B,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D,SAAS,OAAO;AACd,UAAM,aAAa,mBAAmB,KAAK;AAC3C,QAAI,CAAC,WAAY,OAAM;AACvB,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,eAAe,aAAiC,MAA4C;AAChH,QAAM,OAAO,eAAe,aAAa,IAAI;AAC7C,QAAM,UAAU,qBAAqB,MAAM,IAAI;AAC/C,SAAO;AAAA,IACL,GAAG,MAAM,QAAQ,UAAU;AAAA,IAC3B,WAAW,mBAAmB,MAAM,IAAI;AAAA,EAC1C;AACF;;;AgD7aA,eAAsB,qBACpB,aACA,MACA,MACA,YAC0B;AAC1B,QAAM,SAAS,MAAM,iBAAiB,aAAa,MAAM,MAAM,UAAU;AACzE,MAAI,OAAO,SAAS,WAAY,QAAO,EAAE,MAAM,mBAAmB,OAAO,QAAQ,EAAE;AACnF,MAAI,OAAO,SAAS,SAAU,QAAO,EAAE,MAAM,qBAAqB,OAAO,MAAM,EAAE;AACjF,MAAI,OAAO,SAAS,OAAQ,QAAO,EAAE,MAAM,OAAO,MAAM,SAAS,KAAK;AACtE,MAAI,OAAO,SAAS,UAAW,QAAO,EAAE,MAAM,OAAO,KAAK;AAC1D,SAAO,EAAE,MAAM,iBAAiB,OAAO,OAAO,KAAK,WAAW,KAAK,EAAE;AACvE;AAEA,eAAsB,mBACpB,aACA,MAC0B;AAC1B,SAAO,EAAE,MAAM,aAAa,MAAM,eAAe,aAAa,IAAI,CAAC,EAAE;AACvE;AAiCA,eAAsB,4BACpB,aACA,MACA,MAC0B;AAC1B,QAAM,UAAU,MAAM,qBAAqB,aAAa,MAAM,KAAK,OAAO;AAAA,IACxE,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,IACf,WAAW,KAAK;AAAA,EAClB,CAAC;AACD,SAAO,EAAE,MAAM,uBAAuB,SAAS,KAAK,KAAK,EAAE;AAC7D;AAEA,eAAsB,iBACpB,aACA,MACA,MAC0B;AAC1B,SAAO,EAAE,MAAM,sBAAsB,MAAM,iBAAiB,aAAa,MAAM,IAAI,CAAC,EAAE;AACxF;;;AClIA,mBAAqC;AACrC,IAAAC,cAA4C;AAC5C,IAAAC,MAAoB;AACpB,IAAAC,SAAsB;AACtB,iBAA8B;;;ACN9B,IAAAC,cAAuD;AACvD,IAAAC,SAAsB;;;ACDtB,IAAAC,UAAwB;AACxB,IAAAC,cAA2B;AAC3B,IAAAC,SAAsB;;;ACFtB,IAAAC,cAA2E;AAC3E,IAAAC,MAAoB;AACpB,IAAAC,SAAsB;;;ACFtB,IAAAC,cAA6B;;;ACG7B,IAAAC,SAAsB;;;ACHtB,IAAAC,SAAsB;;;ACAtB,iBAA0B;;;ACA1B,IAAAC,cAA6B;;;ACC7B,iBAAkB;;;ACAlB,IAAAC,cAAkB;;;ACDX,IAAM,YAAY;AAAA,EACvB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,iBAAiB;AACnB;AAIO,IAAM,sBAAsB;AAAA,EACjC,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AACZ;AAEO,IAAM,sBAAsB;AAAA,EACjC,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AACZ;AAEO,IAAM,gBAAgB;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AACZ;AAMO,IAAM,iBAAiB;AAAA,EAC5B,GAAG;AAAA,EACH,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AACZ;;;ACjGA,IAAAC,cAAqC;AAErC,IAAAC,SAAsB;;;ACFtB,qBAA8D;AAC9D,IAAAC,SAAsB;;;ACGtB,IAAAC,cAA4B;AAC5B,IAAAC,SAAsB;;;ACJtB,IAAAC,SAAsB;;;ACDtB,IAAAC,wBAA6B;AAC7B,IAAAC,SAAsB;;;ACDtB,IAAAC,SAAsB;;;AjBkEf,SAAS,eAAe,MAAgB,KAA2B;AACxE,MAAI,UAAU;AACd,MAAI,OAAiB;AACrB,MAAI;AACJ,MAAI,QAAQ;AACZ,MAAI,eAAe;AACnB,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,OAAO,KAAK,IAAI,CAAC;AAEvB,QAAI,QAAQ,eAAe,IAAI,WAAW,YAAY,GAAG;AACvD,YAAM,QAAQ,IAAI,WAAW,YAAY,IAAI,IAAI,MAAM,aAAa,MAAM,IAAI;AAC9E,UAAI,CAAC,SAAU,CAAC,IAAI,SAAS,GAAG,KAAK,MAAM,WAAW,IAAI,GAAI;AAC5D,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AACA,UAAI,CAAC,IAAI,WAAW,YAAY,GAAG;AACjC,aAAK;AAAA,MACP;AACA,gBAAe,eAAQ,KAAK,KAAK;AACjC;AAAA,IACF;AAEA,QAAI,QAAQ,cAAc,IAAI,WAAW,WAAW,GAAG;AACrD,YAAM,QAAQ,IAAI,WAAW,WAAW,IAAI,IAAI,MAAM,YAAY,MAAM,IAAI;AAC5E,UAAI,CAAC,SAAU,CAAC,IAAI,SAAS,GAAG,KAAK,MAAM,WAAW,IAAI,GAAI;AAC5D,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AACA,UAAI,CAAC,IAAI,WAAW,WAAW,GAAG;AAChC,aAAK;AAAA,MACP;AACA,eAAc,eAAQ,KAAK,KAAK;AAChC;AAAA,IACF;AAEA,QAAI,QAAQ,YAAY,IAAI,WAAW,SAAS,GAAG;AACjD,YAAM,QAAQ,IAAI,WAAW,SAAS,IAAI,IAAI,MAAM,UAAU,MAAM,IAAI;AACxE,UAAI,CAAC,SAAU,CAAC,IAAI,SAAS,GAAG,KAAK,MAAM,WAAW,IAAI,GAAI;AAC5D,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AACA,UAAI,CAAC,IAAI,WAAW,SAAS,GAAG;AAC9B,aAAK;AAAA,MACP;AACA,aAAO,cAAc,KAAK;AAC1B;AAAA,IACF;AAEA,QAAI,QAAQ,aAAa,QAAQ,qBAAqB,QAAQ,eAAe,QAAQ,aAAa;AAChG,UAAI,QAAQ,WAAW;AACrB,gBAAQ;AAAA,MACV;AACA,UAAI,QAAQ,mBAAmB;AAC7B,uBAAe;AAAA,MACjB;AACA,UAAI,QAAQ,aAAa;AACvB,iBAAS;AAAA,MACX;AACA,UAAI,QAAQ,aAAa;AACvB,kBAAU;AAAA,MACZ;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,YAAY,QAAQ,MAAM;AACpC,YAAM,IAAI,MAAM,gBAAgB;AAAA,IAClC;AAEA,UAAM,IAAI,MAAM,yBAAyB,GAAG,EAAE;AAAA,EAChD;AAEA,SAAO,EAAE,SAAS,MAAM,QAAQ,OAAO,cAAc,QAAQ,QAAQ;AACvE;AAMO,SAASC,YAAW,SAAiC,CAAC,SAAS,QAAQ,MAAM,IAAI,GAAS;AAC/F;AAAA,IAAO;AAAA;AAAA,IAEL,QAAQ,KAAK,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAYZ,QAAQ,KAAK,CAAC,CAAC,eAAe,QAAQ,KAAK,CAAC,CAAC;AAAA;AAAA,EAElD;AACF;AAqLA,SAAS,mBAAmB,YAAoC,OAAe,UAAyC;AACtH,QAAM,UAAU,OAAO,QAAQ,QAAQ,EACpC,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,UAAa,UAAU,IAAI,EAC3D,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,eAAe,GAAG,IAAI,eAAe,OAAO,KAAK,CAAC,EAAE,EACpF,KAAK,GAAG;AACX,aAAW,QAAQ,WAAW,IAAI,QAAQ,GAAG,KAAK,IAAI,OAAO,EAAE;AACjE;AAEA,SAAS,eAAe,KAAsB;AAC5C,SAAO,uDAAuD,KAAK,GAAG;AACxE;AAEO,SAAS,oBAAoB,MAAsB;AACxD,SAAO,KAAK;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,MACA,KACA,OAA4B,CAAC,GACZ;AACjB,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,6BAA6B,KAAK,8BAA8B;AACtE,QAAM,oBAAoB,KAAK,qBAAqB;AACpD,QAAM,cAAc,KAAK,gBAAgB,CAAC,SAAS,QAAQ,IAAI,IAAI;AACnE,QAAM,cAAc,KAAK,gBAAgB,CAAC,SAAS,QAAQ,MAAM,oBAAoB,IAAI,CAAC;AAE1F,MAAI;AACJ,MAAI;AACF,iBAAa,eAAe,MAAM,GAAG;AAAA,EACvC,SAAS,OAAO;AACd,QAAI,iBAAiB,SAAS,MAAM,YAAY,kBAAkB;AAChE,MAAAC,YAAW,WAAW;AACtB,aAAO;AAAA,IACT;AACA,gBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAClE,IAAAA,YAAW,WAAW;AACtB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,QAAI,WAAW,WAAW,QAAW;AACnC,YAAM,YAAY,kBAAkB,WAAW,MAAM;AACrD,UAAI,cAAc,MAAM;AACtB,cAAM,IAAI,MAAM,0BAA0B,WAAW,MAAM,EAAE;AAAA,MAC/D;AACA,iCAA2B,WAAW,SAAS,YAAY,SAAS,GAAG,WAAW,IAAI;AAAA,IACxF;AAEA,UAAM,YAAqC;AAAA,MACzC,OAAO,WAAW;AAAA,MAClB,cAAc,WAAW;AAAA,MACzB,QAAQ,WAAW;AAAA,MACnB,SAAS,WAAW;AAAA,IACtB;AAEA,UAAM,SAAS,MAAM,SAAS,WAAW,SAAS,WAAW,MAAM,WAAW,CAAC,OAAO,aAAa;AACjG,yBAAmB,aAAa,OAAO,QAAQ;AAAA,IACjD,CAAC;AAED,QAAI,OAAO,SAAS;AAClB,kBAAY,OAAO,IAAI;AACvB,aAAO;AAAA,IACT;AAEA,gBAAY,OAAO,IAAI;AACvB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,gBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAClE,WAAO;AAAA,EACT;AACF;;;AhEhXA,SAASC,YAAW,QAAwB;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAcR;AACD;AAEA,SAAS,kBAAkB,QAAkB,SAAuB;AAClE,QAAM,QAAgC;AAAA,IACpC,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AACA,SAAO,MAAM,OAAO,KAAK,gCAAgC;AAC3D;AAEA,SAAS,YAAY,MAAgB,OAAe,MAAmD;AACrG,QAAM,MAAM,KAAK,KAAK;AACtB,QAAM,eAAe,KAAK,IAAI;AAC9B,MAAI,IAAI,WAAW,YAAY,EAAG,QAAO,EAAE,OAAO,IAAI,MAAM,aAAa,MAAM,GAAG,UAAU,EAAE;AAC9F,QAAM,QAAQ,KAAK,QAAQ,CAAC;AAC5B,MAAI,CAAC,SAAS,MAAM,WAAW,IAAI,EAAG,OAAM,IAAI,MAAM,KAAK,IAAI,oBAAoB;AACnF,SAAO,EAAE,OAAO,UAAU,EAAE;AAC9B;AAEO,SAAS,oBAAoB,SAAiB,MAAgB,KAA6B;AAChG,MAAI,UAAU;AACd,MAAI,OAAiB;AACrB,MAAI;AACJ,MAAI,QAAQ;AACZ,MAAI;AACJ,QAAM,cAAwB,CAAC;AAE/B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,QAAQ,YAAY,QAAQ,KAAM,OAAM,IAAI,MAAM,gBAAgB;AAEtE,QAAI,QAAQ,eAAe,IAAI,WAAW,YAAY,GAAG;AACvD,YAAM,SAAS,YAAY,MAAM,OAAO,SAAS;AACjD,gBAAe,eAAQ,KAAK,OAAO,KAAK;AACxC,eAAS,OAAO;AAChB;AAAA,IACF;AACA,QAAI,QAAQ,YAAY,IAAI,WAAW,SAAS,GAAG;AACjD,YAAM,SAAS,YAAY,MAAM,OAAO,MAAM;AAC9C,aAAO,cAAc,OAAO,KAAK;AACjC,eAAS,OAAO;AAChB;AAAA,IACF;AACA,QAAI,QAAQ,cAAc,IAAI,WAAW,WAAW,GAAG;AACrD,YAAM,SAAS,YAAY,MAAM,OAAO,QAAQ;AAChD,eAAc,eAAQ,KAAK,OAAO,KAAK;AACvC,eAAS,OAAO;AAChB;AAAA,IACF;AACA,QAAI,YAAY,aAAa,QAAQ,aAAa,IAAI,WAAW,UAAU,IAAI;AAC7E,YAAM,SAAS,YAAY,MAAM,OAAO,OAAO;AAC/C,cAAQ,OAAO,OAAO,KAAK;AAC3B,UAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,EAAG,OAAM,IAAI,MAAM,qCAAqC;AAChG,eAAS,OAAO;AAChB;AAAA,IACF;AACA,QAAI,YAAY,YAAY,QAAQ,YAAY,IAAI,WAAW,SAAS,IAAI;AAC1E,YAAM,SAAS,YAAY,MAAM,OAAO,MAAM;AAC9C,iBAAgB,eAAQ,KAAK,OAAO,KAAK;AACzC,eAAS,OAAO;AAChB;AAAA,IACF;AACA,QAAI,IAAI,WAAW,IAAI,EAAG,OAAM,IAAI,MAAM,mBAAmB,GAAG,EAAE;AAClE,gBAAY,KAAK,GAAG;AAAA,EACtB;AAEA,SAAO,EAAE,SAAS,MAAM,QAAQ,OAAO,UAAU,YAAY;AAC/D;AAEA,eAAe,qBAAqB,MAAsB,MAA8B;AACtF,MAAI,CAAC,KAAK,OAAQ;AAClB,QAAM,aAAa,KAAK,kBAAkB,gBAAgB,KAAK,MAAM;AACrE,MAAI,cAAc,KAAM,OAAM,IAAI,MAAM,0BAA0B,KAAK,MAAM,EAAE;AAC/E,GAAC,KAAK,8BAA8B,iBAAiB,KAAK,SAAS,YAAY,SAAS,GAAG,KAAK,IAAI;AACtG;AAEA,IAAM,gBAAgB,OAAO,aAAiC,MAAgB,OAAe,UAAmC;AAC9H,QAAM,UAAU,MAAM,eAAe,aAAa,MAAM,OAAO,EAAE,MAAM,CAAC;AACxE,SAAO,QAAQ,WAAW,IACtB,EAAE,MAAM,0EAA0E,IAClF,EAAE,MAAM,SAAS,QAAQ,MAAM,iBAAiB,KAAK;AAAA;AAAA,EAAS,oBAAoB,SAAS,OAAO,CAAC,GAAG;AAC5G;AAEA,SAAS,mBAAmB,MAAsB,SAAiB,OAAyB;AAC1F,MAAI,KAAK,YAAY,WAAW,OAAO;AACrC,UAAM,IAAI,MAAM,GAAG,OAAO,aAAa,UAAU,IAAI,yBAAyB,0BAA0B,GAAG;AAAA,EAC7G;AACA,SAAO,KAAK;AACd;AAEA,eAAsB,UAAU,MAAgB,KAAa,OAAgB,CAAC,GAAoB;AAChG,QAAM,SAAS,KAAK,gBAAgB,CAAC,SAAS,QAAQ,IAAI,IAAI;AAC9D,QAAM,SAAS,KAAK,gBAAgB,CAAC,SAAS,QAAQ,MAAM,oBAAoB,IAAI,CAAC;AACrF,QAAM,UAAU,KAAK,CAAC;AAEtB,MAAI,CAAC,WAAW,YAAY,UAAU,YAAY,YAAY,YAAY,MAAM;AAC9E,IAAAA,YAAW,MAAM;AACjB,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,CAAC,UAAU,SAAS,UAAU,cAAc,OAAO,EAAE,SAAS,OAAO,GAAG;AAC3E,WAAO,oBAAoB,OAAO,EAAE;AACpC,IAAAA,YAAW,MAAM;AACjB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,QAAI,YAAY,SAAS;AACvB,aAAO,OAAO,KAAK,YAAY,oBAAoB,KAAK,MAAM,CAAC,GAAG,KAAK;AAAA,QACrE,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,oBAAoB,SAAS,KAAK,MAAM,CAAC,GAAG,GAAG;AAC5D,UAAM,qBAAqB,MAAM,IAAI;AAErC,QAAI,YAAY,UAAU;AACxB,yBAAmB,MAAM,SAAS,CAAC;AACnC,YAAMC,UAAS,OAAO,KAAK,aAAa,oBAAoB,KAAK,SAAS,KAAK,IAAI;AACnF,UAAIA,QAAO,SAAS;AAAE,eAAOA,QAAO,IAAI;AAAG,eAAO;AAAA,MAAG;AACrD,aAAOA,QAAO,IAAI;AAClB,aAAO;AAAA,IACT;AACA,QAAI,YAAY,UAAU;AACxB,YAAM,CAAC,KAAK,IAAI,mBAAmB,MAAM,SAAS,CAAC;AACnD,YAAMA,UAAS,OAAO,KAAK,aAAa,eAAe,KAAK,SAAS,KAAK,MAAM,OAAO,KAAK,KAAK;AACjG,UAAIA,QAAO,SAAS;AAAE,eAAOA,QAAO,IAAI;AAAG,eAAO;AAAA,MAAG;AACrD,aAAOA,QAAO,IAAI;AAClB,aAAO;AAAA,IACT;AACA,QAAI,YAAY,cAAc;AAC5B,YAAM,CAAC,KAAK,IAAI,mBAAmB,MAAM,SAAS,CAAC;AACnD,YAAMA,UAAS,OAAO,KAAK,kBAAkB,CAAC,MAAM,UAAUC,YAC5D,4BAA4B,MAAM,UAAU,EAAE,OAAOA,SAAQ,OAAO,EAAE,CAAC,IAAI,KAAK,SAAS,KAAK,MAAM,KAAK;AAC3G,UAAID,QAAO,SAAS;AAAE,eAAOA,QAAO,IAAI;AAAG,eAAO;AAAA,MAAG;AACrD,aAAOA,QAAO,IAAI;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,CAAC,WAAW,MAAM,IAAI,mBAAmB,MAAM,SAAS,CAAC;AAC/D,QAAI,cAAc,aAAa,cAAc,UAAW,OAAM,IAAI,MAAM,6CAA6C;AACrH,UAAM,SAAS,OAAO,KAAK,iBAAiB,CAAC,MAAM,UAAU,MAAM,gBAAgB,SACjF,iBAAiB,MAAM,UAAU,EAAE,MAAM,WAAW,gBAAgB,UAAU,KAAK,CAAC,IAAI,KAAK,SAAS,KAAK,MAAM,QAAQ,WAAW,KAAK,QAAQ;AACnJ,QAAI,OAAO,SAAS;AAAE,aAAO,OAAO,IAAI;AAAG,aAAO;AAAA,IAAG;AACrD,WAAO,OAAO,IAAI;AAClB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,SAAS,MAAM,YAAY,kBAAkB;AAChE,wBAAkB,QAAQ,OAAO;AACjC,aAAO;AAAA,IACT;AACA,WAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAC7D,sBAAkB,QAAQ,OAAO;AACjC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAAgB,WAAmB,UAAuC;AACxF,SAAO,aAAa,cAAa,kCAAa,gCAAc,SAAS,CAAC,UAAM,8BAAa,QAAQ;AACnG;;;ADrOA,IAAAE,eAAA;AAMA,SAAS,mBAAmB,OAAuB;AACjD,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAI,QAAQ,WAAW,mBAAmB,GAAG;AAC3C,YAAQ,MAAM,OAAO;AACrB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,MAAM,gEAAgE;AAC9E,MAAI,SAAS;AACX,YAAQ,MAAM,OAAO;AAAA,EACvB;AACA,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAI,gBAAgBA,aAAY,KAAK,QAAQ,KAAK,CAAC,CAAC,GAAG;AACrD,YAAU,QAAQ,MAAM,QAAQ,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa;AACxD,YAAQ,WAAW;AAAA,EACrB,CAAC,EAAE,MAAM,kBAAkB;AAC7B;","names":["exports","module","path","Ignore","exports","module","EventEmitter","import_node_fs","path","import_node_url","import_fs","path","import_fs","path","import_fs","path","stat","path","path","path","isStringArray","defaultSearch","isStringArray","import_fs","path","path","lines","formatted","import_fs","os","path","import_fs","os","path","import_fs","path","ignore","fsPromises","stat","resolve","platform","calculatePercentage","resolve","coordinator","import_fs","path","import_fs","path","import_child_process","import_util","resolve","EventEmitter","now","resolve","reject","resolve","import_fs","path","os","hostname","os","path","module","platform","arch","require","import_fs","os","path","import_crypto","getErrorMessage","fsPromises","relative","getErrorMessage","import_child_process","import_fs","path","import_util","execFileAsync","getErrorMessage","headRepositoryIdentity","getCurrentBranch","relative","import_child_process","path","import_util","execFileAsync","STOPWORDS","isLikelyImplementationPath","isDocumentationPath","basename","fs","path","anchor","getErrorMessage","isPathWithinRoot","isLikelyImplementationPath","symbolName","getErrorMessage","resolve","fsPromises","now","path","execFileAsync","import_fs","os","path","import_fs","path","crypto","import_fs","path","import_fs","os","path","import_fs","path","path","import_fs","import_zod","import_fs","path","path","fsPromises","path","path","import_child_process","path","path","printUsage","printUsage","printUsage","result","symbol","import_meta"]}
|