dsh-subscriptions 0.1.5 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +212 -154
  2. package/lib/auth/claude-code-creds.js +31 -9
  3. package/lib/auth/device-flow.js +16 -9
  4. package/lib/auth/oauth-flow.js +13 -10
  5. package/lib/auth/rpc.d.ts +73 -2
  6. package/lib/auth/rpc.js +124 -23
  7. package/lib/auth/store.js +80 -31
  8. package/lib/client/CursorCard.d.ts +1 -1
  9. package/lib/client/CursorCard.js +50 -16
  10. package/lib/client/ExternalUsageCards.d.ts +1 -1
  11. package/lib/client/ExternalUsageCards.js +37 -16
  12. package/lib/client/ImageGallery.d.ts +2 -2
  13. package/lib/client/ImageGallery.js +92 -33
  14. package/lib/client/ImageGenerateToolview.js +50 -14
  15. package/lib/client/OllamaCard.d.ts +13 -0
  16. package/lib/client/OllamaCard.js +94 -0
  17. package/lib/client/OllamaSettingsManager.d.ts +24 -0
  18. package/lib/client/OllamaSettingsManager.js +329 -0
  19. package/lib/client/ProviderAccountManager.d.ts +1 -1
  20. package/lib/client/ProviderAccountManager.js +164 -49
  21. package/lib/client/ProviderModelEditor.js +109 -26
  22. package/lib/client/SpeedSelect.d.ts +62 -14
  23. package/lib/client/SpeedSelect.js +257 -46
  24. package/lib/client/SubscriptionUsageBadge.d.ts +5 -11
  25. package/lib/client/SubscriptionUsageBadge.js +301 -112
  26. package/lib/client/SubscriptionsSection.d.ts +2 -0
  27. package/lib/client/SubscriptionsSection.js +259 -85
  28. package/lib/client/UsageBadgeDisplaySetting.js +35 -12
  29. package/lib/client/UsageMeter.d.ts +1 -1
  30. package/lib/client/UsageMeter.js +69 -27
  31. package/lib/client/VideoGenerateToolview.js +69 -17
  32. package/lib/client/account-preferences.d.ts +8 -0
  33. package/lib/client/account-preferences.js +20 -5
  34. package/lib/client/host-contract.d.ts +11 -2
  35. package/lib/client/host-contract.js +20 -3
  36. package/lib/client/index.d.ts +5 -5
  37. package/lib/client/index.js +34 -12
  38. package/lib/client/locales.d.ts +78 -0
  39. package/lib/client/locales.js +121 -34
  40. package/lib/client/ollama-draft.d.ts +229 -0
  41. package/lib/client/ollama-draft.js +255 -0
  42. package/lib/client/reset-action.js +6 -4
  43. package/lib/client/reset-credits-view.d.ts +1 -1
  44. package/lib/client/reset-credits-view.js +66 -17
  45. package/lib/client/subscription-card-styles.js +94 -24
  46. package/lib/client/usage-color-preferences.js +4 -2
  47. package/lib/client/usage-pace.d.ts +7 -0
  48. package/lib/client/usage-pace.js +43 -10
  49. package/lib/client.js +1647 -266
  50. package/lib/client.js.map +1 -1
  51. package/lib/http.js +1 -1
  52. package/lib/index.d.ts +28 -3
  53. package/lib/index.js +9329 -8217
  54. package/lib/model-defaults.js +4 -2
  55. package/lib/provider-settings.d.ts +14 -1
  56. package/lib/provider-settings.js +64 -20
  57. package/lib/providers/account-preferences.js +51 -22
  58. package/lib/providers/accounts.js +15 -9
  59. package/lib/providers/antigravity-oauth-client.js +2 -2
  60. package/lib/providers/antigravity.js +141 -68
  61. package/lib/providers/catalog-store.js +120 -41
  62. package/lib/providers/claude-cli-version.js +3 -3
  63. package/lib/providers/claude.d.ts +23 -3
  64. package/lib/providers/claude.js +167 -92
  65. package/lib/providers/codex-client-version.js +3 -3
  66. package/lib/providers/codex-search.js +40 -13
  67. package/lib/providers/codex.js +196 -112
  68. package/lib/providers/common.d.ts +14 -0
  69. package/lib/providers/common.js +118 -38
  70. package/lib/providers/copilot.js +143 -82
  71. package/lib/providers/cursor-adapter.js +42 -18
  72. package/lib/providers/cursor-auth.d.ts +1 -1
  73. package/lib/providers/cursor-auth.js +69 -24
  74. package/lib/providers/cursor-model-settings.js +14 -5
  75. package/lib/providers/cursor-usage.js +27 -13
  76. package/lib/providers/external-usage-controller.d.ts +9 -2
  77. package/lib/providers/external-usage-controller.js +30 -7
  78. package/lib/providers/external-usage.d.ts +8 -0
  79. package/lib/providers/external-usage.js +140 -20
  80. package/lib/providers/grok.js +152 -89
  81. package/lib/providers/image-pool.js +29 -11
  82. package/lib/providers/minimax-usage.js +31 -11
  83. package/lib/providers/npm-cli-version.js +10 -3
  84. package/lib/providers/ollama-settings.d.ts +90 -0
  85. package/lib/providers/ollama-settings.js +213 -0
  86. package/lib/providers/ollama-web.d.ts +46 -0
  87. package/lib/providers/ollama-web.js +231 -0
  88. package/lib/providers/ollama.d.ts +107 -0
  89. package/lib/providers/ollama.js +608 -0
  90. package/lib/providers/pool-family.js +11 -3
  91. package/lib/providers/pool-health.js +28 -8
  92. package/lib/providers/pool-usage.js +16 -9
  93. package/lib/providers/pool.d.ts +8 -0
  94. package/lib/providers/pool.js +81 -42
  95. package/lib/providers/rate-limit.js +8 -2
  96. package/lib/providers/replay.js +40 -17
  97. package/lib/providers/reset-redemption.js +18 -6
  98. package/lib/tools/image-generate.js +123 -65
  99. package/lib/tools/registration.js +5 -2
  100. package/lib/tools/video-generate.js +51 -31
  101. package/lib/tools/x-search.js +50 -22
  102. package/lib/translate/anthropic.js +85 -37
  103. package/lib/translate/antigravity-schema.js +71 -28
  104. package/lib/translate/antigravity-thinking.js +22 -9
  105. package/lib/translate/antigravity.js +141 -50
  106. package/lib/translate/chat-completions.js +67 -23
  107. package/lib/translate/resolved.js +55 -21
  108. package/lib/translate/responses.js +69 -29
  109. package/lib/translate/sse.js +4 -1
  110. package/package.json +26 -4
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["result: RpcResult<unknown>","border","actions: CSSProperties","ProviderModelEditor","error","windows: Record<string, number>","actions","stack: CSSProperties","actions: CSSProperties","error","message","subscriptionCardStyles: Record<string, CSSProperties>","window","UNIT_KEYS: Record<CountdownPart['unit'], [SubscriptionsKey, SubscriptionsKey]>","SOURCES: readonly { id: Source; name: string; ref: string }[]","window","styles","styles","window","STATE_KEYS: Record<ResetCreditState, SubscriptionsKey>","cardStyles","message","styles","styles: Record<string, CSSProperties>","POLL_INTERVAL_MS","CLIENT_VERSION_SOURCES: Record<ClientVersionSource, SubscriptionsKey>","PROVIDERS: readonly { id: SubscriptionProvider; name: string }[]","fallbackTranslate","text: string","styles: Record<string, CSSProperties>","cardStyles","usageWindowLabel","window","message","response: StatusResponse","styles","styles: Record<string, CSSProperties>","styles","NoIcon: ComponentType<IconProps>","exports","SparkleIcon","primitives","PROMPT_MAX_LENGTH","fallbackTranslate","text: string","derivePrompt","parsed: unknown","prompt: string | undefined","resultText","parts: string[]","images: { attachment: ImageAttachmentRef }[]","styles: Record<string, CSSProperties>","labels: MessageImageLabels","styles","primitives","fallbackTranslate","text: string","parsed: unknown","prompt: string | undefined","parts: string[]","styles: Record<string, CSSProperties>","objectUrl: string | undefined","styles","fallbackTranslate","TIERS: readonly SpeedTier[]","styles","styles: Record<string, CSSProperties>","primitives","PROVIDER_NAMES: Record<BadgeProvider, string>","row: AccountUsageDisplay","roster: UsageRosterEntry[]","parts","window","translate: Translate","seat","node: HTMLElement | null","MEASURE_STYLE: CSSProperties","styles: Record<string, CSSProperties>"],"sources":["../src/client/locales.ts","../src/client/reset-action.ts","../src/client/subscriptions-rpc.ts","../src/client/account-preferences.ts","../src/client/ProviderModelEditor.tsx","../src/client/provider-settings-styles.ts","../src/client/ProviderAccountManager.tsx","../src/client/subscription-card-styles.ts","../src/client/usage-badge-preferences.ts","../src/client/usage-pace.ts","../src/client/usage-color-preferences.ts","../src/client/UsageMeter.tsx","../src/client/ExternalUsageCards.tsx","../src/client/CursorCard.tsx","../src/client/reset-credits-view.tsx","../src/client/UsageBadgeDisplaySetting.tsx","../src/client/SubscriptionsSection.tsx","../src/client/ImageGallery.tsx","../src/client/host-contract.ts","../src/client/host-icons.ts","../src/client/ImageGenerateToolview.tsx","../src/client/VideoGenerateToolview.tsx","../src/client/SpeedSelect.tsx","../src/client/SubscriptionUsageBadge.tsx","../src/client/fast-command.ts","../src/client/index.ts"],"sourcesContent":["/** Copy dictionaries for the Subscriptions settings section. */\n\n/** English strings (the key-set source of truth for this pair). */\nexport const en = {\n accountsManage: 'Manage',\n accountsTitle: 'Manage {provider} accounts',\n accountsHint: 'Choose which accounts serve pooled LLM requests. Pool exclusion applies only to LLM routing, not tools or session-wide isolation.',\n accountsLoading: 'Loading accounts…',\n accountsLoadFailed: 'Could not load account settings: {message}',\n accountsSaveFailed: 'Could not save changes: {message}',\n accountsEmpty: 'No connected accounts. Add an account on the provider card first.',\n accountsAlias: 'Alias (optional)',\n accountsPoolEnabled: 'Include in the LLM account pool',\n accountsIndependent: 'Show an independent entry in the model picker',\n accountsIndependentHint: 'Independent LLM routes use only this account, with no fallback to another account. This does not isolate tools or the whole session.',\n accountsModels: 'Pool model allowlist',\n accountsModelsAll: 'All models',\n accountsModelsCount: '{count} selected',\n accountsModelsHint: 'Applies only to pooled LLM routing, not independent entries. An empty selection allows no models. Turning off pool participation keeps this selection for later.',\n accountsModelsAutomatic: 'Allow all models, including future models',\n accountsNoModels: 'No models reported for this account.',\n accountsCatalogUnavailable: 'Model discovery is currently unavailable. Saved model selections are preserved.',\n modelsPartialSave: 'Some reasoning defaults were saved. Remaining changes are still in the draft; retry to finish.',\n modelsEdit: \"Edit model list\",\n modelsHint: \"Configure model visibility, default reasoning effort, context and tools here; Save changes below submits them together with the account settings. Hidden models remain usable by existing sessions; tool changes apply to new sessions.\",\n modelsAutomatic: \"Automatically show all models, including new models\",\n modelsSelectAll: \"Select all\",\n modelsSelectNone: \"Clear selection\",\n modelsContext: \"Context (tokens)\",\n modelsContextBounds: \"Default {default} · Maximum {max}\",\n modelsContextHint: \"Leave blank to follow the provider. The requested window is capped by the account’s advertised maximum; account pools use the smallest member window. This controls local history and compaction, not the API’s capacity.\",\n modelsContextInvalid: \"Enter a positive whole number of tokens for {model}.\",\n modelsTools: \"Provider tools\",\n modelsToolsHint: \"Changes apply only to sessions created after saving. Existing sessions keep their tools. Shared tools remain available if any supporting provider is enabled.\",\n modelsImage: \"Image generation\",\n modelsVideo: \"Video generation\",\n modelsSearch: \"X search\",\n modelsWebSearch: \"Web search\",\n modelsSave: \"Save changes\",\n modelsUnavailable: \"Currently unavailable\",\n\n nav: 'Subscriptions',\n intro: 'Log a subscription provider in or out. Login opens the provider’s authorization page in a new tab; headless setups can paste the callback URL or code instead.',\n unavailable: 'Connection unavailable; subscription status cannot be loaded.',\n checking: 'Checking…',\n loginInProgress: 'Login in progress…',\n notLoggedIn: 'Not logged in',\n loggedInCount: '{count} account(s) connected',\n clientVersion: 'CLI {version} · {source}',\n clientVersionNpm: 'latest on npm',\n clientVersionLocal: 'local CLI',\n clientVersionFallback: 'built-in',\n clientVersionConfig: 'configured',\n clientVersionHint: 'Requests present this CLI version, and newer models may require a recent one. It is the latest release on npm, or the local CLI / built-in version while npm is unreachable. Refreshing the model list checks again.',\n accountExpires: 'expires {date}',\n defaultBadge: 'Default',\n setDefault: 'Set as default',\n addAccount: 'Add account',\n addAccountOAuth: 'Browser authorization',\n addAccountKeychain: 'Import Claude Code',\n addAccountHint: 'Browser authorization signs in whichever account the browser currently uses — switch accounts there first (or use an incognito window with the manual code below) to add a different one.',\n login: 'Log in',\n cancel: 'Cancel',\n logout: 'Log out',\n logoutAccountConfirm: 'Log out {account} of {provider}?',\n manualSummary: 'Browser flow not working? Paste the callback URL or code',\n manualPlaceholder: 'Paste the callback URL or code',\n submit: 'Submit',\n loginMissingUrl: 'login answered without an authorizeUrl',\n deviceCodePrompt: 'Enter this code on the GitHub verification page:',\n deviceCodeCopy: 'Copy code',\n deviceCodeCopied: 'Copied',\n deviceCodeOpenPage: 'Open GitHub verification page',\n usageTitle: 'Usage',\n usageRefresh: 'Refresh',\n usageLoading: 'Loading usage…',\n usageEmpty: 'No usage windows reported.',\n usageError: 'Usage lookup failed: {message}',\n usageSession: '5-hour window',\n usageWeekly: 'Weekly',\n usageMonthly: 'Monthly',\n usageWindow: 'Window',\n usageResets: 'resets {date}',\n usageMeterUsed: 'Used {used}% · Remaining {remaining}%',\n usageMeterPace: 'Time elapsed {elapsed}% (vertical marker)',\n usageMeterPaceAhead: '{points} points ahead of pace',\n usageMeterPaceBehind: '{points} points behind pace',\n usageMeterPaceEven: 'On pace',\n usageMeterInvalid: 'Quota unavailable',\n usageMeterStale: 'Reading is stale or unavailable; refresh to confirm',\n usageMeterNearLimit: 'Near exhaustion',\n usageMeterAhead: 'Usage ahead of pace',\n usageMeterNoWarning: 'No quota warning',\n usageMeterUnknownTime: 'Time progress unknown',\n usageMeterReset: 'Resets in {duration}',\n usageUnitDay: '{count} day',\n usageUnitDays: '{count} days',\n usageUnitHour: '{count} hour',\n usageUnitHours: '{count} hours',\n usageUnitMinute: '{count} minute',\n usageUnitMinutes: '{count} minutes',\n usageColorLabel: 'Usage coloring',\n usageColorStandard: 'Standard (default · 10-point lead)',\n usageColorRelaxed: 'Relaxed (15-point lead)',\n usageColorRemaining: 'Remaining quota only (no yellow)',\n usageColorPaceHint: 'Yellow when usage leads elapsed time by {allowance} points; red at 90% used takes priority. Saved in this browser; only colors change.',\n usageColorRemainingHint: 'Red at 90% used; no yellow pace warnings. Reliable time markers remain visible. Saved in this browser.',\n usagePlan: 'Plan: {plan}',\n resetCreditsTitle: 'Usage limit resets',\n resetCreditsAvailable: '{count} available',\n resetCreditsError: 'Usage limit resets unavailable: {message}',\n resetCreditsErrorFixed: 'Usage limit resets are unavailable. Refresh usage to try again.',\n resetCreditReadOnly: 'Read only. This page cannot spend a Claude reset.',\n resetCreditReadOnlyLabel: 'Read only',\n resetCreditAvailable: 'Available',\n resetCreditNotUsable: 'Not yet usable',\n resetCreditPaused: 'Paused',\n resetCreditExhausted: 'Exhausted',\n resetCreditExpired: 'Expired',\n resetCreditRemaining: '{left} of {total} left',\n resetCreditLeft: '{left} left',\n resetCreditRemainingUnknown: 'Remaining count unavailable',\n resetCreditCooldownUntil: 'Usable after {date}',\n resetUseButton: 'Use…',\n resetUseChecking: 'Checking…',\n resetUseGuard: 'You can use this reset when weekly usage reaches at least 80%.',\n resetUseRestart: 'Reset details are missing. Restart DSH, reload this page, then refresh usage.',\n resetUseRefresh: 'Refresh usage to verify current limits and reset availability.',\n resetUseReady: 'Use this reset — the earliest-expiring credit. Confirmation required.',\n resetUseConfirmTitle: 'Confirm full reset',\n resetUseWarning: 'This consumes one credit and resets weekly + 5-hour limits. This interface cannot undo it. Confirmation expires in 60 seconds.',\n resetUseAcknowledge: 'I understand that one credit will be consumed.',\n resetUseConfirm: 'Consume 1 reset',\n resetUseSuccess: 'Reset confirmed. Usage refreshed.',\n resetCreditFull: 'Full reset',\n resetCreditExpires: 'Expires {date}',\n resetCreditExpiryUnknown: 'Expiry date unavailable',\n externalUsageTitle: 'Built-in provider usage',\n externalUsageConnected: 'API key configured',\n externalUsageNotConfigured: 'Not configured',\n externalUsageApiKey: 'API key',\n externalUsageConfigure: 'No API key found at {ref}. Add one in Settings → Models.',\n externalUsageUnavailable: 'Usage status unavailable: {message}',\n cursorTitle: 'Cursor',\n cursorOpenLogin: 'Open Cursor sign-in',\n cursorWaiting: 'Waiting for Cursor sign-in…',\n cursorConnected: 'Connected',\n cursorManageTitle: 'Manage Cursor',\n cursorManageSignIn: 'Sign in to see the models available to this Cursor account.',\n cursorAccountsHint: 'Cursor uses one connected account. Choose which of its models appear in the model picker.',\n cursorManageHint: 'Choose model visibility here. Refresh fetches the current models from Cursor; Save changes updates the model picker.',\n cursorFilterModels: 'Filter models',\n cursorModelsLoading: 'Loading Cursor models…',\n cursorModelsError: 'Could not load Cursor models: {message}',\n cursorModelsCount: '{count} models available',\n cursorIncluded: 'Included usage',\n cursorModels: 'Cursor Models',\n cursorOtherModels: 'Other Models',\n cursorIncludedRequests: 'Included requests',\n modelDefaultsTitle: 'Default reasoning effort',\n modelDefaultsHint: 'The model picker preselects this level when you switch to the model; models without levels always follow the provider.',\n modelDefaultsFollowProvider: 'Follow provider',\n modelDefaultsNoLevels: '{count} model(s) advertise no reasoning levels and always follow the provider.',\n modelDefaultsLoading: 'Loading models…',\n modelDefaultsLoadFailed: 'Failed to load models: {message}',\n modelDefaultsRetry: 'Retry',\n modelDefaultsRefresh: 'Refresh model lists (all subscriptions)',\n modelDefaultsSaving: 'Saving…',\n modelDefaultsSaveFailedNamed: 'Save failed for {model}: {message}',\n modelDefaultsSummary: '{total} model(s) · {configured} overridden',\n modelDefaultsSummaryNone: '{total} model(s) · following the provider',\n modelDefaultsSummaryEmpty: 'No model advertises reasoning levels',\n modelDefaultsFilterPlaceholder: 'Filter models',\n modelDefaultsFilterEmpty: 'No model matches “{query}”.',\n generating: 'Generating image…',\n image: 'image',\n viewImage: 'View image',\n viewImageNamed: 'View {name}',\n imageLoading: 'Loading…',\n imageLoadFailed: 'Retry',\n imagePreview: 'Image preview',\n imageClose: 'Close',\n generatingVideo: 'Generating video…',\n videoLoading: 'Loading video…',\n videoLoadFailed: 'Video failed to load: {message}',\n usageBadgeTitle: 'Provider usage',\n usageBadgeDisplay: 'Status-bar quota display',\n usageBadgeDisplayRecent: 'Current / most recent provider with usage',\n usageBadgeDisplayAlways: 'Always show one provider, rotating through the rest',\n usageBadgeDisplayHidden: 'Hidden',\n usageBadgeDisplayHint: 'Saved automatically in this browser. One provider is shown at a time. Models without a quota source keep the most recent provider selected in this view, or show nothing. Always show instead rotates through the providers with usage every 10 seconds while the current model has no quota source. Hiding does not affect usage details here.',\n usageBadgeDisplaySaveFailed: 'Could not save the display preference. Check browser storage permissions.',\n usageBadgeCurrent: 'current',\n usageBadgeModelCount: '{count} model quotas',\n usageBadgeModelUnavailable: 'Current model quota unavailable',\n usageBadgeMoreWindows: 'More quota windows ({count})',\n speed: 'Speed',\n speedStandard: 'Standard',\n speedStandardDescription: 'Default speed',\n speedFast: 'Fast',\n speedFastDescription: '1.5x speed, more usage',\n commandFast: 'Switch the Codex speed tier (Standard/Fast)',\n commandFastUnavailable: 'The current model has no fast tier; /fast only works on Codex models whose catalog advertises one',\n} satisfies Record<string, string>\n\n/** zh strings, one per {@link en} key. */\nexport const zh = {\n accountsManage: '管理',\n accountsTitle: '管理 {provider} 账号',\n accountsHint: '选择参与账号池 LLM 请求的账号。退出账号池仅影响 LLM 路由,不影响工具,也不代表整个会话隔离。',\n accountsLoading: '加载账号中…',\n accountsLoadFailed: '账号设置加载失败:{message}',\n accountsSaveFailed: '保存失败:{message}',\n accountsEmpty: '暂无已连接账号,请先在服务商卡片中添加账号。',\n accountsAlias: '别名(可选)',\n accountsPoolEnabled: '参与 LLM 账号池',\n accountsIndependent: '在模型选择器中显示独立入口',\n accountsIndependentHint: '独立 LLM 路由仅使用此账号,失败时不会回退到其他账号。这不代表工具或整个会话的隔离。',\n accountsModels: '账号池模型白名单',\n accountsModelsAll: '全部模型',\n accountsModelsCount: '已选 {count} 个',\n accountsModelsHint: '仅影响账号池 LLM 路由,不限制独立入口。清空选择表示不允许任何模型。关闭参与账号池后仍保留此选择。',\n accountsModelsAutomatic: '允许全部模型(包含以后新增的模型)',\n accountsNoModels: '此账号暂未返回模型。',\n accountsCatalogUnavailable: '暂时无法获取模型目录,已保存的模型选择会被保留。',\n modelsPartialSave: '部分推理档已保存,其余更改仍保留在草稿中,请重试完成保存。',\n modelsEdit: \"编辑模型列表\",\n modelsHint: \"在此配置模型显示、默认推理档、上下文与工具,底部的「保存更改」会连同账号设置一起提交。隐藏模型不影响已有会话;工具开关对新建会话生效。\",\n modelsAutomatic: \"自动显示全部模型(包含以后新增的模型)\",\n modelsSelectAll: \"全选\",\n modelsSelectNone: \"清空选择\",\n modelsContext: \"上下文(token)\",\n modelsContextBounds: \"默认 {default} · 最大 {max}\",\n modelsContextHint: \"留空跟随服务商。配置值按账号返回的最大窗口限制;账号池取各成员的最小窗口。此设置控制本地历史保留和压缩时机,不会扩大 API 本身的容量。\",\n modelsContextInvalid: \"请为 {model} 输入正整数 token 数。\",\n modelsTools: \"Provider 工具\",\n modelsToolsHint: \"仅对保存后新建的会话生效,已有会话保留原工具。任一支持的服务商启用共享工具时,该工具仍会显示。\",\n modelsImage: \"图片生成\",\n modelsVideo: \"视频生成\",\n modelsSearch: \"X 搜索\",\n modelsWebSearch: \"网页搜索\",\n modelsSave: \"保存更改\",\n modelsUnavailable: \"当前不可用\",\n\n nav: '订阅',\n intro: '在此登录或退出订阅服务商。点击登录会在新标签页打开服务商的授权页面;无浏览器环境可改为粘贴回调 URL 或授权码。',\n unavailable: '连接不可用,无法加载订阅状态。',\n checking: '查询中…',\n loginInProgress: '登录中…',\n notLoggedIn: '未登录',\n loggedInCount: '已连接 {count} 个账号',\n clientVersion: 'CLI {version} · {source}',\n clientVersionNpm: 'npm 最新',\n clientVersionLocal: '本机 CLI',\n clientVersionFallback: '内置版本',\n clientVersionConfig: '手动配置',\n clientVersionHint: '请求以这个 CLI 版本号发出,新模型可能要求较新的版本。默认使用 npm 上的最新版本;npm 无法访问时使用本机 CLI 或内置版本。刷新模型列表会重新检查。',\n accountExpires: '过期时间 {date}',\n defaultBadge: '默认',\n setDefault: '设为默认',\n addAccount: '添加账号',\n addAccountOAuth: '浏览器授权',\n addAccountKeychain: '导入 Claude Code',\n addAccountHint: '浏览器授权以浏览器当前登录的账号为准;要添加不同账号,请先在浏览器里切换账号,或用无痕窗口走下方手动授权码。',\n login: '登录',\n cancel: '取消',\n logout: '退出登录',\n logoutAccountConfirm: '确定退出 {provider} 的账号 {account} 吗?',\n manualSummary: '浏览器流程无法完成?粘贴回调 URL 或授权码',\n manualPlaceholder: '粘贴回调 URL 或授权码',\n submit: '提交',\n loginMissingUrl: 'login 响应缺少 authorizeUrl',\n deviceCodePrompt: '在 GitHub 验证页面输入此验证码:',\n deviceCodeCopy: '复制验证码',\n deviceCodeCopied: '已复制',\n deviceCodeOpenPage: '打开 GitHub 验证页面',\n usageTitle: '用量',\n usageRefresh: '刷新',\n usageLoading: '用量加载中…',\n usageEmpty: '服务商未返回任何用量窗口。',\n usageError: '用量查询失败:{message}',\n usageSession: '5 小时窗口',\n usageWeekly: '每周',\n usageMonthly: '每月',\n usageWindow: '窗口',\n usageResets: '{date} 重置',\n usageMeterUsed: '已用 {used}% · 剩余 {remaining}%',\n usageMeterPace: '时间已过 {elapsed}%(竖线标记)',\n usageMeterPaceAhead: '领先时间进度 {points} 个百分点',\n usageMeterPaceBehind: '落后时间进度 {points} 个百分点',\n usageMeterPaceEven: '与时间进度一致',\n usageMeterInvalid: '额度数据不可用',\n usageMeterStale: '读数已陈旧或不可用,请刷新确认',\n usageMeterNearLimit: '额度接近耗尽',\n usageMeterAhead: '用量领先时间进度',\n usageMeterNoWarning: '未触发额度警告',\n usageMeterUnknownTime: '时间进度未知',\n usageMeterReset: '{duration}后重置',\n usageUnitDay: '{count} 天',\n usageUnitDays: '{count} 天',\n usageUnitHour: '{count} 小时',\n usageUnitHours: '{count} 小时',\n usageUnitMinute: '{count} 分钟',\n usageUnitMinutes: '{count} 分钟',\n usageColorLabel: '用量配色',\n usageColorStandard: '标准(默认 · 领先 10 个百分点)',\n usageColorRelaxed: '宽松(领先 15 个百分点)',\n usageColorRemaining: '仅剩余额度(不显示黄色)',\n usageColorPaceHint: '用量领先时间进度 {allowance} 个百分点时变黄;已用达到 90% 时优先变红。自动保存到当前浏览器,仅改变配色。',\n usageColorRemainingHint: '已用达到 90% 时变红,不显示黄色节奏警告。可靠的时间标记仍保留,自动保存到当前浏览器。',\n usagePlan: '计划:{plan}',\n resetCreditsTitle: '用量限制重置',\n resetCreditsAvailable: '可用 {count} 次',\n resetCreditsError: '用量限制重置查询失败:{message}',\n resetCreditsErrorFixed: '用量限制重置暂不可用,请刷新用量后重试。',\n resetCreditReadOnly: '只读。此页面不能消耗 Claude 的重置额度。',\n resetCreditReadOnlyLabel: '只读',\n resetCreditAvailable: '可用',\n resetCreditNotUsable: '暂不可用',\n resetCreditPaused: '已暂停',\n resetCreditExhausted: '已用尽',\n resetCreditExpired: '已过期',\n resetCreditRemaining: '剩余 {left} / {total}',\n resetCreditLeft: '剩余 {left}',\n resetCreditRemainingUnknown: '剩余次数不可用',\n resetCreditCooldownUntil: '{date} 后可用',\n resetUseButton: '使用…',\n resetUseChecking: '正在检查…',\n resetUseGuard: '每周用量达到 80% 后才可使用此重置。',\n resetUseRestart: '缺少重置详情。请重启 DSH、重新加载页面并刷新用量。',\n resetUseRefresh: '请刷新用量以验证当前限制和重置可用性。',\n resetUseReady: '使用此最早到期的重置额度,操作前需要确认。',\n resetUseConfirmTitle: '确认完整重置',\n resetUseWarning: '将消耗一次额度并重置每周和 5 小时限制,无法撤销。确认将在 60 秒后过期。',\n resetUseAcknowledge: '我理解将消耗一次额度。',\n resetUseConfirm: '消耗一次重置',\n resetUseSuccess: '重置已确认,用量已刷新。',\n resetCreditFull: '完整重置',\n resetCreditExpires: '{date} 到期',\n resetCreditExpiryUnknown: '到期时间不可用',\n externalUsageTitle: '内置供应商用量',\n externalUsageConnected: '已配置 API 密钥',\n externalUsageNotConfigured: '未配置',\n externalUsageApiKey: 'API 密钥',\n externalUsageConfigure: '未在 {ref} 找到 API 密钥。请在「设置 → 模型」中添加。',\n externalUsageUnavailable: '无法获取用量状态:{message}',\n cursorTitle: 'Cursor',\n cursorOpenLogin: '打开 Cursor 登录页面',\n cursorWaiting: '等待 Cursor 登录…',\n cursorConnected: '已连接',\n cursorManageTitle: '管理 Cursor',\n cursorManageSignIn: '登录后可查看此 Cursor 账号可用的模型。',\n cursorAccountsHint: 'Cursor 使用一个已连接账号。可在此选择模型选择器中显示的模型。',\n cursorManageHint: '在此选择模型是否显示。刷新可从 Cursor 获取当前模型;保存更改后更新模型选择器。',\n cursorFilterModels: '筛选模型',\n cursorModelsLoading: '正在加载 Cursor 模型…',\n cursorModelsError: '无法加载 Cursor 模型:{message}',\n cursorModelsCount: '可用模型:{count} 个',\n cursorIncluded: '套餐内用量',\n cursorModels: 'Cursor 模型',\n cursorOtherModels: '其他模型',\n cursorIncludedRequests: '套餐内请求',\n modelDefaultsTitle: '默认推理档',\n modelDefaultsHint: '切换到该模型时,模型选择器会预选此档位;没有推理档的模型始终跟随服务商默认。',\n modelDefaultsFollowProvider: '跟随服务商',\n modelDefaultsNoLevels: '{count} 个模型未声明推理档,始终跟随服务商默认。',\n modelDefaultsLoading: '加载模型中…',\n modelDefaultsLoadFailed: '模型加载失败:{message}',\n modelDefaultsRetry: '重试',\n modelDefaultsRefresh: '刷新模型列表(全部订阅)',\n modelDefaultsSaving: '保存中…',\n modelDefaultsSaveFailedNamed: '{model} 保存失败:{message}',\n modelDefaultsSummary: '{total} 个模型 · {configured} 个已覆盖',\n modelDefaultsSummaryNone: '{total} 个模型 · 全部跟随服务商',\n modelDefaultsSummaryEmpty: '没有模型声明推理档',\n modelDefaultsFilterPlaceholder: '筛选模型',\n modelDefaultsFilterEmpty: '没有匹配「{query}」的模型。',\n generating: '正在生成图片…',\n image: '图片',\n viewImage: '查看图片',\n viewImageNamed: '查看 {name}',\n imageLoading: '加载中…',\n imageLoadFailed: '重试',\n imagePreview: '图片预览',\n imageClose: '关闭',\n generatingVideo: '正在生成视频…',\n videoLoading: '视频加载中…',\n videoLoadFailed: '视频加载失败:{message}',\n usageBadgeTitle: '服务商用量',\n usageBadgeDisplay: '状态栏额度显示',\n usageBadgeDisplayRecent: '仅显示当前/最近使用的用量服务商',\n usageBadgeDisplayAlways: '始终显示一家,其余服务商轮播',\n usageBadgeDisplayHidden: '不显示',\n usageBadgeDisplayHint: '自动保存到当前浏览器。状态栏一次显示一家服务商;没有额度来源的模型沿用本视图最近选择的服务商,没有记录则隐藏。选择“始终显示”时,当前模型没有额度来源,就每 10 秒轮播一家有额度的服务商。关闭不影响本页的额度详情。',\n usageBadgeDisplaySaveFailed: '显示设置保存失败,请检查浏览器存储权限。',\n usageBadgeCurrent: '当前',\n usageBadgeModelCount: '{count} 个模型配额',\n usageBadgeModelUnavailable: '当前模型暂无配额数据',\n usageBadgeMoreWindows: '更多配额窗口({count})',\n speed: '速度',\n speedStandard: '标准',\n speedStandardDescription: '默认速度',\n speedFast: '快速',\n speedFastDescription: '约 1.5 倍速度,消耗更多用量',\n commandFast: '切换 Codex 速度档(标准/快速)',\n commandFastUnavailable: '当前模型不支持快速档;/fast 仅对目录声明了 fast tier 的 Codex 模型可用',\n} satisfies Record<keyof typeof en, string>\n\n/** The Subscriptions namespace key union (en is the key-set source of truth). */\nexport type SubscriptionsKey = keyof typeof en\n","/** Explain client-side gating; the server independently revalidates before spending. */\nexport function resetActionBlock(usage: {\n windows?: { kind: string; scope?: string; usedPercent: number; resetsAt?: number }[]\n resetCredits?: { id?: string; expiresAt?: number }[]\n resetCreditsError?: string\n}, now = Date.now()): 'resetUseGuard' | 'resetUseRefresh' | 'resetUseRestart' | undefined {\n const weekly = usage.windows?.find(w => w.kind === 'weekly' && w.scope === undefined)\n if (!weekly || !Number.isFinite(weekly.usedPercent)) return 'resetUseRefresh'\n if (weekly.usedPercent < 80) return 'resetUseGuard'\n if (weekly.resetsAt === undefined || weekly.resetsAt <= now || usage.resetCreditsError) return 'resetUseRefresh'\n if (!usage.resetCredits?.some(c => c.id)) return 'resetUseRestart'\n if (!usage.resetCredits.some(c => c.id && (c.expiresAt === undefined || c.expiresAt > now))) return 'resetUseRefresh'\n return undefined\n}\n","import type { ConnectionHandle, RpcResult } from '@deepseek-ai/dsh-api-remotes/client'\n\n/**\n * The node half mounts every endpoint as an exact POST route on the shared\n * `/api` channel (`/api/subscriptions-auth.<endpoint>`), so the browser\n * reaches it through the `/api` channel with a prefixed endpoint name.\n * A dedicated channel is no longer used: since dsh 0.1.5 `rpc.handle`\n * cannot register one from a plugin (see `src/auth/rpc.ts`).\n */\nconst SUBSCRIPTIONS_AUTH_CHANNEL = '/api'\nconst SUBSCRIPTIONS_AUTH_PREFIX = 'subscriptions-auth.'\n\n/** Business error returned by a `subscriptions-auth` endpoint (error branch message). */\nexport class SubscriptionsAuthError extends Error {}\n\n/**\n * Call one `subscriptions-auth` endpoint and unwrap the business result.\n * Shared by the settings section, the composer Speed toggle, the usage\n * badge, and the image/video toolviews.\n * @param rpc - Connection RPC caller.\n * @param endpoint - endpoint name (`status`, `usage`, `image`, ...).\n * @param payload - endpoint-owned request payload.\n * @returns the success value, cast by the caller to the endpoint's shape.\n */\nexport async function callSubscriptionsAuth<T>(rpc: ConnectionHandle['rpc'], endpoint: string, payload: unknown): Promise<T> {\n let result: RpcResult<unknown>\n try {\n result = await rpc.call(SUBSCRIPTIONS_AUTH_CHANNEL, `${SUBSCRIPTIONS_AUTH_PREFIX}${endpoint}`, payload)\n } catch (error) {\n // The transport rejected rather than answering; surface the same way.\n throw new SubscriptionsAuthError(error instanceof Error ? error.message : String(error))\n }\n if (!result.ok) throw new SubscriptionsAuthError(result.error.message)\n return result.value as T\n}\n","import type { AccountPreferences, ProviderPreferences } from '../provider-settings.js'\n\nexport interface AccountCatalogRow {\n key: string\n label: string\n models: { id: string; name: string }[]\n unavailable?: boolean\n}\n\n/** Missing allowlist follows discovery; explicit [] must remain empty. */\nexport function accountPoolSelection(account: AccountPreferences, models: readonly { id: string }[]): Set<string> {\n return new Set(account.poolModels ?? models.map(model => model.id))\n}\n\n/** Retain unavailable saved IDs so a temporary catalog failure cannot erase them. */\nexport function accountModelRows(account: AccountCatalogRow, preferences: AccountPreferences) {\n const known = new Set(account.models.map(model => model.id))\n return [\n ...account.models.map(model => ({ ...model, unavailable: false })),\n ...(preferences.poolModels ?? []).filter(id => !known.has(id)).map(id => ({ id, name: id, unavailable: true })),\n ]\n}\n\n/** The model editor owns everything except the separately managed accounts. */\nexport function mergeLatestAccounts(draft: ProviderPreferences, latest: ProviderPreferences): ProviderPreferences {\n const { accounts: _stale, ...settings } = draft\n return { ...settings, ...(latest.accounts === undefined ? {} : { accounts: latest.accounts }) }\n}\n\n/** Only touched accounts replace their latest preferences; other settings survive. */\nexport function mergeAccountChanges(\n latest: ProviderPreferences,\n changes: Record<string, AccountPreferences>,\n): ProviderPreferences {\n return { ...latest, accounts: { ...latest.accounts, ...changes } }\n}\n","import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ProviderPreferences, SubscriptionTool } from '../provider-settings.js'\nimport type { SubscriptionProvider } from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport type { SubscriptionsKey } from './locales.js'\n\ninterface ModelRow {\n id: string\n name: string\n contextWindow?: number\n defaultContextWindow?: number\n efforts?: { id: string; name: string }[]\n configured?: string\n maxContextWindow?: number\n}\ninterface Catalog {\n provider: SubscriptionProvider | 'cursor-subscription'\n settings: ProviderPreferences\n models: ModelRow[]\n tools: SubscriptionTool[]\n}\ninterface Props {\n provider: SubscriptionProvider | 'cursor-subscription'\n rpc: ConnectionHandle['rpc']\n t: (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n /** Freeze the editor while the owning dialog submits. */\n disabled?: boolean\n /** Reports whether the draft differs from the loaded catalog. */\n onDirtyChange?: (dirty: boolean) => void\n}\n\n/** The editor's unsaved edits, collected by the owning dialog's single Save. */\nexport interface ModelDraft {\n /** Provider settings minus `accounts`; absent when the draft has no edits. */\n settings?: ProviderPreferences\n /** Reasoning-effort overrides that differ from the catalog; '' clears one. */\n efforts: { model: string; effort: string }[]\n}\nexport interface ProviderModelEditorHandle {\n /**\n * Validate and collect the draft without mutating it, so a failed submit\n * keeps every edit. Returns undefined when a value is invalid; the editor\n * shows the reason itself.\n */\n collect(): ModelDraft | undefined\n}\n\nconst border = '0.5px solid var(--dsw-alias-border-l2, #ddd)'\nconst actions: CSSProperties = { display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }\n\n/**\n * Embedded section of the account manager dialog. It owns the model draft\n * (visibility, effort, context, tools) but not its submission: the dialog\n * collects the draft through the handle and saves it with the account edits\n * in one go, so there is a single Save/Cancel pair.\n */\nexport const ProviderModelEditor = forwardRef<ProviderModelEditorHandle, Props>(function ProviderModelEditor(\n { provider, rpc, t, disabled = false, onDirtyChange }, ref,\n) {\n const [catalog, setCatalog] = useState<Catalog>()\n const [draft, setDraft] = useState<ProviderPreferences>({})\n const [contexts, setContexts] = useState<Record<string, string>>({})\n const [efforts, setEfforts] = useState<Record<string, string>>({})\n const [query, setQuery] = useState('')\n const [busy, setBusy] = useState(false)\n const [dirty, setDirty] = useState(false)\n const [error, setError] = useState('')\n const generation = useRef(0)\n useEffect(() => () => { generation.current++ }, [])\n useEffect(() => { onDirtyChange?.(dirty) }, [dirty])\n\n function reset(data: Catalog) {\n setCatalog(data)\n setDraft(data.settings)\n setEfforts(Object.fromEntries(data.models.map(model => [model.id, model.configured ?? ''])))\n setContexts(Object.fromEntries(Object.entries(data.settings.contextWindows ?? {}).map(([id, value]) => [id, String(value)])))\n setDirty(false)\n }\n async function load(force = false) {\n const request = ++generation.current\n setBusy(true)\n setError('')\n try {\n const data = await callSubscriptionsAuth<Catalog>(rpc,\n provider === 'cursor-subscription' ? 'cursorSettings' : 'providerSettings', { provider, force })\n if (generation.current === request) reset(data)\n } catch (error) {\n if (generation.current === request) setError(String(error instanceof Error ? error.message : error))\n } finally {\n if (generation.current === request) setBusy(false)\n }\n }\n function edit(next: ProviderPreferences) { setDraft(next); setDirty(true) }\n useEffect(() => { void load() }, [provider, rpc])\n\n useImperativeHandle(ref, () => ({\n collect() {\n if (!catalog || !dirty) return { efforts: [] }\n const windows: Record<string, number> = Object.create(null) as Record<string, number>\n for (const [model, text] of Object.entries(contexts)) {\n if (!text.trim()) continue\n const value = Number(text)\n if (!/^\\d+$/.test(text.trim()) || !Number.isSafeInteger(value) || value <= 0) {\n setError(t('modelsContextInvalid', { model }))\n return undefined\n }\n windows[model] = value\n }\n setError('')\n const { accounts: _accounts, ...settings } = { ...draft, ...(provider === 'codex' ? { contextWindows: windows } : {}) }\n return {\n settings,\n efforts: catalog.models.flatMap(model => {\n const effort = efforts[model.id] ?? ''\n return effort === (model.configured ?? '') || !model.efforts?.length ? [] : [{ model: model.id, effort }]\n }),\n }\n },\n }), [catalog, dirty, draft, contexts, efforts, provider])\n\n const allModels = catalog?.models ?? []\n const known = new Set(allModels.map(model => model.id))\n const missing = (draft.visibleModels ?? []).filter(id => !known.has(id)).map(id => ({ id, name: id } as ModelRow))\n const models = [...allModels, ...missing].filter(model => `${model.name} ${model.id}`.toLowerCase().includes(query.trim().toLowerCase()))\n const selected = new Set(draft.visibleModels ?? allModels.map(model => model.id))\n return <div style={{ borderTop: border, marginTop: 12, paddingTop: 12 }}>\n <h3 style={{ margin: 0 }}>{t('modelsEdit')}</h3>\n <div style={{ display: 'grid', gap: 12, marginTop: 12 }}>\n <p className=\"dsh-subscription-hint\">{t(provider === 'cursor-subscription' ? 'cursorManageHint' : 'modelsHint')}</p>\n {error && <p role=\"alert\">{error}</p>}\n <div style={actions}>\n <button type=\"button\" className=\"dsh-subscription-quiet\" disabled={busy || disabled || dirty} onClick={() => { void load(true) }}>{t('usageRefresh')}</button>\n {busy && <span role=\"status\">{t('modelDefaultsLoading')}</span>}\n </div>\n {catalog && <fieldset disabled={busy || disabled} style={{ border: 0, padding: 0, margin: 0, minWidth: 0, display: 'grid', gap: 12 }}>\n <label><input type=\"checkbox\" checked={draft.visibleModels === undefined} onChange={event => {\n const next = { ...draft }\n if (event.target.checked) delete next.visibleModels\n else next.visibleModels = allModels.map(model => model.id)\n edit(next)\n }} /> {t('modelsAutomatic')}</label>\n <div style={actions}>\n <input style={{ flex: '1 1 180px' }} value={query} onChange={event => setQuery(event.target.value)}\n placeholder={t('modelDefaultsFilterPlaceholder')} aria-label={t('modelDefaultsFilterPlaceholder')} />\n <button type=\"button\" onClick={() => edit({ ...draft, visibleModels: allModels.map(model => model.id) })}>{t('modelsSelectAll')}</button>\n <button type=\"button\" onClick={() => edit({ ...draft, visibleModels: [] })}>{t('modelsSelectNone')}</button>\n </div>\n <div style={{ maxHeight: 360, overflowY: 'auto', display: 'grid', gap: 8 }}>\n {models.map(model => <div key={model.id} style={{ borderBottom: border, padding: '8px 2px', display: 'grid', gap: 8 }}>\n <label style={{ overflowWrap: 'anywhere' }}><input type=\"checkbox\" checked={selected.has(model.id)} onChange={event => {\n const next = new Set(selected)\n if (event.target.checked) next.add(model.id); else next.delete(model.id)\n edit({ ...draft, visibleModels: [...next] })\n }} /> {model.name}{!known.has(model.id) && ` (${t('modelsUnavailable')})`}</label>\n <div style={actions}>\n {(model.efforts?.length ?? 0) > 0 && <label style={actions}>{t('modelDefaultsTitle')}\n <select aria-label={`${model.name} ${t('modelDefaultsTitle')}`}\n value={efforts[model.id] ?? ''} onChange={event => {\n setEfforts({ ...efforts, [model.id]: event.target.value }); setDirty(true)\n }}>\n <option value=\"\">{t('modelDefaultsFollowProvider')}</option>\n {model.configured && !model.efforts?.some(effort => effort.id === model.configured) &&\n <option value={model.configured} disabled>{model.configured} ({t('modelsUnavailable')})</option>}\n {model.efforts?.map(effort => <option key={effort.id} value={effort.id}>{effort.name}</option>)}\n </select>\n </label>}\n {provider === 'codex' && model.maxContextWindow !== undefined && <div style={actions}>\n <label style={actions}>{t('modelsContext')}\n <input style={{ width: 140 }} inputMode=\"numeric\" value={contexts[model.id] ?? ''}\n aria-label={`${model.name} ${t('modelsContext')}`} placeholder={String(model.defaultContextWindow)}\n onChange={event => { setContexts({ ...contexts, [model.id]: event.target.value }); setDirty(true) }} />\n </label>\n <small>{t('modelsContextBounds', { default: model.defaultContextWindow, max: model.maxContextWindow })}</small>\n </div>}\n </div>\n </div>)}\n {models.length === 0 && <span>{t('modelDefaultsFilterEmpty', { query })}</span>}\n </div>\n {provider === 'codex' && <small>{t('modelsContextHint')}</small>}\n {catalog.tools.length > 0 && <div style={{ display: 'grid', gap: 8 }}>\n <strong>{t('modelsTools')}</strong>\n <small>{t('modelsToolsHint')}</small>\n {catalog.tools.map(tool => <label key={tool}>\n <input type=\"checkbox\" checked={draft.tools?.[tool] !== false} onChange={event => edit({\n ...draft, tools: { ...draft.tools, [tool]: event.target.checked },\n })} /> {t(tool === 'image_generate' ? 'modelsImage' : tool === 'video_generate' ? 'modelsVideo' : tool === 'web_search' ? 'modelsWebSearch' : 'modelsSearch')}\n </label>)}\n </div>}\n </fieldset>}\n </div>\n </div>\n})\n","/**\n * The host loads one JS client bundle, so keep this small, scoped stylesheet\n * with the dialog instead of relying on a separate CSS asset. Geometry and\n * theme tokens follow the host's settings-form and ui-primitives controls.\n *\n * `color-scheme` is left to the host deliberately. Its boot script sets the\n * property on `:root`, and it inherits, so native controls inside these panels\n * follow the theme. Upstream also pins `color-scheme: light` here and flips it\n * back under `body[data-ds-dark-theme]`; without that flip our scoped rules are\n * more specific than `:root` and would force every native control light inside\n * a dark theme.\n */\nconst formScope = ':is(.dsh-subscription-manager, .dsh-subscriptions-settings)'\n\nexport const providerSettingsCss = `\n.dsh-subscription-manager {\n box-sizing: border-box;\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-panel, 16px);\n background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-elevation-prominent, 0 20px 70px #0004);\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n.dsh-subscriptions-settings {\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n.dsh-subscription-manager::backdrop {\n background: var(--dsw-alias-bg-mask-1, #0006);\n backdrop-filter: var(--dsw-mask-blur, none);\n}\n${formScope} h2 {\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n}\n${formScope} h3 {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n}\n${formScope} strong,\n${formScope} .dsh-subscription-label {\n font-size: 13px;\n line-height: 1.5;\n font-weight: 500;\n}\n${formScope} legend {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n}\n${formScope} small,\n${formScope} .dsh-subscription-hint,\n${formScope} [role=\"status\"] {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n${formScope} [role=\"alert\"] {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary, #b42318);\n}\n${formScope} input:not([type=\"checkbox\"]),\n${formScope} select {\n box-sizing: border-box;\n min-width: 0;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4, var(--dsw-alias-border-l2));\n border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-layer-1));\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n font-weight: 400;\n line-height: 1.5;\n}\n${formScope} input::placeholder {\n color: var(--dsw-alias-label-tertiary);\n opacity: 1;\n}\n${formScope} input:not([type=\"checkbox\"]):focus-visible,\n${formScope} select:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary));\n}\n${formScope} input:not([type=\"checkbox\"]):disabled,\n${formScope} select:disabled {\n color: var(--dsw-alias-label-tertiary);\n cursor: default;\n}\n${formScope} input[aria-invalid=\"true\"] {\n border-color: var(--dsw-alias-state-error-primary, #b42318);\n}\n${formScope} option {\n background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));\n color: var(--dsw-alias-label-primary);\n}\n${formScope} label:has(> input[type=\"checkbox\"]) {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n font-size: 14px;\n line-height: 20px;\n cursor: pointer;\n}\n${formScope} input[type=\"checkbox\"] {\n flex: 0 0 auto;\n width: 16px;\n height: 16px;\n margin: 2px 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: inherit;\n}\n${formScope} label:has(> input[type=\"checkbox\"]:disabled) {\n cursor: default;\n opacity: 0.5;\n}\n${formScope} button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-height: 28px;\n padding: 0 10px;\n border: 0.5px solid var(--dsw-alias-border-l3, var(--dsw-alias-border-l2));\n border-radius: var(--dsw-radius-sm, 6px);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n}\n${formScope} button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, var(--dsw-alias-bg-layer-3));\n}\n${formScope} button:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, var(--dsw-alias-bg-layer-3));\n}\n${formScope} button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n${formScope} button.dsh-subscription-quiet {\n border-color: transparent;\n color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-primary));\n}\n${formScope} :is(footer, .dsh-subscription-dialog-actions) button {\n min-height: 34px;\n padding: 0 14px;\n border-radius: var(--dsw-radius-md, 8px);\n font-size: 13px;\n line-height: 1.5;\n}\n${formScope} button.dsh-subscription-primary {\n border-color: transparent;\n background: var(--dsw-alias-button-primary-fill, var(--dsw-alias-label-primary));\n color: var(--dsw-alias-label-primary-foreground, var(--dsw-alias-bg-layer-1));\n font-weight: 500;\n}\n${formScope} button.dsh-subscription-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, var(--dsw-alias-label-secondary));\n}\n${formScope} button:focus-visible,\n${formScope} input[type=\"checkbox\"]:focus-visible,\n${formScope} summary:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n${formScope} summary {\n border-radius: var(--dsw-radius-sm, 6px);\n}\n${formScope} summary:hover {\n color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-primary));\n}\n`\n\n/** Composer controls retain their own geometry, separate from settings forms. */\nexport const subscriptionChromeCss = `\n.dsh-subscription-usage-pill { corner-shape: round; }\n.dsh-subscription-usage-panel {\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n backdrop-filter: var(--dsw-menu-backdrop-filter, none);\n}\n.dsh-subscription-speed button:hover:not(:disabled) {\n --dsh-subscription-speed-hover: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-subscription-speed button:active:not(:disabled) {\n --dsh-subscription-speed-hover: var(--dsw-alias-interactive-bg-active);\n}\n.dsh-subscription-speed button:disabled { opacity: 0.4; cursor: default; }\n.dsh-subscription-speed button:focus-visible,\n.dsh-subscription-usage-pill:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n`\n","import { useEffect, useId, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { AccountPreferences, ProviderPreferences } from '../provider-settings.js'\nimport type { SubscriptionProvider } from './SubscriptionsSection.js'\nimport type { SubscriptionsKey } from './locales.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { accountModelRows, accountPoolSelection, mergeAccountChanges, mergeLatestAccounts } from './account-preferences.js'\nimport type { AccountCatalogRow } from './account-preferences.js'\nimport { ProviderModelEditor } from './ProviderModelEditor.js'\nimport type { ProviderModelEditorHandle } from './ProviderModelEditor.js'\nimport { providerSettingsCss } from './provider-settings-styles.js'\n\ninterface Catalog { settings: ProviderPreferences; accounts: AccountCatalogRow[] }\ninterface Props {\n provider: SubscriptionProvider | 'cursor-subscription'\n name: string\n rpc: ConnectionHandle['rpc']\n t: (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n onClose: () => void\n}\nconst border = '0.5px solid var(--dsw-alias-border-l2)'\nconst stack: CSSProperties = { display: 'grid', gap: 12, minWidth: 0 }\nconst actions: CSSProperties = { display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }\n\n/** Native top-layer dialog provides keyboard containment, Escape and focus restoration. */\nexport function ProviderAccountManager({ provider, name, rpc, t, onClose }: Props) {\n const dialog = useRef<HTMLDialogElement>(null)\n const title = useId()\n const description = useId()\n const [catalog, setCatalog] = useState<Catalog>()\n const [changes, setChanges] = useState<Record<string, AccountPreferences>>({})\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState('')\n const [saveError, setSaveError] = useState('')\n const [attempt, setAttempt] = useState(0)\n const [modelsDirty, setModelsDirty] = useState(false)\n const alive = useRef(true)\n const saveLock = useRef(false)\n const editor = useRef<ProviderModelEditorHandle>(null)\n useEffect(() => {\n alive.current = true\n const element = dialog.current!\n const previous = document.activeElement\n element.showModal()\n return () => {\n alive.current = false\n element.close()\n if (previous instanceof HTMLElement && previous.isConnected) previous.focus()\n }\n }, [])\n useEffect(() => {\n let current = true\n setLoading(true)\n setError('')\n void callSubscriptionsAuth<Catalog>(rpc,\n provider === 'cursor-subscription' ? 'cursorSettings' : 'providerSettings', { provider }).then(data => {\n if (current) setCatalog(data)\n }).catch(error => {\n if (current) setError(t('accountsLoadFailed', { message: error instanceof Error ? error.message : String(error) }))\n }).finally(() => { if (current) setLoading(false) })\n return () => { current = false }\n }, [provider, rpc, attempt])\n\n function edit(key: string, next: AccountPreferences) {\n setChanges(current => ({ ...current, [key]: next }))\n }\n /**\n * One submit for both drafts: the model editor's (visibility, effort,\n * context, tools) and this dialog's account edits. A failure keeps the\n * dialog open with every edit intact.\n */\n async function save() {\n if (saveLock.current) return\n // An invalid model draft (e.g. a malformed context window) blocks the\n // whole submit; the editor shows the reason next to the field.\n const models = editor.current === null ? { efforts: [] } : editor.current.collect()\n if (models === undefined) return\n saveLock.current = true\n setSaving(true)\n setSaveError('')\n let savedEfforts = 0\n try {\n if (provider !== 'cursor-subscription') {\n for (const { model, effort } of models.efforts) {\n await callSubscriptionsAuth(rpc, 'setModelDefault', { provider, model, ...(effort ? { effort } : {}) })\n savedEfforts++\n if (!alive.current) return\n }\n }\n // Re-read before writing: another client may have saved since this\n // dialog loaded, and a stale snapshot must never be written back.\n const latest = await callSubscriptionsAuth<Catalog>(rpc,\n provider === 'cursor-subscription' ? 'cursorSettings' : 'providerSettings', { provider })\n if (!alive.current) return\n if (provider === 'cursor-subscription') {\n await callSubscriptionsAuth(rpc, 'cursorSetSettings', { settings: models.settings ?? latest.settings })\n } else {\n const base = models.settings === undefined ? latest.settings : mergeLatestAccounts(models.settings, latest.settings)\n await callSubscriptionsAuth(rpc, 'setProviderSettings', { provider, settings: mergeAccountChanges(base, changes) })\n }\n if (alive.current) onClose()\n } catch (error) {\n if (alive.current) {\n const message = error instanceof Error ? error.message : String(error)\n setSaveError((savedEfforts ? t('modelsPartialSave') + ' ' : '') + t('accountsSaveFailed', { message }))\n }\n } finally {\n saveLock.current = false\n if (alive.current) setSaving(false)\n }\n }\n return <dialog className=\"dsh-subscription-manager\" ref={dialog} aria-labelledby={title} aria-describedby={description}\n onCancel={event => { if (saveLock.current) event.preventDefault() }} onClose={onClose}\n style={{ width: 620, maxWidth: 'calc(100vw - 32px)', maxHeight: 'calc(100dvh - 32px)', overflow: 'auto' }}>\n <style>{providerSettingsCss}</style>\n <div style={{ ...stack, padding: 20 }}>\n <header style={{ ...actions, justifyContent: 'space-between' }}>\n <h2 id={title} style={{ margin: 0 }}>{t('accountsTitle', { provider: name })}</h2>\n <button type=\"button\" autoFocus disabled={saving} onClick={onClose}>{t('imageClose')}</button>\n </header>\n <p id={description} className=\"dsh-subscription-hint\">{t(provider === 'cursor-subscription' ? 'cursorAccountsHint' : 'accountsHint')}</p>\n {error && <p role=\"alert\">{error}</p>}\n {loading && <p role=\"status\" className=\"dsh-subscription-hint\">{t('accountsLoading')}</p>}\n {!loading && !catalog && <button type=\"button\" onClick={() => setAttempt(value => value + 1)}>{t('modelDefaultsRetry')}</button>}\n {catalog && <fieldset disabled={saving || loading} style={{ ...stack, border: 0, margin: 0, padding: 0 }}>\n {catalog.accounts.length === 0 && <p className=\"dsh-subscription-hint\">{t(provider === 'cursor-subscription' ? 'cursorManageSignIn' : 'accountsEmpty')}</p>}\n {provider === 'cursor-subscription' && catalog.accounts.length > 0 &&\n <fieldset style={{ border, borderRadius: 'var(--dsw-radius-lg, 12px)', padding: 14 }}>\n <legend style={{ padding: '0 6px' }}>{name}</legend>\n <p className=\"dsh-subscription-hint\">{t('cursorConnected')}</p>\n </fieldset>}\n {provider !== 'cursor-subscription' && catalog.accounts.map(account => {\n const preferences = changes[account.key] ?? catalog.settings.accounts?.[account.key] ?? {}\n const selected = accountPoolSelection(preferences, account.models)\n const models = accountModelRows(account, preferences)\n return <fieldset key={account.key} style={{ ...stack, border, borderRadius: 'var(--dsw-radius-lg, 12px)', padding: 14, margin: 0 }}>\n <legend style={{ padding: '0 6px', overflowWrap: 'anywhere', maxWidth: '100%' }}>{account.label}</legend>\n {account.unavailable && <p className=\"dsh-subscription-hint\">{t('accountsCatalogUnavailable')}</p>}\n <label style={{ ...stack, gap: 6 }}>\n <span className=\"dsh-subscription-label\">{t('accountsAlias')}</span>\n <input value={preferences.alias ?? ''} placeholder={account.label}\n onChange={event => {\n const next = { ...preferences }\n if (event.target.value.trim()) next.alias = event.target.value\n else delete next.alias\n edit(account.key, next)\n }} />\n </label>\n <label><input type=\"checkbox\" checked={preferences.poolEnabled !== false}\n onChange={event => edit(account.key, { ...preferences, poolEnabled: event.target.checked })} /> {t('accountsPoolEnabled')}</label>\n <label><input type=\"checkbox\" checked={preferences.independentEntry === true}\n onChange={event => edit(account.key, { ...preferences, independentEntry: event.target.checked })} /> {t('accountsIndependent')}</label>\n <p className=\"dsh-subscription-hint\">{t('accountsIndependentHint')}</p>\n <details>\n <summary style={{ cursor: 'pointer', fontSize: 13 }}>{t('accountsModels')} · {preferences.poolModels === undefined\n ? t('accountsModelsAll') : t('accountsModelsCount', { count: preferences.poolModels.length })}</summary>\n <div style={{ ...stack, marginTop: 12 }}>\n <p className=\"dsh-subscription-hint\">{t('accountsModelsHint')}</p>\n <label><input type=\"checkbox\" checked={preferences.poolModels === undefined} onChange={event => {\n const next = { ...preferences }\n if (event.target.checked) delete next.poolModels\n else next.poolModels = account.models.map(model => model.id)\n edit(account.key, next)\n }} /> {t('accountsModelsAutomatic')}</label>\n <div style={actions}>\n <button type=\"button\" onClick={() => edit(account.key, { ...preferences, poolModels: models.map(model => model.id) })}>{t('modelsSelectAll')}</button>\n <button type=\"button\" onClick={() => edit(account.key, { ...preferences, poolModels: [] })}>{t('modelsSelectNone')}</button>\n </div>\n <div style={{ ...stack, gap: 8, maxHeight: 240, overflowY: 'auto' }}>\n {models.map(model => <label key={model.id} style={{ overflowWrap: 'anywhere' }}>\n <input type=\"checkbox\" checked={selected.has(model.id)} onChange={event => {\n const next = new Set(selected)\n if (event.target.checked) next.add(model.id); else next.delete(model.id)\n edit(account.key, { ...preferences, poolModels: [...next] })\n }} /> {model.name}{model.unavailable && ` (${t('modelsUnavailable')})`}\n </label>)}\n {models.length === 0 && <p className=\"dsh-subscription-hint\">{t('accountsNoModels')}</p>}\n </div>\n </div>\n </details>\n </fieldset>\n })}\n </fieldset>}\n {(provider !== 'cursor-subscription' || (catalog?.accounts.length ?? 0) > 0) &&\n <ProviderModelEditor ref={editor} provider={provider} rpc={rpc} t={t} disabled={saving} onDirtyChange={setModelsDirty} />}\n <footer style={{ ...stack, gap: 8, borderTop: border, padding: '14px 0 8px',\n position: 'sticky', bottom: 0, background: 'var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1))' }}>\n {saveError && <p role=\"alert\">{saveError}</p>}\n <div style={{ ...actions, justifyContent: 'flex-end' }}>\n <button type=\"button\" disabled={saving} onClick={onClose}>{t('cancel')}</button>\n <button type=\"button\" className=\"dsh-subscription-primary\" disabled={loading || saving || (!Object.keys(changes).length && !modelsDirty)}\n onClick={() => { void save() }}>{saving ? t('modelDefaultsSaving') : t('modelsSave')}</button>\n </div>\n </footer>\n </div>\n </dialog>\n}\n","import type { CSSProperties } from 'react'\n\n/** Shared visual language for OAuth, Cursor, and built-in provider cards. */\nexport const subscriptionCardStyles: Record<string, CSSProperties> = {\n card: {\n border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 12,\n padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 6,\n color: 'var(--dsw-alias-label-primary)',\n },\n header: { display: 'flex', alignItems: 'center', gap: 8 },\n dot: { width: 8, height: 8, borderRadius: '50%', flexShrink: 0 },\n name: { fontWeight: 500, fontSize: 14, lineHeight: '22px', color: 'var(--dsw-alias-label-primary)' },\n status: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' },\n error: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-state-error-primary)' },\n actions: { display: 'flex', gap: 8, marginTop: 4, alignItems: 'center', flexWrap: 'wrap' },\n button: {\n boxSizing: 'border-box', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n height: 28, padding: '0 10px', borderRadius: 14,\n border: '1px solid var(--dsw-alias-border-l2)', background: 'transparent',\n color: 'var(--dsw-alias-label-primary)', font: 'inherit', fontSize: 12, lineHeight: '18px',\n cursor: 'pointer',\n },\n account: {\n display: 'flex', flexDirection: 'column', gap: 6,\n border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8,\n padding: '8px 10px', marginTop: 4,\n },\n accountHeader: { display: 'flex', alignItems: 'center', gap: 8 },\n accountName: { fontSize: 13, lineHeight: '20px', color: 'var(--dsw-alias-label-primary)', userSelect: 'all' },\n defaultStar: { color: 'var(--dsw-alias-state-warn-label)' },\n usage: {\n display: 'flex', flexDirection: 'column', gap: 6, marginTop: 4,\n borderTop: '1px solid var(--dsw-alias-border-l2)', paddingTop: 8,\n },\n usageHeader: { display: 'flex', alignItems: 'center', gap: 8 },\n usageTitle: { fontSize: 12, lineHeight: '18px', fontWeight: 500, color: 'var(--dsw-alias-label-secondary)' },\n usagePlan: { fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' },\n usageRefresh: {\n boxSizing: 'border-box', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n height: 22, padding: '0 8px', borderRadius: 11, marginLeft: 'auto',\n border: '1px solid var(--dsw-alias-border-l2)', background: 'transparent',\n color: 'var(--dsw-alias-label-secondary)', font: 'inherit', fontSize: 12, lineHeight: '18px',\n cursor: 'pointer',\n },\n usageRow: { display: 'flex', flexDirection: 'column', gap: 3 },\n usageMeta: {\n display: 'flex', justifyContent: 'space-between', gap: 8,\n fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)',\n },\n}\n","import { useSyncExternalStore } from 'react'\n\n/**\n * Display-only preference: no credentials or account history are stored.\n * `recent` pins the current/most-recent provider; `always` keeps a provider\n * visible at all times, rotating through the others when the current model\n * has no quota source; `hidden` shows nothing.\n */\nexport type UsageBadgeMode = 'recent' | 'always' | 'hidden'\nconst MODE_KEY = 'dsh.subscriptions.usageBadgeMode'\nconst MODE_EVENT = 'dsh:subscriptions:usage-badge-mode'\nexport const USAGE_BADGE_REFRESH_EVENT = 'dsh:subscriptions:usage-refresh'\n\n/** Read the browser preference; blocked storage retains the default display. */\nexport function readUsageBadgeMode(): UsageBadgeMode {\n if (typeof window === 'undefined') return 'recent'\n try {\n const value = window.localStorage.getItem(MODE_KEY)\n return value === 'hidden' || value === 'always' ? value : 'recent'\n } catch (error) {\n if (!(error instanceof DOMException) || error.name !== 'SecurityError') throw error\n return 'recent'\n }\n}\n\n/** Save first, then notify; the settings control reports a rejected write. */\nexport function setUsageBadgeMode(mode: UsageBadgeMode): void {\n if (mode !== 'recent' && mode !== 'always' && mode !== 'hidden') throw new TypeError('Invalid subscription usage display mode')\n window.localStorage.setItem(MODE_KEY, mode)\n window.dispatchEvent(new Event(MODE_EVENT))\n}\n\n/** Same-tab writes need a custom event; other tabs use the storage event. */\nexport function subscribeUsageBadgeMode(notify: () => void): () => void {\n const onStorage = (event: StorageEvent): void => {\n if (event.key === MODE_KEY || event.key === null) notify()\n }\n window.addEventListener(MODE_EVENT, notify)\n window.addEventListener('storage', onStorage)\n return () => {\n window.removeEventListener(MODE_EVENT, notify)\n window.removeEventListener('storage', onStorage)\n }\n}\n\n/** Shared React snapshot used by the settings control and every mounted badge. */\nexport function useUsageBadgeMode(): UsageBadgeMode {\n return useSyncExternalStore(subscribeUsageBadgeMode, readUsageBadgeMode, () => 'recent')\n}\n","import type { UsageWindow } from './SubscriptionsSection.js'\nimport type { UsageColorPreset } from './usage-color-preferences.js'\n\nexport interface UsageObservation { observedAt?: number | undefined; stale?: boolean | undefined }\nexport type UsageColorState = 'neutral' | 'red' | 'yellow' | 'green'\nexport const USAGE_FRESHNESS_MS = 5 * 60_000\nexport function validUsage(used: number): boolean {\n return Number.isFinite(used) && used >= 0 && used <= 100\n}\n\n/**\n * Rounded share for display, or undefined when the provider's number is\n * unusable. Callers must show the unavailable state rather than clamp an\n * out-of-range reading into 0% or 100%.\n */\nexport function displayUsedPercent(used: number): number | undefined {\n return validUsage(used) ? Math.round(used) : undefined\n}\n\nexport interface CountdownPart { unit: 'day' | 'hour' | 'minute'; count: number }\n\n/**\n * Reset countdown as the two largest nonzero whole units, rounded up so a\n * window never announces zero remaining time. Always at least one minute.\n */\nexport function resetCountdownParts(ms: number): CountdownPart[] {\n const total = Math.max(1, Math.ceil(ms / 60_000))\n const parts: CountdownPart[] = [\n { unit: 'day', count: Math.floor(total / 1440) },\n { unit: 'hour', count: Math.floor((total % 1440) / 60) },\n { unit: 'minute', count: total % 60 },\n ]\n return parts.filter(part => part.count > 0).slice(0, 2)\n}\n/**\n * Whether the reported percentage still describes the window now. Only a fresh\n * reading may be compared with the current time (pace warnings); an old one\n * keeps its absolute color. This does not decide whether the time cursor is\n * drawn: where the window stands in time never depends on the reading.\n */\nexport function isUsageFresh(window: UsageWindow, observation: UsageObservation, now = Date.now()): boolean {\n return validUsage(window.usedPercent) && observation.stale !== true\n && observation.observedAt !== undefined && Number.isFinite(observation.observedAt)\n && observation.observedAt <= now && now - observation.observedAt <= USAGE_FRESHNESS_MS\n && (window.resetsAt === undefined || Number.isFinite(window.resetsAt) && window.resetsAt > now)\n}\n\n/**\n * How far through its window the clock is, from the window's own timing alone.\n * It ignores the percentage and how recently it was read, so an unused,\n * stale, aged or unobserved reading keeps its cursor whenever the timing\n * places it. Returns undefined when the timing cannot: only an explicit\n * interval or a provider-verified fixed duration supports linear pace, and no\n * start is invented from a window's kind or label.\n */\nexport function elapsedPercent(window: UsageWindow, now = Date.now()): number | undefined {\n const end = window.resetsAt\n if (end === undefined || !Number.isFinite(end) || end <= now) return undefined\n const duration = window.windowDurationMs\n const start = window.startsAt ?? (window.fixedWindow === true && duration !== undefined && Number.isFinite(duration) && duration > 0 ? end - duration : undefined)\n if (start === undefined || !Number.isFinite(start) || start >= end || start > now) return undefined\n return Math.min(100, Math.max(0, (now - start) / (end - start) * 100))\n}\nexport function usageColorState(used: number, elapsed: number | undefined, preset: UsageColorPreset, fresh: boolean): UsageColorState {\n if (!validUsage(used)) return 'neutral'\n if (used >= 90) return 'red'\n // Missing pace or stale observations retain the last reported absolute color.\n if (!fresh || preset === 'remaining' || elapsed === undefined) return 'green'\n return used - elapsed >= (preset === 'relaxed' ? 15 : 10) ? 'yellow' : 'green'\n}\nexport function usageBarColor(used: number, elapsed?: number, preset: UsageColorPreset = 'standard', fresh = true): string {\n const state = usageColorState(used, elapsed, preset, fresh)\n return state === 'red' ? 'var(--dsw-alias-state-error-primary)'\n : state === 'yellow' ? 'var(--dsw-alias-state-warn-label)'\n : 'var(--dsw-alias-state-success-primary)'\n}\n","import { useSyncExternalStore } from 'react'\n\nexport type UsageColorPreset = 'standard' | 'relaxed' | 'remaining'\nconst KEY = 'dsh.subscriptions.usageColorPreset'\nconst EVENT = 'dsh:subscriptions:usage-color-preset'\nexport function isUsageColorPreset(value: unknown): value is UsageColorPreset {\n return value === 'standard' || value === 'relaxed' || value === 'remaining'\n}\nexport function readUsageColorPreset(): UsageColorPreset {\n if (typeof window === 'undefined') return 'standard'\n try {\n const value = window.localStorage.getItem(KEY)\n return isUsageColorPreset(value) ? value : 'standard'\n } catch (error) {\n if (!(error instanceof DOMException) || error.name !== 'SecurityError') throw error\n return 'standard'\n }\n}\nexport function setUsageColorPreset(value: UsageColorPreset): void {\n if (!isUsageColorPreset(value)) throw new TypeError('Invalid usage coloring preset')\n window.localStorage.setItem(KEY, value)\n window.dispatchEvent(new Event(EVENT))\n}\nexport function subscribeUsageColorPreset(notify: () => void): () => void {\n const storage = (event: StorageEvent) => { if (event.key === KEY || event.key === null) notify() }\n window.addEventListener(EVENT, notify)\n window.addEventListener('storage', storage)\n return () => {\n window.removeEventListener(EVENT, notify)\n window.removeEventListener('storage', storage)\n }\n}\nexport function useUsageColorPreset(): UsageColorPreset {\n return useSyncExternalStore(subscribeUsageColorPreset, readUsageColorPreset, () => 'standard')\n}\n","import { useEffect, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { UsageWindow, SubscriptionsSectionInjected } from './SubscriptionsSection.js'\nimport { elapsedPercent, isUsageFresh, resetCountdownParts, usageBarColor, usageColorState, validUsage } from './usage-pace.js'\nimport type { CountdownPart, UsageObservation } from './usage-pace.js'\nimport { useUsageColorPreset } from './usage-color-preferences.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** Singular/plural locale keys per countdown unit (zh maps both to one string). */\nconst UNIT_KEYS: Record<CountdownPart['unit'], [SubscriptionsKey, SubscriptionsKey]> = {\n day: ['usageUnitDay', 'usageUnitDays'],\n hour: ['usageUnitHour', 'usageUnitHours'],\n minute: ['usageUnitMinute', 'usageUnitMinutes'],\n}\n\nexport function UsageMeter({ window: quota, t, style, observedAt, stale }: {\n window: UsageWindow; t: SubscriptionsSectionInjected['t']; style?: CSSProperties\n} & UsageObservation) {\n const preset = useUsageColorPreset()\n const [now, setNow] = useState(Date.now)\n useEffect(() => {\n const timer = setInterval(() => setNow(Date.now()), 60_000)\n return () => clearInterval(timer)\n }, [])\n // Use render time for new readings, without trusting a future observation timestamp.\n const current = Math.max(now, Date.now())\n const valid = validUsage(quota.usedPercent)\n const used = valid ? quota.usedPercent : 0\n const fresh = isUsageFresh(quota, { observedAt, stale }, current)\n // The cursor is where the window stands in time. It needs only the window's\n // own timing, so it stays for an unused, stale, aged or unobserved reading.\n const elapsed = elapsedPercent(quota, current)\n // Comparing usage with elapsed time is meaningful only while the percentage\n // is current; an old one is not set against today's clock.\n const pace = fresh ? elapsed : undefined\n const state = usageColorState(quota.usedPercent, pace, preset, fresh)\n const lead = pace === undefined ? 0 : Math.round(used - pace)\n const label = [\n valid ? t('usageMeterUsed', { used: Math.round(used), remaining: Math.round(100 - used) }) : t('usageMeterInvalid'),\n // An invalid reading already states unavailability; the stale line would repeat it.\n !valid ? '' : !fresh ? t('usageMeterStale') : state === 'red' ? t('usageMeterNearLimit')\n : pace === undefined && preset !== 'remaining' ? t('usageMeterUnknownTime')\n : state === 'yellow' ? t('usageMeterAhead') : t('usageMeterNoWarning'),\n elapsed === undefined ? '' : t('usageMeterPace', { elapsed: Math.round(elapsed) }),\n pace === undefined ? '' : lead > 0 ? t('usageMeterPaceAhead', { points: lead })\n : lead < 0 ? t('usageMeterPaceBehind', { points: -lead }) : t('usageMeterPaceEven'),\n quota.resetsAt !== undefined && quota.resetsAt > current ? t('usageMeterReset', {\n duration: resetCountdownParts(quota.resetsAt - current)\n .map(part => t(UNIT_KEYS[part.unit][part.count === 1 ? 0 : 1], { count: part.count }))\n .join(' '),\n }) : '',\n ].filter(Boolean).join(' · ')\n return <div role=\"img\" aria-label={label} title={label} data-usage-color={state} style={{\n height: 6, borderRadius: 3, overflow: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)', border: '1px solid var(--dsw-alias-border-l2)',\n ...style, position: 'relative',\n }}>\n <div style={{ height: '100%', borderRadius: 'inherit', width: `${used}%`,\n background: usageBarColor(quota.usedPercent, pace, preset, fresh) }} />\n {elapsed !== undefined && <span aria-hidden=\"true\" data-usage-time-marker style={{\n position: 'absolute', left: `clamp(0px, calc(${elapsed}% - 1px), calc(100% - 2px))`,\n top: 0, bottom: 0, width: 2, background: 'var(--dsw-alias-label-primary)',\n boxShadow: '0 0 0 1px var(--dsw-alias-bg-layer-1)',\n }} />}\n </div>\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ProviderUsage, SubscriptionsSectionInjected, UsageWindow } from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { subscriptionCardStyles as styles } from './subscription-card-styles.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\n\ntype Source = 'opencode-go' | 'kimi-code' | 'minimax' | 'minimax-cn'\ntype Translate = SubscriptionsSectionInjected['t']\n\nconst SOURCES: readonly { id: Source; name: string; ref: string }[] = [\n { id: 'opencode-go', name: 'OpenCode Go', ref: 'OPENCODE_GO_API_KEY' },\n { id: 'kimi-code', name: 'Kimi Code', ref: 'KIMI_CODING_API_KEY' },\n { id: 'minimax', name: 'MiniMax', ref: 'MINIMAX_API_KEY' },\n { id: 'minimax-cn', name: 'MiniMax CN', ref: 'MINIMAX_CN_API_KEY' },\n]\n\ntype Status = Record<Source, { configured: boolean }>\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Row label of one window on an external usage card. A session or weekly\n * window appends the model it belongs to when the provider names one (MiniMax\n * reports a window per model), so two models' weekly rows stay distinguishable.\n * The monthly pool is a scope on an `other` window, not a model.\n * @param t - section translate.\n * @param window - the reported window.\n * @returns the localized label, e.g. \"Weekly · general\".\n */\nexport function externalUsageWindowLabel(t: Translate, window: UsageWindow): string {\n const named = window.scope !== undefined && window.scope !== ''\n if (window.kind === 'other') {\n return window.scope === 'Monthly' ? t('usageMonthly') : named ? window.scope! : t('usageWindow')\n }\n const base = window.kind === 'session' ? t('usageSession') : t('usageWeekly')\n return named ? `${base} · ${window.scope}` : base\n}\n\n/** Quota cards for API-key providers already available through DSH itself. */\nexport function ExternalUsageCards({ rpc, t }: { rpc: ConnectionHandle['rpc']; t: Translate }) {\n const [status, setStatus] = useState<Status>()\n const [statusError, setStatusError] = useState<string>()\n const [usage, setUsage] = useState<Partial<Record<Source, ProviderUsage>>>({})\n const [observedAt, setObservedAt] = useState<Partial<Record<Source, number>>>({})\n const [errors, setErrors] = useState<Partial<Record<Source, string>>>({})\n const [loading, setLoading] = useState<Partial<Record<Source, boolean>>>({})\n\n const refresh = useCallback(async (source: Source) => {\n setLoading(prev => ({ ...prev, [source]: true }))\n try {\n const value = await callSubscriptionsAuth<ProviderUsage>(rpc, 'externalUsage', { source })\n setUsage(prev => ({ ...prev, [source]: value }))\n // Prefer the server's observation time; a cached reading must not look fresh.\n setObservedAt(prev => ({ ...prev, [source]: value.observedAt ?? Date.now() }))\n setErrors(prev => ({ ...prev, [source]: undefined }))\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n } catch (error) {\n setErrors(prev => ({ ...prev, [source]: errorText(error) }))\n } finally {\n setLoading(prev => ({ ...prev, [source]: false }))\n }\n }, [rpc])\n\n const refreshStatus = useCallback(async () => {\n try {\n const value = await callSubscriptionsAuth<Status>(rpc, 'externalStatus', {})\n setStatus(value)\n setStatusError(undefined)\n for (const { id } of SOURCES) if (value[id]?.configured) void refresh(id)\n } catch (error) { setStatusError(errorText(error)) }\n }, [rpc, refresh])\n\n useEffect(() => {\n void refreshStatus()\n }, [refreshStatus])\n\n return <>\n {SOURCES.map(({ id, name, ref }) => {\n const configured = status?.[id]?.configured === true\n const snapshot = usage[id]\n return <div key={id} style={styles.card}>\n <div style={styles.header}>\n <span style={{ ...styles.dot, background: configured\n ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-label-dimmed)' }} />\n <span style={styles.name}>{name}</span>\n </div>\n {!(status === undefined && statusError !== undefined) && <p style={styles.status}>\n {status === undefined ? t('checking')\n : configured ? t('externalUsageConnected') : t('externalUsageNotConfigured')}\n </p>}\n {statusError !== undefined && <p style={styles.error}>\n {t('externalUsageUnavailable', { message: statusError })}</p>}\n {status !== undefined && !configured && <p style={styles.status}>{t('externalUsageConfigure', { ref })}</p>}\n {configured && <div style={styles.account}>\n <div style={styles.accountHeader}>\n <span style={styles.defaultStar} title={t('defaultBadge')}>★</span>\n <span style={styles.accountName}>{t('externalUsageApiKey')}</span>\n </div>\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {snapshot?.plan !== undefined && <span style={styles.usagePlan}>{t('usagePlan', { plan: snapshot.plan })}</span>}\n <button type=\"button\" style={styles.usageRefresh} disabled={loading[id] === true}\n onClick={() => { void refresh(id) }}>{t('usageRefresh')}</button>\n </div>\n {loading[id] === true && snapshot === undefined && <p style={styles.status}>{t('usageLoading')}</p>}\n {errors[id] !== undefined && <p style={styles.error}>{t('usageError', { message: errors[id] })}</p>}\n {snapshot?.windows?.length === 0 && <p style={styles.status}>{t('usageEmpty')}</p>}\n {snapshot?.windows?.map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n const label = externalUsageWindowLabel(t, window)\n return <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{label}</span>\n <span>{percent === undefined ? t('usageMeterInvalid') : `${percent}%`}{window.resetsAt === undefined ? ''\n : ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}</span>\n </div>\n <UsageMeter window={window} t={t} observedAt={observedAt[id]} stale={errors[id] !== undefined || snapshot?.stale === true} />\n </div>\n })}\n </div>\n </div>}\n {!configured && <div style={styles.actions}>\n <button type=\"button\" style={styles.button} onClick={() => { void refreshStatus() }}>\n {t('usageRefresh')}\n </button>\n </div>}\n </div>\n })}\n </>\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ProviderUsage, SubscriptionsSectionInjected } from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { ProviderAccountManager } from './ProviderAccountManager.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { subscriptionCardStyles as styles } from './subscription-card-styles.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\n\ntype Translate = SubscriptionsSectionInjected['t']\ntype CursorStatus = { authenticated: boolean; busy: boolean; expiresAt?: number; error?: string }\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/** Cursor's single connected account, rendered with the same card and Manage dialog as the other providers. */\nexport function CursorCard({ rpc, t }: { rpc: ConnectionHandle['rpc']; t: Translate }) {\n const [status, setStatus] = useState<CursorStatus>()\n const [usage, setUsage] = useState<ProviderUsage>()\n const [observedAt, setObservedAt] = useState<number>()\n const [usageStale, setUsageStale] = useState(false)\n const [authorizeUrl, setAuthorizeUrl] = useState<string>()\n const [error, setError] = useState<string>()\n const [loading, setLoading] = useState(false)\n const [manage, setManage] = useState(false)\n const authenticated = useRef<boolean>()\n\n const refreshStatus = useCallback(async () => {\n try {\n const value = await callSubscriptionsAuth<CursorStatus>(rpc, 'cursorStatus', {})\n setStatus(value)\n if (authenticated.current !== value.authenticated) {\n authenticated.current = value.authenticated\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n }\n if (value.authenticated) setAuthorizeUrl(undefined)\n if (value.error) setError(value.error)\n } catch (failure) { setError(message(failure)) }\n }, [rpc])\n\n const refreshUsage = useCallback(async () => {\n setLoading(true)\n try {\n const value = await callSubscriptionsAuth<ProviderUsage>(rpc, 'cursorUsage', {})\n setUsage(value)\n // Prefer the server's observation time; a cached reading must not look fresh.\n setObservedAt(value.observedAt ?? Date.now())\n setUsageStale(value.stale === true)\n setError(undefined)\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n } catch (failure) { setError(message(failure)); setUsageStale(true) }\n finally { setLoading(false) }\n }, [rpc])\n\n useEffect(() => { void refreshStatus() }, [refreshStatus])\n useEffect(() => {\n if (status?.busy !== true) return\n const timer = setInterval(() => { void refreshStatus() }, 2000)\n return () => clearInterval(timer)\n }, [status?.busy, refreshStatus])\n useEffect(() => { if (status?.authenticated === true) void refreshUsage() }, [status?.authenticated, refreshUsage])\n\n const login = async () => {\n setError(undefined)\n try {\n const value = await callSubscriptionsAuth<{ authorizeUrl: string }>(rpc, 'cursorLogin', {})\n setAuthorizeUrl(value.authorizeUrl)\n window.open(value.authorizeUrl, '_blank', 'noopener')\n await refreshStatus()\n } catch (failure) { setError(message(failure)) }\n }\n const cancel = async () => {\n try {\n await callSubscriptionsAuth(rpc, 'cursorCancel', {})\n setAuthorizeUrl(undefined)\n await refreshStatus()\n } catch (failure) { setError(message(failure)) }\n }\n const logout = async () => {\n if (!window.confirm(t('logoutAccountConfirm', { account: 'Cursor', provider: 'Cursor' }))) return\n try {\n await callSubscriptionsAuth(rpc, 'cursorLogout', {})\n setUsage(undefined)\n setObservedAt(undefined)\n setUsageStale(false)\n await refreshStatus()\n } catch (failure) { setError(message(failure)) }\n }\n\n const connected = status?.authenticated === true\n return <div style={styles.card}>\n <div style={styles.header}>\n <span style={{ ...styles.dot, background: status?.busy ? 'var(--dsw-alias-state-warn-label)'\n : connected ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-label-dimmed)' }} />\n <span style={styles.name}>{t('cursorTitle')}</span>\n </div>\n <p style={styles.status}>{status === undefined ? t('checking') : status.busy ? t('loginInProgress')\n : connected ? t('loggedInCount', { count: 1 }) : t('notLoggedIn')}</p>\n {error !== undefined && <p style={styles.error}>{error}</p>}\n {connected && <div style={styles.account}>\n <div style={styles.accountHeader}>\n <span style={styles.defaultStar} title={t('defaultBadge')}>★</span>\n <span style={styles.accountName}>Cursor</span>\n {status.expiresAt !== undefined && <span style={styles.status}>\n {t('accountExpires', { date: new Date(status.expiresAt).toLocaleString() })}</span>}\n <button type=\"button\" style={{ ...styles.button, marginLeft: 'auto', flexShrink: 0 }}\n onClick={() => { void logout() }}>{t('logout')}</button>\n </div>\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {usage?.plan !== undefined && <span style={styles.status}>{t('usagePlan', { plan: usage.plan })}</span>}\n <button type=\"button\" style={styles.usageRefresh} disabled={loading}\n onClick={() => { void refreshUsage() }}>{t('usageRefresh')}</button>\n </div>\n {loading && usage === undefined && <p style={styles.status}>{t('usageLoading')}</p>}\n {usage?.windows?.length === 0 && <p style={styles.status}>{t('usageEmpty')}</p>}\n {usage?.windows?.map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n const label = window.scope === 'Included' ? t('cursorIncluded')\n : window.scope === 'Cursor Models' ? t('cursorModels')\n : window.scope === 'Other Models' ? t('cursorOtherModels')\n : window.scope === 'Included requests' ? t('cursorIncludedRequests')\n : window.scope ?? t('usageWindow')\n return <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{label}</span>\n <span>{percent === undefined ? t('usageMeterInvalid') : `${percent}%`}{window.resetsAt === undefined ? ''\n : ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}</span>\n </div>\n <UsageMeter window={window} t={t} observedAt={observedAt} stale={usageStale} />\n </div>\n })}\n </div>\n </div>}\n <div style={styles.actions}>\n {status?.authenticated === false && !status.busy && <button type=\"button\" style={styles.button}\n onClick={() => { void login() }}>{t('login')}</button>}\n <button type=\"button\" style={styles.button} aria-haspopup=\"dialog\" onClick={() => setManage(true)}>\n {t('accountsManage')}\n </button>\n {status?.busy === true && <button type=\"button\" style={styles.button}\n onClick={() => { void cancel() }}>{t('cancel')}</button>}\n </div>\n {status?.busy === true && authorizeUrl !== undefined && <a href={authorizeUrl}\n target=\"_blank\" rel=\"noopener noreferrer\">{t('cursorOpenLogin')}</a>}\n {manage && <ProviderAccountManager provider=\"cursor-subscription\" name=\"Cursor\" rpc={rpc} t={t}\n onClose={() => setManage(false)} />}\n </div>\n}\n","/**\n * Shared usage-limit-reset disclosure.\n *\n * Codex and Claude use the same closed `<details>` row. Codex may offer Use\n * on the earliest unexpired credit. Claude is read-only: `claimable` is\n * server metadata and never becomes a control. `expiresAt` is when the grant\n * expires, not a window reset, so it is never passed to the elapsed-time\n * cursor.\n */\nimport type { SubscriptionsKey } from './locales.js'\nimport { subscriptionCardStyles as cardStyles } from './subscription-card-styles.js'\nimport type { ResetCreditView, SubscriptionsSectionInjected } from './SubscriptionsSection.js'\n\ntype Translate = SubscriptionsSectionInjected['t']\n\n/** How one grant reads. Color is not the only carrier; the state word is in the row name. */\nexport type ResetCreditState = 'available' | 'notUsable' | 'paused' | 'exhausted' | 'expired'\n\nconst STATE_KEYS: Record<ResetCreditState, SubscriptionsKey> = {\n available: 'resetCreditAvailable',\n notUsable: 'resetCreditNotUsable',\n paused: 'resetCreditPaused',\n exhausted: 'resetCreditExhausted',\n expired: 'resetCreditExpired',\n}\n\n/**\n * Classify one grant. Expired outranks every other flag. A future\n * `cooldownUntil` or `usableNow: false` is not usable even when `claimable`\n * is true. `claimable` does not change the word: it is not an action.\n */\nexport function resetCreditState(credit: ResetCreditView, now: number): ResetCreditState {\n if (credit.expiresAt !== undefined && credit.expiresAt <= now) return 'expired'\n if (credit.paused === true) return 'paused'\n if (credit.resetsLeft === 0) return 'exhausted'\n if ((credit.cooldownUntil !== undefined && credit.cooldownUntil > now) || credit.usableNow === false) return 'notUsable'\n return 'available'\n}\n\n/**\n * Headline count. Codex passes one entry per credit, so the count is the\n * list length. Claude passes one entry per grant, so the count is the sum of\n * `resetsLeft` on grants that are neither expired nor paused. A missing\n * `resetsLeft` adds nothing; the row says the count is unavailable.\n */\nexport function resetCreditsAvailableCount(\n credits: readonly ResetCreditView[],\n now: number,\n mode: 'credits' | 'grants',\n): number {\n if (mode === 'credits') return credits.length\n let sum = 0\n for (const credit of credits) {\n const state = resetCreditState(credit, now)\n if (state === 'expired' || state === 'paused') continue\n if (typeof credit.resetsLeft === 'number' && Number.isFinite(credit.resetsLeft) && credit.resetsLeft > 0) {\n sum += credit.resetsLeft\n }\n }\n return sum\n}\n\n/** Codex Use control. Absent for Claude, which must not render a button. */\nexport interface ResetCreditUseAction {\n accountKey: string\n busy: boolean\n disabled: boolean\n title: string\n label: string\n onUse: () => void\n}\n\nfunction expiryText(t: Translate, credit: ResetCreditView): string {\n return credit.expiresAt === undefined\n ? t('resetCreditExpiryUnknown')\n : t('resetCreditExpires', { date: new Date(credit.expiresAt).toLocaleString() })\n}\n\nfunction remainingText(t: Translate, credit: ResetCreditView): string {\n const left = credit.resetsLeft\n const total = credit.resetsTotal\n const hasLeft = typeof left === 'number' && Number.isFinite(left)\n const hasTotal = typeof total === 'number' && Number.isFinite(total)\n if (hasLeft && hasTotal) return t('resetCreditRemaining', { left, total })\n if (hasLeft) return t('resetCreditLeft', { left })\n return t('resetCreditRemainingUnknown')\n}\n\n/** Accessible name of one Claude grant row: state, remaining, and expiry, not a control name. */\nexport function resetCreditRowName(t: Translate, credit: ResetCreditView, now: number): string {\n const state = resetCreditState(credit, now)\n const parts = [t('resetCreditFull'), t(STATE_KEYS[state]), remainingText(t, credit), expiryText(t, credit)]\n if (state === 'notUsable' && credit.cooldownUntil !== undefined && credit.cooldownUntil > now) {\n parts.push(t('resetCreditCooldownUntil', { date: new Date(credit.cooldownUntil).toLocaleString() }))\n }\n return parts.join(', ')\n}\n\n/** Claude omits an empty grant list; Codex still shows a defined, possibly empty, list. */\nexport function showsResetCredits(\n provider: 'codex' | 'claude',\n credits: readonly ResetCreditView[] | undefined,\n): boolean {\n if (provider === 'codex') return credits !== undefined\n return (credits?.length ?? 0) > 0\n}\n\n/** The error line the settings card mounts. Claude never interpolates provider text. */\nexport function ResetCreditsErrorLine({ provider, message, t }: {\n provider: 'codex' | 'claude'\n message: string\n t: Translate\n}) {\n return <p style={cardStyles.error}>{resetCreditsErrorText(provider, message, t)}</p>\n}\n\n/** Fixed sentence for Claude. Codex may include the lookup message; Claude must not. */\nexport function resetCreditsErrorText(\n provider: 'codex' | 'claude',\n message: string,\n t: Translate,\n): string {\n return provider === 'claude' ? t('resetCreditsErrorFixed') : t('resetCreditsError', { message })\n}\n\nconst summaryStyle = {\n ...cardStyles.usageMeta, cursor: 'pointer', listStyle: 'none', justifyContent: 'flex-start', gap: 6,\n} as const\n\n/**\n * The closed disclosure both providers share. Claude rows are plain text:\n * no button, no `role=\"button\"`, and `cursor: default`, including when\n * `claimable` is true.\n */\nexport function ResetCreditsDisclosure({\n mode,\n credits,\n t,\n now = Date.now(),\n nextCredit,\n useAction,\n statusMessage,\n}: {\n mode: 'credits' | 'grants'\n credits: readonly ResetCreditView[]\n t: Translate\n now?: number\n nextCredit?: ResetCreditView\n useAction?: ResetCreditUseAction\n statusMessage?: string\n}) {\n const count = resetCreditsAvailableCount(credits, now, mode)\n return (\n <details className=\"subscriptions-reset-credits\" style={cardStyles.usageRow}>\n <summary style={summaryStyle}>\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" style={{ flexShrink: 0 }}>\n <path d=\"m6 3 5 5-5 5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n <span>{t('resetCreditsTitle')}</span>\n {mode === 'grants' && <span>{t('resetCreditReadOnlyLabel')}</span>}\n <span style={{ marginLeft: 'auto' }}>{t('resetCreditsAvailable', { count })}</span>\n </summary>\n <style>{\n '.subscriptions-reset-credits > summary::-webkit-details-marker { display: none; }'\n + '.subscriptions-reset-credits[open] > summary > svg { transform: rotate(90deg); }'\n }</style>\n <div style={{ paddingLeft: 18, marginTop: 6 }}>\n {mode === 'grants' && <p style={cardStyles.status}>{t('resetCreditReadOnly')}</p>}\n {credits.map((credit, index) => {\n const state = resetCreditState(credit, now)\n const showUse = mode === 'credits' && useAction !== undefined && credit === nextCredit\n return (\n <div\n key={credit.id ?? index}\n data-reset-state={mode === 'grants' ? state : undefined}\n data-reset-claimable={mode === 'grants' && credit.claimable === true ? 'true' : undefined}\n role={mode === 'grants' ? 'group' : undefined}\n aria-label={mode === 'grants' ? resetCreditRowName(t, credit, now) : undefined}\n style={{ ...cardStyles.usageMeta, minHeight: 28, gap: 12, cursor: mode === 'grants' ? 'default' : undefined }}\n >\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>\n {t('resetCreditFull')}\n {mode === 'grants' && (\n <span aria-hidden=\"true\" data-reset-state-word={state}>{t(STATE_KEYS[state])}</span>\n )}\n {showUse && (\n <button type=\"button\" aria-disabled={useAction.disabled}\n title={useAction.title}\n style={{ minHeight: 22, height: 22, padding: '0 7px', borderRadius: 6,\n opacity: useAction.disabled ? 0.35 : 1, cursor: useAction.disabled ? 'not-allowed' : 'pointer' }}\n onClick={() => { if (!useAction.disabled) useAction.onUse() }}>\n {useAction.busy ? t('resetUseChecking') : useAction.label}\n </button>\n )}\n </span>\n <span style={{ textAlign: 'right' }}>\n {mode === 'grants' && <span aria-hidden=\"true\">{remainingText(t, credit)} · </span>}\n {mode === 'grants' && state === 'notUsable' && credit.cooldownUntil !== undefined && credit.cooldownUntil > now && (\n <span aria-hidden=\"true\">{t('resetCreditCooldownUntil', { date: new Date(credit.cooldownUntil).toLocaleString() })} · </span>\n )}\n <span aria-hidden={mode === 'grants' ? true : undefined}>{expiryText(t, credit)}</span>\n </span>\n </div>\n )\n })}\n {statusMessage !== undefined && statusMessage !== '' && <p role=\"status\" style={cardStyles.status}>{statusMessage}</p>}\n </div>\n </details>\n )\n}\n","import { useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { SubscriptionsKey } from './locales.js'\nimport { setUsageBadgeMode, useUsageBadgeMode } from './usage-badge-preferences.js'\nimport { isUsageColorPreset, setUsageColorPreset, useUsageColorPreset } from './usage-color-preferences.js'\n\ntype Translate = (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n\n/** Browser-local display preference; never changes provider or account settings. */\nexport function UsageBadgeDisplaySetting({ t }: { t: Translate }) {\n const mode = useUsageBadgeMode()\n const preset = useUsageColorPreset()\n const [failed, setFailed] = useState(false)\n return (\n <div style={styles.card}>\n <label style={styles.field}>\n <span>{t('usageBadgeDisplay')}</span>\n <select\n style={styles.select}\n aria-label={t('usageBadgeDisplay')}\n value={mode}\n onChange={event => {\n const value = event.currentTarget.value\n if (value !== 'recent' && value !== 'always' && value !== 'hidden') return\n try {\n setUsageBadgeMode(value)\n setFailed(false)\n } catch (error) {\n if (!(error instanceof DOMException) || !['SecurityError', 'QuotaExceededError'].includes(error.name)) throw error\n setFailed(true)\n }\n }}\n >\n <option value=\"recent\">{t('usageBadgeDisplayRecent')}</option>\n <option value=\"always\">{t('usageBadgeDisplayAlways')}</option>\n <option value=\"hidden\">{t('usageBadgeDisplayHidden')}</option>\n </select>\n </label>\n <p style={styles.hint}>{t('usageBadgeDisplayHint')}</p>\n <label style={styles.field}>\n <span>{t('usageColorLabel')}</span>\n <select style={styles.select} aria-label={t('usageColorLabel')} value={preset}\n onChange={event => {\n const value = event.currentTarget.value\n if (!isUsageColorPreset(value)) return\n try { setUsageColorPreset(value); setFailed(false) }\n catch (error) {\n if (!(error instanceof DOMException) || !['SecurityError', 'QuotaExceededError'].includes(error.name)) throw error\n setFailed(true)\n }\n }}>\n <option value=\"standard\">{t('usageColorStandard')}</option>\n <option value=\"relaxed\">{t('usageColorRelaxed')}</option>\n <option value=\"remaining\">{t('usageColorRemaining')}</option>\n </select>\n </label>\n <p style={styles.hint}>{t(preset === 'remaining' ? 'usageColorRemainingHint' : 'usageColorPaceHint', {\n allowance: preset === 'relaxed' ? 15 : 10,\n })}</p>\n {failed && <p role=\"alert\" style={{ ...styles.hint, color: 'var(--dsw-alias-state-error-primary)' }}>{t('usageBadgeDisplaySaveFailed')}</p>}\n </div>\n )\n}\n\nconst styles: Record<string, CSSProperties> = {\n card: {\n border: '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',\n borderRadius: 'var(--dsw-radius-xl, 20px)', background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',\n padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 6,\n },\n field: { display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13, fontWeight: 500, lineHeight: '20px' },\n select: { width: '100%' },\n hint: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' },\n}\n","/**\n * Subscriptions settings section: one card per subscription provider with an\n * OAuth login/logout flow driven by the node half's\n * `/api/subscriptions-auth.<endpoint>` RPC routes. Login state lives server-side; the page polls `status` only while\n * a login attempt is busy, so an idle page never polls. All state is local\n * React state — the page has no store.\n *\n * Every color resolves through a `--dsw-alias-*` design token (the ui-theme\n * design-platform.css values flip under `body[data-ds-dark-theme]`), and\n * every user-visible string goes through the locale-bound `t` of the\n * 'settings.subscriptions' namespace. Buttons and inputs take the\n * native settings vocabulary with shared, scoped control states.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport { en } from './locales.js'\nimport { resetActionBlock } from './reset-action.js'\nimport { ProviderAccountManager } from './ProviderAccountManager.js'\nimport { providerSettingsCss } from './provider-settings-styles.js'\nimport { ExternalUsageCards } from './ExternalUsageCards.js'\nimport { CursorCard } from './CursorCard.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { ResetCreditsDisclosure, ResetCreditsErrorLine, showsResetCredits } from './reset-credits-view.js'\nimport { displayUsedPercent } from './usage-pace.js'\nimport { UsageBadgeDisplaySetting } from './UsageBadgeDisplaySetting.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { subscriptionCardStyles as cardStyles } from './subscription-card-styles.js'\nimport type { SubscriptionsKey } from './locales.js'\n\nimport { callSubscriptionsAuth, SubscriptionsAuthError } from './subscriptions-rpc.js'\nexport { callSubscriptionsAuth } from './subscriptions-rpc.js'\n\n/** Poll cadence while a provider login attempt is busy. */\nconst POLL_INTERVAL_MS = 2000\n\n/** Subscription provider ids, fixed by the node half's OAuth adapters. */\nexport type SubscriptionProvider = 'codex' | 'claude' | 'grok' | 'copilot' | 'antigravity'\n\n/** One logged-in account as answered by the `status` endpoint. */\nexport interface AccountStatus {\n key: string\n account?: string\n expiresAt?: number\n plan?: string\n isDefault: boolean\n}\n\n/** One provider's login state as answered by the `status` endpoint. */\nexport interface ProviderStatus {\n busy: boolean\n accounts: AccountStatus[]\n detail?: string\n /** The CLI version the route presents (Codex, Claude), and where it came from. */\n clientVersion?: { version: string; source: ClientVersionSource }\n}\n\n/** Where a presented CLI version came from; the tag names the source so a stale one is visible. */\nexport type ClientVersionSource = 'npm' | 'local' | 'fallback' | 'config'\n\nconst CLIENT_VERSION_SOURCES: Record<ClientVersionSource, SubscriptionsKey> = {\n npm: 'clientVersionNpm',\n local: 'clientVersionLocal',\n fallback: 'clientVersionFallback',\n config: 'clientVersionConfig',\n}\n\n/** `status` endpoint value: the node half owns this shape. */\ninterface StatusResponse {\n providers: Record<SubscriptionProvider, ProviderStatus>\n}\n\n/** One rate-limit window as answered by the `usage` endpoint. */\nexport interface UsageWindow {\n kind: 'session' | 'weekly' | 'other'\n scope?: string\n usedPercent: number\n resetsAt?: number\n startsAt?: number\n windowDurationMs?: number\n fixedWindow?: boolean\n}\n\n/** `usage` endpoint value: the node half owns this shape. */\nexport interface ProviderUsage {\n observedAt?: number\n stale?: boolean\n supported: boolean\n windows?: UsageWindow[]\n plan?: string\n /**\n * Banked limit-reset grants. Codex entries carry id/expiry only. Claude\n * entries are one row per grant: `expiresAt` is when the grant expires, not\n * a window reset, and `resetsLeft` is the remaining credit count.\n */\n resetCredits?: ResetCreditView[]\n resetCreditsError?: string\n}\n\n/** One banked reset grant as the usage RPC returns it. */\nexport interface ResetCreditView {\n id?: string\n grantedAt?: number\n /** Epoch milliseconds when the grant expires. Never a periodic window reset. */\n expiresAt?: number\n resetsTotal?: number\n resetsLeft?: number\n usableNow?: boolean\n paused?: boolean\n /** Server metadata only. Claude has no redemption control. */\n claimable?: boolean\n /** Epoch milliseconds until which the grant is visible but not usable. */\n cooldownUntil?: number\n}\n\n/** `login` endpoint value: the URL the user completes OAuth at. */\ninterface LoginResponse {\n authorizeUrl: string\n /** Device-flow providers (copilot): the code the user types at authorizeUrl. */\n userCode?: string\n}\n\n/** Injected dependencies of {@link SubscriptionsSection} (slot `inject`). */\nexport interface SubscriptionsSectionInjected {\n /** Generic logical-RPC caller over the Connection transport. */\n rpc: ConnectionHandle['rpc']\n /** Section copy: translate a 'settings.subscriptions' key with `{name}` template params. */\n t: (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n}\n\n/**\n * Props delivered by the slot outlet: the inject face spread flat (the\n * renderer erases the share boundary at the render call).\n */\nexport type SubscriptionsSectionProps = Partial<SubscriptionsSectionInjected>\n\n/** Card display metadata, in page order (names are brand names, not translated). */\nconst PROVIDERS: readonly { id: SubscriptionProvider; name: string }[] = [\n { id: 'codex', name: 'Codex (ChatGPT)' },\n { id: 'claude', name: 'Claude' },\n { id: 'grok', name: 'Grok (X Premium)' },\n { id: 'copilot', name: 'GitHub Copilot' },\n { id: 'antigravity', name: 'Google Antigravity' },\n]\n\n/** Human text of an action failure, SubscriptionsAuthError or not. */\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/** Copy a keyed map without the entries whose key is not in `live`. */\nfunction dropStale<T>(map: Record<string, T>, live: ReadonlySet<string>): Record<string, T> {\n const stale = Object.keys(map).filter(key => !live.has(key))\n if (stale.length === 0) return map\n const next = { ...map }\n for (const key of stale) delete next[key]\n return next\n}\n\n/**\n * English-dictionary fallback for a missing inject `t` (standalone renders);\n * the slot inject always supplies the locale-bound one.\n * @param key - dictionary key.\n * @param params - `{name}` template params.\n * @returns the template with params substituted.\n */\nfunction fallbackTranslate(key: SubscriptionsKey, params?: Record<string, unknown>): string {\n let text: string = en[key]\n for (const [name, value] of Object.entries(params ?? {})) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\nconst styles: Record<string, CSSProperties> = {\n section: {\n display: 'flex', flexDirection: 'column', gap: 12, maxWidth: 560,\n color: 'var(--dsw-alias-label-primary)',\n },\n intro: { margin: 0, color: 'var(--dsw-alias-label-tertiary)', fontSize: 14, lineHeight: '22px' },\n card: { ...cardStyles.card,\n border: '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',\n borderRadius: 'var(--dsw-radius-xl, 20px)', background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',\n },\n cardHeader: cardStyles.header,\n dot: cardStyles.dot,\n name: cardStyles.name,\n statusLine: cardStyles.status,\n clientVersion: { fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)', fontVariantNumeric: 'tabular-nums' },\n errorLine: cardStyles.error,\n actions: cardStyles.actions,\n usage: { ...cardStyles.usage, borderTop: '0.5px solid var(--dsw-alias-border-l2)' },\n usageHeader: cardStyles.usageHeader,\n usageTitle: cardStyles.usageTitle,\n usagePlan: cardStyles.usagePlan,\n usageRefresh: { minHeight: 22, height: 22, padding: '0 8px', marginLeft: 'auto' },\n usageRow: cardStyles.usageRow,\n usageMeta: cardStyles.usageMeta,\n accountRow: { ...cardStyles.account, border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)' },\n accountHeader: cardStyles.accountHeader,\n accountName: cardStyles.accountName,\n starButton: {\n border: 'none', padding: 0, width: 28,\n font: 'inherit', fontSize: 14, lineHeight: '20px', cursor: 'pointer',\n color: 'var(--dsw-alias-state-warn-label)',\n },\n deviceCode: {\n marginTop: 4, display: 'flex', flexDirection: 'column', gap: 6,\n border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)',\n padding: '10px 12px', background: 'var(--dsw-alias-bg-layer-1)',\n },\n deviceCodeText: {\n fontFamily: 'monospace', fontSize: 18, lineHeight: '24px', letterSpacing: 2,\n color: 'var(--dsw-alias-label-primary)', userSelect: 'all',\n },\n manual: { fontSize: 13, lineHeight: '20px' },\n manualRow: { display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', marginTop: 8 },\n manualInput: { flex: '1 1 200px', minWidth: 0 },\n modalOverlay: {\n position: 'fixed', inset: 0, zIndex: 1000,\n display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16,\n background: 'var(--dsw-alias-bg-mask-1, #0006)', backdropFilter: 'var(--dsw-mask-blur, none)',\n },\n modal: {\n width: 460, maxWidth: '100%', maxHeight: '90vh', overflowY: 'auto',\n boxSizing: 'border-box', display: 'flex', flexDirection: 'column', gap: 12,\n padding: '16px 18px', borderRadius: 'var(--dsw-radius-panel, 28px)',\n background: 'var(--dsw-alias-bg-layer-2)', border: 0, boxShadow: 'var(--dsw-elevation-prominent)',\n },\n modalHeader: { display: 'flex', alignItems: 'center', gap: 8 },\n modalTitle: { fontWeight: 500, fontSize: 16, lineHeight: '24px', color: 'var(--dsw-alias-label-primary)' },\n}\n\n/** Status dot color for one provider state. */\nfunction dotColor(status: ProviderStatus | undefined): string {\n if (status?.busy === true) return 'var(--dsw-alias-state-warn-label)'\n if ((status?.accounts.length ?? 0) > 0) return 'var(--dsw-alias-state-success-primary)'\n return 'var(--dsw-alias-label-dimmed)'\n}\n\n/**\n * Whether a provider has at least one connected account. Multi-account made\n * \"logged in\" a property of the account list rather than a flag, so every\n * logged-in test goes through this one predicate.\n * @param status - the provider's last reported state, possibly absent.\n * @returns true when the provider serves at least one account.\n */\nfunction hasAccount(status: ProviderStatus | undefined): boolean {\n return (status?.accounts.length ?? 0) > 0\n}\n\n/**\n * One-line status text for one provider state.\n * @param t - section translate.\n * @param status - the provider's last reported state.\n * @returns the localized status line.\n */\nfunction statusText(t: SubscriptionsSectionInjected['t'], status: ProviderStatus | undefined): string {\n if (status === undefined) return t('checking')\n if (status.busy) return t('loginInProgress')\n if (status.accounts.length > 0) return t('loggedInCount', { count: status.accounts.length })\n return t('notLoggedIn')\n}\n\n/**\n * The CLI version a route presents, beside the provider name; nothing for\n * routes without one. The source word (npm / local / built-in / configured)\n * is the fix for upstream issue #108: a failed npm lookup must read as a\n * fallback, never as a plan limit.\n */\nexport function clientVersionText(\n t: SubscriptionsSectionInjected['t'],\n clientVersion: ProviderStatus['clientVersion'],\n): string {\n if (clientVersion === undefined) return ''\n return t('clientVersion', { version: clientVersion.version, source: t(CLIENT_VERSION_SOURCES[clientVersion.source]) })\n}\n\n/**\n * Localized label of one usage window (kind, plus the model scope when named).\n * @param t - section translate.\n * @param window - the reported window.\n * @returns e.g. \"5-hour window\" or \"Weekly · Opus\".\n */\nfunction usageWindowLabel(t: SubscriptionsSectionInjected['t'], window: UsageWindow): string {\n const base = window.kind === 'session'\n ? t('usageSession')\n : window.kind === 'weekly' ? t('usageWeekly') : t('usageWindow')\n return window.scope !== undefined && window.scope !== '' ? `${base} · ${window.scope}` : base\n}\n\n/** Meter fill color lives with the pace logic: fresh 90%+ is red, pace presets add a yellow lead threshold. */\nexport { usageBarColor } from './usage-pace.js'\n\n/**\n * The Subscriptions settings page component.\n * @param props - the slot inject face ({@link SubscriptionsSectionInjected}).\n * @returns the section body, or a notice while the RPC face is absent.\n */\nexport function SubscriptionsSection(props: SubscriptionsSectionProps) {\n const { rpc } = props\n const t = props.t ?? fallbackTranslate\n const [statuses, setStatuses] = useState<Partial<Record<SubscriptionProvider, ProviderStatus>>>({})\n const [errors, setErrors] = useState<Partial<Record<SubscriptionProvider, string>>>({})\n const [manualDrafts, setManualDrafts] = useState<Record<SubscriptionProvider, string>>({\n codex: '', claude: '', grok: '', copilot: '', antigravity: '',\n })\n /** Pending device-flow codes (copilot), shown while the attempt polls. */\n const [deviceCodes, setDeviceCodes] = useState<Partial<Record<SubscriptionProvider, { userCode: string; verificationUrl: string }>>>({})\n const [copiedCode, setCopiedCode] = useState<SubscriptionProvider | undefined>(undefined)\n /** Usage snapshots keyed `${provider}:${accountKey}` — every account tracks its own windows. */\n const [usages, setUsages] = useState<Record<string, ProviderUsage>>({})\n const [observedAt, setObservedAt] = useState<Record<string, number>>({})\n const [usageErrors, setUsageErrors] = useState<Record<string, string>>({})\n const [usageLoading, setUsageLoading] = useState<Record<string, boolean>>({})\n const [resetConfirmation, setResetConfirmation] = useState<{ account: string; ticket: string; expiresAt: number; creditExpiresAt?: number; weeklyUsedPercent: number }>()\n const [resetBusy, setResetBusy] = useState(false)\n const [resetAcknowledged, setResetAcknowledged] = useState(false)\n const [resetMessage, setResetMessage] = useState('')\n const [resetAccount, setResetAccount] = useState<string>()\n const resetDialogRef = useRef<HTMLDialogElement>(null)\n useEffect(() => {\n if (resetConfirmation) resetDialogRef.current?.showModal()\n else resetDialogRef.current?.close()\n }, [resetConfirmation])\n const resetInflight = useRef(false)\n const mountedRef = useRef(true)\n const pollersRef = useRef(new Map<SubscriptionProvider, ReturnType<typeof setInterval>>())\n /** Accounts with a `usage` call in flight; guards the auto-fetch effect against re-entry. */\n /** In-flight usage reads per key, holding the promise so a forced read can wait one out. */\n const usageInflightRef = useRef(new Map<string, Promise<void>>())\n const usageRosterSignatureRef = useRef<string>()\n const [managedProvider, setManagedProvider] = useState<{ id: SubscriptionProvider; name: string }>()\n const setProviderError = useCallback((provider: SubscriptionProvider, message: string | undefined): void => {\n if (!mountedRef.current) return\n setErrors((prev) => {\n const next = { ...prev }\n if (message === undefined) delete next[provider]\n else next[provider] = message\n return next\n })\n }, [])\n\n const stopPolling = useCallback((provider: SubscriptionProvider): void => {\n const poller = pollersRef.current.get(provider)\n if (poller !== undefined) {\n clearInterval(poller)\n pollersRef.current.delete(provider)\n }\n }, [])\n\n /** Refetch every provider's status; stop a provider's poller once its attempt settles. */\n const refresh = useCallback(async (): Promise<void> => {\n if (rpc === undefined) return\n let response: StatusResponse\n try {\n response = await callSubscriptionsAuth<StatusResponse>(rpc, 'status', {})\n } catch (error) {\n // A failed poll must not kill the page; busy providers keep polling and\n // the action paths report their own errors. But staying silent turns a\n // persistent failure into an endless \"Checking…\" — show it instead.\n const message = error instanceof Error ? error.message : String(error)\n for (const { id } of PROVIDERS) setProviderError(id, message)\n return\n }\n if (!mountedRef.current) return\n setStatuses(response.providers)\n const signature = PROVIDERS.map(({ id }) => `${id}:${response.providers[id].accounts\n .map(account => `${account.key}:${account.isDefault}`).join(',')}`).join(';')\n if (signature !== usageRosterSignatureRef.current) {\n usageRosterSignatureRef.current = signature\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n }\n // The poll recovered: drop any error line a previous failed poll left.\n for (const { id } of PROVIDERS) setProviderError(id, undefined)\n for (const { id } of PROVIDERS) {\n const status = response.providers[id]\n if (status.accounts.length > 0 || !status.busy) {\n stopPolling(id)\n // The attempt settled (success, timeout, or cancel): drop the code card.\n setDeviceCodes((prev) => {\n if (prev[id] === undefined) return prev\n const next = { ...prev }\n delete next[id]\n return next\n })\n }\n }\n }, [rpc, stopPolling, setProviderError])\n\n const startPolling = useCallback((provider: SubscriptionProvider): void => {\n if (pollersRef.current.has(provider)) return\n pollersRef.current.set(provider, setInterval(() => { void refresh() }, POLL_INTERVAL_MS))\n }, [refresh])\n\n // Initial load; every busy provider (e.g. an attempt started before a page\n // reload) resumes polling. Teardown clears pollers and the mounted guard.\n useEffect(() => {\n mountedRef.current = true\n void refresh().then(() => {\n if (!mountedRef.current) return\n setStatuses((current) => {\n for (const { id } of PROVIDERS) {\n if (current[id]?.busy === true) startPolling(id)\n }\n return current\n })\n })\n return () => {\n mountedRef.current = false\n for (const poller of pollersRef.current.values()) clearInterval(poller)\n pollersRef.current.clear()\n }\n }, [refresh, startPolling])\n\n const loadUsage = useCallback(async (provider: SubscriptionProvider, account: string, force = false): Promise<void> => {\n if (rpc === undefined) return\n const key = `${provider}:${account}`\n const pending = usageInflightRef.current.get(key)\n // A forced read must never be dropped behind a poll that started before the\n // state changed. The refresh after a credit redemption is the only thing\n // that picks up the new numbers, and the next automatic poll is minutes\n // away, so waiting the earlier read out is cheaper than showing a stale\n // percentage next to a success message.\n if (pending !== undefined) {\n if (!force) return\n await pending\n }\n if (rpc === undefined || usageInflightRef.current.has(key)) return\n const read = (async () => {\n setUsageLoading(prev => ({ ...prev, [key]: true }))\n try {\n const usage = await callSubscriptionsAuth<ProviderUsage>(rpc, 'usage', { provider, account, ...force ? { force: true } : {} })\n if (!mountedRef.current) return\n setUsages(prev => ({ ...prev, [key]: usage }))\n setObservedAt(prev => ({ ...prev, [key]: usage.observedAt ?? Date.now() }))\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n setUsageErrors((prev) => {\n const next = { ...prev }\n delete next[key]\n return next\n })\n } catch (error) {\n if (mountedRef.current) setUsageErrors(prev => ({ ...prev, [key]: messageOf(error) }))\n } finally {\n usageInflightRef.current.delete(key)\n if (mountedRef.current) setUsageLoading(prev => ({ ...prev, [key]: false }))\n }\n })()\n usageInflightRef.current.set(key, read)\n await read\n }, [rpc])\n\n async function prepareReset(account: string): Promise<void> {\n if (!rpc || resetInflight.current) return\n resetInflight.current = true\n setResetBusy(true)\n setResetAccount(account)\n setResetConfirmation(undefined)\n setResetMessage('')\n try {\n const result = await callSubscriptionsAuth<Omit<NonNullable<typeof resetConfirmation>, 'account'>>(rpc, 'prepareReset', { account })\n setResetAcknowledged(false)\n setResetConfirmation({ ...result, account })\n } catch (error) { setResetMessage(messageOf(error)) }\n finally { resetInflight.current = false; setResetBusy(false) }\n }\n\n async function consumeReset(): Promise<void> {\n if (!rpc || !resetConfirmation || !resetAcknowledged || resetInflight.current) return\n const { account, ticket } = resetConfirmation\n resetInflight.current = true\n setResetBusy(true)\n setResetConfirmation(undefined)\n try {\n await callSubscriptionsAuth(rpc, 'consumeReset', { account, ticket })\n setResetMessage(t('resetUseSuccess'))\n } catch (error) { setResetMessage(messageOf(error)) }\n finally {\n await loadUsage('codex', account, true)\n resetInflight.current = false; setResetBusy(false)\n }\n }\n\n // Fetch usage once an account is logged in; drop the snapshots of accounts\n // that vanished so a re-login refetches. A failed lookup does not auto-retry\n // — the per-account Refresh button is the retry path.\n useEffect(() => {\n const live = new Set<string>()\n for (const { id } of PROVIDERS) {\n for (const account of statuses[id]?.accounts ?? []) {\n const key = `${id}:${account.key}`\n live.add(key)\n if (usages[key] === undefined && usageErrors[key] === undefined) void loadUsage(id, account.key)\n }\n }\n setUsages(prev => dropStale(prev, live))\n setUsageErrors(prev => dropStale(prev, live))\n }, [statuses, usages, usageErrors, loadUsage])\n\n const login = useCallback(async (provider: SubscriptionProvider, method?: 'oauth' | 'keychain'): Promise<void> => {\n if (rpc === undefined) return\n setProviderError(provider, undefined)\n try {\n const response = await callSubscriptionsAuth<LoginResponse>(rpc, 'login', {\n provider,\n ...method === undefined ? {} : { method },\n })\n if (typeof response.authorizeUrl === 'string' && response.authorizeUrl === '') {\n // Instant login (e.g. imported from Claude Code credentials)\n await refresh()\n return\n }\n if (typeof response.authorizeUrl !== 'string') {\n throw new SubscriptionsAuthError(t('loginMissingUrl'))\n }\n if (!mountedRef.current) return\n // Optimistic busy so Cancel and the manual fallback appear before the first poll tick.\n setStatuses(prev => ({\n ...prev,\n [provider]: { accounts: prev[provider]?.accounts ?? [], ...prev[provider], busy: true },\n }))\n if (typeof response.userCode === 'string' && response.userCode.length > 0) {\n // Device flow: show the code card instead of opening the page blind —\n // the user copies the code first, then opens the verification page.\n setDeviceCodes(prev => ({ ...prev, [provider]: { userCode: response.userCode as string, verificationUrl: response.authorizeUrl } }))\n } else {\n window.open(response.authorizeUrl, '_blank', 'noopener')\n }\n startPolling(provider)\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n }, [rpc, t, setProviderError, startPolling])\n\n const cancel = useCallback(async (provider: SubscriptionProvider): Promise<void> => {\n if (rpc === undefined) return\n stopPolling(provider)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'cancel', { provider })\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n }, [rpc, stopPolling, setProviderError, refresh])\n\n const submitManual = useCallback(async (provider: SubscriptionProvider): Promise<void> => {\n if (rpc === undefined) return\n const input = manualDrafts[provider].trim()\n if (input === '') return\n setProviderError(provider, undefined)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'manual', { provider, input })\n if (mountedRef.current) setManualDrafts(prev => ({ ...prev, [provider]: '' }))\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n }, [rpc, manualDrafts, setProviderError, refresh])\n\n const logout = useCallback(async (provider: SubscriptionProvider, account: string, display: string, name: string): Promise<void> => {\n if (rpc === undefined) return\n if (!window.confirm(t('logoutAccountConfirm', { provider: name, account: display }))) return\n setProviderError(provider, undefined)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'logout', { provider, account })\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n }, [rpc, t, setProviderError, refresh])\n\n const setDefault = useCallback(async (provider: SubscriptionProvider, account: string): Promise<void> => {\n if (rpc === undefined) return\n setProviderError(provider, undefined)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'setDefault', { provider, account })\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n }, [rpc, setProviderError, refresh])\n\n const copyDeviceCode = useCallback((provider: SubscriptionProvider, userCode: string): void => {\n void navigator.clipboard?.writeText(userCode).then(() => {\n if (!mountedRef.current) return\n setCopiedCode(provider)\n setTimeout(() => {\n if (mountedRef.current) {\n setCopiedCode(current => current === provider ? undefined : current)\n }\n }, 1500)\n }).catch(() => undefined)\n }, [])\n\n if (rpc === undefined) {\n return <p style={styles.intro}>{t('unavailable')}</p>\n }\n\n return (\n <div className=\"dsh-subscriptions-settings\" style={styles.section}>\n <style>{providerSettingsCss}</style>\n <p style={styles.intro}>{t('intro')}</p>\n <UsageBadgeDisplaySetting t={t} />\n {PROVIDERS.map(({ id, name }) => {\n const status = statuses[id]\n const busy = status?.busy === true\n const deviceCode = deviceCodes[id]\n const accounts = status?.accounts ?? []\n return (\n <div key={id} style={styles.card}>\n <div style={styles.cardHeader}>\n <span style={{ ...styles.dot, background: dotColor(status) }} />\n <span style={styles.name}>{name}</span>\n {status?.clientVersion !== undefined && (\n <span style={styles.clientVersion} title={t('clientVersionHint')}>\n {clientVersionText(t, status.clientVersion)}\n </span>\n )}\n </div>\n <p style={styles.statusLine}>{statusText(t, status)}</p>\n {status?.detail !== undefined && status.detail !== '' && (\n <p style={styles.statusLine}>{status.detail}</p>\n )}\n {errors[id] !== undefined && <p style={styles.errorLine}>{errors[id]}</p>}\n {accounts.map((account) => {\n const usageKey = `${id}:${account.key}`\n const usage = usages[usageKey]\n const usageError = usageErrors[usageKey]\n const display = account.account ?? account.key\n const sortedCredits = [...(usage?.resetCredits ?? [])].sort((a, b) => (a.expiresAt ?? Infinity) - (b.expiresAt ?? Infinity))\n const nextReset = sortedCredits.find(c => c.expiresAt === undefined || c.expiresAt > Date.now())\n const resetBlock = usage ? resetActionBlock(usage) : 'resetUseRefresh'\n const resetDisabled = resetBusy || resetBlock !== undefined\n // Providers without a usage endpoint answer supported:false — no block.\n const showUsage = usage?.supported !== false\n && (usage !== undefined || usageError !== undefined || usageLoading[usageKey] === true)\n return (\n <div key={account.key} style={styles.accountRow}>\n <div style={styles.accountHeader}>\n <button\n type=\"button\"\n style={styles.starButton}\n title={account.isDefault ? t('defaultBadge') : t('setDefault')}\n onClick={() => {\n if (!account.isDefault) void setDefault(id, account.key)\n }}\n >\n {account.isDefault ? '★' : '☆'}\n </button>\n <span style={styles.accountName}>{display}</span>\n {account.plan !== undefined && (\n <span style={styles.usagePlan}>{account.plan}</span>\n )}\n {account.expiresAt !== undefined && (\n <span style={styles.statusLine}>\n {t('accountExpires', { date: new Date(account.expiresAt).toLocaleString() })}\n </span>\n )}\n <button\n type=\"button\"\n style={{ marginLeft: 'auto', flexShrink: 0 }}\n onClick={() => { void logout(id, account.key, display, name) }}\n >\n {t('logout')}\n </button>\n </div>\n {showUsage && (\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {usage?.plan !== undefined && (\n <span style={styles.usagePlan}>{t('usagePlan', { plan: usage.plan })}</span>\n )}\n <button\n type=\"button\"\n style={styles.usageRefresh}\n disabled={usageLoading[usageKey] === true}\n onClick={() => { void loadUsage(id, account.key, true) }}\n >\n {t('usageRefresh')}\n </button>\n </div>\n {usage === undefined && usageError === undefined && (\n <p style={styles.statusLine}>{t('usageLoading')}</p>\n )}\n {usageError !== undefined && (\n <p style={styles.errorLine}>{t('usageError', { message: usageError })}</p>\n )}\n {usage?.windows !== undefined && usage.windows.length === 0 && (\n <p style={styles.statusLine}>{t('usageEmpty')}</p>\n )}\n {(usage?.windows ?? []).map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n return (\n <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{usageWindowLabel(t, window)}</span>\n <span>\n {percent === undefined ? t('usageMeterInvalid') : `${percent}%`}\n {window.resetsAt !== undefined\n && ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}\n </span>\n </div>\n <UsageMeter window={window} t={t} observedAt={observedAt[usageKey]} stale={usageError !== undefined || usage.stale === true} />\n </div>\n )\n })}\n {(id === 'codex' || id === 'claude') && usage?.resetCreditsError !== undefined && (\n <ResetCreditsErrorLine provider={id} message={usage.resetCreditsError} t={t} />\n )}\n {(id === 'codex' || id === 'claude') && showsResetCredits(id, usage?.resetCredits) && (\n <ResetCreditsDisclosure\n mode={id === 'claude' ? 'grants' : 'credits'}\n credits={sortedCredits}\n t={t}\n {...nextReset !== undefined ? { nextCredit: nextReset } : {}}\n {...id === 'codex' ? { useAction: {\n accountKey: account.key,\n busy: resetBusy && resetAccount === account.key,\n disabled: resetDisabled,\n title: t(resetBusy ? 'resetUseChecking' : resetBlock ?? 'resetUseReady'),\n label: t('resetUseButton'),\n onUse: () => { if (!resetDisabled) void prepareReset(account.key) },\n } } : {}}\n {...resetAccount === account.key && resetMessage !== '' ? { statusMessage: resetMessage } : {}}\n />\n )}\n </div>\n )}\n </div>\n )\n })}\n <div style={styles.actions}>\n {!busy && accounts.length === 0 && (\n <button type=\"button\" onClick={() => { void login(id) }}>\n {t('login')}\n </button>\n )}\n {!busy && accounts.length > 0 && id === 'claude' && (\n <>\n <button type=\"button\" onClick={() => { void login(id, 'oauth') }}>\n {t('addAccountOAuth')}\n </button>\n <button type=\"button\" onClick={() => { void login(id, 'keychain') }}>\n {t('addAccountKeychain')}\n </button>\n </>\n )}\n {!busy && accounts.length > 0 && id !== 'claude' && (\n <button type=\"button\" onClick={() => { void login(id) }}>\n {t('addAccount')}\n </button>\n )}\n <button type=\"button\" aria-haspopup=\"dialog\"\n onClick={() => setManagedProvider({ id, name })}>\n {t('accountsManage')}\n </button>\n {busy && (\n <button type=\"button\" onClick={() => { void cancel(id) }}>\n {t('cancel')}\n </button>\n )}\n </div>\n {!busy && accounts.length > 0 && (\n <p style={styles.statusLine}>{t('addAccountHint')}</p>\n )}\n\n {busy && deviceCode !== undefined && (\n <div style={styles.deviceCode}>\n <span style={styles.statusLine}>{t('deviceCodePrompt')}</span>\n <span style={styles.deviceCodeText}>{deviceCode.userCode}</span>\n <div style={styles.actions}>\n <button type=\"button\" onClick={() => { copyDeviceCode(id, deviceCode.userCode) }}>\n {copiedCode === id ? t('deviceCodeCopied') : t('deviceCodeCopy')}\n </button>\n <button\n type=\"button\"\n onClick={() => { window.open(deviceCode.verificationUrl, '_blank', 'noopener') }}\n >\n {t('deviceCodeOpenPage')}\n </button>\n </div>\n </div>\n )}\n {busy && deviceCode === undefined && (\n <details style={styles.manual}>\n <summary>{t('manualSummary')}</summary>\n <div style={styles.manualRow}>\n <input\n style={styles.manualInput}\n value={manualDrafts[id]}\n placeholder={t('manualPlaceholder')}\n onChange={event => setManualDrafts(prev => ({ ...prev, [id]: event.target.value }))}\n />\n <button type=\"button\" onClick={() => { void submitManual(id) }}>\n {t('submit')}\n </button>\n </div>\n </details>\n )}\n </div>\n )\n })}\n <CursorCard rpc={rpc} t={t} />\n <ExternalUsageCards rpc={rpc} t={t} />\n {managedProvider && <ProviderAccountManager provider={managedProvider.id} name={managedProvider.name}\n rpc={rpc} t={t} onClose={() => setManagedProvider(undefined)} />}\n <style>{'.subscriptions-reset-dialog::backdrop { background: var(--dsw-alias-bg-mask-1, #0006); backdrop-filter: var(--dsw-mask-blur, none); }'}</style>\n <dialog ref={resetDialogRef} className=\"subscriptions-reset-dialog\"\n aria-labelledby=\"subscriptions-reset-title\" onCancel={() => setResetConfirmation(undefined)}\n onClose={() => setResetConfirmation(undefined)}\n style={{ ...styles.modal, display: resetConfirmation ? 'flex' : 'none', margin: 'auto', color: 'var(--dsw-alias-label-primary)' }}>\n {resetConfirmation && <>\n <h3 id=\"subscriptions-reset-title\" style={{ ...styles.modalTitle, margin: 0 }}>{t('resetUseConfirmTitle')}</h3>\n <p style={{ ...styles.statusLine, overflowWrap: 'anywhere' }}>{statuses.codex?.accounts.find(a => a.key === resetConfirmation.account)?.account ?? resetConfirmation.account}</p>\n <div style={{ ...styles.usageMeta, gap: 12 }}>\n <span>{t('usageWeekly')}</span><strong>{Math.round(resetConfirmation.weeklyUsedPercent)}%</strong>\n </div>\n <div style={styles.usageMeta}>\n <span>{resetConfirmation.creditExpiresAt === undefined ? t('resetCreditExpiryUnknown') : t('resetCreditExpires', { date: new Date(resetConfirmation.creditExpiresAt).toLocaleString() })}</span>\n </div>\n <p style={{ ...styles.statusLine, margin: '4px 0' }}>{t('resetUseWarning')}</p>\n <label style={{ display: 'flex', gap: 8, alignItems: 'flex-start', fontSize: 12 }}>\n <input type=\"checkbox\" checked={resetAcknowledged} onChange={e => setResetAcknowledged(e.target.checked)} />\n {t('resetUseAcknowledge')}\n </label>\n <div className=\"dsh-subscription-dialog-actions\" style={{ ...styles.actions, justifyContent: 'flex-end', marginTop: 8 }}>\n <button type=\"button\" autoFocus onClick={() => setResetConfirmation(undefined)}>{t('cancel')}</button>\n <button type=\"button\" className=\"dsh-subscription-primary\" disabled={!resetAcknowledged || resetBusy}\n onClick={() => { void consumeReset() }}>{t('resetUseConfirm')}</button>\n </div>\n </>}\n </dialog>\n </div>\n )\n}\n","/**\n * Plugin-local image gallery for generated-image toolviews.\n *\n * Since web-app rc.8, `@deepseek-ai/dsh-client-ui-attachment`'s browser module\n * exports only its cordis plugin surface (`apply`/`inject`) — the React\n * components are no longer package values, so importing `ImageGallery` from it\n * yields `undefined` at runtime and crashes the toolview inside the slot error\n * boundary (the whole call row disappears). This module re-implements the\n * gallery contract the toolview needs (loader-driven thumbnails, retry on\n * failure, click-to-open lightbox) with the same sizing rules as the platform\n * component, keeping this plugin independent of harness component exports.\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { CSSProperties } from 'react'\n\n/**\n * Mirror of ImageAttachmentRef (packages/attachment/attachment/src/types.ts);\n * the brand on attachmentId is compile-time only, so string suffices here.\n */\nexport interface ImageAttachmentRef {\n attachmentId: string\n mediaType: string\n bytes: number\n width: number\n height: number\n name?: string\n}\n\n/** Loads a session-authorized durable image URL (resolves to a data/blob URL). */\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\n/** Lightbox strings forwarded to the opened preview. */\nexport interface ImageLightboxLabels {\n dialog: string\n close: string\n}\n\n/** Message-image strings the owner resolves from its own locale namespace. */\nexport interface MessageImageLabels {\n /** Fallback display name for an unnamed image. */\n image: string\n /** Thumbnail tooltip inviting the original-image preview. */\n open: string\n /** Accessible thumbnail label; receives the image's display name. */\n openNamed: (label: string) => string\n /** Loading placeholder shown until bytes resolve. */\n loading: string\n /** Retry-control label shown when the load fails. */\n loadFailed: string\n /** Lightbox strings forwarded to the opened preview. */\n lightbox: ImageLightboxLabels\n}\n\n/** Display box for a lone image (platform rule): long edge 240px with the\n * rendered aspect ratio clamped to [0.25, 4] — the overflow is cropped by\n * `object-fit: cover` — and never upscaled past the image's natural size. The\n * crop anchor keeps the top of very tall images and the left of very wide\n * ones, where the informative content usually starts. */\nfunction singleFit(attachment: ImageAttachmentRef): { width: number; height: number; objectPosition: string } {\n const natural = attachment.width / attachment.height\n const ratio = Math.min(4, Math.max(0.25, natural))\n const box = ratio >= 1 ? { width: 240, height: 240 / ratio } : { width: 240 * ratio, height: 240 }\n const scale = Math.min(1, attachment.width / box.width, attachment.height / box.height)\n return {\n width: Math.max(1, Math.round(box.width * scale)),\n height: Math.max(1, Math.round(box.height * scale)),\n objectPosition: natural < 0.25 ? 'center top' : natural > 4 ? 'left center' : 'center',\n }\n}\n\nconst styles: Record<string, CSSProperties> = {\n gallery: { display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'flex-start' },\n frame: {\n display: 'grid', placeItems: 'center', overflow: 'hidden', padding: 0,\n border: '1px solid var(--dsw-alias-border-l2-darkmode-thin)', borderRadius: 8,\n background: 'var(--dsw-alias-interactive-bg-hover-solid)', cursor: 'zoom-in',\n },\n tile: { width: 64, height: 64 },\n img: { width: '100%', height: '100%', objectFit: 'cover', display: 'block' },\n loading: { fontSize: 12, color: 'var(--dsw-alias-label-tertiary)', padding: '0 8px' },\n error: {\n fontSize: 12, color: 'var(--dsw-alias-state-error-primary)', cursor: 'pointer',\n border: '1px solid var(--dsw-alias-border-l2-darkmode-thin)', borderRadius: 8,\n background: 'transparent', padding: '6px 10px',\n },\n overlay: {\n position: 'fixed', inset: 0, zIndex: 1000, display: 'grid', placeItems: 'center',\n background: 'rgba(0, 0, 0, 0.72)', padding: 24,\n },\n overlayImg: { maxWidth: '92vw', maxHeight: '92vh', objectFit: 'contain', borderRadius: 4 },\n close: {\n position: 'absolute', top: 12, right: 12, width: 32, height: 32, display: 'grid',\n placeItems: 'center', border: 'none', borderRadius: '50%', cursor: 'pointer',\n background: 'rgba(255, 255, 255, 0.16)', color: '#fff', fontSize: 16, lineHeight: 1,\n },\n}\n\n/**\n * Full-viewport original-image preview: backdrop or close-control click and\n * Escape all dismiss; the image itself is inert so a click on it does not\n * fall through to the backdrop dismissal.\n */\nfunction ImageLightbox({ src, alt, labels, onClose }: {\n src: string\n alt: string\n labels: ImageLightboxLabels\n onClose: () => void\n}) {\n useEffect(() => {\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape') onClose() }\n window.addEventListener('keydown', onKey)\n return () => { window.removeEventListener('keydown', onKey) }\n }, [onClose])\n return (\n <div role=\"dialog\" aria-label={labels.dialog} style={styles.overlay} onClick={onClose}>\n <img src={src} alt={alt} style={styles.overlayImg} onClick={event => { event.stopPropagation() }} />\n <button type=\"button\" aria-label={labels.close} style={styles.close} onClick={onClose}>×</button>\n </div>\n )\n}\n\n/**\n * Compact history renderer with retryable loading and click-to-open original\n * preview. A lone image renders at its `singleFit` size; an image among\n * several renders as a fixed 64px square tile.\n */\nexport function MessageImage({ attachment, load, variant, labels }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n variant: 'single' | 'tile'\n labels: MessageImageLabels\n}) {\n const [src, setSrc] = useState<string | null>(null)\n const [error, setError] = useState(false)\n const [open, setOpen] = useState(false)\n // Retry re-arms the one load effect below, so every attempt — first load or\n // retry — runs under the same liveness guard and the same reset.\n const [attempt, setAttempt] = useState(0)\n const retry = useCallback(() => { setAttempt(a => a + 1) }, [])\n const close = useCallback(() => { setOpen(false) }, [])\n const fit = useMemo(\n () => (variant === 'single' ? singleFit(attachment) : undefined),\n [attachment, variant],\n )\n\n useEffect(() => {\n let live = true\n setError(false)\n setSrc(null)\n void load(attachment).then((url) => { if (live) setSrc(url) }).catch(() => { if (live) setError(true) })\n return () => { live = false }\n }, [attachment, load, attempt])\n\n const label = attachment.name ?? labels.image\n if (error) {\n return <button type=\"button\" style={styles.error} onClick={retry}>{labels.loadFailed}</button>\n }\n const box = fit === undefined ? styles.tile : { width: fit.width, height: fit.height }\n return (\n <>\n <button\n type=\"button\"\n style={{ ...styles.frame, ...box }}\n title={labels.open}\n aria-label={labels.openNamed(label)}\n onClick={() => { if (src !== null) setOpen(true) }}\n >\n {src === null\n ? <span style={styles.loading}>{labels.loading}</span>\n : <img src={src} alt={label} style={{ ...styles.img, objectPosition: fit?.objectPosition }} />}\n </button>\n {open && src !== null && <ImageLightbox src={src} alt={label} labels={labels.lightbox} onClose={close} />}\n </>\n )\n}\n\n/** Wrapping image group: a lone image renders large, several render as 64px\n * square tiles (same rule as the platform gallery). */\nexport function ImageGallery({ images, load, labels }: {\n images: readonly { attachment: ImageAttachmentRef }[]\n load: ImageLoader\n labels: MessageImageLabels\n}) {\n if (images.length === 0) return null\n const variant = images.length === 1 ? 'single' : 'tile'\n return (\n <div style={styles.gallery}>\n {images.map((image, index) => (\n <MessageImage key={`${image.attachment.attachmentId}:${index}`} attachment={image.attachment} load={load} variant={variant} labels={labels} />\n ))}\n </div>\n )\n}\n","/**\n * Everything the client half assumes about the DSH host that the compiler\n * cannot check.\n *\n * The client bundle reads host modules at runtime, not at build time. A\n * renamed icon export compiles against the old type declarations and then\n * renders `undefined`. A slot outlet the host stops rendering never mounts our\n * entry, so the page looks normal and the feature is just gone. A removed DOM\n * marker only breaks layout. None of these fail `tsc`, and a unit test with\n * a hand-made host cannot see them either.\n *\n * So each such assumption is listed here once, next to the host package that\n * owns it. `scripts/check-host-contract.mjs` downloads every supported DSH\n * version and checks that each entry appears in that version's published\n * code. The host E2E reads the same diagnostics entries to catch slot\n * crashes. The spec test/host-contract.spec.ts scans src/client and fails\n * when code starts relying on a literal host name that is missing here.\n *\n * This module has no imports, so plain Node scripts can import it directly.\n */\n\n/** Prefix of the console warning the client logs when a host lacks a listed name. */\nexport const HOST_CONTRACT_MISS = 'dsh-subscriptions: host contract miss'\n\nexport const HOST_CONTRACT = {\n /**\n * Host modules the client bundle loads by specifier. The web shell serves\n * only the modules in its static module table (`staticModules` in\n * dsh-web-frontend), so each specifier the built lib/client.js loads must\n * be a key of that table.\n */\n moduleTable: '@deepseek-ai/dsh-web-frontend',\n\n /** Named runtime exports the client reads from a host module. */\n exports: {\n '@deepseek-ai/dsh-client-ui-primitives': ['useAnchoredPosition', 'useDismissOnOutsidePointer'],\n },\n\n /**\n * 16px glyphs read through hostIcon(). The host must export\n * `Icon<Name>Regular` (DSH 0.1.7 and later) or `Icon<Name>16` (earlier).\n */\n icons: {\n package: '@deepseek-ai/dsh-client-ui-primitives',\n names: ['Sparkle', 'DataOutline'],\n },\n\n /** Slots the client registers into, each with the package that renders its outlet. */\n slots: {\n 'settings.section': '@deepseek-ai/dsh-client-ui-settings-general',\n 'tool.call.toolview': '@deepseek-ai/dsh-client-ui-tool',\n 'conversation.input.right': '@deepseek-ai/dsh-client-ui-conversation',\n 'conversation.composer.dock': '@deepseek-ai/dsh-client-ui-conversation',\n },\n\n /**\n * Context services the client injects or reads, each with the package that\n * provides it (`ctx.provide(\"<name>\")` or a cordis Service named `<name>`).\n * A service nobody provides leaves the plugin's apply() waiting forever,\n * with nothing in the console.\n */\n services: {\n commandUi: '@deepseek-ai/dsh-client-ui-commands',\n connection: '@deepseek-ai/dsh-client-connection',\n locale: '@deepseek-ai/dsh-client-locale',\n modelDirectories: '@deepseek-ai/dsh-client-ui-model-selection',\n slots: '@deepseek-ai/dsh-client-ui-renderer',\n },\n\n /** DOM attributes the client looks up in host-rendered markup. */\n markers: {\n /** The shipped StatsPills row; the usage badge renders into it as a third pill. */\n composerStats: { attribute: 'data-composer-stats', package: '@deepseek-ai/dsh-client-ui-chat' },\n },\n\n /**\n * What the slot renderer emits when an entry throws. It catches the error,\n * logs `crashLog`, and renders an element carrying `errorAttribute` in the\n * entry's place, so a crash never reaches the page's error handlers. The\n * host E2E watches for both.\n */\n diagnostics: {\n package: '@deepseek-ai/dsh-client-ui-renderer',\n crashLog: 'slot entry crashed in',\n errorAttribute: 'data-slot-error',\n slotAttribute: 'data-slot',\n },\n\n /** Design tokens the client styles with; the host theme must define each one. */\n tokens: {\n package: '@deepseek-ai/dsh-client-ui-theme',\n names: [\n '--dsw-alias-bg-layer-1',\n '--dsw-alias-bg-layer-2',\n '--dsw-alias-bg-layer-3',\n '--dsw-alias-bg-mask-1',\n '--dsw-alias-bg-skeleton',\n '--dsw-alias-border-l1',\n '--dsw-alias-border-l2',\n '--dsw-alias-border-l2-darkmode-thin',\n '--dsw-alias-border-l3',\n '--dsw-alias-border-l4',\n '--dsw-alias-brand-primary',\n '--dsw-alias-button-primary-fill',\n '--dsw-alias-button-primary-hover',\n '--dsw-alias-interactive-bg-active',\n '--dsw-alias-interactive-bg-hover',\n '--dsw-alias-interactive-bg-hover-solid',\n '--dsw-alias-label-dimmed',\n '--dsw-alias-label-primary',\n '--dsw-alias-label-primary-foreground',\n '--dsw-alias-label-secondary',\n '--dsw-alias-label-tertiary',\n '--dsw-alias-settings-card-fill',\n '--dsw-alias-settings-card-stroke',\n '--dsw-alias-state-business-primary',\n '--dsw-alias-state-error-primary',\n '--dsw-alias-state-success-primary',\n '--dsw-alias-state-warn-label',\n '--dsw-elevation-prominent',\n '--dsw-focus-ring-color',\n '--dsw-focus-ring-width',\n '--dsw-mask-blur',\n '--dsw-menu-backdrop-filter',\n '--dsw-radius-lg',\n '--dsw-radius-md',\n '--dsw-radius-panel',\n '--dsw-radius-sm',\n '--dsw-radius-xl',\n '--dsw-specific-menu',\n ],\n },\n} as const\n\n/** A glyph name listed in {@link HOST_CONTRACT}; hostIcon() accepts no other. */\nexport type HostIconName = (typeof HOST_CONTRACT.icons.names)[number]\n","/**\n * Glyphs from the host's icon set that survive its renames. DSH 0.1.7\n * renamed the 16px glyphs from `Icon<Name>16` to `Icon<Name>Regular`. The\n * client reads host modules at runtime, so a named import of a glyph the\n * host no longer exports is `undefined`, and rendering it crashes the whole\n * slot (React error #130).\n *\n * A glyph name must be listed in HOST_CONTRACT.icons, which\n * scripts/check-host-contract.mjs checks against each supported DSH version.\n */\nimport type { ComponentType } from 'react'\nimport type { IconProps } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { HOST_CONTRACT, HOST_CONTRACT_MISS } from './host-contract.js'\nimport type { HostIconName } from './host-contract.js'\n\n/** A decorative glyph the host lacks renders nothing rather than crashing. */\nconst NoIcon: ComponentType<IconProps> = () => null\n\n/**\n * Resolve one 16px glyph under either host naming.\n *\n * A glyph the host lacks renders nothing, and the lookup logs a\n * {@link HOST_CONTRACT_MISS} warning. The host E2E fails on that warning, so a\n * missing icon is reported instead of shipping as a blank space.\n * @param icons - the host primitives module (`import * as`), read by name.\n * @param name - the glyph name without prefix or size, e.g. `Sparkle`.\n * @returns the host's component, or one rendering nothing.\n */\nexport function hostIcon(icons: object, name: HostIconName): ComponentType<IconProps> {\n const exports = icons as Record<string, ComponentType<IconProps> | undefined>\n const icon = exports[`Icon${name}Regular`] ?? exports[`Icon${name}16`]\n if (icon !== undefined) return icon\n console.warn(\n `${HOST_CONTRACT_MISS}: ${HOST_CONTRACT.icons.package} exports neither Icon${name}Regular nor Icon${name}16`,\n )\n return NoIcon\n}\n","/**\n * Keyed toolview for the `image_generate` tool: renders generated images\n * inline in the conversation. The row shows the call's prompt while running\n * and after settling; a settled result with image blocks renders them through\n * this plugin's own ImageGallery (harness rc.8 stopped exporting the platform\n * one as a package value), whose bytes load through the node half's\n * `/subscriptions-auth` RPC channel (the durable ImageAttachmentRef is never\n * a fetchable URL on its own). A text-only settled result (degraded route)\n * renders its text; an error result renders the first error line.\n *\n * The 'tool.call.toolview' slot contract is owned by ui-tool\n * (packages/client/ui-tool/src/client/contract/slots.ts), which this package\n * does not resolve; the SlotMap merge and ToolCallOwnerProps below mirror it\n * structurally (same discipline as platform-modules.d.ts).\n */\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\nimport { ImageGallery } from './ImageGallery.js'\nimport type { ImageAttachmentRef, ImageLoader, MessageImageLabels } from './ImageGallery.js'\nimport { hostIcon } from './host-icons.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** DSH 0.1.7 renamed IconSparkle16; resolving it by name keeps older hosts working too. */\nconst SparkleIcon = hostIcon(primitives, 'Sparkle')\n\n/** Title prompt truncation budget (characters). */\nconst PROMPT_MAX_LENGTH = 60\n\n/** Mirror of ui-tool's ToolCallOwnerProps (see the module header). */\ninterface ToolCallOwnerProps {\n callId: string\n toolName: string\n block: ToolCallBlock\n cwd?: string | undefined\n openFile: (path: string) => void\n inspect?: (() => void) | undefined\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n /** Mirror of ui-tool's keyed atomic Tool view declaration (see the module header). */\n 'tool.call.toolview': { kind: 'keyed'; scope: 'session'; owner: ToolCallOwnerProps }\n }\n}\n\n/** Injected dependencies of {@link ImageGenerateToolview} (slot `inject`). */\nexport interface ImageGenerateToolviewInjected {\n /** Session-authorized image URL loader riding the `/subscriptions-auth` channel. */\n load: ImageLoader\n}\n\n/**\n * Props delivered by the toolview outlet: the owner share plus the inject\n * face and the framework locale seat, spread flat.\n */\nexport type ImageGenerateToolviewProps =\n Partial<ToolCallOwnerProps>\n & Partial<ImageGenerateToolviewInjected>\n & { t?: ((key: SubscriptionsKey, params?: Record<string, unknown>) => string) | undefined }\n\n/** `image` endpoint result: the node half owns this shape. */\ninterface ImageEndpointResult {\n mediaType: string\n dataBase64: string\n}\n\n/**\n * Build the ImageGallery loader over the `image` endpoint.\n * @param rpc - Connection RPC caller.\n * @returns loader resolving an attachment ref to a data URL.\n */\nexport function createImageLoader(rpc: ConnectionHandle['rpc']): ImageLoader {\n // The host validates a full ImageAttachmentRef payload (readImage takes the\n // whole ref), so forward the attachment verbatim.\n return attachment =>\n callSubscriptionsAuth<ImageEndpointResult>(rpc, 'image', { ...attachment })\n .then(result => `data:${result.mediaType};base64,${result.dataBase64}`)\n}\n\n/**\n * English-dictionary fallback for a missing locale seat (standalone renders);\n * the framework always supplies the namespace-bound one.\n * @param key - dictionary key.\n * @param params - `{name}` template params.\n * @returns the template with params substituted.\n */\nfunction fallbackTranslate(key: SubscriptionsKey, params?: Record<string, unknown>): string {\n let text: string = en[key]\n for (const [name, value] of Object.entries(params ?? {})) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\n/** Extract the prompt from the call's raw args JSON; falls back to the first string value, then the raw line. */\nfunction derivePrompt(argsRaw: string): string {\n let parsed: unknown\n try {\n parsed = JSON.parse(argsRaw)\n } catch {\n // Non-JSON args (mid-stream truncation): fall back to the raw string below.\n parsed = undefined\n }\n let prompt: string | undefined\n if (typeof parsed === 'object' && parsed !== null) {\n const args = parsed as Record<string, unknown>\n if (typeof args.prompt === 'string' && args.prompt !== '') prompt = args.prompt\n else {\n for (const value of Object.values(args)) {\n if (typeof value === 'string' && value !== '') { prompt = value; break }\n }\n }\n }\n const line = (prompt ?? argsRaw).split('\\n', 1)[0] ?? ''\n return line.length > PROMPT_MAX_LENGTH ? `${line.slice(0, PROMPT_MAX_LENGTH)}…` : line\n}\n\n/** Flatten a settled result's text blocks (the degraded text-only route and the error line). */\nfunction resultText(block: ToolCallBlock): string {\n if (!('kind' in block)) return ''\n const parts: string[] = []\n for (const part of block.content) {\n if (part.type === 'text') parts.push(part.text)\n }\n if (parts.length === 0 && block.error !== undefined) parts.push(`${block.error.name}: ${block.error.code}`)\n return parts.join('\\n')\n}\n\n/** Image attachments of a settled result; empty while running or on the text-only route. */\nfunction resultImages(block: ToolCallBlock): { attachment: ImageAttachmentRef }[] {\n if (!('kind' in block)) return []\n const images: { attachment: ImageAttachmentRef }[] = []\n for (const part of block.content) {\n if (part.type === 'image') images.push({ attachment: part.attachment as ImageAttachmentRef })\n }\n return images\n}\n\nconst styles: Record<string, CSSProperties> = {\n container: { display: 'flex', flexDirection: 'column', gap: 6, padding: '4px 0' },\n row: { display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 },\n icon: { display: 'inline-flex', flexShrink: 0, color: 'var(--dsw-alias-label-tertiary)' },\n title: {\n fontSize: 13, lineHeight: '20px', color: 'var(--dsw-alias-label-primary)',\n overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',\n },\n subtle: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' },\n output: {\n margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-secondary)',\n whiteSpace: 'pre-wrap', overflowWrap: 'anywhere',\n },\n error: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-state-error-primary)' },\n}\n\n/**\n * The `image_generate` keyed toolview component.\n * @param props - owner share, inject face, and locale seat (spread flat).\n * @returns the call row plus, once settled, the gallery / text / error body.\n */\nexport function ImageGenerateToolview(props: ImageGenerateToolviewProps) {\n const { block, load } = props\n const t = props.t ?? fallbackTranslate\n if (block === undefined) return null\n const settled = 'kind' in block\n const argsRaw = (settled ? block.call?.argsRaw : block.phase === 'start' ? block.argsRaw : undefined) ?? ''\n let references = 0\n try {\n const args = JSON.parse(argsRaw)\n if (Array.isArray(args?.referenceImages)) references = args.referenceImages.length\n } catch { /* Arguments may still be streaming. */ }\n const title = `image_generate${references > 0 ? ` (${references} ref)` : ''}: ${derivePrompt(argsRaw)}`\n const images = resultImages(block)\n const text = settled ? resultText(block) : ''\n const labels: MessageImageLabels = {\n image: t('image'),\n open: t('viewImage'),\n openNamed: name => t('viewImageNamed', { name }),\n loading: t('imageLoading'),\n loadFailed: t('imageLoadFailed'),\n lightbox: { dialog: t('imagePreview'), close: t('imageClose') },\n }\n return (\n <div style={styles.container}>\n <div style={styles.row}>\n <span style={styles.icon}><SparkleIcon size={14} /></span>\n <span style={styles.title}>{title}</span>\n </div>\n {!settled && <p style={styles.subtle}>{t('generating')}</p>}\n {settled && block.isError && text !== '' && (\n <p style={styles.error}>{text.split('\\n', 1)[0]}</p>\n )}\n {settled && !block.isError && images.length > 0 && load !== undefined && (\n <ImageGallery images={images} load={load} labels={labels} />\n )}\n {settled && !block.isError && images.length === 0 && text !== '' && (\n <p style={styles.output}>{text}</p>\n )}\n </div>\n )\n}\n","/**\n * Keyed toolview for the `video_generate` tool: renders the generated video\n * inline in the conversation. The row shows the call's prompt while running\n * and after settling; a settled success loads the MP4 bytes through the node\n * half's `/subscriptions-auth` `video` endpoint (by bare file name), builds a\n * Blob URL, and plays it in a native `<video controls>` element. The file\n * name comes from the result's presentation meta when the dispatch was\n * top-level, and is recovered from the \"Saved video to …\" text line for\n * nested (Code Mode) dispatches, where the harness computes no meta. A result\n * with neither renders its text; an error result renders the first error line.\n *\n * The 'tool.call.toolview' SlotMap entry is declared by\n * ImageGenerateToolview.tsx in this same package (one declaration per\n * augmentation), so this file only mirrors the owner-props shape.\n */\nimport { useEffect, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\nimport { hostIcon } from './host-icons.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** DSH 0.1.7 renamed IconSparkle16; resolving it by name keeps older hosts working too. */\nconst SparkleIcon = hostIcon(primitives, 'Sparkle')\n\n/** Title prompt truncation budget (characters). */\nconst PROMPT_MAX_LENGTH = 60\n\n/** Mirror of ui-tool's ToolCallOwnerProps (see ImageGenerateToolview). */\ninterface ToolCallOwnerProps {\n callId: string\n toolName: string\n block: ToolCallBlock\n cwd?: string | undefined\n openFile: (path: string) => void\n inspect?: (() => void) | undefined\n}\n\n/** Decoded video bytes as the node half's `video` endpoint answers them. */\nexport interface VideoBytes {\n mediaType: string\n dataBase64: string\n}\n\n/** Injected dependencies of {@link VideoGenerateToolview} (slot `inject`). */\nexport interface VideoGenerateToolviewInjected {\n /** Loads one generated video's bytes by bare file name. */\n loadVideo: (name: string) => Promise<VideoBytes>\n}\n\n/**\n * Props delivered by the toolview outlet: the owner share plus the inject\n * face and the framework locale seat, spread flat.\n */\nexport type VideoGenerateToolviewProps =\n Partial<ToolCallOwnerProps>\n & Partial<VideoGenerateToolviewInjected>\n & { t?: ((key: SubscriptionsKey, params?: Record<string, unknown>) => string) | undefined }\n\n/**\n * Build the video loader over the `/subscriptions-auth` `video` endpoint.\n * @param rpc - Connection RPC caller.\n * @returns loader resolving a bare file name to the decoded bytes.\n */\nexport function createVideoLoader(rpc: ConnectionHandle['rpc']): (name: string) => Promise<VideoBytes> {\n return name => callSubscriptionsAuth<VideoBytes>(rpc, 'video', { name })\n}\n\n/**\n * English-dictionary fallback for a missing locale seat (standalone renders);\n * the framework always supplies the namespace-bound one.\n */\nfunction fallbackTranslate(key: SubscriptionsKey, params?: Record<string, unknown>): string {\n let text: string = en[key]\n for (const [name, value] of Object.entries(params ?? {})) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\n/** Extract the prompt from the call's raw args JSON; falls back to the first string value, then the raw line. */\nfunction derivePrompt(argsRaw: string): string {\n let parsed: unknown\n try {\n parsed = JSON.parse(argsRaw)\n } catch {\n // Non-JSON args (mid-stream truncation): fall back to the raw string below.\n parsed = undefined\n }\n let prompt: string | undefined\n if (typeof parsed === 'object' && parsed !== null) {\n const args = parsed as Record<string, unknown>\n if (typeof args.prompt === 'string' && args.prompt !== '') prompt = args.prompt\n else {\n for (const value of Object.values(args)) {\n if (typeof value === 'string' && value !== '') { prompt = value; break }\n }\n }\n }\n const line = (prompt ?? argsRaw).split('\\n', 1)[0] ?? ''\n return line.length > PROMPT_MAX_LENGTH ? `${line.slice(0, PROMPT_MAX_LENGTH)}…` : line\n}\n\n/** Flatten a settled result's text blocks (the fallback body and the error line). */\nfunction resultText(block: ToolCallBlock): string {\n if (!('kind' in block)) return ''\n const parts: string[] = []\n for (const part of block.content) {\n if (part.type === 'text') parts.push(part.text)\n }\n if (parts.length === 0 && block.error !== undefined) parts.push(`${block.error.name}: ${block.error.code}`)\n return parts.join('\\n')\n}\n\n/**\n * The generated video's bare file name: presentation meta first (top-level\n * dispatches), then the render text's \"Saved video to …\" line (nested\n * dispatches compute no meta).\n */\nfunction resolveFileName(block: ToolCallBlock): string | undefined {\n if (!('kind' in block)) return undefined\n const meta = block.meta\n if (typeof meta === 'object' && meta !== null) {\n const fileName = (meta as Record<string, unknown>).fileName\n if (typeof fileName === 'string' && fileName.length > 0) return fileName\n }\n const match = /^Saved video to (.+\\.mp4)/m.exec(resultText(block))\n if (match === null) return undefined\n const path = match[1]\n return path.slice(path.lastIndexOf('/') + 1)\n}\n\n/** Decode a base64 payload into bytes (browser-side; no Buffer). */\nfunction base64Bytes(dataBase64: string): Uint8Array {\n const binary = atob(dataBase64)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index)\n return bytes\n}\n\n/** Loading lifecycle of the Blob URL. */\ntype LoadState =\n | { phase: 'loading' }\n | { phase: 'ready'; url: string }\n | { phase: 'failed'; message: string }\n\nconst styles: Record<string, CSSProperties> = {\n container: { display: 'flex', flexDirection: 'column', gap: 6, padding: '4px 0' },\n row: { display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 },\n icon: { display: 'inline-flex', flexShrink: 0, color: 'var(--dsw-alias-label-tertiary)' },\n title: {\n fontSize: 13, lineHeight: '20px', color: 'var(--dsw-alias-label-primary)',\n overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',\n },\n subtle: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' },\n output: {\n margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-secondary)',\n whiteSpace: 'pre-wrap', overflowWrap: 'anywhere',\n },\n error: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-state-error-primary)' },\n video: {\n display: 'block', maxWidth: 480, width: '100%', borderRadius: 8,\n backgroundColor: 'var(--dsw-alias-bg-skeleton)',\n },\n}\n\n/**\n * The `video_generate` keyed toolview component.\n * @param props - owner share, inject face, and locale seat (spread flat).\n * @returns the call row plus, once settled, the player / text / error body.\n */\nexport function VideoGenerateToolview(props: VideoGenerateToolviewProps) {\n const { block, loadVideo } = props\n const t = props.t ?? fallbackTranslate\n const settled = block !== undefined && 'kind' in block\n const isError = settled && block.isError\n const fileName = block !== undefined && settled && !isError ? resolveFileName(block) : undefined\n const [load, setLoad] = useState<LoadState>({ phase: 'loading' })\n\n useEffect(() => {\n if (fileName === undefined || loadVideo === undefined) return\n let cancelled = false\n let objectUrl: string | undefined\n setLoad({ phase: 'loading' })\n loadVideo(fileName).then(\n (video) => {\n if (cancelled) return\n // Uint8Array#slice detaches a plain ArrayBuffer view for BlobPart.\n objectUrl = URL.createObjectURL(new Blob([base64Bytes(video.dataBase64).slice()], { type: video.mediaType }))\n setLoad({ phase: 'ready', url: objectUrl })\n },\n (error: unknown) => {\n if (cancelled) return\n setLoad({ phase: 'failed', message: error instanceof Error ? error.message : String(error) })\n },\n )\n return () => {\n cancelled = true\n if (objectUrl !== undefined) URL.revokeObjectURL(objectUrl)\n }\n }, [fileName, loadVideo])\n\n if (block === undefined) return null\n const argsRaw = (settled ? block.call?.argsRaw : block.phase === 'start' ? block.argsRaw : undefined) ?? ''\n const title = `video_generate: ${derivePrompt(argsRaw)}`\n const text = settled ? resultText(block) : ''\n return (\n <div style={styles.container}>\n <div style={styles.row}>\n <span style={styles.icon}><SparkleIcon size={14} /></span>\n <span style={styles.title}>{title}</span>\n </div>\n {!settled && <p style={styles.subtle}>{t('generatingVideo')}</p>}\n {settled && isError && text !== '' && (\n <p style={styles.error}>{text.split('\\n', 1)[0]}</p>\n )}\n {settled && !isError && fileName !== undefined && load.phase === 'loading' && (\n <p style={styles.subtle}>{t('videoLoading')}</p>\n )}\n {settled && !isError && fileName !== undefined && load.phase === 'failed' && (\n <p style={styles.error}>{t('videoLoadFailed', { message: load.message })}</p>\n )}\n {settled && !isError && fileName !== undefined && load.phase === 'ready' && (\n // eslint-disable-next-line jsx-a11y/media-has-caption -- generated clip; no caption track exists.\n <video style={styles.video} src={load.url} controls preload=\"metadata\" />\n )}\n {settled && !isError && fileName === undefined && text !== '' && (\n <p style={styles.output}>{text}</p>\n )}\n </div>\n )\n}\n","/**\n * Codex Speed toggle: one small control in the composer's right tool row\n * (`conversation.input.right`), switching the session between standard routing\n * and the fast (priority) service tier — the Codex desktop app's Speed menu.\n * The choice is per session and lives in the node half (in-memory); this\n * component holds only viewing state. The control renders nothing until the\n * first load proves the session's current model is a codex model whose catalog\n * advertises the fast tier.\n *\n * Every color resolves through a `--dsw-alias-*` design token and every\n * user-visible string goes through the locale `t` of the\n * 'settings.subscriptions' namespace, same as the settings section.\n */\nimport { useEffect, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport { callSubscriptionsAuth } from './SubscriptionsSection.js'\nimport { subscriptionChromeCss } from './provider-settings-styles.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** One session's speed choice: standard routing or the fast (priority) tier. */\nexport type SpeedTier = 'standard' | 'fast'\n\n/** `speed` endpoint value, mirrored from the node half. */\nexport interface SpeedState {\n tier: SpeedTier\n fastModels: string[]\n}\n\n/** What {@link SpeedSelect} renders from: visibility plus the current tier. */\nexport interface SpeedSelectState {\n visible: boolean\n tier: SpeedTier\n}\n\n/**\n * Minimal structural face of ui-model-selection's `ctx.modelDirectories`\n * service (the sanctioned cross-plugin channel: cordis services, not value\n * imports — same mirroring discipline as ToolCallOwnerProps). Both dsh lines\n * ship it with this shape; it replaces rc.2's `connection.api.sessions.models`\n * read, which the 0.1.2-alpha removed along with the whole `.api` face.\n */\nexport interface ModelDirectoriesLike {\n /** Resolve one session's shared model directory (throws for unknown sessions). */\n directoryFor(sessionId: string): {\n /** Load the directory; `current` is the session's effective model selection. */\n load(): Promise<{ current: { provider: string; model: string } | null }>\n }\n}\n\n/** Injected dependencies of {@link SpeedSelect} (slot `inject`, session-bound). */\nexport interface SpeedSelectInjected {\n /** Load the session's speed state; `visible` false keeps the control hidden. */\n loadSpeed: () => Promise<SpeedSelectState>\n /** Set the session's speed tier; resolves false when the write failed. */\n setSpeed: (tier: SpeedTier) => Promise<boolean>\n}\n\n/**\n * Props delivered by the slot outlet: the framework session kit and InputZone\n * owner share (unused — everything arrives session-bound through the inject\n * face), the injected callbacks, and the locale seat.\n */\nexport type SpeedSelectProps = PropsRuntime<'conversation.input.right'>\n & Partial<SpeedSelectInjected>\n & Partial<PropsLocale<'settings.subscriptions'>>\n\n/**\n * The `loadSpeed` half of the inject face: the plugin's own speed state plus\n * the host's current model selection (the visibility gate). A model-RPC\n * failure throws rather than answering \"hidden\" — the caller keeps its last\n * known state, so a transient failure never locks the toggle away.\n *\n * `sessionId` is a plain string: slot and command contexts brand it through\n * different dsh-session copies, and only the service boundary needs one.\n *\n * `models` resolves lazily per call: the ui-model-selection service may\n * register after this plugin applies, and a shell without it (no model seat\n * at all) simply keeps the toggle hidden.\n */\nexport function createSpeedLoader(\n connection: ConnectionHandle,\n models: () => ModelDirectoriesLike | undefined,\n sessionId: string,\n): SpeedSelectInjected['loadSpeed'] {\n return async () => {\n const state = await callSubscriptionsAuth<SpeedState>(connection.rpc, 'speed', { sessionId })\n const directories = models()\n if (directories === undefined) return { visible: false, tier: state.tier }\n const { current } = await directories.directoryFor(sessionId).load()\n const visible = current !== null && current.provider === 'codex'\n && state.fastModels.includes(current.model)\n return { visible, tier: state.tier }\n }\n}\n\n/** The `setSpeed` half of the inject face: boolean outcome for the component's busy state. */\nexport function createSpeedSetter(\n connection: ConnectionHandle,\n sessionId: string,\n): SpeedSelectInjected['setSpeed'] {\n return tier => callSubscriptionsAuth(connection.rpc, 'setSpeed', { sessionId, tier })\n .then(() => true, () => false)\n}\n\n/** English-dictionary fallback for a missing inject `t` (standalone renders). */\nfunction fallbackTranslate(key: SubscriptionsKey): string {\n return en[key]\n}\n\nconst TIERS: readonly SpeedTier[] = ['standard', 'fast']\n\n/**\n * The composer Speed control: a trigger reading `速度 · 快速`/`速度 · 标准`\n * that opens a two-row menu (standard/fast with descriptions, check mark on\n * the current tier). Mount and every open reload the host state so a model\n * switch made since the last open self-corrects.\n */\n/** How often the control re-reads the host state (model switches arrive only by asking). */\nconst POLL_INTERVAL_MS = 3000\n\n/**\n * The composer Speed control: a trigger reading `速度 · 快速`/`速度 · 标准`\n * that opens a two-row menu (standard/fast with descriptions, check mark on\n * the current tier). The host pushes nothing on a model switch, so the\n * control re-reads on a slow poll with a single-flight guard; a failed read\n * keeps the last known state, so a transient RPC failure can never lock the\n * toggle away (the earlier mount-only load had no recovery path).\n */\nexport function SpeedSelect({ loadSpeed, setSpeed, t }: SpeedSelectProps) {\n const translate = t ?? fallbackTranslate\n const [state, setState] = useState<SpeedSelectState | null>(null)\n const [open, setOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const rootRef = useRef<HTMLDivElement | null>(null)\n // The inject face may be re-evaluated (new callback identities) on re-render;\n // the poll effect mounts once and reads through this ref, so identity churn\n // neither resets the interval nor multiplies in-flight loads.\n const loadRef = useRef(loadSpeed)\n loadRef.current = loadSpeed\n\n useEffect(() => {\n if (loadRef.current === undefined) return\n let cancelled = false\n let inflight = false\n const reload = (): void => {\n const load = loadRef.current\n if (load === undefined || inflight) return\n inflight = true\n void load().then(\n (loaded) => { if (!cancelled) setState(loaded) },\n () => { /* keep the last known state; the next tick retries */ },\n ).finally(() => { inflight = false })\n }\n reload()\n const timer = setInterval(reload, POLL_INTERVAL_MS)\n return () => {\n cancelled = true\n clearInterval(timer)\n }\n }, [])\n\n useEffect(() => {\n if (!open) return\n const closeOutside = (event: MouseEvent): void => {\n if (!rootRef.current?.contains(event.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', closeOutside)\n return () => { document.removeEventListener('mousedown', closeOutside) }\n }, [open])\n\n if (loadSpeed === undefined || setSpeed === undefined || state === null || !state.visible) {\n return null\n }\n\n const choose = (tier: SpeedTier): void => {\n if (busy) return\n if (tier === state.tier) {\n setOpen(false)\n return\n }\n setBusy(true)\n void setSpeed(tier).then((ok) => {\n setBusy(false)\n if (ok) {\n setState({ visible: true, tier })\n setOpen(false)\n }\n })\n }\n\n const show = (): void => {\n setOpen(true)\n const load = loadRef.current\n if (load === undefined) return\n void load().then(setState, () => { /* keep showing the last good state */ })\n }\n\n const tierName = (tier: SpeedTier): string =>\n translate(tier === 'fast' ? 'speedFast' : 'speedStandard')\n const tierDescription = (tier: SpeedTier): string =>\n translate(tier === 'fast' ? 'speedFastDescription' : 'speedStandardDescription')\n const triggerLabel = `${translate('speed')} · ${tierName(state.tier)}`\n\n return (\n <div\n ref={rootRef}\n className=\"dsh-subscription-speed\"\n style={styles.root}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && open) {\n event.preventDefault()\n setOpen(false)\n }\n }}\n >\n <style>{subscriptionChromeCss}</style>\n {open && (\n <div style={styles.menu} role=\"menu\" aria-label={translate('speed')}>\n {TIERS.map(tier => (\n <button\n key={tier}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={tier === state.tier}\n style={styles.item}\n disabled={busy}\n onClick={() => { choose(tier) }}\n >\n <span style={styles.itemCheck}>{tier === state.tier ? '✓' : ''}</span>\n <span style={styles.itemText}>\n <span style={styles.itemName}>{tierName(tier)}</span>\n <span style={styles.itemDescription}>{tierDescription(tier)}</span>\n </span>\n </button>\n ))}\n </div>\n )}\n <button\n type=\"button\"\n style={styles.trigger}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title={triggerLabel}\n disabled={busy}\n onClick={() => {\n if (open) setOpen(false)\n else show()\n }}\n >\n {triggerLabel}\n </button>\n </div>\n )\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: { position: 'relative', display: 'inline-flex' },\n trigger: {\n border: '0.5px solid var(--dsw-alias-border-l3)', borderRadius: 'var(--dsw-radius-sm, 8px)',\n background: 'var(--dsh-subscription-speed-hover, transparent)', color: 'var(--dsw-alias-label-secondary)',\n font: 'inherit', fontSize: 12, lineHeight: '18px',\n padding: '2px 8px', cursor: 'pointer', whiteSpace: 'nowrap',\n },\n menu: {\n position: 'absolute', bottom: '100%', right: 0, marginBottom: 4,\n minWidth: 180, padding: 4, zIndex: 20,\n background: 'var(--dsw-specific-menu, var(--dsw-alias-bg-layer-2))', border: 0,\n boxShadow: 'var(--dsw-elevation-prominent)', borderRadius: 'var(--dsw-radius-lg, 16px)', display: 'flex', flexDirection: 'column', gap: 2,\n },\n item: {\n display: 'flex', alignItems: 'flex-start', gap: 6, width: '100%',\n border: 'none', borderRadius: 'var(--dsw-radius-sm, 8px)', background: 'var(--dsh-subscription-speed-hover, transparent)',\n padding: '6px 8px', cursor: 'pointer', font: 'inherit', textAlign: 'left',\n },\n itemCheck: {\n width: 14, flexShrink: 0, fontSize: 12, lineHeight: '18px',\n color: 'var(--dsw-alias-label-primary)',\n },\n itemText: { display: 'flex', flexDirection: 'column' },\n itemName: { fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-primary)' },\n itemDescription: { fontSize: 11, lineHeight: '16px', color: 'var(--dsw-alias-label-tertiary)' },\n}\n","/**\n * Subscription usage badge: a stats pill in the composer's dock\n * (`conversation.composer.dock`), modelled on the host's own token-usage\n * pill. Collapsed, it shows the rate-limit windows of the provider behind the\n * session's CURRENT model (a GPT model → Codex usage, a Claude model → Claude\n * usage); clicking it opens a trigger-anchored dialog listing every logged-in\n * account of every provider, with long window lists collapsed into previews,\n * the current provider first and the default account (starred) first within\n * a provider. Model-scoped Antigravity usage follows the current model.\n *\n * Usage rides the `subscriptions-auth` usage endpoints on a slow\n * poll (the server shares its cache across UI surfaces); the current model\n * comes from ui-model-selection's `modelDirectories` service on a quicker\n * poll, since the host pushes nothing on a model switch. Renders nothing when\n * no connected provider reports usage.\n *\n * The collapsed pill reads only the default account — the same account\n * direct (non-pool) routes serve — so it stays one short segment even for a\n * provider with several accounts connected; the dialog shows them all.\n * Every color resolves through a `--dsw-*` design token, the dialog wears the\n * host's menu material (its translucent fill plus its backdrop blur), and\n * every user-visible string goes through the locale `t` of the\n * 'settings.subscriptions' namespace.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ComponentType, CSSProperties } from 'react'\nimport { subscriptionChromeCss } from './provider-settings-styles.js'\nimport { createPortal } from 'react-dom'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\nimport { useAnchoredPosition, useDismissOnOutsidePointer } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { callSubscriptionsAuth } from './SubscriptionsSection.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\nimport type { AccountStatus, ProviderStatus, ProviderUsage, SubscriptionProvider, UsageWindow } from './SubscriptionsSection.js'\nimport type { ModelDirectoriesLike } from './SpeedSelect.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\nimport { hostIcon } from './host-icons.js'\nimport { USAGE_BADGE_REFRESH_EVENT, useUsageBadgeMode } from './usage-badge-preferences.js'\n\n/** DSH renamed the data icon in 0.1.7; retain older supported hosts too. */\nexport function usageBadgeIcon(icons: {\n IconDataOutlineRegular?: ComponentType\n IconDataOutline16?: ComponentType\n}): ComponentType {\n return hostIcon(icons, 'DataOutline')\n}\nconst UsageBadgeIcon = usageBadgeIcon(primitives)\n\n/** How often the badge re-reads usage; the server also shares its own cache/negative-cache across UI surfaces. */\nconst USAGE_POLL_INTERVAL_MS = 15 * 60_000\n\n/** How often the badge re-reads the session's current model (model switches arrive only by asking). */\nconst MODEL_POLL_INTERVAL_MS = 3000\n\n/** How long the rotation holds one provider in `always` mode (a display cadence, not a data poll). */\nconst BADGE_ROTATION_INTERVAL_MS = 10_000\n\n/** Distance between the trigger's top edge and the dialog's bottom (host stat dialogs use the same). */\nconst PANEL_GAP = 8\n\n/** Distance kept between the dialog and each viewport edge. */\nconst PANEL_MARGIN = 12\n\n/** Injected dependencies (slot `inject`, session-bound). */\nexport interface SubscriptionUsageBadgeInjected {\n /** Connection RPC caller to reach the `subscriptions-auth` endpoints. */\n rpc: ConnectionHandle['rpc']\n /** Resolve the session's effective provider and model together. */\n currentModel: () => Promise<{ provider: string; model: string } | undefined>\n}\n\n/** Props delivered by the slot outlet + inject + the locale seat. */\nexport type SubscriptionUsageBadgeProps = PropsRuntime<'conversation.composer.dock'>\n & Partial<SubscriptionUsageBadgeInjected>\n & Partial<PropsLocale<'settings.subscriptions'>>\n /** Override the rotation cadence (tests only; the slot never passes it). */\n & { rotationMs?: number }\n\n/** One logged-in account's usage windows, as listed in the expanded dialog. */\nexport interface AccountUsageDisplay {\n /** Account key (the `usage` endpoint's `account` argument). */\n key: string\n /** Display handle (email / login), when the provider reports one. */\n account?: string\n plan?: string\n /** The account direct routes serve; the collapsed pill reads this one. */\n isDefault: boolean\n windows: UsageWindow[]\n observedAt?: number | undefined\n stale?: boolean | undefined\n}\n\n/** One provider's usage snapshot: every logged-in account that reports windows. */\nexport interface ProviderUsageDisplay {\n provider: BadgeProvider\n name: string\n /** Default account first, then the rest in the `status` endpoint's order. */\n accounts: AccountUsageDisplay[]\n}\n\n/** The account the collapsed pill reads: the default one, else the first listed. */\nexport function pillAccountOf(d: ProviderUsageDisplay): AccountUsageDisplay {\n return d.accounts.find(a => a.isDefault) ?? d.accounts[0]!\n}\n\n/** Brand display names (short form for the compact badge). */\nexport type BadgeProvider = SubscriptionProvider | 'cursor-subscription' | 'opencode-go' | 'kimi-coding' | 'minimax' | 'minimax-cn'\n\nconst PROVIDER_NAMES: Record<BadgeProvider, string> = {\n codex: 'Codex',\n claude: 'Claude',\n grok: 'Grok',\n copilot: 'Copilot',\n antigravity: 'Antigravity',\n 'cursor-subscription': 'Cursor',\n 'opencode-go': 'OpenCode Go',\n 'kimi-coding': 'Kimi Code',\n 'minimax': 'MiniMax',\n 'minimax-cn': 'MiniMax CN',\n}\n\nexport interface UsageRosterEntry { provider: BadgeProvider; account: AccountStatus }\n\n/** Key of one account's cached windows: `provider:accountKey`. */\nfunction usageKeyOf(provider: BadgeProvider, account: AccountStatus): string {\n return `${provider}:${account.key}`\n}\n\n/**\n * Group per-account usage into the badge's provider rows, in roster order\n * (the `status` provider order, default account first) so rows don't jump\n * around as polls settle at different times. An account without windows is\n * left out, and so is a provider whose accounts all lack windows.\n * @param roster - accounts from {@link loadBadgeRoster}.\n * @param windowsOf - each account's windows, keyed `provider:accountKey`.\n * @param plans - the plan each usage call reported, same keys; the roster's plan is the fallback.\n * @returns one display per provider with at least one account that has windows.\n */\nexport function groupUsageDisplays(\n roster: readonly UsageRosterEntry[],\n windowsOf: ReadonlyMap<string, UsageWindow[]>,\n plans: ReadonlyMap<string, string>,\n): ProviderUsageDisplay[] {\n const byProvider = new Map<BadgeProvider, ProviderUsageDisplay>()\n for (const { provider, account } of roster) {\n const key = usageKeyOf(provider, account)\n const windows = windowsOf.get(key)\n if (windows === undefined) continue\n const plan = plans.get(key) ?? account.plan\n const row: AccountUsageDisplay = {\n key: account.key,\n isDefault: account.isDefault,\n ...account.account === undefined ? {} : { account: account.account },\n ...plan === undefined ? {} : { plan },\n windows,\n }\n const display = byProvider.get(provider)\n if (display === undefined) byProvider.set(provider, { provider, name: PROVIDER_NAMES[provider], accounts: [row] })\n else display.accounts.push(row)\n }\n return [...byProvider.values()]\n}\n\n/** Read each account source independently so a failing endpoint cannot hide the others. */\nexport async function loadBadgeRoster(rpc: ConnectionHandle['rpc']): Promise<{\n roster: UsageRosterEntry[]\n refreshed: Set<BadgeProvider>\n}> {\n const [subscriptions, cursor, external] = await Promise.allSettled([\n callSubscriptionsAuth<{ providers: Record<SubscriptionProvider, ProviderStatus> }>(rpc, 'status', {}),\n callSubscriptionsAuth<{ authenticated: boolean }>(rpc, 'cursorStatus', {}),\n callSubscriptionsAuth<Record<'opencode-go' | 'kimi-code' | 'minimax' | 'minimax-cn', { configured: boolean }>>(rpc, 'externalStatus', {}),\n ])\n const roster: UsageRosterEntry[] = []\n const refreshed = new Set<BadgeProvider>()\n if (subscriptions.status === 'fulfilled') {\n for (const provider of ['codex', 'claude', 'grok', 'copilot', 'antigravity'] as const) {\n refreshed.add(provider)\n for (const account of accountsOf(subscriptions.value.providers[provider])) roster.push({ provider, account })\n }\n }\n if (cursor.status === 'fulfilled') {\n refreshed.add('cursor-subscription')\n if (cursor.value.authenticated) roster.push({\n provider: 'cursor-subscription', account: { key: 'cursor', isDefault: true },\n })\n }\n if (external.status === 'fulfilled') {\n for (const [source, provider] of [\n ['opencode-go', 'opencode-go'], ['kimi-code', 'kimi-coding'], ['minimax', 'minimax'], ['minimax-cn', 'minimax-cn'],\n ] as const) {\n refreshed.add(provider)\n if (external.value[source]?.configured) roster.push({\n provider, account: { key: source, isDefault: true },\n })\n }\n }\n return { roster, refreshed }\n}\n\nexport async function usageOf(rpc: ConnectionHandle['rpc'], { provider, account }: UsageRosterEntry): Promise<ProviderUsage> {\n if (provider === 'cursor-subscription') return callSubscriptionsAuth(rpc, 'cursorUsage', {})\n if (provider === 'opencode-go' || provider === 'kimi-coding' || provider === 'minimax' || provider === 'minimax-cn') {\n return callSubscriptionsAuth(rpc, 'externalUsage', { source: provider === 'kimi-coding' ? 'kimi-code' : provider })\n }\n return callSubscriptionsAuth(rpc, 'usage', { provider, account: account.key })\n}\n\n/**\n * The `currentModel` half of the inject face: the session's effective\n * model selection through ui-model-selection's `modelDirectories` service,\n * resolved lazily per call (the service may register after this plugin, and\n * a shell without it reports \"unknown\"; the badge keeps the most recent\n * subscription selected in this view, or stays hidden).\n */\nexport function createCurrentModelReader(\n models: () => ModelDirectoriesLike | undefined,\n sessionId: string,\n): SubscriptionUsageBadgeInjected['currentModel'] {\n return async () => {\n const directories = models()\n if (directories === undefined) return undefined\n const { current } = await directories.directoryFor(sessionId).load()\n return current ?? undefined\n }\n}\n\n/**\n * Compact time-remaining label derived from the window's `resetsAt` timestamp:\n * \"6d18h\" (days+hours), \"1h58m\" (hours+minutes), or \"42m\" (minutes only).\n * Falls back to the scope/kind abbreviation when no reset time is known.\n */\nexport function windowLabel(w: UsageWindow): string {\n if (w.resetsAt === undefined || !Number.isFinite(w.resetsAt)) {\n if (w.scope !== undefined && w.scope !== '') return w.scope\n switch (w.kind) {\n case 'session': return '5h'\n case 'weekly': return 'Wk'\n default: return 'W'\n }\n }\n const ms = Math.max(0, w.resetsAt - Date.now())\n const minutes = Math.floor(ms / 60_000)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n if (days > 0) return `${days}d${hours % 24}h`\n if (hours > 0) return `${hours}h${minutes % 60}m`\n return `${Math.max(1, minutes)}m`\n}\n\n/**\n * One compact segment piece (`6d1h 25%`); an unusable provider percentage\n * renders as the no-data dash, consistent with the meter's unavailable state.\n */\nfunction windowSegment(label: string, w: UsageWindow): string {\n const percent = displayUsedPercent(w.usedPercent)\n return percent === undefined ? `${label} —` : `${label} ${percent}%`\n}\n\n/** Keep model quotas separate: matching percentages do not imply a shared pool. */\nexport function prioritizeWindows(windows: readonly UsageWindow[], model?: string): UsageWindow[] {\n return model === undefined ? [...windows] : [\n ...windows.filter(w => w.scope === model),\n ...windows.filter(w => w.scope !== model),\n ]\n}\n\n/** Small previews keep a live model catalog from taking over the dialog. */\nexport const WINDOW_PREVIEW_LIMIT = 4\nexport function previewWindows(windows: readonly UsageWindow[], model?: string, provider?: BadgeProvider) {\n const ordered = prioritizeWindows(windows, model)\n // Antigravity has many model-specific quotas: preview only the current model.\n const limit = provider === 'antigravity'\n ? Math.min(2, model === undefined ? 0 : windows.filter(w => w.scope === model).length)\n : WINDOW_PREVIEW_LIMIT\n return { shown: ordered.slice(0, limit), hidden: ordered.slice(limit) }\n}\n\n/** Bounded readout; Antigravity quotas belong to individual models, not the account. */\nexport function compactSegment(d: ProviderUsageDisplay, model?: string, t: Translate = fallbackTranslate): string {\n const windows = pillAccountOf(d).windows\n if (d.provider === 'antigravity') {\n const matching = model === undefined ? [] : windows.filter(w => w.scope === model)\n if (matching.length === 0) {\n return `${d.name} ${t(model === undefined ? 'usageBadgeModelCount' : 'usageBadgeModelUnavailable', {\n count: new Set(windows.map(w => w.scope).filter(Boolean)).size,\n })}`\n }\n const parts = matching.slice(0, 2).map(w => windowSegment(w.kind === 'weekly' ? t('usageWeekly') : t('usageWindow'), w))\n return `${d.name} ${parts.join(' · ')}`\n }\n const parts = windows.slice(0, 2).map(w => windowSegment(windowLabel(w), w))\n if (windows.length > 2) parts.push(`+${windows.length - 2}`)\n return `${d.name} ${parts.join(' · ')}`\n}\n\ntype ModelSelection = { provider: string; model: string }\n\n/** Remember only the most recent subscription in this view, including its model scope. */\nexport function retainSubscriptionSelection(\n previous: ModelSelection | undefined,\n current: ModelSelection | undefined,\n): ModelSelection | undefined {\n return current !== undefined && Object.hasOwn(PROVIDER_NAMES, current.provider) ? current : previous\n}\n\n/** At most one provider; no known selection or no usage means no badge. */\nexport function collapsedDisplays(\n displays: readonly ProviderUsageDisplay[],\n current: string | undefined,\n): readonly ProviderUsageDisplay[] {\n const match = displays.find(d => d.provider === current)\n return match === undefined ? [] : [match]\n}\n\n/**\n * `always` mode: the current model's provider while it reports usage,\n * otherwise the rotation steps through the providers that do, in display\n * order, wrapping around. The index is taken modulo the current provider\n * count, so providers appearing or dropping out stay inside range; the\n * sequence itself may shift when the roster changes. Unlike `recent`, the\n * retained subscription does not pin the pill — that retention is exactly\n * what this mode exists to escape.\n * @param displays - providers with usage, in display order.\n * @param current - the provider of the session's current model.\n * @param step - rotation tick; consecutive ticks advance one provider.\n */\nexport function rotatingDisplay(\n displays: readonly ProviderUsageDisplay[],\n current: string | undefined,\n step: number,\n): readonly ProviderUsageDisplay[] {\n if (displays.length === 0) return []\n const match = displays.find(d => d.provider === current)\n if (match !== undefined) return [match]\n const index = Number.isFinite(step) ? Math.floor(step) : 0\n return [displays[((index % displays.length) + displays.length) % displays.length]!]\n}\n\n/** Order for the expanded dialog: the current provider first, the rest in poll order. */\nexport function expandedDisplays(\n displays: readonly ProviderUsageDisplay[],\n current: string | undefined,\n): readonly ProviderUsageDisplay[] {\n const match = displays.find(d => d.provider === current)\n return match === undefined ? displays : [match, ...displays.filter(d => d !== match)]\n}\n\n/**\n * A provider's logged-in accounts, the effective default first. When no\n * account is flagged default the first listed stands in, matching what\n * direct routes fall back to.\n */\nfunction accountsOf(status: ProviderStatus | undefined): AccountStatus[] {\n if (status === undefined || status.accounts.length === 0) return []\n const fallback = status.accounts.find(a => a.isDefault) ?? status.accounts[0]!\n return status.accounts\n .map(a => (a === fallback ? { ...a, isDefault: true } : a))\n .sort((a, b) => Number(b.isDefault) - Number(a.isDefault))\n}\n\n/** English-dictionary fallback for a missing inject `t` (standalone renders). */\nfunction fallbackTranslate(key: SubscriptionsKey, params?: Record<string, unknown>): string {\n return en[key].replace(/\\{(\\w+)\\}/g, (_, name: string) => String(params?.[name] ?? ''))\n}\n\ntype Translate = (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n\n/** Localized label of one usage window (kind, plus the model scope when named). */\nfunction usageWindowLabel(t: Translate, window: UsageWindow): string {\n const base = window.kind === 'session'\n ? t('usageSession')\n : window.kind === 'weekly' ? t('usageWeekly') : t('usageWindow')\n return window.scope !== undefined && window.scope !== '' ? `${base} · ${window.scope}` : base\n}\n\n/**\n * The composer subscription-usage badge: a pill reading e.g.\n * `Codex 6d1h 25%` for the current model's provider, opening a dialog with\n * every provider's accounts and their windows. Returns null when no data is\n * available.\n */\nexport function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }: SubscriptionUsageBadgeProps) {\n const translate: Translate = t ?? fallbackTranslate\n const [displays, setDisplays] = useState<ProviderUsageDisplay[]>([])\n const [selection, setSelection] = useState<ModelSelection | undefined>(undefined)\n const [lastSubscription, setLastSubscription] = useState<ModelSelection | undefined>(undefined)\n const displayMode = useUsageBadgeMode()\n const current = selection?.provider\n const badgeSelection = retainSubscriptionSelection(lastSubscription, selection)\n const [open, setOpen] = useState(false)\n const [hover, setHover] = useState(false)\n // Rotation tick for `always` mode; the interval runs only in that mode.\n const [rotation, setRotation] = useState(0)\n // The provider the pill showed when the dialog opened; an open dialog\n // keeps leading with it while the rotation keeps ticking underneath.\n const [dialogLead, setDialogLead] = useState<string | undefined>(undefined)\n const inflightRef = useRef(false)\n const mountedRef = useRef(true)\n const rootRef = useRef<HTMLSpanElement | null>(null)\n const panelRef = useRef<HTMLDivElement | null>(null)\n // Always-rendered, invisible marker in the dock: locates the composer bar\n // (and the host stats row inside it) even while the pill itself is portaled.\n const seatRef = useRef<HTMLSpanElement | null>(null)\n // The inject face may be re-evaluated (new callback identities) on\n // re-render; the model poll mounts once and reads through this ref.\n const currentRef = useRef(currentModel)\n currentRef.current = currentModel\n // Last-known-good windows per account (keyed `provider:accountKey`), kept\n // across a failed poll (e.g. a 429 during the server's own negative-cache\n // cooldown) so a row doesn't flicker away — it only disappears once the\n // account actually logs out or a fetch succeeds but reports the window as\n // unsupported. Observation metadata (freshness) shares this lifecycle: an\n // entry is dropped wherever its windows are dropped.\n const lastKnownRef = useRef(new Map<string, UsageWindow[]>())\n const observationsRef = useRef(new Map<string, { observedAt?: number | undefined; stale: boolean }>())\n\n const refresh = useCallback(async (): Promise<void> => {\n if (rpc === undefined || inflightRef.current) return\n inflightRef.current = true\n try {\n const { roster, refreshed } = await loadBadgeRoster(rpc)\n if (!mountedRef.current) return\n\n const lastKnown = lastKnownRef.current\n // Drop last-known state for anything no longer logged in — that is a\n // real signal, unlike a fetch failure.\n const live = new Set(roster.map(({ provider, account }) => usageKeyOf(provider, account)))\n for (const key of lastKnown.keys()) {\n if (refreshed.has(key.split(':', 1)[0] as BadgeProvider) && !live.has(key)) {\n lastKnown.delete(key)\n observationsRef.current.delete(key)\n }\n }\n\n const results = await Promise.allSettled(\n roster.map(async ({ provider, account }) => {\n const usage = await usageOf(rpc, { provider, account })\n return { provider, account, usage }\n }),\n )\n if (!mountedRef.current) return\n\n for (const { provider, account } of roster) {\n const key = usageKeyOf(provider, account)\n observationsRef.current.set(key, { ...observationsRef.current.get(key), stale: true })\n }\n const plans = new Map<string, string>()\n for (const r of results) {\n if (r.status !== 'fulfilled') continue // keep whatever is cached for this account\n const { provider, account, usage } = r.value\n const key = usageKeyOf(provider, account)\n if (usage.plan !== undefined) plans.set(key, usage.plan)\n if (!usage.supported || !usage.windows || usage.windows.length === 0) {\n lastKnown.delete(key)\n observationsRef.current.delete(key)\n continue\n }\n lastKnown.set(key, usage.windows)\n observationsRef.current.set(key, { observedAt: usage.observedAt ?? Date.now(), stale: usage.stale === true })\n }\n\n setDisplays(previous => [\n ...groupUsageDisplays(roster, lastKnown, plans).map(display => ({ ...display,\n accounts: display.accounts.map(account => ({ ...account,\n ...observationsRef.current.get(`${display.provider}:${account.key}`),\n })),\n })),\n ...previous.filter(display => !refreshed.has(display.provider)).map(display => ({ ...display,\n accounts: display.accounts.map(account => ({ ...account, stale: true })),\n })),\n ])\n } catch {\n // Keep cached numbers, but never present failed observations as current.\n if (mountedRef.current) setDisplays(previous => previous.map(display => ({ ...display,\n accounts: display.accounts.map(account => ({ ...account, stale: true })),\n })))\n } finally {\n inflightRef.current = false\n }\n }, [rpc])\n\n useEffect(() => {\n mountedRef.current = true\n return () => { mountedRef.current = false }\n }, [])\n\n // Hidden renders nothing, so it polls nothing; showing it again refreshes at once.\n useEffect(() => {\n if (displayMode === 'hidden') return\n void refresh()\n const timer = setInterval(() => { void refresh() }, USAGE_POLL_INTERVAL_MS)\n window.addEventListener(USAGE_BADGE_REFRESH_EVENT, refresh)\n return () => {\n clearInterval(timer)\n window.removeEventListener(USAGE_BADGE_REFRESH_EVENT, refresh)\n }\n }, [refresh, displayMode])\n\n useEffect(() => {\n if (currentRef.current === undefined) return\n let cancelled = false\n let inflight = false\n const reload = (): void => {\n const read = currentRef.current\n if (read === undefined || inflight) return\n inflight = true\n void read().then(\n (model) => {\n if (cancelled) return\n setLastSubscription(previous => retainSubscriptionSelection(previous, model))\n setSelection(model)\n },\n () => { /* keep the last known provider; the next tick retries */ },\n ).finally(() => { inflight = false })\n }\n reload()\n const timer = setInterval(reload, MODEL_POLL_INTERVAL_MS)\n return () => {\n cancelled = true\n clearInterval(timer)\n }\n }, [])\n\n const pos = useAnchoredPosition({ open, anchorRef: rootRef, panelRef, side: 'top', gap: PANEL_GAP, margin: PANEL_MARGIN })\n useDismissOnOutsidePointer(rootRef, open, setOpen, panelRef)\n useEffect(() => {\n if (!open) return\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') setOpen(false)\n }\n document.addEventListener('keydown', onKeyDown)\n return () => { document.removeEventListener('keydown', onKeyDown) }\n }, [open])\n\n // Sit on the host's stats row when there is one. Every dock entry is its\n // own row in the composer bar, so a badge rendered in place lands under the\n // shipped time/token pills; the host marks its pill row with\n // `data-composer-stats`, and rendering into it makes the badge a third pill\n // on that line. The marker is watched (the row mounts only once the session\n // has steps or tokens, and unmounts with them) and older hosts without it\n // keep the in-place row.\n const [statsRow, setStatsRow] = useState<HTMLElement | null>(null)\n useEffect(() => {\n const seat = seatRef.current\n if (seat === null) return\n const scope = statsScopeOf(seat)\n if (scope === null) return\n const find = (): HTMLElement | null => scope.querySelector<HTMLElement>('[data-composer-stats]')\n setStatsRow(find())\n const observer = new MutationObserver(() => { setStatsRow(find()) })\n observer.observe(scope, { childList: true, subtree: true })\n return () => { observer.disconnect() }\n }, [])\n\n useEffect(() => {\n if (displayMode === 'hidden') setOpen(false)\n }, [displayMode])\n\n // `always` mode advances the rotation on its own cadence; other modes\n // never advance, so the pill never changes on its own.\n useEffect(() => {\n if (displayMode !== 'always') return\n const interval = rotationMs !== undefined && Number.isFinite(rotationMs) && rotationMs > 0\n ? rotationMs\n : BADGE_ROTATION_INTERVAL_MS\n const timer = setInterval(() => { setRotation(step => step + 1) }, interval)\n return () => { clearInterval(timer) }\n }, [displayMode, rotationMs])\n\n const seat = <span ref={seatRef} style={styles.seat} aria-hidden />\n // `always` follows the live model, not the retained subscription: the\n // retention pins the pill in `recent`, which is what this mode escapes.\n const collapsed = displayMode === 'always'\n ? rotatingDisplay(displays, current, rotation)\n : collapsedDisplays(displays, badgeSelection?.provider)\n if (displayMode === 'hidden' || collapsed.length === 0) return seat\n\n // Model scope only while the pill shows the current model's provider;\n // a rotated provider has no live model, so it reads at account level.\n const pillModel = displayMode === 'always'\n ? (current === collapsed[0]?.provider ? selection?.model : undefined)\n : badgeSelection?.model\n const label = compactSegment(collapsed[0]!, pillModel, translate)\n // The dialog opens from the badge, so it follows the provider and model the\n // badge shows (a retained subscription when the current model is not one).\n // In `always` mode the pill moves under the cursor, so an open dialog keeps\n // the provider that was showing when it opened instead of reordering live.\n const dialogProvider = open && displayMode === 'always' ? dialogLead : badgeSelection?.provider\n const dialogModel = open && displayMode === 'always'\n ? (dialogLead === current ? selection?.model : undefined)\n : badgeSelection?.model\n const expanded = expandedDisplays(displays, dialogProvider)\n const title = translate('usageBadgeTitle')\n\n const toggle = (): void => {\n const next = !open\n setDialogLead(collapsed[0]?.provider)\n setOpen(next)\n if (next) void refresh()\n }\n\n const pill = (\n <span ref={rootRef} style={styles.anchor}>\n <style>{subscriptionChromeCss}</style>\n <button\n type=\"button\"\n className=\"dsh-subscription-usage-pill\"\n style={{ ...styles.pill, ...(hover || open ? styles.pillActive : {}) }}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-label={`${title} · ${label}`}\n title={title}\n onMouseEnter={() => { setHover(true) }}\n onMouseLeave={() => { setHover(false) }}\n onClick={toggle}\n >\n <UsageBadgeIcon />\n <span style={styles.label}>{label}</span>\n </button>\n {open && createPortal(\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-label={title}\n className=\"dsh-subscription-usage-panel\"\n style={{ ...styles.panel, ...(pos ?? MEASURE_STYLE) }}\n >\n <div style={styles.title}>\n <span style={styles.titleLabel}>\n <UsageBadgeIcon />\n {title}\n </span>\n </div>\n <div style={styles.titleRule} aria-hidden />\n {expanded.map((d, index) => (\n <section key={d.provider} style={index === 0 ? undefined : styles.section}>\n <div style={styles.providerRow}>\n <span style={styles.providerName}>\n {d.name}\n {d.provider === current && <span style={styles.currentTag}>{translate('usageBadgeCurrent')}</span>}\n </span>\n {d.accounts.length === 1 && <AccountMeta account={d.accounts[0]!} translate={translate} />}\n </div>\n {d.accounts.map((account, accountIndex) => (\n <div key={account.key} style={accountIndex === 0 ? undefined : styles.accountBlock}>\n {d.accounts.length > 1 && (\n <div style={styles.accountRow}>\n <AccountMeta account={account} translate={translate} />\n </div>\n )}\n <AccountWindows\n key={`${d.provider}:${dialogModel ?? ''}`}\n windows={account.windows}\n observedAt={account.observedAt} stale={account.stale}\n model={d.provider === dialogProvider ? dialogModel : undefined}\n provider={d.provider}\n translate={translate}\n />\n </div>\n ))}\n </section>\n ))}\n </div>,\n document.body,\n )}\n </span>\n )\n\n return (\n <>\n {seat}\n {statsRow !== null && statsRow.isConnected ? createPortal(pill, statsRow) : pill}\n </>\n )\n}\n\n/**\n * Nearest ancestor of the dock seat that can contain the host's stats row:\n * the composer bar. Bounded so a badge in an unfamiliar layout never adopts\n * some other composer's pills.\n */\nfunction statsScopeOf(seat: HTMLElement): HTMLElement | null {\n let node: HTMLElement | null = seat.parentElement\n for (let depth = 0; node !== null && depth < 4; depth++) {\n if (node.querySelector('[data-composer-stats]') !== null) return node\n node = node.parentElement\n }\n return seat.parentElement\n}\n\n/**\n * One account's handle and plan: `★ ys@example.com · 计划:pro`. The star\n * marks the default account (the one direct routes serve and the collapsed\n * pill reads), the same glyph Settings → 订阅 uses.\n */\nfunction AccountMeta({ account, translate }: { account: AccountUsageDisplay; translate: Translate }) {\n const parts = [account.account, account.plan === undefined ? undefined : translate('usagePlan', { plan: account.plan })]\n .filter((part): part is string => part !== undefined && part !== '')\n return (\n <span style={styles.providerMeta} title={account.account}>\n {account.isDefault && <span style={styles.defaultStar} aria-label=\"default\">★ </span>}\n {parts.join(' · ')}\n </span>\n )\n}\n\n/** Preview each account independently; all remaining quotas stay accessible. */\nexport function AccountWindows({ windows, model, provider, translate, observedAt, stale }: {\n windows: readonly UsageWindow[]; model: string | undefined; provider?: BadgeProvider; translate: Translate\n observedAt?: number | undefined; stale?: boolean | undefined\n}) {\n const { shown, hidden } = previewWindows(windows, model, provider)\n const rows = (items: readonly UsageWindow[]) => (\n <dl style={styles.details}>\n {items.map((w, i) => (\n <WindowRow key={i} label={`${usageWindowLabel(translate, w)}${model !== undefined && w.scope === model ? ` · ${translate('usageBadgeCurrent')}` : ''}`} window={w} t={translate} observedAt={observedAt} stale={stale} />\n ))}\n </dl>\n )\n return <>\n {rows(shown)}\n {hidden.length > 0 && <details style={styles.moreWindows}>\n <summary style={styles.moreSummary}>{translate('usageBadgeMoreWindows', { count: hidden.length })}</summary>\n {rows(hidden)}\n </details>}\n </>\n}\n\n/** One `dt`/`dd` pair: window name → `25% · 6d1h`, with the bar underneath. */\nfunction WindowRow({ label, window: w, t, observedAt, stale }: { label: string; window: UsageWindow; t: Translate; observedAt?: number | undefined; stale?: boolean | undefined }) {\n const percent = displayUsedPercent(w.usedPercent)\n return (\n <>\n <dt style={styles.dt}>{label}</dt>\n <dd style={styles.dd}>\n {percent === undefined ? t('usageMeterInvalid') : `${percent}%`}\n {w.resetsAt !== undefined && Number.isFinite(w.resetsAt) && <span style={styles.reset}> · {windowLabel(w)}</span>}\n </dd>\n <UsageMeter window={w} t={t} style={styles.bar} observedAt={observedAt} stale={stale} />\n </>\n )\n}\n\n/**\n * Unplaced portal panel: hidden but laid out so the clamp measures real\n * dimensions (the `useAnchoredPosition` measure pass).\n */\nconst MEASURE_STYLE: CSSProperties = { visibility: 'hidden', left: 0, top: 0 }\n\nconst styles: Record<string, CSSProperties> = {\n seat: { display: 'none' },\n anchor: { minWidth: 0, maxWidth: '100%', display: 'inline-flex' },\n // Mirrors the host StatsPills pill so the badge reads as a sibling of the\n // shipped time/token pills.\n pill: {\n boxSizing: 'border-box', maxWidth: '100%',\n color: 'var(--dsw-alias-label-tertiary)',\n font: 'inherit', fontSize: 'calc(var(--dsh-content-font-size-secondary, 13px) - 1px)',\n fontVariantNumeric: 'tabular-nums', lineHeight: 'calc(20px + var(--dsh-content-font-delta-secondary, 0px))', whiteSpace: 'nowrap',\n background: 'transparent', border: 'none', borderRadius: 999,\n alignItems: 'center', gap: 6, padding: '1px 8px', display: 'inline-flex', cursor: 'pointer',\n },\n pillActive: {\n background: 'var(--dsw-alias-interactive-bg-hover)',\n color: 'var(--dsw-alias-label-secondary)',\n },\n label: { textOverflow: 'ellipsis', minWidth: 0, overflow: 'hidden' },\n // Mirrors the host stat-dialog panel. The menu fill is translucent by\n // design and only the host's backdrop blur keeps it readable as a surface:\n // without the blur the transcript behind the dialog stays sharp and shows\n // through the fill.\n panel: {\n position: 'fixed', zIndex: 1100, boxSizing: 'border-box',\n background: 'var(--dsw-specific-menu)',\n backdropFilter: 'var(--dsw-menu-backdrop-filter)',\n width: 'max-content', minWidth: 'min(300px, 100vw - 24px)', maxWidth: 'min(440px, 100vw - 24px)',\n maxHeight: 'min(560px, 100dvh - 24px)', overflowY: 'auto', overscrollBehavior: 'contain',\n boxShadow: 'var(--dsw-elevation-prominent)',\n color: 'var(--dsw-alias-label-secondary)', cursor: 'default',\n border: 0, borderRadius: 'var(--dsw-radius-lg, 16px)', padding: 16, fontSize: 12, lineHeight: '18px',\n },\n title: {\n color: 'var(--dsw-alias-label-primary)', display: 'flex',\n justifyContent: 'space-between', gap: 16, marginBottom: 8, fontWeight: 500,\n },\n titleLabel: { alignItems: 'center', gap: 6, minWidth: 0, display: 'inline-flex' },\n titleRule: { borderTop: '0.5px solid var(--dsw-alias-border-l2)', marginBottom: 10 },\n section: { marginTop: 12, paddingTop: 10, borderTop: '0.5px solid var(--dsw-alias-border-l2)' },\n providerRow: {\n display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 16, marginBottom: 6,\n },\n providerName: { color: 'var(--dsw-alias-label-primary)', fontWeight: 500, display: 'inline-flex', alignItems: 'center', gap: 6 },\n currentTag: {\n fontSize: 10, lineHeight: '14px', fontWeight: 400, padding: '0 5px', borderRadius: 7,\n color: 'var(--dsw-alias-label-secondary)', background: 'var(--dsw-alias-interactive-bg-hover)',\n },\n providerMeta: {\n color: 'var(--dsw-alias-label-tertiary)', minWidth: 0, overflow: 'hidden',\n textOverflow: 'ellipsis', whiteSpace: 'nowrap',\n },\n // Same star and color as the default-account marker in Settings → 订阅.\n defaultStar: { color: 'var(--dsw-alias-state-warn-label)' },\n accountBlock: { marginTop: 8 },\n accountRow: { display: 'flex', marginBottom: 4 },\n details: {\n color: 'var(--dsw-alias-label-tertiary)', display: 'grid',\n gridTemplateColumns: 'minmax(0, 1fr) max-content', gap: '4px 16px', margin: 0,\n },\n moreWindows: { marginTop: 8 },\n moreSummary: { cursor: 'pointer', color: 'var(--dsw-alias-label-secondary)', marginBottom: 8 },\n dt: { minWidth: 0, margin: 0, overflowWrap: 'anywhere' },\n dd: {\n minWidth: 0, margin: 0, color: 'var(--dsw-alias-label-secondary)',\n fontVariantNumeric: 'tabular-nums', textAlign: 'right',\n },\n reset: { color: 'var(--dsw-alias-label-tertiary)' },\n bar: {\n gridColumn: '1 / -1', height: 4, borderRadius: 2, overflow: 'hidden',\n background: 'var(--dsw-alias-border-l2)', marginBottom: 2,\n },\n}\n","/** Build the locale resolver used by the /fast command contribution. */\nexport function fastCommandDescription(t: () => string): () => string {\n return () => t()\n}\n","/**\n * Subscription OAuth login page, browser half. Registers the Subscriptions\n * settings section; every login state fact arrives through the node half's\n * `/subscriptions-auth` RPC channel — this plugin holds no credential state of its\n * own. Section copy rides the client locale service: one 'settings.subscriptions'\n * namespace with zh/en dictionaries, rebound per read so the nav label and\n * page text follow the active locale.\n */\n// Type-only: pulls the `ctx.slots` Context merge (dsh-client-runtime owned it\n// on rc.2; ui-renderer's augmentation carries it on the 0.1.2-alpha line).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\n// Type-only: pulls the shell's SlotMap merge (the 'settings.section' entry).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls ui-conversation's SlotMap merge (the 'conversation.input.right' entry).\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/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: the slash-command registry contract (the /fast contribution).\nimport type { CommandUiContract } from '@deepseek-ai/dsh-client-ui-commands/client'\n// `.js` extension: this package's tsconfig lacks the reference repo's\n// allowImportingTsExtensions/rewriteRelativeImportExtensions pair; under\n// nodenext the .js specifier resolves to the .tsx source (see README note).\nimport { SubscriptionsSection } from './SubscriptionsSection.js'\nimport type { SubscriptionsSectionInjected } from './SubscriptionsSection.js'\nimport { ImageGenerateToolview, createImageLoader } from './ImageGenerateToolview.js'\nimport type { ImageGenerateToolviewInjected } from './ImageGenerateToolview.js'\nimport { VideoGenerateToolview, createVideoLoader } from './VideoGenerateToolview.js'\nimport type { VideoGenerateToolviewInjected } from './VideoGenerateToolview.js'\nimport { SpeedSelect, createSpeedLoader, createSpeedSetter } from './SpeedSelect.js'\nimport type { ModelDirectoriesLike, SpeedSelectInjected } from './SpeedSelect.js'\nimport { SubscriptionUsageBadge, createCurrentModelReader } from './SubscriptionUsageBadge.js'\nimport type { SubscriptionUsageBadgeInjected } from './SubscriptionUsageBadge.js'\nimport { en, zh } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\nimport { fastCommandDescription } from './fast-command.js'\n\nexport type { SubscriptionsSectionInjected, SubscriptionsSectionProps } from './SubscriptionsSection.js'\nexport type { ImageGenerateToolviewInjected, ImageGenerateToolviewProps } from './ImageGenerateToolview.js'\nexport type { VideoGenerateToolviewInjected, VideoGenerateToolviewProps } from './VideoGenerateToolview.js'\nexport type { SpeedSelectInjected, SpeedSelectProps, SpeedState, SpeedTier } from './SpeedSelect.js'\nexport type { SubscriptionUsageBadgeInjected, SubscriptionUsageBadgeProps } from './SubscriptionUsageBadge.js'\nexport type { SubscriptionsKey } from './locales.js'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The Subscriptions settings page copy. */\n 'settings.subscriptions': SubscriptionsKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'settings.subscriptions'\n\n/**\n * Required services (cordis fiber inject): `slots` carries the registration\n * seat, `connection` the `/subscriptions-auth` RPC caller, and `locale` the copy\n * dictionaries.\n */\nexport const inject = ['slots', 'connection', 'locale']\n\n/**\n * Register the Subscriptions section once the `settings.section` declaration\n * is on the ledger (the shell's apply order relative to this one is NOT\n * constrained; registration depends on the slot through `slots.inject()`).\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-subscriptions: copy dictionaries')\n // Settings-shell nudge: the panel (nav title + header row + section body)\n // sits flush against the panel's top edge; push it down a little to leave\n // breathing room. Scoped by the settings panel's own dialog role + nav child\n // so other aria-modal dialogs (e.g. the attachment lightbox) are untouched.\n ctx.effect(() => {\n const style = document.createElement('style')\n style.setAttribute('data-plugin', 'dsh-subscriptions')\n style.textContent = 'div[role=\"dialog\"][aria-modal=\"true\"]:has(> nav) { padding-top: 14px; }'\n document.head.appendChild(style)\n return () => style.remove()\n }, 'dsh-subscriptions: settings panel breathing room')\n // The shell's Context merge types `connection` as the host handle; in the\n // browser shell the same key holds the full client ConnectionHandle.\n const connection = ctx.get('connection') as unknown as ConnectionHandle\n const t = ctx.locale.bind(NS) as SubscriptionsSectionInjected['t']\n const injected = (): SubscriptionsSectionInjected => ({ rpc: connection.rpc, t })\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'subscriptions',\n order: 90,\n // A thunk re-evaluated per read, so the nav label follows the active locale.\n label: () => t('nav'),\n inject: injected,\n }, SubscriptionsSection))\n\n // The image_generate keyed toolview owns how image calls render inline; its\n // gallery bytes ride the same channel through the injected loader. The\n // framework synthesizes the toolview's own `t` seat from `locale: NS`.\n const toolviewInjected = (): ImageGenerateToolviewInjected => ({ load: createImageLoader(connection.rpc) })\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: 'image_generate',\n locale: NS,\n inject: toolviewInjected,\n }, ImageGenerateToolview))\n\n // The video_generate keyed toolview plays the saved MP4 inline; its bytes\n // ride the same channel's `video` endpoint through the injected loader.\n const videoToolviewInjected = (): VideoGenerateToolviewInjected => ({ loadVideo: createVideoLoader(connection.rpc) })\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: 'video_generate',\n locale: NS,\n inject: videoToolviewInjected,\n }, VideoGenerateToolview))\n\n // The composer Speed toggle (codex fast tier) sits in the right tool row,\n // just left of the model selector; the framework synthesizes its `t` seat\n // from `locale: NS`, and the inject face binds each session's RPC calls.\n // The current-model read rides ui-model-selection's `modelDirectories`\n // service, resolved lazily so registration order never matters.\n const models = (): ModelDirectoriesLike | undefined =>\n ctx.get('modelDirectories') as ModelDirectoriesLike | undefined\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right',\n id: 'codex-speed',\n order: 0,\n locale: NS,\n inject: (sessionId: string): SpeedSelectInjected => ({\n loadSpeed: createSpeedLoader(connection, models, sessionId),\n setSpeed: createSpeedSetter(connection, sessionId),\n }),\n }, SpeedSelect))\n\n // The subscription usage badge renders a stats pill in the composer's dock\n // (conversation.composer.dock) — collapsed, the current model's provider\n // (e.g. \"Codex 6d1h 25%\"); clicking opens every provider's windows. A fresh\n // id means it appears beside the shipped StatsPills, never replacing them;\n // the current-model read shares the Speed toggle's `modelDirectories` path.\n ctx.slots.inject('conversation.composer.dock', () => ctx.slots.register({\n name: 'conversation.composer.dock',\n id: 'subscription-usage',\n order: 10,\n locale: NS,\n inject: (sessionId: string): SubscriptionUsageBadgeInjected => ({\n rpc: connection.rpc,\n currentModel: createCurrentModelReader(models, sessionId),\n }),\n }, SubscriptionUsageBadge))\n\n // The /fast slash command offers the same Standard/Fast choice as a popup.\n // `available` is synchronous and sees only the session id, so the command\n // stays listed everywhere; `options` throws the friendly gate when the\n // session's current model is not a fast-capable codex model (the same\n // in-popup error posture the /model contribution uses for its guards).\n ctx.inject(['commandUi'], (scope: ClientContext) => {\n const command = scope.get('commandUi') as CommandUiContract\n scope.effect(() => command.register({\n name: 'fast',\n // dsh 0.1.5-alpha made `description` a locale resolver evaluated per\n // candidate pass (commit 5d9603b76, \"feat(web): localize slash command\n // descriptions\"); earlier lines read the value as a plain string. The\n // bare string threw `contribution.description is not a function` inside\n // the registry's candidate pass on 0.1.5, aborting the whole `/` source\n // and hiding every host command — /plan, /model, /goal, ... — not just\n // /fast. Older lines render a function child as empty copy, no crash.\n description: fastCommandDescription(() => t('commandFast')),\n available: () => true,\n ui: {\n kind: 'popupSelect',\n options: async (session) => {\n const state = await createSpeedLoader(connection, models, session.sessionId)()\n if (!state.visible) throw new Error(t('commandFastUnavailable'))\n return ([\n { id: 'standard', label: t('speedStandard'), detail: t('speedStandardDescription') },\n { id: 'fast', label: t('speedFast'), detail: t('speedFastDescription') },\n ] as const).map(option => ({ ...option, active: option.id === state.tier }))\n },\n onSelect: async (option, session) => {\n await createSpeedSetter(connection, session.sessionId)(option.id as 'standard' | 'fast')\n },\n },\n }), 'dsh-subscriptions: /fast contribution')\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,MAAa,KAAK;CAChB,gBAAgB;CAChB,eAAe;CACf,cAAc;CACd,iBAAiB;CACjB,oBAAoB;CACpB,oBAAoB;CACpB,eAAe;CACf,eAAe;CACf,qBAAqB;CACrB,qBAAqB;CACrB,yBAAyB;CACzB,gBAAgB;CAChB,mBAAmB;CACnB,qBAAqB;CACrB,oBAAoB;CACpB,yBAAyB;CACzB,kBAAkB;CAClB,4BAA4B;CAC5B,mBAAmB;CACnB,YAAY;CACZ,YAAY;CACZ,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,eAAe;CACf,qBAAqB;CACrB,mBAAmB;CACnB,sBAAsB;CACtB,aAAa;CACb,iBAAiB;CACjB,aAAa;CACb,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,YAAY;CACZ,mBAAmB;CAEnB,KAAK;CACL,OAAO;CACP,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,kBAAkB;CAClB,oBAAoB;CACpB,uBAAuB;CACvB,qBAAqB;CACrB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,iBAAiB;CACjB,oBAAoB;CACpB,gBAAgB;CAChB,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,sBAAsB;CACtB,eAAe;CACf,mBAAmB;CACnB,QAAQ;CACR,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,oBAAoB;CACpB,YAAY;CACZ,cAAc;CACd,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,cAAc;CACd,aAAa;CACb,cAAc;CACd,aAAa;CACb,aAAa;CACb,gBAAgB;CAChB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,oBAAoB;CACpB,mBAAmB;CACnB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,qBAAqB;CACrB,uBAAuB;CACvB,iBAAiB;CACjB,cAAc;CACd,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;CAClB,iBAAiB;CACjB,oBAAoB;CACpB,mBAAmB;CACnB,qBAAqB;CACrB,oBAAoB;CACpB,yBAAyB;CACzB,WAAW;CACX,mBAAmB;CACnB,uBAAuB;CACvB,mBAAmB;CACnB,wBAAwB;CACxB,qBAAqB;CACrB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,mBAAmB;CACnB,sBAAsB;CACtB,oBAAoB;CACpB,sBAAsB;CACtB,iBAAiB;CACjB,6BAA6B;CAC7B,0BAA0B;CAC1B,gBAAgB;CAChB,kBAAkB;CAClB,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,eAAe;CACf,sBAAsB;CACtB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,oBAAoB;CACpB,0BAA0B;CAC1B,oBAAoB;CACpB,wBAAwB;CACxB,4BAA4B;CAC5B,qBAAqB;CACrB,wBAAwB;CACxB,0BAA0B;CAC1B,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,oBAAoB;CACpB,kBAAkB;CAClB,oBAAoB;CACpB,qBAAqB;CACrB,mBAAmB;CACnB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;CACd,mBAAmB;CACnB,wBAAwB;CACxB,oBAAoB;CACpB,mBAAmB;CACnB,6BAA6B;CAC7B,uBAAuB;CACvB,sBAAsB;CACtB,yBAAyB;CACzB,oBAAoB;CACpB,sBAAsB;CACtB,qBAAqB;CACrB,8BAA8B;CAC9B,sBAAsB;CACtB,0BAA0B;CAC1B,2BAA2B;CAC3B,gCAAgC;CAChC,0BAA0B;CAC1B,YAAY;CACZ,OAAO;CACP,WAAW;CACX,gBAAgB;CAChB,cAAc;CACd,iBAAiB;CACjB,cAAc;CACd,YAAY;CACZ,iBAAiB;CACjB,cAAc;CACd,iBAAiB;CACjB,iBAAiB;CACjB,mBAAmB;CACnB,yBAAyB;CACzB,yBAAyB;CACzB,yBAAyB;CACzB,uBAAuB;CACvB,6BAA6B;CAC7B,mBAAmB;CACnB,sBAAsB;CACtB,4BAA4B;CAC5B,uBAAuB;CACvB,OAAO;CACP,eAAe;CACf,0BAA0B;CAC1B,WAAW;CACX,sBAAsB;CACtB,aAAa;CACb,wBAAwB;CACzB;;AAGD,MAAa,KAAK;CAChB,gBAAgB;CAChB,eAAe;CACf,cAAc;CACd,iBAAiB;CACjB,oBAAoB;CACpB,oBAAoB;CACpB,eAAe;CACf,eAAe;CACf,qBAAqB;CACrB,qBAAqB;CACrB,yBAAyB;CACzB,gBAAgB;CAChB,mBAAmB;CACnB,qBAAqB;CACrB,oBAAoB;CACpB,yBAAyB;CACzB,kBAAkB;CAClB,4BAA4B;CAC5B,mBAAmB;CACnB,YAAY;CACZ,YAAY;CACZ,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,eAAe;CACf,qBAAqB;CACrB,mBAAmB;CACnB,sBAAsB;CACtB,aAAa;CACb,iBAAiB;CACjB,aAAa;CACb,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,YAAY;CACZ,mBAAmB;CAEnB,KAAK;CACL,OAAO;CACP,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,kBAAkB;CAClB,oBAAoB;CACpB,uBAAuB;CACvB,qBAAqB;CACrB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,iBAAiB;CACjB,oBAAoB;CACpB,gBAAgB;CAChB,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,sBAAsB;CACtB,eAAe;CACf,mBAAmB;CACnB,QAAQ;CACR,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,oBAAoB;CACpB,YAAY;CACZ,cAAc;CACd,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,cAAc;CACd,aAAa;CACb,cAAc;CACd,aAAa;CACb,aAAa;CACb,gBAAgB;CAChB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,oBAAoB;CACpB,mBAAmB;CACnB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,qBAAqB;CACrB,uBAAuB;CACvB,iBAAiB;CACjB,cAAc;CACd,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;CAClB,iBAAiB;CACjB,oBAAoB;CACpB,mBAAmB;CACnB,qBAAqB;CACrB,oBAAoB;CACpB,yBAAyB;CACzB,WAAW;CACX,mBAAmB;CACnB,uBAAuB;CACvB,mBAAmB;CACnB,wBAAwB;CACxB,qBAAqB;CACrB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,mBAAmB;CACnB,sBAAsB;CACtB,oBAAoB;CACpB,sBAAsB;CACtB,iBAAiB;CACjB,6BAA6B;CAC7B,0BAA0B;CAC1B,gBAAgB;CAChB,kBAAkB;CAClB,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,eAAe;CACf,sBAAsB;CACtB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,oBAAoB;CACpB,0BAA0B;CAC1B,oBAAoB;CACpB,wBAAwB;CACxB,4BAA4B;CAC5B,qBAAqB;CACrB,wBAAwB;CACxB,0BAA0B;CAC1B,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,oBAAoB;CACpB,kBAAkB;CAClB,oBAAoB;CACpB,qBAAqB;CACrB,mBAAmB;CACnB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;CACd,mBAAmB;CACnB,wBAAwB;CACxB,oBAAoB;CACpB,mBAAmB;CACnB,6BAA6B;CAC7B,uBAAuB;CACvB,sBAAsB;CACtB,yBAAyB;CACzB,oBAAoB;CACpB,sBAAsB;CACtB,qBAAqB;CACrB,8BAA8B;CAC9B,sBAAsB;CACtB,0BAA0B;CAC1B,2BAA2B;CAC3B,gCAAgC;CAChC,0BAA0B;CAC1B,YAAY;CACZ,OAAO;CACP,WAAW;CACX,gBAAgB;CAChB,cAAc;CACd,iBAAiB;CACjB,cAAc;CACd,YAAY;CACZ,iBAAiB;CACjB,cAAc;CACd,iBAAiB;CACjB,iBAAiB;CACjB,mBAAmB;CACnB,yBAAyB;CACzB,yBAAyB;CACzB,yBAAyB;CACzB,uBAAuB;CACvB,6BAA6B;CAC7B,mBAAmB;CACnB,sBAAsB;CACtB,4BAA4B;CAC5B,uBAAuB;CACvB,OAAO;CACP,eAAe;CACf,0BAA0B;CAC1B,WAAW;CACX,sBAAsB;CACtB,aAAa;CACb,wBAAwB;CACzB;;;;;ACrZD,SAAgB,iBAAiB,OAI9B,MAAM,KAAK,KAAK,EAAuE;CACxF,MAAM,SAAS,MAAM,SAAS,MAAK,MAAK,EAAE,SAAS,YAAY,EAAE,UAAU,OAAU;AACrF,KAAI,CAAC,UAAU,CAAC,OAAO,SAAS,OAAO,YAAY,CAAE,QAAO;AAC5D,KAAI,OAAO,cAAc,GAAI,QAAO;AACpC,KAAI,OAAO,aAAa,UAAa,OAAO,YAAY,OAAO,MAAM,kBAAmB,QAAO;AAC/F,KAAI,CAAC,MAAM,cAAc,MAAK,MAAK,EAAE,GAAG,CAAE,QAAO;AACjD,KAAI,CAAC,MAAM,aAAa,MAAK,MAAK,EAAE,OAAO,EAAE,cAAc,UAAa,EAAE,YAAY,KAAK,CAAE,QAAO;;;;;;;;;;;;ACFtG,MAAM,6BAA6B;AACnC,MAAM,4BAA4B;;AAGlC,IAAa,yBAAb,cAA4C,MAAM;;;;;;;;;;AAWlD,eAAsB,sBAAyB,KAA8B,UAAkB,SAA8B;CAC3H,IAAIA;AACJ,KAAI;AACF,WAAS,MAAM,IAAI,KAAK,4BAA4B,GAAG,4BAA4B,YAAY,QAAQ;UAChG,OAAO;AAEd,QAAM,IAAI,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;;AAE1F,KAAI,CAAC,OAAO,GAAI,OAAM,IAAI,uBAAuB,OAAO,MAAM,QAAQ;AACtE,QAAO,OAAO;;;;;;ACvBhB,SAAgB,qBAAqB,SAA6B,QAAgD;AAChH,QAAO,IAAI,IAAI,QAAQ,cAAc,OAAO,KAAI,UAAS,MAAM,GAAG,CAAC;;;AAIrE,SAAgB,iBAAiB,SAA4B,aAAiC;CAC5F,MAAM,QAAQ,IAAI,IAAI,QAAQ,OAAO,KAAI,UAAS,MAAM,GAAG,CAAC;AAC5D,QAAO,CACL,GAAG,QAAQ,OAAO,KAAI,WAAU;EAAE,GAAG;EAAO,aAAa;EAAO,EAAE,EAClE,IAAI,YAAY,cAAc,EAAE,EAAE,QAAO,OAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,KAAI,QAAO;EAAE;EAAI,MAAM;EAAI,aAAa;EAAM,EAAE,CAChH;;;AAIH,SAAgB,oBAAoB,OAA4B,QAAkD;CAChH,MAAM,EAAE,UAAU,OAAQ,GAAG,aAAa;AAC1C,QAAO;EAAE,GAAG;EAAU,GAAI,OAAO,aAAa,SAAY,EAAE,GAAG,EAAE,UAAU,OAAO,UAAU;EAAG;;;AAIjG,SAAgB,oBACd,QACA,SACqB;AACrB,QAAO;EAAE,GAAG;EAAQ,UAAU;GAAE,GAAG,OAAO;GAAU,GAAG;GAAS;EAAE;;;;;ACepE,MAAMC,WAAS;AACf,MAAMC,YAAyB;CAAE,SAAS;CAAQ,UAAU;CAAQ,KAAK;CAAG,YAAY;CAAU;;;;;;;AAQlG,MAAa,4CAAmE,SAASC,sBACvF,EAAE,UAAU,KAAK,GAAG,WAAW,OAAO,iBAAiB,KACvD;CACA,MAAM,CAAC,SAAS,mCAAiC;CACjD,MAAM,CAAC,OAAO,gCAA0C,EAAE,CAAC;CAC3D,MAAM,CAAC,UAAU,mCAAgD,EAAE,CAAC;CACpE,MAAM,CAAC,SAAS,kCAA+C,EAAE,CAAC;CAClE,MAAM,CAAC,OAAO,gCAAqB,GAAG;CACtC,MAAM,CAAC,MAAM,+BAAoB,MAAM;CACvC,MAAM,CAAC,OAAO,gCAAqB,MAAM;CACzC,MAAM,CAAC,OAAO,gCAAqB,GAAG;CACtC,MAAM,+BAAoB,EAAE;AAC5B,kCAAsB;AAAE,aAAW;IAAa,EAAE,CAAC;AACnD,4BAAgB;AAAE,kBAAgB,MAAM;IAAI,CAAC,MAAM,CAAC;CAEpD,SAAS,MAAM,MAAe;AAC5B,aAAW,KAAK;AAChB,WAAS,KAAK,SAAS;AACvB,aAAW,OAAO,YAAY,KAAK,OAAO,KAAI,UAAS,CAAC,MAAM,IAAI,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC;AAC5F,cAAY,OAAO,YAAY,OAAO,QAAQ,KAAK,SAAS,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7H,WAAS,MAAM;;CAEjB,eAAe,KAAK,QAAQ,OAAO;EACjC,MAAM,UAAU,EAAE,WAAW;AAC7B,UAAQ,KAAK;AACb,WAAS,GAAG;AACZ,MAAI;GACF,MAAM,OAAO,MAAM,sBAA+B,KAChD,aAAa,wBAAwB,mBAAmB,oBAAoB;IAAE;IAAU;IAAO,CAAC;AAClG,OAAI,WAAW,YAAY,QAAS,OAAM,KAAK;WACxCC,SAAO;AACd,OAAI,WAAW,YAAY,QAAS,UAAS,OAAOA,mBAAiB,QAAQA,QAAM,UAAUA,QAAM,CAAC;YAC5F;AACR,OAAI,WAAW,YAAY,QAAS,SAAQ,MAAM;;;CAGtD,SAAS,KAAK,MAA2B;AAAE,WAAS,KAAK;AAAE,WAAS,KAAK;;AACzE,4BAAgB;AAAE,EAAK,MAAM;IAAI,CAAC,UAAU,IAAI,CAAC;AAEjD,gCAAoB,YAAY,EAC9B,UAAU;AACR,MAAI,CAAC,WAAW,CAAC,MAAO,QAAO,EAAE,SAAS,EAAE,EAAE;EAC9C,MAAMC,UAAkC,OAAO,OAAO,KAAK;AAC3D,OAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,SAAS,EAAE;AACpD,OAAI,CAAC,KAAK,MAAM,CAAE;GAClB,MAAM,QAAQ,OAAO,KAAK;AAC1B,OAAI,CAAC,QAAQ,KAAK,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,cAAc,MAAM,IAAI,SAAS,GAAG;AAC5E,aAAS,EAAE,wBAAwB,EAAE,OAAO,CAAC,CAAC;AAC9C;;AAEF,WAAQ,SAAS;;AAEnB,WAAS,GAAG;EACZ,MAAM,EAAE,UAAU,UAAW,GAAG,aAAa;GAAE,GAAG;GAAO,GAAI,aAAa,UAAU,EAAE,gBAAgB,SAAS,GAAG,EAAE;GAAG;AACvH,SAAO;GACL;GACA,SAAS,QAAQ,OAAO,SAAQ,UAAS;IACvC,MAAM,SAAS,QAAQ,MAAM,OAAO;AACpC,WAAO,YAAY,MAAM,cAAc,OAAO,CAAC,MAAM,SAAS,SAAS,EAAE,GAAG,CAAC;KAAE,OAAO,MAAM;KAAI;KAAQ,CAAC;KACzG;GACH;IAEJ,GAAG;EAAC;EAAS;EAAO;EAAO;EAAU;EAAS;EAAS,CAAC;CAEzD,MAAM,YAAY,SAAS,UAAU,EAAE;CACvC,MAAM,QAAQ,IAAI,IAAI,UAAU,KAAI,UAAS,MAAM,GAAG,CAAC;CACvD,MAAM,WAAW,MAAM,iBAAiB,EAAE,EAAE,QAAO,OAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,KAAI,QAAO;EAAE;EAAI,MAAM;EAAI,EAAc;CAClH,MAAM,SAAS,CAAC,GAAG,WAAW,GAAG,QAAQ,CAAC,QAAO,UAAS,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK,aAAa,CAAC,SAAS,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;CACzI,MAAM,WAAW,IAAI,IAAI,MAAM,iBAAiB,UAAU,KAAI,UAAS,MAAM,GAAG,CAAC;AACjF,QAAO,4CAAC;EAAI,OAAO;GAAE,WAAWJ;GAAQ,WAAW;GAAI,YAAY;GAAI;aACrE,2CAAC;GAAG,OAAO,EAAE,QAAQ,GAAG;aAAG,EAAE,aAAa;IAAM,EAChD,4CAAC;GAAI,OAAO;IAAE,SAAS;IAAQ,KAAK;IAAI,WAAW;IAAI;;IACrD,2CAAC;KAAE,WAAU;eAAyB,EAAE,aAAa,wBAAwB,qBAAqB,aAAa;MAAK;IACnH,SAAS,2CAAC;KAAE,MAAK;eAAS;MAAU;IACrC,4CAAC;KAAI,OAAOK;gBACV,2CAAC;MAAO,MAAK;MAAS,WAAU;MAAyB,UAAU,QAAQ,YAAY;MAAO,eAAe;AAAE,OAAK,KAAK,KAAK;;gBAAK,EAAE,eAAe;OAAU,EAC7J,QAAQ,2CAAC;MAAK,MAAK;gBAAU,EAAE,uBAAuB;OAAQ;MAC3D;IACL,WAAW,4CAAC;KAAS,UAAU,QAAQ;KAAU,OAAO;MAAE,QAAQ;MAAG,SAAS;MAAG,QAAQ;MAAG,UAAU;MAAG,SAAS;MAAQ,KAAK;MAAI;;MAClI,4CAAC;OAAM,2CAAC;QAAM,MAAK;QAAW,SAAS,MAAM,kBAAkB;QAAW,WAAU,UAAS;SAC3F,MAAM,OAAO,EAAE,GAAG,OAAO;AACzB,aAAI,MAAM,OAAO,QAAS,QAAO,KAAK;aACjC,MAAK,gBAAgB,UAAU,KAAI,UAAS,MAAM,GAAG;AAC1D,cAAK,KAAK;;SACP;;OAAE,EAAE,kBAAkB;UAAS;MACpC,4CAAC;OAAI,OAAOA;;QACV,2CAAC;SAAM,OAAO,EAAE,MAAM,aAAa;SAAE,OAAO;SAAO,WAAU,UAAS,SAAS,MAAM,OAAO,MAAM;SAChG,aAAa,EAAE,iCAAiC;SAAE,cAAY,EAAE,iCAAiC;UAAI;QACvG,2CAAC;SAAO,MAAK;SAAS,eAAe,KAAK;UAAE,GAAG;UAAO,eAAe,UAAU,KAAI,UAAS,MAAM,GAAG;UAAE,CAAC;mBAAG,EAAE,kBAAkB;UAAU;QACzI,2CAAC;SAAO,MAAK;SAAS,eAAe,KAAK;UAAE,GAAG;UAAO,eAAe,EAAE;UAAE,CAAC;mBAAG,EAAE,mBAAmB;UAAU;;QACxG;MACN,4CAAC;OAAI,OAAO;QAAE,WAAW;QAAK,WAAW;QAAQ,SAAS;QAAQ,KAAK;QAAG;kBACvE,OAAO,KAAI,UAAS,4CAAC;QAAmB,OAAO;SAAE,cAAcL;SAAQ,SAAS;SAAW,SAAS;SAAQ,KAAK;SAAG;mBACnH,4CAAC;SAAM,OAAO,EAAE,cAAc,YAAY;;UAAE,2CAAC;WAAM,MAAK;WAAW,SAAS,SAAS,IAAI,MAAM,GAAG;WAAE,WAAU,UAAS;YACrH,MAAM,OAAO,IAAI,IAAI,SAAS;AAC9B,gBAAI,MAAM,OAAO,QAAS,MAAK,IAAI,MAAM,GAAG;gBAAO,MAAK,OAAO,MAAM,GAAG;AACxE,iBAAK;aAAE,GAAG;aAAO,eAAe,CAAC,GAAG,KAAK;aAAE,CAAC;;YACzC;;UAAE,MAAM;UAAM,CAAC,MAAM,IAAI,MAAM,GAAG,IAAI,KAAK,EAAE,oBAAoB,CAAC;;UAAW,EAClF,4CAAC;SAAI,OAAOK;qBACV,MAAM,SAAS,UAAU,KAAK,KAAK,4CAAC;UAAM,OAAOA;qBAAU,EAAE,qBAAqB,EAClF,4CAAC;WAAO,cAAY,GAAG,MAAM,KAAK,GAAG,EAAE,qBAAqB;WAC1D,OAAO,QAAQ,MAAM,OAAO;WAAI,WAAU,UAAS;AACjD,uBAAW;aAAE,GAAG;cAAU,MAAM,KAAK,MAAM,OAAO;aAAO,CAAC;AAAE,qBAAS,KAAK;;;YAE5E,2CAAC;aAAO,OAAM;uBAAI,EAAE,8BAA8B;cAAU;YAC3D,MAAM,cAAc,CAAC,MAAM,SAAS,MAAK,WAAU,OAAO,OAAO,MAAM,WAAW,IACjF,4CAAC;aAAO,OAAO,MAAM;aAAY;;cAAU,MAAM;cAAW;cAAG,EAAE,oBAAoB;cAAC;;cAAU;YACjG,MAAM,SAAS,KAAI,WAAU,2CAAC;aAAuB,OAAO,OAAO;uBAAK,OAAO;eAArC,OAAO,GAA4C,CAAC;;YACxF;WACH,EACP,aAAa,WAAW,MAAM,qBAAqB,UAAa,4CAAC;UAAI,OAAOA;qBAC3E,4CAAC;WAAM,OAAOA;sBAAU,EAAE,gBAAgB,EACxC,2CAAC;YAAM,OAAO,EAAE,OAAO,KAAK;YAAE,WAAU;YAAU,OAAO,SAAS,MAAM,OAAO;YAC7E,cAAY,GAAG,MAAM,KAAK,GAAG,EAAE,gBAAgB;YAAI,aAAa,OAAO,MAAM,qBAAqB;YAClG,WAAU,UAAS;AAAE,yBAAY;cAAE,GAAG;eAAW,MAAM,KAAK,MAAM,OAAO;cAAO,CAAC;AAAE,sBAAS,KAAK;;aAAM;YACnG,EACR,2CAAC,qBAAO,EAAE,uBAAuB;WAAE,SAAS,MAAM;WAAsB,KAAK,MAAM;WAAkB,CAAC,GAAS;WAC3G;UACA;UA1BuB,MAAM,GA2B/B,CAAC,EACN,OAAO,WAAW,KAAK,2CAAC,oBAAM,EAAE,4BAA4B,EAAE,OAAO,CAAC,GAAQ;QAC3E;MACL,aAAa,WAAW,2CAAC,qBAAO,EAAE,oBAAoB,GAAS;MAC/D,QAAQ,MAAM,SAAS,KAAK,4CAAC;OAAI,OAAO;QAAE,SAAS;QAAQ,KAAK;QAAG;;QAClE,2CAAC,sBAAQ,EAAE,cAAc,GAAU;QACnC,2CAAC,qBAAO,EAAE,kBAAkB,GAAS;QACpC,QAAQ,MAAM,KAAI,SAAQ,4CAAC;SAC1B,2CAAC;UAAM,MAAK;UAAW,SAAS,MAAM,QAAQ,UAAU;UAAO,WAAU,UAAS,KAAK;WACrF,GAAG;WAAO,OAAO;YAAE,GAAG,MAAM;aAAQ,OAAO,MAAM,OAAO;YAAS;WAClE,CAAC;WAAI;;SAAE,EAAE,SAAS,mBAAmB,gBAAgB,SAAS,mBAAmB,gBAAgB,SAAS,eAAe,oBAAoB,eAAe;aAHxH,KAI/B,CAAC;;QACL;;MACG;;IACP;GACF;EACN;;;;;;;;;;;;;;;;ACrLF,MAAM,YAAY;AAElB,MAAa,sBAAsB;;;;;;;;;;;;;;;;;;;;;;EAsBjC,UAAU;;;;;EAKV,UAAU;;;;;EAKV,UAAU;EACV,UAAU;;;;;EAKV,UAAU;;;;;EAKV,UAAU;EACV,UAAU;EACV,UAAU;;;;;;EAMV,UAAU;;;;;;EAMV,UAAU;EACV,UAAU;;;;;;;;;;;;;;EAcV,UAAU;;;;EAIV,UAAU;EACV,UAAU;;;;EAIV,UAAU;EACV,UAAU;;;;EAIV,UAAU;;;EAGV,UAAU;;;;EAIV,UAAU;;;;;;;;EAQV,UAAU;;;;;;;;EAQV,UAAU;;;;EAIV,UAAU;;;;;;;;;;;;;;;;;EAiBV,UAAU;;;EAGV,UAAU;;;EAGV,UAAU;;;;EAIV,UAAU;;;;EAIV,UAAU;;;;;;;EAOV,UAAU;;;;;;EAMV,UAAU;;;EAGV,UAAU;EACV,UAAU;EACV,UAAU;;;;EAIV,UAAU;;;EAGV,UAAU;;;;;AAMZ,MAAa,wBAAwB;;;;;;;;;;;;;;;;;;;;;;ACxKrC,MAAM,SAAS;AACf,MAAMC,QAAuB;CAAE,SAAS;CAAQ,KAAK;CAAI,UAAU;CAAG;AACtE,MAAMC,UAAyB;CAAE,SAAS;CAAQ,UAAU;CAAQ,KAAK;CAAG,YAAY;CAAU;;AAGlG,SAAgB,uBAAuB,EAAE,UAAU,MAAM,KAAK,GAAG,WAAkB;CACjF,MAAM,2BAAmC,KAAK;CAC9C,MAAM,0BAAe;CACrB,MAAM,gCAAqB;CAC3B,MAAM,CAAC,SAAS,mCAAiC;CACjD,MAAM,CAAC,SAAS,kCAA2D,EAAE,CAAC;CAC9E,MAAM,CAAC,SAAS,kCAAuB,KAAK;CAC5C,MAAM,CAAC,QAAQ,iCAAsB,MAAM;CAC3C,MAAM,CAAC,OAAO,gCAAqB,GAAG;CACtC,MAAM,CAAC,WAAW,oCAAyB,GAAG;CAC9C,MAAM,CAAC,SAAS,kCAAuB,EAAE;CACzC,MAAM,CAAC,aAAa,sCAA2B,MAAM;CACrD,MAAM,0BAAe,KAAK;CAC1B,MAAM,6BAAkB,MAAM;CAC9B,MAAM,2BAA2C,KAAK;AACtD,4BAAgB;AACd,QAAM,UAAU;EAChB,MAAM,UAAU,OAAO;EACvB,MAAM,WAAW,SAAS;AAC1B,UAAQ,WAAW;AACnB,eAAa;AACX,SAAM,UAAU;AAChB,WAAQ,OAAO;AACf,OAAI,oBAAoB,eAAe,SAAS,YAAa,UAAS,OAAO;;IAE9E,EAAE,CAAC;AACN,4BAAgB;EACd,IAAI,UAAU;AACd,aAAW,KAAK;AAChB,WAAS,GAAG;AACZ,EAAK,sBAA+B,KAClC,aAAa,wBAAwB,mBAAmB,oBAAoB,EAAE,UAAU,CAAC,CAAC,MAAK,SAAQ;AACvG,OAAI,QAAS,YAAW,KAAK;IAC7B,CAAC,OAAM,YAAS;AAChB,OAAI,QAAS,UAAS,EAAE,sBAAsB,EAAE,SAASC,mBAAiB,QAAQA,QAAM,UAAU,OAAOA,QAAM,EAAE,CAAC,CAAC;IACnH,CAAC,cAAc;AAAE,OAAI,QAAS,YAAW,MAAM;IAAG;AACpD,eAAa;AAAE,aAAU;;IACxB;EAAC;EAAU;EAAK;EAAQ,CAAC;CAE5B,SAAS,KAAK,KAAa,MAA0B;AACnD,cAAW,aAAY;GAAE,GAAG;IAAU,MAAM;GAAM,EAAE;;;;;;;CAOtD,eAAe,OAAO;AACpB,MAAI,SAAS,QAAS;EAGtB,MAAM,SAAS,OAAO,YAAY,OAAO,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,QAAQ,SAAS;AACnF,MAAI,WAAW,OAAW;AAC1B,WAAS,UAAU;AACnB,YAAU,KAAK;AACf,eAAa,GAAG;EAChB,IAAI,eAAe;AACnB,MAAI;AACF,OAAI,aAAa,sBACf,MAAK,MAAM,EAAE,OAAO,YAAY,OAAO,SAAS;AAC9C,UAAM,sBAAsB,KAAK,mBAAmB;KAAE;KAAU;KAAO,GAAI,SAAS,EAAE,QAAQ,GAAG,EAAE;KAAG,CAAC;AACvG;AACA,QAAI,CAAC,MAAM,QAAS;;GAKxB,MAAM,SAAS,MAAM,sBAA+B,KAClD,aAAa,wBAAwB,mBAAmB,oBAAoB,EAAE,UAAU,CAAC;AAC3F,OAAI,CAAC,MAAM,QAAS;AACpB,OAAI,aAAa,sBACf,OAAM,sBAAsB,KAAK,qBAAqB,EAAE,UAAU,OAAO,YAAY,OAAO,UAAU,CAAC;OAGvG,OAAM,sBAAsB,KAAK,uBAAuB;IAAE;IAAU,UAAU,oBADjE,OAAO,aAAa,SAAY,OAAO,WAAW,oBAAoB,OAAO,UAAU,OAAO,SAAS,EACZ,QAAQ;IAAE,CAAC;AAErH,OAAI,MAAM,QAAS,UAAS;WACrBA,SAAO;AACd,OAAI,MAAM,SAAS;IACjB,MAAMC,YAAUD,mBAAiB,QAAQA,QAAM,UAAU,OAAOA,QAAM;AACtE,kBAAc,eAAe,EAAE,oBAAoB,GAAG,MAAM,MAAM,EAAE,sBAAsB,EAAE,oBAAS,CAAC,CAAC;;YAEjG;AACR,YAAS,UAAU;AACnB,OAAI,MAAM,QAAS,WAAU,MAAM;;;AAGvC,QAAO,4CAAC;EAAO,WAAU;EAA2B,KAAK;EAAQ,mBAAiB;EAAO,oBAAkB;EACzG,WAAU,UAAS;AAAE,OAAI,SAAS,QAAS,OAAM,gBAAgB;;EAAa;EAC9E,OAAO;GAAE,OAAO;GAAK,UAAU;GAAsB,WAAW;GAAuB,UAAU;GAAQ;aACzG,2CAAC,qBAAO,sBAA4B,EACpC,4CAAC;GAAI,OAAO;IAAE,GAAG;IAAO,SAAS;IAAI;;IACnC,4CAAC;KAAO,OAAO;MAAE,GAAG;MAAS,gBAAgB;MAAiB;gBAC5D,2CAAC;MAAG,IAAI;MAAO,OAAO,EAAE,QAAQ,GAAG;gBAAG,EAAE,iBAAiB,EAAE,UAAU,MAAM,CAAC;OAAM,EAClF,2CAAC;MAAO,MAAK;MAAS;MAAU,UAAU;MAAQ,SAAS;gBAAU,EAAE,aAAa;OAAU;MACvF;IACT,2CAAC;KAAE,IAAI;KAAa,WAAU;eAAyB,EAAE,aAAa,wBAAwB,uBAAuB,eAAe;MAAK;IACxI,SAAS,2CAAC;KAAE,MAAK;eAAS;MAAU;IACpC,WAAW,2CAAC;KAAE,MAAK;KAAS,WAAU;eAAyB,EAAE,kBAAkB;MAAK;IACxF,CAAC,WAAW,CAAC,WAAW,2CAAC;KAAO,MAAK;KAAS,eAAe,YAAW,UAAS,QAAQ,EAAE;eAAG,EAAE,qBAAqB;MAAU;IAC/H,WAAW,4CAAC;KAAS,UAAU,UAAU;KAAS,OAAO;MAAE,GAAG;MAAO,QAAQ;MAAG,QAAQ;MAAG,SAAS;MAAG;;MACrG,QAAQ,SAAS,WAAW,KAAK,2CAAC;OAAE,WAAU;iBAAyB,EAAE,aAAa,wBAAwB,uBAAuB,gBAAgB;QAAK;MAC1J,aAAa,yBAAyB,QAAQ,SAAS,SAAS,KAC/D,4CAAC;OAAS,OAAO;QAAE;QAAQ,cAAc;QAA8B,SAAS;QAAI;kBAClF,2CAAC;QAAO,OAAO,EAAE,SAAS,SAAS;kBAAG;SAAc,EACpD,2CAAC;QAAE,WAAU;kBAAyB,EAAE,kBAAkB;SAAK;QACtD;MACZ,aAAa,yBAAyB,QAAQ,SAAS,KAAI,YAAW;OACrE,MAAM,cAAc,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,WAAW,QAAQ,QAAQ,EAAE;OAC1F,MAAM,WAAW,qBAAqB,aAAa,QAAQ,OAAO;OAClE,MAAM,SAAS,iBAAiB,SAAS,YAAY;AACrD,cAAO,4CAAC;QAA2B,OAAO;SAAE,GAAG;SAAO;SAAQ,cAAc;SAA8B,SAAS;SAAI,QAAQ;SAAG;;SAChI,2CAAC;UAAO,OAAO;WAAE,SAAS;WAAS,cAAc;WAAY,UAAU;WAAQ;oBAAG,QAAQ;WAAe;SACxG,QAAQ,eAAe,2CAAC;UAAE,WAAU;oBAAyB,EAAE,6BAA6B;WAAK;SAClG,4CAAC;UAAM,OAAO;WAAE,GAAG;WAAO,KAAK;WAAG;qBAChC,2CAAC;WAAK,WAAU;qBAA0B,EAAE,gBAAgB;YAAQ,EACpE,2CAAC;WAAM,OAAO,YAAY,SAAS;WAAI,aAAa,QAAQ;WAC1D,WAAU,UAAS;YACjB,MAAM,OAAO,EAAE,GAAG,aAAa;AAC/B,gBAAI,MAAM,OAAO,MAAM,MAAM,CAAE,MAAK,QAAQ,MAAM,OAAO;gBACpD,QAAO,KAAK;AACjB,iBAAK,QAAQ,KAAK,KAAK;;YACpB;WACD;SACR,4CAAC;UAAM,2CAAC;WAAM,MAAK;WAAW,SAAS,YAAY,gBAAgB;WACjE,WAAU,UAAS,KAAK,QAAQ,KAAK;YAAE,GAAG;YAAa,aAAa,MAAM,OAAO;YAAS,CAAC;YAAI;;UAAE,EAAE,sBAAsB;aAAS;SACpI,4CAAC;UAAM,2CAAC;WAAM,MAAK;WAAW,SAAS,YAAY,qBAAqB;WACtE,WAAU,UAAS,KAAK,QAAQ,KAAK;YAAE,GAAG;YAAa,kBAAkB,MAAM,OAAO;YAAS,CAAC;YAAI;;UAAE,EAAE,sBAAsB;aAAS;SACzI,2CAAC;UAAE,WAAU;oBAAyB,EAAE,0BAA0B;WAAK;SACvE,4CAAC,wBACC,4CAAC;UAAQ,OAAO;WAAE,QAAQ;WAAW,UAAU;WAAI;;WAAG,EAAE,iBAAiB;WAAC;WAAI,YAAY,eAAe,SACrG,EAAE,oBAAoB,GAAG,EAAE,uBAAuB,EAAE,OAAO,YAAY,WAAW,QAAQ,CAAC;;WAAW,EAC1G,4CAAC;UAAI,OAAO;WAAE,GAAG;WAAO,WAAW;WAAI;;WACrC,2CAAC;YAAE,WAAU;sBAAyB,EAAE,qBAAqB;aAAK;WAClE,4CAAC;YAAM,2CAAC;aAAM,MAAK;aAAW,SAAS,YAAY,eAAe;aAAW,WAAU,UAAS;cAC9F,MAAM,OAAO,EAAE,GAAG,aAAa;AAC/B,kBAAI,MAAM,OAAO,QAAS,QAAO,KAAK;kBACjC,MAAK,aAAa,QAAQ,OAAO,KAAI,UAAS,MAAM,GAAG;AAC5D,mBAAK,QAAQ,KAAK,KAAK;;cACpB;;YAAE,EAAE,0BAA0B;eAAS;WAC5C,4CAAC;YAAI,OAAO;uBACV,2CAAC;aAAO,MAAK;aAAS,eAAe,KAAK,QAAQ,KAAK;cAAE,GAAG;cAAa,YAAY,OAAO,KAAI,UAAS,MAAM,GAAG;cAAE,CAAC;uBAAG,EAAE,kBAAkB;cAAU,EACtJ,2CAAC;aAAO,MAAK;aAAS,eAAe,KAAK,QAAQ,KAAK;cAAE,GAAG;cAAa,YAAY,EAAE;cAAE,CAAC;uBAAG,EAAE,mBAAmB;cAAU;aACxH;WACN,4CAAC;YAAI,OAAO;aAAE,GAAG;aAAO,KAAK;aAAG,WAAW;aAAK,WAAW;aAAQ;uBAChE,OAAO,KAAI,UAAS,4CAAC;aAAqB,OAAO,EAAE,cAAc,YAAY;;cAC5E,2CAAC;eAAM,MAAK;eAAW,SAAS,SAAS,IAAI,MAAM,GAAG;eAAE,WAAU,UAAS;gBACzE,MAAM,OAAO,IAAI,IAAI,SAAS;AAC9B,oBAAI,MAAM,OAAO,QAAS,MAAK,IAAI,MAAM,GAAG;oBAAO,MAAK,OAAO,MAAM,GAAG;AACxE,qBAAK,QAAQ,KAAK;iBAAE,GAAG;iBAAa,YAAY,CAAC,GAAG,KAAK;iBAAE,CAAC;;gBACzD;;cAAE,MAAM;cAAM,MAAM,eAAe,KAAK,EAAE,oBAAoB,CAAC;;eALrC,MAAM,GAM/B,CAAC,EACR,OAAO,WAAW,KAAK,2CAAC;aAAE,WAAU;uBAAyB,EAAE,mBAAmB;cAAK;aACpF;;WACF,IACE;;UA5CU,QAAQ,IA6CnB;QACX;;MACO;KACT,aAAa,0BAA0B,SAAS,SAAS,UAAU,KAAK,MACxE,2CAAC;KAAoB,KAAK;KAAkB;KAAe;KAAQ;KAAG,UAAU;KAAQ,eAAe;MAAkB;IAC3H,4CAAC;KAAO,OAAO;MAAE,GAAG;MAAO,KAAK;MAAG,WAAW;MAAQ,SAAS;MAC7D,UAAU;MAAU,QAAQ;MAAG,YAAY;MAA4D;gBACtG,aAAa,2CAAC;MAAE,MAAK;gBAAS;OAAc,EAC7C,4CAAC;MAAI,OAAO;OAAE,GAAG;OAAS,gBAAgB;OAAY;iBACpD,2CAAC;OAAO,MAAK;OAAS,UAAU;OAAQ,SAAS;iBAAU,EAAE,SAAS;QAAU,EAChF,2CAAC;OAAO,MAAK;OAAS,WAAU;OAA2B,UAAU,WAAW,UAAW,CAAC,OAAO,KAAK,QAAQ,CAAC,UAAU,CAAC;OAC1H,eAAe;AAAE,QAAK,MAAM;;iBAAK,SAAS,EAAE,sBAAsB,GAAG,EAAE,aAAa;QAAU;OAC5F;MACC;;IACL;GACC;;;;;;AClMX,MAAaE,yBAAwD;CACnE,MAAM;EACJ,QAAQ;EAAwC,cAAc;EAC9D,SAAS;EAAa,SAAS;EAAQ,eAAe;EAAU,KAAK;EACrE,OAAO;EACR;CACD,QAAQ;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAG;CACzD,KAAK;EAAE,OAAO;EAAG,QAAQ;EAAG,cAAc;EAAO,YAAY;EAAG;CAChE,MAAM;EAAE,YAAY;EAAK,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAkC;CACpG,QAAQ;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC;CACjG,OAAO;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAwC;CACrG,SAAS;EAAE,SAAS;EAAQ,KAAK;EAAG,WAAW;EAAG,YAAY;EAAU,UAAU;EAAQ;CAC1F,QAAQ;EACN,WAAW;EAAc,SAAS;EAAe,YAAY;EAAU,gBAAgB;EACvF,QAAQ;EAAI,SAAS;EAAU,cAAc;EAC7C,QAAQ;EAAwC,YAAY;EAC5D,OAAO;EAAkC,MAAM;EAAW,UAAU;EAAI,YAAY;EACpF,QAAQ;EACT;CACD,SAAS;EACP,SAAS;EAAQ,eAAe;EAAU,KAAK;EAC/C,QAAQ;EAAwC,cAAc;EAC9D,SAAS;EAAY,WAAW;EACjC;CACD,eAAe;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAG;CAChE,aAAa;EAAE,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAkC,YAAY;EAAO;CAC7G,aAAa,EAAE,OAAO,qCAAqC;CAC3D,OAAO;EACL,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAG,WAAW;EAC7D,WAAW;EAAwC,YAAY;EAChE;CACD,aAAa;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAG;CAC9D,YAAY;EAAE,UAAU;EAAI,YAAY;EAAQ,YAAY;EAAK,OAAO;EAAoC;CAC5G,WAAW;EAAE,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC;CACzF,cAAc;EACZ,WAAW;EAAc,SAAS;EAAe,YAAY;EAAU,gBAAgB;EACvF,QAAQ;EAAI,SAAS;EAAS,cAAc;EAAI,YAAY;EAC5D,QAAQ;EAAwC,YAAY;EAC5D,OAAO;EAAoC,MAAM;EAAW,UAAU;EAAI,YAAY;EACtF,QAAQ;EACT;CACD,UAAU;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAG;CAC9D,WAAW;EACT,SAAS;EAAQ,gBAAgB;EAAiB,KAAK;EACvD,UAAU;EAAI,YAAY;EAAQ,OAAO;EAC1C;CACF;;;;ACxCD,MAAM,WAAW;AACjB,MAAM,aAAa;AACnB,MAAa,4BAA4B;;AAGzC,SAAgB,qBAAqC;AACnD,KAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,KAAI;EACF,MAAM,QAAQ,OAAO,aAAa,QAAQ,SAAS;AACnD,SAAO,UAAU,YAAY,UAAU,WAAW,QAAQ;UACnD,OAAO;AACd,MAAI,EAAE,iBAAiB,iBAAiB,MAAM,SAAS,gBAAiB,OAAM;AAC9E,SAAO;;;;AAKX,SAAgB,kBAAkB,MAA4B;AAC5D,KAAI,SAAS,YAAY,SAAS,YAAY,SAAS,SAAU,OAAM,IAAI,UAAU,0CAA0C;AAC/H,QAAO,aAAa,QAAQ,UAAU,KAAK;AAC3C,QAAO,cAAc,IAAI,MAAM,WAAW,CAAC;;;AAI7C,SAAgB,wBAAwB,QAAgC;CACtE,MAAM,aAAa,UAA8B;AAC/C,MAAI,MAAM,QAAQ,YAAY,MAAM,QAAQ,KAAM,SAAQ;;AAE5D,QAAO,iBAAiB,YAAY,OAAO;AAC3C,QAAO,iBAAiB,WAAW,UAAU;AAC7C,cAAa;AACX,SAAO,oBAAoB,YAAY,OAAO;AAC9C,SAAO,oBAAoB,WAAW,UAAU;;;;AAKpD,SAAgB,oBAAoC;AAClD,wCAA4B,yBAAyB,0BAA0B,SAAS;;;;;AC1C1F,MAAa,qBAAqB,IAAI;AACtC,SAAgB,WAAW,MAAuB;AAChD,QAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,KAAK,QAAQ;;;;;;;AAQvD,SAAgB,mBAAmB,MAAkC;AACnE,QAAO,WAAW,KAAK,GAAG,KAAK,MAAM,KAAK,GAAG;;;;;;AAS/C,SAAgB,oBAAoB,IAA6B;CAC/D,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,IAAO,CAAC;AAMjD,QAL+B;EAC7B;GAAE,MAAM;GAAO,OAAO,KAAK,MAAM,QAAQ,KAAK;GAAE;EAChD;GAAE,MAAM;GAAQ,OAAO,KAAK,MAAO,QAAQ,OAAQ,GAAG;GAAE;EACxD;GAAE,MAAM;GAAU,OAAO,QAAQ;GAAI;EACtC,CACY,QAAO,SAAQ,KAAK,QAAQ,EAAE,CAAC,MAAM,GAAG,EAAE;;;;;;;;AAQzD,SAAgB,aAAa,UAAqB,aAA+B,MAAM,KAAK,KAAK,EAAW;AAC1G,QAAO,WAAWC,SAAO,YAAY,IAAI,YAAY,UAAU,QAC1D,YAAY,eAAe,UAAa,OAAO,SAAS,YAAY,WAAW,IAC/E,YAAY,cAAc,OAAO,MAAM,YAAY,cAAc,uBAChEA,SAAO,aAAa,UAAa,OAAO,SAASA,SAAO,SAAS,IAAIA,SAAO,WAAW;;;;;;;;;;AAW/F,SAAgB,eAAe,UAAqB,MAAM,KAAK,KAAK,EAAsB;CACxF,MAAM,MAAMA,SAAO;AACnB,KAAI,QAAQ,UAAa,CAAC,OAAO,SAAS,IAAI,IAAI,OAAO,IAAK,QAAO;CACrE,MAAM,WAAWA,SAAO;CACxB,MAAM,QAAQA,SAAO,aAAaA,SAAO,gBAAgB,QAAQ,aAAa,UAAa,OAAO,SAAS,SAAS,IAAI,WAAW,IAAI,MAAM,WAAW;AACxJ,KAAI,UAAU,UAAa,CAAC,OAAO,SAAS,MAAM,IAAI,SAAS,OAAO,QAAQ,IAAK,QAAO;AAC1F,QAAO,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,UAAU,MAAM,SAAS,IAAI,CAAC;;AAExE,SAAgB,gBAAgB,MAAc,SAA6B,QAA0B,OAAiC;AACpI,KAAI,CAAC,WAAW,KAAK,CAAE,QAAO;AAC9B,KAAI,QAAQ,GAAI,QAAO;AAEvB,KAAI,CAAC,SAAS,WAAW,eAAe,YAAY,OAAW,QAAO;AACtE,QAAO,OAAO,YAAY,WAAW,YAAY,KAAK,MAAM,WAAW;;AAEzE,SAAgB,cAAc,MAAc,SAAkB,SAA2B,YAAY,QAAQ,MAAc;CACzH,MAAM,QAAQ,gBAAgB,MAAM,SAAS,QAAQ,MAAM;AAC3D,QAAO,UAAU,QAAQ,yCACrB,UAAU,WAAW,sCACnB;;;;;ACvER,MAAM,MAAM;AACZ,MAAM,QAAQ;AACd,SAAgB,mBAAmB,OAA2C;AAC5E,QAAO,UAAU,cAAc,UAAU,aAAa,UAAU;;AAElE,SAAgB,uBAAyC;AACvD,KAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,KAAI;EACF,MAAM,QAAQ,OAAO,aAAa,QAAQ,IAAI;AAC9C,SAAO,mBAAmB,MAAM,GAAG,QAAQ;UACpC,OAAO;AACd,MAAI,EAAE,iBAAiB,iBAAiB,MAAM,SAAS,gBAAiB,OAAM;AAC9E,SAAO;;;AAGX,SAAgB,oBAAoB,OAA+B;AACjE,KAAI,CAAC,mBAAmB,MAAM,CAAE,OAAM,IAAI,UAAU,gCAAgC;AACpF,QAAO,aAAa,QAAQ,KAAK,MAAM;AACvC,QAAO,cAAc,IAAI,MAAM,MAAM,CAAC;;AAExC,SAAgB,0BAA0B,QAAgC;CACxE,MAAM,WAAW,UAAwB;AAAE,MAAI,MAAM,QAAQ,OAAO,MAAM,QAAQ,KAAM,SAAQ;;AAChG,QAAO,iBAAiB,OAAO,OAAO;AACtC,QAAO,iBAAiB,WAAW,QAAQ;AAC3C,cAAa;AACX,SAAO,oBAAoB,OAAO,OAAO;AACzC,SAAO,oBAAoB,WAAW,QAAQ;;;AAGlD,SAAgB,sBAAwC;AACtD,wCAA4B,2BAA2B,4BAA4B,WAAW;;;;;;ACxBhG,MAAMC,YAAiF;CACrF,KAAK,CAAC,gBAAgB,gBAAgB;CACtC,MAAM,CAAC,iBAAiB,iBAAiB;CACzC,QAAQ,CAAC,mBAAmB,mBAAmB;CAChD;AAED,SAAgB,WAAW,EAAE,QAAQ,OAAO,GAAG,OAAO,YAAY,SAE5C;CACpB,MAAM,SAAS,qBAAqB;CACpC,MAAM,CAAC,KAAK,8BAAmB,KAAK,IAAI;AACxC,4BAAgB;EACd,MAAM,QAAQ,kBAAkB,OAAO,KAAK,KAAK,CAAC,EAAE,IAAO;AAC3D,eAAa,cAAc,MAAM;IAChC,EAAE,CAAC;CAEN,MAAM,UAAU,KAAK,IAAI,KAAK,KAAK,KAAK,CAAC;CACzC,MAAM,QAAQ,WAAW,MAAM,YAAY;CAC3C,MAAM,OAAO,QAAQ,MAAM,cAAc;CACzC,MAAM,QAAQ,aAAa,OAAO;EAAE;EAAY;EAAO,EAAE,QAAQ;CAGjE,MAAM,UAAU,eAAe,OAAO,QAAQ;CAG9C,MAAM,OAAO,QAAQ,UAAU;CAC/B,MAAM,QAAQ,gBAAgB,MAAM,aAAa,MAAM,QAAQ,MAAM;CACrE,MAAM,OAAO,SAAS,SAAY,IAAI,KAAK,MAAM,OAAO,KAAK;CAC7D,MAAM,QAAQ;EACZ,QAAQ,EAAE,kBAAkB;GAAE,MAAM,KAAK,MAAM,KAAK;GAAE,WAAW,KAAK,MAAM,MAAM,KAAK;GAAE,CAAC,GAAG,EAAE,oBAAoB;EAEnH,CAAC,QAAQ,KAAK,CAAC,QAAQ,EAAE,kBAAkB,GAAG,UAAU,QAAQ,EAAE,sBAAsB,GACpF,SAAS,UAAa,WAAW,cAAc,EAAE,wBAAwB,GACvE,UAAU,WAAW,EAAE,kBAAkB,GAAG,EAAE,sBAAsB;EAC1E,YAAY,SAAY,KAAK,EAAE,kBAAkB,EAAE,SAAS,KAAK,MAAM,QAAQ,EAAE,CAAC;EAClF,SAAS,SAAY,KAAK,OAAO,IAAI,EAAE,uBAAuB,EAAE,QAAQ,MAAM,CAAC,GAC3E,OAAO,IAAI,EAAE,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,qBAAqB;EACrF,MAAM,aAAa,UAAa,MAAM,WAAW,UAAU,EAAE,mBAAmB,EAC9E,UAAU,oBAAoB,MAAM,WAAW,QAAQ,CACpD,KAAI,SAAQ,EAAE,UAAU,KAAK,MAAM,KAAK,UAAU,IAAI,IAAI,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CACrF,KAAK,IAAI,EACb,CAAC,GAAG;EACN,CAAC,OAAO,QAAQ,CAAC,KAAK,MAAM;AAC7B,QAAO,4CAAC;EAAI,MAAK;EAAM,cAAY;EAAO,OAAO;EAAO,oBAAkB;EAAO,OAAO;GACtF,QAAQ;GAAG,cAAc;GAAG,UAAU;GACtC,YAAY;GAA+B,QAAQ;GACnD,GAAG;GAAO,UAAU;GACrB;aACC,2CAAC,SAAI,OAAO;GAAE,QAAQ;GAAQ,cAAc;GAAW,OAAO,GAAG,KAAK;GACpE,YAAY,cAAc,MAAM,aAAa,MAAM,QAAQ,MAAM;GAAE,GAAI,EACxE,YAAY,UAAa,2CAAC;GAAK,eAAY;GAAO;GAAuB,OAAO;IAC/E,UAAU;IAAY,MAAM,mBAAmB,QAAQ;IACvD,KAAK;IAAG,QAAQ;IAAG,OAAO;IAAG,YAAY;IACzC,WAAW;IACZ;IAAI;GACD;;;;;ACpDR,MAAMC,UAAgE;CACpE;EAAE,IAAI;EAAe,MAAM;EAAe,KAAK;EAAuB;CACtE;EAAE,IAAI;EAAa,MAAM;EAAa,KAAK;EAAuB;CAClE;EAAE,IAAI;EAAW,MAAM;EAAW,KAAK;EAAmB;CAC1D;EAAE,IAAI;EAAc,MAAM;EAAc,KAAK;EAAsB;CACpE;AAID,SAAS,UAAU,OAAwB;AACzC,QAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;;;;;;;;;;AAY/D,SAAgB,yBAAyB,GAAc,UAA6B;CAClF,MAAM,QAAQC,SAAO,UAAU,UAAaA,SAAO,UAAU;AAC7D,KAAIA,SAAO,SAAS,QAClB,QAAOA,SAAO,UAAU,YAAY,EAAE,eAAe,GAAG,QAAQA,SAAO,QAAS,EAAE,cAAc;CAElG,MAAM,OAAOA,SAAO,SAAS,YAAY,EAAE,eAAe,GAAG,EAAE,cAAc;AAC7E,QAAO,QAAQ,GAAG,KAAK,KAAKA,SAAO,UAAU;;;AAI/C,SAAgB,mBAAmB,EAAE,KAAK,KAAqD;CAC7F,MAAM,CAAC,QAAQ,kCAA+B;CAC9C,MAAM,CAAC,aAAa,uCAAoC;CACxD,MAAM,CAAC,OAAO,gCAA6D,EAAE,CAAC;CAC9E,MAAM,CAAC,YAAY,qCAA2D,EAAE,CAAC;CACjF,MAAM,CAAC,QAAQ,iCAAuD,EAAE,CAAC;CACzE,MAAM,CAAC,SAAS,kCAAyD,EAAE,CAAC;CAE5E,MAAM,iCAAsB,OAAO,WAAmB;AACpD,cAAW,UAAS;GAAE,GAAG;IAAO,SAAS;GAAM,EAAE;AACjD,MAAI;GACF,MAAM,QAAQ,MAAM,sBAAqC,KAAK,iBAAiB,EAAE,QAAQ,CAAC;AAC1F,aAAS,UAAS;IAAE,GAAG;KAAO,SAAS;IAAO,EAAE;AAEhD,kBAAc,UAAS;IAAE,GAAG;KAAO,SAAS,MAAM,cAAc,KAAK,KAAK;IAAE,EAAE;AAC9E,cAAU,UAAS;IAAE,GAAG;KAAO,SAAS;IAAW,EAAE;AACrD,UAAO,cAAc,IAAI,MAAM,0BAA0B,CAAC;WACnD,OAAO;AACd,cAAU,UAAS;IAAE,GAAG;KAAO,SAAS,UAAU,MAAM;IAAE,EAAE;YACpD;AACR,eAAW,UAAS;IAAE,GAAG;KAAO,SAAS;IAAO,EAAE;;IAEnD,CAAC,IAAI,CAAC;CAET,MAAM,uCAA4B,YAAY;AAC5C,MAAI;GACF,MAAM,QAAQ,MAAM,sBAA8B,KAAK,kBAAkB,EAAE,CAAC;AAC5E,aAAU,MAAM;AAChB,kBAAe,OAAU;AACzB,QAAK,MAAM,EAAE,QAAQ,QAAS,KAAI,MAAM,KAAK,WAAY,CAAK,QAAQ,GAAG;WAClE,OAAO;AAAE,kBAAe,UAAU,MAAM,CAAC;;IACjD,CAAC,KAAK,QAAQ,CAAC;AAElB,4BAAgB;AACd,EAAK,eAAe;IACnB,CAAC,cAAc,CAAC;AAEnB,QAAO,mFACJ,QAAQ,KAAK,EAAE,IAAI,MAAM,UAAU;EAClC,MAAM,aAAa,SAAS,KAAK,eAAe;EAChD,MAAM,WAAW,MAAM;AACvB,SAAO,4CAAC;GAAa,OAAOC,uBAAO;;IACjC,4CAAC;KAAI,OAAOA,uBAAO;gBACjB,2CAAC,UAAK,OAAO;MAAE,GAAGA,uBAAO;MAAK,YAAY,aACtC,2CAA2C;MAAiC,GAAI,EACpF,2CAAC;MAAK,OAAOA,uBAAO;gBAAO;OAAY;MACnC;IACL,EAAE,WAAW,UAAa,gBAAgB,WAAc,2CAAC;KAAE,OAAOA,uBAAO;eACvE,WAAW,SAAY,EAAE,WAAW,GACjC,aAAa,EAAE,yBAAyB,GAAG,EAAE,6BAA6B;MAC5E;IACH,gBAAgB,UAAa,2CAAC;KAAE,OAAOA,uBAAO;eAC5C,EAAE,4BAA4B,EAAE,SAAS,aAAa,CAAC;MAAK;IAC9D,WAAW,UAAa,CAAC,cAAc,2CAAC;KAAE,OAAOA,uBAAO;eAAS,EAAE,0BAA0B,EAAE,KAAK,CAAC;MAAK;IAC1G,cAAc,4CAAC;KAAI,OAAOA,uBAAO;gBAChC,4CAAC;MAAI,OAAOA,uBAAO;iBACjB,2CAAC;OAAK,OAAOA,uBAAO;OAAa,OAAO,EAAE,eAAe;iBAAE;QAAQ,EACnE,2CAAC;OAAK,OAAOA,uBAAO;iBAAc,EAAE,sBAAsB;QAAQ;OAC9D,EACN,4CAAC;MAAI,OAAOA,uBAAO;;OACjB,4CAAC;QAAI,OAAOA,uBAAO;;SACjB,2CAAC;UAAK,OAAOA,uBAAO;oBAAa,EAAE,aAAa;WAAQ;SACvD,UAAU,SAAS,UAAa,2CAAC;UAAK,OAAOA,uBAAO;oBAAY,EAAE,aAAa,EAAE,MAAM,SAAS,MAAM,CAAC;WAAQ;SAChH,2CAAC;UAAO,MAAK;UAAS,OAAOA,uBAAO;UAAc,UAAU,QAAQ,QAAQ;UAC1E,eAAe;AAAE,WAAK,QAAQ,GAAG;;oBAAK,EAAE,eAAe;WAAU;;SAC/D;OACL,QAAQ,QAAQ,QAAQ,aAAa,UAAa,2CAAC;QAAE,OAAOA,uBAAO;kBAAS,EAAE,eAAe;SAAK;OAClG,OAAO,QAAQ,UAAa,2CAAC;QAAE,OAAOA,uBAAO;kBAAQ,EAAE,cAAc,EAAE,SAAS,OAAO,KAAK,CAAC;SAAK;OAClG,UAAU,SAAS,WAAW,KAAK,2CAAC;QAAE,OAAOA,uBAAO;kBAAS,EAAE,aAAa;SAAK;OACjF,UAAU,SAAS,KAAK,UAAQ,UAAU;QACzC,MAAM,UAAU,mBAAmBD,SAAO,YAAY;QACtD,MAAM,QAAQ,yBAAyB,GAAGA,SAAO;AACjD,eAAO,4CAAC;SAAgB,OAAOC,uBAAO;oBACpC,4CAAC;UAAI,OAAOA,uBAAO;qBACjB,2CAAC,oBAAM,QAAa,EACpB,4CAAC,qBAAM,YAAY,SAAY,EAAE,oBAAoB,GAAG,GAAG,QAAQ,IAAID,SAAO,aAAa,SAAY,KACnG,MAAM,EAAE,eAAe,EAAE,MAAM,IAAI,KAAKA,SAAO,SAAS,CAAC,gBAAgB,EAAE,CAAC,MAAU;WACtF,EACN,2CAAC;UAAW,QAAQA;UAAW;UAAG,YAAY,WAAW;UAAK,OAAO,OAAO,QAAQ,UAAa,UAAU,UAAU;WAAQ;WAN9G,MAOX;SACN;;OACE;MACF;IACL,CAAC,cAAc,2CAAC;KAAI,OAAOC,uBAAO;eACjC,2CAAC;MAAO,MAAK;MAAS,OAAOA,uBAAO;MAAQ,eAAe;AAAE,OAAK,eAAe;;gBAC9E,EAAE,eAAe;OACX;MACL;;KA9CS,GA+CX;GACN,GACD;;;;;ACzHL,SAAS,QAAQ,OAAwB;AACvC,QAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;;AAI/D,SAAgB,WAAW,EAAE,KAAK,KAAqD;CACrF,MAAM,CAAC,QAAQ,kCAAqC;CACpD,MAAM,CAAC,OAAO,iCAAqC;CACnD,MAAM,CAAC,YAAY,sCAAmC;CACtD,MAAM,CAAC,YAAY,qCAA0B,MAAM;CACnD,MAAM,CAAC,cAAc,wCAAqC;CAC1D,MAAM,CAAC,OAAO,iCAA8B;CAC5C,MAAM,CAAC,SAAS,kCAAuB,MAAM;CAC7C,MAAM,CAAC,QAAQ,iCAAsB,MAAM;CAC3C,MAAM,mCAAiC;CAEvC,MAAM,uCAA4B,YAAY;AAC5C,MAAI;GACF,MAAM,QAAQ,MAAM,sBAAoC,KAAK,gBAAgB,EAAE,CAAC;AAChF,aAAU,MAAM;AAChB,OAAI,cAAc,YAAY,MAAM,eAAe;AACjD,kBAAc,UAAU,MAAM;AAC9B,WAAO,cAAc,IAAI,MAAM,0BAA0B,CAAC;;AAE5D,OAAI,MAAM,cAAe,iBAAgB,OAAU;AACnD,OAAI,MAAM,MAAO,UAAS,MAAM,MAAM;WAC/B,SAAS;AAAE,YAAS,QAAQ,QAAQ,CAAC;;IAC7C,CAAC,IAAI,CAAC;CAET,MAAM,sCAA2B,YAAY;AAC3C,aAAW,KAAK;AAChB,MAAI;GACF,MAAM,QAAQ,MAAM,sBAAqC,KAAK,eAAe,EAAE,CAAC;AAChF,YAAS,MAAM;AAEf,iBAAc,MAAM,cAAc,KAAK,KAAK,CAAC;AAC7C,iBAAc,MAAM,UAAU,KAAK;AACnC,YAAS,OAAU;AACnB,UAAO,cAAc,IAAI,MAAM,0BAA0B,CAAC;WACnD,SAAS;AAAE,YAAS,QAAQ,QAAQ,CAAC;AAAE,iBAAc,KAAK;YAC3D;AAAE,cAAW,MAAM;;IAC1B,CAAC,IAAI,CAAC;AAET,4BAAgB;AAAE,EAAK,eAAe;IAAI,CAAC,cAAc,CAAC;AAC1D,4BAAgB;AACd,MAAI,QAAQ,SAAS,KAAM;EAC3B,MAAM,QAAQ,kBAAkB;AAAE,GAAK,eAAe;KAAI,IAAK;AAC/D,eAAa,cAAc,MAAM;IAChC,CAAC,QAAQ,MAAM,cAAc,CAAC;AACjC,4BAAgB;AAAE,MAAI,QAAQ,kBAAkB,KAAM,CAAK,cAAc;IAAI,CAAC,QAAQ,eAAe,aAAa,CAAC;CAEnH,MAAM,QAAQ,YAAY;AACxB,WAAS,OAAU;AACnB,MAAI;GACF,MAAM,QAAQ,MAAM,sBAAgD,KAAK,eAAe,EAAE,CAAC;AAC3F,mBAAgB,MAAM,aAAa;AACnC,UAAO,KAAK,MAAM,cAAc,UAAU,WAAW;AACrD,SAAM,eAAe;WACd,SAAS;AAAE,YAAS,QAAQ,QAAQ,CAAC;;;CAEhD,MAAM,SAAS,YAAY;AACzB,MAAI;AACF,SAAM,sBAAsB,KAAK,gBAAgB,EAAE,CAAC;AACpD,mBAAgB,OAAU;AAC1B,SAAM,eAAe;WACd,SAAS;AAAE,YAAS,QAAQ,QAAQ,CAAC;;;CAEhD,MAAM,SAAS,YAAY;AACzB,MAAI,CAAC,OAAO,QAAQ,EAAE,wBAAwB;GAAE,SAAS;GAAU,UAAU;GAAU,CAAC,CAAC,CAAE;AAC3F,MAAI;AACF,SAAM,sBAAsB,KAAK,gBAAgB,EAAE,CAAC;AACpD,YAAS,OAAU;AACnB,iBAAc,OAAU;AACxB,iBAAc,MAAM;AACpB,SAAM,eAAe;WACd,SAAS;AAAE,YAAS,QAAQ,QAAQ,CAAC;;;CAGhD,MAAM,YAAY,QAAQ,kBAAkB;AAC5C,QAAO,4CAAC;EAAI,OAAOC,uBAAO;;GACxB,4CAAC;IAAI,OAAOA,uBAAO;eACjB,2CAAC,UAAK,OAAO;KAAE,GAAGA,uBAAO;KAAK,YAAY,QAAQ,OAAO,sCACrD,YAAY,2CAA2C;KAAiC,GAAI,EAChG,2CAAC;KAAK,OAAOA,uBAAO;eAAO,EAAE,cAAc;MAAQ;KAC/C;GACN,2CAAC;IAAE,OAAOA,uBAAO;cAAS,WAAW,SAAY,EAAE,WAAW,GAAG,OAAO,OAAO,EAAE,kBAAkB,GAC/F,YAAY,EAAE,iBAAiB,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,cAAc;KAAK;GACvE,UAAU,UAAa,2CAAC;IAAE,OAAOA,uBAAO;cAAQ;KAAU;GAC1D,aAAa,4CAAC;IAAI,OAAOA,uBAAO;eAC/B,4CAAC;KAAI,OAAOA,uBAAO;;MACjB,2CAAC;OAAK,OAAOA,uBAAO;OAAa,OAAO,EAAE,eAAe;iBAAE;QAAQ;MACnE,2CAAC;OAAK,OAAOA,uBAAO;iBAAa;QAAa;MAC7C,OAAO,cAAc,UAAa,2CAAC;OAAK,OAAOA,uBAAO;iBACpD,EAAE,kBAAkB,EAAE,MAAM,IAAI,KAAK,OAAO,UAAU,CAAC,gBAAgB,EAAE,CAAC;QAAQ;MACrF,2CAAC;OAAO,MAAK;OAAS,OAAO;QAAE,GAAGA,uBAAO;QAAQ,YAAY;QAAQ,YAAY;QAAG;OAClF,eAAe;AAAE,QAAK,QAAQ;;iBAAK,EAAE,SAAS;QAAU;;MACtD,EACN,4CAAC;KAAI,OAAOA,uBAAO;;MACjB,4CAAC;OAAI,OAAOA,uBAAO;;QACjB,2CAAC;SAAK,OAAOA,uBAAO;mBAAa,EAAE,aAAa;UAAQ;QACvD,OAAO,SAAS,UAAa,2CAAC;SAAK,OAAOA,uBAAO;mBAAS,EAAE,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC;UAAQ;QACvG,2CAAC;SAAO,MAAK;SAAS,OAAOA,uBAAO;SAAc,UAAU;SAC1D,eAAe;AAAE,UAAK,cAAc;;mBAAK,EAAE,eAAe;UAAU;;QAClE;MACL,WAAW,UAAU,UAAa,2CAAC;OAAE,OAAOA,uBAAO;iBAAS,EAAE,eAAe;QAAK;MAClF,OAAO,SAAS,WAAW,KAAK,2CAAC;OAAE,OAAOA,uBAAO;iBAAS,EAAE,aAAa;QAAK;MAC9E,OAAO,SAAS,KAAK,UAAQ,UAAU;OACtC,MAAM,UAAU,mBAAmBC,SAAO,YAAY;OACtD,MAAM,QAAQA,SAAO,UAAU,aAAa,EAAE,iBAAiB,GAC3DA,SAAO,UAAU,kBAAkB,EAAE,eAAe,GAClDA,SAAO,UAAU,iBAAiB,EAAE,oBAAoB,GACtDA,SAAO,UAAU,sBAAsB,EAAE,yBAAyB,GAChEA,SAAO,SAAS,EAAE,cAAc;AAC1C,cAAO,4CAAC;QAAgB,OAAOD,uBAAO;mBACpC,4CAAC;SAAI,OAAOA,uBAAO;oBACjB,2CAAC,oBAAM,QAAa,EACpB,4CAAC,qBAAM,YAAY,SAAY,EAAE,oBAAoB,GAAG,GAAG,QAAQ,IAAIC,SAAO,aAAa,SAAY,KACnG,MAAM,EAAE,eAAe,EAAE,MAAM,IAAI,KAAKA,SAAO,SAAS,CAAC,gBAAgB,EAAE,CAAC,MAAU;UACtF,EACN,2CAAC;SAAW,QAAQA;SAAW;SAAe;SAAY,OAAO;UAAc;UANhE,MAOX;QACN;;MACE;KACF;GACN,4CAAC;IAAI,OAAOD,uBAAO;;KAChB,QAAQ,kBAAkB,SAAS,CAAC,OAAO,QAAQ,2CAAC;MAAO,MAAK;MAAS,OAAOA,uBAAO;MACtF,eAAe;AAAE,OAAK,OAAO;;gBAAK,EAAE,QAAQ;OAAU;KACxD,2CAAC;MAAO,MAAK;MAAS,OAAOA,uBAAO;MAAQ,iBAAc;MAAS,eAAe,UAAU,KAAK;gBAC9F,EAAE,iBAAiB;OACb;KACR,QAAQ,SAAS,QAAQ,2CAAC;MAAO,MAAK;MAAS,OAAOA,uBAAO;MAC5D,eAAe;AAAE,OAAK,QAAQ;;gBAAK,EAAE,SAAS;OAAU;;KACtD;GACL,QAAQ,SAAS,QAAQ,iBAAiB,UAAa,2CAAC;IAAE,MAAM;IAC/D,QAAO;IAAS,KAAI;cAAuB,EAAE,kBAAkB;KAAK;GACrE,UAAU,2CAAC;IAAuB,UAAS;IAAsB,MAAK;IAAc;IAAQ;IAC3F,eAAe,UAAU,MAAM;KAAI;;GACjC;;;;;ACpIR,MAAME,aAAyD;CAC7D,WAAW;CACX,WAAW;CACX,QAAQ;CACR,WAAW;CACX,SAAS;CACV;;;;;;AAOD,SAAgB,iBAAiB,QAAyB,KAA+B;AACvF,KAAI,OAAO,cAAc,UAAa,OAAO,aAAa,IAAK,QAAO;AACtE,KAAI,OAAO,WAAW,KAAM,QAAO;AACnC,KAAI,OAAO,eAAe,EAAG,QAAO;AACpC,KAAK,OAAO,kBAAkB,UAAa,OAAO,gBAAgB,OAAQ,OAAO,cAAc,MAAO,QAAO;AAC7G,QAAO;;;;;;;;AAST,SAAgB,2BACd,SACA,KACA,MACQ;AACR,KAAI,SAAS,UAAW,QAAO,QAAQ;CACvC,IAAI,MAAM;AACV,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ,iBAAiB,QAAQ,IAAI;AAC3C,MAAI,UAAU,aAAa,UAAU,SAAU;AAC/C,MAAI,OAAO,OAAO,eAAe,YAAY,OAAO,SAAS,OAAO,WAAW,IAAI,OAAO,aAAa,EACrG,QAAO,OAAO;;AAGlB,QAAO;;AAaT,SAAS,WAAW,GAAc,QAAiC;AACjE,QAAO,OAAO,cAAc,SACxB,EAAE,2BAA2B,GAC7B,EAAE,sBAAsB,EAAE,MAAM,IAAI,KAAK,OAAO,UAAU,CAAC,gBAAgB,EAAE,CAAC;;AAGpF,SAAS,cAAc,GAAc,QAAiC;CACpE,MAAM,OAAO,OAAO;CACpB,MAAM,QAAQ,OAAO;CACrB,MAAM,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,KAAK;AAEjE,KAAI,WADa,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,CAC3C,QAAO,EAAE,wBAAwB;EAAE;EAAM;EAAO,CAAC;AAC1E,KAAI,QAAS,QAAO,EAAE,mBAAmB,EAAE,MAAM,CAAC;AAClD,QAAO,EAAE,8BAA8B;;;AAIzC,SAAgB,mBAAmB,GAAc,QAAyB,KAAqB;CAC7F,MAAM,QAAQ,iBAAiB,QAAQ,IAAI;CAC3C,MAAM,QAAQ;EAAC,EAAE,kBAAkB;EAAE,EAAE,WAAW,OAAO;EAAE,cAAc,GAAG,OAAO;EAAE,WAAW,GAAG,OAAO;EAAC;AAC3G,KAAI,UAAU,eAAe,OAAO,kBAAkB,UAAa,OAAO,gBAAgB,IACxF,OAAM,KAAK,EAAE,4BAA4B,EAAE,MAAM,IAAI,KAAK,OAAO,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAEtG,QAAO,MAAM,KAAK,KAAK;;;AAIzB,SAAgB,kBACd,UACA,SACS;AACT,KAAI,aAAa,QAAS,QAAO,YAAY;AAC7C,SAAQ,SAAS,UAAU,KAAK;;;AAIlC,SAAgB,sBAAsB,EAAE,UAAU,oBAAS,KAIxD;AACD,QAAO,2CAAC;EAAE,OAAOC,uBAAW;YAAQ,sBAAsB,UAAUC,WAAS,EAAE;GAAK;;;AAItF,SAAgB,sBACd,UACA,WACA,GACQ;AACR,QAAO,aAAa,WAAW,EAAE,yBAAyB,GAAG,EAAE,qBAAqB,EAAE,oBAAS,CAAC;;AAGlG,MAAM,eAAe;CACnB,GAAGD,uBAAW;CAAW,QAAQ;CAAW,WAAW;CAAQ,gBAAgB;CAAc,KAAK;CACnG;;;;;;AAOD,SAAgB,uBAAuB,EACrC,MACA,SACA,GACA,MAAM,KAAK,KAAK,EAChB,YACA,WACA,iBASC;CACD,MAAM,QAAQ,2BAA2B,SAAS,KAAK,KAAK;AAC5D,QACE,4CAAC;EAAQ,WAAU;EAA8B,OAAOA,uBAAW;;GACjE,4CAAC;IAAQ,OAAO;;KACd,2CAAC;MAAI,eAAY;MAAO,OAAM;MAAK,QAAO;MAAK,SAAQ;MAAY,OAAO,EAAE,YAAY,GAAG;gBACzF,2CAAC;OAAK,GAAE;OAAe,MAAK;OAAO,QAAO;OAAe,aAAY;OAAM,eAAc;OAAQ,gBAAe;QAAU;OACtH;KACN,2CAAC,oBAAM,EAAE,oBAAoB,GAAQ;KACpC,SAAS,YAAY,2CAAC,oBAAM,EAAE,2BAA2B,GAAQ;KAClE,2CAAC;MAAK,OAAO,EAAE,YAAY,QAAQ;gBAAG,EAAE,yBAAyB,EAAE,OAAO,CAAC;OAAQ;;KAC3E;GACV,2CAAC,qBACC,sKAEO;GACT,4CAAC;IAAI,OAAO;KAAE,aAAa;KAAI,WAAW;KAAG;;KAC1C,SAAS,YAAY,2CAAC;MAAE,OAAOA,uBAAW;gBAAS,EAAE,sBAAsB;OAAK;KAChF,QAAQ,KAAK,QAAQ,UAAU;MAC9B,MAAM,QAAQ,iBAAiB,QAAQ,IAAI;MAC3C,MAAM,UAAU,SAAS,aAAa,cAAc,UAAa,WAAW;AAC5E,aACE,4CAAC;OAEC,oBAAkB,SAAS,WAAW,QAAQ;OAC9C,wBAAsB,SAAS,YAAY,OAAO,cAAc,OAAO,SAAS;OAChF,MAAM,SAAS,WAAW,UAAU;OACpC,cAAY,SAAS,WAAW,mBAAmB,GAAG,QAAQ,IAAI,GAAG;OACrE,OAAO;QAAE,GAAGA,uBAAW;QAAW,WAAW;QAAI,KAAK;QAAI,QAAQ,SAAS,WAAW,YAAY;QAAW;kBAE7G,4CAAC;QAAK,OAAO;SAAE,SAAS;SAAe,YAAY;SAAU,KAAK;SAAG,YAAY;SAAG;;SACjF,EAAE,kBAAkB;SACpB,SAAS,YACR,2CAAC;UAAK,eAAY;UAAO,yBAAuB;oBAAQ,EAAE,WAAW,OAAO;WAAQ;SAErF,WACC,2CAAC;UAAO,MAAK;UAAS,iBAAe,UAAU;UAC7C,OAAO,UAAU;UACjB,OAAO;WAAE,WAAW;WAAI,QAAQ;WAAI,SAAS;WAAS,cAAc;WAClE,SAAS,UAAU,WAAW,MAAO;WAAG,QAAQ,UAAU,WAAW,gBAAgB;WAAW;UAClG,eAAe;AAAE,eAAI,CAAC,UAAU,SAAU,WAAU,OAAO;;oBAC1D,UAAU,OAAO,EAAE,mBAAmB,GAAG,UAAU;WAC7C;;SAEN,EACP,4CAAC;QAAK,OAAO,EAAE,WAAW,SAAS;;SAChC,SAAS,YAAY,4CAAC;UAAK,eAAY;qBAAQ,cAAc,GAAG,OAAO,EAAC;WAAU;SAClF,SAAS,YAAY,UAAU,eAAe,OAAO,kBAAkB,UAAa,OAAO,gBAAgB,OAC1G,4CAAC;UAAK,eAAY;qBAAQ,EAAE,4BAA4B,EAAE,MAAM,IAAI,KAAK,OAAO,cAAc,CAAC,gBAAgB,EAAE,CAAC,EAAC;WAAU;SAE/H,2CAAC;UAAK,eAAa,SAAS,WAAW,OAAO;oBAAY,WAAW,GAAG,OAAO;WAAQ;;SAClF;SA5BF,OAAO,MAAM,MA6Bd;OAER;KACD,kBAAkB,UAAa,kBAAkB,MAAM,2CAAC;MAAE,MAAK;MAAS,OAAOA,uBAAW;gBAAS;OAAkB;;KAClH;;GACE;;;;;;ACtMd,SAAgB,yBAAyB,EAAE,KAAuB;CAChE,MAAM,OAAO,mBAAmB;CAChC,MAAM,SAAS,qBAAqB;CACpC,MAAM,CAAC,QAAQ,iCAAsB,MAAM;AAC3C,QACE,4CAAC;EAAI,OAAOE,SAAO;;GACjB,4CAAC;IAAM,OAAOA,SAAO;eACnB,2CAAC,oBAAM,EAAE,oBAAoB,GAAQ,EACrC,4CAAC;KACC,OAAOA,SAAO;KACd,cAAY,EAAE,oBAAoB;KAClC,OAAO;KACP,WAAU,UAAS;MACjB,MAAM,QAAQ,MAAM,cAAc;AAClC,UAAI,UAAU,YAAY,UAAU,YAAY,UAAU,SAAU;AACpE,UAAI;AACF,yBAAkB,MAAM;AACxB,iBAAU,MAAM;eACT,OAAO;AACd,WAAI,EAAE,iBAAiB,iBAAiB,CAAC,CAAC,iBAAiB,qBAAqB,CAAC,SAAS,MAAM,KAAK,CAAE,OAAM;AAC7G,iBAAU,KAAK;;;;MAInB,2CAAC;OAAO,OAAM;iBAAU,EAAE,0BAA0B;QAAU;MAC9D,2CAAC;OAAO,OAAM;iBAAU,EAAE,0BAA0B;QAAU;MAC9D,2CAAC;OAAO,OAAM;iBAAU,EAAE,0BAA0B;QAAU;;MACvD;KACH;GACR,2CAAC;IAAE,OAAOA,SAAO;cAAO,EAAE,wBAAwB;KAAK;GACvD,4CAAC;IAAM,OAAOA,SAAO;eACnB,2CAAC,oBAAM,EAAE,kBAAkB,GAAQ,EACnC,4CAAC;KAAO,OAAOA,SAAO;KAAQ,cAAY,EAAE,kBAAkB;KAAE,OAAO;KACrE,WAAU,UAAS;MACjB,MAAM,QAAQ,MAAM,cAAc;AAClC,UAAI,CAAC,mBAAmB,MAAM,CAAE;AAChC,UAAI;AAAE,2BAAoB,MAAM;AAAE,iBAAU,MAAM;eAC3C,OAAO;AACZ,WAAI,EAAE,iBAAiB,iBAAiB,CAAC,CAAC,iBAAiB,qBAAqB,CAAC,SAAS,MAAM,KAAK,CAAE,OAAM;AAC7G,iBAAU,KAAK;;;;MAGnB,2CAAC;OAAO,OAAM;iBAAY,EAAE,qBAAqB;QAAU;MAC3D,2CAAC;OAAO,OAAM;iBAAW,EAAE,oBAAoB;QAAU;MACzD,2CAAC;OAAO,OAAM;iBAAa,EAAE,sBAAsB;QAAU;;MACtD;KACH;GACR,2CAAC;IAAE,OAAOA,SAAO;cAAO,EAAE,WAAW,cAAc,4BAA4B,sBAAsB,EACnG,WAAW,WAAW,YAAY,KAAK,IACxC,CAAC;KAAK;GACN,UAAU,2CAAC;IAAE,MAAK;IAAQ,OAAO;KAAE,GAAGA,SAAO;KAAM,OAAO;KAAwC;cAAG,EAAE,8BAA8B;KAAK;;GACvI;;AAIV,MAAMC,WAAwC;CAC5C,MAAM;EACJ,QAAQ;EACR,cAAc;EAA8B,YAAY;EACxD,SAAS;EAAa,SAAS;EAAQ,eAAe;EAAU,KAAK;EACtE;CACD,OAAO;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAG,UAAU;EAAI,YAAY;EAAK,YAAY;EAAQ;CAC9G,QAAQ,EAAE,OAAO,QAAQ;CACzB,MAAM;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC;CAChG;;;;;ACvCD,MAAMC,qBAAmB;AA0BzB,MAAMC,yBAAwE;CAC5E,KAAK;CACL,OAAO;CACP,UAAU;CACV,QAAQ;CACT;;AAwED,MAAMC,YAAmE;CACvE;EAAE,IAAI;EAAS,MAAM;EAAmB;CACxC;EAAE,IAAI;EAAU,MAAM;EAAU;CAChC;EAAE,IAAI;EAAQ,MAAM;EAAoB;CACxC;EAAE,IAAI;EAAW,MAAM;EAAkB;CACzC;EAAE,IAAI;EAAe,MAAM;EAAsB;CAClD;;AAGD,SAAS,UAAU,OAAwB;AACzC,QAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;;AAI/D,SAAS,UAAa,KAAwB,MAA8C;CAC1F,MAAM,QAAQ,OAAO,KAAK,IAAI,CAAC,QAAO,QAAO,CAAC,KAAK,IAAI,IAAI,CAAC;AAC5D,KAAI,MAAM,WAAW,EAAG,QAAO;CAC/B,MAAM,OAAO,EAAE,GAAG,KAAK;AACvB,MAAK,MAAM,OAAO,MAAO,QAAO,KAAK;AACrC,QAAO;;;;;;;;;AAUT,SAASC,oBAAkB,KAAuB,QAA0C;CAC1F,IAAIC,OAAe,GAAG;AACtB,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,UAAU,EAAE,CAAC,CACtD,QAAO,KAAK,WAAW,IAAI,KAAK,IAAI,OAAO,MAAM,CAAC;AAEpD,QAAO;;AAGT,MAAMC,WAAwC;CAC5C,SAAS;EACP,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAI,UAAU;EAC7D,OAAO;EACR;CACD,OAAO;EAAE,QAAQ;EAAG,OAAO;EAAmC,UAAU;EAAI,YAAY;EAAQ;CAChG,MAAM;EAAE,GAAGC,uBAAW;EACpB,QAAQ;EACR,cAAc;EAA8B,YAAY;EACzD;CACD,YAAYA,uBAAW;CACvB,KAAKA,uBAAW;CAChB,MAAMA,uBAAW;CACjB,YAAYA,uBAAW;CACvB,eAAe;EAAE,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC,oBAAoB;EAAgB;CACjI,WAAWA,uBAAW;CACtB,SAASA,uBAAW;CACpB,OAAO;EAAE,GAAGA,uBAAW;EAAO,WAAW;EAA0C;CACnF,aAAaA,uBAAW;CACxB,YAAYA,uBAAW;CACvB,WAAWA,uBAAW;CACtB,cAAc;EAAE,WAAW;EAAI,QAAQ;EAAI,SAAS;EAAS,YAAY;EAAQ;CACjF,UAAUA,uBAAW;CACrB,WAAWA,uBAAW;CACtB,YAAY;EAAE,GAAGA,uBAAW;EAAS,QAAQ;EAA0C,cAAc;EAA8B;CACnI,eAAeA,uBAAW;CAC1B,aAAaA,uBAAW;CACxB,YAAY;EACV,QAAQ;EAAQ,SAAS;EAAG,OAAO;EACnC,MAAM;EAAW,UAAU;EAAI,YAAY;EAAQ,QAAQ;EAC3D,OAAO;EACR;CACD,YAAY;EACV,WAAW;EAAG,SAAS;EAAQ,eAAe;EAAU,KAAK;EAC7D,QAAQ;EAA0C,cAAc;EAChE,SAAS;EAAa,YAAY;EACnC;CACD,gBAAgB;EACd,YAAY;EAAa,UAAU;EAAI,YAAY;EAAQ,eAAe;EAC1E,OAAO;EAAkC,YAAY;EACtD;CACD,QAAQ;EAAE,UAAU;EAAI,YAAY;EAAQ;CAC5C,WAAW;EAAE,SAAS;EAAQ,UAAU;EAAQ,KAAK;EAAG,YAAY;EAAU,WAAW;EAAG;CAC5F,aAAa;EAAE,MAAM;EAAa,UAAU;EAAG;CAC/C,cAAc;EACZ,UAAU;EAAS,OAAO;EAAG,QAAQ;EACrC,SAAS;EAAQ,YAAY;EAAU,gBAAgB;EAAU,SAAS;EAC1E,YAAY;EAAqC,gBAAgB;EAClE;CACD,OAAO;EACL,OAAO;EAAK,UAAU;EAAQ,WAAW;EAAQ,WAAW;EAC5D,WAAW;EAAc,SAAS;EAAQ,eAAe;EAAU,KAAK;EACxE,SAAS;EAAa,cAAc;EACpC,YAAY;EAA+B,QAAQ;EAAG,WAAW;EAClE;CACD,aAAa;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAG;CAC9D,YAAY;EAAE,YAAY;EAAK,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAkC;CAC3G;;AAGD,SAAS,SAAS,QAA4C;AAC5D,KAAI,QAAQ,SAAS,KAAM,QAAO;AAClC,MAAK,QAAQ,SAAS,UAAU,KAAK,EAAG,QAAO;AAC/C,QAAO;;;;;;;;AAoBT,SAAS,WAAW,GAAsC,QAA4C;AACpG,KAAI,WAAW,OAAW,QAAO,EAAE,WAAW;AAC9C,KAAI,OAAO,KAAM,QAAO,EAAE,kBAAkB;AAC5C,KAAI,OAAO,SAAS,SAAS,EAAG,QAAO,EAAE,iBAAiB,EAAE,OAAO,OAAO,SAAS,QAAQ,CAAC;AAC5F,QAAO,EAAE,cAAc;;;;;;;;AASzB,SAAgB,kBACd,GACA,eACQ;AACR,KAAI,kBAAkB,OAAW,QAAO;AACxC,QAAO,EAAE,iBAAiB;EAAE,SAAS,cAAc;EAAS,QAAQ,EAAE,uBAAuB,cAAc,QAAQ;EAAE,CAAC;;;;;;;;AASxH,SAASC,mBAAiB,GAAsC,UAA6B;CAC3F,MAAM,OAAOC,SAAO,SAAS,YACzB,EAAE,eAAe,GACjBA,SAAO,SAAS,WAAW,EAAE,cAAc,GAAG,EAAE,cAAc;AAClE,QAAOA,SAAO,UAAU,UAAaA,SAAO,UAAU,KAAK,GAAG,KAAK,KAAKA,SAAO,UAAU;;;;;;;AAW3F,SAAgB,qBAAqB,OAAkC;CACrE,MAAM,EAAE,QAAQ;CAChB,MAAM,IAAI,MAAM,KAAKL;CACrB,MAAM,CAAC,UAAU,mCAA+E,EAAE,CAAC;CACnG,MAAM,CAAC,QAAQ,iCAAqE,EAAE,CAAC;CACvF,MAAM,CAAC,cAAc,uCAAkE;EACrF,OAAO;EAAI,QAAQ;EAAI,MAAM;EAAI,SAAS;EAAI,aAAa;EAC5D,CAAC;;CAEF,MAAM,CAAC,aAAa,sCAAiH,EAAE,CAAC;CACxI,MAAM,CAAC,YAAY,qCAA4D,OAAU;;CAEzF,MAAM,CAAC,QAAQ,iCAAqD,EAAE,CAAC;CACvE,MAAM,CAAC,YAAY,qCAAkD,EAAE,CAAC;CACxE,MAAM,CAAC,aAAa,sCAAmD,EAAE,CAAC;CAC1E,MAAM,CAAC,cAAc,uCAAqD,EAAE,CAAC;CAC7E,MAAM,CAAC,mBAAmB,6CAA+I;CACzK,MAAM,CAAC,WAAW,oCAAyB,MAAM;CACjD,MAAM,CAAC,mBAAmB,4CAAiC,MAAM;CACjE,MAAM,CAAC,cAAc,uCAA4B,GAAG;CACpD,MAAM,CAAC,cAAc,wCAAqC;CAC1D,MAAM,mCAA2C,KAAK;AACtD,4BAAgB;AACd,MAAI,kBAAmB,gBAAe,SAAS,WAAW;MACrD,gBAAe,SAAS,OAAO;IACnC,CAAC,kBAAkB,CAAC;CACvB,MAAM,kCAAuB,MAAM;CACnC,MAAM,+BAAoB,KAAK;CAC/B,MAAM,+CAAoB,IAAI,KAA2D,CAAC;;;CAG1F,MAAM,qDAA0B,IAAI,KAA4B,CAAC;CACjE,MAAM,6CAA0C;CAChD,MAAM,CAAC,iBAAiB,2CAA4E;CACpG,MAAM,2CAAgC,UAAgC,cAAsC;AAC1G,MAAI,CAAC,WAAW,QAAS;AACzB,aAAW,SAAS;GAClB,MAAM,OAAO,EAAE,GAAG,MAAM;AACxB,OAAIM,cAAY,OAAW,QAAO,KAAK;OAClC,MAAK,YAAYA;AACtB,UAAO;IACP;IACD,EAAE,CAAC;CAEN,MAAM,sCAA2B,aAAyC;EACxE,MAAM,SAAS,WAAW,QAAQ,IAAI,SAAS;AAC/C,MAAI,WAAW,QAAW;AACxB,iBAAc,OAAO;AACrB,cAAW,QAAQ,OAAO,SAAS;;IAEpC,EAAE,CAAC;;CAGN,MAAM,iCAAsB,YAA2B;AACrD,MAAI,QAAQ,OAAW;EACvB,IAAIC;AACJ,MAAI;AACF,cAAW,MAAM,sBAAsC,KAAK,UAAU,EAAE,CAAC;WAClE,OAAO;GAId,MAAMD,YAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,MAAM,EAAE,QAAQ,UAAW,kBAAiB,IAAIA,UAAQ;AAC7D;;AAEF,MAAI,CAAC,WAAW,QAAS;AACzB,cAAY,SAAS,UAAU;EAC/B,MAAM,YAAY,UAAU,KAAK,EAAE,SAAS,GAAG,GAAG,GAAG,SAAS,UAAU,IAAI,SACzE,KAAI,YAAW,GAAG,QAAQ,IAAI,GAAG,QAAQ,YAAY,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI;AAC/E,MAAI,cAAc,wBAAwB,SAAS;AACjD,2BAAwB,UAAU;AAClC,UAAO,cAAc,IAAI,MAAM,0BAA0B,CAAC;;AAG5D,OAAK,MAAM,EAAE,QAAQ,UAAW,kBAAiB,IAAI,OAAU;AAC/D,OAAK,MAAM,EAAE,QAAQ,WAAW;GAC9B,MAAM,SAAS,SAAS,UAAU;AAClC,OAAI,OAAO,SAAS,SAAS,KAAK,CAAC,OAAO,MAAM;AAC9C,gBAAY,GAAG;AAEf,oBAAgB,SAAS;AACvB,SAAI,KAAK,QAAQ,OAAW,QAAO;KACnC,MAAM,OAAO,EAAE,GAAG,MAAM;AACxB,YAAO,KAAK;AACZ,YAAO;MACP;;;IAGL;EAAC;EAAK;EAAa;EAAiB,CAAC;CAExC,MAAM,uCAA4B,aAAyC;AACzE,MAAI,WAAW,QAAQ,IAAI,SAAS,CAAE;AACtC,aAAW,QAAQ,IAAI,UAAU,kBAAkB;AAAE,GAAK,SAAS;KAAIT,mBAAiB,CAAC;IACxF,CAAC,QAAQ,CAAC;AAIb,4BAAgB;AACd,aAAW,UAAU;AACrB,EAAK,SAAS,CAAC,WAAW;AACxB,OAAI,CAAC,WAAW,QAAS;AACzB,gBAAa,YAAY;AACvB,SAAK,MAAM,EAAE,QAAQ,UACnB,KAAI,QAAQ,KAAK,SAAS,KAAM,cAAa,GAAG;AAElD,WAAO;KACP;IACF;AACF,eAAa;AACX,cAAW,UAAU;AACrB,QAAK,MAAM,UAAU,WAAW,QAAQ,QAAQ,CAAE,eAAc,OAAO;AACvE,cAAW,QAAQ,OAAO;;IAE3B,CAAC,SAAS,aAAa,CAAC;CAE3B,MAAM,mCAAwB,OAAO,UAAgC,SAAiB,QAAQ,UAAyB;AACrH,MAAI,QAAQ,OAAW;EACvB,MAAM,MAAM,GAAG,SAAS,GAAG;EAC3B,MAAM,UAAU,iBAAiB,QAAQ,IAAI,IAAI;AAMjD,MAAI,YAAY,QAAW;AACzB,OAAI,CAAC,MAAO;AACZ,SAAM;;AAER,MAAI,QAAQ,UAAa,iBAAiB,QAAQ,IAAI,IAAI,CAAE;EAC5D,MAAM,QAAQ,YAAY;AACxB,oBAAgB,UAAS;IAAE,GAAG;KAAO,MAAM;IAAM,EAAE;AACnD,OAAI;IACF,MAAM,QAAQ,MAAM,sBAAqC,KAAK,SAAS;KAAE;KAAU;KAAS,GAAG,QAAQ,EAAE,OAAO,MAAM,GAAG,EAAE;KAAE,CAAC;AAC9H,QAAI,CAAC,WAAW,QAAS;AACzB,eAAU,UAAS;KAAE,GAAG;MAAO,MAAM;KAAO,EAAE;AAC9C,mBAAc,UAAS;KAAE,GAAG;MAAO,MAAM,MAAM,cAAc,KAAK,KAAK;KAAE,EAAE;AAC3E,WAAO,cAAc,IAAI,MAAM,0BAA0B,CAAC;AAC1D,oBAAgB,SAAS;KACvB,MAAM,OAAO,EAAE,GAAG,MAAM;AACxB,YAAO,KAAK;AACZ,YAAO;MACP;YACK,OAAO;AACd,QAAI,WAAW,QAAS,iBAAe,UAAS;KAAE,GAAG;MAAO,MAAM,UAAU,MAAM;KAAE,EAAE;aAC9E;AACR,qBAAiB,QAAQ,OAAO,IAAI;AACpC,QAAI,WAAW,QAAS,kBAAgB,UAAS;KAAE,GAAG;MAAO,MAAM;KAAO,EAAE;;MAE5E;AACJ,mBAAiB,QAAQ,IAAI,KAAK,KAAK;AACvC,QAAM;IACL,CAAC,IAAI,CAAC;CAET,eAAe,aAAa,SAAgC;AAC1D,MAAI,CAAC,OAAO,cAAc,QAAS;AACnC,gBAAc,UAAU;AACxB,eAAa,KAAK;AAClB,kBAAgB,QAAQ;AACxB,uBAAqB,OAAU;AAC/B,kBAAgB,GAAG;AACnB,MAAI;GACF,MAAM,SAAS,MAAM,sBAA8E,KAAK,gBAAgB,EAAE,SAAS,CAAC;AACpI,wBAAqB,MAAM;AAC3B,wBAAqB;IAAE,GAAG;IAAQ;IAAS,CAAC;WACrC,OAAO;AAAE,mBAAgB,UAAU,MAAM,CAAC;YAC3C;AAAE,iBAAc,UAAU;AAAO,gBAAa,MAAM;;;CAG9D,eAAe,eAA8B;AAC3C,MAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,qBAAqB,cAAc,QAAS;EAC/E,MAAM,EAAE,SAAS,WAAW;AAC5B,gBAAc,UAAU;AACxB,eAAa,KAAK;AAClB,uBAAqB,OAAU;AAC/B,MAAI;AACF,SAAM,sBAAsB,KAAK,gBAAgB;IAAE;IAAS;IAAQ,CAAC;AACrE,mBAAgB,EAAE,kBAAkB,CAAC;WAC9B,OAAO;AAAE,mBAAgB,UAAU,MAAM,CAAC;YAC3C;AACN,SAAM,UAAU,SAAS,SAAS,KAAK;AACvC,iBAAc,UAAU;AAAO,gBAAa,MAAM;;;AAOtD,4BAAgB;EACd,MAAM,uBAAO,IAAI,KAAa;AAC9B,OAAK,MAAM,EAAE,QAAQ,UACnB,MAAK,MAAM,WAAW,SAAS,KAAK,YAAY,EAAE,EAAE;GAClD,MAAM,MAAM,GAAG,GAAG,GAAG,QAAQ;AAC7B,QAAK,IAAI,IAAI;AACb,OAAI,OAAO,SAAS,UAAa,YAAY,SAAS,OAAW,CAAK,UAAU,IAAI,QAAQ,IAAI;;AAGpG,aAAU,SAAQ,UAAU,MAAM,KAAK,CAAC;AACxC,kBAAe,SAAQ,UAAU,MAAM,KAAK,CAAC;IAC5C;EAAC;EAAU;EAAQ;EAAa;EAAU,CAAC;CAE9C,MAAM,+BAAoB,OAAO,UAAgC,WAAiD;AAChH,MAAI,QAAQ,OAAW;AACvB,mBAAiB,UAAU,OAAU;AACrC,MAAI;GACF,MAAM,WAAW,MAAM,sBAAqC,KAAK,SAAS;IACxE;IACA,GAAG,WAAW,SAAY,EAAE,GAAG,EAAE,QAAQ;IAC1C,CAAC;AACF,OAAI,OAAO,SAAS,iBAAiB,YAAY,SAAS,iBAAiB,IAAI;AAE7E,UAAM,SAAS;AACf;;AAEF,OAAI,OAAO,SAAS,iBAAiB,SACnC,OAAM,IAAI,uBAAuB,EAAE,kBAAkB,CAAC;AAExD,OAAI,CAAC,WAAW,QAAS;AAEzB,gBAAY,UAAS;IACnB,GAAG;KACF,WAAW;KAAE,UAAU,KAAK,WAAW,YAAY,EAAE;KAAE,GAAG,KAAK;KAAW,MAAM;KAAM;IACxF,EAAE;AACH,OAAI,OAAO,SAAS,aAAa,YAAY,SAAS,SAAS,SAAS,EAGtE,iBAAe,UAAS;IAAE,GAAG;KAAO,WAAW;KAAE,UAAU,SAAS;KAAoB,iBAAiB,SAAS;KAAc;IAAE,EAAE;OAEpI,QAAO,KAAK,SAAS,cAAc,UAAU,WAAW;AAE1D,gBAAa,SAAS;WACf,OAAO;AACd,oBAAiB,UAAU,UAAU,MAAM,CAAC;;IAE7C;EAAC;EAAK;EAAG;EAAkB;EAAa,CAAC;CAE5C,MAAM,gCAAqB,OAAO,aAAkD;AAClF,MAAI,QAAQ,OAAW;AACvB,cAAY,SAAS;AACrB,MAAI;AACF,SAAM,sBAAoC,KAAK,UAAU,EAAE,UAAU,CAAC;WAC/D,OAAO;AACd,oBAAiB,UAAU,UAAU,MAAM,CAAC;;AAE9C,QAAM,SAAS;IACd;EAAC;EAAK;EAAa;EAAkB;EAAQ,CAAC;CAEjD,MAAM,sCAA2B,OAAO,aAAkD;AACxF,MAAI,QAAQ,OAAW;EACvB,MAAM,QAAQ,aAAa,UAAU,MAAM;AAC3C,MAAI,UAAU,GAAI;AAClB,mBAAiB,UAAU,OAAU;AACrC,MAAI;AACF,SAAM,sBAAoC,KAAK,UAAU;IAAE;IAAU;IAAO,CAAC;AAC7E,OAAI,WAAW,QAAS,kBAAgB,UAAS;IAAE,GAAG;KAAO,WAAW;IAAI,EAAE;WACvE,OAAO;AACd,oBAAiB,UAAU,UAAU,MAAM,CAAC;;AAE9C,QAAM,SAAS;IACd;EAAC;EAAK;EAAc;EAAkB;EAAQ,CAAC;CAElD,MAAM,gCAAqB,OAAO,UAAgC,SAAiB,SAAiB,SAAgC;AAClI,MAAI,QAAQ,OAAW;AACvB,MAAI,CAAC,OAAO,QAAQ,EAAE,wBAAwB;GAAE,UAAU;GAAM,SAAS;GAAS,CAAC,CAAC,CAAE;AACtF,mBAAiB,UAAU,OAAU;AACrC,MAAI;AACF,SAAM,sBAAoC,KAAK,UAAU;IAAE;IAAU;IAAS,CAAC;WACxE,OAAO;AACd,oBAAiB,UAAU,UAAU,MAAM,CAAC;;AAE9C,QAAM,SAAS;IACd;EAAC;EAAK;EAAG;EAAkB;EAAQ,CAAC;CAEvC,MAAM,oCAAyB,OAAO,UAAgC,YAAmC;AACvG,MAAI,QAAQ,OAAW;AACvB,mBAAiB,UAAU,OAAU;AACrC,MAAI;AACF,SAAM,sBAAoC,KAAK,cAAc;IAAE;IAAU;IAAS,CAAC;WAC5E,OAAO;AACd,oBAAiB,UAAU,UAAU,MAAM,CAAC;;AAE9C,QAAM,SAAS;IACd;EAAC;EAAK;EAAkB;EAAQ,CAAC;CAEpC,MAAM,yCAA8B,UAAgC,aAA2B;AAC7F,EAAK,UAAU,WAAW,UAAU,SAAS,CAAC,WAAW;AACvD,OAAI,CAAC,WAAW,QAAS;AACzB,iBAAc,SAAS;AACvB,oBAAiB;AACf,QAAI,WAAW,QACb,gBAAc,YAAW,YAAY,WAAW,SAAY,QAAQ;MAErE,KAAK;IACR,CAAC,YAAY,OAAU;IACxB,EAAE,CAAC;AAEN,KAAI,QAAQ,OACV,QAAO,2CAAC;EAAE,OAAOW,SAAO;YAAQ,EAAE,cAAc;GAAK;AAGvD,QACE,4CAAC;EAAI,WAAU;EAA6B,OAAOA,SAAO;;GACxD,2CAAC,qBAAO,sBAA4B;GACpC,2CAAC;IAAE,OAAOA,SAAO;cAAQ,EAAE,QAAQ;KAAK;GACxC,2CAAC,4BAA4B,IAAK;GACjC,UAAU,KAAK,EAAE,IAAI,WAAW;IAC/B,MAAM,SAAS,SAAS;IACxB,MAAM,OAAO,QAAQ,SAAS;IAC9B,MAAM,aAAa,YAAY;IAC/B,MAAM,WAAW,QAAQ,YAAY,EAAE;AACvC,WACE,4CAAC;KAAa,OAAOA,SAAO;;MAC1B,4CAAC;OAAI,OAAOA,SAAO;;QACjB,2CAAC,UAAK,OAAO;SAAE,GAAGA,SAAO;SAAK,YAAY,SAAS,OAAO;SAAE,GAAI;QAChE,2CAAC;SAAK,OAAOA,SAAO;mBAAO;UAAY;QACtC,QAAQ,kBAAkB,UACzB,2CAAC;SAAK,OAAOA,SAAO;SAAe,OAAO,EAAE,oBAAoB;mBAC7D,kBAAkB,GAAG,OAAO,cAAc;UACtC;;QAEL;MACN,2CAAC;OAAE,OAAOA,SAAO;iBAAa,WAAW,GAAG,OAAO;QAAK;MACvD,QAAQ,WAAW,UAAa,OAAO,WAAW,MACjD,2CAAC;OAAE,OAAOA,SAAO;iBAAa,OAAO;QAAW;MAEjD,OAAO,QAAQ,UAAa,2CAAC;OAAE,OAAOA,SAAO;iBAAY,OAAO;QAAQ;MACxE,SAAS,KAAK,YAAY;OACzB,MAAM,WAAW,GAAG,GAAG,GAAG,QAAQ;OAClC,MAAM,QAAQ,OAAO;OACrB,MAAM,aAAa,YAAY;OAC/B,MAAM,UAAU,QAAQ,WAAW,QAAQ;OAC3C,MAAM,gBAAgB,CAAC,GAAI,OAAO,gBAAgB,EAAE,CAAE,CAAC,MAAM,GAAG,OAAO,EAAE,aAAa,aAAa,EAAE,aAAa,UAAU;OAC5H,MAAM,YAAY,cAAc,MAAK,MAAK,EAAE,cAAc,UAAa,EAAE,YAAY,KAAK,KAAK,CAAC;OAChG,MAAM,aAAa,QAAQ,iBAAiB,MAAM,GAAG;OACrD,MAAM,gBAAgB,aAAa,eAAe;OAElD,MAAM,YAAY,OAAO,cAAc,UACjC,UAAU,UAAa,eAAe,UAAa,aAAa,cAAc;AACpF,cACE,4CAAC;QAAsB,OAAOA,SAAO;mBACnC,4CAAC;SAAI,OAAOA,SAAO;;UACjB,2CAAC;WACC,MAAK;WACL,OAAOA,SAAO;WACd,OAAO,QAAQ,YAAY,EAAE,eAAe,GAAG,EAAE,aAAa;WAC9D,eAAe;AACb,gBAAI,CAAC,QAAQ,UAAW,CAAK,WAAW,IAAI,QAAQ,IAAI;;qBAGzD,QAAQ,YAAY,MAAM;YACpB;UACT,2CAAC;WAAK,OAAOA,SAAO;qBAAc;YAAe;UAChD,QAAQ,SAAS,UAChB,2CAAC;WAAK,OAAOA,SAAO;qBAAY,QAAQ;YAAY;UAErD,QAAQ,cAAc,UACrB,2CAAC;WAAK,OAAOA,SAAO;qBACjB,EAAE,kBAAkB,EAAE,MAAM,IAAI,KAAK,QAAQ,UAAU,CAAC,gBAAgB,EAAE,CAAC;YACvE;UAET,2CAAC;WACC,MAAK;WACL,OAAO;YAAE,YAAY;YAAQ,YAAY;YAAG;WAC5C,eAAe;AAAE,YAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,KAAK;;qBAE3D,EAAE,SAAS;YACL;;UACL,EACL,aACC,4CAAC;SAAI,OAAOA,SAAO;;UACjB,4CAAC;WAAI,OAAOA,SAAO;;YACjB,2CAAC;aAAK,OAAOA,SAAO;uBAAa,EAAE,aAAa;cAAQ;YACvD,OAAO,SAAS,UACf,2CAAC;aAAK,OAAOA,SAAO;uBAAY,EAAE,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC;cAAQ;YAE9E,2CAAC;aACC,MAAK;aACL,OAAOA,SAAO;aACd,UAAU,aAAa,cAAc;aACrC,eAAe;AAAE,cAAK,UAAU,IAAI,QAAQ,KAAK,KAAK;;uBAErD,EAAE,eAAe;cACX;;YACL;UACL,UAAU,UAAa,eAAe,UACrC,2CAAC;WAAE,OAAOA,SAAO;qBAAa,EAAE,eAAe;YAAK;UAErD,eAAe,UACd,2CAAC;WAAE,OAAOA,SAAO;qBAAY,EAAE,cAAc,EAAE,SAAS,YAAY,CAAC;YAAK;UAE3E,OAAO,YAAY,UAAa,MAAM,QAAQ,WAAW,KACxD,2CAAC;WAAE,OAAOA,SAAO;qBAAa,EAAE,aAAa;YAAK;WAElD,OAAO,WAAW,EAAE,EAAE,KAAK,UAAQ,UAAU;WAC7C,MAAM,UAAU,mBAAmBH,SAAO,YAAY;AACtD,kBACE,4CAAC;YAAgB,OAAOG,SAAO;uBAC7B,4CAAC;aAAI,OAAOA,SAAO;wBACjB,2CAAC,oBAAMJ,mBAAiB,GAAGC,SAAO,GAAQ,EAC1C,4CAAC,qBACE,YAAY,SAAY,EAAE,oBAAoB,GAAG,GAAG,QAAQ,IAC5DA,SAAO,aAAa,UAChB,MAAM,EAAE,eAAe,EAAE,MAAM,IAAI,KAAKA,SAAO,SAAS,CAAC,gBAAgB,EAAE,CAAC,MAC5E;cACH,EACN,2CAAC;aAAW,QAAQA;aAAW;aAAG,YAAY,WAAW;aAAW,OAAO,eAAe,UAAa,MAAM,UAAU;cAAQ;cATvH,MAUJ;YAER;WACA,OAAO,WAAW,OAAO,aAAa,OAAO,sBAAsB,UACnE,2CAAC;WAAsB,UAAU;WAAI,SAAS,MAAM;WAAsB;YAAK;WAE/E,OAAO,WAAW,OAAO,aAAa,kBAAkB,IAAI,OAAO,aAAa,IAChF,2CAAC;WACC,MAAM,OAAO,WAAW,WAAW;WACnC,SAAS;WACN;WACH,GAAI,cAAc,SAAY,EAAE,YAAY,WAAW,GAAG,EAAE;WAC5D,GAAI,OAAO,UAAU,EAAE,WAAW;YAChC,YAAY,QAAQ;YACpB,MAAM,aAAa,iBAAiB,QAAQ;YAC5C,UAAU;YACV,OAAO,EAAE,YAAY,qBAAqB,cAAc,gBAAgB;YACxE,OAAO,EAAE,iBAAiB;YAC1B,aAAa;AAAE,iBAAI,CAAC,cAAe,CAAK,aAAa,QAAQ,IAAI;;YAClE,EAAE,GAAG,EAAE;WACR,GAAI,iBAAiB,QAAQ,OAAO,iBAAiB,KAAK,EAAE,eAAe,cAAc,GAAG,EAAE;YAC9F;;UAEA;UA1FA,QAAQ,IA4FZ;QAER;MACF,4CAAC;OAAI,OAAOG,SAAO;;QAChB,CAAC,QAAQ,SAAS,WAAW,KAC5B,2CAAC;SAAO,MAAK;SAAS,eAAe;AAAE,UAAK,MAAM,GAAG;;mBAClD,EAAE,QAAQ;UACJ;QAEV,CAAC,QAAQ,SAAS,SAAS,KAAK,OAAO,YACtC,qFACE,2CAAC;SAAO,MAAK;SAAS,eAAe;AAAE,UAAK,MAAM,IAAI,QAAQ;;mBAC3D,EAAE,kBAAkB;UACd,EACT,2CAAC;SAAO,MAAK;SAAS,eAAe;AAAE,UAAK,MAAM,IAAI,WAAW;;mBAC9D,EAAE,qBAAqB;UACjB,IACR;QAEJ,CAAC,QAAQ,SAAS,SAAS,KAAK,OAAO,YACtC,2CAAC;SAAO,MAAK;SAAS,eAAe;AAAE,UAAK,MAAM,GAAG;;mBAClD,EAAE,aAAa;UACT;QAEX,2CAAC;SAAO,MAAK;SAAS,iBAAc;SAClC,eAAe,mBAAmB;UAAE;UAAI;UAAM,CAAC;mBAC9C,EAAE,iBAAiB;UACb;QACR,QACC,2CAAC;SAAO,MAAK;SAAS,eAAe;AAAE,UAAK,OAAO,GAAG;;mBACnD,EAAE,SAAS;UACL;;QAEP;MACL,CAAC,QAAQ,SAAS,SAAS,KAC1B,2CAAC;OAAE,OAAOA,SAAO;iBAAa,EAAE,iBAAiB;QAAK;MAGvD,QAAQ,eAAe,UACtB,4CAAC;OAAI,OAAOA,SAAO;;QACjB,2CAAC;SAAK,OAAOA,SAAO;mBAAa,EAAE,mBAAmB;UAAQ;QAC9D,2CAAC;SAAK,OAAOA,SAAO;mBAAiB,WAAW;UAAgB;QAChE,4CAAC;SAAI,OAAOA,SAAO;oBACjB,2CAAC;UAAO,MAAK;UAAS,eAAe;AAAE,0BAAe,IAAI,WAAW,SAAS;;oBAC3E,eAAe,KAAK,EAAE,mBAAmB,GAAG,EAAE,iBAAiB;WACzD,EACT,2CAAC;UACC,MAAK;UACL,eAAe;AAAE,kBAAO,KAAK,WAAW,iBAAiB,UAAU,WAAW;;oBAE7E,EAAE,qBAAqB;WACjB;UACL;;QACF;MAEP,QAAQ,eAAe,UACtB,4CAAC;OAAQ,OAAOA,SAAO;kBACrB,2CAAC,uBAAS,EAAE,gBAAgB,GAAW,EACvC,4CAAC;QAAI,OAAOA,SAAO;mBACjB,2CAAC;SACC,OAAOA,SAAO;SACd,OAAO,aAAa;SACpB,aAAa,EAAE,oBAAoB;SACnC,WAAU,UAAS,iBAAgB,UAAS;UAAE,GAAG;WAAO,KAAK,MAAM,OAAO;UAAO,EAAE;UACnF,EACF,2CAAC;SAAO,MAAK;SAAS,eAAe;AAAE,UAAK,aAAa,GAAG;;mBACzD,EAAE,SAAS;UACL;SACL;QACE;;OA7LJ,GA+LJ;KAER;GACF,2CAAC;IAAgB;IAAQ;KAAK;GAC9B,2CAAC;IAAwB;IAAQ;KAAK;GACrC,mBAAmB,2CAAC;IAAuB,UAAU,gBAAgB;IAAI,MAAM,gBAAgB;IACzF;IAAQ;IAAG,eAAe,mBAAmB,OAAU;KAAI;GAClE,2CAAC,qBAAO,0IAAgJ;GACxJ,2CAAC;IAAO,KAAK;IAAgB,WAAU;IACrC,mBAAgB;IAA4B,gBAAgB,qBAAqB,OAAU;IAC3F,eAAe,qBAAqB,OAAU;IAC9C,OAAO;KAAE,GAAGA,SAAO;KAAO,SAAS,oBAAoB,SAAS;KAAQ,QAAQ;KAAQ,OAAO;KAAkC;cAChI,qBAAqB;KACpB,2CAAC;MAAG,IAAG;MAA4B,OAAO;OAAE,GAAGA,SAAO;OAAY,QAAQ;OAAG;gBAAG,EAAE,uBAAuB;OAAM;KAC/G,2CAAC;MAAE,OAAO;OAAE,GAAGA,SAAO;OAAY,cAAc;OAAY;gBAAG,SAAS,OAAO,SAAS,MAAK,MAAK,EAAE,QAAQ,kBAAkB,QAAQ,EAAE,WAAW,kBAAkB;OAAY;KACjL,4CAAC;MAAI,OAAO;OAAE,GAAGA,SAAO;OAAW,KAAK;OAAI;iBAC1C,2CAAC,oBAAM,EAAE,cAAc,GAAQ,8CAAC,uBAAQ,KAAK,MAAM,kBAAkB,kBAAkB,EAAC,OAAU;OAC9F;KACN,2CAAC;MAAI,OAAOA,SAAO;gBACjB,2CAAC,oBAAM,kBAAkB,oBAAoB,SAAY,EAAE,2BAA2B,GAAG,EAAE,sBAAsB,EAAE,MAAM,IAAI,KAAK,kBAAkB,gBAAgB,CAAC,gBAAgB,EAAE,CAAC,GAAQ;OAC5L;KACN,2CAAC;MAAE,OAAO;OAAE,GAAGA,SAAO;OAAY,QAAQ;OAAS;gBAAG,EAAE,kBAAkB;OAAK;KAC/E,4CAAC;MAAM,OAAO;OAAE,SAAS;OAAQ,KAAK;OAAG,YAAY;OAAc,UAAU;OAAI;iBAC/E,2CAAC;OAAM,MAAK;OAAW,SAAS;OAAmB,WAAU,MAAK,qBAAqB,EAAE,OAAO,QAAQ;QAAI,EAC3G,EAAE,sBAAsB;OACnB;KACR,4CAAC;MAAI,WAAU;MAAkC,OAAO;OAAE,GAAGA,SAAO;OAAS,gBAAgB;OAAY,WAAW;OAAG;iBACrH,2CAAC;OAAO,MAAK;OAAS;OAAU,eAAe,qBAAqB,OAAU;iBAAG,EAAE,SAAS;QAAU,EACtG,2CAAC;OAAO,MAAK;OAAS,WAAU;OAA2B,UAAU,CAAC,qBAAqB;OACzF,eAAe;AAAE,QAAK,cAAc;;iBAAK,EAAE,kBAAkB;QAAU;OACrE;QACL;KACI;;GACL;;;;;;;;;;ACxwBV,SAAS,UAAU,YAA2F;CAC5G,MAAM,UAAU,WAAW,QAAQ,WAAW;CAC9C,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,QAAQ,CAAC;CAClD,MAAM,MAAM,SAAS,IAAI;EAAE,OAAO;EAAK,QAAQ,MAAM;EAAO,GAAG;EAAE,OAAO,MAAM;EAAO,QAAQ;EAAK;CAClG,MAAM,QAAQ,KAAK,IAAI,GAAG,WAAW,QAAQ,IAAI,OAAO,WAAW,SAAS,IAAI,OAAO;AACvF,QAAO;EACL,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,QAAQ,MAAM,CAAC;EACjD,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,SAAS,MAAM,CAAC;EACnD,gBAAgB,UAAU,MAAO,eAAe,UAAU,IAAI,gBAAgB;EAC/E;;AAGH,MAAMC,WAAwC;CAC5C,SAAS;EAAE,SAAS;EAAQ,UAAU;EAAQ,KAAK;EAAG,gBAAgB;EAAc;CACpF,OAAO;EACL,SAAS;EAAQ,YAAY;EAAU,UAAU;EAAU,SAAS;EACpE,QAAQ;EAAsD,cAAc;EAC5E,YAAY;EAA+C,QAAQ;EACpE;CACD,MAAM;EAAE,OAAO;EAAI,QAAQ;EAAI;CAC/B,KAAK;EAAE,OAAO;EAAQ,QAAQ;EAAQ,WAAW;EAAS,SAAS;EAAS;CAC5E,SAAS;EAAE,UAAU;EAAI,OAAO;EAAmC,SAAS;EAAS;CACrF,OAAO;EACL,UAAU;EAAI,OAAO;EAAwC,QAAQ;EACrE,QAAQ;EAAsD,cAAc;EAC5E,YAAY;EAAe,SAAS;EACrC;CACD,SAAS;EACP,UAAU;EAAS,OAAO;EAAG,QAAQ;EAAM,SAAS;EAAQ,YAAY;EACxE,YAAY;EAAuB,SAAS;EAC7C;CACD,YAAY;EAAE,UAAU;EAAQ,WAAW;EAAQ,WAAW;EAAW,cAAc;EAAG;CAC1F,OAAO;EACL,UAAU;EAAY,KAAK;EAAI,OAAO;EAAI,OAAO;EAAI,QAAQ;EAAI,SAAS;EAC1E,YAAY;EAAU,QAAQ;EAAQ,cAAc;EAAO,QAAQ;EACnE,YAAY;EAA6B,OAAO;EAAQ,UAAU;EAAI,YAAY;EACnF;CACF;;;;;;AAOD,SAAS,cAAc,EAAE,KAAK,KAAK,QAAQ,WAKxC;AACD,4BAAgB;EACd,MAAM,SAAS,UAAyB;AAAE,OAAI,MAAM,QAAQ,SAAU,UAAS;;AAC/E,SAAO,iBAAiB,WAAW,MAAM;AACzC,eAAa;AAAE,UAAO,oBAAoB,WAAW,MAAM;;IAC1D,CAAC,QAAQ,CAAC;AACb,QACE,4CAAC;EAAI,MAAK;EAAS,cAAY,OAAO;EAAQ,OAAOC,SAAO;EAAS,SAAS;aAC5E,2CAAC;GAAS;GAAU;GAAK,OAAOA,SAAO;GAAY,UAAS,UAAS;AAAE,UAAM,iBAAiB;;IAAM,EACpG,2CAAC;GAAO,MAAK;GAAS,cAAY,OAAO;GAAO,OAAOA,SAAO;GAAO,SAAS;aAAS;IAAU;GAC7F;;;;;;;AASV,SAAgB,aAAa,EAAE,YAAY,MAAM,SAAS,UAKvD;CACD,MAAM,CAAC,KAAK,8BAAkC,KAAK;CACnD,MAAM,CAAC,OAAO,gCAAqB,MAAM;CACzC,MAAM,CAAC,MAAM,+BAAoB,MAAM;CAGvC,MAAM,CAAC,SAAS,kCAAuB,EAAE;CACzC,MAAM,qCAA0B;AAAE,cAAW,MAAK,IAAI,EAAE;IAAI,EAAE,CAAC;CAC/D,MAAM,qCAA0B;AAAE,UAAQ,MAAM;IAAI,EAAE,CAAC;CACvD,MAAM,+BACG,YAAY,WAAW,UAAU,WAAW,GAAG,QACtD,CAAC,YAAY,QAAQ,CACtB;AAED,4BAAgB;EACd,IAAI,OAAO;AACX,WAAS,MAAM;AACf,SAAO,KAAK;AACZ,EAAK,KAAK,WAAW,CAAC,MAAM,QAAQ;AAAE,OAAI,KAAM,QAAO,IAAI;IAAG,CAAC,YAAY;AAAE,OAAI,KAAM,UAAS,KAAK;IAAG;AACxG,eAAa;AAAE,UAAO;;IACrB;EAAC;EAAY;EAAM;EAAQ,CAAC;CAE/B,MAAM,QAAQ,WAAW,QAAQ,OAAO;AACxC,KAAI,MACF,QAAO,2CAAC;EAAO,MAAK;EAAS,OAAOA,SAAO;EAAO,SAAS;YAAQ,OAAO;GAAoB;CAEhG,MAAM,MAAM,QAAQ,SAAYA,SAAO,OAAO;EAAE,OAAO,IAAI;EAAO,QAAQ,IAAI;EAAQ;AACtF,QACE,qFACE,2CAAC;EACC,MAAK;EACL,OAAO;GAAE,GAAGA,SAAO;GAAO,GAAG;GAAK;EAClC,OAAO,OAAO;EACd,cAAY,OAAO,UAAU,MAAM;EACnC,eAAe;AAAE,OAAI,QAAQ,KAAM,SAAQ,KAAK;;YAE/C,QAAQ,OACL,2CAAC;GAAK,OAAOA,SAAO;aAAU,OAAO;IAAe,GACpD,2CAAC;GAAS;GAAK,KAAK;GAAO,OAAO;IAAE,GAAGA,SAAO;IAAK,gBAAgB,KAAK;IAAgB;IAAI;GACzF,EACR,QAAQ,QAAQ,QAAQ,2CAAC;EAAmB;EAAK,KAAK;EAAO,QAAQ,OAAO;EAAU,SAAS;GAAS,IACxG;;;;AAMP,SAAgB,aAAa,EAAE,QAAQ,MAAM,UAI1C;AACD,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,UAAU,OAAO,WAAW,IAAI,WAAW;AACjD,QACE,2CAAC;EAAI,OAAOA,SAAO;YAChB,OAAO,KAAK,OAAO,UAClB,2CAAC;GAA+D,YAAY,MAAM;GAAkB;GAAe;GAAiB;KAAjH,GAAG,MAAM,WAAW,aAAa,GAAG,QAAuF,CAC9I;GACE;;;;;;;;;;;;;;;;;;;;;;;;;;ACxKV,MAAa,qBAAqB;AAElC,MAAa,gBAAgB;CAO3B,aAAa;CAGb,SAAS,EACP,yCAAyC,CAAC,uBAAuB,6BAA6B,EAC/F;CAMD,OAAO;EACL,SAAS;EACT,OAAO,CAAC,WAAW,cAAc;EAClC;CAGD,OAAO;EACL,oBAAoB;EACpB,sBAAsB;EACtB,4BAA4B;EAC5B,8BAA8B;EAC/B;CAQD,UAAU;EACR,WAAW;EACX,YAAY;EACZ,QAAQ;EACR,kBAAkB;EAClB,OAAO;EACR;CAGD,SAAS,EAEP,eAAe;EAAE,WAAW;EAAuB,SAAS;EAAmC,EAChG;CAQD,aAAa;EACX,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,eAAe;EAChB;CAGD,QAAQ;EACN,SAAS;EACT,OAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACF;CACF;;;;;ACpHD,MAAMC,eAAyC;;;;;;;;;;;AAY/C,SAAgB,SAAS,OAAe,MAA8C;CACpF,MAAMC,YAAU;CAChB,MAAM,OAAOA,UAAQ,OAAO,KAAK,aAAaA,UAAQ,OAAO,KAAK;AAClE,KAAI,SAAS,OAAW,QAAO;AAC/B,SAAQ,KACN,GAAG,mBAAmB,IAAI,cAAc,MAAM,QAAQ,uBAAuB,KAAK,kBAAkB,KAAK,IAC1G;AACD,QAAO;;;;;;ACRT,MAAMC,gBAAc,SAASC,wCAAY,UAAU;;AAGnD,MAAMC,sBAAoB;;;;;;AA6C1B,SAAgB,kBAAkB,KAA2C;AAG3E,SAAO,eACL,sBAA2C,KAAK,SAAS,EAAE,GAAG,YAAY,CAAC,CACxE,MAAK,WAAU,QAAQ,OAAO,UAAU,UAAU,OAAO,aAAa;;;;;;;;;AAU7E,SAASC,oBAAkB,KAAuB,QAA0C;CAC1F,IAAIC,OAAe,GAAG;AACtB,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,UAAU,EAAE,CAAC,CACtD,QAAO,KAAK,WAAW,IAAI,KAAK,IAAI,OAAO,MAAM,CAAC;AAEpD,QAAO;;;AAIT,SAASC,eAAa,SAAyB;CAC7C,IAAIC;AACJ,KAAI;AACF,WAAS,KAAK,MAAM,QAAQ;SACtB;AAEN,WAAS;;CAEX,IAAIC;AACJ,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,OAAO;AACb,MAAI,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW,GAAI,UAAS,KAAK;MAEvE,MAAK,MAAM,SAAS,OAAO,OAAO,KAAK,CACrC,KAAI,OAAO,UAAU,YAAY,UAAU,IAAI;AAAE,YAAS;AAAO;;;CAIvE,MAAM,QAAQ,UAAU,SAAS,MAAM,MAAM,EAAE,CAAC,MAAM;AACtD,QAAO,KAAK,SAASL,sBAAoB,GAAG,KAAK,MAAM,GAAGA,oBAAkB,CAAC,KAAK;;;AAIpF,SAASM,aAAW,OAA8B;AAChD,KAAI,EAAE,UAAU,OAAQ,QAAO;CAC/B,MAAMC,QAAkB,EAAE;AAC1B,MAAK,MAAM,QAAQ,MAAM,QACvB,KAAI,KAAK,SAAS,OAAQ,OAAM,KAAK,KAAK,KAAK;AAEjD,KAAI,MAAM,WAAW,KAAK,MAAM,UAAU,OAAW,OAAM,KAAK,GAAG,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,OAAO;AAC3G,QAAO,MAAM,KAAK,KAAK;;;AAIzB,SAAS,aAAa,OAA4D;AAChF,KAAI,EAAE,UAAU,OAAQ,QAAO,EAAE;CACjC,MAAMC,SAA+C,EAAE;AACvD,MAAK,MAAM,QAAQ,MAAM,QACvB,KAAI,KAAK,SAAS,QAAS,QAAO,KAAK,EAAE,YAAY,KAAK,YAAkC,CAAC;AAE/F,QAAO;;AAGT,MAAMC,WAAwC;CAC5C,WAAW;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAG,SAAS;EAAS;CACjF,KAAK;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAG,UAAU;EAAG;CACnE,MAAM;EAAE,SAAS;EAAe,YAAY;EAAG,OAAO;EAAmC;CACzF,OAAO;EACL,UAAU;EAAI,YAAY;EAAQ,OAAO;EACzC,UAAU;EAAU,cAAc;EAAY,YAAY;EAC3D;CACD,QAAQ;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC;CACjG,QAAQ;EACN,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EACpD,YAAY;EAAY,cAAc;EACvC;CACD,OAAO;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAwC;CACtG;;;;;;AAOD,SAAgB,sBAAsB,OAAmC;CACvE,MAAM,EAAE,OAAO,SAAS;CACxB,MAAM,IAAI,MAAM,KAAKR;AACrB,KAAI,UAAU,OAAW,QAAO;CAChC,MAAM,UAAU,UAAU;CAC1B,MAAM,WAAW,UAAU,MAAM,MAAM,UAAU,MAAM,UAAU,UAAU,MAAM,UAAU,WAAc;CACzG,IAAI,aAAa;AACjB,KAAI;EACF,MAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,MAAI,MAAM,QAAQ,MAAM,gBAAgB,CAAE,cAAa,KAAK,gBAAgB;SACtE;CACR,MAAM,QAAQ,iBAAiB,aAAa,IAAI,KAAK,WAAW,SAAS,GAAG,IAAIE,eAAa,QAAQ;CACrG,MAAM,SAAS,aAAa,MAAM;CAClC,MAAM,OAAO,UAAUG,aAAW,MAAM,GAAG;CAC3C,MAAMI,SAA6B;EACjC,OAAO,EAAE,QAAQ;EACjB,MAAM,EAAE,YAAY;EACpB,YAAW,SAAQ,EAAE,kBAAkB,EAAE,MAAM,CAAC;EAChD,SAAS,EAAE,eAAe;EAC1B,YAAY,EAAE,kBAAkB;EAChC,UAAU;GAAE,QAAQ,EAAE,eAAe;GAAE,OAAO,EAAE,aAAa;GAAE;EAChE;AACD,QACE,4CAAC;EAAI,OAAOC,SAAO;;GACjB,4CAAC;IAAI,OAAOA,SAAO;eACjB,2CAAC;KAAK,OAAOA,SAAO;eAAM,2CAACb,iBAAY,MAAM,KAAM;MAAO,EAC1D,2CAAC;KAAK,OAAOa,SAAO;eAAQ;MAAa;KACrC;GACL,CAAC,WAAW,2CAAC;IAAE,OAAOA,SAAO;cAAS,EAAE,aAAa;KAAK;GAC1D,WAAW,MAAM,WAAW,SAAS,MACpC,2CAAC;IAAE,OAAOA,SAAO;cAAQ,KAAK,MAAM,MAAM,EAAE,CAAC;KAAO;GAErD,WAAW,CAAC,MAAM,WAAW,OAAO,SAAS,KAAK,SAAS,UAC1D,2CAAC;IAAqB;IAAc;IAAc;KAAU;GAE7D,WAAW,CAAC,MAAM,WAAW,OAAO,WAAW,KAAK,SAAS,MAC5D,2CAAC;IAAE,OAAOA,SAAO;cAAS;KAAS;;GAEjC;;;;;;AC/KV,MAAM,cAAc,SAASC,wCAAY,UAAU;;AAGnD,MAAM,oBAAoB;;;;;;AAsC1B,SAAgB,kBAAkB,KAAqE;AACrG,SAAO,SAAQ,sBAAkC,KAAK,SAAS,EAAE,MAAM,CAAC;;;;;;AAO1E,SAASC,oBAAkB,KAAuB,QAA0C;CAC1F,IAAIC,OAAe,GAAG;AACtB,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,UAAU,EAAE,CAAC,CACtD,QAAO,KAAK,WAAW,IAAI,KAAK,IAAI,OAAO,MAAM,CAAC;AAEpD,QAAO;;;AAIT,SAAS,aAAa,SAAyB;CAC7C,IAAIC;AACJ,KAAI;AACF,WAAS,KAAK,MAAM,QAAQ;SACtB;AAEN,WAAS;;CAEX,IAAIC;AACJ,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,OAAO;AACb,MAAI,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW,GAAI,UAAS,KAAK;MAEvE,MAAK,MAAM,SAAS,OAAO,OAAO,KAAK,CACrC,KAAI,OAAO,UAAU,YAAY,UAAU,IAAI;AAAE,YAAS;AAAO;;;CAIvE,MAAM,QAAQ,UAAU,SAAS,MAAM,MAAM,EAAE,CAAC,MAAM;AACtD,QAAO,KAAK,SAAS,oBAAoB,GAAG,KAAK,MAAM,GAAG,kBAAkB,CAAC,KAAK;;;AAIpF,SAAS,WAAW,OAA8B;AAChD,KAAI,EAAE,UAAU,OAAQ,QAAO;CAC/B,MAAMC,QAAkB,EAAE;AAC1B,MAAK,MAAM,QAAQ,MAAM,QACvB,KAAI,KAAK,SAAS,OAAQ,OAAM,KAAK,KAAK,KAAK;AAEjD,KAAI,MAAM,WAAW,KAAK,MAAM,UAAU,OAAW,OAAM,KAAK,GAAG,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,OAAO;AAC3G,QAAO,MAAM,KAAK,KAAK;;;;;;;AAQzB,SAAS,gBAAgB,OAA0C;AACjE,KAAI,EAAE,UAAU,OAAQ,QAAO;CAC/B,MAAM,OAAO,MAAM;AACnB,KAAI,OAAO,SAAS,YAAY,SAAS,MAAM;EAC7C,MAAM,WAAY,KAAiC;AACnD,MAAI,OAAO,aAAa,YAAY,SAAS,SAAS,EAAG,QAAO;;CAElE,MAAM,QAAQ,6BAA6B,KAAK,WAAW,MAAM,CAAC;AAClE,KAAI,UAAU,KAAM,QAAO;CAC3B,MAAM,OAAO,MAAM;AACnB,QAAO,KAAK,MAAM,KAAK,YAAY,IAAI,GAAG,EAAE;;;AAI9C,SAAS,YAAY,YAAgC;CACnD,MAAM,SAAS,KAAK,WAAW;CAC/B,MAAM,QAAQ,IAAI,WAAW,OAAO,OAAO;AAC3C,MAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,QAAS,OAAM,SAAS,OAAO,WAAW,MAAM;AAC3F,QAAO;;AAST,MAAMC,WAAwC;CAC5C,WAAW;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAG,SAAS;EAAS;CACjF,KAAK;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAG,UAAU;EAAG;CACnE,MAAM;EAAE,SAAS;EAAe,YAAY;EAAG,OAAO;EAAmC;CACzF,OAAO;EACL,UAAU;EAAI,YAAY;EAAQ,OAAO;EACzC,UAAU;EAAU,cAAc;EAAY,YAAY;EAC3D;CACD,QAAQ;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC;CACjG,QAAQ;EACN,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EACpD,YAAY;EAAY,cAAc;EACvC;CACD,OAAO;EAAE,QAAQ;EAAG,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAwC;CACrG,OAAO;EACL,SAAS;EAAS,UAAU;EAAK,OAAO;EAAQ,cAAc;EAC9D,iBAAiB;EAClB;CACF;;;;;;AAOD,SAAgB,sBAAsB,OAAmC;CACvE,MAAM,EAAE,OAAO,cAAc;CAC7B,MAAM,IAAI,MAAM,KAAKL;CACrB,MAAM,UAAU,UAAU,UAAa,UAAU;CACjD,MAAM,UAAU,WAAW,MAAM;CACjC,MAAM,WAAW,UAAU,UAAa,WAAW,CAAC,UAAU,gBAAgB,MAAM,GAAG;CACvF,MAAM,CAAC,MAAM,+BAA+B,EAAE,OAAO,WAAW,CAAC;AAEjE,4BAAgB;AACd,MAAI,aAAa,UAAa,cAAc,OAAW;EACvD,IAAI,YAAY;EAChB,IAAIM;AACJ,UAAQ,EAAE,OAAO,WAAW,CAAC;AAC7B,YAAU,SAAS,CAAC,MACjB,UAAU;AACT,OAAI,UAAW;AAEf,eAAY,IAAI,gBAAgB,IAAI,KAAK,CAAC,YAAY,MAAM,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,MAAM,WAAW,CAAC,CAAC;AAC7G,WAAQ;IAAE,OAAO;IAAS,KAAK;IAAW,CAAC;MAE5C,UAAmB;AAClB,OAAI,UAAW;AACf,WAAQ;IAAE,OAAO;IAAU,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAAE,CAAC;IAEhG;AACD,eAAa;AACX,eAAY;AACZ,OAAI,cAAc,OAAW,KAAI,gBAAgB,UAAU;;IAE5D,CAAC,UAAU,UAAU,CAAC;AAEzB,KAAI,UAAU,OAAW,QAAO;CAEhC,MAAM,QAAQ,mBAAmB,cADhB,UAAU,MAAM,MAAM,UAAU,MAAM,UAAU,UAAU,MAAM,UAAU,WAAc,GACnD;CACtD,MAAM,OAAO,UAAU,WAAW,MAAM,GAAG;AAC3C,QACE,4CAAC;EAAI,OAAOC,SAAO;;GACjB,4CAAC;IAAI,OAAOA,SAAO;eACjB,2CAAC;KAAK,OAAOA,SAAO;eAAM,2CAAC,eAAY,MAAM,KAAM;MAAO,EAC1D,2CAAC;KAAK,OAAOA,SAAO;eAAQ;MAAa;KACrC;GACL,CAAC,WAAW,2CAAC;IAAE,OAAOA,SAAO;cAAS,EAAE,kBAAkB;KAAK;GAC/D,WAAW,WAAW,SAAS,MAC9B,2CAAC;IAAE,OAAOA,SAAO;cAAQ,KAAK,MAAM,MAAM,EAAE,CAAC;KAAO;GAErD,WAAW,CAAC,WAAW,aAAa,UAAa,KAAK,UAAU,aAC/D,2CAAC;IAAE,OAAOA,SAAO;cAAS,EAAE,eAAe;KAAK;GAEjD,WAAW,CAAC,WAAW,aAAa,UAAa,KAAK,UAAU,YAC/D,2CAAC;IAAE,OAAOA,SAAO;cAAQ,EAAE,mBAAmB,EAAE,SAAS,KAAK,SAAS,CAAC;KAAK;GAE9E,WAAW,CAAC,WAAW,aAAa,UAAa,KAAK,UAAU,WAE/D,2CAAC;IAAM,OAAOA,SAAO;IAAO,KAAK,KAAK;IAAK;IAAS,SAAQ;KAAa;GAE1E,WAAW,CAAC,WAAW,aAAa,UAAa,SAAS,MACzD,2CAAC;IAAE,OAAOA,SAAO;cAAS;KAAS;;GAEjC;;;;;;;;;;;;;;;;;;ACtJV,SAAgB,kBACd,YACA,QACA,WACkC;AAClC,QAAO,YAAY;EACjB,MAAM,QAAQ,MAAM,sBAAkC,WAAW,KAAK,SAAS,EAAE,WAAW,CAAC;EAC7F,MAAM,cAAc,QAAQ;AAC5B,MAAI,gBAAgB,OAAW,QAAO;GAAE,SAAS;GAAO,MAAM,MAAM;GAAM;EAC1E,MAAM,EAAE,YAAY,MAAM,YAAY,aAAa,UAAU,CAAC,MAAM;AAGpE,SAAO;GAAE,SAFO,YAAY,QAAQ,QAAQ,aAAa,WACpD,MAAM,WAAW,SAAS,QAAQ,MAAM;GAC3B,MAAM,MAAM;GAAM;;;;AAKxC,SAAgB,kBACd,YACA,WACiC;AACjC,SAAO,SAAQ,sBAAsB,WAAW,KAAK,YAAY;EAAE;EAAW;EAAM,CAAC,CAClF,WAAW,YAAY,MAAM;;;AAIlC,SAASC,oBAAkB,KAA+B;AACxD,QAAO,GAAG;;AAGZ,MAAMC,QAA8B,CAAC,YAAY,OAAO;;;;;;;;AASxD,MAAM,mBAAmB;;;;;;;;;AAUzB,SAAgB,YAAY,EAAE,WAAW,UAAU,KAAuB;CACxE,MAAM,YAAY,KAAKD;CACvB,MAAM,CAAC,OAAO,gCAA8C,KAAK;CACjE,MAAM,CAAC,MAAM,+BAAoB,MAAM;CACvC,MAAM,CAAC,MAAM,+BAAoB,MAAM;CACvC,MAAM,4BAAwC,KAAK;CAInD,MAAM,4BAAiB,UAAU;AACjC,SAAQ,UAAU;AAElB,4BAAgB;AACd,MAAI,QAAQ,YAAY,OAAW;EACnC,IAAI,YAAY;EAChB,IAAI,WAAW;EACf,MAAM,eAAqB;GACzB,MAAM,OAAO,QAAQ;AACrB,OAAI,SAAS,UAAa,SAAU;AACpC,cAAW;AACX,GAAK,MAAM,CAAC,MACT,WAAW;AAAE,QAAI,CAAC,UAAW,UAAS,OAAO;YACxC,GACP,CAAC,cAAc;AAAE,eAAW;KAAQ;;AAEvC,UAAQ;EACR,MAAM,QAAQ,YAAY,QAAQ,iBAAiB;AACnD,eAAa;AACX,eAAY;AACZ,iBAAc,MAAM;;IAErB,EAAE,CAAC;AAEN,4BAAgB;AACd,MAAI,CAAC,KAAM;EACX,MAAM,gBAAgB,UAA4B;AAChD,OAAI,CAAC,QAAQ,SAAS,SAAS,MAAM,OAAe,CAAE,SAAQ,MAAM;;AAEtE,WAAS,iBAAiB,aAAa,aAAa;AACpD,eAAa;AAAE,YAAS,oBAAoB,aAAa,aAAa;;IACrE,CAAC,KAAK,CAAC;AAEV,KAAI,cAAc,UAAa,aAAa,UAAa,UAAU,QAAQ,CAAC,MAAM,QAChF,QAAO;CAGT,MAAM,UAAU,SAA0B;AACxC,MAAI,KAAM;AACV,MAAI,SAAS,MAAM,MAAM;AACvB,WAAQ,MAAM;AACd;;AAEF,UAAQ,KAAK;AACb,EAAK,SAAS,KAAK,CAAC,MAAM,OAAO;AAC/B,WAAQ,MAAM;AACd,OAAI,IAAI;AACN,aAAS;KAAE,SAAS;KAAM;KAAM,CAAC;AACjC,YAAQ,MAAM;;IAEhB;;CAGJ,MAAM,aAAmB;AACvB,UAAQ,KAAK;EACb,MAAM,OAAO,QAAQ;AACrB,MAAI,SAAS,OAAW;AACxB,EAAK,MAAM,CAAC,KAAK,gBAAgB,GAA2C;;CAG9E,MAAM,YAAY,SAChB,UAAU,SAAS,SAAS,cAAc,gBAAgB;CAC5D,MAAM,mBAAmB,SACvB,UAAU,SAAS,SAAS,yBAAyB,2BAA2B;CAClF,MAAM,eAAe,GAAG,UAAU,QAAQ,CAAC,KAAK,SAAS,MAAM,KAAK;AAEpE,QACE,4CAAC;EACC,KAAK;EACL,WAAU;EACV,OAAOE,SAAO;EACd,YAAY,UAAU;AACpB,OAAI,MAAM,QAAQ,YAAY,MAAM;AAClC,UAAM,gBAAgB;AACtB,YAAQ,MAAM;;;;GAIlB,2CAAC,qBAAO,wBAA8B;GACrC,QACC,2CAAC;IAAI,OAAOA,SAAO;IAAM,MAAK;IAAO,cAAY,UAAU,QAAQ;cAChE,MAAM,KAAI,SACT,4CAAC;KAEC,MAAK;KACL,MAAK;KACL,gBAAc,SAAS,MAAM;KAC7B,OAAOA,SAAO;KACd,UAAU;KACV,eAAe;AAAE,aAAO,KAAK;;gBAE7B,2CAAC;MAAK,OAAOA,SAAO;gBAAY,SAAS,MAAM,OAAO,MAAM;OAAU,EACtE,4CAAC;MAAK,OAAOA,SAAO;iBAClB,2CAAC;OAAK,OAAOA,SAAO;iBAAW,SAAS,KAAK;QAAQ,EACrD,2CAAC;OAAK,OAAOA,SAAO;iBAAkB,gBAAgB,KAAK;QAAQ;OAC9D;OAZF,KAaE,CACT;KACE;GAER,2CAAC;IACC,MAAK;IACL,OAAOA,SAAO;IACd,iBAAc;IACd,iBAAe;IACf,OAAO;IACP,UAAU;IACV,eAAe;AACb,SAAI,KAAM,SAAQ,MAAM;SACnB,OAAM;;cAGZ;KACM;;GACL;;AAIV,MAAMC,WAAwC;CAC5C,MAAM;EAAE,UAAU;EAAY,SAAS;EAAe;CACtD,SAAS;EACP,QAAQ;EAA0C,cAAc;EAChE,YAAY;EAAoD,OAAO;EACvE,MAAM;EAAW,UAAU;EAAI,YAAY;EAC3C,SAAS;EAAW,QAAQ;EAAW,YAAY;EACpD;CACD,MAAM;EACJ,UAAU;EAAY,QAAQ;EAAQ,OAAO;EAAG,cAAc;EAC9D,UAAU;EAAK,SAAS;EAAG,QAAQ;EACnC,YAAY;EAAyD,QAAQ;EAC7E,WAAW;EAAkC,cAAc;EAA8B,SAAS;EAAQ,eAAe;EAAU,KAAK;EACzI;CACD,MAAM;EACJ,SAAS;EAAQ,YAAY;EAAc,KAAK;EAAG,OAAO;EAC1D,QAAQ;EAAQ,cAAc;EAA6B,YAAY;EACvE,SAAS;EAAW,QAAQ;EAAW,MAAM;EAAW,WAAW;EACpE;CACD,WAAW;EACT,OAAO;EAAI,YAAY;EAAG,UAAU;EAAI,YAAY;EACpD,OAAO;EACR;CACD,UAAU;EAAE,SAAS;EAAQ,eAAe;EAAU;CACtD,UAAU;EAAE,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAkC;CACvF,iBAAiB;EAAE,UAAU;EAAI,YAAY;EAAQ,OAAO;EAAmC;CAChG;;;;;ACjPD,SAAgB,eAAe,OAGb;AAChB,QAAO,SAAS,OAAO,cAAc;;AAEvC,MAAM,iBAAiB,eAAeC,uCAAW;;AAGjD,MAAM,yBAAyB,KAAK;;AAGpC,MAAM,yBAAyB;;AAG/B,MAAM,6BAA6B;;AAGnC,MAAM,YAAY;;AAGlB,MAAM,eAAe;;AAwCrB,SAAgB,cAAc,GAA8C;AAC1E,QAAO,EAAE,SAAS,MAAK,MAAK,EAAE,UAAU,IAAI,EAAE,SAAS;;AAMzD,MAAMC,iBAAgD;CACpD,OAAO;CACP,QAAQ;CACR,MAAM;CACN,SAAS;CACT,aAAa;CACb,uBAAuB;CACvB,eAAe;CACf,eAAe;CACf,WAAW;CACX,cAAc;CACf;;AAKD,SAAS,WAAW,UAAyB,SAAgC;AAC3E,QAAO,GAAG,SAAS,GAAG,QAAQ;;;;;;;;;;;;AAahC,SAAgB,mBACd,QACA,WACA,OACwB;CACxB,MAAM,6BAAa,IAAI,KAA0C;AACjE,MAAK,MAAM,EAAE,UAAU,aAAa,QAAQ;EAC1C,MAAM,MAAM,WAAW,UAAU,QAAQ;EACzC,MAAM,UAAU,UAAU,IAAI,IAAI;AAClC,MAAI,YAAY,OAAW;EAC3B,MAAM,OAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;EACvC,MAAMC,MAA2B;GAC/B,KAAK,QAAQ;GACb,WAAW,QAAQ;GACnB,GAAG,QAAQ,YAAY,SAAY,EAAE,GAAG,EAAE,SAAS,QAAQ,SAAS;GACpE,GAAG,SAAS,SAAY,EAAE,GAAG,EAAE,MAAM;GACrC;GACD;EACD,MAAM,UAAU,WAAW,IAAI,SAAS;AACxC,MAAI,YAAY,OAAW,YAAW,IAAI,UAAU;GAAE;GAAU,MAAM,eAAe;GAAW,UAAU,CAAC,IAAI;GAAE,CAAC;MAC7G,SAAQ,SAAS,KAAK,IAAI;;AAEjC,QAAO,CAAC,GAAG,WAAW,QAAQ,CAAC;;;AAIjC,eAAsB,gBAAgB,KAGnC;CACD,MAAM,CAAC,eAAe,QAAQ,YAAY,MAAM,QAAQ,WAAW;EACjE,sBAAmF,KAAK,UAAU,EAAE,CAAC;EACrG,sBAAkD,KAAK,gBAAgB,EAAE,CAAC;EAC1E,sBAA+G,KAAK,kBAAkB,EAAE,CAAC;EAC1I,CAAC;CACF,MAAMC,SAA6B,EAAE;CACrC,MAAM,4BAAY,IAAI,KAAoB;AAC1C,KAAI,cAAc,WAAW,YAC3B,MAAK,MAAM,YAAY;EAAC;EAAS;EAAU;EAAQ;EAAW;EAAc,EAAW;AACrF,YAAU,IAAI,SAAS;AACvB,OAAK,MAAM,WAAW,WAAW,cAAc,MAAM,UAAU,UAAU,CAAE,QAAO,KAAK;GAAE;GAAU;GAAS,CAAC;;AAGjH,KAAI,OAAO,WAAW,aAAa;AACjC,YAAU,IAAI,sBAAsB;AACpC,MAAI,OAAO,MAAM,cAAe,QAAO,KAAK;GAC1C,UAAU;GAAuB,SAAS;IAAE,KAAK;IAAU,WAAW;IAAM;GAC7E,CAAC;;AAEJ,KAAI,SAAS,WAAW,YACtB,MAAK,MAAM,CAAC,QAAQ,aAAa;EAC/B,CAAC,eAAe,cAAc;EAAE,CAAC,aAAa,cAAc;EAAE,CAAC,WAAW,UAAU;EAAE,CAAC,cAAc,aAAa;EACnH,EAAW;AACV,YAAU,IAAI,SAAS;AACvB,MAAI,SAAS,MAAM,SAAS,WAAY,QAAO,KAAK;GAClD;GAAU,SAAS;IAAE,KAAK;IAAQ,WAAW;IAAM;GACpD,CAAC;;AAGN,QAAO;EAAE;EAAQ;EAAW;;AAG9B,eAAsB,QAAQ,KAA8B,EAAE,UAAU,WAAqD;AAC3H,KAAI,aAAa,sBAAuB,QAAO,sBAAsB,KAAK,eAAe,EAAE,CAAC;AAC5F,KAAI,aAAa,iBAAiB,aAAa,iBAAiB,aAAa,aAAa,aAAa,aACrG,QAAO,sBAAsB,KAAK,iBAAiB,EAAE,QAAQ,aAAa,gBAAgB,cAAc,UAAU,CAAC;AAErH,QAAO,sBAAsB,KAAK,SAAS;EAAE;EAAU,SAAS,QAAQ;EAAK,CAAC;;;;;;;;;AAUhF,SAAgB,yBACd,QACA,WACgD;AAChD,QAAO,YAAY;EACjB,MAAM,cAAc,QAAQ;AAC5B,MAAI,gBAAgB,OAAW,QAAO;EACtC,MAAM,EAAE,YAAY,MAAM,YAAY,aAAa,UAAU,CAAC,MAAM;AACpE,SAAO,WAAW;;;;;;;;AAStB,SAAgB,YAAY,GAAwB;AAClD,KAAI,EAAE,aAAa,UAAa,CAAC,OAAO,SAAS,EAAE,SAAS,EAAE;AAC5D,MAAI,EAAE,UAAU,UAAa,EAAE,UAAU,GAAI,QAAO,EAAE;AACtD,UAAQ,EAAE,MAAV;GACE,KAAK,UAAW,QAAO;GACvB,KAAK,SAAU,QAAO;GACtB,QAAS,QAAO;;;CAGpB,MAAM,KAAK,KAAK,IAAI,GAAG,EAAE,WAAW,KAAK,KAAK,CAAC;CAC/C,MAAM,UAAU,KAAK,MAAM,KAAK,IAAO;CACvC,MAAM,QAAQ,KAAK,MAAM,UAAU,GAAG;CACtC,MAAM,OAAO,KAAK,MAAM,QAAQ,GAAG;AACnC,KAAI,OAAO,EAAG,QAAO,GAAG,KAAK,GAAG,QAAQ,GAAG;AAC3C,KAAI,QAAQ,EAAG,QAAO,GAAG,MAAM,GAAG,UAAU,GAAG;AAC/C,QAAO,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC;;;;;;AAOjC,SAAS,cAAc,OAAe,GAAwB;CAC5D,MAAM,UAAU,mBAAmB,EAAE,YAAY;AACjD,QAAO,YAAY,SAAY,GAAG,MAAM,MAAM,GAAG,MAAM,GAAG,QAAQ;;;AAIpE,SAAgB,kBAAkB,SAAiC,OAA+B;AAChG,QAAO,UAAU,SAAY,CAAC,GAAG,QAAQ,GAAG,CAC1C,GAAG,QAAQ,QAAO,MAAK,EAAE,UAAU,MAAM,EACzC,GAAG,QAAQ,QAAO,MAAK,EAAE,UAAU,MAAM,CAC1C;;;AAIH,MAAa,uBAAuB;AACpC,SAAgB,eAAe,SAAiC,OAAgB,UAA0B;CACxG,MAAM,UAAU,kBAAkB,SAAS,MAAM;CAEjD,MAAM,QAAQ,aAAa,gBACvB,KAAK,IAAI,GAAG,UAAU,SAAY,IAAI,QAAQ,QAAO,MAAK,EAAE,UAAU,MAAM,CAAC,OAAO,GACpF;AACJ,QAAO;EAAE,OAAO,QAAQ,MAAM,GAAG,MAAM;EAAE,QAAQ,QAAQ,MAAM,MAAM;EAAE;;;AAIzE,SAAgB,eAAe,GAAyB,OAAgB,IAAe,mBAA2B;CAChH,MAAM,UAAU,cAAc,EAAE,CAAC;AACjC,KAAI,EAAE,aAAa,eAAe;EAChC,MAAM,WAAW,UAAU,SAAY,EAAE,GAAG,QAAQ,QAAO,MAAK,EAAE,UAAU,MAAM;AAClF,MAAI,SAAS,WAAW,EACtB,QAAO,GAAG,EAAE,KAAK,GAAG,EAAE,UAAU,SAAY,yBAAyB,8BAA8B,EACjG,OAAO,IAAI,IAAI,QAAQ,KAAI,MAAK,EAAE,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC,MAC3D,CAAC;EAEJ,MAAMC,UAAQ,SAAS,MAAM,GAAG,EAAE,CAAC,KAAI,MAAK,cAAc,EAAE,SAAS,WAAW,EAAE,cAAc,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC;AACxH,SAAO,GAAG,EAAE,KAAK,GAAGA,QAAM,KAAK,MAAM;;CAEvC,MAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE,CAAC,KAAI,MAAK,cAAc,YAAY,EAAE,EAAE,EAAE,CAAC;AAC5E,KAAI,QAAQ,SAAS,EAAG,OAAM,KAAK,IAAI,QAAQ,SAAS,IAAI;AAC5D,QAAO,GAAG,EAAE,KAAK,GAAG,MAAM,KAAK,MAAM;;;AAMvC,SAAgB,4BACd,UACA,SAC4B;AAC5B,QAAO,YAAY,UAAa,OAAO,OAAO,gBAAgB,QAAQ,SAAS,GAAG,UAAU;;;AAI9F,SAAgB,kBACd,UACA,SACiC;CACjC,MAAM,QAAQ,SAAS,MAAK,MAAK,EAAE,aAAa,QAAQ;AACxD,QAAO,UAAU,SAAY,EAAE,GAAG,CAAC,MAAM;;;;;;;;;;;;;;AAe3C,SAAgB,gBACd,UACA,SACA,MACiC;AACjC,KAAI,SAAS,WAAW,EAAG,QAAO,EAAE;CACpC,MAAM,QAAQ,SAAS,MAAK,MAAK,EAAE,aAAa,QAAQ;AACxD,KAAI,UAAU,OAAW,QAAO,CAAC,MAAM;AAEvC,QAAO,CAAC,WADM,OAAO,SAAS,KAAK,GAAG,KAAK,MAAM,KAAK,GAAG,KAC9B,SAAS,SAAU,SAAS,UAAU,SAAS,QAAS;;;AAIrF,SAAgB,iBACd,UACA,SACiC;CACjC,MAAM,QAAQ,SAAS,MAAK,MAAK,EAAE,aAAa,QAAQ;AACxD,QAAO,UAAU,SAAY,WAAW,CAAC,OAAO,GAAG,SAAS,QAAO,MAAK,MAAM,MAAM,CAAC;;;;;;;AAQvF,SAAS,WAAW,QAAqD;AACvE,KAAI,WAAW,UAAa,OAAO,SAAS,WAAW,EAAG,QAAO,EAAE;CACnE,MAAM,WAAW,OAAO,SAAS,MAAK,MAAK,EAAE,UAAU,IAAI,OAAO,SAAS;AAC3E,QAAO,OAAO,SACX,KAAI,MAAM,MAAM,WAAW;EAAE,GAAG;EAAG,WAAW;EAAM,GAAG,EAAG,CAC1D,MAAM,GAAG,MAAM,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;;;AAI9D,SAAS,kBAAkB,KAAuB,QAA0C;AAC1F,QAAO,GAAG,KAAK,QAAQ,eAAe,GAAG,SAAiB,OAAO,SAAS,SAAS,GAAG,CAAC;;;AAMzF,SAAS,iBAAiB,GAAc,UAA6B;CACnE,MAAM,OAAOC,SAAO,SAAS,YACzB,EAAE,eAAe,GACjBA,SAAO,SAAS,WAAW,EAAE,cAAc,GAAG,EAAE,cAAc;AAClE,QAAOA,SAAO,UAAU,UAAaA,SAAO,UAAU,KAAK,GAAG,KAAK,KAAKA,SAAO,UAAU;;;;;;;;AAS3F,SAAgB,uBAAuB,EAAE,KAAK,cAAc,GAAG,cAA2C;CACxG,MAAMC,YAAuB,KAAK;CAClC,MAAM,CAAC,UAAU,mCAAgD,EAAE,CAAC;CACpE,MAAM,CAAC,WAAW,oCAAqD,OAAU;CACjF,MAAM,CAAC,kBAAkB,2CAA4D,OAAU;CAC/F,MAAM,cAAc,mBAAmB;CACvC,MAAM,UAAU,WAAW;CAC3B,MAAM,iBAAiB,4BAA4B,kBAAkB,UAAU;CAC/E,MAAM,CAAC,MAAM,+BAAoB,MAAM;CACvC,MAAM,CAAC,OAAO,gCAAqB,MAAM;CAEzC,MAAM,CAAC,UAAU,mCAAwB,EAAE;CAG3C,MAAM,CAAC,YAAY,qCAA8C,OAAU;CAC3E,MAAM,gCAAqB,MAAM;CACjC,MAAM,+BAAoB,KAAK;CAC/B,MAAM,4BAAyC,KAAK;CACpD,MAAM,6BAAyC,KAAK;CAGpD,MAAM,4BAAyC,KAAK;CAGpD,MAAM,+BAAoB,aAAa;AACvC,YAAW,UAAU;CAOrB,MAAM,iDAAsB,IAAI,KAA4B,CAAC;CAC7D,MAAM,oDAAyB,IAAI,KAAkE,CAAC;CAEtG,MAAM,iCAAsB,YAA2B;AACrD,MAAI,QAAQ,UAAa,YAAY,QAAS;AAC9C,cAAY,UAAU;AACtB,MAAI;GACF,MAAM,EAAE,QAAQ,cAAc,MAAM,gBAAgB,IAAI;AACxD,OAAI,CAAC,WAAW,QAAS;GAEzB,MAAM,YAAY,aAAa;GAG/B,MAAM,OAAO,IAAI,IAAI,OAAO,KAAK,EAAE,UAAU,cAAc,WAAW,UAAU,QAAQ,CAAC,CAAC;AAC1F,QAAK,MAAM,OAAO,UAAU,MAAM,CAChC,KAAI,UAAU,IAAI,IAAI,MAAM,KAAK,EAAE,CAAC,GAAoB,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE;AAC1E,cAAU,OAAO,IAAI;AACrB,oBAAgB,QAAQ,OAAO,IAAI;;GAIvC,MAAM,UAAU,MAAM,QAAQ,WAC5B,OAAO,IAAI,OAAO,EAAE,UAAU,cAAc;AAE1C,WAAO;KAAE;KAAU;KAAS,OADd,MAAM,QAAQ,KAAK;MAAE;MAAU;MAAS,CAAC;KACpB;KACnC,CACH;AACD,OAAI,CAAC,WAAW,QAAS;AAEzB,QAAK,MAAM,EAAE,UAAU,aAAa,QAAQ;IAC1C,MAAM,MAAM,WAAW,UAAU,QAAQ;AACzC,oBAAgB,QAAQ,IAAI,KAAK;KAAE,GAAG,gBAAgB,QAAQ,IAAI,IAAI;KAAE,OAAO;KAAM,CAAC;;GAExF,MAAM,wBAAQ,IAAI,KAAqB;AACvC,QAAK,MAAM,KAAK,SAAS;AACvB,QAAI,EAAE,WAAW,YAAa;IAC9B,MAAM,EAAE,UAAU,SAAS,UAAU,EAAE;IACvC,MAAM,MAAM,WAAW,UAAU,QAAQ;AACzC,QAAI,MAAM,SAAS,OAAW,OAAM,IAAI,KAAK,MAAM,KAAK;AACxD,QAAI,CAAC,MAAM,aAAa,CAAC,MAAM,WAAW,MAAM,QAAQ,WAAW,GAAG;AACpE,eAAU,OAAO,IAAI;AACrB,qBAAgB,QAAQ,OAAO,IAAI;AACnC;;AAEF,cAAU,IAAI,KAAK,MAAM,QAAQ;AACjC,oBAAgB,QAAQ,IAAI,KAAK;KAAE,YAAY,MAAM,cAAc,KAAK,KAAK;KAAE,OAAO,MAAM,UAAU;KAAM,CAAC;;AAG/G,gBAAY,aAAY,CACtB,GAAG,mBAAmB,QAAQ,WAAW,MAAM,CAAC,KAAI,aAAY;IAAE,GAAG;IACnE,UAAU,QAAQ,SAAS,KAAI,aAAY;KAAE,GAAG;KAC9C,GAAG,gBAAgB,QAAQ,IAAI,GAAG,QAAQ,SAAS,GAAG,QAAQ,MAAM;KACrE,EAAE;IACJ,EAAE,EACH,GAAG,SAAS,QAAO,YAAW,CAAC,UAAU,IAAI,QAAQ,SAAS,CAAC,CAAC,KAAI,aAAY;IAAE,GAAG;IACnF,UAAU,QAAQ,SAAS,KAAI,aAAY;KAAE,GAAG;KAAS,OAAO;KAAM,EAAE;IACzE,EAAE,CACJ,CAAC;UACI;AAEN,OAAI,WAAW,QAAS,cAAY,aAAY,SAAS,KAAI,aAAY;IAAE,GAAG;IAC5E,UAAU,QAAQ,SAAS,KAAI,aAAY;KAAE,GAAG;KAAS,OAAO;KAAM,EAAE;IACzE,EAAE,CAAC;YACI;AACR,eAAY,UAAU;;IAEvB,CAAC,IAAI,CAAC;AAET,4BAAgB;AACd,aAAW,UAAU;AACrB,eAAa;AAAE,cAAW,UAAU;;IACnC,EAAE,CAAC;AAGN,4BAAgB;AACd,MAAI,gBAAgB,SAAU;AAC9B,EAAK,SAAS;EACd,MAAM,QAAQ,kBAAkB;AAAE,GAAK,SAAS;KAAI,uBAAuB;AAC3E,SAAO,iBAAiB,2BAA2B,QAAQ;AAC3D,eAAa;AACX,iBAAc,MAAM;AACpB,UAAO,oBAAoB,2BAA2B,QAAQ;;IAE/D,CAAC,SAAS,YAAY,CAAC;AAE1B,4BAAgB;AACd,MAAI,WAAW,YAAY,OAAW;EACtC,IAAI,YAAY;EAChB,IAAI,WAAW;EACf,MAAM,eAAqB;GACzB,MAAM,OAAO,WAAW;AACxB,OAAI,SAAS,UAAa,SAAU;AACpC,cAAW;AACX,GAAK,MAAM,CAAC,MACT,UAAU;AACT,QAAI,UAAW;AACf,yBAAoB,aAAY,4BAA4B,UAAU,MAAM,CAAC;AAC7E,iBAAa,MAAM;YAEf,GACP,CAAC,cAAc;AAAE,eAAW;KAAQ;;AAEvC,UAAQ;EACR,MAAM,QAAQ,YAAY,QAAQ,uBAAuB;AACzD,eAAa;AACX,eAAY;AACZ,iBAAc,MAAM;;IAErB,EAAE,CAAC;CAEN,MAAM,sEAA0B;EAAE;EAAM,WAAW;EAAS;EAAU,MAAM;EAAO,KAAK;EAAW,QAAQ;EAAc,CAAC;AAC1H,wEAA2B,SAAS,MAAM,SAAS,SAAS;AAC5D,4BAAgB;AACd,MAAI,CAAC,KAAM;EACX,MAAM,aAAa,UAA+B;AAChD,OAAI,MAAM,QAAQ,SAAU,SAAQ,MAAM;;AAE5C,WAAS,iBAAiB,WAAW,UAAU;AAC/C,eAAa;AAAE,YAAS,oBAAoB,WAAW,UAAU;;IAChE,CAAC,KAAK,CAAC;CASV,MAAM,CAAC,UAAU,mCAA4C,KAAK;AAClE,4BAAgB;EACd,MAAMC,SAAO,QAAQ;AACrB,MAAIA,WAAS,KAAM;EACnB,MAAM,QAAQ,aAAaA,OAAK;AAChC,MAAI,UAAU,KAAM;EACpB,MAAM,aAAiC,MAAM,cAA2B,wBAAwB;AAChG,cAAY,MAAM,CAAC;EACnB,MAAM,WAAW,IAAI,uBAAuB;AAAE,eAAY,MAAM,CAAC;IAAG;AACpE,WAAS,QAAQ,OAAO;GAAE,WAAW;GAAM,SAAS;GAAM,CAAC;AAC3D,eAAa;AAAE,YAAS,YAAY;;IACnC,EAAE,CAAC;AAEN,4BAAgB;AACd,MAAI,gBAAgB,SAAU,SAAQ,MAAM;IAC3C,CAAC,YAAY,CAAC;AAIjB,4BAAgB;AACd,MAAI,gBAAgB,SAAU;EAC9B,MAAM,WAAW,eAAe,UAAa,OAAO,SAAS,WAAW,IAAI,aAAa,IACrF,aACA;EACJ,MAAM,QAAQ,kBAAkB;AAAE,gBAAY,SAAQ,OAAO,EAAE;KAAI,SAAS;AAC5E,eAAa;AAAE,iBAAc,MAAM;;IAClC,CAAC,aAAa,WAAW,CAAC;CAE7B,MAAM,OAAO,2CAAC;EAAK,KAAK;EAAS,OAAO,OAAO;EAAM;GAAc;CAGnE,MAAM,YAAY,gBAAgB,WAC9B,gBAAgB,UAAU,SAAS,SAAS,GAC5C,kBAAkB,UAAU,gBAAgB,SAAS;AACzD,KAAI,gBAAgB,YAAY,UAAU,WAAW,EAAG,QAAO;CAI/D,MAAM,YAAY,gBAAgB,WAC7B,YAAY,UAAU,IAAI,WAAW,WAAW,QAAQ,SACzD,gBAAgB;CACpB,MAAM,QAAQ,eAAe,UAAU,IAAK,WAAW,UAAU;CAKjE,MAAM,iBAAiB,QAAQ,gBAAgB,WAAW,aAAa,gBAAgB;CACvF,MAAM,cAAc,QAAQ,gBAAgB,WACvC,eAAe,UAAU,WAAW,QAAQ,SAC7C,gBAAgB;CACpB,MAAM,WAAW,iBAAiB,UAAU,eAAe;CAC3D,MAAM,QAAQ,UAAU,kBAAkB;CAE1C,MAAM,eAAqB;EACzB,MAAM,OAAO,CAAC;AACd,gBAAc,UAAU,IAAI,SAAS;AACrC,UAAQ,KAAK;AACb,MAAI,KAAM,CAAK,SAAS;;CAG1B,MAAM,OACJ,4CAAC;EAAK,KAAK;EAAS,OAAO,OAAO;;GAChC,2CAAC,qBAAO,wBAA8B;GACtC,4CAAC;IACC,MAAK;IACL,WAAU;IACV,OAAO;KAAE,GAAG,OAAO;KAAM,GAAI,SAAS,OAAO,OAAO,aAAa,EAAE;KAAG;IACtE,iBAAc;IACd,iBAAe;IACf,cAAY,GAAG,MAAM,KAAK;IACnB;IACP,oBAAoB;AAAE,cAAS,KAAK;;IACpC,oBAAoB;AAAE,cAAS,MAAM;;IACrC,SAAS;eAET,2CAAC,mBAAiB,EAClB,2CAAC;KAAK,OAAO,OAAO;eAAQ;MAAa;KAClC;GACR,oCACC,4CAAC;IACC,KAAK;IACL,MAAK;IACL,cAAY;IACZ,WAAU;IACV,OAAO;KAAE,GAAG,OAAO;KAAO,GAAI,OAAO;KAAgB;;KAErD,2CAAC;MAAI,OAAO,OAAO;gBACjB,4CAAC;OAAK,OAAO,OAAO;kBAClB,2CAAC,mBAAiB,EACjB;QACI;OACH;KACN,2CAAC;MAAI,OAAO,OAAO;MAAW;OAAc;KAC3C,SAAS,KAAK,GAAG,UAChB,4CAAC;MAAyB,OAAO,UAAU,IAAI,SAAY,OAAO;iBAChE,4CAAC;OAAI,OAAO,OAAO;kBACjB,4CAAC;QAAK,OAAO,OAAO;mBACjB,EAAE,MACF,EAAE,aAAa,WAAW,2CAAC;SAAK,OAAO,OAAO;mBAAa,UAAU,oBAAoB;UAAQ;SAC7F,EACN,EAAE,SAAS,WAAW,KAAK,2CAAC;QAAY,SAAS,EAAE,SAAS;QAAgB;SAAa;QACtF,EACL,EAAE,SAAS,KAAK,SAAS,iBACxB,4CAAC;OAAsB,OAAO,iBAAiB,IAAI,SAAY,OAAO;kBACnE,EAAE,SAAS,SAAS,KACnB,2CAAC;QAAI,OAAO,OAAO;kBACjB,2CAAC;SAAqB;SAAoB;UAAa;SACnD,EAER,2CAAC;QAEC,SAAS,QAAQ;QACjB,YAAY,QAAQ;QAAY,OAAO,QAAQ;QAC/C,OAAO,EAAE,aAAa,iBAAiB,cAAc;QACrD,UAAU,EAAE;QACD;UALN,GAAG,EAAE,SAAS,GAAG,eAAe,KAMrC;SAbM,QAAQ,IAcZ,CACN;QAxBU,EAAE,SAyBN,CACV;;KACE,EACN,SAAS,KACV;;GACI;AAGT,QACE,qFACG,MACA,aAAa,QAAQ,SAAS,0CAA2B,MAAM,SAAS,GAAG,QAC3E;;;;;;;AASP,SAAS,aAAa,MAAuC;CAC3D,IAAIC,OAA2B,KAAK;AACpC,MAAK,IAAI,QAAQ,GAAG,SAAS,QAAQ,QAAQ,GAAG,SAAS;AACvD,MAAI,KAAK,cAAc,wBAAwB,KAAK,KAAM,QAAO;AACjE,SAAO,KAAK;;AAEd,QAAO,KAAK;;;;;;;AAQd,SAAS,YAAY,EAAE,SAAS,aAAqE;CACnG,MAAM,QAAQ,CAAC,QAAQ,SAAS,QAAQ,SAAS,SAAY,SAAY,UAAU,aAAa,EAAE,MAAM,QAAQ,MAAM,CAAC,CAAC,CACrH,QAAQ,SAAyB,SAAS,UAAa,SAAS,GAAG;AACtE,QACE,4CAAC;EAAK,OAAO,OAAO;EAAc,OAAO,QAAQ;aAC9C,QAAQ,aAAa,2CAAC;GAAK,OAAO,OAAO;GAAa,cAAW;aAAU;IAAS,EACpF,MAAM,KAAK,MAAM;GACb;;;AAKX,SAAgB,eAAe,EAAE,SAAS,OAAO,UAAU,WAAW,YAAY,SAG/E;CACD,MAAM,EAAE,OAAO,WAAW,eAAe,SAAS,OAAO,SAAS;CAClE,MAAM,QAAQ,UACZ,2CAAC;EAAG,OAAO,OAAO;YACf,MAAM,KAAK,GAAG,MACb,2CAAC;GAAkB,OAAO,GAAG,iBAAiB,WAAW,EAAE,GAAG,UAAU,UAAa,EAAE,UAAU,QAAQ,MAAM,UAAU,oBAAoB,KAAK;GAAM,QAAQ;GAAG,GAAG;GAAuB;GAAmB;KAAhM,EAAyM,CACzN;GACC;AAEP,QAAO,qFACJ,KAAK,MAAM,EACX,OAAO,SAAS,KAAK,4CAAC;EAAQ,OAAO,OAAO;aAC3C,2CAAC;GAAQ,OAAO,OAAO;aAAc,UAAU,yBAAyB,EAAE,OAAO,OAAO,QAAQ,CAAC;IAAW,EAC3G,KAAK,OAAO;GACL,IACT;;;AAIL,SAAS,UAAU,EAAE,OAAO,QAAQ,GAAG,GAAG,YAAY,SAA6H;CACjL,MAAM,UAAU,mBAAmB,EAAE,YAAY;AACjD,QACE;EACE,2CAAC;GAAG,OAAO,OAAO;aAAK;IAAW;EAClC,4CAAC;GAAG,OAAO,OAAO;cACf,YAAY,SAAY,EAAE,oBAAoB,GAAG,GAAG,QAAQ,IAC5D,EAAE,aAAa,UAAa,OAAO,SAAS,EAAE,SAAS,IAAI,4CAAC;IAAK,OAAO,OAAO;eAAO,OAAI,YAAY,EAAE;KAAQ;IAC9G;EACL,2CAAC;GAAW,QAAQ;GAAM;GAAG,OAAO,OAAO;GAAiB;GAAmB;IAAS;KACvF;;;;;;AAQP,MAAMC,gBAA+B;CAAE,YAAY;CAAU,MAAM;CAAG,KAAK;CAAG;AAE9E,MAAMC,SAAwC;CAC5C,MAAM,EAAE,SAAS,QAAQ;CACzB,QAAQ;EAAE,UAAU;EAAG,UAAU;EAAQ,SAAS;EAAe;CAGjE,MAAM;EACJ,WAAW;EAAc,UAAU;EACnC,OAAO;EACP,MAAM;EAAW,UAAU;EAC3B,oBAAoB;EAAgB,YAAY;EAA6D,YAAY;EACzH,YAAY;EAAe,QAAQ;EAAQ,cAAc;EACzD,YAAY;EAAU,KAAK;EAAG,SAAS;EAAW,SAAS;EAAe,QAAQ;EACnF;CACD,YAAY;EACV,YAAY;EACZ,OAAO;EACR;CACD,OAAO;EAAE,cAAc;EAAY,UAAU;EAAG,UAAU;EAAU;CAKpE,OAAO;EACL,UAAU;EAAS,QAAQ;EAAM,WAAW;EAC5C,YAAY;EACZ,gBAAgB;EAChB,OAAO;EAAe,UAAU;EAA4B,UAAU;EACtE,WAAW;EAA6B,WAAW;EAAQ,oBAAoB;EAC/E,WAAW;EACX,OAAO;EAAoC,QAAQ;EACnD,QAAQ;EAAG,cAAc;EAA8B,SAAS;EAAI,UAAU;EAAI,YAAY;EAC/F;CACD,OAAO;EACL,OAAO;EAAkC,SAAS;EAClD,gBAAgB;EAAiB,KAAK;EAAI,cAAc;EAAG,YAAY;EACxE;CACD,YAAY;EAAE,YAAY;EAAU,KAAK;EAAG,UAAU;EAAG,SAAS;EAAe;CACjF,WAAW;EAAE,WAAW;EAA0C,cAAc;EAAI;CACpF,SAAS;EAAE,WAAW;EAAI,YAAY;EAAI,WAAW;EAA0C;CAC/F,aAAa;EACX,SAAS;EAAQ,gBAAgB;EAAiB,YAAY;EAAY,KAAK;EAAI,cAAc;EAClG;CACD,cAAc;EAAE,OAAO;EAAkC,YAAY;EAAK,SAAS;EAAe,YAAY;EAAU,KAAK;EAAG;CAChI,YAAY;EACV,UAAU;EAAI,YAAY;EAAQ,YAAY;EAAK,SAAS;EAAS,cAAc;EACnF,OAAO;EAAoC,YAAY;EACxD;CACD,cAAc;EACZ,OAAO;EAAmC,UAAU;EAAG,UAAU;EACjE,cAAc;EAAY,YAAY;EACvC;CAED,aAAa,EAAE,OAAO,qCAAqC;CAC3D,cAAc,EAAE,WAAW,GAAG;CAC9B,YAAY;EAAE,SAAS;EAAQ,cAAc;EAAG;CAChD,SAAS;EACP,OAAO;EAAmC,SAAS;EACnD,qBAAqB;EAA8B,KAAK;EAAY,QAAQ;EAC7E;CACD,aAAa,EAAE,WAAW,GAAG;CAC7B,aAAa;EAAE,QAAQ;EAAW,OAAO;EAAoC,cAAc;EAAG;CAC9F,IAAI;EAAE,UAAU;EAAG,QAAQ;EAAG,cAAc;EAAY;CACxD,IAAI;EACF,UAAU;EAAG,QAAQ;EAAG,OAAO;EAC/B,oBAAoB;EAAgB,WAAW;EAChD;CACD,OAAO,EAAE,OAAO,mCAAmC;CACnD,KAAK;EACH,YAAY;EAAU,QAAQ;EAAG,cAAc;EAAG,UAAU;EAC5D,YAAY;EAA8B,cAAc;EACzD;CACF;;;;;ACvzBD,SAAgB,uBAAuB,GAA+B;AACpE,cAAa,GAAG;;;;;;ACmDlB,MAAM,KAAK;;;;;;AAOX,MAAa,SAAS;CAAC;CAAS;CAAc;CAAS;;;;;;;AAQvD,SAAgB,MAAM,KAA0B;AAC9C,KAAI,aAAa,IAAI,OAAO,SAAS,IAAI;EAAE;EAAI;EAAI,CAAC,EAAE,uCAAuC;AAK7F,KAAI,aAAa;EACf,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,QAAM,aAAa,eAAe,oBAAoB;AACtD,QAAM,cAAc;AACpB,WAAS,KAAK,YAAY,MAAM;AAChC,eAAa,MAAM,QAAQ;IAC1B,mDAAmD;CAGtD,MAAM,aAAa,IAAI,IAAI,aAAa;CACxC,MAAM,IAAI,IAAI,OAAO,KAAK,GAAG;CAC7B,MAAM,kBAAgD;EAAE,KAAK,WAAW;EAAK;EAAG;AAChF,KAAI,MAAM,OAAO,0BAA0B,IAAI,MAAM,SAAS;EAC5D,MAAM;EACN,IAAI;EACJ,OAAO;EAEP,aAAa,EAAE,MAAM;EACrB,QAAQ;EACT,EAAE,qBAAqB,CAAC;CAKzB,MAAM,0BAAyD,EAAE,MAAM,kBAAkB,WAAW,IAAI,EAAE;AAC1G,KAAI,MAAM,OAAO,4BAA4B,IAAI,MAAM,SAAS;EAC9D,MAAM;EACN,KAAK;EACL,QAAQ;EACR,QAAQ;EACT,EAAE,sBAAsB,CAAC;CAI1B,MAAM,+BAA8D,EAAE,WAAW,kBAAkB,WAAW,IAAI,EAAE;AACpH,KAAI,MAAM,OAAO,4BAA4B,IAAI,MAAM,SAAS;EAC9D,MAAM;EACN,KAAK;EACL,QAAQ;EACR,QAAQ;EACT,EAAE,sBAAsB,CAAC;CAO1B,MAAM,eACJ,IAAI,IAAI,mBAAmB;AAC7B,KAAI,MAAM,OAAO,kCAAkC,IAAI,MAAM,SAAS;EACpE,MAAM;EACN,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,eAA4C;GACnD,WAAW,kBAAkB,YAAY,QAAQ,UAAU;GAC3D,UAAU,kBAAkB,YAAY,UAAU;GACnD;EACF,EAAE,YAAY,CAAC;AAOhB,KAAI,MAAM,OAAO,oCAAoC,IAAI,MAAM,SAAS;EACtE,MAAM;EACN,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,eAAuD;GAC9D,KAAK,WAAW;GAChB,cAAc,yBAAyB,QAAQ,UAAU;GAC1D;EACF,EAAE,uBAAuB,CAAC;AAO3B,KAAI,OAAO,CAAC,YAAY,GAAG,UAAyB;EAClD,MAAM,UAAU,MAAM,IAAI,YAAY;AACtC,QAAM,aAAa,QAAQ,SAAS;GAClC,MAAM;GAQN,aAAa,6BAA6B,EAAE,cAAc,CAAC;GAC3D,iBAAiB;GACjB,IAAI;IACF,MAAM;IACN,SAAS,OAAO,YAAY;KAC1B,MAAM,QAAQ,MAAM,kBAAkB,YAAY,QAAQ,QAAQ,UAAU,EAAE;AAC9E,SAAI,CAAC,MAAM,QAAS,OAAM,IAAI,MAAM,EAAE,yBAAyB,CAAC;AAChE,YAAQ,CACN;MAAE,IAAI;MAAY,OAAO,EAAE,gBAAgB;MAAE,QAAQ,EAAE,2BAA2B;MAAE,EACpF;MAAE,IAAI;MAAQ,OAAO,EAAE,YAAY;MAAE,QAAQ,EAAE,uBAAuB;MAAE,CACzE,CAAW,KAAI,YAAW;MAAE,GAAG;MAAQ,QAAQ,OAAO,OAAO,MAAM;MAAM,EAAE;;IAE9E,UAAU,OAAO,QAAQ,YAAY;AACnC,WAAM,kBAAkB,YAAY,QAAQ,UAAU,CAAC,OAAO,GAA0B;;IAE3F;GACF,CAAC,EAAE,wCAAwC;GAC5C"}
1
+ {"version":3,"file":"client.js","names":["result: RpcResult<unknown>","border","actions: CSSProperties","ProviderModelEditor","error","windows: Record<string, number>","actions","border","stack: CSSProperties","actions: CSSProperties","error","message","stack","actions","subscriptionCardStyles: Record<string, CSSProperties>","window","UNIT_KEYS: Record<\n CountdownPart['unit'],\n [SubscriptionsKey, SubscriptionsKey]\n>","SOURCES: readonly { id: Source; name: string; ref: string }[]","window","styles","message","styles","window","options: EffortOption[]","stack: CSSProperties","actions: CSSProperties","message","styles","styles","window","STATE_KEYS: Record<ResetCreditState, SubscriptionsKey>","cardStyles","message","styles","styles: Record<string, CSSProperties>","CLIENT_VERSION_SOURCES: Record<ClientVersionSource, SubscriptionsKey>","PROVIDERS: readonly { id: SubscriptionProvider; name: string }[]","fallbackTranslate","text: string","styles: Record<string, CSSProperties>","cardStyles","usageWindowLabel","window","message","response: StatusResponse","styles","styles: Record<string, CSSProperties>","styles","NoIcon: ComponentType<IconProps>","exports","SparkleIcon","primitives","PROMPT_MAX_LENGTH","fallbackTranslate","text: string","derivePrompt","parsed: unknown","prompt: string | undefined","resultText","parts: string[]","images: { attachment: ImageAttachmentRef }[]","styles: Record<string, CSSProperties>","labels: MessageImageLabels","styles","primitives","fallbackTranslate","text: string","parsed: unknown","prompt: string | undefined","parts: string[]","styles: Record<string, CSSProperties>","objectUrl: string | undefined","styles","current: ModelSelectionSnapshot['current']","unsubscribeStore: (() => void) | undefined","timer: ReturnType<typeof setInterval> | undefined","mode: 'seek' | 'store' | 'poll'","lastKey: string | undefined","directory:\n ReturnType<ModelDirectoriesLike['directoryFor']> | undefined","fallbackTranslate","TIERS: readonly SpeedTier[]","retry: ReturnType<typeof setInterval> | undefined","styles","styles: Record<string, CSSProperties>","primitives","PROVIDER_NAMES: Record<BadgeProvider, string>","row: AccountUsageDisplay","roster: UsageRosterEntry[]","parts","window","translate: Translate","seat","node: HTMLElement | null","MEASURE_STYLE: CSSProperties","styles: Record<string, CSSProperties>"],"sources":["../src/client/locales.ts","../src/client/reset-action.ts","../src/client/subscriptions-rpc.ts","../src/client/account-preferences.ts","../src/client/ProviderModelEditor.tsx","../src/client/provider-settings-styles.ts","../src/client/ProviderAccountManager.tsx","../src/client/subscription-card-styles.ts","../src/client/usage-badge-preferences.ts","../src/client/usage-pace.ts","../src/client/usage-color-preferences.ts","../src/client/UsageMeter.tsx","../src/client/ExternalUsageCards.tsx","../src/client/CursorCard.tsx","../src/client/ollama-draft.ts","../src/client/OllamaSettingsManager.tsx","../src/client/OllamaCard.tsx","../src/client/reset-credits-view.tsx","../src/client/UsageBadgeDisplaySetting.tsx","../src/client/SubscriptionsSection.tsx","../src/client/ImageGallery.tsx","../src/client/host-contract.ts","../src/client/host-icons.ts","../src/client/ImageGenerateToolview.tsx","../src/client/VideoGenerateToolview.tsx","../src/client/SpeedSelect.tsx","../src/client/SubscriptionUsageBadge.tsx","../src/client/fast-command.ts","../src/client/index.ts"],"sourcesContent":["/** Copy dictionaries for the Subscriptions settings section. */\n\n/** English strings (the key-set source of truth for this pair). */\nexport const en = {\n accountsManage: 'Manage',\n accountsTitle: 'Manage {provider} accounts',\n accountsHint:\n 'Choose which accounts serve pooled LLM requests. Pool exclusion applies only to LLM routing, not tools or session-wide isolation.',\n accountsLoading: 'Loading accounts…',\n accountsLoadFailed: 'Could not load account settings: {message}',\n accountsSaveFailed: 'Could not save changes: {message}',\n accountsEmpty:\n 'No connected accounts. Add an account on the provider card first.',\n accountsAlias: 'Alias (optional)',\n accountsPoolEnabled: 'Include in the LLM account pool',\n accountsIndependent: 'Show an independent entry in the model picker',\n accountsIndependentHint:\n 'Independent LLM routes use only this account, with no fallback to another account. This does not isolate tools or the whole session.',\n accountsModels: 'Pool model allowlist',\n accountsModelsAll: 'All models',\n accountsModelsCount: '{count} selected',\n accountsModelsHint:\n 'Applies only to pooled LLM routing, not independent entries. An empty selection allows no models. Turning off pool participation keeps this selection for later.',\n accountsModelsAutomatic: 'Allow all models, including future models',\n accountsNoModels: 'No models reported for this account.',\n accountsCatalogUnavailable:\n 'Model discovery is currently unavailable. Saved model selections are preserved.',\n modelsPartialSave:\n 'Some reasoning defaults were saved. Remaining changes are still in the draft; retry to finish.',\n modelsEdit: 'Edit model list',\n modelsHint:\n 'Configure model visibility, default reasoning effort, context and tools here; Save changes below submits them together with the account settings. Hidden models remain usable by existing sessions; tool changes apply to new sessions.',\n modelsAutomatic: 'Automatically show all models, including new models',\n modelsSelectAll: 'Select all',\n modelsSelectNone: 'Clear selection',\n modelsContext: 'Context (tokens)',\n modelsContextBounds: 'Default {default} · Maximum {max}',\n modelsContextHint:\n 'Leave blank to follow the provider. The requested window is capped by the account’s advertised maximum; account pools use the smallest member window. This controls local history and compaction, not the API’s capacity.',\n modelsContextInvalid: 'Enter a positive whole number of tokens for {model}.',\n modelsTools: 'Provider tools',\n modelsToolsHint:\n 'Changes apply only to sessions created after saving. Existing sessions keep their tools. Shared tools remain available if any supporting provider is enabled.',\n modelsImage: 'Image generation',\n modelsVideo: 'Video generation',\n modelsSearch: 'X search',\n modelsWebSearch: 'Web search',\n modelsSave: 'Save changes',\n modelsUnavailable: 'Currently unavailable',\n claudeCacheTtl: 'Prompt cache lifetime',\n claudeCacheTtlFollowConfig: 'Follow config',\n claudeCacheTtl5m: '5 minutes',\n claudeCacheTtl1h: '1 hour',\n claudeCacheTtlHint:\n 'Overrides the claudePromptCacheTtl config for this Claude route; Follow config uses the configured value. Saved changes apply from the next request. One hour keeps cached prefixes longer but writes them at a higher input price; compaction and session-title requests stay at five minutes.',\n nav: 'Subscriptions',\n intro:\n 'Log a subscription provider in or out. Login opens the provider’s authorization page in a new tab; headless setups can paste the callback URL or code instead.',\n unavailable: 'Connection unavailable; subscription status cannot be loaded.',\n checking: 'Checking…',\n loginInProgress: 'Login in progress…',\n notLoggedIn: 'Not logged in',\n loggedInCount: '{count} account(s) connected',\n clientVersion: 'CLI {version} · {source}',\n clientVersionNpm: 'latest on npm',\n clientVersionLocal: 'local CLI',\n clientVersionFallback: 'built-in',\n clientVersionConfig: 'configured',\n clientVersionHint:\n 'Requests present this CLI version, and newer models may require a recent one. It is the latest release on npm, or the local CLI / built-in version while npm is unreachable. Refreshing the model list checks again.',\n accountExpires: 'expires {date}',\n defaultBadge: 'Default',\n setDefault: 'Set as default',\n addAccount: 'Add account',\n addAccountOAuth: 'Browser authorization',\n addAccountKeychain: 'Import Claude Code',\n addAccountHint:\n 'Browser authorization signs in whichever account the browser currently uses — switch accounts there first (or use an incognito window with the manual code below) to add a different one.',\n login: 'Log in',\n cancel: 'Cancel',\n logout: 'Log out',\n logoutAccountConfirm: 'Log out {account} of {provider}?',\n manualSummary: 'Browser flow not working? Paste the callback URL or code',\n manualPlaceholder: 'Paste the callback URL or code',\n submit: 'Submit',\n loginMissingUrl: 'login answered without an authorizeUrl',\n deviceCodePrompt: 'Enter this code on the GitHub verification page:',\n deviceCodeCopy: 'Copy code',\n deviceCodeCopied: 'Copied',\n deviceCodeOpenPage: 'Open GitHub verification page',\n usageTitle: 'Usage',\n usageRefresh: 'Refresh',\n usageLoading: 'Loading usage…',\n usageEmpty: 'No usage windows reported.',\n usageUnsupported: 'This endpoint has no usage surface.',\n usageError: 'Usage lookup failed: {message}',\n usageSession: '5-hour window',\n usageWeekly: 'Weekly',\n usageMonthly: 'Monthly',\n usageWindow: 'Window',\n usageResets: 'resets {date}',\n usageMeterUsed: 'Used {used}% · Remaining {remaining}%',\n usageMeterPace: 'Time elapsed {elapsed}% (vertical marker)',\n usageMeterPaceAhead: '{points} points ahead of pace',\n usageMeterPaceBehind: '{points} points behind pace',\n usageMeterPaceEven: 'On pace',\n usageMeterInvalid: 'Quota unavailable',\n usageMeterStale: 'Reading is stale or unavailable; refresh to confirm',\n usageMeterNearLimit: 'Near exhaustion',\n usageMeterAhead: 'Usage ahead of pace',\n usageMeterNoWarning: 'No quota warning',\n usageMeterUnknownTime: 'Time progress unknown',\n usageMeterReset: 'Resets in {duration}',\n usageUnitDay: '{count} day',\n usageUnitDays: '{count} days',\n usageUnitHour: '{count} hour',\n usageUnitHours: '{count} hours',\n usageUnitMinute: '{count} minute',\n usageUnitMinutes: '{count} minutes',\n usageColorLabel: 'Usage coloring',\n usageColorStandard: 'Standard (default · 10-point lead)',\n usageColorRelaxed: 'Relaxed (15-point lead)',\n usageColorRemaining: 'Remaining quota only (no yellow)',\n usageColorPaceHint:\n 'Yellow when usage leads elapsed time by {allowance} points; red at 90% used takes priority. Saved in this browser; only colors change.',\n usageColorRemainingHint:\n 'Red at 90% used; no yellow pace warnings. Reliable time markers remain visible. Saved in this browser.',\n usagePlan: 'Plan: {plan}',\n resetCreditsTitle: 'Usage limit resets',\n resetCreditsAvailable: '{count} available',\n resetCreditsError: 'Usage limit resets unavailable: {message}',\n resetCreditsErrorFixed:\n 'Usage limit resets are unavailable. Refresh usage to try again.',\n resetCreditReadOnly: 'Read only. This page cannot spend a Claude reset.',\n resetCreditReadOnlyLabel: 'Read only',\n resetCreditAvailable: 'Available',\n resetCreditNotUsable: 'Not yet usable',\n resetCreditPaused: 'Paused',\n resetCreditExhausted: 'Exhausted',\n resetCreditExpired: 'Expired',\n resetCreditRemaining: '{left} of {total} left',\n resetCreditLeft: '{left} left',\n resetCreditRemainingUnknown: 'Remaining count unavailable',\n resetCreditCooldownUntil: 'Usable after {date}',\n resetUseButton: 'Use…',\n resetUseChecking: 'Checking…',\n resetUseGuard:\n 'You can use this reset when weekly usage reaches at least 80%.',\n resetUseRestart:\n 'Reset details are missing. Restart DSH, reload this page, then refresh usage.',\n resetUseRefresh:\n 'Refresh usage to verify current limits and reset availability.',\n resetUseReady:\n 'Use this reset — the earliest-expiring credit. Confirmation required.',\n resetUseConfirmTitle: 'Confirm full reset',\n resetUseWarning:\n 'This consumes one credit and resets weekly + 5-hour limits. This interface cannot undo it. Confirmation expires in 60 seconds.',\n resetUseAcknowledge: 'I understand that one credit will be consumed.',\n resetUseConfirm: 'Consume 1 reset',\n resetUseSuccess: 'Reset confirmed. Usage refreshed.',\n resetCreditFull: 'Full reset',\n resetCreditExpires: 'Expires {date}',\n resetCreditExpiryUnknown: 'Expiry date unavailable',\n externalUsageTitle: 'Built-in provider usage',\n externalUsageConnected: 'API key configured',\n externalUsageNotConfigured: 'Not configured',\n externalUsageApiKey: 'API key',\n externalUsageConfigure:\n 'No API key found at {ref}. Add one in Settings → Models.',\n externalUsageUnavailable: 'Usage status unavailable: {message}',\n cursorTitle: 'Cursor',\n cursorOpenLogin: 'Open Cursor sign-in',\n cursorWaiting: 'Waiting for Cursor sign-in…',\n cursorConnected: 'Connected',\n cursorManageTitle: 'Manage Cursor',\n cursorManageSignIn:\n 'Sign in to see the models available to this Cursor account.',\n cursorAccountsHint:\n 'Cursor uses one connected account. Choose which of its models appear in the model picker.',\n cursorManageHint:\n 'Choose model visibility here. Refresh fetches the current models from Cursor; Save changes updates the model picker.',\n cursorFilterModels: 'Filter models',\n cursorModelsLoading: 'Loading Cursor models…',\n cursorModelsError: 'Could not load Cursor models: {message}',\n cursorModelsCount: '{count} models available',\n cursorIncluded: 'Included usage',\n cursorModels: 'Cursor Models',\n cursorOtherModels: 'Other Models',\n cursorIncludedRequests: 'Included requests',\n modelDefaultsTitle: 'Default reasoning effort',\n modelDefaultsHint:\n 'The model picker preselects this level when you switch to the model; models without levels always follow the provider.',\n modelDefaultsFollowProvider: 'Follow provider',\n modelDefaultsNoLevels:\n '{count} model(s) advertise no reasoning levels and always follow the provider.',\n modelDefaultsLoading: 'Loading models…',\n modelDefaultsLoadFailed: 'Failed to load models: {message}',\n modelDefaultsRetry: 'Retry',\n modelDefaultsRefresh: 'Refresh model lists (all subscriptions)',\n modelDefaultsSaving: 'Saving…',\n modelDefaultsSaveFailedNamed: 'Save failed for {model}: {message}',\n modelDefaultsSummary: '{total} model(s) · {configured} overridden',\n modelDefaultsSummaryNone: '{total} model(s) · following the provider',\n modelDefaultsSummaryEmpty: 'No model advertises reasoning levels',\n modelDefaultsFilterPlaceholder: 'Filter models',\n modelDefaultsFilterEmpty: 'No model matches “{query}”.',\n generating: 'Generating image…',\n image: 'image',\n viewImage: 'View image',\n viewImageNamed: 'View {name}',\n imageLoading: 'Loading…',\n imageLoadFailed: 'Retry',\n imagePreview: 'Image preview',\n imageClose: 'Close',\n generatingVideo: 'Generating video…',\n videoLoading: 'Loading video…',\n videoLoadFailed: 'Video failed to load: {message}',\n usageBadgeTitle: 'Provider usage',\n usageBadgeDisplay: 'Status-bar quota display',\n usageBadgeDisplayRecent: 'Current / most recent provider with usage',\n usageBadgeDisplayAlways:\n 'Always show one provider, rotating through the rest',\n usageBadgeDisplayHidden: 'Hidden',\n usageBadgeDisplayHint:\n 'Saved automatically in this browser. One provider is shown at a time. Models without a quota source keep the most recent provider selected in this view, or show nothing. Always show instead rotates through the providers with usage every 10 seconds while the current model has no quota source. Hiding does not affect usage details here.',\n usageBadgeDisplaySaveFailed:\n 'Could not save the display preference. Check browser storage permissions.',\n usageBadgeCurrent: 'current',\n usageBadgeModelCount: '{count} model quotas',\n usageBadgeModelUnavailable: 'Current model quota unavailable',\n usageBadgeMoreWindows: 'More quota windows ({count})',\n speed: 'Speed',\n speedStandard: 'Standard',\n speedStandardDescription: 'Default speed',\n speedFast: 'Fast',\n speedFastDescription: '1.5x speed, more usage',\n commandFast: 'Switch the Codex speed tier (Standard/Fast)',\n commandFastUnavailable:\n 'The current model has no fast tier; /fast only works on Codex models whose catalog advertises one',\n ollamaTitle: 'Ollama Cloud',\n ollamaStatus: '{count} model(s) in the picker',\n ollamaStatusNone: 'No models configured',\n ollamaWebOn: 'Web search/fetch enabled',\n ollamaWebOff: 'Web search/fetch off',\n ollamaManageTitle: 'Manage Ollama Cloud',\n ollamaManageHint:\n 'Fetch the Cloud list, tick the models this route serves, then Save. The picker ' +\n 'shows the ticked models in order; the API key itself stays in DSH credentials.',\n ollamaFetch: 'Fetch cloud models',\n ollamaFetching: 'Fetching…',\n ollamaKeyPlaceholder: 'One-time API key (optional)',\n ollamaKeyHint:\n 'A key typed here is used for this fetch only and is never saved. Leave it ' +\n 'blank to use the stored credential.',\n ollamaFetchFailed: 'Could not fetch cloud models: {message}',\n ollamaCandidatesCount: '{count} returned',\n ollamaCandidatesEmpty: 'No cloud models returned.',\n ollamaModelsEmpty:\n 'No models configured. Fetch the cloud list and tick the ones to keep.',\n ollamaModelsLoadFailed: 'Could not load Ollama settings: {message}',\n ollamaModelsSaveFailed: 'Could not save Ollama settings: {message}',\n ollamaConfigureHint:\n 'No API key found at {ref}. Add it to the credentials file ' +\n '(~/.dsh/.credentials.yaml).',\n ollamaDisplayName: 'Display name',\n ollamaRowDetails: 'Details',\n ollamaEffortsUnknown:\n 'This model reasons; its level set will come from live discovery.',\n ollamaMoveUp: 'Move up',\n ollamaMoveDown: 'Move down',\n ollamaBaseURL: 'Base URL',\n ollamaApiKeyRef: 'API key reference',\n ollamaConnectionHint:\n \"The base URL receives this route's requests and the credential lookup; the \" +\n 'reference names the DSH credential, not the key itself. Requests send ' +\n 'the resolved key to that address, so point it only at a host you trust.',\n ollamaWebHint:\n 'Enables the Ollama Cloud web search and fetch providers. The host still ' +\n 'has to select them before the web tools use them.',\n ollamaCatalogOverride:\n \"A profile pins this route's model list; the picker ignores store models \" +\n 'until that override is removed.',\n ollamaResetDefaults: 'Restore deployment defaults',\n ollamaResetConfirm:\n 'Clear every saved Ollama override? The profile values and built-in ' +\n 'defaults apply again.',\n ollamaCapVision: 'vision',\n ollamaCapThinking: 'thinking',\n ollamaContext: 'context {tokens}',\n} satisfies Record<string, string>\n\n/** zh strings, one per {@link en} key. */\nexport const zh = {\n accountsManage: '管理',\n accountsTitle: '管理 {provider} 账号',\n accountsHint:\n '选择参与账号池 LLM 请求的账号。退出账号池仅影响 LLM 路由,不影响工具,也不代表整个会话隔离。',\n accountsLoading: '加载账号中…',\n accountsLoadFailed: '账号设置加载失败:{message}',\n accountsSaveFailed: '保存失败:{message}',\n accountsEmpty: '暂无已连接账号,请先在服务商卡片中添加账号。',\n accountsAlias: '别名(可选)',\n accountsPoolEnabled: '参与 LLM 账号池',\n accountsIndependent: '在模型选择器中显示独立入口',\n accountsIndependentHint:\n '独立 LLM 路由仅使用此账号,失败时不会回退到其他账号。这不代表工具或整个会话的隔离。',\n accountsModels: '账号池模型白名单',\n accountsModelsAll: '全部模型',\n accountsModelsCount: '已选 {count} 个',\n accountsModelsHint:\n '仅影响账号池 LLM 路由,不限制独立入口。清空选择表示不允许任何模型。关闭参与账号池后仍保留此选择。',\n accountsModelsAutomatic: '允许全部模型(包含以后新增的模型)',\n accountsNoModels: '此账号暂未返回模型。',\n accountsCatalogUnavailable:\n '暂时无法获取模型目录,已保存的模型选择会被保留。',\n modelsPartialSave:\n '部分推理档已保存,其余更改仍保留在草稿中,请重试完成保存。',\n modelsEdit: '编辑模型列表',\n modelsHint:\n '在此配置模型显示、默认推理档、上下文与工具,底部的「保存更改」会连同账号设置一起提交。隐藏模型不影响已有会话;工具开关对新建会话生效。',\n modelsAutomatic: '自动显示全部模型(包含以后新增的模型)',\n modelsSelectAll: '全选',\n modelsSelectNone: '清空选择',\n modelsContext: '上下文(token)',\n modelsContextBounds: '默认 {default} · 最大 {max}',\n modelsContextHint:\n '留空跟随服务商。配置值按账号返回的最大窗口限制;账号池取各成员的最小窗口。此设置控制本地历史保留和压缩时机,不会扩大 API 本身的容量。',\n modelsContextInvalid: '请为 {model} 输入正整数 token 数。',\n modelsTools: 'Provider 工具',\n modelsToolsHint:\n '仅对保存后新建的会话生效,已有会话保留原工具。任一支持的服务商启用共享工具时,该工具仍会显示。',\n modelsImage: '图片生成',\n modelsVideo: '视频生成',\n modelsSearch: 'X 搜索',\n modelsWebSearch: '网页搜索',\n modelsSave: '保存更改',\n modelsUnavailable: '当前不可用',\n claudeCacheTtl: '提示词缓存时长',\n claudeCacheTtlFollowConfig: '跟随配置',\n claudeCacheTtl5m: '5 分钟',\n claudeCacheTtl1h: '1 小时',\n claudeCacheTtlHint:\n '覆盖此 Claude 路由的 claudePromptCacheTtl 配置;选择「跟随配置」时使用配置值。保存后自下一次请求生效。1 小时可更久保留缓存前缀,但写入按更高的输入价格计费;压缩与会话标题请求仍为 5 分钟。',\n nav: '订阅',\n intro:\n '在此登录或退出订阅服务商。点击登录会在新标签页打开服务商的授权页面;无浏览器环境可改为粘贴回调 URL 或授权码。',\n unavailable: '连接不可用,无法加载订阅状态。',\n checking: '查询中…',\n loginInProgress: '登录中…',\n notLoggedIn: '未登录',\n loggedInCount: '已连接 {count} 个账号',\n clientVersion: 'CLI {version} · {source}',\n clientVersionNpm: 'npm 最新',\n clientVersionLocal: '本机 CLI',\n clientVersionFallback: '内置版本',\n clientVersionConfig: '手动配置',\n clientVersionHint:\n '请求以这个 CLI 版本号发出,新模型可能要求较新的版本。默认使用 npm 上的最新版本;npm 无法访问时使用本机 CLI 或内置版本。刷新模型列表会重新检查。',\n accountExpires: '过期时间 {date}',\n defaultBadge: '默认',\n setDefault: '设为默认',\n addAccount: '添加账号',\n addAccountOAuth: '浏览器授权',\n addAccountKeychain: '导入 Claude Code',\n addAccountHint:\n '浏览器授权以浏览器当前登录的账号为准;要添加不同账号,请先在浏览器里切换账号,或用无痕窗口走下方手动授权码。',\n login: '登录',\n cancel: '取消',\n logout: '退出登录',\n logoutAccountConfirm: '确定退出 {provider} 的账号 {account} 吗?',\n manualSummary: '浏览器流程无法完成?粘贴回调 URL 或授权码',\n manualPlaceholder: '粘贴回调 URL 或授权码',\n submit: '提交',\n loginMissingUrl: 'login 响应缺少 authorizeUrl',\n deviceCodePrompt: '在 GitHub 验证页面输入此验证码:',\n deviceCodeCopy: '复制验证码',\n deviceCodeCopied: '已复制',\n deviceCodeOpenPage: '打开 GitHub 验证页面',\n usageTitle: '用量',\n usageRefresh: '刷新',\n usageLoading: '用量加载中…',\n usageEmpty: '服务商未返回任何用量窗口。',\n usageUnsupported: '该端点不提供用量查询。',\n usageError: '用量查询失败:{message}',\n usageSession: '5 小时窗口',\n usageWeekly: '每周',\n usageMonthly: '每月',\n usageWindow: '窗口',\n usageResets: '{date} 重置',\n usageMeterUsed: '已用 {used}% · 剩余 {remaining}%',\n usageMeterPace: '时间已过 {elapsed}%(竖线标记)',\n usageMeterPaceAhead: '领先时间进度 {points} 个百分点',\n usageMeterPaceBehind: '落后时间进度 {points} 个百分点',\n usageMeterPaceEven: '与时间进度一致',\n usageMeterInvalid: '额度数据不可用',\n usageMeterStale: '读数已陈旧或不可用,请刷新确认',\n usageMeterNearLimit: '额度接近耗尽',\n usageMeterAhead: '用量领先时间进度',\n usageMeterNoWarning: '未触发额度警告',\n usageMeterUnknownTime: '时间进度未知',\n usageMeterReset: '{duration}后重置',\n usageUnitDay: '{count} 天',\n usageUnitDays: '{count} 天',\n usageUnitHour: '{count} 小时',\n usageUnitHours: '{count} 小时',\n usageUnitMinute: '{count} 分钟',\n usageUnitMinutes: '{count} 分钟',\n usageColorLabel: '用量配色',\n usageColorStandard: '标准(默认 · 领先 10 个百分点)',\n usageColorRelaxed: '宽松(领先 15 个百分点)',\n usageColorRemaining: '仅剩余额度(不显示黄色)',\n usageColorPaceHint:\n '用量领先时间进度 {allowance} 个百分点时变黄;已用达到 90% 时优先变红。自动保存到当前浏览器,仅改变配色。',\n usageColorRemainingHint:\n '已用达到 90% 时变红,不显示黄色节奏警告。可靠的时间标记仍保留,自动保存到当前浏览器。',\n usagePlan: '计划:{plan}',\n resetCreditsTitle: '用量限制重置',\n resetCreditsAvailable: '可用 {count} 次',\n resetCreditsError: '用量限制重置查询失败:{message}',\n resetCreditsErrorFixed: '用量限制重置暂不可用,请刷新用量后重试。',\n resetCreditReadOnly: '只读。此页面不能消耗 Claude 的重置额度。',\n resetCreditReadOnlyLabel: '只读',\n resetCreditAvailable: '可用',\n resetCreditNotUsable: '暂不可用',\n resetCreditPaused: '已暂停',\n resetCreditExhausted: '已用尽',\n resetCreditExpired: '已过期',\n resetCreditRemaining: '剩余 {left} / {total}',\n resetCreditLeft: '剩余 {left}',\n resetCreditRemainingUnknown: '剩余次数不可用',\n resetCreditCooldownUntil: '{date} 后可用',\n resetUseButton: '使用…',\n resetUseChecking: '正在检查…',\n resetUseGuard: '每周用量达到 80% 后才可使用此重置。',\n resetUseRestart: '缺少重置详情。请重启 DSH、重新加载页面并刷新用量。',\n resetUseRefresh: '请刷新用量以验证当前限制和重置可用性。',\n resetUseReady: '使用此最早到期的重置额度,操作前需要确认。',\n resetUseConfirmTitle: '确认完整重置',\n resetUseWarning:\n '将消耗一次额度并重置每周和 5 小时限制,无法撤销。确认将在 60 秒后过期。',\n resetUseAcknowledge: '我理解将消耗一次额度。',\n resetUseConfirm: '消耗一次重置',\n resetUseSuccess: '重置已确认,用量已刷新。',\n resetCreditFull: '完整重置',\n resetCreditExpires: '{date} 到期',\n resetCreditExpiryUnknown: '到期时间不可用',\n externalUsageTitle: '内置供应商用量',\n externalUsageConnected: '已配置 API 密钥',\n externalUsageNotConfigured: '未配置',\n externalUsageApiKey: 'API 密钥',\n externalUsageConfigure:\n '未在 {ref} 找到 API 密钥。请在「设置 → 模型」中添加。',\n externalUsageUnavailable: '无法获取用量状态:{message}',\n cursorTitle: 'Cursor',\n cursorOpenLogin: '打开 Cursor 登录页面',\n cursorWaiting: '等待 Cursor 登录…',\n cursorConnected: '已连接',\n cursorManageTitle: '管理 Cursor',\n cursorManageSignIn: '登录后可查看此 Cursor 账号可用的模型。',\n cursorAccountsHint:\n 'Cursor 使用一个已连接账号。可在此选择模型选择器中显示的模型。',\n cursorManageHint:\n '在此选择模型是否显示。刷新可从 Cursor 获取当前模型;保存更改后更新模型选择器。',\n cursorFilterModels: '筛选模型',\n cursorModelsLoading: '正在加载 Cursor 模型…',\n cursorModelsError: '无法加载 Cursor 模型:{message}',\n cursorModelsCount: '可用模型:{count} 个',\n cursorIncluded: '套餐内用量',\n cursorModels: 'Cursor 模型',\n cursorOtherModels: '其他模型',\n cursorIncludedRequests: '套餐内请求',\n modelDefaultsTitle: '默认推理档',\n modelDefaultsHint:\n '切换到该模型时,模型选择器会预选此档位;没有推理档的模型始终跟随服务商默认。',\n modelDefaultsFollowProvider: '跟随服务商',\n modelDefaultsNoLevels: '{count} 个模型未声明推理档,始终跟随服务商默认。',\n modelDefaultsLoading: '加载模型中…',\n modelDefaultsLoadFailed: '模型加载失败:{message}',\n modelDefaultsRetry: '重试',\n modelDefaultsRefresh: '刷新模型列表(全部订阅)',\n modelDefaultsSaving: '保存中…',\n modelDefaultsSaveFailedNamed: '{model} 保存失败:{message}',\n modelDefaultsSummary: '{total} 个模型 · {configured} 个已覆盖',\n modelDefaultsSummaryNone: '{total} 个模型 · 全部跟随服务商',\n modelDefaultsSummaryEmpty: '没有模型声明推理档',\n modelDefaultsFilterPlaceholder: '筛选模型',\n modelDefaultsFilterEmpty: '没有匹配「{query}」的模型。',\n generating: '正在生成图片…',\n image: '图片',\n viewImage: '查看图片',\n viewImageNamed: '查看 {name}',\n imageLoading: '加载中…',\n imageLoadFailed: '重试',\n imagePreview: '图片预览',\n imageClose: '关闭',\n generatingVideo: '正在生成视频…',\n videoLoading: '视频加载中…',\n videoLoadFailed: '视频加载失败:{message}',\n usageBadgeTitle: '服务商用量',\n usageBadgeDisplay: '状态栏额度显示',\n usageBadgeDisplayRecent: '仅显示当前/最近使用的用量服务商',\n usageBadgeDisplayAlways: '始终显示一家,其余服务商轮播',\n usageBadgeDisplayHidden: '不显示',\n usageBadgeDisplayHint:\n '自动保存到当前浏览器。状态栏一次显示一家服务商;没有额度来源的模型沿用本视图最近选择的服务商,没有记录则隐藏。选择“始终显示”时,当前模型没有额度来源,就每 10 秒轮播一家有额度的服务商。关闭不影响本页的额度详情。',\n usageBadgeDisplaySaveFailed: '显示设置保存失败,请检查浏览器存储权限。',\n usageBadgeCurrent: '当前',\n usageBadgeModelCount: '{count} 个模型配额',\n usageBadgeModelUnavailable: '当前模型暂无配额数据',\n usageBadgeMoreWindows: '更多配额窗口({count})',\n speed: '速度',\n speedStandard: '标准',\n speedStandardDescription: '默认速度',\n speedFast: '快速',\n speedFastDescription: '约 1.5 倍速度,消耗更多用量',\n commandFast: '切换 Codex 速度档(标准/快速)',\n commandFastUnavailable:\n '当前模型不支持快速档;/fast 仅对目录声明了 fast tier 的 Codex 模型可用',\n ollamaTitle: 'Ollama Cloud',\n ollamaStatus: '选择器中 {count} 个模型',\n ollamaStatusNone: '尚未配置模型',\n ollamaWebOn: '网页搜索/抓取已启用',\n ollamaWebOff: '网页搜索/抓取已关闭',\n ollamaManageTitle: '管理 Ollama Cloud',\n ollamaManageHint:\n '选择此路由提供的云端模型后保存。模型选择器按此顺序显示这份列表;API 密钥本身仍保存在 DSH 凭据中。',\n ollamaFetch: '拉取云端模型',\n ollamaFetching: '拉取中…',\n ollamaKeyPlaceholder: '一次性 API 密钥(可选)',\n ollamaKeyHint: '在此输入的密钥仅用于本次拉取,不会保存。留空则使用已存凭据。',\n ollamaFetchFailed: '拉取云端模型失败:{message}',\n ollamaCandidatesCount: '返回 {count} 个',\n ollamaCandidatesEmpty: '未返回任何云端模型。',\n ollamaModelsEmpty: '尚未配置模型。请拉取云端列表并勾选需要保留的模型。',\n ollamaModelsLoadFailed: 'Ollama 设置加载失败:{message}',\n ollamaModelsSaveFailed: 'Ollama 设置保存失败:{message}',\n ollamaConfigureHint:\n '未在 {ref} 找到 API 密钥。请在凭据文件(~/.dsh/.credentials.yaml)中添加。',\n ollamaDisplayName: '显示名',\n ollamaRowDetails: '详情',\n ollamaEffortsUnknown: '该模型支持思考,推理档位将由实时发现补充。',\n ollamaMoveUp: '上移',\n ollamaMoveDown: '下移',\n ollamaBaseURL: '基础 URL',\n ollamaApiKeyRef: 'API 密钥引用',\n ollamaConnectionHint:\n '基础 URL 用于此路由的请求与凭据查询;引用是 DSH 凭据的名称,不是密钥本身。' +\n '请求会把解析出的密钥发往该地址,请只填写可信主机。',\n ollamaWebHint:\n '启用 Ollama Cloud 的网页搜索与抓取能力。宿主仍需选择它们,网页工具才会使用。',\n ollamaCatalogOverride:\n '配置档案固定了此路由的模型列表;在移除该覆盖前,选择器会忽略存储中的模型。',\n ollamaResetDefaults: '恢复部署默认值',\n ollamaResetConfirm:\n '清除全部已保存的 Ollama 覆盖项?将重新使用配置档案值与内置默认值。',\n ollamaCapVision: '视觉',\n ollamaCapThinking: '思考',\n ollamaContext: '上下文 {tokens}',\n} satisfies Record<keyof typeof en, string>\n\n/** The Subscriptions namespace key union (en is the key-set source of truth). */\nexport type SubscriptionsKey = keyof typeof en\n","/** Explain client-side gating; the server independently revalidates before spending. */\nexport function resetActionBlock(\n usage: {\n windows?: {\n kind: string\n scope?: string\n usedPercent: number\n resetsAt?: number\n }[]\n resetCredits?: { id?: string; expiresAt?: number }[]\n resetCreditsError?: string\n },\n now = Date.now(),\n): 'resetUseGuard' | 'resetUseRefresh' | 'resetUseRestart' | undefined {\n const weekly = usage.windows?.find(\n (w) => w.kind === 'weekly' && w.scope === undefined,\n )\n if (!weekly || !Number.isFinite(weekly.usedPercent)) return 'resetUseRefresh'\n if (weekly.usedPercent < 80) return 'resetUseGuard'\n if (\n weekly.resetsAt === undefined ||\n weekly.resetsAt <= now ||\n usage.resetCreditsError\n )\n return 'resetUseRefresh'\n if (!usage.resetCredits?.some((c) => c.id)) return 'resetUseRestart'\n if (\n !usage.resetCredits.some(\n (c) => c.id && (c.expiresAt === undefined || c.expiresAt > now),\n )\n )\n return 'resetUseRefresh'\n return undefined\n}\n","import type {\n ConnectionHandle,\n RpcResult,\n} from '@deepseek-ai/dsh-api-remotes/client'\n\n/**\n * The node half mounts every endpoint as an exact POST route on the shared\n * `/api` channel (`/api/subscriptions-auth.<endpoint>`), so the browser\n * reaches it through the `/api` channel with a prefixed endpoint name.\n * A dedicated channel is no longer used: since dsh 0.1.5 `rpc.handle`\n * cannot register one from a plugin (see `src/auth/rpc.ts`).\n */\nconst SUBSCRIPTIONS_AUTH_CHANNEL = '/api'\nconst SUBSCRIPTIONS_AUTH_PREFIX = 'subscriptions-auth.'\n\n/** Business error returned by a `subscriptions-auth` endpoint (error branch message). */\nexport class SubscriptionsAuthError extends Error {}\n\n/**\n * Call one `subscriptions-auth` endpoint and unwrap the business result.\n * Shared by the settings section, the composer Speed toggle, the usage\n * badge, and the image/video toolviews.\n * @param rpc - Connection RPC caller.\n * @param endpoint - endpoint name (`status`, `usage`, `image`, ...).\n * @param payload - endpoint-owned request payload.\n * @returns the success value, cast by the caller to the endpoint's shape.\n */\nexport async function callSubscriptionsAuth<T>(\n rpc: ConnectionHandle['rpc'],\n endpoint: string,\n payload: unknown,\n): Promise<T> {\n let result: RpcResult<unknown>\n try {\n result = await rpc.call(\n SUBSCRIPTIONS_AUTH_CHANNEL,\n `${SUBSCRIPTIONS_AUTH_PREFIX}${endpoint}`,\n payload,\n )\n } catch (error) {\n // The transport rejected rather than answering; surface the same way.\n throw new SubscriptionsAuthError(\n error instanceof Error ? error.message : String(error),\n )\n }\n if (!result.ok) throw new SubscriptionsAuthError(result.error.message)\n return result.value as T\n}\n","import type {\n AccountPreferences,\n ProviderPreferences,\n} from '../provider-settings.js'\nimport type { PromptCacheTtl } from '../translate/anthropic.js'\n\nexport interface AccountCatalogRow {\n key: string\n label: string\n models: { id: string; name: string }[]\n unavailable?: boolean\n}\n\n/** Missing allowlist follows discovery; explicit [] must remain empty. */\nexport function accountPoolSelection(\n account: AccountPreferences,\n models: readonly { id: string }[],\n): Set<string> {\n return new Set(account.poolModels ?? models.map((model) => model.id))\n}\n\n/** Retain unavailable saved IDs so a temporary catalog failure cannot erase them. */\nexport function accountModelRows(\n account: AccountCatalogRow,\n preferences: AccountPreferences,\n) {\n const known = new Set(account.models.map((model) => model.id))\n return [\n ...account.models.map((model) => ({ ...model, unavailable: false })),\n ...(preferences.poolModels ?? [])\n .filter((id) => !known.has(id))\n .map((id) => ({ id, name: id, unavailable: true })),\n ]\n}\n\n/** The model editor owns everything except the separately managed accounts. */\nexport function mergeLatestAccounts(\n draft: ProviderPreferences,\n latest: ProviderPreferences,\n): ProviderPreferences {\n const { accounts: _stale, ...settings } = draft\n return {\n ...settings,\n ...(latest.accounts === undefined ? {} : { accounts: latest.accounts }),\n }\n}\n\n/**\n * The account manager owns the Claude prompt-cache TTL picker. The model\n * editor's draft carries the TTL it loaded, so the dialog always replaces it\n * with the picker's choice when touched, or the freshly re-read value\n * otherwise.\n */\nexport function mergePromptCacheTtl(\n settings: ProviderPreferences,\n promptCacheTtl: PromptCacheTtl | undefined,\n): ProviderPreferences {\n const { promptCacheTtl: _stale, ...rest } = settings\n return promptCacheTtl === undefined ? rest : { ...rest, promptCacheTtl }\n}\n\n/** Only touched accounts replace their latest preferences; other settings survive. */\nexport function mergeAccountChanges(\n latest: ProviderPreferences,\n changes: Record<string, AccountPreferences>,\n): ProviderPreferences {\n return { ...latest, accounts: { ...latest.accounts, ...changes } }\n}\n","import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {\n ProviderPreferences,\n SubscriptionTool,\n} from '../provider-settings.js'\nimport type { SubscriptionProvider } from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport type { SubscriptionsKey } from './locales.js'\n\ninterface ModelRow {\n id: string\n name: string\n contextWindow?: number\n defaultContextWindow?: number\n efforts?: { id: string; name: string }[]\n configured?: string\n maxContextWindow?: number\n}\ninterface Catalog {\n provider: SubscriptionProvider | 'cursor-subscription'\n settings: ProviderPreferences\n models: ModelRow[]\n tools: SubscriptionTool[]\n}\ninterface Props {\n provider: SubscriptionProvider | 'cursor-subscription'\n rpc: ConnectionHandle['rpc']\n t: (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n /** Freeze the editor while the owning dialog submits. */\n disabled?: boolean\n /** Reports whether the draft differs from the loaded catalog. */\n onDirtyChange?: (dirty: boolean) => void\n}\n\n/** The editor's unsaved edits, collected by the owning dialog's single Save. */\nexport interface ModelDraft {\n /** Provider settings minus `accounts`; absent when the draft has no edits. */\n settings?: ProviderPreferences\n /** Reasoning-effort overrides that differ from the catalog; '' clears one. */\n efforts: { model: string; effort: string }[]\n}\nexport interface ProviderModelEditorHandle {\n /**\n * Validate and collect the draft without mutating it, so a failed submit\n * keeps every edit. Returns undefined when a value is invalid; the editor\n * shows the reason itself.\n */\n collect(): ModelDraft | undefined\n}\n\n/** Providers whose runtime honours a local context-window override. */\nconst supportsContext = (provider: string): boolean =>\n provider === 'codex' || provider === 'claude'\nconst border = '0.5px solid var(--dsw-alias-border-l2, #ddd)'\nconst actions: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n alignItems: 'center',\n}\n\n/**\n * Embedded section of the account manager dialog. It owns the model draft\n * (visibility, effort, context, tools) but not its submission: the dialog\n * collects the draft through the handle and saves it with the account edits\n * in one go, so there is a single Save/Cancel pair.\n */\nexport const ProviderModelEditor = forwardRef<ProviderModelEditorHandle, Props>(\n function ProviderModelEditor(\n { provider, rpc, t, disabled = false, onDirtyChange },\n ref,\n ) {\n const [catalog, setCatalog] = useState<Catalog>()\n const [draft, setDraft] = useState<ProviderPreferences>({})\n const [contexts, setContexts] = useState<Record<string, string>>({})\n const [efforts, setEfforts] = useState<Record<string, string>>({})\n const [query, setQuery] = useState('')\n const [busy, setBusy] = useState(false)\n const [dirty, setDirty] = useState(false)\n const [error, setError] = useState('')\n const generation = useRef(0)\n useEffect(\n () => () => {\n generation.current++\n },\n [],\n )\n // Notify only when dirty changes. The parent passes a fresh callback each render.\n /* eslint-disable react-hooks/exhaustive-deps -- onDirtyChange is not a trigger */\n useEffect(() => {\n onDirtyChange?.(dirty)\n }, [dirty])\n /* eslint-enable react-hooks/exhaustive-deps */\n\n function reset(data: Catalog) {\n setCatalog(data)\n setDraft(data.settings)\n setEfforts(\n Object.fromEntries(\n data.models.map((model) => [model.id, model.configured ?? '']),\n ),\n )\n setContexts(\n Object.fromEntries(\n Object.entries(data.settings.contextWindows ?? {}).map(\n ([id, value]) => [id, String(value)],\n ),\n ),\n )\n setDirty(false)\n }\n async function load(force = false) {\n const request = ++generation.current\n setBusy(true)\n setError('')\n try {\n const data = await callSubscriptionsAuth<Catalog>(\n rpc,\n provider === 'cursor-subscription'\n ? 'cursorSettings'\n : 'providerSettings',\n { provider, force },\n )\n if (generation.current === request) reset(data)\n } catch (error) {\n if (generation.current === request)\n setError(String(error instanceof Error ? error.message : error))\n } finally {\n if (generation.current === request) setBusy(false)\n }\n }\n function edit(next: ProviderPreferences) {\n setDraft(next)\n setDirty(true)\n }\n // `load` is a new function each render; provider and rpc are the triggers.\n /* eslint-disable react-hooks/exhaustive-deps -- avoid refetching every render */\n useEffect(() => {\n void load()\n }, [provider, rpc])\n /* eslint-enable react-hooks/exhaustive-deps */\n\n useImperativeHandle(\n ref,\n () => ({\n collect() {\n if (!catalog || !dirty) return { efforts: [] }\n const windows: Record<string, number> = Object.create(null) as Record<\n string,\n number\n >\n for (const [model, text] of Object.entries(contexts)) {\n if (!text.trim()) continue\n const value = Number(text)\n if (\n !/^\\d+$/.test(text.trim()) ||\n !Number.isSafeInteger(value) ||\n value <= 0\n ) {\n setError(t('modelsContextInvalid', { model }))\n return undefined\n }\n windows[model] = value\n }\n setError('')\n const { accounts: _accounts, ...settings } = {\n ...draft,\n ...(supportsContext(provider) ? { contextWindows: windows } : {}),\n }\n return {\n settings,\n efforts: catalog.models.flatMap((model) => {\n const effort = efforts[model.id] ?? ''\n return effort === (model.configured ?? '') ||\n !model.efforts?.length\n ? []\n : [{ model: model.id, effort }]\n }),\n }\n },\n }),\n [catalog, dirty, draft, contexts, efforts, provider, t],\n )\n\n const allModels = catalog?.models ?? []\n const known = new Set(allModels.map((model) => model.id))\n const missing = (draft.visibleModels ?? [])\n .filter((id) => !known.has(id))\n .map((id) => ({ id, name: id }) as ModelRow)\n const models = [...allModels, ...missing].filter((model) =>\n `${model.name} ${model.id}`\n .toLowerCase()\n .includes(query.trim().toLowerCase()),\n )\n const selected = new Set(\n draft.visibleModels ?? allModels.map((model) => model.id),\n )\n return (\n <div style={{ borderTop: border, marginTop: 12, paddingTop: 12 }}>\n <h3 style={{ margin: 0 }}>{t('modelsEdit')}</h3>\n <div style={{ display: 'grid', gap: 12, marginTop: 12 }}>\n <p className=\"dsh-subscription-hint\">\n {t(\n provider === 'cursor-subscription'\n ? 'cursorManageHint'\n : 'modelsHint',\n )}\n </p>\n {error && <p role=\"alert\">{error}</p>}\n <div style={actions}>\n <button\n type=\"button\"\n className=\"dsh-subscription-quiet\"\n disabled={busy || disabled || dirty}\n onClick={() => {\n void load(true)\n }}\n >\n {t('usageRefresh')}\n </button>\n {busy && <span role=\"status\">{t('modelDefaultsLoading')}</span>}\n </div>\n {catalog && (\n <fieldset\n disabled={busy || disabled}\n style={{\n border: 0,\n padding: 0,\n margin: 0,\n minWidth: 0,\n display: 'grid',\n gap: 12,\n }}\n >\n <label>\n <input\n type=\"checkbox\"\n checked={draft.visibleModels === undefined}\n onChange={(event) => {\n const next = { ...draft }\n if (event.target.checked) delete next.visibleModels\n else next.visibleModels = allModels.map((model) => model.id)\n edit(next)\n }}\n />{' '}\n {t('modelsAutomatic')}\n </label>\n <div style={actions}>\n <input\n style={{ flex: '1 1 180px' }}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder={t('modelDefaultsFilterPlaceholder')}\n aria-label={t('modelDefaultsFilterPlaceholder')}\n />\n <button\n type=\"button\"\n onClick={() =>\n edit({\n ...draft,\n visibleModels: allModels.map((model) => model.id),\n })\n }\n >\n {t('modelsSelectAll')}\n </button>\n <button\n type=\"button\"\n onClick={() => edit({ ...draft, visibleModels: [] })}\n >\n {t('modelsSelectNone')}\n </button>\n </div>\n <div\n style={{\n maxHeight: 360,\n overflowY: 'auto',\n display: 'grid',\n gap: 8,\n }}\n >\n {models.map((model) => (\n <div\n key={model.id}\n style={{\n borderBottom: border,\n padding: '8px 2px',\n display: 'grid',\n gap: 8,\n }}\n >\n <label style={{ overflowWrap: 'anywhere' }}>\n <input\n type=\"checkbox\"\n checked={selected.has(model.id)}\n onChange={(event) => {\n const next = new Set(selected)\n if (event.target.checked) next.add(model.id)\n else next.delete(model.id)\n edit({ ...draft, visibleModels: [...next] })\n }}\n />{' '}\n {model.name}\n {!known.has(model.id) && ` (${t('modelsUnavailable')})`}\n </label>\n <div style={actions}>\n {(model.efforts?.length ?? 0) > 0 && (\n <label style={actions}>\n {t('modelDefaultsTitle')}\n <select\n aria-label={`${model.name} ${t('modelDefaultsTitle')}`}\n value={efforts[model.id] ?? ''}\n onChange={(event) => {\n setEfforts({\n ...efforts,\n [model.id]: event.target.value,\n })\n setDirty(true)\n }}\n >\n <option value=\"\">\n {t('modelDefaultsFollowProvider')}\n </option>\n {model.configured &&\n !model.efforts?.some(\n (effort) => effort.id === model.configured,\n ) && (\n <option value={model.configured} disabled>\n {model.configured} ({t('modelsUnavailable')})\n </option>\n )}\n {model.efforts?.map((effort) => (\n <option key={effort.id} value={effort.id}>\n {effort.name}\n </option>\n ))}\n </select>\n </label>\n )}\n {supportsContext(provider) &&\n model.maxContextWindow !== undefined && (\n <div style={actions}>\n <label style={actions}>\n {t('modelsContext')}\n <input\n style={{ width: 140 }}\n inputMode=\"numeric\"\n value={contexts[model.id] ?? ''}\n aria-label={`${model.name} ${t('modelsContext')}`}\n placeholder={String(model.defaultContextWindow)}\n onChange={(event) => {\n setContexts({\n ...contexts,\n [model.id]: event.target.value,\n })\n setDirty(true)\n }}\n />\n </label>\n <small>\n {t('modelsContextBounds', {\n default: model.defaultContextWindow,\n max: model.maxContextWindow,\n })}\n </small>\n </div>\n )}\n </div>\n </div>\n ))}\n {models.length === 0 && (\n <span>{t('modelDefaultsFilterEmpty', { query })}</span>\n )}\n </div>\n {supportsContext(provider) && (\n <small>{t('modelsContextHint')}</small>\n )}\n {catalog.tools.length > 0 && (\n <div style={{ display: 'grid', gap: 8 }}>\n <strong>{t('modelsTools')}</strong>\n <small>{t('modelsToolsHint')}</small>\n {catalog.tools.map((tool) => (\n <label key={tool}>\n <input\n type=\"checkbox\"\n checked={draft.tools?.[tool] !== false}\n onChange={(event) =>\n edit({\n ...draft,\n tools: {\n ...draft.tools,\n [tool]: event.target.checked,\n },\n })\n }\n />{' '}\n {t(\n tool === 'image_generate'\n ? 'modelsImage'\n : tool === 'video_generate'\n ? 'modelsVideo'\n : tool === 'web_search'\n ? 'modelsWebSearch'\n : 'modelsSearch',\n )}\n </label>\n ))}\n </div>\n )}\n </fieldset>\n )}\n </div>\n </div>\n )\n },\n)\n","/**\n * The host loads one JS client bundle, so keep this small, scoped stylesheet\n * with the dialog instead of relying on a separate CSS asset. Geometry and\n * theme tokens follow the host's settings-form and ui-primitives controls.\n *\n * `color-scheme` is left to the host deliberately. Its boot script sets the\n * property on `:root`, and it inherits, so native controls inside these panels\n * follow the theme. Upstream also pins `color-scheme: light` here and flips it\n * back under `body[data-ds-dark-theme]`; without that flip our scoped rules are\n * more specific than `:root` and would force every native control light inside\n * a dark theme.\n */\nconst formScope = ':is(.dsh-subscription-manager, .dsh-subscriptions-settings)'\n\nexport const providerSettingsCss = `\n.dsh-subscription-manager {\n box-sizing: border-box;\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-panel, 16px);\n background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-elevation-prominent, 0 20px 70px #0004);\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n.dsh-subscriptions-settings {\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n.dsh-subscription-manager::backdrop {\n background: var(--dsw-alias-bg-mask-1, #0006);\n backdrop-filter: var(--dsw-mask-blur, none);\n}\n${formScope} h2 {\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n}\n${formScope} h3 {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n}\n${formScope} strong,\n${formScope} .dsh-subscription-label {\n font-size: 13px;\n line-height: 1.5;\n font-weight: 500;\n}\n${formScope} legend {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n}\n${formScope} small,\n${formScope} .dsh-subscription-hint,\n${formScope} [role=\"status\"] {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n${formScope} [role=\"alert\"] {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary, #b42318);\n}\n${formScope} input:not([type=\"checkbox\"]),\n${formScope} select {\n box-sizing: border-box;\n min-width: 0;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4, var(--dsw-alias-border-l2));\n border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-layer-1));\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n font-weight: 400;\n line-height: 1.5;\n}\n${formScope} input::placeholder {\n color: var(--dsw-alias-label-tertiary);\n opacity: 1;\n}\n${formScope} input:not([type=\"checkbox\"]):focus-visible,\n${formScope} select:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary));\n}\n${formScope} input:not([type=\"checkbox\"]):disabled,\n${formScope} select:disabled {\n color: var(--dsw-alias-label-tertiary);\n cursor: default;\n}\n${formScope} input[aria-invalid=\"true\"] {\n border-color: var(--dsw-alias-state-error-primary, #b42318);\n}\n${formScope} option {\n background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));\n color: var(--dsw-alias-label-primary);\n}\n${formScope} label:has(> input[type=\"checkbox\"]) {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n font-size: 14px;\n line-height: 20px;\n cursor: pointer;\n}\n${formScope} input[type=\"checkbox\"] {\n flex: 0 0 auto;\n width: 16px;\n height: 16px;\n margin: 2px 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: inherit;\n}\n${formScope} label:has(> input[type=\"checkbox\"]:disabled) {\n cursor: default;\n opacity: 0.5;\n}\n${formScope} button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-height: 28px;\n padding: 0 10px;\n border: 0.5px solid var(--dsw-alias-border-l3, var(--dsw-alias-border-l2));\n border-radius: var(--dsw-radius-sm, 6px);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n}\n${formScope} button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, var(--dsw-alias-bg-layer-3));\n}\n${formScope} button:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, var(--dsw-alias-bg-layer-3));\n}\n${formScope} button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n${formScope} button.dsh-subscription-quiet {\n border-color: transparent;\n color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-primary));\n}\n${formScope} :is(footer, .dsh-subscription-dialog-actions) button {\n min-height: 34px;\n padding: 0 14px;\n border-radius: var(--dsw-radius-md, 8px);\n font-size: 13px;\n line-height: 1.5;\n}\n${formScope} button.dsh-subscription-primary {\n border-color: transparent;\n background: var(--dsw-alias-button-primary-fill, var(--dsw-alias-label-primary));\n color: var(--dsw-alias-label-primary-foreground, var(--dsw-alias-bg-layer-1));\n font-weight: 500;\n}\n${formScope} button.dsh-subscription-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, var(--dsw-alias-label-secondary));\n}\n${formScope} button:focus-visible,\n${formScope} input[type=\"checkbox\"]:focus-visible,\n${formScope} summary:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n${formScope} summary {\n border-radius: var(--dsw-radius-sm, 6px);\n}\n${formScope} summary:hover {\n color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-primary));\n}\n`\n\n/** Composer controls retain their own geometry, separate from settings forms. */\nexport const subscriptionChromeCss = `\n.dsh-subscription-usage-pill { corner-shape: round; }\n.dsh-subscription-usage-panel {\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n backdrop-filter: var(--dsw-menu-backdrop-filter, none);\n}\n.dsh-subscription-speed button:hover:not(:disabled) {\n --dsh-subscription-speed-hover: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-subscription-speed button:active:not(:disabled) {\n --dsh-subscription-speed-hover: var(--dsw-alias-interactive-bg-active);\n}\n.dsh-subscription-speed button:disabled { opacity: 0.4; cursor: default; }\n.dsh-subscription-speed button:focus-visible,\n.dsh-subscription-usage-pill:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n`\n","import { useEffect, useId, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {\n AccountPreferences,\n ProviderPreferences,\n} from '../provider-settings.js'\nimport type { PromptCacheTtl } from '../translate/anthropic.js'\nimport type { SubscriptionProvider } from './SubscriptionsSection.js'\nimport type { SubscriptionsKey } from './locales.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport {\n accountModelRows,\n accountPoolSelection,\n mergeAccountChanges,\n mergeLatestAccounts,\n mergePromptCacheTtl,\n} from './account-preferences.js'\nimport type { AccountCatalogRow } from './account-preferences.js'\nimport { ProviderModelEditor } from './ProviderModelEditor.js'\nimport type { ProviderModelEditorHandle } from './ProviderModelEditor.js'\nimport { providerSettingsCss } from './provider-settings-styles.js'\n\ninterface Catalog {\n settings: ProviderPreferences\n accounts: AccountCatalogRow[]\n}\ninterface Props {\n provider: SubscriptionProvider | 'cursor-subscription'\n name: string\n rpc: ConnectionHandle['rpc']\n t: (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n onClose: () => void\n}\nconst border = '0.5px solid var(--dsw-alias-border-l2)'\nconst stack: CSSProperties = { display: 'grid', gap: 12, minWidth: 0 }\nconst actions: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n alignItems: 'center',\n}\n\n/** Native top-layer dialog provides keyboard containment, Escape and focus restoration. */\nexport function ProviderAccountManager({\n provider,\n name,\n rpc,\n t,\n onClose,\n}: Props) {\n const dialog = useRef<HTMLDialogElement>(null)\n const title = useId()\n const description = useId()\n const [catalog, setCatalog] = useState<Catalog>()\n const [changes, setChanges] = useState<Record<string, AccountPreferences>>({})\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState('')\n const [saveError, setSaveError] = useState('')\n const [attempt, setAttempt] = useState(0)\n const [modelsDirty, setModelsDirty] = useState(false)\n // The Claude prompt-cache TTL draft: undefined follows the plugin config.\n const [ttlDraft, setTtlDraft] = useState<PromptCacheTtl>()\n const [ttlDirty, setTtlDirty] = useState(false)\n const alive = useRef(true)\n const saveLock = useRef(false)\n const editor = useRef<ProviderModelEditorHandle>(null)\n useEffect(() => {\n alive.current = true\n const element = dialog.current!\n const previous = document.activeElement\n element.showModal()\n return () => {\n alive.current = false\n element.close()\n if (previous instanceof HTMLElement && previous.isConnected)\n previous.focus()\n }\n }, [])\n useEffect(() => {\n let current = true\n setLoading(true)\n setError('')\n void callSubscriptionsAuth<Catalog>(\n rpc,\n provider === 'cursor-subscription'\n ? 'cursorSettings'\n : 'providerSettings',\n { provider },\n )\n .then((data) => {\n if (current) {\n setCatalog(data)\n setTtlDraft(data.settings.promptCacheTtl)\n setTtlDirty(false)\n }\n })\n .catch((error) => {\n if (current)\n setError(\n t('accountsLoadFailed', {\n message: error instanceof Error ? error.message : String(error),\n }),\n )\n })\n .finally(() => {\n if (current) setLoading(false)\n })\n return () => {\n current = false\n }\n // `t` only formats the load error. A new translator must not refetch.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- refetch on provider, rpc, and attempt only\n }, [provider, rpc, attempt])\n\n function edit(key: string, next: AccountPreferences) {\n setChanges((current) => ({ ...current, [key]: next }))\n }\n /**\n * One submit for both drafts: the model editor's (visibility, effort,\n * context, tools) and this dialog's account edits. A failure keeps the\n * dialog open with every edit intact.\n */\n async function save() {\n if (saveLock.current) return\n // An invalid model draft (e.g. a malformed context window) blocks the\n // whole submit; the editor shows the reason next to the field.\n const models =\n editor.current === null ? { efforts: [] } : editor.current.collect()\n if (models === undefined) return\n saveLock.current = true\n setSaving(true)\n setSaveError('')\n let savedEfforts = 0\n try {\n if (provider !== 'cursor-subscription') {\n for (const { model, effort } of models.efforts) {\n await callSubscriptionsAuth(rpc, 'setModelDefault', {\n provider,\n model,\n ...(effort ? { effort } : {}),\n })\n savedEfforts++\n if (!alive.current) return\n }\n }\n // Re-read before writing: another client may have saved since this\n // dialog loaded, and a stale snapshot must never be written back.\n const latest = await callSubscriptionsAuth<Catalog>(\n rpc,\n provider === 'cursor-subscription'\n ? 'cursorSettings'\n : 'providerSettings',\n { provider },\n )\n if (!alive.current) return\n if (provider === 'cursor-subscription') {\n await callSubscriptionsAuth(rpc, 'cursorSetSettings', {\n settings: models.settings ?? latest.settings,\n })\n } else {\n const base =\n models.settings === undefined\n ? latest.settings\n : mergeLatestAccounts(models.settings, latest.settings)\n // The editor's draft carries the TTL it loaded, so the dialog always\n // replaces it: the picker's choice when touched, otherwise the value\n // from the freshly re-read settings.\n const withTtl = mergePromptCacheTtl(\n base,\n ttlDirty ? ttlDraft : latest.settings.promptCacheTtl,\n )\n await callSubscriptionsAuth(rpc, 'setProviderSettings', {\n provider,\n settings: mergeAccountChanges(withTtl, changes),\n })\n }\n if (alive.current) onClose()\n } catch (error) {\n if (alive.current) {\n const message = error instanceof Error ? error.message : String(error)\n setSaveError(\n (savedEfforts ? t('modelsPartialSave') + ' ' : '') +\n t('accountsSaveFailed', { message }),\n )\n }\n } finally {\n saveLock.current = false\n if (alive.current) setSaving(false)\n }\n }\n return (\n <dialog\n className=\"dsh-subscription-manager\"\n ref={dialog}\n aria-labelledby={title}\n aria-describedby={description}\n onCancel={(event) => {\n if (saveLock.current) event.preventDefault()\n }}\n onClose={onClose}\n style={{\n width: 620,\n maxWidth: 'calc(100vw - 32px)',\n maxHeight: 'calc(100dvh - 32px)',\n overflow: 'auto',\n }}\n >\n <style>{providerSettingsCss}</style>\n <div style={{ ...stack, padding: 20 }}>\n <header style={{ ...actions, justifyContent: 'space-between' }}>\n <h2 id={title} style={{ margin: 0 }}>\n {t('accountsTitle', { provider: name })}\n </h2>\n <button type=\"button\" autoFocus disabled={saving} onClick={onClose}>\n {t('imageClose')}\n </button>\n </header>\n <p id={description} className=\"dsh-subscription-hint\">\n {t(\n provider === 'cursor-subscription'\n ? 'cursorAccountsHint'\n : 'accountsHint',\n )}\n </p>\n {error && <p role=\"alert\">{error}</p>}\n {loading && (\n <p role=\"status\" className=\"dsh-subscription-hint\">\n {t('accountsLoading')}\n </p>\n )}\n {!loading && !catalog && (\n <button\n type=\"button\"\n onClick={() => setAttempt((value) => value + 1)}\n >\n {t('modelDefaultsRetry')}\n </button>\n )}\n {catalog && (\n <fieldset\n disabled={saving || loading}\n style={{ ...stack, border: 0, margin: 0, padding: 0 }}\n >\n {catalog.accounts.length === 0 && (\n <p className=\"dsh-subscription-hint\">\n {t(\n provider === 'cursor-subscription'\n ? 'cursorManageSignIn'\n : 'accountsEmpty',\n )}\n </p>\n )}\n {provider === 'cursor-subscription' &&\n catalog.accounts.length > 0 && (\n <fieldset\n style={{\n border,\n borderRadius: 'var(--dsw-radius-lg, 12px)',\n padding: 14,\n }}\n >\n <legend style={{ padding: '0 6px' }}>{name}</legend>\n <p className=\"dsh-subscription-hint\">\n {t('cursorConnected')}\n </p>\n </fieldset>\n )}\n {provider !== 'cursor-subscription' &&\n catalog.accounts.map((account) => {\n const preferences =\n changes[account.key] ??\n catalog.settings.accounts?.[account.key] ??\n {}\n const selected = accountPoolSelection(\n preferences,\n account.models,\n )\n const models = accountModelRows(account, preferences)\n return (\n <fieldset\n key={account.key}\n style={{\n ...stack,\n border,\n borderRadius: 'var(--dsw-radius-lg, 12px)',\n padding: 14,\n margin: 0,\n }}\n >\n <legend\n style={{\n padding: '0 6px',\n overflowWrap: 'anywhere',\n maxWidth: '100%',\n }}\n >\n {account.label}\n </legend>\n {account.unavailable && (\n <p className=\"dsh-subscription-hint\">\n {t('accountsCatalogUnavailable')}\n </p>\n )}\n <label style={{ ...stack, gap: 6 }}>\n <span className=\"dsh-subscription-label\">\n {t('accountsAlias')}\n </span>\n <input\n value={preferences.alias ?? ''}\n placeholder={account.label}\n onChange={(event) => {\n const next = { ...preferences }\n if (event.target.value.trim())\n next.alias = event.target.value\n else delete next.alias\n edit(account.key, next)\n }}\n />\n </label>\n <label>\n <input\n type=\"checkbox\"\n checked={preferences.poolEnabled !== false}\n onChange={(event) =>\n edit(account.key, {\n ...preferences,\n poolEnabled: event.target.checked,\n })\n }\n />{' '}\n {t('accountsPoolEnabled')}\n </label>\n <label>\n <input\n type=\"checkbox\"\n checked={preferences.independentEntry === true}\n onChange={(event) =>\n edit(account.key, {\n ...preferences,\n independentEntry: event.target.checked,\n })\n }\n />{' '}\n {t('accountsIndependent')}\n </label>\n <p className=\"dsh-subscription-hint\">\n {t('accountsIndependentHint')}\n </p>\n <details>\n <summary style={{ cursor: 'pointer', fontSize: 13 }}>\n {t('accountsModels')} ·{' '}\n {preferences.poolModels === undefined\n ? t('accountsModelsAll')\n : t('accountsModelsCount', {\n count: preferences.poolModels.length,\n })}\n </summary>\n <div style={{ ...stack, marginTop: 12 }}>\n <p className=\"dsh-subscription-hint\">\n {t('accountsModelsHint')}\n </p>\n <label>\n <input\n type=\"checkbox\"\n checked={preferences.poolModels === undefined}\n onChange={(event) => {\n const next = { ...preferences }\n if (event.target.checked) delete next.poolModels\n else\n next.poolModels = account.models.map(\n (model) => model.id,\n )\n edit(account.key, next)\n }}\n />{' '}\n {t('accountsModelsAutomatic')}\n </label>\n <div style={actions}>\n <button\n type=\"button\"\n onClick={() =>\n edit(account.key, {\n ...preferences,\n poolModels: models.map((model) => model.id),\n })\n }\n >\n {t('modelsSelectAll')}\n </button>\n <button\n type=\"button\"\n onClick={() =>\n edit(account.key, {\n ...preferences,\n poolModels: [],\n })\n }\n >\n {t('modelsSelectNone')}\n </button>\n </div>\n <div\n style={{\n ...stack,\n gap: 8,\n maxHeight: 240,\n overflowY: 'auto',\n }}\n >\n {models.map((model) => (\n <label\n key={model.id}\n style={{ overflowWrap: 'anywhere' }}\n >\n <input\n type=\"checkbox\"\n checked={selected.has(model.id)}\n onChange={(event) => {\n const next = new Set(selected)\n if (event.target.checked) next.add(model.id)\n else next.delete(model.id)\n edit(account.key, {\n ...preferences,\n poolModels: [...next],\n })\n }}\n />{' '}\n {model.name}\n {model.unavailable &&\n ` (${t('modelsUnavailable')})`}\n </label>\n ))}\n {models.length === 0 && (\n <p className=\"dsh-subscription-hint\">\n {t('accountsNoModels')}\n </p>\n )}\n </div>\n </div>\n </details>\n </fieldset>\n )\n })}\n </fieldset>\n )}\n {(provider !== 'cursor-subscription' ||\n (catalog?.accounts.length ?? 0) > 0) && (\n <ProviderModelEditor\n ref={editor}\n provider={provider}\n rpc={rpc}\n t={t}\n disabled={saving}\n onDirtyChange={setModelsDirty}\n />\n )}\n {provider === 'claude' && catalog && (\n <div\n style={{\n ...stack,\n gap: 6,\n borderTop: border,\n marginTop: 12,\n paddingTop: 12,\n }}\n >\n <label style={{ ...stack, gap: 6 }}>\n <span className=\"dsh-subscription-label\">\n {t('claudeCacheTtl')}\n </span>\n <select\n aria-label={t('claudeCacheTtl')}\n style={{ width: 220 }}\n value={ttlDraft ?? ''}\n disabled={saving}\n onChange={(event) => {\n const value = event.target.value\n setTtlDraft(\n value === '' ? undefined : (value as PromptCacheTtl),\n )\n setTtlDirty(true)\n }}\n >\n <option value=\"\">{t('claudeCacheTtlFollowConfig')}</option>\n <option value=\"5m\">{t('claudeCacheTtl5m')}</option>\n <option value=\"1h\">{t('claudeCacheTtl1h')}</option>\n </select>\n </label>\n <p className=\"dsh-subscription-hint\">{t('claudeCacheTtlHint')}</p>\n </div>\n )}\n <footer\n style={{\n ...stack,\n gap: 8,\n borderTop: border,\n padding: '14px 0 8px',\n position: 'sticky',\n bottom: 0,\n background:\n 'var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1))',\n }}\n >\n {saveError && <p role=\"alert\">{saveError}</p>}\n <div style={{ ...actions, justifyContent: 'flex-end' }}>\n <button type=\"button\" disabled={saving} onClick={onClose}>\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n className=\"dsh-subscription-primary\"\n disabled={\n loading ||\n saving ||\n (!Object.keys(changes).length && !modelsDirty && !ttlDirty)\n }\n onClick={() => {\n void save()\n }}\n >\n {saving ? t('modelDefaultsSaving') : t('modelsSave')}\n </button>\n </div>\n </footer>\n </div>\n </dialog>\n )\n}\n","import type { CSSProperties } from 'react'\n\n/** Shared visual language for OAuth, Cursor, and built-in provider cards. */\nexport const subscriptionCardStyles: Record<string, CSSProperties> = {\n card: {\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: '12px 14px',\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n color: 'var(--dsw-alias-label-primary)',\n },\n header: { display: 'flex', alignItems: 'center', gap: 8 },\n dot: { width: 8, height: 8, borderRadius: '50%', flexShrink: 0 },\n name: {\n fontWeight: 500,\n fontSize: 14,\n lineHeight: '22px',\n color: 'var(--dsw-alias-label-primary)',\n },\n status: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n error: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-state-error-primary)',\n },\n actions: {\n display: 'flex',\n gap: 8,\n marginTop: 4,\n alignItems: 'center',\n flexWrap: 'wrap',\n },\n button: {\n boxSizing: 'border-box',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: 28,\n padding: '0 10px',\n borderRadius: 14,\n border: '1px solid var(--dsw-alias-border-l2)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary)',\n font: 'inherit',\n fontSize: 12,\n lineHeight: '18px',\n cursor: 'pointer',\n },\n account: {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n padding: '8px 10px',\n marginTop: 4,\n },\n accountHeader: { display: 'flex', alignItems: 'center', gap: 8 },\n accountName: {\n fontSize: 13,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary)',\n userSelect: 'all',\n },\n defaultStar: { color: 'var(--dsw-alias-state-warn-label)' },\n usage: {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n marginTop: 4,\n borderTop: '1px solid var(--dsw-alias-border-l2)',\n paddingTop: 8,\n },\n usageHeader: { display: 'flex', alignItems: 'center', gap: 8 },\n usageTitle: {\n fontSize: 12,\n lineHeight: '18px',\n fontWeight: 500,\n color: 'var(--dsw-alias-label-secondary)',\n },\n usagePlan: {\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n usageRefresh: {\n boxSizing: 'border-box',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: 22,\n padding: '0 8px',\n borderRadius: 11,\n marginLeft: 'auto',\n border: '1px solid var(--dsw-alias-border-l2)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-secondary)',\n font: 'inherit',\n fontSize: 12,\n lineHeight: '18px',\n cursor: 'pointer',\n },\n usageRow: { display: 'flex', flexDirection: 'column', gap: 3 },\n usageMeta: {\n display: 'flex',\n justifyContent: 'space-between',\n gap: 8,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n}\n","import { useSyncExternalStore } from 'react'\n\n/**\n * Display-only preference: no credentials or account history are stored.\n * `recent` pins the current/most-recent provider; `always` keeps a provider\n * visible at all times, rotating through the others when the current model\n * has no quota source; `hidden` shows nothing.\n */\nexport type UsageBadgeMode = 'recent' | 'always' | 'hidden'\nconst MODE_KEY = 'dsh.subscriptions.usageBadgeMode'\nconst MODE_EVENT = 'dsh:subscriptions:usage-badge-mode'\nexport const USAGE_BADGE_REFRESH_EVENT = 'dsh:subscriptions:usage-refresh'\n\n/** Read the browser preference; blocked storage retains the default display. */\nexport function readUsageBadgeMode(): UsageBadgeMode {\n if (typeof window === 'undefined') return 'recent'\n try {\n const value = window.localStorage.getItem(MODE_KEY)\n return value === 'hidden' || value === 'always' ? value : 'recent'\n } catch (error) {\n if (!(error instanceof DOMException) || error.name !== 'SecurityError')\n throw error\n return 'recent'\n }\n}\n\n/** Save first, then notify; the settings control reports a rejected write. */\nexport function setUsageBadgeMode(mode: UsageBadgeMode): void {\n if (mode !== 'recent' && mode !== 'always' && mode !== 'hidden')\n throw new TypeError('Invalid subscription usage display mode')\n window.localStorage.setItem(MODE_KEY, mode)\n window.dispatchEvent(new Event(MODE_EVENT))\n}\n\n/** Same-tab writes need a custom event; other tabs use the storage event. */\nexport function subscribeUsageBadgeMode(notify: () => void): () => void {\n const onStorage = (event: StorageEvent): void => {\n if (event.key === MODE_KEY || event.key === null) notify()\n }\n window.addEventListener(MODE_EVENT, notify)\n window.addEventListener('storage', onStorage)\n return () => {\n window.removeEventListener(MODE_EVENT, notify)\n window.removeEventListener('storage', onStorage)\n }\n}\n\n/** Shared React snapshot used by the settings control and every mounted badge. */\nexport function useUsageBadgeMode(): UsageBadgeMode {\n return useSyncExternalStore(\n subscribeUsageBadgeMode,\n readUsageBadgeMode,\n () => 'recent',\n )\n}\n","import type { UsageWindow } from './SubscriptionsSection.js'\nimport type { UsageColorPreset } from './usage-color-preferences.js'\n\nexport interface UsageObservation {\n observedAt?: number | undefined\n stale?: boolean | undefined\n}\nexport type UsageColorState = 'neutral' | 'red' | 'yellow' | 'green'\nexport const USAGE_FRESHNESS_MS = 5 * 60_000\nexport function validUsage(used: number): boolean {\n return Number.isFinite(used) && used >= 0 && used <= 100\n}\n\n/**\n * Rounded share for display, or undefined when the provider's number is\n * unusable. Callers must show the unavailable state rather than clamp an\n * out-of-range reading into 0% or 100%.\n */\nexport function displayUsedPercent(used: number): number | undefined {\n return validUsage(used) ? Math.round(used) : undefined\n}\n\nexport interface CountdownPart {\n unit: 'day' | 'hour' | 'minute'\n count: number\n}\n\n/**\n * Reset countdown as the two largest nonzero whole units, rounded up so a\n * window never announces zero remaining time. Always at least one minute.\n */\nexport function resetCountdownParts(ms: number): CountdownPart[] {\n const total = Math.max(1, Math.ceil(ms / 60_000))\n const parts: CountdownPart[] = [\n { unit: 'day', count: Math.floor(total / 1440) },\n { unit: 'hour', count: Math.floor((total % 1440) / 60) },\n { unit: 'minute', count: total % 60 },\n ]\n return parts.filter((part) => part.count > 0).slice(0, 2)\n}\n/**\n * Whether the reported percentage still describes the window now. Only a fresh\n * reading may be compared with the current time (pace warnings); an old one\n * keeps its absolute color. This does not decide whether the time cursor is\n * drawn: where the window stands in time never depends on the reading.\n */\nexport function isUsageFresh(\n window: UsageWindow,\n observation: UsageObservation,\n now = Date.now(),\n): boolean {\n return (\n validUsage(window.usedPercent) &&\n observation.stale !== true &&\n observation.observedAt !== undefined &&\n Number.isFinite(observation.observedAt) &&\n observation.observedAt <= now &&\n now - observation.observedAt <= USAGE_FRESHNESS_MS &&\n (window.resetsAt === undefined ||\n (Number.isFinite(window.resetsAt) && window.resetsAt > now))\n )\n}\n\n/**\n * How far through its window the clock is, from the window's own timing alone.\n * It ignores the percentage and how recently it was read, so an unused,\n * stale, aged or unobserved reading keeps its cursor whenever the timing\n * places it. Returns undefined when the timing cannot: only an explicit\n * interval or a provider-verified fixed duration supports linear pace, and no\n * start is invented from a window's kind or label.\n */\nexport function elapsedPercent(\n window: UsageWindow,\n now = Date.now(),\n): number | undefined {\n const end = window.resetsAt\n if (end === undefined || !Number.isFinite(end) || end <= now) return undefined\n const duration = window.windowDurationMs\n const start =\n window.startsAt ??\n (window.fixedWindow === true &&\n duration !== undefined &&\n Number.isFinite(duration) &&\n duration > 0\n ? end - duration\n : undefined)\n if (\n start === undefined ||\n !Number.isFinite(start) ||\n start >= end ||\n start > now\n )\n return undefined\n return Math.min(100, Math.max(0, ((now - start) / (end - start)) * 100))\n}\nexport function usageColorState(\n used: number,\n elapsed: number | undefined,\n preset: UsageColorPreset,\n fresh: boolean,\n): UsageColorState {\n if (!validUsage(used)) return 'neutral'\n if (used >= 90) return 'red'\n // Missing pace or stale observations retain the last reported absolute color.\n if (!fresh || preset === 'remaining' || elapsed === undefined) return 'green'\n return used - elapsed >= (preset === 'relaxed' ? 15 : 10) ? 'yellow' : 'green'\n}\nexport function usageBarColor(\n used: number,\n elapsed?: number,\n preset: UsageColorPreset = 'standard',\n fresh = true,\n): string {\n const state = usageColorState(used, elapsed, preset, fresh)\n return state === 'red'\n ? 'var(--dsw-alias-state-error-primary)'\n : state === 'yellow'\n ? 'var(--dsw-alias-state-warn-label)'\n : 'var(--dsw-alias-state-success-primary)'\n}\n\n/**\n * Marker position from the window's display-only assumed start\n * (`displayStartsAt`): the reading and its age are irrelevant, exactly\n * like the verified marker. Returns undefined when the window carries no\n * assumed start or its reset has passed.\n */\nexport function displayStartPercent(\n window: UsageWindow,\n now = Date.now(),\n): number | undefined {\n const end = window.resetsAt\n const start = window.displayStartsAt\n if (end === undefined || !Number.isFinite(end) || end <= now) return undefined\n if (\n start === undefined ||\n !Number.isFinite(start) ||\n start >= end ||\n start > now\n )\n return undefined\n return Math.min(100, Math.max(0, ((now - start) / (end - start)) * 100))\n}\n","import { useSyncExternalStore } from 'react'\n\nexport type UsageColorPreset = 'standard' | 'relaxed' | 'remaining'\nconst KEY = 'dsh.subscriptions.usageColorPreset'\nconst EVENT = 'dsh:subscriptions:usage-color-preset'\nexport function isUsageColorPreset(value: unknown): value is UsageColorPreset {\n return value === 'standard' || value === 'relaxed' || value === 'remaining'\n}\nexport function readUsageColorPreset(): UsageColorPreset {\n if (typeof window === 'undefined') return 'standard'\n try {\n const value = window.localStorage.getItem(KEY)\n return isUsageColorPreset(value) ? value : 'standard'\n } catch (error) {\n if (!(error instanceof DOMException) || error.name !== 'SecurityError')\n throw error\n return 'standard'\n }\n}\nexport function setUsageColorPreset(value: UsageColorPreset): void {\n if (!isUsageColorPreset(value))\n throw new TypeError('Invalid usage coloring preset')\n window.localStorage.setItem(KEY, value)\n window.dispatchEvent(new Event(EVENT))\n}\nexport function subscribeUsageColorPreset(notify: () => void): () => void {\n const storage = (event: StorageEvent) => {\n if (event.key === KEY || event.key === null) notify()\n }\n window.addEventListener(EVENT, notify)\n window.addEventListener('storage', storage)\n return () => {\n window.removeEventListener(EVENT, notify)\n window.removeEventListener('storage', storage)\n }\n}\nexport function useUsageColorPreset(): UsageColorPreset {\n return useSyncExternalStore(\n subscribeUsageColorPreset,\n readUsageColorPreset,\n () => 'standard',\n )\n}\n","import { useEffect, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type {\n UsageWindow,\n SubscriptionsSectionInjected,\n} from './SubscriptionsSection.js'\nimport {\n displayStartPercent,\n elapsedPercent,\n isUsageFresh,\n resetCountdownParts,\n usageBarColor,\n usageColorState,\n validUsage,\n} from './usage-pace.js'\nimport type { CountdownPart, UsageObservation } from './usage-pace.js'\nimport { useUsageColorPreset } from './usage-color-preferences.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** Singular/plural locale keys per countdown unit (zh maps both to one string). */\nconst UNIT_KEYS: Record<\n CountdownPart['unit'],\n [SubscriptionsKey, SubscriptionsKey]\n> = {\n day: ['usageUnitDay', 'usageUnitDays'],\n hour: ['usageUnitHour', 'usageUnitHours'],\n minute: ['usageUnitMinute', 'usageUnitMinutes'],\n}\n\nexport function UsageMeter({\n window: quota,\n t,\n style,\n observedAt,\n stale,\n}: {\n window: UsageWindow\n t: SubscriptionsSectionInjected['t']\n style?: CSSProperties\n} & UsageObservation) {\n const preset = useUsageColorPreset()\n const [now, setNow] = useState(Date.now)\n useEffect(() => {\n const timer = setInterval(() => setNow(Date.now()), 60_000)\n return () => clearInterval(timer)\n }, [])\n // Use render time for new readings, without trusting a future observation timestamp.\n const current = Math.max(now, Date.now())\n const valid = validUsage(quota.usedPercent)\n const used = valid ? quota.usedPercent : 0\n const fresh = isUsageFresh(quota, { observedAt, stale }, current)\n // The cursor is where the window stands in time: a provider-verified start\n // through elapsedPercent, else the display-only assumption.\n const elapsed = elapsedPercent(quota, current)\n const marker = elapsed ?? displayStartPercent(quota, current)\n // Comparing usage with elapsed time is meaningful only while the percentage\n // is current AND the start is verified: a display-estimated start must not\n // color the bar — elapsed already excludes it, so pace below is safe.\n const pace = fresh ? elapsed : undefined\n const state = usageColorState(quota.usedPercent, pace, preset, fresh)\n const lead = pace === undefined ? 0 : Math.round(used - pace)\n const label = [\n valid\n ? t('usageMeterUsed', {\n used: Math.round(used),\n remaining: Math.round(100 - used),\n })\n : t('usageMeterInvalid'),\n // An invalid reading already states unavailability; the stale line would repeat it.\n !valid\n ? ''\n : !fresh\n ? t('usageMeterStale')\n : state === 'red'\n ? t('usageMeterNearLimit')\n : pace === undefined && preset !== 'remaining'\n ? t('usageMeterUnknownTime')\n : state === 'yellow'\n ? t('usageMeterAhead')\n : t('usageMeterNoWarning'),\n // The elapsed-time line is a timing fact: it shows whenever the window's\n // interval is known, even for a stale or invalid reading.\n marker === undefined\n ? ''\n : t('usageMeterPace', { elapsed: Math.round(marker) }),\n pace === undefined\n ? ''\n : lead > 0\n ? t('usageMeterPaceAhead', { points: lead })\n : lead < 0\n ? t('usageMeterPaceBehind', { points: -lead })\n : t('usageMeterPaceEven'),\n quota.resetsAt !== undefined && quota.resetsAt > current\n ? t('usageMeterReset', {\n duration: resetCountdownParts(quota.resetsAt - current)\n .map((part) =>\n t(UNIT_KEYS[part.unit][part.count === 1 ? 0 : 1], {\n count: part.count,\n }),\n )\n .join(' '),\n })\n : '',\n ]\n .filter(Boolean)\n .join(' · ')\n return (\n <div\n role=\"img\"\n aria-label={label}\n title={label}\n data-usage-color={state}\n style={{\n height: 6,\n borderRadius: 3,\n overflow: 'hidden',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '1px solid var(--dsw-alias-border-l2)',\n ...style,\n position: 'relative',\n }}\n >\n <div\n style={{\n height: '100%',\n borderRadius: 'inherit',\n width: `${used}%`,\n background: usageBarColor(quota.usedPercent, pace, preset, fresh),\n }}\n />\n {marker !== undefined && (\n <span\n aria-hidden=\"true\"\n data-usage-time-marker\n style={{\n position: 'absolute',\n left: `clamp(0px, calc(${marker}% - 1px), calc(100% - 2px))`,\n top: 0,\n bottom: 0,\n width: 2,\n background: 'var(--dsw-alias-label-primary)',\n boxShadow: '0 0 0 1px var(--dsw-alias-bg-layer-1)',\n }}\n />\n )}\n </div>\n )\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {\n ProviderUsage,\n SubscriptionsSectionInjected,\n UsageWindow,\n} from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { subscriptionCardStyles as styles } from './subscription-card-styles.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\n\ntype Source = 'opencode-go' | 'kimi-code' | 'minimax' | 'minimax-cn'\ntype Translate = SubscriptionsSectionInjected['t']\n\nconst SOURCES: readonly { id: Source; name: string; ref: string }[] = [\n { id: 'opencode-go', name: 'OpenCode Go', ref: 'OPENCODE_GO_API_KEY' },\n { id: 'kimi-code', name: 'Kimi Code', ref: 'KIMI_CODING_API_KEY' },\n { id: 'minimax', name: 'MiniMax', ref: 'MINIMAX_API_KEY' },\n { id: 'minimax-cn', name: 'MiniMax CN', ref: 'MINIMAX_CN_API_KEY' },\n]\n\ntype Status = Record<Source, { configured: boolean }>\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Row label of one window on an external usage card. A session or weekly\n * window appends the model it belongs to when the provider names one (MiniMax\n * reports a window per model), so two models' weekly rows stay distinguishable.\n * The monthly pool is a scope on an `other` window, not a model.\n * @param t - section translate.\n * @param window - the reported window.\n * @returns the localized label, e.g. \"Weekly · general\".\n */\nexport function externalUsageWindowLabel(\n t: Translate,\n window: UsageWindow,\n): string {\n const named = window.scope !== undefined && window.scope !== ''\n if (window.kind === 'other') {\n return window.scope === 'Monthly'\n ? t('usageMonthly')\n : named\n ? window.scope!\n : t('usageWindow')\n }\n const base = window.kind === 'session' ? t('usageSession') : t('usageWeekly')\n return named ? `${base} · ${window.scope}` : base\n}\n\n/** Quota cards for API-key providers already available through DSH itself. */\nexport function ExternalUsageCards({\n rpc,\n t,\n}: {\n rpc: ConnectionHandle['rpc']\n t: Translate\n}) {\n const [status, setStatus] = useState<Status>()\n const [statusError, setStatusError] = useState<string>()\n const [usage, setUsage] = useState<Partial<Record<Source, ProviderUsage>>>({})\n const [observedAt, setObservedAt] = useState<Partial<Record<Source, number>>>(\n {},\n )\n const [errors, setErrors] = useState<Partial<Record<Source, string>>>({})\n const [loading, setLoading] = useState<Partial<Record<Source, boolean>>>({})\n\n const refresh = useCallback(\n async (source: Source) => {\n setLoading((prev) => ({ ...prev, [source]: true }))\n try {\n const value = await callSubscriptionsAuth<ProviderUsage>(\n rpc,\n 'externalUsage',\n { source },\n )\n setUsage((prev) => ({ ...prev, [source]: value }))\n // Prefer the server's observation time; a cached reading must not look fresh.\n setObservedAt((prev) => ({\n ...prev,\n [source]: value.observedAt ?? Date.now(),\n }))\n setErrors((prev) => ({ ...prev, [source]: undefined }))\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n } catch (error) {\n setErrors((prev) => ({ ...prev, [source]: errorText(error) }))\n } finally {\n setLoading((prev) => ({ ...prev, [source]: false }))\n }\n },\n [rpc],\n )\n\n const refreshStatus = useCallback(async () => {\n try {\n const value = await callSubscriptionsAuth<Status>(\n rpc,\n 'externalStatus',\n {},\n )\n setStatus(value)\n setStatusError(undefined)\n for (const { id } of SOURCES) if (value[id]?.configured) void refresh(id)\n } catch (error) {\n setStatusError(errorText(error))\n }\n }, [rpc, refresh])\n\n useEffect(() => {\n void refreshStatus()\n }, [refreshStatus])\n\n return (\n <>\n {SOURCES.map(({ id, name, ref }) => {\n const configured = status?.[id]?.configured === true\n const snapshot = usage[id]\n return (\n <div key={id} style={styles.card}>\n <div style={styles.header}>\n <span\n style={{\n ...styles.dot,\n background: configured\n ? 'var(--dsw-alias-state-success-primary)'\n : 'var(--dsw-alias-label-dimmed)',\n }}\n />\n <span style={styles.name}>{name}</span>\n </div>\n {!(status === undefined && statusError !== undefined) && (\n <p style={styles.status}>\n {status === undefined\n ? t('checking')\n : configured\n ? t('externalUsageConnected')\n : t('externalUsageNotConfigured')}\n </p>\n )}\n {statusError !== undefined && (\n <p style={styles.error}>\n {t('externalUsageUnavailable', { message: statusError })}\n </p>\n )}\n {status !== undefined && !configured && (\n <p style={styles.status}>\n {t('externalUsageConfigure', { ref })}\n </p>\n )}\n {configured && (\n <div style={styles.account}>\n <div style={styles.accountHeader}>\n <span style={styles.defaultStar} title={t('defaultBadge')}>\n ★\n </span>\n <span style={styles.accountName}>\n {t('externalUsageApiKey')}\n </span>\n </div>\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {snapshot?.plan !== undefined && (\n <span style={styles.usagePlan}>\n {t('usagePlan', { plan: snapshot.plan })}\n </span>\n )}\n <button\n type=\"button\"\n style={styles.usageRefresh}\n disabled={loading[id] === true}\n onClick={() => {\n void refresh(id)\n }}\n >\n {t('usageRefresh')}\n </button>\n </div>\n {loading[id] === true && snapshot === undefined && (\n <p style={styles.status}>{t('usageLoading')}</p>\n )}\n {errors[id] !== undefined && (\n <p style={styles.error}>\n {t('usageError', { message: errors[id] })}\n </p>\n )}\n {snapshot !== undefined && snapshot.supported === false && (\n <p style={styles.status}>{t('usageUnsupported')}</p>\n )}\n {snapshot?.windows?.length === 0 && (\n <p style={styles.status}>{t('usageEmpty')}</p>\n )}\n {snapshot?.windows?.map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n const label = externalUsageWindowLabel(t, window)\n return (\n <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{label}</span>\n <span>\n {percent === undefined\n ? t('usageMeterInvalid')\n : `${percent}%`}\n {window.resetsAt === undefined\n ? ''\n : ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}\n </span>\n </div>\n <UsageMeter\n window={window}\n t={t}\n observedAt={observedAt[id]}\n stale={\n errors[id] !== undefined || snapshot?.stale === true\n }\n />\n </div>\n )\n })}\n </div>\n </div>\n )}\n {!configured && (\n <div style={styles.actions}>\n <button\n type=\"button\"\n style={styles.button}\n onClick={() => {\n void refreshStatus()\n }}\n >\n {t('usageRefresh')}\n </button>\n </div>\n )}\n </div>\n )\n })}\n </>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {\n ProviderUsage,\n SubscriptionsSectionInjected,\n} from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { ProviderAccountManager } from './ProviderAccountManager.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { subscriptionCardStyles as styles } from './subscription-card-styles.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\n\ntype Translate = SubscriptionsSectionInjected['t']\ntype CursorStatus = {\n authenticated: boolean\n busy: boolean\n expiresAt?: number\n error?: string\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/** Cursor's single connected account, rendered with the same card and Manage dialog as the other providers. */\nexport function CursorCard({\n rpc,\n t,\n}: {\n rpc: ConnectionHandle['rpc']\n t: Translate\n}) {\n const [status, setStatus] = useState<CursorStatus>()\n const [usage, setUsage] = useState<ProviderUsage>()\n const [observedAt, setObservedAt] = useState<number>()\n const [usageStale, setUsageStale] = useState(false)\n const [authorizeUrl, setAuthorizeUrl] = useState<string>()\n const [error, setError] = useState<string>()\n const [loading, setLoading] = useState(false)\n const [manage, setManage] = useState(false)\n const authenticated = useRef<boolean>()\n\n const refreshStatus = useCallback(async () => {\n try {\n const value = await callSubscriptionsAuth<CursorStatus>(\n rpc,\n 'cursorStatus',\n {},\n )\n setStatus(value)\n if (authenticated.current !== value.authenticated) {\n authenticated.current = value.authenticated\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n }\n if (value.authenticated) setAuthorizeUrl(undefined)\n if (value.error) setError(value.error)\n } catch (failure) {\n setError(message(failure))\n }\n }, [rpc])\n\n const refreshUsage = useCallback(async () => {\n setLoading(true)\n try {\n const value = await callSubscriptionsAuth<ProviderUsage>(\n rpc,\n 'cursorUsage',\n {},\n )\n setUsage(value)\n // Prefer the server's observation time; a cached reading must not look fresh.\n setObservedAt(value.observedAt ?? Date.now())\n setUsageStale(value.stale === true)\n setError(undefined)\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n } catch (failure) {\n setError(message(failure))\n setUsageStale(true)\n } finally {\n setLoading(false)\n }\n }, [rpc])\n\n useEffect(() => {\n void refreshStatus()\n }, [refreshStatus])\n useEffect(() => {\n if (status?.busy !== true) return\n const timer = setInterval(() => {\n void refreshStatus()\n }, 2000)\n return () => clearInterval(timer)\n }, [status?.busy, refreshStatus])\n useEffect(() => {\n if (status?.authenticated === true) void refreshUsage()\n }, [status?.authenticated, refreshUsage])\n\n const login = async () => {\n setError(undefined)\n try {\n const value = await callSubscriptionsAuth<{ authorizeUrl: string }>(\n rpc,\n 'cursorLogin',\n {},\n )\n setAuthorizeUrl(value.authorizeUrl)\n window.open(value.authorizeUrl, '_blank', 'noopener')\n await refreshStatus()\n } catch (failure) {\n setError(message(failure))\n }\n }\n const cancel = async () => {\n try {\n await callSubscriptionsAuth(rpc, 'cursorCancel', {})\n setAuthorizeUrl(undefined)\n await refreshStatus()\n } catch (failure) {\n setError(message(failure))\n }\n }\n const logout = async () => {\n if (\n !window.confirm(\n t('logoutAccountConfirm', { account: 'Cursor', provider: 'Cursor' }),\n )\n )\n return\n try {\n await callSubscriptionsAuth(rpc, 'cursorLogout', {})\n setUsage(undefined)\n setObservedAt(undefined)\n setUsageStale(false)\n await refreshStatus()\n } catch (failure) {\n setError(message(failure))\n }\n }\n\n const connected = status?.authenticated === true\n return (\n <div style={styles.card}>\n <div style={styles.header}>\n <span\n style={{\n ...styles.dot,\n background: status?.busy\n ? 'var(--dsw-alias-state-warn-label)'\n : connected\n ? 'var(--dsw-alias-state-success-primary)'\n : 'var(--dsw-alias-label-dimmed)',\n }}\n />\n <span style={styles.name}>{t('cursorTitle')}</span>\n </div>\n <p style={styles.status}>\n {status === undefined\n ? t('checking')\n : status.busy\n ? t('loginInProgress')\n : connected\n ? t('loggedInCount', { count: 1 })\n : t('notLoggedIn')}\n </p>\n {error !== undefined && <p style={styles.error}>{error}</p>}\n {connected && (\n <div style={styles.account}>\n <div style={styles.accountHeader}>\n <span style={styles.defaultStar} title={t('defaultBadge')}>\n ★\n </span>\n <span style={styles.accountName}>Cursor</span>\n {status.expiresAt !== undefined && (\n <span style={styles.status}>\n {t('accountExpires', {\n date: new Date(status.expiresAt).toLocaleString(),\n })}\n </span>\n )}\n <button\n type=\"button\"\n style={{ ...styles.button, marginLeft: 'auto', flexShrink: 0 }}\n onClick={() => {\n void logout()\n }}\n >\n {t('logout')}\n </button>\n </div>\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {usage?.plan !== undefined && (\n <span style={styles.status}>\n {t('usagePlan', { plan: usage.plan })}\n </span>\n )}\n <button\n type=\"button\"\n style={styles.usageRefresh}\n disabled={loading}\n onClick={() => {\n void refreshUsage()\n }}\n >\n {t('usageRefresh')}\n </button>\n </div>\n {loading && usage === undefined && (\n <p style={styles.status}>{t('usageLoading')}</p>\n )}\n {usage?.windows?.length === 0 && (\n <p style={styles.status}>{t('usageEmpty')}</p>\n )}\n {usage?.windows?.map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n const label =\n window.scope === 'Included'\n ? t('cursorIncluded')\n : window.scope === 'Cursor Models'\n ? t('cursorModels')\n : window.scope === 'Other Models'\n ? t('cursorOtherModels')\n : window.scope === 'Included requests'\n ? t('cursorIncludedRequests')\n : (window.scope ?? t('usageWindow'))\n return (\n <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{label}</span>\n <span>\n {percent === undefined\n ? t('usageMeterInvalid')\n : `${percent}%`}\n {window.resetsAt === undefined\n ? ''\n : ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}\n </span>\n </div>\n <UsageMeter\n window={window}\n t={t}\n observedAt={observedAt}\n stale={usageStale}\n />\n </div>\n )\n })}\n </div>\n </div>\n )}\n <div style={styles.actions}>\n {status?.authenticated === false && !status.busy && (\n <button\n type=\"button\"\n style={styles.button}\n onClick={() => {\n void login()\n }}\n >\n {t('login')}\n </button>\n )}\n <button\n type=\"button\"\n style={styles.button}\n aria-haspopup=\"dialog\"\n onClick={() => setManage(true)}\n >\n {t('accountsManage')}\n </button>\n {status?.busy === true && (\n <button\n type=\"button\"\n style={styles.button}\n onClick={() => {\n void cancel()\n }}\n >\n {t('cancel')}\n </button>\n )}\n </div>\n {status?.busy === true && authorizeUrl !== undefined && (\n <a href={authorizeUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {t('cursorOpenLogin')}\n </a>\n )}\n {manage && (\n <ProviderAccountManager\n provider=\"cursor-subscription\"\n name=\"Cursor\"\n rpc={rpc}\n t={t}\n onClose={() => setManage(false)}\n />\n )}\n </div>\n )\n}\n","/**\n * Draft rules of the Ollama Cloud settings dialog, kept free of React and the\n * DOM so they can be unit tested. The node half owns the shapes below; the\n * client restates them locally because the browser bundle does not import\n * node-side modules.\n */\n\n/** One model entry as stored in the route settings. */\nexport interface OllamaModelSetting {\n id: string\n name?: string\n contextWindow?: number\n /** The user's explicit local context window; absent follows the endpoint. */\n contextOverride?: number\n maxTokens?: number\n vision?: boolean\n thinking?: boolean\n efforts?: string[]\n defaultEffort?: string\n}\n\n/** One model row of the editable draft (same fields as the stored entry). */\nexport interface OllamaModelDraft {\n id: string\n name?: string\n contextWindow?: number\n /** The user's explicit local context window; absent follows the endpoint. */\n contextOverride?: number\n maxTokens?: number\n vision?: boolean\n thinking?: boolean\n efforts?: string[]\n defaultEffort?: string\n}\n\n/** The editable settings draft; every field is an override of the deployment value. */\nexport interface OllamaSettingsDraft {\n models?: OllamaModelDraft[]\n web?: boolean\n baseURL?: string\n apiKeyRef?: string\n}\n\n/** `ollamaSettings` endpoint value. */\nexport interface OllamaSettingsView {\n provider: 'ollama-cloud'\n settings: {\n models?: OllamaModelSetting[]\n web?: boolean\n baseURL?: string\n apiKeyRef?: string\n }\n effective: { baseURL: string; apiKeyRef: string; web: boolean }\n models: {\n id: string\n name: string\n vision: boolean\n thinking: boolean\n contextWindow?: number\n /** Advertised reasoning levels and the endpoint default, when the model reasons. */\n efforts?: { id: string; name: string }[]\n defaultEffort?: string\n }[]\n configOverridesModels: boolean\n}\n\n/** One cloud catalog entry returned by the `ollamaModels` endpoint. */\nexport interface OllamaCloudCandidate {\n /** Normalized wire id; this is what the store keeps. */\n id: string\n /** Listing id before normalization. */\n rawId: string\n /** Display basename. */\n name: string\n vision: boolean\n thinking: boolean\n contextWindow?: number\n efforts: string[]\n defaultEffort?: string\n}\n\n/**\n * Append the checked candidates to the draft's model list. Existing rows are\n * never replaced or reordered, ids already present are skipped, and adopted\n * rows keep the candidate order. Optional fields are set only when the\n * candidate advertises a value, because `exactOptionalPropertyTypes` (and the\n * store) must not see an explicit `undefined`.\n * @param current - the draft list before adoption.\n * @param candidates - the cloud list as fetched, in display order.\n * @param selectedIds - ids the user checked.\n * @returns a new list; the input array is not mutated.\n */\nexport function adoptCandidates(\n current: readonly OllamaModelDraft[] | undefined,\n candidates: readonly OllamaCloudCandidate[],\n selectedIds: readonly string[],\n): OllamaModelDraft[] {\n const models = [...(current ?? [])]\n const present = new Set(models.map((model) => model.id))\n const selected = new Set(selectedIds)\n for (const candidate of candidates) {\n if (!selected.has(candidate.id) || present.has(candidate.id)) continue\n present.add(candidate.id)\n models.push({\n id: candidate.id,\n name: candidate.name,\n ...(candidate.contextWindow === undefined\n ? {}\n : { contextWindow: candidate.contextWindow }),\n ...(candidate.vision ? { vision: true } : {}),\n ...(candidate.thinking ? { thinking: true } : {}),\n // The vendor's default is not copied: defaultEffort in the store is\n // the user's explicit choice only, so the resolver's priority\n // (user, then vendor, then family) keeps the vendor default live\n // in discovery while the selector stays an override.\n ...(candidate.efforts.length ? { efforts: [...candidate.efforts] } : {}),\n })\n }\n return models\n}\n\n/**\n * Swap one model with its neighbour. An id that is absent or a move past\n * either end returns the same order.\n * @param models - the current list.\n * @param id - the row to move.\n * @param delta - `-1` moves up, `1` moves down.\n * @returns a new list; the input array is not mutated.\n */\nexport function moveModel(\n models: readonly OllamaModelDraft[],\n id: string,\n delta: -1 | 1,\n): OllamaModelDraft[] {\n const next = [...models]\n const index = next.findIndex((model) => model.id === id)\n const target = index + delta\n if (index === -1 || target < 0 || target >= next.length) return next\n const moved = next[index]\n next[index] = next[target]\n next[target] = moved\n return next\n}\n\n/**\n * Drop one model from the list.\n * @param models - the current list.\n * @param id - the row to drop; an unknown id leaves the list unchanged.\n * @returns a new list; the input array is not mutated.\n */\nexport function removeModel(\n models: readonly OllamaModelDraft[],\n id: string,\n): OllamaModelDraft[] {\n return models.filter((model) => model.id !== id)\n}\n\n/**\n * Short context-window label for a model row.\n * @param contextWindow - the advertised window in tokens.\n * @returns `'1M'`, `'262K'`, the bare number below 1000, or `undefined` when unknown.\n */\nexport function contextLabel(\n contextWindow: number | undefined,\n): string | undefined {\n if (contextWindow === undefined) return undefined\n if (contextWindow < 1000) return String(contextWindow)\n if (contextWindow >= 1_000_000) {\n const millions = contextWindow / 1_000_000\n return `${Number.isInteger(millions) ? millions : Number(millions.toFixed(1))}M`\n }\n return `${Math.round(contextWindow / 1000)}K`\n}\n\n/**\n * Rename one model row. An empty display name deletes the field so the\n * validator keeps accepting the draft; a blank id leaves the list unchanged.\n * @param models - the current list.\n * @param id - the row to rename; an unknown id leaves the list unchanged.\n * @param name - the new display name; whitespace trims before storing.\n * @returns a new list; the input array is not mutated.\n */\nexport function renameModel(\n models: readonly OllamaModelDraft[],\n id: string,\n name: string,\n): OllamaModelDraft[] {\n return models.map((model) => {\n if (model.id !== id) return model\n const next = { ...model }\n if (name === '') delete next.name\n else next.name = name\n return next\n })\n}\n\n/**\n * Set or clear one model row's default reasoning effort. An empty choice\n * deletes the field so the resolver falls back to the vendor or family\n * default.\n * @param models - the current list.\n * @param id - the row to edit; an unknown id leaves the list unchanged.\n * @param effort - the chosen level, or `''` to clear.\n * @returns a new list; the input array is not mutated.\n */\nexport function setModelEffort(\n models: readonly OllamaModelDraft[],\n id: string,\n effort: string,\n): OllamaModelDraft[] {\n return models.map((model) => {\n if (model.id !== id) return model\n if (effort === '') {\n const next = { ...model }\n delete next.defaultEffort\n return next\n }\n return { ...model, defaultEffort: effort }\n })\n}\n\n/**\n * Set or clear one model row's local context-window override. `undefined`\n * deletes the field so the model follows the endpoint again; the runtime\n * caps a stored value at the advertised window.\n * @param models - the current list.\n * @param id - the row to edit; an unknown id leaves the list unchanged.\n * @param tokens - a positive safe integer, or `undefined` to clear.\n * @returns a new list; the input array is not mutated.\n */\nexport function setModelContext(\n models: readonly OllamaModelDraft[],\n id: string,\n tokens: number | undefined,\n): OllamaModelDraft[] {\n return models.map((model) => {\n if (model.id !== id) return model\n const next = { ...model }\n if (tokens === undefined) delete next.contextOverride\n else next.contextOverride = tokens\n return next\n })\n}\n\n/**\n * Parse the context input's text. Only a positive safe integer is a value;\n * an empty string clears the override.\n * @param text - what the user typed.\n * @returns the number, `undefined` for blank, or `null` for text to reject.\n */\nexport function parseContextInput(text: string): number | undefined | null {\n const trimmed = text.trim()\n if (trimmed === '') return undefined\n if (!/^\\d+$/.test(trimmed)) return null\n const value = Number(trimmed)\n return Number.isSafeInteger(value) && value > 0 ? value : null\n}\n\n/** Models the user unticked in this dialog, kept by id so a re-tick restores them. */\nexport type OllamaStash = ReadonlyMap<string, OllamaModelDraft>\n\n/**\n * Untick one model: drop it from the list and keep its full row (display\n * name, default effort, context, ...) in the stash so ticking it again is\n * lossless, even when the cloud listing no longer carries the id.\n * @param models - the current list.\n * @param stash - the stash before this untick.\n * @param id - the row to untick; an absent id changes nothing.\n * @returns the new list and stash; neither input is mutated.\n */\nexport function untickModel(\n models: readonly OllamaModelDraft[],\n stash: OllamaStash,\n id: string,\n): { models: OllamaModelDraft[]; stash: OllamaStash } {\n const row = models.find((model) => model.id === id)\n if (row === undefined) return { models: [...models], stash }\n return { models: removeModel(models, id), stash: new Map(stash).set(id, row) }\n}\n\n/**\n * Tick one model: restore its stashed row when this dialog unticked it,\n * otherwise adopt it from the fetched candidates (which never copies the\n * vendor default effort). A model already in the list, or unknown to both\n * sources, leaves the list unchanged.\n * @param models - the current list.\n * @param stash - rows unticked earlier in this dialog.\n * @param candidates - the cloud list as fetched.\n * @param id - the row to tick.\n * @returns a new list and the stash without the restored row.\n */\nexport function tickModel(\n models: readonly OllamaModelDraft[],\n stash: OllamaStash,\n candidates: readonly OllamaCloudCandidate[],\n id: string,\n): { models: OllamaModelDraft[]; stash: OllamaStash } {\n if (models.some((model) => model.id === id))\n return { models: [...models], stash }\n const stashed = stash.get(id)\n if (stashed === undefined)\n return { models: adoptCandidates(models, candidates, [id]), stash }\n const next = new Map(stash)\n next.delete(id)\n return { models: [...models, stashed], stash: next }\n}\n\n/**\n * Tick every listed id in order. Rows already in the list stay where they\n * are; restored and adopted rows append in the given order.\n * @param models - the current list.\n * @param stash - rows unticked earlier in this dialog.\n * @param candidates - the cloud list as fetched.\n * @param ids - the ids to tick, typically the filtered view.\n * @returns the new list and stash; neither input is mutated.\n */\nexport function tickModels(\n models: readonly OllamaModelDraft[],\n stash: OllamaStash,\n candidates: readonly OllamaCloudCandidate[],\n ids: readonly string[],\n): { models: OllamaModelDraft[]; stash: OllamaStash } {\n let state = { models: [...models], stash }\n for (const id of ids)\n state = tickModel(state.models, state.stash, candidates, id)\n return state\n}\n\n/**\n * Untick every listed id, stashing each removed row. Ids outside the list,\n * such as filtered-out rows, are untouched.\n * @param models - the current list.\n * @param stash - the stash before this untick.\n * @param ids - the ids to untick, typically the filtered view.\n * @returns the new list and stash; neither input is mutated.\n */\nexport function untickModels(\n models: readonly OllamaModelDraft[],\n stash: OllamaStash,\n ids: readonly string[],\n): { models: OllamaModelDraft[]; stash: OllamaStash } {\n let state = { models: [...models], stash }\n for (const id of ids) state = untickModel(state.models, state.stash, id)\n return state\n}\n\n/** One effort choice shown in a row's selector. */\nexport interface EffortOption {\n id: string\n name: string\n unavailable?: boolean\n}\n\n/**\n * The effort choices for one ticked row. The row's own `efforts` decide the\n * ids because the store rejects a default outside them, so the selector must\n * never offer anything else. A snapshot of the endpoint (`labels`) may only\n * supply friendlier names for the same ids. A saved default the list no\n * longer contains is kept visible and marked unavailable instead of\n * silently reading as \"follow the provider\".\n * @param row - the draft row.\n * @param fetched - efforts from this dialog's latest fetch, when it returned the row.\n * @param labels - the opened dialog's snapshot of named efforts for the id.\n * @returns the options in picker order.\n */\nexport function effortOptions(\n row: OllamaModelDraft,\n fetched: readonly string[] | undefined,\n labels: readonly { id: string; name: string }[] | undefined,\n): EffortOption[] {\n const ids = row.efforts ?? fetched ?? labels?.map((entry) => entry.id) ?? []\n const options: EffortOption[] = ids.map((id) => ({\n id,\n name: labels?.find((entry) => entry.id === id)?.name ?? id,\n }))\n if (row.defaultEffort !== undefined && !ids.includes(row.defaultEffort)) {\n options.push({\n id: row.defaultEffort,\n name: row.defaultEffort,\n unavailable: true,\n })\n }\n return options\n}\n","import { useEffect, useId, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { SubscriptionsSectionInjected } from './SubscriptionsSection.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport {\n contextLabel,\n effortOptions,\n moveModel,\n parseContextInput,\n renameModel,\n setModelContext,\n setModelEffort,\n tickModel,\n tickModels,\n untickModel,\n untickModels,\n} from './ollama-draft.js'\nimport type {\n OllamaCloudCandidate,\n OllamaModelDraft,\n OllamaSettingsDraft,\n OllamaSettingsView,\n OllamaStash,\n} from './ollama-draft.js'\nimport { subscriptionCardStyles as styles } from './subscription-card-styles.js'\nimport { providerSettingsCss } from './provider-settings-styles.js'\n\ntype Translate = SubscriptionsSectionInjected['t']\ninterface Props {\n rpc: ConnectionHandle['rpc']\n t: Translate\n onClose: () => void\n /** Called after a successful save or reset, so the card re-reads its status. */\n onSaved: () => void\n}\ninterface OllamaRow {\n id: string\n name: string\n /** In the draft list, so Save will keep it. */\n ticked: boolean\n vision: boolean\n thinking: boolean\n contextWindow?: number\n efforts: string[]\n}\nconst border = '0.5px solid var(--dsw-alias-border-l2)'\nconst stack: CSSProperties = { display: 'grid', gap: 12, minWidth: 0 }\nconst actions: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n alignItems: 'center',\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/** `vision · thinking · context 262K`, dropping whatever the model does not advertise. */\nfunction capabilities(\n t: Translate,\n model: { vision?: boolean; thinking?: boolean; contextWindow?: number },\n): string {\n const context = contextLabel(model.contextWindow)\n return [\n model.vision === true ? t('ollamaCapVision') : false,\n model.thinking === true ? t('ollamaCapThinking') : false,\n context === undefined ? false : t('ollamaContext', { tokens: context }),\n ]\n .filter(Boolean)\n .join(' · ')\n}\n\n/**\n * Ollama Cloud settings dialog. It owns one draft (model list, web toggle,\n * base URL and credential reference) that Save writes in a single\n * `ollamaSetSettings` call, so a failure keeps every edit. Fetching the cloud\n * catalog is a read-only side trip, and a key typed for the fetch never\n * leaves this component. The model list follows the shared model editor: a\n * filter, select all/none over the filtered rows, and one checkbox per\n * model, where ticking edits the draft and enables Save. Ollama adds what the\n * shared editor lacks: a display name, ordering, and a local context window.\n * Unticking keeps the row's full settings in a dialog-local stash, so ticking\n * it again restores them even when the cloud listing no longer returns it.\n */\nexport function OllamaSettingsManager({ rpc, t, onClose, onSaved }: Props) {\n const dialog = useRef<HTMLDialogElement>(null)\n const title = useId()\n const description = useId()\n const [view, setView] = useState<OllamaSettingsView>()\n const [draft, setDraft] = useState<OllamaSettingsDraft>({})\n const [dirty, setDirty] = useState(false)\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState('')\n const [saveError, setSaveError] = useState('')\n const [attempt, setAttempt] = useState(0)\n const [apiKey, setApiKey] = useState('')\n const [candidates, setCandidates] = useState<OllamaCloudCandidate[]>()\n const [fetching, setFetching] = useState(false)\n const [fetchError, setFetchError] = useState('')\n const [query, setQuery] = useState('')\n const [expanded, setExpanded] = useState<Set<string>>(new Set())\n const [stash, setStash] = useState<OllamaStash>(new Map())\n const [contextText, setContextText] = useState<Record<string, string>>({})\n const alive = useRef(true)\n const saveLock = useRef(false)\n const fetchLock = useRef(false)\n\n useEffect(() => {\n alive.current = true\n const element = dialog.current!\n const previous = document.activeElement\n element.showModal()\n return () => {\n alive.current = false\n element.close()\n if (previous instanceof HTMLElement && previous.isConnected)\n previous.focus()\n }\n }, [])\n useEffect(() => {\n let current = true\n setLoading(true)\n setError('')\n void callSubscriptionsAuth<OllamaSettingsView>(rpc, 'ollamaSettings', {})\n .then((data) => {\n if (!current) return\n setView(data)\n // An unset store value inherits the deployed config: the checkbox\n // shows the effective state, and ticking it writes the override.\n setDraft({ ...data.settings })\n setStash(new Map())\n setContextText({})\n setDirty(false)\n })\n .catch((failure) => {\n if (current)\n setError(t('ollamaModelsLoadFailed', { message: message(failure) }))\n })\n .finally(() => {\n if (current) setLoading(false)\n })\n return () => {\n current = false\n }\n // `t` only formats the load error. A new translator must not refetch.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- refetch on rpc and attempt only\n }, [rpc, attempt])\n\n function edit(next: OllamaSettingsDraft) {\n setDraft(next)\n setDirty(true)\n }\n\n /** Fetch the cloud catalog; a failure keeps the previous list and the draft. */\n async function fetchCandidates() {\n if (fetchLock.current) return\n fetchLock.current = true\n setFetching(true)\n setFetchError('')\n try {\n const value = await callSubscriptionsAuth<{\n models: OllamaCloudCandidate[]\n }>(rpc, 'ollamaModels', {\n ...(apiKey ? { apiKey } : {}),\n ...(draft.baseURL ? { baseURL: draft.baseURL } : {}),\n })\n if (!alive.current) return\n setCandidates(value.models)\n } catch (failure) {\n if (alive.current)\n setFetchError(t('ollamaFetchFailed', { message: message(failure) }))\n } finally {\n fetchLock.current = false\n if (alive.current) setFetching(false)\n }\n }\n\n /** Save the whole draft; a failure keeps the dialog open with every edit. */\n async function save() {\n if (saveLock.current) return\n saveLock.current = true\n setSaving(true)\n setSaveError('')\n try {\n await callSubscriptionsAuth(rpc, 'ollamaSetSettings', { settings: draft })\n if (alive.current) {\n onSaved()\n onClose()\n }\n } catch (failure) {\n if (alive.current)\n setSaveError(t('ollamaModelsSaveFailed', { message: message(failure) }))\n } finally {\n saveLock.current = false\n if (alive.current) setSaving(false)\n }\n }\n\n /** Drop every stored override, then reload the draft from the deployment values. */\n async function resetDefaults() {\n if (saveLock.current) return\n if (!window.confirm(t('ollamaResetConfirm'))) return\n saveLock.current = true\n setSaving(true)\n setSaveError('')\n try {\n await callSubscriptionsAuth(rpc, 'ollamaSetSettings', { settings: {} })\n if (alive.current) {\n setAttempt((value) => value + 1)\n onSaved()\n }\n } catch (failure) {\n if (alive.current)\n setSaveError(t('ollamaModelsSaveFailed', { message: message(failure) }))\n } finally {\n saveLock.current = false\n if (alive.current) setSaving(false)\n }\n }\n\n function editOverride(field: 'baseURL' | 'apiKeyRef', value: string) {\n const next = { ...draft }\n if (value.trim()) next[field] = value\n else delete next[field]\n edit(next)\n }\n\n /**\n * One list for both sources, like the shared editor: the ticked models in\n * draft order first (so Move up/down is visible), then the unticked ones\n * (stashed in this dialog, or fetched and not yet adopted). A kept model\n * the fetch did not return stays listed, ticked or not.\n */\n const fetchedById = new Map(\n (candidates ?? []).map((candidate) => [candidate.id, candidate]),\n )\n const present = new Set((draft.models ?? []).map((model) => model.id))\n const asRow = (model: OllamaModelDraft, ticked: boolean): OllamaRow => {\n const fetched = fetchedById.get(model.id)\n // The latest fetch outranks the stored snapshot, matching the runtime:\n // discovery is the ceiling and the snapshot only stands in without it.\n const contextWindow = fetched?.contextWindow ?? model.contextWindow\n return {\n id: model.id,\n name: model.name ?? fetched?.name ?? model.id,\n ticked,\n vision: model.vision === true || fetched?.vision === true,\n thinking: model.thinking === true || fetched?.thinking === true,\n ...(contextWindow === undefined ? {} : { contextWindow }),\n efforts: model.efforts ?? fetched?.efforts ?? [],\n }\n }\n const rows: OllamaRow[] = [\n ...(draft.models ?? []).map((model) => asRow(model, true)),\n ...[...stash.values()]\n .filter((model) => !present.has(model.id))\n .map((model) => asRow(model, false)),\n ...(candidates ?? [])\n .filter(\n (candidate) => !present.has(candidate.id) && !stash.has(candidate.id),\n )\n .map((candidate) => asRow({ id: candidate.id }, false)),\n ]\n const shown = rows.filter((row) =>\n `${row.name} ${row.id}`.toLowerCase().includes(query.trim().toLowerCase()),\n )\n\n /** Rename and default-effort edits ride the tested draft helpers. */\n function rename(id: string, name: string): void {\n edit({ ...draft, models: renameModel(draft.models ?? [], id, name) })\n }\n function setEffort(id: string, effort: string): void {\n edit({ ...draft, models: setModelEffort(draft.models ?? [], id, effort) })\n }\n /** Keep the typed text; only a valid number (or blank) reaches the draft. */\n function setContext(id: string, text: string): void {\n setContextText((current) => ({ ...current, [id]: text }))\n const tokens = parseContextInput(text)\n if (tokens !== null)\n edit({\n ...draft,\n models: setModelContext(draft.models ?? [], id, tokens),\n })\n }\n function applyTicks(next: {\n models: OllamaModelDraft[]\n stash: OllamaStash\n }): void {\n setStash(next.stash)\n edit({ ...draft, models: next.models })\n }\n const invalidContext = Object.entries(contextText)\n .filter(([id, text]) => present.has(id) && parseContextInput(text) === null)\n .map(([id]) => id)\n return (\n <dialog\n className=\"dsh-subscription-manager\"\n ref={dialog}\n aria-labelledby={title}\n aria-describedby={description}\n onCancel={(event) => {\n if (saveLock.current) event.preventDefault()\n }}\n onClose={onClose}\n style={{\n width: 620,\n maxWidth: 'calc(100vw - 32px)',\n maxHeight: 'calc(100dvh - 32px)',\n overflow: 'auto',\n }}\n >\n <style>{providerSettingsCss}</style>\n <div style={{ ...stack, padding: 20 }}>\n <header style={{ ...actions, justifyContent: 'space-between' }}>\n <h2 id={title} style={{ margin: 0 }}>\n {t('ollamaManageTitle')}\n </h2>\n <button type=\"button\" autoFocus disabled={saving} onClick={onClose}>\n {t('imageClose')}\n </button>\n </header>\n <p id={description} className=\"dsh-subscription-hint\">\n {t('ollamaManageHint')}\n </p>\n {view?.configOverridesModels === true && (\n <p className=\"dsh-subscription-hint\">{t('ollamaCatalogOverride')}</p>\n )}\n {error && <p role=\"alert\">{error}</p>}\n {loading && (\n <p role=\"status\" className=\"dsh-subscription-hint\">\n {t('modelDefaultsLoading')}\n </p>\n )}\n {!loading && !view && (\n <button\n type=\"button\"\n onClick={() => setAttempt((value) => value + 1)}\n >\n {t('modelDefaultsRetry')}\n </button>\n )}\n {view && (\n <fieldset\n disabled={saving}\n style={{ ...stack, border: 0, margin: 0, padding: 0, minWidth: 0 }}\n >\n <div\n style={{\n borderTop: border,\n paddingTop: 12,\n display: 'grid',\n gap: 12,\n }}\n >\n <h3 style={{ margin: 0 }}>{t('modelsEdit')}</h3>\n <div style={actions}>\n <input\n type=\"password\"\n autoComplete=\"off\"\n style={{ flex: '1 1 180px' }}\n aria-label={t('ollamaKeyPlaceholder')}\n placeholder={t('ollamaKeyPlaceholder')}\n value={apiKey}\n onChange={(event) => setApiKey(event.target.value)}\n />\n <button\n type=\"button\"\n className=\"dsh-subscription-quiet\"\n disabled={fetching}\n onClick={() => {\n void fetchCandidates()\n }}\n >\n {fetching ? t('ollamaFetching') : t('ollamaFetch')}\n </button>\n {candidates !== undefined && (\n <span className=\"dsh-subscription-hint\">\n {t('ollamaCandidatesCount', { count: candidates.length })}\n </span>\n )}\n </div>\n <p className=\"dsh-subscription-hint\">{t('ollamaKeyHint')}</p>\n {fetchError && <p role=\"alert\">{fetchError}</p>}\n {candidates?.length === 0 && (\n <p className=\"dsh-subscription-hint\">\n {t('ollamaCandidatesEmpty')}\n </p>\n )}\n <div style={actions}>\n <input\n style={{ flex: '1 1 180px' }}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder={t('modelDefaultsFilterPlaceholder')}\n aria-label={t('modelDefaultsFilterPlaceholder')}\n />\n <button\n type=\"button\"\n onClick={() =>\n applyTicks(\n tickModels(\n draft.models ?? [],\n stash,\n candidates ?? [],\n shown.map((row) => row.id),\n ),\n )\n }\n >\n {t('modelsSelectAll')}\n </button>\n <button\n type=\"button\"\n onClick={() =>\n applyTicks(\n untickModels(\n draft.models ?? [],\n stash,\n shown.map((row) => row.id),\n ),\n )\n }\n >\n {t('modelsSelectNone')}\n </button>\n </div>\n <div\n style={{\n maxHeight: 360,\n overflowY: 'auto',\n display: 'grid',\n gap: 8,\n }}\n >\n {shown.map((row) => {\n const stored = (draft.models ?? []).find(\n (entry) => entry.id === row.id,\n )\n const index = (draft.models ?? []).findIndex(\n (entry) => entry.id === row.id,\n )\n const open = expanded.has(row.id)\n const details = `${row.id}-details`\n const efforts =\n stored === undefined\n ? []\n : effortOptions(\n stored,\n fetchedById.get(row.id)?.efforts,\n view.models.find((entry) => entry.id === row.id)\n ?.efforts,\n )\n const contextProblem = invalidContext.includes(row.id)\n return (\n <div\n key={row.id}\n style={{\n borderBottom: border,\n padding: '8px 2px',\n display: 'grid',\n gap: 8,\n }}\n >\n <label style={{ overflowWrap: 'anywhere' }}>\n <input\n type=\"checkbox\"\n checked={row.ticked}\n onChange={(event) => {\n applyTicks(\n event.target.checked\n ? tickModel(\n draft.models ?? [],\n stash,\n candidates ?? [],\n row.id,\n )\n : untickModel(\n draft.models ?? [],\n stash,\n row.id,\n ),\n )\n }}\n />{' '}\n {row.name}{' '}\n <span style={styles.status}>\n {capabilities(t, row)}\n </span>\n </label>\n {stored !== undefined && (\n <div style={actions}>\n {row.thinking && efforts.length > 0 && (\n <label style={actions}>\n {t('modelDefaultsTitle')}\n <select\n aria-label={`${row.name} ${t('modelDefaultsTitle')}`}\n value={stored.defaultEffort ?? ''}\n onChange={(event) =>\n setEffort(row.id, event.target.value)\n }\n >\n <option value=\"\">\n {t('modelDefaultsFollowProvider')}\n </option>\n {efforts.map((effort) => (\n <option\n key={effort.id}\n value={effort.id}\n disabled={effort.unavailable === true}\n >\n {effort.unavailable === true\n ? `${effort.name} (${t('modelsUnavailable')})`\n : effort.name}\n </option>\n ))}\n </select>\n </label>\n )}\n {row.thinking && efforts.length === 0 && (\n <small>{t('ollamaEffortsUnknown')}</small>\n )}\n <label style={actions}>\n {t('modelsContext')}\n <input\n style={{ width: 140 }}\n inputMode=\"numeric\"\n aria-invalid={contextProblem}\n value={\n contextText[row.id] ??\n (stored.contextOverride === undefined\n ? ''\n : String(stored.contextOverride))\n }\n aria-label={`${row.name} ${t('modelsContext')}`}\n placeholder={\n row.contextWindow === undefined\n ? ''\n : String(row.contextWindow)\n }\n onChange={(event) =>\n setContext(row.id, event.target.value)\n }\n />\n </label>\n {row.contextWindow !== undefined && (\n <small>\n {t('modelsContextBounds', {\n default: row.contextWindow,\n max: row.contextWindow,\n })}\n </small>\n )}\n <button\n type=\"button\"\n className=\"dsh-subscription-quiet\"\n aria-expanded={open}\n aria-controls={details}\n aria-label={`${row.name} ${t('ollamaRowDetails')}`}\n onClick={() => {\n const next = new Set(expanded)\n if (open) next.delete(row.id)\n else next.add(row.id)\n setExpanded(next)\n }}\n >\n {t('ollamaRowDetails')} {open ? '\\u25BE' : '\\u25B8'}\n </button>\n </div>\n )}\n {contextProblem && (\n <p role=\"alert\">\n {t('modelsContextInvalid', { model: row.name })}\n </p>\n )}\n {stored !== undefined && open && (\n <div id={details} style={actions}>\n <label style={actions}>\n {t('ollamaDisplayName')}\n <input\n value={stored.name ?? ''}\n placeholder={row.id}\n aria-label={`${row.name} ${t('ollamaDisplayName')}`}\n onChange={(event) =>\n rename(row.id, event.target.value)\n }\n onBlur={(event) =>\n rename(row.id, event.target.value.trim())\n }\n />\n </label>\n <button\n type=\"button\"\n disabled={index === 0}\n aria-label={`${row.name} ${t('ollamaMoveUp')}`}\n onClick={() =>\n edit({\n ...draft,\n models: moveModel(\n draft.models ?? [],\n row.id,\n -1,\n ),\n })\n }\n >\n {t('ollamaMoveUp')}\n </button>\n <button\n type=\"button\"\n disabled={index === (draft.models ?? []).length - 1}\n aria-label={`${row.name} ${t('ollamaMoveDown')}`}\n onClick={() =>\n edit({\n ...draft,\n models: moveModel(\n draft.models ?? [],\n row.id,\n 1,\n ),\n })\n }\n >\n {t('ollamaMoveDown')}\n </button>\n </div>\n )}\n </div>\n )\n })}\n {shown.length === 0 && (\n <span className=\"dsh-subscription-hint\">\n {query.trim()\n ? t('modelDefaultsFilterEmpty', { query })\n : t('ollamaModelsEmpty')}\n </span>\n )}\n </div>\n <small>{t('modelsContextHint')}</small>\n </div>\n <label style={{ ...stack, gap: 6 }}>\n <span className=\"dsh-subscription-label\">\n {t('ollamaBaseURL')}\n </span>\n <input\n value={draft.baseURL ?? ''}\n placeholder={view.effective.baseURL}\n onChange={(event) =>\n editOverride('baseURL', event.target.value)\n }\n />\n </label>\n <label style={{ ...stack, gap: 6 }}>\n <span className=\"dsh-subscription-label\">\n {t('ollamaApiKeyRef')}\n </span>\n <input\n value={draft.apiKeyRef ?? ''}\n placeholder={view.effective.apiKeyRef}\n onChange={(event) =>\n editOverride('apiKeyRef', event.target.value)\n }\n />\n </label>\n <p className=\"dsh-subscription-hint\">{t('ollamaConnectionHint')}</p>\n <label>\n <input\n type=\"checkbox\"\n checked={(draft.web ?? view.effective.web) === true}\n onChange={(event) =>\n edit({ ...draft, web: event.target.checked })\n }\n />{' '}\n {t('modelsWebSearch')}\n </label>\n <p className=\"dsh-subscription-hint\">{t('ollamaWebHint')}</p>\n </fieldset>\n )}\n <footer\n style={{\n ...stack,\n gap: 8,\n borderTop: border,\n padding: '14px 0 8px',\n position: 'sticky',\n bottom: 0,\n background:\n 'var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1))',\n }}\n >\n {saveError && <p role=\"alert\">{saveError}</p>}\n <div style={{ ...actions, justifyContent: 'flex-end' }}>\n <button\n type=\"button\"\n style={{ marginRight: 'auto' }}\n disabled={loading || saving}\n onClick={() => {\n void resetDefaults()\n }}\n >\n {t('ollamaResetDefaults')}\n </button>\n <button type=\"button\" disabled={saving} onClick={onClose}>\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n className=\"dsh-subscription-primary\"\n disabled={\n loading || saving || !dirty || invalidContext.length > 0\n }\n onClick={() => {\n void save()\n }}\n >\n {saving ? t('modelDefaultsSaving') : t('modelsSave')}\n </button>\n </div>\n </footer>\n </div>\n </dialog>\n )\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {\n ProviderUsage,\n SubscriptionsSectionInjected,\n} from './SubscriptionsSection.js'\nimport type { OllamaSettingsView } from './ollama-draft.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { externalUsageWindowLabel } from './ExternalUsageCards.js'\nimport { OllamaSettingsManager } from './OllamaSettingsManager.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { subscriptionCardStyles as styles } from './subscription-card-styles.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\n\ntype Translate = SubscriptionsSectionInjected['t']\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Ollama Cloud route card: the catalog the model picker shows, the web\n * capability toggle, and the API-key usage row. The settings dialog owns\n * every write; the card only reads, so a save is reflected by re-reading.\n */\nexport function OllamaCard({\n rpc,\n t,\n}: {\n rpc: ConnectionHandle['rpc']\n t: Translate\n}) {\n const [view, setView] = useState<OllamaSettingsView>()\n const [configured, setConfigured] = useState<boolean>()\n const [usage, setUsage] = useState<ProviderUsage>()\n const [observedAt, setObservedAt] = useState<number>()\n const [usageStale, setUsageStale] = useState(false)\n const [loading, setLoading] = useState(false)\n // Two failure surfaces: the card's own load and the usage lookup. They\n // render in different places so a stale usage reading cannot masquerade as\n // a settings failure.\n const [statusError, setStatusError] = useState<string>()\n const [usageError, setUsageError] = useState<string>()\n const [manage, setManage] = useState(false)\n\n const refreshUsage = useCallback(async () => {\n setLoading(true)\n try {\n const value = await callSubscriptionsAuth<ProviderUsage>(\n rpc,\n 'externalUsage',\n { source: 'ollama-cloud' },\n )\n setUsage(value)\n // Prefer the server's observation time; a cached reading must not look fresh.\n setObservedAt(value.observedAt ?? Date.now())\n setUsageStale(value.stale === true)\n setUsageError(undefined)\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n } catch (failure) {\n setUsageError(message(failure))\n setUsageStale(true)\n } finally {\n setLoading(false)\n }\n }, [rpc])\n\n const refreshStatus = useCallback(async () => {\n try {\n const [settings, status] = await Promise.all([\n callSubscriptionsAuth<OllamaSettingsView>(rpc, 'ollamaSettings', {}),\n callSubscriptionsAuth<Record<string, { configured: boolean }>>(\n rpc,\n 'externalStatus',\n {},\n ),\n ])\n setView(settings)\n setStatusError(undefined)\n const isConfigured = status['ollama-cloud']?.configured === true\n setConfigured(isConfigured)\n if (isConfigured) void refreshUsage()\n } catch (failure) {\n setStatusError(message(failure))\n }\n }, [rpc, refreshUsage])\n\n useEffect(() => {\n void refreshStatus()\n }, [refreshStatus])\n\n return (\n <div style={styles.card}>\n <div style={styles.header}>\n <span\n style={{\n ...styles.dot,\n background:\n configured === true\n ? 'var(--dsw-alias-state-success-primary)'\n : 'var(--dsw-alias-label-dimmed)',\n }}\n />\n <span style={styles.name}>{t('ollamaTitle')}</span>\n </div>\n <p style={styles.status}>\n {view === undefined\n ? t('checking')\n : view.models.length > 0\n ? t('ollamaStatus', { count: view.models.length })\n : t('ollamaStatusNone')}\n </p>\n {view !== undefined && (\n <p style={styles.status}>\n {view.effective.web ? t('ollamaWebOn') : t('ollamaWebOff')}\n </p>\n )}\n {statusError !== undefined && (\n <p style={styles.error}>\n {t('ollamaModelsLoadFailed', { message: statusError })}\n </p>\n )}\n {view !== undefined && configured === false && (\n <p style={styles.status}>\n {t('ollamaConfigureHint', { ref: view.effective.apiKeyRef })}\n </p>\n )}\n {configured === true && (\n <div style={styles.account}>\n <div style={styles.accountHeader}>\n <span style={styles.defaultStar} title={t('defaultBadge')}>\n ★\n </span>\n <span style={styles.accountName}>{t('externalUsageApiKey')}</span>\n </div>\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {usage?.plan !== undefined && (\n <span style={styles.usagePlan}>\n {t('usagePlan', { plan: usage.plan })}\n </span>\n )}\n <button\n type=\"button\"\n style={styles.usageRefresh}\n disabled={loading}\n onClick={() => {\n void refreshUsage()\n }}\n >\n {t('usageRefresh')}\n </button>\n </div>\n {loading && usage === undefined && (\n <p style={styles.status}>{t('usageLoading')}</p>\n )}\n {usageError !== undefined && (\n <p style={styles.error}>\n {t('usageError', { message: usageError })}\n </p>\n )}\n {usage !== undefined && usage.supported === false && (\n <p style={styles.status}>{t('usageUnsupported')}</p>\n )}\n {usage?.windows?.length === 0 && (\n <p style={styles.status}>{t('usageEmpty')}</p>\n )}\n {usage?.windows?.map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n const label = externalUsageWindowLabel(t, window)\n return (\n <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{label}</span>\n <span>\n {percent === undefined\n ? t('usageMeterInvalid')\n : `${percent}%`}\n {window.resetsAt === undefined\n ? ''\n : ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}\n </span>\n </div>\n <UsageMeter\n window={window}\n t={t}\n observedAt={observedAt}\n stale={usageStale}\n />\n </div>\n )\n })}\n </div>\n </div>\n )}\n {view?.configOverridesModels === true && (\n <p style={styles.status}>{t('ollamaCatalogOverride')}</p>\n )}\n <div style={styles.actions}>\n <button\n type=\"button\"\n style={styles.button}\n aria-haspopup=\"dialog\"\n onClick={() => setManage(true)}\n >\n {t('accountsManage')}\n </button>\n {configured !== true && (\n <button\n type=\"button\"\n style={styles.button}\n onClick={() => {\n void refreshStatus()\n }}\n >\n {t('usageRefresh')}\n </button>\n )}\n </div>\n {manage && (\n <OllamaSettingsManager\n rpc={rpc}\n t={t}\n onClose={() => setManage(false)}\n onSaved={() => {\n void refreshStatus()\n }}\n />\n )}\n </div>\n )\n}\n","/**\n * Shared usage-limit-reset disclosure.\n *\n * Codex and Claude use the same closed `<details>` row. Codex may offer Use\n * on the earliest unexpired credit. Claude is read-only: `claimable` is\n * server metadata and never becomes a control. `expiresAt` is when the grant\n * expires, not a window reset, so it is never passed to the elapsed-time\n * cursor.\n */\nimport type { SubscriptionsKey } from './locales.js'\nimport { subscriptionCardStyles as cardStyles } from './subscription-card-styles.js'\nimport type {\n ResetCreditView,\n SubscriptionsSectionInjected,\n} from './SubscriptionsSection.js'\n\ntype Translate = SubscriptionsSectionInjected['t']\n\n/** How one grant reads. Color is not the only carrier; the state word is in the row name. */\nexport type ResetCreditState =\n 'available' | 'notUsable' | 'paused' | 'exhausted' | 'expired'\n\nconst STATE_KEYS: Record<ResetCreditState, SubscriptionsKey> = {\n available: 'resetCreditAvailable',\n notUsable: 'resetCreditNotUsable',\n paused: 'resetCreditPaused',\n exhausted: 'resetCreditExhausted',\n expired: 'resetCreditExpired',\n}\n\n/**\n * Classify one grant. Expired outranks every other flag. A future\n * `cooldownUntil` or `usableNow: false` is not usable even when `claimable`\n * is true. `claimable` does not change the word: it is not an action.\n */\nexport function resetCreditState(\n credit: ResetCreditView,\n now: number,\n): ResetCreditState {\n if (credit.expiresAt !== undefined && credit.expiresAt <= now)\n return 'expired'\n if (credit.paused === true) return 'paused'\n if (credit.resetsLeft === 0) return 'exhausted'\n if (\n (credit.cooldownUntil !== undefined && credit.cooldownUntil > now) ||\n credit.usableNow === false\n )\n return 'notUsable'\n return 'available'\n}\n\n/**\n * Headline count. Codex passes one entry per credit, so the count is the\n * list length. Claude passes one entry per grant, so the count is the sum of\n * `resetsLeft` on grants that are neither expired nor paused. A missing\n * `resetsLeft` adds nothing; the row says the count is unavailable.\n */\nexport function resetCreditsAvailableCount(\n credits: readonly ResetCreditView[],\n now: number,\n mode: 'credits' | 'grants',\n): number {\n if (mode === 'credits') return credits.length\n let sum = 0\n for (const credit of credits) {\n const state = resetCreditState(credit, now)\n if (state === 'expired' || state === 'paused') continue\n if (\n typeof credit.resetsLeft === 'number' &&\n Number.isFinite(credit.resetsLeft) &&\n credit.resetsLeft > 0\n ) {\n sum += credit.resetsLeft\n }\n }\n return sum\n}\n\n/** Codex Use control. Absent for Claude, which must not render a button. */\nexport interface ResetCreditUseAction {\n accountKey: string\n busy: boolean\n disabled: boolean\n title: string\n label: string\n onUse: () => void\n}\n\nfunction expiryText(t: Translate, credit: ResetCreditView): string {\n return credit.expiresAt === undefined\n ? t('resetCreditExpiryUnknown')\n : t('resetCreditExpires', {\n date: new Date(credit.expiresAt).toLocaleString(),\n })\n}\n\nfunction remainingText(t: Translate, credit: ResetCreditView): string {\n const left = credit.resetsLeft\n const total = credit.resetsTotal\n const hasLeft = typeof left === 'number' && Number.isFinite(left)\n const hasTotal = typeof total === 'number' && Number.isFinite(total)\n if (hasLeft && hasTotal) return t('resetCreditRemaining', { left, total })\n if (hasLeft) return t('resetCreditLeft', { left })\n return t('resetCreditRemainingUnknown')\n}\n\n/** Accessible name of one Claude grant row: state, remaining, and expiry, not a control name. */\nexport function resetCreditRowName(\n t: Translate,\n credit: ResetCreditView,\n now: number,\n): string {\n const state = resetCreditState(credit, now)\n const parts = [\n t('resetCreditFull'),\n t(STATE_KEYS[state]),\n remainingText(t, credit),\n expiryText(t, credit),\n ]\n if (\n state === 'notUsable' &&\n credit.cooldownUntil !== undefined &&\n credit.cooldownUntil > now\n ) {\n parts.push(\n t('resetCreditCooldownUntil', {\n date: new Date(credit.cooldownUntil).toLocaleString(),\n }),\n )\n }\n return parts.join(', ')\n}\n\n/** Claude omits an empty grant list; Codex still shows a defined, possibly empty, list. */\nexport function showsResetCredits(\n provider: 'codex' | 'claude',\n credits: readonly ResetCreditView[] | undefined,\n): boolean {\n if (provider === 'codex') return credits !== undefined\n return (credits?.length ?? 0) > 0\n}\n\n/** The error line the settings card mounts. Claude never interpolates provider text. */\nexport function ResetCreditsErrorLine({\n provider,\n message,\n t,\n}: {\n provider: 'codex' | 'claude'\n message: string\n t: Translate\n}) {\n return (\n <p style={cardStyles.error}>\n {resetCreditsErrorText(provider, message, t)}\n </p>\n )\n}\n\n/** Fixed sentence for Claude. Codex may include the lookup message; Claude must not. */\nexport function resetCreditsErrorText(\n provider: 'codex' | 'claude',\n message: string,\n t: Translate,\n): string {\n return provider === 'claude'\n ? t('resetCreditsErrorFixed')\n : t('resetCreditsError', { message })\n}\n\nconst summaryStyle = {\n ...cardStyles.usageMeta,\n cursor: 'pointer',\n listStyle: 'none',\n justifyContent: 'flex-start',\n gap: 6,\n} as const\n\n/**\n * The closed disclosure both providers share. Claude rows are plain text:\n * no button, no `role=\"button\"`, and `cursor: default`, including when\n * `claimable` is true.\n */\nexport function ResetCreditsDisclosure({\n mode,\n credits,\n t,\n now = Date.now(),\n nextCredit,\n useAction,\n statusMessage,\n}: {\n mode: 'credits' | 'grants'\n credits: readonly ResetCreditView[]\n t: Translate\n now?: number\n nextCredit?: ResetCreditView\n useAction?: ResetCreditUseAction\n statusMessage?: string\n}) {\n const count = resetCreditsAvailableCount(credits, now, mode)\n return (\n <details\n className=\"subscriptions-reset-credits\"\n style={cardStyles.usageRow}\n >\n <summary style={summaryStyle}>\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 16 16\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"m6 3 5 5-5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span>{t('resetCreditsTitle')}</span>\n {mode === 'grants' && <span>{t('resetCreditReadOnlyLabel')}</span>}\n <span style={{ marginLeft: 'auto' }}>\n {t('resetCreditsAvailable', { count })}\n </span>\n </summary>\n <style>\n {'.subscriptions-reset-credits > summary::-webkit-details-marker { display: none; }' +\n '.subscriptions-reset-credits[open] > summary > svg { transform: rotate(90deg); }'}\n </style>\n <div style={{ paddingLeft: 18, marginTop: 6 }}>\n {mode === 'grants' && (\n <p style={cardStyles.status}>{t('resetCreditReadOnly')}</p>\n )}\n {credits.map((credit, index) => {\n const state = resetCreditState(credit, now)\n const showUse =\n mode === 'credits' &&\n useAction !== undefined &&\n credit === nextCredit\n return (\n <div\n key={credit.id ?? index}\n data-reset-state={mode === 'grants' ? state : undefined}\n data-reset-claimable={\n mode === 'grants' && credit.claimable === true\n ? 'true'\n : undefined\n }\n role={mode === 'grants' ? 'group' : undefined}\n aria-label={\n mode === 'grants'\n ? resetCreditRowName(t, credit, now)\n : undefined\n }\n style={{\n ...cardStyles.usageMeta,\n minHeight: 28,\n gap: 12,\n cursor: mode === 'grants' ? 'default' : undefined,\n }}\n >\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n flexShrink: 0,\n }}\n >\n {t('resetCreditFull')}\n {mode === 'grants' && (\n <span aria-hidden=\"true\" data-reset-state-word={state}>\n {t(STATE_KEYS[state])}\n </span>\n )}\n {showUse && (\n <button\n type=\"button\"\n aria-disabled={useAction.disabled}\n title={useAction.title}\n style={{\n minHeight: 22,\n height: 22,\n padding: '0 7px',\n borderRadius: 6,\n opacity: useAction.disabled ? 0.35 : 1,\n cursor: useAction.disabled ? 'not-allowed' : 'pointer',\n }}\n onClick={() => {\n if (!useAction.disabled) useAction.onUse()\n }}\n >\n {useAction.busy ? t('resetUseChecking') : useAction.label}\n </button>\n )}\n </span>\n <span style={{ textAlign: 'right' }}>\n {mode === 'grants' && (\n <span aria-hidden=\"true\">{remainingText(t, credit)} · </span>\n )}\n {mode === 'grants' &&\n state === 'notUsable' &&\n credit.cooldownUntil !== undefined &&\n credit.cooldownUntil > now && (\n <span aria-hidden=\"true\">\n {t('resetCreditCooldownUntil', {\n date: new Date(credit.cooldownUntil).toLocaleString(),\n })}{' '}\n ·{' '}\n </span>\n )}\n <span aria-hidden={mode === 'grants' ? true : undefined}>\n {expiryText(t, credit)}\n </span>\n </span>\n </div>\n )\n })}\n {statusMessage !== undefined && statusMessage !== '' && (\n <p role=\"status\" style={cardStyles.status}>\n {statusMessage}\n </p>\n )}\n </div>\n </details>\n )\n}\n","import { useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { SubscriptionsKey } from './locales.js'\nimport {\n setUsageBadgeMode,\n useUsageBadgeMode,\n} from './usage-badge-preferences.js'\nimport {\n isUsageColorPreset,\n setUsageColorPreset,\n useUsageColorPreset,\n} from './usage-color-preferences.js'\n\ntype Translate = (\n key: SubscriptionsKey,\n params?: Record<string, unknown>,\n) => string\n\n/** Browser-local display preference; never changes provider or account settings. */\nexport function UsageBadgeDisplaySetting({ t }: { t: Translate }) {\n const mode = useUsageBadgeMode()\n const preset = useUsageColorPreset()\n const [failed, setFailed] = useState(false)\n return (\n <div style={styles.card}>\n <label style={styles.field}>\n <span>{t('usageBadgeDisplay')}</span>\n <select\n style={styles.select}\n aria-label={t('usageBadgeDisplay')}\n value={mode}\n onChange={(event) => {\n const value = event.currentTarget.value\n if (value !== 'recent' && value !== 'always' && value !== 'hidden')\n return\n try {\n setUsageBadgeMode(value)\n setFailed(false)\n } catch (error) {\n if (\n !(error instanceof DOMException) ||\n !['SecurityError', 'QuotaExceededError'].includes(error.name)\n )\n throw error\n setFailed(true)\n }\n }}\n >\n <option value=\"recent\">{t('usageBadgeDisplayRecent')}</option>\n <option value=\"always\">{t('usageBadgeDisplayAlways')}</option>\n <option value=\"hidden\">{t('usageBadgeDisplayHidden')}</option>\n </select>\n </label>\n <p style={styles.hint}>{t('usageBadgeDisplayHint')}</p>\n <label style={styles.field}>\n <span>{t('usageColorLabel')}</span>\n <select\n style={styles.select}\n aria-label={t('usageColorLabel')}\n value={preset}\n onChange={(event) => {\n const value = event.currentTarget.value\n if (!isUsageColorPreset(value)) return\n try {\n setUsageColorPreset(value)\n setFailed(false)\n } catch (error) {\n if (\n !(error instanceof DOMException) ||\n !['SecurityError', 'QuotaExceededError'].includes(error.name)\n )\n throw error\n setFailed(true)\n }\n }}\n >\n <option value=\"standard\">{t('usageColorStandard')}</option>\n <option value=\"relaxed\">{t('usageColorRelaxed')}</option>\n <option value=\"remaining\">{t('usageColorRemaining')}</option>\n </select>\n </label>\n <p style={styles.hint}>\n {t(\n preset === 'remaining'\n ? 'usageColorRemainingHint'\n : 'usageColorPaceHint',\n {\n allowance: preset === 'relaxed' ? 15 : 10,\n },\n )}\n </p>\n {failed && (\n <p\n role=\"alert\"\n style={{\n ...styles.hint,\n color: 'var(--dsw-alias-state-error-primary)',\n }}\n >\n {t('usageBadgeDisplaySaveFailed')}\n </p>\n )}\n </div>\n )\n}\n\nconst styles: Record<string, CSSProperties> = {\n card: {\n border:\n '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',\n borderRadius: 'var(--dsw-radius-xl, 20px)',\n background:\n 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',\n padding: '12px 14px',\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n },\n field: {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n fontSize: 13,\n fontWeight: 500,\n lineHeight: '20px',\n },\n select: { width: '100%' },\n hint: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n}\n","/**\n * Subscriptions settings section: one card per subscription provider with an\n * OAuth login/logout flow driven by the node half's\n * `/api/subscriptions-auth.<endpoint>` RPC routes. Login state lives server-side; the page polls `status` only while\n * a login attempt is busy, so an idle page never polls. All state is local\n * React state — the page has no store.\n *\n * Every color resolves through a `--dsw-alias-*` design token (the ui-theme\n * design-platform.css values flip under `body[data-ds-dark-theme]`), and\n * every user-visible string goes through the locale-bound `t` of the\n * 'settings.subscriptions' namespace. Buttons and inputs take the\n * native settings vocabulary with shared, scoped control states.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport { en } from './locales.js'\nimport { resetActionBlock } from './reset-action.js'\nimport { ProviderAccountManager } from './ProviderAccountManager.js'\nimport { providerSettingsCss } from './provider-settings-styles.js'\nimport { ExternalUsageCards } from './ExternalUsageCards.js'\nimport { CursorCard } from './CursorCard.js'\nimport { OllamaCard } from './OllamaCard.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport {\n ResetCreditsDisclosure,\n ResetCreditsErrorLine,\n showsResetCredits,\n} from './reset-credits-view.js'\nimport { displayUsedPercent } from './usage-pace.js'\nimport { UsageBadgeDisplaySetting } from './UsageBadgeDisplaySetting.js'\nimport { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js'\nimport { subscriptionCardStyles as cardStyles } from './subscription-card-styles.js'\nimport type { SubscriptionsKey } from './locales.js'\n\nimport {\n callSubscriptionsAuth,\n SubscriptionsAuthError,\n} from './subscriptions-rpc.js'\nexport { callSubscriptionsAuth } from './subscriptions-rpc.js'\n\n/** Poll cadence while a provider login attempt is busy. */\nconst POLL_INTERVAL_MS = 2000\n\n/** Subscription provider ids, fixed by the node half's OAuth adapters. */\nexport type SubscriptionProvider =\n 'codex' | 'claude' | 'grok' | 'copilot' | 'antigravity'\n\n/** One logged-in account as answered by the `status` endpoint. */\nexport interface AccountStatus {\n key: string\n account?: string\n expiresAt?: number\n plan?: string\n isDefault: boolean\n}\n\n/** One provider's login state as answered by the `status` endpoint. */\nexport interface ProviderStatus {\n busy: boolean\n accounts: AccountStatus[]\n detail?: string\n /** The CLI version the route presents (Codex, Claude), and where it came from. */\n clientVersion?: { version: string; source: ClientVersionSource }\n}\n\n/** Where a presented CLI version came from; the tag names the source so a stale one is visible. */\nexport type ClientVersionSource = 'npm' | 'local' | 'fallback' | 'config'\n\nconst CLIENT_VERSION_SOURCES: Record<ClientVersionSource, SubscriptionsKey> = {\n npm: 'clientVersionNpm',\n local: 'clientVersionLocal',\n fallback: 'clientVersionFallback',\n config: 'clientVersionConfig',\n}\n\n/** `status` endpoint value: the node half owns this shape. */\ninterface StatusResponse {\n providers: Record<SubscriptionProvider, ProviderStatus>\n}\n\n/** One rate-limit window as answered by the `usage` endpoint. */\nexport interface UsageWindow {\n kind: 'session' | 'weekly' | 'other'\n scope?: string\n usedPercent: number\n resetsAt?: number\n startsAt?: number\n windowDurationMs?: number\n fixedWindow?: boolean\n /** Display-only assumed start; the marker rides it, never pace. */\n displayStartsAt?: number\n}\n\n/** `usage` endpoint value: the node half owns this shape. */\nexport interface ProviderUsage {\n observedAt?: number\n stale?: boolean\n supported: boolean\n windows?: UsageWindow[]\n plan?: string\n /**\n * Banked limit-reset grants. Codex entries carry id/expiry only. Claude\n * entries are one row per grant: `expiresAt` is when the grant expires, not\n * a window reset, and `resetsLeft` is the remaining credit count.\n */\n resetCredits?: ResetCreditView[]\n resetCreditsError?: string\n}\n\n/** One banked reset grant as the usage RPC returns it. */\nexport interface ResetCreditView {\n id?: string\n grantedAt?: number\n /** Epoch milliseconds when the grant expires. Never a periodic window reset. */\n expiresAt?: number\n resetsTotal?: number\n resetsLeft?: number\n usableNow?: boolean\n paused?: boolean\n /** Server metadata only. Claude has no redemption control. */\n claimable?: boolean\n /** Epoch milliseconds until which the grant is visible but not usable. */\n cooldownUntil?: number\n}\n\n/** `login` endpoint value: the URL the user completes OAuth at. */\ninterface LoginResponse {\n authorizeUrl: string\n /** Device-flow providers (copilot): the code the user types at authorizeUrl. */\n userCode?: string\n}\n\n/** Injected dependencies of {@link SubscriptionsSection} (slot `inject`). */\nexport interface SubscriptionsSectionInjected {\n /** Generic logical-RPC caller over the Connection transport. */\n rpc: ConnectionHandle['rpc']\n /** Section copy: translate a 'settings.subscriptions' key with `{name}` template params. */\n t: (key: SubscriptionsKey, params?: Record<string, unknown>) => string\n}\n\n/**\n * Props delivered by the slot outlet: the inject face spread flat (the\n * renderer erases the share boundary at the render call).\n */\nexport type SubscriptionsSectionProps = Partial<SubscriptionsSectionInjected>\n\n/** Card display metadata, in page order (names are brand names, not translated). */\nconst PROVIDERS: readonly { id: SubscriptionProvider; name: string }[] = [\n { id: 'codex', name: 'Codex (ChatGPT)' },\n { id: 'claude', name: 'Claude' },\n { id: 'grok', name: 'Grok (X Premium)' },\n { id: 'copilot', name: 'GitHub Copilot' },\n { id: 'antigravity', name: 'Google Antigravity' },\n]\n\n/** Human text of an action failure, SubscriptionsAuthError or not. */\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/** Copy a keyed map without the entries whose key is not in `live`. */\nfunction dropStale<T>(\n map: Record<string, T>,\n live: ReadonlySet<string>,\n): Record<string, T> {\n const stale = Object.keys(map).filter((key) => !live.has(key))\n if (stale.length === 0) return map\n const next = { ...map }\n for (const key of stale) delete next[key]\n return next\n}\n\n/**\n * English-dictionary fallback for a missing inject `t` (standalone renders);\n * the slot inject always supplies the locale-bound one.\n * @param key - dictionary key.\n * @param params - `{name}` template params.\n * @returns the template with params substituted.\n */\nfunction fallbackTranslate(\n key: SubscriptionsKey,\n params?: Record<string, unknown>,\n): string {\n let text: string = en[key]\n for (const [name, value] of Object.entries(params ?? {})) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\nconst styles: Record<string, CSSProperties> = {\n section: {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n maxWidth: 560,\n color: 'var(--dsw-alias-label-primary)',\n },\n intro: {\n margin: 0,\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 14,\n lineHeight: '22px',\n },\n card: {\n ...cardStyles.card,\n border:\n '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',\n borderRadius: 'var(--dsw-radius-xl, 20px)',\n background:\n 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',\n },\n cardHeader: cardStyles.header,\n dot: cardStyles.dot,\n name: cardStyles.name,\n statusLine: cardStyles.status,\n clientVersion: {\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n fontVariantNumeric: 'tabular-nums',\n },\n errorLine: cardStyles.error,\n actions: cardStyles.actions,\n usage: {\n ...cardStyles.usage,\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n },\n usageHeader: cardStyles.usageHeader,\n usageTitle: cardStyles.usageTitle,\n usagePlan: cardStyles.usagePlan,\n usageRefresh: {\n minHeight: 22,\n height: 22,\n padding: '0 8px',\n marginLeft: 'auto',\n },\n usageRow: cardStyles.usageRow,\n usageMeta: cardStyles.usageMeta,\n accountRow: {\n ...cardStyles.account,\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 'var(--dsw-radius-lg, 16px)',\n },\n accountHeader: cardStyles.accountHeader,\n accountName: cardStyles.accountName,\n starButton: {\n border: 'none',\n padding: 0,\n width: 28,\n font: 'inherit',\n fontSize: 14,\n lineHeight: '20px',\n cursor: 'pointer',\n color: 'var(--dsw-alias-state-warn-label)',\n },\n deviceCode: {\n marginTop: 4,\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 'var(--dsw-radius-lg, 16px)',\n padding: '10px 12px',\n background: 'var(--dsw-alias-bg-layer-1)',\n },\n deviceCodeText: {\n fontFamily: 'monospace',\n fontSize: 18,\n lineHeight: '24px',\n letterSpacing: 2,\n color: 'var(--dsw-alias-label-primary)',\n userSelect: 'all',\n },\n manual: { fontSize: 13, lineHeight: '20px' },\n manualRow: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n alignItems: 'center',\n marginTop: 8,\n },\n manualInput: { flex: '1 1 200px', minWidth: 0 },\n modalOverlay: {\n position: 'fixed',\n inset: 0,\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 16,\n background: 'var(--dsw-alias-bg-mask-1, #0006)',\n backdropFilter: 'var(--dsw-mask-blur, none)',\n },\n modal: {\n width: 460,\n maxWidth: '100%',\n maxHeight: '90vh',\n overflowY: 'auto',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n padding: '16px 18px',\n borderRadius: 'var(--dsw-radius-panel, 28px)',\n background: 'var(--dsw-alias-bg-layer-2)',\n border: 0,\n boxShadow: 'var(--dsw-elevation-prominent)',\n },\n modalHeader: { display: 'flex', alignItems: 'center', gap: 8 },\n modalTitle: {\n fontWeight: 500,\n fontSize: 16,\n lineHeight: '24px',\n color: 'var(--dsw-alias-label-primary)',\n },\n}\n\n/** Status dot color for one provider state. */\nfunction dotColor(status: ProviderStatus | undefined): string {\n if (status?.busy === true) return 'var(--dsw-alias-state-warn-label)'\n if ((status?.accounts.length ?? 0) > 0)\n return 'var(--dsw-alias-state-success-primary)'\n return 'var(--dsw-alias-label-dimmed)'\n}\n\n/**\n * One-line status text for one provider state.\n * @param t - section translate.\n * @param status - the provider's last reported state.\n * @returns the localized status line.\n */\nfunction statusText(\n t: SubscriptionsSectionInjected['t'],\n status: ProviderStatus | undefined,\n): string {\n if (status === undefined) return t('checking')\n if (status.busy) return t('loginInProgress')\n if (status.accounts.length > 0)\n return t('loggedInCount', { count: status.accounts.length })\n return t('notLoggedIn')\n}\n\n/**\n * The CLI version a route presents, beside the provider name; nothing for\n * routes without one. The source word (npm / local / built-in / configured)\n * is the fix for upstream issue #108: a failed npm lookup must read as a\n * fallback, never as a plan limit.\n */\nexport function clientVersionText(\n t: SubscriptionsSectionInjected['t'],\n clientVersion: ProviderStatus['clientVersion'],\n): string {\n if (clientVersion === undefined) return ''\n return t('clientVersion', {\n version: clientVersion.version,\n source: t(CLIENT_VERSION_SOURCES[clientVersion.source]),\n })\n}\n\n/**\n * Localized label of one usage window (kind, plus the model scope when named).\n * @param t - section translate.\n * @param window - the reported window.\n * @returns e.g. \"5-hour window\" or \"Weekly · Opus\".\n */\nfunction usageWindowLabel(\n t: SubscriptionsSectionInjected['t'],\n window: UsageWindow,\n): string {\n const base =\n window.kind === 'session'\n ? t('usageSession')\n : window.kind === 'weekly'\n ? t('usageWeekly')\n : t('usageWindow')\n return window.scope !== undefined && window.scope !== ''\n ? `${base} · ${window.scope}`\n : base\n}\n\n/** Meter fill color lives with the pace logic: fresh 90%+ is red, pace presets add a yellow lead threshold. */\nexport { usageBarColor } from './usage-pace.js'\n\n/**\n * The Subscriptions settings page component.\n * @param props - the slot inject face ({@link SubscriptionsSectionInjected}).\n * @returns the section body, or a notice while the RPC face is absent.\n */\nexport function SubscriptionsSection(props: SubscriptionsSectionProps) {\n const { rpc } = props\n const t = props.t ?? fallbackTranslate\n const [statuses, setStatuses] = useState<\n Partial<Record<SubscriptionProvider, ProviderStatus>>\n >({})\n const [errors, setErrors] = useState<\n Partial<Record<SubscriptionProvider, string>>\n >({})\n const [manualDrafts, setManualDrafts] = useState<\n Record<SubscriptionProvider, string>\n >({\n codex: '',\n claude: '',\n grok: '',\n copilot: '',\n antigravity: '',\n })\n /** Pending device-flow codes (copilot), shown while the attempt polls. */\n const [deviceCodes, setDeviceCodes] = useState<\n Partial<\n Record<\n SubscriptionProvider,\n { userCode: string; verificationUrl: string }\n >\n >\n >({})\n const [copiedCode, setCopiedCode] = useState<\n SubscriptionProvider | undefined\n >(undefined)\n /** Usage snapshots keyed `${provider}:${accountKey}` — every account tracks its own windows. */\n const [usages, setUsages] = useState<Record<string, ProviderUsage>>({})\n const [observedAt, setObservedAt] = useState<Record<string, number>>({})\n const [usageErrors, setUsageErrors] = useState<Record<string, string>>({})\n const [usageLoading, setUsageLoading] = useState<Record<string, boolean>>({})\n const [resetConfirmation, setResetConfirmation] = useState<{\n account: string\n ticket: string\n expiresAt: number\n creditExpiresAt?: number\n weeklyUsedPercent: number\n }>()\n const [resetBusy, setResetBusy] = useState(false)\n const [resetAcknowledged, setResetAcknowledged] = useState(false)\n const [resetMessage, setResetMessage] = useState('')\n const [resetAccount, setResetAccount] = useState<string>()\n const resetDialogRef = useRef<HTMLDialogElement>(null)\n useEffect(() => {\n if (resetConfirmation) resetDialogRef.current?.showModal()\n else resetDialogRef.current?.close()\n }, [resetConfirmation])\n const resetInflight = useRef(false)\n const mountedRef = useRef(true)\n const pollersRef = useRef(\n new Map<SubscriptionProvider, ReturnType<typeof setInterval>>(),\n )\n /** Accounts with a `usage` call in flight; guards the auto-fetch effect against re-entry. */\n /** In-flight usage reads per key, holding the promise so a forced read can wait one out. */\n const usageInflightRef = useRef(new Map<string, Promise<void>>())\n const usageRosterSignatureRef = useRef<string>()\n const [managedProvider, setManagedProvider] = useState<{\n id: SubscriptionProvider\n name: string\n }>()\n const setProviderError = useCallback(\n (provider: SubscriptionProvider, message: string | undefined): void => {\n if (!mountedRef.current) return\n setErrors((prev) => {\n const next = { ...prev }\n if (message === undefined) delete next[provider]\n else next[provider] = message\n return next\n })\n },\n [],\n )\n\n const stopPolling = useCallback((provider: SubscriptionProvider): void => {\n const poller = pollersRef.current.get(provider)\n if (poller !== undefined) {\n clearInterval(poller)\n pollersRef.current.delete(provider)\n }\n }, [])\n\n /** Refetch every provider's status; stop a provider's poller once its attempt settles. */\n const refresh = useCallback(async (): Promise<void> => {\n if (rpc === undefined) return\n let response: StatusResponse\n try {\n response = await callSubscriptionsAuth<StatusResponse>(rpc, 'status', {})\n } catch (error) {\n // A failed poll must not kill the page; busy providers keep polling and\n // the action paths report their own errors. But staying silent turns a\n // persistent failure into an endless \"Checking…\" — show it instead.\n const message = error instanceof Error ? error.message : String(error)\n for (const { id } of PROVIDERS) setProviderError(id, message)\n return\n }\n if (!mountedRef.current) return\n setStatuses(response.providers)\n const signature = PROVIDERS.map(\n ({ id }) =>\n `${id}:${response.providers[id].accounts\n .map((account) => `${account.key}:${account.isDefault}`)\n .join(',')}`,\n ).join(';')\n if (signature !== usageRosterSignatureRef.current) {\n usageRosterSignatureRef.current = signature\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n }\n // The poll recovered: drop any error line a previous failed poll left.\n for (const { id } of PROVIDERS) setProviderError(id, undefined)\n for (const { id } of PROVIDERS) {\n const status = response.providers[id]\n if (status.accounts.length > 0 || !status.busy) {\n stopPolling(id)\n // The attempt settled (success, timeout, or cancel): drop the code card.\n setDeviceCodes((prev) => {\n if (prev[id] === undefined) return prev\n const next = { ...prev }\n delete next[id]\n return next\n })\n }\n }\n }, [rpc, stopPolling, setProviderError])\n\n const startPolling = useCallback(\n (provider: SubscriptionProvider): void => {\n if (pollersRef.current.has(provider)) return\n pollersRef.current.set(\n provider,\n setInterval(() => {\n void refresh()\n }, POLL_INTERVAL_MS),\n )\n },\n [refresh],\n )\n\n // Initial load; every busy provider (e.g. an attempt started before a page\n // reload) resumes polling. Teardown clears pollers and the mounted guard.\n useEffect(() => {\n mountedRef.current = true\n void refresh().then(() => {\n if (!mountedRef.current) return\n setStatuses((current) => {\n for (const { id } of PROVIDERS) {\n if (current[id]?.busy === true) startPolling(id)\n }\n return current\n })\n })\n return () => {\n mountedRef.current = false\n // The ref holds pollers started after this effect began. Copying .current\n // at setup would clear an empty set and leave those intervals running.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- read the live set at unmount\n for (const poller of pollersRef.current.values()) clearInterval(poller)\n pollersRef.current.clear()\n }\n }, [refresh, startPolling])\n\n const loadUsage = useCallback(\n async (\n provider: SubscriptionProvider,\n account: string,\n force = false,\n ): Promise<void> => {\n if (rpc === undefined) return\n const key = `${provider}:${account}`\n const pending = usageInflightRef.current.get(key)\n // A forced read must never be dropped behind a poll that started before the\n // state changed. The refresh after a credit redemption is the only thing\n // that picks up the new numbers, and the next automatic poll is minutes\n // away, so waiting the earlier read out is cheaper than showing a stale\n // percentage next to a success message.\n if (pending !== undefined) {\n if (!force) return\n await pending\n }\n if (rpc === undefined || usageInflightRef.current.has(key)) return\n const read = (async () => {\n setUsageLoading((prev) => ({ ...prev, [key]: true }))\n try {\n const usage = await callSubscriptionsAuth<ProviderUsage>(\n rpc,\n 'usage',\n { provider, account, ...(force ? { force: true } : {}) },\n )\n if (!mountedRef.current) return\n setUsages((prev) => ({ ...prev, [key]: usage }))\n setObservedAt((prev) => ({\n ...prev,\n [key]: usage.observedAt ?? Date.now(),\n }))\n window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT))\n setUsageErrors((prev) => {\n const next = { ...prev }\n delete next[key]\n return next\n })\n } catch (error) {\n if (mountedRef.current)\n setUsageErrors((prev) => ({ ...prev, [key]: messageOf(error) }))\n } finally {\n usageInflightRef.current.delete(key)\n if (mountedRef.current)\n setUsageLoading((prev) => ({ ...prev, [key]: false }))\n }\n })()\n usageInflightRef.current.set(key, read)\n await read\n },\n [rpc],\n )\n\n async function prepareReset(account: string): Promise<void> {\n if (!rpc || resetInflight.current) return\n resetInflight.current = true\n setResetBusy(true)\n setResetAccount(account)\n setResetConfirmation(undefined)\n setResetMessage('')\n try {\n const result = await callSubscriptionsAuth<\n Omit<NonNullable<typeof resetConfirmation>, 'account'>\n >(rpc, 'prepareReset', { account })\n setResetAcknowledged(false)\n setResetConfirmation({ ...result, account })\n } catch (error) {\n setResetMessage(messageOf(error))\n } finally {\n resetInflight.current = false\n setResetBusy(false)\n }\n }\n\n async function consumeReset(): Promise<void> {\n if (\n !rpc ||\n !resetConfirmation ||\n !resetAcknowledged ||\n resetInflight.current\n )\n return\n const { account, ticket } = resetConfirmation\n resetInflight.current = true\n setResetBusy(true)\n setResetConfirmation(undefined)\n try {\n await callSubscriptionsAuth(rpc, 'consumeReset', { account, ticket })\n setResetMessage(t('resetUseSuccess'))\n } catch (error) {\n setResetMessage(messageOf(error))\n } finally {\n await loadUsage('codex', account, true)\n resetInflight.current = false\n setResetBusy(false)\n }\n }\n\n // Fetch usage once an account is logged in; drop the snapshots of accounts\n // that vanished so a re-login refetches. A failed lookup does not auto-retry\n // — the per-account Refresh button is the retry path.\n useEffect(() => {\n const live = new Set<string>()\n for (const { id } of PROVIDERS) {\n for (const account of statuses[id]?.accounts ?? []) {\n const key = `${id}:${account.key}`\n live.add(key)\n if (usages[key] === undefined && usageErrors[key] === undefined)\n void loadUsage(id, account.key)\n }\n }\n setUsages((prev) => dropStale(prev, live))\n setUsageErrors((prev) => dropStale(prev, live))\n }, [statuses, usages, usageErrors, loadUsage])\n\n const login = useCallback(\n async (\n provider: SubscriptionProvider,\n method?: 'oauth' | 'keychain',\n ): Promise<void> => {\n if (rpc === undefined) return\n setProviderError(provider, undefined)\n try {\n const response = await callSubscriptionsAuth<LoginResponse>(\n rpc,\n 'login',\n {\n provider,\n ...(method === undefined ? {} : { method }),\n },\n )\n if (\n typeof response.authorizeUrl === 'string' &&\n response.authorizeUrl === ''\n ) {\n // Instant login (e.g. imported from Claude Code credentials)\n await refresh()\n return\n }\n if (typeof response.authorizeUrl !== 'string') {\n throw new SubscriptionsAuthError(t('loginMissingUrl'))\n }\n if (!mountedRef.current) return\n // Optimistic busy so Cancel and the manual fallback appear before the first poll tick.\n setStatuses((prev) => ({\n ...prev,\n [provider]: {\n accounts: prev[provider]?.accounts ?? [],\n ...prev[provider],\n busy: true,\n },\n }))\n if (\n typeof response.userCode === 'string' &&\n response.userCode.length > 0\n ) {\n // Device flow: show the code card instead of opening the page blind —\n // the user copies the code first, then opens the verification page.\n setDeviceCodes((prev) => ({\n ...prev,\n [provider]: {\n userCode: response.userCode as string,\n verificationUrl: response.authorizeUrl,\n },\n }))\n } else {\n window.open(response.authorizeUrl, '_blank', 'noopener')\n }\n startPolling(provider)\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n },\n [rpc, t, setProviderError, startPolling, refresh],\n )\n\n const cancel = useCallback(\n async (provider: SubscriptionProvider): Promise<void> => {\n if (rpc === undefined) return\n stopPolling(provider)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'cancel', { provider })\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n },\n [rpc, stopPolling, setProviderError, refresh],\n )\n\n const submitManual = useCallback(\n async (provider: SubscriptionProvider): Promise<void> => {\n if (rpc === undefined) return\n const input = manualDrafts[provider].trim()\n if (input === '') return\n setProviderError(provider, undefined)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'manual', {\n provider,\n input,\n })\n if (mountedRef.current)\n setManualDrafts((prev) => ({ ...prev, [provider]: '' }))\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n },\n [rpc, manualDrafts, setProviderError, refresh],\n )\n\n const logout = useCallback(\n async (\n provider: SubscriptionProvider,\n account: string,\n display: string,\n name: string,\n ): Promise<void> => {\n if (rpc === undefined) return\n if (\n !window.confirm(\n t('logoutAccountConfirm', { provider: name, account: display }),\n )\n )\n return\n setProviderError(provider, undefined)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'logout', {\n provider,\n account,\n })\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n },\n [rpc, t, setProviderError, refresh],\n )\n\n const setDefault = useCallback(\n async (provider: SubscriptionProvider, account: string): Promise<void> => {\n if (rpc === undefined) return\n setProviderError(provider, undefined)\n try {\n await callSubscriptionsAuth<{ ok: true }>(rpc, 'setDefault', {\n provider,\n account,\n })\n } catch (error) {\n setProviderError(provider, messageOf(error))\n }\n await refresh()\n },\n [rpc, setProviderError, refresh],\n )\n\n const copyDeviceCode = useCallback(\n (provider: SubscriptionProvider, userCode: string): void => {\n void navigator.clipboard\n ?.writeText(userCode)\n .then(() => {\n if (!mountedRef.current) return\n setCopiedCode(provider)\n setTimeout(() => {\n if (mountedRef.current) {\n setCopiedCode((current) =>\n current === provider ? undefined : current,\n )\n }\n }, 1500)\n })\n .catch(() => undefined)\n },\n [],\n )\n\n if (rpc === undefined) {\n return <p style={styles.intro}>{t('unavailable')}</p>\n }\n\n return (\n <div className=\"dsh-subscriptions-settings\" style={styles.section}>\n <style>{providerSettingsCss}</style>\n <p style={styles.intro}>{t('intro')}</p>\n <UsageBadgeDisplaySetting t={t} />\n {PROVIDERS.map(({ id, name }) => {\n const status = statuses[id]\n const busy = status?.busy === true\n const deviceCode = deviceCodes[id]\n const accounts = status?.accounts ?? []\n return (\n <div key={id} style={styles.card}>\n <div style={styles.cardHeader}>\n <span style={{ ...styles.dot, background: dotColor(status) }} />\n <span style={styles.name}>{name}</span>\n {status?.clientVersion !== undefined && (\n <span\n style={styles.clientVersion}\n title={t('clientVersionHint')}\n >\n {clientVersionText(t, status.clientVersion)}\n </span>\n )}\n </div>\n <p style={styles.statusLine}>{statusText(t, status)}</p>\n {status?.detail !== undefined && status.detail !== '' && (\n <p style={styles.statusLine}>{status.detail}</p>\n )}\n {errors[id] !== undefined && (\n <p style={styles.errorLine}>{errors[id]}</p>\n )}\n {accounts.map((account) => {\n const usageKey = `${id}:${account.key}`\n const usage = usages[usageKey]\n const usageError = usageErrors[usageKey]\n const display = account.account ?? account.key\n const sortedCredits = [...(usage?.resetCredits ?? [])].sort(\n (a, b) => (a.expiresAt ?? Infinity) - (b.expiresAt ?? Infinity),\n )\n const nextReset = sortedCredits.find(\n (c) => c.expiresAt === undefined || c.expiresAt > Date.now(),\n )\n const resetBlock = usage\n ? resetActionBlock(usage)\n : 'resetUseRefresh'\n const resetDisabled = resetBusy || resetBlock !== undefined\n // Providers without a usage endpoint answer supported:false — no block.\n const showUsage =\n usage?.supported !== false &&\n (usage !== undefined ||\n usageError !== undefined ||\n usageLoading[usageKey] === true)\n return (\n <div key={account.key} style={styles.accountRow}>\n <div style={styles.accountHeader}>\n <button\n type=\"button\"\n style={styles.starButton}\n title={\n account.isDefault ? t('defaultBadge') : t('setDefault')\n }\n onClick={() => {\n if (!account.isDefault) void setDefault(id, account.key)\n }}\n >\n {account.isDefault ? '★' : '☆'}\n </button>\n <span style={styles.accountName}>{display}</span>\n {account.plan !== undefined && (\n <span style={styles.usagePlan}>{account.plan}</span>\n )}\n {account.expiresAt !== undefined && (\n <span style={styles.statusLine}>\n {t('accountExpires', {\n date: new Date(account.expiresAt).toLocaleString(),\n })}\n </span>\n )}\n <button\n type=\"button\"\n style={{ marginLeft: 'auto', flexShrink: 0 }}\n onClick={() => {\n void logout(id, account.key, display, name)\n }}\n >\n {t('logout')}\n </button>\n </div>\n {showUsage && (\n <div style={styles.usage}>\n <div style={styles.usageHeader}>\n <span style={styles.usageTitle}>{t('usageTitle')}</span>\n {usage?.plan !== undefined && (\n <span style={styles.usagePlan}>\n {t('usagePlan', { plan: usage.plan })}\n </span>\n )}\n <button\n type=\"button\"\n style={styles.usageRefresh}\n disabled={usageLoading[usageKey] === true}\n onClick={() => {\n void loadUsage(id, account.key, true)\n }}\n >\n {t('usageRefresh')}\n </button>\n </div>\n {usage === undefined && usageError === undefined && (\n <p style={styles.statusLine}>{t('usageLoading')}</p>\n )}\n {usageError !== undefined && (\n <p style={styles.errorLine}>\n {t('usageError', { message: usageError })}\n </p>\n )}\n {usage?.windows !== undefined &&\n usage.windows.length === 0 && (\n <p style={styles.statusLine}>{t('usageEmpty')}</p>\n )}\n {(usage?.windows ?? []).map((window, index) => {\n const percent = displayUsedPercent(window.usedPercent)\n return (\n <div key={index} style={styles.usageRow}>\n <div style={styles.usageMeta}>\n <span>{usageWindowLabel(t, window)}</span>\n <span>\n {percent === undefined\n ? t('usageMeterInvalid')\n : `${percent}%`}\n {window.resetsAt !== undefined &&\n ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`}\n </span>\n </div>\n <UsageMeter\n window={window}\n t={t}\n observedAt={observedAt[usageKey]}\n stale={\n usageError !== undefined || usage.stale === true\n }\n />\n </div>\n )\n })}\n {(id === 'codex' || id === 'claude') &&\n usage?.resetCreditsError !== undefined && (\n <ResetCreditsErrorLine\n provider={id}\n message={usage.resetCreditsError}\n t={t}\n />\n )}\n {(id === 'codex' || id === 'claude') &&\n showsResetCredits(id, usage?.resetCredits) && (\n <ResetCreditsDisclosure\n mode={id === 'claude' ? 'grants' : 'credits'}\n credits={sortedCredits}\n t={t}\n {...(nextReset !== undefined\n ? { nextCredit: nextReset }\n : {})}\n {...(id === 'codex'\n ? {\n useAction: {\n accountKey: account.key,\n busy:\n resetBusy && resetAccount === account.key,\n disabled: resetDisabled,\n title: t(\n resetBusy\n ? 'resetUseChecking'\n : (resetBlock ?? 'resetUseReady'),\n ),\n label: t('resetUseButton'),\n onUse: () => {\n if (!resetDisabled)\n void prepareReset(account.key)\n },\n },\n }\n : {})}\n {...(resetAccount === account.key &&\n resetMessage !== ''\n ? { statusMessage: resetMessage }\n : {})}\n />\n )}\n </div>\n )}\n </div>\n )\n })}\n <div style={styles.actions}>\n {!busy && accounts.length === 0 && (\n <button\n type=\"button\"\n onClick={() => {\n void login(id)\n }}\n >\n {t('login')}\n </button>\n )}\n {!busy && accounts.length > 0 && id === 'claude' && (\n <>\n <button\n type=\"button\"\n onClick={() => {\n void login(id, 'oauth')\n }}\n >\n {t('addAccountOAuth')}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n void login(id, 'keychain')\n }}\n >\n {t('addAccountKeychain')}\n </button>\n </>\n )}\n {!busy && accounts.length > 0 && id !== 'claude' && (\n <button\n type=\"button\"\n onClick={() => {\n void login(id)\n }}\n >\n {t('addAccount')}\n </button>\n )}\n <button\n type=\"button\"\n aria-haspopup=\"dialog\"\n onClick={() => setManagedProvider({ id, name })}\n >\n {t('accountsManage')}\n </button>\n {busy && (\n <button\n type=\"button\"\n onClick={() => {\n void cancel(id)\n }}\n >\n {t('cancel')}\n </button>\n )}\n </div>\n {!busy && accounts.length > 0 && (\n <p style={styles.statusLine}>{t('addAccountHint')}</p>\n )}\n\n {busy && deviceCode !== undefined && (\n <div style={styles.deviceCode}>\n <span style={styles.statusLine}>{t('deviceCodePrompt')}</span>\n <span style={styles.deviceCodeText}>{deviceCode.userCode}</span>\n <div style={styles.actions}>\n <button\n type=\"button\"\n onClick={() => {\n copyDeviceCode(id, deviceCode.userCode)\n }}\n >\n {copiedCode === id\n ? t('deviceCodeCopied')\n : t('deviceCodeCopy')}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n window.open(\n deviceCode.verificationUrl,\n '_blank',\n 'noopener',\n )\n }}\n >\n {t('deviceCodeOpenPage')}\n </button>\n </div>\n </div>\n )}\n {busy && deviceCode === undefined && (\n <details style={styles.manual}>\n <summary>{t('manualSummary')}</summary>\n <div style={styles.manualRow}>\n <input\n style={styles.manualInput}\n value={manualDrafts[id]}\n placeholder={t('manualPlaceholder')}\n onChange={(event) =>\n setManualDrafts((prev) => ({\n ...prev,\n [id]: event.target.value,\n }))\n }\n />\n <button\n type=\"button\"\n onClick={() => {\n void submitManual(id)\n }}\n >\n {t('submit')}\n </button>\n </div>\n </details>\n )}\n </div>\n )\n })}\n <CursorCard rpc={rpc} t={t} />\n <OllamaCard rpc={rpc} t={t} />\n <ExternalUsageCards rpc={rpc} t={t} />\n {managedProvider && (\n <ProviderAccountManager\n provider={managedProvider.id}\n name={managedProvider.name}\n rpc={rpc}\n t={t}\n onClose={() => setManagedProvider(undefined)}\n />\n )}\n <style>\n {\n '.subscriptions-reset-dialog::backdrop { background: var(--dsw-alias-bg-mask-1, #0006); backdrop-filter: var(--dsw-mask-blur, none); }'\n }\n </style>\n <dialog\n ref={resetDialogRef}\n className=\"subscriptions-reset-dialog\"\n aria-labelledby=\"subscriptions-reset-title\"\n onCancel={() => setResetConfirmation(undefined)}\n onClose={() => setResetConfirmation(undefined)}\n style={{\n ...styles.modal,\n display: resetConfirmation ? 'flex' : 'none',\n margin: 'auto',\n color: 'var(--dsw-alias-label-primary)',\n }}\n >\n {resetConfirmation && (\n <>\n <h3\n id=\"subscriptions-reset-title\"\n style={{ ...styles.modalTitle, margin: 0 }}\n >\n {t('resetUseConfirmTitle')}\n </h3>\n <p style={{ ...styles.statusLine, overflowWrap: 'anywhere' }}>\n {statuses.codex?.accounts.find(\n (a) => a.key === resetConfirmation.account,\n )?.account ?? resetConfirmation.account}\n </p>\n <div style={{ ...styles.usageMeta, gap: 12 }}>\n <span>{t('usageWeekly')}</span>\n <strong>\n {Math.round(resetConfirmation.weeklyUsedPercent)}%\n </strong>\n </div>\n <div style={styles.usageMeta}>\n <span>\n {resetConfirmation.creditExpiresAt === undefined\n ? t('resetCreditExpiryUnknown')\n : t('resetCreditExpires', {\n date: new Date(\n resetConfirmation.creditExpiresAt,\n ).toLocaleString(),\n })}\n </span>\n </div>\n <p style={{ ...styles.statusLine, margin: '4px 0' }}>\n {t('resetUseWarning')}\n </p>\n <label\n style={{\n display: 'flex',\n gap: 8,\n alignItems: 'flex-start',\n fontSize: 12,\n }}\n >\n <input\n type=\"checkbox\"\n checked={resetAcknowledged}\n onChange={(e) => setResetAcknowledged(e.target.checked)}\n />\n {t('resetUseAcknowledge')}\n </label>\n <div\n className=\"dsh-subscription-dialog-actions\"\n style={{\n ...styles.actions,\n justifyContent: 'flex-end',\n marginTop: 8,\n }}\n >\n <button\n type=\"button\"\n autoFocus\n onClick={() => setResetConfirmation(undefined)}\n >\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n className=\"dsh-subscription-primary\"\n disabled={!resetAcknowledged || resetBusy}\n onClick={() => {\n void consumeReset()\n }}\n >\n {t('resetUseConfirm')}\n </button>\n </div>\n </>\n )}\n </dialog>\n </div>\n )\n}\n","/**\n * Plugin-local image gallery for generated-image toolviews.\n *\n * Since web-app rc.8, `@deepseek-ai/dsh-client-ui-attachment`'s browser module\n * exports only its cordis plugin surface (`apply`/`inject`) — the React\n * components are no longer package values, so importing `ImageGallery` from it\n * yields `undefined` at runtime and crashes the toolview inside the slot error\n * boundary (the whole call row disappears). This module re-implements the\n * gallery contract the toolview needs (loader-driven thumbnails, retry on\n * failure, click-to-open lightbox) with the same sizing rules as the platform\n * component, keeping this plugin independent of harness component exports.\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { CSSProperties } from 'react'\n\n/**\n * Mirror of ImageAttachmentRef (packages/attachment/attachment/src/types.ts);\n * the brand on attachmentId is compile-time only, so string suffices here.\n */\nexport interface ImageAttachmentRef {\n attachmentId: string\n mediaType: string\n bytes: number\n width: number\n height: number\n name?: string\n}\n\n/** Loads a session-authorized durable image URL (resolves to a data/blob URL). */\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\n/** Lightbox strings forwarded to the opened preview. */\nexport interface ImageLightboxLabels {\n dialog: string\n close: string\n}\n\n/** Message-image strings the owner resolves from its own locale namespace. */\nexport interface MessageImageLabels {\n /** Fallback display name for an unnamed image. */\n image: string\n /** Thumbnail tooltip inviting the original-image preview. */\n open: string\n /** Accessible thumbnail label; receives the image's display name. */\n openNamed: (label: string) => string\n /** Loading placeholder shown until bytes resolve. */\n loading: string\n /** Retry-control label shown when the load fails. */\n loadFailed: string\n /** Lightbox strings forwarded to the opened preview. */\n lightbox: ImageLightboxLabels\n}\n\n/** Display box for a lone image (platform rule): long edge 240px with the\n * rendered aspect ratio clamped to [0.25, 4] — the overflow is cropped by\n * `object-fit: cover` — and never upscaled past the image's natural size. The\n * crop anchor keeps the top of very tall images and the left of very wide\n * ones, where the informative content usually starts. */\nfunction singleFit(attachment: ImageAttachmentRef): {\n width: number\n height: number\n objectPosition: string\n} {\n const natural = attachment.width / attachment.height\n const ratio = Math.min(4, Math.max(0.25, natural))\n const box =\n ratio >= 1\n ? { width: 240, height: 240 / ratio }\n : { width: 240 * ratio, height: 240 }\n const scale = Math.min(\n 1,\n attachment.width / box.width,\n attachment.height / box.height,\n )\n return {\n width: Math.max(1, Math.round(box.width * scale)),\n height: Math.max(1, Math.round(box.height * scale)),\n objectPosition:\n natural < 0.25 ? 'center top' : natural > 4 ? 'left center' : 'center',\n }\n}\n\nconst styles: Record<string, CSSProperties> = {\n gallery: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n justifyContent: 'flex-start',\n },\n frame: {\n display: 'grid',\n placeItems: 'center',\n overflow: 'hidden',\n padding: 0,\n border: '1px solid var(--dsw-alias-border-l2-darkmode-thin)',\n borderRadius: 8,\n background: 'var(--dsw-alias-interactive-bg-hover-solid)',\n cursor: 'zoom-in',\n },\n tile: { width: 64, height: 64 },\n img: { width: '100%', height: '100%', objectFit: 'cover', display: 'block' },\n loading: {\n fontSize: 12,\n color: 'var(--dsw-alias-label-tertiary)',\n padding: '0 8px',\n },\n error: {\n fontSize: 12,\n color: 'var(--dsw-alias-state-error-primary)',\n cursor: 'pointer',\n border: '1px solid var(--dsw-alias-border-l2-darkmode-thin)',\n borderRadius: 8,\n background: 'transparent',\n padding: '6px 10px',\n },\n overlay: {\n position: 'fixed',\n inset: 0,\n zIndex: 1000,\n display: 'grid',\n placeItems: 'center',\n background: 'rgba(0, 0, 0, 0.72)',\n padding: 24,\n },\n overlayImg: {\n maxWidth: '92vw',\n maxHeight: '92vh',\n objectFit: 'contain',\n borderRadius: 4,\n },\n close: {\n position: 'absolute',\n top: 12,\n right: 12,\n width: 32,\n height: 32,\n display: 'grid',\n placeItems: 'center',\n border: 'none',\n borderRadius: '50%',\n cursor: 'pointer',\n background: 'rgba(255, 255, 255, 0.16)',\n color: '#fff',\n fontSize: 16,\n lineHeight: 1,\n },\n}\n\n/**\n * Full-viewport original-image preview: backdrop or close-control click and\n * Escape all dismiss; the image itself is inert so a click on it does not\n * fall through to the backdrop dismissal.\n */\nfunction ImageLightbox({\n src,\n alt,\n labels,\n onClose,\n}: {\n src: string\n alt: string\n labels: ImageLightboxLabels\n onClose: () => void\n}) {\n useEffect(() => {\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => {\n window.removeEventListener('keydown', onKey)\n }\n }, [onClose])\n return (\n <div\n role=\"dialog\"\n aria-label={labels.dialog}\n style={styles.overlay}\n onClick={onClose}\n >\n <img\n src={src}\n alt={alt}\n style={styles.overlayImg}\n onClick={(event) => {\n event.stopPropagation()\n }}\n />\n <button\n type=\"button\"\n aria-label={labels.close}\n style={styles.close}\n onClick={onClose}\n >\n ×\n </button>\n </div>\n )\n}\n\n/**\n * Compact history renderer with retryable loading and click-to-open original\n * preview. A lone image renders at its `singleFit` size; an image among\n * several renders as a fixed 64px square tile.\n */\nexport function MessageImage({\n attachment,\n load,\n variant,\n labels,\n}: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n variant: 'single' | 'tile'\n labels: MessageImageLabels\n}) {\n const [src, setSrc] = useState<string | null>(null)\n const [error, setError] = useState(false)\n const [open, setOpen] = useState(false)\n // Retry re-arms the one load effect below, so every attempt — first load or\n // retry — runs under the same liveness guard and the same reset.\n const [attempt, setAttempt] = useState(0)\n const retry = useCallback(() => {\n setAttempt((a) => a + 1)\n }, [])\n const close = useCallback(() => {\n setOpen(false)\n }, [])\n const fit = useMemo(\n () => (variant === 'single' ? singleFit(attachment) : undefined),\n [attachment, variant],\n )\n\n useEffect(() => {\n let live = true\n setError(false)\n setSrc(null)\n void load(attachment)\n .then((url) => {\n if (live) setSrc(url)\n })\n .catch(() => {\n if (live) setError(true)\n })\n return () => {\n live = false\n }\n }, [attachment, load, attempt])\n\n const label = attachment.name ?? labels.image\n if (error) {\n return (\n <button type=\"button\" style={styles.error} onClick={retry}>\n {labels.loadFailed}\n </button>\n )\n }\n const box =\n fit === undefined ? styles.tile : { width: fit.width, height: fit.height }\n return (\n <>\n <button\n type=\"button\"\n style={{ ...styles.frame, ...box }}\n title={labels.open}\n aria-label={labels.openNamed(label)}\n onClick={() => {\n if (src !== null) setOpen(true)\n }}\n >\n {src === null ? (\n <span style={styles.loading}>{labels.loading}</span>\n ) : (\n <img\n src={src}\n alt={label}\n style={{ ...styles.img, objectPosition: fit?.objectPosition }}\n />\n )}\n </button>\n {open && src !== null && (\n <ImageLightbox\n src={src}\n alt={label}\n labels={labels.lightbox}\n onClose={close}\n />\n )}\n </>\n )\n}\n\n/** Wrapping image group: a lone image renders large, several render as 64px\n * square tiles (same rule as the platform gallery). */\nexport function ImageGallery({\n images,\n load,\n labels,\n}: {\n images: readonly { attachment: ImageAttachmentRef }[]\n load: ImageLoader\n labels: MessageImageLabels\n}) {\n if (images.length === 0) return null\n const variant = images.length === 1 ? 'single' : 'tile'\n return (\n <div style={styles.gallery}>\n {images.map((image, index) => (\n <MessageImage\n key={`${image.attachment.attachmentId}:${index}`}\n attachment={image.attachment}\n load={load}\n variant={variant}\n labels={labels}\n />\n ))}\n </div>\n )\n}\n","/**\n * Everything the client half assumes about the DSH host that the compiler\n * cannot check.\n *\n * The client bundle reads host modules at runtime, not at build time. A\n * renamed icon export compiles against the old type declarations and then\n * renders `undefined`. A slot outlet the host stops rendering never mounts our\n * entry, so the page looks normal and the feature is just gone. A removed DOM\n * marker only breaks layout. None of these fail `tsc`, and a unit test with\n * a hand-made host cannot see them either.\n *\n * So each such assumption is listed here once, next to the host package that\n * owns it. `scripts/check-host-contract.mjs` downloads every supported DSH\n * version and checks that each entry appears in that version's published\n * code. The host E2E reads the same diagnostics entries to catch slot\n * crashes. The spec test/host-contract.spec.ts scans src/client and fails\n * when code starts relying on a literal host name that is missing here.\n *\n * This module has no imports, so plain Node scripts can import it directly.\n */\n\n/** Prefix of the console warning the client logs when a host lacks a listed name. */\nexport const HOST_CONTRACT_MISS = 'dsh-subscriptions: host contract miss'\n\nexport const HOST_CONTRACT = {\n /**\n * Host modules the client bundle loads by specifier. The web shell serves\n * only the modules in its static module table (`staticModules` in\n * dsh-web-frontend), so each specifier the built lib/client.js loads must\n * be a key of that table.\n */\n moduleTable: '@deepseek-ai/dsh-web-frontend',\n\n /** Named runtime exports the client reads from a host module. */\n exports: {\n '@deepseek-ai/dsh-client-ui-primitives': [\n 'useAnchoredPosition',\n 'useDismissOnOutsidePointer',\n ],\n },\n\n /**\n * 16px glyphs read through hostIcon(). The host must export\n * `Icon<Name>Regular` (DSH 0.1.7 and later) or `Icon<Name>16` (earlier).\n */\n icons: {\n package: '@deepseek-ai/dsh-client-ui-primitives',\n names: ['Sparkle', 'DataOutline'],\n },\n\n /** Slots the client registers into, each with the package that renders its outlet. */\n slots: {\n 'settings.section': '@deepseek-ai/dsh-client-ui-settings-general',\n 'tool.call.toolview': '@deepseek-ai/dsh-client-ui-tool',\n 'conversation.input.right': '@deepseek-ai/dsh-client-ui-conversation',\n 'conversation.composer.dock': '@deepseek-ai/dsh-client-ui-conversation',\n },\n\n /**\n * Context services the client injects or reads, each with the package that\n * provides it (`ctx.provide(\"<name>\")` or a cordis Service named `<name>`).\n * A service nobody provides leaves the plugin's apply() waiting forever,\n * with nothing in the console.\n */\n services: {\n commandUi: '@deepseek-ai/dsh-client-ui-commands',\n connection: '@deepseek-ai/dsh-client-connection',\n locale: '@deepseek-ai/dsh-client-locale',\n modelDirectories: '@deepseek-ai/dsh-client-ui-model-selection',\n slots: '@deepseek-ai/dsh-client-ui-renderer',\n },\n\n /** DOM attributes the client looks up in host-rendered markup. */\n markers: {\n /**\n * Stats pill anchors, by role. `row` is the shared stats row through DSH\n * 0.2.0; the badge portals into it. `dock` is the per-pill anchor from\n * 0.2.1; the badge stays in its dock entry and stops watching once that\n * anchor is in scope. A host renders one of them. The package check\n * accepts either spelling; callers read `row` and `dock` by name.\n */\n composerStats: {\n row: 'data-composer-stats',\n dock: 'data-composer-stat',\n package: '@deepseek-ai/dsh-client-ui-chat',\n },\n },\n\n /**\n * What the slot renderer emits when an entry throws. It catches the error,\n * logs `crashLog`, and renders an element carrying `errorAttribute` in the\n * entry's place, so a crash never reaches the page's error handlers. The\n * host E2E watches for both.\n */\n diagnostics: {\n package: '@deepseek-ai/dsh-client-ui-renderer',\n crashLog: 'slot entry crashed in',\n errorAttribute: 'data-slot-error',\n slotAttribute: 'data-slot',\n },\n\n /** Design tokens the client styles with; the host theme must define each one. */\n tokens: {\n package: '@deepseek-ai/dsh-client-ui-theme',\n names: [\n '--dsw-alias-bg-layer-1',\n '--dsw-alias-bg-layer-2',\n '--dsw-alias-bg-layer-3',\n '--dsw-alias-bg-mask-1',\n '--dsw-alias-bg-skeleton',\n '--dsw-alias-border-l1',\n '--dsw-alias-border-l2',\n '--dsw-alias-border-l2-darkmode-thin',\n '--dsw-alias-border-l3',\n '--dsw-alias-border-l4',\n '--dsw-alias-brand-primary',\n '--dsw-alias-button-primary-fill',\n '--dsw-alias-button-primary-hover',\n '--dsw-alias-interactive-bg-active',\n '--dsw-alias-interactive-bg-hover',\n '--dsw-alias-interactive-bg-hover-solid',\n '--dsw-alias-label-dimmed',\n '--dsw-alias-label-primary',\n '--dsw-alias-label-primary-foreground',\n '--dsw-alias-label-secondary',\n '--dsw-alias-label-tertiary',\n '--dsw-alias-settings-card-fill',\n '--dsw-alias-settings-card-stroke',\n '--dsw-alias-state-business-primary',\n '--dsw-alias-state-error-primary',\n '--dsw-alias-state-success-primary',\n '--dsw-alias-state-warn-label',\n '--dsw-elevation-prominent',\n '--dsw-focus-ring-color',\n '--dsw-focus-ring-width',\n '--dsw-mask-blur',\n '--dsw-menu-backdrop-filter',\n '--dsw-radius-lg',\n '--dsw-radius-md',\n '--dsw-radius-panel',\n '--dsw-radius-sm',\n '--dsw-radius-xl',\n '--dsw-specific-menu',\n ],\n },\n} as const\n\n/** A glyph name listed in {@link HOST_CONTRACT}; hostIcon() accepts no other. */\nexport type HostIconName = (typeof HOST_CONTRACT.icons.names)[number]\n\n/** Attribute selector for a host DOM marker (`data-composer-stats` → `[data-composer-stats]`). */\nexport function markerSelector(attribute: string): string {\n return `[${attribute}]`\n}\n","/**\n * Glyphs from the host's icon set that survive its renames. DSH 0.1.7\n * renamed the 16px glyphs from `Icon<Name>16` to `Icon<Name>Regular`. The\n * client reads host modules at runtime, so a named import of a glyph the\n * host no longer exports is `undefined`, and rendering it crashes the whole\n * slot (React error #130).\n *\n * A glyph name must be listed in HOST_CONTRACT.icons, which\n * scripts/check-host-contract.mjs checks against each supported DSH version.\n */\nimport type { ComponentType } from 'react'\nimport type { IconProps } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { HOST_CONTRACT, HOST_CONTRACT_MISS } from './host-contract.js'\nimport type { HostIconName } from './host-contract.js'\n\n/** A decorative glyph the host lacks renders nothing rather than crashing. */\nconst NoIcon: ComponentType<IconProps> = () => null\n\n/**\n * Resolve one 16px glyph under either host naming.\n *\n * A glyph the host lacks renders nothing, and the lookup logs a\n * {@link HOST_CONTRACT_MISS} warning. The host E2E fails on that warning, so a\n * missing icon is reported instead of shipping as a blank space.\n * @param icons - the host primitives module (`import * as`), read by name.\n * @param name - the glyph name without prefix or size, e.g. `Sparkle`.\n * @returns the host's component, or one rendering nothing.\n */\nexport function hostIcon(\n icons: object,\n name: HostIconName,\n): ComponentType<IconProps> {\n const exports = icons as Record<string, ComponentType<IconProps> | undefined>\n const icon = exports[`Icon${name}Regular`] ?? exports[`Icon${name}16`]\n if (icon !== undefined) return icon\n console.warn(\n `${HOST_CONTRACT_MISS}: ${HOST_CONTRACT.icons.package} exports neither Icon${name}Regular nor Icon${name}16`,\n )\n return NoIcon\n}\n","/**\n * Keyed toolview for the `image_generate` tool: renders generated images\n * inline in the conversation. The row shows the call's prompt while running\n * and after settling; a settled result with image blocks renders them through\n * this plugin's own ImageGallery (harness rc.8 stopped exporting the platform\n * one as a package value), whose bytes load through the node half's\n * `/subscriptions-auth` RPC channel (the durable ImageAttachmentRef is never\n * a fetchable URL on its own). A text-only settled result (degraded route)\n * renders its text; an error result renders the first error line.\n *\n * The 'tool.call.toolview' slot contract is owned by ui-tool\n * (packages/client/ui-tool/src/client/contract/slots.ts), which this package\n * does not resolve; the SlotMap merge and ToolCallOwnerProps below mirror it\n * structurally (same discipline as platform-modules.d.ts).\n */\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\nimport { ImageGallery } from './ImageGallery.js'\nimport type {\n ImageAttachmentRef,\n ImageLoader,\n MessageImageLabels,\n} from './ImageGallery.js'\nimport { hostIcon } from './host-icons.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** DSH 0.1.7 renamed IconSparkle16; resolving it by name keeps older hosts working too. */\nconst SparkleIcon = hostIcon(primitives, 'Sparkle')\n\n/** Title prompt truncation budget (characters). */\nconst PROMPT_MAX_LENGTH = 60\n\n/** Mirror of ui-tool's ToolCallOwnerProps (see the module header). */\ninterface ToolCallOwnerProps {\n callId: string\n toolName: string\n block: ToolCallBlock\n cwd?: string | undefined\n openFile: (path: string) => void\n inspect?: (() => void) | undefined\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n /** Mirror of ui-tool's keyed atomic Tool view declaration (see the module header). */\n 'tool.call.toolview': {\n kind: 'keyed'\n scope: 'session'\n owner: ToolCallOwnerProps\n }\n }\n}\n\n/** Injected dependencies of {@link ImageGenerateToolview} (slot `inject`). */\nexport interface ImageGenerateToolviewInjected {\n /** Session-authorized image URL loader riding the `/subscriptions-auth` channel. */\n load: ImageLoader\n}\n\n/**\n * Props delivered by the toolview outlet: the owner share plus the inject\n * face and the framework locale seat, spread flat.\n */\nexport type ImageGenerateToolviewProps = Partial<ToolCallOwnerProps> &\n Partial<ImageGenerateToolviewInjected> & {\n t?:\n | ((key: SubscriptionsKey, params?: Record<string, unknown>) => string)\n | undefined\n }\n\n/** `image` endpoint result: the node half owns this shape. */\ninterface ImageEndpointResult {\n mediaType: string\n dataBase64: string\n}\n\n/**\n * Build the ImageGallery loader over the `image` endpoint.\n * @param rpc - Connection RPC caller.\n * @returns loader resolving an attachment ref to a data URL.\n */\nexport function createImageLoader(rpc: ConnectionHandle['rpc']): ImageLoader {\n // The host validates a full ImageAttachmentRef payload (readImage takes the\n // whole ref), so forward the attachment verbatim.\n return (attachment) =>\n callSubscriptionsAuth<ImageEndpointResult>(rpc, 'image', {\n ...attachment,\n }).then((result) => `data:${result.mediaType};base64,${result.dataBase64}`)\n}\n\n/**\n * English-dictionary fallback for a missing locale seat (standalone renders);\n * the framework always supplies the namespace-bound one.\n * @param key - dictionary key.\n * @param params - `{name}` template params.\n * @returns the template with params substituted.\n */\nfunction fallbackTranslate(\n key: SubscriptionsKey,\n params?: Record<string, unknown>,\n): string {\n let text: string = en[key]\n for (const [name, value] of Object.entries(params ?? {})) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\n/** Extract the prompt from the call's raw args JSON; falls back to the first string value, then the raw line. */\nfunction derivePrompt(argsRaw: string): string {\n let parsed: unknown\n try {\n parsed = JSON.parse(argsRaw)\n } catch {\n // Non-JSON args (mid-stream truncation): fall back to the raw string below.\n parsed = undefined\n }\n let prompt: string | undefined\n if (typeof parsed === 'object' && parsed !== null) {\n const args = parsed as Record<string, unknown>\n if (typeof args.prompt === 'string' && args.prompt !== '')\n prompt = args.prompt\n else {\n for (const value of Object.values(args)) {\n if (typeof value === 'string' && value !== '') {\n prompt = value\n break\n }\n }\n }\n }\n const line = (prompt ?? argsRaw).split('\\n', 1)[0] ?? ''\n return line.length > PROMPT_MAX_LENGTH\n ? `${line.slice(0, PROMPT_MAX_LENGTH)}…`\n : line\n}\n\n/** Flatten a settled result's text blocks (the degraded text-only route and the error line). */\nfunction resultText(block: ToolCallBlock): string {\n if (!('kind' in block)) return ''\n const parts: string[] = []\n for (const part of block.content) {\n if (part.type === 'text') parts.push(part.text)\n }\n if (parts.length === 0 && block.error !== undefined)\n parts.push(`${block.error.name}: ${block.error.code}`)\n return parts.join('\\n')\n}\n\n/** Image attachments of a settled result; empty while running or on the text-only route. */\nfunction resultImages(\n block: ToolCallBlock,\n): { attachment: ImageAttachmentRef }[] {\n if (!('kind' in block)) return []\n const images: { attachment: ImageAttachmentRef }[] = []\n for (const part of block.content) {\n if (part.type === 'image')\n images.push({ attachment: part.attachment as ImageAttachmentRef })\n }\n return images\n}\n\nconst styles: Record<string, CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n padding: '4px 0',\n },\n row: { display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 },\n icon: {\n display: 'inline-flex',\n flexShrink: 0,\n color: 'var(--dsw-alias-label-tertiary)',\n },\n title: {\n fontSize: 13,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n subtle: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n output: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-secondary)',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'anywhere',\n },\n error: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-state-error-primary)',\n },\n}\n\n/**\n * The `image_generate` keyed toolview component.\n * @param props - owner share, inject face, and locale seat (spread flat).\n * @returns the call row plus, once settled, the gallery / text / error body.\n */\nexport function ImageGenerateToolview(props: ImageGenerateToolviewProps) {\n const { block, load } = props\n const t = props.t ?? fallbackTranslate\n if (block === undefined) return null\n const settled = 'kind' in block\n const argsRaw =\n (settled\n ? block.call?.argsRaw\n : block.phase === 'start'\n ? block.argsRaw\n : undefined) ?? ''\n let references = 0\n try {\n const args = JSON.parse(argsRaw)\n if (Array.isArray(args?.referenceImages))\n references = args.referenceImages.length\n } catch {\n /* Arguments may still be streaming. */\n }\n const title = `image_generate${references > 0 ? ` (${references} ref)` : ''}: ${derivePrompt(argsRaw)}`\n const images = resultImages(block)\n const text = settled ? resultText(block) : ''\n const labels: MessageImageLabels = {\n image: t('image'),\n open: t('viewImage'),\n openNamed: (name) => t('viewImageNamed', { name }),\n loading: t('imageLoading'),\n loadFailed: t('imageLoadFailed'),\n lightbox: { dialog: t('imagePreview'), close: t('imageClose') },\n }\n return (\n <div style={styles.container}>\n <div style={styles.row}>\n <span style={styles.icon}>\n <SparkleIcon size={14} />\n </span>\n <span style={styles.title}>{title}</span>\n </div>\n {!settled && <p style={styles.subtle}>{t('generating')}</p>}\n {settled && block.isError && text !== '' && (\n <p style={styles.error}>{text.split('\\n', 1)[0]}</p>\n )}\n {settled && !block.isError && images.length > 0 && load !== undefined && (\n <ImageGallery images={images} load={load} labels={labels} />\n )}\n {settled && !block.isError && images.length === 0 && text !== '' && (\n <p style={styles.output}>{text}</p>\n )}\n </div>\n )\n}\n","/**\n * Keyed toolview for the `video_generate` tool: renders the generated video\n * inline in the conversation. The row shows the call's prompt while running\n * and after settling; a settled success loads the MP4 bytes through the node\n * half's `/subscriptions-auth` `video` endpoint (by bare file name), builds a\n * Blob URL, and plays it in a native `<video controls>` element. The file\n * name comes from the result's presentation meta when the dispatch was\n * top-level, and is recovered from the \"Saved video to …\" text line for\n * nested (Code Mode) dispatches, where the harness computes no meta. A result\n * with neither renders its text; an error result renders the first error line.\n *\n * The 'tool.call.toolview' SlotMap entry is declared by\n * ImageGenerateToolview.tsx in this same package (one declaration per\n * augmentation), so this file only mirrors the owner-props shape.\n */\nimport { useEffect, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\nimport { hostIcon } from './host-icons.js'\nimport { callSubscriptionsAuth } from './subscriptions-rpc.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** DSH 0.1.7 renamed IconSparkle16; resolving it by name keeps older hosts working too. */\nconst SparkleIcon = hostIcon(primitives, 'Sparkle')\n\n/** Title prompt truncation budget (characters). */\nconst PROMPT_MAX_LENGTH = 60\n\n/** Mirror of ui-tool's ToolCallOwnerProps (see ImageGenerateToolview). */\ninterface ToolCallOwnerProps {\n callId: string\n toolName: string\n block: ToolCallBlock\n cwd?: string | undefined\n openFile: (path: string) => void\n inspect?: (() => void) | undefined\n}\n\n/** Decoded video bytes as the node half's `video` endpoint answers them. */\nexport interface VideoBytes {\n mediaType: string\n dataBase64: string\n}\n\n/** Injected dependencies of {@link VideoGenerateToolview} (slot `inject`). */\nexport interface VideoGenerateToolviewInjected {\n /** Loads one generated video's bytes by bare file name. */\n loadVideo: (name: string) => Promise<VideoBytes>\n}\n\n/**\n * Props delivered by the toolview outlet: the owner share plus the inject\n * face and the framework locale seat, spread flat.\n */\nexport type VideoGenerateToolviewProps = Partial<ToolCallOwnerProps> &\n Partial<VideoGenerateToolviewInjected> & {\n t?:\n | ((key: SubscriptionsKey, params?: Record<string, unknown>) => string)\n | undefined\n }\n\n/**\n * Build the video loader over the `/subscriptions-auth` `video` endpoint.\n * @param rpc - Connection RPC caller.\n * @returns loader resolving a bare file name to the decoded bytes.\n */\nexport function createVideoLoader(\n rpc: ConnectionHandle['rpc'],\n): (name: string) => Promise<VideoBytes> {\n return (name) => callSubscriptionsAuth<VideoBytes>(rpc, 'video', { name })\n}\n\n/**\n * English-dictionary fallback for a missing locale seat (standalone renders);\n * the framework always supplies the namespace-bound one.\n */\nfunction fallbackTranslate(\n key: SubscriptionsKey,\n params?: Record<string, unknown>,\n): string {\n let text: string = en[key]\n for (const [name, value] of Object.entries(params ?? {})) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\n/** Extract the prompt from the call's raw args JSON; falls back to the first string value, then the raw line. */\nfunction derivePrompt(argsRaw: string): string {\n let parsed: unknown\n try {\n parsed = JSON.parse(argsRaw)\n } catch {\n // Non-JSON args (mid-stream truncation): fall back to the raw string below.\n parsed = undefined\n }\n let prompt: string | undefined\n if (typeof parsed === 'object' && parsed !== null) {\n const args = parsed as Record<string, unknown>\n if (typeof args.prompt === 'string' && args.prompt !== '')\n prompt = args.prompt\n else {\n for (const value of Object.values(args)) {\n if (typeof value === 'string' && value !== '') {\n prompt = value\n break\n }\n }\n }\n }\n const line = (prompt ?? argsRaw).split('\\n', 1)[0] ?? ''\n return line.length > PROMPT_MAX_LENGTH\n ? `${line.slice(0, PROMPT_MAX_LENGTH)}…`\n : line\n}\n\n/** Flatten a settled result's text blocks (the fallback body and the error line). */\nfunction resultText(block: ToolCallBlock): string {\n if (!('kind' in block)) return ''\n const parts: string[] = []\n for (const part of block.content) {\n if (part.type === 'text') parts.push(part.text)\n }\n if (parts.length === 0 && block.error !== undefined)\n parts.push(`${block.error.name}: ${block.error.code}`)\n return parts.join('\\n')\n}\n\n/**\n * The generated video's bare file name: presentation meta first (top-level\n * dispatches), then the render text's \"Saved video to …\" line (nested\n * dispatches compute no meta).\n */\nfunction resolveFileName(block: ToolCallBlock): string | undefined {\n if (!('kind' in block)) return undefined\n const meta = block.meta\n if (typeof meta === 'object' && meta !== null) {\n const fileName = (meta as Record<string, unknown>).fileName\n if (typeof fileName === 'string' && fileName.length > 0) return fileName\n }\n const match = /^Saved video to (.+\\.mp4)/m.exec(resultText(block))\n if (match === null) return undefined\n const path = match[1]\n return path.slice(path.lastIndexOf('/') + 1)\n}\n\n/** Decode a base64 payload into bytes (browser-side; no Buffer). */\nfunction base64Bytes(dataBase64: string): Uint8Array {\n const binary = atob(dataBase64)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index++)\n bytes[index] = binary.charCodeAt(index)\n return bytes\n}\n\n/** Loading lifecycle of the Blob URL. */\ntype LoadState =\n | { phase: 'loading' }\n | { phase: 'ready'; url: string }\n | { phase: 'failed'; message: string }\n\nconst styles: Record<string, CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n padding: '4px 0',\n },\n row: { display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 },\n icon: {\n display: 'inline-flex',\n flexShrink: 0,\n color: 'var(--dsw-alias-label-tertiary)',\n },\n title: {\n fontSize: 13,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n subtle: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n output: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-secondary)',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'anywhere',\n },\n error: {\n margin: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-state-error-primary)',\n },\n video: {\n display: 'block',\n maxWidth: 480,\n width: '100%',\n borderRadius: 8,\n backgroundColor: 'var(--dsw-alias-bg-skeleton)',\n },\n}\n\n/**\n * The `video_generate` keyed toolview component.\n * @param props - owner share, inject face, and locale seat (spread flat).\n * @returns the call row plus, once settled, the player / text / error body.\n */\nexport function VideoGenerateToolview(props: VideoGenerateToolviewProps) {\n const { block, loadVideo } = props\n const t = props.t ?? fallbackTranslate\n const settled = block !== undefined && 'kind' in block\n const isError = settled && block.isError\n const fileName =\n block !== undefined && settled && !isError\n ? resolveFileName(block)\n : undefined\n const [load, setLoad] = useState<LoadState>({ phase: 'loading' })\n\n useEffect(() => {\n if (fileName === undefined || loadVideo === undefined) return\n let cancelled = false\n let objectUrl: string | undefined\n setLoad({ phase: 'loading' })\n loadVideo(fileName).then(\n (video) => {\n if (cancelled) return\n // Uint8Array#slice detaches a plain ArrayBuffer view for BlobPart.\n objectUrl = URL.createObjectURL(\n new Blob([base64Bytes(video.dataBase64).slice()], {\n type: video.mediaType,\n }),\n )\n setLoad({ phase: 'ready', url: objectUrl })\n },\n (error: unknown) => {\n if (cancelled) return\n setLoad({\n phase: 'failed',\n message: error instanceof Error ? error.message : String(error),\n })\n },\n )\n return () => {\n cancelled = true\n if (objectUrl !== undefined) URL.revokeObjectURL(objectUrl)\n }\n }, [fileName, loadVideo])\n\n if (block === undefined) return null\n const argsRaw =\n (settled\n ? block.call?.argsRaw\n : block.phase === 'start'\n ? block.argsRaw\n : undefined) ?? ''\n const title = `video_generate: ${derivePrompt(argsRaw)}`\n const text = settled ? resultText(block) : ''\n return (\n <div style={styles.container}>\n <div style={styles.row}>\n <span style={styles.icon}>\n <SparkleIcon size={14} />\n </span>\n <span style={styles.title}>{title}</span>\n </div>\n {!settled && <p style={styles.subtle}>{t('generatingVideo')}</p>}\n {settled && isError && text !== '' && (\n <p style={styles.error}>{text.split('\\n', 1)[0]}</p>\n )}\n {settled &&\n !isError &&\n fileName !== undefined &&\n load.phase === 'loading' && (\n <p style={styles.subtle}>{t('videoLoading')}</p>\n )}\n {settled &&\n !isError &&\n fileName !== undefined &&\n load.phase === 'failed' && (\n <p style={styles.error}>\n {t('videoLoadFailed', { message: load.message })}\n </p>\n )}\n {settled &&\n !isError &&\n fileName !== undefined &&\n load.phase === 'ready' && (\n // Generated clip; no caption track exists.\n <video\n style={styles.video}\n src={load.url}\n controls\n preload=\"metadata\"\n />\n )}\n {settled && !isError && fileName === undefined && text !== '' && (\n <p style={styles.output}>{text}</p>\n )}\n </div>\n )\n}\n","/**\n * Codex Speed toggle: one small control in the composer's right tool row\n * (`conversation.input.right`), switching the session between standard routing\n * and the fast (priority) service tier — the Codex desktop app's Speed menu.\n * The choice is per session and lives in the node half (in-memory); this\n * component holds only viewing state. The control renders nothing until the\n * first load proves the session's current model is a codex model whose catalog\n * advertises the fast tier.\n *\n * Every color resolves through a `--dsw-alias-*` design token and every\n * user-visible string goes through the locale `t` of the\n * 'settings.subscriptions' namespace, same as the settings section.\n */\nimport { useEffect, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type {\n PropsLocale,\n PropsRuntime,\n} from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport { callSubscriptionsAuth } from './SubscriptionsSection.js'\nimport { subscriptionChromeCss } from './provider-settings-styles.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\n\n/** One session's speed choice: standard routing or the fast (priority) tier. */\nexport type SpeedTier = 'standard' | 'fast'\n\n/** `speed` endpoint value, mirrored from the node half. */\nexport interface SpeedState {\n tier: SpeedTier\n fastModels: string[]\n}\n\n/** What {@link SpeedSelect} renders from: visibility plus the current tier. */\nexport interface SpeedSelectState {\n visible: boolean\n tier: SpeedTier\n}\n\n/**\n * Minimal structural face of ui-model-selection's `ctx.modelDirectories`\n * service (the sanctioned cross-plugin channel: cordis services, not value\n * imports — same mirroring discipline as ToolCallOwnerProps). Both dsh lines\n * ship it with this shape; it replaces rc.2's `connection.api.sessions.models`\n * read, which the 0.1.2-alpha removed along with the whole `.api` face.\n */\n/** Selected model pushed by ui-model-selection's directory store. */\nexport interface ModelSelectionSnapshot {\n current: { provider: string; model: string } | null\n}\n\n/**\n * The directory store (`ModelDirectory.store`). Present on hosts that publish\n * selection changes; absent on a directory that only offers `load()`.\n */\nexport interface ModelSelectionStore {\n subscribe(listener: () => void): () => void\n getSnapshot(): ModelSelectionSnapshot\n}\n\nexport interface ModelDirectoriesLike {\n /** Resolve one session's shared model directory (throws for unknown sessions). */\n directoryFor(sessionId: string): {\n /** Load the directory; `current` is the session's effective model selection. */\n load(): Promise<ModelSelectionSnapshot>\n /** Pushes selection changes. Missing when the host only offers `load()`. */\n store?: ModelSelectionStore\n }\n}\n\n/** Injected dependencies of {@link SpeedSelect} (slot `inject`, session-bound). */\nexport interface SpeedSelectInjected {\n /** Load the session's speed state; `visible` false keeps the control hidden. */\n loadSpeed: () => Promise<SpeedSelectState>\n /** Set the session's speed tier; resolves false when the write failed. */\n setSpeed: (tier: SpeedTier) => Promise<boolean>\n /**\n * Subscribe to the session's selected model. The listener runs when\n * `provider` or `model` changes, and once when a directory that was missing\n * at subscribe time becomes available. The returned function detaches it.\n */\n watchModel: (listener: () => void) => () => void\n}\n\n/**\n * Props delivered by the slot outlet: the framework session kit and InputZone\n * owner share (unused — everything arrives session-bound through the inject\n * face), the injected callbacks, and the locale seat.\n */\nexport type SpeedSelectProps = PropsRuntime<'conversation.input.right'> &\n Partial<SpeedSelectInjected> &\n Partial<PropsLocale<'settings.subscriptions'>>\n\n/**\n * The `loadSpeed` half of the inject face: the plugin's own speed state plus\n * the host's current model selection (the visibility gate). A session whose\n * model selection is unavailable (an addressed subagent) answers hidden.\n * Any other model-directory failure throws, so the caller keeps its last\n * known state instead of locking the toggle away.\n *\n * `sessionId` is a plain string: slot and command contexts brand it through\n * different dsh-session copies, and only the service boundary needs one.\n *\n * `models` resolves lazily per call: the ui-model-selection service may\n * register after this plugin applies, and a shell without it (no model seat\n * at all) simply keeps the toggle hidden.\n */\nexport function createSpeedLoader(\n connection: ConnectionHandle,\n models: () => ModelDirectoriesLike | undefined,\n sessionId: string,\n): SpeedSelectInjected['loadSpeed'] {\n return async () => {\n const state = await callSubscriptionsAuth<SpeedState>(\n connection.rpc,\n 'speed',\n { sessionId },\n )\n const directories = models()\n if (directories === undefined) return { visible: false, tier: state.tier }\n let current: ModelSelectionSnapshot['current']\n try {\n const loaded = await directories.directoryFor(sessionId).load()\n current = loaded.current\n } catch (error) {\n if (!modelSelectionUnavailable(error)) throw error\n return { visible: false, tier: state.tier }\n }\n const visible =\n current !== null &&\n current.provider === 'codex' &&\n state.fastModels.includes(current.model)\n return { visible, tier: state.tier }\n }\n}\n\n/** Host copy for a session that has no model seat (an addressed subagent). */\nconst MODEL_SELECTION_UNAVAILABLE = 'model selection is unavailable'\n\nfunction modelSelectionUnavailable(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error)\n return message.includes(MODEL_SELECTION_UNAVAILABLE)\n}\n\n/** Stable identity of a model selection. Empty when nothing is selected. */\nexport function modelSelectionKey(\n current: ModelSelectionSnapshot['current'] | undefined,\n): string {\n if (current == null) return ''\n return JSON.stringify([current.provider, current.model])\n}\n\n/**\n * How often a host without a directory store is re-read, and how often a\n * missing directory service is retried. Neither interval calls\n * `subscriptions-auth.speed`.\n */\nexport const MODEL_DIRECTORY_POLL_INTERVAL_MS = 3000\n\n/**\n * Mount reads of `speed`, including the first attempt. Further failures stop\n * instead of polling for the life of the composer.\n */\nexport const SPEED_MOUNT_READ_ATTEMPTS = 4\n\n/** Fired after `/fast` writes a tier, so an open composer re-reads `speed`. */\nexport const SPEED_CHANGED_EVENT = 'dsh:subscriptions:speed-changed'\n\n/** Tell mounted Speed controls that this page changed a session tier. */\nexport function notifySpeedChanged(): void {\n if (typeof window === 'undefined') return\n window.dispatchEvent(new Event(SPEED_CHANGED_EVENT))\n}\n\n/**\n * Subscribe to the session's selected model. A directory store notifies the\n * listener only when `provider` or `model` changes. A directory with no store\n * is re-read on {@link MODEL_DIRECTORY_POLL_INTERVAL_MS}; a service that is\n * not registered yet, or whose `directoryFor` throws, is retried on that same\n * interval. The first successful attach after a miss notifies once, so a\n * mount that ran before the service existed reads `speed` again.\n */\nexport function createModelSelectionWatch(\n models: () => ModelDirectoriesLike | undefined,\n sessionId: string,\n): SpeedSelectInjected['watchModel'] {\n return (listener) => {\n let stopped = false\n let unsubscribeStore: (() => void) | undefined\n let timer: ReturnType<typeof setInterval> | undefined\n let mode: 'seek' | 'store' | 'poll' = 'seek'\n let lastKey: string | undefined\n\n const stopTimer = (): void => {\n if (timer === undefined) return\n clearInterval(timer)\n timer = undefined\n }\n const changed = (\n current: ModelSelectionSnapshot['current'] | undefined,\n ): boolean => {\n const next = modelSelectionKey(current)\n if (lastKey === undefined) {\n lastKey = next\n return false\n }\n if (next === lastKey) return false\n lastKey = next\n return true\n }\n const attach = (late: boolean): void => {\n if (stopped || mode !== 'seek') return\n let directory:\n ReturnType<ModelDirectoriesLike['directoryFor']> | undefined\n try {\n directory = models()?.directoryFor(sessionId)\n } catch {\n return\n }\n if (directory === undefined) return\n const store = directory.store\n if (store !== undefined) {\n mode = 'store'\n stopTimer()\n lastKey = modelSelectionKey(store.getSnapshot().current)\n unsubscribeStore = store.subscribe(() => {\n if (!stopped && changed(store.getSnapshot().current)) listener()\n })\n if (late) listener()\n return\n }\n mode = 'poll'\n stopTimer()\n let force = late\n const seed = (): void => {\n void directory.load().then(\n (state) => {\n if (stopped || mode !== 'poll') return\n const identityChanged = changed(state.current)\n const forced = force\n force = false\n if (identityChanged || forced) listener()\n },\n () => {\n /* keep the last model; the next tick retries */\n },\n )\n }\n seed()\n timer = setInterval(seed, MODEL_DIRECTORY_POLL_INTERVAL_MS)\n }\n\n attach(false)\n if (mode === 'seek')\n timer = setInterval(() => {\n attach(true)\n }, MODEL_DIRECTORY_POLL_INTERVAL_MS)\n return () => {\n stopped = true\n unsubscribeStore?.()\n stopTimer()\n }\n }\n}\n\n/** The `setSpeed` half of the inject face: boolean outcome for the component's busy state. */\nexport function createSpeedSetter(\n connection: ConnectionHandle,\n sessionId: string,\n): SpeedSelectInjected['setSpeed'] {\n return (tier) =>\n callSubscriptionsAuth(connection.rpc, 'setSpeed', { sessionId, tier }).then(\n () => true,\n () => false,\n )\n}\n\n/** English-dictionary fallback for a missing inject `t` (standalone renders). */\nfunction fallbackTranslate(key: SubscriptionsKey): string {\n return en[key]\n}\n\nconst TIERS: readonly SpeedTier[] = ['standard', 'fast']\n\n/**\n * The composer Speed control: a trigger reading `速度 · 快速`/`速度 · 标准`\n * that opens a two-row menu (standard/fast with descriptions, check mark on\n * the current tier). It reads `subscriptions-auth.speed` on mount, when the\n * menu opens, when {@link SpeedSelectInjected.watchModel} reports a new\n * selected model, and when {@link notifySpeedChanged} fires. Until the first\n * read succeeds, a failure is retried on\n * {@link MODEL_DIRECTORY_POLL_INTERVAL_MS}, at most\n * {@link SPEED_MOUNT_READ_ATTEMPTS} times; after that, a failed read keeps\n * the last known state.\n */\nexport function SpeedSelect({\n loadSpeed,\n setSpeed,\n watchModel,\n t,\n}: SpeedSelectProps) {\n const translate = t ?? fallbackTranslate\n const [state, setState] = useState<SpeedSelectState | null>(null)\n const [open, setOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const rootRef = useRef<HTMLDivElement | null>(null)\n // The inject face may be re-evaluated (new callback identities) on re-render;\n // the mount effect reads through these refs, so identity churn neither\n // resubscribes nor multiplies in-flight loads.\n const loadRef = useRef(loadSpeed)\n loadRef.current = loadSpeed\n const watchRef = useRef(watchModel)\n watchRef.current = watchModel\n\n useEffect(() => {\n if (loadRef.current === undefined) return\n let cancelled = false\n let inflight = false\n let again = false\n let loadedOnce = false\n let failures = 0\n let retry: ReturnType<typeof setInterval> | undefined\n const stopRetry = (): void => {\n if (retry === undefined) return\n clearInterval(retry)\n retry = undefined\n }\n const reload = (): void => {\n const load = loadRef.current\n if (load === undefined) return\n if (inflight) {\n again = true\n return\n }\n inflight = true\n void load()\n .then(\n (loaded) => {\n if (cancelled) return\n loadedOnce = true\n stopRetry()\n setState(loaded)\n },\n () => {\n failures += 1\n if (failures >= SPEED_MOUNT_READ_ATTEMPTS) stopRetry()\n },\n )\n .finally(() => {\n inflight = false\n if (cancelled || !again) return\n again = false\n reload()\n })\n }\n reload()\n retry = setInterval(() => {\n if (!loadedOnce) reload()\n }, MODEL_DIRECTORY_POLL_INTERVAL_MS)\n const unsubscribe = watchRef.current?.(reload)\n const onSpeedChanged = (): void => {\n reload()\n }\n window.addEventListener(SPEED_CHANGED_EVENT, onSpeedChanged)\n return () => {\n cancelled = true\n unsubscribe?.()\n stopRetry()\n window.removeEventListener(SPEED_CHANGED_EVENT, onSpeedChanged)\n }\n }, [])\n\n useEffect(() => {\n if (!open) return\n const closeOutside = (event: MouseEvent): void => {\n if (!rootRef.current?.contains(event.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', closeOutside)\n return () => {\n document.removeEventListener('mousedown', closeOutside)\n }\n }, [open])\n\n if (\n loadSpeed === undefined ||\n setSpeed === undefined ||\n state === null ||\n !state.visible\n ) {\n return null\n }\n\n const choose = (tier: SpeedTier): void => {\n if (busy) return\n if (tier === state.tier) {\n setOpen(false)\n return\n }\n setBusy(true)\n void setSpeed(tier).then((ok) => {\n setBusy(false)\n if (ok) {\n setState({ visible: true, tier })\n setOpen(false)\n }\n })\n }\n\n const show = (): void => {\n setOpen(true)\n const load = loadRef.current\n if (load === undefined) return\n void load().then(setState, () => {\n /* keep showing the last good state */\n })\n }\n\n const tierName = (tier: SpeedTier): string =>\n translate(tier === 'fast' ? 'speedFast' : 'speedStandard')\n const tierDescription = (tier: SpeedTier): string =>\n translate(\n tier === 'fast' ? 'speedFastDescription' : 'speedStandardDescription',\n )\n const triggerLabel = `${translate('speed')} · ${tierName(state.tier)}`\n\n return (\n <div\n ref={rootRef}\n className=\"dsh-subscription-speed\"\n style={styles.root}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && open) {\n event.preventDefault()\n setOpen(false)\n }\n }}\n >\n <style>{subscriptionChromeCss}</style>\n {open && (\n <div style={styles.menu} role=\"menu\" aria-label={translate('speed')}>\n {TIERS.map((tier) => (\n <button\n key={tier}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={tier === state.tier}\n style={styles.item}\n disabled={busy}\n onClick={() => {\n choose(tier)\n }}\n >\n <span style={styles.itemCheck}>\n {tier === state.tier ? '✓' : ''}\n </span>\n <span style={styles.itemText}>\n <span style={styles.itemName}>{tierName(tier)}</span>\n <span style={styles.itemDescription}>\n {tierDescription(tier)}\n </span>\n </span>\n </button>\n ))}\n </div>\n )}\n <button\n type=\"button\"\n style={styles.trigger}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title={triggerLabel}\n disabled={busy}\n onClick={() => {\n if (open) setOpen(false)\n else show()\n }}\n >\n {triggerLabel}\n </button>\n </div>\n )\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: { position: 'relative', display: 'inline-flex' },\n trigger: {\n border: '0.5px solid var(--dsw-alias-border-l3)',\n borderRadius: 'var(--dsw-radius-sm, 8px)',\n background: 'var(--dsh-subscription-speed-hover, transparent)',\n color: 'var(--dsw-alias-label-secondary)',\n font: 'inherit',\n fontSize: 12,\n lineHeight: '18px',\n padding: '2px 8px',\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n menu: {\n position: 'absolute',\n bottom: '100%',\n right: 0,\n marginBottom: 4,\n minWidth: 180,\n padding: 4,\n zIndex: 20,\n background: 'var(--dsw-specific-menu, var(--dsw-alias-bg-layer-2))',\n border: 0,\n boxShadow: 'var(--dsw-elevation-prominent)',\n borderRadius: 'var(--dsw-radius-lg, 16px)',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n },\n item: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: 6,\n width: '100%',\n border: 'none',\n borderRadius: 'var(--dsw-radius-sm, 8px)',\n background: 'var(--dsh-subscription-speed-hover, transparent)',\n padding: '6px 8px',\n cursor: 'pointer',\n font: 'inherit',\n textAlign: 'left',\n },\n itemCheck: {\n width: 14,\n flexShrink: 0,\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-primary)',\n },\n itemText: { display: 'flex', flexDirection: 'column' },\n itemName: {\n fontSize: 12,\n lineHeight: '18px',\n color: 'var(--dsw-alias-label-primary)',\n },\n itemDescription: {\n fontSize: 11,\n lineHeight: '16px',\n color: 'var(--dsw-alias-label-tertiary)',\n },\n}\n","/**\n * Subscription usage badge: a stats pill in the composer's dock\n * (`conversation.composer.dock`), modelled on the host's own token-usage\n * pill. Collapsed, it shows the rate-limit windows of the provider behind the\n * session's CURRENT model (a GPT model → Codex usage, a Claude model → Claude\n * usage); clicking it opens a trigger-anchored dialog listing every logged-in\n * account of every provider, with long window lists collapsed into previews,\n * the current provider first and the default account (starred) first within\n * a provider. Model-scoped Antigravity usage follows the current model.\n *\n * Usage rides the `subscriptions-auth` usage endpoints on a slow\n * poll (the server shares its cache across UI surfaces); the current model\n * comes from ui-model-selection's `modelDirectories` service on a quicker\n * poll, since the host pushes nothing on a model switch. Renders nothing when\n * no connected provider reports usage.\n *\n * The collapsed pill reads only the default account — the same account\n * direct (non-pool) routes serve — so it stays one short segment even for a\n * provider with several accounts connected; the dialog shows them all.\n * Every color resolves through a `--dsw-*` design token, the dialog wears the\n * host's menu material (its translucent fill plus its backdrop blur), and\n * every user-visible string goes through the locale `t` of the\n * 'settings.subscriptions' namespace.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ComponentType, CSSProperties } from 'react'\nimport { subscriptionChromeCss } from './provider-settings-styles.js'\nimport { createPortal } from 'react-dom'\nimport type {\n PropsLocale,\n PropsRuntime,\n} from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\nimport {\n useAnchoredPosition,\n useDismissOnOutsidePointer,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport { callSubscriptionsAuth } from './SubscriptionsSection.js'\nimport { UsageMeter } from './UsageMeter.js'\nimport { displayUsedPercent } from './usage-pace.js'\nimport type {\n AccountStatus,\n ProviderStatus,\n ProviderUsage,\n SubscriptionProvider,\n UsageWindow,\n} from './SubscriptionsSection.js'\nimport type { ModelDirectoriesLike } from './SpeedSelect.js'\nimport { en } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\nimport { hostIcon } from './host-icons.js'\nimport { HOST_CONTRACT, markerSelector } from './host-contract.js'\nimport {\n USAGE_BADGE_REFRESH_EVENT,\n useUsageBadgeMode,\n} from './usage-badge-preferences.js'\n\n/** DSH renamed the data icon in 0.1.7; retain older supported hosts too. */\nexport function usageBadgeIcon(icons: {\n IconDataOutlineRegular?: ComponentType\n IconDataOutline16?: ComponentType\n}): ComponentType {\n return hostIcon(icons, 'DataOutline')\n}\nconst UsageBadgeIcon = usageBadgeIcon(primitives)\n\n/** How often the badge re-reads usage; the server also shares its own cache/negative-cache across UI surfaces. */\nconst USAGE_POLL_INTERVAL_MS = 15 * 60_000\n\n/** How often the badge re-reads the session's current model (model switches arrive only by asking). */\nconst MODEL_POLL_INTERVAL_MS = 3000\n\n/** How long the rotation holds one provider in `always` mode (a display cadence, not a data poll). */\nconst BADGE_ROTATION_INTERVAL_MS = 10_000\n\n/** Distance between the trigger's top edge and the dialog's bottom (host stat dialogs use the same). */\nconst PANEL_GAP = 8\n\n/** Distance kept between the dialog and each viewport edge. */\nconst PANEL_MARGIN = 12\n\n/** Injected dependencies (slot `inject`, session-bound). */\nexport interface SubscriptionUsageBadgeInjected {\n /** Connection RPC caller to reach the `subscriptions-auth` endpoints. */\n rpc: ConnectionHandle['rpc']\n /** Resolve the session's effective provider and model together. */\n currentModel: () => Promise<{ provider: string; model: string } | undefined>\n}\n\n/** Props delivered by the slot outlet + inject + the locale seat. */\nexport type SubscriptionUsageBadgeProps =\n PropsRuntime<'conversation.composer.dock'> &\n Partial<SubscriptionUsageBadgeInjected> &\n Partial<PropsLocale<'settings.subscriptions'>> &\n /** Override the rotation cadence (tests only; the slot never passes it). */\n { rotationMs?: number }\n\n/** One logged-in account's usage windows, as listed in the expanded dialog. */\nexport interface AccountUsageDisplay {\n /** Account key (the `usage` endpoint's `account` argument). */\n key: string\n /** Display handle (email / login), when the provider reports one. */\n account?: string\n plan?: string\n /** The account direct routes serve; the collapsed pill reads this one. */\n isDefault: boolean\n windows: UsageWindow[]\n observedAt?: number | undefined\n stale?: boolean | undefined\n}\n\n/** One provider's usage snapshot: every logged-in account that reports windows. */\nexport interface ProviderUsageDisplay {\n provider: BadgeProvider\n name: string\n /** Default account first, then the rest in the `status` endpoint's order. */\n accounts: AccountUsageDisplay[]\n}\n\n/** The account the collapsed pill reads: the default one, else the first listed. */\nexport function pillAccountOf(d: ProviderUsageDisplay): AccountUsageDisplay {\n return d.accounts.find((a) => a.isDefault) ?? d.accounts[0]!\n}\n\n/** Brand display names (short form for the compact badge). */\nexport type BadgeProvider =\n | SubscriptionProvider\n | 'cursor-subscription'\n | 'opencode-go'\n | 'kimi-coding'\n | 'minimax'\n | 'minimax-cn'\n | 'ollama-cloud'\n\nconst PROVIDER_NAMES: Record<BadgeProvider, string> = {\n codex: 'Codex',\n claude: 'Claude',\n grok: 'Grok',\n copilot: 'Copilot',\n antigravity: 'Antigravity',\n 'cursor-subscription': 'Cursor',\n 'opencode-go': 'OpenCode Go',\n 'kimi-coding': 'Kimi Code',\n minimax: 'MiniMax',\n 'minimax-cn': 'MiniMax CN',\n 'ollama-cloud': 'Ollama Cloud',\n}\n\nexport interface UsageRosterEntry {\n provider: BadgeProvider\n account: AccountStatus\n}\n\n/** Key of one account's cached windows: `provider:accountKey`. */\nfunction usageKeyOf(provider: BadgeProvider, account: AccountStatus): string {\n return `${provider}:${account.key}`\n}\n\n/**\n * Group per-account usage into the badge's provider rows, in roster order\n * (the `status` provider order, default account first) so rows don't jump\n * around as polls settle at different times. An account without windows is\n * left out, and so is a provider whose accounts all lack windows.\n * @param roster - accounts from {@link loadBadgeRoster}.\n * @param windowsOf - each account's windows, keyed `provider:accountKey`.\n * @param plans - the plan each usage call reported, same keys; the roster's plan is the fallback.\n * @returns one display per provider with at least one account that has windows.\n */\nexport function groupUsageDisplays(\n roster: readonly UsageRosterEntry[],\n windowsOf: ReadonlyMap<string, UsageWindow[]>,\n plans: ReadonlyMap<string, string>,\n): ProviderUsageDisplay[] {\n const byProvider = new Map<BadgeProvider, ProviderUsageDisplay>()\n for (const { provider, account } of roster) {\n const key = usageKeyOf(provider, account)\n const windows = windowsOf.get(key)\n if (windows === undefined) continue\n const plan = plans.get(key) ?? account.plan\n const row: AccountUsageDisplay = {\n key: account.key,\n isDefault: account.isDefault,\n ...(account.account === undefined ? {} : { account: account.account }),\n ...(plan === undefined ? {} : { plan }),\n windows,\n }\n const display = byProvider.get(provider)\n if (display === undefined)\n byProvider.set(provider, {\n provider,\n name: PROVIDER_NAMES[provider],\n accounts: [row],\n })\n else display.accounts.push(row)\n }\n return [...byProvider.values()]\n}\n\n/** Read each account source independently so a failing endpoint cannot hide the others. */\nexport async function loadBadgeRoster(rpc: ConnectionHandle['rpc']): Promise<{\n roster: UsageRosterEntry[]\n refreshed: Set<BadgeProvider>\n}> {\n const [subscriptions, cursor, external] = await Promise.allSettled([\n callSubscriptionsAuth<{\n providers: Record<SubscriptionProvider, ProviderStatus>\n }>(rpc, 'status', {}),\n callSubscriptionsAuth<{ authenticated: boolean }>(rpc, 'cursorStatus', {}),\n callSubscriptionsAuth<\n Record<\n 'opencode-go' | 'kimi-code' | 'minimax' | 'minimax-cn' | 'ollama-cloud',\n { configured: boolean }\n >\n >(rpc, 'externalStatus', {}),\n ])\n const roster: UsageRosterEntry[] = []\n const refreshed = new Set<BadgeProvider>()\n if (subscriptions.status === 'fulfilled') {\n for (const provider of [\n 'codex',\n 'claude',\n 'grok',\n 'copilot',\n 'antigravity',\n ] as const) {\n refreshed.add(provider)\n for (const account of accountsOf(subscriptions.value.providers[provider]))\n roster.push({ provider, account })\n }\n }\n if (cursor.status === 'fulfilled') {\n refreshed.add('cursor-subscription')\n if (cursor.value.authenticated)\n roster.push({\n provider: 'cursor-subscription',\n account: { key: 'cursor', isDefault: true },\n })\n }\n if (external.status === 'fulfilled') {\n for (const [source, provider] of [\n ['opencode-go', 'opencode-go'],\n ['kimi-code', 'kimi-coding'],\n ['minimax', 'minimax'],\n ['minimax-cn', 'minimax-cn'],\n ['ollama-cloud', 'ollama-cloud'],\n ] as const) {\n refreshed.add(provider)\n if (external.value[source]?.configured)\n roster.push({\n provider,\n account: { key: source, isDefault: true },\n })\n }\n }\n return { roster, refreshed }\n}\n\nexport async function usageOf(\n rpc: ConnectionHandle['rpc'],\n { provider, account }: UsageRosterEntry,\n): Promise<ProviderUsage> {\n if (provider === 'cursor-subscription')\n return callSubscriptionsAuth(rpc, 'cursorUsage', {})\n if (\n provider === 'opencode-go' ||\n provider === 'kimi-coding' ||\n provider === 'minimax' ||\n provider === 'minimax-cn' ||\n provider === 'ollama-cloud'\n ) {\n return callSubscriptionsAuth(rpc, 'externalUsage', {\n source: provider === 'kimi-coding' ? 'kimi-code' : provider,\n })\n }\n return callSubscriptionsAuth(rpc, 'usage', { provider, account: account.key })\n}\n\n/**\n * The `currentModel` half of the inject face: the session's effective\n * model selection through ui-model-selection's `modelDirectories` service,\n * resolved lazily per call (the service may register after this plugin, and\n * a shell without it reports \"unknown\"; the badge keeps the most recent\n * subscription selected in this view, or stays hidden).\n */\nexport function createCurrentModelReader(\n models: () => ModelDirectoriesLike | undefined,\n sessionId: string,\n): SubscriptionUsageBadgeInjected['currentModel'] {\n return async () => {\n const directories = models()\n if (directories === undefined) return undefined\n const { current } = await directories.directoryFor(sessionId).load()\n return current ?? undefined\n }\n}\n\n/**\n * Compact time-remaining label derived from the window's `resetsAt` timestamp:\n * \"6d18h\" (days+hours), \"1h58m\" (hours+minutes), or \"42m\" (minutes only).\n * Falls back to the scope/kind abbreviation when no reset time is known.\n */\nexport function windowLabel(w: UsageWindow): string {\n if (w.resetsAt === undefined || !Number.isFinite(w.resetsAt)) {\n if (w.scope !== undefined && w.scope !== '') return w.scope\n switch (w.kind) {\n case 'session':\n return '5h'\n case 'weekly':\n return 'Wk'\n default:\n return 'W'\n }\n }\n const ms = Math.max(0, w.resetsAt - Date.now())\n const minutes = Math.floor(ms / 60_000)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n if (days > 0) return `${days}d${hours % 24}h`\n if (hours > 0) return `${hours}h${minutes % 60}m`\n return `${Math.max(1, minutes)}m`\n}\n\n/**\n * One compact segment piece (`6d1h 25%`); an unusable provider percentage\n * renders as the no-data dash, consistent with the meter's unavailable state.\n */\nfunction windowSegment(label: string, w: UsageWindow): string {\n const percent = displayUsedPercent(w.usedPercent)\n return percent === undefined ? `${label} —` : `${label} ${percent}%`\n}\n\n/** Keep model quotas separate: matching percentages do not imply a shared pool. */\nexport function prioritizeWindows(\n windows: readonly UsageWindow[],\n model?: string,\n): UsageWindow[] {\n return model === undefined\n ? [...windows]\n : [\n ...windows.filter((w) => w.scope === model),\n ...windows.filter((w) => w.scope !== model),\n ]\n}\n\n/** Small previews keep a live model catalog from taking over the dialog. */\nexport const WINDOW_PREVIEW_LIMIT = 4\nexport function previewWindows(\n windows: readonly UsageWindow[],\n model?: string,\n provider?: BadgeProvider,\n) {\n const ordered = prioritizeWindows(windows, model)\n // Antigravity has many model-specific quotas: preview only the current model.\n const limit =\n provider === 'antigravity'\n ? Math.min(\n 2,\n model === undefined\n ? 0\n : windows.filter((w) => w.scope === model).length,\n )\n : WINDOW_PREVIEW_LIMIT\n return { shown: ordered.slice(0, limit), hidden: ordered.slice(limit) }\n}\n\n/** Bounded readout; Antigravity quotas belong to individual models, not the account. */\nexport function compactSegment(\n d: ProviderUsageDisplay,\n model?: string,\n t: Translate = fallbackTranslate,\n): string {\n const windows = pillAccountOf(d).windows\n if (d.provider === 'antigravity') {\n const matching =\n model === undefined ? [] : windows.filter((w) => w.scope === model)\n if (matching.length === 0) {\n return `${d.name} ${t(\n model === undefined\n ? 'usageBadgeModelCount'\n : 'usageBadgeModelUnavailable',\n {\n count: new Set(windows.map((w) => w.scope).filter(Boolean)).size,\n },\n )}`\n }\n const parts = matching\n .slice(0, 2)\n .map((w) =>\n windowSegment(\n w.kind === 'weekly' ? t('usageWeekly') : t('usageWindow'),\n w,\n ),\n )\n return `${d.name} ${parts.join(' · ')}`\n }\n const parts = windows.slice(0, 2).map((w) => windowSegment(windowLabel(w), w))\n if (windows.length > 2) parts.push(`+${windows.length - 2}`)\n return `${d.name} ${parts.join(' · ')}`\n}\n\ntype ModelSelection = { provider: string; model: string }\n\n/** Remember only the most recent subscription in this view, including its model scope. */\nexport function retainSubscriptionSelection(\n previous: ModelSelection | undefined,\n current: ModelSelection | undefined,\n): ModelSelection | undefined {\n return current !== undefined &&\n Object.hasOwn(PROVIDER_NAMES, current.provider)\n ? current\n : previous\n}\n\n/** At most one provider; no known selection or no usage means no badge. */\nexport function collapsedDisplays(\n displays: readonly ProviderUsageDisplay[],\n current: string | undefined,\n): readonly ProviderUsageDisplay[] {\n const match = displays.find((d) => d.provider === current)\n return match === undefined ? [] : [match]\n}\n\n/**\n * `always` mode: the current model's provider while it reports usage,\n * otherwise the rotation steps through the providers that do, in display\n * order, wrapping around. The index is taken modulo the current provider\n * count, so providers appearing or dropping out stay inside range; the\n * sequence itself may shift when the roster changes. Unlike `recent`, the\n * retained subscription does not pin the pill — that retention is exactly\n * what this mode exists to escape.\n * @param displays - providers with usage, in display order.\n * @param current - the provider of the session's current model.\n * @param step - rotation tick; consecutive ticks advance one provider.\n */\nexport function rotatingDisplay(\n displays: readonly ProviderUsageDisplay[],\n current: string | undefined,\n step: number,\n): readonly ProviderUsageDisplay[] {\n if (displays.length === 0) return []\n const match = displays.find((d) => d.provider === current)\n if (match !== undefined) return [match]\n const index = Number.isFinite(step) ? Math.floor(step) : 0\n return [\n displays[((index % displays.length) + displays.length) % displays.length]!,\n ]\n}\n\n/** Order for the expanded dialog: the current provider first, the rest in poll order. */\nexport function expandedDisplays(\n displays: readonly ProviderUsageDisplay[],\n current: string | undefined,\n): readonly ProviderUsageDisplay[] {\n const match = displays.find((d) => d.provider === current)\n return match === undefined\n ? displays\n : [match, ...displays.filter((d) => d !== match)]\n}\n\n/**\n * A provider's logged-in accounts, the effective default first. When no\n * account is flagged default the first listed stands in, matching what\n * direct routes fall back to.\n */\nfunction accountsOf(status: ProviderStatus | undefined): AccountStatus[] {\n if (status === undefined || status.accounts.length === 0) return []\n const fallback =\n status.accounts.find((a) => a.isDefault) ?? status.accounts[0]!\n return status.accounts\n .map((a) => (a === fallback ? { ...a, isDefault: true } : a))\n .sort((a, b) => Number(b.isDefault) - Number(a.isDefault))\n}\n\n/** English-dictionary fallback for a missing inject `t` (standalone renders). */\nfunction fallbackTranslate(\n key: SubscriptionsKey,\n params?: Record<string, unknown>,\n): string {\n return en[key].replace(/\\{(\\w+)\\}/g, (_, name: string) =>\n String(params?.[name] ?? ''),\n )\n}\n\ntype Translate = (\n key: SubscriptionsKey,\n params?: Record<string, unknown>,\n) => string\n\n/** Localized label of one usage window (kind, plus the model scope when named). */\nfunction usageWindowLabel(t: Translate, window: UsageWindow): string {\n const base =\n window.kind === 'session'\n ? t('usageSession')\n : window.kind === 'weekly'\n ? t('usageWeekly')\n : t('usageWindow')\n return window.scope !== undefined && window.scope !== ''\n ? `${base} · ${window.scope}`\n : base\n}\n\n/**\n * The composer subscription-usage badge: a pill reading e.g.\n * `Codex 6d1h 25%` for the current model's provider, opening a dialog with\n * every provider's accounts and their windows. Returns null when no data is\n * available.\n */\nconst STATS_ROW_SELECTOR = markerSelector(\n HOST_CONTRACT.markers.composerStats.row,\n)\nconst STATS_DOCK_SELECTOR = markerSelector(\n HOST_CONTRACT.markers.composerStats.dock,\n)\n\nexport function SubscriptionUsageBadge({\n rpc,\n currentModel,\n t,\n rotationMs,\n}: SubscriptionUsageBadgeProps) {\n const translate: Translate = t ?? fallbackTranslate\n const [displays, setDisplays] = useState<ProviderUsageDisplay[]>([])\n const [selection, setSelection] = useState<ModelSelection | undefined>(\n undefined,\n )\n const [lastSubscription, setLastSubscription] = useState<\n ModelSelection | undefined\n >(undefined)\n const displayMode = useUsageBadgeMode()\n const current = selection?.provider\n const badgeSelection = retainSubscriptionSelection(\n lastSubscription,\n selection,\n )\n const [open, setOpen] = useState(false)\n const [hover, setHover] = useState(false)\n // Rotation tick for `always` mode; the interval runs only in that mode.\n const [rotation, setRotation] = useState(0)\n // The provider the pill showed when the dialog opened; an open dialog\n // keeps leading with it while the rotation keeps ticking underneath.\n const [dialogLead, setDialogLead] = useState<string | undefined>(undefined)\n const inflightRef = useRef(false)\n const mountedRef = useRef(true)\n const rootRef = useRef<HTMLSpanElement | null>(null)\n const panelRef = useRef<HTMLDivElement | null>(null)\n // Always-rendered, invisible marker in the dock: locates the composer bar\n // (and the host stats row inside it) even while the pill itself is portaled.\n const seatRef = useRef<HTMLSpanElement | null>(null)\n // The inject face may be re-evaluated (new callback identities) on\n // re-render; the model poll mounts once and reads through this ref.\n const currentRef = useRef(currentModel)\n currentRef.current = currentModel\n // Last-known-good windows per account (keyed `provider:accountKey`), kept\n // across a failed poll (e.g. a 429 during the server's own negative-cache\n // cooldown) so a row doesn't flicker away — it only disappears once the\n // account actually logs out or a fetch succeeds but reports the window as\n // unsupported. Observation metadata (freshness) shares this lifecycle: an\n // entry is dropped wherever its windows are dropped.\n const lastKnownRef = useRef(new Map<string, UsageWindow[]>())\n const observationsRef = useRef(\n new Map<string, { observedAt?: number | undefined; stale: boolean }>(),\n )\n\n const refresh = useCallback(async (): Promise<void> => {\n if (rpc === undefined || inflightRef.current) return\n inflightRef.current = true\n try {\n const { roster, refreshed } = await loadBadgeRoster(rpc)\n if (!mountedRef.current) return\n\n const lastKnown = lastKnownRef.current\n // Drop last-known state for anything no longer logged in — that is a\n // real signal, unlike a fetch failure.\n const live = new Set(\n roster.map(({ provider, account }) => usageKeyOf(provider, account)),\n )\n for (const key of lastKnown.keys()) {\n if (\n refreshed.has(key.split(':', 1)[0] as BadgeProvider) &&\n !live.has(key)\n ) {\n lastKnown.delete(key)\n observationsRef.current.delete(key)\n }\n }\n\n const results = await Promise.allSettled(\n roster.map(async ({ provider, account }) => {\n const usage = await usageOf(rpc, { provider, account })\n return { provider, account, usage }\n }),\n )\n if (!mountedRef.current) return\n\n for (const { provider, account } of roster) {\n const key = usageKeyOf(provider, account)\n observationsRef.current.set(key, {\n ...observationsRef.current.get(key),\n stale: true,\n })\n }\n const plans = new Map<string, string>()\n for (const r of results) {\n if (r.status !== 'fulfilled') continue // keep whatever is cached for this account\n const { provider, account, usage } = r.value\n const key = usageKeyOf(provider, account)\n if (usage.plan !== undefined) plans.set(key, usage.plan)\n if (!usage.supported || !usage.windows || usage.windows.length === 0) {\n lastKnown.delete(key)\n observationsRef.current.delete(key)\n continue\n }\n lastKnown.set(key, usage.windows)\n observationsRef.current.set(key, {\n observedAt: usage.observedAt ?? Date.now(),\n stale: usage.stale === true,\n })\n }\n\n setDisplays((previous) => [\n ...groupUsageDisplays(roster, lastKnown, plans).map((display) => ({\n ...display,\n accounts: display.accounts.map((account) => ({\n ...account,\n ...observationsRef.current.get(\n `${display.provider}:${account.key}`,\n ),\n })),\n })),\n ...previous\n .filter((display) => !refreshed.has(display.provider))\n .map((display) => ({\n ...display,\n accounts: display.accounts.map((account) => ({\n ...account,\n stale: true,\n })),\n })),\n ])\n } catch {\n // Keep cached numbers, but never present failed observations as current.\n if (mountedRef.current)\n setDisplays((previous) =>\n previous.map((display) => ({\n ...display,\n accounts: display.accounts.map((account) => ({\n ...account,\n stale: true,\n })),\n })),\n )\n } finally {\n inflightRef.current = false\n }\n }, [rpc])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n // Hidden renders nothing, so it polls nothing; showing it again refreshes at once.\n useEffect(() => {\n if (displayMode === 'hidden') return\n void refresh()\n const timer = setInterval(() => {\n void refresh()\n }, USAGE_POLL_INTERVAL_MS)\n window.addEventListener(USAGE_BADGE_REFRESH_EVENT, refresh)\n return () => {\n clearInterval(timer)\n window.removeEventListener(USAGE_BADGE_REFRESH_EVENT, refresh)\n }\n }, [refresh, displayMode])\n\n useEffect(() => {\n if (currentRef.current === undefined) return\n let cancelled = false\n let inflight = false\n const reload = (): void => {\n const read = currentRef.current\n if (read === undefined || inflight) return\n inflight = true\n void read()\n .then(\n (model) => {\n if (cancelled) return\n setLastSubscription((previous) =>\n retainSubscriptionSelection(previous, model),\n )\n setSelection(model)\n },\n () => {\n /* keep the last known provider; the next tick retries */\n },\n )\n .finally(() => {\n inflight = false\n })\n }\n reload()\n const timer = setInterval(reload, MODEL_POLL_INTERVAL_MS)\n return () => {\n cancelled = true\n clearInterval(timer)\n }\n }, [])\n\n const pos = useAnchoredPosition({\n open,\n anchorRef: rootRef,\n panelRef,\n side: 'top',\n gap: PANEL_GAP,\n margin: PANEL_MARGIN,\n })\n useDismissOnOutsidePointer(rootRef, open, setOpen, panelRef)\n useEffect(() => {\n if (!open) return\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') setOpen(false)\n }\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.removeEventListener('keydown', onKeyDown)\n }\n }, [open])\n\n // Sit on the host's stats row when there is one. Hosts through 0.2.0 render\n // their time/token pills in a row apart from the dock, marked\n // `data-composer-stats`; every dock entry is its own row in the composer\n // bar, so a badge rendered in place lands under those pills, and rendering\n // into the row makes it a third pill on their line. The marker is watched\n // (the row mounts only once the session has steps or tokens, and unmounts\n // with them). From 0.2.1 the shipped pills are dock entries like this\n // badge, each anchored `data-composer-stat`, so the in-place seat already\n // shares their row; seeing a docked anchor ends the watch for a row that\n // will not appear.\n const [statsRow, setStatsRow] = useState<HTMLElement | null>(null)\n useEffect(() => {\n const seat = seatRef.current\n if (seat === null) return\n const scope = statsScopeOf(seat)\n if (scope === null) return\n const find = (): HTMLElement | null =>\n scope.querySelector<HTMLElement>(STATS_ROW_SELECTOR)\n const settle = (): void => {\n const row = find()\n setStatsRow(row)\n if (row === null && scope.querySelector(STATS_DOCK_SELECTOR) !== null)\n observer.disconnect()\n }\n const observer = new MutationObserver(settle)\n observer.observe(scope, { childList: true, subtree: true })\n settle()\n return () => {\n observer.disconnect()\n }\n }, [])\n\n useEffect(() => {\n if (displayMode === 'hidden') setOpen(false)\n }, [displayMode])\n\n // `always` mode advances the rotation on its own cadence; other modes\n // never advance, so the pill never changes on its own.\n useEffect(() => {\n if (displayMode !== 'always') return\n const interval =\n rotationMs !== undefined && Number.isFinite(rotationMs) && rotationMs > 0\n ? rotationMs\n : BADGE_ROTATION_INTERVAL_MS\n const timer = setInterval(() => {\n setRotation((step) => step + 1)\n }, interval)\n return () => {\n clearInterval(timer)\n }\n }, [displayMode, rotationMs])\n\n const seat = <span ref={seatRef} style={styles.seat} aria-hidden />\n // `always` follows the live model, not the retained subscription: the\n // retention pins the pill in `recent`, which is what this mode escapes.\n const collapsed =\n displayMode === 'always'\n ? rotatingDisplay(displays, current, rotation)\n : collapsedDisplays(displays, badgeSelection?.provider)\n if (displayMode === 'hidden' || collapsed.length === 0) return seat\n\n // Model scope only while the pill shows the current model's provider;\n // a rotated provider has no live model, so it reads at account level.\n const pillModel =\n displayMode === 'always'\n ? current === collapsed[0]?.provider\n ? selection?.model\n : undefined\n : badgeSelection?.model\n const label = compactSegment(collapsed[0]!, pillModel, translate)\n // The dialog opens from the badge, so it follows the provider and model the\n // badge shows (a retained subscription when the current model is not one).\n // In `always` mode the pill moves under the cursor, so an open dialog keeps\n // the provider that was showing when it opened instead of reordering live.\n const dialogProvider =\n open && displayMode === 'always' ? dialogLead : badgeSelection?.provider\n const dialogModel =\n open && displayMode === 'always'\n ? dialogLead === current\n ? selection?.model\n : undefined\n : badgeSelection?.model\n const expanded = expandedDisplays(displays, dialogProvider)\n const title = translate('usageBadgeTitle')\n\n const toggle = (): void => {\n const next = !open\n setDialogLead(collapsed[0]?.provider)\n setOpen(next)\n if (next) void refresh()\n }\n\n const pill = (\n <span ref={rootRef} style={styles.anchor}>\n <style>{subscriptionChromeCss}</style>\n <button\n type=\"button\"\n className=\"dsh-subscription-usage-pill\"\n style={{ ...styles.pill, ...(hover || open ? styles.pillActive : {}) }}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-label={`${title} · ${label}`}\n title={title}\n onMouseEnter={() => {\n setHover(true)\n }}\n onMouseLeave={() => {\n setHover(false)\n }}\n onClick={toggle}\n >\n <UsageBadgeIcon />\n <span style={styles.label}>{label}</span>\n </button>\n {open &&\n createPortal(\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-label={title}\n className=\"dsh-subscription-usage-panel\"\n style={{ ...styles.panel, ...(pos ?? MEASURE_STYLE) }}\n >\n <div style={styles.title}>\n <span style={styles.titleLabel}>\n <UsageBadgeIcon />\n {title}\n </span>\n </div>\n <div style={styles.titleRule} aria-hidden />\n {expanded.map((d, index) => (\n <section\n key={d.provider}\n style={index === 0 ? undefined : styles.section}\n >\n <div style={styles.providerRow}>\n <span style={styles.providerName}>\n {d.name}\n {d.provider === current && (\n <span style={styles.currentTag}>\n {translate('usageBadgeCurrent')}\n </span>\n )}\n </span>\n {d.accounts.length === 1 && (\n <AccountMeta\n account={d.accounts[0]!}\n translate={translate}\n />\n )}\n </div>\n {d.accounts.map((account, accountIndex) => (\n <div\n key={account.key}\n style={accountIndex === 0 ? undefined : styles.accountBlock}\n >\n {d.accounts.length > 1 && (\n <div style={styles.accountRow}>\n <AccountMeta account={account} translate={translate} />\n </div>\n )}\n <AccountWindows\n key={`${d.provider}:${dialogModel ?? ''}`}\n windows={account.windows}\n observedAt={account.observedAt}\n stale={account.stale}\n model={\n d.provider === dialogProvider ? dialogModel : undefined\n }\n provider={d.provider}\n translate={translate}\n />\n </div>\n ))}\n </section>\n ))}\n </div>,\n document.body,\n )}\n </span>\n )\n\n return (\n <>\n {seat}\n {statsRow !== null && statsRow.isConnected\n ? createPortal(pill, statsRow)\n : pill}\n </>\n )\n}\n\n/** How far statsScopeOf walks looking for `composerStats.row`. */\nconst LEGACY_STATS_SCOPE_DEPTH = 4\n\n/**\n * Scope for the legacy stats row. The nearest ancestor within\n * LEGACY_STATS_SCOPE_DEPTH that contains `composerStats.row`, so a badge\n * does not adopt another composer's pills. When none does, the seat's\n * parent: the slot outlet, which holds sibling `composerStats.dock` anchors\n * on hosts whose pills are dock entries.\n */\nfunction statsScopeOf(seat: HTMLElement): HTMLElement | null {\n let node: HTMLElement | null = seat.parentElement\n for (\n let depth = 0;\n node !== null && depth < LEGACY_STATS_SCOPE_DEPTH;\n depth++\n ) {\n if (node.querySelector(STATS_ROW_SELECTOR) !== null) return node\n node = node.parentElement\n }\n return seat.parentElement\n}\n\n/**\n * One account's handle and plan: `★ ys@example.com · 计划:pro`. The star\n * marks the default account (the one direct routes serve and the collapsed\n * pill reads), the same glyph Settings → 订阅 uses.\n */\nfunction AccountMeta({\n account,\n translate,\n}: {\n account: AccountUsageDisplay\n translate: Translate\n}) {\n const parts = [\n account.account,\n account.plan === undefined\n ? undefined\n : translate('usagePlan', { plan: account.plan }),\n ].filter((part): part is string => part !== undefined && part !== '')\n return (\n <span style={styles.providerMeta} title={account.account}>\n {account.isDefault && (\n <span style={styles.defaultStar} aria-label=\"default\">\n ★{' '}\n </span>\n )}\n {parts.join(' · ')}\n </span>\n )\n}\n\n/** Preview each account independently; all remaining quotas stay accessible. */\nexport function AccountWindows({\n windows,\n model,\n provider,\n translate,\n observedAt,\n stale,\n}: {\n windows: readonly UsageWindow[]\n model: string | undefined\n provider?: BadgeProvider\n translate: Translate\n observedAt?: number | undefined\n stale?: boolean | undefined\n}) {\n const { shown, hidden } = previewWindows(windows, model, provider)\n const rows = (items: readonly UsageWindow[]) => (\n <dl style={styles.details}>\n {items.map((w, i) => (\n <WindowRow\n key={i}\n label={`${usageWindowLabel(translate, w)}${model !== undefined && w.scope === model ? ` · ${translate('usageBadgeCurrent')}` : ''}`}\n window={w}\n t={translate}\n observedAt={observedAt}\n stale={stale}\n />\n ))}\n </dl>\n )\n return (\n <>\n {rows(shown)}\n {hidden.length > 0 && (\n <details style={styles.moreWindows}>\n <summary style={styles.moreSummary}>\n {translate('usageBadgeMoreWindows', { count: hidden.length })}\n </summary>\n {rows(hidden)}\n </details>\n )}\n </>\n )\n}\n\n/** One `dt`/`dd` pair: window name → `25% · 6d1h`, with the bar underneath. */\nfunction WindowRow({\n label,\n window: w,\n t,\n observedAt,\n stale,\n}: {\n label: string\n window: UsageWindow\n t: Translate\n observedAt?: number | undefined\n stale?: boolean | undefined\n}) {\n const percent = displayUsedPercent(w.usedPercent)\n return (\n <>\n <dt style={styles.dt}>{label}</dt>\n <dd style={styles.dd}>\n {percent === undefined ? t('usageMeterInvalid') : `${percent}%`}\n {w.resetsAt !== undefined && Number.isFinite(w.resetsAt) && (\n <span style={styles.reset}> · {windowLabel(w)}</span>\n )}\n </dd>\n <UsageMeter\n window={w}\n t={t}\n style={styles.bar}\n observedAt={observedAt}\n stale={stale}\n />\n </>\n )\n}\n\n/**\n * Unplaced portal panel: hidden but laid out so the clamp measures real\n * dimensions (the `useAnchoredPosition` measure pass).\n */\nconst MEASURE_STYLE: CSSProperties = { visibility: 'hidden', left: 0, top: 0 }\n\nconst styles: Record<string, CSSProperties> = {\n seat: { display: 'none' },\n anchor: { minWidth: 0, maxWidth: '100%', display: 'inline-flex' },\n // Mirrors the host StatsPills pill so the badge reads as a sibling of the\n // shipped time/token pills.\n pill: {\n boxSizing: 'border-box',\n maxWidth: '100%',\n color: 'var(--dsw-alias-label-tertiary)',\n font: 'inherit',\n fontSize: 'calc(var(--dsh-content-font-size-secondary, 13px) - 1px)',\n fontVariantNumeric: 'tabular-nums',\n lineHeight: 'calc(20px + var(--dsh-content-font-delta-secondary, 0px))',\n whiteSpace: 'nowrap',\n background: 'transparent',\n border: 'none',\n borderRadius: 999,\n alignItems: 'center',\n gap: 6,\n padding: '1px 8px',\n display: 'inline-flex',\n cursor: 'pointer',\n },\n pillActive: {\n background: 'var(--dsw-alias-interactive-bg-hover)',\n color: 'var(--dsw-alias-label-secondary)',\n },\n label: { textOverflow: 'ellipsis', minWidth: 0, overflow: 'hidden' },\n // Mirrors the host stat-dialog panel. The menu fill is translucent by\n // design and only the host's backdrop blur keeps it readable as a surface:\n // without the blur the transcript behind the dialog stays sharp and shows\n // through the fill.\n panel: {\n position: 'fixed',\n zIndex: 1100,\n boxSizing: 'border-box',\n background: 'var(--dsw-specific-menu)',\n backdropFilter: 'var(--dsw-menu-backdrop-filter)',\n width: 'max-content',\n minWidth: 'min(300px, 100vw - 24px)',\n maxWidth: 'min(440px, 100vw - 24px)',\n maxHeight: 'min(560px, 100dvh - 24px)',\n overflowY: 'auto',\n overscrollBehavior: 'contain',\n boxShadow: 'var(--dsw-elevation-prominent)',\n color: 'var(--dsw-alias-label-secondary)',\n cursor: 'default',\n border: 0,\n borderRadius: 'var(--dsw-radius-lg, 16px)',\n padding: 16,\n fontSize: 12,\n lineHeight: '18px',\n },\n title: {\n color: 'var(--dsw-alias-label-primary)',\n display: 'flex',\n justifyContent: 'space-between',\n gap: 16,\n marginBottom: 8,\n fontWeight: 500,\n },\n titleLabel: {\n alignItems: 'center',\n gap: 6,\n minWidth: 0,\n display: 'inline-flex',\n },\n titleRule: {\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n marginBottom: 10,\n },\n section: {\n marginTop: 12,\n paddingTop: 10,\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n },\n providerRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'baseline',\n gap: 16,\n marginBottom: 6,\n },\n providerName: {\n color: 'var(--dsw-alias-label-primary)',\n fontWeight: 500,\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n },\n currentTag: {\n fontSize: 10,\n lineHeight: '14px',\n fontWeight: 400,\n padding: '0 5px',\n borderRadius: 7,\n color: 'var(--dsw-alias-label-secondary)',\n background: 'var(--dsw-alias-interactive-bg-hover)',\n },\n providerMeta: {\n color: 'var(--dsw-alias-label-tertiary)',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n // Same star and color as the default-account marker in Settings → 订阅.\n defaultStar: { color: 'var(--dsw-alias-state-warn-label)' },\n accountBlock: { marginTop: 8 },\n accountRow: { display: 'flex', marginBottom: 4 },\n details: {\n color: 'var(--dsw-alias-label-tertiary)',\n display: 'grid',\n gridTemplateColumns: 'minmax(0, 1fr) max-content',\n gap: '4px 16px',\n margin: 0,\n },\n moreWindows: { marginTop: 8 },\n moreSummary: {\n cursor: 'pointer',\n color: 'var(--dsw-alias-label-secondary)',\n marginBottom: 8,\n },\n dt: { minWidth: 0, margin: 0, overflowWrap: 'anywhere' },\n dd: {\n minWidth: 0,\n margin: 0,\n color: 'var(--dsw-alias-label-secondary)',\n fontVariantNumeric: 'tabular-nums',\n textAlign: 'right',\n },\n reset: { color: 'var(--dsw-alias-label-tertiary)' },\n bar: {\n gridColumn: '1 / -1',\n height: 4,\n borderRadius: 2,\n overflow: 'hidden',\n background: 'var(--dsw-alias-border-l2)',\n marginBottom: 2,\n },\n}\n","/** Build the locale resolver used by the /fast command contribution. */\nexport function fastCommandDescription(t: () => string): () => string {\n return () => t()\n}\n","/**\n * Subscription OAuth login page, browser half. Registers the Subscriptions\n * settings section; every login state fact arrives through the node half's\n * `/subscriptions-auth` RPC channel — this plugin holds no credential state of its\n * own. Section copy rides the client locale service: one 'settings.subscriptions'\n * namespace with zh/en dictionaries, rebound per read so the nav label and\n * page text follow the active locale.\n */\n// Type-only: pulls the `ctx.slots` Context merge (dsh-client-runtime owned it\n// on rc.2; ui-renderer's augmentation carries it on the 0.1.2-alpha line).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\n// Type-only: pulls the shell's SlotMap merge (the 'settings.section' entry).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls ui-conversation's SlotMap merge (the 'conversation.input.right' entry).\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/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: the slash-command registry contract (the /fast contribution).\nimport type { CommandUiContract } from '@deepseek-ai/dsh-client-ui-commands/client'\n// `.js` extension: this package's tsconfig lacks the reference repo's\n// allowImportingTsExtensions/rewriteRelativeImportExtensions pair; under\n// nodenext the .js specifier resolves to the .tsx source (see README note).\nimport { SubscriptionsSection } from './SubscriptionsSection.js'\nimport type { SubscriptionsSectionInjected } from './SubscriptionsSection.js'\nimport {\n ImageGenerateToolview,\n createImageLoader,\n} from './ImageGenerateToolview.js'\nimport type { ImageGenerateToolviewInjected } from './ImageGenerateToolview.js'\nimport {\n VideoGenerateToolview,\n createVideoLoader,\n} from './VideoGenerateToolview.js'\nimport type { VideoGenerateToolviewInjected } from './VideoGenerateToolview.js'\nimport {\n SpeedSelect,\n createModelSelectionWatch,\n createSpeedLoader,\n createSpeedSetter,\n notifySpeedChanged,\n} from './SpeedSelect.js'\nimport type {\n ModelDirectoriesLike,\n SpeedSelectInjected,\n} from './SpeedSelect.js'\nimport {\n SubscriptionUsageBadge,\n createCurrentModelReader,\n} from './SubscriptionUsageBadge.js'\nimport type { SubscriptionUsageBadgeInjected } from './SubscriptionUsageBadge.js'\nimport { en, zh } from './locales.js'\nimport type { SubscriptionsKey } from './locales.js'\nimport { fastCommandDescription } from './fast-command.js'\n\nexport type {\n SubscriptionsSectionInjected,\n SubscriptionsSectionProps,\n} from './SubscriptionsSection.js'\nexport type {\n ImageGenerateToolviewInjected,\n ImageGenerateToolviewProps,\n} from './ImageGenerateToolview.js'\nexport type {\n VideoGenerateToolviewInjected,\n VideoGenerateToolviewProps,\n} from './VideoGenerateToolview.js'\nexport type {\n SpeedSelectInjected,\n SpeedSelectProps,\n SpeedState,\n SpeedTier,\n} from './SpeedSelect.js'\nexport type {\n SubscriptionUsageBadgeInjected,\n SubscriptionUsageBadgeProps,\n} from './SubscriptionUsageBadge.js'\nexport type { SubscriptionsKey } from './locales.js'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The Subscriptions settings page copy. */\n 'settings.subscriptions': SubscriptionsKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'settings.subscriptions'\n\n/**\n * Required services (cordis fiber inject): `slots` carries the registration\n * seat, `connection` the `/subscriptions-auth` RPC caller, and `locale` the copy\n * dictionaries.\n */\nexport const inject = ['slots', 'connection', 'locale']\n\n/**\n * Register the Subscriptions section once the `settings.section` declaration\n * is on the ledger (the shell's apply order relative to this one is NOT\n * constrained; registration depends on the slot through `slots.inject()`).\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(\n () => ctx.locale.register(NS, { zh, en }),\n 'dsh-subscriptions: copy dictionaries',\n )\n // Settings-shell nudge: the panel (nav title + header row + section body)\n // sits flush against the panel's top edge; push it down a little to leave\n // breathing room. Scoped by the settings panel's own dialog role + nav child\n // so other aria-modal dialogs (e.g. the attachment lightbox) are untouched.\n ctx.effect(() => {\n const style = document.createElement('style')\n style.setAttribute('data-plugin', 'dsh-subscriptions')\n style.textContent =\n 'div[role=\"dialog\"][aria-modal=\"true\"]:has(> nav) { padding-top: 14px; }'\n document.head.appendChild(style)\n return () => style.remove()\n }, 'dsh-subscriptions: settings panel breathing room')\n // The shell's Context merge types `connection` as the host handle; in the\n // browser shell the same key holds the full client ConnectionHandle.\n const connection = ctx.get('connection') as unknown as ConnectionHandle\n const t = ctx.locale.bind(NS) as SubscriptionsSectionInjected['t']\n const injected = (): SubscriptionsSectionInjected => ({\n rpc: connection.rpc,\n t,\n })\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n {\n name: 'settings.section',\n id: 'subscriptions',\n order: 90,\n // A thunk re-evaluated per read, so the nav label follows the active locale.\n label: () => t('nav'),\n inject: injected,\n },\n SubscriptionsSection,\n ),\n )\n\n // The image_generate keyed toolview owns how image calls render inline; its\n // gallery bytes ride the same channel through the injected loader. The\n // framework synthesizes the toolview's own `t` seat from `locale: NS`.\n const toolviewInjected = (): ImageGenerateToolviewInjected => ({\n load: createImageLoader(connection.rpc),\n })\n ctx.slots.inject('tool.call.toolview', () =>\n ctx.slots.register(\n {\n name: 'tool.call.toolview',\n key: 'image_generate',\n locale: NS,\n inject: toolviewInjected,\n },\n ImageGenerateToolview,\n ),\n )\n\n // The video_generate keyed toolview plays the saved MP4 inline; its bytes\n // ride the same channel's `video` endpoint through the injected loader.\n const videoToolviewInjected = (): VideoGenerateToolviewInjected => ({\n loadVideo: createVideoLoader(connection.rpc),\n })\n ctx.slots.inject('tool.call.toolview', () =>\n ctx.slots.register(\n {\n name: 'tool.call.toolview',\n key: 'video_generate',\n locale: NS,\n inject: videoToolviewInjected,\n },\n VideoGenerateToolview,\n ),\n )\n\n // The composer Speed toggle (codex fast tier) sits in the right tool row,\n // just left of the model selector; the framework synthesizes its `t` seat\n // from `locale: NS`, and the inject face binds each session's RPC calls.\n // The current-model read rides ui-model-selection's `modelDirectories`\n // service, resolved lazily so registration order never matters.\n const models = (): ModelDirectoriesLike | undefined =>\n ctx.get('modelDirectories') as ModelDirectoriesLike | undefined\n ctx.slots.inject('conversation.input.right', () =>\n ctx.slots.register(\n {\n name: 'conversation.input.right',\n id: 'codex-speed',\n order: 0,\n locale: NS,\n inject: (sessionId: string): SpeedSelectInjected => ({\n loadSpeed: createSpeedLoader(connection, models, sessionId),\n setSpeed: createSpeedSetter(connection, sessionId),\n watchModel: createModelSelectionWatch(models, sessionId),\n }),\n },\n SpeedSelect,\n ),\n )\n\n // The subscription usage badge renders a stats pill in the composer's dock\n // (conversation.composer.dock) — collapsed, the current model's provider\n // (e.g. \"Codex 6d1h 25%\"); clicking opens every provider's windows. A fresh\n // id means it appears beside the shipped StatsPills, never replacing them;\n // the current-model read shares the Speed toggle's `modelDirectories` path.\n ctx.slots.inject('conversation.composer.dock', () =>\n ctx.slots.register(\n {\n name: 'conversation.composer.dock',\n id: 'subscription-usage',\n order: 10,\n locale: NS,\n inject: (sessionId: string): SubscriptionUsageBadgeInjected => ({\n rpc: connection.rpc,\n currentModel: createCurrentModelReader(models, sessionId),\n }),\n },\n SubscriptionUsageBadge,\n ),\n )\n\n // The /fast slash command offers the same Standard/Fast choice as a popup.\n // `available` is synchronous and sees only the session id, so the command\n // stays listed everywhere; `options` throws the friendly gate when the\n // session's current model is not a fast-capable codex model (the same\n // in-popup error posture the /model contribution uses for its guards).\n ctx.inject(['commandUi'], (scope: ClientContext) => {\n const command = scope.get('commandUi') as CommandUiContract\n scope.effect(\n () =>\n command.register({\n name: 'fast',\n // dsh 0.1.5-alpha made `description` a locale resolver evaluated per\n // candidate pass (commit 5d9603b76, \"feat(web): localize slash command\n // descriptions\"); earlier lines read the value as a plain string. The\n // bare string threw `contribution.description is not a function` inside\n // the registry's candidate pass on 0.1.5, aborting the whole `/` source\n // and hiding every host command — /plan, /model, /goal, ... — not just\n // /fast. Older lines render a function child as empty copy, no crash.\n description: fastCommandDescription(() => t('commandFast')),\n available: () => true,\n ui: {\n kind: 'popupSelect',\n options: async (session) => {\n const state = await createSpeedLoader(\n connection,\n models,\n session.sessionId,\n )()\n if (!state.visible) throw new Error(t('commandFastUnavailable'))\n return (\n [\n {\n id: 'standard',\n label: t('speedStandard'),\n detail: t('speedStandardDescription'),\n },\n {\n id: 'fast',\n label: t('speedFast'),\n detail: t('speedFastDescription'),\n },\n ] as const\n ).map((option) => ({\n ...option,\n active: option.id === state.tier,\n }))\n },\n onSelect: async (option, session) => {\n const wrote = await createSpeedSetter(\n connection,\n session.sessionId,\n )(option.id as 'standard' | 'fast')\n if (wrote) notifySpeedChanged()\n },\n },\n }),\n 'dsh-subscriptions: /fast contribution',\n )\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,MAAa,KAAK;CAChB,gBAAgB;CAChB,eAAe;CACf,cACE;CACF,iBAAiB;CACjB,oBAAoB;CACpB,oBAAoB;CACpB,eACE;CACF,eAAe;CACf,qBAAqB;CACrB,qBAAqB;CACrB,yBACE;CACF,gBAAgB;CAChB,mBAAmB;CACnB,qBAAqB;CACrB,oBACE;CACF,yBAAyB;CACzB,kBAAkB;CAClB,4BACE;CACF,mBACE;CACF,YAAY;CACZ,YACE;CACF,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,eAAe;CACf,qBAAqB;CACrB,mBACE;CACF,sBAAsB;CACtB,aAAa;CACb,iBACE;CACF,aAAa;CACb,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,YAAY;CACZ,mBAAmB;CACnB,gBAAgB;CAChB,4BAA4B;CAC5B,kBAAkB;CAClB,kBAAkB;CAClB,oBACE;CACF,KAAK;CACL,OACE;CACF,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,kBAAkB;CAClB,oBAAoB;CACpB,uBAAuB;CACvB,qBAAqB;CACrB,mBACE;CACF,gBAAgB;CAChB,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,iBAAiB;CACjB,oBAAoB;CACpB,gBACE;CACF,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,sBAAsB;CACtB,eAAe;CACf,mBAAmB;CACnB,QAAQ;CACR,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,oBAAoB;CACpB,YAAY;CACZ,cAAc;CACd,cAAc;CACd,YAAY;CACZ,kBAAkB;CAClB,YAAY;CACZ,cAAc;CACd,aAAa;CACb,cAAc;CACd,aAAa;CACb,aAAa;CACb,gBAAgB;CAChB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,oBAAoB;CACpB,mBAAmB;CACnB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,qBAAqB;CACrB,uBAAuB;CACvB,iBAAiB;CACjB,cAAc;CACd,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;CAClB,iBAAiB;CACjB,oBAAoB;CACpB,mBAAmB;CACnB,qBAAqB;CACrB,oBACE;CACF,yBACE;CACF,WAAW;CACX,mBAAmB;CACnB,uBAAuB;CACvB,mBAAmB;CACnB,wBACE;CACF,qBAAqB;CACrB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,mBAAmB;CACnB,sBAAsB;CACtB,oBAAoB;CACpB,sBAAsB;CACtB,iBAAiB;CACjB,6BAA6B;CAC7B,0BAA0B;CAC1B,gBAAgB;CAChB,kBAAkB;CAClB,eACE;CACF,iBACE;CACF,iBACE;CACF,eACE;CACF,sBAAsB;CACtB,iBACE;CACF,qBAAqB;CACrB,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,oBAAoB;CACpB,0BAA0B;CAC1B,oBAAoB;CACpB,wBAAwB;CACxB,4BAA4B;CAC5B,qBAAqB;CACrB,wBACE;CACF,0BAA0B;CAC1B,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,iBAAiB;CACjB,mBAAmB;CACnB,oBACE;CACF,oBACE;CACF,kBACE;CACF,oBAAoB;CACpB,qBAAqB;CACrB,mBAAmB;CACnB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;CACd,mBAAmB;CACnB,wBAAwB;CACxB,oBAAoB;CACpB,mBACE;CACF,6BAA6B;CAC7B,uBACE;CACF,sBAAsB;CACtB,yBAAyB;CACzB,oBAAoB;CACpB,sBAAsB;CACtB,qBAAqB;CACrB,8BAA8B;CAC9B,sBAAsB;CACtB,0BAA0B;CAC1B,2BAA2B;CAC3B,gCAAgC;CAChC,0BAA0B;CAC1B,YAAY;CACZ,OAAO;CACP,WAAW;CACX,gBAAgB;CAChB,cAAc;CACd,iBAAiB;CACjB,cAAc;CACd,YAAY;CACZ,iBAAiB;CACjB,cAAc;CACd,iBAAiB;CACjB,iBAAiB;CACjB,mBAAmB;CACnB,yBAAyB;CACzB,yBACE;CACF,yBAAyB;CACzB,uBACE;CACF,6BACE;CACF,mBAAmB;CACnB,sBAAsB;CACtB,4BAA4B;CAC5B,uBAAuB;CACvB,OAAO;CACP,eAAe;CACf,0BAA0B;CAC1B,WAAW;CACX,sBAAsB;CACtB,aAAa;CACb,wBACE;CACF,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,aAAa;CACb,cAAc;CACd,mBAAmB;CACnB,kBACE;CAEF,aAAa;CACb,gBAAgB;CAChB,sBAAsB;CACtB,eACE;CAEF,mBAAmB;CACnB,uBAAuB;CACvB,uBAAuB;CACvB,mBACE;CACF,wBAAwB;CACxB,wBAAwB;CACxB,qBACE;CAEF,mBAAmB;CACnB,kBAAkB;CAClB,sBACE;CACF,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,sBACE;CAGF,eACE;CAEF,uBACE;CAEF,qBAAqB;CACrB,oBACE;CAEF,iBAAiB;CACjB,mBAAmB;CACnB,eAAe;CAChB;;AAGD,MAAa,KAAK;CAChB,gBAAgB;CAChB,eAAe;CACf,cACE;CACF,iBAAiB;CACjB,oBAAoB;CACpB,oBAAoB;CACpB,eAAe;CACf,eAAe;CACf,qBAAqB;CACrB,qBAAqB;CACrB,yBACE;CACF,gBAAgB;CAChB,mBAAmB;CACnB,qBAAqB;CACrB,oBACE;CACF,yBAAyB;CACzB,kBAAkB;CAClB,4BACE;CACF,mBACE;CACF,YAAY;CACZ,YACE;CACF,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,eAAe;CACf,qBAAqB;CACrB,mBACE;CACF,sBAAsB;CACtB,aAAa;CACb,iBACE;CACF,aAAa;CACb,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,YAAY;CACZ,mBAAmB;CACnB,gBAAgB;CAChB,4BAA4B;CAC5B,kBAAkB;CAClB,kBAAkB;CAClB,oBACE;CACF,KAAK;CACL,OACE;CACF,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,kBAAkB;CAClB,oBAAoB;CACpB,uBAAuB;CACvB,qBAAqB;CACrB,mBACE;CACF,gBAAgB;CAChB,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,iBAAiB;CACjB,oBAAoB;CACpB,gBACE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"}