dsh-ui-tweaks 0.14.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -8,19 +8,19 @@ A [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/) (DSH)
8
8
 
9
9
  | | |
10
10
  |---|---|
11
- | ![Claude Desktop table style](assets/table.png) | ![Settings panel](assets/settings.png) |
12
- | **Table style**: the Claude Desktop look (light-gray rounded cards) | **Settings panel**: code font size / table style / GitBar toggles |
13
- | ![GitBar](assets/git.png) | ![Branch panel](assets/branch.png) |
14
- | **GitBar**: the branch chip in the session header (branch management) plus **terminal** / **code diff** tabs in the native right sidebar, with commit & push from the code diff page (uncommitted changes dot the branch chip and its tab) | **Branch panel**: pops up from the branch chip — local / remote branch lists, click to switch, delete, pull & push to remote, new-branch field at the bottom, plus a **commit graph** dialog (colored SVG fork/merge lanes) |
15
- | ![Diff panel](assets/gitdiff.png) | ![Terminal panel](assets/terminal.png) |
16
- | **Code diff**: file list + per-file diff (changed hunks only by default) with a commit area (commit / commit & push) at the bottom | **Terminal**: a real PTY terminal in the sidebar (xterm.js over WebSocket) — full interactivity |
17
- | ![Archive manager](assets/archive.png) | ![MCP manager](assets/mcp.png) |
18
- | **Archive manager**: an Archive page in the Settings dialog listing archived sessions (title / workspace / relative time) with Restore and Delete actions | **MCP manager**: an MCP page in the Settings dialog listing configured MCP servers with live status and full management (Add / Edit / Enable / Disable / Delete / Restart) |
11
+ | ![Settings panel](assets/settings.png) | ![GitBar](assets/git.png) |
12
+ | **Settings panel**: code font size / theme skin / GitBar toggles | **GitBar**: the branch chip in the session header (branch management) plus **terminal** / **code diff** tabs in the native right sidebar, with commit & push from the code diff page (uncommitted changes dot the branch chip and its tab) |
13
+ | ![Branch panel](assets/branch.png) | ![Diff panel](assets/gitdiff.png) |
14
+ | **Branch panel**: pops up from the branch chip — local / remote branch lists, click to switch, delete, pull & push to remote, new-branch field at the bottom, plus a **commit graph** dialog (colored SVG fork/merge lanes) | **Code diff**: file list + per-file diff (changed hunks only by default) with a commit area (commit / commit & push) at the bottom |
15
+ | ![Terminal panel](assets/terminal.png) | ![Archive manager](assets/archive.png) |
16
+ | **Terminal**: a real PTY terminal in the sidebar (xterm.js over WebSocket) — full interactivity | **Archive manager**: an Archive page in the Settings dialog listing archived sessions (title / workspace / relative time) with Restore and Delete actions |
17
+ | ![MCP manager](assets/mcp.png) | |
18
+ | **MCP manager**: an MCP page in the Settings dialog listing configured MCP servers with live status and full management (Add / Edit / Enable / Disable / Delete / Restart) | |
19
19
 
20
20
  ## Features
21
21
 
22
22
  - **Code font size (px)** — absolute 8–32px, default 13 (DSH's stock code-block size at a 16px body); applies to code blocks, with inline code following proportionally. The legacy percentage (`codeFontScale`) stays compatible and is overridden once a px value is set. Message text keeps DSH's stock sizing.
23
- - **Table style** — choose `Default` or the **Claude Desktop** look (light-gray rounded cell cards with small gaps, no borders; cells share the inline-code background; header not bold).
23
+ - **Theme (single choice in Layout, stock look by default)** — choose `Default` or **Neon lime**: a two-scheme poster skin — paper-white with ink-black hairlines in light mode, near-black with light hairlines in dark mode, both with lime highlights and a magenta action accent (buttons, links and selections follow the theme tokens automatically; code blocks and the composer card get hard offset shadows), applied live. Future skins will be added as further options the same way.
24
24
  - **Timeline (single choice in Features)** — one switch, two options:
25
25
  - **Native (default)** — DSH's built-in turn rail (the row of small dots beside the messages), the stock behavior.
26
26
  - **Web (classic)** — the v0.11 classic right-side navigation rail, restored: vertically centered on the message area's right edge, a thin line strip when collapsed, a 240px panel on hover (message previews + current-position highlight), a per-item detail bubble with timestamp, and **click to jump** (deep history pages in automatically before landing, with a landing self-check); wheel over the rail scrubs clipped items into reach. Data comes from the server-side `dshChatTimeline` session projection (every user message, independent of the browser's loaded window); sessions with fewer than two user messages hide it. On the web option the native turn rail is hidden with one theme-independent CSS rule (matching its `--turn-natural-height` inline variable), so the two never appear together.
@@ -46,8 +46,8 @@ All changes apply **live** — no reload needed. The same values can be hand-edi
46
46
 
