10 Commits
0.2.0 ... 0.3.1

Author SHA1 Message Date
lenn
7e047daf00 remove log file 2026-04-15 09:50:29 +08:00
lenn
842d4980d9 remove target dirs 2026-04-15 09:49:33 +08:00
lenn
04a0c3e46b remove unnecessary dotfiles 2026-04-15 09:46:19 +08:00
lenn
d4e1da6219 更新软件版本号 2026-04-15 09:44:54 +08:00
lenn
d1c9be56ec Merge branch 'main' of https://gitea.e-skin.top/E-Skin/JE-Skin 2026-04-15 09:28:09 +08:00
lenn
2e30fa388a 导出数据添加summary列 2026-04-15 09:20:56 +08:00
Lenn
4b2203e008 合并请求 #2
feat:增加点和数字切换,减小点最大尺寸,增加range配色方案
2026-04-09 01:18:56 +00:00
lenn
a3cefc3c79 feat:增加点和数字切换,减小点最大尺寸,增加range配色方案 2026-04-09 09:17:07 +08:00
Lenn
1c3a811154 合并请求 #1
feat:add game!
2026-04-06 17:45:38 +00:00
lennlouisgeek
aeb17f194c feat:add game! 2026-04-06 02:56:40 +08:00
103 changed files with 1762 additions and 1110 deletions

View File

@@ -1,62 +0,0 @@
# Details
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 8908 codes, 94 comments, 1250 blanks, all 10252 lines
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [.idea/modules.xml](/.idea/modules.xml) | XML | 8 | 0 | 0 | 8 |
| [.idea/tauri-demo.iml](/.idea/tauri-demo.iml) | XML | 11 | 0 | 0 | 11 |
| [README.md](/README.md) | Markdown | 34 | 0 | 20 | 54 |
| [flowus\_tools.json](/flowus_tools.json) | JSON | 1 | 0 | 1 | 2 |
| [frontend\_prompt.md](/frontend_prompt.md) | Markdown | 189 | 0 | 66 | 255 |
| [package-lock.json](/package-lock.json) | JSON | 1,957 | 0 | 1 | 1,958 |
| [package.json](/package.json) | JSON | 31 | 0 | 1 | 32 |
| [src-tauri/build.rs](/src-tauri/build.rs) | Rust | 3 | 0 | 1 | 4 |
| [src-tauri/capabilities/default.json](/src-tauri/capabilities/default.json) | JSON | 15 | 0 | 1 | 16 |
| [src-tauri/src/commands/mod.rs](/src-tauri/src/commands/mod.rs) | Rust | 2 | 0 | 1 | 3 |
| [src-tauri/src/commands/serial.rs](/src-tauri/src/commands/serial.rs) | Rust | 246 | 0 | 44 | 290 |
| [src-tauri/src/commands/window.rs](/src-tauri/src/commands/window.rs) | Rust | 27 | 0 | 6 | 33 |
| [src-tauri/src/lib.rs](/src-tauri/src/lib.rs) | Rust | 22 | 0 | 2 | 24 |
| [src-tauri/src/log.rs](/src-tauri/src/log.rs) | Rust | 34 | 0 | 2 | 36 |
| [src-tauri/src/main.rs](/src-tauri/src/main.rs) | Rust | 8 | 1 | 2 | 11 |
| [src-tauri/src/serial\_core/codec.rs](/src-tauri/src/serial_core/codec.rs) | Rust | 6 | 0 | 1 | 7 |
| [src-tauri/src/serial\_core/codecs/mod.rs](/src-tauri/src/serial_core/codecs/mod.rs) | Rust | 4 | 0 | 1 | 5 |
| [src-tauri/src/serial\_core/codecs/tactile\_a.rs](/src-tauri/src/serial_core/codecs/tactile_a.rs) | Rust | 67 | 0 | 17 | 84 |
| [src-tauri/src/serial\_core/codecs/test.rs](/src-tauri/src/serial_core/codecs/test.rs) | Rust | 213 | 7 | 40 | 260 |
| [src-tauri/src/serial\_core/error.rs](/src-tauri/src/serial_core/error.rs) | Rust | 47 | 0 | 6 | 53 |
| [src-tauri/src/serial\_core/frame.rs](/src-tauri/src/serial_core/frame.rs) | Rust | 46 | 3 | 9 | 58 |
| [src-tauri/src/serial\_core/mod.rs](/src-tauri/src/serial_core/mod.rs) | Rust | 22 | 0 | 7 | 29 |
| [src-tauri/src/serial\_core/model.rs](/src-tauri/src/serial_core/model.rs) | Rust | 377 | 57 | 67 | 501 |
| [src-tauri/src/serial\_core/record.rs](/src-tauri/src/serial_core/record.rs) | Rust | 50 | 4 | 11 | 65 |
| [src-tauri/src/serial\_core/serial.rs](/src-tauri/src/serial_core/serial.rs) | Rust | 73 | 0 | 8 | 81 |
| [src-tauri/src/serial\_core/utils.rs](/src-tauri/src/serial_core/utils.rs) | Rust | 26 | 0 | 6 | 32 |
| [src-tauri/tauri.conf.json](/src-tauri/tauri.conf.json) | JSON | 36 | 0 | 1 | 37 |
| [src/app.html](/src/app.html) | HTML | 13 | 0 | 1 | 14 |
| [src/lib/components/CenterStage.svelte](/src/lib/components/CenterStage.svelte) | Svelte | 691 | 0 | 96 | 787 |
| [src/lib/components/ConfigPanel.svelte](/src/lib/components/ConfigPanel.svelte) | Svelte | 398 | 0 | 63 | 461 |
| [src/lib/components/HudPanel.svelte](/src/lib/components/HudPanel.svelte) | Svelte | 861 | 0 | 110 | 971 |
| [src/lib/components/PressureMatrixViewer.svelte](/src/lib/components/PressureMatrixViewer.svelte) | Svelte | 558 | 0 | 97 | 655 |
| [src/lib/components/SignalChart.svelte](/src/lib/components/SignalChart.svelte) | Svelte | 382 | 0 | 71 | 453 |
| [src/lib/components/SummaryCurve.svelte](/src/lib/components/SummaryCurve.svelte) | Svelte | 497 | 0 | 88 | 585 |
| [src/lib/config/color-map.ts](/src/lib/config/color-map.ts) | TypeScript | 55 | 0 | 3 | 58 |
| [src/lib/styles/theme.css](/src/lib/styles/theme.css) | PostCSS | 43 | 1 | 7 | 51 |
| [src/lib/types/hud.ts](/src/lib/types/hud.ts) | TypeScript | 126 | 0 | 20 | 146 |
| [src/routes/+layout.svelte](/src/routes/+layout.svelte) | Svelte | 13 | 0 | 5 | 18 |
| [src/routes/+layout.ts](/src/routes/+layout.ts) | TypeScript | 1 | 4 | 1 | 6 |
| [src/routes/+page.svelte](/src/routes/+page.svelte) | Svelte | 1,286 | 0 | 176 | 1,462 |
| [static/svelte.svg](/static/svelte.svg) | XML | 1 | 0 | 0 | 1 |
| [static/tauri.svg](/static/tauri.svg) | XML | 6 | 0 | 1 | 7 |
| [static/vite.svg](/static/vite.svg) | XML | 1 | 0 | 0 | 1 |
| [svelte.config.js](/svelte.config.js) | JavaScript | 11 | 5 | 3 | 19 |
| [tauri-event.md](/tauri-event.md) | Markdown | 374 | 0 | 181 | 555 |
| [tsconfig.json](/tsconfig.json) | JSON with Comments | 14 | 5 | 1 | 20 |
| [vite.config.js](/vite.config.js) | JavaScript | 22 | 7 | 4 | 33 |
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,15 +0,0 @@
# Diff Details
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details

View File

@@ -1,2 +0,0 @@
"filename", "language", "", "comment", "blank", "total"
"Total", "-", , 0, 0, 0
1 filename language comment blank total
2 Total - 0 0 0

View File

@@ -1,19 +0,0 @@
# Diff Summary
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)

View File

@@ -1,22 +0,0 @@
Date : 2026-04-01 16:39:17
Directory : e:\Workspace\JE-Skin
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
Languages
+----------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+----------+------------+------------+------------+------------+------------+
+----------+------------+------------+------------+------------+------------+
Directories
+------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+------+------------+------------+------------+------------+------------+
+------+------------+------------+------------+------------+------------+
Files
+----------+----------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+----------+----------+------------+------------+------------+------------+
| Total | | 0 | 0 | 0 | 0 |
+----------+----------+------------+------------+------------+------------+

View File

@@ -1,49 +0,0 @@
"filename", "language", "JavaScript", "JSON", "Markdown", "JSON with Comments", "XML", "TypeScript", "Svelte", "Rust", "PostCSS", "HTML", "comment", "blank", "total"
"e:\Workspace\JE-Skin\.idea\modules.xml", "XML", 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8
"e:\Workspace\JE-Skin\.idea\tauri-demo.iml", "XML", 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 11
"e:\Workspace\JE-Skin\README.md", "Markdown", 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 20, 54
"e:\Workspace\JE-Skin\flowus_tools.json", "JSON", 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
"e:\Workspace\JE-Skin\frontend_prompt.md", "Markdown", 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 0, 66, 255
"e:\Workspace\JE-Skin\package-lock.json", "JSON", 0, 1957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1958
"e:\Workspace\JE-Skin\package.json", "JSON", 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32
"e:\Workspace\JE-Skin\src-tauri\build.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 4
"e:\Workspace\JE-Skin\src-tauri\capabilities\default.json", "JSON", 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16
"e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 3
"e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 44, 290
"e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 6, 33
"e:\Workspace\JE-Skin\src-tauri\src\lib.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 2, 24
"e:\Workspace\JE-Skin\src-tauri\src\log.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 2, 36
"e:\Workspace\JE-Skin\src-tauri\src\main.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 1, 2, 11
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 5
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 17, 84
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 7, 40, 260
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 6, 53
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 3, 9, 58
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 7, 29
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 377, 0, 0, 57, 67, 501
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 4, 11, 65
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 8, 81
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 6, 32
"e:\Workspace\JE-Skin\src-tauri\tauri.conf.json", "JSON", 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 37
"e:\Workspace\JE-Skin\src\app.html", "HTML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 1, 14
"e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 691, 0, 0, 0, 0, 96, 787
"e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 63, 461
"e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 861, 0, 0, 0, 0, 110, 971
"e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 97, 655
"e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 382, 0, 0, 0, 0, 71, 453
"e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, 88, 585
"e:\Workspace\JE-Skin\src\lib\config\color-map.ts", "TypeScript", 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 3, 58
"e:\Workspace\JE-Skin\src\lib\styles\theme.css", "PostCSS", 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 1, 7, 51
"e:\Workspace\JE-Skin\src\lib\types\hud.ts", "TypeScript", 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 20, 146
"e:\Workspace\JE-Skin\src\routes\+layout.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 5, 18
"e:\Workspace\JE-Skin\src\routes\+layout.ts", "TypeScript", 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 1, 6
"e:\Workspace\JE-Skin\src\routes\+page.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 1286, 0, 0, 0, 0, 176, 1462
"e:\Workspace\JE-Skin\static\svelte.svg", "XML", 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\static\tauri.svg", "XML", 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\static\vite.svg", "XML", 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\svelte.config.js", "JavaScript", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 19
"e:\Workspace\JE-Skin\tauri-event.md", "Markdown", 0, 0, 374, 0, 0, 0, 0, 0, 0, 0, 0, 181, 555
"e:\Workspace\JE-Skin\tsconfig.json", "JSON with Comments", 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 5, 1, 20
"e:\Workspace\JE-Skin\vite.config.js", "JavaScript", 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 33
"Total", "-", 33, 2040, 597, 14, 27, 182, 4686, 1273, 43, 13, 94, 1250, 10252
1 filename language JavaScript JSON Markdown JSON with Comments XML TypeScript Svelte Rust PostCSS HTML comment blank total
2 e:\Workspace\JE-Skin\.idea\modules.xml XML 0 0 0 0 8 0 0 0 0 0 0 0 8
3 e:\Workspace\JE-Skin\.idea\tauri-demo.iml XML 0 0 0 0 11 0 0 0 0 0 0 0 11
4 e:\Workspace\JE-Skin\README.md Markdown 0 0 34 0 0 0 0 0 0 0 0 20 54
5 e:\Workspace\JE-Skin\flowus_tools.json JSON 0 1 0 0 0 0 0 0 0 0 0 1 2
6 e:\Workspace\JE-Skin\frontend_prompt.md Markdown 0 0 189 0 0 0 0 0 0 0 0 66 255
7 e:\Workspace\JE-Skin\package-lock.json JSON 0 1957 0 0 0 0 0 0 0 0 0 1 1958
8 e:\Workspace\JE-Skin\package.json JSON 0 31 0 0 0 0 0 0 0 0 0 1 32
9 e:\Workspace\JE-Skin\src-tauri\build.rs Rust 0 0 0 0 0 0 0 3 0 0 0 1 4
10 e:\Workspace\JE-Skin\src-tauri\capabilities\default.json JSON 0 15 0 0 0 0 0 0 0 0 0 1 16
11 e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs Rust 0 0 0 0 0 0 0 2 0 0 0 1 3
12 e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs Rust 0 0 0 0 0 0 0 246 0 0 0 44 290
13 e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs Rust 0 0 0 0 0 0 0 27 0 0 0 6 33
14 e:\Workspace\JE-Skin\src-tauri\src\lib.rs Rust 0 0 0 0 0 0 0 22 0 0 0 2 24
15 e:\Workspace\JE-Skin\src-tauri\src\log.rs Rust 0 0 0 0 0 0 0 34 0 0 0 2 36
16 e:\Workspace\JE-Skin\src-tauri\src\main.rs Rust 0 0 0 0 0 0 0 8 0 0 1 2 11
17 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs Rust 0 0 0 0 0 0 0 6 0 0 0 1 7
18 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs Rust 0 0 0 0 0 0 0 4 0 0 0 1 5
19 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs Rust 0 0 0 0 0 0 0 67 0 0 0 17 84
20 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs Rust 0 0 0 0 0 0 0 213 0 0 7 40 260
21 e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs Rust 0 0 0 0 0 0 0 47 0 0 0 6 53
22 e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs Rust 0 0 0 0 0 0 0 46 0 0 3 9 58
23 e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs Rust 0 0 0 0 0 0 0 22 0 0 0 7 29
24 e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs Rust 0 0 0 0 0 0 0 377 0 0 57 67 501
25 e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs Rust 0 0 0 0 0 0 0 50 0 0 4 11 65
26 e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs Rust 0 0 0 0 0 0 0 73 0 0 0 8 81
27 e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs Rust 0 0 0 0 0 0 0 26 0 0 0 6 32
28 e:\Workspace\JE-Skin\src-tauri\tauri.conf.json JSON 0 36 0 0 0 0 0 0 0 0 0 1 37
29 e:\Workspace\JE-Skin\src\app.html HTML 0 0 0 0 0 0 0 0 0 13 0 1 14
30 e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte Svelte 0 0 0 0 0 0 691 0 0 0 0 96 787
31 e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte Svelte 0 0 0 0 0 0 398 0 0 0 0 63 461
32 e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte Svelte 0 0 0 0 0 0 861 0 0 0 0 110 971
33 e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte Svelte 0 0 0 0 0 0 558 0 0 0 0 97 655
34 e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte Svelte 0 0 0 0 0 0 382 0 0 0 0 71 453
35 e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte Svelte 0 0 0 0 0 0 497 0 0 0 0 88 585
36 e:\Workspace\JE-Skin\src\lib\config\color-map.ts TypeScript 0 0 0 0 0 55 0 0 0 0 0 3 58
37 e:\Workspace\JE-Skin\src\lib\styles\theme.css PostCSS 0 0 0 0 0 0 0 0 43 0 1 7 51
38 e:\Workspace\JE-Skin\src\lib\types\hud.ts TypeScript 0 0 0 0 0 126 0 0 0 0 0 20 146
39 e:\Workspace\JE-Skin\src\routes\+layout.svelte Svelte 0 0 0 0 0 0 13 0 0 0 0 5 18
40 e:\Workspace\JE-Skin\src\routes\+layout.ts TypeScript 0 0 0 0 0 1 0 0 0 0 4 1 6
41 e:\Workspace\JE-Skin\src\routes\+page.svelte Svelte 0 0 0 0 0 0 1286 0 0 0 0 176 1462
42 e:\Workspace\JE-Skin\static\svelte.svg XML 0 0 0 0 1 0 0 0 0 0 0 0 1
43 e:\Workspace\JE-Skin\static\tauri.svg XML 0 0 0 0 6 0 0 0 0 0 0 1 7
44 e:\Workspace\JE-Skin\static\vite.svg XML 0 0 0 0 1 0 0 0 0 0 0 0 1
45 e:\Workspace\JE-Skin\svelte.config.js JavaScript 11 0 0 0 0 0 0 0 0 0 5 3 19
46 e:\Workspace\JE-Skin\tauri-event.md Markdown 0 0 374 0 0 0 0 0 0 0 0 181 555
47 e:\Workspace\JE-Skin\tsconfig.json JSON with Comments 0 0 0 14 0 0 0 0 0 0 5 1 20
48 e:\Workspace\JE-Skin\vite.config.js JavaScript 22 0 0 0 0 0 0 0 0 0 7 4 33
49 Total - 33 2040 597 14 27 182 4686 1273 43 13 94 1250 10252

