@askdkc/dsh-lsp-server 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Support DSH `0.1.7-rc.2` by updating the bundled LSP packages, host peer ranges, and isolated package verification.
6
+
7
+ ## 0.1.3
8
+
9
+ - Install the required DSH LSP service and tool automatically; require DSH `^0.1.3-alpha.2` and validate against `0.1.3-alpha.2`.
5
10
  - Connect the provider and extra tool to actual DSH services, schemas, session workspaces, and plugin disposal.
6
11
  - Implement real navigation, diagnostics, completion, document synchronization, configuration replies, timeouts, and bounded process cleanup.
7
12
  - Add CSS routing, Tailwind candidate ranking, executable availability checks, and working packaged CLI/declarations.
package/README.md CHANGED
@@ -6,20 +6,22 @@ Supports PHP/Blade via **PHPantom**, TypeScript/JavaScript, Svelte, HTML, CSS, a
6
6
 
7
7
  ## Install
8
8
 
9
- Requires Node.js **22.18+**. For PHP/Blade, install **PHPantom** with `phpantom_lsp` in `PATH`. The other language servers are included.
9
+ Requires Node.js **22.18+** and DSH **0.1.7-rc.2 or a compatible later 0.1.x release**. Compatibility is tested against **0.1.7-rc.2**; later DSH releases require their own verification. The required `@deepseek-ai/dsh-lsp` and `@deepseek-ai/dsh-tool-lsp` packages are installed automatically. For PHP/Blade, install **PHPantom** with `phpantom_lsp` in `PATH`. The other language servers are included.
10
10
 
11
11
  From npm:
12
12
 
13
13
  ```sh
14
- pnpm dsh plugin --profile web add @askdkc/dsh-lsp-server
14
+ npx @deepseek-ai/dsh@0.1.7-rc.2 plugin --profile web add @askdkc/dsh-lsp-server
15
15
  ```
16
16
 
17
17
  Or from GitHub:
18
18
 
19
19
  ```sh
20
- pnpm dsh plugin --profile web add github:askdkc/dsh-lsp-server
20
+ npx @deepseek-ai/dsh@0.1.7-rc.2 plugin --profile web add github:askdkc/dsh-lsp-server
21
21
  ```
22
22
 
23
+ If you run DSH from a source checkout with `pnpm dsh web`, use `pnpm dsh plugin --profile web add ...` instead.
24
+
23
25
  [Configuration, tool usage, and troubleshooting](docs/usage.md)
24
26
 
25
27
  ## License
package/docs/usage.md CHANGED
@@ -18,9 +18,22 @@ The five Node language servers and TypeScript are package dependencies. PHPantom
18
18
 
