Compare commits
157 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a79f40a711 | |||
| 03d0342469 | |||
| 13d62705f3 | |||
| 7fad8dbec0 | |||
| 83ac98ac76 | |||
| 42ec27cfe4 | |||
| ca75f86947 | |||
| 7a6c884418 | |||
| a6ef3ee4d2 | |||
| 153af8da22 | |||
| 392f4ed396 | |||
| 0e4c5ae577 | |||
| d2f0627421 | |||
| e0e2c566e7 | |||
| ebdc0bc07e | |||
| d1398e2c52 | |||
| 5bdb11bd56 | |||
| 69e45b88e7 | |||
| 5869f4c247 | |||
| 98abb249c4 | |||
| 7b03439dda | |||
| 74d1db902e | |||
| 882737ff94 | |||
| 295d04932f | |||
| 0d18757ed7 | |||
| 9030d2ff19 | |||
| 38820658fa | |||
| c8c5c882de | |||
| 5dc95ef7f6 | |||
| e2d409e6ed | |||
| 3179cd2ebd | |||
| d139e415e4 | |||
| d14dbe5e39 | |||
| 143145751c | |||
| 98658142c0 | |||
| ee6ec09b0a | |||
| 0accea759d | |||
| 8962ae10e7 | |||
| 28b27aac8f | |||
| 5a477b7774 | |||
| 236b5c9ebf | |||
| 95ff76cb97 | |||
| d245541075 | |||
| 9a7b657fdc | |||
| d0c594d311 | |||
| 4515af3eb9 | |||
| c5fbf6650c | |||
| 1aaa2cdc2a | |||
| 98b57a3588 | |||
| 35913ced46 | |||
| 02981d6bcf | |||
| 96b3ebba54 | |||
| 5bd8387cf7 | |||
| ec877315c3 | |||
| 98d021c523 | |||
| 04e4e72ea1 | |||
| 2151bc0497 | |||
| 1a9c4cd99d | |||
| b1cf66b628 | |||
| 285fa9433b | |||
| f5bfd6d1f2 | |||
| 48c8965853 | |||
| e7e8a1ef26 | |||
| ae530bff44 | |||
| 3574956d29 | |||
| 27728b10e2 | |||
| 1c109be836 | |||
| 388266ca37 | |||
| 2346c1ae81 | |||
| 8372c476ab | |||
| 4ad285570c | |||
| 4766aea8d7 | |||
| ad749d3399 | |||
| 0f8593b180 | |||
| f8d2d90a16 | |||
| 69a46fb6a3 | |||
| b2f69ab314 | |||
| 7e8ccad341 | |||
| d28874bec1 | |||
| 95515ed2bf | |||
| 46552bdc3a | |||
| ae3d4faf53 | |||
| 05eb283242 | |||
| 6b7f1934b1 | |||
| f9c8abb329 | |||
| 53cba0cf51 | |||
| d95646378b | |||
| 75c8700724 | |||
| fac811565b | |||
| fb7ca86dc7 | |||
| 9b84789da0 | |||
| 9d01dcb358 | |||
| 0b0886b87c | |||
| 6081226fa6 | |||
| 329ef29f24 | |||
| f82e517bcb | |||
| e8302b5757 | |||
| 98762fd20b | |||
| e0809b427c | |||
| 17339cf65c | |||
| b5728f284b | |||
| dc32cff620 | |||
| 22ede1bde3 | |||
| 7895c14e3f | |||
| d9ccba0134 | |||
| 531fc04db8 | |||
| 4907429439 | |||
| 192ef78ff3 | |||
| 44a0be8d94 | |||
| 9cba66c14d | |||
| 4afd93331f | |||
| 698621dfdf | |||
| 5fc23436ca | |||
| 76879f8b39 | |||
| 514b0c84f9 | |||
| ddca1054ab | |||
| 783ee91404 | |||
| 38dedcca3b | |||
| 99cca6a11a | |||
| af07f4e0e5 | |||
| 0c16cfefbb | |||
| b2189e3f4d | |||
| 6e12f5954f | |||
| 3ad5a360f2 | |||
| 6848c78424 | |||
| b47f82d406 | |||
| 614e006eac | |||
| 4e07b6c4b7 | |||
| efa2cae0b4 | |||
| 78d80e0144 | |||
| 13f650b695 | |||
| a7c1909766 | |||
| 702f35ae6e | |||
| 2d629069c6 | |||
| 4b327bab1f | |||
| 237341423c | |||
| b99761a3f7 | |||
| 3726959d82 | |||
| af1d15b5ea | |||
| 84a3a0c478 | |||
| 1551c0acef | |||
| f1cc49bcdb | |||
| 622a392a83 | |||
| 5622963b91 | |||
| 3bea744823 | |||
| e8eb7ee11a | |||
| ebb6cc53ab | |||
| 924724dc89 | |||
| 56bcd872cb | |||
| 6c0fca30a7 | |||
| ef1d02f274 | |||
| 367aa249bc | |||
| afd6a5c584 | |||
| 65366ba131 | |||
| f077f48318 | |||
| bd44f6f496 | |||
| 3918f23c3d |
@@ -9,9 +9,10 @@ parameter to watch the timeline rebuild. [Documentation](https://docs.solidcraft
|
||||
[ROADMAP](https://github.com/bherbruck/solidcraft/blob/main/ROADMAP.md#known-limitations) lists
|
||||
the known limitations. Designs from every earlier version open in this one.
|
||||
|
||||
**Upgrading from 0.7 or earlier.** 0.8 changed the Linux app ID to `ai.storyteller.solidcraft`:
|
||||
`flatpak update` offers to replace the old app, and the `.deb`, `.rpm` and AppImage remove the old
|
||||
menu entry.
|
||||
**New app ID.** The app ID is now `io.tangencylabs.solidcraft` (it was `ai.storyteller.solidcraft`,
|
||||
and `ai.storyteller.solvecraft` up to 0.7): `flatpak update` offers to replace the old app, the
|
||||
`.deb`, `.rpm` and AppImage remove the old menu entry, and settings stay. On macOS the bundle ID
|
||||
changed too, so macOS asks once more for the permissions it had granted.
|
||||
|
||||
**Upgrading from 0.5 or earlier.** 0.6 renamed SolveCraft to SolidCraft and made the zip
|
||||
container the default save format. `.solvecraft` designs, old settings folders and
|
||||
@@ -42,16 +43,16 @@ installing SolidCraft; keep both remotes in the same user installation:
|
||||
```sh
|
||||
flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --user --if-not-exists solidcraft https://docs.solidcraft.io/flatpak/solidcraft.flatpakrepo
|
||||
flatpak install --user solidcraft ai.storyteller.solidcraft
|
||||
flatpak run ai.storyteller.solidcraft
|
||||
flatpak install --user solidcraft io.tangencylabs.solidcraft
|
||||
flatpak run io.tangencylabs.solidcraft
|
||||
```
|
||||
|
||||
A remote added from the old `bherbruck.github.io` address no longer finds updates: run
|
||||
`flatpak remote-modify --user --url=https://docs.solidcraft.io/flatpak/repo/ solidcraft`, then
|
||||
`flatpak update --user`.
|
||||
|
||||
Flatpak installs from 0.7 or earlier use the old ID `ai.storyteller.solvecraft`: `flatpak update --user`
|
||||
offers to replace it with `ai.storyteller.solidcraft`, and settings move along.
|
||||
Flatpak installs under an old ID (`ai.storyteller.solidcraft`, or `ai.storyteller.solvecraft` from 0.7 or
|
||||
earlier): `flatpak update --user` offers to replace it with `io.tangencylabs.solidcraft`, and settings move along.
|
||||
|
||||
Single-file `.flatpak` bundles include the runtime repository address; missing runtimes
|
||||
still need an internet connection. [Linux installation details](https://docs.solidcraft.io/guide/getting-started.html#linux-flatpak).
|
||||
|
||||
@@ -98,15 +98,16 @@ jobs:
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
permissions:
|
||||
contents: read
|
||||
# To ask whether the merge queue already tested a commit pushed to main.
|
||||
# To ask whether the merge queue already tested a commit pushed to main, and which labels the
|
||||
# pull requests of a merge group carry (the render-tests opt-in).
|
||||
pull-requests: read
|
||||
actions: read
|
||||
outputs:
|
||||
native: ${{ steps.paths.outputs.native }}
|
||||
kernel: ${{ steps.paths.outputs.kernel }}
|
||||
goldens: ${{ steps.paths.outputs.goldens }}
|
||||
windows: ${{ steps.paths.outputs.windows }}
|
||||
# The GPU path tests run: native, and the whole workspace or solidcraft-gpu selected. The
|
||||
# job's `if` and the `ci` job's check both read this, so they cannot disagree.
|
||||
# The GPU path tests run (see the rule where it is computed). The job's `if` and the `ci` job's check both read this, so they cannot disagree.
|
||||
gpu: ${{ steps.paths.outputs.gpu }}
|
||||
full: ${{ steps.paths.outputs.full }}
|
||||
# Code changed on a pull request that has no approved-for-ci label yet: only Quick compile.
|
||||
@@ -131,6 +132,7 @@ jobs:
|
||||
GROUP_HEAD_SHA: ${{ github.event.merge_group.head_sha }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
RENDER_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'render-tests') }}
|
||||
HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
||||
REPO: ${{ github.repository }}
|
||||
APPROVED: ${{ contains(github.event.pull_request.labels.*.name, 'approved-for-ci') }}
|
||||
@@ -140,6 +142,7 @@ jobs:
|
||||
kernel=false
|
||||
goldens=false
|
||||
windows=false
|
||||
gpu_paths=false
|
||||
full=true
|
||||
packages=
|
||||
# Whether the NUL-separated paths in $1 reach any code: scripts/ci/affected.py selects
|
||||
@@ -168,6 +171,29 @@ jobs:
|
||||
windows=true
|
||||
fi
|
||||
}
|
||||
# Whether the NUL-separated paths in $1 are render code: the render crate, the path
|
||||
# tracer and its shaders in the GPU crate, the render workspace UI, the render assets.
|
||||
# Core, kernel and CI changes do not trigger the path tests (about 56 runner-minutes):
|
||||
# the tracer reads the scene through interfaces the other tests cover, and the nightly
|
||||
# runs them for everything.
|
||||
gpu_paths() {
|
||||
while IFS= read -r -d '' path; do
|
||||
case "$path" in
|
||||
crates/render/*|crates/gpu/src/path/*|crates/ui-egui/src/render_workspace*|assets/render/*) gpu_paths=true ;;
|
||||
esac
|
||||
done < "$1"
|
||||
}
|
||||
# Opt-in for a big render change: a pull request labelled render-tests, or a merge group
|
||||
# holding one (its pull requests are the (#N) of its squash commits), runs them whatever
|
||||
# the paths say.
|
||||
group_has_render_label() {
|
||||
for pr in $(git log --format=%s "$1" | grep -o '(#[0-9]*)$' | tr -d '(#)'); do
|
||||
if gh api "repos/$REPO/issues/$pr" --jq '.labels[].name' | grep -qx render-tests; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
if [ "$EVENT_NAME" = push ]; then
|
||||
# The queue lands the very commit its merge_group run tested. If that run passed,
|
||||
# testing the push again proves nothing new; otherwise (a merge that skipped the
|
||||
@@ -201,14 +227,20 @@ jobs:
|
||||
# the nightly runs it whatever changed. A group that can't be compared runs it.
|
||||
if git diff --no-renames --name-only -z "$GROUP_BASE_SHA...$GROUP_HEAD_SHA" > "$RUNNER_TEMP/ci-paths"; then
|
||||
windows_paths "$RUNNER_TEMP/ci-paths" "$GROUP_BASE_SHA...$GROUP_HEAD_SHA"
|
||||
gpu_paths "$RUNNER_TEMP/ci-paths"
|
||||
if [ "$gpu_paths" = false ] && group_has_render_label "$GROUP_BASE_SHA..$GROUP_HEAD_SHA"; then
|
||||
gpu_paths=true
|
||||
fi
|
||||
else
|
||||
windows=true
|
||||
gpu_paths=true
|
||||
fi
|
||||
echo "windows=$windows for $GROUP_BASE_SHA...$GROUP_HEAD_SHA"
|
||||
echo "windows=$windows gpu_paths=$gpu_paths for $GROUP_BASE_SHA...$GROUP_HEAD_SHA"
|
||||
elif [ "$EVENT_NAME" != pull_request ]; then
|
||||
# The nightly run and Run workflow: everything, Windows included.
|
||||
native=true
|
||||
windows=true
|
||||
gpu_paths=true
|
||||
else
|
||||
# Compare both old and new paths of renames; unknown paths run native checks.
|
||||
git diff --no-renames --name-only -z "$BASE_SHA...$HEAD_SHA" > "$RUNNER_TEMP/ci-paths"
|
||||
@@ -268,12 +300,24 @@ jobs:
|
||||
goldens=false
|
||||
fi
|
||||
fi
|
||||
# The GPU path tests (their own job) run with the other tests, when solidcraft-gpu is
|
||||
# among the packages they test.
|
||||
# The GPU path tests (their own job, about 56 runner-minutes) are for render changes only:
|
||||
# - on a pull request, when it carries the render-tests label (opt-in for a big render
|
||||
# change) or touches render code (gpu_paths); no other pull request runs them;
|
||||
# - in the merge queue, when the group's diff touches render code or one of its pull
|
||||
# requests carries render-tests;
|
||||
# - in the nightly and by hand, always, so anything the above skipped is caught within a day;
|
||||
# - not on a push to main: the queue tested that commit, or the nightly will.
|
||||
gpu=false
|
||||
if [ "$native" = true ]; then
|
||||
case " $packages " in *" solidcraft-gpu "*) gpu=true ;; esac
|
||||
if [ "$full" = true ]; then gpu=true; fi
|
||||
case "$EVENT_NAME" in
|
||||
pull_request)
|
||||
gpu_paths "$RUNNER_TEMP/ci-paths"
|
||||
gpu=$gpu_paths
|
||||
if [ "$RENDER_LABEL" = true ]; then gpu=true; fi ;;
|
||||
merge_group) gpu=$gpu_paths ;;
|
||||
push) gpu=false ;;
|
||||
*) gpu=true ;;
|
||||
esac
|
||||
fi
|
||||
{
|
||||
echo "native=$native"
|
||||
|
||||
@@ -55,13 +55,15 @@ jobs:
|
||||
- name: XML, desktop entry, AppStream, Flatpak manifest
|
||||
run: |
|
||||
xmllint --noout assets/platforms/windows/solidcraft.wxs assets/platforms/windows/solidcraft.en-us.wxl assets/platforms/macos/*.plist* assets/platforms/linux/*.xml*
|
||||
desktop-file-validate assets/platforms/linux/ai.storyteller.solidcraft.desktop
|
||||
# The window's X11 class is its app id; the old id stays only as the rename shims.
|
||||
grep -qx 'StartupWMClass=ai.storyteller.solidcraft' assets/platforms/linux/ai.storyteller.solidcraft.desktop
|
||||
grep -q '<id>ai.storyteller.solvecraft</id>' assets/platforms/linux/ai.storyteller.solidcraft.metainfo.xml.in
|
||||
desktop-file-validate assets/platforms/linux/io.tangencylabs.solidcraft.desktop
|
||||
# The window's X11 class is its app id; the old ids stay only as the rename shims.
|
||||
grep -qx 'StartupWMClass=io.tangencylabs.solidcraft' assets/platforms/linux/io.tangencylabs.solidcraft.desktop
|
||||
grep -q '<id>ai.storyteller.solidcraft</id>' assets/platforms/linux/io.tangencylabs.solidcraft.metainfo.xml.in
|
||||
grep -q '<id>ai.storyteller.solvecraft</id>' assets/platforms/linux/io.tangencylabs.solidcraft.metainfo.xml.in
|
||||
grep -qx 'X-Flatpak-RenamedFrom=ai.storyteller.solidcraft.desktop;ai.storyteller.solvecraft.desktop;' assets/platforms/linux/io.tangencylabs.solidcraft.desktop
|
||||
grep -qF -e '--end-of-life-rebase=' packaging/flatpak-site.sh
|
||||
sed -e 's/@VERSION@/0.0.0/' -e 's/@DATE@/2026-01-01/' assets/platforms/linux/ai.storyteller.solidcraft.metainfo.xml.in >"$RUNNER_TEMP/ai.storyteller.solidcraft.metainfo.xml"
|
||||
appstreamcli validate --no-net --explain "$RUNNER_TEMP/ai.storyteller.solidcraft.metainfo.xml"
|
||||
python3 -c "import yaml; m = yaml.safe_load(open('packaging/linux/flatpak/ai.storyteller.solidcraft.bundle.yml')); assert m['id'] == 'ai.storyteller.solidcraft' and m['command'] == 'solidcraft'"
|
||||
sed -e 's/@VERSION@/0.0.0/' -e 's/@DATE@/2026-01-01/' assets/platforms/linux/io.tangencylabs.solidcraft.metainfo.xml.in >"$RUNNER_TEMP/io.tangencylabs.solidcraft.metainfo.xml"
|
||||
appstreamcli validate --no-net --explain "$RUNNER_TEMP/io.tangencylabs.solidcraft.metainfo.xml"
|
||||
python3 -c "import yaml; m = yaml.safe_load(open('packaging/linux/flatpak/io.tangencylabs.solidcraft.bundle.yml')); assert m['id'] == 'io.tangencylabs.solidcraft' and m['command'] == 'solidcraft'"
|
||||
python3 -c "import yaml; m = yaml.safe_load(open('packaging/linux/snap/snapcraft.yaml')); assert m['name'] == 'solidcraft' and m['confinement'] == 'strict' and m['apps']['solidcraft']['command'] == 'usr/bin/solidcraft'"
|
||||
python3 -m py_compile packaging/linux/snap-smoke.py
|
||||
|
||||
@@ -297,7 +297,7 @@ jobs:
|
||||
export CARGO_TARGET_DIR=/var/tmp/solidcraft-target CARGO_BUILD_JOBS=4
|
||||
bash packaging/freebsd/package.sh
|
||||
tar -tzf dist/release/solidcraft-*-freebsd-x86_64.tar.gz \
|
||||
| grep -E '/bin/solidcraft$|/bin/solidcraft-cli$|/share/applications/ai\.storyteller\.solvecraft\.desktop$|/share/doc/solidcraft/THIRD-PARTY-LICENSES\.txt$'
|
||||
| grep -E '/bin/solidcraft$|/bin/solidcraft-cli$|/share/applications/io\.tangencylabs\.solidcraft\.desktop$|/share/doc/solidcraft/THIRD-PARTY-LICENSES\.txt$'
|
||||
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: release-freebsd-x86_64
|
||||
|
||||
@@ -45,4 +45,3 @@ Work: ROADMAP.md, "Where help is wanted most" in CONTRIBUTING.md, issues labelle
|
||||
| A bug report, a crash, a wrong result | `skills/solidcraft-reporting/SKILL.md` |
|
||||
| Checking, porting, designs in git | `skills/solidcraft-checking/SKILL.md` |
|
||||
| Assemblies, joints, motion | `skills/solidcraft-mechanisms/SKILL.md` |
|
||||
>>>>>>> 4a3e0772a (Agents: AGENTS.md becomes a router to focused skills, with a staleness check (Refs #6439))
|
||||
|
||||
@@ -128,14 +128,14 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| assets/fonts/ibm-plex-mono/OFL.txt | IBM Corp. | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
| assets/fonts/ibm-plex-sans/OFL.txt | IBM Corp. | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
| assets/fonts/liberation-sans/OFL.txt | Red Hat, Inc.; Liberation Fonts contributors | Unmodified accompanying font licence | SIL OFL 1.1 |
|
||||
| assets/icons/app/linux/exports/hicolor/128x128/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/16x16/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/24x24/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/256x256/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/32x32/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/48x48/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/512x512/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/64x64/apps/ai.storyteller.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/128x128/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/16x16/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/24x24/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/256x256/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/32x32/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/48x48/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/512x512/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/linux/exports/hicolor/64x64/apps/io.tangencylabs.solidcraft.png | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/shared/source/app_icon.rs | SolidCraft contributors | Original SolidCraft drawing code: the borderless mark, drawn from the faces and gradients of assets/icons/app/macos/source/SolidCraft.icon/Assets/03-solid-blue-cutout.svg | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/shared/source/windows_ico.rs | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| assets/icons/app/windows/exports/solidcraft-executable.ico | SolidCraft contributors | Generated from assets/icons/app/shared/source/app_icon.rs with the original CLI/ICO encoders | MIT OR Apache-2.0 |
|
||||
@@ -171,9 +171,9 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| assets/locales/zh.json | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| assets/locales/zh-TW.json | SolidCraft contributors | Original Traditional Chinese (Taiwan) translation of SolidCraft's English catalog; no commercial CAD text used | MIT OR Apache-2.0 |
|
||||
| assets/materials/library.rs | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| assets/platforms/linux/ai.storyteller.solidcraft.desktop | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/platforms/linux/ai.storyteller.solidcraft.metainfo.xml.in | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/platforms/linux/ai.storyteller.solidcraft.mime.xml | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/platforms/linux/io.tangencylabs.solidcraft.desktop | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/platforms/linux/io.tangencylabs.solidcraft.metainfo.xml.in | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/platforms/linux/io.tangencylabs.solidcraft.mime.xml | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/platforms/macos/dmg/background.tiff | SolidCraft contributors | original disk image window background (blueprint sheet: grid, double border, circles, centre lines, leader arrow, title block) drawn by assets/platforms/macos/dmg/make_background.py in IBM Plex Sans/Mono; 1x and 2x representations | MIT OR Apache-2.0 |
|
||||
| assets/platforms/macos/dmg/make_background.py | SolidCraft contributors | authoring script that draws the disk image background (Pillow); not part of any build | MIT OR Apache-2.0 |
|
||||
| assets/platforms/macos/dmg/layout.json | SolidCraft contributors | disk image window size, icon size and icon positions shared by the background script and settings.py | MIT OR Apache-2.0 |
|
||||
@@ -292,6 +292,53 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| assets/icons/ui/design/svg/model/colored_components_off.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/combine.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/component.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
|
||||
### Render workspace icon drafts
|
||||
|
||||
Original SolidCraft drawings, Open for owner review; no runtime assignments.
|
||||
|
||||
| File | Author | Source | Licence |
|
||||
|---|---|---|---|
|
||||
| assets/icons/ui/design/svg/model/render_all_shots.svg | SolidCraft contributors | original Camera icon master (64 grid): stacked camera bodies with a lower-right play badge | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_appearance.svg | SolidCraft contributors | original Looks icon master (64 grid): shaded look sphere on the top corner of an accent-shaded cube | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_aspect_frame.svg | SolidCraft contributors | original Camera icon master (64 grid): wide rounded frame with two opposite corner brackets | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_backdrop.svg | SolidCraft contributors | original Studio icon master (64 grid): grey cube in front of a tall upright accent panel | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_cancel.svg | SolidCraft contributors | original Output icon master (64 grid): picture with a lower-right round stop badge | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_check.svg | SolidCraft contributors | original Output icon master (64 grid): picture with a lower-right round check badge | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_compare.svg | SolidCraft contributors | original Output icon master (64 grid): two grey pictures split by a vertical slider with opposed arrows | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_copy_look.svg | SolidCraft contributors | original Looks icon master (64 grid): look sphere in a square frame offset from a second frame outline | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_execute.svg | SolidCraft contributors | original Output icon master (64 grid): picture with a lower-right round play badge | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_export_image.svg | SolidCraft contributors | original Output icon master (64 grid): picture with a large outward diagonal arrow at the upper right | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_exposure.svg | SolidCraft contributors | original Camera icon master (64 grid): split light and accent disc with plus and minus marks | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_fit_product.svg | SolidCraft contributors | original Camera icon master (64 grid): grey cube inside four corner brackets | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_frame_guides.svg | SolidCraft contributors | original Camera icon master (64 grid): rounded frame with a rule-of-thirds grid and four accent nodes | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_from_material.svg | SolidCraft contributors | original Looks icon master (64 grid): look sphere struck through above a plain grey slab | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_ground.svg | SolidCraft contributors | original Studio icon master (64 grid): grey cube on a slab with an accent contact patch | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_lens.svg | SolidCraft contributors | original Camera icon master (64 grid): concentric lens rings around an accent centre | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_library.svg | SolidCraft contributors | original Studio icon master (64 grid): row of three look spheres, middle one accent, on a shelf bar | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_light_area.svg | SolidCraft contributors | original Lights icon master (64 grid): slanted flat panel above a dotted accent stem | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_light_by_highlight.svg | SolidCraft contributors | original Lights icon master (64 grid): shaded sphere with a ringed highlight target and dotted stem arriving from above | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_light_point.svg | SolidCraft contributors | original Lights icon master (64 grid): round source disc with centre dot above a dotted accent stem | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_light_spot.svg | SolidCraft contributors | original Lights icon master (64 grid): cone source with curved rim above a dotted accent stem | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_lighting_presets.svg | SolidCraft contributors | original Studio icon master (64 grid): two stacked cards, the front one holding a light bulb | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_output_size.svg | SolidCraft contributors | original Output icon master (64 grid): picture frame with a diagonal double-headed dimension arrow | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_paint.svg | SolidCraft contributors | original Looks icon master (64 grid): flat brush with an accent tip, light ferrule and slate handle | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_pick_up.svg | SolidCraft contributors | original Looks icon master (64 grid): eyedropper with a grey bulb, slate crossbar and accent sampling tip | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_quality.svg | SolidCraft contributors | original Output icon master (64 grid): three rising bars, the tallest in accent | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_replace_all.svg | SolidCraft contributors | original Looks icon master (64 grid): grey sample sphere with an arrow to an accent sphere beside a second one | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_results.svg | SolidCraft contributors | original Output icon master (64 grid): stack of two pictures, the front one showing a landscape | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_same_look.svg | SolidCraft contributors | original Looks icon master (64 grid): look sphere and three cubes, the two matching cubes ringed | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_shot.svg | SolidCraft contributors | original Camera icon master (64 grid): camera body with a lower-right plus badge | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_shots_strip.svg | SolidCraft contributors | original Camera icon master (64 grid): strip of three small frames, the middle one in accent | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_solo_light.svg | SolidCraft contributors | original Lights icon master (64 grid): point source and dotted stem inside four corner focus brackets | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_sun.svg | SolidCraft contributors | original Lights icon master (64 grid): source disc with eight short radial rays | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_transparent_background.svg | SolidCraft contributors | original Output icon master (64 grid): grey cube on a checker tile | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_update_shot.svg | SolidCraft contributors | original Camera icon master (64 grid): camera body with a lower-right refresh badge | MIT OR Apache-2.0 |
|
||||
|
||||
### UI icon masters (continued)
|
||||
|
||||
| File | Author | Source | Licence |
|
||||
|---|---|---|---|
|
||||
| assets/icons/ui/design/svg/model/compute.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/configuration_table.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/conic.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
@@ -381,6 +428,7 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| assets/icons/ui/design/svg/flat/shield.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/status_recovery.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/frame_member.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/render_environment.svg | SolidCraft contributors | original Studio icon master (64 grid): dome with a grey cube inside | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/placeholder.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/plane.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/plane_angle.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
|
||||
@@ -527,6 +575,12 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| docs/book/scripts/hem.json | SolidCraft contributors | original parametric recipe for an 80 × 50 mm sheet with an 8 mm returned edge, authored for the command guide | MIT OR Apache-2.0 |
|
||||
| assets/styles/ui/themes/clay.json | SolidCraft contributors | original SolidCraft theme file (Clay, light): warm paper palette chosen for SolidCraft | MIT OR Apache-2.0 |
|
||||
| assets/styles/ui/themes/clay-dark.json | SolidCraft contributors | original SolidCraft theme file (Clay Dark): warm charcoal palette chosen for SolidCraft | MIT OR Apache-2.0 |
|
||||
| assets/icons/ui/design/svg/model/cone.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
|
||||
| assets/locales/ar.json | Abdullah (A-AL-ANAZI) | Original Arabic translation of SolidCraft's English catalog; no commercial CAD text used | MIT OR Apache-2.0 |
|
||||
| assets/locales/he.json | SolidCraft contributors | Original Hebrew translation of SolidCraft's English catalog; no commercial CAD text used | MIT OR Apache-2.0 |
|
||||
| assets/styles/ui/themes/cga.json | SolidCraft contributors | original SolidCraft theme file using the 16 colours of the IBM Color Graphics Adapter (black, cyan, magenta, and white of its high-intensity palette 1 for the interface) | MIT OR Apache-2.0 |
|
||||
| assets/styles/ui/themes/1-bit.json | SolidCraft contributors | original SolidCraft theme file | MIT OR Apache-2.0 |
|
||||
| assets/styles/ui/themes/1-bit-dark.json | SolidCraft contributors | original SolidCraft theme file | MIT OR Apache-2.0 |
|
||||
|
||||
## Code adapted from sibling projects
|
||||
|
||||
|
||||
@@ -4208,7 +4208,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"block2 0.6.2",
|
||||
"eframe",
|
||||
@@ -4217,6 +4217,7 @@ dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"hidapi",
|
||||
"keyring",
|
||||
"libc",
|
||||
"log",
|
||||
"muda",
|
||||
"objc2 0.6.5",
|
||||
@@ -4228,6 +4229,7 @@ dependencies = [
|
||||
"rfd",
|
||||
"ron",
|
||||
"rustls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"solidcraft-3dx-client",
|
||||
"solidcraft-engine",
|
||||
@@ -4240,11 +4242,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-3dx-client"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-cli"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
@@ -4256,7 +4258,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-derive"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4265,7 +4267,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-doc"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -4282,8 +4284,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-engine"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -4302,7 +4305,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-geom"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4311,7 +4314,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-gpu"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"log",
|
||||
@@ -4331,7 +4334,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-io"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"cadmpeg-core",
|
||||
"cadmpeg-ir",
|
||||
@@ -4355,7 +4358,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-kernel"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"proptest",
|
||||
@@ -4375,7 +4378,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-mcp"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"solidcraft-engine",
|
||||
@@ -4384,7 +4387,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-render"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"moxcms",
|
||||
@@ -4398,7 +4401,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-sketch"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4409,14 +4412,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-space-mouse"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-ui-egui"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"egui",
|
||||
@@ -4438,6 +4441,7 @@ dependencies = [
|
||||
"tiny-skia",
|
||||
"toml",
|
||||
"ttf-parser",
|
||||
"unicode-bidi",
|
||||
"web-time",
|
||||
"winreg",
|
||||
"zip",
|
||||
@@ -4445,7 +4449,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solidcraft-web"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui",
|
||||
@@ -4947,6 +4951,12 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-general-category"
|
||||
version = "1.1.0"
|
||||
@@ -5984,7 +5994,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
|
||||
|
||||
[[package]]
|
||||
name = "xtask"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"serde",
|
||||
|
||||
@@ -5,7 +5,7 @@ members = ["crates/*", "apps/*", "xtask"]
|
||||
exclude = ["vendor"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
edition = "2024"
|
||||
license = "MIT OR Apache-2.0"
|
||||
rust-version = "1.95"
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Disclaimer
|
||||
|
||||
This disclaimer covers the software, models, data, documentation and every other file in this
|
||||
repository and in the releases built from it (together, "the files").
|
||||
|
||||
## No warranty
|
||||
|
||||
The files are provided "as is", without warranty of any kind, express or implied, including
|
||||
warranties of accuracy, merchantability, fitness for a particular purpose and non-infringement.
|
||||
Results produced with the files, such as geometry, meshes, analyses and simulations, can be
|
||||
wrong. A qualified person must check them before anyone relies on them for a design,
|
||||
manufacturing or safety decision.
|
||||
|
||||
## No liability
|
||||
|
||||
To the fullest extent permitted by law, Tangency Labs and the contributors are not liable for any
|
||||
claim, damage, loss or other liability arising from the files or from their use, modification or
|
||||
distribution, whether in contract, tort or otherwise.
|
||||
|
||||
## No indemnity
|
||||
|
||||
Neither Tangency Labs nor any contributor indemnifies, defends or holds harmless anyone who uses,
|
||||
modifies or distributes the files, including against claims that the files infringe someone
|
||||
else's rights.
|
||||
|
||||
## Harmful or unlawful use
|
||||
|
||||
Tangency Labs and the contributors do not authorise, endorse or accept any responsibility for use
|
||||
of the files to harm people, animals, property or the environment, or for any unlawful use.
|
||||
Whoever uses the files is solely responsible for how they use them, for what they make with them
|
||||
and for complying with the laws that apply to them. Tangency Labs and the contributors must not be
|
||||
named or held out as responsible for any such use.
|
||||
|
||||
## No endorsement
|
||||
|
||||
Using, modifying or distributing the files does not mean that Tangency Labs or any contributor
|
||||
endorses you, your product or your results. Do not use the name of Tangency Labs or of a
|
||||
contributor to suggest such an endorsement without written permission.
|
||||
|
||||
## Relation to the licence
|
||||
|
||||
This disclaimer adds to the warranty and liability terms of the licence the files are distributed
|
||||
under. It does not restrict any right that licence grants; where the two differ, the licence
|
||||
governs.
|
||||
@@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img src="assets/icons/app/linux/exports/hicolor/256x256/apps/ai.storyteller.solidcraft.png" width="96" height="96" alt="SolidCraft" />
|
||||
<img src="assets/icons/app/linux/exports/hicolor/256x256/apps/io.tangencylabs.solidcraft.png" width="96" height="96" alt="SolidCraft" />
|
||||
</p>
|
||||
|
||||
<h1 align="center">SolidCraft</h1>
|
||||
@@ -121,6 +121,12 @@ the clean-room and licence rules, and where help is wanted most. Open work is in
|
||||
SolidCraft's continuous integration runs on [Blacksmith](https://www.blacksmith.sh), which
|
||||
sponsors its CI minutes.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
The files in this repository are provided as is, without warranty, liability or indemnity, and
|
||||
Tangency Labs and the contributors accept no responsibility for any harmful or unlawful use of
|
||||
them: read [DISCLAIMER.md](DISCLAIMER.md).
|
||||
|
||||
## Licence
|
||||
|
||||
MIT OR Apache-2.0, at your option. Developed under the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Third-party software in SolidCraft
|
||||
|
||||
SolidCraft (the desktop app, solidcraft-cli and the web app) is built from the 559 crates below.
|
||||
SolidCraft (the desktop app, solidcraft-cli and the web app) is built from the 560 crates below.
|
||||
Generated by `cargo xtask licences` from Cargo.lock and the crates' own licence files.
|
||||
SolidCraft's own licence is in LICENSE-MIT and LICENSE-APACHE, and NOTICE.
|
||||
|
||||
@@ -439,6 +439,7 @@ typed-path 0.12.3 (MIT OR Apache-2.0)
|
||||
typeid 1.0.3 (MIT OR Apache-2.0)
|
||||
typenum 1.20.1 (MIT OR Apache-2.0)
|
||||
uds_windows 1.2.1 (MIT)
|
||||
unicode-bidi 0.3.18 (MIT OR Apache-2.0)
|
||||
unicode-general-category 1.1.0 (Apache-2.0)
|
||||
unicode-ident 1.0.26 ((MIT OR Apache-2.0) AND Unicode-3.0)
|
||||
unicode-segmentation 1.13.3 (MIT OR Apache-2.0)
|
||||
@@ -1123,9 +1124,9 @@ parking_lot_core 0.9.12, percent-encoding 2.3.2, piper 0.2.5, plain 0.2.3, png 0
|
||||
rustls-native-certs 0.8.5, scoped-tls 1.0.1, scopeguard 1.2.0, secret-service 4.0.0,
|
||||
security-framework 2.11.1, security-framework 3.7.0, security-framework-sys 2.17.0,
|
||||
signal-hook-registry 1.4.8, simd_cesu8 1.2.0, smallvec 1.16.2, smol_str 0.2.2, stable_deref_trait
|
||||
1.2.1, syn 1.0.109, tempfile 3.27.0, ttf-parser 0.25.1, unicode-segmentation 1.13.3, unicode-width
|
||||
0.2.2, url 2.5.8, uuid 1.27.0, wasi 0.11.1+wasi-snapshot-preview1, wasip2 1.0.4+wasi-0.2.12,
|
||||
wasm-bindgen 0.2.129, wasm-bindgen-futures 0.4.79, wasm-bindgen-macro 0.2.129,
|
||||
1.2.1, syn 1.0.109, tempfile 3.27.0, ttf-parser 0.25.1, unicode-bidi 0.3.18, unicode-segmentation
|
||||
1.13.3, unicode-width 0.2.2, url 2.5.8, uuid 1.27.0, wasi 0.11.1+wasi-snapshot-preview1, wasip2
|
||||
1.0.4+wasi-0.2.12, wasm-bindgen 0.2.129, wasm-bindgen-futures 0.4.79, wasm-bindgen-macro 0.2.129,
|
||||
wasm-bindgen-macro-support 0.2.129, wasm-bindgen-shared 0.2.129, web-sys 0.3.106, weezl 0.1.12,
|
||||
wit-bindgen 0.57.1
|
||||
================================================================================
|
||||
@@ -14524,6 +14525,49 @@ MIT License
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
||||
================================================================================
|
||||
unicode-bidi 0.3.18
|
||||
================================================================================
|
||||
|
||||
This project is copyright 2015, The Servo Project Developers (given in the
|
||||
file AUTHORS).
|
||||
|
||||
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
http://opensource.org/licenses/MIT>, at your option. All files in the project
|
||||
carrying such notice may not be copied, modified, or distributed except
|
||||
according to those terms.
|
||||
|
||||
================================================================================
|
||||
unicode-bidi 0.3.18, unicode-segmentation 1.13.3, unicode-width 0.2.2
|
||||
================================================================================
|
||||
|
||||
Copyright (c) 2015 The Rust Project Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
================================================================================
|
||||
unicode-ident 1.0.26
|
||||
================================================================================
|
||||
@@ -14572,36 +14616,6 @@ authorization of the copyright holder.
|
||||
unicode-segmentation 1.13.3, unicode-width 0.2.2
|
||||
================================================================================
|
||||
|
||||
Copyright (c) 2015 The Rust Project Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
================================================================================
|
||||
unicode-segmentation 1.13.3, unicode-width 0.2.2
|
||||
================================================================================
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
<LICENSE-APACHE or
|
||||
http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||
|
||||
@@ -419,7 +419,7 @@ fn wait_for_turn(control: &mut Control, mut chat: Value, began: Instant, end: In
|
||||
let idle = !matches!(state, "busy" | "starting") && !turn && !queued;
|
||||
// A turn can start and end between two polls: then the conversation has its answer.
|
||||
let answered = chat["items"].as_array().into_iter().flatten().any(|i| i.get("user").is_none());
|
||||
if idle && (seen_busy || answered || matches!(state, "exited" | "auth" | "off") || began.elapsed() >= START_GRACE) {
|
||||
if idle && (seen_busy || answered || matches!(state, "exited" | "failed" | "auth" | "off") || began.elapsed() >= START_GRACE) {
|
||||
return Ok((chat, false));
|
||||
}
|
||||
let Some(left) = end.checked_duration_since(Instant::now()).filter(|d| !d.is_zero()) else { return Ok((chat, true)) };
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! ```text
|
||||
//! solidcraft-cli run <script.json|design.solidcraft|part.step|mesh.3mf> [--in design|part.step|mesh.3mf] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]
|
||||
//! solidcraft-cli eval <script.json|design.solidcraft|part.step> [--json-out FILE] (alias: inspect) measurements as JSON
|
||||
//! solidcraft-cli eval <script.json|design.solidcraft|part.step> [--in design.solidcraft|part.step] [--json-out FILE] (alias: inspect) measurements as JSON
|
||||
//! solidcraft-cli script <design.solidcraft> [--out script.json] the design's history as a command script
|
||||
//! solidcraft-cli bench-open <design.solidcraft | part.step> [--parse-only] [--save OUT.solidcraft] [--display LEVEL [--edit NAME EXPR]] [--ops script.json] loading timings as JSON lines
|
||||
//! solidcraft-cli bench-agent [--scale F] [--save F] [--script-out F] a ~1,300-body design built command by command, timed
|
||||
@@ -58,7 +58,7 @@ struct Command {
|
||||
/// `run`'s lines in the usage.
|
||||
const USAGE_RUN: &str = " solidcraft-cli run <script.json|design.solidcraft|part.step> [--in design.solidcraft|part.step] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]\n solidcraft-cli run --in <design.solidcraft|part.step> [--out FILE]...\n (a timeline feature that fails fails the run and nothing is written; --allow-errors writes anyway)\n (--timings prints {timings: [{index, command, ms}], total_ms} for a script, with --results its results too;\n --profile adds each command's profile: {boolean_ms, tessellate_ms, other_ms}, the kernel's share)\n";
|
||||
/// `eval`'s lines in the usage.
|
||||
const USAGE_EVAL: &str = " solidcraft-cli eval <script.json|design.solidcraft|part.step> [--json-out FILE] (alias: inspect; or --in FILE)\n (--json-out FILE writes the JSON that run (with --results, else the measurement) and eval print to FILE instead of stdout,\n as plain UTF-8: a shell's > can re-encode it, e.g. Windows PowerShell adds a byte-order mark)\n";
|
||||
const USAGE_EVAL: &str = " solidcraft-cli eval <script.json|design.solidcraft|part.step> [--in design.solidcraft|part.step] [--json-out FILE] (alias: inspect)\n solidcraft-cli eval --in <script.json|design.solidcraft|part.step> [--json-out FILE]\n (with both inputs, runs the positional script on --in before measuring; does not automatically save the modified design)\n (--json-out FILE writes the JSON that run (with --results, else the measurement) and eval print to FILE instead of stdout,\n as plain UTF-8: a shell's > can re-encode it, e.g. Windows PowerShell adds a byte-order mark)\n";
|
||||
/// `script`'s lines in the usage.
|
||||
const USAGE_SCRIPT: &str = " solidcraft-cli script <design.solidcraft|script.json> [--out script.json]\n (the design's history as a command script that eval and run replay)\n";
|
||||
/// `bench-open`'s lines in the usage.
|
||||
@@ -392,7 +392,7 @@ fn cmd_run(args: &[String]) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The session `run` and `snapshot` start from: `--in` (a design or STEP file) with the
|
||||
/// The session `run`, `eval` and `snapshot` start from: `--in` (a design or STEP file) with the
|
||||
/// positional script run on top of it, or either one alone.
|
||||
fn open(base: Option<&str>, path: Option<&String>) -> Result<Session, String> {
|
||||
match (base, path) {
|
||||
@@ -445,8 +445,7 @@ fn timeline_ok(s: &Session) -> Result<(), String> {
|
||||
fn cmd_eval(args: &[String]) -> Result<(), String> {
|
||||
let json_out = json_out(args)?;
|
||||
known_args("eval", args, &["--in", "--json-out"], &[], true)?;
|
||||
let path = flag(args, "--in").or_else(|| positional(args).map(String::as_str)).ok_or_else(usage)?;
|
||||
let mut s = load(path)?;
|
||||
let mut s = open(flag(args, "--in"), positional(args))?;
|
||||
let m = s.execute("inspect.measure", &json!({})).map_err(|e| e.to_string())?;
|
||||
let d = s.execute("document.inspect", &json!({})).map_err(|e| e.to_string())?;
|
||||
let out = json!({
|
||||
|
||||
@@ -139,11 +139,13 @@ fn eval_json_out_holds_what_stdout_would() {
|
||||
fn json_out_needs_a_file_and_fails_when_it_cannot_write() {
|
||||
let dir = Scratch::new();
|
||||
let script = dir.script();
|
||||
for cmd in ["run", "eval"] {
|
||||
let output = cli().arg(cmd).arg(&script).arg("--json-out").output().unwrap();
|
||||
assert_eq!(output.status.code(), Some(1), "{cmd}");
|
||||
assert!(String::from_utf8_lossy(&output.stderr).contains("--json-out needs a FILE"), "{cmd}");
|
||||
assert!(output.stdout.is_empty(), "{cmd}");
|
||||
for cmd in ["run", "eval", "inspect"] {
|
||||
for trailing in [&[][..], &["--in"][..]] {
|
||||
let output = cli().arg(cmd).arg(&script).arg("--json-out").args(trailing).output().unwrap();
|
||||
assert_eq!(output.status.code(), Some(1), "{cmd}");
|
||||
assert!(String::from_utf8_lossy(&output.stderr).contains("--json-out needs a FILE"), "{cmd}");
|
||||
assert!(output.stdout.is_empty(), "{cmd}");
|
||||
}
|
||||
|
||||
let missing = dir.0.join("missing").join("out.json");
|
||||
let output = cli().arg(cmd).arg(&script).arg("--json-out").arg(&missing).output().unwrap();
|
||||
|
||||
@@ -267,6 +267,110 @@ fn results_with_base_design_and_quiet_still_report_and_save() {
|
||||
assert_eq!(body_count(&base), 1);
|
||||
}
|
||||
|
||||
/// `eval` and its alias must measure the script applied to the input design, rather than
|
||||
/// silently reporting the input alone (#6861).
|
||||
#[test]
|
||||
fn eval_runs_its_script_on_the_in_design() {
|
||||
let dir = Scratch::new();
|
||||
let base = dir.0.join("base.solidcraft");
|
||||
let script = dir.0.join("add.json");
|
||||
json_output(cli().arg("run").arg(dir.script()).arg("--save").arg(&base).output().unwrap());
|
||||
let original = std::fs::read(&base).unwrap();
|
||||
std::fs::write(
|
||||
&script,
|
||||
json!({"commands": [{"command": "solid.box", "params": {"length": 5, "width": 3, "height": 4, "corner": [10, 0, 0]}}]}).to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
for command in ["eval", "inspect"] {
|
||||
// Both existing one-input forms still measure just the original body.
|
||||
for input in [&base, &dir.script()] {
|
||||
for named_input in [false, true] {
|
||||
let mut c = cli();
|
||||
c.arg(command);
|
||||
if named_input {
|
||||
c.arg("--in");
|
||||
}
|
||||
let measured = json_output(c.arg(input).output().unwrap());
|
||||
assert_eq!(measured["body_count"], 1);
|
||||
assert!((measured["total"]["volume_mm3"].as_f64().unwrap() - 24.0).abs() < 1e-6);
|
||||
}
|
||||
}
|
||||
for input_first in [false, true] {
|
||||
for to_file in [false, true] {
|
||||
let mut c = cli();
|
||||
c.arg(command);
|
||||
if input_first {
|
||||
c.arg("--in").arg(&base).arg(&script);
|
||||
} else {
|
||||
c.arg(&script).arg("--in").arg(&base);
|
||||
}
|
||||
let report = dir.0.join("measurement.json");
|
||||
if to_file {
|
||||
c.arg("--json-out").arg(&report);
|
||||
}
|
||||
let output = c.output().unwrap();
|
||||
let measured = if to_file {
|
||||
assert!(output.status.success(), "{}", String::from_utf8_lossy(&output.stderr));
|
||||
assert!(output.stdout.is_empty());
|
||||
serde_json::from_slice(&std::fs::read(&report).unwrap()).unwrap()
|
||||
} else {
|
||||
json_output(output)
|
||||
};
|
||||
assert_eq!(measured["body_count"], 2, "{command}, input_first={input_first}, to_file={to_file}");
|
||||
assert!((measured["total"]["volume_mm3"].as_f64().unwrap() - 84.0).abs() < 1e-6);
|
||||
assert_eq!(measured["timeline"].as_array().unwrap().len(), 2, "the script runs exactly once");
|
||||
assert_eq!(std::fs::read(&base).unwrap(), original, "evaluation never saves its changes to the input");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_propagates_script_errors_before_writing_a_report() {
|
||||
let dir = Scratch::new();
|
||||
let base = dir.script();
|
||||
let script = dir.0.join("bad.json");
|
||||
for command in ["eval", "inspect"] {
|
||||
for contents in ["{", r#"{"commands":[{"command":"missing.command","params":{}}]}"#] {
|
||||
std::fs::write(&script, contents).unwrap();
|
||||
let report = dir.0.join("report.json");
|
||||
let output = cli().arg(command).arg(&script).arg("--in").arg(&base).arg("--json-out").arg(&report).output().unwrap();
|
||||
assert_eq!(output.status.code(), Some(1));
|
||||
assert!(!output.stderr.is_empty());
|
||||
assert!(output.stdout.is_empty());
|
||||
assert!(!report.exists());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_rejects_unknown_options_and_missing_input_values_before_writing_a_report() {
|
||||
let dir = Scratch::new();
|
||||
let script = dir.script();
|
||||
let report = dir.0.join("report.json");
|
||||
for command in ["eval", "inspect"] {
|
||||
for (options, message) in [(&["--frobnicate", "1"][..], "doesn't take --frobnicate"), (&["--in"][..], "--in needs a value")] {
|
||||
for options_first in [false, true] {
|
||||
std::fs::write(&report, b"previous report").unwrap();
|
||||
let mut c = cli();
|
||||
c.arg(command);
|
||||
if options_first {
|
||||
c.args(options).arg("--json-out").arg(&report).arg(&script);
|
||||
} else {
|
||||
c.arg(&script).args(options).arg("--json-out").arg(&report);
|
||||
}
|
||||
// A following option also proves that --in cannot consume a flag as its value.
|
||||
let output = c.output().unwrap();
|
||||
assert_eq!(output.status.code(), Some(1), "{command}, {options:?}");
|
||||
let error = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(error.contains(message), "{command}: {error}");
|
||||
assert!(output.stdout.is_empty());
|
||||
assert_eq!(std::fs::read(&report).unwrap(), b"previous report");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn results_propagate_output_errors() {
|
||||
let dir = Scratch::new();
|
||||
|
||||
@@ -37,5 +37,5 @@ web-sys = { version = "0.3", features = [
|
||||
"WritableStream", "File", "FileList", "Blob", "BlobPropertyBag", "Url", "HtmlAnchorElement", "HtmlInputElement", "Storage",
|
||||
"IdbFactory", "IdbDatabase", "IdbObjectStore", "IdbOpenDbRequest", "IdbRequest", "IdbTransaction", "IdbTransactionMode",
|
||||
"Headers", "ReadableStream", "ReadableStreamDefaultReader",
|
||||
"BeforeUnloadEvent", "Event", "EventTarget", "KeyboardEvent", "Response", "MediaQueryList", "Gamepad", "Performance",
|
||||
"BeforeUnloadEvent", "Event", "EventTarget", "KeyboardEvent", "Response", "FormData", "RequestInit", "MediaQueryList", "Gamepad", "Performance",
|
||||
] }
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
<!-- Installable as an app (manifest.webmanifest); the icons are the Linux exports of the app mark. -->
|
||||
<meta name="theme-color" content="#343840">
|
||||
<link rel="manifest" href="manifest.webmanifest">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="icons/32x32/ai.storyteller.solidcraft.png">
|
||||
<link rel="apple-touch-icon" href="icons/256x256/ai.storyteller.solidcraft.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="icons/32x32/io.tangencylabs.solidcraft.png">
|
||||
<link rel="apple-touch-icon" href="icons/256x256/io.tangencylabs.solidcraft.png">
|
||||
<link data-trunk rel="copy-file" href="manifest.webmanifest" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/icons/app/linux/exports/hicolor/32x32/apps/ai.storyteller.solidcraft.png" data-target-path="icons/32x32" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/icons/app/linux/exports/hicolor/256x256/apps/ai.storyteller.solidcraft.png" data-target-path="icons/256x256" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/icons/app/linux/exports/hicolor/512x512/apps/ai.storyteller.solidcraft.png" data-target-path="icons/512x512" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/icons/app/linux/exports/hicolor/32x32/apps/io.tangencylabs.solidcraft.png" data-target-path="icons/32x32" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/icons/app/linux/exports/hicolor/256x256/apps/io.tangencylabs.solidcraft.png" data-target-path="icons/256x256" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/icons/app/linux/exports/hicolor/512x512/apps/io.tangencylabs.solidcraft.png" data-target-path="icons/512x512" />
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="solidcraft_canvas"></canvas>
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
"theme_color": "#343840",
|
||||
"categories": ["productivity", "utilities"],
|
||||
"icons": [
|
||||
{ "src": "icons/32x32/ai.storyteller.solidcraft.png", "sizes": "32x32", "type": "image/png" },
|
||||
{ "src": "icons/256x256/ai.storyteller.solidcraft.png", "sizes": "256x256", "type": "image/png" },
|
||||
{ "src": "icons/512x512/ai.storyteller.solidcraft.png", "sizes": "512x512", "type": "image/png" }
|
||||
{ "src": "icons/32x32/io.tangencylabs.solidcraft.png", "sizes": "32x32", "type": "image/png" },
|
||||
{ "src": "icons/256x256/io.tangencylabs.solidcraft.png", "sizes": "256x256", "type": "image/png" },
|
||||
{ "src": "icons/512x512/io.tangencylabs.solidcraft.png", "sizes": "512x512", "type": "image/png" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -147,6 +147,21 @@ pub fn accept_list(extensions: &[&str]) -> String {
|
||||
list.join(",")
|
||||
}
|
||||
|
||||
/// The `accept` of a file input for `extensions` on this device (`apple_touch`: an iPhone or
|
||||
/// iPad). The picker there offers only files of a type the system knows from the list and greys
|
||||
/// out the rest, `.solidcraft` designs among them, since no system type has that extension
|
||||
/// (#6977). So it offers every file there, and the opener checks what it gets.
|
||||
pub fn input_accept(extensions: &[&str], apple_touch: bool) -> String {
|
||||
if apple_touch { String::new() } else { accept_list(extensions) }
|
||||
}
|
||||
|
||||
/// The browser runs on an iPhone or iPad (every browser there is WebKit), from its
|
||||
/// `navigator.userAgent` and `navigator.maxTouchPoints`. iPadOS presents itself as a Mac; only its
|
||||
/// touch screen tells them apart.
|
||||
pub fn apple_touch(user_agent: &str, touch_points: i32) -> bool {
|
||||
["iPhone", "iPad", "iPod"].iter().any(|d| user_agent.contains(d)) || (user_agent.contains("Macintosh") && touch_points > 1)
|
||||
}
|
||||
|
||||
/// The largest file an upload for `extensions` reads: images go into a canvas, which has a size
|
||||
/// limit, so a bigger one is refused before it is read. `None`: the importer checks the file.
|
||||
pub fn upload_limit(extensions: &[&str]) -> Option<usize> {
|
||||
@@ -612,6 +627,8 @@ mod tests {
|
||||
assert_eq!(route("/disk/18f-2a/Bracket.solidcraft"), WriteTo::Disk);
|
||||
assert_eq!(route("/downloads/part.step"), WriteTo::Download);
|
||||
assert_eq!(route("/upload/part.step"), WriteTo::Memory);
|
||||
// The temporary folder (a screenshot without a path, #7192) stays in memory.
|
||||
assert_eq!(route(&format!("{}/solidcraft-shot.png", solidcraft_engine::io::vfs::BROWSER_TEMP)), WriteTo::Memory);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -671,6 +688,26 @@ mod tests {
|
||||
assert_eq!(upload_limit(&["dxf"]), None);
|
||||
}
|
||||
|
||||
/// An iPhone or iPad greys out a `.solidcraft` design the `accept` list names, as it knows no
|
||||
/// type for that extension, so its inputs offer every file; other devices keep the list (#6977).
|
||||
#[test]
|
||||
fn file_inputs_on_an_iphone_or_ipad_offer_every_file() {
|
||||
let iphone =
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1";
|
||||
let mac = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Safari/605.1.15";
|
||||
let chrome_ios = "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/138.0.7204.156 Mobile/15E148 Safari/604.1";
|
||||
let chrome = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36";
|
||||
assert!(apple_touch(iphone, 5));
|
||||
assert!(apple_touch(chrome_ios, 5), "every browser on iOS has the same picker");
|
||||
assert!(apple_touch(mac, 5), "an iPad presents itself as a Mac");
|
||||
assert!(!apple_touch(mac, 0), "a Mac has no touch screen");
|
||||
assert!(!apple_touch(chrome, 10), "a touch screen elsewhere filters as before");
|
||||
assert!(!apple_touch("", 0), "hostile input is just not an iPhone");
|
||||
let designs = ["solidcraft", "json", "step"];
|
||||
assert_eq!(input_accept(&designs, true), "");
|
||||
assert_eq!(input_accept(&designs, false), ".solidcraft,.json,.step");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_save_dialog_offers_the_type_of_the_name() {
|
||||
assert_eq!(save_type("Plate.solidcraft").2, ".solidcraft");
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//! Open with EasyPrint in the browser: upload the model to Printables' import endpoint with
|
||||
//! `fetch` (it allows any origin) and answer with the address to open.
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use js_sys::{Array, Uint8Array};
|
||||
use solidcraft_engine::easyprint::{IMPORT_URL, parse_import_response};
|
||||
use wasm_bindgen::JsCast as _;
|
||||
use wasm_bindgen_futures::{JsFuture, spawn_local};
|
||||
|
||||
use crate::files::err;
|
||||
|
||||
/// Start the upload; the answer arrives on `done`.
|
||||
pub fn upload(name: &str, bytes: Vec<u8>, done: Sender<Result<String, String>>) {
|
||||
let name = name.to_string();
|
||||
spawn_local(async move {
|
||||
let _ = done.send(post(&name, &bytes).await);
|
||||
});
|
||||
}
|
||||
|
||||
async fn post(name: &str, bytes: &[u8]) -> Result<String, String> {
|
||||
let window = web_sys::window().ok_or("no window")?;
|
||||
let parts = Array::new();
|
||||
parts.push(&Uint8Array::from(bytes));
|
||||
let blob = web_sys::Blob::new_with_u8_array_sequence(&parts).map_err(err)?;
|
||||
let form = web_sys::FormData::new().map_err(err)?;
|
||||
form.append_with_blob_and_filename("file", &blob, name).map_err(err)?;
|
||||
form.append_with_str("file_name", name).map_err(err)?;
|
||||
let headers = web_sys::Headers::new().map_err(err)?;
|
||||
headers.set("Accept", "application/json").map_err(err)?;
|
||||
let init = web_sys::RequestInit::new();
|
||||
init.set_method("POST");
|
||||
init.set_body(&form);
|
||||
init.set_headers(&headers);
|
||||
let response = JsFuture::from(window.fetch_with_str_and_init(IMPORT_URL, &init)).await.map_err(err)?;
|
||||
let response: web_sys::Response = response.dyn_into().map_err(|_| "response cast failed".to_string())?;
|
||||
let status = response.status();
|
||||
let text = JsFuture::from(response.text().map_err(err)?).await.map_err(err)?;
|
||||
parse_import_response(status, text.as_string().unwrap_or_default().as_bytes())
|
||||
}
|
||||
@@ -513,9 +513,9 @@ fn input_picker(files: &Rc<Files>, intent: Intent) {
|
||||
input.set_type("file");
|
||||
// Everything the browser build imports, from the format registry: cadmpeg is pure Rust, so
|
||||
// FreeCAD and Rhino files are part of it; plus the DXF and SVG drawings Open and Insert take.
|
||||
let accept =
|
||||
solidcraft_engine::io::formats::open_extensions(true).iter().chain(&["dxf", "svg"]).map(|e| format!(".{e}")).collect::<Vec<_>>().join(",");
|
||||
input.set_accept(&accept);
|
||||
let mut extensions = solidcraft_engine::io::formats::open_extensions(true);
|
||||
extensions.extend(["dxf", "svg"]);
|
||||
input.set_accept(&disk::input_accept(&extensions, apple_touch()));
|
||||
// Attached (hidden) while it is open: some browsers ignore a click on a detached input.
|
||||
let _ = input.set_attribute("style", "display:none");
|
||||
if let Some(body) = doc.body() {
|
||||
@@ -546,7 +546,7 @@ fn input_picker(files: &Rc<Files>, intent: Intent) {
|
||||
/// `None` when the dialog was closed or the file could not be read.
|
||||
pub fn pick_upload(files: &Rc<Files>, extensions: &[&str]) -> impl std::future::Future<Output = Option<String>> + use<> {
|
||||
// Shown now, in the click: a file dialog needs the user's gesture.
|
||||
let chosen = choose_file(&disk::accept_list(extensions));
|
||||
let chosen = choose_file(&disk::input_accept(extensions, apple_touch()));
|
||||
let limit = disk::upload_limit(extensions);
|
||||
let files = files.clone();
|
||||
async move {
|
||||
@@ -573,6 +573,14 @@ pub fn pick_upload(files: &Rc<Files>, extensions: &[&str]) -> impl std::future::
|
||||
}
|
||||
}
|
||||
|
||||
/// The page runs on an iPhone or iPad, whose file inputs offer every file (`disk::input_accept`).
|
||||
fn apple_touch() -> bool {
|
||||
web_sys::window().is_some_and(|w| {
|
||||
let nav = w.navigator();
|
||||
disk::apple_touch(&nav.user_agent().unwrap_or_default(), nav.max_touch_points())
|
||||
})
|
||||
}
|
||||
|
||||
/// Show a hidden `<input type=file>` offering `accept` (call in the click). The promise answers
|
||||
/// the picked `File`, or `null` when the dialog is closed (the input's `cancel` event).
|
||||
fn choose_file(accept: &str) -> Result<js_sys::Promise, String> {
|
||||
|
||||
@@ -11,6 +11,8 @@ mod api;
|
||||
#[cfg(any(target_arch = "wasm32", test))]
|
||||
mod disk;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod easyprint;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod files;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod install;
|
||||
@@ -777,6 +779,7 @@ mod web {
|
||||
})),
|
||||
restore_file: Some(Box::new(move |path: &str| disk::restore(&restorer, path))),
|
||||
download_design: Some(Box::new(files::download)),
|
||||
easyprint_upload: Some(std::sync::Arc::new(crate::easyprint::upload)),
|
||||
browser_files: Some(Box::new(move || shown.panel.set(true))),
|
||||
install_app: Some(crate::install::service(&cc.egui_ctx)),
|
||||
..Default::default()
|
||||
|
||||
@@ -13,8 +13,9 @@ bundled-render-library = ["solidcraft-engine/bundled-render-library"]
|
||||
raytrace-cpu = ["solidcraft-engine/raytrace-cpu"]
|
||||
|
||||
# The workspace lints, except unsafe_code: denied, not forbidden, so that src/open_documents.rs
|
||||
# (macOS file-open events), src/native_crash.rs (Windows exception filter) and src/native_frame.rs
|
||||
# (Windows resize border, taskbar icon) can allow it: none has a safe API. Keep the rest in sync with [workspace.lints].
|
||||
# (macOS file-open events), src/native_crash.rs (Windows exception filter), src/native_crash_macos.rs
|
||||
# (macOS crash signal handler) and src/native_frame.rs (Windows resize border, taskbar icon) can
|
||||
# allow it: none has a safe API. Keep the rest in sync with [workspace.lints].
|
||||
[lints.rust]
|
||||
unsafe_code = "deny"
|
||||
|
||||
@@ -31,6 +32,7 @@ solidcraft-ui-egui = { workspace = true }
|
||||
solidcraft-space-mouse = { workspace = true }
|
||||
eframe = { workspace = true, features = ["default_fonts", "wgpu", "accesskit", "wayland", "x11", "links"] }
|
||||
egui = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rfd = { workspace = true }
|
||||
@@ -88,6 +90,9 @@ objc2 = "0.6"
|
||||
objc2-app-kit = { version = "0.3", default-features = false, features = ["std", "NSApplication", "NSResponder", "NSWindow"] }
|
||||
objc2-foundation = { version = "0.3", default-features = false, features = ["std", "block2", "NSArray", "NSNotification", "NSOperation", "NSProcessInfo", "NSString", "NSURL"] }
|
||||
block2 = "0.6"
|
||||
# Native crash capture (src/native_crash_macos.rs): the signal handler, the faulting module
|
||||
# (already in the tree through many crates).
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
|
||||
winit = { version = "0.30", default-features = false, features = ["x11"] }
|
||||
|
||||
@@ -187,6 +187,35 @@ fn send(out: &mut impl Write, reply: &Value) -> std::io::Result<()> {
|
||||
out.write_all(&line)
|
||||
}
|
||||
|
||||
/// The `"token"` of a request line that is a JSON object, read without building the rest of it.
|
||||
/// Until a connection shows the token, a line costs only its own bytes: parsed whole, a 16 MiB
|
||||
/// line of `[0,0,…]` is hundreds of MB, and 16 such connections could exhaust memory before any
|
||||
/// token was checked.
|
||||
fn token_of(line: &str) -> Option<String> {
|
||||
struct Token;
|
||||
impl<'de> serde::de::Visitor<'de> for Token {
|
||||
type Value = Option<String>;
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.write_str("a request object")
|
||||
}
|
||||
fn visit_map<A: serde::de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
|
||||
let mut token = None;
|
||||
while let Some(key) = map.next_key::<String>()? {
|
||||
if key == "token" {
|
||||
token = Some(map.next_value::<String>()?);
|
||||
} else {
|
||||
map.next_value::<serde::de::IgnoredAny>()?;
|
||||
}
|
||||
}
|
||||
Ok(token)
|
||||
}
|
||||
}
|
||||
let mut de = serde_json::Deserializer::from_str(line);
|
||||
let token = serde::Deserializer::deserialize_map(&mut de, Token).ok()?;
|
||||
de.end().ok()?;
|
||||
token
|
||||
}
|
||||
|
||||
/// The reply to a connection that didn't show the token; the connection is then closed.
|
||||
fn unauthorized() -> Value {
|
||||
json!({"ok": false, "error": "unauthorized: send the control token as \"token\" (see docs/control-protocol.md)"})
|
||||
@@ -388,7 +417,6 @@ impl Lines {
|
||||
struct Subscription {
|
||||
lines: Arc<Lines>,
|
||||
stop: Arc<AtomicBool>,
|
||||
_counted: Subscriber,
|
||||
}
|
||||
|
||||
impl Subscription {
|
||||
@@ -406,10 +434,13 @@ impl Subscription {
|
||||
let stop = Arc::new(AtomicBool::new(false));
|
||||
let first = lines.turn.lock().unwrap_or_else(PoisonError::into_inner);
|
||||
let (l, s) = (lines.clone(), stop.clone());
|
||||
std::thread::Builder::new().stack_size(64 * 1024).spawn(move || send_events(design, &l, &s, seen)).ok()?;
|
||||
// The connection's seat on the watch rides the events thread: it leaves when the thread
|
||||
// does, so the next failed write to a closed client retires it even while the connection's
|
||||
// own thread is slow to see the end of the stream (#7226).
|
||||
std::thread::Builder::new().stack_size(64 * 1024).spawn(move || send_events(design, &l, &s, seen, counted)).ok()?;
|
||||
let sent = send(&mut &lines.socket, reply);
|
||||
drop(first);
|
||||
Some((Subscription { lines, stop, _counted: counted }, sent))
|
||||
Some((Subscription { lines, stop }, sent))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,8 +460,10 @@ impl Drop for Subscription {
|
||||
}
|
||||
|
||||
/// The `design.changed` lines of a subscribed connection, each time the design differs from the
|
||||
/// last one it was told of (`seen`), until `stop`.
|
||||
fn send_events(design: &DesignWatch, lines: &Lines, stop: &AtomicBool, mut seen: (String, u64)) {
|
||||
/// last one it was told of (`seen`), until `stop`. Owns the connection's seat on the watch
|
||||
/// (`counted`), so the seat leaves exactly when this thread does: on `stop`, or on the first
|
||||
/// write a closed client refuses (#7226).
|
||||
fn send_events(design: &DesignWatch, lines: &Lines, stop: &AtomicBool, mut seen: (String, u64), _counted: Subscriber) {
|
||||
while !stop.load(Ordering::Relaxed) {
|
||||
let Some(now) = design.wait(&seen, stop, Duration::from_secs(1)).filter(|now| *now != seen) else { continue };
|
||||
if lines.send(&json!({"event": "design.changed", "params": {"document_id": now.0, "revision": now.1}})).is_err() {
|
||||
@@ -486,18 +519,18 @@ fn serve_with(
|
||||
if line.trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
// The first request must carry the token; later ones on the same connection may.
|
||||
if !authenticated {
|
||||
match token_of(&line) {
|
||||
Some(t) if control_auth::tokens_match(&t, token) => authenticated = true,
|
||||
_ => {
|
||||
refuse(&mut out, &mut reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let reply = match serde_json::from_str::<Value>(&line) {
|
||||
Ok(msg) => {
|
||||
// The first request must carry the token; later ones on the same connection may.
|
||||
if !authenticated {
|
||||
match msg.get("token").and_then(Value::as_str) {
|
||||
Some(t) if control_auth::tokens_match(t, token) => authenticated = true,
|
||||
_ => {
|
||||
refuse(&mut out, &mut reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let id = msg.get("id").cloned().unwrap_or(Value::Null);
|
||||
let method = msg.get("method").and_then(Value::as_str).unwrap_or("").to_string();
|
||||
let params = msg.get("params").cloned().unwrap_or(json!({}));
|
||||
@@ -563,10 +596,6 @@ fn serve_with(
|
||||
}
|
||||
r
|
||||
}
|
||||
Err(_) if !authenticated => {
|
||||
refuse(&mut out, &mut reader);
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
bad += 1;
|
||||
json!({"ok": false, "error": format!("bad JSON: {e}")})
|
||||
@@ -841,11 +870,17 @@ mod tests {
|
||||
assert_eq!(next(&mut lines), json!({"id": 3, "ok": true, "result": "ui.view"}));
|
||||
writeln!(quiet_out, "{}", json!({"id": 2, "method": "ui.view"})).unwrap();
|
||||
assert_eq!(next(&mut quiet), json!({"id": 2, "ok": true, "result": "ui.view"}), "no events without subscribing");
|
||||
// Closed, it is no longer counted.
|
||||
// Closed, it is no longer counted. Each publish asks the events thread for one more line,
|
||||
// and its write to the closed connection is what retires the seat; that keeps the wait off
|
||||
// the connection's own thread, which anything else this process is doing may hold up past
|
||||
// the deadline (#7226).
|
||||
drop((out, lines));
|
||||
let mut revision = 11;
|
||||
let deadline = Instant::now() + Duration::from_secs(10);
|
||||
while WATCH.subscribed() && Instant::now() < deadline {
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
WATCH.publish("d-1", revision);
|
||||
revision += 1;
|
||||
std::thread::sleep(Duration::from_millis(20));
|
||||
}
|
||||
assert!(!WATCH.subscribed());
|
||||
}
|
||||
@@ -869,6 +904,19 @@ mod tests {
|
||||
assert!(render.contains("will still write the file"), "{render}");
|
||||
}
|
||||
|
||||
/// The token is read from a request object without building the rest of it: other fields,
|
||||
/// however large or nested, are only skipped. Anything but an object with a string token is
|
||||
/// no token.
|
||||
#[test]
|
||||
fn token_is_read_without_parsing_the_request() {
|
||||
assert_eq!(token_of(r#"{"id":1,"token":"abc","params":{"a":[1,[2,{"b":null}]]}}"#).as_deref(), Some("abc"));
|
||||
let flood = format!(r#"{{"params":[{}0],"token":"t"}}"#, "0,".repeat(1 << 20));
|
||||
assert_eq!(token_of(&flood).as_deref(), Some("t"));
|
||||
for no in [r#"["abc"]"#, r#"{"token":5}"#, r#"{"token":"a"} x"#, r#"{"id":1}"#, "GET / HTTP/1.1", r#""token""#] {
|
||||
assert_eq!(token_of(no), None, "{no}");
|
||||
}
|
||||
}
|
||||
|
||||
/// #205: a connection runs nothing until a request carries the launch's token; a wrong or
|
||||
/// missing token, or garbage, is refused and the connection closed. Once shown, the token
|
||||
/// need not be repeated on that connection.
|
||||
|
||||
@@ -24,6 +24,8 @@ mod control_server;
|
||||
mod device_lost;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod native_crash;
|
||||
#[cfg(target_os = "macos")]
|
||||
mod native_crash_macos;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod native_frame;
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -90,6 +92,8 @@ struct App {
|
||||
native_menu: Option<native_menu::NativeMenu>,
|
||||
/// A device's own app moving the view (Preferences › Navigation, off by default).
|
||||
nav_bridge: nav_bridge::NavBridge,
|
||||
/// Where the next file dialog opens: it follows the open design (#7756).
|
||||
dialog_folder: DialogFolder,
|
||||
}
|
||||
|
||||
impl eframe::App for App {
|
||||
@@ -120,6 +124,7 @@ impl eframe::App for App {
|
||||
// Automation runs (a control port was asked for) leave the user's AI apps alone.
|
||||
if !self.take_focus_unwanted {
|
||||
solidcraft_ui_egui::ai_connect::begin(&mut self.solve);
|
||||
solidcraft_ui_egui::agent_chat::begin(&mut self.solve);
|
||||
}
|
||||
if let Some(dir) = self.starting.take() {
|
||||
startup::started(&dir);
|
||||
@@ -144,6 +149,7 @@ impl eframe::App for App {
|
||||
menu.tick(&mut self.solve, ctx);
|
||||
}
|
||||
self.solve.logic(ctx);
|
||||
self.dialog_folder.design(self.solve.session.path.as_deref());
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
if !self.solve.file_picker_busy() {
|
||||
self.space_mouse.tick(&mut self.solve, ctx);
|
||||
@@ -238,6 +244,60 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
/// Where the next file dialog opens (#7756): the folder of the file last chosen in one, or of the
|
||||
/// design last opened or saved, whichever came last. Linux dialogs otherwise open in the home
|
||||
/// folder every time; macOS and Windows remember a folder of their own, which this agrees with.
|
||||
#[derive(Clone, Default)]
|
||||
struct DialogFolder(std::sync::Arc<std::sync::Mutex<DialogFolderState>>);
|
||||
|
||||
#[derive(Default)]
|
||||
struct DialogFolderState {
|
||||
folder: Option<std::path::PathBuf>,
|
||||
/// The open design's path when last looked at, to notice another design opened or saved.
|
||||
design: Option<String>,
|
||||
}
|
||||
|
||||
impl DialogFolder {
|
||||
/// A file was chosen in a dialog: the next one opens in its folder.
|
||||
fn chosen(&self, file: &std::path::Path) {
|
||||
if let (Some(folder), Ok(mut state)) = (file.parent().filter(|f| !f.as_os_str().is_empty()), self.0.lock()) {
|
||||
state.folder = Some(folder.to_path_buf());
|
||||
}
|
||||
}
|
||||
|
||||
/// The open design's path, every frame: a design opened or saved somewhere else moves the
|
||||
/// next dialog to its folder; the same design again leaves a folder chosen since alone.
|
||||
fn design(&self, path: Option<&str>) {
|
||||
let Ok(mut state) = self.0.lock() else { return };
|
||||
if state.design.as_deref() == path {
|
||||
return;
|
||||
}
|
||||
state.design = path.map(str::to_string);
|
||||
if let Some(folder) = path.and_then(|p| std::path::Path::new(p).parent()).filter(|f| !f.as_os_str().is_empty()) {
|
||||
state.folder = Some(folder.to_path_buf());
|
||||
}
|
||||
}
|
||||
|
||||
/// A dialog's answer as a path, its folder remembered for the next dialog.
|
||||
fn answer(&self, picked: Option<rfd::FileHandle>) -> Option<String> {
|
||||
let picked = picked?;
|
||||
self.chosen(picked.path());
|
||||
Some(picked.path().to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
fn folder(&self) -> Option<std::path::PathBuf> {
|
||||
self.0.lock().ok().and_then(|state| state.folder.clone())
|
||||
}
|
||||
|
||||
/// The dialog, opening in the remembered folder when there is one.
|
||||
fn start(&self, dialog: rfd::AsyncFileDialog) -> rfd::AsyncFileDialog {
|
||||
match self.folder() {
|
||||
Some(folder) => dialog.set_directory(folder),
|
||||
None => dialog,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Linux file dialogs match patterns by case, so each extension goes in as lower and upper
|
||||
/// case, plus FreeCAD's own mixed casing.
|
||||
fn case_variants(exts: &[&str]) -> Vec<String> {
|
||||
@@ -287,15 +347,16 @@ fn fullscreen_content_insets(raw: &mut egui::RawInput, title_height: f32, zoom:
|
||||
raw.safe_area_insets = Some(insets);
|
||||
}
|
||||
|
||||
fn services(cc: &eframe::CreationContext<'_>) -> Services {
|
||||
fn services(cc: &eframe::CreationContext<'_>, folder: &DialogFolder) -> Services {
|
||||
let parent = rfd::AsyncFileDialog::new().set_parent(cc);
|
||||
let open_parent = parent.clone();
|
||||
let program_parent = parent.clone();
|
||||
let file_parent = parent.clone();
|
||||
let (open_folder, file_folder, save_folder) = (folder.clone(), folder.clone(), folder.clone());
|
||||
Services {
|
||||
pick_open: Some(Box::new(move |first: &[&str]| {
|
||||
// The file type the command reads comes first, so the picker opens on it (#1801).
|
||||
let mut dialog = open_parent.clone();
|
||||
let mut dialog = open_folder.start(open_parent.clone());
|
||||
if !first.is_empty() {
|
||||
let label = first.iter().map(|e| e.to_uppercase()).collect::<Vec<_>>().join(", ");
|
||||
dialog = dialog.add_filter(label, &case_variants(first));
|
||||
@@ -308,7 +369,8 @@ fn services(cc: &eframe::CreationContext<'_>) -> Services {
|
||||
dialog = dialog.add_filter(label, &case_variants(&exts));
|
||||
}
|
||||
let future = dialog.add_filter("All files", &["*"]).pick_file();
|
||||
Box::pin(async move { future.await.map(|p| p.path().to_string_lossy().into_owned()) })
|
||||
let folder = open_folder.clone();
|
||||
Box::pin(async move { folder.answer(future.await) })
|
||||
})),
|
||||
// One kind of file (the agent chat's attachments): only the types it names, as given and in
|
||||
// lower and upper case (Linux dialogs match case; macOS allows just the listed types).
|
||||
@@ -323,8 +385,9 @@ fn services(cc: &eframe::CreationContext<'_>) -> Services {
|
||||
}
|
||||
let all: Vec<&str> = all.iter().map(String::as_str).collect();
|
||||
// Any other file attaches by reference, so the list is not the only choice.
|
||||
let future = file_parent.clone().add_filter(label, &all).add_filter("All files", &["*"]).pick_file();
|
||||
Box::pin(async move { future.await.map(|p| p.path().to_string_lossy().into_owned()) })
|
||||
let future = file_folder.start(file_parent.clone()).add_filter(label, &all).add_filter("All files", &["*"]).pick_file();
|
||||
let folder = file_folder.clone();
|
||||
Box::pin(async move { folder.answer(future.await) })
|
||||
})),
|
||||
pick_program: Some(Box::new(move || {
|
||||
let dialog = program_parent.clone().set_title("Choose your slicer");
|
||||
@@ -333,7 +396,7 @@ fn services(cc: &eframe::CreationContext<'_>) -> Services {
|
||||
Box::pin(async move { future.await.map(|p| p.path().to_string_lossy().into_owned()) })
|
||||
})),
|
||||
pick_save: Some(Box::new(move |name: &str, exts: &[&str]| {
|
||||
let dialog = parent.clone().set_file_name(name);
|
||||
let dialog = save_folder.start(parent.clone()).set_file_name(name);
|
||||
let dialog = if exts == [io::DESIGN_EXT, "json"] {
|
||||
if name.ends_with(".json") {
|
||||
dialog.add_filter("Plain JSON design", &["json"]).add_filter("SolidCraft container", &[io::DESIGN_EXT])
|
||||
@@ -344,7 +407,8 @@ fn services(cc: &eframe::CreationContext<'_>) -> Services {
|
||||
dialog.add_filter("File", exts)
|
||||
};
|
||||
let future = dialog.save_file();
|
||||
Box::pin(async move { future.await.map(|p| p.path().to_string_lossy().into_owned()) })
|
||||
let folder = save_folder.clone();
|
||||
Box::pin(async move { folder.answer(future.await) })
|
||||
})),
|
||||
graphics_adapters: Vec::new(),
|
||||
graphics_path: graphics_path().map(|p| p.to_string_lossy().to_string()),
|
||||
@@ -356,6 +420,7 @@ fn services(cc: &eframe::CreationContext<'_>) -> Services {
|
||||
can_restore: None,
|
||||
restore_file: None,
|
||||
download_design: None,
|
||||
easyprint_upload: Some(std::sync::Arc::new(easyprint_upload)),
|
||||
browser_files: None,
|
||||
agent_http: Some(std::sync::Arc::new(agent_http)),
|
||||
secrets: Some(std::sync::Arc::new(Keychain)),
|
||||
@@ -452,6 +517,24 @@ fn agent_http(r: &solidcraft_ui_egui::agent_chat::backend::HttpRequest) -> Resul
|
||||
Ok((status, body))
|
||||
}
|
||||
|
||||
/// Open with EasyPrint: upload the model to Printables' import endpoint on a worker and answer on
|
||||
/// `done` with the address to open. Through [`agent_http`]: no redirects, a timeout, no cookies.
|
||||
fn easyprint_upload(name: &str, bytes: Vec<u8>, done: std::sync::mpsc::Sender<Result<String, String>>) {
|
||||
use solidcraft_engine::easyprint;
|
||||
let name = name.to_string();
|
||||
std::thread::spawn(move || {
|
||||
let (content_type, body) = easyprint::multipart(&name, &bytes);
|
||||
let request = solidcraft_ui_egui::agent_chat::backend::HttpRequest {
|
||||
method: "POST",
|
||||
url: easyprint::IMPORT_URL.into(),
|
||||
headers: vec![("Content-Type".into(), content_type), ("Accept".into(), "application/json".into())],
|
||||
body: Some(body),
|
||||
timeout_s: 180,
|
||||
};
|
||||
let _ = done.send(agent_http(&request).and_then(|(status, body)| easyprint::parse_import_response(status, &body)));
|
||||
});
|
||||
}
|
||||
|
||||
/// API keys in the system keychain (service "SolidCraft agent chat", one entry per agent).
|
||||
struct Keychain;
|
||||
|
||||
@@ -532,26 +615,26 @@ fn graphics_path() -> Option<std::path::PathBuf> {
|
||||
/// Compatibility shim (docs/compatibility.md): on the first launch after the rename, copy the
|
||||
/// settings of earlier releases into the new folder. They kept `graphics.json` (and, on Linux
|
||||
/// and macOS, the recovery folder) under the old product name, and eframe's `app.ron` under the
|
||||
/// window's old app id. In the Flatpak sandbox, releases before 0.8 kept everything under the
|
||||
/// old app id's `~/.var/app` folder; that copy comes first, as it is the newest. The old folders
|
||||
/// window's old app id. In the Flatpak sandbox, earlier releases kept everything under an
|
||||
/// old app id's `~/.var/app` folder; those copies come first, newest first. The old folders
|
||||
/// are never changed.
|
||||
fn adopt_legacy_settings() {
|
||||
let (Some(current), Some(legacy)) = (settings_dir().ok().flatten(), eframe::storage_dir("SolveCraft")) else { return };
|
||||
let legacy_eframe = eframe::storage_dir(solidcraft_engine::io::LEGACY_APP_ID);
|
||||
let old_flatpak = solidcraft_engine::io::legacy_flatpak_path(¤t);
|
||||
if let Err(e) = adopt_settings(¤t, old_flatpak.as_deref(), &legacy, legacy_eframe.as_deref()) {
|
||||
let old_flatpak = solidcraft_engine::io::legacy_flatpak_paths(¤t);
|
||||
if let Err(e) = adopt_settings(¤t, &old_flatpak, &legacy, legacy_eframe.as_deref()) {
|
||||
log::warn!("settings: could not copy the previous release's settings into {}: {e}", current.display());
|
||||
}
|
||||
}
|
||||
|
||||
fn adopt_settings(
|
||||
current: &std::path::Path,
|
||||
old_flatpak: Option<&std::path::Path>,
|
||||
old_flatpak: &[std::path::PathBuf],
|
||||
legacy: &std::path::Path,
|
||||
legacy_eframe: Option<&std::path::Path>,
|
||||
) -> std::io::Result<()> {
|
||||
let fresh = !current.exists();
|
||||
if let Some(old) = old_flatpak {
|
||||
for old in old_flatpak {
|
||||
solidcraft_engine::io::adopt_legacy_dir(current, old)?;
|
||||
}
|
||||
solidcraft_engine::io::adopt_legacy_dir(current, legacy)?;
|
||||
@@ -667,11 +750,14 @@ fn main() -> eframe::Result {
|
||||
let mut control_port: Option<u16> = solidcraft_engine::geom::env::var("CONTROL_PORT").and_then(|p| p.parse().ok());
|
||||
let mut files = Vec::new();
|
||||
let mut sample = false;
|
||||
// `--theme-file PATH`: follow that theme file for this run without saving it (#7573).
|
||||
let mut theme_file: Option<String> = None;
|
||||
let mut args = std::env::args().skip(1);
|
||||
while let Some(a) = args.next() {
|
||||
match a.as_str() {
|
||||
"--control" => control_port = args.next().and_then(|p| p.parse().ok()),
|
||||
"--sample" => sample = true,
|
||||
"--theme-file" => theme_file = args.next(),
|
||||
"--safe-mode" => safe_mode = true,
|
||||
"--version" | "-V" => {
|
||||
println!("solidcraft {}", env!("CARGO_PKG_VERSION"));
|
||||
@@ -691,7 +777,9 @@ fn main() -> eframe::Result {
|
||||
return Ok(());
|
||||
}
|
||||
"--help" | "-h" => {
|
||||
println!("usage: solidcraft [--control PORT] [--sample] [--crash-log] [--safe-mode] [design.solidcraft | part.step]");
|
||||
println!(
|
||||
"usage: solidcraft [--control PORT] [--sample] [--theme-file THEME.json] [--crash-log] [--safe-mode] [design.solidcraft | part.step]"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
_ => files.push(a),
|
||||
@@ -738,10 +826,12 @@ fn main() -> eframe::Result {
|
||||
solidcraft_engine::crash::install(dir, build)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
// A crash in native code (a graphics driver) says where it happened: the exception and the
|
||||
// module on Windows, and on every system the startup step the app was in.
|
||||
// A crash in native code (a graphics driver) says where it happened: the exception or signal
|
||||
// and the module on Windows and macOS, and on every system the startup step the app was in.
|
||||
#[cfg(target_os = "windows")]
|
||||
native_crash::install();
|
||||
#[cfg(target_os = "macos")]
|
||||
native_crash_macos::install();
|
||||
// Windows with only OpenGL to start: the system title bar instead of ours (#2063).
|
||||
let started = match &wgpu_options.wgpu_setup {
|
||||
eframe::egui_wgpu::WgpuSetup::CreateNew(setup) => setup.instance_descriptor.backends,
|
||||
@@ -817,7 +907,8 @@ fn main() -> eframe::Result {
|
||||
solidcraft_ui_egui::fonts::setup_bundled_fonts(&cc.egui_ctx);
|
||||
solidcraft_ui_egui::fonts::load_system_fonts_in_background(&cc.egui_ctx);
|
||||
mark("fonts");
|
||||
let mut app = SolveApp::new(Session::default(), services(cc));
|
||||
let dialog_folder = DialogFolder::default();
|
||||
let mut app = SolveApp::new(Session::default(), services(cc, &dialog_folder));
|
||||
app.apply_off_thread = Some(solidcraft_ui_egui::dialogs::APPLY_AT_ONCE);
|
||||
app.custom_titlebar = custom_titlebar;
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -840,6 +931,11 @@ fn main() -> eframe::Result {
|
||||
if let Some(p) = cc.storage.and_then(|s| solidcraft_ui_egui::prefs::stored(|k| s.get_string(k))).filter(|_| !safe_mode) {
|
||||
app.load_prefs(&p);
|
||||
}
|
||||
if let Some(path) = &theme_file
|
||||
&& let Err(e) = solidcraft_ui_egui::prefs::follow_theme_file_for_run(&mut app, path)
|
||||
{
|
||||
app.set_status(format!("--theme-file: {e}"), true);
|
||||
}
|
||||
mark("app state and prefs");
|
||||
let gpu = cc.wgpu_render_state.as_ref().map(|rs| LostWatch {
|
||||
lost: rs.device_lost.clone(),
|
||||
@@ -910,6 +1006,10 @@ fn main() -> eframe::Result {
|
||||
open_documents::set_ui(&cc.egui_ctx);
|
||||
[files, open_documents::take()].concat()
|
||||
};
|
||||
// No design given: the designs open at the last quit, when the preference asks (#5542).
|
||||
// Not when driven over the control channel, whose clients expect a fresh design.
|
||||
let files =
|
||||
if files.is_empty() && !sample && control_port.is_none() { solidcraft_ui_egui::documents::designs_to_reopen(&app) } else { files };
|
||||
for f in &files {
|
||||
app.open_path_async(f);
|
||||
}
|
||||
@@ -966,6 +1066,7 @@ fn main() -> eframe::Result {
|
||||
#[cfg(target_os = "macos")]
|
||||
native_menu,
|
||||
nav_bridge,
|
||||
dialog_folder,
|
||||
}))
|
||||
}),
|
||||
);
|
||||
@@ -1144,6 +1245,40 @@ mod backend_tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod dialog_folder_tests {
|
||||
use super::DialogFolder;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// #7756: a file dialog opens where the last one left off, not in the home folder.
|
||||
#[test]
|
||||
fn the_next_dialog_opens_in_the_folder_of_the_file_chosen_last() {
|
||||
let folder = DialogFolder::default();
|
||||
assert_eq!(folder.folder(), None, "before any choice the system decides");
|
||||
folder.chosen(Path::new("/work/prints/bracket.stl"));
|
||||
assert_eq!(folder.folder(), Some(PathBuf::from("/work/prints")));
|
||||
// A bare file name has no folder to remember.
|
||||
folder.chosen(Path::new("bracket.step"));
|
||||
assert_eq!(folder.folder(), Some(PathBuf::from("/work/prints")));
|
||||
}
|
||||
|
||||
/// Save As starts beside the open design (#7756), and a folder chosen since wins until another
|
||||
/// design is opened or saved.
|
||||
#[test]
|
||||
fn the_open_design_moves_the_folder_only_when_it_changes() {
|
||||
let folder = DialogFolder::default();
|
||||
folder.design(Some("/work/lid/lid.solidcraft"));
|
||||
assert_eq!(folder.folder(), Some(PathBuf::from("/work/lid")));
|
||||
folder.chosen(Path::new("/exports/lid.3mf"));
|
||||
folder.design(Some("/work/lid/lid.solidcraft"));
|
||||
assert_eq!(folder.folder(), Some(PathBuf::from("/exports")), "the same design again leaves the export folder");
|
||||
folder.design(None);
|
||||
assert_eq!(folder.folder(), Some(PathBuf::from("/exports")), "a new, unsaved design has no folder of its own");
|
||||
folder.design(Some("/work/base/base.solidcraft"));
|
||||
assert_eq!(folder.folder(), Some(PathBuf::from("/work/base")));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod viewport_tests {
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -1253,14 +1388,14 @@ mod msaa_tests {
|
||||
std::fs::create_dir_all(&legacy_eframe).unwrap();
|
||||
std::fs::write(legacy.join("graphics.json"), r#"{"msaa":8}"#).unwrap();
|
||||
std::fs::write(legacy_eframe.join("app.ron"), "(prefs)").unwrap();
|
||||
super::adopt_settings(¤t, None, &legacy, Some(&legacy_eframe)).unwrap();
|
||||
super::adopt_settings(¤t, &[], &legacy, Some(&legacy_eframe)).unwrap();
|
||||
assert_eq!(std::fs::read_to_string(current.join("graphics.json")).unwrap(), r#"{"msaa":8}"#);
|
||||
assert_eq!(std::fs::read_to_string(current.join("app.ron")).unwrap(), "(prefs)");
|
||||
assert!(legacy.join("graphics.json").is_file() && legacy_eframe.join("app.ron").is_file());
|
||||
// Later launches leave the current settings alone.
|
||||
std::fs::write(current.join("app.ron"), "(mine)").unwrap();
|
||||
std::fs::remove_file(current.join("graphics.json")).unwrap();
|
||||
super::adopt_settings(¤t, None, &legacy, Some(&legacy_eframe)).unwrap();
|
||||
super::adopt_settings(¤t, &[], &legacy, Some(&legacy_eframe)).unwrap();
|
||||
assert_eq!(std::fs::read_to_string(current.join("app.ron")).unwrap(), "(mine)");
|
||||
assert!(!current.join("graphics.json").exists());
|
||||
let _ = std::fs::remove_dir_all(&d);
|
||||
|
||||
@@ -0,0 +1,879 @@
|
||||
//! macOS: what a crash in native code leaves behind (docs/crash-reports.md).
|
||||
//!
|
||||
//! A crash inside a graphics driver or another library (a segfault, an `abort()`, a stack
|
||||
//! overflow) is no Rust panic: the panic hook never runs and the next start only found "an
|
||||
//! unclean exit". A signal handler for SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP (how a trap
|
||||
//! instruction arrives on Apple silicon) and SIGABRT now writes, before the process goes, the
|
||||
//! same small JSON file as the Windows filter (`native_crash.rs`): the signal, the faulting
|
||||
//! module and the offset into it, and a short frame-pointer walk, next to the run's crash journal
|
||||
//! (`solidcraft_engine::crash::native_paths`). The next start puts it into the unclean exit's
|
||||
//! report. The signal then goes on to the handler that was there before (the standard library's
|
||||
//! stack overflow message) or to the default action, so the process still dies of it and macOS
|
||||
//! still writes its own crash report (`~/Library/Logs/DiagnosticReports`; the file names the
|
||||
//! `pid` the JSON records).
|
||||
//!
|
||||
//! Installing a signal handler and asking dyld which image holds an address have no safe API,
|
||||
//! hence the `unsafe_code` allowance on this module (the app crate denies it). The handler runs
|
||||
//! on a thread that may have a broken heap, or on the small alternate stack after a stack
|
||||
//! overflow: it doesn't allocate, formats into a buffer on the stack, and only reads memory on
|
||||
//! the thread's own stack. It writes what it knows from the signal first and only then calls
|
||||
//! `dladdr` (not on POSIX's async-signal-safe list; it takes dyld's recursive reader lock and
|
||||
//! doesn't allocate) to name the modules, rewriting the file, so a hang or a fault in there
|
||||
//! still leaves a record.
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use std::ffi::{CStr, CString, c_int, c_void};
|
||||
use std::fmt::Write as _;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::sync::OnceLock;
|
||||
use std::sync::atomic::{AtomicBool, AtomicI32, AtomicUsize, Ordering};
|
||||
|
||||
use libc::{SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP, siginfo_t};
|
||||
|
||||
/// The signals a crash arrives as, in the order of [`PREVIOUS`].
|
||||
const SIGNALS: [c_int; 6] = [SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP, SIGABRT];
|
||||
/// Frames the walk records (the faulting instruction first).
|
||||
const MAX_FRAMES: usize = 24;
|
||||
/// A fault this far below a thread's stack is taken for a stack overflow.
|
||||
const GUARD: usize = 64 << 10;
|
||||
|
||||
/// Where the handler writes (NUL-terminated), set once by [`install`].
|
||||
static PATH: OnceLock<CString> = OnceLock::new();
|
||||
/// The handler that was installed before ours for each of [`SIGNALS`] (called after ours), as an
|
||||
/// address (`SIG_DFL` is 0, `SIG_IGN` 1), and its `sa_flags`.
|
||||
static PREVIOUS: [AtomicUsize; 6] = [const { AtomicUsize::new(libc::SIG_DFL) }; 6];
|
||||
static PREVIOUS_FLAGS: [AtomicI32; 6] = [const { AtomicI32::new(0) }; 6];
|
||||
/// The handler has started writing (a second signal while it does is only passed on).
|
||||
static BUSY: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// Catch native crashes from now on (after `solidcraft_engine::crash::install`; nothing without it).
|
||||
pub fn install() {
|
||||
let Some((info, _)) = solidcraft_engine::crash::native_paths() else { return };
|
||||
let Ok(path) = CString::new(info.as_os_str().as_bytes()) else { return };
|
||||
if PATH.set(path).is_err() {
|
||||
return;
|
||||
}
|
||||
for (slot, &signal) in SIGNALS.iter().enumerate() {
|
||||
// SAFETY: `sigaction` is plain data; all zeros is a valid (empty) value.
|
||||
let mut ours: libc::sigaction = unsafe { std::mem::zeroed() };
|
||||
ours.sa_sigaction = handler as *const () as usize;
|
||||
// On the alternate stack the standard library gives each of its threads, so that a stack
|
||||
// overflow can still be recorded.
|
||||
ours.sa_flags = libc::SA_SIGINFO | libc::SA_ONSTACK;
|
||||
// SAFETY: as above.
|
||||
let mut old: libc::sigaction = unsafe { std::mem::zeroed() };
|
||||
// SAFETY: `handler` has the signature SA_SIGINFO calls it with and stays valid for the
|
||||
// process's life; both structs are valid for the call.
|
||||
if unsafe { libc::sigaction(signal, &ours, &mut old) } == 0
|
||||
&& old.sa_sigaction != ours.sa_sigaction
|
||||
&& let (Some(p), Some(f)) = (PREVIOUS.get(slot), PREVIOUS_FLAGS.get(slot))
|
||||
{
|
||||
f.store(old.sa_flags, Ordering::SeqCst);
|
||||
p.store(old.sa_sigaction, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The signal handler: record, then pass the signal on.
|
||||
unsafe extern "C" fn handler(signal: c_int, info: *mut siginfo_t, context: *mut c_void) {
|
||||
// SAFETY: `__error` is this thread's errno, restored for whatever runs after us.
|
||||
let errno = unsafe { *libc::__error() };
|
||||
let slot = SIGNALS.iter().position(|&s| s == signal).unwrap_or(0);
|
||||
let previous = PREVIOUS.get(slot).map_or(libc::SIG_DFL, |p| p.load(Ordering::SeqCst));
|
||||
// SAFETY: the system passes a valid siginfo and the interrupted thread's context for the
|
||||
// duration of an SA_SIGINFO handler.
|
||||
let f = unsafe { fault(signal, info, context) };
|
||||
// Someone sent a signal the app ignored before: still nothing to record.
|
||||
let ignored = previous == libc::SIG_IGN && !f.fault;
|
||||
if !ignored && !BUSY.swap(true, Ordering::SeqCst) {
|
||||
record(&f);
|
||||
}
|
||||
// SAFETY: as above.
|
||||
unsafe { pass_on(signal, slot, previous, f.fault, info, context) };
|
||||
// SAFETY: as above.
|
||||
unsafe { *libc::__error() = errno };
|
||||
}
|
||||
|
||||
/// The signal comes from the faulting instruction itself (not `kill`, `raise` or `abort`), so
|
||||
/// returning runs it again: on arm64, the exception the thread last took matches the signal.
|
||||
/// macOS gives a SIGSEGV sent with `kill` the same `si_code` as a real one (SEGV_ACCERR), but
|
||||
/// the exception is then the thread's last system call (or something long past, whose fault
|
||||
/// address doesn't match).
|
||||
#[cfg(any(target_arch = "aarch64", test))]
|
||||
fn arm64_fault(signal: c_int, si_code: c_int, addr: usize, esr: u32, far: u64) -> bool {
|
||||
const ABORTS: [u32; 4] = [0x20, 0x21, 0x24, 0x25];
|
||||
const SVC: u32 = 0x15;
|
||||
let class = esr >> 26;
|
||||
signal != SIGABRT
|
||||
&& (1..0x10000).contains(&si_code)
|
||||
&& match signal {
|
||||
SIGSEGV | SIGBUS => ABORTS.contains(&class) && far as usize == addr,
|
||||
_ => class != SVC && !ABORTS.contains(&class),
|
||||
}
|
||||
}
|
||||
|
||||
/// As [`arm64_fault`], from the x86 trap number and page-fault address.
|
||||
#[cfg(any(target_arch = "x86_64", test))]
|
||||
fn x86_fault(signal: c_int, si_code: c_int, addr: usize, trapno: u16, faultvaddr: u64) -> bool {
|
||||
signal != SIGABRT
|
||||
&& (1..0x10000).contains(&si_code)
|
||||
&& match signal {
|
||||
SIGSEGV | SIGBUS => (trapno == 14 && faultvaddr as usize == addr) || matches!(trapno, 12 | 13),
|
||||
SIGILL => trapno == 6,
|
||||
SIGFPE => matches!(trapno, 0 | 16 | 19),
|
||||
SIGTRAP => matches!(trapno, 1 | 3),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Hand the signal to the previous handler, or to the default action. A crash signal that was
|
||||
/// only sent goes to the default action: the handler before ours (the standard library's, for
|
||||
/// SIGSEGV and SIGBUS) expects a fault that happens again when it returns.
|
||||
unsafe fn pass_on(signal: c_int, slot: usize, previous: usize, fault: bool, info: *mut siginfo_t, context: *mut c_void) {
|
||||
let ours = handler as *const () as usize;
|
||||
if previous != libc::SIG_DFL && previous != libc::SIG_IGN && previous != ours && (fault || signal == SIGABRT) {
|
||||
let flags = PREVIOUS_FLAGS.get(slot).map_or(0, |f| f.load(Ordering::SeqCst));
|
||||
if flags & libc::SA_SIGINFO != 0 {
|
||||
// SAFETY: the address came from `sigaction` as an SA_SIGINFO handler.
|
||||
let previous: unsafe extern "C" fn(c_int, *mut siginfo_t, *mut c_void) = unsafe { std::mem::transmute(previous) };
|
||||
// SAFETY: as for this handler.
|
||||
unsafe { previous(signal, info, context) };
|
||||
} else {
|
||||
// SAFETY: the address came from `sigaction` as a plain handler.
|
||||
let previous: unsafe extern "C" fn(c_int) = unsafe { std::mem::transmute(previous) };
|
||||
// SAFETY: as for this handler.
|
||||
unsafe { previous(signal) };
|
||||
}
|
||||
return;
|
||||
}
|
||||
if previous == libc::SIG_IGN && !fault {
|
||||
return;
|
||||
}
|
||||
// SAFETY: as in `install`.
|
||||
let mut default: libc::sigaction = unsafe { std::mem::zeroed() };
|
||||
default.sa_sigaction = libc::SIG_DFL;
|
||||
// SAFETY: a valid struct; restoring the default action is async-signal-safe.
|
||||
unsafe { libc::sigaction(signal, &default, std::ptr::null_mut()) };
|
||||
// A fault happens again when we return, now with the default action, so macOS reports it at
|
||||
// the instruction; anything else is raised again, and arrives once this handler returns.
|
||||
if !fault {
|
||||
// SAFETY: async-signal-safe.
|
||||
unsafe { libc::raise(signal) };
|
||||
}
|
||||
}
|
||||
|
||||
/// The darwin `ucontext_t`, up to the pointer to the machine context (`<sys/_types/_ucontext.h>`).
|
||||
#[repr(C)]
|
||||
struct UContext {
|
||||
_onstack: c_int,
|
||||
_sigmask: u32,
|
||||
_stack: libc::stack_t,
|
||||
_link: *mut c_void,
|
||||
_mcsize: usize,
|
||||
mcontext: *const MContext,
|
||||
}
|
||||
|
||||
/// The darwin arm64 machine context: exception state, then the general registers
|
||||
/// (`<mach/arm/_structs.h>`; the floating-point state that follows isn't read).
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[repr(C)]
|
||||
struct MContext {
|
||||
far: u64,
|
||||
esr: u32,
|
||||
_exception: u32,
|
||||
_x: [u64; 29],
|
||||
fp: u64,
|
||||
_lr: u64,
|
||||
_sp: u64,
|
||||
pc: u64,
|
||||
}
|
||||
|
||||
/// The darwin x86_64 machine context: exception state, then the general registers
|
||||
/// (`<mach/i386/_structs.h>`; rax rbx rcx rdx rdi rsi rbp rsp r8–r15, then rip).
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[repr(C)]
|
||||
struct MContext {
|
||||
trapno: u16,
|
||||
_cpu: u16,
|
||||
err: u32,
|
||||
faultvaddr: u64,
|
||||
gpr: [u64; 16],
|
||||
rip: u64,
|
||||
}
|
||||
|
||||
/// What the faulting instruction did to its address, when the processor says.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum Access {
|
||||
Unknown,
|
||||
Read,
|
||||
Write,
|
||||
Execute,
|
||||
}
|
||||
|
||||
/// What a crash signal says, read out of the signal before anything is looked up.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct Fault {
|
||||
signal: c_int,
|
||||
si_code: c_int,
|
||||
/// `si_addr`: the address that faulted (for SIGILL, SIGFPE and SIGTRAP, the instruction).
|
||||
addr: usize,
|
||||
pc: usize,
|
||||
fp: usize,
|
||||
access: Access,
|
||||
/// It comes from the faulting instruction (not `kill`, `raise` or `abort`).
|
||||
fault: bool,
|
||||
/// The process that sent the signal (0 or our own for a fault or an `abort()`).
|
||||
sender: i32,
|
||||
pid: i32,
|
||||
thread: u64,
|
||||
thread_name: [u8; 64],
|
||||
/// The thread's stack, `[low, high)` (0, 0 when unknown).
|
||||
stack: (usize, usize),
|
||||
}
|
||||
|
||||
impl Fault {
|
||||
/// The fault hit just below the thread's stack: the stack ran out.
|
||||
fn overflow(&self) -> bool {
|
||||
let (low, high) = self.stack;
|
||||
matches!(self.signal, SIGSEGV | SIGBUS) && high > low && self.addr < low.saturating_add(4096) && self.addr >= low.saturating_sub(GUARD)
|
||||
}
|
||||
|
||||
fn signal_name(&self) -> &'static str {
|
||||
match self.signal {
|
||||
SIGSEGV => "SIGSEGV",
|
||||
SIGBUS => "SIGBUS",
|
||||
SIGILL => "SIGILL",
|
||||
SIGFPE => "SIGFPE",
|
||||
SIGTRAP => "SIGTRAP",
|
||||
SIGABRT => "SIGABRT",
|
||||
_ => "signal",
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
if self.overflow() {
|
||||
return "stack overflow";
|
||||
}
|
||||
match self.signal {
|
||||
SIGSEGV => "segmentation fault",
|
||||
SIGBUS => "bus error",
|
||||
SIGILL => "illegal instruction",
|
||||
SIGFPE => "arithmetic exception",
|
||||
SIGTRAP => "trap",
|
||||
SIGABRT => "abort",
|
||||
_ => "signal",
|
||||
}
|
||||
}
|
||||
|
||||
/// The `si_code` names that say something about a crash.
|
||||
fn code_name(&self) -> Option<&'static str> {
|
||||
Some(match (self.signal, self.si_code) {
|
||||
(SIGSEGV, 1) => "SEGV_MAPERR",
|
||||
(SIGSEGV, 2) => "SEGV_ACCERR",
|
||||
(SIGBUS, 1) => "BUS_ADRALN",
|
||||
(SIGBUS, 2) => "BUS_ADRERR",
|
||||
(SIGBUS, 3) => "BUS_OBJERR",
|
||||
(SIGFPE, 7) => "FPE_INTDIV",
|
||||
(SIGFPE, 8) => "FPE_INTOVF",
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// One line on what happened: the address read or written, a stack overflow, who sent it.
|
||||
fn detail(&self, b: &mut Buf) {
|
||||
if self.sender != 0 && self.sender != self.pid {
|
||||
let _ = write!(b, "sent by process {}", self.sender);
|
||||
return;
|
||||
}
|
||||
if !self.fault {
|
||||
if self.signal != SIGABRT {
|
||||
let _ = b.write_str("sent with kill or raise, not a fault");
|
||||
}
|
||||
return;
|
||||
}
|
||||
let what = match self.access {
|
||||
Access::Read => "read of",
|
||||
Access::Write => "write to",
|
||||
Access::Execute => "execution at",
|
||||
Access::Unknown => "access to",
|
||||
};
|
||||
if self.overflow() {
|
||||
let _ = write!(b, "{what} 0x{:016X}, below the thread's stack", self.addr);
|
||||
} else if matches!(self.signal, SIGSEGV | SIGBUS) {
|
||||
let _ = write!(b, "{what} 0x{:016X}", self.addr);
|
||||
} else {
|
||||
let _ = write!(b, "at 0x{:016X}", self.addr);
|
||||
}
|
||||
if let Some(c) = self.code_name() {
|
||||
let _ = write!(b, " ({c})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An image that holds an address, as `dladdr` names it.
|
||||
struct Module<'a> {
|
||||
path: &'a [u8],
|
||||
base: usize,
|
||||
symbol: Option<(&'a [u8], usize)>,
|
||||
}
|
||||
|
||||
/// A fixed buffer to format into without allocating (what doesn't fit is cut off).
|
||||
struct Buf {
|
||||
bytes: [u8; 8192],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Buf {
|
||||
fn new() -> Buf {
|
||||
Buf { bytes: [0; 8192], len: 0 }
|
||||
}
|
||||
|
||||
fn room(&self) -> usize {
|
||||
self.bytes.len().saturating_sub(self.len)
|
||||
}
|
||||
|
||||
fn as_bytes(&self) -> &[u8] {
|
||||
self.bytes.get(..self.len).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// `s` as the inside of a JSON string, at most `max` bytes of it (bytes that aren't UTF-8
|
||||
/// and control characters become `?`).
|
||||
fn escaped(&mut self, s: &[u8], max: usize) {
|
||||
for chunk in s.get(..s.len().min(max)).unwrap_or_default().utf8_chunks() {
|
||||
for c in chunk.valid().chars() {
|
||||
let _ = match c {
|
||||
'"' => self.write_str("\\\""),
|
||||
'\\' => self.write_str("\\\\"),
|
||||
c if (c as u32) < 0x20 => self.write_str("?"),
|
||||
c => self.write_char(c),
|
||||
};
|
||||
}
|
||||
if !chunk.invalid().is_empty() {
|
||||
let _ = self.write_str("?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Write for Buf {
|
||||
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
||||
let n = s.len().min(self.room());
|
||||
if let (Some(to), Some(from)) = (self.bytes.get_mut(self.len..self.len + n), s.as_bytes().get(..n)) {
|
||||
to.copy_from_slice(from);
|
||||
self.len += n;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// The last part of a path.
|
||||
fn file_name(path: &[u8]) -> &[u8] {
|
||||
path.rsplit(|&c| c == b'/').next().unwrap_or(path)
|
||||
}
|
||||
|
||||
/// The report: what the signal says, then (with `resolve`) the module of the faulting
|
||||
/// instruction and the `frames`. Always valid JSON: frames stop while there is room to close it.
|
||||
fn json(b: &mut Buf, f: &Fault, frames: &[usize], resolve: impl Fn(usize, bool) -> Option<Module<'static>>) {
|
||||
let signal = f.signal_name();
|
||||
let _ = write!(b, "{{\"signal\":\"{signal}\",\"number\":{},\"code\":\"{signal}\",\"name\":\"{}\"", f.signal, f.name());
|
||||
let _ = write!(b, ",\"si_code\":{},\"address\":\"0x{:016X}\",\"thread\":{},\"pid\":{}", f.si_code, f.pc, f.thread, f.pid);
|
||||
let name = f.thread_name.split(|&c| c == 0).next().unwrap_or_default();
|
||||
if !name.is_empty() {
|
||||
let _ = b.write_str(",\"thread_name\":\"");
|
||||
b.escaped(name, 64);
|
||||
let _ = b.write_str("\"");
|
||||
}
|
||||
let mark = b.len;
|
||||
let _ = b.write_str(",\"detail\":\"");
|
||||
let start = b.len;
|
||||
f.detail(b);
|
||||
if b.len == start {
|
||||
b.len = mark;
|
||||
} else {
|
||||
let _ = b.write_str("\"");
|
||||
}
|
||||
if let Some(m) = resolve(f.pc, false) {
|
||||
let _ = write!(b, ",\"offset\":\"0x{:X}\",\"module\":\"", f.pc.wrapping_sub(m.base));
|
||||
b.escaped(m.path, 300);
|
||||
let _ = b.write_str("\"");
|
||||
}
|
||||
if !frames.is_empty() {
|
||||
let _ = b.write_str(",\"frames\":[");
|
||||
for (i, &at) in frames.iter().enumerate() {
|
||||
// A frame is at most ~300 bytes; keep room for it and the closing `]}`.
|
||||
if b.room() < 400 {
|
||||
break;
|
||||
}
|
||||
if i > 0 {
|
||||
let _ = b.write_str(",");
|
||||
}
|
||||
let _ = b.write_str("\"");
|
||||
// A return address points after the call: look up the call itself.
|
||||
match resolve(at, i > 0) {
|
||||
Some(m) => {
|
||||
b.escaped(file_name(m.path), 100);
|
||||
let _ = write!(b, "+0x{:X}", at.wrapping_sub(m.base));
|
||||
if let Some((symbol, start)) = m.symbol {
|
||||
let _ = b.write_str(" ");
|
||||
b.escaped(symbol, 160);
|
||||
let _ = write!(b, "+0x{:X}", at.wrapping_sub(start));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let _ = write!(b, "0x{at:016X}");
|
||||
}
|
||||
}
|
||||
let _ = b.write_str("\"");
|
||||
}
|
||||
let _ = b.write_str("]");
|
||||
}
|
||||
let _ = b.write_str("}");
|
||||
}
|
||||
|
||||
/// The return addresses up the frame-pointer chain from `fp`, after `pc`. `read` gives the word
|
||||
/// at an address; frames outside `stack`, misaligned or not going up end the walk.
|
||||
fn walk(pc: usize, fp: usize, stack: (usize, usize), read: impl Fn(usize) -> Option<usize>, out: &mut [usize; MAX_FRAMES]) -> usize {
|
||||
let (low, high) = stack;
|
||||
let mut n = 0;
|
||||
if let Some(slot) = out.get_mut(n) {
|
||||
*slot = pc;
|
||||
n += 1;
|
||||
}
|
||||
let mut fp = fp;
|
||||
while n < MAX_FRAMES {
|
||||
let in_stack = fp >= low && fp.checked_add(16).is_some_and(|end| end <= high);
|
||||
if !fp.is_multiple_of(8) || !in_stack {
|
||||
break;
|
||||
}
|
||||
let (Some(next), Some(ret)) = (read(fp), read(fp + 8)) else { break };
|
||||
let ret = strip_pointer_auth(ret);
|
||||
if ret == 0 {
|
||||
break;
|
||||
}
|
||||
if let Some(slot) = out.get_mut(n) {
|
||||
*slot = ret;
|
||||
n += 1;
|
||||
}
|
||||
if next <= fp {
|
||||
break;
|
||||
}
|
||||
fp = next;
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
/// Return addresses saved by arm64e code carry a signature in their top bits.
|
||||
fn strip_pointer_auth(addr: usize) -> usize {
|
||||
if cfg!(target_arch = "aarch64") { addr & 0x0000_7FFF_FFFF_FFFF } else { addr }
|
||||
}
|
||||
|
||||
/// Read what the signal and the interrupted thread's registers say.
|
||||
unsafe fn fault(signal: c_int, info: *const siginfo_t, context: *const c_void) -> Fault {
|
||||
let mut f = Fault {
|
||||
signal,
|
||||
si_code: 0,
|
||||
addr: 0,
|
||||
pc: 0,
|
||||
fp: 0,
|
||||
access: Access::Unknown,
|
||||
fault: false,
|
||||
sender: 0,
|
||||
// SAFETY: async-signal-safe.
|
||||
pid: unsafe { libc::getpid() },
|
||||
thread: 0,
|
||||
thread_name: [0; 64],
|
||||
stack: (0, 0),
|
||||
};
|
||||
if !info.is_null() {
|
||||
// SAFETY: the system passes a valid siginfo for the duration of the handler.
|
||||
let info = unsafe { &*info };
|
||||
f.si_code = info.si_code;
|
||||
f.addr = info.si_addr as usize;
|
||||
f.sender = info.si_pid;
|
||||
// Without registers (never seen), the signal's own code has to do.
|
||||
f.fault = signal != SIGABRT && (1..0x10000).contains(&f.si_code);
|
||||
}
|
||||
let context = context as *const UContext;
|
||||
// SAFETY: an SA_SIGINFO handler's third argument is the interrupted thread's ucontext, whose
|
||||
// machine context pointer the kernel fills in.
|
||||
let mcontext = if context.is_null() { std::ptr::null() } else { unsafe { (*context).mcontext } };
|
||||
if !mcontext.is_null() {
|
||||
// SAFETY: as above.
|
||||
let m = unsafe { &*mcontext };
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
f.pc = strip_pointer_auth(m.pc as usize);
|
||||
f.fp = m.fp as usize;
|
||||
f.fault = arm64_fault(signal, f.si_code, f.addr, m.esr, m.far);
|
||||
// A data abort says whether it was a write (WnR); an instruction abort is execution.
|
||||
f.access = match m.esr >> 26 {
|
||||
0x24 | 0x25 if m.esr & (1 << 6) != 0 => Access::Write,
|
||||
0x24 | 0x25 => Access::Read,
|
||||
0x20 | 0x21 => Access::Execute,
|
||||
_ => Access::Unknown,
|
||||
};
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
f.pc = m.rip as usize;
|
||||
f.fp = m.gpr.get(6).copied().unwrap_or(0) as usize;
|
||||
f.fault = x86_fault(signal, f.si_code, f.addr, m.trapno, m.faultvaddr);
|
||||
// A page fault's error code: bit 4 instruction fetch, bit 1 write.
|
||||
f.access = match (m.trapno, m.err) {
|
||||
(14, e) if e & 0x10 != 0 => Access::Execute,
|
||||
(14, e) if e & 0x2 != 0 => Access::Write,
|
||||
(14, _) => Access::Read,
|
||||
_ => Access::Unknown,
|
||||
};
|
||||
}
|
||||
}
|
||||
if f.pc == 0 && matches!(signal, SIGILL | SIGFPE | SIGTRAP) {
|
||||
f.pc = f.addr;
|
||||
}
|
||||
// SAFETY: these read the calling thread's own pthread structure; the buffers are as long as
|
||||
// we say.
|
||||
unsafe {
|
||||
let me = libc::pthread_self();
|
||||
libc::pthread_threadid_np(me, &mut f.thread);
|
||||
libc::pthread_getname_np(me, f.thread_name.as_mut_ptr().cast(), f.thread_name.len());
|
||||
let high = libc::pthread_get_stackaddr_np(me) as usize;
|
||||
let size = libc::pthread_get_stacksize_np(me);
|
||||
if let Some(low) = high.checked_sub(size) {
|
||||
f.stack = (low, high);
|
||||
}
|
||||
}
|
||||
f
|
||||
}
|
||||
|
||||
/// The image that holds `addr` (the call before it, for a return address).
|
||||
fn resolve(addr: usize, return_address: bool) -> Option<Module<'static>> {
|
||||
let at = if return_address { addr.saturating_sub(1) } else { addr };
|
||||
// SAFETY: `Dl_info` is plain data; all zeros is a valid value.
|
||||
let mut info: libc::Dl_info = unsafe { std::mem::zeroed() };
|
||||
// SAFETY: `dladdr` only reads dyld's image list; the strings it returns live as long as the
|
||||
// image, which a crashing process never unloads.
|
||||
unsafe {
|
||||
if libc::dladdr(at as *const c_void, &mut info) == 0 || info.dli_fname.is_null() {
|
||||
return None;
|
||||
}
|
||||
let symbol = (!info.dli_sname.is_null()).then(|| (CStr::from_ptr(info.dli_sname).to_bytes(), info.dli_saddr as usize));
|
||||
Some(Module { path: CStr::from_ptr(info.dli_fname).to_bytes(), base: info.dli_fbase as usize, symbol })
|
||||
}
|
||||
}
|
||||
|
||||
/// Write what the signal says into the info file, then again with the modules and frames.
|
||||
fn record(f: &Fault) {
|
||||
let Some(path) = PATH.get() else { return };
|
||||
// SAFETY: NUL-terminated path; the descriptor is closed below.
|
||||
let fd = unsafe { libc::open(path.as_ptr(), libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC | libc::O_CLOEXEC, 0o600) };
|
||||
if fd < 0 {
|
||||
return;
|
||||
}
|
||||
let mut b = Buf::new();
|
||||
json(&mut b, f, &[], |_, _| None);
|
||||
let bytes = b.as_bytes();
|
||||
// SAFETY: the buffer is as long as we say.
|
||||
unsafe { libc::write(fd, bytes.as_ptr().cast(), bytes.len()) };
|
||||
let mut frames = [0usize; MAX_FRAMES];
|
||||
// SAFETY: `walk` only reads inside the thread's own stack, 8-byte aligned.
|
||||
let n = walk(f.pc, f.fp, f.stack, |at| Some(unsafe { (at as *const usize).read() }), &mut frames);
|
||||
b.len = 0;
|
||||
json(&mut b, f, frames.get(..n).unwrap_or_default(), resolve);
|
||||
let bytes = b.as_bytes();
|
||||
// SAFETY: as above.
|
||||
unsafe {
|
||||
if libc::pwrite(fd, bytes.as_ptr().cast(), bytes.len(), 0) == bytes.len() as isize {
|
||||
libc::ftruncate(fd, bytes.len() as libc::off_t);
|
||||
}
|
||||
libc::close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::*;
|
||||
|
||||
fn fault(signal: c_int, si_code: c_int, addr: usize) -> Fault {
|
||||
let mut thread_name = [0u8; 64];
|
||||
thread_name[..4].copy_from_slice(b"main");
|
||||
Fault {
|
||||
signal,
|
||||
si_code,
|
||||
addr,
|
||||
pc: 0x1_0000_1234,
|
||||
fp: 0,
|
||||
access: Access::Read,
|
||||
fault: true,
|
||||
sender: 0,
|
||||
pid: 77,
|
||||
thread: 4242,
|
||||
thread_name,
|
||||
stack: (0x7000_0000, 0x7080_0000),
|
||||
}
|
||||
}
|
||||
|
||||
fn report(f: &Fault, frames: &[usize]) -> serde_json::Value {
|
||||
let mut b = Buf::new();
|
||||
json(&mut b, f, frames, |at, _| {
|
||||
(at >= 0x1_0000_0000).then_some(Module {
|
||||
path: b"/Applications/SolidCraft.app/Contents/MacOS/solidcraft",
|
||||
base: 0x1_0000_0000,
|
||||
symbol: Some((b"_ZN4main17h0123456789abcdefE", 0x1_0000_1200)),
|
||||
})
|
||||
});
|
||||
serde_json::from_slice(b.as_bytes()).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_segfault_says_the_signal_the_address_read_and_the_module() {
|
||||
let v = report(&fault(SIGSEGV, 1, 0x10), &[0x1_0000_1234, 0x1_0000_2000, 0x5000]);
|
||||
assert_eq!(v["signal"], "SIGSEGV");
|
||||
assert_eq!(v["code"], "SIGSEGV");
|
||||
assert_eq!(v["name"], "segmentation fault");
|
||||
assert_eq!(v["detail"], "read of 0x0000000000000010 (SEGV_MAPERR)");
|
||||
assert_eq!(v["address"], "0x0000000100001234");
|
||||
assert_eq!(v["module"], "/Applications/SolidCraft.app/Contents/MacOS/solidcraft");
|
||||
assert_eq!(v["offset"], "0x1234");
|
||||
assert_eq!(v["thread"], 4242);
|
||||
assert_eq!(v["thread_name"], "main");
|
||||
assert_eq!(v["pid"], 77);
|
||||
let frames: Vec<&str> = v["frames"].as_array().unwrap().iter().map(|f| f.as_str().unwrap()).collect();
|
||||
assert_eq!(
|
||||
frames,
|
||||
["solidcraft+0x1234 _ZN4main17h0123456789abcdefE+0x34", "solidcraft+0x2000 _ZN4main17h0123456789abcdefE+0xE00", "0x0000000000005000"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_fault_below_the_stack_is_a_stack_overflow() {
|
||||
let mut f = fault(SIGBUS, 2, 0x7000_0000 - 0x100);
|
||||
f.access = Access::Write;
|
||||
let v = report(&f, &[]);
|
||||
assert_eq!(v["name"], "stack overflow");
|
||||
assert_eq!(v["code"], "SIGBUS");
|
||||
assert_eq!(v["detail"], "write to 0x000000006FFFFF00, below the thread's stack (BUS_ADRERR)");
|
||||
// Far below it, or inside it, it is not.
|
||||
assert_eq!(report(&fault(SIGBUS, 2, 0x10), &[])["name"], "bus error");
|
||||
assert_eq!(report(&fault(SIGSEGV, 2, 0x7040_0000), &[])["name"], "segmentation fault");
|
||||
// Nor without knowing the stack.
|
||||
let mut f = fault(SIGSEGV, 1, 0x7000_0000 - 0x100);
|
||||
f.stack = (0, 0);
|
||||
assert_eq!(report(&f, &[])["name"], "segmentation fault");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_abort_or_a_signal_sent_by_another_process_has_no_address_detail() {
|
||||
let mut f = fault(SIGABRT, 0, 0);
|
||||
f.fault = false;
|
||||
f.sender = 77;
|
||||
let v = report(&f, &[]);
|
||||
assert_eq!(v["signal"], "SIGABRT");
|
||||
assert_eq!(v["name"], "abort");
|
||||
assert!(v.get("detail").is_none(), "{v}");
|
||||
let mut f = fault(SIGSEGV, 0x10001, 0);
|
||||
f.fault = false;
|
||||
f.sender = 501;
|
||||
assert_eq!(report(&f, &[])["detail"], "sent by process 501");
|
||||
// `kill` without a sender, or `raise`.
|
||||
f.sender = 0;
|
||||
assert_eq!(report(&f, &[])["detail"], "sent with kill or raise, not a fault");
|
||||
// A trap names the instruction.
|
||||
assert_eq!(report(&fault(SIGTRAP, 1, 0x1_0000_1234), &[])["detail"], "at 0x0000000100001234");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_a_fault_runs_again_when_the_handler_returns() {
|
||||
// Measured on an M5 Pro, macOS 27: a read of address 16, then `kill -SEGV` while the
|
||||
// thread waits in a system call. Both have si_code 2.
|
||||
assert!(arm64_fault(SIGSEGV, 2, 0x10, 0x9200_0046, 0x10));
|
||||
assert!(!arm64_fault(SIGSEGV, 2, 0, 0x5600_0080, 0));
|
||||
assert!(!arm64_fault(SIGBUS, 1, 0, 0x5600_0080, 0));
|
||||
// A data abort long past, while the signal names no address.
|
||||
assert!(!arm64_fault(SIGSEGV, 2, 0, 0x9200_0046, 0x10));
|
||||
// A trap instruction (BRK) or an undefined one; but not a system call.
|
||||
assert!(arm64_fault(SIGTRAP, 1, 0x1000, 0xF200_0001, 0));
|
||||
assert!(arm64_fault(SIGILL, 1, 0x1000, 0x0200_0000, 0));
|
||||
assert!(!arm64_fault(SIGILL, 1, 0x1000, 0x5600_0080, 0));
|
||||
// Sent: SI_USER, no code, or an abort.
|
||||
assert!(!arm64_fault(SIGSEGV, 0x10001, 0x10, 0x9200_0046, 0x10));
|
||||
assert!(!arm64_fault(SIGTRAP, 0, 0, 0xF200_0001, 0));
|
||||
assert!(!arm64_fault(SIGABRT, 1, 0, 0x5600_0080, 0));
|
||||
// x86_64: a page fault at its address, a general protection fault, ud2, int3.
|
||||
assert!(x86_fault(SIGSEGV, 1, 0x10, 14, 0x10));
|
||||
assert!(!x86_fault(SIGSEGV, 1, 0, 14, 0x10));
|
||||
assert!(x86_fault(SIGSEGV, 1, 0, 13, 0));
|
||||
assert!(x86_fault(SIGILL, 1, 0x1000, 6, 0));
|
||||
assert!(x86_fault(SIGTRAP, 1, 0x1000, 3, 0));
|
||||
assert!(!x86_fault(SIGILL, 1, 0x1000, 14, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn names_with_quotes_control_characters_or_bad_utf8_stay_valid_json() {
|
||||
let mut f = fault(SIGILL, 1, 0x1_0000_1234);
|
||||
f.thread_name = [0; 64];
|
||||
f.thread_name[..7].copy_from_slice(b"a\"b\\\n\xFFc");
|
||||
let v = report(&f, &[]);
|
||||
assert_eq!(v["thread_name"], "a\"b\\??c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_report_with_long_names_still_closes_its_json() {
|
||||
let long: &'static [u8] = Box::leak(vec![b'x'; 4000].into_boxed_slice());
|
||||
let f = fault(SIGSEGV, 1, 0x10);
|
||||
let mut b = Buf::new();
|
||||
json(&mut b, &f, &[0x1_0000_1234; MAX_FRAMES], |_, _| Some(Module { path: long, base: 0x1_0000_0000, symbol: Some((long, 0x1_0000_0000)) }));
|
||||
let v: serde_json::Value = serde_json::from_slice(b.as_bytes()).unwrap();
|
||||
assert_eq!(v["module"].as_str().unwrap().len(), 300);
|
||||
let frames = v["frames"].as_array().unwrap();
|
||||
assert!(!frames.is_empty() && frames.len() <= MAX_FRAMES, "{}", frames.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_frame_walk_stays_on_the_stack_and_goes_up() {
|
||||
let stack = (0x1000, 0x2000);
|
||||
// Three frames: 0x1100 -> 0x1200 -> 0x1300 -> 0 (end).
|
||||
let memory = |at: usize| match at {
|
||||
0x1100 => Some(0x1200),
|
||||
0x1108 => Some(0xA),
|
||||
0x1200 => Some(0x1300),
|
||||
0x1208 => Some(0xB),
|
||||
0x1300 => Some(0),
|
||||
0x1308 => Some(0xC),
|
||||
_ => None,
|
||||
};
|
||||
let mut out = [0; MAX_FRAMES];
|
||||
let n = walk(0x9, 0x1100, stack, memory, &mut out);
|
||||
assert_eq!(&out[..n], &[0x9, 0xA, 0xB, 0xC]);
|
||||
// A frame pointer off the stack, misaligned, or one that doesn't go up ends the walk.
|
||||
assert_eq!(walk(0x9, 0x3000, stack, memory, &mut out), 1);
|
||||
assert_eq!(walk(0x9, 0x1101, stack, memory, &mut out), 1);
|
||||
let looping = |at: usize| if at.is_multiple_of(16) { Some(at) } else { Some(0xA) };
|
||||
assert_eq!(walk(0x9, 0x1100, stack, looping, &mut out), 2);
|
||||
// A chain that never ends stops at MAX_FRAMES.
|
||||
let endless = |at: usize| if at.is_multiple_of(16) { Some(at + 16) } else { Some(0xA) };
|
||||
assert_eq!(walk(0x9, 0x1000, stack, endless, &mut out), MAX_FRAMES);
|
||||
}
|
||||
|
||||
/// The child half: install crash reporting and the handler, then crash the way
|
||||
/// `SOLIDCRAFT_NATIVE_CRASH_FAULT` says.
|
||||
#[test]
|
||||
fn child() {
|
||||
let Some(dir) = std::env::var_os("SOLIDCRAFT_NATIVE_CRASH_CHILD") else { return };
|
||||
let build = solidcraft_engine::crash::Build { version: "9.9.9", commit: "abc1234", built: "2026-10-25" };
|
||||
let fresh = solidcraft_engine::crash::install(PathBuf::from(dir), build);
|
||||
println!("FRESH {}", serde_json::to_string(&fresh).unwrap_or_default());
|
||||
let Some(fault) = std::env::var_os("SOLIDCRAFT_NATIVE_CRASH_FAULT") else {
|
||||
solidcraft_engine::crash::end_session();
|
||||
return;
|
||||
};
|
||||
super::install();
|
||||
solidcraft_engine::crash::phase("device creation");
|
||||
match fault.to_str() {
|
||||
Some("abort") => std::process::abort(),
|
||||
Some("overflow") => println!("unreachable {}", recurse(0)),
|
||||
Some("raise") => {
|
||||
// SAFETY: none needed; this is the crash under test.
|
||||
unsafe { libc::raise(SIGSEGV) };
|
||||
println!("survived");
|
||||
}
|
||||
_ => segfault(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs out of stack.
|
||||
#[inline(never)]
|
||||
fn recurse(n: u64) -> u64 {
|
||||
let a = std::hint::black_box([n; 64]);
|
||||
if n == u64::MAX { 0 } else { recurse(n + 1).wrapping_add(a[0]) }
|
||||
}
|
||||
|
||||
/// The crash under test: a read of address 16, as a null struct pointer's field would be.
|
||||
#[inline(never)]
|
||||
fn segfault() {
|
||||
// SAFETY: none; this is the crash under test.
|
||||
let v = unsafe { std::ptr::read_volatile(std::hint::black_box(16usize) as *const u64) };
|
||||
println!("unreachable {v}");
|
||||
}
|
||||
|
||||
fn run(dir: &Path, fault: Option<&str>) -> std::process::Output {
|
||||
let mut c = std::process::Command::new(std::env::current_exe().unwrap());
|
||||
c.args(["--exact", "native_crash_macos::tests::child", "--test-threads=1", "--nocapture"]).env("SOLIDCRAFT_NATIVE_CRASH_CHILD", dir);
|
||||
if let Some(f) = fault {
|
||||
c.env("SOLIDCRAFT_NATIVE_CRASH_FAULT", f);
|
||||
}
|
||||
c.output().unwrap()
|
||||
}
|
||||
|
||||
/// Crash a child the way `fault` says; returns what the handler wrote and the next start's report.
|
||||
fn crash(name: &str, fault: &str, signal: c_int) -> (serde_json::Value, serde_json::Value, String) {
|
||||
let dir = std::env::temp_dir().join(format!("solidcraft-native-crash-{name}-{}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
let out = run(&dir, Some(fault));
|
||||
assert_eq!(out.status.signal(), Some(signal), "the child died of the signal itself: {out:?}");
|
||||
let stderr = String::from_utf8_lossy(&out.stderr).into_owned();
|
||||
let info =
|
||||
std::fs::read_dir(dir.join("sessions")).unwrap().flatten().map(|e| e.path()).find(|p| p.to_string_lossy().ends_with(".native.json"));
|
||||
let info = info.expect("the handler wrote what it caught");
|
||||
let v: serde_json::Value = serde_json::from_slice(&std::fs::read(info).unwrap()).unwrap();
|
||||
// The next start reports it.
|
||||
let out = run(&dir, None);
|
||||
assert!(out.status.success(), "{out:?}");
|
||||
let reports = solidcraft_engine::crash::list(&dir);
|
||||
assert_eq!(reports.len(), 1, "{reports:?}");
|
||||
let r = solidcraft_engine::crash::read(&dir, &reports[0].id).unwrap();
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
(v, r, stderr)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_segfault_is_reported_with_its_signal_module_frames_and_step() {
|
||||
let (v, r, _) = crash("segv", "segv", SIGSEGV);
|
||||
assert_eq!(v["signal"], "SIGSEGV", "{v}");
|
||||
// Address 16 is in __PAGEZERO, mapped without access: SEGV_ACCERR.
|
||||
assert_eq!(v["detail"], "read of 0x0000000000000010 (SEGV_ACCERR)", "{v}");
|
||||
assert!(v["module"].as_str().unwrap().contains("solidcraft"), "the fault is in the test binary: {v}");
|
||||
let frames = v["frames"].as_array().unwrap();
|
||||
assert!(frames.len() >= 3, "{v}");
|
||||
assert!(frames.iter().any(|f| f.as_str().unwrap().contains("child")), "the walk reaches the test that crashed: {v}");
|
||||
let message = r["message"].as_str().unwrap();
|
||||
assert!(message.contains("segmentation fault (SIGSEGV) in solidcraft"), "{r}");
|
||||
assert!(message.contains("during startup (device creation"), "{r}");
|
||||
assert_eq!(r["kind"], "unclean_exit");
|
||||
assert_eq!(r["native"]["signal"], "SIGSEGV");
|
||||
assert!(r["backtrace"].as_array().unwrap().iter().any(|f| f.as_str().unwrap().contains("segfault")), "{r}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_abort_is_reported_as_sigabrt_with_the_code_that_called_it() {
|
||||
let (v, r, _) = crash("abrt", "abort", SIGABRT);
|
||||
assert_eq!(v["signal"], "SIGABRT", "{v}");
|
||||
assert!(v.get("detail").is_none(), "{v}");
|
||||
let frames = v["frames"].as_array().unwrap();
|
||||
assert!(frames.iter().any(|f| f.as_str().unwrap().contains("abort")), "{v}");
|
||||
assert!(r["message"].as_str().unwrap().contains("abort (SIGABRT)"), "{r}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_stack_overflow_is_recorded_and_the_standard_library_still_says_so() {
|
||||
// The fault on the guard page is recorded on the alternate stack; the standard library's
|
||||
// handler, called after ours, prints its message and aborts.
|
||||
let (v, r, stderr) = crash("overflow", "overflow", SIGABRT);
|
||||
assert!(matches!(v["signal"].as_str(), Some("SIGSEGV" | "SIGBUS")), "{v}");
|
||||
assert_eq!(v["name"], "stack overflow", "{v}");
|
||||
assert!(v["detail"].as_str().unwrap().contains("below the thread's stack"), "{v}");
|
||||
assert!(stderr.contains("has overflowed its stack"), "{stderr}");
|
||||
assert!(r["message"].as_str().unwrap().contains("stack overflow ("), "{r}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_segfault_signal_that_was_only_sent_still_ends_the_app() {
|
||||
// The standard library's handler, which comes before ours, returns expecting the fault
|
||||
// to happen again; a sent signal never does, so it goes to the default action instead.
|
||||
let (v, r, _) = crash("raise", "raise", SIGSEGV);
|
||||
assert_eq!(v["detail"], "sent with kill or raise, not a fault", "{v}");
|
||||
assert!(r["message"].as_str().unwrap().contains("(SIGSEGV)"), "{r}");
|
||||
}
|
||||
}
|
||||
@@ -146,8 +146,7 @@ impl NativeMenu {
|
||||
}
|
||||
|
||||
fn action_enabled(action: &FileAction, app: &SolveApp, ctx: &egui::Context) -> bool {
|
||||
action.enabled(app)
|
||||
|| (matches!(action, FileAction::Undo | FileAction::Redo) && ctx.egui_wants_keyboard_input() && FileAction::Settings.enabled(app))
|
||||
action.menu_enabled(app, ctx.egui_wants_keyboard_input())
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, app: &mut SolveApp, ctx: &egui::Context) {
|
||||
@@ -157,6 +156,12 @@ impl NativeMenu {
|
||||
item.set_enabled(enabled);
|
||||
}
|
||||
}
|
||||
for (item, action) in &self.help_actions {
|
||||
let enabled = solidcraft_ui_egui::help::available(app, action);
|
||||
if item.is_enabled() != enabled {
|
||||
item.set_enabled(enabled);
|
||||
}
|
||||
}
|
||||
if !self.recent_paths.iter().eq(app.home.recent.iter().take(32))
|
||||
&& let Err(error) = self.update_recent(app)
|
||||
{
|
||||
|
||||
@@ -543,9 +543,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn probing_a_backend_alone_never_panics() {
|
||||
// Whatever this machine has (often nothing): an answer, not a crash.
|
||||
for b in WINDOWS_ORDER {
|
||||
let _ = has_hardware_adapter(b);
|
||||
// Whatever this machine has (often nothing): an answer, not a crash. On Windows the probe
|
||||
// goes the way the app's does, stopping at the first backend with a GPU: a machine with
|
||||
// D3D12 never loads its OpenGL driver into the test process, and AMD's (`atio6axx.dll`)
|
||||
// aborted the process as it exited (#1156).
|
||||
if cfg!(target_os = "windows") {
|
||||
let _ = choose_backends(true, false, false, None, has_hardware_adapter);
|
||||
} else {
|
||||
for b in WINDOWS_ORDER {
|
||||
let _ = has_hardware_adapter(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,8 +565,18 @@ mod tests {
|
||||
#[test]
|
||||
fn the_software_adapter_is_preferred_and_its_absence_is_an_error_not_a_panic() {
|
||||
assert!(pick_cpu_adapter(&[], None).unwrap_err().contains("none"));
|
||||
let instance = eframe::wgpu::Instance::new(eframe::wgpu::InstanceDescriptor::new_without_display_handle());
|
||||
let adapters = pollster::block_on(instance.enumerate_adapters(eframe::wgpu::Backends::all()));
|
||||
// The adapters the software renderer chooses among: it starts D3D12 alone on Windows
|
||||
// (WARP), not every backend, so the test doesn't load the OpenGL driver either (#1156).
|
||||
let options = crate::wgpu_options(true, None);
|
||||
let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &options.wgpu_setup else { panic!("the software renderer makes its own device") };
|
||||
let backends = setup.instance_descriptor.backends;
|
||||
if cfg!(target_os = "windows") && std::env::var_os(WGPU_BACKEND_ENV).is_none() {
|
||||
assert_eq!(backends, eframe::wgpu::Backends::DX12);
|
||||
}
|
||||
let mut desc = eframe::wgpu::InstanceDescriptor::new_without_display_handle_from_env();
|
||||
desc.backends = backends;
|
||||
let instance = eframe::wgpu::Instance::new(desc);
|
||||
let adapters = pollster::block_on(instance.enumerate_adapters(backends));
|
||||
if adapters.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ The CLI still supports arbitrary PNG/ICO exports with `solidcraft-cli icon`.
|
||||
| macOS | Composer master and paired exports; bundle installs `Assets.car` and `SolidCraft.icns` |
|
||||
| Windows executable | `solidcraft-executable.ico`: original DIB/mask representations at 16/24/32/48/64/128/256 px |
|
||||
| Windows installer | `solidcraft.ico`: PNG representations at 16/20/24/32/40/48/64/128/256 px; `SOLIDCRAFT_ICONS` override retained |
|
||||
| Linux, Nix, deb/rpm, tar, Flatpak, Snap | Copy canonical hicolor images; icon name stays `ai.storyteller.solidcraft` |
|
||||
| Linux, Nix, deb/rpm, tar, Flatpak, Snap | Copy canonical hicolor images; icon name stays `io.tangencylabs.solidcraft` |
|
||||
| AppImage | Uses the Linux 256 px image and `.DirIcon` alias |
|
||||
| FreeBSD | Shares Linux hicolor images and freedesktop metadata |
|
||||
| Web | HTML/Trunk and `manifest.webmanifest` stay in `apps/solidcraft-web/`; copies Japanese font/licence to `fonts/`, uses the collected CSS, and copies the Linux 32/256/512 px images to `icons/` for the favicon and installed app |
|
||||
|
||||
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 660 B After Width: | Height: | Size: 660 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,93 @@
|
||||
# Render workspace icon drafts
|
||||
|
||||
All ids below are **Open** for owner review, except `render_scene` and `render_image`,
|
||||
which are existing accepted icons used only as references. No commands, toolbar
|
||||
entries, browser selectors or runtime request manifests are changed by this draft set.
|
||||
`render_remove_override` is the one remaining alias (of `render_from_material`);
|
||||
`render_execute`, `render_environment` and `render_fit_product` now have their own
|
||||
masters in `design/svg/model/`. Accepted source masters stay unchanged.
|
||||
|
||||
Review with `python3 -B assets/icons/ui/design/tools/icon_status.py --serve`,
|
||||
search `render_`, and select Open. See [STYLE_GUIDE.md](STYLE_GUIDE.md) for
|
||||
acceptance; drafts do not imply implemented commands.
|
||||
|
||||
The finished references in each row were read and previewed in both themes
|
||||
before authoring. Draft contact sheets (96, 24 and 16 px, both themes) are local
|
||||
review evidence, not shipped assets. The icons are grouped in five families, each
|
||||
with one shared design rule.
|
||||
|
||||
## Lights
|
||||
|
||||
Rule: a slate source glyph with light passive fill, 2.55-unit outlines and a dotted
|
||||
accent stem (three dots, 4.25 diameter, 7 units apart) showing the direction.
|
||||
|
||||
| Meaning | Id | Finished references | Drawing |
|
||||
|---|---|---|---|
|
||||
| Light area | `render_light_area` | `box`, `camera` | Slanted flat panel on the canonical axes above the dotted stem. |
|
||||
| Light spot | `render_light_spot` | `camera`, `material` | Cone with a curved rim above the dotted stem. |
|
||||
| Light point | `render_light_point` | `camera`, `material` | Round source disc with a centre dot above the dotted stem. |
|
||||
| Sun | `render_sun` | `sphere`, `camera` | Source disc of the same size with eight short radial rays instead of a stem. |
|
||||
| Light by highlight | `render_light_by_highlight` | `sphere`, `material` | Shaded sphere with a ringed highlight target; the dotted stem arrives from above. |
|
||||
| Solo light | `render_solo_light` | `fit`, `camera` | Point source and stem inside four corner focus brackets. |
|
||||
|
||||
## Looks
|
||||
|
||||
Rule: the lit look sphere (top-left highlight, bottom-right shade) plus one cue that
|
||||
says what happens to it; receiving bodies stay canonical grey or cube shapes.
|
||||
|
||||
| Meaning | Id | Finished references | Drawing |
|
||||
|---|---|---|---|
|
||||
| Appearance | `render_appearance` | `material`, `box` | Shaded look sphere on the top corner of an accent-shaded cube: a look assigned to a body. |
|
||||
| Paint | `render_paint` | `material`, `paste` | Flat brush with an accent tip, light ferrule and slate handle. |
|
||||
| Pick up | `render_pick_up` | `material`, `copy` | Eyedropper with a grey bulb, slate crossbar and accent sampling tip. |
|
||||
| Replace all | `render_replace_all` | `copy`, `box` | Grey sample sphere with an arrow to an accent sphere, beside a second accent sphere. |
|
||||
| Copy look | `render_copy_look` | `material`, `copy` | Look sphere in a square frame, offset from a second frame outline. |
|
||||
| Remove override | `render_remove_override` | `appearance`, `box` | Alias of `render_from_material`: the custom look is crossed off. |
|
||||
| Same look | `render_same_look` | `select`, `box` | Look sphere and three cubes; the two matching cubes are ringed. |
|
||||
| From material | `render_from_material` | `material`, `extrude` | Look sphere struck through above a plain grey slab, so the material shows. |
|
||||
|
||||
## Studio
|
||||
|
||||
Rule: the standard grey cube stands in the set-up it is lit or placed in.
|
||||
|
||||
| Meaning | Id | Finished references | Drawing |
|
||||
|---|---|---|---|
|
||||
| Library | `render_library` | `library`, `copy` | Row of three look spheres, the middle one accent, on a shelf bar. |
|
||||
| Lighting presets | `render_lighting_presets` | `new`, `render_scene` | Two stacked cards, the front one holding a light bulb. |
|
||||
| Environment | `render_environment` | `environment_map`, `render_scene` | Dome with a grey cube inside. |
|
||||
| Ground | `render_ground` | `box`, `render_scene` | Grey cube on a slab with an accent contact patch. |
|
||||
| Backdrop | `render_backdrop` | `render_scene`, `render_image` | Grey cube in front of a tall upright accent panel. |
|
||||
|
||||
## Camera and shots
|
||||
|
||||
Rule: one chunky camera body with a lower-right round badge for shot actions; the
|
||||
other camera icons are simple frames.
|
||||
|
||||
| Meaning | Id | Finished references | Drawing |
|
||||
|---|---|---|---|
|
||||
| Shot | `render_shot` | `camera`, `new` | Camera body with a plus badge: save a shot. |
|
||||
| Update shot | `render_update_shot` | `camera`, `undo` | Camera body with a refresh badge. |
|
||||
| Render all shots | `render_all_shots` | `copy`, `render_image` | Stacked camera bodies with a play badge. |
|
||||
| Shots strip | `render_shots_strip` | `camera`, `copy` | Strip of three small frames, the middle one in accent. |
|
||||
| Fit product | `render_fit_product` | `fit`, `camera` | Grey cube inside four corner brackets. |
|
||||
| Lens / field of view | `render_lens` | `camera`, `fit` | Concentric lens rings around an accent centre. |
|
||||
| Exposure | `render_exposure` | `material`, `environment_map` | Disc split light and accent, with plus and minus marks. |
|
||||
| Aspect frame | `render_aspect_frame` | `render_image`, `fit` | Wide rounded frame with two opposite corner brackets. |
|
||||
| Frame guides | `render_frame_guides` | `render_image`, `fit` | Rounded frame with a rule-of-thirds grid and four accent nodes. |
|
||||
|
||||
## Output and result
|
||||
|
||||
Rule: one picture base (frame with landscape) with a lower-right round badge; the
|
||||
size, background and quality icons draw their own simple subject.
|
||||
|
||||
| Meaning | Id | Finished references | Drawing |
|
||||
|---|---|---|---|
|
||||
| Render image | `render_execute` | `render_image`, `camera` | Picture with a play badge: create a rendered image. |
|
||||
| Render output size | `render_output_size` | `render_image`, `fit` | Picture frame with a diagonal double-headed dimension arrow. |
|
||||
| Transparent background | `render_transparent_background` | `material`, `render_image` | Grey cube on a checker tile. |
|
||||
| Quality | `render_quality` | `list`, `library` | Three rising bars, the tallest in accent. |
|
||||
| Check render | `render_check` | `render_image`, `new` | Picture with a check badge. |
|
||||
| Cancel render | `render_cancel` | `render_image`, `delete` | Picture with a square stop badge. |
|
||||
| Export image | `render_export_image` | `render_image`, `copy` | Picture with a large outward diagonal arrow at the upper right. |
|
||||
| Compare | `render_compare` | `render_image`, `material` | Two grey pictures split by a vertical slider with opposed arrows. |
|
||||
| Results | `render_results` | `render_image`, `copy` | Stack of two pictures, the front one showing a landscape. |
|
||||
@@ -45,3 +45,7 @@ sketch_chamfer_equal = { master = "sketch_chamfer", accent = "sketch" }
|
||||
sketch_chamfer_two = { master = "sketch_chamfer_two_distances", accent = "sketch" }
|
||||
offset_one_side = { master = "offset", accent = "sketch" }
|
||||
bom = "list"
|
||||
|
||||
# Render workspace drafts: shared meanings; owner review remains Open.
|
||||
# Removing a look override returns the body to its material look.
|
||||
render_remove_override = "render_from_material"
|
||||
|
||||
@@ -63,6 +63,7 @@ combine false
|
||||
compare false
|
||||
component false
|
||||
compute false
|
||||
cone false
|
||||
configuration_table false
|
||||
conic false
|
||||
constrainer false
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
"error": "b7188fcdfadf1512ddd2896805a14618179789f87047b219560a7dab74bd360f",
|
||||
"explode": "2aecb05d5f05aff1ab629066cb9bea8718ea213ac70948ef71a3ced3321f4cb2",
|
||||
"export": "c8c2abf007e43e896479d78798e3976ba9eda809507c820bb38538f77db696ac",
|
||||
"export_tray": "f18606e1f63726c57a0787dced4fb8a221b4a4fc18b88b0bbdee743e546cb489",
|
||||
"extend": "28c63df352c77d02feffe44cf09fb0fc1d48f7905aaabbfa6dba601dbb70f8e8",
|
||||
"extrude": "9cc1538971c5d25467aaed23f739899d9d102fd07f86472ac3197c54ca2e1144",
|
||||
"eye": "2449167c8410826dc1106b687c12a309d5bea8f7817b897943e80f182a163c2d",
|
||||
@@ -122,6 +123,7 @@
|
||||
"hole": "f82d47751f826e08682db847a270897474661bfe9f35b6d3678f49a203172563",
|
||||
"home": "ab5f1c41d377687e4c5a808dfdccf2757b33dd43f934d44df43d6e9118176853",
|
||||
"import": "e343540eb49fdb1e53c4d54b9e60ae513b3103df6c9133048bed878e58067455",
|
||||
"import_tray": "c6aec9556dc8ecb6c953d6bf1f384f220c68167a92e444950c24ded81f66a0b6",
|
||||
"include": "f5b80ad3e06e3b863fcfbe415ec912e4e09653dd519f9ac207819339fe34730f",
|
||||
"infinite": "53fb781131078d2f8e71be23aa610d9f9d9c8bb79ba5f97fa397475e9ff8c3bd",
|
||||
"inspect": "d2b4644b2d5f1aa50cb576b9265e275fa91201e296c2bc79865f810067d538e9",
|
||||
@@ -206,8 +208,45 @@
|
||||
"redo": "28e925493fa9e5f52e2c8e3beeb288af13fdb4f85f3cd92270096a10561e7a1a",
|
||||
"refold": "1fa6a8604af7d04c01bc31d0e5875eb2cc91f5fa6bfc5491dd6680d3299eb26f",
|
||||
"rename": "6887c5467101dca1d213154020d3b03be9b2704ac310de9d0a8ebde62c013bf5",
|
||||
"render_all_shots": "9c04f49624cc2685472041cb3f3e95da2c5f32deeebb9723f4a8e3c369680a5b",
|
||||
"render_appearance": "53287b30915a266d8a3858d5bef24b93ed11f8d612c20c445d3032f400a925cc",
|
||||
"render_aspect_frame": "5d74b263eeb03eb0494b3774817135b8f119caff205a8b31c480d7dd0e5a8554",
|
||||
"render_backdrop": "d27f7d6da7a31c5944dd0ff67c21838690f000f2d87b0bf5274bef0744de34ce",
|
||||
"render_cancel": "2f1d8b3039007ccfc224390758e05d6202fa2eabf63724c744217dcab5d58e5e",
|
||||
"render_check": "65ccf0407d80937c6931cbf87b6d0e628cfb62ca3e841483d02dd9de19c3717c",
|
||||
"render_compare": "1b2d3f3920782490b96b4d14a7cc9506eff98ff2efae00f86d911fabcabc7cb0",
|
||||
"render_copy_look": "25e9138a839a7e6b8225b48cd2f36daba42a928eff541fe616f3df39a1bc82b7",
|
||||
"render_environment": "50cb18380d9310f6e04084c24ac85529599966b1d90c6bef514f4e63f9b30854",
|
||||
"render_execute": "e4d9a66f4569e00c4b4b2ac05a80a9f3eba4e59802c62d3af5bb951ba9153cbf",
|
||||
"render_export_image": "2456f55fa3b50ab84ae871963d4a6b6e92f486cf6ed3039f3a2f07f11192a655",
|
||||
"render_exposure": "60eb5fa040aefe872ab2de66099493513a494ab758a23d443753d033eaf3a05d",
|
||||
"render_fit_product": "8e58b293a39a06fca4cda0543adc2afef3d0041fe34b0bc0c800afb2d5635123",
|
||||
"render_frame_guides": "cb1df01051de42047e38de9dd2a96fcb5b67bd5979cb5756412890400b69e5bc",
|
||||
"render_from_material": "c928daa803a28f90ce24096731b8de711c6cd3215259ac9cd761b6be2e1b9618",
|
||||
"render_ground": "2b900b433870cbc4bd0282e54c604ec696aa28354c753a13b09806f5e87d99c3",
|
||||
"render_image": "e3dd622591de4fdc211f9bd3c6dcb54b01a308e8bcebd02bb80dd6b3982ce2a5",
|
||||
"render_lens": "79bb615d46a05ea5ffc9e2e905cc25f266b3b7e761c160f7d25bbdb3dea0a430",
|
||||
"render_library": "828af74034a62616c774ab0cbe70b7cf9fd42778b574febfb1812f8aa17fd49b",
|
||||
"render_light_area": "b1f3ee596ee1d35f6e8444b54e94f36a34c2129697c88e5286dbf38565f50816",
|
||||
"render_light_by_highlight": "5b37c8c6aa27ac2002dd8c8094e415c64e9eb315a55c4f146e328314e8f639a2",
|
||||
"render_light_point": "a602cb5fa26f04f1bb9be7c14e5a9a9ce52b37550dfd3211a55e915f941f5803",
|
||||
"render_light_spot": "a9413de906266bec0165b4cb06ecac8e36dce0b6ddec4bc4cc6ff4f152601483",
|
||||
"render_lighting_presets": "e0a08433f548a9dd139296107b04b1d4c57ff04303c9bee32d896e2ea06a8d07",
|
||||
"render_output_size": "f08fe354e4d5a6dd21af29cb077ceed96c413c68f48d9f72548ae1614337f88b",
|
||||
"render_paint": "e3d3202205a5a90906348cae519340d38f475e42039a7f60c835cf7a21081da1",
|
||||
"render_pick_up": "df67d10f333a3c9e367897d599a4be510f10ed36c24763c26817f22d24ff35b7",
|
||||
"render_quality": "28fe44cdd2b2f58b91d91dcf20a6dfbd22cf3db6008e1db179717523ecc4889e",
|
||||
"render_remove_override": "c928daa803a28f90ce24096731b8de711c6cd3215259ac9cd761b6be2e1b9618",
|
||||
"render_replace_all": "3bbf830619a91be186b9dc91726b8e47c293556d2ac8c93d87c71014c9f3abcd",
|
||||
"render_results": "94e78898d88eef415e56ca5ec1e056089a2a5aa709abc69e5b8103d6096a019c",
|
||||
"render_same_look": "2b5c69c523a1c949c22638c378803e77123095fddd36cfa58e94b2fd91ca61d7",
|
||||
"render_scene": "1c4d7350f6f17ad637a7d633cb65a64c298af20321b1dbdac01b51d47a0e2822",
|
||||
"render_shot": "4428080faa94f276c8a1d20eb38d04835ee5ae9d6337402371a5edf09f97ddc5",
|
||||
"render_shots_strip": "1dcf5cc8e704691985284e0ca06e03b22540ea9d4cd23f4fb8675801ae7e69ec",
|
||||
"render_solo_light": "abb9f8993be108a79d491bfaca32cde59d07a69db3ead58195e8ca0d8e8d909b",
|
||||
"render_sun": "d86b51f3d4d83df4e932a22bb20d567513529a2eaaa42b93f744412eed2be901",
|
||||
"render_transparent_background": "71dab4763516053734d4eec964b0899716d617597fe0d09e3bfa0cc36224dd7a",
|
||||
"render_update_shot": "22d82ad332f8325395596c4bec4c1ec9bbb72d9fc4cd62ad658a93d7f5f803b9",
|
||||
"reorder": "c45755c8f23575415397bffb316eed9f2d8c014f451ab6f8c3123aca1a99b675",
|
||||
"replace_face": "fcee556c684a1138a30a2574ea565c98ff29f9368c2e861d0fb861155a57d28b",
|
||||
"rest": "eab64961b5340bdbbd92affe0c9b8477dc297a3b49e05e39d5fa71c0f2fda66c",
|
||||
@@ -224,10 +263,17 @@
|
||||
"screw": "5e30570785360d6a591ea22862a82f1cf62228385c1e96382536db8a453ac791",
|
||||
"section": "cdd13f99f15f6d59bfa21c747810608d6afd00cb8207faf0337928c8521e7eae",
|
||||
"select": "fdf6431270006ca7409c60c37cfed59572de04229f104ec723e6010ffa2b7163",
|
||||
"send": "f83b6cdab792f9567a81d46d7828ed20795513c57a2c7d00fbbe6bd14d2f5848",
|
||||
"settings": "9193dd3a1007c43660d0d47b6499cb2571338b67949e1a99df112057b9bf2b8a",
|
||||
"settings_keyboard": "4968c70788094365af9c6e2b1c15b2aac45cf21212a14b8a256daf1ffe17f41a",
|
||||
"settings_monitor": "6fcea26e2fc1673c76c6e7fadac4a91812ed43250cfb363c4f40c0cacfbd7aa5",
|
||||
"settings_mouse": "47754752ea6fb37ec9686c0460740935a4db30fb267f1136a9246aec9a17b3f1",
|
||||
"settings_palette": "a060015a750ff4367c65c04b83bf43720e13a38d8dee35330e1d8880f89eaa22",
|
||||
"settings_plug": "79c00b84b2d1d28e3bf6096639c75476b7e1ee0a326c34ad76a79ad866c0102e",
|
||||
"sheet": "774e30923ef6f37dd9c0b2bc3e45705e83b3a76700bf071cd41155a365d0daa4",
|
||||
"sheet_rules": "5d3a2f37d3b4a4262b3ddbdae53d61f29e0f8e284dd54006da25a7acebfa1114",
|
||||
"shell": "a1959ea0d0441a479bf654b6e549e2e44a0bfdc9cda4eb46fe1fbfd884de7e38",
|
||||
"shield": "5e2d2d157309e0daa72f7c53073dfdb0a474def972a041cd172567f1d1e485ec",
|
||||
"silhouette": "2a848aed2f247b1c0439f830a34a513c93bc5493c40044c821d493d863ad996e",
|
||||
"sketch": "b52e5862b1709a9a7e3ca00d7436d126fbfc01b38080006fa4e17dc581dfa103",
|
||||
"sketch_break": "67a5fab332616e6d6a9aeae3bedc04ee0768179143ba34b795bdd98cea04bb24",
|
||||
@@ -261,6 +307,7 @@
|
||||
"status_error": "b7188fcdfadf1512ddd2896805a14618179789f87047b219560a7dab74bd360f",
|
||||
"status_warning": "1ac4f0ccfac2c01f6f66cb42188f9ae053c4aef9c5bbd249f1fb09611eb4d825",
|
||||
"stitch": "6c3205d64007b771ed78d6f8055867578439fb25d591563b32dbd3343c98732d",
|
||||
"stop": "36967eb4d423370d0d6c679b0a71f8d09f4fb2c73eed3e8cc50c604c44b0c32b",
|
||||
"style": "6c2b04234b82ea4858c80190cc7208c60f549358253005afc35ab4e29506b578",
|
||||
"suppress": "c54fbc01c12c0175d78cd63f692e8aaf73fc2cac79752b2a3ad821ac32734343",
|
||||
"surface": "ba0e839ce0ee03e7ff95a2389a5ecb20bd80c713064d9b1bd5f461f4a80d1921",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Cone</title>
|
||||
<path d="M32 5L12.7 45.97A20 11.55 0 1 0 51.3 45.97Z" fill="#328bd3"/>
|
||||
<path d="M32 5L39 59.82A20 11.55 0 0 0 51.3 45.97Z" fill="#236ead"/>
|
||||
<path d="M32 5L12.7 45.97A20 11.55 0 1 0 51.3 45.97Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 388 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Render all shots — every saved camera view at once</title>
|
||||
<path d="M27.1 12L29.26 12L31.42 6.96Q31.85 5.52 33.22 5.52L36.82 5.52Q38.19 5.52 38.62 6.96L40.78 12L51.58 12Q55.18 12 55.18 15.6L55.18 31.44Q55.18 35.04 51.58 35.04L27.1 35.04Q23.5 35.04 23.5 31.44L23.5 15.6Q23.5 12 27.1 12Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M16.6 21L18.76 21L20.92 15.96Q21.35 14.52 22.72 14.52L26.32 14.52Q27.69 14.52 28.12 15.96L30.28 21L41.08 21Q44.68 21 44.68 24.6L44.68 40.44Q44.68 44.04 41.08 44.04L16.6 44.04Q13 44.04 13 40.44L13 24.6Q13 21 16.6 21Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M6.1 30L8.26 30L10.42 24.96Q10.85 23.52 12.22 23.52L15.82 23.52Q17.19 23.52 17.62 24.96L19.78 30L30.58 30Q34.18 30 34.18 33.6L34.18 49.44Q34.18 53.04 30.58 53.04L6.1 53.04Q2.5 53.04 2.5 49.44L2.5 33.6Q2.5 30 6.1 30Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="18.34" cy="41.52" r="7.56" fill="#b9ddf8" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="47.5" cy="47.5" r="14" fill="#ffffff"/>
|
||||
<circle cx="47.5" cy="47.5" r="12" fill="#236ead"/>
|
||||
<path d="M43.9 41.7L53.3 47.5L43.9 53.3Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Appearance — a body wearing the look sphere</title>
|
||||
<path d="M17.33 24.8L38.98 37.3L38.98 62.3L17.33 49.8Z" fill="#328bd3"/>
|
||||
<path d="M60.63 24.8L38.98 37.3L38.98 62.3L60.63 49.8Z" fill="#236ead"/>
|
||||
<path d="M38.98 12.3L60.63 24.8L38.98 37.3L17.33 24.8Z" fill="#b9ddf8"/>
|
||||
<path d="M38.98 12.3L60.63 24.8L60.63 49.8L38.98 62.3L17.33 49.8L17.33 24.8Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M17.33 24.8L38.98 37.3L60.63 24.8" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M38.98 37.3L38.98 62.3" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="18.98" cy="17.3" r="16.88" fill="#ffffff"/>
|
||||
<circle cx="18.98" cy="17.3" r="14" fill="#328bd3"/>
|
||||
<path d="M32.14 12.51A14 14 0 0 1 14.19 30.46A18.31 18.31 0 0 0 32.14 12.51Z" fill="#236ead"/>
|
||||
<circle cx="14.22" cy="12.54" r="3.78" fill="#b9ddf8"/>
|
||||
<circle cx="18.98" cy="17.3" r="14" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Aspect frame — the shape of the picture</title>
|
||||
<path d="M13 17L51 17A4 4 0 0 1 55 21L55 43A4 4 0 0 1 51 47L13 47A4 4 0 0 1 9 43L9 21A4 4 0 0 1 13 17Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M4.5 23.5L4.5 12.5L15.5 12.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M59.5 40.5L59.5 51.5L48.5 51.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 614 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Backdrop — the coloured wall behind the product</title>
|
||||
<path d="M30.69 4L54.25 17.6L54.25 41.6L30.69 28Z" fill="#328bd3" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.91 29.2L30 35.6L30 48.4L18.91 42Z" fill="#b8c3cf"/>
|
||||
<path d="M41.09 29.2L30 35.6L30 48.4L41.09 42Z" fill="#8e9faf"/>
|
||||
<path d="M30 22.8L41.09 29.2L30 35.6L18.91 29.2Z" fill="#e2e8ef"/>
|
||||
<path d="M30 22.8L41.09 29.2L41.09 42L30 48.4L18.91 42L18.91 29.2Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.91 29.2L30 35.6L41.09 29.2" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M30 35.6L30 48.4" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 928 B |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Cancel render — stop the running render</title>
|
||||
<path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="pic1"><path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#pic1)">
|
||||
<path d="M4 40.8L17.8 27.12L30.68 38.64L38.04 32.88L50 42.96L50 48L4 48Z" fill="#8e9faf"/>
|
||||
</g>
|
||||
<circle cx="36.2" cy="22.8" r="4.2" fill="#8e9faf"/>
|
||||
<path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="47.5" cy="47.5" r="14" fill="#ffffff"/>
|
||||
<circle cx="47.5" cy="47.5" r="12" fill="#236ead"/>
|
||||
<path d="M44.1 42.9L50.9 42.9A1.2 1.2 0 0 1 52.1 44.1L52.1 50.9A1.2 1.2 0 0 1 50.9 52.1L44.1 52.1A1.2 1.2 0 0 1 42.9 50.9L42.9 44.1A1.2 1.2 0 0 1 44.1 42.9Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Check render — verify the request is ready, without rendering</title>
|
||||
<path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="pic1"><path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#pic1)">
|
||||
<path d="M4 40.8L17.8 27.12L30.68 38.64L38.04 32.88L50 42.96L50 48L4 48Z" fill="#8e9faf"/>
|
||||
</g>
|
||||
<circle cx="36.2" cy="22.8" r="4.2" fill="#8e9faf"/>
|
||||
<path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="47.5" cy="47.5" r="14" fill="#ffffff"/>
|
||||
<circle cx="47.5" cy="47.5" r="12" fill="#236ead"/>
|
||||
<path d="M41.9 47.7L45.9 51.9L53.3 43.1" fill="none" stroke="#ffffff" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Compare — live preview and render side by side</title>
|
||||
<path d="M9 12L55 12A5 5 0 0 1 60 17L60 47A5 5 0 0 1 55 52L9 52A5 5 0 0 1 4 47L4 17A5 5 0 0 1 9 12Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="cmpL"><path d="M4 12L32 12L32 52L4 52Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#cmpL)">
|
||||
<path d="M9 12L55 12A5 5 0 0 1 60 17L60 47A5 5 0 0 1 55 52L9 52A5 5 0 0 1 4 47L4 17A5 5 0 0 1 9 12Z" fill="#b8c3cf"/>
|
||||
</g>
|
||||
<defs><clipPath id="cmp"><path d="M9 12L55 12A5 5 0 0 1 60 17L60 47A5 5 0 0 1 55 52L9 52A5 5 0 0 1 4 47L4 17A5 5 0 0 1 9 12Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#cmp)">
|
||||
<path d="M4 44L20.8 28.8L36.48 41.6L45.44 35.2L60 46.4L60 52L4 52Z" fill="#8e9faf"/>
|
||||
</g>
|
||||
<path d="M9 12L55 12A5 5 0 0 1 60 17L60 47A5 5 0 0 1 55 52L9 52A5 5 0 0 1 4 47L4 17A5 5 0 0 1 9 12Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 5L32 59" fill="none" stroke="#ffffff" stroke-width="8.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="32" r="14.5" fill="#ffffff"/>
|
||||
<path d="M32 5L32 59" fill="none" stroke="#236ead" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="32" r="12.8" fill="#236ead"/>
|
||||
<path d="M23.4 32L29.8 25.6L29.8 38.4Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M40.6 32L34.2 25.6L34.2 38.4Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Copy Look — the look in front of a copy outline</title>
|
||||
<path d="M8 40L8 12.5A4.5 4.5 0 0 1 12.5 8L40 8" fill="none" stroke="currentColor" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M24 19L51 19A5 5 0 0 1 56 24L56 51A5 5 0 0 1 51 56L24 56A5 5 0 0 1 19 51L19 24A5 5 0 0 1 24 19Z" fill="none" stroke="currentColor" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="37.5" cy="37.5" r="12" fill="#328bd3"/>
|
||||
<path d="M48.78 33.4A12 12 0 0 1 33.4 48.78A15.69 15.69 0 0 0 48.78 33.4Z" fill="#236ead"/>
|
||||
<circle cx="33.42" cy="33.42" r="3.24" fill="#b9ddf8"/>
|
||||
<circle cx="37.5" cy="37.5" r="12" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 841 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Environment — a sky dome lighting the product</title>
|
||||
<path d="M4.04 42A25.96 25.96 0 0 1 55.96 42A25.96 14.99 0 0 1 4.04 42Z" fill="#b9ddf8" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.91 29.2L30 35.6L30 48.4L18.91 42Z" fill="#b8c3cf"/>
|
||||
<path d="M41.09 29.2L30 35.6L30 48.4L41.09 42Z" fill="#8e9faf"/>
|
||||
<path d="M30 22.8L41.09 29.2L30 35.6L18.91 29.2Z" fill="#e2e8ef"/>
|
||||
<path d="M30 22.8L41.09 29.2L41.09 42L30 48.4L18.91 42L18.91 29.2Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.91 29.2L30 35.6L41.09 29.2" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M30 35.6L30 48.4" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 948 B |
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Render image — start rendering the picture</title>
|
||||
<path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="pic1"><path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#pic1)">
|
||||
<path d="M4 40.8L17.8 27.12L30.68 38.64L38.04 32.88L50 42.96L50 48L4 48Z" fill="#328bd3"/>
|
||||
</g>
|
||||
<path d="M9 12L45 12A5 5 0 0 1 50 17L50 43A5 5 0 0 1 45 48L9 48A5 5 0 0 1 4 43L4 17A5 5 0 0 1 9 12Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="47.5" cy="47.5" r="14" fill="#ffffff"/>
|
||||
<circle cx="47.5" cy="47.5" r="12" fill="#236ead"/>
|
||||
<path d="M43.9 41.7L53.3 47.5L43.9 53.3Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 993 B |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Export image — save the finished picture as a PNG file</title>
|
||||
<path d="M9 18L43 18A5 5 0 0 1 48 23L48 49A5 5 0 0 1 43 54L9 54A5 5 0 0 1 4 49L4 23A5 5 0 0 1 9 18Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="pic1"><path d="M9 18L43 18A5 5 0 0 1 48 23L48 49A5 5 0 0 1 43 54L9 54A5 5 0 0 1 4 49L4 23A5 5 0 0 1 9 18Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#pic1)">
|
||||
<path d="M4 46.8L17.2 33.12L29.52 44.64L36.56 38.88L48 48.96L48 54L4 54Z" fill="#8e9faf"/>
|
||||
</g>
|
||||
<path d="M9 18L43 18A5 5 0 0 1 48 23L48 49A5 5 0 0 1 43 54L9 54A5 5 0 0 1 4 49L4 23A5 5 0 0 1 9 18Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M28 36L47.77 17.55" fill="none" stroke="#ffffff" stroke-width="11.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M58 8L53.52 25.18L40.55 11.29Z" fill="#ffffff" stroke="#ffffff" stroke-width="6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M28 36L47.77 17.55" fill="none" stroke="#236ead" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M58 8L53.52 25.18L40.55 11.29Z" fill="#236ead" stroke="#236ead" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Exposure — brighten or darken the picture</title>
|
||||
<circle cx="32" cy="32" r="25" fill="#e2e8ef"/>
|
||||
<path d="M32 7A25 25 0 0 1 32 57Z" fill="#236ead"/>
|
||||
<circle cx="32" cy="32" r="25" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M14 32L27 32M20.5 25.5L20.5 38.5" fill="none" stroke="#34465b" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37 32L50 32" fill="none" stroke="#ffffff" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 630 B |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Fit product — frame the whole product in the view</title>
|
||||
<path d="M15.98 22.75L32 32L32 50.5L15.98 41.25Z" fill="#b8c3cf"/>
|
||||
<path d="M48.02 22.75L32 32L32 50.5L48.02 41.25Z" fill="#8e9faf"/>
|
||||
<path d="M32 13.5L48.02 22.75L32 32L15.98 22.75Z" fill="#e2e8ef"/>
|
||||
<path d="M32 13.5L48.02 22.75L48.02 41.25L32 50.5L15.98 41.25L15.98 22.75Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M15.98 22.75L32 32L48.02 22.75" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 32L32 50.5" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M5.5 18.5L5.5 5.5L18.5 5.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M58.5 18.5L58.5 5.5L45.5 5.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M58.5 45.5L58.5 58.5L45.5 58.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M5.5 45.5L5.5 58.5L18.5 58.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Frame guides — rule of thirds over the picture</title>
|
||||
<path d="M10 14L54 14A4 4 0 0 1 58 18L58 46A4 4 0 0 1 54 50L10 50A4 4 0 0 1 6 46L6 18A4 4 0 0 1 10 14Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M23.33 15.3L23.33 48.7M7.3 26L56.7 26M40.67 15.3L40.67 48.7M7.3 38L56.7 38" fill="none" stroke="#6f879c" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="23.33" cy="26" r="3.6" fill="#236ead"/>
|
||||
<circle cx="23.33" cy="38" r="3.6" fill="#236ead"/>
|
||||
<circle cx="40.67" cy="26" r="3.6" fill="#236ead"/>
|
||||
<circle cx="40.67" cy="38" r="3.6" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 742 B |
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>From Material — custom look crossed off, material shows</title>
|
||||
<path d="M6 38L32 53.01L32 57.01L6 42Z" fill="#b8c3cf"/>
|
||||
<path d="M58 38L32 53.01L32 57.01L58 42Z" fill="#8e9faf"/>
|
||||
<path d="M32 22.99L58 38L32 53.01L6 38Z" fill="#e2e8ef"/>
|
||||
<path d="M32 22.99L58 38L58 42L32 57.01L6 42L6 38Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M6 38L32 53.01L58 38" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 53.01L32 57.01" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="22" r="15" fill="#328bd3"/>
|
||||
<path d="M46.1 16.87A15 15 0 0 1 26.87 36.1A19.62 19.62 0 0 0 46.1 16.87Z" fill="#236ead"/>
|
||||
<circle cx="26.9" cy="16.9" r="4.05" fill="#b9ddf8"/>
|
||||
<circle cx="32" cy="22" r="15" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M21 11L43 33M43 11L21 33" fill="none" stroke="#ffffff" stroke-width="6.65" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M21 11L43 33M43 11L21 33" fill="none" stroke="currentColor" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Ground — the floor the product stands on, with its contact shadow</title>
|
||||
<path d="M5.06 42L30 56.4L30 58.8L5.06 44.4Z" fill="#328bd3"/>
|
||||
<path d="M54.94 42L30 56.4L30 58.8L54.94 44.4Z" fill="#236ead"/>
|
||||
<path d="M30 27.6L54.94 42L30 56.4L5.06 42Z" fill="#b9ddf8"/>
|
||||
<path d="M30 27.6L54.94 42L54.94 44.4L30 58.8L5.06 44.4L5.06 42Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M5.06 42L30 56.4L54.94 42" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M30 56.4L30 58.8" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M30 35.6L45.93 44.8L34.85 51.2L18.91 42Z" fill="#328bd3"/>
|
||||
<path d="M18.91 29.2L30 35.6L30 48.4L18.91 42Z" fill="#b8c3cf"/>
|
||||
<path d="M41.09 29.2L30 35.6L30 48.4L41.09 42Z" fill="#8e9faf"/>
|
||||
<path d="M30 22.8L41.09 29.2L30 35.6L18.91 29.2Z" fill="#e2e8ef"/>
|
||||
<path d="M30 22.8L41.09 29.2L41.09 42L30 48.4L18.91 42L18.91 29.2Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.91 29.2L30 35.6L41.09 29.2" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M30 35.6L30 48.4" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Lens — the camera lens and its field of view</title>
|
||||
<circle cx="32" cy="32" r="27" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="32" r="19" fill="#b9ddf8" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="32" r="8.5" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="21.75" cy="21.75" r="3" fill="#e2e8ef"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 587 B |
@@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Appearance library — looks on a shelf</title>
|
||||
<circle cx="13" cy="28.35" r="9.5" fill="#b8c3cf"/>
|
||||
<path d="M21.93 25.1A9.5 9.5 0 0 1 9.75 37.28A12.42 12.42 0 0 0 21.93 25.1Z" fill="#8e9faf"/>
|
||||
<circle cx="9.77" cy="25.12" r="2.57" fill="#e2e8ef"/>
|
||||
<circle cx="13" cy="28.35" r="9.5" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="51" cy="28.35" r="9.5" fill="#b8c3cf"/>
|
||||
<path d="M59.93 25.1A9.5 9.5 0 0 1 47.75 37.28A12.42 12.42 0 0 0 59.93 25.1Z" fill="#8e9faf"/>
|
||||
<circle cx="47.77" cy="25.12" r="2.57" fill="#e2e8ef"/>
|
||||
<circle cx="51" cy="28.35" r="9.5" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="28.35" r="13.97" fill="#ffffff"/>
|
||||
<circle cx="32" cy="28.35" r="11.5" fill="#328bd3"/>
|
||||
<path d="M42.81 24.42A11.5 11.5 0 0 1 28.07 39.16A15.04 15.04 0 0 0 42.81 24.42Z" fill="#236ead"/>
|
||||
<circle cx="28.09" cy="24.44" r="3.11" fill="#b9ddf8"/>
|
||||
<circle cx="32" cy="28.35" r="11.5" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M7 42.35L57 42.35A2 2 0 0 1 59 44.35L59 46.35A2 2 0 0 1 57 48.35L7 48.35A2 2 0 0 1 5 46.35L5 44.35A2 2 0 0 1 7 42.35Z" fill="#8e9faf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Area light — angled panel and dotted direction stem</title>
|
||||
<path d="M23.34 11L54.52 29L40.66 37L9.48 19Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="44" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="51" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="58" r="2.125" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 448 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Light by highlight — dotted aim stem and sphere target</title>
|
||||
<circle cx="32" cy="9" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="16" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="23" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="42" r="15" fill="#e2e8ef"/>
|
||||
<path d="M44.29 33.4A15 15 0 0 1 23.4 54.29A19.62 19.62 0 0 0 44.29 33.4Z" fill="#b8c3cf"/>
|
||||
<circle cx="32" cy="42" r="15" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="37.5" r="5.5" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 712 B |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Point light — source disc and dotted direction stem</title>
|
||||
<circle cx="32" cy="23" r="15" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="23" r="2.125" fill="#34465b"/>
|
||||
<circle cx="32" cy="44" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="51" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="58" r="2.125" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 485 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Spot light — cone source and dotted direction stem</title>
|
||||
<path d="M32 8L49 33Q32 43 15 33Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="44" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="51" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="58" r="2.125" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 435 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Lighting presets — a stack of ready-made light set-ups</title>
|
||||
<path d="M24 5L54 5A5 5 0 0 1 59 10L59 40A5 5 0 0 1 54 45L24 45A5 5 0 0 1 19 40L19 10A5 5 0 0 1 24 5Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M10 17L42 17A5 5 0 0 1 47 22L47 54A5 5 0 0 1 42 59L10 59A5 5 0 0 1 5 54L5 22A5 5 0 0 1 10 17Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M18.3 41.55A11.5 11.5 0 1 1 33.7 41.55L33.2 45.55L18.8 45.55Z" fill="#b9ddf8" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M21.3 45.55L30.7 45.55A2.5 2.5 0 0 1 33.2 48.05L33.2 50.05A2.5 2.5 0 0 1 30.7 52.55L21.3 52.55A2.5 2.5 0 0 1 18.8 50.05L18.8 48.05A2.5 2.5 0 0 1 21.3 45.55Z" fill="#8e9faf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1000 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Output size — the picture size in pixels</title>
|
||||
<path d="M9 12L55 12A5 5 0 0 1 60 17L60 47A5 5 0 0 1 55 52L9 52A5 5 0 0 1 4 47L4 17A5 5 0 0 1 9 12Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M22.08 38.79L41.92 25.21" fill="none" stroke="#236ead" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M51 19L45.33 31.97L36.86 19.59Z" fill="#236ead" stroke="#236ead" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M13 45L18.67 32.03L27.14 44.41Z" fill="#236ead" stroke="#236ead" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 750 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Paint — flat brush with look-coloured bristles</title>
|
||||
<path d="M26.13 59.09L22.24 55.2L22.94 48.83L16.58 49.54L14.46 47.42L15.17 41.06L8.8 41.76L4.91 37.87L19.06 23.73L40.27 44.94Z" fill="#328bd3" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M22.24 20.55L28.25 14.54L37.09 16.31L46.28 7.11A7.5 7.5 0 0 1 56.89 17.72L47.69 26.91L49.46 35.75L43.45 41.76Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 589 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Pick Up — eyedropper with a look-coloured tube</title>
|
||||
<path d="M8.96 52.22Q15.32 44.44 14.97 37.01L28.4 23.58L40.42 35.6L26.99 49.03Q19.56 48.68 11.78 55.04Z" fill="#328bd3" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M30.52 20.04L39.01 11.56A9.5 9.5 0 0 1 52.44 24.99L43.96 33.48Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M25.22 18.98L29.46 14.74L49.26 34.54L45.02 38.78Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 682 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Render quality — draft, balanced or high</title>
|
||||
<path d="M10 38L17 38A3.5 3.5 0 0 1 20.5 41.5L20.5 52.5A3.5 3.5 0 0 1 17 56L10 56A3.5 3.5 0 0 1 6.5 52.5L6.5 41.5A3.5 3.5 0 0 1 10 38Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M28.5 24L35.5 24A3.5 3.5 0 0 1 39 27.5L39 52.5A3.5 3.5 0 0 1 35.5 56L28.5 56A3.5 3.5 0 0 1 25 52.5L25 27.5A3.5 3.5 0 0 1 28.5 24Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M47 8L54 8A3.5 3.5 0 0 1 57.5 11.5L57.5 52.5A3.5 3.5 0 0 1 54 56L47 56A3.5 3.5 0 0 1 43.5 52.5L43.5 11.5A3.5 3.5 0 0 1 47 8Z" fill="#328bd3" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 848 B |
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Replace All — every use of a look switched to another</title>
|
||||
<circle cx="12.5" cy="13.3" r="10" fill="#b8c3cf"/>
|
||||
<path d="M21.9 9.88A10 10 0 0 1 9.08 22.7A13.08 13.08 0 0 0 21.9 9.88Z" fill="#8e9faf"/>
|
||||
<circle cx="9.1" cy="9.9" r="2.7" fill="#e2e8ef"/>
|
||||
<circle cx="12.5" cy="13.3" r="10" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M36 36.8L25.39 34.68L33.88 26.19Z" fill="#236ead"/>
|
||||
<path d="M21 21.8L30.34 31.14" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="52.5" cy="35.3" r="9" fill="#328bd3"/>
|
||||
<path d="M60.96 32.22A9 9 0 0 1 49.42 43.76A11.77 11.77 0 0 0 60.96 32.22Z" fill="#236ead"/>
|
||||
<circle cx="49.44" cy="32.24" r="2.43" fill="#b9ddf8"/>
|
||||
<circle cx="52.5" cy="35.3" r="9" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="46.5" cy="47.3" r="14.68" fill="#ffffff"/>
|
||||
<circle cx="46.5" cy="47.3" r="12" fill="#328bd3"/>
|
||||
<path d="M57.78 43.2A12 12 0 0 1 42.4 58.58A15.69 15.69 0 0 0 57.78 43.2Z" fill="#236ead"/>
|
||||
<circle cx="42.42" cy="43.22" r="3.24" fill="#b9ddf8"/>
|
||||
<circle cx="46.5" cy="47.3" r="12" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Render results — open the finished renders</title>
|
||||
<path d="M21 6L55 6A5 5 0 0 1 60 11L60 35A5 5 0 0 1 55 40L21 40A5 5 0 0 1 16 35L16 11A5 5 0 0 1 21 6Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M9 17.5L43 17.5A7.5 7.5 0 0 1 50.5 25L50.5 51A7.5 7.5 0 0 1 43 58.5L9 58.5A7.5 7.5 0 0 1 1.5 51L1.5 25A7.5 7.5 0 0 1 9 17.5Z" fill="#ffffff"/>
|
||||
<path d="M9 20L43 20A5 5 0 0 1 48 25L48 51A5 5 0 0 1 43 56L9 56A5 5 0 0 1 4 51L4 25A5 5 0 0 1 9 20Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="res"><path d="M9 20L43 20A5 5 0 0 1 48 25L48 51A5 5 0 0 1 43 56L9 56A5 5 0 0 1 4 51L4 25A5 5 0 0 1 9 20Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#res)">
|
||||
<path d="M4 48.8L17.2 35.12L29.52 46.64L36.56 40.88L48 50.96L48 56L4 56Z" fill="#328bd3"/>
|
||||
</g>
|
||||
<path d="M9 20L43 20A5 5 0 0 1 48 25L48 51A5 5 0 0 1 43 56L9 56A5 5 0 0 1 4 51L4 25A5 5 0 0 1 9 20Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Same Look — the bodies wearing this look selected</title>
|
||||
<path d="M6.3 41.5L15.83 47L15.83 58L6.3 52.5Z" fill="#b8c3cf"/>
|
||||
<path d="M25.36 41.5L15.83 47L15.83 58L25.36 52.5Z" fill="#8e9faf"/>
|
||||
<path d="M15.83 36L25.36 41.5L15.83 47L6.3 41.5Z" fill="#e2e8ef"/>
|
||||
<path d="M15.83 36L25.36 41.5L25.36 52.5L15.83 58L6.3 52.5L6.3 41.5Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M6.3 41.5L15.83 47L25.36 41.5" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M15.83 47L15.83 58" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37.17 12L45.83 17L45.83 27L37.17 22Z" fill="#328bd3"/>
|
||||
<path d="M54.48 12L45.83 17L45.83 27L54.48 22Z" fill="#236ead"/>
|
||||
<path d="M45.83 7L54.48 12L45.83 17L37.17 12Z" fill="#b9ddf8"/>
|
||||
<path d="M45.83 7L54.48 12L54.48 22L45.83 27L37.17 22L37.17 12Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37.17 12L45.83 17L54.48 12" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M45.83 17L45.83 27" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37.33 4L54.33 4A4.5 4.5 0 0 1 58.83 8.5L58.83 25.5A4.5 4.5 0 0 1 54.33 30L37.33 30A4.5 4.5 0 0 1 32.83 25.5L32.83 8.5A4.5 4.5 0 0 1 37.33 4Z" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37.17 42L45.83 47L45.83 57L37.17 52Z" fill="#328bd3"/>
|
||||
<path d="M54.48 42L45.83 47L45.83 57L54.48 52Z" fill="#236ead"/>
|
||||
<path d="M45.83 37L54.48 42L45.83 47L37.17 42Z" fill="#b9ddf8"/>
|
||||
<path d="M45.83 37L54.48 42L54.48 52L45.83 57L37.17 52L37.17 42Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37.17 42L45.83 47L54.48 42" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M45.83 47L45.83 57" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M37.33 34L54.33 34A4.5 4.5 0 0 1 58.83 38.5L58.83 55.5A4.5 4.5 0 0 1 54.33 60L37.33 60A4.5 4.5 0 0 1 32.83 55.5L32.83 38.5A4.5 4.5 0 0 1 37.33 34Z" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="15.83" cy="17" r="11.5" fill="#328bd3"/>
|
||||
<path d="M26.64 13.07A11.5 11.5 0 0 1 11.9 27.81A15.04 15.04 0 0 0 26.64 13.07Z" fill="#236ead"/>
|
||||
<circle cx="11.92" cy="13.09" r="3.11" fill="#b9ddf8"/>
|
||||
<circle cx="15.83" cy="17" r="11.5" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Shot — save the camera view as a named shot</title>
|
||||
<path d="M9 19L12 19L15 12Q15.6 10 17.5 10L22.5 10Q24.4 10 25 12L28 19L43 19Q48 19 48 24L48 46Q48 51 43 51L9 51Q4 51 4 46L4 24Q4 19 9 19Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="26" cy="35" r="10.5" fill="#b9ddf8" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="47.5" cy="47.5" r="14" fill="#ffffff"/>
|
||||
<circle cx="47.5" cy="47.5" r="12" fill="#236ead"/>
|
||||
<path d="M42 47.5L53 47.5M47.5 42L47.5 53" fill="none" stroke="#ffffff" stroke-width="3.4" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 759 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Shots strip — show or hide the strip of shot thumbnails</title>
|
||||
<path d="M8 19L56 19A5 5 0 0 1 61 24L61 40A5 5 0 0 1 56 45L8 45A5 5 0 0 1 3 40L3 24A5 5 0 0 1 8 19Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M10.5 24.5L19.5 24.5A2.5 2.5 0 0 1 22 27L22 37A2.5 2.5 0 0 1 19.5 39.5L10.5 39.5A2.5 2.5 0 0 1 8 37L8 27A2.5 2.5 0 0 1 10.5 24.5Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M27.5 24.5L36.5 24.5A2.5 2.5 0 0 1 39 27L39 37A2.5 2.5 0 0 1 36.5 39.5L27.5 39.5A2.5 2.5 0 0 1 25 37L25 27A2.5 2.5 0 0 1 27.5 24.5Z" fill="#328bd3" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M44.5 24.5L53.5 24.5A2.5 2.5 0 0 1 56 27L56 37A2.5 2.5 0 0 1 53.5 39.5L44.5 39.5A2.5 2.5 0 0 1 42 37L42 27A2.5 2.5 0 0 1 44.5 24.5Z" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Solo light — point source and dotted stem inside focus brackets</title>
|
||||
<path d="M13.5 5L5.5 5L5.5 13M50.5 5L58.5 5L58.5 13M58.5 51.5L58.5 59.5L50.5 59.5M13.5 59.5L5.5 59.5L5.5 51.5" fill="none" stroke="currentColor" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="23" r="15" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="32" cy="23" r="2.125" fill="#34465b"/>
|
||||
<circle cx="32" cy="44" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="51" r="2.125" fill="#236ead"/>
|
||||
<circle cx="32" cy="58" r="2.125" fill="#236ead"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 713 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Sun — source disc with short radial rays</title>
|
||||
<circle cx="32" cy="32" r="15" fill="#e2e8ef" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 5.5L32 10.5M32 53.5L32 58.5M5.5 32L10.5 32M53.5 32L58.5 32M13.26 13.26L16.8 16.8M47.2 47.2L50.74 50.74M13.26 50.74L16.8 47.2M47.2 16.8L50.74 13.26" fill="none" stroke="#236ead" stroke-width="4.25" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 523 B |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Transparent background — render with an alpha background</title>
|
||||
<path d="M11 6L53 6A5 5 0 0 1 58 11L58 53A5 5 0 0 1 53 58L11 58A5 5 0 0 1 6 53L6 11A5 5 0 0 1 11 6Z" fill="#e2e8ef"/>
|
||||
<defs><clipPath id="chk"><path d="M11 6L53 6A5 5 0 0 1 58 11L58 53A5 5 0 0 1 53 58L11 58A5 5 0 0 1 6 53L6 11A5 5 0 0 1 11 6Z" fill="none"/></clipPath></defs>
|
||||
<g clip-path="url(#chk)">
|
||||
<path d="M6 19L19 19L19 32L6 32ZM6 45L19 45L19 58L6 58ZM19 6L32 6L32 19L19 19ZM19 32L32 32L32 45L19 45ZM32 19L45 19L45 32L32 32ZM32 45L45 45L45 58L32 58ZM45 6L58 6L58 19L45 19ZM45 32L58 32L58 45L45 45Z" fill="#b9ddf8"/>
|
||||
</g>
|
||||
<path d="M11 6L53 6A5 5 0 0 1 58 11L58 53A5 5 0 0 1 53 58L11 58A5 5 0 0 1 6 53L6 11A5 5 0 0 1 11 6Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 18L44.12 25L44.12 39L32 46L19.88 39L19.88 25Z" fill="#ffffff" stroke="#ffffff" stroke-width="7.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M19.88 25L32 32L32 46L19.88 39Z" fill="#b8c3cf"/>
|
||||
<path d="M44.12 25L32 32L32 46L44.12 39Z" fill="#8e9faf"/>
|
||||
<path d="M32 18L44.12 25L32 32L19.88 25Z" fill="#e2e8ef"/>
|
||||
<path d="M32 18L44.12 25L44.12 39L32 46L19.88 39L19.88 25Z" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M19.88 25L32 32L44.12 25" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M32 32L32 46" fill="none" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>Update shot — overwrite the active shot with the current camera</title>
|
||||
<path d="M9 19L12 19L15 12Q15.6 10 17.5 10L22.5 10Q24.4 10 25 12L28 19L43 19Q48 19 48 24L48 46Q48 51 43 51L9 51Q4 51 4 46L4 24Q4 19 9 19Z" fill="#b8c3cf" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="26" cy="35" r="10.5" fill="#b9ddf8" stroke="#34465b" stroke-width="2.55" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<circle cx="47.5" cy="47.5" r="14" fill="#ffffff"/>
|
||||
<circle cx="47.5" cy="47.5" r="12" fill="#236ead"/>
|
||||
<path d="M50.97 43.36A5.4 5.4 0 1 1 43.08 44.4" fill="none" stroke="#ffffff" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
<path d="M46.06 40.14L39.8 42.11L46.35 46.7Z" fill="#ffffff" stroke="#ffffff" stroke-width="0.8" stroke-linejoin="round" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 930 B |
@@ -457,6 +457,7 @@
|
||||
"cmd.canvas_delete": "Smazat plátno",
|
||||
"cmd.canvas_edit": "Upravit plátno",
|
||||
"cmd.canvas_insert": "Plátno",
|
||||
"cmd.canvas_to_sketch": "Náčrt z plátna",
|
||||
"cmd.component_activate": "Aktivovat komponentu",
|
||||
"cmd.component_break_link": "Zrušit odkaz",
|
||||
"cmd.component_capture_position": "Zachytit polohu",
|
||||
@@ -534,6 +535,7 @@
|
||||
"cmd.file_export": "Exportovat",
|
||||
"cmd.file_insert_mesh": "Vložit síť",
|
||||
"cmd.file_insert_step": "Vložit STEP",
|
||||
"cmd.file_open_in_easyprint": "Otevřít v EasyPrint",
|
||||
"cmd.file_save_mesh": "Uložit jako síť",
|
||||
"cmd.file_slicers": "Nainstalované slicery",
|
||||
"cmd.frame_member": "Prvek rámu",
|
||||
@@ -1014,6 +1016,12 @@
|
||||
"pick one or two vertices, edges or faces": "vyberte jeden nebo dva vrcholy, hrany či plochy",
|
||||
"prefs.cpu": "CPU (softwarově)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Sledovat soubor motivu",
|
||||
"prefs.theme_follow_error": "Nepoužito: {error}. Zůstává poslední funkční motiv.",
|
||||
"prefs.theme_follow_launch": "Sledování jen pro toto spuštění (--theme-file); načte se znovu při každém přepsání jiným nástrojem.",
|
||||
"prefs.theme_follow_note": "Načte se znovu při každém přepsání jiným nástrojem. Výběr motivu sledování ukončí.",
|
||||
"prefs.theme_follow_off": "Vypnuto",
|
||||
"prefs.theme_follow_stop": "Ukončit sledování",
|
||||
"properties.title": "Vlastnosti: {name}",
|
||||
"recovery.days_ago": "před {count} dny",
|
||||
"recovery.detail": "{file} · prvků: {features} · automaticky uloženo {when}",
|
||||
@@ -1493,7 +1501,7 @@
|
||||
"ui.agent_chat_pop_out": "Otevřít ve vlastním okně, které lze přesunout na jinou obrazovku",
|
||||
"ui.agent_chat_previous_picture": "Předchozí obrázek",
|
||||
"ui.agent_chat_privacy": "Nic se nikam neodesílá, jen agentovi, kterého spouštíte pod vlastním účtem.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft nic nikam neodesílá: agent, kterého spouštíte, komunikuje se svou službou pod vaším účtem. SolidCraft nikdy nevidí ani neukládá klíč či heslo.",
|
||||
"ui.agent_chat_privacy_note": "Chat sám nic nikam neodesílá: agent, kterého spouštíte, komunikuje se svou službou pod vaším účtem. SolidCraft nikdy nevidí ani neukládá klíč či heslo.",
|
||||
"ui.agent_chat_queue": "Zařadit",
|
||||
"ui.agent_chat_queue_full": "Čeká příliš mnoho zpráv: některou odeberte nebo počkejte na agenta.",
|
||||
"ui.agent_chat_queued": "Ve frontě",
|
||||
@@ -1678,6 +1686,7 @@
|
||||
"ui.command_done": "{command} hotovo",
|
||||
"ui.command_palette_hint": "Zadejte příkaz, např. {example} — nebo stiskněte S pro hledání",
|
||||
"ui.concentric": "Soustřednost",
|
||||
"ui.cone": "Kužel",
|
||||
"ui.conic_curve": "Kuželosečka",
|
||||
"ui.constant": "Konstantní",
|
||||
"ui.constraints_conflict": "Konflikt vazeb",
|
||||
@@ -1736,6 +1745,11 @@
|
||||
"ui.draft": "Úkos",
|
||||
"ui.drawing": "Výkres",
|
||||
"ui.drill_point": "Špička vrtáku",
|
||||
"ui.easyprint_consent": "EasyPrint je slicer od Printables v prohlížeči. Aby se v něm model otevřel, SolidCraft jej nahraje na servery Printables. Odkaz vyprší po 30 minutách a musíte být přihlášeni k Printables. Pokračovat?",
|
||||
"ui.easyprint_failed": "Nahrání do EasyPrint se nezdařilo: {error}",
|
||||
"ui.easyprint_opened": "Otevřeno v EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, v prohlížeči)",
|
||||
"ui.easyprint_uploading": "Nahrávám na Printables…",
|
||||
"ui.edit": "Upravit",
|
||||
"ui.editJointLimits": "Upravit limity kloubu",
|
||||
"ui.edit_section_analysis": "Upravit analýzu řezu",
|
||||
@@ -1793,6 +1807,7 @@
|
||||
"ui.heading_circular_pattern": "KRUHOVÉ POLE",
|
||||
"ui.heading_coil": "ŠROUBOVICE",
|
||||
"ui.heading_combine": "KOMBINOVAT",
|
||||
"ui.heading_cone": "KUŽEL",
|
||||
"ui.heading_configure": "KONFIGURACE",
|
||||
"ui.heading_constraints": "VAZBY",
|
||||
"ui.heading_construct": "KONSTRUKCE",
|
||||
@@ -2030,9 +2045,7 @@
|
||||
"ui.right": "Zprava",
|
||||
"ui.save": "Uložit",
|
||||
"ui.save_as": "Uložit jako",
|
||||
"ui.save_mesh_no_slicer": "Nebyl nalezen žádný slicer: zvolte Vlastní… a vyberte svůj slicer, nebo vypněte Odeslat do sliceru",
|
||||
"ui.save_mesh_pick_bodies": "Vyberte tělesa k uložení",
|
||||
"ui.save_mesh_temp_failed": "Nelze vytvořit {folder}: {error}",
|
||||
"ui.saved_to": "Uloženo {path}",
|
||||
"ui.sbox_pin": "Připnout nahoru ve vyhledávání S",
|
||||
"ui.sbox_unpin": "Odepnout",
|
||||
@@ -2047,7 +2060,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+klik pouze přidává",
|
||||
"ui.selection_shift_add_only_tip": "Zapnuto: Shift přidává položky, Ctrl/Cmd přepíná. Vypnuto (výchozí): Shift i Ctrl/Cmd přepínají.",
|
||||
"ui.send": "Odeslat",
|
||||
"ui.send_to_slicer": "Odeslat do sliceru",
|
||||
"ui.sent_to_slicer": "Odesláno do {slicer}",
|
||||
"ui.sheet_gap": "Mezera",
|
||||
"ui.shell": "Skořepina",
|
||||
@@ -2139,6 +2151,7 @@
|
||||
"ui.untitled": "Bez názvu",
|
||||
"ui.up_axis_note": "Která osa v pohledech míří nahoru (pohled podél osy, výchozí pohled, pohled kolmo). Návrhy se nemění.",
|
||||
"ui.updateToCurrentView": "Aktualizovat na aktuální pohled",
|
||||
"ui.upload": "Nahrát",
|
||||
"ui.view_centre": "Střed pohledu",
|
||||
"ui.visual_shaded_hidden_edges": "Stínovaný se skrytými hranami",
|
||||
"ui.visual_shaded_with_edges": "Stínovaný s hranami",
|
||||
|
||||
@@ -649,6 +649,7 @@
|
||||
"cmd.canvas_delete": "Slet referencebillede",
|
||||
"cmd.canvas_edit": "Redigér referencebillede",
|
||||
"cmd.canvas_insert": "Referencebillede",
|
||||
"cmd.canvas_to_sketch": "Skitse fra referencebillede",
|
||||
"cmd.component_activate": "Aktivér komponent",
|
||||
"cmd.component_break_link": "Bryd forbindelse",
|
||||
"cmd.component_capture_position": "Registrér position",
|
||||
@@ -729,6 +730,7 @@
|
||||
"cmd.file_export": "Eksportér",
|
||||
"cmd.file_insert_mesh": "Indsæt mesh",
|
||||
"cmd.file_insert_step": "Indsæt STEP",
|
||||
"cmd.file_open_in_easyprint": "Åbn med EasyPrint",
|
||||
"cmd.file_save_mesh": "Gem som mesh",
|
||||
"cmd.file_slicers": "Installerede slicere",
|
||||
"cmd.frame_member": "Rammeelement",
|
||||
@@ -1322,6 +1324,12 @@
|
||||
"prefs.supersampling_brief": "Tegner visningen i større størrelse og nedskalerer den med filtrering: meget skarpt og mere krævende.",
|
||||
"prefs.tab_accent_note": "Accentfarven følger den aktive fane",
|
||||
"prefs.theme_file": "temafil",
|
||||
"prefs.theme_follow": "Følg en temafil",
|
||||
"prefs.theme_follow_error": "Ikke anvendt: {error}. Det seneste gyldige tema bevares.",
|
||||
"prefs.theme_follow_launch": "Følges kun denne gang (--theme-file); genindlæses, når et andet værktøj overskriver filen.",
|
||||
"prefs.theme_follow_note": "Genindlæses, når et andet værktøj overskriver filen. Valg af et tema stopper dette.",
|
||||
"prefs.theme_follow_off": "Fra",
|
||||
"prefs.theme_follow_stop": "Stop med at følge",
|
||||
"prefs.timeline_half_hour": "−30 min",
|
||||
"prefs.timeline_now": "nu",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
@@ -1670,7 +1678,7 @@
|
||||
"ui.agent_chat_pop_out": "Åbn i eget vindue, som du kan flytte til en anden skærm",
|
||||
"ui.agent_chat_previous_picture": "Forrige billede",
|
||||
"ui.agent_chat_privacy": "Intet sendes andre steder end til den agent, du kører, under din egen konto.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft sender intet nogen steder: Agenten, du kører, kommunikerer med sin egen tjeneste under din egen konto. SolidCraft ser eller gemmer aldrig en nøgle eller adgangskode.",
|
||||
"ui.agent_chat_privacy_note": "Chatten sender selv intet nogen steder: Agenten, du kører, kommunikerer med sin egen tjeneste under din egen konto. SolidCraft ser eller gemmer aldrig en nøgle eller adgangskode.",
|
||||
"ui.agent_chat_queue": "Sæt i kø",
|
||||
"ui.agent_chat_queue_full": "For mange beskeder venter: Fjern en, eller vent på agenten.",
|
||||
"ui.agent_chat_queued": "I kø",
|
||||
@@ -1863,6 +1871,7 @@
|
||||
"ui.command_done": "{command} udført",
|
||||
"ui.command_palette_hint": "Skriv en kommando, f.eks. {example} — eller tryk S for at søge",
|
||||
"ui.concentric": "Koncentrisk",
|
||||
"ui.cone": "Kegle",
|
||||
"ui.conic_curve": "Keglesnitskurve",
|
||||
"ui.constant": "Konstant",
|
||||
"ui.constraints_conflict": "Bindinger er i konflikt",
|
||||
@@ -1921,6 +1930,11 @@
|
||||
"ui.draft": "Slipvinkel",
|
||||
"ui.drawing": "Tegning",
|
||||
"ui.drill_point": "Borspids",
|
||||
"ui.easyprint_consent": "EasyPrint er Printables' slicer i browseren. For at åbne modellen der uploader SolidCraft den til Printables' servere. Linket udløber efter 30 minutter, og du skal være logget ind på Printables. Fortsæt?",
|
||||
"ui.easyprint_failed": "Upload til EasyPrint mislykkedes: {error}",
|
||||
"ui.easyprint_opened": "Åbnet i EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, i browseren)",
|
||||
"ui.easyprint_uploading": "Uploader til Printables…",
|
||||
"ui.edit": "Redigér",
|
||||
"ui.editJointLimits": "Redigér ledgrænser",
|
||||
"ui.edit_section_analysis": "Redigér snitanalyse",
|
||||
@@ -1982,6 +1996,7 @@
|
||||
"ui.heading_circular_pattern": "CIRKULÆRT MØNSTER",
|
||||
"ui.heading_coil": "SPIRAL",
|
||||
"ui.heading_combine": "KOMBINÉR",
|
||||
"ui.heading_cone": "KEGLE",
|
||||
"ui.heading_configure": "KONFIGURÉR",
|
||||
"ui.heading_constraints": "BINDINGER",
|
||||
"ui.heading_construct": "KONSTRUKTION",
|
||||
@@ -2232,9 +2247,7 @@
|
||||
"ui.right": "Fra højre",
|
||||
"ui.save": "Gem",
|
||||
"ui.save_as": "Gem som",
|
||||
"ui.save_mesh_no_slicer": "Ingen slicer fundet: Vælg Brugerdefineret…, og vælg dit slicerprogram, eller slå Send til slicer fra",
|
||||
"ui.save_mesh_pick_bodies": "Vælg de emner, der skal gemmes",
|
||||
"ui.save_mesh_temp_failed": "Kunne ikke oprette {folder}: {error}",
|
||||
"ui.saved_to": "Gemt: {path}",
|
||||
"ui.sbox_pin": "Fastgør øverst i S-menuen",
|
||||
"ui.sbox_unpin": "Fjern fastgørelse",
|
||||
@@ -2249,7 +2262,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+klik tilføjer uden at fjerne",
|
||||
"ui.selection_shift_add_only_tip": "Slået til: Shift tilføjer til markeringen. Ctrl/Cmd tilføjer eller fjerner. Slået fra (standard): Både Shift og Ctrl/Cmd tilføjer eller fjerner.",
|
||||
"ui.send": "Send",
|
||||
"ui.send_to_slicer": "Send til slicer",
|
||||
"ui.sent_to_slicer": "Sendt til {slicer}",
|
||||
"ui.sheet_gap": "Mellemrum",
|
||||
"ui.shell": "Udhulning",
|
||||
@@ -2347,6 +2359,7 @@
|
||||
"ui.untitled": "Uden titel",
|
||||
"ui.up_axis_note": "Hvilken akse der peger opad i visningerne (aksevisning, Hjem, Se på). Designs ændres ikke.",
|
||||
"ui.updateToCurrentView": "Opdatér til aktuel visning",
|
||||
"ui.upload": "Upload",
|
||||
"ui.view_centre": "Visningens centrum",
|
||||
"ui.visual_shaded_hidden_edges": "Skyggelagt med skjulte kanter",
|
||||
"ui.visual_shaded_with_edges": "Skyggelagt med kanter",
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
"2. Attach your screenshot: copy and paste it, or save and upload the PNG.": "2. Screenshot anhängen: kopieren und einfügen oder als PNG speichern und hochladen.",
|
||||
"2D": "2D",
|
||||
"3. Click Submit new issue on GitHub to send your report.": "3. Auf GitHub auf Submit new issue klicken, um den Bericht zu senden.",
|
||||
"A Single hole snaps to the middle of its face and to the centres of its round edges": "Eine einzelne Bohrung rastet am Flächenmittelpunkt und an den Mittelpunkten ihrer kreisförmigen Kanten ein",
|
||||
"A new configuration, a copy of the active one": "Eine neue Konfiguration, eine Kopie der aktiven",
|
||||
"A placed Single hole has a handle to drag it, and picking its face again moves the hole there instead of taking it out": "Eine platzierte einzelne Bohrung lässt sich über einen Ziehgriff verschieben. Durch erneutes Anklicken ihrer Fläche wird die Bohrung dorthin verschoben, statt entfernt zu werden",
|
||||
"A short title for the problem (optional)": "Kurzer Problemtitel (optional)",
|
||||
"ARRANGE": "ANORDNEN",
|
||||
"About SolidCraft": "Über SolidCraft",
|
||||
"Acceleration": "Beschleunigung",
|
||||
@@ -19,19 +22,27 @@
|
||||
"Add Mid Radius": "Mittleren Radius hinzufügen",
|
||||
"Add Row": "Zeile hinzufügen",
|
||||
"Add a tool": "Werkzeug hinzufügen",
|
||||
"Add all bodies": "Alle Körper hinzufügen",
|
||||
"Add bend": "Biegung hinzufügen",
|
||||
"Add condition": "Bedingung hinzufügen",
|
||||
"Add or edit rule": "Regel hinzufügen oder bearbeiten",
|
||||
"Add to New Folder": "Zu neuem Ordner hinzufügen",
|
||||
"Add visible bodies": "Sichtbare Körper hinzufügen",
|
||||
"Advanced": "Erweitert",
|
||||
"Against": "Gegen",
|
||||
"Alignment": "Ausrichtung",
|
||||
"All Lines": "Alle Linien",
|
||||
"All Sketch Points": "Alle Skizzenpunkte",
|
||||
"All components": "Alle Komponenten",
|
||||
"All open designs": "Alle geöffneten Designs",
|
||||
"Allowed expressions, separated by semicolons": "Zulässige Ausdrücke, durch Semikolons getrennt",
|
||||
"Also deletes": "Löscht auch",
|
||||
"Anchor": "Anker",
|
||||
"Angle 2": "Winkel 2",
|
||||
"Angle Display": "Winkelanzeige",
|
||||
"Animate": "Animieren",
|
||||
"Another bend on the far edge of the last flange": "Eine weitere Biegung an der gegenüberliegenden Kante des letzten Flansches",
|
||||
"App/system information and command settings are included. Review private details before sharing.": "App- und Systeminformationen sowie Befehlseinstellungen werden mit übermittelt. Prüfen Sie vor dem Teilen, ob private Angaben enthalten sind.",
|
||||
"Appearance name": "Name des Erscheinungsbilds",
|
||||
"Applied Radius": "Angewendeter Radius",
|
||||
"Apply To": "Anwenden auf",
|
||||
@@ -46,6 +57,8 @@
|
||||
"BLEND SURFACE": "ÜBERGANGSFLÄCHE",
|
||||
"BOUNDARY SURFACE": "BERANDUNGSFLÄCHE",
|
||||
"BROWSER": "BROWSER",
|
||||
"Bar": "Flachstab",
|
||||
"Bend": "Biegung",
|
||||
"Bend Edges": "Biegekanten",
|
||||
"Bend Line Position": "Position der Biegelinie",
|
||||
"Bend Position": "Biegeposition",
|
||||
@@ -58,6 +71,9 @@
|
||||
"Body (last if none)": "Körper (letzter, wenn keiner)",
|
||||
"Body to split": "Zu teilender Körper",
|
||||
"Body, or faces to take out": "Körper oder zu entfernende Flächen",
|
||||
"Bottom Left": "Unten links",
|
||||
"Bottom Middle": "Unten Mitte",
|
||||
"Bottom Right": "Unten rechts",
|
||||
"Boundary": "Begrenzung",
|
||||
"Bounding box": "Hüllquader",
|
||||
"CHECK": "PRÜFEN",
|
||||
@@ -77,12 +93,15 @@
|
||||
"Center Y": "Mittelpunkt Y",
|
||||
"Center of mass": "Massenschwerpunkt",
|
||||
"Centre to centre": "Mitte zu Mitte",
|
||||
"Centroid": "Flächenschwerpunkt",
|
||||
"Chamfer Type": "Abschrägungstyp",
|
||||
"Channel": "U-Profil",
|
||||
"Check collisions": "Kollisionen prüfen",
|
||||
"Checked": "Geprüft",
|
||||
"Choose Variable radius or Spline in Type.": "Unter „Typ“ „Variable radius“ oder „Spline“ wählen.",
|
||||
"Choose a new plane. Sketch geometry and dimensions stay unchanged in its two-dimensional coordinates.": "Wählen Sie eine neue Ebene. Skizzengeometrie und Bemaßungen bleiben in ihren zweidimensionalen Koordinaten unverändert.",
|
||||
"Choose…": "Auswählen…",
|
||||
"Circle center": "Kreismittelpunkt",
|
||||
"Circular": "Kreisförmig",
|
||||
"Circumference": "Umfang",
|
||||
"Clockwise": "Im Uhrzeigersinn",
|
||||
@@ -102,8 +121,10 @@
|
||||
"Contact": "Kontakt",
|
||||
"Contact Sets": "Kontaktsätze",
|
||||
"Contact sets": "Kontaktsätze",
|
||||
"Continue on GitHub": "Auf GitHub fortfahren",
|
||||
"Continuity": "Stetigkeit",
|
||||
"Control Radius": "Kontrollradius",
|
||||
"Copies the definition only. Assign it from Physical Material when ready.": "Kopiert nur die Materialdefinition. Weisen Sie das Material anschließend unter „Physikalisches Material“ zu.",
|
||||
"Copy Error Message": "Fehlermeldung kopieren",
|
||||
"Copy Warning Message": "Warnmeldung kopieren",
|
||||
"Copy all licences": "Alle Lizenzen kopieren",
|
||||
@@ -112,23 +133,29 @@
|
||||
"Copy screenshot": "Screenshot kopieren",
|
||||
"Corner Relief": "Eckenentlastung",
|
||||
"Corner Relief Shape": "Form der Eckenentlastung",
|
||||
"Corner radius": "Eckenradius",
|
||||
"Counterbore depth": "Tiefe der Senkung",
|
||||
"Counterbore Ø": "Tiefenbohrung Ø",
|
||||
"Countersink angle": "Winkel der Kegelsenkung",
|
||||
"Countersink Ø": "Senkung Ø",
|
||||
"Create Hole": "Bohrung erstellen",
|
||||
"Create Issue — review draft": "Issue erstellen — Entwurf prüfen",
|
||||
"Create Issue…": "Issue erstellen…",
|
||||
"Cross curves": "Querkurven",
|
||||
"Ctrl+Enter continues on GitHub.": "Strg+Enter geht weiter zu GitHub.",
|
||||
"Cube": "Würfel",
|
||||
"Current orthographic view (1:1 mm)": "Aktuelle orthogonale Ansicht (1:1 mm)",
|
||||
"Current perspective view": "Aktuelle perspektivische Ansicht",
|
||||
"Current plane": "Aktuelle Ebene",
|
||||
"Curv. Comb": "Krümmungskamm",
|
||||
"Curvature (G2)": "Krümmung (G2)",
|
||||
"Curvature change (G3)": "Krümmungsänderung (G3)",
|
||||
"Custom": "Benutzerdefiniert",
|
||||
"Customize Toolbar": "Symbolleiste anpassen",
|
||||
"Customize…": "Anpassen…",
|
||||
"Cylindrical face": "Zylindrische Fläche",
|
||||
"Delete": "Löschen",
|
||||
"Delete Folders and Features…": "Ordner mit Features löschen…",
|
||||
"Delete Selected Features…": "Ausgewählte Merkmale löschen…",
|
||||
"Delete Selected Folders": "Ausgewählte Ordner löschen",
|
||||
"Delete all": "Alle löschen",
|
||||
@@ -137,6 +164,8 @@
|
||||
"Delete the set": "Satz löschen",
|
||||
"Density": "Dichte",
|
||||
"Dependents": "Abhängige Elemente",
|
||||
"Describe the problem you saw": "Beschreiben Sie das aufgetretene Problem",
|
||||
"Describe what happened before continuing.": "Beschreiben Sie, was passiert ist, bevor Sie fortfahren.",
|
||||
"Designs you open or save appear here.": "Designs, die Sie öffnen oder speichern, erscheinen hier.",
|
||||
"Determined by To Object. Choose Angle to edit the angular extent.": "Bestimmt durch Bis Objekt. Wählen Sie Winkel, um den Winkelbereich zu bearbeiten.",
|
||||
"Diameter": "Durchmesser",
|
||||
@@ -148,6 +177,7 @@
|
||||
"Don't ask again": "Nicht mehr fragen",
|
||||
"Double-click to rename": "Double-click to rename",
|
||||
"Double-clicking the middle button in the view: Home (the home view, framing what is shown), Fit (frame what is shown, keeping the orientation) or nothing": "Doppelklick mit der mittleren Taste in der Ansicht: Home (Startansicht, zeigt alles Sichtbare), Einpassen (Sichtbares einpassen, Ausrichtung beibehalten) oder nichts",
|
||||
"Drag to move the hole; click to remove it": "Ziehen, um die Bohrung zu verschieben; anklicken, um sie zu entfernen",
|
||||
"Drive Joint": "Gelenk antreiben",
|
||||
"Duration": "Dauer",
|
||||
"Edges": "Kanten",
|
||||
@@ -159,6 +189,7 @@
|
||||
"End bulge": "Endausbauchung",
|
||||
"End continuity": "Endstetigkeit",
|
||||
"Expand": "Ausklappen",
|
||||
"Expected result (optional)": "Erwartetes Ergebnis (optional)",
|
||||
"Explode": "Explodieren",
|
||||
"Explode Text": "Text auflösen",
|
||||
"Export Animation…": "Animation exportieren…",
|
||||
@@ -171,6 +202,7 @@
|
||||
"Export JSON…": "JSON exportieren…",
|
||||
"Export design library...": "Designbibliothek exportieren...",
|
||||
"Export hidden edges as dashed lines": "Verdeckte Kanten gestrichelt exportieren",
|
||||
"Exported by SolidWorks, which usually saves Y up": "Aus SolidWorks exportiert; dort zeigt die Y-Achse normalerweise nach oben",
|
||||
"Expression": "Ausdruck",
|
||||
"Extend to meet": "Verlängern, bis sie sich treffen",
|
||||
"Extents": "Ausdehnung",
|
||||
@@ -179,6 +211,7 @@
|
||||
"Face": "Fläche",
|
||||
"Face Appearance": "Flächenerscheinungsbild",
|
||||
"Face attachment lost": "Flächenanbindung verloren",
|
||||
"Face center": "Flächenmittelpunkt",
|
||||
"Faces": "Flächen",
|
||||
"Faces / edges / vertices": "Flächen / Kanten / Ecken",
|
||||
"Faces to split": "Zu teilende Flächen",
|
||||
@@ -194,6 +227,8 @@
|
||||
"First plane": "Erste Ebene",
|
||||
"Fit and G2 corners require Constant radius.": "Passung und G2-Ecken erfordern Constant radius.",
|
||||
"Fixed Face": "Feste Fläche",
|
||||
"Flange thickness": "Flanschdicke",
|
||||
"Flanges": "Flansche",
|
||||
"Flat Pattern": "Flachmuster",
|
||||
"Flat size": "Abwicklungsgröße",
|
||||
"Follow camera (Look At sketches)": "Kamera folgen (Skizzen ansehen)",
|
||||
@@ -203,23 +238,32 @@
|
||||
"From Bodies": "Aus Körpern",
|
||||
"From edges": "Ausgangskanten",
|
||||
"Full Length": "Volle Länge",
|
||||
"Full thread depth": "Volle Gewindetiefe",
|
||||
"Further Bends": "Weitere Biegungen",
|
||||
"G2 corners require a constant radius and Exact fit. G2 corner construction is not supported yet.": "G2-Ecken erfordern einen konstanten Radius und Exact fit. Die Konstruktion von G2-Ecken wird noch nicht unterstützt.",
|
||||
"Gap": "Spalt",
|
||||
"Grid": "Raster",
|
||||
"HISTORY": "VERLAUF",
|
||||
"Halo under sketch curves": "Hervorhebung unter Skizzenkurven",
|
||||
"Height": "Höhe",
|
||||
"Height From": "Höhe ab",
|
||||
"Hidden edges": "Verdeckte Kanten",
|
||||
"History layout": "Verlaufslayout",
|
||||
"History names": "Namen im Konstruktionsverlauf",
|
||||
"Hole (optional)": "Bohrung (optional)",
|
||||
"Holes": "Löcher",
|
||||
"Holes (edges on them)": "Löcher (ihre Kanten)",
|
||||
"Home view": "Startansicht",
|
||||
"Horiz./Vert.": "Horiz./Vert.",
|
||||
"I-Beam": "I-Träger",
|
||||
"IMAGES": "BILDER",
|
||||
"Import material into design": "Material ins Design importieren",
|
||||
"Import…": "Importieren…",
|
||||
"In This Design": "In diesem Design",
|
||||
"In place (surfaces)": "An Ort und Stelle (Flächen)",
|
||||
"In plane": "In der Ebene",
|
||||
"Included": "Enthalten",
|
||||
"Inner Sharp": "Innenkante",
|
||||
"Inside": "Innen",
|
||||
"Instant": "Sofort",
|
||||
"Interface font": "Schriftart der Oberfläche",
|
||||
@@ -235,10 +279,12 @@
|
||||
"Keep of the other surface": "Vom anderen Flächenkörper behalten",
|
||||
"Key a joint's value at this step": "Gelenkwert in diesem Schritt als Schlüsselbild setzen",
|
||||
"Keys": "Schlüsselbilder",
|
||||
"L-Angle": "L-Profil",
|
||||
"LIBRARY": "BIBLIOTHEK",
|
||||
"LINKS": "VERKNÜPFUNGEN",
|
||||
"Later": "Später",
|
||||
"Leave it": "Belassen",
|
||||
"Left Middle": "Links Mitte",
|
||||
"Legacy face attachment. Rebinding to a certified face creates an exact attachment.": "Alte Flächenanbindung. Das erneute Anbinden an eine zertifizierte Fläche erzeugt eine exakte Anbindung.",
|
||||
"Length": "Länge",
|
||||
"Length units": "Length units",
|
||||
@@ -248,11 +294,13 @@
|
||||
"Limits": "Grenzen",
|
||||
"Line Spacing": "Zeilenabstand",
|
||||
"Line Type": "Linientyp",
|
||||
"Lines": "Linien",
|
||||
"Listing the installed fonts…": "Installierte Schriftarten werden aufgelistet…",
|
||||
"Load library": "Bibliothek laden",
|
||||
"Local library": "Lokale Bibliothek",
|
||||
"Loop": "Schleife",
|
||||
"M5 or M5x0.5": "M5 oder M5x0.5",
|
||||
"M5, M5x0.5, 1/4-20 UNC": "M5, M5x0.5, 1/4-20 UNC",
|
||||
"MANAGE": "VERWALTEN",
|
||||
"MATERIALS": "MATERIALIEN",
|
||||
"MODEL": "MODELL",
|
||||
@@ -262,6 +310,8 @@
|
||||
"Mass Center": "Massenschwerpunkt",
|
||||
"Matched restrictions check the final values.": "Zutreffende Einschränkungen prüfen die endgültigen Werte.",
|
||||
"Material": "Material",
|
||||
"Material Outside": "Material außen",
|
||||
"Material copied. Existing body assignments are unchanged.": "Material kopiert. Bestehende Materialzuweisungen der Körper bleiben unverändert.",
|
||||
"Max": "Max",
|
||||
"Maximum": "Maximum",
|
||||
"Mesh body": "Netzkörper",
|
||||
@@ -281,9 +331,11 @@
|
||||
"Move Type": "Verschiebungstyp",
|
||||
"Move down": "Nach unten",
|
||||
"Move earlier": "Nach vorn verschieben",
|
||||
"Move holes by clicking or dragging": "Bohrungen durch Anklicken oder Ziehen verschieben",
|
||||
"Move later": "Nach hinten verschieben",
|
||||
"Move up": "Nach oben",
|
||||
"Name": "Name",
|
||||
"Name on import": "Name beim Import",
|
||||
"Nearest": "Nächstgelegen",
|
||||
"New": "Neu",
|
||||
"New Comp.": "Neue Komp.",
|
||||
@@ -293,22 +345,32 @@
|
||||
"No crash reports.": "Keine Absturzberichte.",
|
||||
"No matching appearance presets.": "Keine passenden Erscheinungsbildvorlagen.",
|
||||
"No matching appearances": "Keine passenden Erscheinungsbilder",
|
||||
"No matching physical materials.": "Keine passenden physikalischen Materialien gefunden.",
|
||||
"No visible bodies or sketches to export.": "Keine sichtbaren Körper oder Skizzen zum Exportieren.",
|
||||
"Nominal diameter": "Nenndurchmesser",
|
||||
"None": "Keine",
|
||||
"Not available yet": "Noch nicht verfügbar",
|
||||
"Not saved yet": "Noch nicht gespeichert",
|
||||
"Notch": "Ausklinkung",
|
||||
"OUTPUT": "AUSGABE",
|
||||
"Of": "Freiheitsgrad",
|
||||
"On your computer": "Auf diesem Computer",
|
||||
"Opacity": "Deckkraft",
|
||||
"Open GitHub draft": "GitHub-Entwurf öffnen",
|
||||
"Open bodies (no volume)": "Offene Körper (ohne Volumen)",
|
||||
"Open library...": "Bibliothek öffnen...",
|
||||
"Open local libraries in the desktop app. You can export this design's library here.": "Öffnen Sie lokale Bibliotheken in der Desktop-App. Die Bibliothek dieses Designs können Sie hier exportieren.",
|
||||
"Open surface — no volume": "Offene Oberfläche – kein Volumen",
|
||||
"Open-source parametric 3D CAD in Rust. Licensed MIT OR Apache-2.0.": "Quelloffenes parametrisches 3D-CAD in Rust. Lizenziert unter MIT OR Apache-2.0.",
|
||||
"Opens your browser and copies the report text for you to paste into GitHub.": "Öffnet den Browser und kopiert den Berichtstext, den Sie anschließend auf GitHub einfügen können.",
|
||||
"Opens your browser. Review and submit your report on GitHub.": "Öffnet den Browser. Prüfen Sie den Bericht und reichen Sie ihn auf GitHub ein.",
|
||||
"Operator": "Operator",
|
||||
"Orbit (right drag)": "Drehen (mit rechts ziehen)",
|
||||
"Other side": "Andere Seite",
|
||||
"Other surface (mutual trim)": "Anderer Flächenkörper (gegenseitig trimmen)",
|
||||
"Other way": "Entgegengesetzte Richtung",
|
||||
"Outer Sharp": "Außenkante",
|
||||
"Outer radius": "Außenradius",
|
||||
"Outside": "Außen",
|
||||
"Overall length": "Gesamtlänge",
|
||||
"Param. Graph": "Param.-Graph",
|
||||
@@ -318,9 +380,11 @@
|
||||
"Path": "Pfad",
|
||||
"Pattern": "Muster",
|
||||
"Per Edge": "Pro Kante",
|
||||
"Physical material definitions": "Definitionen physikalischer Materialien",
|
||||
"Pick the tool bodies": "Werkzeugkörper wählen",
|
||||
"Picked": "Ausgewählte",
|
||||
"Picked point": "Gewählter Punkt",
|
||||
"Pitch": "Steigung",
|
||||
"Pivot": "Drehpunkt",
|
||||
"Place at the origin instead": "Stattdessen im Ursprung platzieren",
|
||||
"Plastic Rules": "Kunststoffregeln",
|
||||
@@ -350,6 +414,7 @@
|
||||
"Recover": "Wiederherstellen",
|
||||
"Recover unsaved design?": "Nicht gespeichertes Design wiederherstellen?",
|
||||
"Rectangular": "Rechteckig",
|
||||
"Rectangular Tube": "Rechteckrohr",
|
||||
"Reference face": "Referenzfläche",
|
||||
"Remove Tools": "Werkzeuge entfernen",
|
||||
"Remove condition": "Bedingung entfernen",
|
||||
@@ -360,11 +425,15 @@
|
||||
"Remove screenshot": "Screenshot entfernen",
|
||||
"Remove the column": "Spalte entfernen",
|
||||
"Remove the track": "Spur entfernen",
|
||||
"Remove this bend": "Diese Biegung entfernen",
|
||||
"Remove this point": "Diesen Punkt entfernen",
|
||||
"Rename Feature": "Merkmal umbenennen",
|
||||
"Rename Folder": "Ordner umbenennen",
|
||||
"Render Stage": "Renderphase",
|
||||
"Replace existing library file": "Vorhandene Bibliotheksdatei ersetzen",
|
||||
"Report a bug — review a screenshot and open a GitHub draft": "Fehler melden — Screenshot prüfen und einen GitHub-Entwurf öffnen",
|
||||
"Report text copied. Paste it into GitHub and submit your report there.": "Berichtstext kopiert. Fügen Sie ihn auf GitHub ein und reichen Sie den Bericht dort ein.",
|
||||
"Reports are public. A GitHub account is required.": "Berichte sind öffentlich. Ein GitHub-Konto ist erforderlich.",
|
||||
"Reset Toolbar": "Symbolleiste zurücksetzen",
|
||||
"Resize Part": "Teil skalieren",
|
||||
"Restore View": "Ansicht wiederherstellen",
|
||||
@@ -380,31 +449,40 @@
|
||||
"Revert Pos.": "Pos. zurücksetzen",
|
||||
"Revert Position": "Position zurücksetzen",
|
||||
"Review the report and screenshot before opening GitHub.": "Prüfen Sie Bericht und Screenshot, bevor Sie GitHub öffnen.",
|
||||
"Review your report on GitHub and click Submit new issue to publish it.": "Prüfen Sie Ihren Bericht auf GitHub und klicken Sie auf „Submit new issue“, um ihn zu veröffentlichen.",
|
||||
"Rib Length": "Rippenlänge",
|
||||
"Rib Offset": "Rippenversatz",
|
||||
"Rib Thickness": "Rippendicke",
|
||||
"Ribs": "Rippen",
|
||||
"Right Middle": "Rechts Mitte",
|
||||
"Rim Edge": "Randkante",
|
||||
"Ring of tools on the right button": "Werkzeugring auf der rechten Maustaste",
|
||||
"Roll Back Here": "Hierher zurücksetzen",
|
||||
"Roll History Marker Here": "Verlaufsmarkierung hierher verschieben",
|
||||
"Root radius": "Kehlradius",
|
||||
"Round": "Rund",
|
||||
"Round Bar": "Rundstab",
|
||||
"Round Tube": "Rundrohr",
|
||||
"Rule": "Rule",
|
||||
"Rule name": "Regelname",
|
||||
"Rules run from top to bottom. Matched drives change effective values.": "Regeln werden von oben nach unten ausgeführt. Zutreffende Steuerungen ändern die wirksamen Werte.",
|
||||
"SECTION": "SCHNITT",
|
||||
"SURFACE QUALITY": "OBERFLÄCHENQUALITÄT",
|
||||
"Same way": "Gleiche Richtung",
|
||||
"Save Rule": "Regel speichern",
|
||||
"Save View": "Ansicht speichern",
|
||||
"Save screenshot…": "Screenshot speichern…",
|
||||
"Save the study as an animated GIF, seen as the viewport shows it": "Die Studie als animiertes GIF speichern, so wie der Ansichtsbereich sie zeigt",
|
||||
"Saved preview. Geometry is being checked before editing.": "Gespeicherte Vorschau. Die Geometrie wird vor dem Bearbeiten geprüft.",
|
||||
"Scale factor": "Skalierungsfaktor",
|
||||
"Scene": "Szene",
|
||||
"Screenshot (optional)": "Screenshot (optional)",
|
||||
"Search": "Suchen",
|
||||
"Search commands": "Befehle suchen",
|
||||
"Search this library": "Diese Bibliothek durchsuchen",
|
||||
"Second plane": "Zweite Ebene",
|
||||
"Section": "Schnitt",
|
||||
"Section (optional)": "Abschnitt (optional)",
|
||||
"Section position": "Lage des Querschnitts",
|
||||
"Sections (one sketch each)": "Querschnitte (je eine Skizze)",
|
||||
"Select Other": "Andere auswählen",
|
||||
@@ -419,6 +497,7 @@
|
||||
"Shape": "Form",
|
||||
"Sheet Rules": "Blechregeln",
|
||||
"Show Agent Cursor": "Agenten-Cursor anzeigen",
|
||||
"Show ghost": "Geistermodell anzeigen",
|
||||
"Show in folder": "Im Ordner anzeigen",
|
||||
"Show the pointer an AI agent moves (#35)": "Den Zeiger anzeigen, den ein KI-Agent bewegt (#35)",
|
||||
"Show tool at cursor": "Werkzeug am Cursor anzeigen",
|
||||
@@ -431,6 +510,7 @@
|
||||
"Sketch plane has no body-face attachment.": "Die Skizzenebene hat keine Anbindung an eine Körperfläche.",
|
||||
"Sketch points": "Skizzenpunkte",
|
||||
"Slot width": "Langlochbreite",
|
||||
"Snap to face and edge centres": "An Flächen- und Kantenmittelpunkten einrasten",
|
||||
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft wurde beendet, bevor diese Designs gespeichert wurden. Ihr letzter Autosave kann geöffnet werden.",
|
||||
"Specialise": "Spezialisieren",
|
||||
"Speed": "Geschwindigkeit",
|
||||
@@ -444,23 +524,30 @@
|
||||
"Start continuity": "Startstetigkeit",
|
||||
"Step": "Schritt",
|
||||
"Steps": "Schritte",
|
||||
"Steps to reproduce (optional)": "Schritte zur Reproduktion (optional)",
|
||||
"Stitch the kept pieces": "Behaltene Teile vernähen",
|
||||
"Stitch to both bodies": "Mit beiden Körpern vernähen",
|
||||
"Studio": "Studio",
|
||||
"Study": "Untersuchung",
|
||||
"Style": "Stil",
|
||||
"Summary": "Zusammenfassung",
|
||||
"Suppress": "Unterdrücken",
|
||||
"Suppress Selected Folders": "Ausgewählte Ordner unterdrücken",
|
||||
"Suppressed": "Unterdrückt",
|
||||
"Surface": "Flächenkörper",
|
||||
"Surface, or faces to turn over": "Fläche oder umzudrehende Flächen",
|
||||
"Swap Ends": "Enden vertauschen",
|
||||
"TRIM": "TRIMMEN",
|
||||
"Tangent": "Tangential",
|
||||
"Tangent (G1)": "Tangente (G1)",
|
||||
"Tangent Chain": "Tangentenkette",
|
||||
"Tangent chain": "Tangentialkette",
|
||||
"Tangent to Edge": "Tangential an Kante",
|
||||
"Tap drill diameter": "Kernlochdurchmesser",
|
||||
"Target": "Ziel",
|
||||
"Target Body": "Zielkörper",
|
||||
"Tear": "Reißen",
|
||||
"Technical details": "Technische Details",
|
||||
"The dashed sketch is a saved plane guide. Select a new face to repair the attachment.": "Die gestrichelte Skizze ist eine gespeicherte Ebenenführung. Wählen Sie eine neue Fläche, um die Anbindung zu reparieren.",
|
||||
"The saved author occurrence is missing. Select a valid author placement before rebinding.": "Das gespeicherte Autorvorkommen fehlt. Wählen Sie vor dem erneuten Anbinden eine gültige Autorplatzierung.",
|
||||
"Then": "Then",
|
||||
@@ -472,20 +559,28 @@
|
||||
"This child is shared. Deleting it removes it from every copy of its parent.": "Dieses untergeordnete Element ist geteilt. Löschen entfernt es aus jeder Kopie des übergeordneten Elements.",
|
||||
"This child is shared. Position changes apply to every copy of its parent.": "Dieses untergeordnete Element ist geteilt. Positionsänderungen gelten für jede Kopie des übergeordneten Elements.",
|
||||
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Diese Fläche kann keine dauerhafte Anbindung bieten. Wählen Sie eine andere Fläche oder verwenden Sie ausdrücklich eine feste Ebene.",
|
||||
"This image is not attached to GitHub yet. Copy or save it, then attach it on GitHub.": "Dieses Bild wurde noch nicht an GitHub angehängt. Kopieren oder speichern Sie es und fügen Sie es anschließend Ihrem GitHub-Bericht hinzu.",
|
||||
"Thread depth": "Gewindetiefe",
|
||||
"Thread diameter": "Gewindedurchmesser",
|
||||
"To": "Bis",
|
||||
"To Offset": "Bis Versatz",
|
||||
"To edges": "Zielkanten",
|
||||
"Toe radius": "Kantenradius",
|
||||
"Tolerance": "Toleranz",
|
||||
"Too close": "Zu nah",
|
||||
"Tool Bodies": "Werkzeugkörper",
|
||||
"Tools": "Werkzeuge",
|
||||
"Tools, clockwise from the top": "Werkzeuge, im Uhrzeigersinn von oben",
|
||||
"Top Left": "Oben links",
|
||||
"Top Middle": "Oben Mitte",
|
||||
"Top Right": "Oben rechts",
|
||||
"Trimming tool (plane, face or curves)": "Trimmwerkzeug (Ebene, Fläche oder Kurven)",
|
||||
"Turn off section analysis before exporting the view.": "Deaktivieren Sie die Schnittanalyse, bevor Sie die Ansicht exportieren.",
|
||||
"Type": "Typ",
|
||||
"UNTRIM": "TRIMMEN AUFHEBEN",
|
||||
"Unit": "Einheit",
|
||||
"Unsuppress": "Unterdrückung aufheben",
|
||||
"Unsuppress Selected Folders": "Unterdrückung der ausgewählten Ordner aufheben",
|
||||
"Updating the preview": "Vorschau wird aktualisiert",
|
||||
"Use active author placement": "Aktive Autorplatzierung verwenden",
|
||||
"Use fixed plane": "Feste Ebene verwenden",
|
||||
@@ -504,6 +599,10 @@
|
||||
"Wall": "Wand",
|
||||
"Wall Location": "Wandlage",
|
||||
"Wall Thickness": "Wandstärke",
|
||||
"Web thickness": "Stegdicke",
|
||||
"What did you do just before the problem? A short list is enough": "Was haben Sie unmittelbar vor dem Auftreten des Problems getan? Eine kurze Liste genügt.",
|
||||
"What did you expect to see?": "Was hatten Sie erwartet?",
|
||||
"What happened?": "Was ist passiert?",
|
||||
"When": "When",
|
||||
"Width": "Breite",
|
||||
"Will fail": "Schlägt fehl",
|
||||
@@ -522,6 +621,34 @@
|
||||
"Z angle": "Z-Winkel",
|
||||
"Z distance": "Z-Abstand",
|
||||
"Zebra": "Zebra",
|
||||
"ai.connected_toast": "SolidCraft ist jetzt in {clients} verfügbar. Starten Sie diese neu, um es zu nutzen (Einstellungen > Assistent).",
|
||||
"ai.prefs.allow_control": "Verbindungen von KI-Agenten zulassen (Steuerkanal / MCP)",
|
||||
"ai.prefs.allow_control_note": "Öffnet einen Steuerkanal nur auf diesem Computer (127.0.0.1, Port 27878 oder der nächste freie). Ein verbindendes Programm muss zusätzlich ein geheimes Token vorweisen, das nur Ihr Benutzerkonto lesen kann und bei jedem Start neu erzeugt wird. Wirkt ab dem nächsten Start von SolidCraft. Aus: Es wartet nichts auf Verbindungen, außer Sie starten SolidCraft mit --control.",
|
||||
"ai.prefs.availability": "Assistenten-Steuerung",
|
||||
"ai.prefs.background_commands": "Agentenbefehle im Hintergrund ausführen",
|
||||
"ai.prefs.connect_apps": "SolidCraft für KI-Apps auf diesem Computer verfügbar machen",
|
||||
"ai.prefs.connect_apps_note": "Trägt SolidCraft beim Start als MCP-Server in die auf diesem Computer gefundenen KI-Apps ein (OpenCode, Claude Desktop, Claude Code, Cursor, Codex, Gemini CLI, Copilot CLI, Windsurf, Zed, VS Code), damit ein Agent es ohne Einrichtung nutzen kann. Nur der Eintrag „solidcraft“ wird hinzugefügt oder sein Pfad aktualisiert; ein von Ihnen geänderter Eintrag bleibt unberührt, und die Datei wird vorher gesichert. Aus: Die hinzugefügten Einträge werden entfernt. Hilfe > KI-Assistenten verbinden… erledigt das von Hand.",
|
||||
"ai.prefs.follow_camera": "Kamera zu Skizzen drehen",
|
||||
"ai.prefs.follow_camera_off": "Die automatische Kameraführung ist aus.",
|
||||
"ai.prefs.follow_camera_on": "Die Kamera dreht sich zu Skizzen, die der Agent erstellt.",
|
||||
"ai.prefs.intro": "Agenten, Berechtigungen und wie ihre Arbeit angezeigt wird.",
|
||||
"ai.prefs.make_default": "Standardmäßig verwenden",
|
||||
"ai.prefs.no_agents": "Noch keine Agenten. Fügen Sie einen Agenten hinzu oder aktualisieren Sie, um installierte Agenten zu finden.",
|
||||
"ai.prefs.no_saved_approvals": "Keine gespeicherten Freigaben.",
|
||||
"ai.prefs.override_all_warning": "Dieser Agent darf das Design ohne Rückfrage speichern, überschreiben, exportieren oder ersetzen.",
|
||||
"ai.prefs.permission_all": "Alles erlauben",
|
||||
"ai.prefs.permission_all_summary": "Verfügbare SolidCraft-Werkzeuge werden ohne Rückfrage ausgeführt.",
|
||||
"ai.prefs.permission_ask": "Vor Änderungen fragen",
|
||||
"ai.prefs.permission_ask_summary": "Jede Designänderung und Dateiaktion bestätigen.",
|
||||
"ai.prefs.permission_edits": "Modelländerungen erlauben",
|
||||
"ai.prefs.permission_edits_summary": "Modelländerungen werden ohne Rückfrage ausgeführt; Datei- und destruktive Aktionen fragen weiterhin nach.",
|
||||
"ai.prefs.permission_scope": "Gilt nur für SolidCraft-Werkzeuge. Shell und Dateiänderungen des Agenten unterliegen dessen eigenen Berechtigungen.",
|
||||
"ai.prefs.pointer_preview_hidden": "Zeiger ausgeblendet",
|
||||
"ai.prefs.pointer_preview_speed": "Agentenzeiger · {speed}",
|
||||
"ai.prefs.pointer_speed": "Bewegungsgeschwindigkeit",
|
||||
"ai.prefs.privacy_note": "Die Unterhaltung geht nur an den von Ihnen gewählten Agenten oder API-Endpunkt. API-Schlüssel werden im Schlüsselbund des Systems gespeichert.",
|
||||
"ai.prefs.show_pointer": "Agentenzeiger anzeigen",
|
||||
"ai.prefs.turn_limit_hint": "Höchstzahl designändernder Werkzeugaufrufe, die der Assistent für eine Nachricht ausführen darf.",
|
||||
"angle, height": "Winkel, Höhe",
|
||||
"appearance.dielectric_ior": "Brechungsindex des Dielektrikums",
|
||||
"appearance.metallic": "Metallanteil",
|
||||
@@ -552,8 +679,13 @@
|
||||
"cmd.appearance_assign": "Erscheinungsbild",
|
||||
"cmd.appearance_library": "Erscheinungsbild-Bibliothek",
|
||||
"cmd.appearance_list": "Erscheinungsbilder auflisten",
|
||||
"cmd.appearance_paint": "Aussehen aufmalen",
|
||||
"cmd.appearance_pick_up": "Aussehen aufnehmen",
|
||||
"cmd.appearance_replace": "Erscheinungsbild ersetzen",
|
||||
"cmd.assembly_bom": "Stückliste",
|
||||
"cmd.body_rename": "Körper umbenennen",
|
||||
"cmd.browser_collapse_all": "Alles einklappen",
|
||||
"cmd.browser_expand_all": "Alles ausklappen",
|
||||
"cmd.browser_group": "Neue Gruppe",
|
||||
"cmd.browser_move": "Browser-Elemente verschieben",
|
||||
"cmd.browser_order": "Browser-Elemente ordnen",
|
||||
@@ -565,11 +697,13 @@
|
||||
"cmd.canvas_delete": "Zeichenfläche löschen",
|
||||
"cmd.canvas_edit": "Zeichenfläche bearbeiten",
|
||||
"cmd.canvas_insert": "Zeichenfläche",
|
||||
"cmd.canvas_to_sketch": "Skizze aus Zeichenfläche",
|
||||
"cmd.component_activate": "Komponente aktivieren",
|
||||
"cmd.component_break_link": "Verknüpfung trennen",
|
||||
"cmd.component_capture_position": "Position erfassen",
|
||||
"cmd.component_copies": "Identische Kopien finden",
|
||||
"cmd.component_create": "Neue Komponente",
|
||||
"cmd.component_cycle_color": "Komponentenfarbe wechseln",
|
||||
"cmd.component_delete": "Komponente löschen",
|
||||
"cmd.component_extract": "In Datei extrahieren",
|
||||
"cmd.component_from_bodies": "Komponenten aus Körpern erstellen",
|
||||
@@ -634,6 +768,7 @@
|
||||
"cmd.document_revision": "Konstruktionsrevision",
|
||||
"cmd.document_units": "Einheiten der Konstruktion ändern",
|
||||
"cmd.edit_checkpoint": "Prüfpunkt",
|
||||
"cmd.edit_repeat": "Letzten Befehl wiederholen",
|
||||
"cmd.edit_restore_checkpoint": "Prüfpunkt wiederherstellen",
|
||||
"cmd.engine_commands": "Befehle auflisten",
|
||||
"cmd.engine_describe": "Befehl beschreiben",
|
||||
@@ -646,6 +781,7 @@
|
||||
"cmd.file_export": "Exportieren",
|
||||
"cmd.file_insert_mesh": "Netz einfügen",
|
||||
"cmd.file_insert_step": "STEP einfügen",
|
||||
"cmd.file_open_in_easyprint": "Mit EasyPrint öffnen",
|
||||
"cmd.file_save_mesh": "Als Netz speichern",
|
||||
"cmd.file_slicers": "Installierte Slicer",
|
||||
"cmd.frame_member": "Rahmenelement",
|
||||
@@ -655,6 +791,8 @@
|
||||
"cmd.inspect_accessibility": "Zugänglichkeitsanalyse",
|
||||
"cmd.inspect_center_of_mass": "Massenschwerpunkt",
|
||||
"cmd.inspect_clearance": "Freiraum",
|
||||
"cmd.inspect_colored_components": "Komponentenfarben einschalten",
|
||||
"cmd.inspect_colored_components_disable": "Komponentenfarben ausschalten",
|
||||
"cmd.inspect_compare": "Körper vergleichen",
|
||||
"cmd.inspect_continuity": "Kontinuitätsprüfung",
|
||||
"cmd.inspect_curvature_comb": "Krümmungskamm-Analyse",
|
||||
@@ -664,6 +802,7 @@
|
||||
"cmd.inspect_interference": "Eingriff",
|
||||
"cmd.inspect_isocurve": "Isokurvenanalyse",
|
||||
"cmd.inspect_minimum_radius": "Mindestradiusanalyse",
|
||||
"cmd.inspect_parameter_sweep": "Parametervariation",
|
||||
"cmd.inspect_silhouette": "Silhouette",
|
||||
"cmd.inspect_zebra": "Zebra-Analyse",
|
||||
"cmd.joint_as_built": "Fertigungsgelenk",
|
||||
@@ -708,8 +847,10 @@
|
||||
"cmd.motion_plot": "Diagramm der Bewegungsuntersuchung",
|
||||
"cmd.motion_study": "Bewegungsuntersuchung",
|
||||
"cmd.motion_trace": "Bewegungsbahn",
|
||||
"cmd.motion_trace_edit": "Bewegungsbahn bearbeiten",
|
||||
"cmd.motion_trace_keep": "Bewegungsbahn behalten",
|
||||
"cmd.occurrence_copy": "Einfügen (Instanz)",
|
||||
"cmd.occurrence_drag": "Instanz ziehen",
|
||||
"cmd.occurrence_ground": "Festsetzen",
|
||||
"cmd.occurrence_move": "Instanz verschieben",
|
||||
"cmd.occurrence_properties": "Physikalische Eigenschaften der Instanz",
|
||||
@@ -737,10 +878,14 @@
|
||||
"cmd.plastic_rest": "Auflage",
|
||||
"cmd.plastic_rules": "Kunststoffregeln auflisten",
|
||||
"cmd.plastic_snap_fit": "Rastverbindung",
|
||||
"cmd.render_aging_describe": "Mehrschichtige Oberflächenalterung",
|
||||
"cmd.render_backends": "Render-Backends",
|
||||
"cmd.render_batch": "Alle Aufnahmen rendern",
|
||||
"cmd.render_camera_fit": "Renderobjekt einpassen",
|
||||
"cmd.render_camera_get": "Renderkamera prüfen",
|
||||
"cmd.render_cancel": "Rendering abbrechen",
|
||||
"cmd.render_compare": "Bilder vergleichen",
|
||||
"cmd.render_effects_describe": "Objektiv- und Kreativeffekte",
|
||||
"cmd.render_export": "PNG exportieren",
|
||||
"cmd.render_hdr_inspect": "HDR-Quelle untersuchen",
|
||||
"cmd.render_library_appearance_apply": "Opakes Bibliotheksaussehen anwenden",
|
||||
@@ -748,19 +893,30 @@
|
||||
"cmd.render_library_environment_apply": "Integrierte HDR-Umgebung anwenden",
|
||||
"cmd.render_library_list": "Render-Bibliothek durchsuchen",
|
||||
"cmd.render_library_physical_prepare": "Prepare Physical Reference",
|
||||
"cmd.render_library_preview": "Originale Oberflächentextur anzeigen",
|
||||
"cmd.render_library_studio_apply": "Erstellte Studiolichter anwenden",
|
||||
"cmd.render_library_studio_prepare": "Erstellte Studiolichter vorbereiten",
|
||||
"cmd.render_library_surface_bind": "Save Surface Binding",
|
||||
"cmd.render_library_surface_prepare": "Erstellte Oberflächenmaps vorbereiten",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "Ziele für Render-Ressourcen suchen",
|
||||
"cmd.render_lights_solo": "Licht allein anzeigen",
|
||||
"cmd.render_optics_bind": "Optische Einstellungen zuweisen",
|
||||
"cmd.render_optics_unbind": "Zuweisung optischer Einstellungen entfernen",
|
||||
"cmd.render_preflight": "Renderanfrage prüfen",
|
||||
"cmd.render_preset_apply": "Studio-Voreinstellung anwenden",
|
||||
"cmd.render_preset_resolve": "Studio-Voreinstellung überprüfen",
|
||||
"cmd.render_quality_prepare": "Festes Sampling-Budget überprüfen",
|
||||
"cmd.render_result_pin": "Angezeigtes Render-Ergebnis behalten",
|
||||
"cmd.render_result_regrade": "Lineares Master-Rendering erneut farbkorrigieren",
|
||||
"cmd.render_scene": "Renderszene prüfen",
|
||||
"cmd.render_settings_apply": "Renderkamera anwenden",
|
||||
"cmd.render_settings_capture_hdr": "Render-Einstellungen mit HDR speichern",
|
||||
"cmd.render_settings_get": "Rendereinstellungen",
|
||||
"cmd.render_settings_set": "Rendereinstellungen speichern",
|
||||
"cmd.render_shot_duplicate": "Render-Aufnahme duplizieren",
|
||||
"cmd.render_shot_remove": "Render-Aufnahme entfernen",
|
||||
"cmd.render_shot_rename": "Render-Aufnahme umbenennen",
|
||||
"cmd.render_stage_backdrop": "Physischen Renderhintergrund speichern",
|
||||
"cmd.render_stage_clear": "Remove Render Stage",
|
||||
"cmd.render_stage_ground": "Save Render Ground",
|
||||
@@ -775,6 +931,7 @@
|
||||
"cmd.sheet_fold": "Falten",
|
||||
"cmd.sheet_hem": "Umkantung",
|
||||
"cmd.sheet_manage_rules": "Blechregeln",
|
||||
"cmd.sheet_path_flange": "Pfadflansch",
|
||||
"cmd.sheet_perforate": "Perforieren",
|
||||
"cmd.sheet_refold": "Wieder falten",
|
||||
"cmd.sheet_rules": "Blechregeln auflisten",
|
||||
@@ -786,6 +943,7 @@
|
||||
"cmd.sketch_auto_constrain_from_datum": "Auto-Bedingung von Bezug",
|
||||
"cmd.sketch_auto_project": "Kanten automatisch auf Referenz projizieren",
|
||||
"cmd.sketch_blend_curve": "Übergangskurve",
|
||||
"cmd.sketch_cancel": "Skizze abbrechen",
|
||||
"cmd.sketch_chain": "Kette",
|
||||
"cmd.sketch_chamfer_distance_angle": "Abschrägung mit Abstand und Winkel",
|
||||
"cmd.sketch_chamfer_equal_distance": "Abschrägung mit gleichem Abstand",
|
||||
@@ -850,8 +1008,11 @@
|
||||
"cmd.sketch_spline_control_point": "Spline mit Kontrollpunkten",
|
||||
"cmd.sketch_spline_control_point_5": "Spline mit Kontrollpunkten (Grad 5)",
|
||||
"cmd.sketch_spline_fit_point": "Spline mit Fitpunkten",
|
||||
"cmd.sketch_spline_insert_point": "Splinepunkt hinzufügen",
|
||||
"cmd.sketch_spun_profile": "Gedrehtes Profil",
|
||||
"cmd.sketch_toggle_diameter": "Radius / Durchmesser umschalten",
|
||||
"cmd.sketch_toggle_driven": "Abhängiges Maß umschalten",
|
||||
"cmd.sketch_transform": "Transformieren",
|
||||
"cmd.sketch_trim_path": "Entlang Pfad trimmen",
|
||||
"cmd.solid_align": "Ausrichten",
|
||||
"cmd.solid_boundary_fill": "Begrenzungsfüllung",
|
||||
@@ -897,13 +1058,21 @@
|
||||
"cmd.timeline_suppress": "Merkmal unterdrücken",
|
||||
"cmd.view_ambient_occlusion": "Umgebungsverdeckung",
|
||||
"cmd.view_apply": "Benannte Ansicht wiederherstellen",
|
||||
"cmd.view_back": "Rückansicht",
|
||||
"cmd.view_bottom": "Untersicht",
|
||||
"cmd.view_delete": "Benannte Ansicht löschen",
|
||||
"cmd.view_front": "Vorderansicht",
|
||||
"cmd.view_graphics_preset": "Grafikprofil",
|
||||
"cmd.view_isometric": "Isometrische Ansicht",
|
||||
"cmd.view_left": "Linke Seitenansicht",
|
||||
"cmd.view_list": "Benannte Ansichten auflisten",
|
||||
"cmd.view_navigate": "Ansicht navigieren",
|
||||
"cmd.view_normal_to": "Senkrecht zur Auswahl",
|
||||
"cmd.view_rename": "Benannte Ansicht umbenennen",
|
||||
"cmd.view_right": "Rechte Seitenansicht",
|
||||
"cmd.view_save": "Neue benannte Ansicht",
|
||||
"cmd.view_shots_strip": "Aufnahmenleiste",
|
||||
"cmd.view_top": "Draufsicht",
|
||||
"color.copy": "Klicken, um Farbwerte zu kopieren",
|
||||
"color.edit": "Klicken, um Farbe zu bearbeiten",
|
||||
"color.gamma": "Farbwerte im Gammaraum 0-255 anzeigen",
|
||||
@@ -944,6 +1113,7 @@
|
||||
"crash.report": "Bericht…",
|
||||
"crash.unclean_explanation": "Beim späteren Start erkannt; der genaue Zeitpunkt des Beendens wurde nicht aufgezeichnet. Auch ein Herunterfahren des Systems oder ein erzwungener Stopp kann ein unsauberes Beenden verursachen.",
|
||||
"delete.and_more": "… und {count} weitere",
|
||||
"diagnostic.empty_boolean_component": "In Komponente '{component}' gibt es keinen Körper zum Abziehen oder für eine Schnittmenge; das Werkzeug überschneidet sich eventuell mit '{body}' in Komponente '{other}' – aktivieren Sie diese Komponente oder wählen Sie den Körper als Ziel",
|
||||
"dialog.bodies_count": "{count} Körper",
|
||||
"dialog.clearance_invalid": "der Abstand muss eine Länge von 0 oder mehr sein",
|
||||
"dialog.compute": "Berechnen",
|
||||
@@ -959,7 +1129,18 @@
|
||||
"dialog.selection_guidance": "Wählen Sie eine Eingabe aus, um sie zu ändern. Klicken Sie auf ausgewählte Objekte, um sie zu entfernen; Strg/Cmd-Klick schaltet sie ebenfalls um. Prüfen Sie die Vorschau und drücken Sie dann OK.",
|
||||
"dialog.selection_step": "{step} von {total}: {input} auswählen",
|
||||
"dialog.step": "Schritt",
|
||||
"document.changed_on_disk": "{name} wurde auf dem Datenträger geändert",
|
||||
"document.changed_on_disk_detail": "{name} wurde seit dem Öffnen oder letzten Speichern von einem anderen Programm oder Computer geändert. „Überschreiben“ ersetzt diese Änderungen durch Ihre; „Kopie speichern“ behält beide.",
|
||||
"document.copy_name": "{name} - Kopie",
|
||||
"document.open_anyway": "Trotzdem öffnen",
|
||||
"document.open_elsewhere": "{name} ist bereits geöffnet",
|
||||
"document.open_elsewhere_detail": "{name} ist in SolidCraft {app} auf {who} geöffnet, seit {when}. Wenn Sie beide speichern, verliert einer von Ihnen Arbeit. Öffnen Sie die Datei schreibgeschützt, um sie anzusehen, ohne sie zu überschreiben.",
|
||||
"document.open_read_only": "Schreibgeschützt öffnen",
|
||||
"document.opened_read_only": "Schreibgeschützt geöffnet: Speichern fragt nach einer neuen Datei",
|
||||
"document.overwrite": "Überschreiben",
|
||||
"document.read_only_save": "Dieses Design wurde schreibgeschützt geöffnet: Speichern Sie es als neue Datei",
|
||||
"document.save_changes": "Änderungen in {name} speichern?",
|
||||
"document.save_copy": "Kopie speichern…",
|
||||
"document.unsaved_changes": "{name} enthält ungespeicherte Änderungen. Wenn Sie nicht speichern, gehen sie verloren.",
|
||||
"drive.stopped_by_contact": "Angehalten bei {value}: {a} würde {b} durchdringen",
|
||||
"drive.stopped_by_loop": "Angehalten bei {value}: die Schleife über {joint} lässt sich nicht weiter schließen",
|
||||
@@ -976,9 +1157,11 @@
|
||||
"dxf.progress.write": "DXF schreiben (5/5)",
|
||||
"dxf.tolerance": "Kurventoleranz",
|
||||
"dxf.tolerance_help": "Nur sichtbare Körper und angezeigte Skizzen. Kurven werden durch gerade Segmente angenähert. Eine kleinere Toleranz liefert feinere Kurven und benötigt mehr Zeit und Speicher.",
|
||||
"file.open.drawing_filter": "Designs, CAD-Dateien, Netze und Zeichnungen",
|
||||
"file_load.built": "Bisher erstellt: {built} von {total} Merkmalen.",
|
||||
"file_load.converting": "Volumenkörper {done} von {total} wird konvertiert",
|
||||
"file_load.inserting": "Geometrie wird eingefügt",
|
||||
"file_load.link_item": "{name} ({done} von {total})",
|
||||
"file_load.opening": "Design wird geöffnet",
|
||||
"file_load.preparing_thumbnail": "Vorschaubild wird vorbereitet...",
|
||||
"file_load.preparing_view": "Ansicht wird vorbereitet...",
|
||||
@@ -988,17 +1171,33 @@
|
||||
"file_load.rebuilding": "Merkmal {done} von {total} wird neu aufgebaut",
|
||||
"file_load.recovering": "Design wird wiederhergestellt",
|
||||
"file_load.stopping": "Warten, bis der vorherige Vorgang beendet ist...",
|
||||
"file_load.updating_links": "Verknüpfungen werden aktualisiert",
|
||||
"file_load.waiting": "Warten auf Dateivorgang",
|
||||
"fits the face, e.g. M8": "passt zur Fläche, z. B. M8",
|
||||
"from the profile": "aus dem Profil",
|
||||
"from the rule": "aus der Regel",
|
||||
"help.apache": "Apache-Lizenz 2.0",
|
||||
"help.attributions": "Quellenangaben (ATTRIBUTION.md)",
|
||||
"help.build": "Version {version} · Commit {commit} · erstellt am {date}",
|
||||
"help.connect_note": "Starten Sie jeden Assistenten neu, damit er den SolidCraft-Server lädt. Jede Datei wurde vor der Änderung als .bak gesichert.",
|
||||
"help.connect_title": "KI-Assistenten verbinden",
|
||||
"help.font_details": "Die Oberfläche verwendet die integrierten Schriftarten von egui (Ubuntu Light und Hack unter der Ubuntu Font Licence und der MIT/Bitstream-Vera-Lizenz; Noto Emoji und die Emoji-Symbolschrift unter OFL und MIT). Skizzentext verwendet Liberation Sans (SIL OFL 1.1). Das optionale Schriftpaket craft-fonts von The Crafting Apps (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC, Noto Sans Arabic; SIL OFL 1.1) ist nicht in SolidCraft-Builds enthalten.",
|
||||
"help.fonts": "Schriftarten",
|
||||
"help.licences": "Lizenzen",
|
||||
"help.mit": "MIT-Lizenz",
|
||||
"help.notice": "NOTICE",
|
||||
"help.solid.chamfer": "Schneidet die gewählten Kanten mit einer ebenen Fase im eingestellten Abstand ab. Damit brechen Sie scharfe Kanten oder erleichtern das Einführen eines Stifts oder einer Schraube.",
|
||||
"help.solid.combine": "Kombiniert Körper: vereinigt sie, zieht sie von einem Zielkörper ab oder behält nur das gemeinsame Volumen; die Werkzeugkörper können erhalten bleiben. Damit fügen Sie Teile zusammen, schneiden eine Form mit einer anderen aus oder finden, wo sich zwei Körper überschneiden.",
|
||||
"help.solid.extrude": "Zieht ein Skizzenprofil über eine Strecke in die dritte Dimension und fügt dabei Material hinzu oder entfernt es. Damit machen Sie aus einer flachen Kontur einen Block, eine Erhebung oder eine Tasche.",
|
||||
"help.solid.fillet": "Rundet die gewählten Kanten mit einem glatten Kreisübergang im eingestellten Radius ab. Damit entschärfen Sie scharfe Kanten für Festigkeit, Griffigkeit oder Optik.",
|
||||
"help.solid.hole": "Bohrt an einem gewählten Punkt auf einer Fläche ein rundes Loch im eingestellten Durchmesser. Für Durchgangsbohrungen für Schrauben, Stifte und andere einfache runde Öffnungen.",
|
||||
"help.solid.loft": "Erzeugt einen glatten Übergangskörper zwischen zwei oder mehr Skizzenprofilen oder von einem Profil zu einem Punkt. Für Übergänge, Trichter, Griffe und alle Formen, deren Querschnitt sich über die Länge ändert.",
|
||||
"help.solid.mirror": "Erzeugt eine gespiegelte Kopie der gewählten Körper oder Features an einer Ebene und kann sie mit dem Original vereinigen. Für symmetrische Teile: Sie modellieren eine Hälfte und erhalten beide.",
|
||||
"help.solid.pattern.circular": "Wiederholt die gewählten Objekte um eine Achse, mit der eingestellten Anzahl und dem Gesamtwinkel. Für Lochkreise, Speichen, Kühlrippen und Zähne.",
|
||||
"help.solid.pattern.rectangular": "Wiederholt die gewählten Objekte in einer oder zwei Richtungen mit der eingestellten Anzahl und dem Abstand. Für Reihen und Raster von Bohrungen, Rippen, Stiften oder Füßen.",
|
||||
"help.solid.revolve": "Dreht ein Skizzenprofil um eine Achse und erzeugt so einen runden Körper. Für Wellen, Knöpfe, Schalen und alle Teile, die um eine Mittellinie rund sind.",
|
||||
"help.solid.shell": "Höhlt einen Körper aus, lässt Wände in der eingestellten Dicke stehen und kann gewählte Flächen öffnen. Für Kästen, Deckel und andere dünnwandige Teile.",
|
||||
"help.solid.sweep": "Führt ein Skizzenprofil entlang eines Pfads und erzeugt so einen Körper. Für Rohre, Schienen, Griffe und alle Teile mit gleichbleibendem Querschnitt entlang einer Kurve.",
|
||||
"help.third_party": "Drittanbieterlizenzen",
|
||||
"home.back": "Zurück zu {name}",
|
||||
"home.crashes": "Absturzberichte",
|
||||
@@ -1064,6 +1263,9 @@
|
||||
"install.steps_intro": "Safari installiert Web-Apps über seine eigenen Menüs:",
|
||||
"install.title": "SolidCraft installieren",
|
||||
"issue.body_label": "Berichtstext",
|
||||
"issue.note_changed_while_waiting": "Einstellungen oder Modell haben sich geändert, während auf die Vorschau gewartet wurde. Nehmen Sie den Screenshot neu auf, um die technischen Details für die aktuelle Ansicht zu aktualisieren.",
|
||||
"issue.note_details_kept": "Screenshot lokal aufgenommen. Ihre bearbeiteten technischen Details wurden beibehalten: Prüfen Sie, ob sie noch zur aktuellen Ansicht passen.",
|
||||
"issue.note_details_updated": "Technische Details an die aktuelle Ansicht angepasst. Screenshot lokal aufgenommen. Prüfen Sie ihn, bevor Sie ihn auf GitHub anhängen.",
|
||||
"issue.note_image_copied": "Fügen Sie das Bild in den GitHub-Entwurf ein oder speichern Sie das PNG, falls das Kopieren von Bildern nicht verfügbar ist.",
|
||||
"issue.note_opened": "Prüfen Sie den GitHub-Entwurf und hängen Sie den Screenshot an. Die Schaltfläche Submit new issue von GitHub veröffentlicht ihn.",
|
||||
"issue.note_opened_copied": "Bericht kopiert. Fügen Sie ihn in den GitHub-Entwurf ein, hängen Sie den Screenshot an und klicken Sie auf GitHub auf Submit new issue.",
|
||||
@@ -1075,6 +1277,8 @@
|
||||
"joint.from_bodies_hint": "Jeder ausgewählte Körper kommt in eine eigene neue Komponente und bleibt, wo er ist.",
|
||||
"joint.one_body": "Beide Auswahlen liegen auf {body}. Wählen Sie die zweite auf einem anderen Teil.",
|
||||
"joint.one_component": "Diese Teile sind Körper einer Komponente: {bodies}. Ein Gelenk bewegt eine Komponente gegenüber einer anderen, daher braucht jedes Teil eine eigene Komponente.",
|
||||
"joint.rigid_group_one_component": "Diese {count} Körper liegen alle in einer Komponente (oder direkt im Design): Verwenden Sie zuerst {command}.",
|
||||
"joint.rigid_group_select_components": "Wählen Sie zwei oder mehr Komponenten aus.",
|
||||
"keymap.command_id": "Befehls-ID",
|
||||
"keymap.empty": "Keine passenden Befehle",
|
||||
"keymap.use_anyway": "{key} hier trotzdem verwenden",
|
||||
@@ -1085,8 +1289,51 @@
|
||||
"manage.material_hint": "Wählen Sie Körper und deren physikalisches Material aus.",
|
||||
"manage.parameters_hint": "Bearbeiten Sie Ausdrücke und Einheiten. Änderungen werden mit der Eingabetaste oder beim Verlassen eines Feldes übernommen.",
|
||||
"manage.rules_hint": "Wählen Sie eine Regel zum Bearbeiten oder erstellen Sie eine neue. Bestätigen Sie, um die Regel zu speichern.",
|
||||
"material.editor.add_property": "Eigenschaft hinzufügen",
|
||||
"material.editor.add_source": "Quelle hinzufügen",
|
||||
"material.editor.assigned_density": "Zugewiesene Dichte",
|
||||
"material.editor.axes": "Materialachsen",
|
||||
"material.editor.axes_numeric": "1 / 2 / 3",
|
||||
"material.editor.axes_wood": "L / R / T",
|
||||
"material.editor.copy_name": "Kopie von {name}",
|
||||
"material.editor.density_range": "Die zugewiesene Dichte muss größer als 0 und höchstens 1000 g/cm³ sein.",
|
||||
"material.editor.designation": "Bezeichnung",
|
||||
"material.editor.duplicate": "Duplizieren",
|
||||
"material.editor.engineering_card": "Technisches Datenblatt",
|
||||
"material.editor.family": "Werkstoffgruppe",
|
||||
"material.editor.glass": "Glas",
|
||||
"material.editor.illustrative": "Beispielwerte",
|
||||
"material.editor.invalid_property": "Nicht unterstützter Eigenschaftstyp.",
|
||||
"material.editor.isotropic": "Isotrop",
|
||||
"material.editor.measurement": "Messung",
|
||||
"material.editor.metal": "Metall",
|
||||
"material.editor.moisture": "Feuchte, bezogen auf Trockenmasse",
|
||||
"material.editor.name_required": "Geben Sie einen Namen mit 1–128 Zeichen ein.",
|
||||
"material.editor.no_draft": "Kein Materialentwurf geöffnet.",
|
||||
"material.editor.number_required": "Geben Sie einen gültigen Zahlenwert ein.",
|
||||
"material.editor.orthotropic": "Orthotrop",
|
||||
"material.editor.other": "Sonstiges",
|
||||
"material.editor.polymer": "Polymer",
|
||||
"material.editor.preserved_appearance": "Beibehaltenes Erscheinungsbild",
|
||||
"material.editor.public_reference": "Öffentliche Quelle",
|
||||
"material.editor.reference": "Referenz",
|
||||
"material.editor.save_or_discard": "Speichern oder verwerfen Sie den Materialentwurf, bevor Sie ein Material zuweisen.",
|
||||
"material.editor.saved": "Material gespeichert. Körperzuweisungen bleiben unverändert.",
|
||||
"material.editor.scope": "Speichern legt dieses Material ab, ohne es Körpern zuzuweisen. Leere Eigenschaften und Bedingungen bleiben unbekannt. Die Dichte im Datenblatt ändert weder die zugewiesene Dichte noch die Masse.",
|
||||
"material.editor.source_id": "Quellen-ID",
|
||||
"material.editor.source_kind": "Quellentyp",
|
||||
"material.editor.source_title": "Quellentitel",
|
||||
"material.editor.sources": "Quellen",
|
||||
"material.editor.stale": "Dieses Material wurde geändert, während der Entwurf geöffnet war. Verwerfen und öffnen Sie es erneut, bevor Sie speichern.",
|
||||
"material.editor.state": "Materialzustand",
|
||||
"material.editor.strain_rate": "Dehnrate",
|
||||
"material.editor.symmetry": "Elastische Symmetrie",
|
||||
"material.editor.temperature": "Temperatur",
|
||||
"material.editor.unknown_card": "Die technischen Eigenschaften sind unbekannt. Beim Speichern bleiben eventuell nur die zugewiesene Dichte und das vorhandene Erscheinungsbild erhalten.",
|
||||
"material.editor.user_supplied": "Vom Benutzer angegeben",
|
||||
"material.editor.wood": "Holz",
|
||||
"material.selection.choose": "Material auswählen",
|
||||
"material.selection.mixed": "Unterschiedliche Materialien",
|
||||
"measure.at": "Bei",
|
||||
"measure.item": "Element {number}",
|
||||
"messages.ago_h": "vor {n} Std.",
|
||||
@@ -1115,6 +1362,9 @@
|
||||
"nav.blender.help": "Mittlere Maustaste dreht, Umschalt+Mitte verschiebt, Strg+Mitte zoomt; rechtes Ziehen lässt die Kamera unverändert",
|
||||
"nav.free_orbit.help": "Maus und 3D-Maus drehen über beide Pole hinweg und behalten die Rollneigung bei. Das Einrasten mit Umschalt ist deaktiviert.",
|
||||
"nav.free_orbit.label": "Freie Drehung",
|
||||
"nav.free_orbit.snap_help": "Maus und 3D-Maus drehen über beide Pole hinweg und behalten die Rollausrichtung bei. Halten Sie beim Ziehen zum Drehen die Umschalttaste gedrückt, um Blickrichtung und Rollausrichtung einrasten zu lassen.",
|
||||
"nav.free_orbit_upright.help": "Seitliches Ziehen mit der Maus dreht das Modell um die senkrechte Achse der Welt; Ziehen nach oben und unten neigt es ohne Begrenzung über den Pol hinweg.",
|
||||
"nav.free_orbit_upright.label": "Um die senkrechte Achse drehen",
|
||||
"nav.fusion.help": "Mittlere Maustaste verschiebt, Umschalt+Mitte dreht, rechte Maustaste dreht",
|
||||
"nav.inventor.help": "Mittlere Maustaste verschiebt, Umschalt+Mitte dreht, Strg+Mitte zoomt, rechte Maustaste dreht",
|
||||
"nav.openscad.help": "Linksziehen auf leerem Hintergrund dreht, Umschalt+Linksziehen zieht ein Auswahlrechteck auf, Skizzengeometrie wird durch Ziehen bearbeitet; rechtes oder mittleres Ziehen verschiebt, Umschalt+rechtes oder Umschalt+mittleres Ziehen zoomt",
|
||||
@@ -1144,7 +1394,21 @@
|
||||
"pick a hole to seat it, or OK places it at the origin": "Wählen Sie eine Bohrung zum Einsetzen, oder OK platziert es im Ursprung",
|
||||
"pick one or two vertices, edges or faces": "Wählen Sie ein oder zwei Ecken, Kanten oder Flächen",
|
||||
"prefs.cpu": "CPU (Software)",
|
||||
"prefs.dialogs": "Dialoge",
|
||||
"prefs.dialogs_edge": "Am Rand der Ansicht",
|
||||
"prefs.dialogs_left_column": "In der linken Spalte",
|
||||
"prefs.dialogs_note": "Wo Befehlsdialoge öffnen: am Rand der Ansicht angedockt oder in der linken Spalte anstelle von Browser und Verlauf, die beim Schließen des Dialogs wie zuvor zurückkehren.",
|
||||
"prefs.history_origin_bodies": "Ursprung und Körper oben zeigen",
|
||||
"prefs.history_origin_bodies_note": "Der Verlauf links oder unter dem Browser beginnt mit dem Körper-Ordner der aktiven Komponente und dem Ursprung, mit Augen und Menüs wie im Browser. Der Verlauf unten bleibt unverändert.",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.origin_plane_names": "Namen der Ursprungsebenen",
|
||||
"prefs.origin_plane_names_note": "Namen in Browser, Dialogen und Listen. {top} ist XY, {front} ist XZ und {right} ist YZ, mit Z nach oben. Befehle, Skripte und gespeicherte Konstruktionen behalten XY, XZ und YZ.",
|
||||
"prefs.theme_follow": "Einer Designdatei folgen",
|
||||
"prefs.theme_follow_error": "Nicht angewendet: {error}. Das letzte gültige Design bleibt aktiv.",
|
||||
"prefs.theme_follow_launch": "Nur für diesen Start (--theme-file); wird neu geladen, sobald ein anderes Werkzeug die Datei überschreibt.",
|
||||
"prefs.theme_follow_note": "Wird neu geladen, sobald ein anderes Werkzeug die Datei überschreibt. Die Auswahl eines Designs beendet das Folgen.",
|
||||
"prefs.theme_follow_off": "Aus",
|
||||
"prefs.theme_follow_stop": "Nicht mehr folgen",
|
||||
"properties.title": "Eigenschaften: {name}",
|
||||
"recovery.days_ago": "vor {count} Tagen",
|
||||
"recovery.detail": "{file} · {features} Merkmale · automatisch gespeichert {when}",
|
||||
@@ -1153,6 +1417,7 @@
|
||||
"recovery.min_ago": "vor {count} Min.",
|
||||
"recovery.never_saved": "nie gespeichert",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.all_shots_label": "Alle Aufnahmen",
|
||||
"render.background": "Szenenhintergrund",
|
||||
"render.bloom_enable": "Darstellungs-Bloom",
|
||||
"render.bloom_help": "Kreativer Ausgabeglanz aus linearen Glanzlichtern mit drei normierten Durchläufen. Radius in Ausgabepixeln; Addition vor sRGB. Keine Linsen-, Volumen- oder Konvergenzsimulation. Das rohe EXR bleibt unverändert.",
|
||||
@@ -1174,8 +1439,17 @@
|
||||
"render.cpu_budget_studio": "Studio (große Bilder)",
|
||||
"render.cpu_budget_triangles": "Dreiecksobergrenze",
|
||||
"render.cpu_budget_workstation": "Workstation (komplexe Szenen)",
|
||||
"render.export_image_label": "Bild exportieren",
|
||||
"render.exr_pending": "Die GPU kann rohe lineare EXR-Dateien behalten. Kompression, mehrschichtige Bilder und zusätzliche Renderpässe bleiben nicht verfügbar.",
|
||||
"render.fit": "Produkt einpassen",
|
||||
"render.fixed_camera": "Kamera",
|
||||
"render.fixed_world": "Welt",
|
||||
"render.heading_batch": "Stapel",
|
||||
"render.heading_frame": "Bildrahmen",
|
||||
"render.heading_lens": "Objektiv",
|
||||
"render.heading_results": "Ergebnisse",
|
||||
"render.heading_shots": "Aufnahmen",
|
||||
"render.hide_shots_label": "Aufnahmenleiste ausblenden",
|
||||
"render.image_cancelled": "Rendering abgebrochen",
|
||||
"render.image_cancelling": "Wird abgebrochen",
|
||||
"render.image_completed": "Bild bereit zum Export",
|
||||
@@ -1199,6 +1473,7 @@
|
||||
"render.image_use_largest": "Größte Größe mit diesem Seitenverhältnis verwenden:",
|
||||
"render.image_width": "Breite",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspector": "Inspektor",
|
||||
"render.library_applied": "Ressourcenvariante angewendet. Vollständigen Renderauftrag vor dem Start prüfen.",
|
||||
"render.library_apply_hdr": "Mit dieser HDR-Umgebung speichern",
|
||||
"render.library_apply_maps": "Erstellte GPU-Oberflächenmaps verwenden",
|
||||
@@ -1234,6 +1509,8 @@
|
||||
"render.library_target": "Zielkörper",
|
||||
"render.library_title": "Render-Ressourcenbibliothek",
|
||||
"render.library_uniform_ack": "Einheitliche Näherung ohne räumliche oder erweiterte Effekte verwenden",
|
||||
"render.light_anchor_pending": "Das Koordinatensystem der Lichter kann noch nicht geändert werden.",
|
||||
"render.lights_fixed_to": "Lichter gebunden an",
|
||||
"render.material_color_replace": "Basismap ersetzt Körperfarbe",
|
||||
"render.material_limits": "Höchstens 128 Körperüberschreibungen, 32 getrennte Glaskörper, 64 Beschichtungen und 128 Texturbindungen. Identische Maps teilen Speicher; Geräte- und Gesamtspeichergrenzen bleiben aktiv.",
|
||||
"render.material_metallic_map": "Metallanteil-Map (linear)",
|
||||
@@ -1243,6 +1520,8 @@
|
||||
"render.opaque_image_summary": "Vorschau-PNG · opakes PBR · Transparenz durch Blending",
|
||||
"render.opaque_preview_help": "Opakes PBR und einfache Farben; Transparenz durch Blending. Brechung, HDRI und finales Rendering sind noch nicht verfügbar.",
|
||||
"render.output_format_status": "PNG enthält das exakte fertige Anzeigebild. Optionales GPU-EXR bewahrt rohe lineare FLOAT32-Strahldichte vor Filtern. Export ersetzt nie durch Vorschaucache oder anderen Auftrag.",
|
||||
"render.output_tools_inspector": "Größe und Format im Ausgabe-Inspektor bearbeiten.",
|
||||
"render.paint_label": "Aufmalen",
|
||||
"render.passive_stage": "Render-only stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "Perspektivische Kamera",
|
||||
@@ -1255,9 +1534,16 @@
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.pick_component": "Komponente",
|
||||
"render.pick_label": "Auswahl",
|
||||
"render.pick_up_label": "Aufnehmen",
|
||||
"render.pick_waiting": "Die Produktauswahl wird noch nicht unterstützt.",
|
||||
"render.preview": "Integrierte Vorschau",
|
||||
"render.preview_help": "Rasterdarstellung mit gemischter Transparenz. Brechung, HDRI und finales Rendering sind noch nicht verfügbar.",
|
||||
"render.preview_lighting_help": "Die Live-Vorschau zeigt nur direktes Licht und keine Schatten.",
|
||||
"render.regrade_label": "Neu abstimmen",
|
||||
"render.reload_settings": "Gespeicherte Einstellungen laden",
|
||||
"render.replace_label": "Ersetzen",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "Gespeicherte Kamera laden",
|
||||
"render.result_reduced_display": "Anzeigevorschau auf die Geräte-/Cachegrenze reduziert. PNG und Export behalten die volle Auflösung; native 100%-Ansicht ist hier nicht verfügbar.",
|
||||
@@ -1284,15 +1570,33 @@
|
||||
"render.ribbon_studios_help": "Implementierte Studios durchsuchen und Ersetzungen vor dem Anwenden prüfen. Konzepte bleiben gekennzeichnet.",
|
||||
"render.ribbon_surface_maps": "Oberflächen",
|
||||
"render.save_setup": "Setup speichern",
|
||||
"render.save_shot": "Aufnahme speichern",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.setup_name": "Name des Setups",
|
||||
"render.shell_tab_appearance": "Aussehen",
|
||||
"render.shell_tab_camera": "Kamera",
|
||||
"render.shell_tab_scene": "SZENE",
|
||||
"render.show_shots_label": "Aufnahmenleiste einblenden",
|
||||
"render.stage_frame": "Bildausschnitt",
|
||||
"render.stage_light": "Licht",
|
||||
"render.stage_look": "Aussehen",
|
||||
"render.stage_orthographic": "Orthografisch",
|
||||
"render.stage_output": "Ausgabe",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.stage_preview_note": "Integrierte Vorschau · direktes Licht",
|
||||
"render.strip_label": "Leiste",
|
||||
"render.unavailable_preview": "Dieses Setup verlangt ein nicht verfügbares Vorschauprofil.",
|
||||
"render.unsaved": "Ungespeicherte Vorschauänderungen",
|
||||
"render.use_preview": "Integrierte Vorschau verwenden",
|
||||
"render.wait_batch": "Noch nicht unterstützt: Renderwarteschlange gespeicherter Aufnahmen",
|
||||
"render.wait_compare": "Noch nicht unterstützt: Vergleich gespeicherter Bilder",
|
||||
"render.wait_paint": "Noch nicht unterstützt: Produktauswahl und Auftragen von Erscheinungsbildern",
|
||||
"render.wait_pick_up": "Noch nicht unterstützt: Produktauswahl und Übernehmen von Erscheinungsbildern",
|
||||
"render.wait_replace": "Noch nicht unterstützt: Ersetzen aller Verwendungen eines Erscheinungsbilds",
|
||||
"render.wait_solo": "Noch nicht unterstützt: Lichtsichtbarkeit und Solo-Steuerung",
|
||||
"sample.bracket.about": "Grundflansch mit Kantenflanschen und einer Umkantung nach einer 2-mm-Blechregel",
|
||||
"sample.bracket.name": "Blechwinkel",
|
||||
"sample.enclosure.about": "Ausgehöhlter Block mit Lippe, Schraubenerhöhungen, Auflage und Rastverbindung",
|
||||
@@ -1366,12 +1670,14 @@
|
||||
"thread.designation": "Bezeichnung",
|
||||
"thread.iso_metric": "ISO metrisch",
|
||||
"thread.select_size": "Größe wählen",
|
||||
"timeline.delete_folders_with_features_tip": "Löscht die Ordner mit allen Features darin und ihren Unterordnern",
|
||||
"timeline.feature_hint": "Doppelklicken zum Bearbeiten · Ziehen zum Neuordnen · Rechtsklicken für weitere Optionen",
|
||||
"timeline.group": "Neuen Merkmalsordner anlegen",
|
||||
"timeline.move_many": "Zeitleistenelemente verschieben",
|
||||
"timeline.move_to_group": "Merkmale in Ordner verschieben",
|
||||
"timeline.rename_group": "Merkmalsordner umbenennen",
|
||||
"timeline.reorder_many": "Merkmale neu ordnen",
|
||||
"timeline.suppress_folders_tip": "Unterdrückt alle Features in den Ordnern und ihren Unterordnern oder hebt die Unterdrückung auf",
|
||||
"timeline.ungroup": "Merkmalsordner entfernen",
|
||||
"to the face": "bis zur Fläche",
|
||||
"to the next face": "bis zur nächsten Fläche",
|
||||
@@ -1382,7 +1688,11 @@
|
||||
"toolbar.render_camera": "KAMERA",
|
||||
"toolbar.render_environment": "UMGEBUNG",
|
||||
"toolbar.render_lighting": "BELEUCHTUNG",
|
||||
"toolbar.render_lights": "LICHTER",
|
||||
"toolbar.render_result": "ERGEBNIS",
|
||||
"toolbar.render_scene": "SZENE",
|
||||
"toolbar.render_stage": "BÜHNE",
|
||||
"toolbar.render_studio": "STUDIO",
|
||||
"trace.points": "{count} Punkte entlang der Bahn",
|
||||
"trace.stopped_by_contact": "Endet bei Probe {sample}: {a} würde {b} durchdringen",
|
||||
"trace.stopped_by_loop": "Endet bei Probe {sample}: die Schleife über {joint} lässt sich nicht weiter schließen",
|
||||
@@ -1580,7 +1890,7 @@
|
||||
"ui.agent_chat_pop_out": "In eigenem Fenster öffnen, das Sie auf einen anderen Bildschirm verschieben können",
|
||||
"ui.agent_chat_previous_picture": "Vorheriges Bild",
|
||||
"ui.agent_chat_privacy": "Nichts geht irgendwohin außer an den Agenten, den Sie unter Ihrem eigenen Konto ausführen.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft sendet nichts irgendwohin: Der Agent, den Sie starten, spricht unter Ihrem eigenen Konto mit seinem eigenen Dienst. SolidCraft sieht und speichert nie einen Schlüssel oder ein Passwort.",
|
||||
"ui.agent_chat_privacy_note": "Der Chat sendet von sich aus nichts irgendwohin: Der Agent, den Sie starten, spricht unter Ihrem eigenen Konto mit seinem eigenen Dienst. SolidCraft sieht und speichert nie einen Schlüssel oder ein Passwort.",
|
||||
"ui.agent_chat_queue": "Einreihen",
|
||||
"ui.agent_chat_queue_full": "Zu viele Nachrichten warten: Entfernen Sie eine oder warten Sie auf den Agenten.",
|
||||
"ui.agent_chat_queued": "Eingereiht",
|
||||
@@ -1765,6 +2075,7 @@
|
||||
"ui.command_done": "{command} fertig",
|
||||
"ui.command_palette_hint": "Befehl eingeben, z. B. {example} — oder S drücken, um zu suchen",
|
||||
"ui.concentric": "Konzentrisch",
|
||||
"ui.cone": "Kegel",
|
||||
"ui.conic_curve": "Kegelschnitt",
|
||||
"ui.constant": "Konstant",
|
||||
"ui.constraints_conflict": "Bedingungen konfliktreich",
|
||||
@@ -1823,6 +2134,11 @@
|
||||
"ui.draft": "Abziehen",
|
||||
"ui.drawing": "Zeichnung",
|
||||
"ui.drill_point": "Bohrpunkt",
|
||||
"ui.easyprint_consent": "EasyPrint ist der Slicer von Printables im Browser. Um das Modell dort zu öffnen, lädt SolidCraft es auf die Server von Printables hoch. Der Link läuft nach 30 Minuten ab, und Sie müssen bei Printables angemeldet sein. Fortfahren?",
|
||||
"ui.easyprint_failed": "Upload zu EasyPrint fehlgeschlagen: {error}",
|
||||
"ui.easyprint_opened": "In EasyPrint geöffnet",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, im Browser)",
|
||||
"ui.easyprint_uploading": "Wird zu Printables hochgeladen …",
|
||||
"ui.edit": "Bearbeiten",
|
||||
"ui.editJointLimits": "Gelenkgrenzen bearbeiten",
|
||||
"ui.edit_section_analysis": "Querschnittsanalyse bearbeiten",
|
||||
@@ -1864,6 +2180,7 @@
|
||||
"ui.fully_constrained": "Vollständig bestimmt",
|
||||
"ui.function": "Funktion",
|
||||
"ui.general": "Allgemein",
|
||||
"ui.gpu_memory_lowered": "Die Grafikkarte hat keinen Speicher mehr frei: Die Ansicht wird in geringerer Qualität gezeichnet.",
|
||||
"ui.graphics": "Grafik",
|
||||
"ui.graphics_custom": "Benutzerdefiniert",
|
||||
"ui.graphics_performance": "Leistung",
|
||||
@@ -1882,6 +2199,7 @@
|
||||
"ui.heading_circular_pattern": "RADIALES MUSTER",
|
||||
"ui.heading_coil": "SCHRAUBE",
|
||||
"ui.heading_combine": "KOMBINIEREN",
|
||||
"ui.heading_cone": "KEGEL",
|
||||
"ui.heading_configure": "KONFIGURIEREN",
|
||||
"ui.heading_constraints": "RANDBEDINGUNGEN",
|
||||
"ui.heading_construct": "KONSTRUKTION",
|
||||
@@ -2105,6 +2423,7 @@
|
||||
"ui.render": "Rendern",
|
||||
"ui.renderer": "Renderer",
|
||||
"ui.repeat": "Wiederholen",
|
||||
"ui.repeat_nothing": "Noch nichts zu wiederholen: Starten Sie zuerst ein Werkzeug oder einen Dialog.",
|
||||
"ui.replace_with_link_done": "Die Kopien sind jetzt Platzierungen des verknüpften Designs.",
|
||||
"ui.report_a_bug": "Fehler melden",
|
||||
"ui.reset": "Zurücksetzen",
|
||||
@@ -2123,9 +2442,7 @@
|
||||
"ui.right": "Rechts",
|
||||
"ui.save": "Speichern",
|
||||
"ui.save_as": "Speichern unter",
|
||||
"ui.save_mesh_no_slicer": "Kein Slicer gefunden: „Benutzerdefiniert…“ wählen und das Slicer-Programm angeben, oder „An Slicer senden“ ausschalten",
|
||||
"ui.save_mesh_pick_bodies": "Wähle die Körper zum Speichern aus",
|
||||
"ui.save_mesh_temp_failed": "{folder} konnte nicht angelegt werden: {error}",
|
||||
"ui.saved_to": "Gespeichert: {path}",
|
||||
"ui.sbox_pin": "Oben im S-Feld anheften",
|
||||
"ui.sbox_unpin": "Lösen",
|
||||
@@ -2140,7 +2457,6 @@
|
||||
"ui.selection_shift_add_only": "Umschalt+Klick fügt hinzu, ohne zu entfernen",
|
||||
"ui.selection_shift_add_only_tip": "An: Umschalt fügt Elemente hinzu, Strg/Cmd schaltet um. Aus (Standard): Umschalt und Strg/Cmd schalten beide um.",
|
||||
"ui.send": "Senden",
|
||||
"ui.send_to_slicer": "An Slicer senden",
|
||||
"ui.sent_to_slicer": "An {slicer} gesendet",
|
||||
"ui.sheet_gap": "Spalt",
|
||||
"ui.shell": "Hülle",
|
||||
@@ -2238,6 +2554,7 @@
|
||||
"ui.untitled": "Ohne Titel",
|
||||
"ui.up_axis_note": "Welche Achse in den Ansichten nach oben zeigt (Achsenansicht, Home, Ansehen). Designs bleiben unverändert.",
|
||||
"ui.updateToCurrentView": "Auf aktuelle Ansicht aktualisieren",
|
||||
"ui.upload": "Hochladen",
|
||||
"ui.view_centre": "Ansichtszentrum",
|
||||
"ui.viewport_theme_follow": "Dem Design folgen",
|
||||
"ui.visual_shaded_hidden_edges": "Schattiert mit verdeckten Kanten",
|
||||
@@ -2300,5 +2617,6 @@
|
||||
"update.up_to_date": "SolidCraft ist aktuell.",
|
||||
"update.update_now": "Jetzt aktualisieren",
|
||||
"update.you_have": "Installiert ist {version}.",
|
||||
"↑ ↓ choose · Enter / Tab complete · Esc dismiss": "↑ ↓ auswählen · Eingabe / Tab vervollständigen · Esc schließen"
|
||||
"↑ ↓ choose · Enter / Tab complete · Esc dismiss": "↑ ↓ auswählen · Eingabe / Tab vervollständigen · Esc schließen",
|
||||
"⌘Enter continues on GitHub.": "⌘Enter geht weiter zu GitHub."
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"Base Center": "Base Centre",
|
||||
"Center X": "Centre X",
|
||||
"Center Y": "Centre Y",
|
||||
"Center of mass": "Centre of mass",
|
||||
@@ -16,6 +17,12 @@
|
||||
"cmd.sketch_slot_center_point": "Centre Point Slot",
|
||||
"cmd.sketch_slot_center_to_center": "Centre to Centre Slot",
|
||||
"pattern.alignment_hint": "Counts include the original. Centre balances copies; Flip chooses the extra side for even totals.",
|
||||
"prefs.theme_follow": "Follow a theme file",
|
||||
"prefs.theme_follow_error": "Not applied: {error}. The last good theme stays on.",
|
||||
"prefs.theme_follow_launch": "Followed for this run only (--theme-file); reloaded whenever another tool rewrites it.",
|
||||
"prefs.theme_follow_note": "Reloaded whenever another tool rewrites it. Choosing a theme stops following it.",
|
||||
"prefs.theme_follow_off": "Off",
|
||||
"prefs.theme_follow_stop": "Stop following",
|
||||
"render.aging_add": "Add aging layer",
|
||||
"render.aging_airborne": "Airborne dust / participating medium",
|
||||
"render.aging_airborne_help": "Airborne dust is a separate finite homogeneous scattering volume. It changes transport and raw EXR, not the surface-aging stack. Existing volume/glass/denoising restrictions remain explicit; no atmosphere is added automatically.",
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
"Add Mid Radius": "Add Mid Radius",
|
||||
"Add Row": "Add Row",
|
||||
"Add a tool": "Add a tool",
|
||||
"Add all bodies": "Add all bodies",
|
||||
"Add bend": "Add bend",
|
||||
"Add condition": "Add condition",
|
||||
"Add or edit rule": "Add or edit rule",
|
||||
"Add to New Folder": "Add to New Folder",
|
||||
"Add visible bodies": "Add visible bodies",
|
||||
"Advanced": "Advanced",
|
||||
"Against": "Against",
|
||||
"Alignment": "Alignment",
|
||||
@@ -56,6 +58,7 @@
|
||||
"BOUNDARY SURFACE": "BOUNDARY SURFACE",
|
||||
"BROWSER": "BROWSER",
|
||||
"Bar": "Bar",
|
||||
"Base Center": "Base Center",
|
||||
"Bend": "Bend",
|
||||
"Bend Edges": "Bend Edges",
|
||||
"Bend Line Position": "Bend Line Position",
|
||||
@@ -140,6 +143,7 @@
|
||||
"Create Issue — review draft": "Create Issue — review draft",
|
||||
"Create Issue…": "Create Issue…",
|
||||
"Cross curves": "Cross curves",
|
||||
"Ctrl+Enter continues on GitHub.": "Ctrl+Enter continues on GitHub.",
|
||||
"Cube": "Cube",
|
||||
"Current orthographic view (1:1 mm)": "Current orthographic view (1:1 mm)",
|
||||
"Current perspective view": "Current perspective view",
|
||||
@@ -152,6 +156,7 @@
|
||||
"Customize…": "Customize…",
|
||||
"Cylindrical face": "Cylindrical face",
|
||||
"Delete": "Delete",
|
||||
"Delete Folders and Features…": "Delete Folders and Features…",
|
||||
"Delete Selected Features…": "Delete Selected Features…",
|
||||
"Delete Selected Folders": "Delete Selected Folders",
|
||||
"Delete all": "Delete all",
|
||||
@@ -430,6 +435,9 @@
|
||||
"Remove this point": "Remove this point",
|
||||
"Rename Feature": "Rename Feature",
|
||||
"Rename Folder": "Rename Folder",
|
||||
"Render Stage": "Render Stage",
|
||||
"Reopen designs": "Reopen designs",
|
||||
"Reopen the designs that were open when SolidCraft was last closed": "Reopen the designs that were open when SolidCraft was last closed",
|
||||
"Replace existing library file": "Replace existing library file",
|
||||
"Report a bug — review a screenshot and open a GitHub draft": "Report a bug — review a screenshot and open a GitHub draft",
|
||||
"Report text copied. Paste it into GitHub and submit your report there.": "Report text copied. Paste it into GitHub and submit your report there.",
|
||||
@@ -532,6 +540,7 @@
|
||||
"Style": "Style",
|
||||
"Summary": "Summary",
|
||||
"Suppress": "Suppress",
|
||||
"Suppress Selected Folders": "Suppress Selected Folders",
|
||||
"Suppressed": "Suppressed",
|
||||
"Surface": "Surface",
|
||||
"Surface, or faces to turn over": "Surface, or faces to turn over",
|
||||
@@ -579,6 +588,7 @@
|
||||
"UNTRIM": "UNTRIM",
|
||||
"Unit": "Unit",
|
||||
"Unsuppress": "Unsuppress",
|
||||
"Unsuppress Selected Folders": "Unsuppress Selected Folders",
|
||||
"Updating the preview": "Updating the preview",
|
||||
"Use active author placement": "Use active author placement",
|
||||
"Use fixed plane": "Use fixed plane",
|
||||
@@ -626,6 +636,8 @@
|
||||
"ai.prefs.background_commands": "Run agent commands in the background",
|
||||
"ai.prefs.connect_apps": "Make SolidCraft available to AI apps on this computer",
|
||||
"ai.prefs.connect_apps_note": "When SolidCraft starts, adds it as an MCP server to the AI apps found on this computer (OpenCode, Claude Desktop, Claude Code, Cursor, Codex, Gemini CLI, Copilot CLI, Windsurf, Zed, VS Code), so an agent can use it without any setup. Only the solidcraft entry is added or its path refreshed; an entry you changed is left alone, and the file is backed up first. Off: the entries it added are removed. Help > Connect AI assistants… does this by hand.",
|
||||
"ai.prefs.connect_at_start": "Connect the last-used agent when SolidCraft starts",
|
||||
"ai.prefs.connect_at_start_note": "Starts the agent you connected last (or the default one) in the background each time SolidCraft starts, so it is ready for chatting. Not when SolidCraft is started with --control. If it cannot connect, the Assistant shows Connection failed and a Retry button.",
|
||||
"ai.prefs.follow_camera": "Turn the camera to sketches",
|
||||
"ai.prefs.follow_camera_off": "Automatic camera following is off.",
|
||||
"ai.prefs.follow_camera_on": "The camera turns to face sketches the agent creates.",
|
||||
@@ -633,6 +645,8 @@
|
||||
"ai.prefs.make_default": "Use by default",
|
||||
"ai.prefs.no_agents": "No agents yet. Add an agent or refresh to find installed agents.",
|
||||
"ai.prefs.no_saved_approvals": "No saved approvals.",
|
||||
"ai.prefs.open_at_start": "Open the Assistant panel when SolidCraft starts",
|
||||
"ai.prefs.open_at_start_note": "Shows the Assistant panel (or its own window) each time SolidCraft starts. Not when SolidCraft is started with --control.",
|
||||
"ai.prefs.override_all_warning": "This agent may save, overwrite, export or replace the design without asking.",
|
||||
"ai.prefs.permission_all": "Allow everything",
|
||||
"ai.prefs.permission_all_summary": "Available SolidCraft tools run without asking.",
|
||||
@@ -677,6 +691,9 @@
|
||||
"cmd.appearance_assign": "Appearance",
|
||||
"cmd.appearance_library": "Appearance Library",
|
||||
"cmd.appearance_list": "List Appearances",
|
||||
"cmd.appearance_paint": "Paint Appearance",
|
||||
"cmd.appearance_pick_up": "Pick Up Appearance",
|
||||
"cmd.appearance_replace": "Replace Appearance",
|
||||
"cmd.assembly_bom": "Bill of Materials",
|
||||
"cmd.body_rename": "Rename Body",
|
||||
"cmd.browser_collapse_all": "Collapse All",
|
||||
@@ -692,10 +709,12 @@
|
||||
"cmd.canvas_delete": "Delete Canvas",
|
||||
"cmd.canvas_edit": "Edit Canvas",
|
||||
"cmd.canvas_insert": "Canvas",
|
||||
"cmd.canvas_to_sketch": "Canvas to Sketch",
|
||||
"cmd.component_activate": "Activate Component",
|
||||
"cmd.component_break_link": "Break Link",
|
||||
"cmd.component_capture_position": "Capture Position",
|
||||
"cmd.component_copies": "Find Identical Copies",
|
||||
"cmd.component_copy_bodies": "Paste Bodies",
|
||||
"cmd.component_create": "New Component",
|
||||
"cmd.component_cycle_color": "Cycle Component Color",
|
||||
"cmd.component_delete": "Delete Component",
|
||||
@@ -762,6 +781,7 @@
|
||||
"cmd.document_revision": "Design Revision",
|
||||
"cmd.document_units": "Change Design Units",
|
||||
"cmd.edit_checkpoint": "Checkpoint",
|
||||
"cmd.edit_repeat": "Repeat Last Command",
|
||||
"cmd.edit_restore_checkpoint": "Restore Checkpoint",
|
||||
"cmd.engine_commands": "List Commands",
|
||||
"cmd.engine_describe": "Describe Command",
|
||||
@@ -774,7 +794,9 @@
|
||||
"cmd.file_export": "Export",
|
||||
"cmd.file_insert_mesh": "Insert Mesh",
|
||||
"cmd.file_insert_step": "Insert STEP",
|
||||
"cmd.file_open_in_easyprint": "Open with EasyPrint",
|
||||
"cmd.file_save_mesh": "Save As Mesh",
|
||||
"cmd.file_send_to_slicer": "Send to Slicer",
|
||||
"cmd.file_slicers": "Installed Slicers",
|
||||
"cmd.frame_member": "Frame Member",
|
||||
"cmd.frame_profile_insert": "Insert Profile",
|
||||
@@ -846,6 +868,7 @@
|
||||
"cmd.occurrence_ground": "Ground",
|
||||
"cmd.occurrence_move": "Move Occurrence",
|
||||
"cmd.occurrence_properties": "Occurrence Physical Properties",
|
||||
"cmd.occurrence_reparent": "Move to Component",
|
||||
"cmd.parameters_add": "Add User Parameter",
|
||||
"cmd.parameters_change": "Change Parameters",
|
||||
"cmd.parameters_comment": "Comment Parameter",
|
||||
@@ -872,9 +895,11 @@
|
||||
"cmd.plastic_snap_fit": "Snap Fit",
|
||||
"cmd.render_aging_describe": "Layered Surface Aging",
|
||||
"cmd.render_backends": "Render Backends",
|
||||
"cmd.render_batch": "Render All Shots",
|
||||
"cmd.render_camera_fit": "Frame Render Subject",
|
||||
"cmd.render_camera_get": "Inspect Render Camera",
|
||||
"cmd.render_cancel": "Cancel Render",
|
||||
"cmd.render_compare": "Compare Images",
|
||||
"cmd.render_effects_describe": "Lens and Creative Effects",
|
||||
"cmd.render_export": "Export Render Image",
|
||||
"cmd.render_hdr_inspect": "Inspect HDR Source",
|
||||
@@ -890,6 +915,7 @@
|
||||
"cmd.render_library_surface_prepare": "Prepare Authored Surface Maps",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "Find Render Library Targets",
|
||||
"cmd.render_lights_solo": "Solo Light",
|
||||
"cmd.render_optics_bind": "Save Optical Binding",
|
||||
"cmd.render_optics_unbind": "Remove Optical Binding",
|
||||
"cmd.render_preflight": "Check Render Request",
|
||||
@@ -954,6 +980,7 @@
|
||||
"cmd.sketch_drag": "Drag Sketch Geometry",
|
||||
"cmd.sketch_drag_end": "End Sketch Drag",
|
||||
"cmd.sketch_draw_dimensioned": "Draw Dimensioned Sketch Geometry",
|
||||
"cmd.sketch_drawing_bounds": "Drawing Size",
|
||||
"cmd.sketch_edit": "Edit Sketch",
|
||||
"cmd.sketch_edit_text": "Edit Text",
|
||||
"cmd.sketch_export_dxf": "Save As DXF",
|
||||
@@ -998,8 +1025,11 @@
|
||||
"cmd.sketch_spline_control_point": "Control Point Spline",
|
||||
"cmd.sketch_spline_control_point_5": "Control Point Spline (Degree 5)",
|
||||
"cmd.sketch_spline_fit_point": "Fit Point Spline",
|
||||
"cmd.sketch_spline_insert_point": "Add Spline Point",
|
||||
"cmd.sketch_spun_profile": "Spun Profile",
|
||||
"cmd.sketch_toggle_diameter": "Toggle Radius / Diameter",
|
||||
"cmd.sketch_toggle_driven": "Toggle Driven Dimension",
|
||||
"cmd.sketch_transform": "Transform",
|
||||
"cmd.sketch_trim_path": "Trim Along Path",
|
||||
"cmd.solid_align": "Align",
|
||||
"cmd.solid_boundary_fill": "Boundary Fill",
|
||||
@@ -1063,6 +1093,7 @@
|
||||
"cmd.view_rename": "Rename Named View",
|
||||
"cmd.view_right": "Right View",
|
||||
"cmd.view_save": "New Named View",
|
||||
"cmd.view_shots_strip": "Shots Strip",
|
||||
"cmd.view_spin": "Continuous orbit",
|
||||
"cmd.view_tool": "Navigation tool",
|
||||
"cmd.view_top": "Top View",
|
||||
@@ -1136,6 +1167,7 @@
|
||||
"document.save_changes": "Save changes to {name}?",
|
||||
"document.save_copy": "Save a Copy…",
|
||||
"document.unsaved_changes": "{name} has unsaved changes. If you don't save, they are lost.",
|
||||
"drive.rigid": "{joint} is a rigid joint: it holds its parts still, so it has nothing to drive. To let them move, change its type in Edit Joint: Revolute to rotate, Slider to slide, Cylindrical for both.",
|
||||
"drive.stopped_by_contact": "Stopped at {value}: {a} would pass through {b}",
|
||||
"drive.stopped_by_loop": "Stopped at {value}: the loop through {joint} can't close any further",
|
||||
"drive.unconnected": "Moves nothing: {part} is not connected to anything grounded",
|
||||
@@ -1277,6 +1309,9 @@
|
||||
"install.steps_intro": "Safari installs web apps from its own menus:",
|
||||
"install.title": "Install SolidCraft",
|
||||
"issue.body_label": "Report text",
|
||||
"issue.note_changed_while_waiting": "Settings or model changed while waiting for the preview. Retake the screenshot to update the technical details for the current view.",
|
||||
"issue.note_details_kept": "Screenshot captured locally. Your edited technical details were kept: check that they still match the current view.",
|
||||
"issue.note_details_updated": "Technical details updated to match the current view. Screenshot captured locally. Review it before attaching it on GitHub.",
|
||||
"issue.note_image_copied": "Paste the image into the GitHub draft, or save the PNG if image copying is unavailable.",
|
||||
"issue.note_opened": "Review the GitHub draft and attach the screenshot. GitHub's Submit new issue button publishes it.",
|
||||
"issue.note_opened_copied": "Report copied. Paste into the GitHub draft, attach the screenshot, then click Submit new issue on GitHub.",
|
||||
@@ -1343,6 +1378,8 @@
|
||||
"material.editor.unknown_card": "Engineering properties are unknown. Save may keep only the assigned density and existing appearance.",
|
||||
"material.editor.user_supplied": "User supplied",
|
||||
"material.editor.wood": "Wood",
|
||||
"material.selection.choose": "Choose a material",
|
||||
"material.selection.mixed": "Different materials",
|
||||
"measure.at": "At",
|
||||
"measure.item": "Item {number}",
|
||||
"messages.ago_h": "{n} h ago",
|
||||
@@ -1371,6 +1408,9 @@
|
||||
"nav.blender.help": "Middle drag orbits, Shift+middle pans, Ctrl+middle zooms; right drag leaves the camera alone",
|
||||
"nav.free_orbit.help": "Mouse and 3D mouse rotate through both poles and preserve roll. Shift axis snapping is disabled.",
|
||||
"nav.free_orbit.label": "Free orbit",
|
||||
"nav.free_orbit.snap_help": "Mouse and 3D mouse rotate through both poles and preserve roll. Hold Shift during an orbit drag to snap the view direction and roll.",
|
||||
"nav.free_orbit_upright.help": "Sideways mouse drags spin the model around the world's vertical axis; up and down drags tilt over the top without a limit.",
|
||||
"nav.free_orbit_upright.label": "Turn around the vertical axis",
|
||||
"nav.fusion.help": "Middle drag pans, Shift+middle orbits, right drag orbits",
|
||||
"nav.inventor.help": "Middle drag pans, Shift+middle orbits, Ctrl+middle zooms, right drag orbits",
|
||||
"nav.openscad.help": "Left drag on empty space orbits, Shift+left drag box-selects, sketch geometry drags edit; right or middle drag pans, Shift+right or Shift+middle drag zooms",
|
||||
@@ -1445,6 +1485,11 @@
|
||||
"prefs.design": "Design defaults",
|
||||
"prefs.design_note": "What new designs start with. Open designs keep their own.",
|
||||
"prefs.devices": "3D mouse",
|
||||
"prefs.dialog_buttons": "Dialog buttons",
|
||||
"prefs.dialogs": "Dialogs",
|
||||
"prefs.dialogs_edge": "At the view's edge",
|
||||
"prefs.dialogs_left_column": "In the left column",
|
||||
"prefs.dialogs_note": "Where command dialogs open: docked at the view's edge, or in the left column in place of the browser and the History, which come back as they were when the dialog closes.",
|
||||
"prefs.display": "Display",
|
||||
"prefs.edges": "Edges and shading",
|
||||
"prefs.extend": "Extend",
|
||||
@@ -1467,6 +1512,12 @@
|
||||
"prefs.graphics_note": "Trade speed for smoothness. Each choice shows its effect on a sample.",
|
||||
"prefs.graphics_presets_note": "Presets set the choices below together.",
|
||||
"prefs.history": "History",
|
||||
"prefs.history_origin_bodies": "Show origin and bodies at the top",
|
||||
"prefs.history_origin_bodies_note": "The History on the left or under the browser starts with the active component's Bodies folder and the Origin, with their eyes and menus as in the browser. The History at the bottom is unchanged.",
|
||||
"prefs.history_sketches": "Sketches",
|
||||
"prefs.history_sketches_in_order": "In order",
|
||||
"prefs.history_sketches_note": "With Sketches set to Under their feature, the History at the left lists each sketch one level in, under the first feature built from it, whenever it is wide enough for names. The timeline at the bottom always keeps the creation order.",
|
||||
"prefs.history_sketches_under_feature": "Under their feature",
|
||||
"prefs.hold_stop_snapping": "Hold to stop snapping",
|
||||
"prefs.icons_only": "Icons only",
|
||||
"prefs.imported_file": "Imported file",
|
||||
@@ -1498,6 +1549,8 @@
|
||||
"prefs.opaque": "Opaque",
|
||||
"prefs.orbit_snap": "Hold Shift during orbit to snap to an axis.",
|
||||
"prefs.orientation": "Orientation",
|
||||
"prefs.origin_plane_names": "Origin plane names",
|
||||
"prefs.origin_plane_names_note": "Names shown in the browser, dialogs and lists. {top} is XY, {front} is XZ and {right} is YZ, with Z up. Commands, scripts and saved designs keep XY, XZ and YZ.",
|
||||
"prefs.overall_speed": "Overall speed",
|
||||
"prefs.placement": "Placement",
|
||||
"prefs.prefer_free_sketch_points": "Prefer movable sketch points when points overlap",
|
||||
@@ -1538,11 +1591,18 @@
|
||||
"prefs.supersampling_brief": "Draws the view larger and filters it down: very crisp, and heavier.",
|
||||
"prefs.tab_accent_note": "The accent follows the active tab",
|
||||
"prefs.theme_file": "theme file",
|
||||
"prefs.theme_follow": "Follow a theme file",
|
||||
"prefs.theme_follow_error": "Not applied: {error}. The last good theme stays on.",
|
||||
"prefs.theme_follow_launch": "Followed for this run only (--theme-file); reloaded whenever another tool rewrites it.",
|
||||
"prefs.theme_follow_note": "Reloaded whenever another tool rewrites it. Choosing a theme stops following it.",
|
||||
"prefs.theme_follow_off": "Off",
|
||||
"prefs.theme_follow_stop": "Stop following",
|
||||
"prefs.timeline_half_hour": "−30 min",
|
||||
"prefs.timeline_now": "now",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
"prefs.toggle_item": "Add the item, or take it out again",
|
||||
"prefs.toolbar": "Toolbar",
|
||||
"prefs.top": "Top",
|
||||
"prefs.translucent": "Translucent",
|
||||
"prefs.under_browser": "Under browser",
|
||||
"prefs.under_cursor": "Under cursor",
|
||||
@@ -1601,6 +1661,7 @@
|
||||
"render.aging_target_search": "Filter body names",
|
||||
"render.aging_upward": "Upward-facing deposition",
|
||||
"render.all_controls_help": "Dense inspection of all current controls. Section pages provide focused editing without changing the underlying request.",
|
||||
"render.all_shots_label": "All Shots",
|
||||
"render.appearance_physics_separate": "Visual appearance does not assign density, thermal data or other engineering properties.",
|
||||
"render.availability_native": "Native composition; review before applying",
|
||||
"render.availability_projection": "Supported projection; see scope and omissions",
|
||||
@@ -1755,10 +1816,13 @@
|
||||
"render.effects_reset_lens": "Reset lens effects",
|
||||
"render.effects_seed": "Pattern seed",
|
||||
"render.export_display": "Export: display PNG",
|
||||
"render.export_image_label": "Export Image",
|
||||
"render.export_linear": "Export: raw linear EXR",
|
||||
"render.exr_pending": "GPU can retain raw linear EXR. Compression, multilayer images and auxiliary render passes remain unavailable.",
|
||||
"render.film_grain": "Photographic grain",
|
||||
"render.fit": "Fit Product",
|
||||
"render.fixed_camera": "Camera",
|
||||
"render.fixed_world": "World",
|
||||
"render.flare_ghosts": "Ghost rings per source",
|
||||
"render.flare_halo": "Flare halo",
|
||||
"render.flare_streak": "Anamorphic-style streak",
|
||||
@@ -1785,6 +1849,12 @@
|
||||
"render.hdr_primaries_srgb": "Color primaries: sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "The source does not declare primaries; review the renderer color requirements.",
|
||||
"render.hdr_resource_missing": "This design is missing the saved HDR resource.",
|
||||
"render.heading_batch": "BATCH",
|
||||
"render.heading_frame": "FRAME",
|
||||
"render.heading_lens": "LENS",
|
||||
"render.heading_results": "RESULTS",
|
||||
"render.heading_shots": "SHOTS",
|
||||
"render.hide_shots_label": "Hide Shots strip",
|
||||
"render.image_advanced": "Advanced GPU controls",
|
||||
"render.image_cancelled": "Render cancelled",
|
||||
"render.image_cancelling": "Cancelling",
|
||||
@@ -1816,6 +1886,7 @@
|
||||
"render.image_width": "Width",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspect_scene": "Refresh captured scene summary",
|
||||
"render.inspector": "Inspector",
|
||||
"render.keep_editing": "Keep editing",
|
||||
"render.layer_down": "Move down",
|
||||
"render.layer_enabled": "Layer enabled",
|
||||
@@ -1884,6 +1955,8 @@
|
||||
"render.library_unfavorite": "Remove favorite",
|
||||
"render.library_uniform_ack": "Use the uniform approximation without spatial or advanced effects",
|
||||
"render.library_usable": "Executable projections",
|
||||
"render.light_anchor_pending": "Changing the light coordinate frame is not supported yet.",
|
||||
"render.lights_fixed_to": "Lights fixed to",
|
||||
"render.linear_help": "Keeps a 32-bit float RGBA master before denoising, exposure, tone mapping, filters and backdrop. Linear sRGB/D65; coverage-premultiplied. Additional memory is admitted explicitly. No compression or extra passes.",
|
||||
"render.linear_retain": "Retain raw linear EXR",
|
||||
"render.linear_unavailable": "The selected completed frame has no retained EXR. Enable retention before rendering; an older PNG cannot recover raw radiance.",
|
||||
@@ -1969,6 +2042,7 @@
|
||||
"render.output_over_budget": "The requested image exceeds the selected resource envelope. Choose a compatible size or profile explicitly; no automatic downgrade occurs.",
|
||||
"render.output_ratio_refused": "The linked dimension exceeds this method’s size limit. The previous size is retained; unlock the ratio or choose a smaller value.",
|
||||
"render.output_swap_orientation": "Swap width and height",
|
||||
"render.output_tools_inspector": "Edit size and format in the Output inspector.",
|
||||
"render.page_aging": "Aging & contamination",
|
||||
"render.page_all": "All controls",
|
||||
"render.page_appearance": "Appearance",
|
||||
@@ -1980,6 +2054,7 @@
|
||||
"render.page_lighting": "Lighting",
|
||||
"render.page_output": "Output",
|
||||
"render.page_scene": "Scene",
|
||||
"render.paint_label": "Paint",
|
||||
"render.passive_stage": "Ground and passive stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "Perspective camera",
|
||||
@@ -1995,6 +2070,10 @@
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.pick_component": "Component",
|
||||
"render.pick_label": "Pick",
|
||||
"render.pick_up_label": "Pick Up",
|
||||
"render.pick_waiting": "Product picking is not supported yet.",
|
||||
"render.post_contrast": "Contrast",
|
||||
"render.post_gain_b": "Blue gain",
|
||||
"render.post_gain_g": "Green gain",
|
||||
@@ -2007,6 +2086,7 @@
|
||||
"render.preview": "Integrated preview",
|
||||
"render.preview_help": "Raster shading and blended transparency. Refraction, HDRI and final rendering are not available yet.",
|
||||
"render.preview_image_settings_help": "Live Preview keeps fixed studio lighting. Exposure and image lighting apply to the image job when you Check or Start.",
|
||||
"render.preview_lighting_help": "The live preview shows direct light only and no shadows.",
|
||||
"render.preview_retry": "Retry live preview",
|
||||
"render.preview_unavailable_help": "The live preview is unavailable. Saved setups and image-job controls remain accessible. Change the scene or explicitly retry; a refused scene is not rebuilt on every frame.",
|
||||
"render.preview_upload": "Live-preview vertex payload",
|
||||
@@ -2020,8 +2100,10 @@
|
||||
"render.radial_distortion": "Radial distortion",
|
||||
"render.regrade_action": "Regrade raw master (no denoising)",
|
||||
"render.regrade_help": "Creates a separate PNG from the selected completed raw master, using these presentation controls. Does not trace rays, change the captured size/camera/lights, or overwrite the EXR. Denoising is not reapplied: raw masters do not retain its guides. The derivative remains exportable through the same job controls.",
|
||||
"render.regrade_label": "Regrade",
|
||||
"render.reload_settings": "Reload Saved Settings",
|
||||
"render.replace_ground": "Confirm replacement of existing stage",
|
||||
"render.replace_label": "Replace",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "Restore Saved Camera",
|
||||
"render.result_actual_help": "One image pixel per display pixel.",
|
||||
@@ -2067,6 +2149,7 @@
|
||||
"render.sampling_title": "Adaptive and transmission sampling",
|
||||
"render.save_continue": "Save and continue",
|
||||
"render.save_setup": "Save Setup",
|
||||
"render.save_shot": "Save Shot",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
@@ -2086,6 +2169,9 @@
|
||||
"render.setup_runtime_unsupported": "This full job cannot be saved yet: it contains maps or scene-body bindings. Remove those temporary inputs before saving a portable setup.",
|
||||
"render.setup_save_missing": "The saved render configuration could not be found after the command completed.",
|
||||
"render.sharpening": "Detail sharpening",
|
||||
"render.shell_tab_appearance": "RENDER APPEARANCE",
|
||||
"render.shell_tab_camera": "RENDER CAMERA",
|
||||
"render.shell_tab_scene": "RENDER SCENE",
|
||||
"render.shot_duplicate": "Duplicate saved shot",
|
||||
"render.shot_manager": "Saved shots",
|
||||
"render.shot_new_name": "New shot name",
|
||||
@@ -2094,11 +2180,19 @@
|
||||
"render.shot_remove_title": "Remove saved shot?",
|
||||
"render.shot_rename": "Rename saved shot",
|
||||
"render.shot_saved_only": "Save the current draft first. Duplicate and rename preserve exact saved options and resource references.",
|
||||
"render.show_shots_label": "Show Shots strip",
|
||||
"render.sky_ground": "Ground · linear RGB",
|
||||
"render.sky_horizon": "Horizon · linear RGB",
|
||||
"render.sky_zenith": "Zenith · linear RGB",
|
||||
"render.soft_focus": "Soft focus",
|
||||
"render.stage_frame": "Frame",
|
||||
"render.stage_light": "Light",
|
||||
"render.stage_look": "Look",
|
||||
"render.stage_orthographic": "Orthographic",
|
||||
"render.stage_output": "Output",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.stage_preview_note": "Integrated preview · direct light",
|
||||
"render.strip_label": "Strip",
|
||||
"render.studio_add_area": "Add area light",
|
||||
"render.studio_ambient": "Constant environment radiance",
|
||||
"render.studio_ambient_rgb": "Constant environment radiance (linear RGB)",
|
||||
@@ -2155,6 +2249,12 @@
|
||||
"render.volume_max": "Maximum bounds · world mm",
|
||||
"render.volume_min": "Minimum bounds · world mm",
|
||||
"render.volume_title": "Bounded homogeneous volume",
|
||||
"render.wait_batch": "not supported yet: the saved-shot render queue",
|
||||
"render.wait_compare": "not supported yet: retained image comparison",
|
||||
"render.wait_paint": "not supported yet: product picking and appearance painting",
|
||||
"render.wait_pick_up": "not supported yet: product picking and appearance sampling",
|
||||
"render.wait_replace": "not supported yet: replacing all uses of an appearance",
|
||||
"render.wait_solo": "not supported yet: light visibility and solo controls",
|
||||
"sample.bracket.about": "Base flange with edge flanges and a hem on a 2 mm rule",
|
||||
"sample.bracket.name": "Sheet Metal Bracket",
|
||||
"sample.enclosure.about": "Shelled box with a lip, screw bosses, a rest and a snap fit",
|
||||
@@ -2246,6 +2346,7 @@
|
||||
"timeline.delete_after_marker_one": "Delete 1 Feature After History Marker",
|
||||
"timeline.delete_after_marker_other": "Delete {count} Features After History Marker",
|
||||
"timeline.delete_folders_tip": "Keep their features and nested folders in the history",
|
||||
"timeline.delete_folders_with_features_tip": "Delete the folders with every feature in them and their nested folders",
|
||||
"timeline.delete_many": "Delete {count} Selected Features",
|
||||
"timeline.feature_error": "Error: {message}",
|
||||
"timeline.feature_hint": "Double-click to edit · drag to reorder · right-click for more",
|
||||
@@ -2255,6 +2356,7 @@
|
||||
"timeline.move_to_group": "Move Features to Folder",
|
||||
"timeline.rename_group": "Rename Feature Folder",
|
||||
"timeline.reorder_many": "Reorder Features",
|
||||
"timeline.suppress_folders_tip": "Suppress or unsuppress every feature in the folders and their nested folders",
|
||||
"timeline.ungroup": "Remove Feature Folders",
|
||||
"to the face": "to the face",
|
||||
"to the next face": "to the next face",
|
||||
@@ -2265,7 +2367,11 @@
|
||||
"toolbar.render_camera": "CAMERA",
|
||||
"toolbar.render_environment": "ENVIRONMENT",
|
||||
"toolbar.render_lighting": "LIGHTING",
|
||||
"toolbar.render_lights": "LIGHTS",
|
||||
"toolbar.render_result": "RESULT",
|
||||
"toolbar.render_scene": "SCENE",
|
||||
"toolbar.render_stage": "STAGE",
|
||||
"toolbar.render_studio": "STUDIO",
|
||||
"trace.points": "{count} points along the path",
|
||||
"trace.stopped_by_contact": "Ends at sample {sample}: {a} would pass through {b}",
|
||||
"trace.stopped_by_loop": "Ends at sample {sample}: the loop through {joint} can't close any further",
|
||||
@@ -2444,6 +2550,7 @@
|
||||
"ui.agent_chat_import_failed": "{name}: the import failed: {error}",
|
||||
"ui.agent_chat_intro": "Chat with a coding agent you already use, or a model endpoint you choose. It works on the open design through SolidCraft's tools: its changes show as it makes them and undo as one step per message. What it may do without asking is set in Preferences > AI.",
|
||||
"ui.agent_chat_key_in_env": "key set",
|
||||
"ui.agent_chat_last_missing": "The agent used last ({agent}) is not available any more. Pick an agent, then press Retry.",
|
||||
"ui.agent_chat_left": "Left",
|
||||
"ui.agent_chat_limit": "The agent reached the limit of {limit} changes for one message. Send another message to let it go on.",
|
||||
"ui.agent_chat_login_found": "login found",
|
||||
@@ -2477,7 +2584,7 @@
|
||||
"ui.agent_chat_pop_out": "Open in its own window, which you can move to another screen",
|
||||
"ui.agent_chat_previous_picture": "Previous picture",
|
||||
"ui.agent_chat_privacy": "Nothing goes anywhere except to the agent you run, under your own account.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft sends nothing anywhere: the agent you run talks to its own service under your own account. SolidCraft never sees or stores a key or password.",
|
||||
"ui.agent_chat_privacy_note": "The chat itself sends nothing anywhere: the agent you run talks to its own service under your own account. SolidCraft never sees or stores a key or password.",
|
||||
"ui.agent_chat_provider_models": "{count} models",
|
||||
"ui.agent_chat_provider_other": "Other",
|
||||
"ui.agent_chat_provider_tip": "The provider whose models the next list shows.",
|
||||
@@ -2490,6 +2597,7 @@
|
||||
"ui.agent_chat_remove": "Remove from the queue",
|
||||
"ui.agent_chat_remove_file": "Take it off this message",
|
||||
"ui.agent_chat_remove_imported": "Take it off this message; the part stays in the design (Undo removes it)",
|
||||
"ui.agent_chat_retry": "Retry",
|
||||
"ui.agent_chat_right": "Right",
|
||||
"ui.agent_chat_save": "Save",
|
||||
"ui.agent_chat_send": "Send",
|
||||
@@ -2502,6 +2610,7 @@
|
||||
"ui.agent_chat_state_auth": "Sign-in needed",
|
||||
"ui.agent_chat_state_busy": "Working…",
|
||||
"ui.agent_chat_state_exited": "Agent stopped",
|
||||
"ui.agent_chat_state_failed": "Connection failed",
|
||||
"ui.agent_chat_state_off": "Not connected",
|
||||
"ui.agent_chat_state_ready": "Ready",
|
||||
"ui.agent_chat_state_starting": "Starting…",
|
||||
@@ -2695,6 +2804,7 @@
|
||||
"ui.command_done": "{command} done",
|
||||
"ui.command_palette_hint": "Type a command, e.g. {example} — or press S to search",
|
||||
"ui.concentric": "Concentric",
|
||||
"ui.cone": "Cone",
|
||||
"ui.conic_curve": "Conic Curve",
|
||||
"ui.constant": "Constant",
|
||||
"ui.constraints_conflict": "Constraints conflict",
|
||||
@@ -2755,6 +2865,11 @@
|
||||
"ui.draft": "Draft",
|
||||
"ui.drawing": "Drawing",
|
||||
"ui.drill_point": "Drill Point",
|
||||
"ui.easyprint_consent": "EasyPrint is Printables' slicer in the browser. To open the model there, SolidCraft uploads it to Printables' servers. The link expires after 30 minutes, and you'll need to be signed in to Printables. Continue?",
|
||||
"ui.easyprint_failed": "EasyPrint upload failed: {error}",
|
||||
"ui.easyprint_opened": "Opened in EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, in the browser)",
|
||||
"ui.easyprint_uploading": "Uploading to Printables…",
|
||||
"ui.edit": "Edit",
|
||||
"ui.editJointLimits": "Edit Joint Limits",
|
||||
"ui.edit_section_analysis": "Edit Section Analysis",
|
||||
@@ -2799,6 +2914,7 @@
|
||||
"ui.fully_constrained": "Fully constrained",
|
||||
"ui.function": "Function",
|
||||
"ui.general": "General",
|
||||
"ui.gpu_memory_lowered": "The graphics card is out of memory: the view is drawn at a lower quality.",
|
||||
"ui.graphics": "Graphics",
|
||||
"ui.graphics_custom": "Custom",
|
||||
"ui.graphics_performance": "Performance",
|
||||
@@ -2817,6 +2933,7 @@
|
||||
"ui.heading_circular_pattern": "CIRCULAR PATTERN",
|
||||
"ui.heading_coil": "COIL",
|
||||
"ui.heading_combine": "COMBINE",
|
||||
"ui.heading_cone": "CONE",
|
||||
"ui.heading_configure": "CONFIGURE",
|
||||
"ui.heading_constraints": "CONSTRAINTS",
|
||||
"ui.heading_construct": "CONSTRUCT",
|
||||
@@ -2897,6 +3014,7 @@
|
||||
"ui.history_names": "Names",
|
||||
"ui.history_play": "Play to the end",
|
||||
"ui.history_show_names": "Show names",
|
||||
"ui.history_sketch_listed_under": "Listed under {feature}",
|
||||
"ui.history_title": "History",
|
||||
"ui.history_toggle_names": "Show or hide feature names",
|
||||
"ui.hole": "Hole",
|
||||
@@ -3067,6 +3185,7 @@
|
||||
"ui.render": "Render",
|
||||
"ui.renderer": "Renderer",
|
||||
"ui.repeat": "Repeat",
|
||||
"ui.repeat_nothing": "Nothing to repeat yet: start a tool or dialog first.",
|
||||
"ui.replace_with_link_done": "The copies are now placements of the linked design.",
|
||||
"ui.report_a_bug": "Report a bug",
|
||||
"ui.reset": "Reset",
|
||||
@@ -3085,9 +3204,8 @@
|
||||
"ui.right": "Right",
|
||||
"ui.save": "Save",
|
||||
"ui.save_as": "Save As",
|
||||
"ui.save_mesh_no_slicer": "No slicer found: choose Custom… and pick your slicer program, or turn off Send to slicer",
|
||||
"ui.save_mesh_no_slicer_open": "No slicer found: choose Custom… and pick your slicer program",
|
||||
"ui.save_mesh_pick_bodies": "Select the bodies to save",
|
||||
"ui.save_mesh_temp_failed": "Couldn't make {folder}: {error}",
|
||||
"ui.saved_to": "Saved {path}",
|
||||
"ui.sbox_pin": "Pin to the top of the S box",
|
||||
"ui.sbox_unpin": "Unpin",
|
||||
@@ -3102,8 +3220,9 @@
|
||||
"ui.selection_shift_add_only": "Shift+click adds without removing",
|
||||
"ui.selection_shift_add_only_tip": "On: Shift adds items, Ctrl/Cmd toggles. Off (default): Shift and Ctrl/Cmd both toggle.",
|
||||
"ui.send": "Send",
|
||||
"ui.send_to_slicer": "Send to slicer",
|
||||
"ui.send_to_slicer_unavailable": "Send to Slicer needs the desktop app: a browser can't start a program",
|
||||
"ui.sent_to_slicer": "Sent to {slicer}",
|
||||
"ui.sent_to_slicer_copy": "Sent to {slicer} as {file}, because the first file is still open there",
|
||||
"ui.sheet_gap": "Gap",
|
||||
"ui.shell": "Shell",
|
||||
"ui.shortcut_capture_add_key": "Add one ordinary key. Escape cancels.",
|
||||
@@ -3138,6 +3257,15 @@
|
||||
"ui.slice": "Slice",
|
||||
"ui.slicer": "Slicer",
|
||||
"ui.slicer_delete_tip": "{program}\nPress Delete to remove it from the list",
|
||||
"ui.slicer_lost": "{slicer} was started but can't be found again to send it the file. The file is saved at {path}: open it from there.",
|
||||
"ui.slicer_no_file": "{slicer} is ready, but there is no file to send to it.",
|
||||
"ui.slicer_no_response": "{slicer} didn't respond in time. The file is already saved at {path}: send it again once the slicer has started.",
|
||||
"ui.slicer_resend_hint": "Sending again replaces the file the slicer has open.",
|
||||
"ui.slicer_single_instance": "Open files in a slicer that is already running",
|
||||
"ui.slicer_single_instance_tip": "PrusaSlicer, SuperSlicer and Cura load the file in the window that is open instead of starting another. Other slicers are started as they are. PrusaSlicer 3.0 always does this: its launcher can't take a file any other way.",
|
||||
"ui.slicer_starting": "Starting {slicer}…",
|
||||
"ui.slicer_still_starting": "Still waiting for {slicer} to start. Nothing else was sent.",
|
||||
"ui.slicer_stl_fallback": "The 3MF could not be written, so this is an STL.",
|
||||
"ui.slot": "Slot",
|
||||
"ui.smooth": "Smooth",
|
||||
"ui.smooth_wheel_zoom": "Smooth wheel zoom",
|
||||
@@ -3205,6 +3333,7 @@
|
||||
"ui.untitled": "Untitled",
|
||||
"ui.up_axis_note": "Which axis points up in the views (axis view, Home, Look At). Designs are unchanged.",
|
||||
"ui.updateToCurrentView": "Update to Current View",
|
||||
"ui.upload": "Upload",
|
||||
"ui.vertical_constraint": "Vertical Constraint",
|
||||
"ui.view_centre": "View centre",
|
||||
"ui.viewport_theme_follow": "Follow theme",
|
||||
@@ -3279,5 +3408,6 @@
|
||||
"web.open_link": "Open linked design?",
|
||||
"web.open_link_confirm": "There are unsaved changes. Open the linked design in a new tab?",
|
||||
"↑ ↓ choose · Enter / Tab complete · Esc dismiss": "↑ ↓ choose · Enter / Tab complete · Esc dismiss",
|
||||
"↑ ↓ choose · Enter applies what you typed · Esc dismiss": "↑ ↓ choose · Enter applies what you typed · Esc dismiss"
|
||||
"↑ ↓ choose · Enter applies what you typed · Esc dismiss": "↑ ↓ choose · Enter applies what you typed · Esc dismiss",
|
||||
"⌘Enter continues on GitHub.": "⌘Enter continues on GitHub."
|
||||
}
|
||||
|
||||
@@ -463,6 +463,7 @@
|
||||
"cmd.canvas_delete": "Eliminar lienzo",
|
||||
"cmd.canvas_edit": "Editar lienzo",
|
||||
"cmd.canvas_insert": "Lienzo",
|
||||
"cmd.canvas_to_sketch": "Boceto desde lienzo",
|
||||
"cmd.component_activate": "Activar componente",
|
||||
"cmd.component_break_link": "Romper vínculo",
|
||||
"cmd.component_capture_position": "Capturar posición",
|
||||
@@ -540,6 +541,7 @@
|
||||
"cmd.file_export": "Exportar",
|
||||
"cmd.file_insert_mesh": "Insertar malla",
|
||||
"cmd.file_insert_step": "Insertar STEP",
|
||||
"cmd.file_open_in_easyprint": "Abrir con EasyPrint",
|
||||
"cmd.file_save_mesh": "Guardar como malla",
|
||||
"cmd.file_slicers": "Laminadores instalados",
|
||||
"cmd.frame_member": "Miembro estructural",
|
||||
@@ -757,6 +759,7 @@
|
||||
"cmd.sketch_spline_control_point_5": "Spline por puntos de control (grado 5)",
|
||||
"cmd.sketch_spline_fit_point": "Spline por puntos de ajuste",
|
||||
"cmd.sketch_spun_profile": "Perfil de revolución",
|
||||
"cmd.sketch_toggle_diameter": "Alternar radio / diámetro",
|
||||
"cmd.sketch_toggle_driven": "Alternar cota de referencia",
|
||||
"cmd.sketch_trim_path": "Recortar a lo largo de la trayectoria",
|
||||
"cmd.solid_align": "Alinear",
|
||||
@@ -1087,6 +1090,12 @@
|
||||
"pick one or two vertices, edges or faces": "selecciona uno o dos vértices, aristas o caras",
|
||||
"prefs.cpu": "CPU (software)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Seguir un archivo de tema",
|
||||
"prefs.theme_follow_error": "No aplicado: {error}. Se mantiene el último tema válido.",
|
||||
"prefs.theme_follow_launch": "Solo en esta sesión (--theme-file); se recarga cada vez que otra herramienta reescribe el archivo.",
|
||||
"prefs.theme_follow_note": "Se recarga cada vez que otra herramienta reescribe el archivo. Elegir un tema deja de seguirlo.",
|
||||
"prefs.theme_follow_off": "Desactivado",
|
||||
"prefs.theme_follow_stop": "Dejar de seguir",
|
||||
"properties.title": "Propiedades: {name}",
|
||||
"recovery.days_ago": "hace {count} días",
|
||||
"recovery.detail": "{file} · {features} operaciones · autoguardado {when}",
|
||||
@@ -1975,7 +1984,7 @@
|
||||
"ui.agent_chat_pop_out": "Abrir en su propia ventana, que puedes mover a otra pantalla",
|
||||
"ui.agent_chat_previous_picture": "Imagen anterior",
|
||||
"ui.agent_chat_privacy": "Solo se envían datos al agente que ejecutes, con tu propia cuenta.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft no envía nada a otros destinos: el agente que ejecutas se comunica con su propio servicio utilizando tu cuenta. SolidCraft nunca ve ni almacena claves o contraseñas.",
|
||||
"ui.agent_chat_privacy_note": "El chat no envía nada por sí mismo a otros destinos: el agente que ejecutas se comunica con su propio servicio utilizando tu cuenta. SolidCraft nunca ve ni almacena claves o contraseñas.",
|
||||
"ui.agent_chat_queue": "Poner en cola",
|
||||
"ui.agent_chat_queue_full": "Hay demasiados mensajes en espera: elimina uno o espera a que termine el agente.",
|
||||
"ui.agent_chat_queued": "En cola",
|
||||
@@ -2162,6 +2171,7 @@
|
||||
"ui.command_done": "{command} completado",
|
||||
"ui.command_palette_hint": "Escribe un comando, p. ej., {example}, o pulsa S para buscar",
|
||||
"ui.concentric": "Concéntrico",
|
||||
"ui.cone": "Cono",
|
||||
"ui.conic_curve": "Curva cónica",
|
||||
"ui.constant": "Constante",
|
||||
"ui.constraints_conflict": "Conflicto entre restricciones",
|
||||
@@ -2220,6 +2230,11 @@
|
||||
"ui.draft": "Ángulo de salida",
|
||||
"ui.drawing": "Dibujo",
|
||||
"ui.drill_point": "Punta de broca",
|
||||
"ui.easyprint_consent": "EasyPrint es el slicer de Printables en el navegador. Para abrir el modelo allí, SolidCraft lo sube a los servidores de Printables. El enlace caduca a los 30 minutos y tendrás que haber iniciado sesión en Printables. ¿Continuar?",
|
||||
"ui.easyprint_failed": "No se pudo subir a EasyPrint: {error}",
|
||||
"ui.easyprint_opened": "Abierto en EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, en el navegador)",
|
||||
"ui.easyprint_uploading": "Subiendo a Printables…",
|
||||
"ui.edit": "Editar",
|
||||
"ui.editJointLimits": "Editar límites de unión",
|
||||
"ui.edit_section_analysis": "Editar análisis de sección",
|
||||
@@ -2276,6 +2291,7 @@
|
||||
"ui.heading_circular_pattern": "PATRÓN CIRCULAR",
|
||||
"ui.heading_coil": "HÉLICE",
|
||||
"ui.heading_combine": "COMBINAR",
|
||||
"ui.heading_cone": "CONO",
|
||||
"ui.heading_configure": "CONFIGURAR",
|
||||
"ui.heading_constraints": "RESTRICCIONES",
|
||||
"ui.heading_construct": "CONSTRUIR",
|
||||
@@ -2512,9 +2528,7 @@
|
||||
"ui.right": "Derecha",
|
||||
"ui.save": "Guardar",
|
||||
"ui.save_as": "Guardar como",
|
||||
"ui.save_mesh_no_slicer": "No se ha encontrado ningún laminador: elige Personalizado… y selecciona tu laminador, o desactiva Enviar al laminador",
|
||||
"ui.save_mesh_pick_bodies": "Selecciona los cuerpos que se van a guardar",
|
||||
"ui.save_mesh_temp_failed": "No se ha podido crear {folder}: {error}",
|
||||
"ui.saved_to": "Guardado en {path}",
|
||||
"ui.sbox_pin": "Fijar arriba en la búsqueda S",
|
||||
"ui.sbox_unpin": "Desfijar",
|
||||
@@ -2529,7 +2543,6 @@
|
||||
"ui.selection_shift_add_only": "Mayús+clic añade sin quitar",
|
||||
"ui.selection_shift_add_only_tip": "Activado: Mayús añade elementos, Ctrl/Cmd alterna. Desactivado (predeterminado): Mayús y Ctrl/Cmd alternan.",
|
||||
"ui.send": "Enviar",
|
||||
"ui.send_to_slicer": "Enviar al laminador",
|
||||
"ui.sent_to_slicer": "Enviado a {slicer}",
|
||||
"ui.sheet_gap": "Separación",
|
||||
"ui.shell": "Vaciado",
|
||||
@@ -2621,6 +2634,7 @@
|
||||
"ui.untitled": "Sin título",
|
||||
"ui.up_axis_note": "Eje que apunta hacia arriba en las vistas (vista de eje, Inicio, Mirar hacia). Los diseños no cambian.",
|
||||
"ui.updateToCurrentView": "Actualizar a vista actual",
|
||||
"ui.upload": "Subir",
|
||||
"ui.view_centre": "Centro de la vista",
|
||||
"ui.visual_shaded_hidden_edges": "Sombreado con aristas ocultas",
|
||||
"ui.visual_shaded_with_edges": "Sombreado con aristas",
|
||||
|
||||
@@ -457,6 +457,7 @@
|
||||
"cmd.canvas_delete": "Eliminar o lenzo",
|
||||
"cmd.canvas_edit": "Editar o lenzo",
|
||||
"cmd.canvas_insert": "Lenzo",
|
||||
"cmd.canvas_to_sketch": "Bosquexo desde o lenzo",
|
||||
"cmd.component_activate": "Activar o compoñente",
|
||||
"cmd.component_break_link": "Romper a ligazón",
|
||||
"cmd.component_capture_position": "Capturar a posición",
|
||||
@@ -534,6 +535,7 @@
|
||||
"cmd.file_export": "Exportar",
|
||||
"cmd.file_insert_mesh": "Inserir malla",
|
||||
"cmd.file_insert_step": "Inserir STEP",
|
||||
"cmd.file_open_in_easyprint": "Abrir con EasyPrint",
|
||||
"cmd.file_save_mesh": "Gardar como malla",
|
||||
"cmd.file_slicers": "Laminadores instalados",
|
||||
"cmd.frame_member": "Membro estrutural",
|
||||
@@ -1001,6 +1003,12 @@
|
||||
"pick one or two vertices, edges or faces": "escolle un ou dous vértices, arestas ou caras",
|
||||
"prefs.cpu": "CPU (software)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Seguir un ficheiro de tema",
|
||||
"prefs.theme_follow_error": "Non aplicado: {error}. Mantense o último tema válido.",
|
||||
"prefs.theme_follow_launch": "Só nesta sesión (--theme-file); vólvese cargar cando outra ferramenta reescribe o ficheiro.",
|
||||
"prefs.theme_follow_note": "Vólvese cargar cando outra ferramenta reescribe o ficheiro. Escoller un tema detén o seguimento.",
|
||||
"prefs.theme_follow_off": "Desactivado",
|
||||
"prefs.theme_follow_stop": "Deixar de seguir",
|
||||
"properties.title": "Propiedades: {name}",
|
||||
"recovery.days_ago": "hai {count} días",
|
||||
"recovery.detail": "{file} · {features} operacións · gardado automaticamente {when}",
|
||||
@@ -1326,7 +1334,7 @@
|
||||
"ui.agent_chat_pop_out": "Abrir nunha xanela propia, que podes mover a outra pantalla",
|
||||
"ui.agent_chat_previous_picture": "Imaxe anterior",
|
||||
"ui.agent_chat_privacy": "Nada vai a ningún sitio agás ao axente que executas, coa túa propia conta.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft non envía nada a ningún sitio: o axente que executas fala co seu propio servizo coa túa propia conta. SolidCraft nunca ve nin garda ningunha clave nin contrasinal.",
|
||||
"ui.agent_chat_privacy_note": "O chat non envía nada por si mesmo a ningún sitio: o axente que executas fala co seu propio servizo coa túa propia conta. SolidCraft nunca ve nin garda ningunha clave nin contrasinal.",
|
||||
"ui.agent_chat_queue": "Pór na cola",
|
||||
"ui.agent_chat_queue_full": "Hai demasiadas mensaxes agardando: quita unha ou agarda polo axente.",
|
||||
"ui.agent_chat_queued": "Na cola",
|
||||
@@ -1511,6 +1519,7 @@
|
||||
"ui.command_done": "{command} feito",
|
||||
"ui.command_palette_hint": "Escribe unha orde, p. ex. {example} — ou preme S para buscar",
|
||||
"ui.concentric": "Concéntrica",
|
||||
"ui.cone": "Cono",
|
||||
"ui.conic_curve": "Curva cónica",
|
||||
"ui.constant": "Constante",
|
||||
"ui.constraints_conflict": "Conflito de restricións",
|
||||
@@ -1569,6 +1578,11 @@
|
||||
"ui.draft": "Ángulo de desmoldaxe",
|
||||
"ui.drawing": "Debuxo",
|
||||
"ui.drill_point": "Punta de broca",
|
||||
"ui.easyprint_consent": "EasyPrint é o slicer de Printables no navegador. Para abrir o modelo alí, SolidCraft cárgao nos servidores de Printables. A ligazón caduca aos 30 minutos e terás que ter a sesión iniciada en Printables. Continuar?",
|
||||
"ui.easyprint_failed": "Non se puido cargar a EasyPrint: {error}",
|
||||
"ui.easyprint_opened": "Aberto en EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, no navegador)",
|
||||
"ui.easyprint_uploading": "Cargando a Printables…",
|
||||
"ui.edit": "Editar",
|
||||
"ui.editJointLimits": "Editar os límites da unión",
|
||||
"ui.edit_section_analysis": "Editar a análise de sección",
|
||||
@@ -1625,6 +1639,7 @@
|
||||
"ui.heading_circular_pattern": "PATRÓN CIRCULAR",
|
||||
"ui.heading_coil": "HÉLICE",
|
||||
"ui.heading_combine": "COMBINAR",
|
||||
"ui.heading_cone": "CONO",
|
||||
"ui.heading_configure": "CONFIGURAR",
|
||||
"ui.heading_constraints": "RESTRICIÓNS",
|
||||
"ui.heading_construct": "CONSTRUÍR",
|
||||
@@ -1860,9 +1875,7 @@
|
||||
"ui.right": "Dereita",
|
||||
"ui.save": "Gardar",
|
||||
"ui.save_as": "Gardar como",
|
||||
"ui.save_mesh_no_slicer": "Non se atopou ningún laminador: escolle Personalizado… e selecciona o teu programa laminador, ou desactiva Enviar ao laminador",
|
||||
"ui.save_mesh_pick_bodies": "Selecciona os corpos que queres gardar",
|
||||
"ui.save_mesh_temp_failed": "Non se puido crear {folder}: {error}",
|
||||
"ui.saved_to": "Gardado {path}",
|
||||
"ui.sbox_pin": "Fixar arriba na caixa S",
|
||||
"ui.sbox_unpin": "Desfixar",
|
||||
@@ -1877,7 +1890,6 @@
|
||||
"ui.selection_shift_add_only": "Maiús+clic engade sen quitar",
|
||||
"ui.selection_shift_add_only_tip": "Activado: Maiús engade elementos, Ctrl/Cmd alterna. Desactivado (predeterminado): Maiús e Ctrl/Cmd alternan ambos.",
|
||||
"ui.send": "Enviar",
|
||||
"ui.send_to_slicer": "Enviar ao laminador",
|
||||
"ui.sent_to_slicer": "Enviado a {slicer}",
|
||||
"ui.sheet_gap": "Separación",
|
||||
"ui.shell": "Baleirado",
|
||||
@@ -1969,6 +1981,7 @@
|
||||
"ui.untitled": "Sen título",
|
||||
"ui.up_axis_note": "Que eixe apunta cara arriba nas vistas (vista de eixe, Inicio, Mirar cara a). Os deseños non cambian.",
|
||||
"ui.updateToCurrentView": "Actualizar á vista actual",
|
||||
"ui.upload": "Cargar",
|
||||
"ui.view_centre": "Centro da vista",
|
||||
"ui.visual_shaded_hidden_edges": "Sombreado con arestas ocultas",
|
||||
"ui.visual_shaded_with_edges": "Sombreado con arestas",
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
"cmd.canvas_delete": "Vászon törlése",
|
||||
"cmd.canvas_edit": "Vászon szerkesztése",
|
||||
"cmd.canvas_insert": "Vászon",
|
||||
"cmd.canvas_to_sketch": "Vázlat vászonból",
|
||||
"cmd.component_activate": "Komponens aktiválása",
|
||||
"cmd.component_break_link": "Kapcsolat megszakítása",
|
||||
"cmd.component_capture_position": "Pozíció rögzítése",
|
||||
@@ -533,6 +534,7 @@
|
||||
"cmd.file_export": "Exportálás",
|
||||
"cmd.file_insert_mesh": "Háló beszúrása",
|
||||
"cmd.file_insert_step": "STEP beszúrása",
|
||||
"cmd.file_open_in_easyprint": "Megnyitás EasyPrinttel",
|
||||
"cmd.file_save_mesh": "Mentés hálóként",
|
||||
"cmd.file_slicers": "Telepített szeletelők",
|
||||
"cmd.frame_member": "Szerkezeti elem",
|
||||
@@ -1000,6 +1002,12 @@
|
||||
"pick one or two vertices, edges or faces": "jelöljön ki egy vagy két csúcsot, élt vagy lapot",
|
||||
"prefs.cpu": "CPU (szoftveres)",
|
||||
"prefs.minutes_suffix": " perc",
|
||||
"prefs.theme_follow": "Témafájl követése",
|
||||
"prefs.theme_follow_error": "Nem alkalmazható: {error}. Az utolsó érvényes téma marad aktív.",
|
||||
"prefs.theme_follow_launch": "Követés csak erre a futásra (--theme-file); újratöltés, ha más eszköz felülírja a fájlt.",
|
||||
"prefs.theme_follow_note": "Újratöltés, ha más eszköz felülírja a fájlt. Téma választása leállítja a követést.",
|
||||
"prefs.theme_follow_off": "Ki",
|
||||
"prefs.theme_follow_stop": "Követés leállítása",
|
||||
"properties.title": "Tulajdonságok: {name}",
|
||||
"recovery.days_ago": "{count} napja",
|
||||
"recovery.detail": "{file} · {features} elem · automatikusan mentve: {when}",
|
||||
@@ -1269,7 +1277,7 @@
|
||||
"ui.agent_chat_pop_out": "Megnyitás saját ablakban, amelyet másik képernyőre mozgathat",
|
||||
"ui.agent_chat_previous_picture": "Előző kép",
|
||||
"ui.agent_chat_privacy": "Semmi sem megy sehová, csak az Ön által futtatott ügynökhöz, az Ön saját fiókja alatt.",
|
||||
"ui.agent_chat_privacy_note": "A SolidCraft semmit sem küld sehová: az Ön által futtatott ügynök a saját szolgáltatásával kommunikál, az Ön saját fiókja alatt. A SolidCraft soha nem lát és nem tárol kulcsot vagy jelszót.",
|
||||
"ui.agent_chat_privacy_note": "A csevegés önmagától semmit sem küld sehová: az Ön által futtatott ügynök a saját szolgáltatásával kommunikál, az Ön saját fiókja alatt. A SolidCraft soha nem lát és nem tárol kulcsot vagy jelszót.",
|
||||
"ui.agent_chat_queue": "Sorba",
|
||||
"ui.agent_chat_queue_full": "Túl sok üzenet vár: távolítson el egyet, vagy várja meg az ügynököt.",
|
||||
"ui.agent_chat_queued": "Sorban",
|
||||
@@ -1453,6 +1461,7 @@
|
||||
"ui.command_done": "{command} kész",
|
||||
"ui.command_palette_hint": "Írjon be egy parancsot, pl. {example} – vagy nyomja meg az S-t a kereséshez",
|
||||
"ui.concentric": "Koncentrikus",
|
||||
"ui.cone": "Kúp",
|
||||
"ui.conic_curve": "Kúpgörbe",
|
||||
"ui.constant": "Állandó",
|
||||
"ui.constraints_conflict": "Kényszerek ütköznek",
|
||||
@@ -1511,6 +1520,11 @@
|
||||
"ui.draft": "Dőlés",
|
||||
"ui.drawing": "Rajz",
|
||||
"ui.drill_point": "Fúrócsúcs",
|
||||
"ui.easyprint_consent": "Az EasyPrint a Printables szeletelője a böngészőben. A modell ott való megnyitásához a SolidCraft feltölti azt a Printables szervereire. A hivatkozás 30 perc után lejár, és be kell jelentkeznie a Printablesbe. Folytatja?",
|
||||
"ui.easyprint_failed": "Az EasyPrintre feltöltés sikertelen: {error}",
|
||||
"ui.easyprint_opened": "Megnyitva az EasyPrintben",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, a böngészőben)",
|
||||
"ui.easyprint_uploading": "Feltöltés a Printablesbe…",
|
||||
"ui.edit": "Szerkesztés",
|
||||
"ui.editJointLimits": "Csuklókorlátok szerkesztése",
|
||||
"ui.edit_section_analysis": "Metszetelemzés szerkesztése",
|
||||
@@ -1567,6 +1581,7 @@
|
||||
"ui.heading_circular_pattern": "KÖRMINTA",
|
||||
"ui.heading_coil": "SPIRÁL",
|
||||
"ui.heading_combine": "EGYESÍTÉS",
|
||||
"ui.heading_cone": "KÚP",
|
||||
"ui.heading_configure": "KONFIGURÁLÁS",
|
||||
"ui.heading_constraints": "KÉNYSZEREK",
|
||||
"ui.heading_construct": "SZERKESZTÉS",
|
||||
@@ -1802,9 +1817,7 @@
|
||||
"ui.right": "Jobb",
|
||||
"ui.save": "Mentés",
|
||||
"ui.save_as": "Mentés másként",
|
||||
"ui.save_mesh_no_slicer": "Nem található szeletelő: válassza az Egyéni… lehetőséget és jelölje ki a szeletelőprogramot, vagy kapcsolja ki a Küldés szeletelőnek beállítást",
|
||||
"ui.save_mesh_pick_bodies": "Jelölje ki a mentendő testeket",
|
||||
"ui.save_mesh_temp_failed": "A(z) {folder} nem hozható létre: {error}",
|
||||
"ui.saved_to": "Mentve: {path}",
|
||||
"ui.sbox_pin": "Rögzítés az S doboz tetejére",
|
||||
"ui.sbox_unpin": "Rögzítés feloldása",
|
||||
@@ -1819,7 +1832,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+kattintás eltávolítás nélkül hozzáad",
|
||||
"ui.selection_shift_add_only_tip": "Be: a Shift hozzáad, a Ctrl/Cmd vált. Ki (alapért.): a Shift és a Ctrl/Cmd is vált.",
|
||||
"ui.send": "Küldés",
|
||||
"ui.send_to_slicer": "Küldés szeletelőnek",
|
||||
"ui.sent_to_slicer": "Elküldve ide: {slicer}",
|
||||
"ui.sheet_gap": "Rés",
|
||||
"ui.shell": "Héjazás",
|
||||
@@ -1911,6 +1923,7 @@
|
||||
"ui.untitled": "Névtelen",
|
||||
"ui.up_axis_note": "Melyik tengely mutat felfelé a nézetekben (tengelynézet, Kezdőlap, Ránézés). A tervek változatlanok.",
|
||||
"ui.updateToCurrentView": "Frissítés az aktuális nézetre",
|
||||
"ui.upload": "Feltöltés",
|
||||
"ui.view_centre": "Nézet középpontja",
|
||||
"ui.visual_shaded_hidden_edges": "Árnyalt rejtett élekkel",
|
||||
"ui.visual_shaded_with_edges": "Árnyalt élekkel",
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
"cmd.canvas_delete": "Hapus Kanvas",
|
||||
"cmd.canvas_edit": "Edit Kanvas",
|
||||
"cmd.canvas_insert": "Kanvas",
|
||||
"cmd.canvas_to_sketch": "Kanvas ke Sketsa",
|
||||
"cmd.component_activate": "Aktifkan Komponen",
|
||||
"cmd.component_break_link": "Putuskan Tautan",
|
||||
"cmd.component_capture_position": "Tangkap Posisi",
|
||||
@@ -533,6 +534,7 @@
|
||||
"cmd.file_export": "Ekspor",
|
||||
"cmd.file_insert_mesh": "Sisipkan Mesh",
|
||||
"cmd.file_insert_step": "Sisipkan STEP",
|
||||
"cmd.file_open_in_easyprint": "Buka dengan EasyPrint",
|
||||
"cmd.file_save_mesh": "Simpan Sebagai Mesh",
|
||||
"cmd.file_slicers": "Slicer Terpasang",
|
||||
"cmd.frame_member": "Batang Rangka",
|
||||
@@ -1000,6 +1002,12 @@
|
||||
"pick one or two vertices, edges or faces": "pilih satu atau dua titik sudut, tepi, atau muka",
|
||||
"prefs.cpu": "CPU (perangkat lunak)",
|
||||
"prefs.minutes_suffix": " mnt",
|
||||
"prefs.theme_follow": "Ikuti file tema",
|
||||
"prefs.theme_follow_error": "Tidak diterapkan: {error}. Tema valid terakhir tetap aktif.",
|
||||
"prefs.theme_follow_launch": "Diikuti hanya untuk sesi ini (--theme-file); dimuat ulang setiap kali alat lain menulis ulang file.",
|
||||
"prefs.theme_follow_note": "Dimuat ulang setiap kali alat lain menulis ulang file. Memilih tema menghentikan pengikutan.",
|
||||
"prefs.theme_follow_off": "Nonaktif",
|
||||
"prefs.theme_follow_stop": "Berhenti mengikuti",
|
||||
"properties.title": "Properti: {name}",
|
||||
"recovery.days_ago": "{count} hari lalu",
|
||||
"recovery.detail": "{file} · {features} fitur · disimpan otomatis {when}",
|
||||
@@ -1269,7 +1277,7 @@
|
||||
"ui.agent_chat_pop_out": "Buka di jendela sendiri, yang dapat dipindah ke layar lain",
|
||||
"ui.agent_chat_previous_picture": "Gambar sebelumnya",
|
||||
"ui.agent_chat_privacy": "Tidak ada yang dikirim ke mana pun kecuali ke agen yang Anda jalankan, di bawah akun Anda sendiri.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft tidak mengirim apa pun ke mana pun: agen yang Anda jalankan berbicara ke layanannya sendiri di bawah akun Anda sendiri. SolidCraft tidak pernah melihat atau menyimpan key atau kata sandi.",
|
||||
"ui.agent_chat_privacy_note": "Obrolan tidak mengirim apa pun ke mana pun dengan sendirinya: agen yang Anda jalankan berbicara ke layanannya sendiri di bawah akun Anda sendiri. SolidCraft tidak pernah melihat atau menyimpan key atau kata sandi.",
|
||||
"ui.agent_chat_queue": "Antre",
|
||||
"ui.agent_chat_queue_full": "Terlalu banyak pesan menunggu: hapus satu atau tunggu agen.",
|
||||
"ui.agent_chat_queued": "Mengantre",
|
||||
@@ -1453,6 +1461,7 @@
|
||||
"ui.command_done": "{command} selesai",
|
||||
"ui.command_palette_hint": "Ketik perintah, mis. {example} — atau tekan S untuk mencari",
|
||||
"ui.concentric": "Konsentris",
|
||||
"ui.cone": "Kerucut",
|
||||
"ui.conic_curve": "Kurva Konik",
|
||||
"ui.constant": "Konstan",
|
||||
"ui.constraints_conflict": "Batasan bertentangan",
|
||||
@@ -1511,6 +1520,11 @@
|
||||
"ui.draft": "Draft",
|
||||
"ui.drawing": "Gambar Kerja",
|
||||
"ui.drill_point": "Ujung Bor",
|
||||
"ui.easyprint_consent": "EasyPrint adalah slicer Printables di browser. Untuk membuka model di sana, SolidCraft mengunggahnya ke server Printables. Tautan kedaluwarsa setelah 30 menit, dan Anda harus masuk ke Printables. Lanjutkan?",
|
||||
"ui.easyprint_failed": "Gagal mengunggah ke EasyPrint: {error}",
|
||||
"ui.easyprint_opened": "Dibuka di EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, di browser)",
|
||||
"ui.easyprint_uploading": "Mengunggah ke Printables…",
|
||||
"ui.edit": "Edit",
|
||||
"ui.editJointLimits": "Edit Batas Sambungan",
|
||||
"ui.edit_section_analysis": "Edit Analisis Penampang",
|
||||
@@ -1567,6 +1581,7 @@
|
||||
"ui.heading_circular_pattern": "POLA MELINGKAR",
|
||||
"ui.heading_coil": "KOIL",
|
||||
"ui.heading_combine": "GABUNGKAN",
|
||||
"ui.heading_cone": "KERUCUT",
|
||||
"ui.heading_configure": "KONFIGURASI",
|
||||
"ui.heading_constraints": "BATASAN",
|
||||
"ui.heading_construct": "KONSTRUKSI",
|
||||
@@ -1802,9 +1817,7 @@
|
||||
"ui.right": "Kanan",
|
||||
"ui.save": "Simpan",
|
||||
"ui.save_as": "Simpan Sebagai",
|
||||
"ui.save_mesh_no_slicer": "Slicer tidak ditemukan: pilih Kustom… dan tunjuk program slicer Anda, atau matikan Kirim ke slicer",
|
||||
"ui.save_mesh_pick_bodies": "Pilih bodi yang akan disimpan",
|
||||
"ui.save_mesh_temp_failed": "Tidak dapat membuat {folder}: {error}",
|
||||
"ui.saved_to": "Disimpan {path}",
|
||||
"ui.sbox_pin": "Sematkan di atas kotak S",
|
||||
"ui.sbox_unpin": "Lepas sematan",
|
||||
@@ -1819,7 +1832,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+klik menambah tanpa menghapus",
|
||||
"ui.selection_shift_add_only_tip": "Aktif: Shift menambah item, Ctrl/Cmd mengalihkan. Mati (default): Shift dan Ctrl/Cmd sama-sama mengalihkan.",
|
||||
"ui.send": "Kirim",
|
||||
"ui.send_to_slicer": "Kirim ke slicer",
|
||||
"ui.sent_to_slicer": "Dikirim ke {slicer}",
|
||||
"ui.sheet_gap": "Celah",
|
||||
"ui.shell": "Shell",
|
||||
@@ -1911,6 +1923,7 @@
|
||||
"ui.untitled": "Tanpa judul",
|
||||
"ui.up_axis_note": "Sumbu mana yang mengarah ke atas di tampilan (tampilan sumbu, Home, Look At). Desain tidak berubah.",
|
||||
"ui.updateToCurrentView": "Perbarui ke Tampilan Saat Ini",
|
||||
"ui.upload": "Unggah",
|
||||
"ui.view_centre": "Pusat tampilan",
|
||||
"ui.visual_shaded_hidden_edges": "Shaded dengan tepi tersembunyi",
|
||||
"ui.visual_shaded_with_edges": "Shaded dengan tepi",
|
||||
|
||||
@@ -462,6 +462,7 @@
|
||||
"cmd.canvas_delete": "Elimina immagine di riferimento",
|
||||
"cmd.canvas_edit": "Modifica immagine di riferimento",
|
||||
"cmd.canvas_insert": "Immagine di riferimento",
|
||||
"cmd.canvas_to_sketch": "Schizzo da immagine di riferimento",
|
||||
"cmd.component_activate": "Attiva componente",
|
||||
"cmd.component_break_link": "Interrompi collegamento",
|
||||
"cmd.component_capture_position": "Acquisisci posizione",
|
||||
@@ -539,6 +540,7 @@
|
||||
"cmd.file_export": "Esporta",
|
||||
"cmd.file_insert_mesh": "Inserisci mesh",
|
||||
"cmd.file_insert_step": "Inserisci STEP",
|
||||
"cmd.file_open_in_easyprint": "Apri con EasyPrint",
|
||||
"cmd.file_save_mesh": "Salva come mesh",
|
||||
"cmd.file_slicers": "Slicer installati",
|
||||
"cmd.frame_member": "Membro strutturale",
|
||||
@@ -978,6 +980,8 @@
|
||||
"manage.material_hint": "Seleziona i corpi e scegli il loro materiale fisico.",
|
||||
"manage.parameters_hint": "Modifica espressioni e unità. Le modifiche vengono applicate premendo Invio o uscendo da un campo.",
|
||||
"manage.rules_hint": "Scegli una regola da modificare o creane una nuova. Conferma per salvare la regola.",
|
||||
"material.selection.choose": "Scegli un materiale",
|
||||
"material.selection.mixed": "Materiali diversi",
|
||||
"measure.at": "In",
|
||||
"measure.item": "Elemento {number}",
|
||||
"messages.ago_h": "{n} h fa",
|
||||
@@ -1036,6 +1040,12 @@
|
||||
"pick one or two vertices, edges or faces": "seleziona uno o due vertici, spigoli o facce",
|
||||
"prefs.cpu": "CPU (software)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Segui un file di tema",
|
||||
"prefs.theme_follow_error": "Non applicato: {error}. Resta attivo l’ultimo tema valido.",
|
||||
"prefs.theme_follow_launch": "Seguito solo per questa sessione (--theme-file); ricaricato quando un altro strumento riscrive il file.",
|
||||
"prefs.theme_follow_note": "Ricaricato quando un altro strumento riscrive il file. Scegliere un tema interrompe il monitoraggio.",
|
||||
"prefs.theme_follow_off": "Disattivato",
|
||||
"prefs.theme_follow_stop": "Smetti di seguire",
|
||||
"properties.title": "Proprietà: {name}",
|
||||
"recovery.days_ago": "{count} giorni fa",
|
||||
"recovery.detail": "{file} · {features} feature · salvato automaticamente {when}",
|
||||
@@ -1365,7 +1375,7 @@
|
||||
"ui.agent_chat_pop_out": "Apri in una finestra separata, che puoi spostare su un altro schermo",
|
||||
"ui.agent_chat_previous_picture": "Immagine precedente",
|
||||
"ui.agent_chat_privacy": "I dati vengono inviati solo all'agente che esegui, con il tuo account.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft non invia dati ad alcun servizio: l'agente che esegui comunica con il proprio servizio usando il tuo account. SolidCraft non vede né memorizza mai chiavi o password.",
|
||||
"ui.agent_chat_privacy_note": "La chat non invia da sola dati ad alcun servizio: l'agente che esegui comunica con il proprio servizio usando il tuo account. SolidCraft non vede né memorizza mai chiavi o password.",
|
||||
"ui.agent_chat_queue": "Metti in coda",
|
||||
"ui.agent_chat_queue_full": "Troppi messaggi in attesa: rimuovine uno o attendi l'agente.",
|
||||
"ui.agent_chat_queued": "In coda",
|
||||
@@ -1550,6 +1560,7 @@
|
||||
"ui.command_done": "{command} completato",
|
||||
"ui.command_palette_hint": "Digita un comando, ad es. {example} — oppure premi S per cercare",
|
||||
"ui.concentric": "Concentrico",
|
||||
"ui.cone": "Cono",
|
||||
"ui.conic_curve": "Curva conica",
|
||||
"ui.constant": "Costante",
|
||||
"ui.constraints_conflict": "Vincoli in conflitto",
|
||||
@@ -1608,6 +1619,11 @@
|
||||
"ui.draft": "Sformo",
|
||||
"ui.drawing": "Disegno",
|
||||
"ui.drill_point": "Punta del trapano",
|
||||
"ui.easyprint_consent": "EasyPrint è lo slicer di Printables nel browser. Per aprire lì il modello, SolidCraft lo carica sui server di Printables. Il link scade dopo 30 minuti e dovrai aver effettuato l'accesso a Printables. Continuare?",
|
||||
"ui.easyprint_failed": "Caricamento su EasyPrint non riuscito: {error}",
|
||||
"ui.easyprint_opened": "Aperto in EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, nel browser)",
|
||||
"ui.easyprint_uploading": "Caricamento su Printables…",
|
||||
"ui.edit": "Modifica",
|
||||
"ui.editJointLimits": "Modifica limiti del giunto",
|
||||
"ui.edit_section_analysis": "Modifica analisi in sezione",
|
||||
@@ -1665,6 +1681,7 @@
|
||||
"ui.heading_circular_pattern": "RIPETIZIONE CIRCOLARE",
|
||||
"ui.heading_coil": "ELICA",
|
||||
"ui.heading_combine": "COMBINA",
|
||||
"ui.heading_cone": "CONO",
|
||||
"ui.heading_configure": "CONFIGURA",
|
||||
"ui.heading_constraints": "VINCOLI",
|
||||
"ui.heading_construct": "COSTRUISCI",
|
||||
@@ -1900,9 +1917,7 @@
|
||||
"ui.right": "Destra",
|
||||
"ui.save": "Salva",
|
||||
"ui.save_as": "Salva con nome",
|
||||
"ui.save_mesh_no_slicer": "Nessuno slicer trovato: scegli Personalizzato… e seleziona lo slicer, oppure disattiva Invia allo slicer",
|
||||
"ui.save_mesh_pick_bodies": "Seleziona i corpi da salvare",
|
||||
"ui.save_mesh_temp_failed": "Impossibile creare {folder}: {error}",
|
||||
"ui.saved_to": "Salvato {path}",
|
||||
"ui.sbox_pin": "Fissa in cima al riquadro S",
|
||||
"ui.sbox_unpin": "Sblocca",
|
||||
@@ -1917,7 +1932,6 @@
|
||||
"ui.selection_shift_add_only": "Maiusc+clic aggiunge senza rimuovere",
|
||||
"ui.selection_shift_add_only_tip": "Attivo: Maiusc aggiunge elementi, Ctrl/Cmd commuta. Disattivo (predefinito): Maiusc e Ctrl/Cmd commutano entrambi.",
|
||||
"ui.send": "Invia",
|
||||
"ui.send_to_slicer": "Invia allo slicer",
|
||||
"ui.sent_to_slicer": "Inviato a {slicer}",
|
||||
"ui.sheet_gap": "Gioco",
|
||||
"ui.shell": "Svuota",
|
||||
@@ -2009,6 +2023,7 @@
|
||||
"ui.untitled": "Senza titolo",
|
||||
"ui.up_axis_note": "L'asse verticale nelle viste (viste degli assi, Vista iniziale, Vista normale). I progetti restano invariati.",
|
||||
"ui.updateToCurrentView": "Aggiorna alla vista corrente",
|
||||
"ui.upload": "Carica",
|
||||
"ui.view_centre": "Centro della vista",
|
||||
"ui.visual_shaded_hidden_edges": "Ombreggiato con spigoli nascosti",
|
||||
"ui.visual_shaded_with_edges": "Ombreggiato con spigoli",
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
"Add Mid Radius": "中間半径を追加",
|
||||
"Add Row": "行を追加",
|
||||
"Add a tool": "ツールを追加",
|
||||
"Add all bodies": "すべてのボディを追加",
|
||||
"Add bend": "曲げを追加",
|
||||
"Add condition": "条件を追加",
|
||||
"Add or edit rule": "ルールを追加または編集",
|
||||
"Add to New Folder": "新しいフォルダーに追加",
|
||||
"Add visible bodies": "表示中のボディを追加",
|
||||
"Advanced": "詳細",
|
||||
"Against": "相手",
|
||||
"Alignment": "配置",
|
||||
@@ -56,6 +58,7 @@
|
||||
"BOUNDARY SURFACE": "境界サーフェス",
|
||||
"BROWSER": "ブラウザ",
|
||||
"Bar": "平鋼",
|
||||
"Base Center": "底面の中心",
|
||||
"Bend": "曲げ角度",
|
||||
"Bend Edges": "曲げエッジ",
|
||||
"Bend Line Position": "曲げ線位置",
|
||||
@@ -140,6 +143,7 @@
|
||||
"Create Issue — review draft": "Issueを作成 — 下書きの確認",
|
||||
"Create Issue…": "Issueを作成…",
|
||||
"Cross curves": "交差する曲線",
|
||||
"Ctrl+Enter continues on GitHub.": "Ctrl+EnterでGitHubに進みます。",
|
||||
"Cube": "キューブ",
|
||||
"Current orthographic view (1:1 mm)": "現在の平行投影(実寸・mm)",
|
||||
"Current perspective view": "現在の透視投影",
|
||||
@@ -152,6 +156,7 @@
|
||||
"Customize…": "カスタマイズ…",
|
||||
"Cylindrical face": "円筒面",
|
||||
"Delete": "削除",
|
||||
"Delete Folders and Features…": "フォルダーとフィーチャーを削除…",
|
||||
"Delete Selected Features…": "選択したフィーチャーを削除…",
|
||||
"Delete Selected Folders": "選択したフォルダーを削除",
|
||||
"Delete all": "すべて削除",
|
||||
@@ -339,7 +344,7 @@
|
||||
"Name on import": "インポート名",
|
||||
"Nearest": "最も近い",
|
||||
"New": "新規",
|
||||
"New Comp.": "新規コンポーネント",
|
||||
"New Comp.": "新規\nコンポ",
|
||||
"New Sketch": "新規スケッチ",
|
||||
"New rule…": "新規ルール…",
|
||||
"New study": "新規スタディ",
|
||||
@@ -430,6 +435,9 @@
|
||||
"Remove this point": "この点を削除",
|
||||
"Rename Feature": "フィーチャーの名前を変更",
|
||||
"Rename Folder": "フォルダーの名前を変更",
|
||||
"Render Stage": "レンダリング段階",
|
||||
"Reopen designs": "デザインを再度開く",
|
||||
"Reopen the designs that were open when SolidCraft was last closed": "前回 SolidCraft を閉じたときに開いていたデザインを再度開く",
|
||||
"Replace existing library file": "既存のライブラリファイルを置き換える",
|
||||
"Report a bug — review a screenshot and open a GitHub draft": "バグを報告 — スクリーンショットを確認してGitHub下書きを作成",
|
||||
"Report text copied. Paste it into GitHub and submit your report there.": "報告本文をコピーしました。GitHubに貼り付けて投稿してください。",
|
||||
@@ -532,6 +540,7 @@
|
||||
"Style": "スタイル",
|
||||
"Summary": "概要",
|
||||
"Suppress": "抑制",
|
||||
"Suppress Selected Folders": "選択したフォルダーを抑制",
|
||||
"Suppressed": "抑制",
|
||||
"Surface": "サーフェス",
|
||||
"Surface, or faces to turn over": "サーフェス、または裏返す面",
|
||||
@@ -579,6 +588,7 @@
|
||||
"UNTRIM": "トリム解除",
|
||||
"Unit": "単位",
|
||||
"Unsuppress": "抑制を解除",
|
||||
"Unsuppress Selected Folders": "選択したフォルダーの抑制を解除",
|
||||
"Updating the preview": "プレビューを更新中",
|
||||
"Use active author placement": "アクティブな作成元配置を使用",
|
||||
"Use fixed plane": "固定平面を使用",
|
||||
@@ -626,6 +636,8 @@
|
||||
"ai.prefs.background_commands": "エージェントのコマンドをバックグラウンドで実行",
|
||||
"ai.prefs.connect_apps": "このコンピューターの AI アプリで SolidCraft を使えるようにする",
|
||||
"ai.prefs.connect_apps_note": "SolidCraft の起動時に、このコンピューターで見つかった AI アプリ(OpenCode、Claude Desktop、Claude Code、Cursor、Codex、Gemini CLI、Copilot CLI、Windsurf、Zed、VS Code)へ MCP サーバーとして追加します。追加または更新するのは solidcraft のエントリのみで、変更済みのエントリには触れず、ファイルは先にバックアップされます。オフにすると追加したエントリを削除します。",
|
||||
"ai.prefs.connect_at_start": "SolidCraft の起動時に前回使用したエージェントに接続",
|
||||
"ai.prefs.connect_at_start_note": "SolidCraft を起動するたびに、前回接続したエージェント (またはデフォルトのエージェント) をバックグラウンドで起動し、すぐにチャットできるようにします。--control を付けて起動した場合は行いません。接続できない場合、アシスタントに「接続に失敗しました」と「再試行」ボタンが表示されます。",
|
||||
"ai.prefs.follow_camera": "カメラをスケッチに向ける",
|
||||
"ai.prefs.follow_camera_off": "カメラの自動追従はオフです。",
|
||||
"ai.prefs.follow_camera_on": "エージェントが作成するスケッチにカメラを向けます。",
|
||||
@@ -633,6 +645,8 @@
|
||||
"ai.prefs.make_default": "既定にする",
|
||||
"ai.prefs.no_agents": "エージェントはまだありません。追加するか、更新してインストール済みのエージェントを検索してください。",
|
||||
"ai.prefs.no_saved_approvals": "保存された許可はありません。",
|
||||
"ai.prefs.open_at_start": "SolidCraft の起動時にアシスタントパネルを開く",
|
||||
"ai.prefs.open_at_start_note": "SolidCraft を起動するたびにアシスタントパネル (または独立したウィンドウ) を表示します。--control を付けて起動した場合は行いません。",
|
||||
"ai.prefs.override_all_warning": "このエージェントは確認せずに設計を保存、上書き、書き出し、置換できます。",
|
||||
"ai.prefs.permission_all": "すべて許可",
|
||||
"ai.prefs.permission_all_summary": "利用可能なSolidCraftツールを確認せず実行します。",
|
||||
@@ -677,6 +691,9 @@
|
||||
"cmd.appearance_assign": "外観",
|
||||
"cmd.appearance_library": "外観ライブラリ",
|
||||
"cmd.appearance_list": "外観を一覧表示",
|
||||
"cmd.appearance_paint": "外観をペイント",
|
||||
"cmd.appearance_pick_up": "外観を取得",
|
||||
"cmd.appearance_replace": "外観を置換",
|
||||
"cmd.assembly_bom": "部品表",
|
||||
"cmd.body_rename": "ボディの名前を変更",
|
||||
"cmd.browser_collapse_all": "すべて折りたたむ",
|
||||
@@ -692,10 +709,12 @@
|
||||
"cmd.canvas_delete": "キャンバスを削除",
|
||||
"cmd.canvas_edit": "キャンバスを編集",
|
||||
"cmd.canvas_insert": "キャンバス",
|
||||
"cmd.canvas_to_sketch": "キャンバスからスケッチ",
|
||||
"cmd.component_activate": "コンポーネントをアクティブ化",
|
||||
"cmd.component_break_link": "リンクを解除",
|
||||
"cmd.component_capture_position": "位置をキャプチャ",
|
||||
"cmd.component_copies": "同一のコピーを検索",
|
||||
"cmd.component_copy_bodies": "ボディを貼り付け",
|
||||
"cmd.component_create": "新規コンポーネント",
|
||||
"cmd.component_cycle_color": "コンポーネントの色を順に変更",
|
||||
"cmd.component_delete": "コンポーネントを削除",
|
||||
@@ -762,6 +781,7 @@
|
||||
"cmd.document_revision": "デザイン リビジョン",
|
||||
"cmd.document_units": "デザインの単位を変更",
|
||||
"cmd.edit_checkpoint": "チェックポイント",
|
||||
"cmd.edit_repeat": "最後のコマンドを繰り返す",
|
||||
"cmd.edit_restore_checkpoint": "チェックポイントを復元",
|
||||
"cmd.engine_commands": "コマンドを一覧表示",
|
||||
"cmd.engine_describe": "コマンドの詳細を表示",
|
||||
@@ -774,7 +794,9 @@
|
||||
"cmd.file_export": "エクスポート",
|
||||
"cmd.file_insert_mesh": "メッシュを挿入",
|
||||
"cmd.file_insert_step": "STEP を挿入",
|
||||
"cmd.file_open_in_easyprint": "EasyPrint で開く",
|
||||
"cmd.file_save_mesh": "メッシュとして保存",
|
||||
"cmd.file_send_to_slicer": "スライサーに送る",
|
||||
"cmd.file_slicers": "インストール済みのスライサー",
|
||||
"cmd.frame_member": "フレーム部材",
|
||||
"cmd.frame_profile_insert": "形材を挿入",
|
||||
@@ -846,6 +868,7 @@
|
||||
"cmd.occurrence_ground": "空間固定",
|
||||
"cmd.occurrence_move": "オカレンスを移動",
|
||||
"cmd.occurrence_properties": "オカレンスの物理的プロパティ",
|
||||
"cmd.occurrence_reparent": "コンポーネントへ移動",
|
||||
"cmd.parameters_add": "ユーザー パラメータを追加",
|
||||
"cmd.parameters_change": "パラメータを変更",
|
||||
"cmd.parameters_comment": "パラメータにコメントを付与",
|
||||
@@ -872,9 +895,11 @@
|
||||
"cmd.plastic_snap_fit": "スナップ フィット",
|
||||
"cmd.render_aging_describe": "レイヤー式表面エイジング",
|
||||
"cmd.render_backends": "レンダリング バックエンド",
|
||||
"cmd.render_batch": "すべてのショットをレンダリング",
|
||||
"cmd.render_camera_fit": "レンダー対象をフレームに合わせる",
|
||||
"cmd.render_camera_get": "レンダーカメラを確認",
|
||||
"cmd.render_cancel": "レンダリングをキャンセル",
|
||||
"cmd.render_compare": "画像を比較",
|
||||
"cmd.render_effects_describe": "レンズとクリエイティブ効果",
|
||||
"cmd.render_export": "PNGをエクスポート",
|
||||
"cmd.render_hdr_inspect": "HDRソースを調査",
|
||||
@@ -890,6 +915,7 @@
|
||||
"cmd.render_library_surface_prepare": "作成済みサーフェスマップを準備",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "レンダリングリソースの対象を検索",
|
||||
"cmd.render_lights_solo": "ライトを単独表示",
|
||||
"cmd.render_optics_bind": "光学割り当てを保存",
|
||||
"cmd.render_optics_unbind": "光学割り当てを削除",
|
||||
"cmd.render_preflight": "レンダリング要求を確認",
|
||||
@@ -954,6 +980,7 @@
|
||||
"cmd.sketch_drag": "スケッチ ジオメトリをドラッグ",
|
||||
"cmd.sketch_drag_end": "スケッチのドラッグを終了",
|
||||
"cmd.sketch_draw_dimensioned": "寸法付きスケッチ ジオメトリを描画",
|
||||
"cmd.sketch_drawing_bounds": "図面のサイズ",
|
||||
"cmd.sketch_edit": "スケッチを編集",
|
||||
"cmd.sketch_edit_text": "テキストを編集",
|
||||
"cmd.sketch_export_dxf": "DXF として保存",
|
||||
@@ -998,8 +1025,11 @@
|
||||
"cmd.sketch_spline_control_point": "制御点スプライン",
|
||||
"cmd.sketch_spline_control_point_5": "制御点スプライン (次数 5)",
|
||||
"cmd.sketch_spline_fit_point": "通過点スプライン",
|
||||
"cmd.sketch_spline_insert_point": "スプライン点を追加",
|
||||
"cmd.sketch_spun_profile": "回転プロファイル",
|
||||
"cmd.sketch_toggle_diameter": "半径 / 直径の切り替え",
|
||||
"cmd.sketch_toggle_driven": "従動寸法の切り替え",
|
||||
"cmd.sketch_transform": "変形",
|
||||
"cmd.sketch_trim_path": "パスに沿ってトリム",
|
||||
"cmd.solid_align": "整列",
|
||||
"cmd.solid_boundary_fill": "境界フィル",
|
||||
@@ -1063,6 +1093,7 @@
|
||||
"cmd.view_rename": "名前付きビューの名前を変更",
|
||||
"cmd.view_right": "右側面ビュー",
|
||||
"cmd.view_save": "新規名前付きビュー",
|
||||
"cmd.view_shots_strip": "ショットストリップ",
|
||||
"cmd.view_spin": "連続オービット",
|
||||
"cmd.view_tool": "ナビゲーションツール",
|
||||
"cmd.view_top": "上面ビュー",
|
||||
@@ -1136,6 +1167,7 @@
|
||||
"document.save_changes": "{name} への変更を保存しますか?",
|
||||
"document.save_copy": "コピーを保存…",
|
||||
"document.unsaved_changes": "{name} には保存されていない変更があります。保存しない場合、変更内容は失われます。",
|
||||
"drive.rigid": "{joint} は剛体ジョイントです。部品をその場に固定するため、駆動するものがありません。動かすには「ジョイントを編集」で種類を変更してください: 回転させるなら Revolute、スライドさせるなら Slider、両方なら Cylindrical。",
|
||||
"drive.stopped_by_contact": "{value} で停止: {a} が {b} を通り抜けてしまいます",
|
||||
"drive.stopped_by_loop": "{value} で停止: {joint} を通るループはこれ以上閉じられません",
|
||||
"drive.unconnected": "何も動きません: {part} は空間固定されたものに接続されていません",
|
||||
@@ -1277,6 +1309,9 @@
|
||||
"install.steps_intro": "Safari では、Web アプリを Safari 自身のメニューからインストールします:",
|
||||
"install.title": "SolidCraft をインストール",
|
||||
"issue.body_label": "レポート本文",
|
||||
"issue.note_changed_while_waiting": "プレビューを待っている間に設定またはモデルが変更されました。スクリーンショットを撮り直すと、技術的な詳細が現在の表示に合わせて更新されます。",
|
||||
"issue.note_details_kept": "スクリーンショットをローカルに取得しました。編集した技術的な詳細はそのまま残しました。現在の表示と合っているか確認してください。",
|
||||
"issue.note_details_updated": "技術的な詳細を現在の表示に合わせて更新しました。スクリーンショットをローカルに取得しました。GitHub に添付する前に確認してください。",
|
||||
"issue.note_image_copied": "GitHubの下書きに画像を貼り付けてください。画像をコピーできない場合はPNGを保存してください。",
|
||||
"issue.note_opened": "GitHubの下書きを確認し、スクリーンショットを添付してください。GitHubのSubmit new issueボタンで公開されます。",
|
||||
"issue.note_opened_copied": "レポートをコピーしました。GitHubの下書きに貼り付け、スクリーンショットを添付してから、GitHubでSubmit new issueをクリックしてください。",
|
||||
@@ -1343,6 +1378,8 @@
|
||||
"material.editor.unknown_card": "工学特性は不明です。割り当て密度と既存の外観だけでも保存できます。",
|
||||
"material.editor.user_supplied": "ユーザー提供",
|
||||
"material.editor.wood": "木材",
|
||||
"material.selection.choose": "材料を選択",
|
||||
"material.selection.mixed": "異なる材料",
|
||||
"measure.at": "位置",
|
||||
"measure.item": "項目 {number}",
|
||||
"messages.ago_h": "{n} 時間前",
|
||||
@@ -1371,6 +1408,9 @@
|
||||
"nav.blender.help": "中ドラッグで回転、Shift+中ドラッグでパン、Ctrl+中ドラッグでズーム。右ドラッグではカメラは動きません。",
|
||||
"nav.free_orbit.help": "マウスと3Dマウスで、極点を越えて回転し、ロールを保ちます。\nShiftによる軸スナップは無効になります。",
|
||||
"nav.free_orbit.label": "自由回転",
|
||||
"nav.free_orbit.snap_help": "マウスと3Dマウスで両極を越えて回転でき、ロールも保持されます。オービットのドラッグ中にShiftを押すと、視線方向とロールがスナップします。",
|
||||
"nav.free_orbit_upright.help": "マウスを左右にドラッグするとワールドの垂直軸を中心にモデルが回転し、上下にドラッグすると制限なく真上を越えて傾きます。",
|
||||
"nav.free_orbit_upright.label": "垂直軸を中心に回転",
|
||||
"nav.fusion.help": "中ドラッグでパン、Shift+中ドラッグで回転、右ドラッグで回転。",
|
||||
"nav.inventor.help": "中ドラッグでパン、Shift+中ドラッグで回転、Ctrl+中ドラッグでズーム、右ドラッグで回転。",
|
||||
"nav.openscad.help": "空きスペースで左ドラッグすると回転、Shift+左ドラッグで矩形選択、スケッチ ジオメトリはドラッグで編集。右または中ドラッグでパン、Shift+右または Shift+中ドラッグでズーム。",
|
||||
@@ -1445,6 +1485,11 @@
|
||||
"prefs.design": "設計の既定値",
|
||||
"prefs.design_note": "新しいデザインの初期設定です。開いているデザインはそれぞれの設定を保持します。",
|
||||
"prefs.devices": "3D マウス",
|
||||
"prefs.dialog_buttons": "ダイアログのボタン",
|
||||
"prefs.dialogs": "ダイアログ",
|
||||
"prefs.dialogs_edge": "ビューの端",
|
||||
"prefs.dialogs_left_column": "左の列",
|
||||
"prefs.dialogs_note": "コマンドダイアログを開く場所:ビューの端にドッキングするか、左の列でブラウザーと履歴の代わりに表示します。ダイアログを閉じるとブラウザーと履歴は元どおりに戻ります。",
|
||||
"prefs.display": "表示",
|
||||
"prefs.edges": "エッジと陰影",
|
||||
"prefs.extend": "拡張",
|
||||
@@ -1467,6 +1512,12 @@
|
||||
"prefs.graphics_note": "速度と滑らかさのバランスを調整します。各選択肢の効果をサンプルで確認できます。",
|
||||
"prefs.graphics_presets_note": "プリセットは以下の設定をまとめて変更します。",
|
||||
"prefs.history": "履歴",
|
||||
"prefs.history_origin_bodies": "原点とボディを先頭に表示",
|
||||
"prefs.history_origin_bodies_note": "左側またはブラウザー下の履歴の先頭に、アクティブなコンポーネントのボディフォルダーと原点を、ブラウザーと同じ表示切り替えとメニュー付きで表示します。下部の履歴は変わりません。",
|
||||
"prefs.history_sketches": "スケッチ",
|
||||
"prefs.history_sketches_in_order": "作成順",
|
||||
"prefs.history_sketches_note": "スケッチ:「フィーチャーの下」では、左側の履歴に名前が表示される幅があるとき、スケッチをそれから作成した最初のフィーチャーの下に 1 段字下げして表示します。下部のタイムラインは常に作成順です。",
|
||||
"prefs.history_sketches_under_feature": "フィーチャーの下",
|
||||
"prefs.hold_stop_snapping": "押している間スナップを解除",
|
||||
"prefs.icons_only": "アイコンのみ",
|
||||
"prefs.imported_file": "読み込んだファイル",
|
||||
@@ -1498,6 +1549,8 @@
|
||||
"prefs.opaque": "不透明",
|
||||
"prefs.orbit_snap": "回転中にShiftを押すと軸にスナップします。",
|
||||
"prefs.orientation": "方向",
|
||||
"prefs.origin_plane_names": "原点平面の名前",
|
||||
"prefs.origin_plane_names_note": "ブラウザー、ダイアログ、一覧に表示される名前です。{top} は XY、{front} は XZ、{right} は YZ です (Z が上)。コマンド、スクリプト、保存されたデザインでは XY、XZ、YZ のままです。",
|
||||
"prefs.overall_speed": "全体の速度",
|
||||
"prefs.placement": "配置",
|
||||
"prefs.prefer_free_sketch_points": "スケッチ点が重なったときは移動可能な点を優先する",
|
||||
@@ -1538,11 +1591,18 @@
|
||||
"prefs.supersampling_brief": "大きく描画して縮小するため、非常に鮮明になりますが負荷も増えます。",
|
||||
"prefs.tab_accent_note": "アクセント色はアクティブなタブに従います",
|
||||
"prefs.theme_file": "テーマファイル",
|
||||
"prefs.theme_follow": "テーマファイルに従う",
|
||||
"prefs.theme_follow_error": "適用できません: {error}。最後に正常に適用されたテーマを維持します。",
|
||||
"prefs.theme_follow_launch": "今回の起動時のみ有効です (--theme-file)。別のツールがファイルを書き換えるたびに再読み込みします。",
|
||||
"prefs.theme_follow_note": "別のツールがファイルを書き換えるたびに再読み込みします。テーマを選ぶと追従を停止します。",
|
||||
"prefs.theme_follow_off": "オフ",
|
||||
"prefs.theme_follow_stop": "追従を停止",
|
||||
"prefs.timeline_half_hour": "−30 分",
|
||||
"prefs.timeline_now": "現在",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
"prefs.toggle_item": "項目を追加、または選択から外す",
|
||||
"prefs.toolbar": "ツールバー",
|
||||
"prefs.top": "上",
|
||||
"prefs.translucent": "半透明",
|
||||
"prefs.under_browser": "ブラウザー下",
|
||||
"prefs.under_cursor": "カーソル下",
|
||||
@@ -1601,6 +1661,7 @@
|
||||
"render.aging_target_search": "ボディ名を絞り込む",
|
||||
"render.aging_upward": "上向き面への堆積",
|
||||
"render.all_controls_help": "現在の全コントロールをまとめて表示します。各ページでは同じ要求を保ちながら項目別に編集できます。",
|
||||
"render.all_shots_label": "すべてのショット",
|
||||
"render.appearance_physics_separate": "外観の設定では、密度、熱特性などの工学的な物性値は割り当てられません。",
|
||||
"render.availability_native": "ネイティブ構成。適用前に確認してください",
|
||||
"render.availability_projection": "対応する部分適用。範囲と省略項目を確認してください",
|
||||
@@ -1755,10 +1816,13 @@
|
||||
"render.effects_reset_lens": "レンズ効果をリセット",
|
||||
"render.effects_seed": "パターンシード",
|
||||
"render.export_display": "書き出し:表示PNG",
|
||||
"render.export_image_label": "画像を書き出す",
|
||||
"render.export_linear": "書き出し:生の線形EXR",
|
||||
"render.exr_pending": "GPUでは線形EXRを保持できます。圧縮、複数レイヤー、補助パスは未実装です。",
|
||||
"render.film_grain": "写真粒子",
|
||||
"render.fit": "製品を画面に合わせる",
|
||||
"render.fixed_camera": "カメラ",
|
||||
"render.fixed_world": "ワールド",
|
||||
"render.flare_ghosts": "光源ごとのゴースト環",
|
||||
"render.flare_halo": "フレアのハロー",
|
||||
"render.flare_streak": "アナモルフィック風の筋",
|
||||
@@ -1785,6 +1849,12 @@
|
||||
"render.hdr_primaries_srgb": "原色:sRGB/D65",
|
||||
"render.hdr_primaries_undeclared": "原色が宣言されていません。レンダラーの色要件を確認してください。",
|
||||
"render.hdr_resource_missing": "保存されたHDRリソースがこのデザインにありません。",
|
||||
"render.heading_batch": "バッチ",
|
||||
"render.heading_frame": "フレーム",
|
||||
"render.heading_lens": "レンズ",
|
||||
"render.heading_results": "結果",
|
||||
"render.heading_shots": "ショット",
|
||||
"render.hide_shots_label": "ショットストリップを非表示",
|
||||
"render.image_advanced": "GPU 詳細設定",
|
||||
"render.image_cancelled": "レンダリングをキャンセルしました",
|
||||
"render.image_cancelling": "キャンセル中",
|
||||
@@ -1816,6 +1886,7 @@
|
||||
"render.image_width": "幅",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspect_scene": "記録するシーンの概要を更新",
|
||||
"render.inspector": "インスペクター",
|
||||
"render.keep_editing": "編集を続ける",
|
||||
"render.layer_down": "下へ",
|
||||
"render.layer_enabled": "層を有効にする",
|
||||
@@ -1884,6 +1955,8 @@
|
||||
"render.library_unfavorite": "お気に入りから削除",
|
||||
"render.library_uniform_ack": "空間変化や高度な効果のない均一近似を使用",
|
||||
"render.library_usable": "実行可能な部分適用",
|
||||
"render.light_anchor_pending": "ライトの座標系の変更はまだサポートされていません。",
|
||||
"render.lights_fixed_to": "ライトの固定先",
|
||||
"render.linear_help": "ノイズ除去、露出、トーンマッピング、フィルター、背景処理より前の32ビット浮動小数点RGBAを保持します。線形sRGB/D65で、被覆率を乗算した値です。追加メモリを明示的に見積もります。圧縮や追加パスはありません。",
|
||||
"render.linear_retain": "生の線形EXRを保持",
|
||||
"render.linear_unavailable": "選択した完了画像にEXRは保持されていません。レンダー前に保持を有効にしてください。古いPNGから生の放射輝度は復元できません。",
|
||||
@@ -1969,6 +2042,7 @@
|
||||
"render.output_over_budget": "要求画像が選択したリソース枠を超えています。対応するサイズかプロファイルを明示的に選択してください。自動的な品質低下は行いません。",
|
||||
"render.output_ratio_refused": "連動する寸法が方式の上限を超えます。以前のサイズを維持します。縦横比固定を解除するか、小さい値を選択してください。",
|
||||
"render.output_swap_orientation": "幅と高さを交換",
|
||||
"render.output_tools_inspector": "サイズと形式は出力インスペクターで編集してください。",
|
||||
"render.page_aging": "エイジング・付着物",
|
||||
"render.page_all": "全コントロール",
|
||||
"render.page_appearance": "外観",
|
||||
@@ -1980,6 +2054,7 @@
|
||||
"render.page_lighting": "照明",
|
||||
"render.page_output": "出力",
|
||||
"render.page_scene": "シーン",
|
||||
"render.paint_label": "ペイント",
|
||||
"render.passive_stage": "Render-only stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "透視投影カメラ",
|
||||
@@ -1995,6 +2070,10 @@
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.pick_component": "コンポーネント",
|
||||
"render.pick_label": "選択",
|
||||
"render.pick_up_label": "取得",
|
||||
"render.pick_waiting": "製品の選択はまだサポートされていません。",
|
||||
"render.post_contrast": "コントラスト",
|
||||
"render.post_gain_b": "青ゲイン",
|
||||
"render.post_gain_g": "緑ゲイン",
|
||||
@@ -2007,6 +2086,7 @@
|
||||
"render.preview": "統合プレビュー",
|
||||
"render.preview_help": "ラスタシェーディングとブレンド透明度を使用します。屈折、HDRI、最終レンダリングはまだ利用できません。",
|
||||
"render.preview_image_settings_help": "ライブプレビューは固定のスタジオ照明を使用します。画像の露出と照明は、確認または開始時に画像ジョブへ適用されます。",
|
||||
"render.preview_lighting_help": "ライブプレビューは直接光のみを表示し、影は表示しません。",
|
||||
"render.preview_retry": "ライブプレビューを再試行",
|
||||
"render.preview_unavailable_help": "ライブプレビューは利用できません。保存設定と画像ジョブの操作は使用できます。シーンを変更するか明示的に再試行してください。拒否されたシーンを毎フレーム再構築しません。",
|
||||
"render.preview_upload": "ライブプレビューの頂点データ量",
|
||||
@@ -2020,8 +2100,10 @@
|
||||
"render.radial_distortion": "放射状歪み",
|
||||
"render.regrade_action": "生マスターを再調整(ノイズ除去なし)",
|
||||
"render.regrade_help": "選択した完了済み生マスターから、この表示設定で別の PNG を作成します。光線追跡、撮影サイズ・カメラ・照明の変更、EXR の上書きは行いません。ガイドを保持しないためノイズ除去は再適用しません。通常のジョブ操作で書き出せます。",
|
||||
"render.regrade_label": "再グレーディング",
|
||||
"render.reload_settings": "保存した設定を再読み込み",
|
||||
"render.replace_ground": "既存ステージの置換を確認",
|
||||
"render.replace_label": "置換",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "保存したカメラを復元",
|
||||
"render.result_actual_help": "画像の1ピクセルを画面の1ピクセルで表示します。",
|
||||
@@ -2067,6 +2149,7 @@
|
||||
"render.sampling_title": "適応・透過サンプリング",
|
||||
"render.save_continue": "保存して続行",
|
||||
"render.save_setup": "セットアップを保存",
|
||||
"render.save_shot": "ショットを保存",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
@@ -2086,6 +2169,9 @@
|
||||
"render.setup_runtime_unsupported": "このジョブにはマップまたはシーンのボディへの割り当てが含まれるため、全体を保存できません。移植可能な設定を保存する前に、一時入力を削除してください。",
|
||||
"render.setup_save_missing": "コマンド完了後に保存済みレンダリング設定を見つけられませんでした。",
|
||||
"render.sharpening": "ディテールのシャープ化",
|
||||
"render.shell_tab_appearance": "外観",
|
||||
"render.shell_tab_camera": "カメラ",
|
||||
"render.shell_tab_scene": "シーン",
|
||||
"render.shot_duplicate": "保存済みショットを複製",
|
||||
"render.shot_manager": "保存済みショット",
|
||||
"render.shot_new_name": "新しいショット名",
|
||||
@@ -2094,11 +2180,19 @@
|
||||
"render.shot_remove_title": "保存済みショットを削除しますか?",
|
||||
"render.shot_rename": "保存済みショットの名前を変更",
|
||||
"render.shot_saved_only": "先に現在の下書きを保存してください。複製と名前変更では正確な保存オプションとリソース参照を保持します。",
|
||||
"render.show_shots_label": "ショットストリップを表示",
|
||||
"render.sky_ground": "地面・線形RGB",
|
||||
"render.sky_horizon": "地平線・線形RGB",
|
||||
"render.sky_zenith": "天頂・線形RGB",
|
||||
"render.soft_focus": "ソフトフォーカス",
|
||||
"render.stage_frame": "構図",
|
||||
"render.stage_light": "照明",
|
||||
"render.stage_look": "外観",
|
||||
"render.stage_orthographic": "平行投影",
|
||||
"render.stage_output": "出力",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.stage_preview_note": "統合プレビュー · 直接光",
|
||||
"render.strip_label": "ストリップ",
|
||||
"render.studio_add_area": "エリアライトを追加",
|
||||
"render.studio_ambient": "一定の環境放射輝度",
|
||||
"render.studio_ambient_rgb": "一定の環境放射輝度(リニアRGB)",
|
||||
@@ -2155,6 +2249,12 @@
|
||||
"render.volume_max": "最大境界 · ワールド mm",
|
||||
"render.volume_min": "最小境界 · ワールド mm",
|
||||
"render.volume_title": "有限の均一ボリューム",
|
||||
"render.wait_batch": "未対応: 保存ショットのレンダーキュー",
|
||||
"render.wait_compare": "未対応: 保持された画像の比較",
|
||||
"render.wait_paint": "未対応: 製品の選択と外観のペイント",
|
||||
"render.wait_pick_up": "未対応: 製品の選択と外観の採取",
|
||||
"render.wait_replace": "未対応: 外観のすべての使用箇所の置換",
|
||||
"render.wait_solo": "未対応: ライトの表示とソロ操作",
|
||||
"sample.bracket.about": "2 mm の板金ルールによるベース フランジ、エッジ フランジ、ヘミング",
|
||||
"sample.bracket.name": "板金ブラケット",
|
||||
"sample.enclosure.about": "リップ、ねじボス、レスト、スナップ フィットを備えたシェル化した直方体",
|
||||
@@ -2246,6 +2346,7 @@
|
||||
"timeline.delete_after_marker_one": "履歴マーカー以降の 1 個のフィーチャーを削除",
|
||||
"timeline.delete_after_marker_other": "履歴マーカー以降の {count} 個のフィーチャーを削除",
|
||||
"timeline.delete_folders_tip": "フィーチャーと入れ子のフォルダーを履歴に残します",
|
||||
"timeline.delete_folders_with_features_tip": "フォルダーを、中のすべてのフィーチャーと入れ子のフォルダーごと削除します",
|
||||
"timeline.delete_many": "選択した {count} 個のフィーチャーを削除",
|
||||
"timeline.feature_error": "エラー: {message}",
|
||||
"timeline.feature_hint": "ダブルクリックで編集 · ドラッグで並べ替え · 右クリックでその他の操作",
|
||||
@@ -2255,6 +2356,7 @@
|
||||
"timeline.move_to_group": "フィーチャーをフォルダへ移動",
|
||||
"timeline.rename_group": "フィーチャーフォルダの名前を変更",
|
||||
"timeline.reorder_many": "フィーチャーの順序を変更",
|
||||
"timeline.suppress_folders_tip": "フォルダーと入れ子のフォルダー内のすべてのフィーチャーを抑制、または抑制を解除します",
|
||||
"timeline.ungroup": "フィーチャーフォルダを削除",
|
||||
"to the face": "面まで",
|
||||
"to the next face": "次の面まで",
|
||||
@@ -2265,7 +2367,11 @@
|
||||
"toolbar.render_camera": "カメラ",
|
||||
"toolbar.render_environment": "環境",
|
||||
"toolbar.render_lighting": "照明",
|
||||
"toolbar.render_lights": "ライト",
|
||||
"toolbar.render_result": "結果",
|
||||
"toolbar.render_scene": "シーン",
|
||||
"toolbar.render_stage": "ステージ",
|
||||
"toolbar.render_studio": "スタジオ",
|
||||
"trace.points": "経路上の {count} 点",
|
||||
"trace.stopped_by_contact": "サンプル {sample} で終了: {a} が {b} を通り抜けてしまいます",
|
||||
"trace.stopped_by_loop": "サンプル {sample} で終了: {joint} を通るループはこれ以上閉じられません",
|
||||
@@ -2444,6 +2550,7 @@
|
||||
"ui.agent_chat_import_failed": "{name}: インポートに失敗しました: {error}",
|
||||
"ui.agent_chat_intro": "普段使っているコーディングエージェント、または選んだモデルのエンドポイントとチャットできます。SolidCraft のツールで開いているデザインを操作し、変更はその場で表示され、メッセージごとに1回で元に戻せます。確認なしで許可する範囲は「環境設定 > AI」で設定します。",
|
||||
"ui.agent_chat_key_in_env": "キー設定済み",
|
||||
"ui.agent_chat_last_missing": "前回使用したエージェント ({agent}) は利用できなくなりました。エージェントを選んでから「再試行」を押してください。",
|
||||
"ui.agent_chat_left": "左",
|
||||
"ui.agent_chat_limit": "エージェントが1メッセージあたりの変更上限 {limit} に達しました。続けさせるには、もう一度メッセージを送ってください。",
|
||||
"ui.agent_chat_login_found": "ログイン情報あり",
|
||||
@@ -2477,7 +2584,7 @@
|
||||
"ui.agent_chat_pop_out": "独立したウィンドウで開く(別の画面に移動できます)",
|
||||
"ui.agent_chat_previous_picture": "前の画像",
|
||||
"ui.agent_chat_privacy": "あなたのアカウントで実行するエージェント以外には、何も送信されません。",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft はどこにも何も送信しません。あなたが実行するエージェントが、あなた自身のアカウントでそのサービスと通信します。SolidCraft がキーやパスワードを見たり保存したりすることはありません。",
|
||||
"ui.agent_chat_privacy_note": "チャット自体はどこにも何も送信しません。あなたが実行するエージェントが、あなた自身のアカウントでそのサービスと通信します。SolidCraft がキーやパスワードを見たり保存したりすることはありません。",
|
||||
"ui.agent_chat_provider_models": "{count} 個のモデル",
|
||||
"ui.agent_chat_provider_other": "その他",
|
||||
"ui.agent_chat_provider_tip": "隣の一覧にモデルを表示するプロバイダー。",
|
||||
@@ -2490,6 +2597,7 @@
|
||||
"ui.agent_chat_remove": "待機から削除",
|
||||
"ui.agent_chat_remove_file": "このメッセージから外す",
|
||||
"ui.agent_chat_remove_imported": "このメッセージから外します。パーツはデザインに残ります (元に戻すで削除できます)",
|
||||
"ui.agent_chat_retry": "再試行",
|
||||
"ui.agent_chat_right": "右",
|
||||
"ui.agent_chat_save": "保存",
|
||||
"ui.agent_chat_send": "送信",
|
||||
@@ -2502,6 +2610,7 @@
|
||||
"ui.agent_chat_state_auth": "サインインが必要",
|
||||
"ui.agent_chat_state_busy": "作業中…",
|
||||
"ui.agent_chat_state_exited": "エージェント停止",
|
||||
"ui.agent_chat_state_failed": "接続に失敗しました",
|
||||
"ui.agent_chat_state_off": "未接続",
|
||||
"ui.agent_chat_state_ready": "準備完了",
|
||||
"ui.agent_chat_state_starting": "起動中…",
|
||||
@@ -2695,6 +2804,7 @@
|
||||
"ui.command_done": "{command} 完了",
|
||||
"ui.command_palette_hint": "コマンドを入力(例: {example})— または S キーで検索",
|
||||
"ui.concentric": "同心",
|
||||
"ui.cone": "円錐",
|
||||
"ui.conic_curve": "円錐曲線",
|
||||
"ui.constant": "一定",
|
||||
"ui.constraints_conflict": "拘束が競合しています",
|
||||
@@ -2755,6 +2865,11 @@
|
||||
"ui.draft": "勾配",
|
||||
"ui.drawing": "図面",
|
||||
"ui.drill_point": "ドリル先端",
|
||||
"ui.easyprint_consent": "EasyPrint は Printables のブラウザ版スライサーです。モデルを EasyPrint で開くため、SolidCraft はモデルを Printables のサーバーにアップロードします。リンクは 30 分で期限切れになり、Printables にサインインしている必要があります。続行しますか?",
|
||||
"ui.easyprint_failed": "EasyPrint へのアップロードに失敗しました: {error}",
|
||||
"ui.easyprint_opened": "EasyPrint で開きました",
|
||||
"ui.easyprint_row": "EasyPrint(Printables、ブラウザ上)",
|
||||
"ui.easyprint_uploading": "Printables にアップロード中…",
|
||||
"ui.edit": "編集",
|
||||
"ui.editJointLimits": "ジョイント制限を編集",
|
||||
"ui.edit_section_analysis": "断面解析を編集",
|
||||
@@ -2799,6 +2914,7 @@
|
||||
"ui.fully_constrained": "完全拘束",
|
||||
"ui.function": "関数",
|
||||
"ui.general": "一般",
|
||||
"ui.gpu_memory_lowered": "グラフィックカードのメモリが不足しています。ビューは低い画質で描画されます。",
|
||||
"ui.graphics": "グラフィックス",
|
||||
"ui.graphics_custom": "カスタム",
|
||||
"ui.graphics_performance": "パフォーマンス",
|
||||
@@ -2817,6 +2933,7 @@
|
||||
"ui.heading_circular_pattern": "円形パターン",
|
||||
"ui.heading_coil": "コイル",
|
||||
"ui.heading_combine": "結合",
|
||||
"ui.heading_cone": "円錐",
|
||||
"ui.heading_configure": "構成",
|
||||
"ui.heading_constraints": "拘束",
|
||||
"ui.heading_construct": "構築",
|
||||
@@ -2897,6 +3014,7 @@
|
||||
"ui.history_names": "名前",
|
||||
"ui.history_play": "最後まで再生",
|
||||
"ui.history_show_names": "名前を表示",
|
||||
"ui.history_sketch_listed_under": "{feature} の下に表示",
|
||||
"ui.history_title": "履歴",
|
||||
"ui.history_toggle_names": "フィーチャー名を表示・非表示",
|
||||
"ui.hole": "穴",
|
||||
@@ -3067,6 +3185,7 @@
|
||||
"ui.render": "レンダリング",
|
||||
"ui.renderer": "レンダラー",
|
||||
"ui.repeat": "繰り返し",
|
||||
"ui.repeat_nothing": "まだ繰り返すものがありません。先にツールかダイアログを開始してください。",
|
||||
"ui.replace_with_link_done": "コピーはリンクされたデザインの配置になりました。",
|
||||
"ui.report_a_bug": "不具合を報告",
|
||||
"ui.reset": "リセット",
|
||||
@@ -3085,9 +3204,8 @@
|
||||
"ui.right": "右側面",
|
||||
"ui.save": "保存",
|
||||
"ui.save_as": "名前を付けて保存",
|
||||
"ui.save_mesh_no_slicer": "スライサーが見つかりません。「カスタム…」でスライサーのプログラムを選ぶか、「スライサーに送る」をオフにしてください",
|
||||
"ui.save_mesh_no_slicer_open": "スライサーが見つかりません。「カスタム…」でスライサーのプログラムを選んでください",
|
||||
"ui.save_mesh_pick_bodies": "保存するボディを選択してください",
|
||||
"ui.save_mesh_temp_failed": "{folder} を作成できません: {error}",
|
||||
"ui.saved_to": "保存しました: {path}",
|
||||
"ui.sbox_pin": "Sボックスの上部に固定",
|
||||
"ui.sbox_unpin": "固定を解除",
|
||||
@@ -3102,8 +3220,9 @@
|
||||
"ui.selection_shift_add_only": "Shift+クリックで追加のみ(解除なし)",
|
||||
"ui.selection_shift_add_only_tip": "オン: Shift は追加、Ctrl/Cmd はトグル。オフ(既定): Shift と Ctrl/Cmd の両方がトグル。",
|
||||
"ui.send": "送信",
|
||||
"ui.send_to_slicer": "スライサーに送る",
|
||||
"ui.send_to_slicer_unavailable": "「スライサーに送る」にはデスクトップアプリが必要です。ブラウザーではプログラムを起動できません",
|
||||
"ui.sent_to_slicer": "{slicer} に送信しました",
|
||||
"ui.sent_to_slicer_copy": "{slicer} に {file} として送信しました(元のファイルがまだ開かれているため)",
|
||||
"ui.sheet_gap": "ギャップ",
|
||||
"ui.shell": "シェル",
|
||||
"ui.shortcut_capture_add_key": "通常のキーを1つ追加してください。Escでキャンセルします。",
|
||||
@@ -3138,6 +3257,15 @@
|
||||
"ui.slice": "スライス",
|
||||
"ui.slicer": "スライサー",
|
||||
"ui.slicer_delete_tip": "{program}\nDelete キーでリストから削除",
|
||||
"ui.slicer_lost": "{slicer} は起動しましたが、ファイルを送るために再び見つけられませんでした。ファイルは {path} に保存されています。そこから開いてください。",
|
||||
"ui.slicer_no_file": "{slicer} は準備できましたが、送信するファイルがありません。",
|
||||
"ui.slicer_no_response": "{slicer} が時間内に応答しませんでした。ファイルは {path} に保存済みです。スライサーが起動したら、もう一度送ってください。",
|
||||
"ui.slicer_resend_hint": "もう一度送ると、スライサーで開いているファイルが置き換わります。",
|
||||
"ui.slicer_single_instance": "すでに起動しているスライサーでファイルを開く",
|
||||
"ui.slicer_single_instance_tip": "PrusaSlicer、SuperSlicer、Cura は、別のウィンドウを起動せず、開いているウィンドウでファイルを読み込みます。ほかのスライサーはそのまま起動します。PrusaSlicer 3.0 は常にこの動作です。ランチャーはほかの方法ではファイルを受け取れません。",
|
||||
"ui.slicer_starting": "{slicer} を起動しています…",
|
||||
"ui.slicer_still_starting": "まだ {slicer} の起動を待っています。ほかには何も送信していません。",
|
||||
"ui.slicer_stl_fallback": "3MF を書き込めなかったため、STL で送信しました。",
|
||||
"ui.slot": "スロット",
|
||||
"ui.smooth": "スムーズ",
|
||||
"ui.smooth_wheel_zoom": "滑らかなホイールズーム",
|
||||
@@ -3205,6 +3333,7 @@
|
||||
"ui.untitled": "無題",
|
||||
"ui.up_axis_note": "ビュー(軸ビュー、ホーム、正面視)で上向きにする軸を指定します。デザインデータ自体は変更されません。",
|
||||
"ui.updateToCurrentView": "現在のビューに更新",
|
||||
"ui.upload": "アップロード",
|
||||
"ui.vertical_constraint": "垂直拘束",
|
||||
"ui.view_centre": "ビュー中心",
|
||||
"ui.viewport_theme_follow": "テーマに従う",
|
||||
@@ -3279,5 +3408,6 @@
|
||||
"web.open_link": "リンク先のデザインを開きますか?",
|
||||
"web.open_link_confirm": "保存していない変更があります。リンク先のデザインを新しいタブで開きますか?",
|
||||
"↑ ↓ choose · Enter / Tab complete · Esc dismiss": "↑ ↓ 選択 · Enter / Tab 補完 · Esc 閉じる",
|
||||
"↑ ↓ choose · Enter applies what you typed · Esc dismiss": "↑ ↓ 選択 · Enter 入力どおりに適用 · Esc 閉じる"
|
||||
"↑ ↓ choose · Enter applies what you typed · Esc dismiss": "↑ ↓ 選択 · Enter 入力どおりに適用 · Esc 閉じる",
|
||||
"⌘Enter continues on GitHub.": "⌘EnterでGitHubに進みます。"
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
"Add Mid Radius": "중간 반지름 추가",
|
||||
"Add Row": "행 추가",
|
||||
"Add a tool": "도구 추가",
|
||||
"Add all bodies": "모든 바디 추가",
|
||||
"Add condition": "조건 추가",
|
||||
"Add or edit rule": "규칙 추가 또는 편집",
|
||||
"Add to New Folder": "새 폴더에 추가",
|
||||
"Add visible bodies": "보이는 바디 추가",
|
||||
"Advanced": "고급",
|
||||
"Against": "상대",
|
||||
"Alignment": "정렬",
|
||||
@@ -373,6 +375,7 @@
|
||||
"Remove this point": "이 점 제거",
|
||||
"Rename Feature": "피처 이름 바꾸기",
|
||||
"Rename Folder": "폴더 이름 바꾸기",
|
||||
"Render Stage": "렌더링 단계",
|
||||
"Replace existing library file": "기존 라이브러리 파일 바꾸기",
|
||||
"Report a bug — review a screenshot and open a GitHub draft": "버그 신고 — 스크린샷을 검토하고 GitHub 초안 열기",
|
||||
"Report text copied. Paste it into GitHub and submit your report there.": "보고서 텍스트를 복사했습니다. GitHub에 붙여넣고 그곳에서 보고서를 제출하세요.",
|
||||
@@ -598,6 +601,9 @@
|
||||
"cmd.appearance_assign": "외관",
|
||||
"cmd.appearance_library": "외관 라이브러리",
|
||||
"cmd.appearance_list": "외관 목록",
|
||||
"cmd.appearance_paint": "모양 칠하기",
|
||||
"cmd.appearance_pick_up": "모양 가져오기",
|
||||
"cmd.appearance_replace": "모양 바꾸기",
|
||||
"cmd.assembly_bom": "자재 명세서",
|
||||
"cmd.body_rename": "바디 이름 변경",
|
||||
"cmd.browser_group": "새 그룹",
|
||||
@@ -611,6 +617,7 @@
|
||||
"cmd.canvas_delete": "캔버스 삭제",
|
||||
"cmd.canvas_edit": "캔버스 편집",
|
||||
"cmd.canvas_insert": "캔버스",
|
||||
"cmd.canvas_to_sketch": "캔버스에서 스케치",
|
||||
"cmd.component_activate": "구성 요소 활성화",
|
||||
"cmd.component_break_link": "링크 끊기",
|
||||
"cmd.component_capture_position": "위치 캡처",
|
||||
@@ -676,6 +683,7 @@
|
||||
"cmd.document_metadata_set": "설계 속성 변경",
|
||||
"cmd.document_units": "설계 단위 변경",
|
||||
"cmd.edit_checkpoint": "체크포인트",
|
||||
"cmd.edit_repeat": "마지막 명령 반복",
|
||||
"cmd.edit_restore_checkpoint": "체크포인트 복원",
|
||||
"cmd.engine_commands": "명령 목록",
|
||||
"cmd.engine_describe": "명령 설명",
|
||||
@@ -688,6 +696,7 @@
|
||||
"cmd.file_export": "내보내기",
|
||||
"cmd.file_insert_mesh": "메쉬 삽입",
|
||||
"cmd.file_insert_step": "STEP 삽입",
|
||||
"cmd.file_open_in_easyprint": "EasyPrint로 열기",
|
||||
"cmd.file_save_mesh": "메쉬로 저장",
|
||||
"cmd.file_slicers": "설치된 슬라이서",
|
||||
"cmd.frame_member": "프레임 부재",
|
||||
@@ -780,9 +789,11 @@
|
||||
"cmd.plastic_rules": "플라스틱 규칙 목록",
|
||||
"cmd.plastic_snap_fit": "스냅핏",
|
||||
"cmd.render_backends": "렌더링 백엔드",
|
||||
"cmd.render_batch": "모든 샷 렌더링",
|
||||
"cmd.render_camera_fit": "렌더 대상 화면 맞춤",
|
||||
"cmd.render_camera_get": "렌더 카메라 확인",
|
||||
"cmd.render_cancel": "렌더링 취소",
|
||||
"cmd.render_compare": "이미지 비교",
|
||||
"cmd.render_export": "PNG 내보내기",
|
||||
"cmd.render_hdr_inspect": "HDR 소스 검사",
|
||||
"cmd.render_library_appearance_apply": "라이브러리 불투명 외관 적용",
|
||||
@@ -796,6 +807,7 @@
|
||||
"cmd.render_library_surface_prepare": "제작된 표면 맵 준비",
|
||||
"cmd.render_library_surface_unbind": "Remove Surface Binding",
|
||||
"cmd.render_library_targets": "렌더 리소스 대상 찾기",
|
||||
"cmd.render_lights_solo": "광원 단독 표시",
|
||||
"cmd.render_preflight": "렌더 요청 확인",
|
||||
"cmd.render_result_pin": "표시된 렌더 결과 유지",
|
||||
"cmd.render_scene": "렌더링 장면 검사",
|
||||
@@ -894,6 +906,7 @@
|
||||
"cmd.sketch_spline_fit_point": "맞춤점 스플라인",
|
||||
"cmd.sketch_spun_profile": "회전 프로파일",
|
||||
"cmd.sketch_toggle_driven": "종속 치수 전환",
|
||||
"cmd.sketch_transform": "변환",
|
||||
"cmd.sketch_trim_path": "경로를 따라 트림",
|
||||
"cmd.solid_align": "정렬",
|
||||
"cmd.solid_boundary_fill": "경계 채우기",
|
||||
@@ -946,6 +959,7 @@
|
||||
"cmd.view_normal_to": "선택 항목에 수직",
|
||||
"cmd.view_rename": "이름 있는 보기 이름 변경",
|
||||
"cmd.view_save": "새 이름 있는 보기",
|
||||
"cmd.view_shots_strip": "샷 스트립",
|
||||
"color.copy": "클릭하여 색상 값 복사",
|
||||
"color.edit": "클릭하여 색상 편집",
|
||||
"color.gamma": "색상 값을 0-255 감마 공간으로 표시 중",
|
||||
@@ -1133,6 +1147,8 @@
|
||||
"manage.material_hint": "바디를 선택하고 물리 재질을 지정하세요.",
|
||||
"manage.parameters_hint": "표현식과 단위를 편집하세요. Enter를 누르거나 필드를 벗어나면 변경 사항이 적용됩니다.",
|
||||
"manage.rules_hint": "편집할 규칙을 선택하거나 새 규칙을 만드세요. 확인하면 규칙이 저장됩니다.",
|
||||
"material.selection.choose": "재질 선택",
|
||||
"material.selection.mixed": "서로 다른 재질",
|
||||
"measure.at": "위치",
|
||||
"measure.item": "항목 {number}",
|
||||
"messages.ago_h": "{n}시간 전",
|
||||
@@ -1161,6 +1177,9 @@
|
||||
"nav.blender.help": "가운데 드래그는 회전, Shift+가운데 드래그는 이동, Ctrl+가운데 드래그는 확대/축소입니다. 오른쪽 드래그는 카메라에 영향을 주지 않습니다",
|
||||
"nav.free_orbit.help": "마우스와 3D 마우스로 롤을 유지하며 양 극점을 넘어 회전합니다. Shift 축 스냅은 비활성화됩니다.",
|
||||
"nav.free_orbit.label": "자유 회전",
|
||||
"nav.free_orbit.snap_help": "마우스와 3D 마우스로 양쪽 극점을 지나 회전할 수 있으며 롤 각도가 유지됩니다. 궤도 회전 드래그 중 Shift를 누르면 보기 방향과 롤 각도가 스냅됩니다.",
|
||||
"nav.free_orbit_upright.help": "마우스를 좌우로 드래그하면 모델이 월드의 수직 축을 중심으로 회전하고, 위아래로 드래그하면 제한 없이 극점을 넘어 기울어집니다.",
|
||||
"nav.free_orbit_upright.label": "수직 축을 중심으로 회전",
|
||||
"nav.fusion.help": "가운데 드래그는 이동, Shift+가운데 드래그는 회전, 오른쪽 드래그는 회전입니다",
|
||||
"nav.inventor.help": "가운데 드래그는 이동, Shift+가운데 드래그는 회전, Ctrl+가운데 드래그는 확대/축소, 오른쪽 드래그는 회전입니다",
|
||||
"nav.openscad.help": "빈 공간에서 왼쪽 드래그는 회전, Shift+왼쪽 드래그는 상자 선택, 스케치 형상 드래그는 편집입니다. 오른쪽 또는 가운데 드래그는 이동, Shift+오른쪽 또는 Shift+가운데 드래그는 확대/축소입니다",
|
||||
@@ -1219,6 +1238,11 @@
|
||||
"prefs.design": "설계 기본값",
|
||||
"prefs.design_note": "새 설계가 시작할 때의 설정입니다. 열려 있는 설계는 자체 설정을 유지합니다.",
|
||||
"prefs.devices": "3D 마우스",
|
||||
"prefs.dialog_buttons": "대화 상자 버튼",
|
||||
"prefs.dialogs": "대화 상자",
|
||||
"prefs.dialogs_edge": "뷰 가장자리",
|
||||
"prefs.dialogs_left_column": "왼쪽 열",
|
||||
"prefs.dialogs_note": "명령 대화 상자가 열리는 위치: 뷰 가장자리에 고정하거나, 왼쪽 열에서 브라우저와 이력 대신 표시합니다. 대화 상자를 닫으면 브라우저와 이력이 그대로 돌아옵니다.",
|
||||
"prefs.display": "표시",
|
||||
"prefs.edges": "모서리 및 음영",
|
||||
"prefs.extend": "확장",
|
||||
@@ -1237,6 +1261,8 @@
|
||||
"prefs.graphics_note": "속도와 부드러움 중에서 선택합니다. 각 선택의 효과가 샘플에 표시됩니다.",
|
||||
"prefs.graphics_presets_note": "프리셋은 아래의 선택 항목을 한 번에 설정합니다.",
|
||||
"prefs.history": "이력",
|
||||
"prefs.history_origin_bodies": "원점과 바디를 맨 위에 표시",
|
||||
"prefs.history_origin_bodies_note": "왼쪽 또는 브라우저 아래의 히스토리가 활성 구성 요소의 바디 폴더와 원점으로 시작하며, 브라우저처럼 표시 아이콘과 메뉴가 있습니다. 아래쪽 히스토리는 바뀌지 않습니다.",
|
||||
"prefs.hold_stop_snapping": "누르고 있으면 스냅 중지",
|
||||
"prefs.icons_only": "아이콘만",
|
||||
"prefs.imported_file": "가져온 파일",
|
||||
@@ -1264,6 +1290,8 @@
|
||||
"prefs.opaque": "불투명",
|
||||
"prefs.orbit_snap": "회전하는 동안 Shift를 누르면 축에 맞춰집니다.",
|
||||
"prefs.orientation": "방향",
|
||||
"prefs.origin_plane_names": "원점 평면 이름",
|
||||
"prefs.origin_plane_names_note": "브라우저, 대화 상자, 목록에 표시되는 이름입니다. {top}은 XY, {front}는 XZ, {right}는 YZ이며 Z가 위쪽입니다. 명령, 스크립트, 저장된 디자인은 XY, XZ, YZ를 유지합니다.",
|
||||
"prefs.overall_speed": "전체 속도",
|
||||
"prefs.preview_choices": "선택 항목 미리보기",
|
||||
"prefs.quality_default": "기본값",
|
||||
@@ -1297,11 +1325,18 @@
|
||||
"prefs.supersampling_brief": "뷰를 더 크게 그린 뒤 줄여서 필터링합니다. 매우 선명하지만 더 무겁습니다.",
|
||||
"prefs.tab_accent_note": "강조 색상이 활성 탭을 따라갑니다",
|
||||
"prefs.theme_file": "테마 파일",
|
||||
"prefs.theme_follow": "테마 파일 따르기",
|
||||
"prefs.theme_follow_error": "적용되지 않음: {error}. 마지막으로 적용된 정상 테마를 유지합니다.",
|
||||
"prefs.theme_follow_launch": "이번 실행에만 적용됩니다 (--theme-file). 다른 도구가 파일을 다시 쓸 때마다 다시 불러옵니다.",
|
||||
"prefs.theme_follow_note": "다른 도구가 파일을 다시 쓸 때마다 다시 불러옵니다. 테마를 선택하면 따르기를 중지합니다.",
|
||||
"prefs.theme_follow_off": "끄기",
|
||||
"prefs.theme_follow_stop": "따르기 중지",
|
||||
"prefs.timeline_half_hour": "−30분",
|
||||
"prefs.timeline_now": "지금",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
"prefs.toggle_item": "항목을 추가하거나 다시 제거",
|
||||
"prefs.toolbar": "도구 모음",
|
||||
"prefs.top": "위쪽",
|
||||
"prefs.translucent": "반투명",
|
||||
"prefs.under_browser": "브라우저 아래",
|
||||
"prefs.under_cursor": "커서 아래",
|
||||
@@ -1323,6 +1358,7 @@
|
||||
"recovery.min_ago": "{count}분 전",
|
||||
"recovery.never_saved": "저장된 적 없음",
|
||||
"render.add_ground": "Add fitted ground to setup",
|
||||
"render.all_shots_label": "모든 샷",
|
||||
"render.background": "장면 배경",
|
||||
"render.bloom_enable": "표시 블룸",
|
||||
"render.bloom_help": "양의 선형 하이라이트를 세 번의 정규화 필터로 확산하는 출력 전용 효과입니다. 반경은 출력 픽셀 단위이며 sRGB 전에 더합니다. 렌즈·볼륨·수렴 개선이 아니며 원본 EXR은 변하지 않습니다.",
|
||||
@@ -1342,8 +1378,17 @@
|
||||
"render.cpu_budget_studio": "스튜디오 (큰 이미지)",
|
||||
"render.cpu_budget_triangles": "삼각형 수 상한",
|
||||
"render.cpu_budget_workstation": "워크스테이션 (대규모 장면)",
|
||||
"render.export_image_label": "이미지 내보내기",
|
||||
"render.exr_pending": "GPU는 원본 선형 EXR을 보존할 수 있습니다. 압축, 다중 레이어 이미지 및 보조 렌더 패스는 아직 사용할 수 없습니다.",
|
||||
"render.fit": "제품에 맞추기",
|
||||
"render.fixed_camera": "카메라",
|
||||
"render.fixed_world": "월드",
|
||||
"render.heading_batch": "일괄 처리",
|
||||
"render.heading_frame": "프레임",
|
||||
"render.heading_lens": "렌즈",
|
||||
"render.heading_results": "결과",
|
||||
"render.heading_shots": "샷",
|
||||
"render.hide_shots_label": "샷 스트립 숨기기",
|
||||
"render.image_cancelled": "렌더링 취소됨",
|
||||
"render.image_cancelling": "취소 중",
|
||||
"render.image_completed": "이미지 내보내기 준비됨",
|
||||
@@ -1367,6 +1412,7 @@
|
||||
"render.image_use_largest": "이 비율에서 가장 큰 크기 사용:",
|
||||
"render.image_width": "너비",
|
||||
"render.include_rig_cards": "Include passive cards and flags",
|
||||
"render.inspector": "속성 검사기",
|
||||
"render.library_applied": "리소스 변환을 적용했습니다. 시작 전에 전체 렌더 요청을 확인하세요.",
|
||||
"render.library_apply_hdr": "이 HDR 환경과 함께 저장",
|
||||
"render.library_apply_maps": "제작된 GPU 표면 맵 사용",
|
||||
@@ -1402,6 +1448,8 @@
|
||||
"render.library_target": "대상 바디",
|
||||
"render.library_title": "렌더 리소스 라이브러리",
|
||||
"render.library_uniform_ack": "공간 변화나 고급 효과 없는 균일 근사 사용",
|
||||
"render.light_anchor_pending": "조명 좌표계 변경은 아직 지원되지 않습니다.",
|
||||
"render.lights_fixed_to": "조명 고정 기준",
|
||||
"render.material_color_replace": "기본 맵으로 바디 색상 교체",
|
||||
"render.material_limits": "최대 128개 바디 설정, 분리된 유리 32개, 코팅 64개, 텍스처 연결 128개. 같은 맵은 메모리를 공유하며 실제 장치 및 전체 메모리 제한은 유지됩니다.",
|
||||
"render.material_metallic_map": "금속성 맵 (선형)",
|
||||
@@ -1411,6 +1459,8 @@
|
||||
"render.opaque_image_summary": "미리보기 PNG · 불투명 PBR · 블렌딩 투명도",
|
||||
"render.opaque_preview_help": "불투명 PBR 및 단색 표시, 블렌딩 투명도를 지원합니다. 굴절, HDRI 및 최종 렌더링은 아직 지원하지 않습니다.",
|
||||
"render.output_format_status": "PNG는 완료된 표시 이미지 그대로입니다. 선택적 GPU EXR은 표시 필터 전 선형 FLOAT32 방사 휘도를 보존합니다. 미리보기 캐시나 다른 작업으로 바꾸어 내보내지 않습니다.",
|
||||
"render.output_tools_inspector": "출력 검사기에서 크기와 형식을 편집하세요.",
|
||||
"render.paint_label": "칠하기",
|
||||
"render.passive_stage": "Render-only stage",
|
||||
"render.passive_stage_help": "Finite passive panels belong only to rendered images. They do not add CAD bodies or mass. Placement is fixed after applying; intersecting product bounds refuse. CPU does not provide diffuse bounce lighting.",
|
||||
"render.perspective": "원근 카메라",
|
||||
@@ -1423,9 +1473,16 @@
|
||||
"render.physical_prepare_plan": "Prepare creation plan (does not apply)",
|
||||
"render.physical_separate": "Appearance is not material identification. These are sourced references, not certified effective properties. Existing mass, engineering materials and optics are unchanged.",
|
||||
"render.physical_unknown": "No numerical candidate is established. Grade, formulation or construction must be specified; unknown is not zero.",
|
||||
"render.pick_component": "구성요소",
|
||||
"render.pick_label": "선택",
|
||||
"render.pick_up_label": "가져오기",
|
||||
"render.pick_waiting": "제품 선택은 아직 지원되지 않습니다.",
|
||||
"render.preview": "통합 미리보기",
|
||||
"render.preview_help": "래스터 셰이딩과 블렌딩 투명도를 사용합니다. 굴절, HDRI 및 최종 렌더링은 아직 지원하지 않습니다.",
|
||||
"render.preview_lighting_help": "실시간 미리 보기에는 직접 조명만 표시되며 그림자는 표시되지 않습니다.",
|
||||
"render.regrade_label": "색상 재조정",
|
||||
"render.reload_settings": "저장된 설정 다시 불러오기",
|
||||
"render.replace_label": "바꾸기",
|
||||
"render.replace_saved_surface": "Replace an existing saved binding for this target",
|
||||
"render.restore_camera": "저장된 카메라 복원",
|
||||
"render.result_reduced_display": "표시 미리보기를 뷰포트 장치 또는 캐시 제한에 맞춰 축소했습니다. 보관된 PNG와 내보내기는 전체 해상도를 유지합니다. 이 축소 보기에서는 원본 100% 검사가 불가능합니다.",
|
||||
@@ -1452,15 +1509,33 @@
|
||||
"render.ribbon_studios_help": "구현된 스튜디오를 찾아보고 적용 전에 교체 항목을 검토합니다. 개념 장면은 구분됩니다.",
|
||||
"render.ribbon_surface_maps": "표면 맵",
|
||||
"render.save_setup": "설정 저장",
|
||||
"render.save_shot": "샷 저장",
|
||||
"render.saved_maps_runtime_conflict": "Saved surface bindings cannot be mixed with temporary optical overrides or an unsaved HDR. Save the HDR or remove the temporary inputs explicitly.",
|
||||
"render.saved_surface_remove": "Remove saved binding",
|
||||
"render.saved_surfaces": "Saved surface bindings",
|
||||
"render.saved_surfaces_help": "Pinned built-in maps follow the selected occurrence in local millimeters. A replaced or missing target is an error, never an automatic reassignment.",
|
||||
"render.setup_name": "설정 이름",
|
||||
"render.shell_tab_appearance": "모양",
|
||||
"render.shell_tab_camera": "카메라",
|
||||
"render.shell_tab_scene": "장면",
|
||||
"render.show_shots_label": "샷 스트립 표시",
|
||||
"render.stage_frame": "구도",
|
||||
"render.stage_light": "조명",
|
||||
"render.stage_look": "외관",
|
||||
"render.stage_orthographic": "직교 투영",
|
||||
"render.stage_output": "출력",
|
||||
"render.stage_panel_count": "Saved panels",
|
||||
"render.stage_preview_note": "통합 미리 보기 · 직접광",
|
||||
"render.strip_label": "스트립",
|
||||
"render.unavailable_preview": "이 설정은 사용할 수 없는 미리보기 프로필을 요청합니다.",
|
||||
"render.unsaved": "저장하지 않은 미리보기 변경 사항",
|
||||
"render.use_preview": "통합 미리보기 사용",
|
||||
"render.wait_batch": "아직 지원되지 않음: 저장된 샷 렌더 대기열",
|
||||
"render.wait_compare": "아직 지원되지 않음: 보관된 이미지 비교",
|
||||
"render.wait_paint": "아직 지원되지 않음: 제품 선택 및 모양 페인팅",
|
||||
"render.wait_pick_up": "아직 지원되지 않음: 제품 선택 및 모양 샘플링",
|
||||
"render.wait_replace": "아직 지원되지 않음: 모양이 사용된 모든 곳 바꾸기",
|
||||
"render.wait_solo": "아직 지원되지 않음: 조명 표시 및 단독 표시 제어",
|
||||
"sample.bracket.about": "2 mm 판금 규칙을 적용한 베이스 플랜지, 에지 플랜지, 헴",
|
||||
"sample.bracket.name": "판금 브래킷",
|
||||
"sample.enclosure.about": "리프, 나사 보스, 레스트, 스냅핏이 있는 쉘 처리된 박스",
|
||||
@@ -1550,7 +1625,11 @@
|
||||
"toolbar.render_camera": "카메라",
|
||||
"toolbar.render_environment": "환경",
|
||||
"toolbar.render_lighting": "조명",
|
||||
"toolbar.render_lights": "조명",
|
||||
"toolbar.render_result": "결과",
|
||||
"toolbar.render_scene": "장면",
|
||||
"toolbar.render_stage": "스테이지",
|
||||
"toolbar.render_studio": "스튜디오",
|
||||
"trace.points": "경로를 따라 {count}개 점",
|
||||
"trace.stopped_by_contact": "샘플 {sample}에서 끝남: {a}이(가) {b}을(를) 통과합니다",
|
||||
"trace.stopped_by_loop": "샘플 {sample}에서 끝남: {joint}을(를) 지나는 루프를 더 이상 닫을 수 없습니다",
|
||||
@@ -1748,7 +1827,7 @@
|
||||
"ui.agent_chat_pop_out": "다른 화면으로 옮길 수 있는 별도 창으로 열기",
|
||||
"ui.agent_chat_previous_picture": "이전 이미지",
|
||||
"ui.agent_chat_privacy": "사용자의 계정으로 실행하는 에이전트 외에는 아무 데도 전송되지 않습니다.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft는 아무것도 어디로도 보내지 않습니다. 실행한 에이전트가 사용자의 계정으로 자신의 서비스와 통신합니다. SolidCraft는 키나 비밀번호를 보거나 저장하지 않습니다.",
|
||||
"ui.agent_chat_privacy_note": "채팅 자체는 아무것도 어디로도 보내지 않습니다. 실행한 에이전트가 사용자의 계정으로 자신의 서비스와 통신합니다. SolidCraft는 키나 비밀번호를 보거나 저장하지 않습니다.",
|
||||
"ui.agent_chat_queue": "대기열",
|
||||
"ui.agent_chat_queue_full": "대기 중인 메시지가 너무 많습니다. 하나를 제거하거나 에이전트를 기다리세요.",
|
||||
"ui.agent_chat_queued": "대기 중",
|
||||
@@ -1935,6 +2014,7 @@
|
||||
"ui.command_done": "{command} 완료",
|
||||
"ui.command_palette_hint": "명령 입력(예: {example}) — 또는 S 키를 눌러 검색",
|
||||
"ui.concentric": "동심",
|
||||
"ui.cone": "원뿔",
|
||||
"ui.conic_curve": "원뿔 곡선",
|
||||
"ui.constant": "상수",
|
||||
"ui.constraints_conflict": "구속 조건 충돌",
|
||||
@@ -1993,6 +2073,11 @@
|
||||
"ui.draft": "구배",
|
||||
"ui.drawing": "도면",
|
||||
"ui.drill_point": "드릴 선단",
|
||||
"ui.easyprint_consent": "EasyPrint는 Printables의 브라우저용 슬라이서입니다. 모델을 그곳에서 열기 위해 SolidCraft가 모델을 Printables 서버에 업로드합니다. 링크는 30분 후 만료되며 Printables에 로그인되어 있어야 합니다. 계속할까요?",
|
||||
"ui.easyprint_failed": "EasyPrint 업로드 실패: {error}",
|
||||
"ui.easyprint_opened": "EasyPrint에서 열었습니다",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, 브라우저)",
|
||||
"ui.easyprint_uploading": "Printables에 업로드하는 중…",
|
||||
"ui.edit": "편집",
|
||||
"ui.editJointLimits": "조인트 제한 편집",
|
||||
"ui.edit_section_analysis": "단면 분석 편집",
|
||||
@@ -2049,6 +2134,7 @@
|
||||
"ui.heading_circular_pattern": "원형 패턴",
|
||||
"ui.heading_coil": "코일",
|
||||
"ui.heading_combine": "결합",
|
||||
"ui.heading_cone": "원뿔",
|
||||
"ui.heading_configure": "구성",
|
||||
"ui.heading_constraints": "구속 조건",
|
||||
"ui.heading_construct": "구성",
|
||||
@@ -2275,6 +2361,7 @@
|
||||
"ui.render": "렌더",
|
||||
"ui.renderer": "렌더러",
|
||||
"ui.repeat": "반복",
|
||||
"ui.repeat_nothing": "아직 반복할 것이 없습니다. 먼저 도구나 대화 상자를 시작하세요.",
|
||||
"ui.report_a_bug": "버그 신고",
|
||||
"ui.reset": "재설정",
|
||||
"ui.reset_all": "모두 재설정",
|
||||
@@ -2292,9 +2379,7 @@
|
||||
"ui.right": "우측면",
|
||||
"ui.save": "저장",
|
||||
"ui.save_as": "다른 이름으로 저장",
|
||||
"ui.save_mesh_no_slicer": "슬라이서를 찾을 수 없습니다. '사용자 지정…'에서 슬라이서 프로그램을 선택하거나 '슬라이서로 보내기'를 끄세요",
|
||||
"ui.save_mesh_pick_bodies": "저장할 바디를 선택하세요",
|
||||
"ui.save_mesh_temp_failed": "{folder}을(를) 만들 수 없습니다: {error}",
|
||||
"ui.saved_to": "저장됨: {path}",
|
||||
"ui.sbox_pin": "S 상자 맨 위에 고정",
|
||||
"ui.sbox_unpin": "고정 해제",
|
||||
@@ -2309,7 +2394,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+클릭은 추가만 함",
|
||||
"ui.selection_shift_add_only_tip": "켬: Shift는 항목을 추가하고 Ctrl/Cmd는 토글합니다. 끔(기본값): Shift와 Ctrl/Cmd 모두 토글합니다.",
|
||||
"ui.send": "보내기",
|
||||
"ui.send_to_slicer": "슬라이서로 보내기",
|
||||
"ui.sent_to_slicer": "{slicer}(으)로 보냈습니다",
|
||||
"ui.sheet_gap": "틈",
|
||||
"ui.shell": "쉘",
|
||||
@@ -2407,6 +2491,7 @@
|
||||
"ui.untitled": "제목 없음",
|
||||
"ui.up_axis_note": "뷰(축 뷰, 홈, 보기)에서 위쪽을 가리키는 축입니다. 디자인은 변경되지 않습니다.",
|
||||
"ui.updateToCurrentView": "현재 보기로 업데이트",
|
||||
"ui.upload": "업로드",
|
||||
"ui.view_centre": "뷰 중심",
|
||||
"ui.viewport_theme_follow": "테마 따르기",
|
||||
"ui.visual_shaded_hidden_edges": "음영 처리 및 숨겨진 모서리",
|
||||
|
||||
@@ -457,6 +457,7 @@
|
||||
"cmd.canvas_delete": "Padam Kanvas",
|
||||
"cmd.canvas_edit": "Sunting Kanvas",
|
||||
"cmd.canvas_insert": "Kanvas",
|
||||
"cmd.canvas_to_sketch": "Kanvas ke Lakaran",
|
||||
"cmd.component_activate": "Aktifkan Komponen",
|
||||
"cmd.component_break_link": "Putuskan Pautan",
|
||||
"cmd.component_capture_position": "Rakam Kedudukan",
|
||||
@@ -534,6 +535,7 @@
|
||||
"cmd.file_export": "Eksport",
|
||||
"cmd.file_insert_mesh": "Sisip Mesh",
|
||||
"cmd.file_insert_step": "Sisip STEP",
|
||||
"cmd.file_open_in_easyprint": "Buka dengan EasyPrint",
|
||||
"cmd.file_save_mesh": "Simpan sebagai Mesh",
|
||||
"cmd.file_slicers": "Penghiris Terpasang",
|
||||
"cmd.frame_member": "Anggota Rangka",
|
||||
@@ -1001,6 +1003,12 @@
|
||||
"pick one or two vertices, edges or faces": "pilih satu atau dua bucu, tepi atau muka",
|
||||
"prefs.cpu": "CPU (perisian)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Ikut fail tema",
|
||||
"prefs.theme_follow_error": "Tidak digunakan: {error}. Tema sah terakhir kekal aktif.",
|
||||
"prefs.theme_follow_launch": "Diikuti untuk sesi ini sahaja (--theme-file); dimuat semula setiap kali alat lain menulis semula fail.",
|
||||
"prefs.theme_follow_note": "Dimuat semula setiap kali alat lain menulis semula fail. Memilih tema menghentikan ikutan.",
|
||||
"prefs.theme_follow_off": "Mati",
|
||||
"prefs.theme_follow_stop": "Berhenti mengikuti",
|
||||
"properties.title": "Sifat: {name}",
|
||||
"recovery.days_ago": "{count} hari lalu",
|
||||
"recovery.detail": "{file} · {features} ciri · disimpan automatik {when}",
|
||||
@@ -1326,7 +1334,7 @@
|
||||
"ui.agent_chat_pop_out": "Buka dalam tetingkap sendiri, yang boleh dialihkan ke skrin lain",
|
||||
"ui.agent_chat_previous_picture": "Gambar sebelumnya",
|
||||
"ui.agent_chat_privacy": "Data hanya dihantar kepada ejen yang anda jalankan, melalui akaun anda sendiri.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft tidak menghantar data. Ejen berhubung dengan perkhidmatannya melalui akaun anda. SolidCraft tidak melihat atau menyimpan kunci atau kata laluan.",
|
||||
"ui.agent_chat_privacy_note": "Sembang tidak menghantar data dengan sendirinya. Ejen berhubung dengan perkhidmatannya melalui akaun anda. SolidCraft tidak melihat atau menyimpan kunci atau kata laluan.",
|
||||
"ui.agent_chat_queue": "Hantar Nanti",
|
||||
"ui.agent_chat_queue_full": "Terlalu banyak mesej menunggu: buang satu atau tunggu ejen selesai.",
|
||||
"ui.agent_chat_queued": "Menunggu",
|
||||
@@ -1511,6 +1519,7 @@
|
||||
"ui.command_done": "{command} selesai",
|
||||
"ui.command_palette_hint": "Taip arahan, cth. {example} — atau tekan S untuk mencari",
|
||||
"ui.concentric": "Sepusat",
|
||||
"ui.cone": "Kon",
|
||||
"ui.conic_curve": "Lengkung Kon",
|
||||
"ui.constant": "Malar",
|
||||
"ui.constraints_conflict": "Kekangan bercanggah",
|
||||
@@ -1569,6 +1578,11 @@
|
||||
"ui.draft": "Sudut Draf",
|
||||
"ui.drawing": "Lukisan",
|
||||
"ui.drill_point": "Hujung Gerudi",
|
||||
"ui.easyprint_consent": "EasyPrint ialah slicer Printables dalam pelayar. Untuk membuka model di sana, SolidCraft memuat naiknya ke pelayan Printables. Pautan tamat tempoh selepas 30 minit, dan anda perlu log masuk ke Printables. Teruskan?",
|
||||
"ui.easyprint_failed": "Muat naik ke EasyPrint gagal: {error}",
|
||||
"ui.easyprint_opened": "Dibuka dalam EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, dalam pelayar)",
|
||||
"ui.easyprint_uploading": "Memuat naik ke Printables…",
|
||||
"ui.edit": "Sunting",
|
||||
"ui.editJointLimits": "Sunting Had Sendi",
|
||||
"ui.edit_section_analysis": "Sunting Analisis Keratan",
|
||||
@@ -1625,6 +1639,7 @@
|
||||
"ui.heading_circular_pattern": "CORAK MEMBULAT",
|
||||
"ui.heading_coil": "GEGELUNG",
|
||||
"ui.heading_combine": "GABUNG",
|
||||
"ui.heading_cone": "KON",
|
||||
"ui.heading_configure": "KONFIGURASI",
|
||||
"ui.heading_constraints": "KEKANGAN",
|
||||
"ui.heading_construct": "BINA",
|
||||
@@ -1860,9 +1875,7 @@
|
||||
"ui.right": "Kanan",
|
||||
"ui.save": "Simpan",
|
||||
"ui.save_as": "Simpan Sebagai",
|
||||
"ui.save_mesh_no_slicer": "Tiada penghiris: pilih program melalui Tersuai… atau matikan Hantar ke penghiris",
|
||||
"ui.save_mesh_pick_bodies": "Pilih jasad untuk disimpan",
|
||||
"ui.save_mesh_temp_failed": "Tidak dapat mencipta {folder}: {error}",
|
||||
"ui.saved_to": "{path} disimpan",
|
||||
"ui.sbox_pin": "Semat di atas kotak S",
|
||||
"ui.sbox_unpin": "Nyahsemat",
|
||||
@@ -1877,7 +1890,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+klik menambah tanpa membuang",
|
||||
"ui.selection_shift_add_only_tip": "Hidup: Shift menambah item, Ctrl/Cmd menogol. Mati (lalai): Shift dan Ctrl/Cmd kedua-duanya menogol.",
|
||||
"ui.send": "Hantar",
|
||||
"ui.send_to_slicer": "Hantar ke penghiris",
|
||||
"ui.sent_to_slicer": "Dihantar ke {slicer}",
|
||||
"ui.sheet_gap": "Jarak",
|
||||
"ui.shell": "Ronggakan",
|
||||
@@ -1969,6 +1981,7 @@
|
||||
"ui.untitled": "Tanpa Tajuk",
|
||||
"ui.up_axis_note": "Paksi yang menghala ke atas dalam pandangan paksi, Utama dan Pandang Tepat. Reka bentuk tidak berubah.",
|
||||
"ui.updateToCurrentView": "Kemas Kini Pandangan Semasa",
|
||||
"ui.upload": "Muat naik",
|
||||
"ui.view_centre": "Pusat pandangan",
|
||||
"ui.visual_shaded_hidden_edges": "Berlorek dengan tepi tersembunyi",
|
||||
"ui.visual_shaded_with_edges": "Berlorek dengan tepi",
|
||||
|
||||
@@ -1270,6 +1270,12 @@
|
||||
"prefs.supersampling_brief": "Tegner visningen større og skalerer den ned: svært skarpt, og mer krevende.",
|
||||
"prefs.tab_accent_note": "Aksentfargen følger den aktive fanen",
|
||||
"prefs.theme_file": "temafil",
|
||||
"prefs.theme_follow": "Følg en temafil",
|
||||
"prefs.theme_follow_error": "Ikke brukt: {error}. Det siste gyldige temaet forblir aktivt.",
|
||||
"prefs.theme_follow_launch": "Følges bare denne kjøringen (--theme-file); lastes inn på nytt når et annet verktøy skriver om filen.",
|
||||
"prefs.theme_follow_note": "Lastes inn på nytt når et annet verktøy skriver om filen. Valg av et tema stopper dette.",
|
||||
"prefs.theme_follow_off": "Av",
|
||||
"prefs.theme_follow_stop": "Slutt å følge",
|
||||
"prefs.timeline_half_hour": "−30 min",
|
||||
"prefs.timeline_now": "nå",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
@@ -2066,9 +2072,7 @@
|
||||
"ui.right": "Høyre",
|
||||
"ui.save": "Lagre",
|
||||
"ui.save_as": "Lagre som",
|
||||
"ui.save_mesh_no_slicer": "Ingen slicer funnet: velg Egendefinert… og velg slicer-programmet ditt, eller slå av Send til slicer",
|
||||
"ui.save_mesh_pick_bodies": "Velg kroppene som skal lagres",
|
||||
"ui.save_mesh_temp_failed": "Kunne ikke lage {folder}: {error}",
|
||||
"ui.saved_to": "Lagret {path}",
|
||||
"ui.sbox_pin": "Fest øverst i S-boksen",
|
||||
"ui.sbox_unpin": "Løsne",
|
||||
@@ -2083,7 +2087,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+klikk legger til uten å fjerne",
|
||||
"ui.selection_shift_add_only_tip": "På: Shift legger til elementer, Ctrl/Cmd veksler. Av (standard): Shift og Ctrl/Cmd veksler begge.",
|
||||
"ui.send": "Send",
|
||||
"ui.send_to_slicer": "Send til slicer",
|
||||
"ui.sent_to_slicer": "Sendt til {slicer}",
|
||||
"ui.sheet_gap": "Mellomrom",
|
||||
"ui.shell": "Skall",
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
"cmd.canvas_delete": "Canvas verwijderen",
|
||||
"cmd.canvas_edit": "Canvas bewerken",
|
||||
"cmd.canvas_insert": "Canvas",
|
||||
"cmd.canvas_to_sketch": "Canvas naar schets",
|
||||
"cmd.component_activate": "Component activeren",
|
||||
"cmd.component_break_link": "Koppeling verbreken",
|
||||
"cmd.component_capture_position": "Positie vastleggen",
|
||||
@@ -533,6 +534,7 @@
|
||||
"cmd.file_export": "Exporteren",
|
||||
"cmd.file_insert_mesh": "Mesh invoegen",
|
||||
"cmd.file_insert_step": "STEP invoegen",
|
||||
"cmd.file_open_in_easyprint": "Openen met EasyPrint",
|
||||
"cmd.file_save_mesh": "Opslaan als mesh",
|
||||
"cmd.file_slicers": "Geïnstalleerde slicers",
|
||||
"cmd.frame_member": "Constructiedeel",
|
||||
@@ -999,7 +1001,17 @@
|
||||
"pick a hole to seat it, or OK places it at the origin": "kies een gat om het te plaatsen, of OK plaatst het op de oorsprong",
|
||||
"pick one or two vertices, edges or faces": "kies een of twee hoekpunten, randen of vlakken",
|
||||
"prefs.cpu": "CPU (software)",
|
||||
"prefs.dialogs": "Dialogen",
|
||||
"prefs.dialogs_edge": "Aan de rand van de weergave",
|
||||
"prefs.dialogs_left_column": "In de linkerkolom",
|
||||
"prefs.dialogs_note": "Waar opdrachtdialogen openen: vastgezet aan de rand van de weergave, of in de linkerkolom in plaats van de browser en de geschiedenis, die terugkomen zoals ze waren wanneer de dialoog sluit.",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Een themabestand volgen",
|
||||
"prefs.theme_follow_error": "Niet toegepast: {error}. Het laatste geldige thema blijft actief.",
|
||||
"prefs.theme_follow_launch": "Alleen deze sessie gevolgd (--theme-file); opnieuw geladen zodra een ander hulpmiddel het bestand overschrijft.",
|
||||
"prefs.theme_follow_note": "Opnieuw geladen zodra een ander hulpmiddel het bestand overschrijft. Een thema kiezen stopt het volgen.",
|
||||
"prefs.theme_follow_off": "Uit",
|
||||
"prefs.theme_follow_stop": "Volgen stoppen",
|
||||
"properties.title": "Eigenschappen: {name}",
|
||||
"recovery.days_ago": "{count} dagen geleden",
|
||||
"recovery.detail": "{file} · {features} kenmerken · automatisch opgeslagen {when}",
|
||||
@@ -1269,7 +1281,7 @@
|
||||
"ui.agent_chat_pop_out": "Openen in een eigen venster, dat u naar een ander scherm kunt verplaatsen",
|
||||
"ui.agent_chat_previous_picture": "Vorige afbeelding",
|
||||
"ui.agent_chat_privacy": "Er gaat niets naar buiten behalve naar de agent die u uitvoert, onder uw eigen account.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft verstuurt niets: de agent die u uitvoert praat met zijn eigen service onder uw eigen account. SolidCraft ziet of bewaart nooit een sleutel of wachtwoord.",
|
||||
"ui.agent_chat_privacy_note": "De chat verstuurt zelf niets: de agent die u uitvoert praat met zijn eigen service onder uw eigen account. SolidCraft ziet of bewaart nooit een sleutel of wachtwoord.",
|
||||
"ui.agent_chat_queue": "In wachtrij",
|
||||
"ui.agent_chat_queue_full": "Te veel berichten wachten: verwijder er een of wacht op de agent.",
|
||||
"ui.agent_chat_queued": "In wachtrij",
|
||||
@@ -1453,6 +1465,7 @@
|
||||
"ui.command_done": "{command} gereed",
|
||||
"ui.command_palette_hint": "Typ een opdracht, bijv. {example} — of druk op S om te zoeken",
|
||||
"ui.concentric": "Concentrisch",
|
||||
"ui.cone": "Kegel",
|
||||
"ui.conic_curve": "Kegelsnede",
|
||||
"ui.constant": "Constant",
|
||||
"ui.constraints_conflict": "Beperkingen conflicteren",
|
||||
@@ -1511,6 +1524,11 @@
|
||||
"ui.draft": "Aanzet",
|
||||
"ui.drawing": "Tekening",
|
||||
"ui.drill_point": "Boorpunt",
|
||||
"ui.easyprint_consent": "EasyPrint is de slicer van Printables in de browser. Om het model daar te openen, uploadt SolidCraft het naar de servers van Printables. De link verloopt na 30 minuten en u moet bij Printables zijn ingelogd. Doorgaan?",
|
||||
"ui.easyprint_failed": "Uploaden naar EasyPrint mislukt: {error}",
|
||||
"ui.easyprint_opened": "Geopend in EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, in de browser)",
|
||||
"ui.easyprint_uploading": "Uploaden naar Printables…",
|
||||
"ui.edit": "Bewerken",
|
||||
"ui.editJointLimits": "Verbindingslimieten bewerken",
|
||||
"ui.edit_section_analysis": "Doorsnedeanalyse bewerken",
|
||||
@@ -1567,6 +1585,7 @@
|
||||
"ui.heading_circular_pattern": "CIRKELVORMIG PATROON",
|
||||
"ui.heading_coil": "SPIRAAL",
|
||||
"ui.heading_combine": "COMBINEREN",
|
||||
"ui.heading_cone": "KEGEL",
|
||||
"ui.heading_configure": "CONFIGUREREN",
|
||||
"ui.heading_constraints": "BEPERKINGEN",
|
||||
"ui.heading_construct": "CONSTRUEREN",
|
||||
@@ -1802,9 +1821,7 @@
|
||||
"ui.right": "Rechts",
|
||||
"ui.save": "Opslaan",
|
||||
"ui.save_as": "Opslaan als",
|
||||
"ui.save_mesh_no_slicer": "Geen slicer gevonden: kies Aangepast… en selecteer uw slicerprogramma, of schakel Naar slicer verzenden uit",
|
||||
"ui.save_mesh_pick_bodies": "Selecteer de op te slaan lichamen",
|
||||
"ui.save_mesh_temp_failed": "{folder} kon niet worden gemaakt: {error}",
|
||||
"ui.saved_to": "{path} opgeslagen",
|
||||
"ui.sbox_pin": "Bovenaan het S-vak vastpinnen",
|
||||
"ui.sbox_unpin": "Losmaken",
|
||||
@@ -1819,7 +1836,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+klik voegt toe zonder te verwijderen",
|
||||
"ui.selection_shift_add_only_tip": "Aan: Shift voegt items toe, Ctrl/Cmd schakelt om. Uit (standaard): Shift en Ctrl/Cmd schakelen beide om.",
|
||||
"ui.send": "Verzenden",
|
||||
"ui.send_to_slicer": "Naar slicer verzenden",
|
||||
"ui.sent_to_slicer": "Verzonden naar {slicer}",
|
||||
"ui.sheet_gap": "Opening",
|
||||
"ui.shell": "Schalen",
|
||||
@@ -1911,6 +1927,7 @@
|
||||
"ui.untitled": "Naamloos",
|
||||
"ui.up_axis_note": "Welke as in de weergaven omhoog wijst (aanzicht op as, Home, Kijken naar). Ontwerpen blijven ongewijzigd.",
|
||||
"ui.updateToCurrentView": "Bijwerken naar huidige weergave",
|
||||
"ui.upload": "Uploaden",
|
||||
"ui.view_centre": "Weergavemidden",
|
||||
"ui.visual_shaded_hidden_edges": "Gearceerd met verborgen randen",
|
||||
"ui.visual_shaded_with_edges": "Gearceerd met randen",
|
||||
|
||||
@@ -510,6 +510,7 @@
|
||||
"cmd.canvas_delete": "Usuń płótno",
|
||||
"cmd.canvas_edit": "Edytuj płótno",
|
||||
"cmd.canvas_insert": "Płótno",
|
||||
"cmd.canvas_to_sketch": "Szkic z płótna",
|
||||
"cmd.component_activate": "Aktywuj komponent",
|
||||
"cmd.component_break_link": "Zerwij łącze",
|
||||
"cmd.component_capture_position": "Zapamiętaj położenie",
|
||||
@@ -588,6 +589,7 @@
|
||||
"cmd.file_export": "Eksportuj",
|
||||
"cmd.file_insert_mesh": "Wstaw siatkę",
|
||||
"cmd.file_insert_step": "Wstaw STEP",
|
||||
"cmd.file_open_in_easyprint": "Otwórz w EasyPrint",
|
||||
"cmd.file_save_mesh": "Zapisz jako siatkę",
|
||||
"cmd.file_slicers": "Zainstalowane slicery",
|
||||
"cmd.frame_member": "Element ramy",
|
||||
@@ -1171,6 +1173,12 @@
|
||||
"prefs.supersampling_brief": "Rysuje widok w większym rozmiarze i go zmniejsza: bardzo ostro, ale bardziej obciąża.",
|
||||
"prefs.tab_accent_note": "Kolor akcentu podąża za aktywną kartą",
|
||||
"prefs.theme_file": "plik motywu",
|
||||
"prefs.theme_follow": "Śledź plik motywu",
|
||||
"prefs.theme_follow_error": "Nie zastosowano: {error}. Ostatni poprawny motyw pozostaje aktywny.",
|
||||
"prefs.theme_follow_launch": "Śledzenie tylko w tej sesji (--theme-file); plik jest wczytywany ponownie po każdym nadpisaniu przez inne narzędzie.",
|
||||
"prefs.theme_follow_note": "Plik jest wczytywany ponownie po każdym nadpisaniu przez inne narzędzie. Wybór motywu kończy śledzenie.",
|
||||
"prefs.theme_follow_off": "Wyłączone",
|
||||
"prefs.theme_follow_stop": "Zakończ śledzenie",
|
||||
"prefs.timeline_half_hour": "−30 min",
|
||||
"prefs.timeline_now": "teraz",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
@@ -1517,7 +1525,7 @@
|
||||
"ui.agent_chat_pop_out": "Otwórz w osobnym oknie, które możesz przenieść na inny ekran",
|
||||
"ui.agent_chat_previous_picture": "Poprzedni obraz",
|
||||
"ui.agent_chat_privacy": "Nic nie trafia nigdzie poza uruchomionym przez Ciebie agentem, na Twoim własnym koncie.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft nigdzie niczego nie wysyła: uruchomiony przez Ciebie agent łączy się z własną usługą na Twoim koncie. SolidCraft nigdy nie widzi ani nie przechowuje klucza ani hasła.",
|
||||
"ui.agent_chat_privacy_note": "Czat sam z siebie nigdzie niczego nie wysyła: uruchomiony przez Ciebie agent łączy się z własną usługą na Twoim koncie. SolidCraft nigdy nie widzi ani nie przechowuje klucza ani hasła.",
|
||||
"ui.agent_chat_queue": "Kolejka",
|
||||
"ui.agent_chat_queue_full": "Za dużo wiadomości czeka: usuń jedną lub poczekaj na agenta.",
|
||||
"ui.agent_chat_queued": "W kolejce",
|
||||
@@ -1704,6 +1712,7 @@
|
||||
"ui.command_done": "Wykonano: {command}",
|
||||
"ui.command_palette_hint": "Wpisz polecenie, np. {example} — lub naciśnij S, aby wyszukać",
|
||||
"ui.concentric": "Współśrodkowość",
|
||||
"ui.cone": "Stożek",
|
||||
"ui.conic_curve": "Krzywa stożkowa",
|
||||
"ui.constant": "Stały",
|
||||
"ui.constraints_conflict": "Konflikt wiązań",
|
||||
@@ -1762,6 +1771,11 @@
|
||||
"ui.draft": "Pochylenie",
|
||||
"ui.drawing": "Rysunek",
|
||||
"ui.drill_point": "Wierzchołek wiertła",
|
||||
"ui.easyprint_consent": "EasyPrint to slicer Printables w przeglądarce. Aby otworzyć w nim model, SolidCraft wysyła go na serwery Printables. Link wygasa po 30 minutach, a Ty musisz być zalogowany w Printables. Kontynuować?",
|
||||
"ui.easyprint_failed": "Nie udało się wysłać do EasyPrint: {error}",
|
||||
"ui.easyprint_opened": "Otwarto w EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, w przeglądarce)",
|
||||
"ui.easyprint_uploading": "Wysyłanie do Printables…",
|
||||
"ui.edit": "Edytuj",
|
||||
"ui.editJointLimits": "Edytuj limity złącza",
|
||||
"ui.edit_section_analysis": "Edytuj analizę przekroju",
|
||||
@@ -1818,6 +1832,7 @@
|
||||
"ui.heading_circular_pattern": "SZYK KOŁOWY",
|
||||
"ui.heading_coil": "SPIRALA",
|
||||
"ui.heading_combine": "KOMBINACJA",
|
||||
"ui.heading_cone": "STOŻEK",
|
||||
"ui.heading_configure": "KONFIGURACJA",
|
||||
"ui.heading_constraints": "WIĄZANIA",
|
||||
"ui.heading_construct": "KONSTRUKCJA",
|
||||
@@ -2067,9 +2082,7 @@
|
||||
"ui.right": "Prawy",
|
||||
"ui.save": "Zapisz",
|
||||
"ui.save_as": "Zapisz jako",
|
||||
"ui.save_mesh_no_slicer": "Nie znaleziono slicera: wybierz Niestandardowy… i wskaż program slicera albo wyłącz Wyślij do slicera",
|
||||
"ui.save_mesh_pick_bodies": "Zaznacz bryły do zapisania",
|
||||
"ui.save_mesh_temp_failed": "Nie udało się utworzyć {folder}: {error}",
|
||||
"ui.saved_to": "Zapisano {path}",
|
||||
"ui.sbox_pin": "Przypnij na górze okna S",
|
||||
"ui.sbox_unpin": "Odepnij",
|
||||
@@ -2084,7 +2097,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+kliknięcie tylko dodaje",
|
||||
"ui.selection_shift_add_only_tip": "Wł.: Shift dodaje elementy, Ctrl/Cmd przełącza. Wył. (domyślnie): Shift i Ctrl/Cmd przełączają.",
|
||||
"ui.send": "Wyślij",
|
||||
"ui.send_to_slicer": "Wyślij do slicera",
|
||||
"ui.sent_to_slicer": "Wysłano do {slicer}",
|
||||
"ui.sheet_gap": "Szczelina",
|
||||
"ui.shell": "Skorupa",
|
||||
@@ -2176,6 +2188,7 @@
|
||||
"ui.untitled": "Bez tytułu",
|
||||
"ui.up_axis_note": "Która oś wskazuje górę w widokach (widok osi, Widok główny, Patrz na). Projekty pozostają bez zmian.",
|
||||
"ui.updateToCurrentView": "Aktualizuj do bieżącego widoku",
|
||||
"ui.upload": "Wyślij",
|
||||
"ui.view_centre": "Środek widoku",
|
||||
"ui.visual_shaded_hidden_edges": "Cieniowany z krawędziami niewidocznymi",
|
||||
"ui.visual_shaded_with_edges": "Cieniowany z krawędziami",
|
||||
|
||||
@@ -613,6 +613,7 @@
|
||||
"cmd.canvas_delete": "Excluir tela de referência",
|
||||
"cmd.canvas_edit": "Editar tela de referência",
|
||||
"cmd.canvas_insert": "Tela de referência",
|
||||
"cmd.canvas_to_sketch": "Esboço a partir da tela de referência",
|
||||
"cmd.component_activate": "Ativar componente",
|
||||
"cmd.component_break_link": "Quebrar vínculo",
|
||||
"cmd.component_capture_position": "Capturar posição",
|
||||
@@ -693,6 +694,7 @@
|
||||
"cmd.file_export": "Exportar",
|
||||
"cmd.file_insert_mesh": "Inserir malha",
|
||||
"cmd.file_insert_step": "Inserir STEP",
|
||||
"cmd.file_open_in_easyprint": "Abrir com o EasyPrint",
|
||||
"cmd.file_save_mesh": "Salvar como malha",
|
||||
"cmd.file_slicers": "Fatiadores instalados",
|
||||
"cmd.frame_member": "Membro estrutural",
|
||||
@@ -1155,6 +1157,7 @@
|
||||
"nav.blender.help": "Arrastar com o meio orbita, Shift+meio desloca, Ctrl+meio aplica zoom; arrastar com o direito não mexe na câmera",
|
||||
"nav.free_orbit.help": "O mouse e o mouse 3D giram passando pelos dois polos e preservam o giro lateral (roll). O encaixe em eixo com Shift fica desativado.",
|
||||
"nav.free_orbit.label": "Órbita livre",
|
||||
"nav.free_orbit.snap_help": "Mouse e mouse 3D giram através dos dois polos e preservam a rotação da imagem. Mantenha Shift pressionado durante uma órbita por arraste para alinhar a direção da vista e a rotação da imagem.",
|
||||
"nav.fusion.help": "Arrastar com o meio desloca, Shift+meio orbita, arrastar com o direito orbita",
|
||||
"nav.inventor.help": "Arrastar com o meio desloca, Shift+meio orbita, Ctrl+meio aplica zoom, arrastar com o direito orbita",
|
||||
"nav.openscad.help": "Arrastar com o esquerdo no espaço vazio orbita, Shift+arrastar com o esquerdo seleciona por caixa, arrastar a geometria do esboço a edita; arrastar com o direito ou o meio desloca, Shift+arrastar com o direito ou o meio aplica zoom",
|
||||
@@ -1290,6 +1293,12 @@
|
||||
"prefs.supersampling_brief": "Desenha a vista maior e a reduz com filtragem: muito nítida, e mais pesada.",
|
||||
"prefs.tab_accent_note": "A cor de destaque acompanha a aba ativa",
|
||||
"prefs.theme_file": "arquivo de tema",
|
||||
"prefs.theme_follow": "Seguir um arquivo de tema",
|
||||
"prefs.theme_follow_error": "Não aplicado: {error}. O último tema válido continua ativo.",
|
||||
"prefs.theme_follow_launch": "Seguido apenas nesta sessão (--theme-file); recarregado sempre que outra ferramenta reescreve o arquivo.",
|
||||
"prefs.theme_follow_note": "Recarregado sempre que outra ferramenta reescreve o arquivo. Escolher um tema interrompe o acompanhamento.",
|
||||
"prefs.theme_follow_off": "Desativado",
|
||||
"prefs.theme_follow_stop": "Parar de seguir",
|
||||
"prefs.timeline_half_hour": "−30 min",
|
||||
"prefs.timeline_now": "agora",
|
||||
"prefs.timeline_quarter_hour": "−15",
|
||||
@@ -1637,7 +1646,7 @@
|
||||
"ui.agent_chat_pop_out": "Abrir em janela própria, que você pode mover para outra tela",
|
||||
"ui.agent_chat_previous_picture": "Imagem anterior",
|
||||
"ui.agent_chat_privacy": "Nada vai para lugar algum além do agente que você executa, na sua própria conta.",
|
||||
"ui.agent_chat_privacy_note": "O SolidCraft não envia nada a lugar nenhum: o agente que você executa fala com o próprio serviço, na sua própria conta. O SolidCraft nunca vê nem guarda chaves ou senhas.",
|
||||
"ui.agent_chat_privacy_note": "O chat não envia nada a lugar nenhum por conta própria: o agente que você executa fala com o próprio serviço, na sua própria conta. O SolidCraft nunca vê nem guarda chaves ou senhas.",
|
||||
"ui.agent_chat_queue": "Fila",
|
||||
"ui.agent_chat_queue_full": "Há mensagens demais esperando: remova uma ou aguarde o agente.",
|
||||
"ui.agent_chat_queued": "Na fila",
|
||||
@@ -1830,6 +1839,7 @@
|
||||
"ui.command_done": "{command} concluído",
|
||||
"ui.command_palette_hint": "Digite um comando, p. ex. {example} — ou pressione S para pesquisar",
|
||||
"ui.concentric": "Concêntrico",
|
||||
"ui.cone": "Cone",
|
||||
"ui.conic_curve": "Curva cônica",
|
||||
"ui.constant": "Constante",
|
||||
"ui.constraints_conflict": "Restrições em conflito",
|
||||
@@ -1888,6 +1898,11 @@
|
||||
"ui.draft": "Ângulo de saída",
|
||||
"ui.drawing": "Desenho",
|
||||
"ui.drill_point": "Ponta de broca",
|
||||
"ui.easyprint_consent": "O EasyPrint é o slicer do Printables no navegador. Para abrir o modelo lá, o SolidCraft o envia para os servidores do Printables. O link expira em 30 minutos e você precisa estar conectado ao Printables. Continuar?",
|
||||
"ui.easyprint_failed": "Falha ao enviar para o EasyPrint: {error}",
|
||||
"ui.easyprint_opened": "Aberto no EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, no navegador)",
|
||||
"ui.easyprint_uploading": "Enviando para o Printables…",
|
||||
"ui.edit": "Editar",
|
||||
"ui.editJointLimits": "Editar limites da junta",
|
||||
"ui.edit_section_analysis": "Editar análise de seção",
|
||||
@@ -1947,6 +1962,7 @@
|
||||
"ui.heading_circular_pattern": "PADRÃO CIRCULAR",
|
||||
"ui.heading_coil": "ESPIRAL",
|
||||
"ui.heading_combine": "COMBINAR",
|
||||
"ui.heading_cone": "CONE",
|
||||
"ui.heading_configure": "CONFIGURAR",
|
||||
"ui.heading_constraints": "RESTRIÇÕES",
|
||||
"ui.heading_construct": "CONSTRUIR",
|
||||
@@ -2194,9 +2210,7 @@
|
||||
"ui.right": "Direita",
|
||||
"ui.save": "Salvar",
|
||||
"ui.save_as": "Salvar como",
|
||||
"ui.save_mesh_no_slicer": "Nenhum fatiador encontrado: escolha Personalizado… e selecione seu programa fatiador, ou desative Enviar ao fatiador",
|
||||
"ui.save_mesh_pick_bodies": "Selecione os corpos a salvar",
|
||||
"ui.save_mesh_temp_failed": "Não foi possível criar {folder}: {error}",
|
||||
"ui.saved_to": "Salvo {path}",
|
||||
"ui.sbox_pin": "Fixar no topo da caixa S",
|
||||
"ui.sbox_unpin": "Desafixar",
|
||||
@@ -2211,7 +2225,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+clique adiciona sem remover",
|
||||
"ui.selection_shift_add_only_tip": "Ativado: Shift adiciona itens, Ctrl/Cmd alterna. Desativado (padrão): Shift e Ctrl/Cmd alternam.",
|
||||
"ui.send": "Enviar",
|
||||
"ui.send_to_slicer": "Enviar ao fatiador",
|
||||
"ui.sent_to_slicer": "Enviado para {slicer}",
|
||||
"ui.sheet_gap": "Folga",
|
||||
"ui.shell": "Casca",
|
||||
@@ -2303,6 +2316,7 @@
|
||||
"ui.untitled": "Sem título",
|
||||
"ui.up_axis_note": "Qual eixo aponta para cima nas vistas (vista do eixo, Início, Olhar para). Os projetos não mudam.",
|
||||
"ui.updateToCurrentView": "Atualizar para a vista atual",
|
||||
"ui.upload": "Enviar",
|
||||
"ui.view_centre": "Centro da vista",
|
||||
"ui.visual_shaded_hidden_edges": "Sombreado com arestas ocultas",
|
||||
"ui.visual_shaded_with_edges": "Sombreado com arestas",
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
"cmd.canvas_delete": "Șterge pânza",
|
||||
"cmd.canvas_edit": "Editează pânza",
|
||||
"cmd.canvas_insert": "Pânză",
|
||||
"cmd.canvas_to_sketch": "Schiță din pânză",
|
||||
"cmd.component_activate": "Activează componenta",
|
||||
"cmd.component_break_link": "Rupe legătura",
|
||||
"cmd.component_capture_position": "Capturează poziția",
|
||||
@@ -533,6 +534,7 @@
|
||||
"cmd.file_export": "Exportă",
|
||||
"cmd.file_insert_mesh": "Inserează plasă",
|
||||
"cmd.file_insert_step": "Inserează STEP",
|
||||
"cmd.file_open_in_easyprint": "Deschide cu EasyPrint",
|
||||
"cmd.file_save_mesh": "Salvează ca plasă",
|
||||
"cmd.file_slicers": "Slicere instalate",
|
||||
"cmd.frame_member": "Element de cadru",
|
||||
@@ -1000,6 +1002,12 @@
|
||||
"pick one or two vertices, edges or faces": "alegeți unul sau două vârfuri, muchii sau fețe",
|
||||
"prefs.cpu": "CPU (software)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Urmărește un fișier de temă",
|
||||
"prefs.theme_follow_error": "Nu s-a aplicat: {error}. Ultima temă validă rămâne activă.",
|
||||
"prefs.theme_follow_launch": "Urmărit doar în această sesiune (--theme-file); reîncărcat când alt instrument rescrie fișierul.",
|
||||
"prefs.theme_follow_note": "Reîncărcat când alt instrument rescrie fișierul. Alegerea unei teme oprește urmărirea.",
|
||||
"prefs.theme_follow_off": "Dezactivat",
|
||||
"prefs.theme_follow_stop": "Oprește urmărirea",
|
||||
"properties.title": "Proprietăți: {name}",
|
||||
"recovery.days_ago": "acum {count} zile",
|
||||
"recovery.detail": "{file} · {features} operații · salvat automat {when}",
|
||||
@@ -1269,7 +1277,7 @@
|
||||
"ui.agent_chat_pop_out": "Deschide în propria fereastră, pe care o puteți muta pe alt ecran",
|
||||
"ui.agent_chat_previous_picture": "Imaginea anterioară",
|
||||
"ui.agent_chat_privacy": "Nimic nu merge nicăieri în afară de agentul pe care îl rulați, sub propriul cont.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft nu trimite nimic nicăieri: agentul pe care îl rulați comunică cu propriul serviciu sub contul dumneavoastră. SolidCraft nu vede și nu stochează niciodată o cheie sau o parolă.",
|
||||
"ui.agent_chat_privacy_note": "Chatul nu trimite nimic nicăieri de la sine: agentul pe care îl rulați comunică cu propriul serviciu sub contul dumneavoastră. SolidCraft nu vede și nu stochează niciodată o cheie sau o parolă.",
|
||||
"ui.agent_chat_queue": "Coadă",
|
||||
"ui.agent_chat_queue_full": "Prea multe mesaje așteaptă: eliminați unul sau așteptați agentul.",
|
||||
"ui.agent_chat_queued": "În coadă",
|
||||
@@ -1453,6 +1461,7 @@
|
||||
"ui.command_done": "{command} efectuat",
|
||||
"ui.command_palette_hint": "Tastați o comandă, ex. {example} — sau apăsați S pentru căutare",
|
||||
"ui.concentric": "Concentric",
|
||||
"ui.cone": "Con",
|
||||
"ui.conic_curve": "Curbă conică",
|
||||
"ui.constant": "Constant",
|
||||
"ui.constraints_conflict": "Conflict de constrângeri",
|
||||
@@ -1511,6 +1520,11 @@
|
||||
"ui.draft": "Înclinare",
|
||||
"ui.drawing": "Desen",
|
||||
"ui.drill_point": "Vârf de burghiu",
|
||||
"ui.easyprint_consent": "EasyPrint este slicerul Printables din browser. Pentru a deschide modelul acolo, SolidCraft îl încarcă pe serverele Printables. Linkul expiră după 30 de minute, iar dumneavoastră trebuie să fiți autentificat pe Printables. Continuați?",
|
||||
"ui.easyprint_failed": "Încărcarea în EasyPrint a eșuat: {error}",
|
||||
"ui.easyprint_opened": "Deschis în EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, în browser)",
|
||||
"ui.easyprint_uploading": "Se încarcă pe Printables…",
|
||||
"ui.edit": "Editează",
|
||||
"ui.editJointLimits": "Editează limitele îmbinării",
|
||||
"ui.edit_section_analysis": "Editează analiza secțiunii",
|
||||
@@ -1567,6 +1581,7 @@
|
||||
"ui.heading_circular_pattern": "MATRICE CIRCULARĂ",
|
||||
"ui.heading_coil": "SPIRALĂ",
|
||||
"ui.heading_combine": "COMBINARE",
|
||||
"ui.heading_cone": "CON",
|
||||
"ui.heading_configure": "CONFIGURARE",
|
||||
"ui.heading_constraints": "CONSTRÂNGERI",
|
||||
"ui.heading_construct": "CONSTRUCȚIE",
|
||||
@@ -1802,9 +1817,7 @@
|
||||
"ui.right": "Dreapta",
|
||||
"ui.save": "Salvează",
|
||||
"ui.save_as": "Salvează ca",
|
||||
"ui.save_mesh_no_slicer": "Niciun slicer găsit: alegeți Personalizat… și selectați programul slicer sau dezactivați Trimite la slicer",
|
||||
"ui.save_mesh_pick_bodies": "Selectați corpurile de salvat",
|
||||
"ui.save_mesh_temp_failed": "Nu s-a putut crea {folder}: {error}",
|
||||
"ui.saved_to": "Salvat {path}",
|
||||
"ui.sbox_pin": "Fixează în partea de sus a casetei S",
|
||||
"ui.sbox_unpin": "Defixează",
|
||||
@@ -1819,7 +1832,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+clic adaugă fără a elimina",
|
||||
"ui.selection_shift_add_only_tip": "Activat: Shift adaugă elemente, Ctrl/Cmd comută. Dezactivat (implicit): Shift și Ctrl/Cmd comută ambele.",
|
||||
"ui.send": "Trimite",
|
||||
"ui.send_to_slicer": "Trimite la slicer",
|
||||
"ui.sent_to_slicer": "Trimis la {slicer}",
|
||||
"ui.sheet_gap": "Spațiu",
|
||||
"ui.shell": "Scobire",
|
||||
@@ -1911,6 +1923,7 @@
|
||||
"ui.untitled": "Fără titlu",
|
||||
"ui.up_axis_note": "Ce axă indică în sus în vizualizări (vizualizare pe axă, Acasă, Privește spre). Proiectele rămân neschimbate.",
|
||||
"ui.updateToCurrentView": "Actualizează la vizualizarea curentă",
|
||||
"ui.upload": "Încarcă",
|
||||
"ui.view_centre": "Centrul vizualizării",
|
||||
"ui.visual_shaded_hidden_edges": "Umbrit cu muchii ascunse",
|
||||
"ui.visual_shaded_with_edges": "Umbrit cu muchii",
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
"cmd.canvas_delete": "Удалить подложку",
|
||||
"cmd.canvas_edit": "Изменить подложку",
|
||||
"cmd.canvas_insert": "Подложка",
|
||||
"cmd.canvas_to_sketch": "Эскиз из подложки",
|
||||
"cmd.component_activate": "Активировать компонент",
|
||||
"cmd.component_break_link": "Разорвать связь",
|
||||
"cmd.component_capture_position": "Зафиксировать положение",
|
||||
@@ -533,6 +534,7 @@
|
||||
"cmd.file_export": "Экспорт",
|
||||
"cmd.file_insert_mesh": "Вставить меш",
|
||||
"cmd.file_insert_step": "Вставить STEP",
|
||||
"cmd.file_open_in_easyprint": "Открыть в EasyPrint",
|
||||
"cmd.file_save_mesh": "Сохранить как меш",
|
||||
"cmd.file_slicers": "Установленные слайсеры",
|
||||
"cmd.frame_member": "Элемент рамы",
|
||||
@@ -1000,6 +1002,12 @@
|
||||
"pick one or two vertices, edges or faces": "выберите одну-две вершины, ребра или грани",
|
||||
"prefs.cpu": "ЦП (программный)",
|
||||
"prefs.minutes_suffix": " min",
|
||||
"prefs.theme_follow": "Следить за файлом темы",
|
||||
"prefs.theme_follow_error": "Не применено: {error}. Последняя рабочая тема остаётся активной.",
|
||||
"prefs.theme_follow_launch": "Только для этого запуска (--theme-file); перезагружается, когда другой инструмент перезаписывает файл.",
|
||||
"prefs.theme_follow_note": "Перезагружается, когда другой инструмент перезаписывает файл. Выбор темы прекращает отслеживание.",
|
||||
"prefs.theme_follow_off": "Выкл.",
|
||||
"prefs.theme_follow_stop": "Прекратить отслеживание",
|
||||
"properties.title": "Свойства: {name}",
|
||||
"recovery.days_ago": "{count} дн. назад",
|
||||
"recovery.detail": "{file} · операций: {features} · автосохранение {when}",
|
||||
@@ -1325,7 +1333,7 @@
|
||||
"ui.agent_chat_pop_out": "Открыть в отдельном окне, которое можно перенести на другой экран",
|
||||
"ui.agent_chat_previous_picture": "Предыдущее изображение",
|
||||
"ui.agent_chat_privacy": "Ничего не уходит никуда, кроме запускаемого вами агента, под вашей учётной записью.",
|
||||
"ui.agent_chat_privacy_note": "SolidCraft ничего никуда не отправляет: запускаемый вами агент обращается к своему сервису под вашей учётной записью. SolidCraft никогда не видит и не хранит ключ или пароль.",
|
||||
"ui.agent_chat_privacy_note": "Чат сам ничего никуда не отправляет: запускаемый вами агент обращается к своему сервису под вашей учётной записью. SolidCraft никогда не видит и не хранит ключ или пароль.",
|
||||
"ui.agent_chat_queue": "В очередь",
|
||||
"ui.agent_chat_queue_full": "Слишком много сообщений в ожидании: удалите одно или дождитесь агента.",
|
||||
"ui.agent_chat_queued": "В очереди",
|
||||
@@ -1510,6 +1518,7 @@
|
||||
"ui.command_done": "{command} — готово",
|
||||
"ui.command_palette_hint": "Введите команду, напр. {example} — или нажмите S для поиска",
|
||||
"ui.concentric": "Концентричность",
|
||||
"ui.cone": "Конус",
|
||||
"ui.conic_curve": "Коническая кривая",
|
||||
"ui.constant": "Постоянный",
|
||||
"ui.constraints_conflict": "Ограничения конфликтуют",
|
||||
@@ -1568,6 +1577,11 @@
|
||||
"ui.draft": "Уклон",
|
||||
"ui.drawing": "Чертёж",
|
||||
"ui.drill_point": "Конус сверла",
|
||||
"ui.easyprint_consent": "EasyPrint — это слайсер Printables в браузере. Чтобы открыть модель там, SolidCraft загружает её на серверы Printables. Ссылка действует 30 минут, и вам нужно войти в Printables. Продолжить?",
|
||||
"ui.easyprint_failed": "Не удалось загрузить в EasyPrint: {error}",
|
||||
"ui.easyprint_opened": "Открыто в EasyPrint",
|
||||
"ui.easyprint_row": "EasyPrint (Printables, в браузере)",
|
||||
"ui.easyprint_uploading": "Загрузка в Printables…",
|
||||
"ui.edit": "Изменить",
|
||||
"ui.editJointLimits": "Изменить ограничения сопряжения",
|
||||
"ui.edit_section_analysis": "Изменить анализ сечения",
|
||||
@@ -1624,6 +1638,7 @@
|
||||
"ui.heading_circular_pattern": "КРУГОВОЙ МАССИВ",
|
||||
"ui.heading_coil": "СПИРАЛЬ",
|
||||
"ui.heading_combine": "ОБЪЕДИНЕНИЕ",
|
||||
"ui.heading_cone": "КОНУС",
|
||||
"ui.heading_configure": "КОНФИГУРАЦИЯ",
|
||||
"ui.heading_constraints": "ОГРАНИЧЕНИЯ",
|
||||
"ui.heading_construct": "ПОСТРОЕНИЕ",
|
||||
@@ -1859,9 +1874,7 @@
|
||||
"ui.right": "Справа",
|
||||
"ui.save": "Сохранить",
|
||||
"ui.save_as": "Сохранить как",
|
||||
"ui.save_mesh_no_slicer": "Слайсер не найден: выберите «Другая…» и укажите программу или отключите «Отправить в слайсер»",
|
||||
"ui.save_mesh_pick_bodies": "Выберите тела для сохранения",
|
||||
"ui.save_mesh_temp_failed": "Не удалось создать {folder}: {error}",
|
||||
"ui.saved_to": "Сохранено: {path}",
|
||||
"ui.sbox_pin": "Закрепить вверху панели S",
|
||||
"ui.sbox_unpin": "Открепить",
|
||||
@@ -1876,7 +1889,6 @@
|
||||
"ui.selection_shift_add_only": "Shift+щелчок добавляет без удаления",
|
||||
"ui.selection_shift_add_only_tip": "Вкл.: Shift добавляет объекты, Ctrl/Cmd переключает. Выкл. (по умолчанию): Shift и Ctrl/Cmd оба переключают.",
|
||||
"ui.send": "Отправить",
|
||||
"ui.send_to_slicer": "Отправить в слайсер",
|
||||
"ui.sent_to_slicer": "Отправлено в {slicer}",
|
||||
"ui.sheet_gap": "Зазор",
|
||||
"ui.shell": "Оболочка",
|
||||
@@ -1968,6 +1980,7 @@
|
||||
"ui.untitled": "Без имени",
|
||||
"ui.up_axis_note": "Какая ось направлена вверх в видах (осевые виды, «Главная», «Взгляд на»). Дизайны не меняются.",
|
||||
"ui.updateToCurrentView": "Обновить до текущего вида",
|
||||
"ui.upload": "Загрузить",
|
||||
"ui.view_centre": "Центр вида",
|
||||
"ui.visual_shaded_hidden_edges": "Заполненный с невидимыми рёбрами",
|
||||
"ui.visual_shaded_with_edges": "Заполненный с рёбрами",
|
||||
|
||||