Compare commits
91 Commits
v0.62.6
...
v0.63.3-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4319745c52 | ||
|
|
69d2b36788 | ||
|
|
eebc785e4c | ||
|
|
d109220e0d | ||
|
|
a88a2e601d | ||
|
|
7cefb16086 | ||
|
|
c2c30f6615 | ||
|
|
bf9a1091e3 | ||
|
|
e1f1a706a6 | ||
|
|
75ebaabc2c | ||
|
|
d608331f08 | ||
|
|
448c472ee6 | ||
|
|
370a6f3dbd | ||
|
|
d8685baa47 | ||
|
|
6a07f59d34 | ||
|
|
7981cd45ed | ||
|
|
66b1283c95 | ||
|
|
d275474b23 | ||
|
|
86057ab071 | ||
|
|
aafc3a9584 | ||
|
|
dc657a647e | ||
|
|
e5f0965138 | ||
|
|
b2b25acc4c | ||
|
|
0b79950510 | ||
|
|
d6d1e20f07 | ||
|
|
c58abf1b0b | ||
|
|
88d2e2e277 | ||
|
|
946c92667f | ||
|
|
f54f653d42 | ||
|
|
ef72c75fab | ||
|
|
c6e52dbef7 | ||
|
|
62547e87dd | ||
|
|
eb6b545eeb | ||
|
|
4c4ebbfa19 | ||
|
|
61f31bf010 | ||
|
|
495fd151f5 | ||
|
|
482a5bb02a | ||
|
|
4e35b26365 | ||
|
|
c180137e02 | ||
|
|
ef837232bc | ||
|
|
d0aa9f1c57 | ||
|
|
aa549d1da7 | ||
|
|
259a758849 | ||
|
|
7ac45379eb | ||
|
|
0940482c62 | ||
|
|
9cbb698b96 | ||
|
|
1820be4990 | ||
|
|
37ca232548 | ||
|
|
ea9b009a22 | ||
|
|
dbc804669c | ||
|
|
c8fbc0d348 | ||
|
|
8361b4d47a | ||
|
|
ae2021e073 | ||
|
|
c4b21a0ab5 | ||
|
|
8a095d0a55 | ||
|
|
c0bf8fd6a8 | ||
|
|
14329980e1 | ||
|
|
950626fe9e | ||
|
|
8b7e587467 | ||
|
|
552ebc0f29 | ||
|
|
9148e1d30a | ||
|
|
9156d488ca | ||
|
|
e1ac1675ea | ||
|
|
863250904b | ||
|
|
8a926c4a23 | ||
|
|
760cceb378 | ||
|
|
c5650f9334 | ||
|
|
bf968707df | ||
|
|
31fa7ca90c | ||
|
|
309f401015 | ||
|
|
33d02cedd7 | ||
|
|
daa75b5282 | ||
|
|
36c64045ae | ||
|
|
93e1e30323 | ||
|
|
9b69f9a3ff | ||
|
|
d5fbb59656 | ||
|
|
7ba95d5d6c | ||
|
|
d79aeba2c1 | ||
|
|
672b445676 | ||
|
|
e02199fa2a | ||
|
|
9e55051811 | ||
|
|
7db176a763 | ||
|
|
92886236a2 | ||
|
|
8d94de8eb2 | ||
|
|
eaebec88c0 | ||
|
|
22fa6c07dd | ||
|
|
afe9ab9d8c | ||
|
|
16139cc6b6 | ||
|
|
31a904d370 | ||
|
|
02cf7679a3 | ||
|
|
d85d4de218 |
4
.github/workflows/ci.yml
vendored
@@ -4,6 +4,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "v*"
|
||||
tags:
|
||||
- "v*"
|
||||
pull_request:
|
||||
@@ -52,12 +53,13 @@ jobs:
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- bundle
|
||||
if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') }}
|
||||
needs: tests
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
|
||||
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
ZED_AMPLITUDE_API_KEY: ${{ secrets.ZED_AMPLITUDE_API_KEY }}
|
||||
ZED_MIXPANEL_TOKEN: ${{ secrets.ZED_MIXPANEL_TOKEN }}
|
||||
steps:
|
||||
- name: Install Rust
|
||||
|
||||
18
.github/workflows/release_actions.yml
vendored
@@ -8,19 +8,20 @@ jobs:
|
||||
steps:
|
||||
- name: Discord Webhook Action
|
||||
uses: tsickert/discord-webhook@v5.3.0
|
||||
if: ${{ ! github.event.release.prerelease }}
|
||||
with:
|
||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
content: |
|
||||
📣 Zed ${{ github.event.release.tag_name }} was just released!
|
||||
|
||||
|
||||
Restart your Zed or head to https://zed.dev/releases to grab it.
|
||||
|
||||
|
||||
```md
|
||||
### Changelog
|
||||
|
||||
|
||||
${{ github.event.release.body }}
|
||||
```
|
||||
amplitude_release:
|
||||
mixpanel_release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -29,5 +30,10 @@ jobs:
|
||||
python-version: "3.10.5"
|
||||
architecture: "x64"
|
||||
cache: "pip"
|
||||
- run: pip install -r script/amplitude_release/requirements.txt
|
||||
- run: python script/amplitude_release/main.py ${{ github.event.release.tag_name }} ${{ secrets.ZED_AMPLITUDE_API_KEY }} ${{ secrets.ZED_AMPLITUDE_SECRET_KEY }}
|
||||
- run: pip install -r script/mixpanel_release/requirements.txt
|
||||
- run: >
|
||||
python script/mixpanel_release/main.py
|
||||
${{ github.event.release.tag_name }}
|
||||
${{ secrets.MIXPANEL_PROJECT_ID }}
|
||||
${{ secrets.MIXPANEL_SERVICE_ACCOUNT_USERNAME }}
|
||||
${{ secrets.MIXPANEL_SERVICE_ACCOUNT_SECRET }}
|
||||
|
||||
9
Cargo.lock
generated
@@ -4839,8 +4839,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rusqlite_migration"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eda44233be97aea786691f9f6f7ef230bcf905061f4012e90f4f39e6dcf31163"
|
||||
source = "git+https://github.com/cljoly/rusqlite_migration?rev=c433555d7c1b41b103426e35756eb3144d0ebbc6#c433555d7c1b41b103426e35756eb3144d0ebbc6"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rusqlite",
|
||||
@@ -6494,9 +6493,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-rust"
|
||||
version = "0.20.1"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13470fafb7327a3acf96f5bc1013b5539a899a182f01c59b5af53f6b93195717"
|
||||
checksum = "797842733e252dc11ae5d403a18060bf337b822fc2ae5ddfaa6ff4d9cc20bda6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
@@ -7629,7 +7628,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.62.0"
|
||||
version = "0.63.3"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"anyhow",
|
||||
|
||||
1
Procfile
@@ -1,2 +1,3 @@
|
||||
web: cd ../zed.dev && PORT=3000 npx vercel dev
|
||||
collab: cd crates/collab && cargo run serve
|
||||
livekit: livekit-server --dev
|
||||
45
README.md
@@ -6,36 +6,43 @@ Welcome to Zed, a lightning-fast, collaborative code editor that makes your drea
|
||||
|
||||
## Development tips
|
||||
|
||||
### Dependencies
|
||||
|
||||
* Install [Postgres.app](https://postgresapp.com) and start it.
|
||||
* Install the `LiveKit` server and the `foreman` process supervisor:
|
||||
|
||||
```
|
||||
brew install livekit
|
||||
brew install foreman
|
||||
```
|
||||
|
||||
* Ensure the Zed.dev website is checked out in a sibling directory:
|
||||
|
||||
```
|
||||
cd ..
|
||||
git clone https://github.com/zed-industries/zed.dev
|
||||
```
|
||||
|
||||
* Set up a local `zed` database and seed it with some initial users:
|
||||
|
||||
```
|
||||
script/bootstrap
|
||||
```
|
||||
|
||||
### Testing against locally-running servers
|
||||
|
||||
Make sure you have `zed.dev` cloned as a sibling to this repo.
|
||||
Start the web and collab servers:
|
||||
|
||||
```
|
||||
cd ..
|
||||
git clone https://github.com/zed-industries/zed.dev
|
||||
```
|
||||
|
||||
Make sure your local database is created, migrated, and seeded with initial data. Install [Postgres](https://postgresapp.com), then from the `zed` repository root, run:
|
||||
|
||||
```
|
||||
script/sqlx database create
|
||||
script/sqlx migrate run
|
||||
script/seed-db
|
||||
```
|
||||
|
||||
Run the web frontend and the collaboration server.
|
||||
|
||||
```
|
||||
brew install foreman
|
||||
foreman start
|
||||
```
|
||||
|
||||
If you want to run Zed pointed at the local servers, you can run:
|
||||
|
||||
```
|
||||
script/zed_with_local_servers
|
||||
script/zed-with-local-servers
|
||||
# or...
|
||||
script/zed_with_local_servers --release
|
||||
script/zed-with-local-servers --release
|
||||
```
|
||||
|
||||
### Dump element JSON
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1271)">
|
||||
<path d="M10.9007 7.45347L6.60649 11.7477C6.44009 11.9168 6.22001 12 5.99993 12C5.77985 12 5.56031 11.9161 5.39283 11.7484L1.09859 7.45414C0.763098 7.11865 0.763098 6.57516 1.09859 6.23967C1.43407 5.90419 1.97756 5.90419 2.31305 6.23967L5.14108 9.06904V0.834694C5.14108 0.359912 5.52568 0 5.97577 0C6.42587 0 6.85878 0.359912 6.85878 0.834694V9.06891L9.68761 6.24008C10.0231 5.90459 10.5666 5.90459 10.9021 6.24008C11.2376 6.57556 11.2362 7.11771 10.9007 7.4532V7.45347Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1271">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 590 B After Width: | Height: | Size: 734 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.0538 9.45347L8.75952 13.7477C8.59312 13.9168 8.37304 14 8.15296 14C7.93288 14 7.71334 13.9161 7.54586 13.7484L3.25162 9.45414C2.91613 9.11865 2.91613 8.57516 3.25162 8.23967C3.5871 7.90419 4.13059 7.90419 4.46608 8.23967L7.29411 11.069V2.83469C7.29411 2.35991 7.67871 2 8.1288 2C8.5789 2 9.01181 2.35991 9.01181 2.83469V11.0689L11.8406 8.24008C12.1761 7.90459 12.7196 7.90459 13.0551 8.24008C13.3906 8.57556 13.3893 9.11771 13.0538 9.4532V9.45347Z" fill="white"/>
|
||||
<path d="M13.0538 9.45347L8.75952 13.7477C8.59312 13.9168 8.37304 14 8.15296 14C7.93288 14 7.71334 13.9161 7.54586 13.7484L3.25162 9.45414C2.91613 9.11865 2.91613 8.57516 3.25162 8.23967C3.5871 7.90418 4.13059 7.90418 4.46608 8.23967L7.29411 11.069V2.83469C7.29411 2.35991 7.67871 2 8.12881 2C8.5789 2 9.01181 2.35991 9.01181 2.83469V11.0689L11.8406 8.24008C12.1761 7.90459 12.7196 7.90459 13.0551 8.24008C13.3906 8.57556 13.3893 9.11771 13.0538 9.4532V9.45347Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 580 B After Width: | Height: | Size: 581 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1354)">
|
||||
<path d="M7.26716 4.96898L4.40433 7.83181C4.2934 7.94453 4.14668 8 3.99996 8C3.85324 8 3.70688 7.94409 3.59523 7.83226L0.732395 4.96943C0.508737 4.74577 0.508737 4.38344 0.732395 4.15978C0.956054 3.93612 1.31838 3.93612 1.54204 4.15978L3.42739 6.04603V0.556463C3.42739 0.239941 3.68379 0 3.98385 0C4.28392 0 4.57252 0.239941 4.57252 0.556463V6.04594L6.45841 4.16005C6.68207 3.93639 7.0444 3.93639 7.26806 4.16005C7.49172 4.38371 7.49082 4.74514 7.26716 4.9688V4.96898Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1354">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 584 B After Width: | Height: | Size: 726 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1272)">
|
||||
<path d="M12 6.00001C12 6.47507 11.6403 6.85889 11.1653 6.85889H2.93347L5.7624 9.68781C6.0979 10.0233 6.0979 10.5668 5.7624 10.9023C5.59331 11.0701 5.37322 11.1533 5.15313 11.1533C4.93305 11.1533 4.71349 11.0694 4.54601 10.9017L0.251624 6.60726C-0.0838748 6.27176 -0.0838748 5.72825 0.251624 5.39275L4.54601 1.09837C4.88151 0.762866 5.42502 0.762866 5.76052 1.09837C6.09602 1.43386 6.09602 1.97737 5.76052 2.31287L2.93347 5.14113H11.1653C11.6403 5.14113 12 5.52494 12 6.00001Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1272">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 740 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14 8.15327C14 8.62833 13.6403 9.01214 13.1653 9.01214H4.93347L7.7624 11.8411C8.0979 12.1766 8.0979 12.7201 7.7624 13.0556C7.59331 13.2233 7.37322 13.3065 7.15313 13.3065C6.93305 13.3065 6.71349 13.2227 6.54601 13.0549L2.25162 8.76052C1.91613 8.42502 1.91613 7.88151 2.25162 7.54601L6.54601 3.25162C6.88151 2.91613 7.42502 2.91613 7.76052 3.25162C8.09602 3.58712 8.09602 4.13063 7.76052 4.46613L4.93347 7.29439H13.1653C13.6403 7.29439 14 7.6782 14 8.15327Z" fill="white"/>
|
||||
<path d="M14 8.15327C14 8.62833 13.6403 9.01215 13.1653 9.01215H4.93347L7.7624 11.8411C8.0979 12.1766 8.0979 12.7201 7.7624 13.0556C7.59331 13.2233 7.37322 13.3065 7.15313 13.3065C6.93305 13.3065 6.71349 13.2227 6.54601 13.0549L2.25162 8.76052C1.91613 8.42502 1.91613 7.88151 2.25162 7.54601L6.54601 3.25162C6.88151 2.91613 7.42502 2.91613 7.76052 3.25162C8.09602 3.58712 8.09602 4.13063 7.76052 4.46613L4.93347 7.29439H13.1653C13.6403 7.29439 14 7.6782 14 8.15327Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 585 B After Width: | Height: | Size: 585 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1355)">
|
||||
<path d="M8 4.00003C8 4.31674 7.76023 4.57261 7.44352 4.57261H1.95565L3.8416 6.45856C4.06527 6.68223 4.06527 7.04457 3.8416 7.26823C3.72887 7.38007 3.58215 7.43554 3.43542 7.43554C3.2887 7.43554 3.14233 7.37962 3.03068 7.26779L0.16775 4.40486C-0.0559165 4.1812 -0.0559165 3.81886 0.16775 3.59519L3.03068 0.732264C3.25434 0.508598 3.61668 0.508598 3.84035 0.732264C4.06401 0.95593 4.06401 1.31827 3.84035 1.54194L1.95565 3.42744H7.44352C7.76023 3.42744 8 3.68331 8 4.00003Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1355">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 588 B After Width: | Height: | Size: 730 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1273)">
|
||||
<path d="M11.749 6.60576L7.46298 10.8917C7.2969 11.0605 7.07724 11.1436 6.85758 11.1436C6.63793 11.1436 6.41881 11.0598 6.25165 10.8924C5.91681 10.5576 5.91681 10.0151 6.25165 9.68029L9.07558 6.85756H0.857198C0.383864 6.85756 0 6.4745 0 6.00036C0 5.52623 0.383596 5.14317 0.85693 5.14317H9.07531L6.25192 2.31977C5.91708 1.98493 5.91708 1.44248 6.25192 1.10764C6.58676 0.772796 7.12921 0.772796 7.46405 1.10764L11.75 5.39363C12.0835 5.72981 12.0835 6.27092 11.7487 6.60576H11.749Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1273">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 743 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1356)">
|
||||
<path d="M7.83265 4.40382L4.97532 7.26115C4.8646 7.37365 4.71816 7.42901 4.57172 7.42901C4.42528 7.42901 4.2792 7.37321 4.16777 7.26159C3.94454 7.03836 3.94454 6.67673 4.16777 6.4535L6.05039 4.57169H0.571465C0.255909 4.57169 0 4.31631 0 4.00022C0 3.68413 0.255731 3.42876 0.571287 3.42876H6.05021L4.16795 1.54649C3.94472 1.32326 3.94472 0.961634 4.16795 0.738405C4.39117 0.515177 4.75281 0.515177 4.97603 0.738405L7.83336 3.59573C8.0557 3.81985 8.0557 4.18059 7.83247 4.40382H7.83265Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1356">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 742 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1274)">
|
||||
<path d="M10.9009 5.7604C10.7345 5.92948 10.5144 6.01268 10.2943 6.01268C10.0742 6.01268 9.85471 5.92881 9.68724 5.76107L6.85903 2.93408V11.1653C6.85903 11.6401 6.47444 12 6.02437 12C5.57429 12 5.14139 11.6404 5.14139 11.1653V2.93408L2.31346 5.76013C1.97798 6.09561 1.43451 6.09561 1.09903 5.76013C0.763558 5.42466 0.763558 4.88119 1.09903 4.54571L5.39314 0.251607C5.72861 -0.0838692 6.27209 -0.0838692 6.60756 0.251607L10.9017 4.54571C11.2363 4.88253 11.2363 5.42466 10.9009 5.76013V5.7604Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1274">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 611 B After Width: | Height: | Size: 755 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1357)">
|
||||
<path d="M7.26724 3.84027C7.15631 3.95299 7.0096 4.00845 6.86288 4.00845C6.71617 4.00845 6.56981 3.95254 6.45816 3.84072L4.57269 1.95605V7.44356C4.57269 7.76007 4.3163 8 4.01625 8C3.7162 8 3.4276 7.76025 3.4276 7.44356V1.95605L1.54231 3.84009C1.31866 4.06374 0.956346 4.06374 0.732695 3.84009C0.509044 3.61644 0.509044 3.25412 0.732695 3.03047L3.59543 0.167738C3.81908 -0.0559128 4.1814 -0.0559128 4.40505 0.167738L7.26778 3.03047C7.49089 3.25502 7.49089 3.61644 7.26724 3.84009V3.84027Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1357">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 603 B After Width: | Height: | Size: 745 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.17314 8L5.89399 3.29329L6.20495 7.94346L8 6.14841L7.67491 0.339222L1.85159 0L0.0565371 1.79505L4.70671 2.12014L0 6.82685L1.17314 8Z" fill="white"/>
|
||||
<path d="M6 2H6.5C6.5 1.86739 6.44732 1.74021 6.35355 1.64645C6.25979 1.55268 6.13261 1.5 6 1.5V2ZM2 1.5C1.72386 1.5 1.5 1.72386 1.5 2C1.5 2.27614 1.72386 2.5 2 2.5L2 1.5ZM5.5 6C5.5 6.27614 5.72386 6.5 6 6.5C6.27614 6.5 6.5 6.27614 6.5 6H5.5ZM1.64645 5.64645C1.45118 5.84171 1.45118 6.15829 1.64645 6.35355C1.84171 6.54882 2.15829 6.54882 2.35355 6.35355L1.64645 5.64645ZM6 1.5H2L2 2.5H6V1.5ZM5.5 2V6H6.5V2H5.5ZM5.64645 1.64645L1.64645 5.64645L2.35355 6.35355L6.35355 2.35355L5.64645 1.64645Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 259 B After Width: | Height: | Size: 608 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.14029 5.25005H9.75348C10.0652 5.25005 10.3464 5.44457 10.4355 5.73518C10.5644 6.02814 10.4824 6.3586 10.248 6.56484L4.24822 11.8146C3.98338 12.0443 3.59598 12.0631 3.31286 11.8568C3.02951 11.6506 2.92639 11.2756 3.06443 10.9545L4.86694 6.74999H2.23267C1.94135 6.74999 1.66152 6.55546 1.5516 6.26485C1.44171 5.97189 1.52465 5.64144 1.75986 5.43519L7.75893 0.185629C8.02376 -0.0449871 8.41046 -0.0625645 8.69405 0.143209C8.97763 0.349123 9.08075 0.723265 8.94248 1.04542L7.1402 5.24972L7.14029 5.25005Z" fill="white"/>
|
||||
<path d="M7.01442 5.33285H9.33914C9.61643 5.33285 9.86663 5.5059 9.94586 5.76443C10.0605 6.02505 9.98756 6.31903 9.77906 6.50251L4.4416 11.1728C4.206 11.3771 3.86136 11.3938 3.6095 11.2103C3.35743 11.0268 3.26569 10.6932 3.38849 10.4076L4.99202 6.66722H2.64855C2.38939 6.66722 2.14044 6.49417 2.04266 6.23563C1.9449 5.97501 2.01868 5.68104 2.22793 5.49756L7.56476 0.827491C7.80036 0.622333 8.14438 0.606695 8.39666 0.789754C8.64894 0.972937 8.74067 1.30578 8.61766 1.59237L7.01434 5.33256L7.01442 5.33285Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 625 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.76019 3.50003H6.50231C6.71012 3.50003 6.89761 3.62971 6.95698 3.82346C7.04292 4.01876 6.98823 4.23906 6.83199 4.37656L2.83214 7.87643C2.65558 8.02954 2.39731 8.04204 2.20857 7.90455C2.01967 7.76705 1.95092 7.51706 2.04295 7.30301L3.24462 4.49999H1.48844C1.29423 4.49999 1.10767 4.37031 1.0344 4.17657C0.961132 3.98126 1.01643 3.76096 1.17323 3.62346L5.17261 0.123753C5.34917 -0.0299914 5.60697 -0.0417097 5.79603 0.0954726C5.98508 0.232749 6.05383 0.482177 5.96164 0.69695L4.76013 3.49981L4.76019 3.50003Z" fill="white"/>
|
||||
<path d="M4.76019 3.50003H6.50231C6.71012 3.50003 6.89761 3.62971 6.95698 3.82346C7.04292 4.01876 6.98823 4.23906 6.83199 4.37656L2.83214 7.87643C2.65558 8.02954 2.39731 8.04204 2.20857 7.90455C2.01967 7.76705 1.95092 7.51706 2.04295 7.30301L3.24462 4.49999H1.48844C1.29423 4.49999 1.10767 4.37031 1.0344 4.17657C0.961132 3.98126 1.01643 3.76096 1.17323 3.62346L5.17261 0.123753C5.34917 -0.0299914 5.60697 -0.0417097 5.79603 0.0954726C5.98508 0.232749 6.05383 0.482177 5.96165 0.69695L4.76013 3.49981L4.76019 3.50003Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 633 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.00788 3.83701L7.62903 0.754503C7.87479 0.546451 8.23364 0.530593 8.4968 0.716233C8.75996 0.901999 8.85565 1.23953 8.72734 1.53017L7.05487 5.3231H9.47984C9.7691 5.3231 10.0301 5.49859 10.1127 5.76077C10.2323 6.02506 10.1562 6.32318 9.93874 6.50925L8.79258 7.48396L11.7998 9.86631C12.026 10.0397 12.0673 10.3589 11.889 10.5788C11.7106 10.7987 11.3822 10.8389 11.156 10.6655L0.200158 2.51988C-0.0268974 2.34693 -0.0666975 2.02808 0.111206 1.80735C0.28911 1.58661 0.616862 1.54792 0.843918 1.72108L4.00788 3.83701ZM2.06138 5.49043L2.40718 5.17751L4.34064 6.67658H2.52027C2.23102 6.67658 1.97003 6.50109 1.86782 6.23891C1.76777 5.97461 1.84389 5.67649 2.06138 5.49043ZM3.27278 10.4697L4.79301 7.02333L7.18318 8.83533L4.37108 11.2457C4.12532 11.4529 3.76647 11.4698 3.50331 11.2837C3.24015 11.0977 3.14446 10.7594 3.27278 10.4697Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1336)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.01443 5.33285H9.33914C9.61644 5.33285 9.86663 5.5059 9.94586 5.76443C10.0605 6.02505 9.98756 6.31903 9.77906 6.50251L9.11489 7.08366L11.4605 8.90799C11.7874 9.16229 11.8463 9.6335 11.592 9.96045C11.3377 10.2874 10.8665 10.3463 10.5395 10.092L1.53955 3.09201C1.21259 2.83771 1.15369 2.3665 1.40799 2.03954C1.66229 1.71258 2.1335 1.65368 2.46046 1.90799L4.50911 3.50138L7.56477 0.827491C7.80037 0.622333 8.14438 0.606695 8.39666 0.789754C8.64894 0.972937 8.74068 1.30578 8.61767 1.59237L7.01434 5.33256L7.01443 5.33285ZM2.88883 4.91923L7.49455 8.50146L4.4416 11.1728C4.206 11.3771 3.86136 11.3938 3.6095 11.2103C3.35743 11.0268 3.26569 10.6932 3.3885 10.4076L4.99203 6.66722H2.64855C2.38939 6.66722 2.14045 6.49416 2.04266 6.23563C1.9449 5.97501 2.01869 5.68104 2.22793 5.49756L2.88883 4.91923Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1336">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 956 B After Width: | Height: | Size: 1.1 KiB |
@@ -1,9 +1,9 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1350)">
|
||||
<path d="M2.8102 2.0687L5.08603 0.503002C5.24987 0.364301 5.4891 0.353729 5.66454 0.477489C5.83998 0.601333 5.90377 0.826356 5.81823 1.02011L4.70325 3.54873H6.3199C6.51274 3.54873 6.68673 3.66573 6.74182 3.84051C6.82157 4.01671 6.77082 4.21546 6.62583 4.3395L6.22432 4.68222L8.0048 6.08823C8.15559 6.20381 8.18314 6.41666 8.06425 6.56325C7.94536 6.70985 7.72642 6.73663 7.57563 6.62104L0.271717 1.19061C0.120346 1.07531 0.093813 0.862748 0.212416 0.715589C0.331018 0.56843 0.54952 0.542635 0.70089 0.658079L2.8102 2.0687ZM1.37426 3.66029L1.60479 3.45167L2.89376 4.45105H1.68019C1.48735 4.45105 1.31336 4.33406 1.24521 4.15927C1.17852 3.98308 1.22927 3.78433 1.37426 3.66029ZM2.18186 6.97981L3.19534 4.68222L4.78879 5.89022L2.91406 7.49712C2.75022 7.63526 2.51099 7.64653 2.33555 7.52249C2.16011 7.39845 2.09631 7.17292 2.18186 6.97981Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_702_132)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.67628 3.55525H6.22609C6.41096 3.55525 6.57775 3.67062 6.63057 3.84298C6.70702 4.01672 6.65837 4.21271 6.51937 4.33502L6.07659 4.72246L7.6403 5.93868C7.85828 6.10821 7.89754 6.42235 7.72801 6.64032C7.55847 6.8583 7.24434 6.89756 7.02636 6.72803L1.02636 2.06136C0.808388 1.89183 0.769121 1.57769 0.938656 1.35972C1.10819 1.14174 1.42233 1.10248 1.6403 1.27201L3.00607 2.33428L5.04318 0.551681C5.20024 0.414909 5.42959 0.404484 5.59777 0.526523C5.76596 0.648645 5.82712 0.870539 5.74511 1.0616L4.67622 3.55506L4.67628 3.55525ZM3.25023 4.62627L4.80474 5.83533L2.96106 7.44854C2.804 7.58476 2.57424 7.59588 2.40633 7.47356C2.23828 7.35125 2.17713 7.12885 2.25899 6.93843L3.25023 4.62627ZM1.73426 3.44719L3.01695 4.44483H1.7657C1.59292 4.44483 1.42696 4.32946 1.36177 4.15711C1.2966 3.98336 1.34579 3.78738 1.48528 3.66506L1.73426 3.44719Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1350">
|
||||
<clipPath id="clip0_702_132">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.78057 2.96296L4.59642 6.16966C4.41855 6.32749 4.21312 6.40515 4.00769 6.40515C3.80226 6.40515 3.59733 6.32686 3.44075 6.17028L0.256599 2.96358C0.00482339 2.73498 -0.06382 2.38913 0.0601891 2.09088C0.184298 1.79276 0.47686 1.59485 0.800787 1.59485H7.19164C7.51582 1.59485 7.80843 1.78976 7.93269 2.08963C8.05695 2.38926 8.01085 2.73473 7.78037 2.96271L7.78057 2.96296Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1359)">
|
||||
<path d="M6.36286 3.35324L4.37276 5.35315C4.26159 5.45158 4.1332 5.50002 4.0048 5.50002C3.87641 5.50002 3.74833 5.45119 3.65047 5.35354L1.66037 3.35363C1.50301 3.21106 1.46011 2.99537 1.53762 2.80936C1.61519 2.62343 1.79804 2.5 2.00049 2.5H5.99478C6.19739 2.5 6.38027 2.62156 6.45793 2.80858C6.53559 2.99545 6.50678 3.2109 6.36273 3.35309L6.36286 3.35324Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1359">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 495 B After Width: | Height: | Size: 613 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.03717 7.78065L1.83086 4.59689C1.67355 4.41904 1.5954 4.21363 1.5954 3.98568C1.5954 3.75774 1.67368 3.57538 1.83011 3.41882L5.03641 0.235058C5.26562 0.00560697 5.61029 -0.0630281 5.91013 0.0609657C6.20997 0.18496 6.40461 0.478537 6.40461 0.801672V7.19174C6.40461 7.51588 6.20947 7.80845 5.90988 7.9327C5.61004 8.05694 5.26486 8.01085 5.03692 7.7804L5.03717 7.78065Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1360)">
|
||||
<path d="M4.64677 6.36286L2.64687 4.37276C2.54843 4.26159 2.5 4.1332 2.5 4.0048C2.5 3.87641 2.54882 3.74833 2.64648 3.65047L4.64638 1.66037C4.78895 1.50301 5.00465 1.46011 5.19065 1.53762C5.37658 1.61519 5.50002 1.79804 5.50002 2.00049L5.50002 5.99478C5.50002 6.19739 5.37846 6.38027 5.19144 6.45793C5.00457 6.53559 4.78911 6.50678 4.64693 6.36273L4.64677 6.36286Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1360">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 492 B After Width: | Height: | Size: 622 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.95931 0.236879L6.17709 3.43204C6.33546 3.61052 6.4134 3.81666 6.4134 4.00018C6.4134 4.18369 6.33484 4.41195 6.17772 4.56907L2.95993 7.76423C2.72966 7.99425 2.384 8.06338 2.08309 7.93869C1.78217 7.81401 1.58659 7.56463 1.58659 7.21771V0.804768C1.58659 0.47947 1.78217 0.185847 2.08309 0.0611582C2.38375 -0.0635309 2.73042 0.0061038 2.95918 0.236628L2.95931 0.236879Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1361)">
|
||||
<path d="M3.35323 1.63714L5.35313 3.62724C5.45157 3.73841 5.5 3.8668 5.5 3.9952C5.5 4.12359 5.45118 4.25167 5.35352 4.34953L3.35362 6.33963C3.21105 6.49699 2.99535 6.53989 2.80935 6.46238C2.62342 6.38481 2.49998 6.20196 2.49998 5.99951L2.49998 2.00522C2.49998 1.80261 2.62154 1.61973 2.80856 1.54207C2.99543 1.46441 3.21089 1.49322 3.35307 1.63727L3.35323 1.63714Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1361">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 493 B After Width: | Height: | Size: 622 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.235788 5.03793L3.42201 1.82915C3.60024 1.67122 3.80581 1.59351 4.01137 1.59351C4.21693 1.59351 4.42199 1.67185 4.57867 1.82852L7.76489 5.0373C7.99427 5.26668 8.06321 5.61163 7.93887 5.9117C7.81453 6.21177 7.54328 6.40655 7.19734 6.40655H0.802589C0.478202 6.40655 0.1854 6.21127 0.0610601 5.91145C-0.0632802 5.61137 0.00590919 5.26593 0.235538 5.03781L0.235788 5.03793Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1362)">
|
||||
<path d="M1.63714 4.64676L3.62724 2.64685C3.73841 2.54842 3.8668 2.49998 3.9952 2.49998C4.12359 2.49998 4.25167 2.54881 4.34953 2.64646L6.33963 4.64637C6.49699 4.78894 6.53989 5.00463 6.46238 5.19064C6.38481 5.37657 6.20196 5.5 5.99951 5.5L2.00522 5.5C1.80261 5.5 1.61973 5.37844 1.54207 5.19142C1.46441 5.00455 1.49322 4.7891 1.63727 4.64691L1.63714 4.64676Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1362">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 496 B After Width: | Height: | Size: 617 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.28561 8C2.13936 8 1.99311 7.9442 1.88168 7.83259C1.65846 7.60937 1.65846 7.24776 1.88168 7.02454L4.90707 3.99996L1.88168 0.975457C1.65846 0.75224 1.65846 0.390629 1.88168 0.167413C2.10489 -0.0558042 2.4665 -0.0558042 2.68972 0.167413L6.11833 3.59602C6.34155 3.81924 6.34155 4.18085 6.11833 4.40407L2.68972 7.83268C2.57847 7.94464 2.43204 8 2.28561 8Z" fill="white"/>
|
||||
<path d="M2.28561 8C2.13936 8 1.99311 7.9442 1.88168 7.83259C1.65846 7.60937 1.65846 7.24776 1.88168 7.02454L4.90707 3.99996L1.88168 0.975457C1.65846 0.752241 1.65846 0.390629 1.88168 0.167413C2.10489 -0.0558042 2.4665 -0.0558042 2.68972 0.167413L6.11833 3.59602C6.34155 3.81924 6.34155 4.18085 6.11833 4.40407L2.68972 7.83268C2.57847 7.94464 2.43204 8 2.28561 8Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 478 B After Width: | Height: | Size: 479 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1285)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 12C9.31371 12 12 9.31371 12 6C12 2.68629 9.31371 0 6 0C2.68629 0 0 2.68629 0 6C0 9.31371 2.68629 12 6 12ZM9.53033 4.28033L8.46967 3.21967L4.875 6.81434L3.53033 5.46967L2.46967 6.53033L4.875 8.93566L9.53033 4.28033Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1285">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 530 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1370)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 8C6.20914 8 8 6.20914 8 4C8 1.79086 6.20914 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM6.35355 2.85355L5.64645 2.14645L3.25 4.54289L2.35355 3.64645L1.64645 4.35355L3.25 5.95711L6.35355 2.85355Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1370">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 373 B After Width: | Height: | Size: 515 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1294)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM5.25 6H4.5V4.5H6.75V8.25H7.5V9.75H5.25V6ZM6.75 3.75V2.25H5.25V3.75H6.75Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1294">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 350 B After Width: | Height: | Size: 494 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1372)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 4C8 6.20914 6.20914 8 4 8C1.79086 8 0 6.20914 0 4C0 1.79086 1.79086 0 4 0C6.20914 0 8 1.79086 8 4ZM3.5 4H3V3H4.5V5.5H5V6.5H3.5V4ZM4.5 2.5V1.5H3.5V2.5H4.5Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1372">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 464 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1287)">
|
||||
<path d="M6 0C2.68594 0 0 2.68594 0 6C0 9.31406 2.68594 12 6 12C9.31406 12 12 9.31406 12 6C12 2.68594 9.31406 0 6 0ZM8.97187 5.76797C8.91328 5.90859 8.77734 6 8.625 6H7.125V8.25C7.125 8.66414 6.78914 9 6.375 9H5.625C5.21086 9 4.875 8.66414 4.875 8.25V6H3.375C3.22266 6 3.08672 5.90859 3.02812 5.76797C2.96953 5.62734 3.00234 5.46797 3.11016 5.36016L5.73516 2.73516C5.88141 2.58867 6.11906 2.58867 6.26531 2.73516L8.89031 5.36016C8.99766 5.46797 9.03047 5.62734 8.97187 5.76797Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1287">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 597 B After Width: | Height: | Size: 741 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1376)">
|
||||
<path d="M4 0C1.79063 0 0 1.79063 0 4C0 6.20937 1.79063 8 4 8C6.20937 8 8 6.20937 8 4C8 1.79063 6.20937 0 4 0ZM5.98125 3.84531C5.94219 3.93906 5.85156 4 5.75 4H4.75V5.5C4.75 5.77609 4.52609 6 4.25 6H3.75C3.47391 6 3.25 5.77609 3.25 5.5V4H2.25C2.14844 4 2.05781 3.93906 2.01875 3.84531C1.97969 3.75156 2.00156 3.64531 2.07344 3.57344L3.82344 1.82344C3.92094 1.72578 4.07938 1.72578 4.17688 1.82344L5.92688 3.57344C5.99844 3.64531 6.02031 3.75156 5.98125 3.84531Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1376">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 577 B After Width: | Height: | Size: 719 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1292)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 12C9.31371 12 12 9.31371 12 6C12 2.68629 9.31371 0 6 0C2.68629 0 0 2.68629 0 6C0 9.31371 2.68629 12 6 12ZM3.21967 4.28033L4.93934 6L3.21967 7.71967L4.28033 8.78033L6 7.06066L7.71967 8.78033L8.78033 7.71967L7.06066 6L8.78033 4.28033L7.71967 3.21967L6 4.93934L4.28033 3.21967L3.21967 4.28033Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1292">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 606 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1365)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 8C6.20914 8 8 6.20914 8 4C8 1.79086 6.20914 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM2.14645 2.85355L3.29289 4L2.14645 5.14645L2.85355 5.85355L4 4.70711L5.14645 5.85355L5.85355 5.14645L4.70711 4L5.85355 2.85355L5.14645 2.14645L4 3.29289L2.85355 2.14645L2.14645 2.85355Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1365">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 593 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.59892 2.76222C3.14641 2.17067 3.93013 1.80018 4.80011 1.80018C5.91195 1.80018 6.8813 2.40485 7.40066 3.30389C7.68565 3.09577 8.03064 3.00015 8.4 3.00015C9.39372 3.00015 10.1999 3.7895 10.1999 4.80009C10.1999 5.02884 10.1568 5.24633 10.08 5.44882C11.1749 5.67007 11.9999 6.63941 11.9999 7.8C11.9999 8.48623 11.7112 9.10497 11.233 9.52683L11.8274 9.99557C12.0224 10.1493 12.058 10.4324 11.9043 10.6274C11.7505 10.8224 11.4674 10.858 11.2724 10.7043L0.172556 2.00436C-0.0231882 1.85099 -0.0574997 1.56825 0.0958708 1.37251C0.249241 1.17676 0.531796 1.14245 0.727671 1.29582L2.59868 2.76184L2.59892 2.76222ZM1.82213 4.43635L9.13873 10.1999H2.70017C1.20903 10.1999 0.000248596 8.99059 0.000248596 7.50001C0.000248596 6.32255 0.753414 5.32133 1.80395 4.95196C1.80151 4.90134 1.8002 4.85072 1.8002 4.80009C1.8002 4.67635 1.8077 4.55448 1.82213 4.43635Z" fill="white"/>
|
||||
<path d="M2.59892 2.76222C3.14641 2.17067 3.93013 1.80018 4.80011 1.80018C5.91195 1.80018 6.8813 2.40485 7.40066 3.30389C7.68565 3.09577 8.03064 3.00015 8.4 3.00015C9.39372 3.00015 10.1999 3.7895 10.1999 4.80009C10.1999 5.02884 10.1568 5.24633 10.08 5.44882C11.1749 5.67007 11.9999 6.63941 11.9999 7.80001C11.9999 8.48623 11.7112 9.10497 11.233 9.52683L11.8274 9.99557C12.0224 10.1493 12.058 10.4324 11.9043 10.6274C11.7505 10.8224 11.4674 10.858 11.2724 10.7043L0.172556 2.00436C-0.0231882 1.85099 -0.0574997 1.56825 0.0958708 1.37251C0.249241 1.17676 0.531795 1.14245 0.727671 1.29582L2.59868 2.76184L2.59892 2.76222ZM1.82213 4.43635L9.13873 10.1999H2.70017C1.20903 10.1999 0.000248596 8.99059 0.000248596 7.50001C0.000248596 6.32255 0.753414 5.32133 1.80395 4.95196C1.80151 4.90134 1.8002 4.85072 1.8002 4.80009C1.8002 4.67635 1.8077 4.55448 1.82213 4.43635Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 977 B After Width: | Height: | Size: 981 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.73261 1.8415C2.0976 1.44713 2.62009 1.20014 3.20007 1.20014C3.9413 1.20014 4.58753 1.60325 4.93377 2.20261C5.12376 2.06387 5.35376 2.00012 5.6 2.00012C6.26248 2.00012 6.79996 2.52635 6.79996 3.20008C6.79996 3.35258 6.77122 3.49757 6.71997 3.63257C7.44995 3.78007 7.99993 4.4263 7.99993 5.20002C7.99993 5.65751 7.80744 6.07 7.48869 6.35124L7.88493 6.66373C8.01493 6.76623 8.03868 6.95497 7.93618 7.08497C7.83368 7.21496 7.64494 7.23871 7.51494 7.13622L0.115037 1.33626C-0.0154588 1.23402 -0.0383331 1.04552 0.0639139 0.915025C0.166161 0.784529 0.35453 0.761655 0.485114 0.863902L1.73245 1.84125L1.73261 1.8415ZM1.21475 2.95759L6.09249 6.79998H1.80011C0.806017 6.79998 0.000165731 5.99375 0.000165731 5.00003C0.000165731 4.21505 0.502276 3.54757 1.20263 3.30133C1.20101 3.26758 1.20013 3.23383 1.20013 3.20008C1.20013 3.11759 1.20513 3.03634 1.21475 2.95759Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1352)">
|
||||
<path d="M1.73261 1.8415C2.0976 1.44713 2.62009 1.20014 3.20007 1.20014C3.9413 1.20014 4.58753 1.60325 4.93377 2.20261C5.12376 2.06387 5.35376 2.00012 5.6 2.00012C6.26248 2.00012 6.79997 2.52635 6.79997 3.20008C6.79997 3.35258 6.77122 3.49757 6.71997 3.63257C7.44995 3.78007 7.99993 4.4263 7.99993 5.20002C7.99993 5.65751 7.80744 6.07 7.48869 6.35124L7.88493 6.66373C8.01493 6.76623 8.03868 6.95497 7.93618 7.08497C7.83368 7.21496 7.64494 7.23871 7.51494 7.13622L0.115037 1.33626C-0.0154588 1.23402 -0.0383331 1.04552 0.0639139 0.915025C0.166161 0.784529 0.35453 0.761655 0.485114 0.863902L1.73245 1.84125L1.73261 1.8415ZM1.21475 2.95759L6.09249 6.79998H1.80011C0.806017 6.79998 0.000165731 5.99375 0.000165731 5.00003C0.000165731 4.21505 0.502276 3.54757 1.20263 3.30133C1.20101 3.26758 1.20013 3.23383 1.20013 3.20008C1.20013 3.11759 1.20513 3.03634 1.21475 2.95759Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1352">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 1.1 KiB |
@@ -1,11 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_616_81)">
|
||||
<path opacity="0.6" d="M11 11L11 7L1 7L1 11L11 11Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
|
||||
<path d="M11 8L11 7L1 7L1 8L11 8Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_702_214)">
|
||||
<rect x="0.5" y="0.5" width="11" height="11" rx="1" stroke="white" stroke-opacity="0.4"/>
|
||||
<path d="M12 7.5L12 10.5C12 11.3284 11.3284 12 10.5 12L1.5 12C0.671573 12 -1.67346e-07 11.3284 -1.31134e-07 10.5L0 7.5L12 7.5Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_616_81">
|
||||
<clipPath id="clip0_702_214">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 478 B |
@@ -1,7 +1,7 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_610_112)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 4.37114e-08 0.447715 4.37114e-08 1V7C4.37114e-08 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
|
||||
<path d="M7 4C7.55228 4 8 4.44772 8 5V7C8 7.55228 7.55228 8 7 8H1C0.447715 8 4.37114e-08 7.55228 4.37114e-08 7L0 5C2.41411e-08 4.44771 0.447715 4 1 4L7 4Z" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="7" height="7" rx="0.5" stroke="white" stroke-opacity="0.4"/>
|
||||
<path d="M8 5L8 7C8 7.55228 7.55228 8 7 8L1 8C0.447715 8 -1.11564e-07 7.55228 -8.74228e-08 7L0 5L8 5Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_610_112">
|
||||
|
||||
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 447 B |
@@ -1,11 +0,0 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_616_82)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 4C5.5 3.72386 5.72386 3.5 6 3.5H8C8.27614 3.5 8.5 3.72386 8.5 4V6C8.5 6.27614 8.27614 6.5 8 6.5C7.72386 6.5 7.5 6.27614 7.5 6V5.20711L5.20711 7.5H6C6.27614 7.5 6.5 7.72386 6.5 8C6.5 8.27614 6.27614 8.5 6 8.5H4C3.72386 8.5 3.5 8.27614 3.5 8V6C3.5 5.72386 3.72386 5.5 4 5.5C4.27614 5.5 4.5 5.72386 4.5 6V6.79289L6.79289 4.5H6C5.72386 4.5 5.5 4.27614 5.5 4Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_616_82">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,13 +0,0 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_610_113)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
|
||||
<path d="M6 2H3L6 5V2Z" fill="white"/>
|
||||
<path d="M2 6L5 6L2 3L2 6Z" fill="white"/>
|
||||
<path d="M5.5 2.5L2.5 5.5" stroke="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_610_113">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 557 B |
@@ -1,11 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_620_198)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
|
||||
<rect opacity="0.6" x="4" y="4" width="4" height="4" fill="white"/>
|
||||
<rect x="3.5" y="3.5" width="5" height="5" rx="0.5" stroke="white"/>
|
||||
<g clip-path="url(#clip0_702_213)">
|
||||
<rect x="2" y="3" width="8" height="6" rx="1" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="11" height="11" rx="1" stroke="white" stroke-opacity="0.4"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_620_198">
|
||||
<clipPath id="clip0_702_213">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 813 B After Width: | Height: | Size: 396 B |
@@ -1,6 +1,6 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_620_186)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white" fill-opacity="0.4"/>
|
||||
<rect x="2" y="2" width="4" height="4" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 485 B After Width: | Height: | Size: 504 B |
@@ -1,11 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_616_83)">
|
||||
<path opacity="0.6" d="M11 1H7V11H11V1Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
|
||||
<path d="M8 1H7V11H8V1Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_702_215)">
|
||||
<rect x="0.5" y="0.5" width="11" height="11" rx="1" stroke="white" stroke-opacity="0.4"/>
|
||||
<path d="M7.5 0H10.5C11.3284 0 12 0.671573 12 1.5V10.5C12 11.3284 11.3284 12 10.5 12H7.5V0Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_616_83">
|
||||
<clipPath id="clip0_702_215">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 770 B After Width: | Height: | Size: 443 B |
@@ -1,7 +1,7 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_610_114)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
|
||||
<path d="M4 1C4 0.447715 4.44772 0 5 0H7C7.55228 0 8 0.447715 8 1V7C8 7.55228 7.55228 8 7 8H5C4.44772 8 4 7.55228 4 7V1Z" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="7" height="7" rx="0.5" stroke="white" stroke-opacity="0.4"/>
|
||||
<path d="M5 0H7C7.55228 0 8 0.447715 8 1V7C8 7.55228 7.55228 8 7 8H5V0Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_610_114">
|
||||
|
||||
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 417 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1286)">
|
||||
<path d="M11.3333 1.33335H9L8.33333 0.666687H6.66667C6.29958 0.666687 6 0.96627 6 1.33335V4.66669C6 5.03377 6.29958 5.33335 6.66667 5.33335H11.3333C11.7004 5.33335 12 5.03377 12 4.66669V2.00002C12 1.63294 11.7 1.33335 11.3333 1.33335ZM11.3333 7.33335H9L8.33333 6.66669H6.66667C6.29958 6.66669 6 6.96627 6 7.33335V10.6667C6 11.0338 6.29958 11.3334 6.66667 11.3334H11.3333C11.7004 11.3334 12 11.0338 12 10.6667V8.00002C12 7.63335 11.7 7.33335 11.3333 7.33335ZM1.33333 1.00002C1.33333 0.815125 1.185 0.666687 1 0.666687H0.333333C0.148438 0.666687 0 0.81502 0 1.00002V9.33335C0 9.70044 0.299583 10 0.666667 10H5.33333V8.66669H1.33333V4.00002H5.33333V2.66669H1.33333V1.00002Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1286">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 790 B After Width: | Height: | Size: 934 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1367)">
|
||||
<path d="M7.55556 0.888902H6L5.55556 0.444458H4.44444C4.19972 0.444458 4 0.64418 4 0.888902V3.11112C4 3.35585 4.19972 3.55557 4.44444 3.55557H7.55556C7.80028 3.55557 8 3.35585 8 3.11112V1.33335C8 1.08862 7.8 0.888902 7.55556 0.888902ZM7.55556 4.8889H6L5.55556 4.44446H4.44444C4.19972 4.44446 4 4.64418 4 4.8889V7.11112C4 7.35585 4.19972 7.55557 4.44444 7.55557H7.55556C7.80028 7.55557 8 7.35585 8 7.11112V5.33335C8 5.0889 7.8 4.8889 7.55556 4.8889ZM0.888889 0.66668C0.888889 0.543416 0.79 0.444458 0.666667 0.444458H0.222222C0.0989583 0.444458 0 0.543347 0 0.66668V6.22224C0 6.46696 0.199722 6.66668 0.444444 6.66668H3.55556V5.77779H0.888889V2.66668H3.55556V1.77779H0.888889V0.66668Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1367">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 799 B After Width: | Height: | Size: 941 B |
@@ -1,6 +1,6 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_614_97)">
|
||||
<path d="M5 7.62515C5 7.77359 4.9125 7.90796 4.77812 7.96734C4.64219 8.02828 4.47031 8.00327 4.37344 7.90328L3.12344 6.77828C3.04531 6.70796 3 6.6064 3 6.50015C3 6.3939 3.04531 6.29234 3.12344 6.22203L4.37344 5.09703C4.47031 4.99703 4.64219 4.97203 4.77812 5.03296C4.9125 5.09234 5 5.22671 5 5.37515V6.00015H5.25C5.80156 6.00015 6.25 5.55171 6.25 5.00015V2.39546C5.80781 2.18921 5.5 1.76265 5.5 1.25015C5.5 0.559838 6.05937 0.000150232 6.75 0.000150232C7.44063 0.000134607 8 0.559838 8 1.25015C8 1.76265 7.69219 2.18921 7.25 2.39546V5.00015C7.25 6.10484 6.35469 7.00015 5.25 7.00015H5V7.62515ZM7.125 1.23609C7.125 1.04296 6.95781 0.861088 6.75 0.861088C6.54219 0.861088 6.375 1.04296 6.375 1.23609C6.375 1.45718 6.54219 1.61109 6.75 1.61109C6.95781 1.61109 7.125 1.45718 7.125 1.23609ZM3 0.37515C3 0.227025 3.0875 0.0928065 3.22187 0.032494C3.35781 -0.0278185 3.51562 -0.00281852 3.62656 0.096244L4.87656 1.22123C4.95469 1.29232 5 1.39373 5 1.49998C5 1.60623 4.95469 1.70779 4.87656 1.7781L3.62656 2.9031C3.51562 3.0031 3.35781 3.0281 3.22187 2.96717C3.0875 2.90779 3 2.77342 3 2.62498V1.99998H2.75C2.19844 1.99998 1.75 2.44842 1.75 2.99998V5.60467C2.19219 5.79685 2.5 6.23748 2.5 6.74998C2.5 7.4406 1.94062 7.99998 1.25 7.99998C0.559687 7.99998 0 7.4406 0 6.74998C0 6.23748 0.308594 5.79685 0.75 5.60467V2.99998C0.75 1.89529 1.64531 0.999978 2.75 0.999978H3V0.374978V0.37515ZM0.875 6.75015C0.875 6.95796 1.04297 7.12515 1.25 7.12515C1.45703 7.12515 1.625 6.95796 1.625 6.75015C1.625 6.54234 1.45703 6.37515 1.25 6.37515C1.04297 6.37515 0.875 6.54234 0.875 6.75015Z" fill="white"/>
|
||||
<path d="M5 7.62515C5 7.77359 4.9125 7.90796 4.77812 7.96734C4.64219 8.02828 4.47031 8.00328 4.37344 7.90328L3.12344 6.77828C3.04531 6.70796 3 6.6064 3 6.50015C3 6.3939 3.04531 6.29234 3.12344 6.22203L4.37344 5.09703C4.47031 4.99703 4.64219 4.97203 4.77812 5.03296C4.9125 5.09234 5 5.22671 5 5.37515V6.00015H5.25C5.80156 6.00015 6.25 5.55171 6.25 5.00015V2.39546C5.80781 2.18921 5.5 1.76265 5.5 1.25015C5.5 0.559838 6.05937 0.000150232 6.75 0.000150232C7.44063 0.000134607 8 0.559838 8 1.25015C8 1.76265 7.69219 2.18921 7.25 2.39546V5.00015C7.25 6.10484 6.35469 7.00015 5.25 7.00015H5V7.62515ZM7.125 1.23609C7.125 1.04296 6.95781 0.861088 6.75 0.861088C6.54219 0.861088 6.375 1.04296 6.375 1.23609C6.375 1.45718 6.54219 1.61109 6.75 1.61109C6.95781 1.61109 7.125 1.45718 7.125 1.23609ZM3 0.37515C3 0.227025 3.0875 0.0928065 3.22187 0.032494C3.35781 -0.0278185 3.51563 -0.00281852 3.62656 0.096244L4.87656 1.22123C4.95469 1.29232 5 1.39373 5 1.49998C5 1.60623 4.95469 1.70779 4.87656 1.7781L3.62656 2.9031C3.51563 3.0031 3.35781 3.0281 3.22187 2.96717C3.0875 2.90779 3 2.77342 3 2.62498V1.99998H2.75C2.19844 1.99998 1.75 2.44842 1.75 2.99998V5.60467C2.19219 5.79685 2.5 6.23748 2.5 6.74998C2.5 7.4406 1.94063 7.99998 1.25 7.99998C0.559687 7.99998 0 7.4406 0 6.74998C0 6.23748 0.308594 5.79685 0.75 5.60467V2.99998C0.75 1.89529 1.64531 0.999978 2.75 0.999978H3V0.374978V0.37515ZM0.875 6.75015C0.875 6.95796 1.04297 7.12515 1.25 7.12515C1.45703 7.12515 1.625 6.95796 1.625 6.75015C1.625 6.54234 1.45703 6.37515 1.25 6.37515C1.04297 6.37515 0.875 6.54234 0.875 6.75015Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_614_97">
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.8167 11.0391L8.67607 7.89844C9.35576 7.06641 9.73076 6.01875 9.73076 4.875C9.73076 2.18203 7.54802 0 4.85576 0C2.16349 0 0.00161743 2.18273 0.00161743 4.875C0.00161743 7.56727 2.18412 9.75 4.85552 9.75C5.99904 9.75 7.0481 9.35367 7.87896 8.69438L11.0196 11.835C11.1508 11.9461 11.2961 12 11.4391 12C11.5821 12 11.7269 11.9449 11.8369 11.835C12.0555 11.6154 12.0555 11.2591 11.8165 11.0388L11.8167 11.0391ZM1.12685 4.875C1.12685 2.80734 2.8092 1.125 4.87685 1.125C6.94451 1.125 8.62685 2.80734 8.62685 4.875C8.62685 6.94266 6.94451 8.625 4.87685 8.625C2.8092 8.625 1.12685 6.94219 1.12685 4.875Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1288)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.40624 7.54167C6.77901 8.13568 5.93205 8.5 5 8.5C3.067 8.5 1.5 6.933 1.5 5C1.5 3.067 3.067 1.5 5 1.5C6.933 1.5 8.5 3.067 8.5 5C8.5 5.93205 8.13568 6.77901 7.54167 7.40624C7.51667 7.42558 7.49261 7.44673 7.46967 7.46967C7.44673 7.49261 7.42558 7.51667 7.40624 7.54167ZM7.96544 9.0261C7.13578 9.63821 6.11014 10 5 10C2.23858 10 0 7.76142 0 5C0 2.23858 2.23858 0 5 0C7.76142 0 10 2.23858 10 5C10 6.11014 9.63821 7.13578 9.0261 7.96544L11.5303 10.4697C11.8232 10.7626 11.8232 11.2374 11.5303 11.5303C11.2374 11.8232 10.7626 11.8232 10.4697 11.5303L7.96544 9.0261Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1288">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 727 B After Width: | Height: | Size: 874 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.87779 7.35938L5.78404 5.26562C6.23716 4.71094 6.48716 4.0125 6.48716 3.25C6.48716 1.45469 5.03201 0 3.23716 0C1.44232 0 0.00106812 1.45516 0.00106812 3.25C0.00106812 5.04484 1.45607 6.5 3.23701 6.5C3.99935 6.5 4.69873 6.23578 5.25263 5.79625L7.34638 7.89C7.43388 7.96406 7.53076 8 7.62607 8C7.72138 8 7.81794 7.96328 7.89123 7.89C8.03701 7.74359 8.03701 7.50609 7.87763 7.35922L7.87779 7.35938ZM0.751224 3.25C0.751224 1.87156 1.87279 0.75 3.25122 0.75C4.62966 0.75 5.75122 1.87156 5.75122 3.25C5.75122 4.62844 4.62966 5.75 3.25122 5.75C1.87279 5.75 0.751224 4.62813 0.751224 3.25Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1369)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.16734 5.87445C4.62987 6.26778 3.96705 6.5 3.25 6.5C1.45507 6.5 0 5.04493 0 3.25C0 1.45507 1.45507 0 3.25 0C5.04493 0 6.5 1.45507 6.5 3.25C6.5 3.96705 6.26778 4.62987 5.87445 5.16734L7.85355 7.14645C8.04882 7.34171 8.04882 7.65829 7.85355 7.85355C7.65829 8.04882 7.34171 8.04882 7.14645 7.85355L5.16734 5.87445ZM5.5 3.25C5.5 4.49264 4.49264 5.5 3.25 5.5C2.00736 5.5 1 4.49264 1 3.25C1 2.00736 2.00736 1 3.25 1C4.49264 1 5.5 2.00736 5.5 3.25Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1369">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 750 B |
@@ -1,6 +1,6 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_609_69)">
|
||||
<path d="M2.77187 4.52188L0.999998 6.29375V5.50001C0.999998 5.2236 0.776405 5.00001 0.499999 5.00001C0.223593 5.00001 0 5.2236 0 5.50001V7.5C0 7.565 0.013125 7.62985 0.0385155 7.69094C0.0891405 7.81328 0.186484 7.91078 0.308984 7.96141C0.370077 7.9875 0.434921 8 0.499921 8H2.49992C2.77632 8 2.99992 7.77641 2.99992 7.5C2.99992 7.2236 2.77632 7 2.49992 7H1.70773L3.4796 5.22813C3.67492 5.03282 3.67492 4.71641 3.4796 4.5211C3.28429 4.32579 2.9671 4.32657 2.77179 4.52188H2.77187ZM7.96092 0.309078C7.91014 0.186578 7.8128 0.089078 7.6903 0.038453C7.62967 0.0131406 7.56561 0 7.49999 0H5.49999C5.22358 0 4.99999 0.223593 4.99999 0.499999C4.99999 0.776405 5.22358 0.999998 5.49999 0.999998H6.29296L4.52109 2.77187C4.32577 2.96718 4.32577 3.28359 4.52109 3.4789C4.71624 3.67406 5.03265 3.67437 5.22812 3.4789L6.99999 1.70782V2.50001C6.99999 2.77642 7.22358 3.00001 7.49999 3.00001C7.77639 3.00001 7.99998 2.77642 7.99998 2.50001V0.500015C7.99998 0.435015 7.98748 0.370171 7.96092 0.309078Z" fill="white"/>
|
||||
<path d="M2.77188 4.52188L1.00001 6.29375V5.50001C1.00001 5.2236 0.776412 5.00001 0.500007 5.00001C0.223601 5.00001 7.62939e-06 5.2236 7.62939e-06 5.50001V7.5C7.62939e-06 7.565 0.0131326 7.62984 0.0385232 7.69094C0.0891481 7.81328 0.186492 7.91078 0.308991 7.96141C0.370085 7.9875 0.434929 8 0.499929 8H2.49992C2.77633 8 2.99992 7.77641 2.99992 7.5C2.99992 7.2236 2.77633 7 2.49992 7H1.70774L3.47961 5.22813C3.67492 5.03282 3.67492 4.71641 3.47961 4.5211C3.2843 4.32579 2.96711 4.32657 2.7718 4.52188H2.77188ZM7.96093 0.309078C7.91015 0.186578 7.81281 0.089078 7.69031 0.0384531C7.62968 0.0131406 7.56562 0 7.49999 0H5.5C5.22359 0 5 0.223593 5 0.499999C5 0.776405 5.22359 0.999998 5.5 0.999998H6.29296L4.52109 2.77187C4.32578 2.96718 4.32578 3.28359 4.52109 3.4789C4.71625 3.67406 5.03265 3.67437 5.22812 3.4789L6.99999 1.70782V2.50001C6.99999 2.77642 7.22359 3.00001 7.49999 3.00001C7.7764 3.00001 7.99999 2.77642 7.99999 2.50001V0.500015C7.99999 0.435015 7.98749 0.370171 7.96093 0.309078Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_609_69">
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1,6 +1,6 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_609_75)">
|
||||
<path d="M0.854041 7.85284L2.75022 5.95775V6.74984C2.75022 7.02622 2.97379 7.24978 3.25017 7.24978C3.52654 7.24978 3.75011 7.02622 3.75011 6.74984V4.75008C3.75011 4.68493 3.73683 4.62009 3.71152 4.55916C3.6609 4.43605 3.56404 4.33919 3.44061 4.28919C3.37968 4.26264 3.31563 4.25014 3.25001 4.25014H1.25024C0.97387 4.25014 0.750303 4.4737 0.750303 4.75008C0.750303 5.02645 0.97387 5.25002 1.25024 5.25002H2.04312L0.146467 7.14667C-0.0488224 7.34196 -0.0488224 7.65833 0.146467 7.85362C0.341757 8.04891 0.658595 8.04813 0.853884 7.85284H0.854041ZM4.28911 3.44086C4.33973 3.56334 4.43706 3.66083 4.5597 3.71145C4.62032 3.7377 4.68437 3.7502 4.74999 3.7502H6.74976C7.02613 3.7502 7.2497 3.52663 7.2497 3.25025C7.2497 2.97388 7.02613 2.75031 6.74976 2.75031H5.95688L7.85353 0.85366C8.04882 0.65837 8.04882 0.342001 7.85353 0.146711C7.6584 -0.048422 7.34203 -0.0487345 7.14658 0.146711L5.24993 2.04415V1.25049C5.24993 0.974114 5.02636 0.750547 4.74999 0.750547C4.47362 0.750547 4.25005 0.974114 4.25005 1.25049V3.23619C4.25005 3.31587 4.26255 3.37993 4.28911 3.44086Z" fill="white"/>
|
||||
<path d="M0.854041 7.85284L2.75022 5.95775V6.74984C2.75022 7.02622 2.97379 7.24979 3.25017 7.24979C3.52654 7.24979 3.75011 7.02622 3.75011 6.74984V4.75008C3.75011 4.68493 3.73683 4.62009 3.71152 4.55916C3.6609 4.43605 3.56404 4.33919 3.44061 4.28919C3.37968 4.26264 3.31563 4.25014 3.25001 4.25014H1.25024C0.97387 4.25014 0.750303 4.4737 0.750303 4.75008C0.750303 5.02645 0.97387 5.25002 1.25024 5.25002H2.04312L0.146467 7.14667C-0.0488224 7.34196 -0.0488224 7.65833 0.146467 7.85362C0.341757 8.04891 0.658595 8.04813 0.853884 7.85284H0.854041ZM4.28911 3.44086C4.33973 3.56334 4.43706 3.66083 4.5597 3.71145C4.62032 3.7377 4.68437 3.7502 4.74999 3.7502H6.74976C7.02613 3.7502 7.2497 3.52663 7.2497 3.25025C7.2497 2.97388 7.02613 2.75031 6.74976 2.75031H5.95688L7.85353 0.85366C8.04882 0.65837 8.04882 0.342001 7.85353 0.146711C7.6584 -0.048422 7.34203 -0.0487345 7.14658 0.146711L5.24993 2.04415V1.25049C5.24993 0.974114 5.02636 0.750547 4.74999 0.750547C4.47362 0.750547 4.25005 0.974114 4.25005 1.25049V3.23619C4.25005 3.31587 4.26255 3.37993 4.28911 3.44086Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_609_75">
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 2.5V9.5M2.5 6H9.5" stroke="white" stroke-linecap="round"/>
|
||||
<g clip-path="url(#clip0_519_280)">
|
||||
<path d="M6 2.5V9.5M2.5 6H9.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_519_280">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 335 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 2V14M2 8H14" stroke="white" stroke-width="1.71429" stroke-linecap="round"/>
|
||||
<g clip-path="url(#clip0_702_228)">
|
||||
<path d="M8.00001 3.33331V12.6666M3.33334 7.99998H12.6667" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_702_228">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 191 B After Width: | Height: | Size: 363 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 1.5V6.5M1.5 4H6.5" stroke="white" stroke-linecap="round"/>
|
||||
<g clip-path="url(#clip0_519_287)">
|
||||
<path d="M4 1V7M1 4H7" stroke="white" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_519_287">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 170 B After Width: | Height: | Size: 302 B |
@@ -1,5 +1,12 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1301)">
|
||||
<path d="M11 1H6V11H11V1Z" fill="white" fill-opacity="0.2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
|
||||
<path d="M6.09091 1H5V11H6.09091V1Z" fill="white"/>
|
||||
<path d="M6 1H5V11H6V1Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1301">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 647 B After Width: | Height: | Size: 779 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1295)">
|
||||
<path d="M0 2.25C0 1.42148 0.67148 0.75 1.5 0.75H10.5C11.3273 0.75 12 1.42148 12 2.25V9.75C12 10.5773 11.3273 11.25 10.5 11.25H1.5C0.67148 11.25 0 10.5773 0 9.75V2.25ZM2.39766 3.55781C2.18789 3.7875 2.20336 4.14141 2.43281 4.35234L4.23047 6L2.43281 7.64766C2.20336 7.85859 2.18789 8.2125 2.39766 8.44219C2.60859 8.65078 2.9625 8.68594 3.19219 8.47734L5.44219 6.41484C5.55937 6.30703 5.625 6.15703 5.625 5.97891C5.625 5.84297 5.55937 5.69297 5.44219 5.58516L3.19219 3.52266C2.9625 3.31406 2.60859 3.32813 2.39766 3.55781ZM5.8125 7.875C5.50078 7.875 5.25 8.12578 5.25 8.4375C5.25 8.74922 5.50078 9 5.8125 9H9.1875C9.4992 9 9.75 8.74922 9.75 8.4375C9.75 8.12578 9.4992 7.875 9.1875 7.875H5.8125Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1295">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 812 B After Width: | Height: | Size: 956 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1381)">
|
||||
<path d="M0 1.5C0 0.947653 0.447653 0.5 1 0.5H7C7.55153 0.5 8 0.947653 8 1.5V6.5C8 7.05153 7.55153 7.5 7 7.5H1C0.447653 7.5 0 7.05153 0 6.5V1.5ZM1.59844 2.37187C1.45859 2.525 1.46891 2.76094 1.62187 2.90156L2.82031 4L1.62187 5.09844C1.46891 5.23906 1.45859 5.475 1.59844 5.62813C1.73906 5.76719 1.975 5.79063 2.12813 5.65156L3.62813 4.27656C3.70625 4.20469 3.75 4.10469 3.75 3.98594C3.75 3.89531 3.70625 3.79531 3.62813 3.72344L2.12813 2.34844C1.975 2.20937 1.73906 2.21875 1.59844 2.37187ZM3.875 5.25C3.66719 5.25 3.5 5.41719 3.5 5.625C3.5 5.83281 3.66719 6 3.875 6H6.125C6.3328 6 6.5 5.83281 6.5 5.625C6.5 5.41719 6.3328 5.25 6.125 5.25H3.875Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1381">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 761 B After Width: | Height: | Size: 903 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1297)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 11.625H0V9.375L5.25 0.375H6.75L12 9.375V11.625ZM5.25 3.375H6.75V7.125H5.25V3.375ZM5.25 8.625H6.75V10.125H5.25V8.625Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1297">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 433 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1371)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 7.75H0V6.25L3.5 0.25H4.5L8 6.25V7.75ZM3.5 2.25H4.5V4.75H3.5V2.25ZM3.5 5.75H4.5V6.75H3.5V5.75Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1371">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 403 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1383)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.75 1C5.33579 1 5 1.33579 5 1.75V3H6.5V8H0.5V3H4V1.75C4 0.783502 4.7835 0 5.75 0C6.7165 0 7.5 0.783502 7.5 1.75V2H6.5V1.75C6.5 1.33579 6.16421 1 5.75 1ZM4.5 5H2.5V6H4.5V5Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1383">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 480 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1299)">
|
||||
<path d="M6 0C2.68594 0 0 2.68594 0 6C0 9.31406 2.68594 12 6 12C9.31406 12 12 9.31406 12 6C12 2.68594 9.31406 0 6 0ZM6 3C6.93211 3 7.6875 3.75563 7.6875 4.6875C7.6875 5.61937 6.93281 6.375 6 6.375C5.06813 6.375 4.3125 5.61937 4.3125 4.6875C4.3125 3.75563 5.06719 3 6 3ZM6 10.5C4.75945 10.5 3.63516 9.99539 2.81953 9.1807C3.19922 8.20078 4.13672 7.5 5.25 7.5H6.75C7.86422 7.5 8.80172 8.20031 9.18047 9.1807C8.36484 9.99609 7.23984 10.5 6 10.5Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1299">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 562 B After Width: | Height: | Size: 706 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0C1.79063 0 0 1.79063 0 4C0 6.20937 1.79063 8 4 8C6.20937 8 8 6.20937 8 4C8 1.79063 6.20937 0 4 0ZM4 2C4.62141 2 5.125 2.50375 5.125 3.125C5.125 3.74625 4.62187 4.25 4 4.25C3.37875 4.25 2.875 3.74625 2.875 3.125C2.875 2.50375 3.37812 2 4 2ZM4 7C3.17297 7 2.42344 6.66359 1.87969 6.12047C2.13281 5.46719 2.75781 5 3.5 5H4.5C5.24281 5 5.86781 5.46688 6.12031 6.12047C5.57656 6.66406 4.82656 7 4 7Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1382)">
|
||||
<path d="M4 0C1.79063 0 0 1.79063 0 4C0 6.20937 1.79063 8 4 8C6.20937 8 8 6.20937 8 4C8 1.79063 6.20937 0 4 0ZM4 2C4.62141 2 5.125 2.50375 5.125 3.125C5.125 3.74625 4.62187 4.25 4 4.25C3.37875 4.25 2.875 3.74625 2.875 3.125C2.875 2.50375 3.37813 2 4 2ZM4 7C3.17297 7 2.42344 6.66359 1.87969 6.12047C2.13281 5.46719 2.75781 5 3.5 5H4.5C5.24281 5 5.86781 5.46687 6.12031 6.12047C5.57656 6.66406 4.82656 7 4 7Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1382">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 665 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.2 6.00001C5.52563 6.00001 6.6 4.92545 6.6 3.60001C6.6 2.27457 5.52563 1.20001 4.2 1.20001C2.87438 1.20001 1.8 2.27457 1.8 3.60001C1.8 4.92545 2.87438 6.00001 4.2 6.00001ZM5.15063 6.90001H3.24938C1.45444 6.90001 0 8.35501 0 10.1494C0 10.5094 0.291 10.8 0.649875 10.8H7.74937C8.10938 10.8 8.4 10.5094 8.4 10.1494C8.4 8.35501 6.945 6.90001 5.15063 6.90001ZM8.98313 7.20001H7.59844C8.46 7.90689 9 8.96439 9 10.1494C9 10.3894 8.92875 10.6106 8.8125 10.8H11.4C11.7319 10.8 12 10.53 12 10.1831C12 8.54251 10.6575 7.20001 8.98313 7.20001ZM8.1 6.00001C9.26063 6.00001 10.2 5.06064 10.2 3.90001C10.2 2.73939 9.26063 1.80001 8.1 1.80001C7.62919 1.80001 7.19925 1.96042 6.849 2.22207C7.065 2.63682 7.2 3.10126 7.2 3.60001C7.2 4.26601 6.97631 4.87764 6.60769 5.37582C6.98813 5.76001 7.515 6.00001 8.1 6.00001Z" fill="white"/>
|
||||
<path d="M4.2 6.00001C5.52563 6.00001 6.6 4.92545 6.6 3.60001C6.6 2.27457 5.52563 1.20001 4.2 1.20001C2.87438 1.20001 1.8 2.27457 1.8 3.60001C1.8 4.92545 2.87438 6.00001 4.2 6.00001ZM5.15063 6.90001H3.24938C1.45444 6.90001 0 8.35501 0 10.1494C0 10.5094 0.291 10.8 0.649875 10.8H7.74938C8.10938 10.8 8.4 10.5094 8.4 10.1494C8.4 8.35501 6.945 6.90001 5.15063 6.90001ZM8.98313 7.20001H7.59844C8.46 7.90689 9 8.96439 9 10.1494C9 10.3894 8.92875 10.6106 8.8125 10.8H11.4C11.7319 10.8 12 10.53 12 10.1831C12 8.54251 10.6575 7.20001 8.98313 7.20001ZM8.1 6.00001C9.26063 6.00001 10.2 5.06064 10.2 3.90001C10.2 2.73939 9.26063 1.80001 8.1 1.80001C7.62919 1.80001 7.19925 1.96042 6.849 2.22207C7.065 2.63682 7.2 3.10126 7.2 3.60001C7.2 4.26601 6.97631 4.87764 6.60769 5.37582C6.98813 5.76001 7.515 6.00001 8.1 6.00001Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 928 B After Width: | Height: | Size: 928 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.8 3.99999C3.68375 3.99999 4.4 3.28361 4.4 2.39999C4.4 1.51636 3.68375 0.799988 2.8 0.799988C1.91625 0.799988 1.2 1.51636 1.2 2.39999C1.2 3.28361 1.91625 3.99999 2.8 3.99999ZM3.43375 4.59999H2.16625C0.969625 4.59999 0 5.56999 0 6.76624C0 7.00624 0.194 7.19999 0.43325 7.19999H5.16625C5.40625 7.19999 5.6 7.00624 5.6 6.76624C5.6 5.56999 4.63 4.59999 3.43375 4.59999ZM5.98875 4.79999H5.06563C5.64 5.27124 6 5.97624 6 6.76624C6 6.92624 5.9525 7.07374 5.875 7.19999H7.6C7.82125 7.19999 8 7.01999 8 6.78874C8 5.69499 7.105 4.79999 5.98875 4.79999ZM5.4 3.99999C6.17375 3.99999 6.8 3.37374 6.8 2.59999C6.8 1.82624 6.17375 1.19999 5.4 1.19999C5.08612 1.19999 4.7995 1.30693 4.566 1.48136C4.71 1.75786 4.8 2.06749 4.8 2.39999C4.8 2.84399 4.65088 3.25174 4.40513 3.58386C4.65875 3.83999 5.01 3.99999 5.4 3.99999Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1375)">
|
||||
<path d="M2.8 3.99999C3.68375 3.99999 4.4 3.28361 4.4 2.39999C4.4 1.51636 3.68375 0.799988 2.8 0.799988C1.91625 0.799988 1.2 1.51636 1.2 2.39999C1.2 3.28361 1.91625 3.99999 2.8 3.99999ZM3.43375 4.59999H2.16625C0.969625 4.59999 0 5.56999 0 6.76624C0 7.00624 0.194 7.19999 0.43325 7.19999H5.16625C5.40625 7.19999 5.6 7.00624 5.6 6.76624C5.6 5.56999 4.63 4.59999 3.43375 4.59999ZM5.98875 4.79999H5.06563C5.64 5.27124 6 5.97624 6 6.76624C6 6.92624 5.9525 7.07374 5.875 7.19999H7.6C7.82125 7.19999 8 7.01999 8 6.78874C8 5.69499 7.105 4.79999 5.98875 4.79999ZM5.4 3.99999C6.17375 3.99999 6.8 3.37374 6.8 2.59999C6.8 1.82624 6.17375 1.19999 5.4 1.19999C5.08613 1.19999 4.7995 1.30693 4.566 1.48136C4.71 1.75786 4.8 2.06749 4.8 2.39999C4.8 2.84399 4.65088 3.25174 4.40513 3.58386C4.65875 3.83999 5.01 3.99999 5.4 3.99999Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1375">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 929 B After Width: | Height: | Size: 1.0 KiB |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_430_1373)">
|
||||
<path d="M2.8 3.99999C3.68375 3.99999 4.4 3.28361 4.4 2.39999C4.4 1.51636 3.68375 0.799988 2.8 0.799988C1.91625 0.799988 1.2 1.51636 1.2 2.39999C1.2 3.28361 1.91625 3.99999 2.8 3.99999ZM3.43375 4.59999H2.16625C0.970125 4.59999 0 5.56999 0 6.76624C0 7.00624 0.194 7.19999 0.43325 7.19999H5.167C5.40625 7.19999 5.6 7.00624 5.6 6.76624C5.6 5.56999 4.63 4.59999 3.43375 4.59999ZM7.7 3.29999H7.1V2.69999C7.1 2.53499 6.96625 2.39999 6.8 2.39999C6.63375 2.39999 6.5 2.53436 6.5 2.69999V3.29999H5.9C5.735 3.29999 5.6 3.43499 5.6 3.59999C5.6 3.76499 5.73438 3.89999 5.9 3.89999H6.5V4.49999C6.5 4.66624 6.635 4.79999 6.8 4.79999C6.965 4.79999 7.1 4.66561 7.1 4.49999V3.89999H7.7C7.86625 3.89999 8 3.76624 8 3.59999C8 3.43374 7.86625 3.29999 7.7 3.29999Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1373">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 859 B After Width: | Height: | Size: 1001 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.71108 6L0 2.28892L2.28892 0L6 3.71108L9.71108 0L12 2.28892L8.28892 6L12 9.71108L9.71108 12L6 8.28892L2.28892 12L0 9.71108L3.71108 6Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1296)">
|
||||
<path d="M9.5 2.5L6 6M2.5 9.5L6 6M2.5 2.5L6 6M6 6L9.5 9.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1296">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 365 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.32959 8L1 3.67041L3.67041 1L8 5.32959L12.3296 1L15 3.67041L10.6704 8L15 12.3296L12.3296 15L8 10.6704L3.67041 15L1 12.3296L5.32959 8Z" fill="white"/>
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_702_229)">
|
||||
<path d="M11.875 3.125L7.5 7.5M3.125 11.875L7.5 7.5M3.125 3.125L7.5 7.5M7.5 7.5L11.875 11.875" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_702_229">
|
||||
<rect width="15" height="15" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 399 B |
@@ -1,3 +1,10 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.47405 4L0 1.52595L1.52595 0L4 2.47405L6.47405 0L8 1.52595L5.52595 4L8 6.47405L6.47405 8L4 5.52595L1.52595 8L0 6.47405L2.47405 4Z" fill="white"/>
|
||||
<g clip-path="url(#clip0_430_1379)">
|
||||
<path d="M6.49999 1.49999L1.49997 6.5M1.49998 1.50002L6.49999 6.50004" stroke="white" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_430_1379">
|
||||
<rect width="8" height="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 352 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.76433 6.63513C8.0768 6.9476 8.0768 7.4538 7.76433 7.76627C7.60935 7.92251 7.40437 8 7.19939 8C6.99441 8 6.78992 7.92188 6.63394 7.76565L3.99969 5.13264L1.36568 7.7649C1.20945 7.92238 1.00472 7.99988 0.799986 7.99988C0.595255 7.99988 0.390774 7.92238 0.234414 7.7649C-0.0780566 7.45243 -0.0780566 6.94622 0.234414 6.63375L2.86917 3.999L0.234414 1.3655C-0.0780566 1.05303 -0.0780566 0.546824 0.234414 0.234353C0.546885 -0.0781177 1.05309 -0.0781177 1.36556 0.234353L3.99969 2.87023L6.63444 0.235478C6.94691 -0.0769928 7.45311 -0.0769928 7.76558 0.235478C8.07805 0.547949 8.07805 1.05415 7.76558 1.36662L5.13083 4.00138L7.76433 6.63488V6.63513Z" fill="white"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 769 B |
@@ -402,7 +402,9 @@
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"alt-enter": "editor::OpenExcerpts"
|
||||
"alt-enter": "editor::OpenExcerpts",
|
||||
"cmd-f8": "editor::GoToHunk",
|
||||
"cmd-shift-f8": "editor::GoToPrevHunk"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
29
crates/assets/build.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
let output = Command::new("npm")
|
||||
.current_dir("../../styles")
|
||||
.args(["install", "--no-save"])
|
||||
.output()
|
||||
.expect("failed to run npm");
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"failed to install theme dependencies {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
let output = Command::new("npm")
|
||||
.current_dir("../../styles")
|
||||
.args(["run", "build"])
|
||||
.output()
|
||||
.expect("failed to run npm");
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"build script failed {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
println!("cargo:rerun-if-changed=../../styles/src");
|
||||
}
|
||||
@@ -218,11 +218,14 @@ impl AutoUpdater {
|
||||
let temp_dir = tempdir::TempDir::new("zed-auto-update")?;
|
||||
let dmg_path = temp_dir.path().join("Zed.dmg");
|
||||
let mount_path = temp_dir.path().join("Zed");
|
||||
let mut mounted_app_path: OsString = mount_path.join("Zed.app").into();
|
||||
mounted_app_path.push("/");
|
||||
let running_app_path = ZED_APP_PATH
|
||||
.clone()
|
||||
.map_or_else(|| cx.platform().app_path(), Ok)?;
|
||||
let running_app_filename = running_app_path
|
||||
.file_name()
|
||||
.ok_or_else(|| anyhow!("invalid running app path"))?;
|
||||
let mut mounted_app_path: OsString = mount_path.join(running_app_filename).into();
|
||||
mounted_app_path.push("/");
|
||||
|
||||
let mut dmg_file = File::create(&dmg_path).await?;
|
||||
let mut response = client.get(&release.url, Default::default(), true).await?;
|
||||
|
||||
@@ -5,7 +5,7 @@ use gpui::{
|
||||
Element, Entity, MouseButton, View, ViewContext,
|
||||
};
|
||||
use menu::Cancel;
|
||||
use settings::Settings;
|
||||
use settings::{ReleaseChannel, Settings};
|
||||
use workspace::Notification;
|
||||
|
||||
pub struct UpdateNotification {
|
||||
@@ -29,13 +29,15 @@ impl View for UpdateNotification {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let theme = &theme.update_notification;
|
||||
|
||||
let app_name = cx.global::<ReleaseChannel>().name();
|
||||
|
||||
MouseEventHandler::<ViewReleaseNotes>::new(0, cx, |state, cx| {
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Text::new(
|
||||
format!("Updated to Zed {}", self.version),
|
||||
format!("Updated to {app_name} {}", self.version),
|
||||
theme.message.text.clone(),
|
||||
)
|
||||
.contained()
|
||||
@@ -49,7 +51,7 @@ impl View for UpdateNotification {
|
||||
.with_child(
|
||||
MouseEventHandler::<Cancel>::new(0, cx, |state, _| {
|
||||
let style = theme.dismiss_button.style_for(state, false);
|
||||
Svg::new("icons/x_mark_thin_8.svg")
|
||||
Svg::new("icons/x_mark_8.svg")
|
||||
.with_color(style.color)
|
||||
.constrained()
|
||||
.with_width(style.icon_width)
|
||||
|
||||
@@ -1,277 +0,0 @@
|
||||
use crate::http::HttpClient;
|
||||
use db::Db;
|
||||
use gpui::{
|
||||
executor::Background,
|
||||
serde_json::{self, value::Map, Value},
|
||||
AppContext, Task,
|
||||
};
|
||||
use isahc::Request;
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
use std::{
|
||||
io::Write,
|
||||
mem,
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
use tempfile::NamedTempFile;
|
||||
use util::{post_inc, ResultExt, TryFutureExt};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct AmplitudeTelemetry {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
executor: Arc<Background>,
|
||||
session_id: u128,
|
||||
state: Mutex<AmplitudeTelemetryState>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct AmplitudeTelemetryState {
|
||||
metrics_id: Option<Arc<str>>,
|
||||
device_id: Option<Arc<str>>,
|
||||
app_version: Option<Arc<str>>,
|
||||
os_version: Option<Arc<str>>,
|
||||
os_name: &'static str,
|
||||
queue: Vec<AmplitudeEvent>,
|
||||
next_event_id: usize,
|
||||
flush_task: Option<Task<()>>,
|
||||
log_file: Option<NamedTempFile>,
|
||||
}
|
||||
|
||||
const AMPLITUDE_EVENTS_URL: &'static str = "https://api2.amplitude.com/batch";
|
||||
|
||||
lazy_static! {
|
||||
static ref AMPLITUDE_API_KEY: Option<String> = std::env::var("ZED_AMPLITUDE_API_KEY")
|
||||
.ok()
|
||||
.or_else(|| option_env!("ZED_AMPLITUDE_API_KEY").map(|key| key.to_string()));
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct AmplitudeEventBatch {
|
||||
api_key: &'static str,
|
||||
events: Vec<AmplitudeEvent>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct AmplitudeEvent {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
user_id: Option<Arc<str>>,
|
||||
device_id: Option<Arc<str>>,
|
||||
event_type: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
event_properties: Option<Map<String, Value>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
user_properties: Option<Map<String, Value>>,
|
||||
os_name: &'static str,
|
||||
os_version: Option<Arc<str>>,
|
||||
app_version: Option<Arc<str>>,
|
||||
platform: &'static str,
|
||||
event_id: usize,
|
||||
session_id: u128,
|
||||
time: u128,
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
const MAX_QUEUE_LEN: usize = 1;
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
const MAX_QUEUE_LEN: usize = 10;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(1);
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);
|
||||
|
||||
impl AmplitudeTelemetry {
|
||||
pub fn new(client: Arc<dyn HttpClient>, cx: &AppContext) -> Arc<Self> {
|
||||
let platform = cx.platform();
|
||||
let this = Arc::new(Self {
|
||||
http_client: client,
|
||||
executor: cx.background().clone(),
|
||||
session_id: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis(),
|
||||
state: Mutex::new(AmplitudeTelemetryState {
|
||||
os_version: platform
|
||||
.os_version()
|
||||
.log_err()
|
||||
.map(|v| v.to_string().into()),
|
||||
os_name: platform.os_name().into(),
|
||||
app_version: platform
|
||||
.app_version()
|
||||
.log_err()
|
||||
.map(|v| v.to_string().into()),
|
||||
device_id: None,
|
||||
queue: Default::default(),
|
||||
flush_task: Default::default(),
|
||||
next_event_id: 0,
|
||||
log_file: None,
|
||||
metrics_id: None,
|
||||
}),
|
||||
});
|
||||
|
||||
if AMPLITUDE_API_KEY.is_some() {
|
||||
this.executor
|
||||
.spawn({
|
||||
let this = this.clone();
|
||||
async move {
|
||||
if let Some(tempfile) = NamedTempFile::new().log_err() {
|
||||
this.state.lock().log_file = Some(tempfile);
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
this
|
||||
}
|
||||
|
||||
pub fn log_file_path(&self) -> Option<PathBuf> {
|
||||
Some(self.state.lock().log_file.as_ref()?.path().to_path_buf())
|
||||
}
|
||||
|
||||
pub fn start(self: &Arc<Self>, db: Db) {
|
||||
let this = self.clone();
|
||||
self.executor
|
||||
.spawn(
|
||||
async move {
|
||||
let device_id = if let Ok(Some(device_id)) = db.read_kvp("device_id") {
|
||||
device_id
|
||||
} else {
|
||||
let device_id = Uuid::new_v4().to_string();
|
||||
db.write_kvp("device_id", &device_id)?;
|
||||
device_id
|
||||
};
|
||||
|
||||
let device_id = Some(Arc::from(device_id));
|
||||
let mut state = this.state.lock();
|
||||
state.device_id = device_id.clone();
|
||||
for event in &mut state.queue {
|
||||
event.device_id = device_id.clone();
|
||||
}
|
||||
if !state.queue.is_empty() {
|
||||
drop(state);
|
||||
this.flush();
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
}
|
||||
.log_err(),
|
||||
)
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn set_authenticated_user_info(
|
||||
self: &Arc<Self>,
|
||||
metrics_id: Option<String>,
|
||||
is_staff: bool,
|
||||
) {
|
||||
let is_signed_in = metrics_id.is_some();
|
||||
self.state.lock().metrics_id = metrics_id.map(|s| s.into());
|
||||
if is_signed_in {
|
||||
self.report_event_with_user_properties(
|
||||
"$identify",
|
||||
Default::default(),
|
||||
json!({ "$set": { "staff": is_staff } }),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_event(self: &Arc<Self>, kind: &str, properties: Value) {
|
||||
self.report_event_with_user_properties(kind, properties, Default::default());
|
||||
}
|
||||
|
||||
fn report_event_with_user_properties(
|
||||
self: &Arc<Self>,
|
||||
kind: &str,
|
||||
properties: Value,
|
||||
user_properties: Value,
|
||||
) {
|
||||
if AMPLITUDE_API_KEY.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut state = self.state.lock();
|
||||
let event = AmplitudeEvent {
|
||||
event_type: kind.to_string(),
|
||||
time: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis(),
|
||||
session_id: self.session_id,
|
||||
event_properties: if let Value::Object(properties) = properties {
|
||||
Some(properties)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
user_properties: if let Value::Object(user_properties) = user_properties {
|
||||
Some(user_properties)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
user_id: state.metrics_id.clone(),
|
||||
device_id: state.device_id.clone(),
|
||||
os_name: state.os_name,
|
||||
platform: "Zed",
|
||||
os_version: state.os_version.clone(),
|
||||
app_version: state.app_version.clone(),
|
||||
event_id: post_inc(&mut state.next_event_id),
|
||||
};
|
||||
state.queue.push(event);
|
||||
if state.device_id.is_some() {
|
||||
if state.queue.len() >= MAX_QUEUE_LEN {
|
||||
drop(state);
|
||||
self.flush();
|
||||
} else {
|
||||
let this = self.clone();
|
||||
let executor = self.executor.clone();
|
||||
state.flush_task = Some(self.executor.spawn(async move {
|
||||
executor.timer(DEBOUNCE_INTERVAL).await;
|
||||
this.flush();
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(self: &Arc<Self>) {
|
||||
let mut state = self.state.lock();
|
||||
let events = mem::take(&mut state.queue);
|
||||
state.flush_task.take();
|
||||
drop(state);
|
||||
|
||||
if let Some(api_key) = AMPLITUDE_API_KEY.as_ref() {
|
||||
let this = self.clone();
|
||||
self.executor
|
||||
.spawn(
|
||||
async move {
|
||||
let mut json_bytes = Vec::new();
|
||||
|
||||
if let Some(file) = &mut this.state.lock().log_file {
|
||||
let file = file.as_file_mut();
|
||||
for event in &events {
|
||||
json_bytes.clear();
|
||||
serde_json::to_writer(&mut json_bytes, event)?;
|
||||
file.write_all(&json_bytes)?;
|
||||
file.write(b"\n")?;
|
||||
}
|
||||
}
|
||||
|
||||
let batch = AmplitudeEventBatch { api_key, events };
|
||||
json_bytes.clear();
|
||||
serde_json::to_writer(&mut json_bytes, &batch)?;
|
||||
let request =
|
||||
Request::post(AMPLITUDE_EVENTS_URL).body(json_bytes.into())?;
|
||||
this.http_client.send(request).await?;
|
||||
Ok(())
|
||||
}
|
||||
.log_err(),
|
||||
)
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub mod test;
|
||||
|
||||
pub mod amplitude_telemetry;
|
||||
pub mod channel;
|
||||
pub mod http;
|
||||
pub mod telemetry;
|
||||
pub mod user;
|
||||
|
||||
use amplitude_telemetry::AmplitudeTelemetry;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_recursion::async_recursion;
|
||||
use async_tungstenite::tungstenite::{
|
||||
@@ -85,7 +83,6 @@ pub struct Client {
|
||||
peer: Arc<Peer>,
|
||||
http: Arc<dyn HttpClient>,
|
||||
telemetry: Arc<Telemetry>,
|
||||
amplitude_telemetry: Arc<AmplitudeTelemetry>,
|
||||
state: RwLock<ClientState>,
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
@@ -265,7 +262,6 @@ impl Client {
|
||||
id: 0,
|
||||
peer: Peer::new(),
|
||||
telemetry: Telemetry::new(http.clone(), cx),
|
||||
amplitude_telemetry: AmplitudeTelemetry::new(http.clone(), cx),
|
||||
http,
|
||||
state: Default::default(),
|
||||
|
||||
@@ -378,8 +374,6 @@ impl Client {
|
||||
}
|
||||
Status::SignedOut | Status::UpgradeRequired => {
|
||||
self.telemetry.set_authenticated_user_info(None, false);
|
||||
self.amplitude_telemetry
|
||||
.set_authenticated_user_info(None, false);
|
||||
state._reconnect_task.take();
|
||||
}
|
||||
_ => {}
|
||||
@@ -835,11 +829,14 @@ impl Client {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(handler) = state.message_handlers.get(&payload_type_id).cloned()
|
||||
{
|
||||
drop(state); // Avoid deadlocks if the handler interacts with rpc::Client
|
||||
let future = handler(model, message, &this, cx.clone());
|
||||
let handler = state.message_handlers.get(&payload_type_id).cloned();
|
||||
// Dropping the state prevents deadlocks if the handler interacts with rpc::Client.
|
||||
// It also ensures we don't hold the lock while yielding back to the executor, as
|
||||
// that might cause the executor thread driving this future to block indefinitely.
|
||||
drop(state);
|
||||
|
||||
if let Some(handler) = handler {
|
||||
let future = handler(model, message, &this, cx.clone());
|
||||
let client_id = this.id;
|
||||
log::debug!(
|
||||
"rpc message received. client_id:{}, message_id:{}, sender_id:{:?}, type:{}",
|
||||
@@ -1029,7 +1026,6 @@ impl Client {
|
||||
let platform = cx.platform();
|
||||
let executor = cx.background();
|
||||
let telemetry = self.telemetry.clone();
|
||||
let amplitude_telemetry = self.amplitude_telemetry.clone();
|
||||
let http = self.http.clone();
|
||||
executor.clone().spawn(async move {
|
||||
// Generate a pair of asymmetric encryption keys. The public key will be used by the
|
||||
@@ -1114,7 +1110,6 @@ impl Client {
|
||||
platform.activate(true);
|
||||
|
||||
telemetry.report_event("authenticate with browser", Default::default());
|
||||
amplitude_telemetry.report_event("authenticate with browser", Default::default());
|
||||
|
||||
Ok(Credentials {
|
||||
user_id: user_id.parse()?,
|
||||
@@ -1227,16 +1222,13 @@ impl Client {
|
||||
|
||||
pub fn start_telemetry(&self, db: Db) {
|
||||
self.telemetry.start(db.clone());
|
||||
self.amplitude_telemetry.start(db);
|
||||
}
|
||||
|
||||
pub fn report_event(&self, kind: &str, properties: Value) {
|
||||
self.telemetry.report_event(kind, properties.clone());
|
||||
self.amplitude_telemetry.report_event(kind, properties);
|
||||
}
|
||||
|
||||
pub fn telemetry_log_file_path(&self) -> Option<PathBuf> {
|
||||
self.amplitude_telemetry.log_file_path();
|
||||
self.telemetry.log_file_path()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use lazy_static::lazy_static;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
use settings::ReleaseChannel;
|
||||
use std::{
|
||||
io::Write,
|
||||
mem,
|
||||
@@ -32,6 +33,7 @@ struct TelemetryState {
|
||||
metrics_id: Option<Arc<str>>,
|
||||
device_id: Option<Arc<str>>,
|
||||
app_version: Option<Arc<str>>,
|
||||
release_channel: Option<&'static str>,
|
||||
os_version: Option<Arc<str>>,
|
||||
os_name: &'static str,
|
||||
queue: Vec<MixpanelEvent>,
|
||||
@@ -67,11 +69,16 @@ struct MixpanelEventProperties {
|
||||
// Custom fields
|
||||
#[serde(skip_serializing_if = "Option::is_none", flatten)]
|
||||
event_properties: Option<Map<String, Value>>,
|
||||
#[serde(rename = "OS Name")]
|
||||
os_name: &'static str,
|
||||
#[serde(rename = "OS Version")]
|
||||
os_version: Option<Arc<str>>,
|
||||
#[serde(rename = "Release Channel")]
|
||||
release_channel: Option<&'static str>,
|
||||
#[serde(rename = "App Version")]
|
||||
app_version: Option<Arc<str>>,
|
||||
#[serde(rename = "Signed In")]
|
||||
signed_in: bool,
|
||||
platform: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -99,19 +106,19 @@ const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);
|
||||
impl Telemetry {
|
||||
pub fn new(client: Arc<dyn HttpClient>, cx: &AppContext) -> Arc<Self> {
|
||||
let platform = cx.platform();
|
||||
let release_channel = if cx.has_global::<ReleaseChannel>() {
|
||||
Some(cx.global::<ReleaseChannel>().name())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let this = Arc::new(Self {
|
||||
http_client: client,
|
||||
executor: cx.background().clone(),
|
||||
state: Mutex::new(TelemetryState {
|
||||
os_version: platform
|
||||
.os_version()
|
||||
.log_err()
|
||||
.map(|v| v.to_string().into()),
|
||||
os_version: platform.os_version().ok().map(|v| v.to_string().into()),
|
||||
os_name: platform.os_name().into(),
|
||||
app_version: platform
|
||||
.app_version()
|
||||
.log_err()
|
||||
.map(|v| v.to_string().into()),
|
||||
app_version: platform.app_version().ok().map(|v| v.to_string().into()),
|
||||
release_channel,
|
||||
device_id: None,
|
||||
metrics_id: None,
|
||||
queue: Default::default(),
|
||||
@@ -194,7 +201,11 @@ impl Telemetry {
|
||||
let json_bytes = serde_json::to_vec(&[MixpanelEngageRequest {
|
||||
token,
|
||||
distinct_id: device_id,
|
||||
set: json!({ "staff": is_staff, "id": metrics_id }),
|
||||
set: json!({
|
||||
"Staff": is_staff,
|
||||
"ID": metrics_id,
|
||||
"App": true
|
||||
}),
|
||||
}])?;
|
||||
let request = Request::post(MIXPANEL_ENGAGE_URL)
|
||||
.header("Content-Type", "application/json")
|
||||
@@ -227,9 +238,9 @@ impl Telemetry {
|
||||
},
|
||||
os_name: state.os_name,
|
||||
os_version: state.os_version.clone(),
|
||||
release_channel: state.release_channel,
|
||||
app_version: state.app_version.clone(),
|
||||
signed_in: state.metrics_id.is_some(),
|
||||
platform: "Zed",
|
||||
},
|
||||
};
|
||||
state.queue.push(event);
|
||||
|
||||
@@ -146,21 +146,11 @@ impl UserStore {
|
||||
Some(info.metrics_id.clone()),
|
||||
info.staff,
|
||||
);
|
||||
client.amplitude_telemetry.set_authenticated_user_info(
|
||||
Some(info.metrics_id),
|
||||
info.staff,
|
||||
);
|
||||
} else {
|
||||
client.telemetry.set_authenticated_user_info(None, false);
|
||||
client
|
||||
.amplitude_telemetry
|
||||
.set_authenticated_user_info(None, false);
|
||||
}
|
||||
|
||||
client.telemetry.report_event("sign in", Default::default());
|
||||
client
|
||||
.amplitude_telemetry
|
||||
.report_event("sign in", Default::default());
|
||||
current_user_tx.send(user).await.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,17 +1041,19 @@ impl Server {
|
||||
|
||||
for conn_id in project.connection_ids() {
|
||||
if conn_id != request.sender_id {
|
||||
self.peer.send(
|
||||
conn_id,
|
||||
proto::AddProjectCollaborator {
|
||||
project_id: project_id.to_proto(),
|
||||
collaborator: Some(proto::Collaborator {
|
||||
peer_id: request.sender_id.0,
|
||||
replica_id: replica_id as u32,
|
||||
user_id: guest_user_id.to_proto(),
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
self.peer
|
||||
.send(
|
||||
conn_id,
|
||||
proto::AddProjectCollaborator {
|
||||
project_id: project_id.to_proto(),
|
||||
collaborator: Some(proto::Collaborator {
|
||||
peer_id: request.sender_id.0,
|
||||
replica_id: replica_id as u32,
|
||||
user_id: guest_user_id.to_proto(),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.trace_err();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -674,8 +674,13 @@ impl Store {
|
||||
.connected_users
|
||||
.get_mut(&recipient_user_id)
|
||||
.ok_or_else(|| anyhow!("no such connection"))?;
|
||||
if let Some(active_call) = recipient.active_call.take() {
|
||||
if let Some(active_call) = recipient.active_call {
|
||||
anyhow::ensure!(active_call.room_id == room_id, "no such room");
|
||||
anyhow::ensure!(
|
||||
active_call.connection_id.is_none(),
|
||||
"cannot decline a call after joining room"
|
||||
);
|
||||
recipient.active_call.take();
|
||||
let recipient_connection_ids = self
|
||||
.connection_ids_for_user(recipient_user_id)
|
||||
.collect::<Vec<_>>();
|
||||
@@ -1196,7 +1201,9 @@ impl Store {
|
||||
assert!(
|
||||
self.connections
|
||||
.contains_key(&ConnectionId(participant.peer_id)),
|
||||
"room contains participant that has disconnected"
|
||||
"room {} contains participant {:?} that has disconnected",
|
||||
room_id,
|
||||
participant
|
||||
);
|
||||
|
||||
for participant_project in &participant.projects {
|
||||
|
||||
@@ -54,6 +54,7 @@ impl View for CollabTitlebarItem {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
let mut container = Flex::row();
|
||||
|
||||
container.add_children(self.render_toggle_screen_sharing_button(&theme, cx));
|
||||
|
||||
if workspace.read(cx).client().status().borrow().is_connected() {
|
||||
@@ -324,6 +325,8 @@ impl CollabTitlebarItem {
|
||||
cx,
|
||||
)
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_left(theme.workspace.titlebar.avatar_margin)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||
)),
|
||||
titlebar: None,
|
||||
center: false,
|
||||
focus: false,
|
||||
kind: WindowKind::PopUp,
|
||||
is_movable: false,
|
||||
screen: Some(screen),
|
||||
|
||||
@@ -52,7 +52,7 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
|
||||
.with_child(
|
||||
MouseEventHandler::<Dismiss>::new(user.id as usize, cx, |state, _| {
|
||||
let style = theme.dismiss_button.style_for(state, false);
|
||||
Svg::new("icons/x_mark_thin_8.svg")
|
||||
Svg::new("icons/x_mark_8.svg")
|
||||
.with_color(style.color)
|
||||
.constrained()
|
||||
.with_width(style.icon_width)
|
||||
|
||||
@@ -40,6 +40,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||
)),
|
||||
titlebar: None,
|
||||
center: false,
|
||||
focus: false,
|
||||
kind: WindowKind::PopUp,
|
||||
is_movable: false,
|
||||
screen: Some(screen),
|
||||
|
||||
@@ -18,7 +18,7 @@ lazy_static = "1.4.0"
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
|
||||
parking_lot = "0.11.1"
|
||||
rusqlite = { version = "0.28.0", features = ["bundled", "serde_json"] }
|
||||
rusqlite_migration = "1.0.0"
|
||||
rusqlite_migration = { git = "https://github.com/cljoly/rusqlite_migration", rev = "c433555d7c1b41b103426e35756eb3144d0ebbc6" }
|
||||
serde = { workspace = true }
|
||||
serde_rusqlite = "0.31.0"
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ pub struct RealDb {
|
||||
|
||||
impl Db {
|
||||
/// Open or create a database at the given directory path.
|
||||
pub fn open(db_dir: &Path) -> Self {
|
||||
pub fn open(db_dir: &Path, channel: &'static str) -> Self {
|
||||
// Use 0 for now. Will implement incrementing and clearing of old db files soon TM
|
||||
let current_db_dir = db_dir.join(Path::new("0"));
|
||||
let current_db_dir = db_dir.join(Path::new(&format!("0-{}", channel)));
|
||||
fs::create_dir_all(¤t_db_dir)
|
||||
.expect("Should be able to create the database directory");
|
||||
let db_path = current_db_dir.join(Path::new("db.sqlite"));
|
||||
|
||||
@@ -100,7 +100,7 @@ impl View for ProjectDiagnosticsEditor {
|
||||
}
|
||||
|
||||
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
if !self.path_states.is_empty() {
|
||||
if cx.is_self_focused() && !self.path_states.is_empty() {
|
||||
cx.focus(&self.editor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@ impl BlinkManager {
|
||||
if epoch == self.blink_epoch && self.enabled && !self.blinking_paused {
|
||||
self.visible = !self.visible;
|
||||
cx.notify();
|
||||
dbg!(cx.handle());
|
||||
|
||||
let epoch = self.next_blink_epoch();
|
||||
let interval = self.blink_interval;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
mod blink_manager;
|
||||
pub mod display_map;
|
||||
mod element;
|
||||
mod git;
|
||||
mod highlight_matching_bracket;
|
||||
mod hover_popover;
|
||||
pub mod items;
|
||||
@@ -42,6 +43,7 @@ use gpui::{
|
||||
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
||||
use hover_popover::{hide_hover, HoverState};
|
||||
pub use items::MAX_TAB_TITLE_LEN;
|
||||
use itertools::Itertools;
|
||||
pub use language::{char_kind, CharKind};
|
||||
use language::{
|
||||
AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, CursorShape,
|
||||
@@ -79,6 +81,8 @@ use theme::{DiagnosticStyle, Theme};
|
||||
use util::{post_inc, ResultExt, TryFutureExt};
|
||||
use workspace::{ItemNavHistory, Workspace};
|
||||
|
||||
use crate::git::diff_hunk_to_display;
|
||||
|
||||
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
|
||||
const MAX_LINE_LEN: usize = 1024;
|
||||
@@ -162,6 +166,8 @@ actions!(
|
||||
NewlineBelow,
|
||||
GoToDiagnostic,
|
||||
GoToPrevDiagnostic,
|
||||
GoToHunk,
|
||||
GoToPrevHunk,
|
||||
Indent,
|
||||
Outdent,
|
||||
DeleteLine,
|
||||
@@ -338,6 +344,8 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||
cx.add_action(Editor::redo_selection);
|
||||
cx.add_action(Editor::go_to_diagnostic);
|
||||
cx.add_action(Editor::go_to_prev_diagnostic);
|
||||
cx.add_action(Editor::go_to_hunk);
|
||||
cx.add_action(Editor::go_to_prev_hunk);
|
||||
cx.add_action(Editor::go_to_definition);
|
||||
cx.add_action(Editor::go_to_type_definition);
|
||||
cx.add_action(Editor::fold);
|
||||
@@ -1353,6 +1361,7 @@ impl Editor {
|
||||
) {
|
||||
self.scroll_top_anchor = anchor;
|
||||
self.scroll_position = position;
|
||||
self.make_scrollbar_visible(cx);
|
||||
cx.emit(Event::ScrollPositionChanged { local: false });
|
||||
cx.notify();
|
||||
}
|
||||
@@ -5231,6 +5240,72 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
fn go_to_hunk(&mut self, _: &GoToHunk, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_hunk_impl(Direction::Next, cx)
|
||||
}
|
||||
|
||||
fn go_to_prev_hunk(&mut self, _: &GoToPrevHunk, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_hunk_impl(Direction::Prev, cx)
|
||||
}
|
||||
|
||||
pub fn go_to_hunk_impl(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
|
||||
let snapshot = self
|
||||
.display_map
|
||||
.update(cx, |display_map, cx| display_map.snapshot(cx));
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
|
||||
fn seek_in_direction(
|
||||
this: &mut Editor,
|
||||
snapshot: &DisplaySnapshot,
|
||||
initial_point: Point,
|
||||
is_wrapped: bool,
|
||||
direction: Direction,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> bool {
|
||||
let hunks = if direction == Direction::Next {
|
||||
snapshot
|
||||
.buffer_snapshot
|
||||
.git_diff_hunks_in_range(initial_point.row..u32::MAX, false)
|
||||
} else {
|
||||
snapshot
|
||||
.buffer_snapshot
|
||||
.git_diff_hunks_in_range(0..initial_point.row, true)
|
||||
};
|
||||
|
||||
let display_point = initial_point.to_display_point(snapshot);
|
||||
let mut hunks = hunks
|
||||
.map(|hunk| diff_hunk_to_display(hunk, &snapshot))
|
||||
.skip_while(|hunk| {
|
||||
if is_wrapped {
|
||||
false
|
||||
} else {
|
||||
hunk.contains_display_row(display_point.row())
|
||||
}
|
||||
})
|
||||
.dedup();
|
||||
|
||||
if let Some(hunk) = hunks.next() {
|
||||
this.change_selections(Some(Autoscroll::Center), cx, |s| {
|
||||
let row = hunk.start_display_row();
|
||||
let point = DisplayPoint::new(row, 0);
|
||||
s.select_display_ranges([point..point]);
|
||||
});
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
if !seek_in_direction(self, &snapshot, selection.head(), false, direction, cx) {
|
||||
let wrapped_point = match direction {
|
||||
Direction::Next => Point::zero(),
|
||||
Direction::Prev => snapshot.buffer_snapshot.max_point(),
|
||||
};
|
||||
seek_in_direction(self, &snapshot, wrapped_point, true, direction, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn go_to_definition(
|
||||
workspace: &mut Workspace,
|
||||
_: &GoToDefinition,
|
||||
@@ -6395,7 +6470,7 @@ impl Editor {
|
||||
project.read(cx).client().report_event(
|
||||
name,
|
||||
json!({
|
||||
"file_extension": file
|
||||
"File Extension": file
|
||||
.path()
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::test::{
|
||||
editor_test_context::EditorTestContext, select_ranges,
|
||||
};
|
||||
use gpui::{
|
||||
executor::Deterministic,
|
||||
geometry::rect::RectF,
|
||||
platform::{WindowBounds, WindowOptions},
|
||||
};
|
||||
@@ -1566,7 +1567,7 @@ async fn test_tab(cx: &mut gpui::TestAppContext) {
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_tab_on_blank_line_auto_indents(cx: &mut gpui::TestAppContext) {
|
||||
async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorTestContext::new(cx);
|
||||
let language = Arc::new(
|
||||
Language::new(
|
||||
@@ -1623,6 +1624,43 @@ async fn test_tab_on_blank_line_auto_indents(cx: &mut gpui::TestAppContext) {
|
||||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_tab_with_mixed_whitespace(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorTestContext::new(cx);
|
||||
let language = Arc::new(
|
||||
Language::new(
|
||||
LanguageConfig::default(),
|
||||
Some(tree_sitter_rust::language()),
|
||||
)
|
||||
.with_indents_query(r#"(_ "{" "}" @end) @indent"#)
|
||||
.unwrap(),
|
||||
);
|
||||
cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
|
||||
|
||||
cx.update(|cx| {
|
||||
cx.update_global::<Settings, _, _>(|settings, _| {
|
||||
settings.editor_overrides.tab_size = Some(4.try_into().unwrap());
|
||||
});
|
||||
});
|
||||
|
||||
cx.set_state(indoc! {"
|
||||
fn a() {
|
||||
if b {
|
||||
\t ˇc
|
||||
}
|
||||
}
|
||||
"});
|
||||
|
||||
cx.update_editor(|e, cx| e.tab(&Tab, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
fn a() {
|
||||
if b {
|
||||
ˇc
|
||||
}
|
||||
}
|
||||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorTestContext::new(cx);
|
||||
@@ -5079,6 +5117,111 @@ fn test_combine_syntax_and_fuzzy_match_highlights() {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn go_to_hunk(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorTestContext::new(cx);
|
||||
|
||||
let diff_base = r#"
|
||||
use some::mod;
|
||||
|
||||
const A: u32 = 42;
|
||||
|
||||
fn main() {
|
||||
println!("hello");
|
||||
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent();
|
||||
|
||||
// Edits are modified, removed, modified, added
|
||||
cx.set_state(
|
||||
&r#"
|
||||
use some::modified;
|
||||
|
||||
ˇ
|
||||
fn main() {
|
||||
println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.set_diff_base(Some(&diff_base));
|
||||
deterministic.run_until_parked();
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
//Wrap around the bottom of the buffer
|
||||
for _ in 0..3 {
|
||||
editor.go_to_hunk(&GoToHunk, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.assert_editor_state(
|
||||
&r#"
|
||||
ˇuse some::modified;
|
||||
|
||||
|
||||
fn main() {
|
||||
println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
//Wrap around the top of the buffer
|
||||
for _ in 0..2 {
|
||||
editor.go_to_prev_hunk(&GoToPrevHunk, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.assert_editor_state(
|
||||
&r#"
|
||||
use some::modified;
|
||||
|
||||
|
||||
fn main() {
|
||||
ˇ println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
editor.fold(&Fold, cx);
|
||||
|
||||
//Make sure that the fold only gets one hunk
|
||||
for _ in 0..4 {
|
||||
editor.go_to_hunk(&GoToHunk, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.assert_editor_state(
|
||||
&r#"
|
||||
ˇuse some::modified;
|
||||
|
||||
|
||||
fn main() {
|
||||
println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
}
|
||||
|
||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||
let point = DisplayPoint::new(row as u32, column as u32);
|
||||
point..point
|
||||
|
||||
@@ -5,6 +5,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
display_map::{BlockStyle, DisplaySnapshot, TransformBlock},
|
||||
git::{diff_hunk_to_display, DisplayDiffHunk},
|
||||
hover_popover::{
|
||||
HoverAt, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT,
|
||||
},
|
||||
@@ -12,7 +13,7 @@ use crate::{
|
||||
GoToFetchedDefinition, GoToFetchedTypeDefinition, UpdateGoToDefinitionLink,
|
||||
},
|
||||
mouse_context_menu::DeployMouseContextMenu,
|
||||
AnchorRangeExt, EditorStyle,
|
||||
EditorStyle,
|
||||
};
|
||||
use clock::ReplicaId;
|
||||
use collections::{BTreeMap, HashMap};
|
||||
@@ -33,8 +34,9 @@ use gpui::{
|
||||
Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, MutableAppContext,
|
||||
PaintContext, Quad, SceneBuilder, SizeConstraint, ViewContext, WeakViewHandle,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use json::json;
|
||||
use language::{Bias, CursorShape, DiagnosticSeverity, OffsetUtf16, Point, Selection};
|
||||
use language::{Bias, CursorShape, DiagnosticSeverity, OffsetUtf16, Selection};
|
||||
use project::ProjectPath;
|
||||
use settings::{GitGutter, Settings};
|
||||
use smallvec::SmallVec;
|
||||
@@ -46,13 +48,6 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DiffHunkLayout {
|
||||
visual_range: Range<u32>,
|
||||
status: DiffHunkStatus,
|
||||
is_folded: bool,
|
||||
}
|
||||
|
||||
struct SelectionLayout {
|
||||
head: DisplayPoint,
|
||||
cursor_shape: CursorShape,
|
||||
@@ -576,14 +571,41 @@ impl EditorElement {
|
||||
let scroll_position = layout.position_map.snapshot.scroll_position();
|
||||
let scroll_top = scroll_position.y() * line_height;
|
||||
|
||||
for hunk in &layout.hunk_layouts {
|
||||
let color = match (hunk.status, hunk.is_folded) {
|
||||
(DiffHunkStatus::Added, false) => diff_style.inserted,
|
||||
(DiffHunkStatus::Modified, false) => diff_style.modified,
|
||||
for hunk in &layout.display_hunks {
|
||||
let (display_row_range, status) = match hunk {
|
||||
//TODO: This rendering is entirely a horrible hack
|
||||
&DisplayDiffHunk::Folded { display_row: row } => {
|
||||
let start_y = row as f32 * line_height - scroll_top;
|
||||
let end_y = start_y + line_height;
|
||||
|
||||
let width = diff_style.removed_width_em * line_height;
|
||||
let highlight_origin = bounds.origin() + vec2f(-width, start_y);
|
||||
let highlight_size = vec2f(width * 2., end_y - start_y);
|
||||
let highlight_bounds = RectF::new(highlight_origin, highlight_size);
|
||||
|
||||
cx.scene.push_quad(Quad {
|
||||
bounds: highlight_bounds,
|
||||
background: Some(diff_style.modified),
|
||||
border: Border::new(0., Color::transparent_black()),
|
||||
corner_radius: 1. * line_height,
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range,
|
||||
status,
|
||||
} => (display_row_range, status),
|
||||
};
|
||||
|
||||
let color = match status {
|
||||
DiffHunkStatus::Added => diff_style.inserted,
|
||||
DiffHunkStatus::Modified => diff_style.modified,
|
||||
|
||||
//TODO: This rendering is entirely a horrible hack
|
||||
(DiffHunkStatus::Removed, false) => {
|
||||
let row = hunk.visual_range.start;
|
||||
DiffHunkStatus::Removed => {
|
||||
let row = *display_row_range.start();
|
||||
|
||||
let offset = line_height / 2.;
|
||||
let start_y = row as f32 * line_height - offset - scroll_top;
|
||||
@@ -603,33 +625,13 @@ impl EditorElement {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
(_, true) => {
|
||||
let row = hunk.visual_range.start;
|
||||
let start_y = row as f32 * line_height - scroll_top;
|
||||
let end_y = start_y + line_height;
|
||||
|
||||
let width = diff_style.removed_width_em * line_height;
|
||||
let highlight_origin = bounds.origin() + vec2f(-width, start_y);
|
||||
let highlight_size = vec2f(width * 2., end_y - start_y);
|
||||
let highlight_bounds = RectF::new(highlight_origin, highlight_size);
|
||||
|
||||
cx.scene.push_quad(Quad {
|
||||
bounds: highlight_bounds,
|
||||
background: Some(diff_style.modified),
|
||||
border: Border::new(0., Color::transparent_black()),
|
||||
corner_radius: 1. * line_height,
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let start_row = hunk.visual_range.start;
|
||||
let end_row = hunk.visual_range.end;
|
||||
let start_row = *display_row_range.start();
|
||||
let end_row = *display_row_range.end();
|
||||
|
||||
let start_y = start_row as f32 * line_height - scroll_top;
|
||||
let end_y = end_row as f32 * line_height - scroll_top;
|
||||
let end_y = end_row as f32 * line_height - scroll_top + line_height;
|
||||
|
||||
let width = diff_style.width_em * line_height;
|
||||
let highlight_origin = bounds.origin() + vec2f(-width, start_y);
|
||||
@@ -1107,69 +1109,23 @@ impl EditorElement {
|
||||
//If a fold contains any hunks then that fold line is marked as modified
|
||||
fn layout_git_gutters(
|
||||
&self,
|
||||
rows: Range<u32>,
|
||||
display_rows: Range<u32>,
|
||||
snapshot: &EditorSnapshot,
|
||||
) -> Vec<DiffHunkLayout> {
|
||||
) -> Vec<DisplayDiffHunk> {
|
||||
let buffer_snapshot = &snapshot.buffer_snapshot;
|
||||
let visual_start = DisplayPoint::new(rows.start, 0).to_point(snapshot).row;
|
||||
let visual_end = DisplayPoint::new(rows.end, 0).to_point(snapshot).row;
|
||||
let hunks = buffer_snapshot.git_diff_hunks_in_range(visual_start..visual_end);
|
||||
|
||||
let mut layouts = Vec::<DiffHunkLayout>::new();
|
||||
let buffer_start_row = DisplayPoint::new(display_rows.start, 0)
|
||||
.to_point(snapshot)
|
||||
.row;
|
||||
let buffer_end_row = DisplayPoint::new(display_rows.end, 0)
|
||||
.to_point(snapshot)
|
||||
.row;
|
||||
|
||||
for hunk in hunks {
|
||||
let hunk_start_point = Point::new(hunk.buffer_range.start, 0);
|
||||
let hunk_end_point = Point::new(hunk.buffer_range.end, 0);
|
||||
let hunk_start_point_sub = Point::new(hunk.buffer_range.start.saturating_sub(1), 0);
|
||||
let hunk_end_point_sub = Point::new(
|
||||
hunk.buffer_range
|
||||
.end
|
||||
.saturating_sub(1)
|
||||
.max(hunk.buffer_range.start),
|
||||
0,
|
||||
);
|
||||
|
||||
let is_removal = hunk.status() == DiffHunkStatus::Removed;
|
||||
|
||||
let folds_start = Point::new(hunk.buffer_range.start.saturating_sub(1), 0);
|
||||
let folds_end = Point::new(hunk.buffer_range.end + 1, 0);
|
||||
let folds_range = folds_start..folds_end;
|
||||
|
||||
let containing_fold = snapshot.folds_in_range(folds_range).find(|fold_range| {
|
||||
let fold_point_range = fold_range.to_point(buffer_snapshot);
|
||||
let fold_point_range = fold_point_range.start..=fold_point_range.end;
|
||||
|
||||
let folded_start = fold_point_range.contains(&hunk_start_point);
|
||||
let folded_end = fold_point_range.contains(&hunk_end_point_sub);
|
||||
let folded_start_sub = fold_point_range.contains(&hunk_start_point_sub);
|
||||
|
||||
(folded_start && folded_end) || (is_removal && folded_start_sub)
|
||||
});
|
||||
|
||||
let visual_range = if let Some(fold) = containing_fold {
|
||||
let row = fold.start.to_display_point(snapshot).row();
|
||||
row..row
|
||||
} else {
|
||||
let start = hunk_start_point.to_display_point(snapshot).row();
|
||||
let end = hunk_end_point.to_display_point(snapshot).row();
|
||||
start..end
|
||||
};
|
||||
|
||||
let has_existing_layout = match layouts.last() {
|
||||
Some(e) => visual_range == e.visual_range && e.status == hunk.status(),
|
||||
None => false,
|
||||
};
|
||||
|
||||
if !has_existing_layout {
|
||||
layouts.push(DiffHunkLayout {
|
||||
visual_range,
|
||||
status: hunk.status(),
|
||||
is_folded: containing_fold.is_some(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
layouts
|
||||
buffer_snapshot
|
||||
.git_diff_hunks_in_range(buffer_start_row..buffer_end_row, false)
|
||||
.map(|hunk| diff_hunk_to_display(hunk, snapshot))
|
||||
.dedup()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn layout_line_numbers(
|
||||
@@ -1721,7 +1677,7 @@ impl Element for EditorElement {
|
||||
let line_number_layouts =
|
||||
self.layout_line_numbers(start_row..end_row, &active_rows, &snapshot, cx);
|
||||
|
||||
let hunk_layouts = self.layout_git_gutters(start_row..end_row, &snapshot);
|
||||
let display_hunks = self.layout_git_gutters(start_row..end_row, &snapshot);
|
||||
|
||||
let scrollbar_row_range = scroll_position.y()..(scroll_position.y() + height_in_lines);
|
||||
|
||||
@@ -1880,7 +1836,7 @@ impl Element for EditorElement {
|
||||
highlighted_rows,
|
||||
highlighted_ranges,
|
||||
line_number_layouts,
|
||||
hunk_layouts,
|
||||
display_hunks,
|
||||
blocks,
|
||||
selections,
|
||||
context_menu,
|
||||
@@ -2002,7 +1958,7 @@ pub struct LayoutState {
|
||||
active_rows: BTreeMap<u32, bool>,
|
||||
highlighted_rows: Option<Range<u32>>,
|
||||
line_number_layouts: Vec<Option<text_layout::Line>>,
|
||||
hunk_layouts: Vec<DiffHunkLayout>,
|
||||
display_hunks: Vec<DisplayDiffHunk>,
|
||||
blocks: Vec<BlockLayout>,
|
||||
highlighted_ranges: Vec<(Range<DisplayPoint>, Color)>,
|
||||
selections: Vec<(ReplicaId, Vec<SelectionLayout>)>,
|
||||
|
||||
93
crates/editor/src/git.rs
Normal file
@@ -0,0 +1,93 @@
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use git::diff::{DiffHunk, DiffHunkStatus};
|
||||
use language::Point;
|
||||
|
||||
use crate::{
|
||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||
AnchorRangeExt,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum DisplayDiffHunk {
|
||||
Folded {
|
||||
display_row: u32,
|
||||
},
|
||||
|
||||
Unfolded {
|
||||
display_row_range: RangeInclusive<u32>,
|
||||
status: DiffHunkStatus,
|
||||
},
|
||||
}
|
||||
|
||||
impl DisplayDiffHunk {
|
||||
pub fn start_display_row(&self) -> u32 {
|
||||
match self {
|
||||
&DisplayDiffHunk::Folded { display_row } => display_row,
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range, ..
|
||||
} => *display_row_range.start(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_display_row(&self, display_row: u32) -> bool {
|
||||
let range = match self {
|
||||
&DisplayDiffHunk::Folded { display_row } => display_row..=display_row,
|
||||
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range, ..
|
||||
} => display_row_range.clone(),
|
||||
};
|
||||
|
||||
range.contains(&display_row)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn diff_hunk_to_display(hunk: DiffHunk<u32>, snapshot: &DisplaySnapshot) -> DisplayDiffHunk {
|
||||
let hunk_start_point = Point::new(hunk.buffer_range.start, 0);
|
||||
let hunk_start_point_sub = Point::new(hunk.buffer_range.start.saturating_sub(1), 0);
|
||||
let hunk_end_point_sub = Point::new(
|
||||
hunk.buffer_range
|
||||
.end
|
||||
.saturating_sub(1)
|
||||
.max(hunk.buffer_range.start),
|
||||
0,
|
||||
);
|
||||
|
||||
let is_removal = hunk.status() == DiffHunkStatus::Removed;
|
||||
|
||||
let folds_start = Point::new(hunk.buffer_range.start.saturating_sub(2), 0);
|
||||
let folds_end = Point::new(hunk.buffer_range.end + 2, 0);
|
||||
let folds_range = folds_start..folds_end;
|
||||
|
||||
let containing_fold = snapshot.folds_in_range(folds_range).find(|fold_range| {
|
||||
let fold_point_range = fold_range.to_point(&snapshot.buffer_snapshot);
|
||||
let fold_point_range = fold_point_range.start..=fold_point_range.end;
|
||||
|
||||
let folded_start = fold_point_range.contains(&hunk_start_point);
|
||||
let folded_end = fold_point_range.contains(&hunk_end_point_sub);
|
||||
let folded_start_sub = fold_point_range.contains(&hunk_start_point_sub);
|
||||
|
||||
(folded_start && folded_end) || (is_removal && folded_start_sub)
|
||||
});
|
||||
|
||||
if let Some(fold) = containing_fold {
|
||||
let row = fold.start.to_display_point(snapshot).row();
|
||||
DisplayDiffHunk::Folded { display_row: row }
|
||||
} else {
|
||||
let start = hunk_start_point.to_display_point(snapshot).row();
|
||||
|
||||
let hunk_end_row_inclusive = hunk
|
||||
.buffer_range
|
||||
.end
|
||||
.saturating_sub(1)
|
||||
.max(hunk.buffer_range.start);
|
||||
let hunk_end_point = Point::new(hunk_end_row_inclusive, 0);
|
||||
let end = hunk_end_point.to_display_point(snapshot).row();
|
||||
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range: start..=end,
|
||||
status: hunk.status(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2592,10 +2592,13 @@ impl MultiBufferSnapshot {
|
||||
pub fn git_diff_hunks_in_range<'a>(
|
||||
&'a self,
|
||||
row_range: Range<u32>,
|
||||
reversed: bool,
|
||||
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||
self.as_singleton()
|
||||
.into_iter()
|
||||
.flat_map(move |(_, _, buffer)| buffer.git_diff_hunks_in_range(row_range.clone()))
|
||||
.flat_map(move |(_, _, buffer)| {
|
||||
buffer.git_diff_hunks_in_range(row_range.clone(), reversed)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
|
||||
|
||||
@@ -594,7 +594,6 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||
self.select_anchors(selections)
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn select_display_ranges<T>(&mut self, ranges: T)
|
||||
where
|
||||
T: IntoIterator<Item = Range<DisplayPoint>>,
|
||||
@@ -678,6 +677,19 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn maybe_move_cursors_with(
|
||||
&mut self,
|
||||
mut update_cursor_position: impl FnMut(
|
||||
&DisplaySnapshot,
|
||||
DisplayPoint,
|
||||
SelectionGoal,
|
||||
) -> Option<(DisplayPoint, SelectionGoal)>,
|
||||
) {
|
||||
self.move_cursors_with(|map, point, goal| {
|
||||
update_cursor_position(map, point, goal).unwrap_or((point, goal))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn replace_cursors_with(
|
||||
&mut self,
|
||||
mut find_replacement_cursors: impl FnMut(&DisplaySnapshot) -> Vec<DisplayPoint>,
|
||||
|
||||
@@ -151,6 +151,11 @@ impl<'a> EditorTestContext<'a> {
|
||||
snapshot.anchor_before(ranges[0].start)..snapshot.anchor_after(ranges[0].end)
|
||||
}
|
||||
|
||||
pub fn set_diff_base(&mut self, diff_base: Option<&str>) {
|
||||
let diff_base = diff_base.map(String::from);
|
||||
self.update_buffer(|buffer, cx| buffer.set_diff_base(diff_base, cx));
|
||||
}
|
||||
|
||||
/// Change the editor's text and selections using a string containing
|
||||
/// embedded range markers that represent the ranges and directions of
|
||||
/// each selection.
|
||||
|
||||
@@ -631,6 +631,21 @@ impl FakeFs {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn directories(&self) -> Vec<PathBuf> {
|
||||
let mut result = Vec::new();
|
||||
let mut queue = collections::VecDeque::new();
|
||||
queue.push_back((PathBuf::from("/"), self.state.lock().await.root.clone()));
|
||||
while let Some((path, entry)) = queue.pop_front() {
|
||||
if let FakeFsEntry::Dir { entries, .. } = &*entry.lock().await {
|
||||
for (name, entry) in entries {
|
||||
queue.push_back((path.join(name), entry.clone()));
|
||||
}
|
||||
result.push(path);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub async fn files(&self) -> Vec<PathBuf> {
|
||||
let mut result = Vec::new();
|
||||
let mut queue = collections::VecDeque::new();
|
||||
|
||||
@@ -15,12 +15,12 @@ pub enum DiffHunkStatus {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DiffHunk<T> {
|
||||
pub buffer_range: Range<T>,
|
||||
pub head_byte_range: Range<usize>,
|
||||
pub diff_base_byte_range: Range<usize>,
|
||||
}
|
||||
|
||||
impl DiffHunk<u32> {
|
||||
pub fn status(&self) -> DiffHunkStatus {
|
||||
if self.head_byte_range.is_empty() {
|
||||
if self.diff_base_byte_range.is_empty() {
|
||||
DiffHunkStatus::Added
|
||||
} else if self.buffer_range.is_empty() {
|
||||
DiffHunkStatus::Removed
|
||||
@@ -75,6 +75,7 @@ impl BufferDiff {
|
||||
&'a self,
|
||||
query_row_range: Range<u32>,
|
||||
buffer: &'a BufferSnapshot,
|
||||
reversed: bool,
|
||||
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||
let start = buffer.anchor_before(Point::new(query_row_range.start, 0));
|
||||
let end = buffer.anchor_after(Point::new(query_row_range.end, 0));
|
||||
@@ -86,7 +87,12 @@ impl BufferDiff {
|
||||
});
|
||||
|
||||
std::iter::from_fn(move || {
|
||||
cursor.next(buffer);
|
||||
if reversed {
|
||||
cursor.prev(buffer);
|
||||
} else {
|
||||
cursor.next(buffer);
|
||||
}
|
||||
|
||||
let hunk = cursor.item()?;
|
||||
|
||||
let range = hunk.buffer_range.to_point(buffer);
|
||||
@@ -98,7 +104,7 @@ impl BufferDiff {
|
||||
|
||||
Some(DiffHunk {
|
||||
buffer_range: range.start.row..end_row,
|
||||
head_byte_range: hunk.head_byte_range.clone(),
|
||||
diff_base_byte_range: hunk.diff_base_byte_range.clone(),
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -135,7 +141,7 @@ impl BufferDiff {
|
||||
|
||||
#[cfg(test)]
|
||||
fn hunks<'a>(&'a self, text: &'a BufferSnapshot) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||
self.hunks_in_range(0..u32::MAX, text)
|
||||
self.hunks_in_range(0..u32::MAX, text, false)
|
||||
}
|
||||
|
||||
fn diff<'a>(head: &'a str, current: &'a str) -> Option<GitPatch<'a>> {
|
||||
@@ -171,7 +177,7 @@ impl BufferDiff {
|
||||
|
||||
let mut first_deletion_buffer_row: Option<u32> = None;
|
||||
let mut buffer_row_range: Option<Range<u32>> = None;
|
||||
let mut head_byte_range: Option<Range<usize>> = None;
|
||||
let mut diff_base_byte_range: Option<Range<usize>> = None;
|
||||
|
||||
for line_index in 0..line_item_count {
|
||||
let line = patch.line_in_hunk(hunk_index, line_index).unwrap();
|
||||
@@ -192,9 +198,9 @@ impl BufferDiff {
|
||||
if kind == GitDiffLineType::Deletion {
|
||||
let end = content_offset + content_len;
|
||||
|
||||
match &mut head_byte_range {
|
||||
match &mut diff_base_byte_range {
|
||||
Some(head_byte_range) => head_byte_range.end = end as usize,
|
||||
None => head_byte_range = Some(content_offset as usize..end as usize),
|
||||
None => diff_base_byte_range = Some(content_offset as usize..end as usize),
|
||||
}
|
||||
|
||||
if first_deletion_buffer_row.is_none() {
|
||||
@@ -215,14 +221,14 @@ impl BufferDiff {
|
||||
});
|
||||
|
||||
//unwrap_or addition without deletion
|
||||
let head_byte_range = head_byte_range.unwrap_or(0..0);
|
||||
let diff_base_byte_range = diff_base_byte_range.unwrap_or(0..0);
|
||||
|
||||
let start = Point::new(buffer_row_range.start, 0);
|
||||
let end = Point::new(buffer_row_range.end, 0);
|
||||
let buffer_range = buffer.anchor_before(start)..buffer.anchor_before(end);
|
||||
DiffHunk {
|
||||
buffer_range,
|
||||
head_byte_range,
|
||||
diff_base_byte_range,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,7 +248,7 @@ pub fn assert_hunks<Iter>(
|
||||
.map(|hunk| {
|
||||
(
|
||||
hunk.buffer_range.clone(),
|
||||
&diff_base[hunk.head_byte_range],
|
||||
&diff_base[hunk.diff_base_byte_range],
|
||||
buffer
|
||||
.text_for_range(
|
||||
Point::new(hunk.buffer_range.start, 0)
|
||||
@@ -349,7 +355,7 @@ mod tests {
|
||||
assert_eq!(diff.hunks(&buffer).count(), 8);
|
||||
|
||||
assert_hunks(
|
||||
diff.hunks_in_range(7..12, &buffer),
|
||||
diff.hunks_in_range(7..12, &buffer, false),
|
||||
&buffer,
|
||||
&diff_base,
|
||||
&[
|
||||
|
||||
@@ -1544,17 +1544,18 @@ impl MutableAppContext {
|
||||
{
|
||||
MatchResult::None => false,
|
||||
MatchResult::Pending => true,
|
||||
MatchResult::Match { view_id, action } => {
|
||||
if self.handle_dispatch_action_from_effect(
|
||||
window_id,
|
||||
Some(view_id),
|
||||
action.as_ref(),
|
||||
) {
|
||||
self.keystroke_matcher.clear_pending();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
MatchResult::Matches(matches) => {
|
||||
for (view_id, action) in matches {
|
||||
if self.handle_dispatch_action_from_effect(
|
||||
window_id,
|
||||
Some(view_id),
|
||||
action.as_ref(),
|
||||
) {
|
||||
self.keystroke_matcher.clear_pending();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -13,16 +13,11 @@ extern "C" {
|
||||
}
|
||||
|
||||
pub struct Matcher {
|
||||
pending: HashMap<usize, Pending>,
|
||||
pending_views: HashMap<usize, Context>,
|
||||
pending_keystrokes: Vec<Keystroke>,
|
||||
keymap: Keymap,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Pending {
|
||||
keystrokes: Vec<Keystroke>,
|
||||
context: Option<Context>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Keymap {
|
||||
bindings: Vec<Binding>,
|
||||
@@ -77,21 +72,21 @@ where
|
||||
pub enum MatchResult {
|
||||
None,
|
||||
Pending,
|
||||
Match {
|
||||
view_id: usize,
|
||||
action: Box<dyn Action>,
|
||||
},
|
||||
Matches(Vec<(usize, Box<dyn Action>)>),
|
||||
}
|
||||
|
||||
impl Debug for MatchResult {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
MatchResult::None => f.debug_struct("MatchResult2::None").finish(),
|
||||
MatchResult::Pending => f.debug_struct("MatchResult2::Pending").finish(),
|
||||
MatchResult::Match { view_id, action } => f
|
||||
.debug_struct("MatchResult::Match")
|
||||
.field("view_id", view_id)
|
||||
.field("action", &action.name())
|
||||
MatchResult::None => f.debug_struct("MatchResult::None").finish(),
|
||||
MatchResult::Pending => f.debug_struct("MatchResult::Pending").finish(),
|
||||
MatchResult::Matches(matches) => f
|
||||
.debug_list()
|
||||
.entries(
|
||||
matches
|
||||
.iter()
|
||||
.map(|(view_id, action)| format!("{view_id}, {}", action.name())),
|
||||
)
|
||||
.finish(),
|
||||
}
|
||||
}
|
||||
@@ -102,13 +97,14 @@ impl PartialEq for MatchResult {
|
||||
match (self, other) {
|
||||
(MatchResult::None, MatchResult::None) => true,
|
||||
(MatchResult::Pending, MatchResult::Pending) => true,
|
||||
(
|
||||
MatchResult::Match { view_id, action },
|
||||
MatchResult::Match {
|
||||
view_id: other_view_id,
|
||||
action: other_action,
|
||||
},
|
||||
) => view_id == other_view_id && action.eq(other_action.as_ref()),
|
||||
(MatchResult::Matches(matches), MatchResult::Matches(other_matches)) => {
|
||||
matches.len() == other_matches.len()
|
||||
&& matches.iter().zip(other_matches.iter()).all(
|
||||
|((view_id, action), (other_view_id, other_action))| {
|
||||
view_id == other_view_id && action.eq(other_action.as_ref())
|
||||
},
|
||||
)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -119,23 +115,24 @@ impl Eq for MatchResult {}
|
||||
impl Matcher {
|
||||
pub fn new(keymap: Keymap) -> Self {
|
||||
Self {
|
||||
pending: HashMap::new(),
|
||||
pending_views: HashMap::new(),
|
||||
pending_keystrokes: Vec::new(),
|
||||
keymap,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_keymap(&mut self, keymap: Keymap) {
|
||||
self.pending.clear();
|
||||
self.clear_pending();
|
||||
self.keymap = keymap;
|
||||
}
|
||||
|
||||
pub fn add_bindings<T: IntoIterator<Item = Binding>>(&mut self, bindings: T) {
|
||||
self.pending.clear();
|
||||
self.clear_pending();
|
||||
self.keymap.add_bindings(bindings);
|
||||
}
|
||||
|
||||
pub fn clear_bindings(&mut self) {
|
||||
self.pending.clear();
|
||||
self.clear_pending();
|
||||
self.keymap.clear();
|
||||
}
|
||||
|
||||
@@ -144,11 +141,12 @@ impl Matcher {
|
||||
}
|
||||
|
||||
pub fn clear_pending(&mut self) {
|
||||
self.pending.clear();
|
||||
self.pending_keystrokes.clear();
|
||||
self.pending_views.clear();
|
||||
}
|
||||
|
||||
pub fn has_pending_keystrokes(&self) -> bool {
|
||||
!self.pending.is_empty()
|
||||
!self.pending_keystrokes.is_empty()
|
||||
}
|
||||
|
||||
pub fn push_keystroke(
|
||||
@@ -157,53 +155,53 @@ impl Matcher {
|
||||
dispatch_path: Vec<(usize, Context)>,
|
||||
) -> MatchResult {
|
||||
let mut any_pending = false;
|
||||
let mut matched_bindings = Vec::new();
|
||||
|
||||
let first_keystroke = self.pending_keystrokes.is_empty();
|
||||
self.pending_keystrokes.push(keystroke);
|
||||
|
||||
let first_keystroke = self.pending.is_empty();
|
||||
for (view_id, context) in dispatch_path {
|
||||
if !first_keystroke && !self.pending.contains_key(&view_id) {
|
||||
// Don't require pending view entry if there are no pending keystrokes
|
||||
if !first_keystroke && !self.pending_views.contains_key(&view_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let pending = self.pending.entry(view_id).or_default();
|
||||
|
||||
if let Some(pending_context) = pending.context.as_ref() {
|
||||
if pending_context != &context {
|
||||
pending.keystrokes.clear();
|
||||
// If there is a previous view context, invalidate that view if it
|
||||
// has changed
|
||||
if let Some(previous_view_context) = self.pending_views.remove(&view_id) {
|
||||
if previous_view_context != context {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
pending.keystrokes.push(keystroke.clone());
|
||||
|
||||
let mut retain_pending = false;
|
||||
// Find the bindings which map the pending keystrokes and current context
|
||||
for binding in self.keymap.bindings.iter().rev() {
|
||||
if binding.keystrokes.starts_with(&pending.keystrokes)
|
||||
if binding.keystrokes.starts_with(&self.pending_keystrokes)
|
||||
&& binding
|
||||
.context_predicate
|
||||
.as_ref()
|
||||
.map(|c| c.eval(&context))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
if binding.keystrokes.len() == pending.keystrokes.len() {
|
||||
self.pending.remove(&view_id);
|
||||
return MatchResult::Match {
|
||||
view_id,
|
||||
action: binding.action.boxed_clone(),
|
||||
};
|
||||
// If the binding is completed, push it onto the matches list
|
||||
if binding.keystrokes.len() == self.pending_keystrokes.len() {
|
||||
matched_bindings.push((view_id, binding.action.boxed_clone()));
|
||||
} else {
|
||||
retain_pending = true;
|
||||
pending.context = Some(context.clone());
|
||||
// Otherwise, the binding is still pending
|
||||
self.pending_views.insert(view_id, context.clone());
|
||||
any_pending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if retain_pending {
|
||||
any_pending = true;
|
||||
} else {
|
||||
self.pending.remove(&view_id);
|
||||
}
|
||||
}
|
||||
|
||||
if any_pending {
|
||||
if !any_pending {
|
||||
self.clear_pending();
|
||||
}
|
||||
|
||||
if !matched_bindings.is_empty() {
|
||||
MatchResult::Matches(matched_bindings)
|
||||
} else if any_pending {
|
||||
MatchResult::Pending
|
||||
} else {
|
||||
MatchResult::None
|
||||
@@ -499,7 +497,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_push_keystroke() -> Result<()> {
|
||||
actions!(test, [B, AB, C]);
|
||||
actions!(test, [B, AB, C, D, DA]);
|
||||
|
||||
let mut ctx1 = Context::default();
|
||||
ctx1.set.insert("1".into());
|
||||
@@ -513,39 +511,58 @@ mod tests {
|
||||
Binding::new("a b", AB, Some("1")),
|
||||
Binding::new("b", B, Some("2")),
|
||||
Binding::new("c", C, Some("2")),
|
||||
Binding::new("d", D, Some("1")),
|
||||
Binding::new("d", D, Some("2")),
|
||||
Binding::new("d a", DA, Some("2")),
|
||||
]);
|
||||
|
||||
let mut matcher = Matcher::new(keymap);
|
||||
|
||||
// Binding with pending prefix always takes precedence
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, dispatch_path.clone()),
|
||||
MatchResult::Pending,
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, dispatch_path.clone())
|
||||
);
|
||||
// B alone doesn't match because a was pending, so AB is returned instead
|
||||
assert_eq!(
|
||||
MatchResult::Match {
|
||||
view_id: 1,
|
||||
action: Box::new(AB)
|
||||
},
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, dispatch_path.clone())
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, dispatch_path.clone()),
|
||||
MatchResult::Matches(vec![(1, Box::new(AB))]),
|
||||
);
|
||||
assert!(matcher.pending.is_empty());
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
// Without an a prefix, B is dispatched like expected
|
||||
assert_eq!(
|
||||
MatchResult::Match {
|
||||
view_id: 2,
|
||||
action: Box::new(B)
|
||||
},
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, dispatch_path.clone())
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, dispatch_path.clone()),
|
||||
MatchResult::Matches(vec![(2, Box::new(B))]),
|
||||
);
|
||||
assert!(matcher.pending.is_empty());
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
// If a is prefixed, C will not be dispatched because there
|
||||
// was a pending binding for it
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, dispatch_path.clone()),
|
||||
MatchResult::Pending,
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, dispatch_path.clone())
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("c")?, dispatch_path.clone()),
|
||||
MatchResult::None,
|
||||
matcher.push_keystroke(Keystroke::parse("c")?, dispatch_path.clone())
|
||||
);
|
||||
assert!(matcher.pending.is_empty());
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
// If a single keystroke matches multiple bindings in the tree
|
||||
// all of them are returned so that we can fallback if the action
|
||||
// handler decides to propagate the action
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("d")?, dispatch_path.clone()),
|
||||
MatchResult::Matches(vec![(2, Box::new(D)), (1, Box::new(D))]),
|
||||
);
|
||||
// If none of the d action handlers consume the binding, a pending
|
||||
// binding may then be used
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, dispatch_path.clone()),
|
||||
MatchResult::Matches(vec![(2, Box::new(DA))]),
|
||||
);
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -666,71 +683,60 @@ mod tests {
|
||||
|
||||
// Basic match
|
||||
assert_eq!(
|
||||
downcast(&matcher.test_keystroke("a", vec![(1, ctx_a.clone())])),
|
||||
Some(&A("x".to_string()))
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, vec![(1, ctx_a.clone())]),
|
||||
MatchResult::Matches(vec![(1, Box::new(A("x".to_string())))])
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
// Multi-keystroke match
|
||||
assert!(matcher
|
||||
.test_keystroke("a", vec![(1, ctx_b.clone())])
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
downcast(&matcher.test_keystroke("b", vec![(1, ctx_b.clone())])),
|
||||
Some(&Ab)
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, vec![(1, ctx_b.clone())]),
|
||||
MatchResult::Pending
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, vec![(1, ctx_b.clone())]),
|
||||
MatchResult::Matches(vec![(1, Box::new(Ab))])
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
// Failed matches don't interfere with matching subsequent keys
|
||||
assert!(matcher
|
||||
.test_keystroke("x", vec![(1, ctx_a.clone())])
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
downcast(&matcher.test_keystroke("a", vec![(1, ctx_a.clone())])),
|
||||
Some(&A("x".to_string()))
|
||||
matcher.push_keystroke(Keystroke::parse("x")?, vec![(1, ctx_a.clone())]),
|
||||
MatchResult::None
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, vec![(1, ctx_a.clone())]),
|
||||
MatchResult::Matches(vec![(1, Box::new(A("x".to_string())))])
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
// Pending keystrokes are cleared when the context changes
|
||||
assert!(&matcher
|
||||
.test_keystroke("a", vec![(1, ctx_b.clone())])
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
downcast(&matcher.test_keystroke("b", vec![(1, ctx_a.clone())])),
|
||||
Some(&B)
|
||||
matcher.push_keystroke(Keystroke::parse("a")?, vec![(1, ctx_b.clone())]),
|
||||
MatchResult::Pending
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, vec![(1, ctx_a.clone())]),
|
||||
MatchResult::None
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
let mut ctx_c = Context::default();
|
||||
ctx_c.set.insert("c".into());
|
||||
|
||||
// Pending keystrokes are maintained per-view
|
||||
assert!(matcher
|
||||
.test_keystroke("a", vec![(1, ctx_b.clone()), (2, ctx_c.clone())])
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
downcast(&matcher.test_keystroke("b", vec![(1, ctx_b.clone())])),
|
||||
Some(&Ab)
|
||||
matcher.push_keystroke(
|
||||
Keystroke::parse("a")?,
|
||||
vec![(1, ctx_b.clone()), (2, ctx_c.clone())]
|
||||
),
|
||||
MatchResult::Pending
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.push_keystroke(Keystroke::parse("b")?, vec![(1, ctx_b.clone())]),
|
||||
MatchResult::Matches(vec![(1, Box::new(Ab))])
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn downcast<A: Action>(action: &Option<Box<dyn Action>>) -> Option<&A> {
|
||||
action
|
||||
.as_ref()
|
||||
.and_then(|action| action.as_any().downcast_ref())
|
||||
}
|
||||
|
||||
impl Matcher {
|
||||
fn test_keystroke(
|
||||
&mut self,
|
||||
keystroke: &str,
|
||||
dispatch_path: Vec<(usize, Context)>,
|
||||
) -> Option<Box<dyn Action>> {
|
||||
if let MatchResult::Match { action, .. } =
|
||||
self.push_keystroke(Keystroke::parse(keystroke).unwrap(), dispatch_path)
|
||||
{
|
||||
Some(action.boxed_clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ pub struct WindowOptions<'a> {
|
||||
pub bounds: WindowBounds,
|
||||
pub titlebar: Option<TitlebarOptions<'a>>,
|
||||
pub center: bool,
|
||||
pub focus: bool,
|
||||
pub kind: WindowKind,
|
||||
pub is_movable: bool,
|
||||
pub screen: Option<Rc<dyn Screen>>,
|
||||
@@ -296,6 +297,7 @@ impl<'a> Default for WindowOptions<'a> {
|
||||
traffic_light_position: Default::default(),
|
||||
}),
|
||||
center: false,
|
||||
focus: true,
|
||||
kind: WindowKind::Normal,
|
||||
is_movable: true,
|
||||
screen: None,
|
||||
|
||||
@@ -514,7 +514,11 @@ impl Window {
|
||||
);
|
||||
}
|
||||
}
|
||||
native_window.makeKeyAndOrderFront_(nil);
|
||||
if options.focus {
|
||||
native_window.makeKeyAndOrderFront_(nil);
|
||||
} else {
|
||||
native_window.orderFront_(nil);
|
||||
}
|
||||
|
||||
window.0.borrow().move_traffic_light();
|
||||
pool.drain();
|
||||
|
||||