47
47
  ```yaml
48
48
  ui-tweaks:
49
- tableStyle: claude
50
49
  timelineStyle: web # defaults to native (DSH's built-in turn rail); web is the classic web timeline
50
+ themeStyle: neon-lime # defaults to default (DSH's stock look); neon-lime is the fluorescent-lime skin
51
51
  gitBarEnabled: true # defaults to false (off); set true to enable GitBar
52
52
  archiveManagerEnabled: true # defaults to false (off); set true to show the Archive page
53
53
  initCommandEnabled: true # defaults to false (off); set true to register the /init slash command
package/README.md CHANGED
@@ -2,25 +2,25 @@
2
2
 
3
3
  > **依赖版本**:当前依赖 **DSH v0.1.5-alpha.1**。
4
4
 
5
- [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/)(DSH)Web UI 插件:在设置面板中实时调整对话界面——代码字号、表格样式、**时间线切换**(原生回合导航轨 / 经典网页时间线)、**GitBar**(输入框工具行内的 git 状态胶囊:分支在权限旁、差异在模型前),可开关的**归档管理**(设置中的「归档」页面:查看、恢复或彻底删除已归档会话),可开关的**任务提醒**(会话完成或需要交互时,通过标签页标题闪烁 / 系统通知 / 提示音把你唤回来),以及**缓存命中率两位小数**(把输入框下方统计条的缓存命中百分比改写为精确值)。
5
+ [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/)(DSH)Web UI 插件:在设置面板中实时调整对话界面——代码字号、**主题皮肤**(荧光黄海报风)、**时间线切换**(原生回合导航轨 / 经典网页时间线)、**GitBar**(输入框工具行内的 git 状态胶囊:分支在权限旁、差异在模型前),可开关的**归档管理**(设置中的「归档」页面:查看、恢复或彻底删除已归档会话),可开关的**任务提醒**(会话完成或需要交互时,通过标签页标题闪烁 / 系统通知 / 提示音把你唤回来),以及**缓存命中率两位小数**(把输入框下方统计条的缓存命中百分比改写为精确值)。
6
6
 
7
7
  ## 预览
8
8
 
9
9
  | | |
10
10
  |---|---|
11
- | ![Claude Desktop 表格样式](assets/table.png) | ![设置面板](assets/settings.png) |
12
- | **表格样式**:Claude Desktop 浅灰圆角卡片风格 | **设置面板**:代码字号 / 表格样式 / Git 状态栏等功能开关 |
13
- | ![GitBar](assets/git.png) | ![分支面板](assets/branch.png) |
14
- | **GitBar**:会话头部的分支胶囊(分支管理)+ 右侧边栏里的**终端** / **代码差异**标签页,代码差异页内可直接提交 | **分支面板**:点击分支胶囊向下弹出——本地 / 远程分支列表,点击即切换,支持删除、拉取、推送远程,底部可新建分支,菜单里可打开**提交图谱**(彩色 SVG 分叉图) |
15
- | ![差异面板](assets/gitdiff.png) | ![终端面板](assets/terminal.png) |
16
- | **代码差异**:文件列表 + 逐文件 diff(默认只显示有差异的 hunk),底部提交区可提交 / 提交并推送 | **终端**:边栏里的真 PTY 终端(xterm.js + WebSocket),完整终端交互 |
17
- | ![归档管理](assets/archive.png) | ![MCP 管理](assets/mcp.png) |
18
- | **归档管理**:设置中的「归档」页面,列出所有已归档会话(标题 / 工作区 / 相对时间),支持恢复与彻底删除 | **MCP 管理**:设置中的「MCP 管理」页面,列出所有配置的 MCP 服务器及其运行状态,支持添加 / 编辑 / 启用停用 / 删除 / 重启 |
11
+ | ![设置面板](assets/settings.png) | ![GitBar](assets/git.png) |
12
+ | **设置面板**:代码字号 / 主题皮肤 / Git 状态栏等功能开关 | **GitBar**:会话头部的分支胶囊(分支管理)+ 右侧边栏里的**终端** / **代码差异**标签页,代码差异页内可直接提交 |
13
+ | ![分支面板](assets/branch.png) | ![差异面板](assets/gitdiff.png) |
14
+ | **分支面板**:点击分支胶囊向下弹出——本地 / 远程分支列表,点击即切换,支持删除、拉取、推送远程,底部可新建分支,菜单里可打开**提交图谱**(彩色 SVG 分叉图) | **代码差异**:文件列表 + 逐文件 diff(默认只显示有差异的 hunk),底部提交区可提交 / 提交并推送 |
15
+ | ![终端面板](assets/terminal.png) | ![归档管理](assets/archive.png) |
16
+ | **终端**:边栏里的真 PTY 终端(xterm.js + WebSocket),完整终端交互 | **归档管理**:设置中的「归档」页面,列出所有已归档会话(标题 / 工作区 / 相对时间),支持恢复与彻底删除 |
17
+ | ![MCP 管理](assets/mcp.png) | |
18
+ | **MCP 管理**:设置中的「MCP 管理」页面,列出所有配置的 MCP 服务器及其运行状态,支持添加 / 编辑 / 启用停用 / 删除 / 重启 | |
19
19
 
20
20
  ## 功能
21
21
 
22
22
  - **代码字号(px)**:绝对值 8–32,默认 13(正文 16 时的 DSH 原生代码块字号);作用于代码块,行内代码按比例跟随——旧版的百分比配置(`codeFontScale`)仍然兼容,一旦设置新的 px 值即以其为准。消息正文保持 DSH 原生字号。
23
- - **表格样式**:可选 `默认` 或 **Claude Desktop** 风格(浅灰圆角单元格卡片、单元格间有间隙、无边框、单元格与行内代码同底色、表头不加粗)。Claude 风格下表格默认撑满列宽;放不下的宽表保持自然宽度、在表格内横向滚动(悬停出现滚动条),不会被挤压换行或裁掉后面的列。
23
+ - **主题(布局区单选,默认即原生外观)**:可选 `默认` 或 **荧光黄**——海报风双方案皮肤:浅色模式纸白底 + 黑粗线条,深色模式近黑底 + 浅色粗线条,都配荧光黄高亮 + 品红点缀(按钮、链接、选中态跟随主题变量自动变色,代码块与输入框卡片带硬阴影贴纸效果),切换即时生效。后续皮肤会以同样方式追加为新选项。
24
24
  - **时间线(功能区内单选)**:一个开关两档,选一个:
25
25
  - **原生(默认)**:DSH 自带的回合导航轨(消息右侧的小圆点条),即官方默认行为。
26
26
  - **网页(经典)**:找回 v0.11 的经典右侧导航轨——消息区右缘垂直居中,收起时是一列细线,悬停展开为 240px 面板(消息预览 + 高亮当前位),悬停单项弹出带时间戳的详情气泡,**点击跳转**到对应消息(深历史会自动连续翻页加载后落点,带落点自校验);滚轮可在轨上直接翻阅被裁剪的条目。数据来自服务端 `dshChatTimeline` 会话投影(全量用户消息,与浏览器已加载窗口无关),少于两条用户消息的会话自动隐藏;切换到网页档时,原生回合导航轨由插件用一条主题无关的 CSS 规则(命中其 `--turn-natural-height` 内联变量)隐藏,两个不会同时出现。
@@ -49,8 +49,8 @@
49
49
 
50
50
  ```yaml
51
51
  ui-tweaks:
52
- tableStyle: claude
53
52
  timelineStyle: web # 默认 native(DSH 自带回合导航轨),web 为经典网页时间线
53
+ themeStyle: neon-lime # 默认 default(DSH 原生外观),neon-lime 为荧光黄皮肤
54
54
  gitBarEnabled: true # 默认 false(关闭),设为 true 开启 GitBar
55
55
  archiveManagerEnabled: true # 默认 false(关闭),设为 true 开启「归档」页面
56
56
  initCommandEnabled: true # 默认 false(关闭),设为 true 开启 /init 斜杠命令
@@ -107,7 +107,7 @@ npx -y @deepseek-ai/dsh plugin --profile web add . # 从本目录作为 b
107
107
 
108
108
  - **服务端**(`src/index.ts`):注册 `ui-tweaks` 设置命名空间,并挂载同源路由 `/_dsh/ui-tweaks/settings`——自 rc.6 起,Web 设置 RPC 只暴露固定白名单命名空间,因此自定义路由是插件拥有配置页的方式。
109
109
  - **Git 后端**(`src/git.ts` + `src/git-web.ts`):通过 `ctx.get('sessions')`(可选服务)解析会话 header 的 `cwd` 作为“当前项目”,用 `child_process.execFile('git', …)`(无 shell、cwd 固定、超时 + 中止传播)执行只读/写操作;同源路由 `/_dsh/ui-tweaks/git/*` 提供 status / branches / diff(hunk 或完整文件,含绝对行号)/ graph(结构化提交行,含父哈希,供前端排布分支 lane)/ commit / push / pull(仅快进)/ checkout / create / branch-delete / remote-delete。
