dsh-skill-hub 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["css","IconChevronDownOutline14","css","css","css","css","IconTrashOutline16","css","css","css","css","css","css","Fragment","css","IconSkillOutline16"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/locales.ts","../src/client/settings-nav-icon.ts","../src/client/settings-card.tsx","../src/client/settings-form.ts","../src/client/SkillHubSettingsCard.tsx","../src/client/helpers.ts","../src/client/grouping.ts","../src/client/panel/format.ts","../src/client/panel/SourceStatusBadge.tsx","../src/client/panel/SkillDetailView.tsx","../src/client/panel/TagEditorView.tsx","../src/client/panel/SkillRow.tsx","../src/client/panel/DisabledRow.tsx","../src/client/panel/GroupSummary.tsx","../src/client/panel/SourcesView.tsx","../src/client/panel/ScenesView.tsx","../src/client/market-catalog.ts","../src/client/panel/dialogs.tsx","../src/client/panel/MarketView.tsx","../src/client/panel/useSkillHub.ts","../src/client/panel/SkillHubPanel.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * Shared API contract for dsh-skill-hub: the route paths and payload shapes\n * both the host half and the browser half import. The browser half must never\n * depend on host SDK packages, so registry types are re-spelled here as\n * plain JSON-safe interfaces.\n */\n\n/** Browser-facing base paths of the skill-hub API family. */\nexport const SKILL_HUB_API = {\n catalog: '/api/skill-hub/catalog',\n skill: '/api/skill-hub/skill',\n skillDelete: '/api/skill-hub/skill/delete',\n toggle: '/api/skill-hub/toggle',\n toggleBatch: '/api/skill-hub/toggle-batch',\n create: '/api/skill-hub/create',\n stats: '/api/skill-hub/stats',\n config: '/api/skill-hub/config',\n market: '/api/skill-hub/market',\n marketSource: '/api/skill-hub/market/source',\n marketSourceDelete: '/api/skill-hub/market/source/delete',\n marketSourceRef: '/api/skill-hub/market/source/ref',\n marketCheck: '/api/skill-hub/market/check',\n marketSync: '/api/skill-hub/market/source/sync',\n repo: '/api/skill-hub/repo',\n repoImport: '/api/skill-hub/repo/import',\n update: '/api/skill-hub/update',\n groups: '/api/skill-hub/groups',\n tag: '/api/skill-hub/tag',\n tagDelete: '/api/skill-hub/tag/delete',\n tagMembers: '/api/skill-hub/tag/members',\n sources: '/api/skill-hub/sources',\n sourceCheck: '/api/skill-hub/sources/check',\n sourceSync: '/api/skill-hub/sources/sync',\n sourceDelete: '/api/skill-hub/sources/delete',\n sourceRestore: '/api/skill-hub/sources/restore',\n sourceTrashClear: '/api/skill-hub/sources/trash/clear',\n} as const\n\n/** User-level roots the hub may write to (matches dsh-skill-filesystem ranks 400/500). */\nexport type WritableRoot = 'user-dsh' | 'user-agents'\n\n/** Invocation policy resolved by the registry, re-spelled for the wire. */\nexport interface HubInvocation {\n /** Whether model-facing catalogs may load this skill. */\n modelInvocable: boolean\n /** Whether human-facing command catalogs may load this skill. */\n userInvocable: boolean\n}\n\n/** One enabled skill row in the catalog. */\nexport interface CatalogSkill {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Whether the hub may toggle this skill (user-level filesystem skills only). */\n writable: boolean\n /** 技能来源标识(user-dsh/user-agents/project-dsh/project-agents/...)。 */\n source: string\n /** SKILL.md creation time (epoch ms); used for \"added\" sorting. Absent when unknown. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); used for \"updated\" display. Absent when unknown. */\n updatedAt?: number\n /** 项目技能的所属工作区路径(仅 project-dsh/project-agents 来源携带)。 */\n workspace?: string\n /** 工作区显示标题(来自 workspace.json;无则回退为路径)。 */\n workspaceTitle?: string\n}\n\n/** One disabled skill tracked by the hub sidecar (SKILL.md renamed away). */\nexport interface DisabledSkill {\n name: string\n description: string\n /** Absolute path of the renamed file (SKILL.md.disabled / <name>.md.disabled). */\n path: string\n root: WritableRoot\n disabledAt: number\n}\n\n/** One discovery diagnostic: a file the filesystem provider skips, with the reason. */\nexport interface DiagnosticEntry {\n path: string\n root: string\n reason: string\n}\n\n/** GET /api/skill-hub/catalog */\nexport interface CatalogResponse {\n ok: true\n /** Whether discovery completed within a stable catalog revision. */\n complete: boolean\n /** Sorted winning summaries of every enabled skill (all roots + providers). */\n skills: CatalogSkill[]\n /** Skills the hub has toggled off (kept outside provider discovery). */\n disabled: DisabledSkill[]\n /** Files in the writable roots the provider ignores, with reasons. */\n diagnostics: DiagnosticEntry[]\n}\n\n/** GET /api/skill-hub/skill */\nexport interface SkillDetail {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Absolute file path when the skill came from disk. */\n path?: string\n /** SKILL.md creation time (epoch ms); absent when the file is unreadable. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); absent when the file is unreadable. */\n updatedAt?: number\n /** Markdown instruction body. */\n content: string\n}\n\nexport interface SkillDetailResponse {\n ok: true\n skill: SkillDetail\n}\n\n/** POST /api/skill-hub/skill/delete — 把单个技能移入回收站(可恢复)。 */\nexport interface SkillDeleteRequest {\n name: string\n}\n\n/** POST /api/skill-hub/skill/delete */\nexport interface SkillDeleteResponse {\n ok: true\n name: string\n /** 移入回收站后的路径(目录或文件)。 */\n path: string\n}\n\n/** POST /api/skill-hub/toggle */\nexport interface ToggleRequest {\n /** Kebab-case skill name. */\n name: string\n /** true re-enables a hub-disabled skill; false disables an enabled one. */\n enabled: boolean\n}\n\nexport interface ToggleResponse {\n ok: true\n /** Fresh catalog after the mutation (the filesystem provider may lag a beat). */\n catalog: CatalogResponse\n}\n\n/** POST /api/skill-hub/toggle-batch — one group of skills, one write. */\nexport interface ToggleBatchRequest {\n names: string[]\n enabled: boolean\n}\n\n/** POST /api/skill-hub/toggle-batch */\nexport interface ToggleBatchResponse {\n ok: true\n catalog: CatalogResponse\n /** Per-name failures (unknown/read-only skills); empty means all landed. */\n failures: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/create */\nexport interface CreateRequest {\n /** Kebab-case skill name (validated with the official isSkillName grammar). */\n name: string\n /** Optional one-line routing description for the frontmatter. */\n description?: string\n /** Target user root; defaults to user-dsh (~/.dsh/skills). */\n root?: WritableRoot\n}\n\nexport interface CreateResponse {\n ok: true\n path: string\n root: WritableRoot\n}\n\n/** One skill's invocation stats across the local session logs. */\nexport interface SkillStat {\n /** Kebab-case skill name. */\n name: string\n /** How many sessions recorded a user-explicit invocation of this skill. */\n count: number\n /** Unix epoch ms of the most recent invocation (absent when never called). */\n lastUsed?: number\n}\n\n/** GET /api/skill-hub/stats */\nexport interface StatsResponse {\n ok: true\n /** Whether a session-log source was available (false means counts are empty). */\n available: boolean\n /** Sorted per-skill invocation counts. */\n stats: SkillStat[]\n}\n\n/** JSON error body shared by every route. */\nexport interface ErrorResponse {\n error: string\n}\n\n/** The skill hub's own runtime configuration, edited from the settings card. */\nexport interface HubConfig {\n /** Master switch: routes, provider, and announcement all go live with this. */\n enabled: boolean\n /** When true, a system-prompt section announces the hub to every agent. */\n announceToAgent: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n /** Show per-skill invocation count chip. Default true. */\n showUseCount?: boolean\n /** Show per-skill last-used relative time. Default true. */\n showUseTime?: boolean\n /** Show group-header usage summaries (count + last used). Default true. */\n showGroupSummary?: boolean\n}\n\n/**\n * The resolved shape of the hub's settings namespace (schema defaults, then\n * the composition base, then the user layer). Kept as a type alias so the\n * browser-side settings scope snapshot is index-compatible with the card\n * form's record shape.\n */\nexport type HubSettingsValue = {\n enabled: boolean\n announceToAgent: boolean\n showUseCount: boolean\n showUseTime: boolean\n showGroupSummary: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n}\n\n/**\n * Hub config defaults — the single source every layer reads: the cordis\n * schema (index.ts), the host's saved-override merge, and the routes'\n * fallback view. Changing a default here changes all three.\n */\nexport const HUB_CONFIG_DEFAULTS = {\n enabled: true,\n announceToAgent: true,\n showUseCount: true,\n showUseTime: true,\n showGroupSummary: true,\n} as const\n\n/**\n * Resolve the effective hub config: saved sidecar overrides win over the\n * cordis composition entry (the web card owns runtime config), missing\n * booleans fall back to HUB_CONFIG_DEFAULTS, and dot colors pass through\n * (saved first, then base) only when set.\n */\nexport function resolveHubConfig(saved: Partial<HubConfig>, base: Partial<HubConfig> = {}): HubConfig {\n const dotModelColor = saved.dotModelColor !== undefined ? saved.dotModelColor : base.dotModelColor\n const dotUserColor = saved.dotUserColor !== undefined ? saved.dotUserColor : base.dotUserColor\n return {\n enabled: saved.enabled ?? base.enabled ?? HUB_CONFIG_DEFAULTS.enabled,\n announceToAgent: saved.announceToAgent ?? base.announceToAgent ?? HUB_CONFIG_DEFAULTS.announceToAgent,\n showUseCount: saved.showUseCount ?? base.showUseCount ?? HUB_CONFIG_DEFAULTS.showUseCount,\n showUseTime: saved.showUseTime ?? base.showUseTime ?? HUB_CONFIG_DEFAULTS.showUseTime,\n showGroupSummary: saved.showGroupSummary ?? base.showGroupSummary ?? HUB_CONFIG_DEFAULTS.showGroupSummary,\n ...(dotModelColor !== undefined ? { dotModelColor } : {}),\n ...(dotUserColor !== undefined ? { dotUserColor } : {}),\n }\n}\n\n/** HEX color validation shared by host routes and the settings card. */\nexport const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i\n\n/** GET /api/skill-hub/config */\nexport interface ConfigResponse {\n ok: true\n /** Effective configuration (saved overrides merged over the defaults). */\n config: HubConfig\n /** Raw user overrides persisted in the sidecar (absent fields inherit defaults). */\n saved: Partial<HubConfig>\n}\n\n/** POST /api/skill-hub/config — a partial patch; omitted fields keep their values. */\nexport interface ConfigRequest {\n /** Set the field; null clears the saved override so it re-inherits the default. */\n enabled?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n announceToAgent?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseCount?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseTime?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showGroupSummary?: boolean | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotModelColor?: string | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotUserColor?: string | null\n}\n\n/** One market source: a tracked upstream repo plus its pinned version. */\nexport interface MarketSourceRecord {\n /** Repo slug (owner/repo). */\n repo: string\n /** Pinned version: release tag, branch name, or custom ref. Absent = not yet pinned. */\n ref?: string\n /** Commit the pinned ref last resolved to (update-check baseline). */\n commitSha?: string\n}\n\n/** GET /api/skill-hub/market — the user's added market sources. */\nexport interface MarketSourcesResponse {\n ok: true\n /** Added market sources, in addition order. */\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source — add one repo as a market source. */\nexport interface MarketSourceRequest {\n /** owner/repo, owner/repo@ref, or a github.com URL. */\n repo: string\n}\n\n/** POST /api/skill-hub/market/source|delete */\nexport interface MarketSourceResponse {\n ok: true\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source/ref — pin a market source to an explicit ref. */\nexport interface MarketSourceRefRequest {\n repo: string\n /** Release tag or branch name chosen for the repo. */\n ref: string\n}\n\n/** GET /api/skill-hub/market/check — update check over market sources. */\nexport interface MarketCheckResponse {\n ok: true\n results: Array<{\n repo: string\n /** Pinned ref, when one is recorded. */\n ref?: string\n /** Latest release tag on the repo, when it has one. */\n latestTag?: string\n /** Whether the pinned ref (or the repo) has moved ahead. */\n updateAvailable: boolean\n /** Latest commit of the checked ref. */\n commitSha: string\n /** Throttled: the check was skipped within the interval. */\n throttled?: boolean\n error?: string\n }>\n}\n\n/** POST /api/skill-hub/market/source/sync — align a market source to its pinned ref. */\nexport interface MarketSyncResponse {\n ok: true\n repo: string\n /** The ref the source is now pinned to. */\n ref: string\n commitSha: string\n /** Local skills tracked from this repo (candidates for a batch update). */\n skills: string[]\n}\n\n/** A skill discovered in a GitHub repo under skills/ or design-templates/. */\nexport interface RepoSkillEntry {\n /** Kebab-case skill name (directory basename). */\n name: string\n /** Root-relative skill directory, e.g. skills/code-review. */\n dir: string\n /** Root-relative SKILL.md path, e.g. skills/code-review/SKILL.md. */\n path: string\n /** Repo root the skill lives in. */\n root: RepoRoot\n /** Collection name recorded as origin after import. */\n origin: string\n /** Number of files in the skill directory. */\n fileCount: number\n /** Total bytes across all files in the skill directory. */\n totalBytes: number\n /** Whether a same-named skill already exists locally. */\n existing: boolean\n}\n\n/** Supported skill roots in a GitHub repo. */\nexport type RepoRoot = 'skills' | 'design-templates'\n\n/** GET /api/skill-hub/repo — discover importable skills in a GitHub repo. */\nexport interface RepoDiscoverResponse {\n ok: true\n repo: string\n /**\n * Ref the discovery ran against (release tag / branch / default branch).\n * Null means the repo has no release and no pinned ref — the client must\n * ask the user to pick a branch (see `branches`) and pin it first.\n */\n ref: string | null\n /** Branch names to choose from when ref is null (default branch first). */\n branches?: string[]\n entries: RepoSkillEntry[]\n}\n\n/** POST /api/skill-hub/repo/import — install selected repo skills. */\nexport interface RepoImportRequest {\n repo: string\n /** Selected SKILL.md paths from the discover response. */\n paths: string[]\n /** The ref the discovery ran against; the import must use the same one. */\n ref?: string\n}\n\n/** POST /api/skill-hub/repo/import */\nexport interface RepoImportResponse {\n ok: true\n imported: Array<{ name: string; origin: string; path: string }>\n skipped: Array<{ name: string; reason: 'exists' }>\n failed: Array<{ name: string; error: string }>\n}\n\n/** GET /api/skill-hub/update — check the plugin's own latest GitHub release. */\nexport interface UpdateCheckResponse {\n ok: true\n /** Installed plugin version (from the bundled host build). */\n currentVersion: string\n /** Latest release tag, normalized without the leading v; null when unknown. */\n latestVersion: string | null\n /** True when latestVersion is strictly newer than currentVersion. */\n updateAvailable: boolean\n /** Release page URL; null when unavailable. */\n url: string | null\n /** Best-effort message when the check failed or no release exists. */\n error?: string\n}\n\n/** 用户自定义 tag 分组:纯组织视图,不改技能文件。 */\nexport interface SkillTag {\n /** 稳定 ID(新建时由宿主生成)。 */\n id: string\n /** 显示名。 */\n name: string\n /** 成员技能名(集合技能与独立技能都可加入)。 */\n skillNames: string[]\n /** 默认场景(「通用」):系统预置、不可删除、新技能自动归入。 */\n default?: boolean\n}\n\n/** 系统集合组:按 origin(来源集合标识)自动聚合。 */\nexport interface CollectionGroup {\n /** 集合名(origin 值,如 \"superpowers\" / \"anthropics/skills\")。 */\n name: string\n /** 该集合下的技能名,按名称排序。 */\n skillNames: string[]\n}\n\n/** GET /api/skill-hub/groups */\nexport interface GroupsResponse {\n ok: true\n /** 用户自定义 tag 分组(按创建顺序)。 */\n tags: SkillTag[]\n /** 系统集合组(按 origin 聚合,名称排序)。 */\n collections: CollectionGroup[]\n /** skillName → 集合名 的完整映射。 */\n origins: Record<string, string>\n}\n\n/** POST /api/skill-hub/tag — 新建(缺省 id)或重命名(带 id)。 */\nexport interface TagSaveRequest {\n /** 已有 tag 的 id;缺省表示新建。 */\n id?: string\n /** 显示名(去空格后非空)。 */\n name: string\n}\n\n/** POST /api/skill-hub/tag */\nexport interface TagSaveResponse {\n ok: true\n /** 变更后的全部 tag。 */\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteRequest {\n id: string\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/members — 直接设置某 tag 的完整成员列表(幂等)。 */\nexport interface TagMembersRequest {\n id: string\n /** 目标成员技能名;后端只保留目录中存在的名字。 */\n skillNames: string[]\n}\n\n/** POST /api/skill-hub/tag/members */\nexport interface TagMembersResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** 来源跟踪记录:一组来自同一上游仓库根目录的技能。 */\nexport interface SourceRecord {\n /** GitHub owner/repo。 */\n repo: string\n /** 显式分支/tag;缺省表示默认分支。 */\n ref?: string\n /** 技能在仓库中的根目录。 */\n root: RepoRoot\n /** 上次导入/同步时的上游 commit SHA;空 = 尚未核对过。 */\n commitSha: string\n /** 该来源下的技能名(来源组 = 这些技能)。 */\n skills: string[]\n /** 仓库内路径 → 文件大小 的基线清单(差异检测用;缺失 = 无基线)。 */\n manifest?: Record<string, number>\n}\n\n/** 回收站条目:上游删除后跟进删除(移入 .trash)的技能。 */\nexport interface TrashEntry {\n name: string\n /** .trash 下的绝对路径。 */\n path: string\n /** 移入回收站的时间(epoch ms)。 */\n movedAt: number\n /** 移入回收站前的原始路径(目录或文件);旧版本条目没有该字段。 */\n sourcePath?: string\n /**\n * 移入回收站前的来源跟踪快照(恢复时用它把技能重新挂回来源记录,\n * 否则恢复后的技能会丢失来源归属、变成「个人技能」)。\n */\n origin?: {\n repo: string\n root: RepoRoot\n ref?: string\n commitSha: string\n }\n /** 移入回收站前所属的场景(tag)ID;恢复时重新加回这些场景。 */\n tagIds?: string[]\n}\n\n/** GET /api/skill-hub/sources */\nexport interface SourcesResponse {\n ok: true\n /** 全部来源记录(按 repo 排序)。 */\n sources: SourceRecord[]\n /** skillName → 集合名(由 sources 派生)。 */\n origins: Record<string, string>\n /** 来源集合组(按 origin 聚合)。 */\n collections: CollectionGroup[]\n /** 回收站内容。 */\n trash: TrashEntry[]\n}\n\n/** POST /api/skill-hub/sources/check — 检查指定(或全部)来源的上游更新。 */\nexport interface SourceCheckRequest {\n /** 仅检查该 repo;缺省检查全部。 */\n repo?: string\n}\n\n/** 单个来源的检查结果。 */\nexport interface SourceCheckResult {\n repo: string\n ref?: string\n /** 检查失败时的原因(如仓库不可达/限流)。 */\n error?: string\n /** 上游 commit 是否变化。 */\n changed: boolean\n /** 上游最新 commit SHA(检查成功时)。 */\n commitSha?: string\n /** 上游有更新的技能名(changed 时经 tree 差异得出)。 */\n updated: string[]\n /** 上游已删除的技能名(changed 时经 tree 差异得出)。 */\n deleted: string[]\n /** 节流跳过(距上次检查不足 5 分钟,未访问网络)。 */\n throttled?: boolean\n /** 该来源此前没有快照(迁移/旧记录),本次已回填 commit,尚未有差异基线。 */\n unverified?: boolean\n}\n\n/** POST /api/skill-hub/sources/check */\nexport interface SourceCheckResponse {\n ok: true\n results: SourceCheckResult[]\n}\n\n/** POST /api/skill-hub/sources/sync — 按上游重新下载所选技能并更新快照。 */\nexport interface SourceSyncRequest {\n repo: string\n /** 要同步的技能名;缺省同步该来源全部技能。 */\n skills?: string[]\n}\n\n/** POST /api/skill-hub/sources/sync */\nexport interface SourceSyncResponse {\n ok: true\n repo: string\n /** 同步后的上游 commit SHA。 */\n commitSha: string\n /** 成功同步的技能。 */\n synced: string[]\n /** 失败的技能。 */\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/delete — 跟进上游删除,本地移入回收站。 */\nexport interface SourceDeleteRequest {\n repo: string\n /** 要删除的技能名(移入 .trash)。 */\n skills: string[]\n}\n\n/** POST /api/skill-hub/sources/delete */\nexport interface SourceDeleteResponse {\n ok: true\n /** 已移入回收站的技能。 */\n trashed: string[]\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/restore — 从回收站恢复一个技能。 */\nexport interface SourceRestoreRequest {\n name: string\n}\n\n/** POST /api/skill-hub/sources/restore */\nexport interface SourceRestoreResponse {\n ok: true\n name: string\n path: string\n}\n\n/** POST /api/skill-hub/sources/trash/clear — 永久删除回收站里的全部技能。 */\nexport interface SourceTrashClearResponse {\n ok: true\n /** 已永久删除的技能名。 */\n deleted: string[]\n /** 未能删除的技能(保留在回收站中)。 */\n failed: Array<{ name: string; error: string }>\n}\n","/**\n * Browser-side API client for the /api/skill-hub route family. The only\n * data access path the panel uses — plain fetch, same origin.\n */\nimport {\n SKILL_HUB_API,\n type CatalogResponse,\n type ConfigRequest,\n type ConfigResponse,\n type CreateRequest,\n type CreateResponse,\n type MarketCheckResponse,\n type MarketSourceRefRequest,\n type MarketSourceRequest,\n type MarketSourceResponse,\n type MarketSourcesResponse,\n type MarketSyncResponse,\n type RepoDiscoverResponse,\n type RepoImportRequest,\n type RepoImportResponse,\n type SkillDetail,\n type SkillDetailResponse,\n type SkillDeleteRequest,\n type SkillDeleteResponse,\n type SourceCheckRequest,\n type SourceCheckResponse,\n type SourceDeleteRequest,\n type SourceDeleteResponse,\n type SourceRestoreRequest,\n type SourceRestoreResponse,\n type SourceTrashClearResponse,\n type SourcesResponse,\n type SourceSyncRequest,\n type SourceSyncResponse,\n type StatsResponse,\n type ToggleBatchRequest,\n type ToggleBatchResponse,\n type UpdateCheckResponse,\n} from '../protocol.ts'\n\n/** Error carrying the route's JSON error message. */\nexport class SkillHubApiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'SkillHubApiError'\n }\n}\n\n/** Parse a JSON response or throw a SkillHubApiError. */\nasync function readJson<T>(response: Response): Promise<T> {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new SkillHubApiError('HTTP ' + response.status + ': invalid JSON response')\n }\n if (!response.ok) {\n const message = typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : 'HTTP ' + response.status\n throw new SkillHubApiError(message)\n }\n return body as T\n}\n\n/**\n * Fetch with a hard timeout: a hung connection (proxy, stalled keep-alive,\n * host wedged) must never leave the panel stuck on \"loading\" forever — it\n * fails fast and surfaces the error banner instead.\n */\nasync function fetchWithTimeout(input: RequestInfo | URL, init?: RequestInit, ms = 10_000): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), ms)\n try {\n return await fetch(input, { ...init, signal: controller.signal })\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** The browser half's only data entry point. */\nexport class SkillHubApi {\n /** Catalog lookup options (cwd selects a workspace's project skills). */\n catalog(options?: { cwd?: string }): Promise<CatalogResponse> {\n const url = options?.cwd !== undefined && options.cwd !== '' ? SKILL_HUB_API.catalog + '?cwd=' + encodeURIComponent(options.cwd) : SKILL_HUB_API.catalog\n return fetchWithTimeout(url).then((response) => readJson<CatalogResponse>(response))\n }\n\n /** One skill's detail (cwd selects a workspace's project skills). */\n async skill(name: string, options?: { cwd?: string }): Promise<SkillDetail> {\n const cwd = options?.cwd !== undefined && options.cwd !== '' ? '&cwd=' + encodeURIComponent(options.cwd) : ''\n const url = SKILL_HUB_API.skill + '?name=' + encodeURIComponent(name) + cwd\n const response = await fetchWithTimeout(url)\n const body = await readJson<SkillDetailResponse>(response)\n return body.skill\n }\n\n /** Move one writable skill into the restorable trash. */\n async deleteSkill(name: string): Promise<SkillDeleteResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.skillDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name } satisfies SkillDeleteRequest),\n })\n return readJson<SkillDeleteResponse>(response)\n }\n\n /** Toggle one skill; resolves with the fresh catalog from the route. */\n async toggle(name: string, enabled: boolean): Promise<CatalogResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.toggle, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name, enabled } satisfies import('../protocol.ts').ToggleRequest),\n })\n const body = await readJson<import('../protocol.ts').ToggleResponse>(response)\n return body.catalog\n }\n\n async create(payload: CreateRequest): Promise<CreateResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.create, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<CreateResponse>(response)\n }\n\n async stats(): Promise<StatsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.stats)\n return readJson<StatsResponse>(response)\n }\n\n /** Toggle a whole group in one write; resolves with the fresh catalog + failures. */\n async toggleBatch(names: string[], enabled: boolean): Promise<ToggleBatchResponse> {\n const payload: ToggleBatchRequest = { names, enabled }\n const response = await fetchWithTimeout(SKILL_HUB_API.toggleBatch, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<ToggleBatchResponse>(response)\n }\n\n /** The user's added market sources. */\n async market(): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.market)\n return readJson<MarketSourcesResponse>(response)\n }\n\n /** Add a market source repo; resolves with the fresh list. */\n async addMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSource, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Remove a market source repo; resolves with the fresh list. */\n async removeMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check every market source for updates (throttled server-side). */\n async marketCheck(): Promise<MarketCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketCheck)\n return readJson<MarketCheckResponse>(response)\n }\n\n /** Align a market source to its pinned ref; resolves with tracked skills. */\n async marketSync(repo: string): Promise<MarketSyncResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo }),\n })\n return readJson<MarketSyncResponse>(response)\n }\n\n /** Pin a market source to an explicit ref (branch picker). */\n async setMarketSourceRef(repo: string, ref: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceRef, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo, ref } satisfies MarketSourceRefRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check the hub's own latest GitHub release. */\n async updateCheck(): Promise<UpdateCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.update)\n return readJson<UpdateCheckResponse>(response)\n }\n\n /** Discover importable skills in a GitHub repo. */\n async repoDiscover(repo: string): Promise<RepoDiscoverResponse> {\n const url = SKILL_HUB_API.repo + '?repo=' + encodeURIComponent(repo)\n const response = await fetchWithTimeout(url)\n return readJson<RepoDiscoverResponse>(response)\n }\n\n /** Install selected repo skills into the user-dsh root (records the source). */\n async repoImport(repo: string, paths: string[], ref?: string): Promise<RepoImportResponse> {\n const payload: RepoImportRequest = { repo, paths, ...(ref !== undefined && ref !== '' ? { ref } : {}) }\n const response = await fetchWithTimeout(SKILL_HUB_API.repoImport, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<RepoImportResponse>(response)\n }\n\n /** Read the hub's runtime config (effective values + saved overrides). */\n async config(): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config)\n return readJson<ConfigResponse>(response)\n }\n\n /** Patch the hub's runtime config (null clears a saved override). */\n async saveConfig(patch: ConfigRequest): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n })\n return readJson<ConfigResponse>(response)\n }\n\n /** 用户 tag 分组 + 系统集合组 + origin 映射。 */\n async groups(): Promise<import('../protocol.ts').GroupsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.groups)\n return readJson<import('../protocol.ts').GroupsResponse>(response)\n }\n\n /** 新建(无 id)或重命名(带 id)一个 tag 分组;返回全部 tag。 */\n async saveTag(payload: import('../protocol.ts').TagSaveRequest): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tag, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const body = await readJson<import('../protocol.ts').TagSaveResponse>(response)\n return body.tags\n }\n\n /** 删除一个 tag 分组;返回全部 tag。 */\n async deleteTag(id: string): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id } satisfies import('../protocol.ts').TagDeleteRequest),\n })\n const body = await readJson<import('../protocol.ts').TagDeleteResponse>(response)\n return body.tags\n }\n\n /** 直接设置某 tag 的完整成员列表;返回全部 tag。 */\n async setTagMembers(id: string, skillNames: string[]): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagMembers, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id, skillNames } satisfies import('../protocol.ts').TagMembersRequest),\n })\n const body = await readJson<import('../protocol.ts').TagMembersResponse>(response)\n return body.tags\n }\n\n /** 来源列表 + 派生 origin 映射 + 集合组 + 回收站。 */\n async sources(): Promise<SourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sources)\n return readJson<SourcesResponse>(response)\n }\n\n /** 检查指定(或全部)来源的上游更新。 */\n async checkSources(repo?: string): Promise<SourceCheckResponse> {\n const payload: SourceCheckRequest = repo !== undefined ? { repo } : {}\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceCheck, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceCheckResponse>(response)\n }\n\n /** 同步一个来源的所选(或全部)技能到上游最新版本。 */\n async syncSource(repo: string, skills?: string[]): Promise<SourceSyncResponse> {\n const payload: SourceSyncRequest = skills !== undefined ? { repo, skills } : { repo }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceSyncResponse>(response)\n }\n\n /** 跟进上游删除:把所选技能移入回收站。 */\n async confirmDeleteSource(repo: string, skills: string[]): Promise<SourceDeleteResponse> {\n const payload: SourceDeleteRequest = { repo, skills }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceDeleteResponse>(response)\n }\n\n /** 从回收站恢复一个技能。 */\n async restoreSource(name: string): Promise<SourceRestoreResponse> {\n const payload: SourceRestoreRequest = { name }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceRestore, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceRestoreResponse>(response)\n }\n\n /** Permanently delete every skill currently in the trash. */\n async clearTrash(): Promise<SourceTrashClearResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceTrashClear, { method: 'POST' })\n return readJson<SourceTrashClearResponse>(response)\n }\n}\n","/**\n * dsh-skill-hub surface copy (zh/en). The dictionary type is re-exported\n * so the LocaleNamespaceMap module augmentation in client/index.ts can\n * reference it without a value import.\n */\n\nexport const zh = {\n 'entry.label': '技能',\n 'entry.tooltip': '技能中枢:浏览、分组与同步管理本地技能',\n 'view.sources': '来源',\n 'view.scenes': '场景',\n 'view.market': '市场',\n 'view.flat': '平铺',\n 'view.grouped': '分组',\n 'panel.title': '技能中枢',\n 'panel.count': '共 {count} 个技能',\n 'panel.disabledCount': '已禁用 {count}',\n 'panel.new': '新建技能',\n 'panel.search': '搜索技能…',\n 'legend.model': '模型可调 — Agent 可自动调用',\n 'legend.user': '用户可调 — 仅显式点名时触发',\n 'legend.hint': '圆点标在技能名旁;无圆点表示该技能不可被调用。',\n 'panel.enabled': '已启用',\n 'panel.disabled': '已禁用',\n 'panel.diagnostics': '发现诊断',\n 'panel.empty': '没有匹配的技能。',\n 'panel.emptyAll': '本地还没有技能。点击「新建技能」创建第一个。',\n 'panel.loading': '读取中…',\n 'panel.incomplete': '(目录可能不完整)',\n 'panel.workspacePlaceholder': '工作区路径(回车应用)',\n 'panel.workspaceHint': '填写项目路径后,面板同时显示该项目 .dsh/skills 与 .agents/skills 下的技能(只读);留空回车恢复用户级视图。',\n 'panel.workspaceClear': '清除工作区',\n 'market.addPlaceholder': 'owner/repo 或 https://github.com/…',\n 'market.addSource': '添加源',\n 'market.noSources': '还没有市场源。从下方内置市场添加,或输入一个 GitHub 仓库。',\n 'market.title': '市场',\n 'market.catalogHint': '精选技能仓库,添加后即可扫描安装,并持续检查更新。',\n 'market.catalog.anthropics': 'Anthropic 官方技能合集(Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers 社区技能合集',\n 'market.catalog.mattpocock': 'Matt Pocock 技能集',\n 'market.catalog.openDesign': '设计技能合集(design-templates)',\n 'market.add': '添加',\n 'market.installed': '已装 {count}',\n 'market.updatable': '可更新 {count}',\n 'market.deletedUpstream': '上游已删 {count}',\n 'market.checkAll': '检查全部',\n 'market.updateAll': '全部更新',\n 'market.updateAllConfirmTitle': '批量更新全部技能?',\n 'market.updateAllConfirmText': '将把以下来源的可更新技能更新到上游最新版本(覆盖本地修改):',\n 'market.updateAllItem': '{repo}({count} 个技能)',\n 'market.updateAllDone': '已更新 {count} 个来源',\n 'market.deleteSource': '移除源',\n 'market.scan': '扫描',\n 'market.scanning': '扫描中…',\n 'market.check': '检查',\n 'market.sync': '同步',\n 'market.syncing': '同步中…',\n 'market.updated': '有更新',\n 'market.newRelease': '新版本 v{version}',\n 'market.branchTitle': '选择分支',\n 'market.branchHint': '该仓库没有正式发布,选择要跟踪的分支(默认为 main):',\n 'market.branchConfirm': '确定',\n 'market.syncTitle': '同步本地技能',\n 'market.syncText': '市场源已对齐到 {ref},要同步更新以下本地技能吗?',\n 'market.syncNone': '该来源还没有导入本地技能。',\n 'market.syncCancel': '跳过',\n 'market.removeHint': '移除源不影响已安装的技能。',\n 'repo.ready': '发现 {count} 个可导入技能',\n 'repo.empty': '没有找到可导入技能。',\n 'repo.selectAll': '全选',\n 'repo.clearAll': '清空',\n 'repo.import': '导入所选 ({count})',\n 'repo.importing': '导入中…',\n 'repo.existing': '已存在',\n 'repo.files': '{count} 个文件 · {size}',\n 'repo.imported': '导入成功 {count} 个',\n 'repo.skippedExisting': '跳过已存在 {count} 个',\n 'repo.failed': '失败 {count} 个',\n 'repo.root.skills': '技能 skills',\n 'repo.root.designTemplates': '模板 design-templates',\n 'update.check': '检查更新',\n 'update.checking': '检查中…',\n 'update.upToDate': '已是最新版本 v{version}',\n 'update.available': '发现新版本 v{version}(当前 v{current})',\n 'update.newVersion': '新版本 v{version}',\n 'update.viewRelease': '查看发布',\n 'update.error': '检查更新失败:{error}',\n 'update.unavailable': '暂无可用的发布版本',\n 'group.project-dsh': '项目 .dsh/skills',\n 'group.project-agents': '项目 .agents/skills',\n 'group.custom': '自定义目录',\n 'group.runtime': '运行时',\n 'group.user-dsh': '用户 ~/.dsh/skills',\n 'group.user-agents': '用户 ~/.agents/skills',\n 'group.bundled': '内置',\n 'group.other': '其他来源',\n 'groups.new': '新建场景',\n 'groups.namePlaceholder': '场景名',\n 'groups.edit': '编辑',\n 'groups.rename': '保存名称',\n 'groups.delete': '删除场景',\n 'groups.saveMembers': '保存成员',\n 'groups.membersHint': '勾选技能加入此场景(含已禁用)。',\n 'groups.empty': '还没有场景。先新建一个,再把技能归类。',\n 'groups.noCollections': '暂无来源组。从市场导入技能后自动按来源聚合。',\n 'groups.personal': '个人',\n 'groups.project': '项目级',\n 'groups.subdivide': '细分',\n 'groups.merge': '合并',\n 'groups.noWritable': '该组没有可写技能(只读技能无法由中枢开关)',\n 'groups.closeAll': '全部关闭',\n 'groups.keepOn': '保留开启',\n 'groups.conflictTitle': '关闭此组?',\n 'groups.conflictText': '以下技能也在其他组中开启,关闭它们会影响那些组:',\n 'filter.allSources': '全部来源',\n 'filter.private': '个人',\n 'sort.name': '按名称',\n 'sort.added': '按添加时间',\n 'sort.uses': '按调用次数',\n 'time.justNow': '刚刚',\n 'time.minutesAgo': '{value} 分钟前',\n 'time.hoursAgo': '{value} 小时前',\n 'time.daysAgo': '{value} 天前',\n 'time.weeksAgo': '{value} 周前',\n 'badge.source.project-dsh': '项目 .dsh',\n 'badge.source.project-agents': '项目 .agents',\n 'badge.source.custom': '自定义',\n 'badge.source.runtime': '运行时',\n 'badge.source.user-dsh': '用户 .dsh',\n 'badge.source.user-agents': '用户 .agents',\n 'badge.source.bundled': '内置',\n 'row.readonly': '只读',\n 'row.disable': '禁用',\n 'row.enable': '启用',\n 'row.delete': '移入回收站',\n 'row.open': '查看 {name} 详情(回车)',\n 'delete.confirmTitle': '移入回收站?',\n 'delete.confirmText': '确定把「{name}」移入回收站吗?可随时恢复。',\n 'delete.confirm': '移入回收站',\n 'detail.back': '返回列表',\n 'detail.provider': '提供者',\n 'detail.addedAt': '添加时间',\n 'detail.updatedAt': '更新时间',\n 'detail.path': '路径',\n 'detail.whenToUse': '适用场景',\n 'detail.uses': '调用次数',\n 'detail.groups': '所属场景',\n 'detail.loading': '读取技能正文…',\n 'source.private': '个人技能(未绑定上游,不检查更新)',\n 'source.commit': '已同步版本',\n 'source.unverified': '尚未核对上游',\n 'source.check': '检查更新',\n 'source.checkHint': '点击检查上游更新',\n 'source.checking': '检查中…',\n 'source.upToDate': '已是最新',\n 'source.updated': '有更新 {count} 个',\n 'source.deleted': '上游已删除 {count} 个',\n 'source.error': '检查失败',\n 'source.throttled': '刚刚检查过',\n 'source.sync': '同步',\n 'source.syncing': '同步中…',\n 'source.syncConfirmTitle': '同步技能?',\n 'source.syncConfirmText': '将用上游最新版本覆盖本地对以下技能的所有修改:',\n 'source.followDelete': '跟进删除',\n 'source.deleteConfirmTitle': '跟进上游删除?',\n 'source.deleteConfirmText': '以下技能已从上游仓库移除,本地目录将移入回收站(可恢复):',\n 'source.trash': '回收站',\n 'source.restore': '恢复',\n 'source.clearTrash': '清空回收站',\n 'source.clearTrashConfirmTitle': '清空回收站?',\n 'source.clearTrashConfirmText': '回收站里的技能会被永久删除,无法恢复。此操作不可撤销。',\n 'source.clearTrashConfirm': '永久删除',\n 'form.capabilityHint': '能力怎么选:重复方法 → 技能;外部系统 → MCP;长期资料 → 知识库。',\n 'form.descPlaceholder': '一句话说明用途(含触发词),Agent 靠它自动激活技能',\n 'form.name': '技能名(kebab-case,如 code-review)',\n 'form.desc': '描述(一句话路由说明)',\n 'form.root': '目标目录',\n 'form.submit': '创建',\n 'form.cancel': '取消',\n 'form.busy': '创建中…',\n 'form.success': '已创建:',\n 'form.error': '创建失败:',\n 'err.dismiss': '知道了',\n 'settings.title': 'Skill Hub',\n 'settings.description': '管理 dsh 本地技能目录:浏览、分组、来源同步与新建。',\n 'settings.enabled': '启用插件',\n 'settings.enabledHint': '关闭后技能中枢的路由、入口与公告全部下线。',\n 'settings.announceToAgent': '向 Agent 公告',\n 'settings.announceToAgentHint': '在系统提示中加入本插件说明,用户提到技能管理时 Agent 知道如何协作。',\n 'settings.dotModelColor': '模型可调圆点颜色',\n 'settings.dotModelColorHint': '技能名旁蓝色圆点的颜色(#rrggbb)。',\n 'settings.dotUserColor': '用户可调圆点颜色',\n 'settings.dotUserColorHint': '技能名旁绿色圆点的颜色(#rrggbb)。',\n 'settings.showUseCount': '显示调用次数',\n 'settings.showUseCountHint': '在技能名旁显示琥珀色调用次数。',\n 'settings.showUseTime': '显示最近调用时间',\n 'settings.showUseTimeHint': '在技能名行右侧显示相对时间(如「3 天前」)。',\n 'settings.showGroupSummary': '显示分组汇总',\n 'settings.showGroupSummaryHint': '在分组标题后汇总调用次数与最近调用时间。',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '恢复默认',\n 'settings.unsaved': '未保存',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.saveFailed': '本部署没有接受这些值,已保留供你修改。',\n 'settings.readOnly': '本部署的设置为只读。',\n 'settings.notExposed': '本部署没有挂载该设置命名空间。',\n 'settings.collapse': '收起设置',\n 'settings.expand': '展开设置',\n} as const\n\nexport const en: Record<HubKey, string> = {\n 'entry.label': 'Skills',\n 'entry.tooltip': 'Skill hub: browse, group, and sync local skills',\n 'view.sources': 'Sources',\n 'view.scenes': 'Scenes',\n 'view.market': 'Market',\n 'view.flat': 'Flat',\n 'view.grouped': 'Grouped',\n 'panel.title': 'Skill Hub',\n 'panel.count': '{count} skills total',\n 'panel.disabledCount': '{count} disabled',\n 'panel.new': 'New Skill',\n 'panel.search': 'Search skills…',\n 'legend.model': 'Model-invocable — agents may call automatically',\n 'legend.user': 'User-invocable — explicit invocation only',\n 'legend.hint': 'Dots sit beside the skill name; no dot means the skill is not invocable.',\n 'panel.enabled': 'Enabled',\n 'panel.disabled': 'Disabled',\n 'panel.diagnostics': 'Discovery diagnostics',\n 'panel.empty': 'No matching skills.',\n 'panel.emptyAll': 'No skills installed yet. Create the first one.',\n 'panel.loading': 'Loading…',\n 'panel.incomplete': '(catalog may be incomplete)',\n 'panel.workspacePlaceholder': 'Workspace path (Enter to apply)',\n 'panel.workspaceHint': 'Enter a project path to also show that workspace\\'s .dsh/skills and .agents/skills skills (read-only); clear + Enter to return to the user-level view.',\n 'panel.workspaceClear': 'Clear workspace',\n 'market.addPlaceholder': 'owner/repo or https://github.com/…',\n 'market.addSource': 'Add source',\n 'market.noSources': 'No market sources yet. Add one from the built-in catalog below, or enter a GitHub repo.',\n 'market.title': 'Market',\n 'market.catalogHint': 'Curated skill repos — add one to scan and install, with ongoing update checks.',\n 'market.catalog.anthropics': 'Official Anthropic skill collection (Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers community skill collection',\n 'market.catalog.mattpocock': 'Matt Pocock skill collection',\n 'market.catalog.openDesign': 'Design skill collection (design-templates)',\n 'market.add': 'Add',\n 'market.installed': '{count} installed',\n 'market.updatable': '{count} updatable',\n 'market.deletedUpstream': '{count} deleted upstream',\n 'market.checkAll': 'Check all',\n 'market.updateAll': 'Update all',\n 'market.updateAllConfirmTitle': 'Update every skill?',\n 'market.updateAllConfirmText': 'The updatable skills of these sources will be overwritten with their latest upstream versions:',\n 'market.updateAllItem': '{repo} ({count} skills)',\n 'market.updateAllDone': 'Updated {count} sources',\n 'market.deleteSource': 'Remove source',\n 'market.scan': 'Scan',\n 'market.scanning': 'Scanning…',\n 'market.check': 'Check',\n 'market.sync': 'Sync',\n 'market.syncing': 'Syncing…',\n 'market.updated': 'Updates available',\n 'market.newRelease': 'New release v{version}',\n 'market.branchTitle': 'Choose a branch',\n 'market.branchHint': 'This repo has no releases. Pick a branch to track (main by default):',\n 'market.branchConfirm': 'Confirm',\n 'market.syncTitle': 'Update local skills',\n 'market.syncText': 'Market source aligned to {ref}. Update these local skills?',\n 'market.syncNone': 'No local skills tracked from this repo yet.',\n 'market.syncCancel': 'Skip',\n 'market.removeHint': 'Removing a source does not affect installed skills.',\n 'repo.ready': '{count} importable skills found',\n 'repo.empty': 'No importable skills found.',\n 'repo.selectAll': 'Select all',\n 'repo.clearAll': 'Clear',\n 'repo.import': 'Import selected ({count})',\n 'repo.importing': 'Importing…',\n 'repo.existing': 'Existing',\n 'repo.files': '{count} files · {size}',\n 'repo.imported': 'Imported {count}',\n 'repo.skippedExisting': 'Skipped existing {count}',\n 'repo.failed': 'Failed {count}',\n 'repo.root.skills': 'Skills',\n 'repo.root.designTemplates': 'Templates design-templates',\n 'update.check': 'Check for updates',\n 'update.checking': 'Checking…',\n 'update.upToDate': 'Up to date: v{version}',\n 'update.available': 'Update available: v{version} (current v{current})',\n 'update.newVersion': 'New version v{version}',\n 'update.viewRelease': 'View release',\n 'update.error': 'Update check failed: {error}',\n 'update.unavailable': 'No release available',\n 'group.project-dsh': 'Project .dsh/skills',\n 'group.project-agents': 'Project .agents/skills',\n 'group.custom': 'Custom directories',\n 'group.runtime': 'Runtime',\n 'group.user-dsh': 'User ~/.dsh/skills',\n 'group.user-agents': 'User ~/.agents/skills',\n 'group.bundled': 'Bundled',\n 'group.other': 'Other sources',\n 'groups.new': 'New scene',\n 'groups.namePlaceholder': 'Scene name',\n 'groups.edit': 'Edit',\n 'groups.rename': 'Save name',\n 'groups.delete': 'Delete scene',\n 'groups.saveMembers': 'Save members',\n 'groups.membersHint': 'Check skills to add to this scene (disabled skills included).',\n 'groups.empty': 'No scenes yet. Create one and start categorizing skills.',\n 'groups.noCollections': 'No source groups yet. Import skills from the market to group them by source.',\n 'groups.personal': 'Personal',\n 'groups.project': 'Project',\n 'groups.subdivide': 'Split',\n 'groups.merge': 'Merge',\n 'groups.noWritable': 'No writable skills in this group (read-only skills cannot be switched from the hub)',\n 'groups.closeAll': 'Close all',\n 'groups.keepOn': 'Keep on',\n 'groups.conflictTitle': 'Close this group?',\n 'groups.conflictText': 'These skills are also enabled in other groups; closing them affects those groups:',\n 'filter.allSources': 'All sources',\n 'filter.private': 'Personal',\n 'sort.name': 'By name',\n 'sort.added': 'By added',\n 'sort.uses': 'By uses',\n 'time.justNow': 'just now',\n 'time.minutesAgo': '{value} min ago',\n 'time.hoursAgo': '{value} h ago',\n 'time.daysAgo': '{value} d ago',\n 'time.weeksAgo': '{value} w ago',\n 'badge.source.project-dsh': 'project .dsh',\n 'badge.source.project-agents': 'project .agents',\n 'badge.source.custom': 'custom',\n 'badge.source.runtime': 'runtime',\n 'badge.source.user-dsh': 'user .dsh',\n 'badge.source.user-agents': 'user .agents',\n 'badge.source.bundled': 'bundled',\n 'row.readonly': 'read-only',\n 'row.disable': 'Disable',\n 'row.enable': 'Enable',\n 'row.delete': 'Move to trash',\n 'row.open': 'View {name} details (Enter)',\n 'delete.confirmTitle': 'Move to trash?',\n 'delete.confirmText': 'Move \"{name}\" to trash? It can be restored anytime.',\n 'delete.confirm': 'Move to trash',\n 'detail.back': 'Back to list',\n 'detail.provider': 'Provider',\n 'detail.addedAt': 'Added',\n 'detail.updatedAt': 'Updated',\n 'detail.path': 'Path',\n 'detail.whenToUse': 'When to use',\n 'detail.uses': 'Uses',\n 'detail.groups': 'Groups',\n 'detail.loading': 'Loading skill body…',\n 'source.private': 'Personal skill (not bound to an upstream; no update checks)',\n 'source.commit': 'Synced commit',\n 'source.unverified': 'upstream not verified yet',\n 'source.check': 'Check for updates',\n 'source.checkHint': 'Click to check the upstream for updates',\n 'source.checking': 'Checking…',\n 'source.upToDate': 'Up to date',\n 'source.updated': '{count} updates',\n 'source.deleted': '{count} deleted upstream',\n 'source.error': 'Check failed',\n 'source.throttled': 'Checked recently',\n 'source.sync': 'Sync',\n 'source.syncing': 'Syncing…',\n 'source.syncConfirmTitle': 'Sync skills?',\n 'source.syncConfirmText': 'This overwrites local changes to these skills with the latest upstream version:',\n 'source.followDelete': 'Follow deletion',\n 'source.deleteConfirmTitle': 'Follow upstream deletion?',\n 'source.deleteConfirmText': 'These skills were removed upstream; their local directories move to trash (restorable):',\n 'source.trash': 'Trash',\n 'source.restore': 'Restore',\n 'source.clearTrash': 'Empty trash',\n 'source.clearTrashConfirmTitle': 'Empty the trash?',\n 'source.clearTrashConfirmText': 'Skills in the trash will be permanently deleted and cannot be restored.',\n 'source.clearTrashConfirm': 'Delete permanently',\n 'form.capabilityHint': 'Choosing a capability: repeatable method → skill; external system → MCP; long-term knowledge → knowledge base.',\n 'form.descPlaceholder': 'One line on what it does (with trigger words) — agents auto-activate from this',\n 'form.name': 'Skill name (kebab-case, e.g. code-review)',\n 'form.desc': 'Description (one routing sentence)',\n 'form.root': 'Target root',\n 'form.submit': 'Create',\n 'form.cancel': 'Cancel',\n 'form.busy': 'Creating…',\n 'form.success': 'Created: ',\n 'form.error': 'Create failed: ',\n 'err.dismiss': 'Dismiss',\n 'settings.title': 'Skill Hub',\n 'settings.description': 'Manage the local dsh skill catalog: browse, group, sync, and scaffold skills.',\n 'settings.enabled': 'Enable plugin',\n 'settings.enabledHint': 'Disables the hub routes, entries, and announcement.',\n 'settings.announceToAgent': 'Announce to agent',\n 'settings.announceToAgentHint': 'Adds a system-prompt section so agents know how to collaborate when users mention skill management.',\n 'settings.dotModelColor': 'Model-invocable dot color',\n 'settings.dotModelColorHint': 'Color of the blue dot beside skill names (#rrggbb).',\n 'settings.dotUserColor': 'User-invocable dot color',\n 'settings.dotUserColorHint': 'Color of the green dot beside skill names (#rrggbb).',\n 'settings.showUseCount': 'Show invocation count',\n 'settings.showUseCountHint': 'Show the amber invocation count beside each skill name.',\n 'settings.showUseTime': 'Show last-used time',\n 'settings.showUseTimeHint': 'Show relative last-used time on the name row (e.g. \"3 d ago\").',\n 'settings.showGroupSummary': 'Show group summaries',\n 'settings.showGroupSummaryHint': 'Summarize invocation count and last-used time after group titles.',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset to default',\n 'settings.unsaved': 'Unsaved',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'settings.readOnly': 'This deployment stores settings read-only.',\n 'settings.notExposed': 'This deployment does not expose the settings namespace.',\n 'settings.collapse': 'Hide settings',\n 'settings.expand': 'Show settings',\n}\n\n/** Union of every translatable key (the namespace's registered dictionary type). */\nexport type HubKey = keyof typeof zh\n\n/** Template values accepted by the interpolator. */\nexport type TranslateValues = Record<string, string | number>\n\n/** Interpolate a {name} template with the given values. */\nexport function t(dict: Record<string, string>, key: HubKey, values?: TranslateValues): string {\n let text = dict[key] ?? key\n if (values !== undefined) {\n for (const [name, value] of Object.entries(values)) {\n text = text.replaceAll('{' + name + '}', String(value))\n }\n }\n return text\n}\n","/**\n * The settings shell renders section nav icons from a hard-coded id map and\n * exposes no registrant icon option, so the skill-hub section falls back to\n * the generic gear. This scoped DOM patch swaps in the official skill icon\n * whenever the settings dialog re-renders.\n */\n\nconst SKILL_SECTION_LABELS = ['技能', 'Skills']\n\nconst SKILL_ICON_SVG = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-skill-hub-nav-icon=\"true\"><path d=\"M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z\" fill=\"currentColor\"/><path d=\"M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z\" fill=\"currentColor\"/></svg>`\n\nlet iconTemplate: SVGSVGElement | null = null\n\nfunction skillIcon(): SVGSVGElement {\n if (iconTemplate === null) {\n iconTemplate = new DOMParser().parseFromString(SKILL_ICON_SVG, 'image/svg+xml').documentElement as unknown as SVGSVGElement\n }\n return iconTemplate.cloneNode(true) as SVGSVGElement\n}\n\nfunction patchNavIcon(): void {\n const dialog = document.querySelector('[role=\"dialog\"]')\n if (dialog === null) return\n for (const button of dialog.querySelectorAll<HTMLButtonElement>('button')) {\n const label = button.querySelector('span')\n if (label === null || !SKILL_SECTION_LABELS.includes(label.textContent?.trim() ?? '')) continue\n if (button.querySelector('svg[data-skill-hub-nav-icon]') !== null) continue\n const current = button.querySelector('svg')\n const icon = skillIcon()\n if (current !== null) current.replaceWith(icon)\n else button.insertBefore(icon, button.firstChild)\n }\n}\n\n/** Swap the settings nav gear for the skill icon and keep it in sync. */\nexport function applySettingsNavIcon(): () => void {\n if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return () => {}\n patchNavIcon()\n const observer = new MutationObserver(() => { patchNavIcon() })\n observer.observe(document.body, { childList: true, subtree: true })\n return () => { observer.disconnect() }\n}\n","/**\n * Shared chrome for the plugin settings card, aligned with the official\n * dsh-client-ui-settings-plugins PluginCard design language: the same tokens,\n * disclosure header, field rhythm, and copy. Renders nothing while the\n * namespace is unavailable — a deployment that does not compose the owning\n * plugin should show no trace of it.\n */\n\nimport { useState, type ReactElement } from 'react'\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { HubKey } from './locales.ts'\nimport type { CardShell } from './settings-form.ts'\nimport css from './settings-card.module.css'\n\n/** Card-level chrome props. */\nexport interface PluginSettingsCardProps {\n /** Locale translator for the owning plugin's namespace (its own key domain). */\n t: (key: HubKey) => string\n /** Locale key of the card title. */\n titleKey: HubKey\n /** Locale key of the card description. */\n descriptionKey: HubKey\n /** The form shell state. */\n state: CardShell\n onSave: () => void\n onDiscard: () => void\n children?: ReactElement | ReactElement[]\n}\n\n/**\n * Render one plugin settings card.\n * @param props - the plugin's copy keys, its form state, and its controls.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function PluginSettingsCard(props: PluginSettingsCardProps): ReactElement | null {\n const [open, setOpen] = useState(false)\n const { state } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const blocked = !state.dirty || state.invalid || state.saving\n\n const header = (\n <button\n type='button'\n className={css.header}\n aria-expanded={open}\n aria-label={props.t(open ? 'settings.collapse' : 'settings.expand') + ': ' + title}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{props.t('settings.unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? css.chevronOpen : css.chevron} />\n </button>\n )\n\n if (!state.exposed) {\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? <div className={css.body}><p className={css.notExposed} role='status'>{props.t('settings.notExposed')}</p></div> : null}\n </li>\n )\n }\n\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role='status'>{props.t('settings.readOnly')}</p> : null}\n {props.children}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role='status'>{props.t('settings.saveFailed')}</p> : null}\n <button type='button' className={css.discard} disabled={!state.dirty || state.saving} onClick={props.onDiscard}>\n {props.t('settings.discard')}\n </button>\n <button type='button' className={css.save} disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n )\n}\n\n/** One staged boolean field: 继承 / 开 / 关. */\nexport interface BooleanFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n onLabel: string\n offLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n text: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function BooleanField(props: BooleanFieldProps): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <select id={props.id} className={css.input} value={props.text} disabled={props.disabled} onChange={(event) => { props.onEdit(event.target.value) }}>\n <option value=''>{props.inheritLabel}</option>\n <option value='true'>{props.onLabel}</option>\n <option value='false'>{props.offLabel}</option>\n </select>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n\n/**\n * A compact sliding switch for the card's master enable/disable control.\n * An empty text value means the field inherits its default; the switch still\n * reflects the effective default and becomes an explicit override on click.\n */\nexport interface SwitchFieldProps {\n label: string\n hint: string\n disabled: boolean\n text: string\n overridden: boolean\n overriddenLabel: string\n resetLabel: string\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function SwitchField(props: SwitchFieldProps): ReactElement {\n const checked = props.text !== 'false'\n return (\n <div className={css.field}>\n <div className={css.switchRow}>\n <div className={css.switchText}>\n <div className={css.head}>\n <span className={css.label}>{props.label}</span>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n <button\n type='button'\n className={checked ? css.switchOn : css.switch}\n role='switch'\n aria-checked={checked}\n aria-label={props.label}\n disabled={props.disabled}\n onClick={() => { props.onEdit(String(!checked)) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n </div>\n )\n}\n\n/** One staged color field: a native color picker plus the hex draft text. */\nexport interface ColorFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n /** Effective hex (#rrggbb) when overridden; empty string means inherit. */\n text: string\n /** The default color the picker shows while inheriting (per-field). */\n defaultColor: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function ColorField(props: ColorFieldProps): ReactElement {\n const value = /^#[0-9a-f]{6}$/i.test(props.text) ? props.text : props.defaultColor\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <div className={css.colorRow}>\n <input\n id={props.id}\n type='color'\n className={css.colorInput}\n value={value}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <input\n type='text'\n className={css.input + ' ' + css.colorText}\n value={props.text}\n disabled={props.disabled}\n placeholder={props.inheritLabel}\n onChange={(event) => { props.onEdit(event.target.value.trim()) }}\n />\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","/**\n * Settings-card form machinery, vendored from the dsh-web-ui family bucket\n * (packages/dsh-task-board/src/client/settings-form.ts) and re-typed. Stages\n * one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\n\nimport { createSnapshotStore, type SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** One staged field: its draft text plus the clear/reset marker. */\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\n/** One editable field spec: formatting plus text parsing. */\nexport interface FieldSpec {\n field: string\n format: (value: unknown) => string\n parse: (text: string) => { kind: 'set'; value: unknown } | { kind: 'clear' } | undefined\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n if (text === 'true') return { kind: 'set', value: true }\n if (text === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/** A #rrggbb color field, edited through hex draft text. */\nexport function colorField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value) ? value : ''),\n parse: (text) => {\n if (/^#[0-9a-f]{6}$/i.test(text)) return { kind: 'set', value: text }\n return undefined\n },\n }\n}\n\n/** Card-level state the chrome renders. */\nexport interface CardShell {\n available: boolean\n exposed: boolean\n writable: boolean\n dirty: boolean\n invalid: boolean\n saving: boolean\n failed: boolean\n}\n\n/** One field's state from the effective section and its staged draft. */\nexport interface FieldState {\n text: string\n overridden: boolean\n invalid: boolean\n}\n\n/** The settings scope face the form consumes (subset of SettingsScope<T>). */\nexport interface FormScope {\n subscribe(listener: () => void): () => void\n getSnapshot(): { status: string; writable: boolean; value?: Record<string, unknown>; base?: unknown; user?: unknown }\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/** Stages one card's edits and writes them through the settings transport. */\nexport class CardForm {\n private readonly scope: FormScope\n private readonly specs = new Map<string, FieldSpec>()\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /** @param scope - the bound settings scope for this card's namespace. */\n constructor(scope: FormScope, specs: FieldSpec[]) {\n this.scope = scope\n for (const spec of specs) this.specs.set(spec.field, spec)\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<T>(project: () => T) {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return { text: staged.text, overridden: write?.kind === 'set', invalid: write === undefined }\n }\n\n /** The actions the card's slot registration injects. */\n actions() {\n return {\n edit: (field: string, text: string) => { this.stage(field, { text, clear: false }) },\n resetField: (field: string) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /** Write every staged edit, then re-seed from what the Host accepted. */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap((item) => (item.run === undefined ? [] : [item.run]))\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) landed = (await write()) && landed\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n /** Every staged edit a save would write, in staging order. */\n plan(): Array<{ field: string; run: (() => Promise<boolean>) | undefined }> {\n const plan: Array<{ field: string; run: (() => Promise<boolean>) | undefined }> = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n }\n\n private userRecord(): Record<string, unknown> | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null ? user as Record<string, unknown> : undefined\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error('settings card has no field ' + field)\n return spec\n }\n\n private sectionValue(field: string): unknown {\n return this.scope.getSnapshot().value?.[field]\n }\n\n private baseValue(field: string): unknown {\n const base = this.scope.getSnapshot().base\n return typeof base === 'object' && base !== null ? (base as Record<string, unknown>)[field] : undefined\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.userRecord()\n }\n\n private stored(field: string): boolean {\n const user = this.userRecord()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n\n","/**\n * The dsh-skill-hub plugin settings card: bridges the hub's settings\n * namespace (bound through the official settings transport) onto the\n * family-style staged card form (enabled master switch + agent announcement).\n * Registered into the official `settings.plugin.item` slot keyed by that\n * namespace, so the plugin shows up in Settings → 插件 on dsh rc.7+.\n */\n\nimport type { ReactElement } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { ColorField, PluginSettingsCard, SwitchField } from './settings-card.tsx'\nimport { booleanField, CardForm, colorField, type CardShell, type FieldState, type FormScope } from './settings-form.ts'\n\n/** Model-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-model (panel.module.css). */\nexport const DEFAULT_DOT_MODEL_COLOR = '#2f81f7'\n/** User-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-user (panel.module.css). */\nexport const DEFAULT_DOT_USER_COLOR = '#3fb950'\n\n/** The card's projected state. */\nexport interface SkillHubSettingsState extends CardShell {\n enabled: FieldState\n announceToAgent: FieldState\n dotModelColor: FieldState\n dotUserColor: FieldState\n showUseCount: FieldState\n showUseTime: FieldState\n showGroupSummary: FieldState\n}\n\n/** The business face the card's slot registration injects. */\nexport interface SkillHubSettingsCardFace {\n hooks: {\n /** The card's snapshot store (projected form state). */\n skillHubSettingsCard: SnapshotStore<SkillHubSettingsState>\n }\n save: () => void\n discard: () => void\n edit: (field: string, text: string) => void\n resetField: (field: string) => void\n}\n\n/** Props the slot renderer binds (locale copy + injected form actions). */\nexport type SkillHubSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'dsh-skill-hub'> & InjectFace<SkillHubSettingsCardFace>\n\n/** Bridges the hub's config scope onto the card's staged form. */\nexport class SkillHubSettingsCardController {\n private readonly form: CardForm\n private readonly store: SnapshotStore<SkillHubSettingsState>\n\n /** @param scope - the hub settings scope the card edits (FormScope-compatible). */\n constructor(scope: FormScope) {\n this.form = new CardForm(scope, [booleanField('enabled'), booleanField('announceToAgent'), colorField('dotModelColor'), colorField('dotUserColor'), booleanField('showUseCount'), booleanField('showUseTime'), booleanField('showGroupSummary')])\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): SkillHubSettingsState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n announceToAgent: this.form.field('announceToAgent'),\n dotModelColor: this.form.field('dotModelColor'),\n dotUserColor: this.form.field('dotUserColor'),\n showUseCount: this.form.field('showUseCount'),\n showUseTime: this.form.field('showUseTime'),\n showGroupSummary: this.form.field('showGroupSummary'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot hook and its form actions.\n */\n inject(): SkillHubSettingsCardFace {\n return {\n hooks: { skillHubSettingsCard: this.store },\n ...this.form.actions(),\n }\n }\n}\n\n/**\n * Render the dsh-skill-hub card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function SkillHubSettingsCard(props: SkillHubSettingsCardProps): ReactElement {\n const { t } = props\n const state = props.useSkillHubSettingsCard((snapshot) => snapshot)\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n disabled,\n }\n return (\n <PluginSettingsCard\n t={t}\n titleKey='settings.title'\n descriptionKey='settings.description'\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <SwitchField\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <SwitchField\n label={t('settings.announceToAgent')}\n hint={t('settings.announceToAgentHint')}\n {...fieldProps}\n {...state.announceToAgent}\n onEdit={(text) => { props.edit('announceToAgent', text) }}\n onReset={() => { props.resetField('announceToAgent') }}\n />\n <ColorField\n id='skill-hub-dot-model-color'\n label={t('settings.dotModelColor')}\n hint={t('settings.dotModelColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_MODEL_COLOR}\n {...fieldProps}\n {...state.dotModelColor}\n onEdit={(text) => { props.edit('dotModelColor', text) }}\n onReset={() => { props.resetField('dotModelColor') }}\n />\n <ColorField\n id='skill-hub-dot-user-color'\n label={t('settings.dotUserColor')}\n hint={t('settings.dotUserColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_USER_COLOR}\n {...fieldProps}\n {...state.dotUserColor}\n onEdit={(text) => { props.edit('dotUserColor', text) }}\n onReset={() => { props.resetField('dotUserColor') }}\n />\n <SwitchField\n label={t('settings.showUseCount')}\n hint={t('settings.showUseCountHint')}\n {...fieldProps}\n {...state.showUseCount}\n onEdit={(text) => { props.edit('showUseCount', text) }}\n onReset={() => { props.resetField('showUseCount') }}\n />\n <SwitchField\n label={t('settings.showUseTime')}\n hint={t('settings.showUseTimeHint')}\n {...fieldProps}\n {...state.showUseTime}\n onEdit={(text) => { props.edit('showUseTime', text) }}\n onReset={() => { props.resetField('showUseTime') }}\n />\n <SwitchField\n label={t('settings.showGroupSummary')}\n hint={t('settings.showGroupSummaryHint')}\n {...fieldProps}\n {...state.showGroupSummary}\n onEdit={(text) => { props.edit('showGroupSummary', text) }}\n onReset={() => { props.resetField('showGroupSummary') }}\n />\n </PluginSettingsCard>\n )\n}\n","/**\n * Shared panel helpers: the active-dictionary pick (document-language\n * based, family precedent) plus a small error-message extractor.\n */\nimport { en, t, zh, type HubKey, type TranslateValues } from './locales.ts'\n\n/** Active dictionary, picked by the document language at call time. */\nexport function dictionary(): Record<string, string> {\n const lang = typeof document !== 'undefined' ? document.documentElement.lang : 'zh'\n return lang.toLowerCase().startsWith('en') ? { ...en } : { ...zh }\n}\n\n/** Translate a key with optional {name} template params (current language). */\nexport function tt(key: HubKey, values?: TranslateValues): string {\n return t(dictionary(), key, values)\n}\n\n/** Human-readable error text from an unknown thrown value. */\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n\n","/**\n * Pure grouping helpers for the skill-hub panel (no React/DOM deps, so the\n * merge/classify/filter logic stays unit-testable).\n *\n * The \"分组\" view unifies two ways a skill can belong to a group:\n * - user tags (sidecar SkillTag)\n * - origin collections (sidecar sources → backend-aggregated CollectionGroup)\n *\n * Switch semantics: a skill's enabled state is global (the file is renamed\n * once), so a group switch is derived from its members' actual states:\n * all members enabled → 'on', all disabled → 'off', otherwise 'mixed'.\n * Closing a group whose member is enabled in another group is a conflict the\n * GUI resolves with a dialog; the helpers below compute both sides.\n */\n\nimport type { CatalogSkill, CollectionGroup, SkillTag } from '../protocol.ts'\n\n/** Grouped switch state derived from member enablement. */\nexport type GroupSwitchState = 'on' | 'off' | 'mixed'\n\n/** The derived switch view of one group. */\nexport interface GroupSwitchView {\n state: GroupSwitchState\n /** Writable members currently enabled. */\n enabled: string[]\n /** Writable members currently disabled. */\n disabled: string[]\n}\n\n/**\n * Derive a group switch view from its member names and the set of currently\n * enabled skill names (catalog.skills). Members not in the enabled set count\n * as disabled (catalog.disabled or absent read-only rows).\n */\nexport function groupSwitchView(members: readonly string[], enabledNames: ReadonlySet<string>): GroupSwitchView {\n const enabled: string[] = []\n const disabled: string[] = []\n for (const name of members) {\n if (enabledNames.has(name)) enabled.push(name)\n else disabled.push(name)\n }\n const state: GroupSwitchState = disabled.length === 0 ? 'on' : enabled.length === 0 ? 'off' : 'mixed'\n return { state, enabled, disabled }\n}\n\n/** Names of every group a skill belongs to (tags + collections). */\nexport function groupNamesOf(name: string, tags: readonly SkillTag[], collections: readonly CollectionGroup[]): string[] {\n const names: string[] = []\n for (const tag of tags) if (tag.skillNames.includes(name)) names.push(tag.name)\n for (const collection of collections) if (collection.skillNames.includes(name)) names.push(collection.name)\n return names\n}\n\n/**\n * Members of a group that are currently enabled AND also belong to at least\n * one other group — the set a \"close\" action must ask about.\n */\nexport function conflictsOnClose(\n members: readonly string[],\n enabledNames: ReadonlySet<string>,\n otherGroups: ReadonlyArray<{ members: readonly string[] }>,\n): string[] {\n return members.filter((name) => {\n if (!enabledNames.has(name)) return false\n return otherGroups.some((group) => group.members.includes(name))\n })\n}\n\n/** Origin-repo filter value: skills with no source record (private skills). */\nexport const PRIVATE_SOURCE = 'private'\n\n/** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */\nexport function isProjectSource(source: string): boolean {\n return source === 'project-dsh' || source === 'project-agents'\n}\n\n/**\n * Apply the origin filter ('all' or a specific origin repo; skills without a\n * source record count as PRIVATE_SOURCE). The origins map is the store's\n * skillName → repo derivation, so filtering follows the tracked source\n * records instead of the filesystem root a skill happens to live under.\n * 项目级技能(有 workspace 归属)永远不算「个人」。\n */\nexport function filterBySource(skills: readonly CatalogSkill[], source: string, origins: Readonly<Record<string, string>>): CatalogSkill[] {\n if (source === 'all') return [...skills]\n return skills.filter((skill) => {\n if (isProjectSource(skill.source)) return false\n return (origins[skill.name] ?? PRIVATE_SOURCE) === source\n })\n}\n\n/** Catalog sort keys offered by the filter bar. */\nexport type SortKey = 'name' | 'added' | 'uses'\n\n/**\n * Sort a skill list in place-safe copy order: name ascending, added\n * descending (newest first, unknown addedAt last), or uses descending\n * (most-called first). Unknown values always trail.\n */\nexport function sortSkills(skills: readonly CatalogSkill[], key: SortKey, getUses?: (name: string) => number | undefined): CatalogSkill[] {\n const list = [...skills]\n if (key === 'name') {\n list.sort((a, b) => a.name.localeCompare(b.name))\n } else if (key === 'added') {\n list.sort((a, b) => (b.addedAt ?? -Infinity) - (a.addedAt ?? -Infinity))\n } else if (key === 'uses') {\n list.sort((a, b) => (getUses?.(b.name) ?? 0) - (getUses?.(a.name) ?? 0))\n }\n return list\n}\n\n/** Localized relative-time tuple; the caller resolves it via tt(). */\nexport interface RelativeTime {\n key: 'time.justNow' | 'time.minutesAgo' | 'time.hoursAgo' | 'time.daysAgo' | 'time.weeksAgo'\n value?: number\n}\n\n/** Format an epoch-ms timestamp as a short relative time bucket. */\nexport function formatRelativeTime(ms: number, now = Date.now()): RelativeTime {\n const diff = Math.max(0, now - ms)\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return { key: 'time.justNow' }\n if (minutes < 60) return { key: 'time.minutesAgo', value: minutes }\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return { key: 'time.hoursAgo', value: hours }\n const days = Math.floor(hours / 24)\n if (days < 7) return { key: 'time.daysAgo', value: days }\n return { key: 'time.weeksAgo', value: Math.floor(days / 7) }\n}\n","/**\n * Shared display helpers for the panel views (skill rows, detail view, and\n * dialogs): dot color styling, relative/absolute time text, and commit-SHA\n * shortening. Kept in one place so the views render identically.\n */\n\nimport type { CSSProperties } from 'react'\nimport { formatRelativeTime } from '../grouping.ts'\nimport { tt } from '../helpers.ts'\n\n/** Dot inline style from the user-chosen color (undefined keeps the CSS default). */\nexport function dotStyle(color: string | undefined): CSSProperties | undefined {\n if (color === undefined) return undefined\n return { background: color, borderColor: color }\n}\n\n/** Localized relative-time text for a Unix-ms timestamp. */\nexport function relativeTimeText(ms: number): string {\n const rt = formatRelativeTime(ms)\n return tt(rt.key, rt.value !== undefined ? { value: rt.value } : undefined)\n}\n\n/** Localized absolute time for the detail meta (e.g. \"2026/8/16 11:00:00\"). */\nexport function formatDateTime(ms: number): string {\n return new Date(ms).toLocaleString()\n}\n\n/** Short form of a commit SHA for display. */\nexport function shortSha(sha: string): string {\n return sha.length > 7 ? sha.slice(0, 7) : sha\n}\n","/**\n * Source check-status badges (up-to-date / updated / deleted / error /\n * throttled / unverified). Shared by the panel's source-group headers and\n * the skill detail view.\n *\n * In the group headers the badge doubles as the re-check affordance: it\n * shows a clickable \"检查更新\" badge before the first check, \"检查中…\" while\n * checking, and the status badge (clickable again to re-check) afterwards.\n */\n\nimport type { JSX } from 'react'\nimport type { SourceCheckResult } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport function SourceStatusBadge(props: {\n check: SourceCheckResult | undefined\n /** 正在检查该来源(显示「检查中…」)。 */\n checking?: boolean\n /** 提供后徽章区域可点击触发检查(组头用;详情页有自己的检查按钮)。 */\n onCheck?: () => void\n}): JSX.Element | null {\n const { check, checking, onCheck } = props\n if (checking === true) {\n return <span className={css.statusBadge}>{tt('source.checking')}</span>\n }\n if (check === undefined) {\n if (onCheck === undefined) return null\n return (\n <button type='button' className={css.statusBadge + ' ' + css.statusButton} title={tt('source.checkHint')} onClick={onCheck}>\n {tt('source.check')}\n </button>\n )\n }\n const badges = ((): JSX.Element | null => {\n if (check.error !== undefined) {\n return <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.error')}</span>\n }\n if (check.throttled === true) {\n return <span className={css.statusBadge}>{tt('source.throttled')}</span>\n }\n if (check.unverified === true) {\n return <span className={css.statusBadge}>{tt('source.unverified')}</span>\n }\n if (check.changed) {\n return (\n <span className={css.statusBadges}>\n {check.updated.length > 0 ? <span className={css.statusBadge + ' ' + css.statusUpdated}>{tt('source.updated', { count: check.updated.length })}</span> : null}\n {check.deleted.length > 0 ? <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.deleted', { count: check.deleted.length })}</span> : null}\n </span>\n )\n }\n return <span className={css.statusBadge + ' ' + css.statusOk}>{tt('source.upToDate')}</span>\n })()\n if (onCheck === undefined) return badges\n return (\n <button type='button' className={css.statusWrap} title={tt('source.checkHint')} onClick={onCheck}>\n {badges}\n </button>\n )\n}\n","/**\n * Full-page skill detail view: metadata, upstream source card with\n * check/sync/follow-delete actions, and the raw SKILL.md body. Pure\n * presentation — every state value and action arrives as a prop, so the\n * panel stays the single owner of state.\n */\n\nimport type { JSX } from 'react'\nimport type { GroupsResponse, HubConfig, SkillDetail, SourceCheckResult, SourcesResponse } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\nimport { dotStyle, formatDateTime, shortSha } from './format.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\n\nexport interface SkillDetailViewProps {\n detail: SkillDetail\n hubConfig: HubConfig | null\n /** skillName → usage stat (count + last used). */\n uses: ReadonlyMap<string, { count: number; lastUsed?: number }>\n groupsState: GroupsResponse | null\n sourcesState: SourcesResponse | null\n sourceCheck: Readonly<Record<string, SourceCheckResult>>\n checkingSource: string | null\n syncingSource: string | null\n loading: boolean\n onBack: () => void\n /** Check one source repo for upstream updates. */\n onCheck: (repo: string) => void\n /** Request syncing the skill (overwrites local edits; opens a confirm). */\n onSync: (repo: string, skills: string[]) => void\n /** Request following the upstream deletion (moves into the trash). */\n onFollowDelete: (repo: string, skills: string[]) => void\n}\n\nexport function SkillDetailView(props: SkillDetailViewProps): JSX.Element {\n const { detail, hubConfig, uses, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource, loading, onBack, onCheck, onSync, onFollowDelete } = props\n const detailSource = sourcesState?.sources.find((source) => source.skills.includes(detail.name))\n const detailCheck = detailSource !== undefined ? sourceCheck[detailSource.repo] : undefined\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <span className={css.detailName}>\n {detail.name}\n {detail.invocation.modelInvocable ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} title={tt('legend.model')} /> : null}\n {detail.invocation.userInvocable ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} title={tt('legend.user')} /> : null}\n </span>\n </div>\n <div className={css.detailMeta}>\n <div className={css.detailMetaLine}>{tt('detail.provider')}: {detail.provider}</div>\n {detail.addedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.addedAt')}: {formatDateTime(detail.addedAt)}</div> : null}\n {detail.updatedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.updatedAt')}: {formatDateTime(detail.updatedAt)}</div> : null}\n {detail.path !== undefined ? <div className={css.detailMetaLine}>{tt('detail.path')}: {detail.path}</div> : null}\n {detail.whenToUse !== undefined ? <div className={css.detailMetaLine}>{tt('detail.whenToUse')}: {detail.whenToUse}</div> : null}\n {(() => {\n const stat = uses.get(detail.name)\n if (stat === undefined || stat.count === 0) return null\n const at = stat.lastUsed !== undefined ? ' · ' + new Date(stat.lastUsed).toLocaleString() : ''\n return <div className={css.detailMetaLine}>{tt('detail.uses')}: {stat.count}{at}</div>\n })()}\n {(() => {\n const tags = (groupsState?.tags ?? []).filter((tag) => tag.skillNames.includes(detail.name)).map((tag) => tag.name)\n return tags.length > 0 ? <div className={css.detailMetaLine}>{tt('detail.groups')}: {tags.join(', ')}</div> : null\n })()}\n </div>\n {detailSource !== undefined ? (\n <div className={css.sourceCard}>\n <div className={css.sourceCardTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + detailSource.repo} target='_blank' rel='noreferrer'>{detailSource.repo}</a>\n {detailSource.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{detailSource.ref}</span> : null}\n <SourceStatusBadge check={detailCheck} />\n </div>\n <div className={css.detailMetaLine}>\n {tt('source.commit')}: {detailSource.commitSha === '' ? tt('source.unverified') : shortSha(detailSource.commitSha)}\n </div>\n <div className={css.buttons + ' ' + css.actionsTop}>\n <button type='button' className={css.opBtn} disabled={checkingSource !== null} onClick={() => { onCheck(detailSource.repo) }}>\n {checkingSource === detailSource.repo ? tt('source.checking') : tt('source.check')}\n </button>\n <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={() => { onSync(detailSource.repo, [detail.name]) }}>\n {syncingSource === detailSource.repo ? tt('source.syncing') : tt('source.sync')}\n </button>\n {detailCheck?.deleted.includes(detail.name) === true\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={() => { onFollowDelete(detailSource.repo, [detail.name]) }}>{tt('source.followDelete')}</button>\n : null}\n </div>\n </div>\n ) : (\n <p className={css.hintLine}>{tt('source.private')}</p>\n )}\n {loading ? <div className={css.muted}>{tt('detail.loading')}</div> : null}\n <pre className={css.detailContent}>{detail.content}</pre>\n </div>\n )\n}\n","/**\n * Full-page tag (scene) editor: rename / delete header, member checkbox\n * lists (enabled + disabled skills), and the save-members action. Pure\n * presentation — the draft state lives in the panel and arrives as props.\n */\n\nimport type { JSX } from 'react'\nimport type { CatalogResponse, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport interface TagEditorViewProps {\n tag: SkillTag\n /** Current name draft (panel-owned). */\n editName: string\n /** Current member-checkbox draft (panel-owned). */\n membersDraft: ReadonlySet<string>\n /** Current member-list search text (panel-owned). */\n editSearch: string\n catalog: CatalogResponse | null\n tagBusy: boolean\n onBack: () => void\n onEditName: (value: string) => void\n onEditSearch: (value: string) => void\n onToggleMember: (name: string, checked: boolean) => void\n /** Rename with the current draft (disabled while blank). */\n onRename: () => void\n /** Delete this tag (hidden for the default scene). */\n onDelete: () => void\n /** Persist the current member draft and leave the editor. */\n onSaveMembers: () => void\n}\n\nexport function TagEditorView(props: TagEditorViewProps): JSX.Element {\n const { tag, editName, membersDraft, editSearch, catalog, tagBusy, onBack, onEditName, onEditSearch, onToggleMember, onRename, onDelete, onSaveMembers } = props\n const editQuery = editSearch.trim().toLocaleLowerCase()\n const editSkills = (catalog?.skills ?? []).filter((skill) => editQuery.length === 0 || skill.name.toLocaleLowerCase().includes(editQuery) || skill.description.toLocaleLowerCase().includes(editQuery))\n const editDisabled = (catalog?.disabled ?? []).filter((record) => editQuery.length === 0 || record.name.toLocaleLowerCase().includes(editQuery) || record.description.toLocaleLowerCase().includes(editQuery))\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <input\n className={css.input + ' ' + css.grow}\n value={editName}\n onChange={(event) => { onEditName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='button' className={css.opBtn} disabled={tagBusy || editName.trim() === ''} onClick={onRename}>{tt('groups.rename')}</button>\n {tag.default !== true\n ? <button type='button' className={css.opBtn} disabled={tagBusy} onClick={onDelete}>{tt('groups.delete')}</button>\n : null}\n </div>\n <p className={css.hintLine}>{tt('groups.membersHint')}</p>\n <input className={css.search} value={editSearch} onChange={(event) => { onEditSearch(event.target.value) }} placeholder={tt('panel.search')} />\n <div className={css.section}>\n {editSkills.map((skill) => (\n <label key={skill.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(skill.name)}\n onChange={(event) => { onToggleMember(skill.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{skill.name}</div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n </label>\n ))}\n {editDisabled.map((record) => (\n <label key={record.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(record.name)}\n onChange={(event) => { onToggleMember(record.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description} · {tt('panel.disabled')}</div>\n </div>\n </label>\n ))}\n </div>\n <div className={css.buttons}>\n <button type='button' className={css.button + ' ' + css.primary} disabled={tagBusy} onClick={onSaveMembers}>{tt('groups.saveMembers')}</button>\n </div>\n </div>\n )\n}\n","/**\n * One enabled skill row: name + invocation dots + usage meta, delete and\n * disable actions. Shared by the flat list and both grouped views.\n */\n\nimport type { JSX, KeyboardEvent } from 'react'\nimport type { CatalogSkill } from '../../protocol.ts'\nimport { IconTrashOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { tt } from '../helpers.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function SkillRow(props: { skill: CatalogSkill; hub: SkillHubState }): JSX.Element {\n const { skill, hub } = props\n const stat = hub.uses.get(skill.name)\n const count = stat?.count ?? 0\n const lastUsed = stat?.lastUsed\n /** 键盘打开详情:Enter 或空格。仅当焦点在行本身(而非行内按钮)时生效。 */\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {\n if (event.target !== event.currentTarget) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n void hub.openDetail(skill.name)\n }\n }\n return (\n <div\n className={css.row}\n role='button'\n tabIndex={0}\n aria-label={tt('row.open', { name: skill.name })}\n onClick={() => { void hub.openDetail(skill.name) }}\n onKeyDown={onKeyDown}\n >\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <span className={css.rowNameText}>{skill.name}</span>\n {count > 0 && hub.hubConfig?.showUseCount !== false ? <span className={css.useCount}>{count}</span> : null}\n {skill.invocation.modelInvocable ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hub.hubConfig?.dotModelColor)} title={tt('legend.model')} /> : null}\n {skill.invocation.userInvocable ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hub.hubConfig?.dotUserColor)} title={tt('legend.user')} /> : null}\n {lastUsed !== undefined && hub.hubConfig?.showUseTime !== false ? <span className={css.useTime}>{relativeTimeText(lastUsed)}</span> : null}\n </div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n {skill.writable\n ? <>\n <button\n type='button'\n className={css.opBtn + ' ' + css.opDanger + ' ' + css.iconBtn}\n disabled={hub.busyNames.has(skill.name) || hub.tagBusy}\n title={tt('row.delete')}\n aria-label={tt('row.delete')}\n onClick={(event) => { event.stopPropagation(); hub.requestDeleteSkill(skill.name) }}\n ><IconTrashOutline16 size={14} /></button>\n <button\n type='button'\n role='switch'\n aria-checked={true}\n aria-label={tt('row.disable')}\n className={css.switch + ' ' + css.switchOn}\n disabled={hub.busyNames.has(skill.name)}\n onClick={(event) => { event.stopPropagation(); void hub.toggle(skill, false) }}\n ><span className={css.switchThumb} /></button>\n </>\n : <span className={css.badge + ' ' + css.badgeReadonly}>{tt('row.readonly')}</span>}\n </div>\n )\n}\n","/**\n * One disabled skill row (name + description + root badge + enable switch).\n * Shared by the source-group lists, the scene-group lists, and the bottom\n * disabled section.\n */\n\nimport type { JSX } from 'react'\nimport type { DisabledSkill, WritableRoot } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport type { HubKey } from '../locales.ts'\nimport css from './panel.module.css'\n\n/** Source badge label for a disabled record, derived from its writable root. */\nfunction disabledSourceLabel(root: WritableRoot): string {\n return tt(('badge.source.' + root) as HubKey)\n}\n\nexport function DisabledRow(props: { record: DisabledSkill; busy: boolean; onEnable: () => void }): JSX.Element {\n const { record, busy, onEnable } = props\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description}</div>\n </div>\n <span className={css.badges}>\n <span className={css.badge + ' ' + css.badgeSource}>{disabledSourceLabel(record.root)}</span>\n </span>\n <button type='button' role='switch' aria-checked={false} aria-label={tt('row.enable')} className={css.switch} disabled={busy} onClick={onEnable}><span className={css.switchThumb} /></button>\n </div>\n )\n}\n","/**\n * Group-header usage summary: total invocation count chip + the group's most\n * recent last-used time. Honours the showGroupSummary config switch.\n */\n\nimport type { JSX } from 'react'\nimport { relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function GroupSummary(props: { members: readonly string[]; hub: SkillHubState }): JSX.Element {\n const { members, hub } = props\n let total = 0\n let latest: number | undefined\n for (const name of members) {\n const stat = hub.uses.get(name)\n if (stat === undefined) continue\n total += stat.count\n if (stat.lastUsed !== undefined && (latest === undefined || stat.lastUsed > latest)) latest = stat.lastUsed\n }\n return (\n <span className={css.groupTitleInner}>\n {hub.hubConfig?.showGroupSummary !== false && total > 0 ? <span className={css.useCount}>{total}</span> : null}\n {hub.hubConfig?.showGroupSummary !== false && latest !== undefined ? <span className={css.useTime + ' ' + css.groupTime}>{relativeTimeText(latest)}</span> : null}\n </span>\n )\n}\n","/**\n * Sources tab: the flat skill list or the grouped view — a project-level\n * three-tier tree (workspaces from workspace.json, each optionally split by\n * .dsh/.agents), one card per upstream collection with check/sync/\n * follow-delete actions and the tri-state switch, plus the uncategorized\n * \"personal\" card (project skills never count as personal).\n */\n\nimport type { JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { filterBySource, groupSwitchView, isProjectSource, PRIVATE_SOURCE } from '../grouping.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** 项目级三级树:项目级 → 具体工作区(可折叠、可细分)→ .dsh/.agents。 */\nfunction ProjectTree(props: { hub: SkillHubState }): JSX.Element | null {\n const { hub } = props\n const { sorted, sourceFilter, origins, collapsedGroups, subdividedProjects, toggleGroupCollapse, toggleSubdivide } = hub\n const projectSkills = filterBySource(sorted, sourceFilter, origins).filter((skill) => isProjectSource(skill.source))\n if (projectSkills.length === 0) return null\n // workspace 缺失(过渡态)时按 source 降级分组,避免空标题。\n const byProject = new Map<string, { title: string; skills: typeof projectSkills }>()\n for (const skill of projectSkills) {\n const key = skill.workspace ?? skill.source\n const entry = byProject.get(key)\n if (entry === undefined) {\n byProject.set(key, {\n title: skill.workspaceTitle ?? skill.workspace ?? tt('groups.project'),\n skills: [skill],\n })\n } else {\n entry.skills.push(skill)\n }\n }\n const topCollapsed = collapsedGroups.has('project')\n return (\n <section className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!topCollapsed} onClick={() => { toggleGroupCollapse('project') }}>\n <span className={css.chevron + (topCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt('groups.project')} · {byProject.size}\n </span>\n </button>\n </div>\n {!topCollapsed ? [...byProject.entries()].map(([key, proj]) => {\n const projKey = 'project:' + key\n const projCollapsed = collapsedGroups.has(projKey)\n const subdivided = subdividedProjects.has(key)\n return (\n <div key={projKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!projCollapsed} onClick={() => { toggleGroupCollapse(projKey) }}>\n <span className={css.chevron + (projCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {proj.title} · {proj.skills.length}\n <GroupSummary members={proj.skills.map((skill) => skill.name)} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' className={css.opBtn} onClick={(event) => { event.stopPropagation(); toggleSubdivide(key) }}>\n {subdivided ? tt('groups.merge') : tt('groups.subdivide')}\n </button>\n </span>\n </div>\n {!projCollapsed ? (\n subdivided ? (\n <div className={css.projectNest}>\n {(['project-dsh', 'project-agents'] as const).map((source) => {\n const list = proj.skills.filter((skill) => skill.source === source)\n if (list.length === 0) return null\n const srcKey = projKey + ':' + source\n const srcCollapsed = collapsedGroups.has(srcKey)\n return (\n <div key={srcKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!srcCollapsed} onClick={() => { toggleGroupCollapse(srcKey) }}>\n <span className={css.chevron + (srcCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt(('badge.source.' + source) as 'badge.source.project-dsh' | 'badge.source.project-agents')} · {list.length}\n </span>\n </button>\n </div>\n {!srcCollapsed ? list.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </div>\n )\n })}\n </div>\n ) : proj.skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)\n ) : null}\n </div>\n )\n }) : null}\n </section>\n )\n}\n\nexport function SourcesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, skillView, sourceFilter, origins, sorted, normalized, collapsedGroups, viewNames, sourceCheck, actionNames, checkingSource, syncingSource, batchBusy, busyNames, toggleGroupCollapse, checkSources, requestSync, requestDelete, toggleGroup, enableDisabled } = hub\n\n if (skillView === 'flat') {\n return <>{filterBySource(sorted, sourceFilter, origins).map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}</>\n }\n\n return (\n <>\n <ProjectTree hub={hub} />\n {groupsState !== null && groupsState.collections.length === 0 ? <div className={css.empty}>{tt('groups.noCollections')}</div> : null}\n {groupsState?.collections.map((collection) => {\n const skills = filterBySource(sorted, sourceFilter, origins).filter((skill) => collection.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) =>\n collection.skillNames.includes(record.name)\n && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n && (sourceFilter === 'all' || (origins[record.name] ?? PRIVATE_SOURCE) === sourceFilter))\n const collapsed = collapsedGroups.has('col:' + collection.name)\n const view = groupSwitchView(collection.skillNames, viewNames)\n const check = sourceCheck[collection.name]\n const hasWritable = collection.skillNames.some((name) => actionNames.has(name))\n return (\n <section key={'col:' + collection.name} className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('col:' + collection.name) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + collection.name} target='_blank' rel='noreferrer' onClick={(event) => { event.stopPropagation() }}>{collection.name}</a>\n {' · ' + collection.skillNames.length}\n <GroupSummary members={collection.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <SourceStatusBadge\n check={check}\n checking={checkingSource === collection.name}\n onCheck={() => { void checkSources(collection.name) }}\n />\n {check !== undefined && check.changed && check.updated.length > 0\n ? <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={(event) => { event.stopPropagation(); requestSync(collection.name, check.updated) }}>\n {syncingSource === collection.name ? tt('source.syncing') : tt('source.sync')}\n </button>\n : null}\n {check !== undefined && check.deleted.length > 0\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={(event) => { event.stopPropagation(); requestDelete(collection.name, check.deleted) }}>{tt('source.followDelete')}</button>\n : null}\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={collection.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || collection.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('col:' + collection.name, collection.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n })}\n {(() => {\n // 「个人」组:无来源记录 且 非项目技能(项目技能归项目树)。\n const uncategorized = filterBySource(sorted, sourceFilter, origins).filter((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n if (uncategorized.length === 0) return null\n const collapsed = collapsedGroups.has('uncategorized-source')\n return (\n <section className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('uncategorized-source') }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt('groups.personal')} · {uncategorized.length}\n <GroupSummary members={uncategorized.map((skill) => skill.name)} hub={hub} />\n </span>\n </button>\n </div>\n {!collapsed ? uncategorized.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </section>\n )\n })()}\n </>\n )\n}\n","/**\n * Scenes tab: user tag groups (one card per scene with the tri-state switch\n * and edit entry) plus the new-scene form. Scenes are the user's own\n * enable/disable units (e.g. a Godot scene vs a Java scene); upstream repos\n * are managed in the sources tab.\n */\n\nimport type { JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { groupSwitchView } from '../grouping.ts'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function ScenesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, sorted, normalized, collapsedGroups, viewNames, actionNames, batchBusy, busyNames, newTagName, setNewTagName, tagBusy, createTag, toggleGroupCollapse, toggleGroup, setEditingTag, setEditName, setMembersDraft, setEditSearch, enableDisabled } = hub\n return (\n <>\n <form className={css.form} onSubmit={(event) => { void createTag(event) }}>\n <div className={css.buttons}>\n <input\n className={css.input + ' ' + css.grow}\n value={newTagName}\n onChange={(event) => { setNewTagName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='submit' className={css.button + ' ' + css.primary} disabled={tagBusy || newTagName.trim() === ''}>{tt('groups.new')}</button>\n </div>\n </form>\n\n {groupsState !== null && groupsState.tags.length === 0 ? <div className={css.empty}>{tt('groups.empty')}</div> : null}\n {groupsState?.tags.map((tag) => {\n const skills = sorted.filter((skill) => tag.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) => tag.skillNames.includes(record.name) && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized)))\n const collapsed = collapsedGroups.has('tag:' + tag.id)\n const view = groupSwitchView(tag.skillNames, viewNames)\n const hasWritable = tag.skillNames.some((name) => actionNames.has(name))\n return (\n <section key={'tag:' + tag.id} className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('tag:' + tag.id) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tag.name} · {tag.skillNames.length}\n <GroupSummary members={tag.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={tag.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || tag.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('tag:' + tag.id, tag.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n <button type='button' className={css.opBtn} onClick={() => { setEditingTag(tag); setEditName(tag.name); setMembersDraft(new Set(tag.skillNames)); setEditSearch('') }}>{tt('groups.edit')}</button>\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n })}\n </>\n )\n}\n","/**\n * Built-in market catalog: well-known skill repos shown on the market tab so\n * users can browse and install without knowing repo URLs.\n * Only the repo slug lives here; adding goes through the normal\n * market-source route and records upstream tracking like any manual source.\n */\n\nimport type { HubKey } from './locales.ts'\n\nexport interface MarketCatalogEntry {\n repo: string\n /** locales.ts key for the one-line description. */\n descriptionKey: HubKey\n}\n\n/** 默认市场目录:精选技能仓库(顺序即展示顺序)。 */\nexport const MARKET_CATALOG: readonly MarketCatalogEntry[] = [\n { repo: 'anthropics/skills', descriptionKey: 'market.catalog.anthropics' },\n { repo: 'obra/superpowers', descriptionKey: 'market.catalog.superpowers' },\n { repo: 'mattpocock/skills', descriptionKey: 'market.catalog.mattpocock' },\n { repo: 'nexu-io/open-design', descriptionKey: 'market.catalog.openDesign' },\n]\n","/**\n * Shared dialog family for the panel: one overlay shell plus the specific\n * dialogs (group-close conflict, sync/delete confirm, branch picker, and\n * market sync selection). Every dialog closes on outside click and keeps\n * the same role/aria shell; the panel owns all dialog state.\n */\n\nimport { useEffect, type JSX, type ReactNode } from 'react'\nimport type { CollectionGroup, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport { groupNamesOf } from '../grouping.ts'\nimport css from './panel.module.css'\n\n/** A group-close conflict waiting for the user's decision. */\nexport interface ConflictDialogState {\n /** Group key: 'tag:<id>' or 'col:<name>'. */\n key: string\n name: string\n /** Conflicting skill names (enabled here and in other groups). */\n conflicts: string[]\n}\n\n/** A destructive/sync confirmation waiting for the user's decision. */\nexport interface ConfirmDialogState {\n kind: 'sync' | 'delete'\n repo: string\n /** Skills the action applies to. */\n skills: string[]\n}\n\n/** Branch picker shown when a repo has no release and no pinned ref. */\nexport interface BranchChoiceState {\n repo: string\n branches: string[]\n selected: string\n}\n\n/** Post-sync skill update dialog: which tracked skills to refresh. */\nexport interface MarketSyncDialogState {\n repo: string\n ref: string\n skills: string[]\n selected: ReadonlySet<string>\n}\n\n/** Overlay + centered alert-dialog shell; outside click or Escape cancels. */\nfunction DialogShell(props: { onClose: () => void; children: ReactNode }): JSX.Element {\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') props.onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => { window.removeEventListener('keydown', onKey) }\n })\n return (\n <div className={css.dialogOverlay} onClick={props.onClose}>\n <div className={css.dialog} role='alertdialog' aria-modal='true' onClick={(event) => { event.stopPropagation() }}>\n {props.children}\n </div>\n </div>\n )\n}\n\n/** Simple confirm dialog: title + text + optional skill list + cancel/confirm. */\nexport function ConfirmDialog(props: {\n title: string\n text: string\n /** Optional skill names listed between the text and the buttons. */\n items?: readonly string[]\n confirmLabel: string\n /** Danger-styled confirm button (destructive actions). */\n danger?: boolean\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { title, text, items, confirmLabel, danger, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{title}</h3>\n <p className={css.dialogText}>{text}</p>\n {items !== undefined ? (\n <ul className={css.dialogList}>\n {items.map((name) => <li key={name}><span className={css.rowNameText}>{name}</span></li>)}\n </ul>\n ) : null}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + (danger === true ? ' ' + css.danger : ' ' + css.primary)} onClick={onConfirm}>\n {confirmLabel}\n </button>\n </div>\n </DialogShell>\n )\n}\n\n/** Group-close conflict: which skills stay on, and which other groups also enable them. */\nexport function ConflictDialog(props: {\n dialog: ConflictDialogState\n tags: readonly SkillTag[]\n collections: readonly CollectionGroup[]\n onClose: () => void\n onKeepOn: () => void\n onCloseAll: () => void\n}): JSX.Element {\n const { dialog, tags, collections, onClose, onKeepOn, onCloseAll } = props\n return (\n <DialogShell onClose={onClose}>\n <h3 className={css.dialogTitle}>{tt('groups.conflictTitle')}</h3>\n <p className={css.dialogText}>{tt('groups.conflictText')}</p>\n <ul className={css.dialogList}>\n {dialog.conflicts.map((name) => (\n <li key={name}>\n <span className={css.rowNameText}>{name}</span>\n {' — ' + groupNamesOf(name, [...tags], [...collections]).join(', ')}\n </li>\n ))}\n </ul>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onKeepOn}>{tt('groups.keepOn')}</button>\n <button type='button' className={css.button + ' ' + css.primary} onClick={onCloseAll}>{tt('groups.closeAll')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Branch picker for a repo without releases (pins the ref, then rescans). */\nexport function BranchChoiceDialog(props: {\n choice: BranchChoiceState\n busy: boolean\n onSelect: (branch: string) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { choice, busy, onSelect, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.branchTitle')}</h3>\n <p className={css.dialogText}>{tt('market.branchHint')}</p>\n <select className={css.select + ' ' + css.dialogSelect} value={choice.selected}\n onChange={(event) => { onSelect(event.target.value) }}>\n {choice.branches.map((branch) => <option key={branch} value={branch}>{branch}</option>)}\n </select>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy} onClick={onConfirm}>{tt('market.branchConfirm')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Post-sync selection: which tracked skills to batch-update to the new version. */\nexport function MarketSyncDialog(props: {\n dialog: MarketSyncDialogState\n busy: boolean\n onToggle: (name: string, checked: boolean) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { dialog, busy, onToggle, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.syncTitle')}</h3>\n <p className={css.dialogText}>{tt('market.syncText', { ref: dialog.ref })}</p>\n {dialog.skills.length === 0 ? (\n <p className={css.dialogText}>{tt('market.syncNone')}</p>\n ) : (\n <div className={css.dialogList}>\n {dialog.skills.map((name) => (\n <label key={name} className={css.dialogRow}>\n <input type='checkbox' checked={dialog.selected.has(name)}\n onChange={(event) => { onToggle(name, event.target.checked) }} />\n <span className={css.rowNameText}>{name}</span>\n </label>\n ))}\n </div>\n )}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('market.syncCancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy || dialog.skills.length === 0} onClick={onConfirm}>\n {busy ? tt('source.syncing') : tt('source.sync')}\n </button>\n </div>\n </DialogShell>\n )\n}\n","/**\n * Market tab: one unified market list — built-in catalog entries (add\n * button while not yet added) and the user's market sources (full state\n * badges + actions once added, plus custom sources), with check-all and\n * update-all actions and the repo scan result with the importable checklist.\n */\n\nimport { Fragment, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { MARKET_CATALOG } from '../market-catalog.ts'\nimport type { MarketSourceRecord } from '../../protocol.ts'\nimport { ConfirmDialog } from './dialogs.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** Compact byte size for repo preview rows. */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return bytes + ' B'\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n return (bytes / 1024 / 1024).toFixed(1) + ' MB'\n}\n\nexport function MarketView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { marketState, marketCheck, sourceCheck, sourcesState, repoDiscoverState, scanningRepo, repoSelected, setRepoSelected, repoImporting, repoResult, newSourceName, setNewSourceName, syncingMarket, tagBusy, addSource, addMarketSource, removeMarketSource, scanRepo, checkMarket, checkSources, syncMarketSource, toggleRepoSelected, importRepo, updateAllDialog, setUpdateAllDialog, updateAll } = hub\n /** 有可更新技能的来源(全部更新按钮与确认列表共用)。 */\n const updatableRepos = Object.entries(sourceCheck).filter(([, check]) => check.changed && check.updated.length > 0)\n\n /** 一个已添加来源的完整行:状态徽章 + 操作按钮。 */\n const sourceRow = (record: MarketSourceRecord): JSX.Element => {\n const releaseCheck = marketCheck[record.repo]\n const skillCheck = sourceCheck[record.repo]\n const installedCount = sourcesState?.sources.find((source) => source.repo === record.repo)?.skills.length ?? 0\n const scanning = scanningRepo === record.repo\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + record.repo} target='_blank' rel='noreferrer'>{record.repo}</a>\n {record.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{record.ref}</span> : null}\n {installedCount > 0 ? <span className={css.badge + ' ' + css.badgeCount}>{tt('market.installed', { count: installedCount })}</span> : null}\n {skillCheck?.changed === true && skillCheck.updated.length > 0\n ? <span className={css.badge + ' ' + css.statusUpdated}>{tt('market.updatable', { count: skillCheck.updated.length })}</span>\n : null}\n {skillCheck !== undefined && skillCheck.deleted.length > 0\n ? <span className={css.badge + ' ' + css.statusError}>{tt('market.deletedUpstream', { count: skillCheck.deleted.length })}</span>\n : null}\n {releaseCheck?.updateAvailable === true\n ? <span className={css.badge + ' ' + css.statusUpdated}>{releaseCheck.latestTag !== undefined ? tt('market.newRelease', { version: releaseCheck.latestTag }) : tt('market.updated')}</span>\n : null}\n </div>\n </div>\n <button type='button' className={css.opBtn} disabled={scanning} onClick={() => { void checkMarket() }}>{tt('market.check')}</button>\n <button type='button' className={css.opBtn + (releaseCheck?.updateAvailable === true ? ' ' + css.opDanger : '')} disabled={syncingMarket === record.repo} onClick={() => { void syncMarketSource(record.repo) }}>\n {syncingMarket === record.repo ? tt('market.syncing') : tt('market.sync')}\n </button>\n <button type='button' className={css.opBtn} disabled={scanning} onClick={() => { void scanRepo(record.repo) }}>\n {scanning ? tt('market.scanning') : tt('market.scan')}\n </button>\n <button type='button' className={css.opBtn} disabled={tagBusy} title={tt('market.removeHint')} onClick={() => { void removeMarketSource(record.repo) }}>{tt('market.deleteSource')}</button>\n </div>\n )\n }\n\n // 统一列表:内置目录(未添加 → 描述+添加按钮;已添加 → 完整行)在前,\n // 自定义市场源(不在内置目录里)随后。同一个仓库不会出现两次。\n const rows: Array<{ key: string; element: JSX.Element }> = []\n for (const entry of MARKET_CATALOG) {\n const record = marketState.repos.find((item) => item.repo === entry.repo)\n if (record !== undefined) {\n rows.push({ key: entry.repo, element: sourceRow(record) })\n } else {\n const busy = scanningRepo !== null || tagBusy\n rows.push({\n key: entry.repo,\n element: (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + entry.repo} target='_blank' rel='noreferrer'>{entry.repo}</a>\n </div>\n <div className={css.rowDesc}>{tt(entry.descriptionKey)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={busy} onClick={() => { void addSource(entry.repo) }}>{tt('market.add')}</button>\n </div>\n ),\n })\n }\n }\n for (const record of marketState.repos) {\n if (MARKET_CATALOG.some((entry) => entry.repo === record.repo)) continue\n rows.push({ key: record.repo, element: sourceRow(record) })\n }\n const unaddedCatalog = MARKET_CATALOG.filter((entry) => !marketState.repos.some((record) => record.repo === entry.repo))\n\n return (\n <>\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('market.title')}</span>\n <button type='button' className={css.opBtn} onClick={() => { void checkSources(); void checkMarket() }}>{tt('market.checkAll')}</button>\n <button\n type='button'\n className={css.opBtn + (updatableRepos.length > 0 ? ' ' + css.opDanger : '')}\n disabled={updatableRepos.length === 0 || tagBusy}\n onClick={() => { setUpdateAllDialog(true) }}\n >{tt('market.updateAll')}</button>\n </div>\n <div className={css.buttons + ' ' + css.actionsPadded}>\n <input\n className={css.input + ' ' + css.grow}\n value={newSourceName}\n onChange={(event) => { setNewSourceName(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') { event.preventDefault(); void addMarketSource() } }}\n placeholder={tt('market.addPlaceholder')}\n />\n <button type='button' className={css.button + ' ' + css.primary} disabled={newSourceName.trim() === ''} onClick={() => { void addMarketSource() }}>{tt('market.addSource')}</button>\n </div>\n {unaddedCatalog.length > 0 ? <p className={css.hintLine + ' ' + css.hintPadded}>{tt('market.catalogHint')}</p> : null}\n\n {marketState.status === 'loading' ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n {marketState.status !== 'loading' && rows.length === 0 ? <div className={css.empty}>{tt('market.noSources')}</div> : null}\n {marketState.status !== 'loading' ? rows.map((row) => <Fragment key={row.key}>{row.element}</Fragment>) : null}\n </section>\n {repoDiscoverState.status === 'scanning' ? <div className={css.empty}>{tt('market.scanning')}</div> : null}\n {repoDiscoverState.status === 'error' ? <div className={css.errorBanner}>{repoDiscoverState.message}</div> : null}\n {repoDiscoverState.status === 'ready' ? (() => {\n const entries = repoDiscoverState.data.entries\n const selected = entries.filter((entry) => repoSelected.has(entry.path) && !entry.existing)\n return (\n <>\n <p className={css.hintLine + ' ' + css.hintInline}>{tt('repo.ready', { count: entries.length })}</p>\n {entries.length === 0 ? <div className={css.empty}>{tt('repo.empty')}</div> : (\n <>\n <div className={css.buttons + ' ' + css.actionsBottom}>\n <button type='button' className={css.button} onClick={() => { setRepoSelected(new Set(entries.filter((entry) => !entry.existing).map((entry) => entry.path))) }}>{tt('repo.selectAll')}</button>\n <button type='button' className={css.button} onClick={() => { setRepoSelected(new Set()) }}>{tt('repo.clearAll')}</button>\n </div>\n {(['skills', 'design-templates'] as const).map((root) => {\n const rootEntries = entries.filter((entry) => entry.root === root)\n if (rootEntries.length === 0) return null\n return (\n <div key={root} className={css.section}>\n <div className={css.sectionTitle}>{root === 'skills' ? tt('repo.root.skills') : tt('repo.root.designTemplates')}</div>\n {rootEntries.map((entry) => (\n <label key={entry.path} className={css.row + (entry.existing ? ' ' + css.rowMuted : '')}>\n <input\n type='checkbox'\n checked={repoSelected.has(entry.path)}\n disabled={entry.existing}\n onChange={(event) => { toggleRepoSelected(entry.path, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{entry.dir} · {tt('repo.files', { count: entry.fileCount, size: formatBytes(entry.totalBytes) })}</div>\n </div>\n {entry.existing\n ? <span className={css.badge + ' ' + css.badgeReadonly}>{tt('repo.existing')}</span>\n : <span className={css.badge + ' ' + css.badgeSource}>{entry.origin}</span>}\n </label>\n ))}\n </div>\n )\n })}\n <button type='button' className={css.button + ' ' + css.primary} disabled={selected.length === 0 || repoImporting} onClick={() => { void importRepo() }}>{repoImporting ? tt('repo.importing') : tt('repo.import', { count: selected.length })}</button>\n </>\n )}\n </>\n )\n })() : null}\n {repoResult !== null ? <div className={css.formSuccess + ' ' + css.actionsTop}>{tt('repo.imported', { count: repoResult.imported.length })} · {tt('repo.skippedExisting', { count: repoResult.skipped.length })} · {tt('repo.failed', { count: repoResult.failed.length })}</div> : null}\n\n {updateAllDialog ? (\n <ConfirmDialog\n title={tt('market.updateAllConfirmTitle')}\n text={tt('market.updateAllConfirmText')}\n items={updatableRepos.map(([repo, check]) => tt('market.updateAllItem', { repo, count: check.updated.length }))}\n confirmLabel={tt('market.updateAll')}\n danger\n onCancel={() => { setUpdateAllDialog(false) }}\n onConfirm={() => { void updateAll() }}\n />\n ) : null}\n </>\n )\n}\n","/**\n * useSkillHub — the panel's state owner. Everything the skill hub panel\n * knows (catalog, groups, sources, market, dialogs, drafts) plus every\n * async flow lives here; the panel itself only renders. All hooks run\n * unconditionally at the top, so the panel may early-return for the detail\n * and tag-editor views without violating the rules of hooks.\n */\n\nimport { useCallback, useEffect, useMemo, useState, type FormEvent } from 'react'\nimport type {\n CatalogResponse,\n CatalogSkill,\n DisabledSkill,\n GroupsResponse,\n HubConfig,\n MarketCheckResponse,\n MarketSourceRecord,\n RepoDiscoverResponse,\n RepoImportResponse,\n SkillDetail,\n SkillTag,\n SourceCheckResult,\n SourcesResponse,\n UpdateCheckResponse,\n WritableRoot,\n} from '../../protocol.ts'\nimport type { SkillHubApi } from '../api.ts'\nimport { errorMessage, tt } from '../helpers.ts'\nimport { conflictsOnClose, isProjectSource, PRIVATE_SOURCE, sortSkills, type SortKey, type GroupSwitchState } from '../grouping.ts'\nimport type { BranchChoiceState, ConfirmDialogState, ConflictDialogState, MarketSyncDialogState } from './dialogs.tsx'\n\n/** Catalog poll interval while the panel is mounted (the provider watcher feeds this). */\nconst POLL_MS = 5000\n/** Relaxed poll for slower-changing data (stats, groups, sources, config). */\nconst SLOW_POLL_MS = 60_000\n\n/** localStorage key of the last daily auto-check timestamp (survives sessions). */\nconst AUTO_CHECK_KEY = 'skill-hub.last-auto-check'\n/** Daily auto-check interval: at most one network round per day. */\nconst AUTO_CHECK_INTERVAL_MS = 24 * 60 * 60_000\n\n/** Whether the daily auto-check should run now (first visit or ≥24h since the last). */\nfunction shouldAutoCheck(): boolean {\n try {\n const raw = localStorage.getItem(AUTO_CHECK_KEY)\n const last = raw === null ? NaN : Number(raw)\n if (!Number.isFinite(last)) return true\n return Date.now() - last >= AUTO_CHECK_INTERVAL_MS\n } catch {\n // 无 localStorage(隐私模式等):每次打开都尝试,服务端 5 分钟节流兜底。\n return true\n }\n}\n\n/** Record that the daily auto-check ran. */\nfunction markAutoChecked(): void {\n try {\n localStorage.setItem(AUTO_CHECK_KEY, String(Date.now()))\n } catch {\n // 无 localStorage:不记录,下次打开仍会尝试(服务端节流兜底)。\n }\n}\n\n/** One-shot self-update check state. */\ntype UpdateState =\n | { status: 'idle' }\n | { status: 'checking' }\n | { status: 'ready'; data: UpdateCheckResponse }\n | { status: 'error'; message: string }\n\n/** Repo scanner/import state (drives the market source preview). */\ntype RepoDiscoverState =\n | { status: 'idle' }\n | { status: 'scanning' }\n | { status: 'ready'; data: RepoDiscoverResponse }\n | { status: 'error'; message: string }\n\n/** Market sources list state. */\ntype MarketState = { status: 'loading' | 'ready' | 'error'; repos: MarketSourceRecord[] }\n\n/** One market source's update-check outcome. */\ntype MarketCheckResult = MarketCheckResponse['results'][number]\n\n/** The hook's result: the panel's complete state + action surface. */\nexport type SkillHubState = ReturnType<typeof useSkillHub>\n\nexport function useSkillHub(api: SkillHubApi) {\n const [catalog, setCatalog] = useState<CatalogResponse | null>(null)\n const [loading, setLoading] = useState(true)\n const [loadError, setLoadError] = useState<string | null>(null)\n /** Green success banner (create finished); shown outside the closing form. */\n const [successBanner, setSuccessBanner] = useState<string | null>(null)\n const [updateState, setUpdateState] = useState<UpdateState>({ status: 'idle' })\n const [repoDiscoverState, setRepoDiscoverState] = useState<RepoDiscoverState>({ status: 'idle' })\n /** Market repo currently being scanned (null when idle); per-row busy state. */\n const [scanningRepo, setScanningRepo] = useState<string | null>(null)\n const [repoSelected, setRepoSelected] = useState<ReadonlySet<string>>(new Set())\n const [repoImporting, setRepoImporting] = useState(false)\n const [repoResult, setRepoResult] = useState<RepoImportResponse | null>(null)\n const [search, setSearch] = useState('')\n /** 工作区(项目)路径;空 = 只看用户级技能。 */\n const [workspace, setWorkspace] = useState('')\n const [detail, setDetail] = useState<SkillDetail | null>(null)\n const [detailLoading, setDetailLoading] = useState(false)\n const [busyNames, setBusyNames] = useState<ReadonlySet<string>>(new Set())\n const [batchBusy, setBatchBusy] = useState(false)\n const [showForm, setShowForm] = useState(false)\n const [formName, setFormName] = useState('')\n const [formDesc, setFormDesc] = useState('')\n const [formRoot, setFormRoot] = useState<WritableRoot>('user-dsh')\n const [formBusy, setFormBusy] = useState(false)\n const [formMessage, setFormMessage] = useState<{ kind: 'error' | 'success'; text: string } | null>(null)\n const [uses, setUses] = useState<ReadonlyMap<string, { count: number; lastUsed?: number }>>(new Map())\n const [hubConfig, setHubConfig] = useState<HubConfig | null>(null)\n const [tab, setTab] = useState<'sources' | 'scenes' | 'market'>('sources')\n const [skillView, setSkillView] = useState<'flat' | 'groups'>('groups')\n const [sourceFilter, setSourceFilter] = useState('all')\n const [sortKey, setSortKey] = useState<SortKey>('name')\n const [marketState, setMarketState] = useState<MarketState>({ status: 'loading', repos: [] })\n const [marketCheck, setMarketCheck] = useState<Readonly<Record<string, MarketCheckResult>>>({})\n const [branchChoice, setBranchChoice] = useState<BranchChoiceState | null>(null)\n const [branchBusy, setBranchBusy] = useState(false)\n const [marketSyncDialog, setMarketSyncDialog] = useState<MarketSyncDialogState | null>(null)\n const [syncingMarket, setSyncingMarket] = useState<string | null>(null)\n const [syncBusy, setSyncBusy] = useState(false)\n const [newSourceName, setNewSourceName] = useState('')\n const [groupsState, setGroupsState] = useState<GroupsResponse | null>(null)\n const [sourcesState, setSourcesState] = useState<SourcesResponse | null>(null)\n const [sourceCheck, setSourceCheck] = useState<Readonly<Record<string, SourceCheckResult>>>({})\n const [checkingSource, setCheckingSource] = useState<string | null>(null)\n const [syncingSource, setSyncingSource] = useState<string | null>(null)\n const [conflictDialog, setConflictDialog] = useState<ConflictDialogState | null>(null)\n const [confirmDialog, setConfirmDialog] = useState<ConfirmDialogState | null>(null)\n const [deleteSkillDialog, setDeleteSkillDialog] = useState<string | null>(null)\n const [confirmClearTrash, setConfirmClearTrash] = useState(false)\n /** 「全部更新」确认对话框(市场 tab)。 */\n const [updateAllDialog, setUpdateAllDialog] = useState(false)\n const [editingTag, setEditingTag] = useState<SkillTag | null>(null)\n const [editName, setEditName] = useState('')\n const [membersDraft, setMembersDraft] = useState<ReadonlySet<string>>(new Set())\n const [newTagName, setNewTagName] = useState('')\n const [tagBusy, setTagBusy] = useState(false)\n const [editSearch, setEditSearch] = useState('')\n /** 分组视图里收起的分组(key 为 tag:<id>、col:<name> 或 project 树键)。 */\n const [collapsedGroups, setCollapsedGroups] = useState<ReadonlySet<string>>(new Set())\n /** 项目级三级树里已细分(按 .dsh/.agents)的项目键。 */\n const [subdividedProjects, setSubdividedProjects] = useState<ReadonlySet<string>>(new Set())\n const [showLegend, setShowLegend] = useState(false)\n\n const toggleGroupCollapse = useCallback((key: string): void => {\n setCollapsedGroups((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const toggleSubdivide = useCallback((key: string): void => {\n setSubdividedProjects((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n const next = await api.catalog(workspace !== '' ? { cwd: workspace } : undefined)\n setCatalog(next)\n setLoadError(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setLoading(false)\n }\n }, [api, workspace])\n\n const loadUses = useCallback(async (): Promise<void> => {\n try {\n const result = await api.stats()\n if (result.available) setUses(new Map(result.stats.map((stat) => [stat.name, { count: stat.count, ...(stat.lastUsed !== undefined ? { lastUsed: stat.lastUsed } : {}) }])))\n } catch {\n // Invocation counts are best-effort; a stats failure must not disturb the catalog.\n }\n }, [api])\n\n const loadConfig = useCallback(async (): Promise<void> => {\n try {\n setHubConfig((await api.config()).config)\n } catch {\n // Dot colors are cosmetic; a config failure falls back to the defaults.\n }\n }, [api])\n\n /** Check the hub's own GitHub release once, and again on demand. */\n const checkUpdate = useCallback(async (): Promise<void> => {\n setUpdateState({ status: 'checking' })\n try {\n setUpdateState({ status: 'ready', data: await api.updateCheck() })\n } catch (error) {\n setUpdateState({ status: 'error', message: errorMessage(error) })\n }\n }, [api])\n\n /** 加载用户 tag 分组 + 系统集合组 + origin 映射。 */\n const loadGroups = useCallback(async (): Promise<void> => {\n try {\n setGroupsState(await api.groups())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载来源记录 + 回收站。 */\n const loadSources = useCallback(async (): Promise<void> => {\n try {\n setSourcesState(await api.sources())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载市场源列表。 */\n const loadMarket = useCallback(async (): Promise<void> => {\n try {\n const next = await api.market()\n setMarketState({ status: 'ready', repos: next.repos })\n } catch (error) {\n setMarketState({ status: 'error', repos: [] })\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 把最新的 tag 列表合并进 groups 状态(tags 以外的字段保持原样)。 */\n const applyTags = useCallback((tags: SkillTag[]): void => {\n setGroupsState((previous) => previous === null\n ? { ok: true, tags, collections: [], origins: {} }\n : { ...previous, tags })\n }, [])\n\n // 初始全量加载 + 双速轮询:目录是「活视图」(文件变化要 5 秒内可见),\n // 统计/分组/来源/配置变化慢,60 秒一次足够;写操作本身会触发即时刷新。\n // 更新检查、来源检查、市场检查全部改为手动按钮触发,打开面板不再自动\n // 打三路 GitHub 请求。\n useEffect(() => {\n void load()\n void loadUses()\n void loadGroups()\n void loadSources()\n void loadConfig()\n const fast = window.setInterval(() => { void load() }, POLL_MS)\n const slow = window.setInterval(() => { void loadUses(); void loadGroups(); void loadSources(); void loadConfig() }, SLOW_POLL_MS)\n return () => { window.clearInterval(fast); window.clearInterval(slow) }\n }, [load, loadUses, loadGroups, loadSources, loadConfig])\n\n const openDetail = useCallback(async (name: string): Promise<void> => {\n setDetailLoading(true)\n setLoadError(null)\n try {\n setDetail(await api.skill(name, workspace !== '' ? { cwd: workspace } : undefined))\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setDetailLoading(false)\n }\n }, [api, workspace])\n\n const toggle = useCallback(async (skill: CatalogSkill, enabled: boolean): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(skill.name))\n setLoadError(null)\n try {\n const next = await api.toggle(skill.name, enabled)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(skill.name)\n return next\n })\n }\n }, [api])\n\n const enableDisabled = useCallback(async (record: DisabledSkill): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(record.name))\n setLoadError(null)\n try {\n const next = await api.toggle(record.name, true)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(record.name)\n return next\n })\n }\n }, [api])\n\n /** Toggle an explicit name set in one write (enables disabled members too). */\n const batchToggleNames = useCallback(async (names: string[], enabled: boolean): Promise<void> => {\n if (names.length === 0) return\n setBatchBusy(true)\n setLoadError(null)\n try {\n const next = await api.toggleBatch(names, enabled)\n setCatalog(next.catalog)\n if (next.failures.length > 0) {\n setLoadError('toggle-batch: ' + next.failures.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBatchBusy(false)\n }\n }, [api])\n\n // -------------------------------------------------------- group switches\n\n /** 所有分组:key → 成员名(tag 与来源集合)。 */\n const groupMap = useCallback((): Map<string, string[]> => {\n const map = new Map<string, string[]>()\n for (const tag of groupsState?.tags ?? []) map.set('tag:' + tag.id, tag.skillNames)\n for (const collection of groupsState?.collections ?? []) map.set('col:' + collection.name, collection.skillNames)\n return map\n }, [groupsState])\n\n /** 当前启用且可写的技能名(组开关只作用于它们)。 */\n const actionNames = useMemo(() => new Set((catalog?.skills ?? []).filter((skill) => skill.writable).map((skill) => skill.name)), [catalog])\n\n /** 当前启用的全部技能名(含只读,用于派生开关状态)。 */\n const viewNames = useMemo(() => new Set((catalog?.skills ?? []).map((skill) => skill.name)), [catalog])\n\n /**\n * Toggle a whole group via its tri-state switch. Closing with members that\n * are enabled in other groups opens the conflict dialog instead.\n */\n const toggleGroup = useCallback((key: string, name: string, view: GroupSwitchState): void => {\n const members = groupMap().get(key) ?? []\n if (members.length === 0) return\n if (view === 'off') {\n void batchToggleNames(members, true)\n return\n }\n const others = [...groupMap().entries()].filter(([otherKey]) => otherKey !== key).map(([, memberNames]) => ({ members: memberNames }))\n const conflicts = conflictsOnClose(members, actionNames, others)\n if (conflicts.length > 0) {\n setConflictDialog({ key, name, conflicts })\n } else {\n void batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n }\n }, [groupMap, actionNames, batchToggleNames])\n\n /** Resolve the open conflict dialog. */\n const resolveConflict = useCallback(async (closeAll: boolean): Promise<void> => {\n const dialog = conflictDialog\n if (dialog === null) return\n setConflictDialog(null)\n const members = groupMap().get(dialog.key) ?? []\n if (closeAll) {\n await batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n } else {\n await batchToggleNames(\n members.filter((member) => actionNames.has(member) && !dialog.conflicts.includes(member)),\n false,\n )\n }\n }, [conflictDialog, groupMap, actionNames, batchToggleNames])\n\n /** Dismiss a confirm dialog and run the pending source action. */\n const runConfirmed = useCallback(async (): Promise<void> => {\n const dialog = confirmDialog\n if (dialog === null) return\n setConfirmDialog(null)\n if (dialog.kind === 'sync') {\n setSyncingSource(dialog.repo)\n setLoadError(null)\n try {\n const result = await api.syncSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n if (result.failed.length > 0) {\n setLoadError('sync: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingSource(null)\n }\n } else {\n setLoadError(null)\n try {\n await api.confirmDeleteSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }\n }, [confirmDialog, api, load, loadGroups, loadSources])\n\n // ---------------------------------------------------------- source ops\n\n /** 检查全部来源的上游更新(服务端 5 分钟节流)。 */\n const checkSources = useCallback(async (repo?: string): Promise<void> => {\n setCheckingSource(repo ?? 'all')\n setLoadError(null)\n try {\n const result = await api.checkSources(repo)\n const next: Record<string, SourceCheckResult> = { ...sourceCheck }\n for (const item of result.results) next[item.repo] = item\n setSourceCheck(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setCheckingSource(null)\n }\n }, [api, sourceCheck])\n\n /** 请求同步某个来源的所选技能(弹确认,因为会覆盖本地修改)。 */\n const requestSync = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'sync', repo, skills })\n }, [])\n\n /** 请求跟进上游删除(弹确认,移入回收站)。 */\n const requestDelete = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'delete', repo, skills })\n }, [])\n\n /** 从回收站恢复一个技能。 */\n const restoreTrash = useCallback(async (name: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.restoreSource(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadGroups, loadSources])\n\n /** 确认后永久删除回收站里的全部技能。 */\n const clearTrash = useCallback(async (): Promise<void> => {\n setConfirmClearTrash(false)\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.clearTrash()\n if (result.failed.length > 0) {\n setLoadError('clear trash: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n await Promise.all([load(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadSources])\n\n /** 打开单个技能的删除确认(移入回收站,可恢复)。 */\n const requestDeleteSkill = useCallback((name: string): void => {\n setDeleteSkillDialog(name)\n }, [])\n\n /** 执行删除确认后的回收站迁移。 */\n const runDeleteSkill = useCallback(async (): Promise<void> => {\n const name = deleteSkillDialog\n if (name === null) return\n setDeleteSkillDialog(null)\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.deleteSkill(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, deleteSkillDialog, load, loadGroups, loadSources])\n\n // ----------------------------------------------------------- tag editing\n\n /** 新建一个空 tag 分组。 */\n const createTag = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n const name = newTagName.trim()\n if (name === '') return\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.saveTag({ name }))\n setNewTagName('')\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags, newTagName])\n\n /** 删除一个 tag 分组(不影响技能文件)。 */\n const deleteTag = useCallback(async (id: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.deleteTag(id))\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n /** 重命名 tag,或保存成员勾选后回到列表。 */\n const saveTag = useCallback(async (id: string, name: string, memberNames: string[] | null): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const safeName = name.trim()\n let tags: SkillTag[] | null = null\n if (safeName !== '') tags = await api.saveTag({ id, name: safeName })\n if (memberNames !== null) tags = await api.setTagMembers(id, memberNames)\n if (tags === null) return\n applyTags(tags)\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n // -------------------------------------------------------------- market\n\n /** 添加一个市场源(内置市场目录与手动输入共用),并立即扫描它。 */\n const addSource = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setLoadError(null)\n try {\n const result = await api.addMarketSource(value)\n setMarketState({ status: 'ready', repos: result.repos })\n setNewSourceName('')\n setRepoResult(null)\n setRepoSelected(new Set())\n // 用服务端归一化后的 slug 扫描(URL/owner@repo 输入都能对上记录)。\n const slug = result.repos[result.repos.length - 1].repo\n setScanningRepo(slug)\n setRepoDiscoverState({ status: 'scanning' })\n try {\n const data = await api.repoDiscover(slug)\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 手动输入框的添加动作。 */\n const addMarketSource = useCallback(async (): Promise<void> => {\n await addSource(newSourceName)\n }, [addSource, newSourceName])\n\n /** 删除一个市场源(不影响已装技能)。 */\n const removeMarketSource = useCallback(async (repo: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.removeMarketSource(repo)\n setMarketState({ status: 'ready', repos: result.repos })\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api])\n\n /** 扫描一个市场源(或手动输入)的仓库。 */\n const scanRepo = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setRepoResult(null)\n setRepoSelected(new Set())\n setScanningRepo(value)\n setRepoDiscoverState({ status: 'scanning' })\n setLoadError(null)\n try {\n const data = await api.repoDiscover(value)\n if (data.ref === null) {\n // 无 release 且未定版:让用户选分支(默认第一项,通常是 main)。\n setBranchChoice({ repo: data.repo, branches: data.branches ?? [], selected: (data.branches ?? [])[0] ?? 'main' })\n setRepoDiscoverState({ status: 'idle' })\n return\n }\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n }, [api])\n\n /** 确认分支选择:持久化 ref 后重新扫描。 */\n const confirmBranchChoice = useCallback(async (): Promise<void> => {\n if (branchChoice === null) return\n setBranchBusy(true)\n setLoadError(null)\n try {\n await api.setMarketSourceRef(branchChoice.repo, branchChoice.selected)\n setBranchChoice(null)\n await scanRepo(branchChoice.repo)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBranchBusy(false)\n }\n }, [api, branchChoice, scanRepo])\n\n /** Toggle one repo preview row. */\n const toggleRepoSelected = useCallback((path: string, checked: boolean): void => {\n setRepoSelected((previous) => {\n const next = new Set(previous)\n if (checked) next.add(path)\n else next.delete(path)\n return next\n })\n }, [])\n\n /** Import every checked, non-existing repo skill, then refresh the hub. */\n const importRepo = useCallback(async (): Promise<void> => {\n if (repoDiscoverState.status !== 'ready') return\n setRepoImporting(true)\n setRepoResult(null)\n setLoadError(null)\n try {\n const result = await api.repoImport(repoDiscoverState.data.repo, [...repoSelected], repoDiscoverState.data.ref ?? undefined)\n setRepoResult(result)\n await Promise.all([load(), loadMarket(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setRepoImporting(false)\n }\n }, [api, repoDiscoverState, repoSelected, load, loadMarket, loadGroups, loadSources])\n\n /** 检查所有市场源的上游更新(服务端节流)。 */\n const checkMarket = useCallback(async (): Promise<void> => {\n try {\n const result = await api.marketCheck()\n const next: Record<string, MarketCheckResult> = {}\n for (const item of result.results) next[item.repo] = item\n setMarketCheck(next)\n } catch {\n // 检查失败不打扰市场列表本身。\n }\n }, [api])\n\n /** 市场源同步:版本对齐后询问是否批量更新本地技能。 */\n const syncMarketSource = useCallback(async (repo: string): Promise<void> => {\n setSyncingMarket(repo)\n setLoadError(null)\n try {\n const result = await api.marketSync(repo)\n setMarketSyncDialog({ repo: result.repo, ref: result.ref, skills: result.skills, selected: new Set(result.skills) })\n await loadMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingMarket(null)\n }\n }, [api, loadMarket])\n\n /** 批量更新本地技能到市场源当前版本(复用来源同步路径)。 */\n const confirmMarketSync = useCallback(async (): Promise<void> => {\n if (marketSyncDialog === null) return\n const selected = [...marketSyncDialog.selected]\n setSyncBusy(true)\n setLoadError(null)\n try {\n if (selected.length > 0) {\n const result = await api.syncSource(marketSyncDialog.repo, selected)\n if (result.failed.length > 0) setLoadError(result.failed.map((item) => item.name + ': ' + item.error).join('\\n'))\n }\n setMarketSyncDialog(null)\n await Promise.all([load(), loadGroups(), loadSources()])\n void checkMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncBusy(false)\n }\n }, [api, marketSyncDialog, load, loadGroups, loadSources, checkMarket])\n\n /**\n * 一键全部更新:把每个「有可更新技能」的来源逐个同步到上游最新版本\n * (复用来源同步路径,覆盖本地修改),随后刷新并重新检查。\n */\n const updateAll = useCallback(async (): Promise<void> => {\n setUpdateAllDialog(false)\n setBatchBusy(true)\n setLoadError(null)\n const failures: string[] = []\n let done = 0\n try {\n for (const [repo, check] of Object.entries(sourceCheck)) {\n if (!check.changed || check.updated.length === 0) continue\n try {\n const result = await api.syncSource(repo, check.updated)\n done += 1\n if (result.failed.length > 0) {\n failures.push(tt('market.updateAllItem', { repo, count: result.failed.length }) + ': ' + result.failed.map((item) => item.name + ': ' + item.error).join('; '))\n }\n } catch (error) {\n failures.push(repo + ': ' + errorMessage(error))\n }\n }\n await Promise.all([load(), loadGroups(), loadSources()])\n await checkSources()\n void checkMarket()\n if (failures.length > 0) setLoadError(failures.join('\\n'))\n else if (done > 0) setSuccessBanner(tt('market.updateAllDone', { count: done }))\n } finally {\n setBatchBusy(false)\n }\n }, [api, sourceCheck, checkSources, checkMarket, load, loadGroups, loadSources])\n\n // ------------------------------------------------- daily auto-check\n // 打开面板时每天最多自动检查一次(自身更新 + 全部来源 + 全部市场源),\n // 时间戳存 localStorage 跨会话生效;手动按钮随时可用,不受节流限制。\n useEffect(() => {\n if (!shouldAutoCheck()) return\n markAutoChecked()\n void checkUpdate()\n void checkSources()\n void checkMarket()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // ---------------------------------------------------------------- create\n\n const create = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n setFormBusy(true)\n setFormMessage(null)\n setSuccessBanner(null)\n try {\n const result = await api.create({ name: formName, description: formDesc, root: formRoot })\n // The form closes on success, so the confirmation lives in the green\n // banner outside it (a success message inside the closing form is\n // never visible).\n setSuccessBanner(tt('form.success') + result.path)\n setFormName('')\n setFormDesc('')\n setShowForm(false)\n await load()\n } catch (error) {\n setFormMessage({ kind: 'error', text: tt('form.error') + errorMessage(error) })\n } finally {\n setFormBusy(false)\n }\n }, [api, formName, formDesc, formRoot, load])\n\n // ------------------------------------------------------------- derived\n\n const normalized = search.trim().toLocaleLowerCase()\n /** skillName → origin repo(无来源记录的技能不在此映射中,筛选中视为 private)。 */\n const origins = groupsState?.origins ?? {}\n /** 来源筛选选项:来源记录中的仓库(排序)+ 末尾的「个人」;没有技能的仓库不列。 */\n const sourceOptions = useMemo(() => {\n const skills = catalog?.skills ?? []\n const repos = [...new Set(skills.map((skill) => origins[skill.name]).filter((repo): repo is string => repo !== undefined))].sort()\n // 项目级技能(有 workspace 归属)不算「个人」。\n const hasPrivate = skills.some((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n return [...repos, ...(hasPrivate ? [PRIVATE_SOURCE] : [])]\n }, [catalog, origins])\n const filtered = useMemo(() => (catalog?.skills ?? []).filter((skill) =>\n normalized.length === 0 || skill.name.toLocaleLowerCase().includes(normalized) || skill.description.toLocaleLowerCase().includes(normalized),\n ), [catalog, normalized])\n /** 排序后的技能列表(所有视图共用;调用次数未知按 0 处理)。 */\n const sorted = useMemo(() => sortSkills(filtered, sortKey, (name) => uses.get(name)?.count), [filtered, sortKey, uses])\n\n return {\n // state\n catalog, loading, loadError, successBanner, updateState, repoDiscoverState, scanningRepo, repoSelected, repoImporting, repoResult,\n search, workspace, detail, detailLoading, busyNames, batchBusy, showForm, formName, formDesc, formRoot, formBusy, formMessage,\n uses, hubConfig, tab, skillView, sourceFilter, sortKey, marketState, marketCheck, branchChoice, branchBusy,\n marketSyncDialog, syncingMarket, syncBusy, newSourceName, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource,\n conflictDialog, confirmDialog, deleteSkillDialog, confirmClearTrash, updateAllDialog, editingTag, editName, membersDraft, newTagName, tagBusy,\n editSearch, collapsedGroups, subdividedProjects, showLegend,\n // derived\n actionNames, viewNames, normalized, origins, sourceOptions, filtered, sorted,\n // actions + setters\n setLoadError, setSuccessBanner, setSearch, setWorkspace, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage,\n setRepoSelected, setTab, setSkillView,\n setSourceFilter, setSortKey, setBranchChoice, setMarketSyncDialog, setNewSourceName, setConflictDialog, setConfirmDialog,\n setDeleteSkillDialog, setConfirmClearTrash, setUpdateAllDialog, setEditingTag, setEditName, setMembersDraft, setNewTagName, setEditSearch, setShowLegend,\n toggleGroupCollapse, toggleSubdivide, checkUpdate, loadMarket, openDetail, toggle, enableDisabled, batchToggleNames, toggleGroup, resolveConflict,\n runConfirmed, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, requestDeleteSkill, runDeleteSkill, createTag,\n deleteTag, saveTag, addSource, addMarketSource, removeMarketSource, scanRepo, confirmBranchChoice, toggleRepoSelected, importRepo,\n checkMarket, syncMarketSource, confirmMarketSync, updateAll, create,\n }\n}\n","/**\n * The skill hub panel: catalog grouped by tags + source collections, search\n * and filter in one row, per-group tri-state switches with conflict dialogs,\n * upstream source tracking (check / sync / follow upstream deletion into a\n * restorable trash), market sources, disabled re-enable,\n * detail inspection, and the new-skill scaffold form.\n *\n * Thin shell: state and flows live in useSkillHub, the tab contents live in\n * SourcesView / ScenesView / MarketView, and the dialog family lives in\n * dialogs.tsx. This component owns only the shared chrome (header, banners,\n * filter bar, shared sections) and the view routing — and holds no hooks,\n * so the detail / tag-editor early returns are safe.\n */\n\nimport { useState } from 'react'\nimport type { WritableRoot } from '../../protocol.ts'\nimport { IconSkillOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { SkillHubApi } from '../api.ts'\nimport { tt } from '../helpers.ts'\nimport { PRIVATE_SOURCE, type SortKey } from '../grouping.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport { SkillDetailView } from './SkillDetailView.tsx'\nimport { TagEditorView } from './TagEditorView.tsx'\nimport { SourcesView } from './SourcesView.tsx'\nimport { ScenesView } from './ScenesView.tsx'\nimport { MarketView } from './MarketView.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { BranchChoiceDialog, ConfirmDialog, ConflictDialog, MarketSyncDialog } from './dialogs.tsx'\nimport { useSkillHub } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport interface SkillHubPanelProps {\n api: SkillHubApi\n}\n\nexport function SkillHubPanel(props: SkillHubPanelProps): React.JSX.Element {\n const hub = useSkillHub(props.api)\n /** 工作区输入草稿:回车才应用,避免每次按键都触发目录重拉。 */\n const [workspaceDraft, setWorkspaceDraft] = useState('')\n const {\n catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc,\n formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search,\n workspace, setWorkspace,\n sourcesState, tagBusy, busyNames, normalized, origins, sourceOptions, filtered,\n conflictDialog, confirmDialog, deleteSkillDialog, confirmClearTrash, branchChoice, branchBusy, marketSyncDialog,\n syncBusy, editingTag, editName, membersDraft, editSearch, uses, groupsState, sourceCheck, checkingSource, syncingSource,\n showLegend,\n setLoadError, setSuccessBanner, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage, setTab,\n setSkillView, setSourceFilter, setSortKey, setSearch, setConflictDialog, setConfirmDialog, setDeleteSkillDialog,\n setConfirmClearTrash, setBranchChoice, setMarketSyncDialog, setEditingTag, setEditName, setMembersDraft, setEditSearch,\n setShowLegend,\n checkUpdate, loadMarket, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, runDeleteSkill,\n runConfirmed, resolveConflict, confirmBranchChoice, confirmMarketSync, create, saveTag, deleteTag, enableDisabled,\n } = hub\n\n // -------------------------------------------------------------- detail\n\n if (detail !== null) {\n return (\n <SkillDetailView\n detail={detail}\n hubConfig={hubConfig}\n uses={uses}\n groupsState={groupsState}\n sourcesState={sourcesState}\n sourceCheck={sourceCheck}\n checkingSource={checkingSource}\n syncingSource={syncingSource}\n loading={detailLoading}\n onBack={() => { setDetail(null) }}\n onCheck={(repo) => { void checkSources(repo) }}\n onSync={requestSync}\n onFollowDelete={requestDelete}\n />\n )\n }\n\n if (editingTag !== null) {\n return (\n <TagEditorView\n tag={editingTag}\n editName={editName}\n membersDraft={membersDraft}\n editSearch={editSearch}\n catalog={catalog}\n tagBusy={tagBusy}\n onBack={() => { setEditingTag(null) }}\n onEditName={setEditName}\n onEditSearch={setEditSearch}\n onToggleMember={(name, checked) => {\n setMembersDraft((previous) => {\n const next = new Set(previous)\n if (checked) next.add(name)\n else next.delete(name)\n return next\n })\n }}\n onRename={() => { void saveTag(editingTag.id, editName, null) }}\n onDelete={() => { void deleteTag(editingTag.id) }}\n onSaveMembers={() => { void saveTag(editingTag.id, editName, [...membersDraft]) }}\n />\n )\n }\n\n /** 检查结果的悬停提示:收敛到「检查更新」按钮上,不再占面板顶部横幅。 */\n const updateTitle = ((): string | undefined => {\n if (updateState.status === 'checking') return tt('update.checking')\n if (updateState.status === 'error') return tt('update.error', { error: updateState.message })\n if (updateState.status === 'ready') {\n const data = updateState.data\n if (data.error !== undefined) return tt('update.error', { error: data.error })\n if (data.updateAvailable) return tt('update.available', { version: data.latestVersion ?? '', current: data.currentVersion })\n if (data.latestVersion === null) return tt('update.unavailable')\n return tt('update.upToDate', { version: data.latestVersion })\n }\n return undefined\n })()\n\n return (\n <div className={css.panel}>\n <div className={css.header}>\n <h2 className={css.title}><IconSkillOutline16 size={16} className={css.titleIcon} /> {tt('panel.title')}</h2>\n {catalog !== null\n ? <span className={css.headerCount}>\n {tt('panel.count', { count: catalog.skills.length + catalog.disabled.length })}\n {catalog.disabled.length > 0 ? ' · ' + tt('panel.disabledCount', { count: catalog.disabled.length }) : null}\n </span>\n : null}\n {catalog !== null && !catalog.complete ? <span className={css.hint}>{tt('panel.incomplete')}</span> : null}\n <span className={css.actions}>\n <button type='button' className={css.button} disabled={updateState.status === 'checking'} title={updateTitle} onClick={() => { void checkUpdate() }}>{updateState.status === 'checking' ? tt('update.checking') : tt('update.check')}</button>\n {updateState.status === 'ready' && updateState.data.updateAvailable && updateState.data.url !== null\n ? <a className={css.updateLink} href={updateState.data.url} target='_blank' rel='noreferrer'>{tt('update.newVersion', { version: updateState.data.latestVersion ?? '' })}</a>\n : null}\n </span>\n </div>\n <div className={css.subbar}>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (tab === 'sources' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('sources') }}>{tt('view.sources')}</button>\n <button type='button' className={css.segBtn + (tab === 'scenes' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('scenes') }}>{tt('view.scenes')}</button>\n <button type='button' className={css.segBtn + (tab === 'market' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('market'); void loadMarket() }}>{tt('view.market')}</button>\n </span>\n <span className={css.workspaceBox}>\n <input\n className={css.search + ' ' + css.workspaceInput}\n value={workspaceDraft}\n placeholder={workspace !== '' ? workspace : tt('panel.workspacePlaceholder')}\n title={tt('panel.workspaceHint')}\n onChange={(event) => { setWorkspaceDraft(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') setWorkspace((event.target as HTMLInputElement).value.trim()) }}\n />\n {workspace !== ''\n ? <button type='button' className={css.opBtn} title={tt('panel.workspaceClear')} onClick={() => { setWorkspace(''); setWorkspaceDraft('') }}>✕</button>\n : null}\n </span>\n <button type='button' className={css.legendToggle + (showLegend ? ' ' + css.legendToggleActive : '')} onClick={() => { setShowLegend((value) => !value) }} title={tt('legend.hint')}>?</button>\n <span className={css.actions}>\n <button type='button' className={css.button + ' ' + css.primary} onClick={() => { setShowForm((value) => !value) }}>{tt('panel.new')}</button>\n </span>\n </div>\n\n {showForm ? (\n <form className={css.form} onSubmit={(event) => { void create(event) }}>\n <p className={css.hintLine}>{tt('form.capabilityHint')}</p>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.name')}</label>\n <input className={css.input} value={formName} onChange={(event) => { setFormName(event.target.value) }} placeholder='code-review' />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.desc')}</label>\n <input className={css.input} value={formDesc} onChange={(event) => { setFormDesc(event.target.value) }} placeholder={tt('form.descPlaceholder')} />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.root')}</label>\n <select className={css.select} value={formRoot} onChange={(event) => { setFormRoot(event.target.value as WritableRoot) }}>\n <option value='user-dsh'>~/.dsh/skills</option>\n <option value='user-agents'>~/.agents/skills</option>\n </select>\n </div>\n {formMessage !== null ? <div className={formMessage.kind === 'error' ? css.formError : css.formSuccess}>{formMessage.text}</div> : null}\n <div className={css.buttons}>\n <button type='submit' className={css.button + ' ' + css.primary} disabled={formBusy}>{formBusy ? tt('form.busy') : tt('form.submit')}</button>\n <button type='button' className={css.button} onClick={() => { setShowForm(false); setFormMessage(null) }}>{tt('form.cancel')}</button>\n </div>\n </form>\n ) : null}\n\n {loadError !== null ? (\n <div className={css.errorBanner}>\n <span>{loadError}</span>\n <button type='button' className={css.button} onClick={() => { setLoadError(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {successBanner !== null ? (\n <div className={css.successBanner}>\n <span>{successBanner}</span>\n <button type='button' className={css.button} onClick={() => { setSuccessBanner(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {showLegend ? (\n <div className={css.legend}>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} />{tt('legend.model')}</span>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} />{tt('legend.user')}</span>\n <span className={css.legendHint}>{tt('legend.hint')}</span>\n </div>\n ) : null}\n\n {loading ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n\n {detailLoading ? <div className={css.empty}>{tt('detail.loading')}</div> : null}\n\n {tab === 'market' ? (\n <MarketView hub={hub} />\n ) : catalog !== null ? (\n <>\n <div className={css.filterBar}>\n {tab === 'sources' ? (\n <>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (skillView === 'flat' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('flat') }}>{tt('view.flat')}</button>\n <button type='button' className={css.segBtn + (skillView === 'groups' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('groups') }}>{tt('view.grouped')}</button>\n </span>\n <select className={css.select} value={sourceFilter} onChange={(event) => { setSourceFilter(event.target.value) }}>\n <option value='all'>{tt('filter.allSources')}</option>\n {sourceOptions.map((source) => (\n <option key={source} value={source}>{source === PRIVATE_SOURCE ? tt('filter.private') : source}</option>\n ))}\n </select>\n </>\n ) : null}\n <select className={css.select} value={sortKey} onChange={(event) => { setSortKey(event.target.value as SortKey) }}>\n <option value='name'>{tt('sort.name')}</option>\n <option value='added'>{tt('sort.added')}</option>\n <option value='uses'>{tt('sort.uses')}</option>\n </select>\n <input className={css.search} value={search} onChange={(event) => { setSearch(event.target.value) }} placeholder={tt('panel.search')} />\n </div>\n\n {filtered.length === 0 && search.trim() !== '' ? <div className={css.empty}>{tt('panel.empty')}</div> : null}\n {filtered.length === 0 && search.trim() === '' && catalog.skills.length === 0 && catalog.disabled.length === 0 && catalog.diagnostics.length === 0\n ? <div className={css.empty}>{tt('panel.emptyAll')}</div>\n : null}\n\n {tab === 'sources' ? <SourcesView hub={hub} /> : <ScenesView hub={hub} />}\n\n {sourcesState !== null && sourcesState.trash.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('source.trash')}</span>\n <button type='button' className={css.opBtn + ' ' + css.opDanger} disabled={tagBusy} onClick={() => { setConfirmClearTrash(true) }}>{tt('source.clearTrash')}</button>\n </div>\n {sourcesState.trash.map((entry) => (\n <div key={entry.name} className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{relativeTimeText(entry.movedAt)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={tagBusy} onClick={() => { void restoreTrash(entry.name) }}>{tt('source.restore')}</button>\n </div>\n ))}\n </section>\n ) : null}\n\n {catalog.disabled.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle}>{tt('panel.disabled')}</div>\n {catalog.disabled\n .filter((record) =>\n (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n && (sourceFilter === 'all' || (origins[record.name] ?? PRIVATE_SOURCE) === sourceFilter))\n .map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </section>\n ) : null}\n\n {catalog.diagnostics.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle}>{tt('panel.diagnostics')}</div>\n {catalog.diagnostics.map((entry) => (\n <div key={entry.path} className={css.diagRow}>\n <div className={css.diagPath}>{entry.path}</div>\n <div className={css.diagReason}>{entry.reason}</div>\n </div>\n ))}\n </section>\n ) : null}\n </>\n ) : null}\n\n {conflictDialog !== null ? (\n <ConflictDialog\n dialog={conflictDialog}\n tags={groupsState?.tags ?? []}\n collections={groupsState?.collections ?? []}\n onClose={() => { setConflictDialog(null) }}\n onKeepOn={() => { void resolveConflict(false) }}\n onCloseAll={() => { void resolveConflict(true) }}\n />\n ) : null}\n\n {confirmDialog !== null ? (\n <ConfirmDialog\n title={confirmDialog.kind === 'sync' ? tt('source.syncConfirmTitle') : tt('source.deleteConfirmTitle')}\n text={confirmDialog.kind === 'sync' ? tt('source.syncConfirmText') : tt('source.deleteConfirmText')}\n items={confirmDialog.skills}\n confirmLabel={confirmDialog.kind === 'sync' ? tt('source.sync') : tt('source.followDelete')}\n danger={confirmDialog.kind === 'delete'}\n onCancel={() => { setConfirmDialog(null) }}\n onConfirm={() => { void runConfirmed() }}\n />\n ) : null}\n\n {branchChoice !== null ? (\n <BranchChoiceDialog\n choice={branchChoice}\n busy={branchBusy}\n onSelect={(selected) => { setBranchChoice({ ...branchChoice, selected }) }}\n onCancel={() => { setBranchChoice(null) }}\n onConfirm={() => { void confirmBranchChoice() }}\n />\n ) : null}\n\n {marketSyncDialog !== null ? (\n <MarketSyncDialog\n dialog={marketSyncDialog}\n busy={syncBusy}\n onToggle={(name, checked) => {\n const next = new Set(marketSyncDialog.selected)\n if (checked) next.add(name)\n else next.delete(name)\n setMarketSyncDialog({ ...marketSyncDialog, selected: next })\n }}\n onCancel={() => { setMarketSyncDialog(null) }}\n onConfirm={() => { void confirmMarketSync() }}\n />\n ) : null}\n\n {deleteSkillDialog !== null ? (\n <ConfirmDialog\n title={tt('delete.confirmTitle')}\n text={tt('delete.confirmText', { name: deleteSkillDialog })}\n confirmLabel={tt('delete.confirm')}\n danger\n onCancel={() => { setDeleteSkillDialog(null) }}\n onConfirm={() => { void runDeleteSkill() }}\n />\n ) : null}\n\n {confirmClearTrash ? (\n <ConfirmDialog\n title={tt('source.clearTrashConfirmTitle')}\n text={tt('source.clearTrashConfirmText')}\n confirmLabel={tt('source.clearTrashConfirm')}\n danger\n onCancel={() => { setConfirmClearTrash(false) }}\n onConfirm={() => { void clearTrash() }}\n />\n ) : null}\n </div>\n )\n}\n","/**\n * Browser-half entry for the dsh-skill-hub plugin — runs inside the dsh\n * web GUI.\n *\n * Registers the dsh-skill-hub locale dictionaries and mounts two Settings\n * surfaces, both through official slots (no DOM injection):\n * - a plugin-management card in the `settings.plugin.item` slot (Settings →\n * 插件 → 可配置插件列表), keyed by the hub's settings namespace and bound\n * through the official settings transport (dsh rc.7 serves every\n * registered namespace to the web client, and the tab dispatches cards by\n * namespace) — the family-bucket card pattern (PluginSettingsCard +\n * CardForm vendored from dsh-task-board);\n * - a top-level Settings section (Settings → 技能) hosting the skill hub\n * panel: catalog, search, enable/disable, diagnostics, new-skill form.\n *\n * Failure policy: mounting problems are logged, never thrown — the web\n * shell fails the whole boot when a plugin apply throws, and an external\n * plugin must not take the GUI down.\n *\n * Export discipline (packages/client rule): the /client surface carries\n * what cordis loading needs plus types only — all value exports stay\n * internal.\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-scope service merge and the settings.section slot.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the LocaleNamespaceMap merge table.\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n// Type-only: pulls the settings-plugins SlotMap merge (settings.plugin.item).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport type { HubSettingsValue } from '../protocol.ts'\nimport { SkillHubApi } from './api.ts'\nimport { en, zh, type HubKey } from './locales.ts'\nimport { applySettingsNavIcon } from './settings-nav-icon.ts'\nimport { SkillHubSettingsCard, SkillHubSettingsCardController } from './SkillHubSettingsCard.tsx'\nimport { SkillHubPanel } from './panel/SkillHubPanel.tsx'\n\n/** Locale namespace this plugin owns. */\nconst NS = 'dsh-skill-hub'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** dsh-skill-hub surface copy. */\n 'dsh-skill-hub': HubKey\n }\n}\n\n/**\n * Required services (fiber inject waiting — the runtime must be up first).\n * `connection`/`remote` are the settings transport's own prerequisites\n * (`ctx.settingsScope.bind` resolves them on the caller's fiber), and\n * `settingsScope` is the namespace-scope binder itself; mirror the official\n * settings-plugins inject list.\n */\nexport const inject = ['slots', 'locale', 'connection', 'remote', 'settingsScope']\n\n/** Type-only surface (export discipline: no value exports beyond the plugin contract). */\nexport type { SkillHubPanelProps } from './panel/SkillHubPanel.tsx'\nexport type { SkillHubSettingsState } from './SkillHubSettingsCard.tsx'\nexport type { HubKey } from './locales.ts'\n\n/**\n * Mount the settings card and the skill hub section.\n * @param ctx - client root context (slots, locale).\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-skill-hub: dictionaries')\n const t = ctx.locale.bind(NS)\n const api = new SkillHubApi()\n\n // The card edits the hub's settings namespace through the official\n // settings transport — the configurable-plugins tab only dispatches cards\n // whose key the Host serves, and the Host serves every registered namespace\n // since rc.7, so this is what makes the card appear (and stay in sync).\n const settingsCard = new SkillHubSettingsCardController(\n ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS }),\n )\n\n // Plugin-management card: Settings → 插件 → 可配置插件列表.\n // rc.7's slot contract declares this keyed slot with options `key`\n // (the settings namespace the card edits), so registration is fully typed.\n ctx.effect(\n () => ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: NS,\n locale: NS,\n inject: () => settingsCard.inject(),\n }, SkillHubSettingsCard)),\n 'dsh-skill-hub: settings card',\n )\n\n // Top-level Settings section: the skill management page.\n ctx.effect(\n () => ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'skill-hub',\n order: 12,\n label: () => t('entry.label'),\n locale: NS,\n inject: () => ({}),\n }, () => <SkillHubPanel api={api} />)),\n 'dsh-skill-hub: settings section',\n )\n\n // Host shell has no section-icon registration; keep the nav gear swapped for the skill icon.\n ctx.effect(() => applySettingsNavIcon(), 'dsh-skill-hub: settings nav icon')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["css","css","css","css","css","css","css","css","css","css","css","Fragment","css"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/locales.ts","../src/client/settings-nav-icon.ts","../src/client/grouping.ts","../src/client/helpers.ts","../src/client/panel/format.ts","../src/client/slash-dots.tsx","../src/client/icons.tsx","../src/client/settings-card.tsx","../src/client/settings-form.ts","../src/client/SkillHubSettingsCard.tsx","../src/client/panel/SourceStatusBadge.tsx","../src/client/panel/SkillDetailView.tsx","../src/client/panel/TagEditorView.tsx","../src/client/panel/SkillRow.tsx","../src/client/panel/DisabledRow.tsx","../src/client/panel/GroupSummary.tsx","../src/client/panel/SourcesView.tsx","../src/client/panel/ScenesView.tsx","../src/client/market-catalog.ts","../src/client/panel/dialogs.tsx","../src/client/panel/MarketView.tsx","../src/client/panel/useSkillHub.ts","../src/client/panel/SkillHubPanel.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * Shared API contract for dsh-skill-hub: the route paths and payload shapes\n * both the host half and the browser half import. The browser half must never\n * depend on host SDK packages, so registry types are re-spelled here as\n * plain JSON-safe interfaces.\n */\n\n/** Browser-facing base paths of the skill-hub API family. */\nexport const SKILL_HUB_API = {\n catalog: '/api/skill-hub/catalog',\n skill: '/api/skill-hub/skill',\n skillDelete: '/api/skill-hub/skill/delete',\n toggle: '/api/skill-hub/toggle',\n toggleBatch: '/api/skill-hub/toggle-batch',\n create: '/api/skill-hub/create',\n stats: '/api/skill-hub/stats',\n config: '/api/skill-hub/config',\n market: '/api/skill-hub/market',\n marketSource: '/api/skill-hub/market/source',\n marketSourceDelete: '/api/skill-hub/market/source/delete',\n marketSourceRef: '/api/skill-hub/market/source/ref',\n marketCheck: '/api/skill-hub/market/check',\n marketSync: '/api/skill-hub/market/source/sync',\n repo: '/api/skill-hub/repo',\n repoImport: '/api/skill-hub/repo/import',\n update: '/api/skill-hub/update',\n groups: '/api/skill-hub/groups',\n tag: '/api/skill-hub/tag',\n tagDelete: '/api/skill-hub/tag/delete',\n tagMembers: '/api/skill-hub/tag/members',\n sources: '/api/skill-hub/sources',\n sourceCheck: '/api/skill-hub/sources/check',\n sourceSync: '/api/skill-hub/sources/sync',\n sourceDelete: '/api/skill-hub/sources/delete',\n sourceRestore: '/api/skill-hub/sources/restore',\n sourceTrashClear: '/api/skill-hub/sources/trash/clear',\n} as const\n\n/** User-level roots the hub may write to (matches dsh-skill-filesystem ranks 400/500). */\nexport type WritableRoot = 'user-dsh' | 'user-agents'\n\n/** Invocation policy resolved by the registry, re-spelled for the wire. */\nexport interface HubInvocation {\n /** Whether model-facing catalogs may load this skill. */\n modelInvocable: boolean\n /** Whether human-facing command catalogs may load this skill. */\n userInvocable: boolean\n}\n\n/** One enabled skill row in the catalog. */\nexport interface CatalogSkill {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Whether the hub may toggle this skill (user-level filesystem skills only). */\n writable: boolean\n /** 技能来源标识(user-dsh/user-agents/project-dsh/project-agents/...)。 */\n source: string\n /** SKILL.md creation time (epoch ms); used for \"added\" sorting. Absent when unknown. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); used for \"updated\" display. Absent when unknown. */\n updatedAt?: number\n /** 项目技能的所属工作区路径(仅 project-dsh/project-agents 来源携带)。 */\n workspace?: string\n /** 工作区显示标题(来自 workspace.json;无则回退为路径)。 */\n workspaceTitle?: string\n}\n\n/** One disabled skill tracked by the hub sidecar (SKILL.md renamed away). */\nexport interface DisabledSkill {\n name: string\n description: string\n /** Absolute path of the renamed file (SKILL.md.disabled / <name>.md.disabled). */\n path: string\n root: WritableRoot\n disabledAt: number\n}\n\n/** One discovery diagnostic: a file the filesystem provider skips, with the reason. */\nexport interface DiagnosticEntry {\n path: string\n root: string\n reason: string\n}\n\n/** GET /api/skill-hub/catalog */\nexport interface CatalogResponse {\n ok: true\n /** Whether discovery completed within a stable catalog revision. */\n complete: boolean\n /** Sorted winning summaries of every enabled skill (all roots + providers). */\n skills: CatalogSkill[]\n /** Skills the hub has toggled off (kept outside provider discovery). */\n disabled: DisabledSkill[]\n /** Files in the writable roots the provider ignores, with reasons. */\n diagnostics: DiagnosticEntry[]\n}\n\n/** GET /api/skill-hub/skill */\nexport interface SkillDetail {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Absolute file path when the skill came from disk. */\n path?: string\n /** SKILL.md creation time (epoch ms); absent when the file is unreadable. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); absent when the file is unreadable. */\n updatedAt?: number\n /** Markdown instruction body. */\n content: string\n}\n\nexport interface SkillDetailResponse {\n ok: true\n skill: SkillDetail\n}\n\n/** POST /api/skill-hub/skill/delete — 把单个技能移入回收站(可恢复)。 */\nexport interface SkillDeleteRequest {\n name: string\n}\n\n/** POST /api/skill-hub/skill/delete */\nexport interface SkillDeleteResponse {\n ok: true\n name: string\n /** 移入回收站后的路径(目录或文件)。 */\n path: string\n}\n\n/** POST /api/skill-hub/toggle */\nexport interface ToggleRequest {\n /** Kebab-case skill name. */\n name: string\n /** true re-enables a hub-disabled skill; false disables an enabled one. */\n enabled: boolean\n}\n\nexport interface ToggleResponse {\n ok: true\n /** Fresh catalog after the mutation (the filesystem provider may lag a beat). */\n catalog: CatalogResponse\n}\n\n/** POST /api/skill-hub/toggle-batch — one group of skills, one write. */\nexport interface ToggleBatchRequest {\n names: string[]\n enabled: boolean\n}\n\n/** POST /api/skill-hub/toggle-batch */\nexport interface ToggleBatchResponse {\n ok: true\n catalog: CatalogResponse\n /** Per-name failures (unknown/read-only skills); empty means all landed. */\n failures: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/create */\nexport interface CreateRequest {\n /** Kebab-case skill name (validated with the official isSkillName grammar). */\n name: string\n /** Optional one-line routing description for the frontmatter. */\n description?: string\n /** Target user root; defaults to user-dsh (~/.dsh/skills). */\n root?: WritableRoot\n}\n\nexport interface CreateResponse {\n ok: true\n path: string\n root: WritableRoot\n}\n\n/** One skill's invocation stats across the local session logs. */\nexport interface SkillStat {\n /** Kebab-case skill name. */\n name: string\n /** How many sessions recorded a user-explicit invocation of this skill. */\n count: number\n /** Unix epoch ms of the most recent invocation (absent when never called). */\n lastUsed?: number\n}\n\n/** GET /api/skill-hub/stats */\nexport interface StatsResponse {\n ok: true\n /** Whether a session-log source was available (false means counts are empty). */\n available: boolean\n /** Sorted per-skill invocation counts. */\n stats: SkillStat[]\n}\n\n/** JSON error body shared by every route. */\nexport interface ErrorResponse {\n error: string\n}\n\n/** The skill hub's own runtime configuration, edited from the settings card. */\nexport interface HubConfig {\n /** Master switch: routes, provider, and announcement all go live with this. */\n enabled: boolean\n /** When true, a system-prompt section announces the hub to every agent. */\n announceToAgent: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n /** Show per-skill invocation count chip. Default true. */\n showUseCount?: boolean\n /** Show per-skill last-used relative time. Default true. */\n showUseTime?: boolean\n /** Show group-header usage summaries (count + last used). Default true. */\n showGroupSummary?: boolean\n}\n\n/**\n * The resolved shape of the hub's settings namespace (schema defaults, then\n * the composition base, then the user layer). Kept as a type alias so the\n * browser-side settings scope snapshot is index-compatible with the card\n * form's record shape.\n */\nexport type HubSettingsValue = {\n enabled: boolean\n announceToAgent: boolean\n showUseCount: boolean\n showUseTime: boolean\n showGroupSummary: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n}\n\n/**\n * Hub config defaults — the single source every layer reads: the cordis\n * schema (index.ts), the host's saved-override merge, and the routes'\n * fallback view. Changing a default here changes all three.\n */\nexport const HUB_CONFIG_DEFAULTS = {\n enabled: true,\n announceToAgent: true,\n showUseCount: true,\n showUseTime: true,\n showGroupSummary: true,\n} as const\n\n/**\n * Resolve the effective hub config: saved sidecar overrides win over the\n * cordis composition entry (the web card owns runtime config), missing\n * booleans fall back to HUB_CONFIG_DEFAULTS, and dot colors pass through\n * (saved first, then base) only when set.\n */\nexport function resolveHubConfig(saved: Partial<HubConfig>, base: Partial<HubConfig> = {}): HubConfig {\n const dotModelColor = saved.dotModelColor !== undefined ? saved.dotModelColor : base.dotModelColor\n const dotUserColor = saved.dotUserColor !== undefined ? saved.dotUserColor : base.dotUserColor\n return {\n enabled: saved.enabled ?? base.enabled ?? HUB_CONFIG_DEFAULTS.enabled,\n announceToAgent: saved.announceToAgent ?? base.announceToAgent ?? HUB_CONFIG_DEFAULTS.announceToAgent,\n showUseCount: saved.showUseCount ?? base.showUseCount ?? HUB_CONFIG_DEFAULTS.showUseCount,\n showUseTime: saved.showUseTime ?? base.showUseTime ?? HUB_CONFIG_DEFAULTS.showUseTime,\n showGroupSummary: saved.showGroupSummary ?? base.showGroupSummary ?? HUB_CONFIG_DEFAULTS.showGroupSummary,\n ...(dotModelColor !== undefined ? { dotModelColor } : {}),\n ...(dotUserColor !== undefined ? { dotUserColor } : {}),\n }\n}\n\n/** HEX color validation shared by host routes and the settings card. */\nexport const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i\n\n/** GET /api/skill-hub/config */\nexport interface ConfigResponse {\n ok: true\n /** Effective configuration (saved overrides merged over the defaults). */\n config: HubConfig\n /** Raw user overrides persisted in the sidecar (absent fields inherit defaults). */\n saved: Partial<HubConfig>\n}\n\n/** POST /api/skill-hub/config — a partial patch; omitted fields keep their values. */\nexport interface ConfigRequest {\n /** Set the field; null clears the saved override so it re-inherits the default. */\n enabled?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n announceToAgent?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseCount?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseTime?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showGroupSummary?: boolean | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotModelColor?: string | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotUserColor?: string | null\n}\n\n/** One market source: a tracked upstream repo plus its pinned version. */\nexport interface MarketSourceRecord {\n /** Repo slug (owner/repo). */\n repo: string\n /** Pinned version: release tag, branch name, or custom ref. Absent = not yet pinned. */\n ref?: string\n /** Commit the pinned ref last resolved to (update-check baseline). */\n commitSha?: string\n}\n\n/** GET /api/skill-hub/market — the user's added market sources. */\nexport interface MarketSourcesResponse {\n ok: true\n /** Added market sources, in addition order. */\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source — add one repo as a market source. */\nexport interface MarketSourceRequest {\n /** owner/repo, owner/repo@ref, or a github.com URL. */\n repo: string\n}\n\n/** POST /api/skill-hub/market/source|delete */\nexport interface MarketSourceResponse {\n ok: true\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source/ref — pin a market source to an explicit ref. */\nexport interface MarketSourceRefRequest {\n repo: string\n /** Release tag or branch name chosen for the repo. */\n ref: string\n}\n\n/** GET /api/skill-hub/market/check — update check over market sources. */\nexport interface MarketCheckResponse {\n ok: true\n results: Array<{\n repo: string\n /** Pinned ref, when one is recorded. */\n ref?: string\n /** Latest release tag on the repo, when it has one. */\n latestTag?: string\n /** Whether the pinned ref (or the repo) has moved ahead. */\n updateAvailable: boolean\n /** Latest commit of the checked ref. */\n commitSha: string\n /** Throttled: the check was skipped within the interval. */\n throttled?: boolean\n error?: string\n }>\n}\n\n/** POST /api/skill-hub/market/source/sync — align a market source to its pinned ref. */\nexport interface MarketSyncResponse {\n ok: true\n repo: string\n /** The ref the source is now pinned to. */\n ref: string\n commitSha: string\n /** Local skills tracked from this repo (candidates for a batch update). */\n skills: string[]\n}\n\n/** A skill discovered in a GitHub repo under skills/ or design-templates/. */\nexport interface RepoSkillEntry {\n /** Kebab-case skill name (directory basename). */\n name: string\n /** Root-relative skill directory, e.g. skills/code-review. */\n dir: string\n /** Root-relative SKILL.md path, e.g. skills/code-review/SKILL.md. */\n path: string\n /** Repo root the skill lives in. */\n root: RepoRoot\n /** Collection name recorded as origin after import. */\n origin: string\n /** Number of files in the skill directory. */\n fileCount: number\n /** Total bytes across all files in the skill directory. */\n totalBytes: number\n /** Whether a same-named skill already exists locally. */\n existing: boolean\n}\n\n/** Supported skill roots in a GitHub repo. */\nexport type RepoRoot = 'skills' | 'design-templates'\n\n/** GET /api/skill-hub/repo — discover importable skills in a GitHub repo. */\nexport interface RepoDiscoverResponse {\n ok: true\n repo: string\n /**\n * Ref the discovery ran against (release tag / branch / default branch).\n * Null means the repo has no release and no pinned ref — the client must\n * ask the user to pick a branch (see `branches`) and pin it first.\n */\n ref: string | null\n /** Branch names to choose from when ref is null (default branch first). */\n branches?: string[]\n entries: RepoSkillEntry[]\n}\n\n/** POST /api/skill-hub/repo/import — install selected repo skills. */\nexport interface RepoImportRequest {\n repo: string\n /** Selected SKILL.md paths from the discover response. */\n paths: string[]\n /** The ref the discovery ran against; the import must use the same one. */\n ref?: string\n}\n\n/** POST /api/skill-hub/repo/import */\nexport interface RepoImportResponse {\n ok: true\n imported: Array<{ name: string; origin: string; path: string }>\n skipped: Array<{ name: string; reason: 'exists' }>\n failed: Array<{ name: string; error: string }>\n}\n\n/** GET /api/skill-hub/update — check the plugin's own latest GitHub release. */\nexport interface UpdateCheckResponse {\n ok: true\n /** Installed plugin version (from the bundled host build). */\n currentVersion: string\n /** Latest release tag, normalized without the leading v; null when unknown. */\n latestVersion: string | null\n /** True when latestVersion is strictly newer than currentVersion. */\n updateAvailable: boolean\n /** Release page URL; null when unavailable. */\n url: string | null\n /** Best-effort message when the check failed or no release exists. */\n error?: string\n}\n\n/** 用户自定义 tag 分组:纯组织视图,不改技能文件。 */\nexport interface SkillTag {\n /** 稳定 ID(新建时由宿主生成)。 */\n id: string\n /** 显示名。 */\n name: string\n /** 成员技能名(集合技能与独立技能都可加入)。 */\n skillNames: string[]\n /** 默认场景(「通用」):系统预置、不可删除、新技能自动归入。 */\n default?: boolean\n}\n\n/** 系统集合组:按 origin(来源集合标识)自动聚合。 */\nexport interface CollectionGroup {\n /** 集合名(origin 值,如 \"superpowers\" / \"anthropics/skills\")。 */\n name: string\n /** 该集合下的技能名,按名称排序。 */\n skillNames: string[]\n}\n\n/** GET /api/skill-hub/groups */\nexport interface GroupsResponse {\n ok: true\n /** 用户自定义 tag 分组(按创建顺序)。 */\n tags: SkillTag[]\n /** 系统集合组(按 origin 聚合,名称排序)。 */\n collections: CollectionGroup[]\n /** skillName → 集合名 的完整映射。 */\n origins: Record<string, string>\n}\n\n/** POST /api/skill-hub/tag — 新建(缺省 id)或重命名(带 id)。 */\nexport interface TagSaveRequest {\n /** 已有 tag 的 id;缺省表示新建。 */\n id?: string\n /** 显示名(去空格后非空)。 */\n name: string\n}\n\n/** POST /api/skill-hub/tag */\nexport interface TagSaveResponse {\n ok: true\n /** 变更后的全部 tag。 */\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteRequest {\n id: string\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/members — 直接设置某 tag 的完整成员列表(幂等)。 */\nexport interface TagMembersRequest {\n id: string\n /** 目标成员技能名;后端只保留目录中存在的名字。 */\n skillNames: string[]\n}\n\n/** POST /api/skill-hub/tag/members */\nexport interface TagMembersResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** 来源跟踪记录:一组来自同一上游仓库根目录的技能。 */\nexport interface SourceRecord {\n /** GitHub owner/repo。 */\n repo: string\n /** 显式分支/tag;缺省表示默认分支。 */\n ref?: string\n /** 技能在仓库中的根目录。 */\n root: RepoRoot\n /** 上次导入/同步时的上游 commit SHA;空 = 尚未核对过。 */\n commitSha: string\n /** 该来源下的技能名(来源组 = 这些技能)。 */\n skills: string[]\n /** 仓库内路径 → 文件大小 的基线清单(差异检测用;缺失 = 无基线)。 */\n manifest?: Record<string, number>\n}\n\n/** 回收站条目:上游删除后跟进删除(移入 .trash)的技能。 */\nexport interface TrashEntry {\n name: string\n /** .trash 下的绝对路径。 */\n path: string\n /** 移入回收站的时间(epoch ms)。 */\n movedAt: number\n /** 移入回收站前的原始路径(目录或文件);旧版本条目没有该字段。 */\n sourcePath?: string\n /**\n * 移入回收站前的来源跟踪快照(恢复时用它把技能重新挂回来源记录,\n * 否则恢复后的技能会丢失来源归属、变成「个人技能」)。\n */\n origin?: {\n repo: string\n root: RepoRoot\n ref?: string\n commitSha: string\n }\n /** 移入回收站前所属的场景(tag)ID;恢复时重新加回这些场景。 */\n tagIds?: string[]\n}\n\n/** GET /api/skill-hub/sources */\nexport interface SourcesResponse {\n ok: true\n /** 全部来源记录(按 repo 排序)。 */\n sources: SourceRecord[]\n /** skillName → 集合名(由 sources 派生)。 */\n origins: Record<string, string>\n /** 来源集合组(按 origin 聚合)。 */\n collections: CollectionGroup[]\n /** 回收站内容。 */\n trash: TrashEntry[]\n}\n\n/** POST /api/skill-hub/sources/check — 检查指定(或全部)来源的上游更新。 */\nexport interface SourceCheckRequest {\n /** 仅检查该 repo;缺省检查全部。 */\n repo?: string\n}\n\n/** 单个来源的检查结果。 */\nexport interface SourceCheckResult {\n repo: string\n ref?: string\n /** 检查失败时的原因(如仓库不可达/限流)。 */\n error?: string\n /** 上游 commit 是否变化。 */\n changed: boolean\n /** 上游最新 commit SHA(检查成功时)。 */\n commitSha?: string\n /** 上游有更新的技能名(changed 时经 tree 差异得出)。 */\n updated: string[]\n /** 上游已删除的技能名(changed 时经 tree 差异得出)。 */\n deleted: string[]\n /** 节流跳过(距上次检查不足 5 分钟,未访问网络)。 */\n throttled?: boolean\n /** 该来源此前没有快照(迁移/旧记录),本次已回填 commit,尚未有差异基线。 */\n unverified?: boolean\n}\n\n/** POST /api/skill-hub/sources/check */\nexport interface SourceCheckResponse {\n ok: true\n results: SourceCheckResult[]\n}\n\n/** POST /api/skill-hub/sources/sync — 按上游重新下载所选技能并更新快照。 */\nexport interface SourceSyncRequest {\n repo: string\n /** 要同步的技能名;缺省同步该来源全部技能。 */\n skills?: string[]\n}\n\n/** POST /api/skill-hub/sources/sync */\nexport interface SourceSyncResponse {\n ok: true\n repo: string\n /** 同步后的上游 commit SHA。 */\n commitSha: string\n /** 成功同步的技能。 */\n synced: string[]\n /** 失败的技能。 */\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/delete — 跟进上游删除,本地移入回收站。 */\nexport interface SourceDeleteRequest {\n repo: string\n /** 要删除的技能名(移入 .trash)。 */\n skills: string[]\n}\n\n/** POST /api/skill-hub/sources/delete */\nexport interface SourceDeleteResponse {\n ok: true\n /** 已移入回收站的技能。 */\n trashed: string[]\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/restore — 从回收站恢复一个技能。 */\nexport interface SourceRestoreRequest {\n name: string\n}\n\n/** POST /api/skill-hub/sources/restore */\nexport interface SourceRestoreResponse {\n ok: true\n name: string\n path: string\n}\n\n/** POST /api/skill-hub/sources/trash/clear — 永久删除回收站里的全部技能。 */\nexport interface SourceTrashClearResponse {\n ok: true\n /** 已永久删除的技能名。 */\n deleted: string[]\n /** 未能删除的技能(保留在回收站中)。 */\n failed: Array<{ name: string; error: string }>\n}\n","/**\n * Browser-side API client for the /api/skill-hub route family. The only\n * data access path the panel uses — plain fetch, same origin.\n */\nimport {\n SKILL_HUB_API,\n type CatalogResponse,\n type ConfigRequest,\n type ConfigResponse,\n type CreateRequest,\n type CreateResponse,\n type MarketCheckResponse,\n type MarketSourceRefRequest,\n type MarketSourceRequest,\n type MarketSourceResponse,\n type MarketSourcesResponse,\n type MarketSyncResponse,\n type RepoDiscoverResponse,\n type RepoImportRequest,\n type RepoImportResponse,\n type SkillDetail,\n type SkillDetailResponse,\n type SkillDeleteRequest,\n type SkillDeleteResponse,\n type SourceCheckRequest,\n type SourceCheckResponse,\n type SourceDeleteRequest,\n type SourceDeleteResponse,\n type SourceRestoreRequest,\n type SourceRestoreResponse,\n type SourceTrashClearResponse,\n type SourcesResponse,\n type SourceSyncRequest,\n type SourceSyncResponse,\n type StatsResponse,\n type ToggleBatchRequest,\n type ToggleBatchResponse,\n type UpdateCheckResponse,\n} from '../protocol.ts'\n\n/** Error carrying the route's JSON error message. */\nexport class SkillHubApiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'SkillHubApiError'\n }\n}\n\n/** Parse a JSON response or throw a SkillHubApiError. */\nasync function readJson<T>(response: Response): Promise<T> {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new SkillHubApiError('HTTP ' + response.status + ': invalid JSON response')\n }\n if (!response.ok) {\n const message = typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : 'HTTP ' + response.status\n throw new SkillHubApiError(message)\n }\n return body as T\n}\n\n/**\n * Fetch with a hard timeout: a hung connection (proxy, stalled keep-alive,\n * host wedged) must never leave the panel stuck on \"loading\" forever — it\n * fails fast and surfaces the error banner instead.\n */\nasync function fetchWithTimeout(input: RequestInfo | URL, init?: RequestInit, ms = 10_000): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), ms)\n try {\n return await fetch(input, { ...init, signal: controller.signal })\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** The browser half's only data entry point. */\nexport class SkillHubApi {\n /** Catalog lookup options (cwd selects a workspace's project skills). */\n catalog(options?: { cwd?: string }): Promise<CatalogResponse> {\n const url = options?.cwd !== undefined && options.cwd !== '' ? SKILL_HUB_API.catalog + '?cwd=' + encodeURIComponent(options.cwd) : SKILL_HUB_API.catalog\n return fetchWithTimeout(url).then((response) => readJson<CatalogResponse>(response))\n }\n\n /** One skill's detail (cwd selects a workspace's project skills). */\n async skill(name: string, options?: { cwd?: string }): Promise<SkillDetail> {\n const cwd = options?.cwd !== undefined && options.cwd !== '' ? '&cwd=' + encodeURIComponent(options.cwd) : ''\n const url = SKILL_HUB_API.skill + '?name=' + encodeURIComponent(name) + cwd\n const response = await fetchWithTimeout(url)\n const body = await readJson<SkillDetailResponse>(response)\n return body.skill\n }\n\n /** Move one writable skill into the restorable trash. */\n async deleteSkill(name: string): Promise<SkillDeleteResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.skillDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name } satisfies SkillDeleteRequest),\n })\n return readJson<SkillDeleteResponse>(response)\n }\n\n /** Toggle one skill; resolves with the fresh catalog from the route. */\n async toggle(name: string, enabled: boolean): Promise<CatalogResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.toggle, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name, enabled } satisfies import('../protocol.ts').ToggleRequest),\n })\n const body = await readJson<import('../protocol.ts').ToggleResponse>(response)\n return body.catalog\n }\n\n async create(payload: CreateRequest): Promise<CreateResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.create, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<CreateResponse>(response)\n }\n\n async stats(): Promise<StatsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.stats)\n return readJson<StatsResponse>(response)\n }\n\n /** Toggle a whole group in one write; resolves with the fresh catalog + failures. */\n async toggleBatch(names: string[], enabled: boolean): Promise<ToggleBatchResponse> {\n const payload: ToggleBatchRequest = { names, enabled }\n const response = await fetchWithTimeout(SKILL_HUB_API.toggleBatch, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<ToggleBatchResponse>(response)\n }\n\n /** The user's added market sources. */\n async market(): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.market)\n return readJson<MarketSourcesResponse>(response)\n }\n\n /** Add a market source repo; resolves with the fresh list. */\n async addMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSource, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Remove a market source repo; resolves with the fresh list. */\n async removeMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check every market source for updates (throttled server-side). */\n async marketCheck(): Promise<MarketCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketCheck)\n return readJson<MarketCheckResponse>(response)\n }\n\n /** Align a market source to its pinned ref; resolves with tracked skills. */\n async marketSync(repo: string): Promise<MarketSyncResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo }),\n })\n return readJson<MarketSyncResponse>(response)\n }\n\n /** Pin a market source to an explicit ref (branch picker). */\n async setMarketSourceRef(repo: string, ref: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceRef, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo, ref } satisfies MarketSourceRefRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check the hub's own latest GitHub release. */\n async updateCheck(): Promise<UpdateCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.update)\n return readJson<UpdateCheckResponse>(response)\n }\n\n /** Discover importable skills in a GitHub repo. */\n async repoDiscover(repo: string): Promise<RepoDiscoverResponse> {\n const url = SKILL_HUB_API.repo + '?repo=' + encodeURIComponent(repo)\n const response = await fetchWithTimeout(url)\n return readJson<RepoDiscoverResponse>(response)\n }\n\n /** Install selected repo skills into the user-dsh root (records the source). */\n async repoImport(repo: string, paths: string[], ref?: string): Promise<RepoImportResponse> {\n const payload: RepoImportRequest = { repo, paths, ...(ref !== undefined && ref !== '' ? { ref } : {}) }\n const response = await fetchWithTimeout(SKILL_HUB_API.repoImport, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<RepoImportResponse>(response)\n }\n\n /** Read the hub's runtime config (effective values + saved overrides). */\n async config(): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config)\n return readJson<ConfigResponse>(response)\n }\n\n /** Patch the hub's runtime config (null clears a saved override). */\n async saveConfig(patch: ConfigRequest): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n })\n return readJson<ConfigResponse>(response)\n }\n\n /** 用户 tag 分组 + 系统集合组 + origin 映射。 */\n async groups(): Promise<import('../protocol.ts').GroupsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.groups)\n return readJson<import('../protocol.ts').GroupsResponse>(response)\n }\n\n /** 新建(无 id)或重命名(带 id)一个 tag 分组;返回全部 tag。 */\n async saveTag(payload: import('../protocol.ts').TagSaveRequest): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tag, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const body = await readJson<import('../protocol.ts').TagSaveResponse>(response)\n return body.tags\n }\n\n /** 删除一个 tag 分组;返回全部 tag。 */\n async deleteTag(id: string): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id } satisfies import('../protocol.ts').TagDeleteRequest),\n })\n const body = await readJson<import('../protocol.ts').TagDeleteResponse>(response)\n return body.tags\n }\n\n /** 直接设置某 tag 的完整成员列表;返回全部 tag。 */\n async setTagMembers(id: string, skillNames: string[]): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagMembers, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id, skillNames } satisfies import('../protocol.ts').TagMembersRequest),\n })\n const body = await readJson<import('../protocol.ts').TagMembersResponse>(response)\n return body.tags\n }\n\n /** 来源列表 + 派生 origin 映射 + 集合组 + 回收站。 */\n async sources(): Promise<SourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sources)\n return readJson<SourcesResponse>(response)\n }\n\n /** 检查指定(或全部)来源的上游更新。 */\n async checkSources(repo?: string): Promise<SourceCheckResponse> {\n const payload: SourceCheckRequest = repo !== undefined ? { repo } : {}\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceCheck, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceCheckResponse>(response)\n }\n\n /** 同步一个来源的所选(或全部)技能到上游最新版本。 */\n async syncSource(repo: string, skills?: string[]): Promise<SourceSyncResponse> {\n const payload: SourceSyncRequest = skills !== undefined ? { repo, skills } : { repo }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceSyncResponse>(response)\n }\n\n /** 跟进上游删除:把所选技能移入回收站。 */\n async confirmDeleteSource(repo: string, skills: string[]): Promise<SourceDeleteResponse> {\n const payload: SourceDeleteRequest = { repo, skills }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceDeleteResponse>(response)\n }\n\n /** 从回收站恢复一个技能。 */\n async restoreSource(name: string): Promise<SourceRestoreResponse> {\n const payload: SourceRestoreRequest = { name }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceRestore, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceRestoreResponse>(response)\n }\n\n /** Permanently delete every skill currently in the trash. */\n async clearTrash(): Promise<SourceTrashClearResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceTrashClear, { method: 'POST' })\n return readJson<SourceTrashClearResponse>(response)\n }\n}\n","/**\n * dsh-skill-hub surface copy (zh/en). The dictionary type is re-exported\n * so the LocaleNamespaceMap module augmentation in client/index.ts can\n * reference it without a value import.\n */\n\nexport const zh = {\n 'entry.label': '技能',\n 'entry.tooltip': '技能中枢:浏览、分组与同步管理本地技能',\n 'view.sources': '来源',\n 'view.scenes': '场景',\n 'view.market': '市场',\n 'view.flat': '平铺',\n 'view.grouped': '分组',\n 'panel.title': '技能中枢',\n 'panel.count': '共 {count} 个技能',\n 'panel.disabledCount': '已禁用 {count}',\n 'panel.new': '新建技能',\n 'panel.search': '搜索技能…',\n 'legend.model': '模型可调 — Agent 可自动调用',\n 'legend.user': '用户可调 — 仅显式点名时触发',\n 'legend.hint': '每个技能最多一个圆点;无圆点 = 不可被调用。',\n 'panel.enabled': '已启用',\n 'panel.disabled': '已禁用',\n 'panel.diagnostics': '发现诊断',\n 'panel.empty': '没有匹配的技能。',\n 'panel.emptyAll': '本地还没有技能。点击「新建技能」创建第一个。',\n 'panel.loading': '读取中…',\n 'panel.incomplete': '(目录可能不完整)',\n 'panel.workspacePlaceholder': '工作区路径(回车应用)',\n 'panel.workspaceHint': '填写项目路径后,面板同时显示该项目 .dsh/skills 与 .agents/skills 下的技能(只读);留空回车恢复用户级视图。',\n 'panel.workspaceClear': '清除工作区',\n 'market.addPlaceholder': 'owner/repo 或 https://github.com/…',\n 'market.addSource': '添加源',\n 'market.noSources': '还没有市场源。从下方内置市场添加,或输入一个 GitHub 仓库。',\n 'market.title': '市场',\n 'market.catalogHint': '精选技能仓库,添加后即可扫描安装,并持续检查更新。',\n 'market.catalog.anthropics': 'Anthropic 官方技能合集(Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers 社区技能合集',\n 'market.catalog.mattpocock': 'Matt Pocock 技能集',\n 'market.catalog.openDesign': '设计技能合集(design-templates)',\n 'market.add': '添加',\n 'market.installed': '已装 {count}',\n 'market.updatable': '可更新 {count}',\n 'market.deletedUpstream': '上游已删 {count}',\n 'market.checkAll': '检查全部',\n 'market.updateAll': '全部更新',\n 'market.updateAllConfirmTitle': '批量更新全部技能?',\n 'market.updateAllConfirmText': '将把以下来源的可更新技能更新到上游最新版本(覆盖本地修改):',\n 'market.updateAllItem': '{repo}({count} 个技能)',\n 'market.updateAllDone': '已更新 {count} 个来源',\n 'market.deleteSource': '移除源',\n 'market.scan': '扫描',\n 'market.scanning': '扫描中…',\n 'market.check': '检查',\n 'market.sync': '同步',\n 'market.syncing': '同步中…',\n 'market.updated': '有更新',\n 'market.newRelease': '新版本 v{version}',\n 'market.branchTitle': '选择分支',\n 'market.branchHint': '该仓库没有正式发布,选择要跟踪的分支(默认为 main):',\n 'market.branchConfirm': '确定',\n 'market.syncTitle': '同步本地技能',\n 'market.syncText': '市场源已对齐到 {ref},要同步更新以下本地技能吗?',\n 'market.syncNone': '该来源还没有导入本地技能。',\n 'market.syncCancel': '跳过',\n 'market.removeHint': '移除源不影响已安装的技能。',\n 'repo.ready': '发现 {count} 个可导入技能',\n 'repo.empty': '没有找到可导入技能。',\n 'repo.selectAll': '全选',\n 'repo.clearAll': '清空',\n 'repo.import': '导入所选 ({count})',\n 'repo.importing': '导入中…',\n 'repo.existing': '已存在',\n 'repo.files': '{count} 个文件 · {size}',\n 'repo.imported': '导入成功 {count} 个',\n 'repo.skippedExisting': '跳过已存在 {count} 个',\n 'repo.failed': '失败 {count} 个',\n 'repo.root.skills': '技能 skills',\n 'repo.root.designTemplates': '模板 design-templates',\n 'update.check': '检查更新',\n 'update.checking': '检查中…',\n 'update.upToDate': '已是最新版本 v{version}',\n 'update.available': '发现新版本 v{version}(当前 v{current})',\n 'update.newVersion': '新版本 v{version}',\n 'update.viewRelease': '查看发布',\n 'update.error': '检查更新失败:{error}',\n 'update.unavailable': '暂无可用的发布版本',\n 'group.project-dsh': '项目 .dsh/skills',\n 'group.project-agents': '项目 .agents/skills',\n 'group.custom': '自定义目录',\n 'group.runtime': '运行时',\n 'group.user-dsh': '用户 ~/.dsh/skills',\n 'group.user-agents': '用户 ~/.agents/skills',\n 'group.bundled': '内置',\n 'group.other': '其他来源',\n 'groups.new': '新建场景',\n 'groups.namePlaceholder': '场景名',\n 'groups.edit': '编辑',\n 'groups.rename': '保存名称',\n 'groups.delete': '删除场景',\n 'groups.saveMembers': '保存成员',\n 'groups.membersHint': '勾选技能加入此场景(含已禁用)。',\n 'groups.empty': '还没有场景。先新建一个,再把技能归类。',\n 'groups.noCollections': '暂无来源组。从市场导入技能后自动按来源聚合。',\n 'groups.personal': '个人',\n 'groups.project': '项目级',\n 'groups.subdivide': '细分',\n 'groups.merge': '合并',\n 'groups.noWritable': '该组没有可写技能(只读技能无法由中枢开关)',\n 'groups.closeAll': '全部关闭',\n 'groups.keepOn': '保留开启',\n 'groups.conflictTitle': '关闭此组?',\n 'groups.conflictText': '以下技能也在其他组中开启,关闭它们会影响那些组:',\n 'filter.allSources': '全部来源',\n 'filter.private': '个人',\n 'sort.name': '按名称',\n 'sort.added': '按添加时间',\n 'sort.uses': '按调用次数',\n 'time.justNow': '刚刚',\n 'time.minutesAgo': '{value} 分钟前',\n 'time.hoursAgo': '{value} 小时前',\n 'time.daysAgo': '{value} 天前',\n 'time.weeksAgo': '{value} 周前',\n 'badge.source.project-dsh': '项目 .dsh',\n 'badge.source.project-agents': '项目 .agents',\n 'badge.source.custom': '自定义',\n 'badge.source.runtime': '运行时',\n 'badge.source.user-dsh': '用户 .dsh',\n 'badge.source.user-agents': '用户 .agents',\n 'badge.source.bundled': '内置',\n 'row.readonly': '只读',\n 'row.disable': '禁用',\n 'row.enable': '启用',\n 'row.delete': '移入回收站',\n 'row.open': '查看 {name} 详情(回车)',\n 'delete.confirmTitle': '移入回收站?',\n 'delete.confirmText': '确定把「{name}」移入回收站吗?可随时恢复。',\n 'delete.confirm': '移入回收站',\n 'detail.back': '返回列表',\n 'detail.provider': '提供者',\n 'detail.addedAt': '添加时间',\n 'detail.updatedAt': '更新时间',\n 'detail.path': '路径',\n 'detail.whenToUse': '适用场景',\n 'detail.uses': '调用次数',\n 'detail.groups': '所属场景',\n 'detail.loading': '读取技能正文…',\n 'source.private': '个人技能(未绑定上游,不检查更新)',\n 'source.commit': '已同步版本',\n 'source.unverified': '尚未核对上游',\n 'source.check': '检查更新',\n 'source.checkHint': '点击检查上游更新',\n 'source.checking': '检查中…',\n 'source.upToDate': '已是最新',\n 'source.updated': '有更新 {count} 个',\n 'source.deleted': '上游已删除 {count} 个',\n 'source.error': '检查失败',\n 'source.throttled': '刚刚检查过',\n 'source.sync': '同步',\n 'source.syncing': '同步中…',\n 'source.syncConfirmTitle': '同步技能?',\n 'source.syncConfirmText': '将用上游最新版本覆盖本地对以下技能的所有修改:',\n 'source.followDelete': '跟进删除',\n 'source.deleteConfirmTitle': '跟进上游删除?',\n 'source.deleteConfirmText': '以下技能已从上游仓库移除,本地目录将移入回收站(可恢复):',\n 'source.trash': '回收站',\n 'source.restore': '恢复',\n 'source.clearTrash': '清空回收站',\n 'source.clearTrashConfirmTitle': '清空回收站?',\n 'source.clearTrashConfirmText': '回收站里的技能会被永久删除,无法恢复。此操作不可撤销。',\n 'source.clearTrashConfirm': '永久删除',\n 'form.capabilityHint': '能力怎么选:重复方法 → 技能;外部系统 → MCP;长期资料 → 知识库。',\n 'form.descPlaceholder': '一句话说明用途(含触发词),Agent 靠它自动激活技能',\n 'form.name': '技能名(kebab-case,如 code-review)',\n 'form.desc': '描述(一句话路由说明)',\n 'form.root': '目标目录',\n 'form.submit': '创建',\n 'form.cancel': '取消',\n 'form.busy': '创建中…',\n 'form.success': '已创建:',\n 'form.error': '创建失败:',\n 'err.dismiss': '知道了',\n 'settings.title': 'Skill Hub',\n 'settings.description': '管理 dsh 本地技能目录:浏览、分组、来源同步与新建。',\n 'settings.enabled': '启用插件',\n 'settings.enabledHint': '关闭后技能中枢的路由、入口与公告全部下线。',\n 'settings.announceToAgent': '向 Agent 公告',\n 'settings.announceToAgentHint': '在系统提示中加入本插件说明,用户提到技能管理时 Agent 知道如何协作。',\n 'settings.dotModelColor': '模型可调圆点颜色',\n 'settings.dotModelColorHint': '技能行/聊天 / 菜单中「模型可调」蓝色圆点的颜色(#rrggbb)。',\n 'settings.dotUserColor': '用户可调圆点颜色',\n 'settings.dotUserColorHint': '技能行/聊天 / 菜单中「仅用户可调」绿色圆点的颜色(#rrggbb)。',\n 'settings.showUseCount': '显示调用次数',\n 'settings.showUseCountHint': '在技能名旁显示琥珀色调用次数。',\n 'settings.showUseTime': '显示最近调用时间',\n 'settings.showUseTimeHint': '在技能名行右侧显示相对时间(如「3 天前」)。',\n 'settings.showGroupSummary': '显示分组汇总',\n 'settings.showGroupSummaryHint': '在分组标题后汇总调用次数与最近调用时间。',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '恢复默认',\n 'settings.unsaved': '未保存',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.saveFailed': '本部署没有接受这些值,已保留供你修改。',\n 'settings.readOnly': '本部署的设置为只读。',\n 'settings.notExposed': '本部署没有挂载该设置命名空间。',\n 'settings.collapse': '收起设置',\n 'settings.expand': '展开设置',\n} as const\n\nexport const en: Record<HubKey, string> = {\n 'entry.label': 'Skills',\n 'entry.tooltip': 'Skill hub: browse, group, and sync local skills',\n 'view.sources': 'Sources',\n 'view.scenes': 'Scenes',\n 'view.market': 'Market',\n 'view.flat': 'Flat',\n 'view.grouped': 'Grouped',\n 'panel.title': 'Skill Hub',\n 'panel.count': '{count} skills total',\n 'panel.disabledCount': '{count} disabled',\n 'panel.new': 'New Skill',\n 'panel.search': 'Search skills…',\n 'legend.model': 'Model-invocable — agents may call automatically',\n 'legend.user': 'User-invocable — explicit invocation only',\n 'legend.hint': 'At most one dot per skill; no dot = not invocable.',\n 'panel.enabled': 'Enabled',\n 'panel.disabled': 'Disabled',\n 'panel.diagnostics': 'Discovery diagnostics',\n 'panel.empty': 'No matching skills.',\n 'panel.emptyAll': 'No skills installed yet. Create the first one.',\n 'panel.loading': 'Loading…',\n 'panel.incomplete': '(catalog may be incomplete)',\n 'panel.workspacePlaceholder': 'Workspace path (Enter to apply)',\n 'panel.workspaceHint': 'Enter a project path to also show that workspace\\'s .dsh/skills and .agents/skills skills (read-only); clear + Enter to return to the user-level view.',\n 'panel.workspaceClear': 'Clear workspace',\n 'market.addPlaceholder': 'owner/repo or https://github.com/…',\n 'market.addSource': 'Add source',\n 'market.noSources': 'No market sources yet. Add one from the built-in catalog below, or enter a GitHub repo.',\n 'market.title': 'Market',\n 'market.catalogHint': 'Curated skill repos — add one to scan and install, with ongoing update checks.',\n 'market.catalog.anthropics': 'Official Anthropic skill collection (Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers community skill collection',\n 'market.catalog.mattpocock': 'Matt Pocock skill collection',\n 'market.catalog.openDesign': 'Design skill collection (design-templates)',\n 'market.add': 'Add',\n 'market.installed': '{count} installed',\n 'market.updatable': '{count} updatable',\n 'market.deletedUpstream': '{count} deleted upstream',\n 'market.checkAll': 'Check all',\n 'market.updateAll': 'Update all',\n 'market.updateAllConfirmTitle': 'Update every skill?',\n 'market.updateAllConfirmText': 'The updatable skills of these sources will be overwritten with their latest upstream versions:',\n 'market.updateAllItem': '{repo} ({count} skills)',\n 'market.updateAllDone': 'Updated {count} sources',\n 'market.deleteSource': 'Remove source',\n 'market.scan': 'Scan',\n 'market.scanning': 'Scanning…',\n 'market.check': 'Check',\n 'market.sync': 'Sync',\n 'market.syncing': 'Syncing…',\n 'market.updated': 'Updates available',\n 'market.newRelease': 'New release v{version}',\n 'market.branchTitle': 'Choose a branch',\n 'market.branchHint': 'This repo has no releases. Pick a branch to track (main by default):',\n 'market.branchConfirm': 'Confirm',\n 'market.syncTitle': 'Update local skills',\n 'market.syncText': 'Market source aligned to {ref}. Update these local skills?',\n 'market.syncNone': 'No local skills tracked from this repo yet.',\n 'market.syncCancel': 'Skip',\n 'market.removeHint': 'Removing a source does not affect installed skills.',\n 'repo.ready': '{count} importable skills found',\n 'repo.empty': 'No importable skills found.',\n 'repo.selectAll': 'Select all',\n 'repo.clearAll': 'Clear',\n 'repo.import': 'Import selected ({count})',\n 'repo.importing': 'Importing…',\n 'repo.existing': 'Existing',\n 'repo.files': '{count} files · {size}',\n 'repo.imported': 'Imported {count}',\n 'repo.skippedExisting': 'Skipped existing {count}',\n 'repo.failed': 'Failed {count}',\n 'repo.root.skills': 'Skills',\n 'repo.root.designTemplates': 'Templates design-templates',\n 'update.check': 'Check for updates',\n 'update.checking': 'Checking…',\n 'update.upToDate': 'Up to date: v{version}',\n 'update.available': 'Update available: v{version} (current v{current})',\n 'update.newVersion': 'New version v{version}',\n 'update.viewRelease': 'View release',\n 'update.error': 'Update check failed: {error}',\n 'update.unavailable': 'No release available',\n 'group.project-dsh': 'Project .dsh/skills',\n 'group.project-agents': 'Project .agents/skills',\n 'group.custom': 'Custom directories',\n 'group.runtime': 'Runtime',\n 'group.user-dsh': 'User ~/.dsh/skills',\n 'group.user-agents': 'User ~/.agents/skills',\n 'group.bundled': 'Bundled',\n 'group.other': 'Other sources',\n 'groups.new': 'New scene',\n 'groups.namePlaceholder': 'Scene name',\n 'groups.edit': 'Edit',\n 'groups.rename': 'Save name',\n 'groups.delete': 'Delete scene',\n 'groups.saveMembers': 'Save members',\n 'groups.membersHint': 'Check skills to add to this scene (disabled skills included).',\n 'groups.empty': 'No scenes yet. Create one and start categorizing skills.',\n 'groups.noCollections': 'No source groups yet. Import skills from the market to group them by source.',\n 'groups.personal': 'Personal',\n 'groups.project': 'Project',\n 'groups.subdivide': 'Split',\n 'groups.merge': 'Merge',\n 'groups.noWritable': 'No writable skills in this group (read-only skills cannot be switched from the hub)',\n 'groups.closeAll': 'Close all',\n 'groups.keepOn': 'Keep on',\n 'groups.conflictTitle': 'Close this group?',\n 'groups.conflictText': 'These skills are also enabled in other groups; closing them affects those groups:',\n 'filter.allSources': 'All sources',\n 'filter.private': 'Personal',\n 'sort.name': 'By name',\n 'sort.added': 'By added',\n 'sort.uses': 'By uses',\n 'time.justNow': 'just now',\n 'time.minutesAgo': '{value} min ago',\n 'time.hoursAgo': '{value} h ago',\n 'time.daysAgo': '{value} d ago',\n 'time.weeksAgo': '{value} w ago',\n 'badge.source.project-dsh': 'project .dsh',\n 'badge.source.project-agents': 'project .agents',\n 'badge.source.custom': 'custom',\n 'badge.source.runtime': 'runtime',\n 'badge.source.user-dsh': 'user .dsh',\n 'badge.source.user-agents': 'user .agents',\n 'badge.source.bundled': 'bundled',\n 'row.readonly': 'read-only',\n 'row.disable': 'Disable',\n 'row.enable': 'Enable',\n 'row.delete': 'Move to trash',\n 'row.open': 'View {name} details (Enter)',\n 'delete.confirmTitle': 'Move to trash?',\n 'delete.confirmText': 'Move \"{name}\" to trash? It can be restored anytime.',\n 'delete.confirm': 'Move to trash',\n 'detail.back': 'Back to list',\n 'detail.provider': 'Provider',\n 'detail.addedAt': 'Added',\n 'detail.updatedAt': 'Updated',\n 'detail.path': 'Path',\n 'detail.whenToUse': 'When to use',\n 'detail.uses': 'Uses',\n 'detail.groups': 'Groups',\n 'detail.loading': 'Loading skill body…',\n 'source.private': 'Personal skill (not bound to an upstream; no update checks)',\n 'source.commit': 'Synced commit',\n 'source.unverified': 'upstream not verified yet',\n 'source.check': 'Check for updates',\n 'source.checkHint': 'Click to check the upstream for updates',\n 'source.checking': 'Checking…',\n 'source.upToDate': 'Up to date',\n 'source.updated': '{count} updates',\n 'source.deleted': '{count} deleted upstream',\n 'source.error': 'Check failed',\n 'source.throttled': 'Checked recently',\n 'source.sync': 'Sync',\n 'source.syncing': 'Syncing…',\n 'source.syncConfirmTitle': 'Sync skills?',\n 'source.syncConfirmText': 'This overwrites local changes to these skills with the latest upstream version:',\n 'source.followDelete': 'Follow deletion',\n 'source.deleteConfirmTitle': 'Follow upstream deletion?',\n 'source.deleteConfirmText': 'These skills were removed upstream; their local directories move to trash (restorable):',\n 'source.trash': 'Trash',\n 'source.restore': 'Restore',\n 'source.clearTrash': 'Empty trash',\n 'source.clearTrashConfirmTitle': 'Empty the trash?',\n 'source.clearTrashConfirmText': 'Skills in the trash will be permanently deleted and cannot be restored.',\n 'source.clearTrashConfirm': 'Delete permanently',\n 'form.capabilityHint': 'Choosing a capability: repeatable method → skill; external system → MCP; long-term knowledge → knowledge base.',\n 'form.descPlaceholder': 'One line on what it does (with trigger words) — agents auto-activate from this',\n 'form.name': 'Skill name (kebab-case, e.g. code-review)',\n 'form.desc': 'Description (one routing sentence)',\n 'form.root': 'Target root',\n 'form.submit': 'Create',\n 'form.cancel': 'Cancel',\n 'form.busy': 'Creating…',\n 'form.success': 'Created: ',\n 'form.error': 'Create failed: ',\n 'err.dismiss': 'Dismiss',\n 'settings.title': 'Skill Hub',\n 'settings.description': 'Manage the local dsh skill catalog: browse, group, sync, and scaffold skills.',\n 'settings.enabled': 'Enable plugin',\n 'settings.enabledHint': 'Disables the hub routes, entries, and announcement.',\n 'settings.announceToAgent': 'Announce to agent',\n 'settings.announceToAgentHint': 'Adds a system-prompt section so agents know how to collaborate when users mention skill management.',\n 'settings.dotModelColor': 'Model-invocable dot color',\n 'settings.dotModelColorHint': 'Color of the blue \"model-callable\" dot in the skill panel and the chat / menu (#rrggbb).',\n 'settings.dotUserColor': 'User-invocable dot color',\n 'settings.dotUserColorHint': 'Color of the green \"user-only\" dot in the skill panel and the chat / menu (#rrggbb).',\n 'settings.showUseCount': 'Show invocation count',\n 'settings.showUseCountHint': 'Show the amber invocation count beside each skill name.',\n 'settings.showUseTime': 'Show last-used time',\n 'settings.showUseTimeHint': 'Show relative last-used time on the name row (e.g. \"3 d ago\").',\n 'settings.showGroupSummary': 'Show group summaries',\n 'settings.showGroupSummaryHint': 'Summarize invocation count and last-used time after group titles.',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset to default',\n 'settings.unsaved': 'Unsaved',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'settings.readOnly': 'This deployment stores settings read-only.',\n 'settings.notExposed': 'This deployment does not expose the settings namespace.',\n 'settings.collapse': 'Hide settings',\n 'settings.expand': 'Show settings',\n}\n\n/** Union of every translatable key (the namespace's registered dictionary type). */\nexport type HubKey = keyof typeof zh\n\n/** Template values accepted by the interpolator. */\nexport type TranslateValues = Record<string, string | number>\n\n/** Interpolate a {name} template with the given values. */\nexport function t(dict: Record<string, string>, key: HubKey, values?: TranslateValues): string {\n let text = dict[key] ?? key\n if (values !== undefined) {\n for (const [name, value] of Object.entries(values)) {\n text = text.replaceAll('{' + name + '}', String(value))\n }\n }\n return text\n}\n","/**\n * The settings shell renders section nav icons from a hard-coded id map and\n * exposes no registrant icon option, so the skill-hub section falls back to\n * the generic gear. This scoped DOM patch swaps in the official skill icon\n * whenever the settings dialog re-renders.\n */\n\nconst SKILL_SECTION_LABELS = ['技能', 'Skills']\n\nconst SKILL_ICON_SVG = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-skill-hub-nav-icon=\"true\"><path d=\"M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z\" fill=\"currentColor\"/><path d=\"M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z\" fill=\"currentColor\"/></svg>`\n\nlet iconTemplate: SVGSVGElement | null = null\n\nfunction skillIcon(): SVGSVGElement {\n if (iconTemplate === null) {\n iconTemplate = new DOMParser().parseFromString(SKILL_ICON_SVG, 'image/svg+xml').documentElement as unknown as SVGSVGElement\n }\n return iconTemplate.cloneNode(true) as SVGSVGElement\n}\n\nfunction patchNavIcon(): void {\n const dialog = document.querySelector('[role=\"dialog\"]')\n if (dialog === null) return\n for (const button of dialog.querySelectorAll<HTMLButtonElement>('button')) {\n const label = button.querySelector('span')\n if (label === null || !SKILL_SECTION_LABELS.includes(label.textContent?.trim() ?? '')) continue\n if (button.querySelector('svg[data-skill-hub-nav-icon]') !== null) continue\n const current = button.querySelector('svg')\n const icon = skillIcon()\n if (current !== null) current.replaceWith(icon)\n else button.insertBefore(icon, button.firstChild)\n }\n}\n\n/** Swap the settings nav gear for the skill icon and keep it in sync. */\nexport function applySettingsNavIcon(): () => void {\n if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return () => {}\n patchNavIcon()\n const observer = new MutationObserver(() => { patchNavIcon() })\n observer.observe(document.body, { childList: true, subtree: true })\n return () => { observer.disconnect() }\n}\n","/**\n * Pure grouping helpers for the skill-hub panel (no React/DOM deps, so the\n * merge/classify/filter logic stays unit-testable).\n *\n * The \"分组\" view unifies two ways a skill can belong to a group:\n * - user tags (sidecar SkillTag)\n * - origin collections (sidecar sources → backend-aggregated CollectionGroup)\n *\n * Switch semantics: a skill's enabled state is global (the file is renamed\n * once), so a group switch is derived from its members' actual states:\n * all members enabled → 'on', all disabled → 'off', otherwise 'mixed'.\n * Closing a group whose member is enabled in another group is a conflict the\n * GUI resolves with a dialog; the helpers below compute both sides.\n */\n\nimport type { CatalogSkill, CollectionGroup, SkillTag } from '../protocol.ts'\n\n/** Grouped switch state derived from member enablement. */\nexport type GroupSwitchState = 'on' | 'off' | 'mixed'\n\n/** The derived switch view of one group. */\nexport interface GroupSwitchView {\n state: GroupSwitchState\n /** Writable members currently enabled. */\n enabled: string[]\n /** Writable members currently disabled. */\n disabled: string[]\n}\n\n/**\n * Derive a group switch view from its member names and the set of currently\n * enabled skill names (catalog.skills). Members not in the enabled set count\n * as disabled (catalog.disabled or absent read-only rows).\n */\nexport function groupSwitchView(members: readonly string[], enabledNames: ReadonlySet<string>): GroupSwitchView {\n const enabled: string[] = []\n const disabled: string[] = []\n for (const name of members) {\n if (enabledNames.has(name)) enabled.push(name)\n else disabled.push(name)\n }\n const state: GroupSwitchState = disabled.length === 0 ? 'on' : enabled.length === 0 ? 'off' : 'mixed'\n return { state, enabled, disabled }\n}\n\n/** Names of every group a skill belongs to (tags + collections). */\nexport function groupNamesOf(name: string, tags: readonly SkillTag[], collections: readonly CollectionGroup[]): string[] {\n const names: string[] = []\n for (const tag of tags) if (tag.skillNames.includes(name)) names.push(tag.name)\n for (const collection of collections) if (collection.skillNames.includes(name)) names.push(collection.name)\n return names\n}\n\n/**\n * Members of a group that are currently enabled AND also belong to at least\n * one other group — the set a \"close\" action must ask about.\n */\nexport function conflictsOnClose(\n members: readonly string[],\n enabledNames: ReadonlySet<string>,\n otherGroups: ReadonlyArray<{ members: readonly string[] }>,\n): string[] {\n return members.filter((name) => {\n if (!enabledNames.has(name)) return false\n return otherGroups.some((group) => group.members.includes(name))\n })\n}\n\n/** Origin-repo filter value: skills with no source record (private skills). */\nexport const PRIVATE_SOURCE = 'private'\n\n/** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */\nexport function isProjectSource(source: string): boolean {\n return source === 'project-dsh' || source === 'project-agents'\n}\n\n/**\n * Apply the origin filter ('all' or a specific origin repo; skills without a\n * source record count as PRIVATE_SOURCE). The origins map is the store's\n * skillName → repo derivation, so filtering follows the tracked source\n * records instead of the filesystem root a skill happens to live under.\n * 项目级技能(有 workspace 归属)永远不算「个人」。\n */\nexport function filterBySource(skills: readonly CatalogSkill[], source: string, origins: Readonly<Record<string, string>>): CatalogSkill[] {\n if (source === 'all') return [...skills]\n return skills.filter((skill) => {\n if (isProjectSource(skill.source)) return false\n return (origins[skill.name] ?? PRIVATE_SOURCE) === source\n })\n}\n\n/** Catalog sort keys offered by the filter bar. */\nexport type SortKey = 'name' | 'added' | 'uses'\n\n/**\n * Sort a skill list in place-safe copy order: name ascending, added\n * descending (newest first, unknown addedAt last), or uses descending\n * (most-called first). Unknown values always trail.\n */\nexport function sortSkills(skills: readonly CatalogSkill[], key: SortKey, getUses?: (name: string) => number | undefined): CatalogSkill[] {\n const list = [...skills]\n if (key === 'name') {\n list.sort((a, b) => a.name.localeCompare(b.name))\n } else if (key === 'added') {\n list.sort((a, b) => (b.addedAt ?? -Infinity) - (a.addedAt ?? -Infinity))\n } else if (key === 'uses') {\n list.sort((a, b) => (getUses?.(b.name) ?? 0) - (getUses?.(a.name) ?? 0))\n }\n return list\n}\n\n/** Localized relative-time tuple; the caller resolves it via tt(). */\nexport interface RelativeTime {\n key: 'time.justNow' | 'time.minutesAgo' | 'time.hoursAgo' | 'time.daysAgo' | 'time.weeksAgo'\n value?: number\n}\n\n/** Format an epoch-ms timestamp as a short relative time bucket. */\nexport function formatRelativeTime(ms: number, now = Date.now()): RelativeTime {\n const diff = Math.max(0, now - ms)\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return { key: 'time.justNow' }\n if (minutes < 60) return { key: 'time.minutesAgo', value: minutes }\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return { key: 'time.hoursAgo', value: hours }\n const days = Math.floor(hours / 24)\n if (days < 7) return { key: 'time.daysAgo', value: days }\n return { key: 'time.weeksAgo', value: Math.floor(days / 7) }\n}\n","/**\n * Shared panel helpers: the active-dictionary pick (document-language\n * based, family precedent) plus a small error-message extractor.\n */\nimport { en, t, zh, type HubKey, type TranslateValues } from './locales.ts'\n\n/** Active dictionary, picked by the document language at call time. */\nexport function dictionary(): Record<string, string> {\n const lang = typeof document !== 'undefined' ? document.documentElement.lang : 'zh'\n return lang.toLowerCase().startsWith('en') ? { ...en } : { ...zh }\n}\n\n/** Translate a key with optional {name} template params (current language). */\nexport function tt(key: HubKey, values?: TranslateValues): string {\n return t(dictionary(), key, values)\n}\n\n/** Human-readable error text from an unknown thrown value. */\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n\n","/**\n * Shared display helpers for the panel views (skill rows, detail view, and\n * dialogs): dot color styling, relative/absolute time text, and commit-SHA\n * shortening. Kept in one place so the views render identically.\n *\n * The invocation-status dot defaults live here (not in the settings card) so\n * both the panel legend and the chat `/` skill menu draw from one source and\n * so this primitives-free module stays unit-testable.\n */\n\nimport type { CSSProperties } from 'react'\nimport { formatRelativeTime } from '../grouping.ts'\nimport { tt } from '../helpers.ts'\n\n/** Model-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-model (panel.module.css). */\nexport const DEFAULT_DOT_MODEL_COLOR = '#2f81f7'\n/** User-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-user (panel.module.css). */\nexport const DEFAULT_DOT_USER_COLOR = '#3fb950'\n\n/** Dot inline style from the user-chosen color (undefined keeps the CSS default). */\nexport function dotStyle(color: string | undefined): CSSProperties | undefined {\n if (color === undefined) return undefined\n return { background: color, borderColor: color }\n}\n\n/** Localized relative-time text for a Unix-ms timestamp. */\nexport function relativeTimeText(ms: number): string {\n const rt = formatRelativeTime(ms)\n return tt(rt.key, rt.value !== undefined ? { value: rt.value } : undefined)\n}\n\n/** Localized absolute time for the detail meta (e.g. \"2026/8/16 11:00:00\"). */\nexport function formatDateTime(ms: number): string {\n return new Date(ms).toLocaleString()\n}\n\n/** Short form of a commit SHA for display. */\nexport function shortSha(sha: string): string {\n return sha.length > 7 ? sha.slice(0, 7) : sha\n}\n","/**\n * Slash-menu skill dots: puts the invocation-status dot (model-callable blue /\n * user-only green) in front of every skill candidate in the chat `/` menu.\n *\n * Mechanism (mirrors how dsh-at-file fills the menu icon slot): the candidate\n * menu's rows already render an optional `icon` slot (`MenuView` renders\n * `item.icon` in a 16×16 leading span when it's defined), but the core `/skill`\n * source (`dsh-client-ui-skill`) returns candidates without `icon`. This module\n * wraps that source's `candidates` and stamps each row with a colored dot,\n * reusing the same settings (dotModelColor / dotUserColor) and the same\n * `modelInvocable` classification the panel legend uses — so the chat menu and\n * the Settings → 技能 panel stay in sync, and editing the color updates both.\n *\n * The skill source is registered by the core plugin under the `name` \"skill\"\n * on the `/` trigger; re-registering the same name would throw, so this wraps\n * the already-registered source object instead (found through the runtime\n * source registry, which the frozen contract exposes only as `registerSource`\n * / `sessionOf` — the lookup below is defensive: it never throws).\n */\n\nimport type { ClientContext, SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: pulls the Context merge for ctx.inputTriggers.\nimport type {} from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport type { InputTriggerCandidate, InputTriggerServiceContract, InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport { createElement } from 'react'\nimport type { HubSettingsValue } from '../protocol.ts'\nimport type { SkillHubApi } from './api.ts'\nimport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR } from './panel/format.ts'\n\n/** The core plugin's skill source identity on the '/' trigger. */\nconst SKILL_SOURCE = { trigger: '/', name: 'skill' } as const\n\n/** How long one catalog-derived modelInvocable map stays hot before refresh. */\nconst MODEL_TTL_MS = 60_000\n\n/** Runtime view of the source registry (the contract keeps `live` private). */\ntype SourceRegistry = {\n live?: { sources?: InputTriggerSource[] }\n}\n\n/**\n * Find the core `/skill` source through the runtime registry, or undefined.\n * The lookup never throws: a missing/reshaped registry just means no dots. Exported\n * for unit tests; the apply path only calls it indirectly through setupSkillSlashDots.\n * @param service - the ctx.inputTriggers service face.\n * @returns the registered skill source, or undefined.\n */\nexport function findSkillSource(service: InputTriggerServiceContract): InputTriggerSource | undefined {\n const live = (service as unknown as SourceRegistry).live\n if (live?.sources === undefined) return undefined\n return live.sources.find((source) => source.trigger === SKILL_SOURCE.trigger && source.name === SKILL_SOURCE.name)\n}\n\n/** One catalog-derived name → modelInvocable snapshot with a load timestamp. */\nlet modelCache: { at: number; map: Map<string, boolean> } | { at: number; failed: true } | undefined\n\n/**\n * Clear the modelInvocable cache. Called on connection/reset so a fresh\n * catalog wins after reconnect; exported for deterministic unit tests.\n */\nexport function resetModelCache(): void {\n modelCache = undefined\n}\n\n/**\n * Resolve name → modelInvocable from the hub's catalog, cached for\n * MODEL_TTL_MS. A failed load caches the failure briefly so a downed route\n * doesn't hammer the host on every keystroke; the returned map is empty then\n * (callers fall back to the model dot for unknown names).\n * @param api - the hub browser API.\n * @returns name → whether the model may call the skill.\n */\nasync function modelInvocableMap(api: SkillHubApi): Promise<Map<string, boolean>> {\n const now = Date.now()\n const cached = modelCache\n if (cached !== undefined && now - cached.at < MODEL_TTL_MS) {\n return 'failed' in cached ? new Map() : cached.map\n }\n try {\n const catalog = await api.catalog()\n const map = new Map<string, boolean>(catalog.skills.map((skill) => [skill.name, skill.invocation.modelInvocable]))\n modelCache = { at: now, map }\n return map\n } catch (error) {\n console.error('[dsh-skill-hub] slash dot color lookup failed:', error)\n modelCache = { at: now, failed: true }\n return new Map()\n }\n}\n\n/**\n * One menu-row dot element. Inline span so it needs no CSS module; the\n * candidate menu centers it inside its 16×16 leading icon slot.\n * @param color - the dot's background color.\n * @returns a React node (memory-only, never crosses the Host boundary).\n */\nfunction dotIcon(color: string): InputTriggerCandidate['icon'] {\n return createElement('span', {\n 'aria-hidden': true,\n style: {\n display: 'inline-block',\n width: 6,\n height: 6,\n borderRadius: 3,\n background: color,\n flex: 'none',\n },\n }) as unknown as InputTriggerCandidate['icon']\n}\n\n/**\n * Wrap the core skill source so every menu row carries the invocation dot.\n * Exported for unit tests; production wiring goes through setupSkillSlashDots.\n * @param source - the registered `/skill` source.\n * @param api - hub browser API for the modelInvocable lookup.\n * @param scope - hub settings scope for the dot colors.\n * @returns a disposer restoring the original candidates.\n */\nexport function wrapSkillSource(source: InputTriggerSource, api: SkillHubApi, scope: SettingsScope<HubSettingsValue>): () => void {\n const original = source.candidates\n source.candidates = async (session, req) => {\n const items = await original(session, req)\n if (req.signal.aborted) return items\n const modelByName = await modelInvocableMap(api)\n if (req.signal.aborted) return items\n const snapshot = scope.getSnapshot()\n const modelColor = snapshot.value?.dotModelColor ?? DEFAULT_DOT_MODEL_COLOR\n const userColor = snapshot.value?.dotUserColor ?? DEFAULT_DOT_USER_COLOR\n return items.map((item) => ({\n ...item,\n icon: dotIcon((modelByName.get(item.name) ?? true) ? modelColor : userColor),\n }))\n }\n return () => {\n source.candidates = original\n }\n}\n\n/**\n * Mount the slash-menu dots on the registered `/skill` source. Idempotent and\n * defensive: if the core source isn't registered yet (or the registry shape\n * changes), it retries briefly and then gives up silently — the chat keeps\n * working, it simply shows no dots. The returned disposer restores the\n * original candidates and clears the model cache.\n * @param ctx - the client root context (inputTriggers + events).\n * @param api - hub browser API.\n * @param scope - hub settings scope for dot colors.\n * @returns a cleanup function for `ctx.effect`.\n */\nexport function setupSkillSlashDots(\n ctx: ClientContext,\n api: SkillHubApi,\n scope: SettingsScope<HubSettingsValue>,\n): () => void {\n const inputTriggers = ctx.get('inputTriggers')\n if (inputTriggers === undefined) return () => {}\n\n let disposed = false\n let restore: (() => void) | undefined\n let attempts = 0\n\n // The core ui-skill source registers early in the bundle, but not strictly\n // before this apply runs — poll briefly so order never matters.\n const attempt = (): void => {\n if (disposed) return\n const source = findSkillSource(inputTriggers)\n if (source === undefined) {\n if (attempts < 10) {\n attempts += 1\n setTimeout(attempt, 100)\n }\n return\n }\n restore = wrapSkillSource(source, api, scope)\n }\n attempt()\n\n const clearCache = (): void => {\n resetModelCache()\n }\n // ctx.on returns the listener disposer; cordis has no ctx.off.\n const offReset = ctx.on('connection/reset', clearCache)\n\n return () => {\n disposed = true\n offReset()\n restore?.()\n restore = undefined\n }\n}\n","/**\n * Vendored UI icons for dsh-skill-hub.\n *\n * These were originally imported from `@deepseek-ai/dsh-client-ui-primitives`.\n * That package is still published for the rc.7/rc.2 SDK families, but newer dsh\n * web builds no longer expose it as a standalone plugin module — they keep a\n * static compatibility module instead. Vendoring the few tiny outline icons the\n * hub uses makes the browser half self-contained and equally compatible with\n * older and newer dsh hosts.\n *\n * SVG paths are copied verbatim from dsh-client-ui-primitives (MIT licensed)\n * so the visuals remain pixel-identical to the dsh icon family.\n */\n\nimport type { JSX } from 'react'\n\n/** Props understood by the dsh icon family: size + optional className. */\nexport interface IconProps {\n size?: number\n className?: string\n}\n\n/** ic_ds_chevron_down_outline_14 */\nexport function IconChevronDownOutline14({ size = 14, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 14 14' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z'\n fill='currentColor'\n />\n </svg>\n )\n}\n\n/** ic_ds_trash_outline_16 */\nexport function IconTrashOutline16({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M14.4782 4.84067L14.2138 10.1152C14.1102 12.1872 14.067 13.0115 13.3866 13.9607C13.1044 14.3546 12.7498 14.6912 12.3424 14.9535C11.8239 15.2872 11.2415 15.4316 10.5585 15.4998C9.88727 15.5668 9.04946 15.5656 7.99998 15.5656C6.95051 15.5656 6.1127 15.5668 5.44142 15.4998C4.75851 15.4316 4.17602 15.2872 3.65753 14.9535C3.25012 14.6912 2.89559 14.3546 2.61332 13.9607C1.93296 13.0115 1.88979 12.1872 1.78619 10.1152L1.52179 4.84067L2.89006 4.77277L3.15343 10.0463C3.26221 12.2218 3.32452 12.6015 3.72646 13.1624C3.90825 13.4161 4.13686 13.6334 4.39927 13.8023C4.66204 13.9714 5.00263 14.0792 5.57825 14.1367C6.16562 14.1953 6.92298 14.1963 7.99998 14.1963C9.07699 14.1963 9.83434 14.1953 10.4217 14.1367C10.9973 14.0792 11.3379 13.9714 11.6007 13.8023C11.8631 13.6334 12.0917 13.4161 12.2735 13.1624C12.6755 12.6015 12.7378 12.2218 12.8465 10.0463L13.1099 4.77277L14.4782 4.84067ZM5.43011 6.22849H6.7994V11.3909H5.43011V6.22849ZM9.20056 6.22849H10.5699V11.3909H9.20056V6.22849ZM8.53597 0.434431C9.17976 0.434431 9.6522 0.426926 10.0966 0.571258C10.2357 0.616451 10.3717 0.672554 10.502 0.738948C10.9182 0.951107 11.2464 1.29099 11.7015 1.74612L12.4978 2.54136H15.3742V3.91169H0.625732V2.54136H3.50218L4.29845 1.74612C4.75358 1.29099 5.08174 0.951107 5.49801 0.738948C5.62831 0.672554 5.76425 0.616451 5.90334 0.571258C6.34776 0.426926 6.82021 0.434431 7.46399 0.434431H8.53597ZM7.46399 1.80476C6.73208 1.80476 6.51641 1.81187 6.32617 1.87369C6.25545 1.89667 6.18668 1.92533 6.12041 1.95907C5.96398 2.03878 5.82348 2.16253 5.44142 2.54136H10.5585C10.1765 2.16253 10.036 2.03878 9.87955 1.95907C9.81329 1.92533 9.74452 1.89667 9.6738 1.87369C9.48356 1.81187 9.26789 1.80476 8.53597 1.80476H7.46399Z'\n fill='currentColor'\n />\n </svg>\n )\n}\n\n/** ic_ds_skill_outline_16 */\nexport function IconSkillOutline16({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z'\n fill='currentColor'\n />\n <path\n d='M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z'\n fill='currentColor'\n />\n </svg>\n )\n}","/**\n * Shared chrome for the plugin settings card, aligned with the official\n * dsh-client-ui-settings-plugins PluginCard design language: the same tokens,\n * disclosure header, field rhythm, and copy. Renders nothing while the\n * namespace is unavailable — a deployment that does not compose the owning\n * plugin should show no trace of it.\n */\n\nimport { useState, type ReactElement } from 'react'\nimport { IconChevronDownOutline14 } from './icons.tsx'\nimport type { HubKey } from './locales.ts'\nimport type { CardShell } from './settings-form.ts'\nimport css from './settings-card.module.css'\n\n/** Card-level chrome props. */\nexport interface PluginSettingsCardProps {\n /** Locale translator for the owning plugin's namespace (its own key domain). */\n t: (key: HubKey) => string\n /** Locale key of the card title. */\n titleKey: HubKey\n /** Locale key of the card description. */\n descriptionKey: HubKey\n /** The form shell state. */\n state: CardShell\n onSave: () => void\n onDiscard: () => void\n children?: ReactElement | ReactElement[]\n}\n\n/**\n * Render one plugin settings card.\n * @param props - the plugin's copy keys, its form state, and its controls.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function PluginSettingsCard(props: PluginSettingsCardProps): ReactElement | null {\n const [open, setOpen] = useState(false)\n const { state } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const blocked = !state.dirty || state.invalid || state.saving\n\n const header = (\n <button\n type='button'\n className={css.header}\n aria-expanded={open}\n aria-label={props.t(open ? 'settings.collapse' : 'settings.expand') + ': ' + title}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{props.t('settings.unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? css.chevronOpen : css.chevron} />\n </button>\n )\n\n if (!state.exposed) {\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? <div className={css.body}><p className={css.notExposed} role='status'>{props.t('settings.notExposed')}</p></div> : null}\n </li>\n )\n }\n\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role='status'>{props.t('settings.readOnly')}</p> : null}\n {props.children}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role='status'>{props.t('settings.saveFailed')}</p> : null}\n <button type='button' className={css.discard} disabled={!state.dirty || state.saving} onClick={props.onDiscard}>\n {props.t('settings.discard')}\n </button>\n <button type='button' className={css.save} disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n )\n}\n\n/** One staged boolean field: 继承 / 开 / 关. */\nexport interface BooleanFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n onLabel: string\n offLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n text: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function BooleanField(props: BooleanFieldProps): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <select id={props.id} className={css.input} value={props.text} disabled={props.disabled} onChange={(event) => { props.onEdit(event.target.value) }}>\n <option value=''>{props.inheritLabel}</option>\n <option value='true'>{props.onLabel}</option>\n <option value='false'>{props.offLabel}</option>\n </select>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n\n/**\n * A compact sliding switch for the card's master enable/disable control.\n * An empty text value means the field inherits its default; the switch still\n * reflects the effective default and becomes an explicit override on click.\n */\nexport interface SwitchFieldProps {\n label: string\n hint: string\n disabled: boolean\n text: string\n overridden: boolean\n overriddenLabel: string\n resetLabel: string\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function SwitchField(props: SwitchFieldProps): ReactElement {\n const checked = props.text !== 'false'\n return (\n <div className={css.field}>\n <div className={css.switchRow}>\n <div className={css.switchText}>\n <div className={css.head}>\n <span className={css.label}>{props.label}</span>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n <button\n type='button'\n className={checked ? css.switchOn : css.switch}\n role='switch'\n aria-checked={checked}\n aria-label={props.label}\n disabled={props.disabled}\n onClick={() => { props.onEdit(String(!checked)) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n </div>\n )\n}\n\n/** One staged color field: a native color picker plus the hex draft text. */\nexport interface ColorFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n /** Effective hex (#rrggbb) when overridden; empty string means inherit. */\n text: string\n /** The default color the picker shows while inheriting (per-field). */\n defaultColor: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function ColorField(props: ColorFieldProps): ReactElement {\n const value = /^#[0-9a-f]{6}$/i.test(props.text) ? props.text : props.defaultColor\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <div className={css.colorRow}>\n <input\n id={props.id}\n type='color'\n className={css.colorInput}\n value={value}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <input\n type='text'\n className={css.input + ' ' + css.colorText}\n value={props.text}\n disabled={props.disabled}\n placeholder={props.inheritLabel}\n onChange={(event) => { props.onEdit(event.target.value.trim()) }}\n />\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","/**\n * Settings-card form machinery, vendored from the dsh-web-ui family bucket\n * (packages/dsh-task-board/src/client/settings-form.ts) and re-typed. Stages\n * one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\n\nimport { createSnapshotStore, type SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** One staged field: its draft text plus the clear/reset marker. */\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\n/** One editable field spec: formatting plus text parsing. */\nexport interface FieldSpec {\n field: string\n format: (value: unknown) => string\n parse: (text: string) => { kind: 'set'; value: unknown } | { kind: 'clear' } | undefined\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n if (text === 'true') return { kind: 'set', value: true }\n if (text === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/** A #rrggbb color field, edited through hex draft text. */\nexport function colorField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value) ? value : ''),\n parse: (text) => {\n if (/^#[0-9a-f]{6}$/i.test(text)) return { kind: 'set', value: text }\n return undefined\n },\n }\n}\n\n/** Card-level state the chrome renders. */\nexport interface CardShell {\n available: boolean\n exposed: boolean\n writable: boolean\n dirty: boolean\n invalid: boolean\n saving: boolean\n failed: boolean\n}\n\n/** One field's state from the effective section and its staged draft. */\nexport interface FieldState {\n text: string\n overridden: boolean\n invalid: boolean\n}\n\n/** The settings scope face the form consumes (subset of SettingsScope<T>). */\nexport interface FormScope {\n subscribe(listener: () => void): () => void\n getSnapshot(): { status: string; writable: boolean; value?: Record<string, unknown>; base?: unknown; user?: unknown }\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/** Stages one card's edits and writes them through the settings transport. */\nexport class CardForm {\n private readonly scope: FormScope\n private readonly specs = new Map<string, FieldSpec>()\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /** @param scope - the bound settings scope for this card's namespace. */\n constructor(scope: FormScope, specs: FieldSpec[]) {\n this.scope = scope\n for (const spec of specs) this.specs.set(spec.field, spec)\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<T>(project: () => T) {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return { text: staged.text, overridden: write?.kind === 'set', invalid: write === undefined }\n }\n\n /** The actions the card's slot registration injects. */\n actions() {\n return {\n edit: (field: string, text: string) => { this.stage(field, { text, clear: false }) },\n resetField: (field: string) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /** Write every staged edit, then re-seed from what the Host accepted. */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap((item) => (item.run === undefined ? [] : [item.run]))\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) landed = (await write()) && landed\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n /** Every staged edit a save would write, in staging order. */\n plan(): Array<{ field: string; run: (() => Promise<boolean>) | undefined }> {\n const plan: Array<{ field: string; run: (() => Promise<boolean>) | undefined }> = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n }\n\n private userRecord(): Record<string, unknown> | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null ? user as Record<string, unknown> : undefined\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error('settings card has no field ' + field)\n return spec\n }\n\n private sectionValue(field: string): unknown {\n return this.scope.getSnapshot().value?.[field]\n }\n\n private baseValue(field: string): unknown {\n const base = this.scope.getSnapshot().base\n return typeof base === 'object' && base !== null ? (base as Record<string, unknown>)[field] : undefined\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.userRecord()\n }\n\n private stored(field: string): boolean {\n const user = this.userRecord()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n\n","/**\n * The dsh-skill-hub plugin settings card: bridges the hub's settings\n * namespace (bound through the official settings transport) onto the\n * family-style staged card form (enabled master switch + agent announcement).\n * Registered into the official `settings.plugin.item` slot keyed by that\n * namespace, so the plugin shows up in Settings → 插件 on dsh rc.7+.\n */\n\nimport type { ReactElement } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { ColorField, PluginSettingsCard, SwitchField } from './settings-card.tsx'\nimport { booleanField, CardForm, colorField, type CardShell, type FieldState, type FormScope } from './settings-form.ts'\n// Single source for the TS-side dot defaults (the panel CSS mirrors these).\nimport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR } from './panel/format.ts'\n// Re-export for any consumer that imported them from the card before the move.\nexport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR }\n\n/** The card's projected state. */\nexport interface SkillHubSettingsState extends CardShell {\n enabled: FieldState\n announceToAgent: FieldState\n dotModelColor: FieldState\n dotUserColor: FieldState\n showUseCount: FieldState\n showUseTime: FieldState\n showGroupSummary: FieldState\n}\n\n/** The business face the card's slot registration injects. */\nexport interface SkillHubSettingsCardFace {\n hooks: {\n /** The card's snapshot store (projected form state). */\n skillHubSettingsCard: SnapshotStore<SkillHubSettingsState>\n }\n save: () => void\n discard: () => void\n edit: (field: string, text: string) => void\n resetField: (field: string) => void\n}\n\n/** Props the slot renderer binds (locale copy + injected form actions). */\nexport type SkillHubSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'dsh-skill-hub'> & InjectFace<SkillHubSettingsCardFace>\n\n/** Bridges the hub's config scope onto the card's staged form. */\nexport class SkillHubSettingsCardController {\n private readonly form: CardForm\n private readonly store: SnapshotStore<SkillHubSettingsState>\n\n /** @param scope - the hub settings scope the card edits (FormScope-compatible). */\n constructor(scope: FormScope) {\n this.form = new CardForm(scope, [booleanField('enabled'), booleanField('announceToAgent'), colorField('dotModelColor'), colorField('dotUserColor'), booleanField('showUseCount'), booleanField('showUseTime'), booleanField('showGroupSummary')])\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): SkillHubSettingsState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n announceToAgent: this.form.field('announceToAgent'),\n dotModelColor: this.form.field('dotModelColor'),\n dotUserColor: this.form.field('dotUserColor'),\n showUseCount: this.form.field('showUseCount'),\n showUseTime: this.form.field('showUseTime'),\n showGroupSummary: this.form.field('showGroupSummary'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot hook and its form actions.\n */\n inject(): SkillHubSettingsCardFace {\n return {\n hooks: { skillHubSettingsCard: this.store },\n ...this.form.actions(),\n }\n }\n}\n\n/**\n * Render the dsh-skill-hub card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function SkillHubSettingsCard(props: SkillHubSettingsCardProps): ReactElement {\n const { t } = props\n const state = props.useSkillHubSettingsCard((snapshot) => snapshot)\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n disabled,\n }\n return (\n <PluginSettingsCard\n t={t}\n titleKey='settings.title'\n descriptionKey='settings.description'\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <SwitchField\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <SwitchField\n label={t('settings.announceToAgent')}\n hint={t('settings.announceToAgentHint')}\n {...fieldProps}\n {...state.announceToAgent}\n onEdit={(text) => { props.edit('announceToAgent', text) }}\n onReset={() => { props.resetField('announceToAgent') }}\n />\n <ColorField\n id='skill-hub-dot-model-color'\n label={t('settings.dotModelColor')}\n hint={t('settings.dotModelColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_MODEL_COLOR}\n {...fieldProps}\n {...state.dotModelColor}\n onEdit={(text) => { props.edit('dotModelColor', text) }}\n onReset={() => { props.resetField('dotModelColor') }}\n />\n <ColorField\n id='skill-hub-dot-user-color'\n label={t('settings.dotUserColor')}\n hint={t('settings.dotUserColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_USER_COLOR}\n {...fieldProps}\n {...state.dotUserColor}\n onEdit={(text) => { props.edit('dotUserColor', text) }}\n onReset={() => { props.resetField('dotUserColor') }}\n />\n <SwitchField\n label={t('settings.showUseCount')}\n hint={t('settings.showUseCountHint')}\n {...fieldProps}\n {...state.showUseCount}\n onEdit={(text) => { props.edit('showUseCount', text) }}\n onReset={() => { props.resetField('showUseCount') }}\n />\n <SwitchField\n label={t('settings.showUseTime')}\n hint={t('settings.showUseTimeHint')}\n {...fieldProps}\n {...state.showUseTime}\n onEdit={(text) => { props.edit('showUseTime', text) }}\n onReset={() => { props.resetField('showUseTime') }}\n />\n <SwitchField\n label={t('settings.showGroupSummary')}\n hint={t('settings.showGroupSummaryHint')}\n {...fieldProps}\n {...state.showGroupSummary}\n onEdit={(text) => { props.edit('showGroupSummary', text) }}\n onReset={() => { props.resetField('showGroupSummary') }}\n />\n </PluginSettingsCard>\n )\n}\n","/**\n * Source check-status badges (up-to-date / updated / deleted / error /\n * throttled / unverified). Shared by the panel's source-group headers and\n * the skill detail view.\n *\n * In the group headers the badge doubles as the re-check affordance: it\n * shows a clickable \"检查更新\" badge before the first check, \"检查中…\" while\n * checking, and the status badge (clickable again to re-check) afterwards.\n */\n\nimport type { JSX } from 'react'\nimport type { SourceCheckResult } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport function SourceStatusBadge(props: {\n check: SourceCheckResult | undefined\n /** 正在检查该来源(显示「检查中…」)。 */\n checking?: boolean\n /** 提供后徽章区域可点击触发检查(组头用;详情页有自己的检查按钮)。 */\n onCheck?: () => void\n}): JSX.Element | null {\n const { check, checking, onCheck } = props\n if (checking === true) {\n return <span className={css.statusBadge}>{tt('source.checking')}</span>\n }\n if (check === undefined) {\n if (onCheck === undefined) return null\n return (\n <button type='button' className={css.statusBadge + ' ' + css.statusButton} title={tt('source.checkHint')} onClick={onCheck}>\n {tt('source.check')}\n </button>\n )\n }\n const badges = ((): JSX.Element | null => {\n if (check.error !== undefined) {\n return <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.error')}</span>\n }\n if (check.throttled === true) {\n return <span className={css.statusBadge}>{tt('source.throttled')}</span>\n }\n if (check.unverified === true) {\n return <span className={css.statusBadge}>{tt('source.unverified')}</span>\n }\n if (check.changed) {\n return (\n <span className={css.statusBadges}>\n {check.updated.length > 0 ? <span className={css.statusBadge + ' ' + css.statusUpdated}>{tt('source.updated', { count: check.updated.length })}</span> : null}\n {check.deleted.length > 0 ? <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.deleted', { count: check.deleted.length })}</span> : null}\n </span>\n )\n }\n return <span className={css.statusBadge + ' ' + css.statusOk}>{tt('source.upToDate')}</span>\n })()\n if (onCheck === undefined) return badges\n return (\n <button type='button' className={css.statusWrap} title={tt('source.checkHint')} onClick={onCheck}>\n {badges}\n </button>\n )\n}\n","/**\n * Full-page skill detail view: metadata, upstream source card with\n * check/sync/follow-delete actions, and the raw SKILL.md body. Pure\n * presentation — every state value and action arrives as a prop, so the\n * panel stays the single owner of state.\n */\n\nimport type { JSX } from 'react'\nimport type { GroupsResponse, HubConfig, SkillDetail, SourceCheckResult, SourcesResponse } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\nimport { dotStyle, formatDateTime, shortSha } from './format.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\n\nexport interface SkillDetailViewProps {\n detail: SkillDetail\n hubConfig: HubConfig | null\n /** skillName → usage stat (count + last used). */\n uses: ReadonlyMap<string, { count: number; lastUsed?: number }>\n groupsState: GroupsResponse | null\n sourcesState: SourcesResponse | null\n sourceCheck: Readonly<Record<string, SourceCheckResult>>\n checkingSource: string | null\n syncingSource: string | null\n loading: boolean\n onBack: () => void\n /** Check one source repo for upstream updates. */\n onCheck: (repo: string) => void\n /** Request syncing the skill (overwrites local edits; opens a confirm). */\n onSync: (repo: string, skills: string[]) => void\n /** Request following the upstream deletion (moves into the trash). */\n onFollowDelete: (repo: string, skills: string[]) => void\n}\n\nexport function SkillDetailView(props: SkillDetailViewProps): JSX.Element {\n const { detail, hubConfig, uses, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource, loading, onBack, onCheck, onSync, onFollowDelete } = props\n const detailSource = sourcesState?.sources.find((source) => source.skills.includes(detail.name))\n const detailCheck = detailSource !== undefined ? sourceCheck[detailSource.repo] : undefined\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <span className={css.detailName}>\n {detail.name}\n {/* 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */}\n {detail.invocation.modelInvocable\n ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} title={tt('legend.model')} />\n : detail.invocation.userInvocable\n ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} title={tt('legend.user')} />\n : null}\n </span>\n </div>\n <div className={css.detailMeta}>\n <div className={css.detailMetaLine}>{tt('detail.provider')}: {detail.provider}</div>\n {detail.addedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.addedAt')}: {formatDateTime(detail.addedAt)}</div> : null}\n {detail.updatedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.updatedAt')}: {formatDateTime(detail.updatedAt)}</div> : null}\n {detail.path !== undefined ? <div className={css.detailMetaLine}>{tt('detail.path')}: {detail.path}</div> : null}\n {detail.whenToUse !== undefined ? <div className={css.detailMetaLine}>{tt('detail.whenToUse')}: {detail.whenToUse}</div> : null}\n {(() => {\n const stat = uses.get(detail.name)\n if (stat === undefined || stat.count === 0) return null\n const at = stat.lastUsed !== undefined ? ' · ' + new Date(stat.lastUsed).toLocaleString() : ''\n return <div className={css.detailMetaLine}>{tt('detail.uses')}: {stat.count}{at}</div>\n })()}\n {(() => {\n const tags = (groupsState?.tags ?? []).filter((tag) => tag.skillNames.includes(detail.name)).map((tag) => tag.name)\n return tags.length > 0 ? <div className={css.detailMetaLine}>{tt('detail.groups')}: {tags.join(', ')}</div> : null\n })()}\n </div>\n {detailSource !== undefined ? (\n <div className={css.sourceCard}>\n <div className={css.sourceCardTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + detailSource.repo} target='_blank' rel='noreferrer'>{detailSource.repo}</a>\n {detailSource.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{detailSource.ref}</span> : null}\n <SourceStatusBadge check={detailCheck} />\n </div>\n <div className={css.detailMetaLine}>\n {tt('source.commit')}: {detailSource.commitSha === '' ? tt('source.unverified') : shortSha(detailSource.commitSha)}\n </div>\n <div className={css.buttons + ' ' + css.actionsTop}>\n <button type='button' className={css.opBtn} disabled={checkingSource !== null} onClick={() => { onCheck(detailSource.repo) }}>\n {checkingSource === detailSource.repo ? tt('source.checking') : tt('source.check')}\n </button>\n <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={() => { onSync(detailSource.repo, [detail.name]) }}>\n {syncingSource === detailSource.repo ? tt('source.syncing') : tt('source.sync')}\n </button>\n {detailCheck?.deleted.includes(detail.name) === true\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={() => { onFollowDelete(detailSource.repo, [detail.name]) }}>{tt('source.followDelete')}</button>\n : null}\n </div>\n </div>\n ) : (\n <p className={css.hintLine}>{tt('source.private')}</p>\n )}\n {loading ? <div className={css.muted}>{tt('detail.loading')}</div> : null}\n <pre className={css.detailContent}>{detail.content}</pre>\n </div>\n )\n}\n","/**\n * Full-page tag (scene) editor: rename / delete header, member checkbox\n * lists (enabled + disabled skills), and the save-members action. Pure\n * presentation — the draft state lives in the panel and arrives as props.\n */\n\nimport type { JSX } from 'react'\nimport type { CatalogResponse, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport interface TagEditorViewProps {\n tag: SkillTag\n /** Current name draft (panel-owned). */\n editName: string\n /** Current member-checkbox draft (panel-owned). */\n membersDraft: ReadonlySet<string>\n /** Current member-list search text (panel-owned). */\n editSearch: string\n catalog: CatalogResponse | null\n tagBusy: boolean\n onBack: () => void\n onEditName: (value: string) => void\n onEditSearch: (value: string) => void\n onToggleMember: (name: string, checked: boolean) => void\n /** Rename with the current draft (disabled while blank). */\n onRename: () => void\n /** Delete this tag (hidden for the default scene). */\n onDelete: () => void\n /** Persist the current member draft and leave the editor. */\n onSaveMembers: () => void\n}\n\nexport function TagEditorView(props: TagEditorViewProps): JSX.Element {\n const { tag, editName, membersDraft, editSearch, catalog, tagBusy, onBack, onEditName, onEditSearch, onToggleMember, onRename, onDelete, onSaveMembers } = props\n const editQuery = editSearch.trim().toLocaleLowerCase()\n const editSkills = (catalog?.skills ?? []).filter((skill) => editQuery.length === 0 || skill.name.toLocaleLowerCase().includes(editQuery) || skill.description.toLocaleLowerCase().includes(editQuery))\n const editDisabled = (catalog?.disabled ?? []).filter((record) => editQuery.length === 0 || record.name.toLocaleLowerCase().includes(editQuery) || record.description.toLocaleLowerCase().includes(editQuery))\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <input\n className={css.input + ' ' + css.grow}\n value={editName}\n onChange={(event) => { onEditName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='button' className={css.opBtn} disabled={tagBusy || editName.trim() === ''} onClick={onRename}>{tt('groups.rename')}</button>\n {tag.default !== true\n ? <button type='button' className={css.opBtn} disabled={tagBusy} onClick={onDelete}>{tt('groups.delete')}</button>\n : null}\n </div>\n <p className={css.hintLine}>{tt('groups.membersHint')}</p>\n <input className={css.search} value={editSearch} onChange={(event) => { onEditSearch(event.target.value) }} placeholder={tt('panel.search')} />\n <div className={css.section}>\n {editSkills.map((skill) => (\n <label key={skill.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(skill.name)}\n onChange={(event) => { onToggleMember(skill.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{skill.name}</div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n </label>\n ))}\n {editDisabled.map((record) => (\n <label key={record.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(record.name)}\n onChange={(event) => { onToggleMember(record.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description} · {tt('panel.disabled')}</div>\n </div>\n </label>\n ))}\n </div>\n <div className={css.buttons}>\n <button type='button' className={css.button + ' ' + css.primary} disabled={tagBusy} onClick={onSaveMembers}>{tt('groups.saveMembers')}</button>\n </div>\n </div>\n )\n}\n","/**\n * One enabled skill row: name + invocation dots + usage meta, delete and\n * disable actions. Shared by the flat list and both grouped views.\n */\n\nimport type { JSX, KeyboardEvent } from 'react'\nimport type { CatalogSkill } from '../../protocol.ts'\nimport { IconTrashOutline16 } from '../icons.tsx'\nimport { tt } from '../helpers.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function SkillRow(props: { skill: CatalogSkill; hub: SkillHubState }): JSX.Element {\n const { skill, hub } = props\n const stat = hub.uses.get(skill.name)\n const count = stat?.count ?? 0\n const lastUsed = stat?.lastUsed\n /** 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */\n const dot = skill.invocation.modelInvocable\n ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hub.hubConfig?.dotModelColor)} title={tt('legend.model')} />\n : skill.invocation.userInvocable\n ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hub.hubConfig?.dotUserColor)} title={tt('legend.user')} />\n : null\n /** 键盘打开详情:Enter 或空格。仅当焦点在行本身(而非行内按钮)时生效。 */\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {\n if (event.target !== event.currentTarget) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n void hub.openDetail(skill.name)\n }\n }\n return (\n <div\n className={css.row}\n role='button'\n tabIndex={0}\n aria-label={tt('row.open', { name: skill.name })}\n onClick={() => { void hub.openDetail(skill.name) }}\n onKeyDown={onKeyDown}\n >\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <span className={css.rowNameText}>{skill.name}</span>\n {count > 0 && hub.hubConfig?.showUseCount !== false ? <span className={css.useCount}>{count}</span> : null}\n {dot}\n {lastUsed !== undefined && hub.hubConfig?.showUseTime !== false ? <span className={css.useTime}>{relativeTimeText(lastUsed)}</span> : null}\n </div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n {skill.writable\n ? <>\n <button\n type='button'\n className={css.opBtn + ' ' + css.opDanger + ' ' + css.iconBtn}\n disabled={hub.busyNames.has(skill.name) || hub.tagBusy}\n title={tt('row.delete')}\n aria-label={tt('row.delete')}\n onClick={(event) => { event.stopPropagation(); hub.requestDeleteSkill(skill.name) }}\n ><IconTrashOutline16 size={14} /></button>\n <button\n type='button'\n role='switch'\n aria-checked={true}\n aria-label={tt('row.disable')}\n className={css.switch + ' ' + css.switchOn}\n disabled={hub.busyNames.has(skill.name)}\n onClick={(event) => { event.stopPropagation(); void hub.toggle(skill, false) }}\n ><span className={css.switchThumb} /></button>\n </>\n : <span className={css.badge + ' ' + css.badgeReadonly}>{tt('row.readonly')}</span>}\n </div>\n )\n}\n","/**\n * One disabled skill row (name + description + root badge + enable switch).\n * Shared by the source-group lists, the scene-group lists, and the bottom\n * disabled section.\n */\n\nimport type { JSX } from 'react'\nimport type { DisabledSkill, WritableRoot } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport type { HubKey } from '../locales.ts'\nimport css from './panel.module.css'\n\n/** Source badge label for a disabled record, derived from its writable root. */\nfunction disabledSourceLabel(root: WritableRoot): string {\n return tt(('badge.source.' + root) as HubKey)\n}\n\nexport function DisabledRow(props: { record: DisabledSkill; busy: boolean; onEnable: () => void }): JSX.Element {\n const { record, busy, onEnable } = props\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description}</div>\n </div>\n <span className={css.badges}>\n <span className={css.badge + ' ' + css.badgeSource}>{disabledSourceLabel(record.root)}</span>\n </span>\n <button type='button' role='switch' aria-checked={false} aria-label={tt('row.enable')} className={css.switch} disabled={busy} onClick={onEnable}><span className={css.switchThumb} /></button>\n </div>\n )\n}\n","/**\n * Group-header usage summary: total invocation count chip + the group's most\n * recent last-used time. Honours the showGroupSummary config switch.\n */\n\nimport type { JSX } from 'react'\nimport { relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function GroupSummary(props: { members: readonly string[]; hub: SkillHubState }): JSX.Element {\n const { members, hub } = props\n let total = 0\n let latest: number | undefined\n for (const name of members) {\n const stat = hub.uses.get(name)\n if (stat === undefined) continue\n total += stat.count\n if (stat.lastUsed !== undefined && (latest === undefined || stat.lastUsed > latest)) latest = stat.lastUsed\n }\n return (\n <span className={css.groupTitleInner}>\n {hub.hubConfig?.showGroupSummary !== false && total > 0 ? <span className={css.useCount}>{total}</span> : null}\n {hub.hubConfig?.showGroupSummary !== false && latest !== undefined ? <span className={css.useTime + ' ' + css.groupTime}>{relativeTimeText(latest)}</span> : null}\n </span>\n )\n}\n","/**\n * Sources tab: the flat skill list or the grouped view — a project-level\n * three-tier tree (workspaces from workspace.json, each optionally split by\n * .dsh/.agents), one card per upstream collection with check/sync/\n * follow-delete actions and the tri-state switch, plus the uncategorized\n * \"personal\" card (project skills never count as personal).\n */\n\nimport type { JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { filterBySource, groupSwitchView, isProjectSource, PRIVATE_SOURCE } from '../grouping.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** 项目级三级树:项目级 → 具体工作区(可折叠、可细分)→ .dsh/.agents。 */\nfunction ProjectTree(props: { hub: SkillHubState }): JSX.Element | null {\n const { hub } = props\n const { sorted, sourceFilter, origins, collapsedGroups, subdividedProjects, toggleGroupCollapse, toggleSubdivide } = hub\n const projectSkills = filterBySource(sorted, sourceFilter, origins).filter((skill) => isProjectSource(skill.source))\n if (projectSkills.length === 0) return null\n // workspace 缺失(过渡态)时按 source 降级分组,避免空标题。\n const byProject = new Map<string, { title: string; skills: typeof projectSkills }>()\n for (const skill of projectSkills) {\n const key = skill.workspace ?? skill.source\n const entry = byProject.get(key)\n if (entry === undefined) {\n byProject.set(key, {\n title: skill.workspaceTitle ?? skill.workspace ?? tt('groups.project'),\n skills: [skill],\n })\n } else {\n entry.skills.push(skill)\n }\n }\n const topCollapsed = collapsedGroups.has('project')\n return (\n <section className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!topCollapsed} onClick={() => { toggleGroupCollapse('project') }}>\n <span className={css.chevron + (topCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt('groups.project')} · {byProject.size}\n </span>\n </button>\n </div>\n {!topCollapsed ? [...byProject.entries()].map(([key, proj]) => {\n const projKey = 'project:' + key\n const projCollapsed = collapsedGroups.has(projKey)\n const subdivided = subdividedProjects.has(key)\n return (\n <div key={projKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!projCollapsed} onClick={() => { toggleGroupCollapse(projKey) }}>\n <span className={css.chevron + (projCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {proj.title} · {proj.skills.length}\n <GroupSummary members={proj.skills.map((skill) => skill.name)} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' className={css.opBtn} onClick={(event) => { event.stopPropagation(); toggleSubdivide(key) }}>\n {subdivided ? tt('groups.merge') : tt('groups.subdivide')}\n </button>\n </span>\n </div>\n {!projCollapsed ? (\n subdivided ? (\n <div className={css.projectNest}>\n {(['project-dsh', 'project-agents'] as const).map((source) => {\n const list = proj.skills.filter((skill) => skill.source === source)\n if (list.length === 0) return null\n const srcKey = projKey + ':' + source\n const srcCollapsed = collapsedGroups.has(srcKey)\n return (\n <div key={srcKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!srcCollapsed} onClick={() => { toggleGroupCollapse(srcKey) }}>\n <span className={css.chevron + (srcCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt(('badge.source.' + source) as 'badge.source.project-dsh' | 'badge.source.project-agents')} · {list.length}\n </span>\n </button>\n </div>\n {!srcCollapsed ? list.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </div>\n )\n })}\n </div>\n ) : proj.skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)\n ) : null}\n </div>\n )\n }) : null}\n </section>\n )\n}\n\nexport function SourcesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, skillView, sourceFilter, origins, sorted, normalized, collapsedGroups, viewNames, sourceCheck, actionNames, checkingSource, syncingSource, batchBusy, busyNames, toggleGroupCollapse, checkSources, requestSync, requestDelete, toggleGroup, enableDisabled } = hub\n\n if (skillView === 'flat') {\n return <>{filterBySource(sorted, sourceFilter, origins).map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}</>\n }\n\n return (\n <>\n <ProjectTree hub={hub} />\n {groupsState !== null && groupsState.collections.length === 0 ? <div className={css.empty}>{tt('groups.noCollections')}</div> : null}\n {groupsState?.collections.map((collection) => {\n const skills = filterBySource(sorted, sourceFilter, origins).filter((skill) => collection.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) =>\n collection.skillNames.includes(record.name)\n && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n && (sourceFilter === 'all' || (origins[record.name] ?? PRIVATE_SOURCE) === sourceFilter))\n const collapsed = collapsedGroups.has('col:' + collection.name)\n const view = groupSwitchView(collection.skillNames, viewNames)\n const check = sourceCheck[collection.name]\n const hasWritable = collection.skillNames.some((name) => actionNames.has(name))\n return (\n <section key={'col:' + collection.name} className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('col:' + collection.name) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + collection.name} target='_blank' rel='noreferrer' onClick={(event) => { event.stopPropagation() }}>{collection.name}</a>\n {' · ' + collection.skillNames.length}\n <GroupSummary members={collection.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <SourceStatusBadge\n check={check}\n checking={checkingSource === collection.name}\n onCheck={() => { void checkSources(collection.name) }}\n />\n {check !== undefined && check.changed && check.updated.length > 0\n ? <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={(event) => { event.stopPropagation(); requestSync(collection.name, check.updated) }}>\n {syncingSource === collection.name ? tt('source.syncing') : tt('source.sync')}\n </button>\n : null}\n {check !== undefined && check.deleted.length > 0\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={(event) => { event.stopPropagation(); requestDelete(collection.name, check.deleted) }}>{tt('source.followDelete')}</button>\n : null}\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={collection.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || collection.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('col:' + collection.name, collection.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n })}\n {(() => {\n // 「个人」组:无来源记录 且 非项目技能(项目技能归项目树)。\n const uncategorized = filterBySource(sorted, sourceFilter, origins).filter((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n if (uncategorized.length === 0) return null\n const collapsed = collapsedGroups.has('uncategorized-source')\n return (\n <section className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('uncategorized-source') }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt('groups.personal')} · {uncategorized.length}\n <GroupSummary members={uncategorized.map((skill) => skill.name)} hub={hub} />\n </span>\n </button>\n </div>\n {!collapsed ? uncategorized.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </section>\n )\n })()}\n </>\n )\n}\n","/**\n * Scenes tab: user tag groups (one card per scene with the tri-state switch\n * and edit entry) plus the new-scene form. Scenes are the user's own\n * enable/disable units (e.g. a Godot scene vs a Java scene); upstream repos\n * are managed in the sources tab.\n */\n\nimport type { JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { groupSwitchView } from '../grouping.ts'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function ScenesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, sorted, normalized, collapsedGroups, viewNames, actionNames, batchBusy, busyNames, newTagName, setNewTagName, tagBusy, createTag, toggleGroupCollapse, toggleGroup, setEditingTag, setEditName, setMembersDraft, setEditSearch, enableDisabled } = hub\n return (\n <>\n <form className={css.form} onSubmit={(event) => { void createTag(event) }}>\n <div className={css.buttons}>\n <input\n className={css.input + ' ' + css.grow}\n value={newTagName}\n onChange={(event) => { setNewTagName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='submit' className={css.button + ' ' + css.primary} disabled={tagBusy || newTagName.trim() === ''}>{tt('groups.new')}</button>\n </div>\n </form>\n\n {groupsState !== null && groupsState.tags.length === 0 ? <div className={css.empty}>{tt('groups.empty')}</div> : null}\n {groupsState?.tags.map((tag) => {\n const skills = sorted.filter((skill) => tag.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) => tag.skillNames.includes(record.name) && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized)))\n const collapsed = collapsedGroups.has('tag:' + tag.id)\n const view = groupSwitchView(tag.skillNames, viewNames)\n const hasWritable = tag.skillNames.some((name) => actionNames.has(name))\n return (\n <section key={'tag:' + tag.id} className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('tag:' + tag.id) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tag.name} · {tag.skillNames.length}\n <GroupSummary members={tag.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={tag.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || tag.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('tag:' + tag.id, tag.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n <button type='button' className={css.opBtn} onClick={() => { setEditingTag(tag); setEditName(tag.name); setMembersDraft(new Set(tag.skillNames)); setEditSearch('') }}>{tt('groups.edit')}</button>\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n })}\n </>\n )\n}\n","/**\n * Built-in market catalog: well-known skill repos shown on the market tab so\n * users can browse and install without knowing repo URLs.\n * Only the repo slug lives here; adding goes through the normal\n * market-source route and records upstream tracking like any manual source.\n */\n\nimport type { HubKey } from './locales.ts'\n\nexport interface MarketCatalogEntry {\n repo: string\n /** locales.ts key for the one-line description. */\n descriptionKey: HubKey\n}\n\n/** 默认市场目录:精选技能仓库(顺序即展示顺序)。 */\nexport const MARKET_CATALOG: readonly MarketCatalogEntry[] = [\n { repo: 'anthropics/skills', descriptionKey: 'market.catalog.anthropics' },\n { repo: 'obra/superpowers', descriptionKey: 'market.catalog.superpowers' },\n { repo: 'mattpocock/skills', descriptionKey: 'market.catalog.mattpocock' },\n { repo: 'nexu-io/open-design', descriptionKey: 'market.catalog.openDesign' },\n]\n","/**\n * Shared dialog family for the panel: one overlay shell plus the specific\n * dialogs (group-close conflict, sync/delete confirm, branch picker, and\n * market sync selection). Every dialog closes on outside click and keeps\n * the same role/aria shell; the panel owns all dialog state.\n */\n\nimport { useEffect, type JSX, type ReactNode } from 'react'\nimport type { CollectionGroup, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport { groupNamesOf } from '../grouping.ts'\nimport css from './panel.module.css'\n\n/** A group-close conflict waiting for the user's decision. */\nexport interface ConflictDialogState {\n /** Group key: 'tag:<id>' or 'col:<name>'. */\n key: string\n name: string\n /** Conflicting skill names (enabled here and in other groups). */\n conflicts: string[]\n}\n\n/** A destructive/sync confirmation waiting for the user's decision. */\nexport interface ConfirmDialogState {\n kind: 'sync' | 'delete'\n repo: string\n /** Skills the action applies to. */\n skills: string[]\n}\n\n/** Branch picker shown when a repo has no release and no pinned ref. */\nexport interface BranchChoiceState {\n repo: string\n branches: string[]\n selected: string\n}\n\n/** Post-sync skill update dialog: which tracked skills to refresh. */\nexport interface MarketSyncDialogState {\n repo: string\n ref: string\n skills: string[]\n selected: ReadonlySet<string>\n}\n\n/** Overlay + centered alert-dialog shell; outside click or Escape cancels. */\nfunction DialogShell(props: { onClose: () => void; children: ReactNode }): JSX.Element {\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') props.onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => { window.removeEventListener('keydown', onKey) }\n })\n return (\n <div className={css.dialogOverlay} onClick={props.onClose}>\n <div className={css.dialog} role='alertdialog' aria-modal='true' onClick={(event) => { event.stopPropagation() }}>\n {props.children}\n </div>\n </div>\n )\n}\n\n/** Simple confirm dialog: title + text + optional skill list + cancel/confirm. */\nexport function ConfirmDialog(props: {\n title: string\n text: string\n /** Optional skill names listed between the text and the buttons. */\n items?: readonly string[]\n confirmLabel: string\n /** Danger-styled confirm button (destructive actions). */\n danger?: boolean\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { title, text, items, confirmLabel, danger, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{title}</h3>\n <p className={css.dialogText}>{text}</p>\n {items !== undefined ? (\n <ul className={css.dialogList}>\n {items.map((name) => <li key={name}><span className={css.rowNameText}>{name}</span></li>)}\n </ul>\n ) : null}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + (danger === true ? ' ' + css.danger : ' ' + css.primary)} onClick={onConfirm}>\n {confirmLabel}\n </button>\n </div>\n </DialogShell>\n )\n}\n\n/** Group-close conflict: which skills stay on, and which other groups also enable them. */\nexport function ConflictDialog(props: {\n dialog: ConflictDialogState\n tags: readonly SkillTag[]\n collections: readonly CollectionGroup[]\n onClose: () => void\n onKeepOn: () => void\n onCloseAll: () => void\n}): JSX.Element {\n const { dialog, tags, collections, onClose, onKeepOn, onCloseAll } = props\n return (\n <DialogShell onClose={onClose}>\n <h3 className={css.dialogTitle}>{tt('groups.conflictTitle')}</h3>\n <p className={css.dialogText}>{tt('groups.conflictText')}</p>\n <ul className={css.dialogList}>\n {dialog.conflicts.map((name) => (\n <li key={name}>\n <span className={css.rowNameText}>{name}</span>\n {' — ' + groupNamesOf(name, [...tags], [...collections]).join(', ')}\n </li>\n ))}\n </ul>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onKeepOn}>{tt('groups.keepOn')}</button>\n <button type='button' className={css.button + ' ' + css.primary} onClick={onCloseAll}>{tt('groups.closeAll')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Branch picker for a repo without releases (pins the ref, then rescans). */\nexport function BranchChoiceDialog(props: {\n choice: BranchChoiceState\n busy: boolean\n onSelect: (branch: string) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { choice, busy, onSelect, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.branchTitle')}</h3>\n <p className={css.dialogText}>{tt('market.branchHint')}</p>\n <select className={css.select + ' ' + css.dialogSelect} value={choice.selected}\n onChange={(event) => { onSelect(event.target.value) }}>\n {choice.branches.map((branch) => <option key={branch} value={branch}>{branch}</option>)}\n </select>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy} onClick={onConfirm}>{tt('market.branchConfirm')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Post-sync selection: which tracked skills to batch-update to the new version. */\nexport function MarketSyncDialog(props: {\n dialog: MarketSyncDialogState\n busy: boolean\n onToggle: (name: string, checked: boolean) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { dialog, busy, onToggle, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.syncTitle')}</h3>\n <p className={css.dialogText}>{tt('market.syncText', { ref: dialog.ref })}</p>\n {dialog.skills.length === 0 ? (\n <p className={css.dialogText}>{tt('market.syncNone')}</p>\n ) : (\n <div className={css.dialogList}>\n {dialog.skills.map((name) => (\n <label key={name} className={css.dialogRow}>\n <input type='checkbox' checked={dialog.selected.has(name)}\n onChange={(event) => { onToggle(name, event.target.checked) }} />\n <span className={css.rowNameText}>{name}</span>\n </label>\n ))}\n </div>\n )}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('market.syncCancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy || dialog.skills.length === 0} onClick={onConfirm}>\n {busy ? tt('source.syncing') : tt('source.sync')}\n </button>\n </div>\n </DialogShell>\n )\n}\n","/**\n * Market tab: one unified market list — built-in catalog entries (add\n * button while not yet added) and the user's market sources (full state\n * badges + actions once added, plus custom sources), with check-all and\n * update-all actions and the repo scan result with the importable checklist.\n */\n\nimport { Fragment, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { MARKET_CATALOG } from '../market-catalog.ts'\nimport type { MarketSourceRecord } from '../../protocol.ts'\nimport { ConfirmDialog } from './dialogs.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** Compact byte size for repo preview rows. */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return bytes + ' B'\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n return (bytes / 1024 / 1024).toFixed(1) + ' MB'\n}\n\nexport function MarketView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { marketState, marketCheck, sourceCheck, sourcesState, repoDiscoverState, scanningRepo, repoSelected, setRepoSelected, repoImporting, repoResult, newSourceName, setNewSourceName, syncingMarket, tagBusy, addSource, addMarketSource, removeMarketSource, scanRepo, checkMarket, checkSources, syncMarketSource, toggleRepoSelected, importRepo, updateAllDialog, setUpdateAllDialog, updateAll } = hub\n /** 有可更新技能的来源(全部更新按钮与确认列表共用)。 */\n const updatableRepos = Object.entries(sourceCheck).filter(([, check]) => check.changed && check.updated.length > 0)\n\n /** 一个已添加来源的完整行:状态徽章 + 操作按钮。 */\n const sourceRow = (record: MarketSourceRecord): JSX.Element => {\n const releaseCheck = marketCheck[record.repo]\n const skillCheck = sourceCheck[record.repo]\n const installedCount = sourcesState?.sources.find((source) => source.repo === record.repo)?.skills.length ?? 0\n const scanning = scanningRepo === record.repo\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + record.repo} target='_blank' rel='noreferrer'>{record.repo}</a>\n {record.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{record.ref}</span> : null}\n {installedCount > 0 ? <span className={css.badge + ' ' + css.badgeCount}>{tt('market.installed', { count: installedCount })}</span> : null}\n {skillCheck?.changed === true && skillCheck.updated.length > 0\n ? <span className={css.badge + ' ' + css.statusUpdated}>{tt('market.updatable', { count: skillCheck.updated.length })}</span>\n : null}\n {skillCheck !== undefined && skillCheck.deleted.length > 0\n ? <span className={css.badge + ' ' + css.statusError}>{tt('market.deletedUpstream', { count: skillCheck.deleted.length })}</span>\n : null}\n {releaseCheck?.updateAvailable === true\n ? <span className={css.badge + ' ' + css.statusUpdated}>{releaseCheck.latestTag !== undefined ? tt('market.newRelease', { version: releaseCheck.latestTag }) : tt('market.updated')}</span>\n : null}\n </div>\n </div>\n <button type='button' className={css.opBtn} disabled={scanning} onClick={() => { void checkMarket() }}>{tt('market.check')}</button>\n <button type='button' className={css.opBtn + (releaseCheck?.updateAvailable === true ? ' ' + css.opDanger : '')} disabled={syncingMarket === record.repo} onClick={() => { void syncMarketSource(record.repo) }}>\n {syncingMarket === record.repo ? tt('market.syncing') : tt('market.sync')}\n </button>\n <button type='button' className={css.opBtn} disabled={scanning} onClick={() => { void scanRepo(record.repo) }}>\n {scanning ? tt('market.scanning') : tt('market.scan')}\n </button>\n <button type='button' className={css.opBtn} disabled={tagBusy} title={tt('market.removeHint')} onClick={() => { void removeMarketSource(record.repo) }}>{tt('market.deleteSource')}</button>\n </div>\n )\n }\n\n // 统一列表:内置目录(未添加 → 描述+添加按钮;已添加 → 完整行)在前,\n // 自定义市场源(不在内置目录里)随后。同一个仓库不会出现两次。\n const rows: Array<{ key: string; element: JSX.Element }> = []\n for (const entry of MARKET_CATALOG) {\n const record = marketState.repos.find((item) => item.repo === entry.repo)\n if (record !== undefined) {\n rows.push({ key: entry.repo, element: sourceRow(record) })\n } else {\n const busy = scanningRepo !== null || tagBusy\n rows.push({\n key: entry.repo,\n element: (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + entry.repo} target='_blank' rel='noreferrer'>{entry.repo}</a>\n </div>\n <div className={css.rowDesc}>{tt(entry.descriptionKey)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={busy} onClick={() => { void addSource(entry.repo) }}>{tt('market.add')}</button>\n </div>\n ),\n })\n }\n }\n for (const record of marketState.repos) {\n if (MARKET_CATALOG.some((entry) => entry.repo === record.repo)) continue\n rows.push({ key: record.repo, element: sourceRow(record) })\n }\n const unaddedCatalog = MARKET_CATALOG.filter((entry) => !marketState.repos.some((record) => record.repo === entry.repo))\n\n return (\n <>\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('market.title')}</span>\n <button type='button' className={css.opBtn} onClick={() => { void checkSources(); void checkMarket() }}>{tt('market.checkAll')}</button>\n <button\n type='button'\n className={css.opBtn + (updatableRepos.length > 0 ? ' ' + css.opDanger : '')}\n disabled={updatableRepos.length === 0 || tagBusy}\n onClick={() => { setUpdateAllDialog(true) }}\n >{tt('market.updateAll')}</button>\n </div>\n <div className={css.buttons + ' ' + css.actionsPadded}>\n <input\n className={css.input + ' ' + css.grow}\n value={newSourceName}\n onChange={(event) => { setNewSourceName(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') { event.preventDefault(); void addMarketSource() } }}\n placeholder={tt('market.addPlaceholder')}\n />\n <button type='button' className={css.button + ' ' + css.primary} disabled={newSourceName.trim() === ''} onClick={() => { void addMarketSource() }}>{tt('market.addSource')}</button>\n </div>\n {unaddedCatalog.length > 0 ? <p className={css.hintLine + ' ' + css.hintPadded}>{tt('market.catalogHint')}</p> : null}\n\n {marketState.status === 'loading' ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n {marketState.status !== 'loading' && rows.length === 0 ? <div className={css.empty}>{tt('market.noSources')}</div> : null}\n {marketState.status !== 'loading' ? rows.map((row) => <Fragment key={row.key}>{row.element}</Fragment>) : null}\n </section>\n {repoDiscoverState.status === 'scanning' ? <div className={css.empty}>{tt('market.scanning')}</div> : null}\n {repoDiscoverState.status === 'error' ? <div className={css.errorBanner}>{repoDiscoverState.message}</div> : null}\n {repoDiscoverState.status === 'ready' ? (() => {\n const entries = repoDiscoverState.data.entries\n const selected = entries.filter((entry) => repoSelected.has(entry.path) && !entry.existing)\n return (\n <>\n <p className={css.hintLine + ' ' + css.hintInline}>{tt('repo.ready', { count: entries.length })}</p>\n {entries.length === 0 ? <div className={css.empty}>{tt('repo.empty')}</div> : (\n <>\n <div className={css.buttons + ' ' + css.actionsBottom}>\n <button type='button' className={css.button} onClick={() => { setRepoSelected(new Set(entries.filter((entry) => !entry.existing).map((entry) => entry.path))) }}>{tt('repo.selectAll')}</button>\n <button type='button' className={css.button} onClick={() => { setRepoSelected(new Set()) }}>{tt('repo.clearAll')}</button>\n </div>\n {(['skills', 'design-templates'] as const).map((root) => {\n const rootEntries = entries.filter((entry) => entry.root === root)\n if (rootEntries.length === 0) return null\n return (\n <div key={root} className={css.section}>\n <div className={css.sectionTitle}>{root === 'skills' ? tt('repo.root.skills') : tt('repo.root.designTemplates')}</div>\n {rootEntries.map((entry) => (\n <label key={entry.path} className={css.row + (entry.existing ? ' ' + css.rowMuted : '')}>\n <input\n type='checkbox'\n checked={repoSelected.has(entry.path)}\n disabled={entry.existing}\n onChange={(event) => { toggleRepoSelected(entry.path, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{entry.dir} · {tt('repo.files', { count: entry.fileCount, size: formatBytes(entry.totalBytes) })}</div>\n </div>\n {entry.existing\n ? <span className={css.badge + ' ' + css.badgeReadonly}>{tt('repo.existing')}</span>\n : <span className={css.badge + ' ' + css.badgeSource}>{entry.origin}</span>}\n </label>\n ))}\n </div>\n )\n })}\n <button type='button' className={css.button + ' ' + css.primary} disabled={selected.length === 0 || repoImporting} onClick={() => { void importRepo() }}>{repoImporting ? tt('repo.importing') : tt('repo.import', { count: selected.length })}</button>\n </>\n )}\n </>\n )\n })() : null}\n {repoResult !== null ? <div className={css.formSuccess + ' ' + css.actionsTop}>{tt('repo.imported', { count: repoResult.imported.length })} · {tt('repo.skippedExisting', { count: repoResult.skipped.length })} · {tt('repo.failed', { count: repoResult.failed.length })}</div> : null}\n\n {updateAllDialog ? (\n <ConfirmDialog\n title={tt('market.updateAllConfirmTitle')}\n text={tt('market.updateAllConfirmText')}\n items={updatableRepos.map(([repo, check]) => tt('market.updateAllItem', { repo, count: check.updated.length }))}\n confirmLabel={tt('market.updateAll')}\n danger\n onCancel={() => { setUpdateAllDialog(false) }}\n onConfirm={() => { void updateAll() }}\n />\n ) : null}\n </>\n )\n}\n","/**\n * useSkillHub — the panel's state owner. Everything the skill hub panel\n * knows (catalog, groups, sources, market, dialogs, drafts) plus every\n * async flow lives here; the panel itself only renders. All hooks run\n * unconditionally at the top, so the panel may early-return for the detail\n * and tag-editor views without violating the rules of hooks.\n */\n\nimport { useCallback, useEffect, useMemo, useState, type FormEvent } from 'react'\nimport type {\n CatalogResponse,\n CatalogSkill,\n DisabledSkill,\n GroupsResponse,\n HubConfig,\n MarketCheckResponse,\n MarketSourceRecord,\n RepoDiscoverResponse,\n RepoImportResponse,\n SkillDetail,\n SkillTag,\n SourceCheckResult,\n SourcesResponse,\n UpdateCheckResponse,\n WritableRoot,\n} from '../../protocol.ts'\nimport type { SkillHubApi } from '../api.ts'\nimport { errorMessage, tt } from '../helpers.ts'\nimport { conflictsOnClose, isProjectSource, PRIVATE_SOURCE, sortSkills, type SortKey, type GroupSwitchState } from '../grouping.ts'\nimport type { BranchChoiceState, ConfirmDialogState, ConflictDialogState, MarketSyncDialogState } from './dialogs.tsx'\n\n/** Catalog poll interval while the panel is mounted (the provider watcher feeds this). */\nconst POLL_MS = 5000\n/** Relaxed poll for slower-changing data (stats, groups, sources, config). */\nconst SLOW_POLL_MS = 60_000\n\n/** localStorage key of the last daily auto-check timestamp (survives sessions). */\nconst AUTO_CHECK_KEY = 'skill-hub.last-auto-check'\n/** Daily auto-check interval: at most one network round per day. */\nconst AUTO_CHECK_INTERVAL_MS = 24 * 60 * 60_000\n\n/** Whether the daily auto-check should run now (first visit or ≥24h since the last). */\nfunction shouldAutoCheck(): boolean {\n try {\n const raw = localStorage.getItem(AUTO_CHECK_KEY)\n const last = raw === null ? NaN : Number(raw)\n if (!Number.isFinite(last)) return true\n return Date.now() - last >= AUTO_CHECK_INTERVAL_MS\n } catch {\n // 无 localStorage(隐私模式等):每次打开都尝试,服务端 5 分钟节流兜底。\n return true\n }\n}\n\n/** Record that the daily auto-check ran. */\nfunction markAutoChecked(): void {\n try {\n localStorage.setItem(AUTO_CHECK_KEY, String(Date.now()))\n } catch {\n // 无 localStorage:不记录,下次打开仍会尝试(服务端节流兜底)。\n }\n}\n\n/** One-shot self-update check state. */\ntype UpdateState =\n | { status: 'idle' }\n | { status: 'checking' }\n | { status: 'ready'; data: UpdateCheckResponse }\n | { status: 'error'; message: string }\n\n/** Repo scanner/import state (drives the market source preview). */\ntype RepoDiscoverState =\n | { status: 'idle' }\n | { status: 'scanning' }\n | { status: 'ready'; data: RepoDiscoverResponse }\n | { status: 'error'; message: string }\n\n/** Market sources list state. */\ntype MarketState = { status: 'loading' | 'ready' | 'error'; repos: MarketSourceRecord[] }\n\n/** One market source's update-check outcome. */\ntype MarketCheckResult = MarketCheckResponse['results'][number]\n\n/** The hook's result: the panel's complete state + action surface. */\nexport type SkillHubState = ReturnType<typeof useSkillHub>\n\nexport function useSkillHub(api: SkillHubApi) {\n const [catalog, setCatalog] = useState<CatalogResponse | null>(null)\n const [loading, setLoading] = useState(true)\n const [loadError, setLoadError] = useState<string | null>(null)\n /** Green success banner (create finished); shown outside the closing form. */\n const [successBanner, setSuccessBanner] = useState<string | null>(null)\n const [updateState, setUpdateState] = useState<UpdateState>({ status: 'idle' })\n const [repoDiscoverState, setRepoDiscoverState] = useState<RepoDiscoverState>({ status: 'idle' })\n /** Market repo currently being scanned (null when idle); per-row busy state. */\n const [scanningRepo, setScanningRepo] = useState<string | null>(null)\n const [repoSelected, setRepoSelected] = useState<ReadonlySet<string>>(new Set())\n const [repoImporting, setRepoImporting] = useState(false)\n const [repoResult, setRepoResult] = useState<RepoImportResponse | null>(null)\n const [search, setSearch] = useState('')\n /** 工作区(项目)路径;空 = 只看用户级技能。 */\n const [workspace, setWorkspace] = useState('')\n const [detail, setDetail] = useState<SkillDetail | null>(null)\n const [detailLoading, setDetailLoading] = useState(false)\n const [busyNames, setBusyNames] = useState<ReadonlySet<string>>(new Set())\n const [batchBusy, setBatchBusy] = useState(false)\n const [showForm, setShowForm] = useState(false)\n const [formName, setFormName] = useState('')\n const [formDesc, setFormDesc] = useState('')\n const [formRoot, setFormRoot] = useState<WritableRoot>('user-dsh')\n const [formBusy, setFormBusy] = useState(false)\n const [formMessage, setFormMessage] = useState<{ kind: 'error' | 'success'; text: string } | null>(null)\n const [uses, setUses] = useState<ReadonlyMap<string, { count: number; lastUsed?: number }>>(new Map())\n const [hubConfig, setHubConfig] = useState<HubConfig | null>(null)\n const [tab, setTab] = useState<'sources' | 'scenes' | 'market'>('sources')\n const [skillView, setSkillView] = useState<'flat' | 'groups'>('groups')\n const [sourceFilter, setSourceFilter] = useState('all')\n const [sortKey, setSortKey] = useState<SortKey>('name')\n const [marketState, setMarketState] = useState<MarketState>({ status: 'loading', repos: [] })\n const [marketCheck, setMarketCheck] = useState<Readonly<Record<string, MarketCheckResult>>>({})\n const [branchChoice, setBranchChoice] = useState<BranchChoiceState | null>(null)\n const [branchBusy, setBranchBusy] = useState(false)\n const [marketSyncDialog, setMarketSyncDialog] = useState<MarketSyncDialogState | null>(null)\n const [syncingMarket, setSyncingMarket] = useState<string | null>(null)\n const [syncBusy, setSyncBusy] = useState(false)\n const [newSourceName, setNewSourceName] = useState('')\n const [groupsState, setGroupsState] = useState<GroupsResponse | null>(null)\n const [sourcesState, setSourcesState] = useState<SourcesResponse | null>(null)\n const [sourceCheck, setSourceCheck] = useState<Readonly<Record<string, SourceCheckResult>>>({})\n const [checkingSource, setCheckingSource] = useState<string | null>(null)\n const [syncingSource, setSyncingSource] = useState<string | null>(null)\n const [conflictDialog, setConflictDialog] = useState<ConflictDialogState | null>(null)\n const [confirmDialog, setConfirmDialog] = useState<ConfirmDialogState | null>(null)\n const [deleteSkillDialog, setDeleteSkillDialog] = useState<string | null>(null)\n const [confirmClearTrash, setConfirmClearTrash] = useState(false)\n /** 「全部更新」确认对话框(市场 tab)。 */\n const [updateAllDialog, setUpdateAllDialog] = useState(false)\n const [editingTag, setEditingTag] = useState<SkillTag | null>(null)\n const [editName, setEditName] = useState('')\n const [membersDraft, setMembersDraft] = useState<ReadonlySet<string>>(new Set())\n const [newTagName, setNewTagName] = useState('')\n const [tagBusy, setTagBusy] = useState(false)\n const [editSearch, setEditSearch] = useState('')\n /** 分组视图里收起的分组(key 为 tag:<id>、col:<name> 或 project 树键)。 */\n const [collapsedGroups, setCollapsedGroups] = useState<ReadonlySet<string>>(new Set())\n /** 项目级三级树里已细分(按 .dsh/.agents)的项目键。 */\n const [subdividedProjects, setSubdividedProjects] = useState<ReadonlySet<string>>(new Set())\n const [showLegend, setShowLegend] = useState(false)\n\n const toggleGroupCollapse = useCallback((key: string): void => {\n setCollapsedGroups((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const toggleSubdivide = useCallback((key: string): void => {\n setSubdividedProjects((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n const next = await api.catalog(workspace !== '' ? { cwd: workspace } : undefined)\n setCatalog(next)\n setLoadError(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setLoading(false)\n }\n }, [api, workspace])\n\n const loadUses = useCallback(async (): Promise<void> => {\n try {\n const result = await api.stats()\n if (result.available) setUses(new Map(result.stats.map((stat) => [stat.name, { count: stat.count, ...(stat.lastUsed !== undefined ? { lastUsed: stat.lastUsed } : {}) }])))\n } catch {\n // Invocation counts are best-effort; a stats failure must not disturb the catalog.\n }\n }, [api])\n\n const loadConfig = useCallback(async (): Promise<void> => {\n try {\n setHubConfig((await api.config()).config)\n } catch {\n // Dot colors are cosmetic; a config failure falls back to the defaults.\n }\n }, [api])\n\n /** Check the hub's own GitHub release once, and again on demand. */\n const checkUpdate = useCallback(async (): Promise<void> => {\n setUpdateState({ status: 'checking' })\n try {\n setUpdateState({ status: 'ready', data: await api.updateCheck() })\n } catch (error) {\n setUpdateState({ status: 'error', message: errorMessage(error) })\n }\n }, [api])\n\n /** 加载用户 tag 分组 + 系统集合组 + origin 映射。 */\n const loadGroups = useCallback(async (): Promise<void> => {\n try {\n setGroupsState(await api.groups())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载来源记录 + 回收站。 */\n const loadSources = useCallback(async (): Promise<void> => {\n try {\n setSourcesState(await api.sources())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载市场源列表。 */\n const loadMarket = useCallback(async (): Promise<void> => {\n try {\n const next = await api.market()\n setMarketState({ status: 'ready', repos: next.repos })\n } catch (error) {\n setMarketState({ status: 'error', repos: [] })\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 把最新的 tag 列表合并进 groups 状态(tags 以外的字段保持原样)。 */\n const applyTags = useCallback((tags: SkillTag[]): void => {\n setGroupsState((previous) => previous === null\n ? { ok: true, tags, collections: [], origins: {} }\n : { ...previous, tags })\n }, [])\n\n // 初始全量加载 + 双速轮询:目录是「活视图」(文件变化要 5 秒内可见),\n // 统计/分组/来源/配置变化慢,60 秒一次足够;写操作本身会触发即时刷新。\n // 更新检查、来源检查、市场检查全部改为手动按钮触发,打开面板不再自动\n // 打三路 GitHub 请求。\n useEffect(() => {\n void load()\n void loadUses()\n void loadGroups()\n void loadSources()\n void loadConfig()\n const fast = window.setInterval(() => { void load() }, POLL_MS)\n const slow = window.setInterval(() => { void loadUses(); void loadGroups(); void loadSources(); void loadConfig() }, SLOW_POLL_MS)\n return () => { window.clearInterval(fast); window.clearInterval(slow) }\n }, [load, loadUses, loadGroups, loadSources, loadConfig])\n\n const openDetail = useCallback(async (name: string): Promise<void> => {\n setDetailLoading(true)\n setLoadError(null)\n try {\n setDetail(await api.skill(name, workspace !== '' ? { cwd: workspace } : undefined))\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setDetailLoading(false)\n }\n }, [api, workspace])\n\n const toggle = useCallback(async (skill: CatalogSkill, enabled: boolean): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(skill.name))\n setLoadError(null)\n try {\n const next = await api.toggle(skill.name, enabled)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(skill.name)\n return next\n })\n }\n }, [api])\n\n const enableDisabled = useCallback(async (record: DisabledSkill): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(record.name))\n setLoadError(null)\n try {\n const next = await api.toggle(record.name, true)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(record.name)\n return next\n })\n }\n }, [api])\n\n /** Toggle an explicit name set in one write (enables disabled members too). */\n const batchToggleNames = useCallback(async (names: string[], enabled: boolean): Promise<void> => {\n if (names.length === 0) return\n setBatchBusy(true)\n setLoadError(null)\n try {\n const next = await api.toggleBatch(names, enabled)\n setCatalog(next.catalog)\n if (next.failures.length > 0) {\n setLoadError('toggle-batch: ' + next.failures.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBatchBusy(false)\n }\n }, [api])\n\n // -------------------------------------------------------- group switches\n\n /** 所有分组:key → 成员名(tag 与来源集合)。 */\n const groupMap = useCallback((): Map<string, string[]> => {\n const map = new Map<string, string[]>()\n for (const tag of groupsState?.tags ?? []) map.set('tag:' + tag.id, tag.skillNames)\n for (const collection of groupsState?.collections ?? []) map.set('col:' + collection.name, collection.skillNames)\n return map\n }, [groupsState])\n\n /** 当前启用且可写的技能名(组开关只作用于它们)。 */\n const actionNames = useMemo(() => new Set((catalog?.skills ?? []).filter((skill) => skill.writable).map((skill) => skill.name)), [catalog])\n\n /** 当前启用的全部技能名(含只读,用于派生开关状态)。 */\n const viewNames = useMemo(() => new Set((catalog?.skills ?? []).map((skill) => skill.name)), [catalog])\n\n /**\n * Toggle a whole group via its tri-state switch. Closing with members that\n * are enabled in other groups opens the conflict dialog instead.\n */\n const toggleGroup = useCallback((key: string, name: string, view: GroupSwitchState): void => {\n const members = groupMap().get(key) ?? []\n if (members.length === 0) return\n if (view === 'off') {\n void batchToggleNames(members, true)\n return\n }\n const others = [...groupMap().entries()].filter(([otherKey]) => otherKey !== key).map(([, memberNames]) => ({ members: memberNames }))\n const conflicts = conflictsOnClose(members, actionNames, others)\n if (conflicts.length > 0) {\n setConflictDialog({ key, name, conflicts })\n } else {\n void batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n }\n }, [groupMap, actionNames, batchToggleNames])\n\n /** Resolve the open conflict dialog. */\n const resolveConflict = useCallback(async (closeAll: boolean): Promise<void> => {\n const dialog = conflictDialog\n if (dialog === null) return\n setConflictDialog(null)\n const members = groupMap().get(dialog.key) ?? []\n if (closeAll) {\n await batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n } else {\n await batchToggleNames(\n members.filter((member) => actionNames.has(member) && !dialog.conflicts.includes(member)),\n false,\n )\n }\n }, [conflictDialog, groupMap, actionNames, batchToggleNames])\n\n /** Dismiss a confirm dialog and run the pending source action. */\n const runConfirmed = useCallback(async (): Promise<void> => {\n const dialog = confirmDialog\n if (dialog === null) return\n setConfirmDialog(null)\n if (dialog.kind === 'sync') {\n setSyncingSource(dialog.repo)\n setLoadError(null)\n try {\n const result = await api.syncSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n if (result.failed.length > 0) {\n setLoadError('sync: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingSource(null)\n }\n } else {\n setLoadError(null)\n try {\n await api.confirmDeleteSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }\n }, [confirmDialog, api, load, loadGroups, loadSources])\n\n // ---------------------------------------------------------- source ops\n\n /** 检查全部来源的上游更新(服务端 5 分钟节流)。 */\n const checkSources = useCallback(async (repo?: string): Promise<void> => {\n setCheckingSource(repo ?? 'all')\n setLoadError(null)\n try {\n const result = await api.checkSources(repo)\n const next: Record<string, SourceCheckResult> = { ...sourceCheck }\n for (const item of result.results) next[item.repo] = item\n setSourceCheck(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setCheckingSource(null)\n }\n }, [api, sourceCheck])\n\n /** 请求同步某个来源的所选技能(弹确认,因为会覆盖本地修改)。 */\n const requestSync = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'sync', repo, skills })\n }, [])\n\n /** 请求跟进上游删除(弹确认,移入回收站)。 */\n const requestDelete = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'delete', repo, skills })\n }, [])\n\n /** 从回收站恢复一个技能。 */\n const restoreTrash = useCallback(async (name: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.restoreSource(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadGroups, loadSources])\n\n /** 确认后永久删除回收站里的全部技能。 */\n const clearTrash = useCallback(async (): Promise<void> => {\n setConfirmClearTrash(false)\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.clearTrash()\n if (result.failed.length > 0) {\n setLoadError('clear trash: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n await Promise.all([load(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadSources])\n\n /** 打开单个技能的删除确认(移入回收站,可恢复)。 */\n const requestDeleteSkill = useCallback((name: string): void => {\n setDeleteSkillDialog(name)\n }, [])\n\n /** 执行删除确认后的回收站迁移。 */\n const runDeleteSkill = useCallback(async (): Promise<void> => {\n const name = deleteSkillDialog\n if (name === null) return\n setDeleteSkillDialog(null)\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.deleteSkill(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, deleteSkillDialog, load, loadGroups, loadSources])\n\n // ----------------------------------------------------------- tag editing\n\n /** 新建一个空 tag 分组。 */\n const createTag = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n const name = newTagName.trim()\n if (name === '') return\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.saveTag({ name }))\n setNewTagName('')\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags, newTagName])\n\n /** 删除一个 tag 分组(不影响技能文件)。 */\n const deleteTag = useCallback(async (id: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.deleteTag(id))\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n /** 重命名 tag,或保存成员勾选后回到列表。 */\n const saveTag = useCallback(async (id: string, name: string, memberNames: string[] | null): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const safeName = name.trim()\n let tags: SkillTag[] | null = null\n if (safeName !== '') tags = await api.saveTag({ id, name: safeName })\n if (memberNames !== null) tags = await api.setTagMembers(id, memberNames)\n if (tags === null) return\n applyTags(tags)\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n // -------------------------------------------------------------- market\n\n /** 添加一个市场源(内置市场目录与手动输入共用),并立即扫描它。 */\n const addSource = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setLoadError(null)\n try {\n const result = await api.addMarketSource(value)\n setMarketState({ status: 'ready', repos: result.repos })\n setNewSourceName('')\n setRepoResult(null)\n setRepoSelected(new Set())\n // 用服务端归一化后的 slug 扫描(URL/owner@repo 输入都能对上记录)。\n const slug = result.repos[result.repos.length - 1].repo\n setScanningRepo(slug)\n setRepoDiscoverState({ status: 'scanning' })\n try {\n const data = await api.repoDiscover(slug)\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 手动输入框的添加动作。 */\n const addMarketSource = useCallback(async (): Promise<void> => {\n await addSource(newSourceName)\n }, [addSource, newSourceName])\n\n /** 删除一个市场源(不影响已装技能)。 */\n const removeMarketSource = useCallback(async (repo: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.removeMarketSource(repo)\n setMarketState({ status: 'ready', repos: result.repos })\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api])\n\n /** 扫描一个市场源(或手动输入)的仓库。 */\n const scanRepo = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setRepoResult(null)\n setRepoSelected(new Set())\n setScanningRepo(value)\n setRepoDiscoverState({ status: 'scanning' })\n setLoadError(null)\n try {\n const data = await api.repoDiscover(value)\n if (data.ref === null) {\n // 无 release 且未定版:让用户选分支(默认第一项,通常是 main)。\n setBranchChoice({ repo: data.repo, branches: data.branches ?? [], selected: (data.branches ?? [])[0] ?? 'main' })\n setRepoDiscoverState({ status: 'idle' })\n return\n }\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n }, [api])\n\n /** 确认分支选择:持久化 ref 后重新扫描。 */\n const confirmBranchChoice = useCallback(async (): Promise<void> => {\n if (branchChoice === null) return\n setBranchBusy(true)\n setLoadError(null)\n try {\n await api.setMarketSourceRef(branchChoice.repo, branchChoice.selected)\n setBranchChoice(null)\n await scanRepo(branchChoice.repo)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBranchBusy(false)\n }\n }, [api, branchChoice, scanRepo])\n\n /** Toggle one repo preview row. */\n const toggleRepoSelected = useCallback((path: string, checked: boolean): void => {\n setRepoSelected((previous) => {\n const next = new Set(previous)\n if (checked) next.add(path)\n else next.delete(path)\n return next\n })\n }, [])\n\n /** Import every checked, non-existing repo skill, then refresh the hub. */\n const importRepo = useCallback(async (): Promise<void> => {\n if (repoDiscoverState.status !== 'ready') return\n setRepoImporting(true)\n setRepoResult(null)\n setLoadError(null)\n try {\n const result = await api.repoImport(repoDiscoverState.data.repo, [...repoSelected], repoDiscoverState.data.ref ?? undefined)\n setRepoResult(result)\n await Promise.all([load(), loadMarket(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setRepoImporting(false)\n }\n }, [api, repoDiscoverState, repoSelected, load, loadMarket, loadGroups, loadSources])\n\n /** 检查所有市场源的上游更新(服务端节流)。 */\n const checkMarket = useCallback(async (): Promise<void> => {\n try {\n const result = await api.marketCheck()\n const next: Record<string, MarketCheckResult> = {}\n for (const item of result.results) next[item.repo] = item\n setMarketCheck(next)\n } catch {\n // 检查失败不打扰市场列表本身。\n }\n }, [api])\n\n /** 市场源同步:版本对齐后询问是否批量更新本地技能。 */\n const syncMarketSource = useCallback(async (repo: string): Promise<void> => {\n setSyncingMarket(repo)\n setLoadError(null)\n try {\n const result = await api.marketSync(repo)\n setMarketSyncDialog({ repo: result.repo, ref: result.ref, skills: result.skills, selected: new Set(result.skills) })\n await loadMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingMarket(null)\n }\n }, [api, loadMarket])\n\n /** 批量更新本地技能到市场源当前版本(复用来源同步路径)。 */\n const confirmMarketSync = useCallback(async (): Promise<void> => {\n if (marketSyncDialog === null) return\n const selected = [...marketSyncDialog.selected]\n setSyncBusy(true)\n setLoadError(null)\n try {\n if (selected.length > 0) {\n const result = await api.syncSource(marketSyncDialog.repo, selected)\n if (result.failed.length > 0) setLoadError(result.failed.map((item) => item.name + ': ' + item.error).join('\\n'))\n }\n setMarketSyncDialog(null)\n await Promise.all([load(), loadGroups(), loadSources()])\n void checkMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncBusy(false)\n }\n }, [api, marketSyncDialog, load, loadGroups, loadSources, checkMarket])\n\n /**\n * 一键全部更新:把每个「有可更新技能」的来源逐个同步到上游最新版本\n * (复用来源同步路径,覆盖本地修改),随后刷新并重新检查。\n */\n const updateAll = useCallback(async (): Promise<void> => {\n setUpdateAllDialog(false)\n setBatchBusy(true)\n setLoadError(null)\n const failures: string[] = []\n let done = 0\n try {\n for (const [repo, check] of Object.entries(sourceCheck)) {\n if (!check.changed || check.updated.length === 0) continue\n try {\n const result = await api.syncSource(repo, check.updated)\n done += 1\n if (result.failed.length > 0) {\n failures.push(tt('market.updateAllItem', { repo, count: result.failed.length }) + ': ' + result.failed.map((item) => item.name + ': ' + item.error).join('; '))\n }\n } catch (error) {\n failures.push(repo + ': ' + errorMessage(error))\n }\n }\n await Promise.all([load(), loadGroups(), loadSources()])\n await checkSources()\n void checkMarket()\n if (failures.length > 0) setLoadError(failures.join('\\n'))\n else if (done > 0) setSuccessBanner(tt('market.updateAllDone', { count: done }))\n } finally {\n setBatchBusy(false)\n }\n }, [api, sourceCheck, checkSources, checkMarket, load, loadGroups, loadSources])\n\n // ------------------------------------------------- daily auto-check\n // 打开面板时每天最多自动检查一次(自身更新 + 全部来源 + 全部市场源),\n // 时间戳存 localStorage 跨会话生效;手动按钮随时可用,不受节流限制。\n useEffect(() => {\n if (!shouldAutoCheck()) return\n markAutoChecked()\n void checkUpdate()\n void checkSources()\n void checkMarket()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // ---------------------------------------------------------------- create\n\n const create = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n setFormBusy(true)\n setFormMessage(null)\n setSuccessBanner(null)\n try {\n const result = await api.create({ name: formName, description: formDesc, root: formRoot })\n // The form closes on success, so the confirmation lives in the green\n // banner outside it (a success message inside the closing form is\n // never visible).\n setSuccessBanner(tt('form.success') + result.path)\n setFormName('')\n setFormDesc('')\n setShowForm(false)\n await load()\n } catch (error) {\n setFormMessage({ kind: 'error', text: tt('form.error') + errorMessage(error) })\n } finally {\n setFormBusy(false)\n }\n }, [api, formName, formDesc, formRoot, load])\n\n // ------------------------------------------------------------- derived\n\n const normalized = search.trim().toLocaleLowerCase()\n /** skillName → origin repo(无来源记录的技能不在此映射中,筛选中视为 private)。 */\n const origins = groupsState?.origins ?? {}\n /** 来源筛选选项:来源记录中的仓库(排序)+ 末尾的「个人」;没有技能的仓库不列。 */\n const sourceOptions = useMemo(() => {\n const skills = catalog?.skills ?? []\n const repos = [...new Set(skills.map((skill) => origins[skill.name]).filter((repo): repo is string => repo !== undefined))].sort()\n // 项目级技能(有 workspace 归属)不算「个人」。\n const hasPrivate = skills.some((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n return [...repos, ...(hasPrivate ? [PRIVATE_SOURCE] : [])]\n }, [catalog, origins])\n const filtered = useMemo(() => (catalog?.skills ?? []).filter((skill) =>\n normalized.length === 0 || skill.name.toLocaleLowerCase().includes(normalized) || skill.description.toLocaleLowerCase().includes(normalized),\n ), [catalog, normalized])\n /** 排序后的技能列表(所有视图共用;调用次数未知按 0 处理)。 */\n const sorted = useMemo(() => sortSkills(filtered, sortKey, (name) => uses.get(name)?.count), [filtered, sortKey, uses])\n\n return {\n // state\n catalog, loading, loadError, successBanner, updateState, repoDiscoverState, scanningRepo, repoSelected, repoImporting, repoResult,\n search, workspace, detail, detailLoading, busyNames, batchBusy, showForm, formName, formDesc, formRoot, formBusy, formMessage,\n uses, hubConfig, tab, skillView, sourceFilter, sortKey, marketState, marketCheck, branchChoice, branchBusy,\n marketSyncDialog, syncingMarket, syncBusy, newSourceName, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource,\n conflictDialog, confirmDialog, deleteSkillDialog, confirmClearTrash, updateAllDialog, editingTag, editName, membersDraft, newTagName, tagBusy,\n editSearch, collapsedGroups, subdividedProjects, showLegend,\n // derived\n actionNames, viewNames, normalized, origins, sourceOptions, filtered, sorted,\n // actions + setters\n setLoadError, setSuccessBanner, setSearch, setWorkspace, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage,\n setRepoSelected, setTab, setSkillView,\n setSourceFilter, setSortKey, setBranchChoice, setMarketSyncDialog, setNewSourceName, setConflictDialog, setConfirmDialog,\n setDeleteSkillDialog, setConfirmClearTrash, setUpdateAllDialog, setEditingTag, setEditName, setMembersDraft, setNewTagName, setEditSearch, setShowLegend,\n toggleGroupCollapse, toggleSubdivide, checkUpdate, loadMarket, openDetail, toggle, enableDisabled, batchToggleNames, toggleGroup, resolveConflict,\n runConfirmed, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, requestDeleteSkill, runDeleteSkill, createTag,\n deleteTag, saveTag, addSource, addMarketSource, removeMarketSource, scanRepo, confirmBranchChoice, toggleRepoSelected, importRepo,\n checkMarket, syncMarketSource, confirmMarketSync, updateAll, create,\n }\n}\n","/**\n * The skill hub panel: catalog grouped by tags + source collections, search\n * and filter in one row, per-group tri-state switches with conflict dialogs,\n * upstream source tracking (check / sync / follow upstream deletion into a\n * restorable trash), market sources, disabled re-enable,\n * detail inspection, and the new-skill scaffold form.\n *\n * Thin shell: state and flows live in useSkillHub, the tab contents live in\n * SourcesView / ScenesView / MarketView, and the dialog family lives in\n * dialogs.tsx. This component owns only the shared chrome (header, banners,\n * filter bar, shared sections) and the view routing — and holds no hooks,\n * so the detail / tag-editor early returns are safe.\n */\n\nimport { useState } from 'react'\nimport type { WritableRoot } from '../../protocol.ts'\nimport { IconSkillOutline16 } from '../icons.tsx'\nimport type { SkillHubApi } from '../api.ts'\nimport { tt } from '../helpers.ts'\nimport { PRIVATE_SOURCE, type SortKey } from '../grouping.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport { SkillDetailView } from './SkillDetailView.tsx'\nimport { TagEditorView } from './TagEditorView.tsx'\nimport { SourcesView } from './SourcesView.tsx'\nimport { ScenesView } from './ScenesView.tsx'\nimport { MarketView } from './MarketView.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { BranchChoiceDialog, ConfirmDialog, ConflictDialog, MarketSyncDialog } from './dialogs.tsx'\nimport { useSkillHub } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport interface SkillHubPanelProps {\n api: SkillHubApi\n}\n\nexport function SkillHubPanel(props: SkillHubPanelProps): React.JSX.Element {\n const hub = useSkillHub(props.api)\n /** 工作区输入草稿:回车才应用,避免每次按键都触发目录重拉。 */\n const [workspaceDraft, setWorkspaceDraft] = useState('')\n const {\n catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc,\n formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search,\n workspace, setWorkspace,\n sourcesState, tagBusy, busyNames, normalized, origins, sourceOptions, filtered,\n conflictDialog, confirmDialog, deleteSkillDialog, confirmClearTrash, branchChoice, branchBusy, marketSyncDialog,\n syncBusy, editingTag, editName, membersDraft, editSearch, uses, groupsState, sourceCheck, checkingSource, syncingSource,\n showLegend,\n setLoadError, setSuccessBanner, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage, setTab,\n setSkillView, setSourceFilter, setSortKey, setSearch, setConflictDialog, setConfirmDialog, setDeleteSkillDialog,\n setConfirmClearTrash, setBranchChoice, setMarketSyncDialog, setEditingTag, setEditName, setMembersDraft, setEditSearch,\n setShowLegend,\n checkUpdate, loadMarket, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, runDeleteSkill,\n runConfirmed, resolveConflict, confirmBranchChoice, confirmMarketSync, create, saveTag, deleteTag, enableDisabled,\n } = hub\n\n // -------------------------------------------------------------- detail\n\n if (detail !== null) {\n return (\n <SkillDetailView\n detail={detail}\n hubConfig={hubConfig}\n uses={uses}\n groupsState={groupsState}\n sourcesState={sourcesState}\n sourceCheck={sourceCheck}\n checkingSource={checkingSource}\n syncingSource={syncingSource}\n loading={detailLoading}\n onBack={() => { setDetail(null) }}\n onCheck={(repo) => { void checkSources(repo) }}\n onSync={requestSync}\n onFollowDelete={requestDelete}\n />\n )\n }\n\n if (editingTag !== null) {\n return (\n <TagEditorView\n tag={editingTag}\n editName={editName}\n membersDraft={membersDraft}\n editSearch={editSearch}\n catalog={catalog}\n tagBusy={tagBusy}\n onBack={() => { setEditingTag(null) }}\n onEditName={setEditName}\n onEditSearch={setEditSearch}\n onToggleMember={(name, checked) => {\n setMembersDraft((previous) => {\n const next = new Set(previous)\n if (checked) next.add(name)\n else next.delete(name)\n return next\n })\n }}\n onRename={() => { void saveTag(editingTag.id, editName, null) }}\n onDelete={() => { void deleteTag(editingTag.id) }}\n onSaveMembers={() => { void saveTag(editingTag.id, editName, [...membersDraft]) }}\n />\n )\n }\n\n /** 检查结果的悬停提示:收敛到「检查更新」按钮上,不再占面板顶部横幅。 */\n const updateTitle = ((): string | undefined => {\n if (updateState.status === 'checking') return tt('update.checking')\n if (updateState.status === 'error') return tt('update.error', { error: updateState.message })\n if (updateState.status === 'ready') {\n const data = updateState.data\n if (data.error !== undefined) return tt('update.error', { error: data.error })\n if (data.updateAvailable) return tt('update.available', { version: data.latestVersion ?? '', current: data.currentVersion })\n if (data.latestVersion === null) return tt('update.unavailable')\n return tt('update.upToDate', { version: data.latestVersion })\n }\n return undefined\n })()\n\n return (\n <div className={css.panel}>\n <div className={css.header}>\n <h2 className={css.title}><IconSkillOutline16 size={16} className={css.titleIcon} /> {tt('panel.title')}</h2>\n {catalog !== null\n ? <span className={css.headerCount}>\n {tt('panel.count', { count: catalog.skills.length + catalog.disabled.length })}\n {catalog.disabled.length > 0 ? ' · ' + tt('panel.disabledCount', { count: catalog.disabled.length }) : null}\n </span>\n : null}\n {catalog !== null && !catalog.complete ? <span className={css.hint}>{tt('panel.incomplete')}</span> : null}\n <span className={css.actions}>\n <button type='button' className={css.button} disabled={updateState.status === 'checking'} title={updateTitle} onClick={() => { void checkUpdate() }}>{updateState.status === 'checking' ? tt('update.checking') : tt('update.check')}</button>\n {updateState.status === 'ready' && updateState.data.updateAvailable && updateState.data.url !== null\n ? <a className={css.updateLink} href={updateState.data.url} target='_blank' rel='noreferrer'>{tt('update.newVersion', { version: updateState.data.latestVersion ?? '' })}</a>\n : null}\n </span>\n </div>\n <div className={css.subbar}>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (tab === 'sources' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('sources') }}>{tt('view.sources')}</button>\n <button type='button' className={css.segBtn + (tab === 'scenes' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('scenes') }}>{tt('view.scenes')}</button>\n <button type='button' className={css.segBtn + (tab === 'market' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('market'); void loadMarket() }}>{tt('view.market')}</button>\n </span>\n <span className={css.workspaceBox}>\n <input\n className={css.search + ' ' + css.workspaceInput}\n value={workspaceDraft}\n placeholder={workspace !== '' ? workspace : tt('panel.workspacePlaceholder')}\n title={tt('panel.workspaceHint')}\n onChange={(event) => { setWorkspaceDraft(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') setWorkspace((event.target as HTMLInputElement).value.trim()) }}\n />\n {workspace !== ''\n ? <button type='button' className={css.opBtn} title={tt('panel.workspaceClear')} onClick={() => { setWorkspace(''); setWorkspaceDraft('') }}>✕</button>\n : null}\n </span>\n <button type='button' className={css.legendToggle + (showLegend ? ' ' + css.legendToggleActive : '')} onClick={() => { setShowLegend((value) => !value) }} title={tt('legend.hint')}>?</button>\n <span className={css.actions}>\n <button type='button' className={css.button + ' ' + css.primary} onClick={() => { setShowForm((value) => !value) }}>{tt('panel.new')}</button>\n </span>\n </div>\n\n {showForm ? (\n <form className={css.form} onSubmit={(event) => { void create(event) }}>\n <p className={css.hintLine}>{tt('form.capabilityHint')}</p>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.name')}</label>\n <input className={css.input} value={formName} onChange={(event) => { setFormName(event.target.value) }} placeholder='code-review' />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.desc')}</label>\n <input className={css.input} value={formDesc} onChange={(event) => { setFormDesc(event.target.value) }} placeholder={tt('form.descPlaceholder')} />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.root')}</label>\n <select className={css.select} value={formRoot} onChange={(event) => { setFormRoot(event.target.value as WritableRoot) }}>\n <option value='user-dsh'>~/.dsh/skills</option>\n <option value='user-agents'>~/.agents/skills</option>\n </select>\n </div>\n {formMessage !== null ? <div className={formMessage.kind === 'error' ? css.formError : css.formSuccess}>{formMessage.text}</div> : null}\n <div className={css.buttons}>\n <button type='submit' className={css.button + ' ' + css.primary} disabled={formBusy}>{formBusy ? tt('form.busy') : tt('form.submit')}</button>\n <button type='button' className={css.button} onClick={() => { setShowForm(false); setFormMessage(null) }}>{tt('form.cancel')}</button>\n </div>\n </form>\n ) : null}\n\n {loadError !== null ? (\n <div className={css.errorBanner}>\n <span>{loadError}</span>\n <button type='button' className={css.button} onClick={() => { setLoadError(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {successBanner !== null ? (\n <div className={css.successBanner}>\n <span>{successBanner}</span>\n <button type='button' className={css.button} onClick={() => { setSuccessBanner(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {showLegend ? (\n <div className={css.legend}>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} />{tt('legend.model')}</span>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} />{tt('legend.user')}</span>\n <span className={css.legendHint}>{tt('legend.hint')}</span>\n </div>\n ) : null}\n\n {loading ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n\n {detailLoading ? <div className={css.empty}>{tt('detail.loading')}</div> : null}\n\n {tab === 'market' ? (\n <MarketView hub={hub} />\n ) : catalog !== null ? (\n <>\n <div className={css.filterBar}>\n {tab === 'sources' ? (\n <>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (skillView === 'flat' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('flat') }}>{tt('view.flat')}</button>\n <button type='button' className={css.segBtn + (skillView === 'groups' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('groups') }}>{tt('view.grouped')}</button>\n </span>\n <select className={css.select} value={sourceFilter} onChange={(event) => { setSourceFilter(event.target.value) }}>\n <option value='all'>{tt('filter.allSources')}</option>\n {sourceOptions.map((source) => (\n <option key={source} value={source}>{source === PRIVATE_SOURCE ? tt('filter.private') : source}</option>\n ))}\n </select>\n </>\n ) : null}\n <select className={css.select} value={sortKey} onChange={(event) => { setSortKey(event.target.value as SortKey) }}>\n <option value='name'>{tt('sort.name')}</option>\n <option value='added'>{tt('sort.added')}</option>\n <option value='uses'>{tt('sort.uses')}</option>\n </select>\n <input className={css.search} value={search} onChange={(event) => { setSearch(event.target.value) }} placeholder={tt('panel.search')} />\n </div>\n\n {filtered.length === 0 && search.trim() !== '' ? <div className={css.empty}>{tt('panel.empty')}</div> : null}\n {filtered.length === 0 && search.trim() === '' && catalog.skills.length === 0 && catalog.disabled.length === 0 && catalog.diagnostics.length === 0\n ? <div className={css.empty}>{tt('panel.emptyAll')}</div>\n : null}\n\n {tab === 'sources' ? <SourcesView hub={hub} /> : <ScenesView hub={hub} />}\n\n {sourcesState !== null && sourcesState.trash.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('source.trash')}</span>\n <button type='button' className={css.opBtn + ' ' + css.opDanger} disabled={tagBusy} onClick={() => { setConfirmClearTrash(true) }}>{tt('source.clearTrash')}</button>\n </div>\n {sourcesState.trash.map((entry) => (\n <div key={entry.name} className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{relativeTimeText(entry.movedAt)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={tagBusy} onClick={() => { void restoreTrash(entry.name) }}>{tt('source.restore')}</button>\n </div>\n ))}\n </section>\n ) : null}\n\n {catalog.disabled.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle}>{tt('panel.disabled')}</div>\n {catalog.disabled\n .filter((record) =>\n (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n && (sourceFilter === 'all' || (origins[record.name] ?? PRIVATE_SOURCE) === sourceFilter))\n .map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </section>\n ) : null}\n\n {catalog.diagnostics.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle}>{tt('panel.diagnostics')}</div>\n {catalog.diagnostics.map((entry) => (\n <div key={entry.path} className={css.diagRow}>\n <div className={css.diagPath}>{entry.path}</div>\n <div className={css.diagReason}>{entry.reason}</div>\n </div>\n ))}\n </section>\n ) : null}\n </>\n ) : null}\n\n {conflictDialog !== null ? (\n <ConflictDialog\n dialog={conflictDialog}\n tags={groupsState?.tags ?? []}\n collections={groupsState?.collections ?? []}\n onClose={() => { setConflictDialog(null) }}\n onKeepOn={() => { void resolveConflict(false) }}\n onCloseAll={() => { void resolveConflict(true) }}\n />\n ) : null}\n\n {confirmDialog !== null ? (\n <ConfirmDialog\n title={confirmDialog.kind === 'sync' ? tt('source.syncConfirmTitle') : tt('source.deleteConfirmTitle')}\n text={confirmDialog.kind === 'sync' ? tt('source.syncConfirmText') : tt('source.deleteConfirmText')}\n items={confirmDialog.skills}\n confirmLabel={confirmDialog.kind === 'sync' ? tt('source.sync') : tt('source.followDelete')}\n danger={confirmDialog.kind === 'delete'}\n onCancel={() => { setConfirmDialog(null) }}\n onConfirm={() => { void runConfirmed() }}\n />\n ) : null}\n\n {branchChoice !== null ? (\n <BranchChoiceDialog\n choice={branchChoice}\n busy={branchBusy}\n onSelect={(selected) => { setBranchChoice({ ...branchChoice, selected }) }}\n onCancel={() => { setBranchChoice(null) }}\n onConfirm={() => { void confirmBranchChoice() }}\n />\n ) : null}\n\n {marketSyncDialog !== null ? (\n <MarketSyncDialog\n dialog={marketSyncDialog}\n busy={syncBusy}\n onToggle={(name, checked) => {\n const next = new Set(marketSyncDialog.selected)\n if (checked) next.add(name)\n else next.delete(name)\n setMarketSyncDialog({ ...marketSyncDialog, selected: next })\n }}\n onCancel={() => { setMarketSyncDialog(null) }}\n onConfirm={() => { void confirmMarketSync() }}\n />\n ) : null}\n\n {deleteSkillDialog !== null ? (\n <ConfirmDialog\n title={tt('delete.confirmTitle')}\n text={tt('delete.confirmText', { name: deleteSkillDialog })}\n confirmLabel={tt('delete.confirm')}\n danger\n onCancel={() => { setDeleteSkillDialog(null) }}\n onConfirm={() => { void runDeleteSkill() }}\n />\n ) : null}\n\n {confirmClearTrash ? (\n <ConfirmDialog\n title={tt('source.clearTrashConfirmTitle')}\n text={tt('source.clearTrashConfirmText')}\n confirmLabel={tt('source.clearTrashConfirm')}\n danger\n onCancel={() => { setConfirmClearTrash(false) }}\n onConfirm={() => { void clearTrash() }}\n />\n ) : null}\n </div>\n )\n}\n","/**\n * Browser-half entry for the dsh-skill-hub plugin — runs inside the dsh\n * web GUI.\n *\n * Registers the dsh-skill-hub locale dictionaries and mounts two Settings\n * surfaces, both through official slots (no DOM injection):\n * - a plugin-management card in the `settings.plugin.item` slot (Settings →\n * 插件 → 可配置插件列表), keyed by the hub's settings namespace and bound\n * through the official settings transport (dsh rc.7 serves every\n * registered namespace to the web client, and the tab dispatches cards by\n * namespace) — the family-bucket card pattern (PluginSettingsCard +\n * CardForm vendored from dsh-task-board);\n * - a top-level Settings section (Settings → 技能) hosting the skill hub\n * panel: catalog, search, enable/disable, diagnostics, new-skill form.\n *\n * Failure policy: mounting problems are logged, never thrown — the web\n * shell fails the whole boot when a plugin apply throws, and an external\n * plugin must not take the GUI down.\n *\n * Export discipline (packages/client rule): the /client surface carries\n * what cordis loading needs plus types only — all value exports stay\n * internal.\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-scope service merge and the settings.section slot.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the LocaleNamespaceMap merge table.\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n// Type-only: pulls the settings-plugins SlotMap merge (settings.plugin.item).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\n// Type-only: pulls the Context merge for ctx.inputTriggers (slash-dots wiring).\nimport type {} from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport type { HubSettingsValue } from '../protocol.ts'\nimport { SkillHubApi } from './api.ts'\nimport { en, zh, type HubKey } from './locales.ts'\nimport { applySettingsNavIcon } from './settings-nav-icon.ts'\nimport { setupSkillSlashDots } from './slash-dots.tsx'\nimport { SkillHubSettingsCard, SkillHubSettingsCardController } from './SkillHubSettingsCard.tsx'\nimport { SkillHubPanel } from './panel/SkillHubPanel.tsx'\n\n/** Locale namespace this plugin owns. */\nconst NS = 'dsh-skill-hub'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** dsh-skill-hub surface copy. */\n 'dsh-skill-hub': HubKey\n }\n}\n\n/**\n * Required services (fiber inject waiting — the runtime must be up first).\n * `connection`/`remote` are the settings transport's own prerequisites\n * (`ctx.settingsScope.bind` resolves them on the caller's fiber), and\n * `settingsScope` is the namespace-scope binder itself; mirror the official\n * settings-plugins inject list.\n */\nexport const inject = ['slots', 'locale', 'connection', 'remote', 'settingsScope', 'inputTriggers']\n\n/** Type-only surface (export discipline: no value exports beyond the plugin contract). */\nexport type { SkillHubPanelProps } from './panel/SkillHubPanel.tsx'\nexport type { SkillHubSettingsState } from './SkillHubSettingsCard.tsx'\nexport type { HubKey } from './locales.ts'\n\n/**\n * Mount the settings card and the skill hub section.\n * @param ctx - client root context (slots, locale).\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-skill-hub: dictionaries')\n const t = ctx.locale.bind(NS)\n const api = new SkillHubApi()\n\n // The card edits the hub's settings namespace through the official\n // settings transport — the configurable-plugins tab only dispatches cards\n // whose key the Host serves, and the Host serves every registered namespace\n // since rc.7, so this is what makes the card appear (and stay in sync).\n const settingsCard = new SkillHubSettingsCardController(\n ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS }),\n )\n\n // Chat `/` menu skill dots: wrap the core skill source so every candidate\n // row carries the invocation dot, colored from the same settings the panel\n // legend uses (dotModelColor / dotUserColor). Own scope = independent reader;\n // fails silent, never takes the GUI down.\n ctx.effect(\n () => setupSkillSlashDots(ctx, api, ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS })),\n 'dsh-skill-hub: slash dots',\n )\n\n // Plugin-management card: Settings → 插件 → 可配置插件列表.\n // rc.7's slot contract declares this keyed slot with options `key`\n // (the settings namespace the card edits), so registration is fully typed.\n ctx.effect(\n () => ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: NS,\n locale: NS,\n inject: () => settingsCard.inject(),\n }, SkillHubSettingsCard)),\n 'dsh-skill-hub: settings card',\n )\n\n // Top-level Settings section: the skill management page.\n ctx.effect(\n () => ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'skill-hub',\n order: 12,\n label: () => t('entry.label'),\n locale: NS,\n inject: () => ({}),\n }, () => <SkillHubPanel api={api} />)),\n 'dsh-skill-hub: settings section',\n )\n\n // Host shell has no section-icon registration; keep the nav gear swapped for the skill icon.\n ctx.effect(() => applySettingsNavIcon(), 'dsh-skill-hub: settings nav icon')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;EAQA,MAAa,gBAAgB;GAC3B,SAAS;GACT,OAAO;GACP,aAAa;GACb,QAAQ;GACR,aAAa;GACb,QAAQ;GACR,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,cAAc;GACd,oBAAoB;GACpB,iBAAiB;GACjB,aAAa;GACb,YAAY;GACZ,MAAM;GACN,YAAY;GACZ,QAAQ;GACR,QAAQ;GACR,KAAK;GACL,WAAW;GACX,YAAY;GACZ,SAAS;GACT,aAAa;GACb,YAAY;GACZ,cAAc;GACd,eAAe;GACf,kBAAkB;EACpB;;;;;;;;ECKA,IAAa,mBAAb,cAAsC,MAAM;GAC1C,YAAY,SAAiB;IAC3B,MAAM,OAAO;IACb,KAAK,OAAO;GACd;EACF;;EAGA,eAAe,SAAY,UAAgC;GACzD,IAAI;GACJ,IAAI;IACF,OAAO,MAAM,SAAS,KAAK;GAC7B,QAAQ;IACN,MAAM,IAAI,iBAAiB,UAAU,SAAS,SAAS,yBAAyB;GAClF;GACA,IAAI,CAAC,SAAS,IAIZ,MAAM,IAAI,iBAHM,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAQ,KAA6B,UAAU,WACvG,KAA2B,QAC5B,UAAU,SAAS,MACW;GAEpC,OAAO;EACT;;;;;;EAOA,eAAe,iBAAiB,OAA0B,MAAoB,KAAK,KAA2B;GAC5G,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,EAAE;GACrD,IAAI;IACF,OAAO,MAAM,MAAM,OAAO;KAAE,GAAG;KAAM,QAAQ,WAAW;IAAO,CAAC;GAClE,UAAU;IACR,aAAa,KAAK;GACpB;EACF;;EAGA,IAAa,cAAb,MAAyB;;GAEvB,QAAQ,SAAsD;IAE5D,OAAO,iBADK,SAAS,QAAQ,KAAA,KAAa,QAAQ,QAAQ,KAAK,cAAc,UAAU,UAAU,mBAAmB,QAAQ,GAAG,IAAI,cAAc,OACtH,CAAC,CAAC,MAAM,aAAa,SAA0B,QAAQ,CAAC;GACrF;;GAGA,MAAM,MAAM,MAAc,SAAkD;IAC1E,MAAM,MAAM,SAAS,QAAQ,KAAA,KAAa,QAAQ,QAAQ,KAAK,UAAU,mBAAmB,QAAQ,GAAG,IAAI;IAI3G,QAAO,MADY,SAA8B,MAD1B,iBADX,cAAc,QAAQ,WAAW,mBAAmB,IAAI,IAAI,GAC7B,CACc,EAAA,CAC7C;GACd;;GAGA,MAAM,YAAY,MAA4C;IAM5D,OAAO,SAA8B,MALd,iBAAiB,cAAc,aAAa;KACjE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAA8B;IAC5D,CAAC,CAC4C;GAC/C;;GAGA,MAAM,OAAO,MAAc,SAA4C;IAOrE,QAAO,MADY,SAAkD,MAL9C,iBAAiB,cAAc,QAAQ;KAC5D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAM;KAAQ,CAAkD;IACzF,CAAC,CAC4E,EAAA,CACjE;GACd;GAEA,MAAM,OAAO,SAAiD;IAM5D,OAAO,SAAyB,MALT,iBAAiB,cAAc,QAAQ;KAC5D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CACuC;GAC1C;GAEA,MAAM,QAAgC;IAEpC,OAAO,SAAwB,MADR,iBAAiB,cAAc,KAAK,CACpB;GACzC;;GAGA,MAAM,YAAY,OAAiB,SAAgD;IACjF,MAAM,UAA8B;KAAE;KAAO;IAAQ;IAMrD,OAAO,SAA8B,MALd,iBAAiB,cAAc,aAAa;KACjE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC4C;GAC/C;;GAGA,MAAM,SAAyC;IAE7C,OAAO,SAAgC,MADhB,iBAAiB,cAAc,MAAM,CACb;GACjD;;GAGA,MAAM,gBAAgB,MAA8C;IAMlE,OAAO,SAA+B,MALf,iBAAiB,cAAc,cAAc;KAClE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAA+B;IAC7D,CAAC,CAC6C;GAChD;;GAGA,MAAM,mBAAmB,MAA8C;IAMrE,OAAO,SAA+B,MALf,iBAAiB,cAAc,oBAAoB;KACxE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAA+B;IAC7D,CAAC,CAC6C;GAChD;;GAGA,MAAM,cAA4C;IAEhD,OAAO,SAA8B,MADd,iBAAiB,cAAc,WAAW,CACpB;GAC/C;;GAGA,MAAM,WAAW,MAA2C;IAM1D,OAAO,SAA6B,MALb,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;IAC/B,CAAC,CAC2C;GAC9C;;GAGA,MAAM,mBAAmB,MAAc,KAA6C;IAMlF,OAAO,SAA+B,MALf,iBAAiB,cAAc,iBAAiB;KACrE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAM;KAAI,CAAkC;IACrE,CAAC,CAC6C;GAChD;;GAGA,MAAM,cAA4C;IAEhD,OAAO,SAA8B,MADd,iBAAiB,cAAc,MAAM,CACf;GAC/C;;GAGA,MAAM,aAAa,MAA6C;IAG9D,OAAO,SAA+B,MADf,iBADX,cAAc,OAAO,WAAW,mBAAmB,IAAI,CACxB,CACG;GAChD;;GAGA,MAAM,WAAW,MAAc,OAAiB,KAA2C;IACzF,MAAM,UAA6B;KAAE;KAAM;KAAO,GAAI,QAAQ,KAAA,KAAa,QAAQ,KAAK,EAAE,IAAI,IAAI,CAAC;IAAG;IAMtG,OAAO,SAA6B,MALb,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC2C;GAC9C;;GAGA,MAAM,SAAkC;IAEtC,OAAO,SAAyB,MADT,iBAAiB,cAAc,MAAM,CACpB;GAC1C;;GAGA,MAAM,WAAW,OAA+C;IAM9D,OAAO,SAAyB,MALT,iBAAiB,cAAc,QAAQ;KAC5D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,KAAK;IAC5B,CAAC,CACuC;GAC1C;;GAGA,MAAM,SAA2D;IAE/D,OAAO,SAAkD,MADlC,iBAAiB,cAAc,MAAM,CACK;GACnE;;GAGA,MAAM,QAAQ,SAAgG;IAO5G,QAAO,MADY,SAAmD,MAL/C,iBAAiB,cAAc,KAAK;KACzD,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC6E,EAAA,CAClE;GACd;;GAGA,MAAM,UAAU,IAA0D;IAOxE,QAAO,MADY,SAAqD,MALjD,iBAAiB,cAAc,WAAW;KAC/D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,CAAqD;IACjF,CAAC,CAC+E,EAAA,CACpE;GACd;;GAGA,MAAM,cAAc,IAAY,YAAoE;IAOlG,QAAO,MADY,SAAsD,MALlD,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAI;KAAW,CAAsD;IAC9F,CAAC,CACgF,EAAA,CACrE;GACd;;GAGA,MAAM,UAAoC;IAExC,OAAO,SAA0B,MADV,iBAAiB,cAAc,OAAO,CACpB;GAC3C;;GAGA,MAAM,aAAa,MAA6C;IAC9D,MAAM,UAA8B,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;IAMrE,OAAO,SAA8B,MALd,iBAAiB,cAAc,aAAa;KACjE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC4C;GAC/C;;GAGA,MAAM,WAAW,MAAc,QAAgD;IAC7E,MAAM,UAA6B,WAAW,KAAA,IAAY;KAAE;KAAM;IAAO,IAAI,EAAE,KAAK;IAMpF,OAAO,SAA6B,MALb,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC2C;GAC9C;;GAGA,MAAM,oBAAoB,MAAc,QAAiD;IACvF,MAAM,UAA+B;KAAE;KAAM;IAAO;IAMpD,OAAO,SAA+B,MALf,iBAAiB,cAAc,cAAc;KAClE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC6C;GAChD;;GAGA,MAAM,cAAc,MAA8C;IAChE,MAAM,UAAgC,EAAE,KAAK;IAM7C,OAAO,SAAgC,MALhB,iBAAiB,cAAc,eAAe;KACnE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC8C;GACjD;;GAGA,MAAM,aAAgD;IAEpD,OAAO,SAAmC,MADnB,iBAAiB,cAAc,kBAAkB,EAAE,QAAQ,OAAO,CAAC,CACxC;GACpD;EACF;;;;;;;;ECnUA,MAAa,KAAK;GAChB,eAAe;GACf,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,uBAAuB;GACvB,aAAa;GACb,gBAAgB;GAChB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,oBAAoB;GACpB,8BAA8B;GAC9B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,oBAAoB;GACpB,oBAAoB;GACpB,gBAAgB;GAChB,sBAAsB;GACtB,6BAA6B;GAC7B,8BAA8B;GAC9B,6BAA6B;GAC7B,6BAA6B;GAC7B,cAAc;GACd,oBAAoB;GACpB,oBAAoB;GACpB,0BAA0B;GAC1B,mBAAmB;GACnB,oBAAoB;GACpB,gCAAgC;GAChC,+BAA+B;GAC/B,wBAAwB;GACxB,wBAAwB;GACxB,uBAAuB;GACvB,eAAe;GACf,mBAAmB;GACnB,gBAAgB;GAChB,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,qBAAqB;GACrB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,qBAAqB;GACrB,qBAAqB;GACrB,cAAc;GACd,cAAc;GACd,kBAAkB;GAClB,iBAAiB;GACjB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,cAAc;GACd,iBAAiB;GACjB,wBAAwB;GACxB,eAAe;GACf,oBAAoB;GACpB,6BAA6B;GAC7B,gBAAgB;GAChB,mBAAmB;GACnB,mBAAmB;GACnB,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,gBAAgB;GAChB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,gBAAgB;GAChB,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,iBAAiB;GACjB,eAAe;GACf,cAAc;GACd,0BAA0B;GAC1B,eAAe;GACf,iBAAiB;GACjB,iBAAiB;GACjB,sBAAsB;GACtB,sBAAsB;GACtB,gBAAgB;GAChB,wBAAwB;GACxB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,gBAAgB;GAChB,qBAAqB;GACrB,mBAAmB;GACnB,iBAAiB;GACjB,wBAAwB;GACxB,uBAAuB;GACvB,qBAAqB;GACrB,kBAAkB;GAClB,aAAa;GACb,cAAc;GACd,aAAa;GACb,gBAAgB;GAChB,mBAAmB;GACnB,iBAAiB;GACjB,gBAAgB;GAChB,iBAAiB;GACjB,4BAA4B;GAC5B,+BAA+B;GAC/B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,4BAA4B;GAC5B,wBAAwB;GACxB,gBAAgB;GAChB,eAAe;GACf,cAAc;GACd,cAAc;GACd,YAAY;GACZ,uBAAuB;GACvB,sBAAsB;GACtB,kBAAkB;GAClB,eAAe;GACf,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,eAAe;GACf,oBAAoB;GACpB,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,kBAAkB;GAClB,iBAAiB;GACjB,qBAAqB;GACrB,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,kBAAkB;GAClB,kBAAkB;GAClB,gBAAgB;GAChB,oBAAoB;GACpB,eAAe;GACf,kBAAkB;GAClB,2BAA2B;GAC3B,0BAA0B;GAC1B,uBAAuB;GACvB,6BAA6B;GAC7B,4BAA4B;GAC5B,gBAAgB;GAChB,kBAAkB;GAClB,qBAAqB;GACrB,iCAAiC;GACjC,gCAAgC;GAChC,4BAA4B;GAC5B,uBAAuB;GACvB,wBAAwB;GACxB,aAAa;GACb,aAAa;GACb,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,cAAc;GACd,eAAe;GACf,kBAAkB;GAClB,wBAAwB;GACxB,oBAAoB;GACpB,wBAAwB;GACxB,4BAA4B;GAC5B,gCAAgC;GAChC,0BAA0B;GAC1B,8BAA8B;GAC9B,yBAAyB;GACzB,6BAA6B;GAC7B,yBAAyB;GACzB,6BAA6B;GAC7B,wBAAwB;GACxB,4BAA4B;GAC5B,6BAA6B;GAC7B,iCAAiC;GACjC,oBAAoB;GACpB,eAAe;GACf,gBAAgB;GAChB,uBAAuB;GACvB,kBAAkB;GAClB,oBAAoB;GACpB,iBAAiB;GACjB,mBAAmB;GACnB,oBAAoB;GACpB,uBAAuB;GACvB,qBAAqB;GACrB,uBAAuB;GACvB,qBAAqB;GACrB,mBAAmB;EACrB;EAEA,MAAa,KAA6B;GACxC,eAAe;GACf,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,uBAAuB;GACvB,aAAa;GACb,gBAAgB;GAChB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,oBAAoB;GACpB,8BAA8B;GAC9B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,oBAAoB;GACpB,oBAAoB;GACpB,gBAAgB;GAChB,sBAAsB;GACtB,6BAA6B;GAC7B,8BAA8B;GAC9B,6BAA6B;GAC7B,6BAA6B;GAC7B,cAAc;GACd,oBAAoB;GACpB,oBAAoB;GACpB,0BAA0B;GAC1B,mBAAmB;GACnB,oBAAoB;GACpB,gCAAgC;GAChC,+BAA+B;GAC/B,wBAAwB;GACxB,wBAAwB;GACxB,uBAAuB;GACvB,eAAe;GACf,mBAAmB;GACnB,gBAAgB;GAChB,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,qBAAqB;GACrB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,qBAAqB;GACrB,qBAAqB;GACrB,cAAc;GACd,cAAc;GACd,kBAAkB;GAClB,iBAAiB;GACjB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,cAAc;GACd,iBAAiB;GACjB,wBAAwB;GACxB,eAAe;GACf,oBAAoB;GACpB,6BAA6B;GAC7B,gBAAgB;GAChB,mBAAmB;GACnB,mBAAmB;GACnB,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,gBAAgB;GAChB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,gBAAgB;GAChB,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,iBAAiB;GACjB,eAAe;GACf,cAAc;GACd,0BAA0B;GAC1B,eAAe;GACf,iBAAiB;GACjB,iBAAiB;GACjB,sBAAsB;GACtB,sBAAsB;GACtB,gBAAgB;GAChB,wBAAwB;GACxB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,gBAAgB;GAChB,qBAAqB;GACrB,mBAAmB;GACnB,iBAAiB;GACjB,wBAAwB;GACxB,uBAAuB;GACvB,qBAAqB;GACrB,kBAAkB;GAClB,aAAa;GACb,cAAc;GACd,aAAa;GACb,gBAAgB;GAChB,mBAAmB;GACnB,iBAAiB;GACjB,gBAAgB;GAChB,iBAAiB;GACjB,4BAA4B;GAC5B,+BAA+B;GAC/B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,4BAA4B;GAC5B,wBAAwB;GACxB,gBAAgB;GAChB,eAAe;GACf,cAAc;GACd,cAAc;GACd,YAAY;GACZ,uBAAuB;GACvB,sBAAsB;GACtB,kBAAkB;GAClB,eAAe;GACf,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,eAAe;GACf,oBAAoB;GACpB,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,kBAAkB;GAClB,iBAAiB;GACjB,qBAAqB;GACrB,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,kBAAkB;GAClB,kBAAkB;GAClB,gBAAgB;GAChB,oBAAoB;GACpB,eAAe;GACf,kBAAkB;GAClB,2BAA2B;GAC3B,0BAA0B;GAC1B,uBAAuB;GACvB,6BAA6B;GAC7B,4BAA4B;GAC5B,gBAAgB;GAChB,kBAAkB;GAClB,qBAAqB;GACrB,iCAAiC;GACjC,gCAAgC;GAChC,4BAA4B;GAC5B,uBAAuB;GACvB,wBAAwB;GACxB,aAAa;GACb,aAAa;GACb,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,cAAc;GACd,eAAe;GACf,kBAAkB;GAClB,wBAAwB;GACxB,oBAAoB;GACpB,wBAAwB;GACxB,4BAA4B;GAC5B,gCAAgC;GAChC,0BAA0B;GAC1B,8BAA8B;GAC9B,yBAAyB;GACzB,6BAA6B;GAC7B,yBAAyB;GACzB,6BAA6B;GAC7B,wBAAwB;GACxB,4BAA4B;GAC5B,6BAA6B;GAC7B,iCAAiC;GACjC,oBAAoB;GACpB,eAAe;GACf,gBAAgB;GAChB,uBAAuB;GACvB,kBAAkB;GAClB,oBAAoB;GACpB,iBAAiB;GACjB,mBAAmB;GACnB,oBAAoB;GACpB,uBAAuB;GACvB,qBAAqB;GACrB,uBAAuB;GACvB,qBAAqB;GACrB,mBAAmB;EACrB;;EASA,SAAgB,EAAE,MAA8B,KAAa,QAAkC;GAC7F,IAAI,OAAO,KAAK,QAAQ;GACxB,IAAI,WAAW,KAAA,GACb,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAC/C,OAAO,KAAK,WAAW,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC;GAG1D,OAAO;EACT;;;;;;;;;EChbA,MAAM,uBAAuB,CAAC,MAAM,QAAQ;EAE5C,MAAM,iBAAiB;EAEvB,IAAI,eAAqC;EAEzC,SAAS,YAA2B;GAClC,IAAI,iBAAiB,MACnB,eAAe,IAAI,UAAU,CAAC,CAAC,gBAAgB,gBAAgB,eAAe,CAAC,CAAC;GAElF,OAAO,aAAa,UAAU,IAAI;EACpC;EAEA,SAAS,eAAqB;GAC5B,MAAM,SAAS,SAAS,cAAc,mBAAiB;GACvD,IAAI,WAAW,MAAM;GACrB,KAAK,MAAM,UAAU,OAAO,iBAAoC,QAAQ,GAAG;IACzE,MAAM,QAAQ,OAAO,cAAc,MAAM;IACzC,IAAI,UAAU,QAAQ,CAAC,qBAAqB,SAAS,MAAM,aAAa,KAAK,KAAK,EAAE,GAAG;IACvF,IAAI,OAAO,cAAc,8BAA8B,MAAM,MAAM;IACnE,MAAM,UAAU,OAAO,cAAc,KAAK;IAC1C,MAAM,OAAO,UAAU;IACvB,IAAI,YAAY,MAAM,QAAQ,YAAY,IAAI;SACzC,OAAO,aAAa,MAAM,OAAO,UAAU;GAClD;EACF;;EAGA,SAAgB,uBAAmC;GACjD,IAAI,OAAO,aAAa,eAAe,OAAO,qBAAqB,aAAa,aAAa,CAAC;GAC9F,aAAa;GACb,MAAM,WAAW,IAAI,uBAAuB;IAAE,aAAa;GAAE,CAAC;GAC9D,SAAS,QAAQ,SAAS,MAAM;IAAE,WAAW;IAAM,SAAS;GAAK,CAAC;GAClE,aAAa;IAAE,SAAS,WAAW;GAAE;EACvC;;;;;;;;ECPA,SAAgB,gBAAgB,SAA4B,cAAoD;GAC9G,MAAM,UAAoB,CAAC;GAC3B,MAAM,WAAqB,CAAC;GAC5B,KAAK,MAAM,QAAQ,SACjB,IAAI,aAAa,IAAI,IAAI,GAAG,QAAQ,KAAK,IAAI;QACxC,SAAS,KAAK,IAAI;GAGzB,OAAO;IAAE,OADuB,SAAS,WAAW,IAAI,OAAO,QAAQ,WAAW,IAAI,QAAQ;IAC9E;IAAS;GAAS;EACpC;;EAGA,SAAgB,aAAa,MAAc,MAA2B,aAAmD;GACvH,MAAM,QAAkB,CAAC;GACzB,KAAK,MAAM,OAAO,MAAM,IAAI,IAAI,WAAW,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI,IAAI;GAC9E,KAAK,MAAM,cAAc,aAAa,IAAI,WAAW,WAAW,SAAS,IAAI,GAAG,MAAM,KAAK,WAAW,IAAI;GAC1G,OAAO;EACT;;;;;EAMA,SAAgB,iBACd,SACA,cACA,aACU;GACV,OAAO,QAAQ,QAAQ,SAAS;IAC9B,IAAI,CAAC,aAAa,IAAI,IAAI,GAAG,OAAO;IACpC,OAAO,YAAY,MAAM,UAAU,MAAM,QAAQ,SAAS,IAAI,CAAC;GACjE,CAAC;EACH;;EAGA,MAAa,iBAAiB;;EAG9B,SAAgB,gBAAgB,QAAyB;GACvD,OAAO,WAAW,iBAAiB,WAAW;EAChD;;;;;;;;EASA,SAAgB,eAAe,QAAiC,QAAgB,SAA2D;GACzI,IAAI,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM;GACvC,OAAO,OAAO,QAAQ,UAAU;IAC9B,IAAI,gBAAgB,MAAM,MAAM,GAAG,OAAO;IAC1C,QAAQ,QAAQ,MAAM,SAAA,eAA6B;GACrD,CAAC;EACH;;;;;;EAUA,SAAgB,WAAW,QAAiC,KAAc,SAAgE;GACxI,MAAM,OAAO,CAAC,GAAG,MAAM;GACvB,IAAI,QAAQ,QACV,KAAK,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;QAC3C,IAAI,QAAQ,SACjB,KAAK,MAAM,GAAG,OAAO,EAAE,WAAW,cAAc,EAAE,WAAW,UAAU;QAClE,IAAI,QAAQ,QACjB,KAAK,MAAM,GAAG,OAAO,UAAU,EAAE,IAAI,KAAK,MAAM,UAAU,EAAE,IAAI,KAAK,EAAE;GAEzE,OAAO;EACT;;EASA,SAAgB,mBAAmB,IAAY,MAAM,KAAK,IAAI,GAAiB;GAC7E,MAAM,OAAO,KAAK,IAAI,GAAG,MAAM,EAAE;GACjC,MAAM,UAAU,KAAK,MAAM,OAAO,GAAM;GACxC,IAAI,UAAU,GAAG,OAAO,EAAE,KAAK,eAAe;GAC9C,IAAI,UAAU,IAAI,OAAO;IAAE,KAAK;IAAmB,OAAO;GAAQ;GAClE,MAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;GACrC,IAAI,QAAQ,IAAI,OAAO;IAAE,KAAK;IAAiB,OAAO;GAAM;GAC5D,MAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;GAClC,IAAI,OAAO,GAAG,OAAO;IAAE,KAAK;IAAgB,OAAO;GAAK;GACxD,OAAO;IAAE,KAAK;IAAiB,OAAO,KAAK,MAAM,OAAO,CAAC;GAAE;EAC7D;;;;;;;;ECzHA,SAAgB,aAAqC;GAEnD,QADa,OAAO,aAAa,cAAc,SAAS,gBAAgB,OAAO,KAAA,CACnE,YAAY,CAAC,CAAC,WAAW,IAAI,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG;EACnE;;EAGA,SAAgB,GAAG,KAAa,QAAkC;GAChE,OAAO,EAAE,WAAW,GAAG,KAAK,MAAM;EACpC;;EAGA,SAAgB,aAAa,OAAwB;GACnD,IAAI,iBAAiB,OAAO,OAAO,MAAM;GACzC,OAAO,OAAO,KAAK;EACrB;;;;;ECLA,MAAa,0BAA0B;;;EAGvC,MAAa,yBAAyB;;EAGtC,SAAgB,SAAS,OAAsD;GAC7E,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;GAChC,OAAO;IAAE,YAAY;IAAO,aAAa;GAAM;EACjD;;EAGA,SAAgB,iBAAiB,IAAoB;GACnD,MAAM,KAAK,mBAAmB,EAAE;GAChC,OAAO,GAAG,GAAG,KAAK,GAAG,UAAU,KAAA,IAAY,EAAE,OAAO,GAAG,MAAM,IAAI,KAAA,CAAS;EAC5E;;EAGA,SAAgB,eAAe,IAAoB;GACjD,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,eAAe;EACrC;;EAGA,SAAgB,SAAS,KAAqB;GAC5C,OAAO,IAAI,SAAS,IAAI,IAAI,MAAM,GAAG,CAAC,IAAI;EAC5C;;;;ECXA,MAAM,eAAe;GAAE,SAAS;GAAK,MAAM;EAAQ;;EAGnD,MAAM,eAAe;;;;;;;;EAcrB,SAAgB,gBAAgB,SAAsE;GACpG,MAAM,OAAQ,QAAsC;GACpD,IAAI,MAAM,YAAY,KAAA,GAAW,OAAO,KAAA;GACxC,OAAO,KAAK,QAAQ,MAAM,WAAW,OAAO,YAAY,aAAa,WAAW,OAAO,SAAS,aAAa,IAAI;EACnH;;EAGA,IAAI;;;;;EAMJ,SAAgB,kBAAwB;GACtC,aAAa,KAAA;EACf;;;;;;;;;EAUA,eAAe,kBAAkB,KAAiD;GAChF,MAAM,MAAM,KAAK,IAAI;GACrB,MAAM,SAAS;GACf,IAAI,WAAW,KAAA,KAAa,MAAM,OAAO,KAAK,cAC5C,OAAO,YAAY,yBAAS,IAAI,IAAI,IAAI,OAAO;GAEjD,IAAI;IACF,MAAM,UAAU,MAAM,IAAI,QAAQ;IAClC,MAAM,MAAM,IAAI,IAAqB,QAAQ,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,MAAM,WAAW,cAAc,CAAC,CAAC;IACjH,aAAa;KAAE,IAAI;KAAK;IAAI;IAC5B,OAAO;GACT,SAAS,OAAO;IACd,QAAQ,MAAM,kDAAkD,KAAK;IACrE,aAAa;KAAE,IAAI;KAAK,QAAQ;IAAK;IACrC,uBAAO,IAAI,IAAI;GACjB;EACF;;;;;;;EAQA,SAAS,QAAQ,OAA8C;GAC7D,QAAA,GAAA,MAAA,cAAA,CAAqB,QAAQ;IAC3B,eAAe;IACf,OAAO;KACL,SAAS;KACT,OAAO;KACP,QAAQ;KACR,cAAc;KACd,YAAY;KACZ,MAAM;IACR;GACF,CAAC;EACH;;;;;;;;;EAUA,SAAgB,gBAAgB,QAA4B,KAAkB,OAAoD;GAChI,MAAM,WAAW,OAAO;GACxB,OAAO,aAAa,OAAO,SAAS,QAAQ;IAC1C,MAAM,QAAQ,MAAM,SAAS,SAAS,GAAG;IACzC,IAAI,IAAI,OAAO,SAAS,OAAO;IAC/B,MAAM,cAAc,MAAM,kBAAkB,GAAG;IAC/C,IAAI,IAAI,OAAO,SAAS,OAAO;IAC/B,MAAM,WAAW,MAAM,YAAY;IACnC,MAAM,aAAa,SAAS,OAAO,iBAAA;IACnC,MAAM,YAAY,SAAS,OAAO,gBAAA;IAClC,OAAO,MAAM,KAAK,UAAU;KAC1B,GAAG;KACH,MAAM,QAAS,YAAY,IAAI,KAAK,IAAI,KAAK,OAAQ,aAAa,SAAS;IAC7E,EAAE;GACJ;GACA,aAAa;IACX,OAAO,aAAa;GACtB;EACF;;;;;;;;;;;;EAaA,SAAgB,oBACd,KACA,KACA,OACY;GACZ,MAAM,gBAAgB,IAAI,IAAI,eAAe;GAC7C,IAAI,kBAAkB,KAAA,GAAW,aAAa,CAAC;GAE/C,IAAI,WAAW;GACf,IAAI;GACJ,IAAI,WAAW;GAIf,MAAM,gBAAsB;IAC1B,IAAI,UAAU;IACd,MAAM,SAAS,gBAAgB,aAAa;IAC5C,IAAI,WAAW,KAAA,GAAW;KACxB,IAAI,WAAW,IAAI;MACjB,YAAY;MACZ,WAAW,SAAS,GAAG;KACzB;KACA;IACF;IACA,UAAU,gBAAgB,QAAQ,KAAK,KAAK;GAC9C;GACA,QAAQ;GAER,MAAM,mBAAyB;IAC7B,gBAAgB;GAClB;GAEA,MAAM,WAAW,IAAI,GAAG,oBAAoB,UAAU;GAEtD,aAAa;IACX,WAAW;IACX,SAAS;IACT,UAAU;IACV,UAAU,KAAA;GACZ;EACF;;;;ECtKA,SAAgB,yBAAyB,EAAE,OAAO,IAAI,aAAqC;GACzF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;IAAM,QAAQ;IAAiB;IAAW,SAAQ;IAAY,MAAK;IAAO,OAAM;cAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA;GACE,CAAA;EAET;;EAGA,SAAgB,mBAAmB,EAAE,OAAO,IAAI,aAAqC;GACnF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;IAAM,QAAQ;IAAiB;IAAW,SAAQ;IAAY,MAAK;IAAO,OAAM;cAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA;GACE,CAAA;EAET;;EAGA,SAAgB,mBAAmB,EAAE,OAAO,IAAI,aAAqC;GACnF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;IAAM,QAAQ;IAAiB;IAAW,SAAQ;IAAY,MAAK;IAAO,OAAM;cAA5F,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA,CACE;;EAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EC1BA,SAAgB,mBAAmB,OAAqD;GACtF,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAoB,KAAK;GACtC,MAAM,EAAE,UAAU;GAClB,IAAI,CAAC,MAAM,WAAW,OAAO;GAC7B,MAAM,QAAQ,MAAM,EAAE,MAAM,QAAQ;GACpC,MAAM,UAAU,CAAC,MAAM,SAAS,MAAM,WAAW,MAAM;GAEvD,MAAM,SACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;IACE,MAAK;IACL,WAAWA,iCAAI;IACf,iBAAe;IACf,cAAY,MAAM,EAAE,OAAO,sBAAsB,iBAAiB,IAAI,OAAO;IAC7E,eAAe;KAAE,QAAQ,CAAC,IAAI;IAAE;cALlC;KAOE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWA,iCAAI;gBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAAO;MAAY,CAAA,GACxC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAAc,MAAM,EAAE,MAAM,cAAc;MAAQ,CAAA,CACnE;;KACL,MAAM,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,iCAAI;gBAAU,MAAM,EAAE,kBAAkB;KAAQ,CAAA,IAAI;KACpF,iBAAA,GAAA,kBAAA,IAAA,CAAC,0BAAD,EAA0B,WAAW,OAAOA,iCAAI,cAAcA,iCAAI,QAAU,CAAA;IACtE;;GAGV,IAAI,CAAC,MAAM,SACT,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAI,WAAWA,iCAAI,QAAQ,OAAO,MAAMA,iCAAI,WAAW;cAAvD,CACG,QACA,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,iCAAI;eAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAI;MAAY,MAAK;gBAAU,MAAM,EAAE,qBAAqB;KAAK,CAAA;IAAM,CAAA,IAAI,IACzH;;GAIR,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAI,WAAWA,iCAAI,QAAQ,OAAO,MAAMA,iCAAI,WAAW;cAAvD,CACG,QACA,OACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,iCAAI;eAApB;MACG,CAAC,MAAM,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,iCAAI;OAAU,MAAK;iBAAU,MAAM,EAAE,mBAAmB;MAAK,CAAA,IAAI;MACjG,MAAM;MACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAI;iBAApB;QACG,MAAM,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,iCAAI;SAAQ,MAAK;mBAAU,MAAM,EAAE,qBAAqB;QAAK,CAAA,IAAI;QAC/F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,iCAAI;SAAS,UAAU,CAAC,MAAM,SAAS,MAAM;SAAQ,SAAS,MAAM;mBAClG,MAAM,EAAE,kBAAkB;QACrB,CAAA;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,iCAAI;SAAM,UAAU;SAAS,SAAS,MAAM;mBAC1E,MAAM,EAAE,CAAC,MAAM,SAAS,kBAAkB,iBAAiB;QACtD,CAAA;OACL;;KACF;SACH,IACF;;EAER;EA6DA,SAAgB,YAAY,OAAuC;GACjE,MAAM,UAAU,MAAM,SAAS;GAC/B,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,iCAAI;cAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,iCAAI;eAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAI;iBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAAQ,MAAM;OAAY,CAAA,GAC9C,MAAM,aACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAI;mBAAQ,MAAM;QAAsB,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,iCAAI;SAAO,UAAU,MAAM;SAAU,SAAS,MAAM;mBAClF,MAAM;QACD,CAAA,CACJ;YACJ,IACD;UACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,iCAAI;iBAAO,MAAM;MAAQ,CAAA,CACpC;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MACE,MAAK;MACL,WAAW,UAAUA,iCAAI,WAAWA,iCAAI;MACxC,MAAK;MACL,gBAAc;MACd,cAAY,MAAM;MAClB,UAAU,MAAM;MAChB,eAAe;OAAE,MAAM,OAAO,OAAO,CAAC,OAAO,CAAC;MAAE;gBAEhD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,iCAAI,YAAc,CAAA;KAC7B,CAAA,CACL;;GACF,CAAA;EAET;EAoBA,SAAgB,WAAW,OAAsC;GAC/D,MAAM,QAAQ,kBAAkB,KAAK,MAAM,IAAI,IAAI,MAAM,OAAO,MAAM;GACtE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,iCAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,WAAWA,iCAAI;OAAO,SAAS,MAAM;iBAAK,MAAM;MAAa,CAAA,GACnE,MAAM,aACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAAQ,MAAM;OAAsB,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,iCAAI;QAAO,UAAU,MAAM;QAAU,SAAS,MAAM;kBAClF,MAAM;OACD,CAAA,CACJ;WACJ,IACD;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,IAAI,MAAM;OACV,MAAK;OACL,WAAWA,iCAAI;OACR;OACP,UAAU,MAAM;OAChB,WAAW,UAAU;QAAE,MAAM,OAAO,MAAM,OAAO,KAAK;OAAE;MACzD,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,MAAK;OACL,WAAWA,iCAAI,QAAQ,MAAMA,iCAAI;OACjC,OAAO,MAAM;OACb,UAAU,MAAM;OAChB,aAAa,MAAM;OACnB,WAAW,UAAU;QAAE,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;OAAE;MAChE,CAAA,CACE;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAI;gBAAO,MAAM;KAAQ,CAAA;IACpC;;EAET;;;;;;;;;;;;;;EClNA,SAAgB,aAAa,OAA0B;GACrD,OAAO;IACL;IACA,SAAS,UAAW,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI;IACjE,QAAQ,SAAS;KACf,IAAI,SAAS,QAAQ,OAAO;MAAE,MAAM;MAAO,OAAO;KAAK;KACvD,IAAI,SAAS,SAAS,OAAO;MAAE,MAAM;MAAO,OAAO;KAAM;IAE3D;GACF;EACF;;EAGA,SAAgB,WAAW,OAA0B;GACnD,OAAO;IACL;IACA,SAAS,UAAW,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK,IAAI,QAAQ;IACzF,QAAQ,SAAS;KACf,IAAI,kBAAkB,KAAK,IAAI,GAAG,OAAO;MAAE,MAAM;MAAO,OAAO;KAAK;IAEtE;GACF;EACF;;EA6BA,IAAa,WAAb,MAAsB;GACpB;GACA,wBAAyB,IAAI,IAAuB;GACpD,yBAA0B,IAAI,IAAwB;GACtD,4BAA6B,IAAI,IAAgB;GACjD,SAAiB;GACjB,SAAiB;;GAGjB,YAAY,OAAkB,OAAoB;IAChD,KAAK,QAAQ;IACb,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO,IAAI;IACzD,MAAM,gBAAgB;KAAE,KAAK,QAAQ;IAAE,CAAC;GAC1C;;GAGA,KAAQ,SAAkB;IACxB,MAAM,SAAA,GAAA,uCAAA,oBAAA,CAA4B,QAAQ,CAAC;IAC3C,KAAK,UAAU,UAAU;KAAE,MAAM,IAAI,QAAQ,CAAC;IAAE,CAAC;IACjD,OAAO;GACT;;GAGA,QAAmB;IACjB,MAAM,WAAW,KAAK,MAAM,YAAY;IACxC,MAAM,OAAO,KAAK,KAAK;IACvB,OAAO;KACL,WAAW,SAAS,WAAW;KAC/B,SAAS,SAAS,WAAW;KAC7B,UAAU,SAAS;KACnB,OAAO,KAAK,SAAS;KACrB,SAAS,KAAK,MAAM,SAAS,KAAK,QAAQ,KAAA,CAAS;KACnD,QAAQ,KAAK;KACb,QAAQ,KAAK;IACf;GACF;;GAGA,MAAM,OAA2B;IAC/B,MAAM,OAAO,KAAK,OAAO,KAAK;IAC9B,MAAM,SAAS,KAAK,OAAO,IAAI,KAAK;IACpC,IAAI,WAAW,KAAA,GACb,OAAO;KAAE,MAAM,KAAK,OAAO,KAAK,aAAa,KAAK,CAAC;KAAG,YAAY,KAAK,OAAO,KAAK;KAAG,SAAS;IAAM;IAEvG,MAAM,QAAQ,OAAO,QAAQ,EAAE,MAAM,QAAiB,IAAI,KAAK,MAAM,OAAO,IAAI;IAChF,OAAO;KAAE,MAAM,OAAO;KAAM,YAAY,OAAO,SAAS;KAAO,SAAS,UAAU,KAAA;IAAU;GAC9F;;GAGA,UAAU;IACR,OAAO;KACL,OAAO,OAAe,SAAiB;MAAE,KAAK,MAAM,OAAO;OAAE;OAAM,OAAO;MAAM,CAAC;KAAE;KACnF,aAAa,UAAkB;MAC7B,KAAK,MAAM,OAAO;OAAE,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,UAAU,KAAK,CAAC;OAAG,OAAO;MAAK,CAAC;KAC3F;KACA,YAAY;MAAE,KAAU,KAAK;KAAE;KAC/B,eAAe;MACb,IAAI,KAAK,OAAO,SAAS,KAAK,CAAC,KAAK,QAAQ;MAC5C,KAAK,OAAO,MAAM;MAClB,KAAK,SAAS;MACd,KAAK,QAAQ;KACf;IACF;GACF;;GAGA,MAAM,OAAsB;IAC1B,MAAM,OAAO,KAAK,KAAK;IACvB,MAAM,SAAS,KAAK,SAAS,SAAU,KAAK,QAAQ,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,GAAG,CAAE;IAChF,IAAI,KAAK,WAAW,KAAK,KAAK,UAAU,OAAO,WAAW,KAAK,QAAQ;IACvE,KAAK,SAAS;IACd,KAAK,SAAS;IACd,KAAK,QAAQ;IACb,IAAI,SAAS;IACb,KAAK,MAAM,SAAS,QAAQ,SAAU,MAAM,MAAM,KAAM;IACxD,IAAI,QAAQ,KAAK,OAAO,MAAM;IAC9B,KAAK,SAAS;IACd,KAAK,SAAS,CAAC;IACf,KAAK,QAAQ;GACf;;GAGA,OAA4E;IAC1E,MAAM,OAA4E,CAAC;IACnF,KAAK,MAAM,CAAC,OAAO,WAAW,KAAK,QAAQ;KACzC,MAAM,OAAO,KAAK,OAAO,KAAK;KAC9B,IAAI,OAAO,OAAO;MAChB,IAAI,KAAK,OAAO,KAAK,GAAG,KAAK,KAAK;OAAE;OAAO,WAAW,KAAK,MAAM,KAAK;MAAE,CAAC;MACzE;KACF;KACA,IAAI,OAAO,SAAS,KAAK,OAAO,KAAK,aAAa,KAAK,CAAC,GAAG;KAC3D,MAAM,QAAQ,KAAK,MAAM,OAAO,IAAI;KACpC,IAAI,UAAU,KAAA,GAAW,KAAK,KAAK;MAAE;MAAO,KAAK,KAAA;KAAU,CAAC;UACvD,IAAI,MAAM,SAAS,SAAS,KAAK,KAAK;MAAE;MAAO,WAAW,KAAK,MAAM,KAAK;KAAE,CAAC;UAC7E,KAAK,KAAK;MAAE;MAAO,WAAW,KAAK,MAAM,OAAO,MAAM,KAAK;KAAE,CAAC;IACrE;IACA,OAAO;GACT;GAEA,MAAc,MAAM,OAAiC;IACnD,MAAM,KAAK,MAAM,MAAM,KAAK;IAC5B,OAAO,CAAC,KAAK,OAAO,KAAK;GAC3B;GAEA,MAAc,MAAM,OAAe,OAAkC;IACnE,MAAM,KAAK,MAAM,IAAI,OAAO,KAAK;IACjC,OAAO,KAAK,UAAU,CAAC,GAAG,WAAW;GACvC;GAEA,aAA0D;IACxD,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC;IACtC,OAAO,OAAO,SAAS,YAAY,SAAS,OAAO,OAAkC,KAAA;GACvF;GAEA,MAAc,OAAe,MAAwB;IACnD,KAAK,OAAO,IAAI,OAAO,IAAI;IAC3B,KAAK,SAAS;IACd,KAAK,QAAQ;GACf;GAEA,OAAe,OAA0B;IACvC,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;IACjC,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,MAAM,gCAAgC,KAAK;IAC7E,OAAO;GACT;GAEA,aAAqB,OAAwB;IAC3C,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC,QAAQ;GAC1C;GAEA,UAAkB,OAAwB;IACxC,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC;IACtC,OAAO,OAAO,SAAS,YAAY,SAAS,OAAQ,KAAiC,SAAS,KAAA;GAChG;GAEA,YAAyD;IACvD,OAAO,KAAK,WAAW;GACzB;GAEA,OAAe,OAAwB;IACrC,MAAM,OAAO,KAAK,WAAW;IAC7B,OAAO,SAAS,KAAA,KAAa,OAAO,OAAO,MAAM,KAAK;GACxD;GAEA,UAAwB;IACtB,KAAK,MAAM,YAAY,KAAK,WAAW,SAAS;GAClD;EACF;;;;ECnLA,IAAa,iCAAb,MAA4C;GAC1C;GACA;;GAGA,YAAY,OAAkB;IAC5B,KAAK,OAAO,IAAI,SAAS,OAAO;KAAC,aAAa,SAAS;KAAG,aAAa,iBAAiB;KAAG,WAAW,eAAe;KAAG,WAAW,cAAc;KAAG,aAAa,cAAc;KAAG,aAAa,aAAa;KAAG,aAAa,kBAAkB;IAAC,CAAC;IAChP,KAAK,QAAQ,KAAK,KAAK,WAAW,KAAK,WAAW,CAAC;GACrD;GAEA,aAA4C;IAC1C,OAAO;KACL,GAAG,KAAK,KAAK,MAAM;KACnB,SAAS,KAAK,KAAK,MAAM,SAAS;KAClC,iBAAiB,KAAK,KAAK,MAAM,iBAAiB;KAClD,eAAe,KAAK,KAAK,MAAM,eAAe;KAC9C,cAAc,KAAK,KAAK,MAAM,cAAc;KAC5C,cAAc,KAAK,KAAK,MAAM,cAAc;KAC5C,aAAa,KAAK,KAAK,MAAM,aAAa;KAC1C,kBAAkB,KAAK,KAAK,MAAM,kBAAkB;IACtD;GACF;;;;;GAMA,SAAmC;IACjC,OAAO;KACL,OAAO,EAAE,sBAAsB,KAAK,MAAM;KAC1C,GAAG,KAAK,KAAK,QAAQ;IACvB;GACF;EACF;;;;;;EAOA,SAAgB,qBAAqB,OAAgD;GACnF,MAAM,EAAE,MAAM;GACd,MAAM,QAAQ,MAAM,yBAAyB,aAAa,QAAQ;GAClE,MAAM,WAAW,CAAC,MAAM;GACxB,MAAM,aAAa;IACjB,iBAAiB,EAAE,qBAAqB;IACxC,YAAY,EAAE,gBAAgB;IAC9B;GACF;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,oBAAD;IACK;IACH,UAAS;IACT,gBAAe;IACR;IACP,QAAQ,MAAM;IACd,WAAW,MAAM;cANnB;KAQE,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,kBAAkB;MAC3B,MAAM,EAAE,sBAAsB;MAC9B,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,WAAW,IAAI;MAAE;MAChD,eAAe;OAAE,MAAM,WAAW,SAAS;MAAE;KAC9C,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,0BAA0B;MACnC,MAAM,EAAE,8BAA8B;MACtC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,mBAAmB,IAAI;MAAE;MACxD,eAAe;OAAE,MAAM,WAAW,iBAAiB;MAAE;KACtD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;MACE,IAAG;MACH,OAAO,EAAE,wBAAwB;MACjC,MAAM,EAAE,4BAA4B;MACpC,cAAc,EAAE,kBAAkB;MAClC,cAAc;MACd,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,iBAAiB,IAAI;MAAE;MACtD,eAAe;OAAE,MAAM,WAAW,eAAe;MAAE;KACpD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;MACE,IAAG;MACH,OAAO,EAAE,uBAAuB;MAChC,MAAM,EAAE,2BAA2B;MACnC,cAAc,EAAE,kBAAkB;MAClC,cAAc;MACd,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,gBAAgB,IAAI;MAAE;MACrD,eAAe;OAAE,MAAM,WAAW,cAAc;MAAE;KACnD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,uBAAuB;MAChC,MAAM,EAAE,2BAA2B;MACnC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,gBAAgB,IAAI;MAAE;MACrD,eAAe;OAAE,MAAM,WAAW,cAAc;MAAE;KACnD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,sBAAsB;MAC/B,MAAM,EAAE,0BAA0B;MAClC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,eAAe,IAAI;MAAE;MACpD,eAAe;OAAE,MAAM,WAAW,aAAa;MAAE;KAClD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,2BAA2B;MACpC,MAAM,EAAE,+BAA+B;MACvC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,oBAAoB,IAAI;MAAE;MACzD,eAAe;OAAE,MAAM,WAAW,kBAAkB;MAAE;KACvD,CAAA;IACiB;;EAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECzJA,SAAgB,kBAAkB,OAMX;GACrB,MAAM,EAAE,OAAO,UAAU,YAAY;GACrC,IAAI,aAAa,MACf,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWC,yBAAI;cAAc,GAAG,iBAAiB;GAAQ,CAAA;GAExE,IAAI,UAAU,KAAA,GAAW;IACvB,IAAI,YAAY,KAAA,GAAW,OAAO;IAClC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAQ,MAAK;KAAS,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;KAAc,OAAO,GAAG,kBAAkB;KAAG,SAAS;eAChH,GAAG,cAAc;IACZ,CAAA;GAEZ;GACA,MAAM,gBAAoC;IACxC,IAAI,MAAM,UAAU,KAAA,GAClB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;eAAc,GAAG,cAAc;IAAQ,CAAA;IAE7F,IAAI,MAAM,cAAc,MACtB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAAc,GAAG,kBAAkB;IAAQ,CAAA;IAEzE,IAAI,MAAM,eAAe,MACvB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAAc,GAAG,mBAAmB;IAAQ,CAAA;IAE1E,IAAI,MAAM,SACR,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAArB,CACG,MAAM,QAAQ,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;gBAAgB,GAAG,kBAAkB,EAAE,OAAO,MAAM,QAAQ,OAAO,CAAC;KAAQ,CAAA,IAAI,MACxJ,MAAM,QAAQ,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;gBAAc,GAAG,kBAAkB,EAAE,OAAO,MAAM,QAAQ,OAAO,CAAC;KAAQ,CAAA,IAAI,IACnJ;;IAGV,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;eAAW,GAAG,iBAAiB;IAAQ,CAAA;GAC7F,EAAA,CAAG;GACH,IAAI,YAAY,KAAA,GAAW,OAAO;GAClC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAAQ,MAAK;IAAS,WAAWA,yBAAI;IAAY,OAAO,GAAG,kBAAkB;IAAG,SAAS;cACtF;GACK,CAAA;EAEZ;;;EC1BA,SAAgB,gBAAgB,OAA0C;GACxE,MAAM,EAAE,QAAQ,WAAW,MAAM,aAAa,cAAc,aAAa,gBAAgB,eAAe,SAAS,QAAQ,SAAS,QAAQ,mBAAmB;GAC7J,MAAM,eAAe,cAAc,QAAQ,MAAM,WAAW,OAAO,OAAO,SAAS,OAAO,IAAI,CAAC;GAC/F,MAAM,cAAc,iBAAiB,KAAA,IAAY,YAAY,aAAa,QAAQ,KAAA;GAClF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAM,SAAS;iBAAS,GAAG,aAAa;MAAU,CAAA,GACvF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAArB,CACG,OAAO,MAEP,OAAO,WAAW,iBACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;QAAU,OAAO,SAAS,WAAW,aAAa;QAAG,OAAO,GAAG,cAAc;OAAI,CAAA,IACtH,OAAO,WAAW,gBAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;QAAS,OAAO,SAAS,WAAW,YAAY;QAAG,OAAO,GAAG,aAAa;OAAI,CAAA,IACnH,IACF;QACH;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,iBAAiB;SAAE;SAAG,OAAO;QAAc;;OAClF,OAAO,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,gBAAgB;SAAE;SAAG,eAAe,OAAO,OAAO;QAAO;YAAI;OACpI,OAAO,cAAc,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,kBAAkB;SAAE;SAAG,eAAe,OAAO,SAAS;QAAO;YAAI;OAC1I,OAAO,SAAS,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,aAAa;SAAE;SAAG,OAAO;QAAU;YAAI;OAC3G,OAAO,cAAc,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,kBAAkB;SAAE;SAAG,OAAO;QAAe;YAAI;cACnH;QACN,MAAM,OAAO,KAAK,IAAI,OAAO,IAAI;QACjC,IAAI,SAAS,KAAA,KAAa,KAAK,UAAU,GAAG,OAAO;QACnD,MAAM,KAAK,KAAK,aAAa,KAAA,IAAY,QAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,eAAe,IAAI;QAC5F,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB;UAAqC,GAAG,aAAa;UAAE;UAAG,KAAK;UAAO;SAAQ;;OACvF,EAAA,CAAG;cACK;QACN,MAAM,QAAQ,aAAa,QAAQ,CAAC,EAAA,CAAG,QAAQ,QAAQ,IAAI,WAAW,SAAS,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI;QAClH,OAAO,KAAK,SAAS,IAAI,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB;UAAqC,GAAG,eAAe;UAAE;UAAG,KAAK,KAAK,IAAI;SAAO;aAAI;OAChH,EAAA,CAAG;MACA;;KACJ,iBAAiB,KAAA,IAChB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,WAAWA,yBAAI;UAAY,MAAM,wBAAwB,aAAa;UAAM,QAAO;UAAS,KAAI;oBAAc,aAAa;SAAQ,CAAA;SACrI,aAAa,QAAQ,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAc,aAAa;SAAU,CAAA,IAAI;SAClH,iBAAA,GAAA,kBAAA,IAAA,CAAC,mBAAD,EAAmB,OAAO,YAAc,CAAA;QACrC;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SACG,GAAG,eAAe;SAAE;SAAG,aAAa,cAAc,KAAK,GAAG,mBAAmB,IAAI,SAAS,aAAa,SAAS;QAC9G;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;kBAAxC;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAO,UAAU,mBAAmB;UAAM,eAAe;WAAE,QAAQ,aAAa,IAAI;UAAE;oBACxH,mBAAmB,aAAa,OAAO,GAAG,iBAAiB,IAAI,GAAG,cAAc;SAC3E,CAAA;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAO,UAAU,kBAAkB;UAAM,eAAe;WAAE,OAAO,aAAa,MAAM,CAAC,OAAO,IAAI,CAAC;UAAE;oBACrI,kBAAkB,aAAa,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;SACxE,CAAA;SACP,aAAa,QAAQ,SAAS,OAAO,IAAI,MAAM,OAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;UAAU,eAAe;WAAE,eAAe,aAAa,MAAM,CAAC,OAAO,IAAI,CAAC;UAAE;oBAAI,GAAG,qBAAqB;SAAU,CAAA,IACzK;QACD;;MACF;UAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAW,GAAG,gBAAgB;KAAK,CAAA;KAEtD,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,gBAAgB;KAAO,CAAA,IAAI;KACrE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAgB,OAAO;KAAa,CAAA;IACrD;;EAET;;;ECjEA,SAAgB,cAAc,OAAwC;GACpE,MAAM,EAAE,KAAK,UAAU,cAAc,YAAY,SAAS,SAAS,QAAQ,YAAY,cAAc,gBAAgB,UAAU,UAAU,kBAAkB;GAC3J,MAAM,YAAY,WAAW,KAAK,CAAC,CAAC,kBAAkB;GACtD,MAAM,cAAc,SAAS,UAAU,CAAC,EAAA,CAAG,QAAQ,UAAU,UAAU,WAAW,KAAK,MAAM,KAAK,kBAAkB,CAAC,CAAC,SAAS,SAAS,KAAK,MAAM,YAAY,kBAAkB,CAAC,CAAC,SAAS,SAAS,CAAC;GACtM,MAAM,gBAAgB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WAAW,UAAU,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,SAAS,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,SAAS,CAAC;GAC7M,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAM,SAAS;kBAAS,GAAG,aAAa;OAAU,CAAA;OACvF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;QACjC,OAAO;QACP,WAAW,UAAU;SAAE,WAAW,MAAM,OAAO,KAAK;QAAE;QACtD,aAAa,GAAG,wBAAwB;OACzC,CAAA;OACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAO,UAAU,WAAW,SAAS,KAAK,MAAM;QAAI,SAAS;kBAAW,GAAG,eAAe;OAAU,CAAA;OACxI,IAAI,YAAY,OACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAO,UAAU;QAAS,SAAS;kBAAW,GAAG,eAAe;OAAU,CAAA,IAC/G;MACD;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAW,GAAG,oBAAoB;KAAK,CAAA;KACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MAAO,WAAWA,yBAAI;MAAQ,OAAO;MAAY,WAAW,UAAU;OAAE,aAAa,MAAM,OAAO,KAAK;MAAE;MAAG,aAAa,GAAG,cAAc;KAAI,CAAA;KAC9I,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACG,WAAW,KAAK,UACf,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAwB,WAAWA,yBAAI;iBAAvC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,SAAS,aAAa,IAAI,MAAM,IAAI;QACpC,WAAW,UAAU;SAAE,eAAe,MAAM,MAAM,MAAM,OAAO,OAAO;QAAE;OACzE,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,MAAM;QAAU,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,MAAM;QAAiB,CAAA,CAClD;SACA;SAVK,MAAM,IAUX,CACR,GACA,aAAa,KAAK,WACjB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAyB,WAAWA,yBAAI;iBAAxC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,SAAS,aAAa,IAAI,OAAO,IAAI;QACrC,WAAW,UAAU;SAAE,eAAe,OAAO,MAAM,MAAM,OAAO,OAAO;QAAE;OAC1E,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,OAAO;QAAU,CAAA,GAC/C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB;UAA8B,OAAO;UAAY;UAAI,GAAG,gBAAgB;SAAO;UAC5E;SACA;SAVK,OAAO,IAUZ,CACR,CACE;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU;OAAS,SAAS;iBAAgB,GAAG,oBAAoB;MAAU,CAAA;KAC3I,CAAA;IACF;;EAET;;;EC3EA,SAAgB,SAAS,OAAiE;GACxF,MAAM,EAAE,OAAO,QAAQ;GACvB,MAAM,OAAO,IAAI,KAAK,IAAI,MAAM,IAAI;GACpC,MAAM,QAAQ,MAAM,SAAS;GAC7B,MAAM,WAAW,MAAM;;GAEvB,MAAM,MAAM,MAAM,WAAW,iBACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWC,yBAAI,MAAM,MAAMA,yBAAI;IAAU,OAAO,SAAS,IAAI,WAAW,aAAa;IAAG,OAAO,GAAG,cAAc;GAAI,CAAA,IAC1H,MAAM,WAAW,gBACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;IAAS,OAAO,SAAS,IAAI,WAAW,YAAY;IAAG,OAAO,GAAG,aAAa;GAAI,CAAA,IACvH;;GAEN,MAAM,aAAa,UAA+C;IAChE,IAAI,MAAM,WAAW,MAAM,eAAe;IAC1C,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;KAC9C,MAAM,eAAe;KACrB,IAAS,WAAW,MAAM,IAAI;IAChC;GACF;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IACE,WAAWA,yBAAI;IACf,MAAK;IACL,UAAU;IACV,cAAY,GAAG,YAAY,EAAE,MAAM,MAAM,KAAK,CAAC;IAC/C,eAAe;KAAE,IAAS,WAAW,MAAM,IAAI;IAAE;IACtC;cANb,CAQE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAc,MAAM;OAAW,CAAA;OACnD,QAAQ,KAAK,IAAI,WAAW,iBAAiB,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAW;OAAY,CAAA,IAAI;OACrG;OACA,aAAa,KAAA,KAAa,IAAI,WAAW,gBAAgB,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAU,iBAAiB,QAAQ;OAAQ,CAAA,IAAI;MACnI;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAU,MAAM;KAAiB,CAAA,CAClD;QACJ,MAAM,WACH,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI,WAAW,MAAMA,yBAAI;KACtD,UAAU,IAAI,UAAU,IAAI,MAAM,IAAI,KAAK,IAAI;KAC/C,OAAO,GAAG,YAAY;KACtB,cAAY,GAAG,YAAY;KAC3B,UAAU,UAAU;MAAE,MAAM,gBAAgB;MAAG,IAAI,mBAAmB,MAAM,IAAI;KAAE;eACnF,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD,EAAoB,MAAM,GAAK,CAAA;IAAS,CAAA,GACzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,gBAAc;KACd,cAAY,GAAG,aAAa;KAC5B,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;KAClC,UAAU,IAAI,UAAU,IAAI,MAAM,IAAI;KACtC,UAAU,UAAU;MAAE,MAAM,gBAAgB;MAAG,IAAS,OAAO,OAAO,KAAK;KAAE;eAC9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;IAAS,CAAA,CAC7C,EAAA,CAAA,IACF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;eAAgB,GAAG,cAAc;IAAQ,CAAA,CACjF;;EAET;;;;EC5DA,SAAS,oBAAoB,MAA4B;GACvD,OAAO,GAAI,kBAAkB,IAAe;EAC9C;EAEA,SAAgB,YAAY,OAAoF;GAC9G,MAAM,EAAE,QAAQ,MAAM,aAAa;GACnC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI,MAAM,MAAMA,yBAAI;cAApC;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAU,OAAO;MAAU,CAAA,GAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAU,OAAO;MAAiB,CAAA,CACnD;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI;gBACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;iBAAc,oBAAoB,OAAO,IAAI;MAAQ,CAAA;KACxF,CAAA;KACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAQ,MAAK;MAAS,MAAK;MAAS,gBAAc;MAAO,cAAY,GAAG,YAAY;MAAG,WAAWA,yBAAI;MAAQ,UAAU;MAAM,SAAS;gBAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;KAAS,CAAA;IAC1L;;EAET;;;ECrBA,SAAgB,aAAa,OAAwE;GACnG,MAAM,EAAE,SAAS,QAAQ;GACzB,IAAI,QAAQ;GACZ,IAAI;GACJ,KAAK,MAAM,QAAQ,SAAS;IAC1B,MAAM,OAAO,IAAI,KAAK,IAAI,IAAI;IAC9B,IAAI,SAAS,KAAA,GAAW;IACxB,SAAS,KAAK;IACd,IAAI,KAAK,aAAa,KAAA,MAAc,WAAW,KAAA,KAAa,KAAK,WAAW,SAAS,SAAS,KAAK;GACrG;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;IAAM,WAAWC,yBAAI;cAArB,CACG,IAAI,WAAW,qBAAqB,SAAS,QAAQ,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAAW;IAAY,CAAA,IAAI,MACzG,IAAI,WAAW,qBAAqB,SAAS,WAAW,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;eAAY,iBAAiB,MAAM;IAAQ,CAAA,IAAI,IACzJ;;EAEV;;;;ECPA,SAAS,YAAY,OAAmD;GACtE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,QAAQ,cAAc,SAAS,iBAAiB,oBAAoB,qBAAqB,oBAAoB;GACrH,MAAM,gBAAgB,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,gBAAgB,MAAM,MAAM,CAAC;GACnH,IAAI,cAAc,WAAW,GAAG,OAAO;GAEvC,MAAM,4BAAY,IAAI,IAA6D;GACnF,KAAK,MAAM,SAAS,eAAe;IACjC,MAAM,MAAM,MAAM,aAAa,MAAM;IACrC,MAAM,QAAQ,UAAU,IAAI,GAAG;IAC/B,IAAI,UAAU,KAAA,GACZ,UAAU,IAAI,KAAK;KACjB,OAAO,MAAM,kBAAkB,MAAM,aAAa,GAAG,gBAAgB;KACrE,QAAQ,CAAC,KAAK;IAChB,CAAC;SAED,MAAM,OAAO,KAAK,KAAK;GAE3B;GACA,MAAM,eAAe,gBAAgB,IAAI,SAAS;GAClD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;IAAS,WAAWC,yBAAI;cAAxB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;MAAQ,MAAK;MAAS,WAAWA,yBAAI;MAAY,iBAAe,CAAC;MAAc,eAAe;OAAE,oBAAoB,SAAS;MAAE;gBAA/H,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,eAAe,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAClF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAArB;QACG,GAAG,gBAAgB;QAAE;QAAI,UAAU;OAChC;QACA;;IACL,CAAA,GACJ,CAAC,eAAe,CAAC,GAAG,UAAU,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,UAAU;KAC7D,MAAM,UAAU,aAAa;KAC7B,MAAM,gBAAgB,gBAAgB,IAAI,OAAO;KACjD,MAAM,aAAa,mBAAmB,IAAI,GAAG;KAC7C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAmB,WAAWA,yBAAI;gBAAlC,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAY,iBAAe,CAAC;QAAe,eAAe;SAAE,oBAAoB,OAAO;QAAE;kBAA9H,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,gBAAgB,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GACnF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB;UACG,KAAK;UAAM;UAAI,KAAK,OAAO;UAC5B,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;WAAc,SAAS,KAAK,OAAO,KAAK,UAAU,MAAM,IAAI;WAAQ;UAAM,CAAA;SACtE;UACA;WACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,UAAU,UAAU;UAAE,MAAM,gBAAgB;UAAG,gBAAgB,GAAG;SAAE;mBAC7G,aAAa,GAAG,cAAc,IAAI,GAAG,kBAAkB;QAClD,CAAA;OACJ,CAAA,CACH;UACJ,CAAC,gBACA,aACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAChB,CAAC,eAAe,gBAAgB,CAAC,CAAW,KAAK,WAAW;QAC5D,MAAM,OAAO,KAAK,OAAO,QAAQ,UAAU,MAAM,WAAW,MAAM;QAClE,IAAI,KAAK,WAAW,GAAG,OAAO;QAC9B,MAAM,SAAS,UAAU,MAAM;QAC/B,MAAM,eAAe,gBAAgB,IAAI,MAAM;QAC/C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAkB,WAAWA,yBAAI;mBAAjC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;oBAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI;WAAY,iBAAe,CAAC;WAAc,eAAe;YAAE,oBAAoB,MAAM;WAAE;qBAA5H,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,eAAe,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAClF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWA,yBAAI;sBAArB;aACG,GAAI,kBAAkB,MAAqE;aAAE;aAAI,KAAK;YACnG;aACA;;SACL,CAAA,GACJ,CAAC,eAAe,KAAK,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAkC;UAAY;SAAM,GAArC,MAAM,IAA+B,CAAC,IAAI,IAC3F;WAVK,MAUL;OAET,CAAC;MACE,CAAA,IACH,KAAK,OAAO,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,IAClF,IACD;QAxCK,OAwCL;IAET,CAAC,IAAI,IACE;;EAEb;EAEA,SAAgB,YAAY,OAA4C;GACtE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,SAAS,aAAa,WAAW,cAAc,SAAS,QAAQ,YAAY,iBAAiB,WAAW,aAAa,aAAa,gBAAgB,eAAe,WAAW,WAAW,qBAAqB,cAAc,aAAa,eAAe,aAAa,mBAAmB;GAE9R,IAAI,cAAc,QAChB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAA,kBAAA,UAAA,EAAA,UAAG,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAAkC;IAAY;GAAM,GAArC,MAAM,IAA+B,CAAC,EAAI,CAAA;GAGlI,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD,EAAkB,IAAM,CAAA;IACvB,gBAAgB,QAAQ,YAAY,YAAY,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAAQ,GAAG,sBAAsB;IAAO,CAAA,IAAI;IAC/H,aAAa,YAAY,KAAK,eAAe;KAC5C,MAAM,SAAS,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,WAAW,WAAW,SAAS,MAAM,IAAI,CAAC;KACzH,MAAM,mBAAmB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WACxD,WAAW,WAAW,SAAS,OAAO,IAAI,MACtC,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,OAC7I,iBAAiB,UAAU,QAAQ,OAAO,SAAA,eAA6B,aAAa;KAC1F,MAAM,YAAY,gBAAgB,IAAI,SAAS,WAAW,IAAI;KAC9D,MAAM,OAAO,gBAAgB,WAAW,YAAY,SAAS;KAC7D,MAAM,QAAQ,YAAY,WAAW;KACrC,MAAM,cAAc,WAAW,WAAW,MAAM,SAAS,YAAY,IAAI,IAAI,CAAC;KAC9E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAAwC,WAAWA,yBAAI;gBAAvD,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAY,iBAAe,CAAC;QAAW,eAAe;SAAE,oBAAoB,SAAS,WAAW,IAAI;QAAE;kBAA3I,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,YAAY,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAC/E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;WAAG,WAAWA,yBAAI;WAAY,MAAM,wBAAwB,WAAW;WAAM,QAAO;WAAS,KAAI;WAAa,UAAU,UAAU;YAAE,MAAM,gBAAgB;WAAE;qBAAI,WAAW;UAAQ,CAAA;UAClL,QAAQ,WAAW,WAAW;UAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;WAAc,SAAS,WAAW;WAAiB;UAAM,CAAA;SACrD;UACA;WACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,mBAAD;UACS;UACP,UAAU,mBAAmB,WAAW;UACxC,eAAe;WAAE,aAAkB,WAAW,IAAI;UAAE;SACrD,CAAA;SACA,UAAU,KAAA,KAAa,MAAM,WAAW,MAAM,QAAQ,SAAS,IAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAO,UAAU,kBAAkB;UAAM,UAAU,UAAU;WAAE,MAAM,gBAAgB;WAAG,YAAY,WAAW,MAAM,MAAM,OAAO;UAAE;oBACtK,kBAAkB,WAAW,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;SACtE,CAAA,IACR;SACH,UAAU,KAAA,KAAa,MAAM,QAAQ,SAAS,IAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;UAAU,UAAU,UAAU;WAAE,MAAM,gBAAgB;WAAG,cAAc,WAAW,MAAM,MAAM,OAAO;UAAE;oBAAI,GAAG,qBAAqB;SAAU,CAAA,IACpM;SACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,MAAK;UAAS,gBAAc,KAAK,UAAU;UAAO,cAAY,WAAW;UAC7F,WAAWA,yBAAI,UAAU,KAAK,UAAU,OAAO,MAAMA,yBAAI,WAAW,KAAK,UAAU,UAAU,MAAMA,yBAAI,cAAc;UACrH,UAAU,aAAa,WAAW,WAAW,WAAW,KAAM,KAAK,UAAU,SAAS,CAAC;UACvF,OAAO,KAAK,UAAU,SAAS,CAAC,cAAc,GAAG,mBAAmB,IAAI,KAAA;UACxE,UAAU,UAAU;WAAE,MAAM,gBAAgB;WAAG,YAAY,SAAS,WAAW,MAAM,WAAW,MAAM,KAAK,KAAK;UAAE;oBAClH,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;SAC7B,CAAA;QACJ;SACH;UACJ,CAAC,YACA,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACG,OAAO,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,GAC3E,gBAAgB,KAAK,WACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;OAAuC;OAAQ,MAAM,UAAU,IAAI,OAAO,IAAI;OAAG,gBAAgB;QAAE,eAAoB,MAAM;OAAE;MAAI,GAAjH,OAAO,IAA0G,CACpI,CACD,EAAA,CAAA,IACA,IACG;QAzCK,SAAS,WAAW,IAyCzB;IAEb,CAAC;WACO;KAEN,MAAM,gBAAgB,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,QAAQ,MAAM,UAAU,KAAA,KAAa,CAAC,gBAAgB,MAAM,MAAM,CAAC;KACzJ,IAAI,cAAc,WAAW,GAAG,OAAO;KACvC,MAAM,YAAY,gBAAgB,IAAI,sBAAsB;KAC5D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAAS,WAAWA,yBAAI;gBAAxB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAY,iBAAe,CAAC;QAAW,eAAe;SAAE,oBAAoB,sBAAsB;QAAE;kBAAzI,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,YAAY,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAC/E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB;UACG,GAAG,iBAAiB;UAAE;UAAI,cAAc;UACzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;WAAc,SAAS,cAAc,KAAK,UAAU,MAAM,IAAI;WAAQ;UAAM,CAAA;SACxE;UACA;;MACL,CAAA,GACJ,CAAC,YAAY,cAAc,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,IAAI,IAC7F;;IAEb,EAAA,CAAG;GACH,EAAA,CAAA;EAEN;;;EC9KA,SAAgB,WAAW,OAA4C;GACrE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,SAAS,aAAa,QAAQ,YAAY,iBAAiB,WAAW,aAAa,WAAW,WAAW,YAAY,eAAe,SAAS,WAAW,qBAAqB,aAAa,eAAe,aAAa,iBAAiB,eAAe,mBAAmB;GACjR,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWC,yBAAI;KAAM,WAAW,UAAU;MAAE,UAAe,KAAK;KAAE;eACtE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;OACjC,OAAO;OACP,WAAW,UAAU;QAAE,cAAc,MAAM,OAAO,KAAK;OAAE;OACzD,aAAa,GAAG,wBAAwB;MACzC,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU,WAAW,WAAW,KAAK,MAAM;iBAAK,GAAG,YAAY;MAAU,CAAA,CACvI;;IACD,CAAA;IAEL,gBAAgB,QAAQ,YAAY,KAAK,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAAQ,GAAG,cAAc;IAAO,CAAA,IAAI;IAChH,aAAa,KAAK,KAAK,QAAQ;KAC9B,MAAM,SAAS,OAAO,QAAQ,UAAU,IAAI,WAAW,SAAS,MAAM,IAAI,CAAC;KAC3E,MAAM,mBAAmB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WAAW,IAAI,WAAW,SAAS,OAAO,IAAI,MAAM,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,EAAE;KAC7P,MAAM,YAAY,gBAAgB,IAAI,SAAS,IAAI,EAAE;KACrD,MAAM,OAAO,gBAAgB,IAAI,YAAY,SAAS;KACtD,MAAM,cAAc,IAAI,WAAW,MAAM,SAAS,YAAY,IAAI,IAAI,CAAC;KACvE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAA+B,WAAWA,yBAAI;gBAA9C,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAY,iBAAe,CAAC;QAAW,eAAe;SAAE,oBAAoB,SAAS,IAAI,EAAE;QAAE;kBAAlI,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,YAAY,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAC/E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB;UACG,IAAI;UAAK;UAAI,IAAI,WAAW;UAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;WAAc,SAAS,IAAI;WAAiB;UAAM,CAAA;SAC9C;UACA;WACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,MAAK;SAAS,gBAAc,KAAK,UAAU;SAAO,cAAY,IAAI;SACtF,WAAWA,yBAAI,UAAU,KAAK,UAAU,OAAO,MAAMA,yBAAI,WAAW,KAAK,UAAU,UAAU,MAAMA,yBAAI,cAAc;SACrH,UAAU,aAAa,IAAI,WAAW,WAAW,KAAM,KAAK,UAAU,SAAS,CAAC;SAChF,OAAO,KAAK,UAAU,SAAS,CAAC,cAAc,GAAG,mBAAmB,IAAI,KAAA;SACxE,UAAU,UAAU;UAAE,MAAM,gBAAgB;UAAG,YAAY,SAAS,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK;SAAE;mBAClG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;QAC7B,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,eAAe;UAAE,cAAc,GAAG;UAAG,YAAY,IAAI,IAAI;UAAG,gBAAgB,IAAI,IAAI,IAAI,UAAU,CAAC;UAAG,cAAc,EAAE;SAAE;mBAAI,GAAG,aAAa;QAAU,CAAA,CAC9L;SACH;UACJ,CAAC,YACA,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACG,OAAO,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,GAC3E,gBAAgB,KAAK,WACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;OAAuC;OAAQ,MAAM,UAAU,IAAI,OAAO,IAAI;OAAG,gBAAgB;QAAE,eAAoB,MAAM;OAAE;MAAI,GAAjH,OAAO,IAA0G,CACpI,CACD,EAAA,CAAA,IACA,IACG;QA5BK,SAAS,IAAI,EA4BlB;IAEb,CAAC;GACD,EAAA,CAAA;EAEN;;;;EC1DA,MAAa,iBAAgD;GAC3D;IAAE,MAAM;IAAqB,gBAAgB;GAA4B;GACzE;IAAE,MAAM;IAAoB,gBAAgB;GAA6B;GACzE;IAAE,MAAM;IAAqB,gBAAgB;GAA4B;GACzE;IAAE,MAAM;IAAuB,gBAAgB;GAA4B;EAC7E;;;;;;;;;;ECyBA,SAAS,YAAY,OAAkE;GACrF,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,MAAM,SAAS,UAA+B;KAC5C,IAAI,MAAM,QAAQ,UAAU,MAAM,QAAQ;IAC5C;IACA,OAAO,iBAAiB,WAAW,KAAK;IACxC,aAAa;KAAE,OAAO,oBAAoB,WAAW,KAAK;IAAE;GAC9D,CAAC;GACD,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;IAAe,SAAS,MAAM;cAChD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;KAAQ,MAAK;KAAc,cAAW;KAAO,UAAU,UAAU;MAAE,MAAM,gBAAgB;KAAE;eAC5G,MAAM;IACJ,CAAA;GACF,CAAA;EAET;;EAGA,SAAgB,cAAc,OAUd;GACd,MAAM,EAAE,OAAO,MAAM,OAAO,cAAc,QAAQ,UAAU,cAAc;GAC1E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAa,SAAS;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc;KAAU,CAAA;KAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa;KAAQ,CAAA;KACtC,UAAU,KAAA,IACT,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAChB,MAAM,KAAK,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAe,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAAc;MAAW,CAAA,EAAK,GAAzD,IAAyD,CAAC;KACtF,CAAA,IACF;KACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,aAAa;MAAU,CAAA,GAC3F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,UAAU,WAAW,OAAO,MAAMA,yBAAI,SAAS,MAAMA,yBAAI;OAAU,SAAS;iBAC9G;MACK,CAAA,CACL;;IACM;;EAEjB;;EAGA,SAAgB,eAAe,OAOf;GACd,MAAM,EAAE,QAAQ,MAAM,aAAa,SAAS,UAAU,eAAe;GACrE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAsB;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc,GAAG,sBAAsB;KAAM,CAAA;KAChE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,qBAAqB;KAAK,CAAA;KAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAChB,OAAO,UAAU,KAAK,SACrB,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAAc;MAAW,CAAA,GAC7C,QAAQ,aAAa,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAChE,EAAA,GAHK,IAGL,CACL;KACC,CAAA;KACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,eAAe;MAAU,CAAA,GAC7F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,SAAS;iBAAa,GAAG,iBAAiB;MAAU,CAAA,CAClH;;IACM;;EAEjB;;EAGA,SAAgB,mBAAmB,OAMnB;GACd,MAAM,EAAE,QAAQ,MAAM,UAAU,UAAU,cAAc;GACxD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAa,SAAS;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc,GAAG,oBAAoB;KAAM,CAAA;KAC9D,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,mBAAmB;KAAK,CAAA;KAC1D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAQ,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;MAAc,OAAO,OAAO;MACpE,WAAW,UAAU;OAAE,SAAS,MAAM,OAAO,KAAK;MAAE;gBACnD,OAAO,SAAS,KAAK,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAqB,OAAO;iBAAS;MAAe,GAAvC,MAAuC,CAAC;KAChF,CAAA;KACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,aAAa;MAAU,CAAA,GAC3F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU;OAAM,SAAS;iBAAY,GAAG,sBAAsB;MAAU,CAAA,CACtI;;IACM;;EAEjB;;EAGA,SAAgB,iBAAiB,OAMjB;GACd,MAAM,EAAE,QAAQ,MAAM,UAAU,UAAU,cAAc;GACxD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAa,SAAS;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc,GAAG,kBAAkB;KAAM,CAAA;KAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,mBAAmB,EAAE,KAAK,OAAO,IAAI,CAAC;KAAK,CAAA;KAC5E,OAAO,OAAO,WAAW,IACxB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,iBAAiB;KAAK,CAAA,IAExD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBACjB,OAAO,OAAO,KAAK,SAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAkB,WAAWA,yBAAI;iBAAjC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QAAO,MAAK;QAAW,SAAS,OAAO,SAAS,IAAI,IAAI;QACtD,WAAW,UAAU;SAAE,SAAS,MAAM,MAAM,OAAO,OAAO;QAAE;OAAI,CAAA,GAClE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAc;OAAW,CAAA,CACzC;SAJK,IAIL,CACR;KACE,CAAA;KAEP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,mBAAmB;MAAU,CAAA,GACjG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU,QAAQ,OAAO,OAAO,WAAW;OAAG,SAAS;iBACrH,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;MACzC,CAAA,CACL;;IACM;;EAEjB;;;;;;;;;;ECxKA,SAAS,YAAY,OAAuB;GAC1C,IAAI,QAAQ,MAAM,OAAO,QAAQ;GACjC,IAAI,QAAQ,OAAO,MAAM,QAAQ,QAAQ,KAAA,CAAM,QAAQ,CAAC,IAAI;GAC5D,QAAQ,QAAQ,OAAO,KAAA,CAAM,QAAQ,CAAC,IAAI;EAC5C;EAEA,SAAgB,WAAW,OAA4C;GACrE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,aAAa,aAAa,aAAa,cAAc,mBAAmB,cAAc,cAAc,iBAAiB,eAAe,YAAY,eAAe,kBAAkB,eAAe,SAAS,WAAW,iBAAiB,oBAAoB,UAAU,aAAa,cAAc,kBAAkB,oBAAoB,YAAY,iBAAiB,oBAAoB,cAAc;;GAE3Y,MAAM,iBAAiB,OAAO,QAAQ,WAAW,CAAC,CAAC,QAAQ,GAAG,WAAW,MAAM,WAAW,MAAM,QAAQ,SAAS,CAAC;;GAGlH,MAAM,aAAa,WAA4C;IAC7D,MAAM,eAAe,YAAY,OAAO;IACxC,MAAM,aAAa,YAAY,OAAO;IACtC,MAAM,iBAAiB,cAAc,QAAQ,MAAM,WAAW,OAAO,SAAS,OAAO,IAAI,CAAC,EAAE,OAAO,UAAU;IAC7G,MAAM,WAAW,iBAAiB,OAAO;IACzC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,yBAAI,MAAM,MAAMA,yBAAI;eAApC;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,WAAWA,yBAAI;UAAY,MAAM,wBAAwB,OAAO;UAAM,QAAO;UAAS,KAAI;oBAAc,OAAO;SAAQ,CAAA;SACzH,OAAO,QAAQ,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAc,OAAO;SAAU,CAAA,IAAI;SACrG,iBAAiB,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAa,GAAG,oBAAoB,EAAE,OAAO,eAAe,CAAC;SAAQ,CAAA,IAAI;SACrI,YAAY,YAAY,QAAQ,WAAW,QAAQ,SAAS,IACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAgB,GAAG,oBAAoB,EAAE,OAAO,WAAW,QAAQ,OAAO,CAAC;SAAQ,CAAA,IAC1H;SACH,eAAe,KAAA,KAAa,WAAW,QAAQ,SAAS,IACrD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAc,GAAG,0BAA0B,EAAE,OAAO,WAAW,QAAQ,OAAO,CAAC;SAAQ,CAAA,IAC9H;SACH,cAAc,oBAAoB,OAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAgB,aAAa,cAAc,KAAA,IAAY,GAAG,qBAAqB,EAAE,SAAS,aAAa,UAAU,CAAC,IAAI,GAAG,gBAAgB;SAAQ,CAAA,IACxL;QACD;;MACF,CAAA;MACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAO,UAAU;OAAU,eAAe;QAAE,YAAiB;OAAE;iBAAI,GAAG,cAAc;MAAU,CAAA;MACnI,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,cAAc,oBAAoB,OAAO,MAAMA,yBAAI,WAAW;OAAK,UAAU,kBAAkB,OAAO;OAAM,eAAe;QAAE,iBAAsB,OAAO,IAAI;OAAE;iBAC3M,kBAAkB,OAAO,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;MAClE,CAAA;MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAO,UAAU;OAAU,eAAe;QAAE,SAAc,OAAO,IAAI;OAAE;iBACzG,WAAW,GAAG,iBAAiB,IAAI,GAAG,aAAa;MAC9C,CAAA;MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAO,UAAU;OAAS,OAAO,GAAG,mBAAmB;OAAG,eAAe;QAAE,mBAAwB,OAAO,IAAI;OAAE;iBAAI,GAAG,qBAAqB;MAAU,CAAA;KACxL;;GAET;GAIA,MAAM,OAAqD,CAAC;GAC5D,KAAK,MAAM,SAAS,gBAAgB;IAClC,MAAM,SAAS,YAAY,MAAM,MAAM,SAAS,KAAK,SAAS,MAAM,IAAI;IACxE,IAAI,WAAW,KAAA,GACb,KAAK,KAAK;KAAE,KAAK,MAAM;KAAM,SAAS,UAAU,MAAM;IAAE,CAAC;SACpD;KACL,MAAM,OAAO,iBAAiB,QAAQ;KACtC,KAAK,KAAK;MACR,KAAK,MAAM;MACX,SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;iBAApC,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,WAAWA,yBAAI;UAAY,MAAM,wBAAwB,MAAM;UAAM,QAAO;UAAS,KAAI;oBAAc,MAAM;SAAQ,CAAA;QACrH,CAAA,GACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,GAAG,MAAM,cAAc;QAAO,CAAA,CACzD;WACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAO,UAAU;QAAM,eAAe;SAAE,UAAe,MAAM,IAAI;QAAE;kBAAI,GAAG,YAAY;OAAU,CAAA,CAClI;;KAET,CAAC;IACH;GACF;GACA,KAAK,MAAM,UAAU,YAAY,OAAO;IACtC,IAAI,eAAe,MAAM,UAAU,MAAM,SAAS,OAAO,IAAI,GAAG;IAChE,KAAK,KAAK;KAAE,KAAK,OAAO;KAAM,SAAS,UAAU,MAAM;IAAE,CAAC;GAC5D;GACA,MAAM,iBAAiB,eAAe,QAAQ,UAAU,CAAC,YAAY,MAAM,MAAM,WAAW,OAAO,SAAS,MAAM,IAAI,CAAC;GAEvH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KAAS,WAAWA,yBAAI;eAAxB;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,eAAe,MAAMA,yBAAI;iBAA7C;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAAmB,GAAG,cAAc;QAAQ,CAAA;QACjE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,eAAe;UAAE,aAAkB;UAAG,YAAiB;SAAE;mBAAI,GAAG,iBAAiB;QAAU,CAAA;QACvI,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAWA,yBAAI,SAAS,eAAe,SAAS,IAAI,MAAMA,yBAAI,WAAW;SACzE,UAAU,eAAe,WAAW,KAAK;SACzC,eAAe;UAAE,mBAAmB,IAAI;SAAE;mBAC1C,GAAG,kBAAkB;QAAU,CAAA;OAC9B;;MACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;iBAAxC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;QACjC,OAAO;QACP,WAAW,UAAU;SAAE,iBAAiB,MAAM,OAAO,KAAK;QAAE;QAC5D,YAAY,UAAU;SAAE,IAAI,MAAM,QAAQ,SAAS;UAAE,MAAM,eAAe;UAAG,gBAAqB;SAAE;QAAE;QACtG,aAAa,GAAG,uBAAuB;OACxC,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;QAAS,UAAU,cAAc,KAAK,MAAM;QAAI,eAAe;SAAE,gBAAqB;QAAE;kBAAI,GAAG,kBAAkB;OAAU,CAAA,CAChL;;MACJ,eAAe,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,yBAAI,WAAW,MAAMA,yBAAI;iBAAa,GAAG,oBAAoB;MAAK,CAAA,IAAI;MAEhH,YAAY,WAAW,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,eAAe;MAAO,CAAA,IAAI;MAC5F,YAAY,WAAW,aAAa,KAAK,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,kBAAkB;MAAO,CAAA,IAAI;MACpH,YAAY,WAAW,YAAY,KAAK,KAAK,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAACC,MAAAA,UAAD,EAAA,UAAyB,IAAI,QAAkB,GAAhC,IAAI,GAA4B,CAAC,IAAI;KACnG;;IACR,kBAAkB,WAAW,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWD,yBAAI;eAAQ,GAAG,iBAAiB;IAAO,CAAA,IAAI;IACrG,kBAAkB,WAAW,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAAc,kBAAkB;IAAa,CAAA,IAAI;IAC5G,kBAAkB,WAAW,iBAAiB;KAC7C,MAAM,UAAU,kBAAkB,KAAK;KACvC,MAAM,WAAW,QAAQ,QAAQ,UAAU,aAAa,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,QAAQ;KAC1F,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI,WAAW,MAAMA,yBAAI;gBAAa,GAAG,cAAc,EAAE,OAAO,QAAQ,OAAO,CAAC;KAAK,CAAA,GAClG,QAAQ,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,YAAY;KAAO,CAAA,IACxE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;iBAAxC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAQ,eAAe;SAAE,gBAAgB,IAAI,IAAI,QAAQ,QAAQ,UAAU,CAAC,MAAM,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC;QAAE;kBAAI,GAAG,gBAAgB;OAAU,CAAA,GAC/L,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAQ,eAAe;SAAE,gCAAgB,IAAI,IAAI,CAAC;QAAE;kBAAI,GAAG,eAAe;OAAU,CAAA,CACtH;;MACH,CAAC,UAAU,kBAAkB,CAAC,CAAW,KAAK,SAAS;OACvD,MAAM,cAAc,QAAQ,QAAQ,UAAU,MAAM,SAAS,IAAI;OACjE,IAAI,YAAY,WAAW,GAAG,OAAO;OACrC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAgB,WAAWA,yBAAI;kBAA/B,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAe,SAAS,WAAW,GAAG,kBAAkB,IAAI,GAAG,2BAA2B;QAAO,CAAA,GACpH,YAAY,KAAK,UAChB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;SAAwB,WAAWA,yBAAI,OAAO,MAAM,WAAW,MAAMA,yBAAI,WAAW;mBAApF;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;WACE,MAAK;WACL,SAAS,aAAa,IAAI,MAAM,IAAI;WACpC,UAAU,MAAM;WAChB,WAAW,UAAU;YAAE,mBAAmB,MAAM,MAAM,MAAM,OAAO,OAAO;WAAE;UAC7E,CAAA;UACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,yBAAI;qBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;YAAK,WAAWA,yBAAI;sBAAU,MAAM;WAAU,CAAA,GAC9C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,WAAWA,yBAAI;sBAApB;aAA8B,MAAM;aAAI;aAAI,GAAG,cAAc;cAAE,OAAO,MAAM;cAAW,MAAM,YAAY,MAAM,UAAU;aAAE,CAAC;YAAO;aAChI;;UACJ,MAAM,WACH,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;qBAAgB,GAAG,eAAe;UAAQ,CAAA,IACjF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;qBAAc,MAAM;UAAa,CAAA;SACvE;WAdK,MAAM,IAcX,CACR,CACE;UAnBK,IAmBL;MAET,CAAC;MACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU,SAAS,WAAW,KAAK;OAAe,eAAe;QAAE,WAAgB;OAAE;iBAAI,gBAAgB,GAAG,gBAAgB,IAAI,GAAG,eAAe,EAAE,OAAO,SAAS,OAAO,CAAC;MAAU,CAAA;KACvP,EAAA,CAAA,CAEJ,EAAA,CAAA;IAEN,EAAA,CAAG,IAAI;IACN,eAAe,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;eAA5C;MAAyD,GAAG,iBAAiB,EAAE,OAAO,WAAW,SAAS,OAAO,CAAC;MAAE;MAAI,GAAG,wBAAwB,EAAE,OAAO,WAAW,QAAQ,OAAO,CAAC;MAAE;MAAI,GAAG,eAAe,EAAE,OAAO,WAAW,OAAO,OAAO,CAAC;KAAO;SAAI;IAEnR,kBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;KACE,OAAO,GAAG,8BAA8B;KACxC,MAAM,GAAG,6BAA6B;KACtC,OAAO,eAAe,KAAK,CAAC,MAAM,WAAW,GAAG,wBAAwB;MAAE;MAAM,OAAO,MAAM,QAAQ;KAAO,CAAC,CAAC;KAC9G,cAAc,GAAG,kBAAkB;KACnC,QAAA;KACA,gBAAgB;MAAE,mBAAmB,KAAK;KAAE;KAC5C,iBAAiB;MAAE,UAAe;KAAE;IACrC,CAAA,IACC;GACJ,EAAA,CAAA;EAEN;;;;;;;;;;;ECzJA,MAAM,UAAU;;EAEhB,MAAM,eAAe;;EAGrB,MAAM,iBAAiB;;EAEvB,MAAM,yBAAyB,OAAU;;EAGzC,SAAS,kBAA2B;GAClC,IAAI;IACF,MAAM,MAAM,aAAa,QAAQ,cAAc;IAC/C,MAAM,OAAO,QAAQ,OAAO,MAAM,OAAO,GAAG;IAC5C,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;IACnC,OAAO,KAAK,IAAI,IAAI,QAAQ;GAC9B,QAAQ;IAEN,OAAO;GACT;EACF;;EAGA,SAAS,kBAAwB;GAC/B,IAAI;IACF,aAAa,QAAQ,gBAAgB,OAAO,KAAK,IAAI,CAAC,CAAC;GACzD,QAAQ,CAER;EACF;EAyBA,SAAgB,YAAY,KAAkB;GAC5C,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAA+C,IAAI;GACnE,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAuB,IAAI;GAC3C,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAAwC,IAAI;;GAE9D,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GACtE,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwC,EAAE,QAAQ,OAAO,CAAC;GAC9E,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAoD,EAAE,QAAQ,OAAO,CAAC;;GAEhG,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GACpE,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,iBAAiD,IAAI,IAAI,CAAC;GAC/E,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA6B,KAAK;GACxD,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAAqD,IAAI;GAC5E,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAsB,EAAE;;GAEvC,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAAyB,EAAE;GAC7C,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAA0C,IAAI;GAC7D,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA6B,KAAK;GACxD,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,iBAA8C,IAAI,IAAI,CAAC;GACzE,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAAyB,KAAK;GAChD,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAC9C,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,EAAE;GAC3C,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,EAAE;GAC3C,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAsC,UAAU;GACjE,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAC9C,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAA+E,IAAI;GACvG,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,iBAA+E,IAAI,IAAI,CAAC;GACrG,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GACjE,MAAM,CAAC,KAAK,WAAA,GAAA,MAAA,SAAA,CAAoD,SAAS;GACzE,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAA4C,QAAQ;GACtE,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA4B,KAAK;GACtD,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAgC,MAAM;GACtD,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwC;IAAE,QAAQ;IAAW,OAAO,CAAC;GAAE,CAAC;GAC5F,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwE,CAAC,CAAC;GAC9F,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAAsD,IAAI;GAC/E,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,KAAK;GAClD,MAAM,CAAC,kBAAkB,wBAAA,GAAA,MAAA,SAAA,CAA8D,IAAI;GAC3F,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GACtE,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAC9C,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA6B,EAAE;GACrD,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAkD,IAAI;GAC1E,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAAoD,IAAI;GAC7E,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwE,CAAC,CAAC;GAC9F,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA6C,IAAI;GACxE,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GACtE,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA0D,IAAI;GACrF,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAAwD,IAAI;GAClF,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAgD,IAAI;GAC9E,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAiC,KAAK;;GAEhE,MAAM,CAAC,iBAAiB,uBAAA,GAAA,MAAA,SAAA,CAA+B,KAAK;GAC5D,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GAClE,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,EAAE;GAC3C,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,iBAAiD,IAAI,IAAI,CAAC;GAC/E,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,EAAE;GAC/C,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAuB,KAAK;GAC5C,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,EAAE;;GAE/C,MAAM,CAAC,iBAAiB,uBAAA,GAAA,MAAA,SAAA,iBAAoD,IAAI,IAAI,CAAC;;GAErF,MAAM,CAAC,oBAAoB,0BAAA,GAAA,MAAA,SAAA,iBAAuD,IAAI,IAAI,CAAC;GAC3F,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,KAAK;GAElD,MAAM,uBAAA,GAAA,MAAA,YAAA,EAAmC,QAAsB;IAC7D,oBAAoB,aAAa;KAC/B,MAAM,OAAO,IAAI,IAAI,QAAQ;KAC7B,IAAI,KAAK,IAAI,GAAG,GAAG,KAAK,OAAO,GAAG;UAC7B,KAAK,IAAI,GAAG;KACjB,OAAO;IACT,CAAC;GACH,GAAG,CAAC,CAAC;GAEL,MAAM,mBAAA,GAAA,MAAA,YAAA,EAA+B,QAAsB;IACzD,uBAAuB,aAAa;KAClC,MAAM,OAAO,IAAI,IAAI,QAAQ;KAC7B,IAAI,KAAK,IAAI,GAAG,GAAG,KAAK,OAAO,GAAG;UAC7B,KAAK,IAAI,GAAG;KACjB,OAAO;IACT,CAAC;GACH,GAAG,CAAC,CAAC;GAEL,MAAM,QAAA,GAAA,MAAA,YAAA,CAAmB,YAA2B;IAClD,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,QAAQ,cAAc,KAAK,EAAE,KAAK,UAAU,IAAI,KAAA,CAAS;KAChF,WAAW,IAAI;KACf,aAAa,IAAI;IACnB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;GAEnB,MAAM,YAAA,GAAA,MAAA,YAAA,CAAuB,YAA2B;IACtD,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,MAAM;KAC/B,IAAI,OAAO,WAAW,QAAQ,IAAI,IAAI,OAAO,MAAM,KAAK,SAAS,CAAC,KAAK,MAAM;MAAE,OAAO,KAAK;MAAO,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;KAAG,CAAC,CAAC,CAAC,CAAC;IAC5K,QAAQ,CAER;GACF,GAAG,CAAC,GAAG,CAAC;GAER,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI;KACF,cAAc,MAAM,IAAI,OAAO,EAAA,CAAG,MAAM;IAC1C,QAAQ,CAER;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,YAA2B;IACzD,eAAe,EAAE,QAAQ,WAAW,CAAC;IACrC,IAAI;KACF,eAAe;MAAE,QAAQ;MAAS,MAAM,MAAM,IAAI,YAAY;KAAE,CAAC;IACnE,SAAS,OAAO;KACd,eAAe;MAAE,QAAQ;MAAS,SAAS,aAAa,KAAK;KAAE,CAAC;IAClE;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI;KACF,eAAe,MAAM,IAAI,OAAO,CAAC;IACnC,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,YAA2B;IACzD,IAAI;KACF,gBAAgB,MAAM,IAAI,QAAQ,CAAC;IACrC,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO;KAC9B,eAAe;MAAE,QAAQ;MAAS,OAAO,KAAK;KAAM,CAAC;IACvD,SAAS,OAAO;KACd,eAAe;MAAE,QAAQ;MAAS,OAAO,CAAC;KAAE,CAAC;KAC7C,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,aAAA,GAAA,MAAA,YAAA,EAAyB,SAA2B;IACxD,gBAAgB,aAAa,aAAa,OACtC;KAAE,IAAI;KAAM;KAAM,aAAa,CAAC;KAAG,SAAS,CAAC;IAAE,IAC/C;KAAE,GAAG;KAAU;IAAK,CAAC;GAC3B,GAAG,CAAC,CAAC;GAML,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,KAAU;IACV,SAAc;IACd,WAAgB;IAChB,YAAiB;IACjB,WAAgB;IAChB,MAAM,OAAO,OAAO,kBAAkB;KAAE,KAAU;IAAE,GAAG,OAAO;IAC9D,MAAM,OAAO,OAAO,kBAAkB;KAAE,SAAc;KAAG,WAAgB;KAAG,YAAiB;KAAG,WAAgB;IAAE,GAAG,YAAY;IACjI,aAAa;KAAE,OAAO,cAAc,IAAI;KAAG,OAAO,cAAc,IAAI;IAAE;GACxE,GAAG;IAAC;IAAM;IAAU;IAAY;IAAa;GAAU,CAAC;GAExD,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,OAAO,SAAgC;IACpE,iBAAiB,IAAI;IACrB,aAAa,IAAI;IACjB,IAAI;KACF,UAAU,MAAM,IAAI,MAAM,MAAM,cAAc,KAAK,EAAE,KAAK,UAAU,IAAI,KAAA,CAAS,CAAC;IACpF,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,iBAAiB,KAAK;IACxB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;GAEnB,MAAM,UAAA,GAAA,MAAA,YAAA,CAAqB,OAAO,OAAqB,YAAoC;IACzF,cAAc,aAAa,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC;IAC5D,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO,MAAM,MAAM,OAAO;KACjD,WAAW,IAAI;IACjB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,cAAc,aAAa;MACzB,MAAM,OAAO,IAAI,IAAI,QAAQ;MAC7B,KAAK,OAAO,MAAM,IAAI;MACtB,OAAO;KACT,CAAC;IACH;GACF,GAAG,CAAC,GAAG,CAAC;GAER,MAAM,kBAAA,GAAA,MAAA,YAAA,CAA6B,OAAO,WAAyC;IACjF,cAAc,aAAa,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC;IAC7D,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO,OAAO,MAAM,IAAI;KAC/C,WAAW,IAAI;IACjB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,cAAc,aAAa;MACzB,MAAM,OAAO,IAAI,IAAI,QAAQ;MAC7B,KAAK,OAAO,OAAO,IAAI;MACvB,OAAO;KACT,CAAC;IACH;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,oBAAA,GAAA,MAAA,YAAA,CAA+B,OAAO,OAAiB,YAAoC;IAC/F,IAAI,MAAM,WAAW,GAAG;IACxB,aAAa,IAAI;IACjB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,YAAY,OAAO,OAAO;KACjD,WAAW,KAAK,OAAO;KACvB,IAAI,KAAK,SAAS,SAAS,GACzB,aAAa,mBAAmB,KAAK,SAAS,KAAK,YAAY,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;IAElH,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,aAAa,KAAK;IACpB;GACF,GAAG,CAAC,GAAG,CAAC;;GAKR,MAAM,YAAA,GAAA,MAAA,YAAA,OAAoD;IACxD,MAAM,sBAAM,IAAI,IAAsB;IACtC,KAAK,MAAM,OAAO,aAAa,QAAQ,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,IAAI,IAAI,UAAU;IAClF,KAAK,MAAM,cAAc,aAAa,eAAe,CAAC,GAAG,IAAI,IAAI,SAAS,WAAW,MAAM,WAAW,UAAU;IAChH,OAAO;GACT,GAAG,CAAC,WAAW,CAAC;;GAGhB,MAAM,eAAA,GAAA,MAAA,QAAA,OAA4B,IAAI,KAAK,SAAS,UAAU,CAAC,EAAA,CAAG,QAAQ,UAAU,MAAM,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;;GAG1I,MAAM,aAAA,GAAA,MAAA,QAAA,OAA0B,IAAI,KAAK,SAAS,UAAU,CAAC,EAAA,CAAG,KAAK,UAAU,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;;;;;GAMtG,MAAM,eAAA,GAAA,MAAA,YAAA,EAA2B,KAAa,MAAc,SAAiC;IAC3F,MAAM,UAAU,SAAS,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;IACxC,IAAI,QAAQ,WAAW,GAAG;IAC1B,IAAI,SAAS,OAAO;KAClB,iBAAsB,SAAS,IAAI;KACnC;IACF;IACA,MAAM,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,aAAa,GAAG,CAAC,CAAC,KAAK,GAAG,kBAAkB,EAAE,SAAS,YAAY,EAAE;IACrI,MAAM,YAAY,iBAAiB,SAAS,aAAa,MAAM;IAC/D,IAAI,UAAU,SAAS,GACrB,kBAAkB;KAAE;KAAK;KAAM;IAAU,CAAC;SAE1C,iBAAsB,QAAQ,QAAQ,WAAW,YAAY,IAAI,MAAM,CAAC,GAAG,KAAK;GAEpF,GAAG;IAAC;IAAU;IAAa;GAAgB,CAAC;;GAG5C,MAAM,mBAAA,GAAA,MAAA,YAAA,CAA8B,OAAO,aAAqC;IAC9E,MAAM,SAAS;IACf,IAAI,WAAW,MAAM;IACrB,kBAAkB,IAAI;IACtB,MAAM,UAAU,SAAS,CAAC,CAAC,IAAI,OAAO,GAAG,KAAK,CAAC;IAC/C,IAAI,UACF,MAAM,iBAAiB,QAAQ,QAAQ,WAAW,YAAY,IAAI,MAAM,CAAC,GAAG,KAAK;SAEjF,MAAM,iBACJ,QAAQ,QAAQ,WAAW,YAAY,IAAI,MAAM,KAAK,CAAC,OAAO,UAAU,SAAS,MAAM,CAAC,GACxF,KACF;GAEJ,GAAG;IAAC;IAAgB;IAAU;IAAa;GAAgB,CAAC;;GAG5D,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,YAA2B;IAC1D,MAAM,SAAS;IACf,IAAI,WAAW,MAAM;IACrB,iBAAiB,IAAI;IACrB,IAAI,OAAO,SAAS,QAAQ;KAC1B,iBAAiB,OAAO,IAAI;KAC5B,aAAa,IAAI;KACjB,IAAI;MACF,MAAM,SAAS,MAAM,IAAI,WAAW,OAAO,MAAM,OAAO,MAAM;MAC9D,MAAM,QAAQ,IAAI;OAAC,KAAK;OAAG,WAAW;OAAG,YAAY;MAAC,CAAC;MACvD,IAAI,OAAO,OAAO,SAAS,GACzB,aAAa,WAAW,OAAO,OAAO,KAAK,YAAY,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;KAE1G,SAAS,OAAO;MACd,aAAa,aAAa,KAAK,CAAC;KAClC,UAAU;MACR,iBAAiB,IAAI;KACvB;IACF,OAAO;KACL,aAAa,IAAI;KACjB,IAAI;MACF,MAAM,IAAI,oBAAoB,OAAO,MAAM,OAAO,MAAM;MACxD,MAAM,QAAQ,IAAI;OAAC,KAAK;OAAG,WAAW;OAAG,YAAY;MAAC,CAAC;KACzD,SAAS,OAAO;MACd,aAAa,aAAa,KAAK,CAAC;KAClC;IACF;GACF,GAAG;IAAC;IAAe;IAAK;IAAM;IAAY;GAAW,CAAC;;GAKtD,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,OAAO,SAAiC;IACvE,kBAAkB,QAAQ,KAAK;IAC/B,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,aAAa,IAAI;KAC1C,MAAM,OAA0C,EAAE,GAAG,YAAY;KACjE,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,KAAK,QAAQ;KACrD,eAAe,IAAI;IACrB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,kBAAkB,IAAI;IACxB;GACF,GAAG,CAAC,KAAK,WAAW,CAAC;;GAGrB,MAAM,eAAA,GAAA,MAAA,YAAA,EAA2B,MAAc,WAA2B;IACxE,iBAAiB;KAAE,MAAM;KAAQ;KAAM;IAAO,CAAC;GACjD,GAAG,CAAC,CAAC;;GAGL,MAAM,iBAAA,GAAA,MAAA,YAAA,EAA6B,MAAc,WAA2B;IAC1E,iBAAiB;KAAE,MAAM;KAAU;KAAM;IAAO,CAAC;GACnD,GAAG,CAAC,CAAC;;GAGL,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,OAAO,SAAgC;IACtE,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,cAAc,IAAI;KAC5B,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;IACzD,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAM;IAAY;GAAW,CAAC;;GAGvC,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,qBAAqB,KAAK;IAC1B,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,WAAW;KACpC,IAAI,OAAO,OAAO,SAAS,GACzB,aAAa,kBAAkB,OAAO,OAAO,KAAK,YAAY,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;KAE/G,MAAM,QAAQ,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC,CAAC;IAC3C,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAM;GAAW,CAAC;;GAG3B,MAAM,sBAAA,GAAA,MAAA,YAAA,EAAkC,SAAuB;IAC7D,qBAAqB,IAAI;GAC3B,GAAG,CAAC,CAAC;;GAGL,MAAM,kBAAA,GAAA,MAAA,YAAA,CAA6B,YAA2B;IAC5D,MAAM,OAAO;IACb,IAAI,SAAS,MAAM;IACnB,qBAAqB,IAAI;IACzB,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,YAAY,IAAI;KAC1B,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;IACzD,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAmB;IAAM;IAAY;GAAW,CAAC;;GAK1D,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,OAAO,UAAoC;IACvE,MAAM,eAAe;IACrB,MAAM,OAAO,WAAW,KAAK;IAC7B,IAAI,SAAS,IAAI;IACjB,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,UAAU,MAAM,IAAI,QAAQ,EAAE,KAAK,CAAC,CAAC;KACrC,cAAc,EAAE;IAClB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAW;GAAU,CAAC;;GAG/B,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,OAAO,OAA8B;IACjE,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,UAAU,MAAM,IAAI,UAAU,EAAE,CAAC;KACjC,cAAc,IAAI;IACpB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;;GAGnB,MAAM,WAAA,GAAA,MAAA,YAAA,CAAsB,OAAO,IAAY,MAAc,gBAAgD;IAC3G,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,WAAW,KAAK,KAAK;KAC3B,IAAI,OAA0B;KAC9B,IAAI,aAAa,IAAI,OAAO,MAAM,IAAI,QAAQ;MAAE;MAAI,MAAM;KAAS,CAAC;KACpE,IAAI,gBAAgB,MAAM,OAAO,MAAM,IAAI,cAAc,IAAI,WAAW;KACxE,IAAI,SAAS,MAAM;KACnB,UAAU,IAAI;KACd,cAAc,IAAI;IACpB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;;GAKnB,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,OAAO,UAAiC;IACpE,MAAM,QAAQ,MAAM,KAAK;IACzB,IAAI,UAAU,IAAI;IAClB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,gBAAgB,KAAK;KAC9C,eAAe;MAAE,QAAQ;MAAS,OAAO,OAAO;KAAM,CAAC;KACvD,iBAAiB,EAAE;KACnB,cAAc,IAAI;KAClB,gCAAgB,IAAI,IAAI,CAAC;KAEzB,MAAM,OAAO,OAAO,MAAM,OAAO,MAAM,SAAS,EAAE,CAAC;KACnD,gBAAgB,IAAI;KACpB,qBAAqB,EAAE,QAAQ,WAAW,CAAC;KAC3C,IAAI;MACF,MAAM,OAAO,MAAM,IAAI,aAAa,IAAI;MACxC,qBAAqB;OAAE,QAAQ;OAAS;MAAK,CAAC;KAChD,SAAS,OAAO;MACd,qBAAqB;OAAE,QAAQ;OAAS,SAAS,aAAa,KAAK;MAAE,CAAC;KACxE,UAAU;MACR,gBAAgB,IAAI;KACtB;IACF,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,mBAAA,GAAA,MAAA,YAAA,CAA8B,YAA2B;IAC7D,MAAM,UAAU,aAAa;GAC/B,GAAG,CAAC,WAAW,aAAa,CAAC;;GAG7B,MAAM,sBAAA,GAAA,MAAA,YAAA,CAAiC,OAAO,SAAgC;IAC5E,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,mBAAmB,IAAI;KAChD,eAAe;MAAE,QAAQ;MAAS,OAAO,OAAO;KAAM,CAAC;IACzD,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,YAAA,GAAA,MAAA,YAAA,CAAuB,OAAO,UAAiC;IACnE,MAAM,QAAQ,MAAM,KAAK;IACzB,IAAI,UAAU,IAAI;IAClB,cAAc,IAAI;IAClB,gCAAgB,IAAI,IAAI,CAAC;IACzB,gBAAgB,KAAK;IACrB,qBAAqB,EAAE,QAAQ,WAAW,CAAC;IAC3C,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,aAAa,KAAK;KACzC,IAAI,KAAK,QAAQ,MAAM;MAErB,gBAAgB;OAAE,MAAM,KAAK;OAAM,UAAU,KAAK,YAAY,CAAC;OAAG,WAAW,KAAK,YAAY,CAAC,EAAA,CAAG,MAAM;MAAO,CAAC;MAChH,qBAAqB,EAAE,QAAQ,OAAO,CAAC;MACvC;KACF;KACA,qBAAqB;MAAE,QAAQ;MAAS;KAAK,CAAC;IAChD,SAAS,OAAO;KACd,qBAAqB;MAAE,QAAQ;MAAS,SAAS,aAAa,KAAK;KAAE,CAAC;IACxE,UAAU;KACR,gBAAgB,IAAI;IACtB;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,uBAAA,GAAA,MAAA,YAAA,CAAkC,YAA2B;IACjE,IAAI,iBAAiB,MAAM;IAC3B,cAAc,IAAI;IAClB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,mBAAmB,aAAa,MAAM,aAAa,QAAQ;KACrE,gBAAgB,IAAI;KACpB,MAAM,SAAS,aAAa,IAAI;IAClC,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,cAAc,KAAK;IACrB;GACF,GAAG;IAAC;IAAK;IAAc;GAAQ,CAAC;;GAGhC,MAAM,sBAAA,GAAA,MAAA,YAAA,EAAkC,MAAc,YAA2B;IAC/E,iBAAiB,aAAa;KAC5B,MAAM,OAAO,IAAI,IAAI,QAAQ;KAC7B,IAAI,SAAS,KAAK,IAAI,IAAI;UACrB,KAAK,OAAO,IAAI;KACrB,OAAO;IACT,CAAC;GACH,GAAG,CAAC,CAAC;;GAGL,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI,kBAAkB,WAAW,SAAS;IAC1C,iBAAiB,IAAI;IACrB,cAAc,IAAI;IAClB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,WAAW,kBAAkB,KAAK,MAAM,CAAC,GAAG,YAAY,GAAG,kBAAkB,KAAK,OAAO,KAAA,CAAS;KAC3H,cAAc,MAAM;KACpB,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;IACvE,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,iBAAiB,KAAK;IACxB;GACF,GAAG;IAAC;IAAK;IAAmB;IAAc;IAAM;IAAY;IAAY;GAAW,CAAC;;GAGpF,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,YAA2B;IACzD,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,YAAY;KACrC,MAAM,OAA0C,CAAC;KACjD,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,KAAK,QAAQ;KACrD,eAAe,IAAI;IACrB,QAAQ,CAER;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,oBAAA,GAAA,MAAA,YAAA,CAA+B,OAAO,SAAgC;IAC1E,iBAAiB,IAAI;IACrB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,WAAW,IAAI;KACxC,oBAAoB;MAAE,MAAM,OAAO;MAAM,KAAK,OAAO;MAAK,QAAQ,OAAO;MAAQ,UAAU,IAAI,IAAI,OAAO,MAAM;KAAE,CAAC;KACnH,MAAM,WAAW;IACnB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,iBAAiB,IAAI;IACvB;GACF,GAAG,CAAC,KAAK,UAAU,CAAC;;GAGpB,MAAM,qBAAA,GAAA,MAAA,YAAA,CAAgC,YAA2B;IAC/D,IAAI,qBAAqB,MAAM;IAC/B,MAAM,WAAW,CAAC,GAAG,iBAAiB,QAAQ;IAC9C,YAAY,IAAI;IAChB,aAAa,IAAI;IACjB,IAAI;KACF,IAAI,SAAS,SAAS,GAAG;MACvB,MAAM,SAAS,MAAM,IAAI,WAAW,iBAAiB,MAAM,QAAQ;MACnE,IAAI,OAAO,OAAO,SAAS,GAAG,aAAa,OAAO,OAAO,KAAK,SAAS,KAAK,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;KAClH;KACA,oBAAoB,IAAI;KACxB,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;KACvD,YAAiB;IACnB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,YAAY,KAAK;IACnB;GACF,GAAG;IAAC;IAAK;IAAkB;IAAM;IAAY;IAAa;GAAW,CAAC;;;;;GAMtE,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,YAA2B;IACvD,mBAAmB,KAAK;IACxB,aAAa,IAAI;IACjB,aAAa,IAAI;IACjB,MAAM,WAAqB,CAAC;IAC5B,IAAI,OAAO;IACX,IAAI;KACF,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,WAAW,GAAG;MACvD,IAAI,CAAC,MAAM,WAAW,MAAM,QAAQ,WAAW,GAAG;MAClD,IAAI;OACF,MAAM,SAAS,MAAM,IAAI,WAAW,MAAM,MAAM,OAAO;OACvD,QAAQ;OACR,IAAI,OAAO,OAAO,SAAS,GACzB,SAAS,KAAK,GAAG,wBAAwB;QAAE;QAAM,OAAO,OAAO,OAAO;OAAO,CAAC,IAAI,OAAO,OAAO,OAAO,KAAK,SAAS,KAAK,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;MAElK,SAAS,OAAO;OACd,SAAS,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC;MACjD;KACF;KACA,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;KACvD,MAAM,aAAa;KACnB,YAAiB;KACjB,IAAI,SAAS,SAAS,GAAG,aAAa,SAAS,KAAK,IAAI,CAAC;UACpD,IAAI,OAAO,GAAG,iBAAiB,GAAG,wBAAwB,EAAE,OAAO,KAAK,CAAC,CAAC;IACjF,UAAU;KACR,aAAa,KAAK;IACpB;GACF,GAAG;IAAC;IAAK;IAAa;IAAc;IAAa;IAAM;IAAY;GAAW,CAAC;GAK/E,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,gBAAgB,GAAG;IACxB,gBAAgB;IAChB,YAAiB;IACjB,aAAkB;IAClB,YAAiB;GAEnB,GAAG,CAAC,CAAC;GAIL,MAAM,UAAA,GAAA,MAAA,YAAA,CAAqB,OAAO,UAAoC;IACpE,MAAM,eAAe;IACrB,YAAY,IAAI;IAChB,eAAe,IAAI;IACnB,iBAAiB,IAAI;IACrB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,OAAO;MAAE,MAAM;MAAU,aAAa;MAAU,MAAM;KAAS,CAAC;KAIzF,iBAAiB,GAAG,cAAc,IAAI,OAAO,IAAI;KACjD,YAAY,EAAE;KACd,YAAY,EAAE;KACd,YAAY,KAAK;KACjB,MAAM,KAAK;IACb,SAAS,OAAO;KACd,eAAe;MAAE,MAAM;MAAS,MAAM,GAAG,YAAY,IAAI,aAAa,KAAK;KAAE,CAAC;IAChF,UAAU;KACR,YAAY,KAAK;IACnB;GACF,GAAG;IAAC;IAAK;IAAU;IAAU;IAAU;GAAI,CAAC;GAI5C,MAAM,aAAa,OAAO,KAAK,CAAC,CAAC,kBAAkB;;GAEnD,MAAM,UAAU,aAAa,WAAW,CAAC;;GAEzC,MAAM,iBAAA,GAAA,MAAA,QAAA,OAA8B;IAClC,MAAM,SAAS,SAAS,UAAU,CAAC;IACnC,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,UAAU,QAAQ,MAAM,KAAK,CAAC,CAAC,QAAQ,SAAyB,SAAS,KAAA,CAAS,CAAC,CAAC,CAAC,CAAC,KAAK;IAEjI,MAAM,aAAa,OAAO,MAAM,UAAU,QAAQ,MAAM,UAAU,KAAA,KAAa,CAAC,gBAAgB,MAAM,MAAM,CAAC;IAC7G,OAAO,CAAC,GAAG,OAAO,GAAI,aAAa,CAAC,cAAc,IAAI,CAAC,CAAE;GAC3D,GAAG,CAAC,SAAS,OAAO,CAAC;GACrB,MAAM,YAAA,GAAA,MAAA,QAAA,QAA0B,SAAS,UAAU,CAAC,EAAA,CAAG,QAAQ,UAC7D,WAAW,WAAW,KAAK,MAAM,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,MAAM,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,CAC7I,GAAG,CAAC,SAAS,UAAU,CAAC;GAIxB,OAAO;IAEL;IAAS;IAAS;IAAW;IAAe;IAAa;IAAmB;IAAc;IAAc;IAAe;IACvH;IAAQ;IAAW;IAAQ;IAAe;IAAW;IAAW;IAAU;IAAU;IAAU;IAAU;IAAU;IAClH;IAAM;IAAW;IAAK;IAAW;IAAc;IAAS;IAAa;IAAa;IAAc;IAChG;IAAkB;IAAe;IAAU;IAAe;IAAa;IAAc;IAAa;IAAgB;IAClH;IAAgB;IAAe;IAAmB;IAAmB;IAAiB;IAAY;IAAU;IAAc;IAAY;IACtI;IAAY;IAAiB;IAAoB;IAEjD;IAAa;IAAW;IAAY;IAAS;IAAe;IAAU,SAAA,GAAA,MAAA,QAAA,OAX3C,WAAW,UAAU,UAAU,SAAS,KAAK,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG;KAAC;KAAU;KAAS;IAAI,CAWxC;IAE3E;IAAc;IAAkB;IAAW;IAAc;IAAW;IAAa;IAAa;IAAa;IAAa;IACxH;IAAiB;IAAQ;IACzB;IAAiB;IAAY;IAAiB;IAAqB;IAAkB;IAAmB;IACxG;IAAsB;IAAsB;IAAoB;IAAe;IAAa;IAAiB;IAAe;IAAe;IAC3I;IAAqB;IAAiB;IAAa;IAAY;IAAY;IAAQ;IAAgB;IAAkB;IAAa;IAClI;IAAc;IAAc;IAAa;IAAe;IAAc;IAAY;IAAoB;IAAgB;IACtH;IAAW;IAAS;IAAW;IAAiB;IAAoB;IAAU;IAAqB;IAAoB;IACvH;IAAa;IAAkB;IAAmB;IAAW;GAC/D;EACF;;;;;;;;;;;;;;;;ECvwBA,SAAgB,cAAc,OAA8C;GAC1E,MAAM,MAAM,YAAY,MAAM,GAAG;;GAEjC,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA8B,EAAE;GACvD,MAAM,EACJ,SAAS,SAAS,WAAW,eAAe,aAAa,QAAQ,eAAe,UAAU,UAAU,UACpG,UAAU,UAAU,aAAa,WAAW,KAAK,WAAW,cAAc,SAAS,QACnF,WAAW,cACX,cAAc,SAAS,WAAW,YAAY,SAAS,eAAe,UACtE,gBAAgB,eAAe,mBAAmB,mBAAmB,cAAc,YAAY,kBAC/F,UAAU,YAAY,UAAU,cAAc,YAAY,MAAM,aAAa,aAAa,gBAAgB,eAC1G,YACA,cAAc,kBAAkB,WAAW,aAAa,aAAa,aAAa,aAAa,gBAAgB,QAC/G,cAAc,iBAAiB,YAAY,WAAW,mBAAmB,kBAAkB,sBAC3F,sBAAsB,iBAAiB,qBAAqB,eAAe,aAAa,iBAAiB,eACzG,eACA,aAAa,YAAY,cAAc,aAAa,eAAe,cAAc,YAAY,gBAC7F,cAAc,iBAAiB,qBAAqB,mBAAmB,QAAQ,SAAS,WAAW,mBACjG;GAIJ,IAAI,WAAW,MACb,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;IACU;IACG;IACL;IACO;IACC;IACD;IACG;IACD;IACf,SAAS;IACT,cAAc;KAAE,UAAU,IAAI;IAAE;IAChC,UAAU,SAAS;KAAE,aAAkB,IAAI;IAAE;IAC7C,QAAQ;IACR,gBAAgB;GACjB,CAAA;GAIL,IAAI,eAAe,MACjB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;IACE,KAAK;IACK;IACI;IACF;IACH;IACA;IACT,cAAc;KAAE,cAAc,IAAI;IAAE;IACpC,YAAY;IACZ,cAAc;IACd,iBAAiB,MAAM,YAAY;KACjC,iBAAiB,aAAa;MAC5B,MAAM,OAAO,IAAI,IAAI,QAAQ;MAC7B,IAAI,SAAS,KAAK,IAAI,IAAI;WACrB,KAAK,OAAO,IAAI;MACrB,OAAO;KACT,CAAC;IACH;IACA,gBAAgB;KAAE,QAAa,WAAW,IAAI,UAAU,IAAI;IAAE;IAC9D,gBAAgB;KAAE,UAAe,WAAW,EAAE;IAAE;IAChD,qBAAqB;KAAE,QAAa,WAAW,IAAI,UAAU,CAAC,GAAG,YAAY,CAAC;IAAE;GACjF,CAAA;;GAKL,MAAM,qBAAyC;IAC7C,IAAI,YAAY,WAAW,YAAY,OAAO,GAAG,iBAAiB;IAClE,IAAI,YAAY,WAAW,SAAS,OAAO,GAAG,gBAAgB,EAAE,OAAO,YAAY,QAAQ,CAAC;IAC5F,IAAI,YAAY,WAAW,SAAS;KAClC,MAAM,OAAO,YAAY;KACzB,IAAI,KAAK,UAAU,KAAA,GAAW,OAAO,GAAG,gBAAgB,EAAE,OAAO,KAAK,MAAM,CAAC;KAC7E,IAAI,KAAK,iBAAiB,OAAO,GAAG,oBAAoB;MAAE,SAAS,KAAK,iBAAiB;MAAI,SAAS,KAAK;KAAe,CAAC;KAC3H,IAAI,KAAK,kBAAkB,MAAM,OAAO,GAAG,oBAAoB;KAC/D,OAAO,GAAG,mBAAmB,EAAE,SAAS,KAAK,cAAc,CAAC;IAC9D;GAEF,EAAA,CAAG;GAEH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWE,yBAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAAI,WAAWA,yBAAI;kBAAnB;SAA0B,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;UAAoB,MAAM;UAAI,WAAWA,yBAAI;SAAY,CAAA;SAAC;SAAE,GAAG,aAAa;QAAM;;OAC3G,YAAY,OACT,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACG,GAAG,eAAe,EAAE,OAAO,QAAQ,OAAO,SAAS,QAAQ,SAAS,OAAO,CAAC,GAC5E,QAAQ,SAAS,SAAS,IAAI,QAAQ,GAAG,uBAAuB,EAAE,OAAO,QAAQ,SAAS,OAAO,CAAC,IAAI,IACnG;YACN;OACH,YAAY,QAAQ,CAAC,QAAQ,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAO,GAAG,kBAAkB;OAAQ,CAAA,IAAI;OACtG,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAQ,UAAU,YAAY,WAAW;SAAY,OAAO;SAAa,eAAe;UAAE,YAAiB;SAAE;mBAAI,YAAY,WAAW,aAAa,GAAG,iBAAiB,IAAI,GAAG,cAAc;QAAU,CAAA,GAC5O,YAAY,WAAW,WAAW,YAAY,KAAK,mBAAmB,YAAY,KAAK,QAAQ,OAC5F,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,yBAAI;SAAY,MAAM,YAAY,KAAK;SAAK,QAAO;SAAS,KAAI;mBAAc,GAAG,qBAAqB,EAAE,SAAS,YAAY,KAAK,iBAAiB,GAAG,CAAC;QAAK,CAAA,IAC1K,IACA;;MACH;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,QAAQ,YAAY,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,OAAO,SAAS;UAAE;oBAAI,GAAG,cAAc;SAAU,CAAA;SACnK,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,QAAQ,WAAW,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,OAAO,QAAQ;UAAE;oBAAI,GAAG,aAAa;SAAU,CAAA;SAChK,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,QAAQ,WAAW,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,OAAO,QAAQ;WAAG,WAAgB;UAAE;oBAAI,GAAG,aAAa;SAAU,CAAA;QAC/K;;OACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;SAClC,OAAO;SACP,aAAa,cAAc,KAAK,YAAY,GAAG,4BAA4B;SAC3E,OAAO,GAAG,qBAAqB;SAC/B,WAAW,UAAU;UAAE,kBAAkB,MAAM,OAAO,KAAK;SAAE;SAC7D,YAAY,UAAU;UAAE,IAAI,MAAM,QAAQ,SAAS,aAAc,MAAM,OAA4B,MAAM,KAAK,CAAC;SAAE;QAClH,CAAA,GACA,cAAc,KACX,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,OAAO,GAAG,sBAAsB;SAAG,eAAe;UAAE,aAAa,EAAE;UAAG,kBAAkB,EAAE;SAAE;mBAAG;QAAS,CAAA,IACpJ,IACA;;OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI,gBAAgB,aAAa,MAAMA,yBAAI,qBAAqB;QAAK,eAAe;SAAE,eAAe,UAAU,CAAC,KAAK;QAAE;QAAG,OAAO,GAAG,aAAa;kBAAG;OAAS,CAAA;OAC9L,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;SAAS,eAAe;UAAE,aAAa,UAAU,CAAC,KAAK;SAAE;mBAAI,GAAG,WAAW;QAAU,CAAA;OACzI,CAAA;MACH;;KAEJ,WACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI;MAAM,WAAW,UAAU;OAAE,OAAY,KAAK;MAAE;gBAArE;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;QAAG,WAAWA,yBAAI;kBAAW,GAAG,qBAAqB;OAAK,CAAA;OAC1D,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;mBAAY,GAAG,WAAW;QAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;SAAO,OAAO;SAAU,WAAW,UAAU;UAAE,YAAY,MAAM,OAAO,KAAK;SAAE;SAAG,aAAY;QAAe,CAAA,CAChI;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;mBAAY,GAAG,WAAW;QAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;SAAO,OAAO;SAAU,WAAW,UAAU;UAAE,YAAY,MAAM,OAAO,KAAK;SAAE;SAAG,aAAa,GAAG,sBAAsB;QAAI,CAAA,CAC/I;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;mBAAY,GAAG,WAAW;QAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,WAAWA,yBAAI;SAAQ,OAAO;SAAU,WAAW,UAAU;UAAE,YAAY,MAAM,OAAO,KAAqB;SAAE;mBAAvH,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;oBAAW;SAAqB,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;oBAAc;SAAwB,CAAA,CAC9C;UACL;;OACJ,gBAAgB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAW,YAAY,SAAS,UAAUA,yBAAI,YAAYA,yBAAI;kBAAc,YAAY;OAAU,CAAA,IAAI;OACnI,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;SAAS,UAAU;mBAAW,WAAW,GAAG,WAAW,IAAI,GAAG,aAAa;QAAU,CAAA,GAC7I,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAQ,eAAe;UAAE,YAAY,KAAK;UAAG,eAAe,IAAI;SAAE;mBAAI,GAAG,aAAa;QAAU,CAAA,CAClI;;MACD;UACJ;KAEH,cAAc,OACb,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,UAAgB,CAAA,GACvB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,eAAe;QAAE,aAAa,IAAI;OAAE;iBAAI,GAAG,aAAa;MAAU,CAAA,CAC5G;UACH;KAEH,kBAAkB,OACjB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,cAAoB,CAAA,GAC3B,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,eAAe;QAAE,iBAAiB,IAAI;OAAE;iBAAI,GAAG,aAAa;MAAU,CAAA,CAChH;UACH;KAEH,aACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CAAiC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;SAAU,OAAO,SAAS,WAAW,aAAa;QAAI,CAAA,GAAE,GAAG,cAAc,CAAQ;;OACvJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CAAiC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;SAAS,OAAO,SAAS,WAAW,YAAY;QAAI,CAAA,GAAE,GAAG,aAAa,CAAQ;;OACpJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAa,GAAG,aAAa;OAAQ,CAAA;MACvD;UACH;KAEH,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,eAAe;KAAO,CAAA,IAAI;KAEnE,gBAAgB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,gBAAgB;KAAO,CAAA,IAAI;KAE1E,QAAQ,WACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD,EAAiB,IAAM,CAAA,IACrB,YAAY,OACd,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB;QACG,QAAQ,YACP,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,cAAc,SAAS,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,aAAa,MAAM;UAAE;oBAAI,GAAG,WAAW;SAAU,CAAA,GACtK,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,cAAc,WAAW,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,aAAa,QAAQ;UAAE;oBAAI,GAAG,cAAc;SAAU,CAAA,CACzK;YACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,WAAWA,yBAAI;SAAQ,OAAO;SAAc,WAAW,UAAU;UAAE,gBAAgB,MAAM,OAAO,KAAK;SAAE;mBAA/G,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;oBAAO,GAAG,mBAAmB;SAAU,CAAA,GACpD,cAAc,KAAK,WAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAqB,OAAO;oBAAS,WAAA,YAA4B,GAAG,gBAAgB,IAAI;SAAe,GAA1F,MAA0F,CACxG,CACK;UACR,EAAA,CAAA,IACA;QACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,WAAWA,yBAAI;SAAQ,OAAO;SAAS,WAAW,UAAU;UAAE,WAAW,MAAM,OAAO,KAAgB;SAAE;mBAAhH;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAQ,GAAG,WAAW;UAAU,CAAA;UAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAS,GAAG,YAAY;UAAU,CAAA;UAChD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAQ,GAAG,WAAW;UAAU,CAAA;SACxC;;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;SAAQ,OAAO;SAAQ,WAAW,UAAU;UAAE,UAAU,MAAM,OAAO,KAAK;SAAE;SAAG,aAAa,GAAG,cAAc;QAAI,CAAA;OACpI;;MAEJ,SAAS,WAAW,KAAK,OAAO,KAAK,MAAM,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,aAAa;MAAO,CAAA,IAAI;MACvG,SAAS,WAAW,KAAK,OAAO,KAAK,MAAM,MAAM,QAAQ,OAAO,WAAW,KAAK,QAAQ,SAAS,WAAW,KAAK,QAAQ,YAAY,WAAW,IAC7I,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,gBAAgB;MAAO,CAAA,IACtD;MAEH,QAAQ,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD,EAAkB,IAAM,CAAA,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD,EAAiB,IAAM,CAAA;MAEvE,iBAAiB,QAAQ,aAAa,MAAM,SAAS,IACpD,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,yBAAI;iBAAxB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI,eAAe,MAAMA,yBAAI;kBAA7C,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAAmB,GAAG,cAAc;QAAQ,CAAA,GACjE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;SAAU,UAAU;SAAS,eAAe;UAAE,qBAAqB,IAAI;SAAE;mBAAI,GAAG,mBAAmB;QAAU,CAAA,CACjK;WACJ,aAAa,MAAM,KAAK,UACvB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAsB,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;kBAArD,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;oBAAU,MAAM;SAAU,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;oBAAU,iBAAiB,MAAM,OAAO;SAAO,CAAA,CAChE;YACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,UAAU;SAAS,eAAe;UAAE,aAAkB,MAAM,IAAI;SAAE;mBAAI,GAAG,gBAAgB;QAAU,CAAA,CAC5I;UANK,MAAM,IAMX,CACN,CACM;WACP;MAEH,QAAQ,SAAS,SAAS,IACzB,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,yBAAI;iBAAxB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAAe,GAAG,gBAAgB;OAAO,CAAA,GAC5D,QAAQ,SACN,QAAQ,YACN,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,OAC1I,iBAAiB,UAAU,QAAQ,OAAO,SAAA,eAA6B,aAAa,CAAC,CAC1F,KAAK,WACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;QAAuC;QAAQ,MAAM,UAAU,IAAI,OAAO,IAAI;QAAG,gBAAgB;SAAE,eAAoB,MAAM;QAAE;OAAI,GAAjH,OAAO,IAA0G,CACpI,CACI;WACP;MAEH,QAAQ,YAAY,SAAS,IAC5B,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,yBAAI;iBAAxB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAAe,GAAG,mBAAmB;OAAO,CAAA,GAC/D,QAAQ,YAAY,KAAK,UACxB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAsB,WAAWA,yBAAI;kBAArC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAW,MAAM;QAAU,CAAA,GAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAa,MAAM;QAAY,CAAA,CAChD;UAHK,MAAM,IAGX,CACN,CACM;WACP;KACJ,EAAA,CAAA,IACA;KAEH,mBAAmB,OAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD;MACE,QAAQ;MACR,MAAM,aAAa,QAAQ,CAAC;MAC5B,aAAa,aAAa,eAAe,CAAC;MAC1C,eAAe;OAAE,kBAAkB,IAAI;MAAE;MACzC,gBAAgB;OAAE,gBAAqB,KAAK;MAAE;MAC9C,kBAAkB;OAAE,gBAAqB,IAAI;MAAE;KAChD,CAAA,IACC;KAEH,kBAAkB,OACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,cAAc,SAAS,SAAS,GAAG,yBAAyB,IAAI,GAAG,2BAA2B;MACrG,MAAM,cAAc,SAAS,SAAS,GAAG,wBAAwB,IAAI,GAAG,0BAA0B;MAClG,OAAO,cAAc;MACrB,cAAc,cAAc,SAAS,SAAS,GAAG,aAAa,IAAI,GAAG,qBAAqB;MAC1F,QAAQ,cAAc,SAAS;MAC/B,gBAAgB;OAAE,iBAAiB,IAAI;MAAE;MACzC,iBAAiB;OAAE,aAAkB;MAAE;KACxC,CAAA,IACC;KAEH,iBAAiB,OAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;MACE,QAAQ;MACR,MAAM;MACN,WAAW,aAAa;OAAE,gBAAgB;QAAE,GAAG;QAAc;OAAS,CAAC;MAAE;MACzE,gBAAgB;OAAE,gBAAgB,IAAI;MAAE;MACxC,iBAAiB;OAAE,oBAAyB;MAAE;KAC/C,CAAA,IACC;KAEH,qBAAqB,OACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD;MACE,QAAQ;MACR,MAAM;MACN,WAAW,MAAM,YAAY;OAC3B,MAAM,OAAO,IAAI,IAAI,iBAAiB,QAAQ;OAC9C,IAAI,SAAS,KAAK,IAAI,IAAI;YACrB,KAAK,OAAO,IAAI;OACrB,oBAAoB;QAAE,GAAG;QAAkB,UAAU;OAAK,CAAC;MAC7D;MACA,gBAAgB;OAAE,oBAAoB,IAAI;MAAE;MAC5C,iBAAiB;OAAE,kBAAuB;MAAE;KAC7C,CAAA,IACC;KAEH,sBAAsB,OACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,GAAG,qBAAqB;MAC/B,MAAM,GAAG,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;MAC1D,cAAc,GAAG,gBAAgB;MACjC,QAAA;MACA,gBAAgB;OAAE,qBAAqB,IAAI;MAAE;MAC7C,iBAAiB;OAAE,eAAoB;MAAE;KAC1C,CAAA,IACC;KAEH,oBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,GAAG,+BAA+B;MACzC,MAAM,GAAG,8BAA8B;MACvC,cAAc,GAAG,0BAA0B;MAC3C,QAAA;MACA,gBAAgB;OAAE,qBAAqB,KAAK;MAAE;MAC9C,iBAAiB;OAAE,WAAgB;MAAE;KACtC,CAAA,IACC;IACD;;EAET;;;;EC/TA,MAAM,KAAK;;;;;;;;EAgBX,MAAa,SAAS;GAAC;GAAS;GAAU;GAAc;GAAU;GAAiB;EAAe;;;;;EAWlG,SAAgB,MAAM,KAA0B;GAC9C,IAAI,aAAa,IAAI,OAAO,SAAS,IAAI;IAAE;IAAI;GAAG,CAAC,GAAG,6BAA6B;GACnF,MAAM,IAAI,IAAI,OAAO,KAAK,EAAE;GAC5B,MAAM,MAAM,IAAI,YAAY;GAM5B,MAAM,eAAe,IAAI,+BACvB,IAAI,cAAc,KAAuB,EAAE,WAAW,GAAG,CAAC,CAC5D;GAMA,IAAI,aACI,oBAAoB,KAAK,KAAK,IAAI,cAAc,KAAuB,EAAE,WAAW,GAAG,CAAC,CAAC,GAC/F,2BACF;GAKA,IAAI,aACI,IAAI,MAAM,OAAO,8BAA8B,IAAI,MAAM,SAAS;IACtE,MAAM;IACN,KAAK;IACL,QAAQ;IACR,cAAc,aAAa,OAAO;GACpC,GAAG,oBAAoB,CAAC,GACxB,8BACF;GAGA,IAAI,aACI,IAAI,MAAM,OAAO,0BAA0B,IAAI,MAAM,SAAS;IAClE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,aAAa,EAAE,aAAa;IAC5B,QAAQ;IACR,eAAe,CAAC;GAClB,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD,EAAoB,IAAM,CAAA,CAAC,CAAC,GACrC,iCACF;GAGA,IAAI,aAAa,qBAAqB,GAAG,kCAAkC;EAC7E"}