File diff suppressed because one or more lines are too long

View File

@@ -1,50 +0,0 @@
# Summary
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 8908 codes, 94 comments, 1250 blanks, all 10252 lines
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,273 | 72 | 231 | 1,576 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 47 | 8,908 | 94 | 1,250 | 10,252 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,324 | 72 | 233 | 1,629 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\\src | 17 | 1,270 | 72 | 230 | 1,572 |
| src-tauri\\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\\src\\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\\src\\serial_core | 11 | 931 | 71 | 173 | 1,175 |
| src-tauri\\src\\serial_core (Files) | 8 | 647 | 64 | 115 | 826 |
| src-tauri\\src\\serial_core\\codecs | 3 | 284 | 7 | 58 | 349 |
| src\\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\\lib\\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\\lib\\config | 1 | 55 | 0 | 3 | 58 |
| src\\lib\\styles | 1 | 43 | 1 | 7 | 51 |
| src\\lib\\types | 1 | 126 | 0 | 20 | 146 |
| src\\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,100 +0,0 @@
Date : 2026-04-01 16:39:17
Directory : e:\Workspace\JE-Skin
Total : 47 files, 8908 codes, 94 comments, 1250 blanks, all 10252 lines
Languages
+--------------------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+--------------------+------------+------------+------------+------------+------------+
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,273 | 72 | 231 | 1,576 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
+--------------------+------------+------------+------------+------------+------------+
Directories
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 47 | 8,908 | 94 | 1,250 | 10,252 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,324 | 72 | 233 | 1,629 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\src | 17 | 1,270 | 72 | 230 | 1,572 |
| src-tauri\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\src\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\src\serial_core | 11 | 931 | 71 | 173 | 1,175 |
| src-tauri\src\serial_core (Files) | 8 | 647 | 64 | 115 | 826 |
| src-tauri\src\serial_core\codecs | 3 | 284 | 7 | 58 | 349 |
| src\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\lib\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\lib\config | 1 | 55 | 0 | 3 | 58 |
| src\lib\styles | 1 | 43 | 1 | 7 | 51 |
| src\lib\types | 1 | 126 | 0 | 20 | 146 |
| src\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| e:\Workspace\JE-Skin\.idea\modules.xml | XML | 8 | 0 | 0 | 8 |
| e:\Workspace\JE-Skin\.idea\tauri-demo.iml | XML | 11 | 0 | 0 | 11 |
| e:\Workspace\JE-Skin\README.md | Markdown | 34 | 0 | 20 | 54 |
| e:\Workspace\JE-Skin\flowus_tools.json | JSON | 1 | 0 | 1 | 2 |
| e:\Workspace\JE-Skin\frontend_prompt.md | Markdown | 189 | 0 | 66 | 255 |
| e:\Workspace\JE-Skin\package-lock.json | JSON | 1,957 | 0 | 1 | 1,958 |
| e:\Workspace\JE-Skin\package.json | JSON | 31 | 0 | 1 | 32 |
| e:\Workspace\JE-Skin\src-tauri\build.rs | Rust | 3 | 0 | 1 | 4 |
| e:\Workspace\JE-Skin\src-tauri\capabilities\default.json | JSON | 15 | 0 | 1 | 16 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs | Rust | 2 | 0 | 1 | 3 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs | Rust | 246 | 0 | 44 | 290 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs | Rust | 27 | 0 | 6 | 33 |
| e:\Workspace\JE-Skin\src-tauri\src\lib.rs | Rust | 22 | 0 | 2 | 24 |
| e:\Workspace\JE-Skin\src-tauri\src\log.rs | Rust | 34 | 0 | 2 | 36 |
| e:\Workspace\JE-Skin\src-tauri\src\main.rs | Rust | 8 | 1 | 2 | 11 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs | Rust | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs | Rust | 4 | 0 | 1 | 5 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs | Rust | 67 | 0 | 17 | 84 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs | Rust | 213 | 7 | 40 | 260 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs | Rust | 47 | 0 | 6 | 53 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs | Rust | 46 | 3 | 9 | 58 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs | Rust | 22 | 0 | 7 | 29 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs | Rust | 377 | 57 | 67 | 501 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs | Rust | 50 | 4 | 11 | 65 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs | Rust | 73 | 0 | 8 | 81 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs | Rust | 26 | 0 | 6 | 32 |
| e:\Workspace\JE-Skin\src-tauri\tauri.conf.json | JSON | 36 | 0 | 1 | 37 |
| e:\Workspace\JE-Skin\src\app.html | HTML | 13 | 0 | 1 | 14 |
| e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte | Svelte | 691 | 0 | 96 | 787 |
| e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte | Svelte | 398 | 0 | 63 | 461 |
| e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte | Svelte | 861 | 0 | 110 | 971 |
| e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte | Svelte | 558 | 0 | 97 | 655 |
| e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte | Svelte | 382 | 0 | 71 | 453 |
| e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte | Svelte | 497 | 0 | 88 | 585 |
| e:\Workspace\JE-Skin\src\lib\config\color-map.ts | TypeScript | 55 | 0 | 3 | 58 |
| e:\Workspace\JE-Skin\src\lib\styles\theme.css | PostCSS | 43 | 1 | 7 | 51 |
| e:\Workspace\JE-Skin\src\lib\types\hud.ts | TypeScript | 126 | 0 | 20 | 146 |
| e:\Workspace\JE-Skin\src\routes\+layout.svelte | Svelte | 13 | 0 | 5 | 18 |
| e:\Workspace\JE-Skin\src\routes\+layout.ts | TypeScript | 1 | 4 | 1 | 6 |
| e:\Workspace\JE-Skin\src\routes\+page.svelte | Svelte | 1,286 | 0 | 176 | 1,462 |
| e:\Workspace\JE-Skin\static\svelte.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\static\tauri.svg | XML | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\static\vite.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\svelte.config.js | JavaScript | 11 | 5 | 3 | 19 |
| e:\Workspace\JE-Skin\tauri-event.md | Markdown | 374 | 0 | 181 | 555 |
| e:\Workspace\JE-Skin\tsconfig.json | JSON with Comments | 14 | 5 | 1 | 20 |
| e:\Workspace\JE-Skin\vite.config.js | JavaScript | 22 | 7 | 4 | 33 |
| Total | | 8,908 | 94 | 1,250 | 10,252 |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+

View File

@@ -1,62 +0,0 @@
# Details
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 9155 codes, 95 comments, 1279 blanks, all 10529 lines
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [.idea/modules.xml](/.idea/modules.xml) | XML | 8 | 0 | 0 | 8 |
| [.idea/tauri-demo.iml](/.idea/tauri-demo.iml) | XML | 11 | 0 | 0 | 11 |
| [README.md](/README.md) | Markdown | 34 | 0 | 20 | 54 |
| [flowus\_tools.json](/flowus_tools.json) | JSON | 1 | 0 | 1 | 2 |
| [frontend\_prompt.md](/frontend_prompt.md) | Markdown | 189 | 0 | 66 | 255 |
| [package-lock.json](/package-lock.json) | JSON | 1,957 | 0 | 1 | 1,958 |
| [package.json](/package.json) | JSON | 31 | 0 | 1 | 32 |
| [src-tauri/build.rs](/src-tauri/build.rs) | Rust | 3 | 0 | 1 | 4 |
| [src-tauri/capabilities/default.json](/src-tauri/capabilities/default.json) | JSON | 15 | 0 | 1 | 16 |
| [src-tauri/src/commands/mod.rs](/src-tauri/src/commands/mod.rs) | Rust | 2 | 0 | 1 | 3 |
| [src-tauri/src/commands/serial.rs](/src-tauri/src/commands/serial.rs) | Rust | 246 | 0 | 44 | 290 |
| [src-tauri/src/commands/window.rs](/src-tauri/src/commands/window.rs) | Rust | 27 | 0 | 6 | 33 |
| [src-tauri/src/lib.rs](/src-tauri/src/lib.rs) | Rust | 22 | 0 | 2 | 24 |
| [src-tauri/src/log.rs](/src-tauri/src/log.rs) | Rust | 34 | 0 | 2 | 36 |
| [src-tauri/src/main.rs](/src-tauri/src/main.rs) | Rust | 8 | 1 | 2 | 11 |
| [src-tauri/src/serial\_core/codec.rs](/src-tauri/src/serial_core/codec.rs) | Rust | 6 | 0 | 1 | 7 |
| [src-tauri/src/serial\_core/codecs/mod.rs](/src-tauri/src/serial_core/codecs/mod.rs) | Rust | 4 | 0 | 1 | 5 |
| [src-tauri/src/serial\_core/codecs/tactile\_a.rs](/src-tauri/src/serial_core/codecs/tactile_a.rs) | Rust | 220 | 0 | 28 | 248 |
| [src-tauri/src/serial\_core/codecs/test.rs](/src-tauri/src/serial_core/codecs/test.rs) | Rust | 215 | 8 | 38 | 261 |
| [src-tauri/src/serial\_core/error.rs](/src-tauri/src/serial_core/error.rs) | Rust | 49 | 0 | 6 | 55 |
| [src-tauri/src/serial\_core/frame.rs](/src-tauri/src/serial_core/frame.rs) | Rust | 47 | 3 | 8 | 58 |
| [src-tauri/src/serial\_core/mod.rs](/src-tauri/src/serial_core/mod.rs) | Rust | 22 | 0 | 7 | 29 |
| [src-tauri/src/serial\_core/model.rs](/src-tauri/src/serial_core/model.rs) | Rust | 377 | 57 | 67 | 501 |
| [src-tauri/src/serial\_core/record.rs](/src-tauri/src/serial_core/record.rs) | Rust | 50 | 4 | 11 | 65 |
| [src-tauri/src/serial\_core/serial.rs](/src-tauri/src/serial_core/serial.rs) | Rust | 141 | 0 | 22 | 163 |
| [src-tauri/src/serial\_core/utils.rs](/src-tauri/src/serial_core/utils.rs) | Rust | 47 | 0 | 13 | 60 |
| [src-tauri/tauri.conf.json](/src-tauri/tauri.conf.json) | JSON | 36 | 0 | 1 | 37 |
| [src/app.html](/src/app.html) | HTML | 13 | 0 | 1 | 14 |
| [src/lib/components/CenterStage.svelte](/src/lib/components/CenterStage.svelte) | Svelte | 691 | 0 | 96 | 787 |
| [src/lib/components/ConfigPanel.svelte](/src/lib/components/ConfigPanel.svelte) | Svelte | 398 | 0 | 63 | 461 |
| [src/lib/components/HudPanel.svelte](/src/lib/components/HudPanel.svelte) | Svelte | 861 | 0 | 110 | 971 |
| [src/lib/components/PressureMatrixViewer.svelte](/src/lib/components/PressureMatrixViewer.svelte) | Svelte | 558 | 0 | 97 | 655 |
| [src/lib/components/SignalChart.svelte](/src/lib/components/SignalChart.svelte) | Svelte | 382 | 0 | 71 | 453 |
| [src/lib/components/SummaryCurve.svelte](/src/lib/components/SummaryCurve.svelte) | Svelte | 497 | 0 | 88 | 585 |
| [src/lib/config/color-map.ts](/src/lib/config/color-map.ts) | TypeScript | 55 | 0 | 3 | 58 |
| [src/lib/styles/theme.css](/src/lib/styles/theme.css) | PostCSS | 43 | 1 | 7 | 51 |
| [src/lib/types/hud.ts](/src/lib/types/hud.ts) | TypeScript | 126 | 0 | 20 | 146 |
| [src/routes/+layout.svelte](/src/routes/+layout.svelte) | Svelte | 13 | 0 | 5 | 18 |
| [src/routes/+layout.ts](/src/routes/+layout.ts) | TypeScript | 1 | 4 | 1 | 6 |
| [src/routes/+page.svelte](/src/routes/+page.svelte) | Svelte | 1,286 | 0 | 176 | 1,462 |
| [static/svelte.svg](/static/svelte.svg) | XML | 1 | 0 | 0 | 1 |
| [static/tauri.svg](/static/tauri.svg) | XML | 6 | 0 | 1 | 7 |
| [static/vite.svg](/static/vite.svg) | XML | 1 | 0 | 0 | 1 |
| [svelte.config.js](/svelte.config.js) | JavaScript | 11 | 5 | 3 | 19 |
| [tauri-event.md](/tauri-event.md) | Markdown | 374 | 0 | 181 | 555 |
| [tsconfig.json](/tsconfig.json) | JSON with Comments | 14 | 5 | 1 | 20 |
| [vite.config.js](/vite.config.js) | JavaScript | 22 | 7 | 4 | 33 |
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,21 +0,0 @@
# Diff Details
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 6 files, 247 codes, 1 comments, 29 blanks, all 277 lines
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [src-tauri/src/serial\_core/codecs/tactile\_a.rs](/src-tauri/src/serial_core/codecs/tactile_a.rs) | Rust | 153 | 0 | 11 | 164 |
| [src-tauri/src/serial\_core/codecs/test.rs](/src-tauri/src/serial_core/codecs/test.rs) | Rust | 2 | 1 | -2 | 1 |
| [src-tauri/src/serial\_core/error.rs](/src-tauri/src/serial_core/error.rs) | Rust | 2 | 0 | 0 | 2 |
| [src-tauri/src/serial\_core/frame.rs](/src-tauri/src/serial_core/frame.rs) | Rust | 1 | 0 | -1 | 0 |
| [src-tauri/src/serial\_core/serial.rs](/src-tauri/src/serial_core/serial.rs) | Rust | 68 | 0 | 14 | 82 |
| [src-tauri/src/serial\_core/utils.rs](/src-tauri/src/serial_core/utils.rs) | Rust | 21 | 0 | 7 | 28 |
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details

