various bundle optimizations (#1549)

* fix: missing "@element-plus/icons-vue" dependency

* fix: update vite (40% faster builds)

* fix: don't include sentry in non-nightly builds

* fix: swap to variable fonts & don't include font files in repo

* fix: lazy load languages to not keep them in memory

* nit: revert vite to stable

* nit: retain `.json` message files in bundle

* nit: remove bundle analyzer

* fix: availableLocales does not include unloaded locales
This commit is contained in:
Aries
2026-01-03 23:51:00 -07:00
committed by GitHub
parent 327e7d9b58
commit b02d287190
38 changed files with 574 additions and 619 deletions

View File

@@ -29,6 +29,8 @@ export default defineConfig([
AssetBundleManager: 'readonly', AssetBundleManager: 'readonly',
WINDOWS: 'readonly', WINDOWS: 'readonly',
LINUX: 'readonly', LINUX: 'readonly',
VERSION: 'readonly',
NIGHTLY: 'readonly',
webApiService: 'readonly', webApiService: 'readonly',
process: 'readonly' process: 'readonly'
} }

450
package-lock.json generated
View File

@@ -7,13 +7,18 @@
"name": "VRCX", "name": "VRCX",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fontsource-variable/inter": "^5.2.8",
"hazardous": "^0.3.0", "hazardous": "^0.3.0",
"node-api-dotnet": "^0.9.18" "node-api-dotnet": "^0.9.18"
}, },
"devDependencies": { "devDependencies": {
"@electron/rebuild": "^4.0.2", "@electron/rebuild": "^4.0.2",
"@element-plus/icons-vue": "^2.3.2",
"@eslint/js": "^9.39.2", "@eslint/js": "^9.39.2",
"@fontsource-variable/inter": "^5.2.8",
"@fontsource-variable/noto-sans-jp": "^5.2.9",
"@fontsource-variable/noto-sans-kr": "^5.2.9",
"@fontsource-variable/noto-sans-sc": "^5.2.9",
"@fontsource-variable/noto-sans-tc": "^5.2.9",
"@kamiya4047/eslint-plugin-pretty-import": "^0.1.6", "@kamiya4047/eslint-plugin-pretty-import": "^0.1.6",
"@sentry/vite-plugin": "^4.6.1", "@sentry/vite-plugin": "^4.6.1",
"@sentry/vue": "^10.32.1", "@sentry/vue": "^10.32.1",
@@ -1568,9 +1573,9 @@
} }
}, },
"node_modules/@electron/windows-sign/node_modules/fs-extra": { "node_modules/@electron/windows-sign/node_modules/fs-extra": {
"version": "11.3.2", "version": "11.3.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz",
"integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@@ -1684,9 +1689,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
"integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -1701,9 +1706,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
"integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1718,9 +1723,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
"integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1735,9 +1740,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
"integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1752,9 +1757,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
"integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1769,9 +1774,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
"integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1786,9 +1791,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
"integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1803,9 +1808,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
"integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1820,9 +1825,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
"integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1837,9 +1842,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
"integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1854,9 +1859,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
"integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -1871,9 +1876,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
"integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -1888,9 +1893,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
"integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@@ -1905,9 +1910,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
"integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -1922,9 +1927,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
"integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -1939,9 +1944,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
"integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -1956,9 +1961,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
"integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==", "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1973,9 +1978,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-arm64": { "node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
"integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1990,9 +1995,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
"integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2007,9 +2012,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-arm64": { "node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
"integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2024,9 +2029,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
"integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2041,9 +2046,9 @@
} }
}, },
"node_modules/@esbuild/openharmony-arm64": { "node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
"integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2058,9 +2063,9 @@
} }
}, },
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
"integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2075,9 +2080,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
"integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2092,9 +2097,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
"integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -2109,9 +2114,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
"integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2340,6 +2345,47 @@
"version": "5.2.8", "version": "5.2.8",
"resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz", "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz",
"integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==", "integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==",
"dev": true,
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource-variable/noto-sans-jp": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-jp/-/noto-sans-jp-5.2.9.tgz",
"integrity": "sha512-osPL5f7dvGDjuMuFwDTGPLG37030D8X5zk+3BWea6txAVDFeE/ZIrKW0DY0uSDfRn9+NiKbiFn/2QvZveKXTog==",
"dev": true,
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource-variable/noto-sans-kr": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-kr/-/noto-sans-kr-5.2.9.tgz",
"integrity": "sha512-g1BnJdJbnAgRUP8YxyPIm8npZVUbtt6VgtLnkGR7poa/RVbVGd27i+9138DmwRvtbKhJG1fPLQ/V3BonvFykRQ==",
"dev": true,
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource-variable/noto-sans-sc": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-sc/-/noto-sans-sc-5.2.9.tgz",
"integrity": "sha512-ZEEpZlxjYEIVdg85K38mqaoeBcorrN3Z6MaIkwK5w5Dqn/e9v5uVIYr0ukoLsFxaVyEXSi/c3caOeMHjbOMtfA==",
"dev": true,
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource-variable/noto-sans-tc": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-tc/-/noto-sans-tc-5.2.9.tgz",
"integrity": "sha512-GhtbSE8IZTP3vZj7Fu1G/PERxguMe3jryAbHovSd22Rs7aYdbXQD8vBqkTT/tkHIUn6t2IFReTfgKUoQBPCe+w==",
"dev": true,
"license": "OFL-1.1", "license": "OFL-1.1",
"funding": { "funding": {
"url": "https://github.com/sponsors/ayuhito" "url": "https://github.com/sponsors/ayuhito"
@@ -4407,9 +4453,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz",
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -4421,9 +4467,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz",
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4435,9 +4481,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz",
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4449,9 +4495,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz",
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -4463,9 +4509,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz",
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4477,9 +4523,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz",
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -4491,9 +4537,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz",
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -4505,9 +4551,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz",
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -4519,9 +4565,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz",
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4533,9 +4579,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz",
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4547,9 +4593,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loong64-gnu": { "node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz",
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -4561,9 +4607,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-ppc64-gnu": { "node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz",
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -4575,9 +4621,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz",
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -4589,9 +4635,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-musl": { "node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz",
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -4603,9 +4649,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz",
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -4617,9 +4663,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz",
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -4631,9 +4677,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz",
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -4645,9 +4691,9 @@
] ]
}, },
"node_modules/@rollup/rollup-openharmony-arm64": { "node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz",
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4659,9 +4705,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz",
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -4673,9 +4719,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz",
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -4687,9 +4733,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-gnu": { "node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz",
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -4701,9 +4747,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz",
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -8983,9 +9029,9 @@
"optional": true "optional": true
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.27.1", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
"integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==", "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
@@ -8997,32 +9043,32 @@
"node": ">=18" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.1", "@esbuild/aix-ppc64": "0.27.2",
"@esbuild/android-arm": "0.27.1", "@esbuild/android-arm": "0.27.2",
"@esbuild/android-arm64": "0.27.1", "@esbuild/android-arm64": "0.27.2",
"@esbuild/android-x64": "0.27.1", "@esbuild/android-x64": "0.27.2",
"@esbuild/darwin-arm64": "0.27.1", "@esbuild/darwin-arm64": "0.27.2",
"@esbuild/darwin-x64": "0.27.1", "@esbuild/darwin-x64": "0.27.2",
"@esbuild/freebsd-arm64": "0.27.1", "@esbuild/freebsd-arm64": "0.27.2",
"@esbuild/freebsd-x64": "0.27.1", "@esbuild/freebsd-x64": "0.27.2",
"@esbuild/linux-arm": "0.27.1", "@esbuild/linux-arm": "0.27.2",
"@esbuild/linux-arm64": "0.27.1", "@esbuild/linux-arm64": "0.27.2",
"@esbuild/linux-ia32": "0.27.1", "@esbuild/linux-ia32": "0.27.2",
"@esbuild/linux-loong64": "0.27.1", "@esbuild/linux-loong64": "0.27.2",
"@esbuild/linux-mips64el": "0.27.1", "@esbuild/linux-mips64el": "0.27.2",
"@esbuild/linux-ppc64": "0.27.1", "@esbuild/linux-ppc64": "0.27.2",
"@esbuild/linux-riscv64": "0.27.1", "@esbuild/linux-riscv64": "0.27.2",
"@esbuild/linux-s390x": "0.27.1", "@esbuild/linux-s390x": "0.27.2",
"@esbuild/linux-x64": "0.27.1", "@esbuild/linux-x64": "0.27.2",
"@esbuild/netbsd-arm64": "0.27.1", "@esbuild/netbsd-arm64": "0.27.2",
"@esbuild/netbsd-x64": "0.27.1", "@esbuild/netbsd-x64": "0.27.2",
"@esbuild/openbsd-arm64": "0.27.1", "@esbuild/openbsd-arm64": "0.27.2",
"@esbuild/openbsd-x64": "0.27.1", "@esbuild/openbsd-x64": "0.27.2",
"@esbuild/openharmony-arm64": "0.27.1", "@esbuild/openharmony-arm64": "0.27.2",
"@esbuild/sunos-x64": "0.27.1", "@esbuild/sunos-x64": "0.27.2",
"@esbuild/win32-arm64": "0.27.1", "@esbuild/win32-arm64": "0.27.2",
"@esbuild/win32-ia32": "0.27.1", "@esbuild/win32-ia32": "0.27.2",
"@esbuild/win32-x64": "0.27.1" "@esbuild/win32-x64": "0.27.2"
} }
}, },
"node_modules/esbuild-jest": { "node_modules/esbuild-jest": {
@@ -15749,9 +15795,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.53.3", "version": "4.54.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz",
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -15765,28 +15811,28 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.53.3", "@rollup/rollup-android-arm-eabi": "4.54.0",
"@rollup/rollup-android-arm64": "4.53.3", "@rollup/rollup-android-arm64": "4.54.0",
"@rollup/rollup-darwin-arm64": "4.53.3", "@rollup/rollup-darwin-arm64": "4.54.0",
"@rollup/rollup-darwin-x64": "4.53.3", "@rollup/rollup-darwin-x64": "4.54.0",
"@rollup/rollup-freebsd-arm64": "4.53.3", "@rollup/rollup-freebsd-arm64": "4.54.0",
"@rollup/rollup-freebsd-x64": "4.53.3", "@rollup/rollup-freebsd-x64": "4.54.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.53.3", "@rollup/rollup-linux-arm-gnueabihf": "4.54.0",
"@rollup/rollup-linux-arm-musleabihf": "4.53.3", "@rollup/rollup-linux-arm-musleabihf": "4.54.0",
"@rollup/rollup-linux-arm64-gnu": "4.53.3", "@rollup/rollup-linux-arm64-gnu": "4.54.0",
"@rollup/rollup-linux-arm64-musl": "4.53.3", "@rollup/rollup-linux-arm64-musl": "4.54.0",
"@rollup/rollup-linux-loong64-gnu": "4.53.3", "@rollup/rollup-linux-loong64-gnu": "4.54.0",
"@rollup/rollup-linux-ppc64-gnu": "4.53.3", "@rollup/rollup-linux-ppc64-gnu": "4.54.0",
"@rollup/rollup-linux-riscv64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-gnu": "4.54.0",
"@rollup/rollup-linux-riscv64-musl": "4.53.3", "@rollup/rollup-linux-riscv64-musl": "4.54.0",
"@rollup/rollup-linux-s390x-gnu": "4.53.3", "@rollup/rollup-linux-s390x-gnu": "4.54.0",
"@rollup/rollup-linux-x64-gnu": "4.53.3", "@rollup/rollup-linux-x64-gnu": "4.54.0",
"@rollup/rollup-linux-x64-musl": "4.53.3", "@rollup/rollup-linux-x64-musl": "4.54.0",
"@rollup/rollup-openharmony-arm64": "4.53.3", "@rollup/rollup-openharmony-arm64": "4.54.0",
"@rollup/rollup-win32-arm64-msvc": "4.53.3", "@rollup/rollup-win32-arm64-msvc": "4.54.0",
"@rollup/rollup-win32-ia32-msvc": "4.53.3", "@rollup/rollup-win32-ia32-msvc": "4.54.0",
"@rollup/rollup-win32-x64-gnu": "4.53.3", "@rollup/rollup-win32-x64-gnu": "4.54.0",
"@rollup/rollup-win32-x64-msvc": "4.53.3", "@rollup/rollup-win32-x64-msvc": "4.54.0",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },

View File

@@ -33,7 +33,13 @@
"homepage": "https://github.com/vrcx-team/VRCX#readme", "homepage": "https://github.com/vrcx-team/VRCX#readme",
"devDependencies": { "devDependencies": {
"@electron/rebuild": "^4.0.2", "@electron/rebuild": "^4.0.2",
"@element-plus/icons-vue": "^2.3.2",
"@eslint/js": "^9.39.2", "@eslint/js": "^9.39.2",
"@fontsource-variable/inter": "^5.2.8",
"@fontsource-variable/noto-sans-jp": "^5.2.9",
"@fontsource-variable/noto-sans-kr": "^5.2.9",
"@fontsource-variable/noto-sans-sc": "^5.2.9",
"@fontsource-variable/noto-sans-tc": "^5.2.9",
"@kamiya4047/eslint-plugin-pretty-import": "^0.1.6", "@kamiya4047/eslint-plugin-pretty-import": "^0.1.6",
"@sentry/vite-plugin": "^4.6.1", "@sentry/vite-plugin": "^4.6.1",
"@sentry/vue": "^10.32.1", "@sentry/vue": "^10.32.1",
@@ -158,7 +164,6 @@
} }
}, },
"dependencies": { "dependencies": {
"@fontsource-variable/inter": "^5.2.8",
"hazardous": "^0.3.0", "hazardous": "^0.3.0",
"node-api-dotnet": "^0.9.18" "node-api-dotnet": "^0.9.18"
} }

