Compare commits
45 Commits
extrude-ma
...
path-to-no
Author | SHA1 | Date | |
---|---|---|---|
7a7a83c835 | |||
de63e4f19f | |||
b70b271e6b | |||
08b7cdc5f6 | |||
6efe6b54c0 | |||
69f72d62e0 | |||
e04b09fcd8 | |||
4903f6b9fc | |||
ef8149f03a | |||
1b75321bf1 | |||
3ed263da6b | |||
d59c4a2258 | |||
9c8351ea40 | |||
db98bcf2a0 | |||
15d96a072d | |||
088968c664 | |||
4bbf98bc34 | |||
ca08f5b337 | |||
a3649d09c0 | |||
635cb58036 | |||
7f050b114f | |||
c999819450 | |||
82905caad6 | |||
519e6d74ac | |||
edb7d68c05 | |||
345dd45caa | |||
b6a5f133f3 | |||
bc6407be6e | |||
038409124a | |||
d5567f8602 | |||
df8c17ac18 | |||
9d40f282a8 | |||
a61d931826 | |||
418350ddbc | |||
d43abe20d9 | |||
84380f3da9 | |||
eea55ff2b1 | |||
10b6c1cfbc | |||
d5570e5c62 | |||
0c9589f7ee | |||
ddf66c1e0f | |||
cf1f2bd235 | |||
0b5bb5f77d | |||
0825cb5a59 | |||
4ec94a721c |
@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list: crate,everytime
|
||||
skip: **/target,node_modules,build
|
||||
skip: **/target,node_modules,build,**/Cargo.lock
|
||||
|
@ -1,6 +1,6 @@
|
||||
VITE_KC_API_WS_MODELING_URL=wss://api.dev.kittycad.io/ws/modeling/commands
|
||||
VITE_KC_API_BASE_URL=https://api.dev.kittycad.io
|
||||
VITE_KC_SITE_BASE_URL=https://dev.kittycad.io
|
||||
VITE_KC_API_WS_MODELING_URL=wss://api.dev.zoo.dev/ws/modeling/commands
|
||||
VITE_KC_API_BASE_URL=https://api.dev.zoo.dev
|
||||
VITE_KC_SITE_BASE_URL=https://dev.zoo.dev
|
||||
VITE_KC_SKIP_AUTH=false
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS=5000
|
||||
VITE_KC_SENTRY_DSN=
|
||||
|
@ -1,6 +1,6 @@
|
||||
VITE_KC_API_WS_MODELING_URL=wss://api.kittycad.io/ws/modeling/commands
|
||||
VITE_KC_API_BASE_URL=https://api.kittycad.io
|
||||
VITE_KC_SITE_BASE_URL=https://kittycad.io
|
||||
VITE_KC_API_WS_MODELING_URL=wss://api.zoo.dev/ws/modeling/commands
|
||||
VITE_KC_API_BASE_URL=https://api.zoo.dev
|
||||
VITE_KC_SITE_BASE_URL=https://zoo.dev
|
||||
VITE_KC_SKIP_AUTH=false
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS=15000
|
||||
VITE_KC_SENTRY_DSN=https://a814f2f66734989a90367f48feee28ca@o1042111.ingest.sentry.io/4505789425844224
|
||||
|
11
.github/workflows/cargo-clippy.yml
vendored
@ -43,17 +43,6 @@ jobs:
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
|
||||
- name: Install ffmpeg
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install \
|
||||
ffmpeg \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libclang-dev \
|
||||
libswscale-dev \
|
||||
--no-install-recommends
|
||||
|
||||
- name: Run clippy
|
||||
run: |
|
||||
cd "${{ matrix.dir }}"
|
||||
|
10
.github/workflows/cargo-test.yml
vendored
@ -44,16 +44,6 @@ jobs:
|
||||
- uses: taiki-e/install-action@nextest
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
- name: Install ffmpeg
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install \
|
||||
ffmpeg \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libclang-dev \
|
||||
libswscale-dev \
|
||||
--no-install-recommends
|
||||
- name: cargo test
|
||||
shell: bash
|
||||
run: |-
|
||||
|
44
.github/workflows/ci.yml
vendored
@ -104,7 +104,7 @@ jobs:
|
||||
if: github.event_name == 'schedule'
|
||||
run: |
|
||||
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
||||
echo "$(jq --arg url 'https://dl.kittycad.io/releases/modeling-app/nightly/last_update.json' \
|
||||
echo "$(jq --arg url 'https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json' \
|
||||
'.tauri.updater.endpoints[]=$url' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
@ -123,6 +123,7 @@ jobs:
|
||||
needs: [prepare-json-files]
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
steps:
|
||||
@ -243,6 +244,7 @@ jobs:
|
||||
args: "${{ matrix.os == 'macos-latest' && '--target universal-apple-darwin' || '' }} ${{ env.TAURI_CONF_ARGS }}"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: matrix.os != 'ubuntu-latest'
|
||||
env:
|
||||
PREFIX: ${{ matrix.os == 'macos-latest' && 'src-tauri/target/universal-apple-darwin' || 'src-tauri/target' }}
|
||||
MODE: ${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}
|
||||
@ -257,7 +259,7 @@ jobs:
|
||||
export VITE_KC_API_BASE_URL
|
||||
xvfb-run yarn test:e2e:tauri
|
||||
env:
|
||||
E2E_APPLICATION: "./src-tauri/target/${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}/kittycad-modeling"
|
||||
E2E_APPLICATION: "./src-tauri/target/${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}/zoo-modeling-app"
|
||||
KITTYCAD_API_TOKEN: ${{ env.BUILD_RELEASE == 'true' && secrets.KITTYCAD_API_TOKEN || secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
|
||||
|
||||
@ -271,26 +273,24 @@ jobs:
|
||||
PUB_DATE: ${{ github.event_name == 'release' && github.event.release.created_at || github.event.repository.updated_at }}
|
||||
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Nightly build, commit {0}', github.sha) }}
|
||||
BUCKET_DIR: ${{ github.event_name == 'release' && 'dl.kittycad.io/releases/modeling-app' || 'dl.kittycad.io/releases/modeling-app/nightly' }}
|
||||
WEBSITE_DIR: ${{ github.event_name == 'release' && 'dl.zoo.dev/releases/modeling-app' || 'dl.zoo.dev/releases/modeling-app/nightly' }}
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
|
||||
- name: Generate the update static endpoint
|
||||
run: |
|
||||
ls -l artifact/*/*itty*
|
||||
ls -l artifact/*/*oo*
|
||||
DARWIN_SIG=`cat artifact/macos/*.app.tar.gz.sig`
|
||||
LINUX_SIG=`cat artifact/appimage/*.AppImage.tar.gz.sig`
|
||||
WINDOWS_SIG=`cat artifact/msi/*.msi.zip.sig`
|
||||
RELEASE_DIR=https://${BUCKET_DIR}/${VERSION}
|
||||
RELEASE_DIR=https://${WEBSITE_DIR}/${VERSION}
|
||||
jq --null-input \
|
||||
--arg version "${VERSION}" \
|
||||
--arg pub_date "${PUB_DATE}" \
|
||||
--arg notes "${NOTES}" \
|
||||
--arg darwin_sig "$DARWIN_SIG" \
|
||||
--arg darwin_url "$RELEASE_DIR/macos/KittyCAD%20Modeling.app.tar.gz" \
|
||||
--arg linux_sig "$LINUX_SIG" \
|
||||
--arg linux_url "$RELEASE_DIR/appimage/kittycad-modeling_${VERSION_NO_V}_amd64.AppImage.tar.gz" \
|
||||
--arg darwin_url "$RELEASE_DIR/macos/Zoo%20Modeling%20App.app.tar.gz" \
|
||||
--arg windows_sig "$WINDOWS_SIG" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/KittyCAD%20Modeling_${VERSION_NO_V}_x64_en-US.msi.zip" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/Zoo%20Modeling%20App_${VERSION_NO_V}_x64_en-US.msi.zip" \
|
||||
'{
|
||||
"version": $version,
|
||||
"pub_date": $pub_date,
|
||||
@ -304,10 +304,6 @@ jobs:
|
||||
"signature": $darwin_sig,
|
||||
"url": $darwin_url
|
||||
},
|
||||
"linux-x86_64": {
|
||||
"signature": $linux_sig,
|
||||
"url": $linux_url
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"signature": $windows_sig,
|
||||
"url": $windows_url
|
||||
@ -318,14 +314,13 @@ jobs:
|
||||
|
||||
- name: Generate the download static endpoint
|
||||
run: |
|
||||
RELEASE_DIR=https://${BUCKET_DIR}/${VERSION}
|
||||
RELEASE_DIR=https://${WEBSITE_DIR}/${VERSION}
|
||||
jq --null-input \
|
||||
--arg version "${VERSION}" \
|
||||
--arg pub_date "${PUB_DATE}" \
|
||||
--arg notes "${NOTES}" \
|
||||
--arg darwin_url "$RELEASE_DIR/dmg/KittyCAD%20Modeling_${VERSION_NO_V}_universal.dmg" \
|
||||
--arg linux_url "$RELEASE_DIR/appimage/kittycad-modeling_${VERSION_NO_V}_amd64.AppImage" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/KittyCAD%20Modeling_${VERSION_NO_V}_x64_en-US.msi" \
|
||||
--arg darwin_url "$RELEASE_DIR/dmg/Zoo%20Modeling%20App_${VERSION_NO_V}_universal.dmg" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/Zoo%20Modeling%20App_${VERSION_NO_V}_x64_en-US.msi" \
|
||||
'{
|
||||
"version": $version,
|
||||
"pub_date": $pub_date,
|
||||
@ -334,9 +329,6 @@ jobs:
|
||||
"dmg-universal": {
|
||||
"url": $darwin_url
|
||||
},
|
||||
"appimage-x86_64": {
|
||||
"url": $linux_url
|
||||
},
|
||||
"msi-x86_64": {
|
||||
"url": $windows_url
|
||||
}
|
||||
@ -350,26 +342,26 @@ jobs:
|
||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||
|
||||
- name: Set up Google Cloud SDK
|
||||
uses: google-github-actions/setup-gcloud@v1.1.1
|
||||
uses: google-github-actions/setup-gcloud@v2.0.0
|
||||
with:
|
||||
project_id: kittycadapi
|
||||
|
||||
- name: Upload release files to public bucket
|
||||
uses: google-github-actions/upload-cloud-storage@v1.0.3
|
||||
uses: google-github-actions/upload-cloud-storage@v2.0.0
|
||||
with:
|
||||
path: artifact
|
||||
glob: '*/*itty*'
|
||||
glob: '*/Zoo*'
|
||||
parent: false
|
||||
destination: ${{ env.BUCKET_DIR }}/${{ env.VERSION }}
|
||||
|
||||
- name: Upload update endpoint to public bucket
|
||||
uses: google-github-actions/upload-cloud-storage@v1.0.3
|
||||
uses: google-github-actions/upload-cloud-storage@v2.0.0
|
||||
with:
|
||||
path: last_update.json
|
||||
destination: ${{ env.BUCKET_DIR }}
|
||||
|
||||
- name: Upload download endpoint to public bucket
|
||||
uses: google-github-actions/upload-cloud-storage@v1.0.3
|
||||
uses: google-github-actions/upload-cloud-storage@v2.0.0
|
||||
with:
|
||||
path: last_download.json
|
||||
destination: ${{ env.BUCKET_DIR }}
|
||||
@ -378,4 +370,4 @@ jobs:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: artifact/*/*itty*
|
||||
files: 'artifact/*/Zoo*'
|
||||
|
2
.github/workflows/playwright.yml
vendored
@ -14,6 +14,7 @@ jobs:
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- uses: KittyCAD/action-install-cli@v0.2.16
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
- name: Install Playwright Browsers
|
||||
@ -33,6 +34,7 @@ jobs:
|
||||
env:
|
||||
CI: true
|
||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
|
9
.gitignore
vendored
@ -37,6 +37,15 @@ src/wasm-lib/lcov.info
|
||||
e2e/playwright/playwright-secrets.env
|
||||
e2e/playwright/temp1.png
|
||||
e2e/playwright/temp2.png
|
||||
# exports from snapshot-tests.spec.ts
|
||||
e2e/playwright/export-snapshots/*.ply
|
||||
e2e/playwright/export-snapshots/*.obj
|
||||
e2e/playwright/export-snapshots/*.step
|
||||
e2e/playwright/export-snapshots/*.stl
|
||||
e2e/playwright/export-snapshots/*binary.gltf
|
||||
e2e/playwright/export-snapshots/*embedded.gltf
|
||||
|
||||
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
|
2
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 The KittyCAD Authors
|
||||
Copyright (c) 2023 The Zoo Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
21
README.md
@ -1,17 +1,17 @@
|
||||

|
||||

|
||||
|
||||
## KittyCAD Modeling App
|
||||
## Zoo Modeling App
|
||||
|
||||
live at [app.kittycad.io](https://app.kittycad.io/)
|
||||
live at [app.zoo.dev](https://app.zoo.dev/)
|
||||
|
||||
A CAD application from the future, brought to you by the [KittyCAD team](https://kittycad.io).
|
||||
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
|
||||
|
||||
The KittyCAD modeling app is our take on what a modern modelling experience can be. It is applying several lessons learned in the decades since most major CAD tools came into existence:
|
||||
Modeling App is our take on what a modern modelling experience can be. It is applying several lessons learned in the decades since most major CAD tools came into existence:
|
||||
|
||||
- All artifacts—including parts and assemblies—should be represented as human-readable code. At the end of the day, your CAD project should be "plain text"
|
||||
- This makes version control—which is a solved problem in software engineering—trivial for CAD
|
||||
- All GUI (or point-and-click) interactions should be actions performed on this code representation under the hood
|
||||
- This unlocks a hybrid approach to modeling. Whether you point-and-click as you always have or you write your own KCL code, you are performing the same action in KittyCAD Modeling App
|
||||
- This unlocks a hybrid approach to modeling. Whether you point-and-click as you always have or you write your own KCL code, you are performing the same action in Modeling App
|
||||
- Everything graphics _has_ to be built for the GPU
|
||||
- Most CAD applications have had to retrofit support for GPUs, but our geometry engine is made for GPUs (primarily Nvidia's Vulkan), getting the order of magnitude rendering performance boost with it
|
||||
- Make the resource-intensive pieces of an application auto-scaling
|
||||
@ -19,9 +19,9 @@ The KittyCAD modeling app is our take on what a modern modelling experience can
|
||||
|
||||
We are excited about what a small team of people could build in a short time with our API. We welcome you to try our API, build your own applications, or contribute to ours!
|
||||
|
||||
KittyCAD Modeling App is a _hybrid_ user interface for CAD modeling. You can point-and-click to design parts (and soon assemblies), but everything you make is really just [`kcl` code](https://github.com/KittyCAD/kcl-experiments) under the hood. All of your CAD models can be checked into source control such as GitHub and responsibly versioned, rolled back, and more.
|
||||
Modeling App is a _hybrid_ user interface for CAD modeling. You can point-and-click to design parts (and soon assemblies), but everything you make is really just [`kcl` code](https://github.com/KittyCAD/kcl-experiments) under the hood. All of your CAD models can be checked into source control such as GitHub and responsibly versioned, rolled back, and more.
|
||||
|
||||
The 3D view in KittyCAD Modeling App is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine.
|
||||
The 3D view in Modeling App is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine.
|
||||
|
||||
## Tools
|
||||
|
||||
@ -94,7 +94,6 @@ For running the rust (not tauri rust though) only, you can
|
||||
cd src/wasm-lib
|
||||
cargo test
|
||||
```
|
||||
but you will need to have install ffmpeg prior to.
|
||||
|
||||
## Tauri
|
||||
|
||||
@ -183,9 +182,9 @@ For more information on fuzzing you can check out
|
||||
First time running plawright locally, you'll need to add the secrets file
|
||||
```bash
|
||||
touch ./e2e/playwright/playwright-secrets.env
|
||||
echo 'token="your-token"' > ./e2e/playwright/playwright-secrets.env
|
||||
echo 'token="your-token"\nsnapshottoken="your-snapshot-token"' > ./e2e/playwright/playwright-secrets2.env
|
||||
```
|
||||
then replace "your-token" with a dev token from dev.kittycad.io/account/api-tokens
|
||||
then replace "your-token" with a dev token from dev.zoo.dev/account/api-tokens
|
||||
|
||||
then:
|
||||
run playwright
|
||||
|
BIN
app-icon.png
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 120 KiB |
@ -19765,46 +19765,16 @@
|
||||
"tags": [],
|
||||
"args": [
|
||||
{
|
||||
"name": "data",
|
||||
"type": "TangentialArcToData",
|
||||
"name": "to",
|
||||
"type": "[number]",
|
||||
"schema": {
|
||||
"description": "Data to draw a tangential arc to a specific point.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "A point with a tag.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"tag",
|
||||
"to"
|
||||
],
|
||||
"properties": {
|
||||
"tag": {
|
||||
"description": "The tag.",
|
||||
"type": "string"
|
||||
},
|
||||
"to": {
|
||||
"description": "Where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A point where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
}
|
||||
]
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
@ -20246,6 +20216,15 @@
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "tag",
|
||||
"type": "String",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returnValue": {
|
||||
|
@ -3905,21 +3905,12 @@ Draw an arc.
|
||||
|
||||
|
||||
```
|
||||
tangentialArcTo(data: TangentialArcToData, sketch_group: SketchGroup) -> SketchGroup
|
||||
tangentialArcTo(to: [number], sketch_group: SketchGroup, tag: String) -> SketchGroup
|
||||
```
|
||||
|
||||
#### Arguments
|
||||
|
||||
* `data`: `TangentialArcToData` - Data to draw a tangential arc to a specific point.
|
||||
```
|
||||
{
|
||||
// The tag.
|
||||
tag: string,
|
||||
// Where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
to: [number, number],
|
||||
} |
|
||||
[number, number]
|
||||
```
|
||||
* `to`: `[number]`
|
||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
|
||||
```
|
||||
{
|
||||
@ -3985,6 +3976,7 @@ tangentialArcTo(data: TangentialArcToData, sketch_group: SketchGroup) -> SketchG
|
||||
}],
|
||||
}
|
||||
```
|
||||
* `tag`: `String`
|
||||
|
||||
#### Returns
|
||||
|
||||
|
BIN
e2e/playwright/export-snapshots/gltf-binary.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
e2e/playwright/export-snapshots/gltf-embedded.png
Normal file
After Width: | Height: | Size: 80 KiB |
@ -1,189 +0,0 @@
|
||||
v 0 -4 0
|
||||
v 0 0 0
|
||||
v 0 -4 -1
|
||||
v 0 0 -1
|
||||
v 3.0950184 -4 -1
|
||||
v 3.0950184 0 -1
|
||||
v 5.9513144 -4 -3
|
||||
v 5.9513144 0 -3
|
||||
v 9.5 -4 -3
|
||||
v 9.5 0 -3
|
||||
v 9.5 -4 -2.5
|
||||
v 9.5 0 -2.5
|
||||
v 6.108964 -4 -2.5
|
||||
v 6.108964 0 -2.5
|
||||
v 3.4311862 -4 -0.625
|
||||
v 4.323779 -4 -1.25
|
||||
v 4.323779 -0 -1.25
|
||||
v 3.4311862 -0 -0.625
|
||||
v 2.5385938 0 0
|
||||
v 2.5385938 -4 0
|
||||
v 3.342784 -4 0.375
|
||||
v 4.146974 -4 0.75
|
||||
v 3.342784 -0 0.375
|
||||
v 4.146974 -0 0.75
|
||||
v 5.755354 0 1.5
|
||||
v 5.755354 -4 1.5
|
||||
v 9.5 -4 1.5
|
||||
v 9.5 0 1.5
|
||||
v 9.5 -4 2
|
||||
v 9.5 0 2
|
||||
v 5.644507 -4 2
|
||||
v 5.644507 0 2
|
||||
v 3.5 -4 1
|
||||
v 3.5 0 1
|
||||
v 0 -4 1
|
||||
v 0 0 1
|
||||
vt 0.0127 -0.0508
|
||||
vt 0.0127 0.0508
|
||||
vt -0.0127 -0.0508
|
||||
vt -0.0127 0.0508
|
||||
vt -0.039306734 0.0508
|
||||
vt -0.039306734 -0.0508
|
||||
vt 0.039306734 0.0508
|
||||
vt 0.039306734 -0.0508
|
||||
vt -0.04428355 0.0508
|
||||
vt -0.04428355 -0.0508
|
||||
vt 0.04428355 0.0508
|
||||
vt 0.04428355 -0.0508
|
||||
vt -0.045068305 0.0508
|
||||
vt -0.045068305 -0.0508
|
||||
vt 0.045068305 0.0508
|
||||
vt 0.045068305 -0.0508
|
||||
vt -0.00635 0.0508
|
||||
vt -0.00635 -0.0508
|
||||
vt 0.00635 0.0508
|
||||
vt 0.00635 -0.0508
|
||||
vt 0.04306616 -0.0508
|
||||
vt 0.04306616 0.0508
|
||||
vt -0.04306616 -0.0508
|
||||
vt -0.04306616 0.0508
|
||||
vt -0.027677217 -0.0508
|
||||
vt 0.000000000000000048572257 -0.0508
|
||||
vt 0.000000000000000048572257 0.0508
|
||||
vt 0.055354435 -0.0508
|
||||
vt 0.055354435 0.0508
|
||||
vt -0.027677217 0.0508
|
||||
vt -0.055354435 0.0508
|
||||
vt -0.055354435 -0.0508
|
||||
vt -0.02253807 0.0508
|
||||
vt -0.04507614 0.0508
|
||||
vt -0.04507614 -0.0508
|
||||
vt 0.00000000000000005551115 0.0508
|
||||
vt -0.02253807 -0.0508
|
||||
vt 0.00000000000000005551115 -0.0508
|
||||
vt 0.04507614 -0.0508
|
||||
vt 0.04507614 0.0508
|
||||
vt -0.047557 0.0508
|
||||
vt -0.047557 -0.0508
|
||||
vt 0.047557 0.0508
|
||||
vt 0.047557 -0.0508
|
||||
vt 0.04896476 -0.0508
|
||||
vt 0.04896476 0.0508
|
||||
vt -0.04896476 -0.0508
|
||||
vt -0.04896476 0.0508
|
||||
vt 0.03005076 -0.0508
|
||||
vt 0.03005076 0.0508
|
||||
vt -0.03005076 -0.0508
|
||||
vt -0.03005076 0.0508
|
||||
vt 0.04445 -0.0508
|
||||
vt 0.04445 0.0508
|
||||
vt -0.04445 -0.0508
|
||||
vt -0.04445 0.0508
|
||||
vt 0.08490671 0.009525
|
||||
vt 0.06448028 0
|
||||
vt 0.0889 0.0254
|
||||
vt 0.08715213 -0.015875
|
||||
vt 0.10982399 -0.03175
|
||||
vt 0.07861347 -0.0254
|
||||
vt 0.10533314 0.01905
|
||||
vt 0.15116338 -0.0762
|
||||
vt 0 -0.0254
|
||||
vt 0 0
|
||||
vt 0.2413 -0.0762
|
||||
vt 0.15516768 -0.0635
|
||||
vt 0.2413 -0.0635
|
||||
vt 0.14337048 0.0508
|
||||
vt 0.146186 0.0381
|
||||
vt 0.2413 0.0381
|
||||
vt 0.2413 0.0508
|
||||
vt 0 0.0254
|
||||
vn -1 -0 0
|
||||
vn 0 -0 -1
|
||||
vn -0.57357645 -0 -0.81915206
|
||||
vn 1 -0 0
|
||||
vn 0 -0 1
|
||||
vn 0.57357645 -0 0.81915206
|
||||
vn 0.42261827 -0 -0.9063078
|
||||
vn -0.42261827 -0 0.9063078
|
||||
vn -0 1 -0
|
||||
vn 0 -1 0
|
||||
o Unnamed-0
|
||||
f 1/1/1 2/2/1 3/3/1
|
||||
f 3/3/1 2/2/1 4/4/1
|
||||
f 3/5/2 4/6/2 5/7/2
|
||||
f 5/7/2 4/6/2 6/8/2
|
||||
f 5/9/3 6/10/3 7/11/3
|
||||
f 7/11/3 6/10/3 8/12/3
|
||||
f 7/13/2 8/14/2 9/15/2
|
||||
f 9/15/2 8/14/2 10/16/2
|
||||
f 9/17/4 10/18/4 11/19/4
|
||||
f 11/19/4 10/18/4 12/20/4
|
||||
f 11/21/5 12/22/5 13/23/5
|
||||
f 13/23/5 12/22/5 14/24/5
|
||||
f 15/25/6 16/26/6 17/27/6
|
||||
f 16/26/6 13/28/6 14/29/6
|
||||
f 18/30/6 19/31/6 20/32/6
|
||||
f 15/25/6 18/30/6 20/32/6
|
||||
f 16/26/6 14/29/6 17/27/6
|
||||
f 18/30/6 15/25/6 17/27/6
|
||||
f 21/33/7 20/34/7 19/35/7
|
||||
f 22/36/7 21/33/7 23/37/7
|
||||
f 23/37/7 24/38/7 22/36/7
|
||||
f 24/38/7 25/39/7 26/40/7
|
||||
f 21/33/7 19/35/7 23/37/7
|
||||
f 26/40/7 22/36/7 24/38/7
|
||||
f 26/41/2 25/42/2 27/43/2
|
||||
f 27/43/2 25/42/2 28/44/2
|
||||
f 27/17/4 28/18/4 29/19/4
|
||||
f 29/19/4 28/18/4 30/20/4
|
||||
f 29/45/5 30/46/5 31/47/5
|
||||
f 31/47/5 30/46/5 32/48/5
|
||||
f 31/49/8 32/50/8 33/51/8
|
||||
f 33/51/8 32/50/8 34/52/8
|
||||
f 33/53/5 34/54/5 35/55/5
|
||||
f 35/55/5 34/54/5 36/56/5
|
||||
f 35/1/1 36/2/1 1/3/1
|
||||
f 1/3/1 36/2/1 2/4/1
|
||||
f 23/57/9 19/58/9 34/59/9
|
||||
f 18/60/9 17/61/9 6/62/9
|
||||
f 23/57/9 34/59/9 24/63/9
|
||||
f 17/61/9 8/64/9 6/62/9
|
||||
f 4/65/9 19/58/9 6/62/9
|
||||
f 4/65/9 2/66/9 19/58/9
|
||||
f 10/67/9 14/68/9 12/69/9
|
||||
f 10/67/9 8/64/9 14/68/9
|
||||
f 8/64/9 17/61/9 14/68/9
|
||||
f 32/70/9 25/71/9 24/63/9
|
||||
f 6/62/9 19/58/9 18/60/9
|
||||
f 24/63/9 34/59/9 32/70/9
|
||||
f 28/72/9 25/71/9 30/73/9
|
||||
f 25/71/9 32/70/9 30/73/9
|
||||
f 19/58/9 2/66/9 36/74/9
|
||||
f 34/59/9 19/58/9 36/74/9
|
||||
f 21/57/10 33/59/10 20/58/10
|
||||
f 22/63/10 33/59/10 21/57/10
|
||||
f 15/60/10 5/62/10 16/61/10
|
||||
f 22/63/10 26/71/10 31/70/10
|
||||
f 35/74/10 20/58/10 33/59/10
|
||||
f 35/74/10 1/66/10 20/58/10
|
||||
f 31/70/10 26/71/10 29/73/10
|
||||
f 29/73/10 26/71/10 27/72/10
|
||||
f 22/63/10 31/70/10 33/59/10
|
||||
f 20/58/10 5/62/10 15/60/10
|
||||
f 16/61/10 5/62/10 7/64/10
|
||||
f 13/68/10 16/61/10 7/64/10
|
||||
f 11/69/10 13/68/10 9/67/10
|
||||
f 13/68/10 7/64/10 9/67/10
|
||||
f 20/58/10 3/65/10 5/62/10
|
||||
f 3/65/10 20/58/10 1/66/10
|
BIN
e2e/playwright/export-snapshots/obj-.png
Normal file
After Width: | Height: | Size: 56 KiB |
@ -1,282 +0,0 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Generated by kittycad.io
|
||||
element vertex 204
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
element face 68
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
0 0 4
|
||||
0 0 0
|
||||
0 -1 4
|
||||
0 -1 4
|
||||
0 0 0
|
||||
0 -1 0
|
||||
0 -1 4
|
||||
0 -1 0
|
||||
3.0950184 -1 4
|
||||
3.0950184 -1 4
|
||||
0 -1 0
|
||||
3.0950184 -1 0
|
||||
3.0950184 -1 4
|
||||
3.0950184 -1 0
|
||||
5.9513144 -3 4
|
||||
5.9513144 -3 4
|
||||
3.0950184 -1 0
|
||||
5.9513144 -3 0
|
||||
5.9513144 -3 4
|
||||
5.9513144 -3 0
|
||||
9.5 -3 4
|
||||
9.5 -3 4
|
||||
5.9513144 -3 0
|
||||
9.5 -3 0
|
||||
9.5 -3 4
|
||||
9.5 -3 0
|
||||
9.5 -2.5 4
|
||||
9.5 -2.5 4
|
||||
9.5 -3 0
|
||||
9.5 -2.5 0
|
||||
9.5 -2.5 4
|
||||
9.5 -2.5 0
|
||||
6.108964 -2.5 4
|
||||
6.108964 -2.5 4
|
||||
9.5 -2.5 0
|
||||
6.108964 -2.5 0
|
||||
3.4311862 -0.625 4
|
||||
4.323779 -1.25 4
|
||||
4.323779 -1.25 0
|
||||
4.323779 -1.25 4
|
||||
6.108964 -2.5 4
|
||||
6.108964 -2.5 0
|
||||
3.4311862 -0.625 0
|
||||
2.5385938 0 0
|
||||
2.5385938 0 4
|
||||
3.4311862 -0.625 4
|
||||
3.4311862 -0.625 0
|
||||
2.5385938 0 4
|
||||
4.323779 -1.25 4
|
||||
6.108964 -2.5 0
|
||||
4.323779 -1.25 0
|
||||
3.4311862 -0.625 0
|
||||
3.4311862 -0.625 4
|
||||
4.323779 -1.25 0
|
||||
3.342784 0.375 4
|
||||
2.5385938 0 4
|
||||
2.5385938 0 0
|
||||
4.146974 0.75 4
|
||||
3.342784 0.375 4
|
||||
3.342784 0.375 0
|
||||
3.342784 0.375 0
|
||||
4.146974 0.75 0
|
||||
4.146974 0.75 4
|
||||
4.146974 0.75 0
|
||||
5.755354 1.5 0
|
||||
5.755354 1.5 4
|
||||
3.342784 0.375 4
|
||||
2.5385938 0 0
|
||||
3.342784 0.375 0
|
||||
5.755354 1.5 4
|
||||
4.146974 0.75 4
|
||||
4.146974 0.75 0
|
||||
5.755354 1.5 4
|
||||
5.755354 1.5 0
|
||||
9.5 1.5 4
|
||||
9.5 1.5 4
|
||||
5.755354 1.5 0
|
||||
9.5 1.5 0
|
||||
9.5 1.5 4
|
||||
9.5 1.5 0
|
||||
9.5 2 4
|
||||
9.5 2 4
|
||||
9.5 1.5 0
|
||||
9.5 2 0
|
||||
9.5 2 4
|
||||
9.5 2 0
|
||||
5.644507 2 4
|
||||
5.644507 2 4
|
||||
9.5 2 0
|
||||
5.644507 2 0
|
||||
5.644507 2 4
|
||||
5.644507 2 0
|
||||
3.5 1 4
|
||||
3.5 1 4
|
||||
5.644507 2 0
|
||||
3.5 1 0
|
||||
3.5 1 4
|
||||
3.5 1 0
|
||||
0 1 4
|
||||
0 1 4
|
||||
3.5 1 0
|
||||
0 1 0
|
||||
0 1 4
|
||||
0 1 0
|
||||
0 0 4
|
||||
0 0 4
|
||||
0 1 0
|
||||
0 0 0
|
||||
3.342784 0.375 0
|
||||
2.5385938 0 0
|
||||
3.5 1 0
|
||||
3.4311862 -0.625 0
|
||||
4.323779 -1.25 0
|
||||
3.0950184 -1 0
|
||||
3.342784 0.375 0
|
||||
3.5 1 0
|
||||
4.146974 0.75 0
|
||||
4.323779 -1.25 0
|
||||
5.9513144 -3 0
|
||||
3.0950184 -1 0
|
||||
0 -1 0
|
||||
2.5385938 0 0
|
||||
3.0950184 -1 0
|
||||
0 -1 0
|
||||
0 0 0
|
||||
2.5385938 0 0
|
||||
9.5 -3 0
|
||||
6.108964 -2.5 0
|
||||
9.5 -2.5 0
|
||||
9.5 -3 0
|
||||
5.9513144 -3 0
|
||||
6.108964 -2.5 0
|
||||
5.9513144 -3 0
|
||||
4.323779 -1.25 0
|
||||
6.108964 -2.5 0
|
||||
5.644507 2 0
|
||||
5.755354 1.5 0
|
||||
4.146974 0.75 0
|
||||
3.0950184 -1 0
|
||||
2.5385938 0 0
|
||||
3.4311862 -0.625 0
|
||||
4.146974 0.75 0
|
||||
3.5 1 0
|
||||
5.644507 2 0
|
||||
9.5 1.5 0
|
||||
5.755354 1.5 0
|
||||
9.5 2 0
|
||||
5.755354 1.5 0
|
||||
5.644507 2 0
|
||||
9.5 2 0
|
||||
2.5385938 0 0
|
||||
0 0 0
|
||||
0 1 0
|
||||
3.5 1 0
|
||||
2.5385938 0 0
|
||||
0 1 0
|
||||
3.342784 0.375 4
|
||||
3.5 1 4
|
||||
2.5385938 0 4
|
||||
4.146974 0.75 4
|
||||
3.5 1 4
|
||||
3.342784 0.375 4
|
||||
3.4311862 -0.625 4
|
||||
3.0950184 -1 4
|
||||
4.323779 -1.25 4
|
||||
4.146974 0.75 4
|
||||
5.755354 1.5 4
|
||||
5.644507 2 4
|
||||
0 1 4
|
||||
2.5385938 0 4
|
||||
3.5 1 4
|
||||
0 1 4
|
||||
0 0 4
|
||||
2.5385938 0 4
|
||||
5.644507 2 4
|
||||
5.755354 1.5 4
|
||||
9.5 2 4
|
||||
9.5 2 4
|
||||
5.755354 1.5 4
|
||||
9.5 1.5 4
|
||||
4.146974 0.75 4
|
||||
5.644507 2 4
|
||||
3.5 1 4
|
||||
2.5385938 0 4
|
||||
3.0950184 -1 4
|
||||
3.4311862 -0.625 4
|
||||
4.323779 -1.25 4
|
||||
3.0950184 -1 4
|
||||
5.9513144 -3 4
|
||||
6.108964 -2.5 4
|
||||
4.323779 -1.25 4
|
||||
5.9513144 -3 4
|
||||
9.5 -2.5 4
|
||||
6.108964 -2.5 4
|
||||
9.5 -3 4
|
||||
6.108964 -2.5 4
|
||||
5.9513144 -3 4
|
||||
9.5 -3 4
|
||||
2.5385938 0 4
|
||||
0 -1 4
|
||||
3.0950184 -1 4
|
||||
0 -1 4
|
||||
2.5385938 0 4
|
||||
0 0 4
|
||||
3 0 1 2
|
||||
3 3 4 5
|
||||
3 6 7 8
|
||||
3 9 10 11
|
||||
3 12 13 14
|
||||
3 15 16 17
|
||||
3 18 19 20
|
||||
3 21 22 23
|
||||
3 24 25 26
|
||||
3 27 28 29
|
||||
3 30 31 32
|
||||
3 33 34 35
|
||||
3 36 37 38
|
||||
3 39 40 41
|
||||
3 42 43 44
|
||||
3 45 46 47
|
||||
3 48 49 50
|
||||
3 51 52 53
|
||||
3 54 55 56
|
||||
3 57 58 59
|
||||
3 60 61 62
|
||||
3 63 64 65
|
||||
3 66 67 68
|
||||
3 69 70 71
|
||||
3 72 73 74
|
||||
3 75 76 77
|
||||
3 78 79 80
|
||||
3 81 82 83
|
||||
3 84 85 86
|
||||
3 87 88 89
|
||||
3 90 91 92
|
||||
3 93 94 95
|
||||
3 96 97 98
|
||||
3 99 100 101
|
||||
3 102 103 104
|
||||
3 105 106 107
|
||||
3 108 109 110
|
||||
3 111 112 113
|
||||
3 114 115 116
|
||||
3 117 118 119
|
||||
3 120 121 122
|
||||
3 123 124 125
|
||||
3 126 127 128
|
||||
3 129 130 131
|
||||
3 132 133 134
|
||||
3 135 136 137
|
||||
3 138 139 140
|
||||
3 141 142 143
|
||||
3 144 145 146
|
||||
3 147 148 149
|
||||
3 150 151 152
|
||||
3 153 154 155
|
||||
3 156 157 158
|
||||
3 159 160 161
|
||||
3 162 163 164
|
||||
3 165 166 167
|
||||
3 168 169 170
|
||||
3 171 172 173
|
||||
3 174 175 176
|
||||
3 177 178 179
|
||||
3 180 181 182
|
||||
3 183 184 185
|
||||
3 186 187 188
|
||||
3 189 190 191
|
||||
3 192 193 194
|
||||
3 195 196 197
|
||||
3 198 199 200
|
||||
3 201 202 203
|
BIN
e2e/playwright/export-snapshots/ply-ascii.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
e2e/playwright/export-snapshots/ply-binary_big_endian.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
e2e/playwright/export-snapshots/ply-binary_little_endian.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
e2e/playwright/export-snapshots/step-.png
Normal file
After Width: | Height: | Size: 80 KiB |
@ -74,171 +74,171 @@ DATA;
|
||||
#58 = CARTESIAN_POINT('NONE', (0, 0.0254, 0.1016));
|
||||
#59 = VERTEX_POINT('NONE', #58);
|
||||
#60 = DIRECTION('NONE', (0, -1, 0));
|
||||
#61 = VECTOR('NONE', #60, 0.0254);
|
||||
#61 = VECTOR('NONE', #60, 1);
|
||||
#62 = CARTESIAN_POINT('NONE', (0, 0, -0));
|
||||
#63 = LINE('NONE', #62, #61);
|
||||
#64 = DIRECTION('NONE', (0, 0, 1));
|
||||
#65 = VECTOR('NONE', #64, 0.1016);
|
||||
#65 = VECTOR('NONE', #64, 1);
|
||||
#66 = CARTESIAN_POINT('NONE', (0, -0.0254, -0));
|
||||
#67 = LINE('NONE', #66, #65);
|
||||
#68 = DIRECTION('NONE', (0, -1, 0));
|
||||
#69 = VECTOR('NONE', #68, 0.0254);
|
||||
#69 = VECTOR('NONE', #68, 1);
|
||||
#70 = CARTESIAN_POINT('NONE', (0, 0, 0.1016));
|
||||
#71 = LINE('NONE', #70, #69);
|
||||
#72 = DIRECTION('NONE', (0, 0, 1));
|
||||
#73 = VECTOR('NONE', #72, 0.1016);
|
||||
#73 = VECTOR('NONE', #72, 1);
|
||||
#74 = CARTESIAN_POINT('NONE', (0, 0, -0));
|
||||
#75 = LINE('NONE', #74, #73);
|
||||
#76 = DIRECTION('NONE', (1, 0, 0));
|
||||
#77 = VECTOR('NONE', #76, 0.07861346939195568);
|
||||
#77 = VECTOR('NONE', #76, 1);
|
||||
#78 = CARTESIAN_POINT('NONE', (0, -0.0254, -0));
|
||||
#79 = LINE('NONE', #78, #77);
|
||||
#80 = DIRECTION('NONE', (0, 0, 1));
|
||||
#81 = VECTOR('NONE', #80, 0.1016);
|
||||
#81 = VECTOR('NONE', #80, 1);
|
||||
#82 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, -0));
|
||||
#83 = LINE('NONE', #82, #81);
|
||||
#84 = DIRECTION('NONE', (1, 0, 0));
|
||||
#85 = VECTOR('NONE', #84, 0.07861346939195568);
|
||||
#85 = VECTOR('NONE', #84, 1);
|
||||
#86 = CARTESIAN_POINT('NONE', (0, -0.0254, 0.1016));
|
||||
#87 = LINE('NONE', #86, #85);
|
||||
#88 = DIRECTION('NONE', (0.8191520442889919, -0.5735764363510459, 0));
|
||||
#89 = VECTOR('NONE', #88, 0.08856709721755177);
|
||||
#89 = VECTOR('NONE', #88, 1);
|
||||
#90 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, -0));
|
||||
#91 = LINE('NONE', #90, #89);
|
||||
#92 = DIRECTION('NONE', (0, 0, 1));
|
||||
#93 = VECTOR('NONE', #92, 0.1016);
|
||||
#93 = VECTOR('NONE', #92, 1);
|
||||
#94 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, -0));
|
||||
#95 = LINE('NONE', #94, #93);
|
||||
#96 = DIRECTION('NONE', (0.8191520442889919, -0.5735764363510459, 0));
|
||||
#97 = VECTOR('NONE', #96, 0.08856709721755177);
|
||||
#97 = VECTOR('NONE', #96, 1);
|
||||
#98 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, 0.1016));
|
||||
#99 = LINE('NONE', #98, #97);
|
||||
#100 = DIRECTION('NONE', (1, -0.0000000000000003079278779307945, 0));
|
||||
#101 = VECTOR('NONE', #100, 0.09013661186554489);
|
||||
#101 = VECTOR('NONE', #100, 1);
|
||||
#102 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, -0));
|
||||
#103 = LINE('NONE', #102, #101);
|
||||
#104 = DIRECTION('NONE', (0, 0, 1));
|
||||
#105 = VECTOR('NONE', #104, 0.1016);
|
||||
#105 = VECTOR('NONE', #104, 1);
|
||||
#106 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, -0));
|
||||
#107 = LINE('NONE', #106, #105);
|
||||
#108 = DIRECTION('NONE', (1, -0.0000000000000003079278779307945, 0));
|
||||
#109 = VECTOR('NONE', #108, 0.09013661186554489);
|
||||
#109 = VECTOR('NONE', #108, 1);
|
||||
#110 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, 0.1016));
|
||||
#111 = LINE('NONE', #110, #109);
|
||||
#112 = DIRECTION('NONE', (0, 1, 0));
|
||||
#113 = VECTOR('NONE', #112, 0.012700000000000003);
|
||||
#113 = VECTOR('NONE', #112, 1);
|
||||
#114 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, -0));
|
||||
#115 = LINE('NONE', #114, #113);
|
||||
#116 = DIRECTION('NONE', (0, 0, 1));
|
||||
#117 = VECTOR('NONE', #116, 0.1016);
|
||||
#117 = VECTOR('NONE', #116, 1);
|
||||
#118 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, -0));
|
||||
#119 = LINE('NONE', #118, #117);
|
||||
#120 = DIRECTION('NONE', (0, 1, 0));
|
||||
#121 = VECTOR('NONE', #120, 0.012700000000000003);
|
||||
#121 = VECTOR('NONE', #120, 1);
|
||||
#122 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, 0.1016));
|
||||
#123 = LINE('NONE', #122, #121);
|
||||
#124 = DIRECTION('NONE', (-1, 0, 0));
|
||||
#125 = VECTOR('NONE', #124, 0.08613231724678178);
|
||||
#125 = VECTOR('NONE', #124, 1);
|
||||
#126 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, -0));
|
||||
#127 = LINE('NONE', #126, #125);
|
||||
#128 = DIRECTION('NONE', (0, 0, 1));
|
||||
#129 = VECTOR('NONE', #128, 0.1016);
|
||||
#129 = VECTOR('NONE', #128, 1);
|
||||
#130 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, -0));
|
||||
#131 = LINE('NONE', #130, #129);
|
||||
#132 = DIRECTION('NONE', (-1, 0, 0));
|
||||
#133 = VECTOR('NONE', #132, 0.08613231724678178);
|
||||
#133 = VECTOR('NONE', #132, 1);
|
||||
#134 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, 0.1016));
|
||||
#135 = LINE('NONE', #134, #133);
|
||||
#136 = DIRECTION('NONE', (-0.8191520442889918, 0.573576436351046, 0));
|
||||
#137 = VECTOR('NONE', #136, 0.11070887152193974);
|
||||
#136 = DIRECTION('NONE', (-0.8191520442889919, 0.573576436351046, 0));
|
||||
#137 = VECTOR('NONE', #136, 1);
|
||||
#138 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, -0));
|
||||
#139 = LINE('NONE', #138, #137);
|
||||
#140 = DIRECTION('NONE', (0, 0, 1));
|
||||
#141 = VECTOR('NONE', #140, 0.1016);
|
||||
#141 = VECTOR('NONE', #140, 1);
|
||||
#142 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, -0));
|
||||
#143 = LINE('NONE', #142, #141);
|
||||
#144 = DIRECTION('NONE', (-0.8191520442889918, 0.573576436351046, 0));
|
||||
#145 = VECTOR('NONE', #144, 0.11070887152193974);
|
||||
#144 = DIRECTION('NONE', (-0.8191520442889919, 0.573576436351046, 0));
|
||||
#145 = VECTOR('NONE', #144, 1);
|
||||
#146 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, 0.1016));
|
||||
#147 = LINE('NONE', #146, #145);
|
||||
#148 = DIRECTION('NONE', (0.90630778703665, 0.4226182617406993, 0));
|
||||
#149 = VECTOR('NONE', #148, 0.09015228031811025);
|
||||
#149 = VECTOR('NONE', #148, 1);
|
||||
#150 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, -0));
|
||||
#151 = LINE('NONE', #150, #149);
|
||||
#152 = DIRECTION('NONE', (0, 0, 1));
|
||||
#153 = VECTOR('NONE', #152, 0.1016);
|
||||
#153 = VECTOR('NONE', #152, 1);
|
||||
#154 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, -0));
|
||||
#155 = LINE('NONE', #154, #153);
|
||||
#156 = DIRECTION('NONE', (0.90630778703665, 0.4226182617406993, 0));
|
||||
#157 = VECTOR('NONE', #156, 0.09015228031811025);
|
||||
#157 = VECTOR('NONE', #156, 1);
|
||||
#158 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, 0.1016));
|
||||
#159 = LINE('NONE', #158, #157);
|
||||
#160 = DIRECTION('NONE', (1, -0.00000000000000007295344279228718, 0));
|
||||
#161 = VECTOR('NONE', #160, 0.09511400200349182);
|
||||
#161 = VECTOR('NONE', #160, 1);
|
||||
#162 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, -0));
|
||||
#163 = LINE('NONE', #162, #161);
|
||||
#164 = DIRECTION('NONE', (0, 0, 1));
|
||||
#165 = VECTOR('NONE', #164, 0.1016);
|
||||
#165 = VECTOR('NONE', #164, 1);
|
||||
#166 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, -0));
|
||||
#167 = LINE('NONE', #166, #165);
|
||||
#168 = DIRECTION('NONE', (1, -0.00000000000000007295344279228718, 0));
|
||||
#169 = VECTOR('NONE', #168, 0.09511400200349182);
|
||||
#169 = VECTOR('NONE', #168, 1);
|
||||
#170 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, 0.1016));
|
||||
#171 = LINE('NONE', #170, #169);
|
||||
#172 = DIRECTION('NONE', (0, 1, 0));
|
||||
#173 = VECTOR('NONE', #172, 0.012699999999999996);
|
||||
#173 = VECTOR('NONE', #172, 1);
|
||||
#174 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, -0));
|
||||
#175 = LINE('NONE', #174, #173);
|
||||
#176 = DIRECTION('NONE', (0, 0, 1));
|
||||
#177 = VECTOR('NONE', #176, 0.1016);
|
||||
#177 = VECTOR('NONE', #176, 1);
|
||||
#178 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, -0));
|
||||
#179 = LINE('NONE', #178, #177);
|
||||
#180 = DIRECTION('NONE', (0, 1, 0));
|
||||
#181 = VECTOR('NONE', #180, 0.012699999999999996);
|
||||
#181 = VECTOR('NONE', #180, 1);
|
||||
#182 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, 0.1016));
|
||||
#183 = LINE('NONE', #182, #181);
|
||||
#184 = DIRECTION('NONE', (-1, 0, 0));
|
||||
#185 = VECTOR('NONE', #184, 0.0979295242190572);
|
||||
#185 = VECTOR('NONE', #184, 1);
|
||||
#186 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, -0));
|
||||
#187 = LINE('NONE', #186, #185);
|
||||
#188 = DIRECTION('NONE', (0, 0, 1));
|
||||
#189 = VECTOR('NONE', #188, 0.1016);
|
||||
#189 = VECTOR('NONE', #188, 1);
|
||||
#190 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, -0));
|
||||
#191 = LINE('NONE', #190, #189);
|
||||
#192 = DIRECTION('NONE', (-1, 0, 0));
|
||||
#193 = VECTOR('NONE', #192, 0.0979295242190572);
|
||||
#193 = VECTOR('NONE', #192, 1);
|
||||
#194 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, 0.1016));
|
||||
#195 = LINE('NONE', #194, #193);
|
||||
#196 = DIRECTION('NONE', (-0.9063077870366499, -0.42261826174069944, 0));
|
||||
#197 = VECTOR('NONE', #196, 0.06010152021207346);
|
||||
#196 = DIRECTION('NONE', (-0.90630778703665, -0.42261826174069944, 0));
|
||||
#197 = VECTOR('NONE', #196, 1);
|
||||
#198 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, -0));
|
||||
#199 = LINE('NONE', #198, #197);
|
||||
#200 = DIRECTION('NONE', (0, 0, 1));
|
||||
#201 = VECTOR('NONE', #200, 0.1016);
|
||||
#201 = VECTOR('NONE', #200, 1);
|
||||
#202 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, -0));
|
||||
#203 = LINE('NONE', #202, #201);
|
||||
#204 = DIRECTION('NONE', (-0.9063077870366499, -0.42261826174069944, 0));
|
||||
#205 = VECTOR('NONE', #204, 0.06010152021207346);
|
||||
#204 = DIRECTION('NONE', (-0.90630778703665, -0.42261826174069944, 0));
|
||||
#205 = VECTOR('NONE', #204, 1);
|
||||
#206 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, 0.1016));
|
||||
#207 = LINE('NONE', #206, #205);
|
||||
#208 = DIRECTION('NONE', (-1, 0, 0));
|
||||
#209 = VECTOR('NONE', #208, 0.08889999999999999);
|
||||
#209 = VECTOR('NONE', #208, 1);
|
||||
#210 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, -0));
|
||||
#211 = LINE('NONE', #210, #209);
|
||||
#212 = DIRECTION('NONE', (0, 0, 1));
|
||||
#213 = VECTOR('NONE', #212, 0.1016);
|
||||
#213 = VECTOR('NONE', #212, 1);
|
||||
#214 = CARTESIAN_POINT('NONE', (0, 0.0254, -0));
|
||||
#215 = LINE('NONE', #214, #213);
|
||||
#216 = DIRECTION('NONE', (-1, 0, 0));
|
||||
#217 = VECTOR('NONE', #216, 0.08889999999999999);
|
||||
#217 = VECTOR('NONE', #216, 1);
|
||||
#218 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, 0.1016));
|
||||
#219 = LINE('NONE', #218, #217);
|
||||
#220 = DIRECTION('NONE', (0, -1, 0));
|
||||
#221 = VECTOR('NONE', #220, 0.0254);
|
||||
#221 = VECTOR('NONE', #220, 1);
|
||||
#222 = CARTESIAN_POINT('NONE', (0, 0.0254, -0));
|
||||
#223 = LINE('NONE', #222, #221);
|
||||
#224 = DIRECTION('NONE', (0, -1, 0));
|
||||
#225 = VECTOR('NONE', #224, 0.0254);
|
||||
#225 = VECTOR('NONE', #224, 1);
|
||||
#226 = CARTESIAN_POINT('NONE', (0, 0.0254, 0.1016));
|
||||
#227 = LINE('NONE', #226, #225);
|
||||
#228 = EDGE_CURVE('NONE', #5, #7, #63, .T.);
|
||||
|
BIN
e2e/playwright/export-snapshots/stl-ascii.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
e2e/playwright/export-snapshots/stl-binary.png
Normal file
After Width: | Height: | Size: 57 KiB |
@ -14,6 +14,7 @@ try {
|
||||
} catch (err) {
|
||||
// probably running in CI
|
||||
secrets.token = process.env.token || ''
|
||||
secrets.snapshottoken = process.env.snapshottoken || ''
|
||||
// add more env vars here to make them available in CI
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@ import { v4 as uuidv4 } from 'uuid'
|
||||
import { getUtils } from './test-utils'
|
||||
import { Models } from '@kittycad/lib'
|
||||
import fsp from 'fs/promises'
|
||||
import { spawn } from 'child_process'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
|
||||
test.beforeEach(async ({ context, page }) => {
|
||||
await context.addInitScript(async (token) => {
|
||||
@ -137,6 +139,7 @@ test('change camera, show planes', async ({ page, context }) => {
|
||||
|
||||
test('exports of each format should work', async ({ page, context }) => {
|
||||
// FYI this test doesn't work with only engine running locally
|
||||
// And you will need to have the KittyCAD CLI installed
|
||||
const u = getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
;(window as any).playwrightSkipFilePicker = true
|
||||
@ -194,9 +197,16 @@ const part001 = startSketchOn('-XZ')
|
||||
await page.waitForTimeout(1000)
|
||||
await u.clearAndCloseDebugPanel()
|
||||
|
||||
await page.getByRole('button', { name: 'KittyCAD Modeling App' }).click()
|
||||
await page.getByRole('button', { name: APP_NAME }).click()
|
||||
|
||||
const doExport = async (output: Models['OutputFormat_type']) => {
|
||||
interface Paths {
|
||||
modelPath: string
|
||||
imagePath: string
|
||||
outputType: string
|
||||
}
|
||||
const doExport = async (
|
||||
output: Models['OutputFormat_type']
|
||||
): Promise<Paths> => {
|
||||
await page.getByRole('button', { name: 'Export Model' }).click()
|
||||
|
||||
const exportSelect = page.getByTestId('export-type')
|
||||
@ -210,10 +220,10 @@ const part001 = startSketchOn('-XZ')
|
||||
const downloadPromise = page.waitForEvent('download')
|
||||
await page.getByRole('button', { name: 'Export', exact: true }).click()
|
||||
const download = await downloadPromise
|
||||
const downloadLocationer = (extra = '') =>
|
||||
const downloadLocationer = (extra = '', isImage = false) =>
|
||||
`./e2e/playwright/export-snapshots/${output.type}-${
|
||||
'storage' in output ? output.storage : ''
|
||||
}${extra}.${output.type}`
|
||||
}${extra}.${isImage ? 'png' : output.type}`
|
||||
const downloadLocation = downloadLocationer()
|
||||
const downloadLocation2 = downloadLocationer('-2')
|
||||
|
||||
@ -249,6 +259,11 @@ const part001 = startSketchOn('-XZ')
|
||||
)
|
||||
await fsp.writeFile(downloadLocation, newFileContents)
|
||||
}
|
||||
return {
|
||||
modelPath: downloadLocation,
|
||||
imagePath: downloadLocationer('', true),
|
||||
outputType: output.type,
|
||||
}
|
||||
}
|
||||
const axisDirectionPair: Models['AxisDirectionPair_type'] = {
|
||||
axis: 'z',
|
||||
@ -258,67 +273,116 @@ const part001 = startSketchOn('-XZ')
|
||||
forward: axisDirectionPair,
|
||||
up: axisDirectionPair,
|
||||
}
|
||||
|
||||
const exportLocations: Paths[] = []
|
||||
|
||||
// NOTE it was easiest to leverage existing types and have doExport take Models['OutputFormat_type'] as in input
|
||||
// just note that only `type` and `storage` are used for selecting the drop downs is the app
|
||||
// the rest are only there to make typescript happy
|
||||
await doExport({
|
||||
type: 'step',
|
||||
coords: sysType,
|
||||
})
|
||||
await doExport({
|
||||
type: 'gltf',
|
||||
storage: 'embedded',
|
||||
presentation: 'pretty',
|
||||
})
|
||||
await doExport({
|
||||
type: 'gltf',
|
||||
storage: 'binary',
|
||||
presentation: 'pretty',
|
||||
})
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'step',
|
||||
coords: sysType,
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'ply',
|
||||
coords: sysType,
|
||||
selection: { type: 'default_scene' },
|
||||
storage: 'ascii',
|
||||
units: 'in',
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'ply',
|
||||
storage: 'binary_little_endian',
|
||||
coords: sysType,
|
||||
selection: { type: 'default_scene' },
|
||||
units: 'in',
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'ply',
|
||||
storage: 'binary_big_endian',
|
||||
coords: sysType,
|
||||
selection: { type: 'default_scene' },
|
||||
units: 'in',
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'stl',
|
||||
storage: 'ascii',
|
||||
coords: sysType,
|
||||
units: 'in',
|
||||
selection: { type: 'default_scene' },
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'stl',
|
||||
storage: 'binary',
|
||||
coords: sysType,
|
||||
units: 'in',
|
||||
selection: { type: 'default_scene' },
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
// obj seems to be a little flaky, times out tests sometimes
|
||||
type: 'obj',
|
||||
coords: sysType,
|
||||
units: 'in',
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'gltf',
|
||||
storage: 'embedded',
|
||||
presentation: 'pretty',
|
||||
})
|
||||
)
|
||||
exportLocations.push(
|
||||
await doExport({
|
||||
type: 'gltf',
|
||||
storage: 'binary',
|
||||
presentation: 'pretty',
|
||||
})
|
||||
)
|
||||
|
||||
// TODO: gltfs don't seem to work with snap shots. push onto exportLocations once it's figured out
|
||||
await doExport({
|
||||
type: 'gltf',
|
||||
storage: 'standard',
|
||||
presentation: 'pretty',
|
||||
})
|
||||
await doExport({
|
||||
type: 'ply',
|
||||
coords: sysType,
|
||||
selection: { type: 'default_scene' },
|
||||
storage: 'ascii',
|
||||
units: 'in',
|
||||
})
|
||||
await doExport({
|
||||
type: 'ply',
|
||||
storage: 'binary_little_endian',
|
||||
coords: sysType,
|
||||
selection: { type: 'default_scene' },
|
||||
units: 'in',
|
||||
})
|
||||
await doExport({
|
||||
type: 'ply',
|
||||
storage: 'binary_big_endian',
|
||||
coords: sysType,
|
||||
selection: { type: 'default_scene' },
|
||||
units: 'in',
|
||||
})
|
||||
await doExport({
|
||||
type: 'stl',
|
||||
storage: 'ascii',
|
||||
coords: sysType,
|
||||
units: 'in',
|
||||
selection: { type: 'default_scene' },
|
||||
})
|
||||
await doExport({
|
||||
type: 'stl',
|
||||
storage: 'binary',
|
||||
coords: sysType,
|
||||
units: 'in',
|
||||
selection: { type: 'default_scene' },
|
||||
})
|
||||
await doExport({
|
||||
// obj seems to be a little flaky, times out tests sometimes
|
||||
type: 'obj',
|
||||
coords: sysType,
|
||||
units: 'in',
|
||||
})
|
||||
|
||||
// close page to disconnect websocket since we can only have one open atm
|
||||
await page.close()
|
||||
|
||||
// snapshot exports, good compromise to capture that exports are healthy without getting bogged down in "did the formatting change" changes
|
||||
// context: https://github.com/KittyCAD/modeling-app/issues/1222
|
||||
for (const { modelPath, imagePath, outputType } of exportLocations) {
|
||||
const cliCommand = `export KITTYCAD_TOKEN=${secrets.snapshottoken} && kittycad file snapshot --output-format=png --src-format=${outputType} ${modelPath} ${imagePath}`
|
||||
const child = spawn(cliCommand, { shell: true })
|
||||
await new Promise((resolve, reject) => {
|
||||
child.on('error', (code: any, msg: any) => {
|
||||
console.log('error', code, msg)
|
||||
reject()
|
||||
})
|
||||
child.on('exit', (code, msg) => {
|
||||
console.log('exit', code, msg)
|
||||
if (code !== 0) {
|
||||
reject(`exit code ${code} for model ${modelPath}`)
|
||||
} else {
|
||||
resolve(true)
|
||||
}
|
||||
})
|
||||
child.stderr.on('data', (data) => console.log(`stderr: ${data}`))
|
||||
child.stdout.on('data', (data) => console.log(`stdout: ${data}`))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
@ -1,19 +1,26 @@
|
||||
import { browser, $, expect } from '@wdio/globals'
|
||||
import fs from 'fs/promises'
|
||||
|
||||
describe('KCMA (Tauri, Linux)', () => {
|
||||
it('opens the auth page, signs in, and signs out', async () => {
|
||||
// Clean up previous tests
|
||||
const defaultDir = `${process.env.HOME}/Documents/zoo-modeling-app-projects`
|
||||
const userCodeDir = '/tmp/kittycad_user_code'
|
||||
|
||||
async function click(element: WebdriverIO.Element): Promise<void> {
|
||||
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
|
||||
await element.waitForClickable()
|
||||
await browser.execute('arguments[0].click();', element)
|
||||
}
|
||||
|
||||
describe('ZMA (Tauri, Linux)', () => {
|
||||
it('opens the auth page and signs in', async () => {
|
||||
// Clean up filesystem from previous tests
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
await fs.rm('/tmp/kittycad_user_code', { force: true })
|
||||
await browser.execute('window.localStorage.clear()')
|
||||
await fs.rm(defaultDir, { force: true, recursive: true })
|
||||
await fs.rm(userCodeDir, { force: true })
|
||||
|
||||
const signInButton = await $('[data-testid="sign-in-button"]')
|
||||
expect(await signInButton.getText()).toEqual('Sign in')
|
||||
|
||||
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
|
||||
await signInButton.waitForClickable()
|
||||
await browser.execute('arguments[0].click();', signInButton)
|
||||
await click(signInButton)
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
|
||||
// Get from main.rs
|
||||
@ -49,14 +56,51 @@ describe('KCMA (Tauri, Linux)', () => {
|
||||
// Now should be signed in
|
||||
const newFileButton = await $('[data-testid="home-new-file"]')
|
||||
expect(await newFileButton.getText()).toEqual('New file')
|
||||
})
|
||||
|
||||
// So let's sign out!
|
||||
it('opens the settings page, checks filesystem settings, and closes the settings page', async () => {
|
||||
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
||||
await menuButton.waitForClickable()
|
||||
await browser.execute('arguments[0].click();', menuButton)
|
||||
await click(menuButton)
|
||||
|
||||
const settingsButton = await $('[data-testid="settings-button"]')
|
||||
await click(settingsButton)
|
||||
|
||||
const defaultDirInput = await $('[data-testid="default-directory-input"]')
|
||||
expect(await defaultDirInput.getValue()).toEqual(defaultDir)
|
||||
|
||||
const nameInput = await $('[data-testid="name-input"]')
|
||||
expect(await nameInput.getValue()).toEqual('project-$nnn')
|
||||
|
||||
const closeButton = await $('[data-testid="close-button"]')
|
||||
await click(closeButton)
|
||||
})
|
||||
|
||||
it('checks that no file exists, creates a new file', async () => {
|
||||
const homeSection = await $('[data-testid="home-section"]')
|
||||
expect(await homeSection.getText()).toContain('No Projects found')
|
||||
|
||||
const newFileButton = await $('[data-testid="home-new-file"]')
|
||||
await click(newFileButton)
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
|
||||
expect(await homeSection.getText()).toContain('project-000')
|
||||
})
|
||||
|
||||
it('opens the new file and expects an error on Linux', async () => {
|
||||
const projectLink = await $('[data-testid="project-link"]')
|
||||
await click(projectLink)
|
||||
const error = await $('h3')
|
||||
expect(await error.getText()).toContain(
|
||||
"Can't find variable: RTCPeerConnection"
|
||||
)
|
||||
await browser.execute('window.location.href = "tauri://localhost/home"')
|
||||
})
|
||||
|
||||
it('signs out', async () => {
|
||||
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
||||
await click(menuButton)
|
||||
const signoutButton = await $('[data-testid="user-sidebar-sign-out"]')
|
||||
await signoutButton.waitForClickable()
|
||||
await browser.execute('arguments[0].click();', signoutButton)
|
||||
await click(signoutButton)
|
||||
const newSignInButton = await $('[data-testid="sign-in-button"]')
|
||||
expect(await newSignInButton.getText()).toEqual('Sign in')
|
||||
})
|
||||
|
11
index.html
@ -7,12 +7,17 @@
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="An open-source CAD modeling tool from the future by KittyCAD."
|
||||
content="An open-source CAD modeling tool from the future by Zoo."
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="/logo192.png" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<script defer data-domain="app.kittycad.io" src="https://plausible.corp.kittycad.io/js/script.js"></script>
|
||||
<title>KittyCAD Modeling App</title>
|
||||
<link rel="stylesheet" href="https://use.typekit.net/zzv8rvm.css" />
|
||||
<script
|
||||
defer
|
||||
data-domain="app.zoo.dev"
|
||||
src="https://plausible.corp.zoo.dev/js/script.js"
|
||||
></script>
|
||||
<title>Zoo Modeling App</title>
|
||||
</head>
|
||||
<body class="body-bg">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "untitled-app",
|
||||
"version": "0.13.0",
|
||||
"version": "0.14.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.10.2",
|
||||
@ -136,7 +136,7 @@
|
||||
"prettier": "^2.8.0",
|
||||
"setimmediate": "^1.0.5",
|
||||
"tailwindcss": "^3.3.6",
|
||||
"vite": "^4.5.0",
|
||||
"vite": "^4.5.2",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-tsconfig-paths": "^4.2.1",
|
||||
"wait-on": "^7.2.0",
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
First off, thank you so much for your interest in being a part of the closed Alpha program! We are thrilled to have others use our product and see what you build with it (and truthfully, how you break it too).
|
||||
|
||||
### KittyCAD Modeling App (KCMA)
|
||||
### Zoo Modeling App (ZMA)
|
||||
|
||||
What we are introducing to you is our KittyCAD Modeling App (KCMA). KCMA is a CAD application that expresses a hybrid style of traditional CAD interface along with a code-CAD interface. KCMA is a great way for us to test our own APIs as well as inspire others to develop their own applications.
|
||||
What we are introducing to you is our Zoo Modeling App (ZMA). ZMA is a CAD application that expresses a hybrid style of traditional CAD interface along with a code-CAD interface. ZMA is a great way for us to test our own APIs as well as inspire others to develop their own applications.
|
||||
|
||||
### Why Code?
|
||||
|
||||
@ -18,11 +18,11 @@ Plenty of you have professional CAD experience, and may not understand why codin
|
||||
- Reproducibility
|
||||
- Easier integration with other tools
|
||||
|
||||
### Before You Use KCMA
|
||||
### Before You Use ZMA
|
||||
|
||||
Before you dive straight into the app, we wanted to lay some expectations out for you.
|
||||
|
||||
- KCMA is in early development. Kurt pitched the idea back in January, and the team has been working hard on it since then. KCMA has really basic CAD features for now, but we have plenty of features on our roadmap. Most of the features that you may be currently used to in your CAD workflow today will be available down the road.
|
||||
- ZMA is in early development. Kurt pitched the idea back in January, and the team has been working hard on it since then. ZMA has really basic CAD features for now, but we have plenty of features on our roadmap. Most of the features that you may be currently used to in your CAD workflow today will be available down the road.
|
||||
- For a list of all scripting functions, please reference our [documentation](https://github.com/KittyCAD/modeling-app/blob/main/docs/kcl/std.md). For a basic rundown of our types, please reference [this document](https://github.com/KittyCAD/modeling-app/blob/main/docs/kcl/types.md).
|
||||
- With that being said, we have created an external new features list in [GH Discussions](https://github.com/KittyCAD/modeling-app/discussions). For our current priority list, please click [here](https://github.com/KittyCAD/modeling-app/blob/main/public/roadmap.md). Please upvote any features in the GH Discussions page that you would like to see implemented first. We will prioritize the highest upvoted items or items that are foundational for other features on the list. You can also add your own, but we will review it to make sure it’s not a duplicate or it’s feasible for the current state of the app.
|
||||
- Please report any and all bugs/issues you find. Even the smallest bugs are important! You can report them in a GH Issue [here](https://github.com/KittyCAD/modeling-app/issues/new). You are more than welcome to link your GH Issue in the **bugs** section of our Discord, but if you want to discuss the bug further, please keep that in the GH Issue thread. Please include the severity of the bug in your GH Issue ticket (High, Medium, or Low). If you are having trouble deciding what severity the bug is, use this guideline:
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"short_name": "KCMA",
|
||||
"name": "KittyCAD Modeling App",
|
||||
"short_name": "ZMA",
|
||||
"name": "Zoo Modeling App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
|
@ -1,4 +1,4 @@
|
||||
## KittyCAD Modeling App Roadmap
|
||||
## Zoo Modeling App Roadmap
|
||||
|
||||
This document ties into our [GH Discussions Feature List](https://github.com/KittyCAD/modeling-app/discussions). Please upvote any features that you want to see next, or add ones that are not listed and we will review.
|
||||
|
||||
|
13
public/zma-logomark-dark.svg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
public/zma-logomark-outlined.png
Normal file
After Width: | Height: | Size: 11 KiB |
13
public/zma-logomark.svg
Normal file
After Width: | Height: | Size: 13 KiB |
7
public/zoo-logo.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="438" height="145" viewBox="0 0 438 145" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M88.2136 25.3021V3.12744H0.595269V34.3994H79.827L0.609484 120.312H0.595269V120.326L0.581055 120.34L0.595269 120.355V141.364H20.8936L41.3341 119.189V141.364H128.952V110.092H49.7349L128.952 24.1649V3.12744L108.64 3.15587L88.2136 25.3021Z" fill="white"/>
|
||||
<path d="M167.36 72.4372C167.36 49.7366 185.824 31.2719 208.525 31.2719C216.514 31.2719 223.976 33.5605 230.288 37.5121L251.78 14.3709C239.698 5.34466 224.73 0 208.525 0C168.582 0 136.088 32.4944 136.088 72.4372C136.088 90.5465 142.769 107.135 153.828 119.857L175.32 96.7156C170.316 89.9069 167.36 81.5061 167.36 72.4372Z" fill="white"/>
|
||||
<path d="M241.745 48.1442C246.734 54.9671 249.691 63.3679 249.691 72.4368C249.691 95.1232 231.226 113.588 208.525 113.588C200.537 113.588 193.088 111.299 186.777 107.348L165.271 130.503C177.353 139.515 192.321 144.86 208.525 144.86C248.468 144.86 280.963 112.365 280.963 72.4368C280.963 54.3133 274.282 37.7249 263.223 25.0029L241.745 48.1442Z" fill="white"/>
|
||||
<path d="M419.312 25.0029L397.834 48.1442C402.823 54.9671 405.779 63.3679 405.779 72.4368C405.779 95.1232 387.315 113.588 364.614 113.588C356.626 113.588 349.177 111.299 342.866 107.348L321.359 130.503C333.442 139.515 348.41 144.86 364.614 144.86C404.557 144.86 437.051 112.365 437.051 72.4368C437.051 54.3133 430.371 37.7249 419.312 25.0029Z" fill="white"/>
|
||||
<path d="M323.449 72.4372C323.449 49.7366 341.913 31.2719 364.614 31.2719C372.603 31.2719 380.065 33.5605 386.376 37.5121L407.869 14.3709C395.786 5.34466 380.819 0 364.614 0C324.671 0 292.177 32.4944 292.177 72.4372C292.177 90.5465 298.858 107.135 309.916 119.857L331.409 96.7156C326.405 89.9069 323.449 81.5061 323.449 72.4372Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
162
src-tauri/Cargo.lock
generated
@ -547,12 +547,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.26"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||
checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.33",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1242,9 +1242,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.20"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
|
||||
checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
@ -1252,7 +1252,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.0.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@ -1530,9 +1530,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a898e4b7951673fce96614ce5751d13c40fc5674bc2d759288e46c3ab62598b3"
|
||||
checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc"
|
||||
dependencies = [
|
||||
"cfb",
|
||||
]
|
||||
@ -1652,9 +1652,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "json-patch"
|
||||
version = "1.0.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f54898088ccb91df1b492cc80029a6fdf1c48ca0db7c6822a8babad69c94658"
|
||||
checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -2194,11 +2194,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.55"
|
||||
version = "0.10.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
|
||||
checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.4.0",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@ -2226,9 +2226,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.90"
|
||||
version = "0.9.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
|
||||
checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -2400,9 +2400,17 @@ version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
|
||||
dependencies = [
|
||||
"phf_macros 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2445,6 +2453,16 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.8.0"
|
||||
@ -2461,16 +2479,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.10.0"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.33",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2491,6 +2508,15 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phonenumber"
|
||||
version = "0.3.3+8.13.9"
|
||||
@ -3734,9 +3760,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "1.5.2"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bfe673cf125ef364d6f56b15e8ce7537d9ca7e4dae1cf6fbbdeed2e024db3d9"
|
||||
checksum = "32d563b672acde8d0cc4c1b1f5b855976923f67e8d6fe1eba51df0211e197be2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -3831,9 +3857,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-macros"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613740228de92d9196b795ac455091d3a5fbdac2654abb8bb07d010b62ab43af"
|
||||
checksum = "acea6445eececebd72ed7720cfcca46eee3b5bad8eb408be8f7ef2e3f7411500"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
@ -3878,9 +3904,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "0.14.1"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8141d72b6b65f2008911e9ef5b98a68d1e3413b7a1464e8f85eb3673bb19a895"
|
||||
checksum = "803a01101bc611ba03e13329951a1bde44287a54234189b9024b78619c1bc206"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"gtk",
|
||||
@ -3898,9 +3924,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-utils"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34d55e185904a84a419308d523c2c6891d5e2dbcee740c4997eb42e75a7b0f46"
|
||||
checksum = "a52165bb340e6f6a75f1f5eeeab1bb49f861c12abe3a176067d53642b5454986"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"ctor",
|
||||
@ -3913,7 +3939,7 @@ dependencies = [
|
||||
"kuchikiki",
|
||||
"log",
|
||||
"memchr",
|
||||
"phf 0.10.1",
|
||||
"phf 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"semver",
|
||||
@ -3923,7 +3949,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"url",
|
||||
"walkdir",
|
||||
"windows 0.39.0",
|
||||
"windows-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4747,12 +4773,36 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-tokens"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597"
|
||||
|
||||
[[package]]
|
||||
name = "windows-version"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75aa004c988e080ad34aff5739c39d0312f4684699d6d71fc8a198d057b8b9b4"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@ -4765,6 +4815,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.37.0"
|
||||
@ -4789,6 +4845,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.37.0"
|
||||
@ -4813,6 +4875,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.37.0"
|
||||
@ -4837,6 +4905,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.37.0"
|
||||
@ -4861,6 +4935,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@ -4873,6 +4953,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.37.0"
|
||||
@ -4897,6 +4983,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.15"
|
||||
@ -4928,9 +5020,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.24.4"
|
||||
version = "0.24.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ef04bdad49eba2e01f06e53688c8413bd6a87b0bc14b72284465cf96e3578e"
|
||||
checksum = "64a70547e8f9d85da0f5af609143f7bde3ac7457a6e1073104d9b73d6c5ac744"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"block",
|
||||
|
@ -20,7 +20,7 @@ kittycad = "0.2.42"
|
||||
oauth2 = "4.4.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tauri = { version = "1.5.2", features = [ "os-all", "dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "devtools"] }
|
||||
tauri = { version = "1.5.3", features = [ "os-all", "dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "devtools"] }
|
||||
tauri-plugin-fs-extra = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
tokio = { version = "1.34.0", features = ["time"] }
|
||||
toml = "0.8.2"
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 69 KiB |
@ -76,16 +76,13 @@ async fn login(app: tauri::AppHandle, host: &str) -> Result<String, InvokeError>
|
||||
// Here we're using an env var to enable the /tmp file (windows not supported for now)
|
||||
// and bypass the shell::open call as it fails on GitHub Actions.
|
||||
let e2e_tauri_enabled = env::var("E2E_TAURI_ENABLED").is_ok();
|
||||
if (e2e_tauri_enabled) {
|
||||
if e2e_tauri_enabled {
|
||||
println!(
|
||||
"E2E_TAURI_ENABLED is set, won't open {} externally",
|
||||
auth_uri.secret()
|
||||
);
|
||||
fs::write(
|
||||
"/tmp/kittycad_user_code",
|
||||
details.user_code().secret().to_string(),
|
||||
)
|
||||
.expect("Unable to write /tmp/kittycad_user_code file");
|
||||
fs::write("/tmp/kittycad_user_code", details.user_code().secret())
|
||||
.expect("Unable to write /tmp/kittycad_user_code file");
|
||||
} else {
|
||||
tauri::api::shell::open(&app.shell_scope(), auth_uri.secret(), None)
|
||||
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
|
||||
|
@ -6,8 +6,8 @@
|
||||
"distDir": "../build"
|
||||
},
|
||||
"package": {
|
||||
"productName": "kittycad-modeling",
|
||||
"version": "0.13.0"
|
||||
"productName": "zoo-modeling-app",
|
||||
"version": "0.14.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
@ -84,7 +84,7 @@
|
||||
"fullscreen": false,
|
||||
"height": 1200,
|
||||
"resizable": true,
|
||||
"title": "KittyCAD Modeling",
|
||||
"title": "Zoo Modeling App",
|
||||
"width": 1800
|
||||
}
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"package": {
|
||||
"productName": "KittyCAD Modeling"
|
||||
"productName": "Zoo Modeling App"
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
"updater": {
|
||||
"active": true,
|
||||
"endpoints": [
|
||||
"https://dl.kittycad.io/releases/modeling-app/last_update.json"
|
||||
"https://dl.zoo.dev/releases/modeling-app/last_update.json"
|
||||
],
|
||||
"dialog": true,
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEUzNzA4MjBEQjFBRTY4NzYKUldSMmFLNnhEWUp3NCtsT21Jd05wQktOaGVkOVp6MUFma0hNTDRDSnI2RkJJTEZOWG1ncFhqcU8K"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"package": {
|
||||
"productName": "KittyCAD Modeling"
|
||||
"productName": "Zoo Modeling App"
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ export const Auth = ({ children }: React.PropsWithChildren) => {
|
||||
|
||||
return isLoggingIn ? (
|
||||
<Loading>
|
||||
<span data-testid="initial-load">Loading KittyCAD Modeling App...</span>
|
||||
<span data-testid="initial-load">Loading Modeling App...</span>
|
||||
</Loading>
|
||||
) : (
|
||||
<>{children}</>
|
||||
|
@ -112,6 +112,7 @@ export type ProjectWithEntryPointMetadata = FileEntry & {
|
||||
}
|
||||
export type HomeLoaderData = {
|
||||
projects: ProjectWithEntryPointMetadata[]
|
||||
newDefaultDirectory?: string
|
||||
}
|
||||
|
||||
type CreateBrowserRouterArg = Parameters<typeof createBrowserRouter>[0]
|
||||
@ -259,6 +260,7 @@ const router = createBrowserRouter(
|
||||
const projectDir = await initializeProjectDirectory(
|
||||
persistedSettings.defaultDirectory || ''
|
||||
)
|
||||
let newDefaultDirectory: string | undefined = undefined
|
||||
if (projectDir !== persistedSettings.defaultDirectory) {
|
||||
localStorage.setItem(
|
||||
SETTINGS_PERSIST_KEY,
|
||||
@ -267,6 +269,7 @@ const router = createBrowserRouter(
|
||||
defaultDirectory: projectDir,
|
||||
})
|
||||
)
|
||||
newDefaultDirectory = projectDir
|
||||
}
|
||||
const projectsNoMeta = (await readDir(projectDir)).filter(
|
||||
isProjectDirectory
|
||||
@ -282,6 +285,7 @@ const router = createBrowserRouter(
|
||||
|
||||
return {
|
||||
projects,
|
||||
newDefaultDirectory,
|
||||
}
|
||||
},
|
||||
children: [
|
||||
|
@ -33,7 +33,7 @@ export const AppHeader = ({
|
||||
className={
|
||||
'w-full grid ' +
|
||||
styles.header +
|
||||
' overlaid-panes sticky top-0 z-20 py-1 px-5 bg-chalkboard-10/70 dark:bg-chalkboard-100/50 border-b dark:border-b-2 border-chalkboard-30 dark:border-chalkboard-90 items-center ' +
|
||||
' overlaid-panes sticky top-0 z-20 py-1 px-2 bg-chalkboard-10/70 dark:bg-chalkboard-100/50 border-b dark:border-b-2 border-chalkboard-30 dark:border-chalkboard-90 items-center ' +
|
||||
className
|
||||
}
|
||||
>
|
||||
|
@ -19,7 +19,7 @@ const DownloadAppBanner = () => {
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<div className="flex gap-2 justify-between items-start">
|
||||
<h2 className="text-xl font-bold mb-4">
|
||||
KittyCAD Modeling App is better as a desktop app!
|
||||
Modeling App is better as a desktop app!
|
||||
</h2>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
@ -42,7 +42,7 @@ const DownloadAppBanner = () => {
|
||||
</code>
|
||||
, and isn't backed up anywhere! Visit{' '}
|
||||
<a
|
||||
href="https://kittycad.io/modeling-app/download"
|
||||
href="https://zoo.dev/modeling-app/download"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
className="!text-warn-80 dark:!text-warn-80 dark:hover:!text-warn-70 underline"
|
||||
|
33
src/components/Logo.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
export const Logo = ({
|
||||
className = 'w-auto h-5 text-chalkboard-120 dark:text-chalkboard-10',
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
{...props}
|
||||
className={className}
|
||||
viewBox="0 0 438 145"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M88.2136 25.3021V3.12744H0.595269V34.3994H79.827L0.609484 120.312H0.595269V120.326L0.581055 120.34L0.595269 120.355V141.364H20.8936L41.3341 119.189V141.364H128.952V110.092H49.7349L128.952 24.1649V3.12744L108.64 3.15587L88.2136 25.3021Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M167.36 72.4372C167.36 49.7366 185.824 31.2719 208.525 31.2719C216.514 31.2719 223.976 33.5605 230.288 37.5121L251.78 14.3709C239.698 5.34466 224.73 0 208.525 0C168.582 0 136.088 32.4944 136.088 72.4372C136.088 90.5465 142.769 107.135 153.828 119.857L175.32 96.7156C170.316 89.9069 167.36 81.5061 167.36 72.4372Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M241.745 48.1442C246.734 54.9671 249.691 63.3679 249.691 72.4368C249.691 95.1232 231.226 113.588 208.525 113.588C200.537 113.588 193.088 111.299 186.777 107.348L165.271 130.503C177.353 139.515 192.321 144.86 208.525 144.86C248.468 144.86 280.963 112.365 280.963 72.4368C280.963 54.3133 274.282 37.7249 263.223 25.0029L241.745 48.1442Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M419.312 25.0029L397.834 48.1442C402.823 54.9671 405.779 63.3679 405.779 72.4368C405.779 95.1232 387.315 113.588 364.614 113.588C356.626 113.588 349.177 111.299 342.866 107.348L321.359 130.503C333.442 139.515 348.41 144.86 364.614 144.86C404.557 144.86 437.051 112.365 437.051 72.4368C437.051 54.3133 430.371 37.7249 419.312 25.0029Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M323.449 72.4372C323.449 49.7366 341.913 31.2719 364.614 31.2719C372.603 31.2719 380.065 33.5605 386.376 37.5121L407.869 14.3709C395.786 5.34466 380.819 0 364.614 0C324.671 0 292.177 32.4944 292.177 72.4372C292.177 90.5465 298.858 107.135 309.916 119.857L331.409 96.7156C326.405 89.9069 323.449 81.5061 323.449 72.4372Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
)
|
@ -107,6 +107,7 @@ function ProjectCard({
|
||||
<Link
|
||||
className="flex-1 text-liquid-100 after:content-[''] after:absolute after:inset-0"
|
||||
to={`${paths.FILE}/${encodeURIComponent(project.path)}`}
|
||||
data-testid="project-link"
|
||||
>
|
||||
{project.name?.replace(FILE_EXT, '')}
|
||||
</Link>
|
||||
|
@ -4,6 +4,7 @@ import ProjectSidebarMenu from './ProjectSidebarMenu'
|
||||
import { ProjectWithEntryPointMetadata } from '../Router'
|
||||
import { GlobalStateProvider } from './GlobalStateProvider'
|
||||
import CommandBarProvider from './CommandBar/CommandBar'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
|
||||
const now = new Date()
|
||||
const projectWellFormed = {
|
||||
@ -71,9 +72,7 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
|
||||
fireEvent.click(screen.getByTestId('project-sidebar-toggle'))
|
||||
|
||||
expect(screen.getByTestId('projectName')).toHaveTextContent(
|
||||
'KittyCAD Modeling App'
|
||||
)
|
||||
expect(screen.getByTestId('projectName')).toHaveTextContent(APP_NAME)
|
||||
})
|
||||
|
||||
test('Renders as a link if set to do so', () => {
|
||||
|
@ -8,6 +8,8 @@ import { ExportButton } from './ExportButton'
|
||||
import { Fragment } from 'react'
|
||||
import { FileTree } from './FileTree'
|
||||
import { sep } from '@tauri-apps/api/path'
|
||||
import { Logo } from './Logo'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
|
||||
const ProjectSidebarMenu = ({
|
||||
project,
|
||||
@ -21,37 +23,29 @@ const ProjectSidebarMenu = ({
|
||||
return renderAsLink ? (
|
||||
<Link
|
||||
to={paths.HOME}
|
||||
className="rounded-sm h-9 mr-auto max-h-min min-w-max border-0 p-0.5 pr-2 flex items-center gap-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50 dark:hover:bg-chalkboard-90"
|
||||
className="rounded-sm h-9 mr-auto max-h-min min-w-max border-0 py-1 px-2 flex items-center gap-3 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50 dark:hover:bg-chalkboard-90"
|
||||
data-testid="project-sidebar-link"
|
||||
>
|
||||
<img
|
||||
src="/kitt-8bit-winking.svg"
|
||||
alt="KittyCAD App"
|
||||
className="w-auto h-9"
|
||||
/>
|
||||
<Logo />
|
||||
<span
|
||||
className="hidden text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap lg:block"
|
||||
data-testid="project-sidebar-link-name"
|
||||
>
|
||||
{project?.name ? project.name : 'KittyCAD Modeling App'}
|
||||
{project?.name ? project.name : APP_NAME}
|
||||
</span>
|
||||
</Link>
|
||||
) : (
|
||||
<Popover className="relative">
|
||||
<Popover.Button
|
||||
className="rounded-sm h-9 mr-auto max-h-min min-w-max border-0 p-0.5 pr-2 flex items-center gap-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50 dark:hover:bg-chalkboard-90"
|
||||
className="rounded-sm h-9 mr-auto max-h-min min-w-max border-0 py-1 px-2 flex items-center gap-3 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50 dark:hover:bg-chalkboard-90"
|
||||
data-testid="project-sidebar-toggle"
|
||||
>
|
||||
<img
|
||||
src="/kitt-8bit-winking.svg"
|
||||
alt="KittyCAD App"
|
||||
className="w-auto h-full"
|
||||
/>
|
||||
<Logo />
|
||||
<div className="flex flex-col items-start py-0.5">
|
||||
<span className="hidden text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap lg:block">
|
||||
{isTauri() && file?.name
|
||||
? file.name.slice(file.name.lastIndexOf(sep) + 1)
|
||||
: 'KittyCAD Modeling App'}
|
||||
: APP_NAME}
|
||||
</span>
|
||||
{isTauri() && project?.name && (
|
||||
<span className="hidden text-xs text-chalkboard-70 dark:text-chalkboard-40 whitespace-nowrap lg:block">
|
||||
@ -88,18 +82,13 @@ const ProjectSidebarMenu = ({
|
||||
{({ close }) => (
|
||||
<>
|
||||
<div className="flex items-center gap-4 px-4 py-3">
|
||||
<img
|
||||
src="/kitt-8bit-winking.svg"
|
||||
alt="KittyCAD App"
|
||||
className="w-auto h-9"
|
||||
/>
|
||||
|
||||
<Logo />
|
||||
<div>
|
||||
<p
|
||||
className="m-0 text-chalkboard-100 dark:text-energy-10 text-mono"
|
||||
data-testid="projectName"
|
||||
>
|
||||
{project?.name ? project.name : 'KittyCAD Modeling App'}
|
||||
{project?.name ? project.name : APP_NAME}
|
||||
</p>
|
||||
{project?.entrypointMetadata && (
|
||||
<p
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
} from 'react'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useStore } from '../useStore'
|
||||
import { getNormalisedCoordinates } from '../lib/utils'
|
||||
import { getNormalisedCoordinates, throttle } from '../lib/utils'
|
||||
import Loading from './Loading'
|
||||
import { cameraMouseDragGuards } from 'lib/cameraControls'
|
||||
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
||||
@ -115,9 +115,9 @@ export const Stream = ({ className = '' }) => {
|
||||
setClickCoords({ x, y })
|
||||
}
|
||||
|
||||
const handleScroll: WheelEventHandler<HTMLVideoElement> = (e) => {
|
||||
const fps = 60
|
||||
const handleScroll: WheelEventHandler<HTMLVideoElement> = throttle((e) => {
|
||||
if (!cameraMouseDragGuards[cameraControls].zoom.scrollCallback(e)) return
|
||||
|
||||
engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd: {
|
||||
@ -126,7 +126,7 @@ export const Stream = ({ className = '' }) => {
|
||||
},
|
||||
cmd_id: uuidv4(),
|
||||
})
|
||||
}
|
||||
}, Math.round(1000 / fps))
|
||||
|
||||
const handleMouseUp: MouseEventHandler<HTMLVideoElement> = ({
|
||||
clientX,
|
||||
|
@ -128,6 +128,7 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
|
||||
: paths.HOME + paths.SETTINGS
|
||||
navigate(targetPath)
|
||||
}}
|
||||
data-testid="settings-button"
|
||||
>
|
||||
Settings
|
||||
</ActionButton>
|
||||
|
@ -6,9 +6,7 @@
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
@apply font-sans;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
@apply text-chalkboard-110;
|
||||
@ -17,6 +15,15 @@ body {
|
||||
scrollbar-color: var(--color-chalkboard-20) var(--color-chalkboard-40);
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
@apply font-display;
|
||||
}
|
||||
|
||||
.body-bg {
|
||||
@apply bg-chalkboard-10;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ export function getCoordsFromPaths(skGroup: SketchGroup, index = 0): Coords2d {
|
||||
} else if (!currentPath) {
|
||||
return [0, 0]
|
||||
}
|
||||
if (currentPath.type === 'toPoint') {
|
||||
if (currentPath.type === 'topoint') {
|
||||
return [currentPath.to[0], currentPath.to[1]]
|
||||
}
|
||||
return [0, 0]
|
||||
|
@ -1537,7 +1537,8 @@ export function isLiteralArrayOrStatic(
|
||||
if (!val) return false
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
const [a, b] = val
|
||||
const a = val[0]
|
||||
const b = val[1]
|
||||
return isLiteralArrayOrStatic(a) && isLiteralArrayOrStatic(b)
|
||||
}
|
||||
return (
|
||||
@ -1550,7 +1551,8 @@ export function isNotLiteralArrayOrStatic(
|
||||
val: Value | [Value, Value] | [Value, Value, Value]
|
||||
): boolean {
|
||||
if (Array.isArray(val)) {
|
||||
const [a, b] = val
|
||||
const a = val[0]
|
||||
const b = val[1]
|
||||
return isNotLiteralArrayOrStatic(a) && isNotLiteralArrayOrStatic(b)
|
||||
}
|
||||
return (
|
||||
|
1
src/lib/constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const APP_NAME = 'Modeling App'
|
@ -10,7 +10,7 @@ import { isTauri } from './isTauri'
|
||||
import { ProjectWithEntryPointMetadata } from '../Router'
|
||||
import { metadata } from 'tauri-plugin-fs-extra-api'
|
||||
|
||||
const PROJECT_FOLDER = 'kittycad-modeling-projects'
|
||||
const PROJECT_FOLDER = 'zoo-modeling-app-projects'
|
||||
export const FILE_EXT = '.kcl'
|
||||
export const PROJECT_ENTRYPOINT = 'main' + FILE_EXT
|
||||
const INDEX_IDENTIFIER = '$n' // $nn.. will pad the number with 0s
|
||||
@ -38,7 +38,7 @@ export async function initializeProjectDirectory(directory: string) {
|
||||
docDirectory = await documentDir()
|
||||
} catch (e) {
|
||||
console.log('error', e)
|
||||
docDirectory = await homeDir() // seems to work better on Linux
|
||||
docDirectory = `${await homeDir()}Documents/` // for headless Linux (eg. Github Actions)
|
||||
}
|
||||
|
||||
const INITIAL_DEFAULT_DIR = docDirectory + PROJECT_FOLDER
|
||||
|
@ -37,13 +37,20 @@ import { homeCommandBarConfig } from 'lib/commandBarConfigs/homeCommandConfig'
|
||||
const Home = () => {
|
||||
const { commandBarSend } = useCommandsContext()
|
||||
const navigate = useNavigate()
|
||||
const { projects: loadedProjects } = useLoaderData() as HomeLoaderData
|
||||
const { projects: loadedProjects, newDefaultDirectory } =
|
||||
useLoaderData() as HomeLoaderData
|
||||
const {
|
||||
settings: {
|
||||
context: { defaultDirectory, defaultProjectName },
|
||||
send: sendToSettings,
|
||||
},
|
||||
} = useGlobalStateContext()
|
||||
if (newDefaultDirectory) {
|
||||
sendToSettings({
|
||||
type: 'Set Default Directory',
|
||||
data: { defaultDirectory: newDefaultDirectory },
|
||||
})
|
||||
}
|
||||
|
||||
const [state, send] = useMachine(homeMachine, {
|
||||
context: {
|
||||
@ -177,7 +184,7 @@ const Home = () => {
|
||||
<AppHeader showToolbar={false} />
|
||||
<div className="w-full max-w-5xl px-4 mx-auto my-24 overflow-y-auto lg:px-0">
|
||||
<section className="flex justify-between">
|
||||
<h1 className="text-3xl text-bold">Your Projects</h1>
|
||||
<h1 className="text-3xl font-bold">Your Projects</h1>
|
||||
<div className="flex gap-2 items-center">
|
||||
<small>Sort by</small>
|
||||
<ActionButton
|
||||
@ -222,7 +229,7 @@ const Home = () => {
|
||||
</ActionButton>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<section data-testid="home-section">
|
||||
<p className="my-4 text-sm text-chalkboard-80 dark:text-chalkboard-30">
|
||||
Loaded from{' '}
|
||||
<span className="text-energy-70 dark:text-energy-40">
|
||||
|
@ -27,7 +27,7 @@ export default function Units() {
|
||||
<div className="fixed inset-0 z-50 grid items-end justify-start px-4 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-2xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
|
@ -14,11 +14,11 @@ export default function CmdK() {
|
||||
<div className="fixed inset-0 z-50 grid items-end justify-center pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-full xl:max-w-4xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-full xl:max-w-4xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<h2 className="text-2xl">Command Bar</h2>
|
||||
<h2 className="text-2xl font-bold">Command Bar</h2>
|
||||
<p className="my-4">
|
||||
Press{' '}
|
||||
{platformName === 'darwin' ? (
|
||||
@ -34,8 +34,8 @@ export default function CmdK() {
|
||||
</p>
|
||||
<p className="my-4">
|
||||
We are working on a command bar that will allow you to quickly see and
|
||||
search for any available commands. We are building KittyCAD Modeling
|
||||
App's state management system on top of{' '}
|
||||
search for any available commands. We are building Zoo Modeling App's
|
||||
state management system on top of{' '}
|
||||
<a
|
||||
href="https://xstate.js.org/"
|
||||
rel="noreferrer noopener"
|
||||
|
@ -17,19 +17,19 @@ export default function CodeEditor() {
|
||||
></div>
|
||||
<div
|
||||
className={
|
||||
'z-10 max-w-xl h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl">
|
||||
<h2 className="text-2xl font-bold">
|
||||
Editing code with <code>kcl</code>
|
||||
</h2>
|
||||
<p className="my-4">
|
||||
The left pane is where you write your code. It's a code editor with
|
||||
syntax highlighting and autocompletion. We've decided to take the
|
||||
difficult route of writing our own language—called <code>kcl</code>
|
||||
—for describing geometry, because don't want to inherit all the
|
||||
—for describing geometry, because we don't want to inherit all the
|
||||
other functionality from existing languages. We have a lot of ideas
|
||||
about how <code>kcl</code> will evolve, and we want to hear your
|
||||
thoughts on it.
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
import { OnboardingButtons, onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useStore } from '../../useStore'
|
||||
|
||||
@ -12,19 +13,19 @@ export default function Export() {
|
||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-full xl:max-w-2xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl">Export</h2>
|
||||
<h2 className="text-2xl font-bold">Export</h2>
|
||||
<p className="my-4">
|
||||
Try opening the project menu and clicking "Export Model".
|
||||
</p>
|
||||
<p className="my-4">
|
||||
KittyCAD Modeling App uses{' '}
|
||||
{APP_NAME} uses{' '}
|
||||
<a
|
||||
href="https://kittycad.io/gltf-format-extension"
|
||||
href="https://zoo.dev/gltf-format-extension"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
@ -32,7 +33,7 @@ export default function Export() {
|
||||
</a>{' '}
|
||||
for the GLTF file format.{' '}
|
||||
<a
|
||||
href="https://kittycad.io/docs/api/convert-cad-file"
|
||||
href="https://zoo.dev/docs/api/convert-cad-file"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
|
@ -3,6 +3,7 @@ import { useEffect } from 'react'
|
||||
import { bracket } from 'lib/exampleKcl'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
import { useModelingContext } from 'hooks/useModelingContext'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
|
||||
export default function FutureWork() {
|
||||
const { send } = useModelingContext()
|
||||
@ -22,7 +23,7 @@ export default function FutureWork() {
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-center inset-0 bg-chalkboard-100/50 z-50">
|
||||
<div className="max-w-full xl:max-w-2xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded">
|
||||
<div className="max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded">
|
||||
<h1 className="text-2xl font-bold">Future Work</h1>
|
||||
<p className="my-4">
|
||||
We have curves, cuts, and many more CAD features coming soon. We want
|
||||
@ -32,10 +33,10 @@ export default function FutureWork() {
|
||||
</p>
|
||||
<p className="my-4">
|
||||
If you make anything with the app we'd love to see it! Thank you for
|
||||
taking time to try out KittyCAD Modeling App, and build the future of
|
||||
hardware design with us 💚.
|
||||
taking time to try out {APP_NAME}, and build the future of hardware
|
||||
design with us.
|
||||
</p>
|
||||
<p className="my-4">— The KittyCAD Team</p>
|
||||
<p className="my-4">💚 The Zoo Team</p>
|
||||
<OnboardingButtons
|
||||
className="mt-6"
|
||||
dismiss={dismiss}
|
||||
|
@ -17,12 +17,12 @@ export default function InteractiveNumbers() {
|
||||
></div>
|
||||
<div
|
||||
className={
|
||||
'z-10 max-w-xl h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1 overflow-y-auto mb-6">
|
||||
<h2 className="text-2xl">Interactive Numbers</h2>
|
||||
<h2 className="text-2xl font-bold">Interactive Numbers</h2>
|
||||
<p className="my-4">
|
||||
Let's do a little bit of hybrid editing to this part.
|
||||
</p>
|
||||
|
@ -21,6 +21,7 @@ import { paths } from 'Router'
|
||||
import { useEffect } from 'react'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
import { sep } from '@tauri-apps/api/path'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
|
||||
function OnboardingWithNewFile() {
|
||||
const navigate = useNavigate()
|
||||
@ -129,8 +130,8 @@ export default function Introduction() {
|
||||
<div className="max-w-3xl p-8 rounded bg-chalkboard-10 dark:bg-chalkboard-90">
|
||||
<h1 className="flex flex-wrap items-center gap-4 text-2xl font-bold">
|
||||
<img
|
||||
src={`/kcma-logomark${getLogoTheme()}.svg`}
|
||||
alt="KittyCAD Modeling App"
|
||||
src={`/zma-logomark${getLogoTheme()}.svg`}
|
||||
alt={APP_NAME}
|
||||
className="h-20 max-w-full"
|
||||
/>
|
||||
<span className="px-3 py-1 text-base rounded-full bg-energy-10 text-energy-80">
|
||||
@ -139,11 +140,11 @@ export default function Introduction() {
|
||||
</h1>
|
||||
<section className="my-12">
|
||||
<p className="my-4">
|
||||
Welcome to KittyCAD Modeling App! This is a hardware design tool
|
||||
that lets you edit visually, with code, or both. It's powered by the
|
||||
first API created for anyone to build hardware design tools. The 3D
|
||||
view is not running on your computer, but is instead being streamed
|
||||
to you from a remote GPU as video.
|
||||
Welcome to {APP_NAME}! This is a hardware design tool that lets you
|
||||
edit visually, with code, or both. It's powered by the first API
|
||||
created for anyone to build hardware design tools. The 3D view is
|
||||
not running on your computer, but is instead being streamed to you
|
||||
from a remote GPU as video.
|
||||
</p>
|
||||
<p className="my-4">
|
||||
This is an alpha release, so you will encounter bugs and missing
|
||||
|
@ -29,12 +29,14 @@ export default function ParametricModeling() {
|
||||
></div>
|
||||
<div
|
||||
className={
|
||||
'z-10 max-w-xl h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1 overflow-y-auto mb-6">
|
||||
<h2 className="text-2xl">Towards true parametric modeling</h2>
|
||||
<h2 className="text-2xl font-bold">
|
||||
Towards true parametric modeling
|
||||
</h2>
|
||||
<p className="my-4">
|
||||
This example script shows how having access to the code
|
||||
representation of a part can allow us to do things that are tedious
|
||||
|
@ -13,17 +13,17 @@ export default function ProjectMenu() {
|
||||
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-xl flex flex-col border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl">Project Menu</h2>
|
||||
<h2 className="text-2xl font-bold">Project Menu</h2>
|
||||
<p className="my-4">
|
||||
Click on Kitt in the upper left to open the project menu. You can
|
||||
only {isTauri() && 'go home or '}export your model—which we'll talk
|
||||
about next—for now. We'll add more options here soon, especially as
|
||||
we add support for multi-file assemblies.
|
||||
Click on the Zoo logo in the upper left to open the project menu.
|
||||
You can only {isTauri() && 'go home or '}export your model—which
|
||||
we'll talk about next—for now. We'll add more options here soon,
|
||||
especially as we add support for multi-file assemblies.
|
||||
</p>
|
||||
</section>
|
||||
<OnboardingButtons
|
||||
|
@ -22,7 +22,7 @@ export default function Sketching() {
|
||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-full xl:max-w-2xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
@ -35,7 +35,7 @@ export default function Sketching() {
|
||||
</p>
|
||||
<p className="my-4">
|
||||
Watch the code pane as you click. Point-and-click interactions are
|
||||
always just modifying and generating code in KittyCAD Modeling App.
|
||||
always just modifying and generating code in Zoo Modeling App.
|
||||
</p>
|
||||
<OnboardingButtons
|
||||
className="mt-6"
|
||||
|
@ -12,28 +12,28 @@ export default function Streaming() {
|
||||
<div className="fixed grid justify-start items-center inset-0 z-50 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-xl h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-3/4 flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl">Streaming Video</h2>
|
||||
<h2 className="text-2xl font-bold">Streaming Video</h2>
|
||||
<p className="my-4">
|
||||
The 3D view is not running on your computer. Instead, our
|
||||
infrastructure spins up the KittyCAD Geometry Engine on a remote
|
||||
GPU, KittyCAD Modeling App sends it a series of commands via
|
||||
Websockets and WebRTC, and the Geometry Engine sends back a video
|
||||
stream of the 3D view.
|
||||
infrastructure spins up our Geometry Engine on a remote GPU,
|
||||
Modeling App sends it a series of commands via Websockets and
|
||||
WebRTC, and the Geometry Engine sends back a video stream of the 3D
|
||||
view.
|
||||
</p>
|
||||
<p className="my-4">
|
||||
This means that you could run KittyCAD Modeling App on a Chromebook,
|
||||
a tablet, or even a phone, as long as you have a good internet
|
||||
This means that you could run our Modeling App on a Chromebook, a
|
||||
tablet, or even a phone, as long as you have a good internet
|
||||
connection.
|
||||
</p>
|
||||
<p className="my-4">
|
||||
It also means that whatever tools you build on top of the KittyCAD
|
||||
Geometry Engine will be able to run on any device with a browser,
|
||||
and you won't have to worry about the performance of the device.
|
||||
It also means that whatever tools you build on top of our Geometry
|
||||
Engine will be able to run on any device with a browser, and you
|
||||
won't have to worry about the performance of the device.
|
||||
</p>
|
||||
</section>
|
||||
<OnboardingButtons
|
||||
|
@ -12,12 +12,12 @@ export default function UserMenu() {
|
||||
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
'max-w-xl flex flex-col border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
||||
}
|
||||
>
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl">User Menu</h2>
|
||||
<h2 className="text-2xl font-bold">User Menu</h2>
|
||||
<p className="my-4">
|
||||
Click your avatar on the upper right to open the user menu. You can
|
||||
change your settings, sign out, or request a feature.
|
||||
|
@ -113,6 +113,7 @@ export const Settings = () => {
|
||||
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
|
||||
}}
|
||||
className="hover:border-destroy-40"
|
||||
data-testid="close-button"
|
||||
>
|
||||
Close
|
||||
</ActionButton>
|
||||
@ -178,6 +179,7 @@ export const Settings = () => {
|
||||
className="flex-1 px-2 bg-transparent"
|
||||
value={defaultDirectory}
|
||||
disabled
|
||||
data-testid="default-directory-input"
|
||||
/>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
@ -209,6 +211,7 @@ export const Settings = () => {
|
||||
}}
|
||||
autoCapitalize="off"
|
||||
autoComplete="off"
|
||||
data-testid="name-input"
|
||||
/>
|
||||
</SettingsSection>
|
||||
</>
|
||||
@ -326,7 +329,7 @@ export function SettingsSection({
|
||||
}
|
||||
>
|
||||
<div className="w-80">
|
||||
<h2 className="text-2xl">{title}</h2>
|
||||
<h2 className="text-2xl font-bold">{title}</h2>
|
||||
<p className="mt-2 text-sm">{description}</p>
|
||||
</div>
|
||||
<div>{children}</div>
|
||||
|
@ -5,8 +5,14 @@ import { VITE_KC_SITE_BASE_URL, VITE_KC_API_BASE_URL } from '../env'
|
||||
import { Themes, getSystemTheme } from '../lib/theme'
|
||||
import { paths } from '../Router'
|
||||
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
|
||||
const SignIn = () => {
|
||||
const getLogoTheme = () =>
|
||||
theme === Themes.Light ||
|
||||
(theme === Themes.System && getSystemTheme() === Themes.Light)
|
||||
? '-dark'
|
||||
: ''
|
||||
const {
|
||||
auth: { send },
|
||||
settings: {
|
||||
@ -34,31 +40,26 @@ const SignIn = () => {
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div>
|
||||
<img
|
||||
src={`/kittycad-logomark${
|
||||
appliedTheme === Themes.Dark ? '-light' : ''
|
||||
}.svg`}
|
||||
alt="KittyCAD"
|
||||
src={`/zma-logomark${getLogoTheme()}.svg`}
|
||||
alt="Zoo Modeling App"
|
||||
className="w-48 inline-block"
|
||||
/>
|
||||
<span className="text-3xl leading-none w-auto inline-block align-middle ml-2">
|
||||
Modeling App
|
||||
</span>
|
||||
</div>
|
||||
<h1 className="font-bold text-2xl mt-12 mb-6">
|
||||
Sign in to get started with the KittyCAD Modeling App
|
||||
Sign in to get started with the {APP_NAME}
|
||||
</h1>
|
||||
<p className="py-4">
|
||||
KCMA is an open-source CAD application for creating accurate 3D models
|
||||
for use in manufacturing. It is built on top of the KittyCAD API.
|
||||
KittyCAD is the first software infrastructure company built
|
||||
specifically for the needs of the manufacturing industry. With KCMA we
|
||||
are showing how the KittyCAD API can be used to build entirely new
|
||||
kinds of software for manufacturing.
|
||||
ZMA is an open-source CAD application for creating accurate 3D models
|
||||
for use in manufacturing. It is built on top of KittyCAD, the design
|
||||
API from Zoo. Zoo is the first software infrastructure company built
|
||||
specifically for the needs of the manufacturing industry. With ZMA we
|
||||
are showing how the KittyCAD API from Zoo can be used to build
|
||||
entirely new kinds of software for manufacturing.
|
||||
</p>
|
||||
<p className="py-4">
|
||||
KCMA is currently in development. If you would like to be notified
|
||||
when KCMA is ready for production, please sign up for our mailing list
|
||||
at <a href="https://kittycad.io">kittycad.io</a>.
|
||||
ZMA is currently in development. If you would like to be notified when
|
||||
ZMA is ready for production, please sign up for our mailing list at{' '}
|
||||
<a href="https://zoo.dev">zoo.dev</a>.
|
||||
</p>
|
||||
{isTauri() ? (
|
||||
<ActionButton
|
||||
|