19
19
  See the [installation commands](../README.md#install).
20
20
 
21
- The bundle adds `lsp`, `lsp-webstack-provider`, `tool-lsp`, and `tool-lsp-extra` rows. It requires DSH's LSP/tool packages and the profile's `fs`, `subprocess`, `tools`, and `systemPrompt` services. DSH packages are host-provided peers; installing this package alone does not install the harness. If you already enabled another LSP provider for these extensions, remove its overlapping mappings first: DSH intentionally rejects duplicate ownership with `LSP_CONFLICT`. If your profile already declares the `lsp` or `tool-lsp` rows, compose the provider and extra-tool rows manually instead of inserting the whole bundle twice.
21
+ The bundle adds `lsp`, `lsp-webstack-provider`, `tool-lsp`, and `tool-lsp-extra` rows. Its `@deepseek-ai/dsh-lsp` and `@deepseek-ai/dsh-tool-lsp` dependencies are installed automatically; do not install them separately. The harness still provides the profile's `fs`, `subprocess`, `tools`, and `systemPrompt` services and the shared Cordis instance. Installing this package does not install the harness itself.
22
22
 
23
- These instructions follow [DSH's profile composition](https://github.com/deepseek-ai/deepseek-harness/blob/d347e703908d0406b7a7ef80e3a0e594d86b2215/apps/cli/README.md). No user profile is changed by this repository's tests or doctor command.
23
+ The bundled DSH LSP service and tool are pinned to `0.1.7-rc.2`. Host peer ranges start at `0.1.7-rc.2` and stop before `0.2.0`. They admit later stable `0.1.x` releases, but semver excludes prereleases of a different patch version. Only `0.1.7-rc.2` is verified here; test each later DSH release before relying on it. Older DSH releases are no longer supported.
24
+
25
+ DSH 0.1.7-rc.2 may stop `plugin add` with `ERR_PNPM_IGNORED_BUILDS` for `core-js`, a dependency of the bundled HTML/CSS server. Decide whether to allow its build script in DSH's plugin manager. To **deny** the script from the CLI, set `allowBuilds.core-js: false` in the selected profile's `pnpm-workspace.yaml` before adding this bundle:
26
+
27
+ ```yaml
28
+ allowBuilds:
29
+ core-js: false
30
+ ```
31
+
32
+ The packed-artifact test runs HTML/CSS servers with dependency scripts disabled. If an earlier CLI add stopped after writing the dependency, check that `@askdkc/dsh-lsp-server` appears in `dsh.profile.bundles` in that profile's `package.json`; a dependency entry alone does not activate the bundle. If it is absent, remove the package with `dsh plugin --profile web remove @askdkc/dsh-lsp-server`, set the build decision, then repeat the original add command. Use the same launcher prefix you use for `dsh web` (for example, `npx @deepseek-ai/dsh@0.1.7-rc.2` or `pnpm dsh` from a source checkout).
33
+
34
+ If you already enabled another LSP provider for these extensions, remove its overlapping mappings first: DSH intentionally rejects duplicate ownership with `LSP_CONFLICT`. If your profile already declares the `lsp` or `tool-lsp` rows, compose the provider and extra-tool rows manually instead of inserting the whole bundle twice.
35
+
36
+ These instructions follow [DSH's profile composition and bundle dependency resolution](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.7-rc.2/docs/user/develop/basic/publish.md). No user profile is changed by this repository's tests or doctor command.
24
37
 
25
38
  ## Tools
26
39
 
@@ -80,7 +93,7 @@ The JSON config file contains the provider configuration object above. Doctor ch
80
93
 
81
94
  ## Verification
82
95
 
83
- Source installs build automatically through `prepare`; npm releases include the built files. `.npmrc` prevents automatic resolution of the published DSH packages’ incomplete peer tree during development and Git builds.
96
+ Source installs build automatically through `prepare`; npm releases include the built files. `.npmrc` disables automatic peer installation during development and Git builds; development dependencies provide the host services needed by the tests.
84
97
 
85
98
  ```sh
86
99
  pnpm install --frozen-lockfile
@@ -89,9 +102,9 @@ pnpm test:e2e # real TS/JS, HTML, CSS, Svelte, Tailwind v3/v4
89
102
  PHPANTOM_E2E=1 pnpm test:e2e # additionally tests installed PHPantom with PHP and Blade
90
103
  ```
91
104
 
92
- The packed-artifact test extracts the archive into an isolated consumer, supplies DSH peers, imports its public exports, and runs a real TypeScript query. It also checks declaration paths and the executable doctor. E2E needs working OS file watchers; sandboxed macOS watchers may fail with `EMFILE`.
105
+ The packed-artifact test installs the archive into a fresh consumer with DSH's hoisted layout, peer auto-installation disabled, and dependency scripts disabled. It provides the host service packages but does not preinstall either LSP package, then verifies bundle imports, both tool registrations, and real TypeScript, HTML, and CSS queries. It also checks declaration paths and the executable doctor. The consumer install prefers cached packages but needs registry access for uncached packages or metadata. E2E needs working OS file watchers; sandboxed macOS watchers may fail with `EMFILE`.
93
106
 
94
- Integration tests run against the published DSH `0.0.1-rc.1` service/tool packages and Cordis 4.0.2. Contracts were also compared with upstream commit `d347e703908d0406b7a7ef80e3a0e594d86b2215` (`0.1.3-alpha.1`). The full Web UI and a source-built upstream application are not exercised here.
107
+ Integration tests run against the published DSH `0.1.7-rc.2` service/tool packages and Cordis 4.0.4. The full Web UI and a source-built upstream application are not exercised here.
95
108
 
96
109
  ### Dependency security
97
110
 
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","names":["CLASSIFIERS: ReadonlyArray<{ suffix: string; kind: FileKind }>","ROUTES: Record<ClassifiedFile['kind'], Route>","maxMessageBytes: number","messages: unknown[]","text: string","length: number | undefined","input: Readable","output: Writable","messages: unknown[]","isRecord","options: ServerSessionOptions","factory: SessionFactory<S>","release!: () => void","isRange","isRecord","isPosition","isRecord","isRange","isPosition","isRecord","config: ResolvedConfig","fs: HostFileSystem","subprocess: HostSubprocess","executable: string","auxiliary: typeof primary","omittedServers: string[]"],"sources":["../src/runtime/cancellation.ts","../src/host/dsh.ts","../src/routing/classifier.ts","../src/routing/route-table.ts","../src/routing/tailwind-candidate.ts","../src/protocol/initialize.ts","../src/runtime/framing.ts","../src/runtime/connection.ts","../src/runtime/server-session.ts","../src/runtime/server-pool.ts","../src/protocol/capabilities.ts","../src/protocol/normalize-hover.ts","../src/protocol/normalize-location.ts","../src/protocol/normalize-diagnostic.ts","../src/protocol/normalize-completion.ts","../src/merge/hover.ts","../src/runtime/webstack-runtime.ts","../src/provider.ts"],"sourcesContent":["export function abortError(): Error {\n const error = new Error('The operation was aborted')\n error.name = 'AbortError'\n return error\n}\n\nexport function throwIfAborted(signal?: AbortSignal): void {\n if (signal?.aborted) throw abortError()\n}\n\nexport function onAbort(signal: AbortSignal | undefined, callback: () => void): () => void {\n if (!signal) return () => {}\n if (signal.aborted) {\n callback()\n return () => {}\n }\n signal.addEventListener('abort', callback, { once: true })\n return () => signal.removeEventListener('abort', callback)\n}\n\nexport async function withAbort<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n throwIfAborted(signal)\n if (!signal) return promise\n return new Promise<T>((resolve, reject) => {\n const remove = onAbort(signal, () => reject(abortError()))\n promise.then((value) => { remove(); resolve(value) }, (error: unknown) => { remove(); reject(error) })\n })\n}\n","import type { FileSystem } from '@deepseek-ai/dsh-fs'\nimport { WebstackLspError } from '../errors.js'\nimport { throwIfAborted } from '../runtime/cancellation.js'\n\nexport type HostFileSystem = Pick<FileSystem, 'resolve' | 'stat' | 'processPath' | 'fileUrl' | 'contains' | 'streamText'>\nexport interface HostSource { workspace: string; workspaceUri: string; key: string; uri: string; text: string }\n\nexport async function readSource(fs: HostFileSystem, workspaceRoot: string, filePath: string, maxBytes: number, signal?: AbortSignal): Promise<HostSource> {\n if (!workspaceRoot?.trim() || !filePath?.trim()) throw new WebstackLspError('LSP_WORKSPACE_REQUIRED', 'workspaceRoot and filePath are required')\n throwIfAborted(signal)\n const options = signal ? { signal } : {}\n const root = await fs.resolve(workspaceRoot, options)\n if ((await fs.stat(root, signal))?.type !== 'directory') throw new Error('workspace root is not a directory')\n const workspace = fs.processPath(root)\n const target = await fs.resolve(filePath, { cwd: workspace, ...options })\n if (!fs.contains(root, target)) throw new Error('source is outside workspace')\n if ((await fs.stat(target, signal))?.type !== 'file') throw new Error('source is not a regular file')\n let text = '', bytes = 0\n for await (const chunk of await fs.streamText(target, signal)) {\n throwIfAborted(signal)\n bytes += Buffer.byteLength(chunk)\n if (bytes > maxBytes) throw new Error('source exceeds document limit')\n text += chunk\n }\n throwIfAborted(signal)\n return { workspace, workspaceUri: fs.fileUrl(root), key: root.targetKey, uri: fs.fileUrl(target), text }\n}\n","export type FileKind = 'blade' | 'php' | 'typescript' | 'typescriptreact' | 'javascript' | 'javascriptreact' | 'svelte' | 'html' | 'css'\n\nexport interface ClassifiedFile {\n path: string\n basename: string\n suffix: string\n kind: FileKind\n}\n\nconst CLASSIFIERS: ReadonlyArray<{ suffix: string; kind: FileKind }> = [\n { suffix: '.blade.php', kind: 'blade' },\n { suffix: '.typescriptreact', kind: 'typescriptreact' },\n { suffix: '.javascriptreact', kind: 'javascriptreact' },\n { suffix: '.tsx', kind: 'typescriptreact' },\n { suffix: '.jsx', kind: 'javascriptreact' },\n { suffix: '.mts', kind: 'typescript' },\n { suffix: '.cts', kind: 'typescript' },\n { suffix: '.mjs', kind: 'javascript' },\n { suffix: '.cjs', kind: 'javascript' },\n { suffix: '.svelte', kind: 'svelte' },\n { suffix: '.html', kind: 'html' },\n { suffix: '.htm', kind: 'html' },\n { suffix: '.php', kind: 'php' },\n { suffix: '.ts', kind: 'typescript' },\n { suffix: '.js', kind: 'javascript' },\n { suffix: '.css', kind: 'css' },\n { suffix: '.pcss', kind: 'css' },\n]\n\nexport function classifyFile(filePath: string, bladeSuffixes: string[] = ['.blade.php']): ClassifiedFile | undefined {\n const normalizedPath = filePath.replaceAll('\\\\', '/')\n const basename = normalizedPath.slice(normalizedPath.lastIndexOf('/') + 1).toLowerCase()\n if (!basename || basename === '.' || basename === '..' || basename.startsWith('.')) return undefined\n const customBlade = bladeSuffixes.map((suffix) => suffix.toLowerCase()).sort((left, right) => right.length - left.length)\n const classifiers = [...customBlade.map((suffix) => ({ suffix, kind: 'blade' as const })), ...CLASSIFIERS.filter((item) => !customBlade.includes(item.suffix))]\n const match = classifiers.find((item) => basename.endsWith(item.suffix))\n if (!match) return undefined\n return { path: normalizedPath, basename, suffix: match.suffix, kind: match.kind }\n}\n","import type { ServerId } from '../config.js'\nimport type { ClassifiedFile } from './classifier.js'\n\nexport interface Route {\n primary: { server: ServerId; languageId: string }\n auxiliary?: { server: 'tailwind'; languageId: string }\n}\n\nconst ROUTES: Record<ClassifiedFile['kind'], Route> = {\n blade: { primary: { server: 'phpantom', languageId: 'blade' }, auxiliary: { server: 'tailwind', languageId: 'html' } },\n php: { primary: { server: 'phpantom', languageId: 'php' } },\n typescript: { primary: { server: 'typescript', languageId: 'typescript' }, auxiliary: { server: 'tailwind', languageId: 'typescript' } },\n typescriptreact: { primary: { server: 'typescript', languageId: 'typescriptreact' }, auxiliary: { server: 'tailwind', languageId: 'typescriptreact' } },\n javascript: { primary: { server: 'typescript', languageId: 'javascript' }, auxiliary: { server: 'tailwind', languageId: 'javascript' } },\n javascriptreact: { primary: { server: 'typescript', languageId: 'javascriptreact' }, auxiliary: { server: 'tailwind', languageId: 'javascriptreact' } },\n svelte: { primary: { server: 'svelte', languageId: 'svelte' }, auxiliary: { server: 'tailwind', languageId: 'svelte' } },\n html: { primary: { server: 'html', languageId: 'html' }, auxiliary: { server: 'tailwind', languageId: 'html' } },\n css: { primary: { server: 'css', languageId: 'css' }, auxiliary: { server: 'tailwind', languageId: 'css' } },\n}\n\nexport function routeFor(file: ClassifiedFile): Route {\n const route = ROUTES[file.kind]\n return { primary: { ...route.primary }, ...(route.auxiliary ? { auxiliary: { ...route.auxiliary } } : {}) }\n}\n","const DEFAULT_PATTERNS = [\n /\\bclass\\s*=\\s*[\"'][^\"']*$/i,\n /\\bclassName\\s*=\\s*[\"'][^\"']*$/i,\n /\\bclass:list\\s*=\\s*[\"'][^\"']*$/i,\n /@apply\\s+[\\w-]*$/i,\n /\\b(?:clsx|cva)\\s*\\([^)]*[\"'][^\"']*$/i,\n]\n\nexport function hasTailwindCandidate(source: string, line: number, classRegex: Array<string | [string, string]> = [], character?: number, classAttributes: string[] = ['class', 'className', 'class:list']): boolean {\n const lines = source.split(/\\r?\\n/)\n const context = [...lines.slice(Math.max(0, line - 2), line), (lines[line] ?? '').slice(0, character)].join('\\n')\n if (classAttributes.some(attribute => {\n const index = context.lastIndexOf(attribute + '=')\n return index >= 0 && /^[\\\"'][^\\\"']*$/.test(context.slice(index + attribute.length + 1).trimStart())\n })) return true\n const configured = classRegex.flatMap((item) => Array.isArray(item) ? item : [item]).map((pattern) => new RegExp(pattern))\n return [...DEFAULT_PATTERNS, ...configured].some((pattern) => pattern.test(context))\n}\n","import type { InitializeParams, InitializeResult } from './types.js'\nimport type { JsonRpcConnection } from '../runtime/connection.js'\nimport { throwIfAborted } from '../runtime/cancellation.js'\n\nexport async function initializeServer(connection: JsonRpcConnection, params: InitializeParams, signal?: AbortSignal): Promise<InitializeResult> {\n throwIfAborted(signal)\n const value = await connection.request('initialize', params, signal)\n if (!isInitializeResult(value)) throw new Error('malformed initialize response')\n await connection.notify('initialized', {})\n return value\n}\n\nfunction isInitializeResult(value: unknown): value is InitializeResult {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && typeof (value as { capabilities?: unknown }).capabilities === 'object' && (value as { capabilities?: unknown }).capabilities !== null\n}\n","import { TextDecoder } from 'node:util'\n\nexport class JsonRpcFrameError extends Error {\n readonly code = 'LSP_MALFORMED_RESPONSE'\n\n constructor(message: string) {\n super(message)\n this.name = 'JsonRpcFrameError'\n }\n}\n\nexport class ContentLengthDecoder {\n private buffer = Buffer.alloc(0)\n private readonly decoder = new TextDecoder('utf-8', { fatal: true })\n\n constructor(private readonly maxMessageBytes: number) {\n if (!Number.isSafeInteger(maxMessageBytes) || maxMessageBytes <= 0) throw new RangeError('maxMessageBytes must be positive')\n }\n\n feed(chunk: Uint8Array): unknown[] {\n this.buffer = Buffer.concat([this.buffer, Buffer.from(chunk)])\n const messages: unknown[] = []\n while (true) {\n const headerEnd = this.buffer.indexOf(Buffer.from('\\r\\n\\r\\n'))\n if (headerEnd < 0) {\n if (this.buffer.length > 8192) throw new JsonRpcFrameError('header exceeds limit')\n break\n }\n const header = this.buffer.subarray(0, headerEnd).toString('ascii')\n const length = this.parseLength(header)\n const bodyStart = headerEnd + 4\n if (length > this.maxMessageBytes) throw new JsonRpcFrameError('message exceeds configured limit')\n if (this.buffer.length < bodyStart + length) break\n const body = this.buffer.subarray(bodyStart, bodyStart + length)\n this.buffer = this.buffer.subarray(bodyStart + length)\n let text: string\n try {\n text = this.decoder.decode(body)\n } catch {\n throw new JsonRpcFrameError('message is not valid UTF-8')\n }\n try {\n messages.push(JSON.parse(text) as unknown)\n } catch {\n throw new JsonRpcFrameError('message body is not valid JSON')\n }\n }\n return messages\n }\n\n end(): void {\n if (this.buffer.length > 0) throw new JsonRpcFrameError('incomplete JSON-RPC frame')\n }\n\n private parseLength(header: string): number {\n const lines = header.split('\\r\\n')\n let length: number | undefined\n for (const line of lines) {\n const separator = line.indexOf(':')\n if (separator < 1) throw new JsonRpcFrameError('malformed header')\n const key = line.slice(0, separator).toLowerCase()\n const value = line.slice(separator + 1).trim()\n if (key === 'content-length') {\n if (length !== undefined || !/^\\d+$/.test(value)) throw new JsonRpcFrameError('invalid Content-Length')\n length = Number(value)\n }\n }\n if (length === undefined || !Number.isSafeInteger(length)) throw new JsonRpcFrameError('Content-Length is required')\n return length\n }\n}\n\nexport function encodeJsonRpc(message: object): Buffer {\n const body = Buffer.from(JSON.stringify(message), 'utf8')\n return Buffer.concat([Buffer.from(`Content-Length: ${body.length}\\r\\n\\r\\n`, 'ascii'), body])\n}\n","import type { Readable, Writable } from 'node:stream'\nimport { abortError, onAbort, throwIfAborted } from './cancellation.js'\nimport { ContentLengthDecoder, encodeJsonRpc, JsonRpcFrameError } from './framing.js'\nimport type { JsonRpcConnectionOptions, JsonRpcId, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse } from '../protocol/types.js'\n\ninterface PendingRequest {\n resolve: (value: unknown) => void\n reject: (error: unknown) => void\n method: string\n}\n\nexport class JsonRpcConnection {\n private readonly decoder: ContentLengthDecoder\n private readonly pending = new Map<JsonRpcId, PendingRequest>()\n private readonly notificationListeners = new Set<(notification: JsonRpcNotification) => void>()\n private nextId = 1\n private closed = false\n private requestHandler: NonNullable<JsonRpcConnectionOptions['onServerRequest']>\n\n constructor(private readonly input: Readable, private readonly output: Writable, options: JsonRpcConnectionOptions) {\n this.decoder = new ContentLengthDecoder(options.maxMessageBytes)\n this.requestHandler = options.onServerRequest ?? (() => null)\n if (options.onNotification) this.notificationListeners.add(options.onNotification)\n input.on('data', (chunk: Buffer) => this.receive(chunk))\n input.once('end', () => this.close(new Error('LSP process closed stdout')))\n input.once('error', (error) => this.close(error))\n output.on('error', (error) => this.close(error))\n }\n\n get isOpen(): boolean { return !this.closed }\n\n onNotification(listener: (notification: JsonRpcNotification) => void): () => void {\n this.notificationListeners.add(listener)\n return () => this.notificationListeners.delete(listener)\n }\n\n setRequestHandler(handler: NonNullable<JsonRpcConnectionOptions['onServerRequest']>): void {\n this.requestHandler = handler\n }\n\n async request(method: string, params?: unknown, signal?: AbortSignal): Promise<unknown> {\n throwIfAborted(signal)\n if (this.closed) throw new Error('connection is closed')\n const id = this.nextId++\n const promise = new Promise<unknown>((resolve, reject) => this.pending.set(id, { resolve, reject, method }))\n void promise.catch(() => {})\n const remove = onAbort(signal, () => {\n void this.notify('$/cancelRequest', { id }).catch(() => {})\n this.pending.get(id)?.reject(abortError())\n this.pending.delete(id)\n })\n try {\n void this.write({ jsonrpc: '2.0', id, method, ...(params === undefined ? {} : { params }) }).catch(error => this.close(error))\n return await promise\n } finally {\n remove()\n this.pending.delete(id)\n }\n }\n\n async notify(method: string, params?: unknown): Promise<void> {\n if (this.closed) throw new Error('connection is closed')\n await this.write({ jsonrpc: '2.0', method, ...(params === undefined ? {} : { params }) })\n }\n\n close(reason = new Error('connection closed')): void {\n if (this.closed) return\n this.closed = true\n for (const pending of this.pending.values()) pending.reject(reason)\n this.pending.clear()\n }\n\n private receive(chunk: Buffer): void {\n if (this.closed) return\n let messages: unknown[]\n try {\n messages = this.decoder.feed(chunk)\n } catch (error) {\n this.close(error instanceof Error ? error : new JsonRpcFrameError('invalid frame'))\n return\n }\n for (const message of messages) this.dispatch(message)\n }\n\n private dispatch(value: unknown): void {\n if (!isRecord(value) || value.jsonrpc !== '2.0') return this.close(new JsonRpcFrameError('invalid JSON-RPC message'))\n if ('method' in value && typeof value.method === 'string') {\n if ('id' in value) {\n const request = value as unknown as JsonRpcRequest\n Promise.resolve().then(() => this.requestHandler(request.method, request.params)).then(\n (result) => this.write({ jsonrpc: '2.0', id: request.id, result }),\n (error: unknown) => this.write({ jsonrpc: '2.0', id: request.id, error: { code: -32603, message: error instanceof Error ? error.message : 'server request failed' } }),\n ).catch(() => {})\n } else {\n for (const listener of this.notificationListeners) listener(value as unknown as JsonRpcNotification)\n }\n return\n }\n if ('id' in value) {\n const response = value as unknown as JsonRpcResponse\n const pending = this.pending.get(response.id)\n if (!pending) return\n if (response.error) pending.reject(new Error(`${response.error.code}: ${response.error.message}`))\n else pending.resolve(response.result)\n this.pending.delete(response.id)\n }\n }\n\n private write(message: JsonRpcMessage): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.output.write(encodeJsonRpc(message), (error?: Error | null) => error ? reject(error) : resolve())\n })\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { SubprocessHandle } from '@deepseek-ai/dsh-subprocess'\nimport type { InitializeParams, InitializeResult } from '../protocol/types.js'\nimport { initializeServer } from '../protocol/initialize.js'\nimport { JsonRpcConnection } from './connection.js'\nimport { withAbort, throwIfAborted } from './cancellation.js'\n\nexport type SessionState = 'NEW' | 'STARTING' | 'READY' | 'STOPPING' | 'STOPPED' | 'FAILED'\nexport interface ServerSessionOptions {\n spawn(): SubprocessHandle\n initialize: InitializeParams\n configuration: unknown\n maxMessageBytes: number\n shutdown: { shutdownMs: number; killGraceMs: number }\n}\n\nexport class ServerSession {\n state: SessionState = 'NEW'\n capabilities: Record<string, unknown> = {}\n private child?: SubprocessHandle\n private connection?: JsonRpcConnection\n private stopping?: Promise<void>\n private readonly lifetime = new AbortController()\n constructor(private readonly options: ServerSessionOptions) {}\n\n async start(signal?: AbortSignal): Promise<InitializeResult> {\n throwIfAborted(signal)\n this.state = 'STARTING'\n try {\n const child = this.options.spawn()\n this.child = child\n // Observe failed spawn even when stdio could not be allocated.\n void child.done.catch(() => {})\n if (!child.stdout || !child.stdin) throw new Error('server stdio is unavailable')\n const connection = new JsonRpcConnection(child.stdout, child.stdin, {\n maxMessageBytes: this.options.maxMessageBytes,\n onServerRequest: (method, params) => this.answer(method, params),\n })\n this.connection = connection\n void child.done.then(() => connection.close(new Error('LSP process exited')), error => connection.close(error instanceof Error ? error : new Error('LSP spawn failed'))).then(() => {\n if (this.state !== 'STOPPING' && this.state !== 'STOPPED') this.state = 'FAILED'\n })\n const result = await initializeServer(connection, this.options.initialize, this.signal(signal))\n if (result.capabilities.positionEncoding && result.capabilities.positionEncoding !== 'utf-16') throw new Error('server requires unsupported position encoding')\n const sync = result.capabilities.textDocumentSync\n if (sync === undefined || sync === 0 || (typeof sync === 'object' && sync !== null && !(sync as { openClose?: boolean }).openClose)) throw new Error('server does not support document open/close')\n this.capabilities = result.capabilities\n await connection.notify('workspace/didChangeConfiguration', { settings: this.options.configuration })\n throwIfAborted(this.signal(signal))\n this.state = 'READY'\n return result\n } catch (error) {\n this.state = 'FAILED'\n await this.stop()\n throw error\n }\n }\n\n get usable(): boolean { return this.state === 'READY' && !!this.connection?.isOpen }\n isUsable(): boolean { return this.usable }\n async run<T>(task: (connection: JsonRpcConnection) => Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!this.usable || !this.connection) throw new Error('session is not ready')\n try { return await withAbort(task(this.connection), this.signal(signal)) }\n catch (error) {\n // Stop cancelled work before the next queued request can reuse this process.\n if (signal?.aborted || !this.connection.isOpen) await this.stop()\n throw error\n }\n }\n\n stop(): Promise<void> {\n return this.stopping ??= this.teardown()\n }\n private async teardown(): Promise<void> {\n this.state = 'STOPPING'\n this.lifetime.abort()\n const child = this.child, connection = this.connection\n const timeout = AbortSignal.timeout(this.options.shutdown.shutdownMs)\n if (connection?.isOpen) {\n try { await connection.request('shutdown', null, timeout); await connection.notify('exit') } catch {}\n }\n connection?.close(new Error('session stopped'))\n if (child) {\n child.terminate()\n if (!await child.waitForExit(AbortSignal.timeout(this.options.shutdown.killGraceMs + 1000))) throw new Error('language server process tree did not exit within the cleanup deadline')\n }\n this.state = 'STOPPED'\n }\n private signal(signal?: AbortSignal): AbortSignal { return signal ? AbortSignal.any([signal, this.lifetime.signal]) : this.lifetime.signal }\n private answer(method: string, params: unknown): unknown {\n if (method === 'workspace/applyEdit') return { applied: false, failureReason: 'read-only provider' }\n if (method === 'workspace/workspaceFolders') return this.options.initialize.workspaceFolders ?? []\n if (method === 'workspace/configuration') {\n const items = (params as { items?: Array<{ section?: string }> } | undefined)?.items ?? []\n return items.map(item => {\n let value = this.options.configuration\n for (const key of item.section?.split('.') ?? []) {\n value = typeof value === 'object' && value !== null ? (value as Record<string, unknown>)[key] : undefined\n }\n return value ?? null\n })\n }\n return null\n }\n}\n","import { throwIfAborted, withAbort } from './cancellation.js'\n\nexport interface PoolSession {\n readonly state: string\n start(signal?: AbortSignal): Promise<unknown>\n stop(): Promise<void>\n isUsable(): boolean\n}\nexport type SessionFactory<S extends PoolSession> = (serverId: string, workspace: string, signal?: AbortSignal) => Promise<S>\n\nexport class ServerPool<S extends PoolSession> {\n private readonly sessions = new Map<string, S>()\n private readonly creation = new Map<string, Promise<S>>()\n private readonly queues = new Map<string, Promise<void>>()\n private disposing = false\n constructor(private readonly factory: SessionFactory<S>) {}\n\n async getOrCreate(serverId: string, workspace: string, signal?: AbortSignal): Promise<S> {\n throwIfAborted(signal)\n if (this.disposing) throw new Error('server pool is disposing')\n const key = keyOf(serverId, workspace)\n const existing = this.sessions.get(key)\n if (existing?.isUsable()) return existing\n const pending = this.creation.get(key)\n if (pending) return withAbort(pending, signal)\n const creation = this.create(key, serverId, workspace, existing, signal)\n this.creation.set(key, creation)\n try { return await creation }\n finally { if (this.creation.get(key) === creation) this.creation.delete(key) }\n }\n\n run<T>(serverId: string, workspace: string, task: (session: S) => Promise<T>, signal?: AbortSignal): Promise<T> {\n return this.serialize(keyOf(serverId, workspace), async () => task(await this.getOrCreate(serverId, workspace, signal)), signal)\n }\n\n runWithRetry<T>(serverId: string, workspace: string, task: (session: S) => Promise<T>, signal?: AbortSignal, canReuse?: (session: S) => boolean): Promise<T> {\n // Keep failure eviction and the retry inside the same queue slot. A later query\n // must never enter a replacement process before the failed query finishes cleanup.\n return this.serialize(keyOf(serverId, workspace), async () => {\n const existing = this.sessions.get(keyOf(serverId, workspace))\n // Replacement belongs to this queue slot, after earlier work has completed.\n if (existing?.isUsable() && canReuse && !canReuse(existing)) await this.evict(serverId, workspace)\n for (let attempt = 0; ; attempt++) {\n const session = await this.getOrCreate(serverId, workspace, signal)\n try { return await task(session) }\n catch (error) {\n throwIfAborted(signal)\n if (attempt > 0 || session.isUsable()) throw error\n if (this.sessions.get(keyOf(serverId, workspace)) === session) await this.evict(serverId, workspace)\n }\n }\n }, signal)\n }\n\n async evict(serverId: string, workspace: string): Promise<void> {\n const key = keyOf(serverId, workspace)\n const session = this.sessions.get(key)\n this.sessions.delete(key)\n if (session) await session.stop()\n }\n\n async disposeAll(): Promise<void> {\n this.disposing = true\n const results = await Promise.allSettled([...this.sessions.values()].map(session => session.stop()))\n this.sessions.clear()\n await Promise.all([...this.creation.values()].map(creation => creation.then(session => session.stop(), () => {})))\n this.creation.clear()\n const failures = results.filter((result): result is PromiseRejectedResult => result.status === 'rejected')\n if (failures.length) throw new AggregateError(failures.map(result => result.reason), 'language server cleanup failed')\n }\n\n get size(): number { return this.sessions.size }\n\n private async serialize<T>(key: string, task: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n const previous = this.queues.get(key) ?? Promise.resolve()\n let release!: () => void\n const current = new Promise<void>(resolve => { release = resolve })\n this.queues.set(key, current)\n try {\n await withAbort(previous, signal)\n throwIfAborted(signal)\n return await task()\n } finally {\n // A cancelled waiter cannot let its successor bypass still-running work.\n void previous.then(release, release)\n void current.then(() => { if (this.queues.get(key) === current) this.queues.delete(key) })\n }\n }\n\n private async create(key: string, serverId: string, workspace: string, previous?: S, signal?: AbortSignal): Promise<S> {\n if (previous) { this.sessions.delete(key); await previous.stop() }\n throwIfAborted(signal)\n const session = await this.factory(serverId, workspace, signal)\n try { await session.start(signal) } catch (error) { await session.stop(); throw error }\n if (this.disposing) { await session.stop(); throw new Error('server pool is disposing') }\n this.sessions.set(key, session)\n return session\n }\n}\n\nexport function keyOf(serverId: string, workspace: string): string { return `${serverId}\\u0000${workspace}` }\n","export type StandardOperation = 'goToDefinition' | 'findReferences' | 'goToImplementation' | 'hover'\n\nexport function supportsOperation(capabilities: Record<string, unknown>, operation: StandardOperation): boolean {\n if (operation === 'goToDefinition') return capabilities.definitionProvider === true || isProvider(capabilities.definitionProvider)\n if (operation === 'findReferences') return capabilities.referencesProvider === true || isProvider(capabilities.referencesProvider)\n if (operation === 'goToImplementation') return capabilities.implementationProvider === true || isProvider(capabilities.implementationProvider)\n return capabilities.hoverProvider === true || isProvider(capabilities.hoverProvider)\n}\n\nfunction isProvider(value: unknown): boolean {\n return typeof value === 'object' && value !== null || value === true\n}\n\nexport function defaultServerRequest(method: string, params: unknown): unknown {\n if (method === 'workspace/configuration') {\n return Array.isArray(params) ? params.map(() => null) : []\n }\n if (method === 'window/workDoneProgress/create' || method === 'client/registerCapability' || method === 'client/unregisterCapability') return null\n if (method === 'workspace/applyEdit') return { applied: false, failureReason: 'read-only provider' }\n return null\n}\n","import type { LspRange } from '../service.js'\n\nexport interface NormalizedHover {\n contents: string\n range?: LspRange\n}\n\nexport function normalizeHover(value: unknown): NormalizedHover | null | undefined {\n if (value === null || value === undefined) return null\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as { contents?: unknown; range?: unknown }\n const contents = normalizeContents(record.contents)\n if (contents === undefined) return undefined\n return { contents, ...(isRange(record.range) ? { range: record.range } : {}) }\n}\n\nfunction normalizeContents(value: unknown): string | undefined {\n if (typeof value === 'string') return value\n if (Array.isArray(value)) {\n const parts = value.map((item) => typeof item === 'string' ? item : isRecord(item) && typeof item.value === 'string' ? item.value : undefined)\n return parts.every((item): item is string => item !== undefined) ? parts.join('\\n') : undefined\n }\n if (isRecord(value) && typeof value.value === 'string') return value.value\n return undefined\n}\n\nfunction isRange(value: unknown): value is LspRange {\n return isRecord(value) && isPosition(value.start) && isPosition(value.end)\n}\n\nfunction isPosition(value: unknown): boolean {\n return isRecord(value) && Number.isInteger(value.line) && Number.isInteger(value.character) && value.line >= 0 && value.character >= 0\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { LspPosition, LspRange } from '../service.js'\n\nexport interface NormalizedLocation {\n uri: string\n range: LspRange\n}\n\nexport function normalizeLocation(value: unknown): NormalizedLocation | undefined {\n if (isRecord(value) && typeof value.targetUri === 'string' && isRange(value.targetSelectionRange)) return { uri: value.targetUri, range: value.targetSelectionRange }\n if (!isRecord(value) || typeof value.uri !== 'string' || !isRange(value.range)) return undefined\n return { uri: value.uri, range: value.range }\n}\n\nexport function normalizeLocations(value: unknown): NormalizedLocation[] {\n const values = Array.isArray(value) ? value : value === null || value === undefined ? [] : [value]\n return values.map(normalizeLocation).filter((location): location is NormalizedLocation => location !== undefined)\n}\n\nfunction isRange(value: unknown): value is LspRange {\n return isRecord(value) && isPosition(value.start) && isPosition(value.end)\n}\n\nfunction isPosition(value: unknown): value is LspPosition {\n return isRecord(value) && Number.isInteger(value.line) && Number.isInteger(value.character) && value.line >= 0 && value.character >= 0\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { LspRange, NormalizedDiagnostic } from '../service.js'\n\nexport function normalizeDiagnostic(value: unknown, server: string, fallbackUri: string): NormalizedDiagnostic | undefined {\n if (!isRecord(value) || !isRange(value.range) || typeof value.message !== 'string') return undefined\n const uri = typeof value.uri === 'string' ? value.uri : fallbackUri\n const severity = typeof value.severity === 'number' && value.severity >= 1 && value.severity <= 4 ? value.severity as 1 | 2 | 3 | 4 : undefined\n const code = typeof value.code === 'string' || typeof value.code === 'number' ? value.code : undefined\n return { server, uri, range: value.range, message: value.message, ...(severity === undefined ? {} : { severity }), ...(code === undefined ? {} : { code }), ...(typeof value.source === 'string' ? { source: value.source } : {}) }\n}\n\nexport function normalizeDiagnostics(value: unknown, server: string, fallbackUri: string): NormalizedDiagnostic[] {\n const values = Array.isArray(value) ? value : []\n return values.map((item) => normalizeDiagnostic(item, server, fallbackUri)).filter((item): item is NormalizedDiagnostic => item !== undefined)\n}\n\nfunction isRange(value: unknown): value is LspRange {\n return isRecord(value) && isPosition(value.start) && isPosition(value.end)\n}\n\nfunction isPosition(value: unknown): boolean {\n return isRecord(value) && Number.isInteger(value.line) && Number.isInteger(value.character) && value.line >= 0 && value.character >= 0\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { NormalizedCompletionItem } from '../service.js'\n\nexport function normalizeCompletionItem(value: unknown, server: string): NormalizedCompletionItem | undefined {\n if (!isRecord(value) || typeof value.label !== 'string' || value.label.length === 0) return undefined\n return {\n server,\n label: value.label,\n ...(typeof value.kind === 'number' ? { kind: value.kind } : {}),\n ...(typeof value.detail === 'string' ? { detail: value.detail } : {}),\n ...(typeof value.documentation === 'string' ? { documentation: value.documentation } : {}),\n ...(typeof value.sortText === 'string' ? { sortText: value.sortText } : {}),\n ...(typeof value.filterText === 'string' ? { filterText: value.filterText } : {}),\n ...(typeof value.insertText === 'string' ? { insertText: value.insertText } : {}),\n ...(typeof value.insertTextFormat === 'number' ? { insertTextFormat: value.insertTextFormat } : {}),\n ...(typeof value.deprecated === 'boolean' ? { deprecated: value.deprecated } : {}),\n }\n}\n\nexport function normalizeCompletion(value: unknown, server: string): NormalizedCompletionItem[] {\n const items = isRecord(value) && Array.isArray(value.items) ? value.items : Array.isArray(value) ? value : []\n return items.map((item) => normalizeCompletionItem(item, server)).filter((item): item is NormalizedCompletionItem => item !== undefined)\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { NormalizedHover } from '../protocol/normalize-hover.js'\nimport type { LspRange } from '../service.js'\n\nexport interface ServerHover extends NormalizedHover {\n server: string\n}\n\nexport function mergeHover(primary: ServerHover | null | undefined, auxiliary: ServerHover | null | undefined): ServerHover | null {\n if (!primary && !auxiliary) return null\n if (!primary) return auxiliary ? { ...auxiliary } : null\n if (!auxiliary) return { ...primary }\n const contents = [primary.contents, auxiliary.contents].filter((value, index, values) => values.indexOf(value) === index)\n const range = sameRange(primary.range, auxiliary.range) ? primary.range : undefined\n return { server: primary.server, contents: contents.join('\\n\\n'), ...(range ? { range } : {}) }\n}\n\nfunction sameRange(left: LspRange | undefined, right: LspRange | undefined): boolean {\n return JSON.stringify(left) === JSON.stringify(right)\n}\n","import type { LspProviderQuery, LspQueryResult } from '@deepseek-ai/dsh-lsp'\nimport type { SubprocessService } from '@deepseek-ai/dsh-subprocess'\nimport type { ResolvedConfig, ServerId } from '../config.js'\nimport { SERVER_IDS } from '../config.js'\nimport { readSource, type HostFileSystem, type HostSource } from '../host/dsh.js'\nimport { classifyFile } from '../routing/classifier.js'\nimport { routeFor, type Route } from '../routing/route-table.js'\nimport { hasTailwindCandidate } from '../routing/tailwind-candidate.js'\nimport { resolveLaunch, initializationOptions, serverConfiguration } from '../servers/launch.js'\nimport { ServerSession } from './server-session.js'\nimport { ServerPool } from './server-pool.js'\nimport { throwIfAborted, withAbort } from './cancellation.js'\nimport { WebstackLspError } from '../errors.js'\nimport { supportsOperation } from '../protocol/capabilities.js'\nimport { normalizeHover } from '../protocol/normalize-hover.js'\nimport { normalizeLocations } from '../protocol/normalize-location.js'\nimport { normalizeDiagnostics } from '../protocol/normalize-diagnostic.js'\nimport { normalizeCompletion } from '../protocol/normalize-completion.js'\nimport { mergeHover } from '../merge/hover.js'\nimport { mergeDiagnostics } from '../merge/diagnostics.js'\nimport { mergeCompletions } from '../merge/completion.js'\nimport type { CompletionRequest, CompletionResult, DiagnosticsRequest, DiagnosticsResult, LspPosition, WebstackLspStatus } from '../service.js'\nimport type { JsonRpcConnection } from './connection.js'\n\nexport type HostSubprocess = Pick<SubprocessService, 'spawn' | 'resolveExecutable'>\nconst methods = { hover: 'textDocument/hover', goToDefinition: 'textDocument/definition', findReferences: 'textDocument/references', goToImplementation: 'textDocument/implementation' } as const\nconst clientCapabilities = {\n general: { positionEncodings: ['utf-16'] },\n workspace: { configuration: true, workspaceFolders: true, applyEdit: false },\n textDocument: {\n synchronization: { dynamicRegistration: false, didSave: false },\n hover: { contentFormat: ['markdown', 'plaintext'] },\n completion: { completionItem: { snippetSupport: true, documentationFormat: ['markdown', 'plaintext'] } },\n publishDiagnostics: { versionSupport: true }, diagnostic: {},\n },\n}\n\nexport class WebstackLspRuntime {\n private readonly pool: ServerPool<ServerSession>\n private readonly workspaces = new Map<string, HostSource>()\n private readonly lifetime = new AbortController()\n private readonly live = new Map<ServerSession, ServerId>()\n private readonly starts = new Map<string, number>()\n private readonly restarts = new Map<ServerId, number>()\n constructor(private readonly config: ResolvedConfig, private readonly fs: HostFileSystem, private readonly subprocess: HostSubprocess) {\n this.pool = new ServerPool(async (rawId, key, signal) => {\n const id = rawId as ServerId, source = this.workspaces.get(key)!\n const spec = await resolveLaunch(id, config, source.workspace)\n let executable: string\n try { executable = await subprocess.resolveExecutable(spec.command, spec.env, signal) }\n catch { throwIfAborted(signal); throw new WebstackLspError('LSP_UNAVAILABLE', `${id} executable is unavailable; run dsh-lsp-webstack --json`) }\n const session = new ServerSession({\n spawn: () => subprocess.spawn({ argv: [executable, ...spec.args], cwd: source.workspace, env: spec.env, stdio: { stdin: 'pipe', stdout: 'pipe', stderr: { maxBytes: config.limits.maxStderrBytes } }, graceMs: config.timeouts.killGraceMs }),\n initialize: { processId: null, rootUri: source.workspaceUri, workspaceFolders: [{ uri: source.workspaceUri, name: 'workspace' }], capabilities: clientCapabilities, initializationOptions: initializationOptions(id, config) },\n configuration: serverConfiguration(id, config), maxMessageBytes: config.limits.maxMessageBytes,\n shutdown: { shutdownMs: config.timeouts.shutdownMs, killGraceMs: config.timeouts.killGraceMs },\n })\n const slot = `${id}\\u0000${key}`\n if (this.starts.has(slot)) this.restarts.set(id, (this.restarts.get(id) ?? 0) + 1)\n this.starts.set(slot, (this.starts.get(slot) ?? 0) + 1)\n for (const [old] of this.live) if (old.state === 'STOPPED' || old.state === 'FAILED') this.live.delete(old)\n this.live.set(session, id)\n return session\n })\n }\n\n async navigation(request: LspProviderQuery, signal?: AbortSignal): Promise<LspQueryResult> {\n const deadline = this.signal(request.operation === 'hover' ? this.config.timeouts.primaryHoverMs : this.config.timeouts.navigationMs, signal)\n const [source, route] = await this.prepare(request, deadline)\n this.validatePosition(source.text, request.position)\n const result = await this.document(route.primary.server, source, route.primary.languageId, deadline, async (session, connection) => {\n if (!supportsOperation(session.capabilities, request.operation)) throw new WebstackLspError('LSP_UNSUPPORTED_OPERATION', `${route.primary.server} does not support ${request.operation}`)\n return connection.request(methods[request.operation], { textDocument: { uri: source.uri }, position: request.position, ...(request.operation === 'findReferences' ? { context: { includeDeclaration: true } } : {}) }, deadline)\n })\n if (request.operation !== 'hover') return { kind: 'locations', locations: normalizeLocations(result), resolvedWorkspaceUri: source.workspaceUri }\n const primary = normalizeHover(result)\n if (primary === undefined) throw new WebstackLspError('LSP_MALFORMED_RESPONSE', 'invalid hover result')\n let auxiliary = null\n if (this.useTailwind(route, source, request.position)) {\n const auxSignal = this.signal(this.config.timeouts.auxiliaryHoverMs, signal)\n try {\n const value = await this.document('tailwind', source, route.auxiliary!.languageId, auxSignal, (_session, connection) => connection.request('textDocument/hover', { textDocument: { uri: source.uri }, position: request.position }, auxSignal))\n auxiliary = normalizeHover(value) ?? null\n } catch { throwIfAborted(signal); throwIfAborted(this.lifetime.signal) }\n }\n const hover = mergeHover(primary && { ...primary, server: route.primary.server }, auxiliary && { ...auxiliary, server: 'tailwind' })\n return { kind: 'hover', hover: hover ? { contents: hover.contents, ...(hover.range ? { range: hover.range } : {}) } : null }\n }\n\n async completion(request: CompletionRequest, signal?: AbortSignal): Promise<CompletionResult> {\n const deadline = this.signal(this.config.timeouts.completionMs, signal)\n const [source, route] = await this.prepare(request, deadline)\n this.validatePosition(source.text, request.position)\n const query = (id: ServerId, language: string) => this.document(id, source, language, deadline, (session, connection) => {\n if (!session.capabilities.completionProvider) throw new WebstackLspError('LSP_UNSUPPORTED_OPERATION', `${id} does not support completion`)\n return connection.request('textDocument/completion', { textDocument: { uri: source.uri }, position: request.position, context: { triggerKind: request.triggerKind ?? 1, ...(request.triggerCharacter ? { triggerCharacter: request.triggerCharacter } : {}) } }, deadline)\n }).then(value => {\n const prefix = source.text.split(/\\r?\\n/)[request.position.line]!.slice(0, request.position.character).match(/[\\w$:@/!\\[\\]-]+$/)?.[0]?.toLowerCase() ?? ''\n // Servers such as Tailwind return the whole catalog; the client must rank the typed prefix before applying a result cap.\n return normalizeCompletion(value, id).sort((a, b) => Number((b.filterText ?? b.label).toLowerCase().startsWith(prefix)) - Number((a.filterText ?? a.label).toLowerCase().startsWith(prefix)))\n })\n const primary = await query(route.primary.server, route.primary.languageId)\n let auxiliary: typeof primary = []\n if (this.useTailwind(route, source, request.position)) {\n try { auxiliary = await query('tailwind', route.auxiliary!.languageId) } catch { throwIfAborted(signal); throwIfAborted(this.lifetime.signal) }\n }\n return mergeCompletions([primary, auxiliary], { maxCompletions: Number.MAX_SAFE_INTEGER, maxResultChars: Number.MAX_SAFE_INTEGER })\n }\n\n async diagnostics(request: DiagnosticsRequest, signal?: AbortSignal): Promise<DiagnosticsResult> {\n const deadline = this.signal(this.config.timeouts.diagnosticsMs, signal)\n const [source, route] = await this.prepare(request, deadline)\n const selected = [route.primary, ...(route.auxiliary && this.config.tailwind.enabled ? [route.auxiliary] : [])].filter(item => this.config.servers[item.server].enabled && (!request.servers || request.servers.includes(item.server)))\n if (!selected.length) throw new WebstackLspError('LSP_UNAVAILABLE', 'no selected diagnostic server supports this file')\n const omittedServers: string[] = []\n const groups = await Promise.all(selected.map(async item => {\n try {\n const value = await this.document(item.server, source, item.languageId, deadline, async (session, connection, opened) => {\n if (session.capabilities.diagnosticProvider) {\n await opened()\n const report = await connection.request('textDocument/diagnostic', { textDocument: { uri: source.uri } }, deadline) as { items?: unknown }\n return report?.items ?? []\n }\n // Subscribe before didOpen; do not confuse a missing publication with a clean file.\n let remove = () => {}\n const published = new Promise<unknown>(resolve => {\n remove = connection.onNotification(message => {\n const p = message.params as { uri?: string; diagnostics?: unknown; version?: number } | undefined\n if (message.method === 'textDocument/publishDiagnostics' && p?.uri === source.uri && (p.version === undefined || p.version === 1)) resolve(p.diagnostics)\n })\n })\n try { await opened(); return await withAbort(published, deadline) } finally { remove() }\n }, true)\n return normalizeDiagnostics(value, item.server, source.uri).filter(d => !request.severity || request.severity === 'all' || d.severity === (request.severity === 'error' ? 1 : 2))\n } catch (error) {\n throwIfAborted(signal); throwIfAborted(this.lifetime.signal)\n if (item.server === route.primary.server || this.config.missingServerPolicy === 'error') throw error\n omittedServers.push(item.server)\n return []\n }\n }))\n return { ...mergeDiagnostics(groups, { maxDiagnostics: Number.MAX_SAFE_INTEGER, maxResultChars: Number.MAX_SAFE_INTEGER }), ...(omittedServers.length ? { omittedServers: omittedServers.sort() } : {}) }\n }\n\n async status(): Promise<WebstackLspStatus> {\n return { providerId: this.config.providerId, servers: await Promise.all(SERVER_IDS.map(async id => {\n const config = this.config.servers[id]\n let available = false\n try {\n const launch = await resolveLaunch(id, this.config, '.')\n await this.subprocess.resolveExecutable(launch.command, launch.env, this.signal(5000))\n available = true\n } catch {}\n return { id, enabled: config.enabled && (id !== 'tailwind' || this.config.tailwind.enabled), available, source: config.mode, liveWorkspaces: [...this.live].filter(([s, server]) => server === id && s.isUsable()).length, restarts: this.restarts.get(id) ?? 0 }\n })) }\n }\n\n async dispose(): Promise<void> { this.lifetime.abort(); await this.pool.disposeAll(); this.workspaces.clear(); this.live.clear() }\n\n private signal(ms: number, signal?: AbortSignal): AbortSignal { return AbortSignal.any([this.lifetime.signal, AbortSignal.timeout(ms), ...(signal ? [signal] : [])]) }\n private async prepare(request: { workspaceRoot: string; filePath: string }, signal: AbortSignal): Promise<[HostSource, Route]> {\n throwIfAborted(signal)\n const file = classifyFile(request.filePath, this.config.routing.bladeSuffixes)\n if (!file) throw new WebstackLspError('LSP_UNAVAILABLE', 'unsupported file extension')\n const source = await readSource(this.fs, request.workspaceRoot, request.filePath, this.config.limits.maxDocumentBytes, signal).catch(error => { throwIfAborted(signal); throw error })\n this.workspaces.set(source.key, { ...source, text: '' })\n return [source, routeFor(file)]\n }\n private validatePosition(text: string, position: LspPosition): void {\n const line = text.split(/\\r?\\n/)[position.line]\n if (!Number.isSafeInteger(position.line) || !Number.isSafeInteger(position.character) || position.line < 0 || position.character < 0 || line === undefined || position.character > line.length) throw new RangeError('position is outside document (zero-based UTF-16 required)')\n }\n private useTailwind(route: Route, source: HostSource, position: LspPosition): boolean {\n return !!route.auxiliary && this.config.tailwind.enabled && this.config.servers.tailwind.enabled && (route.primary.languageId === 'blade' || this.config.routing.tailwindLanguages.includes(route.primary.languageId) || route.primary.languageId === 'css') && (this.config.tailwind.queryStrategy === 'always' || hasTailwindCandidate(source.text, position.line, this.config.tailwind.classRegex, position.character, this.config.tailwind.classAttributes))\n }\n private async document<T>(id: ServerId, source: HostSource, language: string, signal: AbortSignal, task: (session: ServerSession, connection: JsonRpcConnection, open: () => Promise<void>) => Promise<T>, manualOpen = false): Promise<T> {\n if (!this.config.servers[id].enabled) throw new WebstackLspError('LSP_UNAVAILABLE', `${id} is disabled`)\n return this.pool.runWithRetry(id, source.key, session => session.run(async connection => {\n let opened = false\n const open = async () => { opened = true; await connection.notify('textDocument/didOpen', { textDocument: { uri: source.uri, languageId: language, version: 1, text: source.text } }) }\n try { if (!manualOpen) await open(); return await task(session, connection, open) }\n finally { if (opened && connection.isOpen) await connection.notify('textDocument/didClose', { textDocument: { uri: source.uri } }).catch(() => {}) }\n }, signal), signal, manualOpen ? session => {\n // Push notifications can omit document versions. A delayed didClose clear\n // from a previous operation is indistinguishable from a fresh clean result.\n // Use a fresh process for push diagnostics; pull responses have request IDs.\n return !!session.capabilities.diagnosticProvider\n } : undefined)\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { LspProviderId } from '@deepseek-ai/dsh-lsp'\nimport type { LspProvider, LspProviderQuery, LspQueryResult } from '@deepseek-ai/dsh-lsp'\nimport type { Config as PluginConfig, ResolvedConfig } from './config.js'\nimport { resolveConfig } from './config.js'\nimport type { WebstackLspService } from './service.js'\nimport { createWebstackLspService } from './service.js'\nimport { WebstackLspRuntime } from './runtime/webstack-runtime.js'\nimport type {} from '@deepseek-ai/dsh-fs'\nimport type {} from '@deepseek-ai/dsh-subprocess'\n\nexport type { LspProvider, LspProviderQuery, LspQueryResult }\nexport type Config = PluginConfig\nexport const name = 'lsp-webstack-provider'\nexport const inject = ['fs', 'lsp', 'subprocess']\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { webstackLsp: WebstackLspService }\n}\n\nexport const OUTER_EXTENSION_MAP = {\n '.php': 'php', '.ts': 'typescript', '.tsx': 'typescriptreact', '.mts': 'typescript', '.cts': 'typescript',\n '.js': 'javascript', '.jsx': 'javascriptreact', '.mjs': 'javascript', '.cjs': 'javascript',\n '.svelte': 'svelte', '.html': 'html', '.htm': 'html', '.css': 'css', '.pcss': 'css',\n} as const\n\nexport interface CompositeRuntime {\n navigation(request: LspProviderQuery, signal?: AbortSignal): Promise<LspQueryResult>\n dispose?(): Promise<void>\n}\n\nexport function createCompositeProvider(runtime: CompositeRuntime, config: Pick<ResolvedConfig, 'providerId'> = { providerId: 'webstack' }): LspProvider {\n return { id: LspProviderId(config.providerId), extensionToLanguage: { ...OUTER_EXTENSION_MAP }, query: (request, signal) => runtime.navigation(request, signal) }\n}\n\nexport async function apply(ctx: Context, config: unknown = {}): Promise<void> {\n const resolved = resolveConfig(config)\n const runtime = new WebstackLspRuntime(resolved, ctx.fs, ctx.subprocess)\n await ctx.effect(async function* () {\n yield () => runtime.dispose()\n if (resolved.missingServerPolicy === 'error') {\n const missing = (await runtime.status()).servers.filter(server => server.enabled && !server.available)\n if (missing.length) throw new Error(`unavailable language servers: ${missing.map(server => server.id).join(', ')}`)\n }\n yield ctx.lsp.registerProvider(createCompositeProvider(runtime, resolved))\n yield ctx.provide('webstackLsp', createWebstackLspService(runtime))\n }, 'webstack LSP provider')\n}\n"],"mappings":";;;;;;;AAAA,SAAgB,aAAoB;CAClC,MAAM,wBAAQ,IAAI,MAAM,4BAA4B;AACpD,OAAM,OAAO;AACb,QAAO;;AAGT,SAAgB,eAAe,QAA4B;AACzD,KAAI,QAAQ,QAAS,OAAM,YAAY;;AAGzC,SAAgB,QAAQ,QAAiC,UAAkC;AACzF,KAAI,CAAC,OAAQ,cAAa;AAC1B,KAAI,OAAO,SAAS;AAClB,YAAU;AACV,eAAa;;AAEf,QAAO,iBAAiB,SAAS,UAAU,EAAE,MAAM,MAAM,CAAC;AAC1D,cAAa,OAAO,oBAAoB,SAAS,SAAS;;AAG5D,eAAsB,UAAa,SAAqB,QAAkC;AACxF,gBAAe,OAAO;AACtB,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,IAAI,SAAY,SAAS,WAAW;EACzC,MAAM,SAAS,QAAQ,cAAc,OAAO,YAAY,CAAC,CAAC;AAC1D,UAAQ,MAAM,UAAU;AAAE,WAAQ;AAAE,WAAQ,MAAM;MAAK,UAAmB;AAAE,WAAQ;AAAE,UAAO,MAAM;IAAG;GACtG;;;;;ACnBJ,eAAsB,WAAW,IAAoB,eAAuB,UAAkB,UAAkB,QAA2C;AACzJ,KAAI,CAAC,eAAe,MAAM,IAAI,CAAC,UAAU,MAAM,CAAE,OAAM,IAAI,iBAAiB,0BAA0B,0CAA0C;AAChJ,gBAAe,OAAO;CACtB,MAAM,UAAU,SAAS,EAAE,QAAQ,GAAG,EAAE;CACxC,MAAM,OAAO,MAAM,GAAG,QAAQ,eAAe,QAAQ;AACrD,MAAK,MAAM,GAAG,KAAK,MAAM,OAAO,GAAG,SAAS,YAAa,OAAM,IAAI,MAAM,oCAAoC;CAC7G,MAAM,YAAY,GAAG,YAAY,KAAK;CACtC,MAAM,SAAS,MAAM,GAAG,QAAQ,UAAU;EAAE,KAAK;EAAW,GAAG;EAAS,CAAC;AACzE,KAAI,CAAC,GAAG,SAAS,MAAM,OAAO,CAAE,OAAM,IAAI,MAAM,8BAA8B;AAC9E,MAAK,MAAM,GAAG,KAAK,QAAQ,OAAO,GAAG,SAAS,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CACrG,IAAI,OAAO,IAAI,QAAQ;AACvB,YAAW,MAAM,SAAS,MAAM,GAAG,WAAW,QAAQ,OAAO,EAAE;AAC7D,iBAAe,OAAO;AACtB,WAAS,OAAO,WAAW,MAAM;AACjC,MAAI,QAAQ,SAAU,OAAM,IAAI,MAAM,gCAAgC;AACtE,UAAQ;;AAEV,gBAAe,OAAO;AACtB,QAAO;EAAE;EAAW,cAAc,GAAG,QAAQ,KAAK;EAAE,KAAK,KAAK;EAAW,KAAK,GAAG,QAAQ,OAAO;EAAE;EAAM;;;;;AChB1G,MAAMA,cAAiE;CACrE;EAAE,QAAQ;EAAc,MAAM;EAAS;CACvC;EAAE,QAAQ;EAAoB,MAAM;EAAmB;CACvD;EAAE,QAAQ;EAAoB,MAAM;EAAmB;CACvD;EAAE,QAAQ;EAAQ,MAAM;EAAmB;CAC3C;EAAE,QAAQ;EAAQ,MAAM;EAAmB;CAC3C;EAAE,QAAQ;EAAQ,MAAM;EAAc;CACtC;EAAE,QAAQ;EAAQ,MAAM;EAAc;CACtC;EAAE,QAAQ;EAAQ,MAAM;EAAc;CACtC;EAAE,QAAQ;EAAQ,MAAM;EAAc;CACtC;EAAE,QAAQ;EAAW,MAAM;EAAU;CACrC;EAAE,QAAQ;EAAS,MAAM;EAAQ;CACjC;EAAE,QAAQ;EAAQ,MAAM;EAAQ;CAChC;EAAE,QAAQ;EAAQ,MAAM;EAAO;CAC/B;EAAE,QAAQ;EAAO,MAAM;EAAc;CACrC;EAAE,QAAQ;EAAO,MAAM;EAAc;CACrC;EAAE,QAAQ;EAAQ,MAAM;EAAO;CAC/B;EAAE,QAAQ;EAAS,MAAM;EAAO;CACjC;AAED,SAAgB,aAAa,UAAkB,gBAA0B,CAAC,aAAa,EAA8B;CACnH,MAAM,iBAAiB,SAAS,WAAW,MAAM,IAAI;CACrD,MAAM,WAAW,eAAe,MAAM,eAAe,YAAY,IAAI,GAAG,EAAE,CAAC,aAAa;AACxF,KAAI,CAAC,YAAY,aAAa,OAAO,aAAa,QAAQ,SAAS,WAAW,IAAI,CAAE,QAAO;CAC3F,MAAM,cAAc,cAAc,KAAK,WAAW,OAAO,aAAa,CAAC,CAAC,MAAM,MAAM,UAAU,MAAM,SAAS,KAAK,OAAO;CAEzH,MAAM,QADc,CAAC,GAAG,YAAY,KAAK,YAAY;EAAE;EAAQ,MAAM;EAAkB,EAAE,EAAE,GAAG,YAAY,QAAQ,SAAS,CAAC,YAAY,SAAS,KAAK,OAAO,CAAC,CAAC,CACrI,MAAM,SAAS,SAAS,SAAS,KAAK,OAAO,CAAC;AACxE,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EAAE,MAAM;EAAgB;EAAU,QAAQ,MAAM;EAAQ,MAAM,MAAM;EAAM;;;;;AC7BnF,MAAMC,SAAgD;CACpD,OAAO;EAAE,SAAS;GAAE,QAAQ;GAAY,YAAY;GAAS;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAQ;EAAE;CACtH,KAAK,EAAE,SAAS;EAAE,QAAQ;EAAY,YAAY;EAAO,EAAE;CAC3D,YAAY;EAAE,SAAS;GAAE,QAAQ;GAAc,YAAY;GAAc;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAc;EAAE;CACxI,iBAAiB;EAAE,SAAS;GAAE,QAAQ;GAAc,YAAY;GAAmB;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAmB;EAAE;CACvJ,YAAY;EAAE,SAAS;GAAE,QAAQ;GAAc,YAAY;GAAc;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAc;EAAE;CACxI,iBAAiB;EAAE,SAAS;GAAE,QAAQ;GAAc,YAAY;GAAmB;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAmB;EAAE;CACvJ,QAAQ;EAAE,SAAS;GAAE,QAAQ;GAAU,YAAY;GAAU;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAU;EAAE;CACxH,MAAM;EAAE,SAAS;GAAE,QAAQ;GAAQ,YAAY;GAAQ;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAQ;EAAE;CAChH,KAAK;EAAE,SAAS;GAAE,QAAQ;GAAO,YAAY;GAAO;EAAE,WAAW;GAAE,QAAQ;GAAY,YAAY;GAAO;EAAE;CAC7G;AAED,SAAgB,SAAS,MAA6B;CACpD,MAAM,QAAQ,OAAO,KAAK;AAC1B,QAAO;EAAE,SAAS,EAAE,GAAG,MAAM,SAAS;EAAE,GAAI,MAAM,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,WAAW,EAAE,GAAG,EAAE;EAAG;;;;;ACtB7G,MAAM,mBAAmB;CACvB;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,qBAAqB,QAAgB,MAAc,aAA+C,EAAE,EAAE,WAAoB,kBAA4B;CAAC;CAAS;CAAa;CAAa,EAAW;CACnN,MAAM,QAAQ,OAAO,MAAM,QAAQ;CACnC,MAAM,UAAU,CAAC,GAAG,MAAM,MAAM,KAAK,IAAI,GAAG,OAAO,EAAE,EAAE,KAAK,GAAG,MAAM,SAAS,IAAI,MAAM,GAAG,UAAU,CAAC,CAAC,KAAK,KAAK;AACjH,KAAI,gBAAgB,MAAK,cAAa;EACpC,MAAM,QAAQ,QAAQ,YAAY,YAAY,IAAI;AAClD,SAAO,SAAS,KAAK,iBAAiB,KAAK,QAAQ,MAAM,QAAQ,UAAU,SAAS,EAAE,CAAC,WAAW,CAAC;GACnG,CAAE,QAAO;CACX,MAAM,aAAa,WAAW,SAAS,SAAS,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,YAAY,IAAI,OAAO,QAAQ,CAAC;AAC1H,QAAO,CAAC,GAAG,kBAAkB,GAAG,WAAW,CAAC,MAAM,YAAY,QAAQ,KAAK,QAAQ,CAAC;;;;;ACZtF,eAAsB,iBAAiB,YAA+B,QAA0B,QAAiD;AAC/I,gBAAe,OAAO;CACtB,MAAM,QAAQ,MAAM,WAAW,QAAQ,cAAc,QAAQ,OAAO;AACpE,KAAI,CAAC,mBAAmB,MAAM,CAAE,OAAM,IAAI,MAAM,gCAAgC;AAChF,OAAM,WAAW,OAAO,eAAe,EAAE,CAAC;AAC1C,QAAO;;AAGT,SAAS,mBAAmB,OAA2C;AACrE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAI,OAAQ,MAAqC,iBAAiB,YAAa,MAAqC,iBAAiB;;;;;ACXlN,IAAa,oBAAb,cAAuC,MAAM;CAC3C,AAAS,OAAO;CAEhB,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAIhB,IAAa,uBAAb,MAAkC;CAChC,AAAQ,SAAS,OAAO,MAAM,EAAE;CAChC,AAAiB,UAAU,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,CAAC;CAEpE,YAAY,AAAiBC,iBAAyB;EAAzB;AAC3B,MAAI,CAAC,OAAO,cAAc,gBAAgB,IAAI,mBAAmB,EAAG,OAAM,IAAI,WAAW,mCAAmC;;CAG9H,KAAK,OAA8B;AACjC,OAAK,SAAS,OAAO,OAAO,CAAC,KAAK,QAAQ,OAAO,KAAK,MAAM,CAAC,CAAC;EAC9D,MAAMC,WAAsB,EAAE;AAC9B,SAAO,MAAM;GACX,MAAM,YAAY,KAAK,OAAO,QAAQ,OAAO,KAAK,WAAW,CAAC;AAC9D,OAAI,YAAY,GAAG;AACjB,QAAI,KAAK,OAAO,SAAS,KAAM,OAAM,IAAI,kBAAkB,uBAAuB;AAClF;;GAEF,MAAM,SAAS,KAAK,OAAO,SAAS,GAAG,UAAU,CAAC,SAAS,QAAQ;GACnE,MAAM,SAAS,KAAK,YAAY,OAAO;GACvC,MAAM,YAAY,YAAY;AAC9B,OAAI,SAAS,KAAK,gBAAiB,OAAM,IAAI,kBAAkB,mCAAmC;AAClG,OAAI,KAAK,OAAO,SAAS,YAAY,OAAQ;GAC7C,MAAM,OAAO,KAAK,OAAO,SAAS,WAAW,YAAY,OAAO;AAChE,QAAK,SAAS,KAAK,OAAO,SAAS,YAAY,OAAO;GACtD,IAAIC;AACJ,OAAI;AACF,WAAO,KAAK,QAAQ,OAAO,KAAK;WAC1B;AACN,UAAM,IAAI,kBAAkB,6BAA6B;;AAE3D,OAAI;AACF,aAAS,KAAK,KAAK,MAAM,KAAK,CAAY;WACpC;AACN,UAAM,IAAI,kBAAkB,iCAAiC;;;AAGjE,SAAO;;CAGT,MAAY;AACV,MAAI,KAAK,OAAO,SAAS,EAAG,OAAM,IAAI,kBAAkB,4BAA4B;;CAGtF,AAAQ,YAAY,QAAwB;EAC1C,MAAM,QAAQ,OAAO,MAAM,OAAO;EAClC,IAAIC;AACJ,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,YAAY,KAAK,QAAQ,IAAI;AACnC,OAAI,YAAY,EAAG,OAAM,IAAI,kBAAkB,mBAAmB;GAClE,MAAM,MAAM,KAAK,MAAM,GAAG,UAAU,CAAC,aAAa;GAClD,MAAM,QAAQ,KAAK,MAAM,YAAY,EAAE,CAAC,MAAM;AAC9C,OAAI,QAAQ,kBAAkB;AAC5B,QAAI,WAAW,UAAa,CAAC,QAAQ,KAAK,MAAM,CAAE,OAAM,IAAI,kBAAkB,yBAAyB;AACvG,aAAS,OAAO,MAAM;;;AAG1B,MAAI,WAAW,UAAa,CAAC,OAAO,cAAc,OAAO,CAAE,OAAM,IAAI,kBAAkB,6BAA6B;AACpH,SAAO;;;AAIX,SAAgB,cAAc,SAAyB;CACrD,MAAM,OAAO,OAAO,KAAK,KAAK,UAAU,QAAQ,EAAE,OAAO;AACzD,QAAO,OAAO,OAAO,CAAC,OAAO,KAAK,mBAAmB,KAAK,OAAO,WAAW,QAAQ,EAAE,KAAK,CAAC;;;;;AC/D9F,IAAa,oBAAb,MAA+B;CAC7B,AAAiB;CACjB,AAAiB,0BAAU,IAAI,KAAgC;CAC/D,AAAiB,wCAAwB,IAAI,KAAkD;CAC/F,AAAQ,SAAS;CACjB,AAAQ,SAAS;CACjB,AAAQ;CAER,YAAY,AAAiBC,OAAiB,AAAiBC,QAAkB,SAAmC;EAAvF;EAAkC;AAC7D,OAAK,UAAU,IAAI,qBAAqB,QAAQ,gBAAgB;AAChE,OAAK,iBAAiB,QAAQ,0BAA0B;AACxD,MAAI,QAAQ,eAAgB,MAAK,sBAAsB,IAAI,QAAQ,eAAe;AAClF,QAAM,GAAG,SAAS,UAAkB,KAAK,QAAQ,MAAM,CAAC;AACxD,QAAM,KAAK,aAAa,KAAK,sBAAM,IAAI,MAAM,4BAA4B,CAAC,CAAC;AAC3E,QAAM,KAAK,UAAU,UAAU,KAAK,MAAM,MAAM,CAAC;AACjD,SAAO,GAAG,UAAU,UAAU,KAAK,MAAM,MAAM,CAAC;;CAGlD,IAAI,SAAkB;AAAE,SAAO,CAAC,KAAK;;CAErC,eAAe,UAAmE;AAChF,OAAK,sBAAsB,IAAI,SAAS;AACxC,eAAa,KAAK,sBAAsB,OAAO,SAAS;;CAG1D,kBAAkB,SAAyE;AACzF,OAAK,iBAAiB;;CAGxB,MAAM,QAAQ,QAAgB,QAAkB,QAAwC;AACtF,iBAAe,OAAO;AACtB,MAAI,KAAK,OAAQ,OAAM,IAAI,MAAM,uBAAuB;EACxD,MAAM,KAAK,KAAK;EAChB,MAAM,UAAU,IAAI,SAAkB,SAAS,WAAW,KAAK,QAAQ,IAAI,IAAI;GAAE;GAAS;GAAQ;GAAQ,CAAC,CAAC;AAC5G,EAAK,QAAQ,YAAY,GAAG;EAC5B,MAAM,SAAS,QAAQ,cAAc;AACnC,GAAK,KAAK,OAAO,mBAAmB,EAAE,IAAI,CAAC,CAAC,YAAY,GAAG;AAC3D,QAAK,QAAQ,IAAI,GAAG,EAAE,OAAO,YAAY,CAAC;AAC1C,QAAK,QAAQ,OAAO,GAAG;IACvB;AACF,MAAI;AACF,GAAK,KAAK,MAAM;IAAE,SAAS;IAAO;IAAI;IAAQ,GAAI,WAAW,SAAY,EAAE,GAAG,EAAE,QAAQ;IAAG,CAAC,CAAC,OAAM,UAAS,KAAK,MAAM,MAAM,CAAC;AAC9H,UAAO,MAAM;YACL;AACR,WAAQ;AACR,QAAK,QAAQ,OAAO,GAAG;;;CAI3B,MAAM,OAAO,QAAgB,QAAiC;AAC5D,MAAI,KAAK,OAAQ,OAAM,IAAI,MAAM,uBAAuB;AACxD,QAAM,KAAK,MAAM;GAAE,SAAS;GAAO;GAAQ,GAAI,WAAW,SAAY,EAAE,GAAG,EAAE,QAAQ;GAAG,CAAC;;CAG3F,MAAM,yBAAS,IAAI,MAAM,oBAAoB,EAAQ;AACnD,MAAI,KAAK,OAAQ;AACjB,OAAK,SAAS;AACd,OAAK,MAAM,WAAW,KAAK,QAAQ,QAAQ,CAAE,SAAQ,OAAO,OAAO;AACnE,OAAK,QAAQ,OAAO;;CAGtB,AAAQ,QAAQ,OAAqB;AACnC,MAAI,KAAK,OAAQ;EACjB,IAAIC;AACJ,MAAI;AACF,cAAW,KAAK,QAAQ,KAAK,MAAM;WAC5B,OAAO;AACd,QAAK,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,kBAAkB,gBAAgB,CAAC;AACnF;;AAEF,OAAK,MAAM,WAAW,SAAU,MAAK,SAAS,QAAQ;;CAGxD,AAAQ,SAAS,OAAsB;AACrC,MAAI,CAACC,WAAS,MAAM,IAAI,MAAM,YAAY,MAAO,QAAO,KAAK,MAAM,IAAI,kBAAkB,2BAA2B,CAAC;AACrH,MAAI,YAAY,SAAS,OAAO,MAAM,WAAW,UAAU;AACzD,OAAI,QAAQ,OAAO;IACjB,MAAM,UAAU;AAChB,YAAQ,SAAS,CAAC,WAAW,KAAK,eAAe,QAAQ,QAAQ,QAAQ,OAAO,CAAC,CAAC,MAC/E,WAAW,KAAK,MAAM;KAAE,SAAS;KAAO,IAAI,QAAQ;KAAI;KAAQ,CAAC,GACjE,UAAmB,KAAK,MAAM;KAAE,SAAS;KAAO,IAAI,QAAQ;KAAI,OAAO;MAAE,MAAM;MAAQ,SAAS,iBAAiB,QAAQ,MAAM,UAAU;MAAyB;KAAE,CAAC,CACvK,CAAC,YAAY,GAAG;SAEjB,MAAK,MAAM,YAAY,KAAK,sBAAuB,UAAS,MAAwC;AAEtG;;AAEF,MAAI,QAAQ,OAAO;GACjB,MAAM,WAAW;GACjB,MAAM,UAAU,KAAK,QAAQ,IAAI,SAAS,GAAG;AAC7C,OAAI,CAAC,QAAS;AACd,OAAI,SAAS,MAAO,SAAQ,uBAAO,IAAI,MAAM,GAAG,SAAS,MAAM,KAAK,IAAI,SAAS,MAAM,UAAU,CAAC;OAC7F,SAAQ,QAAQ,SAAS,OAAO;AACrC,QAAK,QAAQ,OAAO,SAAS,GAAG;;;CAIpC,AAAQ,MAAM,SAAwC;AACpD,SAAO,IAAI,SAAe,SAAS,WAAW;AAC5C,QAAK,OAAO,MAAM,cAAc,QAAQ,GAAG,UAAyB,QAAQ,OAAO,MAAM,GAAG,SAAS,CAAC;IACtG;;;AAIN,SAASA,WAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;ACrG7E,IAAa,gBAAb,MAA2B;CACzB,QAAsB;CACtB,eAAwC,EAAE;CAC1C,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAiB,WAAW,IAAI,iBAAiB;CACjD,YAAY,AAAiBC,SAA+B;EAA/B;;CAE7B,MAAM,MAAM,QAAiD;AAC3D,iBAAe,OAAO;AACtB,OAAK,QAAQ;AACb,MAAI;GACF,MAAM,QAAQ,KAAK,QAAQ,OAAO;AAClC,QAAK,QAAQ;AAEb,GAAK,MAAM,KAAK,YAAY,GAAG;AAC/B,OAAI,CAAC,MAAM,UAAU,CAAC,MAAM,MAAO,OAAM,IAAI,MAAM,8BAA8B;GACjF,MAAM,aAAa,IAAI,kBAAkB,MAAM,QAAQ,MAAM,OAAO;IAClE,iBAAiB,KAAK,QAAQ;IAC9B,kBAAkB,QAAQ,WAAW,KAAK,OAAO,QAAQ,OAAO;IACjE,CAAC;AACF,QAAK,aAAa;AAClB,GAAK,MAAM,KAAK,WAAW,WAAW,sBAAM,IAAI,MAAM,qBAAqB,CAAC,GAAE,UAAS,WAAW,MAAM,iBAAiB,QAAQ,wBAAQ,IAAI,MAAM,mBAAmB,CAAC,CAAC,CAAC,WAAW;AAClL,QAAI,KAAK,UAAU,cAAc,KAAK,UAAU,UAAW,MAAK,QAAQ;KACxE;GACF,MAAM,SAAS,MAAM,iBAAiB,YAAY,KAAK,QAAQ,YAAY,KAAK,OAAO,OAAO,CAAC;AAC/F,OAAI,OAAO,aAAa,oBAAoB,OAAO,aAAa,qBAAqB,SAAU,OAAM,IAAI,MAAM,gDAAgD;GAC/J,MAAM,OAAO,OAAO,aAAa;AACjC,OAAI,SAAS,UAAa,SAAS,KAAM,OAAO,SAAS,YAAY,SAAS,QAAQ,CAAE,KAAiC,UAAY,OAAM,IAAI,MAAM,8CAA8C;AACnM,QAAK,eAAe,OAAO;AAC3B,SAAM,WAAW,OAAO,oCAAoC,EAAE,UAAU,KAAK,QAAQ,eAAe,CAAC;AACrG,kBAAe,KAAK,OAAO,OAAO,CAAC;AACnC,QAAK,QAAQ;AACb,UAAO;WACA,OAAO;AACd,QAAK,QAAQ;AACb,SAAM,KAAK,MAAM;AACjB,SAAM;;;CAIV,IAAI,SAAkB;AAAE,SAAO,KAAK,UAAU,WAAW,CAAC,CAAC,KAAK,YAAY;;CAC5E,WAAoB;AAAE,SAAO,KAAK;;CAClC,MAAM,IAAO,MAAqD,QAAkC;AAClG,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,WAAY,OAAM,IAAI,MAAM,uBAAuB;AAC7E,MAAI;AAAE,UAAO,MAAM,UAAU,KAAK,KAAK,WAAW,EAAE,KAAK,OAAO,OAAO,CAAC;WACjE,OAAO;AAEZ,OAAI,QAAQ,WAAW,CAAC,KAAK,WAAW,OAAQ,OAAM,KAAK,MAAM;AACjE,SAAM;;;CAIV,OAAsB;AACpB,SAAO,KAAK,aAAa,KAAK,UAAU;;CAE1C,MAAc,WAA0B;AACtC,OAAK,QAAQ;AACb,OAAK,SAAS,OAAO;EACrB,MAAM,QAAQ,KAAK,OAAO,aAAa,KAAK;EAC5C,MAAM,UAAU,YAAY,QAAQ,KAAK,QAAQ,SAAS,WAAW;AACrE,MAAI,YAAY,OACd,KAAI;AAAE,SAAM,WAAW,QAAQ,YAAY,MAAM,QAAQ;AAAE,SAAM,WAAW,OAAO,OAAO;UAAS;AAErG,cAAY,sBAAM,IAAI,MAAM,kBAAkB,CAAC;AAC/C,MAAI,OAAO;AACT,SAAM,WAAW;AACjB,OAAI,CAAC,MAAM,MAAM,YAAY,YAAY,QAAQ,KAAK,QAAQ,SAAS,cAAc,IAAK,CAAC,CAAE,OAAM,IAAI,MAAM,wEAAwE;;AAEvL,OAAK,QAAQ;;CAEf,AAAQ,OAAO,QAAmC;AAAE,SAAO,SAAS,YAAY,IAAI,CAAC,QAAQ,KAAK,SAAS,OAAO,CAAC,GAAG,KAAK,SAAS;;CACpI,AAAQ,OAAO,QAAgB,QAA0B;AACvD,MAAI,WAAW,sBAAuB,QAAO;GAAE,SAAS;GAAO,eAAe;GAAsB;AACpG,MAAI,WAAW,6BAA8B,QAAO,KAAK,QAAQ,WAAW,oBAAoB,EAAE;AAClG,MAAI,WAAW,0BAEb,SADe,QAAgE,SAAS,EAAE,EAC7E,KAAI,SAAQ;GACvB,IAAI,QAAQ,KAAK,QAAQ;AACzB,QAAK,MAAM,OAAO,KAAK,SAAS,MAAM,IAAI,IAAI,EAAE,CAC9C,SAAQ,OAAO,UAAU,YAAY,UAAU,OAAQ,MAAkC,OAAO;AAElG,UAAO,SAAS;IAChB;AAEJ,SAAO;;;;;;AC3FX,IAAa,aAAb,MAA+C;CAC7C,AAAiB,2BAAW,IAAI,KAAgB;CAChD,AAAiB,2BAAW,IAAI,KAAyB;CACzD,AAAiB,yBAAS,IAAI,KAA4B;CAC1D,AAAQ,YAAY;CACpB,YAAY,AAAiBC,SAA4B;EAA5B;;CAE7B,MAAM,YAAY,UAAkB,WAAmB,QAAkC;AACvF,iBAAe,OAAO;AACtB,MAAI,KAAK,UAAW,OAAM,IAAI,MAAM,2BAA2B;EAC/D,MAAM,MAAM,MAAM,UAAU,UAAU;EACtC,MAAM,WAAW,KAAK,SAAS,IAAI,IAAI;AACvC,MAAI,UAAU,UAAU,CAAE,QAAO;EACjC,MAAM,UAAU,KAAK,SAAS,IAAI,IAAI;AACtC,MAAI,QAAS,QAAO,UAAU,SAAS,OAAO;EAC9C,MAAM,WAAW,KAAK,OAAO,KAAK,UAAU,WAAW,UAAU,OAAO;AACxE,OAAK,SAAS,IAAI,KAAK,SAAS;AAChC,MAAI;AAAE,UAAO,MAAM;YACX;AAAE,OAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAU,MAAK,SAAS,OAAO,IAAI;;;CAG9E,IAAO,UAAkB,WAAmB,MAAkC,QAAkC;AAC9G,SAAO,KAAK,UAAU,MAAM,UAAU,UAAU,EAAE,YAAY,KAAK,MAAM,KAAK,YAAY,UAAU,WAAW,OAAO,CAAC,EAAE,OAAO;;CAGlI,aAAgB,UAAkB,WAAmB,MAAkC,QAAsB,UAAgD;AAG3J,SAAO,KAAK,UAAU,MAAM,UAAU,UAAU,EAAE,YAAY;GAC5D,MAAM,WAAW,KAAK,SAAS,IAAI,MAAM,UAAU,UAAU,CAAC;AAE9D,OAAI,UAAU,UAAU,IAAI,YAAY,CAAC,SAAS,SAAS,CAAE,OAAM,KAAK,MAAM,UAAU,UAAU;AAClG,QAAK,IAAI,UAAU,IAAK,WAAW;IACjC,MAAM,UAAU,MAAM,KAAK,YAAY,UAAU,WAAW,OAAO;AACnE,QAAI;AAAE,YAAO,MAAM,KAAK,QAAQ;aACzB,OAAO;AACZ,oBAAe,OAAO;AACtB,SAAI,UAAU,KAAK,QAAQ,UAAU,CAAE,OAAM;AAC7C,SAAI,KAAK,SAAS,IAAI,MAAM,UAAU,UAAU,CAAC,KAAK,QAAS,OAAM,KAAK,MAAM,UAAU,UAAU;;;KAGvG,OAAO;;CAGZ,MAAM,MAAM,UAAkB,WAAkC;EAC9D,MAAM,MAAM,MAAM,UAAU,UAAU;EACtC,MAAM,UAAU,KAAK,SAAS,IAAI,IAAI;AACtC,OAAK,SAAS,OAAO,IAAI;AACzB,MAAI,QAAS,OAAM,QAAQ,MAAM;;CAGnC,MAAM,aAA4B;AAChC,OAAK,YAAY;EACjB,MAAM,UAAU,MAAM,QAAQ,WAAW,CAAC,GAAG,KAAK,SAAS,QAAQ,CAAC,CAAC,KAAI,YAAW,QAAQ,MAAM,CAAC,CAAC;AACpG,OAAK,SAAS,OAAO;AACrB,QAAM,QAAQ,IAAI,CAAC,GAAG,KAAK,SAAS,QAAQ,CAAC,CAAC,KAAI,aAAY,SAAS,MAAK,YAAW,QAAQ,MAAM,QAAQ,GAAG,CAAC,CAAC;AAClH,OAAK,SAAS,OAAO;EACrB,MAAM,WAAW,QAAQ,QAAQ,WAA4C,OAAO,WAAW,WAAW;AAC1G,MAAI,SAAS,OAAQ,OAAM,IAAI,eAAe,SAAS,KAAI,WAAU,OAAO,OAAO,EAAE,iCAAiC;;CAGxH,IAAI,OAAe;AAAE,SAAO,KAAK,SAAS;;CAE1C,MAAc,UAAa,KAAa,MAAwB,QAAkC;EAChG,MAAM,WAAW,KAAK,OAAO,IAAI,IAAI,IAAI,QAAQ,SAAS;EAC1D,IAAIC;EACJ,MAAM,UAAU,IAAI,SAAc,YAAW;AAAE,aAAU;IAAU;AACnE,OAAK,OAAO,IAAI,KAAK,QAAQ;AAC7B,MAAI;AACF,SAAM,UAAU,UAAU,OAAO;AACjC,kBAAe,OAAO;AACtB,UAAO,MAAM,MAAM;YACX;AAER,GAAK,SAAS,KAAK,SAAS,QAAQ;AACpC,GAAK,QAAQ,WAAW;AAAE,QAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAS,MAAK,OAAO,OAAO,IAAI;KAAG;;;CAI9F,MAAc,OAAO,KAAa,UAAkB,WAAmB,UAAc,QAAkC;AACrH,MAAI,UAAU;AAAE,QAAK,SAAS,OAAO,IAAI;AAAE,SAAM,SAAS,MAAM;;AAChE,iBAAe,OAAO;EACtB,MAAM,UAAU,MAAM,KAAK,QAAQ,UAAU,WAAW,OAAO;AAC/D,MAAI;AAAE,SAAM,QAAQ,MAAM,OAAO;WAAU,OAAO;AAAE,SAAM,QAAQ,MAAM;AAAE,SAAM;;AAChF,MAAI,KAAK,WAAW;AAAE,SAAM,QAAQ,MAAM;AAAE,SAAM,IAAI,MAAM,2BAA2B;;AACvF,OAAK,SAAS,IAAI,KAAK,QAAQ;AAC/B,SAAO;;;AAIX,SAAgB,MAAM,UAAkB,WAA2B;AAAE,QAAO,GAAG,SAAS,QAAQ;;;;;AClGhG,SAAgB,kBAAkB,cAAuC,WAAuC;AAC9G,KAAI,cAAc,iBAAkB,QAAO,aAAa,uBAAuB,QAAQ,WAAW,aAAa,mBAAmB;AAClI,KAAI,cAAc,iBAAkB,QAAO,aAAa,uBAAuB,QAAQ,WAAW,aAAa,mBAAmB;AAClI,KAAI,cAAc,qBAAsB,QAAO,aAAa,2BAA2B,QAAQ,WAAW,aAAa,uBAAuB;AAC9I,QAAO,aAAa,kBAAkB,QAAQ,WAAW,aAAa,cAAc;;AAGtF,SAAS,WAAW,OAAyB;AAC3C,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU;;;;;ACHlE,SAAgB,eAAe,OAAoD;AACjF,KAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,SAAS;CACf,MAAM,WAAW,kBAAkB,OAAO,SAAS;AACnD,KAAI,aAAa,OAAW,QAAO;AACnC,QAAO;EAAE;EAAU,GAAIC,UAAQ,OAAO,MAAM,GAAG,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;EAAG;;AAGhF,SAAS,kBAAkB,OAAoC;AAC7D,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI,MAAM,QAAQ,MAAM,EAAE;EACxB,MAAM,QAAQ,MAAM,KAAK,SAAS,OAAO,SAAS,WAAW,OAAOC,WAAS,KAAK,IAAI,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,OAAU;AAC9I,SAAO,MAAM,OAAO,SAAyB,SAAS,OAAU,GAAG,MAAM,KAAK,KAAK,GAAG;;AAExF,KAAIA,WAAS,MAAM,IAAI,OAAO,MAAM,UAAU,SAAU,QAAO,MAAM;;AAIvE,SAASD,UAAQ,OAAmC;AAClD,QAAOC,WAAS,MAAM,IAAIC,aAAW,MAAM,MAAM,IAAIA,aAAW,MAAM,IAAI;;AAG5E,SAASA,aAAW,OAAyB;AAC3C,QAAOD,WAAS,MAAM,IAAI,OAAO,UAAU,MAAM,KAAK,IAAI,OAAO,UAAU,MAAM,UAAU,IAAI,MAAM,QAAQ,KAAK,MAAM,aAAa;;AAGvI,SAASA,WAAS,OAA8C;AAC9D,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;AC5B7E,SAAgB,kBAAkB,OAAgD;AAChF,KAAIE,WAAS,MAAM,IAAI,OAAO,MAAM,cAAc,YAAYC,UAAQ,MAAM,qBAAqB,CAAE,QAAO;EAAE,KAAK,MAAM;EAAW,OAAO,MAAM;EAAsB;AACrK,KAAI,CAACD,WAAS,MAAM,IAAI,OAAO,MAAM,QAAQ,YAAY,CAACC,UAAQ,MAAM,MAAM,CAAE,QAAO;AACvF,QAAO;EAAE,KAAK,MAAM;EAAK,OAAO,MAAM;EAAO;;AAG/C,SAAgB,mBAAmB,OAAsC;AAEvE,SADe,MAAM,QAAQ,MAAM,GAAG,QAAQ,UAAU,QAAQ,UAAU,SAAY,EAAE,GAAG,CAAC,MAAM,EACpF,IAAI,kBAAkB,CAAC,QAAQ,aAA6C,aAAa,OAAU;;AAGnH,SAASA,UAAQ,OAAmC;AAClD,QAAOD,WAAS,MAAM,IAAIE,aAAW,MAAM,MAAM,IAAIA,aAAW,MAAM,IAAI;;AAG5E,SAASA,aAAW,OAAsC;AACxD,QAAOF,WAAS,MAAM,IAAI,OAAO,UAAU,MAAM,KAAK,IAAI,OAAO,UAAU,MAAM,UAAU,IAAI,MAAM,QAAQ,KAAK,MAAM,aAAa;;AAGvI,SAASA,WAAS,OAA8C;AAC9D,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;ACzB7E,SAAgB,oBAAoB,OAAgB,QAAgB,aAAuD;AACzH,KAAI,CAACG,WAAS,MAAM,IAAI,CAAC,QAAQ,MAAM,MAAM,IAAI,OAAO,MAAM,YAAY,SAAU,QAAO;CAC3F,MAAM,MAAM,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM;CACxD,MAAM,WAAW,OAAO,MAAM,aAAa,YAAY,MAAM,YAAY,KAAK,MAAM,YAAY,IAAI,MAAM,WAA4B;CACtI,MAAM,OAAO,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC7F,QAAO;EAAE;EAAQ;EAAK,OAAO,MAAM;EAAO,SAAS,MAAM;EAAS,GAAI,aAAa,SAAY,EAAE,GAAG,EAAE,UAAU;EAAG,GAAI,SAAS,SAAY,EAAE,GAAG,EAAE,MAAM;EAAG,GAAI,OAAO,MAAM,WAAW,WAAW,EAAE,QAAQ,MAAM,QAAQ,GAAG,EAAE;EAAG;;AAGrO,SAAgB,qBAAqB,OAAgB,QAAgB,aAA6C;AAEhH,SADe,MAAM,QAAQ,MAAM,GAAG,QAAQ,EAAE,EAClC,KAAK,SAAS,oBAAoB,MAAM,QAAQ,YAAY,CAAC,CAAC,QAAQ,SAAuC,SAAS,OAAU;;AAGhJ,SAAS,QAAQ,OAAmC;AAClD,QAAOA,WAAS,MAAM,IAAI,WAAW,MAAM,MAAM,IAAI,WAAW,MAAM,IAAI;;AAG5E,SAAS,WAAW,OAAyB;AAC3C,QAAOA,WAAS,MAAM,IAAI,OAAO,UAAU,MAAM,KAAK,IAAI,OAAO,UAAU,MAAM,UAAU,IAAI,MAAM,QAAQ,KAAK,MAAM,aAAa;;AAGvI,SAASA,WAAS,OAA8C;AAC9D,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;ACtB7E,SAAgB,wBAAwB,OAAgB,QAAsD;AAC5G,KAAI,CAAC,SAAS,MAAM,IAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,WAAW,EAAG,QAAO;AAC5F,QAAO;EACL;EACA,OAAO,MAAM;EACb,GAAI,OAAO,MAAM,SAAS,WAAW,EAAE,MAAM,MAAM,MAAM,GAAG,EAAE;EAC9D,GAAI,OAAO,MAAM,WAAW,WAAW,EAAE,QAAQ,MAAM,QAAQ,GAAG,EAAE;EACpE,GAAI,OAAO,MAAM,kBAAkB,WAAW,EAAE,eAAe,MAAM,eAAe,GAAG,EAAE;EACzF,GAAI,OAAO,MAAM,aAAa,WAAW,EAAE,UAAU,MAAM,UAAU,GAAG,EAAE;EAC1E,GAAI,OAAO,MAAM,eAAe,WAAW,EAAE,YAAY,MAAM,YAAY,GAAG,EAAE;EAChF,GAAI,OAAO,MAAM,eAAe,WAAW,EAAE,YAAY,MAAM,YAAY,GAAG,EAAE;EAChF,GAAI,OAAO,MAAM,qBAAqB,WAAW,EAAE,kBAAkB,MAAM,kBAAkB,GAAG,EAAE;EAClG,GAAI,OAAO,MAAM,eAAe,YAAY,EAAE,YAAY,MAAM,YAAY,GAAG,EAAE;EAClF;;AAGH,SAAgB,oBAAoB,OAAgB,QAA4C;AAE9F,SADc,SAAS,MAAM,IAAI,MAAM,QAAQ,MAAM,MAAM,GAAG,MAAM,QAAQ,MAAM,QAAQ,MAAM,GAAG,QAAQ,EAAE,EAChG,KAAK,SAAS,wBAAwB,MAAM,OAAO,CAAC,CAAC,QAAQ,SAA2C,SAAS,OAAU;;AAG1I,SAAS,SAAS,OAA8C;AAC9D,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;ACjB7E,SAAgB,WAAW,SAAyC,WAA+D;AACjI,KAAI,CAAC,WAAW,CAAC,UAAW,QAAO;AACnC,KAAI,CAAC,QAAS,QAAO,YAAY,EAAE,GAAG,WAAW,GAAG;AACpD,KAAI,CAAC,UAAW,QAAO,EAAE,GAAG,SAAS;CACrC,MAAM,WAAW,CAAC,QAAQ,UAAU,UAAU,SAAS,CAAC,QAAQ,OAAO,OAAO,WAAW,OAAO,QAAQ,MAAM,KAAK,MAAM;CACzH,MAAM,QAAQ,UAAU,QAAQ,OAAO,UAAU,MAAM,GAAG,QAAQ,QAAQ;AAC1E,QAAO;EAAE,QAAQ,QAAQ;EAAQ,UAAU,SAAS,KAAK,OAAO;EAAE,GAAI,QAAQ,EAAE,OAAO,GAAG,EAAE;EAAG;;AAGjG,SAAS,UAAU,MAA4B,OAAsC;AACnF,QAAO,KAAK,UAAU,KAAK,KAAK,KAAK,UAAU,MAAM;;;;;ACQvD,MAAM,UAAU;CAAE,OAAO;CAAsB,gBAAgB;CAA2B,gBAAgB;CAA2B,oBAAoB;CAA+B;AACxL,MAAM,qBAAqB;CACzB,SAAS,EAAE,mBAAmB,CAAC,SAAS,EAAE;CAC1C,WAAW;EAAE,eAAe;EAAM,kBAAkB;EAAM,WAAW;EAAO;CAC5E,cAAc;EACZ,iBAAiB;GAAE,qBAAqB;GAAO,SAAS;GAAO;EAC/D,OAAO,EAAE,eAAe,CAAC,YAAY,YAAY,EAAE;EACnD,YAAY,EAAE,gBAAgB;GAAE,gBAAgB;GAAM,qBAAqB,CAAC,YAAY,YAAY;GAAE,EAAE;EACxG,oBAAoB,EAAE,gBAAgB,MAAM;EAAE,YAAY,EAAE;EAC7D;CACF;AAED,IAAa,qBAAb,MAAgC;CAC9B,AAAiB;CACjB,AAAiB,6BAAa,IAAI,KAAyB;CAC3D,AAAiB,WAAW,IAAI,iBAAiB;CACjD,AAAiB,uBAAO,IAAI,KAA8B;CAC1D,AAAiB,yBAAS,IAAI,KAAqB;CACnD,AAAiB,2BAAW,IAAI,KAAuB;CACvD,YAAY,AAAiBC,QAAwB,AAAiBC,IAAoB,AAAiBC,YAA4B;EAA1G;EAAyC;EAAqC;AACzG,OAAK,OAAO,IAAI,WAAW,OAAO,OAAO,KAAK,WAAW;GACvD,MAAM,KAAK,OAAmB,SAAS,KAAK,WAAW,IAAI,IAAI;GAC/D,MAAM,OAAO,MAAM,cAAc,IAAI,QAAQ,OAAO,UAAU;GAC9D,IAAIC;AACJ,OAAI;AAAE,iBAAa,MAAM,WAAW,kBAAkB,KAAK,SAAS,KAAK,KAAK,OAAO;WAC/E;AAAE,mBAAe,OAAO;AAAE,UAAM,IAAI,iBAAiB,mBAAmB,GAAG,GAAG,yDAAyD;;GAC7I,MAAM,UAAU,IAAI,cAAc;IAChC,aAAa,WAAW,MAAM;KAAE,MAAM,CAAC,YAAY,GAAG,KAAK,KAAK;KAAE,KAAK,OAAO;KAAW,KAAK,KAAK;KAAK,OAAO;MAAE,OAAO;MAAQ,QAAQ;MAAQ,QAAQ,EAAE,UAAU,OAAO,OAAO,gBAAgB;MAAE;KAAE,SAAS,OAAO,SAAS;KAAa,CAAC;IAC7O,YAAY;KAAE,WAAW;KAAM,SAAS,OAAO;KAAc,kBAAkB,CAAC;MAAE,KAAK,OAAO;MAAc,MAAM;MAAa,CAAC;KAAE,cAAc;KAAoB,uBAAuB,sBAAsB,IAAI,OAAO;KAAE;IAC9N,eAAe,oBAAoB,IAAI,OAAO;IAAE,iBAAiB,OAAO,OAAO;IAC/E,UAAU;KAAE,YAAY,OAAO,SAAS;KAAY,aAAa,OAAO,SAAS;KAAa;IAC/F,CAAC;GACF,MAAM,OAAO,GAAG,GAAG,QAAQ;AAC3B,OAAI,KAAK,OAAO,IAAI,KAAK,CAAE,MAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,IAAI,KAAK,EAAE;AAClF,QAAK,OAAO,IAAI,OAAO,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK,EAAE;AACvD,QAAK,MAAM,CAAC,QAAQ,KAAK,KAAM,KAAI,IAAI,UAAU,aAAa,IAAI,UAAU,SAAU,MAAK,KAAK,OAAO,IAAI;AAC3G,QAAK,KAAK,IAAI,SAAS,GAAG;AAC1B,UAAO;IACP;;CAGJ,MAAM,WAAW,SAA2B,QAA+C;EACzF,MAAM,WAAW,KAAK,OAAO,QAAQ,cAAc,UAAU,KAAK,OAAO,SAAS,iBAAiB,KAAK,OAAO,SAAS,cAAc,OAAO;EAC7I,MAAM,CAAC,QAAQ,SAAS,MAAM,KAAK,QAAQ,SAAS,SAAS;AAC7D,OAAK,iBAAiB,OAAO,MAAM,QAAQ,SAAS;EACpD,MAAM,SAAS,MAAM,KAAK,SAAS,MAAM,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,YAAY,UAAU,OAAO,SAAS,eAAe;AAClI,OAAI,CAAC,kBAAkB,QAAQ,cAAc,QAAQ,UAAU,CAAE,OAAM,IAAI,iBAAiB,6BAA6B,GAAG,MAAM,QAAQ,OAAO,oBAAoB,QAAQ,YAAY;AACzL,UAAO,WAAW,QAAQ,QAAQ,QAAQ,YAAY;IAAE,cAAc,EAAE,KAAK,OAAO,KAAK;IAAE,UAAU,QAAQ;IAAU,GAAI,QAAQ,cAAc,mBAAmB,EAAE,SAAS,EAAE,oBAAoB,MAAM,EAAE,GAAG,EAAE;IAAG,EAAE,SAAS;IAChO;AACF,MAAI,QAAQ,cAAc,QAAS,QAAO;GAAE,MAAM;GAAa,WAAW,mBAAmB,OAAO;GAAE,sBAAsB,OAAO;GAAc;EACjJ,MAAM,UAAU,eAAe,OAAO;AACtC,MAAI,YAAY,OAAW,OAAM,IAAI,iBAAiB,0BAA0B,uBAAuB;EACvG,IAAI,YAAY;AAChB,MAAI,KAAK,YAAY,OAAO,QAAQ,QAAQ,SAAS,EAAE;GACrD,MAAM,YAAY,KAAK,OAAO,KAAK,OAAO,SAAS,kBAAkB,OAAO;AAC5E,OAAI;IACF,MAAM,QAAQ,MAAM,KAAK,SAAS,YAAY,QAAQ,MAAM,UAAW,YAAY,YAAY,UAAU,eAAe,WAAW,QAAQ,sBAAsB;KAAE,cAAc,EAAE,KAAK,OAAO,KAAK;KAAE,UAAU,QAAQ;KAAU,EAAE,UAAU,CAAC;AAC/O,gBAAY,eAAe,MAAM,IAAI;WAC/B;AAAE,mBAAe,OAAO;AAAE,mBAAe,KAAK,SAAS,OAAO;;;EAExE,MAAM,QAAQ,WAAW,WAAW;GAAE,GAAG;GAAS,QAAQ,MAAM,QAAQ;GAAQ,EAAE,aAAa;GAAE,GAAG;GAAW,QAAQ;GAAY,CAAC;AACpI,SAAO;GAAE,MAAM;GAAS,OAAO,QAAQ;IAAE,UAAU,MAAM;IAAU,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,OAAO,GAAG,EAAE;IAAG,GAAG;GAAM;;CAG9H,MAAM,WAAW,SAA4B,QAAiD;EAC5F,MAAM,WAAW,KAAK,OAAO,KAAK,OAAO,SAAS,cAAc,OAAO;EACvE,MAAM,CAAC,QAAQ,SAAS,MAAM,KAAK,QAAQ,SAAS,SAAS;AAC7D,OAAK,iBAAiB,OAAO,MAAM,QAAQ,SAAS;EACpD,MAAM,SAAS,IAAc,aAAqB,KAAK,SAAS,IAAI,QAAQ,UAAU,WAAW,SAAS,eAAe;AACvH,OAAI,CAAC,QAAQ,aAAa,mBAAoB,OAAM,IAAI,iBAAiB,6BAA6B,GAAG,GAAG,8BAA8B;AAC1I,UAAO,WAAW,QAAQ,2BAA2B;IAAE,cAAc,EAAE,KAAK,OAAO,KAAK;IAAE,UAAU,QAAQ;IAAU,SAAS;KAAE,aAAa,QAAQ,eAAe;KAAG,GAAI,QAAQ,mBAAmB,EAAE,kBAAkB,QAAQ,kBAAkB,GAAG,EAAE;KAAG;IAAE,EAAE,SAAS;IAC1Q,CAAC,MAAK,UAAS;GACf,MAAM,SAAS,OAAO,KAAK,MAAM,QAAQ,CAAC,QAAQ,SAAS,MAAO,MAAM,GAAG,QAAQ,SAAS,UAAU,CAAC,MAAM,mBAAmB,GAAG,IAAI,aAAa,IAAI;AAExJ,UAAO,oBAAoB,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM,QAAQ,EAAE,cAAc,EAAE,OAAO,aAAa,CAAC,WAAW,OAAO,CAAC,GAAG,QAAQ,EAAE,cAAc,EAAE,OAAO,aAAa,CAAC,WAAW,OAAO,CAAC,CAAC;IAC7L;EACF,MAAM,UAAU,MAAM,MAAM,MAAM,QAAQ,QAAQ,MAAM,QAAQ,WAAW;EAC3E,IAAIC,YAA4B,EAAE;AAClC,MAAI,KAAK,YAAY,OAAO,QAAQ,QAAQ,SAAS,CACnD,KAAI;AAAE,eAAY,MAAM,MAAM,YAAY,MAAM,UAAW,WAAW;UAAS;AAAE,kBAAe,OAAO;AAAE,kBAAe,KAAK,SAAS,OAAO;;AAE/I,SAAO,iBAAiB,CAAC,SAAS,UAAU,EAAE;GAAE,gBAAgB,OAAO;GAAkB,gBAAgB,OAAO;GAAkB,CAAC;;CAGrI,MAAM,YAAY,SAA6B,QAAkD;EAC/F,MAAM,WAAW,KAAK,OAAO,KAAK,OAAO,SAAS,eAAe,OAAO;EACxE,MAAM,CAAC,QAAQ,SAAS,MAAM,KAAK,QAAQ,SAAS,SAAS;EAC7D,MAAM,WAAW,CAAC,MAAM,SAAS,GAAI,MAAM,aAAa,KAAK,OAAO,SAAS,UAAU,CAAC,MAAM,UAAU,GAAG,EAAE,CAAE,CAAC,QAAO,SAAQ,KAAK,OAAO,QAAQ,KAAK,QAAQ,YAAY,CAAC,QAAQ,WAAW,QAAQ,QAAQ,SAAS,KAAK,OAAO,EAAE;AACvO,MAAI,CAAC,SAAS,OAAQ,OAAM,IAAI,iBAAiB,mBAAmB,mDAAmD;EACvH,MAAMC,iBAA2B,EAAE;EACnC,MAAM,SAAS,MAAM,QAAQ,IAAI,SAAS,IAAI,OAAM,SAAQ;AAC1D,OAAI;IACF,MAAM,QAAQ,MAAM,KAAK,SAAS,KAAK,QAAQ,QAAQ,KAAK,YAAY,UAAU,OAAO,SAAS,YAAY,WAAW;AACvH,SAAI,QAAQ,aAAa,oBAAoB;AAC3C,YAAM,QAAQ;AAEd,cADe,MAAM,WAAW,QAAQ,2BAA2B,EAAE,cAAc,EAAE,KAAK,OAAO,KAAK,EAAE,EAAE,SAAS,GACpG,SAAS,EAAE;;KAG5B,IAAI,eAAe;KACnB,MAAM,YAAY,IAAI,SAAiB,YAAW;AAChD,eAAS,WAAW,gBAAe,YAAW;OAC5C,MAAM,IAAI,QAAQ;AAClB,WAAI,QAAQ,WAAW,qCAAqC,GAAG,QAAQ,OAAO,QAAQ,EAAE,YAAY,UAAa,EAAE,YAAY,GAAI,SAAQ,EAAE,YAAY;QACzJ;OACF;AACF,SAAI;AAAE,YAAM,QAAQ;AAAE,aAAO,MAAM,UAAU,WAAW,SAAS;eAAW;AAAE,cAAQ;;OACrF,KAAK;AACR,WAAO,qBAAqB,OAAO,KAAK,QAAQ,OAAO,IAAI,CAAC,QAAO,MAAK,CAAC,QAAQ,YAAY,QAAQ,aAAa,SAAS,EAAE,cAAc,QAAQ,aAAa,UAAU,IAAI,GAAG;YAC1K,OAAO;AACd,mBAAe,OAAO;AAAE,mBAAe,KAAK,SAAS,OAAO;AAC5D,QAAI,KAAK,WAAW,MAAM,QAAQ,UAAU,KAAK,OAAO,wBAAwB,QAAS,OAAM;AAC/F,mBAAe,KAAK,KAAK,OAAO;AAChC,WAAO,EAAE;;IAEX,CAAC;AACH,SAAO;GAAE,GAAG,iBAAiB,QAAQ;IAAE,gBAAgB,OAAO;IAAkB,gBAAgB,OAAO;IAAkB,CAAC;GAAE,GAAI,eAAe,SAAS,EAAE,gBAAgB,eAAe,MAAM,EAAE,GAAG,EAAE;GAAG;;CAG3M,MAAM,SAAqC;AACzC,SAAO;GAAE,YAAY,KAAK,OAAO;GAAY,SAAS,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAM,OAAM;IACjG,MAAM,SAAS,KAAK,OAAO,QAAQ;IACnC,IAAI,YAAY;AAChB,QAAI;KACF,MAAM,SAAS,MAAM,cAAc,IAAI,KAAK,QAAQ,IAAI;AACxD,WAAM,KAAK,WAAW,kBAAkB,OAAO,SAAS,OAAO,KAAK,KAAK,OAAO,IAAK,CAAC;AACtF,iBAAY;YACN;AACR,WAAO;KAAE;KAAI,SAAS,OAAO,YAAY,OAAO,cAAc,KAAK,OAAO,SAAS;KAAU;KAAW,QAAQ,OAAO;KAAM,gBAAgB,CAAC,GAAG,KAAK,KAAK,CAAC,QAAQ,CAAC,GAAG,YAAY,WAAW,MAAM,EAAE,UAAU,CAAC,CAAC;KAAQ,UAAU,KAAK,SAAS,IAAI,GAAG,IAAI;KAAG;KACjQ,CAAC;GAAE;;CAGP,MAAM,UAAyB;AAAE,OAAK,SAAS,OAAO;AAAE,QAAM,KAAK,KAAK,YAAY;AAAE,OAAK,WAAW,OAAO;AAAE,OAAK,KAAK,OAAO;;CAEhI,AAAQ,OAAO,IAAY,QAAmC;AAAE,SAAO,YAAY,IAAI;GAAC,KAAK,SAAS;GAAQ,YAAY,QAAQ,GAAG;GAAE,GAAI,SAAS,CAAC,OAAO,GAAG,EAAE;GAAE,CAAC;;CACpK,MAAc,QAAQ,SAAsD,QAAmD;AAC7H,iBAAe,OAAO;EACtB,MAAM,OAAO,aAAa,QAAQ,UAAU,KAAK,OAAO,QAAQ,cAAc;AAC9E,MAAI,CAAC,KAAM,OAAM,IAAI,iBAAiB,mBAAmB,6BAA6B;EACtF,MAAM,SAAS,MAAM,WAAW,KAAK,IAAI,QAAQ,eAAe,QAAQ,UAAU,KAAK,OAAO,OAAO,kBAAkB,OAAO,CAAC,OAAM,UAAS;AAAE,kBAAe,OAAO;AAAE,SAAM;IAAQ;AACtL,OAAK,WAAW,IAAI,OAAO,KAAK;GAAE,GAAG;GAAQ,MAAM;GAAI,CAAC;AACxD,SAAO,CAAC,QAAQ,SAAS,KAAK,CAAC;;CAEjC,AAAQ,iBAAiB,MAAc,UAA6B;EAClE,MAAM,OAAO,KAAK,MAAM,QAAQ,CAAC,SAAS;AAC1C,MAAI,CAAC,OAAO,cAAc,SAAS,KAAK,IAAI,CAAC,OAAO,cAAc,SAAS,UAAU,IAAI,SAAS,OAAO,KAAK,SAAS,YAAY,KAAK,SAAS,UAAa,SAAS,YAAY,KAAK,OAAQ,OAAM,IAAI,WAAW,4DAA4D;;CAEnR,AAAQ,YAAY,OAAc,QAAoB,UAAgC;AACpF,SAAO,CAAC,CAAC,MAAM,aAAa,KAAK,OAAO,SAAS,WAAW,KAAK,OAAO,QAAQ,SAAS,YAAY,MAAM,QAAQ,eAAe,WAAW,KAAK,OAAO,QAAQ,kBAAkB,SAAS,MAAM,QAAQ,WAAW,IAAI,MAAM,QAAQ,eAAe,WAAW,KAAK,OAAO,SAAS,kBAAkB,YAAY,qBAAqB,OAAO,MAAM,SAAS,MAAM,KAAK,OAAO,SAAS,YAAY,SAAS,WAAW,KAAK,OAAO,SAAS,gBAAgB;;CAEjc,MAAc,SAAY,IAAc,QAAoB,UAAkB,QAAqB,MAAwG,aAAa,OAAmB;AACzO,MAAI,CAAC,KAAK,OAAO,QAAQ,IAAI,QAAS,OAAM,IAAI,iBAAiB,mBAAmB,GAAG,GAAG,cAAc;AACxG,SAAO,KAAK,KAAK,aAAa,IAAI,OAAO,MAAK,YAAW,QAAQ,IAAI,OAAM,eAAc;GACvF,IAAI,SAAS;GACb,MAAM,OAAO,YAAY;AAAE,aAAS;AAAM,UAAM,WAAW,OAAO,wBAAwB,EAAE,cAAc;KAAE,KAAK,OAAO;KAAK,YAAY;KAAU,SAAS;KAAG,MAAM,OAAO;KAAM,EAAE,CAAC;;AACrL,OAAI;AAAE,QAAI,CAAC,WAAY,OAAM,MAAM;AAAE,WAAO,MAAM,KAAK,SAAS,YAAY,KAAK;aACzE;AAAE,QAAI,UAAU,WAAW,OAAQ,OAAM,WAAW,OAAO,yBAAyB,EAAE,cAAc,EAAE,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC,YAAY,GAAG;;KACjJ,OAAO,EAAE,QAAQ,cAAa,YAAW;AAI1C,UAAO,CAAC,CAAC,QAAQ,aAAa;MAC5B,OAAU;;;;;;AC9KlB,MAAa,OAAO;AACpB,MAAa,SAAS;CAAC;CAAM;CAAO;CAAa;AAMjD,MAAa,sBAAsB;CACjC,QAAQ;CAAO,OAAO;CAAc,QAAQ;CAAmB,QAAQ;CAAc,QAAQ;CAC7F,OAAO;CAAc,QAAQ;CAAmB,QAAQ;CAAc,QAAQ;CAC9E,WAAW;CAAU,SAAS;CAAQ,QAAQ;CAAQ,QAAQ;CAAO,SAAS;CAC/E;AAOD,SAAgB,wBAAwB,SAA2B,SAA6C,EAAE,YAAY,YAAY,EAAe;AACvJ,QAAO;EAAE,IAAI,cAAc,OAAO,WAAW;EAAE,qBAAqB,EAAE,GAAG,qBAAqB;EAAE,QAAQ,SAAS,WAAW,QAAQ,WAAW,SAAS,OAAO;EAAE;;AAGnK,eAAsB,MAAM,KAAc,SAAkB,EAAE,EAAiB;CAC7E,MAAM,WAAW,cAAc,OAAO;CACtC,MAAM,UAAU,IAAI,mBAAmB,UAAU,IAAI,IAAI,IAAI,WAAW;AACxE,OAAM,IAAI,OAAO,mBAAmB;AAClC,cAAY,QAAQ,SAAS;AAC7B,MAAI,SAAS,wBAAwB,SAAS;GAC5C,MAAM,WAAW,MAAM,QAAQ,QAAQ,EAAE,QAAQ,QAAO,WAAU,OAAO,WAAW,CAAC,OAAO,UAAU;AACtG,OAAI,QAAQ,OAAQ,OAAM,IAAI,MAAM,iCAAiC,QAAQ,KAAI,WAAU,OAAO,GAAG,CAAC,KAAK,KAAK,GAAG;;AAErH,QAAM,IAAI,IAAI,iBAAiB,wBAAwB,SAAS,SAAS,CAAC;AAC1E,QAAM,IAAI,QAAQ,eAAe,yBAAyB,QAAQ,CAAC;IAClE,wBAAwB"}
1
+ {"version":3,"file":"provider.js","names":["CLASSIFIERS: ReadonlyArray<{ suffix: string; kind: FileKind }>","ROUTES: Record<ClassifiedFile['kind'], Route>","maxMessageBytes: number","messages: unknown[]","text: string","length: number | undefined","input: Readable","output: Writable","messages: unknown[]","isRecord","options: ServerSessionOptions","factory: SessionFactory<S>","release!: () => void","isRange","isRecord","isPosition","isRecord","isRange","isPosition","isRecord","config: ResolvedConfig","fs: HostFileSystem","subprocess: HostSubprocess","executable: string","auxiliary: typeof primary","omittedServers: string[]"],"sources":["../src/runtime/cancellation.ts","../src/host/dsh.ts","../src/routing/classifier.ts","../src/routing/route-table.ts","../src/routing/tailwind-candidate.ts","../src/protocol/initialize.ts","../src/runtime/framing.ts","../src/runtime/connection.ts","../src/runtime/server-session.ts","../src/runtime/server-pool.ts","../src/protocol/capabilities.ts","../src/protocol/normalize-hover.ts","../src/protocol/normalize-location.ts","../src/protocol/normalize-diagnostic.ts","../src/protocol/normalize-completion.ts","../src/merge/hover.ts","../src/runtime/webstack-runtime.ts","../src/provider.ts"],"sourcesContent":["export function abortError(): Error {\n const error = new Error('The operation was aborted')\n error.name = 'AbortError'\n return error\n}\n\nexport function throwIfAborted(signal?: AbortSignal): void {\n if (signal?.aborted) throw abortError()\n}\n\nexport function onAbort(signal: AbortSignal | undefined, callback: () => void): () => void {\n if (!signal) return () => {}\n if (signal.aborted) {\n callback()\n return () => {}\n }\n signal.addEventListener('abort', callback, { once: true })\n return () => signal.removeEventListener('abort', callback)\n}\n\nexport async function withAbort<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n throwIfAborted(signal)\n if (!signal) return promise\n return new Promise<T>((resolve, reject) => {\n const remove = onAbort(signal, () => reject(abortError()))\n promise.then((value) => { remove(); resolve(value) }, (error: unknown) => { remove(); reject(error) })\n })\n}\n","import type { FileSystem } from '@deepseek-ai/dsh-fs'\nimport { WebstackLspError } from '../errors.js'\nimport { throwIfAborted } from '../runtime/cancellation.js'\n\nexport type HostFileSystem = Pick<FileSystem, 'resolve' | 'stat' | 'processPath' | 'fileUrl' | 'contains' | 'streamText'>\nexport interface HostSource { workspace: string; workspaceUri: string; key: string; uri: string; text: string }\n\nexport async function readSource(fs: HostFileSystem, workspaceRoot: string, filePath: string, maxBytes: number, signal?: AbortSignal): Promise<HostSource> {\n if (!workspaceRoot?.trim() || !filePath?.trim()) throw new WebstackLspError('LSP_WORKSPACE_REQUIRED', 'workspaceRoot and filePath are required')\n throwIfAborted(signal)\n const options = signal ? { signal } : {}\n const root = await fs.resolve(workspaceRoot, options)\n if ((await fs.stat(root, signal))?.type !== 'directory') throw new Error('workspace root is not a directory')\n const workspace = fs.processPath(root)\n const target = await fs.resolve(filePath, { cwd: workspace, ...options })\n if (!fs.contains(root, target)) throw new Error('source is outside workspace')\n if ((await fs.stat(target, signal))?.type !== 'file') throw new Error('source is not a regular file')\n let text = '', bytes = 0\n for await (const chunk of await fs.streamText(target, signal)) {\n throwIfAborted(signal)\n bytes += Buffer.byteLength(chunk)\n if (bytes > maxBytes) throw new Error('source exceeds document limit')\n text += chunk\n }\n throwIfAborted(signal)\n return { workspace, workspaceUri: fs.fileUrl(root), key: root.targetKey, uri: fs.fileUrl(target), text }\n}\n","export type FileKind = 'blade' | 'php' | 'typescript' | 'typescriptreact' | 'javascript' | 'javascriptreact' | 'svelte' | 'html' | 'css'\n\nexport interface ClassifiedFile {\n path: string\n basename: string\n suffix: string\n kind: FileKind\n}\n\nconst CLASSIFIERS: ReadonlyArray<{ suffix: string; kind: FileKind }> = [\n { suffix: '.blade.php', kind: 'blade' },\n { suffix: '.typescriptreact', kind: 'typescriptreact' },\n { suffix: '.javascriptreact', kind: 'javascriptreact' },\n { suffix: '.tsx', kind: 'typescriptreact' },\n { suffix: '.jsx', kind: 'javascriptreact' },\n { suffix: '.mts', kind: 'typescript' },\n { suffix: '.cts', kind: 'typescript' },\n { suffix: '.mjs', kind: 'javascript' },\n { suffix: '.cjs', kind: 'javascript' },\n { suffix: '.svelte', kind: 'svelte' },\n { suffix: '.html', kind: 'html' },\n { suffix: '.htm', kind: 'html' },\n { suffix: '.php', kind: 'php' },\n { suffix: '.ts', kind: 'typescript' },\n { suffix: '.js', kind: 'javascript' },\n { suffix: '.css', kind: 'css' },\n { suffix: '.pcss', kind: 'css' },\n]\n\nexport function classifyFile(filePath: string, bladeSuffixes: string[] = ['.blade.php']): ClassifiedFile | undefined {\n const normalizedPath = filePath.replaceAll('\\\\', '/')\n const basename = normalizedPath.slice(normalizedPath.lastIndexOf('/') + 1).toLowerCase()\n if (!basename || basename === '.' || basename === '..' || basename.startsWith('.')) return undefined\n const customBlade = bladeSuffixes.map((suffix) => suffix.toLowerCase()).sort((left, right) => right.length - left.length)\n const classifiers = [...customBlade.map((suffix) => ({ suffix, kind: 'blade' as const })), ...CLASSIFIERS.filter((item) => !customBlade.includes(item.suffix))]\n const match = classifiers.find((item) => basename.endsWith(item.suffix))\n if (!match) return undefined\n return { path: normalizedPath, basename, suffix: match.suffix, kind: match.kind }\n}\n","import type { ServerId } from '../config.js'\nimport type { ClassifiedFile } from './classifier.js'\n\nexport interface Route {\n primary: { server: ServerId; languageId: string }\n auxiliary?: { server: 'tailwind'; languageId: string }\n}\n\nconst ROUTES: Record<ClassifiedFile['kind'], Route> = {\n blade: { primary: { server: 'phpantom', languageId: 'blade' }, auxiliary: { server: 'tailwind', languageId: 'html' } },\n php: { primary: { server: 'phpantom', languageId: 'php' } },\n typescript: { primary: { server: 'typescript', languageId: 'typescript' }, auxiliary: { server: 'tailwind', languageId: 'typescript' } },\n typescriptreact: { primary: { server: 'typescript', languageId: 'typescriptreact' }, auxiliary: { server: 'tailwind', languageId: 'typescriptreact' } },\n javascript: { primary: { server: 'typescript', languageId: 'javascript' }, auxiliary: { server: 'tailwind', languageId: 'javascript' } },\n javascriptreact: { primary: { server: 'typescript', languageId: 'javascriptreact' }, auxiliary: { server: 'tailwind', languageId: 'javascriptreact' } },\n svelte: { primary: { server: 'svelte', languageId: 'svelte' }, auxiliary: { server: 'tailwind', languageId: 'svelte' } },\n html: { primary: { server: 'html', languageId: 'html' }, auxiliary: { server: 'tailwind', languageId: 'html' } },\n css: { primary: { server: 'css', languageId: 'css' }, auxiliary: { server: 'tailwind', languageId: 'css' } },\n}\n\nexport function routeFor(file: ClassifiedFile): Route {\n const route = ROUTES[file.kind]\n return { primary: { ...route.primary }, ...(route.auxiliary ? { auxiliary: { ...route.auxiliary } } : {}) }\n}\n","const DEFAULT_PATTERNS = [\n /\\bclass\\s*=\\s*[\"'][^\"']*$/i,\n /\\bclassName\\s*=\\s*[\"'][^\"']*$/i,\n /\\bclass:list\\s*=\\s*[\"'][^\"']*$/i,\n /@apply\\s+[\\w-]*$/i,\n /\\b(?:clsx|cva)\\s*\\([^)]*[\"'][^\"']*$/i,\n]\n\nexport function hasTailwindCandidate(source: string, line: number, classRegex: Array<string | [string, string]> = [], character?: number, classAttributes: string[] = ['class', 'className', 'class:list']): boolean {\n const lines = source.split(/\\r?\\n/)\n const context = [...lines.slice(Math.max(0, line - 2), line), (lines[line] ?? '').slice(0, character)].join('\\n')\n if (classAttributes.some(attribute => {\n const index = context.lastIndexOf(attribute + '=')\n return index >= 0 && /^[\\\"'][^\\\"']*$/.test(context.slice(index + attribute.length + 1).trimStart())\n })) return true\n const configured = classRegex.flatMap((item) => Array.isArray(item) ? item : [item]).map((pattern) => new RegExp(pattern))\n return [...DEFAULT_PATTERNS, ...configured].some((pattern) => pattern.test(context))\n}\n","import type { InitializeParams, InitializeResult } from './types.js'\nimport type { JsonRpcConnection } from '../runtime/connection.js'\nimport { throwIfAborted } from '../runtime/cancellation.js'\n\nexport async function initializeServer(connection: JsonRpcConnection, params: InitializeParams, signal?: AbortSignal): Promise<InitializeResult> {\n throwIfAborted(signal)\n const value = await connection.request('initialize', params, signal)\n if (!isInitializeResult(value)) throw new Error('malformed initialize response')\n await connection.notify('initialized', {})\n return value\n}\n\nfunction isInitializeResult(value: unknown): value is InitializeResult {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && typeof (value as { capabilities?: unknown }).capabilities === 'object' && (value as { capabilities?: unknown }).capabilities !== null\n}\n","import { TextDecoder } from 'node:util'\n\nexport class JsonRpcFrameError extends Error {\n readonly code = 'LSP_MALFORMED_RESPONSE'\n\n constructor(message: string) {\n super(message)\n this.name = 'JsonRpcFrameError'\n }\n}\n\nexport class ContentLengthDecoder {\n private buffer = Buffer.alloc(0)\n private readonly decoder = new TextDecoder('utf-8', { fatal: true })\n\n constructor(private readonly maxMessageBytes: number) {\n if (!Number.isSafeInteger(maxMessageBytes) || maxMessageBytes <= 0) throw new RangeError('maxMessageBytes must be positive')\n }\n\n feed(chunk: Uint8Array): unknown[] {\n this.buffer = Buffer.concat([this.buffer, Buffer.from(chunk)])\n const messages: unknown[] = []\n while (true) {\n const headerEnd = this.buffer.indexOf(Buffer.from('\\r\\n\\r\\n'))\n if (headerEnd < 0) {\n if (this.buffer.length > 8192) throw new JsonRpcFrameError('header exceeds limit')\n break\n }\n const header = this.buffer.subarray(0, headerEnd).toString('ascii')\n const length = this.parseLength(header)\n const bodyStart = headerEnd + 4\n if (length > this.maxMessageBytes) throw new JsonRpcFrameError('message exceeds configured limit')\n if (this.buffer.length < bodyStart + length) break\n const body = this.buffer.subarray(bodyStart, bodyStart + length)\n this.buffer = this.buffer.subarray(bodyStart + length)\n let text: string\n try {\n text = this.decoder.decode(body)\n } catch {\n throw new JsonRpcFrameError('message is not valid UTF-8')\n }\n try {\n messages.push(JSON.parse(text) as unknown)\n } catch {\n throw new JsonRpcFrameError('message body is not valid JSON')\n }\n }\n return messages\n }\n\n end(): void {\n if (this.buffer.length > 0) throw new JsonRpcFrameError('incomplete JSON-RPC frame')\n }\n\n private parseLength(header: string): number {\n const lines = header.split('\\r\\n')\n let length: number | undefined\n for (const line of lines) {\n const separator = line.indexOf(':')\n if (separator < 1) throw new JsonRpcFrameError('malformed header')\n const key = line.slice(0, separator).toLowerCase()\n const value = line.slice(separator + 1).trim()\n if (key === 'content-length') {\n if (length !== undefined || !/^\\d+$/.test(value)) throw new JsonRpcFrameError('invalid Content-Length')\n length = Number(value)\n }\n }\n if (length === undefined || !Number.isSafeInteger(length)) throw new JsonRpcFrameError('Content-Length is required')\n return length\n }\n}\n\nexport function encodeJsonRpc(message: object): Buffer {\n const body = Buffer.from(JSON.stringify(message), 'utf8')\n return Buffer.concat([Buffer.from(`Content-Length: ${body.length}\\r\\n\\r\\n`, 'ascii'), body])\n}\n","import type { Readable, Writable } from 'node:stream'\nimport { abortError, onAbort, throwIfAborted } from './cancellation.js'\nimport { ContentLengthDecoder, encodeJsonRpc, JsonRpcFrameError } from './framing.js'\nimport type { JsonRpcConnectionOptions, JsonRpcId, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse } from '../protocol/types.js'\n\ninterface PendingRequest {\n resolve: (value: unknown) => void\n reject: (error: unknown) => void\n method: string\n}\n\nexport class JsonRpcConnection {\n private readonly decoder: ContentLengthDecoder\n private readonly pending = new Map<JsonRpcId, PendingRequest>()\n private readonly notificationListeners = new Set<(notification: JsonRpcNotification) => void>()\n private nextId = 1\n private closed = false\n private requestHandler: NonNullable<JsonRpcConnectionOptions['onServerRequest']>\n\n constructor(private readonly input: Readable, private readonly output: Writable, options: JsonRpcConnectionOptions) {\n this.decoder = new ContentLengthDecoder(options.maxMessageBytes)\n this.requestHandler = options.onServerRequest ?? (() => null)\n if (options.onNotification) this.notificationListeners.add(options.onNotification)\n input.on('data', (chunk: Buffer) => this.receive(chunk))\n input.once('end', () => this.close(new Error('LSP process closed stdout')))\n input.once('error', (error) => this.close(error))\n output.on('error', (error) => this.close(error))\n }\n\n get isOpen(): boolean { return !this.closed }\n\n onNotification(listener: (notification: JsonRpcNotification) => void): () => void {\n this.notificationListeners.add(listener)\n return () => this.notificationListeners.delete(listener)\n }\n\n setRequestHandler(handler: NonNullable<JsonRpcConnectionOptions['onServerRequest']>): void {\n this.requestHandler = handler\n }\n\n async request(method: string, params?: unknown, signal?: AbortSignal): Promise<unknown> {\n throwIfAborted(signal)\n if (this.closed) throw new Error('connection is closed')\n const id = this.nextId++\n const promise = new Promise<unknown>((resolve, reject) => this.pending.set(id, { resolve, reject, method }))\n void promise.catch(() => {})\n const remove = onAbort(signal, () => {\n void this.notify('$/cancelRequest', { id }).catch(() => {})\n this.pending.get(id)?.reject(abortError())\n this.pending.delete(id)\n })\n try {\n void this.write({ jsonrpc: '2.0', id, method, ...(params === undefined ? {} : { params }) }).catch(error => this.close(error))\n return await promise\n } finally {\n remove()\n this.pending.delete(id)\n }\n }\n\n async notify(method: string, params?: unknown): Promise<void> {\n if (this.closed) throw new Error('connection is closed')\n await this.write({ jsonrpc: '2.0', method, ...(params === undefined ? {} : { params }) })\n }\n\n close(reason = new Error('connection closed')): void {\n if (this.closed) return\n this.closed = true\n for (const pending of this.pending.values()) pending.reject(reason)\n this.pending.clear()\n }\n\n private receive(chunk: Buffer): void {\n if (this.closed) return\n let messages: unknown[]\n try {\n messages = this.decoder.feed(chunk)\n } catch (error) {\n this.close(error instanceof Error ? error : new JsonRpcFrameError('invalid frame'))\n return\n }\n for (const message of messages) this.dispatch(message)\n }\n\n private dispatch(value: unknown): void {\n if (!isRecord(value) || value.jsonrpc !== '2.0') return this.close(new JsonRpcFrameError('invalid JSON-RPC message'))\n if ('method' in value && typeof value.method === 'string') {\n if ('id' in value) {\n const request = value as unknown as JsonRpcRequest\n Promise.resolve().then(() => this.requestHandler(request.method, request.params)).then(\n (result) => this.write({ jsonrpc: '2.0', id: request.id, result }),\n (error: unknown) => this.write({ jsonrpc: '2.0', id: request.id, error: { code: -32603, message: error instanceof Error ? error.message : 'server request failed' } }),\n ).catch(() => {})\n } else {\n for (const listener of this.notificationListeners) listener(value as unknown as JsonRpcNotification)\n }\n return\n }\n if ('id' in value) {\n const response = value as unknown as JsonRpcResponse\n const pending = this.pending.get(response.id)\n if (!pending) return\n if (response.error) pending.reject(new Error(`${response.error.code}: ${response.error.message}`))\n else pending.resolve(response.result)\n this.pending.delete(response.id)\n }\n }\n\n private write(message: JsonRpcMessage): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.output.write(encodeJsonRpc(message), (error?: Error | null) => error ? reject(error) : resolve())\n })\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { SubprocessHandle } from '@deepseek-ai/dsh-subprocess'\nimport type { InitializeParams, InitializeResult } from '../protocol/types.js'\nimport { initializeServer } from '../protocol/initialize.js'\nimport { JsonRpcConnection } from './connection.js'\nimport { withAbort, throwIfAborted } from './cancellation.js'\n\nexport type SessionState = 'NEW' | 'STARTING' | 'READY' | 'STOPPING' | 'STOPPED' | 'FAILED'\nexport interface ServerSessionOptions {\n spawn(): SubprocessHandle\n initialize: InitializeParams\n configuration: unknown\n maxMessageBytes: number\n shutdown: { shutdownMs: number; killGraceMs: number }\n}\n\nexport class ServerSession {\n state: SessionState = 'NEW'\n capabilities: Record<string, unknown> = {}\n private child?: SubprocessHandle\n private connection?: JsonRpcConnection\n private stopping?: Promise<void>\n private readonly lifetime = new AbortController()\n constructor(private readonly options: ServerSessionOptions) {}\n\n async start(signal?: AbortSignal): Promise<InitializeResult> {\n throwIfAborted(signal)\n this.state = 'STARTING'\n try {\n const child = this.options.spawn()\n this.child = child\n // Observe failed spawn even when stdio could not be allocated.\n void child.done.catch(() => {})\n if (!child.stdout || !child.stdin) throw new Error('server stdio is unavailable')\n const connection = new JsonRpcConnection(child.stdout, child.stdin, {\n maxMessageBytes: this.options.maxMessageBytes,\n onServerRequest: (method, params) => this.answer(method, params),\n })\n this.connection = connection\n void child.done.then(() => connection.close(new Error('LSP process exited')), error => connection.close(error instanceof Error ? error : new Error('LSP spawn failed'))).then(() => {\n if (this.state !== 'STOPPING' && this.state !== 'STOPPED') this.state = 'FAILED'\n })\n const result = await initializeServer(connection, this.options.initialize, this.signal(signal))\n if (result.capabilities.positionEncoding && result.capabilities.positionEncoding !== 'utf-16') throw new Error('server requires unsupported position encoding')\n const sync = result.capabilities.textDocumentSync\n if (sync === undefined || sync === 0 || (typeof sync === 'object' && sync !== null && !(sync as { openClose?: boolean }).openClose)) throw new Error('server does not support document open/close')\n this.capabilities = result.capabilities\n await connection.notify('workspace/didChangeConfiguration', { settings: this.options.configuration })\n throwIfAborted(this.signal(signal))\n this.state = 'READY'\n return result\n } catch (error) {\n this.state = 'FAILED'\n await this.stop()\n throw error\n }\n }\n\n get usable(): boolean { return this.state === 'READY' && !!this.connection?.isOpen }\n isUsable(): boolean { return this.usable }\n async run<T>(task: (connection: JsonRpcConnection) => Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!this.usable || !this.connection) throw new Error('session is not ready')\n try { return await withAbort(task(this.connection), this.signal(signal)) }\n catch (error) {\n // Stop cancelled work before the next queued request can reuse this process.\n if (signal?.aborted || !this.connection.isOpen) await this.stop()\n throw error\n }\n }\n\n stop(): Promise<void> {\n return this.stopping ??= this.teardown()\n }\n private async teardown(): Promise<void> {\n this.state = 'STOPPING'\n this.lifetime.abort()\n const child = this.child, connection = this.connection\n const timeout = AbortSignal.timeout(this.options.shutdown.shutdownMs)\n if (connection?.isOpen) {\n try { await connection.request('shutdown', null, timeout); await connection.notify('exit') } catch {}\n }\n connection?.close(new Error('session stopped'))\n if (child) {\n child.terminate()\n if (!await child.waitForExit(AbortSignal.timeout(this.options.shutdown.killGraceMs + 1000))) throw new Error('language server process tree did not exit within the cleanup deadline')\n }\n this.state = 'STOPPED'\n }\n private signal(signal?: AbortSignal): AbortSignal { return signal ? AbortSignal.any([signal, this.lifetime.signal]) : this.lifetime.signal }\n private answer(method: string, params: unknown): unknown {\n if (method === 'workspace/applyEdit') return { applied: false, failureReason: 'read-only provider' }\n if (method === 'workspace/workspaceFolders') return this.options.initialize.workspaceFolders ?? []\n if (method === 'workspace/configuration') {\n const items = (params as { items?: Array<{ section?: string }> } | undefined)?.items ?? []\n return items.map(item => {\n let value = this.options.configuration\n for (const key of item.section?.split('.') ?? []) {\n value = typeof value === 'object' && value !== null ? (value as Record<string, unknown>)[key] : undefined\n }\n return value ?? null\n })\n }\n return null\n }\n}\n","import { throwIfAborted, withAbort } from './cancellation.js'\n\nexport interface PoolSession {\n readonly state: string\n start(signal?: AbortSignal): Promise<unknown>\n stop(): Promise<void>\n isUsable(): boolean\n}\nexport type SessionFactory<S extends PoolSession> = (serverId: string, workspace: string, signal?: AbortSignal) => Promise<S>\n\nexport class ServerPool<S extends PoolSession> {\n private readonly sessions = new Map<string, S>()\n private readonly creation = new Map<string, Promise<S>>()\n private readonly queues = new Map<string, Promise<void>>()\n private disposing = false\n constructor(private readonly factory: SessionFactory<S>) {}\n\n async getOrCreate(serverId: string, workspace: string, signal?: AbortSignal): Promise<S> {\n throwIfAborted(signal)\n if (this.disposing) throw new Error('server pool is disposing')\n const key = keyOf(serverId, workspace)\n const existing = this.sessions.get(key)\n if (existing?.isUsable()) return existing\n const pending = this.creation.get(key)\n if (pending) return withAbort(pending, signal)\n const creation = this.create(key, serverId, workspace, existing, signal)\n this.creation.set(key, creation)\n try { return await creation }\n finally { if (this.creation.get(key) === creation) this.creation.delete(key) }\n }\n\n run<T>(serverId: string, workspace: string, task: (session: S) => Promise<T>, signal?: AbortSignal): Promise<T> {\n return this.serialize(keyOf(serverId, workspace), async () => task(await this.getOrCreate(serverId, workspace, signal)), signal)\n }\n\n runWithRetry<T>(serverId: string, workspace: string, task: (session: S) => Promise<T>, signal?: AbortSignal, canReuse?: (session: S) => boolean): Promise<T> {\n // Keep failure eviction and the retry inside the same queue slot. A later query\n // must never enter a replacement process before the failed query finishes cleanup.\n return this.serialize(keyOf(serverId, workspace), async () => {\n const existing = this.sessions.get(keyOf(serverId, workspace))\n // Replacement belongs to this queue slot, after earlier work has completed.\n if (existing?.isUsable() && canReuse && !canReuse(existing)) await this.evict(serverId, workspace)\n for (let attempt = 0; ; attempt++) {\n const session = await this.getOrCreate(serverId, workspace, signal)\n try { return await task(session) }\n catch (error) {\n throwIfAborted(signal)\n if (attempt > 0 || session.isUsable()) throw error\n if (this.sessions.get(keyOf(serverId, workspace)) === session) await this.evict(serverId, workspace)\n }\n }\n }, signal)\n }\n\n async evict(serverId: string, workspace: string): Promise<void> {\n const key = keyOf(serverId, workspace)\n const session = this.sessions.get(key)\n this.sessions.delete(key)\n if (session) await session.stop()\n }\n\n async disposeAll(): Promise<void> {\n this.disposing = true\n const results = await Promise.allSettled([...this.sessions.values()].map(session => session.stop()))\n this.sessions.clear()\n await Promise.all([...this.creation.values()].map(creation => creation.then(session => session.stop(), () => {})))\n this.creation.clear()\n const failures = results.filter((result): result is PromiseRejectedResult => result.status === 'rejected')\n if (failures.length) throw new AggregateError(failures.map(result => result.reason), 'language server cleanup failed')\n }\n\n get size(): number { return this.sessions.size }\n\n private async serialize<T>(key: string, task: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n const previous = this.queues.get(key) ?? Promise.resolve()\n let release!: () => void\n const current = new Promise<void>(resolve => { release = resolve })\n this.queues.set(key, current)\n try {\n await withAbort(previous, signal)\n throwIfAborted(signal)\n return await task()\n } finally {\n // A cancelled waiter cannot let its successor bypass still-running work.\n void previous.then(release, release)\n void current.then(() => { if (this.queues.get(key) === current) this.queues.delete(key) })\n }\n }\n\n private async create(key: string, serverId: string, workspace: string, previous?: S, signal?: AbortSignal): Promise<S> {\n if (previous) { this.sessions.delete(key); await previous.stop() }\n throwIfAborted(signal)\n const session = await this.factory(serverId, workspace, signal)\n try { await session.start(signal) } catch (error) { await session.stop(); throw error }\n if (this.disposing) { await session.stop(); throw new Error('server pool is disposing') }\n this.sessions.set(key, session)\n return session\n }\n}\n\nexport function keyOf(serverId: string, workspace: string): string { return `${serverId}\\u0000${workspace}` }\n","export type StandardOperation = 'goToDefinition' | 'findReferences' | 'goToImplementation' | 'hover'\n\nexport function supportsOperation(capabilities: Record<string, unknown>, operation: StandardOperation): boolean {\n if (operation === 'goToDefinition') return capabilities.definitionProvider === true || isProvider(capabilities.definitionProvider)\n if (operation === 'findReferences') return capabilities.referencesProvider === true || isProvider(capabilities.referencesProvider)\n if (operation === 'goToImplementation') return capabilities.implementationProvider === true || isProvider(capabilities.implementationProvider)\n return capabilities.hoverProvider === true || isProvider(capabilities.hoverProvider)\n}\n\nfunction isProvider(value: unknown): boolean {\n return typeof value === 'object' && value !== null || value === true\n}\n\nexport function defaultServerRequest(method: string, params: unknown): unknown {\n if (method === 'workspace/configuration') {\n return Array.isArray(params) ? params.map(() => null) : []\n }\n if (method === 'window/workDoneProgress/create' || method === 'client/registerCapability' || method === 'client/unregisterCapability') return null\n if (method === 'workspace/applyEdit') return { applied: false, failureReason: 'read-only provider' }\n return null\n}\n","import type { LspRange } from '../service.js'\n\nexport interface NormalizedHover {\n contents: string\n range?: LspRange\n}\n\nexport function normalizeHover(value: unknown): NormalizedHover | null | undefined {\n if (value === null || value === undefined) return null\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as { contents?: unknown; range?: unknown }\n const contents = normalizeContents(record.contents)\n if (contents === undefined) return undefined\n return { contents, ...(isRange(record.range) ? { range: record.range } : {}) }\n}\n\nfunction normalizeContents(value: unknown): string | undefined {\n if (typeof value === 'string') return value\n if (Array.isArray(value)) {\n const parts = value.map((item) => typeof item === 'string' ? item : isRecord(item) && typeof item.value === 'string' ? item.value : undefined)\n return parts.every((item): item is string => item !== undefined) ? parts.join('\\n') : undefined\n }\n if (isRecord(value) && typeof value.value === 'string') return value.value\n return undefined\n}\n\nfunction isRange(value: unknown): value is LspRange {\n return isRecord(value) && isPosition(value.start) && isPosition(value.end)\n}\n\nfunction isPosition(value: unknown): boolean {\n return isRecord(value) && Number.isInteger(value.line) && Number.isInteger(value.character) && value.line >= 0 && value.character >= 0\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { LspPosition, LspRange } from '../service.js'\n\nexport interface NormalizedLocation {\n uri: string\n range: LspRange\n}\n\nexport function normalizeLocation(value: unknown): NormalizedLocation | undefined {\n if (isRecord(value) && typeof value.targetUri === 'string' && isRange(value.targetSelectionRange)) return { uri: value.targetUri, range: value.targetSelectionRange }\n if (!isRecord(value) || typeof value.uri !== 'string' || !isRange(value.range)) return undefined\n return { uri: value.uri, range: value.range }\n}\n\nexport function normalizeLocations(value: unknown): NormalizedLocation[] {\n const values = Array.isArray(value) ? value : value === null || value === undefined ? [] : [value]\n return values.map(normalizeLocation).filter((location): location is NormalizedLocation => location !== undefined)\n}\n\nfunction isRange(value: unknown): value is LspRange {\n return isRecord(value) && isPosition(value.start) && isPosition(value.end)\n}\n\nfunction isPosition(value: unknown): value is LspPosition {\n return isRecord(value) && Number.isInteger(value.line) && Number.isInteger(value.character) && value.line >= 0 && value.character >= 0\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { LspRange, NormalizedDiagnostic } from '../service.js'\n\nexport function normalizeDiagnostic(value: unknown, server: string, fallbackUri: string): NormalizedDiagnostic | undefined {\n if (!isRecord(value) || !isRange(value.range) || typeof value.message !== 'string') return undefined\n const uri = typeof value.uri === 'string' ? value.uri : fallbackUri\n const severity = typeof value.severity === 'number' && value.severity >= 1 && value.severity <= 4 ? value.severity as 1 | 2 | 3 | 4 : undefined\n const code = typeof value.code === 'string' || typeof value.code === 'number' ? value.code : undefined\n return { server, uri, range: value.range, message: value.message, ...(severity === undefined ? {} : { severity }), ...(code === undefined ? {} : { code }), ...(typeof value.source === 'string' ? { source: value.source } : {}) }\n}\n\nexport function normalizeDiagnostics(value: unknown, server: string, fallbackUri: string): NormalizedDiagnostic[] {\n const values = Array.isArray(value) ? value : []\n return values.map((item) => normalizeDiagnostic(item, server, fallbackUri)).filter((item): item is NormalizedDiagnostic => item !== undefined)\n}\n\nfunction isRange(value: unknown): value is LspRange {\n return isRecord(value) && isPosition(value.start) && isPosition(value.end)\n}\n\nfunction isPosition(value: unknown): boolean {\n return isRecord(value) && Number.isInteger(value.line) && Number.isInteger(value.character) && value.line >= 0 && value.character >= 0\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { NormalizedCompletionItem } from '../service.js'\n\nexport function normalizeCompletionItem(value: unknown, server: string): NormalizedCompletionItem | undefined {\n if (!isRecord(value) || typeof value.label !== 'string' || value.label.length === 0) return undefined\n return {\n server,\n label: value.label,\n ...(typeof value.kind === 'number' ? { kind: value.kind } : {}),\n ...(typeof value.detail === 'string' ? { detail: value.detail } : {}),\n ...(typeof value.documentation === 'string' ? { documentation: value.documentation } : {}),\n ...(typeof value.sortText === 'string' ? { sortText: value.sortText } : {}),\n ...(typeof value.filterText === 'string' ? { filterText: value.filterText } : {}),\n ...(typeof value.insertText === 'string' ? { insertText: value.insertText } : {}),\n ...(typeof value.insertTextFormat === 'number' ? { insertTextFormat: value.insertTextFormat } : {}),\n ...(typeof value.deprecated === 'boolean' ? { deprecated: value.deprecated } : {}),\n }\n}\n\nexport function normalizeCompletion(value: unknown, server: string): NormalizedCompletionItem[] {\n const items = isRecord(value) && Array.isArray(value.items) ? value.items : Array.isArray(value) ? value : []\n return items.map((item) => normalizeCompletionItem(item, server)).filter((item): item is NormalizedCompletionItem => item !== undefined)\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { NormalizedHover } from '../protocol/normalize-hover.js'\nimport type { LspRange } from '../service.js'\n\nexport interface ServerHover extends NormalizedHover {\n server: string\n}\n\nexport function mergeHover(primary: ServerHover | null | undefined, auxiliary: ServerHover | null | undefined): ServerHover | null {\n if (!primary && !auxiliary) return null\n if (!primary) return auxiliary ? { ...auxiliary } : null\n if (!auxiliary) return { ...primary }\n const contents = [primary.contents, auxiliary.contents].filter((value, index, values) => values.indexOf(value) === index)\n const range = sameRange(primary.range, auxiliary.range) ? primary.range : undefined\n return { server: primary.server, contents: contents.join('\\n\\n'), ...(range ? { range } : {}) }\n}\n\nfunction sameRange(left: LspRange | undefined, right: LspRange | undefined): boolean {\n return JSON.stringify(left) === JSON.stringify(right)\n}\n","import type { LspProviderQuery, LspQueryResult } from '@deepseek-ai/dsh-lsp'\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport type { ResolvedConfig, ServerId } from '../config.js'\nimport { SERVER_IDS } from '../config.js'\nimport { readSource, type HostFileSystem, type HostSource } from '../host/dsh.js'\nimport { classifyFile } from '../routing/classifier.js'\nimport { routeFor, type Route } from '../routing/route-table.js'\nimport { hasTailwindCandidate } from '../routing/tailwind-candidate.js'\nimport { resolveLaunch, initializationOptions, serverConfiguration } from '../servers/launch.js'\nimport { ServerSession } from './server-session.js'\nimport { ServerPool } from './server-pool.js'\nimport { throwIfAborted, withAbort } from './cancellation.js'\nimport { WebstackLspError } from '../errors.js'\nimport { supportsOperation } from '../protocol/capabilities.js'\nimport { normalizeHover } from '../protocol/normalize-hover.js'\nimport { normalizeLocations } from '../protocol/normalize-location.js'\nimport { normalizeDiagnostics } from '../protocol/normalize-diagnostic.js'\nimport { normalizeCompletion } from '../protocol/normalize-completion.js'\nimport { mergeHover } from '../merge/hover.js'\nimport { mergeDiagnostics } from '../merge/diagnostics.js'\nimport { mergeCompletions } from '../merge/completion.js'\nimport type { CompletionRequest, CompletionResult, DiagnosticsRequest, DiagnosticsResult, LspPosition, WebstackLspStatus } from '../service.js'\nimport type { JsonRpcConnection } from './connection.js'\n\nexport type HostSubprocess = Pick<SubprocessRuntime, 'spawn' | 'resolveExecutable'>\nconst methods = { hover: 'textDocument/hover', goToDefinition: 'textDocument/definition', findReferences: 'textDocument/references', goToImplementation: 'textDocument/implementation' } as const\nconst clientCapabilities = {\n general: { positionEncodings: ['utf-16'] },\n workspace: { configuration: true, workspaceFolders: true, applyEdit: false },\n textDocument: {\n synchronization: { dynamicRegistration: false, didSave: false },\n hover: { contentFormat: ['markdown', 'plaintext'] },\n completion: { completionItem: { snippetSupport: true, documentationFormat: ['markdown', 'plaintext'] } },\n publishDiagnostics: { versionSupport: true }, diagnostic: {},\n },\n}\n\nexport class WebstackLspRuntime {\n private readonly pool: ServerPool<ServerSession>\n private readonly workspaces = new Map<string, HostSource>()\n private readonly lifetime = new AbortController()\n private readonly live = new Map<ServerSession, ServerId>()\n private readonly starts = new Map<string, number>()\n private readonly restarts = new Map<ServerId, number>()\n constructor(private readonly config: ResolvedConfig, private readonly fs: HostFileSystem, private readonly subprocess: HostSubprocess) {\n this.pool = new ServerPool(async (rawId, key, signal) => {\n const id = rawId as ServerId, source = this.workspaces.get(key)!\n const spec = await resolveLaunch(id, config, source.workspace)\n let executable: string\n try { executable = await subprocess.resolveExecutable(spec.command, spec.env, signal) }\n catch { throwIfAborted(signal); throw new WebstackLspError('LSP_UNAVAILABLE', `${id} executable is unavailable; run dsh-lsp-webstack --json`) }\n const session = new ServerSession({\n spawn: () => subprocess.spawn({ argv: [executable, ...spec.args], cwd: source.workspace, env: spec.env, stdio: { stdin: 'pipe', stdout: 'pipe', stderr: { maxBytes: config.limits.maxStderrBytes } }, graceMs: config.timeouts.killGraceMs }),\n initialize: { processId: null, rootUri: source.workspaceUri, workspaceFolders: [{ uri: source.workspaceUri, name: 'workspace' }], capabilities: clientCapabilities, initializationOptions: initializationOptions(id, config) },\n configuration: serverConfiguration(id, config), maxMessageBytes: config.limits.maxMessageBytes,\n shutdown: { shutdownMs: config.timeouts.shutdownMs, killGraceMs: config.timeouts.killGraceMs },\n })\n const slot = `${id}\\u0000${key}`\n if (this.starts.has(slot)) this.restarts.set(id, (this.restarts.get(id) ?? 0) + 1)\n this.starts.set(slot, (this.starts.get(slot) ?? 0) + 1)\n for (const [old] of this.live) if (old.state === 'STOPPED' || old.state === 'FAILED') this.live.delete(old)\n this.live.set(session, id)\n return session\n })\n }\n\n async navigation(request: LspProviderQuery, signal?: AbortSignal): Promise<LspQueryResult> {\n const deadline = this.signal(request.operation === 'hover' ? this.config.timeouts.primaryHoverMs : this.config.timeouts.navigationMs, signal)\n const [source, route] = await this.prepare(request, deadline)\n this.validatePosition(source.text, request.position)\n const result = await this.document(route.primary.server, source, route.primary.languageId, deadline, async (session, connection) => {\n if (!supportsOperation(session.capabilities, request.operation)) throw new WebstackLspError('LSP_UNSUPPORTED_OPERATION', `${route.primary.server} does not support ${request.operation}`)\n return connection.request(methods[request.operation], { textDocument: { uri: source.uri }, position: request.position, ...(request.operation === 'findReferences' ? { context: { includeDeclaration: true } } : {}) }, deadline)\n })\n if (request.operation !== 'hover') return { kind: 'locations', locations: normalizeLocations(result), resolvedWorkspaceUri: source.workspaceUri }\n const primary = normalizeHover(result)\n if (primary === undefined) throw new WebstackLspError('LSP_MALFORMED_RESPONSE', 'invalid hover result')\n let auxiliary = null\n if (this.useTailwind(route, source, request.position)) {\n const auxSignal = this.signal(this.config.timeouts.auxiliaryHoverMs, signal)\n try {\n const value = await this.document('tailwind', source, route.auxiliary!.languageId, auxSignal, (_session, connection) => connection.request('textDocument/hover', { textDocument: { uri: source.uri }, position: request.position }, auxSignal))\n auxiliary = normalizeHover(value) ?? null\n } catch { throwIfAborted(signal); throwIfAborted(this.lifetime.signal) }\n }\n const hover = mergeHover(primary && { ...primary, server: route.primary.server }, auxiliary && { ...auxiliary, server: 'tailwind' })\n return { kind: 'hover', hover: hover ? { contents: hover.contents, ...(hover.range ? { range: hover.range } : {}) } : null }\n }\n\n async completion(request: CompletionRequest, signal?: AbortSignal): Promise<CompletionResult> {\n const deadline = this.signal(this.config.timeouts.completionMs, signal)\n const [source, route] = await this.prepare(request, deadline)\n this.validatePosition(source.text, request.position)\n const query = (id: ServerId, language: string) => this.document(id, source, language, deadline, (session, connection) => {\n if (!session.capabilities.completionProvider) throw new WebstackLspError('LSP_UNSUPPORTED_OPERATION', `${id} does not support completion`)\n return connection.request('textDocument/completion', { textDocument: { uri: source.uri }, position: request.position, context: { triggerKind: request.triggerKind ?? 1, ...(request.triggerCharacter ? { triggerCharacter: request.triggerCharacter } : {}) } }, deadline)\n }).then(value => {\n const prefix = source.text.split(/\\r?\\n/)[request.position.line]!.slice(0, request.position.character).match(/[\\w$:@/!\\[\\]-]+$/)?.[0]?.toLowerCase() ?? ''\n // Servers such as Tailwind return the whole catalog; the client must rank the typed prefix before applying a result cap.\n return normalizeCompletion(value, id).sort((a, b) => Number((b.filterText ?? b.label).toLowerCase().startsWith(prefix)) - Number((a.filterText ?? a.label).toLowerCase().startsWith(prefix)))\n })\n const primary = await query(route.primary.server, route.primary.languageId)\n let auxiliary: typeof primary = []\n if (this.useTailwind(route, source, request.position)) {\n try { auxiliary = await query('tailwind', route.auxiliary!.languageId) } catch { throwIfAborted(signal); throwIfAborted(this.lifetime.signal) }\n }\n return mergeCompletions([primary, auxiliary], { maxCompletions: Number.MAX_SAFE_INTEGER, maxResultChars: Number.MAX_SAFE_INTEGER })\n }\n\n async diagnostics(request: DiagnosticsRequest, signal?: AbortSignal): Promise<DiagnosticsResult> {\n const deadline = this.signal(this.config.timeouts.diagnosticsMs, signal)\n const [source, route] = await this.prepare(request, deadline)\n const selected = [route.primary, ...(route.auxiliary && this.config.tailwind.enabled ? [route.auxiliary] : [])].filter(item => this.config.servers[item.server].enabled && (!request.servers || request.servers.includes(item.server)))\n if (!selected.length) throw new WebstackLspError('LSP_UNAVAILABLE', 'no selected diagnostic server supports this file')\n const omittedServers: string[] = []\n const groups = await Promise.all(selected.map(async item => {\n try {\n const value = await this.document(item.server, source, item.languageId, deadline, async (session, connection, opened) => {\n if (session.capabilities.diagnosticProvider) {\n await opened()\n const report = await connection.request('textDocument/diagnostic', { textDocument: { uri: source.uri } }, deadline) as { items?: unknown }\n return report?.items ?? []\n }\n // Subscribe before didOpen; do not confuse a missing publication with a clean file.\n let remove = () => {}\n const published = new Promise<unknown>(resolve => {\n remove = connection.onNotification(message => {\n const p = message.params as { uri?: string; diagnostics?: unknown; version?: number } | undefined\n if (message.method === 'textDocument/publishDiagnostics' && p?.uri === source.uri && (p.version === undefined || p.version === 1)) resolve(p.diagnostics)\n })\n })\n try { await opened(); return await withAbort(published, deadline) } finally { remove() }\n }, true)\n return normalizeDiagnostics(value, item.server, source.uri).filter(d => !request.severity || request.severity === 'all' || d.severity === (request.severity === 'error' ? 1 : 2))\n } catch (error) {\n throwIfAborted(signal); throwIfAborted(this.lifetime.signal)\n if (item.server === route.primary.server || this.config.missingServerPolicy === 'error') throw error\n omittedServers.push(item.server)\n return []\n }\n }))\n return { ...mergeDiagnostics(groups, { maxDiagnostics: Number.MAX_SAFE_INTEGER, maxResultChars: Number.MAX_SAFE_INTEGER }), ...(omittedServers.length ? { omittedServers: omittedServers.sort() } : {}) }\n }\n\n async status(): Promise<WebstackLspStatus> {\n return { providerId: this.config.providerId, servers: await Promise.all(SERVER_IDS.map(async id => {\n const config = this.config.servers[id]\n let available = false\n try {\n const launch = await resolveLaunch(id, this.config, '.')\n await this.subprocess.resolveExecutable(launch.command, launch.env, this.signal(5000))\n available = true\n } catch {}\n return { id, enabled: config.enabled && (id !== 'tailwind' || this.config.tailwind.enabled), available, source: config.mode, liveWorkspaces: [...this.live].filter(([s, server]) => server === id && s.isUsable()).length, restarts: this.restarts.get(id) ?? 0 }\n })) }\n }\n\n async dispose(): Promise<void> { this.lifetime.abort(); await this.pool.disposeAll(); this.workspaces.clear(); this.live.clear() }\n\n private signal(ms: number, signal?: AbortSignal): AbortSignal { return AbortSignal.any([this.lifetime.signal, AbortSignal.timeout(ms), ...(signal ? [signal] : [])]) }\n private async prepare(request: { workspaceRoot: string; filePath: string }, signal: AbortSignal): Promise<[HostSource, Route]> {\n throwIfAborted(signal)\n const file = classifyFile(request.filePath, this.config.routing.bladeSuffixes)\n if (!file) throw new WebstackLspError('LSP_UNAVAILABLE', 'unsupported file extension')\n const source = await readSource(this.fs, request.workspaceRoot, request.filePath, this.config.limits.maxDocumentBytes, signal).catch(error => { throwIfAborted(signal); throw error })\n this.workspaces.set(source.key, { ...source, text: '' })\n return [source, routeFor(file)]\n }\n private validatePosition(text: string, position: LspPosition): void {\n const line = text.split(/\\r?\\n/)[position.line]\n if (!Number.isSafeInteger(position.line) || !Number.isSafeInteger(position.character) || position.line < 0 || position.character < 0 || line === undefined || position.character > line.length) throw new RangeError('position is outside document (zero-based UTF-16 required)')\n }\n private useTailwind(route: Route, source: HostSource, position: LspPosition): boolean {\n return !!route.auxiliary && this.config.tailwind.enabled && this.config.servers.tailwind.enabled && (route.primary.languageId === 'blade' || this.config.routing.tailwindLanguages.includes(route.primary.languageId) || route.primary.languageId === 'css') && (this.config.tailwind.queryStrategy === 'always' || hasTailwindCandidate(source.text, position.line, this.config.tailwind.classRegex, position.character, this.config.tailwind.classAttributes))\n }\n private async document<T>(id: ServerId, source: HostSource, language: string, signal: AbortSignal, task: (session: ServerSession, connection: JsonRpcConnection, open: () => Promise<void>) => Promise<T>, manualOpen = false): Promise<T> {\n if (!this.config.servers[id].enabled) throw new WebstackLspError('LSP_UNAVAILABLE', `${id} is disabled`)\n return this.pool.runWithRetry(id, source.key, session => session.run(async connection => {\n let opened = false\n const open = async () => { opened = true; await connection.notify('textDocument/didOpen', { textDocument: { uri: source.uri, languageId: language, version: 1, text: source.text } }) }\n try { if (!manualOpen) await open(); return await task(session, connection, open) }\n finally { if (opened && connection.isOpen) await connection.notify('textDocument/didClose', { textDocument: { uri: source.uri } }).catch(() => {}) }\n }, signal), signal, manualOpen ? session => {\n // Push notifications can omit document versions. A delayed didClose clear\n // from a previous operation is indistinguishable from a fresh clean result.\n // Use a fresh process for push diagnostics; pull responses have request IDs.\n return !!session.capabilities.diagnosticProvider\n } : undefined)\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { LspProviderId } from '@deepseek-ai/dsh-lsp'\nimport type { LspProvider, LspProviderQuery, LspQueryResult } from '@deepseek-ai/dsh-lsp'\nimport type { Config as PluginConfig, ResolvedConfig } from './config.js'\nimport { resolveConfig } from './config.js'\nimport type { WebstackLspService } from './service.js'\nimport { createWebstackLspService } from './service.js'\nimport { WebstackLspRuntime } from './runtime/webstack-runtime.js'\nimport type {} from '@deepseek-ai/dsh-fs'\nimport type {} from '@deepseek-ai/dsh-subprocess'\n\nexport type { LspProvider, LspProviderQuery, LspQueryResult }\nexport type Config = PluginConfig\nexport const name = 'lsp-webstack-provider'\nexport const inject = ['fs', 'lsp', 'subprocess']\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { webstackLsp: WebstackLspService }\n}\n\nexport const OUTER_EXTENSION_MAP = {\n '.php': 'php', '.ts': 'typescript', '.tsx': 'typescriptreact', '.mts': 'typescript', '.cts': 'typescript',\n '.js': 'javascript', '.jsx': 'javascriptreact', '.mjs': 'javascript', '.cjs': 'javascript',\n '.svelte': 'svelte', '.html': 'html', '.htm': 'html', '.css': 'css', '.pcss': 'css',\n} as const\n\nexport interface CompositeRuntime {\n navigation(request: LspProviderQuery, signal?: AbortSignal): Promise<LspQueryResult>\n dispose?(): Promise<void>\n}\n\nexport function createCompositeProvider(runtime: CompositeRuntime, config: Pick<ResolvedConfig, 'providerId'> = { providerId: 'webstack' }): LspProvider {\n return { id: LspProviderId(config.providerId), extensionToLanguage: { ...OUTER_EXTENSION_MAP }, query: (request, signal) => runtime.navigation(request, signal) }\n}\n\nexport async function apply(ctx: Context, config: unknown = {}): Promise<void> {\n const resolved = resolveConfig(config)\n const runtime = new WebstackLspRuntime(resolved, ctx.fs, ctx.subprocess)\n await ctx.effect(async function* () {\n yield () => runtime.dispose()\n if (resolved.missingServerPolicy === 'error') {\n const missing = (await runtime.status()).servers.filter(server => server.enabled && !server.available)\n if (missing.length) throw new Error(`unavailable language servers: ${missing.map(server => server.id).join(', ')}`)\n }\n yield ctx.lsp.registerProvider(createCompositeProvider(runtime, resolved))\n yield ctx.provide('webstackLsp', createWebstackLspService(runtime))\n }, 'webstack LSP provider')\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import type { LspProviderQuery, LspQueryResult } from '@deepseek-ai/dsh-lsp';
2
- import type { SubprocessService } from '@deepseek-ai/dsh-subprocess';
2
+ import type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess';
3
3
  import type { ResolvedConfig } from '../config.js';
4
4
  import { type HostFileSystem } from '../host/dsh.js';
5
5
  import type { CompletionRequest, CompletionResult, DiagnosticsRequest, DiagnosticsResult, WebstackLspStatus } from '../service.js';
6
- export type HostSubprocess = Pick<SubprocessService, 'spawn' | 'resolveExecutable'>;
6
+ export type HostSubprocess = Pick<SubprocessRuntime, 'spawn' | 'resolveExecutable'>;
7
7
  export declare class WebstackLspRuntime {
8
8
  private readonly config;
9
9
  private readonly fs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askdkc/dsh-lsp-server",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "Composite read-only LSP provider for DeepSeek Harness web stacks",
5
5
  "type": "module",
6
6
  "main": "./lib/provider.js",
@@ -47,6 +47,8 @@
47
47
  "prepublishOnly": "npm run check"
48
48
  },
49
49
  "dependencies": {
50
+ "@deepseek-ai/dsh-lsp": "0.1.7-rc.2",
51
+ "@deepseek-ai/dsh-tool-lsp": "0.1.7-rc.2",
50
52
  "@tailwindcss/language-server": "0.16.0",
51
53
  "svelte-language-server": "0.17.15",
52
54
  "typescript": "5.7.3",
@@ -54,38 +56,41 @@
54
56
  "vscode-langservers-extracted": "4.10.0"
55
57
  },
56
58
  "peerDependencies": {
57
- "@deepseek-ai/cordis": "^4.0.2",
58
- "@deepseek-ai/dsh-lsp": "0.0.1-rc.1 || ^0.1.3-alpha.1",
59
- "@deepseek-ai/schemastery": "^3.18.2",
60
- "@deepseek-ai/dsh-fs": "0.0.1-rc.1 || ^0.1.3-alpha.1",
61
- "@deepseek-ai/dsh-subprocess": "0.0.1-rc.1 || ^0.1.3-alpha.1",
62
- "@deepseek-ai/dsh-tools": "0.0.1-rc.1 || ^0.1.3-alpha.1",
63
- "@deepseek-ai/dsh-system-prompt": "0.0.1-rc.1 || ^0.1.3-alpha.1",
64
- "@deepseek-ai/dsh-tool-lsp": "0.0.1-rc.1 || ^0.1.3-alpha.1"
59
+ "@deepseek-ai/cordis": "~4.0.4",
60
+ "@deepseek-ai/dsh-fs": ">=0.1.7-rc.2 <0.2.0",
61
+ "@deepseek-ai/dsh-subprocess": ">=0.1.7-rc.2 <0.2.0",
62
+ "@deepseek-ai/dsh-system-prompt": ">=0.1.7-rc.2 <0.2.0",
63
+ "@deepseek-ai/dsh-tools": ">=0.1.7-rc.2 <0.2.0",
64
+ "@deepseek-ai/schemastery": "~3.18.4"
65
65
  },
66
66
  "devDependencies": {
67
+ "@deepseek-ai/cordis": "~4.0.4",
68
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
69
+ "@deepseek-ai/dsh-brand": "0.1.7-rc.2",
70
+ "@deepseek-ai/dsh-fs": "0.1.7-rc.2",
71
+ "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2",
72
+ "@deepseek-ai/dsh-http-proxy": "0.1.7-rc.2",
73
+ "@deepseek-ai/dsh-invariants": "0.1.7-rc.2",
74
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
75
+ "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2",
76
+ "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2",
77
+ "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2",
78
+ "@deepseek-ai/dsh-scope": "0.1.7-rc.2",
79
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
80
+ "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2",
81
+ "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2",
82
+ "@deepseek-ai/dsh-subprocess-local": "0.1.7-rc.2",
83
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2",
84
+ "@deepseek-ai/dsh-timeout": "0.1.7-rc.2",
85
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
86
+ "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2",
87
+ "@deepseek-ai/schemastery": "~3.18.4",
67
88
  "@types/node": "22.10.5",
89
+ "tailwindcss-v3": "npm:tailwindcss@3.4.17",
90
+ "tailwindcss-v4": "npm:tailwindcss@4.1.13",
68
91
  "tsdown": "0.15.0",
69
92
  "typescript": "5.7.3",
70
- "vitest": "3.2.6",
71
- "@deepseek-ai/cordis": "^4.0.2",
72
- "@deepseek-ai/dsh-lsp": "0.0.1-rc.1",
73
- "@deepseek-ai/schemastery": "^3.18.2",
74
- "@deepseek-ai/dsh-fs": "0.0.1-rc.1",
75
- "@deepseek-ai/dsh-subprocess": "0.0.1-rc.1",
76
- "@deepseek-ai/dsh-tools": "0.0.1-rc.1",
77
- "@deepseek-ai/dsh-system-prompt": "0.0.1-rc.1",
78
- "@deepseek-ai/dsh-tool-lsp": "0.0.1-rc.1",
79
- "@deepseek-ai/dsh-brand": "0.0.1-rc.1",
80
- "@deepseek-ai/dsh-invariants": "0.0.1-rc.1",
81
- "@deepseek-ai/dsh-llm": "0.0.1-rc.1",
82
- "@deepseek-ai/dsh-timeout": "0.0.1-rc.1",
83
- "@deepseek-ai/dsh-scope": "0.0.1-rc.1",
84
- "@deepseek-ai/dsh-session": "0.0.1-rc.1",
85
- "@deepseek-ai/dsh-fs-local": "0.0.1-rc.1",
86
- "@deepseek-ai/dsh-subprocess-local": "0.0.1-rc.1",
87
- "tailwindcss-v3": "npm:tailwindcss@3.4.17",
88
- "tailwindcss-v4": "npm:tailwindcss@4.1.13"
93
+ "vitest": "3.2.6"
89
94
  },
90
95
  "engines": {
91
96
  "node": ">=22.18.0"
@@ -119,9 +124,6 @@
119
124
  "@deepseek-ai/cordis": {
120
125
  "optional": true
121
126
  },
122
- "@deepseek-ai/dsh-lsp": {
123
- "optional": true
124
- },
125
127
  "@deepseek-ai/schemastery": {
126
128
  "optional": true
127
129
  },
@@ -136,9 +138,6 @@
136
138
  },
137
139
  "@deepseek-ai/dsh-system-prompt": {
138
140
  "optional": true
139
- },
140
- "@deepseek-ai/dsh-tool-lsp": {
141
- "optional": true
142
141
  }
143
142
  }
144
143
  }