Compare commits
2
Commits
1e57b0e59b
...
ac92453685
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac92453685 | ||
|
|
ecd5f6b34e |
No files matched your search
Vendored
+9
-2
@@ -1,19 +1,26 @@
|
||||
{
|
||||
"editor.tabSize": 2,
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.formatOnSave": true
|
||||
// "editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
// "editor.formatOnSave": true
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[rust]": {
|
||||
"editor.tabSize": 4,
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"files.associations": {
|
||||
"tauri*.conf.json5": "jsonc"
|
||||
},
|
||||
"json.schemaDownload.trustedDomains": {
|
||||
"https://schema.tauri.app": true
|
||||
}
|
||||
},
|
||||
"vue3snippets.enable-compile-vue-file-on-did-save-code": true
|
||||
}
|
||||
+4
-1
@@ -13,13 +13,16 @@
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@primeuix/themes": "^2.0.3",
|
||||
"@tauri-apps/api": "^2.10.1",
|
||||
"@tauri-apps/plugin-clipboard-manager": "~2.3.2",
|
||||
"@tauri-apps/plugin-fs": "~2.4.5",
|
||||
"@tauri-apps/plugin-http": "~2.5.7",
|
||||
"@tauri-apps/plugin-opener": "^2.5.3",
|
||||
"@tauri-apps/plugin-sql": "~2.3.2",
|
||||
"vue": "^3.5.31"
|
||||
"primevue": "^4.5.4",
|
||||
"vue": "^3.5.31",
|
||||
"vue-router": "^5.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2.10.1",
|
||||
|
||||
Generated
+381
-5
@@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@primeuix/themes':
|
||||
specifier: ^2.0.3
|
||||
version: 2.0.3
|
||||
'@tauri-apps/api':
|
||||
specifier: ^2.10.1
|
||||
version: 2.10.1
|
||||
@@ -26,28 +29,38 @@ importers:
|
||||
'@tauri-apps/plugin-sql':
|
||||
specifier: ~2.3.2
|
||||
version: 2.3.2
|
||||
primevue:
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(vue@3.5.31(typescript@5.6.3))
|
||||
vue:
|
||||
specifier: ^3.5.31
|
||||
version: 3.5.31(typescript@5.6.3)
|
||||
vue-router:
|
||||
specifier: ^5.0.4
|
||||
version: 5.0.4(@vue/compiler-sfc@3.5.31)(vue@3.5.31(typescript@5.6.3))
|
||||
devDependencies:
|
||||
'@tauri-apps/cli':
|
||||
specifier: ^2.10.1
|
||||
version: 2.10.1
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.2.4
|
||||
version: 5.2.4(vite@6.4.1)(vue@3.5.31(typescript@5.6.3))
|
||||
version: 5.2.4(vite@6.4.1(yaml@2.8.3))(vue@3.5.31(typescript@5.6.3))
|
||||
typescript:
|
||||
specifier: ~5.6.3
|
||||
version: 5.6.3
|
||||
vite:
|
||||
specifier: ^6.4.1
|
||||
version: 6.4.1
|
||||
version: 6.4.1(yaml@2.8.3)
|
||||
vue-tsc:
|
||||
specifier: ^2.2.12
|
||||
version: 2.2.12(typescript@5.6.3)
|
||||
|
||||
packages:
|
||||
|
||||
'@babel/generator@7.29.1':
|
||||
resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@7.27.1':
|
||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -221,9 +234,46 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||
|
||||
'@jridgewell/remapping@2.3.5':
|
||||
resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5':
|
||||
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@primeuix/styled@0.7.4':
|
||||
resolution: {integrity: sha512-QSO/NpOQg8e9BONWRBx9y8VGMCMYz0J/uKfNJEya/RGEu7ARx0oYW0ugI1N3/KB1AAvyGxzKBzGImbwg0KUiOQ==}
|
||||
engines: {node: '>=12.11.0'}
|
||||
|
||||
'@primeuix/styles@2.0.3':
|
||||
resolution: {integrity: sha512-2ykAB6BaHzR/6TwF8ShpJTsZrid6cVIEBVlookSdvOdmlWuevGu5vWOScgIwqWwlZcvkFYAGR/SUV3OHCTBMdw==}
|
||||
|
||||
'@primeuix/themes@2.0.3':
|
||||
resolution: {integrity: sha512-3fS1883mtCWhgUgNf/feiaaDSOND4EBIOu9tZnzJlJ8QtYyL6eFLcA6V3ymCWqLVXQ1+lTVEZv1gl47FIdXReg==}
|
||||
|
||||
'@primeuix/utils@0.6.4':
|
||||
resolution: {integrity: sha512-pZ5f+vj7wSzRhC7KoEQRU5fvYAe+RP9+m39CTscZ3UywCD1Y2o6Fe1rRgklMPSkzUcty2jzkA0zMYkiJBD1hgg==}
|
||||
engines: {node: '>=12.11.0'}
|
||||
|
||||
'@primevue/core@4.5.4':
|
||||
resolution: {integrity: sha512-lYJJB3wTrDJ8MkLctzHfrPZAqXVxoatjIsswSJzupatf6ZogJHVYADUKcn1JAkLLk8dtV1FA2AxDek663fHO5Q==}
|
||||
engines: {node: '>=12.11.0'}
|
||||
peerDependencies:
|
||||
vue: ^3.5.0
|
||||
|
||||
'@primevue/icons@4.5.4':
|
||||
resolution: {integrity: sha512-DxgryEc7ZmUqcEhYMcxGBRyFzdtLIoy3jLtlH1zsVSRZaG+iSAcjQ88nvfkZxGUZtZBFL7sRjF6KLq3bJZJwUw==}
|
||||
engines: {node: '>=12.11.0'}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.60.0':
|
||||
resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==}
|
||||
cpu: [arm]
|
||||
@@ -475,6 +525,15 @@ packages:
|
||||
'@volar/typescript@2.4.15':
|
||||
resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==}
|
||||
|
||||
'@vue-macros/common@3.1.2':
|
||||
resolution: {integrity: sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
peerDependencies:
|
||||
vue: ^2.7.0 || ^3.2.25
|
||||
peerDependenciesMeta:
|
||||
vue:
|
||||
optional: true
|
||||
|
||||
'@vue/compiler-core@3.5.31':
|
||||
resolution: {integrity: sha512-k/ueL14aNIEy5Onf0OVzR8kiqF/WThgLdFhxwa4e/KF/0qe38IwIdofoSWBTvvxQOesaz6riAFAUaYjoF9fLLQ==}
|
||||
|
||||
@@ -490,6 +549,15 @@ packages:
|
||||
'@vue/compiler-vue2@2.7.16':
|
||||
resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
|
||||
|
||||
'@vue/devtools-api@8.1.1':
|
||||
resolution: {integrity: sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw==}
|
||||
|
||||
'@vue/devtools-kit@8.1.1':
|
||||
resolution: {integrity: sha512-gVBaBv++i+adg4JpH71k9ppl4soyR7Y2McEqO5YNgv0BI1kMZ7BDX5gnwkZ5COYgiCyhejZG+yGNrBAjj6Coqg==}
|
||||
|
||||
'@vue/devtools-shared@8.1.1':
|
||||
resolution: {integrity: sha512-+h4ttmJYl/txpxHKaoZcaKpC+pvckgLzIDiSQlaQ7kKthKh8KuwoLW2D8hPJEnqKzXOvu15UHEoGyngAXCz0EQ==}
|
||||
|
||||
'@vue/language-core@2.2.12':
|
||||
resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==}
|
||||
peerDependencies:
|
||||
@@ -515,15 +583,41 @@ packages:
|
||||
'@vue/shared@3.5.31':
|
||||
resolution: {integrity: sha512-nBxuiuS9Lj5bPkPbWogPUnjxxWpkRniX7e5UBQDWl6Fsf4roq9wwV+cR7ezQ4zXswNvPIlsdj1slcLB7XCsRAw==}
|
||||
|
||||
acorn@8.16.0:
|
||||
resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
alien-signals@1.0.13:
|
||||
resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
|
||||
|
||||
ast-kit@2.2.0:
|
||||
resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
ast-walker-scope@0.8.3:
|
||||
resolution: {integrity: sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
birpc@2.9.0:
|
||||
resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==}
|
||||
|
||||
brace-expansion@2.0.3:
|
||||
resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==}
|
||||
|
||||
chokidar@5.0.0:
|
||||
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
confbox@0.1.8:
|
||||
resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
|
||||
|
||||
confbox@0.2.4:
|
||||
resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
|
||||
|
||||
csstype@3.2.3:
|
||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||
|
||||
@@ -542,6 +636,9 @@ packages:
|
||||
estree-walker@2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
exsolve@1.0.8:
|
||||
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
|
||||
|
||||
fdir@6.5.0:
|
||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -560,6 +657,27 @@ packages:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
|
||||
hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
|
||||
jsesc@3.1.0:
|
||||
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
json5@2.2.3:
|
||||
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
local-pkg@1.1.2:
|
||||
resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
magic-string-ast@1.0.3:
|
||||
resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
@@ -567,6 +685,9 @@ packages:
|
||||
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
mlly@1.8.2:
|
||||
resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
|
||||
|
||||
muggle-string@0.4.1:
|
||||
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
|
||||
|
||||
@@ -578,6 +699,12 @@ packages:
|
||||
path-browserify@1.0.1:
|
||||
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
|
||||
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
perfect-debounce@2.1.0:
|
||||
resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
@@ -585,15 +712,35 @@ packages:
|
||||
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
pkg-types@1.3.1:
|
||||
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
||||
|
||||
pkg-types@2.3.0:
|
||||
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
|
||||
|
||||
postcss@8.5.8:
|
||||
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
primevue@4.5.4:
|
||||
resolution: {integrity: sha512-nTyEohZABFJhVIpeUxgP0EJ8vKcJAhD+Z7DYj95e7ie/MNUCjRNcGjqmE1cXtXi4z54qDfTSI9h2uJ51qz2DIw==}
|
||||
engines: {node: '>=12.11.0'}
|
||||
|
||||
quansync@0.2.11:
|
||||
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
|
||||
|
||||
readdirp@5.0.0:
|
||||
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
rollup@4.60.0:
|
||||
resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
scule@1.3.0:
|
||||
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
|
||||
|
||||
source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -607,6 +754,17 @@ packages:
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
ufo@1.6.3:
|
||||
resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
|
||||
|
||||
unplugin-utils@0.3.1:
|
||||
resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
unplugin@3.0.0:
|
||||
resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
|
||||
vite@6.4.1:
|
||||
resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
@@ -650,6 +808,21 @@ packages:
|
||||
vscode-uri@3.1.0:
|
||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||
|
||||
vue-router@5.0.4:
|
||||
resolution: {integrity: sha512-lCqDLCI2+fKVRl2OzXuzdSWmxXFLQRxQbmHugnRpTMyYiT+hNaycV0faqG5FBHDXoYrZ6MQcX87BvbY8mQ20Bg==}
|
||||
peerDependencies:
|
||||
'@pinia/colada': '>=0.21.2'
|
||||
'@vue/compiler-sfc': ^3.5.17
|
||||
pinia: ^3.0.4
|
||||
vue: ^3.5.0
|
||||
peerDependenciesMeta:
|
||||
'@pinia/colada':
|
||||
optional: true
|
||||
'@vue/compiler-sfc':
|
||||
optional: true
|
||||
pinia:
|
||||
optional: true
|
||||
|
||||
vue-tsc@2.2.12:
|
||||
resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==}
|
||||
hasBin: true
|
||||
@@ -664,8 +837,24 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
webpack-virtual-modules@0.6.2:
|
||||
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
||||
|
||||
yaml@2.8.3:
|
||||
resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==}
|
||||
engines: {node: '>= 14.6'}
|
||||
hasBin: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@babel/generator@7.29.1':
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/types': 7.29.0
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jsesc: 3.1.0
|
||||
|
||||
'@babel/helper-string-parser@7.27.1': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.28.5': {}
|
||||
@@ -757,8 +946,52 @@ snapshots:
|
||||
'@esbuild/win32-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
|
||||
'@jridgewell/remapping@2.3.5':
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@primeuix/styled@0.7.4':
|
||||
dependencies:
|
||||
'@primeuix/utils': 0.6.4
|
||||
|
||||
'@primeuix/styles@2.0.3':
|
||||
dependencies:
|
||||
'@primeuix/styled': 0.7.4
|
||||
|
||||
'@primeuix/themes@2.0.3':
|
||||
dependencies:
|
||||
'@primeuix/styled': 0.7.4
|
||||
|
||||
'@primeuix/utils@0.6.4': {}
|
||||
|
||||
'@primevue/core@4.5.4(vue@3.5.31(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@primeuix/styled': 0.7.4
|
||||
'@primeuix/utils': 0.6.4
|
||||
vue: 3.5.31(typescript@5.6.3)
|
||||
|
||||
'@primevue/icons@4.5.4(vue@3.5.31(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@primeuix/utils': 0.6.4
|
||||
'@primevue/core': 4.5.4(vue@3.5.31(typescript@5.6.3))
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.60.0':
|
||||
optional: true
|
||||
|
||||
@@ -905,9 +1138,9 @@ snapshots:
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@vitejs/plugin-vue@5.2.4(vite@6.4.1)(vue@3.5.31(typescript@5.6.3))':
|
||||
'@vitejs/plugin-vue@5.2.4(vite@6.4.1(yaml@2.8.3))(vue@3.5.31(typescript@5.6.3))':
|
||||
dependencies:
|
||||
vite: 6.4.1
|
||||
vite: 6.4.1(yaml@2.8.3)
|
||||
vue: 3.5.31(typescript@5.6.3)
|
||||
|
||||
'@volar/language-core@2.4.15':
|
||||
@@ -922,6 +1155,16 @@ snapshots:
|
||||
path-browserify: 1.0.1
|
||||
vscode-uri: 3.1.0
|
||||
|
||||
'@vue-macros/common@3.1.2(vue@3.5.31(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@vue/compiler-sfc': 3.5.31
|
||||
ast-kit: 2.2.0
|
||||
local-pkg: 1.1.2
|
||||
magic-string-ast: 1.0.3
|
||||
unplugin-utils: 0.3.1
|
||||
optionalDependencies:
|
||||
vue: 3.5.31(typescript@5.6.3)
|
||||
|
||||
'@vue/compiler-core@3.5.31':
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.2
|
||||
@@ -957,6 +1200,19 @@ snapshots:
|
||||
de-indent: 1.0.2
|
||||
he: 1.2.0
|
||||
|
||||
'@vue/devtools-api@8.1.1':
|
||||
dependencies:
|
||||
'@vue/devtools-kit': 8.1.1
|
||||
|
||||
'@vue/devtools-kit@8.1.1':
|
||||
dependencies:
|
||||
'@vue/devtools-shared': 8.1.1
|
||||
birpc: 2.9.0
|
||||
hookable: 5.5.3
|
||||
perfect-debounce: 2.1.0
|
||||
|
||||
'@vue/devtools-shared@8.1.1': {}
|
||||
|
||||
'@vue/language-core@2.2.12(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.15
|
||||
@@ -994,14 +1250,36 @@ snapshots:
|
||||
|
||||
'@vue/shared@3.5.31': {}
|
||||
|
||||
acorn@8.16.0: {}
|
||||
|
||||
alien-signals@1.0.13: {}
|
||||
|
||||
ast-kit@2.2.0:
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.2
|
||||
pathe: 2.0.3
|
||||
|
||||
ast-walker-scope@0.8.3:
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.2
|
||||
ast-kit: 2.2.0
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
birpc@2.9.0: {}
|
||||
|
||||
brace-expansion@2.0.3:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
chokidar@5.0.0:
|
||||
dependencies:
|
||||
readdirp: 5.0.0
|
||||
|
||||
confbox@0.1.8: {}
|
||||
|
||||
confbox@0.2.4: {}
|
||||
|
||||
csstype@3.2.3: {}
|
||||
|
||||
de-indent@1.0.2: {}
|
||||
@@ -1039,6 +1317,8 @@ snapshots:
|
||||
|
||||
estree-walker@2.0.2: {}
|
||||
|
||||
exsolve@1.0.8: {}
|
||||
|
||||
fdir@6.5.0(picomatch@4.0.4):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.4
|
||||
@@ -1048,6 +1328,22 @@ snapshots:
|
||||
|
||||
he@1.2.0: {}
|
||||
|
||||
hookable@5.5.3: {}
|
||||
|
||||
jsesc@3.1.0: {}
|
||||
|
||||
json5@2.2.3: {}
|
||||
|
||||
local-pkg@1.1.2:
|
||||
dependencies:
|
||||
mlly: 1.8.2
|
||||
pkg-types: 2.3.0
|
||||
quansync: 0.2.11
|
||||
|
||||
magic-string-ast@1.0.3:
|
||||
dependencies:
|
||||
magic-string: 0.30.21
|
||||
|
||||
magic-string@0.30.21:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
@@ -1056,22 +1352,59 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.3
|
||||
|
||||
mlly@1.8.2:
|
||||
dependencies:
|
||||
acorn: 8.16.0
|
||||
pathe: 2.0.3
|
||||
pkg-types: 1.3.1
|
||||
ufo: 1.6.3
|
||||
|
||||
muggle-string@0.4.1: {}
|
||||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
path-browserify@1.0.1: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
perfect-debounce@2.1.0: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@4.0.4: {}
|
||||
|
||||
pkg-types@1.3.1:
|
||||
dependencies:
|
||||
confbox: 0.1.8
|
||||
mlly: 1.8.2
|
||||
pathe: 2.0.3
|
||||
|
||||
pkg-types@2.3.0:
|
||||
dependencies:
|
||||
confbox: 0.2.4
|
||||
exsolve: 1.0.8
|
||||
pathe: 2.0.3
|
||||
|
||||
postcss@8.5.8:
|
||||
dependencies:
|
||||
nanoid: 3.3.11
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
primevue@4.5.4(vue@3.5.31(typescript@5.6.3)):
|
||||
dependencies:
|
||||
'@primeuix/styled': 0.7.4
|
||||
'@primeuix/styles': 2.0.3
|
||||
'@primeuix/utils': 0.6.4
|
||||
'@primevue/core': 4.5.4(vue@3.5.31(typescript@5.6.3))
|
||||
'@primevue/icons': 4.5.4(vue@3.5.31(typescript@5.6.3))
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
quansync@0.2.11: {}
|
||||
|
||||
readdirp@5.0.0: {}
|
||||
|
||||
rollup@4.60.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@@ -1103,6 +1436,8 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc': 4.60.0
|
||||
fsevents: 2.3.3
|
||||
|
||||
scule@1.3.0: {}
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
@@ -1112,7 +1447,20 @@ snapshots:
|
||||
|
||||
typescript@5.6.3: {}
|
||||
|
||||
vite@6.4.1:
|
||||
ufo@1.6.3: {}
|
||||
|
||||
unplugin-utils@0.3.1:
|
||||
dependencies:
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.4
|
||||
|
||||
unplugin@3.0.0:
|
||||
dependencies:
|
||||
'@jridgewell/remapping': 2.3.5
|
||||
picomatch: 4.0.4
|
||||
webpack-virtual-modules: 0.6.2
|
||||
|
||||
vite@6.4.1(yaml@2.8.3):
|
||||
dependencies:
|
||||
esbuild: 0.25.12
|
||||
fdir: 6.5.0(picomatch@4.0.4)
|
||||
@@ -1122,9 +1470,33 @@ snapshots:
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
yaml: 2.8.3
|
||||
|
||||
vscode-uri@3.1.0: {}
|
||||
|
||||
vue-router@5.0.4(@vue/compiler-sfc@3.5.31)(vue@3.5.31(typescript@5.6.3)):
|
||||
dependencies:
|
||||
'@babel/generator': 7.29.1
|
||||
'@vue-macros/common': 3.1.2(vue@3.5.31(typescript@5.6.3))
|
||||
'@vue/devtools-api': 8.1.1
|
||||
ast-walker-scope: 0.8.3
|
||||
chokidar: 5.0.0
|
||||
json5: 2.2.3
|
||||
local-pkg: 1.1.2
|
||||
magic-string: 0.30.21
|
||||
mlly: 1.8.2
|
||||
muggle-string: 0.4.1
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.4
|
||||
scule: 1.3.0
|
||||
tinyglobby: 0.2.15
|
||||
unplugin: 3.0.0
|
||||
unplugin-utils: 0.3.1
|
||||
vue: 3.5.31(typescript@5.6.3)
|
||||
yaml: 2.8.3
|
||||
optionalDependencies:
|
||||
'@vue/compiler-sfc': 3.5.31
|
||||
|
||||
vue-tsc@2.2.12(typescript@5.6.3):
|
||||
dependencies:
|
||||
'@volar/typescript': 2.4.15
|
||||
@@ -1140,3 +1512,7 @@ snapshots:
|
||||
'@vue/shared': 3.5.31
|
||||
optionalDependencies:
|
||||
typescript: 5.6.3
|
||||
|
||||
webpack-virtual-modules@0.6.2: {}
|
||||
|
||||
yaml@2.8.3: {}
|
||||
Generated
+3
@@ -673,8 +673,11 @@ dependencies = [
|
||||
"tauri-plugin-http",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-sql",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"vibrato-rkyv",
|
||||
"zip",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -29,3 +29,6 @@ tauri-plugin-clipboard-manager = "2"
|
||||
zip = "8.1.0"
|
||||
blake3 = "1.8.3"
|
||||
vibrato-rkyv = "0.7.5"
|
||||
tokio = { version = "1.50.0", features = ["io-util"] }
|
||||
thiserror = "2.0.18"
|
||||
zstd = "0.13.3"
|
||||
@@ -1,4 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">cjdic2-next</string>
|
||||
<string name="main_activity_title">cjdic2-next</string>
|
||||
<string name="app_name">cjdic2</string>
|
||||
<string name="main_activity_title">cjdic2</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,110 @@
|
||||
use serde::Serialize;
|
||||
use std::{fs::remove_file, path::PathBuf};
|
||||
use tauri::{AppHandle, Emitter, Manager};
|
||||
use tauri_plugin_http::reqwest::Client;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
use crate::{error::CJDicError, service::AppService};
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn tokenize(
|
||||
text: String,
|
||||
state: tauri::State<'_, AppService>,
|
||||
) -> Result<Vec<String>, CJDicError> {
|
||||
state.tokenize(text)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn normalize(
|
||||
text: String,
|
||||
state: tauri::State<'_, AppService>,
|
||||
) -> Result<Vec<String>, CJDicError> {
|
||||
state.normalize(text)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
struct DownloadProgress {
|
||||
url: String,
|
||||
filepath: String,
|
||||
content_length: u64,
|
||||
downloaded: u64,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn download_url(app: AppHandle, url: &str, filepath: &str) -> Result<bool, CJDicError> {
|
||||
download_url_local(url, &app.path().app_data_dir()?, filepath, |progress| {
|
||||
app.emit("download-url-progress", progress).unwrap();
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn download_url_local(
|
||||
url: &str,
|
||||
rootdir: &PathBuf,
|
||||
filepath: &str,
|
||||
callback: impl Fn(DownloadProgress),
|
||||
) -> Result<bool, CJDicError> {
|
||||
let client = Client::new();
|
||||
let file_pf = rootdir.join(filepath);
|
||||
|
||||
let temp_pf = rootdir.join(format!("{}.dl-tmp", filepath));
|
||||
let temp_path = temp_pf.as_path();
|
||||
// Check existing partial download size
|
||||
let existing_size = tokio::fs::metadata(temp_path)
|
||||
.await
|
||||
.map(|m| m.len())
|
||||
.unwrap_or(0);
|
||||
|
||||
let mut request = client.get(url);
|
||||
// Request only the remaining bytes
|
||||
if existing_size > 0 {
|
||||
request = request.header("Range", format!("bytes={}-", existing_size));
|
||||
}
|
||||
|
||||
// Making the asynchronous GET request
|
||||
let mut response = request.send().await?;
|
||||
|
||||
// Check if the request was successful
|
||||
if response.status().is_success() {
|
||||
let content_length = response.content_length().unwrap_or(0);
|
||||
let mut file = if existing_size > 0 {
|
||||
tokio::fs::OpenOptions::new()
|
||||
.append(true)
|
||||
.open(temp_path)
|
||||
.await?
|
||||
} else {
|
||||
tokio::fs::File::create(&file_pf).await?
|
||||
};
|
||||
|
||||
// Downloading the file in chunks
|
||||
let mut downloaded: u64 = 0;
|
||||
while let Some(chunk) = response.chunk().await? {
|
||||
file.write_all(&chunk).await?;
|
||||
downloaded += chunk.len() as u64;
|
||||
|
||||
callback(DownloadProgress {
|
||||
url: url.to_owned(),
|
||||
filepath: filepath.to_owned(),
|
||||
content_length,
|
||||
downloaded,
|
||||
});
|
||||
}
|
||||
|
||||
// Verify download completeness
|
||||
if content_length > 0 && downloaded < content_length {
|
||||
// Delete incomplete file
|
||||
drop(file); // ensure file handle is released before deleting
|
||||
remove_file(&file_pf).ok();
|
||||
return Err(CJDicError::Error(format!(
|
||||
"Incomplete download: expected {} bytes, got {}",
|
||||
content_length, downloaded
|
||||
)));
|
||||
}
|
||||
|
||||
println!("File downloaded successfully to {:?}", &file_pf);
|
||||
} else {
|
||||
eprintln!("Failed to download file: {:?}", response.status());
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use vibrato_rkyv::Tokenizer;
|
||||
|
||||
pub struct AppService {
|
||||
tokenizer: Tokenizer,
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
use std::{backtrace::Backtrace, string::FromUtf8Error};
|
||||
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
use vibrato_rkyv::errors::VibratoError;
|
||||
use zip::result::ZipError;
|
||||
|
||||
#[derive(Debug, Error, Serialize)]
|
||||
#[serde(tag = "kind", content = "message")]
|
||||
pub enum CJDicError {
|
||||
#[error("SerializationError: {0}")]
|
||||
SerializationError(String),
|
||||
|
||||
#[error("IOError: {0}")]
|
||||
IOError(String),
|
||||
|
||||
#[error("ZipError: {0}")]
|
||||
ZipError(String),
|
||||
|
||||
#[error("VibratoError: {0}")]
|
||||
VibratoError(String),
|
||||
|
||||
#[error("FromUtf8Error: {0}")]
|
||||
FromUtf8Error(String),
|
||||
|
||||
#[error("TauriError: {0}")]
|
||||
TauriError(String),
|
||||
|
||||
#[error("TauriReqwestError: {0}")]
|
||||
TauriReqwestError(String),
|
||||
|
||||
#[error("Error: {0}")]
|
||||
Error(String),
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for CJDicError {
|
||||
fn from(e: serde_json::Error) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::SerializationError(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for CJDicError {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::IOError(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ZipError> for CJDicError {
|
||||
fn from(e: ZipError) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::ZipError(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VibratoError> for CJDicError {
|
||||
fn from(e: VibratoError) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::VibratoError(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FromUtf8Error> for CJDicError {
|
||||
fn from(e: FromUtf8Error) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::FromUtf8Error(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<tauri::Error> for CJDicError {
|
||||
fn from(e: tauri::Error) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::TauriError(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<tauri_plugin_http::reqwest::Error> for CJDicError {
|
||||
fn from(e: tauri_plugin_http::reqwest::Error) -> Self {
|
||||
let bt = Backtrace::capture();
|
||||
eprintln!("{e:#}\n{bt}");
|
||||
CJDicError::TauriReqwestError(e.to_string())
|
||||
}
|
||||
}
|
||||
+57
-3
@@ -1,4 +1,17 @@
|
||||
mod core;
|
||||
use std::fs::{create_dir_all, File};
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_fs::FsExt;
|
||||
|
||||
use crate::command::*;
|
||||
use crate::service::AppService;
|
||||
use crate::yomitan::search::YomitanSearch;
|
||||
|
||||
mod tokenizer;
|
||||
mod yomitan;
|
||||
|
||||
mod command;
|
||||
mod error;
|
||||
mod service;
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
#[tauri::command]
|
||||
@@ -11,10 +24,51 @@ pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_clipboard_manager::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_sql::Builder::new().build())
|
||||
.plugin(
|
||||
tauri_plugin_sql::Builder::default()
|
||||
.add_migrations("sqlite:search.db", YomitanSearch::migrations())
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_http::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![greet])
|
||||
.setup(|app| {
|
||||
let config_dir = app.path().app_config_dir()?;
|
||||
create_dir_all(&config_dir)?;
|
||||
|
||||
let data_dir = app.path().app_data_dir()?;
|
||||
create_dir_all(&data_dir.join("yomitan/ja"))?;
|
||||
|
||||
let cache_dir = app.path().app_cache_dir()?;
|
||||
let vibrato_dic_dir = cache_dir.join("vibrato");
|
||||
create_dir_all(&vibrato_dic_dir)?;
|
||||
|
||||
let vibrato_dic_path = vibrato_dic_dir.join("system.dic");
|
||||
if !vibrato_dic_path.exists() {
|
||||
let zst_path = app.path().resolve(
|
||||
"resources/mecab-ipadic/system.dic.zst",
|
||||
tauri::path::BaseDirectory::Resource,
|
||||
)?;
|
||||
|
||||
// Use Tauri's fs abstraction — works on both Android and desktop
|
||||
let bytes = app.fs().read(&zst_path)?;
|
||||
|
||||
let mut decoder = zstd::Decoder::new(bytes.as_slice())?;
|
||||
let mut out = File::create(&vibrato_dic_path)?;
|
||||
std::io::copy(&mut decoder, &mut out)?;
|
||||
}
|
||||
|
||||
// db_path is at config_dir;
|
||||
let service = AppService::new(&vibrato_dic_path)?;
|
||||
app.manage(service);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
greet,
|
||||
tokenize,
|
||||
normalize,
|
||||
download_url
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{error::CJDicError, tokenizer::ja::Tokenizer};
|
||||
|
||||
pub struct AppService {
|
||||
pub ja_tokenizer: Tokenizer,
|
||||
}
|
||||
|
||||
impl AppService {
|
||||
pub fn new(vibrato_dic: impl AsRef<Path>) -> Result<Self, CJDicError> {
|
||||
Ok(Self {
|
||||
ja_tokenizer: Tokenizer::new(vibrato_dic)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn tokenize(&self, text: String) -> Result<Vec<String>, CJDicError> {
|
||||
self.ja_tokenizer.tokenize(text)
|
||||
}
|
||||
|
||||
pub fn normalize(&self, text: String) -> Result<Vec<String>, CJDicError> {
|
||||
self.ja_tokenizer.normalize(text)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
use std::{collections::HashSet, fs::File, io::BufReader, path::Path};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::error::CJDicError;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct TokenizeSegment {
|
||||
pub surface: String,
|
||||
/// ```txt
|
||||
/// 0 品詞 Part-of-speech
|
||||
/// 1 品詞細分類1 Part-of-speech subcategory 1
|
||||
/// 2 品詞細分類2 Part-of-speech subcategory 2
|
||||
/// 3 品詞細分類3 Part-of-speech subcategory 3
|
||||
/// 4 活用形 Conjugation form
|
||||
/// 5 活用型 Conjugation type
|
||||
/// 6 原形 Base form
|
||||
/// 7 読み Reading
|
||||
/// 8 発音 Pronunciation
|
||||
/// ```
|
||||
/// @see https://lindera.github.io/lindera/dictionaries/ipadic.html
|
||||
pub details: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Tokenizer {
|
||||
tokenizer: vibrato_rkyv::Tokenizer,
|
||||
exclude_pos: HashSet<String>,
|
||||
}
|
||||
|
||||
impl Tokenizer {
|
||||
pub fn new(vibrato_dic: impl AsRef<Path>) -> Result<Self, CJDicError> {
|
||||
let reader = BufReader::new(File::open(vibrato_dic)?);
|
||||
let dictionary = vibrato_rkyv::Dictionary::read(reader)?;
|
||||
Ok(Self {
|
||||
tokenizer: vibrato_rkyv::Tokenizer::new(dictionary),
|
||||
exclude_pos: HashSet::from(["助詞", "助動詞", "記号", "接続詞"].map(|p| p.to_string())),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn tokenize(&self, text: String) -> Result<Vec<String>, CJDicError> {
|
||||
let mut segmented: Vec<String> = vec![];
|
||||
for t in self.ja_tokenize(text)? {
|
||||
segmented.push(t.surface);
|
||||
}
|
||||
Ok(segmented)
|
||||
}
|
||||
|
||||
fn ja_tokenize(&self, text: String) -> Result<Vec<TokenizeSegment>, CJDicError> {
|
||||
let mut worker = self.tokenizer.new_worker();
|
||||
worker.reset_sentence(text);
|
||||
worker.tokenize();
|
||||
|
||||
let mut output: Vec<TokenizeSegment> = vec![];
|
||||
|
||||
for token in worker.token_iter() {
|
||||
let surface = token.surface().to_string();
|
||||
let details = token.feature().split(",").map(|s| s.to_string()).collect();
|
||||
|
||||
output.push(TokenizeSegment { surface, details });
|
||||
}
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
pub fn normalize(&self, text: String) -> Result<Vec<String>, CJDicError> {
|
||||
let mut segmented: Vec<String> = vec![];
|
||||
for t in self.ja_tokenize(text)? {
|
||||
let mut surface = t.surface;
|
||||
let mut pos = None;
|
||||
|
||||
for (i, dt) in t.details.iter().enumerate() {
|
||||
match i {
|
||||
0 => pos = Some(dt),
|
||||
6 => {
|
||||
let base = dt.to_string();
|
||||
if base != "*" {
|
||||
surface = base
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(p) = pos {
|
||||
if self.exclude_pos.contains(p.as_str()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
segmented.push(surface);
|
||||
}
|
||||
|
||||
Ok(segmented)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod ja;
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod search;
|
||||
pub mod unzip;
|
||||
@@ -0,0 +1,75 @@
|
||||
use tauri_plugin_sql::{Migration, MigrationKind};
|
||||
|
||||
pub struct YomitanSearch;
|
||||
|
||||
impl YomitanSearch {
|
||||
pub fn migrations() -> Vec<Migration> {
|
||||
vec![
|
||||
Migration {
|
||||
version: 1,
|
||||
description: "create yomitan dict-version tables",
|
||||
sql: "
|
||||
CREATE TABLE dict (
|
||||
id INTEGER PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
revision TEXT NOT NULL,
|
||||
author TEXT,
|
||||
url TEXT,
|
||||
description TEXT,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
installed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
bundle_name TEXT, -- custom
|
||||
lang TEXT NOT NULL, -- custom
|
||||
asset_count INTEGER, -- custom
|
||||
source TEXT, -- custom
|
||||
UNIQUE (title, revision)
|
||||
);
|
||||
",
|
||||
kind: MigrationKind::Up,
|
||||
},
|
||||
Migration {
|
||||
version: 1,
|
||||
description: "create yomitan ja query tables",
|
||||
sql: "
|
||||
CREATE TABLE ja_search (
|
||||
id INTEGER NOT NULL, -- yomitan.terms.id OR yomitan dups OR -user.terms.id
|
||||
dict_id INTEGER NOT NULL REFERENCES dict(id) ON DELETE CASCADE,
|
||||
term TEXT NOT NULL, -- normalized
|
||||
term_seg TEXT, -- segmented and filtered for fillers
|
||||
reading TEXT NOT NULL, -- normalized
|
||||
frequency INTEGER,
|
||||
PRIMARY KEY (id, dict_id)
|
||||
);
|
||||
|
||||
CREATE INDEX ja_search_term ON ja_search (term);
|
||||
CREATE INDEX ja_search_reading ON ja_search (reading);
|
||||
CREATE INDEX ja_search_frequency ON ja_search (frequency DESC);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS ja_search_ft USING fts5 (
|
||||
term_seg,
|
||||
content='ja_search',
|
||||
content_rowid='rowid',
|
||||
tokenize=unicode61
|
||||
);
|
||||
|
||||
CREATE TRIGGER t_ja_search_ft_after_insert
|
||||
AFTER INSERT ON ja_search BEGIN
|
||||
INSERT INTO ja_search_ft (rowid, term_seg) VALUES (NEW.rowid, NEW.term_seg);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER t_ja_search_ft_after_delete
|
||||
AFTER DELETE ON ja_search BEGIN
|
||||
INSERT INTO ja_search_ft (ja_search_ft, rowid, term_seg) VALUES ('delete', OLD.rowid, OLD.term_seg);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER t_ja_search_ft_after_update
|
||||
AFTER UPDATE ON ja_search BEGIN
|
||||
INSERT INTO ja_search_ft (ja_search_ft, rowid, term_seg) VALUES ('delete', OLD.rowid, OLD.term_seg);
|
||||
INSERT INTO ja_search_ft (rowid, term_seg) VALUES (NEW.rowid, NEW.term_seg);
|
||||
END;
|
||||
",
|
||||
kind: MigrationKind::Up
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "cjdic2-next",
|
||||
"productName": "cjdic2",
|
||||
"version": "0.1.0",
|
||||
"identifier": "cc.polv.cjdic2.next",
|
||||
"build": {
|
||||
@@ -12,7 +12,7 @@
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "cjdic2-next",
|
||||
"title": "cjdic2",
|
||||
"width": 1024,
|
||||
"height": 768,
|
||||
"maximized": true
|
||||
|
||||
+43
-142
@@ -1,160 +1,61 @@
|
||||
<script setup lang="ts">
|
||||
import Button from "primevue/button";
|
||||
import Dialog from "primevue/dialog";
|
||||
import { ref } from "vue";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
const greetMsg = ref("");
|
||||
const name = ref("");
|
||||
|
||||
async function greet() {
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
greetMsg.value = await invoke("greet", { name: name.value });
|
||||
}
|
||||
const isLoading = ref(true);
|
||||
const isReady = ref(false);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="container">
|
||||
<h1>Welcome to Tauri + Vue</h1>
|
||||
|
||||
<div class="row">
|
||||
<a href="https://vite.dev" target="_blank">
|
||||
<img src="/vite.svg" class="logo vite" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://tauri.app" target="_blank">
|
||||
<img src="/tauri.svg" class="logo tauri" alt="Tauri logo" />
|
||||
</a>
|
||||
<a href="https://vuejs.org/" target="_blank">
|
||||
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
||||
</a>
|
||||
</div>
|
||||
<p>Click on the Tauri, Vite, and Vue logos to learn more.</p>
|
||||
|
||||
<form class="row" @submit.prevent="greet">
|
||||
<input id="greet-input" v-model="name" placeholder="Enter a name..." />
|
||||
<button type="submit">Greet</button>
|
||||
</form>
|
||||
<p>{{ greetMsg }}</p>
|
||||
<main>
|
||||
<RouterView />
|
||||
<Dialog v-model:visible="isLoading" modal>
|
||||
<template #container>
|
||||
<aside class="loading-dialog">
|
||||
<div class="container"></div>
|
||||
<nav>
|
||||
<Button
|
||||
class="btn cancel"
|
||||
label="Cancel"
|
||||
variant="outlined"
|
||||
severity="secondary"
|
||||
@click="
|
||||
isLoading = false;
|
||||
isReady = true;
|
||||
"
|
||||
autofocus
|
||||
/>
|
||||
</nav>
|
||||
</aside>
|
||||
</template>
|
||||
</Dialog>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo.vite:hover {
|
||||
filter: drop-shadow(0 0 2em #747bff);
|
||||
}
|
||||
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #249b73);
|
||||
}
|
||||
|
||||
</style>
|
||||
<style>
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color: #0f0f0f;
|
||||
background-color: #f6f6f6;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0;
|
||||
padding-top: 10vh;
|
||||
.loading-dialog {
|
||||
width: 1000px;
|
||||
max-width: 90vw;
|
||||
min-height: 50vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: 0.75s;
|
||||
}
|
||||
.container {
|
||||
flex-grow: 1;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.logo.tauri:hover {
|
||||
filter: drop-shadow(0 0 2em #24c8db);
|
||||
}
|
||||
|
||||
.row {
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
color: #0f0f0f;
|
||||
background-color: #ffffff;
|
||||
transition: border-color 0.25s;
|
||||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: #396cd8;
|
||||
}
|
||||
button:active {
|
||||
border-color: #396cd8;
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#greet-input {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
color: #f6f6f6;
|
||||
background-color: #2f2f2f;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #24c8db;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
color: #ffffff;
|
||||
background-color: #0f0f0f98;
|
||||
}
|
||||
button:active {
|
||||
background-color: #0f0f0f69;
|
||||
flex-direction: row-reverse;
|
||||
padding: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
</style>
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 496 B |
+11
-3
@@ -1,4 +1,12 @@
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import Aura from "@primeuix/themes/aura";
|
||||
import PrimeVue from "primevue/config";
|
||||
|
||||
createApp(App).mount("#app");
|
||||
import { createApp } from "vue";
|
||||
|
||||
import App from "./App.vue";
|
||||
import { router } from "./router";
|
||||
|
||||
createApp(App)
|
||||
.use(router)
|
||||
.use(PrimeVue, { theme: { preset: Aura } })
|
||||
.mount("#app");
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Welcome to Tauri + Vue</h1>
|
||||
|
||||
<div class="row">
|
||||
<a href="https://vite.dev" target="_blank">
|
||||
<img src="/vite.svg" class="logo vite" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://tauri.app" target="_blank">
|
||||
<img src="/tauri.svg" class="logo tauri" alt="Tauri logo" />
|
||||
</a>
|
||||
</div>
|
||||
<p style="text-align: center">Click on the Tauri, and Vite logos to learn more.</p>
|
||||
|
||||
<form class="row" @submit.prevent="greet">
|
||||
<InputText id="greet-input" v-model="name" placeholder="Enter a name..." />
|
||||
<Button type="submit">Greet</Button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
import Button from "primevue/button";
|
||||
import InputText from "primevue/inputtext";
|
||||
|
||||
import { ref } from "vue";
|
||||
|
||||
const greetMsg = ref("");
|
||||
const name = ref("");
|
||||
|
||||
async function greet() {
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
greetMsg.value = await invoke("greet", { name: name.value });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: 0.75s;
|
||||
|
||||
&.tauri:hover {
|
||||
filter: drop-shadow(0 0 2em #24c8db);
|
||||
}
|
||||
|
||||
&.vite:hover {
|
||||
filter: drop-shadow(0 0 2em #747bff);
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,10 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
|
||||
import SearchView from "./pages/SearchView.vue";
|
||||
|
||||
const routes = [{ path: "/", component: SearchView }];
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes,
|
||||
});
|
||||
Reference in new issue
Block a user