wiki-graph-sdk 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +32 -0
  3. package/dist/archives.cjs +2799 -0
  4. package/dist/archives.cjs.map +1 -0
  5. package/dist/archives.d.ts +249 -0
  6. package/dist/archives.js +2814 -0
  7. package/dist/archives.js.map +1 -0
  8. package/dist/conversions.cjs +1332 -0
  9. package/dist/conversions.cjs.map +1 -0
  10. package/dist/conversions.d.ts +37 -0
  11. package/dist/conversions.js +1308 -0
  12. package/dist/conversions.js.map +1 -0
  13. package/dist/data/editor/clue_reviewer.jinja +410 -0
  14. package/dist/data/editor/clue_reviewer_generator.jinja +428 -0
  15. package/dist/data/editor/revision_feedback.jinja +5 -0
  16. package/dist/data/editor/text_compressor.jinja +131 -0
  17. package/dist/data/guaranteed/response_intent_classifier.jinja +8 -0
  18. package/dist/data/output/epub/cover.xhtml.jinja +13 -0
  19. package/dist/data/output/epub/nav.xhtml.jinja +12 -0
  20. package/dist/data/output/epub/package.opf.xml.jinja +39 -0
  21. package/dist/data/output/epub/section.xhtml.jinja +12 -0
  22. package/dist/data/topologization/book_coherence_extraction.jinja +223 -0
  23. package/dist/data/topologization/chunk_extraction.jinja +233 -0
  24. package/dist/data/topologization/evidence_choice.jinja +38 -0
  25. package/dist/data/topologization/translate_chunks.jinja +138 -0
  26. package/dist/data/topologization/user_focused_extraction.jinja +378 -0
  27. package/dist/default-worker.cjs +1709 -0
  28. package/dist/default-worker.cjs.map +1 -0
  29. package/dist/default-worker.d.ts +10 -0
  30. package/dist/default-worker.js +1705 -0
  31. package/dist/default-worker.js.map +1 -0
  32. package/dist/embedding.cjs +1091 -0
  33. package/dist/embedding.cjs.map +1 -0
  34. package/dist/embedding.d.ts +26 -0
  35. package/dist/embedding.js +1062 -0
  36. package/dist/embedding.js.map +1 -0
  37. package/dist/entry-context.cjs +91 -0
  38. package/dist/entry-context.cjs.map +1 -0
  39. package/dist/entry-context.d.ts +20 -0
  40. package/dist/entry-context.js +68 -0
  41. package/dist/entry-context.js.map +1 -0
  42. package/dist/gc.cjs +731 -0
  43. package/dist/gc.cjs.map +1 -0
  44. package/dist/gc.d.ts +14 -0
  45. package/dist/gc.js +707 -0
  46. package/dist/gc.js.map +1 -0
  47. package/dist/index.cjs +4760 -0
  48. package/dist/index.cjs.map +1 -0
  49. package/dist/index.d.ts +213 -0
  50. package/dist/index.js +4808 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/jobs-Dd5PMSId.d.ts +98 -0
  53. package/dist/llm.cjs +101 -0
  54. package/dist/llm.cjs.map +1 -0
  55. package/dist/llm.d.ts +7 -0
  56. package/dist/llm.js +79 -0
  57. package/dist/llm.js.map +1 -0
  58. package/dist/local-config.cjs +1024 -0
  59. package/dist/local-config.cjs.map +1 -0
  60. package/dist/local-config.d.ts +14 -0
  61. package/dist/local-config.js +989 -0
  62. package/dist/local-config.js.map +1 -0
  63. package/dist/maintenance.cjs +800 -0
  64. package/dist/maintenance.cjs.map +1 -0
  65. package/dist/maintenance.d.ts +24 -0
  66. package/dist/maintenance.js +778 -0
  67. package/dist/maintenance.js.map +1 -0
  68. package/dist/node-platform.cjs +758 -0
  69. package/dist/node-platform.cjs.map +1 -0
  70. package/dist/node-platform.d.ts +49 -0
  71. package/dist/node-platform.js +723 -0
  72. package/dist/node-platform.js.map +1 -0
  73. package/dist/planning.cjs +164 -0
  74. package/dist/planning.cjs.map +1 -0
  75. package/dist/planning.d.ts +43 -0
  76. package/dist/planning.js +137 -0
  77. package/dist/planning.js.map +1 -0
  78. package/dist/runtime-config.cjs +1155 -0
  79. package/dist/runtime-config.cjs.map +1 -0
  80. package/dist/runtime-config.d.ts +50 -0
  81. package/dist/runtime-config.js +1127 -0
  82. package/dist/runtime-config.js.map +1 -0
  83. package/dist/stage.cjs +1265 -0
  84. package/dist/stage.cjs.map +1 -0
  85. package/dist/stage.d.ts +16 -0
  86. package/dist/stage.js +1239 -0
  87. package/dist/stage.js.map +1 -0
  88. package/dist/wikispine.cjs +85 -0
  89. package/dist/wikispine.cjs.map +1 -0
  90. package/dist/wikispine.d.ts +6 -0
  91. package/dist/wikispine.js +63 -0
  92. package/dist/wikispine.js.map +1 -0
  93. package/dist/worker.cjs +738 -0
  94. package/dist/worker.cjs.map +1 -0
  95. package/dist/worker.d.ts +157 -0
  96. package/dist/worker.js +715 -0
  97. package/dist/worker.js.map +1 -0
  98. package/package.json +151 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/conversions.ts","../src/llm.ts","../src/node-platform.ts","../src/runtime-config.ts","../src/local-config.ts","../src/runtime-context.ts","../src/runtime-path.ts"],"sourcesContent":["import { rm } from \"fs/promises\";\n\nimport {\n WikiGraph,\n type ChapterStage,\n type WikiGraphArchive,\n type WikiGraphProgressCallback,\n} from \"wiki-graph-core\";\n\nimport { buildWikiGraphLLMOptions } from \"./llm.js\";\nimport { NodeDirectory, NodeFile } from \"./node-platform.js\";\nimport { loadWikiGraphRuntimeConfig } from \"./runtime-config.js\";\nimport type { WikiGraphJobRuntime } from \"./jobs.js\";\nimport { resolveWikiGraphRuntimePath } from \"./runtime-path.js\";\n\nexport type WikiGraphConversionFormat = \"epub\" | \"markdown\" | \"txt\" | \"wikg\";\nexport type WikiGraphSourceFormat = Exclude<WikiGraphConversionFormat, \"wikg\">;\n\nexport type WikiGraphConversionInput =\n | { readonly format: WikiGraphConversionFormat; readonly path: string }\n | {\n readonly format: Extract<WikiGraphSourceFormat, \"markdown\" | \"txt\">;\n readonly stream: AsyncIterable<string> | Iterable<string>;\n };\n\nexport interface WikiGraphConversionOptions {\n readonly digestDirectory?: string;\n readonly input: WikiGraphConversionInput;\n readonly llmJSON?: string;\n readonly onProgress?: WikiGraphProgressCallback;\n readonly output: {\n readonly format: WikiGraphConversionFormat;\n readonly path: string;\n };\n readonly prompt?: string;\n readonly targetStage?: ChapterStage;\n readonly verbose?: boolean;\n}\n\nexport interface WikiGraphConversionResult {\n readonly inputFormat: WikiGraphConversionFormat;\n readonly outputFormat: WikiGraphConversionFormat;\n readonly outputPath: string;\n}\n\nexport class WikiGraphConversionManager {\n readonly #runtime: WikiGraphJobRuntime;\n\n public constructor(runtime: WikiGraphJobRuntime) {\n this.#runtime = runtime;\n }\n\n public async convert(\n options: WikiGraphConversionOptions,\n ): Promise<WikiGraphConversionResult> {\n return await this.#runtime.run(async () => await this.#convert(options));\n }\n\n async #convert(\n options: WikiGraphConversionOptions,\n ): Promise<WikiGraphConversionResult> {\n const targetStage = options.targetStage ?? \"summarized\";\n if (options.targetStage !== undefined && options.output.format !== \"wikg\") {\n throw new Error(\"targetStage is only supported for wikg output.\");\n }\n if (options.targetStage !== undefined && options.input.format === \"wikg\") {\n throw new Error(\n \"targetStage is only supported when creating a wikg archive.\",\n );\n }\n\n const requiresDigest = options.input.format !== \"wikg\";\n const requiresLLM =\n requiresDigest && targetStage !== \"planned\" && targetStage !== \"sourced\";\n const config = await loadWikiGraphRuntimeConfig({\n ...(options.llmJSON === undefined ? {} : { llmJSON: options.llmJSON }),\n });\n const app = new WikiGraph({\n ...(options.verbose === true ? { verbose: true } : {}),\n ...(requiresLLM ? { llm: buildWikiGraphLLMOptions(config) } : {}),\n });\n const documentDirectory = await prepareDigestDirectory(\n options.digestDirectory,\n requiresDigest,\n );\n const write = async (archive: WikiGraphArchive): Promise<void> => {\n await writeArchive(archive, options.output.path, options.output.format);\n };\n\n if (options.input.format === \"wikg\") {\n if (!(\"path\" in options.input)) {\n throw new Error(\"wikg input requires a file path.\");\n }\n await app.openSession(\n new NodeFile(resolveWikiGraphRuntimePath(options.input.path)),\n write,\n );\n } else if (\"stream\" in options.input) {\n await app.digestTextStreamSession(\n {\n ...(documentDirectory === undefined ? {} : { documentDirectory }),\n ...(options.onProgress === undefined\n ? {}\n : { onProgress: options.onProgress }),\n sourceFormat: options.input.format,\n stream: options.input.stream,\n ...((options.prompt ?? config.prompt) === undefined\n ? {}\n : { extractionPrompt: options.prompt ?? config.prompt }),\n targetStage,\n },\n write,\n );\n } else {\n const digestOptions = {\n ...(documentDirectory === undefined ? {} : { documentDirectory }),\n file: new NodeFile(resolveWikiGraphRuntimePath(options.input.path)),\n ...(options.onProgress === undefined\n ? {}\n : { onProgress: options.onProgress }),\n ...((options.prompt ?? config.prompt) === undefined\n ? {}\n : { extractionPrompt: options.prompt ?? config.prompt }),\n targetStage,\n };\n if (options.input.format === \"epub\") {\n await app.digestEpubSession(digestOptions, write);\n } else if (options.input.format === \"markdown\") {\n await app.digestMarkdownSession(digestOptions, write);\n } else {\n await app.digestTxtSession(digestOptions, write);\n }\n }\n\n return {\n inputFormat: options.input.format,\n outputFormat: options.output.format,\n outputPath: options.output.path,\n };\n }\n}\n\nasync function prepareDigestDirectory(\n path: string | undefined,\n required: boolean,\n): Promise<NodeDirectory | undefined> {\n const normalized = path?.trim();\n if (!required || normalized === undefined || normalized === \"\")\n return undefined;\n const resolved = resolveWikiGraphRuntimePath(normalized);\n await rm(resolved, { force: true, recursive: true });\n return new NodeDirectory(resolved);\n}\n\nasync function writeArchive(\n archive: WikiGraphArchive,\n path: string,\n format: WikiGraphConversionFormat,\n): Promise<void> {\n const file = new NodeFile(resolveWikiGraphRuntimePath(path));\n if (format === \"epub\") await archive.exportEpub(file);\n else if (format === \"wikg\") await archive.saveAs(file);\n else await archive.exportText(file);\n}\n","import type { WikiGraphLLMOptions } from \"wiki-graph-core\";\n\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { createGoogleGenerativeAI } from \"@ai-sdk/google\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport { createOpenAICompatible } from \"@ai-sdk/openai-compatible\";\n\nimport type {\n WikiGraphProvider,\n WikiGraphRuntimeConfig,\n} from \"./runtime-config.js\";\n\nexport function buildWikiGraphLLMOptions(\n config: WikiGraphRuntimeConfig,\n): WikiGraphLLMOptions {\n const llm = config.llm;\n\n if (llm?.provider === undefined || llm.model === undefined) {\n throw new Error(\n \"Missing LLM configuration. Set --llm for one run, or configure `wikg://local/config/llm` with provider and model.\",\n );\n }\n\n return {\n model: createLanguageModel(llm.provider, llm.model, {\n apiKey: llm.apiKey,\n baseURL: llm.baseURL,\n name: llm.name,\n }),\n ...(config.concurrent?.request === undefined\n ? {}\n : { concurrent: config.concurrent.request }),\n };\n}\n\nfunction createLanguageModel(\n provider: WikiGraphProvider,\n model: string,\n options: {\n readonly apiKey: string | undefined;\n readonly baseURL: string | undefined;\n readonly name: string | undefined;\n },\n) {\n switch (provider) {\n case \"anthropic\": {\n const anthropic = createAnthropic({\n ...(options.apiKey === undefined ? {} : { apiKey: options.apiKey }),\n ...(options.name === undefined ? {} : { name: options.name }),\n });\n\n return anthropic(model);\n }\n case \"google\": {\n const google = createGoogleGenerativeAI({\n ...(options.apiKey === undefined ? {} : { apiKey: options.apiKey }),\n ...(options.name === undefined ? {} : { name: options.name }),\n });\n\n return google(model);\n }\n case \"openai\": {\n if (options.baseURL !== undefined) {\n throw new Error(\n \"openai does not accept llm.baseURL or baseURL in --llm JSON. Use openai-compatible for third-party OpenAI-style APIs.\",\n );\n }\n\n const openai = createOpenAI({\n ...(options.apiKey === undefined ? {} : { apiKey: options.apiKey }),\n ...(options.name === undefined ? {} : { name: options.name }),\n });\n\n return openai(model);\n }\n case \"openai-compatible\": {\n if (options.baseURL === undefined) {\n throw new Error(\n \"openai-compatible requires llm.baseURL or baseURL in --llm JSON.\",\n );\n }\n\n const openaiCompatible = createOpenAICompatible({\n baseURL: options.baseURL,\n name: options.name ?? createOpenAICompatibleName(options.baseURL),\n ...(options.apiKey === undefined ? {} : { apiKey: options.apiKey }),\n });\n\n return openaiCompatible(model);\n }\n }\n}\n\nfunction createOpenAICompatibleName(baseURL: string): string {\n try {\n return new URL(baseURL).hostname;\n } catch {\n return \"openai-compatible\";\n }\n}\n","/* eslint-disable no-restricted-syntax, @typescript-eslint/parameter-properties */\nimport * as asyncHooks from \"node:async_hooks\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as fsPromises from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as pathModule from \"node:path\";\nimport * as process from \"node:process\";\nimport { Readable, Writable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport * as sqlite3 from \"sqlite3\";\nimport * as yauzl from \"yauzl\";\nimport * as yazl from \"yazl\";\nimport { Environment, Loader, type LoaderSource } from \"nunjucks\";\n\nconst nodeProcess =\n (process as unknown as { default?: typeof process }).default ?? process;\nconst nodeSqlite3 =\n (sqlite3 as unknown as { default?: typeof sqlite3 }).default ?? sqlite3;\n\nimport {\n getWikiGraphStorage,\n installWikiGraphPlatform,\n installWikiGraphStorage,\n withWikiGraphStorage,\n type Directory,\n type File,\n type FileReader,\n type ReadonlyFile,\n type FileWriter,\n type HostDatabaseConnection,\n type HostDatabaseOpenOptions,\n type HostDatabaseRow,\n type HostDatabaseValue,\n type HostZipWriteEntry,\n type HostZipReader,\n type WikiGraphPlatform,\n type WikiGraphStorage,\n normalizeTemplateName,\n} from \"wiki-graph-core/platform\";\n\n/** Stable across independently bundled SDK entry points. */\nconst NODE_RESOURCE_KIND = Symbol.for(\"wiki-graph-sdk.node-resource.v1\");\n\n/** Install the Node implementation used by the CLI and its workers. */\nexport class NodeFile implements File {\n public readonly kind = \"file\" as const;\n public readonly [NODE_RESOURCE_KIND] = \"file\" as const;\n public readonly identity: string;\n public readonly name: string;\n\n public constructor(\n public readonly path: string,\n name = pathModule.basename(path),\n ) {\n this.identity = encodeNodeResourceIdentity(\"file\", path);\n this.name = name;\n }\n\n public async openReader(): Promise<FileReader> {\n const handle = await fsPromises.open(this.path, \"r\");\n let closed = false;\n try {\n const stats = await handle.stat();\n if (!stats.isFile())\n throw new Error(\"File reader requires a regular file\");\n const { size } = stats;\n return {\n size,\n close: async () => {\n if (!closed) await handle.close();\n closed = true;\n },\n read: async (offset, length) => {\n if (closed) throw new Error(\"Cannot read from a closed FileReader\");\n assertFileRange(offset, length, size);\n const buffer = Buffer.allocUnsafe(length);\n let bytesRead = 0;\n while (bytesRead < length) {\n const result = await handle.read(\n buffer,\n bytesRead,\n length - bytesRead,\n offset + bytesRead,\n );\n if (result.bytesRead === 0) {\n throw new Error(\"File changed while reading its byte range\");\n }\n bytesRead += result.bytesRead;\n }\n return new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);\n },\n };\n } catch (error) {\n await handle.close();\n throw error;\n }\n }\n\n public async getLastModified(): Promise<number | undefined> {\n try {\n return (await fsPromises.stat(this.path)).mtimeMs;\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n public async openWriter(): Promise<FileWriter> {\n await fsPromises.mkdir(pathModule.dirname(this.path), { recursive: true });\n const temporary = `${this.path}.tmp-${crypto.randomUUID()}`;\n const handle = await fsPromises.open(temporary, \"wx\");\n let closed = false;\n return {\n write: async (data) => {\n if (closed) throw new Error(\"Cannot write to a closed FileWriter\");\n await writeNodeFileHandle(handle, data);\n },\n writeAt: async (offset, data) => {\n if (closed) throw new Error(\"Cannot write to a closed FileWriter\");\n assertFileOffset(offset);\n await writeNodeFileHandle(handle, data, offset);\n },\n commit: async () => {\n if (!closed) {\n await handle.close();\n await fsPromises.rename(temporary, this.path);\n }\n closed = true;\n },\n abort: async () => {\n if (!closed) {\n await handle.close();\n await fsPromises.rm(temporary, { force: true });\n }\n closed = true;\n },\n };\n }\n}\n\n/** @internal Completes writes even when the Node file handle reports a short write. */\nexport async function writeNodeFileHandle(\n handle: Pick<fsPromises.FileHandle, \"write\">,\n data: Uint8Array | string,\n position?: number,\n): Promise<void> {\n const buffer = Buffer.from(data);\n let written = 0;\n while (written < buffer.byteLength) {\n const result = await handle.write(\n buffer,\n written,\n buffer.byteLength - written,\n position === undefined ? null : position + written,\n );\n if (result.bytesWritten === 0) {\n throw new Error(\"File writer made no progress\");\n }\n written += result.bytesWritten;\n }\n}\n\nfunction assertFileRange(offset: number, length: number, size: number): void {\n assertFileOffset(offset);\n if (!Number.isSafeInteger(length) || length < 0) {\n throw new RangeError(\n \"File read length must be a non-negative safe integer\",\n );\n }\n if (offset > size || length > size - offset) {\n throw new RangeError(\"File read range exceeds the file size\");\n }\n}\n\nfunction assertFileOffset(offset: number): void {\n if (!Number.isSafeInteger(offset) || offset < 0) {\n throw new RangeError(\"File offset must be a non-negative safe integer\");\n }\n}\n\nexport class NodeDirectory implements Directory {\n public readonly kind = \"directory\" as const;\n public readonly [NODE_RESOURCE_KIND] = \"directory\" as const;\n public readonly identity: string;\n public readonly name: string;\n\n public constructor(public readonly path: string) {\n this.identity = encodeNodeResourceIdentity(\"directory\", path);\n this.name = pathModule.basename(path);\n }\n\n public async getFile(name: string): Promise<File | undefined> {\n assertChildName(name);\n const file = new NodeFile(pathModule.join(this.path, name));\n try {\n return (await fsPromises.stat(file.path)).isFile() ? file : undefined;\n } catch {\n return undefined;\n }\n }\n\n public async getLastModified(): Promise<number | undefined> {\n try {\n return (await fsPromises.stat(this.path)).mtimeMs;\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n public async getDirectory(name: string): Promise<Directory | undefined> {\n assertChildName(name);\n const directory = new NodeDirectory(pathModule.join(this.path, name));\n try {\n return (await fsPromises.stat(directory.path)).isDirectory()\n ? directory\n : undefined;\n } catch {\n return undefined;\n }\n }\n\n public async list(): Promise<ReadonlyArray<File | Directory>> {\n const entries = await fsPromises.readdir(this.path, {\n withFileTypes: true,\n });\n return entries.map((entry) =>\n entry.isDirectory()\n ? new NodeDirectory(pathModule.join(this.path, entry.name))\n : new NodeFile(pathModule.join(this.path, entry.name), entry.name),\n );\n }\n\n public async createFile(name: string): Promise<File> {\n assertChildName(name);\n await fsPromises.mkdir(this.path, { recursive: true });\n const file = new NodeFile(pathModule.join(this.path, name));\n await fsPromises.writeFile(file.path, \"\", { flag: \"wx\" });\n return file;\n }\n\n public async createDirectory(name: string): Promise<Directory> {\n assertChildName(name);\n await fsPromises.mkdir(this.path, { recursive: true });\n const directory = new NodeDirectory(pathModule.join(this.path, name));\n await fsPromises.mkdir(directory.path);\n return directory;\n }\n\n public async remove(\n name: string,\n options?: { readonly recursive?: boolean },\n ): Promise<void> {\n assertChildName(name);\n await fsPromises.rm(pathModule.join(this.path, name), {\n force: true,\n recursive: options?.recursive === true,\n });\n }\n}\n\nfunction encodeNodeResourceIdentity(\n kind: \"directory\" | \"file\",\n path: string,\n): string {\n return `node-${kind}:${Buffer.from(pathModule.resolve(path), \"utf8\").toString(\"base64url\")}`;\n}\n\nfunction decodeNodeResourceIdentity(\n identity: string,\n kind: \"directory\" | \"file\",\n): string | undefined {\n const prefix = `node-${kind}:`;\n if (!identity.startsWith(prefix)) {\n // State created before opaque resource identities stored native paths.\n return pathModule.isAbsolute(identity) ? identity : undefined;\n }\n try {\n return Buffer.from(identity.slice(prefix.length), \"base64url\").toString(\n \"utf8\",\n );\n } catch {\n return undefined;\n }\n}\n\nexport function getNodeResourcePath(resource: File | Directory): string {\n const brandedPath = getBrandedNodeResourcePath(resource, resource.kind);\n if (brandedPath !== undefined) return brandedPath;\n if (\n typeof resource === \"object\" &&\n resource !== null &&\n \"path\" in resource &&\n typeof resource.path === \"string\"\n ) {\n return resource.path;\n }\n throw new TypeError(\"Expected a Node File or Directory resource\");\n}\n\nfunction assertChildName(name: string): void {\n if (\n name.length === 0 ||\n name === \".\" ||\n name === \"..\" ||\n pathModule.isAbsolute(name) ||\n name.includes(\"/\") ||\n name.includes(\"\\\\\")\n ) {\n throw new TypeError(`Directory child must be a relative name: ${name}`);\n }\n}\n\nclass NodeDatabaseConnection implements HostDatabaseConnection {\n public constructor(private readonly database: sqlite3.Database) {}\n\n public async close(): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.close((error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n public async execute(sql: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.exec(sql, (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n public async queryAll(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<readonly HostDatabaseRow[]> {\n return await new Promise((resolve, reject) => {\n this.database.all(sql, [...params], (error, rows: HostDatabaseRow[]) => {\n if (error) reject(error);\n else resolve(rows);\n });\n });\n }\n\n public async queryOne(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<HostDatabaseRow | undefined> {\n return await new Promise((resolve, reject) => {\n this.database.get(sql, [...params], (error, row: HostDatabaseRow) => {\n if (error) reject(error);\n else resolve(row);\n });\n });\n }\n\n public async run(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.run(sql, [...params], (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n}\n\nasync function openNodeDatabase(\n file: ReadonlyFile,\n options: HostDatabaseOpenOptions,\n): Promise<NodeDatabaseConnection> {\n const flags =\n (options.mode === \"readonly\"\n ? nodeSqlite3.OPEN_READONLY\n : nodeSqlite3.OPEN_READWRITE |\n (options.create ? nodeSqlite3.OPEN_CREATE : 0)) |\n nodeSqlite3.OPEN_FULLMUTEX;\n return new NodeDatabaseConnection(await openNativeNodeDatabase(file, flags));\n}\n\nasync function openNativeNodeDatabase(\n file: ReadonlyFile,\n flags: number,\n): Promise<sqlite3.Database> {\n const path = getBrandedNodeResourcePath(file, \"file\");\n if (path === undefined) {\n throw new TypeError(\"The Node database adapter requires a NodeFile\");\n }\n return await new Promise((resolve, reject) => {\n const database = new nodeSqlite3.Database(path, flags, (error) => {\n if (error) reject(error);\n else resolve(database);\n });\n });\n}\n\nasync function openNodeZip(file: ReadonlyFile): Promise<HostZipReader> {\n const path = getBrandedNodeResourcePath(file, \"file\");\n if (path === undefined) {\n throw new TypeError(\"The Node ZIP adapter requires a NodeFile\");\n }\n const zipFile = await new Promise<yauzl.ZipFile>((resolve, reject) => {\n yauzl.open(\n path,\n { autoClose: false, lazyEntries: true },\n (error, opened) => {\n if (error || opened === undefined)\n reject(error ?? new Error(\"Cannot open ZIP\"));\n else resolve(opened);\n },\n );\n });\n\n const entries = await new Promise<Map<string, yauzl.Entry>>(\n (resolve, reject) => {\n const discovered = new Map<string, yauzl.Entry>();\n const rejectAndClose = (error: unknown) => {\n zipFile.close();\n reject(\n error instanceof Error\n ? error\n : new Error(\"Cannot scan ZIP central directory\"),\n );\n };\n const resolveEntries = () => {\n zipFile.off(\"error\", rejectAndClose);\n resolve(discovered);\n };\n zipFile.on(\"entry\", (entry: yauzl.Entry) => {\n if (!entry.fileName.endsWith(\"/\")) {\n discovered.set(entry.fileName, entry);\n }\n zipFile.readEntry();\n });\n zipFile.once(\"error\", rejectAndClose);\n zipFile.once(\"end\", resolveEntries);\n zipFile.readEntry();\n },\n );\n\n let closed = false;\n return {\n close: () => {\n if (!closed) zipFile.close();\n closed = true;\n return Promise.resolve();\n },\n copyEntry: async (name, target) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return false;\n await copyNodeZipEntry(zipFile, entry, target);\n return true;\n },\n getEntrySize: (name) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n return Promise.resolve(entries.get(name)?.uncompressedSize);\n },\n listEntries: () => Promise.resolve([...entries.keys()]),\n readEntryRange: async (name, offset, length) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return undefined;\n return await readNodeZipEntryRange(zipFile, entry, offset, length);\n },\n readEntry: async (name) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return undefined;\n return await readNodeZipEntry(zipFile, entry);\n },\n };\n}\n\nasync function copyNodeZipEntry(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n target: File,\n): Promise<void> {\n const writer = await target.openWriter();\n try {\n const stream = await openNodeZipEntryStream(zipFile, entry);\n await writeNodeStream(stream, writer);\n await writer.commit();\n } catch (error) {\n await writer.abort().catch(() => undefined);\n throw error;\n }\n}\n\nasync function readNodeZipEntry(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n): Promise<Uint8Array> {\n return await collectNodeStream(await openNodeZipEntryStream(zipFile, entry));\n}\n\nasync function readNodeZipEntryRange(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n offset: number,\n length: number,\n): Promise<Uint8Array> {\n assertFileRange(offset, length, entry.uncompressedSize);\n if (length === 0) return new Uint8Array();\n if (entry.compressionMethod !== 0) {\n const content = await collectDecodedNodeStreamRange(\n await openNodeZipEntryStream(zipFile, entry),\n offset,\n length,\n );\n return new Uint8Array(\n content.buffer,\n content.byteOffset,\n content.byteLength,\n );\n }\n const content = await collectNodeStream(\n await openNodeZipEntryStream(zipFile, entry, {\n decompress: null,\n decrypt: null,\n end: offset + length,\n start: offset,\n }),\n );\n return new Uint8Array(content.buffer, content.byteOffset, content.byteLength);\n}\n\nasync function collectDecodedNodeStreamRange(\n input: NodeJS.ReadableStream,\n offset: number,\n length: number,\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n const end = offset + length;\n let position = 0;\n let collected = 0;\n for await (const value of input) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);\n const chunkEnd = position + chunk.byteLength;\n if (chunkEnd > offset && position < end) {\n const selected = chunk.subarray(\n Math.max(0, offset - position),\n Math.min(chunk.byteLength, end - position),\n );\n chunks.push(selected);\n collected += selected.byteLength;\n }\n position = chunkEnd;\n if (position >= end) break;\n }\n if (collected !== length) {\n throw new Error(\"ZIP entry changed while reading its byte range\");\n }\n return Buffer.concat(chunks, collected);\n}\n\nasync function openNodeZipEntryStream(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n options?: yauzl.ZipFileOptions,\n): Promise<NodeJS.ReadableStream> {\n return await new Promise<NodeJS.ReadableStream>((resolve, reject) => {\n const callback = (error: Error | null, opened: Readable) => {\n if (error || opened === undefined) {\n reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));\n } else {\n resolve(opened);\n }\n };\n if (options === undefined) zipFile.openReadStream(entry, callback);\n else zipFile.openReadStream(entry, options, callback);\n });\n}\n\nasync function writeNodeZip(\n file: File,\n entries: Iterable<HostZipWriteEntry> | AsyncIterable<HostZipWriteEntry>,\n): Promise<void> {\n const zipFile = new yazl.ZipFile();\n const writer = await file.openWriter();\n const outputStream = zipFile.outputStream as Readable;\n const outputDone = writeNodeStream(outputStream, writer);\n const entryState = { cancelled: false, complete: false };\n let iterator:\n | Iterator<HostZipWriteEntry>\n | AsyncIterator<HostZipWriteEntry>\n | undefined;\n\n try {\n iterator = getNodeZipEntryIterator(entries);\n const entriesDone = addNodeZipEntries(zipFile, iterator, entryState);\n await Promise.race([entriesDone, outputDone]);\n if (!entryState.complete) {\n throw new Error(\"ZIP output ended before entry production completed\");\n }\n zipFile.end();\n await outputDone;\n await writer.commit();\n } catch (error) {\n entryState.cancelled = true;\n if (!entryState.complete && iterator !== undefined) {\n closeNodeZipEntryIterator(iterator);\n }\n if (!outputStream.destroyed) {\n outputStream.destroy(\n error instanceof Error ? error : new Error(\"Cannot write ZIP archive\"),\n );\n }\n await outputDone.catch(() => undefined);\n await writer.abort().catch(() => undefined);\n throw error;\n }\n}\n\nasync function addNodeZipEntries(\n zipFile: yazl.ZipFile,\n iterator: Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry>,\n state: { cancelled: boolean; complete: boolean },\n): Promise<void> {\n while (!state.cancelled) {\n const result = await iterator.next();\n if (state.cancelled) return;\n if (result.done) {\n state.complete = true;\n return;\n }\n if (\"file\" in result.value) {\n zipFile.addReadStream(\n createNodeFileReadStream(result.value.file),\n result.value.name,\n { compress: false },\n );\n } else if (\"data\" in result.value) {\n zipFile.addBuffer(Buffer.from(result.value.data), result.value.name, {\n compress: false,\n });\n } else {\n zipFile.addReadStream(\n createNodeRangeReadStream(result.value),\n result.value.name,\n { compress: false, size: result.value.size },\n );\n }\n }\n}\n\nfunction createNodeFileReadStream(file: ReadonlyFile): Readable {\n return Readable.from(\n (async function* () {\n const reader = await file.openReader();\n try {\n for (let offset = 0; offset < reader.size; ) {\n const chunk = await reader.read(\n offset,\n Math.min(64 * 1024, reader.size - offset),\n );\n offset += chunk.byteLength;\n yield chunk;\n }\n } finally {\n await reader.close();\n }\n })(),\n );\n}\n\nfunction getBrandedNodeResourcePath(\n resource: unknown,\n kind: \"directory\" | \"file\",\n): string | undefined {\n if (typeof resource !== \"object\" || resource === null) return undefined;\n const candidate = resource as {\n readonly [NODE_RESOURCE_KIND]?: unknown;\n readonly path?: unknown;\n };\n return candidate[NODE_RESOURCE_KIND] === kind &&\n typeof candidate.path === \"string\"\n ? candidate.path\n : undefined;\n}\n\nfunction createNodeRangeReadStream(\n entry: Extract<HostZipWriteEntry, { readonly size: number }>,\n): Readable {\n return Readable.from(\n (async function* () {\n for (let offset = 0; offset < entry.size; ) {\n const chunk = await entry.read(\n offset,\n Math.min(64 * 1024, entry.size - offset),\n );\n offset += chunk.byteLength;\n yield chunk;\n }\n })(),\n );\n}\n\nfunction getNodeZipEntryIterator(\n entries: Iterable<HostZipWriteEntry> | AsyncIterable<HostZipWriteEntry>,\n): Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry> {\n const asyncIterator = (entries as AsyncIterable<HostZipWriteEntry>)[\n Symbol.asyncIterator\n ];\n return asyncIterator === undefined\n ? (entries as Iterable<HostZipWriteEntry>)[Symbol.iterator]()\n : asyncIterator.call(entries);\n}\n\nfunction closeNodeZipEntryIterator(\n iterator: Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry>,\n): void {\n if (iterator.return === undefined) return;\n try {\n void Promise.resolve(iterator.return()).catch(() => undefined);\n } catch {\n // Preserve the failure that caused iteration to stop.\n }\n}\n\nasync function writeNodeStream(\n input: NodeJS.ReadableStream,\n writer: FileWriter,\n): Promise<void> {\n await pipeline(\n input,\n new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n void writer.write(chunk).then(\n () => callback(),\n (error: unknown) =>\n callback(\n error instanceof Error\n ? error\n : new Error(\"Cannot stream ZIP archive\"),\n ),\n );\n },\n }),\n );\n}\n\nasync function collectNodeStream(\n input: NodeJS.ReadableStream,\n): Promise<Buffer> {\n return await new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n input.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n input.once(\"error\", reject);\n input.once(\"end\", () => resolve(Buffer.concat(chunks)));\n });\n}\n\nexport const nodeWikiGraphPlatform: WikiGraphPlatform = {\n asyncContext: {\n create: <T>() => new asyncHooks.AsyncLocalStorage<T>(),\n },\n database: { open: openNodeDatabase },\n lifecycle: {\n instanceId: `node-process:${nodeProcess.pid}`,\n isInstanceAlive: (instanceId) => {\n const match = /^node-process:(\\d+)$/u.exec(instanceId);\n if (match === null) return Promise.resolve(undefined);\n try {\n nodeProcess.kill(Number(match[1]), 0);\n return Promise.resolve(true);\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ESRCH\"\n ) {\n return Promise.resolve(false);\n }\n return Promise.resolve(true);\n }\n },\n },\n resources: {\n getDirectory: (identity) => {\n const path = decodeNodeResourceIdentity(identity, \"directory\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeDirectory(path),\n );\n },\n getFile: (identity) => {\n const path = decodeNodeResourceIdentity(identity, \"file\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeFile(path),\n );\n },\n resolveLegacyDirectory: (reference) => {\n const path = decodeNodeResourceIdentity(reference, \"directory\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeDirectory(path),\n );\n },\n },\n templates: {\n createEnvironment: (options) =>\n new Environment(new NodeTemplateLoader(), options),\n },\n zip: {\n open: openNodeZip,\n write: writeNodeZip,\n },\n};\n\nclass NodeTemplateLoader extends Loader {\n readonly #dataDirectory: string | undefined;\n\n public constructor(dataDirectory?: string) {\n super();\n this.#dataDirectory = dataDirectory;\n }\n\n public getSource(templateName: string): LoaderSource {\n const name = normalizeTemplateName(templateName);\n const filePath = pathModule.join(\n this.#dataDirectory ?? resolveNodeDataDirectory(),\n name,\n );\n return {\n noCache: false,\n path: name,\n src: fs.readFileSync(filePath, \"utf8\"),\n };\n }\n}\n\nexport function createNodeTemplateEnvironment(\n dataDirectory: string,\n options: {\n readonly autoescape?: boolean;\n readonly trimBlocks?: boolean;\n } = {},\n): Environment {\n return new Environment(new NodeTemplateLoader(dataDirectory), {\n autoescape: options.autoescape ?? true,\n trimBlocks: options.trimBlocks ?? true,\n });\n}\n\nfunction resolveNodeDataDirectory(): string {\n const injected = (globalThis as { __WIKIGRAPH_DATA_DIR__?: unknown })\n .__WIKIGRAPH_DATA_DIR__;\n if (typeof injected === \"string\" && injected !== \"\") return injected;\n let directory = nodeProcess.cwd();\n while (true) {\n for (const candidate of [\n pathModule.join(directory, \"data\"),\n pathModule.join(directory, \"packages\", \"core\", \"data\"),\n ]) {\n try {\n if (fs.statSync(candidate).isDirectory()) return candidate;\n } catch {\n // Keep looking toward the filesystem root.\n }\n }\n const parent = pathModule.dirname(directory);\n if (parent === directory)\n throw new Error(\"Could not locate data directory\");\n directory = parent;\n }\n}\n\nexport function createNodeWikiGraphStorage(\n stateRoot = pathModule.join(os.homedir(), \".wikigraph\"),\n): WikiGraphStorage {\n return {\n library: new NodeDirectory(stateRoot),\n documentStore: new NodeDirectory(pathModule.join(stateRoot, \"documents\")),\n };\n}\n\nexport function installNodeWikiGraphPlatform(stateRoot?: string): void {\n installWikiGraphPlatform(nodeWikiGraphPlatform);\n installWikiGraphStorage(createNodeWikiGraphStorage(stateRoot));\n}\n\nexport function ensureNodeWikiGraphPlatform(): void {\n installWikiGraphPlatform(nodeWikiGraphPlatform);\n try {\n getWikiGraphStorage();\n } catch {\n installWikiGraphStorage(createNodeWikiGraphStorage());\n }\n}\n\nexport async function withNodeWikiGraphStorage<T>(\n stateRoot: string | undefined,\n operation: () => Promise<T> | T,\n): Promise<T> {\n return await withWikiGraphStorage(\n stateRoot === undefined ? undefined : createNodeWikiGraphStorage(stateRoot),\n operation,\n );\n}\n","import { z } from \"zod\";\n\nimport { readLocalConfigSection } from \"./local-config.js\";\nimport { getWikiGraphSDKRuntimeContext } from \"./runtime-context.js\";\n\nconst WIKI_GRAPH_PROVIDER_VALUES = [\n \"anthropic\",\n \"google\",\n \"openai\",\n \"openai-compatible\",\n] as const;\n\nconst wikiGraphProviderSchema = z.enum(WIKI_GRAPH_PROVIDER_VALUES);\nconst inlineLLMConfigSchema = z.object({\n apiKey: z.string().min(1).optional(),\n baseURL: z.string().min(1).optional(),\n baseUrl: z.string().min(1).optional(),\n chatCompletionsUrl: z.string().min(1).optional(),\n llm: z\n .object({\n apiKey: z.string().min(1).optional(),\n baseURL: z.string().min(1).optional(),\n baseUrl: z.string().min(1).optional(),\n chatCompletionsUrl: z.string().min(1).optional(),\n model: z.string().min(1).optional(),\n name: z.string().min(1).optional(),\n provider: wikiGraphProviderSchema.optional(),\n })\n .optional(),\n model: z.string().min(1).optional(),\n name: z.string().min(1).optional(),\n provider: wikiGraphProviderSchema.optional(),\n});\n\nexport type WikiGraphProvider = z.infer<typeof wikiGraphProviderSchema>;\n\nexport interface WikiGraphRuntimeConfig {\n readonly embedding?: {\n readonly apiKey?: string;\n readonly baseURL?: string;\n readonly dimensions?: number;\n readonly model?: string;\n readonly name?: string;\n readonly provider?: \"openai\" | \"openai-compatible\";\n };\n readonly llm?: {\n readonly apiKey?: string;\n readonly baseURL?: string;\n readonly model?: string;\n readonly name?: string;\n readonly provider?: WikiGraphProvider;\n };\n readonly prompt?: string;\n readonly concurrent?: {\n readonly job?: number;\n readonly request?: number;\n };\n readonly wikispine?:\n | { readonly provider: \"cli\" }\n | {\n readonly endpoint: string;\n readonly provider: \"fetch\";\n readonly token: string;\n };\n readonly wikimedia?: {\n readonly endpoint: string;\n readonly token: string;\n };\n}\n\nexport type HostedProviderScope = \"wg-wikimedia\" | \"wikispine\";\n\ntype InlineLLMConfig = NonNullable<WikiGraphRuntimeConfig[\"llm\"]>;\n\nexport async function loadWikiGraphRuntimeConfig(options?: {\n readonly llmJSON?: string;\n}): Promise<WikiGraphRuntimeConfig> {\n const [embedding, localLLM, concurrent, wikimedia, wikispine] =\n await Promise.all([\n readLocalConfigSection(\"embeddings\"),\n readLocalConfigSection(\"llm\"),\n readLocalConfigSection(\"concurrent\"),\n readLocalConfigSection(\"wikimedia\"),\n readLocalConfigSection(\"wikispine\"),\n ]);\n const inlineLLMConfig =\n options?.llmJSON === undefined\n ? undefined\n : parseInlineLLMConfig(options.llmJSON);\n const llm = createLLMConfig({\n apiKey: firstDefined(inlineLLMConfig?.apiKey, readString(localLLM.apiKey)),\n baseURL: firstDefined(\n inlineLLMConfig?.baseURL,\n readString(localLLM.baseURL),\n ),\n model: firstDefined(inlineLLMConfig?.model, readString(localLLM.model)),\n name: firstDefined(inlineLLMConfig?.name, readString(localLLM.name)),\n provider: firstDefined(\n inlineLLMConfig?.provider,\n readProvider(localLLM.provider),\n ),\n });\n const requestConcurrent = readPositiveInteger(concurrent.request);\n const jobConcurrent = readPositiveInteger(concurrent.job);\n const envPolicy = getWikiGraphSDKRuntimeContext().envPolicy;\n const wikispineConfig = resolveWikispineConfig(wikispine, envPolicy);\n const wikimediaConfig = createWikimediaConfig(wikimedia, envPolicy);\n const embeddingConfig = createEmbeddingConfig(embedding);\n\n return {\n ...(jobConcurrent === undefined && requestConcurrent === undefined\n ? {}\n : {\n concurrent: {\n ...(jobConcurrent === undefined ? {} : { job: jobConcurrent }),\n ...(requestConcurrent === undefined\n ? {}\n : { request: requestConcurrent }),\n },\n }),\n ...(embeddingConfig === undefined ? {} : { embedding: embeddingConfig }),\n ...(llm === undefined ? {} : { llm }),\n ...(wikimediaConfig === undefined ? {} : { wikimedia: wikimediaConfig }),\n ...(wikispineConfig === undefined ? {} : { wikispine: wikispineConfig }),\n };\n}\n\nfunction createWikimediaConfig(\n input: Record<string, unknown> | undefined,\n envPolicy: \"development\" | \"production\",\n): WikiGraphRuntimeConfig[\"wikimedia\"] | undefined {\n const endpoint = readString(input?.endpoint);\n const token = readString(input?.token);\n\n if (endpoint === undefined && token === undefined) return undefined;\n if (token === undefined) {\n throw new Error(\n \"Remote Wikimedia access requires an API key. Configure `wikg://local/config/wikimedia` token with `put token --secret`.\",\n );\n }\n return {\n endpoint:\n endpoint ?? resolveHostedProviderEndpoint(\"wg-wikimedia\", envPolicy),\n token,\n };\n}\n\nfunction createEmbeddingConfig(\n input: Record<string, unknown> | undefined,\n): WikiGraphRuntimeConfig[\"embedding\"] | undefined {\n const value = input ?? {};\n const provider = readEmbeddingProvider(value.provider);\n const apiKey = readString(value.apiKey);\n const baseURL = readString(value.baseURL);\n const dimensions =\n typeof value.dimensions === \"number\" &&\n Number.isInteger(value.dimensions) &&\n value.dimensions > 0\n ? value.dimensions\n : undefined;\n const model = readString(value.model);\n const name = readString(value.name);\n\n if (\n provider === undefined ||\n model === undefined ||\n (provider === \"openai-compatible\" && baseURL === undefined) ||\n (provider === \"openai\" && baseURL !== undefined)\n ) {\n return undefined;\n }\n\n return {\n ...(apiKey === undefined ? {} : { apiKey }),\n ...(baseURL === undefined ? {} : { baseURL }),\n ...(dimensions === undefined ? {} : { dimensions }),\n ...(model === undefined ? {} : { model }),\n ...(name === undefined ? {} : { name }),\n ...(provider === undefined ? {} : { provider }),\n };\n}\n\nfunction parseInlineLLMConfig(value: string): InlineLLMConfig | undefined {\n const normalized = normalizeString(value);\n\n if (normalized === undefined) {\n throw new Error(\"--llm must be a non-empty JSON object.\");\n }\n\n let parsedJson: unknown;\n\n try {\n parsedJson = JSON.parse(normalized);\n } catch (error) {\n throw new Error(`Invalid --llm JSON: ${formatError(error)}`);\n }\n\n const parsed = inlineLLMConfigSchema.safeParse(parsedJson);\n\n if (!parsed.success) {\n throw new Error(\n `Invalid --llm config: ${parsed.error.issues\n .map((issue) => `${issue.path.join(\".\") || \"<root>\"}: ${issue.message}`)\n .join(\"; \")}`,\n );\n }\n\n const input = parsed.data.llm ?? parsed.data;\n const provider = input.provider ?? inferInlineProvider(input);\n const baseURL = resolveInlineBaseURL(input);\n const config = createLLMConfig({\n apiKey: input.apiKey,\n baseURL,\n model: input.model,\n name: input.name,\n provider,\n });\n\n if (config === undefined) {\n throw new Error(\"--llm must contain at least one supported LLM field.\");\n }\n\n return config;\n}\n\nfunction inferInlineProvider(input: {\n readonly baseURL?: string | undefined;\n readonly baseUrl?: string | undefined;\n readonly chatCompletionsUrl?: string | undefined;\n readonly provider?: WikiGraphProvider | undefined;\n}): WikiGraphProvider | undefined {\n if (\n input.provider === undefined &&\n (input.baseURL !== undefined ||\n input.baseUrl !== undefined ||\n input.chatCompletionsUrl !== undefined)\n ) {\n return \"openai-compatible\";\n }\n\n return input.provider;\n}\n\nfunction inferBaseURLFromChatCompletionsURL(input: {\n readonly chatCompletionsUrl?: string | undefined;\n}): string | undefined {\n if (input.chatCompletionsUrl === undefined) {\n return undefined;\n }\n\n const suffix = \"/chat/completions\";\n\n if (!input.chatCompletionsUrl.endsWith(suffix)) {\n throw new Error(\n \"--llm chatCompletionsUrl must end with /chat/completions when baseURL is not provided.\",\n );\n }\n\n return input.chatCompletionsUrl.slice(0, -suffix.length);\n}\n\nfunction resolveInlineBaseURL(input: {\n readonly baseURL?: string | undefined;\n readonly baseUrl?: string | undefined;\n readonly chatCompletionsUrl?: string | undefined;\n}): string | undefined {\n if (input.baseURL !== undefined) {\n return input.baseURL;\n }\n if (input.baseUrl !== undefined) {\n return input.baseUrl;\n }\n\n return inferBaseURLFromChatCompletionsURL(input);\n}\n\nfunction createLLMConfig(input: {\n readonly apiKey: string | undefined;\n readonly baseURL: string | undefined;\n readonly model: string | undefined;\n readonly name: string | undefined;\n readonly provider: WikiGraphProvider | undefined;\n}): WikiGraphRuntimeConfig[\"llm\"] {\n if (\n input.apiKey === undefined &&\n input.baseURL === undefined &&\n input.model === undefined &&\n input.name === undefined &&\n input.provider === undefined\n ) {\n return undefined;\n }\n\n return {\n ...(input.apiKey === undefined ? {} : { apiKey: input.apiKey }),\n ...(input.baseURL === undefined ? {} : { baseURL: input.baseURL }),\n ...(input.model === undefined ? {} : { model: input.model }),\n ...(input.name === undefined ? {} : { name: input.name }),\n ...(input.provider === undefined ? {} : { provider: input.provider }),\n };\n}\n\nfunction readProvider(value: unknown): WikiGraphProvider | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const parsed = wikiGraphProviderSchema.safeParse(value);\n\n return parsed.success ? parsed.data : undefined;\n}\n\nexport function resolveWikispineConfig(\n value: Record<string, unknown>,\n envPolicy: \"development\" | \"production\" = getWikiGraphSDKRuntimeContext()\n .envPolicy,\n): WikiGraphRuntimeConfig[\"wikispine\"] | undefined {\n const provider = readWikispineProvider(value.provider);\n const endpoint = readString(value.endpoint);\n const token = readString(value.token);\n\n if (provider === undefined) {\n return undefined;\n }\n\n if (provider === \"cli\") return { provider };\n if (token === undefined) {\n throw new Error(\n \"Remote WikiSpine access requires an API key. Configure `wikg://local/config/wikispine` token with `put token --secret`.\",\n );\n }\n\n return {\n endpoint: endpoint ?? resolveHostedProviderEndpoint(\"wikispine\", envPolicy),\n provider,\n token,\n };\n}\n\nexport function resolveHostedProviderEndpoint(\n scope: HostedProviderScope,\n envPolicy: \"development\" | \"production\" = getWikiGraphSDKRuntimeContext()\n .envPolicy,\n): string {\n const origin =\n envPolicy === \"development\"\n ? \"https://pdf-craft-api.oomol.dev\"\n : \"https://api.pdfcraft.ai\";\n return `${origin}/v1/${scope}`;\n}\n\nfunction readWikispineProvider(value: unknown): \"cli\" | \"fetch\" | undefined {\n return value === \"cli\" || value === \"fetch\" ? value : undefined;\n}\n\nfunction readEmbeddingProvider(\n value: unknown,\n): \"openai\" | \"openai-compatible\" | undefined {\n return value === \"openai\" || value === \"openai-compatible\"\n ? value\n : undefined;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction readPositiveInteger(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isInteger(value) && value > 0\n ? value\n : undefined;\n}\n\nfunction firstDefined<T>(\n first: T | undefined,\n second: T | undefined,\n): T | undefined {\n return first ?? second;\n}\n\nfunction normalizeString(value: string | undefined): string | undefined {\n const normalized = value?.trim();\n\n return normalized === undefined || normalized === \"\" ? undefined : normalized;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { openSharedStateDatabase } from \"wiki-graph-core\";\nimport { getWikiGraphSDKStateDir } from \"./runtime-context.js\";\nimport { NodeFile } from \"./node-platform.js\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport type { Database } from \"wiki-graph-core\";\n\nexport const LOCAL_CONFIG_SECTIONS = [\n \"concurrent\",\n \"embeddings\",\n \"llm\",\n \"wikimedia\",\n \"wikispine\",\n] as const;\n\nexport type LocalConfigSection = (typeof LOCAL_CONFIG_SECTIONS)[number];\n\nexport type LocalConfigObject = Readonly<Record<string, unknown>>;\n\nconst LOCAL_CONFIG_SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS config_sections (\n section TEXT PRIMARY KEY,\n value_json TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n`;\n\nexport async function readLocalConfigSection(\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n return await readLocalConfigSectionInDatabase(database, section);\n });\n}\n\nexport async function replaceLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): Promise<LocalConfigObject> {\n const normalized = validateLocalConfigSection(section, value);\n\n return await withLocalConfigDatabase(async (database) => {\n await writeLocalConfigSectionInDatabase(database, section, normalized);\n return normalized;\n });\n}\n\nexport async function putLocalConfigValue(\n section: LocalConfigSection,\n key: string,\n value: unknown,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n const current = await readLocalConfigSectionInDatabase(database, section);\n const next = validateLocalConfigSection(section, {\n ...current,\n [normalizeLocalConfigKey(section, key)]: value,\n });\n\n await writeLocalConfigSectionInDatabase(database, section, next);\n return next;\n });\n}\n\nexport async function deleteLocalConfigValue(\n section: LocalConfigSection,\n key: string,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n const current = await readLocalConfigSectionInDatabase(database, section);\n const normalizedKey = normalizeLocalConfigKey(section, key);\n const { [normalizedKey]: _removed, ...nextInput } = current;\n const next = validateLocalConfigSection(section, nextInput);\n\n await writeLocalConfigSectionInDatabase(database, section, next);\n return next;\n });\n}\n\nexport async function clearLocalConfigSection(\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n return await replaceLocalConfigSection(section, {});\n}\n\nexport function parseLocalConfigSection(\n value: string | undefined,\n): LocalConfigSection | undefined {\n if (value === \"embedding\") {\n return \"embeddings\";\n }\n\n return LOCAL_CONFIG_SECTIONS.find((section) => section === value);\n}\n\nexport function maskLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): LocalConfigObject {\n if (\n (section !== \"llm\" &&\n section !== \"embeddings\" &&\n section !== \"wikimedia\" &&\n section !== \"wikispine\") ||\n (value.apiKey === undefined && value.token === undefined)\n ) {\n return value;\n }\n\n return {\n ...value,\n ...(value.apiKey === undefined ? {} : { apiKey: \"****\" }),\n ...(value.token === undefined ? {} : { token: \"****\" }),\n };\n}\n\nexport function normalizeLocalConfigKey(\n section: LocalConfigSection,\n key: string,\n): string {\n const normalized = key.trim();\n\n if (normalized === \"\") {\n throw new Error(\"Config key cannot be empty.\");\n }\n\n if (section === \"llm\" || section === \"embeddings\") {\n switch (normalized) {\n case \"api-key\":\n return \"apiKey\";\n case \"base-url\":\n return \"baseURL\";\n default:\n return normalized;\n }\n }\n return normalized;\n}\n\nexport function validateLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): LocalConfigObject {\n switch (section) {\n case \"embeddings\":\n return validateEmbeddingsConfig(value);\n case \"llm\":\n return validateLLMConfig(value);\n case \"concurrent\":\n return validateConcurrentConfig(value);\n case \"wikimedia\":\n return validateWikimediaConfig(value);\n case \"wikispine\":\n return validateWikispineConfig(value);\n }\n}\n\nasync function withLocalConfigDatabase<T>(\n operation: (database: Database) => Promise<T>,\n): Promise<T> {\n const database = await openSharedStateDatabase(\n new NodeFile(\n join(\n getWikiGraphSDKStateDir() ?? join(homedir(), \".wikigraph\"),\n \"core.sqlite\",\n ),\n ),\n LOCAL_CONFIG_SCHEMA_SQL,\n );\n\n try {\n return await operation(database);\n } finally {\n await database.close();\n }\n}\n\nasync function readLocalConfigSectionInDatabase(\n database: Database,\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n const value = await database.queryOne(\n \"SELECT value_json FROM config_sections WHERE section = ?\",\n [section],\n (row) => String(row.value_json),\n );\n\n return value === undefined ? {} : parseSectionJSON(section, value);\n}\n\nasync function writeLocalConfigSectionInDatabase(\n database: Database,\n section: LocalConfigSection,\n value: LocalConfigObject,\n): Promise<void> {\n await database.run(\n `\nINSERT INTO config_sections (section, value_json, updated_at)\nVALUES (?, ?, ?)\nON CONFLICT(section) DO UPDATE SET\n value_json = excluded.value_json,\n updated_at = excluded.updated_at\n`,\n [section, JSON.stringify(value), Date.now()],\n );\n}\n\nfunction parseSectionJSON(\n section: LocalConfigSection,\n value: string,\n): LocalConfigObject {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n throw new Error(\n `Invalid local config JSON for ${section}: ${formatError(error)}`,\n );\n }\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\n `Invalid local config section ${section}: expected object.`,\n );\n }\n\n return validateLocalConfigSection(section, parsed as LocalConfigObject);\n}\n\nfunction validateEmbeddingsConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\n \"apiKey\",\n \"baseURL\",\n \"dimensions\",\n \"model\",\n \"name\",\n \"provider\",\n ]);\n const allowedProviders = new Set([\"openai\", \"openai-compatible\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown embeddings config key: ${key}`);\n }\n if (key === \"dimensions\") {\n const parsed =\n typeof entry === \"number\"\n ? entry\n : typeof entry === \"string\"\n ? Number(entry)\n : NaN;\n\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\"embeddings.dimensions must be a positive integer.\");\n }\n next[key] = parsed;\n continue;\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`embeddings.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown embeddings.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateLLMConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\n \"apiKey\",\n \"baseURL\",\n \"model\",\n \"name\",\n \"provider\",\n ]);\n const allowedProviders = new Set([\n \"anthropic\",\n \"google\",\n \"openai\",\n \"openai-compatible\",\n ]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown llm config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`llm.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown llm.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateConcurrentConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\"job\", \"request\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown concurrent config key: ${key}`);\n }\n const parsed =\n typeof entry === \"number\"\n ? entry\n : typeof entry === \"string\"\n ? Number(entry)\n : NaN;\n\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`concurrent.${key} must be a positive integer.`);\n }\n next[key] = parsed;\n }\n\n return next;\n}\n\nfunction validateWikispineConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\"endpoint\", \"provider\", \"token\"]);\n const allowedProviders = new Set([\"cli\", \"fetch\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown wikispine config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`wikispine.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown wikispine.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateWikimediaConfig(value: LocalConfigObject): LocalConfigObject {\n return validateEndpointConfig(\"wikimedia\", value);\n}\n\nfunction validateEndpointConfig(\n section: \"wikimedia\",\n value: LocalConfigObject,\n): LocalConfigObject {\n const allowedKeys = new Set([\"endpoint\", \"token\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown ${section} config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`${section}.${key} must be a non-empty string.`);\n }\n next[key] = entry.trim();\n }\n\n return next;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\n\nexport type WikiGraphSDKEnvPolicy = \"development\" | \"production\";\n\nexport interface WikiGraphSDKRuntimeContext {\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n readonly envPolicy: WikiGraphSDKEnvPolicy;\n readonly stateDir?: string | undefined;\n}\n\n/** Shared by independently bundled SDK entry points in the same process. */\nconst RUNTIME_CONTEXT_KEY = Symbol.for(\"wiki-graph-sdk.runtime-context.v1\");\nconst runtimeContext = getRuntimeContextStorage();\n\nfunction getRuntimeContextStorage(): AsyncLocalStorage<WikiGraphSDKRuntimeContext> {\n const runtimeGlobal = globalThis as unknown as Record<PropertyKey, unknown>;\n const existing = runtimeGlobal[RUNTIME_CONTEXT_KEY];\n if (existing !== undefined) {\n return existing as AsyncLocalStorage<WikiGraphSDKRuntimeContext>;\n }\n\n const storage = new AsyncLocalStorage<WikiGraphSDKRuntimeContext>();\n Object.defineProperty(runtimeGlobal, RUNTIME_CONTEXT_KEY, {\n configurable: false,\n enumerable: false,\n value: storage,\n writable: false,\n });\n return storage;\n}\n\nexport async function withWikiGraphSDKRuntimeContext<T>(\n context: WikiGraphSDKRuntimeContext,\n operation: () => Promise<T> | T,\n): Promise<T> {\n return await runtimeContext.run(context, operation);\n}\n\nexport function getWikiGraphSDKRuntimeContext(): WikiGraphSDKRuntimeContext {\n return (\n runtimeContext.getStore() ?? {\n cwd: process.cwd(),\n env: process.env,\n envPolicy: \"production\",\n }\n );\n}\n\nexport function getWikiGraphSDKStateDir(): string | undefined {\n return getWikiGraphSDKRuntimeContext().stateDir;\n}\n","import { homedir } from \"os\";\nimport { isAbsolute, resolve } from \"path\";\n\nimport { getWikiGraphSDKRuntimeContext } from \"./runtime-context.js\";\n\nexport function resolveWikiGraphRuntimePath(path: string): string {\n const context = getWikiGraphSDKRuntimeContext();\n const environmentHome = context.env.HOME?.trim();\n const home =\n environmentHome === undefined || environmentHome === \"\"\n ? homedir()\n : environmentHome;\n if (path === \"~\") return home;\n if (path.startsWith(\"~/\")) return resolve(home, path.slice(2));\n return isAbsolute(path) ? path : resolve(context.cwd, path);\n}\n"],"mappings":";;;;;AAAA,SAAS,MAAAA,WAAU;AAEnB;AAAA,EACE;AAAA,OAIK;;;ACLP,SAAS,uBAAuB;AAChC,SAAS,gCAAgC;AACzC,SAAS,oBAAoB;AAC7B,SAAS,8BAA8B;AAOhC,SAAS,yBACd,QACqB;AACrB,QAAM,MAAM,OAAO;AAEnB,MAAI,KAAK,aAAa,UAAa,IAAI,UAAU,QAAW;AAC1D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,oBAAoB,IAAI,UAAU,IAAI,OAAO;AAAA,MAClD,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,MAAM,IAAI;AAAA,IACZ,CAAC;AAAA,IACD,GAAI,OAAO,YAAY,YAAY,SAC/B,CAAC,IACD,EAAE,YAAY,OAAO,WAAW,QAAQ;AAAA,EAC9C;AACF;AAEA,SAAS,oBACP,UACA,OACA,SAKA;AACA,UAAQ,UAAU;AAAA,IAChB,KAAK,aAAa;AAChB,YAAM,YAAY,gBAAgB;AAAA,QAChC,GAAI,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;AAAA,QACjE,GAAI,QAAQ,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;AAAA,MAC7D,CAAC;AAED,aAAO,UAAU,KAAK;AAAA,IACxB;AAAA,IACA,KAAK,UAAU;AACb,YAAM,SAAS,yBAAyB;AAAA,QACtC,GAAI,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;AAAA,QACjE,GAAI,QAAQ,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;AAAA,MAC7D,CAAC;AAED,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,IACA,KAAK,UAAU;AACb,UAAI,QAAQ,YAAY,QAAW;AACjC,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,SAAS,aAAa;AAAA,QAC1B,GAAI,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;AAAA,QACjE,GAAI,QAAQ,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;AAAA,MAC7D,CAAC;AAED,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,IACA,KAAK,qBAAqB;AACxB,UAAI,QAAQ,YAAY,QAAW;AACjC,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,mBAAmB,uBAAuB;AAAA,QAC9C,SAAS,QAAQ;AAAA,QACjB,MAAM,QAAQ,QAAQ,2BAA2B,QAAQ,OAAO;AAAA,QAChE,GAAI,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;AAAA,MACnE,CAAC;AAED,aAAO,iBAAiB,KAAK;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,SAAS,2BAA2B,SAAyB;AAC3D,MAAI;AACF,WAAO,IAAI,IAAI,OAAO,EAAE;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClGA,YAAY,gBAAgB;AAC5B,YAAY,YAAY;AACxB,YAAY,QAAQ;AACpB,YAAY,gBAAgB;AAC5B,YAAY,QAAQ;AACpB,YAAY,gBAAgB;AAC5B,YAAYC,cAAa;AACzB,SAAS,UAAU,gBAAgB;AACnC,SAAS,gBAAgB;AACzB,YAAY,aAAa;AACzB,YAAY,WAAW;AACvB,YAAY,UAAU;AACtB,SAAS,aAAa,cAAiC;AAOvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAcA;AAAA,OACK;AAxBP,IAAM,cACiD,oBAAWA;AAClE,IAAM,cACiD,mBAAW;AAwBlE,IAAM,qBAAqB,uBAAO,IAAI,iCAAiC;AAGhE,IAAM,WAAN,MAA+B;AAAA,EAM7B,YACW,MAChB,OAAkB,oBAAS,IAAI,GAC/B;AAFgB;AAGhB,SAAK,WAAW,2BAA2B,QAAQ,IAAI;AACvD,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EANF,OAAO;AAAA,EACvB,CAAiB,kBAAkB,IAAI;AAAA,EACvB;AAAA,EACA;AAAA,EAUhB,MAAa,aAAkC;AAC7C,UAAM,SAAS,MAAiB,gBAAK,KAAK,MAAM,GAAG;AACnD,QAAI,SAAS;AACb,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,KAAK;AAChC,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,qCAAqC;AACvD,YAAM,EAAE,KAAK,IAAI;AACjB,aAAO;AAAA,QACL;AAAA,QACA,OAAO,YAAY;AACjB,cAAI,CAAC,OAAQ,OAAM,OAAO,MAAM;AAChC,mBAAS;AAAA,QACX;AAAA,QACA,MAAM,OAAO,QAAQ,WAAW;AAC9B,cAAI,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAClE,0BAAgB,QAAQ,QAAQ,IAAI;AACpC,gBAAM,SAAS,OAAO,YAAY,MAAM;AACxC,cAAI,YAAY;AAChB,iBAAO,YAAY,QAAQ;AACzB,kBAAM,SAAS,MAAM,OAAO;AAAA,cAC1B;AAAA,cACA;AAAA,cACA,SAAS;AAAA,cACT,SAAS;AAAA,YACX;AACA,gBAAI,OAAO,cAAc,GAAG;AAC1B,oBAAM,IAAI,MAAM,2CAA2C;AAAA,YAC7D;AACA,yBAAa,OAAO;AAAA,UACtB;AACA,iBAAO,IAAI,WAAW,OAAO,QAAQ,OAAO,YAAY,SAAS;AAAA,QACnE;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,OAAO,MAAM;AACnB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,kBAA+C;AAC1D,QAAI;AACF,cAAQ,MAAiB,gBAAK,KAAK,IAAI,GAAG;AAAA,IAC5C,SAAS,OAAO;AACd,UACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,UACf;AACA,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,aAAkC;AAC7C,UAAiB,iBAAiB,mBAAQ,KAAK,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACzE,UAAM,YAAY,GAAG,KAAK,IAAI,QAAe,kBAAW,CAAC;AACzD,UAAM,SAAS,MAAiB,gBAAK,WAAW,IAAI;AACpD,QAAI,SAAS;AACb,WAAO;AAAA,MACL,OAAO,OAAO,SAAS;AACrB,YAAI,OAAQ,OAAM,IAAI,MAAM,qCAAqC;AACjE,cAAM,oBAAoB,QAAQ,IAAI;AAAA,MACxC;AAAA,MACA,SAAS,OAAO,QAAQ,SAAS;AAC/B,YAAI,OAAQ,OAAM,IAAI,MAAM,qCAAqC;AACjE,yBAAiB,MAAM;AACvB,cAAM,oBAAoB,QAAQ,MAAM,MAAM;AAAA,MAChD;AAAA,MACA,QAAQ,YAAY;AAClB,YAAI,CAAC,QAAQ;AACX,gBAAM,OAAO,MAAM;AACnB,gBAAiB,kBAAO,WAAW,KAAK,IAAI;AAAA,QAC9C;AACA,iBAAS;AAAA,MACX;AAAA,MACA,OAAO,YAAY;AACjB,YAAI,CAAC,QAAQ;AACX,gBAAM,OAAO,MAAM;AACnB,gBAAiB,cAAG,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,QAChD;AACA,iBAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAsB,oBACpB,QACA,MACA,UACe;AACf,QAAM,SAAS,OAAO,KAAK,IAAI;AAC/B,MAAI,UAAU;AACd,SAAO,UAAU,OAAO,YAAY;AAClC,UAAM,SAAS,MAAM,OAAO;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,OAAO,aAAa;AAAA,MACpB,aAAa,SAAY,OAAO,WAAW;AAAA,IAC7C;AACA,QAAI,OAAO,iBAAiB,GAAG;AAC7B,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,eAAW,OAAO;AAAA,EACpB;AACF;AAEA,SAAS,gBAAgB,QAAgB,QAAgB,MAAoB;AAC3E,mBAAiB,MAAM;AACvB,MAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAAG;AAC/C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,QAAQ,SAAS,OAAO,QAAQ;AAC3C,UAAM,IAAI,WAAW,uCAAuC;AAAA,EAC9D;AACF;AAEA,SAAS,iBAAiB,QAAsB;AAC9C,MAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAAG;AAC/C,UAAM,IAAI,WAAW,iDAAiD;AAAA,EACxE;AACF;AAEO,IAAM,gBAAN,MAAM,eAAmC;AAAA,EAMvC,YAA4B,MAAc;AAAd;AACjC,SAAK,WAAW,2BAA2B,aAAa,IAAI;AAC5D,SAAK,OAAkB,oBAAS,IAAI;AAAA,EACtC;AAAA,EAHmC;AAAA,EALnB,OAAO;AAAA,EACvB,CAAiB,kBAAkB,IAAI;AAAA,EACvB;AAAA,EACA;AAAA,EAOhB,MAAa,QAAQ,MAAyC;AAC5D,oBAAgB,IAAI;AACpB,UAAM,OAAO,IAAI,SAAoB,gBAAK,KAAK,MAAM,IAAI,CAAC;AAC1D,QAAI;AACF,cAAQ,MAAiB,gBAAK,KAAK,IAAI,GAAG,OAAO,IAAI,OAAO;AAAA,IAC9D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,kBAA+C;AAC1D,QAAI;AACF,cAAQ,MAAiB,gBAAK,KAAK,IAAI,GAAG;AAAA,IAC5C,SAAS,OAAO;AACd,UACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,UACf;AACA,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,aAAa,MAA8C;AACtE,oBAAgB,IAAI;AACpB,UAAM,YAAY,IAAI,eAAyB,gBAAK,KAAK,MAAM,IAAI,CAAC;AACpE,QAAI;AACF,cAAQ,MAAiB,gBAAK,UAAU,IAAI,GAAG,YAAY,IACvD,YACA;AAAA,IACN,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,OAAiD;AAC5D,UAAM,UAAU,MAAiB,mBAAQ,KAAK,MAAM;AAAA,MAClD,eAAe;AAAA,IACjB,CAAC;AACD,WAAO,QAAQ;AAAA,MAAI,CAAC,UAClB,MAAM,YAAY,IACd,IAAI,eAAyB,gBAAK,KAAK,MAAM,MAAM,IAAI,CAAC,IACxD,IAAI,SAAoB,gBAAK,KAAK,MAAM,MAAM,IAAI,GAAG,MAAM,IAAI;AAAA,IACrE;AAAA,EACF;AAAA,EAEA,MAAa,WAAW,MAA6B;AACnD,oBAAgB,IAAI;AACpB,UAAiB,iBAAM,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AACrD,UAAM,OAAO,IAAI,SAAoB,gBAAK,KAAK,MAAM,IAAI,CAAC;AAC1D,UAAiB,qBAAU,KAAK,MAAM,IAAI,EAAE,MAAM,KAAK,CAAC;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,gBAAgB,MAAkC;AAC7D,oBAAgB,IAAI;AACpB,UAAiB,iBAAM,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AACrD,UAAM,YAAY,IAAI,eAAyB,gBAAK,KAAK,MAAM,IAAI,CAAC;AACpE,UAAiB,iBAAM,UAAU,IAAI;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,OACX,MACA,SACe;AACf,oBAAgB,IAAI;AACpB,UAAiB,cAAc,gBAAK,KAAK,MAAM,IAAI,GAAG;AAAA,MACpD,OAAO;AAAA,MACP,WAAW,SAAS,cAAc;AAAA,IACpC,CAAC;AAAA,EACH;AACF;AAEA,SAAS,2BACP,MACA,MACQ;AACR,SAAO,QAAQ,IAAI,IAAI,OAAO,KAAgB,mBAAQ,IAAI,GAAG,MAAM,EAAE,SAAS,WAAW,CAAC;AAC5F;AAEA,SAAS,2BACP,UACA,MACoB;AACpB,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,SAAS,WAAW,MAAM,GAAG;AAEhC,WAAkB,sBAAW,QAAQ,IAAI,WAAW;AAAA,EACtD;AACA,MAAI;AACF,WAAO,OAAO,KAAK,SAAS,MAAM,OAAO,MAAM,GAAG,WAAW,EAAE;AAAA,MAC7D;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAgBA,SAAS,gBAAgB,MAAoB;AAC3C,MACE,KAAK,WAAW,KAChB,SAAS,OACT,SAAS,QACE,sBAAW,IAAI,KAC1B,KAAK,SAAS,GAAG,KACjB,KAAK,SAAS,IAAI,GAClB;AACA,UAAM,IAAI,UAAU,4CAA4C,IAAI,EAAE;AAAA,EACxE;AACF;AAEA,IAAM,yBAAN,MAA+D;AAAA,EACtD,YAA6B,UAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAEpC,MAAa,QAAuB;AAClC,UAAM,IAAI,QAAc,CAACC,UAAS,WAAW;AAC3C,WAAK,SAAS,MAAM,CAAC,UAAU;AAC7B,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,QAAQ,KAA4B;AAC/C,UAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AAC3C,WAAK,SAAS,KAAK,KAAK,CAAC,UAAU;AACjC,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,SACX,KACA,SAAuC,CAAC,GACH;AACrC,WAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,WAAK,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,SAA4B;AACtE,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ,IAAI;AAAA,MACnB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,SACX,KACA,SAAuC,CAAC,GACF;AACtC,WAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,WAAK,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,QAAyB;AACnE,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ,GAAG;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,IACX,KACA,SAAuC,CAAC,GACzB;AACf,UAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AAC3C,WAAK,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,UAAU;AAC7C,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,eAAe,iBACb,MACA,SACiC;AACjC,QAAM,SACH,QAAQ,SAAS,aACd,YAAY,gBACZ,YAAY,kBACX,QAAQ,SAAS,YAAY,cAAc,MAChD,YAAY;AACd,SAAO,IAAI,uBAAuB,MAAM,uBAAuB,MAAM,KAAK,CAAC;AAC7E;AAEA,eAAe,uBACb,MACA,OAC2B;AAC3B,QAAM,OAAO,2BAA2B,MAAM,MAAM;AACpD,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,UAAU,+CAA+C;AAAA,EACrE;AACA,SAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,UAAM,WAAW,IAAI,YAAY,SAAS,MAAM,OAAO,CAAC,UAAU;AAChE,UAAI,MAAO,QAAO,KAAK;AAAA,UAClB,CAAAA,SAAQ,QAAQ;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAe,YAAY,MAA4C;AACrE,QAAM,OAAO,2BAA2B,MAAM,MAAM;AACpD,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,UAAU,0CAA0C;AAAA,EAChE;AACA,QAAM,UAAU,MAAM,IAAI,QAAuB,CAACA,UAAS,WAAW;AACpE,IAAM;AAAA,MACJ;AAAA,MACA,EAAE,WAAW,OAAO,aAAa,KAAK;AAAA,MACtC,CAAC,OAAO,WAAW;AACjB,YAAI,SAAS,WAAW;AACtB,iBAAO,SAAS,IAAI,MAAM,iBAAiB,CAAC;AAAA,YACzC,CAAAA,SAAQ,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,UAAU,MAAM,IAAI;AAAA,IACxB,CAACA,UAAS,WAAW;AACnB,YAAM,aAAa,oBAAI,IAAyB;AAChD,YAAM,iBAAiB,CAAC,UAAmB;AACzC,gBAAQ,MAAM;AACd;AAAA,UACE,iBAAiB,QACb,QACA,IAAI,MAAM,mCAAmC;AAAA,QACnD;AAAA,MACF;AACA,YAAM,iBAAiB,MAAM;AAC3B,gBAAQ,IAAI,SAAS,cAAc;AACnC,QAAAA,SAAQ,UAAU;AAAA,MACpB;AACA,cAAQ,GAAG,SAAS,CAAC,UAAuB;AAC1C,YAAI,CAAC,MAAM,SAAS,SAAS,GAAG,GAAG;AACjC,qBAAW,IAAI,MAAM,UAAU,KAAK;AAAA,QACtC;AACA,gBAAQ,UAAU;AAAA,MACpB,CAAC;AACD,cAAQ,KAAK,SAAS,cAAc;AACpC,cAAQ,KAAK,OAAO,cAAc;AAClC,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,SAAS;AACb,SAAO;AAAA,IACL,OAAO,MAAM;AACX,UAAI,CAAC,OAAQ,SAAQ,MAAM;AAC3B,eAAS;AACT,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,IACA,WAAW,OAAO,MAAM,WAAW;AACjC,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,YAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,UAAI,UAAU,OAAW,QAAO;AAChC,YAAM,iBAAiB,SAAS,OAAO,MAAM;AAC7C,aAAO;AAAA,IACT;AAAA,IACA,cAAc,CAAC,SAAS;AACtB,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,aAAO,QAAQ,QAAQ,QAAQ,IAAI,IAAI,GAAG,gBAAgB;AAAA,IAC5D;AAAA,IACA,aAAa,MAAM,QAAQ,QAAQ,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC;AAAA,IACtD,gBAAgB,OAAO,MAAM,QAAQ,WAAW;AAC9C,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,YAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,UAAI,UAAU,OAAW,QAAO;AAChC,aAAO,MAAM,sBAAsB,SAAS,OAAO,QAAQ,MAAM;AAAA,IACnE;AAAA,IACA,WAAW,OAAO,SAAS;AACzB,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,YAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,UAAI,UAAU,OAAW,QAAO;AAChC,aAAO,MAAM,iBAAiB,SAAS,KAAK;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,eAAe,iBACb,SACA,OACA,QACe;AACf,QAAM,SAAS,MAAM,OAAO,WAAW;AACvC,MAAI;AACF,UAAM,SAAS,MAAM,uBAAuB,SAAS,KAAK;AAC1D,UAAM,gBAAgB,QAAQ,MAAM;AACpC,UAAM,OAAO,OAAO;AAAA,EACtB,SAAS,OAAO;AACd,UAAM,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAC1C,UAAM;AAAA,EACR;AACF;AAEA,eAAe,iBACb,SACA,OACqB;AACrB,SAAO,MAAM,kBAAkB,MAAM,uBAAuB,SAAS,KAAK,CAAC;AAC7E;AAEA,eAAe,sBACb,SACA,OACA,QACA,QACqB;AACrB,kBAAgB,QAAQ,QAAQ,MAAM,gBAAgB;AACtD,MAAI,WAAW,EAAG,QAAO,IAAI,WAAW;AACxC,MAAI,MAAM,sBAAsB,GAAG;AACjC,UAAMC,WAAU,MAAM;AAAA,MACpB,MAAM,uBAAuB,SAAS,KAAK;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AACA,WAAO,IAAI;AAAA,MACTA,SAAQ;AAAA,MACRA,SAAQ;AAAA,MACRA,SAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM,uBAAuB,SAAS,OAAO;AAAA,MAC3C,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,KAAK,SAAS;AAAA,MACd,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO,IAAI,WAAW,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,UAAU;AAC9E;AAEA,eAAe,8BACb,OACA,QACA,QACiB;AACjB,QAAM,SAAmB,CAAC;AAC1B,QAAM,MAAM,SAAS;AACrB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,mBAAiB,SAAS,OAAO;AAC/B,UAAM,QAAQ,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK;AAChE,UAAM,WAAW,WAAW,MAAM;AAClC,QAAI,WAAW,UAAU,WAAW,KAAK;AACvC,YAAM,WAAW,MAAM;AAAA,QACrB,KAAK,IAAI,GAAG,SAAS,QAAQ;AAAA,QAC7B,KAAK,IAAI,MAAM,YAAY,MAAM,QAAQ;AAAA,MAC3C;AACA,aAAO,KAAK,QAAQ;AACpB,mBAAa,SAAS;AAAA,IACxB;AACA,eAAW;AACX,QAAI,YAAY,IAAK;AAAA,EACvB;AACA,MAAI,cAAc,QAAQ;AACxB,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,SAAO,OAAO,OAAO,QAAQ,SAAS;AACxC;AAEA,eAAe,uBACb,SACA,OACA,SACgC;AAChC,SAAO,MAAM,IAAI,QAA+B,CAACD,UAAS,WAAW;AACnE,UAAM,WAAW,CAAC,OAAqB,WAAqB;AAC1D,UAAI,SAAS,WAAW,QAAW;AACjC,eAAO,SAAS,IAAI,MAAM,0BAA0B,MAAM,QAAQ,EAAE,CAAC;AAAA,MACvE,OAAO;AACL,QAAAA,SAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,QAAI,YAAY,OAAW,SAAQ,eAAe,OAAO,QAAQ;AAAA,QAC5D,SAAQ,eAAe,OAAO,SAAS,QAAQ;AAAA,EACtD,CAAC;AACH;AAEA,eAAe,aACb,MACA,SACe;AACf,QAAM,UAAU,IAAS,aAAQ;AACjC,QAAM,SAAS,MAAM,KAAK,WAAW;AACrC,QAAM,eAAe,QAAQ;AAC7B,QAAM,aAAa,gBAAgB,cAAc,MAAM;AACvD,QAAM,aAAa,EAAE,WAAW,OAAO,UAAU,MAAM;AACvD,MAAI;AAKJ,MAAI;AACF,eAAW,wBAAwB,OAAO;AAC1C,UAAM,cAAc,kBAAkB,SAAS,UAAU,UAAU;AACnE,UAAM,QAAQ,KAAK,CAAC,aAAa,UAAU,CAAC;AAC5C,QAAI,CAAC,WAAW,UAAU;AACxB,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,YAAQ,IAAI;AACZ,UAAM;AACN,UAAM,OAAO,OAAO;AAAA,EACtB,SAAS,OAAO;AACd,eAAW,YAAY;AACvB,QAAI,CAAC,WAAW,YAAY,aAAa,QAAW;AAClD,gCAA0B,QAAQ;AAAA,IACpC;AACA,QAAI,CAAC,aAAa,WAAW;AAC3B,mBAAa;AAAA,QACX,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,0BAA0B;AAAA,MACvE;AAAA,IACF;AACA,UAAM,WAAW,MAAM,MAAM,MAAS;AACtC,UAAM,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAC1C,UAAM;AAAA,EACR;AACF;AAEA,eAAe,kBACb,SACA,UACA,OACe;AACf,SAAO,CAAC,MAAM,WAAW;AACvB,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,QAAI,MAAM,UAAW;AACrB,QAAI,OAAO,MAAM;AACf,YAAM,WAAW;AACjB;AAAA,IACF;AACA,QAAI,UAAU,OAAO,OAAO;AAC1B,cAAQ;AAAA,QACN,yBAAyB,OAAO,MAAM,IAAI;AAAA,QAC1C,OAAO,MAAM;AAAA,QACb,EAAE,UAAU,MAAM;AAAA,MACpB;AAAA,IACF,WAAW,UAAU,OAAO,OAAO;AACjC,cAAQ,UAAU,OAAO,KAAK,OAAO,MAAM,IAAI,GAAG,OAAO,MAAM,MAAM;AAAA,QACnE,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,OAAO;AACL,cAAQ;AAAA,QACN,0BAA0B,OAAO,KAAK;AAAA,QACtC,OAAO,MAAM;AAAA,QACb,EAAE,UAAU,OAAO,MAAM,OAAO,MAAM,KAAK;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,MAA8B;AAC9D,SAAO,SAAS;AAAA,KACb,mBAAmB;AAClB,YAAM,SAAS,MAAM,KAAK,WAAW;AACrC,UAAI;AACF,iBAAS,SAAS,GAAG,SAAS,OAAO,QAAQ;AAC3C,gBAAM,QAAQ,MAAM,OAAO;AAAA,YACzB;AAAA,YACA,KAAK,IAAI,KAAK,MAAM,OAAO,OAAO,MAAM;AAAA,UAC1C;AACA,oBAAU,MAAM;AAChB,gBAAM;AAAA,QACR;AAAA,MACF,UAAE;AACA,cAAM,OAAO,MAAM;AAAA,MACrB;AAAA,IACF,GAAG;AAAA,EACL;AACF;AAEA,SAAS,2BACP,UACA,MACoB;AACpB,MAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;AAC9D,QAAM,YAAY;AAIlB,SAAO,UAAU,kBAAkB,MAAM,QACvC,OAAO,UAAU,SAAS,WACxB,UAAU,OACV;AACN;AAEA,SAAS,0BACP,OACU;AACV,SAAO,SAAS;AAAA,KACb,mBAAmB;AAClB,eAAS,SAAS,GAAG,SAAS,MAAM,QAAQ;AAC1C,cAAM,QAAQ,MAAM,MAAM;AAAA,UACxB;AAAA,UACA,KAAK,IAAI,KAAK,MAAM,MAAM,OAAO,MAAM;AAAA,QACzC;AACA,kBAAU,MAAM;AAChB,cAAM;AAAA,MACR;AAAA,IACF,GAAG;AAAA,EACL;AACF;AAEA,SAAS,wBACP,SACgE;AAChE,QAAM,gBAAiB,QACrB,OAAO,aACT;AACA,SAAO,kBAAkB,SACpB,QAAwC,OAAO,QAAQ,EAAE,IAC1D,cAAc,KAAK,OAAO;AAChC;AAEA,SAAS,0BACP,UACM;AACN,MAAI,SAAS,WAAW,OAAW;AACnC,MAAI;AACF,SAAK,QAAQ,QAAQ,SAAS,OAAO,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAC/D,QAAQ;AAAA,EAER;AACF;AAEA,eAAe,gBACb,OACA,QACe;AACf,QAAM;AAAA,IACJ;AAAA,IACA,IAAI,SAAS;AAAA,MACX,OAAO,CAAC,OAAe,WAAW,aAAa;AAC7C,aAAK,OAAO,MAAM,KAAK,EAAE;AAAA,UACvB,MAAM,SAAS;AAAA,UACf,CAAC,UACC;AAAA,YACE,iBAAiB,QACb,QACA,IAAI,MAAM,2BAA2B;AAAA,UAC3C;AAAA,QACJ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,kBACb,OACiB;AACjB,SAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,UAAM,SAAmB,CAAC;AAC1B,UAAM,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AACtD,UAAM,KAAK,SAAS,MAAM;AAC1B,UAAM,KAAK,OAAO,MAAMA,SAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,EACxD,CAAC;AACH;AAEO,IAAM,wBAA2C;AAAA,EACtD,cAAc;AAAA,IACZ,QAAQ,MAAS,IAAe,6BAAqB;AAAA,EACvD;AAAA,EACA,UAAU,EAAE,MAAM,iBAAiB;AAAA,EACnC,WAAW;AAAA,IACT,YAAY,gBAAgB,YAAY,GAAG;AAAA,IAC3C,iBAAiB,CAAC,eAAe;AAC/B,YAAM,QAAQ,wBAAwB,KAAK,UAAU;AACrD,UAAI,UAAU,KAAM,QAAO,QAAQ,QAAQ,MAAS;AACpD,UAAI;AACF,oBAAY,KAAK,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC;AACpC,eAAO,QAAQ,QAAQ,IAAI;AAAA,MAC7B,SAAS,OAAO;AACd,YACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,SACf;AACA,iBAAO,QAAQ,QAAQ,KAAK;AAAA,QAC9B;AACA,eAAO,QAAQ,QAAQ,IAAI;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,cAAc,CAAC,aAAa;AAC1B,YAAM,OAAO,2BAA2B,UAAU,WAAW;AAC7D,aAAO,QAAQ;AAAA,QACb,SAAS,SAAY,SAAY,IAAI,cAAc,IAAI;AAAA,MACzD;AAAA,IACF;AAAA,IACA,SAAS,CAAC,aAAa;AACrB,YAAM,OAAO,2BAA2B,UAAU,MAAM;AACxD,aAAO,QAAQ;AAAA,QACb,SAAS,SAAY,SAAY,IAAI,SAAS,IAAI;AAAA,MACpD;AAAA,IACF;AAAA,IACA,wBAAwB,CAAC,cAAc;AACrC,YAAM,OAAO,2BAA2B,WAAW,WAAW;AAC9D,aAAO,QAAQ;AAAA,QACb,SAAS,SAAY,SAAY,IAAI,cAAc,IAAI;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,mBAAmB,CAAC,YAClB,IAAI,YAAY,IAAI,mBAAmB,GAAG,OAAO;AAAA,EACrD;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEA,IAAM,qBAAN,cAAiC,OAAO;AAAA,EAC7B;AAAA,EAEF,YAAY,eAAwB;AACzC,UAAM;AACN,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEO,UAAU,cAAoC;AACnD,UAAM,OAAO,sBAAsB,YAAY;AAC/C,UAAM,WAAsB;AAAA,MAC1B,KAAK,kBAAkB,yBAAyB;AAAA,MAChD;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,MACN,KAAQ,gBAAa,UAAU,MAAM;AAAA,IACvC;AAAA,EACF;AACF;AAeA,SAAS,2BAAmC;AAC1C,QAAM,WAAY,WACf;AACH,MAAI,OAAO,aAAa,YAAY,aAAa,GAAI,QAAO;AAC5D,MAAI,YAAY,YAAY,IAAI;AAChC,SAAO,MAAM;AACX,eAAW,aAAa;AAAA,MACX,gBAAK,WAAW,MAAM;AAAA,MACtB,gBAAK,WAAW,YAAY,QAAQ,MAAM;AAAA,IACvD,GAAG;AACD,UAAI;AACF,YAAO,YAAS,SAAS,EAAE,YAAY,EAAG,QAAO;AAAA,MACnD,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,SAAoB,mBAAQ,SAAS;AAC3C,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,iCAAiC;AACnD,gBAAY;AAAA,EACd;AACF;;;ACr3BA,SAAS,SAAS;;;ACAlB,SAAS,+BAA+B;;;ACAxC,SAAS,qBAAAE,0BAAyB;AAYlC,IAAM,sBAAsB,uBAAO,IAAI,mCAAmC;AAC1E,IAAM,iBAAiB,yBAAyB;AAEhD,SAAS,2BAA0E;AACjF,QAAM,gBAAgB;AACtB,QAAM,WAAW,cAAc,mBAAmB;AAClD,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,IAAIA,mBAA8C;AAClE,SAAO,eAAe,eAAe,qBAAqB;AAAA,IACxD,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AACD,SAAO;AACT;AASO,SAAS,gCAA4D;AAC1E,SACE,eAAe,SAAS,KAAK;AAAA,IAC3B,KAAK,QAAQ,IAAI;AAAA,IACjB,KAAK,QAAQ;AAAA,IACb,WAAW;AAAA,EACb;AAEJ;AAEO,SAAS,0BAA8C;AAC5D,SAAO,8BAA8B,EAAE;AACzC;;;ADhDA,SAAS,QAAAC,aAAY;AACrB,SAAS,WAAAC,gBAAe;AAexB,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQhC,eAAsB,uBACpB,SAC4B;AAC5B,SAAO,MAAM,wBAAwB,OAAO,aAAa;AACvD,WAAO,MAAM,iCAAiC,UAAU,OAAO;AAAA,EACjE,CAAC;AACH;AA0GO,SAAS,2BACd,SACA,OACmB;AACnB,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,yBAAyB,KAAK;AAAA,IACvC,KAAK;AACH,aAAO,kBAAkB,KAAK;AAAA,IAChC,KAAK;AACH,aAAO,yBAAyB,KAAK;AAAA,IACvC,KAAK;AACH,aAAO,wBAAwB,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,wBAAwB,KAAK;AAAA,EACxC;AACF;AAEA,eAAe,wBACb,WACY;AACZ,QAAM,WAAW,MAAM;AAAA,IACrB,IAAI;AAAA,MACFC;AAAA,QACE,wBAAwB,KAAKA,MAAKC,SAAQ,GAAG,YAAY;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM,UAAU,QAAQ;AAAA,EACjC,UAAE;AACA,UAAM,SAAS,MAAM;AAAA,EACvB;AACF;AAEA,eAAe,iCACb,UACA,SAC4B;AAC5B,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B;AAAA,IACA,CAAC,OAAO;AAAA,IACR,CAAC,QAAQ,OAAO,IAAI,UAAU;AAAA,EAChC;AAEA,SAAO,UAAU,SAAY,CAAC,IAAI,iBAAiB,SAAS,KAAK;AACnE;AAmBA,SAAS,iBACP,SACA,OACmB;AACnB,MAAI;AAEJ,MAAI;AACF,aAAS,KAAK,MAAM,KAAK;AAAA,EAC3B,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,iCAAiC,OAAO,KAAK,YAAY,KAAK,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAC1E,UAAM,IAAI;AAAA,MACR,gCAAgC,OAAO;AAAA,IACzC;AAAA,EACF;AAEA,SAAO,2BAA2B,SAAS,MAA2B;AACxE;AAEA,SAAS,yBAAyB,OAA6C;AAC7E,QAAM,cAAc,oBAAI,IAAI;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,mBAAmB,oBAAI,IAAI,CAAC,UAAU,mBAAmB,CAAC;AAChE,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,kCAAkC,GAAG,EAAE;AAAA,IACzD;AACA,QAAI,QAAQ,cAAc;AACxB,YAAM,SACJ,OAAO,UAAU,WACb,QACA,OAAO,UAAU,WACf,OAAO,KAAK,IACZ;AAER,UAAI,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GAAG;AAC5C,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE;AACA,WAAK,GAAG,IAAI;AACZ;AAAA,IACF;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,cAAc,GAAG,8BAA8B;AAAA,IACjE;AACA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,QAAQ,cAAc,CAAC,iBAAiB,IAAI,UAAU,GAAG;AAC3D,YAAM,IAAI,MAAM,gCAAgC,UAAU,EAAE;AAAA,IAC9D;AAEA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAA6C;AACtE,QAAM,cAAc,oBAAI,IAAI;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,mBAAmB,oBAAI,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,2BAA2B,GAAG,EAAE;AAAA,IAClD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,OAAO,GAAG,8BAA8B;AAAA,IAC1D;AACA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,QAAQ,cAAc,CAAC,iBAAiB,IAAI,UAAU,GAAG;AAC3D,YAAM,IAAI,MAAM,yBAAyB,UAAU,EAAE;AAAA,IACvD;AAEA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,yBAAyB,OAA6C;AAC7E,QAAM,cAAc,oBAAI,IAAI,CAAC,OAAO,SAAS,CAAC;AAC9C,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,kCAAkC,GAAG,EAAE;AAAA,IACzD;AACA,UAAM,SACJ,OAAO,UAAU,WACb,QACA,OAAO,UAAU,WACf,OAAO,KAAK,IACZ;AAER,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GAAG;AAC5C,YAAM,IAAI,MAAM,cAAc,GAAG,8BAA8B;AAAA,IACjE;AACA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,OAA6C;AAC5E,QAAM,cAAc,oBAAI,IAAI,CAAC,YAAY,YAAY,OAAO,CAAC;AAC7D,QAAM,mBAAmB,oBAAI,IAAI,CAAC,OAAO,OAAO,CAAC;AACjD,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,iCAAiC,GAAG,EAAE;AAAA,IACxD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,aAAa,GAAG,8BAA8B;AAAA,IAChE;AACA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,QAAQ,cAAc,CAAC,iBAAiB,IAAI,UAAU,GAAG;AAC3D,YAAM,IAAI,MAAM,+BAA+B,UAAU,EAAE;AAAA,IAC7D;AAEA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,OAA6C;AAC5E,SAAO,uBAAuB,aAAa,KAAK;AAClD;AAEA,SAAS,uBACP,SACA,OACmB;AACnB,QAAM,cAAc,oBAAI,IAAI,CAAC,YAAY,OAAO,CAAC;AACjD,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,WAAW,OAAO,gBAAgB,GAAG,EAAE;AAAA,IACzD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,GAAG,OAAO,IAAI,GAAG,8BAA8B;AAAA,IACjE;AACA,SAAK,GAAG,IAAI,MAAM,KAAK;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;;AD3XA,IAAM,6BAA6B;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,0BAA0B,EAAE,KAAK,0BAA0B;AACjE,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACnC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACpC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACpC,oBAAoB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC/C,KAAK,EACF,OAAO;AAAA,IACN,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACnC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACpC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACpC,oBAAoB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IAClC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACjC,UAAU,wBAAwB,SAAS;AAAA,EAC7C,CAAC,EACA,SAAS;AAAA,EACZ,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAClC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACjC,UAAU,wBAAwB,SAAS;AAC7C,CAAC;AA0CD,eAAsB,2BAA2B,SAEb;AAClC,QAAM,CAAC,WAAW,UAAU,YAAY,WAAW,SAAS,IAC1D,MAAM,QAAQ,IAAI;AAAA,IAChB,uBAAuB,YAAY;AAAA,IACnC,uBAAuB,KAAK;AAAA,IAC5B,uBAAuB,YAAY;AAAA,IACnC,uBAAuB,WAAW;AAAA,IAClC,uBAAuB,WAAW;AAAA,EACpC,CAAC;AACH,QAAM,kBACJ,SAAS,YAAY,SACjB,SACA,qBAAqB,QAAQ,OAAO;AAC1C,QAAM,MAAM,gBAAgB;AAAA,IAC1B,QAAQ,aAAa,iBAAiB,QAAQ,WAAW,SAAS,MAAM,CAAC;AAAA,IACzE,SAAS;AAAA,MACP,iBAAiB;AAAA,MACjB,WAAW,SAAS,OAAO;AAAA,IAC7B;AAAA,IACA,OAAO,aAAa,iBAAiB,OAAO,WAAW,SAAS,KAAK,CAAC;AAAA,IACtE,MAAM,aAAa,iBAAiB,MAAM,WAAW,SAAS,IAAI,CAAC;AAAA,IACnE,UAAU;AAAA,MACR,iBAAiB;AAAA,MACjB,aAAa,SAAS,QAAQ;AAAA,IAChC;AAAA,EACF,CAAC;AACD,QAAM,oBAAoB,oBAAoB,WAAW,OAAO;AAChE,QAAM,gBAAgB,oBAAoB,WAAW,GAAG;AACxD,QAAM,YAAY,8BAA8B,EAAE;AAClD,QAAM,kBAAkB,uBAAuB,WAAW,SAAS;AACnE,QAAM,kBAAkB,sBAAsB,WAAW,SAAS;AAClE,QAAM,kBAAkB,sBAAsB,SAAS;AAEvD,SAAO;AAAA,IACL,GAAI,kBAAkB,UAAa,sBAAsB,SACrD,CAAC,IACD;AAAA,MACE,YAAY;AAAA,QACV,GAAI,kBAAkB,SAAY,CAAC,IAAI,EAAE,KAAK,cAAc;AAAA,QAC5D,GAAI,sBAAsB,SACtB,CAAC,IACD,EAAE,SAAS,kBAAkB;AAAA,MACnC;AAAA,IACF;AAAA,IACJ,GAAI,oBAAoB,SAAY,CAAC,IAAI,EAAE,WAAW,gBAAgB;AAAA,IACtE,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,IAAI;AAAA,IACnC,GAAI,oBAAoB,SAAY,CAAC,IAAI,EAAE,WAAW,gBAAgB;AAAA,IACtE,GAAI,oBAAoB,SAAY,CAAC,IAAI,EAAE,WAAW,gBAAgB;AAAA,EACxE;AACF;AAEA,SAAS,sBACP,OACA,WACiD;AACjD,QAAM,WAAW,WAAW,OAAO,QAAQ;AAC3C,QAAM,QAAQ,WAAW,OAAO,KAAK;AAErC,MAAI,aAAa,UAAa,UAAU,OAAW,QAAO;AAC1D,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,UACE,YAAY,8BAA8B,gBAAgB,SAAS;AAAA,IACrE;AAAA,EACF;AACF;AAEA,SAAS,sBACP,OACiD;AACjD,QAAM,QAAQ,SAAS,CAAC;AACxB,QAAM,WAAW,sBAAsB,MAAM,QAAQ;AACrD,QAAM,SAAS,WAAW,MAAM,MAAM;AACtC,QAAM,UAAU,WAAW,MAAM,OAAO;AACxC,QAAM,aACJ,OAAO,MAAM,eAAe,YAC5B,OAAO,UAAU,MAAM,UAAU,KACjC,MAAM,aAAa,IACf,MAAM,aACN;AACN,QAAM,QAAQ,WAAW,MAAM,KAAK;AACpC,QAAM,OAAO,WAAW,MAAM,IAAI;AAElC,MACE,aAAa,UACb,UAAU,UACT,aAAa,uBAAuB,YAAY,UAChD,aAAa,YAAY,YAAY,QACtC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACzC,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,QAAQ;AAAA,IAC3C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACvC,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,KAAK;AAAA,IACrC,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,EAC/C;AACF;AAEA,SAAS,qBAAqB,OAA4C;AACxE,QAAM,aAAa,gBAAgB,KAAK;AAExC,MAAI,eAAe,QAAW;AAC5B,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAEA,MAAI;AAEJ,MAAI;AACF,iBAAa,KAAK,MAAM,UAAU;AAAA,EACpC,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,uBAAuBC,aAAY,KAAK,CAAC,EAAE;AAAA,EAC7D;AAEA,QAAM,SAAS,sBAAsB,UAAU,UAAU;AAEzD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI;AAAA,MACR,yBAAyB,OAAO,MAAM,OACnC,IAAI,CAAC,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,KAAK,QAAQ,KAAK,MAAM,OAAO,EAAE,EACtE,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AAEA,QAAM,QAAQ,OAAO,KAAK,OAAO,OAAO;AACxC,QAAM,WAAW,MAAM,YAAY,oBAAoB,KAAK;AAC5D,QAAM,UAAU,qBAAqB,KAAK;AAC1C,QAAM,SAAS,gBAAgB;AAAA,IAC7B,QAAQ,MAAM;AAAA,IACd;AAAA,IACA,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,IACZ;AAAA,EACF,CAAC;AAED,MAAI,WAAW,QAAW;AACxB,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAKK;AAChC,MACE,MAAM,aAAa,WAClB,MAAM,YAAY,UACjB,MAAM,YAAY,UAClB,MAAM,uBAAuB,SAC/B;AACA,WAAO;AAAA,EACT;AAEA,SAAO,MAAM;AACf;AAEA,SAAS,mCAAmC,OAErB;AACrB,MAAI,MAAM,uBAAuB,QAAW;AAC1C,WAAO;AAAA,EACT;AAEA,QAAM,SAAS;AAEf,MAAI,CAAC,MAAM,mBAAmB,SAAS,MAAM,GAAG;AAC9C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,mBAAmB,MAAM,GAAG,CAAC,OAAO,MAAM;AACzD;AAEA,SAAS,qBAAqB,OAIP;AACrB,MAAI,MAAM,YAAY,QAAW;AAC/B,WAAO,MAAM;AAAA,EACf;AACA,MAAI,MAAM,YAAY,QAAW;AAC/B,WAAO,MAAM;AAAA,EACf;AAEA,SAAO,mCAAmC,KAAK;AACjD;AAEA,SAAS,gBAAgB,OAMS;AAChC,MACE,MAAM,WAAW,UACjB,MAAM,YAAY,UAClB,MAAM,UAAU,UAChB,MAAM,SAAS,UACf,MAAM,aAAa,QACnB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;AAAA,IAC7D,GAAI,MAAM,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;AAAA,IAChE,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,IAC1D,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AAAA,IACvD,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;AAAA,EACrE;AACF;AAEA,SAAS,aAAa,OAA+C;AACnE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,wBAAwB,UAAU,KAAK;AAEtD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;AAEO,SAAS,uBACd,OACA,YAA0C,8BAA8B,EACrE,WAC8C;AACjD,QAAM,WAAW,sBAAsB,MAAM,QAAQ;AACrD,QAAM,WAAW,WAAW,MAAM,QAAQ;AAC1C,QAAM,QAAQ,WAAW,MAAM,KAAK;AAEpC,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,MAAO,QAAO,EAAE,SAAS;AAC1C,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,YAAY,8BAA8B,aAAa,SAAS;AAAA,IAC1E;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,8BACd,OACA,YAA0C,8BAA8B,EACrE,WACK;AACR,QAAM,SACJ,cAAc,gBACV,oCACA;AACN,SAAO,GAAG,MAAM,OAAO,KAAK;AAC9B;AAEA,SAAS,sBAAsB,OAA6C;AAC1E,SAAO,UAAU,SAAS,UAAU,UAAU,QAAQ;AACxD;AAEA,SAAS,sBACP,OAC4C;AAC5C,SAAO,UAAU,YAAY,UAAU,sBACnC,QACA;AACN;AAEA,SAAS,WAAW,OAAoC;AACtD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,SAAO,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,QAAQ,IACnE,QACA;AACN;AAEA,SAAS,aACP,OACA,QACe;AACf,SAAO,SAAS;AAClB;AAEA,SAAS,gBAAgB,OAA+C;AACtE,QAAM,aAAa,OAAO,KAAK;AAE/B,SAAO,eAAe,UAAa,eAAe,KAAK,SAAY;AACrE;AAEA,SAASA,aAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;;AGpYA,SAAS,WAAAC,gBAAe;AACxB,SAAS,cAAAC,aAAY,WAAAC,gBAAe;AAI7B,SAAS,4BAA4B,MAAsB;AAChE,QAAM,UAAU,8BAA8B;AAC9C,QAAM,kBAAkB,QAAQ,IAAI,MAAM,KAAK;AAC/C,QAAM,OACJ,oBAAoB,UAAa,oBAAoB,KACjDC,SAAQ,IACR;AACN,MAAI,SAAS,IAAK,QAAO;AACzB,MAAI,KAAK,WAAW,IAAI,EAAG,QAAOC,SAAQ,MAAM,KAAK,MAAM,CAAC,CAAC;AAC7D,SAAOC,YAAW,IAAI,IAAI,OAAOD,SAAQ,QAAQ,KAAK,IAAI;AAC5D;;;AN8BO,IAAM,6BAAN,MAAiC;AAAA,EAC7B;AAAA,EAEF,YAAY,SAA8B;AAC/C,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAa,QACX,SACoC;AACpC,WAAO,MAAM,KAAK,SAAS,IAAI,YAAY,MAAM,KAAK,SAAS,OAAO,CAAC;AAAA,EACzE;AAAA,EAEA,MAAM,SACJ,SACoC;AACpC,UAAM,cAAc,QAAQ,eAAe;AAC3C,QAAI,QAAQ,gBAAgB,UAAa,QAAQ,OAAO,WAAW,QAAQ;AACzE,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,QAAI,QAAQ,gBAAgB,UAAa,QAAQ,MAAM,WAAW,QAAQ;AACxE,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBAAiB,QAAQ,MAAM,WAAW;AAChD,UAAM,cACJ,kBAAkB,gBAAgB,aAAa,gBAAgB;AACjE,UAAM,SAAS,MAAM,2BAA2B;AAAA,MAC9C,GAAI,QAAQ,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;AAAA,IACtE,CAAC;AACD,UAAM,MAAM,IAAI,UAAU;AAAA,MACxB,GAAI,QAAQ,YAAY,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,MACpD,GAAI,cAAc,EAAE,KAAK,yBAAyB,MAAM,EAAE,IAAI,CAAC;AAAA,IACjE,CAAC;AACD,UAAM,oBAAoB,MAAM;AAAA,MAC9B,QAAQ;AAAA,MACR;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,YAA6C;AAChE,YAAM,aAAa,SAAS,QAAQ,OAAO,MAAM,QAAQ,OAAO,MAAM;AAAA,IACxE;AAEA,QAAI,QAAQ,MAAM,WAAW,QAAQ;AACnC,UAAI,EAAE,UAAU,QAAQ,QAAQ;AAC9B,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACpD;AACA,YAAM,IAAI;AAAA,QACR,IAAI,SAAS,4BAA4B,QAAQ,MAAM,IAAI,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,IACF,WAAW,YAAY,QAAQ,OAAO;AACpC,YAAM,IAAI;AAAA,QACR;AAAA,UACE,GAAI,sBAAsB,SAAY,CAAC,IAAI,EAAE,kBAAkB;AAAA,UAC/D,GAAI,QAAQ,eAAe,SACvB,CAAC,IACD,EAAE,YAAY,QAAQ,WAAW;AAAA,UACrC,cAAc,QAAQ,MAAM;AAAA,UAC5B,QAAQ,QAAQ,MAAM;AAAA,UACtB,IAAK,QAAQ,UAAU,OAAO,YAAY,SACtC,CAAC,IACD,EAAE,kBAAkB,QAAQ,UAAU,OAAO,OAAO;AAAA,UACxD;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,gBAAgB;AAAA,QACpB,GAAI,sBAAsB,SAAY,CAAC,IAAI,EAAE,kBAAkB;AAAA,QAC/D,MAAM,IAAI,SAAS,4BAA4B,QAAQ,MAAM,IAAI,CAAC;AAAA,QAClE,GAAI,QAAQ,eAAe,SACvB,CAAC,IACD,EAAE,YAAY,QAAQ,WAAW;AAAA,QACrC,IAAK,QAAQ,UAAU,OAAO,YAAY,SACtC,CAAC,IACD,EAAE,kBAAkB,QAAQ,UAAU,OAAO,OAAO;AAAA,QACxD;AAAA,MACF;AACA,UAAI,QAAQ,MAAM,WAAW,QAAQ;AACnC,cAAM,IAAI,kBAAkB,eAAe,KAAK;AAAA,MAClD,WAAW,QAAQ,MAAM,WAAW,YAAY;AAC9C,cAAM,IAAI,sBAAsB,eAAe,KAAK;AAAA,MACtD,OAAO;AACL,cAAM,IAAI,iBAAiB,eAAe,KAAK;AAAA,MACjD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,aAAa,QAAQ,MAAM;AAAA,MAC3B,cAAc,QAAQ,OAAO;AAAA,MAC7B,YAAY,QAAQ,OAAO;AAAA,IAC7B;AAAA,EACF;AACF;AAEA,eAAe,uBACb,MACA,UACoC;AACpC,QAAM,aAAa,MAAM,KAAK;AAC9B,MAAI,CAAC,YAAY,eAAe,UAAa,eAAe;AAC1D,WAAO;AACT,QAAM,WAAW,4BAA4B,UAAU;AACvD,QAAME,IAAG,UAAU,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AACnD,SAAO,IAAI,cAAc,QAAQ;AACnC;AAEA,eAAe,aACb,SACA,MACA,QACe;AACf,QAAM,OAAO,IAAI,SAAS,4BAA4B,IAAI,CAAC;AAC3D,MAAI,WAAW,OAAQ,OAAM,QAAQ,WAAW,IAAI;AAAA,WAC3C,WAAW,OAAQ,OAAM,QAAQ,OAAO,IAAI;AAAA,MAChD,OAAM,QAAQ,WAAW,IAAI;AACpC;","names":["rm","process","resolve","content","AsyncLocalStorage","join","homedir","join","homedir","formatError","homedir","isAbsolute","resolve","homedir","resolve","isAbsolute","rm"]}