110
- - **浏览器端**(`src/client/index.tsx`):读写该路由、渲染设置页,并通过运行时 `<style>` 元素实时应用样式,覆盖稳定的 DSH 锚点(`body` 上的 markdown 代码字体 token、`[data-slot="conversation.chat.node"]` 内的 markdown 表格)。
110
+ - **浏览器端**(`src/client/index.tsx`):读写该路由、渲染设置页,并通过运行时 `<style>` 元素实时应用样式,覆盖稳定的 DSH 锚点(`body` 上的 markdown 代码字体 token 与主题变量、`[data-slot="conversation.chat.node"]` 内的代码块 / 表头)。
111
111
  - **GitBar**(`src/client/gitbar.tsx`):分支胶囊挂在 `conversation.session.header.actions`(会话标题旁),终端与代码差异则注册为右侧边栏原生标签页(page 类型:`ctx.sidebarRightTabs` 注册类型与指南入口,`sidebar.right.pane.tab` 按类型 id 注册内容,代码差异另注册标题席位在页签上补未提交改动的小黄点,随 `gitBarEnabled` 开关按需挂载)。视图是全高 flex 列:文件列表 / diff / 提交区三段高度分配采用「只给被拖的那一段显式高度、diff 段 `flex:1` 吃掉余量」的方式,配合 45% 上限,拖动永远不会撑破视图;终端的 xterm 宿主同样 `flex:1` 吃掉页体高度,fit 插件 + ResizeObserver 自适应。提交保留在代码差异页底部的提交区。在外部应用中打开项目是 DSH 自带的 open-in-app 按钮,本插件的 `/open` 路由与 `openFolder` 后端已随之移除。提交图谱对话框的 lane 布局与 SVG 渲染拆在 `src/client/graphlayout.ts`(纯函数模块:父哈希 → 每行 lane / 边段,经典 first-parent 路由——第一父提交沿用原 lane 让线性历史始终一条线,合并与 fork 画贝塞尔弧线;`parents` 字段可选,兼容宿主里尚未重载的旧服务端)。
112
112
  - **归档管理**(服务端 `src/archive.ts` + 浏览器端 `src/client/archive.tsx`):作为 `settings.section` 插槽(设置面板中的「归档」页面)。列表数据直接来自框架标准 hook `useSessions` + `useWorkspaces`(`archivedSessionIds`),无需额外查询;操作走同源路由 `/_dsh/ui-tweaks/archive`。**恢复**把会话 id 从工作区存储域的 `archivedSessionIds` 全局单例中移除(DSH 只暴露单向 `archiveSession`,无公开的取消归档 API,故直接写活体存储域句柄并同步工作区注册表的内存缓存)。**彻底删除**依次:拒绝正在运行的会话(agent `status === 'running'` 才拒绝,空闲会话先 `cancel` + `whenIdle`)→ 用持久化后端自身的 `findLog` 定位并 `rm` 会话日志目录 → 调用公开的 `WorkspaceEntity.detachSession` 摘除工作区记账 → 从归档集合移除并同步注册表内存缓存与 header 索引 → 清理 `session_projcache` → 从内存 SessionStore 摘除该会话(触发 `host/session-removed` 实时消失)。
113
113
  - **MCP 管理**(服务端 `src/mcp.ts` + 浏览器端 `src/client/mcp.tsx`):同源路由 `/_dsh/ui-tweaks/mcp`。**列表**枚举 `ctx.loader.entries()` 中 `@deepseek-ai/dsh-mcp-client` 实例(id / config / fiber 状态:active=2、failed=3 等)并按 `mcp__<serverName>__` 前缀从工具注册表统计工具。**重启**调用 `entry.fiber.restart()`(仅运行时)。**添加 / 编辑 / 删除 / 启用停用**通过 `yaml`(eemeli)的 Document API 直接编辑 profile 的 `cordis.patch.yml`(保留注释与未知补丁结构,原子写 tmp+rename),随后由 DSH 内置的 `watchUserPatches` 热重载监视器重新应用补丁——`cordis-plugin-include` 对根组做**增量** `root.update`,因此只有被改动的 MCP 实例会重启,其它不受影响;环境变量值返回给同源浏览器(本机配置编辑需要),YAML 模式在服务端用 `yaml.parse` + 白名单校验。
