mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Thu Jul 25 20:31:36 CEST 2024
This commit is contained in:
@@ -713,3 +713,4 @@ Update On Sun Jul 21 20:28:53 CEST 2024
|
||||
Update On Mon Jul 22 20:31:05 CEST 2024
|
||||
Update On Tue Jul 23 20:31:31 CEST 2024
|
||||
Update On Wed Jul 24 20:33:56 CEST 2024
|
||||
Update On Thu Jul 25 20:31:26 CEST 2024
|
||||
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
# Simple workflow for deploying static content to GitHub Pages
|
||||
name: Deploy static content to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["master"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: './docs'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+202
-68
@@ -21,7 +21,7 @@ nami install brook
|
||||
brook server -l :9999 -p hello
|
||||
```
|
||||
|
||||
## GUI Client
|
||||
## Client
|
||||
|
||||
| iOS | Android | Mac |Windows |Linux |OpenWrt |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
@@ -29,22 +29,121 @@ brook server -l :9999 -p hello
|
||||
| / | / | [App Mode](https://www.txthinking.com/talks/articles/macos-app-mode-en.article) | [How](https://www.txthinking.com/talks/articles/msix-brook-en.article) | [How](https://www.txthinking.com/talks/articles/linux-app-brook-en.article) | [How](https://www.txthinking.com/talks/articles/brook-openwrt-en.article) |
|
||||
|
||||
> You may want to use `brook link` to customize some parameters
|
||||
# GUI Documentation
|
||||
|
||||
## Software for which this article applies
|
||||
|
||||
- [Brook](https://github.com/txthinking/brook)
|
||||
- [Shiliew](https://www.txthinking.com/shiliew.html)
|
||||
- [tun2brook](https://github.com/txthinking/tun2brook)
|
||||
|
||||
## Programmable
|
||||
# Client
|
||||
|
||||
Brook GUI will pass different _global variables_ to the script at different times, and the script only needs to assign the processing result to the global variable `out`
|
||||
|
||||
- address: We call it address which includes both host and port. For example, an ip address contains an ip and a port; a domain address contains a domain and a port.
|
||||
- Fake DNS: Fake DNS can allow you to obtain domain address on `in_address` step. [How Fake DNS works](https://www.txthinking.com/talks/articles/brook-fakedns-en.article)
|
||||
## CLI
|
||||
|
||||
### Variables
|
||||
Before discussing the GUI client, let's first talk about the command line client `brook`. As we know, after you have deployed the server, you can use the command line client `brook` to create a local socks5 proxy or http proxy on your machine, and then configure it in your system proxy settings or in your browser to use this proxy. However:
|
||||
|
||||
1. Not all apps will use this proxy, whether they use it is up to the app itself.
|
||||
2. Generally, all UDP protocols will not go through this proxy, such as http3.
|
||||
|
||||
For the specifics of socks5 and http proxy, you can read [this article](https://www.txthinking.com/talks/articles/socks5-and-http-proxy.article).
|
||||
|
||||
## GUI
|
||||
|
||||
The GUI client does not use socks5 and http proxy mode, so there is no issue with some software not using the system proxy. Instead, it uses a virtual network card to take over the entire system's network, including UDP-based http3. Moreover, Brook allows us to control network requests programmatically, so it is necessary to have basic knowledge of network requests.
|
||||
|
||||
## Without Brook: Basic Knowledge of Network Requests
|
||||
|
||||
> Note: When we talk about addresses, we mean addresses that include the port number, such as a domain address: `google.com:443`, or an IP address: `8.8.8.8:53`
|
||||
|
||||
1. When an app requests a domain address, such as `google.com:443`
|
||||
2. It will first perform a DNS resolution, which means that the app will send a network request to the system-configured DNS, such as `8.8.8.8:53`, to inquire about the IP of `google.com`
|
||||
1. The system DNS will return the IP of `google.com`, such as `1.2.3.4`, to the app
|
||||
3. The app will combine the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
4. The app makes a network request to this IP address `1.2.3.4:443`
|
||||
5. The app receives the response data
|
||||
|
||||
In the above process, the app actually makes two network requests: one to the IP address `8.8.8.8:53` and another to the IP address `1.2.3.4:443`. In other words, the domain name is essentially an alias for the IP, and must obtain the domain's IP to establish a connection.
|
||||
|
||||
## With Brook: Fake DNS On
|
||||
|
||||
Brook has a Fake DNS feature, which can parse the domain name out of the query requests that an app sends to the system DNS and decide how to respond to the app.
|
||||
|
||||
1. When an app requests a domain name address, such as `google.com:443`
|
||||
2. A DNS resolution will be performed first. That is, the app will send a network request to the system-configured DNS, such as `8.8.8.8:53`, to inquire about the IP of `google.com`
|
||||
3. The Brook client detects that an app is sending a network request to `8.8.8.8:53`. <mark>This will trigger the `in_dnsquery` variable, carrying information such as `domain`</mark>
|
||||
1. The Brook client returns a fake IP to the app, such as `240.0.0.1`
|
||||
4. The app combines the IP and port into an IP address, such as: `240.0.0.1:443`
|
||||
5. The app makes a network request to the IP address `240.0.0.1:443`
|
||||
6. The Brook client detects that an app is sending a network request to `240.0.0.1:443`, discovers that this is a fake IP, and will convert the fake IP address back to the domain address `google.com:443`. <mark>This will trigger the `in_address` variable, carrying information such as `domainaddress`</mark>
|
||||
1. The Brook client sends `google.com:443` to the Brook Server
|
||||
2. The Brook Server first requests its own DNS to resolve the domain name to find out the IP of `google.com`, such as receiving `1.2.3.4`
|
||||
3. The Brook Server combines the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
4. The Brook Server sends a network request to `1.2.3.4:443` and returns the data to the Brook client
|
||||
5. The Brook client then returns the data to the app
|
||||
7. The app receives the response data
|
||||
|
||||
However, if the following situations occur, the domain name will not/cannot be parsed, meaning that the Brook client will not/cannot know what the domain name is and will treat it as a normal request sent to an IP address:
|
||||
|
||||
- Fake DNS not enabled: in this case, the Brook client will not attempt to parse the domain name from the request sent to the system DNS and will treat it as a normal request sent to an IP address.
|
||||
- Even with Fake DNS enabled, but the app uses the system's secure DNS or the app's own secure DNS: in this case, the Brook client cannot parse the domain name from the request sent to the secure DNS and will treat it as a normal request sent to an IP address.
|
||||
|
||||
To avoid the ineffectiveness of Fake DNS, please refer to [this article](https://www.txthinking.com/talks/articles/brook-fakedns.article).
|
||||
|
||||
## With Brook: Fake DNS Off
|
||||
|
||||
1. When an app requests a domain address, such as `google.com:443`
|
||||
2. A DNS resolution will be performed first. That is, the app will send a network request to the system-configured DNS, such as `8.8.8.8:53`, to inquire about the IP of `google.com`
|
||||
3. The Brook client detects that an app is sending a network request to `8.8.8.8:53`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `8.8.8.8:53` to the Brook Server
|
||||
2. The Brook Server sends a network request to `8.8.8.8:53` and returns the result, such as `1.2.3.4`, to the Brook client
|
||||
3. The Brook client then returns the result to the app
|
||||
4. The app combines the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
5. The app makes a network request to the IP address `1.2.3.4:443`
|
||||
6. The Brook client detects that an app is sending a network request to `1.2.3.4:443`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `1.2.3.4:443` to the Brook Server
|
||||
2. The Brook Server sends a network request to `1.2.3.4:443` and returns the data to the Brook client
|
||||
3. The Brook client then returns the data to the app
|
||||
7. The app receives the response data
|
||||
|
||||
## With Brook: Fake DNS On, But the App Uses the System's Secure DNS or Its Own Secure DNS
|
||||
|
||||
1. When an app requests a domain name address, such as `google.com:443`
|
||||
2. A DNS resolution will be performed first. That is, the app will send a network request to the secure DNS, such as `8.8.8.8:443`, to inquire about the IP of `google.com`
|
||||
3. The Brook client detects that an app is sending a network request to `8.8.8.8:443`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `8.8.8.8:443` to the Brook Server
|
||||
2. The Brook Server sends a network request to `8.8.8.8:443`, and returns the result, such as `1.2.3.4`, to the Brook client
|
||||
3. The Brook client then returns the result to the app
|
||||
4. The app combines the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
5. The app makes a network request to the IP address `1.2.3.4:443`
|
||||
6. The Brook client detects that an app is sending a network request to `1.2.3.4:443`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `1.2.3.4:443` to the Brook Server
|
||||
2. The Brook Server sends a network request to `1.2.3.4:443` and returns the data to the Brook client
|
||||
3. The Brook client then returns the data to the app
|
||||
7. The app receives the response data
|
||||
|
||||
## Handle Variable Trigger
|
||||
|
||||
- When the `in_brooklinks` variable is triggered:
|
||||
- This is currently the only variable that gets triggered before the Brook client starts.
|
||||
- We know that Brook starts with your choice of a Brook Server, and this variable lets you specify multiple Brook Servers.
|
||||
- Then during runtime, you can use one of these Brook Servers as needed.
|
||||
- When the `in_dnsquery` variable is triggered, you can process as needed, such as:
|
||||
- Blocking, such as to prevent ad domain names.
|
||||
- Directly specifying the response IP.
|
||||
- Letting the system DNS resolve this domain.
|
||||
- Letting Bypass DNS resolve this domain.
|
||||
- And so on.
|
||||
- When the `in_address` variable is triggered, you can process as needed, such as:
|
||||
- Block this connection.
|
||||
- Rewrite the destination.
|
||||
- If it's a domain address, you can specify that Bypass DNS is responsible for resolving the IP of this domain.
|
||||
- Allow it to connect directly without going through a proxy.
|
||||
- If it's HTTP/HTTPS, you can start MITM (Man-In-The-Middle), which will subsequently trigger `in_httprequest` and `in_httpresponse`.
|
||||
- And so on.
|
||||
- When the `in_httprequest` variable is triggered, you can process as needed, such as:
|
||||
- Modifying the HTTP request.
|
||||
- Returning a custom HTTP response directly.
|
||||
- When the `in_httpresponse` variable is triggered, you can process as needed, such as:
|
||||
- Modifying the HTTP response.
|
||||
|
||||
For detailed information on the properties and responses of variables, please refer to the following content.
|
||||
|
||||
## Variables
|
||||
|
||||
| variable | type | condition | timing | description | out type |
|
||||
| ------------------------------ | ---- | ----------- | --------------------------------- | ------------------------------------------------- | -------- |
|
||||
@@ -54,7 +153,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| in_httprequest | map | / | When an HTTP(S) request comes in | the script can decide how to handle this request | map |
|
||||
| in_httprequest,in_httpresponse | map | / | when an HTTP(S) response comes in | the script can decide how to handle this response | map |
|
||||
|
||||
### in_brooklinks
|
||||
## in_brooklinks
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------ | ------ | -------- | ---------- |
|
||||
@@ -68,7 +167,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| custom name | string | brook link | brook://... |
|
||||
| ... | ... | ... | ... |
|
||||
|
||||
### in_dnsquery
|
||||
## in_dnsquery
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------ | ------ | ----------- | ---------- |
|
||||
@@ -87,7 +186,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| bypass | bool | Resolve by Bypass DNS, default `false` | false |
|
||||
| brooklinkkey | string | When need to connect the Server,instead, connect to the Server specified by the key in_brooklinks | custom name |
|
||||
|
||||
### in_address
|
||||
## in_address
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------- | -------------- |
|
||||
@@ -115,7 +214,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| mitmserverwritetimeout | int | Timeout for MITM write to client, second, default 0 | 0 |
|
||||
| brooklinkkey | string | When need to connect the Server,instead, connect to the Server specified by the key in_brooklinks | custom name |
|
||||
|
||||
### in_httprequest
|
||||
## in_httprequest
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------ | ------ | ----------------------------- | --------------------------- |
|
||||
@@ -126,7 +225,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
|
||||
`out`, must be set to a request or response
|
||||
|
||||
### in_httpresponse
|
||||
## in_httpresponse
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ---------- | ------ | ----------------------------- | ------- |
|
||||
@@ -136,13 +235,9 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
|
||||
`out`, must be set to a response
|
||||
|
||||
## Module
|
||||
## Modules
|
||||
|
||||
There are already some modules: https://github.com/txthinking/brook/blob/master/programmable/modules/
|
||||
|
||||
### Brook GUI
|
||||
|
||||
In Brook GUI, scripts are abstracted into modules, and it will automatically combine [_header.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_header.tengo) and [_footer.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_footer.tengo), so you only need to write the module itself.
|
||||
In Brook GUI, scripts are abstracted into **Modules**. There are already [some modules](https://github.com/txthinking/brook/blob/master/programmable/modules/), and thre is no magic, it just automatically combine [_header.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_header.tengo) and [_footer.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_footer.tengo), so you only need to write the module itself.
|
||||
|
||||
```
|
||||
modules = append(modules, {
|
||||
@@ -169,9 +264,11 @@ modules = append(modules, {
|
||||
})
|
||||
```
|
||||
|
||||
### tun2brook
|
||||
## tun2brook
|
||||
|
||||
If you are using tun2brook, you can combine multiple modules into a complete script in the following way. For example:
|
||||
https://github.com/txthinking/tun2brook
|
||||
|
||||
If you are using tun2brook, you can manually combine multiple modules into a complete script in the following way. For example:
|
||||
|
||||
```
|
||||
cat _header.tengo > my.tengo
|
||||
@@ -233,7 +330,7 @@ Library
|
||||
|
||||
If you are writing complex scripts, the GUI may not be convenient for debugging. It is recommended to use [tun2brook](https://github.com/txthinking/tun2brook) on desktop to debug with `fmt.println`
|
||||
|
||||
## Install CA
|
||||
## CA
|
||||
|
||||
https://txthinking.github.io/ca/ca.pem
|
||||
|
||||
@@ -246,39 +343,58 @@ https://txthinking.github.io/ca/ca.pem
|
||||
|
||||
> Some software may not read the system CA,you can use `curl --cacert ~/.nami/bin/ca.pem` to debug
|
||||
|
||||
# Resources
|
||||
## OpenWrt
|
||||
|
||||
| CLI | Description |
|
||||
| --- | --- |
|
||||
| [nami](https://github.com/txthinking/nami) | A clean and tidy decentralized package manager |
|
||||
| [joker](https://github.com/txthinking/joker) | Joker can turn process into daemon. Zero-Configuration |
|
||||
| [nico](https://github.com/txthinking/nico) | Nico can work with brook wsserver together |
|
||||
| [zhen](https://github.com/txthinking/zhen) | zhen - process and cron manager |
|
||||
| [tun2brook](https://github.com/txthinking/tun2brook) | Proxy all traffic just one line command |
|
||||
| [mad](https://github.com/txthinking/mad) | Generate root CA and derivative certificate for any domains and any IPs |
|
||||
| [hancock](https://github.com/txthinking/hancock) | Manage multiple remote servers and execute commands remotely |
|
||||
| [sshexec](https://github.com/txthinking/sshexec) | A command-line tool to execute remote command through ssh |
|
||||
| [jb](https://github.com/txthinking/jb) | write script in an easier way than bash |
|
||||
| [bash](https://github.com/txthinking/bash) | Many one-click scripts |
|
||||
| [pacman](https://archlinux.org/packages/extra/x86_64/brook/) | `pacman -S brook` |
|
||||
| [brew](https://formulae.brew.sh/formula/brook) | `brew install brook` |
|
||||
| [docker](https://hub.docker.com/r/txthinking/brook) | `docker run txthinking/brook` |
|
||||
https://www.txthinking.com/talks/articles/brook-openwrt-en.article
|
||||
|
||||
| Resources | Description |
|
||||
| --- | --- |
|
||||
| [Protocol](https://github.com/txthinking/brook/tree/master/protocol) | Brook Protocol |
|
||||
| [Blog](https://www.txthinking.com/talks/) | Some articles you should read |
|
||||
| [YouTube](https://www.youtube.com/txthinking) | Some videos you should watch |
|
||||
| [Telegram](https://t.me/txthinking) | Ask questions here |
|
||||
| [Announce](https://t.me/s/txthinking_news) | All news you should care |
|
||||
| [GitHub](https://github.com/txthinking) | Other useful repos |
|
||||
| [Socks5 Configurator](https://chromewebstore.google.com/detail/socks5-configurator/hnpgnjkeaobghpjjhaiemlahikgmnghb) | If you prefer CLI brook client |
|
||||
| [IPvBar](https://chromewebstore.google.com/detail/ipvbar/nepjlegfiihpkcdhlmaebfdfppckonlj) | See domain, IP and country in browser |
|
||||
| [TxThinking SSH](https://www.txthinking.com/ssh.html) | A SSH Terminal |
|
||||
| [brook-user-system](https://github.com/txthinkinginc/brook-user-system) | A Brook User System |
|
||||
| [TxThinking](https://www.txthinking.com) | Everything |
|
||||
## IPv6
|
||||
|
||||
Brook's stance on IPv6 is positive, if your server or local environment doesn't have an IPv6 stack, read [this article](https://www.txthinking.com/talks/articles/brook-ipv6-en.article).
|
||||
|
||||
## Troubleshooting Steps
|
||||
|
||||
1. After adding your Server to the Brook client
|
||||
2. If your Server uses a domain and has not specified an IP address via `brook link --address`, then Brook client will attempt to resolve the domain's IP using local DNS, preferring AAAA record. For example:
|
||||
- domain.com:9999
|
||||
- ws://domain.com:9999
|
||||
- wss://domain.com:9999
|
||||
- quic://domain.com:9999
|
||||
3. Connectivity check: Go to the Server details page and click `Connectivity Check`. If it works sometimes but not others, this indicates instability.
|
||||
4. After connected
|
||||
1. Brook will change your system DNS to the System DNS configured in Brook (by default Google's DNS). In very rare cases, this change may be ignored on Windows, you can confirm this in the system settings.
|
||||
5. Test IPv4 TCP: Use `Test IPv4 TCP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
5. Test IPv4 UDP: Use `Test IPv4 UDP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
6. Test IPv6 TCP: Use `Test IPv6 TCP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
6. Test IPv6 UDP: Use `Test IPv6 UDP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
7. Test TCP and UDP: Use the `Echo Client` for testing. If the echo server entered is a domain address, it will trigger DNS resolution.
|
||||
8. Ensure the effectiveness of Fake DNS: Fake DNS is essential to do something with a domain or domain address. Generally, enable the `Block Google Secure DNS` module is sufficient. For other cases, refer to [this article](https://www.txthinking.com/talks/articles/brook-fakedns-en.article).
|
||||
9. If your local or Server does not support IPv6: Refer to [this article](https://www.txthinking.com/talks/articles/brook-ipv6-en.article).
|
||||
10. macOS App Mode: Refer to [this article](https://www.txthinking.com/talks/articles/macos-app-mode.article).
|
||||
11. Windows:
|
||||
- The client can pass the tests without any special configuration on a brand-new, genuine Windows 11.
|
||||
- Be aware that the Windows system time is often incorrect.
|
||||
- Do not have other similar network software installed; they can cause conflicting network settings in the system.
|
||||
- Try restarting the computer.
|
||||
- Windows Defender may ask for permission to connect to the network or present other issues.
|
||||
- System DNS may need to be set to 8.8.8.8 and/or 2001:4860:4860::8888
|
||||
12. Android:
|
||||
- The client can pass the tests without any special configuration on the official Google ROM.
|
||||
- Different ROMs may have made different modifications to the system.
|
||||
- Permission for background running might require separate settings.
|
||||
- System DNS may need to be set to 8.8.8.8 and/or 2001:4860:4860::8888
|
||||
13. Bypass traffic such as China, usually requires the following modules to be activated:
|
||||
- `Block Google Secure DNS`
|
||||
- `Bypass Geo`
|
||||
- `Bypass Apple`: To prevent issues receiving Apple message notifications.
|
||||
- `Bypass China domain` or `Bypass China domain A`: The former uses `Bypass DNS` to obtain the IP, then `Bypass Geo` or other modules decide whether to bypass; the latter bypasses directly after obtaining the IP with `Bypass DNS` using A records. The latter is needed if your local does not support IPv6.
|
||||
- If you are a [Shiliew](https://www.txthinking.com/shiliew.html) user, some modules are enabled by default, which is usually sufficient.
|
||||
14. Search [GitHub issues](https://github.com/txthinking/brook/issues?q=is%3Aissue)
|
||||
15. Read the [blog](https://www.txthinking.com/talks/)
|
||||
16. Read the [documentation](https://brook.app)
|
||||
14. Submit [new issue](https://github.com/txthinking/brook/issues?q=is%3Aissue)
|
||||
17. Seek help in the [group](https://t.me/txthinking)
|
||||
# CLI Documentation
|
||||
Each subcommand has a `--example` parameter that can print the minimal example of usage
|
||||
# NAME
|
||||
|
||||
Brook - A cross-platform programmable network tool
|
||||
@@ -1191,16 +1307,34 @@ brook relay --from :9999 --to 1.2.3.4:9999
|
||||
brook socks5tohttp --socks5 127.0.0.1:1080 --listen 127.0.0.1:8010
|
||||
```
|
||||
|
||||
## brook pac creates pac server
|
||||
|
||||
```
|
||||
brook pac --listen 127.0.0.1:8080 --proxy 'SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT' --bypassDomainList ...
|
||||
```
|
||||
|
||||
## brook pac creates pac file
|
||||
|
||||
```
|
||||
brook pac --file proxy.pac --proxy 'SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT' --bypassDomainList ...
|
||||
```
|
||||
|
||||
## There are countless examples; for more feature suggestions, it's best to look at the commands and parameters in the CLI documentation one by one, and blog, YouTube...
|
||||
# Resources
|
||||
|
||||
| CLI | Description |
|
||||
| --- | --- |
|
||||
| [nami](https://github.com/txthinking/nami) | A clean and tidy decentralized package manager |
|
||||
| [joker](https://github.com/txthinking/joker) | Joker can turn process into daemon. Zero-Configuration |
|
||||
| [nico](https://github.com/txthinking/nico) | Nico can work with brook wsserver together |
|
||||
| [z](https://github.com/txthinking/z) | z - process manager |
|
||||
| [tun2brook](https://github.com/txthinking/tun2brook) | Proxy all traffic just one line command |
|
||||
| [mad](https://github.com/txthinking/mad) | Generate root CA and derivative certificate for any domains and any IPs |
|
||||
| [hancock](https://github.com/txthinking/hancock) | Manage multiple remote servers and execute commands remotely |
|
||||
| [sshexec](https://github.com/txthinking/sshexec) | A command-line tool to execute remote command through ssh |
|
||||
| [jb](https://github.com/txthinking/jb) | write script in an easier way than bash |
|
||||
| [bash](https://github.com/txthinking/bash) | Many one-click scripts |
|
||||
| [docker](https://hub.docker.com/r/txthinking/brook) | `docker run txthinking/brook` |
|
||||
|
||||
| Resources | Description |
|
||||
| --- | --- |
|
||||
| [Protocol](https://github.com/txthinking/brook/tree/master/protocol) | Brook Protocol |
|
||||
| [Blog](https://www.txthinking.com/talks/) | Some articles you should read |
|
||||
| [YouTube](https://www.youtube.com/txthinking) | Some videos you should watch |
|
||||
| [Telegram](https://t.me/txthinking) | Ask questions here |
|
||||
| [Announce](https://t.me/s/txthinking_news) | All news you should care |
|
||||
| [GitHub](https://github.com/txthinking) | Other useful repos |
|
||||
| [Socks5 Configurator](https://chromewebstore.google.com/detail/socks5-configurator/hnpgnjkeaobghpjjhaiemlahikgmnghb) | If you prefer CLI brook client |
|
||||
| [IPvBar](https://chromewebstore.google.com/detail/ipvbar/nepjlegfiihpkcdhlmaebfdfppckonlj) | See domain, IP and country in browser |
|
||||
| [TxThinking SSH](https://www.txthinking.com/ssh.html) | A SSH Terminal |
|
||||
| [brook-user-system](https://github.com/txthinkinginc/brook-user-system) | A Brook User System |
|
||||
| [TxThinking](https://www.txthinking.com) | Everything |
|
||||
|
||||
|
||||
+2
-1
@@ -10,12 +10,13 @@ echo '**❤️ [Shiliew - A network app designed for those who value their time
|
||||
|
||||
cat getting-started.md >> ../readme.md
|
||||
cat gui.md >> ../readme.md
|
||||
cat resources.md >> ../readme.md
|
||||
|
||||
echo '# CLI Documentation' >> ../readme.md
|
||||
echo 'Each subcommand has a `--example` parameter that can print the minimal example of usage' >> ../readme.md
|
||||
jb '$1`brook mdpage`.split("\n").filter(v=>!v.startsWith("[")).join("\n").replace("```\n```", "```\nbrook --help\n```").split("\n").forEach(v=> echo(v.startsWith("**") && !v.startsWith("**Usage") ? "- "+v : v))' >> ../readme.md
|
||||
|
||||
cat example.md >> ../readme.md
|
||||
cat resources.md >> ../readme.md
|
||||
|
||||
markdown ../readme.md ./index.html
|
||||
|
||||
|
||||
@@ -262,16 +262,4 @@ brook relay --from :9999 --to 1.2.3.4:9999
|
||||
brook socks5tohttp --socks5 127.0.0.1:1080 --listen 127.0.0.1:8010
|
||||
```
|
||||
|
||||
## brook pac creates pac server
|
||||
|
||||
```
|
||||
brook pac --listen 127.0.0.1:8080 --proxy 'SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT' --bypassDomainList ...
|
||||
```
|
||||
|
||||
## brook pac creates pac file
|
||||
|
||||
```
|
||||
brook pac --file proxy.pac --proxy 'SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT' --bypassDomainList ...
|
||||
```
|
||||
|
||||
## There are countless examples; for more feature suggestions, it's best to look at the commands and parameters in the CLI documentation one by one, and blog, YouTube...
|
||||
|
||||
@@ -14,7 +14,7 @@ nami install brook
|
||||
brook server -l :9999 -p hello
|
||||
```
|
||||
|
||||
## GUI Client
|
||||
## Client
|
||||
|
||||
| iOS | Android | Mac |Windows |Linux |OpenWrt |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
|
||||
+173
-26
@@ -1,19 +1,118 @@
|
||||
# GUI Documentation
|
||||
|
||||
## Software for which this article applies
|
||||
|
||||
- [Brook](https://github.com/txthinking/brook)
|
||||
- [Shiliew](https://www.txthinking.com/shiliew.html)
|
||||
- [tun2brook](https://github.com/txthinking/tun2brook)
|
||||
|
||||
## Programmable
|
||||
# Client
|
||||
|
||||
Brook GUI will pass different _global variables_ to the script at different times, and the script only needs to assign the processing result to the global variable `out`
|
||||
|
||||
- address: We call it address which includes both host and port. For example, an ip address contains an ip and a port; a domain address contains a domain and a port.
|
||||
- Fake DNS: Fake DNS can allow you to obtain domain address on `in_address` step. [How Fake DNS works](https://www.txthinking.com/talks/articles/brook-fakedns-en.article)
|
||||
## CLI
|
||||
|
||||
### Variables
|
||||
Before discussing the GUI client, let's first talk about the command line client `brook`. As we know, after you have deployed the server, you can use the command line client `brook` to create a local socks5 proxy or http proxy on your machine, and then configure it in your system proxy settings or in your browser to use this proxy. However:
|
||||
|
||||
1. Not all apps will use this proxy, whether they use it is up to the app itself.
|
||||
2. Generally, all UDP protocols will not go through this proxy, such as http3.
|
||||
|
||||
For the specifics of socks5 and http proxy, you can read [this article](https://www.txthinking.com/talks/articles/socks5-and-http-proxy.article).
|
||||
|
||||
## GUI
|
||||
|
||||
The GUI client does not use socks5 and http proxy mode, so there is no issue with some software not using the system proxy. Instead, it uses a virtual network card to take over the entire system's network, including UDP-based http3. Moreover, Brook allows us to control network requests programmatically, so it is necessary to have basic knowledge of network requests.
|
||||
|
||||
## Without Brook: Basic Knowledge of Network Requests
|
||||
|
||||
> Note: When we talk about addresses, we mean addresses that include the port number, such as a domain address: `google.com:443`, or an IP address: `8.8.8.8:53`
|
||||
|
||||
1. When an app requests a domain address, such as `google.com:443`
|
||||
2. It will first perform a DNS resolution, which means that the app will send a network request to the system-configured DNS, such as `8.8.8.8:53`, to inquire about the IP of `google.com`
|
||||
1. The system DNS will return the IP of `google.com`, such as `1.2.3.4`, to the app
|
||||
3. The app will combine the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
4. The app makes a network request to this IP address `1.2.3.4:443`
|
||||
5. The app receives the response data
|
||||
|
||||
In the above process, the app actually makes two network requests: one to the IP address `8.8.8.8:53` and another to the IP address `1.2.3.4:443`. In other words, the domain name is essentially an alias for the IP, and must obtain the domain's IP to establish a connection.
|
||||
|
||||
## With Brook: Fake DNS On
|
||||
|
||||
Brook has a Fake DNS feature, which can parse the domain name out of the query requests that an app sends to the system DNS and decide how to respond to the app.
|
||||
|
||||
1. When an app requests a domain name address, such as `google.com:443`
|
||||
2. A DNS resolution will be performed first. That is, the app will send a network request to the system-configured DNS, such as `8.8.8.8:53`, to inquire about the IP of `google.com`
|
||||
3. The Brook client detects that an app is sending a network request to `8.8.8.8:53`. <mark>This will trigger the `in_dnsquery` variable, carrying information such as `domain`</mark>
|
||||
1. The Brook client returns a fake IP to the app, such as `240.0.0.1`
|
||||
4. The app combines the IP and port into an IP address, such as: `240.0.0.1:443`
|
||||
5. The app makes a network request to the IP address `240.0.0.1:443`
|
||||
6. The Brook client detects that an app is sending a network request to `240.0.0.1:443`, discovers that this is a fake IP, and will convert the fake IP address back to the domain address `google.com:443`. <mark>This will trigger the `in_address` variable, carrying information such as `domainaddress`</mark>
|
||||
1. The Brook client sends `google.com:443` to the Brook Server
|
||||
2. The Brook Server first requests its own DNS to resolve the domain name to find out the IP of `google.com`, such as receiving `1.2.3.4`
|
||||
3. The Brook Server combines the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
4. The Brook Server sends a network request to `1.2.3.4:443` and returns the data to the Brook client
|
||||
5. The Brook client then returns the data to the app
|
||||
7. The app receives the response data
|
||||
|
||||
However, if the following situations occur, the domain name will not/cannot be parsed, meaning that the Brook client will not/cannot know what the domain name is and will treat it as a normal request sent to an IP address:
|
||||
|
||||
- Fake DNS not enabled: in this case, the Brook client will not attempt to parse the domain name from the request sent to the system DNS and will treat it as a normal request sent to an IP address.
|
||||
- Even with Fake DNS enabled, but the app uses the system's secure DNS or the app's own secure DNS: in this case, the Brook client cannot parse the domain name from the request sent to the secure DNS and will treat it as a normal request sent to an IP address.
|
||||
|
||||
To avoid the ineffectiveness of Fake DNS, please refer to [this article](https://www.txthinking.com/talks/articles/brook-fakedns.article).
|
||||
|
||||
## With Brook: Fake DNS Off
|
||||
|
||||
1. When an app requests a domain address, such as `google.com:443`
|
||||
2. A DNS resolution will be performed first. That is, the app will send a network request to the system-configured DNS, such as `8.8.8.8:53`, to inquire about the IP of `google.com`
|
||||
3. The Brook client detects that an app is sending a network request to `8.8.8.8:53`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `8.8.8.8:53` to the Brook Server
|
||||
2. The Brook Server sends a network request to `8.8.8.8:53` and returns the result, such as `1.2.3.4`, to the Brook client
|
||||
3. The Brook client then returns the result to the app
|
||||
4. The app combines the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
5. The app makes a network request to the IP address `1.2.3.4:443`
|
||||
6. The Brook client detects that an app is sending a network request to `1.2.3.4:443`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `1.2.3.4:443` to the Brook Server
|
||||
2. The Brook Server sends a network request to `1.2.3.4:443` and returns the data to the Brook client
|
||||
3. The Brook client then returns the data to the app
|
||||
7. The app receives the response data
|
||||
|
||||
## With Brook: Fake DNS On, But the App Uses the System's Secure DNS or Its Own Secure DNS
|
||||
|
||||
1. When an app requests a domain name address, such as `google.com:443`
|
||||
2. A DNS resolution will be performed first. That is, the app will send a network request to the secure DNS, such as `8.8.8.8:443`, to inquire about the IP of `google.com`
|
||||
3. The Brook client detects that an app is sending a network request to `8.8.8.8:443`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `8.8.8.8:443` to the Brook Server
|
||||
2. The Brook Server sends a network request to `8.8.8.8:443`, and returns the result, such as `1.2.3.4`, to the Brook client
|
||||
3. The Brook client then returns the result to the app
|
||||
4. The app combines the IP and port into an IP address, such as: `1.2.3.4:443`
|
||||
5. The app makes a network request to the IP address `1.2.3.4:443`
|
||||
6. The Brook client detects that an app is sending a network request to `1.2.3.4:443`. <mark>This will trigger the `in_address` variable, carrying information such as `ipaddress`</mark>
|
||||
1. The Brook client sends `1.2.3.4:443` to the Brook Server
|
||||
2. The Brook Server sends a network request to `1.2.3.4:443` and returns the data to the Brook client
|
||||
3. The Brook client then returns the data to the app
|
||||
7. The app receives the response data
|
||||
|
||||
## Handle Variable Trigger
|
||||
|
||||
- When the `in_brooklinks` variable is triggered:
|
||||
- This is currently the only variable that gets triggered before the Brook client starts.
|
||||
- We know that Brook starts with your choice of a Brook Server, and this variable lets you specify multiple Brook Servers.
|
||||
- Then during runtime, you can use one of these Brook Servers as needed.
|
||||
- When the `in_dnsquery` variable is triggered, you can process as needed, such as:
|
||||
- Blocking, such as to prevent ad domain names.
|
||||
- Directly specifying the response IP.
|
||||
- Letting the system DNS resolve this domain.
|
||||
- Letting Bypass DNS resolve this domain.
|
||||
- And so on.
|
||||
- When the `in_address` variable is triggered, you can process as needed, such as:
|
||||
- Block this connection.
|
||||
- Rewrite the destination.
|
||||
- If it's a domain address, you can specify that Bypass DNS is responsible for resolving the IP of this domain.
|
||||
- Allow it to connect directly without going through a proxy.
|
||||
- If it's HTTP/HTTPS, you can start MITM (Man-In-The-Middle), which will subsequently trigger `in_httprequest` and `in_httpresponse`.
|
||||
- And so on.
|
||||
- When the `in_httprequest` variable is triggered, you can process as needed, such as:
|
||||
- Modifying the HTTP request.
|
||||
- Returning a custom HTTP response directly.
|
||||
- When the `in_httpresponse` variable is triggered, you can process as needed, such as:
|
||||
- Modifying the HTTP response.
|
||||
|
||||
For detailed information on the properties and responses of variables, please refer to the following content.
|
||||
|
||||
## Variables
|
||||
|
||||
| variable | type | condition | timing | description | out type |
|
||||
| ------------------------------ | ---- | ----------- | --------------------------------- | ------------------------------------------------- | -------- |
|
||||
@@ -23,7 +122,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| in_httprequest | map | / | When an HTTP(S) request comes in | the script can decide how to handle this request | map |
|
||||
| in_httprequest,in_httpresponse | map | / | when an HTTP(S) response comes in | the script can decide how to handle this response | map |
|
||||
|
||||
### in_brooklinks
|
||||
## in_brooklinks
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------ | ------ | -------- | ---------- |
|
||||
@@ -37,7 +136,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| custom name | string | brook link | brook://... |
|
||||
| ... | ... | ... | ... |
|
||||
|
||||
### in_dnsquery
|
||||
## in_dnsquery
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------ | ------ | ----------- | ---------- |
|
||||
@@ -56,7 +155,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| bypass | bool | Resolve by Bypass DNS, default `false` | false |
|
||||
| brooklinkkey | string | When need to connect the Server,instead, connect to the Server specified by the key in_brooklinks | custom name |
|
||||
|
||||
### in_address
|
||||
## in_address
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------- | -------------- |
|
||||
@@ -84,7 +183,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
| mitmserverwritetimeout | int | Timeout for MITM write to client, second, default 0 | 0 |
|
||||
| brooklinkkey | string | When need to connect the Server,instead, connect to the Server specified by the key in_brooklinks | custom name |
|
||||
|
||||
### in_httprequest
|
||||
## in_httprequest
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ------ | ------ | ----------------------------- | --------------------------- |
|
||||
@@ -95,7 +194,7 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
|
||||
`out`, must be set to a request or response
|
||||
|
||||
### in_httpresponse
|
||||
## in_httpresponse
|
||||
|
||||
| Key | Type | Description | Example |
|
||||
| ---------- | ------ | ----------------------------- | ------- |
|
||||
@@ -105,13 +204,9 @@ Brook GUI will pass different _global variables_ to the script at different time
|
||||
|
||||
`out`, must be set to a response
|
||||
|
||||
## Module
|
||||
## Modules
|
||||
|
||||
There are already some modules: https://github.com/txthinking/brook/blob/master/programmable/modules/
|
||||
|
||||
### Brook GUI
|
||||
|
||||
In Brook GUI, scripts are abstracted into modules, and it will automatically combine [_header.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_header.tengo) and [_footer.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_footer.tengo), so you only need to write the module itself.
|
||||
In Brook GUI, scripts are abstracted into **Modules**. There are already [some modules](https://github.com/txthinking/brook/blob/master/programmable/modules/), and thre is no magic, it just automatically combine [_header.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_header.tengo) and [_footer.tengo](https://github.com/txthinking/brook/blob/master/programmable/modules/_footer.tengo), so you only need to write the module itself.
|
||||
|
||||
```
|
||||
modules = append(modules, {
|
||||
@@ -138,9 +233,11 @@ modules = append(modules, {
|
||||
})
|
||||
```
|
||||
|
||||
### tun2brook
|
||||
## tun2brook
|
||||
|
||||
If you are using tun2brook, you can combine multiple modules into a complete script in the following way. For example:
|
||||
https://github.com/txthinking/tun2brook
|
||||
|
||||
If you are using tun2brook, you can manually combine multiple modules into a complete script in the following way. For example:
|
||||
|
||||
```
|
||||
cat _header.tengo > my.tengo
|
||||
@@ -202,7 +299,7 @@ Library
|
||||
|
||||
If you are writing complex scripts, the GUI may not be convenient for debugging. It is recommended to use [tun2brook](https://github.com/txthinking/tun2brook) on desktop to debug with `fmt.println`
|
||||
|
||||
## Install CA
|
||||
## CA
|
||||
|
||||
https://txthinking.github.io/ca/ca.pem
|
||||
|
||||
@@ -215,3 +312,53 @@ https://txthinking.github.io/ca/ca.pem
|
||||
|
||||
> Some software may not read the system CA,you can use `curl --cacert ~/.nami/bin/ca.pem` to debug
|
||||
|
||||
## OpenWrt
|
||||
|
||||
https://www.txthinking.com/talks/articles/brook-openwrt-en.article
|
||||
|
||||
## IPv6
|
||||
|
||||
Brook's stance on IPv6 is positive, if your server or local environment doesn't have an IPv6 stack, read [this article](https://www.txthinking.com/talks/articles/brook-ipv6-en.article).
|
||||
|
||||
## Troubleshooting Steps
|
||||
|
||||
1. After adding your Server to the Brook client
|
||||
2. If your Server uses a domain and has not specified an IP address via `brook link --address`, then Brook client will attempt to resolve the domain's IP using local DNS, preferring AAAA record. For example:
|
||||
- domain.com:9999
|
||||
- ws://domain.com:9999
|
||||
- wss://domain.com:9999
|
||||
- quic://domain.com:9999
|
||||
3. Connectivity check: Go to the Server details page and click `Connectivity Check`. If it works sometimes but not others, this indicates instability.
|
||||
4. After connected
|
||||
1. Brook will change your system DNS to the System DNS configured in Brook (by default Google's DNS). In very rare cases, this change may be ignored on Windows, you can confirm this in the system settings.
|
||||
5. Test IPv4 TCP: Use `Test IPv4 TCP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
5. Test IPv4 UDP: Use `Test IPv4 UDP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
6. Test IPv6 TCP: Use `Test IPv6 TCP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
6. Test IPv6 UDP: Use `Test IPv6 UDP` for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.
|
||||
7. Test TCP and UDP: Use the `Echo Client` for testing. If the echo server entered is a domain address, it will trigger DNS resolution.
|
||||
8. Ensure the effectiveness of Fake DNS: Fake DNS is essential to do something with a domain or domain address. Generally, enable the `Block Google Secure DNS` module is sufficient. For other cases, refer to [this article](https://www.txthinking.com/talks/articles/brook-fakedns-en.article).
|
||||
9. If your local or Server does not support IPv6: Refer to [this article](https://www.txthinking.com/talks/articles/brook-ipv6-en.article).
|
||||
10. macOS App Mode: Refer to [this article](https://www.txthinking.com/talks/articles/macos-app-mode.article).
|
||||
11. Windows:
|
||||
- The client can pass the tests without any special configuration on a brand-new, genuine Windows 11.
|
||||
- Be aware that the Windows system time is often incorrect.
|
||||
- Do not have other similar network software installed; they can cause conflicting network settings in the system.
|
||||
- Try restarting the computer.
|
||||
- Windows Defender may ask for permission to connect to the network or present other issues.
|
||||
- System DNS may need to be set to 8.8.8.8 and/or 2001:4860:4860::8888
|
||||
12. Android:
|
||||
- The client can pass the tests without any special configuration on the official Google ROM.
|
||||
- Different ROMs may have made different modifications to the system.
|
||||
- Permission for background running might require separate settings.
|
||||
- System DNS may need to be set to 8.8.8.8 and/or 2001:4860:4860::8888
|
||||
13. Bypass traffic such as China, usually requires the following modules to be activated:
|
||||
- `Block Google Secure DNS`
|
||||
- `Bypass Geo`
|
||||
- `Bypass Apple`: To prevent issues receiving Apple message notifications.
|
||||
- `Bypass China domain` or `Bypass China domain A`: The former uses `Bypass DNS` to obtain the IP, then `Bypass Geo` or other modules decide whether to bypass; the latter bypasses directly after obtaining the IP with `Bypass DNS` using A records. The latter is needed if your local does not support IPv6.
|
||||
- If you are a [Shiliew](https://www.txthinking.com/shiliew.html) user, some modules are enabled by default, which is usually sufficient.
|
||||
14. Search [GitHub issues](https://github.com/txthinking/brook/issues?q=is%3Aissue)
|
||||
15. Read the [blog](https://www.txthinking.com/talks/)
|
||||
16. Read the [documentation](https://brook.app)
|
||||
14. Submit [new issue](https://github.com/txthinking/brook/issues?q=is%3Aissue)
|
||||
17. Seek help in the [group](https://t.me/txthinking)
|
||||
|
||||
+331
-172
@@ -1157,31 +1157,33 @@
|
||||
<li><a href="#sponsor">Sponsor</a></li>
|
||||
<li><a href="#getting-started">Getting Started</a><ul>
|
||||
<li><a href="#server">Server</a></li>
|
||||
<li><a href="#gui-client">GUI Client</a></li>
|
||||
<li><a href="#client">Client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#gui-documentation">GUI Documentation</a><ul>
|
||||
<li><a href="#software-for-which-this-article-applies">Software for which this article applies</a></li>
|
||||
<li><a href="#programmable">Programmable</a><ul>
|
||||
<li><a href="#client-1">Client</a><ul>
|
||||
<li><a href="#cli">CLI</a></li>
|
||||
<li><a href="#gui">GUI</a></li>
|
||||
<li><a href="#without-brook-basic-knowledge-of-network-requests">Without Brook: Basic Knowledge of Network Requests</a></li>
|
||||
<li><a href="#with-brook-fake-dns-on">With Brook: Fake DNS On</a></li>
|
||||
<li><a href="#with-brook-fake-dns-off">With Brook: Fake DNS Off</a></li>
|
||||
<li><a href="#with-brook-fake-dns-on-but-the-app-uses-the-systems-secure-dns-or-its-own-secure-dns">With Brook: Fake DNS On, But the App Uses the System's Secure DNS or Its Own Secure DNS</a></li>
|
||||
<li><a href="#handle-variable-trigger">Handle Variable Trigger</a></li>
|
||||
<li><a href="#variables">Variables</a></li>
|
||||
<li><a href="#in_brooklinks">in_brooklinks</a></li>
|
||||
<li><a href="#in_dnsquery">in_dnsquery</a></li>
|
||||
<li><a href="#in_address">in_address</a></li>
|
||||
<li><a href="#in_httprequest">in_httprequest</a></li>
|
||||
<li><a href="#in_httpresponse">in_httpresponse</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#module">Module</a><ul>
|
||||
<li><a href="#brook-gui">Brook GUI</a></li>
|
||||
<li><a href="#modules">Modules</a></li>
|
||||
<li><a href="#tun2brook">tun2brook</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#syntax">Syntax</a></li>
|
||||
<li><a href="#debug">Debug</a></li>
|
||||
<li><a href="#install-ca">Install CA</a></li>
|
||||
<li><a href="#ca">CA</a></li>
|
||||
<li><a href="#openwrt">OpenWrt</a></li>
|
||||
<li><a href="#ipv6">IPv6</a></li>
|
||||
<li><a href="#troubleshooting-steps">Troubleshooting Steps</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#resources">Resources</a></li>
|
||||
<li><a href="#cli-documentation">CLI Documentation</a></li>
|
||||
<li><a href="#name">NAME</a></li>
|
||||
<li><a href="#synopsis">SYNOPSIS</a></li>
|
||||
@@ -1242,11 +1244,10 @@
|
||||
<li><a href="#turn-linux-into-a-gateway-with-brook">Turn Linux into a Gateway with Brook</a></li>
|
||||
<li><a href="#brook-relay-can-relay-a-address-to-a-remote-address-it-can-relay-any-tcp-and-udp-server">brook relay can relay a address to a remote address. It can relay any tcp and udp server</a></li>
|
||||
<li><a href="#brook-socks5tohttp-can-convert-a-socks5-to-a-http-proxy">brook socks5tohttp can convert a socks5 to a http proxy</a></li>
|
||||
<li><a href="#brook-pac-creates-pac-server">brook pac creates pac server</a></li>
|
||||
<li><a href="#brook-pac-creates-pac-file">brook pac creates pac file</a></li>
|
||||
<li><a href="#there-are-countless-examples-for-more-feature-suggestions-its-best-to-look-at-the-commands-and-parameters-in-the-cli-documentation-one-by-one-and-blog-youtube">There are countless examples; for more feature suggestions, it's best to look at the commands and parameters in the CLI documentation one by one, and blog, YouTube...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#resources">Resources</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -1259,31 +1260,33 @@
|
||||
<li><a href="#sponsor">Sponsor</a></li>
|
||||
<li><a href="#getting-started">Getting Started</a><ul>
|
||||
<li><a href="#server">Server</a></li>
|
||||
<li><a href="#gui-client">GUI Client</a></li>
|
||||
<li><a href="#client">Client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#gui-documentation">GUI Documentation</a><ul>
|
||||
<li><a href="#software-for-which-this-article-applies">Software for which this article applies</a></li>
|
||||
<li><a href="#programmable">Programmable</a><ul>
|
||||
<li><a href="#client-1">Client</a><ul>
|
||||
<li><a href="#cli">CLI</a></li>
|
||||
<li><a href="#gui">GUI</a></li>
|
||||
<li><a href="#without-brook-basic-knowledge-of-network-requests">Without Brook: Basic Knowledge of Network Requests</a></li>
|
||||
<li><a href="#with-brook-fake-dns-on">With Brook: Fake DNS On</a></li>
|
||||
<li><a href="#with-brook-fake-dns-off">With Brook: Fake DNS Off</a></li>
|
||||
<li><a href="#with-brook-fake-dns-on-but-the-app-uses-the-systems-secure-dns-or-its-own-secure-dns">With Brook: Fake DNS On, But the App Uses the System's Secure DNS or Its Own Secure DNS</a></li>
|
||||
<li><a href="#handle-variable-trigger">Handle Variable Trigger</a></li>
|
||||
<li><a href="#variables">Variables</a></li>
|
||||
<li><a href="#in_brooklinks">in_brooklinks</a></li>
|
||||
<li><a href="#in_dnsquery">in_dnsquery</a></li>
|
||||
<li><a href="#in_address">in_address</a></li>
|
||||
<li><a href="#in_httprequest">in_httprequest</a></li>
|
||||
<li><a href="#in_httpresponse">in_httpresponse</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#module">Module</a><ul>
|
||||
<li><a href="#brook-gui">Brook GUI</a></li>
|
||||
<li><a href="#modules">Modules</a></li>
|
||||
<li><a href="#tun2brook">tun2brook</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#syntax">Syntax</a></li>
|
||||
<li><a href="#debug">Debug</a></li>
|
||||
<li><a href="#install-ca">Install CA</a></li>
|
||||
<li><a href="#ca">CA</a></li>
|
||||
<li><a href="#openwrt">OpenWrt</a></li>
|
||||
<li><a href="#ipv6">IPv6</a></li>
|
||||
<li><a href="#troubleshooting-steps">Troubleshooting Steps</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#resources">Resources</a></li>
|
||||
<li><a href="#cli-documentation">CLI Documentation</a></li>
|
||||
<li><a href="#name">NAME</a></li>
|
||||
<li><a href="#synopsis">SYNOPSIS</a></li>
|
||||
@@ -1344,11 +1347,10 @@
|
||||
<li><a href="#turn-linux-into-a-gateway-with-brook">Turn Linux into a Gateway with Brook</a></li>
|
||||
<li><a href="#brook-relay-can-relay-a-address-to-a-remote-address-it-can-relay-any-tcp-and-udp-server">brook relay can relay a address to a remote address. It can relay any tcp and udp server</a></li>
|
||||
<li><a href="#brook-socks5tohttp-can-convert-a-socks5-to-a-http-proxy">brook socks5tohttp can convert a socks5 to a http proxy</a></li>
|
||||
<li><a href="#brook-pac-creates-pac-server">brook pac creates pac server</a></li>
|
||||
<li><a href="#brook-pac-creates-pac-file">brook pac creates pac file</a></li>
|
||||
<li><a href="#there-are-countless-examples-for-more-feature-suggestions-its-best-to-look-at-the-commands-and-parameters-in-the-cli-documentation-one-by-one-and-blog-youtube">There are countless examples; for more feature suggestions, it's best to look at the commands and parameters in the CLI documentation one by one, and blog, YouTube...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#resources">Resources</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -1365,7 +1367,7 @@
|
||||
</code></pre>
|
||||
<pre><code>brook server -l :9999 -p hello
|
||||
</code></pre>
|
||||
<h2 id="gui-client">GUI Client</h2>
|
||||
<h2 id="client">Client</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1397,20 +1399,136 @@
|
||||
<blockquote>
|
||||
<p>You may want to use <code>brook link</code> to customize some parameters</p>
|
||||
</blockquote>
|
||||
<h1 id="gui-documentation">GUI Documentation</h1>
|
||||
<h2 id="software-for-which-this-article-applies">Software for which this article applies</h2>
|
||||
<ul>
|
||||
<li><a href="https://github.com/txthinking/brook">Brook</a></li>
|
||||
<li><a href="https://www.txthinking.com/shiliew.html">Shiliew</a></li>
|
||||
<li><a href="https://github.com/txthinking/tun2brook">tun2brook</a></li>
|
||||
</ul>
|
||||
<h2 id="programmable">Programmable</h2>
|
||||
<h1 id="client-1">Client</h1>
|
||||
<p>Brook GUI will pass different <em>global variables</em> to the script at different times, and the script only needs to assign the processing result to the global variable <code>out</code></p>
|
||||
<h2 id="cli">CLI</h2>
|
||||
<p>Before discussing the GUI client, let's first talk about the command line client <code>brook</code>. As we know, after you have deployed the server, you can use the command line client <code>brook</code> to create a local socks5 proxy or http proxy on your machine, and then configure it in your system proxy settings or in your browser to use this proxy. However:</p>
|
||||
<ol>
|
||||
<li>Not all apps will use this proxy, whether they use it is up to the app itself.</li>
|
||||
<li>Generally, all UDP protocols will not go through this proxy, such as http3.</li>
|
||||
</ol>
|
||||
<p>For the specifics of socks5 and http proxy, you can read <a href="https://www.txthinking.com/talks/articles/socks5-and-http-proxy.article">this article</a>.</p>
|
||||
<h2 id="gui">GUI</h2>
|
||||
<p>The GUI client does not use socks5 and http proxy mode, so there is no issue with some software not using the system proxy. Instead, it uses a virtual network card to take over the entire system's network, including UDP-based http3. Moreover, Brook allows us to control network requests programmatically, so it is necessary to have basic knowledge of network requests.</p>
|
||||
<h2 id="without-brook-basic-knowledge-of-network-requests">Without Brook: Basic Knowledge of Network Requests</h2>
|
||||
<blockquote>
|
||||
<p>Note: When we talk about addresses, we mean addresses that include the port number, such as a domain address: <code>google.com:443</code>, or an IP address: <code>8.8.8.8:53</code></p>
|
||||
</blockquote>
|
||||
<ol>
|
||||
<li>When an app requests a domain address, such as <code>google.com:443</code></li>
|
||||
<li>It will first perform a DNS resolution, which means that the app will send a network request to the system-configured DNS, such as <code>8.8.8.8:53</code>, to inquire about the IP of <code>google.com</code><ol>
|
||||
<li>The system DNS will return the IP of <code>google.com</code>, such as <code>1.2.3.4</code>, to the app</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app will combine the IP and port into an IP address, such as: <code>1.2.3.4:443</code></li>
|
||||
<li>The app makes a network request to this IP address <code>1.2.3.4:443</code></li>
|
||||
<li>The app receives the response data</li>
|
||||
</ol>
|
||||
<p>In the above process, the app actually makes two network requests: one to the IP address <code>8.8.8.8:53</code> and another to the IP address <code>1.2.3.4:443</code>. In other words, the domain name is essentially an alias for the IP, and must obtain the domain's IP to establish a connection.</p>
|
||||
<h2 id="with-brook-fake-dns-on">With Brook: Fake DNS On</h2>
|
||||
<p>Brook has a Fake DNS feature, which can parse the domain name out of the query requests that an app sends to the system DNS and decide how to respond to the app.</p>
|
||||
<ol>
|
||||
<li>When an app requests a domain name address, such as <code>google.com:443</code></li>
|
||||
<li>A DNS resolution will be performed first. That is, the app will send a network request to the system-configured DNS, such as <code>8.8.8.8:53</code>, to inquire about the IP of <code>google.com</code></li>
|
||||
<li>The Brook client detects that an app is sending a network request to <code>8.8.8.8:53</code>. <mark>This will trigger the <code>in_dnsquery</code> variable, carrying information such as <code>domain</code></mark><ol>
|
||||
<li>The Brook client returns a fake IP to the app, such as <code>240.0.0.1</code></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app combines the IP and port into an IP address, such as: <code>240.0.0.1:443</code></li>
|
||||
<li>The app makes a network request to the IP address <code>240.0.0.1:443</code></li>
|
||||
<li>The Brook client detects that an app is sending a network request to <code>240.0.0.1:443</code>, discovers that this is a fake IP, and will convert the fake IP address back to the domain address <code>google.com:443</code>. <mark>This will trigger the <code>in_address</code> variable, carrying information such as <code>domainaddress</code></mark><ol>
|
||||
<li>The Brook client sends <code>google.com:443</code> to the Brook Server</li>
|
||||
<li>The Brook Server first requests its own DNS to resolve the domain name to find out the IP of <code>google.com</code>, such as receiving <code>1.2.3.4</code></li>
|
||||
<li>The Brook Server combines the IP and port into an IP address, such as: <code>1.2.3.4:443</code></li>
|
||||
<li>The Brook Server sends a network request to <code>1.2.3.4:443</code> and returns the data to the Brook client</li>
|
||||
<li>The Brook client then returns the data to the app</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app receives the response data</li>
|
||||
</ol>
|
||||
<p>However, if the following situations occur, the domain name will not/cannot be parsed, meaning that the Brook client will not/cannot know what the domain name is and will treat it as a normal request sent to an IP address:</p>
|
||||
<ul>
|
||||
<li>address: We call it address which includes both host and port. For example, an ip address contains an ip and a port; a domain address contains a domain and a port.</li>
|
||||
<li>Fake DNS: Fake DNS can allow you to obtain domain address on <code>in_address</code> step. <a href="https://www.txthinking.com/talks/articles/brook-fakedns-en.article">How Fake DNS works</a></li>
|
||||
<li>Fake DNS not enabled: in this case, the Brook client will not attempt to parse the domain name from the request sent to the system DNS and will treat it as a normal request sent to an IP address.</li>
|
||||
<li>Even with Fake DNS enabled, but the app uses the system's secure DNS or the app's own secure DNS: in this case, the Brook client cannot parse the domain name from the request sent to the secure DNS and will treat it as a normal request sent to an IP address.</li>
|
||||
</ul>
|
||||
<h3 id="variables">Variables</h3>
|
||||
<p>To avoid the ineffectiveness of Fake DNS, please refer to <a href="https://www.txthinking.com/talks/articles/brook-fakedns.article">this article</a>.</p>
|
||||
<h2 id="with-brook-fake-dns-off">With Brook: Fake DNS Off</h2>
|
||||
<ol>
|
||||
<li>When an app requests a domain address, such as <code>google.com:443</code></li>
|
||||
<li>A DNS resolution will be performed first. That is, the app will send a network request to the system-configured DNS, such as <code>8.8.8.8:53</code>, to inquire about the IP of <code>google.com</code></li>
|
||||
<li>The Brook client detects that an app is sending a network request to <code>8.8.8.8:53</code>. <mark>This will trigger the <code>in_address</code> variable, carrying information such as <code>ipaddress</code></mark><ol>
|
||||
<li>The Brook client sends <code>8.8.8.8:53</code> to the Brook Server</li>
|
||||
<li>The Brook Server sends a network request to <code>8.8.8.8:53</code> and returns the result, such as <code>1.2.3.4</code>, to the Brook client</li>
|
||||
<li>The Brook client then returns the result to the app</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app combines the IP and port into an IP address, such as: <code>1.2.3.4:443</code></li>
|
||||
<li>The app makes a network request to the IP address <code>1.2.3.4:443</code></li>
|
||||
<li>The Brook client detects that an app is sending a network request to <code>1.2.3.4:443</code>. <mark>This will trigger the <code>in_address</code> variable, carrying information such as <code>ipaddress</code></mark><ol>
|
||||
<li>The Brook client sends <code>1.2.3.4:443</code> to the Brook Server</li>
|
||||
<li>The Brook Server sends a network request to <code>1.2.3.4:443</code> and returns the data to the Brook client</li>
|
||||
<li>The Brook client then returns the data to the app</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app receives the response data</li>
|
||||
</ol>
|
||||
<h2 id="with-brook-fake-dns-on-but-the-app-uses-the-systems-secure-dns-or-its-own-secure-dns">With Brook: Fake DNS On, But the App Uses the System's Secure DNS or Its Own Secure DNS</h2>
|
||||
<ol>
|
||||
<li>When an app requests a domain name address, such as <code>google.com:443</code></li>
|
||||
<li>A DNS resolution will be performed first. That is, the app will send a network request to the secure DNS, such as <code>8.8.8.8:443</code>, to inquire about the IP of <code>google.com</code></li>
|
||||
<li>The Brook client detects that an app is sending a network request to <code>8.8.8.8:443</code>. <mark>This will trigger the <code>in_address</code> variable, carrying information such as <code>ipaddress</code></mark><ol>
|
||||
<li>The Brook client sends <code>8.8.8.8:443</code> to the Brook Server</li>
|
||||
<li>The Brook Server sends a network request to <code>8.8.8.8:443</code>, and returns the result, such as <code>1.2.3.4</code>, to the Brook client</li>
|
||||
<li>The Brook client then returns the result to the app</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app combines the IP and port into an IP address, such as: <code>1.2.3.4:443</code></li>
|
||||
<li>The app makes a network request to the IP address <code>1.2.3.4:443</code></li>
|
||||
<li>The Brook client detects that an app is sending a network request to <code>1.2.3.4:443</code>. <mark>This will trigger the <code>in_address</code> variable, carrying information such as <code>ipaddress</code></mark><ol>
|
||||
<li>The Brook client sends <code>1.2.3.4:443</code> to the Brook Server</li>
|
||||
<li>The Brook Server sends a network request to <code>1.2.3.4:443</code> and returns the data to the Brook client</li>
|
||||
<li>The Brook client then returns the data to the app</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>The app receives the response data</li>
|
||||
</ol>
|
||||
<h2 id="handle-variable-trigger">Handle Variable Trigger</h2>
|
||||
<ul>
|
||||
<li>When the <code>in_brooklinks</code> variable is triggered:<ul>
|
||||
<li>This is currently the only variable that gets triggered before the Brook client starts.</li>
|
||||
<li>We know that Brook starts with your choice of a Brook Server, and this variable lets you specify multiple Brook Servers.</li>
|
||||
<li>Then during runtime, you can use one of these Brook Servers as needed.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>When the <code>in_dnsquery</code> variable is triggered, you can process as needed, such as:<ul>
|
||||
<li>Blocking, such as to prevent ad domain names.</li>
|
||||
<li>Directly specifying the response IP.</li>
|
||||
<li>Letting the system DNS resolve this domain.</li>
|
||||
<li>Letting Bypass DNS resolve this domain.</li>
|
||||
<li>And so on.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>When the <code>in_address</code> variable is triggered, you can process as needed, such as:<ul>
|
||||
<li>Block this connection.</li>
|
||||
<li>Rewrite the destination.</li>
|
||||
<li>If it's a domain address, you can specify that Bypass DNS is responsible for resolving the IP of this domain.</li>
|
||||
<li>Allow it to connect directly without going through a proxy.</li>
|
||||
<li>If it's HTTP/HTTPS, you can start MITM (Man-In-The-Middle), which will subsequently trigger <code>in_httprequest</code> and <code>in_httpresponse</code>.</li>
|
||||
<li>And so on.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>When the <code>in_httprequest</code> variable is triggered, you can process as needed, such as:<ul>
|
||||
<li>Modifying the HTTP request.</li>
|
||||
<li>Returning a custom HTTP response directly.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>When the <code>in_httpresponse</code> variable is triggered, you can process as needed, such as:<ul>
|
||||
<li>Modifying the HTTP response.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>For detailed information on the properties and responses of variables, please refer to the following content.</p>
|
||||
<h2 id="variables">Variables</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1463,7 +1581,7 @@
|
||||
<td>map</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id="in_brooklinks">in_brooklinks</h3>
|
||||
<h2 id="in_brooklinks">in_brooklinks</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1509,7 +1627,7 @@
|
||||
<td>...</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id="in_dnsquery">in_dnsquery</h3>
|
||||
<h2 id="in_dnsquery">in_dnsquery</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1585,7 +1703,7 @@
|
||||
<td>custom name</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id="in_address">in_address</h3>
|
||||
<h2 id="in_address">in_address</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1715,7 +1833,7 @@
|
||||
<td>custom name</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id="in_httprequest">in_httprequest</h3>
|
||||
<h2 id="in_httprequest">in_httprequest</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1751,7 +1869,7 @@
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p><code>out</code>, must be set to a request or response</p>
|
||||
<h3 id="in_httpresponse">in_httpresponse</h3>
|
||||
<h2 id="in_httpresponse">in_httpresponse</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1781,10 +1899,8 @@
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p><code>out</code>, must be set to a response</p>
|
||||
<h2 id="module">Module</h2>
|
||||
<p>There are already some modules: <a href="https://github.com/txthinking/brook/blob/master/programmable/modules/">https://github.com/txthinking/brook/blob/master/programmable/modules/</a></p>
|
||||
<h3 id="brook-gui">Brook GUI</h3>
|
||||
<p>In Brook GUI, scripts are abstracted into modules, and it will automatically combine <a href="https://github.com/txthinking/brook/blob/master/programmable/modules/_header.tengo">_header.tengo</a> and <a href="https://github.com/txthinking/brook/blob/master/programmable/modules/_footer.tengo">_footer.tengo</a>, so you only need to write the module itself.</p>
|
||||
<h2 id="modules">Modules</h2>
|
||||
<p>In Brook GUI, scripts are abstracted into <strong>Modules</strong>. There are already <a href="https://github.com/txthinking/brook/blob/master/programmable/modules/">some modules</a>, and thre is no magic, it just automatically combine <a href="https://github.com/txthinking/brook/blob/master/programmable/modules/_header.tengo">_header.tengo</a> and <a href="https://github.com/txthinking/brook/blob/master/programmable/modules/_footer.tengo">_footer.tengo</a>, so you only need to write the module itself.</p>
|
||||
<pre><code>modules = append(modules, {
|
||||
// If you want to predefine multiple brook links, and then programmatically specify which one to connect to, then define `brooklinks` key a function
|
||||
brooklinks: func(m) {
|
||||
@@ -1808,8 +1924,9 @@
|
||||
}
|
||||
})
|
||||
</code></pre>
|
||||
<h3 id="tun2brook">tun2brook</h3>
|
||||
<p>If you are using tun2brook, you can combine multiple modules into a complete script in the following way. For example:</p>
|
||||
<h2 id="tun2brook">tun2brook</h2>
|
||||
<p><a href="https://github.com/txthinking/tun2brook">https://github.com/txthinking/tun2brook</a></p>
|
||||
<p>If you are using tun2brook, you can manually combine multiple modules into a complete script in the following way. For example:</p>
|
||||
<pre><code>cat _header.tengo > my.tengo
|
||||
|
||||
cat block_google_secure_dns.tengo >> my.tengo
|
||||
@@ -1872,7 +1989,7 @@ Functions
|
||||
</ul>
|
||||
<h2 id="debug">Debug</h2>
|
||||
<p>If you are writing complex scripts, the GUI may not be convenient for debugging. It is recommended to use <a href="https://github.com/txthinking/tun2brook">tun2brook</a> on desktop to debug with <code>fmt.println</code></p>
|
||||
<h2 id="install-ca">Install CA</h2>
|
||||
<h2 id="ca">CA</h2>
|
||||
<p><a href="https://txthinking.github.io/ca/ca.pem">https://txthinking.github.io/ca/ca.pem</a></p>
|
||||
<table>
|
||||
<thead>
|
||||
@@ -1901,120 +2018,63 @@ Functions
|
||||
<blockquote>
|
||||
<p>Some software may not read the system CA,you can use <code>curl --cacert ~/.nami/bin/ca.pem</code> to debug</p>
|
||||
</blockquote>
|
||||
<h1 id="resources">Resources</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>CLI</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td><a href="https://github.com/txthinking/nami">nami</a></td>
|
||||
<td>A clean and tidy decentralized package manager</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/joker">joker</a></td>
|
||||
<td>Joker can turn process into daemon. Zero-Configuration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/nico">nico</a></td>
|
||||
<td>Nico can work with brook wsserver together</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/zhen">zhen</a></td>
|
||||
<td>zhen - process and cron manager</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/tun2brook">tun2brook</a></td>
|
||||
<td>Proxy all traffic just one line command</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/mad">mad</a></td>
|
||||
<td>Generate root CA and derivative certificate for any domains and any IPs</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/hancock">hancock</a></td>
|
||||
<td>Manage multiple remote servers and execute commands remotely</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/sshexec">sshexec</a></td>
|
||||
<td>A command-line tool to execute remote command through ssh</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/jb">jb</a></td>
|
||||
<td>write script in an easier way than bash</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/bash">bash</a></td>
|
||||
<td>Many one-click scripts</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://archlinux.org/packages/extra/x86_64/brook/">pacman</a></td>
|
||||
<td><code>pacman -S brook</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://formulae.brew.sh/formula/brook">brew</a></td>
|
||||
<td><code>brew install brook</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://hub.docker.com/r/txthinking/brook">docker</a></td>
|
||||
<td><code>docker run txthinking/brook</code></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Resources</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td><a href="https://github.com/txthinking/brook/tree/master/protocol">Protocol</a></td>
|
||||
<td>Brook Protocol</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.txthinking.com/talks/">Blog</a></td>
|
||||
<td>Some articles you should read</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.youtube.com/txthinking">YouTube</a></td>
|
||||
<td>Some videos you should watch</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://t.me/txthinking">Telegram</a></td>
|
||||
<td>Ask questions here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://t.me/s/txthinking_news">Announce</a></td>
|
||||
<td>All news you should care</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking">GitHub</a></td>
|
||||
<td>Other useful repos</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://chromewebstore.google.com/detail/socks5-configurator/hnpgnjkeaobghpjjhaiemlahikgmnghb">Socks5 Configurator</a></td>
|
||||
<td>If you prefer CLI brook client</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://chromewebstore.google.com/detail/ipvbar/nepjlegfiihpkcdhlmaebfdfppckonlj">IPvBar</a></td>
|
||||
<td>See domain, IP and country in browser</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.txthinking.com/ssh.html">TxThinking SSH</a></td>
|
||||
<td>A SSH Terminal</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinkinginc/brook-user-system">brook-user-system</a></td>
|
||||
<td>A Brook User System</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.txthinking.com">TxThinking</a></td>
|
||||
<td>Everything</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h2 id="openwrt">OpenWrt</h2>
|
||||
<p><a href="https://www.txthinking.com/talks/articles/brook-openwrt-en.article">https://www.txthinking.com/talks/articles/brook-openwrt-en.article</a></p>
|
||||
<h2 id="ipv6">IPv6</h2>
|
||||
<p>Brook's stance on IPv6 is positive, if your server or local environment doesn't have an IPv6 stack, read <a href="https://www.txthinking.com/talks/articles/brook-ipv6-en.article">this article</a>.</p>
|
||||
<h2 id="troubleshooting-steps">Troubleshooting Steps</h2>
|
||||
<ol>
|
||||
<li>After adding your Server to the Brook client</li>
|
||||
<li>If your Server uses a domain and has not specified an IP address via <code>brook link --address</code>, then Brook client will attempt to resolve the domain's IP using local DNS, preferring AAAA record. For example:<ul>
|
||||
<li>domain.com:9999</li>
|
||||
<li>ws://domain.com:9999</li>
|
||||
<li>wss://domain.com:9999</li>
|
||||
<li>quic://domain.com:9999</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Connectivity check: Go to the Server details page and click <code>Connectivity Check</code>. If it works sometimes but not others, this indicates instability.</li>
|
||||
<li>After connected</li>
|
||||
<li>Brook will change your system DNS to the System DNS configured in Brook (by default Google's DNS). In very rare cases, this change may be ignored on Windows, you can confirm this in the system settings.</li>
|
||||
<li>Test IPv4 TCP: Use <code>Test IPv4 TCP</code> for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.</li>
|
||||
<li>Test IPv4 UDP: Use <code>Test IPv4 UDP</code> for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.</li>
|
||||
<li>Test IPv6 TCP: Use <code>Test IPv6 TCP</code> for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.</li>
|
||||
<li>Test IPv6 UDP: Use <code>Test IPv6 UDP</code> for testing; this test has hardcoded the IP address, so does not trigger DNS resolution.</li>
|
||||
<li>Test TCP and UDP: Use the <code>Echo Client</code> for testing. If the echo server entered is a domain address, it will trigger DNS resolution.</li>
|
||||
<li>Ensure the effectiveness of Fake DNS: Fake DNS is essential to do something with a domain or domain address. Generally, enable the <code>Block Google Secure DNS</code> module is sufficient. For other cases, refer to <a href="https://www.txthinking.com/talks/articles/brook-fakedns-en.article">this article</a>.</li>
|
||||
<li>If your local or Server does not support IPv6: Refer to <a href="https://www.txthinking.com/talks/articles/brook-ipv6-en.article">this article</a>.</li>
|
||||
<li>macOS App Mode: Refer to <a href="https://www.txthinking.com/talks/articles/macos-app-mode.article">this article</a>.</li>
|
||||
<li>Windows:<ul>
|
||||
<li>The client can pass the tests without any special configuration on a brand-new, genuine Windows 11.</li>
|
||||
<li>Be aware that the Windows system time is often incorrect.</li>
|
||||
<li>Do not have other similar network software installed; they can cause conflicting network settings in the system.</li>
|
||||
<li>Try restarting the computer.</li>
|
||||
<li>Windows Defender may ask for permission to connect to the network or present other issues.</li>
|
||||
<li>System DNS may need to be set to 8.8.8.8 and/or 2001:4860:4860::8888</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Android:<ul>
|
||||
<li>The client can pass the tests without any special configuration on the official Google ROM.</li>
|
||||
<li>Different ROMs may have made different modifications to the system.</li>
|
||||
<li>Permission for background running might require separate settings.</li>
|
||||
<li>System DNS may need to be set to 8.8.8.8 and/or 2001:4860:4860::8888</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Bypass traffic such as China, usually requires the following modules to be activated:<ul>
|
||||
<li><code>Block Google Secure DNS</code></li>
|
||||
<li><code>Bypass Geo</code></li>
|
||||
<li><code>Bypass Apple</code>: To prevent issues receiving Apple message notifications.</li>
|
||||
<li><code>Bypass China domain</code> or <code>Bypass China domain A</code>: The former uses <code>Bypass DNS</code> to obtain the IP, then <code>Bypass Geo</code> or other modules decide whether to bypass; the latter bypasses directly after obtaining the IP with <code>Bypass DNS</code> using A records. The latter is needed if your local does not support IPv6.</li>
|
||||
<li>If you are a <a href="https://www.txthinking.com/shiliew.html">Shiliew</a> user, some modules are enabled by default, which is usually sufficient.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Search <a href="https://github.com/txthinking/brook/issues?q=is%3Aissue">GitHub issues</a></li>
|
||||
<li>Read the <a href="https://www.txthinking.com/talks/">blog</a></li>
|
||||
<li>Read the <a href="https://brook.app">documentation</a></li>
|
||||
<li>Submit <a href="https://github.com/txthinking/brook/issues?q=is%3Aissue">new issue</a></li>
|
||||
<li>Seek help in the <a href="https://t.me/txthinking">group</a></li>
|
||||
</ol>
|
||||
<h1 id="cli-documentation">CLI Documentation</h1>
|
||||
<p>Each subcommand has a <code>--example</code> parameter that can print the minimal example of usage</p>
|
||||
<h1 id="name">NAME</h1>
|
||||
<p>Brook - A cross-platform programmable network tool</p>
|
||||
<h1 id="synopsis">SYNOPSIS</h1>
|
||||
@@ -2118,7 +2178,7 @@ Functions
|
||||
<li><p><strong>--updateListInterval</strong>="": This option will be removed in a future version, please use the global option instead (default: 0)</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="client">client</h2>
|
||||
<h2 id="client-2">client</h2>
|
||||
<p>Start a brook client that supports tcp and udp. It can open a socks5 proxy, [src <-> socks5 <-> $ brook client <-> $ brook server <-> dst]</p>
|
||||
<ul>
|
||||
<li><p><strong>--example</strong>: Show a minimal example of usage</p>
|
||||
@@ -2805,13 +2865,112 @@ Functions
|
||||
<h2 id="brook-socks5tohttp-can-convert-a-socks5-to-a-http-proxy">brook socks5tohttp can convert a socks5 to a http proxy</h2>
|
||||
<pre><code>brook socks5tohttp --socks5 127.0.0.1:1080 --listen 127.0.0.1:8010
|
||||
</code></pre>
|
||||
<h2 id="brook-pac-creates-pac-server">brook pac creates pac server</h2>
|
||||
<pre><code>brook pac --listen 127.0.0.1:8080 --proxy 'SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT' --bypassDomainList ...
|
||||
</code></pre>
|
||||
<h2 id="brook-pac-creates-pac-file">brook pac creates pac file</h2>
|
||||
<pre><code>brook pac --file proxy.pac --proxy 'SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT' --bypassDomainList ...
|
||||
</code></pre>
|
||||
<h2 id="there-are-countless-examples-for-more-feature-suggestions-its-best-to-look-at-the-commands-and-parameters-in-the-cli-documentation-one-by-one-and-blog-youtube">There are countless examples; for more feature suggestions, it's best to look at the commands and parameters in the CLI documentation one by one, and blog, YouTube...</h2>
|
||||
<h1 id="resources">Resources</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>CLI</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td><a href="https://github.com/txthinking/nami">nami</a></td>
|
||||
<td>A clean and tidy decentralized package manager</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/joker">joker</a></td>
|
||||
<td>Joker can turn process into daemon. Zero-Configuration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/nico">nico</a></td>
|
||||
<td>Nico can work with brook wsserver together</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/z">z</a></td>
|
||||
<td>z - process manager</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/tun2brook">tun2brook</a></td>
|
||||
<td>Proxy all traffic just one line command</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/mad">mad</a></td>
|
||||
<td>Generate root CA and derivative certificate for any domains and any IPs</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/hancock">hancock</a></td>
|
||||
<td>Manage multiple remote servers and execute commands remotely</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/sshexec">sshexec</a></td>
|
||||
<td>A command-line tool to execute remote command through ssh</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/jb">jb</a></td>
|
||||
<td>write script in an easier way than bash</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking/bash">bash</a></td>
|
||||
<td>Many one-click scripts</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://hub.docker.com/r/txthinking/brook">docker</a></td>
|
||||
<td><code>docker run txthinking/brook</code></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Resources</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td><a href="https://github.com/txthinking/brook/tree/master/protocol">Protocol</a></td>
|
||||
<td>Brook Protocol</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.txthinking.com/talks/">Blog</a></td>
|
||||
<td>Some articles you should read</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.youtube.com/txthinking">YouTube</a></td>
|
||||
<td>Some videos you should watch</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://t.me/txthinking">Telegram</a></td>
|
||||
<td>Ask questions here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://t.me/s/txthinking_news">Announce</a></td>
|
||||
<td>All news you should care</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinking">GitHub</a></td>
|
||||
<td>Other useful repos</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://chromewebstore.google.com/detail/socks5-configurator/hnpgnjkeaobghpjjhaiemlahikgmnghb">Socks5 Configurator</a></td>
|
||||
<td>If you prefer CLI brook client</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://chromewebstore.google.com/detail/ipvbar/nepjlegfiihpkcdhlmaebfdfppckonlj">IPvBar</a></td>
|
||||
<td>See domain, IP and country in browser</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.txthinking.com/ssh.html">TxThinking SSH</a></td>
|
||||
<td>A SSH Terminal</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/txthinkinginc/brook-user-system">brook-user-system</a></td>
|
||||
<td>A Brook User System</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.txthinking.com">TxThinking</a></td>
|
||||
<td>Everything</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,15 +5,13 @@
|
||||
| [nami](https://github.com/txthinking/nami) | A clean and tidy decentralized package manager |
|
||||
| [joker](https://github.com/txthinking/joker) | Joker can turn process into daemon. Zero-Configuration |
|
||||
| [nico](https://github.com/txthinking/nico) | Nico can work with brook wsserver together |
|
||||
| [zhen](https://github.com/txthinking/zhen) | zhen - process and cron manager |
|
||||
| [z](https://github.com/txthinking/z) | z - process manager |
|
||||
| [tun2brook](https://github.com/txthinking/tun2brook) | Proxy all traffic just one line command |
|
||||
| [mad](https://github.com/txthinking/mad) | Generate root CA and derivative certificate for any domains and any IPs |
|
||||
| [hancock](https://github.com/txthinking/hancock) | Manage multiple remote servers and execute commands remotely |
|
||||
| [sshexec](https://github.com/txthinking/sshexec) | A command-line tool to execute remote command through ssh |
|
||||
| [jb](https://github.com/txthinking/jb) | write script in an easier way than bash |
|
||||
| [bash](https://github.com/txthinking/bash) | Many one-click scripts |
|
||||
| [pacman](https://archlinux.org/packages/extra/x86_64/brook/) | `pacman -S brook` |
|
||||
| [brew](https://formulae.brew.sh/formula/brook) | `brew install brook` |
|
||||
| [docker](https://hub.docker.com/r/txthinking/brook) | `docker run txthinking/brook` |
|
||||
|
||||
| Resources | Description |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "20240606",
|
||||
"text": "Refer to get Brook Plus for free",
|
||||
"link": "https://www.txthinking.com/brook.html#referrals",
|
||||
"text_zh": "邀请以免费获得 Brook Plus",
|
||||
"link_zh": "https://www.txthinking.com/brook.html#referrals"
|
||||
"text": "Brook Client Basic Knowledge",
|
||||
"link": "https://www.txthinking.com/talks/articles/brook-en.article",
|
||||
"text_zh": "Brook 客户端基础知识",
|
||||
"link_zh": "https://www.txthinking.com/talks/articles/brook.article"
|
||||
}
|
||||
|
||||
@@ -69,3 +69,5 @@ func WithDSCP(dscp uint8) Addition {
|
||||
metadata.DSCP = dscp
|
||||
}
|
||||
}
|
||||
|
||||
func Placeholder(metadata *C.Metadata) {}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
)
|
||||
|
||||
func newClient(srcConn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) *http.Client {
|
||||
func newClient(srcConn net.Conn, tunnel C.Tunnel, additions []inbound.Addition) *http.Client { // additions using slice let caller can change its value (without size) after newClient return
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{
|
||||
// from http.DefaultTransport
|
||||
|
||||
@@ -10,10 +10,9 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/auth"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
)
|
||||
|
||||
@@ -31,8 +30,10 @@ func (b *bodyWrapper) Read(p []byte) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
|
||||
client := newClient(c, tunnel, additions...)
|
||||
func HandleConn(c net.Conn, tunnel C.Tunnel, authenticator auth.Authenticator, additions ...inbound.Addition) {
|
||||
additions = append(additions, inbound.Placeholder) // Add a placeholder for InUser
|
||||
inUserIdx := len(additions) - 1
|
||||
client := newClient(c, tunnel, additions)
|
||||
defer client.CloseIdleConnections()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@@ -41,7 +42,8 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
conn := N.NewBufferedConn(c)
|
||||
|
||||
keepAlive := true
|
||||
trusted := cache == nil // disable authenticate if lru is nil
|
||||
trusted := authenticator == nil // disable authenticate if lru is nil
|
||||
lastUser := ""
|
||||
|
||||
for keepAlive {
|
||||
peekMutex.Lock()
|
||||
@@ -57,12 +59,10 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
|
||||
var resp *http.Response
|
||||
|
||||
if !trusted {
|
||||
var user string
|
||||
resp, user = authenticate(request, cache)
|
||||
additions = append(additions, inbound.WithInUser(user))
|
||||
trusted = resp == nil
|
||||
}
|
||||
var user string
|
||||
resp, user = authenticate(request, authenticator) // always call authenticate function to get user
|
||||
trusted = trusted || resp == nil
|
||||
additions[inUserIdx] = inbound.WithInUser(user)
|
||||
|
||||
if trusted {
|
||||
if request.Method == http.MethodConnect {
|
||||
@@ -89,6 +89,13 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
return // hijack connection
|
||||
}
|
||||
|
||||
// ensure there is a client with correct additions
|
||||
// when the authenticated user changed, outbound client should close idle connections
|
||||
if user != lastUser {
|
||||
client.CloseIdleConnections()
|
||||
lastUser = user
|
||||
}
|
||||
|
||||
removeHopByHopHeaders(request.Header)
|
||||
removeExtraHTTPHostPort(request)
|
||||
|
||||
@@ -138,34 +145,24 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
_ = conn.Close()
|
||||
}
|
||||
|
||||
func authenticate(request *http.Request, cache *lru.LruCache[string, bool]) (resp *http.Response, u string) {
|
||||
authenticator := authStore.Authenticator()
|
||||
func authenticate(request *http.Request, authenticator auth.Authenticator) (resp *http.Response, user string) {
|
||||
if inbound.SkipAuthRemoteAddress(request.RemoteAddr) {
|
||||
authenticator = nil
|
||||
}
|
||||
if authenticator != nil {
|
||||
credential := parseBasicProxyAuthorization(request)
|
||||
if credential == "" {
|
||||
resp := responseWith(request, http.StatusProxyAuthRequired)
|
||||
resp.Header.Set("Proxy-Authenticate", "Basic")
|
||||
return resp, ""
|
||||
}
|
||||
|
||||
authed, exist := cache.Get(credential)
|
||||
if !exist {
|
||||
user, pass, err := decodeBasicProxyAuthorization(credential)
|
||||
authed = err == nil && authenticator.Verify(user, pass)
|
||||
u = user
|
||||
cache.Set(credential, authed)
|
||||
}
|
||||
if !authed {
|
||||
log.Infoln("Auth failed from %s", request.RemoteAddr)
|
||||
|
||||
return responseWith(request, http.StatusForbidden), u
|
||||
}
|
||||
credential := parseBasicProxyAuthorization(request)
|
||||
if credential == "" && authenticator != nil {
|
||||
resp = responseWith(request, http.StatusProxyAuthRequired)
|
||||
resp.Header.Set("Proxy-Authenticate", "Basic")
|
||||
return
|
||||
}
|
||||
|
||||
return nil, u
|
||||
user, pass, err := decodeBasicProxyAuthorization(credential)
|
||||
authed := authenticator == nil || (err == nil && authenticator.Verify(user, pass))
|
||||
if !authed {
|
||||
log.Infoln("Auth failed from %s", request.RemoteAddr)
|
||||
return responseWith(request, http.StatusForbidden), user
|
||||
}
|
||||
log.Debugln("Auth success from %s -> %s", request.RemoteAddr, user)
|
||||
return
|
||||
}
|
||||
|
||||
func responseWith(request *http.Request, statusCode int) *http.Response {
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/component/auth"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
)
|
||||
|
||||
type Listener struct {
|
||||
@@ -32,10 +33,10 @@ func (l *Listener) Close() error {
|
||||
}
|
||||
|
||||
func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) {
|
||||
return NewWithAuthenticate(addr, tunnel, true, additions...)
|
||||
return NewWithAuthenticate(addr, tunnel, authStore.Authenticator(), additions...)
|
||||
}
|
||||
|
||||
func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additions ...inbound.Addition) (*Listener, error) {
|
||||
func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticator auth.Authenticator, additions ...inbound.Addition) (*Listener, error) {
|
||||
isDefault := false
|
||||
if len(additions) == 0 {
|
||||
isDefault = true
|
||||
@@ -50,11 +51,6 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c *lru.LruCache[string, bool]
|
||||
if authenticate {
|
||||
c = lru.New[string, bool](lru.WithAge[string, bool](30))
|
||||
}
|
||||
|
||||
hl := &Listener{
|
||||
listener: l,
|
||||
addr: addr,
|
||||
@@ -79,7 +75,7 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
|
||||
continue
|
||||
}
|
||||
}
|
||||
go HandleConn(conn, tunnel, c, additions...)
|
||||
go HandleConn(conn, tunnel, authenticator, additions...)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
"github.com/metacubex/mihomo/listener/http"
|
||||
"github.com/metacubex/mihomo/listener/socks"
|
||||
"github.com/metacubex/mihomo/transport/socks4"
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
type Listener struct {
|
||||
listener net.Listener
|
||||
addr string
|
||||
cache *lru.LruCache[string, bool]
|
||||
closed bool
|
||||
}
|
||||
|
||||
@@ -53,7 +52,6 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener
|
||||
ml := &Listener{
|
||||
listener: l,
|
||||
addr: addr,
|
||||
cache: lru.New[string, bool](lru.WithAge[string, bool](30)),
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
@@ -70,14 +68,14 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener
|
||||
continue
|
||||
}
|
||||
}
|
||||
go handleConn(c, tunnel, ml.cache, additions...)
|
||||
go handleConn(c, tunnel, additions...)
|
||||
}
|
||||
}()
|
||||
|
||||
return ml, nil
|
||||
}
|
||||
|
||||
func handleConn(conn net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
|
||||
func handleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
|
||||
N.TCPKeepAlive(conn)
|
||||
|
||||
bufConn := N.NewBufferedConn(conn)
|
||||
@@ -92,6 +90,6 @@ func handleConn(conn net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool
|
||||
case socks5.Version:
|
||||
socks.HandleSocks5(bufConn, tunnel, additions...)
|
||||
default:
|
||||
http.HandleConn(bufConn, tunnel, cache, additions...)
|
||||
http.HandleConn(bufConn, tunnel, authStore.Authenticator(), additions...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
name: "[Single] Build Linux"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
nightly:
|
||||
description: "Nightly prepare"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
nightly:
|
||||
description: "Nightly prepare"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust stable
|
||||
run: |
|
||||
rustup install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./backend/"
|
||||
prefix-key: "rust-stable"
|
||||
key: ubuntu-latest
|
||||
shared-key: "release"
|
||||
|
||||
- name: Install Node latest
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf openssl
|
||||
|
||||
- name: Pnpm install deps and download resources
|
||||
run: |
|
||||
pnpm i
|
||||
pnpm check
|
||||
|
||||
- name: Nightly Prepare
|
||||
if: ${{ inputs.nightly == true }}
|
||||
run: |
|
||||
pnpm prepare:nightly
|
||||
|
||||
- name: Tauri build
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tagName: ${{ inputs.tag }}
|
||||
releaseName: "Clash Nyanpasu Dev"
|
||||
releaseBody: "More new features are now supported."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
tauriScript: pnpm tauri
|
||||
args: -f nightly -c ./backend/tauri/tauri.nightly.conf.json
|
||||
@@ -0,0 +1,128 @@
|
||||
name: "[Single] Build macOS"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
aarch64:
|
||||
description: "Build aarch64 pkg"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
nightly:
|
||||
description: "Nightly prepare"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
aarch64:
|
||||
description: "Build aarch64 pkg"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
nightly:
|
||||
description: "Nightly prepare"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ inputs.aarch64 && 'macos-14' || 'macos-13' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: install Rust stable
|
||||
run: |
|
||||
rustup install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./backend/"
|
||||
prefix-key: "rust-stable"
|
||||
key: ${{ inputs.aarch64 && 'macos-14' || 'macos-13' }}
|
||||
shared-key: "release"
|
||||
|
||||
- name: Install the missing rust target (aarch64 Only)
|
||||
if: ${{ inputs.aarch64 == 'macos-14' }}
|
||||
run: |
|
||||
rustup target add aarch64-apple-darwin
|
||||
|
||||
- name: Install Node latest
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Set xcode version (amd64 Only)
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
if: ${{ inputs.aarch64 == false }}
|
||||
with:
|
||||
xcode-version: "15.0"
|
||||
|
||||
- name: Pnpm install
|
||||
run: |
|
||||
pnpm i
|
||||
pnpm check
|
||||
|
||||
- name: Pnpm check (macOS amd64)
|
||||
if: ${{ inputs.aarch64 == false }}
|
||||
run: |
|
||||
pnpm check
|
||||
|
||||
- name: Pnpm check (macOS aarch64)
|
||||
if: ${{ inputs.aarch64 == true }}
|
||||
run: |
|
||||
pnpm check --arch arm64 --sidecar-host aarch64-apple-darwin
|
||||
|
||||
- name: Nightly Prepare
|
||||
if: ${{ inputs.nightly == true }}
|
||||
run: |
|
||||
pnpm prepare:nightly
|
||||
|
||||
- name: Tauri build
|
||||
if: ${{ inputs.aarch64 == false }}
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tagName: ${{ inputs.tag }}
|
||||
releaseName: "Clash Nyanpasu Dev"
|
||||
releaseBody: "More new features are now supported."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
tauriScript: pnpm tauri
|
||||
args: -f nightly -c ./backend/tauri/tauri.nightly.conf.json
|
||||
|
||||
- name: Tauri build with Upload (macOS aarch64)
|
||||
if: ${{ inputs.aarch64 == true }}
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
run: |
|
||||
pnpm build:nightly --target aarch64-apple-darwin
|
||||
pnpm upload:osx-aarch64
|
||||
@@ -0,0 +1,106 @@
|
||||
name: "[Single] Build Windows NSIS"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
portable:
|
||||
description: "Build Portable pkg"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
nightly:
|
||||
description: "Nightly prepare"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
portable:
|
||||
description: "Build Portable pkg"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
nightly:
|
||||
description: "Nightly prepare"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust stable
|
||||
run: |
|
||||
rustup install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./backend/"
|
||||
prefix-key: "rust-stable"
|
||||
key: windows-latest
|
||||
shared-key: "release"
|
||||
|
||||
- name: Install Node latest
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Pnpm install deps and download resources
|
||||
run: |
|
||||
pnpm i
|
||||
pnpm check
|
||||
|
||||
- name: Nightly Prepare (Windows NSIS and Portable)
|
||||
if: ${{ inputs.nightly == true }}
|
||||
run: |
|
||||
pnpm prepare:nightly --nsis
|
||||
|
||||
- name: Tauri build
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tagName: ${{ inputs.tag }}
|
||||
releaseName: "Clash Nyanpasu Dev"
|
||||
releaseBody: "More new features are now supported."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
tauriScript: pnpm tauri
|
||||
args: -f nightly -c ./backend/tauri/tauri.nightly.conf.json
|
||||
|
||||
- name: Portable Bundle
|
||||
if: ${{ inputs.portable == true }}
|
||||
run: |
|
||||
pnpm portable
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
VITE_WIN_PORTABLE: 1
|
||||
@@ -0,0 +1,54 @@
|
||||
name: "[Single] Create Updater"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
nightly:
|
||||
description: "Nightly"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
nightly:
|
||||
description: "Nightly"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
updater:
|
||||
name: Update Nightly Updater
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true # Fetch all tags
|
||||
|
||||
- name: Install Node latest
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Pnpm install
|
||||
run: pnpm i
|
||||
|
||||
- name: Update Updater
|
||||
if: ${{ inputs.nightly == true }}
|
||||
run: pnpm updater:nightly
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release updater file
|
||||
if: ${{ inputs.nightly == false }}
|
||||
run: pnpm updater
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RELEASE_BODY: ${{ github.event.release.body }}
|
||||
@@ -0,0 +1,43 @@
|
||||
name: "[Single] Delete Current Releases"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
delete:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Delete current release assets
|
||||
uses: mknejp/delete-release-assets@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ inputs.tag }}
|
||||
fail-if-no-assets: false
|
||||
fail-if-no-release: false
|
||||
assets: |
|
||||
*.zip
|
||||
*.gz
|
||||
*.AppImage
|
||||
*.deb
|
||||
*.rpm
|
||||
*.dmg
|
||||
*.msi
|
||||
*.sig
|
||||
*.exe
|
||||
*.json
|
||||
@@ -0,0 +1,53 @@
|
||||
name: "[Single] Send Message to Telegram"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
nightly:
|
||||
description: "Nightly"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
nightly:
|
||||
description: "Nightly"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
telegram:
|
||||
name: Notify Telegram
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Pnpm install
|
||||
run: pnpm i
|
||||
|
||||
- name: Send Releases
|
||||
run: |
|
||||
if [ "${{ inputs.nightly }}" = "true" ]; then
|
||||
pnpm send-notify:nightly
|
||||
else
|
||||
pnpm send-notify
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
|
||||
TELEGRAM_API_ID: ${{ secrets.TELEGRAM_API_ID }}
|
||||
TELEGRAM_API_HASH: ${{ secrets.TELEGRAM_API_HASH }}
|
||||
TELEGRAM_TO: "@keikolog"
|
||||
TELEGRAM_TO_NIGHTLY: "@ClashNyanpasu"
|
||||
@@ -0,0 +1,58 @@
|
||||
name: "[Single] Update Tag"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
update_tag:
|
||||
name: Update tag
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set Env
|
||||
run: |
|
||||
echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
|
||||
echo "CURRENT_GIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
|
||||
- name: Update Tag
|
||||
uses: greenhat616/update-tag@v1
|
||||
with:
|
||||
tag_name: ${{ inputs.tag }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create release body
|
||||
run: |
|
||||
cat > release.txt << 'EOF'
|
||||
## Clash Nyanpasu Nightly Build
|
||||
Release created at ${{ env.BUILDTIME }}.
|
||||
Daily build of **Clash Nyanpasu** on *main* branch.
|
||||
You could download previous Nightly Builds from [here](https://t.me/ClashNyanpasu).
|
||||
***[See the development log here](https://t.me/s/keikolog/)***
|
||||
EOF
|
||||
|
||||
- name: Update Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: Clash Nyanpasu Dev
|
||||
tag_name: ${{ inputs.tag }}
|
||||
body_path: release.txt
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
-233
@@ -1,233 +0,0 @@
|
||||
name: Dev Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "15 0 * * *" # 每天 08:15 UTC+8 自动构建
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUST_BACKTRACE: short
|
||||
|
||||
jobs:
|
||||
release:
|
||||
strategy:
|
||||
matrix:
|
||||
targets:
|
||||
- os: windows-latest
|
||||
category: nsis # and portable
|
||||
# - os: windows-latest
|
||||
# category: msi
|
||||
- os: ubuntu-latest
|
||||
category: all
|
||||
- os: macos-13
|
||||
category: amd64
|
||||
- os: macos-13
|
||||
category: aarch64
|
||||
|
||||
runs-on: ${{ matrix.targets.os }}
|
||||
if: startsWith(github.repository, 'LibNyanpasu')
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: install Rust stable
|
||||
run: |
|
||||
rustup install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./backend/"
|
||||
prefix-key: "rust-stable"
|
||||
key: ${{ matrix.targets.os }}
|
||||
shared-key: "release"
|
||||
|
||||
- name: Install the missing rust target (macOS Only)
|
||||
if: startsWith(matrix.targets.os, 'macos-') && matrix.targets.category == 'aarch64'
|
||||
run: |
|
||||
rustup target add aarch64-apple-darwin
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Delete current release assets
|
||||
if: startsWith(matrix.targets.os, 'ubuntu-')
|
||||
uses: mknejp/delete-release-assets@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: pre-release
|
||||
fail-if-no-assets: false
|
||||
fail-if-no-release: false
|
||||
assets: |
|
||||
*.zip
|
||||
*.gz
|
||||
*.AppImage
|
||||
*.deb
|
||||
*.dmg
|
||||
*.msi
|
||||
*.sig
|
||||
*.exe
|
||||
*.json
|
||||
|
||||
- name: Install Dependencies (Ubuntu Only)
|
||||
if: startsWith(matrix.targets.os, 'ubuntu-')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf openssl
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
if: startsWith(matrix.targets.os, 'macos-')
|
||||
with:
|
||||
xcode-version: "15.0"
|
||||
- name: Pnpm install and check
|
||||
run: |
|
||||
pnpm i
|
||||
pnpm check
|
||||
- name: Nightly Prepare
|
||||
if: startsWith(matrix.targets.os, 'windows-') == false
|
||||
run: |
|
||||
pnpm prepare:nightly
|
||||
- name: Nightly Prepare (MSI only)
|
||||
if: startsWith(matrix.targets.os, 'windows-') && matrix.targets.category == 'msi'
|
||||
run: |
|
||||
pnpm prepare:nightly --msi
|
||||
- name: Nightly Prepare (Windows NSIS and Portable)
|
||||
if: startsWith(matrix.targets.os, 'windows-') && matrix.targets.category == 'nsis'
|
||||
run: |
|
||||
pnpm prepare:nightly --nsis
|
||||
- name: Tauri build
|
||||
if: startsWith(matrix.targets.os, 'macos-') == false || matrix.targets.category != 'aarch64'
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tagName: pre-release
|
||||
releaseName: "Clash Nyanpasu Dev"
|
||||
releaseBody: "More new features are now supported."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
tauriScript: pnpm tauri
|
||||
args: -f nightly -c ./backend/tauri/tauri.nightly.conf.json
|
||||
- name: Portable Bundle (Windows Only)
|
||||
if: startsWith(matrix.targets.os, 'windows-') && matrix.targets.category == 'nsis'
|
||||
run: |
|
||||
pnpm portable
|
||||
env:
|
||||
TAG_NAME: pre-release
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
VITE_WIN_PORTABLE: 1
|
||||
|
||||
- name: Pnpm check (macOS aarch64)
|
||||
if: startsWith(matrix.targets.os, 'macos-') && matrix.targets.category == 'aarch64'
|
||||
run: |
|
||||
pnpm check --arch arm64 --sidecar-host aarch64-apple-darwin
|
||||
|
||||
- name: Tauri build with Upload (macOS aarch64)
|
||||
if: startsWith(matrix.targets.os, 'macos-') && matrix.targets.category == 'aarch64'
|
||||
env:
|
||||
TAG_NAME: pre-release
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
run: |
|
||||
pnpm build:nightly --target aarch64-apple-darwin
|
||||
pnpm upload:osx-aarch64
|
||||
|
||||
update_tag:
|
||||
name: Update tag
|
||||
runs-on: ubuntu-latest
|
||||
needs: [release]
|
||||
if: startsWith(github.repository, 'LibNyanpasu')
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set Env
|
||||
run: |
|
||||
echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
|
||||
echo "CURRENT_GIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- name: Update Tag
|
||||
uses: greenhat616/update-tag@v1
|
||||
with:
|
||||
tag_name: pre-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: |
|
||||
cat > release.txt << 'EOF'
|
||||
## Clash Nyanpasu Nightly Build
|
||||
Release created at ${{ env.BUILDTIME }}.
|
||||
Daily build of **Clash Nyanpasu** on *main* branch.
|
||||
***[See the development log here](https://t.me/keikolog/462)***
|
||||
EOF
|
||||
- name: Update Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: Clash Nyanpasu Dev
|
||||
tag_name: pre-release
|
||||
body_path: release.txt
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
updater:
|
||||
name: Update Nightly Updater
|
||||
runs-on: ubuntu-latest
|
||||
needs: [release, update_tag]
|
||||
if: startsWith(github.repository, 'LibNyanpasu')
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true # Fetch all tags
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Pnpm install
|
||||
run: pnpm i
|
||||
- name: Update Updater
|
||||
run: pnpm updater:nightly
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
telegram:
|
||||
name: Notify Telegram
|
||||
runs-on: ubuntu-latest
|
||||
needs: [release, update_tag]
|
||||
if: startsWith(github.repository, 'LibNyanpasu')
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Pnpm install
|
||||
run: pnpm i
|
||||
|
||||
- name: Send Releases
|
||||
run: pnpm send-notify:nightly
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
|
||||
TELEGRAM_API_ID: ${{ secrets.TELEGRAM_API_ID }}
|
||||
TELEGRAM_API_HASH: ${{ secrets.TELEGRAM_API_HASH }}
|
||||
TELEGRAM_TO: "@keikolog"
|
||||
TELEGRAM_TO_NIGHTLY: "@ClashNyanpasu"
|
||||
@@ -0,0 +1,80 @@
|
||||
name: "[Entire] Build Developer Version"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "15 0 * * *" # 每天 08:15 UTC+8 自动构建
|
||||
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUST_BACKTRACE: short
|
||||
|
||||
jobs:
|
||||
delete_current_releases:
|
||||
name: Delete Current Releases
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.repository, 'LibNyanpasu') }}
|
||||
uses: ./.github/workflows/deps-delete-releases.yaml
|
||||
with:
|
||||
tag: "pre-release"
|
||||
|
||||
windows_build:
|
||||
name: Windows Build
|
||||
uses: ./.github/workflows/deps-build-windows-nsis.yaml
|
||||
needs: [delete_current_releases]
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
tag: "pre-release"
|
||||
secrets: inherit
|
||||
|
||||
linux_build:
|
||||
name: Linux Build
|
||||
uses: ./.github/workflows/deps-build-linux.yaml
|
||||
needs: [delete_current_releases]
|
||||
with:
|
||||
nightly: true
|
||||
tag: "pre-release"
|
||||
secrets: inherit
|
||||
|
||||
macos_amd64_build:
|
||||
name: macOS amd64 Build
|
||||
uses: ./.github/workflows/deps-build-macos.yaml
|
||||
needs: [delete_current_releases]
|
||||
with:
|
||||
nightly: true
|
||||
aarch64: false
|
||||
tag: "pre-release"
|
||||
secrets: inherit
|
||||
|
||||
macos_aarch64_build:
|
||||
name: macOS aarch64 Build
|
||||
uses: ./.github/workflows/deps-build-macos.yaml
|
||||
needs: [delete_current_releases]
|
||||
with:
|
||||
nightly: true
|
||||
aarch64: true
|
||||
tag: "pre-release"
|
||||
secrets: inherit
|
||||
|
||||
update_tag:
|
||||
name: Update tag
|
||||
needs: [windows_build, linux_build, macos_amd64_build, macos_aarch64_build]
|
||||
uses: ./.github/workflows/deps-update-tag.yaml
|
||||
with:
|
||||
tag: "pre-release"
|
||||
|
||||
updater:
|
||||
name: Create Updater
|
||||
needs: [update_tag]
|
||||
uses: ./.github/workflows/deps-create-updater.yaml
|
||||
with:
|
||||
nightly: true
|
||||
|
||||
telegram:
|
||||
name: Send Release Message to Telegram
|
||||
if: startsWith(github.repository, 'LibNyanpasu')
|
||||
needs: [update_tag]
|
||||
uses: ./.github/workflows/deps-message-telegram.yaml
|
||||
with:
|
||||
nightly: true
|
||||
secrets: inherit
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
name: Updater CI
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
release-update:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
startsWith(github.repository, 'LibNyanpasu')
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Pnpm install
|
||||
run: pnpm i
|
||||
|
||||
- name: Release updater file
|
||||
run: pnpm updater
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
Generated
+89
-123
@@ -208,7 +208,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -409,7 +409,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -444,7 +444,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -581,7 +581,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"which 4.4.2",
|
||||
]
|
||||
|
||||
@@ -920,7 +920,7 @@ dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -971,6 +971,7 @@ dependencies = [
|
||||
"objc",
|
||||
"once_cell",
|
||||
"open 5.3.0",
|
||||
"os_pipe",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"port_scanner",
|
||||
@@ -1113,7 +1114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1323,7 +1324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1333,7 +1334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1373,7 +1374,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1384,7 +1385,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1477,7 +1478,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1488,7 +1489,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1509,7 +1510,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1519,7 +1520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1532,7 +1533,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version 0.4.0",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1620,7 +1621,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "dirs-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/LibNyanpasu/nyanpasu-utils#aae6449b002bfd36eba878153e2e3b5029b9fd29"
|
||||
source = "git+https://github.com/LibNyanpasu/nyanpasu-utils#31f59134a7e94922f13b07b21047390b962ce3c4"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"thiserror",
|
||||
@@ -1658,7 +1659,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1771,23 +1772,23 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
checksum = "c6dc8c8ff84895b051f07a0e65f975cf225131742531338752abfb324e4449ff"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
checksum = "06676b12debf7bba6903559720abca942d3a66b8acb88815fd2c7c6537e9ade1"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -1873,9 +1874,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fast_image_resize"
|
||||
version = "4.2.0"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cd2f79218cdfe398519739df6872a6f5747ca08e1f4fd3179f4b053a0b05f9"
|
||||
checksum = "2ca4b58827213977eabab8ee8d8258db8441338f3a1832a1c0f2de3372175531"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"document-features",
|
||||
@@ -2007,7 +2008,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2131,7 +2132,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2949,7 +2950,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3093,9 +3094,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.31"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@@ -3464,7 +3465,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3795,7 +3795,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3861,7 +3861,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nyanpasu-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/LibNyanpasu/nyanpasu-utils#aae6449b002bfd36eba878153e2e3b5029b9fd29"
|
||||
source = "git+https://github.com/LibNyanpasu/nyanpasu-utils#31f59134a7e94922f13b07b21047390b962ce3c4"
|
||||
dependencies = [
|
||||
"constcat",
|
||||
"derive_builder",
|
||||
@@ -3869,6 +3869,7 @@ dependencies = [
|
||||
"encoding_rs",
|
||||
"kill_tree",
|
||||
"memchr",
|
||||
"os-utils",
|
||||
"os_pipe",
|
||||
"parking_lot",
|
||||
"serde",
|
||||
@@ -4020,9 +4021,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.1"
|
||||
version = "0.36.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
|
||||
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -4083,7 +4084,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4139,6 +4140,16 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/LibNyanpasu/nyanpasu-utils#31f59134a7e94922f13b07b21047390b962ce3c4"
|
||||
dependencies = [
|
||||
"nix 0.29.0",
|
||||
"shared_child",
|
||||
"windows 0.58.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_info"
|
||||
version = "3.8.2"
|
||||
@@ -4292,7 +4303,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4430,7 +4441,7 @@ dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4477,7 +4488,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4597,7 +4608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4674,7 +4685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4855,16 +4866,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ravif"
|
||||
version = "0.11.8"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6ba61c28ba24c0cf8406e025cb29a742637e3f70776e61c27a8a8b72a042d12"
|
||||
checksum = "5797d09f9bd33604689e87e8380df4951d4912f01b63f71205e2abd4ae25e6b6"
|
||||
dependencies = [
|
||||
"avif-serialize",
|
||||
"imgref",
|
||||
"loop9",
|
||||
"quick-error",
|
||||
"rav1e",
|
||||
"rayon",
|
||||
"rgb",
|
||||
]
|
||||
|
||||
@@ -4955,7 +4965,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5169,7 +5179,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml 0.8.26",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5434,7 +5444,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5457,7 +5467,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5508,7 +5518,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5897,9 +5907,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
version = "2.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5947,7 +5957,7 @@ dependencies = [
|
||||
"interfaces",
|
||||
"iptools",
|
||||
"thiserror",
|
||||
"windows 0.57.0",
|
||||
"windows 0.58.0",
|
||||
"winreg 0.52.0",
|
||||
]
|
||||
|
||||
@@ -6402,7 +6412,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6428,7 +6438,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6550,7 +6560,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6662,7 +6672,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.14",
|
||||
"winnow 0.6.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6703,7 +6713,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7066,7 +7076,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -7100,7 +7110,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -7482,16 +7492,6 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core 0.57.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.58.0"
|
||||
@@ -7533,18 +7533,6 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement 0.57.0",
|
||||
"windows-interface 0.57.0",
|
||||
"windows-result 0.1.2",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.58.0"
|
||||
@@ -7576,18 +7564,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7598,7 +7575,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7609,18 +7586,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7631,7 +7597,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7974,9 +7940,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.14"
|
||||
version = "0.6.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374ec40a2d767a3c1b4972d9475ecd557356637be906f2cb3f7fe17a6eb5e22f"
|
||||
checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -8167,9 +8133,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "4.3.1"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "851238c133804e0aa888edf4a0229481c753544ca12a60fd1c3230c8a500fe40"
|
||||
checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
@@ -8205,14 +8171,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "4.3.1"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d5a3f12c20bd473be3194af6b49d50d7bb804ef3192dc70eddedb26b85d9da7"
|
||||
checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
|
||||
dependencies = [
|
||||
"proc-macro-crate 3.1.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
@@ -8244,7 +8210,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8264,7 +8230,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8384,9 +8350,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "4.1.2"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1724a2b330760dc7d2a8402d841119dc869ef120b139d29862d6980e9c75bfc9"
|
||||
checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
|
||||
dependencies = [
|
||||
"endi",
|
||||
"enumflags2",
|
||||
@@ -8397,24 +8363,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "4.1.2"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55025a7a518ad14518fb243559c058a2e5b848b015e31f1d90414f36e3317859"
|
||||
checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
|
||||
dependencies = [
|
||||
"proc-macro-crate 3.1.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "2.0.0"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc242db087efc22bd9ade7aa7809e4ba828132edc312871584a6b4391bdf8786"
|
||||
checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
@@ -20,7 +20,7 @@ iptools = "0.2.5"
|
||||
winreg = { version = "0.52", features = ["transactions"] }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies.windows]
|
||||
version = "0.57"
|
||||
version = "0.58"
|
||||
features = [
|
||||
"Win32_Networking_WinInet",
|
||||
# "Win32_Networking_WinHttp",
|
||||
|
||||
@@ -15,6 +15,7 @@ serde = "1"
|
||||
simd-json = "0.13"
|
||||
chrono = "0.4"
|
||||
rustc_version = "0.4"
|
||||
semver = "1.0"
|
||||
|
||||
[dependencies]
|
||||
nyanpasu-utils = { git = "https://github.com/LibNyanpasu/nyanpasu-utils" }
|
||||
@@ -108,6 +109,7 @@ timeago = "0.4"
|
||||
ansi-str = "0.8"
|
||||
humansize = "2.1.3"
|
||||
convert_case = "0.6.0"
|
||||
os_pipe = "1.2.0"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.25.0"
|
||||
|
||||
@@ -10,6 +10,8 @@ struct PackageJson {
|
||||
fn main() {
|
||||
let mut pkg_json = read("../../package.json").unwrap();
|
||||
let pkg_json: PackageJson = simd_json::from_slice(&mut pkg_json).unwrap();
|
||||
let version = semver::Version::parse(pkg_json.version.as_str()).unwrap();
|
||||
let is_prerelase = !version.pre.is_empty();
|
||||
println!("cargo:rustc-env=NYANPASU_VERSION={}", pkg_json.version);
|
||||
// Git Information
|
||||
let output = Command::new("git")
|
||||
@@ -42,10 +44,14 @@ fn main() {
|
||||
// Build Profile
|
||||
println!(
|
||||
"cargo:rustc-env=BUILD_PROFILE={}",
|
||||
match env::var("PROFILE").unwrap().as_str() {
|
||||
"release" => "Release",
|
||||
"debug" => "Debug",
|
||||
_ => "Unknown",
|
||||
if is_prerelase {
|
||||
"Nightly"
|
||||
} else {
|
||||
match env::var("PROFILE").unwrap().as_str() {
|
||||
"release" => "Release",
|
||||
"debug" => "Debug",
|
||||
_ => "Unknown",
|
||||
}
|
||||
}
|
||||
);
|
||||
// Build Platform
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
use clap::Args;
|
||||
|
||||
use crate::core::migration::{
|
||||
units::{find_migration, get_migrations},
|
||||
MigrationAdvice, Runner,
|
||||
};
|
||||
use colored::Colorize;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct MigrateOpts {
|
||||
/// force to run migration without advice
|
||||
#[arg(long, default_value = "false")]
|
||||
skip_advice: bool,
|
||||
/// Run specific migration
|
||||
#[arg(long)]
|
||||
migration: Option<String>,
|
||||
/// Run migration up to specific version
|
||||
#[arg(long)]
|
||||
version: Option<String>,
|
||||
/// List all migrations
|
||||
#[arg(long)]
|
||||
list: bool,
|
||||
}
|
||||
|
||||
pub fn parse(args: &MigrateOpts) {
|
||||
let runner = if args.skip_advice {
|
||||
Runner::new_with_skip_advice()
|
||||
} else {
|
||||
Runner::default()
|
||||
};
|
||||
if args.list {
|
||||
println!("Available migrations:\n");
|
||||
let migrations = get_migrations();
|
||||
for migration in migrations {
|
||||
let advice = runner.advice_migration(migration.as_ref());
|
||||
println!(
|
||||
"[{}] {} - {}",
|
||||
match &advice {
|
||||
MigrationAdvice::Pending => format!("{}", advice).yellow(),
|
||||
MigrationAdvice::Ignored => format!("{}", advice).cyan(),
|
||||
MigrationAdvice::Done => format!("{}", advice).green(),
|
||||
},
|
||||
migration.version(),
|
||||
migration.name()
|
||||
);
|
||||
}
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
if args.migration.is_some() && args.version.is_some() {
|
||||
eprintln!("Please specify only one of migration or version.");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if args.migration.is_none() && args.version.is_none() {
|
||||
match crate::consts::BUILD_INFO.build_profile {
|
||||
"Nightly" => {
|
||||
println!("Running all upcoming migrations.");
|
||||
runner.run_upcoming_units().unwrap();
|
||||
}
|
||||
_ => {
|
||||
println!(
|
||||
"No migration or version specified. Running migrations up to current version."
|
||||
);
|
||||
runner
|
||||
.run_units_up_to_version(&runner.current_version)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(migration) = args.migration.as_ref() {
|
||||
let migration = find_migration(migration);
|
||||
match migration {
|
||||
Some(migration) => {
|
||||
runner.run_migration(migration.as_ref()).unwrap();
|
||||
}
|
||||
None => {
|
||||
eprintln!("Migration not found.");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
} else if let Some(version) = args.version.as_deref() {
|
||||
let version = semver::Version::parse(version).unwrap();
|
||||
runner.run_units_up_to_version(&version).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn migrate_home_dir_handler(target_path: &str) -> anyhow::Result<()> {
|
||||
use crate::utils::{self, dirs};
|
||||
use anyhow::Context;
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
use std::{path::PathBuf, process::Command, str::FromStr, thread, time::Duration};
|
||||
use sysinfo::System;
|
||||
use tauri::utils::platform::current_exe;
|
||||
println!("target path {}", target_path);
|
||||
|
||||
let token = Token::with_current_process()?;
|
||||
if let PrivilegeLevel::NotPrivileged = token.privilege_level()? {
|
||||
eprintln!("Please run this command as admin to prevent authority issue.");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let current_home_dir = dirs::app_config_dir()?;
|
||||
let target_home_dir = PathBuf::from_str(target_path)?;
|
||||
|
||||
// 1. waiting for app exited
|
||||
println!("waiting for app exited.");
|
||||
let placeholder = dirs::get_single_instance_placeholder();
|
||||
let mut single_instance: single_instance::SingleInstance;
|
||||
loop {
|
||||
single_instance = single_instance::SingleInstance::new(&placeholder)
|
||||
.context("failed to create single instance")?;
|
||||
if single_instance.is_single() {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
|
||||
// 2. kill all related processes.
|
||||
let related_names = [
|
||||
"clash-verge-service",
|
||||
"clash-nyanpasu-service", // for upcoming v1.6.x
|
||||
"clash-rs",
|
||||
"mihomo",
|
||||
"mihomo-alpha",
|
||||
"clash",
|
||||
];
|
||||
let sys = System::new_all();
|
||||
'outer: for process in sys.processes().values() {
|
||||
let mut process_name = process.name();
|
||||
if process_name.ends_with(".exe") {
|
||||
process_name = &process_name[..process_name.len() - 4]; // remove .exe
|
||||
}
|
||||
for name in related_names.iter() {
|
||||
if process_name.ends_with(name) {
|
||||
println!(
|
||||
"Process found: {} should be killed. killing...",
|
||||
process_name
|
||||
);
|
||||
if !process.kill() {
|
||||
eprintln!("failed to kill {}.", process_name)
|
||||
}
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. do config migrate and update the registry.
|
||||
utils::init::do_config_migration(¤t_home_dir, &target_home_dir)?;
|
||||
utils::winreg::set_app_dir(target_home_dir.as_path())?;
|
||||
println!("migration finished. starting application...");
|
||||
drop(single_instance); // release single instance lock
|
||||
|
||||
let app_path = current_exe()?;
|
||||
thread::spawn(move || {
|
||||
Command::new(app_path).spawn().unwrap();
|
||||
});
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn migrate_home_dir_handler(_target_path: &str) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
+9
-3
@@ -2,6 +2,7 @@ use std::str::FromStr;
|
||||
|
||||
use anyhow::Ok;
|
||||
use clap::{Parser, Subcommand};
|
||||
use migrate::MigrateOpts;
|
||||
use tauri::utils::platform::current_exe;
|
||||
|
||||
use crate::utils;
|
||||
@@ -24,9 +25,11 @@ pub struct Cli {
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum Commands {
|
||||
/// Migrate home directory to another path.
|
||||
MigrateHomeDir {
|
||||
target_path: String,
|
||||
},
|
||||
MigrateHomeDir { target_path: String },
|
||||
/// do migration
|
||||
Migrate(MigrateOpts),
|
||||
|
||||
/// Collect the environment variables.
|
||||
Collect,
|
||||
/// A launch bridge to resolve the delay exit issue.
|
||||
Launch {
|
||||
@@ -55,6 +58,9 @@ pub fn parse() -> anyhow::Result<()> {
|
||||
if let Some(commands) = &cli.command {
|
||||
let guard = DelayedExitGuard::new();
|
||||
match commands {
|
||||
Commands::Migrate(opts) => {
|
||||
migrate::parse(opts);
|
||||
}
|
||||
Commands::MigrateHomeDir { target_path } => {
|
||||
migrate::migrate_home_dir_handler(target_path).unwrap();
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn migrate_home_dir_handler(target_path: &str) -> anyhow::Result<()> {
|
||||
use crate::utils::{self, dirs};
|
||||
use anyhow::Context;
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
use std::{path::PathBuf, process::Command, str::FromStr, thread, time::Duration};
|
||||
use sysinfo::System;
|
||||
use tauri::utils::platform::current_exe;
|
||||
println!("target path {}", target_path);
|
||||
|
||||
let token = Token::with_current_process()?;
|
||||
if let PrivilegeLevel::NotPrivileged = token.privilege_level()? {
|
||||
eprintln!("Please run this command as admin to prevent authority issue.");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let current_home_dir = dirs::app_home_dir()?;
|
||||
let target_home_dir = PathBuf::from_str(target_path)?;
|
||||
|
||||
// 1. waiting for app exited
|
||||
println!("waiting for app exited.");
|
||||
let placeholder = dirs::get_single_instance_placeholder();
|
||||
let mut single_instance: single_instance::SingleInstance;
|
||||
loop {
|
||||
single_instance = single_instance::SingleInstance::new(&placeholder)
|
||||
.context("failed to create single instance")?;
|
||||
if single_instance.is_single() {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
|
||||
// 2. kill all related processes.
|
||||
let related_names = [
|
||||
"clash-verge-service",
|
||||
"clash-nyanpasu-service", // for upcoming v1.6.x
|
||||
"clash-rs",
|
||||
"mihomo",
|
||||
"mihomo-alpha",
|
||||
"clash",
|
||||
];
|
||||
let sys = System::new_all();
|
||||
'outer: for process in sys.processes().values() {
|
||||
let mut process_name = process.name();
|
||||
if process_name.ends_with(".exe") {
|
||||
process_name = &process_name[..process_name.len() - 4]; // remove .exe
|
||||
}
|
||||
for name in related_names.iter() {
|
||||
if process_name.ends_with(name) {
|
||||
println!(
|
||||
"Process found: {} should be killed. killing...",
|
||||
process_name
|
||||
);
|
||||
if !process.kill() {
|
||||
eprintln!("failed to kill {}.", process_name)
|
||||
}
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. do config migrate and update the registry.
|
||||
utils::init::do_config_migration(¤t_home_dir, &target_home_dir)?;
|
||||
utils::winreg::set_app_dir(target_home_dir.as_path())?;
|
||||
println!("migration finished. starting application...");
|
||||
drop(single_instance); // release single instance lock
|
||||
|
||||
let app_path = current_exe()?;
|
||||
thread::spawn(move || {
|
||||
Command::new(app_path).spawn().unwrap();
|
||||
});
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn migrate_home_dir_handler(_target_path: &str) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
use derive_builder::Builder;
|
||||
use once_cell::sync::Lazy;
|
||||
use semver::Version;
|
||||
/// A simple file based database for storing the migration status.
|
||||
///
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{borrow::Cow, collections::HashMap, io::Write, path::PathBuf};
|
||||
|
||||
use super::MigrationState;
|
||||
|
||||
/// A lockfile store the migrated version and the state.
|
||||
/// The lower version of the migration will be ignored.
|
||||
static MIGRATION_LOCK_FILE: Lazy<PathBuf> = Lazy::new(|| {
|
||||
let mut path = crate::utils::dirs::app_config_dir().unwrap();
|
||||
path.push("migration.lock");
|
||||
path
|
||||
});
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
|
||||
#[builder(default)]
|
||||
pub struct MigrationFile<'a> {
|
||||
pub version: Cow<'a, Version>,
|
||||
pub states: HashMap<Cow<'a, str>, MigrationState>,
|
||||
}
|
||||
|
||||
impl MigrationFileBuilder<'_> {
|
||||
pub fn read_file(mut self) -> Self {
|
||||
let content = std::fs::read_to_string(&*MIGRATION_LOCK_FILE).ok();
|
||||
if let Some(content) = content {
|
||||
let file: Option<MigrationFile> = serde_yaml::from_str(&content).ok();
|
||||
if let Some(file) = file {
|
||||
self.version = Some(file.version);
|
||||
self.states = Some(file.states);
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MigrationFile<'_> {
|
||||
fn default() -> Self {
|
||||
// since 1.6.0, we have introduced the migration system. so the last version of 1.5.x is 1.5.1.
|
||||
let ver = Version::parse("1.5.1").unwrap();
|
||||
Self {
|
||||
version: Cow::Owned(ver),
|
||||
states: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MigrationFile<'a> {
|
||||
/// Create or Truncate the lock file and write the content.
|
||||
pub fn write_file(&self) -> Result<(), std::io::Error> {
|
||||
let content = serde_yaml::to_string(self).map_err(|e| {
|
||||
log::error!("Failed to serialize the migration file: {}", e);
|
||||
std::io::Error::new(std::io::ErrorKind::Other, e)
|
||||
})?;
|
||||
let mut file = std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(&*MIGRATION_LOCK_FILE)?;
|
||||
file.write(
|
||||
"# This file is generated by the migration system, do not edit it manually.\n"
|
||||
.as_bytes(),
|
||||
)
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to write the migration file: {}", e);
|
||||
e
|
||||
})?;
|
||||
file.write_all(content.as_bytes())
|
||||
}
|
||||
|
||||
pub fn get_state(&self, name: &str) -> Option<MigrationState> {
|
||||
self.states.get(name).copied()
|
||||
}
|
||||
|
||||
pub fn set_state(&mut self, name: Cow<'a, str>, state: MigrationState) {
|
||||
self.states.insert(name, state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
#![allow(dead_code)]
|
||||
/// A migration mod indicates the migration of the old version to the new version.
|
||||
/// Because this runner run at the start of the app, it will use eprintln or println to print the migration log.
|
||||
///
|
||||
///
|
||||
use dyn_clone::{clone_trait_object, DynClone};
|
||||
use semver::Version;
|
||||
use std::{borrow::Cow, cell::RefCell};
|
||||
|
||||
mod db;
|
||||
pub mod units;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MigrationState {
|
||||
/// The migration is pending.
|
||||
NotStarted,
|
||||
/// The migration is in progress.
|
||||
InProgress,
|
||||
/// The migration is completed.
|
||||
Completed,
|
||||
/// The migration is failed.
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum MigrationAdvice {
|
||||
/// The migration is required to run.
|
||||
Pending,
|
||||
/// The migration is ignored.
|
||||
Ignored,
|
||||
/// The migration has been run.
|
||||
Done,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MigrationAdvice {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
MigrationAdvice::Pending => write!(f, "Pending"),
|
||||
MigrationAdvice::Ignored => write!(f, "Ignored"),
|
||||
MigrationAdvice::Done => write!(f, "Done"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Unit<'a, T>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
/// A List of migrations, it should be used to wrap a list of migrations in a single version.
|
||||
/// Although the fn signature is T generic, it should use a Vec<DynMigration> as the input.
|
||||
Batch(Cow<'a, [T]>),
|
||||
Single(Cow<'a, T>),
|
||||
}
|
||||
|
||||
impl<'a, T> From<T> for Unit<'a, T>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
fn from(item: T) -> Self {
|
||||
Unit::Single(Cow::Owned(item))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> From<&'a T> for Unit<'a, T>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
fn from(item: &'a T) -> Self {
|
||||
Unit::Single(Cow::Borrowed(item))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> From<&'a [T]> for Unit<'a, T>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
fn from(list: &'a [T]) -> Self {
|
||||
Unit::Batch(Cow::Borrowed(list))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> From<Vec<T>> for Unit<'a, T>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
fn from(list: Vec<T>) -> Self {
|
||||
Unit::Batch(Cow::Owned(list))
|
||||
}
|
||||
}
|
||||
|
||||
type DynMigration<'a> = Box<dyn Migration<'a> + Send + Sync + 'a>;
|
||||
|
||||
pub trait Migration<'a>: DynClone {
|
||||
/// A version field to indicate the version of the migration.
|
||||
/// It used to compare with the current version to determine whether the migration is needed.
|
||||
fn version(&self) -> &'a Version;
|
||||
|
||||
/// A name field to indicate the name of the migration.
|
||||
fn name(&self) -> Cow<'a, str>;
|
||||
|
||||
fn migrate(&self) -> std::io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
clone_trait_object!(Migration<'_>);
|
||||
|
||||
auto trait NotDynMigration {}
|
||||
impl !NotDynMigration for DynMigration<'_> {}
|
||||
|
||||
/// Impl From T for DynMigration excludes itself.
|
||||
impl<'a, T> From<T> for DynMigration<'a>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync + NotDynMigration + 'a,
|
||||
{
|
||||
fn from(item: T) -> Self {
|
||||
Box::new(item)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Migration<'a> for Unit<'a, T>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
fn version(&self) -> &'a Version {
|
||||
match self {
|
||||
Unit::Single(item) => item.version(),
|
||||
Unit::Batch(list) => list.first().unwrap().version(),
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> Cow<'a, str> {
|
||||
match self {
|
||||
Unit::Single(item) => item.name(),
|
||||
Unit::Batch(list) => Cow::Owned(format!(
|
||||
"{} migrations for v{}",
|
||||
list.len(),
|
||||
list.first().unwrap().version()
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn migrate(&self) -> std::io::Result<()> {
|
||||
unimplemented!("Batch migrations should be handled by the runner.")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Migration<'a> for DynMigration<'a> {
|
||||
fn version(&self) -> &'a Version {
|
||||
self.as_ref().version()
|
||||
}
|
||||
|
||||
fn name(&self) -> Cow<'a, str> {
|
||||
self.as_ref().name()
|
||||
}
|
||||
|
||||
fn migrate(&self) -> std::io::Result<()> {
|
||||
self.as_ref().migrate()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Runner<'a> {
|
||||
pub current_version: Cow<'a, Version>,
|
||||
skip_advice: bool,
|
||||
store: RefCell<db::MigrationFile<'a>>,
|
||||
}
|
||||
|
||||
impl Default for Runner<'_> {
|
||||
fn default() -> Self {
|
||||
let ver = Version::parse(crate::consts::BUILD_INFO.pkg_version).unwrap();
|
||||
let file = db::MigrationFileBuilder::default()
|
||||
.read_file()
|
||||
.build()
|
||||
.unwrap();
|
||||
Self {
|
||||
current_version: Cow::Owned(ver),
|
||||
skip_advice: false,
|
||||
store: RefCell::new(file),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Runner<'_> {
|
||||
fn drop(&mut self) {
|
||||
let mut store = self.store.take();
|
||||
store.version = Cow::Borrowed(&self.current_version);
|
||||
store.write_file().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Runner<'_> {
|
||||
pub fn new_with_skip_advice() -> Self {
|
||||
let ver = Version::parse(crate::consts::BUILD_INFO.pkg_version).unwrap();
|
||||
let file = db::MigrationFileBuilder::default()
|
||||
.read_file()
|
||||
.build()
|
||||
.unwrap();
|
||||
Self {
|
||||
skip_advice: true,
|
||||
current_version: Cow::Owned(ver),
|
||||
store: RefCell::new(file),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn advice_migration<'a, T>(&self, migration: &T) -> MigrationAdvice
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
let migration_ver = migration.version();
|
||||
let store = self.store.borrow();
|
||||
if migration_ver >= &store.version {
|
||||
// Judge the migration is run or not.
|
||||
if let Some(state) = store.states.get(&migration.name()) {
|
||||
match state {
|
||||
MigrationState::Completed => MigrationAdvice::Done,
|
||||
MigrationState::Failed => MigrationAdvice::Pending,
|
||||
_ => MigrationAdvice::Ignored,
|
||||
}
|
||||
} else {
|
||||
MigrationAdvice::Pending
|
||||
}
|
||||
} else {
|
||||
MigrationAdvice::Ignored
|
||||
}
|
||||
}
|
||||
|
||||
pub fn advice_unit<'a, T>(&self, unit: &Unit<'a, T>) -> MigrationAdvice
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
match unit {
|
||||
Unit::Single(item) => self.advice_migration(item.as_ref()),
|
||||
Unit::Batch(list) => {
|
||||
let mut advice = MigrationAdvice::Ignored;
|
||||
for item in list.iter() {
|
||||
let item_advice = self.advice_migration(item);
|
||||
if item_advice == MigrationAdvice::Pending {
|
||||
advice = MigrationAdvice::Pending;
|
||||
break;
|
||||
} else if item_advice == MigrationAdvice::Done {
|
||||
advice = MigrationAdvice::Done;
|
||||
}
|
||||
}
|
||||
advice
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_migration<'a, T>(&self, migration: &T) -> std::io::Result<()>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
println!("Running migration: {}", migration.name());
|
||||
let advice = self.advice_migration(migration);
|
||||
println!("Advice: {:?}", advice);
|
||||
if matches!(advice, MigrationAdvice::Ignored | MigrationAdvice::Done) {
|
||||
return Ok(());
|
||||
}
|
||||
let name = migration.name();
|
||||
let mut store = self.store.borrow_mut();
|
||||
match migration.migrate() {
|
||||
Ok(_) => {
|
||||
println!("Migration {} completed.", name);
|
||||
store.set_state(Cow::Owned(name.to_string()), MigrationState::Completed);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Migration {} failed: {}", name, e);
|
||||
store.set_state(Cow::Owned(name.to_string()), MigrationState::Failed);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_unit<'a, T>(&self, unit: &Unit<'a, T>) -> std::io::Result<()>
|
||||
where
|
||||
T: Clone + Migration<'a> + Send + Sync,
|
||||
{
|
||||
println!("Running unit: {}", unit.name());
|
||||
match unit {
|
||||
Unit::Single(item) => self.run_migration(item.as_ref()),
|
||||
Unit::Batch(list) => {
|
||||
for item in list.iter() {
|
||||
self.run_migration(item)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_units_up_to_version(&self, to_ver: &Version) -> std::io::Result<()> {
|
||||
println!("Running units up to version: {}", to_ver);
|
||||
let version = {
|
||||
let store = self.store.borrow();
|
||||
store.version.clone()
|
||||
};
|
||||
let units = units::UNITS
|
||||
.iter()
|
||||
.filter(|(ver, _)| **ver >= &version && **ver <= to_ver);
|
||||
for (_, unit) in units {
|
||||
self.run_unit(unit)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn run_upcoming_units(&self) -> std::io::Result<()> {
|
||||
println!("Running all upcoming units. It is supposed to run in Nightly build. If you see this message in Stable channel, report it in Github Issues Tracker please.");
|
||||
let version = {
|
||||
let store = self.store.borrow();
|
||||
store.version.clone()
|
||||
};
|
||||
let units = units::UNITS.iter().filter(|(ver, _)| **ver >= &version);
|
||||
|
||||
for (_, unit) in units {
|
||||
self.run_unit(unit)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
use super::{DynMigration, Migration, Unit};
|
||||
use once_cell::sync::Lazy;
|
||||
use semver::Version;
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
mod unit_160;
|
||||
|
||||
pub static UNITS: Lazy<HashMap<&'static Version, Unit<'static, DynMigration>>> = Lazy::new(|| {
|
||||
let mut units: HashMap<&'static Version, Unit<'static, DynMigration>> = HashMap::new();
|
||||
let unit = Unit::Batch(Cow::Borrowed(&unit_160::UNITS));
|
||||
units.insert(unit.version(), unit);
|
||||
units
|
||||
});
|
||||
|
||||
pub fn find_migration(name: &str) -> Option<Cow<'static, DynMigration<'static>>> {
|
||||
for unit in UNITS.values() {
|
||||
match unit {
|
||||
Unit::Batch(units) => {
|
||||
for unit in units.iter() {
|
||||
if unit.name() == name {
|
||||
return Some(Cow::Borrowed(unit));
|
||||
}
|
||||
}
|
||||
}
|
||||
Unit::Single(unit) => {
|
||||
if unit.name() == name {
|
||||
return Some(Cow::Borrowed(unit));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_migrations() -> Vec<Cow<'static, DynMigration<'static>>> {
|
||||
let mut migrations = Vec::new();
|
||||
for unit in UNITS.values() {
|
||||
match unit {
|
||||
Unit::Batch(units) => {
|
||||
for unit in units.iter() {
|
||||
migrations.push(Cow::Borrowed(unit));
|
||||
}
|
||||
}
|
||||
Unit::Single(unit) => {
|
||||
migrations.push(Cow::Borrowed(unit));
|
||||
}
|
||||
}
|
||||
}
|
||||
migrations
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{
|
||||
config::RUNTIME_CONFIG,
|
||||
core::migration::{DynMigration, Migration},
|
||||
};
|
||||
|
||||
pub static UNITS: Lazy<Vec<DynMigration>> = Lazy::new(|| vec![MigrateAppHomeDir.into()]);
|
||||
|
||||
pub static VERSION: Lazy<semver::Version> = Lazy::new(|| semver::Version::parse("1.6.0").unwrap());
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MigrateAppHomeDir;
|
||||
|
||||
impl<'a> Migration<'a> for MigrateAppHomeDir {
|
||||
fn name(&self) -> std::borrow::Cow<'a, str> {
|
||||
std::borrow::Cow::Borrowed("Split App Home Dir to Config and Data")
|
||||
}
|
||||
|
||||
fn version(&self) -> &'a semver::Version {
|
||||
&VERSION
|
||||
}
|
||||
|
||||
// Allow deprecated because we are moving deprecated files to new locations
|
||||
#[allow(deprecated)]
|
||||
fn migrate(&self) -> std::io::Result<()> {
|
||||
// create the app config and data dir
|
||||
println!("Creating app config and data dir");
|
||||
let app_config_dir = crate::utils::dirs::app_config_dir().unwrap();
|
||||
fs_extra::dir::create_all(crate::utils::dirs::app_config_dir().unwrap(), false)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
let app_data_dir = crate::utils::dirs::app_data_dir().unwrap();
|
||||
fs_extra::dir::create_all(crate::utils::dirs::app_data_dir().unwrap(), false)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
// move the config files to the new config dir
|
||||
let file_opts = fs_extra::file::CopyOptions::default().skip_exist(true);
|
||||
let dir_opts = fs_extra::dir::CopyOptions::default()
|
||||
.skip_exist(true)
|
||||
.content_only(true);
|
||||
let home_dir = crate::utils::dirs::app_home_dir().unwrap();
|
||||
// move clash runtime config
|
||||
let path = home_dir.join("clash-verge.yaml");
|
||||
if path.exists() {
|
||||
println!("Moving clash-verge.yaml to config dir");
|
||||
fs_extra::file::move_file(path, app_config_dir.join(RUNTIME_CONFIG), &file_opts)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
}
|
||||
// move clash guard overrides
|
||||
let path = home_dir.join("config.yaml");
|
||||
if path.exists() {
|
||||
println!("Moving config.yaml to config dir");
|
||||
fs_extra::file::move_file(
|
||||
path,
|
||||
crate::utils::dirs::clash_guard_overrides_path().unwrap(),
|
||||
&file_opts,
|
||||
)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
}
|
||||
// move nyanpasu config
|
||||
let path = home_dir.join("verge.yaml");
|
||||
if path.exists() {
|
||||
println!("Moving verge.yaml to config dir");
|
||||
fs_extra::file::move_file(
|
||||
path,
|
||||
crate::utils::dirs::app_config_dir()
|
||||
.unwrap()
|
||||
.join(crate::utils::dirs::NYANPASU_CONFIG),
|
||||
&file_opts,
|
||||
)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
}
|
||||
|
||||
// if app config dir is not set by registry, move the files and dirs to data dir
|
||||
if home_dir != app_config_dir {
|
||||
// move profiles.yaml
|
||||
let path = home_dir.join("profiles.yaml");
|
||||
if path.exists() {
|
||||
println!("Moving profiles.yaml to profiles dir");
|
||||
fs_extra::file::move_file(
|
||||
path,
|
||||
crate::utils::dirs::app_profiles_dir()
|
||||
.unwrap()
|
||||
.join("profiles.yaml"),
|
||||
&file_opts,
|
||||
)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
}
|
||||
// move profiles dir
|
||||
let path = home_dir.join("profiles");
|
||||
if path.exists() {
|
||||
println!("Moving profiles dir to profiles dir");
|
||||
fs_extra::dir::move_dir(
|
||||
path,
|
||||
crate::utils::dirs::app_profiles_dir().unwrap(),
|
||||
&dir_opts,
|
||||
)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
}
|
||||
// move other files and dirs to data dir
|
||||
println!("Moving other files and dirs to data dir");
|
||||
fs_extra::dir::move_dir(home_dir, app_data_dir, &dir_opts)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||
}
|
||||
println!("Migration completed");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
pub mod clash;
|
||||
pub mod commands;
|
||||
pub mod handle;
|
||||
pub mod hotkey;
|
||||
pub mod logger;
|
||||
@@ -12,3 +11,4 @@ pub mod updater;
|
||||
pub mod win_service;
|
||||
pub mod win_uwp;
|
||||
pub use self::clash::core::*;
|
||||
pub mod migration;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{cmds, config::Config, feat, utils, utils::resolve};
|
||||
use crate::{config::Config, feat, ipc, utils, utils::resolve};
|
||||
use anyhow::Result;
|
||||
use rust_i18n::t;
|
||||
use tauri::{
|
||||
@@ -153,10 +153,10 @@ impl Tray {
|
||||
"copy_env_cmd" => feat::copy_clash_env("cmd"),
|
||||
#[cfg(target_os = "windows")]
|
||||
"copy_env_ps" => feat::copy_clash_env("ps"),
|
||||
"open_app_config_dir" => crate::log_err!(cmds::open_app_config_dir()),
|
||||
"open_app_data_dir" => crate::log_err!(cmds::open_app_config_dir()),
|
||||
"open_core_dir" => crate::log_err!(cmds::open_core_dir()),
|
||||
"open_logs_dir" => crate::log_err!(cmds::open_logs_dir()),
|
||||
"open_app_config_dir" => crate::log_err!(ipc::open_app_config_dir()),
|
||||
"open_app_data_dir" => crate::log_err!(ipc::open_app_config_dir()),
|
||||
"open_core_dir" => crate::log_err!(ipc::open_core_dir()),
|
||||
"open_logs_dir" => crate::log_err!(ipc::open_logs_dir()),
|
||||
"restart_clash" => feat::restart_clash_core(),
|
||||
"restart_app" => utils::help::restart_application(app_handle),
|
||||
"quit" => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#![feature(auto_traits, negative_impls)]
|
||||
#![cfg_attr(
|
||||
all(not(debug_assertions), target_os = "windows"),
|
||||
windows_subsystem = "windows"
|
||||
@@ -17,11 +18,11 @@ mod consts;
|
||||
mod core;
|
||||
mod enhance;
|
||||
mod feat;
|
||||
mod ipc;
|
||||
mod utils;
|
||||
|
||||
use crate::{
|
||||
config::Config,
|
||||
core::{commands, handle::Handle},
|
||||
core::handle::Handle,
|
||||
utils::{init, resolve},
|
||||
};
|
||||
use tauri::{api, Manager, SystemTray};
|
||||
@@ -56,7 +57,7 @@ fn main() -> std::io::Result<()> {
|
||||
deadlock_detection();
|
||||
|
||||
// Parse commands
|
||||
commands::parse().unwrap();
|
||||
cmds::parse().unwrap();
|
||||
|
||||
// Should be in first place in order prevent single instance check block everything
|
||||
#[cfg(feature = "verge-dev")]
|
||||
@@ -75,6 +76,16 @@ fn main() -> std::io::Result<()> {
|
||||
};
|
||||
rust_i18n::set_locale(locale);
|
||||
|
||||
if let Err(e) = init::run_pending_migrations() {
|
||||
utils::dialog::panic_dialog(
|
||||
&format!(
|
||||
"Failed to finish migration event: {}\nYou can see the detailed information at migration.log in your local data dir.\nYou're supposed to submit it as the attachment of new issue.",
|
||||
e,
|
||||
)
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
crate::log_err!(init::init_config());
|
||||
|
||||
// Panic Hook to show a panic dialog and save logs
|
||||
@@ -129,63 +140,63 @@ fn main() -> std::io::Result<()> {
|
||||
.on_system_tray_event(core::tray::Tray::on_system_tray_event)
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// common
|
||||
cmds::get_sys_proxy,
|
||||
cmds::open_app_config_dir,
|
||||
cmds::open_app_data_dir,
|
||||
cmds::open_logs_dir,
|
||||
cmds::open_web_url,
|
||||
cmds::open_core_dir,
|
||||
ipc::get_sys_proxy,
|
||||
ipc::open_app_config_dir,
|
||||
ipc::open_app_data_dir,
|
||||
ipc::open_logs_dir,
|
||||
ipc::open_web_url,
|
||||
ipc::open_core_dir,
|
||||
// cmds::kill_sidecar,
|
||||
cmds::restart_sidecar,
|
||||
cmds::grant_permission,
|
||||
ipc::restart_sidecar,
|
||||
ipc::grant_permission,
|
||||
// clash
|
||||
cmds::get_clash_info,
|
||||
cmds::get_clash_logs,
|
||||
cmds::patch_clash_config,
|
||||
cmds::change_clash_core,
|
||||
cmds::get_runtime_config,
|
||||
cmds::get_runtime_yaml,
|
||||
cmds::get_runtime_exists,
|
||||
cmds::get_runtime_logs,
|
||||
cmds::clash_api_get_proxy_delay,
|
||||
cmds::uwp::invoke_uwp_tool,
|
||||
ipc::get_clash_info,
|
||||
ipc::get_clash_logs,
|
||||
ipc::patch_clash_config,
|
||||
ipc::change_clash_core,
|
||||
ipc::get_runtime_config,
|
||||
ipc::get_runtime_yaml,
|
||||
ipc::get_runtime_exists,
|
||||
ipc::get_runtime_logs,
|
||||
ipc::clash_api_get_proxy_delay,
|
||||
ipc::uwp::invoke_uwp_tool,
|
||||
// updater
|
||||
cmds::fetch_latest_core_versions,
|
||||
cmds::update_core,
|
||||
cmds::inspect_updater,
|
||||
cmds::get_core_version,
|
||||
ipc::fetch_latest_core_versions,
|
||||
ipc::update_core,
|
||||
ipc::inspect_updater,
|
||||
ipc::get_core_version,
|
||||
// utils
|
||||
cmds::collect_logs,
|
||||
ipc::collect_logs,
|
||||
// verge
|
||||
cmds::get_verge_config,
|
||||
cmds::patch_verge_config,
|
||||
ipc::get_verge_config,
|
||||
ipc::patch_verge_config,
|
||||
// cmds::update_hotkeys,
|
||||
// profile
|
||||
cmds::get_profiles,
|
||||
cmds::enhance_profiles,
|
||||
cmds::patch_profiles_config,
|
||||
cmds::view_profile,
|
||||
cmds::patch_profile,
|
||||
cmds::create_profile,
|
||||
cmds::import_profile,
|
||||
cmds::reorder_profile,
|
||||
cmds::update_profile,
|
||||
cmds::delete_profile,
|
||||
cmds::read_profile_file,
|
||||
cmds::save_profile_file,
|
||||
cmds::save_window_size_state,
|
||||
cmds::get_custom_app_dir,
|
||||
cmds::set_custom_app_dir,
|
||||
ipc::get_profiles,
|
||||
ipc::enhance_profiles,
|
||||
ipc::patch_profiles_config,
|
||||
ipc::view_profile,
|
||||
ipc::patch_profile,
|
||||
ipc::create_profile,
|
||||
ipc::import_profile,
|
||||
ipc::reorder_profile,
|
||||
ipc::update_profile,
|
||||
ipc::delete_profile,
|
||||
ipc::read_profile_file,
|
||||
ipc::save_profile_file,
|
||||
ipc::save_window_size_state,
|
||||
ipc::get_custom_app_dir,
|
||||
ipc::set_custom_app_dir,
|
||||
// service mode
|
||||
cmds::service::check_service,
|
||||
cmds::service::install_service,
|
||||
cmds::service::uninstall_service,
|
||||
cmds::is_portable,
|
||||
cmds::get_proxies,
|
||||
cmds::select_proxy,
|
||||
cmds::update_proxy_provider,
|
||||
cmds::restart_application,
|
||||
cmds::collect_envs,
|
||||
ipc::service::check_service,
|
||||
ipc::service::install_service,
|
||||
ipc::service::uninstall_service,
|
||||
ipc::is_portable,
|
||||
ipc::get_proxies,
|
||||
ipc::select_proxy,
|
||||
ipc::update_proxy_provider,
|
||||
ipc::restart_application,
|
||||
ipc::collect_envs,
|
||||
]);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::core::handle;
|
||||
use anyhow::Result;
|
||||
use nyanpasu_utils::dirs::{suggest_config_dir, suggest_data_dir};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{borrow::Cow, path::PathBuf};
|
||||
use std::{borrow::Cow, fs, path::PathBuf};
|
||||
use tauri::{
|
||||
api::path::{home_dir, resource_dir},
|
||||
Env,
|
||||
@@ -30,10 +30,10 @@ pub static APP_DIR_PLACEHOLDER: Lazy<Cow<'static, str>> = Lazy::new(|| {
|
||||
}
|
||||
});
|
||||
|
||||
static CLASH_CFG_GUARD_OVERRIDES: &str = "clash-guard-overrides.yaml";
|
||||
static NYANPASU_CONFIG: &str = "nyanpasu-config.yaml";
|
||||
static PROFILE_YAML: &str = "profiles.yaml";
|
||||
static STORAGE_DB: &str = "storage.db";
|
||||
pub const CLASH_CFG_GUARD_OVERRIDES: &str = "clash-guard-overrides.yaml";
|
||||
pub const NYANPASU_CONFIG: &str = "nyanpasu-config.yaml";
|
||||
pub const PROFILE_YAML: &str = "profiles.yaml";
|
||||
pub const STORAGE_DB: &str = "storage.db";
|
||||
|
||||
/// portable flag
|
||||
#[allow(unused)]
|
||||
@@ -90,6 +90,12 @@ pub fn app_config_dir() -> Result<PathBuf> {
|
||||
}
|
||||
suggest_config_dir(&APP_DIR_PLACEHOLDER)
|
||||
.ok_or(anyhow::anyhow!("failed to get the app config dir"))
|
||||
.and_then(|dir| {
|
||||
if !dir.exists() {
|
||||
fs::create_dir_all(&dir)?;
|
||||
}
|
||||
Ok(dir)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn app_data_dir() -> Result<PathBuf> {
|
||||
@@ -103,10 +109,25 @@ pub fn app_data_dir() -> Result<PathBuf> {
|
||||
let app_dir = app_exe
|
||||
.parent()
|
||||
.ok_or(anyhow::anyhow!("failed to check the old portable app dir"))?;
|
||||
return Ok(PathBuf::from(app_dir).join(".data").join(PREVIOUS_APP_NAME));
|
||||
|
||||
let data_dir = PathBuf::from(app_dir).join(".data").join(PREVIOUS_APP_NAME);
|
||||
|
||||
if !data_dir.exists() {
|
||||
fs::create_dir_all(&data_dir)?;
|
||||
}
|
||||
|
||||
return Ok(data_dir);
|
||||
}
|
||||
}
|
||||
suggest_data_dir(&APP_DIR_PLACEHOLDER).ok_or(anyhow::anyhow!("failed to get the app data dir"))
|
||||
|
||||
suggest_data_dir(&APP_DIR_PLACEHOLDER)
|
||||
.ok_or(anyhow::anyhow!("failed to get the app data dir"))
|
||||
.and_then(|dir| {
|
||||
if !dir.exists() {
|
||||
fs::create_dir_all(&dir)?;
|
||||
}
|
||||
Ok(dir)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn old_app_home_dir() -> Result<PathBuf> {
|
||||
|
||||
@@ -2,15 +2,103 @@ use crate::{
|
||||
config::*,
|
||||
utils::{dialog::migrate_dialog, dirs, help},
|
||||
};
|
||||
use anyhow::{Context, Result};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use fs_extra::dir::CopyOptions;
|
||||
#[cfg(windows)]
|
||||
use runas::Command as RunasCommand;
|
||||
use rust_i18n::t;
|
||||
use std::{fs, path::PathBuf};
|
||||
use std::{
|
||||
fs,
|
||||
io::{BufReader, Write},
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
};
|
||||
use tauri::utils::platform::current_exe;
|
||||
|
||||
mod logging;
|
||||
pub use logging::refresh_logger;
|
||||
|
||||
pub fn run_pending_migrations() -> Result<()> {
|
||||
let current_exe = current_exe()?;
|
||||
let current_exe = dunce::canonicalize(current_exe)?;
|
||||
let file = std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(crate::utils::dirs::app_data_dir()?.join("migration.log"))?;
|
||||
let file = Arc::new(parking_lot::Mutex::new(file));
|
||||
let (stdout_reader, stdout_writer) = os_pipe::pipe()?;
|
||||
let (stderr_reader, stderr_writer) = os_pipe::pipe()?;
|
||||
let errs = Arc::new(parking_lot::Mutex::new(String::new()));
|
||||
let guard = Arc::new(parking_lot::RwLock::new(()));
|
||||
let mut child = std::process::Command::new(current_exe)
|
||||
.arg("migrate")
|
||||
.stderr(stderr_writer)
|
||||
.stdout(stdout_writer)
|
||||
.spawn()?;
|
||||
let file_ = file.clone();
|
||||
let guard_ = guard.clone();
|
||||
let errs_ = errs.clone();
|
||||
std::thread::spawn(move || {
|
||||
let _l = guard_.read();
|
||||
let mut reader = BufReader::new(stdout_reader);
|
||||
let mut buf = Vec::new();
|
||||
loop {
|
||||
buf.clear();
|
||||
match nyanpasu_utils::io::read_line(&mut reader, &mut buf) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
let mut file = file_.lock();
|
||||
let _ = file.write_all(&buf);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("failed to read stdout: {:?}", e);
|
||||
let mut errs = errs_.lock();
|
||||
errs.push_str(&format!("failed to read stdout: {:?}\n", e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let errs_ = errs.clone();
|
||||
let guard_ = guard.clone();
|
||||
std::thread::spawn(move || {
|
||||
let _l = guard_.read();
|
||||
let mut reader = BufReader::new(stderr_reader);
|
||||
let mut buf = Vec::new();
|
||||
loop {
|
||||
buf.clear();
|
||||
match nyanpasu_utils::io::read_line(&mut reader, &mut buf) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
let mut file = file.lock();
|
||||
let _ = file.write_all(&buf);
|
||||
let mut errs = errs_.lock();
|
||||
errs.push_str(unsafe { std::str::from_utf8_unchecked(&buf) });
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("failed to read stderr: {:?}", e);
|
||||
let mut errs = errs_.lock();
|
||||
errs.push_str(&format!("failed to read stderr: {:?}\n", e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let result = child.wait();
|
||||
let _l = guard.write(); // Just for waiting the thread read all the output
|
||||
let err = errs.lock();
|
||||
result
|
||||
.map_err(|e| anyhow!("Failed to wait for child: {:?}, errs: {}", e, err))
|
||||
.and_then(|status| {
|
||||
if !status.success() {
|
||||
Err(anyhow!("child process failed: {:?}, err: {}", status, err))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Initialize all the config files
|
||||
/// before tauri setup
|
||||
pub fn init_config() -> Result<()> {
|
||||
|
||||
@@ -144,8 +144,12 @@ export const uninstallService = async () => {
|
||||
return await invoke<void>("uninstall_service");
|
||||
};
|
||||
|
||||
export const openAppDir = async () => {
|
||||
return await invoke<void>("open_app_dir");
|
||||
export const openAppConfigDir = async () => {
|
||||
return await invoke<void>("open_app_config_dir");
|
||||
};
|
||||
|
||||
export const openAppDataDir = async () => {
|
||||
return await invoke<void>("open_app_data_dir");
|
||||
};
|
||||
|
||||
export const openCoreDir = async () => {
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
"@generouted/react-router": "1.19.6",
|
||||
"@juggle/resize-observer": "3.4.0",
|
||||
"@material/material-color-utilities": "0.3.0",
|
||||
"@mui/icons-material": "5.16.4",
|
||||
"@mui/lab": "5.0.0-alpha.172",
|
||||
"@mui/material": "5.16.4",
|
||||
"@mui/icons-material": "5.16.5",
|
||||
"@mui/lab": "5.0.0-alpha.173",
|
||||
"@mui/material": "5.16.5",
|
||||
"@nyanpasu/interface": "workspace:^",
|
||||
"@nyanpasu/ui": "workspace:^",
|
||||
"@tauri-apps/api": "1.6.0",
|
||||
@@ -43,7 +43,7 @@
|
||||
"react-router-dom": "6.25.1",
|
||||
"react-split-grid": "1.0.4",
|
||||
"swr": "2.2.5",
|
||||
"virtua": "0.33.3"
|
||||
"virtua": "0.33.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@emotion/babel-plugin": "11.12.0",
|
||||
@@ -58,9 +58,9 @@
|
||||
"sass": "1.77.8",
|
||||
"shiki": "1.11.1",
|
||||
"tailwindcss-textshadow": "2.1.3",
|
||||
"vite": "5.3.4",
|
||||
"vite": "5.3.5",
|
||||
"vite-plugin-monaco-editor": "1.1.3",
|
||||
"vite-plugin-sass-dts": "1.3.24",
|
||||
"vite-plugin-sass-dts": "1.3.25",
|
||||
"vite-plugin-svgr": "4.2.0",
|
||||
"vite-tsconfig-paths": "4.3.2"
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import { classNames } from "@/utils";
|
||||
import { Bolt } from "@mui/icons-material";
|
||||
import { CircularProgress } from "@mui/material";
|
||||
import clsx from "clsx";
|
||||
import { memo, useState } from "react";
|
||||
import FeatureChip from "./feature-chip";
|
||||
import { getColorForDelay } from "./utils";
|
||||
import { classNames } from "@/utils";
|
||||
import { CircularProgress } from "@mui/material";
|
||||
|
||||
export const DelayChip = memo(function DelayChip({
|
||||
className,
|
||||
delay,
|
||||
onClick,
|
||||
}: {
|
||||
className?: string;
|
||||
delay: number;
|
||||
onClick: () => Promise<void>;
|
||||
}) {
|
||||
@@ -25,6 +29,7 @@ export const DelayChip = memo(function DelayChip({
|
||||
|
||||
return (
|
||||
<FeatureChip
|
||||
className={clsx(className, loading && "!visible")}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
color: getColorForDelay(delay),
|
||||
@@ -33,11 +38,17 @@ export const DelayChip = memo(function DelayChip({
|
||||
<>
|
||||
<span
|
||||
className={classNames(
|
||||
"transition-opacity",
|
||||
"transition-opacity flex items-center px-[1px]",
|
||||
loading ? "opacity-0" : "opacity-1",
|
||||
)}
|
||||
>
|
||||
{delay ? `${delay} ms` : "timeout"}
|
||||
{delay === -1 ? (
|
||||
<Bolt className="scale-[0.6]" />
|
||||
) : !!delay && delay < 10000 ? (
|
||||
`${delay} ms`
|
||||
) : (
|
||||
"timeout"
|
||||
)}
|
||||
</span>
|
||||
|
||||
<CircularProgress
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.Card {
|
||||
&.NoDelay {
|
||||
.DelayChip {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.DelayChip {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
declare const classNames: {
|
||||
readonly Card: "Card";
|
||||
readonly NoDelay: "NoDelay";
|
||||
readonly DelayChip: "DelayChip";
|
||||
};
|
||||
export default classNames;
|
||||
@@ -1,10 +1,13 @@
|
||||
import Box from "@mui/material/Box";
|
||||
import { Clash } from "@nyanpasu/interface";
|
||||
import { CSSProperties, memo, useMemo } from "react";
|
||||
import { filterDelay } from "./utils";
|
||||
import { PaperSwitchButton } from "../setting/modules/system-proxy";
|
||||
import Box from "@mui/material/Box";
|
||||
import FeatureChip from "./feature-chip";
|
||||
import DelayChip from "./delay-chip";
|
||||
import FeatureChip from "./feature-chip";
|
||||
import { filterDelay } from "./utils";
|
||||
|
||||
import clsx from "clsx";
|
||||
import styles from "./node-card.module.scss";
|
||||
|
||||
export const NodeCard = memo(function NodeCard({
|
||||
node,
|
||||
@@ -30,13 +33,18 @@ export const NodeCard = memo(function NodeCard({
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
style={style}
|
||||
className={clsx(styles.Card, delay === -1 && styles.NoDelay)}
|
||||
>
|
||||
<Box width="100%" display="flex" gap={0.5}>
|
||||
<FeatureChip label={node.type} />
|
||||
|
||||
{node.udp && <FeatureChip label="UDP" />}
|
||||
|
||||
<DelayChip delay={delay} onClick={onClickDelay} />
|
||||
<DelayChip
|
||||
className={styles.DelayChip}
|
||||
delay={delay}
|
||||
onClick={onClickDelay}
|
||||
/>
|
||||
</Box>
|
||||
</PaperSwitchButton>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ export type History = Clash.Proxy["history"];
|
||||
|
||||
export const filterDelay = (history?: History): number => {
|
||||
if (!history || history.length == 0) {
|
||||
return 0;
|
||||
return -1;
|
||||
} else {
|
||||
return history[history.length - 1].delay;
|
||||
}
|
||||
@@ -15,7 +15,8 @@ export const getColorForDelay = (delay: number): string => {
|
||||
const { palette } = useTheme();
|
||||
|
||||
const delayColorMapping: { [key: string]: string } = {
|
||||
"0": palette.error.main,
|
||||
"-1": palette.text.primary,
|
||||
"0": palette.text.secondary,
|
||||
"1": palette.text.secondary,
|
||||
"100": palette.success.main,
|
||||
"500": palette.warning.main,
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { useMessage } from "@/hooks/use-notification";
|
||||
import { sleep } from "@/utils";
|
||||
import Grid from "@mui/material/Unstable_Grid2";
|
||||
import {
|
||||
collectLogs,
|
||||
openAppDir,
|
||||
openAppConfigDir,
|
||||
openAppDataDir,
|
||||
openCoreDir,
|
||||
openLogsDir,
|
||||
restartApplication,
|
||||
setCustomAppDir,
|
||||
useNyanpasu,
|
||||
} from "@nyanpasu/interface";
|
||||
import { BaseCard } from "@nyanpasu/ui";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Grid from "@mui/material/Unstable_Grid2";
|
||||
import { PaperButton } from "./modules/nyanpasu-path";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { open } from "@tauri-apps/api/dialog";
|
||||
import { useMessage } from "@/hooks/use-notification";
|
||||
import { sleep } from "@/utils";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { PaperButton } from "./modules/nyanpasu-path";
|
||||
|
||||
export const SettingNyanpasuPath = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -60,7 +60,8 @@ export const SettingNyanpasuPath = () => {
|
||||
});
|
||||
|
||||
const gridLists = [
|
||||
{ label: t("Open App Dir"), onClick: openAppDir },
|
||||
{ label: t("Open Config Dir"), onClick: openAppConfigDir },
|
||||
{ label: t("Open Data Dir"), onClick: openAppDataDir },
|
||||
{ label: t("Migration App Path"), onClick: migrateAppPath },
|
||||
{ label: t("Open Core Dir"), onClick: openCoreDir },
|
||||
{ label: t("Open Logs Dir"), onClick: openLogsDir },
|
||||
|
||||
@@ -98,7 +98,8 @@
|
||||
"Page Transition Animation Transparent": "Transparent",
|
||||
"Page Transition Animation None": "None",
|
||||
"Language": "Language",
|
||||
"Open App Dir": "Open App Dir",
|
||||
"Open Config Dir": "Open Config Dir",
|
||||
"Open Data Dir": "Open Data Dir",
|
||||
"Open Core Dir": "Open Core Dir",
|
||||
"Open Logs Dir": "Open Logs Dir",
|
||||
"Auto Check Updates": "Auto Check Updates",
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
"Page Transition Animation Transparent": "Прозрачность",
|
||||
"Page Transition Animation None": "Нет",
|
||||
"Language": "Язык",
|
||||
"Open App Dir": "Открыть папку приложения",
|
||||
"Open Config Dir": "Открыть папку конфигурации",
|
||||
"Open Data Dir": "Открыть папку данных",
|
||||
"Open Core Dir": "Открыть папку ядра",
|
||||
"Open Logs Dir": "Открыть папку логов",
|
||||
"Nyanpasu Version": "Версия Nyanpasu",
|
||||
|
||||
@@ -100,7 +100,8 @@
|
||||
"Page Transition Animation Transparent": "透明",
|
||||
"Page Transition Animation None": "无",
|
||||
"Language": "语言设置",
|
||||
"Open App Dir": "应用目录",
|
||||
"Open Config Dir": "配置目录",
|
||||
"Open Data Dir": "数据目录",
|
||||
"Open Core Dir": "内核目录",
|
||||
"Open Logs Dir": "日志目录",
|
||||
"Auto Check Updates": "自动检查更新",
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"module": "index.ts",
|
||||
"dependencies": {
|
||||
"@material/material-color-utilities": "0.3.0",
|
||||
"@mui/icons-material": "5.16.4",
|
||||
"@mui/lab": "5.0.0-alpha.172",
|
||||
"@mui/material": "5.16.4",
|
||||
"@mui/icons-material": "5.16.5",
|
||||
"@mui/lab": "5.0.0-alpha.173",
|
||||
"@mui/material": "5.16.5",
|
||||
"@radix-ui/react-dialog": "1.1.1",
|
||||
"@tauri-apps/api": "1.6.0",
|
||||
"@types/d3": "7.4.3",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.18.6",
|
||||
"mihomo_alpha": "alpha-4b9fdac",
|
||||
"mihomo_alpha": "alpha-cc7823d",
|
||||
"clash_rs": "v0.1.20",
|
||||
"clash_premium": "2023-09-05-gdcc8d87"
|
||||
},
|
||||
@@ -36,5 +36,5 @@
|
||||
"darwin-x64": "clash-darwin-amd64-n{}.gz"
|
||||
}
|
||||
},
|
||||
"updated_at": "2024-07-23T22:20:23.982Z"
|
||||
"updated_at": "2024-07-24T22:20:12.911Z"
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"license": "GPL-3.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "run-p web:devtools tauri:dev",
|
||||
"dev:diff": "run-p web:devtools tauri:diff",
|
||||
"dev": "run-p -r web:devtools tauri:dev",
|
||||
"dev:diff": "run-p -r web:devtools tauri:diff",
|
||||
"build": "tauri build -c ./backend/tauri/tauri.conf.json",
|
||||
"build:nightly": "tauri build -f nightly -c ./backend/tauri/tauri.nightly.conf.json",
|
||||
"tauri": "tauri",
|
||||
@@ -91,7 +91,7 @@
|
||||
"eslint-plugin-react": "7.34.3",
|
||||
"lint-staged": "15.2.7",
|
||||
"npm-run-all2": "6.2.2",
|
||||
"postcss": "8.4.39",
|
||||
"postcss": "8.4.40",
|
||||
"postcss-html": "1.7.0",
|
||||
"postcss-import": "16.1.0",
|
||||
"postcss-scss": "4.0.9",
|
||||
@@ -105,7 +105,7 @@
|
||||
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
||||
"stylelint-order": "6.0.4",
|
||||
"stylelint-scss": "6.4.1",
|
||||
"tailwindcss": "3.4.6",
|
||||
"tailwindcss": "3.4.7",
|
||||
"tsx": "4.16.2",
|
||||
"typescript": "5.5.4"
|
||||
},
|
||||
|
||||
Generated
+149
-267
@@ -42,7 +42,7 @@ importers:
|
||||
version: 20.14.12
|
||||
autoprefixer:
|
||||
specifier: 10.4.19
|
||||
version: 10.4.19(postcss@8.4.39)
|
||||
version: 10.4.19(postcss@8.4.40)
|
||||
conventional-changelog-conventionalcommits:
|
||||
specifier: 8.0.0
|
||||
version: 8.0.0
|
||||
@@ -89,17 +89,17 @@ importers:
|
||||
specifier: 6.2.2
|
||||
version: 6.2.2
|
||||
postcss:
|
||||
specifier: 8.4.39
|
||||
version: 8.4.39
|
||||
specifier: 8.4.40
|
||||
version: 8.4.40
|
||||
postcss-html:
|
||||
specifier: 1.7.0
|
||||
version: 1.7.0
|
||||
postcss-import:
|
||||
specifier: 16.1.0
|
||||
version: 16.1.0(postcss@8.4.39)
|
||||
version: 16.1.0(postcss@8.4.40)
|
||||
postcss-scss:
|
||||
specifier: 4.0.9
|
||||
version: 4.0.9(postcss@8.4.39)
|
||||
version: 4.0.9(postcss@8.4.40)
|
||||
prettier:
|
||||
specifier: 3.3.2
|
||||
version: 3.3.2
|
||||
@@ -131,8 +131,8 @@ importers:
|
||||
specifier: 6.4.1
|
||||
version: 6.4.1(stylelint@16.7.0(typescript@5.5.4))
|
||||
tailwindcss:
|
||||
specifier: 3.4.6
|
||||
version: 3.4.6
|
||||
specifier: 3.4.7
|
||||
version: 3.4.7
|
||||
tsx:
|
||||
specifier: 4.16.2
|
||||
version: 4.16.2
|
||||
@@ -178,7 +178,7 @@ importers:
|
||||
version: 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@generouted/react-router':
|
||||
specifier: 1.19.6
|
||||
version: 1.19.6(react-router-dom@6.25.1(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
version: 1.19.6(react-router-dom@6.25.1(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
'@juggle/resize-observer':
|
||||
specifier: 3.4.0
|
||||
version: 3.4.0
|
||||
@@ -186,14 +186,14 @@ importers:
|
||||
specifier: 0.3.0
|
||||
version: 0.3.0
|
||||
'@mui/icons-material':
|
||||
specifier: 5.16.4
|
||||
version: 5.16.4(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
specifier: 5.16.5
|
||||
version: 5.16.5(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/lab':
|
||||
specifier: 5.0.0-alpha.172
|
||||
version: 5.0.0-alpha.172(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
specifier: 5.0.0-alpha.173
|
||||
version: 5.0.0-alpha.173(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material':
|
||||
specifier: 5.16.4
|
||||
version: 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
specifier: 5.16.5
|
||||
version: 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@nyanpasu/interface':
|
||||
specifier: workspace:^
|
||||
version: link:../interface
|
||||
@@ -229,13 +229,13 @@ importers:
|
||||
version: 2.9.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
material-react-table:
|
||||
specifier: 2.13.0
|
||||
version: 2.13.0(4ynhcepbjgqbvzf6cwzaqs6d4a)
|
||||
version: 2.13.0(ddsnezj33ahd2557amn3vjv3cu)
|
||||
monaco-editor:
|
||||
specifier: 0.50.0
|
||||
version: 0.50.0
|
||||
mui-color-input:
|
||||
specifier: 3.0.0
|
||||
version: 3.0.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
version: 3.0.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
react:
|
||||
specifier: npm:react@rc
|
||||
version: 19.0.0-rc-df783f9ea1-20240708
|
||||
@@ -250,7 +250,7 @@ importers:
|
||||
version: 1.6.5(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
react-hook-form-mui:
|
||||
specifier: 7.0.1
|
||||
version: 7.0.1(kat3osdwizfjcujladrzqoubpe)
|
||||
version: 7.0.1(csmbkkiu4natw25gzsxr24gk6i)
|
||||
react-i18next:
|
||||
specifier: 15.0.0
|
||||
version: 15.0.0(i18next@23.12.2)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
@@ -267,8 +267,8 @@ importers:
|
||||
specifier: 2.2.5
|
||||
version: 2.2.5(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
virtua:
|
||||
specifier: 0.33.3
|
||||
version: 0.33.3(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
specifier: 0.33.4
|
||||
version: 0.33.4(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
devDependencies:
|
||||
'@emotion/babel-plugin':
|
||||
specifier: 11.12.0
|
||||
@@ -290,10 +290,10 @@ importers:
|
||||
version: 7.16.0(eslint@8.57.0)(typescript@5.5.4)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 4.3.1
|
||||
version: 4.3.1(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
version: 4.3.1(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
'@vitejs/plugin-react-swc':
|
||||
specifier: 3.7.0
|
||||
version: 3.7.0(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
version: 3.7.0(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
clsx:
|
||||
specifier: 2.1.1
|
||||
version: 2.1.1
|
||||
@@ -307,20 +307,20 @@ importers:
|
||||
specifier: 2.1.3
|
||||
version: 2.1.3
|
||||
vite:
|
||||
specifier: 5.3.4
|
||||
version: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
specifier: 5.3.5
|
||||
version: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite-plugin-monaco-editor:
|
||||
specifier: npm:vite-plugin-monaco-editor-new@1.1.3
|
||||
version: vite-plugin-monaco-editor-new@1.1.3(monaco-editor@0.50.0)
|
||||
vite-plugin-sass-dts:
|
||||
specifier: 1.3.24
|
||||
version: 1.3.24(postcss@8.4.39)(prettier@3.3.2)(sass@1.77.8)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
specifier: 1.3.25
|
||||
version: 1.3.25(postcss@8.4.40)(prettier@3.3.2)(sass@1.77.8)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
vite-plugin-svgr:
|
||||
specifier: 4.2.0
|
||||
version: 4.2.0(rollup@4.17.2)(typescript@5.5.4)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
version: 4.2.0(rollup@4.17.2)(typescript@5.5.4)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
vite-tsconfig-paths:
|
||||
specifier: 4.3.2
|
||||
version: 4.3.2(typescript@5.5.4)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
version: 4.3.2(typescript@5.5.4)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
|
||||
frontend/ui:
|
||||
dependencies:
|
||||
@@ -328,14 +328,14 @@ importers:
|
||||
specifier: 0.3.0
|
||||
version: 0.3.0
|
||||
'@mui/icons-material':
|
||||
specifier: 5.16.4
|
||||
version: 5.16.4(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
specifier: 5.16.5
|
||||
version: 5.16.5(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/lab':
|
||||
specifier: 5.0.0-alpha.172
|
||||
version: 5.0.0-alpha.172(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
specifier: 5.0.0-alpha.173
|
||||
version: 5.0.0-alpha.173(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material':
|
||||
specifier: 5.16.4
|
||||
version: 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
specifier: 5.16.5
|
||||
version: 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: 1.1.1
|
||||
version: 1.1.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
@@ -550,10 +550,6 @@ packages:
|
||||
resolution: {integrity: sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/runtime@7.24.7':
|
||||
resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/runtime@7.24.8':
|
||||
resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -701,9 +697,6 @@ packages:
|
||||
'@emotion/babel-plugin@11.12.0':
|
||||
resolution: {integrity: sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==}
|
||||
|
||||
'@emotion/cache@11.12.0':
|
||||
resolution: {integrity: sha512-VFo/F1PthkxHwWDCcXkidyXw70eAkdiNiCzthMI2rRQjFiTvmXt8UDlv/VE1DTsd4CIEY2wQf5AnL2QiPgphlw==}
|
||||
|
||||
'@emotion/cache@11.13.0':
|
||||
resolution: {integrity: sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==}
|
||||
|
||||
@@ -731,9 +724,6 @@ packages:
|
||||
'@emotion/serialize@1.3.0':
|
||||
resolution: {integrity: sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==}
|
||||
|
||||
'@emotion/sheet@1.3.0':
|
||||
resolution: {integrity: sha512-vOPwbKw8fj/oSEa7CWqiKCvLZ1AeLIAApmboGP34xUyUjXalFyf+tMtgMDqP7VMevLPhUa+YWJS46cQUA+tr9A==}
|
||||
|
||||
'@emotion/sheet@1.4.0':
|
||||
resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==}
|
||||
|
||||
@@ -1139,11 +1129,11 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/core-downloads-tracker@5.16.4':
|
||||
resolution: {integrity: sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==}
|
||||
'@mui/core-downloads-tracker@5.16.5':
|
||||
resolution: {integrity: sha512-ziFn1oPm6VjvHQcdGcAO+fXvOQEgieIj0BuSqcltFU+JXIxjPdVYNTdn2HU7/Ak5Gabk6k2u7+9PV7oZ6JT5sA==}
|
||||
|
||||
'@mui/icons-material@5.16.4':
|
||||
resolution: {integrity: sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==}
|
||||
'@mui/icons-material@5.16.5':
|
||||
resolution: {integrity: sha512-bn88xxU/J9UV0s6+eutq7o3TTOrOlbCX+KshFb8kxgIxJZZfYz3JbAXVMivvoMF4Md6jCVUzM9HEkf4Ajab4tw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@mui/material': ^5.0.0
|
||||
@@ -1153,8 +1143,8 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/lab@5.0.0-alpha.172':
|
||||
resolution: {integrity: sha512-stpa3WTsDE1HamFR4eeS6Bhxalm+u9FhzzNph/PrDMdWSRBHlJs2mqvZ6FEoO22O7MOCwNMqbXTkvEwsyEf0ew==}
|
||||
'@mui/lab@5.0.0-alpha.173':
|
||||
resolution: {integrity: sha512-Gt5zopIWwxDgGy/MXcp6GueD84xFFugFai4hYiXY0zowJpTVnIrTQCQXV004Q7rejJ7aaCntX9hpPJqCrioshA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.5.0
|
||||
@@ -1171,8 +1161,8 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/material@5.16.4':
|
||||
resolution: {integrity: sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==}
|
||||
'@mui/material@5.16.5':
|
||||
resolution: {integrity: sha512-eQrjjg4JeczXvh/+8yvJkxWIiKNHVptB/AqpsKfZBWp5mUD5U3VsjODMuUl1K2BSq0omV3CiO/mQmWSSMKSmaA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.5.0
|
||||
@@ -1188,8 +1178,8 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/private-theming@5.16.1':
|
||||
resolution: {integrity: sha512-2EGCKnAlq9vRIFj61jNWNXlKAxXp56577OVvsts7fAqRx+G1y6F+N7Q198SBaz8jYQeGKSz8ZMXK/M3FqjdEyw==}
|
||||
'@mui/private-theming@5.16.5':
|
||||
resolution: {integrity: sha512-CSLg0YkpDqg0aXOxtjo3oTMd3XWMxvNb5d0v4AYVqwOltU8q6GvnZjhWyCLjGSCrcgfwm6/VDjaKLPlR14wxIA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@types/react': npm:types-react@rc
|
||||
@@ -1198,29 +1188,6 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/private-theming@5.16.4':
|
||||
resolution: {integrity: sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@types/react': npm:types-react@rc
|
||||
react: npm:react@rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/styled-engine@5.16.1':
|
||||
resolution: {integrity: sha512-JwWUBaYR8HHCFefSeos0z6JoTbu0MnjAuNHu4QoDgPxl2EE70XH38CsKay66Iy0QkNWmGTRXVU2sVFgUOPL/Dw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.4.1
|
||||
'@emotion/styled': ^11.3.0
|
||||
react: npm:react@rc
|
||||
peerDependenciesMeta:
|
||||
'@emotion/react':
|
||||
optional: true
|
||||
'@emotion/styled':
|
||||
optional: true
|
||||
|
||||
'@mui/styled-engine@5.16.4':
|
||||
resolution: {integrity: sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -1234,24 +1201,8 @@ packages:
|
||||
'@emotion/styled':
|
||||
optional: true
|
||||
|
||||
'@mui/system@5.16.1':
|
||||
resolution: {integrity: sha512-VaFcClC+uhvIEzhzcNmh9FRBvrG9IPjsOokhj6U1HPZsFnLzHV7AD7dJcT6LxWoiIZj9Ej0GK+MGh/b8+BtSlQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.5.0
|
||||
'@emotion/styled': ^11.3.0
|
||||
'@types/react': npm:types-react@rc
|
||||
react: npm:react@rc
|
||||
peerDependenciesMeta:
|
||||
'@emotion/react':
|
||||
optional: true
|
||||
'@emotion/styled':
|
||||
optional: true
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/system@5.16.4':
|
||||
resolution: {integrity: sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==}
|
||||
'@mui/system@5.16.5':
|
||||
resolution: {integrity: sha512-uzIUGdrWddUx1HPxW4+B2o4vpgKyRxGe/8BxbfXVDPNPHX75c782TseoCnR/VyfnZJfqX87GcxDmnZEE1c031g==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.5.0
|
||||
@@ -1274,18 +1225,8 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/utils@5.16.1':
|
||||
resolution: {integrity: sha512-4UQzK46tAEYs2xZv79hRiIc3GxZScd00kGPDadNrGztAEZlmSaUY8cb9ITd2xCiTfzsx5AN6DH8aaQ8QEKJQeQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@types/react': npm:types-react@rc
|
||||
react: npm:react@rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@mui/utils@5.16.4':
|
||||
resolution: {integrity: sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==}
|
||||
'@mui/utils@5.16.5':
|
||||
resolution: {integrity: sha512-CwhcA9y44XwK7k2joL3Y29mRUnoBt+gOZZdGyw7YihbEwEErJYBtDwbZwVgH68zAljGe/b+Kd5bzfl63Gi3R2A==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@types/react': npm:types-react@rc
|
||||
@@ -4927,8 +4868,8 @@ packages:
|
||||
resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
postcss@8.4.39:
|
||||
resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
|
||||
postcss@8.4.40:
|
||||
resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
prelude-ls@1.2.1:
|
||||
@@ -5598,8 +5539,8 @@ packages:
|
||||
engines: {node: '>=8.9.0'}
|
||||
hasBin: true
|
||||
|
||||
tailwindcss@3.4.6:
|
||||
resolution: {integrity: sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==}
|
||||
tailwindcss@3.4.7:
|
||||
resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -5861,8 +5802,8 @@ packages:
|
||||
vfile@6.0.1:
|
||||
resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==}
|
||||
|
||||
virtua@0.33.3:
|
||||
resolution: {integrity: sha512-Zxr2hhmTHARMHdZjs5fvd17bHH2YJ1uZZGaw4SKmynDEXtHFzJn/pL9xYJeXWZ8UfXNIBbPvGlHGpruCRbLHIg==}
|
||||
virtua@0.33.4:
|
||||
resolution: {integrity: sha512-E5PjR2wxebizA0KDFmGnvpPCeRsbAmmJ/Yif+ZH4HPEylrFqIeBOsgNZqHjsMnu5WqfSgEMIq+Qu0WOIC+3UyA==}
|
||||
peerDependencies:
|
||||
react: npm:react@rc
|
||||
react-dom: npm:react-dom@rc
|
||||
@@ -5886,8 +5827,8 @@ packages:
|
||||
peerDependencies:
|
||||
monaco-editor: '>=0.45.0'
|
||||
|
||||
vite-plugin-sass-dts@1.3.24:
|
||||
resolution: {integrity: sha512-t6qxkC8seJJuYmlioKu2QFOJhJgIXwmAGbfOwmZ41QH1eqpqzgQkkXgWVLRf0DlO3FNMPn2y5bO9+R1N7LRgTA==}
|
||||
vite-plugin-sass-dts@1.3.25:
|
||||
resolution: {integrity: sha512-HJkblBpM/AWZuAJuR/GO1YIOlLGfk6sPFcD2kKE4wCpqsgIWXgKHn/d6jIpzKuF2so6oLVq7M4AfeXxD0Wfotw==}
|
||||
engines: {node: '>=20'}
|
||||
peerDependencies:
|
||||
postcss: ^8
|
||||
@@ -5908,8 +5849,8 @@ packages:
|
||||
vite:
|
||||
optional: true
|
||||
|
||||
vite@5.3.4:
|
||||
resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==}
|
||||
vite@5.3.5:
|
||||
resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -6212,10 +6153,6 @@ snapshots:
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
'@babel/runtime@7.24.7':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
'@babel/runtime@7.24.8':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
@@ -6432,14 +6369,6 @@ snapshots:
|
||||
source-map: 0.5.7
|
||||
stylis: 4.2.0
|
||||
|
||||
'@emotion/cache@11.12.0':
|
||||
dependencies:
|
||||
'@emotion/memoize': 0.9.0
|
||||
'@emotion/sheet': 1.3.0
|
||||
'@emotion/utils': 1.3.0
|
||||
'@emotion/weak-memoize': 0.4.0
|
||||
stylis: 4.2.0
|
||||
|
||||
'@emotion/cache@11.13.0':
|
||||
dependencies:
|
||||
'@emotion/memoize': 0.9.0
|
||||
@@ -6486,8 +6415,6 @@ snapshots:
|
||||
'@emotion/utils': 1.4.0
|
||||
csstype: 3.1.3
|
||||
|
||||
'@emotion/sheet@1.3.0': {}
|
||||
|
||||
'@emotion/sheet@1.4.0': {}
|
||||
|
||||
'@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
@@ -6700,13 +6627,13 @@ snapshots:
|
||||
postcss: 7.0.32
|
||||
purgecss: 2.3.0
|
||||
|
||||
'@generouted/react-router@1.19.6(react-router-dom@6.25.1(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))':
|
||||
'@generouted/react-router@1.19.6(react-router-dom@6.25.1(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))':
|
||||
dependencies:
|
||||
fast-glob: 3.3.2
|
||||
generouted: 1.19.6(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
generouted: 1.19.6(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
react-router-dom: 6.25.1(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
|
||||
'@humanwhocodes/config-array@0.11.14':
|
||||
dependencies:
|
||||
@@ -6755,7 +6682,7 @@ snapshots:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@floating-ui/react-dom': 2.0.9(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
'@mui/types': 7.2.15(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@popperjs/core': 2.11.8
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
@@ -6764,24 +6691,24 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/core-downloads-tracker@5.16.4': {}
|
||||
'@mui/core-downloads-tracker@5.16.5': {}
|
||||
|
||||
'@mui/icons-material@5.16.4(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/icons-material@5.16.5(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.7
|
||||
'@mui/material': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/material': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/lab@5.0.0-alpha.172(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/lab@5.0.0-alpha.173(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.7
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/base': 5.0.0-beta.40(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/system': 5.16.1(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/system': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/types': 7.2.15(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
@@ -6791,13 +6718,13 @@ snapshots:
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.7
|
||||
'@mui/core-downloads-tracker': 5.16.4
|
||||
'@mui/system': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/core-downloads-tracker': 5.16.5
|
||||
'@mui/system': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/types': 7.2.15(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@popperjs/core': 2.11.8
|
||||
'@types/react-transition-group': 4.4.10
|
||||
clsx: 2.1.1
|
||||
@@ -6812,39 +6739,19 @@ snapshots:
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/private-theming@5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/private-theming@5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/utils': 5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/private-theming@5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/utils': 5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/styled-engine@5.16.1(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@emotion/cache': 11.12.0
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
|
||||
'@mui/styled-engine@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@emotion/cache': 11.12.0
|
||||
'@emotion/cache': 11.13.0
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
@@ -6852,29 +6759,13 @@ snapshots:
|
||||
'@emotion/react': 11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
|
||||
'@mui/system@5.16.1(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/system@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/private-theming': 5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/styled-engine': 5.16.1(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
'@mui/types': 7.2.15(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/system@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/private-theming': 5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/private-theming': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/styled-engine': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
'@mui/types': 7.2.15(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
@@ -6888,19 +6779,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/utils@5.16.1(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@types/prop-types': 15.7.12
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
react-is: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/utils@5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/utils@5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/types': 7.2.15(types-react@19.0.0-rc.1)
|
||||
'@types/prop-types': 15.7.12
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
@@ -6909,13 +6791,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': types-react@19.0.0-rc.1
|
||||
|
||||
'@mui/x-date-pickers@7.9.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(dayjs@1.11.12)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
'@mui/x-date-pickers@7.9.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(dayjs@1.11.12)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
'@mui/base': 5.0.0-beta.40(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/system': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.4(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/system': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/utils': 5.16.5(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@types/react-transition-group': 4.4.10
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
@@ -7749,11 +7631,11 @@ snapshots:
|
||||
|
||||
'@types/postcss-modules-local-by-default@4.0.2':
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
'@types/postcss-modules-scope@3.0.4':
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
'@types/prop-types@15.7.12': {}
|
||||
|
||||
@@ -7857,21 +7739,21 @@ snapshots:
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@vitejs/plugin-react-swc@3.7.0(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))':
|
||||
'@vitejs/plugin-react-swc@3.7.0(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))':
|
||||
dependencies:
|
||||
'@swc/core': 1.6.1
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
transitivePeerDependencies:
|
||||
- '@swc/helpers'
|
||||
|
||||
'@vitejs/plugin-react@4.3.1(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))':
|
||||
'@vitejs/plugin-react@4.3.1(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0))':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.5
|
||||
'@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5)
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.14.2
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -8068,14 +7950,14 @@ snapshots:
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
autoprefixer@10.4.19(postcss@8.4.39):
|
||||
autoprefixer@10.4.19(postcss@8.4.40):
|
||||
dependencies:
|
||||
browserslist: 4.23.0
|
||||
caniuse-lite: 1.0.30001616
|
||||
fraction.js: 4.3.7
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.1
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
postcss-value-parser: 4.2.0
|
||||
|
||||
autoprefixer@9.8.8:
|
||||
@@ -9368,9 +9250,9 @@ snapshots:
|
||||
|
||||
functions-have-names@1.2.3: {}
|
||||
|
||||
generouted@1.19.6(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
generouted@1.19.6(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
dependencies:
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
|
||||
gensync@1.0.0-beta.2: {}
|
||||
|
||||
@@ -10107,13 +9989,13 @@ snapshots:
|
||||
escape-string-regexp: 4.0.0
|
||||
optional: true
|
||||
|
||||
material-react-table@2.13.0(4ynhcepbjgqbvzf6cwzaqs6d4a):
|
||||
material-react-table@2.13.0(ddsnezj33ahd2557amn3vjv3cu):
|
||||
dependencies:
|
||||
'@emotion/react': 11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/icons-material': 5.16.4(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(dayjs@1.11.12)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/icons-material': 5.16.5(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(dayjs@1.11.12)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@tanstack/match-sorter-utils': 8.15.1
|
||||
'@tanstack/react-table': 8.16.0(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
'@tanstack/react-virtual': 3.3.0(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
@@ -10401,12 +10283,12 @@ snapshots:
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
mui-color-input@3.0.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1):
|
||||
mui-color-input@3.0.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1):
|
||||
dependencies:
|
||||
'@ctrl/tinycolor': 4.1.0
|
||||
'@emotion/react': 11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@emotion/styled': 11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
react-dom: 19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
optionalDependencies:
|
||||
@@ -10697,19 +10579,19 @@ snapshots:
|
||||
dependencies:
|
||||
htmlparser2: 8.0.2
|
||||
js-tokens: 9.0.0
|
||||
postcss: 8.4.39
|
||||
postcss-safe-parser: 6.0.0(postcss@8.4.39)
|
||||
postcss: 8.4.40
|
||||
postcss-safe-parser: 6.0.0(postcss@8.4.40)
|
||||
|
||||
postcss-import@15.1.0(postcss@8.4.39):
|
||||
postcss-import@15.1.0(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
postcss-value-parser: 4.2.0
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.8
|
||||
|
||||
postcss-import@16.1.0(postcss@8.4.39):
|
||||
postcss-import@16.1.0(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
postcss-value-parser: 4.2.0
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.8
|
||||
@@ -10719,10 +10601,10 @@ snapshots:
|
||||
camelcase-css: 2.0.1
|
||||
postcss: 7.0.39
|
||||
|
||||
postcss-js@4.0.1(postcss@8.4.39):
|
||||
postcss-js@4.0.1(postcss@8.4.40):
|
||||
dependencies:
|
||||
camelcase-css: 2.0.1
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
postcss-load-config@3.1.4(postcss@8.4.38):
|
||||
dependencies:
|
||||
@@ -10731,12 +10613,12 @@ snapshots:
|
||||
optionalDependencies:
|
||||
postcss: 8.4.38
|
||||
|
||||
postcss-load-config@4.0.2(postcss@8.4.39):
|
||||
postcss-load-config@4.0.2(postcss@8.4.40):
|
||||
dependencies:
|
||||
lilconfig: 3.1.1
|
||||
yaml: 2.4.2
|
||||
optionalDependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
postcss-media-query-parser@0.2.3: {}
|
||||
|
||||
@@ -10761,24 +10643,24 @@ snapshots:
|
||||
postcss: 7.0.39
|
||||
postcss-selector-parser: 6.1.0
|
||||
|
||||
postcss-nested@6.0.1(postcss@8.4.39):
|
||||
postcss-nested@6.0.1(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
postcss-selector-parser: 6.1.0
|
||||
|
||||
postcss-resolve-nested-selector@0.1.1: {}
|
||||
|
||||
postcss-safe-parser@6.0.0(postcss@8.4.39):
|
||||
postcss-safe-parser@6.0.0(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
postcss-safe-parser@7.0.0(postcss@8.4.39):
|
||||
postcss-safe-parser@7.0.0(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
postcss-scss@4.0.9(postcss@8.4.39):
|
||||
postcss-scss@4.0.9(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
postcss-selector-parser@6.0.16:
|
||||
dependencies:
|
||||
@@ -10790,9 +10672,9 @@ snapshots:
|
||||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
postcss-sorting@8.0.2(postcss@8.4.39):
|
||||
postcss-sorting@8.0.2(postcss@8.4.40):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
|
||||
postcss-value-parser@3.3.1: {}
|
||||
|
||||
@@ -10821,7 +10703,7 @@ snapshots:
|
||||
picocolors: 1.0.1
|
||||
source-map-js: 1.2.0
|
||||
|
||||
postcss@8.4.39:
|
||||
postcss@8.4.40:
|
||||
dependencies:
|
||||
nanoid: 3.3.7
|
||||
picocolors: 1.0.1
|
||||
@@ -10924,14 +10806,14 @@ snapshots:
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
react-dom: 19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
|
||||
react-hook-form-mui@7.0.1(kat3osdwizfjcujladrzqoubpe):
|
||||
react-hook-form-mui@7.0.1(csmbkkiu4natw25gzsxr24gk6i):
|
||||
dependencies:
|
||||
'@mui/material': 5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/material': 5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
react-hook-form: 7.52.1(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
optionalDependencies:
|
||||
'@mui/icons-material': 5.16.4(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.4(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(dayjs@1.11.12)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/icons-material': 5.16.5(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@mui/material@5.16.5(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1))(dayjs@1.11.12)(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
|
||||
|
||||
react-hook-form@7.52.1(react@19.0.0-rc-df783f9ea1-20240708):
|
||||
dependencies:
|
||||
@@ -11442,8 +11324,8 @@ snapshots:
|
||||
|
||||
stylelint-order@6.0.4(stylelint@16.7.0(typescript@5.5.4)):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss-sorting: 8.0.2(postcss@8.4.39)
|
||||
postcss: 8.4.40
|
||||
postcss-sorting: 8.0.2(postcss@8.4.40)
|
||||
stylelint: 16.7.0(typescript@5.5.4)
|
||||
|
||||
stylelint-scss@6.4.1(stylelint@16.7.0(typescript@5.5.4)):
|
||||
@@ -11484,9 +11366,9 @@ snapshots:
|
||||
micromatch: 4.0.7
|
||||
normalize-path: 3.0.0
|
||||
picocolors: 1.0.1
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
postcss-resolve-nested-selector: 0.1.1
|
||||
postcss-safe-parser: 7.0.0(postcss@8.4.39)
|
||||
postcss-safe-parser: 7.0.0(postcss@8.4.40)
|
||||
postcss-selector-parser: 6.1.0
|
||||
postcss-value-parser: 4.2.0
|
||||
resolve-from: 5.0.0
|
||||
@@ -11601,7 +11483,7 @@ snapshots:
|
||||
reduce-css-calc: 2.1.8
|
||||
resolve: 1.22.8
|
||||
|
||||
tailwindcss@3.4.6:
|
||||
tailwindcss@3.4.7:
|
||||
dependencies:
|
||||
'@alloc/quick-lru': 5.2.0
|
||||
arg: 5.0.2
|
||||
@@ -11617,11 +11499,11 @@ snapshots:
|
||||
normalize-path: 3.0.0
|
||||
object-hash: 3.0.0
|
||||
picocolors: 1.0.1
|
||||
postcss: 8.4.39
|
||||
postcss-import: 15.1.0(postcss@8.4.39)
|
||||
postcss-js: 4.0.1(postcss@8.4.39)
|
||||
postcss-load-config: 4.0.2(postcss@8.4.39)
|
||||
postcss-nested: 6.0.1(postcss@8.4.39)
|
||||
postcss: 8.4.40
|
||||
postcss-import: 15.1.0(postcss@8.4.40)
|
||||
postcss-js: 4.0.1(postcss@8.4.40)
|
||||
postcss-load-config: 4.0.2(postcss@8.4.40)
|
||||
postcss-nested: 6.0.1(postcss@8.4.40)
|
||||
postcss-selector-parser: 6.1.0
|
||||
resolve: 1.22.8
|
||||
sucrase: 3.35.0
|
||||
@@ -11936,7 +11818,7 @@ snapshots:
|
||||
unist-util-stringify-position: 4.0.0
|
||||
vfile-message: 4.0.2
|
||||
|
||||
virtua@0.33.3(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708):
|
||||
virtua@0.33.4(react-dom@19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708))(react@19.0.0-rc-df783f9ea1-20240708):
|
||||
optionalDependencies:
|
||||
react: 19.0.0-rc-df783f9ea1-20240708
|
||||
react-dom: 19.0.0-rc-df783f9ea1-20240708(react@19.0.0-rc-df783f9ea1-20240708)
|
||||
@@ -11946,40 +11828,40 @@ snapshots:
|
||||
esbuild: 0.19.12
|
||||
monaco-editor: 0.50.0
|
||||
|
||||
vite-plugin-sass-dts@1.3.24(postcss@8.4.39)(prettier@3.3.2)(sass@1.77.8)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
vite-plugin-sass-dts@1.3.25(postcss@8.4.40)(prettier@3.3.2)(sass@1.77.8)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss-js: 4.0.1(postcss@8.4.39)
|
||||
postcss: 8.4.40
|
||||
postcss-js: 4.0.1(postcss@8.4.40)
|
||||
prettier: 3.3.2
|
||||
sass: 1.77.8
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
|
||||
vite-plugin-svgr@4.2.0(rollup@4.17.2)(typescript@5.5.4)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
vite-plugin-svgr@4.2.0(rollup@4.17.2)(typescript@5.5.4)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.0(rollup@4.17.2)
|
||||
'@svgr/core': 8.1.0(typescript@5.5.4)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.5.4))
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite-tsconfig-paths@4.3.2(typescript@5.5.4)(vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
vite-tsconfig-paths@4.3.2(typescript@5.5.4)(vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)):
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
globrex: 0.1.2
|
||||
tsconfck: 3.0.3(typescript@5.5.4)
|
||||
optionalDependencies:
|
||||
vite: 5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
vite: 5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite@5.3.4(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0):
|
||||
vite@5.3.5(@types/node@20.14.12)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.4.39
|
||||
postcss: 8.4.40
|
||||
rollup: 4.17.2
|
||||
optionalDependencies:
|
||||
'@types/node': 20.14.12
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
channel = "nightly"
|
||||
|
||||
@@ -39,7 +39,7 @@ const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
||||
const resourceFormats = [
|
||||
"x64-setup.exe",
|
||||
"x64_portable.zip",
|
||||
"amd64.AppImage",
|
||||
"x86_64.rpm",
|
||||
"amd64.deb",
|
||||
"x64.dmg",
|
||||
"aarch64.dmg",
|
||||
|
||||
@@ -223,6 +223,11 @@ menu "Target Images"
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default y
|
||||
|
||||
config GRUB_SERIAL
|
||||
string "Serial port device"
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default "ttyS0"
|
||||
|
||||
config GRUB_BAUDRATE
|
||||
int "Serial port baud rate"
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
@@ -231,8 +236,7 @@ menu "Target Images"
|
||||
|
||||
config GRUB_FLOWCONTROL
|
||||
bool "Use RTE/CTS on serial console"
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
depends on TARGET_SERIAL != ""
|
||||
depends on GRUB_SERIAL != ""
|
||||
default n
|
||||
|
||||
config GRUB_BOOTOPTS
|
||||
@@ -285,11 +289,6 @@ menu "Target Images"
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
select PACKAGE_kmod-e1000
|
||||
|
||||
config TARGET_SERIAL
|
||||
string "Serial port device"
|
||||
depends on TARGET_x86 || TARGET_armvirt || TARGET_loongarch64
|
||||
default "ttyS0"
|
||||
|
||||
config TARGET_IMAGES_GZIP
|
||||
bool "GZip images"
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_x86 || TARGET_armvirt || TARGET_malta || TARGET_loongarch64
|
||||
|
||||
@@ -69,3 +69,5 @@ func WithDSCP(dscp uint8) Addition {
|
||||
metadata.DSCP = dscp
|
||||
}
|
||||
}
|
||||
|
||||
func Placeholder(metadata *C.Metadata) {}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
)
|
||||
|
||||
func newClient(srcConn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) *http.Client {
|
||||
func newClient(srcConn net.Conn, tunnel C.Tunnel, additions []inbound.Addition) *http.Client { // additions using slice let caller can change its value (without size) after newClient return
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{
|
||||
// from http.DefaultTransport
|
||||
|
||||
@@ -10,10 +10,9 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/auth"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
)
|
||||
|
||||
@@ -31,8 +30,10 @@ func (b *bodyWrapper) Read(p []byte) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
|
||||
client := newClient(c, tunnel, additions...)
|
||||
func HandleConn(c net.Conn, tunnel C.Tunnel, authenticator auth.Authenticator, additions ...inbound.Addition) {
|
||||
additions = append(additions, inbound.Placeholder) // Add a placeholder for InUser
|
||||
inUserIdx := len(additions) - 1
|
||||
client := newClient(c, tunnel, additions)
|
||||
defer client.CloseIdleConnections()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@@ -41,7 +42,8 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
conn := N.NewBufferedConn(c)
|
||||
|
||||
keepAlive := true
|
||||
trusted := cache == nil // disable authenticate if lru is nil
|
||||
trusted := authenticator == nil // disable authenticate if lru is nil
|
||||
lastUser := ""
|
||||
|
||||
for keepAlive {
|
||||
peekMutex.Lock()
|
||||
@@ -57,12 +59,10 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
|
||||
var resp *http.Response
|
||||
|
||||
if !trusted {
|
||||
var user string
|
||||
resp, user = authenticate(request, cache)
|
||||
additions = append(additions, inbound.WithInUser(user))
|
||||
trusted = resp == nil
|
||||
}
|
||||
var user string
|
||||
resp, user = authenticate(request, authenticator) // always call authenticate function to get user
|
||||
trusted = trusted || resp == nil
|
||||
additions[inUserIdx] = inbound.WithInUser(user)
|
||||
|
||||
if trusted {
|
||||
if request.Method == http.MethodConnect {
|
||||
@@ -89,6 +89,13 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
return // hijack connection
|
||||
}
|
||||
|
||||
// ensure there is a client with correct additions
|
||||
// when the authenticated user changed, outbound client should close idle connections
|
||||
if user != lastUser {
|
||||
client.CloseIdleConnections()
|
||||
lastUser = user
|
||||
}
|
||||
|
||||
removeHopByHopHeaders(request.Header)
|
||||
removeExtraHTTPHostPort(request)
|
||||
|
||||
@@ -138,34 +145,24 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
||||
_ = conn.Close()
|
||||
}
|
||||
|
||||
func authenticate(request *http.Request, cache *lru.LruCache[string, bool]) (resp *http.Response, u string) {
|
||||
authenticator := authStore.Authenticator()
|
||||
func authenticate(request *http.Request, authenticator auth.Authenticator) (resp *http.Response, user string) {
|
||||
if inbound.SkipAuthRemoteAddress(request.RemoteAddr) {
|
||||
authenticator = nil
|
||||
}
|
||||
if authenticator != nil {
|
||||
credential := parseBasicProxyAuthorization(request)
|
||||
if credential == "" {
|
||||
resp := responseWith(request, http.StatusProxyAuthRequired)
|
||||
resp.Header.Set("Proxy-Authenticate", "Basic")
|
||||
return resp, ""
|
||||
}
|
||||
|
||||
authed, exist := cache.Get(credential)
|
||||
if !exist {
|
||||
user, pass, err := decodeBasicProxyAuthorization(credential)
|
||||
authed = err == nil && authenticator.Verify(user, pass)
|
||||
u = user
|
||||
cache.Set(credential, authed)
|
||||
}
|
||||
if !authed {
|
||||
log.Infoln("Auth failed from %s", request.RemoteAddr)
|
||||
|
||||
return responseWith(request, http.StatusForbidden), u
|
||||
}
|
||||
credential := parseBasicProxyAuthorization(request)
|
||||
if credential == "" && authenticator != nil {
|
||||
resp = responseWith(request, http.StatusProxyAuthRequired)
|
||||
resp.Header.Set("Proxy-Authenticate", "Basic")
|
||||
return
|
||||
}
|
||||
|
||||
return nil, u
|
||||
user, pass, err := decodeBasicProxyAuthorization(credential)
|
||||
authed := authenticator == nil || (err == nil && authenticator.Verify(user, pass))
|
||||
if !authed {
|
||||
log.Infoln("Auth failed from %s", request.RemoteAddr)
|
||||
return responseWith(request, http.StatusForbidden), user
|
||||
}
|
||||
log.Debugln("Auth success from %s -> %s", request.RemoteAddr, user)
|
||||
return
|
||||
}
|
||||
|
||||
func responseWith(request *http.Request, statusCode int) *http.Response {
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/component/auth"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
)
|
||||
|
||||
type Listener struct {
|
||||
@@ -32,10 +33,10 @@ func (l *Listener) Close() error {
|
||||
}
|
||||
|
||||
func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) {
|
||||
return NewWithAuthenticate(addr, tunnel, true, additions...)
|
||||
return NewWithAuthenticate(addr, tunnel, authStore.Authenticator(), additions...)
|
||||
}
|
||||
|
||||
func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additions ...inbound.Addition) (*Listener, error) {
|
||||
func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticator auth.Authenticator, additions ...inbound.Addition) (*Listener, error) {
|
||||
isDefault := false
|
||||
if len(additions) == 0 {
|
||||
isDefault = true
|
||||
@@ -50,11 +51,6 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c *lru.LruCache[string, bool]
|
||||
if authenticate {
|
||||
c = lru.New[string, bool](lru.WithAge[string, bool](30))
|
||||
}
|
||||
|
||||
hl := &Listener{
|
||||
listener: l,
|
||||
addr: addr,
|
||||
@@ -79,7 +75,7 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
|
||||
continue
|
||||
}
|
||||
}
|
||||
go HandleConn(conn, tunnel, c, additions...)
|
||||
go HandleConn(conn, tunnel, authenticator, additions...)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
"github.com/metacubex/mihomo/listener/http"
|
||||
"github.com/metacubex/mihomo/listener/socks"
|
||||
"github.com/metacubex/mihomo/transport/socks4"
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
type Listener struct {
|
||||
listener net.Listener
|
||||
addr string
|
||||
cache *lru.LruCache[string, bool]
|
||||
closed bool
|
||||
}
|
||||
|
||||
@@ -53,7 +52,6 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener
|
||||
ml := &Listener{
|
||||
listener: l,
|
||||
addr: addr,
|
||||
cache: lru.New[string, bool](lru.WithAge[string, bool](30)),
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
@@ -70,14 +68,14 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener
|
||||
continue
|
||||
}
|
||||
}
|
||||
go handleConn(c, tunnel, ml.cache, additions...)
|
||||
go handleConn(c, tunnel, additions...)
|
||||
}
|
||||
}()
|
||||
|
||||
return ml, nil
|
||||
}
|
||||
|
||||
func handleConn(conn net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
|
||||
func handleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
|
||||
N.TCPKeepAlive(conn)
|
||||
|
||||
bufConn := N.NewBufferedConn(conn)
|
||||
@@ -92,6 +90,6 @@ func handleConn(conn net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool
|
||||
case socks5.Version:
|
||||
socks.HandleSocks5(bufConn, tunnel, additions...)
|
||||
default:
|
||||
http.HandleConn(bufConn, tunnel, cache, additions...)
|
||||
http.HandleConn(bufConn, tunnel, authStore.Authenticator(), additions...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
trackerConnectFlag = iota
|
||||
trackerAnnounceFlag
|
||||
trackerScrapeFlag
|
||||
|
||||
trackerProtocolID = 0x41727101980
|
||||
|
||||
trackerConnectMinSize = 16
|
||||
trackerAnnounceMinSize = 20
|
||||
trackerScrapeMinSize = 8
|
||||
trackerConnectFlag = 0
|
||||
trackerProtocolID = 0x41727101980
|
||||
trackerConnectMinSize = 16
|
||||
)
|
||||
|
||||
// BitTorrent detects if the stream is a BitTorrent connection.
|
||||
@@ -91,19 +85,15 @@ func UTP(_ context.Context, metadata *adapter.InboundContext, packet []byte) err
|
||||
// UDPTracker detects if the packet is a UDP Tracker Protocol packet.
|
||||
// For the UDP Tracker Protocol specification, see https://www.bittorrent.org/beps/bep_0015.html
|
||||
func UDPTracker(_ context.Context, metadata *adapter.InboundContext, packet []byte) error {
|
||||
switch {
|
||||
case len(packet) >= trackerConnectMinSize &&
|
||||
binary.BigEndian.Uint64(packet[:8]) == trackerProtocolID &&
|
||||
binary.BigEndian.Uint32(packet[8:12]) == trackerConnectFlag:
|
||||
fallthrough
|
||||
case len(packet) >= trackerAnnounceMinSize &&
|
||||
binary.BigEndian.Uint32(packet[8:12]) == trackerAnnounceFlag:
|
||||
fallthrough
|
||||
case len(packet) >= trackerScrapeMinSize &&
|
||||
binary.BigEndian.Uint32(packet[8:12]) == trackerScrapeFlag:
|
||||
metadata.Protocol = C.ProtocolBitTorrent
|
||||
return nil
|
||||
default:
|
||||
if len(packet) < trackerConnectMinSize {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
if binary.BigEndian.Uint64(packet[:8]) != trackerProtocolID {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
if binary.BigEndian.Uint32(packet[8:12]) != trackerConnectFlag {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
metadata.Protocol = C.ProtocolBitTorrent
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -56,20 +56,9 @@ func TestSniffUDPTracker(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
connectPackets := []string{
|
||||
// connect packets
|
||||
"00000417271019800000000078e90560",
|
||||
"00000417271019800000000022c5d64d",
|
||||
"000004172710198000000000b3863541",
|
||||
|
||||
// announce packets
|
||||
"3d7592ead4b8c9e300000001b871a3820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002092f616e6e6f756e6365",
|
||||
"3d7592ead4b8c9e30000000188deed1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002092f616e6e6f756e6365",
|
||||
"3d7592ead4b8c9e300000001ceb948ad0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a3362cdb7020ff920e5aa642c3d4066950dd1f01f4d00000000000000000000000000000000000000000000000000000000000000000000000000000000000002092f616e6e6f756e6365",
|
||||
|
||||
// scrape packets
|
||||
"3d7592ead4b8c9e300000002d2f4bba5a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
|
||||
"3d7592ead4b8c9e300000002441243292aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
|
||||
"3d7592ead4b8c9e300000002b2aa461b1ad1fa9661cf3fe45fb2504ad52ec6c67758e294",
|
||||
}
|
||||
|
||||
for _, pkt := range connectPackets {
|
||||
|
||||
@@ -40,9 +40,10 @@ func PeekStream(ctx context.Context, metadata *adapter.InboundContext, conn net.
|
||||
}
|
||||
for _, sniffer := range sniffers {
|
||||
err = sniffer(ctx, metadata, bytes.NewReader(buffer.Bytes()))
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
return E.Errors(errors...)
|
||||
@@ -52,9 +53,10 @@ func PeekPacket(ctx context.Context, metadata *adapter.InboundContext, packet []
|
||||
var errors []error
|
||||
for _, sniffer := range sniffers {
|
||||
err := sniffer(ctx, metadata, packet)
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
return E.Errors(errors...)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.10.0-alpha.24
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.10.0-alpha.23
|
||||
|
||||
* Add Chromium support for QUIC sniffer
|
||||
|
||||
+7
-7
@@ -27,7 +27,7 @@ require (
|
||||
github.com/sagernet/quic-go v0.45.1-beta.2
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.5.0-alpha.13
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.10
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.12
|
||||
github.com/sagernet/sing-mux v0.2.0
|
||||
github.com/sagernet/sing-quic v0.2.0-beta.12
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||
@@ -44,9 +44,9 @@ require (
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.uber.org/zap v1.27.0
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
||||
golang.org/x/crypto v0.24.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/sys v0.22.0
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||
google.golang.org/grpc v1.63.2
|
||||
google.golang.org/protobuf v1.33.0
|
||||
@@ -89,12 +89,12 @@ require (
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/mod v0.19.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
+15
-15
@@ -117,8 +117,8 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4Wk
|
||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||
github.com/sagernet/sing v0.5.0-alpha.13 h1:fpR4TFZfu/9V3LbHSAnnnwcaXGMF8ijmAAPoY2WHSKw=
|
||||
github.com/sagernet/sing v0.5.0-alpha.13/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.10 h1:Js61EjQXVpcu2VDegWEQTH1isCcVwJju8WEHYgG4tQ0=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.10/go.mod h1:nXE6EYMXahB5DV3AcXYbFfuorqF7tbQ86kxweSxRKM4=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.12 h1:mdTsaVU+0jopEKUDLwLmo8AbiSGZOly97oSPBDX3O8I=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.12/go.mod h1:rscgSr5ixOPk8XM9ZMLuMXCyldEQ1nLvdl0nfv+lp00=
|
||||
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
|
||||
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
|
||||
github.com/sagernet/sing-quic v0.2.0-beta.12 h1:BhvA5mmrDFEyDUQB5eeu+9UhF+ieyuNJ5Rsb0dAG3QY=
|
||||
@@ -172,16 +172,16 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -192,10 +192,10 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
@@ -203,8 +203,8 @@ golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
|
||||
@@ -12,13 +12,13 @@ PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
GEOIP_VER:=202407192357
|
||||
GEOIP_VER:=202407250045
|
||||
GEOIP_FILE:=geoip.dat.$(GEOIP_VER)
|
||||
define Download/geoip
|
||||
URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/
|
||||
URL_FILE:=geoip.dat
|
||||
FILE:=$(GEOIP_FILE)
|
||||
HASH:=8128db0c1431f4c6854dfb7740b497ee0ac73f0f3a52a1e0040c508f7d79c0a4
|
||||
HASH:=f83e89edfd3b35acbbbb862a4c88a8ca3e1ddce4d298cc617be79bdaa23a0672
|
||||
endef
|
||||
|
||||
GEOSITE_VER:=20240720181558
|
||||
|
||||
@@ -197,6 +197,15 @@ namespace v2rayN.Handler
|
||||
}
|
||||
config.clashUIItem ??= new();
|
||||
|
||||
if (config.systemProxyItem == null)
|
||||
{
|
||||
config.systemProxyItem = new()
|
||||
{
|
||||
systemProxyExceptions = config.systemProxyExceptions,
|
||||
systemProxyAdvancedProtocol = config.systemProxyAdvancedProtocol,
|
||||
};
|
||||
}
|
||||
|
||||
LazyConfig.Instance.SetConfig(config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace v2rayN.Handler
|
||||
{
|
||||
try
|
||||
{
|
||||
int index = (int)config.sysProxyType;
|
||||
int index = (int)config.systemProxyItem.sysProxyType;
|
||||
|
||||
//Load from routing setting
|
||||
var createdIcon = GetNotifyIcon4Routing(config);
|
||||
@@ -56,7 +56,7 @@ namespace v2rayN.Handler
|
||||
public System.Windows.Media.ImageSource GetAppIcon(Config config)
|
||||
{
|
||||
int index = 1;
|
||||
switch (config.sysProxyType)
|
||||
switch (config.systemProxyItem.sysProxyType)
|
||||
{
|
||||
case ESysProxyType.ForcedClear:
|
||||
index = 1;
|
||||
@@ -90,7 +90,7 @@ namespace v2rayN.Handler
|
||||
}
|
||||
|
||||
Color color = ColorTranslator.FromHtml("#3399CC");
|
||||
int index = (int)config.sysProxyType;
|
||||
int index = (int)config.systemProxyItem.sysProxyType;
|
||||
if (index > 0)
|
||||
{
|
||||
color = (new[] { Color.Red, Color.Purple, Color.DarkGreen, Color.Orange, Color.DarkSlateBlue, Color.RoyalBlue })[index - 1];
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace v2rayN.Handler
|
||||
|
||||
public static bool UpdateSysProxy(Config config, bool forceDisable)
|
||||
{
|
||||
var type = config.sysProxyType;
|
||||
var type = config.systemProxyItem.sysProxyType;
|
||||
|
||||
if (forceDisable && type != ESysProxyType.Unchanged)
|
||||
{
|
||||
@@ -30,19 +30,19 @@ namespace v2rayN.Handler
|
||||
if (type == ESysProxyType.ForcedChange)
|
||||
{
|
||||
var strExceptions = "";
|
||||
if (config.notProxyLocalAddress)
|
||||
if (config.systemProxyItem.notProxyLocalAddress)
|
||||
{
|
||||
strExceptions = $"<local>;{config.constItem.defIEProxyExceptions};{config.systemProxyExceptions}";
|
||||
strExceptions = $"<local>;{config.constItem.defIEProxyExceptions};{config.systemProxyItem.systemProxyExceptions}";
|
||||
}
|
||||
|
||||
var strProxy = string.Empty;
|
||||
if (Utils.IsNullOrEmpty(config.systemProxyAdvancedProtocol))
|
||||
if (Utils.IsNullOrEmpty(config.systemProxyItem.systemProxyAdvancedProtocol))
|
||||
{
|
||||
strProxy = $"{Global.Loopback}:{port}";
|
||||
}
|
||||
else
|
||||
{
|
||||
strProxy = config.systemProxyAdvancedProtocol
|
||||
strProxy = config.systemProxyItem.systemProxyAdvancedProtocol
|
||||
.Replace("{ip}", Global.Loopback)
|
||||
.Replace("{http_port}", port.ToString())
|
||||
.Replace("{socks_port}", portSocks.ToString());
|
||||
|
||||
@@ -12,9 +12,7 @@ namespace v2rayN.Models
|
||||
|
||||
public string indexId { get; set; }
|
||||
public string subIndexId { get; set; }
|
||||
public ESysProxyType sysProxyType { get; set; }
|
||||
public string systemProxyExceptions { get; set; }
|
||||
public bool notProxyLocalAddress { get; set; } = true;
|
||||
public string systemProxyAdvancedProtocol { get; set; }
|
||||
|
||||
public ECoreType runningCoreType { get; set; }
|
||||
@@ -48,6 +46,7 @@ namespace v2rayN.Models
|
||||
public Mux4SboxItem mux4SboxItem { get; set; }
|
||||
public HysteriaItem hysteriaItem { get; set; }
|
||||
public ClashUIItem clashUIItem { get; set; }
|
||||
public SystemProxyItem systemProxyItem { get; set; }
|
||||
public List<InItem> inbound { get; set; }
|
||||
public List<KeyEventItem> globalHotkeys { get; set; }
|
||||
public List<CoreTypeItem> coreTypeItem { get; set; }
|
||||
|
||||
@@ -227,4 +227,13 @@ namespace v2rayN.Models
|
||||
public bool connectionsAutoRefresh { get; set; }
|
||||
public int connectionsRefreshInterval { get; set; } = 2;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SystemProxyItem
|
||||
{
|
||||
public ESysProxyType sysProxyType { get; set; }
|
||||
public string systemProxyExceptions { get; set; }
|
||||
public bool notProxyLocalAddress { get; set; } = true;
|
||||
public string systemProxyAdvancedProtocol { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -234,7 +234,7 @@ namespace v2rayN.ViewModels
|
||||
y => y != null && !y.Text.IsNullOrEmpty())
|
||||
.Subscribe(c => ServerSelectedChanged(c));
|
||||
|
||||
SystemProxySelected = (int)_config.sysProxyType;
|
||||
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
|
||||
this.WhenAnyValue(
|
||||
x => x.SystemProxySelected,
|
||||
y => y >= 0)
|
||||
@@ -429,7 +429,7 @@ namespace v2rayN.ViewModels
|
||||
//RefreshServers();
|
||||
|
||||
Reload();
|
||||
ChangeSystemProxyStatus(_config.sysProxyType, true);
|
||||
ChangeSystemProxyStatus(_config.systemProxyItem.sysProxyType, true);
|
||||
}
|
||||
|
||||
private void OnProgramStarted(object state, bool timeout)
|
||||
@@ -936,7 +936,7 @@ namespace v2rayN.ViewModels
|
||||
|
||||
//ConfigHandler.SaveConfig(_config, false);
|
||||
|
||||
ChangeSystemProxyStatus(_config.sysProxyType, false);
|
||||
ChangeSystemProxyStatus(_config.systemProxyItem.sysProxyType, false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -955,21 +955,21 @@ namespace v2rayN.ViewModels
|
||||
|
||||
public void SetListenerType(ESysProxyType type)
|
||||
{
|
||||
if (_config.sysProxyType == type)
|
||||
if (_config.systemProxyItem.sysProxyType == type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_config.sysProxyType = type;
|
||||
_config.systemProxyItem.sysProxyType = type;
|
||||
ChangeSystemProxyStatus(type, true);
|
||||
|
||||
SystemProxySelected = (int)_config.sysProxyType;
|
||||
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
|
||||
ConfigHandler.SaveConfig(_config, false);
|
||||
}
|
||||
|
||||
private void ChangeSystemProxyStatus(ESysProxyType type, bool blChange)
|
||||
{
|
||||
SysProxyHandle.UpdateSysProxy(_config, _config.tunModeItem.enableTun ? true : false);
|
||||
_noticeHandler?.SendMessage($"{ResUI.TipChangeSystemProxy} - {_config.sysProxyType.ToString()}", true);
|
||||
_noticeHandler?.SendMessage($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}", true);
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
@@ -1046,7 +1046,7 @@ namespace v2rayN.ViewModels
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_config.sysProxyType == (ESysProxyType)SystemProxySelected)
|
||||
if (_config.systemProxyItem.sysProxyType == (ESysProxyType)SystemProxySelected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1223,7 +1223,7 @@ namespace v2rayN.ViewModels
|
||||
StringBuilder sb = new();
|
||||
sb.Append($"[{EInboundProtocol.socks}:{LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks)}]");
|
||||
sb.Append(" | ");
|
||||
//if (_config.sysProxyType == ESysProxyType.ForcedChange)
|
||||
//if (_config.systemProxyItem.sysProxyType == ESysProxyType.ForcedChange)
|
||||
//{
|
||||
// sb.Append($"[{Global.InboundHttp}({ResUI.SystemProxy}):{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]");
|
||||
//}
|
||||
@@ -1293,4 +1293,4 @@ namespace v2rayN.ViewModels
|
||||
|
||||
#endregion UI
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,9 +179,9 @@ namespace v2rayN.ViewModels
|
||||
|
||||
#region System proxy
|
||||
|
||||
notProxyLocalAddress = _config.notProxyLocalAddress;
|
||||
systemProxyAdvancedProtocol = _config.systemProxyAdvancedProtocol;
|
||||
systemProxyExceptions = _config.systemProxyExceptions;
|
||||
notProxyLocalAddress = _config.systemProxyItem.notProxyLocalAddress;
|
||||
systemProxyAdvancedProtocol = _config.systemProxyItem.systemProxyAdvancedProtocol;
|
||||
systemProxyExceptions = _config.systemProxyItem.systemProxyExceptions;
|
||||
|
||||
#endregion System proxy
|
||||
|
||||
@@ -340,9 +340,9 @@ namespace v2rayN.ViewModels
|
||||
_config.uiItem.mainGirdOrientation = (EGirdOrientation)MainGirdOrientation;
|
||||
|
||||
//systemProxy
|
||||
_config.systemProxyExceptions = systemProxyExceptions;
|
||||
_config.notProxyLocalAddress = notProxyLocalAddress;
|
||||
_config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
|
||||
_config.systemProxyItem.systemProxyExceptions = systemProxyExceptions;
|
||||
_config.systemProxyItem.notProxyLocalAddress = notProxyLocalAddress;
|
||||
_config.systemProxyItem.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
|
||||
|
||||
//tun mode
|
||||
_config.tunModeItem.strictRoute = TunStrictRoute;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="4.0.9" />
|
||||
<PackageReference Include="ReactiveUI.WPF" Version="20.1.1" />
|
||||
<PackageReference Include="Splat.NLog" Version="15.1.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="15.3.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -81,7 +81,9 @@
|
||||
},
|
||||
{
|
||||
"protocol": "freedom",
|
||||
"settings": {},
|
||||
"settings": {
|
||||
"domainStrategy": "UseIP"
|
||||
},
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -173,10 +173,6 @@ object V2rayConfigUtil {
|
||||
&& settingsStorage?.decodeBool(AppConfig.PREF_FAKE_DNS_ENABLED) == true
|
||||
) {
|
||||
v2rayConfig.fakedns = listOf(V2rayConfig.FakednsBean())
|
||||
v2rayConfig.outbounds.filter { it.protocol == PROTOCOL_FREEDOM && it.tag == TAG_DIRECT }
|
||||
.forEach {
|
||||
it.settings?.domainStrategy = "UseIP"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,38 +28,47 @@ object TrojanFmt {
|
||||
|
||||
var flow = ""
|
||||
var fingerprint = config.outboundBean?.streamSettings?.tlsSettings?.fingerprint
|
||||
if (uri.rawQuery.isNullOrEmpty()) return null
|
||||
|
||||
|
||||
val queryParam = uri.rawQuery.split("&")
|
||||
.associate { it.split("=").let { (k, v) -> k to Utils.urlDecode(v) } }
|
||||
|
||||
val sni = config.outboundBean?.streamSettings?.populateTransportSettings(
|
||||
queryParam["type"] ?: "tcp",
|
||||
queryParam["headerType"],
|
||||
queryParam["host"],
|
||||
queryParam["path"],
|
||||
queryParam["seed"],
|
||||
queryParam["quicSecurity"],
|
||||
queryParam["key"],
|
||||
queryParam["mode"],
|
||||
queryParam["serviceName"],
|
||||
queryParam["authority"]
|
||||
)
|
||||
fingerprint = queryParam["fp"] ?: ""
|
||||
allowInsecure = if ((queryParam["allowInsecure"] ?: "") == "1") true else allowInsecure
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(
|
||||
queryParam["security"] ?: V2rayConfig.TLS,
|
||||
allowInsecure,
|
||||
queryParam["sni"] ?: sni ?: "",
|
||||
fingerprint,
|
||||
queryParam["alpn"],
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
flow = queryParam["flow"] ?: ""
|
||||
if (uri.rawQuery.isNullOrEmpty()) {
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(
|
||||
V2rayConfig.TLS,
|
||||
allowInsecure,
|
||||
"",
|
||||
fingerprint,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} else {
|
||||
val queryParam = uri.rawQuery.split("&")
|
||||
.associate { it.split("=").let { (k, v) -> k to Utils.urlDecode(v) } }
|
||||
|
||||
val sni = config.outboundBean?.streamSettings?.populateTransportSettings(
|
||||
queryParam["type"] ?: "tcp",
|
||||
queryParam["headerType"],
|
||||
queryParam["host"],
|
||||
queryParam["path"],
|
||||
queryParam["seed"],
|
||||
queryParam["quicSecurity"],
|
||||
queryParam["key"],
|
||||
queryParam["mode"],
|
||||
queryParam["serviceName"],
|
||||
queryParam["authority"]
|
||||
)
|
||||
fingerprint = queryParam["fp"] ?: ""
|
||||
allowInsecure = if ((queryParam["allowInsecure"] ?: "") == "1") true else allowInsecure
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(
|
||||
queryParam["security"] ?: V2rayConfig.TLS,
|
||||
allowInsecure,
|
||||
queryParam["sni"] ?: sni ?: "",
|
||||
fingerprint,
|
||||
queryParam["alpn"],
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
flow = queryParam["flow"] ?: ""
|
||||
}
|
||||
config.outboundBean?.settings?.servers?.get(0)?.let { server ->
|
||||
server.address = uri.idnHost
|
||||
server.port = uri.port
|
||||
|
||||
@@ -57,7 +57,7 @@ OptionDialog::OptionDialog(const std::string& title, GtkWindow* parent, bool mod
|
||||
gtk_widget_set_margin_right(GTK_WIDGET(grid), 12);
|
||||
#endif
|
||||
gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
|
||||
gtk_grid_set_row_spacing(GTK_GRID(grid), 12);
|
||||
gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
|
||||
|
||||
okay_button_ = GTK_BUTTON(gtk_button_new());
|
||||
gtk_button_set_label(okay_button_, _("Okay"));
|
||||
|
||||
@@ -104,9 +104,11 @@ YASSWindow::YASSWindow() : impl_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))
|
||||
|
||||
start_button_ = GTK_BUTTON(gtk_button_new());
|
||||
gtk_button_set_label(start_button_, _("Start"));
|
||||
gtk_widget_set_size_request(GTK_WIDGET(start_button_), 84, -1);
|
||||
|
||||
stop_button_ = GTK_BUTTON(gtk_button_new());
|
||||
gtk_button_set_label(stop_button_, _("Stop"));
|
||||
gtk_widget_set_size_request(GTK_WIDGET(stop_button_), 84, -1);
|
||||
|
||||
auto start_callback = [](GtkButton* self, gpointer pointer) {
|
||||
YASSWindow* window = (YASSWindow*)pointer;
|
||||
@@ -127,35 +129,69 @@ YASSWindow::YASSWindow() : impl_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))
|
||||
gtk_grid_attach(grid, GTK_WIDGET(start_button_), 0, 2, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(stop_button_), 0, 7, 1, 1);
|
||||
|
||||
auto server_host_label_ = gtk_label_new(_("Server Host"));
|
||||
auto server_sni_label_ = gtk_label_new(_("Server SNI"));
|
||||
auto server_port_label_ = gtk_label_new(_("Server Port"));
|
||||
auto username_label_ = gtk_label_new(_("Username"));
|
||||
auto password_label_ = gtk_label_new(_("Password"));
|
||||
auto method_label_ = gtk_label_new(_("Cipher/Method"));
|
||||
auto local_host_label_ = gtk_label_new(_("Local Host"));
|
||||
auto local_port_label_ = gtk_label_new(_("Local Port"));
|
||||
auto doh_url_label_ = gtk_label_new(_("DNS over HTTPS URL"));
|
||||
auto dot_host_label_ = gtk_label_new(_("DNS over TLS Host"));
|
||||
auto limit_rate_label_ = gtk_label_new(_("Limit Rate"));
|
||||
auto timeout_label_ = gtk_label_new(_("Timeout"));
|
||||
auto autostart_label_ = gtk_label_new(_("Auto Start"));
|
||||
auto systemproxy_label_ = gtk_label_new(_("System Proxy"));
|
||||
auto server_host_label = gtk_label_new(_("Server Host"));
|
||||
auto server_sni_label = gtk_label_new(_("Server SNI"));
|
||||
auto server_port_label = gtk_label_new(_("Server Port"));
|
||||
auto username_label = gtk_label_new(_("Username"));
|
||||
auto password_label = gtk_label_new(_("Password"));
|
||||
auto method_label = gtk_label_new(_("Cipher/Method"));
|
||||
auto local_host_label = gtk_label_new(_("Local Host"));
|
||||
auto local_port_label = gtk_label_new(_("Local Port"));
|
||||
auto doh_url_label = gtk_label_new(_("DNS over HTTPS URL"));
|
||||
auto dot_host_label = gtk_label_new(_("DNS over TLS Host"));
|
||||
auto limit_rate_label = gtk_label_new(_("Limit Rate"));
|
||||
auto timeout_label = gtk_label_new(_("Timeout"));
|
||||
auto autostart_label = gtk_label_new(_("Auto Start"));
|
||||
auto systemproxy_label = gtk_label_new(_("System Proxy"));
|
||||
|
||||
gtk_grid_attach(grid, GTK_WIDGET(server_host_label_), 1, 0, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(server_sni_label_), 1, 1, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(server_port_label_), 1, 2, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(username_label_), 1, 3, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(password_label_), 1, 4, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(method_label_), 1, 5, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(local_host_label_), 1, 6, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(local_port_label_), 1, 7, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(doh_url_label_), 1, 8, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(dot_host_label_), 1, 9, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(limit_rate_label_), 1, 10, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(timeout_label_), 1, 11, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(autostart_label_), 1, 12, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(systemproxy_label_), 1, 13, 1, 1);
|
||||
// see https://stackoverflow.com/questions/24994255/how-to-left-align-a-gtk-label-when-its-width-is-set-by-gtksizegroup
|
||||
#if GTK_CHECK_VERSION(3, 16, 0)
|
||||
gtk_label_set_xalign(GTK_LABEL(server_host_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(server_sni_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(server_port_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(username_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(password_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(method_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(local_host_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(local_port_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(doh_url_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(dot_host_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(limit_rate_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(timeout_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(autostart_label), 0.0);
|
||||
gtk_label_set_xalign(GTK_LABEL(systemproxy_label), 0.0);
|
||||
#else
|
||||
gtk_misc_set_alignment(GTK_MISC(server_host_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(server_host_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(server_sni_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(server_port_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(username_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(password_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(method_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(local_host_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(local_port_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(doh_url_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(dot_host_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(limit_rate_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(timeout_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(autostart_label), 0.0, 0.5);
|
||||
gtk_misc_set_alignment(GTK_MISC(systemproxy_label), 0.0, 0.5);
|
||||
#endif
|
||||
|
||||
gtk_grid_attach(grid, GTK_WIDGET(server_host_label), 1, 0, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(server_sni_label), 1, 1, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(server_port_label), 1, 2, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(username_label), 1, 3, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(password_label), 1, 4, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(method_label), 1, 5, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(local_host_label), 1, 6, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(local_port_label), 1, 7, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(doh_url_label), 1, 8, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(dot_host_label), 1, 9, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(limit_rate_label), 1, 10, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(timeout_label), 1, 11, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(autostart_label), 1, 12, 1, 1);
|
||||
gtk_grid_attach(grid, GTK_WIDGET(systemproxy_label), 1, 13, 1, 1);
|
||||
|
||||
server_host_ = GTK_ENTRY(gtk_entry_new());
|
||||
server_sni_ = GTK_ENTRY(gtk_entry_new());
|
||||
@@ -230,7 +266,7 @@ YASSWindow::YASSWindow() : impl_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))
|
||||
gtk_widget_set_margin_right(GTK_WIDGET(grid), 12);
|
||||
#endif
|
||||
gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
|
||||
gtk_grid_set_row_spacing(GTK_GRID(grid), 12);
|
||||
gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
|
||||
|
||||
gtk_box_pack_start(vbox, GTK_WIDGET(grid), true, false, 0);
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">TCP keep alive:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">TCP keep alive</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
@@ -25,8 +25,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">The number of TCP keep-alive probes:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">The number of TCP keep-alive probes</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
@@ -35,8 +35,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">TCP keep alive after idle:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">TCP keep alive after idle</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
@@ -45,8 +45,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">TCP keep alive interval:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">TCP keep alive interval</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
@@ -55,8 +55,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Kyber post-quantum key agreement for TLS:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Kyber post-quantum key agreement for TLS</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
|
||||
+77
-77
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-07-09 09:56+0800\n"
|
||||
"POT-Creation-Date: 2024-07-25 13:13+0800\n"
|
||||
"PO-Revision-Date: 2023-05-24 14:35+0800\n"
|
||||
"Last-Translator: Chilledheart <keeyou-cn@outlook.com>\n"
|
||||
"Language-Team: Chilledheart <keeyou-cn@outlook.com>\n"
|
||||
@@ -17,63 +17,63 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: yass.cpp:301
|
||||
#: yass.cpp:302
|
||||
msgid "Connected with conns: "
|
||||
msgstr "Connected with conns: "
|
||||
|
||||
#: yass.cpp:303
|
||||
#: yass.cpp:304
|
||||
msgid "Connecting"
|
||||
msgstr "Connecting"
|
||||
|
||||
#: yass.cpp:305
|
||||
#: yass.cpp:306
|
||||
msgid "Failed to connect due to "
|
||||
msgstr "Failed to connect due to "
|
||||
|
||||
#: yass.cpp:307
|
||||
#: yass.cpp:308
|
||||
msgid "Disconnecting"
|
||||
msgstr "Disconnecting"
|
||||
|
||||
#: yass.cpp:309
|
||||
#: yass.cpp:310
|
||||
msgid "Disconnected with "
|
||||
msgstr "Disconnected with "
|
||||
|
||||
#: yass.cpp:420
|
||||
#: yass.cpp:421
|
||||
msgid "Last Change: "
|
||||
msgstr "Last Change: "
|
||||
|
||||
#: yass.cpp:423
|
||||
#: yass.cpp:424
|
||||
msgid "Enabled Feature: "
|
||||
msgstr "Enabled Feature: "
|
||||
|
||||
#: yass.cpp:426
|
||||
#: yass.cpp:427
|
||||
msgid "GUI Variant: "
|
||||
msgstr "GUI Variant: "
|
||||
|
||||
#: yass.cpp:435
|
||||
#: yass.cpp:436
|
||||
msgid "official-site"
|
||||
msgstr "official-site"
|
||||
|
||||
#: yass.cpp:441
|
||||
#: yass.cpp:442
|
||||
msgid "YASS Option"
|
||||
msgstr "YASS Option"
|
||||
|
||||
#: yass_window.cpp:190
|
||||
#: yass_window.cpp:192
|
||||
msgid "READY"
|
||||
msgstr "READY"
|
||||
|
||||
#: yass_window.cpp:314
|
||||
#: yass_window.cpp:319
|
||||
msgid " tx rate: "
|
||||
msgstr " tx rate: "
|
||||
|
||||
#: yass_window.cpp:317
|
||||
#: yass_window.cpp:322
|
||||
msgid " rx rate: "
|
||||
msgstr " rx rate: "
|
||||
|
||||
#: yass_window.cpp:352
|
||||
#: yass_window.cpp:357
|
||||
msgid "Start Failed"
|
||||
msgstr "Start Failed"
|
||||
|
||||
#: yass_window.cpp:353
|
||||
#: yass_window.cpp:358
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
|
||||
@@ -93,31 +93,31 @@ msgstr "Quit"
|
||||
msgid "Option"
|
||||
msgstr "Option"
|
||||
|
||||
#: option_dialog.ui:20
|
||||
msgid "TCP keep alive:"
|
||||
msgstr "TCP keep alive:"
|
||||
#: option_dialog.ui:18
|
||||
msgid "TCP keep alive"
|
||||
msgstr "TCP keep alive"
|
||||
|
||||
#: option_dialog.ui:30
|
||||
msgid "The number of TCP keep-alive probes:"
|
||||
msgstr "The number of TCP keep-alive probes:"
|
||||
#: option_dialog.ui:28
|
||||
msgid "The number of TCP keep-alive probes"
|
||||
msgstr "The number of TCP keep-alive probes"
|
||||
|
||||
#: option_dialog.ui:40
|
||||
msgid "TCP keep alive after idle:"
|
||||
msgstr "TCP keep alive after idle:"
|
||||
#: option_dialog.ui:38
|
||||
msgid "TCP keep alive after idle"
|
||||
msgstr "TCP keep alive after idle"
|
||||
|
||||
#: option_dialog.ui:50
|
||||
msgid "TCP keep alive interval:"
|
||||
msgstr "TCP keep alive interval:"
|
||||
#: option_dialog.ui:48
|
||||
msgid "TCP keep alive interval"
|
||||
msgstr "TCP keep alive interval"
|
||||
|
||||
#: option_dialog.ui:60
|
||||
msgid "Kyber post-quantum key agreement for TLS:"
|
||||
msgstr "Kyber post-quantum key agreement for TLS:"
|
||||
#: option_dialog.ui:58
|
||||
msgid "Kyber post-quantum key agreement for TLS"
|
||||
msgstr "Kyber post-quantum key agreement for TLS"
|
||||
|
||||
#: option_dialog.ui:110
|
||||
#: option_dialog.ui:108
|
||||
msgid "Okay"
|
||||
msgstr "Okay"
|
||||
|
||||
#: option_dialog.ui:119
|
||||
#: option_dialog.ui:117
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
@@ -125,66 +125,66 @@ msgstr "Cancel"
|
||||
msgid "Yet Another Shadow Socket"
|
||||
msgstr "Yet Another Shadow Socket"
|
||||
|
||||
#: yass_window.ui:31
|
||||
msgid "Server Host:"
|
||||
msgstr "Server Host:"
|
||||
#: yass_window.ui:30
|
||||
msgid "Server Host"
|
||||
msgstr "Server Host"
|
||||
|
||||
#: yass_window.ui:41
|
||||
msgid "Server SNI:"
|
||||
msgstr "Server SNI:"
|
||||
#: yass_window.ui:40
|
||||
msgid "Server SNI"
|
||||
msgstr "Server SNI"
|
||||
|
||||
#: yass_window.ui:51
|
||||
msgid "Server Port:"
|
||||
msgstr "Server Port:"
|
||||
#: yass_window.ui:50
|
||||
msgid "Server Port"
|
||||
msgstr "Server Port"
|
||||
|
||||
#: yass_window.ui:61
|
||||
msgid "Username:"
|
||||
msgstr "Username:"
|
||||
#: yass_window.ui:60
|
||||
msgid "Username"
|
||||
msgstr "Username"
|
||||
|
||||
#: yass_window.ui:71
|
||||
msgid "Password:"
|
||||
msgstr "Password:"
|
||||
#: yass_window.ui:70
|
||||
msgid "Password"
|
||||
msgstr "Password"
|
||||
|
||||
#: yass_window.ui:81
|
||||
msgid "Cipher/Method:"
|
||||
msgstr "Cipher/Method:"
|
||||
#: yass_window.ui:80
|
||||
msgid "Cipher/Method"
|
||||
msgstr "Cipher/Method"
|
||||
|
||||
#: yass_window.ui:91
|
||||
msgid "Local Host:"
|
||||
msgstr "Local Host:"
|
||||
#: yass_window.ui:90
|
||||
msgid "Local Host"
|
||||
msgstr "Local Host"
|
||||
|
||||
#: yass_window.ui:101
|
||||
msgid "Local Port:"
|
||||
msgstr "Local Port:"
|
||||
#: yass_window.ui:100
|
||||
msgid "Local Port"
|
||||
msgstr "Local Port"
|
||||
|
||||
#: yass_window.ui:111
|
||||
msgid "DNS over HTTPS URL:"
|
||||
msgstr "DNS over HTTPS URL:"
|
||||
#: yass_window.ui:110
|
||||
msgid "DNS over HTTPS URL"
|
||||
msgstr "DNS over HTTPS URL"
|
||||
|
||||
#: yass_window.ui:121
|
||||
msgid "DNS over TLS Host:"
|
||||
msgstr "DNS over TLS Host:"
|
||||
#: yass_window.ui:120
|
||||
msgid "DNS over TLS Host"
|
||||
msgstr "DNS over TLS Host"
|
||||
|
||||
#: yass_window.ui:131
|
||||
msgid "Limit Rate:"
|
||||
msgstr "Limit Rate:"
|
||||
#: yass_window.ui:130
|
||||
msgid "Limit Rate"
|
||||
msgstr "Limit Rate"
|
||||
|
||||
#: yass_window.ui:141
|
||||
msgid "Timeout:"
|
||||
msgstr "Timeout:"
|
||||
#: yass_window.ui:140
|
||||
msgid "Timeout"
|
||||
msgstr "Timeout"
|
||||
|
||||
#: yass_window.ui:151
|
||||
msgid "Auto Start:"
|
||||
msgstr "Auto Start:"
|
||||
#: yass_window.ui:150
|
||||
msgid "Auto Start"
|
||||
msgstr "Auto Start"
|
||||
|
||||
#: yass_window.ui:161
|
||||
msgid "System Proxy:"
|
||||
msgstr "System Proxy:"
|
||||
#: yass_window.ui:160
|
||||
msgid "System Proxy"
|
||||
msgstr "System Proxy"
|
||||
|
||||
#: yass_window.ui:283
|
||||
#: yass_window.ui:282
|
||||
msgid "Start"
|
||||
msgstr "Start"
|
||||
|
||||
#: yass_window.ui:292
|
||||
#: yass_window.ui:291
|
||||
msgid "Stop"
|
||||
msgstr "Stop"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gears">
|
||||
<property name="direction">none</property>
|
||||
<property name="icon-name">yass</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -22,13 +23,13 @@
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<property name="row-homogeneous">true</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Server Host:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Server Host</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
@@ -37,8 +38,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Server SNI:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Server SNI</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
@@ -47,8 +48,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Server Port:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Server Port</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
@@ -57,8 +58,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Username:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Username</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
@@ -67,8 +68,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Password:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Password</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
@@ -77,8 +78,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Cipher/Method:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Cipher/Method</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">5</property>
|
||||
@@ -87,8 +88,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Local Host:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Local Host</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">6</property>
|
||||
@@ -97,8 +98,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Local Port:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Local Port</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">7</property>
|
||||
@@ -107,8 +108,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">DNS over HTTPS URL:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">DNS over HTTPS URL</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">8</property>
|
||||
@@ -117,8 +118,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">DNS over TLS Host:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">DNS over TLS Host</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">9</property>
|
||||
@@ -127,8 +128,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Limit Rate:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Limit Rate</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">10</property>
|
||||
@@ -137,8 +138,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Timeout:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Timeout</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">11</property>
|
||||
@@ -147,8 +148,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Auto Start:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Auto Start</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">12</property>
|
||||
@@ -157,8 +158,8 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">System Proxy:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">System Proxy</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">13</property>
|
||||
@@ -280,6 +281,7 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="start_button">
|
||||
<property name="label" translatable="yes">Start</property>
|
||||
<property name="width-request">84</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
@@ -289,6 +291,7 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="stop_button">
|
||||
<property name="label" translatable="yes">Stop</property>
|
||||
<property name="width-request">84</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">7</property>
|
||||
@@ -299,6 +302,10 @@
|
||||
</child>
|
||||
<child type="statusbar">
|
||||
<object class="GtkStatusbar" id="status_bar">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
+77
-77
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-07-09 09:56+0800\n"
|
||||
"POT-Creation-Date: 2024-07-25 13:13+0800\n"
|
||||
"PO-Revision-Date: 2023-09-15 11:28+0800\n"
|
||||
"Last-Translator: Chilledheart <keeyou-cn@outlook.com>\n"
|
||||
"Language-Team: Chilledheart <keeyou-cn@outlook.com>\n"
|
||||
@@ -18,63 +18,63 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.2.4\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: yass.cpp:301
|
||||
#: yass.cpp:302
|
||||
msgid "Connected with conns: "
|
||||
msgstr "已产生连接: "
|
||||
|
||||
#: yass.cpp:303
|
||||
#: yass.cpp:304
|
||||
msgid "Connecting"
|
||||
msgstr "连接中"
|
||||
|
||||
#: yass.cpp:305
|
||||
#: yass.cpp:306
|
||||
msgid "Failed to connect due to "
|
||||
msgstr "无法连接因为 "
|
||||
|
||||
#: yass.cpp:307
|
||||
#: yass.cpp:308
|
||||
msgid "Disconnecting"
|
||||
msgstr "断开连接中"
|
||||
|
||||
#: yass.cpp:309
|
||||
#: yass.cpp:310
|
||||
msgid "Disconnected with "
|
||||
msgstr "断开连接于服务器 "
|
||||
|
||||
#: yass.cpp:420
|
||||
#: yass.cpp:421
|
||||
msgid "Last Change: "
|
||||
msgstr "最后改动: "
|
||||
|
||||
#: yass.cpp:423
|
||||
#: yass.cpp:424
|
||||
msgid "Enabled Feature: "
|
||||
msgstr "启用功能: "
|
||||
|
||||
#: yass.cpp:426
|
||||
#: yass.cpp:427
|
||||
msgid "GUI Variant: "
|
||||
msgstr "图形版本: "
|
||||
|
||||
#: yass.cpp:435
|
||||
#: yass.cpp:436
|
||||
msgid "official-site"
|
||||
msgstr "官方网站"
|
||||
|
||||
#: yass.cpp:441
|
||||
#: yass.cpp:442
|
||||
msgid "YASS Option"
|
||||
msgstr "YASS 选项"
|
||||
|
||||
#: yass_window.cpp:190
|
||||
#: yass_window.cpp:192
|
||||
msgid "READY"
|
||||
msgstr "就绪"
|
||||
|
||||
#: yass_window.cpp:314
|
||||
#: yass_window.cpp:319
|
||||
msgid " tx rate: "
|
||||
msgstr " 上传速率: "
|
||||
|
||||
#: yass_window.cpp:317
|
||||
#: yass_window.cpp:322
|
||||
msgid " rx rate: "
|
||||
msgstr " 下载速率: "
|
||||
|
||||
#: yass_window.cpp:352
|
||||
#: yass_window.cpp:357
|
||||
msgid "Start Failed"
|
||||
msgstr "启动失败"
|
||||
|
||||
#: yass_window.cpp:353
|
||||
#: yass_window.cpp:358
|
||||
msgid "OK"
|
||||
msgstr "确认"
|
||||
|
||||
@@ -94,31 +94,31 @@ msgstr "退出"
|
||||
msgid "Option"
|
||||
msgstr "选项"
|
||||
|
||||
#: option_dialog.ui:20
|
||||
msgid "TCP keep alive:"
|
||||
msgstr "TCP 保活:"
|
||||
#: option_dialog.ui:18
|
||||
msgid "TCP keep alive"
|
||||
msgstr "TCP 保活"
|
||||
|
||||
#: option_dialog.ui:30
|
||||
msgid "The number of TCP keep-alive probes:"
|
||||
msgstr "TCP 保活测量数:"
|
||||
#: option_dialog.ui:28
|
||||
msgid "The number of TCP keep-alive probes"
|
||||
msgstr "TCP 保活测量数"
|
||||
|
||||
#: option_dialog.ui:40
|
||||
msgid "TCP keep alive after idle:"
|
||||
msgstr "TCP 在闲置以后的保活次数:"
|
||||
#: option_dialog.ui:38
|
||||
msgid "TCP keep alive after idle"
|
||||
msgstr "TCP 在闲置以后的保活次数"
|
||||
|
||||
#: option_dialog.ui:50
|
||||
msgid "TCP keep alive interval:"
|
||||
msgstr "TCP 保活间隔:"
|
||||
#: option_dialog.ui:48
|
||||
msgid "TCP keep alive interval"
|
||||
msgstr "TCP 保活间隔"
|
||||
|
||||
#: option_dialog.ui:60
|
||||
msgid "Kyber post-quantum key agreement for TLS:"
|
||||
msgstr "TLS的Kyber后量子密钥协商:"
|
||||
#: option_dialog.ui:58
|
||||
msgid "Kyber post-quantum key agreement for TLS"
|
||||
msgstr "TLS的Kyber后量子密钥协商"
|
||||
|
||||
#: option_dialog.ui:110
|
||||
#: option_dialog.ui:108
|
||||
msgid "Okay"
|
||||
msgstr "确认"
|
||||
|
||||
#: option_dialog.ui:119
|
||||
#: option_dialog.ui:117
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
@@ -126,66 +126,66 @@ msgstr "取消"
|
||||
msgid "Yet Another Shadow Socket"
|
||||
msgstr "YASS"
|
||||
|
||||
#: yass_window.ui:31
|
||||
msgid "Server Host:"
|
||||
msgstr "服务器域名:"
|
||||
#: yass_window.ui:30
|
||||
msgid "Server Host"
|
||||
msgstr "服务器域名"
|
||||
|
||||
#: yass_window.ui:41
|
||||
msgid "Server SNI:"
|
||||
msgstr "服务器名称指示:"
|
||||
#: yass_window.ui:40
|
||||
msgid "Server SNI"
|
||||
msgstr "服务器名称指示"
|
||||
|
||||
#: yass_window.ui:51
|
||||
msgid "Server Port:"
|
||||
msgstr "服务器端口号:"
|
||||
#: yass_window.ui:50
|
||||
msgid "Server Port"
|
||||
msgstr "服务器端口号"
|
||||
|
||||
#: yass_window.ui:61
|
||||
msgid "Username:"
|
||||
msgstr "用户名:"
|
||||
#: yass_window.ui:60
|
||||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
#: yass_window.ui:71
|
||||
msgid "Password:"
|
||||
msgstr "密码:"
|
||||
#: yass_window.ui:70
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
#: yass_window.ui:81
|
||||
msgid "Cipher/Method:"
|
||||
msgstr "加密方式:"
|
||||
#: yass_window.ui:80
|
||||
msgid "Cipher/Method"
|
||||
msgstr "加密方式"
|
||||
|
||||
#: yass_window.ui:91
|
||||
msgid "Local Host:"
|
||||
msgstr "本地域名:"
|
||||
#: yass_window.ui:90
|
||||
msgid "Local Host"
|
||||
msgstr "本地域名"
|
||||
|
||||
#: yass_window.ui:101
|
||||
msgid "Local Port:"
|
||||
msgstr "本地端口号:"
|
||||
#: yass_window.ui:100
|
||||
msgid "Local Port"
|
||||
msgstr "本地端口号"
|
||||
|
||||
#: yass_window.ui:111
|
||||
msgid "DNS over HTTPS URL:"
|
||||
msgstr "基于 HTTPS 的 DNS (DoH) URL:"
|
||||
#: yass_window.ui:110
|
||||
msgid "DNS over HTTPS URL"
|
||||
msgstr "基于 HTTPS 的 DNS (DoH) URL"
|
||||
|
||||
#: yass_window.ui:121
|
||||
msgid "DNS over TLS Host:"
|
||||
msgstr "基于 TLS 的 DNS (DoT) 域名:"
|
||||
#: yass_window.ui:120
|
||||
msgid "DNS over TLS Host"
|
||||
msgstr "基于 TLS 的 DNS (DoT) 域名"
|
||||
|
||||
#: yass_window.ui:131
|
||||
msgid "Limit Rate:"
|
||||
msgstr "限制速率:"
|
||||
#: yass_window.ui:130
|
||||
msgid "Limit Rate"
|
||||
msgstr "限制速率"
|
||||
|
||||
#: yass_window.ui:141
|
||||
msgid "Timeout:"
|
||||
msgstr "超时时间:"
|
||||
#: yass_window.ui:140
|
||||
msgid "Timeout"
|
||||
msgstr "超时时间"
|
||||
|
||||
#: yass_window.ui:151
|
||||
msgid "Auto Start:"
|
||||
msgstr "随系统自启动:"
|
||||
#: yass_window.ui:150
|
||||
msgid "Auto Start"
|
||||
msgstr "随系统自启动"
|
||||
|
||||
#: yass_window.ui:161
|
||||
msgid "System Proxy:"
|
||||
msgstr "系统代理:"
|
||||
#: yass_window.ui:160
|
||||
msgid "System Proxy"
|
||||
msgstr "系统代理"
|
||||
|
||||
#: yass_window.ui:283
|
||||
#: yass_window.ui:282
|
||||
msgid "Start"
|
||||
msgstr "启动"
|
||||
|
||||
#: yass_window.ui:292
|
||||
#: yass_window.ui:291
|
||||
msgid "Stop"
|
||||
msgstr "停止"
|
||||
|
||||
@@ -75,11 +75,11 @@
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="YassViewController" id="XfG-lQ-9wD" customClass="YassViewController" sceneMemberID="viewController">
|
||||
<view key="view" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="523" height="516"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="532" height="438"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<gridView xPlacement="leading" yPlacement="bottom" rowAlignment="firstBaseline" rowSpacing="12" columnSpacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="u4K-Et-hUS">
|
||||
<rect key="frame" x="12" y="12" width="499" height="492"/>
|
||||
<gridView xPlacement="leading" yPlacement="bottom" rowAlignment="firstBaseline" columnSpacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="u4K-Et-hUS">
|
||||
<rect key="frame" x="12" y="12" width="508" height="414"/>
|
||||
<constraints>
|
||||
<constraint firstItem="VTW-w6-cOR" firstAttribute="trailing" secondItem="d0Y-hk-xNM" secondAttribute="trailing" id="39R-bq-g6c"/>
|
||||
<constraint firstItem="VTW-w6-cOR" firstAttribute="trailing" secondItem="z07-tR-0U9" secondAttribute="trailing" id="7C1-f5-V76"/>
|
||||
@@ -111,15 +111,15 @@
|
||||
<gridRow height="24" id="1cJ-xv-Xd3"/>
|
||||
</rows>
|
||||
<columns>
|
||||
<gridColumn width="75" id="LO3-Dh-mOI"/>
|
||||
<gridColumn width="84" id="LO3-Dh-mOI"/>
|
||||
<gridColumn width="200" id="a9F-Xp-86m"/>
|
||||
<gridColumn width="200" id="XrQ-Tc-XCS"/>
|
||||
</columns>
|
||||
<gridCells>
|
||||
<gridCell row="cJj-yp-Enp" column="LO3-Dh-mOI" id="Xwk-pR-CCg"/>
|
||||
<gridCell row="cJj-yp-Enp" column="a9F-Xp-86m" id="Cfs-Zz-VA6">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Naa-UR-FJH">
|
||||
<rect key="frame" x="85" y="471" width="76" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Naa-UR-FJH">
|
||||
<rect key="frame" x="94" y="393" width="76" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Server Host" id="g3k-Ab-Oin">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -128,8 +128,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="cJj-yp-Enp" column="XrQ-Tc-XCS" id="gUO-L2-R51">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VTW-w6-cOR">
|
||||
<rect key="frame" x="299" y="468" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VTW-w6-cOR">
|
||||
<rect key="frame" x="308" y="390" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="hcQ-Jk-ceh">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -139,8 +139,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="Wsq-Ny-R0E" column="LO3-Dh-mOI" id="fQT-0E-xvC"/>
|
||||
<gridCell row="Wsq-Ny-R0E" column="a9F-Xp-86m" id="CgG-pY-O5X">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MAC-gA-ioH">
|
||||
<rect key="frame" x="85" y="435" width="69" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MAC-gA-ioH">
|
||||
<rect key="frame" x="94" y="363" width="69" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Server SNI" id="bxG-gg-LTc">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -149,8 +149,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="Wsq-Ny-R0E" column="XrQ-Tc-XCS" id="dhv-f4-1Be">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5JO-ae-X9H">
|
||||
<rect key="frame" x="299" y="432" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5JO-ae-X9H">
|
||||
<rect key="frame" x="308" y="360" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="Blg-iu-XaZ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -158,10 +158,10 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="hyR-W9-a1z" column="LO3-Dh-mOI" id="uOI-bG-SCP">
|
||||
<gridCell row="hyR-W9-a1z" column="LO3-Dh-mOI" xPlacement="center" id="uOI-bG-SCP">
|
||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oW6-a4-bGz">
|
||||
<rect key="frame" x="-7" y="389" width="64" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Start" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KPU-2Q-dN7">
|
||||
<rect key="frame" x="11" y="324" width="62" height="36"/>
|
||||
<buttonCell key="cell" type="push" title="Start" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KPU-2Q-dN7">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
@@ -171,8 +171,8 @@
|
||||
</button>
|
||||
</gridCell>
|
||||
<gridCell row="hyR-W9-a1z" column="a9F-Xp-86m" id="3Tp-MP-Iuu">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FpN-6F-ejx">
|
||||
<rect key="frame" x="85" y="399" width="73" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FpN-6F-ejx">
|
||||
<rect key="frame" x="94" y="333" width="73" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Server Port" id="mcp-Vm-U1E">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -181,8 +181,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="hyR-W9-a1z" column="XrQ-Tc-XCS" id="iFI-Oq-jSi">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R0f-I9-5IS">
|
||||
<rect key="frame" x="299" y="396" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R0f-I9-5IS">
|
||||
<rect key="frame" x="308" y="330" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="aCt-xH-vPZ">
|
||||
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="4Fe-3g-QZ5">
|
||||
<real key="minimum" value="0.0"/>
|
||||
@@ -196,8 +196,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="pkr-kF-jbx" column="LO3-Dh-mOI" id="hax-GH-sFx"/>
|
||||
<gridCell row="pkr-kF-jbx" column="a9F-Xp-86m" id="6kp-AQ-bdX">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" verticalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="nkM-1Q-VtC">
|
||||
<rect key="frame" x="85" y="363" width="66" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" verticalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="nkM-1Q-VtC">
|
||||
<rect key="frame" x="94" y="303" width="66" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Username" id="QRy-PK-jJT">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -206,8 +206,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="pkr-kF-jbx" column="XrQ-Tc-XCS" id="qFw-l7-IDb">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="z07-tR-0U9">
|
||||
<rect key="frame" x="299" y="360" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="z07-tR-0U9">
|
||||
<rect key="frame" x="308" y="300" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="HAi-bY-2sC">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -217,8 +217,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="8qE-4c-4mw" column="LO3-Dh-mOI" id="MHm-pE-P6f"/>
|
||||
<gridCell row="8qE-4c-4mw" column="a9F-Xp-86m" id="6tg-qc-dBJ">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="O29-63-IKZ">
|
||||
<rect key="frame" x="85" y="327" width="63" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="O29-63-IKZ">
|
||||
<rect key="frame" x="94" y="273" width="63" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Password" id="9N4-Lw-6Ob">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -227,8 +227,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="8qE-4c-4mw" column="XrQ-Tc-XCS" id="Yil-mh-t4n">
|
||||
<secureTextField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0pr-Eo-W1k">
|
||||
<rect key="frame" x="299" y="324" width="188" height="21"/>
|
||||
<secureTextField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0pr-Eo-W1k">
|
||||
<rect key="frame" x="308" y="270" width="188" height="21"/>
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="EZ3-1U-Un3">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -241,8 +241,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="Ati-67-7pZ" column="LO3-Dh-mOI" id="2aB-Y2-dTP"/>
|
||||
<gridCell row="Ati-67-7pZ" column="a9F-Xp-86m" id="F3R-J3-yJX">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hCJ-rP-siw">
|
||||
<rect key="frame" x="85" y="290" width="94" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hCJ-rP-siw">
|
||||
<rect key="frame" x="94" y="242" width="94" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Cipher/Method" id="tOi-q9-yJY">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -251,8 +251,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="Ati-67-7pZ" column="XrQ-Tc-XCS" id="FXV-mY-iWS">
|
||||
<comboBox key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4xh-Ub-Yhf">
|
||||
<rect key="frame" x="298" y="286" width="192" height="23"/>
|
||||
<comboBox key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4xh-Ub-Yhf">
|
||||
<rect key="frame" x="307" y="238" width="192" height="23"/>
|
||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="10" id="qHI-jj-mpI">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -265,8 +265,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="Kh8-rv-NWX" column="LO3-Dh-mOI" id="IBD-OY-ImG"/>
|
||||
<gridCell row="Kh8-rv-NWX" column="a9F-Xp-86m" id="x9M-ta-sLa">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bDw-Ik-ckM">
|
||||
<rect key="frame" x="85" y="255" width="69" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bDw-Ik-ckM">
|
||||
<rect key="frame" x="94" y="213" width="69" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Local Host" id="rim-zj-Iub">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -275,8 +275,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="Kh8-rv-NWX" column="XrQ-Tc-XCS" id="0QG-0P-cDO">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Hzm-G4-aes">
|
||||
<rect key="frame" x="299" y="252" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Hzm-G4-aes">
|
||||
<rect key="frame" x="308" y="210" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="Z02-8g-7U6">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -284,10 +284,10 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="wLH-ke-dja" column="LO3-Dh-mOI" id="26B-As-jh6">
|
||||
<gridCell row="wLH-ke-dja" column="LO3-Dh-mOI" xPlacement="center" id="26B-As-jh6">
|
||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dAY-cJ-YEJ">
|
||||
<rect key="frame" x="-7" y="209" width="63" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Stop" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="JYa-MA-4KH">
|
||||
<rect key="frame" x="12" y="174" width="61" height="36"/>
|
||||
<buttonCell key="cell" type="push" title="Stop" bezelStyle="rounded" alignment="center" controlSize="large" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="JYa-MA-4KH">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
@@ -297,8 +297,8 @@
|
||||
</button>
|
||||
</gridCell>
|
||||
<gridCell row="wLH-ke-dja" column="a9F-Xp-86m" id="NRi-eF-70k">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7Lc-g6-Z1Z">
|
||||
<rect key="frame" x="85" y="219" width="65" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7Lc-g6-Z1Z">
|
||||
<rect key="frame" x="94" y="183" width="65" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Local Port" id="3bJ-wb-xnh">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -307,8 +307,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="wLH-ke-dja" column="XrQ-Tc-XCS" id="tY9-oE-V66">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="4ft-zv-tpp">
|
||||
<rect key="frame" x="299" y="216" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="4ft-zv-tpp">
|
||||
<rect key="frame" x="308" y="180" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="6eq-QO-A6b">
|
||||
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="uWT-vl-bd6">
|
||||
<real key="minimum" value="0.0"/>
|
||||
@@ -322,8 +322,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="nlG-nP-3oh" column="LO3-Dh-mOI" id="9jK-dz-vSF"/>
|
||||
<gridCell row="nlG-nP-3oh" column="a9F-Xp-86m" id="a7U-ff-9Pb">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2U7-zl-tc8">
|
||||
<rect key="frame" x="85" y="183" width="136" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2U7-zl-tc8">
|
||||
<rect key="frame" x="94" y="153" width="136" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="DNS over HTTPS URL" id="yxt-ql-TD8">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -332,8 +332,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="nlG-nP-3oh" column="XrQ-Tc-XCS" id="40l-GO-bgp">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VS4-tB-4bb">
|
||||
<rect key="frame" x="299" y="180" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VS4-tB-4bb">
|
||||
<rect key="frame" x="308" y="150" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="https://1.1.1.1/dns-query" drawsBackground="YES" id="IlA-i9-6tc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -343,8 +343,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="6aU-Cw-j5C" column="LO3-Dh-mOI" id="49x-3P-I1V"/>
|
||||
<gridCell row="6aU-Cw-j5C" column="a9F-Xp-86m" id="P0z-mH-Imd">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eZN-yT-YJS">
|
||||
<rect key="frame" x="85" y="147" width="121" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eZN-yT-YJS">
|
||||
<rect key="frame" x="94" y="123" width="121" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="DNS over TLS Host" id="PXx-nB-Hn1">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -353,8 +353,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="6aU-Cw-j5C" column="XrQ-Tc-XCS" id="QvK-s7-HnO">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LsY-AX-mE3">
|
||||
<rect key="frame" x="299" y="144" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LsY-AX-mE3">
|
||||
<rect key="frame" x="308" y="120" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="1.1.1.1" drawsBackground="YES" id="86y-sR-xrG">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -364,8 +364,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="qX1-aa-MLj" column="LO3-Dh-mOI" id="HLC-Y2-4bN"/>
|
||||
<gridCell row="qX1-aa-MLj" column="a9F-Xp-86m" id="dOz-Kf-ah3">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aOE-Cb-Jq7">
|
||||
<rect key="frame" x="85" y="110" width="65" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aOE-Cb-Jq7">
|
||||
<rect key="frame" x="94" y="92" width="65" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Limit Rate" id="Ux8-IL-FUS">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -374,8 +374,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="qX1-aa-MLj" column="XrQ-Tc-XCS" id="98I-JF-Dp3">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="exc-7i-jLy">
|
||||
<rect key="frame" x="299" y="108" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="exc-7i-jLy">
|
||||
<rect key="frame" x="308" y="90" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="10m" drawsBackground="YES" id="Xbb-ks-3E5">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -385,8 +385,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="mTL-cj-Nle" column="LO3-Dh-mOI" id="0zt-ie-sRL"/>
|
||||
<gridCell row="mTL-cj-Nle" column="a9F-Xp-86m" id="Pnu-WJ-mBn">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="AnO-ZT-CUz">
|
||||
<rect key="frame" x="85" y="75" width="54" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="AnO-ZT-CUz">
|
||||
<rect key="frame" x="94" y="63" width="54" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Timeout" id="zY6-tD-aUd">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -395,8 +395,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="mTL-cj-Nle" column="XrQ-Tc-XCS" id="NRI-fr-t3C">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d0Y-hk-xNM">
|
||||
<rect key="frame" x="299" y="72" width="188" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d0Y-hk-xNM">
|
||||
<rect key="frame" x="308" y="60" width="188" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="Srv-97-Ip1">
|
||||
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="gqX-zp-tFE">
|
||||
<real key="minimum" value="0.0"/>
|
||||
@@ -409,8 +409,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="e6X-BZ-bV8" column="LO3-Dh-mOI" id="5aI-Pb-YXS"/>
|
||||
<gridCell row="e6X-BZ-bV8" column="a9F-Xp-86m" id="xkv-I7-ILZ">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OYi-iS-mW2">
|
||||
<rect key="frame" x="85" y="36" width="66" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OYi-iS-mW2">
|
||||
<rect key="frame" x="94" y="30" width="66" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Auto Start" id="8hL-Qd-hQU">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -420,7 +420,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="e6X-BZ-bV8" column="XrQ-Tc-XCS" id="pI2-ba-pFT">
|
||||
<button key="contentView" verticalHuggingPriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="Cu9-FF-7Of">
|
||||
<rect key="frame" x="297" y="35" width="67" height="18"/>
|
||||
<rect key="frame" x="306" y="29" width="67" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="hei-7a-ZHr">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -432,8 +432,8 @@
|
||||
</gridCell>
|
||||
<gridCell row="1cJ-xv-Xd3" column="LO3-Dh-mOI" id="0ZG-UH-0MQ"/>
|
||||
<gridCell row="1cJ-xv-Xd3" column="a9F-Xp-86m" id="dvS-cU-tpD">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gsJ-2M-W13">
|
||||
<rect key="frame" x="85" y="0.0" width="87" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gsJ-2M-W13">
|
||||
<rect key="frame" x="94" y="0.0" width="87" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="System Proxy" id="g0k-mZ-0JW">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -443,7 +443,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="1cJ-xv-Xd3" column="XrQ-Tc-XCS" id="IsN-Qi-s8F">
|
||||
<button key="contentView" verticalHuggingPriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="fIt-Cr-IJG">
|
||||
<rect key="frame" x="297" y="-1" width="67" height="18"/>
|
||||
<rect key="frame" x="306" y="-1" width="67" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Jw2-My-hmB">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -491,11 +491,11 @@
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="OptionViewController" id="Rl3-9N-Ypa" customClass="OptionViewController" sceneMemberID="viewController">
|
||||
<view key="view" id="zIF-tN-wo1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="436" height="228"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="436" height="198"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<gridView xPlacement="leading" yPlacement="bottom" rowAlignment="none" rowSpacing="12" columnSpacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="XUN-Bn-cfn">
|
||||
<rect key="frame" x="12" y="12" width="412" height="204"/>
|
||||
<gridView xPlacement="leading" yPlacement="bottom" rowAlignment="none" columnSpacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="XUN-Bn-cfn">
|
||||
<rect key="frame" x="12" y="12" width="412" height="174"/>
|
||||
<constraints>
|
||||
<constraint firstItem="FCy-Ix-JtV" firstAttribute="trailing" secondItem="vKb-Fc-qV5" secondAttribute="trailing" id="IrF-yb-oaO"/>
|
||||
<constraint firstAttribute="trailing" secondItem="FCy-Ix-JtV" secondAttribute="trailing" constant="12" id="Lgf-n3-NC8"/>
|
||||
@@ -515,8 +515,8 @@
|
||||
</columns>
|
||||
<gridCells>
|
||||
<gridCell row="mrN-pz-1Oa" column="hxb-rW-bCk" id="NN6-Wm-nJC">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ntm-zj-sC8">
|
||||
<rect key="frame" x="-2" y="180" width="96" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ntm-zj-sC8">
|
||||
<rect key="frame" x="-2" y="150" width="96" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="TCP Keep Alive" id="z0q-m8-6KJ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -526,7 +526,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="mrN-pz-1Oa" column="BSc-hd-WXx" id="Opw-34-sct">
|
||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mtt-Vz-5jG">
|
||||
<rect key="frame" x="285" y="179" width="67" height="18"/>
|
||||
<rect key="frame" x="285" y="149" width="67" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="IpF-Ur-Zlh">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -534,8 +534,8 @@
|
||||
</button>
|
||||
</gridCell>
|
||||
<gridCell row="pro-5c-Rbh" column="hxb-rW-bCk" id="Zvf-RC-ruS">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BJp-Io-gl8">
|
||||
<rect key="frame" x="-2" y="144" width="137" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BJp-Io-gl8">
|
||||
<rect key="frame" x="-2" y="120" width="137" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="TCP Keep Alive Count" id="DwU-MU-ncE">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -544,8 +544,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="pro-5c-Rbh" column="BSc-hd-WXx" id="zdE-rB-Pec">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aaB-XL-no7">
|
||||
<rect key="frame" x="287" y="144" width="113" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aaB-XL-no7">
|
||||
<rect key="frame" x="287" y="120" width="113" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="8tD-KN-XwR">
|
||||
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="NCD-jR-QoX"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -555,8 +555,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="OaS-mO-GLn" column="hxb-rW-bCk" id="pJ7-Z4-dpM">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hCK-tE-t9g">
|
||||
<rect key="frame" x="-2" y="108" width="175" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hCK-tE-t9g">
|
||||
<rect key="frame" x="-2" y="90" width="175" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="TCP Keep Alive Idle Timeout" id="EnC-Oa-kda">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -565,8 +565,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="OaS-mO-GLn" column="BSc-hd-WXx" id="VAb-Vg-nQf">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vKb-Fc-qV5">
|
||||
<rect key="frame" x="287" y="108" width="113" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vKb-Fc-qV5">
|
||||
<rect key="frame" x="287" y="90" width="113" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="nOf-jN-DQX">
|
||||
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="NGY-o4-plc"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -576,8 +576,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="u9C-AX-ell" column="hxb-rW-bCk" id="Mki-MU-1Xs">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EQc-sT-cRe">
|
||||
<rect key="frame" x="-2" y="72" width="145" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EQc-sT-cRe">
|
||||
<rect key="frame" x="-2" y="60" width="145" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="TCP Keep Alive Interval" id="dCR-E3-G0W">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -586,8 +586,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="u9C-AX-ell" column="BSc-hd-WXx" id="uea-jg-zXU">
|
||||
<textField key="contentView" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FCy-Ix-JtV">
|
||||
<rect key="frame" x="287" y="72" width="113" height="21"/>
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FCy-Ix-JtV">
|
||||
<rect key="frame" x="287" y="60" width="113" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="fs7-4d-4EQ">
|
||||
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="KMj-84-Y99"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -597,8 +597,8 @@
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="dEK-1Q-llb" column="hxb-rW-bCk" id="yXv-wF-rtT">
|
||||
<textField key="contentView" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3br-w1-dtI">
|
||||
<rect key="frame" x="-2" y="36" width="270" height="16"/>
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3br-w1-dtI">
|
||||
<rect key="frame" x="-2" y="30" width="270" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Kyber post-quantum key agreement for TLS" id="EY5-8C-G6C">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -608,17 +608,17 @@
|
||||
</gridCell>
|
||||
<gridCell row="dEK-1Q-llb" column="BSc-hd-WXx" id="WnE-iw-kNO">
|
||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eCq-VL-0xN">
|
||||
<rect key="frame" x="285" y="35" width="67" height="18"/>
|
||||
<rect key="frame" x="285" y="29" width="67" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="aFJ-Zj-eao">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</gridCell>
|
||||
<gridCell row="7Cr-lG-X0w" column="hxb-rW-bCk" id="bjc-gh-Yad">
|
||||
<gridCell row="7Cr-lG-X0w" column="hxb-rW-bCk" xPlacement="trailing" id="bjc-gh-Yad">
|
||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DeI-uB-d4V">
|
||||
<rect key="frame" x="-7" y="-7" width="53" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yzs-Gu-p7Y">
|
||||
<rect key="frame" x="230" y="-6" width="51" height="36"/>
|
||||
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yzs-Gu-p7Y">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
@@ -632,8 +632,8 @@ DQ
|
||||
</gridCell>
|
||||
<gridCell row="7Cr-lG-X0w" column="BSc-hd-WXx" id="TvI-Ro-1ez">
|
||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="50U-gT-ab3">
|
||||
<rect key="frame" x="280" y="-7" width="76" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Mei-lK-JLB">
|
||||
<rect key="frame" x="281" y="-6" width="74" height="36"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Mei-lK-JLB">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
|
||||
@@ -374,8 +374,11 @@ CPUType GetCPUType() {
|
||||
|
||||
std::string GetModelIdentifier() {
|
||||
std::string return_string;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
gurl_base::mac::ScopedIOObject<io_service_t> platform_expert(
|
||||
IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")));
|
||||
#pragma clang diagnostic pop
|
||||
if (platform_expert) {
|
||||
ScopedCFTypeRef<CFDataRef> model_data(static_cast<CFDataRef>(
|
||||
IORegistryEntryCreateCFProperty(platform_expert, CFSTR("model"), kCFAllocatorDefault, 0)));
|
||||
@@ -414,8 +417,11 @@ std::string GetOSDisplayName() {
|
||||
}
|
||||
|
||||
std::string GetPlatformSerialNumber() {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
gurl_base::mac::ScopedIOObject<io_service_t> expert_device(
|
||||
IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")));
|
||||
#pragma clang diagnostic pop
|
||||
if (!expert_device) {
|
||||
DLOG(ERROR) << "Error retrieving the machine serial number.";
|
||||
return std::string();
|
||||
|
||||
@@ -20,7 +20,8 @@ OptionDialog::OptionDialog(QWidget* parent) : QDialog(parent) {
|
||||
|
||||
QGridLayout* grid = new QGridLayout;
|
||||
grid->setContentsMargins(12, 12, 12, 12);
|
||||
grid->setSpacing(12);
|
||||
grid->setHorizontalSpacing(12);
|
||||
grid->setVerticalSpacing(6);
|
||||
|
||||
auto tcp_keep_alive_label = new QLabel(tr("TCP keep alive"));
|
||||
auto tcp_keep_alive_cnt_label = new QLabel(tr("The number of TCP keep-alive probes"));
|
||||
|
||||
@@ -67,7 +67,8 @@ YASSWindow::YASSWindow(QWidget* parent) : QMainWindow(parent) {
|
||||
|
||||
QGridLayout* grid = new QGridLayout;
|
||||
grid->setContentsMargins(12, 12, 12, 12);
|
||||
grid->setSpacing(12);
|
||||
grid->setHorizontalSpacing(12);
|
||||
grid->setVerticalSpacing(6);
|
||||
|
||||
// Left (Column 0) << Grid << Vertical Box
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ BOOL CYassApp::InitInstance() {
|
||||
std::wstring frame_name = LoadStringStdW(m_hInstance, IDS_APP_TITLE);
|
||||
|
||||
UINT uDpi = Utils::GetDpiForWindowOrSystem(nullptr);
|
||||
RECT rect{0, 0, MULDIVDPI(530), MULDIVDPI(540)};
|
||||
RECT rect{0, 0, MULDIVDPI(500), MULDIVDPI(520)};
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
|
||||
int nCmdShow = absl::GetFlag(FLAGS_background) ? SW_HIDE : SW_SHOW;
|
||||
|
||||
@@ -35,25 +35,29 @@ __CRT_UUID_DECL(TrayIcon, 0x4324603D, 0x4274, 0x47AA, 0xBA, 0xD5, 0x7C, 0xF6, 0x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define INITIAL_COLUMN_ONE_LEFT 20
|
||||
#define INITIAL_COLUMN_TWO_LEFT 120
|
||||
#define INITIAL_COLUMN_THREE_LEFT 240
|
||||
|
||||
#define INITIAL_ROW_HEIGHT 12
|
||||
#define INITIAL_VERTICAL_HEIGHT 30
|
||||
|
||||
#define INITIAL_BUTTON_WIDTH 75
|
||||
#define INITIAL_BUTTON_WIDTH 80
|
||||
#define INITIAL_BUTTON_HEIGHT 30
|
||||
|
||||
#define INITIAL_LABEL_WIDTH 130
|
||||
#define INITIAL_LABEL_HEIGHT 25
|
||||
#define INITIAL_EDIT_WIDTH 220
|
||||
#define INITIAL_EDIT_HEIGHT 25
|
||||
#define INITIAL_LABEL_WIDTH 200
|
||||
#define INITIAL_LABEL_HEIGHT 24
|
||||
#define INITIAL_EDIT_WIDTH 160
|
||||
#define INITIAL_EDIT_HEIGHT 24
|
||||
#define INITIAL_STATUS_BAR_HEIGHT 20
|
||||
|
||||
static_assert(INITIAL_LABEL_HEIGHT == INITIAL_EDIT_HEIGHT);
|
||||
|
||||
#define INITIAL_COLUMN_ONE_LEFT 12
|
||||
#define INITIAL_COLUMN_TWO_LEFT (INITIAL_COLUMN_ONE_LEFT + INITIAL_BUTTON_WIDTH + 12)
|
||||
#define INITIAL_COLUMN_THREE_LEFT (INITIAL_COLUMN_TWO_LEFT + INITIAL_LABEL_WIDTH + 12)
|
||||
|
||||
#define COLUMN_ONE_LEFT MulDiv(INITIAL_COLUMN_ONE_LEFT, uDpi, 96)
|
||||
#define COLUMN_TWO_LEFT MulDiv(INITIAL_COLUMN_TWO_LEFT, uDpi, 96)
|
||||
#define COLUMN_THREE_LEFT MulDiv(INITIAL_COLUMN_THREE_LEFT, uDpi, 96)
|
||||
|
||||
#define ROW_HEIGHT MulDiv(INITIAL_ROW_HEIGHT, uDpi, 96)
|
||||
#define VERTICAL_HEIGHT MulDiv(INITIAL_VERTICAL_HEIGHT, uDpi, 96)
|
||||
|
||||
#define BUTTON_WIDTH MulDiv(INITIAL_BUTTON_WIDTH, uDpi, 96)
|
||||
@@ -841,124 +845,128 @@ void CYassFrame::UpdateLayoutForDpi(UINT uDpi) {
|
||||
// RIGHT Panel
|
||||
// Column 2
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 0;
|
||||
SetWindowPos(server_host_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 2;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 1;
|
||||
SetWindowPos(server_sni_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 3;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 2;
|
||||
SetWindowPos(server_port_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 4;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 3;
|
||||
SetWindowPos(username_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 5;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 4;
|
||||
SetWindowPos(password_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 6;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 5;
|
||||
SetWindowPos(method_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 7;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 6;
|
||||
SetWindowPos(local_host_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 8;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 7;
|
||||
SetWindowPos(local_port_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 9;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 8;
|
||||
SetWindowPos(doh_url_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 10;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 9;
|
||||
SetWindowPos(dot_host_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 11;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 10;
|
||||
SetWindowPos(limit_rate_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 12;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 11;
|
||||
SetWindowPos(timeout_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 13;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 12;
|
||||
SetWindowPos(autostart_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_TWO_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 14;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 13;
|
||||
SetWindowPos(systemproxy_label_, nullptr, rect.left, rect.top, LABEL_WIDTH, LABEL_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
// Column 3
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 0;
|
||||
SetWindowPos(server_host_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 2;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 1;
|
||||
SetWindowPos(server_sni_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 3;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 2;
|
||||
SetWindowPos(server_port_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 4;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 3;
|
||||
SetWindowPos(username_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 5;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 4;
|
||||
SetWindowPos(password_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
for (int i = 0, cnt = ComboBox_GetCount(method_combo_box_); i < cnt; ++i) {
|
||||
ComboBox_SetItemHeight(method_combo_box_, i, EDIT_HEIGHT);
|
||||
}
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 6;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 5;
|
||||
SetWindowPos(method_combo_box_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 7;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 6;
|
||||
SetWindowPos(local_host_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 8;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 7;
|
||||
SetWindowPos(local_port_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 9;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 8;
|
||||
SetWindowPos(doh_url_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 10;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 9;
|
||||
SetWindowPos(dot_host_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 11;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 10;
|
||||
SetWindowPos(limit_rate_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 12;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 11;
|
||||
SetWindowPos(timeout_edit_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 13;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 12;
|
||||
SetWindowPos(autostart_button_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
rect.left = client_rect.left + COLUMN_THREE_LEFT;
|
||||
rect.top = client_rect.top + VERTICAL_HEIGHT * 14;
|
||||
rect.top = client_rect.top + ROW_HEIGHT + VERTICAL_HEIGHT * 13;
|
||||
SetWindowPos(systemproxy_button_, nullptr, rect.left, rect.top, EDIT_WIDTH, EDIT_HEIGHT,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
|
||||
@@ -166,6 +166,14 @@ _NSIG_TESTS = [
|
||||
'https://www.youtube.com/s/player/b22ef6e7/player_ias.vflset/en_US/base.js',
|
||||
'b6HcntHGkvBLk_FRf', 'kNPW6A7FyP2l8A',
|
||||
),
|
||||
(
|
||||
'https://www.youtube.com/s/player/3400486c/player_ias.vflset/en_US/base.js',
|
||||
'lL46g3XifCKUZn1Xfw', 'z767lhet6V2Skl',
|
||||
),
|
||||
(
|
||||
'https://www.youtube.com/s/player/5604538d/player_ias.vflset/en_US/base.js',
|
||||
'7X-he4jjvMx7BCX', 'sViSydX8IHtdWA',
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1647,7 +1647,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||
except JSInterpreter.Exception as e:
|
||||
self.report_warning(
|
||||
'%s (%s %s)' % (
|
||||
'Unable to decode n-parameter: download likely to be throttled',
|
||||
'Unable to decode n-parameter: expect download to be blocked or throttled',
|
||||
error_to_compat_str(e),
|
||||
traceback.format_exc()),
|
||||
video_id=video_id)
|
||||
@@ -1659,18 +1659,22 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||
def _extract_n_function_name(self, jscode):
|
||||
func_name, idx = self._search_regex(
|
||||
# new: (b=String.fromCharCode(110),c=a.get(b))&&c=nfunc[idx](c)
|
||||
# or: (b="nn"[+a.D],c=a.get(b))&&(c=nfunc[idx](c)s
|
||||
# old: .get("n"))&&(b=nfunc[idx](b)
|
||||
# older: .get("n"))&&(b=nfunc(b)
|
||||
r'''(?x)
|
||||
(?:\(\s*(?P<b>[a-z])\s*=\s*String\s*\.\s*fromCharCode\s*\(\s*110\s*\)\s*,(?P<c>[a-z])\s*=\s*[a-z]\s*)?
|
||||
\.\s*get\s*\(\s*(?(b)(?P=b)|"n")(?:\s*\)){2}\s*&&\s*\(\s*(?(c)(?P=c)|b)\s*=\s*
|
||||
(?:\(\s*(?P<b>[a-z])\s*=\s*(?:
|
||||
String\s*\.\s*fromCharCode\s*\(\s*110\s*\)|
|
||||
"n+"\[\s*\+?s*[\w$.]+\s*]
|
||||
)\s*,(?P<c>[a-z])\s*=\s*[a-z]\s*)?
|
||||
\.\s*get\s*\(\s*(?(b)(?P=b)|"n{1,2}")(?:\s*\)){2}\s*&&\s*\(\s*(?(c)(?P=c)|b)\s*=\s*
|
||||
(?P<nfunc>[a-zA-Z_$][\w$]*)(?:\s*\[(?P<idx>\d+)\])?\s*\(\s*[\w$]+\s*\)
|
||||
''', jscode, 'Initial JS player n function name', group=('nfunc', 'idx'))
|
||||
if not idx:
|
||||
return func_name
|
||||
|
||||
return self._parse_json(self._search_regex(
|
||||
r'var {0}\s*=\s*(\[.+?\])\s*[,;]'.format(re.escape(func_name)), jscode,
|
||||
r'var\s+{0}\s*=\s*(\[.+?\])\s*[,;]'.format(re.escape(func_name)), jscode,
|
||||
'Initial JS player n function list ({0}.{1})'.format(func_name, idx)),
|
||||
func_name, transform_source=js_to_json)[int(idx)]
|
||||
|
||||
|
||||
@@ -4,6 +4,19 @@
|
||||
# To create a release, dispatch the https://github.com/yt-dlp/yt-dlp/actions/workflows/release.yml workflow on master
|
||||
-->
|
||||
|
||||
### 2024.07.25
|
||||
|
||||
#### Extractor changes
|
||||
- **abematv**: [Adapt key retrieval to request handler framework](https://github.com/yt-dlp/yt-dlp/commit/a3bab4752a2b3d56e5a59b4e0411bb8f695c010b) ([#10491](https://github.com/yt-dlp/yt-dlp/issues/10491)) by [bashonly](https://github.com/bashonly)
|
||||
- **facebook**: [Fix extraction](https://github.com/yt-dlp/yt-dlp/commit/1a34a802f44a1dab8f642c79c3cc810e21541d3b) ([#10531](https://github.com/yt-dlp/yt-dlp/issues/10531)) by [bashonly](https://github.com/bashonly)
|
||||
- **mlbtv**: [Fix extractor](https://github.com/yt-dlp/yt-dlp/commit/f0993391e6052ec8f7aacc286609564f226943b9) ([#10515](https://github.com/yt-dlp/yt-dlp/issues/10515)) by [bashonly](https://github.com/bashonly)
|
||||
- **tiktok**: [Fix and deprioritize JSON subtitles](https://github.com/yt-dlp/yt-dlp/commit/2f97779f335ac069ecccd9c7bf81abf4a83cfe7a) ([#10516](https://github.com/yt-dlp/yt-dlp/issues/10516)) by [bashonly](https://github.com/bashonly)
|
||||
- **vimeo**: [Fix chapters extraction](https://github.com/yt-dlp/yt-dlp/commit/a0a1bc3d8d8e3bb9a48a06e835815a0460e90e77) ([#10544](https://github.com/yt-dlp/yt-dlp/issues/10544)) by [bashonly](https://github.com/bashonly)
|
||||
- **youtube**: [Fix `n` function name extraction for player `3400486c`](https://github.com/yt-dlp/yt-dlp/commit/713b4cd18f00556771af8cfdd9cea6cc1a09e948) ([#10542](https://github.com/yt-dlp/yt-dlp/issues/10542)) by [bashonly](https://github.com/bashonly)
|
||||
|
||||
#### Misc. changes
|
||||
- **build**: [Pin `setuptools` version](https://github.com/yt-dlp/yt-dlp/commit/e046db8a116b1c320d4785daadd48ea0b22a3987) ([#10493](https://github.com/yt-dlp/yt-dlp/issues/10493)) by [bashonly](https://github.com/bashonly)
|
||||
|
||||
### 2024.07.16
|
||||
|
||||
#### Core changes
|
||||
|
||||
+180
-43
@@ -1,16 +1,21 @@
|
||||
import json
|
||||
import re
|
||||
import urllib.parse
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..networking.exceptions import HTTPError
|
||||
from ..utils import (
|
||||
ExtractorError,
|
||||
determine_ext,
|
||||
int_or_none,
|
||||
join_nonempty,
|
||||
jwt_decode_hs256,
|
||||
parse_duration,
|
||||
parse_iso8601,
|
||||
try_get,
|
||||
url_or_none,
|
||||
urlencode_postdata,
|
||||
)
|
||||
from ..utils.traversal import traverse_obj
|
||||
|
||||
@@ -276,81 +281,213 @@ class MLBVideoIE(MLBBaseIE):
|
||||
class MLBTVIE(InfoExtractor):
|
||||
_VALID_URL = r'https?://(?:www\.)?mlb\.com/tv/g(?P<id>\d{6})'
|
||||
_NETRC_MACHINE = 'mlb'
|
||||
|
||||
_TESTS = [{
|
||||
'url': 'https://www.mlb.com/tv/g661581/vee2eff5f-a7df-4c20-bdb4-7b926fa12638',
|
||||
'info_dict': {
|
||||
'id': '661581',
|
||||
'ext': 'mp4',
|
||||
'title': '2022-07-02 - St. Louis Cardinals @ Philadelphia Phillies',
|
||||
'release_date': '20220702',
|
||||
'release_timestamp': 1656792300,
|
||||
},
|
||||
'params': {
|
||||
'skip_download': True,
|
||||
},
|
||||
}]
|
||||
_GRAPHQL_INIT_QUERY = '''\
|
||||
mutation initSession($device: InitSessionInput!, $clientType: ClientType!, $experience: ExperienceTypeInput) {
|
||||
initSession(device: $device, clientType: $clientType, experience: $experience) {
|
||||
deviceId
|
||||
sessionId
|
||||
entitlements {
|
||||
code
|
||||
}
|
||||
location {
|
||||
countryCode
|
||||
regionName
|
||||
zipCode
|
||||
latitude
|
||||
longitude
|
||||
}
|
||||
clientExperience
|
||||
features
|
||||
}
|
||||
}'''
|
||||
_GRAPHQL_PLAYBACK_QUERY = '''\
|
||||
mutation initPlaybackSession(
|
||||
$adCapabilities: [AdExperienceType]
|
||||
$mediaId: String!
|
||||
$deviceId: String!
|
||||
$sessionId: String!
|
||||
$quality: PlaybackQuality
|
||||
) {
|
||||
initPlaybackSession(
|
||||
adCapabilities: $adCapabilities
|
||||
mediaId: $mediaId
|
||||
deviceId: $deviceId
|
||||
sessionId: $sessionId
|
||||
quality: $quality
|
||||
) {
|
||||
playbackSessionId
|
||||
playback {
|
||||
url
|
||||
token
|
||||
expiration
|
||||
cdn
|
||||
}
|
||||
}
|
||||
}'''
|
||||
_APP_VERSION = '7.8.2'
|
||||
_device_id = None
|
||||
_session_id = None
|
||||
_access_token = None
|
||||
_token_expiry = 0
|
||||
|
||||
@property
|
||||
def _api_headers(self):
|
||||
if (self._token_expiry - 120) <= time.time():
|
||||
self.write_debug('Access token has expired; re-logging in')
|
||||
self._perform_login(*self._get_login_info())
|
||||
return {'Authorization': f'Bearer {self._access_token}'}
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self._access_token:
|
||||
self.raise_login_required(
|
||||
'All videos are only available to registered users', method='password')
|
||||
|
||||
def _set_device_id(self, username):
|
||||
if not self._device_id:
|
||||
self._device_id = self.cache.load(
|
||||
self._NETRC_MACHINE, 'device_ids', default={}).get(username)
|
||||
if self._device_id:
|
||||
return
|
||||
self._device_id = str(uuid.uuid4())
|
||||
self.cache.store(self._NETRC_MACHINE, 'device_ids', {username: self._device_id})
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
data = f'grant_type=password&username={urllib.parse.quote(username)}&password={urllib.parse.quote(password)}&scope=openid offline_access&client_id=0oa3e1nutA1HLzAKG356'
|
||||
access_token = self._download_json(
|
||||
'https://ids.mlb.com/oauth2/aus1m088yK07noBfh356/v1/token', None,
|
||||
headers={
|
||||
'User-Agent': 'okhttp/3.12.1',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}, data=data.encode())['access_token']
|
||||
try:
|
||||
self._access_token = self._download_json(
|
||||
'https://ids.mlb.com/oauth2/aus1m088yK07noBfh356/v1/token', None,
|
||||
'Logging in', 'Unable to log in', headers={
|
||||
'User-Agent': 'okhttp/3.12.1',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}, data=urlencode_postdata({
|
||||
'grant_type': 'password',
|
||||
'username': username,
|
||||
'password': password,
|
||||
'scope': 'openid offline_access',
|
||||
'client_id': '0oa3e1nutA1HLzAKG356',
|
||||
}))['access_token']
|
||||
except ExtractorError as error:
|
||||
if isinstance(error.cause, HTTPError) and error.cause.status == 400:
|
||||
raise ExtractorError('Invalid username or password', expected=True)
|
||||
raise
|
||||
|
||||
entitlement = self._download_webpage(
|
||||
f'https://media-entitlement.mlb.com/api/v3/jwt?os=Android&appname=AtBat&did={uuid.uuid4()}', None,
|
||||
headers={
|
||||
'User-Agent': 'okhttp/3.12.1',
|
||||
'Authorization': f'Bearer {access_token}',
|
||||
})
|
||||
self._token_expiry = traverse_obj(self._access_token, ({jwt_decode_hs256}, 'exp', {int})) or 0
|
||||
self._set_device_id(username)
|
||||
|
||||
data = f'grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token={entitlement}&subject_token_type=urn:ietf:params:oauth:token-type:jwt&platform=android-tv'
|
||||
self._access_token = self._download_json(
|
||||
'https://us.edge.bamgrid.com/token', None,
|
||||
self._session_id = self._call_api({
|
||||
'operationName': 'initSession',
|
||||
'query': self._GRAPHQL_INIT_QUERY,
|
||||
'variables': {
|
||||
'device': {
|
||||
'appVersion': self._APP_VERSION,
|
||||
'deviceFamily': 'desktop',
|
||||
'knownDeviceId': self._device_id,
|
||||
'languagePreference': 'ENGLISH',
|
||||
'manufacturer': '',
|
||||
'model': '',
|
||||
'os': '',
|
||||
'osVersion': '',
|
||||
},
|
||||
'clientType': 'WEB',
|
||||
},
|
||||
}, None, 'session ID')['data']['initSession']['sessionId']
|
||||
|
||||
def _call_api(self, data, video_id, description='GraphQL JSON', fatal=True):
|
||||
return self._download_json(
|
||||
'https://media-gateway.mlb.com/graphql', video_id,
|
||||
f'Downloading {description}', f'Unable to download {description}', fatal=fatal,
|
||||
headers={
|
||||
**self._api_headers,
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer bWxidHYmYW5kcm9pZCYxLjAuMA.6LZMbH2r--rbXcgEabaDdIslpo4RyZrlVfWZhsAgXIk',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}, data=data.encode())['access_token']
|
||||
'Content-Type': 'application/json',
|
||||
'x-client-name': 'WEB',
|
||||
'x-client-version': self._APP_VERSION,
|
||||
}, data=json.dumps(data, separators=(',', ':')).encode())
|
||||
|
||||
def _extract_formats_and_subtitles(self, broadcast, video_id):
|
||||
feed = traverse_obj(broadcast, ('homeAway', {str.title}))
|
||||
medium = traverse_obj(broadcast, ('type', {str}))
|
||||
language = traverse_obj(broadcast, ('language', {str.lower}))
|
||||
format_id = join_nonempty(feed, medium, language)
|
||||
|
||||
response = self._call_api({
|
||||
'operationName': 'initPlaybackSession',
|
||||
'query': self._GRAPHQL_PLAYBACK_QUERY,
|
||||
'variables': {
|
||||
'adCapabilities': ['GOOGLE_STANDALONE_AD_PODS'],
|
||||
'deviceId': self._device_id,
|
||||
'mediaId': broadcast['mediaId'],
|
||||
'quality': 'PLACEHOLDER',
|
||||
'sessionId': self._session_id,
|
||||
},
|
||||
}, video_id, f'{format_id} broadcast JSON', fatal=False)
|
||||
|
||||
playback = traverse_obj(response, ('data', 'initPlaybackSession', 'playback', {dict}))
|
||||
m3u8_url = traverse_obj(playback, ('url', {url_or_none}))
|
||||
token = traverse_obj(playback, ('token', {str}))
|
||||
|
||||
if not (m3u8_url and token):
|
||||
errors = '; '.join(traverse_obj(response, ('errors', ..., 'message', {str})))
|
||||
if 'not entitled' in errors:
|
||||
raise ExtractorError(errors, expected=True)
|
||||
elif errors: # Only warn when 'blacked out' since radio formats are available
|
||||
self.report_warning(f'API returned errors for {format_id}: {errors}')
|
||||
else:
|
||||
self.report_warning(f'No formats available for {format_id} broadcast; skipping')
|
||||
return [], {}
|
||||
|
||||
cdn_headers = {'x-cdn-token': token}
|
||||
fmts, subs = self._extract_m3u8_formats_and_subtitles(
|
||||
m3u8_url.replace(f'/{token}/', '/'), video_id, 'mp4',
|
||||
m3u8_id=format_id, fatal=False, headers=cdn_headers)
|
||||
for fmt in fmts:
|
||||
fmt['http_headers'] = cdn_headers
|
||||
fmt.setdefault('format_note', join_nonempty(feed, medium, delim=' '))
|
||||
fmt.setdefault('language', language)
|
||||
if fmt.get('vcodec') == 'none' and fmt['language'] == 'en':
|
||||
fmt['source_preference'] = 10
|
||||
|
||||
return fmts, subs
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
airings = self._download_json(
|
||||
f'https://search-api-mlbtv.mlb.com/svc/search/v2/graphql/persisted/query/core/Airings?variables=%7B%22partnerProgramIds%22%3A%5B%22{video_id}%22%5D%2C%22applyEsniMediaRightsLabels%22%3Atrue%7D',
|
||||
video_id)['data']['Airings']
|
||||
metadata = traverse_obj(self._download_json(
|
||||
'https://statsapi.mlb.com/api/v1/schedule', video_id, query={
|
||||
'gamePk': video_id,
|
||||
'hydrate': 'broadcasts(all),statusFlags',
|
||||
}), ('dates', ..., 'games', lambda _, v: str(v['gamePk']) == video_id and v['broadcasts'], any))
|
||||
|
||||
broadcasts = traverse_obj(metadata, (
|
||||
'broadcasts', lambda _, v: v['mediaId'] and v['mediaState']['mediaStateCode'] != 'MEDIA_OFF'))
|
||||
|
||||
formats, subtitles = [], {}
|
||||
for airing in traverse_obj(airings, lambda _, v: v['playbackUrls'][0]['href']):
|
||||
format_id = join_nonempty('feedType', 'feedLanguage', from_dict=airing)
|
||||
m3u8_url = traverse_obj(self._download_json(
|
||||
airing['playbackUrls'][0]['href'].format(scenario='browser~csai'), video_id,
|
||||
note=f'Downloading {format_id} stream info JSON',
|
||||
errnote=f'Failed to download {format_id} stream info, skipping',
|
||||
fatal=False, headers={
|
||||
'Authorization': self._access_token,
|
||||
'Accept': 'application/vnd.media-service+json; version=2',
|
||||
}), ('stream', 'complete', {url_or_none}))
|
||||
if not m3u8_url:
|
||||
continue
|
||||
f, s = self._extract_m3u8_formats_and_subtitles(
|
||||
m3u8_url, video_id, 'mp4', m3u8_id=format_id, fatal=False)
|
||||
formats.extend(f)
|
||||
self._merge_subtitles(s, target=subtitles)
|
||||
for broadcast in broadcasts:
|
||||
fmts, subs = self._extract_formats_and_subtitles(broadcast, video_id)
|
||||
formats.extend(fmts)
|
||||
self._merge_subtitles(subs, target=subtitles)
|
||||
|
||||
return {
|
||||
'id': video_id,
|
||||
'title': traverse_obj(airings, (..., 'titles', 0, 'episodeName'), get_all=False),
|
||||
'is_live': traverse_obj(airings, (..., 'mediaConfig', 'productType'), get_all=False) == 'LIVE',
|
||||
'title': join_nonempty(
|
||||
traverse_obj(metadata, ('officialDate', {str})),
|
||||
traverse_obj(metadata, ('teams', ('away', 'home'), 'team', 'name', {str}, all, {' @ '.join})),
|
||||
delim=' - '),
|
||||
'is_live': traverse_obj(broadcasts, (..., 'mediaState', 'mediaStateCode', {str}, any)) == 'MEDIA_ON',
|
||||
'release_timestamp': traverse_obj(metadata, ('gameDate', {parse_iso8601})),
|
||||
'formats': formats,
|
||||
'subtitles': subtitles,
|
||||
'http_headers': {'Authorization': f'Bearer {self._access_token}'},
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Autogenerated by devscripts/update-version.py
|
||||
|
||||
__version__ = '2024.07.16'
|
||||
__version__ = '2024.07.25'
|
||||
|
||||
RELEASE_GIT_HEAD = '89a161e8c62569a662deda1c948664152efcb6b4'
|
||||
RELEASE_GIT_HEAD = 'f0993391e6052ec8f7aacc286609564f226943b9'
|
||||
|
||||
VARIANT = None
|
||||
|
||||
@@ -12,4 +12,4 @@ CHANNEL = 'stable'
|
||||
|
||||
ORIGIN = 'yt-dlp/yt-dlp'
|
||||
|
||||
_pkg_version = '2024.07.16'
|
||||
_pkg_version = '2024.07.25'
|
||||
|
||||
Reference in New Issue
Block a user