{"version":3,"file":"extension-Pm4HwRE6.mjs","names":["lines: Line[]","map: Record<string, unknown>","items: unknown[]","contents: string[]","number: number | undefined","SIMPLE_ESCAPES: Readonly<Record<string, string>>","HEX_ESCAPE_WIDTH: Readonly<Record<string, number>>","list: unknown[]","url: URL","problems: string[]","frontmatter: Record<string, unknown>","BY_EXTENSION: Readonly<Record<string, string>>","errorText","uri: string","tree: TreeEntry[]","entries: SkillFileEntry[]","problems: SkillWarning[]","uriOf: UriOf","built: BuiltSkill[]","manifest: SkillFileInput[]","catalogFiles: CatalogFile[]","children: Resource[]","source: SkillSource","bytes: Uint8Array","index: MemoryIndex | undefined","#source","#trusted","#baseRoot","#cacheHint","#cache","#strict","#warn","#attached","#listResources","#read","#list","#get","#readDirectory","kept: Skill[]","#keepValid","#cacheFields","#state","#files","#build","#servers","#track","build: CatalogBuildOptions","state: CatalogState","#queue","#reloadNow","#pruneAt","#notify","#notifyFailed"],"sources":["../src/ext/skills/errors.ts","../../core-internal/src/ext/skills/bytes.ts","../../core-internal/src/ext/skills/frontmatter.ts","../../core-internal/src/ext/skills/uri.ts","../../core-internal/src/ext/skills/entry.ts","../../core-internal/src/ext/skills/mime.ts","../src/ext/skills/catalogBuild.ts","../src/ext/skills/internal.ts","../src/ext/skills/paging.ts","../src/ext/skills/catalogSource.ts","../src/ext/skills/files.ts","../src/ext/skills/extension.ts"],"sourcesContent":["import { brandedHasInstance, stampErrorBrands } from '@modelcontextprotocol/core-internal';\n\nimport type { SkillWarning } from './types';\n\n/**\n * Thrown when a skill catalog cannot be built: storage failures always, skill problems under `strict`.\n * Branded, so `instanceof` also matches an instance from another bundled copy of the SDK.\n */\nexport class SkillCatalogError extends Error {\n    static {\n        Object.defineProperty(this, 'mcpBrand', { value: 'mcp.SkillCatalogError' });\n    }\n\n    static override [Symbol.hasInstance](value: unknown): boolean {\n        return brandedHasInstance(this, value);\n    }\n\n    /**\n     * Brand-based type guard: equivalent to `value instanceof this`, as an\n     * explicit static predicate (the axios/AWS-SDK `isInstance` style). Must be\n     * invoked on the class — in callback position write\n     * `v => SkillCatalogError.isInstance(v)`, not `.filter(SkillCatalogError.isInstance)`.\n     */\n    static isInstance<T extends abstract new (...args: never[]) => unknown>(this: T, value: unknown): value is InstanceType<T> {\n        if (typeof this !== 'function') {\n            throw new TypeError(\n                'isInstance must be called on the class (e.g. `SkillCatalogError.isInstance(value)`); for callbacks use `v => SkillCatalogError.isInstance(v)`'\n            );\n        }\n        return brandedHasInstance(this, value);\n    }\n\n    readonly problems: readonly SkillWarning[];\n\n    constructor(problems: readonly SkillWarning[]) {\n        const lines = problems.map(problem => `  ${problem.path}: ${problem.message}`).join('\\n');\n        super(`${problems.length} skill problem${problems.length === 1 ? '' : 's'}:\\n${lines}`);\n        this.name = 'SkillCatalogError';\n        this.problems = problems;\n        stampErrorBrands(this, new.target);\n    }\n}\n\n// Stderr, so a warning never corrupts a stdio transport.\nexport function defaultWarn(warning: SkillWarning): void {\n    // eslint-disable-next-line no-console -- the documented default sink for skills warnings\n    console.warn(`[mcp-sdk] skills: ${warning.path}: ${warning.message}`);\n}\n","const encoder = new TextEncoder();\n\n/** UTF-8 bytes of `text`. */\nexport function encodeUtf8(text: string): Uint8Array {\n    return encoder.encode(text);\n}\n\n/** Decodes UTF-8 only if decoding loses nothing (a BOM is kept); otherwise `undefined`. */\nexport function decodeUtf8Lossless(bytes: Uint8Array): string | undefined {\n    try {\n        return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);\n    } catch {\n        return undefined;\n    }\n}\n\n/** Standard base64 of `bytes`. */\nexport function encodeBase64(bytes: Uint8Array): string {\n    let binary = '';\n    const chunk = 0x80_00;\n    for (let offset = 0; offset < bytes.length; offset += chunk) {\n        binary += String.fromCodePoint(...bytes.subarray(offset, offset + chunk));\n    }\n    return btoa(binary);\n}\n\n/** Bytes of a standard base64 string. */\nexport function decodeBase64(base64: string): Uint8Array {\n    const binary = atob(base64);\n    const bytes = new Uint8Array(binary.length);\n    for (let index = 0; index < binary.length; index++) bytes[index] = binary.codePointAt(index)!;\n    return bytes;\n}\n\n/** `sha256:` followed by the lowercase hex SHA-256 of `bytes` (WebCrypto, every runtime). */\nexport async function sha256Digest(bytes: Uint8Array): Promise<string> {\n    const { buffer, byteOffset, byteLength } = bytes;\n    // WebCrypto refuses views over a SharedArrayBuffer; only those are copied.\n    const view = buffer instanceof ArrayBuffer ? new Uint8Array(buffer, byteOffset, byteLength) : new Uint8Array(bytes);\n    const hash = new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', view));\n    let hex = '';\n    for (const byte of hash) hex += byte.toString(16).padStart(2, '0');\n    return `sha256:${hex}`;\n}\n","/**\n * Frontmatter reader for `SKILL.md` (SEP-2640).\n *\n * Reads the YAML subset real skills use — block mappings and sequences;\n * plain, quoted and block scalars; one-line flow collections; comments — with\n * YAML 1.2 core-schema typing. Anything outside the subset throws a\n * {@linkcode FrontmatterError} instead of being read differently from a full\n * YAML parser. Server catalogs and client verification both call it; it is\n * kept behind this module so it can be swapped for a YAML library.\n */\n\nexport class FrontmatterError extends Error {\n    readonly line: number | undefined;\n\n    constructor(message: string, line?: number) {\n        super(line === undefined ? message : `line ${line}: ${message}`);\n        this.name = 'FrontmatterError';\n        this.line = line;\n    }\n}\n\nexport interface SplitSkillMarkdown {\n    /** The YAML between the opening and closing `---` lines, with LF line endings. */\n    yaml: string;\n    /** The markdown after the closing `---` line. */\n    body: string;\n}\n\nexport interface ParsedSkillMarkdown {\n    frontmatter: Record<string, unknown>;\n    body: string;\n}\n\nconst MAX_DEPTH = 32;\n\n/** Splits `SKILL.md` into its frontmatter YAML and markdown body. */\nexport function splitFrontmatter(markdown: string): SplitSkillMarkdown {\n    let text = markdown.replaceAll('\\r\\n', '\\n');\n    if (text.codePointAt(0) === 0xfe_ff) text = text.slice(1);\n    if (!text.startsWith('---\\n')) throw new FrontmatterError('SKILL.md must begin with a \"---\" line', 1);\n    const rest = text.slice(4);\n    const close = /^---[\\t ]*$/m.exec(rest);\n    if (close === null) throw new FrontmatterError('frontmatter has no closing \"---\" line');\n    let body = rest.slice(close.index + close[0].length);\n    if (body.startsWith('\\n')) body = body.slice(1);\n    return { yaml: rest.slice(0, close.index), body };\n}\n\n/** Splits and parses `SKILL.md`. Line numbers in errors count from the file's first line. */\nexport function parseSkillMarkdown(markdown: string): ParsedSkillMarkdown {\n    const { yaml, body } = splitFrontmatter(markdown);\n    return { frontmatter: parseFrontmatterYaml(yaml, 2), body };\n}\n\n/** Parses frontmatter YAML into a JSON object. `firstLine` numbers the first YAML line in errors. */\nexport function parseFrontmatterYaml(yaml: string, firstLine = 1): Record<string, unknown> {\n    return new Parser(toLines(yaml, firstLine)).parseDocument();\n}\n\ninterface Line {\n    readonly no: number;\n    // Leading spaces only: a tab ends the indentation.\n    readonly indent: number;\n    // The line after its leading spaces and tabs.\n    readonly text: string;\n    readonly raw: string;\n}\n\nfunction toLines(yaml: string, firstLine: number): Line[] {\n    const raws = yaml.split('\\n');\n    if (raws.at(-1) === '') raws.pop();\n    return raws.map((raw, index) => ({ no: firstLine + index, indent: /^ */.exec(raw)?.[0].length ?? 0, text: trimWhiteStart(raw), raw }));\n}\n\nconst TAB_INDENT = 'tabs cannot be used for indentation';\n\nconst isSkippable = (line: Line): boolean => line.text === '' || line.text.startsWith('#');\nconst isTabIndented = (line: Line): boolean => line.raw[line.indent] === '\\t';\nconst isSequenceItem = (text: string): boolean => /^-(?:[\\t ]|$)/.test(text);\n\nclass Parser {\n    private index = 0;\n\n    constructor(private readonly lines: Line[]) {}\n\n    parseDocument(): Record<string, unknown> {\n        const first = this.peek();\n        if (first === undefined) return {};\n        // YAML drops a BOM before the first content, so reading it into the first key would differ: fail closed.\n        if (first.text.startsWith('\\uFEFF')) {\n            throw new FrontmatterError('a byte order mark inside the frontmatter is not supported', first.no);\n        }\n        if (isSequenceItem(first.text) || matchKey(first.text, first.no) === undefined) {\n            throw new FrontmatterError('frontmatter must be a mapping of keys to values', first.no);\n        }\n        const map = this.parseMapping(first.indent, 0);\n        const extra = this.peek();\n        if (extra !== undefined) throw new FrontmatterError('unexpected content', extra.no);\n        return map;\n    }\n\n    private peek(): Line | undefined {\n        while (this.index < this.lines.length && isSkippable(this.lines[this.index]!)) this.index++;\n        const line = this.lines[this.index];\n        if (line !== undefined && isTabIndented(line)) throw new FrontmatterError(TAB_INDENT, line.no);\n        return line;\n    }\n\n    private parseMapping(indent: number, depth: number): Record<string, unknown> {\n        assertDepth(depth, this.lines[this.index]?.no);\n        const map: Record<string, unknown> = {};\n        for (let line = this.peek(); line !== undefined && line.indent >= indent; line = this.peek()) {\n            if (line.indent > indent) throw new FrontmatterError('unexpected indentation', line.no);\n            if (isSequenceItem(line.text)) break;\n            const match = matchKey(line.text, line.no);\n            if (match === undefined) throw new FrontmatterError('expected \"key: value\"', line.no);\n            if (Object.hasOwn(map, match.key)) throw new FrontmatterError(`duplicate key \"${match.key}\"`, line.no);\n            this.index++;\n            map[match.key] = this.parseValue(match.rest, line, indent, depth + 1, true);\n        }\n        return map;\n    }\n\n    private parseSequence(indent: number, depth: number): unknown[] {\n        assertDepth(depth, this.lines[this.index]?.no);\n        const items: unknown[] = [];\n        for (let line = this.peek(); line !== undefined && line.indent >= indent; line = this.peek()) {\n            if (line.indent > indent) throw new FrontmatterError('unexpected indentation', line.no);\n            if (!isSequenceItem(line.text)) break;\n            const after = line.text.slice(1);\n            const rest = trimWhiteStart(after);\n            const column = line.indent + 1 + (after.length - rest.length);\n            if (rest !== '' && !rest.startsWith('#') && (isSequenceItem(rest) || matchKey(rest, line.no) !== undefined)) {\n                // `- key: value` or `- - item`: the item is a block node that starts at `column`.\n                if (/^ *\\t/.test(after)) throw new FrontmatterError(TAB_INDENT, line.no);\n                this.lines[this.index] = { ...line, indent: column, text: rest };\n                items.push(isSequenceItem(rest) ? this.parseSequence(column, depth + 1) : this.parseMapping(column, depth + 1));\n                continue;\n            }\n            this.index++;\n            items.push(this.parseValue(rest, line, indent, depth + 1, false));\n        }\n        return items;\n    }\n\n    private parseValue(rest: string, line: Line, parentIndent: number, depth: number, allowCompactSequence: boolean): unknown {\n        if (rest === '' || rest.startsWith('#')) {\n            const next = this.peek();\n            if (next !== undefined && next.indent > parentIndent) return this.parseIndented(parentIndent, depth);\n            if (allowCompactSequence && next !== undefined && next.indent === parentIndent && isSequenceItem(next.text)) {\n                return this.parseSequence(parentIndent, depth);\n            }\n            return null;\n        }\n        const first = rest[0]!;\n        if (first === '|' || first === '>') return this.parseBlockScalar(rest, line, parentIndent);\n        if (first === '\"' || first === \"'\") {\n            const { value, end } = readQuoted(rest, 0, line.no);\n            expectOnlyComment(rest.slice(end), line.no);\n            return value;\n        }\n        if (first === '[' || first === '{') {\n            const { value, end } = readFlow(rest, 0, line.no, depth);\n            expectOnlyComment(rest.slice(end), line.no);\n            return value;\n        }\n        if ('&*!'.includes(first)) throw new FrontmatterError('anchors, aliases and tags are not supported', line.no);\n        if ('%@`,]}'.includes(first)) throw new FrontmatterError(`\"${first}\" cannot start a plain value; quote it`, line.no);\n        if (isSequenceItem(rest) || /^\\?(?:[\\t ]|$)/.test(rest)) {\n            throw new FrontmatterError('a nested collection must start on its own line', line.no);\n        }\n        return this.parsePlain(rest, line, parentIndent);\n    }\n\n    private parseIndented(parentIndent: number, depth: number): unknown {\n        const line = this.peek()!;\n        if (isSequenceItem(line.text)) return this.parseSequence(line.indent, depth);\n        if (matchKey(line.text, line.no) !== undefined) return this.parseMapping(line.indent, depth);\n        this.index++;\n        return this.parseValue(line.text, line, parentIndent, depth, false);\n    }\n\n    private parsePlain(first: string, line: Line, parentIndent: number): unknown {\n        let value = stripComment(first);\n        assertPlain(value, line.no);\n        let commented = COMMENT.test(first);\n        let blanks = 0;\n        while (this.index < this.lines.length) {\n            const next = this.lines[this.index]!;\n            if (next.text === '') {\n                blanks++;\n                this.index++;\n                continue;\n            }\n            if (next.indent <= parentIndent || next.text.startsWith('#')) break;\n            if (isTabIndented(next)) throw new FrontmatterError(TAB_INDENT, next.no);\n            if (commented) throw new FrontmatterError('a comment ends a plain value; quote a value that continues past it', next.no);\n            const part = stripComment(next.text);\n            assertPlain(part, next.no);\n            commented = COMMENT.test(next.text);\n            value += blanks > 0 ? '\\n'.repeat(blanks) : ' ';\n            value += part;\n            blanks = 0;\n            this.index++;\n        }\n        return resolvePlain(value, line.no);\n    }\n\n    private parseBlockScalar(header: string, line: Line, parentIndent: number): string {\n        const match = /^([>|])([+-]?)(?:[\\t ]+#.*)?[\\t ]*$/.exec(header);\n        if (match === null) {\n            const indicator = /^[>|][+-]?\\d|^[>|]\\d/.test(header);\n            throw new FrontmatterError(\n                indicator ? 'block scalar indentation indicators are not supported' : 'invalid block scalar header',\n                line.no\n            );\n        }\n        const contents: string[] = [];\n        let contentIndent = -1;\n        let leadingWidth = 0;\n        while (this.index < this.lines.length) {\n            const next = this.lines[this.index]!;\n            const spacesOnly = next.indent === next.raw.length;\n            if (contentIndent === -1 && !spacesOnly && next.indent > parentIndent) {\n                contentIndent = next.indent;\n                if (leadingWidth > contentIndent) {\n                    throw new FrontmatterError('a leading blank line is indented more than the block scalar content', next.no);\n                }\n            }\n            if (contentIndent !== -1 && next.indent >= contentIndent) {\n                contents.push(next.raw.slice(contentIndent));\n            } else if (spacesOnly) {\n                if (contentIndent === -1) leadingWidth = Math.max(leadingWidth, next.indent);\n                contents.push('');\n            } else if (isTabIndented(next)) {\n                throw new FrontmatterError(TAB_INDENT, next.no);\n            } else {\n                break;\n            }\n            this.index++;\n        }\n        return foldBlock(contents, match[1] === '>', match[2] ?? '');\n    }\n}\n\nfunction assertDepth(depth: number, line: number | undefined): void {\n    if (depth > MAX_DEPTH) throw new FrontmatterError(`nesting deeper than ${MAX_DEPTH} levels is not supported`, line);\n}\n\ninterface KeyMatch {\n    key: string;\n    rest: string;\n}\n\nfunction matchKey(text: string, no: number): KeyMatch | undefined {\n    const first = text[0];\n    if (first === '\"' || first === \"'\") {\n        const { value, end } = readQuoted(text, 0, no);\n        const after = text.slice(end);\n        if (after === ':' || /^:[\\t ]/.test(after)) return { key: checkKey(value, no), rest: trimWhiteStart(after.slice(1)) };\n        return undefined;\n    }\n    if (first === '?') throw new FrontmatterError('complex keys (\"?\") are not supported', no);\n    if (first === undefined || '[]{}&*!|>%@`#,'.includes(first)) return undefined;\n    for (let index = 0; index < text.length; index++) {\n        const char = text[index];\n        const previous = text[index - 1];\n        if (char === '#' && (previous === ' ' || previous === '\\t')) return undefined;\n        if (char === ':') {\n            const next = text[index + 1];\n            if (next === undefined || next === ' ' || next === '\\t') {\n                const key = trimWhiteEnd(text.slice(0, index));\n                if (key === '') return undefined;\n                return { key: resolveKey(key, no), rest: trimWhiteStart(text.slice(index + 1)) };\n            }\n        }\n    }\n    return undefined;\n}\n\nfunction checkKey(key: string, no: number): string {\n    if (key === '__proto__') throw new FrontmatterError('the key \"__proto__\" is not supported', no);\n    return key;\n}\n\nfunction resolveKey(raw: string, no: number): string {\n    if (typeof resolvePlain(raw, no) !== 'string') throw new FrontmatterError(`key \"${raw}\" must be a string; quote it`, no);\n    return checkKey(raw, no);\n}\n\nfunction assertPlain(text: string, no: number): void {\n    if (/:(?:[\\t ]|$)/.test(text)) throw new FrontmatterError('a plain value cannot contain \": \"; quote the value', no);\n}\n\nconst COMMENT = /[\\t ]#/;\n\nfunction stripComment(text: string): string {\n    const match = COMMENT.exec(text);\n    return trimWhiteEnd(match === null ? text : text.slice(0, match.index));\n}\n\nfunction expectOnlyComment(after: string, no: number): void {\n    if (trimWhiteStart(after) === '' || /^[\\t ]+#/.test(after)) return;\n    throw new FrontmatterError('unexpected text after the value', no);\n}\n\n// YAML white space is only space and tab; `String.prototype.trim` would also strip Unicode spaces YAML keeps.\nfunction trimWhiteStart(text: string): string {\n    return text.slice(skipSpaces(text, 0));\n}\n\nfunction trimWhiteEnd(text: string): string {\n    let end = text.length;\n    while (end > 0 && (text[end - 1] === ' ' || text[end - 1] === '\\t')) end--;\n    return text.slice(0, end);\n}\n\nconst NULL = /^(?:~|null|Null|NULL)$/;\nconst TRUE = /^(?:true|True|TRUE)$/;\nconst FALSE = /^(?:false|False|FALSE)$/;\nconst INTEGER = /^[+-]?\\d+$/;\nconst OCTAL = /^0o[0-7]+$/;\nconst HEXADECIMAL = /^0x[\\dA-Fa-f]+$/;\nconst FLOAT = /^[+-]?(?:\\.\\d+|\\d+(?:\\.\\d*)?)(?:[Ee][+-]?\\d+)?$/;\nconst SPECIAL_FLOAT = /^(?:[+-]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$/;\n\nfunction resolvePlain(text: string, no: number): unknown {\n    if (text === '' || NULL.test(text)) return null;\n    if (TRUE.test(text)) return true;\n    if (FALSE.test(text)) return false;\n    let number: number | undefined;\n    if (INTEGER.test(text) || FLOAT.test(text)) number = Number(text);\n    else if (OCTAL.test(text)) number = Number.parseInt(text.slice(2), 8);\n    else if (HEXADECIMAL.test(text)) number = Number.parseInt(text.slice(2), 16);\n    else if (SPECIAL_FLOAT.test(text)) number = Number.NaN;\n    if (number === undefined) return text;\n    if (!Number.isFinite(number)) throw new FrontmatterError(`\"${text}\" cannot be represented in JSON; quote it`, no);\n    return number;\n}\n\nconst SIMPLE_ESCAPES: Readonly<Record<string, string>> = {\n    '0': '\\0',\n    a: '\\u0007',\n    b: '\\b',\n    t: '\\t',\n    '\\t': '\\t',\n    n: '\\n',\n    v: '\\v',\n    f: '\\f',\n    r: '\\r',\n    e: '\\u001B',\n    ' ': ' ',\n    '\"': '\"',\n    '/': '/',\n    '\\\\': '\\\\',\n    N: '\\u0085',\n    _: '\\u00A0',\n    L: '\\u2028',\n    P: '\\u2029'\n};\n\nconst HEX_ESCAPE_WIDTH: Readonly<Record<string, number>> = { x: 2, u: 4, U: 8 };\n\nconst UNCLOSED_QUOTE = 'a quoted value must close on the same line (multi-line quoted values are not supported)';\n\nfunction readQuoted(text: string, start: number, no: number): { value: string; end: number } {\n    const quote = text[start];\n    let value = '';\n    let index = start + 1;\n    while (index < text.length) {\n        const char = text[index]!;\n        if (quote === \"'\") {\n            if (char === \"'\") {\n                if (text[index + 1] === \"'\") {\n                    value += \"'\";\n                    index += 2;\n                    continue;\n                }\n                return { value, end: index + 1 };\n            }\n            value += char;\n            index++;\n            continue;\n        }\n        if (char === '\"') return { value, end: index + 1 };\n        if (char === '\\\\') {\n            const escape = decodeEscape(text, index, no);\n            value += escape.decoded;\n            index += escape.length;\n            continue;\n        }\n        value += char;\n        index++;\n    }\n    throw new FrontmatterError(UNCLOSED_QUOTE, no);\n}\n\nfunction decodeEscape(text: string, index: number, no: number): { decoded: string; length: number } {\n    const code = text[index + 1];\n    if (code === undefined) throw new FrontmatterError(UNCLOSED_QUOTE, no);\n    const simple = SIMPLE_ESCAPES[code];\n    if (simple !== undefined) return { decoded: simple, length: 2 };\n    const width = HEX_ESCAPE_WIDTH[code];\n    if (width === undefined) throw new FrontmatterError(`unknown escape \"\\\\${code}\"`, no);\n    const hex = text.slice(index + 2, index + 2 + width);\n    if (hex.length !== width || !/^[\\dA-Fa-f]+$/.test(hex) || Number.parseInt(hex, 16) > 0x10_ff_ff) {\n        throw new FrontmatterError(`invalid escape \"\\\\${code}${hex}\"`, no);\n    }\n    return { decoded: String.fromCodePoint(Number.parseInt(hex, 16)), length: 2 + width };\n}\n\nfunction skipSpaces(text: string, index: number): number {\n    let position = index;\n    while (text[position] === ' ' || text[position] === '\\t') position++;\n    return position;\n}\n\nconst UNCLOSED_FLOW = 'a flow collection must close on the same line';\n\nfunction readFlow(text: string, start: number, no: number, depth: number): { value: unknown; end: number } {\n    assertDepth(depth, no);\n    const open = text[start];\n    const close = open === '[' ? ']' : '}';\n    const list: unknown[] = [];\n    const map: Record<string, unknown> = {};\n    let index = skipSpaces(text, start + 1);\n    if (text[index] === close) return { value: open === '[' ? list : map, end: index + 1 };\n    for (;;) {\n        if (open === '[') {\n            const item = readFlowValue(text, index, no, depth);\n            list.push(item.value);\n            index = skipSpaces(text, item.end);\n        } else {\n            const key = readFlowKey(text, index, no);\n            const item = readFlowValue(text, key.end + 1, no, depth);\n            if (Object.hasOwn(map, key.key)) throw new FrontmatterError(`duplicate key \"${key.key}\"`, no);\n            map[key.key] = item.value;\n            index = skipSpaces(text, item.end);\n        }\n        const char = text[index];\n        if (char === ',') {\n            index = skipSpaces(text, index + 1);\n            if (text[index] === close) return { value: open === '[' ? list : map, end: index + 1 };\n            continue;\n        }\n        if (char === close) return { value: open === '[' ? list : map, end: index + 1 };\n        if (char === undefined) throw new FrontmatterError(UNCLOSED_FLOW, no);\n        throw new FrontmatterError(`unexpected \"${char}\" in a flow collection`, no);\n    }\n}\n\nfunction readFlowKey(text: string, start: number, no: number): { key: string; end: number } {\n    const index = skipSpaces(text, start);\n    const char = text[index];\n    if (char === undefined) throw new FrontmatterError(UNCLOSED_FLOW, no);\n    if (char === '\"' || char === \"'\") {\n        const quoted = readQuoted(text, index, no);\n        const colon = skipSpaces(text, quoted.end);\n        if (text[colon] !== ':') throw new FrontmatterError('expected \": \" after a key in a flow mapping', no);\n        return { key: checkKey(quoted.value, no), end: colon };\n    }\n    if (char === '[' || char === '{') throw new FrontmatterError('complex keys (flow collections as keys) are not supported', no);\n    assertFlowPlainStart(text, index, no);\n    const end = scanFlowPlain(text, index);\n    const raw = trimWhiteEnd(text.slice(index, end));\n    const after = text[end + 1];\n    if (raw === '' || text[end] !== ':' || (after !== ' ' && after !== '\\t')) {\n        throw new FrontmatterError('expected \"key: value\" in a flow mapping', no);\n    }\n    return { key: resolveKey(raw, no), end };\n}\n\n// After `-`, `?` or `:`, any of these makes it an indicator in a flow collection.\nconst FLOW_SEPARATORS = ' \\t,[]{}';\n\nfunction assertFlowPlainStart(text: string, index: number, no: number): void {\n    const char = text[index]!;\n    if ('&*!'.includes(char)) throw new FrontmatterError('anchors, aliases and tags are not supported', no);\n    if ('|>%@`#'.includes(char) || ('-?:'.includes(char) && FLOW_SEPARATORS.includes(text[index + 1] ?? ' '))) {\n        throw new FrontmatterError(`\"${char}\" cannot start a plain value in a flow collection; quote it`, no);\n    }\n}\n\n// The end of a plain flow scalar: a flow indicator, a comment or a `:` indicator.\nfunction scanFlowPlain(text: string, index: number): number {\n    let end = index;\n    while (end < text.length) {\n        const char = text[end]!;\n        if (',[]{}'.includes(char)) break;\n        if (char === '#' && (text[end - 1] === ' ' || text[end - 1] === '\\t')) break;\n        if (char === ':' && FLOW_SEPARATORS.includes(text[end + 1] ?? ' ')) break;\n        end++;\n    }\n    return end;\n}\n\nfunction readFlowValue(text: string, start: number, no: number, depth: number): { value: unknown; end: number } {\n    const index = skipSpaces(text, start);\n    const char = text[index];\n    if (char === undefined) throw new FrontmatterError(UNCLOSED_FLOW, no);\n    if (char === '[' || char === '{') return readFlow(text, index, no, depth + 1);\n    if (char === '\"' || char === \"'\") return readQuoted(text, index, no);\n    assertFlowPlainStart(text, index, no);\n    const end = scanFlowPlain(text, index);\n    if (text[end] === ':') throw new FrontmatterError('mappings inside flow collections are not supported; quote the value', no);\n    const raw = trimWhiteEnd(text.slice(index, end));\n    if (raw === '') throw new FrontmatterError('empty value in a flow collection', no);\n    return { value: resolvePlain(raw, no), end };\n}\n\n// Joins block scalar lines as YAML does (the algorithm of js-yaml's readBlockScalar).\nfunction foldBlock(contents: readonly string[], folded: boolean, chomping: string): string {\n    let result = '';\n    let emptyLines = 0;\n    let didReadContent = false;\n    let atMoreIndented = false;\n    for (const content of contents) {\n        if (content === '') {\n            emptyLines++;\n            continue;\n        }\n        if (folded) {\n            if (content.startsWith(' ') || content.startsWith('\\t')) {\n                atMoreIndented = true;\n                result += '\\n'.repeat(didReadContent ? 1 + emptyLines : emptyLines);\n            } else if (atMoreIndented) {\n                atMoreIndented = false;\n                result += '\\n'.repeat(emptyLines + 1);\n            } else if (emptyLines === 0) {\n                if (didReadContent) result += ' ';\n            } else {\n                result += '\\n'.repeat(emptyLines);\n            }\n        } else {\n            result += '\\n'.repeat(didReadContent ? 1 + emptyLines : emptyLines);\n        }\n        result += content;\n        didReadContent = true;\n        emptyLines = 0;\n    }\n    if (chomping === '+') result += '\\n'.repeat(didReadContent ? 1 + emptyLines : emptyLines);\n    else if (chomping === '' && didReadContent) result += '\\n';\n    return result;\n}\n","// WHATWG URL's path percent-encode set, `^` included on every runtime (Node 20 and 22 leave it raw), plus `%`, `/` and `\\`.\nconst ENCODED_IN_SEGMENT = /[^\\w!$&'()*+,.:;=@[\\]|~-]/gu;\n\nfunction encodePathText(text: string): string {\n    return text.replaceAll(ENCODED_IN_SEGMENT, char => encodeURIComponent(char));\n}\n\n/** Percent-encodes one path segment as WHATWG URL does, plus `%`, `/`, `\\` and the dots of `.` and `..`; throws `URIError` on a lone surrogate. */\nexport function encodeSegment(segment: string): string {\n    if (segment === '.' || segment === '..') return segment.replaceAll('.', '%2E');\n    return encodePathText(segment);\n}\n\n/** `text` without its trailing `/`s; a loop, since `/\\/+$/` backtracks polynomially on a long run of `/`. */\nexport function trimTrailingSlashes(text: string): string {\n    let end = text.length;\n    while (end > 0 && text.codePointAt(end - 1) === 0x2f) end--;\n    return text.slice(0, end);\n}\n\n/** `base` (`scheme://`, or a URI without a trailing slash) + `/`-joined encoded segments; an authority is encoded strictly. */\nexport function joinUri(base: string, segments: readonly string[]): string {\n    if (!base.endsWith('://')) return `${trimTrailingSlashes(base)}/${segments.map(segment => encodeSegment(segment)).join('/')}`;\n    const [authority, ...path] = segments;\n    if (authority === undefined) return base;\n    return [base + encodeURIComponent(authority), ...path.map(segment => encodeSegment(segment))].join('/');\n}\n\n/** WHATWG-serialised form of `uri`, or `undefined` if it does not parse. */\nexport function canonicalUri(uri: string): string | undefined {\n    try {\n        return new URL(uri).href;\n    } catch {\n        return undefined;\n    }\n}\n\n/** True when `uri` is already in canonical form. */\nexport function isRoundTripUri(uri: string): boolean {\n    return canonicalUri(uri) === uri;\n}\n\nconst MANIFEST_SUFFIX = '/SKILL.md';\n\n/** The skill's root directory URI (no trailing slash), or `undefined` if `skillMdUri` is not a `…/SKILL.md` URI in a named directory. */\nexport function skillRootUri(skillMdUri: string): string | undefined {\n    const canonical = canonicalUri(skillMdUri);\n    if (canonical === undefined || !canonical.endsWith(MANIFEST_SUFFIX)) return undefined;\n    const root = canonical.slice(0, -MANIFEST_SUFFIX.length);\n    // `scheme:/` or `scheme://` (no directory) and `…//SKILL.md` (an empty last segment) name no directory.\n    return root.endsWith('/') ? undefined : root;\n}\n\nfunction safeDecode(segment: string): string {\n    try {\n        return decodeURIComponent(segment);\n    } catch {\n        return segment;\n    }\n}\n\n/** The decoded last segment of a directory URI (the authority when the path is empty). */\nexport function lastSegmentOf(rootUri: string): string {\n    const url = new URL(rootUri);\n    const path = url.pathname;\n    return safeDecode(path === '' || path === '/' ? url.host : path.slice(path.lastIndexOf('/') + 1));\n}\n\n/** True when `uri` is strictly inside `rootUri` and no segment below it decodes to empty, `.`, `..`, or a name holding `/` or NUL. */\nexport function isWithin(rootUri: string, uri: string): boolean {\n    const canonical = canonicalUri(uri);\n    if (canonical === undefined || !canonical.startsWith(`${rootUri}/`)) return false;\n    return canonical\n        .slice(rootUri.length + 1)\n        .split('/')\n        .every(segment => {\n            const decoded = safeDecode(segment);\n            return decoded !== '' && decoded !== '.' && decoded !== '..' && !decoded.includes('/') && !decoded.includes('\\0');\n        });\n}\n\nfunction decodeOrUndefined(escapes: string): string | undefined {\n    try {\n        return decodeURIComponent(escapes);\n    } catch {\n        return undefined;\n    }\n}\n\nfunction utf8Width(lead: number): number {\n    if (lead >= 0xf0) return 4;\n    if (lead >= 0xe0) return 3;\n    if (lead >= 0xc0) return 2;\n    return 1;\n}\n\n// Each valid UTF-8 sequence is decoded and re-encoded; a `%XX` starting none is a literal `%`, as published (`10%25Dec.md`).\nfunction keyOfEscapes(run: string): string {\n    let key = '';\n    for (let at = 0; at < run.length; ) {\n        const width = 3 * utf8Width(Number.parseInt(run.slice(at + 1, at + 3), 16));\n        const decoded = decodeOrUndefined(run.slice(at, at + width));\n        if (decoded === undefined) {\n            key += `%25${run.slice(at + 1, at + 3)}`;\n            at += 3;\n        } else {\n            key += encodePathText(decoded);\n            at += width;\n        }\n    }\n    return key;\n}\n\n// Runs of `%XX` escapes; splitting on this puts them at odd indexes.\nconst ESCAPE_RUN = /((?:%[\\dA-Fa-f]{2})+)/;\n\nfunction keyOfSegment(segment: string): string {\n    return segment\n        .split(ESCAPE_RUN)\n        .map((part, index) => (index % 2 === 0 ? encodePathText(part) : keyOfEscapes(part)))\n        .join('');\n}\n\n/** The one spelling all ways of writing a file's URI below `rootUri` share (`Q&A.md`, `Q%26A.md#x`); `undefined` if it does not parse. */\nexport function skillFileKey(rootUri: string, uri: string): string | undefined {\n    let url: URL;\n    try {\n        url = new URL(uri);\n    } catch {\n        return undefined;\n    }\n    url.hash = '';\n    const canonical = url.href;\n    // A canonical path never holds a raw `?`, so one here starts a query, even an empty one.\n    if (canonical.includes('?') || !canonical.startsWith(`${rootUri}/`)) return canonical;\n    const below = canonical\n        .slice(rootUri.length + 1)\n        .split('/')\n        .map(segment => keyOfSegment(segment));\n    return `${rootUri}/${below.join('/')}`;\n}\n\n/** Resolves `ref` (default `SKILL.md`) against the skill's root, as a browser resolves a link. */\nexport function resolveSkillRef(skillMdUri: string, ref?: string): string {\n    const root = skillRootUri(skillMdUri);\n    if (root === undefined) throw new TypeError(`${skillMdUri} is not a SKILL.md URI`);\n    return new URL(ref ?? 'SKILL.md', `${root}/`).href;\n}\n\n/** Code-unit order of two URIs: the one order for entries, directory children and cursors. */\nexport function compareUris(a: string, b: string): number {\n    if (a < b) return -1;\n    if (a > b) return 1;\n    return 0;\n}\n","import type { Skill } from '@modelcontextprotocol/core/ext/skills';\nimport { SkillSchema } from '@modelcontextprotocol/core/ext/skills';\n\nimport { decodeUtf8Lossless, sha256Digest } from './bytes';\nimport { FrontmatterError, parseSkillMarkdown } from './frontmatter';\nimport { canonicalUri, compareUris, isWithin, lastSegmentOf, skillFileKey, skillRootUri } from './uri';\n\n/** Agent Skills name rule: lowercase letters, digits and single hyphens (length checked separately). */\nexport const SKILL_NAME_PATTERN = /^[\\da-z]+(?:-[\\da-z]+)*$/;\n\nconst isStringMap = (value: unknown): boolean =>\n    typeof value === 'object' &&\n    value !== null &&\n    !Array.isArray(value) &&\n    Object.values(value as Record<string, unknown>).every(item => typeof item === 'string');\n\n// Agent Skills length limits count characters (code points), not UTF-16 code units.\nfunction countCharacters(text: string): number {\n    let count = 0;\n    for (let index = 0; index < text.length; index += text.codePointAt(index)! > 0xff_ff ? 2 : 1) count++;\n    return count;\n}\n\n/** Structural rules of the stable spec and Agent Skills. Empty array = valid. */\nexport function validateSkillEntry(skill: Skill): string[] {\n    const problems: string[] = [];\n    const root = skillRootUri(skill.uri);\n    if (root === undefined) return [`uri \"${skill.uri}\" must be a URI ending in /SKILL.md inside a named directory`];\n    const frontmatter = skill.frontmatter as Record<string, unknown>;\n    const { name, description } = skill.frontmatter;\n    if (name.length === 0 || name.length > 64 || !SKILL_NAME_PATTERN.test(name)) {\n        problems.push(`frontmatter name \"${name}\" must be 1-64 lowercase letters, digits and single hyphens`);\n    } else if (lastSegmentOf(root) !== name) {\n        problems.push(`frontmatter name \"${name}\" must match the last path segment \"${lastSegmentOf(root)}\"`);\n    }\n    if (description === '' || countCharacters(description) > 1024) problems.push('frontmatter description must be 1-1024 characters');\n    const compatibility = frontmatter['compatibility'];\n    if (\n        compatibility !== undefined &&\n        (typeof compatibility !== 'string' || compatibility === '' || countCharacters(compatibility) > 500)\n    ) {\n        problems.push('frontmatter compatibility must be a string of 1-500 characters');\n    }\n    if (frontmatter['metadata'] !== undefined && !isStringMap(frontmatter['metadata'])) {\n        problems.push('frontmatter metadata must map strings to strings');\n    }\n    if (skill.resources !== 'dynamic') {\n        const self = canonicalUri(skill.uri);\n        const seen = new Set<string>();\n        let hasSelf = false;\n        for (const resource of skill.resources) {\n            const canonical = canonicalUri(resource.uri);\n            if (canonical === undefined) {\n                problems.push(`resource \"${resource.uri}\" is not a valid URI`);\n                continue;\n            }\n            // A canonical URI holds a raw `?` or `#` only as a query or fragment, even an empty one.\n            if (/[#?]/.test(canonical)) {\n                problems.push(`resource \"${resource.uri}\" must not have a query or fragment`);\n                continue;\n            }\n            const key = skillFileKey(root, canonical) ?? canonical;\n            if (seen.has(key)) problems.push(`resource \"${resource.uri}\" is listed more than once`);\n            seen.add(key);\n            if (canonical === self) hasSelf = true;\n            else if (!isWithin(root, resource.uri)) problems.push(`resource \"${resource.uri}\" is outside the skill directory ${root}`);\n        }\n        if (!hasSelf) problems.push(`resources must include ${skill.uri}`);\n    }\n    return problems;\n}\n\n/** Schema check plus {@linkcode validateSkillEntry}, for values received from elsewhere. */\nexport function skillEntryProblems(value: unknown): string[] {\n    const parsed = SkillSchema.safeParse(value);\n    if (!parsed.success) return parsed.error.issues.map(issue => `${issue.path.join('.') || '(entry)'}: ${issue.message}`);\n    return validateSkillEntry(parsed.data);\n}\n\nexport interface SkillFileInput {\n    uri: string;\n    bytes: Uint8Array;\n}\n\n/** Builds an entry from a skill's files: parses `SKILL.md`, hashes every file, sorts by URI, validates. */\nexport async function buildSkillEntry(\n    skillMdUri: string,\n    files: readonly SkillFileInput[]\n): Promise<{ skill?: Skill; problems: string[] }> {\n    const manifest = files.find(file => file.uri === skillMdUri);\n    if (manifest === undefined) return { problems: ['SKILL.md is missing'] };\n    const text = decodeUtf8Lossless(manifest.bytes);\n    if (text === undefined) return { problems: ['SKILL.md is not valid UTF-8'] };\n    let frontmatter: Record<string, unknown>;\n    try {\n        frontmatter = parseSkillMarkdown(text).frontmatter;\n    } catch (error) {\n        if (error instanceof FrontmatterError) return { problems: [`SKILL.md frontmatter: ${error.message}`] };\n        throw error;\n    }\n    if (typeof frontmatter['name'] !== 'string' || typeof frontmatter['description'] !== 'string') {\n        return { problems: ['SKILL.md frontmatter must contain string \"name\" and \"description\"'] };\n    }\n    const resources = await Promise.all(\n        files.map(async file => ({ uri: file.uri, digest: await sha256Digest(file.bytes), size: file.bytes.byteLength }))\n    );\n    resources.sort((a, b) => compareUris(a.uri, b.uri));\n    const skill = { uri: skillMdUri, frontmatter, resources } as Skill;\n    return { skill, problems: validateSkillEntry(skill) };\n}\n","const BY_EXTENSION: Readonly<Record<string, string>> = {\n    md: 'text/markdown',\n    markdown: 'text/markdown',\n    txt: 'text/plain',\n    json: 'application/json',\n    yaml: 'application/yaml',\n    yml: 'application/yaml',\n    py: 'text/x-python',\n    sh: 'application/x-sh',\n    bash: 'application/x-sh',\n    js: 'text/javascript',\n    mjs: 'text/javascript',\n    ts: 'text/typescript',\n    html: 'text/html',\n    css: 'text/css',\n    csv: 'text/csv',\n    xml: 'application/xml',\n    svg: 'image/svg+xml',\n    png: 'image/png',\n    jpg: 'image/jpeg',\n    jpeg: 'image/jpeg',\n    gif: 'image/gif',\n    webp: 'image/webp',\n    pdf: 'application/pdf'\n};\n\n/** MIME type from the file extension; `application/octet-stream` when unknown. */\nexport function mimeTypeFor(fileName: string): string {\n    const dot = fileName.lastIndexOf('.');\n    if (dot <= 0) return 'application/octet-stream';\n    const extension = fileName.slice(dot + 1).toLowerCase();\n    // Own keys only: an inherited name such as `__proto__` or `constructor` is not a MIME type.\n    return Object.hasOwn(BY_EXTENSION, extension) ? BY_EXTENSION[extension]! : 'application/octet-stream';\n}\n","import type { Skill } from '@modelcontextprotocol/core/ext/skills';\nimport { DIRECTORY_MIME_TYPE } from '@modelcontextprotocol/core/ext/skills';\nimport type { Resource } from '@modelcontextprotocol/core-internal';\nimport type { SkillFileInput } from '@modelcontextprotocol/core-internal/ext/skills';\nimport {\n    buildSkillEntry,\n    compareUris,\n    isRoundTripUri,\n    joinUri,\n    mimeTypeFor,\n    sha256Digest,\n    validateSkillEntry\n} from '@modelcontextprotocol/core-internal/ext/skills';\n\nimport { SkillCatalogError } from './errors';\nimport type { SkillFileEntry, SkillFiles, SkillWarning } from './types';\n\nexport interface CatalogFile {\n    readonly path: string;\n    readonly uri: string;\n    readonly size: number;\n    readonly digest: string;\n    readonly mimeType: string;\n}\n\ntype Hashed = Pick<CatalogFile, 'digest' | 'size'>;\n\n// Everything a catalog serves, built once per load or reload: metadata only, never file contents.\nexport interface CatalogSnapshot {\n    readonly ordered: readonly Skill[];\n    readonly skills: ReadonlyMap<string, Skill>;\n    readonly files: ReadonlyMap<string, CatalogFile>;\n    readonly dirs: ReadonlyMap<string, readonly Resource[]>;\n    readonly listed: readonly Resource[];\n}\n\nexport interface CatalogBuildOptions {\n    readonly prefix: readonly string[];\n    readonly limits: { readonly files: number; readonly bytes: number };\n    readonly strict: boolean;\n    readonly warn: (warning: SkillWarning) => void;\n}\n\ninterface TreeEntry {\n    readonly path: string;\n    readonly kind: SkillFileEntry['kind'];\n}\n\ninterface BuiltSkill {\n    readonly dir: string;\n    readonly skill: Skill;\n    readonly files: readonly CatalogFile[];\n    readonly manifestSize: number;\n    // Every entry below the skill's folder, nested skills' included, in tree order.\n    readonly inside: readonly TreeEntry[];\n}\n\ntype UriOf = (path: string) => string;\n\nconst basename = (path: string): string => path.slice(path.lastIndexOf('/') + 1);\n\nconst dirname = (path: string): string => {\n    const slash = path.lastIndexOf('/');\n    return slash === -1 ? '' : path.slice(0, slash);\n};\n\nconst errorText = (error: unknown): string => (error instanceof Error ? error.message : String(error));\n\nconst NOT_FOLLOWED = 'symlinks and other special files are not followed; copy the file instead';\n\n// Any non-directory named exactly `SKILL.md` marks a skill, so a symlinked one is reported rather than ignored.\nconst isManifest = (entry: TreeEntry): boolean => entry.kind !== 'directory' && basename(entry.path) === 'SKILL.md';\n\nfunction append<K, V>(lists: Map<K, V[]>, key: K, value: V): void {\n    const list = lists.get(key);\n    if (list === undefined) lists.set(key, [value]);\n    else list.push(value);\n}\n\n// `undefined` when a name in `path` has no URI form (a lone surrogate, or no round trip).\nfunction representableUri(uriOf: UriOf, path: string): string | undefined {\n    let uri: string;\n    try {\n        uri = uriOf(path);\n    } catch (error) {\n        if (error instanceof URIError) return undefined;\n        throw error;\n    }\n    return isRoundTripUri(uri) ? uri : undefined;\n}\n\n// Every non-hidden entry below the root, depth first; storage errors fail the build.\nasync function walk(files: SkillFiles): Promise<TreeEntry[]> {\n    const tree: TreeEntry[] = [];\n    const visit = async (dir: string): Promise<void> => {\n        let entries: SkillFileEntry[];\n        try {\n            entries = await files.list(dir);\n        } catch (error) {\n            throw new SkillCatalogError([{ path: dir === '' ? '.' : dir, message: `cannot be listed: ${errorText(error)}` }]);\n        }\n        for (const entry of entries.toSorted((a, b) => compareUris(a.name, b.name))) {\n            if (entry.name.startsWith('.')) continue;\n            const path = dir === '' ? entry.name : `${dir}/${entry.name}`;\n            tree.push({ path, kind: entry.kind });\n            if (entry.kind === 'directory') await visit(path);\n        }\n    };\n    await visit('');\n    return tree;\n}\n\nasync function readFile(files: SkillFiles, path: string): Promise<Uint8Array> {\n    try {\n        return await files.read(path);\n    } catch (error) {\n        throw new SkillCatalogError([{ path, message: `cannot be read: ${errorText(error)}` }]);\n    }\n}\n\nexport async function buildCatalogSnapshot(files: SkillFiles, options: CatalogBuildOptions): Promise<CatalogSnapshot> {\n    const tree = await walk(files);\n    const problems: SkillWarning[] = [];\n    const report = (warning: SkillWarning): void => {\n        if (options.strict) problems.push(warning);\n        else options.warn(warning);\n    };\n    const uriOf: UriOf = path => joinUri('skill://', [...options.prefix, ...path.split('/')]);\n\n    for (const entry of tree) {\n        const name = basename(entry.path);\n        if (entry.kind === 'file' && name !== 'SKILL.md' && name.toLowerCase() === 'skill.md') {\n            options.warn({ path: entry.path, message: 'did you mean SKILL.md? File names are case-sensitive' });\n        }\n    }\n\n    // Collect each skill's entries, nested skills' included; a special file outside every skill is reported here.\n    const skillDirs = new Set(tree.filter(entry => isManifest(entry)).map(entry => dirname(entry.path)));\n    const insideOf = new Map<string, TreeEntry[]>();\n    for (const entry of tree) {\n        let inSkill = false;\n        for (let dir = dirname(entry.path); dir !== ''; dir = dirname(dir)) {\n            if (!skillDirs.has(dir)) continue;\n            inSkill = true;\n            append(insideOf, dir, entry);\n        }\n        if (!inSkill && entry.kind === 'unsupported' && !isManifest(entry)) {\n            report({ path: entry.path, message: `${NOT_FOLLOWED} (skipped)` });\n        }\n    }\n\n    const built: BuiltSkill[] = [];\n    const hashed = new Map<string, Hashed>();\n    // Deepest first, so each file is read and hashed once: by the innermost skill that holds it.\n    const manifests = tree.filter(entry => isManifest(entry)).toSorted((a, b) => b.path.split('/').length - a.path.split('/').length);\n    for (const entry of manifests) {\n        const dir = dirname(entry.path);\n        if (dir === '') {\n            report({\n                path: entry.path,\n                message: 'a SKILL.md at the root has no skill path; point loadSkills (or your adapter) at its parent folder (skipped)'\n            });\n            continue;\n        }\n        const skill = await buildOne(files, insideOf.get(dir) ?? [], dir, uriOf, options, report, hashed);\n        if (skill !== undefined) built.push(skill);\n    }\n    if (problems.length > 0) throw new SkillCatalogError(problems);\n    if (built.length === 0) options.warn({ path: '.', message: 'no skills found (a skill is a folder containing SKILL.md)' });\n    return assemble(built, tree, uriOf);\n}\n\nasync function buildOne(\n    files: SkillFiles,\n    inside: readonly TreeEntry[],\n    dir: string,\n    uriOf: UriOf,\n    options: CatalogBuildOptions,\n    report: (warning: SkillWarning) => void,\n    hashed: Map<string, Hashed>\n): Promise<BuiltSkill | undefined> {\n    const unsupported = inside.find(entry => entry.kind === 'unsupported');\n    if (unsupported !== undefined) {\n        report({ path: unsupported.path, message: `${NOT_FOLLOWED} (skill skipped)` });\n        return undefined;\n    }\n    const manifestPath = `${dir}/SKILL.md`;\n    const manifest: SkillFileInput[] = [];\n    const catalogFiles: CatalogFile[] = [];\n    for (const entry of inside) {\n        // Folders too: an empty one's name appears only in its parent's directory listing.\n        const uri = representableUri(uriOf, entry.path);\n        if (uri === undefined) {\n            report({ path: entry.path, message: 'this name cannot be represented in a URI (skill skipped)' });\n            return undefined;\n        }\n        if (entry.kind !== 'file') continue;\n        const own = entry.path === manifestPath;\n        let file = own ? undefined : hashed.get(entry.path);\n        if (file === undefined) {\n            const bytes = await readFile(files, entry.path);\n            if (own) manifest.push({ uri, bytes });\n            file = { digest: await sha256Digest(bytes), size: bytes.byteLength };\n            hashed.set(entry.path, file);\n        }\n        catalogFiles.push({ path: entry.path, uri, ...file, mimeType: mimeTypeFor(basename(entry.path)) });\n    }\n    // Parse SKILL.md on its own, then validate the entry that lists every file's digest.\n    const parsed = await buildSkillEntry(uriOf(manifestPath), manifest);\n    const resources = catalogFiles.map(({ uri, digest, size }) => ({ uri, digest, size })).toSorted((a, b) => compareUris(a.uri, b.uri));\n    const skill = parsed.skill === undefined ? undefined : { ...parsed.skill, resources };\n    const problems = skill === undefined ? parsed.problems : validateSkillEntry(skill);\n    if (skill === undefined || problems.length > 0) {\n        for (const message of problems) report({ path: manifestPath, message: `${message} (skill skipped)` });\n        return undefined;\n    }\n    let totalBytes = 0;\n    for (const file of catalogFiles) totalBytes += file.size;\n    if (catalogFiles.length > options.limits.files || totalBytes > options.limits.bytes) {\n        const remedy = options.strict ? 'Raise limits to allow it' : 'Set strict: true to fail instead, or raise limits';\n        report({\n            path: dir,\n            message:\n                `${catalogFiles.length} files / ${totalBytes} bytes exceeds the limit of ${options.limits.files} files / ` +\n                `${options.limits.bytes} bytes; some hosts may decline it. ${remedy}`\n        });\n    }\n    const manifestSize = catalogFiles.find(file => file.path === manifestPath)?.size ?? 0;\n    return { dir, skill, files: catalogFiles, manifestSize, inside };\n}\n\nfunction deepFreeze<T>(value: T): T {\n    if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {\n        Object.freeze(value);\n        for (const item of Object.values(value)) deepFreeze(item);\n    }\n    return value;\n}\n\nfunction assemble(built: readonly BuiltSkill[], tree: readonly TreeEntry[], uriOf: UriOf): CatalogSnapshot {\n    // Frozen: entries are served unchecked and handed out by `entries`, so an edit must throw, not reach clients.\n    const ordered = Object.freeze(built.map(item => deepFreeze(item.skill)).toSorted((a, b) => compareUris(a.uri, b.uri)));\n    const files = new Map<string, CatalogFile>();\n    const dirPaths = new Set<string>();\n    for (const item of built) {\n        for (const file of item.files) files.set(file.uri, file);\n        dirPaths.add(item.dir);\n        for (const entry of item.inside) {\n            if (entry.kind === 'directory') dirPaths.add(entry.path);\n        }\n    }\n    const childrenOf = new Map<string, TreeEntry[]>();\n    for (const entry of tree) append(childrenOf, dirname(entry.path), entry);\n    const dirs = new Map<string, Resource[]>();\n    for (const dirPath of dirPaths) {\n        const children: Resource[] = [];\n        for (const entry of childrenOf.get(dirPath) ?? []) {\n            if (entry.kind === 'directory') {\n                children.push({ uri: uriOf(entry.path), name: basename(entry.path), mimeType: DIRECTORY_MIME_TYPE });\n                continue;\n            }\n            const file = files.get(uriOf(entry.path));\n            if (entry.kind === 'file' && file !== undefined) {\n                children.push({ uri: file.uri, name: basename(entry.path), mimeType: file.mimeType, size: file.size });\n            }\n        }\n        children.sort((a, b) => compareUris(a.uri, b.uri));\n        dirs.set(uriOf(dirPath), children);\n    }\n    const listed = built\n        .map(item => ({\n            uri: item.skill.uri,\n            name: item.skill.frontmatter.name,\n            description: item.skill.frontmatter.description,\n            mimeType: 'text/markdown',\n            size: item.manifestSize\n        }))\n        .toSorted((a, b) => compareUris(a.uri, b.uri));\n    return { ordered, skills: new Map(ordered.map(skill => [skill.uri, skill])), files, dirs, listed };\n}\n","import type { SkillSource } from './types';\n\n// Sources whose entries the SDK built itself, so they are not re-validated per request.\nexport const trustedSources = new WeakSet<SkillSource>();\n","import { ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/core-internal';\nimport { compareUris, decodeBase64, decodeUtf8Lossless, encodeBase64, encodeUtf8 } from '@modelcontextprotocol/core-internal/ext/skills';\n\nconst CURSOR_PREFIX = 'after:';\n\n// An opaque, URL-safe cursor meaning \"after this URI\".\nexport function encodeCursor(uri: string): string {\n    return encodeBase64(encodeUtf8(CURSOR_PREFIX + uri))\n        .replaceAll('+', '-')\n        .replaceAll('/', '_')\n        .replace(/=+$/, '');\n}\n\n// The URI a cursor points after, or `undefined` when it is not one of ours.\nexport function decodeCursor(cursor: string): string | undefined {\n    try {\n        const base64 = cursor.replaceAll('-', '+').replaceAll('_', '/');\n        const decoded = decodeUtf8Lossless(decodeBase64(base64 + '='.repeat((4 - (base64.length % 4)) % 4)));\n        return decoded?.startsWith(CURSOR_PREFIX) ? decoded.slice(CURSOR_PREFIX.length) : undefined;\n    } catch {\n        return undefined;\n    }\n}\n\n// One page of URI-sorted `items` after `cursor`; entries added or removed elsewhere never shift the boundary.\nexport function paginate<T>(\n    items: readonly T[],\n    cursor: string | undefined,\n    pageSize: number,\n    key: (item: T) => string\n): { items: T[]; nextCursor?: string } {\n    let start = 0;\n    if (cursor !== undefined) {\n        const after = decodeCursor(cursor);\n        if (after === undefined) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid cursor');\n        start = items.findIndex(item => compareUris(key(item), after) > 0);\n        if (start === -1) start = items.length;\n    }\n    const end = Math.min(items.length, start + pageSize);\n    const page = items.slice(start, end);\n    const last = page.at(-1);\n    return end < items.length && last !== undefined ? { items: page, nextCursor: encodeCursor(key(last)) } : { items: page };\n}\n\nexport function resolvePageSize(pageSize: number | undefined): number {\n    if (pageSize === undefined) return 100;\n    if (pageSize === Number.POSITIVE_INFINITY || (Number.isSafeInteger(pageSize) && pageSize > 0)) return pageSize;\n    throw new RangeError(`pageSize must be a positive integer or Infinity (got ${pageSize})`);\n}\n","import { ProtocolError, ProtocolErrorCode, ResourceNotFoundError } from '@modelcontextprotocol/core-internal';\nimport { canonicalUri, decodeUtf8Lossless, sha256Digest } from '@modelcontextprotocol/core-internal/ext/skills';\n\nimport type { CatalogSnapshot } from './catalogBuild';\nimport { trustedSources } from './internal';\nimport { paginate } from './paging';\nimport type { SkillFiles, SkillReadResult, SkillSource, SkillWarning } from './types';\n\n// `reload()` swaps `current` in one assignment.\nexport interface CatalogState {\n    current: CatalogSnapshot;\n}\n\nconst errorText = (error: unknown): string => (error instanceof Error ? error.message : String(error));\n\n// A trusted source: the SDK built and checked the snapshot's entries.\nexport function catalogSource(\n    state: CatalogState,\n    files: SkillFiles,\n    pageSize: number,\n    warn: (warning: SkillWarning) => void\n): SkillSource {\n    const source: SkillSource = {\n        async list({ cursor }) {\n            const page = paginate(state.current.ordered, cursor, pageSize, skill => skill.uri);\n            return page.nextCursor === undefined ? { skills: page.items } : { skills: page.items, nextCursor: page.nextCursor };\n        },\n        async get(uri) {\n            const canonical = canonicalUri(uri);\n            return canonical === undefined ? undefined : state.current.skills.get(canonical);\n        },\n        read: uri => readChecked(state.current, files, uri, warn),\n        async readDirectory(uri, { cursor }) {\n            const canonical = canonicalUri(uri);\n            const children = canonical === undefined ? undefined : state.current.dirs.get(canonical);\n            if (children === undefined) return;\n            const page = paginate(children, cursor, pageSize, child => child.uri);\n            return page.nextCursor === undefined ? { resources: page.items } : { resources: page.items, nextCursor: page.nextCursor };\n        },\n        async listResources() {\n            return [...state.current.listed];\n        }\n    };\n    trustedSources.add(source);\n    return source;\n}\n\n// Reads a published file through the adapter and serves it only if it still matches its entry.\nasync function readChecked(\n    snapshot: CatalogSnapshot,\n    files: SkillFiles,\n    uri: string,\n    warn: (warning: SkillWarning) => void\n): Promise<SkillReadResult | undefined> {\n    const canonical = canonicalUri(uri);\n    const file = canonical === undefined ? undefined : snapshot.files.get(canonical);\n    if (file === undefined) {\n        if (canonical !== undefined && snapshot.dirs.has(canonical)) {\n            throw new ResourceNotFoundError(uri, `${uri} is a directory; use resources/directory/read`);\n        }\n        return undefined;\n    }\n    let bytes: Uint8Array;\n    try {\n        bytes = await files.read(file.path);\n    } catch (error) {\n        warn({ path: file.path, message: `could not be read: ${errorText(error)}` });\n        throw new ProtocolError(ProtocolErrorCode.InternalError, `${uri} could not be read`);\n    }\n    if (bytes.byteLength !== file.size || (await sha256Digest(bytes)) !== file.digest) {\n        warn({ path: file.path, message: 'changed since the catalog was loaded; call reload()' });\n        throw new ProtocolError(ProtocolErrorCode.InternalError, `${uri} changed since the skills catalog was loaded`);\n    }\n    // Spec §5: `text` whenever the bytes decode losslessly as UTF-8, whatever the MIME type; otherwise a base64 `blob`.\n    const text = decodeUtf8Lossless(bytes);\n    return text === undefined ? { bytes, mimeType: file.mimeType } : { text, mimeType: file.mimeType };\n}\n","import { encodeUtf8 } from '@modelcontextprotocol/core-internal/ext/skills';\n\nimport type { SkillFileEntry, SkillFiles } from './types';\n\n// Splits a relative `/`-separated path, rejecting `..` and empty paths.\nexport function splitRelativePath(path: string, label: string): string[] {\n    const segments = path.split('/').filter(segment => segment !== '' && segment !== '.');\n    if (segments.length === 0 || segments.includes('..')) {\n        throw new TypeError(`${label} must be a relative path without \"..\" (got ${JSON.stringify(path)})`);\n    }\n    return segments;\n}\n\n// A memory record's directories and files, by normalised path.\ninterface MemoryIndex {\n    // Children of every directory (`''` is the root), in record order.\n    readonly dirs: ReadonlyMap<string, ReadonlyMap<string, SkillFileEntry>>;\n    // The record key that holds each file.\n    readonly files: ReadonlyMap<string, string>;\n}\n\nfunction indexRecord(keys: readonly string[]): MemoryIndex {\n    const dirs = new Map<string, Map<string, SkillFileEntry>>();\n    const files = new Map<string, string>();\n    for (const key of keys) {\n        const segments = splitRelativePath(key, 'file path');\n        let dir = '';\n        for (const [depth, name] of segments.entries()) {\n            let children = dirs.get(dir);\n            if (children === undefined) {\n                children = new Map();\n                dirs.set(dir, children);\n            }\n            children.set(name, { name, kind: depth < segments.length - 1 ? 'directory' : 'file' });\n            dir = dir === '' ? name : `${dir}/${name}`;\n        }\n        files.set(dir, key);\n    }\n    return { dirs, files };\n}\n\n/**\n * An in-memory adapter. The record is re-read whenever a walk starts — `list('')` — so `reload()` sees later changes.\n * Other calls use the index from that read (built on first use if no walk has started), so their cost does not grow\n * with the record. File contents are always read live.\n */\nexport function memorySkillFiles(files: Record<string, string | Uint8Array>): SkillFiles {\n    let index: MemoryIndex | undefined;\n    const reindex = (): MemoryIndex => {\n        index = indexRecord(Object.keys(files));\n        return index;\n    };\n    return {\n        async list(dir) {\n            const children = (dir === '' ? reindex() : (index ?? reindex())).dirs.get(dir);\n            if (children !== undefined) return Array.from(children.values(), entry => ({ ...entry }));\n            if (dir === '') return [];\n            throw new Error(`no such directory: ${dir}`);\n        },\n        async read(path) {\n            // Keys written as `./a/b` or `a//b` are found through the index.\n            const key = Object.hasOwn(files, path) ? path : (index ?? reindex()).files.get(path);\n            const content = key === undefined ? undefined : files[key];\n            if (content === undefined) throw new Error(`no such file: ${path}`);\n            return typeof content === 'string' ? encodeUtf8(content) : content;\n        }\n    };\n}\n","import type { Skill } from '@modelcontextprotocol/core/ext/skills';\nimport {\n    GetSkillRequestParamsSchema,\n    ListSkillsRequestParamsSchema,\n    ReadResourceDirectoryRequestParamsSchema,\n    RESOURCES_DIRECTORY_READ_METHOD,\n    SKILL_LIMITS,\n    SKILLS_EXTENSION_ID,\n    SKILLS_GET_METHOD,\n    SKILLS_LIST_METHOD\n} from '@modelcontextprotocol/core/ext/skills';\nimport type { CacheHint, ListResourcesResult, ReadResourceResult, ServerContext } from '@modelcontextprotocol/core-internal';\nimport {\n    assertValidCacheHint,\n    isModernProtocolVersion,\n    ProtocolError,\n    ProtocolErrorCode,\n    ResourceNotFoundError\n} from '@modelcontextprotocol/core-internal';\nimport {\n    canonicalUri,\n    encodeBase64,\n    joinUri,\n    skillEntryProblems,\n    trimTrailingSlashes\n} from '@modelcontextprotocol/core-internal/ext/skills';\n\nimport type { McpServer } from '../../server/mcp';\nimport { ResourceTemplate } from '../../server/mcp';\nimport type { Server } from '../../server/server';\nimport type { CatalogBuildOptions, CatalogSnapshot } from './catalogBuild';\nimport { buildCatalogSnapshot } from './catalogBuild';\nimport type { CatalogState } from './catalogSource';\nimport { catalogSource } from './catalogSource';\nimport { defaultWarn } from './errors';\nimport { splitRelativePath } from './files';\nimport { trustedSources } from './internal';\nimport { resolvePageSize } from './paging';\nimport type {\n    SkillCatalogChanges,\n    SkillCatalogOptions,\n    SkillFiles,\n    SkillReadResult,\n    SkillSource,\n    SkillSourceOptions,\n    SkillWarning\n} from './types';\n\nconst SCHEME_URI = /^[a-z][\\d+.a-z-]*:\\/\\//i;\n\nfunction describeEntry(value: unknown): string {\n    const uri = (value as { uri?: unknown } | null)?.uri;\n    return typeof uri === 'string' ? uri : '(entry without a uri)';\n}\n\nfunction toContents(uri: string, result: SkillReadResult): ReadResourceResult['contents'][number] {\n    const mimeType = result.mimeType === undefined ? {} : { mimeType: result.mimeType };\n    return 'text' in result ? { uri, ...mimeType, text: result.text } : { uri, ...mimeType, blob: encodeBase64(result.bytes) };\n}\n\n// Servers with a skills extension attached: one per server, as SEP-3371 rejects a duplicate extension identifier.\nconst skillsServers = new WeakSet<McpServer>();\n\n// Runs after a successful `attach`, by extension (`SkillCatalog` tracks servers); off the class so no subclass hooks it.\nconst afterAttach = new WeakMap<SkillsExtension, (mcp: McpServer) => void>();\n\nconst ONE_PER_SERVER =\n    'another skills extension is already attached to this server; attach one per server ' +\n    '(to serve several folders or sources, combine them behind one SkillFiles adapter or SkillSource)';\n\n/**\n * The MCP Skills extension (SEP-2640) for one catalog of skills. One instance\n * serves any number of servers: call {@linkcode SkillsExtension.attach} on each\n * (before connecting). Build it from a {@linkcode SkillSource}, or with\n * `SkillsExtension.load(files)` from storage.\n */\nexport class SkillsExtension {\n    readonly id = SKILLS_EXTENSION_ID;\n    readonly #source: SkillSource;\n    readonly #trusted: boolean;\n    readonly #baseRoot: string;\n    readonly #cacheHint: CacheHint | undefined;\n    readonly #cache: { ttlMs: number; cacheScope: 'public' | 'private' };\n    readonly #strict: boolean;\n    readonly #warn: (warning: SkillWarning) => void;\n    readonly #attached = new WeakSet<McpServer>();\n\n    /**\n     * Builds a catalog from storage through a {@linkcode SkillFiles} adapter\n     * (`memorySkillFiles`, `nodeSkillFiles`, or your own).\n     */\n    static load(files: SkillFiles, options?: SkillCatalogOptions): Promise<SkillCatalog> {\n        return SkillCatalog.load(files, options);\n    }\n\n    constructor(options: SkillSourceOptions) {\n        if (options.cacheHint !== undefined) assertValidCacheHint(options.cacheHint, 'skills cacheHint');\n        const baseUri = options.baseUri ?? 'skill://';\n        // Canonical, like the request URIs that the template and the listResources filter are matched against.\n        const canonical = SCHEME_URI.test(baseUri) ? canonicalUri(baseUri) : undefined;\n        if (canonical === undefined) throw new TypeError(`baseUri must be a \"scheme://…\" URI (got ${JSON.stringify(baseUri)})`);\n        this.#baseRoot = canonical.endsWith('://') ? canonical : `${trimTrailingSlashes(canonical)}/`;\n        this.#source = options.source;\n        this.#trusted = trustedSources.has(options.source);\n        this.#cacheHint = options.cacheHint;\n        this.#cache = { ttlMs: options.cacheHint?.ttlMs ?? 0, cacheScope: options.cacheHint?.cacheScope ?? 'private' };\n        this.#strict = options.strict ?? false;\n        this.#warn = options.onWarning ?? defaultWarn;\n    }\n\n    /**\n     * Serves these skills on `mcp`: registers the skill resource template and\n     * the skills methods, then declares the capability. Must run before\n     * connecting. Calling it again for the same server does nothing. One\n     * skills extension per server: attaching another one throws and leaves the\n     * server as it was, as does attaching to a server that already handles one\n     * of the skills methods.\n     *\n     * @experimental How an extension is wired to a server may change in a minor release.\n     */\n    attach(mcp: McpServer): void {\n        if (this.#attached.has(mcp)) return;\n        if (mcp.isConnected()) throw new Error('attach skills before connecting the server');\n        if (skillsServers.has(mcp)) throw new Error(ONE_PER_SERVER);\n        const server = mcp.server;\n        const directoryRead = this.#source.readDirectory !== undefined;\n        const list = this.#source.listResources === undefined ? undefined : (ctx: ServerContext) => this.#listResources(ctx);\n        server.assertCanSetRequestHandler(SKILLS_LIST_METHOD);\n        server.assertCanSetRequestHandler(SKILLS_GET_METHOD);\n        if (directoryRead) server.assertCanSetRequestHandler(RESOURCES_DIRECTORY_READ_METHOD);\n        // Check before changing anything; declare the capability last, so a server never advertises skills it does not serve.\n        mcp.registerResource(\n            SKILLS_EXTENSION_ID,\n            new ResourceTemplate(`${this.#baseRoot}{+path}`, { list }),\n            this.#cacheHint === undefined ? {} : { cacheHint: this.#cacheHint },\n            (uri, _variables, ctx) => this.#read(uri, ctx)\n        );\n        server.setRequestHandler(SKILLS_LIST_METHOD, { params: ListSkillsRequestParamsSchema }, (params, ctx) =>\n            this.#list(server, params.cursor, ctx)\n        );\n        server.setRequestHandler(SKILLS_GET_METHOD, { params: GetSkillRequestParamsSchema }, (params, ctx) =>\n            this.#get(server, params.uri, ctx)\n        );\n        if (directoryRead) {\n            server.setRequestHandler(RESOURCES_DIRECTORY_READ_METHOD, { params: ReadResourceDirectoryRequestParamsSchema }, (params, ctx) =>\n                this.#readDirectory(server, params.uri, params.cursor, ctx)\n            );\n        }\n        server.registerCapabilities({ extensions: { [SKILLS_EXTENSION_ID]: directoryRead ? { directoryRead: true } : {} } });\n        this.#attached.add(mcp);\n        skillsServers.add(mcp);\n        afterAttach.get(this)?.(mcp);\n    }\n\n    #cacheFields(server: Server): { ttlMs?: number; cacheScope?: 'public' | 'private' } {\n        return isModernProtocolVersion(server.getNegotiatedProtocolVersion() ?? '') ? { ...this.#cache } : {};\n    }\n\n    #keepValid(skills: readonly Skill[]): Skill[] {\n        if (this.#trusted) return [...skills];\n        const kept: Skill[] = [];\n        for (const candidate of skills) {\n            const problems = skillEntryProblems(candidate);\n            if (problems.length === 0) {\n                kept.push(candidate);\n                continue;\n            }\n            const message = `invalid skill entry from the source: ${problems.join('; ')}`;\n            if (this.#strict) throw new ProtocolError(ProtocolErrorCode.InternalError, `${describeEntry(candidate)}: ${message}`);\n            this.#warn({ path: describeEntry(candidate), message: `${message} (dropped from skills/list)` });\n        }\n        return kept;\n    }\n\n    async #list(server: Server, cursor: string | undefined, ctx: ServerContext) {\n        const page = await this.#source.list(cursor === undefined ? {} : { cursor }, ctx);\n        return {\n            skills: this.#keepValid(page.skills),\n            ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n            ...this.#cacheFields(server)\n        };\n    }\n\n    async #get(server: Server, uri: string, ctx: ServerContext) {\n        const skill = await this.#source.get(uri, ctx);\n        if (skill === undefined) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `No skill is served at ${uri}`);\n        if (!this.#trusted) {\n            const problems = skillEntryProblems(skill);\n            if (problems.length > 0) {\n                const message = `invalid skill entry from the source: ${problems.join('; ')}`;\n                this.#warn({ path: uri, message });\n                throw new ProtocolError(ProtocolErrorCode.InternalError, message);\n            }\n        }\n        if (canonicalUri(skill.uri) !== canonicalUri(uri)) {\n            throw new ProtocolError(ProtocolErrorCode.InternalError, `the skill source returned ${skill.uri} for ${uri}`);\n        }\n        return { skill, ...this.#cacheFields(server) };\n    }\n\n    async #read(uri: URL, ctx: ServerContext): Promise<ReadResourceResult> {\n        const result = await this.#source.read(uri.href, ctx);\n        if (result === undefined) throw new ResourceNotFoundError(uri.href);\n        return { contents: [toContents(uri.href, result)] };\n    }\n\n    async #readDirectory(server: Server, uri: string, cursor: string | undefined, ctx: ServerContext) {\n        const page = await this.#source.readDirectory!(uri, cursor === undefined ? {} : { cursor }, ctx);\n        if (page === undefined) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `${uri} is not a directory resource`);\n        return {\n            resources: page.resources,\n            ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n            ...this.#cacheFields(server)\n        };\n    }\n\n    async #listResources(ctx: ServerContext): Promise<ListResourcesResult> {\n        const resources = await this.#source.listResources!(ctx);\n        const kept = [];\n        for (const resource of resources) {\n            if (canonicalUri(resource.uri)?.startsWith(this.#baseRoot)) kept.push(resource);\n            else\n                this.#warn({\n                    path: resource.uri,\n                    message: `listResources returned a URI outside ${this.#baseRoot}; dropped from resources/list`\n                });\n        }\n        return { resources: kept };\n    }\n}\n\ninterface CatalogInit {\n    readonly state: CatalogState;\n    readonly files: SkillFiles;\n    readonly build: CatalogBuildOptions;\n    readonly sourceOptions: SkillSourceOptions;\n}\n\n// Fewest tracked servers at which `attach` drops references to collected ones; then again at twice the survivors.\nconst PRUNE_THRESHOLD = 1024;\n\nfunction resolveLimits(limits: SkillCatalogOptions['limits']): { files: number; bytes: number } {\n    const resolved = { files: limits?.files ?? SKILL_LIMITS.files, bytes: limits?.bytes ?? SKILL_LIMITS.bytes };\n    for (const [name, value] of Object.entries(resolved)) {\n        if (value !== Number.POSITIVE_INFINITY && !(Number.isSafeInteger(value) && value > 0)) {\n            throw new RangeError(`limits.${name} must be a positive integer or Infinity (got ${value})`);\n        }\n    }\n    return resolved;\n}\n\n// What `resources/list_changed` is about: which skills exist, and each one's name and description.\nfunction listingKey(snapshot: CatalogSnapshot): string {\n    return JSON.stringify(snapshot.listed.map(resource => [resource.uri, resource.name, resource.description]));\n}\n\nfunction diffSnapshots(previous: CatalogSnapshot, next: CatalogSnapshot): Omit<SkillCatalogChanges, 'listChanged'> {\n    const same = (uri: string): boolean => JSON.stringify(previous.skills.get(uri)) === JSON.stringify(next.skills.get(uri));\n    return {\n        added: [...next.skills.keys()].filter(uri => !previous.skills.has(uri)),\n        removed: [...previous.skills.keys()].filter(uri => !next.skills.has(uri)),\n        changed: [...next.skills.keys()].filter(uri => previous.skills.has(uri) && !same(uri))\n    };\n}\n\n/**\n * A catalog the SDK built from storage. It holds metadata only: every file\n * read goes through the adapter and is checked against the published entry.\n */\nexport class SkillCatalog extends SkillsExtension {\n    readonly #state: CatalogState;\n    readonly #files: SkillFiles;\n    readonly #build: CatalogBuildOptions;\n    readonly #servers = new Set<WeakRef<McpServer>>();\n    #pruneAt = PRUNE_THRESHOLD;\n    #queue: Promise<unknown> = Promise.resolve();\n\n    private constructor(init: CatalogInit) {\n        super(init.sourceOptions);\n        this.#state = init.state;\n        this.#files = init.files;\n        this.#build = init.build;\n        afterAttach.set(this, mcp => this.#track(mcp));\n    }\n\n    static override async load(files: SkillFiles, options: SkillCatalogOptions = {}): Promise<SkillCatalog> {\n        const pageSize = resolvePageSize(options.pageSize);\n        const build: CatalogBuildOptions = {\n            prefix: options.prefix === undefined ? [] : splitRelativePath(options.prefix, 'prefix'),\n            limits: resolveLimits(options.limits),\n            strict: options.strict ?? false,\n            warn: options.onWarning ?? defaultWarn\n        };\n        const state: CatalogState = { current: await buildCatalogSnapshot(files, build) };\n        return new SkillCatalog({\n            state,\n            files,\n            build,\n            sourceOptions: {\n                source: catalogSource(state, files, pageSize, build.warn),\n                baseUri: build.prefix.length === 0 ? 'skill://' : joinUri('skill://', build.prefix),\n                cacheHint: options.cacheHint,\n                strict: options.strict,\n                onWarning: build.warn\n            }\n        });\n    }\n\n    /** The skills this catalog serves, sorted by URI. Frozen (deeply): they are exactly what clients receive. */\n    get entries(): readonly Skill[] {\n        return this.#state.current.ordered;\n    }\n\n    /**\n     * Scans the storage again and swaps the new catalog in at once. All or\n     * nothing: on failure the old catalog keeps serving. Overlapping calls run\n     * one after another.\n     *\n     * When skills are added or removed, or a `SKILL.md`'s name or description\n     * changes, the result has `listChanged: true` and `resources/list_changed`\n     * goes out through every attached server that is still connected (stdio,\n     * stateful 2025-11-25 HTTP sessions). Servers that `createMcpHandler` builds per\n     * request are closed by then, so publish the change on the handler:\n     * `if (changes.listChanged) handler.notify.resourcesChanged()`. Where the\n     * runtime has no `WeakRef` (Cloudflare Workers with a compatibility date\n     * before 2025-05-05), attached servers are not tracked and nothing is sent.\n     */\n    reload(): Promise<SkillCatalogChanges> {\n        const run = this.#queue.then(() => this.#reloadNow());\n        this.#queue = run.then(\n            () => {},\n            () => {}\n        );\n        return run;\n    }\n\n    #track(mcp: McpServer): void {\n        // Without WeakRef, holding servers strongly would keep every per-request server alive; track none instead.\n        if (typeof WeakRef !== 'function') return;\n        if (this.#servers.size >= this.#pruneAt) {\n            for (const reference of this.#servers) if (reference.deref() === undefined) this.#servers.delete(reference);\n            this.#pruneAt = Math.max(PRUNE_THRESHOLD, 2 * this.#servers.size);\n        }\n        this.#servers.add(new WeakRef(mcp));\n    }\n\n    async #reloadNow(): Promise<SkillCatalogChanges> {\n        const previous = this.#state.current;\n        const next = await buildCatalogSnapshot(this.#files, this.#build);\n        this.#state.current = next;\n        const listChanged = listingKey(previous) !== listingKey(next);\n        if (listChanged) this.#notify();\n        return { ...diffSnapshots(previous, next), listChanged };\n    }\n\n    // A send that fails becomes a warning: never an unhandled rejection, and never a reason to skip the other servers.\n    #notify(): void {\n        for (const reference of this.#servers) {\n            const mcp = reference.deref();\n            if (mcp === undefined) {\n                this.#servers.delete(reference);\n                continue;\n            }\n            if (!mcp.isConnected()) continue;\n            const sessionId = mcp.server.transport?.sessionId;\n            try {\n                // `Server.sendResourceListChanged` is async; `Promise.resolve` also covers a synchronous return.\n                Promise.resolve(mcp.server.sendResourceListChanged()).catch((error: unknown) => this.#notifyFailed(sessionId, error));\n            } catch (error) {\n                this.#notifyFailed(sessionId, error);\n            }\n        }\n    }\n\n    #notifyFailed(sessionId: string | undefined, error: unknown): void {\n        const to = sessionId === undefined ? '' : ` to session ${sessionId}`;\n        const reason = error instanceof Error ? error.message : String(error);\n        try {\n            this.#build.warn({ path: 'resources/list_changed', message: `could not be sent${to}: ${reason}` });\n        } catch {\n            // A throwing onWarning must not escape either: it would reject reload() or go unhandled.\n        }\n    }\n}\n"],"mappings":";;;;;;;;;AAQA,IAAa,oBAAb,cAAuC,MAAM;CACzC;AACI,SAAO,eAAe,MAAM,YAAY,EAAE,OAAO,yBAAyB,CAAC;;CAG/E,QAAiB,OAAO,aAAa,OAAyB;AAC1D,SAAO,mBAAmB,MAAM,MAAM;;;;;;;;CAS1C,OAAO,WAA0E,OAA0C;AACvH,MAAI,OAAO,SAAS,WAChB,OAAM,IAAI,UACN,gJACH;AAEL,SAAO,mBAAmB,MAAM,MAAM;;CAG1C,AAAS;CAET,YAAY,UAAmC;EAC3C,MAAM,QAAQ,SAAS,KAAI,YAAW,KAAK,QAAQ,KAAK,IAAI,QAAQ,UAAU,CAAC,KAAK,KAAK;AACzF,QAAM,GAAG,SAAS,OAAO,gBAAgB,SAAS,WAAW,IAAI,KAAK,IAAI,KAAK,QAAQ;AACvF,OAAK,OAAO;AACZ,OAAK,WAAW;AAChB,mBAAiB,MAAM,IAAI,OAAO;;;AAK1C,SAAgB,YAAY,SAA6B;AAErD,SAAQ,KAAK,qBAAqB,QAAQ,KAAK,IAAI,QAAQ,UAAU;;;;;AC9CzE,MAAM,UAAU,IAAI,aAAa;;AAGjC,SAAgB,WAAW,MAA0B;AACjD,QAAO,QAAQ,OAAO,KAAK;;;AAI/B,SAAgB,mBAAmB,OAAuC;AACtE,KAAI;AACA,SAAO,IAAI,YAAY,SAAS;GAAE,OAAO;GAAM,WAAW;GAAM,CAAC,CAAC,OAAO,MAAM;SAC3E;AACJ;;;;AAKR,SAAgB,aAAa,OAA2B;CACpD,IAAI,SAAS;CACb,MAAM,QAAQ;AACd,MAAK,IAAI,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,MAClD,WAAU,OAAO,cAAc,GAAG,MAAM,SAAS,QAAQ,SAAS,MAAM,CAAC;AAE7E,QAAO,KAAK,OAAO;;;AAIvB,SAAgB,aAAa,QAA4B;CACrD,MAAM,SAAS,KAAK,OAAO;CAC3B,MAAM,QAAQ,IAAI,WAAW,OAAO,OAAO;AAC3C,MAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,QAAS,OAAM,SAAS,OAAO,YAAY,MAAM;AAC5F,QAAO;;;AAIX,eAAsB,aAAa,OAAoC;CACnE,MAAM,EAAE,QAAQ,YAAY,eAAe;CAE3C,MAAM,OAAO,kBAAkB,cAAc,IAAI,WAAW,QAAQ,YAAY,WAAW,GAAG,IAAI,WAAW,MAAM;CACnH,MAAM,OAAO,IAAI,WAAW,MAAM,WAAW,OAAO,OAAO,OAAO,WAAW,KAAK,CAAC;CACnF,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,KAAM,QAAO,KAAK,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI;AAClE,QAAO,UAAU;;;;;;;;;;;;;;;AC/BrB,IAAa,mBAAb,cAAsC,MAAM;CACxC,AAAS;CAET,YAAY,SAAiB,MAAe;AACxC,QAAM,SAAS,SAAY,UAAU,QAAQ,KAAK,IAAI,UAAU;AAChE,OAAK,OAAO;AACZ,OAAK,OAAO;;;AAgBpB,MAAM,YAAY;;AAGlB,SAAgB,iBAAiB,UAAsC;CACnE,IAAI,OAAO,SAAS,WAAW,QAAQ,KAAK;AAC5C,KAAI,KAAK,YAAY,EAAE,KAAK,MAAS,QAAO,KAAK,MAAM,EAAE;AACzD,KAAI,CAAC,KAAK,WAAW,QAAQ,CAAE,OAAM,IAAI,iBAAiB,2CAAyC,EAAE;CACrG,MAAM,OAAO,KAAK,MAAM,EAAE;CAC1B,MAAM,QAAQ,eAAe,KAAK,KAAK;AACvC,KAAI,UAAU,KAAM,OAAM,IAAI,iBAAiB,0CAAwC;CACvF,IAAI,OAAO,KAAK,MAAM,MAAM,QAAQ,MAAM,GAAG,OAAO;AACpD,KAAI,KAAK,WAAW,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE;AAC/C,QAAO;EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,MAAM;EAAE;EAAM;;;AAIrD,SAAgB,mBAAmB,UAAuC;CACtE,MAAM,EAAE,MAAM,SAAS,iBAAiB,SAAS;AACjD,QAAO;EAAE,aAAa,qBAAqB,MAAM,EAAE;EAAE;EAAM;;;AAI/D,SAAgB,qBAAqB,MAAc,YAAY,GAA4B;AACvF,QAAO,IAAI,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,eAAe;;AAY/D,SAAS,QAAQ,MAAc,WAA2B;CACtD,MAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,KAAI,KAAK,GAAG,GAAG,KAAK,GAAI,MAAK,KAAK;AAClC,QAAO,KAAK,KAAK,KAAK,WAAW;EAAE,IAAI,YAAY;EAAO,QAAQ,MAAM,KAAK,IAAI,GAAG,GAAG,UAAU;EAAG,MAAM,eAAe,IAAI;EAAE;EAAK,EAAE;;AAG1I,MAAM,aAAa;AAEnB,MAAM,eAAe,SAAwB,KAAK,SAAS,MAAM,KAAK,KAAK,WAAW,IAAI;AAC1F,MAAM,iBAAiB,SAAwB,KAAK,IAAI,KAAK,YAAY;AACzE,MAAM,kBAAkB,SAA0B,gBAAgB,KAAK,KAAK;AAE5E,IAAM,SAAN,MAAa;CACT,AAAQ,QAAQ;CAEhB,YAAY,AAAiBA,OAAe;EAAf;;CAE7B,gBAAyC;EACrC,MAAM,QAAQ,KAAK,MAAM;AACzB,MAAI,UAAU,OAAW,QAAO,EAAE;AAElC,MAAI,MAAM,KAAK,WAAW,IAAS,CAC/B,OAAM,IAAI,iBAAiB,6DAA6D,MAAM,GAAG;AAErG,MAAI,eAAe,MAAM,KAAK,IAAI,SAAS,MAAM,MAAM,MAAM,GAAG,KAAK,OACjE,OAAM,IAAI,iBAAiB,mDAAmD,MAAM,GAAG;EAE3F,MAAM,MAAM,KAAK,aAAa,MAAM,QAAQ,EAAE;EAC9C,MAAM,QAAQ,KAAK,MAAM;AACzB,MAAI,UAAU,OAAW,OAAM,IAAI,iBAAiB,sBAAsB,MAAM,GAAG;AACnF,SAAO;;CAGX,AAAQ,OAAyB;AAC7B,SAAO,KAAK,QAAQ,KAAK,MAAM,UAAU,YAAY,KAAK,MAAM,KAAK,OAAQ,CAAE,MAAK;EACpF,MAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,MAAI,SAAS,UAAa,cAAc,KAAK,CAAE,OAAM,IAAI,iBAAiB,YAAY,KAAK,GAAG;AAC9F,SAAO;;CAGX,AAAQ,aAAa,QAAgB,OAAwC;AACzE,cAAY,OAAO,KAAK,MAAM,KAAK,QAAQ,GAAG;EAC9C,MAAMC,MAA+B,EAAE;AACvC,OAAK,IAAI,OAAO,KAAK,MAAM,EAAE,SAAS,UAAa,KAAK,UAAU,QAAQ,OAAO,KAAK,MAAM,EAAE;AAC1F,OAAI,KAAK,SAAS,OAAQ,OAAM,IAAI,iBAAiB,0BAA0B,KAAK,GAAG;AACvF,OAAI,eAAe,KAAK,KAAK,CAAE;GAC/B,MAAM,QAAQ,SAAS,KAAK,MAAM,KAAK,GAAG;AAC1C,OAAI,UAAU,OAAW,OAAM,IAAI,iBAAiB,2BAAyB,KAAK,GAAG;AACrF,OAAI,OAAO,OAAO,KAAK,MAAM,IAAI,CAAE,OAAM,IAAI,iBAAiB,kBAAkB,MAAM,IAAI,IAAI,KAAK,GAAG;AACtG,QAAK;AACL,OAAI,MAAM,OAAO,KAAK,WAAW,MAAM,MAAM,MAAM,QAAQ,QAAQ,GAAG,KAAK;;AAE/E,SAAO;;CAGX,AAAQ,cAAc,QAAgB,OAA0B;AAC5D,cAAY,OAAO,KAAK,MAAM,KAAK,QAAQ,GAAG;EAC9C,MAAMC,QAAmB,EAAE;AAC3B,OAAK,IAAI,OAAO,KAAK,MAAM,EAAE,SAAS,UAAa,KAAK,UAAU,QAAQ,OAAO,KAAK,MAAM,EAAE;AAC1F,OAAI,KAAK,SAAS,OAAQ,OAAM,IAAI,iBAAiB,0BAA0B,KAAK,GAAG;AACvF,OAAI,CAAC,eAAe,KAAK,KAAK,CAAE;GAChC,MAAM,QAAQ,KAAK,KAAK,MAAM,EAAE;GAChC,MAAM,OAAO,eAAe,MAAM;GAClC,MAAM,SAAS,KAAK,SAAS,KAAK,MAAM,SAAS,KAAK;AACtD,OAAI,SAAS,MAAM,CAAC,KAAK,WAAW,IAAI,KAAK,eAAe,KAAK,IAAI,SAAS,MAAM,KAAK,GAAG,KAAK,SAAY;AAEzG,QAAI,QAAQ,KAAK,MAAM,CAAE,OAAM,IAAI,iBAAiB,YAAY,KAAK,GAAG;AACxE,SAAK,MAAM,KAAK,SAAS;KAAE,GAAG;KAAM,QAAQ;KAAQ,MAAM;KAAM;AAChE,UAAM,KAAK,eAAe,KAAK,GAAG,KAAK,cAAc,QAAQ,QAAQ,EAAE,GAAG,KAAK,aAAa,QAAQ,QAAQ,EAAE,CAAC;AAC/G;;AAEJ,QAAK;AACL,SAAM,KAAK,KAAK,WAAW,MAAM,MAAM,QAAQ,QAAQ,GAAG,MAAM,CAAC;;AAErE,SAAO;;CAGX,AAAQ,WAAW,MAAc,MAAY,cAAsB,OAAe,sBAAwC;AACtH,MAAI,SAAS,MAAM,KAAK,WAAW,IAAI,EAAE;GACrC,MAAM,OAAO,KAAK,MAAM;AACxB,OAAI,SAAS,UAAa,KAAK,SAAS,aAAc,QAAO,KAAK,cAAc,cAAc,MAAM;AACpG,OAAI,wBAAwB,SAAS,UAAa,KAAK,WAAW,gBAAgB,eAAe,KAAK,KAAK,CACvG,QAAO,KAAK,cAAc,cAAc,MAAM;AAElD,UAAO;;EAEX,MAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,OAAO,UAAU,IAAK,QAAO,KAAK,iBAAiB,MAAM,MAAM,aAAa;AAC1F,MAAI,UAAU,QAAO,UAAU,KAAK;GAChC,MAAM,EAAE,OAAO,QAAQ,WAAW,MAAM,GAAG,KAAK,GAAG;AACnD,qBAAkB,KAAK,MAAM,IAAI,EAAE,KAAK,GAAG;AAC3C,UAAO;;AAEX,MAAI,UAAU,OAAO,UAAU,KAAK;GAChC,MAAM,EAAE,OAAO,QAAQ,SAAS,MAAM,GAAG,KAAK,IAAI,MAAM;AACxD,qBAAkB,KAAK,MAAM,IAAI,EAAE,KAAK,GAAG;AAC3C,UAAO;;AAEX,MAAI,MAAM,SAAS,MAAM,CAAE,OAAM,IAAI,iBAAiB,+CAA+C,KAAK,GAAG;AAC7G,MAAI,SAAS,SAAS,MAAM,CAAE,OAAM,IAAI,iBAAiB,IAAI,MAAM,yCAAyC,KAAK,GAAG;AACpH,MAAI,eAAe,KAAK,IAAI,iBAAiB,KAAK,KAAK,CACnD,OAAM,IAAI,iBAAiB,kDAAkD,KAAK,GAAG;AAEzF,SAAO,KAAK,WAAW,MAAM,MAAM,aAAa;;CAGpD,AAAQ,cAAc,cAAsB,OAAwB;EAChE,MAAM,OAAO,KAAK,MAAM;AACxB,MAAI,eAAe,KAAK,KAAK,CAAE,QAAO,KAAK,cAAc,KAAK,QAAQ,MAAM;AAC5E,MAAI,SAAS,KAAK,MAAM,KAAK,GAAG,KAAK,OAAW,QAAO,KAAK,aAAa,KAAK,QAAQ,MAAM;AAC5F,OAAK;AACL,SAAO,KAAK,WAAW,KAAK,MAAM,MAAM,cAAc,OAAO,MAAM;;CAGvE,AAAQ,WAAW,OAAe,MAAY,cAA+B;EACzE,IAAI,QAAQ,aAAa,MAAM;AAC/B,cAAY,OAAO,KAAK,GAAG;EAC3B,IAAI,YAAY,QAAQ,KAAK,MAAM;EACnC,IAAI,SAAS;AACb,SAAO,KAAK,QAAQ,KAAK,MAAM,QAAQ;GACnC,MAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,OAAI,KAAK,SAAS,IAAI;AAClB;AACA,SAAK;AACL;;AAEJ,OAAI,KAAK,UAAU,gBAAgB,KAAK,KAAK,WAAW,IAAI,CAAE;AAC9D,OAAI,cAAc,KAAK,CAAE,OAAM,IAAI,iBAAiB,YAAY,KAAK,GAAG;AACxE,OAAI,UAAW,OAAM,IAAI,iBAAiB,sEAAsE,KAAK,GAAG;GACxH,MAAM,OAAO,aAAa,KAAK,KAAK;AACpC,eAAY,MAAM,KAAK,GAAG;AAC1B,eAAY,QAAQ,KAAK,KAAK,KAAK;AACnC,YAAS,SAAS,IAAI,KAAK,OAAO,OAAO,GAAG;AAC5C,YAAS;AACT,YAAS;AACT,QAAK;;AAET,SAAO,aAAa,OAAO,KAAK,GAAG;;CAGvC,AAAQ,iBAAiB,QAAgB,MAAY,cAA8B;EAC/E,MAAM,QAAQ,sCAAsC,KAAK,OAAO;AAChE,MAAI,UAAU,KAEV,OAAM,IAAI,iBADQ,uBAAuB,KAAK,OAAO,GAErC,0DAA0D,+BACtE,KAAK,GACR;EAEL,MAAMC,WAAqB,EAAE;EAC7B,IAAI,gBAAgB;EACpB,IAAI,eAAe;AACnB,SAAO,KAAK,QAAQ,KAAK,MAAM,QAAQ;GACnC,MAAM,OAAO,KAAK,MAAM,KAAK;GAC7B,MAAM,aAAa,KAAK,WAAW,KAAK,IAAI;AAC5C,OAAI,kBAAkB,MAAM,CAAC,cAAc,KAAK,SAAS,cAAc;AACnE,oBAAgB,KAAK;AACrB,QAAI,eAAe,cACf,OAAM,IAAI,iBAAiB,uEAAuE,KAAK,GAAG;;AAGlH,OAAI,kBAAkB,MAAM,KAAK,UAAU,cACvC,UAAS,KAAK,KAAK,IAAI,MAAM,cAAc,CAAC;YACrC,YAAY;AACnB,QAAI,kBAAkB,GAAI,gBAAe,KAAK,IAAI,cAAc,KAAK,OAAO;AAC5E,aAAS,KAAK,GAAG;cACV,cAAc,KAAK,CAC1B,OAAM,IAAI,iBAAiB,YAAY,KAAK,GAAG;OAE/C;AAEJ,QAAK;;AAET,SAAO,UAAU,UAAU,MAAM,OAAO,KAAK,MAAM,MAAM,GAAG;;;AAIpE,SAAS,YAAY,OAAe,MAAgC;AAChE,KAAI,QAAQ,UAAW,OAAM,IAAI,iBAAiB,uBAAuB,UAAU,2BAA2B,KAAK;;AAQvH,SAAS,SAAS,MAAc,IAAkC;CAC9D,MAAM,QAAQ,KAAK;AACnB,KAAI,UAAU,QAAO,UAAU,KAAK;EAChC,MAAM,EAAE,OAAO,QAAQ,WAAW,MAAM,GAAG,GAAG;EAC9C,MAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,MAAI,UAAU,OAAO,UAAU,KAAK,MAAM,CAAE,QAAO;GAAE,KAAK,SAAS,OAAO,GAAG;GAAE,MAAM,eAAe,MAAM,MAAM,EAAE,CAAC;GAAE;AACrH;;AAEJ,KAAI,UAAU,IAAK,OAAM,IAAI,iBAAiB,0CAAwC,GAAG;AACzF,KAAI,UAAU,UAAa,iBAAiB,SAAS,MAAM,CAAE,QAAO;AACpE,MAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS;EAC9C,MAAM,OAAO,KAAK;EAClB,MAAM,WAAW,KAAK,QAAQ;AAC9B,MAAI,SAAS,QAAQ,aAAa,OAAO,aAAa,KAAO,QAAO;AACpE,MAAI,SAAS,KAAK;GACd,MAAM,OAAO,KAAK,QAAQ;AAC1B,OAAI,SAAS,UAAa,SAAS,OAAO,SAAS,KAAM;IACrD,MAAM,MAAM,aAAa,KAAK,MAAM,GAAG,MAAM,CAAC;AAC9C,QAAI,QAAQ,GAAI,QAAO;AACvB,WAAO;KAAE,KAAK,WAAW,KAAK,GAAG;KAAE,MAAM,eAAe,KAAK,MAAM,QAAQ,EAAE,CAAC;KAAE;;;;;AAOhG,SAAS,SAAS,KAAa,IAAoB;AAC/C,KAAI,QAAQ,YAAa,OAAM,IAAI,iBAAiB,0CAAwC,GAAG;AAC/F,QAAO;;AAGX,SAAS,WAAW,KAAa,IAAoB;AACjD,KAAI,OAAO,aAAa,KAAK,GAAG,KAAK,SAAU,OAAM,IAAI,iBAAiB,QAAQ,IAAI,+BAA+B,GAAG;AACxH,QAAO,SAAS,KAAK,GAAG;;AAG5B,SAAS,YAAY,MAAc,IAAkB;AACjD,KAAI,eAAe,KAAK,KAAK,CAAE,OAAM,IAAI,iBAAiB,wDAAsD,GAAG;;AAGvH,MAAM,UAAU;AAEhB,SAAS,aAAa,MAAsB;CACxC,MAAM,QAAQ,QAAQ,KAAK,KAAK;AAChC,QAAO,aAAa,UAAU,OAAO,OAAO,KAAK,MAAM,GAAG,MAAM,MAAM,CAAC;;AAG3E,SAAS,kBAAkB,OAAe,IAAkB;AACxD,KAAI,eAAe,MAAM,KAAK,MAAM,WAAW,KAAK,MAAM,CAAE;AAC5D,OAAM,IAAI,iBAAiB,mCAAmC,GAAG;;AAIrE,SAAS,eAAe,MAAsB;AAC1C,QAAO,KAAK,MAAM,WAAW,MAAM,EAAE,CAAC;;AAG1C,SAAS,aAAa,MAAsB;CACxC,IAAI,MAAM,KAAK;AACf,QAAO,MAAM,MAAM,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,OAAO,KAAO;AACrE,QAAO,KAAK,MAAM,GAAG,IAAI;;AAG7B,MAAM,OAAO;AACb,MAAM,OAAO;AACb,MAAM,QAAQ;AACd,MAAM,UAAU;AAChB,MAAM,QAAQ;AACd,MAAM,cAAc;AACpB,MAAM,QAAQ;AACd,MAAM,gBAAgB;AAEtB,SAAS,aAAa,MAAc,IAAqB;AACrD,KAAI,SAAS,MAAM,KAAK,KAAK,KAAK,CAAE,QAAO;AAC3C,KAAI,KAAK,KAAK,KAAK,CAAE,QAAO;AAC5B,KAAI,MAAM,KAAK,KAAK,CAAE,QAAO;CAC7B,IAAIC;AACJ,KAAI,QAAQ,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,CAAE,UAAS,OAAO,KAAK;UACxD,MAAM,KAAK,KAAK,CAAE,UAAS,OAAO,SAAS,KAAK,MAAM,EAAE,EAAE,EAAE;UAC5D,YAAY,KAAK,KAAK,CAAE,UAAS,OAAO,SAAS,KAAK,MAAM,EAAE,EAAE,GAAG;UACnE,cAAc,KAAK,KAAK,CAAE,UAAS;AAC5C,KAAI,WAAW,OAAW,QAAO;AACjC,KAAI,CAAC,OAAO,SAAS,OAAO,CAAE,OAAM,IAAI,iBAAiB,IAAI,KAAK,4CAA4C,GAAG;AACjH,QAAO;;AAGX,MAAMC,iBAAmD;CACrD,KAAK;CACL,GAAG;CACH,GAAG;CACH,GAAG;CACH,KAAM;CACN,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,KAAK;CACL,MAAK;CACL,KAAK;CACL,MAAM;CACN,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACN;AAED,MAAMC,mBAAqD;CAAE,GAAG;CAAG,GAAG;CAAG,GAAG;CAAG;AAE/E,MAAM,iBAAiB;AAEvB,SAAS,WAAW,MAAc,OAAe,IAA4C;CACzF,MAAM,QAAQ,KAAK;CACnB,IAAI,QAAQ;CACZ,IAAI,QAAQ,QAAQ;AACpB,QAAO,QAAQ,KAAK,QAAQ;EACxB,MAAM,OAAO,KAAK;AAClB,MAAI,UAAU,KAAK;AACf,OAAI,SAAS,KAAK;AACd,QAAI,KAAK,QAAQ,OAAO,KAAK;AACzB,cAAS;AACT,cAAS;AACT;;AAEJ,WAAO;KAAE;KAAO,KAAK,QAAQ;KAAG;;AAEpC,YAAS;AACT;AACA;;AAEJ,MAAI,SAAS,KAAK,QAAO;GAAE;GAAO,KAAK,QAAQ;GAAG;AAClD,MAAI,SAAS,MAAM;GACf,MAAM,SAAS,aAAa,MAAM,OAAO,GAAG;AAC5C,YAAS,OAAO;AAChB,YAAS,OAAO;AAChB;;AAEJ,WAAS;AACT;;AAEJ,OAAM,IAAI,iBAAiB,gBAAgB,GAAG;;AAGlD,SAAS,aAAa,MAAc,OAAe,IAAiD;CAChG,MAAM,OAAO,KAAK,QAAQ;AAC1B,KAAI,SAAS,OAAW,OAAM,IAAI,iBAAiB,gBAAgB,GAAG;CACtE,MAAM,SAAS,eAAe;AAC9B,KAAI,WAAW,OAAW,QAAO;EAAE,SAAS;EAAQ,QAAQ;EAAG;CAC/D,MAAM,QAAQ,iBAAiB;AAC/B,KAAI,UAAU,OAAW,OAAM,IAAI,iBAAiB,qBAAqB,KAAK,IAAI,GAAG;CACrF,MAAM,MAAM,KAAK,MAAM,QAAQ,GAAG,QAAQ,IAAI,MAAM;AACpD,KAAI,IAAI,WAAW,SAAS,CAAC,gBAAgB,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,GAAG,GAAG,QACjF,OAAM,IAAI,iBAAiB,qBAAqB,OAAO,IAAI,IAAI,GAAG;AAEtE,QAAO;EAAE,SAAS,OAAO,cAAc,OAAO,SAAS,KAAK,GAAG,CAAC;EAAE,QAAQ,IAAI;EAAO;;AAGzF,SAAS,WAAW,MAAc,OAAuB;CACrD,IAAI,WAAW;AACf,QAAO,KAAK,cAAc,OAAO,KAAK,cAAc,IAAM;AAC1D,QAAO;;AAGX,MAAM,gBAAgB;AAEtB,SAAS,SAAS,MAAc,OAAe,IAAY,OAAgD;AACvG,aAAY,OAAO,GAAG;CACtB,MAAM,OAAO,KAAK;CAClB,MAAM,QAAQ,SAAS,MAAM,MAAM;CACnC,MAAMC,OAAkB,EAAE;CAC1B,MAAMN,MAA+B,EAAE;CACvC,IAAI,QAAQ,WAAW,MAAM,QAAQ,EAAE;AACvC,KAAI,KAAK,WAAW,MAAO,QAAO;EAAE,OAAO,SAAS,MAAM,OAAO;EAAK,KAAK,QAAQ;EAAG;AACtF,UAAS;AACL,MAAI,SAAS,KAAK;GACd,MAAM,OAAO,cAAc,MAAM,OAAO,IAAI,MAAM;AAClD,QAAK,KAAK,KAAK,MAAM;AACrB,WAAQ,WAAW,MAAM,KAAK,IAAI;SAC/B;GACH,MAAM,MAAM,YAAY,MAAM,OAAO,GAAG;GACxC,MAAM,OAAO,cAAc,MAAM,IAAI,MAAM,GAAG,IAAI,MAAM;AACxD,OAAI,OAAO,OAAO,KAAK,IAAI,IAAI,CAAE,OAAM,IAAI,iBAAiB,kBAAkB,IAAI,IAAI,IAAI,GAAG;AAC7F,OAAI,IAAI,OAAO,KAAK;AACpB,WAAQ,WAAW,MAAM,KAAK,IAAI;;EAEtC,MAAM,OAAO,KAAK;AAClB,MAAI,SAAS,KAAK;AACd,WAAQ,WAAW,MAAM,QAAQ,EAAE;AACnC,OAAI,KAAK,WAAW,MAAO,QAAO;IAAE,OAAO,SAAS,MAAM,OAAO;IAAK,KAAK,QAAQ;IAAG;AACtF;;AAEJ,MAAI,SAAS,MAAO,QAAO;GAAE,OAAO,SAAS,MAAM,OAAO;GAAK,KAAK,QAAQ;GAAG;AAC/E,MAAI,SAAS,OAAW,OAAM,IAAI,iBAAiB,eAAe,GAAG;AACrE,QAAM,IAAI,iBAAiB,eAAe,KAAK,yBAAyB,GAAG;;;AAInF,SAAS,YAAY,MAAc,OAAe,IAA0C;CACxF,MAAM,QAAQ,WAAW,MAAM,MAAM;CACrC,MAAM,OAAO,KAAK;AAClB,KAAI,SAAS,OAAW,OAAM,IAAI,iBAAiB,eAAe,GAAG;AACrE,KAAI,SAAS,QAAO,SAAS,KAAK;EAC9B,MAAM,SAAS,WAAW,MAAM,OAAO,GAAG;EAC1C,MAAM,QAAQ,WAAW,MAAM,OAAO,IAAI;AAC1C,MAAI,KAAK,WAAW,IAAK,OAAM,IAAI,iBAAiB,iDAA+C,GAAG;AACtG,SAAO;GAAE,KAAK,SAAS,OAAO,OAAO,GAAG;GAAE,KAAK;GAAO;;AAE1D,KAAI,SAAS,OAAO,SAAS,IAAK,OAAM,IAAI,iBAAiB,6DAA6D,GAAG;AAC7H,sBAAqB,MAAM,OAAO,GAAG;CACrC,MAAM,MAAM,cAAc,MAAM,MAAM;CACtC,MAAM,MAAM,aAAa,KAAK,MAAM,OAAO,IAAI,CAAC;CAChD,MAAM,QAAQ,KAAK,MAAM;AACzB,KAAI,QAAQ,MAAM,KAAK,SAAS,OAAQ,UAAU,OAAO,UAAU,IAC/D,OAAM,IAAI,iBAAiB,6CAA2C,GAAG;AAE7E,QAAO;EAAE,KAAK,WAAW,KAAK,GAAG;EAAE;EAAK;;AAI5C,MAAM,kBAAkB;AAExB,SAAS,qBAAqB,MAAc,OAAe,IAAkB;CACzE,MAAM,OAAO,KAAK;AAClB,KAAI,MAAM,SAAS,KAAK,CAAE,OAAM,IAAI,iBAAiB,+CAA+C,GAAG;AACvG,KAAI,SAAS,SAAS,KAAK,IAAK,MAAM,SAAS,KAAK,IAAI,gBAAgB,SAAS,KAAK,QAAQ,MAAM,IAAI,CACpG,OAAM,IAAI,iBAAiB,IAAI,KAAK,8DAA8D,GAAG;;AAK7G,SAAS,cAAc,MAAc,OAAuB;CACxD,IAAI,MAAM;AACV,QAAO,MAAM,KAAK,QAAQ;EACtB,MAAM,OAAO,KAAK;AAClB,MAAI,QAAQ,SAAS,KAAK,CAAE;AAC5B,MAAI,SAAS,QAAQ,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,OAAO,KAAO;AACvE,MAAI,SAAS,OAAO,gBAAgB,SAAS,KAAK,MAAM,MAAM,IAAI,CAAE;AACpE;;AAEJ,QAAO;;AAGX,SAAS,cAAc,MAAc,OAAe,IAAY,OAAgD;CAC5G,MAAM,QAAQ,WAAW,MAAM,MAAM;CACrC,MAAM,OAAO,KAAK;AAClB,KAAI,SAAS,OAAW,OAAM,IAAI,iBAAiB,eAAe,GAAG;AACrE,KAAI,SAAS,OAAO,SAAS,IAAK,QAAO,SAAS,MAAM,OAAO,IAAI,QAAQ,EAAE;AAC7E,KAAI,SAAS,QAAO,SAAS,IAAK,QAAO,WAAW,MAAM,OAAO,GAAG;AACpE,sBAAqB,MAAM,OAAO,GAAG;CACrC,MAAM,MAAM,cAAc,MAAM,MAAM;AACtC,KAAI,KAAK,SAAS,IAAK,OAAM,IAAI,iBAAiB,uEAAuE,GAAG;CAC5H,MAAM,MAAM,aAAa,KAAK,MAAM,OAAO,IAAI,CAAC;AAChD,KAAI,QAAQ,GAAI,OAAM,IAAI,iBAAiB,oCAAoC,GAAG;AAClF,QAAO;EAAE,OAAO,aAAa,KAAK,GAAG;EAAE;EAAK;;AAIhD,SAAS,UAAU,UAA6B,QAAiB,UAA0B;CACvF,IAAI,SAAS;CACb,IAAI,aAAa;CACjB,IAAI,iBAAiB;CACrB,IAAI,iBAAiB;AACrB,MAAK,MAAM,WAAW,UAAU;AAC5B,MAAI,YAAY,IAAI;AAChB;AACA;;AAEJ,MAAI,OACA,KAAI,QAAQ,WAAW,IAAI,IAAI,QAAQ,WAAW,IAAK,EAAE;AACrD,oBAAiB;AACjB,aAAU,KAAK,OAAO,iBAAiB,IAAI,aAAa,WAAW;aAC5D,gBAAgB;AACvB,oBAAiB;AACjB,aAAU,KAAK,OAAO,aAAa,EAAE;aAC9B,eAAe,GACtB;OAAI,eAAgB,WAAU;QAE9B,WAAU,KAAK,OAAO,WAAW;MAGrC,WAAU,KAAK,OAAO,iBAAiB,IAAI,aAAa,WAAW;AAEvE,YAAU;AACV,mBAAiB;AACjB,eAAa;;AAEjB,KAAI,aAAa,IAAK,WAAU,KAAK,OAAO,iBAAiB,IAAI,aAAa,WAAW;UAChF,aAAa,MAAM,eAAgB,WAAU;AACtD,QAAO;;;;;AC7hBX,MAAM,qBAAqB;AAE3B,SAAS,eAAe,MAAsB;AAC1C,QAAO,KAAK,WAAW,qBAAoB,SAAQ,mBAAmB,KAAK,CAAC;;;AAIhF,SAAgB,cAAc,SAAyB;AACnD,KAAI,YAAY,OAAO,YAAY,KAAM,QAAO,QAAQ,WAAW,KAAK,MAAM;AAC9E,QAAO,eAAe,QAAQ;;;AAIlC,SAAgB,oBAAoB,MAAsB;CACtD,IAAI,MAAM,KAAK;AACf,QAAO,MAAM,KAAK,KAAK,YAAY,MAAM,EAAE,KAAK,GAAM;AACtD,QAAO,KAAK,MAAM,GAAG,IAAI;;;AAI7B,SAAgB,QAAQ,MAAc,UAAqC;AACvE,KAAI,CAAC,KAAK,SAAS,MAAM,CAAE,QAAO,GAAG,oBAAoB,KAAK,CAAC,GAAG,SAAS,KAAI,YAAW,cAAc,QAAQ,CAAC,CAAC,KAAK,IAAI;CAC3H,MAAM,CAAC,WAAW,GAAG,QAAQ;AAC7B,KAAI,cAAc,OAAW,QAAO;AACpC,QAAO,CAAC,OAAO,mBAAmB,UAAU,EAAE,GAAG,KAAK,KAAI,YAAW,cAAc,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI;;;AAI3G,SAAgB,aAAa,KAAiC;AAC1D,KAAI;AACA,SAAO,IAAI,IAAI,IAAI,CAAC;SAChB;AACJ;;;;AAKR,SAAgB,eAAe,KAAsB;AACjD,QAAO,aAAa,IAAI,KAAK;;AAGjC,MAAM,kBAAkB;;AAGxB,SAAgB,aAAa,YAAwC;CACjE,MAAM,YAAY,aAAa,WAAW;AAC1C,KAAI,cAAc,UAAa,CAAC,UAAU,SAAS,gBAAgB,CAAE,QAAO;CAC5E,MAAM,OAAO,UAAU,MAAM,GAAG,GAAwB;AAExD,QAAO,KAAK,SAAS,IAAI,GAAG,SAAY;;AAG5C,SAAS,WAAW,SAAyB;AACzC,KAAI;AACA,SAAO,mBAAmB,QAAQ;SAC9B;AACJ,SAAO;;;;AAKf,SAAgB,cAAc,SAAyB;CACnD,MAAM,MAAM,IAAI,IAAI,QAAQ;CAC5B,MAAM,OAAO,IAAI;AACjB,QAAO,WAAW,SAAS,MAAM,SAAS,MAAM,IAAI,OAAO,KAAK,MAAM,KAAK,YAAY,IAAI,GAAG,EAAE,CAAC;;;AAIrG,SAAgB,SAAS,SAAiB,KAAsB;CAC5D,MAAM,YAAY,aAAa,IAAI;AACnC,KAAI,cAAc,UAAa,CAAC,UAAU,WAAW,GAAG,QAAQ,GAAG,CAAE,QAAO;AAC5E,QAAO,UACF,MAAM,QAAQ,SAAS,EAAE,CACzB,MAAM,IAAI,CACV,OAAM,YAAW;EACd,MAAM,UAAU,WAAW,QAAQ;AACnC,SAAO,YAAY,MAAM,YAAY,OAAO,YAAY,QAAQ,CAAC,QAAQ,SAAS,IAAI,IAAI,CAAC,QAAQ,SAAS,KAAK;GACnH;;AAGV,SAAS,kBAAkB,SAAqC;AAC5D,KAAI;AACA,SAAO,mBAAmB,QAAQ;SAC9B;AACJ;;;AAIR,SAAS,UAAU,MAAsB;AACrC,KAAI,QAAQ,IAAM,QAAO;AACzB,KAAI,QAAQ,IAAM,QAAO;AACzB,KAAI,QAAQ,IAAM,QAAO;AACzB,QAAO;;AAIX,SAAS,aAAa,KAAqB;CACvC,IAAI,MAAM;AACV,MAAK,IAAI,KAAK,GAAG,KAAK,IAAI,SAAU;EAChC,MAAM,QAAQ,IAAI,UAAU,OAAO,SAAS,IAAI,MAAM,KAAK,GAAG,KAAK,EAAE,EAAE,GAAG,CAAC;EAC3E,MAAM,UAAU,kBAAkB,IAAI,MAAM,IAAI,KAAK,MAAM,CAAC;AAC5D,MAAI,YAAY,QAAW;AACvB,UAAO,MAAM,IAAI,MAAM,KAAK,GAAG,KAAK,EAAE;AACtC,SAAM;SACH;AACH,UAAO,eAAe,QAAQ;AAC9B,SAAM;;;AAGd,QAAO;;AAIX,MAAM,aAAa;AAEnB,SAAS,aAAa,SAAyB;AAC3C,QAAO,QACF,MAAM,WAAW,CACjB,KAAK,MAAM,UAAW,QAAQ,MAAM,IAAI,eAAe,KAAK,GAAG,aAAa,KAAK,CAAE,CACnF,KAAK,GAAG;;;AAIjB,SAAgB,aAAa,SAAiB,KAAiC;CAC3E,IAAIO;AACJ,KAAI;AACA,QAAM,IAAI,IAAI,IAAI;SACd;AACJ;;AAEJ,KAAI,OAAO;CACX,MAAM,YAAY,IAAI;AAEtB,KAAI,UAAU,SAAS,IAAI,IAAI,CAAC,UAAU,WAAW,GAAG,QAAQ,GAAG,CAAE,QAAO;AAK5E,QAAO,GAAG,QAAQ,GAJJ,UACT,MAAM,QAAQ,SAAS,EAAE,CACzB,MAAM,IAAI,CACV,KAAI,YAAW,aAAa,QAAQ,CAAC,CACf,KAAK,IAAI;;;AAWxC,SAAgB,YAAY,GAAW,GAAmB;AACtD,KAAI,IAAI,EAAG,QAAO;AAClB,KAAI,IAAI,EAAG,QAAO;AAClB,QAAO;;;;;;ACjJX,MAAa,qBAAqB;AAElC,MAAM,eAAe,UACjB,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,MAAM,IACrB,OAAO,OAAO,MAAiC,CAAC,OAAM,SAAQ,OAAO,SAAS,SAAS;AAG3F,SAAS,gBAAgB,MAAsB;CAC3C,IAAI,QAAQ;AACZ,MAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,KAAK,YAAY,MAAM,GAAI,QAAU,IAAI,EAAG;AAC9F,QAAO;;;AAIX,SAAgB,mBAAmB,OAAwB;CACvD,MAAMC,WAAqB,EAAE;CAC7B,MAAM,OAAO,aAAa,MAAM,IAAI;AACpC,KAAI,SAAS,OAAW,QAAO,CAAC,QAAQ,MAAM,IAAI,8DAA8D;CAChH,MAAM,cAAc,MAAM;CAC1B,MAAM,EAAE,MAAM,gBAAgB,MAAM;AACpC,KAAI,KAAK,WAAW,KAAK,KAAK,SAAS,MAAM,CAAC,mBAAmB,KAAK,KAAK,CACvE,UAAS,KAAK,qBAAqB,KAAK,6DAA6D;UAC9F,cAAc,KAAK,KAAK,KAC/B,UAAS,KAAK,qBAAqB,KAAK,sCAAsC,cAAc,KAAK,CAAC,GAAG;AAEzG,KAAI,gBAAgB,MAAM,gBAAgB,YAAY,GAAG,KAAM,UAAS,KAAK,oDAAoD;CACjI,MAAM,gBAAgB,YAAY;AAClC,KACI,kBAAkB,WACjB,OAAO,kBAAkB,YAAY,kBAAkB,MAAM,gBAAgB,cAAc,GAAG,KAE/F,UAAS,KAAK,iEAAiE;AAEnF,KAAI,YAAY,gBAAgB,UAAa,CAAC,YAAY,YAAY,YAAY,CAC9E,UAAS,KAAK,mDAAmD;AAErE,KAAI,MAAM,cAAc,WAAW;EAC/B,MAAM,OAAO,aAAa,MAAM,IAAI;EACpC,MAAM,uBAAO,IAAI,KAAa;EAC9B,IAAI,UAAU;AACd,OAAK,MAAM,YAAY,MAAM,WAAW;GACpC,MAAM,YAAY,aAAa,SAAS,IAAI;AAC5C,OAAI,cAAc,QAAW;AACzB,aAAS,KAAK,aAAa,SAAS,IAAI,sBAAsB;AAC9D;;AAGJ,OAAI,OAAO,KAAK,UAAU,EAAE;AACxB,aAAS,KAAK,aAAa,SAAS,IAAI,qCAAqC;AAC7E;;GAEJ,MAAM,MAAM,aAAa,MAAM,UAAU,IAAI;AAC7C,OAAI,KAAK,IAAI,IAAI,CAAE,UAAS,KAAK,aAAa,SAAS,IAAI,4BAA4B;AACvF,QAAK,IAAI,IAAI;AACb,OAAI,cAAc,KAAM,WAAU;YACzB,CAAC,SAAS,MAAM,SAAS,IAAI,CAAE,UAAS,KAAK,aAAa,SAAS,IAAI,mCAAmC,OAAO;;AAE9H,MAAI,CAAC,QAAS,UAAS,KAAK,0BAA0B,MAAM,MAAM;;AAEtE,QAAO;;;AAIX,SAAgB,mBAAmB,OAA0B;CACzD,MAAM,SAAS,YAAY,UAAU,MAAM;AAC3C,KAAI,CAAC,OAAO,QAAS,QAAO,OAAO,MAAM,OAAO,KAAI,UAAS,GAAG,MAAM,KAAK,KAAK,IAAI,IAAI,UAAU,IAAI,MAAM,UAAU;AACtH,QAAO,mBAAmB,OAAO,KAAK;;;AAS1C,eAAsB,gBAClB,YACA,OAC8C;CAC9C,MAAM,WAAW,MAAM,MAAK,SAAQ,KAAK,QAAQ,WAAW;AAC5D,KAAI,aAAa,OAAW,QAAO,EAAE,UAAU,CAAC,sBAAsB,EAAE;CACxE,MAAM,OAAO,mBAAmB,SAAS,MAAM;AAC/C,KAAI,SAAS,OAAW,QAAO,EAAE,UAAU,CAAC,8BAA8B,EAAE;CAC5E,IAAIC;AACJ,KAAI;AACA,gBAAc,mBAAmB,KAAK,CAAC;UAClC,OAAO;AACZ,MAAI,iBAAiB,iBAAkB,QAAO,EAAE,UAAU,CAAC,yBAAyB,MAAM,UAAU,EAAE;AACtG,QAAM;;AAEV,KAAI,OAAO,YAAY,YAAY,YAAY,OAAO,YAAY,mBAAmB,SACjF,QAAO,EAAE,UAAU,CAAC,wEAAoE,EAAE;CAE9F,MAAM,YAAY,MAAM,QAAQ,IAC5B,MAAM,IAAI,OAAM,UAAS;EAAE,KAAK,KAAK;EAAK,QAAQ,MAAM,aAAa,KAAK,MAAM;EAAE,MAAM,KAAK,MAAM;EAAY,EAAE,CACpH;AACD,WAAU,MAAM,GAAG,MAAM,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC;CACnD,MAAM,QAAQ;EAAE,KAAK;EAAY;EAAa;EAAW;AACzD,QAAO;EAAE;EAAO,UAAU,mBAAmB,MAAM;EAAE;;;;;AC5GzD,MAAMC,eAAiD;CACnD,IAAI;CACJ,UAAU;CACV,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,MAAM;CACN,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,MAAM;CACN,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;CACR;;AAGD,SAAgB,YAAY,UAA0B;CAClD,MAAM,MAAM,SAAS,YAAY,IAAI;AACrC,KAAI,OAAO,EAAG,QAAO;CACrB,MAAM,YAAY,SAAS,MAAM,MAAM,EAAE,CAAC,aAAa;AAEvD,QAAO,OAAO,OAAO,cAAc,UAAU,GAAG,aAAa,aAAc;;;;;AC2B/E,MAAM,YAAY,SAAyB,KAAK,MAAM,KAAK,YAAY,IAAI,GAAG,EAAE;AAEhF,MAAM,WAAW,SAAyB;CACtC,MAAM,QAAQ,KAAK,YAAY,IAAI;AACnC,QAAO,UAAU,KAAK,KAAK,KAAK,MAAM,GAAG,MAAM;;AAGnD,MAAMC,eAAa,UAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAErG,MAAM,eAAe;AAGrB,MAAM,cAAc,UAA8B,MAAM,SAAS,eAAe,SAAS,MAAM,KAAK,KAAK;AAEzG,SAAS,OAAa,OAAoB,KAAQ,OAAgB;CAC9D,MAAM,OAAO,MAAM,IAAI,IAAI;AAC3B,KAAI,SAAS,OAAW,OAAM,IAAI,KAAK,CAAC,MAAM,CAAC;KAC1C,MAAK,KAAK,MAAM;;AAIzB,SAAS,iBAAiB,OAAc,MAAkC;CACtE,IAAIC;AACJ,KAAI;AACA,QAAM,MAAM,KAAK;UACZ,OAAO;AACZ,MAAI,iBAAiB,SAAU,QAAO;AACtC,QAAM;;AAEV,QAAO,eAAe,IAAI,GAAG,MAAM;;AAIvC,eAAe,KAAK,OAAyC;CACzD,MAAMC,OAAoB,EAAE;CAC5B,MAAM,QAAQ,OAAO,QAA+B;EAChD,IAAIC;AACJ,MAAI;AACA,aAAU,MAAM,MAAM,KAAK,IAAI;WAC1B,OAAO;AACZ,SAAM,IAAI,kBAAkB,CAAC;IAAE,MAAM,QAAQ,KAAK,MAAM;IAAK,SAAS,qBAAqBH,YAAU,MAAM;IAAI,CAAC,CAAC;;AAErH,OAAK,MAAM,SAAS,QAAQ,UAAU,GAAG,MAAM,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;AACzE,OAAI,MAAM,KAAK,WAAW,IAAI,CAAE;GAChC,MAAM,OAAO,QAAQ,KAAK,MAAM,OAAO,GAAG,IAAI,GAAG,MAAM;AACvD,QAAK,KAAK;IAAE;IAAM,MAAM,MAAM;IAAM,CAAC;AACrC,OAAI,MAAM,SAAS,YAAa,OAAM,MAAM,KAAK;;;AAGzD,OAAM,MAAM,GAAG;AACf,QAAO;;AAGX,eAAe,SAAS,OAAmB,MAAmC;AAC1E,KAAI;AACA,SAAO,MAAM,MAAM,KAAK,KAAK;UACxB,OAAO;AACZ,QAAM,IAAI,kBAAkB,CAAC;GAAE;GAAM,SAAS,mBAAmBA,YAAU,MAAM;GAAI,CAAC,CAAC;;;AAI/F,eAAsB,qBAAqB,OAAmB,SAAwD;CAClH,MAAM,OAAO,MAAM,KAAK,MAAM;CAC9B,MAAMI,WAA2B,EAAE;CACnC,MAAM,UAAU,YAAgC;AAC5C,MAAI,QAAQ,OAAQ,UAAS,KAAK,QAAQ;MACrC,SAAQ,KAAK,QAAQ;;CAE9B,MAAMC,SAAe,SAAQ,QAAQ,YAAY,CAAC,GAAG,QAAQ,QAAQ,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAEzF,MAAK,MAAM,SAAS,MAAM;EACtB,MAAM,OAAO,SAAS,MAAM,KAAK;AACjC,MAAI,MAAM,SAAS,UAAU,SAAS,cAAc,KAAK,aAAa,KAAK,WACvE,SAAQ,KAAK;GAAE,MAAM,MAAM;GAAM,SAAS;GAAwD,CAAC;;CAK3G,MAAM,YAAY,IAAI,IAAI,KAAK,QAAO,UAAS,WAAW,MAAM,CAAC,CAAC,KAAI,UAAS,QAAQ,MAAM,KAAK,CAAC,CAAC;CACpG,MAAM,2BAAW,IAAI,KAA0B;AAC/C,MAAK,MAAM,SAAS,MAAM;EACtB,IAAI,UAAU;AACd,OAAK,IAAI,MAAM,QAAQ,MAAM,KAAK,EAAE,QAAQ,IAAI,MAAM,QAAQ,IAAI,EAAE;AAChE,OAAI,CAAC,UAAU,IAAI,IAAI,CAAE;AACzB,aAAU;AACV,UAAO,UAAU,KAAK,MAAM;;AAEhC,MAAI,CAAC,WAAW,MAAM,SAAS,iBAAiB,CAAC,WAAW,MAAM,CAC9D,QAAO;GAAE,MAAM,MAAM;GAAM,SAAS,GAAG,aAAa;GAAa,CAAC;;CAI1E,MAAMC,QAAsB,EAAE;CAC9B,MAAM,yBAAS,IAAI,KAAqB;CAExC,MAAM,YAAY,KAAK,QAAO,UAAS,WAAW,MAAM,CAAC,CAAC,UAAU,GAAG,MAAM,EAAE,KAAK,MAAM,IAAI,CAAC,SAAS,EAAE,KAAK,MAAM,IAAI,CAAC,OAAO;AACjI,MAAK,MAAM,SAAS,WAAW;EAC3B,MAAM,MAAM,QAAQ,MAAM,KAAK;AAC/B,MAAI,QAAQ,IAAI;AACZ,UAAO;IACH,MAAM,MAAM;IACZ,SAAS;IACZ,CAAC;AACF;;EAEJ,MAAM,QAAQ,MAAM,SAAS,OAAO,SAAS,IAAI,IAAI,IAAI,EAAE,EAAE,KAAK,OAAO,SAAS,QAAQ,OAAO;AACjG,MAAI,UAAU,OAAW,OAAM,KAAK,MAAM;;AAE9C,KAAI,SAAS,SAAS,EAAG,OAAM,IAAI,kBAAkB,SAAS;AAC9D,KAAI,MAAM,WAAW,EAAG,SAAQ,KAAK;EAAE,MAAM;EAAK,SAAS;EAA6D,CAAC;AACzH,QAAO,SAAS,OAAO,MAAM,MAAM;;AAGvC,eAAe,SACX,OACA,QACA,KACA,OACA,SACA,QACA,QAC+B;CAC/B,MAAM,cAAc,OAAO,MAAK,UAAS,MAAM,SAAS,cAAc;AACtE,KAAI,gBAAgB,QAAW;AAC3B,SAAO;GAAE,MAAM,YAAY;GAAM,SAAS,GAAG,aAAa;GAAmB,CAAC;AAC9E;;CAEJ,MAAM,eAAe,GAAG,IAAI;CAC5B,MAAMC,WAA6B,EAAE;CACrC,MAAMC,eAA8B,EAAE;AACtC,MAAK,MAAM,SAAS,QAAQ;EAExB,MAAM,MAAM,iBAAiB,OAAO,MAAM,KAAK;AAC/C,MAAI,QAAQ,QAAW;AACnB,UAAO;IAAE,MAAM,MAAM;IAAM,SAAS;IAA4D,CAAC;AACjG;;AAEJ,MAAI,MAAM,SAAS,OAAQ;EAC3B,MAAM,MAAM,MAAM,SAAS;EAC3B,IAAI,OAAO,MAAM,SAAY,OAAO,IAAI,MAAM,KAAK;AACnD,MAAI,SAAS,QAAW;GACpB,MAAM,QAAQ,MAAM,SAAS,OAAO,MAAM,KAAK;AAC/C,OAAI,IAAK,UAAS,KAAK;IAAE;IAAK;IAAO,CAAC;AACtC,UAAO;IAAE,QAAQ,MAAM,aAAa,MAAM;IAAE,MAAM,MAAM;IAAY;AACpE,UAAO,IAAI,MAAM,MAAM,KAAK;;AAEhC,eAAa,KAAK;GAAE,MAAM,MAAM;GAAM;GAAK,GAAG;GAAM,UAAU,YAAY,SAAS,MAAM,KAAK,CAAC;GAAE,CAAC;;CAGtG,MAAM,SAAS,MAAM,gBAAgB,MAAM,aAAa,EAAE,SAAS;CACnE,MAAM,YAAY,aAAa,KAAK,EAAE,KAAK,QAAQ,YAAY;EAAE;EAAK;EAAQ;EAAM,EAAE,CAAC,UAAU,GAAG,MAAM,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC;CACpI,MAAM,QAAQ,OAAO,UAAU,SAAY,SAAY;EAAE,GAAG,OAAO;EAAO;EAAW;CACrF,MAAM,WAAW,UAAU,SAAY,OAAO,WAAW,mBAAmB,MAAM;AAClF,KAAI,UAAU,UAAa,SAAS,SAAS,GAAG;AAC5C,OAAK,MAAM,WAAW,SAAU,QAAO;GAAE,MAAM;GAAc,SAAS,GAAG,QAAQ;GAAmB,CAAC;AACrG;;CAEJ,IAAI,aAAa;AACjB,MAAK,MAAM,QAAQ,aAAc,eAAc,KAAK;AACpD,KAAI,aAAa,SAAS,QAAQ,OAAO,SAAS,aAAa,QAAQ,OAAO,OAAO;EACjF,MAAM,SAAS,QAAQ,SAAS,6BAA6B;AAC7D,SAAO;GACH,MAAM;GACN,SACI,GAAG,aAAa,OAAO,WAAW,WAAW,8BAA8B,QAAQ,OAAO,MAAM,WAC7F,QAAQ,OAAO,MAAM,qCAAqC;GACpE,CAAC;;AAGN,QAAO;EAAE;EAAK;EAAO,OAAO;EAAc,cADrB,aAAa,MAAK,SAAQ,KAAK,SAAS,aAAa,EAAE,QAAQ;EAC5B;EAAQ;;AAGpE,SAAS,WAAc,OAAa;AAChC,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,OAAO,SAAS,MAAM,EAAE;AACxE,SAAO,OAAO,MAAM;AACpB,OAAK,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAE,YAAW,KAAK;;AAE7D,QAAO;;AAGX,SAAS,SAAS,OAA8B,MAA4B,OAA+B;CAEvG,MAAM,UAAU,OAAO,OAAO,MAAM,KAAI,SAAQ,WAAW,KAAK,MAAM,CAAC,CAAC,UAAU,GAAG,MAAM,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;CACtH,MAAM,wBAAQ,IAAI,KAA0B;CAC5C,MAAM,2BAAW,IAAI,KAAa;AAClC,MAAK,MAAM,QAAQ,OAAO;AACtB,OAAK,MAAM,QAAQ,KAAK,MAAO,OAAM,IAAI,KAAK,KAAK,KAAK;AACxD,WAAS,IAAI,KAAK,IAAI;AACtB,OAAK,MAAM,SAAS,KAAK,OACrB,KAAI,MAAM,SAAS,YAAa,UAAS,IAAI,MAAM,KAAK;;CAGhE,MAAM,6BAAa,IAAI,KAA0B;AACjD,MAAK,MAAM,SAAS,KAAM,QAAO,YAAY,QAAQ,MAAM,KAAK,EAAE,MAAM;CACxE,MAAM,uBAAO,IAAI,KAAyB;AAC1C,MAAK,MAAM,WAAW,UAAU;EAC5B,MAAMC,WAAuB,EAAE;AAC/B,OAAK,MAAM,SAAS,WAAW,IAAI,QAAQ,IAAI,EAAE,EAAE;AAC/C,OAAI,MAAM,SAAS,aAAa;AAC5B,aAAS,KAAK;KAAE,KAAK,MAAM,MAAM,KAAK;KAAE,MAAM,SAAS,MAAM,KAAK;KAAE,UAAU;KAAqB,CAAC;AACpG;;GAEJ,MAAM,OAAO,MAAM,IAAI,MAAM,MAAM,KAAK,CAAC;AACzC,OAAI,MAAM,SAAS,UAAU,SAAS,OAClC,UAAS,KAAK;IAAE,KAAK,KAAK;IAAK,MAAM,SAAS,MAAM,KAAK;IAAE,UAAU,KAAK;IAAU,MAAM,KAAK;IAAM,CAAC;;AAG9G,WAAS,MAAM,GAAG,MAAM,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC;AAClD,OAAK,IAAI,MAAM,QAAQ,EAAE,SAAS;;CAEtC,MAAM,SAAS,MACV,KAAI,UAAS;EACV,KAAK,KAAK,MAAM;EAChB,MAAM,KAAK,MAAM,YAAY;EAC7B,aAAa,KAAK,MAAM,YAAY;EACpC,UAAU;EACV,MAAM,KAAK;EACd,EAAE,CACF,UAAU,GAAG,MAAM,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC;AAClD,QAAO;EAAE;EAAS,QAAQ,IAAI,IAAI,QAAQ,KAAI,UAAS,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;EAAE;EAAO;EAAM;EAAQ;;;;;ACnRtG,MAAa,iCAAiB,IAAI,SAAsB;;;;ACAxD,MAAM,gBAAgB;AAGtB,SAAgB,aAAa,KAAqB;AAC9C,QAAO,aAAa,WAAW,gBAAgB,IAAI,CAAC,CAC/C,WAAW,KAAK,IAAI,CACpB,WAAW,KAAK,IAAI,CACpB,QAAQ,OAAO,GAAG;;AAI3B,SAAgB,aAAa,QAAoC;AAC7D,KAAI;EACA,MAAM,SAAS,OAAO,WAAW,KAAK,IAAI,CAAC,WAAW,KAAK,IAAI;EAC/D,MAAM,UAAU,mBAAmB,aAAa,SAAS,IAAI,QAAQ,IAAK,OAAO,SAAS,KAAM,EAAE,CAAC,CAAC;AACpG,SAAO,SAAS,WAAW,cAAc,GAAG,QAAQ,MAAM,EAAqB,GAAG;SAC9E;AACJ;;;AAKR,SAAgB,SACZ,OACA,QACA,UACA,KACmC;CACnC,IAAI,QAAQ;AACZ,KAAI,WAAW,QAAW;EACtB,MAAM,QAAQ,aAAa,OAAO;AAClC,MAAI,UAAU,OAAW,OAAM,IAAI,cAAc,kBAAkB,eAAe,iBAAiB;AACnG,UAAQ,MAAM,WAAU,SAAQ,YAAY,IAAI,KAAK,EAAE,MAAM,GAAG,EAAE;AAClE,MAAI,UAAU,GAAI,SAAQ,MAAM;;CAEpC,MAAM,MAAM,KAAK,IAAI,MAAM,QAAQ,QAAQ,SAAS;CACpD,MAAM,OAAO,MAAM,MAAM,OAAO,IAAI;CACpC,MAAM,OAAO,KAAK,GAAG,GAAG;AACxB,QAAO,MAAM,MAAM,UAAU,SAAS,SAAY;EAAE,OAAO;EAAM,YAAY,aAAa,IAAI,KAAK,CAAC;EAAE,GAAG,EAAE,OAAO,MAAM;;AAG5H,SAAgB,gBAAgB,UAAsC;AAClE,KAAI,aAAa,OAAW,QAAO;AACnC,KAAI,aAAa,OAAO,qBAAsB,OAAO,cAAc,SAAS,IAAI,WAAW,EAAI,QAAO;AACtG,OAAM,IAAI,WAAW,wDAAwD,SAAS,GAAG;;;;;AClC7F,MAAM,aAAa,UAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAGrG,SAAgB,cACZ,OACA,OACA,UACA,MACW;CACX,MAAMC,SAAsB;EACxB,MAAM,KAAK,EAAE,UAAU;GACnB,MAAM,OAAO,SAAS,MAAM,QAAQ,SAAS,QAAQ,WAAU,UAAS,MAAM,IAAI;AAClF,UAAO,KAAK,eAAe,SAAY,EAAE,QAAQ,KAAK,OAAO,GAAG;IAAE,QAAQ,KAAK;IAAO,YAAY,KAAK;IAAY;;EAEvH,MAAM,IAAI,KAAK;GACX,MAAM,YAAY,aAAa,IAAI;AACnC,UAAO,cAAc,SAAY,SAAY,MAAM,QAAQ,OAAO,IAAI,UAAU;;EAEpF,OAAM,QAAO,YAAY,MAAM,SAAS,OAAO,KAAK,KAAK;EACzD,MAAM,cAAc,KAAK,EAAE,UAAU;GACjC,MAAM,YAAY,aAAa,IAAI;GACnC,MAAM,WAAW,cAAc,SAAY,SAAY,MAAM,QAAQ,KAAK,IAAI,UAAU;AACxF,OAAI,aAAa,OAAW;GAC5B,MAAM,OAAO,SAAS,UAAU,QAAQ,WAAU,UAAS,MAAM,IAAI;AACrE,UAAO,KAAK,eAAe,SAAY,EAAE,WAAW,KAAK,OAAO,GAAG;IAAE,WAAW,KAAK;IAAO,YAAY,KAAK;IAAY;;EAE7H,MAAM,gBAAgB;AAClB,UAAO,CAAC,GAAG,MAAM,QAAQ,OAAO;;EAEvC;AACD,gBAAe,IAAI,OAAO;AAC1B,QAAO;;AAIX,eAAe,YACX,UACA,OACA,KACA,MACoC;CACpC,MAAM,YAAY,aAAa,IAAI;CACnC,MAAM,OAAO,cAAc,SAAY,SAAY,SAAS,MAAM,IAAI,UAAU;AAChF,KAAI,SAAS,QAAW;AACpB,MAAI,cAAc,UAAa,SAAS,KAAK,IAAI,UAAU,CACvD,OAAM,IAAI,sBAAsB,KAAK,GAAG,IAAI,+CAA+C;AAE/F;;CAEJ,IAAIC;AACJ,KAAI;AACA,UAAQ,MAAM,MAAM,KAAK,KAAK,KAAK;UAC9B,OAAO;AACZ,OAAK;GAAE,MAAM,KAAK;GAAM,SAAS,sBAAsB,UAAU,MAAM;GAAI,CAAC;AAC5E,QAAM,IAAI,cAAc,kBAAkB,eAAe,GAAG,IAAI,oBAAoB;;AAExF,KAAI,MAAM,eAAe,KAAK,QAAS,MAAM,aAAa,MAAM,KAAM,KAAK,QAAQ;AAC/E,OAAK;GAAE,MAAM,KAAK;GAAM,SAAS;GAAuD,CAAC;AACzF,QAAM,IAAI,cAAc,kBAAkB,eAAe,GAAG,IAAI,8CAA8C;;CAGlH,MAAM,OAAO,mBAAmB,MAAM;AACtC,QAAO,SAAS,SAAY;EAAE;EAAO,UAAU,KAAK;EAAU,GAAG;EAAE;EAAM,UAAU,KAAK;EAAU;;;;;ACtEtG,SAAgB,kBAAkB,MAAc,OAAyB;CACrE,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,QAAO,YAAW,YAAY,MAAM,YAAY,IAAI;AACrF,KAAI,SAAS,WAAW,KAAK,SAAS,SAAS,KAAK,CAChD,OAAM,IAAI,UAAU,GAAG,MAAM,6CAA6C,KAAK,UAAU,KAAK,CAAC,GAAG;AAEtG,QAAO;;AAWX,SAAS,YAAY,MAAsC;CACvD,MAAM,uBAAO,IAAI,KAA0C;CAC3D,MAAM,wBAAQ,IAAI,KAAqB;AACvC,MAAK,MAAM,OAAO,MAAM;EACpB,MAAM,WAAW,kBAAkB,KAAK,YAAY;EACpD,IAAI,MAAM;AACV,OAAK,MAAM,CAAC,OAAO,SAAS,SAAS,SAAS,EAAE;GAC5C,IAAI,WAAW,KAAK,IAAI,IAAI;AAC5B,OAAI,aAAa,QAAW;AACxB,+BAAW,IAAI,KAAK;AACpB,SAAK,IAAI,KAAK,SAAS;;AAE3B,YAAS,IAAI,MAAM;IAAE;IAAM,MAAM,QAAQ,SAAS,SAAS,IAAI,cAAc;IAAQ,CAAC;AACtF,SAAM,QAAQ,KAAK,OAAO,GAAG,IAAI,GAAG;;AAExC,QAAM,IAAI,KAAK,IAAI;;AAEvB,QAAO;EAAE;EAAM;EAAO;;;;;;;AAQ1B,SAAgB,iBAAiB,OAAwD;CACrF,IAAIC;CACJ,MAAM,gBAA6B;AAC/B,UAAQ,YAAY,OAAO,KAAK,MAAM,CAAC;AACvC,SAAO;;AAEX,QAAO;EACH,MAAM,KAAK,KAAK;GACZ,MAAM,YAAY,QAAQ,KAAK,SAAS,GAAI,SAAS,SAAS,EAAG,KAAK,IAAI,IAAI;AAC9E,OAAI,aAAa,OAAW,QAAO,MAAM,KAAK,SAAS,QAAQ,GAAE,WAAU,EAAE,GAAG,OAAO,EAAE;AACzF,OAAI,QAAQ,GAAI,QAAO,EAAE;AACzB,SAAM,IAAI,MAAM,sBAAsB,MAAM;;EAEhD,MAAM,KAAK,MAAM;GAEb,MAAM,MAAM,OAAO,OAAO,OAAO,KAAK,GAAG,QAAQ,SAAS,SAAS,EAAE,MAAM,IAAI,KAAK;GACpF,MAAM,UAAU,QAAQ,SAAY,SAAY,MAAM;AACtD,OAAI,YAAY,OAAW,OAAM,IAAI,MAAM,iBAAiB,OAAO;AACnE,UAAO,OAAO,YAAY,WAAW,WAAW,QAAQ,GAAG;;EAElE;;;;;AClBL,MAAM,aAAa;AAEnB,SAAS,cAAc,OAAwB;CAC3C,MAAM,MAAO,OAAoC;AACjD,QAAO,OAAO,QAAQ,WAAW,MAAM;;AAG3C,SAAS,WAAW,KAAa,QAAiE;CAC9F,MAAM,WAAW,OAAO,aAAa,SAAY,EAAE,GAAG,EAAE,UAAU,OAAO,UAAU;AACnF,QAAO,UAAU,SAAS;EAAE;EAAK,GAAG;EAAU,MAAM,OAAO;EAAM,GAAG;EAAE;EAAK,GAAG;EAAU,MAAM,aAAa,OAAO,MAAM;EAAE;;AAI9H,MAAM,gCAAgB,IAAI,SAAoB;AAG9C,MAAM,8BAAc,IAAI,SAAoD;AAE5E,MAAM,iBACF;;;;;;;AASJ,IAAa,kBAAb,MAA6B;CACzB,AAAS,KAAK;CACd,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC,2BAAY,IAAI,SAAoB;;;;;CAM7C,OAAO,KAAK,OAAmB,SAAsD;AACjF,SAAO,aAAa,KAAK,OAAO,QAAQ;;CAG5C,YAAY,SAA6B;AACrC,MAAI,QAAQ,cAAc,OAAW,sBAAqB,QAAQ,WAAW,mBAAmB;EAChG,MAAM,UAAU,QAAQ,WAAW;EAEnC,MAAM,YAAY,WAAW,KAAK,QAAQ,GAAG,aAAa,QAAQ,GAAG;AACrE,MAAI,cAAc,OAAW,OAAM,IAAI,UAAU,2CAA2C,KAAK,UAAU,QAAQ,CAAC,GAAG;AACvH,QAAKL,WAAY,UAAU,SAAS,MAAM,GAAG,YAAY,GAAG,oBAAoB,UAAU,CAAC;AAC3F,QAAKF,SAAU,QAAQ;AACvB,QAAKC,UAAW,eAAe,IAAI,QAAQ,OAAO;AAClD,QAAKE,YAAa,QAAQ;AAC1B,QAAKC,QAAS;GAAE,OAAO,QAAQ,WAAW,SAAS;GAAG,YAAY,QAAQ,WAAW,cAAc;GAAW;AAC9G,QAAKC,SAAU,QAAQ,UAAU;AACjC,QAAKC,OAAQ,QAAQ,aAAa;;;;;;;;;;;;CAatC,OAAO,KAAsB;AACzB,MAAI,MAAKC,SAAU,IAAI,IAAI,CAAE;AAC7B,MAAI,IAAI,aAAa,CAAE,OAAM,IAAI,MAAM,6CAA6C;AACpF,MAAI,cAAc,IAAI,IAAI,CAAE,OAAM,IAAI,MAAM,eAAe;EAC3D,MAAM,SAAS,IAAI;EACnB,MAAM,gBAAgB,MAAKP,OAAQ,kBAAkB;EACrD,MAAM,OAAO,MAAKA,OAAQ,kBAAkB,SAAY,UAAa,QAAuB,MAAKQ,cAAe,IAAI;AACpH,SAAO,2BAA2B,mBAAmB;AACrD,SAAO,2BAA2B,kBAAkB;AACpD,MAAI,cAAe,QAAO,2BAA2B,gCAAgC;AAErF,MAAI,iBACA,qBACA,IAAI,iBAAiB,GAAG,MAAKN,SAAU,UAAU,EAAE,MAAM,CAAC,EAC1D,MAAKC,cAAe,SAAY,EAAE,GAAG,EAAE,WAAW,MAAKA,WAAY,GAClE,KAAK,YAAY,QAAQ,MAAKM,KAAM,KAAK,IAAI,CACjD;AACD,SAAO,kBAAkB,oBAAoB,EAAE,QAAQ,+BAA+B,GAAG,QAAQ,QAC7F,MAAKC,KAAM,QAAQ,OAAO,QAAQ,IAAI,CACzC;AACD,SAAO,kBAAkB,mBAAmB,EAAE,QAAQ,6BAA6B,GAAG,QAAQ,QAC1F,MAAKC,IAAK,QAAQ,OAAO,KAAK,IAAI,CACrC;AACD,MAAI,cACA,QAAO,kBAAkB,iCAAiC,EAAE,QAAQ,0CAA0C,GAAG,QAAQ,QACrH,MAAKC,cAAe,QAAQ,OAAO,KAAK,OAAO,QAAQ,IAAI,CAC9D;AAEL,SAAO,qBAAqB,EAAE,YAAY,GAAG,sBAAsB,gBAAgB,EAAE,eAAe,MAAM,GAAG,EAAE,EAAE,EAAE,CAAC;AACpH,QAAKL,SAAU,IAAI,IAAI;AACvB,gBAAc,IAAI,IAAI;AACtB,cAAY,IAAI,KAAK,GAAG,IAAI;;CAGhC,aAAa,QAAuE;AAChF,SAAO,wBAAwB,OAAO,8BAA8B,IAAI,GAAG,GAAG,EAAE,GAAG,MAAKH,OAAQ,GAAG,EAAE;;CAGzG,WAAW,QAAmC;AAC1C,MAAI,MAAKH,QAAU,QAAO,CAAC,GAAG,OAAO;EACrC,MAAMY,OAAgB,EAAE;AACxB,OAAK,MAAM,aAAa,QAAQ;GAC5B,MAAM,WAAW,mBAAmB,UAAU;AAC9C,OAAI,SAAS,WAAW,GAAG;AACvB,SAAK,KAAK,UAAU;AACpB;;GAEJ,MAAM,UAAU,wCAAwC,SAAS,KAAK,KAAK;AAC3E,OAAI,MAAKR,OAAS,OAAM,IAAI,cAAc,kBAAkB,eAAe,GAAG,cAAc,UAAU,CAAC,IAAI,UAAU;AACrH,SAAKC,KAAM;IAAE,MAAM,cAAc,UAAU;IAAE,SAAS,GAAG,QAAQ;IAA8B,CAAC;;AAEpG,SAAO;;CAGX,OAAMI,KAAM,QAAgB,QAA4B,KAAoB;EACxE,MAAM,OAAO,MAAM,MAAKV,OAAQ,KAAK,WAAW,SAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI;AACjF,SAAO;GACH,QAAQ,MAAKc,UAAW,KAAK,OAAO;GACpC,GAAI,KAAK,eAAe,SAAY,EAAE,GAAG,EAAE,YAAY,KAAK,YAAY;GACxE,GAAG,MAAKC,YAAa,OAAO;GAC/B;;CAGL,OAAMJ,IAAK,QAAgB,KAAa,KAAoB;EACxD,MAAM,QAAQ,MAAM,MAAKX,OAAQ,IAAI,KAAK,IAAI;AAC9C,MAAI,UAAU,OAAW,OAAM,IAAI,cAAc,kBAAkB,eAAe,yBAAyB,MAAM;AACjH,MAAI,CAAC,MAAKC,SAAU;GAChB,MAAM,WAAW,mBAAmB,MAAM;AAC1C,OAAI,SAAS,SAAS,GAAG;IACrB,MAAM,UAAU,wCAAwC,SAAS,KAAK,KAAK;AAC3E,UAAKK,KAAM;KAAE,MAAM;KAAK;KAAS,CAAC;AAClC,UAAM,IAAI,cAAc,kBAAkB,eAAe,QAAQ;;;AAGzE,MAAI,aAAa,MAAM,IAAI,KAAK,aAAa,IAAI,CAC7C,OAAM,IAAI,cAAc,kBAAkB,eAAe,6BAA6B,MAAM,IAAI,OAAO,MAAM;AAEjH,SAAO;GAAE;GAAO,GAAG,MAAKS,YAAa,OAAO;GAAE;;CAGlD,OAAMN,KAAM,KAAU,KAAiD;EACnE,MAAM,SAAS,MAAM,MAAKT,OAAQ,KAAK,IAAI,MAAM,IAAI;AACrD,MAAI,WAAW,OAAW,OAAM,IAAI,sBAAsB,IAAI,KAAK;AACnE,SAAO,EAAE,UAAU,CAAC,WAAW,IAAI,MAAM,OAAO,CAAC,EAAE;;CAGvD,OAAMY,cAAe,QAAgB,KAAa,QAA4B,KAAoB;EAC9F,MAAM,OAAO,MAAM,MAAKZ,OAAQ,cAAe,KAAK,WAAW,SAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI;AAChG,MAAI,SAAS,OAAW,OAAM,IAAI,cAAc,kBAAkB,eAAe,GAAG,IAAI,8BAA8B;AACtH,SAAO;GACH,WAAW,KAAK;GAChB,GAAI,KAAK,eAAe,SAAY,EAAE,GAAG,EAAE,YAAY,KAAK,YAAY;GACxE,GAAG,MAAKe,YAAa,OAAO;GAC/B;;CAGL,OAAMP,cAAe,KAAkD;EACnE,MAAM,YAAY,MAAM,MAAKR,OAAQ,cAAe,IAAI;EACxD,MAAM,OAAO,EAAE;AACf,OAAK,MAAM,YAAY,UACnB,KAAI,aAAa,SAAS,IAAI,EAAE,WAAW,MAAKE,SAAU,CAAE,MAAK,KAAK,SAAS;MAE3E,OAAKI,KAAM;GACP,MAAM,SAAS;GACf,SAAS,wCAAwC,MAAKJ,SAAU;GACnE,CAAC;AAEV,SAAO,EAAE,WAAW,MAAM;;;AAYlC,MAAM,kBAAkB;AAExB,SAAS,cAAc,QAAyE;CAC5F,MAAM,WAAW;EAAE,OAAO,QAAQ,SAAS,aAAa;EAAO,OAAO,QAAQ,SAAS,aAAa;EAAO;AAC3G,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,SAAS,CAChD,KAAI,UAAU,OAAO,qBAAqB,EAAE,OAAO,cAAc,MAAM,IAAI,QAAQ,GAC/E,OAAM,IAAI,WAAW,UAAU,KAAK,+CAA+C,MAAM,GAAG;AAGpG,QAAO;;AAIX,SAAS,WAAW,UAAmC;AACnD,QAAO,KAAK,UAAU,SAAS,OAAO,KAAI,aAAY;EAAC,SAAS;EAAK,SAAS;EAAM,SAAS;EAAY,CAAC,CAAC;;AAG/G,SAAS,cAAc,UAA2B,MAAiE;CAC/G,MAAM,QAAQ,QAAyB,KAAK,UAAU,SAAS,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU,KAAK,OAAO,IAAI,IAAI,CAAC;AACxH,QAAO;EACH,OAAO,CAAC,GAAG,KAAK,OAAO,MAAM,CAAC,CAAC,QAAO,QAAO,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC;EACvE,SAAS,CAAC,GAAG,SAAS,OAAO,MAAM,CAAC,CAAC,QAAO,QAAO,CAAC,KAAK,OAAO,IAAI,IAAI,CAAC;EACzE,SAAS,CAAC,GAAG,KAAK,OAAO,MAAM,CAAC,CAAC,QAAO,QAAO,SAAS,OAAO,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;EACzF;;;;;;AAOL,IAAa,eAAb,MAAa,qBAAqB,gBAAgB;CAC9C,CAASc;CACT,CAASC;CACT,CAASC;CACT,CAASC,0BAAW,IAAI,KAAyB;CACjD,WAAW;CACX,SAA2B,QAAQ,SAAS;CAE5C,AAAQ,YAAY,MAAmB;AACnC,QAAM,KAAK,cAAc;AACzB,QAAKH,QAAS,KAAK;AACnB,QAAKC,QAAS,KAAK;AACnB,QAAKC,QAAS,KAAK;AACnB,cAAY,IAAI,OAAM,QAAO,MAAKE,MAAO,IAAI,CAAC;;CAGlD,aAAsB,KAAK,OAAmB,UAA+B,EAAE,EAAyB;EACpG,MAAM,WAAW,gBAAgB,QAAQ,SAAS;EAClD,MAAMC,QAA6B;GAC/B,QAAQ,QAAQ,WAAW,SAAY,EAAE,GAAG,kBAAkB,QAAQ,QAAQ,SAAS;GACvF,QAAQ,cAAc,QAAQ,OAAO;GACrC,QAAQ,QAAQ,UAAU;GAC1B,MAAM,QAAQ,aAAa;GAC9B;EACD,MAAMC,QAAsB,EAAE,SAAS,MAAM,qBAAqB,OAAO,MAAM,EAAE;AACjF,SAAO,IAAI,aAAa;GACpB;GACA;GACA;GACA,eAAe;IACX,QAAQ,cAAc,OAAO,OAAO,UAAU,MAAM,KAAK;IACzD,SAAS,MAAM,OAAO,WAAW,IAAI,aAAa,QAAQ,YAAY,MAAM,OAAO;IACnF,WAAW,QAAQ;IACnB,QAAQ,QAAQ;IAChB,WAAW,MAAM;IACpB;GACJ,CAAC;;;CAIN,IAAI,UAA4B;AAC5B,SAAO,MAAKN,MAAO,QAAQ;;;;;;;;;;;;;;;;CAiB/B,SAAuC;EACnC,MAAM,MAAM,MAAKO,MAAO,WAAW,MAAKC,WAAY,CAAC;AACrD,QAAKD,QAAS,IAAI,WACR,UACA,GACT;AACD,SAAO;;CAGX,OAAO,KAAsB;AAEzB,MAAI,OAAO,YAAY,WAAY;AACnC,MAAI,MAAKJ,QAAS,QAAQ,MAAKM,SAAU;AACrC,QAAK,MAAM,aAAa,MAAKN,QAAU,KAAI,UAAU,OAAO,KAAK,OAAW,OAAKA,QAAS,OAAO,UAAU;AAC3G,SAAKM,UAAW,KAAK,IAAI,iBAAiB,IAAI,MAAKN,QAAS,KAAK;;AAErE,QAAKA,QAAS,IAAI,IAAI,QAAQ,IAAI,CAAC;;CAGvC,OAAMK,YAA2C;EAC7C,MAAM,WAAW,MAAKR,MAAO;EAC7B,MAAM,OAAO,MAAM,qBAAqB,MAAKC,OAAQ,MAAKC,MAAO;AACjE,QAAKF,MAAO,UAAU;EACtB,MAAM,cAAc,WAAW,SAAS,KAAK,WAAW,KAAK;AAC7D,MAAI,YAAa,OAAKU,QAAS;AAC/B,SAAO;GAAE,GAAG,cAAc,UAAU,KAAK;GAAE;GAAa;;CAI5D,UAAgB;AACZ,OAAK,MAAM,aAAa,MAAKP,SAAU;GACnC,MAAM,MAAM,UAAU,OAAO;AAC7B,OAAI,QAAQ,QAAW;AACnB,UAAKA,QAAS,OAAO,UAAU;AAC/B;;AAEJ,OAAI,CAAC,IAAI,aAAa,CAAE;GACxB,MAAM,YAAY,IAAI,OAAO,WAAW;AACxC,OAAI;AAEA,YAAQ,QAAQ,IAAI,OAAO,yBAAyB,CAAC,CAAC,OAAO,UAAmB,MAAKQ,aAAc,WAAW,MAAM,CAAC;YAChH,OAAO;AACZ,UAAKA,aAAc,WAAW,MAAM;;;;CAKhD,cAAc,WAA+B,OAAsB;EAC/D,MAAM,KAAK,cAAc,SAAY,KAAK,eAAe;EACzD,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACrE,MAAI;AACA,SAAKT,MAAO,KAAK;IAAE,MAAM;IAA0B,SAAS,oBAAoB,GAAG,IAAI;IAAU,CAAC;UAC9F"}