@@ -0,0 +1,410 @@
1
+ # Your Role
2
+
3
+ You are a rigorous teacher reviewing a student's assignment. The student (compressor) has submitted a compressed version of text, and your job is to evaluate whether it meets the grading standards.
4
+
5
+ ## Your Goal
6
+
7
+ Help the student produce a higher-quality compressed text by providing clear, actionable feedback. Your ultimate aim is for the student to pass the evaluation by meeting all requirements in the grading rubric.
8
+
9
+ ## Your Professional Standards
10
+
11
+ 1. **Objective**: Base all judgments strictly on the grading rubric below. Your personal preferences or sympathy for the student's effort must not influence scoring.
12
+
13
+ 2. **Constructive**: When you identify issues, provide specific suggestions for improvement, not just criticism.
14
+
15
+ 3. **Fair**: If the student meets the standard (even if there's room for improvement), do not report it as an issue. Pass what deserves to pass.
16
+
17
+ 4. **Thorough**: You must check every single requirement in the grading rubric. Never skip any item, regardless of how many issues you've already found.
18
+
19
+ 5. **Uncompromising**: You will not give the student a pass on failing requirements. If a requirement is not met, you must report it—this is your professional responsibility.
20
+
21
+ ## Your Evaluation Context
22
+
23
+ You may be reviewing the student's second, third, or later submission. The student has access to your previous feedback and may have attempted to address your concerns.
24
+
25
+ When evaluating:
26
+ - Focus on the current submission in front of you
27
+ - Check ALL requirements systematically (never assume "I already checked this before")
28
+ - For each unmet requirement, consider: Has the student attempted to fix this? This context will help you craft better suggestions
29
+
30
+ {% if user_language %}
31
+
32
+ ## Cross-Language Review
33
+
34
+ **Important:** The compressed text may be in **{{ user_language }}** (translated for user), while the source text (in the rubric below) is in its original language.
35
+
36
+ You must perform **cross-language semantic verification**:
37
+
38
+ 1. **Focus on SEMANTIC EQUIVALENCE across languages:**
39
+ - Verify if the MEANING is preserved, not exact wording
40
+ - The same concept can be expressed differently in different languages
41
+ - Cultural adaptations are acceptable if meaning is maintained
42
+
43
+ 2. **Terminology and proper nouns:**
44
+ - Check if they accurately represent the original concepts
45
+ - Transliterations or translations should preserve the essence
46
+ - Technical terms should maintain accuracy
47
+
48
+ 3. **Literary expressions (if marked as [LITERARY] in rubric):**
49
+ - Metaphors may use different imagery in {{ user_language }} while preserving symbolic meaning
50
+ - Prophetic/dramatic tone should be maintained even with different phrasing
51
+ - The literary FUNCTION matters more than literal translation
52
+
53
+ 4. **What counts as "present" in cross-language review:**
54
+ - ✅ Same meaning expressed with different language structure
55
+ - ✅ Cultural equivalent metaphors (e.g., "phoenix rebirth" → similar rebirth imagery in target language)
56
+ - ✅ Concepts accurately conveyed even if terminology differs
57
+ - ❌ Key concepts completely missing
58
+ - ❌ Meaning significantly distorted or changed
59
+
60
+ **Your evaluation should be as rigorous as same-language review.** Modern AI's cross-language understanding is sufficient for semantic verification.
61
+
62
+ {% else %}
63
+
64
+ ## Same-Language Review
65
+
66
+ The compressed text is in the **SAME LANGUAGE(S) as the source text** (no translation requested). Verify semantic preservation directly.
67
+
68
+ **What counts as "present":**
69
+ - ✅ Core meaning conveyed with different wording
70
+ - ✅ Information reordered but semantically equivalent
71
+ - ✅ Paraphrasing that preserves key facts
72
+ - ❌ Key facts completely absent
73
+ - ❌ Meaning distorted or changed
74
+
75
+ {% endif %}
76
+
77
+ ---
78
+
79
+ # Grading Rubric
80
+
81
+ The compressed text must preserve information according to a THREE-TIER priority system. Below is the grading standard you will use.
82
+
83
+ ## Verification Strategy for This Clue
84
+
85
+ {{ thread_info }}
86
+
87
+ ---
88
+
89
+ ## Understanding the Three-Tier Grading System
90
+
91
+ The rubric above organizes requirements into three tiers by priority:
92
+
93
+ | Tier | Priority | Pass Condition | If Completely Missing | If Incomplete |
94
+ |------|----------|---------------|----------------------|---------------|
95
+ | **TIER 1** | high | All core facts + ≥1 minor detail | CRITICAL | MAJOR |
96
+ | **TIER 2** | medium | ≥1 key point present | MAJOR | MINOR |
97
+ | **TIER 3** | low | Any form of mention | MINOR | MINOR (acceptable) |
98
+
99
+ **Priority level mapping:**
100
+ - **high**: retention = verbatim/detailed, OR importance = critical
101
+ - **medium**: retention = focused, OR importance = important
102
+ - **low**: retention = relevant, OR importance = helpful
103
+ - When a chunk has both attributes, the higher priority applies
104
+
105
+ ---
106
+
107
+ ## TIER 1: High-Priority Requirements
108
+
109
+ **Pass condition:** The compressed text must include ALL core facts AND at least ONE minor detail.
110
+
111
+ **How to check:**
112
+ 1. Locate the "Core facts (ALL required)" list in the rubric above
113
+ 2. Verify each core fact is present in the compressed text (semantic equivalence accepted—see below)
114
+ 3. Locate the "Minor details (at least ONE required)" list
115
+ 4. Verify at least one minor detail is present
116
+
117
+ **Grading outcomes:**
118
+ - Chunk not mentioned at all → **CRITICAL**
119
+ - Missing any core fact → **MAJOR**
120
+ - All core facts present but NO minor details → **MAJOR**
121
+ - All core facts + ≥1 minor detail, but some other minor details incomplete → **MINOR** (acceptable, do not report)
122
+ - All core facts + ≥1 minor detail present → **Pass** ✅
123
+
124
+ **What counts as "present":**
125
+ - The core meaning is conveyed, even with different wording
126
+ - Key terms are preserved or have clear semantic equivalents
127
+ - Sentence structure and phrasing can differ
128
+
129
+ **What does NOT count:**
130
+ - Core fact completely absent
131
+ - Core meaning distorted or changed
132
+ - All minor details omitted (at least one is required)
133
+
134
+ **Note:** For TIER 1 chunks, the rubric may provide original source text in `<source>` tags for reference.
135
+
136
+ ---
137
+
138
+ ## TIER 2: Medium-Priority Requirements
139
+
140
+ **Pass condition:** The compressed text must mention AT LEAST ONE key point from the provided list.
141
+
142
+ **How to check:**
143
+ 1. Locate the "Key points (at least ONE required)" list in the rubric above
144
+ 2. Verify if ANY one of them appears in the compressed text
145
+ 3. Full semantic equivalence is acceptable—paraphrasing, reordering, and consolidation are all fine
146
+
147
+ **Grading outcomes:**
148
+ - NONE of the key points mentioned → **MAJOR**
149
+ - Any one or more key points mentioned but incomplete → **MINOR** (acceptable, do not report)
150
+ - Any one or more key points fully mentioned → **Pass** ✅
151
+
152
+ **What counts as "mentioned":**
153
+ - Any form of paraphrasing that preserves the core meaning
154
+ - Different sentence structure or word choice
155
+ - Multiple key points combined into one statement
156
+ - Simplified or summarized version
157
+
158
+ **What does NOT count:**
159
+ - ALL key points completely absent
160
+ - Meaning severely distorted for the mentioned point
161
+
162
+ ---
163
+
164
+ ## TIER 3: Low-Priority Requirements
165
+
166
+ **Pass condition:** The topic/concept must be mentioned in ANY form.
167
+
168
+ **How to check:**
169
+ 1. Locate the "Existence check" description in the rubric above
170
+ 2. Verify if the topic/concept appears anywhere in the compressed text
171
+ 3. Very flexible interpretation—even a brief reference counts
172
+
173
+ **Grading outcomes:**
174
+ - Not mentioned at all → **MINOR**
175
+ - Mentioned in any form (even if incomplete) → **MINOR** (acceptable, do not report)
176
+ - Mentioned sufficiently → **Pass** ✅
177
+
178
+ **What counts as "mentioned":**
179
+
180
+ The concept itself must be present, either directly or through clear semantic connection.
181
+
182
+ ✅ **Acceptable forms:**
183
+ - Direct mention: A word or phrase directly naming the concept
184
+ - Indirect reference: The concept is clearly implied through semantically connected information
185
+ - Example: "组织需要资金支持" → implies "面临融资困境" (funding difficulty concept is present)
186
+ - Example: "主角从员工变成了老板" → implies "角色X的身份转变" (if X is the protagonist)
187
+ - Example: "技术团队缺乏关键资源" → implies "技术瓶颈问题" (bottleneck concept is present)
188
+
189
+ **What does NOT count:**
190
+
191
+ ❌ **Not acceptable:**
192
+ - Being in the same general topic area without addressing the specific concept
193
+ - Example: "公司发展" ≠ "公司面临的具体融资问题" (too vague, concept absent)
194
+ - Example: "角色A的失败" ≠ "角色B的困境" (different subjects)
195
+ - Example: "战役X" ≠ "社会制度Y的分析" (same timeframe, different concepts)
196
+ - Example: "主角战胜对手" ≠ "社会结构的必然性分析" (related setting, but wrong analytical level)
197
+
198
+ **Clear test for TIER 3:**
199
+ Ask yourself: "If I remove the specific name/example, is the CORE CONCEPT still present in substance?"
200
+ - If YES (concept is there, just without the specific label) → Acceptable
201
+ - If NO (only tangentially related topics from the same setting) → Not acceptable, report as MINOR
202
+
203
+ ---
204
+
205
+ ## Semantic Equivalence Principle
206
+
207
+ **Important:** You are verifying MEANING, not exact wording. The same information can be expressed many different ways.
208
+
209
+ **Examples of acceptable variations (do NOT report these as issues):**
210
+ - "has his own land" = "possesses land" = "owns land"
211
+ - "can get married" = "is able to marry" = "has the right to marry"
212
+ - "poor family couldn't afford tuition" = "family was poor, couldn't study" = "no money for school"
213
+ - "assigned to the poorest areas" = "deliberately sent to impoverished regions"
214
+
215
+ **Verification process:**
216
+ 1. Read a requirement from the rubric
217
+ 2. Search the compressed text for the CORE MEANING (not exact words)
218
+ 3. Ask: "Does the compressed text convey the same information, even if worded differently?"
219
+ 4. If YES (meaning present) → Do not report
220
+ 5. If NO (meaning absent or severely distorted) → Report as issue
221
+
222
+ **When to report an issue:**
223
+ - The specific fact/concept is completely absent
224
+ - The meaning is severely changed (opposite or major distortion)
225
+ - Critical information is wrong or missing
226
+
227
+ **When NOT to report:**
228
+ - Same fact with different wording
229
+ - Information reordered
230
+ - Summary/consolidation that preserves meaning
231
+ - Minor stylistic changes
232
+
233
+ ---
234
+
235
+ ## Special Rules for Literary/Metaphorical Content
236
+
237
+ Some chunks contain literary, metaphorical, or symbolic language that serves a narrative purpose. For these chunks, factual substitutions alone are NOT sufficient.
238
+
239
+ **How to identify literary content in the rubric:**
240
+ - Core facts or key points include quoted metaphorical expressions (e.g., "命运准备的终结者", "压垮帝国的稻草")
241
+ - Language describing tone, foreshadowing, or symbolic meaning
242
+ - Prophetic or dramatic expressions (e.g., "历史在等待", "凤凰涅槃")
243
+ - Chunk labels marked with [LITERARY] tag
244
+
245
+ **Grading standard for literary content:**
246
+
247
+ When a requirement includes literary/metaphorical language:
248
+ 1. The literary expression itself (or a clear literary equivalent) must be preserved
249
+ 2. Verify the TONE and STYLE, not just underlying facts
250
+ 3. Check if foreshadowing, dramatic tension, or symbolic meaning is maintained
251
+
252
+ **Examples of unacceptable substitutions:**
253
+
254
+ ❌ Requirement: "命运为王朝准备了终结者" → Student wrote: "某年某人出生"
255
+ - Problem: Loses prophetic tone and metaphorical framing
256
+
257
+ ❌ Requirement: "成为压垮帝国的最后一根稻草" → Student wrote: "引发了民众起义"
258
+ - Problem: Loses metaphorical judgment and symbolic meaning
259
+
260
+ ❌ Requirement: "如同凤凰涅槃,在烈火中重生" → Student wrote: "经历了艰难困苦"
261
+ - Problem: Loses vivid metaphor and dramatic imagery
262
+
263
+ **Examples of acceptable literary equivalents:**
264
+
265
+ ✅ Requirement: "命运为王朝准备了终结者" → Student wrote: "天意选中此人作为王朝的掘墓人"
266
+ - Preserves prophetic tone through alternative metaphor
267
+
268
+ ✅ Requirement: "最后一根稻草" → Student wrote: "压垮骆驼的致命一击"
269
+ - Preserves judgmental/conclusive meaning through different metaphor
270
+
271
+ **Note:** Literary language can be simplified, but the literary NATURE must remain. Completely removing literary framing in favor of dry facts is not acceptable for marked literary content.
272
+
273
+ ---
274
+
275
+ ## Narrative Coherence (Optional)
276
+
277
+ **This section only appears if the rubric includes "NARRATIVE COHERENCE" requirements.**
278
+
279
+ If present, these requirements check whether the compressed text maintains logical flow between chunks.
280
+
281
+ **How to check:**
282
+ 1. Read the compressed text as a reader (not just a fact-checker)
283
+ 2. Review each identified coherence issue in the rubric
284
+ 3. Ask: "Would a reader be confused by this transition or logical jump?"
285
+ 4. Only report if the issue genuinely disrupts understanding
286
+
287
+ **Grading outcomes:**
288
+ - Narrative flow severely disrupted (reader cannot understand why topic changed) → **MAJOR** (coherence)
289
+ - Transition awkward but meaning clear (reader can figure it out with effort) → **MINOR** (coherence)
290
+ - Bridging information present (even implicitly) → **Pass** ✅
291
+
292
+ **What to flag:**
293
+ - After discussing divination, suddenly describes government policy without explaining relevance
294
+ - Character makes major decision but triggering event is missing
295
+ - Background information appears without context for why it matters now
296
+
297
+ **What NOT to flag:**
298
+ - Simplified transitions (e.g., "而且更重要的是..." → "此时") that remain clear
299
+ - Condensed causal chains that readers can still follow
300
+ - Implied connections readers can reasonably infer
301
+
302
+ ---
303
+
304
+ # Your Evaluation Process
305
+
306
+ ## Step 1: Systematic Verification
307
+
308
+ Go through EVERY requirement in the grading rubric above (TIER 1, TIER 2, TIER 3, and NARRATIVE COHERENCE if present).
309
+
310
+ For each requirement:
311
+ 1. Check if it is satisfied in the current compressed text
312
+ 2. If NOT satisfied → Identify what is missing
313
+ 3. If satisfied → Move to next requirement (do not report)
314
+
315
+ **Critical rule:** Check ALL requirements. Do not stop after finding a few issues. Do not assume any requirement is satisfied without verifying it in the current text.
316
+
317
+ ## Step 2: Craft Suggestions for Unmet Requirements
318
+
319
+ For each unmet requirement, you will provide a suggestion to help the student improve.
320
+
321
+ **Suggestion guidelines:**
322
+
323
+ Your suggestion should reflect the context of the student's progress:
324
+
325
+ **If this is the first time raising this issue:**
326
+ - Use a clear, instructive tone
327
+ - Explain what is missing and why it matters
328
+ - Example: "建议补充集庆的战略价值(如地势险要、富庶等),这能让读者理解为什么朱元璋要攻打集庆。"
329
+
330
+ **If the student completely ignored your previous suggestion (the issue is unchanged):**
331
+ - Use a firmer tone to emphasize importance
332
+ - Emphasize that this is required information
333
+ - Example: "你仍然没有提及集庆的战略价值。这是必要信息,必须补充,否则无法通过。"
334
+
335
+ **If the student attempted to fix it but fell short:**
336
+ - Acknowledge the improvement
337
+ - Provide encouraging, specific guidance on what's still needed
338
+ - Example: "你提到了'集庆很重要',这是个进步。但过于笼统,再具体一点,比如'地势险要'或'富庶',就能满足要求了。"
339
+
340
+ **Remember:** Once a requirement is met (even if it could be better), do NOT report it. Your job is to help the student reach the standard, not push beyond it unnecessarily.
341
+
342
+ ## Step 3: Determine Severity
343
+
344
+ Use the grading rubric to determine severity:
345
+
346
+ | Situation | Severity |
347
+ |-----------|----------|
348
+ | TIER 1: Chunk not mentioned at all | CRITICAL |
349
+ | TIER 1: Missing any core fact | MAJOR |
350
+ | TIER 1: All core facts present but NO minor details | MAJOR |
351
+ | TIER 2: ALL key points missing | MAJOR |
352
+ | TIER 3: Completely missing | MINOR |
353
+ | Narrative coherence severely disrupted | MAJOR |
354
+ | Narrative coherence awkward but understandable | MINOR |
355
+
356
+ **Note:**
357
+ - TIER 1 with "all core facts + ≥1 minor detail but some incomplete" = MINOR, but this is acceptable—do not report
358
+ - TIER 2 with "≥1 key point mentioned but incomplete" = MINOR, but this is acceptable—do not report
359
+ - TIER 3 "mentioned in any form" = MINOR, but this is acceptable—do not report
360
+
361
+ ---
362
+
363
+ # Output Format
364
+
365
+ Return your evaluation as JSON only, with no additional text.
366
+
367
+ ```json
368
+ {
369
+ "issues": [
370
+ {
371
+ "severity": "critical",
372
+ "problem": "【Chunk label】完全未提及。",
373
+ "suggestion": "你需要补充【chunk label】的内容。【说明为什么重要以及具体建议】。"
374
+ },
375
+ {
376
+ "severity": "major",
377
+ "problem": "关于【Chunk label】的核心事实缺失。缺少:【具体缺失的core fact】。",
378
+ "suggestion": "请补充【具体建议】,这对理解【为什么重要】是必要的。"
379
+ },
380
+ {
381
+ "severity": "minor",
382
+ "problem": "关于【Chunk label】的信息完全缺失。",
383
+ "suggestion": "请简要提及【具体内容】,这能帮助读者理解【为什么有帮助】。"
384
+ }
385
+ ]
386
+ }
387
+ ```
388
+
389
+ **Field definitions:**
390
+ - `issues`: Array of unmet requirements. Use empty array `[]` if all requirements are satisfied.
391
+ - `severity`: Either "critical", "major", or "minor" (determined by the grading rubric)
392
+ - `problem`: Describe specifically what is missing or wrong. Reference the chunk label and the specific requirement.
393
+ - `suggestion`: Actionable guidance for the student. Adjust tone based on context (first mention / ignored / partially fixed). Explain why this information matters.
394
+
395
+ **For narrative coherence issues:**
396
+ - `severity`: "major" or "minor" (never "critical")
397
+ - `problem`: Start with "叙事连贯性问题:" and describe the logical gap or abrupt transition
398
+ - `suggestion`: Explain what bridging information would help
399
+
400
+ ---
401
+
402
+ # Final Reminders
403
+
404
+ - **Check every requirement.** Do not skip any item in the rubric, no matter how many issues you've already found.
405
+ - **Base judgments solely on the rubric.** Your personal standards or preferences are irrelevant.
406
+ - **Pass what meets the standard.** If a requirement is satisfied (even barely), do not report it as an issue.
407
+ - **Empty issues `[]` means success.** The student has met all requirements. This is a positive outcome—do not feel pressured to find problems.
408
+ - **Your role is to help, not to obstruct.** Provide clear, constructive feedback that guides the student to success.
409
+
410
+ Output valid JSON only.