View File

@@ -1,5 +1,6 @@
<template> <template>
<el-config-provider :locale="currentLocale"> <el-config-provider
:locale="/** @type {import('element-plus/es/locale').Language} */ (messages[locale].elementPlus)">
<MacOSTitleBar></MacOSTitleBar> <MacOSTitleBar></MacOSTitleBar>
<div <div
@@ -20,21 +21,6 @@
import { computed, onBeforeMount, onMounted } from 'vue'; import { computed, onBeforeMount, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import cs from 'element-plus/es/locale/lang/cs';
import en from 'element-plus/es/locale/lang/en';
import es from 'element-plus/es/locale/lang/es';
import fr from 'element-plus/es/locale/lang/fr';
import hu from 'element-plus/es/locale/lang/hu';
import ja from 'element-plus/es/locale/lang/ja';
import ko from 'element-plus/es/locale/lang/ko';
import pl from 'element-plus/es/locale/lang/pl';
import pt from 'element-plus/es/locale/lang/pt';
import ru from 'element-plus/es/locale/lang/ru';
import th from 'element-plus/es/locale/lang/th';
import vi from 'element-plus/es/locale/lang/vi';
import zhCN from 'element-plus/es/locale/lang/zh-cn';
import zhTW from 'element-plus/es/locale/lang/zh-tw';
import { createGlobalStores } from './stores'; import { createGlobalStores } from './stores';
import { initNoty } from './plugin/noty'; import { initNoty } from './plugin/noty';
@@ -45,35 +31,12 @@
console.log(`isLinux: ${LINUX}`); console.log(`isLinux: ${LINUX}`);
const isMacOS = computed(() => { const isMacOS = computed(() => navigator.platform.includes('Mac'));
return navigator.platform.indexOf('Mac') > -1;
});
const { locale } = useI18n(); const { locale, messages } = useI18n();
initNoty(); initNoty();
const langMap = {
en: en,
es: es,
fr: fr,
hu: hu,
ja: ja,
ko: ko,
pl: pl,
pt: pt,
cs: cs,
ru: ru,
vi: vi,
'zh-CN': zhCN,
'zh-TW': zhTW,
th: th
};
const currentLocale = computed(() => {
return langMap[locale.value] || en;
});
const store = createGlobalStores(); const store = createGlobalStores();
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {

View File

@@ -7,7 +7,6 @@ For a copy, see <https://opensource.org/licenses/MIT>.
*/ */
@import 'tailwindcss'; @import 'tailwindcss';
@import '@fontsource-variable/inter';
@import 'element-plus/dist/index.css'; @import 'element-plus/dist/index.css';
@import 'element-plus/theme-chalk/dark/css-vars.css'; @import 'element-plus/theme-chalk/dark/css-vars.css';
@@ -26,23 +25,23 @@ For a copy, see <https://opensource.org/licenses/MIT>.
--font-symbol: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; --font-symbol: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
--font-fallback-cjk: sans-serif; --font-fallback-cjk: sans-serif;
--font-primary-cjk: --font-primary-cjk:
'Noto Sans JP', 'Noto Sans SC', 'Noto Sans KR', 'Noto Sans TC'; 'Noto Sans JP Variable', 'Noto Sans SC Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable';
} }
:root[lang='zh-CN'] { :root[lang='zh-CN'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans SC', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC'; 'Noto Sans SC Variable', 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable';
} }
:root[lang='ja'] { :root[lang='ja'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC', 'Noto Sans SC'; 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable', 'Noto Sans SC Variable';
} }
:root[lang='ko'] { :root[lang='ko'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans KR', 'Noto Sans JP', 'Noto Sans TC', 'Noto Sans SC'; 'Noto Sans KR Variable', 'Noto Sans JP Variable', 'Noto Sans TC Variable', 'Noto Sans SC Variable';
} }
:root[lang='zh-TW'] { :root[lang='zh-TW'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans TC', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC'; 'Noto Sans TC Variable', 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans SC Variable';
} }
body { body {
font-family: font-family:

View File

@@ -1,142 +1,9 @@
/* noto-sans-tc-regular - chinese-traditional */ @import '@fontsource-variable/inter';
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 400;
src: url('/fonts/noto-sans-tc-v38-chinese-traditional-regular.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-tc-500 - chinese-traditional */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 500;
src: url('/fonts/noto-sans-tc-v38-chinese-traditional-500.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-tc-600 - chinese-traditional */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 600;
src: url('/fonts/noto-sans-tc-v38-chinese-traditional-600.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-tc-700 - chinese-traditional */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 700;
src: url('/fonts/noto-sans-tc-v38-chinese-traditional-700.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-sc-regular - chinese-simplified */ @import '@fontsource-variable/noto-sans-jp';
@font-face { @import '@fontsource-variable/noto-sans-kr';
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ @import '@fontsource-variable/noto-sans-sc';
font-family: 'Noto Sans SC'; @import '@fontsource-variable/noto-sans-tc';
font-style: normal;
font-weight: 400;
src: url('/fonts/noto-sans-sc-v39-chinese-simplified-regular.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-sc-500 - chinese-simplified */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans SC';
font-style: normal;
font-weight: 500;
src: url('/fonts/noto-sans-sc-v39-chinese-simplified-500.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-sc-600 - chinese-simplified */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans SC';
font-style: normal;
font-weight: 600;
src: url('/fonts/noto-sans-sc-v39-chinese-simplified-600.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-sc-700 - chinese-simplified */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans SC';
font-style: normal;
font-weight: 700;
src: url('/fonts/noto-sans-sc-v39-chinese-simplified-700.woff2')
format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-jp-regular - japanese */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans JP';
font-style: normal;
font-weight: 400;
src: url('/fonts/noto-sans-jp-v55-japanese-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-jp-500 - japanese */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans JP';
font-style: normal;
font-weight: 500;
src: url('/fonts/noto-sans-jp-v55-japanese-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-jp-600 - japanese */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans JP';
font-style: normal;
font-weight: 600;
src: url('/fonts/noto-sans-jp-v55-japanese-600.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-jp-700 - japanese */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans JP';
font-style: normal;
font-weight: 700;
src: url('/fonts/noto-sans-jp-v55-japanese-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-kr-regular - korean */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans KR';
font-style: normal;
font-weight: 400;
src: url('/fonts/noto-sans-kr-v38-korean-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-kr-500 - korean */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans KR';
font-style: normal;
font-weight: 500;
src: url('/fonts/noto-sans-kr-v38-korean-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-kr-600 - korean */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans KR';
font-style: normal;
font-weight: 600;
src: url('/fonts/noto-sans-kr-v38-korean-600.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* noto-sans-kr-700 - korean */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Noto Sans KR';
font-style: normal;
font-weight: 700;
src: url('/fonts/noto-sans-kr-v38-korean-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
@font-face { @font-face {
font-family: 'ellipsis-font'; font-family: 'ellipsis-font';

View File

@@ -56,57 +56,57 @@ body {
), ),
rgb(var(--md-sys-color-surface)); rgb(var(--md-sys-color-surface));
--md-sys-typescale-headline-medium-font: --md-sys-typescale-headline-medium-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-headline-medium-line-height: 36px; --md-sys-typescale-headline-medium-line-height: 36px;
--md-sys-typescale-headline-medium-size: 28px; --md-sys-typescale-headline-medium-size: 28px;
--md-sys-typescale-headline-medium-weight: 500; --md-sys-typescale-headline-medium-weight: 500;
--md-sys-typescale-headline-medium-tracking: 0; --md-sys-typescale-headline-medium-tracking: 0;
--md-sys-typescale-headline-small-font: --md-sys-typescale-headline-small-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-headline-small-line-height: 32px; --md-sys-typescale-headline-small-line-height: 32px;
--md-sys-typescale-headline-small-size: 24px; --md-sys-typescale-headline-small-size: 24px;
--md-sys-typescale-headline-small-weight: 500; --md-sys-typescale-headline-small-weight: 500;
--md-sys-typescale-headline-small-tracking: 0; --md-sys-typescale-headline-small-tracking: 0;
--md-sys-typescale-title-medium-font: --md-sys-typescale-title-medium-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-title-medium-line-height: 24px; --md-sys-typescale-title-medium-line-height: 24px;
--md-sys-typescale-title-medium-size: 16px; --md-sys-typescale-title-medium-size: 16px;
--md-sys-typescale-title-medium-weight: 600; --md-sys-typescale-title-medium-weight: 600;
--md-sys-typescale-title-medium-tracking: 0.15px; --md-sys-typescale-title-medium-tracking: 0.15px;
--md-sys-typescale-label-large-font: --md-sys-typescale-label-large-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-label-large-line-height: 20px; --md-sys-typescale-label-large-line-height: 20px;
--md-sys-typescale-label-large-size: 14px; --md-sys-typescale-label-large-size: 14px;
--md-sys-typescale-label-large-weight: 600; --md-sys-typescale-label-large-weight: 600;
--md-sys-typescale-label-large-tracking: 0.1px; --md-sys-typescale-label-large-tracking: 0.1px;
--md-sys-typescale-label-medium-font: --md-sys-typescale-label-medium-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-label-medium-line-height: 16px; --md-sys-typescale-label-medium-line-height: 16px;
--md-sys-typescale-label-medium-size: 12px; --md-sys-typescale-label-medium-size: 12px;
--md-sys-typescale-label-medium-weight: 600; --md-sys-typescale-label-medium-weight: 600;
--md-sys-typescale-label-medium-tracking: 0.5px; --md-sys-typescale-label-medium-tracking: 0.5px;
--md-sys-typescale-body-large-font: --md-sys-typescale-body-large-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-body-large-line-height: 24px; --md-sys-typescale-body-large-line-height: 24px;
--md-sys-typescale-body-large-size: 16px; --md-sys-typescale-body-large-size: 16px;
--md-sys-typescale-body-large-weight: 400; --md-sys-typescale-body-large-weight: 400;
--md-sys-typescale-body-large-tracking: 0.5px; --md-sys-typescale-body-large-tracking: 0.5px;
--md-sys-typescale-body-medium-font: --md-sys-typescale-body-medium-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-body-medium-line-height: 20px; --md-sys-typescale-body-medium-line-height: 20px;
--md-sys-typescale-body-medium-size: 14px; --md-sys-typescale-body-medium-size: 14px;
--md-sys-typescale-body-medium-weight: 400; --md-sys-typescale-body-medium-weight: 400;
--md-sys-typescale-body-medium-tracking: 0.25px; --md-sys-typescale-body-medium-tracking: 0.25px;
--md-sys-typescale-body-small-font: --md-sys-typescale-body-small-font:
'Google Sans', 'Noto Sans', 'Noto Sans TC', 'Noto Sans JP', 'Google Sans', 'Noto Sans', 'Noto Sans TC Variable', 'Noto Sans JP Variable',
'Noto Sans SC', 'Roboto', sans-serif; 'Noto Sans SC Variable', 'Roboto', sans-serif;
--md-sys-typescale-body-small-line-height: 16px; --md-sys-typescale-body-small-line-height: 16px;
--md-sys-typescale-body-small-size: 12px; --md-sys-typescale-body-small-size: 12px;
--md-sys-typescale-body-small-weight: 400; --md-sys-typescale-body-small-weight: 400;

View File

@@ -14,8 +14,8 @@
--lighter-lighter-lighter-lighter-bg: #857070; --lighter-lighter-lighter-lighter-bg: #857070;
--lighter-border: #aa6065; --lighter-border: #aa6065;
--font: --font:
'Poppins', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC', 'Poppins', 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable',
'Noto Sans SC', sans-serif; 'Noto Sans SC Variable', sans-serif;
--group-calendar-event-bg: rgba(223, 162, 162, 0.1); --group-calendar-event-bg: rgba(223, 162, 162, 0.1);
--group-calendar-badge-following: var(--theme); --group-calendar-badge-following: var(--theme);

View File

@@ -221,6 +221,7 @@
useVRCXUpdaterStore useVRCXUpdaterStore
} from '../stores'; } from '../stores';
import { THEME_CONFIG, links, navDefinitions } from '../shared/constants'; import { THEME_CONFIG, links, navDefinitions } from '../shared/constants';
import { getSentry } from '../plugin';
import { openExternalLink } from '../shared/utils'; import { openExternalLink } from '../shared/utils';
import configRepository from '../service/config'; import configRepository from '../service/config';
@@ -737,12 +738,13 @@
onMounted(async () => { onMounted(async () => {
await loadNavMenuConfig(); await loadNavMenuConfig();
if (!sentryErrorReporting.value) return; if (!NIGHTLY || !sentryErrorReporting.value) return;
try { try {
import('@sentry/vue').then((Sentry) => { const Sentry = await getSentry();
const feedback = Sentry.getFeedback();
feedback?.attachTo(document.getElementById('feedback')); const feedback = Sentry.getFeedback();
}); feedback?.attachTo(document.getElementById('feedback'));
} catch (error) { } catch (error) {
console.error('Error setting up Sentry feedback:', error); console.error('Error setting up Sentry feedback:', error);
} }

View File

@@ -1,37 +1,44 @@
const langCodes = [ const elementPlusStrings = {
'cs', // Vite does not support dynamic imports to `node_modules`.
'en', // https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
'es', cs: () => import('element-plus/es/locale/lang/cs'),
'fr', en: () => import('element-plus/es/locale/lang/en'),
'hu', es: () => import('element-plus/es/locale/lang/es'),
'ja', fr: () => import('element-plus/es/locale/lang/fr'),
'ko', hu: () => import('element-plus/es/locale/lang/hu'),
'pl', ja: () => import('element-plus/es/locale/lang/ja'),
'pt', ko: () => import('element-plus/es/locale/lang/ko'),
'ru', pl: () => import('element-plus/es/locale/lang/pl'),
'th', pt: () => import('element-plus/es/locale/lang/pt'),
'vi', ru: () => import('element-plus/es/locale/lang/ru'),
'zh-CN', th: () => import('element-plus/es/locale/lang/th'),
'zh-TW' vi: () => import('element-plus/es/locale/lang/vi'),
]; 'zh-CN': () => import('element-plus/es/locale/lang/zh-cn'),
'zh-TW': () => import('element-plus/es/locale/lang/zh-tw')
};
async function getLocalizationStrings() { async function getElementPlusStrings(code) {
const urlPromises = Promise.all( return (await elementPlusStrings[code]()).default;
langCodes.map((code) =>
import(`./${code}.json?url`).then((m) => m.default)
)
);
const urls = await urlPromises;
const fetchPromises = Promise.all(
urls.map((url) => fetch(url).then((res) => res.json()))
);
const results = await fetchPromises;
const entries = langCodes.map((code, index) => {
return [code, results[index]];
});
return Object.fromEntries(entries);
} }
export { getLocalizationStrings }; async function getLocalizedStrings(code) {
const localizedStringsUrl = new URL(`./${code}.json`, import.meta.url).href;
const localizedStrings = await fetch(localizedStringsUrl).then((response) => response.json())
return {
...localizedStrings,
elementPlus: await getElementPlusStrings(code)
};
}
const languageNames = import.meta.glob('./*.json', {
eager: true,
import: 'language'
});
function getLanguageName(code) {
return languageNames[`./${code}.json`];
}
export * from "./locales";
export { getLanguageName, getLocalizedStrings };

View File

@@ -0,0 +1,17 @@
// Separate file, to be importable in `vite.config.js`.
export const languageCodes = [
'cs',
'en',
'es',
'fr',
'hu',
'ja',
'ko',
'pl',
'pt',
'ru',
'th',
'vi',
'zh-CN',
'zh-TW'
];

View File

@@ -1,18 +1,9 @@
import { createI18n } from 'vue-i18n'; import { createI18n } from 'vue-i18n';
import { getLocalizedStrings, languageCodes } from '../localization';
import { getLocalizationStrings } from '../localization/index.js';
const localizedStrings = await getLocalizationStrings();
const i18n = createI18n({ const i18n = createI18n({
locale: 'en', locale: 'en',
fallbackLocale: 'en', fallbackLocale: 'en',
messages: Object.fromEntries(
Object.entries(localizedStrings).map(([key, value]) => [
key.replaceAll('_', '-'),
value
])
),
legacy: false, legacy: false,
globalInjection: false, globalInjection: false,
missingWarn: false, missingWarn: false,
@@ -20,11 +11,13 @@ const i18n = createI18n({
fallbackWarn: false fallbackWarn: false
}); });
async function updateLocalizedStrings() { async function loadLocalizedStrings(code) {
const newStrings = await getLocalizationStrings(); const messages = await getLocalizedStrings(code);
Object.entries(newStrings).forEach(([key, value]) => { i18n.global.setLocaleMessage(code, messages);
i18n.global.setLocaleMessage(key.replaceAll('_', '-'), value);
});
} }
export { i18n, updateLocalizedStrings }; async function updateLocalizedStrings() {
await loadLocalizedStrings(i18n.global.locale.value);
}
export { i18n, loadLocalizedStrings, updateLocalizedStrings };

View File

@@ -2,26 +2,23 @@ import { router } from './router';
import configRepository from '../service/config'; import configRepository from '../service/config';
let version = ''; export async function isSentryOptedIn() {
return NIGHTLY && configRepository.getBool('VRCX_SentryEnabled', false);
}
export async function isSentryEnabled() { /**
const enabled = await configRepository.getString( * Guarded import, prevents leaking Sentry into non-nightly bundles.
'VRCX_SentryEnabled', */
'false' export function getSentry() {
); return NIGHTLY ? import('@sentry/vue') : null;
version = await AppApi.GetVersion();
const isNightly = version.includes('Nightly');
if (enabled !== 'true' || !isNightly) {
return false;
}
return true;
} }
export async function initSentry(app) { export async function initSentry(app) {
if (!NIGHTLY) return;
try { try {
if (!(await isSentryEnabled())) { if (!(await isSentryOptedIn())) return;
return;
}
const vrcxId = await configRepository.getString('VRCX_id', ''); const vrcxId = await configRepository.getString('VRCX_id', '');
const response = await webApiService.execute({ const response = await webApiService.execute({
url: 'https://api0.vrcx.app/errorreporting/getdsn', url: 'https://api0.vrcx.app/errorreporting/getdsn',
@@ -40,12 +37,12 @@ export async function initSentry(app) {
return; return;
} }
const dsn = atob(response.data); const dsn = atob(response.data);
const Sentry = await import('@sentry/vue'); const Sentry = await getSentry();
Sentry.init({ Sentry.init({
app, app,
dsn, dsn,
environment: 'nightly', environment: 'nightly',
release: version, release: VERSION,
replaysSessionSampleRate: 0, replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 1.0, replaysOnErrorSampleRate: 1.0,
tracesSampleRate: 0.0001, tracesSampleRate: 0.0001,

View File

@@ -1,6 +1,6 @@
import { createPinia } from 'pinia'; import { createPinia } from 'pinia';
import { isSentryEnabled } from '../plugin'; import { getSentry, isSentryOptedIn } from '../plugin';
import { useAdvancedSettingsStore } from './settings/advanced'; import { useAdvancedSettingsStore } from './settings/advanced';
import { useAppearanceSettingsStore } from './settings/appearance'; import { useAppearanceSettingsStore } from './settings/appearance';
import { useAuthStore } from './auth'; import { useAuthStore } from './auth';
@@ -39,11 +39,10 @@ import { useWristOverlaySettingsStore } from './settings/wristOverlay';
export const pinia = createPinia(); export const pinia = createPinia();
async function registerSentryPiniaPlugin() { async function registerSentryPiniaPlugin() {
if (!(await isSentryEnabled())) { if (!NIGHTLY) return;
return; if (!(await isSentryOptedIn())) return;
}
const Sentry = await import('@sentry/vue'); const Sentry = await getSentry();
pinia.use( pinia.use(
Sentry.createSentryPiniaPlugin({ Sentry.createSentryPiniaPlugin({
stateTransformer: (state) => ({ stateTransformer: (state) => ({

View File

@@ -12,13 +12,14 @@ import { watchState } from '../../service/watchState';
import configRepository from '../../service/config'; import configRepository from '../../service/config';
import webApiService from '../../service/webapi'; import webApiService from '../../service/webapi';
import { languageCodes } from '../../localization';
export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => { export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
const gameStore = useGameStore(); const gameStore = useGameStore();
const vrcxStore = useVrcxStore(); const vrcxStore = useVrcxStore();
const VRCXUpdaterStore = useVRCXUpdaterStore(); const VRCXUpdaterStore = useVRCXUpdaterStore();
const { availableLocales, t } = useI18n(); const { t } = useI18n();
const state = reactive({ const state = reactive({
folderSelectorDialogVisible: false folderSelectorDialogVisible: false
@@ -163,7 +164,7 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
if ( if (
!bioLanguageConfig || !bioLanguageConfig ||
!availableLocales.includes(bioLanguageConfig) !languageCodes.includes(bioLanguageConfig)
) { ) {
bioLanguage.value = 'en'; bioLanguage.value = 'en';
} else { } else {
@@ -467,7 +468,7 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
} }
async function checkSentryConsent() { async function checkSentryConsent() {
ElMessageBox.confirm( const { action: consentAction } = await ElMessageBox.confirm(
'Help improve VRCX by allowing anonymous error reporting?</br></br>' + 'Help improve VRCX by allowing anonymous error reporting?</br></br>' +
'• Only collects crash and error information.</br>' + '• Only collects crash and error information.</br>' +
'• No personal data or VRChat information is collected.</br>' + '• No personal data or VRChat information is collected.</br>' +
@@ -482,42 +483,35 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
closeOnPressEscape: false, closeOnPressEscape: false,
distinguishCancelAndClose: true distinguishCancelAndClose: true
} }
) ).catch(() => ({ action: 'cancel' }));
.then(() => {
sentryErrorReporting.value = true;
configRepository.setString('VRCX_SentryEnabled', 'true');
ElMessageBox.confirm( if (consentAction === 'cancel') return;
'Error reporting setting has been enabled. Would you like to restart VRCX now for the change to take effect?',
'Restart Required', const { action: restartAction } = await ElMessageBox.confirm(
{ 'Error reporting setting has been enabled. Would you like to restart VRCX now for the change to take effect?',
confirmButtonText: 'Restart Now', 'Restart Required',
cancelButtonText: 'Later', {
type: 'warning', confirmButtonText: 'Restart Now',
center: true, cancelButtonText: 'Later',
closeOnClickModal: false, type: 'warning',
closeOnPressEscape: false center: true,
} closeOnClickModal: false,
).then(() => { closeOnPressEscape: false
VRCXUpdaterStore.restartVRCX(false); }
}); ).catch(() => ({ action: 'cancel' }));
})
.catch((action) => { if (restartAction === 'cancel') return;
const act =
typeof action === 'string' ? action : action?.action; sentryErrorReporting.value = true;
if (act === 'cancel') { configRepository.setBool('VRCX_SentryEnabled', true);
sentryErrorReporting.value = false;
configRepository.setString('VRCX_SentryEnabled', 'false'); VRCXUpdaterStore.restartVRCX(false);
}
});
} }
async function setSentryErrorReporting() { async function setSentryErrorReporting() {
if (VRCXUpdaterStore.branch !== 'Nightly') { if (VRCXUpdaterStore.branch !== 'Nightly') return;
return;
}
ElMessageBox.confirm( const { action: restartAction } = await ElMessageBox.confirm(
'Error reporting setting has been disabled. Would you like to restart VRCX now for the change to take effect?', 'Error reporting setting has been disabled. Would you like to restart VRCX now for the change to take effect?',
'Restart Required', 'Restart Required',
{ {
@@ -526,16 +520,16 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
type: 'info', type: 'info',
center: true center: true
} }
) ).catch(() => ({ action: 'cancel' }));
.then(async () => {
sentryErrorReporting.value = !sentryErrorReporting.value; if (restartAction === 'cancel') return;
await configRepository.setString(
'VRCX_SentryEnabled', sentryErrorReporting.value = !sentryErrorReporting.value;
sentryErrorReporting.value ? 'true' : 'false' await configRepository.setBool(
); 'VRCX_SentryEnabled',
VRCXUpdaterStore.restartVRCX(false); sentryErrorReporting.value
}) );
.catch(() => {}); VRCXUpdaterStore.restartVRCX(false);
} }
async function getSqliteTableSizes() { async function getSqliteTableSizes() {

View File

@@ -14,6 +14,7 @@ import {
} from '../../shared/utils/base/ui'; } from '../../shared/utils/base/ui';
import { database } from '../../service/database'; import { database } from '../../service/database';
import { getNameColour } from '../../shared/utils'; import { getNameColour } from '../../shared/utils';
import { loadLocalizedStrings } from '../../plugin';
import { useFeedStore } from '../feed'; import { useFeedStore } from '../feed';
import { useGameLogStore } from '../gameLog'; import { useGameLogStore } from '../gameLog';
import { useUiStore } from '../ui'; import { useUiStore } from '../ui';
@@ -23,6 +24,7 @@ import { useVrcxStore } from '../vrcx';
import { watchState } from '../../service/watchState'; import { watchState } from '../../service/watchState';
import configRepository from '../../service/config'; import configRepository from '../../service/config';
import { languageCodes } from '../../localization';
export const useAppearanceSettingsStore = defineStore( export const useAppearanceSettingsStore = defineStore(
'AppearanceSettings', 'AppearanceSettings',
@@ -36,7 +38,7 @@ export const useAppearanceSettingsStore = defineStore(
const router = useRouter(); const router = useRouter();
const uiStore = useUiStore(); const uiStore = useUiStore();
const { t, availableLocales, locale } = useI18n(); const { t, locale } = useI18n();
const MAX_TABLE_PAGE_SIZE = 1000; const MAX_TABLE_PAGE_SIZE = 1000;
const DEFAULT_TABLE_PAGE_SIZES = [10, 15, 20, 25, 50, 100]; const DEFAULT_TABLE_PAGE_SIZES = [10, 15, 20, 25, 50, 100];
@@ -180,14 +182,15 @@ export const useAppearanceSettingsStore = defineStore(
const result = await AppApi.CurrentLanguage(); const result = await AppApi.CurrentLanguage();
const lang = result.split('-')[0]; const lang = result.split('-')[0];
availableLocales.forEach((ref) => {
for (const ref of languageCodes) {
const refLang = ref.split('_')[0]; const refLang = ref.split('_')[0];
if (refLang === lang) { if (refLang === lang) {
changeAppLanguage(ref); await changeAppLanguage(ref);
} }
}); }
} else { } else {
changeAppLanguage(appLanguageConfig); await changeAppLanguage(appLanguageConfig);
} }
themeMode.value = themeModeConfig; themeMode.value = themeModeConfig;
@@ -257,19 +260,23 @@ export const useAppearanceSettingsStore = defineStore(
* *
* @param {string} language * @param {string} language
*/ */
function changeAppLanguage(language) { async function changeAppLanguage(language) {
setAppLanguage(language); await setAppLanguage(language);
vrStore.updateVRConfigVars(); vrStore.updateVRConfigVars();
} }
/** /**
* @param {string} language * @param {string} language
*/ */
function setAppLanguage(language) { async function setAppLanguage(language) {
console.log('Language changed:', language); console.log('Language changed:', language);
await loadLocalizedStrings(language);
appLanguage.value = language; appLanguage.value = language;
configRepository.setString('VRCX_appLanguage', language); configRepository.setString('VRCX_appLanguage', language);
locale.value = appLanguage.value; locale.value = appLanguage.value;
changeHtmlLangAttribute(language); changeHtmlLangAttribute(language);
} }

View File

@@ -2,6 +2,9 @@
/// <reference types="jest" /> /// <reference types="jest" />
declare global { declare global {
const VERSION: string;
const NIGHTLY: boolean;
const WINDOWS: boolean; const WINDOWS: boolean;
const LINUX: boolean; const LINUX: boolean;
@@ -416,4 +419,4 @@ declare global {
}; };
} }
export {}; export { };

View File

@@ -6,19 +6,18 @@
<span class="name">{{ t('view.settings.appearance.appearance.language') }}</span> <span class="name">{{ t('view.settings.appearance.appearance.language') }}</span>
<el-dropdown trigger="click" size="small" @click.stop> <el-dropdown trigger="click" size="small" @click.stop>
<el-button size="small"> <el-button size="small">
<span <span>
>{{ messages[appLanguage]?.language }} {{ getLanguageName(appLanguage) }} <el-icon class="el-icon--right"> <ArrowDown /></el-icon
<el-icon class="el-icon--right"><ArrowDown /></el-icon
></span> ></span>
</el-button> </el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item <el-dropdown-item
v-for="(obj, language) in messages" v-for="language in languageCodes"
:key="language" :key="language"
:class="{ 'is-active': appLanguage === language }" :class="{ 'is-active': appLanguage === language }"
@click="changeAppLanguage(language)" @click="changeAppLanguage(language)"
v-text="obj.language" /> v-text="getLanguageName(language)" />
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@@ -385,10 +384,11 @@
import { useAppearanceSettingsStore, useFavoriteStore, useVrStore } from '../../../../stores'; import { useAppearanceSettingsStore, useFavoriteStore, useVrStore } from '../../../../stores';
import { THEME_CONFIG } from '../../../../shared/constants'; import { THEME_CONFIG } from '../../../../shared/constants';
import { getLanguageName, languageCodes } from '../../../../localization';
import SimpleSwitch from '../SimpleSwitch.vue'; import SimpleSwitch from '../SimpleSwitch.vue';
const { messages, t } = useI18n(); const { t } = useI18n();
const appearanceSettingsStore = useAppearanceSettingsStore(); const appearanceSettingsStore = useAppearanceSettingsStore();
const { saveOpenVROption, updateVRConfigVars } = useVrStore(); const { saveOpenVROption, updateVRConfigVars } = useVrStore();

View File

@@ -10,17 +10,17 @@
<el-dropdown trigger="click" size="small" style="float: right" @click.stop> <el-dropdown trigger="click" size="small" style="float: right" @click.stop>
<el-button size="small"> <el-button size="small">
<span> <span>
{{ messages[bioLanguage]?.language || bioLanguage }} {{ getLanguageName(bioLanguage) || bioLanguage }}
<el-icon class="el-icon--right"><ArrowDown /></el-icon> <el-icon class="el-icon--right"><ArrowDown /></el-icon>
</span> </span>
</el-button> </el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item <el-dropdown-item
v-for="(obj, language) in messages" v-for="language in languageCodes"
:key="language" :key="language"
@click="setBioLanguage(language)" @click="setBioLanguage(language)"
v-text="obj.language" /> v-text="getLanguageName(language)" />
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@@ -108,6 +108,7 @@
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { getLanguageName, languageCodes } from '../../../localization';
import { openExternalLink } from '../../../shared/utils'; import { openExternalLink } from '../../../shared/utils';
import { useAdvancedSettingsStore } from '../../../stores'; import { useAdvancedSettingsStore } from '../../../stores';
@@ -132,7 +133,7 @@
setTranslationApiPrompt setTranslationApiPrompt
} = advancedSettingsStore; } = advancedSettingsStore;
const { messages, t } = useI18n(); const { t } = useI18n();
const props = defineProps({ const props = defineProps({
isTranslationApiDialogVisible: { isTranslationApiDialogVisible: {

View File

@@ -1,77 +1,128 @@
import { dirname, resolve } from 'node:path'; import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import fs from 'node:fs'; import fs from 'node:fs';
import { defineConfig } from 'vite'; import { defineConfig, loadEnv } from 'vite';
import { sentryVitePlugin } from '@sentry/vite-plugin';
import tailwindcss from '@tailwindcss/vite'; import tailwindcss from '@tailwindcss/vite';
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
const __dirname = dirname(fileURLToPath(import.meta.url)); import { languageCodes } from './localization/locales';
const authToken = process.env.SENTRY_AUTH_TOKEN; function getAssetLanguage(assetId) {
const buildAndUploadSourceMaps = authToken ? true : false; if (!assetId) return null;
const vrcxVersion = fs
.readFileSync(resolve(__dirname, '../Version'), 'utf-8') if (assetId.endsWith('.json')) {
.trim(); const language = assetId.split('.json')[0];
if (buildAndUploadSourceMaps) {
console.log('Source maps will be built and uploaded to Sentry'); if (languageCodes.includes(language)) return language;
}
const language =
assetId.split('element-plus/es/locale/lang/')[1]?.split('.')[0] ||
// Font assets, e.g., noto-sans-jp-regular.woff2 mapped to language code.
{
jp: 'ja',
sc: 'zh-CN',
tc: 'zh-TW',
kr: 'ko'
}[assetId.split('noto-sans-')[1]?.split('-')[0]];
return language || null;
} }
// @ts-ignore function getManualChunk(moduleId) {
export default defineConfig(() => ({ const language = getAssetLanguage(moduleId);
base: '', if (!language) return;
plugins: [
vue(), return `languages/${language}`;
tailwindcss(), }
buildAndUploadSourceMaps &&
sentryVitePlugin({ const defaultAssetName = '[hash][extname]';
authToken,
project: 'vrcx-web', function getAssetFilename({ name }) {
release: { const language = getAssetLanguage(name);
name: vrcxVersion if (!language) return `assets/${defaultAssetName}`;
},
sourcemaps: { return `assets/languages/${language}-${defaultAssetName}`;
assets: './build/html/**', }
filesToDeleteAfterUpload: './build/html/**/*.js.map'
export default defineConfig(({ mode }) => {
const { SENTRY_AUTH_TOKEN: sentryAuthToken } = loadEnv(
mode,
process.cwd(),
''
);
const buildAndUploadSourceMaps = !!sentryAuthToken;
const version = fs
.readFileSync(new URL('../Version', import.meta.url), 'utf-8')
.trim();
const nightly = version.split('-').at(-1).length === 7;
return {
base: '',
plugins: [
vue(),
tailwindcss(),
buildAndUploadSourceMaps &&
import('@sentry/vite-plugin').then(({ sentryVitePlugin }) =>
sentryVitePlugin({
authToken: sentryAuthToken,
project: 'vrcx-web',
release: {
name: version
},
sourcemaps: {
assets: './build/html/**',
filesToDeleteAfterUpload: './build/html/**/*.js.map'
}
})
)
],
css: {
transformer: 'lightningcss',
lightningcss: {
minify: true,
targets: {
chrome: 140
} }
})
],
css: {
transformer: 'lightningcss',
lightningcss: {
minify: true,
targets: {
chrome: 140
}
}
},
define: {
LINUX: JSON.stringify(process.env.PLATFORM === 'linux'),
WINDOWS: JSON.stringify(process.env.PLATFORM === 'windows')
},
server: {
port: 9000,
strictPort: true
},
build: {
target: 'chrome140',
outDir: '../build/html',
cssMinify: 'lightningcss',
license: true,
emptyOutDir: true,
reportCompressedSize: false,
chunkSizeWarningLimit: 5000,
modulePreload: true,
assetsInlineLimit: 0,
rollupOptions: {
input: {
index: resolve(__dirname, 'index.html'),
vr: resolve(__dirname, 'vr.html')
} }
}, },
sourcemap: buildAndUploadSourceMaps define: {
} LINUX: JSON.stringify(process.env.PLATFORM === 'linux'),
})); WINDOWS: JSON.stringify(process.env.PLATFORM === 'windows'),
VERSION: JSON.stringify(version),
NIGHTLY: JSON.stringify(nightly)
},
server: {
port: 9000,
strictPort: true
},
build: {
target: 'chrome140',
outDir: '../build/html',
cssMinify: 'lightningcss',
license: true,
emptyOutDir: true,
copyPublicDir: false,
// reportCompressedSize: false,
// chunkSizeWarningLimit: 5000,
sourcemap: buildAndUploadSourceMaps,
assetsInlineLimit: 0,
rollupOptions: {
preserveEntrySignatures: false,
input: {
index: resolve(import.meta.dirname, './index.html'),
vr: resolve(import.meta.dirname, './vr.html')
},
output: {
assetFileNames: getAssetFilename,
manualChunks: getManualChunk
}
}
}
};
});

View File

@@ -1416,6 +1416,7 @@
import { escapeTag, escapeTagRecursive } from '../shared/utils/base/string'; import { escapeTag, escapeTagRecursive } from '../shared/utils/base/string';
import { changeHtmlLangAttribute } from '../shared/utils/base/ui'; import { changeHtmlLangAttribute } from '../shared/utils/base/ui';
import { displayLocation } from '../shared/utils/location'; import { displayLocation } from '../shared/utils/location';
import { loadLocalizedStrings } from '../plugin/i18n';
import { removeFromArray } from '../shared/utils/base/array'; import { removeFromArray } from '../shared/utils/base/array';
import { timeToText } from '../shared/utils/base/format'; import { timeToText } from '../shared/utils/base/format';
@@ -2094,12 +2095,14 @@
.replace(' pm', ''); .replace(' pm', '');
}; };
function setAppLanguage(appLanguage) { async function setAppLanguage(appLanguage) {
if (!appLanguage) { if (!appLanguage) {
return; return;
} }
if (appLanguage !== vrState.appLanguage) { if (appLanguage !== vrState.appLanguage) {
vrState.appLanguage = appLanguage; vrState.appLanguage = appLanguage;
await loadLocalizedStrings(appLanguage);
changeHtmlLangAttribute(vrState.appLanguage); changeHtmlLangAttribute(vrState.appLanguage);
//@ts-ignore //@ts-ignore
i18n.locale = vrState.appLanguage; i18n.locale = vrState.appLanguage;

View File

@@ -7,7 +7,6 @@ For a copy, see <https://opensource.org/licenses/MIT>.
*/ */
@import 'tailwindcss'; @import 'tailwindcss';
@import '@fontsource-variable/inter';
@import 'animate.css/animate.min.css'; @import 'animate.css/animate.min.css';
@import 'noty/lib/noty.css'; @import 'noty/lib/noty.css';
@@ -38,23 +37,23 @@ body {
--font-symbol: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; --font-symbol: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
--font-fallback-cjk: sans-serif; --font-fallback-cjk: sans-serif;
--font-primary-cjk: --font-primary-cjk:
'Noto Sans JP', 'Noto Sans SC', 'Noto Sans KR', 'Noto Sans TC'; 'Noto Sans JP Variable', 'Noto Sans SC Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable';
} }
:root[lang='zh-CN'] { :root[lang='zh-CN'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans SC', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC'; 'Noto Sans SC Variable', 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable';
} }
:root[lang='ja'] { :root[lang='ja'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC', 'Noto Sans SC'; 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable', 'Noto Sans SC Variable';
} }
:root[lang='ko'] { :root[lang='ko'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans KR', 'Noto Sans JP', 'Noto Sans TC', 'Noto Sans SC'; 'Noto Sans KR Variable', 'Noto Sans JP Variable', 'Noto Sans TC Variable', 'Noto Sans SC Variable';
} }
:root[lang='zh-TW'] { :root[lang='zh-TW'] {
--font-primary-cjk: --font-primary-cjk:
'Noto Sans TC', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC'; 'Noto Sans TC Variable', 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans SC Variable';
} }
body { body {
font-family: font-family:
@@ -225,8 +224,8 @@ textarea,
select, select,
button { button {
font-family: font-family:
'ellipsis-font', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC', 'ellipsis-font', 'Noto Sans JP Variable', 'Noto Sans KR Variable', 'Noto Sans TC Variable',
'Noto Sans SC', 'Meiryo UI', 'Malgun Gothic', 'Segoe UI', sans-serif; 'Noto Sans SC Variable', 'Meiryo UI', 'Malgun Gothic', 'Segoe UI', sans-serif;
line-height: normal; line-height: normal;
text-shadow: text-shadow:
#000 0px 0px 3px, #000 0px 0px 3px,