View File

@@ -1,8 +0,0 @@
"filename", "language", "Rust", "comment", "blank", "total"
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs", "Rust", 153, 0, 11, 164
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs", "Rust", 2, 1, -2, 1
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs", "Rust", 2, 0, 0, 2
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs", "Rust", 1, 0, -1, 0
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs", "Rust", 68, 0, 14, 82
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs", "Rust", 21, 0, 7, 28
"Total", "-", 247, 1, 29, 277
1 filename language Rust comment blank total
2 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs Rust 153 0 11 164
3 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs Rust 2 1 -2 1
4 e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs Rust 2 0 0 2
5 e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs Rust 1 0 -1 0
6 e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs Rust 68 0 14 82
7 e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs Rust 21 0 7 28
8 Total - 247 1 29 277

View File

@@ -1,26 +0,0 @@
# Diff Summary
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 6 files, 247 codes, 1 comments, 29 blanks, all 277 lines
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Rust | 6 | 247 | 1 | 29 | 277 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 6 | 247 | 1 | 29 | 277 |
| src-tauri | 6 | 247 | 1 | 29 | 277 |
| src-tauri\\src | 6 | 247 | 1 | 29 | 277 |
| src-tauri\\src\\serial_core | 6 | 247 | 1 | 29 | 277 |
| src-tauri\\src\\serial_core (Files) | 4 | 92 | 0 | 20 | 112 |
| src-tauri\\src\\serial_core\\codecs | 2 | 155 | 1 | 9 | 165 |
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)

View File

@@ -1,35 +0,0 @@
Date : 2026-04-02 14:42:07
Directory : e:\Workspace\JE-Skin
Total : 6 files, 247 codes, 1 comments, 29 blanks, all 277 lines
Languages
+----------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+----------+------------+------------+------------+------------+------------+
| Rust | 6 | 247 | 1 | 29 | 277 |
+----------+------------+------------+------------+------------+------------+
Directories
+--------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+--------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 6 | 247 | 1 | 29 | 277 |
| src-tauri | 6 | 247 | 1 | 29 | 277 |
| src-tauri\src | 6 | 247 | 1 | 29 | 277 |
| src-tauri\src\serial_core | 6 | 247 | 1 | 29 | 277 |
| src-tauri\src\serial_core (Files) | 4 | 92 | 0 | 20 | 112 |
| src-tauri\src\serial_core\codecs | 2 | 155 | 1 | 9 | 165 |
+--------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+--------------------------------------------------------------------------+----------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+--------------------------------------------------------------------------+----------+------------+------------+------------+------------+
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs | Rust | 153 | 0 | 11 | 164 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs | Rust | 2 | 1 | -2 | 1 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs | Rust | 2 | 0 | 0 | 2 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs | Rust | 1 | 0 | -1 | 0 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs | Rust | 68 | 0 | 14 | 82 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs | Rust | 21 | 0 | 7 | 28 |
| Total | | 247 | 1 | 29 | 277 |
+--------------------------------------------------------------------------+----------+------------+------------+------------+------------+

View File

@@ -1,49 +0,0 @@
"filename", "language", "Markdown", "JSON with Comments", "JSON", "XML", "JavaScript", "HTML", "Rust", "TypeScript", "Svelte", "PostCSS", "comment", "blank", "total"
"e:\Workspace\JE-Skin\.idea\modules.xml", "XML", 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8
"e:\Workspace\JE-Skin\.idea\tauri-demo.iml", "XML", 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 11
"e:\Workspace\JE-Skin\README.md", "Markdown", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 54
"e:\Workspace\JE-Skin\flowus_tools.json", "JSON", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
"e:\Workspace\JE-Skin\frontend_prompt.md", "Markdown", 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 255
"e:\Workspace\JE-Skin\package-lock.json", "JSON", 0, 0, 1957, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1958
"e:\Workspace\JE-Skin\package.json", "JSON", 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32
"e:\Workspace\JE-Skin\src-tauri\build.rs", "Rust", 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 4
"e:\Workspace\JE-Skin\src-tauri\capabilities\default.json", "JSON", 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16
"e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 3
"e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 44, 290
"e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs", "Rust", 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 6, 33
"e:\Workspace\JE-Skin\src-tauri\src\lib.rs", "Rust", 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 2, 24
"e:\Workspace\JE-Skin\src-tauri\src\log.rs", "Rust", 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 2, 36
"e:\Workspace\JE-Skin\src-tauri\src\main.rs", "Rust", 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 2, 11
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs", "Rust", 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 5
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs", "Rust", 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 28, 248
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs", "Rust", 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 8, 38, 261
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs", "Rust", 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 6, 55
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs", "Rust", 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 3, 8, 58
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 7, 29
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs", "Rust", 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 57, 67, 501
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs", "Rust", 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 4, 11, 65
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 22, 163
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs", "Rust", 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 13, 60
"e:\Workspace\JE-Skin\src-tauri\tauri.conf.json", "JSON", 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 1, 37
"e:\Workspace\JE-Skin\src\app.html", "HTML", 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 1, 14
"e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 691, 0, 0, 96, 787
"e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 63, 461
"e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 861, 0, 0, 110, 971
"e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 97, 655
"e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 382, 0, 0, 71, 453
"e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 497, 0, 0, 88, 585
"e:\Workspace\JE-Skin\src\lib\config\color-map.ts", "TypeScript", 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 3, 58
"e:\Workspace\JE-Skin\src\lib\styles\theme.css", "PostCSS", 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 7, 51
"e:\Workspace\JE-Skin\src\lib\types\hud.ts", "TypeScript", 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 20, 146
"e:\Workspace\JE-Skin\src\routes\+layout.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 5, 18
"e:\Workspace\JE-Skin\src\routes\+layout.ts", "TypeScript", 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 1, 6
"e:\Workspace\JE-Skin\src\routes\+page.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 1286, 0, 0, 176, 1462
"e:\Workspace\JE-Skin\static\svelte.svg", "XML", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\static\tauri.svg", "XML", 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\static\vite.svg", "XML", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\svelte.config.js", "JavaScript", 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 5, 3, 19
"e:\Workspace\JE-Skin\tauri-event.md", "Markdown", 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 555
"e:\Workspace\JE-Skin\tsconfig.json", "JSON with Comments", 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 20
"e:\Workspace\JE-Skin\vite.config.js", "JavaScript", 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 7, 4, 33
"Total", "-", 597, 14, 2040, 27, 33, 13, 1520, 182, 4686, 43, 95, 1279, 10529
1 filename language Markdown JSON with Comments JSON XML JavaScript HTML Rust TypeScript Svelte PostCSS comment blank total
2 e:\Workspace\JE-Skin\.idea\modules.xml XML 0 0 0 8 0 0 0 0 0 0 0 0 8
3 e:\Workspace\JE-Skin\.idea\tauri-demo.iml XML 0 0 0 11 0 0 0 0 0 0 0 0 11
4 e:\Workspace\JE-Skin\README.md Markdown 34 0 0 0 0 0 0 0 0 0 0 20 54
5 e:\Workspace\JE-Skin\flowus_tools.json JSON 0 0 1 0 0 0 0 0 0 0 0 1 2
6 e:\Workspace\JE-Skin\frontend_prompt.md Markdown 189 0 0 0 0 0 0 0 0 0 0 66 255
7 e:\Workspace\JE-Skin\package-lock.json JSON 0 0 1957 0 0 0 0 0 0 0 0 1 1958
8 e:\Workspace\JE-Skin\package.json JSON 0 0 31 0 0 0 0 0 0 0 0 1 32
9 e:\Workspace\JE-Skin\src-tauri\build.rs Rust 0 0 0 0 0 0 3 0 0 0 0 1 4
10 e:\Workspace\JE-Skin\src-tauri\capabilities\default.json JSON 0 0 15 0 0 0 0 0 0 0 0 1 16
11 e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs Rust 0 0 0 0 0 0 2 0 0 0 0 1 3
12 e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs Rust 0 0 0 0 0 0 246 0 0 0 0 44 290
13 e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs Rust 0 0 0 0 0 0 27 0 0 0 0 6 33
14 e:\Workspace\JE-Skin\src-tauri\src\lib.rs Rust 0 0 0 0 0 0 22 0 0 0 0 2 24
15 e:\Workspace\JE-Skin\src-tauri\src\log.rs Rust 0 0 0 0 0 0 34 0 0 0 0 2 36
16 e:\Workspace\JE-Skin\src-tauri\src\main.rs Rust 0 0 0 0 0 0 8 0 0 0 1 2 11
17 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs Rust 0 0 0 0 0 0 6 0 0 0 0 1 7
18 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs Rust 0 0 0 0 0 0 4 0 0 0 0 1 5
19 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs Rust 0 0 0 0 0 0 220 0 0 0 0 28 248
20 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs Rust 0 0 0 0 0 0 215 0 0 0 8 38 261
21 e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs Rust 0 0 0 0 0 0 49 0 0 0 0 6 55
22 e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs Rust 0 0 0 0 0 0 47 0 0 0 3 8 58
23 e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs Rust 0 0 0 0 0 0 22 0 0 0 0 7 29
24 e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs Rust 0 0 0 0 0 0 377 0 0 0 57 67 501
25 e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs Rust 0 0 0 0 0 0 50 0 0 0 4 11 65
26 e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs Rust 0 0 0 0 0 0 141 0 0 0 0 22 163
27 e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs Rust 0 0 0 0 0 0 47 0 0 0 0 13 60
28 e:\Workspace\JE-Skin\src-tauri\tauri.conf.json JSON 0 0 36 0 0 0 0 0 0 0 0 1 37
29 e:\Workspace\JE-Skin\src\app.html HTML 0 0 0 0 0 13 0 0 0 0 0 1 14
30 e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte Svelte 0 0 0 0 0 0 0 0 691 0 0 96 787
31 e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte Svelte 0 0 0 0 0 0 0 0 398 0 0 63 461
32 e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte Svelte 0 0 0 0 0 0 0 0 861 0 0 110 971
33 e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte Svelte 0 0 0 0 0 0 0 0 558 0 0 97 655
34 e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte Svelte 0 0 0 0 0 0 0 0 382 0 0 71 453
35 e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte Svelte 0 0 0 0 0 0 0 0 497 0 0 88 585
36 e:\Workspace\JE-Skin\src\lib\config\color-map.ts TypeScript 0 0 0 0 0 0 0 55 0 0 0 3 58
37 e:\Workspace\JE-Skin\src\lib\styles\theme.css PostCSS 0 0 0 0 0 0 0 0 0 43 1 7 51
38 e:\Workspace\JE-Skin\src\lib\types\hud.ts TypeScript 0 0 0 0 0 0 0 126 0 0 0 20 146
39 e:\Workspace\JE-Skin\src\routes\+layout.svelte Svelte 0 0 0 0 0 0 0 0 13 0 0 5 18
40 e:\Workspace\JE-Skin\src\routes\+layout.ts TypeScript 0 0 0 0 0 0 0 1 0 0 4 1 6
41 e:\Workspace\JE-Skin\src\routes\+page.svelte Svelte 0 0 0 0 0 0 0 0 1286 0 0 176 1462
42 e:\Workspace\JE-Skin\static\svelte.svg XML 0 0 0 1 0 0 0 0 0 0 0 0 1
43 e:\Workspace\JE-Skin\static\tauri.svg XML 0 0 0 6 0 0 0 0 0 0 0 1 7
44 e:\Workspace\JE-Skin\static\vite.svg XML 0 0 0 1 0 0 0 0 0 0 0 0 1
45 e:\Workspace\JE-Skin\svelte.config.js JavaScript 0 0 0 0 11 0 0 0 0 0 5 3 19
46 e:\Workspace\JE-Skin\tauri-event.md Markdown 374 0 0 0 0 0 0 0 0 0 0 181 555
47 e:\Workspace\JE-Skin\tsconfig.json JSON with Comments 0 14 0 0 0 0 0 0 0 0 5 1 20
48 e:\Workspace\JE-Skin\vite.config.js JavaScript 0 0 0 0 22 0 0 0 0 0 7 4 33
49 Total - 597 14 2040 27 33 13 1520 182 4686 43 95 1279 10529

File diff suppressed because one or more lines are too long

View File

