diff --git a/build/icon-preview.png b/build/icon-preview.png
index aa38ef2..f6a8540 100644
Binary files a/build/icon-preview.png and b/build/icon-preview.png differ
diff --git a/build/icon.ico b/build/icon.ico
index 36acc48..32591f7 100644
Binary files a/build/icon.ico and b/build/icon.ico differ
diff --git a/build/icon.png b/build/icon.png
index 85562e4..761769a 100644
Binary files a/build/icon.png and b/build/icon.png differ
diff --git a/build/sizes/icon-1024.png b/build/sizes/icon-1024.png
index 85562e4..761769a 100644
Binary files a/build/sizes/icon-1024.png and b/build/sizes/icon-1024.png differ
diff --git a/build/sizes/icon-128.png b/build/sizes/icon-128.png
index 2716969..04b430f 100644
Binary files a/build/sizes/icon-128.png and b/build/sizes/icon-128.png differ
diff --git a/build/sizes/icon-144.png b/build/sizes/icon-144.png
new file mode 100644
index 0000000..c23b145
Binary files /dev/null and b/build/sizes/icon-144.png differ
diff --git a/build/sizes/icon-16.png b/build/sizes/icon-16.png
index 0edf8da..9c7ca58 100644
Binary files a/build/sizes/icon-16.png and b/build/sizes/icon-16.png differ
diff --git a/build/sizes/icon-180.png b/build/sizes/icon-180.png
index 64961a9..f93f54f 100644
Binary files a/build/sizes/icon-180.png and b/build/sizes/icon-180.png differ
diff --git a/build/sizes/icon-192.png b/build/sizes/icon-192.png
new file mode 100644
index 0000000..ac81ee7
Binary files /dev/null and b/build/sizes/icon-192.png differ
diff --git a/build/sizes/icon-20.png b/build/sizes/icon-20.png
index 7ca55da..30a16ed 100644
Binary files a/build/sizes/icon-20.png and b/build/sizes/icon-20.png differ
diff --git a/build/sizes/icon-24.png b/build/sizes/icon-24.png
index 3f0e5a0..45df055 100644
Binary files a/build/sizes/icon-24.png and b/build/sizes/icon-24.png differ
diff --git a/build/sizes/icon-256.png b/build/sizes/icon-256.png
index b928f66..17be2c7 100644
Binary files a/build/sizes/icon-256.png and b/build/sizes/icon-256.png differ
diff --git a/build/sizes/icon-30.png b/build/sizes/icon-30.png
new file mode 100644
index 0000000..715ebda
Binary files /dev/null and b/build/sizes/icon-30.png differ
diff --git a/build/sizes/icon-32.png b/build/sizes/icon-32.png
index c5521df..62ff3c1 100644
Binary files a/build/sizes/icon-32.png and b/build/sizes/icon-32.png differ
diff --git a/build/sizes/icon-36.png b/build/sizes/icon-36.png
new file mode 100644
index 0000000..b9dbfd0
Binary files /dev/null and b/build/sizes/icon-36.png differ
diff --git a/build/sizes/icon-384.png b/build/sizes/icon-384.png
new file mode 100644
index 0000000..8b0255a
Binary files /dev/null and b/build/sizes/icon-384.png differ
diff --git a/build/sizes/icon-40.png b/build/sizes/icon-40.png
index 90a0dca..432bfb8 100644
Binary files a/build/sizes/icon-40.png and b/build/sizes/icon-40.png differ
diff --git a/build/sizes/icon-48.png b/build/sizes/icon-48.png
index 27c4ac0..eadcc93 100644
Binary files a/build/sizes/icon-48.png and b/build/sizes/icon-48.png differ
diff --git a/build/sizes/icon-512.png b/build/sizes/icon-512.png
index b1adaa7..f4c8533 100644
Binary files a/build/sizes/icon-512.png and b/build/sizes/icon-512.png differ
diff --git a/build/sizes/icon-60.png b/build/sizes/icon-60.png
new file mode 100644
index 0000000..ce43836
Binary files /dev/null and b/build/sizes/icon-60.png differ
diff --git a/build/sizes/icon-64.png b/build/sizes/icon-64.png
index 7735cc4..d428613 100644
Binary files a/build/sizes/icon-64.png and b/build/sizes/icon-64.png differ
diff --git a/build/sizes/icon-72.png b/build/sizes/icon-72.png
new file mode 100644
index 0000000..85d9e2d
Binary files /dev/null and b/build/sizes/icon-72.png differ
diff --git a/build/sizes/icon-768.png b/build/sizes/icon-768.png
new file mode 100644
index 0000000..0778820
Binary files /dev/null and b/build/sizes/icon-768.png differ
diff --git a/build/sizes/icon-80.png b/build/sizes/icon-80.png
new file mode 100644
index 0000000..56cc84f
Binary files /dev/null and b/build/sizes/icon-80.png differ
diff --git a/build/sizes/icon-96.png b/build/sizes/icon-96.png
index 625a18e..9140e26 100644
Binary files a/build/sizes/icon-96.png and b/build/sizes/icon-96.png differ
diff --git a/resources/branding/README.zh-CN.txt b/resources/branding/README.zh-CN.txt
new file mode 100644
index 0000000..246c8d2
--- /dev/null
+++ b/resources/branding/README.zh-CN.txt
@@ -0,0 +1,47 @@
+Ycode 软件图标资源包
+==================
+
+采用版本
+--------
+本包采用“朝你举手的象牙精灵.png”,即用户指定的大圆脸、身体饱满、举手末端圆润的原版。
+原始图片为 1254 × 1254 像素;所有尺寸均由同一原图导出,没有重新生成角色。
+
+快速使用
+--------
+Windows 应用、可执行文件和安装程序:windows/ycode.ico
+软件界面、侧边栏、关于页:按显示尺寸选择 png/ycode-尺寸.png
+Windows 托盘:按实际 DPI 和所用框架选择 16、20、24、32、40、48 或 64 像素 PNG。
+网页标签页:web/favicon.ico,也可使用 web/favicon-16.png、favicon-32.png。
+网页或 PWA 常用图片:web/icon-192.png、web/icon-512.png。
+网页图片使用现有红色圆角底板;未声明为可任意裁切的 maskable 图标。
+
+尺寸清单
+--------
+PNG(均为正方形,文件名数字即边长):
+16、20、24、30、32、36、40、48、60、64、72、80、96、128、144、180、192、256、384、512、768、1024。
+
+Windows ICO 实际内嵌 15 个尺寸:
+16、20、24、30、32、36、40、48、60、64、72、80、96、128、256。
+
+favicon.ico 实际内嵌 3 个尺寸:16、32、48。
+
+文件目录
+--------
+png/ 多尺寸 RGBA PNG
+windows/ Windows 多尺寸应用图标
+web/ favicon 与网页常用 PNG
+source/ 1254 像素原图及导出母图
+Ycode-Icon-Preview.png 浅色/深色背景和小尺寸预览
+manifest.json 尺寸、格式及导出信息
+checksums.sha256 包内文件校验值
+
+导出说明
+--------
+PNG 保留红色圆角底板,底板外部透明,精灵为奶白色。
+导出母图与所选原图逐字节一致,保留原始 RGBA、颜色、姿态、比例和画布尺寸。
+本包只进行尺寸缩放和格式封装,没有再次生成、重绘、瘦身、改变表情或修改光影。
+每个 PNG 从 1254 像素导出母图直接缩小,不逐级缩放,不放大低分辨率图片。
+所有 PNG 为 RGBA;ICO 已逐层检查尺寸与像素。
+这些是图形资源文件。应用图标如何绑定到窗口、任务栏和安装包,请按项目实际框架配置。
+
+生成日期:2026-10-21
diff --git a/resources/branding/Ycode-Icon-Preview.png b/resources/branding/Ycode-Icon-Preview.png
new file mode 100644
index 0000000..f6a8540
Binary files /dev/null and b/resources/branding/Ycode-Icon-Preview.png differ
diff --git a/resources/branding/checksums.sha256 b/resources/branding/checksums.sha256
new file mode 100644
index 0000000..c35529b
--- /dev/null
+++ b/resources/branding/checksums.sha256
@@ -0,0 +1,33 @@
+337104a95c7796e5d596ce1d263be5e134380c263251d2c5768de089eba8e06e README.zh-CN.txt
+58896c8593d7cf424c0f175b1c01c606abeafbce8088be6b54eeac0c3ea17260 Ycode-Icon-Preview.png
+39cb370f4097e48e93a1ed98711ef392fc62bbc38d1f2d0ad5745cd66a93374c manifest.json
+b3bfc76d637c4e7fef5c0655079736940b8a560ec19195d25585bd2eaf4a5794 png/ycode-1024.png
+e3656c1694b3264f4e402b938e447b4ef4ade36dee5970a0add4530c51b6ce73 png/ycode-128.png
+ab7cac48cae4959d37b27aa495bd183e7da1dea460c66b2e040bd1a521156dd0 png/ycode-144.png
+17813635b4ebdb738aaf488e9cd90fed8075852b0b4959756498a8cffe828578 png/ycode-16.png
+72cb2126929685153b2973185630599f703fcfcaba3cfe999da2b6e3f07588f4 png/ycode-180.png
+268ec5dacee26dfa8472f2ef22e378e9bd077632106e8f999e8fc498bffe3e3b png/ycode-192.png
+b03f6b2c0cb87d8a4e4dec41e815008bb095d386e83c6d41842a92511c95f920 png/ycode-20.png
+b0ebfd3208863cd673ba156918395e7cc1b553ec3c52b9b4188e03b4e2cdac9f png/ycode-24.png
+79af56168bd46ab0a27c203bb7e26ea54fe34ce4b051115927f30b0f15cc9c08 png/ycode-256.png
+973c76202c110552b8dd19121a155d4200b279382909920d52fbf627149b3d4c png/ycode-30.png
+9f0aa8db122580dbd444d13451619ca2f67ab000013a7ef798eae3c5a79bf0eb png/ycode-32.png
+ccd924280b414e3bd29efe94caf94940554bf2f4b45c513d470ddf4769f5eb89 png/ycode-36.png
+d829d21c7705d7cb1e1203235b326a735cc96b576bf9a84f39f304cf839b2b52 png/ycode-384.png
+5e88346739baebbdf9952172e7adb7ef2e740dc580a95f3961ff67721fd23c7b png/ycode-40.png
+b19031f7aa9d1c5f3e6bc5cbf7fc4586fca785e3a89d07178a010ea1fbf0df0c png/ycode-48.png
+644c0d02e98af33d0d082eb8e980fce2ff4550c40e8727ffd17141d3eccf34e7 png/ycode-512.png
+36c1e2562e3df995309cc17b4d16e36e0bfee6537907c312d50057a7c298e81c png/ycode-60.png
+d7f98cf5dd8ec229cb11c5a4fb8d5a644699961bbfea2fcfd13232e5358b9e5b png/ycode-64.png
+033c89b3e2b9e90d1216ebf3dc5b8fe6be0f582b0a289e8e3c2d6b21cfa94a28 png/ycode-72.png
+bf1b1d1f3b1e8ea345e6c58b8cade7c43fe230a5a8fb6895eb7f470259906015 png/ycode-768.png
+b0043bca0aa1436f7ae18ed88812ddbb7db1b5f4f87bc8a21333f571cc31ae05 png/ycode-80.png
+3275f804551df785f10948af0bbc47a6fd98d0decf14d820443e87e0f3528fc4 png/ycode-96.png
+ef6dcd133be5e19654d66408875e8d08a10cca6fd066edde3c25b58d05e97e98 source/ycode-approved-original-1254.png
+ef6dcd133be5e19654d66408875e8d08a10cca6fd066edde3c25b58d05e97e98 source/ycode-export-master-1254.png
+17813635b4ebdb738aaf488e9cd90fed8075852b0b4959756498a8cffe828578 web/favicon-16.png
+9f0aa8db122580dbd444d13451619ca2f67ab000013a7ef798eae3c5a79bf0eb web/favicon-32.png
+9f8b5bb578e08763389cf824f14ac1213149cbdeb7a8fad7f31926d2fc6f3e94 web/favicon.ico
+268ec5dacee26dfa8472f2ef22e378e9bd077632106e8f999e8fc498bffe3e3b web/icon-192.png
+644c0d02e98af33d0d082eb8e980fce2ff4550c40e8727ffd17141d3eccf34e7 web/icon-512.png
+363e95118364550d34d9c2f268f8d8032e400cf4ebdf4594183c643fbf5ac466 windows/ycode.ico
diff --git a/resources/branding/manifest.json b/resources/branding/manifest.json
new file mode 100644
index 0000000..e7fe658
--- /dev/null
+++ b/resources/branding/manifest.json
@@ -0,0 +1,205 @@
+{
+ "product": "Ycode",
+ "asset_version": "rounded-original-v1",
+ "created_date": "2026-10-21",
+ "source_filename": "朝你举手的象牙精灵.png",
+ "source_dimensions": [
+ 1254,
+ 1254
+ ],
+ "source_sha256": "ef6dcd133be5e19654d66408875e8d08a10cca6fd066edde3c25b58d05e97e98",
+ "png_sizes": [
+ 16,
+ 20,
+ 24,
+ 30,
+ 32,
+ 36,
+ 40,
+ 48,
+ 60,
+ 64,
+ 72,
+ 80,
+ 96,
+ 128,
+ 144,
+ 180,
+ 192,
+ 256,
+ 384,
+ 512,
+ 768,
+ 1024
+ ],
+ "png_color_mode": "RGBA",
+ "resize_filter": "Lanczos",
+ "upscaled": false,
+ "alpha_cleanup": {
+ "applied": false,
+ "changed_pixels": 0,
+ "visible_artwork_changed": false
+ },
+ "ico_files": [
+ {
+ "path": "windows/ycode.ico",
+ "sizes": [
+ 16,
+ 20,
+ 24,
+ 30,
+ 32,
+ 36,
+ 40,
+ 48,
+ 60,
+ 64,
+ 72,
+ 80,
+ 96,
+ 128,
+ 256
+ ],
+ "verified_pixel_exact": true
+ },
+ {
+ "path": "web/favicon.ico",
+ "sizes": [
+ 16,
+ 32,
+ 48
+ ],
+ "verified_pixel_exact": true
+ }
+ ],
+ "files": [
+ {
+ "path": "README.zh-CN.txt",
+ "bytes": 2175
+ },
+ {
+ "path": "Ycode-Icon-Preview.png",
+ "bytes": 297731
+ },
+ {
+ "path": "png/ycode-1024.png",
+ "bytes": 908586
+ },
+ {
+ "path": "png/ycode-128.png",
+ "bytes": 21738
+ },
+ {
+ "path": "png/ycode-144.png",
+ "bytes": 26190
+ },
+ {
+ "path": "png/ycode-16.png",
+ "bytes": 867
+ },
+ {
+ "path": "png/ycode-180.png",
+ "bytes": 37070
+ },
+ {
+ "path": "png/ycode-192.png",
+ "bytes": 40637
+ },
+ {
+ "path": "png/ycode-20.png",
+ "bytes": 1212
+ },
+ {
+ "path": "png/ycode-24.png",
+ "bytes": 1609
+ },
+ {
+ "path": "png/ycode-256.png",
+ "bytes": 65372
+ },
+ {
+ "path": "png/ycode-30.png",
+ "bytes": 2280
+ },
+ {
+ "path": "png/ycode-32.png",
+ "bytes": 2416
+ },
+ {
+ "path": "png/ycode-36.png",
+ "bytes": 2940
+ },
+ {
+ "path": "png/ycode-384.png",
+ "bytes": 135503
+ },
+ {
+ "path": "png/ycode-40.png",
+ "bytes": 3421
+ },
+ {
+ "path": "png/ycode-48.png",
+ "bytes": 4625
+ },
+ {
+ "path": "png/ycode-512.png",
+ "bytes": 234020
+ },
+ {
+ "path": "png/ycode-60.png",
+ "bytes": 6477
+ },
+ {
+ "path": "png/ycode-64.png",
+ "bytes": 7193
+ },
+ {
+ "path": "png/ycode-72.png",
+ "bytes": 8704
+ },
+ {
+ "path": "png/ycode-768.png",
+ "bytes": 520390
+ },
+ {
+ "path": "png/ycode-80.png",
+ "bytes": 10435
+ },
+ {
+ "path": "png/ycode-96.png",
+ "bytes": 13750
+ },
+ {
+ "path": "source/ycode-approved-original-1254.png",
+ "bytes": 1702366
+ },
+ {
+ "path": "source/ycode-export-master-1254.png",
+ "bytes": 1702366
+ },
+ {
+ "path": "web/favicon-16.png",
+ "bytes": 867
+ },
+ {
+ "path": "web/favicon-32.png",
+ "bytes": 2416
+ },
+ {
+ "path": "web/favicon.ico",
+ "bytes": 15086
+ },
+ {
+ "path": "web/icon-192.png",
+ "bytes": 40637
+ },
+ {
+ "path": "web/icon-512.png",
+ "bytes": 234020
+ },
+ {
+ "path": "windows/ycode.ico",
+ "bytes": 289599
+ }
+ ]
+}
diff --git a/resources/branding/png/ycode-1024.png b/resources/branding/png/ycode-1024.png
new file mode 100644
index 0000000..761769a
Binary files /dev/null and b/resources/branding/png/ycode-1024.png differ
diff --git a/resources/branding/png/ycode-128.png b/resources/branding/png/ycode-128.png
new file mode 100644
index 0000000..04b430f
Binary files /dev/null and b/resources/branding/png/ycode-128.png differ
diff --git a/resources/branding/png/ycode-144.png b/resources/branding/png/ycode-144.png
new file mode 100644
index 0000000..c23b145
Binary files /dev/null and b/resources/branding/png/ycode-144.png differ
diff --git a/resources/branding/png/ycode-16.png b/resources/branding/png/ycode-16.png
new file mode 100644
index 0000000..9c7ca58
Binary files /dev/null and b/resources/branding/png/ycode-16.png differ
diff --git a/resources/branding/png/ycode-180.png b/resources/branding/png/ycode-180.png
new file mode 100644
index 0000000..f93f54f
Binary files /dev/null and b/resources/branding/png/ycode-180.png differ
diff --git a/resources/branding/png/ycode-192.png b/resources/branding/png/ycode-192.png
new file mode 100644
index 0000000..ac81ee7
Binary files /dev/null and b/resources/branding/png/ycode-192.png differ
diff --git a/resources/branding/png/ycode-20.png b/resources/branding/png/ycode-20.png
new file mode 100644
index 0000000..30a16ed
Binary files /dev/null and b/resources/branding/png/ycode-20.png differ
diff --git a/resources/branding/png/ycode-24.png b/resources/branding/png/ycode-24.png
new file mode 100644
index 0000000..45df055
Binary files /dev/null and b/resources/branding/png/ycode-24.png differ
diff --git a/resources/branding/png/ycode-256.png b/resources/branding/png/ycode-256.png
new file mode 100644
index 0000000..17be2c7
Binary files /dev/null and b/resources/branding/png/ycode-256.png differ
diff --git a/resources/branding/png/ycode-30.png b/resources/branding/png/ycode-30.png
new file mode 100644
index 0000000..715ebda
Binary files /dev/null and b/resources/branding/png/ycode-30.png differ
diff --git a/resources/branding/png/ycode-32.png b/resources/branding/png/ycode-32.png
new file mode 100644
index 0000000..62ff3c1
Binary files /dev/null and b/resources/branding/png/ycode-32.png differ
diff --git a/resources/branding/png/ycode-36.png b/resources/branding/png/ycode-36.png
new file mode 100644
index 0000000..b9dbfd0
Binary files /dev/null and b/resources/branding/png/ycode-36.png differ
diff --git a/resources/branding/png/ycode-384.png b/resources/branding/png/ycode-384.png
new file mode 100644
index 0000000..8b0255a
Binary files /dev/null and b/resources/branding/png/ycode-384.png differ
diff --git a/resources/branding/png/ycode-40.png b/resources/branding/png/ycode-40.png
new file mode 100644
index 0000000..432bfb8
Binary files /dev/null and b/resources/branding/png/ycode-40.png differ
diff --git a/resources/branding/png/ycode-48.png b/resources/branding/png/ycode-48.png
new file mode 100644
index 0000000..eadcc93
Binary files /dev/null and b/resources/branding/png/ycode-48.png differ
diff --git a/resources/branding/png/ycode-512.png b/resources/branding/png/ycode-512.png
new file mode 100644
index 0000000..f4c8533
Binary files /dev/null and b/resources/branding/png/ycode-512.png differ
diff --git a/resources/branding/png/ycode-60.png b/resources/branding/png/ycode-60.png
new file mode 100644
index 0000000..ce43836
Binary files /dev/null and b/resources/branding/png/ycode-60.png differ
diff --git a/resources/branding/png/ycode-64.png b/resources/branding/png/ycode-64.png
new file mode 100644
index 0000000..d428613
Binary files /dev/null and b/resources/branding/png/ycode-64.png differ
diff --git a/resources/branding/png/ycode-72.png b/resources/branding/png/ycode-72.png
new file mode 100644
index 0000000..85d9e2d
Binary files /dev/null and b/resources/branding/png/ycode-72.png differ
diff --git a/resources/branding/png/ycode-768.png b/resources/branding/png/ycode-768.png
new file mode 100644
index 0000000..0778820
Binary files /dev/null and b/resources/branding/png/ycode-768.png differ
diff --git a/resources/branding/png/ycode-80.png b/resources/branding/png/ycode-80.png
new file mode 100644
index 0000000..56cc84f
Binary files /dev/null and b/resources/branding/png/ycode-80.png differ
diff --git a/resources/branding/png/ycode-96.png b/resources/branding/png/ycode-96.png
new file mode 100644
index 0000000..9140e26
Binary files /dev/null and b/resources/branding/png/ycode-96.png differ
diff --git a/resources/branding/source/ycode-approved-original-1254.png b/resources/branding/source/ycode-approved-original-1254.png
new file mode 100644
index 0000000..7d1c9f2
Binary files /dev/null and b/resources/branding/source/ycode-approved-original-1254.png differ
diff --git a/resources/branding/source/ycode-export-master-1254.png b/resources/branding/source/ycode-export-master-1254.png
new file mode 100644
index 0000000..7d1c9f2
Binary files /dev/null and b/resources/branding/source/ycode-export-master-1254.png differ
diff --git a/resources/branding/web/favicon-16.png b/resources/branding/web/favicon-16.png
new file mode 100644
index 0000000..9c7ca58
Binary files /dev/null and b/resources/branding/web/favicon-16.png differ
diff --git a/resources/branding/web/favicon-32.png b/resources/branding/web/favicon-32.png
new file mode 100644
index 0000000..62ff3c1
Binary files /dev/null and b/resources/branding/web/favicon-32.png differ
diff --git a/resources/branding/web/favicon.ico b/resources/branding/web/favicon.ico
new file mode 100644
index 0000000..40f2821
Binary files /dev/null and b/resources/branding/web/favicon.ico differ
diff --git a/resources/branding/web/icon-192.png b/resources/branding/web/icon-192.png
new file mode 100644
index 0000000..ac81ee7
Binary files /dev/null and b/resources/branding/web/icon-192.png differ
diff --git a/resources/branding/web/icon-512.png b/resources/branding/web/icon-512.png
new file mode 100644
index 0000000..f4c8533
Binary files /dev/null and b/resources/branding/web/icon-512.png differ
diff --git a/resources/branding/windows/ycode.ico b/resources/branding/windows/ycode.ico
new file mode 100644
index 0000000..32591f7
Binary files /dev/null and b/resources/branding/windows/ycode.ico differ
diff --git a/resources/icon.png b/resources/icon.png
index b1adaa7..f4c8533 100644
Binary files a/resources/icon.png and b/resources/icon.png differ
diff --git a/resources/tray.png b/resources/tray.png
index c5521df..62ff3c1 100644
Binary files a/resources/tray.png and b/resources/tray.png differ
diff --git a/scripts/gen-icon.mjs b/scripts/gen-icon.mjs
index 7b49d7c..4ce006a 100644
--- a/scripts/gen-icon.mjs
+++ b/scripts/gen-icon.mjs
@@ -1,115 +1,32 @@
/**
- * 生成 YCode 应用图标资产。
- *
- * 输入:build/icon.svg(唯一矢量源)
- * 输出:build/icon.ico、build/icon.png、resources/icon.png、build/icon-preview.png
- *
- * 图案是深红旗面 + 按国旗制式排布的五颗金星(一大四小,3:1),
- * 星群坐标由 scripts/star-layout.mjs 算出,这里只负责栅格化与打包。
- *
+ * 从已确认的图标包同步 YCode 应用图标,不重新绘制或缩放原图。
+ * 输入:resources/branding/(原图、各尺寸 PNG、Windows ICO 和预览)
* 用法:node scripts/gen-icon.mjs
*/
-import { Resvg } from '@resvg/resvg-js'
-import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
+import { copyFileSync, mkdirSync, readdirSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const root = join(dirname(fileURLToPath(import.meta.url)), '..')
-const buildDir = join(root, 'build')
-const resourcesDir = join(root, 'resources')
+const packDir = join(root, 'resources', 'branding')
-const masterSvg = readFileSync(join(buildDir, 'icon.svg'), 'utf8')
-
-const ICO_SIZES = [16, 24, 32, 48, 64, 128, 256]
-
-function render(svg, size) {
- return new Resvg(svg, { fitTo: { mode: 'width', value: size } }).render().asPng()
+function copy(source, destination) {
+ const target = join(root, destination)
+ mkdirSync(dirname(target), { recursive: true })
+ copyFileSync(join(packDir, source), target)
}
-function pick() {
- return masterSvg
+copy('windows/ycode.ico', 'build/icon.ico')
+copy('png/ycode-1024.png', 'build/icon.png')
+copy('png/ycode-512.png', 'resources/icon.png')
+copy('png/ycode-32.png', 'resources/tray.png')
+copy('Ycode-Icon-Preview.png', 'build/icon-preview.png')
+copy('png/ycode-128.png', 'src/renderer/src/assets/ycode.png')
+copy('web/favicon.ico', 'src/renderer/public/favicon.ico')
+
+for (const filename of readdirSync(join(packDir, 'png'))) {
+ const match = /^ycode-(\d+)\.png$/.exec(filename)
+ if (match) copy(`png/${filename}`, `build/sizes/icon-${match[1]}.png`)
}
-/** 组装 Windows ICO:每个尺寸内嵌一张 PNG(Vista 及以后支持)。 */
-function buildIco(entries) {
- const header = Buffer.alloc(6)
- header.writeUInt16LE(0, 0)
- header.writeUInt16LE(1, 2)
- header.writeUInt16LE(entries.length, 4)
-
- const dirEntries = []
- let offset = 6 + 16 * entries.length
- for (const { size, png } of entries) {
- const entry = Buffer.alloc(16)
- entry.writeUInt8(size >= 256 ? 0 : size, 0)
- entry.writeUInt8(size >= 256 ? 0 : size, 1)
- entry.writeUInt8(0, 2)
- entry.writeUInt8(0, 3)
- entry.writeUInt16LE(1, 4)
- entry.writeUInt16LE(32, 6)
- entry.writeUInt32LE(png.length, 8)
- entry.writeUInt32LE(offset, 12)
- offset += png.length
- dirEntries.push(entry)
- }
-
- return Buffer.concat([header, ...dirEntries, ...entries.map((e) => e.png)])
-}
-
-mkdirSync(resourcesDir, { recursive: true })
-
-const icoEntries = ICO_SIZES.map((size) => ({ size, png: render(pick(), size) }))
-writeFileSync(join(buildDir, 'icon.ico'), buildIco(icoEntries))
-
-writeFileSync(join(buildDir, 'icon.png'), render(masterSvg, 1024))
-writeFileSync(join(resourcesDir, 'icon.png'), render(masterSvg, 512))
-// 托盘:Windows 通知区域按 16/20/24/32 取用,给 32px 让系统自行缩放
-writeFileSync(join(resourcesDir, 'tray.png'), render(masterSvg, 32))
-
-// 备用图:常用尺寸各出一张 PNG,供托盘、商店页、文档等场景直接取用
-const PNG_SIZES = [16, 20, 24, 32, 40, 48, 64, 96, 128, 180, 256, 512, 1024]
-const sizesDir = join(buildDir, 'sizes')
-mkdirSync(sizesDir, { recursive: true })
-for (const size of PNG_SIZES) {
- writeFileSync(join(sizesDir, `icon-${size}.png`), render(pick(), size))
-}
-
-// 对照表:浅色与深色背景下,各尺寸的真实观感
-const sampleSizes = [128, 64, 48, 32, 16]
-function tile(size) {
- return render(pick(), size).toString('base64')
-}
-const rows = [
- { label: '浅色任务栏', bg: '#FFFFFF', fg: '#475467' },
- { label: '深色任务栏', bg: '#202124', fg: '#D0D5DD' }
-]
-let y = 78
-const rowSvg = rows
- .map((row) => {
- let x = 150
- const imgs = sampleSizes
- .map((size) => {
- const markup = `