mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Sat Feb 28 19:45:37 CET 2026
This commit is contained in:
@@ -1285,3 +1285,4 @@ Update On Tue Feb 24 20:15:23 CET 2026
|
||||
Update On Wed Feb 25 20:17:35 CET 2026
|
||||
Update On Thu Feb 26 20:04:04 CET 2026
|
||||
Update On Fri Feb 27 19:57:47 CET 2026
|
||||
Update On Sat Feb 28 19:45:29 CET 2026
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"lodash-es": "4.17.23",
|
||||
"ofetch": "1.5.1",
|
||||
"react": "19.2.4",
|
||||
"swr": "2.4.0"
|
||||
"swr": "2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "4.17.12",
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"react-split-grid": "1.0.4",
|
||||
"react-use": "17.6.0",
|
||||
"rxjs": "7.8.2",
|
||||
"swr": "2.4.0",
|
||||
"swr": "2.4.1",
|
||||
"virtua": "0.46.6",
|
||||
"vite-bundle-visualizer": "1.2.1"
|
||||
},
|
||||
@@ -75,7 +75,7 @@
|
||||
"@csstools/normalize.css": "12.1.1",
|
||||
"@emotion/babel-plugin": "11.13.5",
|
||||
"@emotion/react": "11.14.0",
|
||||
"@iconify/json": "2.2.443",
|
||||
"@iconify/json": "2.2.444",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@tanstack/react-query": "5.90.21",
|
||||
"@tanstack/react-router": "1.161.4",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.20",
|
||||
"mihomo_alpha": "alpha-f6722ab",
|
||||
"mihomo_alpha": "alpha-3035ae8",
|
||||
"clash_rs": "v0.9.4",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.9.4-alpha+sha.ce8c715"
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2026-02-25T22:29:27.456Z"
|
||||
"updated_at": "2026-02-27T22:21:57.836Z"
|
||||
}
|
||||
|
||||
@@ -62,14 +62,14 @@
|
||||
"@tauri-apps/cli": "2.10.0",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/node": "24.10.15",
|
||||
"@types/node": "24.11.0",
|
||||
"autoprefixer": "10.4.27",
|
||||
"conventional-changelog-conventionalcommits": "9.1.0",
|
||||
"cross-env": "10.1.0",
|
||||
"dedent": "1.7.1",
|
||||
"globals": "17.3.0",
|
||||
"knip": "5.85.0",
|
||||
"lint-staged": "16.2.7",
|
||||
"lint-staged": "16.3.0",
|
||||
"npm-run-all2": "8.0.4",
|
||||
"oxlint": "1.50.0",
|
||||
"postcss": "8.5.6",
|
||||
|
||||
Generated
+106
-87
@@ -24,7 +24,7 @@ importers:
|
||||
devDependencies:
|
||||
'@commitlint/cli':
|
||||
specifier: 20.4.2
|
||||
version: 20.4.2(@types/node@24.10.15)(typescript@5.9.3)
|
||||
version: 20.4.2(@types/node@24.11.0)(typescript@5.9.3)
|
||||
'@commitlint/config-conventional':
|
||||
specifier: 20.4.2
|
||||
version: 20.4.2
|
||||
@@ -41,8 +41,8 @@ importers:
|
||||
specifier: 4.17.12
|
||||
version: 4.17.12
|
||||
'@types/node':
|
||||
specifier: 24.10.15
|
||||
version: 24.10.15
|
||||
specifier: 24.11.0
|
||||
version: 24.11.0
|
||||
autoprefixer:
|
||||
specifier: 10.4.27
|
||||
version: 10.4.27(postcss@8.5.6)
|
||||
@@ -60,10 +60,10 @@ importers:
|
||||
version: 17.3.0
|
||||
knip:
|
||||
specifier: 5.85.0
|
||||
version: 5.85.0(@types/node@24.10.15)(typescript@5.9.3)
|
||||
version: 5.85.0(@types/node@24.11.0)(typescript@5.9.3)
|
||||
lint-staged:
|
||||
specifier: 16.2.7
|
||||
version: 16.2.7
|
||||
specifier: 16.3.0
|
||||
version: 16.3.0
|
||||
npm-run-all2:
|
||||
specifier: 8.0.4
|
||||
version: 8.0.4
|
||||
@@ -149,8 +149,8 @@ importers:
|
||||
specifier: 19.2.4
|
||||
version: 19.2.4
|
||||
swr:
|
||||
specifier: 2.4.0
|
||||
version: 2.4.0(react@19.2.4)
|
||||
specifier: 2.4.1
|
||||
version: 2.4.1(react@19.2.4)
|
||||
devDependencies:
|
||||
'@types/lodash-es':
|
||||
specifier: 4.17.12
|
||||
@@ -333,8 +333,8 @@ importers:
|
||||
specifier: 7.8.2
|
||||
version: 7.8.2
|
||||
swr:
|
||||
specifier: 2.4.0
|
||||
version: 2.4.0(react@19.2.4)
|
||||
specifier: 2.4.1
|
||||
version: 2.4.1(react@19.2.4)
|
||||
virtua:
|
||||
specifier: 0.46.6
|
||||
version: 0.46.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.5)
|
||||
@@ -352,8 +352,8 @@ importers:
|
||||
specifier: 11.14.0
|
||||
version: 11.14.0(@types/react@19.2.14)(react@19.2.4)
|
||||
'@iconify/json':
|
||||
specifier: 2.2.443
|
||||
version: 2.2.443
|
||||
specifier: 2.2.444
|
||||
version: 2.2.444
|
||||
'@monaco-editor/react':
|
||||
specifier: 4.7.0
|
||||
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -368,7 +368,7 @@ importers:
|
||||
version: 1.161.4(@tanstack/react-router@1.161.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.161.4)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@tanstack/router-plugin':
|
||||
specifier: 1.161.4
|
||||
version: 1.161.4(@tanstack/react-router@1.161.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 1.161.4(@tanstack/react-router@1.161.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
'@tauri-apps/plugin-clipboard-manager':
|
||||
specifier: 2.3.2
|
||||
version: 2.3.2
|
||||
@@ -404,13 +404,13 @@ importers:
|
||||
version: 13.15.10
|
||||
'@vitejs/plugin-legacy':
|
||||
specifier: 7.2.1
|
||||
version: 7.2.1(terser@5.36.0)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 7.2.1(terser@5.36.0)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 5.1.4
|
||||
version: 5.1.4(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 5.1.4(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
'@vitejs/plugin-react-swc':
|
||||
specifier: 4.2.3
|
||||
version: 4.2.3(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 4.2.3(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
change-case:
|
||||
specifier: 5.4.4
|
||||
version: 5.4.4
|
||||
@@ -449,19 +449,19 @@ importers:
|
||||
version: 13.15.26
|
||||
vite:
|
||||
specifier: 7.3.1
|
||||
version: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
version: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vite-plugin-html:
|
||||
specifier: 3.2.2
|
||||
version: 3.2.2(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 3.2.2(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-plugin-sass-dts:
|
||||
specifier: 1.3.35
|
||||
version: 1.3.35(postcss@8.5.6)(prettier@3.8.1)(sass-embedded@1.97.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 1.3.35(postcss@8.5.6)(prettier@3.8.1)(sass-embedded@1.97.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-plugin-svgr:
|
||||
specifier: 4.5.0
|
||||
version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-tsconfig-paths:
|
||||
specifier: 6.1.1
|
||||
version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
zod:
|
||||
specifier: 4.3.6
|
||||
version: 4.3.6
|
||||
@@ -497,7 +497,7 @@ importers:
|
||||
version: 19.2.14
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 5.1.4
|
||||
version: 5.1.4(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 5.1.4(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
ahooks:
|
||||
specifier: 3.9.6
|
||||
version: 3.9.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -527,10 +527,10 @@ importers:
|
||||
version: 4.2.1
|
||||
vite:
|
||||
specifier: 7.3.1
|
||||
version: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
version: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vite-tsconfig-paths:
|
||||
specifier: 6.1.1
|
||||
version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
devDependencies:
|
||||
'@emotion/react':
|
||||
specifier: 11.14.0
|
||||
@@ -555,7 +555,7 @@ importers:
|
||||
version: 5.2.0(typescript@5.9.3)
|
||||
vite-plugin-dts:
|
||||
specifier: 4.5.4
|
||||
version: 4.5.4(@types/node@24.10.15)(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
version: 4.5.4(@types/node@24.11.0)(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
|
||||
scripts:
|
||||
dependencies:
|
||||
@@ -1686,8 +1686,8 @@ packages:
|
||||
prettier-plugin-ember-template-tag:
|
||||
optional: true
|
||||
|
||||
'@iconify/json@2.2.443':
|
||||
resolution: {integrity: sha512-xyDqw1FeuNWPhYj+Sp2I1kyD6J5U5s8GxEW+dgIY1/Vl0b65t+PlRVCxEBtx73CanfDUPrSEHbxKQJwzXrcV/w==}
|
||||
'@iconify/json@2.2.444':
|
||||
resolution: {integrity: sha512-z0UwFaVtaN/h/iWZ1kzEjqFU3sp0rRy93tzOtpepZU89DY39WsNeYZv2mxtft/2La6Bz2b4z1C/HkU5Cqv3gbw==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
@@ -3894,8 +3894,8 @@ packages:
|
||||
'@types/ms@0.7.34':
|
||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||
|
||||
'@types/node@24.10.15':
|
||||
resolution: {integrity: sha512-BgjLoRuSr0MTI5wA6gMw9Xy0sFudAaUuvrnjgGx9wZ522fYYLA5SYJ+1Y30vTcJEG+DRCyDHx/gzQVfofYzSdg==}
|
||||
'@types/node@24.11.0':
|
||||
resolution: {integrity: sha512-fPxQqz4VTgPI/IQ+lj9r0h+fDR66bzoeMGHp8ASee+32OSGIkeASsoZuJixsQoVef1QJbeubcPBxKk22QVoWdw==}
|
||||
|
||||
'@types/parse-json@4.0.2':
|
||||
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
||||
@@ -4490,6 +4490,10 @@ packages:
|
||||
resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
commander@14.0.3:
|
||||
resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
commander@2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
|
||||
@@ -5682,8 +5686,8 @@ packages:
|
||||
lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
|
||||
lint-staged@16.2.7:
|
||||
resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==}
|
||||
lint-staged@16.3.0:
|
||||
resolution: {integrity: sha512-YVHHy/p6U4/No9Af+35JLh3umJ9dPQnGTvNCbfO/T5fC60us0jFnc+vw33cqveI+kqxIFJQakcMVTO2KM+653A==}
|
||||
engines: {node: '>=20.17'}
|
||||
hasBin: true
|
||||
|
||||
@@ -7079,8 +7083,8 @@ packages:
|
||||
svg-tags@1.0.0:
|
||||
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
|
||||
|
||||
swr@2.4.0:
|
||||
resolution: {integrity: sha512-sUlC20T8EOt1pHmDiqueUWMmRRX03W7w5YxovWX7VR2KHEPCTMly85x05vpkP5i6Bu4h44ePSMD9Tc+G2MItFw==}
|
||||
swr@2.4.1:
|
||||
resolution: {integrity: sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA==}
|
||||
peerDependencies:
|
||||
react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
@@ -7134,6 +7138,10 @@ packages:
|
||||
tinyexec@1.0.1:
|
||||
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
|
||||
|
||||
tinyexec@1.0.2:
|
||||
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -7591,6 +7599,11 @@ packages:
|
||||
engines: {node: '>= 14.6'}
|
||||
hasBin: true
|
||||
|
||||
yaml@2.8.2:
|
||||
resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
|
||||
engines: {node: '>= 14.6'}
|
||||
hasBin: true
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -8485,11 +8498,11 @@ snapshots:
|
||||
hashery: 1.3.0
|
||||
keyv: 5.6.0
|
||||
|
||||
'@commitlint/cli@20.4.2(@types/node@24.10.15)(typescript@5.9.3)':
|
||||
'@commitlint/cli@20.4.2(@types/node@24.11.0)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@commitlint/format': 20.4.0
|
||||
'@commitlint/lint': 20.4.2
|
||||
'@commitlint/load': 20.4.0(@types/node@24.10.15)(typescript@5.9.3)
|
||||
'@commitlint/load': 20.4.0(@types/node@24.11.0)(typescript@5.9.3)
|
||||
'@commitlint/read': 20.4.0
|
||||
'@commitlint/types': 20.4.0
|
||||
tinyexec: 1.0.1
|
||||
@@ -8536,14 +8549,14 @@ snapshots:
|
||||
'@commitlint/rules': 20.4.2
|
||||
'@commitlint/types': 20.4.0
|
||||
|
||||
'@commitlint/load@20.4.0(@types/node@24.10.15)(typescript@5.9.3)':
|
||||
'@commitlint/load@20.4.0(@types/node@24.11.0)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@commitlint/config-validator': 20.4.0
|
||||
'@commitlint/execute-rule': 20.0.0
|
||||
'@commitlint/resolve-extends': 20.4.0
|
||||
'@commitlint/types': 20.4.0
|
||||
cosmiconfig: 9.0.0(typescript@5.9.3)
|
||||
cosmiconfig-typescript-loader: 6.1.0(@types/node@24.10.15)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3)
|
||||
cosmiconfig-typescript-loader: 6.1.0(@types/node@24.11.0)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3)
|
||||
is-plain-obj: 4.1.0
|
||||
lodash.mergewith: 4.6.2
|
||||
picocolors: 1.1.1
|
||||
@@ -8894,7 +8907,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@iconify/json@2.2.443':
|
||||
'@iconify/json@2.2.444':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 2.0.3
|
||||
@@ -8989,23 +9002,23 @@ snapshots:
|
||||
|
||||
'@material/material-color-utilities@0.4.0': {}
|
||||
|
||||
'@microsoft/api-extractor-model@7.30.3(@types/node@24.10.15)':
|
||||
'@microsoft/api-extractor-model@7.30.3(@types/node@24.11.0)':
|
||||
dependencies:
|
||||
'@microsoft/tsdoc': 0.15.1
|
||||
'@microsoft/tsdoc-config': 0.17.1
|
||||
'@rushstack/node-core-library': 5.11.0(@types/node@24.10.15)
|
||||
'@rushstack/node-core-library': 5.11.0(@types/node@24.11.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
'@microsoft/api-extractor@7.51.0(@types/node@24.10.15)':
|
||||
'@microsoft/api-extractor@7.51.0(@types/node@24.11.0)':
|
||||
dependencies:
|
||||
'@microsoft/api-extractor-model': 7.30.3(@types/node@24.10.15)
|
||||
'@microsoft/api-extractor-model': 7.30.3(@types/node@24.11.0)
|
||||
'@microsoft/tsdoc': 0.15.1
|
||||
'@microsoft/tsdoc-config': 0.17.1
|
||||
'@rushstack/node-core-library': 5.11.0(@types/node@24.10.15)
|
||||
'@rushstack/node-core-library': 5.11.0(@types/node@24.11.0)
|
||||
'@rushstack/rig-package': 0.5.3
|
||||
'@rushstack/terminal': 0.15.0(@types/node@24.10.15)
|
||||
'@rushstack/ts-command-line': 4.23.5(@types/node@24.10.15)
|
||||
'@rushstack/terminal': 0.15.0(@types/node@24.11.0)
|
||||
'@rushstack/ts-command-line': 4.23.5(@types/node@24.11.0)
|
||||
lodash: 4.17.21
|
||||
minimatch: 3.0.8
|
||||
resolve: 1.22.8
|
||||
@@ -10249,7 +10262,7 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.46.2':
|
||||
optional: true
|
||||
|
||||
'@rushstack/node-core-library@5.11.0(@types/node@24.10.15)':
|
||||
'@rushstack/node-core-library@5.11.0(@types/node@24.11.0)':
|
||||
dependencies:
|
||||
ajv: 8.13.0
|
||||
ajv-draft-04: 1.0.0(ajv@8.13.0)
|
||||
@@ -10260,23 +10273,23 @@ snapshots:
|
||||
resolve: 1.22.8
|
||||
semver: 7.5.4
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
|
||||
'@rushstack/rig-package@0.5.3':
|
||||
dependencies:
|
||||
resolve: 1.22.8
|
||||
strip-json-comments: 3.1.1
|
||||
|
||||
'@rushstack/terminal@0.15.0(@types/node@24.10.15)':
|
||||
'@rushstack/terminal@0.15.0(@types/node@24.11.0)':
|
||||
dependencies:
|
||||
'@rushstack/node-core-library': 5.11.0(@types/node@24.10.15)
|
||||
'@rushstack/node-core-library': 5.11.0(@types/node@24.11.0)
|
||||
supports-color: 8.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
|
||||
'@rushstack/ts-command-line@4.23.5(@types/node@24.10.15)':
|
||||
'@rushstack/ts-command-line@4.23.5(@types/node@24.11.0)':
|
||||
dependencies:
|
||||
'@rushstack/terminal': 0.15.0(@types/node@24.10.15)
|
||||
'@rushstack/terminal': 0.15.0(@types/node@24.11.0)
|
||||
'@types/argparse': 1.0.38
|
||||
argparse: 1.0.10
|
||||
string-argv: 0.3.2
|
||||
@@ -10609,7 +10622,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-plugin@1.161.4(@tanstack/react-router@1.161.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))':
|
||||
'@tanstack/router-plugin@1.161.4(@tanstack/react-router@1.161.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.0)
|
||||
@@ -10626,7 +10639,7 @@ snapshots:
|
||||
zod: 3.25.76
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.161.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -10766,7 +10779,7 @@ snapshots:
|
||||
|
||||
'@types/adm-zip@0.5.7':
|
||||
dependencies:
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
|
||||
'@types/argparse@1.0.38': {}
|
||||
|
||||
@@ -10927,7 +10940,7 @@ snapshots:
|
||||
'@types/fs-extra@11.0.4':
|
||||
dependencies:
|
||||
'@types/jsonfile': 6.1.4
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
|
||||
'@types/geojson@7946.0.14': {}
|
||||
|
||||
@@ -10943,7 +10956,7 @@ snapshots:
|
||||
|
||||
'@types/jsonfile@6.1.4':
|
||||
dependencies:
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
|
||||
'@types/lodash-es@4.17.12':
|
||||
dependencies:
|
||||
@@ -10957,7 +10970,7 @@ snapshots:
|
||||
|
||||
'@types/ms@0.7.34': {}
|
||||
|
||||
'@types/node@24.10.15':
|
||||
'@types/node@24.11.0':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
@@ -11209,7 +11222,7 @@ snapshots:
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))':
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.0
|
||||
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.0)
|
||||
@@ -11224,19 +11237,19 @@ snapshots:
|
||||
regenerator-runtime: 0.14.1
|
||||
systemjs: 6.15.1
|
||||
terser: 5.36.0
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-react-swc@4.2.3(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))':
|
||||
'@vitejs/plugin-react-swc@4.2.3(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-rc.2
|
||||
'@swc/core': 1.15.11
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- '@swc/helpers'
|
||||
|
||||
'@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))':
|
||||
'@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
|
||||
@@ -11244,7 +11257,7 @@ snapshots:
|
||||
'@rolldown/pluginutils': 1.0.0-rc.3
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.18.0
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -11632,6 +11645,8 @@ snapshots:
|
||||
|
||||
commander@14.0.2: {}
|
||||
|
||||
commander@14.0.3: {}
|
||||
|
||||
commander@2.20.3: {}
|
||||
|
||||
commander@7.2.0: {}
|
||||
@@ -11703,9 +11718,9 @@ snapshots:
|
||||
|
||||
core-util-is@1.0.3: {}
|
||||
|
||||
cosmiconfig-typescript-loader@6.1.0(@types/node@24.10.15)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3):
|
||||
cosmiconfig-typescript-loader@6.1.0(@types/node@24.11.0)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
cosmiconfig: 9.0.0(typescript@5.9.3)
|
||||
jiti: 2.6.1
|
||||
typescript: 5.9.3
|
||||
@@ -12658,10 +12673,10 @@ snapshots:
|
||||
|
||||
kind-of@6.0.3: {}
|
||||
|
||||
knip@5.85.0(@types/node@24.10.15)(typescript@5.9.3):
|
||||
knip@5.85.0(@types/node@24.11.0)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
fast-glob: 3.3.3
|
||||
formatly: 0.3.0
|
||||
jiti: 2.6.1
|
||||
@@ -12748,15 +12763,15 @@ snapshots:
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
|
||||
lint-staged@16.2.7:
|
||||
lint-staged@16.3.0:
|
||||
dependencies:
|
||||
commander: 14.0.2
|
||||
commander: 14.0.3
|
||||
listr2: 9.0.5
|
||||
micromatch: 4.0.8
|
||||
nano-spawn: 2.0.0
|
||||
pidtree: 0.6.0
|
||||
string-argv: 0.3.2
|
||||
yaml: 2.8.1
|
||||
tinyexec: 1.0.2
|
||||
yaml: 2.8.2
|
||||
|
||||
listr2@9.0.5:
|
||||
dependencies:
|
||||
@@ -14299,7 +14314,7 @@ snapshots:
|
||||
|
||||
svg-tags@1.0.0: {}
|
||||
|
||||
swr@2.4.0(react@19.2.4):
|
||||
swr@2.4.1(react@19.2.4):
|
||||
dependencies:
|
||||
dequal: 2.0.3
|
||||
react: 19.2.4
|
||||
@@ -14372,6 +14387,8 @@ snapshots:
|
||||
|
||||
tinyexec@1.0.1: {}
|
||||
|
||||
tinyexec@1.0.2: {}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
@@ -14653,9 +14670,9 @@ snapshots:
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
vite-plugin-dts@4.5.4(@types/node@24.10.15)(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)):
|
||||
vite-plugin-dts@4.5.4(@types/node@24.11.0)(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@microsoft/api-extractor': 7.51.0(@types/node@24.10.15)
|
||||
'@microsoft/api-extractor': 7.51.0(@types/node@24.11.0)
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.46.2)
|
||||
'@volar/typescript': 2.4.11
|
||||
'@vue/language-core': 2.2.0(typescript@5.9.3)
|
||||
@@ -14666,13 +14683,13 @@ snapshots:
|
||||
magic-string: 0.30.17
|
||||
typescript: 5.9.3
|
||||
optionalDependencies:
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
vite-plugin-html@3.2.2(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)):
|
||||
vite-plugin-html@3.2.2(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
colorette: 2.0.20
|
||||
@@ -14686,38 +14703,38 @@ snapshots:
|
||||
html-minifier-terser: 6.1.0
|
||||
node-html-parser: 5.4.2
|
||||
pathe: 0.2.0
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
vite-plugin-sass-dts@1.3.35(postcss@8.5.6)(prettier@3.8.1)(sass-embedded@1.97.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)):
|
||||
vite-plugin-sass-dts@1.3.35(postcss@8.5.6)(prettier@3.8.1)(sass-embedded@1.97.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-js: 4.0.1(postcss@8.5.6)
|
||||
prettier: 3.8.1
|
||||
sass-embedded: 1.97.3
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)):
|
||||
vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
|
||||
'@svgr/core': 8.1.0(typescript@5.9.3)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)):
|
||||
vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
globrex: 0.1.2
|
||||
tsconfck: 3.0.3(typescript@5.9.3)
|
||||
vite: 7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite: 7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite@7.3.1(@types/node@24.10.15)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1):
|
||||
vite@7.3.1(@types/node@24.11.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
esbuild: 0.27.2
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
@@ -14726,7 +14743,7 @@ snapshots:
|
||||
rollup: 4.46.2
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.15
|
||||
'@types/node': 24.11.0
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.6.1
|
||||
less: 4.2.0
|
||||
@@ -14736,7 +14753,7 @@ snapshots:
|
||||
stylus: 0.62.0
|
||||
terser: 5.36.0
|
||||
tsx: 4.21.0
|
||||
yaml: 2.8.1
|
||||
yaml: 2.8.2
|
||||
|
||||
void-elements@3.1.0: {}
|
||||
|
||||
@@ -14819,6 +14836,8 @@ snapshots:
|
||||
|
||||
yaml@2.8.1: {}
|
||||
|
||||
yaml@2.8.2: {}
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs-parser@22.0.0: {}
|
||||
|
||||
@@ -2,6 +2,18 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||
|
||||
## [2.61.0](https://github.com/filebrowser/filebrowser/compare/v2.60.0...v2.61.0) (2026-02-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improved conflict resolution when uploading/copying/moving files ([#5765](https://github.com/filebrowser/filebrowser/issues/5765)) ([aa80909](https://github.com/filebrowser/filebrowser/commit/aa809096eb35fdfbdeb6784b1ebfe2ca1e42f52b))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* correctly clean path ([31194fb](https://github.com/filebrowser/filebrowser/commit/31194fb57a5b92e7155219d7ec7273028fcb2e83))
|
||||
|
||||
## [2.60.0](https://github.com/filebrowser/filebrowser/compare/v2.59.0...v2.60.0) (2026-02-21)
|
||||
|
||||
|
||||
|
||||
@@ -72,5 +72,5 @@
|
||||
"vite-plugin-compression2": "^2.3.1",
|
||||
"vue-tsc": "^3.1.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.30.1+sha512.3590e550d5384caa39bd5c7c739f72270234b2f6059e13018f975c313b1eb9fefcc09714048765d4d9efe961382c312e624572c0420762bdc5d5940cdf9be73a"
|
||||
"packageManager": "pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017"
|
||||
}
|
||||
|
||||
Generated
+355
-172
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "حفظ التغييرات",
|
||||
"editAsText": "تعديل على شكل نص",
|
||||
"increaseFontSize": "زيادة حجم الخط",
|
||||
"decreaseFontSize": "تصغير حجم الخط"
|
||||
"decreaseFontSize": "تصغير حجم الخط",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "تحميل الملف",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "إختر الملفات التي تريد رفعها.",
|
||||
"optionalPassword": "كلمة مرور إختيارية",
|
||||
"resolution": "الدقة",
|
||||
"discardEditorChanges": "هل تريد بالتأكيد إلغاء التغييرات؟"
|
||||
"discardEditorChanges": "هل تريد بالتأكيد إلغاء التغييرات؟",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "الصور",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Запиши промените",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Свали файл",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Изберете опция за качване.",
|
||||
"optionalPassword": "Опционална парола",
|
||||
"resolution": "Резолюция",
|
||||
"discardEditorChanges": "Сигурни ли сте, че искате да откажете направените промени?"
|
||||
"discardEditorChanges": "Сигурни ли сте, че искате да откажете направените промени?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Изображения",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarregar fitxer",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Seleccioneu una opció per pujar.",
|
||||
"optionalPassword": "Contrasenya opcional",
|
||||
"resolution": "Resolució",
|
||||
"discardEditorChanges": "Esteu segur que voleu descartar els canvis que heu fet?"
|
||||
"discardEditorChanges": "Esteu segur que voleu descartar els canvis que heu fet?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Imatges",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Stáhnout soubor",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Vyberte možnost pro nahrání.",
|
||||
"optionalPassword": "Volitelné heslo",
|
||||
"resolution": "Rozlišení",
|
||||
"discardEditorChanges": "Opravdu chcete zrušit provedené změny?"
|
||||
"discardEditorChanges": "Opravdu chcete zrušit provedené změny?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Obrázky",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Änderungen speichern",
|
||||
"editAsText": "Als Text bearbeiten",
|
||||
"increaseFontSize": "Schrift vergrößern",
|
||||
"decreaseFontSize": "Schrift verkleinern"
|
||||
"decreaseFontSize": "Schrift verkleinern",
|
||||
"overrideAll": "Alle Dateien im Zielordner ersetzen",
|
||||
"skipAll": "Alle in Konflikt stehenden Dateien überspringen",
|
||||
"renameAll": "Alle Dateien umbenennen (Kopie erstellen)",
|
||||
"singleDecision": "Bei jeder Datei mit Konflikt entscheiden"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Datei herunterladen",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Wähle eine Upload-Option.",
|
||||
"optionalPassword": "Optionales Passwort",
|
||||
"resolution": "Auflösung",
|
||||
"discardEditorChanges": "Möchtest du deine Änderungen wirklich verwerfen?"
|
||||
"discardEditorChanges": "Möchtest du deine Änderungen wirklich verwerfen?",
|
||||
"replaceOrSkip": "Dateien ersetzen oder überspringen",
|
||||
"resolveConflict": "Welche Dateien möchtest du behalten?",
|
||||
"singleConflictResolve": "Wenn du beide Versionen auswählst, wird dem Namen der kopierten Datei eine Nummer hinzugefügt.",
|
||||
"fastConflictResolve": "Der Zielordner enthält {count} Dateien mit demselben Namen.",
|
||||
"uploadingFiles": "Dateien werden hochgeladen",
|
||||
"filesInOrigin": "Dateien im Ursprungsordner",
|
||||
"filesInDest": "Dateien im Zielordner",
|
||||
"override": "Überschreiben",
|
||||
"skip": "Überspringen",
|
||||
"forbiddenError": "Zugriff verweigert"
|
||||
},
|
||||
"search": {
|
||||
"images": "Bilder",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Λήψη αρχείου",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Επιλέξτε μια επιλογή για τη μεταφόρτωση.",
|
||||
"optionalPassword": "Προαιρετικός κωδικός πρόσβασης",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Εικόνες",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Guardar cambios",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descargar fichero",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Seleccione una opción para subir.",
|
||||
"optionalPassword": "Contraseña opcional",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Imágenes",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "دانلود فایل",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "یک گزینه برای آپلود انتخاب کنید.",
|
||||
"optionalPassword": "رمز عبور اختیاری",
|
||||
"resolution": "وضوح تصویر",
|
||||
"discardEditorChanges": "آیا مطمئن هستید که میخواهید تغییراتی را که ایجاد کردهاید، لغو کنید؟"
|
||||
"discardEditorChanges": "آیا مطمئن هستید که میخواهید تغییراتی را که ایجاد کردهاید، لغو کنید؟",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "تصاویر",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Enregistrer changements",
|
||||
"editAsText": "Editer comme Texte",
|
||||
"increaseFontSize": "Augmenter taille police",
|
||||
"decreaseFontSize": "Réduire taille police"
|
||||
"decreaseFontSize": "Réduire taille police",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Télécharger le fichier",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Sélectionnez une option d'import.",
|
||||
"optionalPassword": "Mot de passe optionnel",
|
||||
"resolution": "Résolution",
|
||||
"discardEditorChanges": "Êtes-vous sûr de vouloir annuler les modifications apportées ?"
|
||||
"discardEditorChanges": "Êtes-vous sûr de vouloir annuler les modifications apportées ?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "הורד קובץ",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "בחר אפשרות העלאה.",
|
||||
"optionalPassword": "סיסמא אופציונלית",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "האם אתה בטוח שברצונך לבטל את השינויים שביצעת?"
|
||||
"discardEditorChanges": "האם אתה בטוח שברצונך לבטל את השינויים שביצעת?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "תמונות",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Spremi promjene",
|
||||
"editAsText": "Uredi kao tekst",
|
||||
"increaseFontSize": "Povećaj veličinu fonta",
|
||||
"decreaseFontSize": "Smanji veličinu fonta"
|
||||
"decreaseFontSize": "Smanji veličinu fonta",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Preuzmi Datoteku",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Odaberite opciju za prijenos.",
|
||||
"optionalPassword": "Opcionalna lozinka",
|
||||
"resolution": "Rezolucija",
|
||||
"discardEditorChanges": "Jeste li sigurni da želite odbaciti promjene koje ste napravili?"
|
||||
"discardEditorChanges": "Jeste li sigurni da želite odbaciti promjene koje ste napravili?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Slike",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Fájl letöltése",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Válasszon egy feltöltési módot.",
|
||||
"optionalPassword": "Választható jelszó",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Képek",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Sækja skjal",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Select an option to upload.",
|
||||
"optionalPassword": "Optional password",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Myndir",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Scarica file",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Seleziona un'opzione per il caricamento.",
|
||||
"optionalPassword": "Password opzionale",
|
||||
"resolution": "Risoluzione",
|
||||
"discardEditorChanges": "Sei sicuro di voler scartare le modifiche apportate?"
|
||||
"discardEditorChanges": "Sei sicuro di voler scartare le modifiche apportate?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Immagini",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "ファイルのダウンロード",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "アップロードするオプションを選択してください。",
|
||||
"optionalPassword": "パスワード(オプション)",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "画像",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "변경사항 저장",
|
||||
"editAsText": "텍스트로 편집",
|
||||
"increaseFontSize": "글꼴 크기 증가",
|
||||
"decreaseFontSize": "글꼴 크기 감소"
|
||||
"decreaseFontSize": "글꼴 크기 감소",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "파일 다운로드",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "업로드 옵션을 선택하세요.",
|
||||
"optionalPassword": "비밀번호 (선택)",
|
||||
"resolution": "해상도",
|
||||
"discardEditorChanges": "변경 사항을 취소하시겠습니까?"
|
||||
"discardEditorChanges": "변경 사항을 취소하시겠습니까?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "이미지",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Saglabāt izmaiņas",
|
||||
"editAsText": "Rediģēt kā tekstu",
|
||||
"increaseFontSize": "Palieliniet fonta lielumu",
|
||||
"decreaseFontSize": "Samaziniet fonta lielumu"
|
||||
"decreaseFontSize": "Samaziniet fonta lielumu",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Lejupielādēt failu",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Atlasiet augšupielādes opciju.",
|
||||
"optionalPassword": "Izvēles parole",
|
||||
"resolution": "Izšķirtspēja",
|
||||
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?"
|
||||
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Attēli",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Saglabāt izmaiņas",
|
||||
"editAsText": "Rediģēt kā tekstu",
|
||||
"increaseFontSize": "Palieliniet fonta lielumu",
|
||||
"decreaseFontSize": "Samaziniet fonta lielumu"
|
||||
"decreaseFontSize": "Samaziniet fonta lielumu",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Lejupielādēt failu",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Atlasiet augšupielādes opciju.",
|
||||
"optionalPassword": "Izvēles parole",
|
||||
"resolution": "Izšķirtspēja",
|
||||
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?"
|
||||
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Attēli",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Bestand downloaden",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Select an option to upload.",
|
||||
"optionalPassword": "Optional password",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Afbeeldingen",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Wijzigingen opslaan",
|
||||
"editAsText": "Als tekst bewerken",
|
||||
"increaseFontSize": "Lettertype vergroten",
|
||||
"decreaseFontSize": "Lettertype verkleinen"
|
||||
"decreaseFontSize": "Lettertype verkleinen",
|
||||
"overrideAll": "Alle bestanden in doelmap vervangen",
|
||||
"skipAll": "Alle conflicterende bestanden overslaan",
|
||||
"renameAll": "Alle bestanden hernoemen (een kopie maken)",
|
||||
"singleDecision": "Voor elk conflicterend bestand besluiten"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Bestand downloaden",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Kies een optie bij de upload.",
|
||||
"optionalPassword": "Optioneel wachtwoord",
|
||||
"resolution": "Resolutie",
|
||||
"discardEditorChanges": "Weet u zeker dat u de door u aangebrachte wijzigingen wilt weggooien?"
|
||||
"discardEditorChanges": "Weet u zeker dat u de door u aangebrachte wijzigingen wilt weggooien?",
|
||||
"replaceOrSkip": "Bestanden vervangen of overslaan",
|
||||
"resolveConflict": "Welke bestanden wilt u behouden?",
|
||||
"singleConflictResolve": "Als u beide versies selecteert, wordt er een nummer toegevoegd aan de naam van het gekopieerde bestand.",
|
||||
"fastConflictResolve": "De doelmap daar bevat {count} bestanden met dezelfde naam.",
|
||||
"uploadingFiles": "Bestanden uploaden",
|
||||
"filesInOrigin": "Bestanden in origineel",
|
||||
"filesInDest": "Bestanden in bestemming",
|
||||
"override": "Overschrijven",
|
||||
"skip": "Overslaan",
|
||||
"forbiddenError": "Verboden Fout"
|
||||
},
|
||||
"search": {
|
||||
"images": "Afbeeldingen",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Lagre Endringane ",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Nedlast filen",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Velg et alternativ for opplasting.",
|
||||
"optionalPassword": "Valgfritt passord",
|
||||
"resolution": "Oppløysning",
|
||||
"discardEditorChanges": "Er du sikker på at du vil forkaste endringene du har gjort?"
|
||||
"discardEditorChanges": "Er du sikker på at du vil forkaste endringene du har gjort?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Bilde",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Zapisz zmiany",
|
||||
"editAsText": "Edytuj jako tekst",
|
||||
"increaseFontSize": "Zwiększ rozmiar czcionki",
|
||||
"decreaseFontSize": "Zmniejsz rozmiar czcionki"
|
||||
"decreaseFontSize": "Zmniejsz rozmiar czcionki",
|
||||
"overrideAll": "Zastąp wszystkie pliki w folderze docelowym",
|
||||
"skipAll": "Pomiń wszystkie pliki powodujące konflikty",
|
||||
"renameAll": "Zmień nazwy wszystkich plików (utwórz kopię)",
|
||||
"singleDecision": "Podejmij decyzję dla każdego pliku powodującego konflikt"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Pobierz plik",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Wybierz opcję przesyłania.",
|
||||
"optionalPassword": "Opcjonalne hasło",
|
||||
"resolution": "Rozdzielczość",
|
||||
"discardEditorChanges": "Czy na pewno chcesz odrzucić wprowadzone zmiany?"
|
||||
"discardEditorChanges": "Czy na pewno chcesz odrzucić wprowadzone zmiany?",
|
||||
"replaceOrSkip": "Zastąp lub pomiń pliki",
|
||||
"resolveConflict": "Które pliki chcesz zachować?",
|
||||
"singleConflictResolve": "Jeśli wybierzesz obie wersje, do nazwy kopiowanego pliku zostanie dodany numer.",
|
||||
"fastConflictResolve": "W folderze docelowym liczba plików o tej samej nazwie to {count}.",
|
||||
"uploadingFiles": "Wysyłanie plików",
|
||||
"filesInOrigin": "Pliki w miejscu pochodzenia",
|
||||
"filesInDest": "Pliki w miejscu docelowym",
|
||||
"override": "Zastąp",
|
||||
"skip": "Pomiń",
|
||||
"forbiddenError": "Błąd zabronionego dostępu"
|
||||
},
|
||||
"search": {
|
||||
"images": "Obrazy",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Baixar arquivo",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Selecione uma opção para enviar.",
|
||||
"optionalPassword": "Senha opcional",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Imagens",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarregar ficheiro",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Select an option to upload.",
|
||||
"optionalPassword": "Optional password",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Imagens",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarcă fișier",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Select an option to upload.",
|
||||
"optionalPassword": "Optional password",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Imagini",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Сохранить",
|
||||
"editAsText": "Редактировать как текст",
|
||||
"increaseFontSize": "Увеличить размер шрифта",
|
||||
"decreaseFontSize": "Уменьшить размер шрифта"
|
||||
"decreaseFontSize": "Уменьшить размер шрифта",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Скачать файл",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Выберите вариант для загрузки.",
|
||||
"optionalPassword": "Необязательный пароль",
|
||||
"resolution": "Разрешение",
|
||||
"discardEditorChanges": "Вы действительно желаете отменить ваши правки?"
|
||||
"discardEditorChanges": "Вы действительно желаете отменить ваши правки?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Изображения",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Uložiť zmeny",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Stiahnuť súbor",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Zvoľte možnosť nahrávania.",
|
||||
"optionalPassword": "Voliteľné heslo",
|
||||
"resolution": "Rozlíšenie",
|
||||
"discardEditorChanges": "Naozaj chcete zahodiť vykonané zmeny?"
|
||||
"discardEditorChanges": "Naozaj chcete zahodiť vykonané zmeny?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Obrázky",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Spara ändringar",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Ladda ner fil",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Välj ett alternativ att ladda upp.",
|
||||
"optionalPassword": "Valfritt lösenord",
|
||||
"resolution": "Upplösning",
|
||||
"discardEditorChanges": "Är du säker på att du vill förkasta ändringarna du gjort?"
|
||||
"discardEditorChanges": "Är du säker på att du vill förkasta ändringarna du gjort?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Bilder",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Dosyayı indir",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Yüklemek için bir seçenek belirleyin.",
|
||||
"optionalPassword": "İsteğe bağlı şifre",
|
||||
"resolution": "Resolution",
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?"
|
||||
"discardEditorChanges": "Are you sure you wish to discard the changes you've made?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Görseller",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Завантажити файл",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Виберіть варіант для вивантаження.",
|
||||
"optionalPassword": "Необов'язковий пароль",
|
||||
"resolution": "Розширення",
|
||||
"discardEditorChanges": "Чи дійсно ви хочете скасувати поточні зміни?"
|
||||
"discardEditorChanges": "Чи дійсно ви хочете скасувати поточні зміни?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Зображення",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Tải xuống tệp tin",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "Chọn một tùy chọn để tải lên.",
|
||||
"optionalPassword": "Mật khẩu tùy chọn",
|
||||
"resolution": "Độ phân giải",
|
||||
"discardEditorChanges": "Bạn có chắc chắn muốn hủy bỏ các thay đổi đã thực hiện không?"
|
||||
"discardEditorChanges": "Bạn có chắc chắn muốn hủy bỏ các thay đổi đã thực hiện không?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "Hình ảnh",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "保存更改",
|
||||
"editAsText": "以文本形式编辑",
|
||||
"increaseFontSize": "增大字体大小",
|
||||
"decreaseFontSize": "减小字体大小"
|
||||
"decreaseFontSize": "减小字体大小",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下载文件",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "选择上传选项。",
|
||||
"optionalPassword": "密码(选填,不填即无密码)",
|
||||
"resolution": "分辨率",
|
||||
"discardEditorChanges": "你确定要放弃所做的更改吗?"
|
||||
"discardEditorChanges": "你确定要放弃所做的更改吗?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "图像",
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"decreaseFontSize": "Decrease font size",
|
||||
"overrideAll": "Replace all files in destination folder",
|
||||
"skipAll": "Skip all conflicting files",
|
||||
"renameAll": "Rename all files (create a copy)",
|
||||
"singleDecision": "Decide for each conflicting file"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下載檔案",
|
||||
@@ -161,7 +165,17 @@
|
||||
"uploadMessage": "選擇上傳項。",
|
||||
"optionalPassword": "密碼(選填,不填即無密碼)",
|
||||
"resolution": "解析度",
|
||||
"discardEditorChanges": "你確定要放棄所做的變更嗎?"
|
||||
"discardEditorChanges": "你確定要放棄所做的變更嗎?",
|
||||
"replaceOrSkip": "Replace or skip files",
|
||||
"resolveConflict": "Which files do you want to keep?",
|
||||
"singleConflictResolve": "If you select both versions, a number will be added to the name of the copied file.",
|
||||
"fastConflictResolve": "The destination folder there are {count} files with same name.",
|
||||
"uploadingFiles": "Uploading files",
|
||||
"filesInOrigin": "Files in origin",
|
||||
"filesInDest": "Files in destination",
|
||||
"override": "Overwrite",
|
||||
"skip": "Skip",
|
||||
"forbiddenError": "Forbidden Error"
|
||||
},
|
||||
"search": {
|
||||
"images": "影像",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ go 1.25
|
||||
|
||||
require (
|
||||
github.com/asdine/storm/v3 v3.2.1
|
||||
github.com/asticode/go-astisub v0.38.0
|
||||
github.com/asticode/go-astisub v0.39.0
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dsoprea/go-exif/v3 v3.0.1
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
||||
|
||||
+2
-2
@@ -31,8 +31,8 @@ github.com/asticode/go-astikit v0.20.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xbl
|
||||
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
|
||||
github.com/asticode/go-astikit v0.56.0 h1:DmD2p7YnvxiPdF0h+dRmos3bsejNEXbycENsY5JfBqw=
|
||||
github.com/asticode/go-astikit v0.56.0/go.mod h1:fV43j20UZYfXzP9oBn33udkvCvDvCDhzjVqoLFuuYZE=
|
||||
github.com/asticode/go-astisub v0.38.0 h1:Qh3IO8Cotn0wwok5maid7xqsIJTwn2DtABT1UajKJaI=
|
||||
github.com/asticode/go-astisub v0.38.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
|
||||
github.com/asticode/go-astisub v0.39.0 h1:j1/rFLRUH0TT2CW9YCtBek9lRdMp96oxaZm6vbgE96M=
|
||||
github.com/asticode/go-astisub v0.39.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
|
||||
github.com/asticode/go-astits v1.8.0/go.mod h1:DkOWmBNQpnr9mv24KfZjq4JawCFX1FCqjLVGvO0DygQ=
|
||||
github.com/asticode/go-astits v1.13.0 h1:XOgkaadfZODnyZRR5Y0/DWkA9vrkLLPLeeOvDwfKZ1c=
|
||||
github.com/asticode/go-astits v1.13.0/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
|
||||
|
||||
@@ -56,7 +56,7 @@ var withHashFile = func(fn handleFunc) handleFunc {
|
||||
filePath := ""
|
||||
|
||||
if file.IsDir {
|
||||
basePath = filepath.Dir(basePath)
|
||||
basePath = filepath.Clean(link.Path)
|
||||
filePath = ifPath
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ openmesh,a42|\
|
||||
openmesh,a62|\
|
||||
pakedge,wr-1|\
|
||||
plasmacloud,pa1200|\
|
||||
plasmacloud,pa2200)
|
||||
plasmacloud,pa2200|\
|
||||
thinkplus,fogpod800)
|
||||
ubootenv_add_uci_config "/dev/mtd5" "0x0" "0x10000" "0x10000"
|
||||
;;
|
||||
aruba,ap-303)
|
||||
|
||||
@@ -64,6 +64,7 @@ ALLWIFIBOARDS:= \
|
||||
qnap_301w \
|
||||
redmi_ax5-jdcloud \
|
||||
redmi_ax6 \
|
||||
thinkplus_fogpod800 \
|
||||
wallys_dr40x9 \
|
||||
xiaomi_ax3600 \
|
||||
xiaomi_ax6000 \
|
||||
@@ -199,6 +200,7 @@ $(eval $(call generate-ipq-wifi-package,qnap_301w,QNAP 301w))
|
||||
$(eval $(call generate-ipq-wifi-package,prpl_haze,prpl Haze))
|
||||
$(eval $(call generate-ipq-wifi-package,redmi_ax5-jdcloud,Redmi AX5 JDCloud))
|
||||
$(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6))
|
||||
$(eval $(call generate-ipq-wifi-package,thinkplus_fogpod800,ThinkPlus FogPOD800))
|
||||
$(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9))
|
||||
$(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600))
|
||||
$(eval $(call generate-ipq-wifi-package,xiaomi_ax6000,Xiaomi AX6000))
|
||||
|
||||
Binary file not shown.
@@ -22,6 +22,16 @@ ipq40xx_setup_interfaces()
|
||||
plasmacloud,pa2200)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
;;
|
||||
alibaba,ap4220-48m|\
|
||||
alibaba,ap4220-128m|\
|
||||
asus,map-ac2200|\
|
||||
cilab,meshpoint-one|\
|
||||
edgecore,ecw5211|\
|
||||
edgecore,oap100|\
|
||||
openmesh,a42|\
|
||||
openmesh,a62)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
;;
|
||||
aruba,ap-303|\
|
||||
aruba,ap-365|\
|
||||
avm,fritzrepeater-1200|\
|
||||
@@ -42,20 +52,6 @@ ipq40xx_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "0u@eth1" "5:wan"
|
||||
;;
|
||||
alibaba,ap4220-48m|\
|
||||
alibaba,ap4220-128m|\
|
||||
asus,map-ac2200|\
|
||||
cilab,meshpoint-one|\
|
||||
edgecore,ecw5211|\
|
||||
edgecore,oap100|\
|
||||
openmesh,a42|\
|
||||
openmesh,a62)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
;;
|
||||
mikrotik,cap-ac)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0t@eth0" "4:lan" "5:wan"
|
||||
;;
|
||||
asus,rt-ac42u|\
|
||||
asus,rt-ac58u|\
|
||||
mikrotik,hap-ac2|\
|
||||
@@ -70,16 +66,12 @@ ipq40xx_setup_interfaces()
|
||||
avm,fritzbox-4040|\
|
||||
linksys,ea6350v3|\
|
||||
linksys,ea8300|\
|
||||
thinkplus,fogpod800|\
|
||||
yyets,le1)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan"
|
||||
;;
|
||||
linksys,mr8300)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan"
|
||||
;;
|
||||
avm,fritzbox-7530)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1"
|
||||
@@ -88,11 +80,6 @@ ipq40xx_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "4:lan:1" "5:lan:2"
|
||||
;;
|
||||
compex,wpj419|\
|
||||
compex,wpj428|\
|
||||
engenius,eap2200)
|
||||
ucidef_set_interface_lan "eth0 eth1"
|
||||
;;
|
||||
buffalo,wtr-m2133hp)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
@@ -103,6 +90,11 @@ ipq40xx_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "3:lan" "4:lan"
|
||||
;;
|
||||
compex,wpj419|\
|
||||
compex,wpj428|\
|
||||
engenius,eap2200)
|
||||
ucidef_set_interface_lan "eth0 eth1"
|
||||
;;
|
||||
devolo,magic-2-wifi-next)
|
||||
ucidef_set_interface_lan "eth0 eth1 eth2"
|
||||
;;
|
||||
@@ -123,6 +115,15 @@ ipq40xx_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "5:lan" "0u@eth1" "4:wan"
|
||||
;;
|
||||
linksys,mr8300)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan"
|
||||
;;
|
||||
mikrotik,cap-ac)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0t@eth0" "4:lan" "5:wan"
|
||||
;;
|
||||
mobipromo,cm520-79f)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "3:lan:2" "4:lan:1"
|
||||
@@ -136,14 +137,14 @@ ipq40xx_setup_interfaces()
|
||||
"0u@eth0" "2:lan" "3:lan" "4:lan"
|
||||
ucidef_set_interface_wan "eth1"
|
||||
;;
|
||||
qxwlan,e2600ac-c1 |\
|
||||
qxwlan,e2600ac-c1|\
|
||||
qxwlan,e2600ac-c2)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "3:lan" "4:lan" "0u@eth1" "5:wan"
|
||||
;;
|
||||
unielec,u4019-32m |\
|
||||
tel,x1pro)
|
||||
tel,x1pro|\
|
||||
unielec,u4019-32m)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan"
|
||||
@@ -172,15 +173,15 @@ ipq40xx_setup_macs()
|
||||
local label_mac=""
|
||||
|
||||
case "$board" in
|
||||
8dev,habanero-dvk)
|
||||
label_mac=$(mtd_get_mac_binary "ART" 0x1006)
|
||||
;;
|
||||
alibaba,ap4220-48m|\
|
||||
alibaba,ap4220-128m)
|
||||
wan_mac=$(mtd_get_mac_text product_info 0x40)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
label_mac="$wan_mac"
|
||||
;;
|
||||
8dev,habanero-dvk)
|
||||
label_mac=$(mtd_get_mac_binary "ART" 0x1006)
|
||||
;;
|
||||
asus,rt-ac58u)
|
||||
wan_mac=$(mtd_get_mac_binary_ubi Factory 0x1006)
|
||||
lan_mac=$(mtd_get_mac_binary_ubi Factory 0x5006)
|
||||
@@ -230,6 +231,11 @@ ipq40xx_setup_macs()
|
||||
lan_mac=$(cat /sys/firmware/mikrotik/hard_config/mac_base)
|
||||
label_mac="$lan_mac"
|
||||
;;
|
||||
thinkplus,fogpod800)
|
||||
wan_mac=$(mtd_get_mac_binary "0:ART" 0x0)
|
||||
lan_mac=$(mtd_get_mac_binary "0:ART" 0x6)
|
||||
label_mac=$wan_mac
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
|
||||
|
||||
@@ -234,7 +234,8 @@ platform_do_upgrade() {
|
||||
netgear,wac510 |\
|
||||
p2w,r619ac-64m |\
|
||||
p2w,r619ac-128m |\
|
||||
qxwlan,e2600ac-c2)
|
||||
qxwlan,e2600ac-c2 |\
|
||||
thinkplus,fogpod800)
|
||||
nand_do_upgrade "$1"
|
||||
;;
|
||||
glinet,gl-b2200)
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
|
||||
#include "qcom-ipq4019.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/soc/qcom,tcsr.h>
|
||||
|
||||
/ {
|
||||
model = "ThinkPlus FogPOD800";
|
||||
compatible = "thinkplus,fogpod800";
|
||||
|
||||
aliases {
|
||||
led-boot = &led_power;
|
||||
led-failsafe = &led_power;
|
||||
led-running = &led_power;
|
||||
led-upgrade = &led_power;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs-append = " ubi.mtd=rootfs root=/dev/ubiblock0_1";
|
||||
};
|
||||
|
||||
soc {
|
||||
rng@22000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
mdio@90000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ess-psgmii@98000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tcsr@1949000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x1949000 0x100>;
|
||||
qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
|
||||
};
|
||||
|
||||
tcsr@194b000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x194b000 0x100>;
|
||||
qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
|
||||
};
|
||||
|
||||
ess_tcsr@1953000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x1953000 0x1000>;
|
||||
qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
|
||||
};
|
||||
|
||||
tcsr@1957000 {
|
||||
compatible = "qcom,tcsr";
|
||||
reg = <0x1957000 0x100>;
|
||||
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
|
||||
};
|
||||
|
||||
usb2@60f8800 {
|
||||
status = "okay";
|
||||
|
||||
dwc3@6000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usb2_port1: port@1 {
|
||||
reg = <1>;
|
||||
#trigger-source-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
usb3@8af8800 {
|
||||
status = "okay";
|
||||
|
||||
dwc3@8a00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usb3_port1: port@1 {
|
||||
reg = <1>;
|
||||
#trigger-source-cells = <0>;
|
||||
};
|
||||
|
||||
usb3_port2: port@2 {
|
||||
reg = <2>;
|
||||
#trigger-source-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
crypto@8e3a000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
watchdog@b017000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ess-switch@c000000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
edma@c080000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_power: status {
|
||||
label = "red:status";
|
||||
gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "green:wan";
|
||||
gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "90000.mdio-1:04:link";
|
||||
};
|
||||
|
||||
wlan5g {
|
||||
label = "blue:wlan5g";
|
||||
gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy1tpt";
|
||||
};
|
||||
|
||||
usb {
|
||||
label = "blue:usb";
|
||||
gpios = <&tlmm 5 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "usbport";
|
||||
trigger-sources = <&usb2_port1>, <&usb3_port1>, <&usb3_port2>;
|
||||
};
|
||||
|
||||
wlan2g {
|
||||
label = "blue:wlan2g";
|
||||
gpios = <&tlmm 58 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy0tpt";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&cryptobam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp_dma {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
serial0_pins: serial0_pinmux {
|
||||
mux {
|
||||
pins = "gpio60", "gpio61";
|
||||
function = "blsp_uart0";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_pins: spi0_pinmux {
|
||||
mux {
|
||||
function = "blsp_spi0";
|
||||
pins = "gpio55", "gpio56", "gpio57";
|
||||
drive-strength = <12>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mux_cs {
|
||||
function = "gpio";
|
||||
pins = "gpio54", "gpio59";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_spi1 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&spi0_pins>;
|
||||
pinctrl-names = "default";
|
||||
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 59 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <24000000>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "0:SBL1";
|
||||
reg = <0x0 0x40000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@40000 {
|
||||
label = "0:MIBIB";
|
||||
reg = <0x40000 0x20000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@60000 {
|
||||
label = "0:QSEE";
|
||||
reg = <0x60000 0x60000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@c0000 {
|
||||
label = "0:CDT";
|
||||
reg = <0xc0000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@d0000 {
|
||||
label = "0:DDRPARAMS";
|
||||
reg = <0xd0000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@e0000 {
|
||||
label = "0:APPSBLENV";
|
||||
reg = <0xe0000 0x10000>;
|
||||
};
|
||||
|
||||
partition@f0000 {
|
||||
label = "0:APPSBL";
|
||||
reg = <0xf0000 0x80000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@170000 {
|
||||
label = "0:ART";
|
||||
reg = <0x170000 0x10000>;
|
||||
read-only;
|
||||
compatible = "nvmem-cells";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
precal_art_1000: precal@1000 {
|
||||
reg = <0x1000 0x2f20>;
|
||||
};
|
||||
|
||||
precal_art_5000: precal@5000 {
|
||||
reg = <0x5000 0x2f20>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nand@1 {
|
||||
compatible = "spi-nand";
|
||||
reg = <1>;
|
||||
spi-max-frequency = <24000000>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "rootfs";
|
||||
reg = <0x0 0x8000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart1 {
|
||||
pinctrl-0 = <&serial0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2_hs_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3_ss_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3_hs_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
status = "okay";
|
||||
nvmem-cell-names = "pre-calibration";
|
||||
nvmem-cells = <&precal_art_1000>;
|
||||
qcom,ath10k-calibration-variant = "ThinkPlus FogPOD800";
|
||||
};
|
||||
|
||||
&wifi1 {
|
||||
status = "okay";
|
||||
nvmem-cell-names = "pre-calibration";
|
||||
nvmem-cells = <&precal_art_5000>;
|
||||
qcom,ath10k-calibration-variant = "ThinkPlus FogPOD800";
|
||||
};
|
||||
@@ -997,6 +997,20 @@ define Device/tel_x1pro
|
||||
endef
|
||||
TARGET_DEVICES += tel_x1pro
|
||||
|
||||
define Device/thinkplus_fogpod800
|
||||
$(call Device/FitImage)
|
||||
$(call Device/UbiFit)
|
||||
DEVICE_VENDOR := ThinkPlus
|
||||
DEVICE_MODEL := FogPOD800
|
||||
SOC := qcom-ipq4028
|
||||
KERNEL_SIZE := 4096k
|
||||
DEVICE_DTS_CONFIG := config@ap.dk01.1-c2
|
||||
BLOCKSIZE := 128k
|
||||
PAGESIZE := 2048
|
||||
DEVICE_PACKAGES := kmod-usb-ledtrig-usbport ipq-wifi-thinkplus_fogpod800
|
||||
endef
|
||||
TARGET_DEVICES += thinkplus_fogpod800
|
||||
|
||||
define Device/unielec_u4019-32m
|
||||
$(call Device/FitImage)
|
||||
DEVICE_VENDOR := Unielec
|
||||
|
||||
@@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -904,11 +904,79 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||
@@ -904,11 +904,80 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||
qcom-apq8074-dragonboard.dtb \
|
||||
qcom-apq8084-ifc6540.dtb \
|
||||
qcom-apq8084-mtp.dtb \
|
||||
@@ -79,6 +79,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||
+ qcom-ipq4019-u4019-32m.dtb \
|
||||
+ qcom-ipq4019-wpj419.dtb \
|
||||
+ qcom-ipq4019-wtr-m2133hp.dtb \
|
||||
+ qcom-ipq4028-fogpod800.dtb \
|
||||
+ qcom-ipq4028-wpj428.dtb \
|
||||
+ qcom-ipq4029-ap-303.dtb \
|
||||
+ qcom-ipq4029-ap-303h.dtb \
|
||||
|
||||
@@ -265,6 +265,16 @@ func TestEncodeDecode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeEmptyString(t *testing.T) {
|
||||
trafficPattern, err := Decode("")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decode empty string: %v", err)
|
||||
}
|
||||
if trafficPattern == nil {
|
||||
t.Errorf("Returned nil traffic pattern")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidate(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
|
||||
@@ -136,6 +136,18 @@ func RegisterClientCommands() {
|
||||
},
|
||||
clientExportTrafficPatternFunc,
|
||||
)
|
||||
RegisterCallback(
|
||||
[]string{"", "explain", "traffic-pattern"},
|
||||
func(s []string) error {
|
||||
if len(s) < 4 {
|
||||
return fmt.Errorf("usage: mieru explain traffic-pattern <STRING>. No string is provided")
|
||||
} else if len(s) > 4 {
|
||||
return fmt.Errorf("usage: mieru explain traffic-pattern <STRING>. More than 1 string is provided")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
explainTrafficPatternFunc,
|
||||
)
|
||||
RegisterCallback(
|
||||
[]string{"", "import", "config"},
|
||||
func(s []string) error {
|
||||
@@ -329,6 +341,10 @@ var clientHelpFunc = func(s []string) error {
|
||||
cmd: "export traffic-pattern",
|
||||
help: []string{"Export traffic pattern as an encoded base64 string."},
|
||||
},
|
||||
{
|
||||
cmd: "explain traffic-pattern <STRING>",
|
||||
help: []string{"Decode and explain a traffic pattern from an encoded base64 string."},
|
||||
},
|
||||
{
|
||||
cmd: "delete profile <PROFILE_NAME>",
|
||||
help: []string{"Delete an inactive client configuration profile."},
|
||||
|
||||
@@ -125,6 +125,18 @@ func RegisterServerCommands() {
|
||||
},
|
||||
serverExportTrafficPatternFunc,
|
||||
)
|
||||
RegisterCallback(
|
||||
[]string{"", "explain", "traffic-pattern"},
|
||||
func(s []string) error {
|
||||
if len(s) < 4 {
|
||||
return fmt.Errorf("usage: mita explain traffic-pattern <STRING>. No string is provided")
|
||||
} else if len(s) > 4 {
|
||||
return fmt.Errorf("usage: mita explain traffic-pattern <STRING>. More than 1 string is provided")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
explainTrafficPatternFunc,
|
||||
)
|
||||
RegisterCallback(
|
||||
[]string{"", "delete", "user"},
|
||||
func(s []string) error {
|
||||
@@ -274,6 +286,10 @@ var serverHelpFunc = func(s []string) error {
|
||||
cmd: "export traffic-pattern",
|
||||
help: []string{"Export traffic pattern as an encoded base64 string."},
|
||||
},
|
||||
{
|
||||
cmd: "explain traffic-pattern <STRING>",
|
||||
help: []string{"Decode and explain a traffic pattern from an encoded base64 string."},
|
||||
},
|
||||
{
|
||||
cmd: "delete user <USER_NAME>",
|
||||
help: []string{"Delete a user from server configuration."},
|
||||
|
||||
@@ -21,7 +21,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/enfein/mieru/v3/apis/trafficpattern"
|
||||
"github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
|
||||
"github.com/enfein/mieru/v3/pkg/common"
|
||||
"github.com/enfein/mieru/v3/pkg/log"
|
||||
"github.com/enfein/mieru/v3/pkg/mathext"
|
||||
"github.com/enfein/mieru/v3/pkg/version"
|
||||
@@ -41,6 +43,19 @@ var describeBuildFunc = func(_ []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var explainTrafficPatternFunc = func(s []string) error {
|
||||
pattern, err := trafficpattern.Decode(s[3])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonBytes, err := common.MarshalJSON(pattern)
|
||||
if err != nil {
|
||||
return fmt.Errorf("common.MarshalJSON() failed: %w", err)
|
||||
}
|
||||
log.Infof("%s", string(jsonBytes))
|
||||
return nil
|
||||
}
|
||||
|
||||
func printSessionInfoList(info *appctlpb.SessionInfoList) {
|
||||
header := []string{
|
||||
"SessionID",
|
||||
|
||||
@@ -38,8 +38,10 @@ echo "mieru server config:"
|
||||
./mita describe config
|
||||
echo "mieru server effective traffic pattern:"
|
||||
./mita describe effective-traffic-pattern
|
||||
encoded_server_traffic_pattern=$(./mita export traffic-pattern)
|
||||
echo "mieru server encoded traffic pattern:"
|
||||
./mita export traffic-pattern
|
||||
echo ${encoded_server_traffic_pattern}
|
||||
./mita explain traffic-pattern $(echo ${encoded_server_traffic_pattern})
|
||||
sleep 1
|
||||
|
||||
# Start mieru server proxy.
|
||||
@@ -76,8 +78,10 @@ echo "mieru client config after import:"
|
||||
./mieru describe config
|
||||
echo "mieru client effective traffic pattern:"
|
||||
./mieru describe effective-traffic-pattern
|
||||
encoded_client_traffic_pattern=$(./mieru export traffic-pattern)
|
||||
echo "mieru client encoded traffic pattern:"
|
||||
./mieru export traffic-pattern
|
||||
echo ${encoded_client_traffic_pattern}
|
||||
./mieru explain traffic-pattern $(echo ${encoded_client_traffic_pattern})
|
||||
sleep 1
|
||||
|
||||
# Start mieru client.
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=filebrowser
|
||||
PKG_VERSION:=2.60.0
|
||||
PKG_VERSION:=2.61.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/filebrowser/filebrowser/tar.gz/v${PKG_VERSION}?
|
||||
PKG_HASH:=6ab1f5bfb68f13799e58db304361d8bbf7d2a42e893f4c1873cb6c1688912df0
|
||||
PKG_HASH:=9c85502cbb28b3812aeec921fb8fe51694d5a837aa4415c026c327522492ba05
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ddns-go
|
||||
PKG_VERSION:=1.6.5
|
||||
PKG_RELEASE:=20260123
|
||||
PKG_VERSION:=1.6.6
|
||||
PKG_RELEASE:=20260228
|
||||
|
||||
PKG_MAINTAINER:=sirpdboy <herboy2008@gmail.com>
|
||||
PKG_CONFIG_DEPENDS:=
|
||||
|
||||
+38
-19
@@ -113,29 +113,30 @@ return view.extend({
|
||||
uci.load('ddns-go')
|
||||
]);
|
||||
},
|
||||
|
||||
handleResetPassword: async function () {
|
||||
try {
|
||||
ui.showModal(_('Resetting Password'), [
|
||||
E('p', { 'class': 'spinning' }, _('Resetting admin password, please wait...'))
|
||||
E('p', { 'class': 'spinning' }, _('Resetting admin username and password, please wait...'))
|
||||
]);
|
||||
|
||||
const result = await fs.exec('/usr/bin/ddns-go', ['-resetPassword', 'admin12345', '-c', '/etc/ddns-go/ddns-go-config.yaml']);
|
||||
const configFile = '/etc/ddns-go/ddns-go-config.yaml';
|
||||
const readResult = await fs.read(configFile);
|
||||
if (readResult && readResult.trim() !== '') {
|
||||
let configContent = readResult;
|
||||
configContent = configContent.replace(/(username:\s*).*/g, '$1admin');
|
||||
|
||||
if (!configContent.includes('user:')) {
|
||||
configContent += '\nuser:\n username: admin\n password: $2a$10$G1xO1cVUYtSpPYwV/Jk3l.u7PxLUxo03wntWG6VA9BxAftNWfZEhK';
|
||||
}
|
||||
|
||||
await fs.write(configFile, configContent);
|
||||
}
|
||||
|
||||
ui.hideModal();
|
||||
|
||||
const output = (result.stdout + result.stderr).trim();
|
||||
|
||||
let success = false;
|
||||
let message = '';
|
||||
|
||||
if (result.code === 0) {
|
||||
|
||||
|
||||
message = _('Password reset successfully to admin12345');
|
||||
|
||||
ui.showModal(_('Password Reset Successful'), [
|
||||
E('p', _('Reset User:admin ,Reset password: admin12345')),
|
||||
ui.showModal(_('Username and Password Reset Successful'), [
|
||||
E('p', _('Username: admin, Password: admin12345')),
|
||||
E('p', _('You need to restart DDNS-Go service for the changes to take effect.')),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
@@ -153,15 +154,33 @@ return view.extend({
|
||||
])
|
||||
]);
|
||||
} else {
|
||||
alert(_('Reset may have failed:') + '\n' + output);
|
||||
ui.showModal(_('Partial Reset'), [
|
||||
E('p', _('DDNS-Go command reset may have failed, but configuration file has been updated.')),
|
||||
E('p', _('Username: admin, Password: admin12345')),
|
||||
E('p', _('You may need to restart DDNS-Go service manually.')),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn cbi-button cbi-button-positive',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
ui.hideModal();
|
||||
this.handleRestartService();
|
||||
})
|
||||
}, _('Restart Service Now')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'btn cbi-button cbi-button-neutral',
|
||||
'click': ui.hideModal
|
||||
}, _('Close'))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
ui.hideModal();
|
||||
console.error('Reset password failed:', error);
|
||||
alert(_('ERROR:') + '\n' + _('Reset password failed:') + '\n' + error.message);
|
||||
//console.error('Reset username/password failed:', error);
|
||||
alert(_('ERROR:') + '\n' + _('Resetusername/ password failed:') + '\n' + error.message);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
handleRestartService: async function() {
|
||||
try {
|
||||
@@ -310,7 +329,7 @@ return view.extend({
|
||||
o.default = '60';
|
||||
|
||||
o = s.option(form.Button, '_newpassword', _('Reset account password'));
|
||||
o.inputtitle = _('ResetPassword');
|
||||
o.inputtitle = _('Reset');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleResetPassword, this, data);
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-ddns-go */
|
||||
/* Copyright (C) 2021-2026 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-ddns-go */
|
||||
|
||||
'use strict';
|
||||
'require view';
|
||||
|
||||
@@ -95,7 +95,7 @@ msgid "Update status unknown"
|
||||
msgstr "更新状态未知"
|
||||
|
||||
msgid "Reset account password"
|
||||
msgstr "重置登录密码"
|
||||
msgstr "重置帐号密码"
|
||||
|
||||
msgid "ResetPassword"
|
||||
msgstr "重置密码"
|
||||
@@ -103,18 +103,33 @@ msgstr "重置密码"
|
||||
msgid "SUCCESS:"
|
||||
msgstr "完成执行:"
|
||||
|
||||
msgid "Password reset successfully to admin12345"
|
||||
msgstr "成功重置密码admin12345"
|
||||
msgid "Resetting admin username and password, please wait...5"
|
||||
msgstr "重置用户名与密码,请稍等"
|
||||
|
||||
msgid "Password Reset Successful"
|
||||
msgstr "重置密码成功"
|
||||
msgid "Username and Password Reset Successful"
|
||||
msgstr "用户名和密码重置成功"
|
||||
|
||||
msgid "Reset User:admin ,Reset password: admin12345"
|
||||
msgid "Reset username to: admin, Reset password to: admin12345"
|
||||
msgstr "重置用户名:admin 重置密码:admin12345"
|
||||
|
||||
msgid "Username: admin, Password: admin12345"
|
||||
msgstr "用户名:admin 密码:admin12345"
|
||||
|
||||
msgid "You need to restart DDNS-Go service for the changes to take effect."
|
||||
msgstr "需要重启DDNS-GO服务更改才生效"
|
||||
|
||||
msgid "You may need to restart DDNS-Go service manually."
|
||||
msgstr "必须要重启DDNS-GO服务."
|
||||
|
||||
msgid "DDNS-Go command reset may have failed, but configuration file has been updated."
|
||||
msgstr "ddns-go重置命令失败,尝试通过直接修改配置文件来重置"
|
||||
|
||||
msgid "Reset username/password"
|
||||
msgstr "重置用户名/密码"
|
||||
|
||||
msgid "DDNS-Go service restarted successfully"
|
||||
msgstr "DDNS-GO服务重启成功"
|
||||
|
||||
msgid "Restart Service Now"
|
||||
msgstr "立刻重启服务"
|
||||
|
||||
@@ -122,4 +137,4 @@ msgid "Restart Later"
|
||||
msgstr "稍后重启"
|
||||
|
||||
msgid "Due to browser security policies, the DDNS-GO interface https cannot be embedded directly."
|
||||
msgstr "由于浏览器安全策略,DDNS-GO接口https不能直接嵌入。"
|
||||
msgstr "由于浏览器安全策略,DDNS-GO接口https不能直接嵌入。"
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
"admin/services/ddns-go/ddns-go": {
|
||||
"title": "DDNS-GO Control panel",
|
||||
"order": 10,
|
||||
"action": {
|
||||
"order": 10,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "ddns-go/ddns-go"
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
"path": "ddns-go/config"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"admin/services/ddns-go/log": {
|
||||
"title": "Log",
|
||||
"order": 30,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"luci-app-ddns-go": {
|
||||
"description": "Grant UCI access for luci-app-ddns-go",
|
||||
"read": {
|
||||
"uci": ["*"],
|
||||
"uci": [ "ddns-go" ],
|
||||
"file": {
|
||||
"/etc/init.d/ddns-go": ["exec"],
|
||||
"/usr/libexec/ddns-go-call": ["exec"],
|
||||
@@ -10,6 +10,7 @@
|
||||
"/bin/pidof": ["exec"],
|
||||
"/bin/ps": ["exec"],
|
||||
"/bin/ash": ["exec"],
|
||||
"/usr/bin/ddns-go": ["exec"],
|
||||
"/etc/ddns-go/ddns-go-config.yaml": ["read"],
|
||||
"/var/log/ddns-go.log": ["read"]
|
||||
},
|
||||
@@ -17,7 +18,6 @@
|
||||
"rc": ["*"],
|
||||
"service": ["list"],
|
||||
"luci.ddns-go": ["*"],
|
||||
"network.interface.*": ["status"],
|
||||
"network": ["*"]
|
||||
}
|
||||
},
|
||||
@@ -28,7 +28,7 @@
|
||||
"file": {
|
||||
"/etc/ddns-go/ddns-go-config.yaml": ["write"]
|
||||
},
|
||||
"uci": ["*"]
|
||||
"uci": ["ddns-go"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=lucky
|
||||
PKG_VERSION:=2.26.1
|
||||
PKG_VERSION:=2.26.2
|
||||
PKG_RELEASE:=1
|
||||
PKGARCH:=all
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ PKG_NAME:=luci-app-partexp
|
||||
LUCI_TITLE:=LuCI Support for Automatic Partition Mount
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+fdisk +block-mount +bc +blkid +parted +btrfs-progs +losetup +resize2fs +e2fsprogs +f2fs-tools +kmod-loop
|
||||
PKG_VERSION:=2.0.2
|
||||
PKG_RELEASE:=20251221
|
||||
PKG_VERSION:=2.0.3
|
||||
PKG_RELEASE:=20260228
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_MAINTAINER:=Sirpdboy <herboy2008@gmail.com>
|
||||
|
||||
+60
-18
@@ -266,32 +266,74 @@ return view.extend({
|
||||
this.updateFormVisibility();
|
||||
}
|
||||
},
|
||||
|
||||
// 加载设备列表
|
||||
loadDevices: function() {
|
||||
var self = this;
|
||||
|
||||
|
||||
loadDevices: function() {
|
||||
var self = this;
|
||||
|
||||
if (self.dom.targetDisk) {
|
||||
var loadingOption = document.createElement('option');
|
||||
loadingOption.value = '';
|
||||
loadingOption.textContent = _('Loading devices...');
|
||||
loadingOption.disabled = true;
|
||||
loadingOption.selected = true;
|
||||
self.dom.targetDisk.innerHTML = '';
|
||||
self.dom.targetDisk.appendChild(loadingOption);
|
||||
}
|
||||
function loadDevicesWithRetry(retryCount = 0) {
|
||||
callPartExpGetDevices().then(function(response) {
|
||||
if (!response || !response.devices || response.devices.length === 0) {
|
||||
return;
|
||||
if (!response) {
|
||||
throw new Error('Empty response');
|
||||
}
|
||||
|
||||
// 清空设备列表
|
||||
if (self.dom.targetDisk) {
|
||||
self.dom.targetDisk.innerHTML = '';
|
||||
|
||||
// 添加设备选项
|
||||
response.devices.forEach(function(device) {
|
||||
var option = document.createElement('option');
|
||||
option.value = device.name;
|
||||
option.textContent = device.name + ' (' + device.dev + ', ' + device.size + ' MB)';
|
||||
self.dom.targetDisk.appendChild(option);
|
||||
});
|
||||
if (response.devices && response.devices.length > 0) {
|
||||
response.devices.forEach(function(device) {
|
||||
var option = document.createElement('option');
|
||||
option.value = device.name;
|
||||
option.textContent = device.name + ' (' + device.dev + ', ' + device.size + ' MB)';
|
||||
self.dom.targetDisk.appendChild(option);
|
||||
});
|
||||
} else {
|
||||
|
||||
var noDeviceOption = document.createElement('option');
|
||||
noDeviceOption.value = '';
|
||||
noDeviceOption.textContent = _('no find device');
|
||||
noDeviceOption.disabled = true;
|
||||
noDeviceOption.selected = true;
|
||||
self.dom.targetDisk.appendChild(noDeviceOption);
|
||||
}
|
||||
}
|
||||
}).catch(function(error) {
|
||||
console.error('Failed to load devices:', error);
|
||||
|
||||
if (retryCount < 3) {
|
||||
setTimeout(function() {
|
||||
loadDevicesWithRetry(retryCount + 1);
|
||||
}, 1000 * (retryCount + 1));
|
||||
} else {
|
||||
if (self.dom.targetDisk) {
|
||||
self.dom.targetDisk.innerHTML = '';
|
||||
var errorOption = document.createElement('option');
|
||||
errorOption.value = '';
|
||||
errorOption.textContent = _('load error');
|
||||
errorOption.disabled = true;
|
||||
errorOption.selected = true;
|
||||
self.dom.targetDisk.appendChild(errorOption);
|
||||
}
|
||||
|
||||
ui.addNotification({
|
||||
title: _('load device error'),
|
||||
text: _('Failed to load devices:'),
|
||||
type: 'error',
|
||||
delay: 5000
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
loadDevicesWithRetry();
|
||||
},
|
||||
|
||||
|
||||
// 加载现有的日志文件内容
|
||||
loadExistingLog: function() {
|
||||
|
||||
+14
-12
@@ -1,19 +1,21 @@
|
||||
{
|
||||
"luci-app-partexp": {
|
||||
"description": "Grant UCI access for luci-app-partexp",
|
||||
"read": {
|
||||
"description": "Grant access for luci-app-partexp",
|
||||
"read": {
|
||||
"ubus": {
|
||||
"file": ["exec", "list", "stat", "read"],
|
||||
"uci": [ "*" ],
|
||||
"partexp": ["*"]
|
||||
"file": ["exec", "list", "stat", "read"],
|
||||
"uci": ["partexp"],
|
||||
"partexp": ["get_devices", "get_log", "get_status"]
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"partexp": ["*"],
|
||||
"file": ["write"],
|
||||
"uci": ["*"]
|
||||
}
|
||||
"partexp": ["autopart", "save_config"],
|
||||
"file": ["write"]
|
||||
},
|
||||
"file": {
|
||||
"/etc/config/partexp": ["write"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,8 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
|
||||
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
o.description = translate(descrStr)
|
||||
o.description = translate(descrStr) .. string.format("<br><font color='red'>%s</font>",
|
||||
translate("Keep the match scope small. Too many nodes can impact router performance."))
|
||||
|
||||
o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy"))
|
||||
o:depends({ [_n("protocol")] = "_balancing" })
|
||||
|
||||
+2
-1
@@ -152,7 +152,8 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
|
||||
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
o.description = translate(descrStr)
|
||||
o.description = translate(descrStr) .. string.format("<br><font color='red'>%s</font>",
|
||||
translate("Keep the match scope small. Too many nodes can impact router performance."))
|
||||
|
||||
o = s:option(Value, _n("urltest_url"), translate("Probe URL"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
|
||||
@@ -45,8 +45,17 @@ _M["sing-box"] = {
|
||||
default_path = "/usr/bin/sing-box",
|
||||
match_fmt_str = "linux%%-%s",
|
||||
file_tree = {
|
||||
x86_64 = "amd64",
|
||||
mips64el = "mips64le"
|
||||
x86_64 = "amd64%-musl",
|
||||
x86 = "386%-musl",
|
||||
aarch64 = "arm64%-musl",
|
||||
rockchip = "arm64%-musl",
|
||||
mips = "mips%-softfloat",
|
||||
mips64 = "mips64%-softfloat",
|
||||
mipsel = "mipsle%-softfloat%-musl",
|
||||
mips64el = "mips64le%-softfloat",
|
||||
armv7 = "armv7%-musl",
|
||||
armv8 = "arm64%-musl",
|
||||
riscv64 = "riscv64%-musl"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,11 +222,11 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
} or nil,
|
||||
grpcSettings = (node.transport == "grpc") and {
|
||||
serviceName = node.grpc_serviceName,
|
||||
multiMode = (node.grpc_mode == "multi") and true or nil,
|
||||
idle_timeout = tonumber(node.grpc_idle_timeout) or nil,
|
||||
multiMode = (node.grpc_mode == "multi") and true or false,
|
||||
idle_timeout = node.grpc_idle_timeout and (tonumber(node.grpc_idle_timeout) < 10 and 10 or tonumber(node.grpc_idle_timeout)) or nil,
|
||||
health_check_timeout = tonumber(node.grpc_health_check_timeout) or nil,
|
||||
permit_without_stream = (node.grpc_permit_without_stream == "1") and true or nil,
|
||||
initial_windows_size = tonumber(node.grpc_initial_windows_size) or nil,
|
||||
permit_without_stream = (node.grpc_permit_without_stream == "1") and true or false,
|
||||
initial_windows_size = node.grpc_initial_windows_size and tonumber(node.grpc_initial_windows_size) or 0,
|
||||
user_agent = node.user_agent
|
||||
} or nil,
|
||||
httpupgradeSettings = (node.transport == "httpupgrade") and {
|
||||
@@ -610,7 +610,7 @@ function gen_config_server(node)
|
||||
host = node.ws_host or nil,
|
||||
path = node.ws_path
|
||||
} or nil,
|
||||
grpcSettings = (node.transport == "grpc") and {
|
||||
grpcSettings = (node.transport == "grpc" and node.grpc_serviceName) and {
|
||||
serviceName = node.grpc_serviceName
|
||||
} or nil,
|
||||
httpupgradeSettings = (node.transport == "httpupgrade") and {
|
||||
|
||||
@@ -496,6 +496,9 @@ msgstr ""
|
||||
"表示节点备注需同时满足:以 A 开头(^)、包含 B、不包含 C(!)、并以 D 结尾($)。<br>"
|
||||
"多个条件使用 <code>&&</code> 连接,条件顺序不影响结果。"
|
||||
|
||||
msgid "Keep the match scope small. Too many nodes can impact router performance."
|
||||
msgstr "建议尽量缩小匹配范围,节点过多会增加路由器负载。"
|
||||
|
||||
msgid "Balancing Strategy"
|
||||
msgstr "负载均衡策略"
|
||||
|
||||
|
||||
@@ -35,8 +35,17 @@ _M["sing-box"] = {
|
||||
default_path = "/usr/bin/sing-box",
|
||||
match_fmt_str = "linux%%-%s",
|
||||
file_tree = {
|
||||
x86_64 = "amd64",
|
||||
mips64el = "mips64le"
|
||||
x86_64 = "amd64%-musl",
|
||||
x86 = "386%-musl",
|
||||
aarch64 = "arm64%-musl",
|
||||
rockchip = "arm64%-musl",
|
||||
mips = "mips%-softfloat",
|
||||
mips64 = "mips64%-softfloat",
|
||||
mipsel = "mipsle%-softfloat%-musl",
|
||||
mips64el = "mips64le%-softfloat",
|
||||
armv7 = "armv7%-musl",
|
||||
armv8 = "arm64%-musl",
|
||||
riscv64 = "riscv64%-musl"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,11 +218,11 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
} or nil,
|
||||
grpcSettings = (node.transport == "grpc") and {
|
||||
serviceName = node.grpc_serviceName,
|
||||
multiMode = (node.grpc_mode == "multi") and true or nil,
|
||||
idle_timeout = tonumber(node.grpc_idle_timeout) or nil,
|
||||
multiMode = (node.grpc_mode == "multi") and true or false,
|
||||
idle_timeout = node.grpc_idle_timeout and (tonumber(node.grpc_idle_timeout) < 10 and 10 or tonumber(node.grpc_idle_timeout)) or nil,
|
||||
health_check_timeout = tonumber(node.grpc_health_check_timeout) or nil,
|
||||
permit_without_stream = (node.grpc_permit_without_stream == "1") and true or nil,
|
||||
initial_windows_size = tonumber(node.grpc_initial_windows_size) or nil,
|
||||
permit_without_stream = (node.grpc_permit_without_stream == "1") and true or false,
|
||||
initial_windows_size = node.grpc_initial_windows_size and tonumber(node.grpc_initial_windows_size) or 0,
|
||||
user_agent = node.user_agent
|
||||
} or nil,
|
||||
httpupgradeSettings = (node.transport == "httpupgrade") and {
|
||||
@@ -605,7 +605,7 @@ function gen_config_server(node)
|
||||
host = node.ws_host or nil,
|
||||
path = node.ws_path
|
||||
} or nil,
|
||||
grpcSettings = (node.transport == "grpc") and {
|
||||
grpcSettings = (node.transport == "grpc" and node.grpc_serviceName) and {
|
||||
serviceName = node.grpc_serviceName
|
||||
} or nil,
|
||||
httpupgradeSettings = (node.transport == "httpupgrade") and {
|
||||
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
./build-release -t ${{ matrix.platform.target }} $compile_features $compile_compress $compile_nightly $compile_cargo_flags
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.platform.target }}
|
||||
path: build/release/*
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
./build/build-host-release -t ${{ matrix.target }}
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.target }}
|
||||
path: build/release/*
|
||||
@@ -164,7 +164,7 @@ jobs:
|
||||
pwsh ./build/build-host-release.ps1 "full winservice"
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: windows-native
|
||||
path: build/release/*
|
||||
|
||||
Generated
+9
-9
@@ -1923,9 +1923,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.180"
|
||||
version = "0.2.182"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -2208,9 +2208,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.31.1"
|
||||
version = "0.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225e7cfe711e0ba79a68baeddb2982723e4235247aefce1482f2f16c27865b66"
|
||||
checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"cfg-if",
|
||||
@@ -2419,18 +2419,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.10"
|
||||
version = "1.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
|
||||
checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.10"
|
||||
version = "1.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
||||
checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3332,7 +3332,7 @@ dependencies = [
|
||||
"lru_time_cache",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"nix 0.31.1",
|
||||
"nix 0.31.2",
|
||||
"pin-project",
|
||||
"rand 0.10.0",
|
||||
"regex",
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{kt,kts}]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
max_line_length = 140
|
||||
ij_kotlin_allow_trailing_comma = true
|
||||
ij_kotlin_allow_trailing_comma_on_call_site = true
|
||||
ktlint_function_naming_ignore_when_annotated_with = Composable
|
||||
ktlint_standard_function-naming = disabled
|
||||
ktlint_standard_no-wildcard-imports = disabled
|
||||
ktlint_standard_property-naming = disabled
|
||||
|
||||
[*.xml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.gradle]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
[*.gradle.kts]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
@@ -3,7 +3,7 @@
|
||||
/local.properties
|
||||
/.idea/
|
||||
.DS_Store
|
||||
/build
|
||||
build/
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "kotlin-parcelize"
|
||||
id "com.google.devtools.ksp"
|
||||
id "org.jetbrains.kotlin.plugin.compose"
|
||||
id "com.github.triplet.play"
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "io.nekohasekai.sfa"
|
||||
compileSdk 36
|
||||
|
||||
ndkVersion "28.0.13004108"
|
||||
|
||||
def ndkPathFromEnv = System.getenv("ANDROID_NDK_HOME")
|
||||
if (ndkPathFromEnv != null) {
|
||||
ndkPath ndkPathFromEnv
|
||||
}
|
||||
|
||||
ksp {
|
||||
arg("room.incremental", "true")
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "io.nekohasekai.sfa"
|
||||
minSdk 21
|
||||
targetSdk 35
|
||||
versionCode getVersionProps("VERSION_CODE").toInteger()
|
||||
versionName getVersionProps("VERSION_NAME")
|
||||
setProperty("archivesBaseName", "SFA-" + versionName)
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file("release.keystore")
|
||||
storePassword getProps("KEYSTORE_PASS")
|
||||
keyAlias getProps("ALIAS_NAME")
|
||||
keyPassword getProps("ALIAS_PASS")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
if (getProps("KEYSTORE_PASS") != "") {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||
signingConfig signingConfigs.release
|
||||
vcsInfo.include false
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
flavorDimensions "vendor"
|
||||
productFlavors {
|
||||
play {
|
||||
}
|
||||
other {
|
||||
}
|
||||
}
|
||||
|
||||
splits {
|
||||
abi {
|
||||
enable true
|
||||
universalApk true
|
||||
reset()
|
||||
include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
aidl true
|
||||
compose true
|
||||
}
|
||||
|
||||
applicationVariants.configureEach { variant ->
|
||||
variant.outputs.configureEach {
|
||||
outputFileName = (outputFileName as String).replace("-release", "")
|
||||
outputFileName = (outputFileName as String).replace("-play", "")
|
||||
outputFileName = (outputFileName as String).replace("-other", "-foss")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(fileTree("libs"))
|
||||
|
||||
implementation "androidx.core:core-ktx:1.16.0"
|
||||
implementation "androidx.appcompat:appcompat:1.7.1"
|
||||
implementation "com.google.android.material:material:1.12.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.2.1"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.9.2"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.2"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.9.3"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:2.9.3"
|
||||
implementation "com.google.zxing:core:3.5.3"
|
||||
implementation "androidx.room:room-runtime:2.7.2"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.3.0"
|
||||
implementation "androidx.preference:preference-ktx:1.2.1"
|
||||
implementation "androidx.camera:camera-view:1.4.2"
|
||||
implementation "androidx.camera:camera-lifecycle:1.4.2"
|
||||
implementation "androidx.camera:camera-camera2:1.4.2"
|
||||
ksp "androidx.room:room-compiler:2.7.2"
|
||||
implementation "androidx.work:work-runtime-ktx:2.10.3"
|
||||
implementation "androidx.browser:browser:1.9.0"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2"
|
||||
|
||||
// DO NOT UPDATE (minSdkVersion updated)
|
||||
implementation "com.blacksquircle.ui:editorkit:2.2.0"
|
||||
implementation "com.blacksquircle.ui:language-json:2.2.0"
|
||||
|
||||
implementation("com.android.tools.smali:smali-dexlib2:3.0.9") {
|
||||
exclude group: "com.google.guava", module: "guava"
|
||||
}
|
||||
implementation "com.google.guava:guava:33.4.8-android"
|
||||
playImplementation "com.google.android.play:app-update-ktx:2.1.0"
|
||||
playImplementation "com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.1"
|
||||
|
||||
def composeBom = platform('androidx.compose:compose-bom:2025.07.00')
|
||||
implementation composeBom
|
||||
androidTestImplementation composeBom
|
||||
implementation 'androidx.compose.material3:material3'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
|
||||
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
||||
implementation 'androidx.compose.material:material-icons-extended'
|
||||
implementation 'androidx.activity:activity-compose:1.10.1'
|
||||
implementation 'me.zhanghai.compose.preference:library:1.1.1'
|
||||
implementation "androidx.navigation:navigation-compose:2.9.3"
|
||||
}
|
||||
|
||||
def playCredentialsJSON = rootProject.file("service-account-credentials.json")
|
||||
if (playCredentialsJSON.exists()) {
|
||||
play {
|
||||
serviceAccountCredentials = playCredentialsJSON
|
||||
defaultToAppBundles = true
|
||||
def version = getVersionProps("VERSION_NAME")
|
||||
if (version.contains("alpha") || version.contains("beta") || version.contains("rc")) {
|
||||
track = "beta"
|
||||
} else {
|
||||
track = "production"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(KotlinCompile.class).configureEach {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
def getProps(String propName) {
|
||||
def propsInEnv = System.getenv("LOCAL_PROPERTIES")
|
||||
if (propsInEnv != null) {
|
||||
def props = new Properties()
|
||||
props.load(new ByteArrayInputStream(Base64.decoder.decode(propsInEnv)))
|
||||
String value = props[propName]
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
def propsFile = rootProject.file("local.properties")
|
||||
if (propsFile.exists()) {
|
||||
def props = new Properties()
|
||||
props.load(new FileInputStream(propsFile))
|
||||
String value = props[propName]
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
def getVersionProps(String propName) {
|
||||
def propsFile = rootProject.file("version.properties")
|
||||
if (propsFile.exists()) {
|
||||
def props = new Properties()
|
||||
props.load(new FileInputStream(propsFile))
|
||||
String value = props[propName]
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
import org.gradle.api.file.DuplicatesStrategy
|
||||
import org.gradle.api.tasks.Sync
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.FileInputStream
|
||||
import java.util.Base64
|
||||
import java.util.Properties
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("org.jetbrains.kotlin.plugin.parcelize")
|
||||
id("com.google.devtools.ksp")
|
||||
id("org.jetbrains.kotlin.plugin.compose")
|
||||
id("org.jetbrains.kotlin.plugin.serialization")
|
||||
id("com.github.triplet.play")
|
||||
alias(libs.plugins.spotless)
|
||||
}
|
||||
|
||||
fun getProps(propName: String): String {
|
||||
val propsInEnv = System.getenv("LOCAL_PROPERTIES")
|
||||
if (propsInEnv != null) {
|
||||
val props = Properties()
|
||||
props.load(ByteArrayInputStream(Base64.getDecoder().decode(propsInEnv)))
|
||||
val value = props.getProperty(propName)
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
val propsFile = rootProject.file("local.properties")
|
||||
if (propsFile.exists()) {
|
||||
val props = Properties()
|
||||
props.load(FileInputStream(propsFile))
|
||||
val value = props.getProperty(propName)
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
fun getVersionProps(propName: String): String {
|
||||
val propsFile = rootProject.file("version.properties")
|
||||
if (propsFile.exists()) {
|
||||
val props = Properties()
|
||||
props.load(FileInputStream(propsFile))
|
||||
val value = props.getProperty(propName)
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.nekohasekai.sfa"
|
||||
compileSdk = 36
|
||||
|
||||
ndkVersion = "28.0.13004108"
|
||||
|
||||
System.getenv("ANDROID_NDK_HOME")?.let { ndkPath = it }
|
||||
|
||||
ksp {
|
||||
arg("room.incremental", "true")
|
||||
arg("room.schemaLocation", "${projectDir}/schemas")
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "io.nekohasekai.sfa"
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
versionCode = getVersionProps("VERSION_CODE").toInt()
|
||||
versionName = getVersionProps("VERSION_NAME")
|
||||
base.archivesName.set("SFA-${versionName}")
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
storeFile = file("release.keystore")
|
||||
storePassword = getProps("KEYSTORE_PASS")
|
||||
keyAlias = getProps("ALIAS_NAME")
|
||||
keyPassword = getProps("ALIAS_PASS")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
if (getProps("KEYSTORE_PASS").isNotEmpty()) {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
}
|
||||
}
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
vcsInfo.include = false
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
flavorDimensions += "vendor"
|
||||
productFlavors {
|
||||
create("play") {
|
||||
minSdk = 23
|
||||
}
|
||||
create("other") {
|
||||
minSdk = 23
|
||||
}
|
||||
create("otherLegacy") {
|
||||
minSdk = 21
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
getByName("play") {
|
||||
java.directories.add("src/minApi23/java")
|
||||
aidl.directories.add("src/minApi23/aidl")
|
||||
}
|
||||
getByName("other") {
|
||||
java.directories.addAll(listOf("src/minApi23/java", "src/github/java"))
|
||||
aidl.directories.add("src/minApi23/aidl")
|
||||
}
|
||||
getByName("otherLegacy") {
|
||||
java.directories.addAll(listOf("src/minApi21/java", "src/github/java"))
|
||||
aidl.directories.add("src/minApi23/aidl")
|
||||
}
|
||||
}
|
||||
|
||||
splits {
|
||||
abi {
|
||||
isEnable = true
|
||||
isUniversalApk = true
|
||||
reset()
|
||||
include("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
androidResources {
|
||||
generateLocaleConfig = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
aidl = true
|
||||
compose = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
packaging {
|
||||
jniLibs {
|
||||
useLegacyPackaging = true
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.configureEach {
|
||||
outputs.configureEach {
|
||||
val output = this as com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
||||
var fileName = output.outputFileName
|
||||
fileName = fileName.replace("-release", "")
|
||||
fileName = fileName.replace("-play", "-play")
|
||||
fileName = fileName.replace("-otherLegacy", "-legacy-android-5")
|
||||
fileName = fileName.replace("-other", "")
|
||||
output.outputFileName = fileName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// libbox
|
||||
"playImplementation"(files("libs/libbox.aar"))
|
||||
"otherImplementation"(files("libs/libbox.aar"))
|
||||
"otherLegacyImplementation"(files("libs/libbox-legacy.aar"))
|
||||
|
||||
// API level specific versions
|
||||
val lifecycleVersion23 = "2.10.0"
|
||||
val roomVersion23 = "2.8.4"
|
||||
val workVersion23 = "2.11.1"
|
||||
val cameraVersion23 = "1.5.3"
|
||||
val browserVersion23 = "1.9.0"
|
||||
|
||||
val lifecycleVersion21 = "2.9.4"
|
||||
val roomVersion21 = "2.7.2"
|
||||
val workVersion21 = "2.10.5"
|
||||
val cameraVersion21 = "1.4.2"
|
||||
val browserVersion21 = "1.9.0"
|
||||
|
||||
// Common dependencies (no API level difference)
|
||||
implementation("androidx.core:core-ktx:1.17.0")
|
||||
implementation("androidx.appcompat:appcompat:1.7.1")
|
||||
implementation("com.google.android.material:material:1.13.0")
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
|
||||
implementation("androidx.navigation:navigation-fragment-ktx:2.9.7")
|
||||
implementation("androidx.navigation:navigation-ui-ktx:2.9.7")
|
||||
implementation("com.google.zxing:core:3.5.4")
|
||||
implementation("androidx.coordinatorlayout:coordinatorlayout:1.3.0")
|
||||
implementation("androidx.preference:preference-ktx:1.2.1")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
|
||||
implementation("com.blacksquircle.ui:editorkit:2.2.0")
|
||||
implementation("com.blacksquircle.ui:language-json:2.2.0")
|
||||
implementation("com.android.tools.smali:smali-dexlib2:3.0.9") {
|
||||
exclude(group = "com.google.guava", module = "guava")
|
||||
}
|
||||
implementation("com.google.guava:guava:33.5.0-android")
|
||||
|
||||
// API 23+ dependencies (play/other)
|
||||
"playImplementation"("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion23")
|
||||
"playImplementation"("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion23")
|
||||
"playImplementation"("androidx.lifecycle:lifecycle-process:$lifecycleVersion23")
|
||||
"playImplementation"("androidx.room:room-runtime:$roomVersion23")
|
||||
"playImplementation"("androidx.work:work-runtime-ktx:$workVersion23")
|
||||
"playImplementation"("androidx.camera:camera-view:$cameraVersion23")
|
||||
"playImplementation"("androidx.camera:camera-lifecycle:$cameraVersion23")
|
||||
"playImplementation"("androidx.camera:camera-camera2:$cameraVersion23")
|
||||
"playImplementation"("androidx.browser:browser:$browserVersion23")
|
||||
"playAnnotationProcessor"("androidx.room:room-compiler:$roomVersion23")
|
||||
"kspPlay"("androidx.room:room-compiler:$roomVersion23")
|
||||
|
||||
"otherImplementation"("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion23")
|
||||
"otherImplementation"("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion23")
|
||||
"otherImplementation"("androidx.lifecycle:lifecycle-process:$lifecycleVersion23")
|
||||
"otherImplementation"("androidx.room:room-runtime:$roomVersion23")
|
||||
"otherImplementation"("androidx.work:work-runtime-ktx:$workVersion23")
|
||||
"otherImplementation"("androidx.camera:camera-view:$cameraVersion23")
|
||||
"otherImplementation"("androidx.camera:camera-lifecycle:$cameraVersion23")
|
||||
"otherImplementation"("androidx.camera:camera-camera2:$cameraVersion23")
|
||||
"otherImplementation"("androidx.browser:browser:$browserVersion23")
|
||||
"kspOther"("androidx.room:room-compiler:$roomVersion23")
|
||||
|
||||
// API 21 dependencies (otherLegacy)
|
||||
"otherLegacyImplementation"("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion21")
|
||||
"otherLegacyImplementation"("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion21")
|
||||
"otherLegacyImplementation"("androidx.lifecycle:lifecycle-process:$lifecycleVersion21")
|
||||
"otherLegacyImplementation"("androidx.room:room-runtime:$roomVersion21")
|
||||
"otherLegacyImplementation"("androidx.work:work-runtime-ktx:$workVersion21")
|
||||
"otherLegacyImplementation"("androidx.camera:camera-view:$cameraVersion21")
|
||||
"otherLegacyImplementation"("androidx.camera:camera-lifecycle:$cameraVersion21")
|
||||
"otherLegacyImplementation"("androidx.camera:camera-camera2:$cameraVersion21")
|
||||
"otherLegacyImplementation"("androidx.browser:browser:$browserVersion21")
|
||||
"kspOtherLegacy"("androidx.room:room-compiler:$roomVersion21")
|
||||
|
||||
// Play Store specific
|
||||
"playImplementation"("com.google.android.play:app-update-ktx:2.1.0")
|
||||
"playImplementation"("com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.1")
|
||||
|
||||
// Shizuku (play and other flavors, API 23+ only)
|
||||
val shizukuVersion = "12.2.0"
|
||||
"playImplementation"("dev.rikka.shizuku:api:$shizukuVersion")
|
||||
"playImplementation"("dev.rikka.shizuku:provider:$shizukuVersion")
|
||||
"otherImplementation"("dev.rikka.shizuku:api:$shizukuVersion")
|
||||
"otherImplementation"("dev.rikka.shizuku:provider:$shizukuVersion")
|
||||
|
||||
// libsu for ROOT package query (all flavors)
|
||||
val libsuVersion = "6.0.0"
|
||||
"playImplementation"("com.github.topjohnwu.libsu:core:$libsuVersion")
|
||||
"playImplementation"("com.github.topjohnwu.libsu:service:$libsuVersion")
|
||||
"otherImplementation"("com.github.topjohnwu.libsu:core:$libsuVersion")
|
||||
"otherImplementation"("com.github.topjohnwu.libsu:service:$libsuVersion")
|
||||
"otherLegacyImplementation"("com.github.topjohnwu.libsu:core:$libsuVersion")
|
||||
"otherLegacyImplementation"("com.github.topjohnwu.libsu:service:$libsuVersion")
|
||||
|
||||
// Compose dependencies - API 23+ (play/other)
|
||||
val composeBom23 = platform("androidx.compose:compose-bom:2026.02.00")
|
||||
val activityVersion23 = "1.12.4"
|
||||
val lifecycleComposeVersion23 = "2.10.0"
|
||||
|
||||
"playImplementation"(composeBom23)
|
||||
"playImplementation"("androidx.compose.material3:material3")
|
||||
"playImplementation"("androidx.compose.material3.adaptive:adaptive")
|
||||
"playImplementation"("androidx.compose.ui:ui")
|
||||
"playImplementation"("androidx.compose.ui:ui-tooling-preview")
|
||||
"playImplementation"("androidx.compose.material:material-icons-extended")
|
||||
"playImplementation"("androidx.activity:activity-compose:$activityVersion23")
|
||||
"playImplementation"("androidx.navigation:navigation-compose:2.9.7")
|
||||
"playImplementation"("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleComposeVersion23")
|
||||
"playImplementation"("androidx.compose.runtime:runtime-livedata")
|
||||
|
||||
"otherImplementation"(composeBom23)
|
||||
"otherImplementation"("androidx.compose.material3:material3")
|
||||
"otherImplementation"("androidx.compose.material3.adaptive:adaptive")
|
||||
"otherImplementation"("androidx.compose.ui:ui")
|
||||
"otherImplementation"("androidx.compose.ui:ui-tooling-preview")
|
||||
"otherImplementation"("androidx.compose.material:material-icons-extended")
|
||||
"otherImplementation"("androidx.activity:activity-compose:$activityVersion23")
|
||||
"otherImplementation"("androidx.navigation:navigation-compose:2.9.7")
|
||||
"otherImplementation"("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleComposeVersion23")
|
||||
"otherImplementation"("androidx.compose.runtime:runtime-livedata")
|
||||
|
||||
// Compose dependencies - API 21 (otherLegacy)
|
||||
val composeBom21 = platform("androidx.compose:compose-bom:2025.01.00")
|
||||
val activityVersion21 = "1.11.0"
|
||||
val lifecycleComposeVersion21 = "2.9.4"
|
||||
|
||||
"otherLegacyImplementation"(composeBom21)
|
||||
"otherLegacyImplementation"("androidx.compose.material3:material3")
|
||||
"otherLegacyImplementation"("androidx.compose.material3.adaptive:adaptive")
|
||||
"otherLegacyImplementation"("androidx.compose.ui:ui")
|
||||
"otherLegacyImplementation"("androidx.compose.ui:ui-tooling-preview")
|
||||
"otherLegacyImplementation"("androidx.compose.material:material-icons-extended")
|
||||
"otherLegacyImplementation"("androidx.activity:activity-compose:$activityVersion21")
|
||||
"otherLegacyImplementation"("androidx.navigation:navigation-compose:2.9.7")
|
||||
"otherLegacyImplementation"("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleComposeVersion21")
|
||||
"otherLegacyImplementation"("androidx.compose.runtime:runtime-livedata")
|
||||
|
||||
// Debug/Test dependencies
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
|
||||
// Common Compose-related libraries
|
||||
implementation("sh.calvin.reorderable:reorderable:3.0.0")
|
||||
implementation("com.github.jeziellago:compose-markdown:0.5.8")
|
||||
implementation("org.kodein.emoji:emoji-kt:2.3.0")
|
||||
|
||||
// Xposed API for self-hooking VPN hide module
|
||||
compileOnly("de.robv.android.xposed:api:82")
|
||||
compileOnly(project(":libxposed-api"))
|
||||
}
|
||||
|
||||
val playCredentialsJSON = rootProject.file("service-account-credentials.json")
|
||||
if (playCredentialsJSON.exists()) {
|
||||
play {
|
||||
serviceAccountCredentials.set(playCredentialsJSON)
|
||||
defaultToAppBundles.set(true)
|
||||
val version = getVersionProps("VERSION_NAME")
|
||||
track.set(
|
||||
if (version.contains("alpha") || version.contains("beta")/* || version.contains("rc")*/) {
|
||||
"beta"
|
||||
} else {
|
||||
"production"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
|
||||
spotless {
|
||||
kotlin {
|
||||
target("src/**/*.kt")
|
||||
ktlint(libs.versions.ktlint.get())
|
||||
.editorConfigOverride(mapOf(
|
||||
"ktlint_standard_backing-property-naming" to "disabled",
|
||||
"ktlint_standard_filename" to "disabled",
|
||||
"ktlint_standard_max-line-length" to "disabled",
|
||||
"ktlint_standard_property-naming" to "disabled",
|
||||
))
|
||||
}
|
||||
java {
|
||||
target("src/**/*.java")
|
||||
googleJavaFormat()
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -2,11 +2,11 @@
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "b7bfa362ec191b0a18660e615da81e46",
|
||||
"identityHash": "24de05fe91b147c75b870f91b2f4871b",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "profiles",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userOrder` INTEGER NOT NULL, `name` TEXT NOT NULL, `typed` BLOB NOT NULL)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userOrder` INTEGER NOT NULL, `name` TEXT NOT NULL, `icon` TEXT, `typed` BLOB NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
@@ -26,6 +26,11 @@
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon",
|
||||
"columnName": "icon",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "typed",
|
||||
"columnName": "typed",
|
||||
@@ -38,15 +43,12 @@
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b7bfa362ec191b0a18660e615da81e46')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '24de05fe91b147c75b870f91b2f4871b')"
|
||||
]
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 2,
|
||||
"identityHash": "dc5fb65e389df8c8391b3435652f4c64",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "profiles",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userOrder` INTEGER NOT NULL, `name` TEXT NOT NULL, `icon` TEXT DEFAULT NULL, `typed` BLOB NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "userOrder",
|
||||
"columnName": "userOrder",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon",
|
||||
"columnName": "icon",
|
||||
"affinity": "TEXT",
|
||||
"defaultValue": "NULL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "typed",
|
||||
"columnName": "typed",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'dc5fb65e389df8c8391b3435652f4c64')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" />
|
||||
|
||||
<application>
|
||||
<receiver
|
||||
android:name=".vendor.InstallResultReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="io.nekohasekai.sfa.INSTALL_COMPLETE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.sfa.Application
|
||||
import io.nekohasekai.sfa.update.UpdateState
|
||||
import io.nekohasekai.sfa.utils.HTTPClient
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
|
||||
class ApkDownloader : Closeable {
|
||||
private val client = Libbox.newHTTPClient().apply {
|
||||
modernTLS()
|
||||
keepAlive()
|
||||
}
|
||||
|
||||
suspend fun download(url: String): File = withContext(Dispatchers.IO) {
|
||||
val cacheDir = File(Application.application.cacheDir, "updates")
|
||||
cacheDir.mkdirs()
|
||||
val apkFile = File(cacheDir, "update.apk")
|
||||
|
||||
if (apkFile.exists()) apkFile.delete()
|
||||
|
||||
val request = client.newRequest()
|
||||
request.setUserAgent(HTTPClient.userAgent)
|
||||
request.setURL(url)
|
||||
|
||||
val response = request.execute()
|
||||
response.writeTo(apkFile.absolutePath)
|
||||
|
||||
if (!apkFile.exists() || apkFile.length() == 0L) {
|
||||
throw Exception("Download failed: empty file")
|
||||
}
|
||||
|
||||
UpdateState.saveApkPath(apkFile)
|
||||
apkFile
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
client.close()
|
||||
}
|
||||
}
|
||||
Vendored
+149
@@ -0,0 +1,149 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import android.os.Build
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.sfa.BuildConfig
|
||||
import io.nekohasekai.sfa.ktx.unwrap
|
||||
import io.nekohasekai.sfa.update.UpdateInfo
|
||||
import io.nekohasekai.sfa.update.UpdateTrack
|
||||
import io.nekohasekai.sfa.utils.HTTPClient
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.io.Closeable
|
||||
|
||||
class GitHubUpdateChecker : Closeable {
|
||||
companion object {
|
||||
private const val RELEASES_URL = "https://api.github.com/repos/SagerNet/sing-box/releases"
|
||||
private const val METADATA_FILENAME = "SFA-version-metadata.json"
|
||||
}
|
||||
|
||||
private val client = Libbox.newHTTPClient().apply {
|
||||
modernTLS()
|
||||
keepAlive()
|
||||
}
|
||||
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
fun checkUpdate(track: UpdateTrack): UpdateInfo? {
|
||||
val releases = getReleases()
|
||||
var selected: ReleaseCandidate? = null
|
||||
|
||||
for (release in releases) {
|
||||
if (!isReleaseInTrack(release, track)) {
|
||||
continue
|
||||
}
|
||||
val metadata = runCatching { downloadMetadata(release) }.getOrNull() ?: continue
|
||||
if (!isNewerThanCurrent(metadata.versionName)) {
|
||||
continue
|
||||
}
|
||||
val currentBest = selected
|
||||
if (currentBest == null || isBetterVersion(metadata, currentBest.metadata)) {
|
||||
selected = ReleaseCandidate(release, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
val release = selected?.release ?: return null
|
||||
val metadata = selected.metadata
|
||||
|
||||
val isLegacy = Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
val apkAsset = release.assets.find { asset ->
|
||||
asset.name.endsWith(".apk") &&
|
||||
!asset.name.contains("play") &&
|
||||
asset.name.contains("legacy-android-5") == isLegacy
|
||||
}
|
||||
|
||||
return UpdateInfo(
|
||||
versionCode = metadata.versionCode,
|
||||
versionName = metadata.versionName,
|
||||
downloadUrl = apkAsset?.browserDownloadUrl ?: release.htmlUrl,
|
||||
releaseUrl = release.htmlUrl,
|
||||
releaseNotes = release.body,
|
||||
isPrerelease = release.prerelease,
|
||||
fileSize = apkAsset?.size ?: 0,
|
||||
)
|
||||
}
|
||||
|
||||
private fun getReleases(): List<GitHubRelease> {
|
||||
val request = client.newRequest()
|
||||
request.setURL(RELEASES_URL)
|
||||
request.setHeader("Accept", "application/vnd.github.v3+json")
|
||||
request.setUserAgent(HTTPClient.userAgent)
|
||||
|
||||
val response = request.execute()
|
||||
val content = response.content.unwrap
|
||||
|
||||
return json.decodeFromString(content)
|
||||
}
|
||||
|
||||
private fun isReleaseInTrack(release: GitHubRelease, track: UpdateTrack): Boolean {
|
||||
if (release.draft) {
|
||||
return false
|
||||
}
|
||||
return when (track) {
|
||||
UpdateTrack.STABLE -> !release.prerelease
|
||||
UpdateTrack.BETA -> true
|
||||
}
|
||||
}
|
||||
|
||||
private fun isNewerThanCurrent(versionName: String): Boolean {
|
||||
return Libbox.compareSemver(versionName, BuildConfig.VERSION_NAME)
|
||||
}
|
||||
|
||||
private fun isBetterVersion(version: VersionMetadata, other: VersionMetadata): Boolean {
|
||||
if (Libbox.compareSemver(version.versionName, other.versionName)) {
|
||||
return true
|
||||
}
|
||||
if (Libbox.compareSemver(other.versionName, version.versionName)) {
|
||||
return false
|
||||
}
|
||||
return version.versionCode > other.versionCode
|
||||
}
|
||||
|
||||
private fun downloadMetadata(release: GitHubRelease): VersionMetadata? {
|
||||
val metadataAsset = release.assets.find { it.name == METADATA_FILENAME }
|
||||
?: return null
|
||||
|
||||
val request = client.newRequest()
|
||||
request.setURL(metadataAsset.browserDownloadUrl)
|
||||
request.setUserAgent(HTTPClient.userAgent)
|
||||
|
||||
val response = request.execute()
|
||||
val content = response.content.unwrap
|
||||
|
||||
return json.decodeFromString<VersionMetadata>(content)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
client.close()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class GitHubRelease(
|
||||
@SerialName("tag_name") val tagName: String = "",
|
||||
val name: String = "",
|
||||
val body: String? = null,
|
||||
val draft: Boolean = false,
|
||||
val prerelease: Boolean = false,
|
||||
@SerialName("html_url") val htmlUrl: String = "",
|
||||
val assets: List<GitHubAsset> = emptyList(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GitHubAsset(
|
||||
val name: String = "",
|
||||
@SerialName("browser_download_url") val browserDownloadUrl: String = "",
|
||||
val size: Long = 0,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class VersionMetadata(
|
||||
@SerialName("version_code") val versionCode: Int = 0,
|
||||
@SerialName("version_name") val versionName: String = "",
|
||||
)
|
||||
|
||||
private data class ReleaseCandidate(
|
||||
val release: GitHubRelease,
|
||||
val metadata: VersionMetadata,
|
||||
)
|
||||
}
|
||||
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.util.Log
|
||||
import io.nekohasekai.sfa.update.UpdateState
|
||||
|
||||
class InstallResultReceiver : BroadcastReceiver() {
|
||||
companion object {
|
||||
const val ACTION_INSTALL_COMPLETE = "io.nekohasekai.sfa.INSTALL_COMPLETE"
|
||||
private const val TAG = "InstallResultReceiver"
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action != ACTION_INSTALL_COMPLETE) return
|
||||
|
||||
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE)
|
||||
val message = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
||||
|
||||
Log.d(TAG, "Install result: status=$status, message=$message")
|
||||
|
||||
when (status) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val confirmIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
||||
intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
intent.getParcelableExtra(Intent.EXTRA_INTENT)
|
||||
}
|
||||
confirmIntent?.let {
|
||||
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(it)
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
Log.d(TAG, "Installation successful")
|
||||
UpdateState.setInstallStatus(UpdateState.InstallStatus.Success)
|
||||
}
|
||||
else -> {
|
||||
Log.e(TAG, "Installation failed: $status - $message")
|
||||
UpdateState.setInstallStatus(UpdateState.InstallStatus.Failed(message ?: "Unknown error"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Looper
|
||||
import android.os.ParcelFileDescriptor
|
||||
import com.topjohnwu.superuser.ipc.RootService
|
||||
import io.nekohasekai.sfa.Application
|
||||
import io.nekohasekai.sfa.bg.IRootService
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
||||
object RootInstaller {
|
||||
|
||||
suspend fun install(apkFile: File) {
|
||||
withContext(Dispatchers.IO) {
|
||||
bindRootService().use { handle ->
|
||||
ParcelFileDescriptor.open(apkFile, ParcelFileDescriptor.MODE_READ_ONLY).use { pfd ->
|
||||
handle.service.installPackage(
|
||||
pfd,
|
||||
apkFile.length(),
|
||||
android.os.Process.myUserHandle().hashCode(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun bindRootService(): RootServiceHandle {
|
||||
return withContext(Dispatchers.Main) {
|
||||
suspendCancellableCoroutine { continuation ->
|
||||
val conn = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: android.content.ComponentName?, binder: IBinder?) {
|
||||
val svc = if (binder != null && binder.pingBinder()) {
|
||||
IRootService.Stub.asInterface(binder)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (svc == null) {
|
||||
continuation.resumeWithException(IllegalStateException("Invalid root service binder"))
|
||||
return
|
||||
}
|
||||
continuation.resume(RootServiceHandle(this, svc))
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: android.content.ComponentName?) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val intent = Intent(Application.application, Class.forName("io.nekohasekai.sfa.bg.RootServer"))
|
||||
RootService.bind(intent, conn)
|
||||
} catch (e: Throwable) {
|
||||
continuation.resumeWithException(e)
|
||||
return@suspendCancellableCoroutine
|
||||
}
|
||||
|
||||
continuation.invokeOnCancellation {
|
||||
RootService.unbind(conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RootServiceHandle(val connection: ServiceConnection, val service: IRootService) : java.io.Closeable {
|
||||
override fun close() {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
RootService.unbind(connection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import android.content.pm.PackageInstaller as AndroidPackageInstaller
|
||||
|
||||
object SystemPackageInstaller {
|
||||
|
||||
fun canSystemSilentInstall(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
|
||||
fun install(context: Context, apkFile: File) {
|
||||
val packageInstaller = context.packageManager.packageInstaller
|
||||
val params = AndroidPackageInstaller.SessionParams(AndroidPackageInstaller.SessionParams.MODE_FULL_INSTALL)
|
||||
params.setAppPackageName(context.packageName)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
params.setRequireUserAction(AndroidPackageInstaller.SessionParams.USER_ACTION_NOT_REQUIRED)
|
||||
}
|
||||
|
||||
val sessionId = packageInstaller.createSession(params)
|
||||
packageInstaller.openSession(sessionId).use { session ->
|
||||
session.openWrite("update.apk", 0, apkFile.length()).use { outputStream ->
|
||||
FileInputStream(apkFile).use { inputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
session.fsync(outputStream)
|
||||
}
|
||||
|
||||
val intent = Intent(context, InstallResultReceiver::class.java).apply {
|
||||
action = InstallResultReceiver.ACTION_INSTALL_COMPLETE
|
||||
}
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context,
|
||||
sessionId,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE,
|
||||
)
|
||||
|
||||
session.commit(pendingIntent.intentSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.BackoffPolicy
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.NetworkType
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
import io.nekohasekai.sfa.database.Settings
|
||||
import io.nekohasekai.sfa.update.UpdateState
|
||||
import io.nekohasekai.sfa.update.UpdateTrack
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class UpdateWorker(private val appContext: Context, params: WorkerParameters) : CoroutineWorker(appContext, params) {
|
||||
|
||||
companion object {
|
||||
private const val WORK_NAME = "AutoUpdate"
|
||||
private const val TAG = "UpdateWorker"
|
||||
|
||||
fun schedule(context: Context) {
|
||||
if (!Settings.autoUpdateEnabled) {
|
||||
WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME)
|
||||
Log.d(TAG, "Auto update disabled, cancelled scheduled work")
|
||||
return
|
||||
}
|
||||
|
||||
val constraints = Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.setRequiresBatteryNotLow(true)
|
||||
.build()
|
||||
|
||||
val workRequest = PeriodicWorkRequestBuilder<UpdateWorker>(
|
||||
24,
|
||||
TimeUnit.HOURS,
|
||||
)
|
||||
.setConstraints(constraints)
|
||||
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.HOURS)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||
WORK_NAME,
|
||||
ExistingPeriodicWorkPolicy.KEEP,
|
||||
workRequest,
|
||||
)
|
||||
Log.d(TAG, "Auto update scheduled")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
if (!Settings.autoUpdateEnabled) {
|
||||
Log.d(TAG, "Auto update disabled, skipping")
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
Log.d(TAG, "Checking for updates...")
|
||||
|
||||
return try {
|
||||
val track = UpdateTrack.fromString(Settings.updateTrack)
|
||||
val updateInfo = GitHubUpdateChecker().use { it.checkUpdate(track) }
|
||||
|
||||
if (updateInfo == null) {
|
||||
Log.d(TAG, "No update available")
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
Log.d(TAG, "Update available: ${updateInfo.versionName}")
|
||||
UpdateState.setUpdate(updateInfo)
|
||||
|
||||
if (Settings.silentInstallEnabled && ApkInstaller.canSilentInstall()) {
|
||||
Log.d(TAG, "Downloading update...")
|
||||
val apkFile = ApkDownloader().use { it.download(updateInfo.downloadUrl) }
|
||||
|
||||
Log.d(TAG, "Installing update...")
|
||||
ApkInstaller.install(appContext, apkFile)
|
||||
Log.d(TAG, "Update installed successfully")
|
||||
} else {
|
||||
Log.d(TAG, "Silent install not available, update will be shown on next app launch")
|
||||
}
|
||||
|
||||
Result.success()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Auto update failed", e)
|
||||
Result.retry()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,10 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<!-- For saving images to gallery on older Android versions -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
@@ -29,6 +33,7 @@
|
||||
android:name=".Application"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:description="@string/xposed_description"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
@@ -36,30 +41,23 @@
|
||||
android:theme="@style/AppTheme"
|
||||
tools:targetApi="31">
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:name=".compose.MainActivity"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:launchMode="singleTask">
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_crashlytics_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@@ -93,50 +91,24 @@
|
||||
<data android:pathPattern="/.*\\.bpf" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:priority="998">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
|
||||
<data android:scheme="file" />
|
||||
<data android:scheme="content" />
|
||||
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.ShortcutActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true"
|
||||
android:label="@string/quick_toggle"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity=""
|
||||
android:theme="@style/AppTheme.Translucent">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.profile.NewProfileActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.profile.EditProfileActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.profile.EditProfileContentActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.profileoverride.ProfileOverrideActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.profileoverride.PerAppProxyActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.debug.DebugActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.debug.VPNScanActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name="io.nekohasekai.sfa.ui.profile.QRScanActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".bg.TileService"
|
||||
android:directBootAware="true"
|
||||
@@ -180,6 +152,11 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<provider
|
||||
android:name="io.github.libxposed.service.XposedProvider"
|
||||
android:authorities="${applicationId}.XposedService"
|
||||
android:exported="true" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.cache"
|
||||
@@ -190,6 +167,17 @@
|
||||
android:resource="@xml/cache_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name=".WorkingDirectoryProvider"
|
||||
android:authorities="${applicationId}.workingdir"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package io.github.libxposed.service;
|
||||
|
||||
interface IXposedScopeCallback {
|
||||
oneway void onScopeRequestPrompted(String packageName) = 1;
|
||||
oneway void onScopeRequestApproved(String packageName) = 2;
|
||||
oneway void onScopeRequestDenied(String packageName) = 3;
|
||||
oneway void onScopeRequestTimeout(String packageName) = 4;
|
||||
oneway void onScopeRequestFailed(String packageName, String message) = 5;
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package io.github.libxposed.service;
|
||||
import io.github.libxposed.service.IXposedScopeCallback;
|
||||
|
||||
interface IXposedService {
|
||||
const int API = 100;
|
||||
|
||||
const int FRAMEWORK_PRIVILEGE_ROOT = 0;
|
||||
const int FRAMEWORK_PRIVILEGE_CONTAINER = 1;
|
||||
const int FRAMEWORK_PRIVILEGE_APP = 2;
|
||||
const int FRAMEWORK_PRIVILEGE_EMBEDDED = 3;
|
||||
|
||||
const String AUTHORITY_SUFFIX = ".XposedService";
|
||||
const String SEND_BINDER = "SendBinder";
|
||||
|
||||
// framework details
|
||||
int getAPIVersion() = 1;
|
||||
String getFrameworkName() = 2;
|
||||
String getFrameworkVersion() = 3;
|
||||
long getFrameworkVersionCode() = 4;
|
||||
int getFrameworkPrivilege() = 5;
|
||||
|
||||
// scope utilities
|
||||
List<String> getScope() = 10;
|
||||
oneway void requestScope(String packageName, IXposedScopeCallback callback) = 11;
|
||||
String removeScope(String packageName) = 12;
|
||||
|
||||
// remote preference utilities
|
||||
Bundle requestRemotePreferences(String group) = 20;
|
||||
void updateRemotePreferences(String group, in Bundle diff) = 21;
|
||||
void deleteRemotePreferences(String group) = 22;
|
||||
|
||||
// remote file utilities
|
||||
String[] listRemoteFiles() = 30;
|
||||
ParcelFileDescriptor openRemoteFile(String name) = 31;
|
||||
boolean deleteRemoteFile(String name) = 32;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.nekohasekai.sfa.bg;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import io.nekohasekai.sfa.bg.ParceledListSlice;
|
||||
|
||||
interface IRootService {
|
||||
void destroy() = 16777114; // Destroy method defined by Shizuku server
|
||||
|
||||
ParceledListSlice getInstalledPackages(int flags, int userId) = 1;
|
||||
|
||||
void installPackage(in ParcelFileDescriptor apk, long size, int userId) = 2;
|
||||
|
||||
String exportDebugInfo(String outputPath) = 3;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.nekohasekai.sfa.bg;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import io.nekohasekai.sfa.bg.ParceledListSlice;
|
||||
|
||||
interface IShizukuService {
|
||||
void destroy() = 16777114; // Destroy method defined by Shizuku server
|
||||
|
||||
ParceledListSlice getInstalledPackages(int flags, int userId) = 1;
|
||||
|
||||
void installPackage(in ParcelFileDescriptor apk, long size, int userId) = 2;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package io.nekohasekai.sfa.bg;
|
||||
|
||||
parcelable LogEntry;
|
||||
@@ -0,0 +1,3 @@
|
||||
package io.nekohasekai.sfa.bg;
|
||||
|
||||
parcelable PackageEntry;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package io.nekohasekai.sfa.bg;
|
||||
|
||||
parcelable ParceledListSlice;
|
||||
@@ -0,0 +1,15 @@
|
||||
package android.content;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.IInterface;
|
||||
|
||||
public interface IIntentReceiver extends IInterface {
|
||||
void performReceive(
|
||||
Intent intent,
|
||||
int resultCode,
|
||||
String data,
|
||||
Bundle extras,
|
||||
boolean ordered,
|
||||
boolean sticky,
|
||||
int sendingUser);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user