package/lib/client.js CHANGED
@@ -2431,19 +2431,19 @@ const en = {
2431
2431
  nav: 'UI Tweaks',
2432
2432
  settingsTitle: 'UI Tweaks',
2433
2433
  settingsIntro: 'Tune the conversation UI — code size, tables and layout, plus optional features: git bar, archive & MCP managers and the /init command. Changes apply live.',
2434
- sectionText: 'Text & tables',
2434
+ sectionText: 'Text',
2435
2435
  sectionLayout: 'Layout',
2436
2436
  sectionFeatures: 'Features',
2437
2437
  codeFontSize: 'Code font size',
2438
2438
  codeFontSizeHint: `Absolute code size in px (${MIN_CODE_FONT_SIZE}–${MAX_CODE_FONT_SIZE}); ${DEFAULT_CODE_FONT_SIZE}px is DSH's default at a 16px body. Applies to code blocks; inline code follows proportionally.`,
2439
- tableStyle: 'Table style',
2440
- tableStyleHint: 'Cell look for markdown tables: stock borders, or the Claude Desktop card style.',
2441
- tableStyleDefault: 'Default',
2442
- tableStyleClaude: 'Claude Desktop',
2443
2439
  timeline: 'Timeline',
2444
2440
  timelineHint: 'Native: DSH\u2019s built-in turn rail at the right edge (stock). Web (classic): the v0.11 right-side navigation rail — hover to preview, click to jump; auto-hidden in short conversations.',
2445
2441
  timelineNative: 'Native',
2446
2442
  timelineWeb: 'Web (classic)',
2443
+ theme: 'Theme',
2444
+ themeHint: 'Conversation skin. Default keeps DSH\u2019s stock look; Neon lime is a poster skin — paper-white with ink-black hairlines in light mode, near-black with light hairlines in dark mode, lime highlights and a magenta action accent, applied live.',
2445
+ themeDefault: 'Default',
2446
+ themeNeonLime: 'Neon lime',
2447
2447
  sectionSearch: 'Web search',
2448
2448
  searchOn: 'On',
2449
2449
  searchOff: 'Off',
@@ -2667,19 +2667,19 @@ const zh = {
2667
2667
  nav: '界面调整',
2668
2668
  settingsTitle: '界面调整',
2669
2669
  settingsIntro: '调整对话界面——代码字号、表格与布局,以及时间线、Git 状态栏、归档 / MCP 管理、/init 命令等功能开关,修改即时生效。',
2670
- sectionText: '文本与表格',
2670
+ sectionText: '文本',
2671
2671
  sectionLayout: '布局',
2672
2672
  sectionFeatures: '功能',
2673
2673
  codeFontSize: '代码字号',
2674
2674
  codeFontSizeHint: `代码绝对字号,取值 ${MIN_CODE_FONT_SIZE}–${MAX_CODE_FONT_SIZE}px;${DEFAULT_CODE_FONT_SIZE}px 为 DSH 默认(正文 16 时)。作用于代码块,行内代码按比例跟随。`,
2675
- tableStyle: '表格样式',
2676
- tableStyleHint: 'Markdown 表格的外观:默认边框,或 Claude Desktop 卡片风格。',
2677
- tableStyleDefault: '默认',
2678
- tableStyleClaude: 'Claude Desktop',
2679
2675
  timeline: '时间线',
2680
2676
  timelineHint: '原生:DSH 自带的回合导航轨(消息右侧小圆点,默认)。网页(经典):找回 v0.11 的右侧导航轨——悬停预览、点击跳转;会话较短时自动隐藏。',
2681
2677
  timelineNative: '原生',
2682
2678
  timelineWeb: '网页(经典)',
2679
+ theme: '主题',
2680
+ themeHint: '对话皮肤。默认保持 DSH 原生外观;荧光黄是海报风双方案——浅色下纸白底黑粗线,深色下近黑底浅粗线,都配荧光黄高亮 + 品红点缀,切换即时生效。',
2681
+ themeDefault: '默认',
2682
+ themeNeonLime: '荧光黄',
2683
2683
  sectionSearch: '网络搜索',
2684
2684
  searchOn: '开',
2685
2685
  searchOff: '关',
@@ -2907,8 +2907,8 @@ function resolveValue(value) {
2907
2907
  : Math.max(8, Math.round(DEFAULT_CODE_FONT_SIZE * ((value?.codeFontScale ?? DEFAULT_CODE_FONT_SCALE) / DEFAULT_CODE_FONT_SCALE)));
2908
2908
  return {
2909
2909
  codeFontSize,
2910
- tableStyle: value?.tableStyle === 'claude' ? 'claude' : 'default',
2911
2910
  timelineStyle: value?.timelineStyle === 'web' ? 'web' : 'native',
2911
+ themeStyle: value?.themeStyle === 'neon-lime' ? 'neon-lime' : 'default',
2912
2912
  searchEngine: value?.searchEngine ?? 'bing',
2913
2913
  bingMarket: value?.bingMarket ?? 'zh-CN',
2914
2914
  gitBarEnabled: value?.gitBarEnabled ?? false,
@@ -2957,46 +2957,265 @@ function buildCodeFontCss(codeFontSize) {
2957
2957
  return `body{${parts.join(';')}}`;
2958
2958
  }
2959
2959
  /**
2960
- * Claude Desktop-ish markdown table look: light-gray rounded cell cards with
2961
- * small gaps, no borders. Cells share the theme's inline-code background.
2962
- * Alignment is left to the markdown renderer, so headers and cells always
2963
- * match; font sizes stay DSH's stock values.
2960
+ * Fluorescent-lime poster skin (Bilibili tech-video look), in two schemes:
2961
+ * the paper-white poster (lime highlights, magenta action accent) in light
2962
+ * mode, and its dark twin in dark mode — near-black paper with the same
2963
+ * lime/magenta stickers. Popovers and menus (model switcher, open-in-app,
2964
+ * stat dialogs, context panel) ride the scheme's own paper so they never read
2965
+ * as a gray slab against the conversation.
2966
+ *
2967
+ * Every colour is a `--dut-*` design variable re-pointed per scheme, and the
2968
+ * DSW alias tokens map onto those variables in one place, so buttons, links,
2969
+ * selections, the sidebar and the plugin's own tinted controls follow
2970
+ * automatically in either host scheme. The host's own hairlines keep their
2971
+ * shipped subtle values (`--dut-line-*`); the bold ink frame is applied only
2972
+ * where this skin says so — code blocks, the composer card, the markdown
2973
+ * table header and the settings panels, all with hard offset shadows.
2974
+ * 'default' emits nothing and stays stock. Future skins add one union member
2975
+ * plus one block.
2964
2976
  */
2965
- const CLAUDE_TABLE_CSS = `
2966
- div[data-slot="conversation.chat.node"] table{
2967
- border-collapse:separate !important;
2968
- border-spacing:3px !important;
2969
- width:100% !important;
2970
- /* Fill the column like Claude Desktop, but never squeeze below the natural
2971
- (no-wrap) width: a table too wide to fit keeps its real width and scrolls
2972
- inside the stock table wrapper instead of hiding columns. */
2973
- min-width:max-content !important;
2974
- border:none !important;
2977
+ const NEON_LIME_CSS = `
2978
+ /* The host injects its theme sheets at runtime, so their <style> order against
2979
+ this one is not guaranteed; the id in :not() lifts the skin above the host's
2980
+ body[data-ds-dark-theme] palette (same specificity, later wins) without
2981
+ !important. The id never exists in the DOM. */
2982
+ body:not(#dsh-ui-tweaks-theme-scope){
2983
+ color-scheme:light;
2984
+ --dut-paper:#ffffff;
2985
+ --dut-paper-2:#fafbfc;
2986
+ --dut-paper-3:#ffffff;
2987
+ --dut-pop:#ffffff;
2988
+ --dut-ink:#101418;
2989
+ --dut-on-ink:#c6ff00;
2990
+ --dut-code:#f7f8f9;
2991
+ --dut-text-1:#101418;
2992
+ --dut-text-2:#3d4750;
2993
+ --dut-text-3:#7a8791;
2994
+ --dut-text-4:#9aa4ad;
2995
+ --dut-btn-fg:#ffffff;
2996
+ --dut-lime:#c6ff00;
2997
+ --dut-lime-soft:#dcff4d;
2998
+ --dut-magenta:#e6007e;
2999
+ --dut-magenta-soft:rgba(230,0,126,.12);
3000
+ --dut-hover:rgba(230,0,126,.07);
3001
+ --dut-active:rgba(230,0,126,.13);
3002
+ --dut-sel-bg:#dcff4d;
3003
+ --dut-sel-fg:#101418;
3004
+ --dut-faint:rgba(0,0,0,.06);
3005
+ --dut-scroll-1:#e3e6ea;
3006
+ --dut-scroll-2:#c8cdd3;
3007
+ --dut-elev:#101418;
3008
+ /* the user bubble: the original pale pink in light mode; dark mode keeps the
3009
+ wine-red tone the user settled on (a lighter pink read as washed out) */
3010
+ --dut-bubble:#ffe4f1;
3011
+ --dut-shadow:#101418;
3012
+ --dut-drop:rgba(255,255,255,.7);
3013
+ /* Hairlines stay the host's own subtle values: the shipped 0.5px pills and
3014
+ dividers are designed around them, and painting them poster-ink read as
3015
+ "changed too much". The bold ink lives only in this skin's own explicit
3016
+ rules (code blocks, composer card, table header, panels). */
3017
+ --dut-line-1:rgba(0,0,0,.04);
3018
+ --dut-line-2:rgba(0,0,0,.10);
3019
+ --dut-line-3:rgba(0,0,0,.12);
3020
+ --dut-line-4:rgba(0,0,0,.16);
3021
+ --dut-error:var(--dsw-static-red-600);
3022
+ --dut-error-2:var(--dsw-static-red-400);
3023
+ --dut-success:var(--dsw-static-green-500);
3024
+ --dut-success-2:var(--dsw-static-green-400);
3025
+ --dut-success-3:var(--dsw-static-green-100);
3026
+ --dut-warn-3:var(--dsw-static-amber-100);
3027
+ --dsw-alias-bg-base:var(--dut-paper);
3028
+ --dsw-alias-bg-layer-1:var(--dut-paper);
3029
+ --dsw-alias-bg-layer-2:var(--dut-paper-2);
3030
+ --dsw-alias-bg-layer-3:var(--dut-paper-3);
3031
+ --dsw-alias-bg-mask-1:rgba(0,0,0,.24);
3032
+ --dsw-alias-bg-mask-2:rgba(0,0,0,.12);
3033
+ --dsw-alias-bg-mask-3:rgba(0,0,0,.48);
3034
+ --dsw-alias-bg-mask-photo:rgba(0,0,0,.88);
3035
+ --dsw-alias-bg-mask-drop:var(--dut-drop);
3036
+ --dsw-alias-bg-module-platform:var(--dut-paper-3);
3037
+ --dsw-alias-bg-multi-select:var(--dut-paper-2);
3038
+ --dsw-alias-bg-overlay:var(--dut-paper-3);
3039
+ --dsw-alias-bg-skeleton:var(--dut-faint);
3040
+ --dsw-alias-border-inverted:rgba(0,0,0,0);
3041
+ --dsw-alias-border-inverted2:rgba(0,0,0,0);
3042
+ --dsw-alias-border-l1:var(--dut-line-1);
3043
+ --dsw-alias-border-l2:var(--dut-line-2);
3044
+ --dsw-alias-border-l2-darkmode-thin:var(--dut-line-2);
3045
+ --dsw-alias-border-l3:var(--dut-line-3);
3046
+ --dsw-alias-border-l4:var(--dut-line-4);
3047
+ --dsw-alias-brand-primary:var(--dut-text-1);
3048
+ --dsw-alias-brand-primary-invert:var(--dut-paper);
3049
+ --dsw-alias-brand-text:var(--dut-text-1);
3050
+ --dsw-alias-brand-primary-new-colorprimary-new-color:var(--dut-magenta);
3051
+ --dsw-alias-button-contrast-fill:var(--dut-text-2);
3052
+ --dsw-alias-button-elevated-fill:var(--dut-paper);
3053
+ --dsw-alias-button-floating-fill:var(--dut-paper);
3054
+ --dsw-alias-button-floating-hover:var(--dut-paper-2);
3055
+ --dsw-alias-button-ghost-active-border:var(--dut-ink);
3056
+ --dsw-alias-button-ghost-active-fill:var(--dut-paper-3);
3057
+ --dsw-alias-button-ghost-active-hover:var(--dut-paper-3);
3058
+ --dsw-alias-button-info-fill:var(--dut-magenta);
3059
+ --dsw-alias-button-info-hover:var(--dut-magenta);
3060
+ --dsw-alias-button-primary-dimmed:var(--dut-paper-2);
3061
+ --dsw-alias-button-primary-fill:var(--dut-text-1);
3062
+ --dsw-alias-button-primary-hover:var(--dut-text-1);
3063
+ --dsw-alias-interactive-bg-active:var(--dut-active);
3064
+ --dsw-alias-interactive-bg-hover:var(--dut-hover);
3065
+ --dsw-alias-interactive-bg-hover-accent:var(--dut-active);
3066
+ --dsw-alias-interactive-bg-hover-danger:rgba(236,19,19,.05);
3067
+ --dsw-alias-interactive-bg-hover-solid:var(--dut-paper-3);
3068
+ --dsw-alias-label-caption:var(--dut-text-4);
3069
+ --dsw-alias-label-dimmed:var(--dut-text-4);
3070
+ --dsw-alias-label-primary:var(--dut-text-1);
3071
+ --dsw-alias-label-primary-bluish:var(--dut-text-1);
3072
+ --dsw-alias-label-primary-dimmed:var(--dut-text-1);
3073
+ --dsw-alias-label-primary-foreground:var(--dut-btn-fg);
3074
+ --dsw-alias-label-primary-inverted:var(--dut-btn-fg);
3075
+ --dsw-alias-label-secondary:var(--dut-text-2);
3076
+ --dsw-alias-label-tertiary:var(--dut-text-3);
3077
+ --dsw-alias-link:var(--dut-magenta);
3078
+ --dsw-alias-markdown-citation:var(--dut-paper-2);
3079
+ --dsw-alias-markdown-code-block:var(--dut-code);
3080
+ --dsw-alias-markdown-code-block-banner:var(--dut-paper-3);
3081
+ --dsw-alias-markdown-code-segment-selected:var(--dut-paper);
3082
+ --dsw-alias-markdown-code-segment-unselected:var(--dut-paper-2);
3083
+ --dsw-alias-markdown-inline-code:var(--dut-lime-soft);
3084
+ --dsw-alias-markdown-placeholder:var(--dut-paper-2);
3085
+ --dsw-alias-markdown-tag:var(--dut-paper-2);
3086
+ --dsw-alias-scrollbar-bg-l1:var(--dut-scroll-1);
3087
+ --dsw-alias-scrollbar-bg-l2:var(--dut-scroll-1);
3088
+ --dsw-alias-scrollbar-hover-l1:var(--dut-scroll-2);
3089
+ --dsw-alias-scrollbar-hover-l2:var(--dut-scroll-2);
3090
+ --dsw-alias-state-business-primary:var(--dut-magenta);
3091
+ --dsw-alias-state-business-tertiary:var(--dut-magenta-soft);
3092
+ --dsw-alias-state-error-primary:var(--dut-error);
3093
+ --dsw-alias-state-error-secondary:var(--dut-error-2);
3094
+ --dsw-alias-state-success-primary:var(--dut-success);
3095
+ --dsw-alias-state-success-secondary:var(--dut-success-2);
3096
+ --dsw-alias-state-success-tertiary:var(--dut-success-3);
3097
+ --dsw-alias-state-warn-label:var(--dsw-static-amber-600);
3098
+ --dsw-alias-state-warn-primary:var(--dsw-static-amber-500);
3099
+ --dsw-alias-state-warn-secondary:var(--dsw-static-amber-400);
3100
+ --dsw-alias-state-warn-tertiary:var(--dut-warn-3);
3101
+ --dsw-alias-toast-bg:var(--dut-elev);
3102
+ --dsw-alias-tooltip-bg:var(--dut-elev);
3103
+ --dsw-specific-bubble:var(--dut-bubble);
3104
+ --dsw-specific-bubble-highlight:var(--dut-lime-soft);
3105
+ --dsw-specific-input-major:var(--dut-pop);
3106
+ --dsw-specific-login-input:var(--dut-paper-2);
3107
+ --dsw-specific-selector:var(--dut-pop);
3108
+ --dsw-specific-menu:var(--dut-pop);
3109
+ --dsw-specific-sidebar-fill:var(--dut-paper);
3110
+ --dsw-specific-sidebar-nav-item-active:var(--dut-lime-soft);
3111
+ --dsw-specific-sidebar-nav-item-active-accent:var(--dut-lime);
3112
+ --dsw-specific-sidebar-nav-item-hover:var(--dut-paper-2);
3113
+ --dsw-specific-tip:var(--dut-paper-2);
2975
3114
  }
2976
- div[data-slot="conversation.chat.node"] table thead th{
2977
- background:var(--dsw-alias-markdown-inline-code) !important;
2978
- color:inherit !important;
2979
- font-weight:400 !important;
2980
- font-size:inherit !important;
2981
- padding:7px 10px !important;
2982
- border:none !important;
2983
- border-radius:6px !important;
3115
+ /* Dark scheme: re-point the design variables only — every alias mapping and
3116
+ element rule follows through var() indirection, so the host's scheme toggle
3117
+ flips the whole skin without a second copy of the rules. */
3118
+ body:not(#dsh-ui-tweaks-theme-scope)[data-ds-dark-theme]{
3119
+ color-scheme:dark;
3120
+ --dut-paper:#0b0d10;
3121
+ --dut-paper-2:#14181d;
3122
+ --dut-paper-3:#1e252c;
3123
+ --dut-pop:#161c22;
3124
+ --dut-ink:#e8ecef;
3125
+ --dut-on-ink:#101418;
3126
+ --dut-code:#171d24;
3127
+ --dut-text-1:#f2f5f3;
3128
+ --dut-text-2:#b9c3ca;
3129
+ --dut-text-3:#7f8d97;
3130
+ --dut-text-4:#66727c;
3131
+ --dut-btn-fg:#101418;
3132
+ --dut-lime:#c6ff00;
3133
+ --dut-lime-soft:#dcff4d;
3134
+ --dut-magenta:#ff3d9a;
3135
+ --dut-magenta-soft:rgba(255,61,154,.16);
3136
+ --dut-hover:rgba(255,61,154,.16);
3137
+ --dut-active:rgba(255,61,154,.26);
3138
+ --dut-sel-bg:#dcff4d;
3139
+ --dut-sel-fg:#101418;
3140
+ --dut-faint:rgba(255,255,255,.07);
3141
+ --dut-scroll-1:#2a3138;
3142
+ --dut-scroll-2:#3a444d;
3143
+ --dut-elev:#1f262c;
3144
+ --dut-bubble:#2a1220;
3145
+ /* the hard sticker offset rides the frame's own ink in both schemes: black
3146
+ under the white-paper card, white under the near-black one, so the border
3147
+ and its offset band read as one shape */
3148
+ --dut-shadow:#e8ecef;
3149
+ --dut-drop:rgba(39,39,48,.7);
3150
+ --dut-line-1:rgba(255,255,255,.06);
3151
+ --dut-line-2:rgba(255,255,255,.12);
3152
+ --dut-line-3:rgba(255,255,255,.16);
3153
+ --dut-line-4:rgba(255,255,255,.20);
3154
+ --dut-error:var(--dsw-static-red-400);
3155
+ --dut-error-2:var(--dsw-static-red-400);
3156
+ --dut-success:var(--dsw-static-green-400);
3157
+ --dut-success-2:var(--dsw-static-green-400);
3158
+ --dut-success-3:var(--dsw-static-green-900);
3159
+ --dut-warn-3:var(--dsw-static-amber-900);
2984
3160
  }
2985
- div[data-slot="conversation.chat.node"] table tbody td{
2986
- background:var(--dsw-alias-markdown-inline-code) !important;
2987
- color:inherit !important;
2988
- font-size:inherit !important;
2989
- padding:7px 10px !important;
2990
- vertical-align:top !important;
3161
+ ::selection{background:var(--dut-sel-bg);color:var(--dut-sel-fg)}
3162
+ /* table header: the screenshot's ink header strip with lime type */
3163
+ div[data-slot="conversation.chat.node"] table th{
3164
+ background:var(--dut-ink);
3165
+ color:var(--dut-on-ink);
3166
+ }
3167
+ div[data-slot="conversation.chat.node"] pre{
3168
+ border:2px solid var(--dut-ink) !important;
3169
+ border-radius:10px !important;
3170
+ box-shadow:5px 5px 0 var(--dut-shadow) !important;
3171
+ background:var(--dut-paper) !important;
3172
+ }
3173
+ div[data-slot="conversation.chat.node"] :not(pre)>code{
3174
+ background:var(--dut-lime-soft) !important;
3175
+ color:#101418 !important;
2991
3176
  border:none !important;
2992
3177
  border-radius:6px !important;
3178
+ padding:1px 6px !important;
2993
3179
  }
2994
- div[data-slot="conversation.chat.node"] table code,
2995
- div[data-slot="conversation.chat.node"] table pre{
2996
- background:transparent !important;
2997
- border:none !important;
2998
- box-shadow:none !important;
3180
+ /* composer card: white framed sticker (hard shadow, ink border) */
3181
+ div[data-composer-card]{
3182
+ border:2px solid var(--dut-ink) !important;
3183
+ box-shadow:5px 5px 0 var(--dut-shadow) !important;
3184
+ background:var(--dut-paper) !important;
2999
3185
  }
3186
+ /* context-occupancy ring: the stock track/fill both read near-ink on this
3187
+ skin; give the track a quiet gray and the used arc the magenta accent
3188
+ (scoped to the composer's svg so the class-substring match stays safe) */
3189
+ div[data-composer-card] svg [class*="track"]{stroke:var(--dut-scroll-1)}
3190
+ div[data-composer-card] svg [class*="fill"]{stroke:var(--dut-magenta)}
3191
+ /* sidebar new-session button: lime sticker. Matched by its CSS-module class,
3192
+ NOT the aria-label — the brand row button shares the same "新建会话"
3193
+ label (it doubles as the new-session shortcut) and must stay plain. */
3194
+ button[class*="newSession"]{
3195
+ background:var(--dut-lime) !important;
3196
+ color:#101418 !important;
3197
+ border:2px solid var(--dut-ink) !important;
3198
+ border-radius:10px !important;
3199
+ box-shadow:3px 3px 0 var(--dut-shadow) !important;
3200
+ }
3201
+ button[class*="newSession"]:hover{background:#d4ff33 !important;color:#101418 !important}
3202
+ /* dark scheme: invert the sticker to a lime-outlined dark pill — a full lime
3203
+ slab was the loudest thing in the column and the black label read as a
3204
+ mistake next to the dark chrome */
3205
+ body:not(#dsh-ui-tweaks-theme-scope)[data-ds-dark-theme] button[class*="newSession"],
3206
+ body:not(#dsh-ui-tweaks-theme-scope)[data-ds-dark-theme] button[class*="newSession"]:hover{
3207
+ background:var(--dut-paper) !important;
3208
+ color:var(--dut-lime) !important;
3209
+ border-color:var(--dut-lime) !important;
3210
+ box-shadow:3px 3px 0 var(--dut-lime) !important;
3211
+ }
3212
+ /* The poster frame is the host's own 1px border (recolored) plus a 1px inset
3213
+ ring, not a real 2px border: a 2px border stole 2px of content width and
3214
+ wrapped the half-width alert cells ("仅页面不可见时" and its buttons broke
3215
+ onto two lines). An inset ring costs no layout. */
3216
+ .dut-panel{border-color:var(--dut-ink) !important;box-shadow:inset 0 0 0 1px var(--dut-ink),5px 5px 0 var(--dut-shadow) !important}
3217
+ .dut-seg button.dut-seg-active{background:var(--dut-lime) !important;color:#101418 !important}
3218
+ .dut-btn.dut-btn-active{background:var(--dut-lime) !important;color:#101418 !important;border-color:var(--dut-ink) !important}
3000
3219
  `;
3001
3220
  function buildRuntimeCss(value) {
3002
3221
  const rules = [];
@@ -3012,9 +3231,6 @@ function buildRuntimeCss(value) {
3012
3231
  const em = (0.875 * (value.codeFontSize / DEFAULT_CODE_FONT_SIZE)).toFixed(3);
3013
3232
  rules.push(`div[data-slot="conversation.chat.node"] div[class*="_markdown_"] :not(pre)>code{font-size:${em}em !important}`);
3014
3233
  }
3015
- if (value.tableStyle === 'claude') {
3016
- rules.push(CLAUDE_TABLE_CSS);
3017
- }
3018
3234
  // Hide the DSH built-in turn-navigation rail while the timeline switch is
3019
3235
  // on 'web'. The rail is a `<nav>` whose inline style carries the frame's
3020
3236
  // `--turn-natural-height` custom property — unique to TurnNavigator (not a
@@ -3023,6 +3239,9 @@ function buildRuntimeCss(value) {
3023
3239
  if (value.timelineStyle === 'web') {
3024
3240
  rules.push('nav[style*="--turn-natural-height"]{display:none !important}');
3025
3241
  }
3242
+ if (value.themeStyle === 'neon-lime') {
3243
+ rules.push(NEON_LIME_CSS);
3244
+ }
3026
3245
  return rules.join('\n');
3027
3246
  }
3028
3247
  function runtimeStyleElement() {
@@ -3256,9 +3475,6 @@ function SettingsSection({ controller, t }) {
3256
3475
  setCodeDraft(String(clamped));
3257
3476
  void controller.set('codeFontSize', clamped).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
3258
3477
  };
3259
- const pickTableStyle = (raw) => {
3260
- void controller.set('tableStyle', raw === 'claude' ? 'claude' : 'default').then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
3261
- };
3262
3478
  const stepCodeSize = (delta) => {
3263
3479
  const next = Math.min(MAX_CODE_FONT_SIZE, Math.max(MIN_CODE_FONT_SIZE, resolved.codeFontSize + delta));
3264
3480
  setCodeDraft(String(next));
@@ -3297,6 +3513,9 @@ function SettingsSection({ controller, t }) {
3297
3513
  const setPreciseCacheHit = (value) => {
3298
3514
  void controller.set('preciseCacheHitEnabled', value).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
3299
3515
  };
3516
+ const setTheme = (value) => {
3517
+ void controller.set('themeStyle', value).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
3518
+ };
3300
3519
  /** Master switch; enabling also asks for notification permission inside this click gesture. */
3301
3520
  const setNotifications = (value) => {
3302
3521
  if (value)
@@ -3348,7 +3567,7 @@ function SettingsSection({ controller, t }) {
3348
3567
  return (0, jsx_runtime_1.jsx)("div", { className: "dut-settings", children: (0, jsx_runtime_1.jsx)("div", { className: "dut-alert error", children: t('unavailable') }) });
3349
3568
  }
3350
3569
  return ((0, jsx_runtime_1.jsxs)("div", { className: "dut-settings", children: [(0, jsx_runtime_1.jsxs)("header", { className: "dut-settings-header", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-logo", children: "\uD83C\uDFA8" }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h2", { children: t('settingsTitle') }), (0, jsx_runtime_1.jsx)("p", { children: t('settingsIntro') })] })] }), !writable ? (0, jsx_runtime_1.jsx)("div", { className: "dut-alert warning", children: t('readOnly') }) : null, status === undefined ? null : (0, jsx_runtime_1.jsx)("div", { className: "dut-status", children: t(status) }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionText') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('codeFontSize'), (0, jsx_runtime_1.jsx)(Hint, { text: t('codeFontSizeHint') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-controls", children: [(0, jsx_runtime_1.jsxs)("div", { className: "dut-stepper", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "\u2212", disabled: !writable || resolved.codeFontSize <= MIN_CODE_FONT_SIZE, onClick: () => { stepCodeSize(-1); }, children: "\u2212" }), (0, jsx_runtime_1.jsx)("input", { type: "number", min: MIN_CODE_FONT_SIZE, max: MAX_CODE_FONT_SIZE, step: 1, value: codeDraft, disabled: !writable, onChange: (event) => { setCodeDraft(event.target.value); }, onBlur: (event) => { commitCodeSize(event.target.value); }, onKeyDown: (event) => { if (event.key === 'Enter')
3351
- commitCodeSize(event.target.value); } }), (0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "+", disabled: !writable || resolved.codeFontSize >= MAX_CODE_FONT_SIZE, onClick: () => { stepCodeSize(1); }, children: "+" })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: 'dut-btn' + (resolved.codeFontSize === DEFAULT_CODE_FONT_SIZE ? ' dut-btn-active' : ''), disabled: !writable, onClick: () => { resetCodeSize(); }, children: t('defaultAction') })] })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('tableStyle'), (0, jsx_runtime_1.jsx)(Hint, { text: t('tableStyleHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.tableStyle === 'claude' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { pickTableStyle('claude'); }, children: t('tableStyleClaude') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.tableStyle === 'default' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { pickTableStyle('default'); }, children: t('tableStyleDefault') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionLayout') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('preciseCacheHit'), (0, jsx_runtime_1.jsx)(Hint, { text: t('preciseCacheHitHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.preciseCacheHitEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setPreciseCacheHit(true); }, children: t('preciseCacheHitOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.preciseCacheHitEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setPreciseCacheHit(false); }, children: t('preciseCacheHitOff') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionSearch') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('searchEnabled'), (0, jsx_runtime_1.jsx)(Hint, { text: t('searchEnabledHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.searchEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setSearchEnabled(true); }, children: t('searchOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.searchEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setSearchEnabled(false); }, children: t('searchOff') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel dut-grid", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionFeatures') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('timeline'), (0, jsx_runtime_1.jsx)(Hint, { text: t('timelineHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.timelineStyle === 'native' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setTimeline('native'); }, children: t('timelineNative') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.timelineStyle === 'web' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setTimeline('web'); }, children: t('timelineWeb') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('gitBar'), (0, jsx_runtime_1.jsx)(Hint, { text: t('gitBarHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.gitBarEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setGitBar(true); }, children: t('gitBarOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.gitBarEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setGitBar(false); }, children: t('gitBarOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('archiveManager'), (0, jsx_runtime_1.jsx)(Hint, { text: t('archiveManagerHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.archiveManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setArchiveManager(true); }, children: t('archiveManagerOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.archiveManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setArchiveManager(false); }, children: t('archiveManagerOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('mcpManager'), (0, jsx_runtime_1.jsx)(Hint, { text: t('mcpManagerHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.mcpManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setMcpManager(true); }, children: t('mcpManagerOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.mcpManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setMcpManager(false); }, children: t('mcpManagerOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('initCommand'), (0, jsx_runtime_1.jsx)(Hint, { text: t('initCommandHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.initCommandEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setInitCommand(true); }, children: t('initCommandOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.initCommandEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setInitCommand(false); }, children: t('initCommandOff') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel dut-grid dut-grid-half", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionNotifications') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field dut-span-all", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifications'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notificationsHint') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-controls", children: [(0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notificationsEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setNotifications(true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notificationsEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setNotifications(false); }, children: t('notifyOff') })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "dut-btn", disabled: !resolved.notificationsEnabled, onClick: () => { testNotifications(); }, children: t('notifyTest') })] })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyOnComplete'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyOnCompleteHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyOnComplete ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnComplete', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyOnComplete ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnComplete', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyOnInteraction'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyOnInteractionHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyOnInteraction ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnInteraction', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyOnInteraction ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnInteraction', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyOnlyWhenHidden'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyOnlyWhenHiddenHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyOnlyWhenHidden ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnlyWhenHidden', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyOnlyWhenHidden ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnlyWhenHidden', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyTitleFlash'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyTitleFlashHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyTitleFlash ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyTitleFlash', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyTitleFlash ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyTitleFlash', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifySystemNotification'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifySystemNotificationHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifySystemNotification ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySystemNotification', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifySystemNotification ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySystemNotification', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifySound'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifySoundHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifySound ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySound', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifySound ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySound', false); }, children: t('notifyOff') })] }) })] }) })] })] }));
3570
+ commitCodeSize(event.target.value); } }), (0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "+", disabled: !writable || resolved.codeFontSize >= MAX_CODE_FONT_SIZE, onClick: () => { stepCodeSize(1); }, children: "+" })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: 'dut-btn' + (resolved.codeFontSize === DEFAULT_CODE_FONT_SIZE ? ' dut-btn-active' : ''), disabled: !writable, onClick: () => { resetCodeSize(); }, children: t('defaultAction') })] })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionLayout') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('theme'), (0, jsx_runtime_1.jsx)(Hint, { text: t('themeHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.themeStyle === 'neon-lime' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setTheme('neon-lime'); }, children: t('themeNeonLime') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.themeStyle === 'default' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setTheme('default'); }, children: t('themeDefault') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('preciseCacheHit'), (0, jsx_runtime_1.jsx)(Hint, { text: t('preciseCacheHitHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.preciseCacheHitEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setPreciseCacheHit(true); }, children: t('preciseCacheHitOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.preciseCacheHitEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setPreciseCacheHit(false); }, children: t('preciseCacheHitOff') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionSearch') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('searchEnabled'), (0, jsx_runtime_1.jsx)(Hint, { text: t('searchEnabledHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.searchEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setSearchEnabled(true); }, children: t('searchOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.searchEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setSearchEnabled(false); }, children: t('searchOff') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel dut-grid", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionFeatures') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('timeline'), (0, jsx_runtime_1.jsx)(Hint, { text: t('timelineHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.timelineStyle === 'native' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setTimeline('native'); }, children: t('timelineNative') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.timelineStyle === 'web' ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setTimeline('web'); }, children: t('timelineWeb') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('gitBar'), (0, jsx_runtime_1.jsx)(Hint, { text: t('gitBarHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.gitBarEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setGitBar(true); }, children: t('gitBarOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.gitBarEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setGitBar(false); }, children: t('gitBarOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('archiveManager'), (0, jsx_runtime_1.jsx)(Hint, { text: t('archiveManagerHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.archiveManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setArchiveManager(true); }, children: t('archiveManagerOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.archiveManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setArchiveManager(false); }, children: t('archiveManagerOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('mcpManager'), (0, jsx_runtime_1.jsx)(Hint, { text: t('mcpManagerHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.mcpManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setMcpManager(true); }, children: t('mcpManagerOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.mcpManagerEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setMcpManager(false); }, children: t('mcpManagerOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('initCommand'), (0, jsx_runtime_1.jsx)(Hint, { text: t('initCommandHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.initCommandEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setInitCommand(true); }, children: t('initCommandOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.initCommandEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setInitCommand(false); }, children: t('initCommandOff') })] }) })] }) })] }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel dut-grid dut-grid-half", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionNotifications') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field dut-span-all", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifications'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notificationsHint') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-controls", children: [(0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notificationsEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setNotifications(true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notificationsEnabled ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setNotifications(false); }, children: t('notifyOff') })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "dut-btn", disabled: !resolved.notificationsEnabled, onClick: () => { testNotifications(); }, children: t('notifyTest') })] })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyOnComplete'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyOnCompleteHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyOnComplete ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnComplete', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyOnComplete ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnComplete', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyOnInteraction'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyOnInteractionHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyOnInteraction ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnInteraction', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyOnInteraction ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnInteraction', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyOnlyWhenHidden'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyOnlyWhenHiddenHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyOnlyWhenHidden ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnlyWhenHidden', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyOnlyWhenHidden ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyOnlyWhenHidden', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifyTitleFlash'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifyTitleFlashHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifyTitleFlash ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyTitleFlash', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifyTitleFlash ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifyTitleFlash', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifySystemNotification'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifySystemNotificationHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifySystemNotification ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySystemNotification', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifySystemNotification ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySystemNotification', false); }, children: t('notifyOff') })] }) })] }) }), (0, jsx_runtime_1.jsx)("div", { className: 'dut-field' + (!resolved.notificationsEnabled ? ' dut-sub-off' : ''), children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('notifySound'), (0, jsx_runtime_1.jsx)(Hint, { text: t('notifySoundHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.notifySound ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySound', true); }, children: t('notifyOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.notifySound ? 'dut-seg-active' : '', disabled: !writable || !resolved.notificationsEnabled, onClick: () => { setNotifyField('notifySound', false); }, children: t('notifyOff') })] }) })] }) })] })] }));
3352
3571
  }
3353
3572
  /**
3354
3573
  * The /init bootstrap prompts, submitted verbatim into the current session on