@@ -1,50 +0,0 @@
# Summary
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 9155 codes, 95 comments, 1279 blanks, all 10529 lines
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,520 | 73 | 260 | 1,853 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 47 | 9,155 | 95 | 1,279 | 10,529 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,571 | 73 | 262 | 1,906 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\\src | 17 | 1,517 | 73 | 259 | 1,849 |
| src-tauri\\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\\src\\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\\src\\serial_core | 11 | 1,178 | 72 | 202 | 1,452 |
| src-tauri\\src\\serial_core (Files) | 8 | 739 | 64 | 135 | 938 |
| src-tauri\\src\\serial_core\\codecs | 3 | 439 | 8 | 67 | 514 |
| src\\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\\lib\\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\\lib\\config | 1 | 55 | 0 | 3 | 58 |
| src\\lib\\styles | 1 | 43 | 1 | 7 | 51 |
| src\\lib\\types | 1 | 126 | 0 | 20 | 146 |
| src\\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,100 +0,0 @@
Date : 2026-04-02 14:42:07
Directory : e:\Workspace\JE-Skin
Total : 47 files, 9155 codes, 95 comments, 1279 blanks, all 10529 lines
Languages
+--------------------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+--------------------+------------+------------+------------+------------+------------+
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,520 | 73 | 260 | 1,853 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
+--------------------+------------+------------+------------+------------+------------+
Directories
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 47 | 9,155 | 95 | 1,279 | 10,529 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,571 | 73 | 262 | 1,906 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\src | 17 | 1,517 | 73 | 259 | 1,849 |
| src-tauri\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\src\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\src\serial_core | 11 | 1,178 | 72 | 202 | 1,452 |
| src-tauri\src\serial_core (Files) | 8 | 739 | 64 | 135 | 938 |
| src-tauri\src\serial_core\codecs | 3 | 439 | 8 | 67 | 514 |
| src\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\lib\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\lib\config | 1 | 55 | 0 | 3 | 58 |
| src\lib\styles | 1 | 43 | 1 | 7 | 51 |
| src\lib\types | 1 | 126 | 0 | 20 | 146 |
| src\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| e:\Workspace\JE-Skin\.idea\modules.xml | XML | 8 | 0 | 0 | 8 |
| e:\Workspace\JE-Skin\.idea\tauri-demo.iml | XML | 11 | 0 | 0 | 11 |
| e:\Workspace\JE-Skin\README.md | Markdown | 34 | 0 | 20 | 54 |
| e:\Workspace\JE-Skin\flowus_tools.json | JSON | 1 | 0 | 1 | 2 |
| e:\Workspace\JE-Skin\frontend_prompt.md | Markdown | 189 | 0 | 66 | 255 |
| e:\Workspace\JE-Skin\package-lock.json | JSON | 1,957 | 0 | 1 | 1,958 |
| e:\Workspace\JE-Skin\package.json | JSON | 31 | 0 | 1 | 32 |
| e:\Workspace\JE-Skin\src-tauri\build.rs | Rust | 3 | 0 | 1 | 4 |
| e:\Workspace\JE-Skin\src-tauri\capabilities\default.json | JSON | 15 | 0 | 1 | 16 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs | Rust | 2 | 0 | 1 | 3 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs | Rust | 246 | 0 | 44 | 290 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs | Rust | 27 | 0 | 6 | 33 |
| e:\Workspace\JE-Skin\src-tauri\src\lib.rs | Rust | 22 | 0 | 2 | 24 |
| e:\Workspace\JE-Skin\src-tauri\src\log.rs | Rust | 34 | 0 | 2 | 36 |
| e:\Workspace\JE-Skin\src-tauri\src\main.rs | Rust | 8 | 1 | 2 | 11 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs | Rust | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs | Rust | 4 | 0 | 1 | 5 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs | Rust | 220 | 0 | 28 | 248 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs | Rust | 215 | 8 | 38 | 261 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs | Rust | 49 | 0 | 6 | 55 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs | Rust | 47 | 3 | 8 | 58 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs | Rust | 22 | 0 | 7 | 29 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs | Rust | 377 | 57 | 67 | 501 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs | Rust | 50 | 4 | 11 | 65 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs | Rust | 141 | 0 | 22 | 163 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs | Rust | 47 | 0 | 13 | 60 |
| e:\Workspace\JE-Skin\src-tauri\tauri.conf.json | JSON | 36 | 0 | 1 | 37 |
| e:\Workspace\JE-Skin\src\app.html | HTML | 13 | 0 | 1 | 14 |
| e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte | Svelte | 691 | 0 | 96 | 787 |
| e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte | Svelte | 398 | 0 | 63 | 461 |
| e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte | Svelte | 861 | 0 | 110 | 971 |
| e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte | Svelte | 558 | 0 | 97 | 655 |
| e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte | Svelte | 382 | 0 | 71 | 453 |
| e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte | Svelte | 497 | 0 | 88 | 585 |
| e:\Workspace\JE-Skin\src\lib\config\color-map.ts | TypeScript | 55 | 0 | 3 | 58 |
| e:\Workspace\JE-Skin\src\lib\styles\theme.css | PostCSS | 43 | 1 | 7 | 51 |
| e:\Workspace\JE-Skin\src\lib\types\hud.ts | TypeScript | 126 | 0 | 20 | 146 |
| e:\Workspace\JE-Skin\src\routes\+layout.svelte | Svelte | 13 | 0 | 5 | 18 |
| e:\Workspace\JE-Skin\src\routes\+layout.ts | TypeScript | 1 | 4 | 1 | 6 |
| e:\Workspace\JE-Skin\src\routes\+page.svelte | Svelte | 1,286 | 0 | 176 | 1,462 |
| e:\Workspace\JE-Skin\static\svelte.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\static\tauri.svg | XML | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\static\vite.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\svelte.config.js | JavaScript | 11 | 5 | 3 | 19 |
| e:\Workspace\JE-Skin\tauri-event.md | Markdown | 374 | 0 | 181 | 555 |
| e:\Workspace\JE-Skin\tsconfig.json | JSON with Comments | 14 | 5 | 1 | 20 |
| e:\Workspace\JE-Skin\vite.config.js | JavaScript | 22 | 7 | 4 | 33 |
| Total | | 9,155 | 95 | 1,279 | 10,529 |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+

10
.idea/.gitignore generated vendored
View File

@@ -1,10 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tauri-demo.iml" filepath="$PROJECT_DIR$/.idea/tauri-demo.iml" />
</modules>
</component>
</project>

11
.idea/tauri-demo.iml generated
View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src-tauri/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/src-tauri/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,7 +0,0 @@
{
"recommendations": [
"svelte.svelte-vscode",
"tauri-apps.tauri-vscode",
"rust-lang.rust-analyzer"
]
}

View File

@@ -1,3 +0,0 @@
{
"svelte.enable-ts-plugin": true
}

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "JE-Skin", "name": "JE-Skin",
"version": "0.1.0", "version": "0.3.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "JE-Skin", "name": "JE-Skin",
"version": "0.1.0", "version": "0.3.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2", "@tauri-apps/api": "^2",

View File

