mirror of
https://github.com/hiddify/hiddify-app.git
synced 2026-05-04 11:22:28 +00:00
Merge branch 'new-design-v2'
This commit is contained in:
@@ -16,7 +16,7 @@ body:
|
||||
id: confirm-search
|
||||
attributes:
|
||||
label: Search first
|
||||
description: Please search [existing issues](https://github.com/hiddify/hiddify-next/issues) before reporting.
|
||||
description: Please search [existing issues](https://github.com/hiddify/hiddify-app/issues) before reporting.
|
||||
options:
|
||||
- label: I searched and no similar issues were found
|
||||
required: true
|
||||
|
||||
@@ -30,7 +30,7 @@ git tag ${TAG} > /dev/null
|
||||
|
||||
gitchangelog > HISTORY.md || { git tag -d ${TAG}; echo "Please run pip install gitchangelog pystache mustache markdown"; exit 2; }
|
||||
git tag -d ${TAG} > /dev/null
|
||||
git add libcore dependencies.properties ios/Runner.xcodeproj/project.pbxproj pubspec.yaml windows/packaging/msix/make_config.yaml HISTORY.md
|
||||
git add hiddify-core dependencies.properties ios/Runner.xcodeproj/project.pbxproj pubspec.yaml windows/packaging/msix/make_config.yaml HISTORY.md
|
||||
git commit -m "release: version ${TAG}"
|
||||
echo "creating git tag : v${TAG}"
|
||||
git push
|
||||
|
||||
+13
-13
@@ -25,29 +25,29 @@
|
||||
<tbody align=left>
|
||||
<tr>
|
||||
<td>Android</td><td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td><td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>macOS (v10.15+)</td>
|
||||
<td><a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-MacOS.dmg"><img src="https://img.shields.io/badge/DMG-Universal-ea005e.svg?logo=apple"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-MacOS-Installer.pkg"><img src="https://img.shields.io/badge/PKG-Universal-bc544b.svg?logo=apple" /></a></a></td>
|
||||
<td><a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-MacOS.dmg"><img src="https://img.shields.io/badge/DMG-Universal-ea005e.svg?logo=apple"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-MacOS-Installer.pkg"><img src="https://img.shields.io/badge/PKG-Universal-bc544b.svg?logo=apple" /></a></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td><a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/download/RELEASE_TAG/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a></td>
|
||||
<td><a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/download/RELEASE_TAG/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -57,6 +57,6 @@
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
**List of all changes:** [ChangeLog](https://github.com/hiddify/hiddify-next/blob/main/HISTORY.md)
|
||||
**List of all changes:** [ChangeLog](https://github.com/hiddify/hiddify-app/blob/main/HISTORY.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -7,8 +7,8 @@ on:
|
||||
release:
|
||||
types: [released] # Run the action when a GitHub release is published
|
||||
|
||||
schedule:
|
||||
- cron: '0 */6 * * *' # Run the action every 6 hours
|
||||
# schedule:
|
||||
# - cron: '0 */6 * * *' # Run the action every 6 hours
|
||||
|
||||
workflow_dispatch: # Manually run the action
|
||||
|
||||
|
||||
+127
-35
@@ -15,16 +15,18 @@ on:
|
||||
env:
|
||||
IS_GITHUB_ACTIONS: 1
|
||||
CHANNEL: "${{ inputs.channel }}"
|
||||
FLUTTER_VERSION: '3.24.0'
|
||||
NDK_VERSION: r26d
|
||||
FLUTTER_VERSION: '3.38.5'
|
||||
NDK_VERSION: r28c
|
||||
UPLOAD_ARTIFACT: "${{ inputs.upload-artifact }}"
|
||||
TAG_NAME: "${{ inputs.tag-name }}"
|
||||
TARGET_NAME_AppImage: "Hiddify-Linux-x64"
|
||||
TARGET_NAME_gz: "Hiddify-Linux-x64-AppImage.tar"
|
||||
TARGET_NAME_deb: "Hiddify-Debian-x64"
|
||||
TARGET_NAME_rpm: "Hiddify-rpm-x64"
|
||||
# TARGET_NAME_rpm: "Hiddify-rpm-x64"
|
||||
TARGET_NAME_apk: "Hiddify-Android"
|
||||
TARGET_NAME_aab: "Hiddify-Android"
|
||||
#TARGET_NAME_exe: "Hiddify-Windows-x64"
|
||||
TARGET_NAME_exe: "Hiddify-Windows-Setup-x64"
|
||||
TARGET_NAME_msix: "Hiddify-Windows-x64"
|
||||
TARGET_NAME_zip: "Hiddify-Windows-Portable-x64"
|
||||
TARGET_NAME_dmg: "Hiddify-MacOS"
|
||||
TARGET_NAME_pkg: "Hiddify-MacOS-Installer"
|
||||
TARGET_NAME_ipa: "Hiddify-iOS"
|
||||
@@ -44,7 +46,7 @@ jobs:
|
||||
cache: true
|
||||
|
||||
- name: Prepare
|
||||
run: make linux-prepare
|
||||
run: make linux-amd64-prepare
|
||||
- name: Test
|
||||
run: flutter test
|
||||
|
||||
@@ -69,17 +71,32 @@ jobs:
|
||||
targets: aab
|
||||
|
||||
- platform: windows
|
||||
os: windows-2019
|
||||
os: windows-latest
|
||||
aarch: amd64
|
||||
targets: exe,msix
|
||||
targets: exe,msix,zip
|
||||
|
||||
- platform: linux
|
||||
- platform: linux-amd64
|
||||
os: ubuntu-22.04
|
||||
aarch: amd64
|
||||
targets: AppImage,deb,rpm
|
||||
targets: deb,gz
|
||||
|
||||
# - platform: linux-arm64
|
||||
# os: ubuntu-24.04-arm
|
||||
# aarch: arm64
|
||||
# targets: deb,gz
|
||||
|
||||
# - platform: linux-amd64-musl
|
||||
# os: ubuntu-22.04
|
||||
# aarch: amd64
|
||||
# targets: deb,gz
|
||||
|
||||
# - platform: linux-arm64-musl
|
||||
# os: ubuntu-24.04-arm
|
||||
# aarch: arm64
|
||||
# targets: deb,gz
|
||||
|
||||
- platform: macos
|
||||
os: macos-13
|
||||
os: macos-15
|
||||
aarch: universal
|
||||
targets: dmg,pkg
|
||||
|
||||
@@ -106,21 +123,46 @@ jobs:
|
||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
echo "${{secrets.APPLE_MOBILE_PROVISIONING_PROFILES_TARGZ_BASE64}}"|base64 --decode | tar xz -C ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
ls ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
security unlock-keychain -p "" signing_temp.keychain
|
||||
security find-identity -v -p codesigning
|
||||
# ls ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
# echo "${{secrets.NEW_APPLE_MOBILE_PROVISIONING_PROFILES_TARXZ_BASE64}}"|base64 --decode | tar xJ -C ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
# # echo "${{secrets.NEW_APPLE_MOBILE_PROVISIONING_PROFILES_TARGZ_BASE64_2}}"|base64 --decode | tar xz -C ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
|
||||
|
||||
|
||||
|
||||
- name: Setup Flutter for arm64
|
||||
if: ${{ startsWith(matrix.platform,'linux-arm64') }}
|
||||
uses: hurelhuyag/flutter-arm64-action@HEAD
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Setup Flutter
|
||||
uses: subosito/flutter-action@v2.16.0 #issue with 2.13
|
||||
if: ${{ !startsWith(matrix.platform, 'linux-arm64') }}
|
||||
uses: subosito/flutter-action@v2.21.0 #issue with 2.13
|
||||
with:
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
# flutter-version-file: pubspec.yaml
|
||||
channel: 'stable'
|
||||
cache: true
|
||||
|
||||
- name: Clean up disk space
|
||||
if: startsWith(matrix.platform,'android')
|
||||
run: |
|
||||
df -h
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
df -h
|
||||
sudo rm -rf /opt/ghc
|
||||
df -h
|
||||
sudo rm -rf /opt/hostedtoolcache/CodeQL
|
||||
df -h
|
||||
rm -rf ~/.gradle/caches
|
||||
df -h
|
||||
sudo apt-get autoremove -y
|
||||
df -h
|
||||
sudo apt-get clean
|
||||
df -h
|
||||
tree
|
||||
|
||||
- name: Setup Java
|
||||
if: startsWith(matrix.platform,'android')
|
||||
@@ -128,24 +170,43 @@ jobs:
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 17
|
||||
- name: Setup NDK
|
||||
if: startsWith(matrix.platform,'android')
|
||||
uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: ${{ env.NDK_VERSION }}
|
||||
add-to-path: true
|
||||
link-to-sdk: true
|
||||
# - name: Setup NDK
|
||||
# if: startsWith(matrix.platform,'android')
|
||||
# uses: nttld/setup-ndk@v1
|
||||
# id: setup-ndk
|
||||
# with:
|
||||
# ndk-version: ${{ env.NDK_VERSION }}
|
||||
# add-to-path: true
|
||||
# link-to-sdk: true
|
||||
|
||||
- name: Setup Gradle 8.1
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v3
|
||||
if: startsWith(matrix.platform,'android')
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
# - name: Cache Android SDK
|
||||
# uses: actions/cache@v4
|
||||
# if: startsWith(matrix.platform,'android')
|
||||
# with:
|
||||
# path: |
|
||||
# /usr/local/lib/android/sdk
|
||||
# key: android-sdk-${{ runner.os }}-${{ env.NDK_VERSION }}
|
||||
# restore-keys: |
|
||||
# android-sdk-${{ runner.os }}-
|
||||
- name: Cache Gradle
|
||||
uses: actions/cache@v4
|
||||
if: startsWith(matrix.platform,'android')
|
||||
|
||||
with:
|
||||
gradle-version: 7.5
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
gradle-${{ runner.os }}-
|
||||
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
make ${{ matrix.platform }}-install-dependencies
|
||||
|
||||
make ${{ matrix.platform }}-install-deps
|
||||
echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Setup Android Signing Properties
|
||||
if: ${{ inputs.upload-artifact && startsWith(matrix.platform,'android') }}
|
||||
@@ -176,7 +237,8 @@ jobs:
|
||||
- name: Prepare for ${{ matrix.platform }}
|
||||
run: |
|
||||
make ${{ matrix.platform }}-prepare
|
||||
tree
|
||||
|
||||
|
||||
- name: Build ${{ matrix.platform }}
|
||||
env:
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
@@ -197,10 +259,24 @@ jobs:
|
||||
|
||||
- name: Copy to out Windows
|
||||
if: matrix.platform == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
tree
|
||||
.\scripts\package_windows.ps1
|
||||
|
||||
Get-ChildItem -Path dist -Recurse | Select-Object FullName
|
||||
New-Item -ItemType Directory -Path "out" -Force | Out-Null
|
||||
$targets = "${{ matrix.targets }}".Split(',')
|
||||
foreach ($ext in $targets) {
|
||||
$ext = $ext.Trim()
|
||||
$key = "TARGET_NAME_$ext"
|
||||
$targetName = (Get-Item "env:$key").Value
|
||||
|
||||
$files = Get-ChildItem -Path dist -Recurse -Filter "*.$ext"
|
||||
|
||||
foreach ($file in $files) {
|
||||
$destination = Join-Path -Path "out" -ChildPath "$targetName.$ext"
|
||||
Move-Item -Path $file.FullName -Destination $destination -Force
|
||||
}
|
||||
}
|
||||
Get-ChildItem -Path out
|
||||
|
||||
- name: Upload Debug Symbols
|
||||
if: ${{ inputs.upload-artifact && inputs.tag-name != 'draft' }}
|
||||
@@ -246,7 +322,7 @@ jobs:
|
||||
echo "For $EXT ($KEY) filename is ${FILENAME}"
|
||||
mv dist/*/*.$EXT tmp_out/${FILENAME}.$EXT
|
||||
ls tmp_out
|
||||
chmod +x tmp_out/${FILENAME}.$EXT
|
||||
[[ "$EXT" != "gz" ]] && chmod +x tmp_out/${FILENAME}.$EXT || echo "Skipping chmod for gz"
|
||||
if [ "${{matrix.platform}}" == "linux" ];then
|
||||
cp ./.github/help/linux/* tmp_out/
|
||||
else
|
||||
@@ -310,11 +386,12 @@ jobs:
|
||||
deleteOnlyFromDrafts: false
|
||||
|
||||
- name: prepare_release_message
|
||||
continue-on-error: true
|
||||
run: |
|
||||
pip install gitchangelog pystache mustache markdown
|
||||
prelease=$(curl --silent "https://api.github.com/repos/hiddify/hiddify-next/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")')
|
||||
current="${{ github.ref_name }}"
|
||||
set +e
|
||||
sed 's|RELEASE_TAG|${{ env.TAG_NAME }}|g' ./.github/release_message.md > release.md
|
||||
pip install gitchangelog pystache mustache markdown
|
||||
prelease=$(curl --silent "https://api.github.com/repos/hiddify/hiddify-app/releases/latest" | grep -Po '"tag_name": "\K([^"]*)')
|
||||
echo -e "\n\n<details markdown=1><summary>All changes from $current to the latest commit:</summary>\n\n">>release.md
|
||||
gitchangelog "${prelease}.." >> release.md 2>&1 || echo "Error in gitchangelog"
|
||||
echo -e "\n\n</details>">>release.md
|
||||
@@ -328,6 +405,21 @@ jobs:
|
||||
tag_name: 'draft'
|
||||
body_path: './release.md'
|
||||
prerelease: true
|
||||
|
||||
- name: Create or Update Draft Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN_FOR_HIDDIFY_APP_REPO }}
|
||||
GITHUB_REPOSITORY: hiddify/hiddify-app
|
||||
with:
|
||||
files: ./out/*
|
||||
name: 'draft'
|
||||
tag_name: 'draft'
|
||||
body_path: './release.md'
|
||||
target_commitish: '530bf77839a74d4f13847ba244a20734ac7ab119'
|
||||
prerelease: true
|
||||
repository: hiddify/hiddify-app
|
||||
|
||||
upload-release:
|
||||
permissions: write-all
|
||||
if: ${{ inputs.upload-artifact && inputs.tag-name != 'draft' }}
|
||||
|
||||
@@ -11,6 +11,7 @@ on:
|
||||
- main
|
||||
- dev
|
||||
- android-fix-action-bug
|
||||
- new-design-v2
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-issue-message: 'With the release of v4.0.0 (pre-release), most reported issues have been fixed. We’re closing all current issues to start fresh.If you’re still experiencing the problem, please open a new issue and let us know.'
|
||||
days-before-stale: 2
|
||||
days-before-close: 1
|
||||
operations-per-run: 6000
|
||||
# stale-issue-message: 'With the release of v4.0.0 (pre-release), most reported issues have been fixed. We’re closing all current issues to start fresh.If you’re still experiencing the problem, please open a new issue and let us know.'
|
||||
days-before-stale: 30
|
||||
days-before-close: 10
|
||||
operations-per-run: 60
|
||||
|
||||
+11
-1
@@ -1,13 +1,17 @@
|
||||
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.sentry-native
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
.github/help
|
||||
# IntelliJ related
|
||||
@@ -41,6 +45,7 @@ migrate_working_dir/
|
||||
**/*.dylib
|
||||
**/*.xcframework
|
||||
/dist/
|
||||
/dist_docker/
|
||||
|
||||
/assets/core/*
|
||||
!/assets/core/.gitkeep
|
||||
@@ -57,4 +62,9 @@ app.*.map.json
|
||||
/android/app/release
|
||||
|
||||
|
||||
/data
|
||||
/data
|
||||
.cxx
|
||||
|
||||
# Windows Self-Signed for msix
|
||||
windows/sign.pfx
|
||||
windows/sign.cer
|
||||
+4
-3
@@ -1,3 +1,4 @@
|
||||
[submodule "libcore"]
|
||||
path = libcore
|
||||
url = https://github.com/hiddify/hiddify-next-core
|
||||
[submodule "hiddify-core"]
|
||||
path = hiddify-core
|
||||
url = ssh://git@github.com/hiddify/hiddify-core
|
||||
branch = v3
|
||||
|
||||
Vendored
+23
-5
@@ -6,9 +6,16 @@
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "./libcore",
|
||||
"program": "./libcore/cli/main.go",
|
||||
"args": ["build","-c","a.txt","-d","b.txt","--full-config"] ,
|
||||
"cwd": "./hiddify-core",
|
||||
"program": "./hiddify-core/cmd/main",
|
||||
// "args": ["build","-c","a.txt","-d","b.txt","--full-config"] ,
|
||||
// "args": ["temp"] ,
|
||||
// "args":["profile","https://raw.githubusercontent.com/hiddify/hiddify-next/refs/heads/main/test.configs/warp"],
|
||||
"args": [
|
||||
"run",
|
||||
"-c",
|
||||
"https://raw.githubusercontent.com/hiddify/hiddify-next/refs/heads/main/test.configs/warp"
|
||||
],
|
||||
"buildFlags": "-tags with_clash_api,with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server"
|
||||
},
|
||||
{
|
||||
@@ -18,7 +25,18 @@
|
||||
"flutterMode": "debug",
|
||||
"program": "lib/main.dart",
|
||||
// "args": ["-d","192.168.1.35:36463"]
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Hiddify Dev Windows Portable",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "debug",
|
||||
"program": "lib/main.dart",
|
||||
"args": [
|
||||
"-d",
|
||||
"windows",
|
||||
"--dart-define=portable=true"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Hiddify Dev Release",
|
||||
@@ -50,7 +68,7 @@
|
||||
"--app-id",
|
||||
"app.hiddify.com"
|
||||
],
|
||||
"deviceId": "designed-for-ipad",
|
||||
"deviceId": "mac-designed-for-ipad",
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+1
-5
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"dart.lineLength": 250,
|
||||
"[dart]": {
|
||||
"editor.defaultFormatter": "Dart-Code.dart-code",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnType": true,
|
||||
"editor.tabSize": 2,
|
||||
"editor.rulers": [
|
||||
250
|
||||
],
|
||||
"editor.detectIndentation": false,
|
||||
"editor.selectionHighlight": false,
|
||||
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
||||
@@ -16,6 +12,6 @@
|
||||
"editor.wordBasedSuggestions": "off"
|
||||
},
|
||||
|
||||
"html.format.wrapLineLength": 250,
|
||||
"html.format.wrapLineLength": 250
|
||||
|
||||
}
|
||||
+7
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
Every contribution to HiddifyApp is welcome, whether it is reporting a bug, submitting a fix, proposing new features, or just asking a question. To make contributing to HiddifyApp as easy as possible, you will find more details for the development flow in this documentation. [Basic tutorial on how to contribute to HiddifyApp](https://hiddify.com/app/How-to-contribute-to-this-project/)
|
||||
|
||||
Please note, we have a [Code of Conduct](https://github.com/hiddify/hiddify-next/blob/main/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
|
||||
Please note, we have a [Code of Conduct](https://github.com/hiddify/hiddify-app/blob/main/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
|
||||
|
||||
- [Feedback, Issues and Questions](#feedback-issues-and-questions)
|
||||
- [Adding new Features](#adding-new-features)
|
||||
@@ -18,8 +18,8 @@ Please note, we have a [Code of Conduct](https://github.com/hiddify/hiddify-next
|
||||
|
||||
If you encounter any issue, or you have an idea to improve, please:
|
||||
|
||||
- Search through [existing open and closed GitHub Issues](https://github.com/hiddify/hiddify-next/issues) for the answer first. If you find a relevant topic, please comment on the issue.
|
||||
- If none of the issues are relevant, please add a new [issue](https://github.com/hiddify/hiddify-next/issues/new/choose) following the templates and provide as much relevant information as possible.
|
||||
- Search through [existing open and closed GitHub Issues](https://github.com/hiddify/hiddify-app/issues) for the answer first. If you find a relevant topic, please comment on the issue.
|
||||
- If none of the issues are relevant, please add a new [issue](https://github.com/hiddify/hiddify-app/issues/new/choose) following the templates and provide as much relevant information as possible.
|
||||
|
||||
## Adding new Features
|
||||
|
||||
@@ -50,7 +50,7 @@ We recommend using [Visual Studio Code](https://docs.flutter.dev/development/too
|
||||
#### Setting up the Environment
|
||||
|
||||
We have extensive use of code generation in the form of [freezed](https://github.com/rrousselGit/freezed), [riverpod](https://github.com/rrousselGit/riverpod), etc. So it's generate these before running the code. Execute the following make commands in order:
|
||||
Assuming you have not built the `libcore` and want to use [existing releases](https://github.com/hiddify/hiddify-next-core/releases), you should run the following command (based on your target platform):
|
||||
Assuming you have not built the `hiddify-core` and want to use [existing releases](https://github.com/hiddify/hiddify-next-core/releases), you should run the following command (based on your target platform):
|
||||
|
||||
|
||||
- `make windows-prepare`
|
||||
@@ -60,8 +60,8 @@ Assuming you have not built the `libcore` and want to use [existing releases](ht
|
||||
- `make android-prepare`
|
||||
|
||||
|
||||
##### build the `libcore` from source (Optional)
|
||||
If you want to build the `libcore` from source after `make prepare`, use:
|
||||
##### build the `hiddify-core` from source (Optional)
|
||||
If you want to build the `hiddify-core` from source after `make prepare`, use:
|
||||
- `make build-windows-libs`
|
||||
- `make build-linux-libs`
|
||||
- `make build-macos-libs`
|
||||
@@ -93,7 +93,7 @@ flutter run --device-id=35492ae2
|
||||
|
||||
## Release
|
||||
|
||||
We use [flutter_distributor](https://github.com/leanflutter/flutter_distributor) for packaging. [GitHub action](https://github.com/hiddify/hiddify-next/blob/main/.github/workflows/build.yml) is triggered on every release tag and will create a new GitHub release.
|
||||
We use [flutter_distributor](https://github.com/leanflutter/flutter_distributor) for packaging. [GitHub action](https://github.com/hiddify/hiddify-app/blob/main/.github/workflows/build.yml) is triggered on every release tag and will create a new GitHub release.
|
||||
After setting up the environment, use the following make commands to build the release version:
|
||||
|
||||
- `make windows-release`
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
|
||||
# ==============================================================
|
||||
# ⚠️ USAGE: TRIGGERED BY MAKEFILE
|
||||
# This file is executed via the 'linux-release-docker' command.
|
||||
# ==============================================================
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
COPY linux_deps.list /tmp/linux_deps.list
|
||||
|
||||
RUN apt-get update && \
|
||||
DEPS=$(cat /tmp/linux_deps.list | tr -d '\r' | sed 's/#.*//g' | xargs) && \
|
||||
\
|
||||
apt-get install -y --no-install-recommends $DEPS && \
|
||||
\
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
echo "root ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
RUN wget -O /usr/local/bin/appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" && \
|
||||
chmod +x /usr/local/bin/appimagetool
|
||||
|
||||
RUN mkdir -p /root/develop && \
|
||||
git clone https://github.com/flutter/flutter.git -b stable /root/develop/flutter
|
||||
|
||||
ENV PATH="/root/develop/flutter/bin:/root/.pub-cache/bin:${PATH}"
|
||||
|
||||
RUN git config --global --add safe.directory /root/develop/flutter && \
|
||||
flutter config --no-analytics && \
|
||||
dart pub global activate fastforge
|
||||
|
||||
ENV APPIMAGE_EXTRACT_AND_RUN=1
|
||||
WORKDIR /app
|
||||
+1435
-421
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,53 @@
|
||||
# .ONESHELL:
|
||||
include dependencies.properties
|
||||
|
||||
# --- Log Colors ---
|
||||
blue := \033[1;34m
|
||||
green := \033[1;92m
|
||||
yellow := \033[1;33m
|
||||
reset := \033[0m
|
||||
# --- Log helpers ---
|
||||
# Usage: $(BLUE) <text> $(DONE)
|
||||
BLUE := echo -e "$(blue)
|
||||
GREEN := echo -e "$(green)
|
||||
YELLOW := echo -e "$(yellow)
|
||||
DONE := $(reset)"
|
||||
|
||||
MKDIR := mkdir -p
|
||||
RM := rm -rf
|
||||
SEP :=/
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
ifeq ($(IS_GITHUB_ACTIONS),)
|
||||
MKDIR := -mkdir
|
||||
# MKDIR := -mkdir
|
||||
RM := rmdir /s /q
|
||||
SEP:=\\
|
||||
# SEP:=\\
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
BINDIR=libcore$(SEP)bin
|
||||
# Define sed command based on the OS
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Windows (Assume Git Bash or similar sed is available, or standard syntax)
|
||||
SED := sed -i
|
||||
else
|
||||
ifeq ($(shell uname),Darwin) # macOS
|
||||
SED :=sed -i ''
|
||||
else # Linux
|
||||
SED :=sed -i
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
BINDIR=hiddify-core$(SEP)bin
|
||||
ANDROID_OUT=android$(SEP)app$(SEP)libs
|
||||
IOS_OUT=ios$(SEP)Frameworks
|
||||
DESKTOP_OUT=libcore$(SEP)bin
|
||||
DESKTOP_OUT=hiddify-core$(SEP)bin
|
||||
GEO_ASSETS_DIR=assets$(SEP)core
|
||||
|
||||
CORE_PRODUCT_NAME=hiddify-core
|
||||
CORE_NAME=$(CORE_PRODUCT_NAME)
|
||||
LIB_NAME=libcore
|
||||
CORE_NAME=hiddify-lib
|
||||
LIB_NAME=hiddify-core
|
||||
|
||||
ifeq ($(CHANNEL),prod)
|
||||
CORE_URL=https://github.com/hiddify/hiddify-next-core/releases/download/v$(core.version)
|
||||
@@ -59,33 +85,69 @@ prepare:
|
||||
@echo make macos-prepare
|
||||
@echo make ios-prepare
|
||||
|
||||
windows-prepare: get gen translate windows-libs
|
||||
common-prepare: get gen translate
|
||||
windows-prepare: common-prepare windows-libs
|
||||
|
||||
ios-prepare: get-geo-assets get gen translate ios-libs
|
||||
ios-prepare: common-prepare ios-libs
|
||||
cd ios; pod repo update; pod install;echo "done ios prepare"
|
||||
|
||||
macos-prepare: get-geo-assets get gen translate macos-libs
|
||||
linux-prepare: get-geo-assets get gen translate linux-libs
|
||||
macos-prepare: common-prepare macos-libs
|
||||
linux-prepare: common-prepare linux-libs
|
||||
|
||||
|
||||
linux-amd64-prepare: common-prepare linux-amd64-libs
|
||||
linux-arm64-prepare: common-prepare linux-arm64-libs
|
||||
linux-amd64-musl-prepare: common-prepare linux-amd64-musl-libs
|
||||
linux-arm64-musl-prepare: common-prepare linux-arm64-musl-libs
|
||||
|
||||
|
||||
linux-appimage-prepare:linux-prepare
|
||||
linux-rpm-prepare:linux-prepare
|
||||
linux-deb-prepare:linux-prepare
|
||||
|
||||
android-prepare: get-geo-assets get gen translate android-libs
|
||||
android-prepare:common-prepare android-libs
|
||||
android-apk-prepare:android-prepare
|
||||
android-aab-prepare:android-prepare
|
||||
|
||||
.PHONY: generate_kotlin_protos
|
||||
generate_kotlin_protos:
|
||||
# Run protoc to generate Kotlin files
|
||||
# protoc \
|
||||
# --proto_path=hiddify-core/ \
|
||||
# --java_out=./android/app/src/main/java/ \
|
||||
# --grpc-java_out=./android/app/src/main/java/ \
|
||||
# $(shell find hiddify-core/v2 hiddify-core/extension -name "*.proto")
|
||||
rsync -av --delete \
|
||||
--include='*/' \
|
||||
--include='*.proto' \
|
||||
--exclude='*' \
|
||||
hiddify-core/v2 hiddify-core/extension ./android/app/src/main/protos/
|
||||
# # Find .proto files and update package declarations
|
||||
# find "./android/app/src/main/java/com/hiddify/hiddify/protos" -type f -name "*.java" | while read -r proto_file; do \
|
||||
# if grep -q "^package " "$$proto_file"; then \
|
||||
# $(SED) 's/^package \([\w\.]*\)/package com.hiddify.hiddify.protos.\1/g' "$$proto_file"; \
|
||||
# fi \
|
||||
# done
|
||||
|
||||
generate_go_protoc:
|
||||
make -C hiddify-core -f Makefile protos
|
||||
echo "SED: $(SED)"
|
||||
generate_dart_protoc:
|
||||
mkdir -p lib/hiddifycore/generated
|
||||
protoc --dart_out=grpc:lib/hiddifycore/generated --proto_path=hiddify-core/ $(shell find hiddify-core/v2 hiddify-core/extension -name "*.proto") google/protobuf/timestamp.proto ; \
|
||||
|
||||
.PHONY: protos
|
||||
protos:
|
||||
make -C libcore -f Makefile protos
|
||||
protoc --dart_out=grpc:lib/singbox/generated --proto_path=libcore/protos libcore/protos/*.proto
|
||||
protos: generate_go_protoc generate_kotlin_protos generate_dart_protoc
|
||||
|
||||
|
||||
|
||||
|
||||
macos-install-dependencies:
|
||||
macos-install-deps:
|
||||
brew install create-dmg tree
|
||||
npm install -g appdmg
|
||||
dart pub global activate flutter_distributor
|
||||
dart pub global activate fastforge
|
||||
|
||||
ios-install-dependencies:
|
||||
ios-install-deps:
|
||||
if [ "$(flutter)" = "true" ]; then \
|
||||
curl -L -o ~/Downloads/flutter_macos_3.19.3-stable.zip https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_3.22.3-stable.zip; \
|
||||
mkdir -p ~/develop; \
|
||||
@@ -105,69 +167,306 @@ ios-install-dependencies:
|
||||
brew install create-dmg tree
|
||||
npm install -g appdmg
|
||||
|
||||
dart pub global activate flutter_distributor
|
||||
dart pub global activate fastforge
|
||||
|
||||
|
||||
android-install-dependencies:
|
||||
echo "nothing yet"
|
||||
android-apk-install-dependencies: android-install-dependencies
|
||||
android-aab-install-dependencies: android-install-dependencies
|
||||
android-install-deps:
|
||||
dart pub global activate fastforge
|
||||
android-apk-install-deps: android-install-deps
|
||||
android-aab-install-deps: android-install-deps
|
||||
# loads the package list from linux_deps.list
|
||||
LINUX_DEPS = $(shell grep -vE '^\s*#|^\s*$$' linux_deps.list)
|
||||
# reads the Flutter version from pubspec.yaml
|
||||
REQUIRED_VER = $(shell sed -n '/environment:/,/flutter:/ s/.*flutter:[[:space:]]*//p' pubspec.yaml | tr -d " '^\"")
|
||||
|
||||
linux-install-dependencies:
|
||||
if [ "$(flutter)" = "true" ]; then \
|
||||
mkdir -p ~/develop; \
|
||||
cd ~/develop; \
|
||||
wget -O flutter_linux-stable.tar.xz https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.19.4-stable.tar.xz; \
|
||||
tar xf flutter_linux-stable.tar.xz; \
|
||||
rm flutter_linux-stable.tar.xz;\
|
||||
export PATH="$$PATH:$$HOME/develop/flutter/bin"; \
|
||||
echo 'export PATH="$$PATH:$$HOME/develop/flutter/bin"' >> ~/.bashrc; \
|
||||
fi
|
||||
PATH="$$PATH":"$$HOME/.pub-cache/bin"
|
||||
echo 'export PATH="$$PATH:$$HOME/.pub-cache/bin"' >>~/.bashrc
|
||||
sudo apt-get update
|
||||
sudo apt install -y clang ninja-build pkg-config cmake libgtk-3-dev locate ninja-build pkg-config libglib2.0-dev libgio2.0-cil-dev libayatana-appindicator3-dev fuse rpm patchelf file appstream
|
||||
|
||||
|
||||
linux-amd64-install-deps:linux-install-deps
|
||||
linux-amd64-musl-install-deps:linux-install-deps
|
||||
linux-arm64-install-deps:linux-install-deps
|
||||
linux-arm64-musl-install-deps:linux-install-deps
|
||||
|
||||
linux-install-deps:
|
||||
@$(BLUE)Installing Debian/Ubuntu dependencies...$(DONE)
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y $(LINUX_DEPS)
|
||||
# loading fuce kernel module
|
||||
@$(BLUE)Loading fuce kernel module$(DONE)
|
||||
sudo modprobe fuse
|
||||
wget -O appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
chmod +x appimagetool
|
||||
sudo mv appimagetool /usr/local/bin/
|
||||
# tools for appimage
|
||||
@$(BLUE)Installing appimagetool$(DONE)
|
||||
if [ "$$(uname -m)" = "aarch64" ]; then \
|
||||
wget -O /tmp/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-aarch64.AppImage"; \
|
||||
else \
|
||||
wget -O /tmp/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"; \
|
||||
fi
|
||||
chmod +x /tmp/appimagetool
|
||||
sudo mv /tmp/appimagetool /usr/local/bin/
|
||||
# cloning flutter sdk
|
||||
@$(BLUE)Cloning Flutter SDK$(DONE); \
|
||||
mkdir -p ~/develop; \
|
||||
cd ~/develop; \
|
||||
\
|
||||
if [ ! -d "flutter/.git" ]; then \
|
||||
$(BLUE)Flutter not found. cloning stable channel$(DONE); \
|
||||
rm -rf flutter; \
|
||||
git clone https://github.com/flutter/flutter.git -b stable flutter; \
|
||||
fi; \
|
||||
\
|
||||
git config --global --add safe.directory $$HOME/develop/flutter; \
|
||||
\
|
||||
export PATH="$$HOME/develop/flutter/bin:$$PATH"; \
|
||||
if ! grep -q 'flutter/bin' ~/.bashrc; then \
|
||||
echo 'export PATH="$$HOME/develop/flutter/bin:$$PATH"' >> ~/.bashrc; \
|
||||
fi
|
||||
# syncing flutter version
|
||||
$(MAKE) linux-flutter-sync
|
||||
# installing fastforge https://pub.dev/packages/fastforge
|
||||
@$(BLUE)Installing fastforge$(DONE); \
|
||||
export PATH="$$HOME/develop/flutter/bin:$$HOME/.pub-cache/bin:$$PATH"; \
|
||||
if ! grep -q '.pub-cache/bin' ~/.bashrc; then \
|
||||
echo 'export PATH="$$HOME/.pub-cache/bin:$$PATH"' >> ~/.bashrc; \
|
||||
fi; \
|
||||
dart pub global activate fastforge; \
|
||||
dart pub global activate protoc_plugin; \
|
||||
echo ""; \
|
||||
echo "============================================================"; \
|
||||
echo "NOTE: After first setup, use the following command to update the PATH"; \
|
||||
echo "source ~/.bashrc"; \
|
||||
echo "============================================================"
|
||||
|
||||
dart pub global activate --source git https://github.com/hiddify/flutter_distributor --git-path packages/flutter_distributor
|
||||
|
||||
windows-install-dependencies:
|
||||
dart pub global activate flutter_distributor
|
||||
# syncing 'flutter sdk' version with pubspec.yaml flutter version
|
||||
linux-flutter-sync:
|
||||
@$(BLUE)Syncing Flutter version with pubspec.yaml flutter version$(DONE); \
|
||||
export PATH="$$HOME/develop/flutter/bin:$$PATH"; \
|
||||
$(BLUE)Downloading Flutter SDK components...$(DONE); \
|
||||
flutter --version > /dev/null; \
|
||||
\
|
||||
$(BLUE)Checking Flutter version...$(DONE); \
|
||||
CURRENT_VER=$$(flutter --version | head -n 1 | awk '{print $$2}'); \
|
||||
$(BLUE)Target: $(REQUIRED_VER) | Current: $$CURRENT_VER$(DONE); \
|
||||
\
|
||||
if [ "$$CURRENT_VER" != "$(REQUIRED_VER)" ]; then \
|
||||
$(BLUE)Version mismatch! switching to $(REQUIRED_VER)...$(DONE); \
|
||||
cd ~/develop/flutter; \
|
||||
git fetch --tags; \
|
||||
git checkout $(REQUIRED_VER); \
|
||||
$(BLUE)Switched to $(REQUIRED_VER)$(DONE); \
|
||||
flutter doctor; \
|
||||
else \
|
||||
$(GREEN)Flutter SDK is ready.$(DONE); \
|
||||
fi
|
||||
|
||||
windows-install-deps:
|
||||
dart pub global activate fastforge
|
||||
# choco install innosetup -y
|
||||
|
||||
gen_translations: #generating missing translations using google translate
|
||||
cd .github && bash sync_translate.sh
|
||||
make translate
|
||||
|
||||
android-release: android-apk-release
|
||||
android-release: android-apk-release android-aab-release
|
||||
|
||||
android-apk-release:
|
||||
echo flutter build apk --target $(TARGET) $(BUILD_ARGS) --target-platform android-arm,android-arm64,android-x64 --split-per-abi --verbose
|
||||
flutter build apk --target $(TARGET) $(BUILD_ARGS) --target-platform android-arm,android-arm64,android-x64 --verbose
|
||||
fastforge package \
|
||||
--platform android \
|
||||
--targets apk \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-target-platform=android-arm,android-arm64,android-x64 \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN)
|
||||
ls -R build/app/outputs
|
||||
|
||||
android-aab-release:
|
||||
flutter build appbundle --target $(TARGET) $(BUILD_ARGS) --dart-define release=google-play
|
||||
ls -R build/app/outputs
|
||||
fastforge package \
|
||||
--platform android \
|
||||
--targets aab \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN) \
|
||||
--build-dart-define=release=google-play
|
||||
|
||||
windows-release:
|
||||
flutter_distributor package --flutter-build-args=verbose --platform windows --targets exe,msix $(DISTRIBUTOR_ARGS)
|
||||
windows-release: windows-zip-release windows-exe-release windows-msix-release
|
||||
|
||||
linux-release:
|
||||
flutter_distributor package --flutter-build-args=verbose --platform linux --targets deb,rpm,appimage $(DISTRIBUTOR_ARGS)
|
||||
windows-zip-release:
|
||||
fastforge package \
|
||||
--platform windows \
|
||||
--targets zip \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN) \
|
||||
--build-dart-define=portable=true
|
||||
@FULL_PATH=$$(ls dist/*/*.zip | head -n 1); \
|
||||
ZIP_DIR=$$(dirname "$$FULL_PATH"); \
|
||||
ZIP_FILE=$$(basename "$$FULL_PATH"); \
|
||||
FILE_NAME=$${ZIP_FILE%.*}; \
|
||||
$(YELLOW)Post-processing Windows portable$(DONE); \
|
||||
cd "$$ZIP_DIR"; \
|
||||
$(BLUE)Extracting and Repacking...$(DONE); \
|
||||
mkdir -p Hiddify; \
|
||||
unzip -q "$$ZIP_FILE" -d Hiddify/; \
|
||||
rm "$$ZIP_FILE"; \
|
||||
tar -a -cf "$$FILE_NAME.zip" Hiddify; \
|
||||
rm -rf Hiddify; \
|
||||
$(GREEN)Successful$(DONE)
|
||||
|
||||
windows-exe-release:
|
||||
fastforge package \
|
||||
--platform windows \
|
||||
--targets exe \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN)
|
||||
|
||||
windows-msix-release:
|
||||
fastforge package \
|
||||
--platform windows \
|
||||
--targets msix \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN)
|
||||
|
||||
linux-release: linux-deb-release linux-appimage-release
|
||||
|
||||
linux-amd64-release: linux-release
|
||||
linux-arm64-release: linux-release
|
||||
linux-amd64-musl-release: linux-release
|
||||
linux-arm64-musl-release: linux-release
|
||||
|
||||
|
||||
linux-deb-release:
|
||||
fastforge package \
|
||||
--platform linux \
|
||||
--targets deb \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN)
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# REFERENCE: MANUAL LIBRARY BUNDLING (INJECTION)
|
||||
# ==============================================================================
|
||||
# Use this method only if you need to manually force specific shared libraries
|
||||
# (e.g., libcurl.so.4) into the AppImage bundle.
|
||||
#
|
||||
# IMPLEMENTATION STEPS:
|
||||
#
|
||||
# 1. PRE-BUILD SCRIPT (Add to Makefile before build command):
|
||||
# Create a temporary directory and copy the target library there.
|
||||
# ---------------------------------------------------------------------------
|
||||
# mkdir -p linux/bundled_libs
|
||||
# cp /usr/lib/x86_64-linux-gnu/libcurl.so.4 linux/bundled_libs/
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# 2. CMAKE CONFIGURATION (Add to linux/CMakeLists.txt):
|
||||
# Instruct CMake to include the copied file in the final bundle.
|
||||
# ---------------------------------------------------------------------------
|
||||
# install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/bundled_libs/libcurl.so.4"
|
||||
# DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
# COMPONENT Runtime)
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# ! WARNING !
|
||||
# This approach is generally DISCOURAGED. Manually bundling libraries can lead to
|
||||
# "Dependency Hell," where bundled libs conflict with system libraries or have
|
||||
# their own unresolved dependencies. It increases maintenance cost and may cause
|
||||
# runtime instability. Use only for specific edge cases where standard linking fails.
|
||||
# ==============================================================================
|
||||
linux-appimage-release:
|
||||
fastforge package \
|
||||
--platform linux \
|
||||
--targets appimage \
|
||||
--skip-clean \
|
||||
--build-target=$(TARGET) \
|
||||
--build-dart-define=sentry_dsn=$(SENTRY_DSN)
|
||||
@$(YELLOW)Post-processing AppImage$(DONE); \
|
||||
$(BLUE)Extracting AppImage$(DONE); \
|
||||
cd dist/* && ./*.AppImage --appimage-extract > /dev/null; \
|
||||
$(BLUE)Replacing AppRun$(DONE); \
|
||||
cp ../../linux/packaging/appimage/AppRun squashfs-root/AppRun; \
|
||||
$(BLUE)Granting permissions$(DONE); \
|
||||
chmod +x squashfs-root/AppRun; \
|
||||
$(BLUE)Adding StartupWMClass to hiddify.desktop$(DONE); \
|
||||
sed -i '/^\[Desktop Entry\]/a StartupWMClass=app.hiddify.com' "squashfs-root/hiddify.desktop"; \
|
||||
$(BLUE)Removing old AppImage$(DONE); \
|
||||
rm *.AppImage; \
|
||||
$(BLUE)Rebuilding AppImage$(DONE); \
|
||||
ARCH=x86_64 appimagetool --no-appstream squashfs-root Hiddify.AppImage > /dev/null; \
|
||||
$(BLUE)Cleaning up squashfs$(DONE); \
|
||||
rm -rf squashfs-root; \
|
||||
$(YELLOW)Creating Portable Package$(DONE); \
|
||||
PKG_DIR_NAME="hiddify-linux-appimage"; \
|
||||
$(BLUE)Creating dir: $$PKG_DIR_NAME$(DONE); \
|
||||
mkdir -p "$$PKG_DIR_NAME"; \
|
||||
$(BLUE)Moving and Renaming to Hiddify.AppImage$(DONE); \
|
||||
mv "Hiddify.AppImage" "$$PKG_DIR_NAME/Hiddify.AppImage"; \
|
||||
$(BLUE)Creating Portable Home directory$(DONE); \
|
||||
mkdir -p "$$PKG_DIR_NAME/Hiddify.AppImage.home"; \
|
||||
$(BLUE)Compressing to .tar.gz$(DONE); \
|
||||
tar -czf "$$PKG_DIR_NAME.tar.gz" -C . "$$PKG_DIR_NAME"; \
|
||||
$(BLUE)Removing intermediate directory$(DONE); \
|
||||
rm -rf "$$PKG_DIR_NAME"; \
|
||||
$(GREEN)Successful$(DONE)
|
||||
|
||||
DOCKER_IMAGE_NAME := hiddify-linux-builder
|
||||
DOCKER_FLUTTER_VOL := hiddify-flutter-sdk-cache
|
||||
DOCKER_PUB_VOL := hiddify-pub-cache
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
FIX_OWNERSHIP := echo \"Windows detected: Skipping chown\"
|
||||
else
|
||||
FIX_OWNERSHIP := chown -R $(shell id -u):$(shell id -g) /host/dist_docker
|
||||
endif
|
||||
|
||||
DOCKER_CMD := \
|
||||
set -e; \
|
||||
echo '** Copying source code to container...'; \
|
||||
mkdir -p /app; \
|
||||
cp -r /host/. /app/; \
|
||||
cd /app; \
|
||||
make linux-flutter-sync; \
|
||||
make linux-prepare; \
|
||||
echo '** Building Release (linux-release)...'; \
|
||||
make linux-release; \
|
||||
echo '** Copying artifacts to host...'; \
|
||||
rm -rf /host/dist_docker; \
|
||||
if [ -d \"dist\" ]; then \
|
||||
cp -r dist /host/dist_docker; \
|
||||
echo '** Fixing permissions for dist_docker...'; \
|
||||
$(FIX_OWNERSHIP); \
|
||||
else \
|
||||
echo 'Error: dist folder not found!'; \
|
||||
exit 1; \
|
||||
fi;
|
||||
|
||||
linux-docker-release:
|
||||
@$(BLUE)Cleaning main project to reduce context size$(DONE)
|
||||
flutter clean
|
||||
|
||||
@$(BLUE)Building docker image (Cached)$(DONE)
|
||||
docker build -t $(DOCKER_IMAGE_NAME) -f Dockerfile .
|
||||
|
||||
@$(BLUE)Ensuring cache volumes exist$(DONE)
|
||||
docker volume create $(DOCKER_FLUTTER_VOL) || true
|
||||
docker volume create $(DOCKER_PUB_VOL) || true
|
||||
|
||||
@$(YELLOW)Running build inside container$(DONE)
|
||||
@docker run --rm \
|
||||
-v "$(CURDIR)://host" \
|
||||
-v $(DOCKER_FLUTTER_VOL)://root/develop/flutter \
|
||||
-v $(DOCKER_PUB_VOL)://root/.pub-cache \
|
||||
-e APPIMAGE_EXTRACT_AND_RUN=1 \
|
||||
$(DOCKER_IMAGE_NAME) \
|
||||
//bin/bash -c "$(DOCKER_CMD)"
|
||||
|
||||
@$(GREEN)Successful. Output is in 'dist_docker' folder.$(DONE)
|
||||
|
||||
macos-release:
|
||||
flutter_distributor package --platform macos --targets dmg,pkg $(DISTRIBUTOR_ARGS)
|
||||
fastforge package --platform macos --targets dmg,pkg $(DISTRIBUTOR_ARGS)
|
||||
|
||||
ios-release: #not tested
|
||||
flutter_distributor package --platform ios --targets ipa --build-export-options-plist ios/exportOptions.plist $(DISTRIBUTOR_ARGS)
|
||||
fastforge package --platform ios --targets ipa --build-export-options-plist ios/exportOptions.plist $(DISTRIBUTOR_ARGS)
|
||||
|
||||
android-libs:
|
||||
@$(MKDIR) $(ANDROID_OUT) || echo Folder already exists. Skipping...
|
||||
$(MKDIR) $(ANDROID_OUT) || echo Folder already exists. Skipping...
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-android.tar.gz | tar xz -C $(ANDROID_OUT)/
|
||||
|
||||
android-apk-libs: android-libs
|
||||
@@ -175,22 +474,34 @@ android-aab-libs: android-libs
|
||||
|
||||
windows-libs:
|
||||
$(MKDIR) $(DESKTOP_OUT) || echo Folder already exists. Skipping...
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-windows-amd64.tar.gz | tar xz -C $(DESKTOP_OUT)$(SEP)
|
||||
ls $(DESKTOP_OUT) || dir $(DESKTOP_OUT)$(SEP)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-windows-amd64.tar.gz | tar xz -C $(DESKTOP_OUT)/
|
||||
ls $(DESKTOP_OUT) || dir $(DESKTOP_OUT)/
|
||||
|
||||
|
||||
linux-libs:
|
||||
linux-amd64-libs:
|
||||
mkdir -p $(DESKTOP_OUT)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-linux-amd64.tar.gz | tar xz -C $(DESKTOP_OUT)/
|
||||
|
||||
linux-arm64-libs:
|
||||
mkdir -p $(DESKTOP_OUT)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-linux-arm64.tar.gz | tar xz -C $(DESKTOP_OUT)/
|
||||
|
||||
linux-amd64-musl-libs:
|
||||
mkdir -p $(DESKTOP_OUT)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-linux-amd64-musl.tar.gz | tar xz -C $(DESKTOP_OUT)/
|
||||
|
||||
linux-arm64-musl-libs:
|
||||
mkdir -p $(DESKTOP_OUT)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-linux-arm64-musl.tar.gz | tar xz -C $(DESKTOP_OUT)/
|
||||
|
||||
|
||||
macos-libs:
|
||||
mkdir -p $(DESKTOP_OUT)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-macos-universal.tar.gz | tar xz -C $(DESKTOP_OUT)
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-macos.tar.gz | tar xz -C $(DESKTOP_OUT)
|
||||
|
||||
ios-libs: #not tested
|
||||
mkdir -p $(IOS_OUT)
|
||||
rm -rf $(IOS_OUT)/Libcore.xcframework
|
||||
rm -rf $(IOS_OUT)/HiddifyCore.xcframework
|
||||
curl -L $(CORE_URL)/$(CORE_NAME)-ios.tar.gz | tar xz -C "$(IOS_OUT)"
|
||||
|
||||
get-geo-assets:
|
||||
@@ -199,25 +510,25 @@ get-geo-assets:
|
||||
# curl -L https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db -o $(GEO_ASSETS_DIR)/geosite.db
|
||||
|
||||
build-headers:
|
||||
make -C libcore -f Makefile headers && mv $(BINDIR)/$(CORE_NAME)-headers.h $(BINDIR)/libcore.h
|
||||
make -C hiddify-core -f Makefile headers && mv $(BINDIR)/$(CORE_NAME)-headers.h $(BINDIR)/hiddify-core.h
|
||||
|
||||
build-android-libs:
|
||||
make -C libcore -f Makefile android
|
||||
make -C hiddify-core -f Makefile android
|
||||
mv $(BINDIR)/$(LIB_NAME).aar $(ANDROID_OUT)/
|
||||
|
||||
build-windows-libs:
|
||||
make -C libcore -f Makefile windows-amd64
|
||||
make -C hiddify-core -f Makefile windows-amd64
|
||||
|
||||
build-linux-libs:
|
||||
make -C libcore -f Makefile linux-amd64
|
||||
make -C hiddify-core -f Makefile linux-amd64
|
||||
|
||||
build-macos-libs:
|
||||
make -C libcore -f Makefile macos-universal
|
||||
make -C hiddify-core -f Makefile macos
|
||||
|
||||
build-ios-libs:
|
||||
rf -rf $(IOS_OUT)/Libcore.xcframework
|
||||
make -C libcore -f Makefile ios
|
||||
mv $(BINDIR)/Libcore.xcframework $(IOS_OUT)/Libcore.xcframework
|
||||
rm -rf $(IOS_OUT)/HiddifyCore.xcframework
|
||||
make -C hiddify-core -f Makefile ios
|
||||
mv $(BINDIR)/HiddifyCore.xcframework $(IOS_OUT)/HiddifyCore.xcframework
|
||||
|
||||
release: # Create a new tag for release.
|
||||
@CORE_VERSION=$(core.version) bash -c ".github/change_version.sh "
|
||||
@@ -229,5 +540,4 @@ ios-temp-prepare:
|
||||
flutter build ios-framework
|
||||
cd ios
|
||||
pod install
|
||||
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
<div align="center">
|
||||
|
||||
<!--
|
||||

|
||||

|
||||
-->
|
||||
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/)
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/)
|
||||
[](https://www.youtube.com/@hiddify)[](https://telegram.dog/hiddify)[](https://telegram.dog/hiddify_board/5)
|
||||
|
||||
</div>
|
||||
@@ -27,7 +27,7 @@
|
||||
<p dir="ltr" style="font-size: 16px">A multi-platform proxy client based on <a href="https://github.com/SagerNet/sing-box">Sing-box</a> universal proxy tool-chain. Hiddify offers a wide range of capabilities, like automatic node selection, TUN mode, remote profiles etc. Hiddify is ad-free and open-source. With support for a wide range of protocols, it provides a secure and private way for accessing free internet.</p>
|
||||
|
||||
<div align=center>
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-next/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-app/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
|
||||
</div>
|
||||
|
||||
@@ -76,24 +76,24 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH etc.
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -107,9 +107,9 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH etc.
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -124,7 +124,7 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH etc.
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://hiddify.com/app/)
|
||||
[](https://hiddify.com/app/)
|
||||
|
||||
|
||||
</div>
|
||||
@@ -185,7 +185,7 @@ Hiddify is a community driven project. If you're interested in contributing, ple
|
||||
</p>
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/hiddify/hiddify-next/graphs/contributors">
|
||||
<a href="https://github.com/hiddify/hiddify-app/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hiddify/hiddify-next" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
+16
-16
@@ -12,10 +12,10 @@
|
||||
<div align="center">
|
||||
|
||||
<!--
|
||||

|
||||

|
||||
-->
|
||||
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/)
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/)
|
||||
[](https://www.youtube.com/@hiddify)[](https://telegram.dog/hiddify)[](https://telegram.dog/hiddify_board/5)
|
||||
|
||||
</div>
|
||||
@@ -27,7 +27,7 @@
|
||||
<p dir="ltr" style="font-size: 16px">Um cliente de proxy multiplataforma baseado na ferramenta de proxy universal <a href="https://github.com/SagerNet/sing-box">Sing-box</a>. O Hiddify oferece uma ampla gama de recursos, como seleção automática de nós, modo TUN, perfis remotos, etc. O Hiddify é livre de anúncios e de código aberto. Com suporte para uma ampla variedade de protocolos, ele oferece uma maneira segura e privada de acessar a internet gratuitamente.</p>
|
||||
|
||||
<div align=center>
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-next/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-app/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
|
||||
</div>
|
||||
|
||||
@@ -79,23 +79,23 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td><td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -109,9 +109,9 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -126,7 +126,7 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://hiddify.com/app/)
|
||||
[](https://hiddify.com/app/)
|
||||
|
||||
|
||||
</div>
|
||||
@@ -186,7 +186,7 @@ Agradecemos a todas as pessoas que estão participando deste projeto. Algumas pe
|
||||
</p>
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/hiddify/hiddify-next/graphs/contributors">
|
||||
<a href="https://github.com/hiddify/hiddify-app/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hiddify/hiddify-next" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
+15
-15
@@ -9,7 +9,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/)
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/)
|
||||
[](https://www.youtube.com/@hiddify)[](https://telegram.dog/hiddify)[](https://telegram.dog/hiddify_board/5)
|
||||
|
||||
</div>
|
||||
@@ -22,7 +22,7 @@
|
||||
<p dir="ltr" style="font-size: 16px">一款基于 <a href="https://github.com/SagerNet/sing-box">Sing-box</a> 通用代理工具的跨平台代理客户端。Hiddify 提供了较全面的代理功能,例如自动选择节点、TUN 模式、使用远程配置文件等。Hiddify 无广告,并且代码开源。它为大家自由访问互联网提供了一个支持多种协议的、安全且私密的工具。</p>
|
||||
|
||||
<div align=center>
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-next/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-app/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
</div>
|
||||
|
||||
|
||||
@@ -73,24 +73,24 @@
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -104,9 +104,9 @@
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
<div align=center>
|
||||
|
||||
[](https://hiddify.com/app/)
|
||||
[](https://hiddify.com/app/)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -182,7 +182,7 @@ Hiddify 是一个由社区驱动的项目。如果您有兴趣为本项目做出
|
||||
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/hiddify/hiddify-next/graphs/contributors">
|
||||
<a href="https://github.com/hiddify/hiddify-app/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hiddify/hiddify-next" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
+16
-16
@@ -10,7 +10,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/)
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/)
|
||||
[](https://www.youtube.com/@hiddify)[](https://telegram.dog/hiddify)[](https://telegram.dog/hiddify_board/5)
|
||||
|
||||
</div>
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
|
||||
<div align=center>
|
||||
<img width=90% alt="Farsi Demo" src="https://github.com/hiddify/hiddify-next/assets/125398461/cfdc4b0e-0a26-42f5-90ef-1d8587d2afd2">
|
||||
<img width=90% alt="Farsi Demo" src="https://github.com/hiddify/hiddify-app/assets/125398461/cfdc4b0e-0a26-42f5-90ef-1d8587d2afd2">
|
||||
|
||||
</div>
|
||||
|
||||
@@ -82,23 +82,23 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>اندروید</td><td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ویندوز</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -112,9 +112,9 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
<tr>
|
||||
<td>لینوکس</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -125,7 +125,7 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://hiddify.com/fa/app/)
|
||||
[](https://hiddify.com/fa/app/)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -134,7 +134,7 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
## 🌎 ترجمهها
|
||||
<div align=center>
|
||||
|
||||

|
||||

|
||||
</div>
|
||||
|
||||
با ویرایش دستی فایلهای JSON در assets/translations/ یا با استفاده از [ویرایشگر آنلاین Inlang](https://inlang.com/editor/github.com/hiddify/hiddify-next)، زبانهای موجود را بهبود بدهید و یا زبانهای جدید اضافه کنید.
|
||||
@@ -185,7 +185,7 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
|
||||
</p>
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/hiddify/hiddify-next/graphs/contributors">
|
||||
<a href="https://github.com/hiddify/hiddify-app/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hiddify/hiddify-next" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
+16
-16
@@ -12,10 +12,10 @@
|
||||
<div align="center">
|
||||
|
||||
<!--
|
||||

|
||||

|
||||
-->
|
||||
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/)
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/)
|
||||
[](https://www.youtube.com/@hiddify)[](https://telegram.dog/hiddify)[](https://telegram.dog/hiddify_board/5)
|
||||
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<p dir="ltr" style="font-size: 16px"><a href="https://github.com/SagerNet/sing-box">Sing-box</a> ユニバーサルプロキシツールチェーンに基づくマルチプラットフォームプロキシクライアントです。Hiddify は、自動ノード選択、TUN モード、リモートプロファイルなど、幅広い機能を提供します。Hiddify は無料でオープンソースです。幅広いプロトコルをサポートし、無料インターネットにアクセスするための安全でプライベートな方法を提供します。</p>
|
||||
|
||||
<div align=center>
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-next/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-app/assets/125398461/ffe5346d-3404-470f-b5e0-4364e23743d2">
|
||||
|
||||
</div>
|
||||
|
||||
@@ -80,24 +80,24 @@ Vless、Vmess、Reality、TUIC、Hysteria、Wireguard、SSH など。
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -111,9 +111,9 @@ Vless、Vmess、Reality、TUIC、Hysteria、Wireguard、SSH など。
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -128,7 +128,7 @@ Vless、Vmess、Reality、TUIC、Hysteria、Wireguard、SSH など。
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://hiddify.com/app/)
|
||||
[](https://hiddify.com/app/)
|
||||
|
||||
|
||||
</div>
|
||||
@@ -188,7 +188,7 @@ Hiddify はコミュニティドリブンのプロジェクトです。コント
|
||||
</p>
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/hiddify/hiddify-next/graphs/contributors">
|
||||
<a href="https://github.com/hiddify/hiddify-app/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hiddify/hiddify-next" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
+15
-15
@@ -11,7 +11,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/releases/)[](https://github.com/hiddify/hiddify-next/)
|
||||
[](https://play.google.com/store/apps/details?id=app.hiddify.com) [](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/releases/)[](https://github.com/hiddify/hiddify-app/)
|
||||
[](https://www.youtube.com/@hiddify)[](https://telegram.dog/hiddify)[](https://telegram.dog/hiddify_board/5)
|
||||
|
||||
</div>
|
||||
@@ -20,7 +20,7 @@
|
||||
Кроссплатформенный прокси-клиент на основе ядра [Sing-box](https://github.com/SagerNet/sing-box). Hiddify предлагает широкий спектр возможностей, таких как автоматический выбор узла, режим TUN, удалённые конфигурации (подписки). Приложение с открытым исходным кодом, без рекламы. Поддерживая широкий спектр протоколов, мы обеспечиваем безопасный и конфиденциальный доступ к свободному интернету.
|
||||
|
||||
<div align=center>
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-next/assets/125398461/1b592bf9-b19f-4592-b02d-a3fa6216d257">
|
||||
<img width=90% alt="English Demo" src="https://github.com/hiddify/hiddify-app/assets/125398461/1b592bf9-b19f-4592-b02d-a3fa6216d257">
|
||||
</div>
|
||||
|
||||
## 🚀 Основные особенности
|
||||
@@ -68,24 +68,24 @@
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-iOS.ipa"><img src="https://img.shields.io/badge/IPA-Universal-c0c0c0.svg?logo=ios"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-universal.apk"><img src="https://img.shields.io/badge/APK-Universal-044d29.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm64.apk"><img src="https://img.shields.io/badge/APK-ARMv8-168039.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-arm7.apk"><img src="https://img.shields.io/badge/APK-ARMv7-45bf55.svg?logo=android"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Android-x86_64.apk"><img src="https://img.shields.io/badge/APK-x64-96ed89.svg?logo=android"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.Msix"><img src="https://img.shields.io/badge/OfficialSetup-x64-0078d7.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Setup-x64.exe"><img src="https://img.shields.io/badge/Setup-x64-2d7d9a.svg?logo=windows"></a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Windows-Portable-x64.zip"><img src="https://img.shields.io/badge/Portable-x64-67b7d1.svg?logo=windows"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -99,9 +99,9 @@
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Linux-x64.AppImage"><img src="https://img.shields.io/badge/AppImage-x64-f84e29.svg?logo=linux"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-Debian-x64.deb"><img src="https://img.shields.io/badge/DebPackage-x64-FF9966.svg?logo=debian"> </a><br>
|
||||
<a href="https://github.com/hiddify/hiddify-app/releases/latest/download/Hiddify-rpm-x64.rpm"><img src="https://img.shields.io/badge/RpmPackage-x64-F1B42F.svg?logo=redhat"> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
<div align="center" width="100%">
|
||||
|
||||
[](https://hiddify.com/app/)
|
||||
[](https://hiddify.com/app/)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -173,7 +173,7 @@ Hiddify - это проект, развиваемый сообществом. Е
|
||||
</p>
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/hiddify/hiddify-next/graphs/contributors">
|
||||
<a href="https://github.com/hiddify/hiddify-app/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hiddify/hiddify-next" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -4,12 +4,15 @@ analyzer:
|
||||
plugins:
|
||||
- custom_lint
|
||||
exclude:
|
||||
- "libcore/**"
|
||||
- "hiddify-core/**"
|
||||
- "**.g.dart"
|
||||
- "lib/gen/**"
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
|
||||
formatter:
|
||||
page_width: 120
|
||||
|
||||
linter:
|
||||
rules:
|
||||
sort_pub_dependencies: false
|
||||
|
||||
+3
-1
@@ -13,4 +13,6 @@ key.properties
|
||||
**/*.jks
|
||||
|
||||
/app/libs/*
|
||||
!/app/libs/.gitkeep
|
||||
!/app/libs/.gitkeep
|
||||
|
||||
/app/.cxx
|
||||
+43
-13
@@ -1,9 +1,26 @@
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "org.jetbrains.kotlin.android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
id "com.google.protobuf" version "0.9.4"
|
||||
id "com.squareup.wire" version "5.3.1"
|
||||
}
|
||||
|
||||
wire {
|
||||
kotlin {
|
||||
android = true
|
||||
}
|
||||
protoPath {
|
||||
srcDir 'src/main/protos'
|
||||
}
|
||||
sourcePath {
|
||||
srcDir 'src/main/protos/'
|
||||
include '**'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
@@ -37,8 +54,8 @@ def flutterVersionName = localProperties.getProperty('flutter.versionName') ?: '
|
||||
android {
|
||||
namespace 'com.hiddify.hiddify'
|
||||
testNamespace "test.com.hiddify.hiddify"
|
||||
compileSdkVersion 34
|
||||
ndkVersion "26.1.10909125"
|
||||
compileSdkVersion 36
|
||||
ndkVersion "28.2.13676358"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
@@ -55,8 +72,8 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "app.hiddify.com"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 34
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdkVersion 36
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
@@ -118,8 +135,21 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
|
||||
}
|
||||
|
||||
implementation 'com.google.code.gson:gson:2.11.0'
|
||||
implementation 'androidx.core:core-ktx:1.16.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.7'
|
||||
implementation "androidx.compose.ui:ui:1.7.8"
|
||||
implementation("com.squareup.wire:wire-grpc-client:5.3.1")
|
||||
|
||||
implementation 'io.grpc:grpc-okhttp:1.64.0'
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.64.0'
|
||||
implementation 'io.grpc:grpc-stub:1.64.0'
|
||||
// protoPath(project(':hiddify_api'))
|
||||
// implementation project(':hiddify_api')
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +30,13 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Hiddify"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
tools:targetApi="31">
|
||||
|
||||
<meta-data
|
||||
android:name="flutter_deeplinking_enabled"
|
||||
android:value="true" />
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
@@ -69,15 +74,18 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="sing-box" />
|
||||
<data android:host="import-remote-profile" />
|
||||
<data android:scheme="hiddify" />
|
||||
<data android:scheme="v2ray" />
|
||||
<data android:scheme="v2rayn" />
|
||||
<data android:scheme="v2rayng" />
|
||||
<data android:scheme="clash" />
|
||||
<data android:host="install-config" />
|
||||
<data android:scheme="clashmeta" />
|
||||
<data android:scheme="hiddify" />
|
||||
<data android:host="install-sub" />
|
||||
<data android:scheme="hiddify" />
|
||||
<data android:host="import" />
|
||||
<data android:scheme="sing-box" />
|
||||
|
||||
<!-- <data android:host="import" />
|
||||
<data android:host="install-config" />
|
||||
<data android:host="import-remote-profile" />
|
||||
<data android:host="install-sub" /> -->
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
@@ -122,6 +130,8 @@
|
||||
<property
|
||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="vpn" />
|
||||
<meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
|
||||
android:value="true"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".bg.ProxyService"
|
||||
|
||||
@@ -2,59 +2,59 @@ package com.hiddify.hiddify
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.hiddify.hiddify.utils.CommandClient
|
||||
//import com.hiddify.hiddify.utils.CommandClient
|
||||
import com.hiddify.hiddify.utils.ParsedOutboundGroup
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import com.hiddify.core.libbox.OutboundGroup
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
|
||||
class ActiveGroupsChannel(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
CommandClient.Handler {
|
||||
companion object {
|
||||
const val TAG = "A/ActiveGroupsChannel"
|
||||
const val CHANNEL = "com.hiddify.app/active-groups"
|
||||
val gson = Gson()
|
||||
}
|
||||
|
||||
private val client =
|
||||
CommandClient(scope, CommandClient.ConnectionType.GroupOnly, this)
|
||||
|
||||
private var channel: EventChannel? = null
|
||||
private var event: EventChannel.EventSink? = null
|
||||
|
||||
override fun updateGroups(groups: List<OutboundGroup>) {
|
||||
MainActivity.instance.runOnUiThread {
|
||||
val parsedGroups = groups.map { group -> ParsedOutboundGroup.fromOutbound(group) }
|
||||
event?.success(gson.toJson(parsedGroups))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = EventChannel(
|
||||
flutterPluginBinding.binaryMessenger,
|
||||
CHANNEL
|
||||
)
|
||||
|
||||
channel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
event = events
|
||||
Log.d(TAG, "connecting active groups command client")
|
||||
client.connect()
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
event = null
|
||||
Log.d(TAG, "disconnecting active groups command client")
|
||||
client.disconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
event = null
|
||||
client.disconnect()
|
||||
channel?.setStreamHandler(null)
|
||||
}
|
||||
}
|
||||
//
|
||||
//class ActiveGroupsChannel(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
// CommandClient.Handler {
|
||||
// companion object {
|
||||
// const val TAG = "A/ActiveGroupsChannel"
|
||||
// const val CHANNEL = "com.hiddify.app/active-groups"
|
||||
// val gson = Gson()
|
||||
// }
|
||||
//
|
||||
// private val client =
|
||||
// CommandClient(scope, CommandClient.ConnectionType.GroupOnly, this)
|
||||
//
|
||||
// private var channel: EventChannel? = null
|
||||
// private var event: EventChannel.EventSink? = null
|
||||
//
|
||||
// override fun updateGroups(groups: List<OutboundGroup>) {
|
||||
// MainActivity.instance.runOnUiThread {
|
||||
// val parsedGroups = groups.map { group -> ParsedOutboundGroup.fromOutbound(group) }
|
||||
// event?.success(gson.toJson(parsedGroups))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// channel = EventChannel(
|
||||
// flutterPluginBinding.binaryMessenger,
|
||||
// CHANNEL
|
||||
// )
|
||||
//
|
||||
// channel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
// override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
// event = events
|
||||
// Log.d(TAG, "connecting active groups command client")
|
||||
// client.connect()
|
||||
// }
|
||||
//
|
||||
// override fun onCancel(arguments: Any?) {
|
||||
// event = null
|
||||
// Log.d(TAG, "disconnecting active groups command client")
|
||||
// client.disconnect()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// event = null
|
||||
// client.disconnect()
|
||||
// channel?.setStreamHandler(null)
|
||||
// }
|
||||
//}
|
||||
@@ -6,6 +6,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.PowerManager
|
||||
import androidx.core.content.getSystemService
|
||||
import com.hiddify.hiddify.bg.AppChangeReceiver
|
||||
@@ -16,7 +17,6 @@ class Application : Application() {
|
||||
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
super.attachBaseContext(base)
|
||||
|
||||
application = this
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ class Application : Application() {
|
||||
val packageManager by lazy { application.packageManager }
|
||||
val powerManager by lazy { application.getSystemService<PowerManager>()!! }
|
||||
val notificationManager by lazy { application.getSystemService<NotificationManager>()!! }
|
||||
|
||||
val wifiManager by lazy { application.getSystemService<WifiManager>()!! }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,57 +2,57 @@ package com.hiddify.hiddify
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.hiddify.hiddify.utils.CommandClient
|
||||
//import com.hiddify.hiddify.utils.CommandClient
|
||||
import com.hiddify.hiddify.utils.ParsedOutboundGroup
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import com.hiddify.core.libbox.OutboundGroup
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
class GroupsChannel(private val scope: CoroutineScope) : FlutterPlugin, CommandClient.Handler {
|
||||
companion object {
|
||||
const val TAG = "A/GroupsChannel"
|
||||
const val CHANNEL = "com.hiddify.app/groups"
|
||||
val gson = Gson()
|
||||
}
|
||||
|
||||
private val client =
|
||||
CommandClient(scope, CommandClient.ConnectionType.Groups, this)
|
||||
|
||||
private var channel: EventChannel? = null
|
||||
private var event: EventChannel.EventSink? = null
|
||||
|
||||
override fun updateGroups(groups: List<OutboundGroup>) {
|
||||
MainActivity.instance.runOnUiThread {
|
||||
val parsedGroups = groups.map { group -> ParsedOutboundGroup.fromOutbound(group) }
|
||||
event?.success(gson.toJson(parsedGroups))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = EventChannel(
|
||||
flutterPluginBinding.binaryMessenger,
|
||||
CHANNEL
|
||||
)
|
||||
|
||||
channel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
event = events
|
||||
Log.d(TAG, "connecting groups command client")
|
||||
client.connect()
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
event = null
|
||||
Log.d(TAG, "disconnecting groups command client")
|
||||
client.disconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
event = null
|
||||
client.disconnect()
|
||||
channel?.setStreamHandler(null)
|
||||
}
|
||||
}
|
||||
//
|
||||
//class GroupsChannel(private val scope: CoroutineScope) : FlutterPlugin, CommandClient.Handler {
|
||||
// companion object {
|
||||
// const val TAG = "A/GroupsChannel"
|
||||
// const val CHANNEL = "com.hiddify.app/groups"
|
||||
// val gson = Gson()
|
||||
// }
|
||||
//
|
||||
// private val client =
|
||||
// CommandClient(scope, CommandClient.ConnectionType.Groups, this)
|
||||
//
|
||||
// private var channel: EventChannel? = null
|
||||
// private var event: EventChannel.EventSink? = null
|
||||
//
|
||||
// override fun updateGroups(groups: List<OutboundGroup>) {
|
||||
// MainActivity.instance.runOnUiThread {
|
||||
// val parsedGroups = groups.map { group -> ParsedOutboundGroup.fromOutbound(group) }
|
||||
// event?.success(gson.toJson(parsedGroups))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// channel = EventChannel(
|
||||
// flutterPluginBinding.binaryMessenger,
|
||||
// CHANNEL
|
||||
// )
|
||||
//
|
||||
// channel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
// override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
// event = events
|
||||
// Log.d(TAG, "connecting groups command client")
|
||||
// client.connect()
|
||||
// }
|
||||
//
|
||||
// override fun onCancel(arguments: Any?) {
|
||||
// event = null
|
||||
// Log.d(TAG, "disconnecting groups command client")
|
||||
// client.disconnect()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// event = null
|
||||
// client.disconnect()
|
||||
// channel?.setStreamHandler(null)
|
||||
// }
|
||||
//}
|
||||
@@ -7,6 +7,7 @@ import android.content.pm.PackageManager
|
||||
import android.net.VpnService
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
@@ -48,35 +49,39 @@ class MainActivity : FlutterFragmentActivity(), ServiceConnection.Callback {
|
||||
flutterEngine.plugins.add(PlatformSettingsHandler())
|
||||
flutterEngine.plugins.add(EventHandler())
|
||||
flutterEngine.plugins.add(LogHandler())
|
||||
flutterEngine.plugins.add(GroupsChannel(lifecycleScope))
|
||||
flutterEngine.plugins.add(ActiveGroupsChannel(lifecycleScope))
|
||||
flutterEngine.plugins.add(StatsChannel(lifecycleScope))
|
||||
// flutterEngine.plugins.add(GroupsChannel(lifecycleScope))
|
||||
// flutterEngine.plugins.add(ActiveGroupsChannel(lifecycleScope))
|
||||
// flutterEngine.plugins.add(StatsChannel(lifecycleScope))
|
||||
}
|
||||
|
||||
fun reconnect() {
|
||||
connection.reconnect()
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
fun startService() {
|
||||
if (!ServiceNotification.checkPermission()) {
|
||||
grantNotificationPermission()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !ServiceNotification.checkPermission()) {
|
||||
notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||
return
|
||||
}
|
||||
startService0()
|
||||
}
|
||||
|
||||
private fun startService0() {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
if (Settings.rebuildServiceMode()) {
|
||||
reconnect()
|
||||
connection.reconnect()
|
||||
}
|
||||
if (Settings.serviceMode == ServiceMode.VPN) {
|
||||
if (prepare()) {
|
||||
Log.d(TAG, "VPN permission required")
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
val intent = Intent(Application.application, Settings.serviceClass())
|
||||
withContext(Dispatchers.Main) {
|
||||
ContextCompat.startForegroundService(Application.application, intent)
|
||||
ContextCompat.startForegroundService(this@MainActivity, intent)
|
||||
}
|
||||
Settings.startedByUser = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,16 +89,37 @@ class MainActivity : FlutterFragmentActivity(), ServiceConnection.Callback {
|
||||
try {
|
||||
val intent = VpnService.prepare(this@MainActivity)
|
||||
if (intent != null) {
|
||||
startActivityForResult(intent, VPN_PERMISSION_REQUEST_CODE)
|
||||
prepareLauncher.launch(intent)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
onServiceAlert(Alert.RequestVPNPermission, e.message)
|
||||
false
|
||||
true
|
||||
}
|
||||
}
|
||||
private val notificationPermissionLauncher =
|
||||
registerForActivityResult(
|
||||
ActivityResultContracts.RequestPermission(),
|
||||
) { isGranted ->
|
||||
if (Settings.dynamicNotification && !isGranted) {
|
||||
onServiceAlert(Alert.RequestNotificationPermission, null)
|
||||
} else {
|
||||
startService0()
|
||||
}
|
||||
}
|
||||
|
||||
private val prepareLauncher =
|
||||
registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult(),
|
||||
) { result ->
|
||||
if (result.resultCode == RESULT_OK) {
|
||||
startService0()
|
||||
} else {
|
||||
onServiceAlert(Alert.RequestVPNPermission, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceStatusChanged(status: Status) {
|
||||
serviceStatus.postValue(status)
|
||||
@@ -103,19 +129,8 @@ class MainActivity : FlutterFragmentActivity(), ServiceConnection.Callback {
|
||||
serviceAlerts.postValue(ServiceEvent(Status.Stopped, type, message))
|
||||
}
|
||||
|
||||
override fun onServiceWriteLog(message: String?) {
|
||||
if (logList.size > 300) {
|
||||
logList.removeFirst()
|
||||
}
|
||||
logList.addLast(message)
|
||||
logCallback?.invoke(false)
|
||||
}
|
||||
|
||||
override fun onServiceResetLogs(messages: MutableList<String>) {
|
||||
logList.clear()
|
||||
logList.addAll(messages)
|
||||
logCallback?.invoke(true)
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
connection.disconnect()
|
||||
|
||||
@@ -2,12 +2,16 @@ package com.hiddify.hiddify
|
||||
|
||||
import android.util.Log
|
||||
import com.hiddify.hiddify.bg.BoxService
|
||||
//import com.hiddify.hiddify.bg.BoxService.Companion.workingDir
|
||||
import com.hiddify.hiddify.constant.Status
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.mobile.Mobile
|
||||
|
||||
import com.hiddify.core.libbox.Libbox
|
||||
import com.hiddify.core.mobile.Mobile
|
||||
import com.hiddify.core.mobile.SetupOptions
|
||||
import com.hiddify.hiddify.bg.Bugs
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
@@ -25,16 +29,12 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
|
||||
enum class Trigger(val method: String) {
|
||||
Setup("setup"),
|
||||
ParseConfig("parse_config"),
|
||||
changeHiddifyOptions("change_hiddify_options"),
|
||||
GenerateConfig("generate_config"),
|
||||
Start("start"),
|
||||
Stop("stop"),
|
||||
Restart("restart"),
|
||||
SelectOutbound("select_outbound"),
|
||||
UrlTest("url_test"),
|
||||
ClearLogs("clear_logs"),
|
||||
GenerateWarpConfig("generate_warp_config"),
|
||||
AddGrpcClientPublicKey("add_grpc_client_public_key"),
|
||||
GetGrpcServerPublicKey("get_grpc_server_public_key"),
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,77 +52,81 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
when (call.method) {
|
||||
Trigger.AddGrpcClientPublicKey.method -> {
|
||||
GlobalScope.launch {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
val clientPub = args["clientPublicKey"] as ByteArray
|
||||
// Mobile.addGrpcClientPublicKey(clientPub)
|
||||
Settings.grpcFlutterPublicKey = clientPub
|
||||
success("")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.GetGrpcServerPublicKey.method -> {
|
||||
GlobalScope.launch {
|
||||
result.runCatching {
|
||||
result.success(Mobile.getServerPublicKey())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.Setup.method -> {
|
||||
GlobalScope.launch {
|
||||
result.runCatching {
|
||||
val baseDir = Application.application.filesDir
|
||||
baseDir.mkdirs()
|
||||
val workingDir = Application.application.getExternalFilesDir(null)
|
||||
workingDir?.mkdirs()
|
||||
val tempDir = Application.application.cacheDir
|
||||
tempDir.mkdirs()
|
||||
Log.d(TAG, "base dir: ${baseDir.path}")
|
||||
Log.d(TAG, "working dir: ${workingDir?.path}")
|
||||
Log.d(TAG, "temp dir: ${tempDir.path}")
|
||||
|
||||
Mobile.setup(baseDir.path, workingDir?.path, tempDir.path, false)
|
||||
Libbox.redirectStderr(File(workingDir, "stderr2.log").path)
|
||||
val args = call.arguments as Map<*, *>
|
||||
Settings.baseDir = args["baseDir"] as String
|
||||
Settings.workingDir = args["workingDir"] as String
|
||||
Settings.tempDir = args["tempDir"] as String
|
||||
Settings.debugMode = args["debug"] as Boolean? ?: false
|
||||
val mode = args["mode"] as Int
|
||||
val grpcPort = args["grpcPort"] as Int
|
||||
Log.d("debugmode","${Settings.debugMode}")
|
||||
runCatching {
|
||||
Mobile.setup(
|
||||
SetupOptions().also {
|
||||
it.basePath = Settings.baseDir
|
||||
it.workingDir = Settings.workingDir
|
||||
it.tempDir = Settings.tempDir
|
||||
it.fixAndroidStack = Bugs.fixAndroidStack
|
||||
it.mode=mode.toLong()
|
||||
it.listen= "127.0.0.1:" + grpcPort
|
||||
it.secret=""
|
||||
it.debug = Settings.debugMode
|
||||
},null)
|
||||
|
||||
// Libbox.setup(Settings.baseDir, Settings.workingDir, Settings.tempDir, false)
|
||||
Libbox.redirectStderr(File(Settings.workingDir, "stderr2.log").path)
|
||||
|
||||
success("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.ParseConfig.method -> {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
val path = args["path"] as String
|
||||
val tempPath = args["tempPath"] as String
|
||||
val debug = args["debug"] as Boolean
|
||||
val msg = BoxService.parseConfig(path, tempPath, debug)
|
||||
success(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.changeHiddifyOptions.method -> {
|
||||
scope.launch {
|
||||
result.runCatching {
|
||||
val args = call.arguments as String
|
||||
Settings.configOptions = args
|
||||
success(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.GenerateConfig.method -> {
|
||||
scope.launch {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
val path = args["path"] as String
|
||||
val options = Settings.configOptions
|
||||
if (options.isBlank() || path.isBlank()) {
|
||||
error("blank properties")
|
||||
}.onFailure {
|
||||
error(it)
|
||||
}
|
||||
val config = BoxService.buildConfig(path, options)
|
||||
success(config)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Trigger.Start.method -> {
|
||||
scope.launch {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
Settings.activeConfigPath = args["path"] as String? ?: ""
|
||||
Settings.activeProfileName = args["name"] as String? ?: ""
|
||||
Settings.debugMode = args["debug"] as Boolean? ?: false
|
||||
Settings.grpcServiceModePort = args["grpcPort"] as Int
|
||||
|
||||
val mainActivity = MainActivity.instance
|
||||
val started = mainActivity.serviceStatus.value == Status.Started
|
||||
if (started) {
|
||||
Log.w(TAG, "service is already running")
|
||||
return@launch success(true)
|
||||
}
|
||||
// val started = mainActivity.serviceStatus.value == Status.Started
|
||||
// if (started) {
|
||||
// Log.w(TAG, "service is already running")
|
||||
// return@launch success(true)
|
||||
// }
|
||||
Settings.startCoreAfterStartingService = false
|
||||
|
||||
mainActivity.startService()
|
||||
success(true)
|
||||
}
|
||||
@@ -136,7 +140,7 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
val started = mainActivity.serviceStatus.value == Status.Started
|
||||
if (!started) {
|
||||
Log.w(TAG, "service is not running")
|
||||
return@launch success(true)
|
||||
// return@launch success(true)
|
||||
}
|
||||
BoxService.stop()
|
||||
success(true)
|
||||
@@ -144,82 +148,32 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.Restart.method -> {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
Settings.activeConfigPath = args["path"] as String? ?: ""
|
||||
Settings.activeProfileName = args["name"] as String? ?: ""
|
||||
val mainActivity = MainActivity.instance
|
||||
val started = mainActivity.serviceStatus.value == Status.Started
|
||||
if (!started) return@launch success(true)
|
||||
val restart = Settings.rebuildServiceMode()
|
||||
if (restart) {
|
||||
mainActivity.reconnect()
|
||||
BoxService.stop()
|
||||
delay(1000L)
|
||||
mainActivity.startService()
|
||||
return@launch success(true)
|
||||
}
|
||||
runCatching {
|
||||
Libbox.newStandaloneCommandClient().serviceReload()
|
||||
success(true)
|
||||
}.onFailure {
|
||||
error(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.SelectOutbound.method -> {
|
||||
scope.launch {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
Libbox.newStandaloneCommandClient()
|
||||
.selectOutbound(
|
||||
args["groupTag"] as String,
|
||||
args["outboundTag"] as String
|
||||
)
|
||||
success(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.UrlTest.method -> {
|
||||
scope.launch {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
Libbox.newStandaloneCommandClient()
|
||||
.urlTest(
|
||||
args["groupTag"] as String
|
||||
)
|
||||
success(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.ClearLogs.method -> {
|
||||
scope.launch {
|
||||
result.runCatching {
|
||||
MainActivity.instance.onServiceResetLogs(mutableListOf())
|
||||
success(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Trigger.GenerateWarpConfig.method -> {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
result.runCatching {
|
||||
val args = call.arguments as Map<*, *>
|
||||
val warpConfig = Mobile.generateWarpConfig(
|
||||
args["license-key"] as String,
|
||||
args["previous-account-id"] as String,
|
||||
args["previous-access-token"] as String,
|
||||
)
|
||||
success(warpConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Trigger.Restart.method -> {
|
||||
// scope.launch(Dispatchers.IO) {
|
||||
// result.runCatching {
|
||||
// val args = call.arguments as Map<*, *>
|
||||
// Settings.activeConfigPath = args["path"] as String? ?: ""
|
||||
// Settings.activeProfileName = args["name"] as String? ?: ""
|
||||
// val mainActivity = MainActivity.instance
|
||||
// val started = mainActivity.serviceStatus.value == Status.Started
|
||||
// if (!started) return@launch success(true)
|
||||
// val restart = Settings.rebuildServiceMode()
|
||||
// if (restart) {
|
||||
// mainActivity.reconnect()
|
||||
// BoxService.stop()
|
||||
// delay(1000L)
|
||||
// mainActivity.startService()
|
||||
// return@launch success(true)
|
||||
// }
|
||||
// runCatching {
|
||||
// Libbox.newStandaloneCommandClient().serviceReload()
|
||||
// success(true)
|
||||
// }.onFailure {
|
||||
// error(it)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
|
||||
@@ -149,8 +149,8 @@ class PlatformSettingsHandler : FlutterPlugin, MethodChannel.MethodCallHandler,
|
||||
list.add(
|
||||
AppItem(
|
||||
it.packageName,
|
||||
it.applicationInfo.loadLabel(packageManager).toString(),
|
||||
it.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 1
|
||||
it.applicationInfo?.loadLabel(packageManager).toString(),
|
||||
(it.applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) == 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.ObjectInputStream
|
||||
|
||||
|
||||
object Settings {
|
||||
|
||||
private val preferences by lazy {
|
||||
@@ -36,9 +37,13 @@ object Settings {
|
||||
preferences.getString(SettingsKey.PER_APP_PROXY_EXCLUDE_LIST, "")!!
|
||||
}
|
||||
if (!stringValue.startsWith(LIST_IDENTIFIER)) {
|
||||
return emptyList()
|
||||
return stringValue.split(";")
|
||||
}
|
||||
return try {
|
||||
decodeListString(stringValue.substring(LIST_IDENTIFIER.length))
|
||||
} catch (e: java.lang.Exception) {
|
||||
emptyList()
|
||||
}
|
||||
return decodeListString(stringValue.substring(LIST_IDENTIFIER.length))
|
||||
}
|
||||
|
||||
private fun decodeListString(listString: String): List<String> {
|
||||
@@ -122,5 +127,37 @@ object Settings {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var workingDir: String
|
||||
get() = preferences.getString(SettingsKey.WORKING_DIR, "./")!!
|
||||
set(value) = preferences.edit().putString(SettingsKey.WORKING_DIR, value).apply()
|
||||
var tempDir: String
|
||||
get() = preferences.getString(SettingsKey.TMP_DIR, "./")!!
|
||||
set(value) = preferences.edit().putString(SettingsKey.TMP_DIR, value).apply()
|
||||
|
||||
var baseDir: String
|
||||
get() = preferences.getString(SettingsKey.BASE_DIR, "./")!!
|
||||
set(value) = preferences.edit().putString(SettingsKey.BASE_DIR, value).apply()
|
||||
|
||||
|
||||
|
||||
var grpcFlutterPublicKey: ByteArray
|
||||
get() {
|
||||
val encoded = preferences.getString(SettingsKey.GRPC_FLUTTER_PUBLIC_KEY, null)
|
||||
return encoded?.let { Base64.decode(it, Base64.DEFAULT) } ?: ByteArray(0)
|
||||
}
|
||||
set(value) {
|
||||
val encoded = Base64.encodeToString(value, Base64.DEFAULT)
|
||||
preferences.edit().putString(SettingsKey.GRPC_FLUTTER_PUBLIC_KEY, encoded).apply()
|
||||
}
|
||||
var grpcServiceModePort: Int
|
||||
get() = preferences.getInt(SettingsKey.GRPC_PORT, 17078)!!
|
||||
set(value) = preferences.edit().putInt(SettingsKey.GRPC_PORT, value).apply()
|
||||
|
||||
var startCoreAfterStartingService: Boolean
|
||||
get() = preferences.getBoolean(SettingsKey.START_CORE_ON_STARTING_SERVICE, false)
|
||||
set(value) = preferences.edit().putBoolean(SettingsKey.START_CORE_ON_STARTING_SERVICE, value).apply()
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
package com.hiddify.hiddify
|
||||
|
||||
import android.util.Log
|
||||
import com.hiddify.hiddify.utils.CommandClient
|
||||
//import com.hiddify.hiddify.utils.CommandClient
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.flutter.plugin.common.JSONMethodCodec
|
||||
import io.nekohasekai.libbox.StatusMessage
|
||||
import com.hiddify.core.libbox.StatusMessage
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
class StatsChannel(private val scope: CoroutineScope) : FlutterPlugin, CommandClient.Handler{
|
||||
companion object {
|
||||
const val TAG = "A/StatsChannel"
|
||||
const val STATS_CHANNEL = "com.hiddify.app/stats"
|
||||
}
|
||||
|
||||
private val commandClient =
|
||||
CommandClient(scope, CommandClient.ConnectionType.Status, this)
|
||||
|
||||
private var statsChannel: EventChannel? = null
|
||||
private var statsEvent: EventChannel.EventSink? = null
|
||||
|
||||
override fun updateStatus(status: StatusMessage) {
|
||||
MainActivity.instance.runOnUiThread {
|
||||
val map = listOf(
|
||||
Pair("connections-in", status.connectionsIn),
|
||||
Pair("connections-out", status.connectionsOut),
|
||||
Pair("uplink", status.uplink),
|
||||
Pair("downlink", status.downlink),
|
||||
Pair("uplink-total", status.uplinkTotal),
|
||||
Pair("downlink-total", status.downlinkTotal)
|
||||
).associate { it.first to it.second }
|
||||
statsEvent?.success(map)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
statsChannel = EventChannel(
|
||||
flutterPluginBinding.binaryMessenger,
|
||||
STATS_CHANNEL,
|
||||
JSONMethodCodec.INSTANCE
|
||||
)
|
||||
|
||||
statsChannel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
statsEvent = events
|
||||
Log.d(TAG, "connecting stats command client")
|
||||
commandClient.connect()
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
statsEvent = null
|
||||
Log.d(TAG, "disconnecting stats command client")
|
||||
commandClient.disconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
statsEvent = null
|
||||
commandClient.disconnect()
|
||||
statsChannel?.setStreamHandler(null)
|
||||
}
|
||||
}
|
||||
//class StatsChannel(private val scope: CoroutineScope) : FlutterPlugin, CommandClient.Handler{
|
||||
// companion object {
|
||||
// const val TAG = "A/StatsChannel"
|
||||
// const val STATS_CHANNEL = "com.hiddify.app/stats"
|
||||
// }
|
||||
//
|
||||
// private val commandClient =
|
||||
// CommandClient(scope, CommandClient.ConnectionType.Status, this)
|
||||
//
|
||||
// private var statsChannel: EventChannel? = null
|
||||
// private var statsEvent: EventChannel.EventSink? = null
|
||||
//
|
||||
// override fun updateStatus(status: StatusMessage) {
|
||||
// MainActivity.instance.runOnUiThread {
|
||||
// val map = listOf(
|
||||
// Pair("connections-in", status.connectionsIn),
|
||||
// Pair("connections-out", status.connectionsOut),
|
||||
// Pair("uplink", status.uplink),
|
||||
// Pair("downlink", status.downlink),
|
||||
// Pair("uplink-total", status.uplinkTotal),
|
||||
// Pair("downlink-total", status.downlinkTotal)
|
||||
// ).associate { it.first to it.second }
|
||||
// statsEvent?.success(map)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// statsChannel = EventChannel(
|
||||
// flutterPluginBinding.binaryMessenger,
|
||||
// STATS_CHANNEL,
|
||||
// JSONMethodCodec.INSTANCE
|
||||
// )
|
||||
//
|
||||
// statsChannel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
// override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
// statsEvent = events
|
||||
// Log.d(TAG, "connecting stats command client")
|
||||
// commandClient.connect()
|
||||
// }
|
||||
//
|
||||
// override fun onCancel(arguments: Any?) {
|
||||
// statsEvent = null
|
||||
// Log.d(TAG, "disconnecting stats command client")
|
||||
// commandClient.disconnect()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// statsEvent = null
|
||||
// commandClient.disconnect()
|
||||
// statsChannel?.setStreamHandler(null)
|
||||
// }
|
||||
//}
|
||||
@@ -1,16 +1,19 @@
|
||||
package com.hiddify.hiddify.bg
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
|
||||
import android.content.Intent
|
||||
import com.hiddify.hiddify.MainActivity
|
||||
import com.hiddify.hiddify.Settings
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (intent.action) {
|
||||
Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_MY_PACKAGE_REPLACED -> {
|
||||
@@ -21,10 +24,10 @@ class BootReceiver : BroadcastReceiver() {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
if (Settings.startedByUser) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Settings.startCoreAfterStartingService=true //H
|
||||
BoxService.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +1,21 @@
|
||||
package com.hiddify.hiddify.bg
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.hiddify.hiddify.Application
|
||||
@@ -19,14 +24,22 @@ import com.hiddify.hiddify.Settings
|
||||
import com.hiddify.hiddify.constant.Action
|
||||
import com.hiddify.hiddify.constant.Alert
|
||||
import com.hiddify.hiddify.constant.Status
|
||||
import com.hiddify.core.mobile.SetupOptions
|
||||
|
||||
import go.Seq
|
||||
import io.nekohasekai.libbox.BoxService
|
||||
import io.nekohasekai.libbox.CommandServer
|
||||
import io.nekohasekai.libbox.CommandServerHandler
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.PlatformInterface
|
||||
import io.nekohasekai.libbox.SystemProxyStatus
|
||||
import io.nekohasekai.mobile.Mobile
|
||||
import com.hiddify.core.libbox.Libbox
|
||||
import com.hiddify.core.mobile.Mobile
|
||||
|
||||
|
||||
import com.hiddify.core.libbox.CommandServer
|
||||
import com.hiddify.core.libbox.CommandServerHandler
|
||||
import com.hiddify.core.libbox.Notification
|
||||
import com.hiddify.core.libbox.PlatformInterface
|
||||
import com.hiddify.core.libbox.SystemProxyStatus
|
||||
import com.hiddify.hiddify.BuildConfig
|
||||
import com.hiddify.hiddify.MainActivity
|
||||
import com.hiddify.hiddify.constant.Bugs
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -38,7 +51,7 @@ import java.io.File
|
||||
class BoxService(
|
||||
private val service: Service,
|
||||
private val platformInterface: PlatformInterface
|
||||
) : CommandServerHandler {
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "A/BoxService"
|
||||
@@ -46,9 +59,11 @@ class BoxService(
|
||||
private var initializeOnce = false
|
||||
private lateinit var workingDir: File
|
||||
private fun initialize() {
|
||||
System.setProperty("GODEBUG", "efence=1,stacktraceback=2");
|
||||
System.setProperty("GOGC", "off");
|
||||
if (initializeOnce) return
|
||||
val baseDir = Application.application.filesDir
|
||||
|
||||
|
||||
baseDir.mkdirs()
|
||||
workingDir = Application.application.getExternalFilesDir(null) ?: return
|
||||
workingDir.mkdirs()
|
||||
@@ -57,27 +72,23 @@ class BoxService(
|
||||
Log.d(TAG, "base dir: ${baseDir.path}")
|
||||
Log.d(TAG, "working dir: ${workingDir.path}")
|
||||
Log.d(TAG, "temp dir: ${tempDir.path}")
|
||||
|
||||
Mobile.setup(baseDir.path, workingDir.path, tempDir.path, false)
|
||||
Libbox.redirectStderr(File(workingDir, "stderr.log").path)
|
||||
|
||||
//
|
||||
//Mobile.setup(baseDir.path, workingDir.path, tempDir.path, 2L ,"127.0.0.1:{Setting}","",false,this)
|
||||
// Libbox.setup(baseDir.path, workingDir.path, tempDir.path, false)
|
||||
|
||||
// Libbox.setup(SetupOptions().also {
|
||||
// it.basePath = baseDir.path
|
||||
// it.workingPath = workingDir.path
|
||||
// it.tempPath = tempDir.path
|
||||
// it.fixAndroidStack = Bugs.fixAndroidStack
|
||||
//
|
||||
// })
|
||||
Libbox.redirectStderr(File(Settings.workingDir, "stderr.log").path)
|
||||
initializeOnce = true
|
||||
return
|
||||
}
|
||||
|
||||
fun parseConfig(path: String, tempPath: String, debug: Boolean): String {
|
||||
return try {
|
||||
Mobile.parse(path, tempPath, debug)
|
||||
""
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
e.message ?: "invalid config"
|
||||
}
|
||||
}
|
||||
|
||||
fun buildConfig(path: String, options: String): String {
|
||||
return Mobile.buildConfig(path, options)
|
||||
}
|
||||
|
||||
fun start() {
|
||||
val intent = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
@@ -95,13 +106,7 @@ class BoxService(
|
||||
)
|
||||
}
|
||||
|
||||
fun reload() {
|
||||
Application.application.sendBroadcast(
|
||||
Intent(Action.SERVICE_RELOAD).setPackage(
|
||||
Application.application.packageName
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var fileDescriptor: ParcelFileDescriptor? = null
|
||||
@@ -109,7 +114,7 @@ class BoxService(
|
||||
private val status = MutableLiveData(Status.Stopped)
|
||||
private val binder = ServiceBinder(status)
|
||||
private val notification = ServiceNotification(status, service)
|
||||
private var boxService: BoxService? = null
|
||||
// private var boxService: BoxService? = null
|
||||
private var commandServer: CommandServer? = null
|
||||
private var receiverRegistered = false
|
||||
private val receiver = object : BroadcastReceiver() {
|
||||
@@ -119,10 +124,6 @@ class BoxService(
|
||||
stopService()
|
||||
}
|
||||
|
||||
Action.SERVICE_RELOAD -> {
|
||||
serviceReload()
|
||||
}
|
||||
|
||||
PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
serviceUpdateIdleMode()
|
||||
@@ -131,17 +132,13 @@ class BoxService(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun startCommandServer() {
|
||||
val commandServer =
|
||||
CommandServer(this, 300)
|
||||
commandServer.start()
|
||||
this.commandServer = commandServer
|
||||
}
|
||||
|
||||
private var activeProfileName = ""
|
||||
private suspend fun startService(delayStart: Boolean = false) {
|
||||
private suspend fun startService() {
|
||||
try {
|
||||
status.postValue(Status.Starting)
|
||||
Log.d(TAG, "starting service")
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.show(activeProfileName, R.string.status_starting)
|
||||
@@ -155,24 +152,6 @@ class BoxService(
|
||||
|
||||
activeProfileName = Settings.activeProfileName
|
||||
|
||||
val configOptions = Settings.configOptions
|
||||
if (configOptions.isBlank()) {
|
||||
stopAndAlert(Alert.EmptyConfiguration)
|
||||
return
|
||||
}
|
||||
|
||||
val content = try {
|
||||
Mobile.buildConfig(selectedConfigPath, configOptions)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
stopAndAlert(Alert.EmptyConfiguration)
|
||||
return
|
||||
}
|
||||
|
||||
if (Settings.debugMode) {
|
||||
File(workingDir, "current-config.json").writeText(content)
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.show(activeProfileName, R.string.status_starting)
|
||||
binder.broadcast {
|
||||
@@ -181,25 +160,41 @@ class BoxService(
|
||||
}
|
||||
|
||||
DefaultNetworkMonitor.start()
|
||||
Libbox.registerLocalDNSTransport(LocalResolver)
|
||||
Libbox.setMemoryLimit(!Settings.disableMemoryLimit)
|
||||
|
||||
val newService = try {
|
||||
Libbox.newService(content, platformInterface)
|
||||
Mobile.setup(
|
||||
SetupOptions().also {
|
||||
it.basePath = Settings.baseDir
|
||||
it.workingDir = Settings.workingDir
|
||||
it.tempDir = Settings.tempDir
|
||||
it.fixAndroidStack = com.hiddify.hiddify.bg.Bugs.fixAndroidStack
|
||||
it.mode=4L//mode.toLong()
|
||||
it.listen= "127.0.0.1:${Settings.grpcServiceModePort}"
|
||||
it.secret=""
|
||||
it.debug = Settings.debugMode
|
||||
},platformInterface)
|
||||
|
||||
|
||||
// Libbox.newService(content,platformInterface)
|
||||
|
||||
} catch (e: Exception) {
|
||||
stopAndAlert(Alert.CreateService, e.message)
|
||||
return
|
||||
}
|
||||
|
||||
if (delayStart) {
|
||||
delay(1000L)
|
||||
}
|
||||
|
||||
newService.start()
|
||||
boxService = newService
|
||||
commandServer?.setService(boxService)
|
||||
status.postValue(Status.Started)
|
||||
|
||||
if (Settings.startCoreAfterStartingService){
|
||||
Mobile.start("","")
|
||||
}
|
||||
// if (delayStart) {
|
||||
// delay(1000L)
|
||||
// }
|
||||
|
||||
// newService.start()
|
||||
// boxService = newService
|
||||
// commandServer?.setService(boxService)
|
||||
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.show(activeProfileName, R.string.status_started)
|
||||
}
|
||||
@@ -210,30 +205,38 @@ class BoxService(
|
||||
}
|
||||
}
|
||||
|
||||
override fun serviceReload() {
|
||||
fun serviceReload() {
|
||||
runBlocking {
|
||||
serviceReload0()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun serviceReload0() {
|
||||
notification.close()
|
||||
status.postValue(Status.Starting)
|
||||
|
||||
val pfd = fileDescriptor
|
||||
if (pfd != null) {
|
||||
pfd.close()
|
||||
fileDescriptor = null
|
||||
}
|
||||
commandServer?.setService(null)
|
||||
boxService?.apply {
|
||||
runCatching {
|
||||
close()
|
||||
}.onFailure {
|
||||
writeLog("service: error when closing: $it")
|
||||
}
|
||||
Seq.destroyRef(refnum)
|
||||
}
|
||||
boxService = null
|
||||
runBlocking {
|
||||
startService(true)
|
||||
}
|
||||
|
||||
// boxService?.apply {
|
||||
// runCatching {
|
||||
// close()
|
||||
// }.onFailure {
|
||||
// writeLog("service: error when closing: $it")
|
||||
// }
|
||||
// Seq.destroyRef(refnum)
|
||||
// }
|
||||
Mobile.stop()
|
||||
// boxService = null
|
||||
|
||||
startService()
|
||||
|
||||
}
|
||||
|
||||
override fun getSystemProxyStatus(): SystemProxyStatus {
|
||||
fun getSystemProxyStatus(): SystemProxyStatus {
|
||||
val status = SystemProxyStatus()
|
||||
if (service is VPNService) {
|
||||
status.available = service.systemProxyAvailable
|
||||
@@ -242,21 +245,23 @@ class BoxService(
|
||||
return status
|
||||
}
|
||||
|
||||
override fun setSystemProxyEnabled(isEnabled: Boolean) {
|
||||
fun setSystemProxyEnabled(isEnabled: Boolean) {
|
||||
serviceReload()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
private fun serviceUpdateIdleMode() {
|
||||
if (Application.powerManager.isDeviceIdleMode) {
|
||||
boxService?.pause()
|
||||
// boxService?.pause()
|
||||
//Mobile.pause()
|
||||
} else {
|
||||
boxService?.wake()
|
||||
Mobile.wake()
|
||||
// boxService?.wake()
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopService() {
|
||||
if (status.value != Status.Started) return
|
||||
if (status.value == Status.Stopped) return
|
||||
status.value = Status.Stopping
|
||||
if (receiverRegistered) {
|
||||
service.unregisterReceiver(receiver)
|
||||
@@ -269,34 +274,34 @@ class BoxService(
|
||||
pfd.close()
|
||||
fileDescriptor = null
|
||||
}
|
||||
commandServer?.setService(null)
|
||||
boxService?.apply {
|
||||
runCatching {
|
||||
close()
|
||||
}.onFailure {
|
||||
writeLog("service: error when closing: $it")
|
||||
}
|
||||
Seq.destroyRef(refnum)
|
||||
}
|
||||
boxService = null
|
||||
Libbox.registerLocalDNSTransport(null)
|
||||
// commandServer?.setService(null)
|
||||
// boxService?.apply {
|
||||
// runCatching {
|
||||
// close()
|
||||
// }.onFailure {
|
||||
// writeLog("service: error when closing: $it")
|
||||
// }
|
||||
// //Seq.destroyRef(refnum)
|
||||
// }
|
||||
|
||||
// boxService = null
|
||||
// Libbox.registerLocalDNSTransport(null)
|
||||
DefaultNetworkMonitor.stop()
|
||||
|
||||
commandServer?.apply {
|
||||
close()
|
||||
Seq.destroyRef(refnum)
|
||||
}
|
||||
commandServer = null
|
||||
// commandServer?.apply {
|
||||
// close()
|
||||
// Seq.destroyRef(refnum)
|
||||
// }
|
||||
// commandServer = null
|
||||
Settings.startedByUser = false
|
||||
withContext(Dispatchers.Main) {
|
||||
Mobile.close(4L)
|
||||
status.value = Status.Stopped
|
||||
service.stopSelf()
|
||||
}
|
||||
notification.close()
|
||||
}
|
||||
}
|
||||
override fun postServiceClose() {
|
||||
// Not used on Android
|
||||
}
|
||||
|
||||
private suspend fun stopAndAlert(type: Alert, message: String? = null) {
|
||||
Settings.startedByUser = false
|
||||
@@ -313,14 +318,15 @@ class BoxService(
|
||||
}
|
||||
}
|
||||
|
||||
fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
@Suppress("SameReturnValue")
|
||||
internal fun onStartCommand(): Int {
|
||||
if (status.value != Status.Stopped) return Service.START_NOT_STICKY
|
||||
status.value = Status.Starting
|
||||
|
||||
if (!receiverRegistered) {
|
||||
ContextCompat.registerReceiver(service, receiver, IntentFilter().apply {
|
||||
addAction(Action.SERVICE_CLOSE)
|
||||
addAction(Action.SERVICE_RELOAD)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)
|
||||
}
|
||||
@@ -331,12 +337,12 @@ class BoxService(
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
Settings.startedByUser = true
|
||||
initialize()
|
||||
try {
|
||||
startCommandServer()
|
||||
} catch (e: Exception) {
|
||||
stopAndAlert(Alert.StartCommandServer, e.message)
|
||||
return@launch
|
||||
}
|
||||
// try {
|
||||
// startCommandServer()
|
||||
// } catch (e: Exception) {
|
||||
// stopAndAlert(Alert.StartCommandServer, e.message)
|
||||
// return@launch
|
||||
// }
|
||||
startService()
|
||||
}
|
||||
return Service.START_NOT_STICKY
|
||||
@@ -354,7 +360,49 @@ class BoxService(
|
||||
stopService()
|
||||
}
|
||||
|
||||
fun writeLog(message: String) {
|
||||
internal fun sendNotification(notification: Notification) {
|
||||
return
|
||||
val builder =
|
||||
NotificationCompat.Builder(service, notification.identifier).setShowWhen(false)
|
||||
.setContentTitle(notification.title).setContentText(notification.body)
|
||||
.setOnlyAlertOnce(true).setSmallIcon(R.drawable.ic_launcher_foreground)
|
||||
.setCategory(NotificationCompat.CATEGORY_EVENT)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH).setAutoCancel(true)
|
||||
if (!notification.subtitle.isNullOrBlank()) {
|
||||
builder.setContentInfo(notification.subtitle)
|
||||
}
|
||||
if (!notification.openURL.isNullOrBlank()) {
|
||||
builder.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
service,
|
||||
0,
|
||||
Intent(
|
||||
service,
|
||||
MainActivity::class.java,
|
||||
).apply {
|
||||
setAction(Action.SERVICE).setData(Uri.parse(notification.openURL))
|
||||
setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
||||
},
|
||||
ServiceNotification.flags,
|
||||
),
|
||||
)
|
||||
}
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
Application.notification.createNotificationChannel(
|
||||
NotificationChannel(
|
||||
notification.identifier,
|
||||
notification.typeName,
|
||||
NotificationManager.IMPORTANCE_HIGH,
|
||||
),
|
||||
)
|
||||
}
|
||||
Application.notification.notify(notification.typeID, builder.build())
|
||||
}
|
||||
}
|
||||
|
||||
fun writeDebugMessage(message: String?) {
|
||||
Log.d("BoxService", message!!)
|
||||
binder.broadcast {
|
||||
it.onServiceWriteLog(message)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.hiddify.hiddify.bg
|
||||
|
||||
import android.os.Build
|
||||
import com.hiddify.hiddify.BuildConfig
|
||||
|
||||
|
||||
object Bugs {
|
||||
// TODO: remove launch after fixed
|
||||
// https://github.com/golang/go/issues/68760
|
||||
val fixAndroidStack =
|
||||
BuildConfig.DEBUG ||
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
|
||||
Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1 ||
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
|
||||
}
|
||||
@@ -10,15 +10,19 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.hiddify.hiddify.Application
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import kotlinx.coroutines.channels.actor
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.net.UnknownHostException
|
||||
|
||||
|
||||
object DefaultNetworkListener {
|
||||
private sealed class NetworkMessage {
|
||||
class Start(val key: Any, val listener: (Network?) -> Unit) : NetworkMessage()
|
||||
|
||||
class Get : NetworkMessage() {
|
||||
val response = CompletableDeferred<Network>()
|
||||
}
|
||||
@@ -26,68 +30,88 @@ object DefaultNetworkListener {
|
||||
class Stop(val key: Any) : NetworkMessage()
|
||||
|
||||
class Put(val network: Network) : NetworkMessage()
|
||||
|
||||
class Update(val network: Network) : NetworkMessage()
|
||||
|
||||
class Lost(val network: Network) : NetworkMessage()
|
||||
}
|
||||
|
||||
private val networkActor = GlobalScope.actor<NetworkMessage>(Dispatchers.Unconfined) {
|
||||
val listeners = mutableMapOf<Any, (Network?) -> Unit>()
|
||||
var network: Network? = null
|
||||
val pendingRequests = arrayListOf<NetworkMessage.Get>()
|
||||
for (message in channel) when (message) {
|
||||
is NetworkMessage.Start -> {
|
||||
if (listeners.isEmpty()) register()
|
||||
listeners[message.key] = message.listener
|
||||
if (network != null) message.listener(network)
|
||||
}
|
||||
@OptIn(DelicateCoroutinesApi::class, ObsoleteCoroutinesApi::class)
|
||||
private val networkActor =
|
||||
GlobalScope.actor<NetworkMessage>(Dispatchers.Unconfined) {
|
||||
val listeners = mutableMapOf<Any, (Network?) -> Unit>()
|
||||
var network: Network? = null
|
||||
val pendingRequests = arrayListOf<NetworkMessage.Get>()
|
||||
for (message in channel) {
|
||||
when (message) {
|
||||
is NetworkMessage.Start -> {
|
||||
if (listeners.isEmpty()) register()
|
||||
listeners[message.key] = message.listener
|
||||
if (network != null) message.listener(network)
|
||||
}
|
||||
|
||||
is NetworkMessage.Get -> {
|
||||
check(listeners.isNotEmpty()) { "Getting network without any listeners is not supported" }
|
||||
if (network == null) pendingRequests += message else message.response.complete(
|
||||
network
|
||||
)
|
||||
}
|
||||
is NetworkMessage.Get -> {
|
||||
check(listeners.isNotEmpty()) { "Getting network without any listeners is not supported" }
|
||||
if (network == null) {
|
||||
pendingRequests += message
|
||||
} else {
|
||||
message.response.complete(
|
||||
network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is NetworkMessage.Stop -> if (listeners.isNotEmpty() && // was not empty
|
||||
listeners.remove(message.key) != null && listeners.isEmpty()
|
||||
) {
|
||||
network = null
|
||||
unregister()
|
||||
}
|
||||
is NetworkMessage.Stop ->
|
||||
if (listeners.isNotEmpty() &&
|
||||
// was not empty
|
||||
listeners.remove(message.key) != null &&
|
||||
listeners.isEmpty()
|
||||
) {
|
||||
network = null
|
||||
unregister()
|
||||
}
|
||||
|
||||
is NetworkMessage.Put -> {
|
||||
network = message.network
|
||||
pendingRequests.forEach { it.response.complete(message.network) }
|
||||
pendingRequests.clear()
|
||||
listeners.values.forEach { it(network) }
|
||||
}
|
||||
is NetworkMessage.Put -> {
|
||||
network = message.network
|
||||
pendingRequests.forEach { it.response.complete(message.network) }
|
||||
pendingRequests.clear()
|
||||
listeners.values.forEach { it(network) }
|
||||
}
|
||||
|
||||
is NetworkMessage.Update -> if (network == message.network) listeners.values.forEach {
|
||||
it(
|
||||
network
|
||||
)
|
||||
}
|
||||
is NetworkMessage.Update ->
|
||||
if (network == message.network) {
|
||||
listeners.values.forEach {
|
||||
it(
|
||||
network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is NetworkMessage.Lost -> if (network == message.network) {
|
||||
network = null
|
||||
listeners.values.forEach { it(null) }
|
||||
is NetworkMessage.Lost ->
|
||||
if (network == message.network) {
|
||||
network = null
|
||||
listeners.values.forEach { it(null) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun start(key: Any, listener: (Network?) -> Unit) = networkActor.send(
|
||||
NetworkMessage.Start(
|
||||
key,
|
||||
listener
|
||||
)
|
||||
listener,
|
||||
),
|
||||
)
|
||||
|
||||
suspend fun get() = if (fallback) @TargetApi(23) {
|
||||
suspend fun get(): Network = if (fallback) {
|
||||
@TargetApi(23)
|
||||
Application.connectivity.activeNetwork
|
||||
?: throw UnknownHostException() // failed to listen, return current if available
|
||||
} else NetworkMessage.Get().run {
|
||||
networkActor.send(this)
|
||||
response.await()
|
||||
?: error("missing default network") // failed to listen, return current if available
|
||||
} else {
|
||||
NetworkMessage.Get().run {
|
||||
networkActor.send(this)
|
||||
response.await()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun stop(key: Any) = networkActor.send(NetworkMessage.Stop(key))
|
||||
@@ -97,15 +121,12 @@ object DefaultNetworkListener {
|
||||
override fun onAvailable(network: Network) = runBlocking {
|
||||
networkActor.send(
|
||||
NetworkMessage.Put(
|
||||
network
|
||||
)
|
||||
network,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
|
||||
// it's a good idea to refresh capabilities
|
||||
runBlocking { networkActor.send(NetworkMessage.Update(network)) }
|
||||
}
|
||||
@@ -113,21 +134,22 @@ object DefaultNetworkListener {
|
||||
override fun onLost(network: Network) = runBlocking {
|
||||
networkActor.send(
|
||||
NetworkMessage.Lost(
|
||||
network
|
||||
)
|
||||
network,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private var fallback = false
|
||||
private val request = NetworkRequest.Builder().apply {
|
||||
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
||||
if (Build.VERSION.SDK_INT == 23) { // workarounds for OEM bugs
|
||||
removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
removeCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)
|
||||
}
|
||||
}.build()
|
||||
private val request =
|
||||
NetworkRequest.Builder().apply {
|
||||
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
||||
if (Build.VERSION.SDK_INT == 23) { // workarounds for OEM bugs
|
||||
removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
removeCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)
|
||||
}
|
||||
}.build()
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
/**
|
||||
@@ -142,33 +164,42 @@ object DefaultNetworkListener {
|
||||
*/
|
||||
private fun register() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
in 31..Int.MAX_VALUE -> @TargetApi(31) {
|
||||
Application.connectivity.registerBestMatchingNetworkCallback(
|
||||
request,
|
||||
Callback,
|
||||
mainHandler
|
||||
)
|
||||
}
|
||||
in 31..Int.MAX_VALUE ->
|
||||
@TargetApi(31)
|
||||
{
|
||||
Application.connectivity.registerBestMatchingNetworkCallback(
|
||||
request,
|
||||
Callback,
|
||||
mainHandler,
|
||||
)
|
||||
}
|
||||
|
||||
in 28 until 31 -> @TargetApi(28) { // we want REQUEST here instead of LISTEN
|
||||
Application.connectivity.requestNetwork(request, Callback, mainHandler)
|
||||
}
|
||||
in 28 until 31 ->
|
||||
@TargetApi(28)
|
||||
{ // we want REQUEST here instead of LISTEN
|
||||
Application.connectivity.requestNetwork(request, Callback, mainHandler)
|
||||
}
|
||||
|
||||
in 26 until 28 -> @TargetApi(26) {
|
||||
Application.connectivity.registerDefaultNetworkCallback(Callback, mainHandler)
|
||||
}
|
||||
in 26 until 28 ->
|
||||
@TargetApi(26)
|
||||
{
|
||||
Application.connectivity.registerDefaultNetworkCallback(Callback, mainHandler)
|
||||
}
|
||||
|
||||
in 24 until 26 -> @TargetApi(24) {
|
||||
Application.connectivity.registerDefaultNetworkCallback(Callback)
|
||||
}
|
||||
in 24 until 26 ->
|
||||
@TargetApi(24)
|
||||
{
|
||||
Application.connectivity.registerDefaultNetworkCallback(Callback)
|
||||
}
|
||||
|
||||
else -> try {
|
||||
fallback = false
|
||||
Application.connectivity.requestNetwork(request, Callback)
|
||||
} catch (e: RuntimeException) {
|
||||
fallback =
|
||||
true // known bug on API 23: https://stackoverflow.com/a/33509180/2245107
|
||||
}
|
||||
else ->
|
||||
try {
|
||||
fallback = false
|
||||
Application.connectivity.requestNetwork(request, Callback)
|
||||
} catch (e: RuntimeException) {
|
||||
fallback =
|
||||
true // known bug on API 23: https://stackoverflow.com/a/33509180/2245107
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,13 @@ package com.hiddify.hiddify.bg
|
||||
import android.net.Network
|
||||
import android.os.Build
|
||||
import com.hiddify.hiddify.Application
|
||||
import io.nekohasekai.libbox.InterfaceUpdateListener
|
||||
import com.hiddify.core.libbox.InterfaceUpdateListener
|
||||
import com.hiddify.hiddify.constant.Bugs
|
||||
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.net.NetworkInterface
|
||||
|
||||
object DefaultNetworkMonitor {
|
||||
@@ -41,9 +46,7 @@ object DefaultNetworkMonitor {
|
||||
checkDefaultInterfaceUpdate(defaultNetwork)
|
||||
}
|
||||
|
||||
private fun checkDefaultInterfaceUpdate(
|
||||
newNetwork: Network?
|
||||
) {
|
||||
private fun checkDefaultInterfaceUpdate(newNetwork: Network?) {
|
||||
val listener = listener ?: return
|
||||
if (newNetwork != null) {
|
||||
val interfaceName =
|
||||
@@ -56,12 +59,10 @@ object DefaultNetworkMonitor {
|
||||
Thread.sleep(100)
|
||||
continue
|
||||
}
|
||||
listener.updateDefaultInterface(interfaceName, interfaceIndex)
|
||||
listener.updateDefaultInterface(interfaceName, interfaceIndex, false, false)
|
||||
}
|
||||
} else {
|
||||
listener.updateDefaultInterface("", -1)
|
||||
listener.updateDefaultInterface("", -1, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import android.os.CancellationSignal
|
||||
import android.system.ErrnoException
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.hiddify.hiddify.ktx.tryResumeWithException
|
||||
import io.nekohasekai.libbox.ExchangeContext
|
||||
import io.nekohasekai.libbox.LocalDNSTransport
|
||||
import com.hiddify.core.libbox.ExchangeContext
|
||||
import com.hiddify.core.libbox.LocalDNSTransport
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.asExecutor
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@@ -17,12 +17,9 @@ import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
object LocalResolver : LocalDNSTransport {
|
||||
|
||||
private const val RCODE_NXDOMAIN = 3
|
||||
|
||||
override fun raw(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
}
|
||||
override fun raw(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
override fun exchange(ctx: ExchangeContext, message: ByteArray) {
|
||||
@@ -31,52 +28,11 @@ object LocalResolver : LocalDNSTransport {
|
||||
suspendCoroutine { continuation ->
|
||||
val signal = CancellationSignal()
|
||||
ctx.onCancel(signal::cancel)
|
||||
val callback = object : DnsResolver.Callback<ByteArray> {
|
||||
override fun onAnswer(answer: ByteArray, rcode: Int) {
|
||||
if (rcode == 0) {
|
||||
ctx.rawSuccess(answer)
|
||||
} else {
|
||||
ctx.errorCode(rcode)
|
||||
}
|
||||
continuation.resume(Unit)
|
||||
}
|
||||
|
||||
override fun onError(error: DnsResolver.DnsException) {
|
||||
when (val cause = error.cause) {
|
||||
is ErrnoException -> {
|
||||
ctx.errnoCode(cause.errno)
|
||||
continuation.resume(Unit)
|
||||
return
|
||||
}
|
||||
}
|
||||
continuation.tryResumeWithException(error)
|
||||
}
|
||||
}
|
||||
DnsResolver.getInstance().rawQuery(
|
||||
defaultNetwork,
|
||||
message,
|
||||
DnsResolver.FLAG_NO_RETRY,
|
||||
Dispatchers.IO.asExecutor(),
|
||||
signal,
|
||||
callback
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun lookup(ctx: ExchangeContext, network: String, domain: String) {
|
||||
return runBlocking {
|
||||
val defaultNetwork = DefaultNetworkMonitor.require()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
suspendCoroutine { continuation ->
|
||||
val signal = CancellationSignal()
|
||||
ctx.onCancel(signal::cancel)
|
||||
val callback = object : DnsResolver.Callback<Collection<InetAddress>> {
|
||||
@Suppress("ThrowableNotThrown")
|
||||
override fun onAnswer(answer: Collection<InetAddress>, rcode: Int) {
|
||||
val callback =
|
||||
object : DnsResolver.Callback<ByteArray> {
|
||||
override fun onAnswer(answer: ByteArray, rcode: Int) {
|
||||
if (rcode == 0) {
|
||||
ctx.success((answer as Collection<InetAddress?>).mapNotNull { it?.hostAddress }
|
||||
.joinToString("\n"))
|
||||
ctx.rawSuccess(answer)
|
||||
} else {
|
||||
ctx.errorCode(rcode)
|
||||
}
|
||||
@@ -94,11 +50,57 @@ object LocalResolver : LocalDNSTransport {
|
||||
continuation.tryResumeWithException(error)
|
||||
}
|
||||
}
|
||||
val type = when {
|
||||
network.endsWith("4") -> DnsResolver.TYPE_A
|
||||
network.endsWith("6") -> DnsResolver.TYPE_AAAA
|
||||
else -> null
|
||||
}
|
||||
DnsResolver.getInstance().rawQuery(
|
||||
defaultNetwork,
|
||||
message,
|
||||
DnsResolver.FLAG_NO_RETRY,
|
||||
Dispatchers.IO.asExecutor(),
|
||||
signal,
|
||||
callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun lookup(ctx: ExchangeContext, network: String, domain: String) {
|
||||
return runBlocking {
|
||||
val defaultNetwork = DefaultNetworkMonitor.require()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
suspendCoroutine { continuation ->
|
||||
val signal = CancellationSignal()
|
||||
ctx.onCancel(signal::cancel)
|
||||
val callback =
|
||||
object : DnsResolver.Callback<Collection<InetAddress>> {
|
||||
@Suppress("ThrowableNotThrown")
|
||||
override fun onAnswer(answer: Collection<InetAddress>, rcode: Int) {
|
||||
if (rcode == 0) {
|
||||
ctx.success(
|
||||
(answer as Collection<InetAddress?>).mapNotNull { it?.hostAddress }
|
||||
.joinToString("\n"),
|
||||
)
|
||||
} else {
|
||||
ctx.errorCode(rcode)
|
||||
}
|
||||
continuation.resume(Unit)
|
||||
}
|
||||
|
||||
override fun onError(error: DnsResolver.DnsException) {
|
||||
when (val cause = error.cause) {
|
||||
is ErrnoException -> {
|
||||
ctx.errnoCode(cause.errno)
|
||||
continuation.resume(Unit)
|
||||
return
|
||||
}
|
||||
}
|
||||
continuation.tryResumeWithException(error)
|
||||
}
|
||||
}
|
||||
val type =
|
||||
when {
|
||||
network.endsWith("4") -> DnsResolver.TYPE_A
|
||||
network.endsWith("6") -> DnsResolver.TYPE_AAAA
|
||||
else -> null
|
||||
}
|
||||
if (type != null) {
|
||||
DnsResolver.getInstance().query(
|
||||
defaultNetwork,
|
||||
@@ -107,7 +109,7 @@ object LocalResolver : LocalDNSTransport {
|
||||
DnsResolver.FLAG_NO_RETRY,
|
||||
Dispatchers.IO.asExecutor(),
|
||||
signal,
|
||||
callback
|
||||
callback,
|
||||
)
|
||||
} else {
|
||||
DnsResolver.getInstance().query(
|
||||
@@ -116,17 +118,18 @@ object LocalResolver : LocalDNSTransport {
|
||||
DnsResolver.FLAG_NO_RETRY,
|
||||
Dispatchers.IO.asExecutor(),
|
||||
signal,
|
||||
callback
|
||||
callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val answer = try {
|
||||
defaultNetwork.getAllByName(domain)
|
||||
} catch (e: UnknownHostException) {
|
||||
ctx.errorCode(RCODE_NXDOMAIN)
|
||||
return@runBlocking
|
||||
}
|
||||
val answer =
|
||||
try {
|
||||
defaultNetwork.getAllByName(domain)
|
||||
} catch (e: UnknownHostException) {
|
||||
ctx.errorCode(RCODE_NXDOMAIN)
|
||||
return@runBlocking
|
||||
}
|
||||
ctx.success(answer.mapNotNull { it.hostAddress }.joinToString("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,38 @@
|
||||
package com.hiddify.hiddify.bg
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.Build
|
||||
import android.os.Process
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.hiddify.hiddify.Application
|
||||
import io.nekohasekai.libbox.InterfaceUpdateListener
|
||||
import io.nekohasekai.libbox.NetworkInterfaceIterator
|
||||
import io.nekohasekai.libbox.PlatformInterface
|
||||
import io.nekohasekai.libbox.StringIterator
|
||||
import io.nekohasekai.libbox.TunOptions
|
||||
import io.nekohasekai.libbox.WIFIState
|
||||
import com.hiddify.core.libbox.InterfaceUpdateListener
|
||||
import com.hiddify.core.libbox.Libbox
|
||||
import com.hiddify.core.libbox.NetworkInterfaceIterator
|
||||
import com.hiddify.core.libbox.PlatformInterface
|
||||
import com.hiddify.core.libbox.StringIterator
|
||||
import com.hiddify.core.libbox.TunOptions
|
||||
import com.hiddify.core.libbox.WIFIState
|
||||
import java.net.Inet6Address
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.InterfaceAddress
|
||||
import java.net.NetworkInterface
|
||||
import java.util.Enumeration
|
||||
import io.nekohasekai.libbox.NetworkInterface as LibboxNetworkInterface
|
||||
import com.hiddify.core.libbox.NetworkInterface as LibboxNetworkInterface
|
||||
|
||||
|
||||
|
||||
import android.system.OsConstants
|
||||
import com.hiddify.core.libbox.ConnectionOwner
|
||||
import com.hiddify.core.libbox.LocalDNSTransport
|
||||
import java.security.KeyStore
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
interface PlatformInterfaceWrapper : PlatformInterface {
|
||||
|
||||
override fun usePlatformAutoDetectInterfaceControl(): Boolean {
|
||||
return true
|
||||
}
|
||||
override fun usePlatformAutoDetectInterfaceControl(): Boolean = true
|
||||
|
||||
override fun autoDetectInterfaceControl(fd: Int) {
|
||||
}
|
||||
@@ -31,9 +41,7 @@ interface PlatformInterfaceWrapper : PlatformInterface {
|
||||
error("invalid argument")
|
||||
}
|
||||
|
||||
override fun useProcFS(): Boolean {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
||||
}
|
||||
override fun useProcFS(): Boolean = Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
override fun findConnectionOwner(
|
||||
@@ -41,42 +49,30 @@ interface PlatformInterfaceWrapper : PlatformInterface {
|
||||
sourceAddress: String,
|
||||
sourcePort: Int,
|
||||
destinationAddress: String,
|
||||
destinationPort: Int
|
||||
): Int {
|
||||
val uid = Application.connectivity.getConnectionOwnerUid(
|
||||
ipProtocol,
|
||||
InetSocketAddress(sourceAddress, sourcePort),
|
||||
InetSocketAddress(destinationAddress, destinationPort)
|
||||
)
|
||||
if (uid == Process.INVALID_UID) error("android: connection owner not found")
|
||||
return uid
|
||||
}
|
||||
|
||||
override fun packageNameByUid(uid: Int): String {
|
||||
val packages = Application.packageManager.getPackagesForUid(uid)
|
||||
if (packages.isNullOrEmpty()) error("android: package not found")
|
||||
return packages[0]
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun uidByPackageName(packageName: String): Int {
|
||||
return try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Application.packageManager.getPackageUid(
|
||||
packageName, PackageManager.PackageInfoFlags.of(0)
|
||||
destinationPort: Int,
|
||||
): ConnectionOwner {
|
||||
try {
|
||||
val uid =
|
||||
Application.connectivity.getConnectionOwnerUid(
|
||||
ipProtocol,
|
||||
InetSocketAddress(sourceAddress, sourcePort),
|
||||
InetSocketAddress(destinationAddress, destinationPort),
|
||||
)
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Application.packageManager.getPackageUid(packageName, 0)
|
||||
} else {
|
||||
Application.packageManager.getApplicationInfo(packageName, 0).uid
|
||||
}
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
error("android: package not found")
|
||||
}
|
||||
}
|
||||
// if (uid == Process.INVALID_UID)error("android: connection owner not found")
|
||||
|
||||
override fun usePlatformDefaultInterfaceMonitor(): Boolean {
|
||||
return true
|
||||
val owner = ConnectionOwner()
|
||||
owner.userId = uid
|
||||
if (uid!=Process.INVALID_UID) {
|
||||
val packages = Application.packageManager.getPackagesForUid(uid)
|
||||
owner.userName = packages?.firstOrNull() ?: ""
|
||||
owner.androidPackageName = owner.userName
|
||||
}
|
||||
return owner
|
||||
} catch (e: Exception) {
|
||||
Log.e("PlatformInterface", "getConnectionOwnerUid", e)
|
||||
e.printStackTrace(System.err)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
override fun startDefaultInterfaceMonitor(listener: InterfaceUpdateListener) {
|
||||
@@ -87,70 +83,130 @@ interface PlatformInterfaceWrapper : PlatformInterface {
|
||||
DefaultNetworkMonitor.setListener(null)
|
||||
}
|
||||
|
||||
override fun usePlatformInterfaceGetter(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||
}
|
||||
|
||||
override fun getInterfaces(): NetworkInterfaceIterator {
|
||||
return InterfaceArray(NetworkInterface.getNetworkInterfaces())
|
||||
val networks = Application.connectivity.allNetworks
|
||||
val networkInterfaces = NetworkInterface.getNetworkInterfaces().toList()
|
||||
val interfaces = mutableListOf<LibboxNetworkInterface>()
|
||||
for (network in networks) {
|
||||
val boxInterface = LibboxNetworkInterface()
|
||||
val linkProperties = Application.connectivity.getLinkProperties(network) ?: continue
|
||||
val networkCapabilities =
|
||||
Application.connectivity.getNetworkCapabilities(network) ?: continue
|
||||
boxInterface.name = linkProperties.interfaceName
|
||||
val networkInterface =
|
||||
networkInterfaces.find { it.name == boxInterface.name } ?: continue
|
||||
boxInterface.dnsServer =
|
||||
StringArray(linkProperties.dnsServers.mapNotNull { it.hostAddress }.iterator())
|
||||
boxInterface.type =
|
||||
when {
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> Libbox.InterfaceTypeWIFI
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> Libbox.InterfaceTypeCellular
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> Libbox.InterfaceTypeEthernet
|
||||
else -> Libbox.InterfaceTypeOther
|
||||
}
|
||||
boxInterface.index = networkInterface.index
|
||||
runCatching {
|
||||
boxInterface.mtu = networkInterface.mtu
|
||||
}.onFailure {
|
||||
Log.e(
|
||||
"PlatformInterface",
|
||||
"failed to get mtu for interface ${boxInterface.name}",
|
||||
it,
|
||||
)
|
||||
}
|
||||
boxInterface.addresses =
|
||||
StringArray(
|
||||
networkInterface.interfaceAddresses.mapTo(mutableListOf()) { it.toPrefix() }
|
||||
.iterator(),
|
||||
)
|
||||
var dumpFlags = 0
|
||||
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
|
||||
dumpFlags = OsConstants.IFF_UP or OsConstants.IFF_RUNNING
|
||||
}
|
||||
if (networkInterface.isLoopback) {
|
||||
dumpFlags = dumpFlags or OsConstants.IFF_LOOPBACK
|
||||
}
|
||||
if (networkInterface.isPointToPoint) {
|
||||
dumpFlags = dumpFlags or OsConstants.IFF_POINTOPOINT
|
||||
}
|
||||
if (networkInterface.supportsMulticast()) {
|
||||
dumpFlags = dumpFlags or OsConstants.IFF_MULTICAST
|
||||
}
|
||||
boxInterface.flags = dumpFlags
|
||||
boxInterface.metered =
|
||||
!networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
|
||||
interfaces.add(boxInterface)
|
||||
}
|
||||
return InterfaceArray(interfaces.iterator())
|
||||
}
|
||||
|
||||
override fun underNetworkExtension(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun includeAllNetworks(): Boolean {
|
||||
return false
|
||||
}
|
||||
override fun underNetworkExtension(): Boolean = false
|
||||
|
||||
override fun includeAllNetworks(): Boolean = false
|
||||
|
||||
override fun clearDNSCache() {
|
||||
}
|
||||
|
||||
override fun readWIFIState(): WIFIState? {
|
||||
return null
|
||||
@Suppress("DEPRECATION")
|
||||
val wifiInfo =
|
||||
Application.wifiManager.connectionInfo ?: return null
|
||||
var ssid = wifiInfo.ssid
|
||||
if (ssid == "<unknown ssid>") {
|
||||
return WIFIState("", "")
|
||||
}
|
||||
if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
|
||||
ssid = ssid.substring(1, ssid.length - 1)
|
||||
}
|
||||
return WIFIState(ssid, wifiInfo.bssid)
|
||||
}
|
||||
|
||||
private class InterfaceArray(private val iterator: Enumeration<NetworkInterface>) :
|
||||
NetworkInterfaceIterator {
|
||||
override fun localDNSTransport(): LocalDNSTransport? = LocalResolver
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return iterator.hasMoreElements()
|
||||
}
|
||||
|
||||
override fun next(): LibboxNetworkInterface {
|
||||
val element = iterator.nextElement()
|
||||
return LibboxNetworkInterface().apply {
|
||||
name = element.name
|
||||
index = element.index
|
||||
runCatching {
|
||||
mtu = element.mtu
|
||||
}
|
||||
addresses =
|
||||
StringArray(
|
||||
element.interfaceAddresses.mapTo(mutableListOf()) { it.toPrefix() }
|
||||
.iterator()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun InterfaceAddress.toPrefix(): String {
|
||||
return if (address is Inet6Address) {
|
||||
"${Inet6Address.getByAddress(address.address).hostAddress}/${networkPrefixLength}"
|
||||
} else {
|
||||
"${address.hostAddress}/${networkPrefixLength}"
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
override fun systemCertificates(): StringIterator {
|
||||
val certificates = mutableListOf<String>()
|
||||
val keyStore = KeyStore.getInstance("AndroidCAStore")
|
||||
if (keyStore != null) {
|
||||
keyStore.load(null, null)
|
||||
val aliases = keyStore.aliases()
|
||||
while (aliases.hasMoreElements()) {
|
||||
val cert = keyStore.getCertificate(aliases.nextElement())
|
||||
certificates.add(
|
||||
"-----BEGIN CERTIFICATE-----\n" + Base64.encode(cert.encoded) + "\n-----END CERTIFICATE-----",
|
||||
)
|
||||
}
|
||||
}
|
||||
return StringArray(certificates.iterator())
|
||||
}
|
||||
|
||||
private class StringArray(private val iterator: Iterator<String>) : StringIterator {
|
||||
private class InterfaceArray(private val iterator: Iterator<LibboxNetworkInterface>) : NetworkInterfaceIterator {
|
||||
override fun hasNext(): Boolean = iterator.hasNext()
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return iterator.hasNext()
|
||||
}
|
||||
|
||||
override fun next(): String {
|
||||
return iterator.next()
|
||||
}
|
||||
override fun next(): LibboxNetworkInterface = iterator.next()
|
||||
}
|
||||
|
||||
class StringArray(private val iterator: Iterator<String>) : StringIterator {
|
||||
override fun len(): Int {
|
||||
// not used by core
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = iterator.hasNext()
|
||||
|
||||
override fun next(): String = iterator.next()
|
||||
}
|
||||
|
||||
private fun InterfaceAddress.toPrefix(): String = if (address is Inet6Address) {
|
||||
"${Inet6Address.getByAddress(address.address).hostAddress}/$networkPrefixLength"
|
||||
} else {
|
||||
"${address.hostAddress}/$networkPrefixLength"
|
||||
}
|
||||
|
||||
private val NetworkInterface.flags: Int
|
||||
@SuppressLint("SoonBlockedPrivateApi")
|
||||
get() {
|
||||
val getFlagsMethod = NetworkInterface::class.java.getDeclaredMethod("getFlags")
|
||||
return getFlagsMethod.invoke(this) as Int
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,18 @@ package com.hiddify.hiddify.bg
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import com.hiddify.core.libbox.Notification
|
||||
|
||||
class ProxyService : Service(), PlatformInterfaceWrapper {
|
||||
|
||||
class ProxyService :
|
||||
Service(),
|
||||
PlatformInterfaceWrapper {
|
||||
private val service = BoxService(this, this)
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) =
|
||||
service.onStartCommand(intent, flags, startId)
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) = service.onStartCommand()
|
||||
|
||||
override fun onBind(intent: Intent) = service.onBind(intent)
|
||||
|
||||
override fun onDestroy() = service.onDestroy()
|
||||
|
||||
override fun writeLog(message: String) = service.writeLog(message)
|
||||
override fun sendNotification(notification: Notification) = service.sendNotification(notification)
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import androidx.lifecycle.MutableLiveData
|
||||
import com.hiddify.hiddify.IService
|
||||
import com.hiddify.hiddify.IServiceCallback
|
||||
import com.hiddify.hiddify.constant.Status
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
class ServiceBinder(private val status: MutableLiveData<Status>) : IService.Stub() {
|
||||
private val callbacks = RemoteCallbackList<IServiceCallback>()
|
||||
private val broadcastLock = Mutex()
|
||||
@@ -23,6 +23,7 @@ class ServiceBinder(private val status: MutableLiveData<Status>) : IService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun broadcast(work: (IServiceCallback) -> Unit) {
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
broadcastLock.withLock {
|
||||
@@ -41,9 +42,7 @@ class ServiceBinder(private val status: MutableLiveData<Status>) : IService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
override fun getStatus(): Int {
|
||||
return (status.value ?: Status.Stopped).ordinal
|
||||
}
|
||||
override fun getStatus(): Int = (status.value ?: Status.Stopped).ordinal
|
||||
|
||||
override fun registerCallback(callback: IServiceCallback) {
|
||||
callbacks.register(callback)
|
||||
@@ -56,4 +55,4 @@ class ServiceBinder(private val status: MutableLiveData<Status>) : IService.Stub
|
||||
fun close() {
|
||||
callbacks.kill()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,8 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ServiceConnection(
|
||||
private val context: Context,
|
||||
callback: Callback,
|
||||
private val register: Boolean = true,
|
||||
) : ServiceConnection {
|
||||
|
||||
class ServiceConnection(private val context: Context, callback: Callback, private val register: Boolean = true) : ServiceConnection {
|
||||
companion object {
|
||||
private const val TAG = "ServiceConnection"
|
||||
}
|
||||
@@ -34,12 +30,14 @@ class ServiceConnection(
|
||||
val status get() = service?.status?.let { Status.values()[it] } ?: Status.Stopped
|
||||
|
||||
fun connect() {
|
||||
val intent = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
Intent(context, Settings.serviceClass()).setAction(Action.SERVICE)
|
||||
val intent =
|
||||
runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
Intent(context, Settings.serviceClass()).setAction(Action.SERVICE)
|
||||
}
|
||||
}
|
||||
}
|
||||
context.bindService(intent, this, AppCompatActivity.BIND_AUTO_CREATE)
|
||||
Log.d(TAG, "request connect")
|
||||
}
|
||||
|
||||
fun disconnect() {
|
||||
@@ -47,6 +45,7 @@ class ServiceConnection(
|
||||
context.unbindService(this)
|
||||
} catch (_: IllegalArgumentException) {
|
||||
}
|
||||
Log.d(TAG, "request disconnect")
|
||||
}
|
||||
|
||||
fun reconnect() {
|
||||
@@ -54,12 +53,14 @@ class ServiceConnection(
|
||||
context.unbindService(this)
|
||||
} catch (_: IllegalArgumentException) {
|
||||
}
|
||||
val intent = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
Intent(context, Settings.serviceClass()).setAction(Action.SERVICE)
|
||||
val intent =
|
||||
runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
Intent(context, Settings.serviceClass()).setAction(Action.SERVICE)
|
||||
}
|
||||
}
|
||||
}
|
||||
context.bindService(intent, this, AppCompatActivity.BIND_AUTO_CREATE)
|
||||
Log.d(TAG, "request reconnect")
|
||||
}
|
||||
|
||||
override fun onServiceConnected(name: ComponentName, binder: IBinder) {
|
||||
@@ -71,6 +72,7 @@ class ServiceConnection(
|
||||
} catch (e: RemoteException) {
|
||||
Log.e(TAG, "initialize service connection", e)
|
||||
}
|
||||
Log.d(TAG, "service connected")
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
@@ -79,17 +81,19 @@ class ServiceConnection(
|
||||
} catch (e: RemoteException) {
|
||||
Log.e(TAG, "cleanup service connection", e)
|
||||
}
|
||||
Log.d(TAG, "service disconnected")
|
||||
}
|
||||
|
||||
override fun onBindingDied(name: ComponentName?) {
|
||||
reconnect()
|
||||
Log.d(TAG, "service dead")
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onServiceStatusChanged(status: Status)
|
||||
fun onServiceAlert(type: Alert, message: String?) {}
|
||||
fun onServiceWriteLog(message: String?) {}
|
||||
fun onServiceResetLogs(messages: MutableList<String>) {}
|
||||
|
||||
fun onServiceAlert(type: Alert, message: String?) {
|
||||
}
|
||||
}
|
||||
|
||||
class ServiceCallback(private val callback: Callback) : IServiceCallback.Stub() {
|
||||
@@ -101,9 +105,12 @@ class ServiceConnection(
|
||||
callback.onServiceAlert(Alert.values()[type], message)
|
||||
}
|
||||
|
||||
override fun onServiceWriteLog(message: String?) = callback.onServiceWriteLog(message)
|
||||
override fun onServiceWriteLog(message: String?) {
|
||||
//TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onServiceResetLogs(messages: MutableList<String>) =
|
||||
callback.onServiceResetLogs(messages)
|
||||
override fun onServiceResetLogs(messages: List<String?>?) {
|
||||
//TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,29 +9,50 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.hiddify.core.api.v2.config.Protocol
|
||||
import com.hiddify.core.api.v2.hcommon.Empty
|
||||
import com.hiddify.core.api.v2.hcore.CoreClient
|
||||
import com.hiddify.core.api.v2.hcore.SystemInfo
|
||||
import com.hiddify.core.api.v2.hello.HelloClient
|
||||
import com.hiddify.core.api.v2.hello.HelloRequest
|
||||
import com.hiddify.hiddify.Application
|
||||
import com.hiddify.hiddify.MainActivity
|
||||
import com.hiddify.hiddify.R
|
||||
import com.hiddify.hiddify.Settings
|
||||
import com.hiddify.hiddify.constant.Action
|
||||
import com.hiddify.hiddify.constant.Status
|
||||
import com.hiddify.hiddify.utils.CommandClient
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.StatusMessage
|
||||
//import com.hiddify.hiddify.utils.CommandClient
|
||||
import com.hiddify.core.libbox.Libbox
|
||||
import com.hiddify.hiddify.Application.Companion.notification
|
||||
import com.hiddify.hiddify.utils.GrpcClientProvider
|
||||
import com.squareup.wire.GrpcClient
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.isActive
|
||||
|
||||
class ServiceNotification(private val status: MutableLiveData<Status>, private val service: Service) : BroadcastReceiver(), CommandClient.Handler {
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.CancellationException
|
||||
class ServiceNotification(private val status: MutableLiveData<Status>, private val service: Service) : BroadcastReceiver(){
|
||||
companion object {
|
||||
private const val notificationId = 1
|
||||
private const val notificationChannel = "service"
|
||||
private val flags =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
|
||||
var coreClient: CoreClient?=null
|
||||
val flags =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
|
||||
|
||||
fun checkPermission(): Boolean {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
@@ -40,10 +61,12 @@ class ServiceNotification(private val status: MutableLiveData<Status>, private v
|
||||
return Application.notification.areNotificationsEnabled()
|
||||
}
|
||||
}
|
||||
val streamingCoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
|
||||
private val commandClient =
|
||||
CommandClient(GlobalScope, CommandClient.ConnectionType.Status, this)
|
||||
//
|
||||
// private val commandClient =
|
||||
// CommandClient(GlobalScope, CommandClient.ConnectionType.Status, this)
|
||||
private var receiverRegistered = false
|
||||
|
||||
|
||||
@@ -72,7 +95,9 @@ class ServiceNotification(private val status: MutableLiveData<Status>, private v
|
||||
0, service.getText(R.string.stop), PendingIntent.getBroadcast(
|
||||
service,
|
||||
0,
|
||||
Intent(Action.SERVICE_CLOSE).setPackage(service.packageName),
|
||||
Intent(Action.SERVICE_CLOSE).setPackage(
|
||||
Application.application.packageName
|
||||
),
|
||||
flags
|
||||
)
|
||||
).build()
|
||||
@@ -97,8 +122,9 @@ class ServiceNotification(private val status: MutableLiveData<Status>, private v
|
||||
|
||||
|
||||
suspend fun start() {
|
||||
if (Settings.dynamicNotification) {
|
||||
commandClient.connect()
|
||||
if (Settings.dynamicNotification && checkPermission()) {
|
||||
// commandClient.connect()
|
||||
startListenSystemInfo()
|
||||
withContext(Dispatchers.Main) {
|
||||
registerReceiver()
|
||||
}
|
||||
@@ -113,33 +139,74 @@ class ServiceNotification(private val status: MutableLiveData<Status>, private v
|
||||
receiverRegistered = true
|
||||
}
|
||||
|
||||
override fun updateStatus(status: StatusMessage) {
|
||||
val content =
|
||||
Libbox.formatBytes(status.uplink) + "/s ↑\t" + Libbox.formatBytes(status.downlink) + "/s ↓"
|
||||
fun updateStatus(previous:SystemInfo,status: SystemInfo) {
|
||||
val uplink=status.uplink_total - previous.uplink_total
|
||||
val downlink=status.downlink_total - previous.downlink_total
|
||||
val content = "${Libbox.formatBytes(uplink)}/s ↑\t${Libbox.formatBytes(downlink)}/s ↓ \n${status.current_outbound}"
|
||||
val title = "${status.current_profile}"
|
||||
Application.notificationManager.notify(
|
||||
notificationId,
|
||||
notificationBuilder.setContentText(content).build()
|
||||
notificationBuilder.setContentTitle(title).setContentText(content).build()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (intent.action) {
|
||||
Intent.ACTION_SCREEN_ON -> {
|
||||
commandClient.connect()
|
||||
startListenSystemInfo()
|
||||
}
|
||||
|
||||
Intent.ACTION_SCREEN_OFF -> {
|
||||
commandClient.disconnect()
|
||||
stopListenSystemInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun close() {
|
||||
commandClient.disconnect()
|
||||
stopListenSystemInfo()
|
||||
ServiceCompat.stopForeground(service, ServiceCompat.STOP_FOREGROUND_REMOVE)
|
||||
if (receiverRegistered) {
|
||||
service.unregisterReceiver(this)
|
||||
receiverRegistered = false
|
||||
}
|
||||
}
|
||||
|
||||
private var streamingJob: Job? = null
|
||||
|
||||
fun startListenSystemInfo() {
|
||||
// Cancel any previous stream if still running
|
||||
Log.d("notification","startListenSystemInfo")
|
||||
streamingJob?.cancel()
|
||||
|
||||
streamingJob = streamingCoroutineScope.launch(Dispatchers.IO) {
|
||||
Log.d("notification", "startListenSystemInfo-launch")
|
||||
|
||||
val coreClient = GrpcClientProvider.grpcClient.create(CoreClient::class)
|
||||
|
||||
try {
|
||||
var previous = coreClient.GetSystemInfo().executeBlocking(Empty())
|
||||
|
||||
while (isActive) {
|
||||
delay(1_000) // ✅ coroutine-friendly
|
||||
val current = coreClient.GetSystemInfo().executeBlocking(Empty())
|
||||
updateStatus(previous,current)
|
||||
previous = current
|
||||
}
|
||||
} catch (e: CancellationException) {
|
||||
// coroutine cancelled normally
|
||||
Log.d("notification", "SystemInfo polling cancelled")
|
||||
notification.cancel(notificationId)
|
||||
} catch (e: Exception) {
|
||||
Log.e("notification", "SystemInfo polling failed", e)
|
||||
notification.cancel(notificationId)
|
||||
}
|
||||
}
|
||||
}
|
||||
fun stopListenSystemInfo(){
|
||||
try {
|
||||
streamingJob?.cancel()
|
||||
}catch (e: Exception){
|
||||
Log.d("notification", "Exception ${e}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,22 @@
|
||||
package com.hiddify.hiddify.bg
|
||||
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.hiddify.hiddify.Application
|
||||
import com.hiddify.hiddify.MainActivity
|
||||
import com.hiddify.hiddify.Settings
|
||||
import com.hiddify.hiddify.constant.ServiceMode
|
||||
import com.hiddify.hiddify.constant.Status
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@RequiresApi(24)
|
||||
class TileService : TileService(), ServiceConnection.Callback {
|
||||
@@ -12,11 +25,12 @@ class TileService : TileService(), ServiceConnection.Callback {
|
||||
|
||||
override fun onServiceStatusChanged(status: Status) {
|
||||
qsTile?.apply {
|
||||
state = when (status) {
|
||||
Status.Started -> Tile.STATE_ACTIVE
|
||||
Status.Stopped -> Tile.STATE_INACTIVE
|
||||
else -> Tile.STATE_UNAVAILABLE
|
||||
}
|
||||
state =
|
||||
when (status) {
|
||||
Status.Started -> Tile.STATE_ACTIVE
|
||||
Status.Stopped -> Tile.STATE_INACTIVE
|
||||
else -> Tile.STATE_UNAVAILABLE
|
||||
}
|
||||
updateTile()
|
||||
}
|
||||
}
|
||||
@@ -30,19 +44,36 @@ class TileService : TileService(), ServiceConnection.Callback {
|
||||
connection.disconnect()
|
||||
super.onStopListening()
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
private fun toggleService() {
|
||||
when (connection.status) {
|
||||
Status.Stopped -> {
|
||||
Settings.startCoreAfterStartingService = true
|
||||
BoxService.start()
|
||||
qsTile?.apply {
|
||||
state = Tile.STATE_ACTIVE
|
||||
updateTile()
|
||||
}
|
||||
}
|
||||
|
||||
Status.Started -> {
|
||||
BoxService.stop()
|
||||
qsTile?.apply {
|
||||
state = Tile.STATE_INACTIVE
|
||||
updateTile()
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
||||
if (keyguardManager.isKeyguardLocked) {
|
||||
unlockAndRun {
|
||||
toggleService()
|
||||
}
|
||||
} else {
|
||||
toggleService()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,9 +8,11 @@ import android.net.ProxyInfo
|
||||
import android.net.VpnService
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.os.ParcelFileDescriptor
|
||||
import com.hiddify.core.libbox.Notification
|
||||
import com.hiddify.hiddify.constant.PerAppProxyMode
|
||||
import com.hiddify.hiddify.ktx.toIpPrefix
|
||||
import io.nekohasekai.libbox.TunOptions
|
||||
import com.hiddify.core.libbox.TunOptions
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -24,7 +26,7 @@ class VPNService : VpnService(), PlatformInterfaceWrapper {
|
||||
private val service = BoxService(this, this)
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) =
|
||||
service.onStartCommand(intent, flags, startId)
|
||||
service.onStartCommand()
|
||||
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
val binder = super.onBind(intent)
|
||||
@@ -73,10 +75,24 @@ class VPNService : VpnService(), PlatformInterfaceWrapper {
|
||||
}
|
||||
|
||||
override fun openTun(options: TunOptions): Int {
|
||||
if (prepare(this) != null) error("android: missing vpn permission")
|
||||
var hasPermission = false
|
||||
for (i in 0 until 20) {
|
||||
if (prepare(this) != null) {
|
||||
Log.w("VPN", "android: missing vpn permission")
|
||||
} else {
|
||||
hasPermission = true
|
||||
break
|
||||
}
|
||||
Thread.sleep(50)
|
||||
}
|
||||
|
||||
if (!hasPermission) {
|
||||
error("android: missing vpn permission")
|
||||
}
|
||||
// service.fileDescriptor?.close()
|
||||
|
||||
val builder = Builder()
|
||||
.setSession("sing-box")
|
||||
.setSession("hiddify")
|
||||
.setMtu(options.mtu)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
@@ -96,7 +112,7 @@ class VPNService : VpnService(), PlatformInterfaceWrapper {
|
||||
}
|
||||
|
||||
if (options.autoRoute) {
|
||||
builder.addDnsServer(options.dnsServerAddress)
|
||||
builder.addDnsServer(options.dnsServerAddress.value)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
val inet4RouteAddress = options.inet4RouteAddress
|
||||
@@ -150,12 +166,12 @@ class VPNService : VpnService(), PlatformInterfaceWrapper {
|
||||
appList.forEach {
|
||||
addIncludePackage(builder,it)
|
||||
}
|
||||
addIncludePackage(builder,packageName)
|
||||
// addIncludePackage(builder,packageName)
|
||||
} else {
|
||||
appList.forEach {
|
||||
addExcludePackage(builder,it)
|
||||
}
|
||||
//addExcludePackage(builder,packageName)
|
||||
addExcludePackage(builder,packageName)
|
||||
}
|
||||
} else {
|
||||
val includePackage = options.includePackage
|
||||
@@ -163,14 +179,17 @@ class VPNService : VpnService(), PlatformInterfaceWrapper {
|
||||
while (includePackage.hasNext()) {
|
||||
addIncludePackage(builder,includePackage.next())
|
||||
}
|
||||
}
|
||||
val excludePackage = options.excludePackage
|
||||
if (excludePackage.hasNext()) {
|
||||
while (excludePackage.hasNext()) {
|
||||
addExcludePackage(builder,excludePackage.next())
|
||||
// addIncludePackage(builder,packageName)
|
||||
}else {
|
||||
val excludePackage = options.excludePackage
|
||||
if (excludePackage.hasNext()) {
|
||||
while (excludePackage.hasNext()) {
|
||||
addExcludePackage(builder, excludePackage.next())
|
||||
}
|
||||
}
|
||||
|
||||
addExcludePackage(builder, packageName)
|
||||
}
|
||||
//addExcludePackage(builder,packageName)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -188,12 +207,14 @@ class VPNService : VpnService(), PlatformInterfaceWrapper {
|
||||
systemProxyEnabled = false
|
||||
}
|
||||
|
||||
val pfd =
|
||||
builder.establish() ?: error("android: the application is not prepared or is revoked")
|
||||
val pfd = builder.establish() ?: error("android: the application is not prepared or is revoked")
|
||||
service.fileDescriptor = pfd
|
||||
return pfd.fd
|
||||
}
|
||||
|
||||
override fun writeLog(message: String) = service.writeLog(message)
|
||||
// override fun writeLog(message: String) = service.writeLog(message)
|
||||
|
||||
override fun sendNotification(notification: Notification) {
|
||||
// service.sendNotification(notification)
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,4 @@ package com.hiddify.hiddify.constant
|
||||
object Action {
|
||||
const val SERVICE = "com.hiddify.app.SERVICE"
|
||||
const val SERVICE_CLOSE = "com.hiddify.app.SERVICE_CLOSE"
|
||||
const val SERVICE_RELOAD = "com.hiddify.app.sfa.SERVICE_RELOAD"
|
||||
}
|
||||
@@ -21,4 +21,12 @@ object SettingsKey {
|
||||
const val STARTED_BY_USER = "${KEY_PREFIX}started_by_user"
|
||||
const val CONFIG_OPTIONS = "config_options_json"
|
||||
|
||||
const val START_CORE_ON_STARTING_SERVICE = "${KEY_PREFIX}starting_core_on_starting_service"
|
||||
|
||||
const val WORKING_DIR = "working_dir"
|
||||
const val BASE_DIR = "base_dir"
|
||||
const val TMP_DIR = "tmp_dir"
|
||||
|
||||
const val GRPC_PORT = "grpc_port"
|
||||
const val GRPC_FLUTTER_PUBLIC_KEY = "grpc_flutter_public_key"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.hiddify.hiddify.constant
|
||||
|
||||
|
||||
import android.os.Build
|
||||
import com.hiddify.hiddify.BuildConfig
|
||||
|
||||
|
||||
object Bugs {
|
||||
|
||||
// TODO: remove launch after fixed
|
||||
// https://github.com/golang/go/issues/68760
|
||||
val fixAndroidStack = BuildConfig.DEBUG ||
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1 ||
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
|
||||
|
||||
}
|
||||
@@ -3,10 +3,17 @@ package com.hiddify.hiddify.ktx
|
||||
import android.net.IpPrefix
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import io.nekohasekai.libbox.RoutePrefix
|
||||
import io.nekohasekai.libbox.StringIterator
|
||||
import com.hiddify.core.libbox.RoutePrefix
|
||||
import com.hiddify.core.libbox.StringIterator
|
||||
import com.hiddify.core.libbox.StringBox
|
||||
import java.net.InetAddress
|
||||
|
||||
val StringBox?.unwrap: String
|
||||
get() {
|
||||
if (this == null) return ""
|
||||
return value
|
||||
}
|
||||
|
||||
fun StringIterator.toList(): List<String> {
|
||||
return mutableListOf<String>().apply {
|
||||
while (hasNext()) {
|
||||
|
||||
@@ -1,139 +1,150 @@
|
||||
package com.hiddify.hiddify.utils
|
||||
|
||||
import go.Seq
|
||||
import io.nekohasekai.libbox.CommandClient
|
||||
import io.nekohasekai.libbox.CommandClientHandler
|
||||
import io.nekohasekai.libbox.CommandClientOptions
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import io.nekohasekai.libbox.OutboundGroupIterator
|
||||
import io.nekohasekai.libbox.StatusMessage
|
||||
import io.nekohasekai.libbox.StringIterator
|
||||
import com.hiddify.core.libbox.CommandClient
|
||||
import com.hiddify.core.libbox.CommandClientHandler
|
||||
import com.hiddify.core.libbox.CommandClientOptions
|
||||
import com.hiddify.core.libbox.Connections
|
||||
import com.hiddify.core.libbox.Libbox
|
||||
import com.hiddify.core.libbox.OutboundGroup
|
||||
import com.hiddify.core.libbox.OutboundGroupIterator
|
||||
import com.hiddify.core.libbox.StatusMessage
|
||||
import com.hiddify.core.libbox.StringIterator
|
||||
import com.hiddify.hiddify.ktx.toList
|
||||
import go.Seq
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
open class CommandClient(
|
||||
private val scope: CoroutineScope,
|
||||
private val connectionType: ConnectionType,
|
||||
private val handler: Handler
|
||||
) {
|
||||
|
||||
enum class ConnectionType {
|
||||
Status, Groups, Log, ClashMode, GroupOnly
|
||||
}
|
||||
|
||||
interface Handler {
|
||||
|
||||
fun onConnected() {}
|
||||
fun onDisconnected() {}
|
||||
fun updateStatus(status: StatusMessage) {}
|
||||
fun updateGroups(groups: List<OutboundGroup>) {}
|
||||
fun clearLog() {}
|
||||
fun appendLog(message: String) {}
|
||||
fun initializeClashMode(modeList: List<String>, currentMode: String) {}
|
||||
fun updateClashMode(newMode: String) {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private var commandClient: CommandClient? = null
|
||||
private val clientHandler = ClientHandler()
|
||||
fun connect() {
|
||||
disconnect()
|
||||
val options = CommandClientOptions()
|
||||
options.command = when (connectionType) {
|
||||
ConnectionType.Status -> Libbox.CommandStatus
|
||||
ConnectionType.Groups -> Libbox.CommandGroup
|
||||
ConnectionType.Log -> Libbox.CommandLog
|
||||
ConnectionType.ClashMode -> Libbox.CommandClashMode
|
||||
ConnectionType.GroupOnly -> Libbox.CommandGroupInfoOnly
|
||||
}
|
||||
options.statusInterval = 2 * 1000 * 1000 * 1000
|
||||
val commandClient = CommandClient(clientHandler, options)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
for (i in 1..10) {
|
||||
delay(100 + i.toLong() * 50)
|
||||
try {
|
||||
commandClient.connect()
|
||||
} catch (ignored: Exception) {
|
||||
continue
|
||||
}
|
||||
if (!isActive) {
|
||||
runCatching {
|
||||
commandClient.disconnect()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
this@CommandClient.commandClient = commandClient
|
||||
return@launch
|
||||
}
|
||||
runCatching {
|
||||
commandClient.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun disconnect() {
|
||||
commandClient?.apply {
|
||||
runCatching {
|
||||
disconnect()
|
||||
}
|
||||
Seq.destroyRef(refnum)
|
||||
}
|
||||
commandClient = null
|
||||
}
|
||||
|
||||
private inner class ClientHandler : CommandClientHandler {
|
||||
|
||||
override fun connected() {
|
||||
handler.onConnected()
|
||||
}
|
||||
|
||||
override fun disconnected(message: String?) {
|
||||
handler.onDisconnected()
|
||||
}
|
||||
|
||||
override fun writeGroups(message: OutboundGroupIterator?) {
|
||||
if (message == null) {
|
||||
return
|
||||
}
|
||||
val groups = mutableListOf<OutboundGroup>()
|
||||
while (message.hasNext()) {
|
||||
groups.add(message.next())
|
||||
}
|
||||
handler.updateGroups(groups)
|
||||
}
|
||||
|
||||
override fun clearLog() {
|
||||
handler.clearLog()
|
||||
}
|
||||
|
||||
override fun writeLog(message: String?) {
|
||||
if (message == null) {
|
||||
return
|
||||
}
|
||||
handler.appendLog(message)
|
||||
}
|
||||
|
||||
override fun writeStatus(message: StatusMessage?) {
|
||||
if (message == null) {
|
||||
return
|
||||
}
|
||||
handler.updateStatus(message)
|
||||
}
|
||||
|
||||
override fun initializeClashMode(modeList: StringIterator, currentMode: String) {
|
||||
handler.initializeClashMode(modeList.toList(), currentMode)
|
||||
}
|
||||
|
||||
override fun updateClashMode(newMode: String) {
|
||||
handler.updateClashMode(newMode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//open class CommandClient(
|
||||
// private val scope: CoroutineScope,
|
||||
// private val connectionType: ConnectionType,
|
||||
// private val handler: Handler
|
||||
//) {
|
||||
//
|
||||
// enum class ConnectionType {
|
||||
// Status, Groups, Log, ClashMode, GroupOnly
|
||||
// }
|
||||
//
|
||||
// interface Handler {
|
||||
//
|
||||
// fun onConnected() {}
|
||||
// fun onDisconnected() {}
|
||||
// fun updateStatus(status: StatusMessage) {}
|
||||
// fun updateGroups(groups: List<OutboundGroup>) {}
|
||||
// fun clearLog() {}
|
||||
// fun appendLog(message: String) {}
|
||||
// fun initializeClashMode(modeList: List<String>, currentMode: String) {}
|
||||
// fun updateClashMode(newMode: String) {}
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private var commandClient: CommandClient? = null
|
||||
// private val clientHandler = ClientHandler()
|
||||
// fun connect() {
|
||||
// disconnect()
|
||||
// val options = CommandClientOptions()
|
||||
// options.command = when (connectionType) {
|
||||
// ConnectionType.Status -> Libbox.CommandStatus
|
||||
// ConnectionType.Groups -> Libbox.CommandGroup
|
||||
// ConnectionType.Log -> Libbox.CommandLog
|
||||
// ConnectionType.ClashMode -> Libbox.CommandClashMode
|
||||
// ConnectionType.GroupOnly -> Libbox.CommandGroupInfoOnly
|
||||
// }
|
||||
// options.statusInterval = 2 * 1000 * 1000 * 1000
|
||||
// val commandClient = CommandClient(clientHandler, options)
|
||||
// scope.launch(Dispatchers.IO) {
|
||||
// for (i in 1..10) {
|
||||
// delay(100 + i.toLong() * 50)
|
||||
// try {
|
||||
// commandClient.connect()
|
||||
// } catch (ignored: Exception) {
|
||||
// continue
|
||||
// }
|
||||
// if (!isActive) {
|
||||
// runCatching {
|
||||
// commandClient.disconnect()
|
||||
// }
|
||||
// return@launch
|
||||
// }
|
||||
// this@CommandClient.commandClient = commandClient
|
||||
// return@launch
|
||||
// }
|
||||
// runCatching {
|
||||
// commandClient.disconnect()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun disconnect() {
|
||||
// commandClient?.apply {
|
||||
// runCatching {
|
||||
// disconnect()
|
||||
// }
|
||||
// Seq.destroyRef(refnum)
|
||||
// }
|
||||
// commandClient = null
|
||||
// }
|
||||
//
|
||||
// private inner class ClientHandler : CommandClientHandler {
|
||||
//
|
||||
// override fun connected() {
|
||||
// handler.onConnected()
|
||||
// }
|
||||
//
|
||||
// override fun disconnected(message: String?) {
|
||||
// handler.onDisconnected()
|
||||
// }
|
||||
//
|
||||
// override fun writeGroups(message: OutboundGroupIterator?) {
|
||||
// if (message == null) {
|
||||
// return
|
||||
// }
|
||||
// val groups = mutableListOf<OutboundGroup>()
|
||||
// while (message.hasNext()) {
|
||||
// groups.add(message.next())
|
||||
// }
|
||||
// handler.updateGroups(groups)
|
||||
// }
|
||||
//
|
||||
// override fun clearLogs() {
|
||||
// handler.clearLog()
|
||||
// }
|
||||
// override fun writeLogs(messageList: StringIterator?) {
|
||||
//
|
||||
// if (messageList == null) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
//
|
||||
// while (messageList.hasNext()) {
|
||||
// handler.appendLog(messageList.next())
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun writeStatus(message: StatusMessage?) {
|
||||
// if (message == null) {
|
||||
// return
|
||||
// }
|
||||
// handler.updateStatus(message)
|
||||
// }
|
||||
//
|
||||
// override fun initializeClashMode(modeList: StringIterator, currentMode: String) {
|
||||
// handler.initializeClashMode(modeList.toList(), currentMode)
|
||||
// }
|
||||
//
|
||||
// override fun updateClashMode(newMode: String) {
|
||||
// handler.updateClashMode(newMode)
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// override fun writeConnections(message: Connections?) {
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.hiddify.hiddify.utils
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.hiddify.core.api.v2.hcore.CoreClient
|
||||
import com.hiddify.hiddify.Settings
|
||||
import com.squareup.wire.GrpcClient
|
||||
import io.grpc.CallOptions
|
||||
import io.grpc.ManagedChannelBuilder
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.security.GeneralSecurityException
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.time.Duration
|
||||
import java.util.Arrays
|
||||
import javax.net.ssl.KeyManagerFactory
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLSocketFactory
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Protocol
|
||||
import okhttp3.Protocol.HTTP_1_1
|
||||
import okhttp3.Protocol.HTTP_2
|
||||
import okio.Buffer
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object GrpcClientProvider {
|
||||
private val okHttpClient = OkHttpClient.Builder()
|
||||
.protocols(listOf(Protocol.H2_PRIOR_KNOWLEDGE))
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.readTimeout(10, TimeUnit.SECONDS)
|
||||
.writeTimeout(10, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
val grpcClient: GrpcClient = GrpcClient.Builder()
|
||||
.client(okHttpClient)
|
||||
.baseUrl("http://127.0.0.1:${Settings.grpcServiceModePort}")
|
||||
.build()
|
||||
|
||||
|
||||
private fun socketFactoryAndTrustManager(): Pair<SSLSocketFactory, X509TrustManager> {
|
||||
val trustManager: X509TrustManager
|
||||
val sslSocketFactory: SSLSocketFactory
|
||||
try {
|
||||
trustManager = trustManagerForCertificates(
|
||||
trustedCertificatesInputStream(),
|
||||
)
|
||||
val sslContext = SSLContext.getInstance("TLS")
|
||||
sslContext.init(null, arrayOf(trustManager), null)
|
||||
sslSocketFactory = sslContext.socketFactory
|
||||
} catch (e: GeneralSecurityException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
return sslSocketFactory to trustManager
|
||||
}
|
||||
|
||||
private fun trustedCertificatesInputStream(): InputStream {
|
||||
val myCertificate = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC/DCCAeSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAvMS0wKwYDVQQDEyRkNWY2\n" +
|
||||
"NTRhNC0zOWJlLTQyYjEtOGNlYi1kYTI3MmJmNTI2ZTQwIBcNMTkwODEyMjEwMzIx\n" +
|
||||
"WhgPMjExOTA3MTkyMTAzMjFaMC8xLTArBgNVBAMTJGQ1ZjY1NGE0LTM5YmUtNDJi\n" +
|
||||
"MS04Y2ViLWRhMjcyYmY1MjZlNDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" +
|
||||
"ggEBAJQzrBa2Zp7lJ8vJ/EWrkGU2BAOublkMl5XI0cbSIfbvuITXgHX7W5sDeEwx\n" +
|
||||
"6ultnUBVg6PmEbLAaZFtqg7gFPaVGbvP4h07FHSjRdf+y8W3QgoBIhc7/zuJiw1h\n" +
|
||||
"CsJ9D7eGl2dnXO6FgdY6ISnPAfxzzrZPCJtKL+Ffm9UnfCA7AYaQQZoymqVTGIsC\n" +
|
||||
"QAekkRkRia7gpUrTvR0hXST18KMcB7QKEv75rL8pEPHirJjyujBh+4VYVpLRDtbc\n" +
|
||||
"QKxCCXcn/zhTsn+4TV/4SgO1IhU+TBv4/iffzLi/aXKEEoPJhgIbMOd5ri1XBsTe\n" +
|
||||
"pGNaBOlYlEm8q8u1E3nGxzmkBtMCAwEAAaMhMB8wHQYDVR0RAQH/BBMwEYIJbG9j\n" +
|
||||
"YWxob3N0hwQKAAICMA0GCSqGSIb3DQEBCwUAA4IBAQAjL/inUHQbYD6bosFDQfyL\n" +
|
||||
"E9LOanO3ewiuZr5Sa4DJ5n8kNPdAO9M9urfmTbOUdvMfrH+fqiEwo6a7NTqT9bGk\n" +
|
||||
"Ewz7/LdpvWIGMpnijLEPTDTur2VmjpjqtawvzbFiHhdzOZk3o6bKbY3qac7CxaaO\n" +
|
||||
"MWZKF+o+YRCXVAJ2NQZLW2D9ee1qOXpK7VA360MFoyfo3cP8z6DDdNJm6gDAK+wI\n" +
|
||||
"1pMCdrdwHuu+ExKKA8za4r6dThVQu5jp6d7GO+2qf9rGkm1idIgjGtsgC+hPmhLb\n" +
|
||||
"7RK0ynU3Ai32elqwTDpD1WGuP2yacSWweh3GG6lG1NNY7n3tsccUWnsZztQ66Oh4\n" +
|
||||
"-----END CERTIFICATE-----"
|
||||
return Buffer()
|
||||
.writeUtf8(myCertificate)
|
||||
.inputStream()
|
||||
}
|
||||
|
||||
@Throws(GeneralSecurityException::class)
|
||||
private fun trustManagerForCertificates(inputStream: InputStream): X509TrustManager {
|
||||
val certificateFactory = CertificateFactory.getInstance("X.509")
|
||||
val certificates = certificateFactory.generateCertificates(inputStream)
|
||||
if (certificates.isEmpty()) {
|
||||
throw IllegalArgumentException("expected non-empty set of trusted certificates")
|
||||
}
|
||||
|
||||
// Put the certificates a key store.
|
||||
val password = "password".toCharArray() // Any password will work.
|
||||
val keyStore = newEmptyKeyStore(password)
|
||||
for ((index, certificate) in certificates.withIndex()) {
|
||||
val certificateAlias = index.toString()
|
||||
keyStore.setCertificateEntry(certificateAlias, certificate)
|
||||
}
|
||||
|
||||
// Use it to build an X509 trust manager.
|
||||
val keyManagerFactory = KeyManagerFactory.getInstance(
|
||||
KeyManagerFactory.getDefaultAlgorithm(),
|
||||
)
|
||||
keyManagerFactory.init(keyStore, password)
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm(),
|
||||
)
|
||||
trustManagerFactory.init(keyStore)
|
||||
val trustManagers = trustManagerFactory.trustManagers
|
||||
if (trustManagers.size != 1 || trustManagers[0] !is X509TrustManager) {
|
||||
throw IllegalStateException(
|
||||
"Unexpected default trust managers:" + Arrays.toString(trustManagers),
|
||||
)
|
||||
}
|
||||
return trustManagers[0] as X509TrustManager
|
||||
}
|
||||
|
||||
@Throws(GeneralSecurityException::class)
|
||||
private fun newEmptyKeyStore(password: CharArray): KeyStore {
|
||||
try {
|
||||
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
|
||||
val inputStream: InputStream? = null // By convention, 'null' creates an empty key store.
|
||||
keyStore.load(inputStream, password)
|
||||
return keyStore
|
||||
} catch (e: IOException) {
|
||||
throw AssertionError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.hiddify.hiddify.utils
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import io.nekohasekai.libbox.OutboundGroupItem
|
||||
import com.hiddify.core.libbox.OutboundGroup
|
||||
import com.hiddify.core.libbox.OutboundGroupItem
|
||||
|
||||
data class ParsedOutboundGroup(
|
||||
@SerializedName("tag") val tag: String,
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "v2/hcommon/common.proto";
|
||||
|
||||
package extension;
|
||||
|
||||
option go_package = "github.com/hiddify/hiddify-core/extension";
|
||||
option java_package = "com.hiddify.core.api.extension";
|
||||
message ExtensionActionResult {
|
||||
string extension_id = 1;
|
||||
hcommon.ResponseCode code = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
message ExtensionList {
|
||||
repeated ExtensionMsg extensions = 1;
|
||||
}
|
||||
|
||||
message EditExtensionRequest {
|
||||
string extension_id = 1;
|
||||
bool enable = 2;
|
||||
}
|
||||
|
||||
message ExtensionMsg {
|
||||
string id = 1;
|
||||
string title = 2;
|
||||
string description = 3;
|
||||
bool enable = 4;
|
||||
}
|
||||
|
||||
message ExtensionRequest {
|
||||
string extension_id = 1;
|
||||
map<string, string> data = 2;
|
||||
}
|
||||
|
||||
message SendExtensionDataRequest {
|
||||
string extension_id = 1;
|
||||
string button=2;
|
||||
map<string, string> data = 3;
|
||||
}
|
||||
|
||||
message ExtensionResponse {
|
||||
ExtensionResponseType type = 1;
|
||||
string extension_id = 2;
|
||||
string json_ui = 3;
|
||||
}
|
||||
|
||||
|
||||
enum ExtensionResponseType {
|
||||
NOTHING = 0;
|
||||
UPDATE_UI = 1;
|
||||
SHOW_DIALOG = 2;
|
||||
END=3;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
import "extension/extension.proto";
|
||||
import "v2/hcommon/common.proto";
|
||||
package extension;
|
||||
|
||||
option go_package = "github.com/hiddify/hiddify-core/extension";
|
||||
option java_package = "com.hiddify.core.api.extension";
|
||||
service ExtensionHostService {
|
||||
rpc ListExtensions (hcommon.Empty) returns (ExtensionList) {}
|
||||
rpc Connect (ExtensionRequest) returns (stream ExtensionResponse) {}
|
||||
rpc EditExtension (EditExtensionRequest) returns (ExtensionActionResult) {}
|
||||
rpc SubmitForm (SendExtensionDataRequest) returns (ExtensionActionResult) {}
|
||||
rpc Close (ExtensionRequest) returns (ExtensionActionResult) {}
|
||||
|
||||
rpc GetUI (ExtensionRequest) returns (ExtensionActionResult) {}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
syntax = "proto3";
|
||||
package config;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/config";
|
||||
option java_package = "com.hiddify.core.api.v2.config";
|
||||
message RouteRule {
|
||||
repeated Rule rules = 1 [json_name = "rules"];
|
||||
}
|
||||
|
||||
message Rule {
|
||||
uint32 list_order = 1 [json_name = "list_order"];
|
||||
bool enabled = 2 [json_name = "enabled"];
|
||||
string name = 3 [json_name = "name"];
|
||||
Outbound outbound = 4 [json_name = "outbound"];
|
||||
repeated string rule_sets = 5 [json_name = "rule_set"];
|
||||
repeated string package_names = 6 [json_name = "package_name"];
|
||||
repeated string process_names = 7 [json_name = "process_name"];
|
||||
repeated string process_paths = 8 [json_name = "process_path"];
|
||||
Network network = 9 [json_name = "network"];
|
||||
repeated string port_ranges = 10 [json_name = "port_range"];
|
||||
repeated string source_port_ranges = 11 [json_name = "source_port_range"];
|
||||
repeated Protocol protocols = 12 [json_name = "protocol"];
|
||||
repeated string ip_cidrs = 13 [json_name = "ip_cidr"];
|
||||
repeated string source_ip_cidrs = 14 [json_name = "source_ip_cidr"];
|
||||
repeated string domains = 15 [json_name = "domain"];
|
||||
repeated string domain_suffixes = 16 [json_name = "domain_suffix"];
|
||||
repeated string domain_keywords = 17 [json_name = "domain_keyword"];
|
||||
repeated string domain_regexes = 18 [json_name = "domain_regex"];
|
||||
}
|
||||
|
||||
enum Outbound {
|
||||
proxy = 0;
|
||||
direct = 1;
|
||||
direct_with_fragment = 2;
|
||||
block = 3;
|
||||
}
|
||||
|
||||
enum Network {
|
||||
all = 0;
|
||||
tcp = 1;
|
||||
udp = 2;
|
||||
}
|
||||
|
||||
enum Protocol {
|
||||
tls = 0;
|
||||
http = 1;
|
||||
quic = 2;
|
||||
stun = 3;
|
||||
dns = 4;
|
||||
bittorrent = 5;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package hcommon;
|
||||
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hcommon";
|
||||
option java_package = "com.hiddify.core.api.v2.hcommon";
|
||||
message Empty {
|
||||
}
|
||||
|
||||
enum ResponseCode {
|
||||
OK = 0;
|
||||
FAILED = 1;
|
||||
AUTH_NEED = 2;
|
||||
}
|
||||
|
||||
message Response {
|
||||
ResponseCode code = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
syntax = "proto3";
|
||||
import "v2/hcommon/common.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
package hcore;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hcore";
|
||||
option java_package = "com.hiddify.core.api.v2.hcore";
|
||||
|
||||
|
||||
enum CoreStates {
|
||||
STOPPED = 0;
|
||||
STARTING = 1;
|
||||
STARTED = 2;
|
||||
STOPPING = 3;
|
||||
}
|
||||
|
||||
enum MessageType {
|
||||
EMPTY=0;
|
||||
EMPTY_CONFIGURATION = 1;
|
||||
START_COMMAND_SERVER = 2;
|
||||
CREATE_SERVICE = 3;
|
||||
START_SERVICE = 4;
|
||||
UNEXPECTED_ERROR = 5;
|
||||
ALREADY_STARTED = 6;
|
||||
ALREADY_STOPPED = 7;
|
||||
INSTANCE_NOT_FOUND = 8;
|
||||
INSTANCE_NOT_STOPPED = 9;
|
||||
INSTANCE_NOT_STARTED = 10;
|
||||
ERROR_BUILDING_CONFIG = 11;
|
||||
ERROR_PARSING_CONFIG = 12;
|
||||
ERROR_READING_CONFIG = 13;
|
||||
ERROR_EXTENSION = 14;
|
||||
}
|
||||
|
||||
message CoreInfoResponse {
|
||||
CoreStates core_state = 1;
|
||||
MessageType message_type = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
message StartRequest {
|
||||
string config_path = 1;
|
||||
string config_content = 2; // Optional if configPath is not provided.
|
||||
bool disable_memory_limit = 3;
|
||||
bool delay_start = 4;
|
||||
bool enable_old_command_server = 5;
|
||||
bool enable_raw_config = 6;
|
||||
string config_name = 7;
|
||||
}
|
||||
|
||||
|
||||
enum SetupMode {
|
||||
OLD = 0;
|
||||
GRPC_NORMAL = 1;
|
||||
GRPC_BACKGROUND = 2;
|
||||
GRPC_NORMAL_INSECURE = 3;
|
||||
GRPC_BACKGROUND_INSECURE = 4;
|
||||
}
|
||||
|
||||
message CloseRequest {
|
||||
SetupMode mode = 1;
|
||||
}
|
||||
// Define the message equivalent of SetupParameters
|
||||
message SetupRequest {
|
||||
string base_path = 1;
|
||||
string working_dir = 2;
|
||||
string temp_dir = 3;
|
||||
int64 flutter_status_port = 4;
|
||||
string listen = 5;
|
||||
string secret = 6;
|
||||
bool debug = 7;
|
||||
SetupMode mode = 8;
|
||||
bool fix_android_stack = 9;
|
||||
}
|
||||
|
||||
message SystemInfo {
|
||||
int64 memory = 1;
|
||||
int32 goroutines = 2;
|
||||
int32 connections_in = 3;
|
||||
int32 connections_out = 4;
|
||||
bool traffic_available = 5;
|
||||
int64 uplink = 6;
|
||||
int64 downlink = 7;
|
||||
int64 uplink_total = 8;
|
||||
int64 downlink_total = 9;
|
||||
string current_outbound = 10;
|
||||
string current_profile = 11;
|
||||
}
|
||||
|
||||
message OutboundInfo {
|
||||
string tag = 1;
|
||||
string type = 2;
|
||||
google.protobuf.Timestamp url_test_time = 3;
|
||||
int32 url_test_delay = 4;
|
||||
optional IpInfo ipinfo = 5;
|
||||
bool is_selected = 6;
|
||||
bool is_group = 7;
|
||||
optional string group_selected_tag=13;
|
||||
optional string group_selected_tag_display=14;
|
||||
bool is_secure = 8;
|
||||
bool is_visible = 9;
|
||||
uint32 port = 10;
|
||||
string host = 11;
|
||||
string tag_display = 12;
|
||||
int64 upload = 15;
|
||||
int64 download = 16;
|
||||
}
|
||||
|
||||
message IpInfo {
|
||||
string ip = 1 [json_name = "ip"]; // The IP address.
|
||||
string country_code = 2 [json_name = "country_code"]; // The country code.
|
||||
string region = 3 [json_name = "region"]; // The region (optional).
|
||||
string city = 4 [json_name = "city"]; // The city (optional).
|
||||
int32 asn = 5 [json_name = "asn"]; // The Autonomous System Number (optional).
|
||||
string org = 6 [json_name = "org"]; // The organization (optional).
|
||||
double latitude = 7 [json_name = "latitude"]; // The latitude (optional).
|
||||
double longitude = 8 [json_name = "longitude"]; // The longitude (optional).
|
||||
string postal_code = 9 [json_name = "postal_code"]; // The postal code (optional).
|
||||
}
|
||||
message OutboundGroup {
|
||||
string tag = 1;
|
||||
string type = 2;
|
||||
string selected=3;
|
||||
bool selectable=4;
|
||||
bool Is_expand=5;
|
||||
repeated OutboundInfo items = 6;
|
||||
|
||||
}
|
||||
message OutboundGroupList{
|
||||
repeated OutboundGroup items = 1;
|
||||
}
|
||||
|
||||
message WarpAccount {
|
||||
string account_id = 1;
|
||||
string access_token = 2;
|
||||
}
|
||||
|
||||
message WarpWireguardConfig {
|
||||
string private_key = 1 [json_name = "private-key"];
|
||||
string local_address_ipv4 = 2 [json_name = "local-address-ipv4"];
|
||||
string local_address_ipv6 = 3 [json_name = "local-address-ipv6"];
|
||||
string peer_public_key = 4 [json_name = "peer-public-key"];
|
||||
string client_id=5 [json_name = "client-id"];
|
||||
}
|
||||
|
||||
message WarpGenerationResponse {
|
||||
WarpAccount account = 1;
|
||||
string log = 2;
|
||||
WarpWireguardConfig config = 3;
|
||||
}
|
||||
|
||||
message SystemProxyStatus {
|
||||
bool available = 1;
|
||||
bool enabled = 2;
|
||||
}
|
||||
|
||||
message ParseRequest {
|
||||
string content = 1;
|
||||
string config_path = 2;
|
||||
string temp_path = 3;
|
||||
bool debug = 4;
|
||||
}
|
||||
|
||||
message ParseResponse {
|
||||
hcommon.ResponseCode response_code = 1;
|
||||
string content = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
message ChangeHiddifySettingsRequest {
|
||||
string hiddify_settings_json = 1;
|
||||
}
|
||||
|
||||
message GenerateConfigRequest {
|
||||
string path = 1;
|
||||
string temp_path = 2;
|
||||
bool debug = 3;
|
||||
}
|
||||
|
||||
message GenerateConfigResponse {
|
||||
string config_content = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
message SelectOutboundRequest {
|
||||
string group_tag = 1;
|
||||
string outbound_tag = 2;
|
||||
}
|
||||
|
||||
message UrlTestRequest {
|
||||
string tag = 1;
|
||||
}
|
||||
|
||||
message GenerateWarpConfigRequest {
|
||||
string license_key = 1;
|
||||
string account_id = 2;
|
||||
string access_token = 3;
|
||||
}
|
||||
|
||||
message SetSystemProxyEnabledRequest {
|
||||
bool is_enabled = 1;
|
||||
}
|
||||
|
||||
enum LogLevel {
|
||||
TRACE = 0;
|
||||
DEBUG = 1;
|
||||
INFO = 2;
|
||||
WARNING = 3;
|
||||
ERROR = 4;
|
||||
FATAL = 5;
|
||||
}
|
||||
enum LogType {
|
||||
CORE = 0;
|
||||
SERVICE = 1;
|
||||
CONFIG = 2;
|
||||
}
|
||||
message LogMessage {
|
||||
LogLevel level = 1;
|
||||
LogType type = 2;
|
||||
string message = 3;
|
||||
google.protobuf.Timestamp time = 4;
|
||||
}
|
||||
|
||||
message LogRequest {
|
||||
LogLevel level = 1;
|
||||
}
|
||||
|
||||
message StopRequest{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
syntax = "proto3";
|
||||
import "v2/hcommon/common.proto";
|
||||
package hcore;
|
||||
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hcore";
|
||||
option java_package = "com.hiddify.core.api.v2.hcore";
|
||||
import "v2/hcore/hcore.proto";
|
||||
|
||||
service Core {
|
||||
rpc Start (StartRequest) returns (CoreInfoResponse);
|
||||
rpc CoreInfoListener (hcommon.Empty) returns (stream CoreInfoResponse);
|
||||
rpc OutboundsInfo (hcommon.Empty) returns (stream OutboundGroupList);
|
||||
rpc MainOutboundsInfo (hcommon.Empty) returns (stream OutboundGroupList);
|
||||
rpc GetSystemInfo (hcommon.Empty) returns (SystemInfo);
|
||||
rpc GetSystemInfoStream (hcommon.Empty) returns (stream SystemInfo);
|
||||
rpc Setup (SetupRequest) returns (hcommon.Response);
|
||||
rpc Parse (ParseRequest) returns (ParseResponse);
|
||||
rpc ChangeHiddifySettings (ChangeHiddifySettingsRequest) returns (CoreInfoResponse);
|
||||
//rpc GenerateConfig (GenerateConfigRequest) returns (GenerateConfigResponse);
|
||||
rpc StartService (StartRequest) returns (CoreInfoResponse);
|
||||
rpc Stop (hcommon.Empty) returns (CoreInfoResponse);
|
||||
rpc Restart (StartRequest) returns (CoreInfoResponse);
|
||||
rpc SelectOutbound (SelectOutboundRequest) returns (hcommon.Response);
|
||||
rpc UrlTest (UrlTestRequest) returns (hcommon.Response);
|
||||
rpc UrlTestActive (hcommon.Empty) returns (hcommon.Response);
|
||||
rpc GenerateWarpConfig (GenerateWarpConfigRequest) returns (WarpGenerationResponse);
|
||||
rpc GetSystemProxyStatus (hcommon.Empty) returns (SystemProxyStatus);
|
||||
rpc SetSystemProxyEnabled (SetSystemProxyEnabledRequest) returns (hcommon.Response);
|
||||
rpc LogListener (LogRequest) returns (stream LogMessage);
|
||||
rpc Close (CloseRequest) returns (hcommon.Empty);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package tunnelservice;
|
||||
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hcore/tunnelservice";
|
||||
option java_package = "com.hiddify.core.api.v2.tunnelservice";
|
||||
|
||||
|
||||
|
||||
message TunnelStartRequest {
|
||||
bool ipv6 = 1;
|
||||
int32 server_port = 2;
|
||||
string server_username=3;
|
||||
string server_password=4;
|
||||
bool strict_route = 5;
|
||||
bool endpoint_independent_nat = 6;
|
||||
string stack = 7;
|
||||
}
|
||||
|
||||
message TunnelResponse {
|
||||
string message = 1;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
syntax = "proto3";
|
||||
import "v2/hcommon/common.proto";
|
||||
package tunnelservice;
|
||||
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hcore/tunnelservice";
|
||||
option java_package = "com.hiddify.core.api.v2.hcore.tunnelservice";
|
||||
import "v2/hcore/tunnelservice/tunnel.proto";
|
||||
|
||||
service TunnelService {
|
||||
rpc Start(TunnelStartRequest) returns (TunnelResponse);
|
||||
rpc Stop(hcommon.Empty) returns (TunnelResponse);
|
||||
rpc Status(hcommon.Empty) returns (TunnelResponse);
|
||||
rpc Exit(hcommon.Empty) returns (TunnelResponse);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package hello;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hello";
|
||||
option java_package = "com.hiddify.core.api.v2.hello";
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message HelloResponse {
|
||||
string message = 1;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package hello;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hello";
|
||||
option java_package = "com.hiddify.core.api.v2.hello";
|
||||
import "v2/hello/hello.proto";
|
||||
|
||||
service Hello {
|
||||
rpc SayHello (HelloRequest) returns (HelloResponse);
|
||||
rpc SayHelloStream (stream HelloRequest) returns (stream HelloResponse);
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* This file defines various configuration options for the Hiddify application.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package hiddifyoptions;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/hiddifyoptions";
|
||||
option java_package = "com.hiddify.core.api.v2.hiddifyoptions";
|
||||
|
||||
/**
|
||||
* HiddifyOptions defines the configuration options for the Hiddify application.
|
||||
*/
|
||||
message HiddifyOptions {
|
||||
bool enable_full_config = 1; // Enables full configuration options.
|
||||
string log_level = 2; // Specifies the logging level (e.g., INFO, DEBUG).
|
||||
string log_file = 3; // Path to the log file.
|
||||
bool enable_clash_api = 4; // Indicates whether the Clash API is enabled.
|
||||
uint32 clash_api_port = 5; // Port for the Clash API (using uint32 for compatibility).
|
||||
string web_secret = 6; // Secret key for accessing the Clash API.
|
||||
string region = 7; // Region for the application.
|
||||
bool block_ads = 8; // If true, blocks ads.
|
||||
bool use_xray_core_when_possible = 9; // If true, use XRay core when possible.
|
||||
repeated Rule rules = 10; // List of routing rules for traffic management.
|
||||
WarpOptions warp = 11; // Configuration options for Warp.
|
||||
WarpOptions warp2 = 12; // Additional configuration options for a second Warp instance.
|
||||
MuxOptions mux = 13; // Configuration options for multiplexing.
|
||||
TLSTricks tls_tricks = 14; // Options for TLS tricks.
|
||||
DNSOptions dns_options = 15; // DNS-related options.
|
||||
InboundOptions inbound_options = 16; // Inbound connection options.
|
||||
URLTestOptions url_test_options = 17; // URL test configuration options.
|
||||
RouteOptions route_options = 18; // Routing-related options.
|
||||
}
|
||||
|
||||
/**
|
||||
* DomainStrategy defines the strategies for IP address preference when resolving domain names.
|
||||
*/
|
||||
enum DomainStrategy {
|
||||
as_is =0; // As it is.
|
||||
prefer_ipv4 = 1; // Prefer IPv4 addresses.
|
||||
prefer_ipv6 = 2; // Prefer IPv6 addresses.
|
||||
ipv4_only = 3; // Only use IPv4 addresses.
|
||||
ipv6_only = 4; // Only use IPv6 addresses.
|
||||
}
|
||||
|
||||
/**
|
||||
* IntRange defines a range of integers for various configurations.
|
||||
* It includes the starting and ending values of the range.
|
||||
*/
|
||||
message IntRange {
|
||||
int32 from = 1; // Starting value of the range.
|
||||
int32 to = 2; // Ending value of the range.
|
||||
}
|
||||
|
||||
/**
|
||||
* DNSOptions defines DNS-related configuration options.
|
||||
*/
|
||||
message DNSOptions {
|
||||
string remote_dns_address = 1; // Remote DNS server address.
|
||||
DomainStrategy remote_dns_domain_strategy = 2; // Strategy for resolving domains with remote DNS.
|
||||
string direct_dns_address = 3; // Direct DNS server address.
|
||||
DomainStrategy direct_dns_domain_strategy = 4; // Strategy for resolving domains with direct DNS.
|
||||
bool independent_dns_cache = 5; // If true, enables independent DNS caching.
|
||||
bool enable_fake_dns = 6; // If true, enables fake DNS responses.
|
||||
bool enable_dns_routing = 7; // If true, enables DNS routing.
|
||||
}
|
||||
|
||||
/**
|
||||
* InboundOptions defines the configuration options for inbound connections.
|
||||
*/
|
||||
message InboundOptions {
|
||||
bool enable_tun = 1; // If true, enables TUN interface.
|
||||
bool enable_tun_service = 2; // If true, enables TUN service.
|
||||
bool set_system_proxy = 3; // If true, sets the system proxy.
|
||||
uint32 mixed_port = 4; // Port for mixed traffic (using uint32 for compatibility).
|
||||
uint32 tproxy_port = 5; // Port for TProxy connections (using uint32 for compatibility).
|
||||
uint32 redirect_port = 10; // Port for TProxy connections (using uint32 for compatibility).
|
||||
uint32 direct_port = 6; // Port for local DNS service (using uint32 for compatibility).
|
||||
uint32 mtu = 7; // Maximum Transmission Unit size (using uint32 for compatibility).
|
||||
bool strict_route = 8; // If true, enforces strict routing.
|
||||
string tun_stack = 9; // Specifies the TUN stack to use.
|
||||
}
|
||||
|
||||
/**
|
||||
* URLTestOptions defines the configuration options for URL testing.
|
||||
*/
|
||||
message URLTestOptions {
|
||||
string connection_test_url = 1; // URL used for connection testing.
|
||||
int64 url_test_interval = 2; // Interval for URL tests in milliseconds.
|
||||
}
|
||||
|
||||
/**
|
||||
* RouteOptions defines options related to traffic routing.
|
||||
*/
|
||||
message RouteOptions {
|
||||
bool resolve_destination = 1; // If true, resolves the destination address.
|
||||
DomainStrategy ipv6_mode = 2; // Strategy for handling IPv6 addresses.
|
||||
bool bypass_lan = 3; // If true, bypasses LAN connections.
|
||||
bool allow_connection_from_lan = 4; // If true, allows connections from LAN.
|
||||
}
|
||||
|
||||
/**
|
||||
* TLSTricks defines options for TLS tricks to obfuscate traffic.
|
||||
*/
|
||||
message TLSTricks {
|
||||
bool enable_fragment = 1; // If true, enables fragmentation of packets.
|
||||
IntRange fragment_size = 2; // Size of fragments to be used.
|
||||
IntRange fragment_sleep = 3; // Sleep time between fragments.
|
||||
bool mixed_sni_case = 4; // If true, enables mixed SNI case for obfuscation.
|
||||
bool enable_padding = 5; // If true, enables padding of packets.
|
||||
IntRange padding_size = 6; // Size of padding to be used.
|
||||
}
|
||||
|
||||
/**
|
||||
* MuxOptions defines options for multiplexing connections.
|
||||
*/
|
||||
message MuxOptions {
|
||||
bool enable = 1; // If true, enables multiplexing.
|
||||
bool padding = 2; // If true, enables padding for multiplexed connections.
|
||||
int32 max_streams = 3; // Maximum number of streams allowed (using int32).
|
||||
string protocol = 4; // Protocol used for multiplexing.
|
||||
}
|
||||
|
||||
/**
|
||||
* WarpOptions defines configuration options for Warp.
|
||||
*/
|
||||
message WarpOptions {
|
||||
string id = 1; // Unique identifier for the Warp configuration.
|
||||
bool enable_warp = 2; // If true, enables Warp functionality.
|
||||
string mode = 3; // Operating mode for Warp.
|
||||
WarpWireguardConfig wireguard_config = 5; // Configuration for WireGuard (defined elsewhere).
|
||||
string fake_packets = 6; // Fake packet configuration.
|
||||
IntRange fake_packet_size = 7; // Size of fake packets.
|
||||
IntRange fake_packet_delay = 8; // Delay for sending fake packets.
|
||||
string fake_packet_mode = 9; // Mode for sending fake packets.
|
||||
string clean_ip = 10; // Clean IP address to use.
|
||||
uint32 clean_port = 11; // Port for clean traffic (using uint32 for compatibility).
|
||||
WarpAccount account = 12; // Account details for Warp (defined elsewhere).
|
||||
}
|
||||
|
||||
/**
|
||||
* WarpAccount defines account details for Warp.
|
||||
*/
|
||||
message WarpAccount {
|
||||
string account_id = 1; // Unique account identifier.
|
||||
string access_token = 2; // Access token for the account.
|
||||
}
|
||||
|
||||
/**
|
||||
* WarpWireguardConfig defines the configuration details for WireGuard.
|
||||
*/
|
||||
message WarpWireguardConfig {
|
||||
string private_key = 1; // Private key for WireGuard.
|
||||
string local_address_ipv4 = 2; // Local IPv4 address for WireGuard.
|
||||
string local_address_ipv6 = 3; // Local IPv6 address for WireGuard.
|
||||
string peer_public_key = 4; // Peer public key for WireGuard.
|
||||
string client_id = 5; // Client identifier for WireGuard.
|
||||
}
|
||||
|
||||
/**
|
||||
* Rule defines routing rules for managing traffic.
|
||||
*/
|
||||
message Rule {
|
||||
string rule_set_url = 1; // URL of the rule set.
|
||||
string domains = 2; // List of domains affected by this rule.
|
||||
string ip = 3; // IP address associated with this rule.
|
||||
string port = 4; // Port number associated with this rule.
|
||||
string network = 5; // Network type (e.g., IPv4, IPv6).
|
||||
string protocol = 6; // Protocol type (e.g., TCP, UDP).
|
||||
string outbound = 7; // Outbound traffic handling (e.g., allow, deny).
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package profile;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/profile";
|
||||
option java_package = "com.hiddify.core.api.v2.profile";
|
||||
import "v2/hiddifyoptions/hiddify_options.proto";
|
||||
|
||||
// ProfileEntity defines a profile entity.
|
||||
message ProfileEntity {
|
||||
string id = 1; // Unique identifier for the profile.
|
||||
// bool active = 2; // Indicates if the profile is active.
|
||||
string name = 3; // Name of the profile.
|
||||
string url = 4; // URL associated with the profile.
|
||||
int64 last_update = 5; // Last update time in milliseconds of the profile.
|
||||
ProfileOptions options = 6; // Options associated with the profile.
|
||||
SubscriptionInfo sub_info = 7; // Subscription-related information.
|
||||
hiddifyoptions.HiddifyOptions override_hiddify_options = 8; // Override Hiddify options.
|
||||
}
|
||||
|
||||
// ProfileOptions defines options for a profile.
|
||||
message ProfileOptions {
|
||||
int64 update_interval = 1; // Update interval in milliseconds.
|
||||
}
|
||||
|
||||
// SubscriptionInfo defines subscription-related information.
|
||||
message SubscriptionInfo {
|
||||
int64 upload = 1; // Upload speed in bytes.
|
||||
int64 download = 2; // Download speed in bytes.
|
||||
int64 total = 3; // Total data in bytes.
|
||||
int64 expire = 4; // Expiration time in milliseconds of the subscription.
|
||||
string web_page_url = 5; // URL for the web page.
|
||||
string support_url = 6; // URL for support.
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package profile;
|
||||
option go_package = "github.com/hiddify/hiddify-core/v2/profile";
|
||||
option java_package = "com.hiddify.core.api.v2.profile";
|
||||
/**
|
||||
* This proto file defines the ProfileService with RPC methods
|
||||
* to manage profiles (add, fetch, update, delete, and set active profiles).
|
||||
*/
|
||||
|
||||
// Import dependencies
|
||||
import "v2/profile/profile.proto"; // Import the ProfileEntity message from another proto file.
|
||||
import "v2/hcommon/common.proto"; // Import the common response codes and messages.
|
||||
|
||||
/**
|
||||
* ProfileRequest is the request message for fetching or identifying
|
||||
* a profile by ID, name, or URL.
|
||||
*/
|
||||
message ProfileRequest {
|
||||
string id = 1; // The ID of the profile to fetch (Fastest and recommended).
|
||||
string name = 2; // The name of the profile to fetch (if both 'id' and 'url' are empty).
|
||||
string url = 3; // The URL of the profile to fetch (if both 'id' and 'name' are empty).
|
||||
}
|
||||
|
||||
/**
|
||||
* AddProfileRequest is the request message for adding a profile
|
||||
* via URL or content.
|
||||
*/
|
||||
message AddProfileRequest {
|
||||
string url = 1; // The URL of the profile to add.
|
||||
string content = 2; // The profile content to add (used if 'url' is empty).
|
||||
string name = 3; // The optional name of the profile.
|
||||
bool mark_as_active = 4; // Whether to mark the profile as active.
|
||||
}
|
||||
|
||||
/**
|
||||
* ProfileResponse is the response message for profile service operations.
|
||||
*/
|
||||
message ProfileResponse {
|
||||
ProfileEntity profile = 1; // The profile entity, populated in successful operations.
|
||||
hcommon.ResponseCode response_code = 2; // The response code indicating success or failure.
|
||||
string message = 3; // A message indicating the result or error, if any.
|
||||
}
|
||||
|
||||
/**
|
||||
* MultiProfilesResponse is the response message for fetching multi profiles.
|
||||
*/
|
||||
message MultiProfilesResponse {
|
||||
repeated ProfileEntity profiles = 1; // A list of profile entities.
|
||||
hcommon.ResponseCode response_code = 2; // The response code indicating success or failure.
|
||||
string message = 3; // A message indicating the result or error, if any.
|
||||
}
|
||||
|
||||
/**
|
||||
* ProfileService defines the RPC methods available for managing profiles.
|
||||
*/
|
||||
service ProfileService {
|
||||
|
||||
/**
|
||||
* GetProfile fetches a profile by ID, name, or URL.
|
||||
*/
|
||||
rpc GetProfile(ProfileRequest) returns (ProfileResponse);
|
||||
|
||||
/**
|
||||
* UpdateProfile updates an existing profile.
|
||||
*/
|
||||
rpc UpdateProfile(ProfileEntity) returns (ProfileResponse);
|
||||
|
||||
/**
|
||||
* GetAllProfiles fetches all profiles.
|
||||
*/
|
||||
rpc GetAllProfiles(hcommon.Empty) returns (MultiProfilesResponse);
|
||||
|
||||
/**
|
||||
* GetActiveProfile retrieves the currently active profile.
|
||||
*/
|
||||
rpc GetActiveProfile(hcommon.Empty) returns (ProfileResponse);
|
||||
|
||||
/**
|
||||
* SetActiveProfile sets a profile as active, identified by ID, name, or URL.
|
||||
*/
|
||||
rpc SetActiveProfile(ProfileRequest) returns (hcommon.Response);
|
||||
|
||||
/**
|
||||
* AddProfile adds a new profile using either a URL or the raw profile content.
|
||||
*/
|
||||
rpc AddProfile(AddProfileRequest) returns (ProfileResponse);
|
||||
|
||||
/**
|
||||
* DeleteProfile deletes a profile identified by ID, name, or URL.
|
||||
*/
|
||||
rpc DeleteProfile(ProfileRequest) returns (hcommon.Response);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="false">127.0.0.1</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@@ -1,10 +1,12 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
@@ -16,4 +18,3 @@ subprojects {
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
org.gradle.jvmargs=-Xmx4048m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
|
||||
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -10,16 +10,17 @@ pluginManagement {
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
google()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "7.4.2" apply false
|
||||
id "org.jetbrains.kotlin.android" version "1.8.21" apply false
|
||||
id "com.android.application" version '8.6.0' apply false
|
||||
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
|
||||
}
|
||||
|
||||
include ":app"
|
||||
include ":app"
|
||||
+10
-3
@@ -13,21 +13,28 @@
|
||||
<title>Version 0.13.6</title>
|
||||
<pubDate>Sun, 7 Jan 2024 22:00:00 +0000</pubDate>
|
||||
<enclosure
|
||||
url="https://github.com/hiddify/hiddify-next/releases/download/v0.13.6/hiddify-windows-x64-setup.zip"
|
||||
url="hhttps://apps.apple.com/us/app/hiddify-proxy-vpn/id6596777532"
|
||||
sparkle:version="0.13.6" sparkle:os="ios" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Version 0.13.6</title>
|
||||
<pubDate>Sun, 7 Jan 2024 22:00:00 +0000</pubDate>
|
||||
<enclosure
|
||||
url="https://github.com/hiddify/hiddify-app/releases/download/v0.13.6/hiddify-windows-x64-setup.zip"
|
||||
sparkle:version="0.13.6" sparkle:os="windows" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Version 0.13.6</title>
|
||||
<pubDate>Sun, 7 Jan 2024 22:00:00 +0000</pubDate>
|
||||
<enclosure
|
||||
url="https://github.com/hiddify/hiddify-next/releases/download/v0.13.6/hiddify-macos-universal.zip"
|
||||
url="https://github.com/hiddify/hiddify-app/releases/download/v0.13.6/hiddify-macos-universal.zip"
|
||||
sparkle:version="0.13.6" sparkle:os="macos" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Version 0.13.6</title>
|
||||
<pubDate>Sun, 7 Jan 2024 22:00:00 +0000</pubDate>
|
||||
<enclosure
|
||||
url="https://github.com/hiddify/hiddify-next/releases/download/v0.13.6/hiddify-linux-x64.zip"
|
||||
url="https://github.com/hiddify/hiddify-app/releases/download/v0.13.6/hiddify-linux-x64.zip"
|
||||
sparkle:version="0.13.6" sparkle:os="linux" />
|
||||
</item>
|
||||
</channel>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,634 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "ابدأ",
|
||||
"version": "الإصدار",
|
||||
"ok": "موافق",
|
||||
"cancel": "إلغاء",
|
||||
"kContinue": "متابعة",
|
||||
"showMore": "عرض المزيد",
|
||||
"showLess": "عرض أقل",
|
||||
"filter": "تصفية",
|
||||
"all": "الكل",
|
||||
"pause": "إيقاف مؤقت",
|
||||
"resume": "استئناف",
|
||||
"clear": "مسح",
|
||||
"close": "إغلاق",
|
||||
"auto": "تلقائي",
|
||||
"manually": "يدوي",
|
||||
"name": "الاسم",
|
||||
"url": "الرابط",
|
||||
"add": "إضافة",
|
||||
"clipboard": "الحافظة",
|
||||
"addToClipboard": "إضافة إلى الحافظة",
|
||||
"scanQr": "مسح رمز QR",
|
||||
"free": "مجاني",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "مساعدة",
|
||||
"save": "حفظ",
|
||||
"update": "تحديث",
|
||||
"share": "مشاركة",
|
||||
"edit": "تعديل",
|
||||
"delete": "حذف",
|
||||
"discard": "تجاهل",
|
||||
"import": "استيراد",
|
||||
"export": "تصدير",
|
||||
"later": "لاحقًا",
|
||||
"ignore": "تجاهل",
|
||||
"quit": "خروج",
|
||||
"notSet": "غير محدد",
|
||||
"hide": "إخفاء",
|
||||
"exit": "خروج",
|
||||
"reset": "إعادة تعيين",
|
||||
"done": "تم",
|
||||
"search": "بحث",
|
||||
"decline": "رفض",
|
||||
"agree": "أوافق",
|
||||
"empty": "فارغ",
|
||||
"unknown": "غير معروف",
|
||||
"hidden": "مخفي",
|
||||
"timeout": "انتهى الوقت",
|
||||
"sort": "فرز",
|
||||
"dashboard": "لوحة التحكم",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "يوم واحد",
|
||||
"two": "يومان",
|
||||
"few": "$n أيام",
|
||||
"many": "$n يومًا",
|
||||
"other": "$n يوم"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "ساعة واحدة",
|
||||
"two": "ساعتان",
|
||||
"few": "$n ساعات",
|
||||
"many": "$n ساعة",
|
||||
"other": "$n ساعة"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "تم رفض الإذن"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "تمت الإضافة إلى الحافظة بنجاح",
|
||||
"failure": "فشل النسخ إلى الحافظة",
|
||||
"contentTooLarge": "المحتوى كبير جدًا. استخدم تصدير الملف بدلاً من ذلك"
|
||||
},
|
||||
"file": {
|
||||
"success": "تم إنشاء ملف JSON بنجاح",
|
||||
"failure": "فشل إنشاء الملف"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "تأكيد الاستيراد",
|
||||
"success": "تم الاستيراد بنجاح",
|
||||
"failure": "فشل الاستيراد"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "كل ما تحتاجه لإنترنت بلا قيود",
|
||||
"termsAndPolicyCaution(rich)": "بالاستمرار، أنت توافق على ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "صُنع بـ ❤️ بواسطة Hiddify - ${tap_source(مفتوح المصدر)} (${tap_license(الرخصة)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "الرئيسية",
|
||||
"quickSettings": "الإعدادات السريعة"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "البروكسيات",
|
||||
"sort": "فرز البروكسيات",
|
||||
"testDelay": "اختبار التأخير",
|
||||
"empty": "لا توجد بروكسيات متاحة",
|
||||
"activeProxy": "البروكسي النشط",
|
||||
"unknownIp": "IP غير معروف",
|
||||
"sortOptions": {
|
||||
"unsorted": "الافتراضي",
|
||||
"name": "أبجديًا",
|
||||
"delay": "حسب التأخير"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "عنوان IP",
|
||||
"country": "الدولة",
|
||||
"organization": "المُنظمة"
|
||||
},
|
||||
"delay": {
|
||||
"result": "التأخير: ${delay} مللي ثانية",
|
||||
"timeout": "انتهى وقت اختبار التأخير",
|
||||
"testing": "التأخير: قيد الاختبار..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "الملفات الشخصية",
|
||||
"add": "إضافة ملف شخصي",
|
||||
"update": "تحديث الملف الشخصي",
|
||||
"viewAllProfiles": "عرض جميع الملفات الشخصية",
|
||||
"activeProfileName": "اسم الملف النشط: \"${name}\".",
|
||||
"nonActiveProfileName": "تحديد \"${name}\" كملف نشط",
|
||||
"freeSubNotFound": "لم يتم العثور على اشتراك مجاني",
|
||||
"freeSubNotFoundForRegion": "لم يتم العثور على اشتراك مجاني لمنطقة \"${region}\"",
|
||||
"failedToLoad": "فشل التحميل",
|
||||
"updateSubscriptions": "تحديث الاشتراكات",
|
||||
"share": {
|
||||
"urlToClipboard": "رابط URL إلى الحافظة",
|
||||
"showUrlQr": "عرض رمز QR للرابط",
|
||||
"jsonToClipboard": "JSON إلى الحافظة"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "تم حفظ الملف الشخصي بنجاح"
|
||||
},
|
||||
"invalidUrl": "رابط غير صالح",
|
||||
"add": {
|
||||
"failure": "فشل إضافة الملف الشخصي"
|
||||
},
|
||||
"update": {
|
||||
"success": "تم تحديث الملف الشخصي بنجاح",
|
||||
"successNamed": "تم تحديث \"${name}\" بنجاح",
|
||||
"failure": "فشل تحديث الملف الشخصي",
|
||||
"failureNamed": "فشل تحديث \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "تم حذف الملف الشخصي بنجاح"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "الملف الشخصي",
|
||||
"lastUpdate": "آخر تحديث",
|
||||
"form": {
|
||||
"nameHint": "اسم الملف الشخصي",
|
||||
"emptyName": "الاسم مطلوب",
|
||||
"invalidUrl": "رابط غير صالح",
|
||||
"urlHint": "رابط الإعدادات الكامل",
|
||||
"disableAutoUpdate": "تعطيل التحديث التلقائي",
|
||||
"autoUpdateInterval": "فاصل التحديث التلقائي",
|
||||
"loading": "جاري إضافة الملف الشخصي..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "السجلات",
|
||||
"shareCoreLogs": "مشاركة سجلات النواة",
|
||||
"shareAppLogs": "مشاركة سجلات التطبيق"
|
||||
},
|
||||
"about": {
|
||||
"title": "حول التطبيق",
|
||||
"notAvailableMsg": "أنت تستخدم أحدث إصدار بالفعل",
|
||||
"checkForUpdate": "التحقق من وجود تحديثات",
|
||||
"openWorkingDir": "فتح مجلد العمل",
|
||||
"sourceCode": "الكود المصدري",
|
||||
"telegramChannel": "قناة التيليجرام",
|
||||
"termsAndConditions": "الشروط والأحكام",
|
||||
"privacyPolicy": "سياسة الخصوصية"
|
||||
},
|
||||
"settings": {
|
||||
"title": "الإعدادات",
|
||||
"resetTunnel": "إعادة تعيين ملف VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "استيراد الخيارات من الحافظة",
|
||||
"file": "استيراد الخيارات من ملف"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "نسخ الخيارات المجهولة إلى الحافظة",
|
||||
"anonymousToFile": "تصدير الخيارات المجهولة إلى ملف",
|
||||
"allToClipboard": "نسخ جميع الخيارات إلى الحافظة",
|
||||
"allToFile": "تصدير جميع الخيارات إلى ملف"
|
||||
},
|
||||
"reset": "إعادة تعيين الخيارات"
|
||||
},
|
||||
"general": {
|
||||
"title": "عام",
|
||||
"locale": "اللغة",
|
||||
"themeMode": "السمة",
|
||||
"themeModes": {
|
||||
"system": "سمة النظام الافتراضية",
|
||||
"dark": "الوضع الداكن",
|
||||
"light": "الوضع الفاتح",
|
||||
"black": "الوضع الأسود"
|
||||
},
|
||||
"enableAnalytics": "تفعيل التحليلات",
|
||||
"enableAnalyticsMsg": "السماح بجمع بيانات التحليل وتقارير الأعطال لتحسين التطبيق",
|
||||
"autoIpCheck": "التحقق التلقائي من IP الاتصال",
|
||||
"dynamicNotification": "عرض السرعة في الإشعار",
|
||||
"hapticFeedback": "ردود الفعل اللمسية",
|
||||
"actionAtClosing": "الإجراء عند الإغلاق",
|
||||
"autoStart": "البدء عند تسجيل الدخول",
|
||||
"silentStart": "البدء في الخلفية",
|
||||
"ignoreBatteryOptimizations": "تجاهل تحسينات البطارية",
|
||||
"ignoreBatteryOptimizationsMsg": "إزالة القيود للحصول على أفضل أداء للـ VPN",
|
||||
"memoryLimit": "حد الذاكرة",
|
||||
"memoryLimitMsg": "قم بتفعيل هذا الخيار إذا كنت تواجه أخطاء نفاد الذاكرة أو تعطل التطبيق بشكل متكرر",
|
||||
"debugMode": "وضع التصحيح",
|
||||
"debugModeMsg": "أعد تشغيل التطبيق لتطبيق هذا التغيير",
|
||||
"logLevel": "مستوى السجل",
|
||||
"connectionTestUrl": "رابط اختبار الاتصال",
|
||||
"urlTestInterval": "فاصل اختبار الرابط",
|
||||
"clashApiPort": "منفذ Clash API",
|
||||
"useXrayCoreWhenPossible": "استخدام xray-core عند الإمكان",
|
||||
"useXrayCoreWhenPossibleMsg": "استخدم xray-core عند تحليل روابط الاشتراك. تحتاج إلى إعادة استيراد الرابط لتفعيل هذا الخيار"
|
||||
},
|
||||
"routing": {
|
||||
"title": "التوجيه",
|
||||
"perAppProxy": {
|
||||
"title": "بروكسي لكل تطبيق",
|
||||
"hideSysApps": "إخفاء تطبيقات النظام",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "استيراد التحديد من الحافظة",
|
||||
"file": "استيراد التحديد من ملف",
|
||||
"msg": "سيؤدي الاستيراد إلى استبدال تحديداتك الحالية. هل أنت متأكد من رغبتك في المتابعة؟"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "نسخ التحديد إلى الحافظة",
|
||||
"file": "تصدير التحديد إلى ملف"
|
||||
},
|
||||
"shareToAll": "مشاركة مع الجميع",
|
||||
"clearAllSelections": "مسح جميع التحديدات"
|
||||
},
|
||||
"modes": {
|
||||
"all": "الكل",
|
||||
"proxy": "بروكسي",
|
||||
"bypass": "تجاوز",
|
||||
"allMsg": "استخدام البروكسي لجميع التطبيقات",
|
||||
"proxyMsg": "استخدام البروكسي للتطبيقات المحددة فقط",
|
||||
"bypassMsg": "عدم استخدام البروكسي للتطبيقات المحددة"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "الاختيار التلقائي",
|
||||
"performNow": "تنفيذ الآن",
|
||||
"resetToDefault": "إعادة التعيين إلى الافتراضي",
|
||||
"autoUpdateInterval": "فاصل التحديث التلقائي",
|
||||
"toast": {
|
||||
"success": "اكتمل الاختيار التلقائي للتطبيقات بنجاح",
|
||||
"failure": "فشل الاختيار التلقائي",
|
||||
"regionNotFound": "لم يتم العثور على اختيار تلقائي لمنطقة \"${region}\"",
|
||||
"alreadyInAuto": "اختياراتك موجودة بالفعل في القائمة التلقائية"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "الاختيار التلقائي للتطبيقات",
|
||||
"msg": "تم تعطيل ميزة الاختيار التلقائي للبروكسي بسبب تغيير المنطقة إلى \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "المنطقة",
|
||||
"regions": {
|
||||
"ir": "إيران (ir) 🇮🇷",
|
||||
"cn": "الصين (cn) 🇨🇳",
|
||||
"ru": "روسيا (ru) 🇷🇺",
|
||||
"af": "أفغانستان (af) 🇦🇫",
|
||||
"id": "إندونيسيا (id) 🇮🇩",
|
||||
"tr": "تركيا (tr) 🇹🇷",
|
||||
"br": "البرازيل (br) 🇧🇷",
|
||||
"other": "أخرى"
|
||||
},
|
||||
"blockAds": "حظر الإعلانات",
|
||||
"bypassLan": "تجاوز الشبكة المحلية",
|
||||
"resolveDestination": "تحديد وجهة الاتصال",
|
||||
"ipv6Route": "توجيه IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "تعطيل",
|
||||
"enable": "تفعيل",
|
||||
"prefer": "مفضل",
|
||||
"only": "فقط"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "قواعد التوجيه",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "استيراد القواعد من الحافظة",
|
||||
"file": "استيراد القواعد من ملف"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "نسخ القواعد إلى الحافظة",
|
||||
"file": "حفظ القواعد في ملف"
|
||||
},
|
||||
"reset": "إعادة تعيين القواعد"
|
||||
},
|
||||
"deleteRule": "حذف القاعدة",
|
||||
"createRule": "إنشاء قاعدة جديدة",
|
||||
"rule": {
|
||||
"title": "قاعدة",
|
||||
"ruleChanged": "تم تغيير القاعدة",
|
||||
"ruleChangedMsg": "هل تريد حفظ تعديلاتك؟",
|
||||
"onlyTunMode": "متوفر فقط في وضع TUN",
|
||||
"notAvailabeInThisPlatform": "غير متوفر على هذا النظام",
|
||||
"canNotBeEmpty": "لا يمكن أن يكون فارغًا",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "\"URL\" صالح مثل\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe or google chrome or chrome",
|
||||
"validProcessName": "\"اسم العملية\" صالح مثل\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "\"مسار العملية\" صالح مثل\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 or 1-65000",
|
||||
"validPortRange": "\"منفذ\" أو \"نطاق منافذ\" صالح مثل\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 or 10.0.0.0/24",
|
||||
"validIpCidr": "IP CIDR صالح مثل\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com or dl.google.com",
|
||||
"validDomain": "\"نطاق\" صالح مثل\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com or .ir",
|
||||
"validDomainSuffix": "\"لاحقة نطاق\" صالحة مثل\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "الاسم",
|
||||
"outbound": "التوجيه عند التطابق",
|
||||
"rule_set": "رابط مجموعة القواعد",
|
||||
"package_name": "أسماء الحزم",
|
||||
"process_name": "أسماء العمليات",
|
||||
"process_path": "مسارات العمليات",
|
||||
"network": "الشبكات",
|
||||
"port_range": "منافذ الوجهة",
|
||||
"source_port_range": "منافذ المصدر",
|
||||
"protocol": "البروتوكول",
|
||||
"ip_cidr": "IP CIDR الوجهة",
|
||||
"source_ip_cidr": "IP CIDR المصدر",
|
||||
"domain": "النطاق",
|
||||
"domain_suffixe": "لاحقة النطاق",
|
||||
"domain_keyword": "كلمة مفتاحية للنطاق",
|
||||
"domain_regex": "تعبير نمطي للنطاق"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "بروكسي",
|
||||
"direct": "مباشر",
|
||||
"direct_with_fragment": "مباشر مع Fragment",
|
||||
"block": "حظر"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "الكل",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "الكل",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "إضافة قيمة جديدة",
|
||||
"update": "تحديث القيمة",
|
||||
"clearList": "مسح القائمة",
|
||||
"clearListMsg": "تم حذف جميع العناصر"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "تطبيقات أندرويد",
|
||||
"showSystemApps": "عرض تطبيقات النظام",
|
||||
"hideSystemApps": "إخفاء تطبيقات النظام",
|
||||
"clearSelection": "مسح التحديد",
|
||||
"uninstalled": "غير مثبت"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "DNS عن بعد",
|
||||
"remoteDnsDomainStrategy": "استراتيجية نطاق DNS عن بعد",
|
||||
"directDns": "DNS مباشر",
|
||||
"directDnsDomainStrategy": "استراتيجية نطاق DNS مباشر",
|
||||
"enableDnsRouting": "تفعيل توجيه DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "تلقائي",
|
||||
"preferIpv6": "تفضيل IPv6",
|
||||
"preferIpv4": "تفضيل IPv4",
|
||||
"ipv4Only": "IPv4 فقط",
|
||||
"ipv6Only": "IPv6 فقط"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "الوارد",
|
||||
"serviceMode": "وضع الخدمة",
|
||||
"serviceModes": {
|
||||
"proxy": "خدمة البروكسي فقط",
|
||||
"systemProxy": "تعيين بروكسي النظام",
|
||||
"tun": "VPN",
|
||||
"tunService": "خدمة VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "بروكسي",
|
||||
"systemProxy": "بروكسي النظام",
|
||||
"tun": "VPN",
|
||||
"tunService": "خدمة VPN"
|
||||
},
|
||||
"strictRoute": "توجيه صارم",
|
||||
"tunImplementation": "تنفيذ Tun",
|
||||
"tunImplementations": {
|
||||
"mixed": "مختلط",
|
||||
"system": "النظام",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "منفذ مختلط",
|
||||
"tproxyPort": "منفذ البروكسي الشفاف",
|
||||
|
||||
"allowConnectionFromLan": "مشاركة VPN على الشبكة المحلية"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "حيل TLS",
|
||||
"enable": "تفعيل fragment",
|
||||
"size": "حجم fragment",
|
||||
"sleep": "تأخير fragment",
|
||||
"mixedSniCase": {
|
||||
"enable": "تفعيل الأحرف المختلطة لـ SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "تفعيل padding",
|
||||
"size": "حجم padding"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "تفعيل WARP",
|
||||
"generateConfig": "إنشاء تكوين WARP",
|
||||
"configGenerated": "تم إنشاء تكوين WARP",
|
||||
"missingConfig": "تكوين WARP مفقود",
|
||||
"detourMode": "وضع توجيه WARP",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "توجيه البروكسيات عبر WARP",
|
||||
"warpOverProxy": "توجيه WARP عبر البروكسيات",
|
||||
"proxyOverWarpExplain": "لإلغاء حظر البروكسيات بواسطة WARP",
|
||||
"warpOverProxyExplain": "لأمان إضافي بواسطة WARP"
|
||||
},
|
||||
"licenseKey": "مفتاح الترخيص",
|
||||
"cleanIp": "IP نظيف",
|
||||
"port": "المنفذ",
|
||||
"noise": {
|
||||
"count": "عدد الضوضاء",
|
||||
"mode": "وضع الضوضاء",
|
||||
"size": "حجم الضوضاء",
|
||||
"delay": "تأخير الضوضاء"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "الاتصال",
|
||||
"traffic": "البيانات",
|
||||
"trafficLive": "البيانات الحالية",
|
||||
"trafficTotal": "إجمالي البيانات",
|
||||
"uplink": "الإرسال",
|
||||
"downlink": "الاستقبال",
|
||||
"speed": "السرعة",
|
||||
"totalTransferred": "إجمالي النقل"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "الرفع",
|
||||
"download": "التنزيل",
|
||||
"total": "إجمالي البيانات",
|
||||
"expireDate": "تاريخ الانتهاء",
|
||||
"expired": "منتهي الصلاحية",
|
||||
"noTraffic": "نفدت الباقة",
|
||||
"remainingTime": "الوقت المتبقي",
|
||||
"remainingDuration": "متبقٍ ${duration} يوم",
|
||||
"remainingDurationNew": "${duration} يوم",
|
||||
"remainingTrafficSemanticLabel": "تم استهلاك ${consumed} من ${total}",
|
||||
"remainingTraffic": "البيانات المتبقية",
|
||||
"remainingUsage": "المتبقي",
|
||||
"profileSite": "المزوّد",
|
||||
"profileSupport": "الدعم"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "فرز حسب",
|
||||
"sort": {
|
||||
"name": "أبجديًا",
|
||||
"lastUpdate": "آخر تحديث"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "موافقة Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP هو مزود VPN مجاني لـ WireGuard. بتفعيل هذا الخيار، فإنك توافق على ${tos(شروط الخدمة)} و ${privacy(سياسة الخصوصية)} الخاصة بـ Cloudflare WARP."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "تحديث متاح",
|
||||
"msg": "إصدار جديد من @:common.appTitle متاح. هل ترغب في التحديث الآن؟",
|
||||
"currentVersion": "الإصدار الحالي: ",
|
||||
"newVersion": "الإصدار الجديد: ",
|
||||
"updateNow": "التحديث الآن"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "سيؤدي هذا إلى استبدال جميع إعداداتك الحالية. هل أنت متأكد؟"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "حذف الملف الشخصي",
|
||||
"msg": "هل أنت متأكد من رغبتك في حذف هذا الملف الشخصي نهائيًا؟"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "تحسين الاختيار التلقائي",
|
||||
"msg": "بمشاركة التطبيقات التي اخترتها، فإنك تساعد في إكمال قائمة \"الاختيار التلقائي\""
|
||||
},
|
||||
"import": {
|
||||
"msg": "سيؤدي هذا إلى استبدال جميع تحديداتك الحالية لبروكسي التطبيقات. هل أنت متأكد من رغبتك في المتابعة؟"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "حذف القاعدة",
|
||||
"msg": "هل أنت متأكد من رغبتك في حذف قاعدة \"$rulename\"؟"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "ميزات تجريبية قيد الاستخدام",
|
||||
"msg": "لقد فعّلت ميزات تجريبية قد تؤثر على جودة الاتصال وتسبب أخطاء غير متوقعة. يمكنك دائمًا تغيير هذه الخيارات أو إعادة تعيينها من صفحة الإعدادات.",
|
||||
"disable": "لا تعرض مرة أخرى"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "اختر ملفًا شخصيًا",
|
||||
"msg": "للبدء، قم بإضافة ملف اتصال يحتوي على تفاصيل اتصال VPN الخاصة بك.\n\nأليس لديك خادم VPN بعد؟ لا تقلق، اتبع الدليل أدناه لإعداد واحد بسرعة ومجانًا.",
|
||||
"helpBtn": {
|
||||
"label": "أرني كيف",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "تحذير من رابط خارجي",
|
||||
"youAreAboutToVisit": "أنت على وشك زيارة:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "هذا الموقع ليس ضمن قائمة المواقع الموثوقة لدينا. يرجى المتابعة بحذر."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "العلامة الكاملة:",
|
||||
"type": "النوع:",
|
||||
"testTime": "وقت الاختبار:",
|
||||
"testDelay": "تأخير الاختبار:",
|
||||
"isSelected": "محدد:",
|
||||
"isGroup": "مجموعة",
|
||||
"isSecure": "آمن:",
|
||||
"port": "المنفذ:",
|
||||
"host": "المضيف:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "رمز الدولة:",
|
||||
"region": "المنطقة:",
|
||||
"city": "المدينة:",
|
||||
"asn": "ASN:",
|
||||
"organization": "المُنظمة:",
|
||||
"location": "الموقع:",
|
||||
"postalCode": "الرمز البريدي:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "السؤال كل مرة",
|
||||
"alertMessage": "هل تريد إخفاء التطبيق أم الخروج منه؟",
|
||||
"remember": "تذكر خياري"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "انقر للاتصال",
|
||||
"connect": "اتصال",
|
||||
"connecting": "جار الاتصال...",
|
||||
"connected": "متصل",
|
||||
"disconnect": "قطع الاتصال",
|
||||
"disconnecting": "جاري قطع الاتصال...",
|
||||
"reconnect": "إعادة الاتصال",
|
||||
"reconnectMsg": "جاري إعادة الاتصال لتطبيق التغييرات...",
|
||||
"secure": "مُؤمَّن بواسطة WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "خطأ غير متوقع",
|
||||
"connection": {
|
||||
"unexpected": "خطأ اتصال غير متوقع",
|
||||
"timeout": "انتهى وقت الاتصال",
|
||||
"badResponse": "استجابة غير صالحة",
|
||||
"connectionError": "خطأ في الاتصال",
|
||||
"badCertificate": "شهادة غير صالحة"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "خطأ غير متوقع",
|
||||
"notFound": "لم يتم العثور على الملف الشخصي",
|
||||
"invalidConfig": "تكوينات غير صالحة",
|
||||
"invalidUrl": "رابط غير صالح",
|
||||
"canceledByUser": "تم الإلغاء من قبل المستخدم"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "فشل غير متوقع",
|
||||
"missingVpnPermission": "إذن الـ VPN مفقود",
|
||||
"missingNotificationPermission": "إذن الإشعارات مفقود",
|
||||
"core": "خطأ في النواة"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "الخدمة لا تعمل",
|
||||
"missingPrivilege": "صلاحيات مطلوبة",
|
||||
"missingPrivilegeMsg": "وضع الـ VPN يتطلب صلاحيات المسؤول. يرجى إعادة تشغيل التطبيق كمسؤول أو تغيير وضع الخدمة.",
|
||||
"invalidConfigOptions": "خيارات تكوين غير صالحة",
|
||||
"invalidConfig": "تكوين غير صالح"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "رخصة WARP مفقودة",
|
||||
"missingLicenseMsg": "الملف الشخصي المحدد يستخدم ميزة WARP. لاستخدام هذه الميزة، يجب الموافقة على شروط رخصة WARP."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Start",
|
||||
"version": "Version",
|
||||
"ok": "OK",
|
||||
"cancel": "Cancel",
|
||||
"kContinue": "Continue",
|
||||
"showMore": "Show more",
|
||||
"showLess": "Show less",
|
||||
"filter": "Filter",
|
||||
"all": "All",
|
||||
"pause": "Pause",
|
||||
"resume": "Resume",
|
||||
"clear": "Clear",
|
||||
"close": "Close",
|
||||
"auto": "Auto",
|
||||
"manually": "Manually",
|
||||
"name": "Name",
|
||||
"url": "URL",
|
||||
"add": "Add",
|
||||
"clipboard": "Clipboard",
|
||||
"addToClipboard": "Add to clipboard",
|
||||
"scanQr": "Scan QR",
|
||||
"free": "Free",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "Help",
|
||||
"save": "Save",
|
||||
"update": "Update",
|
||||
"share": "Share",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"discard": "Discard",
|
||||
"import": "Import",
|
||||
"export": "Export",
|
||||
"later": "Later",
|
||||
"ignore": "Ignore",
|
||||
"quit": "Quit",
|
||||
"notSet": "Not set",
|
||||
"hide": "Hide",
|
||||
"exit": "Exit",
|
||||
"reset": "Reset",
|
||||
"done": "Done",
|
||||
"search": "Search",
|
||||
"decline": "Decline",
|
||||
"agree": "Agree",
|
||||
"empty": "Empty",
|
||||
"unknown": "Unknown",
|
||||
"hidden": "Hidden",
|
||||
"timeout": "Timeout",
|
||||
"sort": "Sort",
|
||||
"dashboard": "Dashboard",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n day",
|
||||
"other": "$n days"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n hour",
|
||||
"other": "$n hours"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "Permission denied"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Added to clipboard successfully",
|
||||
"failure": "Failed to copy to clipboard",
|
||||
"contentTooLarge": "Content too large. Use export file instead"
|
||||
},
|
||||
"file": {
|
||||
"success": "JSON file created successfully",
|
||||
"failure": "Failed to create file"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "Confirm import",
|
||||
"success": "Imported successfully",
|
||||
"failure": "Failed to import"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "All you need for an unrestricted internet",
|
||||
"termsAndPolicyCaution(rich)": "By continuing you agree to ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "Made with ❤️ by Hiddify - ${tap_source(Open Source)} (${tap_license(License)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Home",
|
||||
"quickSettings": "Quick settings"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Proxies",
|
||||
"sort": "Sort proxies",
|
||||
"testDelay": "Test delay",
|
||||
"empty": "No proxies available",
|
||||
"activeProxy": "Active proxy",
|
||||
"unknownIp": "Unknown IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "Default",
|
||||
"name": "Alphabetically",
|
||||
"delay": "By delay",
|
||||
"usage": "By usage"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "IP address",
|
||||
"country": "Country",
|
||||
"organization": "Organization"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Delay: ${delay}ms",
|
||||
"timeout": "Delay test timeout",
|
||||
"testing": "Delay: testing..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Profiles",
|
||||
"add": "Add profile",
|
||||
"update": "Update profile",
|
||||
"viewAllProfiles": "View all profiles",
|
||||
"activeProfileName": "Active profile name: \"${name}\".",
|
||||
"nonActiveProfileName": "Select \"${name}\" as active profile",
|
||||
"freeSubNotFound": "No free subscription was found",
|
||||
"freeSubNotFoundForRegion": "No free subscription was found for \"${region}\" region.",
|
||||
"failedToLoad": "Failed to load",
|
||||
"updateSubscriptions": "Update subscriptions",
|
||||
"share": {
|
||||
"urlToClipboard": "URL to clipboard",
|
||||
"showUrlQr": "Show URL QR",
|
||||
"jsonToClipboard": "JSON to clipboard"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Profile saved successfully"
|
||||
},
|
||||
"invalidUrl": "Invalid URL",
|
||||
"add": {
|
||||
"failure": "Failed to add profile"
|
||||
},
|
||||
"update": {
|
||||
"success": "Profile updated successfully",
|
||||
"successNamed": "\"${name}\" updated successfully",
|
||||
"failure": "Failed to update profile",
|
||||
"failureNamed": "Failed to update \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "Profile deleted successfully"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Profile",
|
||||
"lastUpdate": "Last update",
|
||||
"form": {
|
||||
"nameHint": "Profile name",
|
||||
"emptyName": "Name is required",
|
||||
"invalidUrl": "Invalid URL",
|
||||
"urlHint": "Full config URL",
|
||||
"disableAutoUpdate": "Disable auto update",
|
||||
"autoUpdateInterval": "Auto update interval",
|
||||
"loading": "Adding profile..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Logs",
|
||||
"shareCoreLogs": "Share core logs",
|
||||
"shareAppLogs": "Share app logs"
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
"notAvailableMsg": "Already using the latest version",
|
||||
"checkForUpdate": "Check for update",
|
||||
"openWorkingDir": "Open working directory",
|
||||
"sourceCode": "Source code",
|
||||
"telegramChannel": "Telegram channel",
|
||||
"termsAndConditions": "Terms and conditions",
|
||||
"privacyPolicy": "Privacy policy"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"resetTunnel": "Reset VPN profile",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Import options from clipboard",
|
||||
"file": "Import options from file"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Copy anonymous options to clipboard",
|
||||
"anonymousToFile": "Export anonymous options to file",
|
||||
"allToClipboard": "Copy all options to clipboard",
|
||||
"allToFile": "Export all options to file"
|
||||
},
|
||||
"reset": "Reset options"
|
||||
},
|
||||
"general": {
|
||||
"title": "General",
|
||||
"locale": "Language",
|
||||
"themeMode": "Theme mode",
|
||||
"themeModes": {
|
||||
"system": "System default",
|
||||
"dark": "Dark mode",
|
||||
"light": "Light mode",
|
||||
"black": "Black mode"
|
||||
},
|
||||
"enableAnalytics": "Enable analytics",
|
||||
"enableAnalyticsMsg": "Give permission to collect analytics and send crash reports to improve the app",
|
||||
"autoIpCheck": "Automatically check connection IP",
|
||||
"dynamicNotification": "Display speed in notification",
|
||||
"hapticFeedback": "Haptic feedback",
|
||||
"actionAtClosing": "Action at closing",
|
||||
"autoStart": "Start at login",
|
||||
"silentStart": "Start minimized",
|
||||
"ignoreBatteryOptimizations": "Disable battery optimization",
|
||||
"ignoreBatteryOptimizationsMsg": "Remove restrictions for optimal VPN performance",
|
||||
"memoryLimit": "Memory limit",
|
||||
"memoryLimitMsg": "Enable if you're experiencing out of memory errors or frequent app crashes",
|
||||
"debugMode": "Debug mode",
|
||||
"debugModeMsg": "Restart the app for applying this change",
|
||||
"logLevel": "Log level",
|
||||
"connectionTestUrl": "Connection test URL",
|
||||
"urlTestInterval": "URL test interval",
|
||||
"clashApiPort": "Clash API port",
|
||||
"useXrayCoreWhenPossible": "Use xray-core when possible",
|
||||
"useXrayCoreWhenPossibleMsg": "Use xray-core during parsing sub links. You need to reimport the sub link to enable this option."
|
||||
},
|
||||
"routing": {
|
||||
"title": "Routing",
|
||||
"perAppProxy": {
|
||||
"title": "Per-app proxy",
|
||||
"hideSysApps": "Hide system apps",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Import selection from clipboard",
|
||||
"file": "Import selection from file",
|
||||
"msg": "Importing will replace your current selections. Are you sure you want to continue?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copy selection to clipboard",
|
||||
"file": "Export selection to file"
|
||||
},
|
||||
"shareToAll": "Share to all",
|
||||
"clearAllSelections": "Clear all selections"
|
||||
},
|
||||
"modes": {
|
||||
"all": "All",
|
||||
"proxy": "Proxy",
|
||||
"bypass": "Bypass",
|
||||
"allMsg": "Proxy all apps",
|
||||
"proxyMsg": "Proxy only selected apps",
|
||||
"bypassMsg": "Do not proxy selected apps"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Auto selection",
|
||||
"performNow": "Perform now",
|
||||
"resetToDefault": "Reset to default",
|
||||
"autoUpdateInterval": "Auto update interval",
|
||||
"toast": {
|
||||
"success": "Auto apps selection completed successfully",
|
||||
"failure": "Auto selection failed",
|
||||
"regionNotFound": "Auto selection not found, region \"${region}\"",
|
||||
"alreadyInAuto": "Your selections are already in the auto-list"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Auto apps selection",
|
||||
"msg": "The auto selection feature for per-app proxy was disabled due to the region change to \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Region",
|
||||
"regions": {
|
||||
"ir": "Iran (ir) 🇮🇷",
|
||||
"cn": "China (cn) 🇨🇳",
|
||||
"ru": "Russia (ru) 🇷🇺",
|
||||
"af": "Afghanistan (af) 🇦🇫",
|
||||
"id": "Indonesia (id) 🇮🇩",
|
||||
"tr": "Türkiye (tr) 🇹🇷",
|
||||
"br": "Brazil (br) 🇧🇷",
|
||||
"other": "Other"
|
||||
},
|
||||
"blockAds": "Block advertisements",
|
||||
"bypassLan": "Bypass LAN",
|
||||
"resolveDestination": "Resolve destination",
|
||||
"ipv6Route": "IPv6 route",
|
||||
"ipv6Modes": {
|
||||
"disable": "Disable",
|
||||
"enable": "Enable",
|
||||
"prefer": "Preferred",
|
||||
"only": "Exclusive"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Route rules",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Import rules from clipboard",
|
||||
"file": "Import rules from file"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copy rules to clipboard",
|
||||
"file": "Save rules to file"
|
||||
},
|
||||
"reset": "Reset rules"
|
||||
},
|
||||
"deleteRule": "Delete rule",
|
||||
"createRule": "Create new rule",
|
||||
"rule": {
|
||||
"title": "Rule",
|
||||
"ruleChanged": "Rule changed",
|
||||
"ruleChangedMsg": "Do you want to save your edits?",
|
||||
"onlyTunMode": "Available only in tun mode",
|
||||
"notAvailabeInThisPlatform": "Not available in this platform",
|
||||
"canNotBeEmpty": "Can not be empty",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "Valid \"URL\" like\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe or google chrome or chrome",
|
||||
"validProcessName": "Valid \"Process Name\" like\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "Valid \"Process Path\" like\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 or 1-65000",
|
||||
"validPortRange": "Valid \"Port\" or \"Port Range\" like\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 or 10.0.0.0/24",
|
||||
"validIpCidr": "Valid IP CIDR like\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com or dl.google.com",
|
||||
"validDomain": "Valid \"Domain\" like\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com or .ir",
|
||||
"validDomainSuffix": "Valid \"Domain Suffix\" like\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "Name",
|
||||
"outbound": "Outbound if match",
|
||||
"rule_set": "Rule set URL",
|
||||
"package_name": "Package names",
|
||||
"process_name": "Process names",
|
||||
"process_path": "Process paths",
|
||||
"network": "Networks",
|
||||
"port_range": "Destination ports",
|
||||
"source_port_range": "Source ports",
|
||||
"protocol": "Protocol",
|
||||
"ip_cidr": "Destination IP CIDR",
|
||||
"source_ip_cidr": "Source IP CIDR",
|
||||
"domain": "Domain",
|
||||
"domain_suffixe": "Domain suffix",
|
||||
"domain_keyword": "Domain keyword",
|
||||
"domain_regex": "Domain regex"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Proxy",
|
||||
"direct": "Direct",
|
||||
"direct_with_fragment": "Direct with fragment",
|
||||
"block": "Block"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "All",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "All",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Add new value",
|
||||
"update": "Update value",
|
||||
"clearList": "Clear list",
|
||||
"clearListMsg": "All items are deleted"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Android apps",
|
||||
"showSystemApps": "Show system apps",
|
||||
"hideSystemApps": "Hide system apps",
|
||||
"clearSelection": "Clear selection",
|
||||
"uninstalled": "Uninstalled"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "Remote DNS",
|
||||
"remoteDnsDomainStrategy": "Remote DNS domain strategy",
|
||||
"directDns": "Outbound Server Resolver (Direct)",
|
||||
"directDnsDomainStrategy": "Outbound Domain strategy",
|
||||
"enableDnsRouting": "Enable DNS routing",
|
||||
"enableFakeDns": "Enable fake DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "Auto",
|
||||
"preferIpv6": "Prefer IPv6",
|
||||
"preferIpv4": "Prefer IPv4",
|
||||
"ipv4Only": "IPv4 only",
|
||||
"ipv6Only": "IPv6 only"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Inbound",
|
||||
"serviceMode": "Service mode",
|
||||
"serviceModes": {
|
||||
"proxy": "Proxy service only",
|
||||
"systemProxy": "Set system proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN service"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "System proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN service"
|
||||
},
|
||||
"strictRoute": "Strict route",
|
||||
"tunImplementation": "Tun implementation",
|
||||
"tunImplementations": {
|
||||
"mixed": "Mixed",
|
||||
"system": "System",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Mixed port",
|
||||
"tproxyPort": "Transparent proxy port",
|
||||
"directPort": "Direct port",
|
||||
"redirectPort": "Redirect port",
|
||||
"allowConnectionFromLan": "Share VPN in local network"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "TLS tricks",
|
||||
"enable": "Enable fragment",
|
||||
"size": "Fragment size",
|
||||
"sleep": "Fragment sleep",
|
||||
"mixedSniCase": {
|
||||
"enable": "Enable mixed SNI case"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Enable padding",
|
||||
"size": "Padding size"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "Enable WARP",
|
||||
"generateConfig": "Generate WARP config",
|
||||
"configGenerated": "Warp config is generated",
|
||||
"missingConfig": "Missing WARP config",
|
||||
"detourMode": "Detour mode",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Detour proxies through WARP ",
|
||||
"warpOverProxy": "Detour WARP through proxies",
|
||||
"proxyOverWarpExplain": "Unblock proxies by WARP",
|
||||
"warpOverProxyExplain": "Extra security by WARP"
|
||||
},
|
||||
"licenseKey": "License key",
|
||||
"cleanIp": "Clean IP",
|
||||
"port": "Port",
|
||||
"noise": {
|
||||
"count": "Noise count",
|
||||
"mode": "Noise mode",
|
||||
"size": "Noise size",
|
||||
"delay": "Noise delay"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Connection",
|
||||
"traffic": "Traffic",
|
||||
"trafficLive": "Live traffic",
|
||||
"trafficTotal": "Total traffic",
|
||||
"uplink": "Uplink",
|
||||
"downlink": "Downlink",
|
||||
"speed": "Speed",
|
||||
"totalTransferred": "Total transferred"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Upload",
|
||||
"download": "Download",
|
||||
"total": "Total traffic",
|
||||
"expireDate": "Expire date",
|
||||
"expired": "Expired",
|
||||
"noTraffic": "Out of quota",
|
||||
"remainingTime": "Remaining time",
|
||||
"remainingDuration": "${duration} days remaining",
|
||||
"remainingDurationNew": "${duration} days",
|
||||
"remainingTrafficSemanticLabel": "${consumed} of ${total} traffic consumed",
|
||||
"remainingTraffic": "Remaining traffic",
|
||||
"remainingUsage": "Remaining",
|
||||
"profileSite": "Provider",
|
||||
"profileSupport": "Support"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Sort by",
|
||||
"sort": {
|
||||
"name": "Alphabetically",
|
||||
"lastUpdate": "Recently updated"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Cloudflare WARP consent",
|
||||
"description(rich)": "Cloudflare WARP is a free WireGuard VPN provider. By enabling this option you are agreeing to the Cloudflare WARP's ${tos(Terms of service)} and ${privacy(Privacy policy)}."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Update available",
|
||||
"msg": "A new version of @:common.appTitle is available. Would you like to update now?",
|
||||
"currentVersion": "Current version: ",
|
||||
"newVersion": "New version: ",
|
||||
"updateNow": "Update now"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "This will rewrite all config options with provided values. Are you sure?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Delete profile",
|
||||
"msg": "Are you sure you want to permanently delete this profile?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Improving auto selection",
|
||||
"msg": "By sharing selected apps, you help complete the \"auto selection\" list"
|
||||
},
|
||||
"import": {
|
||||
"msg": "This will replace all your current per-app proxy selections. Are you sure you want to continue?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Delete rule",
|
||||
"msg": "Are you sure you want to delete the \"$rulename\" rule?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Experimental features in use",
|
||||
"msg": "You've enabled some experimental features which might affect connection quality and cause unexpected errors. You can always change or reset these options from config options page.",
|
||||
"disable": "Don't show again"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Choose a profile",
|
||||
"msg": "Let's get started by adding a connection profile that includes your VPN connection details.\n\nDon’t have a VPN server yet? No worries—just follow the tutorial below to set one up quickly and for free.",
|
||||
"helpBtn": {
|
||||
"label": "Show me how",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "External link warning",
|
||||
"youAreAboutToVisit": "You are about to visit :",
|
||||
"thisWebsiteIsNotInOurTrustedList": "This website is not in our trusted list. Please proceed with caution."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Full tag:",
|
||||
"type": "Type:",
|
||||
"testTime": "Test time:",
|
||||
"testDelay": "Test delay:",
|
||||
"isSelected": "Is selected:",
|
||||
"isGroup": "Is group",
|
||||
"isSecure": "Is secure:",
|
||||
"port": "Port:",
|
||||
"host": "Host:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "Country code:",
|
||||
"region": "Region:",
|
||||
"city": "City:",
|
||||
"asn": "ASN:",
|
||||
"organization": "Organization:",
|
||||
"location": "Location:",
|
||||
"postalCode": "Postal code:",
|
||||
"download": "Download:",
|
||||
"upload": "Upload:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Ask each time",
|
||||
"alertMessage": "Hide or exit the application?",
|
||||
"remember": "Remember my choice"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Tap to connect",
|
||||
"connect": "Connect",
|
||||
"connecting": "Connecting...",
|
||||
"connected": "Connected",
|
||||
"disconnect": "Disconnect",
|
||||
"disconnecting": "Disconnecting...",
|
||||
"reconnect": "Reconnect",
|
||||
"reconnectMsg": "Reconnecting for taking into account the changes...",
|
||||
"secure": "Secured by WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Unexpected error",
|
||||
"connection": {
|
||||
"unexpected": "Unexpected connection error",
|
||||
"timeout": "Connection timeout",
|
||||
"badResponse": "Bad response",
|
||||
"connectionError": "Connection error",
|
||||
"badCertificate": "Bad certificate"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Unexpected error",
|
||||
"notFound": "Profile not found",
|
||||
"invalidConfig": "Invalid configs",
|
||||
"invalidUrl": "Invalid URL",
|
||||
"canceledByUser": "Canceled by user"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Unexpected failure",
|
||||
"missingVpnPermission": "Missing VPN permission",
|
||||
"missingNotificationPermission": "Missing notification permission",
|
||||
"core": "Core error"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "Service is not running",
|
||||
"missingPrivilege": "Missing privilege",
|
||||
"missingPrivilegeMsg": "VPN mode requires administrator privileges. Either relaunch the app as administrator or change service mode.",
|
||||
"invalidConfigOptions": "Invalid configuration options",
|
||||
"invalidConfig": "Invalid configuration"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "Warp license",
|
||||
"missingLicenseMsg": "The selected profile uses the WARP feature; to use this feature, the WARP license must be agreed to."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Comenzar",
|
||||
"version": "Versión",
|
||||
"ok": "Aceptar",
|
||||
"cancel": "Cancelar",
|
||||
"kContinue": "Continuar",
|
||||
"showMore": "Mostrar más",
|
||||
"showLess": "Mostrar menos",
|
||||
"filter": "Filtrar",
|
||||
"all": "Todos",
|
||||
"pause": "Pausar",
|
||||
"resume": "Reanudar",
|
||||
"clear": "Limpiar",
|
||||
"close": "Cerrar",
|
||||
"auto": "Automático",
|
||||
"manually": "Manualmente",
|
||||
"name": "Nombre",
|
||||
"url": "URL",
|
||||
"add": "Añadir",
|
||||
"clipboard": "Portapapeles",
|
||||
"addToClipboard": "Añadir al portapapeles",
|
||||
"scanQr": "Escanear QR",
|
||||
"free": "Gratis",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragmento",
|
||||
"help": "Ayuda",
|
||||
"save": "Guardar",
|
||||
"update": "Actualizar",
|
||||
"share": "Compartir",
|
||||
"edit": "Editar",
|
||||
"delete": "Eliminar",
|
||||
"discard": "Descartar",
|
||||
"import": "Importar",
|
||||
"export": "Exportar",
|
||||
"later": "Más tarde",
|
||||
"ignore": "Ignorar",
|
||||
"quit": "Salir",
|
||||
"notSet": "No establecido",
|
||||
"hide": "Ocultar",
|
||||
"exit": "Salir",
|
||||
"reset": "Restablecer",
|
||||
"done": "Hecho",
|
||||
"search": "Buscar",
|
||||
"decline": "Rechazar",
|
||||
"agree": "Aceptar",
|
||||
"empty": "Vacío",
|
||||
"unknown": "Desconocido",
|
||||
"hidden": "Oculto",
|
||||
"timeout": "Tiempo agotado",
|
||||
"sort": "Ordenar",
|
||||
"dashboard": "Panel",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n día",
|
||||
"other": "$n días"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n hora",
|
||||
"other": "$n horas"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "Permiso denegado"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Añadido al portapapeles con éxito",
|
||||
"failure": "Error al copiar al portapapeles",
|
||||
"contentTooLarge": "Contenido demasiado grande. Use la exportación a archivo en su lugar"
|
||||
},
|
||||
"file": {
|
||||
"success": "Archivo JSON creado con éxito",
|
||||
"failure": "Error al crear el archivo"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "Confirmar importación",
|
||||
"success": "Importado con éxito",
|
||||
"failure": "Error al importar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "Todo lo que necesitas para un internet sin restricciones",
|
||||
"termsAndPolicyCaution(rich)": "Al continuar, aceptas los ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "Hecho con ❤️ por Hiddify - ${tap_source(Código Abierto)} (${tap_license(Licencia)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Inicio",
|
||||
"quickSettings": "Ajustes rápidos"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Proxies",
|
||||
"sort": "Ordenar proxies",
|
||||
"testDelay": "Probar latencia",
|
||||
"empty": "No hay proxies disponibles",
|
||||
"activeProxy": "Proxy activo",
|
||||
"unknownIp": "IP desconocida",
|
||||
"sortOptions": {
|
||||
"unsorted": "Por defecto",
|
||||
"name": "Alfabéticamente",
|
||||
"delay": "Por latencia"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "Dirección IP",
|
||||
"country": "País",
|
||||
"organization": "Organización"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Latencia: ${delay}ms",
|
||||
"timeout": "Tiempo de prueba de latencia agotado",
|
||||
"testing": "Latencia: probando..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Perfiles",
|
||||
"add": "Añadir perfil",
|
||||
"update": "Actualizar perfil",
|
||||
"viewAllProfiles": "Ver todos los perfiles",
|
||||
"activeProfileName": "Nombre del perfil activo: \"${name}\".",
|
||||
"nonActiveProfileName": "Seleccionar \"${name}\" como perfil activo",
|
||||
"freeSubNotFound": "No se encontró ninguna suscripción gratuita",
|
||||
"freeSubNotFoundForRegion": "No se encontró ninguna suscripción gratuita para la región \"${region}\"",
|
||||
"failedToLoad": "Error al cargar",
|
||||
"updateSubscriptions": "Actualizar suscripciones",
|
||||
"share": {
|
||||
"urlToClipboard": "URL al portapapeles",
|
||||
"showUrlQr": "Mostrar QR de la URL",
|
||||
"jsonToClipboard": "JSON al portapapeles"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Perfil guardado con éxito"
|
||||
},
|
||||
"invalidUrl": "URL no válida",
|
||||
"add": {
|
||||
"failure": "Error al añadir el perfil"
|
||||
},
|
||||
"update": {
|
||||
"success": "Perfil actualizado con éxito",
|
||||
"successNamed": "\"${name}\" actualizado con éxito",
|
||||
"failure": "Error al actualizar el perfil",
|
||||
"failureNamed": "Error al actualizar \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "Perfil eliminado con éxito"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Perfil",
|
||||
"lastUpdate": "Última actualización",
|
||||
"form": {
|
||||
"nameHint": "Nombre del perfil",
|
||||
"emptyName": "El nombre es obligatorio",
|
||||
"invalidUrl": "URL no válida",
|
||||
"urlHint": "URL de configuración completa",
|
||||
"disableAutoUpdate": "Desactivar actualización automática",
|
||||
"autoUpdateInterval": "Intervalo de actualización automática",
|
||||
"loading": "Añadiendo perfil..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Registros",
|
||||
"shareCoreLogs": "Compartir registros del núcleo",
|
||||
"shareAppLogs": "Compartir registros de la aplicación"
|
||||
},
|
||||
"about": {
|
||||
"title": "Acerca de",
|
||||
"notAvailableMsg": "Ya estás usando la última versión",
|
||||
"checkForUpdate": "Buscar actualizaciones",
|
||||
"openWorkingDir": "Abrir directorio de trabajo",
|
||||
"sourceCode": "Código fuente",
|
||||
"telegramChannel": "Canal de Telegram",
|
||||
"termsAndConditions": "Términos y condiciones",
|
||||
"privacyPolicy": "Política de privacidad"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ajustes",
|
||||
"resetTunnel": "Restablecer perfil de VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importar opciones desde el portapapeles",
|
||||
"file": "Importar opciones desde un archivo"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Copiar opciones anónimas al portapapeles",
|
||||
"anonymousToFile": "Exportar opciones anónimas a un archivo",
|
||||
"allToClipboard": "Copiar todas las opciones al portapapeles",
|
||||
"allToFile": "Exportar todas las opciones a un archivo"
|
||||
},
|
||||
"reset": "Restablecer opciones"
|
||||
},
|
||||
"general": {
|
||||
"title": "General",
|
||||
"locale": "Idioma",
|
||||
"themeMode": "Tema",
|
||||
"themeModes": {
|
||||
"system": "Por defecto del sistema",
|
||||
"dark": "Modo oscuro",
|
||||
"light": "Modo claro",
|
||||
"black": "Modo negro"
|
||||
},
|
||||
"enableAnalytics": "Habilitar análisis",
|
||||
"enableAnalyticsMsg": "Dar permiso para recopilar análisis y enviar informes de fallos para mejorar la aplicación",
|
||||
"autoIpCheck": "Comprobar IP de conexión automáticamente",
|
||||
"dynamicNotification": "Mostrar velocidad en la notificación",
|
||||
"hapticFeedback": "Respuesta háptica",
|
||||
"actionAtClosing": "Acción al cerrar",
|
||||
"autoStart": "Iniciar al arrancar",
|
||||
"silentStart": "Iniciar minimizado",
|
||||
"ignoreBatteryOptimizations": "Desactivar optimización de batería",
|
||||
"ignoreBatteryOptimizationsMsg": "Eliminar restricciones para un rendimiento óptimo de la VPN",
|
||||
"memoryLimit": "Límite de memoria",
|
||||
"memoryLimitMsg": "Habilitar si experimentas errores de falta de memoria o fallos frecuentes de la aplicación",
|
||||
"debugMode": "Modo de depuración",
|
||||
"debugModeMsg": "Reinicia la aplicación para aplicar este cambio",
|
||||
"logLevel": "Nivel de registro",
|
||||
"connectionTestUrl": "URL de prueba de conexión",
|
||||
"urlTestInterval": "Intervalo de prueba de URL",
|
||||
"clashApiPort": "Puerto de la API de Clash",
|
||||
"useXrayCoreWhenPossible": "Usar xray-core cuando sea posible",
|
||||
"useXrayCoreWhenPossibleMsg": "Usa xray-core al analizar enlaces de suscripción. Necesitas reimportar el enlace para habilitar esta opción"
|
||||
},
|
||||
"routing": {
|
||||
"title": "Enrutamiento",
|
||||
"perAppProxy": {
|
||||
"title": "Proxy por aplicación",
|
||||
"hideSysApps": "Ocultar aplicaciones del sistema",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importar selección desde el portapapeles",
|
||||
"file": "Importar selección desde un archivo",
|
||||
"msg": "La importación reemplazará tus selecciones actuales. ¿Estás seguro de que quieres continuar?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copiar selección al portapapeles",
|
||||
"file": "Exportar selección a un archivo"
|
||||
},
|
||||
"shareToAll": "Compartir con todos",
|
||||
"clearAllSelections": "Borrar todas las selecciones"
|
||||
},
|
||||
"modes": {
|
||||
"all": "Todo",
|
||||
"proxy": "Proxy",
|
||||
"bypass": "Omitir",
|
||||
"allMsg": "Usar proxy en todas las aplicaciones",
|
||||
"proxyMsg": "Usar proxy solo en aplicaciones seleccionadas",
|
||||
"bypassMsg": "No usar proxy en aplicaciones seleccionadas"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Selección automática",
|
||||
"performNow": "Ejecutar ahora",
|
||||
"resetToDefault": "Restablecer por defecto",
|
||||
"autoUpdateInterval": "Intervalo de actualización automática",
|
||||
"toast": {
|
||||
"success": "Selección automática de aplicaciones completada con éxito",
|
||||
"failure": "Fallo en la selección automática",
|
||||
"regionNotFound": "No se encontró selección automática para la región \"${region}\"",
|
||||
"alreadyInAuto": "Tus selecciones ya están en la lista automática"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Selección automática de aplicaciones",
|
||||
"msg": "La función de selección automática para el proxy por aplicación se ha desactivado debido al cambio de región a \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Región",
|
||||
"regions": {
|
||||
"ir": "Irán (ir) 🇮🇷",
|
||||
"cn": "China (cn) 🇨🇳",
|
||||
"ru": "Rusia (ru) 🇷🇺",
|
||||
"af": "Afganistán (af) 🇦🇫",
|
||||
"id": "Indonesia (id) 🇮🇩",
|
||||
"tr": "Turquía (tr) 🇹🇷",
|
||||
"br": "Brasil (br) 🇧🇷",
|
||||
"other": "Otro"
|
||||
},
|
||||
"blockAds": "Bloquear anuncios",
|
||||
"bypassLan": "Omitir LAN",
|
||||
"resolveDestination": "Resolver destino",
|
||||
"ipv6Route": "Ruta IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Desactivar",
|
||||
"enable": "Activar",
|
||||
"prefer": "Preferido",
|
||||
"only": "Exclusivo"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Reglas de enrutamiento",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importar reglas desde el portapapeles",
|
||||
"file": "Importar reglas desde un archivo"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copiar reglas al portapapeles",
|
||||
"file": "Guardar reglas en un archivo"
|
||||
},
|
||||
"reset": "Restablecer reglas"
|
||||
},
|
||||
"deleteRule": "Eliminar regla",
|
||||
"createRule": "Crear nueva regla",
|
||||
"rule": {
|
||||
"title": "Regla",
|
||||
"ruleChanged": "Regla modificada",
|
||||
"ruleChangedMsg": "¿Quieres guardar tus cambios?",
|
||||
"onlyTunMode": "Disponible solo en modo TUN",
|
||||
"notAvailabeInThisPlatform": "No disponible en esta plataforma",
|
||||
"canNotBeEmpty": "No puede estar vacío",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "\"URL\" válida como\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe or google chrome or chrome",
|
||||
"validProcessName": "\"Nombre de proceso\" válido como\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "\"Ruta de proceso\" válida como\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 or 1-65000",
|
||||
"validPortRange": "\"Puerto\" o \"Rango de puertos\" válido como\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 or 10.0.0.0/24",
|
||||
"validIpCidr": "IP CIDR válido como\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com or dl.google.com",
|
||||
"validDomain": "\"Dominio\" válido como\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com or .ir",
|
||||
"validDomainSuffix": "\"Sufijo de dominio\" válido como\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "Nombre",
|
||||
"outbound": "Salida si coincide",
|
||||
"rule_set": "URL del conjunto de reglas",
|
||||
"package_name": "Nombres de paquetes",
|
||||
"process_name": "Nombres de procesos",
|
||||
"process_path": "Rutas de procesos",
|
||||
"network": "Redes",
|
||||
"port_range": "Puertos de destino",
|
||||
"source_port_range": "Puertos de origen",
|
||||
"protocol": "Protocolo",
|
||||
"ip_cidr": "IP CIDR de destino",
|
||||
"source_ip_cidr": "IP CIDR de origen",
|
||||
"domain": "Dominio",
|
||||
"domain_suffixe": "Sufijo de dominio",
|
||||
"domain_keyword": "Palabra clave de dominio",
|
||||
"domain_regex": "Expresión regular de dominio"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Proxy",
|
||||
"direct": "Directo",
|
||||
"direct_with_fragment": "Directo con fragmento",
|
||||
"block": "Bloquear"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "Todo",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "Todos",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Añadir nuevo valor",
|
||||
"update": "Actualizar valor",
|
||||
"clearList": "Limpiar lista",
|
||||
"clearListMsg": "Todos los elementos han sido eliminados"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Aplicaciones de Android",
|
||||
"showSystemApps": "Mostrar aplicaciones del sistema",
|
||||
"hideSystemApps": "Ocultar aplicaciones del sistema",
|
||||
"clearSelection": "Borrar selección",
|
||||
"uninstalled": "Desinstalado"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "DNS remoto",
|
||||
"remoteDnsDomainStrategy": "Estrategia de dominio de DNS remoto",
|
||||
"directDns": "DNS directo",
|
||||
"directDnsDomainStrategy": "Estrategia de dominio de DNS directo",
|
||||
"enableDnsRouting": "Habilitar enrutamiento de DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "Automático",
|
||||
"preferIpv6": "Preferir IPv6",
|
||||
"preferIpv4": "Preferir IPv4",
|
||||
"ipv4Only": "Solo IPv4",
|
||||
"ipv6Only": "Solo IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Entrada",
|
||||
"serviceMode": "Modo de servicio",
|
||||
"serviceModes": {
|
||||
"proxy": "Solo servicio de proxy",
|
||||
"systemProxy": "Establecer proxy del sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Servicio VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Proxy del sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Servicio VPN"
|
||||
},
|
||||
"strictRoute": "Ruta estricta",
|
||||
"tunImplementation": "Implementación de TUN",
|
||||
"tunImplementations": {
|
||||
"mixed": "Mixto",
|
||||
"system": "Sistema",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Puerto mixto",
|
||||
"tproxyPort": "Puerto de proxy transparente",
|
||||
"directPort": "Puerto de Directo",
|
||||
"allowConnectionFromLan": "Compartir VPN en la red local"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "Trucos de TLS",
|
||||
"enable": "Habilitar fragmento",
|
||||
"size": "Tamaño de fragmento",
|
||||
"sleep": "Retraso de fragmento",
|
||||
"mixedSniCase": {
|
||||
"enable": "Habilitar mayúsculas/minúsculas mixtas en SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Habilitar relleno",
|
||||
"size": "Tamaño de relleno"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "Habilitar WARP",
|
||||
"generateConfig": "Generar configuración de WARP",
|
||||
"configGenerated": "Configuración de WARP generada",
|
||||
"missingConfig": "Falta la configuración de WARP",
|
||||
"detourMode": "Modo de desvío",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Desviar proxies a través de WARP",
|
||||
"warpOverProxy": "Desviar WARP a través de proxies",
|
||||
"proxyOverWarpExplain": "Desbloquear proxies con WARP",
|
||||
"warpOverProxyExplain": "Seguridad extra con WARP"
|
||||
},
|
||||
"licenseKey": "Clave de licencia",
|
||||
"cleanIp": "IP limpia",
|
||||
"port": "Puerto",
|
||||
"noise": {
|
||||
"count": "Cantidad de ruido",
|
||||
"mode": "Modo de ruido",
|
||||
"size": "Tamaño de ruido",
|
||||
"delay": "Retraso de ruido"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Conexión",
|
||||
"traffic": "Tráfico",
|
||||
"trafficLive": "Tráfico en tiempo real",
|
||||
"trafficTotal": "Tráfico total",
|
||||
"uplink": "Subida",
|
||||
"downlink": "Bajada",
|
||||
"speed": "Velocidad",
|
||||
"totalTransferred": "Total transferido"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Subida",
|
||||
"download": "Descarga",
|
||||
"total": "Tráfico total",
|
||||
"expireDate": "Fecha de caducidad",
|
||||
"expired": "Caducado",
|
||||
"noTraffic": "Cuota agotada",
|
||||
"remainingTime": "Tiempo restante",
|
||||
"remainingDuration": "${duration} días restantes",
|
||||
"remainingDurationNew": "${duration} días",
|
||||
"remainingTrafficSemanticLabel": "${consumed} de ${total} de tráfico consumido",
|
||||
"remainingTraffic": "Tráfico restante",
|
||||
"remainingUsage": "Restante",
|
||||
"profileSite": "Proveedor",
|
||||
"profileSupport": "Soporte"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Ordenar por",
|
||||
"sort": {
|
||||
"name": "Alfabéticamente",
|
||||
"lastUpdate": "Última actualización"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Consentimiento de Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP es un proveedor de VPN WireGuard gratuito. Al habilitar esta opción, aceptas los ${tos(Términos de servicio)} y la ${privacy(Política de privacidad)} de Cloudflare WARP."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Actualización disponible",
|
||||
"msg": "Hay disponible una nueva versión de @:common.appTitle. ¿Quieres actualizar ahora?",
|
||||
"currentVersion": "Versión actual: ",
|
||||
"newVersion": "Nueva versión: ",
|
||||
"updateNow": "Actualizar ahora"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "Esto reemplazará todas las opciones de configuración con los valores proporcionados. ¿Estás seguro?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Eliminar perfil",
|
||||
"msg": "¿Estás seguro de que quieres eliminar este perfil permanentemente?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Mejorando la selección automática",
|
||||
"msg": "Al compartir las aplicaciones seleccionadas, ayudas a completar la lista de \"selección automática\""
|
||||
},
|
||||
"import": {
|
||||
"msg": "Esto reemplazará todas tus selecciones actuales de proxy por aplicación. ¿Estás seguro de que quieres continuar?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Eliminar regla",
|
||||
"msg": "¿Estás seguro de que quieres eliminar la regla \"$rulename\"?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Funciones experimentales en uso",
|
||||
"msg": "Has habilitado algunas funciones experimentales que podrían afectar la calidad de la conexión y causar errores inesperados. Siempre puedes cambiar o restablecer estas opciones desde la página de configuración.",
|
||||
"disable": "No volver a mostrar"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Elige un perfil",
|
||||
"msg": "Para empezar, añade un perfil de conexión que incluya los detalles de tu conexión VPN.\n\n¿Aún no tienes un servidor VPN? No te preocupes, sigue el tutorial a continuación para configurar uno rápidamente y de forma gratuita.",
|
||||
"helpBtn": {
|
||||
"label": "Muéstrame cómo",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "Advertencia de enlace externo",
|
||||
"youAreAboutToVisit": "Estás a punto de visitar:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "Este sitio web no está en nuestra lista de confianza. Procede con precaución."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Etiqueta completa:",
|
||||
"type": "Tipo:",
|
||||
"testTime": "Hora de la prueba:",
|
||||
"testDelay": "Latencia de la prueba:",
|
||||
"isSelected": "Seleccionado:",
|
||||
"isGroup": "Es un grupo",
|
||||
"isSecure": "Es seguro:",
|
||||
"port": "Puerto:",
|
||||
"host": "Host:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "Código de país:",
|
||||
"region": "Región:",
|
||||
"city": "Ciudad:",
|
||||
"asn": "ASN:",
|
||||
"organization": "Organización:",
|
||||
"location": "Ubicación:",
|
||||
"postalCode": "Código postal:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Preguntar cada vez",
|
||||
"alertMessage": "¿Ocultar o salir de la aplicación?",
|
||||
"remember": "Recordar mi elección"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Toca para conectar",
|
||||
"connect": "Conectar",
|
||||
"connecting": "Conectando...",
|
||||
"connected": "Conectado",
|
||||
"disconnect": "Desconectar",
|
||||
"disconnecting": "Desconectando...",
|
||||
"reconnect": "Reconectar",
|
||||
"reconnectMsg": "Reconectando para aplicar los cambios...",
|
||||
"secure": "Protegido por WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Error inesperado",
|
||||
"connection": {
|
||||
"unexpected": "Error de conexión inesperado",
|
||||
"timeout": "Tiempo de conexión agotado",
|
||||
"badResponse": "Respuesta incorrecta",
|
||||
"connectionError": "Error de conexión",
|
||||
"badCertificate": "Certificado no válido"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Error inesperado",
|
||||
"notFound": "Perfil no encontrado",
|
||||
"invalidConfig": "Configuraciones no válidas",
|
||||
"invalidUrl": "URL no válida",
|
||||
"canceledByUser": "Cancelado por el usuario"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Fallo inesperado",
|
||||
"missingVpnPermission": "Falta el permiso de VPN",
|
||||
"missingNotificationPermission": "Falta el permiso de notificación",
|
||||
"core": "Error del núcleo"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "El servicio no se está ejecutando",
|
||||
"missingPrivilege": "Falta privilegio",
|
||||
"missingPrivilegeMsg": "El modo VPN requiere privilegios de administrador. Reinicia la aplicación como administrador o cambia el modo de servicio.",
|
||||
"invalidConfigOptions": "Opciones de configuración no válidas",
|
||||
"invalidConfig": "Configuración no válida"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "Falta la licencia de WARP",
|
||||
"missingLicenseMsg": "El perfil seleccionado utiliza la función WARP. Para usar esta función, debes aceptar la licencia de WARP."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "هیدیفای",
|
||||
"start": "شروع",
|
||||
"version": "نسخه",
|
||||
"ok": "باشه",
|
||||
"cancel": "لغو",
|
||||
"kContinue": "ادامه",
|
||||
"showMore": "نمایش بیشتر",
|
||||
"showLess": "نمایش کمتر",
|
||||
"filter": "فیلتر",
|
||||
"all": "همه",
|
||||
"pause": "مکث",
|
||||
"resume": "ادامه",
|
||||
"clear": "پاکسازی",
|
||||
"close": "بستن",
|
||||
"auto": "خودکار",
|
||||
"manually": "دستی",
|
||||
"name": "نام",
|
||||
"url": "URL",
|
||||
"add": "افزودن",
|
||||
"clipboard": "کلیپبورد",
|
||||
"addToClipboard": "افزودن به کلیپبورد",
|
||||
"scanQr": "اسکن QR",
|
||||
"free": "رایگان",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "راهنما",
|
||||
"save": "ذخیره",
|
||||
"update": "بهروزرسانی",
|
||||
"share": "اشتراکگذاری",
|
||||
"edit": "ویرایش",
|
||||
"delete": "حذف",
|
||||
"discard": "صرفنظر",
|
||||
"import": "وارد کردن",
|
||||
"export": "خروجی گرفتن",
|
||||
"later": "بعداً",
|
||||
"ignore": "نادیده گرفتن",
|
||||
"quit": "خروج",
|
||||
"notSet": "تنظیم نشده",
|
||||
"hide": "پنهان کردن",
|
||||
"exit": "خروج",
|
||||
"reset": "بازنشانی",
|
||||
"done": "انجام شد",
|
||||
"search": "جستجو",
|
||||
"decline": "رد کردن",
|
||||
"agree": "موافقم",
|
||||
"empty": "خالی",
|
||||
"unknown": "ناشناخته",
|
||||
"hidden": "پنهان",
|
||||
"timeout": "عدم پاسخ",
|
||||
"sort": "مرتبسازی",
|
||||
"dashboard": "داشبورد",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n روز",
|
||||
"other": "$n روز"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n ساعت",
|
||||
"other": "$n ساعت"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "دسترسی رد شد"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "با موفقیت در کلیپبورد کپی شد",
|
||||
"failure": "کپی در کلیپبورد ناموفق بود",
|
||||
"contentTooLarge": "محتوا بیش از حد بزرگ است. به جای آن از خروجی فایل استفاده کنید"
|
||||
},
|
||||
"file": {
|
||||
"success": "فایل JSON با موفقیت ایجاد شد",
|
||||
"failure": "ایجاد فایل ناموفق بود"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "تأیید ورود اطلاعات",
|
||||
"success": "با موفقیت وارد شد",
|
||||
"failure": "وارد کردن ناموفق بود"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "هرآنچه برای اینترنت بدون محدودیت نیاز دارید",
|
||||
"termsAndPolicyCaution(rich)": "با ادامه، شما با ${tap(@:pages.about.termsAndConditions)} موافقت میکنید",
|
||||
"info(rich)": "ساخته شده با ❤️ توسط هیدیفای - ${tap_source(متنباز)} (${tap_license(مجوز)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "خانه",
|
||||
"quickSettings": "تنظیمات سریع"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "پروکسیها",
|
||||
"sort": "مرتبسازی پروکسیها",
|
||||
"testDelay": "تست تأخیر",
|
||||
"empty": "هیچ پروکسی موجود نیست",
|
||||
"activeProxy": "پروکسی فعال",
|
||||
"unknownIp": "IP ناشناخته",
|
||||
"sortOptions": {
|
||||
"unsorted": "پیشفرض",
|
||||
"name": "بر اساس نام",
|
||||
"delay": "بر اساس تأخیر"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "آدرس IP",
|
||||
"country": "کشور",
|
||||
"organization": "سازمان"
|
||||
},
|
||||
"delay": {
|
||||
"result": "تأخیر: ${delay} میلیثانیه",
|
||||
"timeout": "تست تأخیر ناموفق بود",
|
||||
"testing": "تأخیر: در حال تست..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "پروفایلها",
|
||||
"add": "افزودن پروفایل",
|
||||
"update": "بهروزرسانی پروفایل",
|
||||
"viewAllProfiles": "مشاهده همه پروفایلها",
|
||||
"activeProfileName": "نام پروفایل فعال: «${name}»",
|
||||
"nonActiveProfileName": "انتخاب «${name}» به عنوان پروفایل فعال",
|
||||
"freeSubNotFound": "اشتراک رایگان یافت نشد",
|
||||
"freeSubNotFoundForRegion": "اشتراک رایگان برای منطقه «${region}» یافت نشد",
|
||||
"failedToLoad": "بارگذاری ناموفق بود",
|
||||
"updateSubscriptions": "بهروزرسانی اشتراکها",
|
||||
"share": {
|
||||
"urlToClipboard": "URL به کلیپبورد",
|
||||
"showUrlQr": "نمایش QR کد URL",
|
||||
"jsonToClipboard": "JSON به کلیپبورد"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "پروفایل با موفقیت ذخیره شد"
|
||||
},
|
||||
"invalidUrl": "URL نامعتبر است",
|
||||
"add": {
|
||||
"failure": "افزودن پروفایل ناموفق بود"
|
||||
},
|
||||
"update": {
|
||||
"success": "پروفایل با موفقیت بهروز شد",
|
||||
"successNamed": "«${name}» با موفقیت بهروز شد",
|
||||
"failure": "بهروزرسانی پروفایل ناموفق بود",
|
||||
"failureNamed": "بهروزرسانی «${name}» ناموفق بود"
|
||||
},
|
||||
"delete": {
|
||||
"success": "پروفایل با موفقیت حذف شد"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "پروفایل",
|
||||
"lastUpdate": "آخرین بهروزرسانی",
|
||||
"form": {
|
||||
"nameHint": "نام پروفایل",
|
||||
"emptyName": "نام الزامی است",
|
||||
"invalidUrl": "URL نامعتبر است",
|
||||
"urlHint": "URL کامل کانفیگ",
|
||||
"disableAutoUpdate": "غیرفعال کردن بهروزرسانی خودکار",
|
||||
"autoUpdateInterval": "فاصله زمانی بهروزرسانی خودکار",
|
||||
"loading": "در حال افزودن پروفایل..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "گزارشها",
|
||||
"shareCoreLogs": "اشتراکگذاری گزارشهای هسته",
|
||||
"shareAppLogs": "اشتراکگذاری گزارشهای برنامه"
|
||||
},
|
||||
"about": {
|
||||
"title": "درباره",
|
||||
"notAvailableMsg": "شما در حال استفاده از آخرین نسخه هستید",
|
||||
"checkForUpdate": "بررسی برای بهروزرسانی",
|
||||
"openWorkingDir": "باز کردن پوشه کاری",
|
||||
"sourceCode": "کد منبع",
|
||||
"telegramChannel": "کانال تلگرام",
|
||||
"termsAndConditions": "شرایط و ضوابط",
|
||||
"privacyPolicy": "سیاست حفظ حریم خصوصی"
|
||||
},
|
||||
"settings": {
|
||||
"title": "تنظیمات",
|
||||
"resetTunnel": "بازنشانی پروفایل VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "وارد کردن تنظیمات از کلیپبورد",
|
||||
"file": "وارد کردن تنظیمات از فایل"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "کپی تنظیمات ناشناس به کلیپبورد",
|
||||
"anonymousToFile": "خروجی تنظیمات ناشناس به فایل",
|
||||
"allToClipboard": "کپی تمام تنظیمات به کلیپبورد",
|
||||
"allToFile": "خروجی تمام تنظیمات به فایل"
|
||||
},
|
||||
"reset": "بازنشانی تنظیمات"
|
||||
},
|
||||
"general": {
|
||||
"title": "عمومی",
|
||||
"locale": "زبان",
|
||||
"themeMode": "حالت پوسته",
|
||||
"themeModes": {
|
||||
"system": "پیشفرض سیستم",
|
||||
"dark": "حالت تیره",
|
||||
"light": "حالت روشن",
|
||||
"black": "حالت مشکی"
|
||||
},
|
||||
"enableAnalytics": "فعالسازی آمار",
|
||||
"enableAnalyticsMsg": "اجازه جمعآوری آمار و ارسال گزارشهای خطا برای بهبود برنامه",
|
||||
"autoIpCheck": "بررسی خودکار IP اتصال",
|
||||
"dynamicNotification": "نمایش سرعت در اعلان",
|
||||
"hapticFeedback": "بازخورد لرزشی",
|
||||
"actionAtClosing": "اقدام هنگام بستن",
|
||||
"autoStart": "شروع هنگام ورود به سیستم",
|
||||
"silentStart": "شروع در حالت کمینه",
|
||||
"ignoreBatteryOptimizations": "غیرفعال کردن بهینهسازی باتری",
|
||||
"ignoreBatteryOptimizationsMsg": "حذف محدودیتها برای عملکرد بهینه VPN",
|
||||
"memoryLimit": "محدودیت حافظه",
|
||||
"memoryLimitMsg": "در صورت مواجهه با خطای کمبود حافظه یا بستهشدنهای مکرر برنامه، این گزینه را فعال کنید",
|
||||
"debugMode": "حالت اشکالزدایی",
|
||||
"debugModeMsg": "برای اعمال این تغییر، برنامه را مجدداً راهاندازی کنید",
|
||||
"logLevel": "سطح گزارشگیری",
|
||||
"connectionTestUrl": "URL تست اتصال",
|
||||
"urlTestInterval": "فاصله زمانی تست URL",
|
||||
"clashApiPort": "پورت Clash API",
|
||||
"useXrayCoreWhenPossible": "استفاده از xray-core در صورت امکان",
|
||||
"useXrayCoreWhenPossibleMsg": "هنگام پردازش لینکهای اشتراک از xray-core استفاده شود. برای فعالسازی این گزینه باید لینک اشتراک را مجدداً وارد کنید."
|
||||
},
|
||||
"routing": {
|
||||
"title": "مسیریابی",
|
||||
"perAppProxy": {
|
||||
"title": "پروکسی برای هر برنامه",
|
||||
"hideSysApps": "پنهان کردن برنامههای سیستمی",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "وارد کردن انتخابها از کلیپبورد",
|
||||
"file": "وارد کردن انتخابها از فایل",
|
||||
"msg": "وارد کردن، انتخابهای فعلی شما را جایگزین خواهد کرد. آیا مطمئن هستید که میخواهید ادامه دهید؟"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "کپی انتخابها به کلیپبورد",
|
||||
"file": "خروجی انتخابها به فایل"
|
||||
},
|
||||
"shareToAll": "اشتراکگذاری با همه",
|
||||
"clearAllSelections": "پاک کردن تمام انتخابها"
|
||||
},
|
||||
"modes": {
|
||||
"all": "همه",
|
||||
"proxy": "پروکسی",
|
||||
"bypass": "دور زدن",
|
||||
"allMsg": "پروکسی کردن تمام برنامهها",
|
||||
"proxyMsg": "فقط برنامههای انتخابشده پروکسی شوند",
|
||||
"bypassMsg": "برنامههای انتخابشده پروکسی نشوند"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "انتخاب خودکار",
|
||||
"performNow": "اکنون انجام بده",
|
||||
"resetToDefault": "بازنشانی به پیشفرض",
|
||||
"autoUpdateInterval": "فاصله زمانی بهروزرسانی خودکار",
|
||||
"toast": {
|
||||
"success": "انتخاب خودکار برنامهها با موفقیت انجام شد",
|
||||
"failure": "انتخاب خودکار ناموفق بود",
|
||||
"regionNotFound": "انتخاب خودکار برای منطقه «${region}» یافت نشد",
|
||||
"alreadyInAuto": "انتخابهای شما از قبل در لیست خودکار موجود است"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "انتخاب خودکار برنامهها",
|
||||
"msg": "قابلیت انتخاب خودکار برای پروکسی هر برنامه به دلیل تغییر منطقه به «${region}» غیرفعال شد"
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "منطقه",
|
||||
"regions": {
|
||||
"ir": "ایران (ir) 🇮🇷",
|
||||
"cn": "چین (cn) 🇨🇳",
|
||||
"ru": "روسیه (ru) 🇷🇺",
|
||||
"af": "افغانستان (af) 🇦🇫",
|
||||
"id": "اندونزی (id) 🇮🇩",
|
||||
"tr": "ترکیه (tr) 🇹🇷",
|
||||
"br": "برزیل (br) 🇧🇷",
|
||||
"other": "سایر"
|
||||
},
|
||||
"blockAds": "مسدودسازی تبلیغات",
|
||||
"bypassLan": "دور زدن LAN",
|
||||
"resolveDestination": "تحلیل آدرس مقصد",
|
||||
"ipv6Route": "مسیریابی IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "غیرفعال",
|
||||
"enable": "فعال",
|
||||
"prefer": "ترجیحی",
|
||||
"only": "انحصاری"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "قوانین مسیریابی",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "وارد کردن قوانین از کلیپبورد",
|
||||
"file": "وارد کردن قوانین از فایل"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "کپی قوانین در کلیپبورد",
|
||||
"file": "ذخیره قوانین در فایل"
|
||||
},
|
||||
"reset": "بازنشانی قوانین"
|
||||
},
|
||||
"deleteRule": "حذف قانون",
|
||||
"createRule": "ایجاد قانون جدید",
|
||||
"rule": {
|
||||
"title": "قانون",
|
||||
"ruleChanged": "قانون تغییر کرد",
|
||||
"ruleChangedMsg": "آیا میخواهید ویرایشهای خود را ذخیره کنید؟",
|
||||
"onlyTunMode": "فقط در حالت TUN در دسترس است",
|
||||
"notAvailabeInThisPlatform": "در این پلتفرم در دسترس نیست",
|
||||
"canNotBeEmpty": "نمیتواند خالی باشد",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "«URL» معتبر مانند\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe یا google chrome یا chrome",
|
||||
"validProcessName": "«نام فرآیند» معتبر مانند\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "«مسیر فرآیند» معتبر مانند\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 یا 1-65000",
|
||||
"validPortRange": "«پورت» یا «محدوده پورت» معتبر مانند\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 یا 10.0.0.0/24",
|
||||
"validIpCidr": "IP CIDR معتبر مانند\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com یا dl.google.com",
|
||||
"validDomain": "«دامنه» معتبر مانند\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com یا .ir",
|
||||
"validDomainSuffix": "«پسوند دامنه» معتبر مانند\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "نام",
|
||||
"outbound": "خروجی در صورت تطابق",
|
||||
"rule_set": "URL مجموعه قوانین",
|
||||
"package_name": "نامهای بسته",
|
||||
"process_name": "نامهای فرآیند",
|
||||
"process_path": "مسیرهای فرآیند",
|
||||
"network": "شبکهها",
|
||||
"port_range": "پورتهای مقصد",
|
||||
"source_port_range": "پورتهای مبدأ",
|
||||
"protocol": "پروتکل",
|
||||
"ip_cidr": "IP CIDR مقصد",
|
||||
"source_ip_cidr": "IP CIDR مبدأ",
|
||||
"domain": "دامنه",
|
||||
"domain_suffixe": "پسوند دامنه",
|
||||
"domain_keyword": "کلمه کلیدی دامنه",
|
||||
"domain_regex": "عبارت منظم دامنه"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "پروکسی",
|
||||
"direct": "مستقیم",
|
||||
"direct_with_fragment": "مستقیم با فرگمنت",
|
||||
"block": "مسدود"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "همه",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "همه",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "افزودن مقدار جدید",
|
||||
"update": "بهروزرسانی مقدار",
|
||||
"clearList": "پاک کردن لیست",
|
||||
"clearListMsg": "تمام موارد حذف شدند"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "برنامههای اندروید",
|
||||
"showSystemApps": "نمایش برنامههای سیستمی",
|
||||
"hideSystemApps": "پنهان کردن برنامههای سیستمی",
|
||||
"clearSelection": "پاک کردن انتخابها",
|
||||
"uninstalled": "نصب نشده"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "DNS اصلی (ریموت)",
|
||||
"remoteDnsDomainStrategy": "استراتژی دامنه DNS ",
|
||||
"directDns": "DNS پروکسیها (مستقیم)",
|
||||
"directDnsDomainStrategy": "استراتژی دامنه DNS مستقیم",
|
||||
"enableDnsRouting": "فعالسازی مسیریابی DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "خودکار",
|
||||
"preferIpv6": "ترجیح IPv6",
|
||||
"preferIpv4": "ترجیح IPv4",
|
||||
"ipv4Only": "فقط IPv4",
|
||||
"ipv6Only": "فقط IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "ورودی",
|
||||
"serviceMode": "حالت سرویس",
|
||||
"serviceModes": {
|
||||
"proxy": "فقط سرویس پروکسی",
|
||||
"systemProxy": "تنظیم پروکسی سیستم",
|
||||
"tun": "VPN",
|
||||
"tunService": "سرویس VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "پروکسی",
|
||||
"systemProxy": "پروکسی سیستم",
|
||||
"tun": "VPN",
|
||||
"tunService": "سرویس VPN"
|
||||
},
|
||||
"strictRoute": "مسیربندی سختگیرانه",
|
||||
"tunImplementation": "پیادهسازی Tun",
|
||||
"tunImplementations": {
|
||||
"mixed": "ترکیبی",
|
||||
"system": "سیستم",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "پورت ترکیبی",
|
||||
"tproxyPort": "پورت پروکسی شفاف",
|
||||
"directPort": "پورت مستقیم",
|
||||
"allowConnectionFromLan": "اشتراک VPN در شبکه محلی"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "ترفندهای TLS",
|
||||
"enable": "فعالسازی fragment",
|
||||
"size": "اندازه fragment",
|
||||
"sleep": "تأخیر fragment",
|
||||
"mixedSniCase": {
|
||||
"enable": "فعالسازی mixed SNI case"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "فعالسازی padding",
|
||||
"size": "اندازه padding"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "فعالسازی WARP",
|
||||
"generateConfig": "ایجاد کانفیگ WARP",
|
||||
"configGenerated": "کانفیگ Warp ایجاد شد",
|
||||
"missingConfig": "کانفیگ WARP موجود نیست",
|
||||
"detourMode": "حالت مسیریابی WARP",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "عبور پروکسیها از طریق WARP",
|
||||
"warpOverProxy": "عبور WARP از طریق پروکسیها",
|
||||
"proxyOverWarpExplain": "رفع انسداد پروکسیها با WARP",
|
||||
"warpOverProxyExplain": "امنیت بیشتر با WARP"
|
||||
},
|
||||
"licenseKey": "کلید لایسنس",
|
||||
"cleanIp": "IP تمیز",
|
||||
"port": "پورت",
|
||||
"noise": {
|
||||
"count": "تعداد نویز",
|
||||
"mode": "حالت نویز",
|
||||
"size": "اندازه نویز",
|
||||
"delay": "تأخیر نویز"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "اتصال",
|
||||
"traffic": "ترافیک",
|
||||
"trafficLive": "ترافیک لحظهای",
|
||||
"trafficTotal": "ترافیک کل",
|
||||
"uplink": "ارسال",
|
||||
"downlink": "دریافت",
|
||||
"speed": "سرعت",
|
||||
"totalTransferred": "کل منتقل شده"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "آپلود",
|
||||
"download": "دانلود",
|
||||
"total": "کل ترافیک",
|
||||
"expireDate": "تاریخ انقضا",
|
||||
"expired": "منقضی شده",
|
||||
"noTraffic": "حجم تمام شده",
|
||||
"remainingTime": "زمان باقیمانده",
|
||||
"remainingDuration": "${duration} روز باقیمانده",
|
||||
"remainingDurationNew": "${duration} روز",
|
||||
"remainingTrafficSemanticLabel": "${consumed} از ${total} ترافیک مصرف شده",
|
||||
"remainingTraffic": "ترافیک باقیمانده",
|
||||
"remainingUsage": "باقیمانده",
|
||||
"profileSite": "سرویسدهنده",
|
||||
"profileSupport": "پشتیبانی"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "مرتبسازی بر اساس",
|
||||
"sort": {
|
||||
"name": "بر اساس نام",
|
||||
"lastUpdate": "آخرین بهروزرسانی"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "رضایتنامه Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP یک ارائهدهنده رایگان WireGuard VPN است. با فعال کردن این گزینه، شما با ${tos(شرایط خدمات)} و ${privacy(سیاست حفظ حریم خصوصی)} Cloudflare WARP موافقت میکنید."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "بهروزرسانی موجود است",
|
||||
"msg": "نسخه جدیدی از @:common.appTitle در دسترس است. آیا مایل به بهروزرسانی هستید؟",
|
||||
"currentVersion": "نسخه فعلی: ",
|
||||
"newVersion": "نسخه جدید: ",
|
||||
"updateNow": "اکنون بهروزرسانی کن"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "این عمل تمام تنظیمات فعلی شما را بازنویسی خواهد کرد. آیا مطمئن هستید؟"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "حذف پروفایل",
|
||||
"msg": "آیا از حذف دائمی این پروفایل مطمئن هستید؟"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "بهبود انتخاب خودکار",
|
||||
"msg": "با اشتراکگذاری برنامههای انتخابشده، به تکمیل لیست «انتخاب خودکار» کمک میکنید"
|
||||
},
|
||||
"import": {
|
||||
"msg": "این عمل تمام انتخابهای فعلی شما برای پروکسی برنامهها را جایگزین خواهد کرد. آیا مطمئن هستید؟"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "حذف قانون",
|
||||
"msg": "آیا از حذف قانون «$rulename» مطمئن هستید؟"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "ویژگیهای آزمایشی در حال استفاده",
|
||||
"msg": "شما برخی ویژگیهای آزمایشی را فعال کردهاید که ممکن است بر کیفیت اتصال تأثیر گذاشته و باعث خطاهای غیرمنتظره شوند. همیشه میتوانید این گزینهها را از صفحه تنظیمات تغییر داده یا بازنشانی کنید.",
|
||||
"disable": "دیگر نمایش نده"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "یک پروفایل انتخاب کنید",
|
||||
"msg": "بیایید با افزودن یک پروفایل اتصال که شامل جزئیات اتصال VPN شماست، شروع کنیم.\n\nهنوز سرور VPN ندارید؟ نگران نباشید، با دنبال کردن راهنمای زیر میتوانید به سرعت و رایگان یکی برای خودتان بسازید.",
|
||||
"helpBtn": {
|
||||
"label": "راهنمایی کن",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "هشدار لینک خارجی",
|
||||
"youAreAboutToVisit": "شما در حال بازدید از این آدرس هستید:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "این وبسایت در لیست مورد اعتماد ما نیست. لطفاً با احتیاط ادامه دهید."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "تگ کامل:",
|
||||
"type": "نوع:",
|
||||
"testTime": "زمان تست:",
|
||||
"testDelay": "تأخیر تست:",
|
||||
"isSelected": "انتخاب شده:",
|
||||
"isGroup": "گروه است",
|
||||
"isSecure": "امن است:",
|
||||
"port": "پورت:",
|
||||
"host": "میزبان:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "کد کشور:",
|
||||
"region": "منطقه:",
|
||||
"city": "شهر:",
|
||||
"asn": "ASN:",
|
||||
"organization": "سازمان:",
|
||||
"location": "مکان:",
|
||||
"postalCode": "کد پستی:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "هر بار بپرس",
|
||||
"alertMessage": "پنهان کردن یا خروج از برنامه؟",
|
||||
"remember": "انتخابم را به خاطر بسپار"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "برای اتصال ضربه بزنید",
|
||||
"connect": "اتصال",
|
||||
"connecting": "در حال اتصال...",
|
||||
"connected": "متصل شد",
|
||||
"disconnect": "قطع اتصال",
|
||||
"disconnecting": "در حال قطع اتصال...",
|
||||
"reconnect": "اتصال مجدد",
|
||||
"reconnectMsg": "در حال اتصال مجدد برای اعمال تغییرات...",
|
||||
"secure": "ایمن شده با WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"connection": {
|
||||
"unexpected": "خطای غیرمنتظره در اتصال",
|
||||
"timeout": "اتصال با وقفه زمانی مواجه شد",
|
||||
"badResponse": "پاسخ نامعتبر",
|
||||
"connectionError": "خطای اتصال",
|
||||
"badCertificate": "گواهینامه نامعتبر"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"notFound": "پروفایل یافت نشد",
|
||||
"invalidConfig": "کانفیگهای نامعتبر",
|
||||
"invalidUrl": "URL نامعتبر",
|
||||
"canceledByUser": "توسط کاربر لغو شد"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "شکست غیرمنتظره",
|
||||
"missingVpnPermission": "مجوز VPN وجود ندارد",
|
||||
"missingNotificationPermission": "مجوز اعلان وجود ندارد",
|
||||
"core": "خطای هسته"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "سرویس در حال اجرا نیست",
|
||||
"missingPrivilege": "دسترسی وجود ندارد",
|
||||
"missingPrivilegeMsg": "حالت VPN به دسترسی ادمین نیاز دارد. یا برنامه را به عنوان ادمین مجدداً راهاندازی کنید یا حالت سرویس را تغییر دهید.",
|
||||
"invalidConfigOptions": "گزینههای پیکربندی نامعتبر",
|
||||
"invalidConfig": "پیکربندی نامعتبر"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "لایسنس Warp",
|
||||
"missingLicenseMsg": "پروفایل انتخابشده از ویژگی WARP استفاده میکند؛ برای استفاده از این قابلیت، باید با لایسنس WARP موافقت شود."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Commencer",
|
||||
"version": "Version",
|
||||
"ok": "OK",
|
||||
"cancel": "Annuler",
|
||||
"kContinue": "Continuer",
|
||||
"showMore": "Afficher plus",
|
||||
"showLess": "Afficher moins",
|
||||
"filter": "Filtrer",
|
||||
"all": "Tous",
|
||||
"pause": "Pause",
|
||||
"resume": "Reprendre",
|
||||
"clear": "Effacer",
|
||||
"close": "Fermer",
|
||||
"auto": "Automatique",
|
||||
"manually": "Manuellement",
|
||||
"name": "Nom",
|
||||
"url": "URL",
|
||||
"add": "Ajouter",
|
||||
"clipboard": "Presse-papiers",
|
||||
"addToClipboard": "Ajouter au presse-papiers",
|
||||
"scanQr": "Scanner le QR code",
|
||||
"free": "Gratuit",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "Aide",
|
||||
"save": "Enregistrer",
|
||||
"update": "Mettre à jour",
|
||||
"share": "Partager",
|
||||
"edit": "Modifier",
|
||||
"delete": "Supprimer",
|
||||
"discard": "Ignorer",
|
||||
"import": "Importer",
|
||||
"export": "Exporter",
|
||||
"later": "Plus tard",
|
||||
"ignore": "Ignorer",
|
||||
"quit": "Quitter",
|
||||
"notSet": "Non défini",
|
||||
"hide": "Masquer",
|
||||
"exit": "Quitter",
|
||||
"reset": "Réinitialiser",
|
||||
"done": "Terminé",
|
||||
"search": "Rechercher",
|
||||
"decline": "Refuser",
|
||||
"agree": "Accepter",
|
||||
"empty": "Vide",
|
||||
"unknown": "Inconnu",
|
||||
"hidden": "Caché",
|
||||
"timeout": "Délai expiré",
|
||||
"sort": "Trier",
|
||||
"dashboard": "Tableau de bord",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n jour",
|
||||
"other": "$n jours"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n heure",
|
||||
"other": "$n heures"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "Permission refusée"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Ajouté au presse-papiers avec succès",
|
||||
"failure": "Échec de la copie dans le presse-papiers",
|
||||
"contentTooLarge": "Contenu trop volumineux. Utilisez plutôt l'exportation de fichier"
|
||||
},
|
||||
"file": {
|
||||
"success": "Fichier JSON créé avec succès",
|
||||
"failure": "Échec de la création du fichier"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "Confirmer l'importation",
|
||||
"success": "Importé avec succès",
|
||||
"failure": "Échec de l'importation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "Tout ce dont vous avez besoin pour un internet sans restrictions",
|
||||
"termsAndPolicyCaution(rich)": "En continuant, vous acceptez les ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "Fait avec ❤️ par Hiddify - ${tap_source(Open Source)} (${tap_license(Licence)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Accueil",
|
||||
"quickSettings": "Réglages rapides"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Proxys",
|
||||
"sort": "Trier les proxys",
|
||||
"testDelay": "Tester le délai",
|
||||
"empty": "Aucun proxy disponible",
|
||||
"activeProxy": "Proxy actif",
|
||||
"unknownIp": "IP inconnue",
|
||||
"sortOptions": {
|
||||
"unsorted": "Par défaut",
|
||||
"name": "Alphabétiquement",
|
||||
"delay": "Par latence"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "Adresse IP",
|
||||
"country": "Pays",
|
||||
"organization": "Organisation"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Latence : ${delay} ms",
|
||||
"timeout": "Délai du test de latence expiré",
|
||||
"testing": "Latence : test en cours..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Profils",
|
||||
"add": "Ajouter un profil",
|
||||
"update": "Mettre à jour le profil",
|
||||
"viewAllProfiles": "Voir tous les profils",
|
||||
"activeProfileName": "Nom du profil actif : \"${name}\".",
|
||||
"nonActiveProfileName": "Sélectionner \"${name}\" comme profil actif",
|
||||
"freeSubNotFound": "Aucun abonnement gratuit trouvé",
|
||||
"freeSubNotFoundForRegion": "Aucun abonnement gratuit trouvé pour la région \"${region}\"",
|
||||
"failedToLoad": "Échec du chargement",
|
||||
"updateSubscriptions": "Mettre à jour les abonnements",
|
||||
"share": {
|
||||
"urlToClipboard": "URL dans le presse-papiers",
|
||||
"showUrlQr": "Afficher le QR code de l'URL",
|
||||
"jsonToClipboard": "JSON dans le presse-papiers"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Profil enregistré avec succès"
|
||||
},
|
||||
"invalidUrl": "URL invalide",
|
||||
"add": {
|
||||
"failure": "Échec de l'ajout du profil"
|
||||
},
|
||||
"update": {
|
||||
"success": "Profil mis à jour avec succès",
|
||||
"successNamed": "\"${name}\" a été mis à jour avec succès",
|
||||
"failure": "Échec de la mise à jour du profil",
|
||||
"failureNamed": "Échec de la mise à jour de \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "Profil supprimé avec succès"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Profil",
|
||||
"lastUpdate": "Dernière mise à jour",
|
||||
"form": {
|
||||
"nameHint": "Nom du profil",
|
||||
"emptyName": "Le nom est requis",
|
||||
"invalidUrl": "URL invalide",
|
||||
"urlHint": "URL complète de la configuration",
|
||||
"disableAutoUpdate": "Désactiver la mise à jour automatique",
|
||||
"autoUpdateInterval": "Intervalle de mise à jour automatique",
|
||||
"loading": "Ajout du profil..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Journaux",
|
||||
"shareCoreLogs": "Partager les journaux du noyau",
|
||||
"shareAppLogs": "Partager les journaux de l'application"
|
||||
},
|
||||
"about": {
|
||||
"title": "À propos",
|
||||
"notAvailableMsg": "Vous utilisez déjà la dernière version",
|
||||
"checkForUpdate": "Vérifier les mises à jour",
|
||||
"openWorkingDir": "Ouvrir le répertoire de travail",
|
||||
"sourceCode": "Code source",
|
||||
"telegramChannel": "Canal Telegram",
|
||||
"termsAndConditions": "Conditions d'utilisation",
|
||||
"privacyPolicy": "Politique de confidentialité"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Paramètres",
|
||||
"resetTunnel": "Réinitialiser le profil VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importer les options depuis le presse-papiers",
|
||||
"file": "Importer les options depuis un fichier"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Copier les options anonymes dans le presse-papiers",
|
||||
"anonymousToFile": "Exporter les options anonymes vers un fichier",
|
||||
"allToClipboard": "Copier toutes les options dans le presse-papiers",
|
||||
"allToFile": "Exporter toutes les options vers un fichier"
|
||||
},
|
||||
"reset": "Réinitialiser les options"
|
||||
},
|
||||
"general": {
|
||||
"title": "Général",
|
||||
"locale": "Langue",
|
||||
"themeMode": "Thème",
|
||||
"themeModes": {
|
||||
"system": "Thème du système par défaut",
|
||||
"dark": "Mode sombre",
|
||||
"light": "Mode clair",
|
||||
"black": "Mode noir"
|
||||
},
|
||||
"enableAnalytics": "Activer les statistiques",
|
||||
"enableAnalyticsMsg": "Autoriser la collecte de statistiques et de rapports d'erreurs pour améliorer l'application",
|
||||
"autoIpCheck": "Vérifier automatiquement l'IP de connexion",
|
||||
"dynamicNotification": "Afficher la vitesse dans la notification",
|
||||
"hapticFeedback": "Retour haptique",
|
||||
"actionAtClosing": "Action à la fermeture",
|
||||
"autoStart": "Lancer au démarrage",
|
||||
"silentStart": "Démarrer réduit",
|
||||
"ignoreBatteryOptimizations": "Désactiver l'optimisation de la batterie",
|
||||
"ignoreBatteryOptimizationsMsg": "Supprimer les restrictions pour une performance VPN optimale",
|
||||
"memoryLimit": "Limite de mémoire",
|
||||
"memoryLimitMsg": "Activer si vous rencontrez des erreurs de mémoire insuffisante ou des plantages fréquents de l'application",
|
||||
"debugMode": "Mode de débogage",
|
||||
"debugModeMsg": "Redémarrez l'application pour appliquer cette modification",
|
||||
"logLevel": "Niveau de journalisation",
|
||||
"connectionTestUrl": "URL de test de connexion",
|
||||
"urlTestInterval": "Intervalle de test de l'URL",
|
||||
"clashApiPort": "Port de l'API Clash",
|
||||
"useXrayCoreWhenPossible": "Utiliser xray-core si possible",
|
||||
"useXrayCoreWhenPossibleMsg": "Utilisez xray-core lors de l'analyse des liens d'abonnement. Vous devez réimporter le lien pour activer cette option"
|
||||
},
|
||||
"routing": {
|
||||
"title": "Routage",
|
||||
"perAppProxy": {
|
||||
"title": "Proxy par application",
|
||||
"hideSysApps": "Masquer les applications système",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importer la sélection depuis le presse-papiers",
|
||||
"file": "Importer la sélection depuis un fichier",
|
||||
"msg": "L'importation remplacera vos sélections actuelles. Êtes-vous sûr de vouloir continuer ?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copier la sélection dans le presse-papiers",
|
||||
"file": "Exporter la sélection vers un fichier"
|
||||
},
|
||||
"shareToAll": "Partager avec tous",
|
||||
"clearAllSelections": "Effacer toutes les sélections"
|
||||
},
|
||||
"modes": {
|
||||
"all": "Toutes",
|
||||
"proxy": "Proxy",
|
||||
"bypass": "Contourner",
|
||||
"allMsg": "Utiliser le proxy pour toutes les applications",
|
||||
"proxyMsg": "Utiliser le proxy uniquement pour les applications sélectionnées",
|
||||
"bypassMsg": "Ne pas utiliser le proxy pour les applications sélectionnées"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Sélection automatique",
|
||||
"performNow": "Exécuter maintenant",
|
||||
"resetToDefault": "Réinitialiser par défaut",
|
||||
"autoUpdateInterval": "Intervalle de mise à jour automatique",
|
||||
"toast": {
|
||||
"success": "Sélection automatique des applications terminée avec succès",
|
||||
"failure": "Échec de la sélection automatique",
|
||||
"regionNotFound": "Sélection automatique non trouvée pour la région \"${region}\"",
|
||||
"alreadyInAuto": "Vos sélections sont déjà dans la liste automatique"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Sélection automatique des applications",
|
||||
"msg": "La fonction de sélection automatique pour le proxy par application a été désactivée en raison du changement de région vers \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Région",
|
||||
"regions": {
|
||||
"ir": "Iran (ir) 🇮🇷",
|
||||
"cn": "Chine (cn) 🇨🇳",
|
||||
"ru": "Russie (ru) 🇷🇺",
|
||||
"af": "Afghanistan (af) 🇦🇫",
|
||||
"id": "Indonésie (id) 🇮🇩",
|
||||
"tr": "Turquie (tr) 🇹🇷",
|
||||
"br": "Brésil (br) 🇧🇷",
|
||||
"other": "Autre"
|
||||
},
|
||||
"blockAds": "Bloquer les publicités",
|
||||
"bypassLan": "Contourner le LAN",
|
||||
"resolveDestination": "Résoudre la destination",
|
||||
"ipv6Route": "Route IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Désactiver",
|
||||
"enable": "Activer",
|
||||
"prefer": "Préféré",
|
||||
"only": "Uniquement"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Règles de routage",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importer les règles depuis le presse-papiers",
|
||||
"file": "Importer les règles depuis un fichier"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copier les règles dans le presse-papiers",
|
||||
"file": "Enregistrer les règles dans un fichier"
|
||||
},
|
||||
"reset": "Réinitialiser les règles"
|
||||
},
|
||||
"deleteRule": "Supprimer la règle",
|
||||
"createRule": "Créer une nouvelle règle",
|
||||
"rule": {
|
||||
"title": "Règle",
|
||||
"ruleChanged": "Règle modifiée",
|
||||
"ruleChangedMsg": "Voulez-vous enregistrer vos modifications ?",
|
||||
"onlyTunMode": "Disponible uniquement en mode TUN",
|
||||
"notAvailabeInThisPlatform": "Non disponible sur cette plateforme",
|
||||
"canNotBeEmpty": "Ne peut pas être vide",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "\"URL\" valide comme\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe ou google chrome ou chrome",
|
||||
"validProcessName": "\"Nom de processus\" valide comme\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "\"Chemin de processus\" valide comme\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 ou 1-65000",
|
||||
"validPortRange": "\"Port\" ou \"Plage de ports\" valide comme\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 ou 10.0.0.0/24",
|
||||
"validIpCidr": "IP CIDR valide comme\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com ou dl.google.com",
|
||||
"validDomain": "\"Domaine\" valide comme\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com ou .ir",
|
||||
"validDomainSuffix": "\"Suffixe de domaine\" valide comme\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "Nom",
|
||||
"outbound": "Sortie si correspondance",
|
||||
"rule_set": "URL de l'ensemble de règles",
|
||||
"package_name": "Noms de paquets",
|
||||
"process_name": "Noms de processus",
|
||||
"process_path": "Chemins de processus",
|
||||
"network": "Réseaux",
|
||||
"port_range": "Ports de destination",
|
||||
"source_port_range": "Ports source",
|
||||
"protocol": "Protocole",
|
||||
"ip_cidr": "IP CIDR de destination",
|
||||
"source_ip_cidr": "IP CIDR source",
|
||||
"domain": "Domaine",
|
||||
"domain_suffixe": "Suffixe de domaine",
|
||||
"domain_keyword": "Mot-clé de domaine",
|
||||
"domain_regex": "Expression régulière de domaine"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Proxy",
|
||||
"direct": "Direct",
|
||||
"direct_with_fragment": "Direct avec fragment",
|
||||
"block": "Bloquer"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "Tous",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "Tous",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Ajouter une nouvelle valeur",
|
||||
"update": "Mettre à jour la valeur",
|
||||
"clearList": "Vider la liste",
|
||||
"clearListMsg": "Tous les éléments ont été supprimés"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Applications Android",
|
||||
"showSystemApps": "Afficher les applications système",
|
||||
"hideSystemApps": "Masquer les applications système",
|
||||
"clearSelection": "Effacer la sélection",
|
||||
"uninstalled": "Désinstallé"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "DNS distant",
|
||||
"remoteDnsDomainStrategy": "Stratégie de domaine DNS distant",
|
||||
"directDns": "DNS direct",
|
||||
"directDnsDomainStrategy": "Stratégie de domaine DNS direct",
|
||||
"enableDnsRouting": "Activer le routage DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "Automatique",
|
||||
"preferIpv6": "Préférer IPv6",
|
||||
"preferIpv4": "Préférer IPv4",
|
||||
"ipv4Only": "IPv4 uniquement",
|
||||
"ipv6Only": "IPv6 uniquement"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Entrant",
|
||||
"serviceMode": "Mode de service",
|
||||
"serviceModes": {
|
||||
"proxy": "Service proxy uniquement",
|
||||
"systemProxy": "Définir le proxy système",
|
||||
"tun": "VPN",
|
||||
"tunService": "Service VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Proxy système",
|
||||
"tun": "VPN",
|
||||
"tunService": "Service VPN"
|
||||
},
|
||||
"strictRoute": "Routage strict",
|
||||
"tunImplementation": "Implémentation TUN",
|
||||
"tunImplementations": {
|
||||
"mixed": "Mixte",
|
||||
"system": "Système",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Port mixte",
|
||||
"tproxyPort": "Port de proxy transparent",
|
||||
"directPort": "Port direct local",
|
||||
"allowConnectionFromLan": "Partager le VPN sur le réseau local"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "Astuces TLS",
|
||||
"enable": "Activer le fragment",
|
||||
"size": "Taille du fragment",
|
||||
"sleep": "Délai du fragment",
|
||||
"mixedSniCase": {
|
||||
"enable": "Activer la casse mixte pour SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Activer le remplissage",
|
||||
"size": "Taille du remplissage"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "Activer WARP",
|
||||
"generateConfig": "Générer la configuration WARP",
|
||||
"configGenerated": "Configuration WARP générée",
|
||||
"missingConfig": "Configuration WARP manquante",
|
||||
"detourMode": "Mode de détour",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Détourner les proxys via WARP",
|
||||
"warpOverProxy": "Détourner WARP via les proxys",
|
||||
"proxyOverWarpExplain": "Débloquer les proxys avec WARP",
|
||||
"warpOverProxyExplain": "Sécurité supplémentaire avec WARP"
|
||||
},
|
||||
"licenseKey": "Clé de licence",
|
||||
"cleanIp": "IP propre",
|
||||
"port": "Port",
|
||||
"noise": {
|
||||
"count": "Nombre de bruits",
|
||||
"mode": "Mode bruit",
|
||||
"size": "Taille du bruit",
|
||||
"delay": "Délai du bruit"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Connexion",
|
||||
"traffic": "Trafic",
|
||||
"trafficLive": "Trafic en direct",
|
||||
"trafficTotal": "Trafic total",
|
||||
"uplink": "Envoi",
|
||||
"downlink": "Réception",
|
||||
"speed": "Vitesse",
|
||||
"totalTransferred": "Total transféré"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Envoi",
|
||||
"download": "Téléchargement",
|
||||
"total": "Trafic total",
|
||||
"expireDate": "Date d'expiration",
|
||||
"expired": "Expiré",
|
||||
"noTraffic": "Quota épuisé",
|
||||
"remainingTime": "Temps restant",
|
||||
"remainingDuration": "${duration} jours restants",
|
||||
"remainingDurationNew": "${duration} jours",
|
||||
"remainingTrafficSemanticLabel": "${consumed} sur ${total} de trafic consommé",
|
||||
"remainingTraffic": "Trafic restant",
|
||||
"remainingUsage": "Restant",
|
||||
"profileSite": "Fournisseur",
|
||||
"profileSupport": "Support"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Trier par",
|
||||
"sort": {
|
||||
"name": "Alphabétiquement",
|
||||
"lastUpdate": "Dernière mise à jour"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Consentement Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP est un fournisseur VPN WireGuard gratuit. En activant cette option, vous acceptez les ${tos(Conditions d'utilisation)} et la ${privacy(Politique de confidentialité)} de Cloudflare WARP."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Mise à jour disponible",
|
||||
"msg": "Une nouvelle version de @:common.appTitle est disponible. Voulez-vous mettre à jour maintenant ?",
|
||||
"currentVersion": "Version actuelle : ",
|
||||
"newVersion": "Nouvelle version : ",
|
||||
"updateNow": "Mettre à jour"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "Cette action remplacera toutes les options de configuration par les valeurs fournies. Êtes-vous sûr ?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Supprimer le profil",
|
||||
"msg": "Êtes-vous sûr de vouloir supprimer ce profil définitivement ?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Améliorer la sélection automatique",
|
||||
"msg": "En partageant les applications sélectionnées, vous aidez à compléter la liste de \"sélection automatique\""
|
||||
},
|
||||
"import": {
|
||||
"msg": "Cette action remplacera toutes vos sélections actuelles de proxy par application. Êtes-vous sûr de vouloir continuer ?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Supprimer la règle",
|
||||
"msg": "Êtes-vous sûr de vouloir supprimer la règle \"$rulename\" ?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Fonctionnalités expérimentales en cours d'utilisation",
|
||||
"msg": "Vous avez activé des fonctionnalités expérimentales qui pourraient affecter la qualité de la connexion et causer des erreurs inattendues. Vous pouvez toujours modifier ou réinitialiser ces options depuis la page de configuration.",
|
||||
"disable": "Ne plus afficher"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Choisissez un profil",
|
||||
"msg": "Pour commencer, ajoutez un profil de connexion qui inclut les détails de votre connexion VPN.\n\nVous n'avez pas encore de serveur VPN ? Pas de problème, suivez le tutoriel ci-dessous pour en configurer un rapidement et gratuitement.",
|
||||
"helpBtn": {
|
||||
"label": "Montrez-moi comment",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "Avertissement de lien externe",
|
||||
"youAreAboutToVisit": "Vous êtes sur le point de visiter :",
|
||||
"thisWebsiteIsNotInOurTrustedList": "Ce site web ne figure pas dans notre liste de confiance. Veuillez procéder avec prudence."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Tag complet :",
|
||||
"type": "Type :",
|
||||
"testTime": "Heure du test :",
|
||||
"testDelay": "Délai du test :",
|
||||
"isSelected": "Sélectionné :",
|
||||
"isGroup": "Est un groupe",
|
||||
"isSecure": "Est sécurisé :",
|
||||
"port": "Port :",
|
||||
"host": "Hôte :",
|
||||
"ip": "IP :",
|
||||
"countryCode": "Code pays :",
|
||||
"region": "Région :",
|
||||
"city": "Ville :",
|
||||
"asn": "ASN :",
|
||||
"organization": "Organisation :",
|
||||
"location": "Emplacement :",
|
||||
"postalCode": "Code postal :"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Demander à chaque fois",
|
||||
"alertMessage": "Masquer ou quitter l'application ?",
|
||||
"remember": "Mémoriser mon choix"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Appuyez pour vous connecter",
|
||||
"connect": "Connecter",
|
||||
"connecting": "Connexion en cours...",
|
||||
"connected": "Connecté",
|
||||
"disconnect": "Déconnecter",
|
||||
"disconnecting": "Déconnexion en cours...",
|
||||
"reconnect": "Reconnecter",
|
||||
"reconnectMsg": "Reconnexion pour prendre en compte les changements...",
|
||||
"secure": "Sécurisé par WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Erreur inattendue",
|
||||
"connection": {
|
||||
"unexpected": "Erreur de connexion inattendue",
|
||||
"timeout": "Délai de connexion expiré",
|
||||
"badResponse": "Mauvaise réponse",
|
||||
"connectionError": "Erreur de connexion",
|
||||
"badCertificate": "Certificat invalide"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Erreur inattendue",
|
||||
"notFound": "Profil non trouvé",
|
||||
"invalidConfig": "Configurations invalides",
|
||||
"invalidUrl": "URL invalide",
|
||||
"canceledByUser": "Annulé par l'utilisateur"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Échec inattendu",
|
||||
"missingVpnPermission": "Autorisation VPN manquante",
|
||||
"missingNotificationPermission": "Autorisation de notification manquante",
|
||||
"core": "Erreur du noyau"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "Le service n'est pas en cours d'exécution",
|
||||
"missingPrivilege": "Autorisation manquante",
|
||||
"missingPrivilegeMsg": "Le mode VPN nécessite des droits d'administrateur. Veuillez relancer l'application en tant qu'administrateur ou changer le mode de service.",
|
||||
"invalidConfigOptions": "Options de configuration invalides",
|
||||
"invalidConfig": "Configuration invalide"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "Licence WARP manquante",
|
||||
"missingLicenseMsg": "Le profil sélectionné utilise la fonctionnalité WARP. Pour utiliser cette fonctionnalité, vous devez accepter la licence WARP."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Mulai",
|
||||
"version": "Versi",
|
||||
"ok": "Oke",
|
||||
"cancel": "Batal",
|
||||
"kContinue": "Lanjutkan",
|
||||
"showMore": "Tampilkan lebih banyak",
|
||||
"showLess": "Tampilkan lebih sedikit",
|
||||
"filter": "Filter",
|
||||
"all": "Semua",
|
||||
"pause": "Jeda",
|
||||
"resume": "Lanjutkan",
|
||||
"clear": "Bersihkan",
|
||||
"close": "Tutup",
|
||||
"auto": "Otomatis",
|
||||
"manually": "Manual",
|
||||
"name": "Nama",
|
||||
"url": "URL",
|
||||
"add": "Tambah",
|
||||
"clipboard": "Papan klip",
|
||||
"addToClipboard": "Tambah ke papan klip",
|
||||
"scanQr": "Pindai QR",
|
||||
"free": "Gratis",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragmen",
|
||||
"help": "Bantuan",
|
||||
"save": "Simpan",
|
||||
"update": "Perbarui",
|
||||
"share": "Bagikan",
|
||||
"edit": "Edit",
|
||||
"delete": "Hapus",
|
||||
"discard": "Buang",
|
||||
"import": "Impor",
|
||||
"export": "Ekspor",
|
||||
"later": "Nanti",
|
||||
"ignore": "Abaikan",
|
||||
"quit": "Keluar",
|
||||
"notSet": "Belum diatur",
|
||||
"hide": "Sembunyikan",
|
||||
"exit": "Keluar",
|
||||
"reset": "Setel ulang",
|
||||
"done": "Selesai",
|
||||
"search": "Cari",
|
||||
"decline": "Tolak",
|
||||
"agree": "Setuju",
|
||||
"empty": "Kosong",
|
||||
"unknown": "Tidak dikenal",
|
||||
"hidden": "Tersembunyi",
|
||||
"timeout": "Waktu habis",
|
||||
"sort": "Urutkan",
|
||||
"dashboard": "Dasbor",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n hari",
|
||||
"other": "$n hari"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n jam",
|
||||
"other": "$n jam"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "Izin ditolak"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Berhasil ditambahkan ke papan klip",
|
||||
"failure": "Gagal menyalin ke papan klip",
|
||||
"contentTooLarge": "Konten terlalu besar. Gunakan ekspor file saja"
|
||||
},
|
||||
"file": {
|
||||
"success": "File JSON berhasil dibuat",
|
||||
"failure": "Gagal membuat file"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "Konfirmasi impor",
|
||||
"success": "Berhasil diimpor",
|
||||
"failure": "Gagal mengimpor"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "Semua yang Anda butuhkan untuk internet tanpa batasan",
|
||||
"termsAndPolicyCaution(rich)": "Dengan melanjutkan, Anda menyetujui ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "Dibuat dengan ❤️ oleh Hiddify - ${tap_source(Sumber Terbuka)} (${tap_license(Lisensi)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Beranda",
|
||||
"quickSettings": "Pengaturan cepat"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Proxy",
|
||||
"sort": "Urutkan proksi",
|
||||
"testDelay": "Uji latensi",
|
||||
"empty": "Tidak ada proksi yang tersedia",
|
||||
"activeProxy": "Proksi aktif",
|
||||
"unknownIp": "IP tidak dikenal",
|
||||
"sortOptions": {
|
||||
"unsorted": "Default",
|
||||
"name": "Berdasarkan abjad",
|
||||
"delay": "Berdasarkan latensi"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "Alamat IP",
|
||||
"country": "Negara",
|
||||
"organization": "Organisasi"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Latensi: ${delay}ms",
|
||||
"timeout": "Waktu tes latensi habis",
|
||||
"testing": "Latensi: sedang menguji..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Profil",
|
||||
"add": "Tambah profil",
|
||||
"update": "Perbarui profil",
|
||||
"viewAllProfiles": "Lihat semua profil",
|
||||
"activeProfileName": "Nama profil aktif: \"${name}\".",
|
||||
"nonActiveProfileName": "Pilih \"${name}\" sebagai profil aktif",
|
||||
"freeSubNotFound": "Tidak ada langganan gratis yang ditemukan",
|
||||
"freeSubNotFoundForRegion": "Tidak ada langganan gratis yang ditemukan untuk wilayah \"${region}\"",
|
||||
"failedToLoad": "Gagal memuat",
|
||||
"updateSubscriptions": "Perbarui langganan",
|
||||
"share": {
|
||||
"urlToClipboard": "URL ke papan klip",
|
||||
"showUrlQr": "Tampilkan QR URL",
|
||||
"jsonToClipboard": "JSON ke papan klip"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Profil berhasil disimpan"
|
||||
},
|
||||
"invalidUrl": "URL tidak valid",
|
||||
"add": {
|
||||
"failure": "Gagal menambahkan profil"
|
||||
},
|
||||
"update": {
|
||||
"success": "Profil berhasil diperbarui",
|
||||
"successNamed": "\"${name}\" berhasil diperbarui",
|
||||
"failure": "Gagal memperbarui profil",
|
||||
"failureNamed": "Gagal memperbarui \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "Profil berhasil dihapus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Profil",
|
||||
"lastUpdate": "Terakhir diperbarui",
|
||||
"form": {
|
||||
"nameHint": "Nama profil",
|
||||
"emptyName": "Nama wajib diisi",
|
||||
"invalidUrl": "URL tidak valid",
|
||||
"urlHint": "URL konfigurasi lengkap",
|
||||
"disableAutoUpdate": "Nonaktifkan pembaruan otomatis",
|
||||
"autoUpdateInterval": "Interval pembaruan otomatis",
|
||||
"loading": "Menambahkan profil..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Log",
|
||||
"shareCoreLogs": "Bagikan log inti",
|
||||
"shareAppLogs": "Bagikan log aplikasi"
|
||||
},
|
||||
"about": {
|
||||
"title": "Tentang",
|
||||
"notAvailableMsg": "Anda sudah menggunakan versi terbaru",
|
||||
"checkForUpdate": "Periksa pembaruan",
|
||||
"openWorkingDir": "Buka direktori kerja",
|
||||
"sourceCode": "Kode sumber",
|
||||
"telegramChannel": "Saluran Telegram",
|
||||
"termsAndConditions": "Syarat dan Ketentuan",
|
||||
"privacyPolicy": "Kebijakan Privasi"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Pengaturan",
|
||||
"resetTunnel": "Setel ulang profil VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Impor opsi dari papan klip",
|
||||
"file": "Impor opsi dari file"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Salin opsi anonim ke papan klip",
|
||||
"anonymousToFile": "Ekspor opsi anonim ke file",
|
||||
"allToClipboard": "Salin semua opsi ke papan klip",
|
||||
"allToFile": "Ekspor semua opsi ke file"
|
||||
},
|
||||
"reset": "Setel ulang opsi"
|
||||
},
|
||||
"general": {
|
||||
"title": "Umum",
|
||||
"locale": "Bahasa",
|
||||
"themeMode": "Tema",
|
||||
"themeModes": {
|
||||
"system": "Default sistem",
|
||||
"dark": "Mode gelap",
|
||||
"light": "Mode terang",
|
||||
"black": "Mode hitam"
|
||||
},
|
||||
"enableAnalytics": "Aktifkan analitik",
|
||||
"enableAnalyticsMsg": "Berikan izin untuk mengumpulkan analitik dan mengirim laporan kerusakan untuk meningkatkan aplikasi",
|
||||
"autoIpCheck": "Periksa IP koneksi secara otomatis",
|
||||
"dynamicNotification": "Tampilkan kecepatan di notifikasi",
|
||||
"hapticFeedback": "Umpan balik haptik",
|
||||
"actionAtClosing": "Tindakan saat menutup",
|
||||
"autoStart": "Mulai saat masuk",
|
||||
"silentStart": "Mulai diminimalkan",
|
||||
"ignoreBatteryOptimizations": "Nonaktifkan optimasi baterai",
|
||||
"ignoreBatteryOptimizationsMsg": "Hapus batasan untuk kinerja VPN yang optimal",
|
||||
"memoryLimit": "Batas memori",
|
||||
"memoryLimitMsg": "Aktifkan jika Anda mengalami kesalahan kehabisan memori atau aplikasi sering macet",
|
||||
"debugMode": "Mode debug",
|
||||
"debugModeMsg": "Mulai ulang aplikasi untuk menerapkan perubahan ini",
|
||||
"logLevel": "Level log",
|
||||
"connectionTestUrl": "URL uji koneksi",
|
||||
"urlTestInterval": "Interval uji URL",
|
||||
"clashApiPort": "Port API Clash",
|
||||
"useXrayCoreWhenPossible": "Gunakan xray-core jika memungkinkan",
|
||||
"useXrayCoreWhenPossibleMsg": "Gunakan xray-core saat mengurai tautan langganan. Anda perlu mengimpor ulang tautan untuk mengaktifkan opsi ini."
|
||||
},
|
||||
"routing": {
|
||||
"title": "Perutean",
|
||||
"perAppProxy": {
|
||||
"title": "Proxy per aplikasi",
|
||||
"hideSysApps": "Sembunyikan aplikasi sistem",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Impor pilihan dari papan klip",
|
||||
"file": "Impor pilihan dari file",
|
||||
"msg": "Mengimpor akan menggantikan pilihan Anda saat ini. Anda yakin ingin melanjutkan?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Salin pilihan ke papan klip",
|
||||
"file": "Ekspor pilihan ke file"
|
||||
},
|
||||
"shareToAll": "Bagikan ke semua",
|
||||
"clearAllSelections": "Hapus semua pilihan"
|
||||
},
|
||||
"modes": {
|
||||
"all": "Semua",
|
||||
"proxy": "Proxy",
|
||||
"bypass": "Lewati",
|
||||
"allMsg": "Proxy semua aplikasi",
|
||||
"proxyMsg": "Proxy hanya aplikasi yang dipilih",
|
||||
"bypassMsg": "Jangan proxy aplikasi yang dipilih"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Pilihan otomatis",
|
||||
"performNow": "Lakukan sekarang",
|
||||
"resetToDefault": "Setel ulang ke default",
|
||||
"autoUpdateInterval": "Interval pembaruan otomatis",
|
||||
"toast": {
|
||||
"success": "Pilihan aplikasi otomatis berhasil diselesaikan",
|
||||
"failure": "Pilihan otomatis gagal",
|
||||
"regionNotFound": "Pilihan otomatis tidak ditemukan untuk wilayah \"${region}\"",
|
||||
"alreadyInAuto": "Pilihan Anda sudah ada dalam daftar otomatis"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Pilihan aplikasi otomatis",
|
||||
"msg": "Fitur pilihan otomatis untuk proxy per aplikasi dinonaktifkan karena perubahan wilayah menjadi \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Wilayah",
|
||||
"regions": {
|
||||
"ir": "Iran (ir) 🇮🇷",
|
||||
"cn": "Tiongkok (cn) 🇨🇳",
|
||||
"ru": "Rusia (ru) 🇷🇺",
|
||||
"af": "Afghanistan (af) 🇦🇫",
|
||||
"id": "Indonesia (id) 🇮🇩",
|
||||
"tr": "Turki (tr) 🇹🇷",
|
||||
"br": "Brasil (br) 🇧🇷",
|
||||
"other": "Lainnya"
|
||||
},
|
||||
"blockAds": "Blokir iklan",
|
||||
"bypassLan": "Lewati LAN",
|
||||
"resolveDestination": "Resolusi tujuan",
|
||||
"ipv6Route": "Rute IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Nonaktifkan",
|
||||
"enable": "Aktifkan",
|
||||
"prefer": "Prioritaskan",
|
||||
"only": "Hanya"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Aturan perutean",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Impor aturan dari papan klip",
|
||||
"file": "Impor aturan dari file"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Salin aturan ke papan klip",
|
||||
"file": "Simpan aturan ke file"
|
||||
},
|
||||
"reset": "Setel ulang aturan"
|
||||
},
|
||||
"deleteRule": "Hapus aturan",
|
||||
"createRule": "Buat aturan baru",
|
||||
"rule": {
|
||||
"title": "Aturan",
|
||||
"ruleChanged": "Aturan diubah",
|
||||
"ruleChangedMsg": "Apakah Anda ingin menyimpan editan Anda?",
|
||||
"onlyTunMode": "Hanya tersedia dalam mode TUN",
|
||||
"notAvailabeInThisPlatform": "Tidak tersedia di platform ini",
|
||||
"canNotBeEmpty": "Tidak boleh kosong",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "\"URL\" yang valid seperti\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe atau google chrome atau chrome",
|
||||
"validProcessName": "\"Nama Proses\" yang valid seperti\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "\"Jalur Proses\" yang valid seperti\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 atau 1-65000",
|
||||
"validPortRange": "\"Port\" atau \"Rentang Port\" yang valid seperti\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 atau 10.0.0.0/24",
|
||||
"validIpCidr": "IP CIDR yang valid seperti\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com atau dl.google.com",
|
||||
"validDomain": "\"Domain\" yang valid seperti\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com atau .ir",
|
||||
"validDomainSuffix": "\"Sufiks Domain\" yang valid seperti\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "Nama",
|
||||
"outbound": "Keluar jika cocok",
|
||||
"rule_set": "URL set aturan",
|
||||
"package_name": "Nama paket",
|
||||
"process_name": "Nama proses",
|
||||
"process_path": "Jalur proses",
|
||||
"network": "Jaringan",
|
||||
"port_range": "Port tujuan",
|
||||
"source_port_range": "Port sumber",
|
||||
"protocol": "Protokol",
|
||||
"ip_cidr": "IP CIDR tujuan",
|
||||
"source_ip_cidr": "IP CIDR sumber",
|
||||
"domain": "Domain",
|
||||
"domain_suffixe": "Sufiks domain",
|
||||
"domain_keyword": "Kata kunci domain",
|
||||
"domain_regex": "Regex domain"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Proxy",
|
||||
"direct": "Langsung",
|
||||
"direct_with_fragment": "Langsung dengan fragmen",
|
||||
"block": "Blokir"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "Semua",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "Semua",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Tambah nilai baru",
|
||||
"update": "Perbarui nilai",
|
||||
"clearList": "Bersihkan daftar",
|
||||
"clearListMsg": "Semua item dihapus"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Aplikasi Android",
|
||||
"showSystemApps": "Tampilkan aplikasi sistem",
|
||||
"hideSystemApps": "Sembunyikan aplikasi sistem",
|
||||
"clearSelection": "Hapus pilihan",
|
||||
"uninstalled": "Dihapus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "DNS jarak jauh",
|
||||
"remoteDnsDomainStrategy": "Strategi domain DNS jarak jauh",
|
||||
"directDns": "DNS langsung",
|
||||
"directDnsDomainStrategy": "Strategi domain DNS langsung",
|
||||
"enableDnsRouting": "Aktifkan perutean DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "Otomatis",
|
||||
"preferIpv6": "Prioritaskan IPv6",
|
||||
"preferIpv4": "Prioritaskan IPv4",
|
||||
"ipv4Only": "Hanya IPv4",
|
||||
"ipv6Only": "Hanya IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Masuk",
|
||||
"serviceMode": "Mode layanan",
|
||||
"serviceModes": {
|
||||
"proxy": "Hanya layanan proksi",
|
||||
"systemProxy": "Atur proksi sistem",
|
||||
"tun": "VPN",
|
||||
"tunService": "Layanan VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Proxy sistem",
|
||||
"tun": "VPN",
|
||||
"tunService": "Layanan VPN"
|
||||
},
|
||||
"strictRoute": "Rute ketat",
|
||||
"tunImplementation": "Implementasi TUN",
|
||||
"tunImplementations": {
|
||||
"mixed": "Campuran",
|
||||
"system": "Sistem",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Port campuran",
|
||||
"tproxyPort": "Port proksi transparan",
|
||||
"directPort": "Port direct",
|
||||
"allowConnectionFromLan": "Bagikan VPN di jaringan lokal"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "Trik TLS",
|
||||
"enable": "Aktifkan fragmen",
|
||||
"size": "Ukuran fragmen",
|
||||
"sleep": "Jeda fragmen",
|
||||
"mixedSniCase": {
|
||||
"enable": "Aktifkan kasus SNI campuran"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Aktifkan padding",
|
||||
"size": "Ukuran padding"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "Aktifkan WARP",
|
||||
"generateConfig": "Buat konfigurasi WARP",
|
||||
"configGenerated": "Konfigurasi WARP dibuat",
|
||||
"missingConfig": "Konfigurasi WARP hilang",
|
||||
"detourMode": "Mode Rute WARP",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Alihkan proksi melalui WARP",
|
||||
"warpOverProxy": "Alihkan WARP melalui proksi",
|
||||
"proxyOverWarpExplain": "Buka blokir proksi dengan WARP",
|
||||
"warpOverProxyExplain": "Keamanan ekstra dengan WARP"
|
||||
},
|
||||
"licenseKey": "Kunci lisensi",
|
||||
"cleanIp": "IP bersih",
|
||||
"port": "Port",
|
||||
"noise": {
|
||||
"count": "Jumlah kebisingan",
|
||||
"mode": "Mode kebisingan",
|
||||
"size": "Ukuran kebisingan",
|
||||
"delay": "Penundaan kebisingan"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Koneksi",
|
||||
"traffic": "Lalu lintas",
|
||||
"trafficLive": "Lalu lintas langsung",
|
||||
"trafficTotal": "Total lalu lintas",
|
||||
"uplink": "Unggah",
|
||||
"downlink": "Unduh",
|
||||
"speed": "Kecepatan",
|
||||
"totalTransferred": "Total ditransfer"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Unggah",
|
||||
"download": "Unduh",
|
||||
"total": "Total lalu lintas",
|
||||
"expireDate": "Tanggal kedaluwarsa",
|
||||
"expired": "Kedaluwarsa",
|
||||
"noTraffic": "Kuota habis",
|
||||
"remainingTime": "Sisa waktu",
|
||||
"remainingDuration": "tersisa ${duration} hari",
|
||||
"remainingDurationNew": "${duration} hari",
|
||||
"remainingTrafficSemanticLabel": "${consumed} dari ${total} lalu lintas terpakai",
|
||||
"remainingTraffic": "Sisa lalu lintas",
|
||||
"remainingUsage": "Sisa",
|
||||
"profileSite": "Penyedia",
|
||||
"profileSupport": "Dukungan"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Urut berdasarkan",
|
||||
"sort": {
|
||||
"name": "Menurut abjad",
|
||||
"lastUpdate": "Terakhir diperbarui"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Persetujuan Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP adalah penyedia VPN WireGuard gratis. Dengan mengaktifkan opsi ini, Anda menyetujui ${tos(Ketentuan Layanan)} dan ${privacy(Kebijakan Privasi)} Cloudflare WARP."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Pembaruan tersedia",
|
||||
"msg": "Versi baru @:common.appTitle tersedia. Apakah Anda ingin memperbarui sekarang?",
|
||||
"currentVersion": "Versi saat ini: ",
|
||||
"newVersion": "Versi baru: ",
|
||||
"updateNow": "Perbarui sekarang"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "Ini akan menimpa semua opsi konfigurasi dengan nilai yang diberikan. Anda yakin?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Hapus profil",
|
||||
"msg": "Anda yakin ingin menghapus profil ini secara permanen?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Meningkatkan pilihan otomatis",
|
||||
"msg": "Dengan membagikan aplikasi yang dipilih, Anda membantu melengkapi daftar \"pilihan otomatis\""
|
||||
},
|
||||
"import": {
|
||||
"msg": "Ini akan menggantikan semua pilihan proksi per aplikasi Anda saat ini. Anda yakin ingin melanjutkan?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Hapus aturan",
|
||||
"msg": "Anda yakin ingin menghapus aturan \"$rulename\"?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Fitur eksperimental sedang digunakan",
|
||||
"msg": "Anda telah mengaktifkan beberapa fitur eksperimental yang mungkin memengaruhi kualitas koneksi dan menyebabkan kesalahan tak terduga. Anda selalu dapat mengubah atau menyetel ulang opsi ini dari halaman konfigurasi.",
|
||||
"disable": "Jangan tampilkan lagi"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Pilih profil",
|
||||
"msg": "Mari kita mulai dengan menambahkan profil koneksi yang berisi detail koneksi VPN Anda.\n\nBelum punya server VPN? Jangan khawatir, ikuti tutorial di bawah ini untuk mengaturnya dengan cepat dan gratis.",
|
||||
"helpBtn": {
|
||||
"label": "Tunjukkan caranya",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "Peringatan tautan eksternal",
|
||||
"youAreAboutToVisit": "Anda akan mengunjungi:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "Situs web ini tidak ada dalam daftar tepercaya kami. Harap lanjutkan dengan hati-hati."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Tag lengkap:",
|
||||
"type": "Tipe:",
|
||||
"testTime": "Waktu uji:",
|
||||
"testDelay": "Jeda uji:",
|
||||
"isSelected": "Dipilih:",
|
||||
"isGroup": "Grup",
|
||||
"isSecure": "Aman:",
|
||||
"port": "Port:",
|
||||
"host": "Host:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "Kode negara:",
|
||||
"region": "Wilayah:",
|
||||
"city": "Kota:",
|
||||
"asn": "ASN:",
|
||||
"organization": "Organisasi:",
|
||||
"location": "Lokasi:",
|
||||
"postalCode": "Kode pos:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Tanyakan setiap kali",
|
||||
"alertMessage": "Sembunyikan atau keluar dari aplikasi?",
|
||||
"remember": "Ingat pilihan saya"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Ketuk untuk menyambungkan",
|
||||
"connect": "Sambungkan",
|
||||
"connecting": "Menyambungkan...",
|
||||
"connected": "Tersambung",
|
||||
"disconnect": "Putuskan",
|
||||
"disconnecting": "Memutuskan...",
|
||||
"reconnect": "Sambungkan kembali",
|
||||
"reconnectMsg": "Menyambungkan kembali untuk menerapkan perubahan...",
|
||||
"secure": "Diamankan oleh WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Kesalahan tak terduga",
|
||||
"connection": {
|
||||
"unexpected": "Kesalahan koneksi tak terduga",
|
||||
"timeout": "Waktu koneksi habis",
|
||||
"badResponse": "Respons buruk",
|
||||
"connectionError": "Kesalahan koneksi",
|
||||
"badCertificate": "Sertifikat rusak"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Kesalahan tak terduga",
|
||||
"notFound": "Profil tidak ditemukan",
|
||||
"invalidConfig": "Konfigurasi tidak valid",
|
||||
"invalidUrl": "URL tidak valid",
|
||||
"canceledByUser": "Dibatalkan oleh pengguna"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Kegagalan tak terduga",
|
||||
"missingVpnPermission": "Izin VPN hilang",
|
||||
"missingNotificationPermission": "Izin notifikasi hilang",
|
||||
"core": "Kesalahan inti"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "Layanan tidak berjalan",
|
||||
"missingPrivilege": "Izin hilang",
|
||||
"missingPrivilegeMsg": "Mode VPN memerlukan izin administrator. Harap mulai ulang aplikasi sebagai administrator atau ubah mode layanan.",
|
||||
"invalidConfigOptions": "Opsi konfigurasi tidak valid",
|
||||
"invalidConfig": "Konfigurasi tidak valid"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "Lisensi WARP hilang",
|
||||
"missingLicenseMsg": "Profil yang dipilih menggunakan fitur WARP. Untuk menggunakan fitur ini, Anda harus menyetujui lisensi WARP."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Começar",
|
||||
"version": "Versão",
|
||||
"ok": "OK",
|
||||
"cancel": "Cancelar",
|
||||
"kContinue": "Continuar",
|
||||
"showMore": "Mostrar mais",
|
||||
"showLess": "Mostrar menos",
|
||||
"filter": "Filtrar",
|
||||
"all": "Todos",
|
||||
"pause": "Pausar",
|
||||
"resume": "Retomar",
|
||||
"clear": "Limpar",
|
||||
"close": "Fechar",
|
||||
"auto": "Automático",
|
||||
"manually": "Manualmente",
|
||||
"name": "Nome",
|
||||
"url": "URL",
|
||||
"add": "Adicionar",
|
||||
"clipboard": "Área de transferência",
|
||||
"addToClipboard": "Adicionar à área de transferência",
|
||||
"scanQr": "Escanear QR",
|
||||
"free": "Grátis",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragmento",
|
||||
"help": "Ajuda",
|
||||
"save": "Salvar",
|
||||
"update": "Atualizar",
|
||||
"share": "Compartilhar",
|
||||
"edit": "Editar",
|
||||
"delete": "Excluir",
|
||||
"discard": "Descartar",
|
||||
"import": "Importar",
|
||||
"export": "Exportar",
|
||||
"later": "Mais tarde",
|
||||
"ignore": "Ignorar",
|
||||
"quit": "Sair",
|
||||
"notSet": "Não definido",
|
||||
"hide": "Ocultar",
|
||||
"exit": "Sair",
|
||||
"reset": "Redefinir",
|
||||
"done": "Concluído",
|
||||
"search": "Buscar",
|
||||
"decline": "Recusar",
|
||||
"agree": "Aceitar",
|
||||
"empty": "Vazio",
|
||||
"unknown": "Desconhecido",
|
||||
"hidden": "Oculto",
|
||||
"timeout": "Tempo esgotado",
|
||||
"sort": "Ordenar",
|
||||
"dashboard": "Painel",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n dia",
|
||||
"other": "$n dias"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n hora",
|
||||
"other": "$n horas"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "Permissão negada"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Adicionado à área de transferência com sucesso",
|
||||
"failure": "Falha ao copiar para a área de transferência",
|
||||
"contentTooLarge": "Conteúdo muito grande. Use a exportação para arquivo"
|
||||
},
|
||||
"file": {
|
||||
"success": "Arquivo JSON criado com sucesso",
|
||||
"failure": "Falha ao criar o arquivo"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "Confirmar importação",
|
||||
"success": "Importado com sucesso",
|
||||
"failure": "Falha ao importar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "Tudo o que você precisa para uma internet sem restrições",
|
||||
"termsAndPolicyCaution(rich)": "Ao continuar, você concorda com os ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "Feito com ❤️ por Hiddify - ${tap_source(Código Aberto)} (${tap_license(Licença)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Início",
|
||||
"quickSettings": "Configurações rápidas"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Proxies",
|
||||
"sort": "Ordenar proxies",
|
||||
"testDelay": "Testar latência",
|
||||
"empty": "Nenhum proxy disponível",
|
||||
"activeProxy": "Proxy ativo",
|
||||
"unknownIp": "IP desconhecido",
|
||||
"sortOptions": {
|
||||
"unsorted": "Padrão",
|
||||
"name": "Alfabeticamente",
|
||||
"delay": "Por latência"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "Endereço de IP",
|
||||
"country": "País",
|
||||
"organization": "Organização"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Latência: ${delay}ms",
|
||||
"timeout": "Tempo limite do teste de latência esgotado",
|
||||
"testing": "Latência: testando..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Perfis",
|
||||
"add": "Adicionar perfil",
|
||||
"update": "Atualizar perfil",
|
||||
"viewAllProfiles": "Ver todos os perfis",
|
||||
"activeProfileName": "Nome do perfil ativo: \"${name}\".",
|
||||
"nonActiveProfileName": "Selecionar \"${name}\" como perfil ativo",
|
||||
"freeSubNotFound": "Nenhuma assinatura gratuita encontrada",
|
||||
"freeSubNotFoundForRegion": "Nenhuma assinatura gratuita encontrada para a região \"${region}\"",
|
||||
"failedToLoad": "Falha ao carregar",
|
||||
"updateSubscriptions": "Atualizar assinaturas",
|
||||
"share": {
|
||||
"urlToClipboard": "URL para a área de transferência",
|
||||
"showUrlQr": "Mostrar QR code da URL",
|
||||
"jsonToClipboard": "JSON para a área de transferência"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Perfil salvo com sucesso"
|
||||
},
|
||||
"invalidUrl": "URL inválida",
|
||||
"add": {
|
||||
"failure": "Falha ao adicionar perfil"
|
||||
},
|
||||
"update": {
|
||||
"success": "Perfil atualizado com sucesso",
|
||||
"successNamed": "\"${name}\" atualizado com sucesso",
|
||||
"failure": "Falha ao atualizar perfil",
|
||||
"failureNamed": "Falha ao atualizar \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "Perfil excluído com sucesso"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Perfil",
|
||||
"lastUpdate": "Última atualização",
|
||||
"form": {
|
||||
"nameHint": "Nome do perfil",
|
||||
"emptyName": "O nome é obrigatório",
|
||||
"invalidUrl": "URL inválida",
|
||||
"urlHint": "URL de configuração completa",
|
||||
"disableAutoUpdate": "Desativar atualização automática",
|
||||
"autoUpdateInterval": "Intervalo de atualização automática",
|
||||
"loading": "Adicionando perfil..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Registros",
|
||||
"shareCoreLogs": "Compartilhar registros do núcleo",
|
||||
"shareAppLogs": "Compartilhar registros do aplicativo"
|
||||
},
|
||||
"about": {
|
||||
"title": "Sobre",
|
||||
"notAvailableMsg": "Você já está usando a versão mais recente",
|
||||
"checkForUpdate": "Verificar atualizações",
|
||||
"openWorkingDir": "Abrir diretório de trabalho",
|
||||
"sourceCode": "Código-fonte",
|
||||
"telegramChannel": "Canal do Telegram",
|
||||
"termsAndConditions": "Termos e Condições",
|
||||
"privacyPolicy": "Política de Privacidade"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configurações",
|
||||
"resetTunnel": "Redefinir perfil de VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importar opções da área de transferência",
|
||||
"file": "Importar opções de um arquivo"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Copiar opções anônimas para a área de transferência",
|
||||
"anonymousToFile": "Exportar opções anônimas para um arquivo",
|
||||
"allToClipboard": "Copiar todas as opções para a área de transferência",
|
||||
"allToFile": "Exportar todas as opções para um arquivo"
|
||||
},
|
||||
"reset": "Redefinir opções"
|
||||
},
|
||||
"general": {
|
||||
"title": "Geral",
|
||||
"locale": "Idioma",
|
||||
"themeMode": "Tema",
|
||||
"themeModes": {
|
||||
"system": "Padrão do sistema",
|
||||
"dark": "Modo escuro",
|
||||
"light": "Modo claro",
|
||||
"black": "Modo preto"
|
||||
},
|
||||
"enableAnalytics": "Ativar análise de dados",
|
||||
"enableAnalyticsMsg": "Permitir a coleta de dados de análise e relatórios de falhas para melhorar o aplicativo",
|
||||
"autoIpCheck": "Verificar IP da conexão automaticamente",
|
||||
"dynamicNotification": "Exibir velocidade na notificação",
|
||||
"hapticFeedback": "Feedback tátil",
|
||||
"actionAtClosing": "Ação ao fechar",
|
||||
"autoStart": "Iniciar com o sistema",
|
||||
"silentStart": "Iniciar minimizado",
|
||||
"ignoreBatteryOptimizations": "Desativar otimização de bateria",
|
||||
"ignoreBatteryOptimizationsMsg": "Remover restrições para um desempenho ideal da VPN",
|
||||
"memoryLimit": "Limite de memória",
|
||||
"memoryLimitMsg": "Ative se estiver enfrentando erros de falta de memória ou travamentos frequentes do aplicativo",
|
||||
"debugMode": "Modo de depuração",
|
||||
"debugModeMsg": "Reinicie o aplicativo para aplicar esta alteração",
|
||||
"logLevel": "Nível de registro",
|
||||
"connectionTestUrl": "URL de teste de conexão",
|
||||
"urlTestInterval": "Intervalo de teste de URL",
|
||||
"clashApiPort": "Porta da API do Clash",
|
||||
"useXrayCoreWhenPossible": "Usar xray-core quando possível",
|
||||
"useXrayCoreWhenPossibleMsg": "Use o xray-core ao analisar links de assinatura. Você precisa reimportar o link para ativar esta opção"
|
||||
},
|
||||
"routing": {
|
||||
"title": "Roteamento",
|
||||
"perAppProxy": {
|
||||
"title": "Proxy por aplicativo",
|
||||
"hideSysApps": "Ocultar aplicativos do sistema",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importar seleção da área de transferência",
|
||||
"file": "Importar seleção de um arquivo",
|
||||
"msg": "A importação substituirá suas seleções atuais. Tem certeza de que deseja continuar?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copiar seleção para a área de transferência",
|
||||
"file": "Exportar seleção para um arquivo"
|
||||
},
|
||||
"shareToAll": "Compartilhar com todos",
|
||||
"clearAllSelections": "Limpar todas as seleções"
|
||||
},
|
||||
"modes": {
|
||||
"all": "Todos",
|
||||
"proxy": "Proxy",
|
||||
"bypass": "Ignorar",
|
||||
"allMsg": "Usar proxy para todos os aplicativos",
|
||||
"proxyMsg": "Usar proxy apenas para aplicativos selecionados",
|
||||
"bypassMsg": "Não usar proxy para aplicativos selecionados"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Seleção automática",
|
||||
"performNow": "Executar agora",
|
||||
"resetToDefault": "Redefinir para o padrão",
|
||||
"autoUpdateInterval": "Intervalo de atualização automática",
|
||||
"toast": {
|
||||
"success": "Seleção automática de aplicativos concluída com sucesso",
|
||||
"failure": "Falha na seleção automática",
|
||||
"regionNotFound": "Seleção automática não encontrada para a região \"${region}\"",
|
||||
"alreadyInAuto": "Suas seleções já estão na lista automática"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Seleção automática de aplicativos",
|
||||
"msg": "A função de seleção automática para o proxy por aplicativo foi desativada devido à mudança de região para \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Região",
|
||||
"regions": {
|
||||
"ir": "Irã (ir) 🇮🇷",
|
||||
"cn": "China (cn) 🇨🇳",
|
||||
"ru": "Rússia (ru) 🇷🇺",
|
||||
"af": "Afeganistão (af) 🇦🇫",
|
||||
"id": "Indonésia (id) 🇮🇩",
|
||||
"tr": "Turquia (tr) 🇹🇷",
|
||||
"br": "Brasil (br) 🇧🇷",
|
||||
"other": "Outro"
|
||||
},
|
||||
"blockAds": "Bloquear anúncios",
|
||||
"bypassLan": "Ignorar LAN",
|
||||
"resolveDestination": "Resolver destino",
|
||||
"ipv6Route": "Rota IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Desativar",
|
||||
"enable": "Ativar",
|
||||
"prefer": "Preferencial",
|
||||
"only": "Exclusivo"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Regras de Roteamento",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Importar regras da área de transferência",
|
||||
"file": "Importar regras de um arquivo"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Copiar regras para a área de transferência",
|
||||
"file": "Salvar regras em um arquivo"
|
||||
},
|
||||
"reset": "Redefinir regras"
|
||||
},
|
||||
"deleteRule": "Excluir regra",
|
||||
"createRule": "Criar nova regra",
|
||||
"rule": {
|
||||
"title": "Regra",
|
||||
"ruleChanged": "Regra alterada",
|
||||
"ruleChangedMsg": "Deseja salvar suas edições?",
|
||||
"onlyTunMode": "Disponível apenas no modo TUN",
|
||||
"notAvailabeInThisPlatform": "Não disponível nesta plataforma",
|
||||
"canNotBeEmpty": "Não pode estar vazio",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "\"URL\" válido como\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe ou google chrome ou chrome",
|
||||
"validProcessName": "\"Nome do Processo\" válido como\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "\"Caminho do Processo\" válido como\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 ou 1-65000",
|
||||
"validPortRange": "\"Porta\" ou \"Intervalo de Portas\" válido como\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 ou 10.0.0.0/24",
|
||||
"validIpCidr": "IP CIDR válido como\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com ou dl.google.com",
|
||||
"validDomain": "\"Domínio\" válido como\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com ou .ir",
|
||||
"validDomainSuffix": "\"Sufixo de Domínio\" válido como\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "Nome",
|
||||
"outbound": "Saída se corresponder",
|
||||
"rule_set": "URL do conjunto de regras",
|
||||
"package_name": "Nomes dos pacotes",
|
||||
"process_name": "Nomes dos processos",
|
||||
"process_path": "Caminhos dos processos",
|
||||
"network": "Redes",
|
||||
"port_range": "Portas de destino",
|
||||
"source_port_range": "Portas de origem",
|
||||
"protocol": "Protocolo",
|
||||
"ip_cidr": "IP CIDR de destino",
|
||||
"source_ip_cidr": "IP CIDR de origem",
|
||||
"domain": "Domínio",
|
||||
"domain_suffixe": "Sufixo de domínio",
|
||||
"domain_keyword": "Palavra-chave de domínio",
|
||||
"domain_regex": "Expressão regular de domínio"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Proxy",
|
||||
"direct": "Direto",
|
||||
"direct_with_fragment": "Direto com fragmento",
|
||||
"block": "Bloquear"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "Todos",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "Todos",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Adicionar novo valor",
|
||||
"update": "Atualizar valor",
|
||||
"clearList": "Limpar lista",
|
||||
"clearListMsg": "Todos os itens foram excluídos"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Aplicativos Android",
|
||||
"showSystemApps": "Mostrar aplicativos do sistema",
|
||||
"hideSystemApps": "Ocultar aplicativos do sistema",
|
||||
"clearSelection": "Limpar seleção",
|
||||
"uninstalled": "Desinstalado"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "DNS remoto",
|
||||
"remoteDnsDomainStrategy": "Estratégia de domínio de DNS remoto",
|
||||
"directDns": "DNS direto",
|
||||
"directDnsDomainStrategy": "Estratégia de domínio de DNS direto",
|
||||
"enableDnsRouting": "Ativar roteamento de DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "Automático",
|
||||
"preferIpv6": "Preferir IPv6",
|
||||
"preferIpv4": "Preferir IPv4",
|
||||
"ipv4Only": "Apenas IPv4",
|
||||
"ipv6Only": "Apenas IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Entrada",
|
||||
"serviceMode": "Modo de serviço",
|
||||
"serviceModes": {
|
||||
"proxy": "Apenas serviço de proxy",
|
||||
"systemProxy": "Definir proxy do sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Serviço VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Proxy do sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Serviço VPN"
|
||||
},
|
||||
"strictRoute": "Roteamento estrito",
|
||||
"tunImplementation": "Implementação de TUN",
|
||||
"tunImplementations": {
|
||||
"mixed": "Misto",
|
||||
"system": "Sistema",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Porta mista",
|
||||
"tproxyPort": "Porta de proxy transparente",
|
||||
"directPort": "Porta de directo",
|
||||
"allowConnectionFromLan": "Compartilhar VPN na rede local"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "Truques de TLS",
|
||||
"enable": "Ativar fragmento",
|
||||
"size": "Tamanho do fragmento",
|
||||
"sleep": "Atraso do fragmento",
|
||||
"mixedSniCase": {
|
||||
"enable": "Ativar maiúsculas/minúsculas mistas no SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Ativar preenchimento",
|
||||
"size": "Tamanho do preenchimento"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "Ativar WARP",
|
||||
"generateConfig": "Gerar configuração WARP",
|
||||
"configGenerated": "Configuração WARP gerada",
|
||||
"missingConfig": "Configuração WARP ausente",
|
||||
"detourMode": "Modo de Roteamento WARP",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Desviar proxies através do WARP",
|
||||
"warpOverProxy": "Desviar WARP através de proxies",
|
||||
"proxyOverWarpExplain": "Desbloquear proxies com WARP",
|
||||
"warpOverProxyExplain": "Segurança extra com WARP"
|
||||
},
|
||||
"licenseKey": "Chave de licença",
|
||||
"cleanIp": "IP limpo",
|
||||
"port": "Porta",
|
||||
"noise": {
|
||||
"count": "Contagem de ruído",
|
||||
"mode": "Modo de ruído",
|
||||
"size": "Tamanho do ruído",
|
||||
"delay": "Atraso do ruído"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Conexão",
|
||||
"traffic": "Tráfego",
|
||||
"trafficLive": "Tráfego ao vivo",
|
||||
"trafficTotal": "Tráfego total",
|
||||
"uplink": "Envio",
|
||||
"downlink": "Recebimento",
|
||||
"speed": "Velocidade",
|
||||
"totalTransferred": "Total transferido"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Upload",
|
||||
"download": "Download",
|
||||
"total": "Tráfego total",
|
||||
"expireDate": "Data de validade",
|
||||
"expired": "Expirado",
|
||||
"noTraffic": "Cota esgotada",
|
||||
"remainingTime": "Tempo restante",
|
||||
"remainingDuration": "${duration} dias restantes",
|
||||
"remainingDurationNew": "${duration} dias",
|
||||
"remainingTrafficSemanticLabel": "${consumed} de ${total} de tráfego consumido",
|
||||
"remainingTraffic": "Tráfego restante",
|
||||
"remainingUsage": "Restante",
|
||||
"profileSite": "Provedor",
|
||||
"profileSupport": "Suporte"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Ordenar por",
|
||||
"sort": {
|
||||
"name": "Alfabeticamente",
|
||||
"lastUpdate": "Última atualização"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Consentimento do Cloudflare WARP",
|
||||
"description(rich)": "O Cloudflare WARP é um provedor de VPN WireGuard gratuito. Ao ativar esta opção, você concorda com os ${tos(Termos de Serviço)} e a ${privacy(Política de Privacidade)} do Cloudflare WARP."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Atualização disponível",
|
||||
"msg": "Uma nova versão do @:common.appTitle está disponível. Deseja atualizar agora?",
|
||||
"currentVersion": "Versão atual: ",
|
||||
"newVersion": "Nova versão: ",
|
||||
"updateNow": "Atualizar agora"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "Isso substituirá todas as opções de configuração pelos valores fornecidos. Você tem certeza?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Excluir perfil",
|
||||
"msg": "Tem certeza de que deseja excluir este perfil permanentemente?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Melhorando a seleção automática",
|
||||
"msg": "Ao compartilhar os aplicativos selecionados, você ajuda a completar a lista de \"seleção automática\""
|
||||
},
|
||||
"import": {
|
||||
"msg": "Isso substituirá todas as suas seleções atuais de proxy por aplicativo. Tem certeza de que deseja continuar?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Excluir regra",
|
||||
"msg": "Tem certeza de que deseja excluir a regra \"$rulename\"?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Recursos experimentais em uso",
|
||||
"msg": "Você ativou alguns recursos experimentais que podem afetar a qualidade da conexão e causar erros inesperados. Você sempre pode alterar ou redefinir essas opções na página de configurações.",
|
||||
"disable": "Não mostrar novamente"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Escolha um perfil",
|
||||
"msg": "Para começar, adicione um perfil de conexão que inclua os detalhes da sua conexão VPN.\n\nAinda não tem um servidor VPN? Não se preocupe, siga o tutorial abaixo para configurar um rapidamente e de graça.",
|
||||
"helpBtn": {
|
||||
"label": "Mostre-me como",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "Aviso de link externo",
|
||||
"youAreAboutToVisit": "Você está prestes a visitar:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "Este site não está na nossa lista de confiança. Prossiga com cautela."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Tag completa:",
|
||||
"type": "Tipo:",
|
||||
"testTime": "Hora do teste:",
|
||||
"testDelay": "Latência do teste:",
|
||||
"isSelected": "Selecionado:",
|
||||
"isGroup": "É um grupo",
|
||||
"isSecure": "É seguro:",
|
||||
"port": "Porta:",
|
||||
"host": "Host:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "Código do país:",
|
||||
"region": "Região:",
|
||||
"city": "Cidade:",
|
||||
"asn": "ASN:",
|
||||
"organization": "Organização:",
|
||||
"location": "Localização:",
|
||||
"postalCode": "Código postal:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Perguntar sempre",
|
||||
"alertMessage": "Ocultar ou sair do aplicativo?",
|
||||
"remember": "Lembrar minha escolha"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Toque para conectar",
|
||||
"connect": "Conectar",
|
||||
"connecting": "Conectando...",
|
||||
"connected": "Conectado",
|
||||
"disconnect": "Desconectar",
|
||||
"disconnecting": "Desconectando...",
|
||||
"reconnect": "Reconectar",
|
||||
"reconnectMsg": "Reconectando para aplicar as alterações...",
|
||||
"secure": "Protegido por WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Erro inesperado",
|
||||
"connection": {
|
||||
"unexpected": "Erro de conexão inesperado",
|
||||
"timeout": "Tempo limite de conexão esgotado",
|
||||
"badResponse": "Resposta inválida",
|
||||
"connectionError": "Erro de conexão",
|
||||
"badCertificate": "Certificado inválido"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Erro inesperado",
|
||||
"notFound": "Perfil não encontrado",
|
||||
"invalidConfig": "Configurações inválidas",
|
||||
"invalidUrl": "URL inválida",
|
||||
"canceledByUser": "Cancelado pelo usuário"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Falha inesperada",
|
||||
"missingVpnPermission": "Permissão de VPN ausente",
|
||||
"missingNotificationPermission": "Permissão de notificação ausente",
|
||||
"core": "Erro no núcleo"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "O serviço não está em execução",
|
||||
"missingPrivilege": "Permissão ausente",
|
||||
"missingPrivilegeMsg": "O modo VPN requer privilégios de administrador. Reinicie o aplicativo como administrador ou altere o modo de serviço.",
|
||||
"invalidConfigOptions": "Opções de configuração inválidas",
|
||||
"invalidConfig": "Configuração inválida"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "Licença do WARP ausente",
|
||||
"missingLicenseMsg": "O perfil selecionado usa o recurso WARP. Para usar este recurso, você deve concordar com a licença do WARP."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,632 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Начать",
|
||||
"version": "Версия",
|
||||
"ok": "OK",
|
||||
"cancel": "Отмена",
|
||||
"kContinue": "Продолжить",
|
||||
"showMore": "Показать больше",
|
||||
"showLess": "Показать меньше",
|
||||
"filter": "Фильтр",
|
||||
"all": "Все",
|
||||
"pause": "Пауза",
|
||||
"resume": "Возобновить",
|
||||
"clear": "Очистить",
|
||||
"close": "Закрыть",
|
||||
"auto": "Авто",
|
||||
"manually": "Вручную",
|
||||
"name": "Имя",
|
||||
"url": "URL",
|
||||
"add": "Добавить",
|
||||
"clipboard": "Буфер обмена",
|
||||
"addToClipboard": "Добавить в буфер обмена",
|
||||
"scanQr": "Сканировать QR",
|
||||
"free": "Бесплатно",
|
||||
"warp": "WARP",
|
||||
"fragment": "Фрагмент",
|
||||
"help": "Справка",
|
||||
"save": "Сохранить",
|
||||
"update": "Обновить",
|
||||
"share": "Поделиться",
|
||||
"edit": "Изменить",
|
||||
"delete": "Удалить",
|
||||
"discard": "Отменить",
|
||||
"import": "Импорт",
|
||||
"export": "Экспорт",
|
||||
"later": "Позже",
|
||||
"ignore": "Игнорировать",
|
||||
"quit": "Выход",
|
||||
"notSet": "Не задано",
|
||||
"hide": "Скрыть",
|
||||
"exit": "Выйти",
|
||||
"reset": "Сброс",
|
||||
"done": "Готово",
|
||||
"search": "Поиск",
|
||||
"decline": "Отклонить",
|
||||
"agree": "Согласен",
|
||||
"empty": "Пусто",
|
||||
"unknown": "Неизвестно",
|
||||
"hidden": "Скрытый",
|
||||
"timeout": "Тайм-аут",
|
||||
"sort": "Сортировать",
|
||||
"dashboard": "Панель управления",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n день",
|
||||
"few": "$n дня",
|
||||
"many": "$n дней",
|
||||
"other": "$n дня"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n час",
|
||||
"few": "$n часа",
|
||||
"many": "$n часов",
|
||||
"other": "$n часа"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "Доступ запрещен"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Успешно добавлено в буфер обмена",
|
||||
"failure": "Не удалось скопировать в буфер обмена",
|
||||
"contentTooLarge": "Слишком большой контент. Используйте экспорт в файл"
|
||||
},
|
||||
"file": {
|
||||
"success": "Файл JSON успешно создан",
|
||||
"failure": "Не удалось создать файл"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "Подтвердить импорт",
|
||||
"success": "Успешно импортировано",
|
||||
"failure": "Не удалось импортировать"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "Все, что вам нужно для интернета без ограничений",
|
||||
"termsAndPolicyCaution(rich)": "Продолжая, вы соглашаетесь с ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "Сделано с ❤️ Hiddify - ${tap_source(Открытый исходный код)} (${tap_license(Лицензия)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Главная",
|
||||
"quickSettings": "Быстрые настройки"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Прокси",
|
||||
"sort": "Сортировать прокси",
|
||||
"testDelay": "Проверить задержку",
|
||||
"empty": "Нет доступных прокси",
|
||||
"activeProxy": "Активный прокси",
|
||||
"unknownIp": "Неизвестный IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "По умолчанию",
|
||||
"name": "По алфавиту",
|
||||
"delay": "По задержке"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "IP-адрес",
|
||||
"country": "Страна",
|
||||
"organization": "Организация"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Задержка: ${delay} мс",
|
||||
"timeout": "Тайм-аут теста задержки",
|
||||
"testing": "Задержка: тестирование..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Профили",
|
||||
"add": "Добавить профиль",
|
||||
"update": "Обновить профиль",
|
||||
"viewAllProfiles": "Посмотреть все профили",
|
||||
"activeProfileName": "Имя активного профиля: \"${name}\".",
|
||||
"nonActiveProfileName": "Выбрать \"${name}\" как активный профиль",
|
||||
"freeSubNotFound": "Бесплатная подписка не найдена",
|
||||
"freeSubNotFoundForRegion": "Бесплатная подписка для региона \"${region}\" не найдена",
|
||||
"failedToLoad": "Не удалось загрузить",
|
||||
"updateSubscriptions": "Обновить подписки",
|
||||
"share": {
|
||||
"urlToClipboard": "URL в буфер обмена",
|
||||
"showUrlQr": "Показать QR-код URL",
|
||||
"jsonToClipboard": "JSON в буфер обмена"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Профиль успешно сохранен"
|
||||
},
|
||||
"invalidUrl": "Неверный URL",
|
||||
"add": {
|
||||
"failure": "Не удалось добавить профиль"
|
||||
},
|
||||
"update": {
|
||||
"success": "Профиль успешно обновлен",
|
||||
"successNamed": "\"${name}\" успешно обновлен",
|
||||
"failure": "Не удалось обновить профиль",
|
||||
"failureNamed": "Не удалось обновить \"${name}\""
|
||||
},
|
||||
"delete": {
|
||||
"success": "Профиль успешно удален"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Профиль",
|
||||
"lastUpdate": "Последнее обновление",
|
||||
"form": {
|
||||
"nameHint": "Имя профиля",
|
||||
"emptyName": "Имя обязательно для заполнения",
|
||||
"invalidUrl": "Неверный URL",
|
||||
"urlHint": "Полный URL конфигурации",
|
||||
"disableAutoUpdate": "Отключить автообновление",
|
||||
"autoUpdateInterval": "Интервал автообновления",
|
||||
"loading": "Добавление профиля..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Логи",
|
||||
"shareCoreLogs": "Поделиться логами ядра",
|
||||
"shareAppLogs": "Поделиться логами приложения"
|
||||
},
|
||||
"about": {
|
||||
"title": "О программе",
|
||||
"notAvailableMsg": "Вы уже используете последнюю версию",
|
||||
"checkForUpdate": "Проверить обновления",
|
||||
"openWorkingDir": "Открыть рабочую папку",
|
||||
"sourceCode": "Исходный код",
|
||||
"telegramChannel": "Канал в Telegram",
|
||||
"termsAndConditions": "Условия использования",
|
||||
"privacyPolicy": "Политика конфиденциальности"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Настройки",
|
||||
"resetTunnel": "Сбросить профиль VPN",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Импортировать настройки из буфера обмена",
|
||||
"file": "Импортировать настройки из файла"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Копировать анонимные настройки в буфер обмена",
|
||||
"anonymousToFile": "Экспортировать анонимные настройки в файл",
|
||||
"allToClipboard": "Копировать все настройки в буфер обмена",
|
||||
"allToFile": "Экспортировать все настройки в файл"
|
||||
},
|
||||
"reset": "Сбросить настройки"
|
||||
},
|
||||
"general": {
|
||||
"title": "Общие",
|
||||
"locale": "Язык",
|
||||
"themeMode": "Тема оформления",
|
||||
"themeModes": {
|
||||
"system": "Системная",
|
||||
"dark": "Темная",
|
||||
"light": "Светлая",
|
||||
"black": "Черная"
|
||||
},
|
||||
"enableAnalytics": "Включить аналитику",
|
||||
"enableAnalyticsMsg": "Разрешить сбор аналитики и отправку отчетов о сбоях для улучшения приложения",
|
||||
"autoIpCheck": "Автоматически проверять IP-адрес",
|
||||
"dynamicNotification": "Отображать скорость в уведомлении",
|
||||
"hapticFeedback": "Тактильный отклик",
|
||||
"actionAtClosing": "Действие при закрытии",
|
||||
"autoStart": "Запускать при входе в систему",
|
||||
"silentStart": "Запускать свернутым",
|
||||
"ignoreBatteryOptimizations": "Отключить оптимизацию батареи",
|
||||
"ignoreBatteryOptimizationsMsg": "Снять ограничения для оптимальной работы VPN",
|
||||
"memoryLimit": "Ограничение памяти",
|
||||
"memoryLimitMsg": "Включите, если вы сталкиваетесь с ошибками нехватки памяти или частыми сбоями приложения",
|
||||
"debugMode": "Режим отладки",
|
||||
"debugModeMsg": "Перезапустите приложение, чтобы применить это изменение",
|
||||
"logLevel": "Уровень логирования",
|
||||
"connectionTestUrl": "URL для теста соединения",
|
||||
"urlTestInterval": "Интервал теста URL",
|
||||
"clashApiPort": "Порт Clash API",
|
||||
"useXrayCoreWhenPossible": "Использовать xray-core, если возможно",
|
||||
"useXrayCoreWhenPossibleMsg": "Использовать xray-core при обработке ссылок на подписку. Необходимо повторно импортировать ссылку, чтобы включить эту опцию."
|
||||
},
|
||||
"routing": {
|
||||
"title": "Маршрутизация",
|
||||
"perAppProxy": {
|
||||
"title": "Прокси для приложений",
|
||||
"hideSysApps": "Скрыть системные приложения",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Импортировать выбор из буфера обмена",
|
||||
"file": "Импортировать выбор из файла",
|
||||
"msg": "Импорт заменит ваш текущий выбор. Вы уверены, что хотите продолжить?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Копировать выбор в буфер обмена",
|
||||
"file": "Экспортировать выбор в файл"
|
||||
},
|
||||
"shareToAll": "Поделиться со всеми",
|
||||
"clearAllSelections": "Очистить весь выбор"
|
||||
},
|
||||
"modes": {
|
||||
"all": "Все",
|
||||
"proxy": "Прокси",
|
||||
"bypass": "В обход",
|
||||
"allMsg": "Проксировать все приложения",
|
||||
"proxyMsg": "Проксировать только выбранные приложения",
|
||||
"bypassMsg": "Не проксировать выбранные приложения"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Автовыбор",
|
||||
"performNow": "Выполнить сейчас",
|
||||
"resetToDefault": "Сбросить по умолчанию",
|
||||
"autoUpdateInterval": "Интервал автообновления",
|
||||
"toast": {
|
||||
"success": "Автовыбор приложений успешно завершен",
|
||||
"failure": "Ошибка автовыбора",
|
||||
"regionNotFound": "Автовыбор для региона \"${region}\" не найден",
|
||||
"alreadyInAuto": "Ваш выбор уже находится в списке автовыбора"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Автовыбор приложений",
|
||||
"msg": "Функция автовыбора для прокси приложений была отключена из-за смены региона на \"${region}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Регион",
|
||||
"regions": {
|
||||
"ir": "Иран (ir) 🇮🇷",
|
||||
"cn": "Китай (cn) 🇨🇳",
|
||||
"ru": "Россия (ru) 🇷🇺",
|
||||
"af": "Афганистан (af) 🇦🇫",
|
||||
"id": "Индонезия (id) 🇮🇩",
|
||||
"tr": "Турция (tr) 🇹🇷",
|
||||
"br": "Бразилия (br) 🇧🇷",
|
||||
"other": "Другой"
|
||||
},
|
||||
"blockAds": "Блокировать рекламу",
|
||||
"bypassLan": "Обход LAN",
|
||||
"resolveDestination": "Определять адрес назначения",
|
||||
"ipv6Route": "Маршрут IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Отключить",
|
||||
"enable": "Включить",
|
||||
"prefer": "Предпочтительно",
|
||||
"only": "Только"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Правила маршрутизации",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Импортировать правила из буфера обмена",
|
||||
"file": "Импортировать правила из файла"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Копировать правила в буфер обмена",
|
||||
"file": "Сохранить правила в файл"
|
||||
},
|
||||
"reset": "Сбросить правила"
|
||||
},
|
||||
"deleteRule": "Удалить правило",
|
||||
"createRule": "Создать новое правило",
|
||||
"rule": {
|
||||
"title": "Правило",
|
||||
"ruleChanged": "Правило изменено",
|
||||
"ruleChangedMsg": "Вы хотите сохранить изменения?",
|
||||
"onlyTunMode": "Доступно только в режиме TUN",
|
||||
"notAvailabeInThisPlatform": "Недоступно на этой платформе",
|
||||
"canNotBeEmpty": "Не может быть пустым",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "Валидный \"URL\", например\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe или google chrome или chrome",
|
||||
"validProcessName": "Валидное \"Имя процесса\", например\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "Валидный \"Путь к процессу\", например\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 или 1-65000",
|
||||
"validPortRange": "Валидный \"Порт\" или \"Диапазон портов\", например\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 или 10.0.0.0/24",
|
||||
"validIpCidr": "Валидный IP CIDR, например\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com или dl.google.com",
|
||||
"validDomain": "Валидный \"Домен\", например\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com или .ru",
|
||||
"validDomainSuffix": "Валидный \"Суффикс домена\", например\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "Имя",
|
||||
"outbound": "Исходящий при совпадении",
|
||||
"rule_set": "URL набора правил",
|
||||
"package_name": "Имена пакетов",
|
||||
"process_name": "Имена процессов",
|
||||
"process_path": "Пути к процессам",
|
||||
"network": "Сети",
|
||||
"port_range": "Порты назначения",
|
||||
"source_port_range": "Исходные порты",
|
||||
"protocol": "Протокол",
|
||||
"ip_cidr": "IP CIDR назначения",
|
||||
"source_ip_cidr": "Исходный IP CIDR",
|
||||
"domain": "Домен",
|
||||
"domain_suffixe": "Суффикс домена",
|
||||
"domain_keyword": "Ключевое слово домена",
|
||||
"domain_regex": "Регулярное выражение домена"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Прокси",
|
||||
"direct": "Напрямую",
|
||||
"direct_with_fragment": "Напрямую с фрагментом",
|
||||
"block": "Блокировать"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "Все",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "Все",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Добавить новое значение",
|
||||
"update": "Обновить значение",
|
||||
"clearList": "Очистить список",
|
||||
"clearListMsg": "Все элементы удалены"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Приложения Android",
|
||||
"showSystemApps": "Показать системные приложения",
|
||||
"hideSystemApps": "Скрыть системные приложения",
|
||||
"clearSelection": "Очистить выбор",
|
||||
"uninstalled": "Удалено"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "Удаленный DNS",
|
||||
"remoteDnsDomainStrategy": "Стратегия удаленного домена DNS",
|
||||
"directDns": "Прямой DNS",
|
||||
"directDnsDomainStrategy": "Стратегия прямого домена DNS",
|
||||
"enableDnsRouting": "Включить маршрутизацию DNS",
|
||||
"domainStrategy": {
|
||||
"auto": "Авто",
|
||||
"preferIpv6": "Предпочитать IPv6",
|
||||
"preferIpv4": "Предпочитать IPv4",
|
||||
"ipv4Only": "Только IPv4",
|
||||
"ipv6Only": "Только IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Входящие",
|
||||
"serviceMode": "Режим службы",
|
||||
"serviceModes": {
|
||||
"proxy": "Только прокси-служба",
|
||||
"systemProxy": "Установить системный прокси",
|
||||
"tun": "VPN",
|
||||
"tunService": "Служба VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Прокси",
|
||||
"systemProxy": "Системный прокси",
|
||||
"tun": "VPN",
|
||||
"tunService": "Служба VPN"
|
||||
},
|
||||
"strictRoute": "Строгая маршрутизация",
|
||||
"tunImplementation": "Реализация TUN",
|
||||
"tunImplementations": {
|
||||
"mixed": "Смешанная",
|
||||
"system": "Системная",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Смешанный порт",
|
||||
"tproxyPort": "Порт прозрачного прокси",
|
||||
"directPort": "Локальный порт direct",
|
||||
"allowConnectionFromLan": "Поделиться VPN в локальной сети"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "Трюки TLS",
|
||||
"enable": "Включить фрагментацию",
|
||||
"size": "Размер фрагмента",
|
||||
"sleep": "Задержка фрагмента",
|
||||
"mixedSniCase": {
|
||||
"enable": "Включить смешанный регистр SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Включить дополнение",
|
||||
"size": "Размер дополнения"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "Включить WARP",
|
||||
"generateConfig": "Сгенерировать конфигурацию WARP",
|
||||
"configGenerated": "Конфигурация Warp сгенерирована",
|
||||
"missingConfig": "Отсутствует конфигурация WARP",
|
||||
"detourMode": "Режим маршрутизации WARP",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Направлять прокси через WARP",
|
||||
"warpOverProxy": "Направлять WARP через прокси",
|
||||
"proxyOverWarpExplain": "Разблокировать прокси с помощью WARP",
|
||||
"warpOverProxyExplain": "Дополнительная безопасность с WARP"
|
||||
},
|
||||
"licenseKey": "Лицензионный ключ",
|
||||
"cleanIp": "Чистый IP",
|
||||
"port": "Порт",
|
||||
"noise": {
|
||||
"count": "Количество шума",
|
||||
"mode": "Режим шума",
|
||||
"size": "Размер шума",
|
||||
"delay": "Задержка шума"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Соединение",
|
||||
"traffic": "Трафик",
|
||||
"trafficLive": "Текущий трафик",
|
||||
"trafficTotal": "Общий трафик",
|
||||
"uplink": "Отправка",
|
||||
"downlink": "Прием",
|
||||
"speed": "Скорость",
|
||||
"totalTransferred": "Всего передано"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Отправлено",
|
||||
"download": "Получено",
|
||||
"total": "Всего трафика",
|
||||
"expireDate": "Дата окончания",
|
||||
"expired": "Истек",
|
||||
"noTraffic": "Квота исчерпана",
|
||||
"remainingTime": "Оставшееся время",
|
||||
"remainingDuration": "осталось ${duration} дней",
|
||||
"remainingDurationNew": "${duration} дней",
|
||||
"remainingTrafficSemanticLabel": "израсходовано ${consumed} из ${total} трафика",
|
||||
"remainingTraffic": "Оставшийся трафик",
|
||||
"remainingUsage": "Осталось",
|
||||
"profileSite": "Провайдер",
|
||||
"profileSupport": "Поддержка"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Сортировать по",
|
||||
"sort": {
|
||||
"name": "По алфавиту",
|
||||
"lastUpdate": "Последнему обновлению"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Соглашение о WARP от Cloudflare",
|
||||
"description(rich)": "Cloudflare WARP - это бесплатный провайдер WireGuard VPN. Включая эту опцию, вы соглашаетесь с ${tos(Условиями обслуживания)} и ${privacy(Политикой конфиденциальности)} Cloudflare WARP."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Доступно обновление",
|
||||
"msg": "Доступна новая версия @:common.appTitle. Хотите обновить сейчас?",
|
||||
"currentVersion": "Текущая версия: ",
|
||||
"newVersion": "Новая версия: ",
|
||||
"updateNow": "Обновить сейчас"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "Это перезапишет все параметры конфигурации предоставленными значениями. Вы уверены?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Удалить профиль",
|
||||
"msg": "Вы уверены, что хотите навсегда удалить этот профиль?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Улучшение автовыбора",
|
||||
"msg": "Делясь выбранными приложениями, вы помогаете пополнить список \"автовыбора\""
|
||||
},
|
||||
"import": {
|
||||
"msg": "Это заменит все ваши текущие настройки прокси для приложений. Вы уверены, что хотите продолжить?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Удалить правило",
|
||||
"msg": "Вы уверены, что хотите удалить правило \"$rulename\"?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Используются экспериментальные функции",
|
||||
"msg": "Вы включили некоторые экспериментальные функции, которые могут повлиять на качество соединения и вызвать непредвиденные ошибки. Вы всегда можете изменить или сбросить эти параметры на странице настроек.",
|
||||
"disable": "Больше не показывать"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Выберите профиль",
|
||||
"msg": "Давайте начнем с добавления профиля подключения, который содержит данные вашего VPN-соединения.\n\nЕще нет VPN-сервера? Не беспокойтесь — просто следуйте руководству ниже, чтобы быстро и бесплатно настроить его.",
|
||||
"helpBtn": {
|
||||
"label": "Покажите, как",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "Предупреждение о внешней ссылке",
|
||||
"youAreAboutToVisit": "Вы собираетесь перейти на сайт:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "Этот сайт не входит в наш список доверенных. Пожалуйста, действуйте с осторожностью."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Полный тег:",
|
||||
"type": "Тип:",
|
||||
"testTime": "Время теста:",
|
||||
"testDelay": "Задержка теста:",
|
||||
"isSelected": "Выбран:",
|
||||
"isGroup": "Это группа",
|
||||
"isSecure": "Защищено:",
|
||||
"port": "Порт:",
|
||||
"host": "Хост:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "Код страны:",
|
||||
"region": "Регион:",
|
||||
"city": "Город:",
|
||||
"asn": "ASN:",
|
||||
"organization": "Организация:",
|
||||
"location": "Местоположение:",
|
||||
"postalCode": "Почтовый индекс:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Спрашивать каждый раз",
|
||||
"alertMessage": "Скрыть или выйти из приложения?",
|
||||
"remember": "Запомнить мой выбор"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Нажмите для подключения",
|
||||
"connect": "Подключить",
|
||||
"connecting": "Подключение...",
|
||||
"connected": "Подключено",
|
||||
"disconnect": "Отключить",
|
||||
"disconnecting": "Отключение...",
|
||||
"reconnect": "Переподключить",
|
||||
"reconnectMsg": "Переподключение для учета изменений...",
|
||||
"secure": "Защищено с помощью WARP"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Непредвиденная ошибка",
|
||||
"connection": {
|
||||
"unexpected": "Непредвиденная ошибка подключения",
|
||||
"timeout": "Тайм-аут подключения",
|
||||
"badResponse": "Неверный ответ",
|
||||
"connectionError": "Ошибка подключения",
|
||||
"badCertificate": "Недействительный сертификат"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Непредвиденная ошибка",
|
||||
"notFound": "Профиль не найден",
|
||||
"invalidConfig": "Неверная конфигурация",
|
||||
"invalidUrl": "Неверный URL",
|
||||
"canceledByUser": "Отменено пользователем"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Непредвиденный сбой",
|
||||
"missingVpnPermission": "Отсутствует разрешение на VPN",
|
||||
"missingNotificationPermission": "Отсутствует разрешение на уведомления",
|
||||
"core": "Ошибка ядра"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "Служба не запущена",
|
||||
"missingPrivilege": "Отсутствуют права",
|
||||
"missingPrivilegeMsg": "Режим VPN требует прав администратора. Либо перезапустите приложение от имени администратора, либо измените режим службы.",
|
||||
"invalidConfigOptions": "Неверные параметры конфигурации",
|
||||
"invalidConfig": "Неверная конфигурация"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "Отсутствует лицензия Warp",
|
||||
"missingLicenseMsg": "Выбранный профиль использует функцию WARP; для использования этой функции необходимо принять лицензию WARP."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,420 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "هیدیفای",
|
||||
"reset": "إعادة تعيين",
|
||||
"toggle": {
|
||||
"enabled": "مُفعّل",
|
||||
"disabled": "غير مُفعّل"
|
||||
},
|
||||
"state": {
|
||||
"disable": "تعطيل"
|
||||
},
|
||||
"sort": "فرز",
|
||||
"sortBy": "فرز حسب",
|
||||
"addToClipboard": "إضافة إلى الحافظة",
|
||||
"notSet": "غير مُحدد",
|
||||
"agree": "موافقة",
|
||||
"decline": "رفض",
|
||||
"unknown": "غير معروف",
|
||||
"hidden": "مخفي",
|
||||
"timeout": "انتهاء الوقت",
|
||||
"clipboardExportSuccessMsg": "تمت إضافة البيانات إلى الحافظة",
|
||||
"showMore": "عرض المزيد",
|
||||
"showLess": "عرض أقل",
|
||||
"openAppSettings": "فتح إعدادات التطبيق",
|
||||
"grantPermission": "منح الإذن"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "بمواصلة استخدامك، فإنك توافق على ${tap(@:about.termsAndConditions)}",
|
||||
"start": "ابدأ"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "الصفحة الرئيسية",
|
||||
"emptyProfilesMsg": "ابدأ بإضافة ملف تعريف اشتراك",
|
||||
"noActiveProfileMsg": "اختر ملف تعريف"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "حركة المرور",
|
||||
"trafficLive": "حركة المرور الحية",
|
||||
"trafficTotal": "إجمالي حركة المرور",
|
||||
"uplink": "الصعود",
|
||||
"downlink": "الهبوط",
|
||||
"connection": "الاتصال",
|
||||
"speed": "السرعة",
|
||||
"totalTransferred": "إجمالي البيانات المنقولة"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "الملفات الشخصية",
|
||||
"detailsPageTitle": "ملف التعريف",
|
||||
"activeProfileNameSemanticLabel": "اسم ملف التعريف النشط: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "عرض جميع ملفات التعريف",
|
||||
"nonActiveProfileBtnSemanticLabel": "اختر \"${name}\" كملف تعريف نشط",
|
||||
"subscription": {
|
||||
"traffic": "حركة المرور",
|
||||
"updatedTimeAgo": "تم التحديث قبل ${timeago}",
|
||||
"remainingDuration": "تبقى ${duration} يومًا",
|
||||
"remainingTrafficSemanticLabel": "استُهلك ${consumed} من أصل ${total} حركة مرور",
|
||||
"expired": "منتهي الصلاحية",
|
||||
"noTraffic": "غير متاح",
|
||||
"upload": "التحميل",
|
||||
"download": "التنزيل",
|
||||
"total": "إجمالي حركة المرور",
|
||||
"expireDate": "تاريخ انتهاء الصلاحية"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "تم التحديث مؤخرًا",
|
||||
"name": "أبجديًا"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "ملف تعريف جديد",
|
||||
"shortBtnTxt": "ملف تعريف جديد",
|
||||
"fromClipboard": "إضافة من الحافظة",
|
||||
"scanQr": "مسح رمز الاستجابة السريعة",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "تم رفض الإذن",
|
||||
"unexpectedError": "حدث خطأ ما",
|
||||
"torchSemanticLabel": "ضوء فلاش",
|
||||
"facingSemanticLabel": "اتجاه الكاميرا",
|
||||
"permissionRequest": "الإذن للكاميرا لمسح رمز الاستجابة السريعة"
|
||||
},
|
||||
"manually": "إدخال يدوي",
|
||||
"addWarp": "أضف WARP",
|
||||
"addingWarpMsg": "الرجاء الانتظار بينما نقوم بتسجيل WARP.",
|
||||
"addingProfileMsg": "إضافة ملف التعريف",
|
||||
"failureMsg": "فشل في إضافة ملف التعريف"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "تحديث",
|
||||
"tooltip": "تحديث ملف التعريف",
|
||||
"updateSubscriptions": "تحديث الاشتراكات",
|
||||
"failureMsg": "فشل في تحديث ملف التعريف",
|
||||
"successMsg": "تم تحديث ملف التعريف بنجاح",
|
||||
"namedFailureMsg": "فشل في تحديث \"${name}\"",
|
||||
"namedSuccessMsg": "تم تحديث \"${name}\" بنجاح"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "مشاركة",
|
||||
"exportToClipboardSuccess": "تم تصدير البيانات إلى الحافظة",
|
||||
"exportSubLinkToClipboard": "تصدير رابط الاشتراك إلى الحافظة",
|
||||
"subLinkQrCode": "رمز الاستجابة السريعة لرابط الاشتراك",
|
||||
"exportConfigToClipboard": "تصدير التكوين إلى الحافظة",
|
||||
"exportConfigToClipboardSuccess": "تم نسخ التكوين إلى الحافظة"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "تحرير",
|
||||
"selectActiveTxt": "اختر ملف التعريف النشط"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "حذف",
|
||||
"confirmationMsg": "حذف ملف التعريف نهائياً؟",
|
||||
"successMsg": "تم حذف ملف التعريف بنجاح"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "حفظ",
|
||||
"successMsg": "تم حفظ ملف التعريف بنجاح",
|
||||
"failureMsg": "فشل في حفظ ملف التعريف"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "الاسم",
|
||||
"nameHint": "اسم ملف التعريف",
|
||||
"urlLabel": "العنوان",
|
||||
"urlHint": "عنوان URL للتكوين الكامل",
|
||||
"emptyNameMsg": "الاسم مطلوب",
|
||||
"invalidUrlMsg": "عنوان URL غير صالح",
|
||||
"lastUpdate": "آخر تحديث",
|
||||
"updateInterval": "التحديث التلقائي",
|
||||
"updateIntervalDialogTitle": "مُدة التحديث التلقائي (بالساعات)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "الخوادم الوكيلية",
|
||||
"emptyProxiesMsg": "لا توجد خوادم وكيلية متاحة",
|
||||
"delayTestTooltip": "اختبار التأخير",
|
||||
"sortTooltip": "فرز الخوادم الوكيلية",
|
||||
"checkIp": "تحقق من عنوان IP",
|
||||
"unknownIp": "عنوان IP غير معروف",
|
||||
"sortOptions": {
|
||||
"unsorted": "افتراضي",
|
||||
"name": "أبجديًا",
|
||||
"delay": "حسب التأخير"
|
||||
},
|
||||
"activeProxySemanticLabel": "الخادم الوكيل النشط",
|
||||
"delaySemantics": {
|
||||
"result": "التأخير: ${delay} مللي ثانية",
|
||||
"timeout": "انتهاء الوقت في اختبار التأخير",
|
||||
"testing": "التأخير: قيد الاختبار..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "عنوان IP",
|
||||
"country": "الدولة"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "السجلات",
|
||||
"filterHint": "تصفية",
|
||||
"allLevelsFilter": "الكل",
|
||||
"shareCoreLogs": "مشاركة سجلات النواة",
|
||||
"shareAppLogs": "مشاركة سجلات التطبيق",
|
||||
"pauseTooltip": "إيقاف مؤقت",
|
||||
"resumeTooltip": "استئناف",
|
||||
"clearTooltip": "مسح"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "الإعدادات",
|
||||
"requiresRestartMsg": "لتطبيق هذه التغييرات، أعد تشغيل التطبيق",
|
||||
"experimental": "تجريبي",
|
||||
"experimentalMsg": "الميزات ذات العلامة التجريبية لا تزال قيد التطوير وقد تسبب مشاكل.",
|
||||
"exportOptions": "تصدير الخيارات إلى الحافظة",
|
||||
"exportAllOptions": "تصدير جميع الخيارات إلى الحافظة (تصحيح الأخطاء)",
|
||||
"importOptions": "استيراد الخيارات من الحافظة",
|
||||
"importOptionsMsg": "سيؤدي هذا إلى إعادة كتابة جميع خيارات التكوين بالقيم المحددة. هل أنت متأكد؟",
|
||||
"general": {
|
||||
"sectionTitle": "عام",
|
||||
"locale": "اللغة",
|
||||
"region": "المنطقة",
|
||||
"regionMsg": "يساعد على تعيين الخيارات الافتراضية لتجاوز العناوين المحلية",
|
||||
"regions": {
|
||||
"ir": "إيران (ir)",
|
||||
"cn": "الصين (cn)",
|
||||
"ru": "روسيا (ru)",
|
||||
"af": "أفغانستان (af)",
|
||||
"id": "إندونيسيا (id)",
|
||||
"tr": "تركيا (tr) 🇹🇷",
|
||||
"other": "أخرى"
|
||||
},
|
||||
"themeMode": "وضع السمة",
|
||||
"themeModes": {
|
||||
"system": "اتباع سمة النظام",
|
||||
"dark": "الوضع الداكن",
|
||||
"light": "الوضع الفاتح",
|
||||
"black": "الوضع الأسود"
|
||||
},
|
||||
"enableAnalytics": "تمكين التحليلات",
|
||||
"enableAnalyticsMsg": "منح الإذن بجمع التحليلات وإرسال تقارير الأعطال لتحسين التطبيق",
|
||||
"autoStart": "بدء التشغيل عند تسجيل الدخول",
|
||||
"silentStart": "بدء التشغيل مُصغر",
|
||||
"openWorkingDir": "فتح دليل العمل",
|
||||
"ignoreBatteryOptimizations": "تعطيل تحسينات البطارية",
|
||||
"ignoreBatteryOptimizationsMsg": "إزالة القيود للحصول على أفضل أداء VPN",
|
||||
"dynamicNotification": "عرض السرعة في الإشعار",
|
||||
"hapticFeedback": "ردود فعل اللمس",
|
||||
"autoIpCheck": "التحقق من عنوان IP للاتصال تلقائيًا"
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "متقدم",
|
||||
"debugMode": "وضع تصحيح الأخطاء",
|
||||
"debugModeMsg": "أعد تشغيل التطبيق لتطبيق هذا التغيير",
|
||||
"memoryLimit": "حد الذاكرة",
|
||||
"memoryLimitMsg": "قم بتمكين هذه الميزة إذا كنت تواجه أخطاء «عدم كفاية الذاكرة» أو تعطل التطبيق بشكل متكرر",
|
||||
"resetTunnel": "إعادة تعيين ملف تعريف VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "الوكيل لكل تطبيق",
|
||||
"perAppProxyModes": {
|
||||
"off": "الكل",
|
||||
"offMsg": "وكيل جميع التطبيقات",
|
||||
"include": "وكيل",
|
||||
"includeMsg": "وكيل التطبيقات المحددة فقط",
|
||||
"exclude": "تجاوز",
|
||||
"excludeMsg": "لا تستخدم الوكيل للتطبيقات المحددة"
|
||||
},
|
||||
"showSystemApps": "عرض تطبيقات النظام",
|
||||
"hideSystemApps": "إخفاء تطبيقات النظام",
|
||||
"clearSelection": "مسح الاختيار"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "أصول التوجيه",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "GeoSite",
|
||||
"version": "الإصدار ${version}",
|
||||
"fileMissing": "الملف مفقود",
|
||||
"update": "تحديث",
|
||||
"download": "تنزيل",
|
||||
"failureMsg": "فشل في تحديث الأصل",
|
||||
"successMsg": "تم تحديث الأصل بنجاح",
|
||||
"addRecommended": "إضافة الأصول الموصى بها",
|
||||
"missingGeoAssetsMsg": "ملفات أصول التوجيه المحددة مفقودة. قم بتنزيلها أو اختر ملفات موجودة"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "حول\nتعريب:م. ابراهيم قاسم",
|
||||
"version": "الإصدار",
|
||||
"sourceCode": "رمز المصدر",
|
||||
"telegramChannel": "قناة تلگرام",
|
||||
"checkForUpdate": "التحقق من وجود تحديث",
|
||||
"privacyPolicy": "سياسة الخصوصية",
|
||||
"termsAndConditions": "الشروط والأحكام"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "أنت تستخدم أحدث إصدار بالفعل",
|
||||
"dialogTitle": "تحديث متاح",
|
||||
"updateMsg": "إصدار جديد من @:general.appTitle متاح. هل تريد التحديث الآن؟",
|
||||
"currentVersionLbl": "الإصدار الحالي",
|
||||
"newVersionLbl": "الإصدار الجديد",
|
||||
"updateNowBtnTxt": "تحديث الآن",
|
||||
"laterBtnTxt": "لاحقًا",
|
||||
"ignoreBtnTxt": "تجاهل"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "لوحة التحكم",
|
||||
"quit": "إنهاء",
|
||||
"open": "فتح",
|
||||
"status": {
|
||||
"connect": "الاتصال",
|
||||
"connecting": "جار الاتصال",
|
||||
"disconnect": "فصم الاتصال",
|
||||
"disconnecting": "جار فصم الاتصال"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "خطأ غير متوقع",
|
||||
"clash": {
|
||||
"unexpected": "خطأ غير متوقع",
|
||||
"core": "خطأ في Clash ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "خطأ في الخدمة غير متوقع",
|
||||
"serviceNotRunning": "الخدمة غير قيد التشغيل",
|
||||
"missingPrivilege": "غياب الامتياز",
|
||||
"missingPrivilegeMsg": "وضع VPN يتطلب امتيازات المسؤول. أعد تشغيل التطبيق كمسؤول أو غيّر وضع الخدمة.",
|
||||
"missingGeoAssets": "أصول Geo مفقودة",
|
||||
"missingGeoAssetsMsg": "أصول Geo مفقودة. فكر في تغيير الأصل النشط أو تنزيل الأصل المحدد في الإعدادات.",
|
||||
"invalidConfigOptions": "خيارات التكوين غير صحيحة",
|
||||
"invalidConfig": "تكوين غير صالح",
|
||||
"create": "خطأ في إنشاء الخدمة",
|
||||
"start": "خطأ في بدء تشغيل الخدمة"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "فشل غير متوقع",
|
||||
"missingVpnPermission": "غياب إذن VPN",
|
||||
"missingNotificationPermission": "غياب إذن الإشعارات",
|
||||
"core": "خطأ في النواة"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "خطأ غير متوقع",
|
||||
"notFound": "لم يتم العثور على ملف التعريف",
|
||||
"invalidConfig": "تكوينات غير صحيحة",
|
||||
"invalidUrl": "عنوان URL غير صالح"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "خطأ في الاتصال غير متوقع",
|
||||
"timeout": "انتهاء الوقت في الاتصال",
|
||||
"badResponse": "استجابة سيئة",
|
||||
"connectionError": "خطأ في الاتصال",
|
||||
"badCertificate": "شهادة غير صالحة"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "خطأ غير متوقع",
|
||||
"notUpdate": "لا يوجد تحديث متاح",
|
||||
"activeNotFound": "لم يتم العثور على أصل Geo النشط"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (معاينة)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "الهدف الرئيسي لـ Hiddify هو توفير عميل نفق آمن وسهل الاستخدام وكفاءة. يمكّنك من توجيه جميع حركة المرور أو حركة المرور من التطبيق المحدد إلى خادم بعيد من اختيارك، باستخدام إذن VPN-Service. \n\nملاحظة: لا نوفر أي خادم، ويتعين على المستخدمين ضمان بقاء أنشطتهم عبر الإنترنت خاصة باستخدام خادمهم المخصص أو الخوادم الموثوقة. \n \nندعم الخوادم مع:\n- رابط اشتراك V2Ray/XRay عادي \n- رابط اشتراك Clash \n- رابط اشتراك Sing-Box \n\nما هي ميزاتنا الفريدة؟\n - سهل الاستخدام \n - مُحسّن وسريع \n - اختيار أدنى Ping تلقائيًا \n - عرض معلومات استخدام المستخدم \n - استيراد sublink بسهولة بنقرة واحدة باستخدام deeplinking \n - مجاني وخالي من الإعلانات \n - تبديل sublinks بسهولة \n - المزيد والمزيد \n\nالدعم:\n- جميع البروتوكولات التي تدعمها Sing-Box \n- VLESS + XTLS Reality, Vision \n- VMess \n- Trojan \n- ShoadowSocks \n- Reality \n- WireGuard \n- V2Ray \n- Hysteria2 \n- TUICv5 \n- SSH \n- ShadowTLS \n\n\nرمز المصدر موجود في https://github.com/hiddify/Hiddify-Next \nتعتمد نواة التطبيق على Sing-Box مفتوحة المصدر.\n\nوصف الإذن:\n- VPN Service: نظرًا لأن هدف هذا التطبيق هو توفير عميل نفق آمن وسهل الاستخدام وكفاءة، نحتاج إلى هذا الإذن لنتمكن من توجيه حركة المرور عبر النفق إلى الخادم البعيد. \n- QUERY ALL PACKAGES: يستخدم هذا الإذن للسماح للمستخدمين بتضمين أو استبعاد تطبيقات محددة للأنفاق. \n- RECEIVE BOOT COMPLETED: يمكن تمكين أو تعطيل هذا الإذن من إعدادات التطبيق لتنشيط هذا التطبيق عند تشغيل الجهاز. \n- POST NOTIFICATIONS: هذا الإذن ضروري لأننا نستخدم خدمة المقدمة لضمان تشغيل خدمة VPN بشكل مستمر. \n- هذا التطبيق خالي من الإعلانات. يتم جمع التحليلات وبيانات الأعطال فقط بموافقة صريحة من المستخدم في أول استخدام للتطبيق."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "انقر للاتصال",
|
||||
"connecting": "جار الاتصال",
|
||||
"disconnecting": "جار فصم الاتصال",
|
||||
"connected": "متصل",
|
||||
"reconnect": "أعد الاتصال",
|
||||
"connectAnyWay": "اتصل",
|
||||
"experimentalNotice": "ميزات تجريبية قيد الاستخدام",
|
||||
"experimentalNoticeMsg": "لقد قمت بتمكين بعض الميزات التجريبية التي قد تؤثر على جودة الاتصال وتسبب أخطاء غير متوقعة. يمكنك دائمًا تغيير هذه الخيارات أو إعادة تعيينها من صفحة خيارات التكوين.",
|
||||
"disableExperimentalNotice": "لا تعرض مرة أخرى",
|
||||
"reconnectMsg": "أعد الاتصال ليتم تطبيق التغييرات"
|
||||
},
|
||||
"config": {
|
||||
"resetBtn": "إعادة تعيين الخيارات",
|
||||
"serviceMode": "وضع الخدمة",
|
||||
"quickSettings": "الإعدادات السريعة",
|
||||
"setupWarp": "إعداد WARP",
|
||||
"allOptions": "جميع خيارات التكوين",
|
||||
"serviceModes": {
|
||||
"proxy": "خدمة الوكيل فقط",
|
||||
"systemProxy": "تعيين وكيل النظام",
|
||||
"tun": "VPN",
|
||||
"tunService": "خدمة VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "وكيل",
|
||||
"systemProxy": "وكيل النظام",
|
||||
"tun": "VPN",
|
||||
"tunService": "خدمة VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "خيارات التوجيه",
|
||||
"dns": "خيارات DNS",
|
||||
"inbound": "خيارات الوارد",
|
||||
"mux": "MultiPlexer",
|
||||
"outbound": "خيارات الخارج",
|
||||
"tlsTricks": "حيل TLS",
|
||||
"warp": "خيارات WARP",
|
||||
"misc": "خيارات متنوعة"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "موافقة Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP هو مزود VPN مجاني لـ WireGuard. بتمكين هذا الخيار، فإنك توافق على ${tos(Terms of Service)} و ${privacy(Privacy Policy)} لـ Cloudflare WARP."
|
||||
},
|
||||
"generateWarpConfig": "إنشاء تكوين WARP",
|
||||
"missingWarpConfig": "تكوين WARP مفقود",
|
||||
"warpConfigGenerated": "تم إنشاء تكوين WARP",
|
||||
"pageTitle": "خيارات التكوين",
|
||||
"logLevel": "مستوى السجل",
|
||||
"blockAds": "منع الإعلانات",
|
||||
"resolveDestination": "حل الوجهة",
|
||||
"ipv6Mode": "توجيه IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "تعطيل",
|
||||
"enable": "تمكين",
|
||||
"prefer": "مُفضل",
|
||||
"only": "حصري"
|
||||
},
|
||||
"remoteDnsAddress": "DNS البعيد",
|
||||
"remoteDnsDomainStrategy": "استراتيجية مجال DNS البعيد",
|
||||
"directDnsAddress": "DNS المباشر",
|
||||
"directDnsDomainStrategy": "استراتيجية مجال DNS المباشر",
|
||||
"mixedPort": "منفذ مُختلط",
|
||||
"tproxyPort": "منفذ الوكيل الشفاف",
|
||||
"localDnsPort": "منفذ DNS المحلي",
|
||||
"allowConnectionFromLan": "مشاركة VPN على الشبكة المحلية",
|
||||
"tunImplementation": "تنفيذ TUN",
|
||||
"mtu": "حجم الحزمة (MTU)",
|
||||
"connectionTestUrl": "عنوان URL لاختبار الاتصال",
|
||||
"urlTestInterval": "مُدة اختبار عنوان URL",
|
||||
"enableClashApi": "تمكين Clash API",
|
||||
"clashApiPort": "منفذ Clash API",
|
||||
"enableTun": "تمكين TUN",
|
||||
"setSystemProxy": "تعيين وكيل النظام",
|
||||
"enableDnsRouting": "تمكين توجيه DNS",
|
||||
"enableFakeDns": "تمكين DNS المزيف",
|
||||
"bypassLan": "تجاوز LAN",
|
||||
"strictRoute": "توجيه صارم",
|
||||
"enableTlsFragment": "تمكين تجزئة TLS",
|
||||
"tlsFragmentSize": "حجم تجزئة TLS",
|
||||
"tlsFragmentSleep": "وقت تعليق تجزئة TLS",
|
||||
"enableTlsMixedSniCase": "تمكين خلط حالات SNI في TLS",
|
||||
"enableTlsPadding": "تمكين حشو TLS",
|
||||
"tlsPaddingSize": "حشو TLS",
|
||||
"enableMux": "تمكين Mux",
|
||||
"muxProtocol": "بروتوكول Mux",
|
||||
"muxMaxStreams": "أقصى عدد من التدفقات المتزامنة",
|
||||
"enableWarp": "تمكين WARP",
|
||||
"warpDetourMode": "وضع التفاف",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "لف الخوادم الوكيلية عبر WARP",
|
||||
"warpOverProxy": "لف WARP عبر الخوادم الوكيلية",
|
||||
"inbound": "لف WARP عبر الخوادم الوكيلية",
|
||||
"outbound": "لف الخوادم الوكيلية عبر WARP"
|
||||
},
|
||||
"warpLicenseKey": "مفتاح الترخيص",
|
||||
"warpCleanIp": "عنوان IP نظيف",
|
||||
"warpPort": "المنفذ",
|
||||
"warpNoise": "عدد الضوضاء",
|
||||
"warpNoiseSize": "حجم الضوضاء",
|
||||
"warpNoiseMode": "وضع الضوضاء",
|
||||
"warpNoiseDelay": "تأخير الضوضاء"
|
||||
}
|
||||
}
|
||||
@@ -1,420 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "هیدیفای",
|
||||
"reset": "ڕێکخستنەوە",
|
||||
"toggle": {
|
||||
"enabled": "چالاک",
|
||||
"disabled": "بێتوانا"
|
||||
},
|
||||
"state": {
|
||||
"disable": "بێتوانا"
|
||||
},
|
||||
"sort": "ڕیزکردن",
|
||||
"sortBy": "ڕیزکردن بەپێی",
|
||||
"addToClipboard": "زیادکردن بۆ کلیپبۆرد",
|
||||
"notSet": "دانەنراوە",
|
||||
"agree": "ڕازی بوون",
|
||||
"decline": " پەسەند نەکردن",
|
||||
"unknown": "نەناسراو",
|
||||
"hidden": "پهنهان",
|
||||
"timeout": "کات تەواوبوو",
|
||||
"clipboardExportSuccessMsg": "زیاد کرا بۆ کلیپبۆرد",
|
||||
"showMore": "زیاتر پێشان بدە",
|
||||
"showLess": "کەمتر پێشان بدە",
|
||||
"openAppSettings": "کردنەوەی ڕێکخستنەکانی ئەپەکە",
|
||||
"grantPermission": "مۆڵەتدان"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "بە بەردەوام بوون تۆ ڕازیت لەگەڵ ${tap(@:about.termsAndConditions)}",
|
||||
"start": "دەستپێک"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "سەرەتا",
|
||||
"emptyProfilesMsg": "سەرەتا بە زیادکردنی پرۆفایلی ئابوونە دەست پێ بکە",
|
||||
"noActiveProfileMsg": "پرۆفایلێک هەڵبژێرە"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "هاتوچۆی داتا",
|
||||
"trafficLive": "هاتوچۆی ڕاستەوخۆ",
|
||||
"trafficTotal": "کۆی گشتی هاتوچۆ",
|
||||
"uplink": "باركردن",
|
||||
"downlink": "داگرتن",
|
||||
"connection": "پهیوهندی",
|
||||
"speed": "خێرایی",
|
||||
"totalTransferred": "کۆی گشتی گواستراو"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "پرۆفایلەکان",
|
||||
"detailsPageTitle": "پرۆفایل",
|
||||
"activeProfileNameSemanticLabel": "ناوی پڕۆفایلی چالاک: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "بینینی هەموو پڕۆفایلیەکان",
|
||||
"nonActiveProfileBtnSemanticLabel": "\"${name}\" وەکو پرۆفایلی چالاک هەڵبژێرە",
|
||||
"subscription": {
|
||||
"traffic": "هاتوچۆ",
|
||||
"updatedTimeAgo": "نوێکرایەوە ${timeago}",
|
||||
"remainingDuration": "${duration} ڕۆژانی ماوەتەوە",
|
||||
"remainingTrafficSemanticLabel": "${consumed} لە ${total} هاتوچۆی بەکارهێنراو",
|
||||
"expired": "بەسەرچوو",
|
||||
"noTraffic": "کۆتایی بەش",
|
||||
"upload": "بارکردن",
|
||||
"download": "داگرتن",
|
||||
"total": "کۆی گشتی هاتوچۆ",
|
||||
"expireDate": "ڕۆژى بەسەرچوون"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "بەم دواییە نوێکراوەتەوە",
|
||||
"name": "بە پێی ئەلفوبێ"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "زیادکردنی پڕۆفایلی نوێ",
|
||||
"shortBtnTxt": "پڕۆفایلی نوێ",
|
||||
"fromClipboard": "زیادکردن لە کلیپبۆردەوە",
|
||||
"scanQr": "سکانکردنی QR Code",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "ڕێگا نەدرا",
|
||||
"unexpectedError": "هەڵەیەک رووی داوە",
|
||||
"torchSemanticLabel": "فلاش لایت",
|
||||
"facingSemanticLabel": "ڕووی کامێرا",
|
||||
"permissionRequest": "ڕێگەدان بە کامێرا بۆ سکانکردنی QR Code"
|
||||
},
|
||||
"manually": "نووسینی دەستی",
|
||||
"addWarp": "WARP زیاد بکە",
|
||||
"addingWarpMsg": "تکایە چاوەڕێ بن تا ئێمە تۆماری WARP دەکەین.",
|
||||
"addingProfileMsg": "خەریکی زیادکردنی پرۆفایل",
|
||||
"failureMsg": "زیادکردنی پڕۆفایل شکستی هێنا"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "بەڕۆژکردنەوە",
|
||||
"tooltip": "بەڕۆژکردنەوەی پرۆفایل",
|
||||
"updateSubscriptions": "بەڕۆژکردنەوەی ئابوونەکان",
|
||||
"failureMsg": "بەڕۆژکردنەوەی پرۆفایل شکستی هێنا ",
|
||||
"successMsg": "بەڕۆژکردنەوەی پرۆفایل بە سەرکەوتوویی",
|
||||
"namedFailureMsg": "شکستی هێنا لە بەڕۆژکردنەوەی \"${name}\"",
|
||||
"namedSuccessMsg": "\"${name}\" بە سەرکەوتوویی بەڕۆژکرایەوە"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "هاوبەش کردن",
|
||||
"exportToClipboardSuccess": "هەناردە کراوە بۆ کلیپبۆرد",
|
||||
"exportSubLinkToClipboard": "هەناردەکردنی بەستەری بەشداربوون بۆ کلیپبۆرد",
|
||||
"subLinkQrCode": "بەستەری بەشداریکردن QR Code",
|
||||
"exportConfigToClipboard": "ڕێکخستن هەناردە بکە بۆ کلیپبۆرد",
|
||||
"exportConfigToClipboardSuccess": "ڕێکخستن کۆپی کرا بۆ کلیپبۆرد"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "دهستكاری",
|
||||
"selectActiveTxt": "هەڵبژاردنی پرۆفایلی چالاک"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "سڕینەوە",
|
||||
"confirmationMsg": "سڕینەوەی پڕۆفایل بۆ هەمیشە؟",
|
||||
"successMsg": "پڕۆفایلی بە سەرکەوتوویی سڕاوەتەوە"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "پاشەکەوت",
|
||||
"successMsg": "پڕۆفایل بە سەرکەوتوویی پاشەکەوت کراوە",
|
||||
"failureMsg": "پاشەکەوتکردنی پڕۆفایل شکستی هێنا"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "ناو",
|
||||
"nameHint": "ناوی پرۆفایل",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "URLی تەواوی ڕێکخستن",
|
||||
"emptyNameMsg": "ناو پێویستە",
|
||||
"invalidUrlMsg": "URLێکی نادروست",
|
||||
"lastUpdate": "دوایین بەڕۆژبوون",
|
||||
"updateInterval": "بەڕۆژکردنی خۆکار",
|
||||
"updateIntervalDialogTitle": "ماوەی بەڕۆژکردنی خۆکار (کاتژمێر)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "پرۆکسیەکان",
|
||||
"emptyProxiesMsg": "هیچ پرۆکسییەک بەردەست نییە",
|
||||
"delayTestTooltip": "تاقیکردنەوەی دواکەوتن",
|
||||
"sortTooltip": "ڕیزکردنی پرۆکسیەکان",
|
||||
"checkIp": "IP پشکنینی",
|
||||
"unknownIp": "ئایپی نەناسراو",
|
||||
"sortOptions": {
|
||||
"unsorted": "بنەڕەتی",
|
||||
"name": "بە پێی ئەلفوبێ",
|
||||
"delay": "بە پێی دواکەوتن"
|
||||
},
|
||||
"activeProxySemanticLabel": "پرۆکسی چالاک",
|
||||
"delaySemantics": {
|
||||
"result": "دواکەوتن: ${delay}ms",
|
||||
"timeout": "وادەی تاقیکردنەوەی دواکەوتن بەسەرچوو",
|
||||
"testing": "دواکەوتن: خەریکی تاقیکردنەوە..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "ناونیشانی IP",
|
||||
"country": "وڵات"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "گوزارشەکان",
|
||||
"filterHint": "پاڵێو",
|
||||
"allLevelsFilter": "هەموو",
|
||||
"shareCoreLogs": "هاوبەشکردن گوزارشەکانی ناوک",
|
||||
"shareAppLogs": "هاوبەشکردن گوزارشەکانی ئەپەکە",
|
||||
"pauseTooltip": "وهستان",
|
||||
"resumeTooltip": "بهردهوامبوونهوه",
|
||||
"clearTooltip": "سڕینەوە"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "ڕێکخستنهکان",
|
||||
"requiresRestartMsg": "ئەپەکە رستارت بکە بۆ ئەوەی ئەمە کاریگەری هەبێت",
|
||||
"experimental": "ئەزموونی",
|
||||
"experimentalMsg": "تایبەتمەندییەکان لەگەڵ ئاڵای ئەزموونی هێشتا لە پەرەپێداندان و لەوانەیە کێشە دروست بکەن.",
|
||||
"exportOptions": "هەناردەکردنی هەڵبژاردەکان بۆ کلیپبۆرد",
|
||||
"exportAllOptions": "هەناردەکردنی ڕێکخستنەکان بۆ کلیپبۆرد (debug)",
|
||||
"importOptions": "هاوردەکردنی ڕێکخستنەکان لە کلیپبۆردەوە",
|
||||
"importOptionsMsg": "ئەمە هەموو هەڵبژاردەکانی ڕێکخستن بە بەهاکانی دابینکراو دەنووسێتەوە. ئایا دڵنیایت؟",
|
||||
"general": {
|
||||
"sectionTitle": "گشتی",
|
||||
"locale": "زمان",
|
||||
"region": "ناوچە",
|
||||
"regionMsg": "یارمەتی دانانی هەڵبژاردەکانی پێشوەختە دەدات بۆ تێپەڕاندنی ناونیشانە ناوخۆییەکان",
|
||||
"regions": {
|
||||
"ir": "ئێران(ir)",
|
||||
"cn": "چین (cn)",
|
||||
"ru": "ڕووسیا (ru)",
|
||||
"af": "ئەفغانستان (af)",
|
||||
"id": "إندونيسيا (id)",
|
||||
"tr": "Tirkiye",
|
||||
"other": "ئی تر"
|
||||
},
|
||||
"themeMode": "دۆخی تێم",
|
||||
"themeModes": {
|
||||
"system": "خۆگونجاندن لەگەڵ تێمی سیستەم",
|
||||
"dark": "تاریک",
|
||||
"light": "ڕووناک",
|
||||
"black": "ڕەش"
|
||||
},
|
||||
"enableAnalytics": "چالاک کردنی شیکاری",
|
||||
"enableAnalyticsMsg": "مۆڵەت بدە بە کۆکردنەوەی شیکاری و ناردنی ڕاپۆرتی تێکچوون بۆ باشترکردنی ئەپەکە",
|
||||
"autoStart": "دەستپێکردن لە کاتی دەستپێکردنی سیستەم",
|
||||
"silentStart": "دەستپێکردن بە شێوەی بچووک",
|
||||
"openWorkingDir": "کردنەوەی پێڕستی چالاک",
|
||||
"ignoreBatteryOptimizations": "لەکارخستنی باشکردنی پاتری",
|
||||
"ignoreBatteryOptimizationsMsg": "لابردنی سنوورەکان بۆ باشترین ئاستی VPN ی گونجاو",
|
||||
"dynamicNotification": "پیشاندانی خێرایی لە باری ئاگادارکردنەوەدا",
|
||||
"hapticFeedback": "پاشخورد بە دەست لێدان",
|
||||
"autoIpCheck": "پشکنینی ئۆتۆماتیکی ip پەیوەندی "
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "پێشکەوتوو",
|
||||
"debugMode": "دۆخی ههڵهدۆزین",
|
||||
"debugModeMsg": "بۆ جێبەجێکردنی ئەم گۆڕانکارییە ئەپەکە دووبارە دابمەزرێنەرەوە",
|
||||
"memoryLimit": "سنووری بیرگه",
|
||||
"memoryLimitMsg": "ئەگەر تووشی هەڵەی دەرەوەی بیرگە یان زۆرجار تێکچوونی ئەپەکە بوویت چالاکی بکە",
|
||||
"resetTunnel": "ڕێستکردنی پڕۆفایلی VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "پرۆکسی بۆ هەر ئەپێک",
|
||||
"perAppProxyModes": {
|
||||
"off": "گشت",
|
||||
"offMsg": "پرۆکسی لەسەر هەموو ئەپەکان",
|
||||
"include": "پرۆکسی",
|
||||
"includeMsg": "تەنها ئەو ئەپانەی هەڵبژێردراون بە پرۆکسی بکرێت",
|
||||
"exclude": "لاتێپهڕی",
|
||||
"excludeMsg": "بەرنامە هەڵبژێردراوەکان بە پرۆکسی مەکە"
|
||||
},
|
||||
"showSystemApps": "نیشاندانی ئەپەکانی سیستەم",
|
||||
"hideSystemApps": "شاردنەوەی بەرنامەکانی سیستەم",
|
||||
"clearSelection": "سڕینەوەی هەڵبژاردنەکان"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "پەڕگەکانی ڕێڕەو",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "GeoSite",
|
||||
"version": "وەشان ${version}",
|
||||
"fileMissing": "پەڕگە بوونی نییە",
|
||||
"update": "بەڕۆژکردن",
|
||||
"download": "داگرتن",
|
||||
"failureMsg": "شکستی هێنا لە نوێکردنەوەی پەڕگە",
|
||||
"successMsg": "پەڕگەکە بە سەرکەوتوویی نوێکرایەوە",
|
||||
"addRecommended": "زیادکردنی فایلەکانی پێشنیار کراو",
|
||||
"missingGeoAssetsMsg": "فایلەکانی ڕێڕەوی هەڵبژێردراو بوونیان نییە. یان دایانبگرە یان یەکێک لەوانە هەڵبژێرە کە بەردەستە"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "سەبارەت",
|
||||
"version": "وەشان",
|
||||
"sourceCode": "سهرچاوه کۆد",
|
||||
"telegramChannel": "کەناڵی تێلێگرام",
|
||||
"checkForUpdate": "پشکنین بۆ نوێکاریی و بەڕۆژبوون",
|
||||
"privacyPolicy": "سیاسەتی پاراستنی نهێنی",
|
||||
"termsAndConditions": "مەرج و ڕێسای بەکارهێنان"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "نوێترین وەشانی هیدیفای بەکاردەهێنیت",
|
||||
"dialogTitle": "نوێکاری بەردەستە",
|
||||
"updateMsg": "وەشانی نوێی @:general.appTitle بەردەستە. دەتەوێت بەڕۆژی بکەیتەوە؟",
|
||||
"currentVersionLbl": "وەشانی ئێستا",
|
||||
"newVersionLbl": "وەشانى نوێ",
|
||||
"updateNowBtnTxt": "ئیستا بەڕۆژی کەرەوە",
|
||||
"laterBtnTxt": "دواتر",
|
||||
"ignoreBtnTxt": "پشتگوێخستن"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "داشبۆرد",
|
||||
"quit": "داخستن",
|
||||
"open": "کردنەوە",
|
||||
"status": {
|
||||
"connect": "بەستنەوە",
|
||||
"connecting": "پەیوەندیکردن",
|
||||
"disconnect": "پچڕانی پەیوەندی",
|
||||
"disconnecting": "پچڕانی پەیوەندی..."
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "هەڵەیەکی چاوەڕواننەکراو",
|
||||
"clash": {
|
||||
"unexpected": "هەڵەیەکی چاوەڕواننەکراو",
|
||||
"core": "هەڵەی Clash ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "هەڵەیەکی چاوەڕواننەکراو لە خزمەتگوزاریدا",
|
||||
"serviceNotRunning": "خزمەتگوزارییەکە کارناکات",
|
||||
"missingPrivilege": "پێویستی دەستڕاگەیشتن",
|
||||
"missingPrivilegeMsg": "دۆخی VPN پێویستی بە دەستگەیشتن بە بەڕێوەبەر هەیە. یان ئەپەکە وەک ئەدمین دووبارە دابمەزرێنەرەوە یان دۆخی خزمەتگوزاری بگۆڕە.",
|
||||
"missingGeoAssets": "هیچ فایلێکی جوگرافی(Geo) نییە",
|
||||
"missingGeoAssetsMsg": "هیچ پەڕگەیێکی جوگرافی نییە. یان پەڕگە چالاکەکە بگۆڕە یان پەڕگە هەڵبژێردراوەکان دابەگرە.",
|
||||
"invalidConfigOptions": "ڕێکخستنەکانی ڕێکخستنی نادروست",
|
||||
"invalidConfig": "ڕێکخستنی نادروست",
|
||||
"create": "هەڵەی دروستکردنی خزمەتگوزاری",
|
||||
"start": "هەڵەی دەستپێکردنی خزمەتگوزاری"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "شکستی چاوەڕواننەکراو",
|
||||
"missingVpnPermission": "مۆڵەت و دەستڕاگەیشتن VPN نییە",
|
||||
"missingNotificationPermission": "هیچ دەستڕاگەیشتنێکی ئاگادارکردنەوە نییە",
|
||||
"core": "هەڵەی ناوک"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "هەڵەی چاوەڕواننەکراو",
|
||||
"notFound": "پڕۆفایلی نەدۆزرایەوە",
|
||||
"invalidConfig": "ڕێکخستنە نادروستەکان",
|
||||
"invalidUrl": "URL ی نادروست"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "هەڵەی پەیوەندی چاوەڕواننەکراو",
|
||||
"timeout": "کاتبەسەرچوونی پەیوەندی",
|
||||
"badResponse": "وەڵامی خراپ",
|
||||
"connectionError": "هەڵەی پەیوەندی",
|
||||
"badCertificate": "بڕوانامەی خراپ"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "هەڵەی چاوەڕواننەکراو",
|
||||
"notUpdate": "هیچ نوێکارییەک بەردەست نییە",
|
||||
"activeNotFound": "پەڕگەی جوگرافی چالاک نەدۆزرایەوە"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "هیدیفای (ئەزموونی)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "ئامانجی سەرەکی Hidify دابینکردنی کرێدەرێکی دژە فلتەری پارێزراو و بەکارهێنەر دۆستانە و کارامەیە. ئەمە ڕێگەت پێدەدات هەموو ترافیکی یان ترافیکی بەرنامە هەڵبژێردراوەکان ئاڕاستە بکەیتەوە بۆ سێرڤەرێکی دوور بە دڵی خۆت بە بەکارهێنانی مۆڵەتی خزمەتگوزاری VPN.\nتێبینی: ئێمە هیچ سێرڤەرێک دابین ناکەین. بەکارهێنەران پێویستە چالاکییە ئۆنلاینەکانیان بە تایبەتی بهێڵنەوە بە بەکارهێنانی سێرڤەر، هۆست یان سێرڤەرە متمانەپێکراوەکانی خۆیان.\n\nئێمە پشتگیری ئەم سێرڤەرانە دەکەین:- بەستەری ئابوونەی ئاسایی V2Ray/XRay- لینکی ئابوونەی کلاش- لینکی ئابوونەی Sing-Box\n\nتایبەتمەندییە ناوازەکانی ئەم بەرنامەیە چین؟- بەکارهێنەر دۆست- گونجاو و خێرا- هەڵبژاردنی نزمترین ping بە شێوەیەکی ئۆتۆماتیکی- پیشاندانی زانیاری بەکارهێنانی بەکارهێنەر- بە ئاسانی sublink بە یەک کلیک بە بەکارهێنانی deeplink دابنێ- بەخۆڕایی و بێ ڕیکلام- بە ئاسانی ژێربەستەرەکانی بەکارهێنەر بگۆڕێت- زیاتر و زیاتر\n\nپشتیوانی:- All Protocols Supported by Sing-Box \n- VLESS + XTLS Reality, Vision\n- VMess\n- Trojan\n- ShadowSocks\n- Reality\n- WireGuard\n- V2Ray\n- Hysteria2\n- TUICv5\n- SSH\n- ShadowTLS\nکۆدی سەرچاوە لە https://github.com/hiddify/Hiddify-Next بەردەستە و ناوەکی بەرنامەکە لەسەر بنەمای سەرچاوە کراوەی Sing-Box دامەزراوە.\n\nوەسفکردنی ڕێپێدان:- خزمەتگوزاری VPN: بەو پێیەی مەبەست لەم بەرنامەیە دابینکردنی کرێدەرێکی دژە فلتەری پارێزراو و بەکارهێنەر دۆستانە و کارامەیە، پێویستمان بەم مۆڵەتە هەیە بۆ ئەوەی ترافیک لە ڕێگەی تونێلەکەوە بۆ سێرڤەری دوور بگوازرێتەوە.- پرسیار لە هەموو پاکێجەکان بکە: ئەم مۆڵەتە بەکاردێت بۆ ئەوەی ڕێگە بە بەکارهێنەران بدرێت بەرنامە تایبەتەکان بۆ تونێلکردن بخەنە ناوەوە یان دەریانبهێنن.- RECEIVE BOOT COMPLETED: ئەم مۆڵەتە دەتوانرێت لە ڕێکخستنەکانی بەرنامەکەوە چالاک یان ناچالاک بکرێت بۆ ئەوەی ئەم بەرنامەیە دوای دەستپێکردنی ئامێرەکە چالاک بێت.- ئاگادارکردنەوەکانی دوای: ئەم مۆڵەتە پێویستە چونکە پێویستە خزمەتگوزاری پاشبنەما بەکاربهێنین بۆ دڵنیابوون لە کارکردنی دروستی VPN.- ئەم ئەپە بێ ڕیکلامە. شیکاری و داتاکانی کەوتنەخوارەوە تەنها بە ڕەزامەندی دەربڕینی بەکارهێنەر لە کاتی یەکەم بەکارهێنانی بەرنامەکەدا ڕوودەدات."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "بۆ پەیوەندیکردن بکوتە",
|
||||
"connecting": "پەیوەندیکردن",
|
||||
"disconnecting": "پچڕانی پەیوەندی...",
|
||||
"connected": "بەستراوەتەوە",
|
||||
"reconnect": "پەیوەندی کردنەوەی دووبارە",
|
||||
"connectAnyWay": "گرێدان",
|
||||
"experimentalNotice": "تایبەتمەندییە تاقیکارییەکانی بەکارهێنراو",
|
||||
"experimentalNoticeMsg": "تۆ هەندێک تایبەتمەندی تاقیکاریت چالاک کردووە کە لەوانەیە کاریگەری لەسەر کوالیتی پەیوەندی هەبێت و ببێتە هۆی هەڵەی چاوەڕواننەکراو. هەمیشە دەتوانیت ئەم هەڵبژاردنانە لە لاپەڕەی هەڵبژاردنەکانی ڕێکخستنەوە بگۆڕیت یان ڕێست بکەیتەوە.",
|
||||
"disableExperimentalNotice": "جارێکی تر نیشان مەدە، وەڕەز بووووووم",
|
||||
"reconnectMsg": "دووبارە پەیوەندی بکەرەوە بۆ ئەوەی گۆڕانکارییەکان کاریگەرییان هەبێت"
|
||||
},
|
||||
"config": {
|
||||
"resetBtn": "ڕێکخستنەکان ڕێکبخەرەوە",
|
||||
"serviceMode": "دۆخی خزمەتگوزاری",
|
||||
"quickSettings": "ڕێکخستنەکانی خێرا",
|
||||
"setupWarp": "ڕێکخستنی WARP",
|
||||
"allOptions": "سەرجەم ڕێکخستنەکانی ڕێکخستن",
|
||||
"serviceModes": {
|
||||
"proxy": "تەنها خزمەتگوزاری پرۆکسی",
|
||||
"systemProxy": "ڕێکخستنی پرۆکسی سیستەم",
|
||||
"tun": "VPN",
|
||||
"tunService": "خزمەتگوزاری VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "پرۆکسی",
|
||||
"systemProxy": "پرۆکسی سیستەم",
|
||||
"tun": "VPN",
|
||||
"tunService": "خزمەتگوزاری VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "ڕێکخستنەکانی ڕێڕەودانان",
|
||||
"dns": "ڕێکخستنەکانی DNS",
|
||||
"inbound": "ڕێکخستنەکانی Inbound",
|
||||
"mux": "مالتیپلێکسێر",
|
||||
"outbound": "ڕێکخستنەکانی دەرچوون",
|
||||
"tlsTricks": "فێڵەکانی TLS",
|
||||
"warp": "ڕێکخستنەکانی WARP",
|
||||
"misc": "ڕێکخستنەکانی جۆراوجۆر"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "ڕێککەوتنی WARP ی Cloudflare",
|
||||
"description(rich)": "Cloudflare WARP دابینکەرێکی VPN ی بێبەرامبەری WireGuard ە. بە چالاککردنی ئەم بژاردە، تۆ ڕەزامەندیت لەسەر ${tos(مەرجەکانی خزمەتگوزاری)} و ${privacy(سیاسەتی نهێنی)} ی Cloudflare WARP."
|
||||
},
|
||||
"generateWarpConfig": "دروستکردنی ڕێکخستنی WARP",
|
||||
"missingWarpConfig": "ڕێکخستنی WARP بەردەست نییە",
|
||||
"warpConfigGenerated": "ڕێکخستنی WARP دروست کراوە",
|
||||
"pageTitle": "ڕێکخستنەکان",
|
||||
"logLevel": "ئاستی گوزارش",
|
||||
"blockAds": "Advertisements Asteng bike",
|
||||
"resolveDestination": "لکاندنی شوێنی مەبەست",
|
||||
"ipv6Mode": "ڕێڕەوکردنی IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "ناچالاک",
|
||||
"enable": "چالاک",
|
||||
"prefer": "پەسەندترە",
|
||||
"only": "تایبەت"
|
||||
},
|
||||
"remoteDnsAddress": "DNS دەرەکی",
|
||||
"remoteDnsDomainStrategy": "ستراتیژی دۆمەینی DNS لە دوورەوە",
|
||||
"directDnsAddress": "DNS ی ڕاستەوخۆ",
|
||||
"directDnsDomainStrategy": "ستراتیژی ڕاستەوخۆی دۆمەینی DNS",
|
||||
"mixedPort": "پۆرتی تێکەڵاو",
|
||||
"tproxyPort": "پۆرتی پرۆکسی نەبینراو",
|
||||
"localDnsPort": "پۆرتی DNS ناوخۆیی",
|
||||
"allowConnectionFromLan": "هاوبەشکردنی VPN لەسەر تۆڕی ناوخۆیی",
|
||||
"tunImplementation": "جێبەجێکردنی TUN",
|
||||
"mtu": "قەبارەی پاکەت (MTU)",
|
||||
"connectionTestUrl": "URLی تاقیکردنەوەی پەیوەندی",
|
||||
"urlTestInterval": "ماوەی پشکنینی بەستەر",
|
||||
"enableClashApi": "چالاک کردنی Clash API",
|
||||
"clashApiPort": "پۆرتی Clash API",
|
||||
"enableTun": "TUN چالاککردن",
|
||||
"setSystemProxy": "ڕێکخستنی پرۆکسی سیستەم",
|
||||
"enableDnsRouting": "ڕێڕەوی DNS چالاک کردنی",
|
||||
"enableFakeDns": "چالاککردنی DNS ساختە",
|
||||
"bypassLan": "دەرباز کردنی LAN",
|
||||
"strictRoute": "ڕێگای ورد",
|
||||
"enableTlsFragment": "TLS Fragment چالاک کردنی",
|
||||
"tlsFragmentSize": "قەبارەی TLS Fragment ",
|
||||
"tlsFragmentSleep": "لابردنی TLS Fragment",
|
||||
"enableTlsMixedSniCase": "چالاک کردنی TLS Mixed SNI Case",
|
||||
"enableTlsPadding": "چالاک کردنی TLS Padding",
|
||||
"tlsPaddingSize": "قەبارەی TLS Padding",
|
||||
"enableMux": "چالاک کردنی Mux",
|
||||
"muxProtocol": "پرۆتۆکۆڵی Mux",
|
||||
"muxMaxStreams": "زۆرترین ڕەوتی هاوکات",
|
||||
"enableWarp": "چالاک کردنی WARP",
|
||||
"warpDetourMode": "دۆخی وارپ",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "تێپەڕاندنی پرۆکسیەکان لە ڕێگەی WARP",
|
||||
"warpOverProxy": "تێپەڕاندنی WARP لە ڕێگەی پرۆکسیەوە",
|
||||
"inbound": "تێپەڕاندنی WARP لە ڕێگەی پرۆکسیەوە",
|
||||
"outbound": "تێپەڕاندنی پرۆکسیەکان لە ڕێگەی WARP"
|
||||
},
|
||||
"warpLicenseKey": "کلیلی مۆڵەت",
|
||||
"warpCleanIp": "IP خاوێن",
|
||||
"warpPort": "پۆرت",
|
||||
"warpNoise": "ژمارەی ژاوەژاو",
|
||||
"warpNoiseSize": "Deng Siza",
|
||||
"warpNoiseMode": "Moda Deng",
|
||||
"warpNoiseDelay": "دواکەوتنی ژاوەژاو"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Reset",
|
||||
"toggle": {
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Disable"
|
||||
},
|
||||
"sort": "Sort",
|
||||
"sortBy": "Sort by",
|
||||
"addToClipboard": "Add To Clipboard",
|
||||
"notSet": "Not Set",
|
||||
"agree": "Agree",
|
||||
"decline": "Decline",
|
||||
"unknown": "Unknown",
|
||||
"hidden": "Hidden",
|
||||
"timeout": "Timeout",
|
||||
"clipboardExportSuccessMsg": "Added To Clipboard",
|
||||
"showMore": "Show More",
|
||||
"showLess": "Show Less",
|
||||
"openAppSettings": "Open App Settings",
|
||||
"grantPermission": "Grant Permission"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "By Continuing You Agree With ${tap(@:about.termsAndConditions)}",
|
||||
"start": "Start"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Home",
|
||||
"emptyProfilesMsg": "Begin by Adding a Subscription Profile",
|
||||
"noActiveProfileMsg": "Choose a Profile"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Traffic",
|
||||
"trafficLive": "Live Traffic",
|
||||
"trafficTotal": "Total Traffic",
|
||||
"uplink": "Uplink",
|
||||
"downlink": "Downlink",
|
||||
"connection": "Connection",
|
||||
"speed": "Speed",
|
||||
"totalTransferred": "Total Transferred"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Profiles",
|
||||
"detailsPageTitle": "Profile",
|
||||
"activeProfileNameSemanticLabel": "Active Profile Name: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "View All Profiles",
|
||||
"nonActiveProfileBtnSemanticLabel": "Select \"${name}\" as Active Profile",
|
||||
"subscription": {
|
||||
"traffic": "Traffic",
|
||||
"updatedTimeAgo": "Updated ${timeago}",
|
||||
"remainingDuration": "${duration} Days Remaining",
|
||||
"remainingTrafficSemanticLabel": "${consumed} of ${total} Traffic Consumed",
|
||||
"expired": "Expired",
|
||||
"noTraffic": "Out of Quota",
|
||||
"upload": "Upload",
|
||||
"download": "Download",
|
||||
"total": "Total Traffic",
|
||||
"expireDate": "Expire Date"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "Recently Updated",
|
||||
"name": "Alphabetically"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "New Profile",
|
||||
"shortBtnTxt": "New Profile",
|
||||
"fromClipboard": "Add From Clipboard",
|
||||
"scanQr": "Scan QR Code",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "Permission Denied",
|
||||
"unexpectedError": "Something Went Wrong",
|
||||
"torchSemanticLabel": "Flash Light",
|
||||
"facingSemanticLabel": "Camera Facing",
|
||||
"permissionRequest": "Permission to camera to scan QR Code"
|
||||
},
|
||||
"manually": "Manual Entry",
|
||||
"addWarp": "Add WARP",
|
||||
"addingWarpMsg": "Please wait while we register WARP.",
|
||||
"addingProfileMsg": "Adding Profile",
|
||||
"failureMsg": "Failed to Add Profile"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Update",
|
||||
"tooltip": "Update Profile",
|
||||
"updateSubscriptions": "Update Subscriptions",
|
||||
"failureMsg": "Failed to Update Profile",
|
||||
"successMsg": "Profile Updated Successfully",
|
||||
"namedFailureMsg": "Failed to Update \"${name}\"",
|
||||
"namedSuccessMsg": "\"${name}\" Updated Successfully"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Share",
|
||||
"exportToClipboardSuccess": "Exported to Clipboard",
|
||||
"exportSubLinkToClipboard": "Export Subscription Link to Clipboard",
|
||||
"subLinkQrCode": "Subscription Link QR Code",
|
||||
"exportConfigToClipboard": "Export Configuration to Clipboard",
|
||||
"exportConfigToClipboardSuccess": "Configuration Copied to Clipboard"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Edit",
|
||||
"selectActiveTxt": "Select Active Profile"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Delete",
|
||||
"confirmationMsg": "Delete Profile Permanently?",
|
||||
"successMsg": "Profile Deleted Successfully"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Save",
|
||||
"successMsg": "Profile Saved Successfully",
|
||||
"failureMsg": "Failed to Save Profile"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "Name",
|
||||
"nameHint": "Profile Name",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "Full Config URL",
|
||||
"emptyNameMsg": "Name Is Required",
|
||||
"invalidUrlMsg": "Invalid URL",
|
||||
"lastUpdate": "Last Update",
|
||||
"updateInterval": "Auto Update",
|
||||
"updateIntervalDialogTitle": "Auto Update Interval (in Hours)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Proxies",
|
||||
"emptyProxiesMsg": "No Proxies Available",
|
||||
"delayTestTooltip": "Test Delay",
|
||||
"sortTooltip": "Sort Proxies",
|
||||
"checkIp": "Check IP",
|
||||
"unknownIp": "Unknown IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "Default",
|
||||
"name": "Alphabetically",
|
||||
"delay": "By Delay"
|
||||
},
|
||||
"activeProxySemanticLabel": "Active Proxy",
|
||||
"delaySemantics": {
|
||||
"result": "Delay: ${delay}ms",
|
||||
"timeout": "Delay Test Timeout",
|
||||
"testing": "Delay: Testing..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "IP Address",
|
||||
"country": "Country"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Logs",
|
||||
"filterHint": "Filter",
|
||||
"allLevelsFilter": "All",
|
||||
"shareCoreLogs": "Share Core Logs",
|
||||
"shareAppLogs": "Share App Logs",
|
||||
"pauseTooltip": "Pause",
|
||||
"resumeTooltip": "Resume",
|
||||
"clearTooltip": "Clear"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Settings",
|
||||
"requiresRestartMsg": "For this to take effect restart the app",
|
||||
"experimental": "Experimental",
|
||||
"experimentalMsg": "Features with Experimental flag are still in development and might cause issues.",
|
||||
"exportOptions": "Copy Anonymous Options to Clipboard",
|
||||
"exportAllOptions": "Copy All Options to Clipboard",
|
||||
"importOptions": "Import Options From Clipboard",
|
||||
"importOptionsMsg": "This will rewrite all config options with provided values. Are you sure?",
|
||||
"general": {
|
||||
"sectionTitle": "General",
|
||||
"locale": "Language",
|
||||
"region": "Region",
|
||||
"regionMsg": "Helps set default options to bypass domestic addresses",
|
||||
"regions": {
|
||||
"ir": "Iran (ir) 🇮🇷",
|
||||
"cn": "China (cn) 🇨🇳",
|
||||
"ru": "Russia (ru) 🇷🇺",
|
||||
"af": "Afghanistan (af) 🇦🇫",
|
||||
"id": "Indonesia (id) 🇮🇩",
|
||||
"tr": "Türkiye (tr) 🇹🇷",
|
||||
"br": "Brazil (br) 🇧🇷",
|
||||
"other": "Other"
|
||||
},
|
||||
"themeMode": "Theme Mode",
|
||||
"themeModes": {
|
||||
"system": "Follow System Theme",
|
||||
"dark": "Dark Mode",
|
||||
"light": "Light Mode",
|
||||
"black": "Black Mode"
|
||||
},
|
||||
"enableAnalytics": "Enable Analytics",
|
||||
"enableAnalyticsMsg": "Give permission to collect analytics and send crash reports to improve the app",
|
||||
"autoStart": "Start At Login",
|
||||
"silentStart": "Start Minimized",
|
||||
"openWorkingDir": "Open Working Directory",
|
||||
"ignoreBatteryOptimizations": "Disable Battery Optimization",
|
||||
"ignoreBatteryOptimizationsMsg": "Remove Restrictions For Optimal VPN Performance",
|
||||
"dynamicNotification": "Display Speed in Notification",
|
||||
"hapticFeedback": "Haptic Feedback",
|
||||
"autoIpCheck": "Automatically Check Connection IP",
|
||||
"actionAtClosing": "Action at closing",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "Ask each time",
|
||||
"hide": "Hide",
|
||||
"exit": "Exit"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Advanced",
|
||||
"debugMode": "Debug Mode",
|
||||
"debugModeMsg": "Restart the app for applying this change",
|
||||
"memoryLimit": "Memory Limit",
|
||||
"memoryLimitMsg": "Enable if you're experiencing out of memory errors or frequent app crash",
|
||||
"resetTunnel": "Reset VPN Profile"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Per-App Proxy",
|
||||
"perAppProxyModes": {
|
||||
"off": "All",
|
||||
"offMsg": "Proxy All Apps",
|
||||
"include": "Proxy",
|
||||
"includeMsg": "Proxy Only Selected Apps",
|
||||
"exclude": "Bypass",
|
||||
"excludeMsg": "Do Not Proxy Selected Apps"
|
||||
},
|
||||
"showSystemApps": "Show System Apps",
|
||||
"hideSystemApps": "Hide System Apps",
|
||||
"clearSelection": "Clear Selection"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Routing Assets",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "GeoSite",
|
||||
"version": "Version ${version}",
|
||||
"fileMissing": "File Missing",
|
||||
"update": "Update",
|
||||
"download": "Download",
|
||||
"failureMsg": "Failed to Update Asset",
|
||||
"successMsg": "Successfully Updated Asset",
|
||||
"addRecommended": "Add Recommended Assets",
|
||||
"missingGeoAssetsMsg": "Selected Routing Assets' files are missing. Either download them or choose existing ones"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "About",
|
||||
"version": "Version",
|
||||
"sourceCode": "Source Code",
|
||||
"telegramChannel": "Telegram Channel",
|
||||
"checkForUpdate": "Check For Update",
|
||||
"privacyPolicy": "Privacy Policy",
|
||||
"termsAndConditions": "Terms and Conditions"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "Already Using The Latest Version",
|
||||
"dialogTitle": "Update Available",
|
||||
"updateMsg": "A new version of @:general.appTitle is available. Would you like to update now?",
|
||||
"currentVersionLbl": "Current Version",
|
||||
"newVersionLbl": "New Version",
|
||||
"updateNowBtnTxt": "Update Now",
|
||||
"laterBtnTxt": "Later",
|
||||
"ignoreBtnTxt": "Ignore"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Dashboard",
|
||||
"quit": "Quit",
|
||||
"open": "Open",
|
||||
"status": {
|
||||
"connect": "Connect",
|
||||
"connecting": "Connecting",
|
||||
"disconnect": "Disconnect",
|
||||
"disconnecting": "Disconnecting"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Unexpected Error",
|
||||
"clash": {
|
||||
"unexpected": "Unexpected Error",
|
||||
"core": "Clash Error ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Unexpected Service Error",
|
||||
"serviceNotRunning": "Service is Not Running",
|
||||
"missingPrivilege": "Missing Privilege",
|
||||
"missingPrivilegeMsg": "VPN Mode Requires Administrator Privileges. Either relaunch the app as administrator or change service mode.",
|
||||
"missingGeoAssets": "Missing Geo Assets",
|
||||
"missingGeoAssetsMsg": "Geo Assets Are Missing. Consider changing active asset or download selected one in the settings.",
|
||||
"invalidConfigOptions": "Invalid Configuration Options",
|
||||
"invalidConfig": "Invalid Configuration",
|
||||
"create": "Service Creation Error",
|
||||
"start": "Service Startup Error"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Unexpected Failure",
|
||||
"missingVpnPermission": "Missing VPN Permission",
|
||||
"missingNotificationPermission": "Missing Notification Permission",
|
||||
"core": "Core Error"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Unexpected Error",
|
||||
"notFound": "Profile Not Found",
|
||||
"invalidConfig": "Invalid Configs",
|
||||
"invalidUrl": "Invalid URL"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Unexpected Connection Error",
|
||||
"timeout": "Connection Timeout",
|
||||
"badResponse": "Bad Response",
|
||||
"connectionError": "Connection Error",
|
||||
"badCertificate": "Bad Certificate"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Unexpected Error",
|
||||
"notUpdate": "No Update Available",
|
||||
"activeNotFound": "Active Geo Asset Not Found"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (Preview)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "The key goal of Hiddify is to provide a secure, user-friendly and efficient tunneling client. It enables you to route all traffic or selected app traffic to a remote server of your choose, utilizing VPN-Service permission.\n\nNote: We do not provide any server; users are required to ensure their online activities stay private by using use their own self-hosted server or trusted servers. \n \nWe Support Servers With:\n- Normal V2Ray/XRay Subscription Link\n- Clash Subscription Link\n- Sing-Box Subscription Link\n\nWhat is our unique features?\n - User Friendly\n - Optimized and Fast\n - Automatically select LowestPing \n - Show user usage information\n - Easily import sublink by one click using deeplinking \n - Free and No ADS\n - Easily switch user sublinks\n - More and more\n\nSupport:\n- All Protocols Supported by Sing-Box \n- VLESS + XTLS Reality, Vision\n- VMess\n- Trojan\n- ShadowSocks\n- Reality\n- WireGuard\n- V2Ray\n- Hysteria2\n- TUICv5\n- SSH\n- ShadowTLS\n\n\nThe source code exist in https://github.com/hiddify/Hiddify-Next\nThe application core is based on open-source Sing-Box.\n\nPermission Description:\n- VPN Service: As the goal of this application is to provide a secure, user-friendly and efficient tunneling client, we need this permission to be able to route the traffic via tunnel to the remote server. \n- QUERY ALL PACKAGES: This permission is used to allow users to include or exclude specific applications for tunneling.\n- RECEIVE BOOT COMPLETED: This permission can be enabled or disabled from app settings to activate this application upon device boot.\n- POST NOTIFICATIONS: This permission is essential as we employ a foreground service to ensure the continuous operation of the VPN service.\n- This application is free from advertisements. The analytics and crash data only occurs with the explicit consent of the user in the first use of application."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Tap To Connect",
|
||||
"connecting": "Connecting",
|
||||
"disconnecting": "Disconnecting",
|
||||
"connected": "Connected",
|
||||
"reconnect": "Reconnect",
|
||||
"connectAnyWay": "Connect",
|
||||
"experimentalNotice": "Experimental Features In Use",
|
||||
"experimentalNoticeMsg": "You've enabled some experimental features which might affect connection quality and cause unexpected errors. You can always change or reset these options from Config options page.",
|
||||
"disableExperimentalNotice": "Don't Show Again",
|
||||
"reconnectMsg": "Reconnecting for taking into account the changes..."
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "Use Xray-core When Possible",
|
||||
"Description": "Use Xray-core during parsing sub links. You need to reimport the sub link to enable this option."
|
||||
},
|
||||
"resetBtn": "Reset Options",
|
||||
"serviceMode": "Service Mode",
|
||||
"quickSettings": "Quick Settings",
|
||||
"setupWarp": "Setup WARP",
|
||||
"allOptions": "All Config Options",
|
||||
"serviceModes": {
|
||||
"proxy": "Proxy Service Only",
|
||||
"systemProxy": "Set System Proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN Service"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "System Proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN Service"
|
||||
},
|
||||
"section": {
|
||||
"route": "Route Options",
|
||||
"dns": "DNS Options",
|
||||
"inbound": "Inbound Options",
|
||||
"mux": "MultiPlexer",
|
||||
"outbound": "Outbound Options",
|
||||
"tlsTricks": "TLS Tricks",
|
||||
"warp": "WARP Options",
|
||||
"misc": "Misc Options"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Cloudflare WARP Consent",
|
||||
"description(rich)": "Cloudflare WARP is a Free WireGuard VPN Provider. By enabling this option you are agreeing to the Cloudflare WARP's ${tos(Terms of Service)} and ${privacy(Privacy Policy)}."
|
||||
},
|
||||
"generateWarpConfig": "Generate WARP Config",
|
||||
"missingWarpConfig": "Missing WARP Config",
|
||||
"warpConfigGenerated": "WARP Config is Generated",
|
||||
"pageTitle": "Config Options",
|
||||
"logLevel": "Log Level",
|
||||
"blockAds": "Block Advertisements",
|
||||
"resolveDestination": "Resolve Destination",
|
||||
"ipv6Mode": "IPv6 Route",
|
||||
"ipv6Modes": {
|
||||
"disable": "Disable",
|
||||
"enable": "Enable",
|
||||
"prefer": "Preferred",
|
||||
"only": "Exclusive"
|
||||
},
|
||||
"remoteDnsAddress": "Remote DNS",
|
||||
"remoteDnsDomainStrategy": "Remote DNS Domain Strategy",
|
||||
"directDnsAddress": "Direct DNS",
|
||||
"directDnsDomainStrategy": "Direct DNS Domain Strategy",
|
||||
"mixedPort": "Mixed Port",
|
||||
"tproxyPort": "Transparent Proxy Port",
|
||||
"localDnsPort": "Local DNS Port",
|
||||
"allowConnectionFromLan": "Share VPN in Local Network",
|
||||
"tunImplementation": "TUN Implementation",
|
||||
"mtu": "Packet Size (MTU)",
|
||||
"connectionTestUrl": "Connection Test URL",
|
||||
"urlTestInterval": "URL Test Interval",
|
||||
"enableClashApi": "Enable Clash API",
|
||||
"clashApiPort": "Clash API Port",
|
||||
"enableTun": "Enable TUN",
|
||||
"setSystemProxy": "Set System Proxy",
|
||||
"enableDnsRouting": "Enable DNS Routing",
|
||||
"enableFakeDns": "Enable Fake DNS",
|
||||
"bypassLan": "Bypass Lan",
|
||||
"strictRoute": "Strict Route",
|
||||
"enableTlsFragment": "Enable TLS Fragment",
|
||||
"tlsFragmentSize": "TLS Fragment Size",
|
||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
||||
"enableTlsPadding": "Enable TLS Padding",
|
||||
"tlsPaddingSize": "TLS Padding",
|
||||
"enableMux": "Enable Mux",
|
||||
"muxProtocol": "Mux Protocol",
|
||||
"muxMaxStreams": "Max Concurrent Streams",
|
||||
"enableWarp": "Enable WARP",
|
||||
"warpDetourMode": "Detour Mode",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "Detour Proxies Through WARP",
|
||||
"warpOverProxy": "Detour WARP Through Proxies",
|
||||
"inbound": "Detour WARP Through Proxies",
|
||||
"outbound": "Detour Proxies Through WARP"
|
||||
},
|
||||
"warpLicenseKey": "License Key",
|
||||
"warpCleanIp": "Clean IP",
|
||||
"warpPort": "Port",
|
||||
"warpNoise": "Noise Count",
|
||||
"warpNoiseSize": "Noise Size",
|
||||
"warpNoiseMode": "Noise Mode",
|
||||
"warpNoiseDelay": "Noise Delay"
|
||||
},
|
||||
"window": {
|
||||
"hide": "Hide",
|
||||
"close": "Exit",
|
||||
"alertMessage": "Hide or Exit the application?",
|
||||
"remember": "Remember my choice"
|
||||
}
|
||||
}
|
||||
@@ -1,420 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Renicio",
|
||||
"toggle": {
|
||||
"enabled": "Activado",
|
||||
"disabled": "Desactivado"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Desactivar"
|
||||
},
|
||||
"sort": "Clasificar",
|
||||
"sortBy": "Ordenar por",
|
||||
"addToClipboard": "Añadir al portapapeles",
|
||||
"notSet": "No establecido",
|
||||
"agree": "Aceptar",
|
||||
"decline": "Rechazar",
|
||||
"unknown": "Desconocido",
|
||||
"hidden": "Oculto",
|
||||
"timeout": "Se acabó el tiempo",
|
||||
"clipboardExportSuccessMsg": "Añadido al portapapeles",
|
||||
"showMore": "Mostrar más",
|
||||
"showLess": "Muestra menos",
|
||||
"openAppSettings": "Abrir la configuración de la aplicación",
|
||||
"grantPermission": "Conceder permiso"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "al continuar, aceptas ${tap(@:about.termsAndConditions)}",
|
||||
"start": "Comenzar"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Hogar",
|
||||
"emptyProfilesMsg": "Comience agregando un perfil de suscripción",
|
||||
"noActiveProfileMsg": "Elige un perfil"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Tráfico",
|
||||
"trafficLive": "Tráfico en tiempo real",
|
||||
"trafficTotal": "Tráfico total",
|
||||
"uplink": "Enlace de subida",
|
||||
"downlink": "Enlace de bajada",
|
||||
"connection": "Conexión",
|
||||
"speed": "Velocidad",
|
||||
"totalTransferred": "Total transferido"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Perfiles",
|
||||
"detailsPageTitle": "Perfil",
|
||||
"activeProfileNameSemanticLabel": "Nombre del perfil activo: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "Ver todos los perfiles",
|
||||
"nonActiveProfileBtnSemanticLabel": "Seleccione \"${name}\" como perfil activo.",
|
||||
"subscription": {
|
||||
"traffic": "Tráfico",
|
||||
"updatedTimeAgo": "Actualizado ${timeago}",
|
||||
"remainingDuration": "${duration} días restantes",
|
||||
"remainingTrafficSemanticLabel": "${consumed} de ${total} Tráfico Consumido",
|
||||
"expired": "Caducado",
|
||||
"noTraffic": "Fuera de cuota",
|
||||
"upload": "Subir",
|
||||
"download": "Descargar",
|
||||
"total": "Tráfico total",
|
||||
"expireDate": "Fecha de expiración"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "Recientemente actualizado",
|
||||
"name": "Alfabéticamente"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "Nuevo perfil",
|
||||
"shortBtnTxt": "Nuevo perfil",
|
||||
"fromClipboard": "Agregar desde el portapapeles",
|
||||
"scanQr": "Escanear código QR",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "Permiso Denegado",
|
||||
"unexpectedError": "Algo salió mal",
|
||||
"torchSemanticLabel": "Linterna",
|
||||
"facingSemanticLabel": "Frente a la cámara",
|
||||
"permissionRequest": "Permiso a la cámara para escanear el código QR"
|
||||
},
|
||||
"manually": "Entrada manual",
|
||||
"addWarp": "Añadir WARP",
|
||||
"addingWarpMsg": "Por favor, espere mientras registramos WARP.",
|
||||
"addingProfileMsg": "Agregar perfil",
|
||||
"failureMsg": "No se pudo agregar el perfil"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Actualizar",
|
||||
"tooltip": "Actualización del perfil",
|
||||
"updateSubscriptions": "Actualizar suscripciones",
|
||||
"failureMsg": "No se pudo actualizar el perfil",
|
||||
"successMsg": "Perfil actualizado con éxito",
|
||||
"namedFailureMsg": "No se pudo actualizar \"${name}\"",
|
||||
"namedSuccessMsg": "\"${name}\" actualizado exitosamente"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Compartir",
|
||||
"exportToClipboardSuccess": "Exportado al portapapeles",
|
||||
"exportSubLinkToClipboard": "Exportar enlace de suscripción al portapapeles",
|
||||
"subLinkQrCode": "Código QR del enlace de suscripción",
|
||||
"exportConfigToClipboard": "Exportar configuración al portapapeles",
|
||||
"exportConfigToClipboardSuccess": "Configuración copiada al portapapeles"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Editar",
|
||||
"selectActiveTxt": "Seleccionar perfil activo"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Borrar",
|
||||
"confirmationMsg": "¿Eliminar perfil permanentemente?",
|
||||
"successMsg": "Perfil eliminado exitosamente"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Ahorrar",
|
||||
"successMsg": "Perfil guardado exitosamente",
|
||||
"failureMsg": "No se pudo guardar el perfil"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "Nombre",
|
||||
"nameHint": "Nombre de perfil",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "URL de configuración completa",
|
||||
"emptyNameMsg": "Se requiere el nombre",
|
||||
"invalidUrlMsg": "URL invalida",
|
||||
"lastUpdate": "Última actualización",
|
||||
"updateInterval": "Actualización automática",
|
||||
"updateIntervalDialogTitle": "Intervalo de actualización automática (en horas)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Proxies",
|
||||
"emptyProxiesMsg": "No proxies disponibles",
|
||||
"delayTestTooltip": "Prueba de Restraso",
|
||||
"sortTooltip": "Ordenar Proxies",
|
||||
"checkIp": "Comprobar IP",
|
||||
"unknownIp": "IP desconocida",
|
||||
"sortOptions": {
|
||||
"unsorted": "Por Defecto",
|
||||
"name": "Alfabéticamente",
|
||||
"delay": "Por retraso"
|
||||
},
|
||||
"activeProxySemanticLabel": "Proxy activo",
|
||||
"delaySemantics": {
|
||||
"result": "Retraso: ${delay}ms",
|
||||
"timeout": "Tiempo de espera del Timeout",
|
||||
"testing": "Retraso: Probando..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "Dirección IP",
|
||||
"country": "País"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Registros",
|
||||
"filterHint": "Filtrar",
|
||||
"allLevelsFilter": "Todo",
|
||||
"shareCoreLogs": "Compartir registros principales",
|
||||
"shareAppLogs": "Compartir registros de aplicaciones",
|
||||
"pauseTooltip": "Pausa",
|
||||
"resumeTooltip": "reanudar",
|
||||
"clearTooltip": "Claro"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Ajustes",
|
||||
"requiresRestartMsg": "Para que esto surta efecto, reinicie la aplicación.",
|
||||
"experimental": "Experimental",
|
||||
"experimentalMsg": "Las funciones con el indicador Experimental aún están en desarrollo y pueden causar problemas.",
|
||||
"exportOptions": "Copiar opciones anónimas al portapapeles",
|
||||
"exportAllOptions": "Copiar todas las opciones al portapapeles",
|
||||
"importOptions": "Importar opciones desde el portapapeles",
|
||||
"importOptionsMsg": "Esto reescribirá todas las opciones de configuración con los valores proporcionados. ¿Está seguro?",
|
||||
"general": {
|
||||
"sectionTitle": "General",
|
||||
"locale": "Idioma",
|
||||
"region": "Región",
|
||||
"regionMsg": "Ayuda a configurar opciones predeterminadas para omitir direcciones nacionales",
|
||||
"regions": {
|
||||
"ir": "Irán (ir)",
|
||||
"cn": "China (CN)",
|
||||
"ru": "Rusia (ru)",
|
||||
"af": "Afganistán (af)",
|
||||
"id": "Indonesia (id)",
|
||||
"tr": "Turquía (tr) 🇹🇷",
|
||||
"other": "Otro"
|
||||
},
|
||||
"themeMode": "Modo temático",
|
||||
"themeModes": {
|
||||
"system": "Seguir el tema del sistema",
|
||||
"dark": "Modo Oscuro",
|
||||
"light": "Modo Claro",
|
||||
"black": "Modo Negro"
|
||||
},
|
||||
"enableAnalytics": "Habilitar análisis",
|
||||
"enableAnalyticsMsg": "Dar permiso para recopilar análisis y enviar informes de fallos para mejorar la aplicación.",
|
||||
"autoStart": "Inicie en el arranque",
|
||||
"silentStart": "Inicio Silencioso",
|
||||
"openWorkingDir": "Abrir directorio de trabajo",
|
||||
"ignoreBatteryOptimizations": "Deshabilitar la optimización de la batería",
|
||||
"ignoreBatteryOptimizationsMsg": "Elimine las restricciones para un rendimiento VPN óptimo",
|
||||
"dynamicNotification": "Mostrar velocidad en la notificación",
|
||||
"hapticFeedback": "Respuesta háptica",
|
||||
"autoIpCheck": "Comprobación automática de la IP de conexión"
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Avanzado",
|
||||
"debugMode": "Modo de depuración",
|
||||
"debugModeMsg": "Reinicie la aplicación para aplicar este cambio.",
|
||||
"memoryLimit": "Limite de memoria",
|
||||
"memoryLimitMsg": "Habilítelo si experimenta errores de falta de memoria o fallas frecuentes de la aplicación",
|
||||
"resetTunnel": "Restablecer perfil VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Proxy por aplicación",
|
||||
"perAppProxyModes": {
|
||||
"off": "Todo",
|
||||
"offMsg": "Proxy en todas las aplicaciones",
|
||||
"include": "Proxy",
|
||||
"includeMsg": "Proxy solo en aplicaciones seleccionadas",
|
||||
"exclude": "Bypass",
|
||||
"excludeMsg": "No hacer proxy de aplicaciones seleccionadas"
|
||||
},
|
||||
"showSystemApps": "Mostrar aplicaciones del sistema",
|
||||
"hideSystemApps": "Ocultar aplicaciones del sistema",
|
||||
"clearSelection": "Selección clara"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Activos de enrutamiento",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "Geosite",
|
||||
"version": "Versión ${version}",
|
||||
"fileMissing": "Archivo faltante",
|
||||
"update": "Actualizar",
|
||||
"download": "Descargar",
|
||||
"failureMsg": "No se pudo actualizar el activo",
|
||||
"successMsg": "Activo actualizado correctamente",
|
||||
"addRecommended": "Agregar activos recomendados",
|
||||
"missingGeoAssetsMsg": "Faltan los archivos de los recursos de enrutamiento seleccionados. Descárgalos o elige los existentes."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "Acerca de",
|
||||
"version": "Versión",
|
||||
"sourceCode": "Código fuente",
|
||||
"telegramChannel": "Canal de Telegram",
|
||||
"checkForUpdate": "Buscar actualizaciones",
|
||||
"privacyPolicy": "Política de privacidad",
|
||||
"termsAndConditions": "Términos y condiciones"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "Ya estas usando la última versión.",
|
||||
"dialogTitle": "Actualización disponible",
|
||||
"updateMsg": "Hay disponible una nueva versión de @:general.appTitle. ¿Te gustaría actualizar ahora?",
|
||||
"currentVersionLbl": "Versión actual",
|
||||
"newVersionLbl": "Nueva versión",
|
||||
"updateNowBtnTxt": "Actualizar ahora",
|
||||
"laterBtnTxt": "Más tarde",
|
||||
"ignoreBtnTxt": "Ignorar"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Panel",
|
||||
"quit": "Abandonar",
|
||||
"open": "Abierto",
|
||||
"status": {
|
||||
"connect": "Conectar",
|
||||
"connecting": "Conectando",
|
||||
"disconnect": "Desconectado",
|
||||
"disconnecting": "Desconectando"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Error inesperado",
|
||||
"clash": {
|
||||
"unexpected": "Error inesperado",
|
||||
"core": "Error de choque ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Error de servicio inesperado",
|
||||
"serviceNotRunning": "El servicio no está funcionando",
|
||||
"missingPrivilege": "Privilegio perdido",
|
||||
"missingPrivilegeMsg": "El modo VPN requiere privilegios de administrador. Reinicie la aplicación como administrador o cambie el modo de servicio.",
|
||||
"missingGeoAssets": "Recursos geográficos faltantes",
|
||||
"missingGeoAssetsMsg": "Faltan recursos geográficos. considere cambiar el activo activo o descargar uno seleccionado en la configuración.",
|
||||
"invalidConfigOptions": "Opciones de configuración no válidas",
|
||||
"invalidConfig": "Configuración no válida",
|
||||
"create": "Error de creación del servicio",
|
||||
"start": "Error de inicio del servicio"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Falla inesperada",
|
||||
"missingVpnPermission": "Permiso VPN faltante",
|
||||
"missingNotificationPermission": "Permiso de notificación faltante",
|
||||
"core": "Error central"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Error Inesperado",
|
||||
"notFound": "Perfil no encontrado",
|
||||
"invalidConfig": "Configuracion Invalida",
|
||||
"invalidUrl": "URL Invalido"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Error de conexión inesperado",
|
||||
"timeout": "El tiempo de conexión expiro",
|
||||
"badResponse": "Mala respuesta",
|
||||
"connectionError": "Error de conexión",
|
||||
"badCertificate": "Certificado malo"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Error inesperado",
|
||||
"notUpdate": "Actualización no disponible",
|
||||
"activeNotFound": "Activo geográfico activo no encontrado"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify Next (vista previa)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "El objetivo clave de HiddifyNext es proporcionar un cliente de túnel seguro, fácil de usar y eficiente. Le permite enrutar todo el tráfico o el tráfico de aplicaciones seleccionadas a un servidor remoto de su elección, utilizando el permiso del servicio VPN.Nota: No proporcionamos ningún servidor; Los usuarios deben garantizar que sus actividades en línea permanezcan privadas mediante el uso de su propio servidor autohospedado o servidores confiables. Soportamos servidores con:- Enlace de suscripción normal a V2ray/Xray- Enlace de suscripción a Choque- Enlace de suscripción a Sing-Box¿Cuáles son nuestras características únicas? - Fácil de usar - Optimizado y Rápido - Seleccionar automáticamente LowestPing - Mostrar información de uso del usuario. - Importe fácilmente un subvínculo con un solo clic mediante enlaces profundos - Gratis y sin anuncios - Cambie fácilmente los subvínculos de usuario - más y másApoyo:- Todos los protocolos soportados por Sing-Box- VLESS + xtls realidad, visión- VMESS- troyano- Calcetines Shoadow- Realidad-V2ray-Histria2-TUIC-SSH- SombraTLSEl código fuente existe en https://github.com/hiddify/Hiddify-NextEl núcleo de la aplicación se basa en sing-box de código abierto.Descripción del permiso:- Servicio VPN: como el objetivo de esta aplicación es proporcionar un cliente de túnel seguro, fácil de usar y eficiente, necesitamos este permiso para poder enrutar el tráfico a través del túnel al servidor remoto.- CONSULTAR TODOS LOS PAQUETES: este permiso se utiliza para permitir a los usuarios incluir o excluir aplicaciones específicas para la tunelización.- RECIBIR ARRANQUE COMPLETADO: este permiso se puede habilitar o deshabilitar desde la configuración de la aplicación para activar esta aplicación al iniciar el dispositivo.- PUBLICAR NOTIFICACIONES: este permiso es esencial ya que empleamos un servicio en primer plano para garantizar el funcionamiento continuo del servicio VPN.- Esta aplicación está libre de publicidad. Los datos analíticos y de fallos solo se producen con el consentimiento explícito del usuario en el primer uso de la aplicación."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Toque para conectarse",
|
||||
"connecting": "Conectando",
|
||||
"disconnecting": "Desconectando",
|
||||
"connected": "Conectado",
|
||||
"reconnect": "Reconectar",
|
||||
"connectAnyWay": "Conectar",
|
||||
"experimentalNotice": "Funciones experimentales en uso",
|
||||
"experimentalNoticeMsg": "Ha habilitado algunas funciones experimentales que podrían afectar la calidad de la conexión y provocar errores inesperados. Siempre puede cambiar o restablecer estas opciones desde la página de opciones de configuración.",
|
||||
"disableExperimentalNotice": "No volver a mostrar",
|
||||
"reconnectMsg": "Reconectar para tener en cuenta los cambios..."
|
||||
},
|
||||
"config": {
|
||||
"resetBtn": "Restablecer opciones",
|
||||
"serviceMode": "Modo de servicio",
|
||||
"quickSettings": "Ajustes rápidos",
|
||||
"setupWarp": "Configurar WARP",
|
||||
"allOptions": "Todas las opciones de configuración",
|
||||
"serviceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Sistema Proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "Servicio VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Proxy del sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Servicio VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "Opciones de ruta",
|
||||
"dns": "Opciones de DNS",
|
||||
"inbound": "Opciones entrantes",
|
||||
"mux": "Multiplexer",
|
||||
"outbound": "Opciones de salida",
|
||||
"tlsTricks": "Trucos TLS",
|
||||
"warp": "WARP Options",
|
||||
"misc": "Opciones varias"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Consentimiento WARP de Cloudflare",
|
||||
"description(rich)": "Cloudflare WARP es un proveedor de VPN WireGuard gratuito. Al habilitar esta opción, acepta los ${tos(Términos de servicio)} y ${privacy(Política de privacidad)} de Cloudflare WARP."
|
||||
},
|
||||
"generateWarpConfig": "Generar configuración WARP",
|
||||
"missingWarpConfig": "Falta la configuración WARP",
|
||||
"warpConfigGenerated": "Se genera la configuración WARP",
|
||||
"pageTitle": "Opciones de configuración",
|
||||
"logLevel": "Registro del Nivel",
|
||||
"blockAds": "Bloquear anuncios",
|
||||
"resolveDestination": "Resolver Destino",
|
||||
"ipv6Mode": "Ruta IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Desactivar",
|
||||
"enable": "Activar",
|
||||
"prefer": "Preferido",
|
||||
"only": "Exclusivo"
|
||||
},
|
||||
"remoteDnsAddress": "DNS Remoto",
|
||||
"remoteDnsDomainStrategy": "Estrategia de dominio DNS remoto",
|
||||
"directDnsAddress": "DNS Directo",
|
||||
"directDnsDomainStrategy": "Estrategia de dominio DNS directo",
|
||||
"mixedPort": "Puerto Mixto",
|
||||
"tproxyPort": "Puerto de proxy transparente",
|
||||
"localDnsPort": "Puerto DNS local",
|
||||
"allowConnectionFromLan": "Permitir conexión desde LAN",
|
||||
"tunImplementation": "Implementación de TUN",
|
||||
"mtu": "Tamaño de paquete (MTU)",
|
||||
"connectionTestUrl": "URL de prueba de conexión",
|
||||
"urlTestInterval": "URL Prueba de Intervalo",
|
||||
"enableClashApi": "Habilitar API de choque",
|
||||
"clashApiPort": "Puerto API de choque",
|
||||
"enableTun": "Habilitar sintonización",
|
||||
"setSystemProxy": "stablecer proxy del sistema",
|
||||
"enableDnsRouting": "Habilitar enrutamiento DNS",
|
||||
"enableFakeDns": "Habilitar DNS falso",
|
||||
"bypassLan": "Omitir LAN",
|
||||
"strictRoute": "Ruta estricta",
|
||||
"enableTlsFragment": "Habilitar fragmento TLS",
|
||||
"tlsFragmentSize": "Tamaño del fragmento TLS",
|
||||
"tlsFragmentSleep": "Sueño de fragmento TLS",
|
||||
"enableTlsMixedSniCase": "Habilitar caso SNI mixto TLS",
|
||||
"enableTlsPadding": "Habilitar el relleno TLS",
|
||||
"tlsPaddingSize": "Relleno TLS",
|
||||
"enableMux": "Enable Mux",
|
||||
"muxProtocol": "Mux Protocol",
|
||||
"muxMaxStreams": "Max Concurrent Streams",
|
||||
"enableWarp": "Enable WARP",
|
||||
"warpDetourMode": "Detour Mode",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "Desvío de proxies a través de WARP",
|
||||
"warpOverProxy": "Desvío de WARP a través de proxies",
|
||||
"inbound": "Detour WARP through proxies",
|
||||
"outbound": "Detour proxies through WARP"
|
||||
},
|
||||
"warpLicenseKey": "License Key",
|
||||
"warpCleanIp": "Clean IP",
|
||||
"warpPort": "Port",
|
||||
"warpNoise": "Noise",
|
||||
"warpNoiseSize": "Tamaño de ruido",
|
||||
"warpNoiseMode": "Modo Ruido",
|
||||
"warpNoiseDelay": "Retraso por ruido"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "هیدیفای",
|
||||
"reset": "بازنشانی",
|
||||
"toggle": {
|
||||
"enabled": "فعال",
|
||||
"disabled": "غیرفعال"
|
||||
},
|
||||
"state": {
|
||||
"disable": "غیرفعال"
|
||||
},
|
||||
"sort": "مرتبسازی",
|
||||
"sortBy": "مرتبسازی براساس",
|
||||
"addToClipboard": "افزودن به کلیپبورد",
|
||||
"notSet": "تنظیم نشده است",
|
||||
"agree": "پذیرفتن",
|
||||
"decline": "صرفنظر کردن",
|
||||
"unknown": "ناشناخته",
|
||||
"hidden": "پنهان",
|
||||
"timeout": "عدم ارتباط",
|
||||
"clipboardExportSuccessMsg": "به کلیپبورد افزوده شد",
|
||||
"showMore": "نمایش بیشتر",
|
||||
"showLess": "نمایش کمتر",
|
||||
"openAppSettings": "باز کردن تنظیمات برنامه",
|
||||
"grantPermission": "اجازه دادن"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "در صورت ادامه با ${tap(@:about.termsAndConditions)} موافقت میکنید",
|
||||
"start": "آغاز"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "خانه",
|
||||
"emptyProfilesMsg": "با افزودن یک پروفایل اشتراک شروع کنید",
|
||||
"noActiveProfileMsg": "یک پروفایل انتخاب کنید"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "مصرف",
|
||||
"trafficLive": "مصرف لحظهای",
|
||||
"trafficTotal": "مصرف کل",
|
||||
"uplink": "ارسال",
|
||||
"downlink": "دریافت",
|
||||
"connection": "اتصال",
|
||||
"speed": "سرعت",
|
||||
"totalTransferred": "کل تبادل"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "پروفایلها",
|
||||
"detailsPageTitle": "پروفایل",
|
||||
"activeProfileNameSemanticLabel": "نام پروفایل فعال: ${name}",
|
||||
"activeProfileBtnSemanticLabel": "نمایش همهی پروفایلها",
|
||||
"nonActiveProfileBtnSemanticLabel": "انتخاب ${name} بهعنوان پروفایل فعال",
|
||||
"subscription": {
|
||||
"traffic": "ترافیک",
|
||||
"updatedTimeAgo": "${timeago} بهروزرسانی شد",
|
||||
"remainingDuration": "${duration} روز باقی مانده",
|
||||
"remainingTrafficSemanticLabel": "${consumed} از ${total} ترافیک مصرف شده",
|
||||
"expired": "پایان زمان مجاز",
|
||||
"noTraffic": "پایان حجم مجاز",
|
||||
"upload": "آپلود",
|
||||
"download": "دانلود",
|
||||
"total": "کل ترافیک",
|
||||
"expireDate": "تاریخ پایان"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "اخیراً بهروز شده",
|
||||
"name": "بر اساس نام"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "افزودن پروفایل جدید",
|
||||
"shortBtnTxt": "پروفایل جدید",
|
||||
"fromClipboard": "افزودن از کلیپبورد",
|
||||
"scanQr": "اسکن کد QR",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "دسترسی داده نشد",
|
||||
"unexpectedError": "خطایی رخ داده است",
|
||||
"torchSemanticLabel": "نور فلاش",
|
||||
"facingSemanticLabel": "جهت دوربین",
|
||||
"permissionRequest": "دسترسی به دوربین برای اسکن کد QR"
|
||||
},
|
||||
"manually": "افزودن دستی",
|
||||
"addWarp": "افزودن WARP",
|
||||
"addingWarpMsg": "لطفا صبر کنید تا وارپ ثبت شود",
|
||||
"addingProfileMsg": "در حال افزودن پروفایل",
|
||||
"failureMsg": "افزودن پروفایل ناموفق بود"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "بهروزرسانی",
|
||||
"tooltip": "بهروزرسانی پروفایل",
|
||||
"updateSubscriptions": "بهروزرسانی اشتراکها",
|
||||
"failureMsg": "بهروزرسانی پروفایل ناموفق بود",
|
||||
"successMsg": "پروفایل با موفقیت بهروزرسانی شد",
|
||||
"namedFailureMsg": "بهروزرسانی \"${name}\" ناموفق بود",
|
||||
"namedSuccessMsg": "\"${name}\" با موفقیت بهروز شد"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "اشتراکگذاری",
|
||||
"exportToClipboardSuccess": "به کلیپبورد اضافه شد",
|
||||
"exportSubLinkToClipboard": "صادر کردن لینک اشتراک به کلیپبورد",
|
||||
"subLinkQrCode": "کد QR لینک اشتراک",
|
||||
"exportConfigToClipboard": "افزودن پیکربندی به کلیپبورد",
|
||||
"exportConfigToClipboardSuccess": "پیکربندی در کلیپبورد کپی شد"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "ویرایش",
|
||||
"selectActiveTxt": "انتخاب پروفایل فعال"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "حذف",
|
||||
"confirmationMsg": "پروفایل برای همیشه حذف شود؟",
|
||||
"successMsg": "پروفایل با موفقیت حذف شد"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "ذخیره",
|
||||
"successMsg": "پروفایل با موفقیت ذخیره شد",
|
||||
"failureMsg": "خطا در ذخیرهی پروفایل"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "نام",
|
||||
"nameHint": "نام پروفایل",
|
||||
"urlLabel": "لینک",
|
||||
"urlHint": "لینک کامل پیکربندی",
|
||||
"emptyNameMsg": "نام نمیتواند خالی باشد",
|
||||
"invalidUrlMsg": "لینک نامعتبر است",
|
||||
"lastUpdate": "آخرین بهروزرسانی",
|
||||
"updateInterval": "بهروزرسانی خودکار",
|
||||
"updateIntervalDialogTitle": "فاصلهی زمانی بهروزرسانی خودکار (ساعت)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "پروکسیها",
|
||||
"emptyProxiesMsg": "هیچ پروکسی موجود نیست",
|
||||
"delayTestTooltip": "تست تأخیر",
|
||||
"sortTooltip": "مرتبسازی پروکسیها",
|
||||
"checkIp": "بررسی آیپی",
|
||||
"unknownIp": "آیپی ناشناخته",
|
||||
"sortOptions": {
|
||||
"unsorted": "پیشفرض",
|
||||
"name": "براساس نام",
|
||||
"delay": "براساس تأخیر"
|
||||
},
|
||||
"activeProxySemanticLabel": "پروکسی فعال",
|
||||
"delaySemantics": {
|
||||
"result": "تأخیر: ${delay}ms",
|
||||
"timeout": "مهلت تست تأخیر به اتمام رسید",
|
||||
"testing": "تأخیر: در حال آزمایش..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "آدرس آیپی",
|
||||
"country": "کشور"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "گزارشها",
|
||||
"filterHint": "فیلتر",
|
||||
"allLevelsFilter": "همه",
|
||||
"shareCoreLogs": "اشتراکگذاری گزارشهای هسته",
|
||||
"shareAppLogs": "اشتراکگذاری گزارشهای برنامه",
|
||||
"pauseTooltip": "مکث",
|
||||
"resumeTooltip": "ادامه دادن",
|
||||
"clearTooltip": "پاکسازی"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "تنظیمات",
|
||||
"requiresRestartMsg": "برای اعمال این تنظیم، برنامه را دوباره راهاندازی کنید",
|
||||
"experimental": "آزمایشی",
|
||||
"experimentalMsg": "تنظیماتی که عنوان آزمایشی دارند، همچنان در دست توسعه هستند و فعالسازی آنها میتواند باعث بروز مشکلاتی شود. ",
|
||||
"exportOptions": "کپی تنظیمات ساده به کلیپبورد",
|
||||
"exportAllOptions": "کپی همه تنظیمات به کلیپبورد",
|
||||
"importOptions": "وارد کردن تنظیمات از کلیپبورد",
|
||||
"importOptionsMsg": "این اقدام همهی تنظیمات پیکربندی را با مقادیر اولیه بازنویسی میکند. آیا مطمئن هستید؟",
|
||||
"general": {
|
||||
"sectionTitle": "عمومی",
|
||||
"locale": "زبان",
|
||||
"region": "منطقه",
|
||||
"regionMsg": "به انتخاب تنظیمات پیشفرض برای دور زدن آدرسهای داخلی کمک میکند",
|
||||
"regions": {
|
||||
"ir": "ایران (ir) 🇮🇷",
|
||||
"cn": "چین (cn) 🇨🇳",
|
||||
"ru": "روسیه (ru) 🇷🇺",
|
||||
"af": "افغانستان (af) 🇦🇫",
|
||||
"id": "إندونيسيا (id) 🇮🇩",
|
||||
"tr": "ترکیه (tr) 🇹🇷",
|
||||
"br": "برزیل (br) 🇧🇷",
|
||||
"other": "سایر"
|
||||
},
|
||||
"themeMode": "حالت پوسته",
|
||||
"themeModes": {
|
||||
"system": "پیروی از پوستهی دستگاه",
|
||||
"dark": "حالت تیره",
|
||||
"light": "حالت روشن",
|
||||
"black": "حالت سیاه"
|
||||
},
|
||||
"enableAnalytics": "فعالسازی تجزیه و تحلیلها",
|
||||
"enableAnalyticsMsg": "ارائهی دسترسی جمعآوری تجزیه و تحلیلها و ارسال گزارشهای خطا برای بهبود عملکرد برنامه",
|
||||
"autoStart": "راهاندازی هنگام شروع سیستم",
|
||||
"silentStart": "اجرای ساکت",
|
||||
"openWorkingDir": "باز کردن دایرکتوری فعال",
|
||||
"ignoreBatteryOptimizations": "غیرفعال کردن بهینهسازی باتری",
|
||||
"ignoreBatteryOptimizationsMsg": "برطرف کردن محدودیتها برای عملکرد بهینهی VPN",
|
||||
"dynamicNotification": "نمایش سرعت در نوار اعلان",
|
||||
"hapticFeedback": "بازخورد لمسی",
|
||||
"autoIpCheck": "بررسی خودکار آیپی اتصال",
|
||||
"actionAtClosing": "اقدام در زمان بسته شدن",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "هر بار پرسیده شود",
|
||||
"hide": "مخفی کردن",
|
||||
"exit": "خارج شدن"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "پیشرفته",
|
||||
"debugMode": "حالت اشکالزدایی",
|
||||
"debugModeMsg": "برنامه را برای اعمال این تغییر دوباره راهاندازی کنید",
|
||||
"memoryLimit": "محدودیت حافظه",
|
||||
"memoryLimitMsg": "اگر با خطاهای کمبود حافظه یا خرابی مکرر برنامه مواجه میشوید، این گزینه را فعال کنید",
|
||||
"resetTunnel": "بازنشانی پروفایل VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "پروکسی براساس برنامه",
|
||||
"perAppProxyModes": {
|
||||
"off": "همه",
|
||||
"offMsg": "همهی برنامهها پروکسی شوند",
|
||||
"include": "پروکسی",
|
||||
"includeMsg": "تنها برنامههای انتخابشده پروکسی شوند",
|
||||
"exclude": "کنار گذاشتن",
|
||||
"excludeMsg": "برنامههای انتخابشده پروکسی نشوند"
|
||||
},
|
||||
"showSystemApps": "نمایش برنامههای سیستمی",
|
||||
"hideSystemApps": "پنهان کردن برنامههای سیستمی",
|
||||
"clearSelection": "پاک کردن انتخابها"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "فایلهای مسیریابی",
|
||||
"geoip": "ژئو آیپی",
|
||||
"geosite": "ژئو سایت",
|
||||
"version": "نسخه ${version}",
|
||||
"fileMissing": "فایل موجود نیست",
|
||||
"update": "بهروزرسانی",
|
||||
"download": "دانلود",
|
||||
"failureMsg": "بهروزرسانی فایل ناموفق بود",
|
||||
"successMsg": "فایل با موفقیت بهروزرسانی شد",
|
||||
"addRecommended": "افزودن فایلهای توصیهشده",
|
||||
"missingGeoAssetsMsg": "فایلهای مسیریابی انتخاب شده وجود ندارند. یا آنها را دانلود کنید و یا یکی از موارد موجود را انتخاب کنید"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "درباره",
|
||||
"version": "نسخه",
|
||||
"sourceCode": "کد منبع",
|
||||
"telegramChannel": "کانال تلگرام",
|
||||
"checkForUpdate": "بررسی برای بهروزرسانی",
|
||||
"privacyPolicy": "سیاستهای حفظ حریم خصوصی",
|
||||
"termsAndConditions": "شرایط و ضوابط استفاده"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "در حال استفاده از آخرین نسخه هستید",
|
||||
"dialogTitle": "بهروزرسانی موجود است",
|
||||
"updateMsg": "نسخهی جدیدی از general.appTitle در دسترس است. آیا میخواهید آن را بهروزرسانی کنید؟",
|
||||
"currentVersionLbl": "نسخهی فعلی",
|
||||
"newVersionLbl": "نسخهی جدید",
|
||||
"updateNowBtnTxt": "هماکنون بهروزرسانی شود",
|
||||
"laterBtnTxt": "بعداً",
|
||||
"ignoreBtnTxt": "نادیدهگرفتن"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "داشبورد",
|
||||
"quit": "خروج",
|
||||
"open": "باز کردن",
|
||||
"status": {
|
||||
"connect": "اتصال",
|
||||
"connecting": "در حال اتصال",
|
||||
"disconnect": "قطع اتصال",
|
||||
"disconnecting": "در حال قطع اتصال"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"clash": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"core": "خطای Clash ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "خطای غیرمنتظره در سرویس",
|
||||
"serviceNotRunning": "سرویس در حال اجرا نیست",
|
||||
"missingPrivilege": "نیازمند دسترسی",
|
||||
"missingPrivilegeMsg": "حالت VPN به دسترسی ادمین نیاز دارد. یا برنامه را دوباره بهعنوان ادمین راهاندازی کنید یا حالت سرویس را تغییر دهید.",
|
||||
"missingGeoAssets": "فایلهای جغرافیایی وجود ندارد",
|
||||
"missingGeoAssetsMsg": "فایلهای جغرافیایی وجود ندارند. یا فایل فعال را تغییر دهید و یا فایل های انتخاب شده را دانلود کنید. ",
|
||||
"invalidConfigOptions": "تنظیمات پیکربندی نامعتبر",
|
||||
"invalidConfig": "پیکربندی نامعتبر",
|
||||
"create": "خطای ایجاد سرویس",
|
||||
"start": "خطای راهاندازی سرویس"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"missingVpnPermission": "مجوز VPN وجود ندارد",
|
||||
"missingNotificationPermission": "مجوز اعلان وجود ندارد",
|
||||
"core": "خطای هسته"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"notFound": "پروفایل یافت نشد",
|
||||
"invalidConfig": "پیکربندیها نامعتبر هستند",
|
||||
"invalidUrl": "لینک نامعتبر است"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": " خطای غیرمنتظره در اتصال",
|
||||
"timeout": "مهلت اتصال به پایان رسید",
|
||||
"badResponse": "پاسخ نامعتبر",
|
||||
"connectionError": "خطای اتصال",
|
||||
"badCertificate": "خطای اعتبارسنجی"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "خطای غیرمنتظره",
|
||||
"notUpdate": "هیچ بهروزرسانی موجود نیست",
|
||||
"activeNotFound": "فایل جغرافیایی فعال یافت نشد"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "هیدیفای (آزمایشی)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "هدف اصلی هیدیفای ارائه یک کلاینت ضدفیلتر ایمن، کاربرپسند و کارآمد است. این به شما امکان میدهد تا با استفاده از مجوز سرویس VPN، تمام ترافیک یا ترافیک برنامهی انتخابی را به یک سرور راه دور مورد نظر خود هدایت کنید.\n\nتوجه: ما هیچ سروری ارائه نمیدهیم. کاربران موظف هستند با استفاده از سرورهای خود، هاست یا سرورهای مورد اعتماد، فعالیتهای آنلاین خود را خصوصی نگه دارند. \n\nما از این سرورها پشتیبانی میکنیم:\n- لینک اشتراک V2Ray/XRay معمولی\n- لینک اشتراک کلش\n- لینک اشتراک Sing-Box\n\nویژگیهای منحصر به فرد این برنامه چیست؟\n- کاربر پسند \n- بهینه و سریع \n- انتخاب کمترین پینگ به صورت خودکار\n- نمایش اطلاعات استفاده کاربر\n- به راحتی لینک فرعی را با یک کلیک با استفاده از دیپ لینک وارد کنید \n- رایگان و بدون تبلیغات \n- بهراحتی لینک های فرعی کاربر را تغییر دهید \n- بیشتر و بیشتر\n\nپشتیبانی از:\n- همهی پروتکلهای پشتیبانیشده توسط Sing-Box- VLESS + XTLS Reality، Vision- VMess- Trojan- ShadowSocks- Reality- WireGuard- V2Ray- Hysteria2- TUICv5- SSH- ShadowTLS\n\nکد منبع در https://github.com/hiddify/Hiddify-Next موجود بوده و هستهی برنامه مبتنی بر منبع باز Sing-Box است.\n\nتوضیحات مجوز:\n- VPN Service: از آنجا که هدف این برنامه ارائهی یک کلاینت ضدفیلتر ایمن، کاربر پسند و کارآمد است، ما به این مجوز نیاز داریم تا بتوانیم ترافیک را از طریق تونل به سرور راه دور هدایت کنیم.\n- QUERY ALL PACKAGES: این مجوز برای اجازه دادن به کاربران برای گنجاندن یا حذف برنامههای کاربردی خاص برای تونلزدن استفاده میشود.\n- RECEIVE BOOT COMPLETED: این مجوز را میتوان از تنظیمات برنامه فعال یا غیرفعال کرد تا این برنامه پس از شروع به کار دستگاه فعال شود.\n- POST NOTIFICATIONS: این مجوز ضروری است زیرا برای اطمینان از عملکرد یکسره VPN نیاز است از یک سرویس پس زمینه استفاده کنیم. \n- این برنامه بدون تبلیغات است. تجزیه و تحلیل و دادههای خرابی فقط با رضایت صریح کاربر در اولین استفاده از برنامه اتفاق میافتد."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "برای اتصال ضربه بزنید",
|
||||
"connecting": "در حال اتصال",
|
||||
"disconnecting": "در حال قطع اتصال",
|
||||
"connected": "متصل شد",
|
||||
"reconnect": "اتصال دوباره",
|
||||
"connectAnyWay": "متصل کردن",
|
||||
"experimentalNotice": "ویژگیهای آزمایشی در حال استفاده",
|
||||
"experimentalNoticeMsg": "شما برخی از ویژگیهای آزمایشی را فعال کردهاید که ممکن است بر کیفیت اتصال تأثیر گذاشته و باعث بروز خطاهای غیرمنتظره شود. شما همیشه میتوانید این گزینهها را از صفحهی تنظیمات پیکربندی تغییر دهید یا بازنشانی کنید.",
|
||||
"disableExperimentalNotice": "دیگر نشان نده",
|
||||
"reconnectMsg": "در حال اتصال مجدد برای اعمال تغییرات..."
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "استفاده از Xray-core در صورت ممکن",
|
||||
"Description": "برای استفاده از Xray-core باید دوباره لینک ساب را وارد کنید تا این گزینه فعال شود."
|
||||
},
|
||||
"resetBtn": "بازنشانی تنظیمات",
|
||||
"serviceMode": "حالت سرویس",
|
||||
"quickSettings": "تنظیمات سریع",
|
||||
"setupWarp": "راهاندازی WARP",
|
||||
"allOptions": "همهی تنظیمات پیکربندی",
|
||||
"serviceModes": {
|
||||
"proxy": "تنها سرویس پروکسی",
|
||||
"systemProxy": "تنظیم پروکسی سیستم",
|
||||
"tun": "VPN",
|
||||
"tunService": "سرویس VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "پروکسی",
|
||||
"systemProxy": "پروکسی سیستم",
|
||||
"tun": "VPN",
|
||||
"tunService": "سرویس VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "تنظیمات مسیریابی",
|
||||
"dns": "تنظیمات DNS",
|
||||
"inbound": "تنظیمات ورودی",
|
||||
"mux": "مالتی پلکسر",
|
||||
"outbound": "تنظیمات خروجی",
|
||||
"tlsTricks": "ترفندهای TLS",
|
||||
"warp": "تنظیمات WARP",
|
||||
"misc": "تنظیمات متفرقه"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "توافقنامهی Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP یک ارائهدهندهی رایگان WireGuard VPN است. با فعال کردن این گزینه، با ${tos(شرایط خدمات)} و ${privacy(خط مشی رازداری)} Cloudflare WARP موافقت میکنید."
|
||||
},
|
||||
"generateWarpConfig": "ایجاد پیکربندی WARP",
|
||||
"missingWarpConfig": "پیکربندی WARP موجود نیست",
|
||||
"warpConfigGenerated": "پیکربندی WARP ایجاد شد",
|
||||
"pageTitle": "تنظیمات پیکربندی",
|
||||
"logLevel": "سطح گزارش",
|
||||
"blockAds": "مسدود سازی تبلیغات",
|
||||
"resolveDestination": "جایگذاری مقصد",
|
||||
"ipv6Mode": "مسیریابی IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "غیرفعال",
|
||||
"enable": "فعال",
|
||||
"prefer": "ترجیح داده شده",
|
||||
"only": "اختصاصی"
|
||||
},
|
||||
"remoteDnsAddress": "DNS خارجی",
|
||||
"remoteDnsDomainStrategy": "استراتژی دامنه DNS خارجی",
|
||||
"directDnsAddress": "DNS مستقیم",
|
||||
"directDnsDomainStrategy": "استراتژی دامنه DNS مستقیم",
|
||||
"mixedPort": "پورت چندمنظوره",
|
||||
"tproxyPort": "پورت پروکسی نامرئی",
|
||||
"localDnsPort": "پورت DNS داخلی",
|
||||
"allowConnectionFromLan": "اشتراک VPN در شبکه داخلی",
|
||||
"tunImplementation": "پیادهسازی TUN",
|
||||
"mtu": "سایز بسته (MTU) ",
|
||||
"connectionTestUrl": "لینک بررسی اتصال",
|
||||
"urlTestInterval": "فاصلهی زمانی بررسی لینک",
|
||||
"enableClashApi": "فعالسازی Clash API",
|
||||
"clashApiPort": "پورت Clash API",
|
||||
"enableTun": "فعالسازی TUN",
|
||||
"setSystemProxy": "تنظیم پروکسی سیستم",
|
||||
"enableDnsRouting": "فعالسازی مسیریابی DNS",
|
||||
"enableFakeDns": "فعالسازی DNS جعلی",
|
||||
"bypassLan": "دور زدن LAN",
|
||||
"strictRoute": "مسیر دقیق",
|
||||
"enableTlsFragment": "فعالسازی TLS Fragment",
|
||||
"tlsFragmentSize": "اندازهی TLS Fragment ",
|
||||
"tlsFragmentSleep": "کنار گذاشتن TLS Fragment",
|
||||
"enableTlsMixedSniCase": "فعالسازی TLS Mixed SNI Case",
|
||||
"enableTlsPadding": "فعالسازی TLS Padding",
|
||||
"tlsPaddingSize": "اندازهی TLS Padding",
|
||||
"enableMux": "فعالسازی Mux",
|
||||
"muxProtocol": "پروتکل Mux",
|
||||
"muxMaxStreams": "حداکثر جریانهای همزمان",
|
||||
"enableWarp": "فعالسازی WARP",
|
||||
"warpDetourMode": "حالت وارپ",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "عبور پروکسیها از طریق WARP",
|
||||
"warpOverProxy": "عبور WARP از طریق پروکسیها",
|
||||
"inbound": "عبور WARP از طریق پروکسیها",
|
||||
"outbound": "عبور پروکسیها از طریق WARP"
|
||||
},
|
||||
"warpLicenseKey": "کلید لایسنس",
|
||||
"warpCleanIp": "آیپی تمیز",
|
||||
"warpPort": "پورت",
|
||||
"warpNoise": "تعداد نویز",
|
||||
"warpNoiseSize": "اندازه نویز",
|
||||
"warpNoiseMode": "حالت نویز",
|
||||
"warpNoiseDelay": "تأخیر نویز"
|
||||
},
|
||||
"window": {
|
||||
"hide": "مخفی کردن",
|
||||
"close": "خارج شدن",
|
||||
"alertMessage": "مخفی کردن یا خروج از برنامه؟",
|
||||
"remember": "انتخاب من را به خاطر بسپار"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Réinitialiser",
|
||||
"toggle": {
|
||||
"enabled": "Activé",
|
||||
"disabled": "Désactivé"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Désactiver"
|
||||
},
|
||||
"sort": "Trier",
|
||||
"sortBy": "Trier par",
|
||||
"addToClipboard": "Ajouter au presse-papiers",
|
||||
"notSet": "Pas encore défini",
|
||||
"agree": "Accepter",
|
||||
"decline": "Déclin",
|
||||
"unknown": "Inconnu",
|
||||
"hidden": "Caché",
|
||||
"timeout": "Temps mort",
|
||||
"clipboardExportSuccessMsg": "Ajouté au presse-papiers",
|
||||
"showMore": "Montre plus",
|
||||
"showLess": "Montrer moins",
|
||||
"openAppSettings": "Ouvrir les paramètres de l'application",
|
||||
"grantPermission": "Donner la permission"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "En continuant, vous êtes d'accord avec ${tap( @:about.termsAndConditions)}",
|
||||
"start": "Commencer"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Maison",
|
||||
"emptyProfilesMsg": "Commencez par ajouter un profil d'abonnement",
|
||||
"noActiveProfileMsg": "Choisissez un profil"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Trafic",
|
||||
"trafficLive": "Trafic en direct",
|
||||
"trafficTotal": "Trafic total",
|
||||
"uplink": "Liaison montante",
|
||||
"downlink": "Liaison descendante",
|
||||
"connection": "Connexion",
|
||||
"speed": "Vitesse",
|
||||
"totalTransferred": "Total transféré"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Profils",
|
||||
"detailsPageTitle": "Profil",
|
||||
"activeProfileNameSemanticLabel": "Nom du profil actif : \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "Afficher tous les profils",
|
||||
"nonActiveProfileBtnSemanticLabel": "Sélectionnez \"${name}\" comme profil actif",
|
||||
"subscription": {
|
||||
"traffic": "Trafic",
|
||||
"updatedTimeAgo": "Mise à jour ${timeago}",
|
||||
"remainingDuration": "${duration} jours restants",
|
||||
"remainingTrafficSemanticLabel": "${consumed} de ${total} de trafic consommé",
|
||||
"expired": "Expiré",
|
||||
"noTraffic": "Hors quota",
|
||||
"upload": "Télécharger",
|
||||
"download": "Télécharger",
|
||||
"total": "Trafic total",
|
||||
"expireDate": "Date d'expiration"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "Récemment mis à jour",
|
||||
"name": "Alphabétiquement"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "Nouveau profile",
|
||||
"shortBtnTxt": "Nouveau profile",
|
||||
"fromClipboard": "Ajouter à partir du presse-papiers",
|
||||
"scanQr": "Scanner le code QR",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "Permission refusée",
|
||||
"unexpectedError": "Quelque chose s'est mal passé",
|
||||
"torchSemanticLabel": "Lampe torche",
|
||||
"facingSemanticLabel": "Face à la caméra",
|
||||
"permissionRequest": "Autorisation de la caméra pour scanner le code QR"
|
||||
},
|
||||
"manually": "Saisie manuelle",
|
||||
"addWarp": "Ajouter WARP",
|
||||
"addingWarpMsg": "Veuillez patienter pendant que nous enregistrons WARP.",
|
||||
"addingProfileMsg": "Ajout d'un profil",
|
||||
"failureMsg": "Échec de l'ajout du profil"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Mise à jour",
|
||||
"tooltip": "Mettre à jour le profil",
|
||||
"updateSubscriptions": "Mettre à jour les abonnements",
|
||||
"failureMsg": "Échec de la mise à jour du profil",
|
||||
"successMsg": "Mise à jour du profil réussie",
|
||||
"namedFailureMsg": "Échec de la mise à jour de \"${name}\"",
|
||||
"namedSuccessMsg": "\"${name}\" a été mis à jour avec succès"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Partager",
|
||||
"exportToClipboardSuccess": "Exporté vers le Presse-papiers",
|
||||
"exportSubLinkToClipboard": "Exporter le lien d'abonnement vers le presse-papiers",
|
||||
"subLinkQrCode": "Code QR du lien d'abonnement",
|
||||
"exportConfigToClipboard": "Exporter la configuration vers le presse-papiers",
|
||||
"exportConfigToClipboardSuccess": "Configuration copiée dans le presse-papiers"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Modifier",
|
||||
"selectActiveTxt": "Sélectionnez un profil actif"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Supprimer",
|
||||
"confirmationMsg": "Supprimer le profil définitivement ?",
|
||||
"successMsg": "Profil supprimé avec succès"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Sauvegarder",
|
||||
"successMsg": "Profil enregistré avec succès",
|
||||
"failureMsg": "Échec de l'enregistrement du profil"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "Nom",
|
||||
"nameHint": "Nom de profil",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "URL de configuration complète",
|
||||
"emptyNameMsg": "Le nom est requis",
|
||||
"invalidUrlMsg": "URL invalide",
|
||||
"lastUpdate": "Dernière mise à jour",
|
||||
"updateInterval": "Mise à jour automatique",
|
||||
"updateIntervalDialogTitle": "Intervalle de mise à jour automatique (en heures)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Procurations",
|
||||
"emptyProxiesMsg": "Aucun proxy disponible",
|
||||
"delayTestTooltip": "Délai de test",
|
||||
"sortTooltip": "Trier les proxys",
|
||||
"checkIp": "Vérifier l'adresse IP",
|
||||
"unknownIp": "IP inconnue",
|
||||
"sortOptions": {
|
||||
"unsorted": "Défaut",
|
||||
"name": "Alphabétiquement",
|
||||
"delay": "Par retard"
|
||||
},
|
||||
"activeProxySemanticLabel": "Mandataire actif",
|
||||
"delaySemantics": {
|
||||
"result": "Délai : ${delay} ms",
|
||||
"timeout": "Délai d'expiration du test",
|
||||
"testing": "Retard : test..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "Adresse IP",
|
||||
"country": "Pays"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Journaux",
|
||||
"filterHint": "Filtre",
|
||||
"allLevelsFilter": "Tous",
|
||||
"shareCoreLogs": "Partager les journaux principaux",
|
||||
"shareAppLogs": "Partager les journaux d'applications",
|
||||
"pauseTooltip": "Pause",
|
||||
"resumeTooltip": "CV",
|
||||
"clearTooltip": "Clair"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Paramètres",
|
||||
"requiresRestartMsg": "Pour que cela prenne effet, redémarrez l'application",
|
||||
"experimental": "Expérimental",
|
||||
"experimentalMsg": "Les fonctionnalités avec l'indicateur expérimental sont encore en développement et peuvent causer des problèmes.",
|
||||
"exportOptions": "Copier les options anonymes dans le presse-papiers",
|
||||
"exportAllOptions": "Copier toutes les options dans le presse-papiers",
|
||||
"importOptions": "Options d'importation à partir du Presse-papiers",
|
||||
"importOptionsMsg": "Cela réécrira toutes les options de configuration avec les valeurs fournies. Es-tu sûr?",
|
||||
"general": {
|
||||
"sectionTitle": "Général",
|
||||
"locale": "Langue",
|
||||
"region": "Région",
|
||||
"regionMsg": "Aide à définir les options par défaut pour contourner les adresses nationales",
|
||||
"regions": {
|
||||
"ir": "Iran (ir) 🇮🇷",
|
||||
"cn": "Chine (cn) 🇨🇳",
|
||||
"ru": "Russie (ru) 🇷🇺",
|
||||
"af": "Afghanistan (af) 🇦🇫",
|
||||
"id": "Indonésie (id) 🇮🇩",
|
||||
"tr": "Turquie (tr) 🇹🇷",
|
||||
"br": "Brésil (br) 🇧🇷",
|
||||
"other": "Autre"
|
||||
},
|
||||
"themeMode": "Mode Thème",
|
||||
"themeModes": {
|
||||
"system": "Suivre le thème du système",
|
||||
"dark": "Mode sombre",
|
||||
"light": "Mode lumière",
|
||||
"black": "Mode noir"
|
||||
},
|
||||
"enableAnalytics": "Activer l'analyse",
|
||||
"enableAnalyticsMsg": "Autoriser la collecte d'analyses et l'envoi de rapports d'erreur pour améliorer l'application",
|
||||
"autoStart": "Commencez par la connexion",
|
||||
"silentStart": "Démarrer réduit",
|
||||
"openWorkingDir": "Ouvrir le répertoire de travail",
|
||||
"ignoreBatteryOptimizations": "Désactiver l'optimisation de la batterie",
|
||||
"ignoreBatteryOptimizationsMsg": "Supprimez les restrictions pour des performances VPN optimales",
|
||||
"dynamicNotification": "Vitesse d'affichage dans les notifications",
|
||||
"hapticFeedback": "Retour haptique",
|
||||
"autoIpCheck": "Vérifier automatiquement l'adresse IP de la connexion",
|
||||
"actionAtClosing": "Action à la clôture",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "Demander à chaque fois",
|
||||
"hide": "Cacher",
|
||||
"exit": "Sortir"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Avancé",
|
||||
"debugMode": "Mode débogage",
|
||||
"debugModeMsg": "Redémarrez l'application pour appliquer cette modification",
|
||||
"memoryLimit": "Limite de mémoire",
|
||||
"memoryLimitMsg": "Activer si vous rencontrez des erreurs de mémoire insuffisante ou des plantages fréquents de l'application",
|
||||
"resetTunnel": "Réinitialiser le profil VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Proxy par application",
|
||||
"perAppProxyModes": {
|
||||
"off": "Tous",
|
||||
"offMsg": "Proxy Toutes les applications",
|
||||
"include": "Proxy",
|
||||
"includeMsg": "Applications sélectionnées par proxy uniquement",
|
||||
"exclude": "Contourne",
|
||||
"excludeMsg": "Ne pas proxyer les applications sélectionnées"
|
||||
},
|
||||
"showSystemApps": "Afficher les applications système",
|
||||
"hideSystemApps": "Masquer les applications système",
|
||||
"clearSelection": "Effacer la sélection"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Actifs de routage",
|
||||
"geoip": "GéoIP",
|
||||
"geosite": "GéoSite",
|
||||
"version": "Version ${version}",
|
||||
"fileMissing": "Dossier manquant",
|
||||
"update": "Mise à jour",
|
||||
"download": "Télécharger",
|
||||
"failureMsg": "Échec de la mise à jour de l'actif",
|
||||
"successMsg": "Actif mis à jour avec succès",
|
||||
"addRecommended": "Ajouter des actifs recommandés",
|
||||
"missingGeoAssetsMsg": "Les fichiers des ressources de routage sélectionnées sont manquants. Téléchargez-les ou choisissez ceux existants"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "À propos",
|
||||
"version": "Version",
|
||||
"sourceCode": "Code source",
|
||||
"telegramChannel": "Chaîne de Telegram",
|
||||
"checkForUpdate": "Rechercher une mise à jour",
|
||||
"privacyPolicy": "politique de confidentialité",
|
||||
"termsAndConditions": "Termes et conditions"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "Vous utilisez déjà la dernière version",
|
||||
"dialogTitle": "Mise à jour disponible",
|
||||
"updateMsg": "Une nouvelle version de @:general.appTitle est disponible. Souhaitez-vous mettre à jour maintenant ?",
|
||||
"currentVersionLbl": "Version actuelle",
|
||||
"newVersionLbl": "Nouvelle version",
|
||||
"updateNowBtnTxt": "Mettez à jour maintenant",
|
||||
"laterBtnTxt": "Plus tard",
|
||||
"ignoreBtnTxt": "Ignorer"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Tableau de bord",
|
||||
"quit": "Quitter",
|
||||
"open": "Ouvrir",
|
||||
"status": {
|
||||
"connect": "Connecter",
|
||||
"connecting": "De liaison",
|
||||
"disconnect": "Déconnecter",
|
||||
"disconnecting": "Déconnexion"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Erreur inattendue",
|
||||
"clash": {
|
||||
"unexpected": "Erreur inattendue",
|
||||
"core": "Erreur de conflit ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Erreur de service inattendue",
|
||||
"serviceNotRunning": "Le service ne fonctionne pas",
|
||||
"missingPrivilege": "Privilège manquant",
|
||||
"missingPrivilegeMsg": "Le mode VPN nécessite des privilèges d'administrateur. Soit relancez l'application en tant qu'administrateur, soit changez de mode de service.",
|
||||
"missingGeoAssets": "Actifs géographiques manquants",
|
||||
"missingGeoAssetsMsg": "Les ressources géographiques sont manquantes. Pensez à modifier l'actif actif ou à télécharger celui sélectionné dans les paramètres.",
|
||||
"invalidConfigOptions": "Options de configuration invalides",
|
||||
"invalidConfig": "Configuration invalide",
|
||||
"create": "Erreur de création de service",
|
||||
"start": "Erreur de démarrage du service"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Échec inattendu",
|
||||
"missingVpnPermission": "Autorisation VPN manquante",
|
||||
"missingNotificationPermission": "Autorisation de notification manquante",
|
||||
"core": "Erreur principale"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Erreur inattendue",
|
||||
"notFound": "Profil non trouvé",
|
||||
"invalidConfig": "Configurations invalides",
|
||||
"invalidUrl": "URL invalide"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Erreur de connexion inattendue",
|
||||
"timeout": "Délai de connection dépassé",
|
||||
"badResponse": "Mauvaise réponse",
|
||||
"connectionError": "Erreur de connexion",
|
||||
"badCertificate": "Mauvais certificat"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Erreur inattendue",
|
||||
"notUpdate": "Pas de mise a jour disponible",
|
||||
"activeNotFound": "Actif géographique actif introuvable"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (aperçu)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, cheval de Troie, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "L'objectif principal de Hiddify est de fournir un client de tunneling sécurisé, convivial et efficace. Il vous permet d'acheminer tout le trafic ou le trafic d'applications sélectionnées vers un serveur distant de votre choix, en utilisant l'autorisation du service VPN.<inlang-LineFeed>\nRemarque : Nous ne fournissons aucun serveur ; les utilisateurs sont tenus de garantir que leurs activités en ligne restent privées en utilisant leur propre serveur auto-hébergé ou des serveurs de confiance.<inlang-LineFeed>\nNous prenons en charge les serveurs avec :\n- Lien d'abonnement normal V2Ray/XRay\n- Lien d'abonnement Clash\n- Lien d'abonnement à Sing-Box<inlang-LineFeed>\nQuelles sont nos caractéristiques uniques ?\n- Convivial\n- Optimisé et rapide\n- Sélectionnez automatiquement le plus bas Ping\n- Afficher les informations d'utilisation de l'utilisateur\n- Importez facilement des sous-liens en un seul clic grâce au deeplinking\n- Gratuit et sans publicité\n- Changez facilement de sous-liens utilisateur\n- De plus en plus<inlang-LineFeed>\nSoutien:\n- Tous les protocoles pris en charge par Sing-Box\n- VLESS + XTLS Réalité, Vision\n-VMess\n- Cheval de Troie\n- Chaussettes Shadow\n- Réalité\n- WireGuard\n-V2Ray\n- Hystérie2\n-TUICv5\n-SSH\n-OmbreTLS<inlang-LineFeed><inlang-LineFeed>\nLe code source existe sur https://github.com/hiddify/Hiddify-Next\nLe cœur de l'application est basé sur Sing-Box open source.<inlang-LineFeed>\nDescription de l'autorisation :\n- Service VPN : L'objectif de cette application étant de fournir un client de tunneling sécurisé, convivial et efficace, nous avons besoin de cette autorisation pour pouvoir acheminer le trafic via un tunnel vers le serveur distant.\n- REQUÊTER TOUS LES PAQUETS : cette autorisation est utilisée pour permettre aux utilisateurs d'inclure ou d'exclure des applications spécifiques pour le tunneling.\n- RECEVOIR LE BOOT TERMINÉ : Cette autorisation peut être activée ou désactivée à partir des paramètres de l'application pour activer cette application au démarrage de l'appareil.\n- POST NOTIFICATIONS : Cette autorisation est essentielle car nous utilisons un service de premier plan pour assurer le fonctionnement continu du service VPN.\n- Cette application est exempte de publicités. Les données d'analyse et de crash n'ont lieu qu'avec le consentement explicite de l'utilisateur lors de la première utilisation de l'application."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Appuyez pour vous connecter",
|
||||
"connecting": "De liaison",
|
||||
"disconnecting": "Déconnexion",
|
||||
"connected": "Connecté",
|
||||
"reconnect": "Reconnecter",
|
||||
"connectAnyWay": "Connecter",
|
||||
"experimentalNotice": "Fonctionnalités expérimentales utilisées",
|
||||
"experimentalNoticeMsg": "Vous avez activé certaines fonctionnalités expérimentales qui peuvent affecter la qualité de la connexion et provoquer des erreurs inattendues. Vous pouvez toujours modifier ou réinitialiser ces options à partir de la page des options de configuration.",
|
||||
"disableExperimentalNotice": "Ne plus montrer",
|
||||
"reconnectMsg": "Se reconnecter pour prendre en compte les changements..."
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "Utiliser Xray-core lorsque cela est possible",
|
||||
"Description": "Utiliser Xray-core lors de l'analyse des sous-liens. Vous devez réimporter le sous-lien pour activer cette option."
|
||||
},
|
||||
"resetBtn": "Options de réinitialisation",
|
||||
"serviceMode": "Mode de service",
|
||||
"quickSettings": "Réglages rapides",
|
||||
"setupWarp": "Configuration de WARP",
|
||||
"allOptions": "Toutes les options de configuration",
|
||||
"serviceModes": {
|
||||
"proxy": "Service proxy uniquement",
|
||||
"systemProxy": "Définir le proxy système",
|
||||
"tun": "VPN",
|
||||
"tunService": "Service VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Proxy système",
|
||||
"tun": "VPN",
|
||||
"tunService": "Service VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "Options d'itinéraire",
|
||||
"dns": "Options DNS",
|
||||
"inbound": "Options entrantes",
|
||||
"mux": "MultiPlexeur",
|
||||
"outbound": "Options sortantes",
|
||||
"tlsTricks": "Astuces TLS",
|
||||
"warp": "Options de WARP ",
|
||||
"misc": "Diverses options"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Consentement du Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP est un fournisseur VPN WireGuard gratuit. En activant cette option, vous acceptez les ${tos(Terms of Service)} et ${privacy(Privacy Policy)} de Cloudflare WARP."
|
||||
},
|
||||
"generateWarpConfig": "Générer une configuration WARP",
|
||||
"missingWarpConfig": "Configuration WARP manquante",
|
||||
"warpConfigGenerated": "La configuration WARP est générée",
|
||||
"pageTitle": "Options de configuration",
|
||||
"logLevel": "Niveau de journalisation",
|
||||
"blockAds": "Bloquer les publicités",
|
||||
"resolveDestination": "Résoudre la destination",
|
||||
"ipv6Mode": "Itinéraire IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Désactiver",
|
||||
"enable": "Activer",
|
||||
"prefer": "Préféré",
|
||||
"only": "Exclusif"
|
||||
},
|
||||
"remoteDnsAddress": "DNS distant",
|
||||
"remoteDnsDomainStrategy": "Stratégie de domaine DNS distant",
|
||||
"directDnsAddress": "DNS direct",
|
||||
"directDnsDomainStrategy": "Stratégie de domaine DNS direct",
|
||||
"mixedPort": "Port mixte",
|
||||
"tproxyPort": "Port proxy transparent",
|
||||
"localDnsPort": "Port DNS local",
|
||||
"allowConnectionFromLan": "Partager un VPN sur un réseau local",
|
||||
"tunImplementation": "Implémentation du TUN",
|
||||
"mtu": "Taille du paquet (MTU)",
|
||||
"connectionTestUrl": "URL de test de connexion",
|
||||
"urlTestInterval": "Intervalle de test d'URL",
|
||||
"enableClashApi": "Activer l'API Clash",
|
||||
"clashApiPort": "Port API de conflit",
|
||||
"enableTun": "Activer TUN",
|
||||
"setSystemProxy": "Définir le proxy système",
|
||||
"enableDnsRouting": "Activer le routage DNS",
|
||||
"enableFakeDns": "Activer le faux DNS",
|
||||
"bypassLan": "Contourner le réseau local",
|
||||
"strictRoute": "Itinéraire strict",
|
||||
"enableTlsFragment": "Activer le fragment TLS",
|
||||
"tlsFragmentSize": "Taille des fragments TLS",
|
||||
"tlsFragmentSleep": "Veille des fragments TLS",
|
||||
"enableTlsMixedSniCase": "Activer le cas TLS Mixed SNI",
|
||||
"enableTlsPadding": "Activer TLS Padding",
|
||||
"tlsPaddingSize": "TLS Padding",
|
||||
"enableMux": "Activer MUX",
|
||||
"muxProtocol": "Protocole MUX",
|
||||
"muxMaxStreams": "Flux simultanés maximum",
|
||||
"enableWarp": "Activer WARP",
|
||||
"warpDetourMode": "Mode détour",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "Proxy de détour via WARP",
|
||||
"warpOverProxy": "Détour WARP via des proxys",
|
||||
"inbound": "Détour WARP via des proxys",
|
||||
"outbound": "Proxy de détour via WARP"
|
||||
},
|
||||
"warpLicenseKey": "Clé de licence",
|
||||
"warpCleanIp": "IP propre",
|
||||
"warpPort": "Port",
|
||||
"warpNoise": "Nombre de bruit",
|
||||
"warpNoiseSize": "Taille du bruit",
|
||||
"warpNoiseMode": "Mode bruit",
|
||||
"warpNoiseDelay": "Retard de bruit"
|
||||
},
|
||||
"window": {
|
||||
"hide": "Cacher",
|
||||
"close": "Sortir",
|
||||
"alertMessage": "Cacher ou quitter l'application ?",
|
||||
"remember": "Se souvenir de mon choix"
|
||||
}
|
||||
}
|
||||
@@ -1,420 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Set Ulang",
|
||||
"toggle": {
|
||||
"enabled": "Mengaktifkan",
|
||||
"disabled": "Menonaktifkan"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Menonaktifkan"
|
||||
},
|
||||
"sort": "Urutkan",
|
||||
"sortBy": "Urut Berdasarkan",
|
||||
"addToClipboard": "Tambah ke Clipboard",
|
||||
"notSet": "Tidak Diatur",
|
||||
"agree": "Setuju",
|
||||
"decline": "Tolak",
|
||||
"unknown": "Tidak Dikenal",
|
||||
"hidden": "Tersembunyi",
|
||||
"timeout": "Waktu habis",
|
||||
"clipboardExportSuccessMsg": "Ditambahkan ke Papan Klip",
|
||||
"showMore": "Menampilkan lebih banyak",
|
||||
"showLess": "Tampilkan Lebih Sedikit",
|
||||
"openAppSettings": "Buka Pengaturan Aplikasi",
|
||||
"grantPermission": "Memberikan ijin"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "lanjut berarti setuju dengan ${tap(@:about.termsAndConditions)}",
|
||||
"start": "Mulai"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Utama",
|
||||
"emptyProfilesMsg": "Mulai menambahkan langganan profil",
|
||||
"noActiveProfileMsg": "Pilih profil"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Trafik Langsung",
|
||||
"trafficLive": "Lalu Lintas Langsung",
|
||||
"trafficTotal": "Total Trafik",
|
||||
"uplink": "Uplink",
|
||||
"downlink": "Downlink",
|
||||
"connection": "Sambungan",
|
||||
"speed": "Kecepatan",
|
||||
"totalTransferred": "Jumlah yang Ditransfer"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Beberapa Profil",
|
||||
"detailsPageTitle": "Profil",
|
||||
"activeProfileNameSemanticLabel": "Nama profil aktif: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "Tampilkan semua profil.",
|
||||
"nonActiveProfileBtnSemanticLabel": "Pilih \"${name}\" sebagai profil aktif.",
|
||||
"subscription": {
|
||||
"traffic": "Trafik",
|
||||
"updatedTimeAgo": "${timeago} diperbarui",
|
||||
"remainingDuration": "Tersisa ${duration} hari lagi",
|
||||
"remainingTrafficSemanticLabel": "${consumed}/${total} trafik terpakai",
|
||||
"expired": "Kadaluarsa",
|
||||
"noTraffic": "Kuota Habis",
|
||||
"upload": "Mengunggah",
|
||||
"download": "Unduh",
|
||||
"total": "Jumlah Lalu Lintas",
|
||||
"expireDate": "Tanggal kadaluarsa"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "Baru diperbaharui",
|
||||
"name": "Alphabetikal"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "Profil Baru",
|
||||
"shortBtnTxt": "Profil Baru",
|
||||
"fromClipboard": "Tambah dari Clipboard",
|
||||
"scanQr": "Pindai QR",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "Izin ditolak",
|
||||
"unexpectedError": "Terjadi masalah",
|
||||
"torchSemanticLabel": "Lampu Flash",
|
||||
"facingSemanticLabel": "Hadap Kamera",
|
||||
"permissionRequest": "Izin ke kamera untuk memindai Kode QR"
|
||||
},
|
||||
"manually": "Isian Manual",
|
||||
"addWarp": "Tambahkan WARP",
|
||||
"addingWarpMsg": "Mohon tunggu selagi kami mendaftarkan WARP.",
|
||||
"addingProfileMsg": "Tambahkan Profil",
|
||||
"failureMsg": "Gagal tambahkan profil"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Perbarui",
|
||||
"tooltip": "Profil terbaru",
|
||||
"updateSubscriptions": "Perbarui Langganan",
|
||||
"failureMsg": "Gagal perbarui profil",
|
||||
"successMsg": "Sukses perbarui profil",
|
||||
"namedFailureMsg": "Gagal perbarui \"${name}\"",
|
||||
"namedSuccessMsg": "Sukses perbarui \"${name}\""
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Bagi",
|
||||
"exportToClipboardSuccess": "Taruh ke clipboard",
|
||||
"exportSubLinkToClipboard": "Taruh link langganan ke clipboard",
|
||||
"subLinkQrCode": "Link Langganan QR",
|
||||
"exportConfigToClipboard": "Taruh konfigurasi ke clipboard",
|
||||
"exportConfigToClipboardSuccess": "Salin konfigurasi ke clipboard"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Ubah",
|
||||
"selectActiveTxt": "Pilih profil aktif"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Hapus",
|
||||
"confirmationMsg": "Hapus profil permanen?",
|
||||
"successMsg": "Sukses hapus profil"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Simpan",
|
||||
"successMsg": "Sukses simpan profil",
|
||||
"failureMsg": "Gagal simpan profil"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "Nama",
|
||||
"nameHint": "Nama Profil",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "URL Lengkap",
|
||||
"emptyNameMsg": "Nama diwajibkan",
|
||||
"invalidUrlMsg": "URL Salah",
|
||||
"lastUpdate": "Terakhir diperbarui",
|
||||
"updateInterval": "Perbarui otomatis",
|
||||
"updateIntervalDialogTitle": "Interval perbarui otomatis (dalam jam)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Proxy",
|
||||
"emptyProxiesMsg": "Tidak ada proxy",
|
||||
"delayTestTooltip": "Test delay",
|
||||
"sortTooltip": "Urut Proxy",
|
||||
"checkIp": "Periksa IP",
|
||||
"unknownIp": "IP tidak dikenal",
|
||||
"sortOptions": {
|
||||
"unsorted": "Awal",
|
||||
"name": "Alfabetikal",
|
||||
"delay": "Berdasarkan Delay"
|
||||
},
|
||||
"activeProxySemanticLabel": "Proksi Aktif",
|
||||
"delaySemantics": {
|
||||
"result": "Penundaan: ${delay}ms",
|
||||
"timeout": "Batas Waktu Uji Tunda",
|
||||
"testing": "Penundaan: Menguji..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "Alamat IP",
|
||||
"country": "Negara"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Log",
|
||||
"filterHint": "Filter",
|
||||
"allLevelsFilter": "Semua",
|
||||
"shareCoreLogs": "Bagikan Log Inti",
|
||||
"shareAppLogs": "Bagikan Log Aplikasi",
|
||||
"pauseTooltip": "Jeda",
|
||||
"resumeTooltip": "Lanjut",
|
||||
"clearTooltip": "Bersih"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Setting",
|
||||
"requiresRestartMsg": "Untuk mencoba restart aplikasi",
|
||||
"experimental": "Eksperimen",
|
||||
"experimentalMsg": "Fitur dengan tanda Eksperimen masih dalam pengembangan dan resiko bermasalah.",
|
||||
"exportOptions": "Salin Opsi Anonim ke Papan Klip",
|
||||
"exportAllOptions": "Salin Semua Opsi ke Clipboard",
|
||||
"importOptions": "Impor Opsi Dari Clipboard",
|
||||
"importOptionsMsg": "Ini akan menulis ulang semua opsi konfigurasi dengan nilai yang diberikan. Apa kamu yakin?",
|
||||
"general": {
|
||||
"sectionTitle": "Umum",
|
||||
"locale": "Bahasa",
|
||||
"region": "Region",
|
||||
"regionMsg": "Bantu tetapkan opsi standar untuk melewati alamat lokal",
|
||||
"regions": {
|
||||
"ir": "İran (ir)",
|
||||
"cn": "Çin (cn)",
|
||||
"ru": "Russia (ru)",
|
||||
"af": "Afghanistan (af)",
|
||||
"id": "Indonesia (id)",
|
||||
"tr": "Turki (tr) 🇹🇷",
|
||||
"other": "Lainnya"
|
||||
},
|
||||
"themeMode": "Jenis Tema",
|
||||
"themeModes": {
|
||||
"system": "Ikut Tema Sistem",
|
||||
"dark": "Tema Gelap",
|
||||
"light": "Tema Cerah",
|
||||
"black": "Tema Hitam"
|
||||
},
|
||||
"enableAnalytics": "Mengaktifkan Analitik",
|
||||
"enableAnalyticsMsg": "Beri izin untuk mengumpulkan analisis dan mengirim laporan kegagalan untuk meningkatkan aplikasi",
|
||||
"autoStart": "Mulai saat Login",
|
||||
"silentStart": "Mulai Minimalkan",
|
||||
"openWorkingDir": "Buka Direktori Kerja",
|
||||
"ignoreBatteryOptimizations": "Menonaktifkan Optimisasi Baterai",
|
||||
"ignoreBatteryOptimizationsMsg": "Hapus batasan untuk performa VPN yang optimal",
|
||||
"dynamicNotification": "Tampilkan Kecepatan di notifikasi",
|
||||
"hapticFeedback": "Umpan Balik Haptik",
|
||||
"autoIpCheck": "Secara Otomatis Memeriksa IP Koneksi"
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Mode Lanjut",
|
||||
"debugMode": "Mode Debug",
|
||||
"debugModeMsg": "Restart aplikasi untuk menerapkan perubahan",
|
||||
"memoryLimit": "Limit Memori",
|
||||
"memoryLimitMsg": "Aktifkan jika kamu mendapatkan error habis memori atau error aplikasi yang sering",
|
||||
"resetTunnel": "Set ulang profil VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Per-app Proxy",
|
||||
"perAppProxyModes": {
|
||||
"off": "Semua",
|
||||
"offMsg": "Proxy semua applikasi",
|
||||
"include": "Proxy",
|
||||
"includeMsg": "Proxy untuk aplikasi terpilih",
|
||||
"exclude": "Bypass",
|
||||
"excludeMsg": "Tidak proxy untuk aplikasi terpilih"
|
||||
},
|
||||
"showSystemApps": "Tampil aplikasi sistem",
|
||||
"hideSystemApps": "Sembunyikan aplikasi sistem",
|
||||
"clearSelection": "Bersihkan seleksi"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Rute Aset",
|
||||
"geoip": "Geoip",
|
||||
"geosite": "Geosite",
|
||||
"version": "Versi ${version}",
|
||||
"fileMissing": "File Hilang",
|
||||
"update": "Perbarui",
|
||||
"download": "Unduh",
|
||||
"failureMsg": "Gagal perbarui aset",
|
||||
"successMsg": "Sukses perbarui aset",
|
||||
"addRecommended": "Tambah aset rekomendasi",
|
||||
"missingGeoAssetsMsg": "Routing aset terpilih filenya hilang. Silahkan unduh atau pilih dari yang ada"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "Tentang",
|
||||
"version": "Versi",
|
||||
"sourceCode": "Code Sumber",
|
||||
"telegramChannel": "Kanal Telegram",
|
||||
"checkForUpdate": "Periksa perbaruan",
|
||||
"privacyPolicy": "Kebijakan Privasi",
|
||||
"termsAndConditions": "Syarat dan Ketentuan Umum"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "Sudah menggunakan versi terakhir",
|
||||
"dialogTitle": "Perbaruan Tersedia",
|
||||
"updateMsg": "Versi terbaru @:general.appTitle tersedia. Ingin di perbarui sekarang?",
|
||||
"currentVersionLbl": "Versi Sekarang",
|
||||
"newVersionLbl": "Versi Baru",
|
||||
"updateNowBtnTxt": "Perbarui Sekarang",
|
||||
"laterBtnTxt": "Nanti",
|
||||
"ignoreBtnTxt": "Lewati"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Dashboard",
|
||||
"quit": "Keluar",
|
||||
"open": "Buka",
|
||||
"status": {
|
||||
"connect": "Sambung",
|
||||
"connecting": "Menyambungkan",
|
||||
"disconnect": "Putus",
|
||||
"disconnecting": "Memutuskan"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Error Tidak Terduga",
|
||||
"clash": {
|
||||
"unexpected": "Error Tidak Terduga",
|
||||
"core": "Clash Error ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Servis Error Tidak Terduga",
|
||||
"serviceNotRunning": "Servis tidak berjalan",
|
||||
"missingPrivilege": "Hak Akses Hilang",
|
||||
"missingPrivilegeMsg": "Mode VPN membutuhkan hak akses administrator. Antara buka ulang aplikasi sebagai administrator atau rubah mode servis",
|
||||
"missingGeoAssets": "Geo Aset Hilang",
|
||||
"missingGeoAssetsMsg": "Geo aset hilang. Pertimbangkan merubah aset aktif atau unduh yang sudah dipilih di seting",
|
||||
"invalidConfigOptions": "Pilihan konfigurasi tidak valid",
|
||||
"invalidConfig": "Konfigurasi tidak valid",
|
||||
"create": "Pembuatan Servis Error",
|
||||
"start": "Jalankan Servis Error"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Kegagalan tidak terduga",
|
||||
"missingVpnPermission": "Izin VPN Hilang",
|
||||
"missingNotificationPermission": "Izin Notifikasi Hilang",
|
||||
"core": "Error Inti"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Error Tidak Terduga",
|
||||
"notFound": "Profil tidak ditemukan",
|
||||
"invalidConfig": "Konfigurasi tidak valid",
|
||||
"invalidUrl": "URL tidak valid"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Sambungan error tidak terduga",
|
||||
"timeout": "Waktu Sambungan Habis",
|
||||
"badResponse": "Response Rusak",
|
||||
"connectionError": "Sambungan Error",
|
||||
"badCertificate": "Sertifikat Rusak"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Error Tidak Terduga",
|
||||
"notUpdate": "Perbaruan tidak tersedia",
|
||||
"activeNotFound": "Geo Aset Aktif tidak ditemukan"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (Preview)",
|
||||
"short_description": "Otomatik, SSH, VLESS, Vmess, Trojan, Reality, Sing-Box, Clash, Xray, Shadowsocks",
|
||||
"full_description": "Tujuan utama Hiddify adalah memberikan keamanan, user-friendly dan client tunnel yg efisien. Hiddify mengizinkanmu untuk mengarahkan semua atau beberapa trafik data aplikasi terpilih ke server remot pilihanmu, memanfaatkan izin VPN-Service.\n\nNote: Kami tidak menyediakan server apapun; pengguna diwajibkan untuk memastikan aktivitas online mereka tetap private dengan menggunakan self-hosted server atau server yg dipercaya pilihan mereka sendiri. \n \nKami mendukung server dengan:\n- Normal V2ray/Xray Subscription Link\n- Clash Subscription Link\n- Sing-Box Subscription Link\n\nApa fitur unik kami?\n - User Friendly\n - Cepat dan teroptimasi\n - Otomatis pilihan PING terendah \n - Menampilkan informasi penggunaan user\n - Dengan mudah import sublink dengan satu klik menggunakan deeplinking \n - Bebas dan tanpa iklan\n - Dengan mudah berganti user sublink\n - dan sebagainya\n\nSupport:\n- Semua protokol di dukung oleh Sing-Box \n- VLESS + xtls reality, vision\n- VMESS\n- Trojan\n- ShadowSocks\n- Reality\n- V2ray\n- Hystria2\n- TUIC\n- SSH\n- ShadowTLS\n\n\nCode Sumber ada di https://github.com/hiddify/Hiddify-Next\nInti Aplikasi didasarkan pada Sing-Box Open Source.\n\nDeskripsi Izin:\n- VPN Servis: Tujuan aplikasi ini menyediakan keamanan, user-friendly dan tunneling client efisien, kami membutuhkan izin untuk bisa mengarahkan traffic data melalui kanal remot server. \n- QUERY ALL PACKAGES: izin ini digunakan untuk memperbolehkan pengguna masuk atau mengeluarkan aplikasi tertentu untuk tunneling.\n- RECEIVE BOOT COMPLETED: izin ini dapat diaktifkan atau dinonaktifkan dari setting aplikasi untuk mengaktikan aplikasi ini saat boot device.\n- POST NOTIFICATIONS: izin ini penting karena kami menggunakan foreground service untuk memastikan operasi berkelanjutan dari VPN Servis.\n- Aplikasi ini bebas dari iklan. Analitik dan data crash hanya terjadi dengan persetujuan eksplisit dari pengguna pada saat penggunaan pertama kali"
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Ketuk untuk Sambung",
|
||||
"connecting": "Sambungkan",
|
||||
"disconnecting": "Putus Sambungan",
|
||||
"connected": "Tersambung",
|
||||
"reconnect": "Hubungkan kembali",
|
||||
"connectAnyWay": "Menghubung",
|
||||
"experimentalNotice": "Fitur Experimental digunakan",
|
||||
"experimentalNoticeMsg": "Kamu telah mengaktifkan fitur experimental yang mungkin mempengaruhi kualitas sambungan dan error tidak terduga. Kamu tetap bisa merubah atau set ulang opsi dari Halaman Konfigurasi",
|
||||
"disableExperimentalNotice": "Jangan tampil lagi",
|
||||
"reconnectMsg": "Menghubungkan kembali untuk memperhitungkan perubahan..."
|
||||
},
|
||||
"config": {
|
||||
"resetBtn": "Set Ulang Opsi",
|
||||
"serviceMode": "Sambung ulang agar perubahan diterapkan",
|
||||
"quickSettings": "Pengaturan Cepat",
|
||||
"setupWarp": "Siapkan WARP",
|
||||
"allOptions": "Semua Opsi Konfigurasi",
|
||||
"serviceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Sistem Proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "Layanan VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proksi",
|
||||
"systemProxy": "Proksi Sistem",
|
||||
"tun": "VPN",
|
||||
"tunService": "Layanan VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "Opsi Route",
|
||||
"dns": "Opsi DNS",
|
||||
"inbound": "Opsi Inbound",
|
||||
"mux": "Multiplexer",
|
||||
"outbound": "Opsi Outbound",
|
||||
"tlsTricks": "TLS Tricks",
|
||||
"warp": "Opsi WARP",
|
||||
"misc": "Opsi Misc"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Persetujuan Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP adalah WireGuard VPN Provider gratis. Dengan mengaktifkan opsi/pilihan ini berarti kamu setuju pada Cloudflare WARP's ${tos(Terms of Service)} dan ${privacy(Privacy Policy)}."
|
||||
},
|
||||
"generateWarpConfig": "Hasilkan Konfigurasi WARP",
|
||||
"missingWarpConfig": "Konfigurasi WARP tidak ada",
|
||||
"warpConfigGenerated": "Konfigurasi WARP Dibuat",
|
||||
"pageTitle": "Opsi Konfig",
|
||||
"logLevel": "Log Level",
|
||||
"blockAds": "Blokir Iklan",
|
||||
"resolveDestination": "Resolve Destination",
|
||||
"ipv6Mode": "IPv6 Route",
|
||||
"ipv6Modes": {
|
||||
"disable": "Nonaktifkan",
|
||||
"enable": "Aktifkan",
|
||||
"prefer": "Prefer",
|
||||
"only": "Exclusive"
|
||||
},
|
||||
"remoteDnsAddress": "Remote DNS",
|
||||
"remoteDnsDomainStrategy": "Remote DNS Domain Strategy",
|
||||
"directDnsAddress": "Direct DNS",
|
||||
"directDnsDomainStrategy": "Direct DNS Domain Strategy",
|
||||
"mixedPort": "Mixed Port",
|
||||
"tproxyPort": "Port Proksi Transparan",
|
||||
"localDnsPort": "DNS Port Lokal",
|
||||
"allowConnectionFromLan": "Perbolehkan Sambungan LAN",
|
||||
"tunImplementation": "Implementasi TUN",
|
||||
"mtu": "Ukuran Paket (MTU)",
|
||||
"connectionTestUrl": "URL Tes Sambungan",
|
||||
"urlTestInterval": "URL Test Interval",
|
||||
"enableClashApi": "Aktifkan Clash API",
|
||||
"clashApiPort": "Clash API Port",
|
||||
"enableTun": "Aktifkan TUN",
|
||||
"setSystemProxy": "Atur Sistem Proxy",
|
||||
"enableDnsRouting": "Aktifkan DNS Routing",
|
||||
"enableFakeDns": "Aktifkan DNS Palsu",
|
||||
"bypassLan": "Bypass LAN",
|
||||
"strictRoute": "Strict Route",
|
||||
"enableTlsFragment": "Aktifkan TLS Fragment",
|
||||
"tlsFragmentSize": "TLS Fragment Size",
|
||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||
"enableTlsMixedSniCase": "Aktifkan TLS Mixed SNI Case",
|
||||
"enableTlsPadding": "Aktifkan TLS Padding",
|
||||
"tlsPaddingSize": "TLS Padding",
|
||||
"enableMux": "Enable Mux",
|
||||
"muxProtocol": "Mux Protocol",
|
||||
"muxMaxStreams": "Max Concurrent Streams",
|
||||
"enableWarp": "Enable WARP",
|
||||
"warpDetourMode": "Detour Mode",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "Memutar Proxy Melalui WARP",
|
||||
"warpOverProxy": "Jalan memutar WARP Melalui Proxy",
|
||||
"inbound": "Detour WARP through proxies",
|
||||
"outbound": "Detour proxies through WARP"
|
||||
},
|
||||
"warpLicenseKey": "License Key",
|
||||
"warpCleanIp": "Clean IP",
|
||||
"warpPort": "Port",
|
||||
"warpNoise": "Noise",
|
||||
"warpNoiseSize": "Ukuran Kebisingan",
|
||||
"warpNoiseMode": "Modus Kebisingan",
|
||||
"warpNoiseDelay": "Penundaan Kebisingan"
|
||||
}
|
||||
}
|
||||
@@ -1,420 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Restaurar",
|
||||
"toggle": {
|
||||
"enabled": "Habilitado",
|
||||
"disabled": "Desabilitado"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Desabilitar"
|
||||
},
|
||||
"sort": "Ordernar",
|
||||
"sortBy": "Ordenar Por",
|
||||
"addToClipboard": "Adicionar à área de transferência",
|
||||
"notSet": "Não configurado",
|
||||
"agree": "Aceitar",
|
||||
"decline": "Recusar",
|
||||
"unknown": "Desconhecido",
|
||||
"hidden": "Escondido",
|
||||
"timeout": "Tempo Esgotado",
|
||||
"clipboardExportSuccessMsg": "Adicionado à área de transferência",
|
||||
"showMore": "Mostre mais",
|
||||
"showLess": "Mostre menos",
|
||||
"openAppSettings": "Abra as configurações do aplicativo",
|
||||
"grantPermission": "Conceder permissão"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "ao continuar você concorda com ${tap( @:about.termsAndConditions)}",
|
||||
"start": "Começar"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Inicio",
|
||||
"emptyProfilesMsg": "Comece adicionando um perfil de assinatura",
|
||||
"noActiveProfileMsg": "Escolha um perfil"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Tráfego",
|
||||
"trafficLive": "Tráfego ao vivo",
|
||||
"trafficTotal": "Tráfego total",
|
||||
"uplink": "Ligação ascendente",
|
||||
"downlink": "Link descendente",
|
||||
"connection": "Conexão",
|
||||
"speed": "Velocidade",
|
||||
"totalTransferred": "Total Transferido"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Perfis",
|
||||
"detailsPageTitle": "Perfil",
|
||||
"activeProfileNameSemanticLabel": "Nome do perfil ativo: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "Ver todos os perfis",
|
||||
"nonActiveProfileBtnSemanticLabel": "Selecione \"${name}\" como perfil ativo.",
|
||||
"subscription": {
|
||||
"traffic": "Tráfego",
|
||||
"updatedTimeAgo": "Atualizado ${timeago}",
|
||||
"remainingDuration": "${duration} dias restantes",
|
||||
"remainingTrafficSemanticLabel": "${consumed} de ${total} tráfego consumido",
|
||||
"expired": "Expirado",
|
||||
"noTraffic": "Fora da cota",
|
||||
"upload": "Upload",
|
||||
"download": "Download",
|
||||
"total": "Tráfego total",
|
||||
"expireDate": "Data de validade"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "Atualizado recentemente",
|
||||
"name": "Alfabeticamente"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "Novo Perfil",
|
||||
"shortBtnTxt": "Novo Perfil",
|
||||
"fromClipboard": "Adicionar da área de transferência",
|
||||
"scanQr": "Digitalize o código QR",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "Permissão Negada",
|
||||
"unexpectedError": "Algo deu errado",
|
||||
"torchSemanticLabel": "Luz do flash",
|
||||
"facingSemanticLabel": "Câmera voltada",
|
||||
"permissionRequest": "Permissão para a câmera digitalizar o QR Code"
|
||||
},
|
||||
"manually": "Entrada manual",
|
||||
"addWarp": "Adicionar WARP",
|
||||
"addingWarpMsg": "Aguarde enquanto registramos o WARP.",
|
||||
"addingProfileMsg": "Adicionando Perfil",
|
||||
"failureMsg": "Falha ao adicionar perfil"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Atualizar",
|
||||
"tooltip": "Atualizar Perfil",
|
||||
"updateSubscriptions": "Atualizar assinaturas",
|
||||
"failureMsg": "Falha ao atualizar perfil",
|
||||
"successMsg": "Perfil atualizado com sucesso",
|
||||
"namedFailureMsg": "Falha ao atualizar \"${name}\"",
|
||||
"namedSuccessMsg": "\"${name}\" atualizado com sucesso"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Compartilhar",
|
||||
"exportToClipboardSuccess": "Exportado para a área de transferência",
|
||||
"exportSubLinkToClipboard": "Exportar link de assinatura para a área de transferência",
|
||||
"subLinkQrCode": "Código QR do link de assinatura",
|
||||
"exportConfigToClipboard": "Exportar configuração para a área de transferência",
|
||||
"exportConfigToClipboardSuccess": "Configuração copiada para a área de transferência"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Editar",
|
||||
"selectActiveTxt": "Selecionar perfil ativo"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Deletar",
|
||||
"confirmationMsg": "Deletar perfil permanentemente?",
|
||||
"successMsg": "Perfil deletado com sucesso"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Salvar",
|
||||
"successMsg": "Perfil salvo com sucesso",
|
||||
"failureMsg": "Falha ao salvar perfil"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "Nome",
|
||||
"nameHint": "Nome do Perfil",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "URL de configuração completo",
|
||||
"emptyNameMsg": "Nome é obrigatório ",
|
||||
"invalidUrlMsg": "URL inválido",
|
||||
"lastUpdate": "Ultima Atualização",
|
||||
"updateInterval": "Atualização Automática ",
|
||||
"updateIntervalDialogTitle": "Intervalo de atualização automática (em horas)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Proxies",
|
||||
"emptyProxiesMsg": "Nenhum proxy disponível",
|
||||
"delayTestTooltip": "Atraso de teste",
|
||||
"sortTooltip": "Ordenar proxies",
|
||||
"checkIp": "Verifique o IP",
|
||||
"unknownIp": "IP desconhecido",
|
||||
"sortOptions": {
|
||||
"unsorted": "Padrão",
|
||||
"name": "Alfabeticamente",
|
||||
"delay": "Por atraso"
|
||||
},
|
||||
"activeProxySemanticLabel": "Proxy ativo",
|
||||
"delaySemantics": {
|
||||
"result": "atraso: ${delay}ms",
|
||||
"timeout": "atrasar o tempo limite do teste",
|
||||
"testing": "atraso: testando..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "Endereço de IP",
|
||||
"country": "País"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Histórico",
|
||||
"filterHint": "Filtro",
|
||||
"allLevelsFilter": "Todos",
|
||||
"shareCoreLogs": "Compartilhe registros principais",
|
||||
"shareAppLogs": "Compartilhe registros de aplicativos",
|
||||
"pauseTooltip": "Pausar",
|
||||
"resumeTooltip": "Resumir",
|
||||
"clearTooltip": "Limpar"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Configurações",
|
||||
"requiresRestartMsg": "Para que isso tenha efeito, reinicie o aplicativo",
|
||||
"experimental": "Experimental",
|
||||
"experimentalMsg": "Os recursos com sinalização Experimental ainda estão em desenvolvimento e podem causar problemas.",
|
||||
"exportOptions": "Copiar opções anônimas para a área de transferência",
|
||||
"exportAllOptions": "Copiar todas as opções para a área de transferência",
|
||||
"importOptions": "Opções de importação da área de transferência",
|
||||
"importOptionsMsg": "Isto irá reescrever todas as opções de configuração com os valores fornecidos. Tem certeza?",
|
||||
"general": {
|
||||
"sectionTitle": "Geral",
|
||||
"locale": "Linguagem",
|
||||
"region": "Região",
|
||||
"regionMsg": "Ajuda a definir opções padrão para ignorar endereços domésticos",
|
||||
"regions": {
|
||||
"ir": "Irã (ir)",
|
||||
"cn": "China (cn)",
|
||||
"ru": "Rússia (ru)",
|
||||
"af": "Afeganistão (af)",
|
||||
"id": "Indonesia (id)",
|
||||
"tr": "Turquia (tr) 🇹🇷",
|
||||
"other": "Outro"
|
||||
},
|
||||
"themeMode": "Modo de Tema",
|
||||
"themeModes": {
|
||||
"system": "Seguir o tema do sistema",
|
||||
"dark": "Modo Escuro",
|
||||
"light": "Modo Claro",
|
||||
"black": "Modo Preto"
|
||||
},
|
||||
"enableAnalytics": "Habilitar Análise",
|
||||
"enableAnalyticsMsg": "Dê permissão para coletar análises e enviar relatórios de falhas para melhorar o aplicativo",
|
||||
"autoStart": "Inicializar no login",
|
||||
"silentStart": "Inicializar minimizado",
|
||||
"openWorkingDir": "Abra o diretório de trabalho",
|
||||
"ignoreBatteryOptimizations": "Desative a otimização da bateria",
|
||||
"ignoreBatteryOptimizationsMsg": "Remova as restrições para obter o desempenho ideal da VPN",
|
||||
"dynamicNotification": "Exibir velocidade na notificação",
|
||||
"hapticFeedback": "Feedback tátil",
|
||||
"autoIpCheck": "Verifique automaticamente o IP da conexão"
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Avançado",
|
||||
"debugMode": "Modo de desenvolvedor",
|
||||
"debugModeMsg": "Reinicie o aplicativo para aplicar esta alteração",
|
||||
"memoryLimit": "Limite de memória",
|
||||
"memoryLimitMsg": "Ative se você estiver enfrentando erros de falta de memória ou travamentos frequentes do aplicativo",
|
||||
"resetTunnel": "Redefinir perfil VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Proxy por aplicativo",
|
||||
"perAppProxyModes": {
|
||||
"off": "Tudo",
|
||||
"offMsg": "Proxy de todos os aplicativos",
|
||||
"include": "Proxy",
|
||||
"includeMsg": "Aplicativos selecionados apenas por proxy",
|
||||
"exclude": "Ignorar",
|
||||
"excludeMsg": "Não faça proxy de aplicativos selecionados"
|
||||
},
|
||||
"showSystemApps": "Mostrar aplicativos do sistema",
|
||||
"hideSystemApps": "Ocultar aplicativos do sistema",
|
||||
"clearSelection": "Limpar seleção"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Ativos de roteamento",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "Geossítio",
|
||||
"version": "Versão ${version}",
|
||||
"fileMissing": "Arquivo faltando",
|
||||
"update": "Atualizar",
|
||||
"download": "Download",
|
||||
"failureMsg": "Falha ao atualizar o recurso",
|
||||
"successMsg": "Recurso atualizado com sucesso",
|
||||
"addRecommended": "Adicionar recursos recomendados",
|
||||
"missingGeoAssetsMsg": "Os arquivos dos ativos de roteamento selecionados estão ausentes. Baixe-os ou escolha os existentes."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "Sobre",
|
||||
"version": "Versão",
|
||||
"sourceCode": "Código fonte",
|
||||
"telegramChannel": "Canal Telegram",
|
||||
"checkForUpdate": "Verifique atualizações",
|
||||
"privacyPolicy": "Política de Privacidade",
|
||||
"termsAndConditions": "Termos e Condições"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "Já usando a versão mais recente",
|
||||
"dialogTitle": "Atualização disponível",
|
||||
"updateMsg": "Uma nova versão de @:general.appTitle está disponível. Gostaria de atualizar agora?",
|
||||
"currentVersionLbl": "Versão Atual",
|
||||
"newVersionLbl": "Nova versão",
|
||||
"updateNowBtnTxt": "Atualizar agora",
|
||||
"laterBtnTxt": "Mais tarde",
|
||||
"ignoreBtnTxt": "Ignorar"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Painel",
|
||||
"quit": "Sair",
|
||||
"open": "Abrir",
|
||||
"status": {
|
||||
"connect": "Conectar",
|
||||
"connecting": "Conectando",
|
||||
"disconnect": "desconectar",
|
||||
"disconnecting": "Desconectando"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Erro inesperado",
|
||||
"clash": {
|
||||
"unexpected": "Erro inesperado",
|
||||
"core": "Erro de conflito ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Erro de serviço inesperado",
|
||||
"serviceNotRunning": "O serviço não está em execução",
|
||||
"missingPrivilege": "Privilégio ausente",
|
||||
"missingPrivilegeMsg": "O modo VPN requer privilégios de administrador. Reinicie o aplicativo como administrador ou altere o modo de serviço.",
|
||||
"missingGeoAssets": "Recursos geográficos ausentes",
|
||||
"missingGeoAssetsMsg": "Os recursos geográficos estão faltando. considere alterar o recurso ativo ou baixar um selecionado nas configurações.",
|
||||
"invalidConfigOptions": "Opções de configuração inválidas",
|
||||
"invalidConfig": "Configuração inválida",
|
||||
"create": "Erro ao criar serviço",
|
||||
"start": "Erro de inicialização do serviço"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Falha inesperada",
|
||||
"missingVpnPermission": "Permissão VPN ausente",
|
||||
"missingNotificationPermission": "Permissão de notificação ausente",
|
||||
"core": "Erro central"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Erro inesperado",
|
||||
"notFound": "Perfil Não Encontrado",
|
||||
"invalidConfig": "Configurações inválidas",
|
||||
"invalidUrl": "URL inválida"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Erro de conexão inesperado",
|
||||
"timeout": "Tempo limite de conexão",
|
||||
"badResponse": "Erro na Resposta",
|
||||
"connectionError": "Erro de conexão",
|
||||
"badCertificate": "Erro no certificado"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Erro inesperado",
|
||||
"notUpdate": "Nenhuma atualização disponível",
|
||||
"activeNotFound": "Recurso geográfico ativo não encontrado"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (Pré-visualização)",
|
||||
"short_description": "Auto, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, XRay, Shadowsocks",
|
||||
"full_description": "O principal objetivo do Hiddify é fornecer um cliente de tunelamento seguro, fácil de usar e eficiente. Ele permite que você direcione todo o tráfego ou tráfego de aplicativo selecionado para um servidor remoto de sua escolha, utilizando a permissão do serviço VPN.<inlang-LineFeed>\nNota: Não fornecemos nenhum servidor; os usuários são obrigados a garantir que suas atividades online permaneçam privadas usando seu próprio servidor auto-hospedado ou servidores confiáveis.<inlang-LineFeed>\nOferecemos suporte a servidores com:\n- Link de assinatura V2Ray/XRay normal\n- Link de assinatura do Clash\n- Link de assinatura do Sing-Box<inlang-LineFeed>\nQuais são os nossos recursos exclusivos?\n- Amigo do usuário\n- Otimizado e rápido\n- Selecione automaticamente o LowerPing\n- Mostrar informações de uso do usuário\n- Importe facilmente sublinks com um clique usando deeplinking\n- Gratuito e sem anúncios\n- Alterne facilmente sublinks de usuários\n- Mais e mais<inlang-LineFeed>\nApoiar:\n- Todos os protocolos suportados pelo Sing-Box\n- VLESS + XTLS Realidade, Visão\n- VMess\n- Trojan\n- ShadowSocks\n- Realidade\n- WireGuard\n-V2Ray\n- Histeria2\n-TUICv5\n-SSH\n- ShadowTLS<inlang-LineFeed><inlang-LineFeed>\nO código-fonte existe em https://github.com/hiddify/Hiddify-Next\nO núcleo do aplicativo é baseado no Sing-Box de código aberto.<inlang-LineFeed>\nDescrição da permissão:\n- Serviço VPN: Como o objetivo desta aplicação é fornecer um cliente de tunelamento seguro, fácil de usar e eficiente, precisamos dessa permissão para poder rotear o tráfego via túnel para o servidor remoto.\n- CONSULTAR TODOS OS PACOTES: Esta permissão é usada para permitir que os usuários incluam ou excluam aplicativos específicos para tunelamento.\n- RECEBER BOOT COMPLETED: Esta permissão pode ser habilitada ou desabilitada nas configurações do aplicativo para ativar este aplicativo na inicialização do dispositivo.\n- PÓS NOTIFICAÇÕES: Esta permissão é essencial, pois empregamos um serviço de primeiro plano para garantir a operação contínua do serviço VPN.\n- Este aplicativo está livre de anúncios. A análise e os dados de travamento só ocorrem com o consentimento explícito do usuário na primeira utilização do aplicativo."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Toque para conectar",
|
||||
"connecting": "Conectando",
|
||||
"disconnecting": "Desconectando",
|
||||
"connected": "Conectado",
|
||||
"reconnect": "Reconectar",
|
||||
"connectAnyWay": "Conectar",
|
||||
"experimentalNotice": "Recursos experimentais em uso",
|
||||
"experimentalNoticeMsg": "Você ativou alguns recursos experimentais que podem afetar a qualidade da conexão e causar erros inesperados. Você sempre pode alterar ou redefinir essas opções na página de opções de configuração.",
|
||||
"disableExperimentalNotice": "Não mostrar novamente",
|
||||
"reconnectMsg": "Reconectando por levar em conta as mudanças..."
|
||||
},
|
||||
"config": {
|
||||
"resetBtn": "Redefinir opções",
|
||||
"serviceMode": "Modo de serviço",
|
||||
"quickSettings": "Configurações rápidas",
|
||||
"setupWarp": "Configurar WARP",
|
||||
"allOptions": "Todas as opções de configuração",
|
||||
"serviceModes": {
|
||||
"proxy": "Somente serviço de proxy",
|
||||
"systemProxy": "Definir proxy do sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Serviço VPN"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Procuração",
|
||||
"systemProxy": "Proxy do sistema",
|
||||
"tun": "VPN",
|
||||
"tunService": "Serviço VPN"
|
||||
},
|
||||
"section": {
|
||||
"route": "Opções de rota",
|
||||
"dns": "Opções de DNS",
|
||||
"inbound": "Opções de entrada",
|
||||
"mux": "Multiplexador",
|
||||
"outbound": "Opções de saída",
|
||||
"tlsTricks": "Truques TLS",
|
||||
"warp": "Opções de WARP",
|
||||
"misc": "Opções diversas"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Consentimento WARP da Cloudflare",
|
||||
"description(rich)": "Cloudflare WARP é um provedor VPN WireGuard gratuito. Ao ativar esta opção, você concorda com os ${tos(Termos de Serviço)} e ${privacy(Política de Privacidade)} do WARP da Cloudflare."
|
||||
},
|
||||
"generateWarpConfig": "Gerar configuração WARP",
|
||||
"missingWarpConfig": "Configuração WARP ausente",
|
||||
"warpConfigGenerated": "A configuração WARP é gerada",
|
||||
"pageTitle": "Opções de configuração",
|
||||
"logLevel": "Nível de registro",
|
||||
"blockAds": "Bloquear anúncios",
|
||||
"resolveDestination": "Resolver destino",
|
||||
"ipv6Mode": "Rota IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Desabilitar",
|
||||
"enable": "Habilitar",
|
||||
"prefer": "Preferido",
|
||||
"only": "Exclusivo"
|
||||
},
|
||||
"remoteDnsAddress": "DNS remoto",
|
||||
"remoteDnsDomainStrategy": "Estratégia de Domínio DNS Remoto",
|
||||
"directDnsAddress": "DNS direto",
|
||||
"directDnsDomainStrategy": "Estratégia de Domínio DNS Direto",
|
||||
"mixedPort": "Porta Mista",
|
||||
"tproxyPort": "Porta proxy transparente",
|
||||
"localDnsPort": "Porta DNS local",
|
||||
"allowConnectionFromLan": "Permitir conexão da LAN",
|
||||
"tunImplementation": "Implementação TUN",
|
||||
"mtu": "Tamanho do pacote (MTU)",
|
||||
"connectionTestUrl": "URL de teste de conexão",
|
||||
"urlTestInterval": "Intervalo de teste de URL",
|
||||
"enableClashApi": "Ativar API Clash",
|
||||
"clashApiPort": "Porta da API Clash",
|
||||
"enableTun": "Ativar TUN",
|
||||
"setSystemProxy": "Definir proxy do sistema",
|
||||
"enableDnsRouting": "Habilitar roteamento DNS",
|
||||
"enableFakeDns": "Habilitar DNS falso",
|
||||
"bypassLan": "Ignorar LAN",
|
||||
"strictRoute": "Rota Estrita",
|
||||
"enableTlsFragment": "Habilitar fragmento TLS",
|
||||
"tlsFragmentSize": "Tamanho do fragmento TLS",
|
||||
"tlsFragmentSleep": "Suspensão do fragmento TLS",
|
||||
"enableTlsMixedSniCase": "Habilitar caso SNI misto TLS",
|
||||
"enableTlsPadding": "Habilitar preenchimento TLS",
|
||||
"tlsPaddingSize": "Preenchimento TLS",
|
||||
"enableMux": "Habilitar Mux",
|
||||
"muxProtocol": "Protocolo Mux",
|
||||
"muxMaxStreams": "Máximo de fluxos simultâneos",
|
||||
"enableWarp": "Habilitar WARP",
|
||||
"warpDetourMode": "Modo de desvio",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "Proxies de desvio através do WARP",
|
||||
"warpOverProxy": "Desvio WARP através de proxies",
|
||||
"inbound": "Desvie o WARP através de proxies",
|
||||
"outbound": "Desviar proxies através do WARP"
|
||||
},
|
||||
"warpLicenseKey": "Chave de licença",
|
||||
"warpCleanIp": "Limpar IP",
|
||||
"warpPort": "Porta",
|
||||
"warpNoise": "Contagem de ruído",
|
||||
"warpNoiseSize": "Tamanho do ruído",
|
||||
"warpNoiseMode": "Modo de ruído",
|
||||
"warpNoiseDelay": "Atraso de ruído"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Сброс",
|
||||
"toggle": {
|
||||
"enabled": "Включено",
|
||||
"disabled": "Отключено"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Отключить"
|
||||
},
|
||||
"sort": "Сортировка",
|
||||
"sortBy": "Сортировка",
|
||||
"addToClipboard": "Копировать в буфер обмена",
|
||||
"notSet": "Не задано",
|
||||
"agree": "Согласиться",
|
||||
"decline": "Отклонить",
|
||||
"unknown": "Неизвестный",
|
||||
"hidden": "Скрытый",
|
||||
"timeout": "Таймаут",
|
||||
"clipboardExportSuccessMsg": "Скопировано в буфер обмена",
|
||||
"showMore": "Развернуть ",
|
||||
"showLess": "Свернуть ",
|
||||
"openAppSettings": "Открыть настройки приложения",
|
||||
"grantPermission": "Дать права доступа"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "Продолжая, Вы соглашаетесь с ${tap(@:about.termsAndConditions)}",
|
||||
"start": "Старт"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Главная",
|
||||
"emptyProfilesMsg": "Начните с добавления профиля подписки",
|
||||
"noActiveProfileMsg": "Выберите профиль"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Трафик",
|
||||
"trafficLive": "Текущий трафик",
|
||||
"trafficTotal": "Весь трафик",
|
||||
"uplink": "Скорость отправки",
|
||||
"downlink": "Скорость загрузки",
|
||||
"connection": "Соединение ",
|
||||
"speed": "Скорость",
|
||||
"totalTransferred": "Всего передано"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Профили",
|
||||
"detailsPageTitle": "Профиль",
|
||||
"activeProfileNameSemanticLabel": "Имя активного профиля: «${name}».",
|
||||
"activeProfileBtnSemanticLabel": "Посмотреть все профили",
|
||||
"nonActiveProfileBtnSemanticLabel": "Выберите «${name}» в качестве активного профиля.",
|
||||
"subscription": {
|
||||
"traffic": "Трафик",
|
||||
"updatedTimeAgo": "Обновлено ${timeago}",
|
||||
"remainingDuration": "Ещё ${duration} дн",
|
||||
"remainingTrafficSemanticLabel": "Использовано ${consumed} трафика из ${total}",
|
||||
"expired": "Истекло",
|
||||
"noTraffic": "Нет доступного трафика",
|
||||
"upload": "Отправлено ",
|
||||
"download": "Скачано",
|
||||
"total": "Всего трафика",
|
||||
"expireDate": "Дата окончания подписки "
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "По последнему обновлению",
|
||||
"name": "По названию"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "Новый профиль",
|
||||
"shortBtnTxt": "Новый профиль",
|
||||
"fromClipboard": "Добавить из буфера обмена",
|
||||
"scanQr": "Сканировать QR-код",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "Нет прав",
|
||||
"unexpectedError": "Неизвестная ошибка",
|
||||
"torchSemanticLabel": "Вспышка",
|
||||
"facingSemanticLabel": "Фронтальная камера",
|
||||
"permissionRequest": "Права на использование камеры для считывания QR"
|
||||
},
|
||||
"manually": "Ввести вручную",
|
||||
"addWarp": "Добавить WARP",
|
||||
"addingWarpMsg": "Пожалуйста, подождите, пока мы зарегистрируем WARP.",
|
||||
"addingProfileMsg": "Добавление профиля",
|
||||
"failureMsg": "Не удалось добавить профиль"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Обновить",
|
||||
"tooltip": "Обновить профиль",
|
||||
"updateSubscriptions": "Обновить подписки",
|
||||
"failureMsg": "Не удалось обновить профиль",
|
||||
"successMsg": "Профиль успешно обновлён",
|
||||
"namedFailureMsg": "Не удалось обновить \"${name}\".",
|
||||
"namedSuccessMsg": "\"${name}\" успешно обновлено"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Поделиться",
|
||||
"exportToClipboardSuccess": "Ссылка скопирована в буфер обмена",
|
||||
"exportSubLinkToClipboard": "Скопировать ссылку на подписку в буфер обмена",
|
||||
"subLinkQrCode": "QR-код ссылки на подписку",
|
||||
"exportConfigToClipboard": "Скопировать конфигурацию в буфер обмена",
|
||||
"exportConfigToClipboardSuccess": "Конфигурация скопирована в буфер обмена"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Изменить",
|
||||
"selectActiveTxt": "Выберите активный профиль"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Удалить",
|
||||
"confirmationMsg": "Безвозвратно удалить профиль?",
|
||||
"successMsg": "Профиль успешно удалён"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Сохранить",
|
||||
"successMsg": "Профиль успешно сохранён",
|
||||
"failureMsg": "Не удалось сохранить профиль"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "Имя",
|
||||
"nameHint": "Имя профиля",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "Полный URL конфигурации",
|
||||
"emptyNameMsg": "Поле «Имя» обязательно",
|
||||
"invalidUrlMsg": "Неправильный URL",
|
||||
"lastUpdate": "Последнее обновление",
|
||||
"updateInterval": "Автоматическое обновление",
|
||||
"updateIntervalDialogTitle": "Интервал обновления (в часах)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Прокси",
|
||||
"emptyProxiesMsg": "Нет доступных прокси",
|
||||
"delayTestTooltip": "Тестирование задержки",
|
||||
"sortTooltip": "Сортировка прокси",
|
||||
"checkIp": "Проверить IP",
|
||||
"unknownIp": "Неизвестный IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "По умолчанию",
|
||||
"name": "По алфавиту",
|
||||
"delay": "По задержке"
|
||||
},
|
||||
"activeProxySemanticLabel": "Активный прокси",
|
||||
"delaySemantics": {
|
||||
"result": "Задержка: ${delay}мс",
|
||||
"timeout": "Тайм-аут при тестировании задержки",
|
||||
"testing": "Задержка: Тестирование..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "IP адрес",
|
||||
"country": "Страна"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Логи",
|
||||
"filterHint": "Фильтр",
|
||||
"allLevelsFilter": "Все",
|
||||
"shareCoreLogs": "Поделиться журналами ядра",
|
||||
"shareAppLogs": "Поделиться журналами приложения",
|
||||
"pauseTooltip": "Приостановить",
|
||||
"resumeTooltip": "Возобновить",
|
||||
"clearTooltip": "Очистить"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Настройки",
|
||||
"requiresRestartMsg": "Чтобы применить изменения, перезапустите приложение",
|
||||
"experimental": "Экспериментальный",
|
||||
"experimentalMsg": "Функции с флагом «Экспериментально» все еще находятся в разработке и могут вызвать проблемы.",
|
||||
"exportOptions": "Копировать анонимные параметры в буфер обмена",
|
||||
"exportAllOptions": "Скопировать все параметры в буфер обмена",
|
||||
"importOptions": "Импорт параметров из буфера обмена",
|
||||
"importOptionsMsg": "Это перезапишет все параметры конфига предоставленными значениями. Вы уверены?",
|
||||
"general": {
|
||||
"sectionTitle": "Основные",
|
||||
"locale": "Язык",
|
||||
"region": "Регион",
|
||||
"regionMsg": "Помогает установить параметры по умолчанию для обхода внутренних (домашних, внутри страны) адресов.",
|
||||
"regions": {
|
||||
"ir": "Иран (ir) 🇮🇷",
|
||||
"cn": "Китай (cn) 🇨🇳",
|
||||
"ru": "Россия (ru) 🇷🇺",
|
||||
"af": "Афганистан (af) 🇦🇫",
|
||||
"id": "Индонезия (id) 🇮🇩",
|
||||
"tr": "Турция (tr) 🇹🇷",
|
||||
"br": "Бразилия (br) 🇧🇷",
|
||||
"other": "Другой"
|
||||
},
|
||||
"themeMode": "Оформление",
|
||||
"themeModes": {
|
||||
"system": "Системная тема",
|
||||
"dark": "Тёмная тема",
|
||||
"light": "Светлая тема",
|
||||
"black": "Чёрная тема"
|
||||
},
|
||||
"enableAnalytics": "Сбор аналитики",
|
||||
"enableAnalyticsMsg": "Сбор данных аналитики и отправка отчётов о сбоях для улучшения приложения",
|
||||
"autoStart": "Запуск при загрузке",
|
||||
"silentStart": "Запуск в свёрнутом виде",
|
||||
"openWorkingDir": "Открыть рабочую папку",
|
||||
"ignoreBatteryOptimizations": "Отключить оптимизацию батареи",
|
||||
"ignoreBatteryOptimizationsMsg": "Отключение ограничений для оптимальной производительности VPN",
|
||||
"dynamicNotification": "Отображение скорости в уведомлении",
|
||||
"hapticFeedback": "Тактильная обратная связь",
|
||||
"autoIpCheck": "Автоматически проверять IP-адрес соединения",
|
||||
"actionAtClosing": "Действие при закрытии",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "Каждый раз спрашивать",
|
||||
"hide": "Скрыть",
|
||||
"exit": "Выйти"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Расширенные",
|
||||
"debugMode": "Режим отладки",
|
||||
"debugModeMsg": "Чтобы применить изменения, перезапустите приложение",
|
||||
"memoryLimit": "Ограничение памяти",
|
||||
"memoryLimitMsg": "Включите, если у вас возникают ошибки нехватки памяти или частые сбои приложения",
|
||||
"resetTunnel": "Сбросить профиль VPN"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Раздельное проксирование приложений",
|
||||
"perAppProxyModes": {
|
||||
"off": "Все",
|
||||
"offMsg": "Проксировать все приложения",
|
||||
"include": "Прокси",
|
||||
"includeMsg": "Проксировать выбранные приложения",
|
||||
"exclude": "Обход",
|
||||
"excludeMsg": "Не проксировать выбранные приложения"
|
||||
},
|
||||
"showSystemApps": "Показать системные приложения",
|
||||
"hideSystemApps": "Скрыть системные приложения",
|
||||
"clearSelection": "Очистить выбор"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Активы маршрутизации",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "Geosite",
|
||||
"version": "Версия ${version}",
|
||||
"fileMissing": "Файл отсутствует",
|
||||
"update": "Обновить",
|
||||
"download": "Скачать",
|
||||
"failureMsg": "Не удалось обновить объект",
|
||||
"successMsg": "Объект успешно обновлен",
|
||||
"addRecommended": "Добавить рекомендуемые активы",
|
||||
"missingGeoAssetsMsg": "Файлы выбранных ресурсов маршрутизации отсутствуют. Либо скачайте их, либо выберите существующие"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "О программе",
|
||||
"version": "Версия",
|
||||
"sourceCode": "Исходный код",
|
||||
"telegramChannel": "Telegram-канал",
|
||||
"checkForUpdate": "Проверка обновления",
|
||||
"privacyPolicy": "Политика конфиденциальности",
|
||||
"termsAndConditions": "Условия и положения"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "Уже используется последняя версия",
|
||||
"dialogTitle": "Доступно обновление",
|
||||
"updateMsg": "Доступна новая версия @:general.appTitle. Обновить сейчас?",
|
||||
"currentVersionLbl": "Текущая версия",
|
||||
"newVersionLbl": "Новая версия",
|
||||
"updateNowBtnTxt": "Обновить",
|
||||
"laterBtnTxt": "Позже",
|
||||
"ignoreBtnTxt": "Пропустить"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Панель",
|
||||
"quit": "Выход",
|
||||
"open": "Открыть",
|
||||
"status": {
|
||||
"connect": "Подключиться",
|
||||
"connecting": "Подключение",
|
||||
"disconnect": "Отключиться",
|
||||
"disconnecting": "Отключение"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Непредвиденная ошибка",
|
||||
"clash": {
|
||||
"unexpected": "Непредвиденная ошибка (Clash)",
|
||||
"core": "Ошибка ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Непредвиденная ошибка (SingBox)",
|
||||
"serviceNotRunning": "Сервис не запущен",
|
||||
"missingPrivilege": "Отсутствуют права",
|
||||
"missingPrivilegeMsg": "Режим VPN требует прав администратора. Перезапустите приложение от имени администратора или измените режим работы приложения.",
|
||||
"missingGeoAssets": "Отсутствуют географические ресурсы",
|
||||
"missingGeoAssetsMsg": "Георесурсы отсутствуют. Изменените выбранный ресурс или загрузите собственный в настройках.",
|
||||
"invalidConfigOptions": "Неправильные параметры конфигурации",
|
||||
"invalidConfig": "Неправильная конфигурация",
|
||||
"create": "Ошибка создания сервиса",
|
||||
"start": "Ошибка запуска сервиса"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Непредвиденная ошибка",
|
||||
"missingVpnPermission": "Отсутствует разрешение VPN",
|
||||
"missingNotificationPermission": "Отсутствует разрешение на показ уведомлений",
|
||||
"core": "Ошибка ядра"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Непредвиденная ошибка",
|
||||
"notFound": "Профиль не найден",
|
||||
"invalidConfig": "Неправильная конфигурация",
|
||||
"invalidUrl": "Неправильный URL"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Неожиданная ошибка подключения",
|
||||
"timeout": "Истекло время подключения",
|
||||
"badResponse": "Неправильный ответ",
|
||||
"connectionError": "Ошибка подключения",
|
||||
"badCertificate": "Неправильный сертификат"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Неожиданная ошибка",
|
||||
"notUpdate": "Нет доступных обновлений",
|
||||
"activeNotFound": "Активный географический актив не найден"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (Предварительная версия)",
|
||||
"short_description": "Автовыбор, SSH, VLESS, VMess, Trojan, Reality, Sing-Box, Clash, Xray, Shadowsocks",
|
||||
"full_description": "Основная цель Hiddify — предоставить безопасный, удобный и эффективный клиент туннелирования. Он позволяет направлять весь трафик или трафик выбранного приложения на указанный Вами удалённый сервер.\n\nПримечание: мы не предоставляем серверы, пользователи должны сами обеспечивать конфиденциальность своих действий в Интернете, используя собственный сервер или доверенные серверы. \nПоддерживаются сервера с:\n- Обычной ссылкой на подписку V2ray/Xray\n- Ссылкой на подписку Clash\n- Ссылкой на подписку на Sing–Box\n\nВ чём уникальные особенности? \n- Удобство\n- Оптимизация и скорость\n- Автоматический выбор минимальной задержки\n- Отображение информации об использовании\n- Простой импорт подписок одним щелчком мыши\n- Бесплатно и без рекламы\n- Простое переключение подписок\n- И многое другое...\n\nПоддерживаются:\n- Все протоколы, поддерживаемые Sing-Box\n- VLESS + XTLS Reality, Vision\n- VMESS\n- Trojan\n- ShoadowSocks\n- Reality\n- V2ray\n- Hystria2\n- TUIC\n- SSH\n- ShadowTLS\n\nИсходный код доступен по адресу https://github.com/hiddify/Hiddify-Next\nЯдро приложения основано на открытом исходном коде Sing–Box.\n\nОписание разрешений:\n- СЛУЖБА VPN: поскольку целью данного приложения является предоставление безопасного, удобного и эффективного клиента туннелирования, это разрешение необходимо, чтобы иметь возможность направлять трафик через туннель на удалённый сервер.\n- ЗАПРОС ВСЕХ ПАКЕТОВ: это разрешение позволяет добавлять или удалять определённые приложения из списка для туннелирования.\n- ИНФОРМИРОВАНИЕ О ЗАВЕРШЕНИИ ЗАГРУЗКИ: это разрешение можно включить или отключить в настройках приложения, чтобы (де)активировать запуск приложения при загрузке устройства.\n- ПОСТОЯННОЕ УВЕДОМЛЕНИЕ: это разрешение необходимо, так как используется приоритетная служба для обеспечения непрерывной работы VPN.\n- Приложение не содержит рекламы. Сбор аналитики и данных о сбоях происходят только с явного согласия пользователя при первом использовании приложения."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Нажмите для подключения",
|
||||
"connecting": "Подключение",
|
||||
"disconnecting": "Отключение",
|
||||
"connected": "Подключено",
|
||||
"reconnect": "Восстановить соединение",
|
||||
"connectAnyWay": "Подключиться",
|
||||
"experimentalNotice": "Экспериментальные функции в использовании",
|
||||
"experimentalNoticeMsg": "Вы включили некоторые экспериментальные функции, которые могут повлиять на качество соединения и вызвать непредвиденные ошибки. Вы всегда можете изменить или сбросить эти параметры на странице параметров конфигурации.",
|
||||
"disableExperimentalNotice": "Больше не показывать",
|
||||
"reconnectMsg": "Переподключение для применения изменений..."
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "Использовать Xray-core по возможности",
|
||||
"Description": "Использование Xray-core для анализа подписок. Чтобы включить эту опцию, вам необходимо повторно импортировать подписку."
|
||||
},
|
||||
"resetBtn": "Сбросить параметры",
|
||||
"serviceMode": "Режим работы",
|
||||
"quickSettings": "Быстрые настройки",
|
||||
"setupWarp": "Настроить WARP",
|
||||
"allOptions": "Все параметры ",
|
||||
"serviceModes": {
|
||||
"proxy": "Прокси",
|
||||
"systemProxy": "Системный прокси",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN Сервис"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Прокси",
|
||||
"systemProxy": "Системный прокси",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN Сервис"
|
||||
},
|
||||
"section": {
|
||||
"route": "Варианты маршрутизации",
|
||||
"dns": "Параметры DNS",
|
||||
"inbound": "Входящие параметры",
|
||||
"mux": "Мультиплексор",
|
||||
"outbound": "Исходящие параметры",
|
||||
"tlsTricks": "Хитрости TLS",
|
||||
"warp": "Настройки WARP",
|
||||
"misc": "Разные параметры"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Согласие Cloudflare WARP",
|
||||
"description(rich)": "Cloudflare WARP — бесплатный провайдер WireGuard VPN. Включая эту опцию, вы соглашаетесь с ${tos(Условиями обслуживания)} и ${privacy(Политикой конфиденциальности)} Cloudflare WARP."
|
||||
},
|
||||
"generateWarpConfig": "Cгенерировать конфигурацию WARP",
|
||||
"missingWarpConfig": "Отсутствует конфигурация WARP",
|
||||
"warpConfigGenerated": "Создана конфигурация WARP",
|
||||
"pageTitle": "Параметры конфигурации",
|
||||
"logLevel": "Уровень логирования",
|
||||
"blockAds": "Блокировать рекламу",
|
||||
"resolveDestination": "Определять назначение",
|
||||
"ipv6Mode": "Маршрутизация IPv6",
|
||||
"ipv6Modes": {
|
||||
"disable": "Отключено",
|
||||
"enable": "Включено",
|
||||
"prefer": "Предпочтительно",
|
||||
"only": "Исключительно"
|
||||
},
|
||||
"remoteDnsAddress": "Удалённый DNS",
|
||||
"remoteDnsDomainStrategy": "Стратегия удалённого домена DNS",
|
||||
"directDnsAddress": "Прямой DNS",
|
||||
"directDnsDomainStrategy": "Стратегия прямого домена DNS",
|
||||
"mixedPort": "Смешанный порт",
|
||||
"tproxyPort": "Прозрачный прокси порт",
|
||||
"localDnsPort": "Локальный порт DNS",
|
||||
"allowConnectionFromLan": "Общий доступ к VPN в локальной сети",
|
||||
"tunImplementation": "Реализация TUN",
|
||||
"mtu": "Размер пакета (MTU)",
|
||||
"connectionTestUrl": "URL для проверки подключения",
|
||||
"urlTestInterval": "Интервал проверки URL",
|
||||
"enableClashApi": "Использовать Clash API",
|
||||
"clashApiPort": "Порт Clash API",
|
||||
"enableTun": "Использовать TUN",
|
||||
"setSystemProxy": "Установить системный прокси",
|
||||
"enableDnsRouting": "Использовать маршрутизацию DNS",
|
||||
"enableFakeDns": "Использовать поддельный DNS",
|
||||
"bypassLan": "Обход локальной сети",
|
||||
"strictRoute": "Строгая маршрутизация",
|
||||
"enableTlsFragment": "Включить Фрагментацию TLS",
|
||||
"tlsFragmentSize": "Размер фрагмента TLS",
|
||||
"tlsFragmentSleep": "Сон фрагмента TLS",
|
||||
"enableTlsMixedSniCase": "Включить TLS Mixed SNI Case",
|
||||
"enableTlsPadding": "Включить TLS Padding",
|
||||
"tlsPaddingSize": "TLS Padding",
|
||||
"enableMux": "Включить Mux",
|
||||
"muxProtocol": "Протокол Mux",
|
||||
"muxMaxStreams": "Масимальное количество параллельных потоков",
|
||||
"enableWarp": "Включить WARP",
|
||||
"warpDetourMode": "Режим обхода WARP",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "Работа Прокси через WARP",
|
||||
"warpOverProxy": "Работа WARP через Прокси",
|
||||
"inbound": "Обход WARP через Прокси",
|
||||
"outbound": "Обход Прокси через WARP"
|
||||
},
|
||||
"warpLicenseKey": "Лицензионный ключ",
|
||||
"warpCleanIp": "Очистить IP",
|
||||
"warpPort": "Порт",
|
||||
"warpNoise": "Шум",
|
||||
"warpNoiseSize": "Размер шума",
|
||||
"warpNoiseMode": "Шумовой режим",
|
||||
"warpNoiseDelay": "Задержка шума"
|
||||
},
|
||||
"window": {
|
||||
"hide": "Скрыть",
|
||||
"close": "Закрыть",
|
||||
"alertMessage": "Скрыть приложение или выйти?",
|
||||
"remember": "Запомнить выбор"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "Sıfırla",
|
||||
"toggle": {
|
||||
"enabled": "Etkin",
|
||||
"disabled": "Devre dışı"
|
||||
},
|
||||
"state": {
|
||||
"disable": "Devre dışı bırak"
|
||||
},
|
||||
"sort": "Sırala",
|
||||
"sortBy": "Sırala",
|
||||
"addToClipboard": "Panoya ekle",
|
||||
"notSet": "Ayarlanmadı",
|
||||
"agree": "Kabul etmek",
|
||||
"decline": "Reddetmek",
|
||||
"unknown": "Bilinmeyen",
|
||||
"hidden": "Gizlenmiş",
|
||||
"timeout": "Zaman aşımı",
|
||||
"clipboardExportSuccessMsg": "Panoya Eklendi",
|
||||
"showMore": "Daha fazla göster",
|
||||
"showLess": "Daha az göster",
|
||||
"openAppSettings": "Uygulama Ayarlarını Aç",
|
||||
"grantPermission": "İzin Ver"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "devam ederek ${tap(@:about.termsAndConditions)} kabul etmiş olursunuz",
|
||||
"start": "Başla"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "Ana Sayfa",
|
||||
"emptyProfilesMsg": "Aboneliği profili ekleyerek başlayın",
|
||||
"noActiveProfileMsg": "Profil seçin"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "Trafik",
|
||||
"trafficLive": "Canlı Trafik",
|
||||
"trafficTotal": "Toplam Trafik",
|
||||
"uplink": "Çıkış Yolu",
|
||||
"downlink": "Giriş Yolu",
|
||||
"connection": "Bağlantı",
|
||||
"speed": "Hız",
|
||||
"totalTransferred": "Toplam Aktarılan"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "Profiller",
|
||||
"detailsPageTitle": "Profil",
|
||||
"activeProfileNameSemanticLabel": "Aktif profil adı: \"${name}\".",
|
||||
"activeProfileBtnSemanticLabel": "Tüm profilleri görüntüleyin",
|
||||
"nonActiveProfileBtnSemanticLabel": "Aktif profil olarak \"${name}\" seçeneğini seçin.",
|
||||
"subscription": {
|
||||
"traffic": "Trafik",
|
||||
"updatedTimeAgo": "${timeago} güncellendi",
|
||||
"remainingDuration": "${duration} Gün Kaldı",
|
||||
"remainingTrafficSemanticLabel": "${consumed}/${total} trafik tüketildi",
|
||||
"expired": "Süresi Doldu",
|
||||
"noTraffic": "Kotal Doldu",
|
||||
"upload": "Yüklemek",
|
||||
"download": "İndirmek",
|
||||
"total": "Toplam Trafik",
|
||||
"expireDate": "Son kullanma tarihi"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "Yakın zamanda güncellendi",
|
||||
"name": "Alfabetik"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "Yeni profil",
|
||||
"shortBtnTxt": "Yeni profil",
|
||||
"fromClipboard": "Panodan Ekle",
|
||||
"scanQr": "QR kodunu tarayın",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "İzin reddedildi",
|
||||
"unexpectedError": "Bir şeyler yanlış gitti",
|
||||
"torchSemanticLabel": "El feneri",
|
||||
"facingSemanticLabel": "Kameraya önü",
|
||||
"permissionRequest": "QR Kodunu taramak için kamera izni"
|
||||
},
|
||||
"manually": "Manuel giriş",
|
||||
"addWarp": "WARP ekle",
|
||||
"addingWarpMsg": "WARP'ı kaydederken lütfen bekleyin.",
|
||||
"addingProfileMsg": "Profil Ekleniyor",
|
||||
"failureMsg": "Profil eklenemedi"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "Güncelle",
|
||||
"tooltip": "Profili Güncelle",
|
||||
"updateSubscriptions": "Abonelikleri Güncelle",
|
||||
"failureMsg": "Profil güncellenemedi",
|
||||
"successMsg": "Profil başarıyla güncellendi",
|
||||
"namedFailureMsg": "\"${name}\" güncellenemedi",
|
||||
"namedSuccessMsg": "\"${name}\" başarıyla güncellendi"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "Paylaş",
|
||||
"exportToClipboardSuccess": "Panoya aktarıldı",
|
||||
"exportSubLinkToClipboard": "Abonelik bağlantısını panoya aktar",
|
||||
"subLinkQrCode": "QR kodun abonelik bağlantısı ",
|
||||
"exportConfigToClipboard": "Yapılandırmayı panoya aktar",
|
||||
"exportConfigToClipboardSuccess": "Yapılandırma panoya kopyalandı"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "Düzenle",
|
||||
"selectActiveTxt": "Etkin profili seçin"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "Sil",
|
||||
"confirmationMsg": "Profil kalıcı olarak silinsin mi?",
|
||||
"successMsg": "Profil başarıyla silindi"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "Kaydet",
|
||||
"successMsg": "Profil başarıyla kaydedildi",
|
||||
"failureMsg": "Profil kaydedilemedi"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "İsim",
|
||||
"nameHint": "Profil ismi",
|
||||
"urlLabel": "URL",
|
||||
"urlHint": "Tam yapılandırma URL'i",
|
||||
"emptyNameMsg": "İsim gerekli",
|
||||
"invalidUrlMsg": "Geçersiz URL",
|
||||
"lastUpdate": "Son Güncelleme",
|
||||
"updateInterval": "Otomatik güncelleme",
|
||||
"updateIntervalDialogTitle": "Otomatik Güncelleme Aralığı (saat olarak)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "Proxyler",
|
||||
"emptyProxiesMsg": "Kullanılabilir proxy yok",
|
||||
"delayTestTooltip": "Test Gecikmesi",
|
||||
"sortTooltip": "Proxy'leri Sırala",
|
||||
"checkIp": "IP'yi kontrol edin",
|
||||
"unknownIp": "Bilinmeyen IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "Varsayılan",
|
||||
"name": "Alfabetik olarak",
|
||||
"delay": "Gecikmeyle"
|
||||
},
|
||||
"activeProxySemanticLabel": "Aktif Vekil",
|
||||
"delaySemantics": {
|
||||
"result": "Gecikme: ${delay}ms",
|
||||
"timeout": "Gecikme Testi Zaman Aşımı",
|
||||
"testing": "Gecikme: Test ediliyor..."
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "IP adresi",
|
||||
"country": "Ülke"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "Log",
|
||||
"filterHint": "Filtre",
|
||||
"allLevelsFilter": "Tüm",
|
||||
"shareCoreLogs": "Çekirdek Loglarını Paylaş",
|
||||
"shareAppLogs": "Uygulama Loglarını paylaş",
|
||||
"pauseTooltip": "Duraklat",
|
||||
"resumeTooltip": "Devam et",
|
||||
"clearTooltip": "Temizle"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "Ayarlar",
|
||||
"requiresRestartMsg": "Bunun etkili olması için uygulamayı yeniden başlatın",
|
||||
"experimental": "Deneysel",
|
||||
"experimentalMsg": "Deneysel işaretli özellikler hâlâ geliştirilme aşamasındadır ve sorunlara neden olabilir.",
|
||||
"exportOptions": "Anonim Seçenekleri Panoya Kopyala",
|
||||
"exportAllOptions": "Tüm Seçenekleri Panoya Kopyala",
|
||||
"importOptions": "Seçenekleri Panodan İçe Aktarma",
|
||||
"importOptionsMsg": "Bu, tüm yapılandırma seçeneklerini sağlanan değerlerle yeniden yazacaktır. Emin misin?",
|
||||
"general": {
|
||||
"sectionTitle": "Genel",
|
||||
"locale": "Dil",
|
||||
"region": "Bölge",
|
||||
"regionMsg": "Yerel adresleri atlamak için varsayılan seçeneği seçebilirsin",
|
||||
"regions": {
|
||||
"ir": "İran (ir) 🇮🇷",
|
||||
"cn": "Çin (cn) 🇨🇳",
|
||||
"ru": "Rusya (ru) 🇷🇺",
|
||||
"af": "Afghanistan (af) 🇦🇫",
|
||||
"id": "Endonezya (id) 🇮🇩",
|
||||
"tr": "Türk (tr) 🇹🇷",
|
||||
"br": "Brezilya (br) 🇧🇷",
|
||||
"other": "Diğer"
|
||||
},
|
||||
"themeMode": "Tema Modu",
|
||||
"themeModes": {
|
||||
"system": "Sistem temasını takip et",
|
||||
"dark": "Karanlık mod",
|
||||
"light": "Işık modu",
|
||||
"black": "Siyah mod"
|
||||
},
|
||||
"enableAnalytics": "Analitikleri Etkinleştir",
|
||||
"enableAnalyticsMsg": "Uygulamayı iyileştirmek için analiz toplama ve kilitlenme raporları göndermeye izni verin",
|
||||
"autoStart": "Önyüklemede Başlat",
|
||||
"silentStart": "Sessiz Başlatma",
|
||||
"openWorkingDir": "Çalışma Dizinini Aç",
|
||||
"ignoreBatteryOptimizations": "Pil Optimizasyonunu Devre Dışı Bırak",
|
||||
"ignoreBatteryOptimizationsMsg": "Optimum VPN performansı için kısıtlamaları kaldırın",
|
||||
"dynamicNotification": "Bildirimde hızı göster",
|
||||
"hapticFeedback": "Dokunsal geribildirim",
|
||||
"autoIpCheck": "Bağlantı IP'sini Otomatik Olarak Kontrol Et",
|
||||
"actionAtClosing": "Kapanışta eylem",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "Her seferinde sor",
|
||||
"hide": "Saklamak",
|
||||
"exit": "Çıkış"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "Gelişmiş",
|
||||
"debugMode": "Hata ayıklama modu",
|
||||
"debugModeMsg": "Bu değişikliği uygulamak için uygulamayı yeniden başlatın",
|
||||
"memoryLimit": "Bellek Sınırı",
|
||||
"memoryLimitMsg": "Yetersiz bellek hataları veya sık sık uygulama çökmesi yaşıyorsanız etkinleştirin",
|
||||
"resetTunnel": "VPN Profilini Sıfırla"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "Uygulama başına Proxy",
|
||||
"perAppProxyModes": {
|
||||
"off": "Tümü",
|
||||
"offMsg": "Proxy tüm uygulamalar",
|
||||
"include": "Proxy",
|
||||
"includeMsg": "Yalnızca proxy seçilen uygulamalar",
|
||||
"exclude": "Atlatma",
|
||||
"excludeMsg": "Seçilen uygulamalara proxy uygulama"
|
||||
},
|
||||
"showSystemApps": "Sistem uygulamalarını göster",
|
||||
"hideSystemApps": "Sistem uygulamalarını gizle",
|
||||
"clearSelection": "Seçimi temizle"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "Varlıkları Yönlendirme",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "Geosite",
|
||||
"version": "Sürüm ${version}",
|
||||
"fileMissing": "Eksik dosya",
|
||||
"update": "Güncelleme",
|
||||
"download": "İndirmek",
|
||||
"failureMsg": "Öğe güncellenemedi",
|
||||
"successMsg": "Öğe başarıyla güncellendi",
|
||||
"addRecommended": "Önerilen Varlıkları Ekle",
|
||||
"missingGeoAssetsMsg": "Seçilen yönlendirme varlıklarının dosyaları eksik. Bunları indirin veya mevcut olanları seçin."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "Hakkında",
|
||||
"version": "Sürüm",
|
||||
"sourceCode": "Kaynak kodu",
|
||||
"telegramChannel": "Telegram Kanalı",
|
||||
"checkForUpdate": "Güncellemeleri kontrol et",
|
||||
"privacyPolicy": "Gizlilik Politikası",
|
||||
"termsAndConditions": "Şartlar ve koşullar"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": " En son sürümü kullanıyorsunuz",
|
||||
"dialogTitle": "Yeni Güncell",
|
||||
"updateMsg": "@:general.appTitle'ın yeni bir sürümü mevcut. Şimdi güncellemek ister misiniz?",
|
||||
"currentVersionLbl": "Şimdiki versiyon",
|
||||
"newVersionLbl": "Yeni versiyon",
|
||||
"updateNowBtnTxt": "Şimdi güncelle",
|
||||
"laterBtnTxt": "Daha sonra",
|
||||
"ignoreBtnTxt": "Görmezden gel"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "Gösterge Paneli",
|
||||
"quit": "Çıkış yap",
|
||||
"open": "Açık",
|
||||
"status": {
|
||||
"connect": "Bağlan",
|
||||
"connecting": "Bağlanıyor",
|
||||
"disconnect": "Bağlantıyı kes",
|
||||
"disconnecting": "Bağlantı kesiliyor"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "Beklenmeyen hata",
|
||||
"clash": {
|
||||
"unexpected": "Beklenmeyen hata",
|
||||
"core": "Çakışma Hatası ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "Beklenmedik Hizmet Hatası",
|
||||
"serviceNotRunning": "Servis çalışmıyor",
|
||||
"missingPrivilege": "Eksik Ayrıcalık",
|
||||
"missingPrivilegeMsg": "VPN modu yönetici ayrıcalıkları gerektirir. Uygulamayı yönetici olarak yeniden başlatın veya hizmet modunu değiştirin.",
|
||||
"missingGeoAssets": "Eksik Coğrafi Varlıklar",
|
||||
"missingGeoAssetsMsg": "Coğrafi öğeler eksik. Aktif varlığı değiştirmeyi veya ayarlarda seçileni indirmeyi düşünün.",
|
||||
"invalidConfigOptions": "Geçersiz yapılandırma seçenekleri",
|
||||
"invalidConfig": "Geçersiz Yapılandırma",
|
||||
"create": "Servis oluşturma hatası",
|
||||
"start": "Servis başlatma hatası"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Beklenmedik Hata",
|
||||
"missingVpnPermission": "Eksik VPN İzni",
|
||||
"missingNotificationPermission": "Eksik Bildirim İzni",
|
||||
"core": "Temel Hata"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Beklenmedik hata",
|
||||
"notFound": "Profil bulunamadı",
|
||||
"invalidConfig": "Geçersiz Yapılandırmalar",
|
||||
"invalidUrl": "Geçersiz URL"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "Beklenmeyen bağlantı hatası",
|
||||
"timeout": "Bağlantı zamanaşımına uğradı",
|
||||
"badResponse": "Kötü yanıt",
|
||||
"connectionError": "Bağlantı hatası",
|
||||
"badCertificate": "Kötü sertifika"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "Beklenmeyen hata",
|
||||
"notUpdate": "Güncelleme mevcut değil",
|
||||
"activeNotFound": "Etkin Coğrafi Varlık Bulunamadı"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify (Önizleme)",
|
||||
"short_description": "Otomatik, SSH, VLESS, Vmess, Trojan, Reality, Sing-Box, Clash, Xray, Shadowsocks",
|
||||
"full_description": "Hiddify'in temel hedefi güvenli, kullanıcı dostu ve verimli bir tünel istemcisi sağlamaktır. VPN Hizmeti iznini kullanarak tüm trafiği veya seçilen uygulama trafiğini seçtiğiniz uzak bir sunucuya yönlendirmenizi sağlar. Not: Herhangi bir sunucu sağlamıyoruz; kullanıcıların kendi barındırılan sunucularını veya güvenilir sunucularını kullanarak çevrimiçi etkinliklerinin gizli kalmasını sağlamaları gerekir. Sunucuları aşağıdakilerle destekliyoruz: - Normal V2ray/Xray Abonelik Bağlantısı - Clash Abonelik Bağlantısı - Sing-Box Abonelik Bağlantısı Benzersiz özelliklerimiz nelerdir? - Kullanıcı Dostu - Optimize Edilmiş ve Hızlı - En Düşük Ping'i otomatik olarak seçin - Kullanıcı kullanım bilgilerini gösterin - Derin bağlantı kullanarak tek tıklamayla alt bağlantıyı kolayca içe aktarın - Ücretsiz ve ADS Yok - Kullanıcı alt bağlantılarını kolayca değiştirin - giderek daha fazla Destek: - Sing-Box tarafından desteklenen tüm Protokoller - VLESS + xtls gerçeklik, vizyon - VMESS - Trojan - ShoadowSocks - Reality - V2ray - Hystria2 - TUIC - SSH - ShadowTLS Kaynak kodu https://github.com/hiddify/Hiddify-Next adresinde mevcuttur. Uygulama çekirdeği açık tabanlıdır. kaynak şarkı kutusu. İzin Açıklaması: - VPN Hizmeti: Bu uygulamanın amacı güvenli, kullanıcı dostu ve verimli bir tünel istemcisi sağlamak olduğundan, trafiği tünel aracılığıyla uzak sunucuya yönlendirebilmek için bu izne ihtiyacımız var. - TÜM PAKETLERİ SORGULAYIN: Bu izin, kullanıcıların tünelleme için belirli uygulamaları dahil etmesine veya hariç tutmasına izin vermek için kullanılır. - ALMA ÖNYÜKLEME TAMAMLANDI: Bu izin, cihaz önyüklemesi sırasında bu uygulamayı etkinleştirmek için uygulama ayarlarından etkinleştirilebilir veya devre dışı bırakılabilir. - BİLDİRİMLER SONRASI: VPN hizmetinin sürekli çalışmasını sağlamak için bir ön plan hizmeti kullandığımız için bu izin önemlidir. - Bu uygulama reklam içermez. Analitik ve kilitlenme verileri yalnızca uygulamanın ilk kullanımında kullanıcının açık rızası ile gerçekleşir."
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Bağlanmak için dokunun",
|
||||
"connecting": "Bağlanıyor",
|
||||
"disconnecting": "Bağlantı kesiliyor",
|
||||
"connected": "Bağlandı",
|
||||
"reconnect": "Yeniden bağlan",
|
||||
"connectAnyWay": "Bağlamak",
|
||||
"experimentalNotice": "Kullanımdaki Deneysel Özellikler",
|
||||
"experimentalNoticeMsg": "Bağlantı kalitesini etkileyebilecek ve beklenmeyen hatalara neden olabilecek bazı deneysel özellikleri etkinleştirdiniz. Bu seçenekleri istediğiniz zaman Yapılandırma seçenekleri sayfasından değiştirebilir veya sıfırlayabilirsiniz.",
|
||||
"disableExperimentalNotice": "Bir daha gösterme",
|
||||
"reconnectMsg": "Değişiklikleri dikkate almak için yeniden bağlanılıyor..."
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "Mümkün Olduğunda X-ray-çekirdeğini Kullanın",
|
||||
"Description": "Alt bağlantıları ayrıştırırken Xray-core kullanın. Bu seçeneği etkinleştirmek için alt bağlantıyı yeniden içe aktarmanız gerekir."
|
||||
},
|
||||
"resetBtn": "Ayarları sıfırla",
|
||||
"serviceMode": "Servis modu",
|
||||
"quickSettings": "Hızlı Ayarlar",
|
||||
"setupWarp": "WARP'ı Kur",
|
||||
"allOptions": "Tüm Yapılandırma Seçenekleri",
|
||||
"serviceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Sistem Proxy",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN Hizmeti"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "vekil",
|
||||
"systemProxy": "Sistem Proxy'si",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN Hizmeti"
|
||||
},
|
||||
"section": {
|
||||
"route": "Rota Seçenekleri",
|
||||
"dns": "DNS Seçenekleri",
|
||||
"inbound": "Gelen Seçenekler",
|
||||
"mux": "Multiplexer",
|
||||
"outbound": "Outbound Options",
|
||||
"tlsTricks": "TLS Tricks",
|
||||
"warp": "WARP Options",
|
||||
"misc": "Çeşitli Seçenekler"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Cloudflare WARP Onayı",
|
||||
"description(rich)": "Cloudflare WARP ücretsiz bir WireGuard VPN sağlayıcısıdır. Bu seçeneği etkinleştirerek Cloudflare WARP'ın ${tos(Hizmet Şartları)} ve ${privacy(Gizlilik Politikası)}'nı kabul etmiş olursunuz."
|
||||
},
|
||||
"generateWarpConfig": "WARP Yapılandırması Oluştur",
|
||||
"missingWarpConfig": "WARP Yapılandırması Eksik",
|
||||
"warpConfigGenerated": "WARP Yapılandırması Oluşturuldu",
|
||||
"pageTitle": "Yapılandırma Seçenekleri",
|
||||
"logLevel": "Log Seviyesi",
|
||||
"blockAds": "Reklamları Engelle",
|
||||
"resolveDestination": "Hedefi Çöz",
|
||||
"ipv6Mode": "IPv6 Rotası",
|
||||
"ipv6Modes": {
|
||||
"disable": "Devre dışı bırak",
|
||||
"enable": "Etkinleştir",
|
||||
"prefer": "Tercih edilen",
|
||||
"only": "Özel"
|
||||
},
|
||||
"remoteDnsAddress": "Uzak DNS",
|
||||
"remoteDnsDomainStrategy": "Uzak DNS Domain Stratejisi",
|
||||
"directDnsAddress": "Doğrudan DNS",
|
||||
"directDnsDomainStrategy": "Doğrudan DNS Domain Stratejisi",
|
||||
"mixedPort": "Mixed Port",
|
||||
"tproxyPort": "Şeffaf Proxy Bağlantı Noktası",
|
||||
"localDnsPort": "Yerel DNS Bağlantı Noktası",
|
||||
"allowConnectionFromLan": "Allow Connection from LAN",
|
||||
"tunImplementation": "TUN İmplementasyonu",
|
||||
"mtu": "Paket Boyutu (MTU)",
|
||||
"connectionTestUrl": "Bağlantı Testi URL'i",
|
||||
"urlTestInterval": "URL Test Aralığı",
|
||||
"enableClashApi": "Clash API'yi etkinleştir",
|
||||
"clashApiPort": "Clash API Bağlantı Noktası",
|
||||
"enableTun": "TUN'u etkinleştir",
|
||||
"setSystemProxy": "Sistem Proxy'sini Ayarla",
|
||||
"enableDnsRouting": "Enable DNS Routing",
|
||||
"enableFakeDns": "Sahte DNS'yi Etkinleştir",
|
||||
"bypassLan": "Lan'ı Atla",
|
||||
"strictRoute": "Kesin Rota",
|
||||
"enableTlsFragment": "Enable TLS Fragment",
|
||||
"tlsFragmentSize": "TLS Fragment Size",
|
||||
"tlsFragmentSleep": "TLS Fragment Sleep",
|
||||
"enableTlsMixedSniCase": "Enable TLS Mixed SNI Case",
|
||||
"enableTlsPadding": "Enable TLS Padding",
|
||||
"tlsPaddingSize": "TLS Padding",
|
||||
"enableMux": "Enable Mux",
|
||||
"muxProtocol": "Mux Protocol",
|
||||
"muxMaxStreams": "Max Concurrent Streams",
|
||||
"enableWarp": "Enable WARP",
|
||||
"warpDetourMode": "Detour Mode",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "WARP Aracılığıyla Proxy'lerin Yönünü Değiştirin",
|
||||
"warpOverProxy": "Proxy'ler Aracılığıyla WARP'tan Sapma",
|
||||
"inbound": "Detour WARP through proxies",
|
||||
"outbound": "Detour proxies through WARP"
|
||||
},
|
||||
"warpLicenseKey": "License Key",
|
||||
"warpCleanIp": "Clean IP",
|
||||
"warpPort": "Port",
|
||||
"warpNoise": "Noise",
|
||||
"warpNoiseSize": "Gürültü Boyutu",
|
||||
"warpNoiseMode": "Gürültü Modu",
|
||||
"warpNoiseDelay": "Gürültü Gecikmesi"
|
||||
},
|
||||
"window": {
|
||||
"hide": "Saklamak",
|
||||
"close": "Çıkış",
|
||||
"alertMessage": "Uygulamayı gizle veya çık?",
|
||||
"remember": "Seçimimi hatırla"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "重置",
|
||||
"toggle": {
|
||||
"enabled": "启用",
|
||||
"disabled": "禁用"
|
||||
},
|
||||
"state": {
|
||||
"disable": "禁用"
|
||||
},
|
||||
"sort": "排序",
|
||||
"sortBy": "排序方式",
|
||||
"addToClipboard": "添加到剪贴板",
|
||||
"notSet": "未设置",
|
||||
"agree": "同意",
|
||||
"decline": "拒绝",
|
||||
"unknown": "未知",
|
||||
"hidden": "隐藏",
|
||||
"timeout": "超时",
|
||||
"clipboardExportSuccessMsg": "已导出到剪贴板",
|
||||
"showMore": "显示更多",
|
||||
"showLess": "显示更少",
|
||||
"openAppSettings": "打开应用设置",
|
||||
"grantPermission": "授予权限"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "继续即表示您同意 ${tap(@:about.termsAndConditions)}",
|
||||
"start": "开始"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "主页",
|
||||
"emptyProfilesMsg": "从添加订阅配置文件开始",
|
||||
"noActiveProfileMsg": "选择配置文件"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "流量",
|
||||
"trafficLive": "实时流量",
|
||||
"trafficTotal": "总流量",
|
||||
"uplink": "上行",
|
||||
"downlink": "下行",
|
||||
"connection": "连接",
|
||||
"speed": "速度",
|
||||
"totalTransferred": "总传输量"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "配置文件",
|
||||
"detailsPageTitle": "配置文件",
|
||||
"activeProfileNameSemanticLabel": "激活的配置文件名称:“${name}”。",
|
||||
"activeProfileBtnSemanticLabel": "查看所有配置文件",
|
||||
"nonActiveProfileBtnSemanticLabel": "选择 “${name}” 作为激活的配置文件",
|
||||
"subscription": {
|
||||
"traffic": "流量",
|
||||
"updatedTimeAgo": "更新于 ${timeago}",
|
||||
"remainingDuration": "剩余 ${duration} 天",
|
||||
"remainingTrafficSemanticLabel": "已使用 ${consumed} 流量,共 ${total} 流量。",
|
||||
"expired": "已过期",
|
||||
"noTraffic": "超出限额",
|
||||
"upload": "上传",
|
||||
"download": "下载",
|
||||
"total": "总流量",
|
||||
"expireDate": "到期时间"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "最近更新",
|
||||
"name": "按字母顺序"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "新的配置文件",
|
||||
"shortBtnTxt": "新的配置文件",
|
||||
"fromClipboard": "从剪贴板添加",
|
||||
"scanQr": "扫描二维码",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "权限不足",
|
||||
"unexpectedError": "出了些问题",
|
||||
"torchSemanticLabel": "闪光灯",
|
||||
"facingSemanticLabel": "切换摄像头",
|
||||
"permissionRequest": "授予相机权限以允许扫描二维码"
|
||||
},
|
||||
"manually": "手动输入",
|
||||
"addWarp": "添加 WARP",
|
||||
"addingWarpMsg": "我们正在注册 WARP,请稍候。",
|
||||
"addingProfileMsg": "添加配置文件",
|
||||
"failureMsg": "添加配置文件失败"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "更新",
|
||||
"tooltip": "更新配置文件",
|
||||
"updateSubscriptions": "更新订阅",
|
||||
"failureMsg": "更新配置文件失败",
|
||||
"successMsg": "配置文件更新成功",
|
||||
"namedFailureMsg": "无法更新\"${name}\"",
|
||||
"namedSuccessMsg": "\"${name}\" 更新成功"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "分享",
|
||||
"exportToClipboardSuccess": "导出到剪贴板",
|
||||
"exportSubLinkToClipboard": "将订阅链接导出到剪贴板",
|
||||
"subLinkQrCode": "订阅链接二维码",
|
||||
"exportConfigToClipboard": "将配置导出到剪贴板",
|
||||
"exportConfigToClipboardSuccess": "配置已复制到剪贴板"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "编辑",
|
||||
"selectActiveTxt": "选择并激活配置文件"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "删除",
|
||||
"confirmationMsg": "要永久删除配置文件吗?",
|
||||
"successMsg": "配置文件删除成功"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "保存",
|
||||
"successMsg": "配置文件保存成功",
|
||||
"failureMsg": "配置文件保存失败"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "名称",
|
||||
"nameHint": "配置文件名称",
|
||||
"urlLabel": "网址",
|
||||
"urlHint": "完整配置网址",
|
||||
"emptyNameMsg": "名称为必填项",
|
||||
"invalidUrlMsg": "无效的网址",
|
||||
"lastUpdate": "最后更新",
|
||||
"updateInterval": "自动更新",
|
||||
"updateIntervalDialogTitle": "自动更新间隔(小时)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "代理",
|
||||
"emptyProxiesMsg": "无可用的代理",
|
||||
"delayTestTooltip": "测试延迟",
|
||||
"sortTooltip": "对代理进行排序",
|
||||
"checkIp": "检测 IP 位置",
|
||||
"unknownIp": "未知的 IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "默认顺序",
|
||||
"name": "按首字母排序",
|
||||
"delay": "按延迟排序"
|
||||
},
|
||||
"activeProxySemanticLabel": "激活中的代理",
|
||||
"delaySemantics": {
|
||||
"result": "延迟: ${delay}ms",
|
||||
"timeout": "延迟测试超时",
|
||||
"testing": "正在测试延迟"
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "IP 地址",
|
||||
"country": "国家"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "日志",
|
||||
"filterHint": "筛选",
|
||||
"allLevelsFilter": "全部",
|
||||
"shareCoreLogs": "分享核心日志",
|
||||
"shareAppLogs": "分享应用日志",
|
||||
"pauseTooltip": "暂停",
|
||||
"resumeTooltip": "恢复",
|
||||
"clearTooltip": "清空"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "设置",
|
||||
"requiresRestartMsg": "要使其生效,请重新启动应用程序",
|
||||
"experimental": "实验性选项",
|
||||
"experimentalMsg": "带有实验标志的功能仍在开发中,可能会出现问题。",
|
||||
"exportOptions": "将匿名选项导出到剪贴板",
|
||||
"exportAllOptions": "将所有选项导出到剪贴板(用于调试)",
|
||||
"importOptions": "从剪贴板导入选项",
|
||||
"importOptionsMsg": "这将使用提供的值覆盖所有配置选项。您确定吗?",
|
||||
"general": {
|
||||
"sectionTitle": "通用",
|
||||
"locale": "语言",
|
||||
"region": "地区",
|
||||
"regionMsg": "帮助设置默认选项以绕过国内地址",
|
||||
"regions": {
|
||||
"ir": "伊朗 (ir) 🇮🇷",
|
||||
"cn": "中国 (cn) 🇨🇳",
|
||||
"ru": "俄罗斯 (ru) 🇷🇺",
|
||||
"af": "阿富汗 (af) 🇦🇫",
|
||||
"id": "印度尼西亚 (id) 🇮🇩",
|
||||
"tr": "土耳其(tr)🇹🇷",
|
||||
"br": "巴西 (br) 🇧🇷",
|
||||
"other": "其它"
|
||||
},
|
||||
"themeMode": "主题模式",
|
||||
"themeModes": {
|
||||
"system": "跟随系统主题",
|
||||
"dark": "深色",
|
||||
"light": "浅色",
|
||||
"black": "黑色"
|
||||
},
|
||||
"enableAnalytics": "启用分析",
|
||||
"enableAnalyticsMsg": "授予收集分析并发送崩溃报告以改进应用程序的权限",
|
||||
"autoStart": "开机启动",
|
||||
"silentStart": "静默启动",
|
||||
"openWorkingDir": "打开工作目录",
|
||||
"ignoreBatteryOptimizations": "禁用电池优化",
|
||||
"ignoreBatteryOptimizationsMsg": "消除限制以获得最佳 VPN 性能",
|
||||
"dynamicNotification": "在通知中显示网络速度",
|
||||
"hapticFeedback": "触觉反馈",
|
||||
"autoIpCheck": "自动检查连接的 IP",
|
||||
"actionAtClosing": "关闭时动作",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "每次都询问",
|
||||
"hide": "隐藏",
|
||||
"exit": "退出"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "高级选项",
|
||||
"debugMode": "调试模式",
|
||||
"debugModeMsg": "重新启动应用程序以应用此更改",
|
||||
"memoryLimit": "内存限制",
|
||||
"memoryLimitMsg": "如果您遇到内存不足或频繁应用程序崩溃的问题,请启用",
|
||||
"resetTunnel": "重置 VPN 配置文件"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "分应用代理",
|
||||
"perAppProxyModes": {
|
||||
"off": "全部",
|
||||
"offMsg": "代理所有应用程序",
|
||||
"include": "代理",
|
||||
"includeMsg": "仅代理选定的应用程序",
|
||||
"exclude": "绕过",
|
||||
"excludeMsg": "不代理选中的应用程序"
|
||||
},
|
||||
"showSystemApps": "显示系统应用程序",
|
||||
"hideSystemApps": "隐藏系统应用程序",
|
||||
"clearSelection": "清空选项"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "路由资源文件",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "Geosite",
|
||||
"version": "版本 ${version}",
|
||||
"fileMissing": "文件丢失",
|
||||
"update": "更新",
|
||||
"download": "下载",
|
||||
"failureMsg": "更新资源文件失败",
|
||||
"successMsg": "已成功更新资源文件",
|
||||
"addRecommended": "添加建议的资源文件",
|
||||
"missingGeoAssetsMsg": "所选路由资源的文件丢失。下载它们或选择现有的。"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "关于",
|
||||
"version": "版本",
|
||||
"sourceCode": "源代码",
|
||||
"telegramChannel": "Telegram 频道",
|
||||
"checkForUpdate": "检查更新",
|
||||
"privacyPolicy": "隐私政策",
|
||||
"termsAndConditions": "条款和条件"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "已是最新版本",
|
||||
"dialogTitle": "有可用更新",
|
||||
"updateMsg": "@:general.appTitle 的新版本现已推出。您想现在更新吗?",
|
||||
"currentVersionLbl": "当前版本",
|
||||
"newVersionLbl": "新版本",
|
||||
"updateNowBtnTxt": "现在更新",
|
||||
"laterBtnTxt": "以后再说",
|
||||
"ignoreBtnTxt": "忽略"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "仪表板",
|
||||
"quit": "退出",
|
||||
"open": "打开",
|
||||
"status": {
|
||||
"connect": "连接",
|
||||
"connecting": "正在连接",
|
||||
"disconnect": "断开连接",
|
||||
"disconnecting": "正在断开连接"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "意外错误",
|
||||
"clash": {
|
||||
"unexpected": "意外错误",
|
||||
"core": "Clash 错误 ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "意外服务错误",
|
||||
"serviceNotRunning": "服务未运行",
|
||||
"missingPrivilege": "缺少权限",
|
||||
"missingPrivilegeMsg": "VPN 模式需要管理员权限。以管理员身份重新启动应用程序或更改服务模式",
|
||||
"missingGeoAssets": "缺失 GEO 资源文件",
|
||||
"missingGeoAssetsMsg": "缺失 GEO 资源文件。请考虑更改激活的资源文件或在设置中下载所选资源文件。",
|
||||
"invalidConfigOptions": "配置选项无效",
|
||||
"invalidConfig": "无效配置",
|
||||
"create": "服务创建错误",
|
||||
"start": "服务启动错误"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "意外失败",
|
||||
"missingVpnPermission": "缺少 VPN 权限",
|
||||
"missingNotificationPermission": "缺少通知权限",
|
||||
"core": "核心错误"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "意外错误",
|
||||
"notFound": "未找到配置文件",
|
||||
"invalidConfig": "无效配置",
|
||||
"invalidUrl": "网址无效"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "意外连接错误",
|
||||
"timeout": "连接超时",
|
||||
"badResponse": "错误响应",
|
||||
"connectionError": "连接错误",
|
||||
"badCertificate": "证书无效"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "意外错误",
|
||||
"notUpdate": "暂无可用更新",
|
||||
"activeNotFound": "未找到激活的 GEO 资源文件"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify(预览)",
|
||||
"short_description": "自动,SSH, VLESS, Vmess, Trojan, Reality, Sing-Box, Clash, Xray, Shadowsocks",
|
||||
"full_description": "Hiddify 的主要目标是提供安全、用户友好且高效的隧道客户端。它使您能够利用 VPN 服务权限将所有流量或选定的应用程序流量路由到您选择的远程服务器。\n\n注:我们不提供任何服务器;用户需要使用自己托管的服务器或可信的服务器来确保您在线活动的私密性。\n \n我们支持以下类型的服务器:\n- 普通 V2ray/Xray 订阅链接\n- Clash 订阅链接\n- Sing-Box 订阅链接\n\n我们的特色是什么?\n\n- 用户友好\n- 优化和高速\n- 自动选择最低延迟\n- 显示用户使用信息\n- 通过一键链接轻松导入\n- 免费且无广告\n- 轻松切换线路\n- 等等\n\n支持:\n- Sing-Box 支持的所有协议\n- VLESS + XTLS Reality、Vision 协议\n- VMESS\n- Trojan\n- ShadowSocks\n- Reality\n- WireGuard\n- V2ray\n- Hystria2\n- TUIC\n- SSH\n- ShadowTLS\n\n\n源代码位于 https://github.com/hiddify/Hiddify-Next\n应用程序核心基于开源的 Sing-Box。\n\n权限说明:\n\n- VPN 服务:由于此应用程序的目标是提供安全、用户友好和高效的隧道客户端,我们需要此权限以能够通过隧道将流量路由到远程服务器。\n获取应用程序列表:此权限用于允许用户包括或排除特定应用程序以进行隧道传输。\n- 接收开机广播:可以从应用程序设置中启用或禁用此权限,以便在设备启动时激活此应用程序。\n- 发送通知:此权限是必需的,因为我们使用前台服务来确保 VPN 服务的持续运行。\n- 本应用程序没有广告。分析和崩溃数据仅在首次使用应用程序时经用户明确同意的情况下发生。"
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "开始连接",
|
||||
"connecting": "正在连接",
|
||||
"disconnecting": "正在断开连接",
|
||||
"connected": "已连接",
|
||||
"reconnect": "重新连接",
|
||||
"connectAnyWay": "连接",
|
||||
"experimentalNotice": "使用中的实验功能",
|
||||
"experimentalNoticeMsg": "您启用了一些实验性功能,这些功能可能会影响连接质量并导致一些意外错误。您可以随时从“配置选项”页面更改或重新设置这些选项。",
|
||||
"disableExperimentalNotice": "不再显示",
|
||||
"reconnectMsg": "重新连接以使更改生效"
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "尽可能使用 Xray-core",
|
||||
"Description": "解析子链接时使用 Xray-core。您需要重新导入子链接才能启用此选项。"
|
||||
},
|
||||
"resetBtn": "重置选项",
|
||||
"serviceMode": "服务模式",
|
||||
"quickSettings": "快速设置",
|
||||
"setupWarp": "配置 WARP",
|
||||
"allOptions": "全部配置选项",
|
||||
"serviceModes": {
|
||||
"proxy": "仅代理",
|
||||
"systemProxy": "系统代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服务"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "仅代理",
|
||||
"systemProxy": "系统代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服务"
|
||||
},
|
||||
"section": {
|
||||
"route": "路由选项",
|
||||
"dns": "DNS 选项",
|
||||
"inbound": "入站选项",
|
||||
"mux": "多路复用",
|
||||
"outbound": "出站选项",
|
||||
"tlsTricks": "TLS 特性",
|
||||
"warp": "WARP 选项",
|
||||
"misc": "其它选项"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Cloudflare WARP 许可条款",
|
||||
"description(rich)": "Cloudflare WARP 是一个免费的 WireGuard VPN 提供商。启用此选项即表示您同意 Cloudflare WARP 的 ${tos(服务条款)} 和 ${privacy(隐私政策)}"
|
||||
},
|
||||
"generateWarpConfig": "生成 WARP 配置文件",
|
||||
"missingWarpConfig": "WARP 配置文件缺失",
|
||||
"warpConfigGenerated": "WARP 配置已生成",
|
||||
"pageTitle": "配置选项",
|
||||
"logLevel": "日志级别",
|
||||
"blockAds": "阻止广告",
|
||||
"resolveDestination": "解析目标地址",
|
||||
"ipv6Mode": "IPv6 路由",
|
||||
"ipv6Modes": {
|
||||
"disable": "禁用",
|
||||
"enable": "启用",
|
||||
"prefer": "首选",
|
||||
"only": "仅限"
|
||||
},
|
||||
"remoteDnsAddress": "远程 DNS",
|
||||
"remoteDnsDomainStrategy": "远程 DNS 域名策略",
|
||||
"directDnsAddress": "直连 DNS",
|
||||
"directDnsDomainStrategy": "直连 DNS 域名策略",
|
||||
"mixedPort": "混合端口",
|
||||
"tproxyPort": "透明代理端口",
|
||||
"localDnsPort": "本地 DNS 端口",
|
||||
"allowConnectionFromLan": "允许局域网连接",
|
||||
"tunImplementation": "TUN 实现",
|
||||
"mtu": "数据包大小 (MTU)",
|
||||
"connectionTestUrl": "连接测试网址",
|
||||
"urlTestInterval": "网址测试间隔",
|
||||
"enableClashApi": "启用 Clash API",
|
||||
"clashApiPort": "Clash API 端口",
|
||||
"enableTun": "启用 TUN",
|
||||
"setSystemProxy": "设置系统代理",
|
||||
"enableDnsRouting": "启用 DNS 路由",
|
||||
"enableFakeDns": "启用 Fake DNS",
|
||||
"bypassLan": "绕过局域网",
|
||||
"strictRoute": "严格路由",
|
||||
"enableTlsFragment": "启用 TLS 数据分段",
|
||||
"tlsFragmentSize": "TLS 分段大小",
|
||||
"tlsFragmentSleep": "TLS 分段休眠",
|
||||
"enableTlsMixedSniCase": "启用 TLS 混合 SNI 情形",
|
||||
"enableTlsPadding": "启用 TLS 填充",
|
||||
"tlsPaddingSize": "TLS 填充",
|
||||
"enableMux": "启用 Mux 多路复用",
|
||||
"muxProtocol": "Mux 协议",
|
||||
"muxMaxStreams": "Mux 最大并发数",
|
||||
"enableWarp": "启用 WARP",
|
||||
"warpDetourMode": "链式代理",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "通过 WARP 连接代理",
|
||||
"warpOverProxy": "通过代理连接 WARP",
|
||||
"inbound": "通过代理绕过 WARP",
|
||||
"outbound": "通过 WARP 绕过代理"
|
||||
},
|
||||
"warpLicenseKey": "许可证密钥",
|
||||
"warpCleanIp": "清理 IP",
|
||||
"warpPort": "端口",
|
||||
"warpNoise": "噪音计数",
|
||||
"warpNoiseSize": "噪音大小",
|
||||
"warpNoiseMode": "噪音模式",
|
||||
"warpNoiseDelay": "噪音延迟"
|
||||
},
|
||||
"window": {
|
||||
"hide": "隐藏",
|
||||
"close": "关闭",
|
||||
"alertMessage": "隐藏或退出应用程序?",
|
||||
"remember": "记住我的选择"
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"appTitle": "Hiddify",
|
||||
"reset": "重置",
|
||||
"toggle": {
|
||||
"enabled": "啟用",
|
||||
"disabled": "停用"
|
||||
},
|
||||
"state": {
|
||||
"disable": "停用"
|
||||
},
|
||||
"sort": "排序",
|
||||
"sortBy": "排序方式",
|
||||
"addToClipboard": "新增至剪貼簿",
|
||||
"notSet": "未設定",
|
||||
"agree": "同意",
|
||||
"decline": "拒絕",
|
||||
"unknown": "不明",
|
||||
"hidden": "隱藏",
|
||||
"timeout": "超時",
|
||||
"clipboardExportSuccessMsg": "已匯出至剪貼簿",
|
||||
"showMore": "顯示更多",
|
||||
"showLess": "顯示較少",
|
||||
"openAppSettings": "開啟應用程式設定",
|
||||
"grantPermission": "授予權限"
|
||||
},
|
||||
"intro": {
|
||||
"termsAndPolicyCaution(rich)": "繼續即表示您同意合約 ${tap(@:about.termsAndConditions)}",
|
||||
"start": "開始"
|
||||
},
|
||||
"home": {
|
||||
"pageTitle": "首頁",
|
||||
"emptyProfilesMsg": "首先新增訂閱設定檔",
|
||||
"noActiveProfileMsg": "選擇設定檔"
|
||||
},
|
||||
"stats": {
|
||||
"traffic": "流量",
|
||||
"trafficLive": "即時流量",
|
||||
"trafficTotal": "總流量",
|
||||
"uplink": "上行",
|
||||
"downlink": "下行",
|
||||
"connection": "連線",
|
||||
"speed": "速度",
|
||||
"totalTransferred": "總傳輸量"
|
||||
},
|
||||
"profile": {
|
||||
"overviewPageTitle": "設定檔",
|
||||
"detailsPageTitle": "設定檔",
|
||||
"activeProfileNameSemanticLabel": "活動設定檔名稱:“${name}”。",
|
||||
"activeProfileBtnSemanticLabel": "查看所有設定檔",
|
||||
"nonActiveProfileBtnSemanticLabel": "選擇“${name}”作為活動設定檔。",
|
||||
"subscription": {
|
||||
"traffic": "流量",
|
||||
"updatedTimeAgo": "更新於 ${timeago}",
|
||||
"remainingDuration": "剩餘 ${duration} 天",
|
||||
"remainingTrafficSemanticLabel": "已使用 ${consumed} 流量,總共 ${total} 流量。",
|
||||
"expired": "已到期",
|
||||
"noTraffic": "超過配額",
|
||||
"upload": "上傳",
|
||||
"download": "下載",
|
||||
"total": "總流量",
|
||||
"expireDate": "到期時間"
|
||||
},
|
||||
"sortBy": {
|
||||
"lastUpdate": "最近更新",
|
||||
"name": "按字母順序"
|
||||
},
|
||||
"add": {
|
||||
"buttonText": "新的設定檔",
|
||||
"shortBtnTxt": "新的設定檔",
|
||||
"fromClipboard": "從剪貼簿新增",
|
||||
"scanQr": "掃描 QR code",
|
||||
"qrScanner": {
|
||||
"permissionDeniedError": "沒有權限",
|
||||
"unexpectedError": "出了點問題",
|
||||
"torchSemanticLabel": "手電筒",
|
||||
"facingSemanticLabel": "相機朝向",
|
||||
"permissionRequest": "授予相機權限已允許掃描 QR code"
|
||||
},
|
||||
"manually": "手動輸入",
|
||||
"addWarp": "添加 WARP",
|
||||
"addingWarpMsg": "我們正在註冊 WARP,請稍候。",
|
||||
"addingProfileMsg": "新增設定檔",
|
||||
"failureMsg": "新增設定檔失敗"
|
||||
},
|
||||
"update": {
|
||||
"buttonTxt": "更新",
|
||||
"tooltip": "更新設定檔",
|
||||
"updateSubscriptions": "更新訂閱",
|
||||
"failureMsg": "更新設定檔失敗",
|
||||
"successMsg": "設定檔更新成功",
|
||||
"namedFailureMsg": "無法更新“${name}”",
|
||||
"namedSuccessMsg": "“${name}” 更新成功"
|
||||
},
|
||||
"share": {
|
||||
"buttonText": "分享",
|
||||
"exportToClipboardSuccess": "匯出到剪貼簿",
|
||||
"exportSubLinkToClipboard": "將訂閱連結匯出到剪貼簿",
|
||||
"subLinkQrCode": "訂閱連結 QR code",
|
||||
"exportConfigToClipboard": "將配置匯出到剪貼簿",
|
||||
"exportConfigToClipboardSuccess": "配置已複製到剪貼簿"
|
||||
},
|
||||
"edit": {
|
||||
"buttonTxt": "編輯",
|
||||
"selectActiveTxt": "選擇活動設定檔"
|
||||
},
|
||||
"delete": {
|
||||
"buttonTxt": "刪除",
|
||||
"confirmationMsg": "要永久刪除設定檔嗎?",
|
||||
"successMsg": "設定檔刪除成功"
|
||||
},
|
||||
"save": {
|
||||
"buttonText": "儲存",
|
||||
"successMsg": "設定檔儲存成功",
|
||||
"failureMsg": "設定檔儲存失敗"
|
||||
},
|
||||
"detailsForm": {
|
||||
"nameLabel": "名稱",
|
||||
"nameHint": "設定檔名稱",
|
||||
"urlLabel": "網址",
|
||||
"urlHint": "完整配置網址",
|
||||
"emptyNameMsg": "名稱為必填項",
|
||||
"invalidUrlMsg": "無效的網址",
|
||||
"lastUpdate": "最後更新",
|
||||
"updateInterval": "自動更新",
|
||||
"updateIntervalDialogTitle": "自動更新間隔(以小時為單位)"
|
||||
}
|
||||
},
|
||||
"proxies": {
|
||||
"pageTitle": "代理",
|
||||
"emptyProxiesMsg": "沒有可用的代理",
|
||||
"delayTestTooltip": "測試延遲",
|
||||
"sortTooltip": "對代理進行排序",
|
||||
"checkIp": "檢測 IP 地址",
|
||||
"unknownIp": "不明的 IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "預設",
|
||||
"name": "按字母排序",
|
||||
"delay": "按延遲排序"
|
||||
},
|
||||
"activeProxySemanticLabel": "生效中的代理",
|
||||
"delaySemantics": {
|
||||
"result": "延遲: ${delay}ms",
|
||||
"timeout": "延遲測試超時",
|
||||
"testing": "正在測試延遲"
|
||||
},
|
||||
"ipInfoSemantics": {
|
||||
"address": "IP 地址",
|
||||
"country": "國家"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"pageTitle": "記錄檔",
|
||||
"filterHint": "篩選",
|
||||
"allLevelsFilter": "全部",
|
||||
"shareCoreLogs": "分享核心記錄檔",
|
||||
"shareAppLogs": "分享應用程式記錄檔",
|
||||
"pauseTooltip": "暫停",
|
||||
"resumeTooltip": "恢復",
|
||||
"clearTooltip": "清除"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "設定",
|
||||
"requiresRestartMsg": "若要使其生效,請重新啟動應用程式",
|
||||
"experimental": "實驗性的",
|
||||
"experimentalMsg": "帶有實驗標誌的功能仍在開發中,可能會導致問題。",
|
||||
"exportOptions": "匯出選項至剪貼簿",
|
||||
"exportAllOptions": "匯出選項至剪貼簿(用於偵錯) ",
|
||||
"importOptions": "從剪貼簿匯入選項",
|
||||
"importOptionsMsg": "這將使用提供的值複寫所有配置選項。您確定嗎?",
|
||||
"general": {
|
||||
"sectionTitle": "一般",
|
||||
"locale": "語言",
|
||||
"region": "地區",
|
||||
"regionMsg": "幫助設定預設選項以繞過國內地址",
|
||||
"regions": {
|
||||
"ir": "伊朗 (ir)",
|
||||
"cn": "中國 (cn)",
|
||||
"ru": "俄羅斯 (ru)",
|
||||
"af": "阿富汗 (af)",
|
||||
"id": "印尼 (id)",
|
||||
"tr": "土耳其 (tr) 🇹🇷",
|
||||
"br": "巴西 (br) 🇧🇷",
|
||||
"other": "其他"
|
||||
},
|
||||
"themeMode": "主題模式",
|
||||
"themeModes": {
|
||||
"system": "遵循系統主題",
|
||||
"dark": "深色",
|
||||
"light": "淺色",
|
||||
"black": "黑色"
|
||||
},
|
||||
"enableAnalytics": "啟用分析",
|
||||
"enableAnalyticsMsg": "授予收集分析並傳送崩潰報告以改進應用程式的權限",
|
||||
"autoStart": "隨系統啟動",
|
||||
"silentStart": "啟動最小化",
|
||||
"openWorkingDir": "開啟工作目錄",
|
||||
"ignoreBatteryOptimizations": "停用電池最佳化",
|
||||
"ignoreBatteryOptimizationsMsg": "消除限制以獲得最佳 VPN 效能",
|
||||
"dynamicNotification": "在通知中顯示速度",
|
||||
"hapticFeedback": "觸覺回饋",
|
||||
"autoIpCheck": "自動檢查連線的 IP",
|
||||
"actionAtClosing": "收盤時行動",
|
||||
"actionsAtClosing": {
|
||||
"askEachTime": "每次都詢問",
|
||||
"hide": "隱藏",
|
||||
"exit": "退出"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"sectionTitle": "進階設定",
|
||||
"debugMode": "偵錯模式",
|
||||
"debugModeMsg": "重新啟動應用程式以套用此變更",
|
||||
"memoryLimit": "記憶體限制",
|
||||
"memoryLimitMsg": "如果您遇到記憶體不足錯誤或頻繁應用程式崩潰,請啟用",
|
||||
"resetTunnel": "重置 VPN 設定檔"
|
||||
},
|
||||
"network": {
|
||||
"perAppProxyPageTitle": "應用程式 VPN 模式",
|
||||
"perAppProxyModes": {
|
||||
"off": "全部",
|
||||
"offMsg": "代理所有應用程式",
|
||||
"include": "代理",
|
||||
"includeMsg": "僅代理選定的應用程式",
|
||||
"exclude": "略過",
|
||||
"excludeMsg": "不代理選定的應用程式"
|
||||
},
|
||||
"showSystemApps": "顯示系統應用程式",
|
||||
"hideSystemApps": "隱藏系統應用程式",
|
||||
"clearSelection": "清空選項"
|
||||
},
|
||||
"geoAssets": {
|
||||
"pageTitle": "路由資源文件",
|
||||
"geoip": "GeoIP",
|
||||
"geosite": "Geosite",
|
||||
"version": "版本${version}",
|
||||
"fileMissing": "檔案遺失",
|
||||
"update": "更新",
|
||||
"download": "下載",
|
||||
"failureMsg": "更新資源文件失敗",
|
||||
"successMsg": "已成功更新資源文件",
|
||||
"addRecommended": "新增推薦的資源文件",
|
||||
"missingGeoAssetsMsg": "所選路由資源的檔案遺失。下載它們或選擇現有的。"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"pageTitle": "關於",
|
||||
"version": "版本",
|
||||
"sourceCode": "原始碼",
|
||||
"telegramChannel": "Telegram 頻道",
|
||||
"checkForUpdate": "檢查更新",
|
||||
"privacyPolicy": "隱私政策",
|
||||
"termsAndConditions": "條款與條件"
|
||||
},
|
||||
"appUpdate": {
|
||||
"notAvailableMsg": "已經是最新版本",
|
||||
"dialogTitle": "有可用更新",
|
||||
"updateMsg": "@:general.appTitle 的更新版本現已推出。您想立即更新嗎?",
|
||||
"currentVersionLbl": "目前版本",
|
||||
"newVersionLbl": "新版本",
|
||||
"updateNowBtnTxt": "立即更新",
|
||||
"laterBtnTxt": "稍後再說",
|
||||
"ignoreBtnTxt": "忽略"
|
||||
},
|
||||
"tray": {
|
||||
"dashboard": "儀表板",
|
||||
"quit": "退出",
|
||||
"open": "開啟",
|
||||
"status": {
|
||||
"connect": "連線",
|
||||
"connecting": "連線中",
|
||||
"disconnect": "中斷連線",
|
||||
"disconnecting": "中斷連線中"
|
||||
}
|
||||
},
|
||||
"failure": {
|
||||
"unexpected": "意外錯誤",
|
||||
"clash": {
|
||||
"unexpected": "意外錯誤",
|
||||
"core": "Clash 錯誤 ${reason}"
|
||||
},
|
||||
"singbox": {
|
||||
"unexpected": "意外服務錯誤",
|
||||
"serviceNotRunning": "服務未執行",
|
||||
"missingPrivilege": "缺少權限",
|
||||
"missingPrivilegeMsg": "VPN 模式需要管理員權限。以管理員身分重新啟動應用程式或變更服務模式。",
|
||||
"missingGeoAssets": "缺少 GEO 資源文件",
|
||||
"missingGeoAssetsMsg": "GEO 資源文件缺失。請考慮更改活動資源文件或在設定中下載選定的資源文件。",
|
||||
"invalidConfigOptions": "配置選項無效",
|
||||
"invalidConfig": "無效配置",
|
||||
"create": "服務建立錯誤",
|
||||
"start": "服務啟動錯誤"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "意外失敗",
|
||||
"missingVpnPermission": "缺少 VPN 權限",
|
||||
"missingNotificationPermission": "缺少通知權限",
|
||||
"core": "核心錯誤"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "意外錯誤",
|
||||
"notFound": "未找到設定檔",
|
||||
"invalidConfig": "無效配置",
|
||||
"invalidUrl": "無效網址"
|
||||
},
|
||||
"connection": {
|
||||
"unexpected": "意外連線錯誤",
|
||||
"timeout": "連線超時",
|
||||
"badResponse": "錯誤反應",
|
||||
"connectionError": "連線錯誤",
|
||||
"badCertificate": "無效證書"
|
||||
},
|
||||
"geoAssets": {
|
||||
"unexpected": "意外錯誤",
|
||||
"notUpdate": "暫無可用更新",
|
||||
"activeNotFound": "未找到活動 GEO 資源文件"
|
||||
}
|
||||
},
|
||||
"play": {
|
||||
"title": "Hiddify(預覽)",
|
||||
"short_description": "自動、SSH、VLESS、Vmess、Trojan、Reality、Sing-Box、Clash、Xray、Shadowsocks",
|
||||
"full_description": "Hiddify 的主要目標是提供安全、使用者友好且高效率的隧道用戶端。它使您能夠利用 VPN 服務權限將所有流量或選定的應用程式流量路由到您選擇的遠端伺服器。\n\n註:我們不提供任何伺服器;使用者需要使用自己的自託管伺服器或受信任的伺服器來確保其線上活動的隱私。\n\n我們透過以下方式支援伺服器:\n - 普通 V2ray/Xray 訂閱連結\n - Clash 訂閱連結\n - Sing-Box 訂閱連結\n\n 我們的獨特功能是什麼?\n - 使用者友善\n - 最佳化且快速\n - 自動選擇最低延遲\n - 顯示使用者使用資訊\n - 使用一鍵連結輕鬆導入\n - 免費且無廣告\n - 輕鬆切換線路\n - 等等\n 支援:\n - Sing-Box 支援的所有協定 \n - VLESS + XTLS Reality、Vision 協定 \n - VMESS\n - Trojan\n - ShadowSocks\n - Reality\n - WireGuard\n - V2ray\n - Hystria2\n - TUIC \n - SSH\n - ShadowTLS\n\n\n 原始碼位於 https://github.com/hiddify/Hiddify-Next\n 應用程式核心基於開源的 Sing-Box。\n\n權限說明:\n\n - VPN 服務:由於此應用程式的目標是提供安全性、使用者友好且高效的隧道用戶端,因此我們需要此權限才能透過隧道將流量路由到遠端伺服器。\n - 獲取應用程式列表:此權限用於允許使用者包含或排除隧道的特定應用程式。\n - 接收啟動廣播:可以從應用程式設定中啟用或停用此權限,以在裝置啟動時啟動此應用程式。\n - 傳送通知:此權限至關重要,因為我們使用前台服務來確保 VPN 服務的持續運作。\n - 該應用程式沒有廣告。分析和崩潰數據僅在用戶首次使用應用程式時明確同意的情況下才會出現。"
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "點擊以連線",
|
||||
"connecting": "連線中",
|
||||
"disconnecting": "中斷連線中",
|
||||
"connected": "已連線",
|
||||
"reconnect": "重新連線",
|
||||
"connectAnyWay": "連線",
|
||||
"experimentalNotice": "使用中的實驗性功能",
|
||||
"experimentalNoticeMsg": "您啟用了一些實驗性功能,這些功能可能會影響連線品質並導致某些意外錯誤。您始終可以從「配置選項」頁面變更或重設這些選項。",
|
||||
"disableExperimentalNotice": "不再提示",
|
||||
"reconnectMsg": "重新連線以使變更生效"
|
||||
},
|
||||
"config": {
|
||||
"useXrayCoreWhenPossible": {
|
||||
"Label": "盡可能使用 Xray-core",
|
||||
"Description": "解析子連結時使用 Xray-core。您需要重新匯入子連結才能啟用此選項。"
|
||||
},
|
||||
"resetBtn": "重置選項",
|
||||
"serviceMode": "服務模式",
|
||||
"quickSettings": "快速設定",
|
||||
"setupWarp": "配置 WARP",
|
||||
"allOptions": "全部配置選項",
|
||||
"serviceModes": {
|
||||
"proxy": "僅代理",
|
||||
"systemProxy": "系統代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服務"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "僅代理",
|
||||
"systemProxy": "系統代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服務"
|
||||
},
|
||||
"section": {
|
||||
"route": "路由選項",
|
||||
"dns": "DNS 選項",
|
||||
"inbound": "入站選項",
|
||||
"mux": "復用器",
|
||||
"outbound": "出站選項",
|
||||
"tlsTricks": "TLS 特性",
|
||||
"warp": "WARP 選項",
|
||||
"misc": "其他選項"
|
||||
},
|
||||
"warpConsent": {
|
||||
"title": "Cloudflare WARP 授權條款",
|
||||
"description(rich)": "Cloudflare WARP 是一個免費的 WireGuard VPN 提供商。啟用此選項即表示您同意 Cloudflare WARP 的 ${tos(服務條款)} 和 ${privacy(隱私權政策)}"
|
||||
},
|
||||
"generateWarpConfig": "生成 WARP 配置檔案",
|
||||
"missingWarpConfig": "WARP 配置檔案缺失",
|
||||
"warpConfigGenerated": "WARP 設定已生成",
|
||||
"pageTitle": "配置選項",
|
||||
"logLevel": "紀錄等級",
|
||||
"blockAds": "阻止廣告",
|
||||
"resolveDestination": "解析目標地址",
|
||||
"ipv6Mode": "IPv6 路由",
|
||||
"ipv6Modes": {
|
||||
"disable": "停用",
|
||||
"enable": "啟用",
|
||||
"prefer": "首選",
|
||||
"only": "僅限"
|
||||
},
|
||||
"remoteDnsAddress": "遠端 DNS",
|
||||
"remoteDnsDomainStrategy": "遠端 DNS 網域策略",
|
||||
"directDnsAddress": "直連 DNS",
|
||||
"directDnsDomainStrategy": "直連 DNS 網域策略",
|
||||
"mixedPort": "混合連接埠",
|
||||
"tproxyPort": "透明代理埠",
|
||||
"localDnsPort": "本機 DNS 連接埠",
|
||||
"allowConnectionFromLan": "允許區域網路連線",
|
||||
"tunImplementation": "TUN 實現",
|
||||
"mtu": "封包大小 (MTU)",
|
||||
"connectionTestUrl": "連線測試網址",
|
||||
"urlTestInterval": "網址測試間隔",
|
||||
"enableClashApi": "啟用 Clash API",
|
||||
"clashApiPort": "Clash API 連接埠",
|
||||
"enableTun": "啟用 TUN",
|
||||
"setSystemProxy": "設定系統代理",
|
||||
"enableDnsRouting": "啟用 DNS 路由",
|
||||
"enableFakeDns": "啟用 Fake DNS",
|
||||
"bypassLan": "繞過區域網路",
|
||||
"strictRoute": "嚴格路由",
|
||||
"enableTlsFragment": "啟用 TLS 分段",
|
||||
"tlsFragmentSize": "TLS 分段大小",
|
||||
"tlsFragmentSleep": "TLS 分段睡眠",
|
||||
"enableTlsMixedSniCase": "啟用 TLS 混合 SNI 情況",
|
||||
"enableTlsPadding": "啟用 TLS 填充",
|
||||
"tlsPaddingSize": "TLS 填充",
|
||||
"enableMux": "啟用復用器",
|
||||
"muxProtocol": "復用器控制",
|
||||
"muxMaxStreams": "最大並發數",
|
||||
"enableWarp": "啟用 WARP",
|
||||
"warpDetourMode": "鏈式代理",
|
||||
"warpDetourModes": {
|
||||
"proxyOverWarp": "透過 WARP 連線代理",
|
||||
"warpOverProxy": "透過代理連線 WARP",
|
||||
"inbound": "透過代理繞過 WARP",
|
||||
"outbound": "透過 WARP 繞過代理"
|
||||
},
|
||||
"warpLicenseKey": "授權金鑰",
|
||||
"warpCleanIp": "清理 IP",
|
||||
"warpPort": "連接埠",
|
||||
"warpNoise": "噪音計數",
|
||||
"warpNoiseSize": "噪音大小",
|
||||
"warpNoiseMode": "噪音模式",
|
||||
"warpNoiseDelay": "噪音延遲"
|
||||
},
|
||||
"window": {
|
||||
"hide": "隱藏",
|
||||
"close": "关闭",
|
||||
"alertMessage": "隱藏或退出應用程式?",
|
||||
"remember": "記住我的選擇"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "Başlat",
|
||||
"version": "Sürüm",
|
||||
"ok": "Tamam",
|
||||
"cancel": "İptal",
|
||||
"kContinue": "Devam et",
|
||||
"showMore": "Daha fazla göster",
|
||||
"showLess": "Daha az göster",
|
||||
"filter": "Filtrele",
|
||||
"all": "Tümü",
|
||||
"pause": "Duraklat",
|
||||
"resume": "Devam et",
|
||||
"clear": "Temizle",
|
||||
"close": "Kapat",
|
||||
"auto": "Otomatik",
|
||||
"manually": "Manuel",
|
||||
"name": "İsim",
|
||||
"url": "URL",
|
||||
"add": "Ekle",
|
||||
"clipboard": "Pano",
|
||||
"addToClipboard": "Panoya ekle",
|
||||
"scanQr": "QR Tara",
|
||||
"free": "Ücretsiz",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "Yardım",
|
||||
"save": "Kaydet",
|
||||
"update": "Güncelle",
|
||||
"share": "Paylaş",
|
||||
"edit": "Düzenle",
|
||||
"delete": "Sil",
|
||||
"discard": "Vazgeç",
|
||||
"import": "İçe aktar",
|
||||
"export": "Dışa aktar",
|
||||
"later": "Daha sonra",
|
||||
"ignore": "Yoksay",
|
||||
"quit": "Çık",
|
||||
"notSet": "Ayarlanmadı",
|
||||
"hide": "Gizle",
|
||||
"exit": "Çıkış",
|
||||
"reset": "Sıfırla",
|
||||
"done": "Bitti",
|
||||
"search": "Ara",
|
||||
"decline": "Reddet",
|
||||
"agree": "Kabul et",
|
||||
"empty": "Boş",
|
||||
"unknown": "Bilinmeyen",
|
||||
"hidden": "Gizli",
|
||||
"timeout": "Zaman aşımı",
|
||||
"sort": "Sırala",
|
||||
"dashboard": "Gösterge Paneli",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n gün",
|
||||
"other": "$n gün"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n saat",
|
||||
"other": "$n saat"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "İzin reddedildi"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "Panoya başarıyla eklendi",
|
||||
"failure": "Panoya kopyalanamadı",
|
||||
"contentTooLarge": "İçerik çok büyük. Bunun yerine dosyaya aktarmayı kullanın"
|
||||
},
|
||||
"file": {
|
||||
"success": "JSON dosyası başarıyla oluşturuldu",
|
||||
"failure": "Dosya oluşturulamadı"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "İçe aktarmayı onayla",
|
||||
"success": "Başarıyla içe aktarıldı",
|
||||
"failure": "İçe aktarılamadı"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "Sınırsız bir internet için ihtiyacınız olan her şey",
|
||||
"termsAndPolicyCaution(rich)": "Devam ederek ${tap(@:pages.about.termsAndConditions)} kabul etmiş olursunuz",
|
||||
"info(rich)": "Hiddify tarafından ❤️ ile yapıldı - ${tap_source(Açık Kaynak)} (${tap_license(Lisans)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "Ana Sayfa",
|
||||
"quickSettings": "Hızlı ayarlar"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "Proxy'ler",
|
||||
"sort": "Proxy'leri sırala",
|
||||
"testDelay": "Gecikmeyi test et",
|
||||
"empty": "Kullanılabilir proxy yok",
|
||||
"activeProxy": "Aktif proxy",
|
||||
"unknownIp": "Bilinmeyen IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "Varsayılan",
|
||||
"name": "Alfabetik",
|
||||
"delay": "Gecikmeye göre"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "IP adresi",
|
||||
"country": "Ülke",
|
||||
"organization": "Kuruluş"
|
||||
},
|
||||
"delay": {
|
||||
"result": "Gecikme: ${delay}ms",
|
||||
"timeout": "Gecikme testi zaman aşımına uğradı",
|
||||
"testing": "Gecikme: test ediliyor..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "Profiller",
|
||||
"add": "Profil ekle",
|
||||
"update": "Profili güncelle",
|
||||
"viewAllProfiles": "Tüm profilleri görüntüle",
|
||||
"activeProfileName": "Aktif profil adı: \"${name}\".",
|
||||
"nonActiveProfileName": "Aktif profil olarak \"${name}\" seçin",
|
||||
"freeSubNotFound": "Ücretsiz abonelik bulunamadı",
|
||||
"freeSubNotFoundForRegion": "\"${region}\" bölgesi için ücretsiz abonelik bulunamadı",
|
||||
"failedToLoad": "Yüklenemedi",
|
||||
"updateSubscriptions": "Abonelikleri güncelle",
|
||||
"share": {
|
||||
"urlToClipboard": "URL'yi panoya kopyala",
|
||||
"showUrlQr": "URL QR kodunu göster",
|
||||
"jsonToClipboard": "JSON'u panoya kopyala"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "Profil başarıyla kaydedildi"
|
||||
},
|
||||
"invalidUrl": "Geçersiz URL",
|
||||
"add": {
|
||||
"failure": "Profil eklenemedi"
|
||||
},
|
||||
"update": {
|
||||
"success": "Profil başarıyla güncellendi",
|
||||
"successNamed": "\"${name}\" başarıyla güncellendi",
|
||||
"failure": "Profil güncellenemedi",
|
||||
"failureNamed": "\"${name}\" güncellenemedi"
|
||||
},
|
||||
"delete": {
|
||||
"success": "Profil başarıyla silindi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "Profil",
|
||||
"lastUpdate": "Son güncelleme",
|
||||
"form": {
|
||||
"nameHint": "Profil adı",
|
||||
"emptyName": "İsim gerekli",
|
||||
"invalidUrl": "Geçersiz URL",
|
||||
"urlHint": "Tam yapılandırma URL'si",
|
||||
"disableAutoUpdate": "Otomatik güncellemeyi devre dışı bırak",
|
||||
"autoUpdateInterval": "Otomatik güncelleme aralığı",
|
||||
"loading": "Profil ekleniyor..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "Loglar",
|
||||
"shareCoreLogs": "Çekirdek loglarını paylaş",
|
||||
"shareAppLogs": "Uygulama loglarını paylaş"
|
||||
},
|
||||
"about": {
|
||||
"title": "Hakkında",
|
||||
"notAvailableMsg": "Zaten en son sürümü kullanıyorsunuz",
|
||||
"checkForUpdate": "Güncellemeleri kontrol et",
|
||||
"openWorkingDir": "Çalışma dizinini aç",
|
||||
"sourceCode": "Kaynak kodu",
|
||||
"telegramChannel": "Telegram kanalı",
|
||||
"termsAndConditions": "Şartlar ve Koşullar",
|
||||
"privacyPolicy": "Gizlilik Politikası"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ayarlar",
|
||||
"resetTunnel": "VPN profilini sıfırla",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Seçenekleri panodan içe aktar",
|
||||
"file": "Seçenekleri dosyadan içe aktar"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "Anonim seçenekleri panoya kopyala",
|
||||
"anonymousToFile": "Anonim seçenekleri dosyaya aktar",
|
||||
"allToClipboard": "Tüm seçenekleri panoya kopyala",
|
||||
"allToFile": "Tüm seçenekleri dosyaya aktar"
|
||||
},
|
||||
"reset": "Seçenekleri sıfırla"
|
||||
},
|
||||
"general": {
|
||||
"title": "Genel",
|
||||
"locale": "Dil",
|
||||
"themeMode": "Tema modu",
|
||||
"themeModes": {
|
||||
"system": "Sistem varsayılanı",
|
||||
"dark": "Karanlık mod",
|
||||
"light": "Açık mod",
|
||||
"black": "Siyah mod"
|
||||
},
|
||||
"enableAnalytics": "Analizi etkinleştir",
|
||||
"enableAnalyticsMsg": "Uygulamayı iyileştirmek için analiz ve kilitlenme raporları toplanmasına izin verin",
|
||||
"autoIpCheck": "Bağlantı IP'sini otomatik kontrol et",
|
||||
"dynamicNotification": "Hızı bildirimde göster",
|
||||
"hapticFeedback": "Dokunsal geri bildirim",
|
||||
"actionAtClosing": "Kapatma eylemi",
|
||||
"autoStart": "Oturum açılışında başlat",
|
||||
"silentStart": "Simge durumunda başlat",
|
||||
"ignoreBatteryOptimizations": "Pil optimizasyonunu devre dışı bırak",
|
||||
"ignoreBatteryOptimizationsMsg": "Optimum VPN performansı için kısıtlamaları kaldırın",
|
||||
"memoryLimit": "Bellek limiti",
|
||||
"memoryLimitMsg": "Bellek yetersizliği hataları veya sık uygulama çökmeleri yaşıyorsanız etkinleştirin",
|
||||
"debugMode": "Hata ayıklama modu",
|
||||
"debugModeMsg": "Bu değişikliği uygulamak için uygulamayı yeniden başlatın",
|
||||
"logLevel": "Log seviyesi",
|
||||
"connectionTestUrl": "Bağlantı testi URL'si",
|
||||
"urlTestInterval": "URL testi aralığı",
|
||||
"clashApiPort": "Clash API portu",
|
||||
"useXrayCoreWhenPossible": "Mümkün olduğunda xray-core kullan",
|
||||
"useXrayCoreWhenPossibleMsg": "Abonelik bağlantılarını ayrıştırırken xray-core kullanın. Bu seçeneği etkinleştirmek için bağlantıyı yeniden içe aktarmanız gerekir."
|
||||
},
|
||||
"routing": {
|
||||
"title": "Yönlendirme",
|
||||
"perAppProxy": {
|
||||
"title": "Uygulama bazlı proxy",
|
||||
"hideSysApps": "Sistem uygulamalarını gizle",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Seçimi panodan içe aktar",
|
||||
"file": "Seçimi dosyadan içe aktar",
|
||||
"msg": "İçe aktarma mevcut seçimlerinizin üzerine yazacaktır. Devam etmek istediğinizden emin misiniz?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Seçimi panoya kopyala",
|
||||
"file": "Seçimi dosyaya aktar"
|
||||
},
|
||||
"shareToAll": "Herkesle paylaş",
|
||||
"clearAllSelections": "Tüm seçimleri temizle"
|
||||
},
|
||||
"modes": {
|
||||
"all": "Tümü",
|
||||
"proxy": "Proxy",
|
||||
"bypass": "Atla",
|
||||
"allMsg": "Tüm uygulamaları proxy'le",
|
||||
"proxyMsg": "Yalnızca seçili uygulamaları proxy'le",
|
||||
"bypassMsg": "Seçili uygulamaları proxy'leme"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "Otomatik seçim",
|
||||
"performNow": "Şimdi gerçekleştir",
|
||||
"resetToDefault": "Varsayılana sıfırla",
|
||||
"autoUpdateInterval": "Otomatik güncelleme aralığı",
|
||||
"toast": {
|
||||
"success": "Otomatik uygulama seçimi başarıyla tamamlandı",
|
||||
"failure": "Otomatik seçim başarısız oldu",
|
||||
"regionNotFound": "\"${region}\" bölgesi için otomatik seçim bulunamadı",
|
||||
"alreadyInAuto": "Seçimleriniz zaten otomatik listede"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "Otomatik uygulama seçimi",
|
||||
"msg": "Uygulama bazlı proxy için otomatik seçim özelliği, bölge \"${region}\" olarak değiştirildiği için devre dışı bırakıldı"
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "Bölge",
|
||||
"regions": {
|
||||
"ir": "İran (ir) 🇮🇷",
|
||||
"cn": "Çin (cn) 🇨🇳",
|
||||
"ru": "Rusya (ru) 🇷🇺",
|
||||
"af": "Afganistan (af) 🇦🇫",
|
||||
"id": "Endonezya (id) 🇮🇩",
|
||||
"tr": "Türkiye (tr) 🇹🇷",
|
||||
"br": "Brezilya (br) 🇧🇷",
|
||||
"other": "Diğer"
|
||||
},
|
||||
"blockAds": "Reklamları engelle",
|
||||
"bypassLan": "LAN'ı atla",
|
||||
"resolveDestination": "Hedefi çözümle",
|
||||
"ipv6Route": "IPv6 rotası",
|
||||
"ipv6Modes": {
|
||||
"disable": "Devre dışı bırak",
|
||||
"enable": "Etkinleştir",
|
||||
"prefer": "Tercih et",
|
||||
"only": "Sadece"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "Yönlendirme kuralları",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "Kuralları panodan içe aktar",
|
||||
"file": "Kuralları dosyadan içe aktar"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "Kuralları panoya kopyala",
|
||||
"file": "Kuralları dosyaya kaydet"
|
||||
},
|
||||
"reset": "Kuralları sıfırla"
|
||||
},
|
||||
"deleteRule": "Kuralı sil",
|
||||
"createRule": "Yeni kural oluştur",
|
||||
"rule": {
|
||||
"title": "Kural",
|
||||
"ruleChanged": "Kural değiştirildi",
|
||||
"ruleChangedMsg": "Düzenlemelerinizi kaydetmek istiyor musunuz?",
|
||||
"onlyTunMode": "Yalnızca TUN modunda kullanılabilir",
|
||||
"notAvailabeInThisPlatform": "Bu platformda mevcut değil",
|
||||
"canNotBeEmpty": "Boş olamaz",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "Geçerli \"URL\", örn.\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe veya google chrome veya chrome",
|
||||
"validProcessName": "Geçerli \"İşlem Adı\", örn.\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "Geçerli \"İşlem Yolu\", örn.\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 veya 1-65000",
|
||||
"validPortRange": "Geçerli \"Port\" veya \"Port Aralığı\", örn.\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 veya 10.0.0.0/24",
|
||||
"validIpCidr": "Geçerli IP CIDR, örn.\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com veya dl.google.com",
|
||||
"validDomain": "Geçerli \"Alan Adı\", örn.\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com veya .tr",
|
||||
"validDomainSuffix": "Geçerli \"Alan Adı Son Eki\", örn.\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "İsim",
|
||||
"outbound": "Eşleşirse giden",
|
||||
"rule_set": "Kural seti URL'si",
|
||||
"package_name": "Paket adları",
|
||||
"process_name": "İşlem adları",
|
||||
"process_path": "İşlem yolları",
|
||||
"network": "Ağlar",
|
||||
"port_range": "Hedef portlar",
|
||||
"source_port_range": "Kaynak portlar",
|
||||
"protocol": "Protokol",
|
||||
"ip_cidr": "Hedef IP CIDR",
|
||||
"source_ip_cidr": "Kaynak IP CIDR",
|
||||
"domain": "Alan adı",
|
||||
"domain_suffixe": "Alan adı son eki",
|
||||
"domain_keyword": "Alan adı anahtar kelimesi",
|
||||
"domain_regex": "Alan adı regex"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "Proxy",
|
||||
"direct": "Doğrudan",
|
||||
"direct_with_fragment": "Doğrudan (fragment ile)",
|
||||
"block": "Engelle"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "Tümü",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "Tümü",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "Yeni değer ekle",
|
||||
"update": "Değeri güncelle",
|
||||
"clearList": "Listeyi temizle",
|
||||
"clearListMsg": "Tüm öğeler silindi"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Android uygulamaları",
|
||||
"showSystemApps": "Sistem uygulamalarını göster",
|
||||
"hideSystemApps": "Sistem uygulamalarını gizle",
|
||||
"clearSelection": "Seçimi temizle",
|
||||
"uninstalled": "Kaldırıldı"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "Uzak DNS",
|
||||
"remoteDnsDomainStrategy": "Uzak DNS alan adı stratejisi",
|
||||
"directDns": "Doğrudan DNS",
|
||||
"directDnsDomainStrategy": "Doğrudan DNS alan adı stratejisi",
|
||||
"enableDnsRouting": "DNS yönlendirmeyi etkinleştir",
|
||||
"domainStrategy": {
|
||||
"auto": "Otomatik",
|
||||
"preferIpv6": "IPv6'yı tercih et",
|
||||
"preferIpv4": "IPv4'ü tercih et",
|
||||
"ipv4Only": "Yalnızca IPv4",
|
||||
"ipv6Only": "Yalnızca IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "Gelen",
|
||||
"serviceMode": "Servis modu",
|
||||
"serviceModes": {
|
||||
"proxy": "Yalnızca proxy servisi",
|
||||
"systemProxy": "Sistem proxy'sini ayarla",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN servisi"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "Proxy",
|
||||
"systemProxy": "Sistem proxy'si",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN servisi"
|
||||
},
|
||||
"strictRoute": "Katı yönlendirme",
|
||||
"tunImplementation": "TUN uygulaması",
|
||||
"tunImplementations": {
|
||||
"mixed": "Karışık",
|
||||
"system": "Sistem",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "Karışık port",
|
||||
"tproxyPort": "Şeffaf proxy portu",
|
||||
"directPort": "Direct portu",
|
||||
"allowConnectionFromLan": "VPN'i yerel ağda paylaş"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "TLS hileleri",
|
||||
"enable": "Fragment'ı etkinleştir",
|
||||
"size": "Fragment boyutu",
|
||||
"sleep": "Fragment gecikmesi",
|
||||
"mixedSniCase": {
|
||||
"enable": "Karışık SNI harf durumunu etkinleştir"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "Dolguyu etkinleştir",
|
||||
"size": "Dolgu boyutu"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "WARP'ı etkinleştir",
|
||||
"generateConfig": "WARP yapılandırması oluştur",
|
||||
"configGenerated": "WARP yapılandırması oluşturuldu",
|
||||
"missingConfig": "WARP yapılandırması eksik",
|
||||
"detourMode": "Yönlendirme modu",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "Proxy'leri WARP üzerinden yönlendir",
|
||||
"warpOverProxy": "WARP'ı proxy'ler üzerinden yönlendir",
|
||||
"proxyOverWarpExplain": "Proxy'lerin engelini WARP ile kaldır",
|
||||
"warpOverProxyExplain": "WARP ile ekstra güvenlik"
|
||||
},
|
||||
"licenseKey": "Lisans anahtarı",
|
||||
"cleanIp": "Temiz IP",
|
||||
"port": "Port",
|
||||
"noise": {
|
||||
"count": "Gürültü sayısı",
|
||||
"mode": "Gürültü modu",
|
||||
"size": "Gürültü boyutu",
|
||||
"delay": "Gürültü gecikmesi"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "Bağlantı",
|
||||
"traffic": "Trafik",
|
||||
"trafficLive": "Canlı trafik",
|
||||
"trafficTotal": "Toplam trafik",
|
||||
"uplink": "Yükleme",
|
||||
"downlink": "İndirme",
|
||||
"speed": "Hız",
|
||||
"totalTransferred": "Toplam aktarılan"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "Yükleme",
|
||||
"download": "İndirme",
|
||||
"total": "Toplam trafik",
|
||||
"expireDate": "Bitiş tarihi",
|
||||
"expired": "Süresi doldu",
|
||||
"noTraffic": "Kota doldu",
|
||||
"remainingTime": "Kalan süre",
|
||||
"remainingDuration": "kalan ${duration} gün",
|
||||
"remainingDurationNew": "${duration} gün",
|
||||
"remainingTrafficSemanticLabel": "${consumed} / ${total} trafik kullanıldı",
|
||||
"remainingTraffic": "Kalan trafik",
|
||||
"remainingUsage": "Kalan",
|
||||
"profileSite": "Sağlayıcı",
|
||||
"profileSupport": "Destek"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "Sıralama ölçütü",
|
||||
"sort": {
|
||||
"name": "Alfabetik",
|
||||
"lastUpdate": "Son güncelleme"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Cloudflare WARP onayı",
|
||||
"description(rich)": "Cloudflare WARP ücretsiz bir WireGuard VPN sağlayıcısıdır. Bu seçeneği etkinleştirerek Cloudflare WARP'ın ${tos(Hizmet Şartları)}'nı ve ${privacy(Gizlilik Politikası)}'nı kabul etmiş olursunuz."
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "Güncelleme mevcut",
|
||||
"msg": "@:common.appTitle'ın yeni bir sürümü mevcut. Şimdi güncellemek ister misiniz?",
|
||||
"currentVersion": "Mevcut sürüm: ",
|
||||
"newVersion": "Yeni sürüm: ",
|
||||
"updateNow": "Şimdi güncelle"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "Bu işlem tüm yapılandırma seçeneklerini verilen değerlerle yeniden yazacaktır. Emin misiniz?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "Profili sil",
|
||||
"msg": "Bu profili kalıcı olarak silmek istediğinizden emin misiniz?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "Otomatik seçimi iyileştirme",
|
||||
"msg": "Seçili uygulamaları paylaşarak \"otomatik seçim\" listesini tamamlamaya yardımcı olursunuz"
|
||||
},
|
||||
"import": {
|
||||
"msg": "Bu işlem mevcut tüm uygulama bazlı proxy seçimlerinizi değiştirecektir. Devam etmek istediğinizden emin misiniz?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "Kuralı sil",
|
||||
"msg": "\"$rulename\" kuralını silmek istediğinizden emin misiniz?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "Deneysel özellikler kullanılıyor",
|
||||
"msg": "Bağlantı kalitesini etkileyebilecek ve beklenmedik hatalara neden olabilecek bazı deneysel özellikleri etkinleştirdiniz. Bu seçenekleri istediğiniz zaman yapılandırma sayfasından değiştirebilir veya sıfırlayabilirsiniz.",
|
||||
"disable": "Tekrar gösterme"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "Bir profil seçin",
|
||||
"msg": "VPN bağlantı ayrıntılarınızı içeren bir bağlantı profili ekleyerek başlayalım.\n\nHenüz bir VPN sunucunuz yok mu? Endişelenmeyin, hızlı ve ücretsiz bir şekilde kurmak için aşağıdaki eğitimi takip edin.",
|
||||
"helpBtn": {
|
||||
"label": "Nasıl yapıldığını göster",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "Dış bağlantı uyarısı",
|
||||
"youAreAboutToVisit": "Şu adresi ziyaret etmek üzeresiniz:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "Bu web sitesi güvenilir listemizde değil. Lütfen dikkatli devam edin."
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "Tam etiket:",
|
||||
"type": "Tür:",
|
||||
"testTime": "Test zamanı:",
|
||||
"testDelay": "Test gecikmesi:",
|
||||
"isSelected": "Seçili:",
|
||||
"isGroup": "Grup",
|
||||
"isSecure": "Güvenli:",
|
||||
"port": "Port:",
|
||||
"host": "Sunucu:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "Ülke kodu:",
|
||||
"region": "Bölge:",
|
||||
"city": "Şehir:",
|
||||
"asn": "ASN:",
|
||||
"organization": "Kuruluş:",
|
||||
"location": "Konum:",
|
||||
"postalCode": "Posta kodu:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "Her seferinde sor",
|
||||
"alertMessage": "Uygulama gizlensin mi, kapatılsın mı?",
|
||||
"remember": "Seçimimi hatırla"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "Bağlanmak için dokunun",
|
||||
"connect": "Bağlan",
|
||||
"connecting": "Bağlanıyor...",
|
||||
"connected": "Bağlı",
|
||||
"disconnect": "Bağlantıyı kes",
|
||||
"disconnecting": "Bağlantı kesiliyor...",
|
||||
"reconnect": "Yeniden bağlan",
|
||||
"reconnectMsg": "Değişiklikleri uygulamak için yeniden bağlanılıyor...",
|
||||
"secure": "WARP ile güvende"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "Beklenmeyen hata",
|
||||
"connection": {
|
||||
"unexpected": "Beklenmeyen bağlantı hatası",
|
||||
"timeout": "Bağlantı zaman aşımına uğradı",
|
||||
"badResponse": "Hatalı yanıt",
|
||||
"connectionError": "Bağlantı hatası",
|
||||
"badCertificate": "Geçersiz sertifika"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "Beklenmeyen hata",
|
||||
"notFound": "Profil bulunamadı",
|
||||
"invalidConfig": "Geçersiz yapılandırmalar",
|
||||
"invalidUrl": "Geçersiz URL",
|
||||
"canceledByUser": "Kullanıcı tarafından iptal edildi"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "Beklenmeyen hata",
|
||||
"missingVpnPermission": "VPN izni eksik",
|
||||
"missingNotificationPermission": "Bildirim izni eksik",
|
||||
"core": "Çekirdek hatası"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "Servis çalışmıyor",
|
||||
"missingPrivilege": "Eksik yetki",
|
||||
"missingPrivilegeMsg": "VPN modu yönetici yetkisi gerektirir. Lütfen uygulamayı yönetici olarak yeniden başlatın veya servis modunu değiştirin.",
|
||||
"invalidConfigOptions": "Geçersiz yapılandırma seçenekleri",
|
||||
"invalidConfig": "Geçersiz yapılandırma"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "WARP lisansı eksik",
|
||||
"missingLicenseMsg": "Seçili profil WARP özelliğini kullanıyor. Bu özelliği kullanmak için WARP lisansını kabul etmeniz gerekir."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "开始",
|
||||
"version": "版本",
|
||||
"ok": "确定",
|
||||
"cancel": "取消",
|
||||
"kContinue": "继续",
|
||||
"showMore": "显示更多",
|
||||
"showLess": "显示更少",
|
||||
"filter": "筛选",
|
||||
"all": "全部",
|
||||
"pause": "暂停",
|
||||
"resume": "恢复",
|
||||
"clear": "清除",
|
||||
"close": "关闭",
|
||||
"auto": "自动",
|
||||
"manually": "手动",
|
||||
"name": "名称",
|
||||
"url": "URL",
|
||||
"add": "添加",
|
||||
"clipboard": "剪贴板",
|
||||
"addToClipboard": "添加到剪贴板",
|
||||
"scanQr": "扫描二维码",
|
||||
"free": "免费",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "帮助",
|
||||
"save": "保存",
|
||||
"update": "更新",
|
||||
"share": "分享",
|
||||
"edit": "编辑",
|
||||
"delete": "删除",
|
||||
"discard": "放弃",
|
||||
"import": "导入",
|
||||
"export": "导出",
|
||||
"later": "稍后",
|
||||
"ignore": "忽略",
|
||||
"quit": "退出",
|
||||
"notSet": "未设置",
|
||||
"hide": "隐藏",
|
||||
"exit": "退出",
|
||||
"reset": "重置",
|
||||
"done": "完成",
|
||||
"search": "搜索",
|
||||
"decline": "拒绝",
|
||||
"agree": "同意",
|
||||
"empty": "空",
|
||||
"unknown": "未知",
|
||||
"hidden": "隐藏",
|
||||
"timeout": "超时",
|
||||
"sort": "排序",
|
||||
"dashboard": "仪表盘",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n 天",
|
||||
"other": "$n 天"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n 小时",
|
||||
"other": "$n 小时"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "权限被拒绝"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "已成功添加到剪贴板",
|
||||
"failure": "复制到剪贴板失败",
|
||||
"contentTooLarge": "内容过大,请使用导出文件"
|
||||
},
|
||||
"file": {
|
||||
"success": "JSON 文件创建成功",
|
||||
"failure": "创建文件失败"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "确认导入",
|
||||
"success": "导入成功",
|
||||
"failure": "导入失败"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "畅享无限制网络的所需一切",
|
||||
"termsAndPolicyCaution(rich)": "继续即表示您同意 ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "由 Hiddify 用 ❤️ 制作 - ${tap_source(开源)} (${tap_license(许可证)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "主页",
|
||||
"quickSettings": "快速设置"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "代理",
|
||||
"sort": "排序代理",
|
||||
"testDelay": "测试延迟",
|
||||
"empty": "无可用代理",
|
||||
"activeProxy": "当前代理",
|
||||
"unknownIp": "未知 IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "默认",
|
||||
"name": "按名称",
|
||||
"delay": "按延迟"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "IP 地址",
|
||||
"country": "国家",
|
||||
"organization": "组织"
|
||||
},
|
||||
"delay": {
|
||||
"result": "延迟:${delay}毫秒",
|
||||
"timeout": "延迟测试超时",
|
||||
"testing": "延迟:测试中..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "配置文件",
|
||||
"add": "添加配置文件",
|
||||
"update": "更新配置文件",
|
||||
"viewAllProfiles": "查看所有配置文件",
|
||||
"activeProfileName": "当前配置文件:\"${name}\"",
|
||||
"nonActiveProfileName": "选择 \"${name}\" 作为当前配置文件",
|
||||
"freeSubNotFound": "未找到免费订阅",
|
||||
"freeSubNotFoundForRegion": "未找到 \"${region}\" 地区的免费订阅",
|
||||
"failedToLoad": "加载失败",
|
||||
"updateSubscriptions": "更新订阅",
|
||||
"share": {
|
||||
"urlToClipboard": "URL 到剪贴板",
|
||||
"showUrlQr": "显示 URL 二维码",
|
||||
"jsonToClipboard": "JSON 到剪贴板"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "配置文件保存成功"
|
||||
},
|
||||
"invalidUrl": "无效的 URL",
|
||||
"add": {
|
||||
"failure": "添加配置文件失败"
|
||||
},
|
||||
"update": {
|
||||
"success": "配置文件更新成功",
|
||||
"successNamed": "\"${name}\" 更新成功",
|
||||
"failure": "更新配置文件失败",
|
||||
"failureNamed": "更新 \"${name}\" 失败"
|
||||
},
|
||||
"delete": {
|
||||
"success": "配置文件删除成功"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "配置文件",
|
||||
"lastUpdate": "最后更新",
|
||||
"form": {
|
||||
"nameHint": "配置文件名称",
|
||||
"emptyName": "名称为必填项",
|
||||
"invalidUrl": "无效的 URL",
|
||||
"urlHint": "完整的配置 URL",
|
||||
"disableAutoUpdate": "禁用自动更新",
|
||||
"autoUpdateInterval": "自动更新间隔",
|
||||
"loading": "正在添加配置文件..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "日志",
|
||||
"shareCoreLogs": "分享核心日志",
|
||||
"shareAppLogs": "分享应用日志"
|
||||
},
|
||||
"about": {
|
||||
"title": "关于",
|
||||
"notAvailableMsg": "已是最新版本",
|
||||
"checkForUpdate": "检查更新",
|
||||
"openWorkingDir": "打开工作目录",
|
||||
"sourceCode": "源代码",
|
||||
"telegramChannel": "Telegram 频道",
|
||||
"termsAndConditions": "条款与条件",
|
||||
"privacyPolicy": "隐私政策"
|
||||
},
|
||||
"settings": {
|
||||
"title": "设置",
|
||||
"resetTunnel": "重置 VPN 配置文件",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "从剪贴板导入选项",
|
||||
"file": "从文件导入选项"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "复制匿名选项到剪贴板",
|
||||
"anonymousToFile": "导出匿名选项到文件",
|
||||
"allToClipboard": "复制所有选项到剪贴板",
|
||||
"allToFile": "导出所有选项到文件"
|
||||
},
|
||||
"reset": "重置选项"
|
||||
},
|
||||
"general": {
|
||||
"title": "通用",
|
||||
"locale": "语言",
|
||||
"themeMode": "主题模式",
|
||||
"themeModes": {
|
||||
"system": "跟随系统",
|
||||
"dark": "深色模式",
|
||||
"light": "浅色模式",
|
||||
"black": "纯黑模式"
|
||||
},
|
||||
"enableAnalytics": "启用分析",
|
||||
"enableAnalyticsMsg": "允许收集分析数据和发送崩溃报告以改进应用",
|
||||
"autoIpCheck": "自动检查连接 IP",
|
||||
"dynamicNotification": "在通知中显示速度",
|
||||
"hapticFeedback": "触觉反馈",
|
||||
"actionAtClosing": "关闭时操作",
|
||||
"autoStart": "开机自启",
|
||||
"silentStart": "静默启动",
|
||||
"ignoreBatteryOptimizations": "忽略电池优化",
|
||||
"ignoreBatteryOptimizationsMsg": "移除限制以获得最佳 VPN 性能",
|
||||
"memoryLimit": "内存限制",
|
||||
"memoryLimitMsg": "如果您遇到内存不足错误或应用频繁崩溃,请启用此选项",
|
||||
"debugMode": "调试模式",
|
||||
"debugModeMsg": "重启应用以应用此更改",
|
||||
"logLevel": "日志级别",
|
||||
"connectionTestUrl": "连接测试 URL",
|
||||
"urlTestInterval": "URL 测试间隔",
|
||||
"clashApiPort": "Clash API 端口",
|
||||
"useXrayCoreWhenPossible": "尽可能使用 xray-core",
|
||||
"useXrayCoreWhenPossibleMsg": "解析订阅链接时使用 xray-core。您需要重新导入订阅链接才能启用此选项"
|
||||
},
|
||||
"routing": {
|
||||
"title": "路由",
|
||||
"perAppProxy": {
|
||||
"title": "分应用代理",
|
||||
"hideSysApps": "隐藏系统应用",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "从剪贴板导入选择",
|
||||
"file": "从文件导入选择",
|
||||
"msg": "导入将替换您当前的选择。确定要继续吗?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "复制选择到剪贴板",
|
||||
"file": "导出选择到文件"
|
||||
},
|
||||
"shareToAll": "分享给所有人",
|
||||
"clearAllSelections": "清除所有选择"
|
||||
},
|
||||
"modes": {
|
||||
"all": "全部",
|
||||
"proxy": "代理",
|
||||
"bypass": "绕过",
|
||||
"allMsg": "代理所有应用",
|
||||
"proxyMsg": "仅代理选定应用",
|
||||
"bypassMsg": "不代理选定应用"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "自动选择",
|
||||
"performNow": "立即执行",
|
||||
"resetToDefault": "重置为默认",
|
||||
"autoUpdateInterval": "自动更新间隔",
|
||||
"toast": {
|
||||
"success": "自动选择应用成功完成",
|
||||
"failure": "自动选择失败",
|
||||
"regionNotFound": "未找到 \"${region}\" 地区的自动选择",
|
||||
"alreadyInAuto": "您的选择已在自动列表中"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "自动选择应用",
|
||||
"msg": "由于地区更改为 \"${region}\",分应用代理的自动选择功能已被禁用"
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "地区",
|
||||
"regions": {
|
||||
"ir": "伊朗 (ir) 🇮🇷",
|
||||
"cn": "中国 (cn) 🇨🇳",
|
||||
"ru": "俄罗斯 (ru) 🇷🇺",
|
||||
"af": "阿富汗 (af) 🇦🇫",
|
||||
"id": "印度尼西亚 (id) 🇮🇩",
|
||||
"tr": "土耳其 (tr) 🇹🇷",
|
||||
"br": "巴西 (br) 🇧🇷",
|
||||
"other": "其他"
|
||||
},
|
||||
"blockAds": "拦截广告",
|
||||
"bypassLan": "绕过局域网",
|
||||
"resolveDestination": "解析目的地",
|
||||
"ipv6Route": "IPv6 路由",
|
||||
"ipv6Modes": {
|
||||
"disable": "禁用",
|
||||
"enable": "启用",
|
||||
"prefer": "首选",
|
||||
"only": "仅"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "路由规则",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "从剪贴板导入规则",
|
||||
"file": "从文件导入规则"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "复制规则到剪贴板",
|
||||
"file": "保存规则到文件"
|
||||
},
|
||||
"reset": "重置规则"
|
||||
},
|
||||
"deleteRule": "删除规则",
|
||||
"createRule": "创建新规则",
|
||||
"rule": {
|
||||
"title": "规则",
|
||||
"ruleChanged": "规则已更改",
|
||||
"ruleChangedMsg": "您想保存您的编辑吗?",
|
||||
"onlyTunMode": "仅在 TUN 模式下可用",
|
||||
"notAvailabeInThisPlatform": "在此平台上不可用",
|
||||
"canNotBeEmpty": "不能为空",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "有效的 \"URL\",例如\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe 或 google chrome 或 chrome",
|
||||
"validProcessName": "有效的 \"进程名\",例如\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "有效的 \"进程路径\",例如\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 或 1-65000",
|
||||
"validPortRange": "有效的 \"端口\" 或 \"端口范围\",例如\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 或 10.0.0.0/24",
|
||||
"validIpCidr": "有效的 IP CIDR,例如\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com 或 dl.google.com",
|
||||
"validDomain": "有效的 \"域名\",例如\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com 或 .cn",
|
||||
"validDomainSuffix": "有效的 \"域名后缀\",例如\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "名称",
|
||||
"outbound": "匹配时出站",
|
||||
"rule_set": "规则集 URL",
|
||||
"package_name": "包名",
|
||||
"process_name": "进程名",
|
||||
"process_path": "进程路径",
|
||||
"network": "网络",
|
||||
"port_range": "目标端口",
|
||||
"source_port_range": "源端口",
|
||||
"protocol": "协议",
|
||||
"ip_cidr": "目标 IP CIDR",
|
||||
"source_ip_cidr": "源 IP CIDR",
|
||||
"domain": "域名",
|
||||
"domain_suffixe": "域名后缀",
|
||||
"domain_keyword": "域名关键词",
|
||||
"domain_regex": "域名正则表达式"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "代理",
|
||||
"direct": "直连",
|
||||
"direct_with_fragment": "直连并分片",
|
||||
"block": "拦截"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "全部",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "全部",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "添加新值",
|
||||
"update": "更新值",
|
||||
"clearList": "清空列表",
|
||||
"clearListMsg": "所有项目已删除"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "安卓应用",
|
||||
"showSystemApps": "显示系统应用",
|
||||
"hideSystemApps": "隐藏系统应用",
|
||||
"clearSelection": "清除选择",
|
||||
"uninstalled": "已卸载"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "远程 DNS",
|
||||
"remoteDnsDomainStrategy": "远程 DNS 域名策略",
|
||||
"directDns": "直连 DNS",
|
||||
"directDnsDomainStrategy": "直连 DNS 域名策略",
|
||||
"enableDnsRouting": "启用 DNS 路由",
|
||||
"domainStrategy": {
|
||||
"auto": "自动",
|
||||
"preferIpv6": "首选 IPv6",
|
||||
"preferIpv4": "首选 IPv4",
|
||||
"ipv4Only": "仅 IPv4",
|
||||
"ipv6Only": "仅 IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "入站",
|
||||
"serviceMode": "服务模式",
|
||||
"serviceModes": {
|
||||
"proxy": "仅代理服务",
|
||||
"systemProxy": "设置系统代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服务"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "代理",
|
||||
"systemProxy": "系统代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服务"
|
||||
},
|
||||
"strictRoute": "严格路由",
|
||||
"tunImplementation": "TUN 实现",
|
||||
"tunImplementations": {
|
||||
"mixed": "混合",
|
||||
"system": "系统",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "混合端口",
|
||||
"tproxyPort": "透明代理端口",
|
||||
"directPort": "本地 Direct 端口",
|
||||
"allowConnectionFromLan": "允许来自局域网的连接"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "TLS 技巧",
|
||||
"enable": "启用分片",
|
||||
"size": "分片大小",
|
||||
"sleep": "分片延迟",
|
||||
"mixedSniCase": {
|
||||
"enable": "启用混合大小写 SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "启用填充",
|
||||
"size": "填充大小"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "启用 WARP",
|
||||
"generateConfig": "生成 WARP 配置",
|
||||
"configGenerated": "WARP 配置已生成",
|
||||
"missingConfig": "WARP 配置缺失",
|
||||
"detourMode": "WARP 路由模式",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "通过 WARP 路由代理",
|
||||
"warpOverProxy": "通过代理路由 WARP",
|
||||
"proxyOverWarpExplain": "通过 WARP 解锁代理",
|
||||
"warpOverProxyExplain": "通过 WARP 增强安全性"
|
||||
},
|
||||
"licenseKey": "许可证密钥",
|
||||
"cleanIp": "优选 IP",
|
||||
"port": "端口",
|
||||
"noise": {
|
||||
"count": "噪声数量",
|
||||
"mode": "噪声模式",
|
||||
"size": "噪声大小",
|
||||
"delay": "噪声延迟"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "连接",
|
||||
"traffic": "流量",
|
||||
"trafficLive": "实时流量",
|
||||
"trafficTotal": "总流量",
|
||||
"uplink": "上传",
|
||||
"downlink": "下载",
|
||||
"speed": "速度",
|
||||
"totalTransferred": "总传输量"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "上传",
|
||||
"download": "下载",
|
||||
"total": "总流量",
|
||||
"expireDate": "到期日期",
|
||||
"expired": "已过期",
|
||||
"noTraffic": "流量已用尽",
|
||||
"remainingTime": "剩余时间",
|
||||
"remainingDuration": "剩余 ${duration} 天",
|
||||
"remainingDurationNew": "${duration} 天",
|
||||
"remainingTrafficSemanticLabel": "已使用 ${consumed} / ${total} 流量",
|
||||
"remainingTraffic": "剩余流量",
|
||||
"remainingUsage": "剩余",
|
||||
"profileSite": "提供商",
|
||||
"profileSupport": "支持"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "排序方式",
|
||||
"sort": {
|
||||
"name": "按字母顺序",
|
||||
"lastUpdate": "最近更新"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Cloudflare WARP 同意书",
|
||||
"description(rich)": "Cloudflare WARP 是一个免费的 WireGuard VPN 提供商。启用此选项即表示您同意 Cloudflare WARP 的 ${tos(服务条款)} 和 ${privacy(隐私政策)}。"
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "有可用更新",
|
||||
"msg": "@:common.appTitle 的新版本已发布。您想现在更新吗?",
|
||||
"currentVersion": "当前版本:",
|
||||
"newVersion": "新版本:",
|
||||
"updateNow": "立即更新"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "这将用提供的值覆盖所有配置选项。您确定吗?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "删除配置文件",
|
||||
"msg": "您确定要永久删除此配置文件吗?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "改进自动选择",
|
||||
"msg": "通过分享您选择的应用,可以帮助完善“自动选择”列表"
|
||||
},
|
||||
"import": {
|
||||
"msg": "这将替换您当前所有的分应用代理选择。您确定要继续吗?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "删除规则",
|
||||
"msg": "您确定要删除规则 \"$rulename\" 吗?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "正在使用实验性功能",
|
||||
"msg": "您已启用了一些实验性功能,这可能会影响连接质量并导致意外错误。您可以随时在配置选项页面更改或重置这些选项。",
|
||||
"disable": "不再显示"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "选择一个配置文件",
|
||||
"msg": "让我们从添加一个包含您 VPN 连接详细信息的配置文件开始。\n\n还没有 VPN 服务器?别担心,按照下面的教程,您可以快速免费地设置一个。",
|
||||
"helpBtn": {
|
||||
"label": "告诉我如何操作",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "外部链接警告",
|
||||
"youAreAboutToVisit": "您即将访问:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "此网站不在我们的信任列表中。请谨慎操作。"
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "完整标签:",
|
||||
"type": "类型:",
|
||||
"testTime": "测试时间:",
|
||||
"testDelay": "测试延迟:",
|
||||
"isSelected": "已选择:",
|
||||
"isGroup": "是组",
|
||||
"isSecure": "安全:",
|
||||
"port": "端口:",
|
||||
"host": "主机:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "国家代码:",
|
||||
"region": "地区:",
|
||||
"city": "城市:",
|
||||
"asn": "ASN:",
|
||||
"organization": "组织:",
|
||||
"location": "位置:",
|
||||
"postalCode": "邮政编码:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "每次询问",
|
||||
"alertMessage": "隐藏还是退出应用程序?",
|
||||
"remember": "记住我的选择"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "点击连接",
|
||||
"connect": "连接",
|
||||
"connecting": "连接中...",
|
||||
"connected": "已连接",
|
||||
"disconnect": "断开连接",
|
||||
"disconnecting": "断开连接中...",
|
||||
"reconnect": "重新连接",
|
||||
"reconnectMsg": "正在重新连接以应用更改...",
|
||||
"secure": "由 WARP 保护"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "意外错误",
|
||||
"connection": {
|
||||
"unexpected": "意外连接错误",
|
||||
"timeout": "连接超时",
|
||||
"badResponse": "响应错误",
|
||||
"connectionError": "连接错误",
|
||||
"badCertificate": "证书无效"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "意外错误",
|
||||
"notFound": "未找到配置文件",
|
||||
"invalidConfig": "配置无效",
|
||||
"invalidUrl": "URL 无效",
|
||||
"canceledByUser": "用户已取消"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "意外失败",
|
||||
"missingVpnPermission": "缺少 VPN 权限",
|
||||
"missingNotificationPermission": "缺少通知权限",
|
||||
"core": "核心错误"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "服务未运行",
|
||||
"missingPrivilege": "缺少权限",
|
||||
"missingPrivilegeMsg": "VPN 模式需要管理员权限。请以管理员身份重新启动应用,或更改服务模式。",
|
||||
"invalidConfigOptions": "配置选项无效",
|
||||
"invalidConfig": "配置无效"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "WARP 许可证缺失",
|
||||
"missingLicenseMsg": "所选配置文件使用 WARP 功能;要使用此功能,必须同意 WARP 许可证。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
{
|
||||
"common": {
|
||||
"appTitle": "Hiddify",
|
||||
"start": "開始",
|
||||
"version": "版本",
|
||||
"ok": "確定",
|
||||
"cancel": "取消",
|
||||
"kContinue": "繼續",
|
||||
"showMore": "顯示更多",
|
||||
"showLess": "顯示較少",
|
||||
"filter": "篩選",
|
||||
"all": "全部",
|
||||
"pause": "暫停",
|
||||
"resume": "恢復",
|
||||
"clear": "清除",
|
||||
"close": "關閉",
|
||||
"auto": "自動",
|
||||
"manually": "手動",
|
||||
"name": "名稱",
|
||||
"url": "URL",
|
||||
"add": "新增",
|
||||
"clipboard": "剪貼簿",
|
||||
"addToClipboard": "新增至剪貼簿",
|
||||
"scanQr": "掃描 QR Code",
|
||||
"free": "免費",
|
||||
"warp": "WARP",
|
||||
"fragment": "Fragment",
|
||||
"help": "說明",
|
||||
"save": "儲存",
|
||||
"update": "更新",
|
||||
"share": "分享",
|
||||
"edit": "編輯",
|
||||
"delete": "刪除",
|
||||
"discard": "捨棄",
|
||||
"import": "匯入",
|
||||
"export": "匯出",
|
||||
"later": "稍後",
|
||||
"ignore": "忽略",
|
||||
"quit": "退出",
|
||||
"notSet": "未設定",
|
||||
"hide": "隱藏",
|
||||
"exit": "退出",
|
||||
"reset": "重設",
|
||||
"done": "完成",
|
||||
"search": "搜尋",
|
||||
"decline": "拒絕",
|
||||
"agree": "同意",
|
||||
"empty": "空",
|
||||
"unknown": "未知",
|
||||
"hidden": "隱藏",
|
||||
"timeout": "超時",
|
||||
"sort": "排序",
|
||||
"dashboard": "儀表板",
|
||||
"interval": {
|
||||
"day": {
|
||||
"zero": "",
|
||||
"one": "$n 天",
|
||||
"other": "$n 天"
|
||||
},
|
||||
"hour": {
|
||||
"zero": "",
|
||||
"one": "$n 小時",
|
||||
"other": "$n 小時"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"permission": {
|
||||
"denied": "權限被拒絕"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": {
|
||||
"success": "已成功新增至剪貼簿",
|
||||
"failure": "複製到剪貼簿失敗",
|
||||
"contentTooLarge": "內容過大,請改用匯出檔案"
|
||||
},
|
||||
"file": {
|
||||
"success": "JSON 檔案建立成功",
|
||||
"failure": "建立檔案失敗"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"confirm": "確認匯入",
|
||||
"success": "匯入成功",
|
||||
"failure": "匯入失敗"
|
||||
}
|
||||
}
|
||||
},
|
||||
"intro": {
|
||||
"banner": "暢享無限制網路的所需一切",
|
||||
"termsAndPolicyCaution(rich)": "繼續即表示您同意 ${tap(@:pages.about.termsAndConditions)}",
|
||||
"info(rich)": "由 Hiddify 以 ❤️ 製作 - ${tap_source(開源)} (${tap_license(授權)})"
|
||||
},
|
||||
"pages": {
|
||||
"home": {
|
||||
"title": "首頁",
|
||||
"quickSettings": "快速設定"
|
||||
},
|
||||
"proxies": {
|
||||
"title": "代理",
|
||||
"sort": "排序代理",
|
||||
"testDelay": "測試延遲",
|
||||
"empty": "無可用代理",
|
||||
"activeProxy": "當前代理",
|
||||
"unknownIp": "未知 IP",
|
||||
"sortOptions": {
|
||||
"unsorted": "預設",
|
||||
"name": "按名稱",
|
||||
"delay": "按延遲"
|
||||
},
|
||||
"ipInfo": {
|
||||
"address": "IP 位址",
|
||||
"country": "國家",
|
||||
"organization": "組織"
|
||||
},
|
||||
"delay": {
|
||||
"result": "延遲:${delay}毫秒",
|
||||
"timeout": "延遲測試超時",
|
||||
"testing": "延遲:測試中..."
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"title": "設定檔",
|
||||
"add": "新增設定檔",
|
||||
"update": "更新設定檔",
|
||||
"viewAllProfiles": "檢視所有設定檔",
|
||||
"activeProfileName": "目前設定檔:「${name}」",
|
||||
"nonActiveProfileName": "選擇「${name}」作為目前設定檔",
|
||||
"freeSubNotFound": "未找到免費訂閱",
|
||||
"freeSubNotFoundForRegion": "未找到「${region}」地區的免費訂閱",
|
||||
"failedToLoad": "載入失敗",
|
||||
"updateSubscriptions": "更新訂閱",
|
||||
"share": {
|
||||
"urlToClipboard": "URL 到剪貼簿",
|
||||
"showUrlQr": "顯示 URL QR Code",
|
||||
"jsonToClipboard": "JSON 到剪貼簿"
|
||||
},
|
||||
"msg": {
|
||||
"save": {
|
||||
"success": "設定檔儲存成功"
|
||||
},
|
||||
"invalidUrl": "無效的 URL",
|
||||
"add": {
|
||||
"failure": "新增設定檔失敗"
|
||||
},
|
||||
"update": {
|
||||
"success": "設定檔更新成功",
|
||||
"successNamed": "「${name}」更新成功",
|
||||
"failure": "更新設定檔失敗",
|
||||
"failureNamed": "更新「${name}」失敗"
|
||||
},
|
||||
"delete": {
|
||||
"success": "設定檔刪除成功"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profileDetails": {
|
||||
"title": "設定檔",
|
||||
"lastUpdate": "最後更新",
|
||||
"form": {
|
||||
"nameHint": "設定檔名稱",
|
||||
"emptyName": "名稱為必填項",
|
||||
"invalidUrl": "無效的 URL",
|
||||
"urlHint": "完整的設定 URL",
|
||||
"disableAutoUpdate": "停用自動更新",
|
||||
"autoUpdateInterval": "自動更新間隔",
|
||||
"loading": "正在新增設定檔..."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"title": "日誌",
|
||||
"shareCoreLogs": "分享核心日誌",
|
||||
"shareAppLogs": "分享應用程式日誌"
|
||||
},
|
||||
"about": {
|
||||
"title": "關於",
|
||||
"notAvailableMsg": "已是最新版本",
|
||||
"checkForUpdate": "檢查更新",
|
||||
"openWorkingDir": "開啟工作目錄",
|
||||
"sourceCode": "原始碼",
|
||||
"telegramChannel": "Telegram 頻道",
|
||||
"termsAndConditions": "條款與條件",
|
||||
"privacyPolicy": "隱私權政策"
|
||||
},
|
||||
"settings": {
|
||||
"title": "設定",
|
||||
"resetTunnel": "重設 VPN 設定檔",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "從剪貼簿匯入選項",
|
||||
"file": "從檔案匯入選項"
|
||||
},
|
||||
"export": {
|
||||
"anonymousToClipboard": "複製匿名選項到剪貼簿",
|
||||
"anonymousToFile": "匯出匿名選項到檔案",
|
||||
"allToClipboard": "複製所有選項到剪貼簿",
|
||||
"allToFile": "匯出所有選項到檔案"
|
||||
},
|
||||
"reset": "重設選項"
|
||||
},
|
||||
"general": {
|
||||
"title": "一般",
|
||||
"locale": "語言",
|
||||
"themeMode": "主題模式",
|
||||
"themeModes": {
|
||||
"system": "跟隨系統",
|
||||
"dark": "深色模式",
|
||||
"light": "淺色模式",
|
||||
"black": "純黑模式"
|
||||
},
|
||||
"enableAnalytics": "啟用分析",
|
||||
"enableAnalyticsMsg": "允許收集分析資料和傳送崩潰報告以改進應用程式",
|
||||
"autoIpCheck": "自動檢查連線 IP",
|
||||
"dynamicNotification": "在通知中顯示速度",
|
||||
"hapticFeedback": "觸覺回饋",
|
||||
"actionAtClosing": "關閉時操作",
|
||||
"autoStart": "開機自啟",
|
||||
"silentStart": "靜默啟動",
|
||||
"ignoreBatteryOptimizations": "忽略電池最佳化",
|
||||
"ignoreBatteryOptimizationsMsg": "移除限制以獲得最佳 VPN 效能",
|
||||
"memoryLimit": "記憶體限制",
|
||||
"memoryLimitMsg": "如果您遇到記憶體不足錯誤或應用程式頻繁崩潰,請啟用此選項",
|
||||
"debugMode": "偵錯模式",
|
||||
"debugModeMsg": "重新啟動應用程式以套用此變更",
|
||||
"logLevel": "日誌級別",
|
||||
"connectionTestUrl": "連線測試 URL",
|
||||
"urlTestInterval": "URL 測試間隔",
|
||||
"clashApiPort": "Clash API 連接埠",
|
||||
"useXrayCoreWhenPossible": "盡可能使用 xray-core",
|
||||
"useXrayCoreWhenPossibleMsg": "解析訂閱連結時使用 xray-core。您需要重新匯入訂閱連結才能啟用此選項"
|
||||
},
|
||||
"routing": {
|
||||
"title": "路由",
|
||||
"perAppProxy": {
|
||||
"title": "依應用程式代理",
|
||||
"hideSysApps": "隱藏系統應用程式",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "從剪貼簿匯入選擇",
|
||||
"file": "從檔案匯入選擇",
|
||||
"msg": "匯入將取代您目前的選擇。確定要繼續嗎?"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "複製選擇到剪貼簿",
|
||||
"file": "匯出選擇到檔案"
|
||||
},
|
||||
"shareToAll": "分享給所有人",
|
||||
"clearAllSelections": "清除所有選擇"
|
||||
},
|
||||
"modes": {
|
||||
"all": "全部",
|
||||
"proxy": "代理",
|
||||
"bypass": "繞過",
|
||||
"allMsg": "代理所有應用程式",
|
||||
"proxyMsg": "僅代理選定應用程式",
|
||||
"bypassMsg": "不代理選定應用程式"
|
||||
},
|
||||
"autoSelection": {
|
||||
"title": "自動選擇",
|
||||
"performNow": "立即執行",
|
||||
"resetToDefault": "重設為預設",
|
||||
"autoUpdateInterval": "自動更新間隔",
|
||||
"toast": {
|
||||
"success": "自動選擇應用程式成功完成",
|
||||
"failure": "自動選擇失敗",
|
||||
"regionNotFound": "未找到「${region}」地區的自動選擇",
|
||||
"alreadyInAuto": "您的選擇已在自動清單中"
|
||||
},
|
||||
"dialog": {
|
||||
"title": "自動選擇應用程式",
|
||||
"msg": "由於地區更改為「${region}」,依應用程式代理的自動選擇功能已被停用"
|
||||
}
|
||||
}
|
||||
},
|
||||
"region": "地區",
|
||||
"regions": {
|
||||
"ir": "伊朗 (ir) 🇮🇷",
|
||||
"cn": "中國 (cn) 🇨🇳",
|
||||
"ru": "俄羅斯 (ru) 🇷🇺",
|
||||
"af": "阿富汗 (af) 🇦🇫",
|
||||
"id": "印尼 (id) 🇮🇩",
|
||||
"tr": "土耳其 (tr) 🇹🇷",
|
||||
"br": "巴西 (br) 🇧🇷",
|
||||
"other": "其他"
|
||||
},
|
||||
"blockAds": "攔截廣告",
|
||||
"bypassLan": "繞過區域網路",
|
||||
"resolveDestination": "解析目的地",
|
||||
"ipv6Route": "IPv6 路由",
|
||||
"ipv6Modes": {
|
||||
"disable": "停用",
|
||||
"enable": "啟用",
|
||||
"prefer": "首選",
|
||||
"only": "僅"
|
||||
},
|
||||
"routeRule": {
|
||||
"title": "路由規則",
|
||||
"options": {
|
||||
"import": {
|
||||
"clipboard": "從剪貼簿匯入規則",
|
||||
"file": "從檔案匯入規則"
|
||||
},
|
||||
"export": {
|
||||
"clipboard": "複製規則到剪貼簿",
|
||||
"file": "儲存規則到檔案"
|
||||
},
|
||||
"reset": "重設規則"
|
||||
},
|
||||
"deleteRule": "刪除規則",
|
||||
"createRule": "建立新規則",
|
||||
"rule": {
|
||||
"title": "規則",
|
||||
"ruleChanged": "規則已變更",
|
||||
"ruleChangedMsg": "您想儲存您的編輯嗎?",
|
||||
"onlyTunMode": "僅在 TUN 模式下可用",
|
||||
"notAvailabeInThisPlatform": "在此平台上不可用",
|
||||
"canNotBeEmpty": "不能為空",
|
||||
"validUrlEx": "https://example.com",
|
||||
"validUrl": "有效的「URL」,例如\n@:pages.settings.routing.routeRule.rule.validUrlEx",
|
||||
"validProcessNameEx": "Chrome.exe 或 google chrome 或 chrome",
|
||||
"validProcessName": "有效的「處理程序名稱」,例如\n@:pages.settings.routing.routeRule.rule.validProcessNameEx",
|
||||
"validProcessPathEx": "C:\\Pro...\\chrome.exe\n/App.../Google Chrome\n/usr/lib.../chrome",
|
||||
"validProcessPath": "有效的「處理程序路徑」,例如\n@:pages.settings.routing.routeRule.rule.validProcessPathEx",
|
||||
"validPortRangeEx": "80 或 1-65000",
|
||||
"validPortRange": "有效的「連接埠」或「連接埠範圍」,例如\n@:pages.settings.routing.routeRule.rule.validPortRangeEx",
|
||||
"validIpCidrEx": "8.8.8.8 或 10.0.0.0/24",
|
||||
"validIpCidr": "有效的 IP CIDR,例如\n@:pages.settings.routing.routeRule.rule.validIpCidrEx",
|
||||
"validDomainEx": "Google.com 或 dl.google.com",
|
||||
"validDomain": "有效的「網域」,例如\n@:pages.settings.routing.routeRule.rule.validDomainEx",
|
||||
"validDomainSuffixEx": ".com 或 .tw",
|
||||
"validDomainSuffix": "有效的「網域後綴」,例如\n@:pages.settings.routing.routeRule.rule.validDomainSuffixEx",
|
||||
"tileTitle(map)": {
|
||||
"name": "名稱",
|
||||
"outbound": "符合時出站",
|
||||
"rule_set": "規則集 URL",
|
||||
"package_name": "套件名稱",
|
||||
"process_name": "處理程序名稱",
|
||||
"process_path": "處理程序路徑",
|
||||
"network": "網路",
|
||||
"port_range": "目標連接埠",
|
||||
"source_port_range": "來源連接埠",
|
||||
"protocol": "協定",
|
||||
"ip_cidr": "目標 IP CIDR",
|
||||
"source_ip_cidr": "來源 IP CIDR",
|
||||
"domain": "網域",
|
||||
"domain_suffixe": "網域後綴",
|
||||
"domain_keyword": "網域關鍵字",
|
||||
"domain_regex": "網域正規表示式"
|
||||
},
|
||||
"outbound(map)": {
|
||||
"proxy": "代理",
|
||||
"direct": "直連",
|
||||
"direct_with_fragment": "直連並分片",
|
||||
"block": "攔截"
|
||||
},
|
||||
"network(map)": {
|
||||
"all": "全部",
|
||||
"tcp": "TCP",
|
||||
"udp": "UDP"
|
||||
},
|
||||
"protocol(map)": {
|
||||
"": "全部",
|
||||
"tls": "TLS",
|
||||
"http": "HTTP",
|
||||
"quic": "QUIC",
|
||||
"stun": "STUN",
|
||||
"dns": "DNS",
|
||||
"bittorrent": "BitTorrent"
|
||||
}
|
||||
},
|
||||
"genericList": {
|
||||
"addNew": "新增值",
|
||||
"update": "更新值",
|
||||
"clearList": "清除清單",
|
||||
"clearListMsg": "所有項目已刪除"
|
||||
},
|
||||
"androidApps": {
|
||||
"pageTitle": "Android 應用程式",
|
||||
"showSystemApps": "顯示系統應用程式",
|
||||
"hideSystemApps": "隱藏系統應用程式",
|
||||
"clearSelection": "清除選擇",
|
||||
"uninstalled": "已解除安裝"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"title": "DNS",
|
||||
"remoteDns": "遠端 DNS",
|
||||
"remoteDnsDomainStrategy": "遠端 DNS 域名策略",
|
||||
"directDns": "直連 DNS",
|
||||
"directDnsDomainStrategy": "直連 DNS 域名策略",
|
||||
"enableDnsRouting": "啟用 DNS 路由",
|
||||
"domainStrategy": {
|
||||
"auto": "自動",
|
||||
"preferIpv6": "首選 IPv6",
|
||||
"preferIpv4": "首選 IPv4",
|
||||
"ipv4Only": "僅 IPv4",
|
||||
"ipv6Only": "僅 IPv6"
|
||||
}
|
||||
},
|
||||
"inbound": {
|
||||
"title": "入站",
|
||||
"serviceMode": "服務模式",
|
||||
"serviceModes": {
|
||||
"proxy": "僅代理服務",
|
||||
"systemProxy": "設定系統代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服務"
|
||||
},
|
||||
"shortServiceModes": {
|
||||
"proxy": "代理",
|
||||
"systemProxy": "系統代理",
|
||||
"tun": "VPN",
|
||||
"tunService": "VPN 服務"
|
||||
},
|
||||
"strictRoute": "嚴格路由",
|
||||
"tunImplementation": "TUN 實現",
|
||||
"tunImplementations": {
|
||||
"mixed": "混合",
|
||||
"system": "系統",
|
||||
"gvisor": "gVisor"
|
||||
},
|
||||
"mixedPort": "混合連接埠",
|
||||
"tproxyPort": "透明代理連接埠",
|
||||
"directPort": "本地 Direct 連接埠",
|
||||
"allowConnectionFromLan": "允許來自區域網路的連線"
|
||||
},
|
||||
"tlsTricks": {
|
||||
"title": "TLS 技巧",
|
||||
"enable": "啟用分片",
|
||||
"size": "分片大小",
|
||||
"sleep": "分片延遲",
|
||||
"mixedSniCase": {
|
||||
"enable": "啟用混合大小寫 SNI"
|
||||
},
|
||||
"padding": {
|
||||
"enable": "啟用填充",
|
||||
"size": "填充大小"
|
||||
}
|
||||
},
|
||||
"warp": {
|
||||
"title": "WARP",
|
||||
"enable": "啟用 WARP",
|
||||
"generateConfig": "產生 WARP 設定",
|
||||
"configGenerated": "WARP 設定已產生",
|
||||
"missingConfig": "WARP 設定缺失",
|
||||
"detourMode": "WARP 路由模式",
|
||||
"detourModes": {
|
||||
"proxyOverWarp": "透過 WARP 路由代理",
|
||||
"warpOverProxy": "透過代理路由 WARP",
|
||||
"proxyOverWarpExplain": "透過 WARP 解鎖代理",
|
||||
"warpOverProxyExplain": "透過 WARP 增強安全性"
|
||||
},
|
||||
"licenseKey": "授權金鑰",
|
||||
"cleanIp": "優選 IP",
|
||||
"port": "連接埠",
|
||||
"noise": {
|
||||
"count": "噪音數量",
|
||||
"mode": "噪音模式",
|
||||
"size": "噪音大小",
|
||||
"delay": "噪音延遲"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"stats": {
|
||||
"connection": "連線",
|
||||
"traffic": "流量",
|
||||
"trafficLive": "即時流量",
|
||||
"trafficTotal": "總流量",
|
||||
"uplink": "上傳",
|
||||
"downlink": "下載",
|
||||
"speed": "速度",
|
||||
"totalTransferred": "總傳輸量"
|
||||
},
|
||||
"subscriptionInfo": {
|
||||
"upload": "上傳",
|
||||
"download": "下載",
|
||||
"total": "總流量",
|
||||
"expireDate": "到期日期",
|
||||
"expired": "已到期",
|
||||
"noTraffic": "流量已用盡",
|
||||
"remainingTime": "剩餘時間",
|
||||
"remainingDuration": "剩餘 ${duration} 天",
|
||||
"remainingDurationNew": "${duration} 天",
|
||||
"remainingTrafficSemanticLabel": "已使用 ${consumed} / ${total} 流量",
|
||||
"remainingTraffic": "剩餘流量",
|
||||
"remainingUsage": "剩餘",
|
||||
"profileSite": "提供商",
|
||||
"profileSupport": "支援"
|
||||
}
|
||||
},
|
||||
"dialogs": {
|
||||
"sortProfiles": {
|
||||
"title": "排序方式",
|
||||
"sort": {
|
||||
"name": "按字母順序",
|
||||
"lastUpdate": "最近更新"
|
||||
}
|
||||
},
|
||||
"warpLicense": {
|
||||
"title": "Cloudflare WARP 同意書",
|
||||
"description(rich)": "Cloudflare WARP 是一個免費的 WireGuard VPN 提供商。啟用此選項即表示您同意 Cloudflare WARP 的 ${tos(服務條款)} 和 ${privacy(隱私權政策)}。"
|
||||
},
|
||||
"newVersion": {
|
||||
"title": "有可用更新",
|
||||
"msg": "@:common.appTitle 的新版本已發布。您想立即更新嗎?",
|
||||
"currentVersion": "目前版本:",
|
||||
"newVersion": "新版本:",
|
||||
"updateNow": "立即更新"
|
||||
},
|
||||
"confirmation": {
|
||||
"settings": {
|
||||
"import": {
|
||||
"msg": "這會使用提供的值覆蓋所有設定選項。您確定嗎?"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"delete": {
|
||||
"title": "刪除設定檔",
|
||||
"msg": "您確定要永久刪除此設定檔嗎?"
|
||||
}
|
||||
},
|
||||
"perAppProxy": {
|
||||
"shareOnGithub": {
|
||||
"title": "改進自動選擇",
|
||||
"msg": "透過分享您選擇的應用程式,可以幫助完善「自動選擇」清單"
|
||||
},
|
||||
"import": {
|
||||
"msg": "這將取代您目前所有的依應用程式代理選擇。您確定要繼續嗎?"
|
||||
}
|
||||
},
|
||||
"routeRule": {
|
||||
"delete": {
|
||||
"title": "刪除規則",
|
||||
"msg": "您確定要刪除規則「$rulename」嗎?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimentalNotice": {
|
||||
"title": "正在使用實驗性功能",
|
||||
"msg": "您已啟用了一些實驗性功能,這可能會影響連線品質並導致意外錯誤。您可以隨時在設定選項頁面變更或重設這些選項。",
|
||||
"disable": "不再顯示"
|
||||
},
|
||||
"noActiveProfile": {
|
||||
"title": "選擇一個設定檔",
|
||||
"msg": "讓我們從新增一個包含您 VPN 連線詳細資訊的設定檔開始。\n\n還沒有 VPN 伺服器?別擔心,按照下面的教學,您可以快速免費地設定一個。",
|
||||
"helpBtn": {
|
||||
"label": "告訴我如何操作",
|
||||
"url": "https://hiddify.com/manager/"
|
||||
}
|
||||
},
|
||||
"unknownDomainsWarning": {
|
||||
"title": "外部連結警告",
|
||||
"youAreAboutToVisit": "您即將造訪:",
|
||||
"thisWebsiteIsNotInOurTrustedList": "此網站不在我們的信任清單中。請謹慎操作。"
|
||||
},
|
||||
"proxyInfo": {
|
||||
"fullTag": "完整標籤:",
|
||||
"type": "類型:",
|
||||
"testTime": "測試時間:",
|
||||
"testDelay": "測試延遲:",
|
||||
"isSelected": "已選擇:",
|
||||
"isGroup": "是群組",
|
||||
"isSecure": "安全:",
|
||||
"port": "連接埠:",
|
||||
"host": "主機:",
|
||||
"ip": "IP:",
|
||||
"countryCode": "國家代碼:",
|
||||
"region": "地區:",
|
||||
"city": "城市:",
|
||||
"asn": "ASN:",
|
||||
"organization": "組織:",
|
||||
"location": "位置:",
|
||||
"postalCode": "郵遞區號:"
|
||||
},
|
||||
"windowClosing": {
|
||||
"askEachTime": "每次詢問",
|
||||
"alertMessage": "隱藏還是退出應用程式?",
|
||||
"remember": "記住我的選擇"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"tapToConnect": "點擊連線",
|
||||
"connect": "連線",
|
||||
"connecting": "連線中...",
|
||||
"connected": "已連線",
|
||||
"disconnect": "中斷連線",
|
||||
"disconnecting": "中斷連線中...",
|
||||
"reconnect": "重新連線",
|
||||
"reconnectMsg": "正在重新連線以套用變更...",
|
||||
"secure": "由 WARP 保護"
|
||||
},
|
||||
"errors": {
|
||||
"unexpected": "意外錯誤",
|
||||
"connection": {
|
||||
"unexpected": "意外連線錯誤",
|
||||
"timeout": "連線超時",
|
||||
"badResponse": "回應錯誤",
|
||||
"connectionError": "連線錯誤",
|
||||
"badCertificate": "憑證無效"
|
||||
},
|
||||
"profiles": {
|
||||
"unexpected": "意外錯誤",
|
||||
"notFound": "未找到設定檔",
|
||||
"invalidConfig": "設定無效",
|
||||
"invalidUrl": "URL 無效",
|
||||
"canceledByUser": "使用者已取消"
|
||||
},
|
||||
"connectivity": {
|
||||
"unexpected": "意外失敗",
|
||||
"missingVpnPermission": "缺少 VPN 權限",
|
||||
"missingNotificationPermission": "缺少通知權限",
|
||||
"core": "核心錯誤"
|
||||
},
|
||||
"singbox": {
|
||||
"serviceNotRunning": "服務未運行",
|
||||
"missingPrivilege": "缺少權限",
|
||||
"missingPrivilegeMsg": "VPN 模式需要管理員權限。請以管理員身份重新啟動應用,或更改服務模式。",
|
||||
"invalidConfigOptions": "設定選項無效",
|
||||
"invalidConfig": "設定無效"
|
||||
},
|
||||
"warp": {
|
||||
"missingLicense": "WARP 授權缺失",
|
||||
"missingLicenseMsg": "所選設定檔使用 WARP 功能;要使用此功能,必須同意 WARP 授權條款。"
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -6,6 +6,9 @@ targets:
|
||||
explicit_to_json: true
|
||||
drift_dev:
|
||||
options:
|
||||
databases:
|
||||
db: "lib/core/db/db.dart"
|
||||
schema_dir: "lib/core/db/schemas"
|
||||
store_date_time_values_as_text: true
|
||||
slang_build_runner:
|
||||
options:
|
||||
@@ -17,3 +20,13 @@ targets:
|
||||
output_file_name: translations.g.dart
|
||||
translation_class_visibility: public
|
||||
locale_handling: false
|
||||
# protoc_builder:
|
||||
# options:
|
||||
# protobuf_version: "3.1.0"
|
||||
# protoc_plugin_version: "21.1.2"
|
||||
# root_dir: "assets/proto"
|
||||
# proto_paths:
|
||||
# - "assets/proto"
|
||||
# out_dir: "lib/gen/proto"
|
||||
# use_installed_protoc: true
|
||||
# precompile_protoc_plugin: false
|
||||
|
||||
@@ -1 +1 @@
|
||||
core.version=3.1.8
|
||||
core.version=4.0..0
|
||||
@@ -1,22 +0,0 @@
|
||||
output: dist/
|
||||
releases:
|
||||
- name: prod
|
||||
jobs:
|
||||
- name: release-windows-exe
|
||||
package:
|
||||
platform: windows
|
||||
target: exe
|
||||
|
||||
- name: release-android-apk
|
||||
package:
|
||||
platform: android
|
||||
target: apk
|
||||
build_args:
|
||||
target-platform: android-arm,android-arm64,android-x64
|
||||
|
||||
- name: release-android-bundle
|
||||
package:
|
||||
platform: android
|
||||
target: aab
|
||||
build_args:
|
||||
target-platform: android-arm,android-arm64,android-x64
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user