@@ -1,6 +1,6 @@
{ {
"name": "JE-Skin", "name": "JE-Skin",
"version": "0.1.0", "version": "0.3.1",
"description": "", "description": "",
"type": "module", "type": "module",
"scripts": { "scripts": {
@@ -9,7 +9,11 @@
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"tauri": "tauri" "tauri": "tauri",
"version:set": "node scripts/bump-version.mjs",
"version:patch": "node scripts/bump-version.mjs patch",
"version:minor": "node scripts/bump-version.mjs minor",
"version:major": "node scripts/bump-version.mjs major"
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

2
src-tauri/Cargo.lock generated
View File

@@ -4,7 +4,7 @@ version = 4
[[package]] [[package]]
name = "JE-Skin" name = "JE-Skin"
version = "0.1.0" version = "0.3.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "JE-Skin" name = "JE-Skin"
version = "0.1.0" version = "0.3.1"
description = "A Tauri App" description = "A Tauri App"
authors = ["you"] authors = ["you"]
edition = "2021" edition = "2021"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src-tauri/icons/16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

BIN
src-tauri/icons/192x192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
src-tauri/icons/256x256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src-tauri/icons/512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
src-tauri/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<background android:drawable="@color/ic_launcher_background"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#fff</color>
</resources>

BIN
src-tauri/icons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src-tauri/icons/icon.icns Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -77,6 +77,40 @@ pub struct SerialConnectionState {
last_record: Mutex<Option<SharedTactileRecording>> last_record: Mutex<Option<SharedTactileRecording>>
} }
pub async fn shutdown_active_session(
state: &SerialConnectionState,
) -> Result<Option<(String, SharedTactileRecording)>, SerialError> {
let session = {
let mut guard = state.session.lock().map_err(|_| SerialError::StateError)?;
guard.take()
};
let Some(SerialSession {
port,
cancel,
task,
current_record,
}) = session else {
return Ok(None);
};
cancel.cancel();
let _ = task.await;
let frame_count = current_record
.lock()
.map(|record| record.frames.len())
.unwrap_or(0);
info!("last_record has {} frames", frame_count);
if let Ok(mut last_record) = state.last_record.lock() {
*last_record = Some(current_record.clone());
}
Ok(Some((port, current_record)))
}
#[tauri::command] #[tauri::command]
pub fn serial_enum() -> Result<Vec<String>, SerialError> { pub fn serial_enum() -> Result<Vec<String>, SerialError> {
let ports = available_ports() let ports = available_ports()
@@ -190,17 +224,7 @@ pub async fn serial_connect(
pub async fn serial_disconnect( pub async fn serial_disconnect(
state: State<'_, SerialConnectionState>, state: State<'_, SerialConnectionState>,
) -> Result<SerialConnectResponse, SerialError> { ) -> Result<SerialConnectResponse, SerialError> {
let session = { let Some((port, _current_record)) = shutdown_active_session(&state).await?
let mut guard = state.session.lock().map_err(|_| SerialError::StateError)?;
guard.take()
};
let Some(SerialSession {
port,
cancel,
task,
current_record,
}) = session
else { else {
return Ok(SerialConnectResponse { return Ok(SerialConnectResponse {
port: String::new(), port: String::new(),
@@ -209,19 +233,6 @@ pub async fn serial_disconnect(
}); });
}; };
cancel.cancel();
let _ = task.await;
let frame_count = current_record.lock().map(|record| {
record.frames.len()
}).unwrap_or(0);
info!("last_record has {} frames", frame_count);
if let Ok(mut last_record) = state.last_record.lock() {
*last_record = Some(current_record);
}
Ok(SerialConnectResponse { Ok(SerialConnectResponse {
port, port,
connected: false, connected: false,

View File

@@ -1,4 +1,6 @@
use tauri::{AppHandle, Manager, WebviewWindow}; use super::serial::SerialConnectionState;
use crate::commands::serial::shutdown_active_session;
use tauri::{AppHandle, Manager, State, WebviewWindow};
fn main_window(app: &AppHandle) -> Result<WebviewWindow, String> { fn main_window(app: &AppHandle) -> Result<WebviewWindow, String> {
app.get_webview_window("main") app.get_webview_window("main")
@@ -25,8 +27,14 @@ pub fn win_toggle_maximize(app: AppHandle) -> Result<(), String> {
} }
#[tauri::command] #[tauri::command]
pub fn win_close(app: AppHandle) -> Result<(), String> { pub async fn win_close(
main_window(&app)? app: AppHandle,
.close() state: State<'_, SerialConnectionState>,
.map_err(|error| error.to_string()) ) -> Result<(), String> {
shutdown_active_session(&state)
.await
.map_err(|error| error.to_string())?;
app.exit(0);
Ok(())
} }

View File

@@ -1,6 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!! // Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use log::{debug, error, info, trace, warn}; use log::debug;
use tauri_demo_lib::log::setup_logger; use tauri_demo_lib::log::setup_logger;
fn main() { fn main() {

View File

@@ -18,7 +18,6 @@ const FRAME_BUFFER_MIN_LENGTH: usize = 15;
pub struct TactileACodec { pub struct TactileACodec {
buffer: Vec<u8>, buffer: Vec<u8>,
frame_nb: u64,
expected_data_len: usize, expected_data_len: usize,
} }
@@ -65,7 +64,6 @@ impl TactileACodec {
pub fn new(cols: usize, rows: usize) -> TactileACodec { pub fn new(cols: usize, rows: usize) -> TactileACodec {
Self { Self {
buffer: Vec::new(), buffer: Vec::new(),
frame_nb: 0,
expected_data_len: cols * rows * 2, expected_data_len: cols * rows * 2,
} }
} }
@@ -77,7 +75,14 @@ impl TactileACodec {
let vals: Vec<i32> = data let vals: Vec<i32> = data
.chunks_exact(2) .chunks_exact(2)
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]) as i32) .map(|chunk| {
let raw = u16::from_le_bytes([chunk[0], chunk[1]]) as i32;
if raw < 15 {
0
} else {
raw
}
})
.collect::<Vec<i32>>(); .collect::<Vec<i32>>();
Ok(vals) Ok(vals)
@@ -216,7 +221,7 @@ impl Codec<TactileAFrame> for TactileACodec {
req_bytes.push(f.meta.device_addr); req_bytes.push(f.meta.device_addr);
req_bytes.push(f.meta.extend_code); req_bytes.push(f.meta.extend_code);
req_bytes.push(f.meta.func_code); req_bytes.push(f.meta.func_code);
req_bytes.extend_from_slice(f.meta.start_addr.to_le_bytes().as_slice()); req_bytes.extend_from_slice(f.meta.start_addr.to_le_bytes().as_slice());
req_bytes.extend_from_slice((f.meta.except_data_len as u16).to_le_bytes().as_slice()); req_bytes.extend_from_slice((f.meta.except_data_len as u16).to_le_bytes().as_slice());
let checksum = calc_crc8_itu(req_bytes.as_slice()); let checksum = calc_crc8_itu(req_bytes.as_slice());
@@ -236,7 +241,6 @@ impl FrameHandler<TactileAFrame, i32> for TactileAHandler {
match frame { match frame {
TactileAFrame::Rep(rep) => { TactileAFrame::Rep(rep) => {
let vals = TactileACodec::parse_data_frame(&rep.payload)?; let vals = TactileACodec::parse_data_frame(&rep.payload)?;
debug!("vals is {:?}", vals);
Ok(Some(vals)) Ok(Some(vals))
} }
_ => Ok(None), _ => Ok(None),
@@ -252,13 +256,14 @@ impl TactileACsvExporter {
impl CsvExporter<TactileARepFrame> for TactileACsvExporter { impl CsvExporter<TactileARepFrame> for TactileACsvExporter {
type Error = CodecError; type Error = CodecError;
fn csv_header(&self, recording: &Recording<TactileARepFrame>) -> Vec<String> { fn csv_header(&self, _recording: &Recording<TactileARepFrame>) -> Vec<String> {
let mut header: Vec<String> = Vec::new(); let mut header: Vec<String> = Vec::new();
for i in 0..self.channels { for i in 0..self.channels {
header.push(format!("channel{}", i + 1)); header.push(format!("channel{}", i + 1));
} }
header.push("dts".to_string()); header.push("dts".to_string());
header.push("summary".to_string());
header header
} }
@@ -267,8 +272,10 @@ impl CsvExporter<TactileARepFrame> for TactileACsvExporter {
item: &RecordedFrame<TactileARepFrame>, item: &RecordedFrame<TactileARepFrame>,
) -> anyhow::Result<Vec<String>> { ) -> anyhow::Result<Vec<String>> {
let packet = TactileADataPacket::try_from(&item.frame)?; let packet = TactileADataPacket::try_from(&item.frame)?;
let summary: i32 = packet.data.iter().sum();
let mut row: Vec<String> = packet.data.iter().map(|x| x.to_string()).collect(); let mut row: Vec<String> = packet.data.iter().map(|x| x.to_string()).collect();
row.push(packet.dts_ms.to_string()); row.push(packet.dts_ms.to_string());
row.push(summary.to_string());
Ok(row) Ok(row)
} }
} }

View File

@@ -12,7 +12,6 @@ use tokio_util::sync::CancellationToken;
use std::future::pending; use std::future::pending;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Instant; use std::time::Instant;
use log::{info, debug};
use crate::serial_core::record::{FrameTiming, RecordedFrame}; use crate::serial_core::record::{FrameTiming, RecordedFrame};
pub enum PollMode<F> { pub enum PollMode<F> {
@@ -158,9 +157,9 @@ impl PollRequester<TactileAFrame> for TactileAPollRequester {
pub async fn run_serial<C, H, T, F>( pub async fn run_serial<C, H, T, F>(
app: AppHandle, app: AppHandle,
mut port: SerialStream, port: SerialStream,
mut codec: C, codec: C,
mut handler: H, handler: H,
session_started_at: Instant, session_started_at: Instant,
recording: Arc<Mutex<Recording<F>>>, recording: Arc<Mutex<Recording<F>>>,
cancel: CancellationToken, cancel: CancellationToken,
@@ -265,7 +264,8 @@ where
let display_values = if let Some(vals) = decode_res.as_ref() { let display_values = if let Some(vals) = decode_res.as_ref() {
let summary = vals.iter().copied().sum::<i32>(); let summary = vals.iter().copied().sum::<i32>();
chart_state.record_summary(summary as f32); let force = raw_to_g1(summary as u32);
chart_state.record_summary(force as f32);
chart_state.record_pressure_matrix(vals.as_slice()); chart_state.record_pressure_matrix(vals.as_slice());
Some(vec![summary]) Some(vec![summary])
} else { } else {
@@ -281,3 +281,36 @@ where
} }
Ok(()) Ok(())
} }
fn raw_to_g1(raw: u32) -> f64 {
const X: [u32; 11] = [
0, 74602, 105503, 131459, 153512, 172041, 193794, 218947, 240580, 295118, 332346,
];
const Y: [f64; 11] = [
0.0, 160.0, 260.0, 360.0, 460.0, 560.0, 660.0, 860.0, 1060.0, 1560.0, 2060.0,
];
let n = X.len();
if raw <= X[0] {
return Y[0] / 100.0;
}
if raw >= X[n - 1] {
return Y[n - 1] / 100.0;
}
let mut left = 0;
let mut right = n - 1;
while left + 1 < right {
let mid = (left + right) / 2;
if raw < X[mid] {
right = mid;
} else {
left = mid;
}
}
let ratio = (raw - X[left]) as f64 / (X[right] - X[left]) as f64;
Y[left] / 100.0 + ratio * (Y[right] - Y[left]) / 100.0
}

View File

@@ -1,3 +0,0 @@
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by cargo.
# For information about cache directory tags see https://bford.info/cachedir/

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "JE-Skin", "productName": "JE-Skin",
"version": "0.1.0", "version": "0.3.1",
"identifier": "com.lenn.tauri-serial", "identifier": "com.lenn.tauri-serial",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",
@@ -27,10 +27,10 @@
"targets": "all", "targets": "all",
"icon": [ "icon": [
"icons/32x32.png", "icons/32x32.png",
"icons/128x128.png", "icons/128x128.png",
"icons/128x128@2x.png", "icons/128x128@2x.png",
"icons/icon.ico", "icons/icon.icns",
"icons/icon.png" "icons/icon.ico"
] ]
} }
} }

View File

@@ -5,6 +5,7 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import { fly } from "svelte/transition"; import { fly } from "svelte/transition";
import ConfigPanel from "$lib/components/ConfigPanel.svelte"; import ConfigPanel from "$lib/components/ConfigPanel.svelte";
import NeonBreakoutArena from "$lib/components/NeonBreakoutArena.svelte";
import PressureMatrixViewer from "$lib/components/PressureMatrixViewer.svelte"; import PressureMatrixViewer from "$lib/components/PressureMatrixViewer.svelte";
import SignalChart from "$lib/components/SignalChart.svelte"; import SignalChart from "$lib/components/SignalChart.svelte";
import SummaryCurve from "$lib/components/SummaryCurve.svelte"; import SummaryCurve from "$lib/components/SummaryCurve.svelte";
@@ -12,14 +13,12 @@
HudColorMapOption, HudColorMapOption,
HudSignalPanel, HudSignalPanel,
HudSummary, HudSummary,
PressureColorMapPreset, LocaleCode,
StageStatusTone MatrixDisplayMode,
PressureColorMapPreset
} from "$lib/types/hud"; } from "$lib/types/hud";
export let title = ""; export let locale: LocaleCode = "zh-CN";
export let hint = "";
export let statusText = "";
export let statusTone: StageStatusTone = "idle";
export let leftPanels: HudSignalPanel[] = []; export let leftPanels: HudSignalPanel[] = [];
export let rightPanels: HudSignalPanel[] = []; export let rightPanels: HudSignalPanel[] = [];
export let summary: HudSummary; export let summary: HudSummary;
@@ -41,6 +40,7 @@
export let rangeMin = 0; export let rangeMin = 0;
export let rangeMax = 16000; export let rangeMax = 16000;
export let colorMapPreset: PressureColorMapPreset = "emerald"; export let colorMapPreset: PressureColorMapPreset = "emerald";
export let matrixDisplayMode: MatrixDisplayMode = "dots";
export let colorMapOptions: HudColorMapOption[] = []; export let colorMapOptions: HudColorMapOption[] = [];
export let replaySectionLabel = ""; export let replaySectionLabel = "";
export let replayPlayLabel = ""; export let replayPlayLabel = "";
@@ -54,9 +54,9 @@
export let replayProgress = 0; export let replayProgress = 0;
export let replayFileName = ""; export let replayFileName = "";
export let replayFrameInfo = ""; export let replayFrameInfo = "";
export let showPrecisionTestPanel = false;
let stagePlaneEl: HTMLDivElement | undefined; let stagePlaneEl: HTMLDivElement | undefined;
let topOverlayEl: HTMLDivElement | undefined;
let panelZoneEl: HTMLDivElement | undefined; let panelZoneEl: HTMLDivElement | undefined;
let leftStackEl: HTMLDivElement | undefined; let leftStackEl: HTMLDivElement | undefined;
let rightStackEl: HTMLDivElement | undefined; let rightStackEl: HTMLDivElement | undefined;
@@ -81,6 +81,9 @@
$: replaySide = summarySide === "left" ? "right" : "left"; $: replaySide = summarySide === "left" ? "right" : "left";
$: replayToggleButtonText = replayIsPlaying ? replayPauseLabel : replayPlayLabel; $: replayToggleButtonText = replayIsPlaying ? replayPauseLabel : replayPlayLabel;
$: replayProgressPercent = Math.round(Math.min(1, Math.max(0, replayProgress)) * 100); $: replayProgressPercent = Math.round(Math.min(1, Math.max(0, replayProgress)) * 100);
$: summaryCurveVisible = summary.points.length > 0 && summary.points.some((value) => Number.isFinite(value) && Math.abs(value) >= 0.0001);
$: splitMatrixTitle = locale === "zh-CN" ? "数字矩阵" : "Matrix";
$: splitMatrixHint = locale === "zh-CN" ? "实时压力数据 / 数字矩阵" : "Live pressure matrix";
function toPxNumber(rawValue: string): number { function toPxNumber(rawValue: string): number {
const value = Number.parseFloat(rawValue); const value = Number.parseFloat(rawValue);
@@ -101,15 +104,11 @@
} }
function recomputePanelLayout(): void { function recomputePanelLayout(): void {
if (!stagePlaneEl || !topOverlayEl) { if (!stagePlaneEl) {
return; return;
} }
const planeRect = stagePlaneEl.getBoundingClientRect(); panelZoneTopPx = showPrecisionTestPanel ? 24 : 16;
const overlayRect = topOverlayEl.getBoundingClientRect();
const overlayBottom = overlayRect.bottom - planeRect.top;
const upperTopLimit = Math.max(72, Math.round(stagePlaneEl.clientHeight * 0.34));
panelZoneTopPx = clamp(Math.round(overlayBottom + 8), 56, upperTopLimit);
const panelZoneBottomPx = panelZoneEl ? toPxNumber(getComputedStyle(panelZoneEl).bottom) : 0; const panelZoneBottomPx = panelZoneEl ? toPxNumber(getComputedStyle(panelZoneEl).bottom) : 0;
const zoneHeight = Math.max(0, stagePlaneEl.clientHeight - panelZoneTopPx - panelZoneBottomPx); const zoneHeight = Math.max(0, stagePlaneEl.clientHeight - panelZoneTopPx - panelZoneBottomPx);
@@ -153,10 +152,6 @@
resizeObserver.observe(stagePlaneEl); resizeObserver.observe(stagePlaneEl);
} }
if (topOverlayEl) {
resizeObserver.observe(topOverlayEl);
}
if (leftStackEl) { if (leftStackEl) {
resizeObserver.observe(leftStackEl); resizeObserver.observe(leftStackEl);
} }
@@ -181,31 +176,61 @@
bind:this={stagePlaneEl} bind:this={stagePlaneEl}
style="--panel-zone-top-dyn: {panelZoneTopPx}px; --rail-scale-left: {leftRailScale}; --rail-scale-right: {rightRailScale};" style="--panel-zone-top-dyn: {panelZoneTopPx}px; --rail-scale-left: {leftRailScale}; --rail-scale-right: {rightRailScale};"
> >
<div class="stage-top-overlay" bind:this={topOverlayEl}> {#if showPrecisionTestPanel}
<div class="stage-meta"> <div class="split-game-wrap">
<p class="meta-label">WebGL2 Stage</p> <section class="split-panel split-matrix-panel">
<h2>{title}</h2> <header class="split-panel-head">
<p class="meta-hint">{hint}</p> <p>{splitMatrixTitle}</p>
<span>{splitMatrixHint}</span>
</header>
<div class="split-panel-body">
{#key `${matrixRows}x${matrixCols}:${colorMapPreset}:split`}
<PressureMatrixViewer
{summary}
{pressureMatrix}
{matrixRows}
{matrixCols}
{rangeMin}
{rangeMax}
{colorMapPreset}
{matrixDisplayMode}
showStatsPanel={true}
/>
{/key}
</div>
</section>
<section class="split-panel split-breakout-panel">
<NeonBreakoutArena
{locale}
{pressureMatrix}
{matrixRows}
{matrixCols}
{rangeMin}
{rangeMax}
{colorMapPreset}
/>
</section>
</div> </div>
<p class="runtime-status" class:is-ok={statusTone === "ok"} class:is-warn={statusTone === "warn"}> {:else}
{statusText} <div class="canvas-wrap">
</p> {#key `${matrixRows}x${matrixCols}:${colorMapPreset}`}
</div> <PressureMatrixViewer
{summary}
{pressureMatrix}
{matrixRows}
{matrixCols}
{rangeMin}
{rangeMax}
{colorMapPreset}
{matrixDisplayMode}
showStatsPanel={true}
/>
{/key}
</div>
{/if}
<div class="canvas-wrap"> {#if showConfigPanel && !showPrecisionTestPanel}
{#key `${matrixRows}x${matrixCols}:${colorMapPreset}`}
<PressureMatrixViewer
{pressureMatrix}
{matrixRows}
{matrixCols}
{rangeMin}
{rangeMax}
{colorMapPreset}
/>
{/key}
</div>
{#if showConfigPanel}
<div class="config-panel-wrap"> <div class="config-panel-wrap">
<ConfigPanel <ConfigPanel
bind:matrixRows bind:matrixRows
@@ -230,71 +255,73 @@
</div> </div>
{/if} {/if}
<div class="panel-zone" bind:this={panelZoneEl}> {#if !showPrecisionTestPanel}
<aside class="side-rail left-rail"> <div class="panel-zone" bind:this={panelZoneEl}>
<div class="rail-stack" bind:this={leftStackEl}> <aside class="side-rail left-rail">
{#each leftPanels as panel, index (panel.id)} <div class="rail-stack" bind:this={leftStackEl}>
<div {#each leftPanels as panel, index (panel.id)}
class="panel-motion-shell" <div
animate:flip={{ duration: 280 }} class="panel-motion-shell"
in:fly={{ x: -180, duration: 340, opacity: 0.08, easing: cubicOut }} animate:flip={{ duration: 280 }}
out:fly={{ x: -180, duration: 280, opacity: 0.06, easing: cubicIn }} in:fly={{ x: -180, duration: 340, opacity: 0.08, easing: cubicOut }}
> out:fly={{ x: -180, duration: 280, opacity: 0.06, easing: cubicIn }}
<SignalChart {panel} panelIndex={index} /> >
</div> <SignalChart {panel} panelIndex={index} />
{/each} </div>
{/each}
{#if summary.points.length > 0 && summarySide === "left"} {#if summaryCurveVisible && summarySide === "left"}
<div <div
class="panel-motion-shell" class="panel-motion-shell"
in:fly={{ x: -180, duration: 340, opacity: 0.08, easing: cubicOut }} in:fly={{ x: -180, duration: 340, opacity: 0.08, easing: cubicOut }}
out:fly={{ x: -180, duration: 280, opacity: 0.06, easing: cubicIn }} out:fly={{ x: -180, duration: 280, opacity: 0.06, easing: cubicIn }}
> >
<SummaryCurve <SummaryCurve
{summary} {summary}
xValues={summary.xValues ?? null} xValues={summary.xValues ?? null}
yValues={summary.points} yValues={summary.points}
side="left" side="left"
panelIndex={leftPanels.length} panelIndex={leftPanels.length}
/> />
</div> </div>
{/if} {/if}
</div> </div>
</aside> </aside>
<aside class="side-rail right-rail"> <aside class="side-rail right-rail">
<div class="rail-stack" bind:this={rightStackEl}> <div class="rail-stack" bind:this={rightStackEl}>
{#each rightPanels as panel, index (panel.id)} {#each rightPanels as panel, index (panel.id)}
<div <div
class="panel-motion-shell" class="panel-motion-shell"
animate:flip={{ duration: 280 }} animate:flip={{ duration: 280 }}
in:fly={{ x: 180, duration: 340, opacity: 0.08, easing: cubicOut }} in:fly={{ x: 180, duration: 340, opacity: 0.08, easing: cubicOut }}
out:fly={{ x: 180, duration: 280, opacity: 0.06, easing: cubicIn }} out:fly={{ x: 180, duration: 280, opacity: 0.06, easing: cubicIn }}
> >
<SignalChart {panel} panelIndex={index} /> <SignalChart {panel} panelIndex={index} />
</div> </div>
{/each} {/each}
{#if summary.points.length > 0 && summarySide === "right"} {#if summaryCurveVisible && summarySide === "right"}
<div <div
class="panel-motion-shell" class="panel-motion-shell"
in:fly={{ x: 180, duration: 340, opacity: 0.08, easing: cubicOut }} in:fly={{ x: 180, duration: 340, opacity: 0.08, easing: cubicOut }}
out:fly={{ x: 180, duration: 280, opacity: 0.06, easing: cubicIn }} out:fly={{ x: 180, duration: 280, opacity: 0.06, easing: cubicIn }}
> >
<SummaryCurve <SummaryCurve
{summary} {summary}
xValues={summary.xValues ?? null} xValues={summary.xValues ?? null}
yValues={summary.points} yValues={summary.points}
side="right" side="right"
panelIndex={rightPanels.length} panelIndex={rightPanels.length}
/> />
</div> </div>
{/if} {/if}
</div> </div>
</aside> </aside>
</div> </div>
{/if}
{#if replayHasData} {#if replayHasData && !showPrecisionTestPanel}
<aside class="replay-floating-panel" class:is-left={replaySide === "left"} class:is-right={replaySide === "right"}> <aside class="replay-floating-panel" class:is-left={replaySide === "left"} class:is-right={replaySide === "right"}>
<div class="replay-panel-head"> <div class="replay-panel-head">
<div class="replay-panel-title-group"> <div class="replay-panel-title-group">
@@ -332,9 +359,11 @@
</aside> </aside>
{/if} {/if}
<div class="stage-bottom-overlay"> {#if !showPrecisionTestPanel}
<slot /> <div class="stage-bottom-overlay">
</div> <slot />
</div>
{/if}
</div> </div>
</article> </article>
</section> </section>
@@ -378,75 +407,6 @@
block-size: 100%; block-size: 100%;
} }
.stage-top-overlay {
position: absolute;
top: clamp(0.55rem, 1.1vw, 0.9rem);
left: calc(var(--rail-width) + var(--safe-gap) + var(--rail-edge-inset));
right: calc(var(--rail-width) + var(--safe-gap) + var(--rail-edge-inset));
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 0.7rem;
z-index: 7;
pointer-events: none;
}
.stage-meta {
min-width: 0;
max-inline-size: min(22rem, 62%);
padding: 0.3rem 0.5rem 0.35rem;
border: 1px solid rgb(var(--hud-border-rgb) / 0.2);
border-radius: 0.45rem;
background: rgb(var(--hud-surface-deep-rgb) / 0.45);
backdrop-filter: blur(2px);
}
.meta-label {
margin: 0;
font-size: 0.56rem;
color: rgb(var(--hud-text-dim-rgb) / 0.8);
text-transform: uppercase;
letter-spacing: 0.1em;
}
h2 {
margin: 0.08rem 0 0;
font-size: clamp(0.75rem, 1.1vw, 0.92rem);
color: rgb(var(--hud-text-main-rgb) / 0.96);
letter-spacing: 0.03em;
font-weight: 500;
line-height: 1.2;
}
.meta-hint {
margin: 0.09rem 0 0;
font-size: 0.62rem;
color: rgb(var(--hud-text-dim-rgb) / 0.76);
line-height: 1.15;
}
.runtime-status {
margin: 0;
align-self: center;
border: 1px solid rgb(var(--hud-border-rgb) / 0.35);
border-radius: 999px;
padding: 0.3rem 0.66rem;
font-size: 0.66rem;
letter-spacing: 0.08em;
color: rgb(var(--hud-text-dim-rgb) / 0.9);
text-transform: uppercase;
white-space: nowrap;
background: rgb(var(--hud-surface-deep-rgb) / 0.62);
}
.runtime-status.is-ok {
color: rgb(var(--hud-lime-rgb) / 0.94);
}
.runtime-status.is-warn {
color: rgb(var(--hud-orange-rgb) / 0.92);
}
.canvas-wrap { .canvas-wrap {
position: absolute; position: absolute;
inset: 0; inset: 0;
@@ -463,6 +423,70 @@
max-inline-size: min(24rem, 40vw); max-inline-size: min(24rem, 40vw);
} }
.split-game-wrap {
position: absolute;
inset: clamp(0.46rem, 1vw, 0.82rem);
z-index: 6;
display: grid;
grid-template-columns: minmax(0, 0.98fr) minmax(0, 1.02fr);
gap: clamp(0.45rem, 1vw, 0.9rem);
}
.split-panel {
position: relative;
min-block-size: 0;
overflow: hidden;
border: 1px solid rgb(var(--hud-border-rgb) / 0.26);
border-radius: 0.58rem;
background:
linear-gradient(180deg, rgb(var(--hud-surface-rgb) / 0.84), rgb(var(--hud-surface-deep-rgb) / 0.9)),
radial-gradient(circle at 50% 0, rgb(var(--hud-glow-rgb) / 0.06), transparent 56%);
box-shadow:
inset 0 1px 0 rgb(var(--hud-border-strong-rgb) / 0.07),
0 0 20px rgb(var(--hud-glow-rgb) / 0.08);
}
.split-panel-head {
position: absolute;
top: 0.42rem;
left: 0.52rem;
z-index: 5;
display: grid;
gap: 0.1rem;
margin: 0;
pointer-events: none;
}
.split-panel-head p {
margin: 0;
color: rgb(var(--hud-text-main-rgb) / 0.96);
font-size: 0.62rem;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.split-panel-head span {
color: rgb(var(--hud-text-dim-rgb) / 0.82);
font-size: 0.52rem;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.split-panel-body {
position: absolute;
inset: 0;
}
.split-matrix-panel :global(.viewer-controls) {
left: clamp(0.7rem, 1.7vw, 1.15rem);
top: clamp(3.8rem, 8.8vh, 4.9rem);
max-inline-size: min(13.2rem, 65%);
}
.split-matrix-panel :global(.stats-panel) {
padding: 0.62rem 0.68rem 0.72rem;
}
.panel-zone { .panel-zone {
position: absolute; position: absolute;
top: var(--panel-zone-top-dyn, var(--panel-zone-top)); top: var(--panel-zone-top-dyn, var(--panel-zone-top));
@@ -744,6 +768,10 @@
.replay-floating-panel { .replay-floating-panel {
inline-size: min(var(--rail-width), 20.8rem); inline-size: min(var(--rail-width), 20.8rem);
} }
.split-game-wrap {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
} }
@media (max-height: 900px) { @media (max-height: 900px) {
@@ -787,5 +815,10 @@
right: calc(var(--rail-edge-inset) + 0.1rem); right: calc(var(--rail-edge-inset) + 0.1rem);
inline-size: auto; inline-size: auto;
} }
.split-game-wrap {
grid-template-columns: 1fr;
grid-template-rows: minmax(0, 0.92fr) minmax(0, 1.08fr);
}
} }
</style> </style>

View File

@@ -89,6 +89,10 @@
colorMapPreset = "emerald"; colorMapPreset = "emerald";
} }
function handleSubmit(): void {
dispatch("close");
}
$: selectedColorMap = colorMapOptions.find((option) => option.id === colorMapPreset) ?? colorMapOptions[0]; $: selectedColorMap = colorMapOptions.find((option) => option.id === colorMapPreset) ?? colorMapOptions[0];
$: { $: {
@@ -120,7 +124,7 @@
} }
</script> </script>
<section class="config-panel" aria-label={title}> <form class="config-panel" aria-label={title} on:submit|preventDefault={handleSubmit}>
<header class="config-head"> <header class="config-head">
<div class="config-copy"> <div class="config-copy">
<p class="config-label">Stage Config</p> <p class="config-label">Stage Config</p>
@@ -214,7 +218,7 @@
<p class="live-note">{applyLiveHint}</p> <p class="live-note">{applyLiveHint}</p>
<button type="button" class="reset-btn" on:click={resetDefaults}>{resetLabel}</button> <button type="button" class="reset-btn" on:click={resetDefaults}>{resetLabel}</button>
</footer> </footer>
</section> </form>
<style> <style>
.config-panel { .config-panel {

View File

@@ -5,6 +5,7 @@
HudConfigLink, HudConfigLink,
HudNoticeTone, HudNoticeTone,
LocaleCode, LocaleCode,
MatrixDisplayMode,
WindowControlAction WindowControlAction
} from "$lib/types/hud"; } from "$lib/types/hud";
@@ -29,6 +30,10 @@
export let refreshPortsLabel = ""; export let refreshPortsLabel = "";
export let configLinksLabel = ""; export let configLinksLabel = "";
export let configLinks: HudConfigLink[] = []; export let configLinks: HudConfigLink[] = [];
export let matrixViewLabel = "";
export let matrixViewNumericLabel = "";
export let matrixViewDotsLabel = "";
export let matrixDisplayMode: MatrixDisplayMode = "dots";
export let connectActionLabel = ""; export let connectActionLabel = "";
export let disconnectActionLabel = ""; export let disconnectActionLabel = "";
export let exportActionLabel = ""; export let exportActionLabel = "";
@@ -46,6 +51,7 @@
windowcontrol: WindowControlAction; windowcontrol: WindowControlAction;
localechange: LocaleCode; localechange: LocaleCode;
configlink: string; configlink: string;
matrixdisplaytoggle: boolean;
portchange: string; portchange: string;
serialrefresh: void; serialrefresh: void;
serialconnect: string; serialconnect: string;
@@ -89,6 +95,10 @@
dispatch("configlink", linkId); dispatch("configlink", linkId);
} }
function emitMatrixDisplayToggle(): void {
dispatch("matrixdisplaytoggle", matrixDisplayMode !== "dots");
}
function emitPortChange(event: Event): void { function emitPortChange(event: Event): void {
const target = event.currentTarget as HTMLSelectElement; const target = event.currentTarget as HTMLSelectElement;
dispatch("portchange", target.value); dispatch("portchange", target.value);
@@ -175,6 +185,24 @@
{/each} {/each}
</section> </section>
<section class="matrix-switch-wrap" aria-label={matrixViewLabel}>
<span class="matrix-switch-label">{matrixViewLabel}</span>
<button
type="button"
class="matrix-switch-btn"
class:is-active={matrixDisplayMode === "dots"}
role="switch"
aria-checked={matrixDisplayMode === "dots"}
aria-label={matrixViewDotsLabel}
on:click={emitMatrixDisplayToggle}
>
<span class="matrix-switch-track" aria-hidden="true">
<span class="matrix-switch-thumb"></span>
</span>
<span class="matrix-switch-copy">{matrixDisplayMode === "dots" ? matrixViewDotsLabel : matrixViewNumericLabel}</span>
</button>
</section>
<section class="state-card" aria-label={connectionLabel}> <section class="state-card" aria-label={connectionLabel}>
<span class="state-dot" class:ok={connectionTone === "ok"} class:warn={connectionTone === "warn"}></span> <span class="state-dot" class:ok={connectionTone === "ok"} class:warn={connectionTone === "warn"}></span>
<span class="state-label">{connectionLabel}</span> <span class="state-label">{connectionLabel}</span>
@@ -432,6 +460,108 @@
background: var(--panel-surface); background: var(--panel-surface);
} }
.matrix-switch-wrap {
display: inline-flex;
align-items: center;
gap: 0.4rem;
min-block-size: 2rem;
border: 1px solid var(--panel-line);
border-radius: 999px;
padding: 0.16rem 0.22rem 0.16rem 0.56rem;
background: var(--panel-surface);
}
.matrix-switch-label {
color: var(--panel-text-dim);
font-size: 0.66rem;
letter-spacing: 0.08em;
text-transform: uppercase;
line-height: 1;
white-space: nowrap;
}
.matrix-switch-btn {
display: inline-flex;
align-items: center;
gap: 0.42rem;
min-block-size: 1.62rem;
border: 1px solid rgb(var(--hud-border-rgb) / 0.26);
border-radius: 999px;
padding: 0.18rem 0.28rem 0.18rem 0.22rem;
background: rgb(var(--hud-surface-deep-rgb) / 0.84);
color: rgb(var(--hud-text-main-rgb) / 0.92);
cursor: pointer;
transition:
border-color 180ms ease,
box-shadow 180ms ease,
background-color 180ms ease,
color 180ms ease;
}
.matrix-switch-btn:hover {
border-color: rgb(var(--hud-cyan-rgb) / 0.4);
}
.matrix-switch-btn.is-active {
border-color: rgb(var(--hud-cyan-rgb) / 0.5);
background:
linear-gradient(180deg, rgb(var(--hud-surface-alt-rgb) / 0.94), rgb(var(--hud-surface-rgb) / 0.9)),
radial-gradient(circle at 50% 0, rgb(var(--hud-cyan-rgb) / 0.12), transparent 60%);
box-shadow:
inset 0 0 0 1px rgb(var(--hud-text-main-rgb) / 0.05),
0 0 12px rgb(var(--hud-cyan-rgb) / 0.12);
}
.matrix-switch-track {
position: relative;
display: inline-flex;
align-items: center;
inline-size: 2.2rem;
block-size: 1.2rem;
border-radius: 999px;
padding: 0.14rem;
background: rgb(var(--hud-surface-rgb) / 0.9);
box-shadow: inset 0 0 0 1px rgb(var(--hud-border-rgb) / 0.24);
transition:
background-color 180ms ease,
box-shadow 180ms ease;
}
.matrix-switch-btn.is-active .matrix-switch-track {
background: rgb(var(--hud-cyan-rgb) / 0.18);
box-shadow: inset 0 0 0 1px rgb(var(--hud-cyan-rgb) / 0.18);
}
.matrix-switch-thumb {
inline-size: 0.92rem;
block-size: 0.92rem;
border-radius: 50%;
background: rgb(var(--hud-text-main-rgb) / 0.96);
box-shadow:
0 1px 4px rgb(0 0 0 / 0.26),
0 0 10px rgb(var(--hud-text-main-rgb) / 0.12);
transform: translateX(0);
transition:
transform 180ms ease,
background-color 180ms ease,
box-shadow 180ms ease;
}
.matrix-switch-btn.is-active .matrix-switch-thumb {
transform: translateX(0.96rem);
background: rgb(var(--hud-cyan-rgb) / 0.96);
box-shadow:
0 1px 4px rgb(0 0 0 / 0.26),
0 0 12px rgb(var(--hud-cyan-rgb) / 0.22);
}
.matrix-switch-copy {
font-size: 0.74rem;
letter-spacing: 0.04em;
white-space: nowrap;
line-height: 1;
}
.state-dot { .state-dot {
inline-size: 0.55rem; inline-size: 0.55rem;
block-size: 0.55rem; block-size: 0.55rem;

File diff suppressed because it is too large Load Diff

View File

@@ -3,12 +3,12 @@
import * as THREE from "three"; import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { pressureColorPalettes } from "$lib/config/color-map"; import { pressureColorPalettes } from "$lib/config/color-map";
import type { PressureColorMapPreset } from "$lib/types/hud"; import type { HudSummary, MatrixDisplayMode, PressureColorMapPreset } from "$lib/types/hud";
interface ViewerStats { interface ViewerStats {
total: number; current: number | null;
max: number; max: number | null;
avg: number; min: number | null;
} }
interface MatrixLayout { interface MatrixLayout {
@@ -28,11 +28,14 @@
export let rangeMin = 0; export let rangeMin = 0;
export let rangeMax = 16000; export let rangeMax = 16000;
export let colorMapPreset: PressureColorMapPreset = "emerald"; export let colorMapPreset: PressureColorMapPreset = "emerald";
export let matrixDisplayMode: MatrixDisplayMode = "dots";
export let summary: HudSummary | null = null;
export let showStatsPanel = true;
let viewerEl: HTMLDivElement | undefined; let viewerEl: HTMLDivElement | undefined;
let canvasEl: HTMLCanvasElement | undefined; let canvasEl: HTMLCanvasElement | undefined;
let overlayEl: HTMLCanvasElement | undefined; let overlayEl: HTMLCanvasElement | undefined;
let stats: ViewerStats = { total: 0, max: 0, avg: 0 }; let stats: ViewerStats = { current: null, max: null, min: null };
const DEFAULT_RANGE_MAX = 16000; const DEFAULT_RANGE_MAX = 16000;
const BASE_MATRIX_SPAN = 24; const BASE_MATRIX_SPAN = 24;
@@ -62,6 +65,7 @@
const CAMERA_TARGET_Y = MATRIX_OFFSET_Y + 0.2; const CAMERA_TARGET_Y = MATRIX_OFFSET_Y + 0.2;
const CAMERA_TARGET_Z = MATRIX_OFFSET_Z - 0.4; const CAMERA_TARGET_Z = MATRIX_OFFSET_Z - 0.4;
const MATRIX_ROTATION_Y = 0; const MATRIX_ROTATION_Y = 0;
const rangeStopPositions = [0, 0.25, 0.5, 0.75, 0.875, 1] as const;
const labelVector = new THREE.Vector3(); const labelVector = new THREE.Vector3();
$: resolvedColorPalette = pressureColorPalettes[colorMapPreset] ?? pressureColorPalettes.emerald; $: resolvedColorPalette = pressureColorPalettes[colorMapPreset] ?? pressureColorPalettes.emerald;
@@ -74,6 +78,7 @@
$: labelLowColor = new THREE.Color(resolvedColorPalette.labelLow); $: labelLowColor = new THREE.Color(resolvedColorPalette.labelLow);
$: labelMidColor = new THREE.Color(resolvedColorPalette.labelMid); $: labelMidColor = new THREE.Color(resolvedColorPalette.labelMid);
$: labelHighColor = new THREE.Color(resolvedColorPalette.labelHigh); $: labelHighColor = new THREE.Color(resolvedColorPalette.labelHigh);
$: rangeStopColors = resolvedColorPalette.rangeStops.map((stop) => new THREE.Color(stop));
$: sceneClearColor = new THREE.Color(resolvedColorPalette.uiTheme.bg30); $: sceneClearColor = new THREE.Color(resolvedColorPalette.uiTheme.bg30);
$: sceneBoardColor = new THREE.Color(resolvedColorPalette.uiTheme.bg20); $: sceneBoardColor = new THREE.Color(resolvedColorPalette.uiTheme.bg20);
$: sceneGridCenterColor = new THREE.Color(resolvedColorPalette.surfaceMid); $: sceneGridCenterColor = new THREE.Color(resolvedColorPalette.surfaceMid);
@@ -83,7 +88,7 @@
$: sceneAccentLightColor = rgbTripletToThreeColor(resolvedColorPalette.uiTheme.glowRgb); $: sceneAccentLightColor = rgbTripletToThreeColor(resolvedColorPalette.uiTheme.glowRgb);
$: surfaceThemeAccentColor = rgbTripletToThreeColor(resolvedColorPalette.uiTheme.glowRgb); $: surfaceThemeAccentColor = rgbTripletToThreeColor(resolvedColorPalette.uiTheme.glowRgb);
$: labelThemeAccentColor = rgbTripletToThreeColor(resolvedColorPalette.uiTheme.glowRgb); $: labelThemeAccentColor = rgbTripletToThreeColor(resolvedColorPalette.uiTheme.glowRgb);
$: labelHighlightCss = colorToCss(surfaceHotColor); $: labelHighlightCss = colorToCss(rangeStopColors[5] ?? surfaceHotColor);
$: viewerThemeStyle = [ $: viewerThemeStyle = [
`--matrix-bg-10: ${resolvedColorPalette.uiTheme.bg10}`, `--matrix-bg-10: ${resolvedColorPalette.uiTheme.bg10}`,
`--matrix-bg-20: ${resolvedColorPalette.uiTheme.bg20}`, `--matrix-bg-20: ${resolvedColorPalette.uiTheme.bg20}`,
@@ -123,7 +128,16 @@
$: resolvedRangeMin = resolvedRange.min; $: resolvedRangeMin = resolvedRange.min;
$: resolvedRangeMax = resolvedRange.max; $: resolvedRangeMax = resolvedRange.max;
$: matrixLayout = buildMatrixLayout(resolvedMatrixRows, resolvedMatrixCols); $: matrixLayout = buildMatrixLayout(resolvedMatrixRows, resolvedMatrixCols);
$: statsNote = `${resolvedMatrixRows}x${resolvedMatrixCols} / color range ${resolvedRangeMin}-${resolvedRangeMax} / label raw`; $: statsModeLabel = matrixDisplayMode === "dots" ? "dot pulse" : "numeric pulse";
$: statsNote = `${resolvedMatrixRows}x${resolvedMatrixCols} / force range ${resolvedRangeMin}-${resolvedRangeMax} / ${statsModeLabel}`;
function formatForceStat(value: number | null): string {
if (value == null || !Number.isFinite(value)) {
return "--";
}
return value.toFixed(1);
}
function clamp(value: number, min: number, max: number): number { function clamp(value: number, min: number, max: number): number {
return Math.min(max, Math.max(min, value)); return Math.min(max, Math.max(min, value));
@@ -142,23 +156,26 @@
return new THREE.Color(`rgb(${rgbTriplet.replace(/\s+/g, ", ")})`); return new THREE.Color(`rgb(${rgbTriplet.replace(/\s+/g, ", ")})`);
} }
function surfaceColorMap(valueNormalized: number, target: THREE.Color = new THREE.Color()): THREE.Color { function sampleRangeStopColor(valueNormalized: number, target: THREE.Color = new THREE.Color()): THREE.Color {
const value = clamp(valueNormalized, 0, 1); const value = clamp(valueNormalized, 0, 1);
let mapped: THREE.Color;
if (value <= 0.45) { for (let index = 0; index < rangeStopPositions.length - 1; index += 1) {
const t = smoothstep(0, 0.45, value); const start = rangeStopPositions[index];
mapped = target.copy(surfaceBaseColor).lerp(surfaceLowColor, t); const end = rangeStopPositions[index + 1];
} else if (value <= 0.78) { if (value <= end) {
const t = smoothstep(0.45, 0.78, value); const localT = smoothstep(start, end, value);
mapped = target.copy(surfaceLowColor).lerp(surfaceMidColor, t); return target.copy(rangeStopColors[index]).lerp(rangeStopColors[index + 1], localT);
} else { }
const t = smoothstep(0.78, 1, value);
mapped = target.copy(surfaceMidColor).lerp(surfaceHighColor, t);
} }
const baseAccentStrength = (1 - smoothstep(0.12, 0.52, value)) * 0.34; return target.copy(rangeStopColors[rangeStopColors.length - 1]);
const highlightStrength = smoothstep(0.82, 1, value) * 0.3; }
function surfaceColorMap(valueNormalized: number, target: THREE.Color = new THREE.Color()): THREE.Color {
const value = clamp(valueNormalized, 0, 1);
const mapped = sampleRangeStopColor(value, target);
const baseAccentStrength = (1 - smoothstep(0.08, 0.28, value)) * 0.16;
const highlightStrength = smoothstep(0.88, 1, value) * 0.2;
return mapped.lerp(surfaceThemeAccentColor, baseAccentStrength).lerp(surfaceHotColor, highlightStrength); return mapped.lerp(surfaceThemeAccentColor, baseAccentStrength).lerp(surfaceHotColor, highlightStrength);
} }
@@ -170,22 +187,10 @@
function labelColorMap(valueNormalized: number, target: THREE.Color = new THREE.Color()): THREE.Color { function labelColorMap(valueNormalized: number, target: THREE.Color = new THREE.Color()): THREE.Color {
const value = clamp(valueNormalized, 0, 1); const value = clamp(valueNormalized, 0, 1);
let mapped: THREE.Color; const mapped = sampleRangeStopColor(value, target);
const baseAccentStrength = (1 - smoothstep(0.08, 0.24, value)) * 0.18;
if (value <= 0.34) { const highlightStrength = smoothstep(0.88, 1, value) * 0.12;
const t = smoothstep(0, 0.34, value); return mapped.lerp(labelThemeAccentColor, baseAccentStrength).lerp(labelHighColor, highlightStrength);
mapped = target.copy(labelZeroColor).lerp(labelLowColor, t);
} else if (value <= 0.76) {
const t = smoothstep(0.34, 0.76, value);
mapped = target.copy(labelLowColor).lerp(labelMidColor, t);
} else {
const t = smoothstep(0.76, 1, value);
mapped = target.copy(labelMidColor).lerp(labelHighColor, t);
}
const baseAccentStrength = (1 - smoothstep(0.16, 0.58, value)) * 0.46;
const highlightStrength = smoothstep(0.8, 1, value) * 0.36;
return mapped.lerp(labelThemeAccentColor, baseAccentStrength).lerp(surfaceHotColor, highlightStrength);
} }
function shapeHeightValue(valueNormalized: number): number { function shapeHeightValue(valueNormalized: number): number {
@@ -262,6 +267,24 @@
return `rgb(${Math.round(color.r * 255)} ${Math.round(color.g * 255)} ${Math.round(color.b * 255)})`; return `rgb(${Math.round(color.r * 255)} ${Math.round(color.g * 255)} ${Math.round(color.b * 255)})`;
} }
function drawProjectedDot(
context: CanvasRenderingContext2D,
screenX: number,
screenY: number,
radius: number,
fillStyle: string,
glowStyle: string,
opacity: number
): void {
context.globalAlpha = opacity;
context.shadowBlur = radius * 2.8;
context.shadowColor = glowStyle;
context.fillStyle = fillStyle;
context.beginPath();
context.arc(screenX, screenY, radius, 0, Math.PI * 2);
context.fill();
}
$: labelPalette = Array.from({ length: 33 }, (_, index) => { $: labelPalette = Array.from({ length: 33 }, (_, index) => {
const t = index / 32; const t = index / 32;
return colorToCss(labelColorMap(t, new THREE.Color())); return colorToCss(labelColorMap(t, new THREE.Color()));
@@ -430,7 +453,7 @@
const compactField = new Uint16Array(instanceCount); const compactField = new Uint16Array(instanceCount);
let lastFrameAt = performance.now(); let lastFrameAt = performance.now();
const drawNumberOverlay = () => { const drawOverlay = () => {
if (!viewerEl || !overlayEl) { if (!viewerEl || !overlayEl) {
return; return;
} }
@@ -463,10 +486,42 @@
const normalized = normalizedField[index]; const normalized = normalizedField[index];
const displayValue = compactField[index]; const displayValue = compactField[index];
const bucket = Math.min(32, Math.round(normalized * 32));
const isDotsMode = matrixDisplayMode === "dots";
if (isDotsMode) {
const baseDotRadius = clamp(cellSpacing * 0.48, 7.2, 21.6);
const dotRadius = clamp(baseDotRadius + smoothstep(0, 1, normalized) * (cellSpacing * 0.86 + 9.6), 7.2, 15);
const dotOpacity = displayValue === 0 ? 0.62 : 0.98;
drawProjectedDot(
overlayContext,
screenX,
screenY,
dotRadius,
labelPalette[bucket],
labelGlowPalette[bucket],
dotOpacity
);
if (normalized >= 0.8) {
drawProjectedDot(
overlayContext,
screenX,
screenY,
dotRadius * 0.46,
labelHighlightCss,
labelHighlightCss,
smoothstep(0.8, 1, normalized) * 0.42
);
}
continue;
}
const displayText = String(displayValue); const displayText = String(displayValue);
const digitCount = displayText.length; const digitCount = displayText.length;
const digitScale = digitCount <= 2 ? 1 : digitCount === 3 ? 0.86 : digitCount === 4 ? 0.74 : 0.64; const digitScale = digitCount <= 2 ? 1 : digitCount === 3 ? 0.86 : digitCount === 4 ? 0.74 : 0.64;
const bucket = Math.min(32, Math.round(normalized * 32));
const baseGlyphSize = fontSize + smoothstep(0, 1, normalized) * (2.3 * labelScale + cellSpacing * 0.26); const baseGlyphSize = fontSize + smoothstep(0, 1, normalized) * (2.3 * labelScale + cellSpacing * 0.26);
const glyphSize = clamp(baseGlyphSize * digitScale, 5.2, 26); const glyphSize = clamp(baseGlyphSize * digitScale, 5.2, 26);
const glowSizeFactor = digitCount >= 4 ? 0.76 : digitCount === 3 ? 0.88 : 1; const glowSizeFactor = digitCount >= 4 ? 0.76 : digitCount === 3 ? 0.88 : 1;
@@ -475,7 +530,6 @@
overlayContext.font = `600 ${glyphSize.toFixed(1)}px "JetBrains Mono", "IBM Plex Mono", "Consolas", monospace`; overlayContext.font = `600 ${glyphSize.toFixed(1)}px "JetBrains Mono", "IBM Plex Mono", "Consolas", monospace`;
overlayContext.shadowBlur = glowBlur; overlayContext.shadowBlur = glowBlur;
overlayContext.shadowColor = labelGlowPalette[bucket]; overlayContext.shadowColor = labelGlowPalette[bucket];
overlayContext.fillStyle = labelPalette[bucket]; overlayContext.fillStyle = labelPalette[bucket];
overlayContext.globalAlpha = displayValue === 0 ? 0.86 : 1; overlayContext.globalAlpha = displayValue === 0 ? 0.86 : 1;
overlayContext.fillText(displayText, screenX, screenY); overlayContext.fillText(displayText, screenX, screenY);
@@ -549,9 +603,6 @@
} }
const maxValue = normalizeField(smoothedField, normalizedField, resolvedRangeMin, resolvedRangeMax); const maxValue = normalizeField(smoothedField, normalizedField, resolvedRangeMin, resolvedRangeMax);
let total = 0;
let activeCount = 0;
for (let index = 0; index < instanceCount; index += 1) { for (let index = 0; index < instanceCount; index += 1) {
const normalized = normalizedField[index]; const normalized = normalizedField[index];
const heightValue = shapeHeightValue(normalized); const heightValue = shapeHeightValue(normalized);
@@ -559,20 +610,15 @@
heightField[index] = height; heightField[index] = height;
compactField[index] = compactDisplayValue(smoothedField[index], resolvedRangeMin, resolvedRangeMax); compactField[index] = compactDisplayValue(smoothedField[index], resolvedRangeMin, resolvedRangeMax);
total += smoothedField[index];
if (smoothedField[index] > 30) {
activeCount += 1;
}
} }
renderer.render(scene, camera); renderer.render(scene, camera);
drawNumberOverlay(); drawOverlay();
stats = { stats = {
total, current: summary?.latest ?? null,
max: maxValue, max: summary?.max ?? null,
avg: activeCount > 0 ? total / activeCount : 0 min: summary?.min ?? null
}; };
}); });
@@ -608,26 +654,28 @@
<div class="viewer-vignette" aria-hidden="true"></div> <div class="viewer-vignette" aria-hidden="true"></div>
<div class="viewer-noise" aria-hidden="true"></div> <div class="viewer-noise" aria-hidden="true"></div>
<div class="viewer-controls"> {#if showStatsPanel}
<section class="stats-panel" aria-label="Pressure Summary"> <div class="viewer-controls">
<p class="stats-label">Pressure Matrix</p> <section class="stats-panel" aria-label="Pressure Summary">
<div class="stats-grid"> <p class="stats-label">Resultant Force</p>
<article class="stats-card stats-card-wide"> <div class="stats-grid">
<span class="stats-key">Total Pressure</span> <article class="stats-card stats-card-wide">
<strong class="stats-value">{stats.total.toFixed(0)}</strong> <span class="stats-key">Current RF</span>
</article> <strong class="stats-value">{formatForceStat(stats.current)}</strong>
<article class="stats-card"> </article>
<span class="stats-key">Max</span> <article class="stats-card">
<strong class="stats-value">{stats.max.toFixed(0)}</strong> <span class="stats-key">Max RF</span>
</article> <strong class="stats-value">{formatForceStat(stats.max)}</strong>
<article class="stats-card"> </article>
<span class="stats-key">Avg</span> <article class="stats-card">
<strong class="stats-value">{stats.avg.toFixed(0)}</strong> <span class="stats-key">Min RF</span>
</article> <strong class="stats-value">{formatForceStat(stats.min)}</strong>
</div> </article>
<p class="stats-note">{statsNote}</p> </div>
</section> <p class="stats-note">{statsNote}</p>
</div> </section>
</div>
{/if}
</div> </div>
<style> <style>

View File

@@ -7,10 +7,13 @@
export let xValues: number[] | null = null; export let xValues: number[] | null = null;
export let yValues: number[] | null = null; export let yValues: number[] | null = null;
const viewportWidth = 100; const viewportWidth = 120;
const viewportHeight = 36; const viewportHeight = 48;
const horizontalInset = 2; const plotInsetLeft = 13;
const verticalInset = 2; const plotInsetRight = 4;
const plotInsetTop = 4;
const plotInsetBottom = 9;
const fixedYBounds = { min: 0, max: 25 };
interface CurveSample { interface CurveSample {
x: number; x: number;
@@ -50,12 +53,7 @@
return String(Math.round(value)); return String(Math.round(value));
} }
if (Math.abs(value) >= 1000) { return `${Math.round(value)} N`;
const compact = Math.round((value / 1000) * 10) / 10;
return Number.isInteger(compact) ? `${compact.toFixed(0)}k` : `${compact.toFixed(1)}k`;
}
return Math.abs(value) >= 100 ? Math.round(value).toString() : value.toFixed(1);
} }
function resolveDataBounds(values: number[]): { min: number; max: number } { function resolveDataBounds(values: number[]): { min: number; max: number } {
@@ -87,18 +85,18 @@
function mapXToViewport(value: number, bounds: { min: number; max: number }): number { function mapXToViewport(value: number, bounds: { min: number; max: number }): number {
const span = bounds.max - bounds.min; const span = bounds.max - bounds.min;
const chartWidth = viewportWidth - horizontalInset * 2; const chartWidth = viewportWidth - plotInsetLeft - plotInsetRight;
const ratio = span <= 0 ? 0.5 : (value - bounds.min) / span; const ratio = span <= 0 ? 0.5 : (value - bounds.min) / span;
const mappedX = horizontalInset + ratio * chartWidth; const mappedX = plotInsetLeft + ratio * chartWidth;
return Math.round(clamp(mappedX, horizontalInset, viewportWidth - horizontalInset) * 100) / 100; return Math.round(clamp(mappedX, plotInsetLeft, viewportWidth - plotInsetRight) * 100) / 100;
} }
function mapYToViewport(value: number, bounds: { min: number; max: number }): number { function mapYToViewport(value: number, bounds: { min: number; max: number }): number {
const span = bounds.max - bounds.min; const span = bounds.max - bounds.min;
const chartHeight = viewportHeight - verticalInset * 2; const chartHeight = viewportHeight - plotInsetTop - plotInsetBottom;
const ratio = span <= 0 ? 0.5 : (value - bounds.min) / span; const ratio = span <= 0 ? 0.5 : (value - bounds.min) / span;
const mappedY = viewportHeight - verticalInset - ratio * chartHeight; const mappedY = viewportHeight - plotInsetBottom - ratio * chartHeight;
return Math.round(clamp(mappedY, verticalInset, viewportHeight - verticalInset) * 100) / 100; return Math.round(clamp(mappedY, plotInsetTop, viewportHeight - plotInsetBottom) * 100) / 100;
} }
function buildSamples(rawYValues: number[], rawXValues: number[]): CurveSample[] { function buildSamples(rawYValues: number[], rawXValues: number[]): CurveSample[] {
@@ -137,16 +135,13 @@
function buildYAxisTicks( function buildYAxisTicks(
yScaleBounds: { min: number; max: number }, yScaleBounds: { min: number; max: number },
yDataBounds: { min: number; max: number } _yDataBounds: { min: number; max: number }
): AxisTick[] { ): AxisTick[] {
const hasRange = Math.abs(yDataBounds.max - yDataBounds.min) >= 0.001; const tickValues = [25, 20, 15, 10, 5, 0];
const tickValues = hasRange
? [yDataBounds.max, (yDataBounds.max + yDataBounds.min) / 2, yDataBounds.min]
: [yScaleBounds.max, (yScaleBounds.max + yScaleBounds.min) / 2, yScaleBounds.min];
return tickValues.map((value) => ({ return tickValues.map((value) => ({
value, value,
label: formatAxisValue(value, "y"), label: formatAxisValue(value, "y"),
plotX: horizontalInset, plotX: plotInsetLeft - 1.8,
plotY: mapYToViewport(value, yScaleBounds) plotY: mapYToViewport(value, yScaleBounds)
})); }));
} }
@@ -164,7 +159,7 @@
value, value,
label: formatAxisValue(value, "x"), label: formatAxisValue(value, "x"),
plotX: mapXToViewport(value, xScaleBounds), plotX: mapXToViewport(value, xScaleBounds),
plotY: viewportHeight - 1.2 plotY: viewportHeight - 0.9
})); }));
} }
@@ -185,7 +180,7 @@
const firstPoint = points[0]; const firstPoint = points[0];
const lastPoint = points[points.length - 1]; const lastPoint = points[points.length - 1];
return `${linePath} L ${lastPoint.x} ${viewportHeight} L ${firstPoint.x} ${viewportHeight} Z`; return `${linePath} L ${lastPoint.x} ${viewportHeight - plotInsetBottom} L ${firstPoint.x} ${viewportHeight - plotInsetBottom} Z`;
} }
$: sourceYValues = yValues && yValues.length ? yValues : summary.points; $: sourceYValues = yValues && yValues.length ? yValues : summary.points;
@@ -193,7 +188,7 @@
$: samples = buildSamples(sourceYValues, sourceXValues); $: samples = buildSamples(sourceYValues, sourceXValues);
$: sampleCount = samples.length; $: sampleCount = samples.length;
$: xScaleBounds = resolveBounds(samples.map((sample) => sample.x)); $: xScaleBounds = resolveBounds(samples.map((sample) => sample.x));
$: yScaleBounds = resolveBounds(samples.map((sample) => sample.y)); $: yScaleBounds = fixedYBounds;
$: xDataBounds = resolveDataBounds(samples.map((sample) => sample.x)); $: xDataBounds = resolveDataBounds(samples.map((sample) => sample.x));
$: yDataBounds = resolveDataBounds(samples.map((sample) => sample.y)); $: yDataBounds = resolveDataBounds(samples.map((sample) => sample.y));
$: plotPoints = convertPoints(samples, xScaleBounds, yScaleBounds); $: plotPoints = convertPoints(samples, xScaleBounds, yScaleBounds);
@@ -215,7 +210,7 @@
> >
<header class="panel-head"> <header class="panel-head">
<div class="head-text"> <div class="head-text">
<p class="panel-code">TOT</p> <p class="panel-code">RF</p>
<p class="panel-title">{summary.label}</p> <p class="panel-title">{summary.label}</p>
</div> </div>
@@ -236,8 +231,8 @@
</defs> </defs>
<g class="grid-lines" aria-hidden="true"> <g class="grid-lines" aria-hidden="true">
{#each [6, 12, 18, 24, 30] as y} {#each yAxisTicks as tick (`grid-${tick.value}`)}
<line x1="0" y1={y} x2={viewportWidth} y2={y}></line> <line x1={plotInsetLeft} y1={tick.plotY} x2={viewportWidth - plotInsetRight} y2={tick.plotY}></line>
{/each} {/each}
</g> </g>
@@ -255,7 +250,7 @@
<g class="axis-labels" aria-hidden="true"> <g class="axis-labels" aria-hidden="true">
{#each yAxisTicks as tick, index (`y-${index}`)} {#each yAxisTicks as tick, index (`y-${index}`)}
<text class="axis-label y-axis-label" x={tick.plotX + 0.8} y={tick.plotY - 0.35} text-anchor="start"> <text class="axis-label y-axis-label" x={tick.plotX} y={tick.plotY + 1.1} text-anchor="end">
{tick.label} {tick.label}
</text> </text>
{/each} {/each}
@@ -305,14 +300,14 @@
--enter-ms: 1800ms; --enter-ms: 1800ms;
--fade-ms: 1000ms; --fade-ms: 1000ms;
overflow: hidden; overflow: hidden;
inline-size: min(100%, clamp(16.8rem, 23vw, 22rem)); inline-size: min(100%, clamp(29rem, 38vw, 37rem));
aspect-ratio: 1.44 / 1; aspect-ratio: 1.42 / 1;
min-block-size: 11.8rem; min-block-size: 20.5rem;
justify-self: start; justify-self: start;
display: grid; display: grid;
grid-template-rows: auto auto auto; grid-template-rows: auto auto auto;
gap: 0.4rem; gap: 0.68rem;
padding: 0.56rem 0.62rem 0.58rem; padding: 0.88rem 0.96rem 1rem;
border: 1px solid rgb(var(--hud-border-strong-rgb) / 0.42); border: 1px solid rgb(var(--hud-border-strong-rgb) / 0.42);
border-radius: 0.92rem; border-radius: 0.92rem;
background: background:
@@ -345,6 +340,10 @@
opacity: 0.82; opacity: 0.82;
} }
.summary-panel {
margin-block-end: clamp(0.8rem, 1.8vh, 1.4rem);
}
.panel-head { .panel-head {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -367,7 +366,7 @@
.panel-title { .panel-title {
margin: 0.12rem 0 0; margin: 0.12rem 0 0;
font-size: 0.75rem; font-size: 1.08rem;
color: rgb(var(--hud-text-main-rgb) / 0.96); color: rgb(var(--hud-text-main-rgb) / 0.96);
letter-spacing: 0.05em; letter-spacing: 0.05em;
} }
@@ -404,7 +403,7 @@
.chart-stage { .chart-stage {
position: relative; position: relative;
block-size: clamp(6.4rem, 9vw, 8.2rem); block-size: clamp(12rem, 15.5vw, 15rem);
overflow: hidden; overflow: hidden;
border: 1px solid rgb(var(--hud-border-strong-rgb) / 0.32); border: 1px solid rgb(var(--hud-border-strong-rgb) / 0.32);
border-radius: 0.62rem; border-radius: 0.62rem;
@@ -444,8 +443,8 @@
.axis-label { .axis-label {
fill: rgb(var(--hud-text-main-rgb) / 0.88); fill: rgb(var(--hud-text-main-rgb) / 0.88);
font-size: 2.8px; font-size: 3.2px;
font-weight: 500; font-weight: 600;
letter-spacing: 0.02em; letter-spacing: 0.02em;
text-shadow: text-shadow:
0 1px 0 rgb(0 0 0 / 0.46), 0 1px 0 rgb(0 0 0 / 0.46),
@@ -487,7 +486,7 @@
align-items: center; align-items: center;
gap: 0.28rem; gap: 0.28rem;
color: rgb(var(--hud-text-main-rgb) / 0.9); color: rgb(var(--hud-text-main-rgb) / 0.9);
font-size: 0.62rem; font-size: 0.76rem;
letter-spacing: 0.04em; letter-spacing: 0.04em;
} }
@@ -520,28 +519,28 @@
@media (max-width: 1180px) { @media (max-width: 1180px) {
.signal-panel { .signal-panel {
inline-size: min(100%, clamp(14rem, 30vw, 17rem)); inline-size: min(100%, clamp(24rem, 36vw, 31rem));
aspect-ratio: 1.5 / 1; aspect-ratio: 1.48 / 1;
min-block-size: 10.1rem; min-block-size: 17rem;
} }
} }
@media (max-height: 900px) { @media (max-height: 900px) {
.signal-panel { .signal-panel {
inline-size: min(100%, clamp(15rem, 22vw, 18.5rem)); inline-size: min(100%, clamp(24rem, 33vw, 30rem));
min-block-size: 10.6rem; min-block-size: 16.8rem;
} }
.chart-stage { .chart-stage {
block-size: clamp(5.7rem, 7.6vw, 6.9rem); block-size: clamp(9.8rem, 12vw, 11.8rem);
} }
} }
@media (max-height: 760px) { @media (max-height: 760px) {
.signal-panel { .signal-panel {
inline-size: min(100%, clamp(13.8rem, 20vw, 16.5rem)); inline-size: min(100%, clamp(21rem, 29vw, 26rem));
min-block-size: 9.8rem; min-block-size: 14.4rem;
padding: 0.46rem 0.5rem 0.5rem; padding: 0.7rem 0.76rem 0.8rem;
} }
.panel-foot { .panel-foot {
@@ -549,15 +548,15 @@
} }
.chart-stage { .chart-stage {
block-size: clamp(5rem, 6.6vw, 6rem); block-size: clamp(8.3rem, 9.6vw, 9.8rem);
} }
} }
@media (max-height: 680px) { @media (max-height: 680px) {
.signal-panel { .signal-panel {
inline-size: min(100%, clamp(12.8rem, 18vw, 15rem)); inline-size: min(100%, clamp(18.5rem, 24vw, 22.5rem));
min-block-size: 8.7rem; min-block-size: 12.4rem;
padding: 0.4rem 0.46rem 0.44rem; padding: 0.62rem 0.66rem 0.68rem;
} }
.panel-head { .panel-head {
@@ -570,7 +569,7 @@
} }
.chart-stage { .chart-stage {
block-size: clamp(4.4rem, 5.6vw, 5.4rem); block-size: clamp(7rem, 7.8vw, 8rem);
} }
} }

View File

@@ -35,17 +35,17 @@ export interface PressureColorPalette {
export const pressureColorPalettes: Record<PressureColorMapPreset, PressureColorPalette> = { export const pressureColorPalettes: Record<PressureColorMapPreset, PressureColorPalette> = {
emerald: { emerald: {
surfaceBase: "#13201a", surfaceBase: "#397557",
surfaceLow: "#285338", surfaceLow: "#24563a",
surfaceMid: "#3f8a66", surfaceMid: "#2f8d78",
surfaceHigh: "#6dd3ad", surfaceHigh: "#62d9cf",
surfaceHot: "#d9fff0", surfaceHot: "#d9fff0",
labelZero: "#2d8d59", labelZero: "#88e3ac",
labelLow: "#54df8e", labelLow: "#52e6a0",
labelMid: "#98e6ff", labelMid: "#5dcfff",
labelHigh: "#ffab78", labelHigh: "#ff5a4f",
rangeStops: ["#13201a", "#285338", "#3f8a66", "#6dd3ad", "#98e6ff", "#ffab78"], rangeStops: ["#397557", "#36c06d", "#59cfff", "#ffd85a", "#ff8d4d", "#ff5247"],
rangeGlow: ["#54df8e", "#98e6ff", "#ffab78"], rangeGlow: ["#52e6a0", "#59cfff", "#ff5247"],
uiTheme: { uiTheme: {
bg00: "#020403", bg00: "#020403",
bg10: "#07100d", bg10: "#07100d",

View File

@@ -21,12 +21,12 @@
--hud-glow-alt-rgb: 133 255 68; --hud-glow-alt-rgb: 133 255 68;
--hud-text-main-rgb: 207 231 255; --hud-text-main-rgb: 207 231 255;
--hud-text-dim-rgb: 134 162 184; --hud-text-dim-rgb: 134 162 184;
--hud-range-0: #13201a; --hud-range-0: #397557;
--hud-range-1: #285338; --hud-range-1: #36c06d;
--hud-range-2: #3f8a66; --hud-range-2: #59cfff;
--hud-range-3: #6dd3ad; --hud-range-3: #ffd85a;
--hud-range-4: #98e6ff; --hud-range-4: #ff8d4d;
--hud-range-5: #ffab78; --hud-range-5: #ff5247;
--hud-text-main: #cfe7ff; --hud-text-main: #cfe7ff;
--hud-text-dim: #86a2b8; --hud-text-dim: #86a2b8;

View File

@@ -9,6 +9,7 @@ export type HudNoticeTone = "ok" | "warn" | "info";
export type SignalTone = "cyan" | "lime" | "orange" | "violet" | "gold" | "rose"; export type SignalTone = "cyan" | "lime" | "orange" | "violet" | "gold" | "rose";
export type PressureColorMapPreset = "emerald" | "arctic" | "ember"; export type PressureColorMapPreset = "emerald" | "arctic" | "ember";
export type MatrixDisplayMode = "numeric" | "dots";
export type SignalPanelSide = "left" | "right"; export type SignalPanelSide = "left" | "right";
@@ -82,6 +83,9 @@ export interface HudCopy {
rangeMinLabel: string; rangeMinLabel: string;
rangeMaxLabel: string; rangeMaxLabel: string;
colorMapLabel: string; colorMapLabel: string;
matrixViewLabel: string;
matrixViewNumericLabel: string;
matrixViewDotsLabel: string;
resetConfigLabel: string; resetConfigLabel: string;
applyLiveHint: string; applyLiveHint: string;
runtimeReady: string; runtimeReady: string;
@@ -131,6 +135,7 @@ export interface HudMatrixConfig {
rangeMin: number; rangeMin: number;
rangeMax: number; rangeMax: number;
colorMapPreset: PressureColorMapPreset; colorMapPreset: PressureColorMapPreset;
matrixDisplayMode: MatrixDisplayMode;
} }
export interface SerialConnectResult { export interface SerialConnectResult {

Some files were not shown because too many files have changed in this diff Show More