Compare commits
58 Commits
v0.1.0
...
feat/updat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35302154ae | ||
|
|
be7f1d9221 | ||
|
|
10b5c9d584 | ||
|
|
ee839c23b8 | ||
|
|
67f825c305 | ||
| 440df2a9be | |||
|
|
1750949afd | ||
| b2c6fc2ebc | |||
|
|
d0c67455dc | ||
|
|
62906b0269 | ||
| 99bc7629e7 | |||
|
|
d95c850b7b | ||
| 1f7dae4f11 | |||
| 1d7e4e2eef | |||
|
|
fe50b1595e | ||
|
|
0e5a259d14 | ||
|
|
bfb2728f8d | ||
|
|
7bec3d5c3b | ||
|
|
145c29d7d6 | ||
|
|
8ba7b73aa8 | ||
|
|
1e4deea130 | ||
|
|
3923e2e4b9 | ||
|
|
9e29b76fbc | ||
|
|
88e025f1c6 | ||
|
|
772d3b3288 | ||
|
|
dfa2b73966 | ||
|
|
056b015e78 | ||
| 6649372f7b | |||
| 5db68dab25 | |||
|
|
c59c704da3 | ||
|
|
a2200b4042 | ||
|
|
c858706d48 | ||
|
|
724440dcb7 | ||
|
|
2f594dac0a | ||
|
|
939b81385e | ||
|
|
84b69b935b | ||
| a6e84552da | |||
| 015df38328 | |||
| db85277f26 | |||
| 679aaec6d4 | |||
| deeb6376f7 | |||
| 103fc28bc6 | |||
| 79c85ed2e5 | |||
| 38358e431d | |||
| 5319387030 | |||
| 405e04bd3e | |||
| 7535a48ec4 | |||
| 1c309a0ca8 | |||
| 2d7735b4c1 | |||
| 69414c5dc5 | |||
| c28d6f92cf | |||
| 224feda4ad | |||
| 67e5598b2e | |||
| 7431746ef0 | |||
| 044983330c | |||
| d60db282ea | |||
| 2a5a645ace | |||
| 434ae797a4 |
11
.gitea/runner/cleanup.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Kindred Create CI runner disk cleanup
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/runner/cleanup.sh
|
||||
Environment=CLEANUP_THRESHOLD=85
|
||||
Environment=CACHE_MAX_AGE_DAYS=7
|
||||
StandardOutput=append:/var/log/runner-cleanup.log
|
||||
StandardError=append:/var/log/runner-cleanup.log
|
||||
220
.gitea/runner/cleanup.sh
Executable file
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env bash
|
||||
# Runner disk cleanup script for Kindred Create CI/CD
|
||||
#
|
||||
# Designed to run as a cron job on the pubworker host:
|
||||
# */30 * * * * /path/to/cleanup.sh >> /var/log/runner-cleanup.log 2>&1
|
||||
#
|
||||
# Or install the systemd timer (see cleanup.timer / cleanup.service).
|
||||
#
|
||||
# What it cleans:
|
||||
# 1. Docker: stopped containers, dangling images, build cache
|
||||
# 2. act_runner action cache: keeps only the newest entry per key prefix
|
||||
# 3. act_runner workspaces: removes leftover build workspaces
|
||||
# 4. System: apt cache, old logs
|
||||
#
|
||||
# What it preserves:
|
||||
# - The current runner container and its image
|
||||
# - The most recent cache entry per prefix (so ccache hits still work)
|
||||
# - Everything outside of known CI paths
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Configuration -- adjust these to match your runner setup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Disk usage threshold (percent) -- only run aggressive cleanup above this
|
||||
THRESHOLD=${CLEANUP_THRESHOLD:-85}
|
||||
|
||||
# act_runner cache directory (default location)
|
||||
CACHE_DIR=${CACHE_DIR:-/root/.cache/actcache}
|
||||
|
||||
# act_runner workspace directories
|
||||
WORKSPACES=(
|
||||
"/root/.cache/act"
|
||||
"/workspace"
|
||||
)
|
||||
|
||||
# Maximum age (days) for cache entries before unconditional deletion
|
||||
CACHE_MAX_AGE_DAYS=${CACHE_MAX_AGE_DAYS:-7}
|
||||
|
||||
# Maximum age (days) for Docker images not used by running containers
|
||||
DOCKER_IMAGE_MAX_AGE=${DOCKER_IMAGE_MAX_AGE:-48h}
|
||||
|
||||
# Log prefix
|
||||
LOG_PREFIX="[runner-cleanup]"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') ${LOG_PREFIX} $*"; }
|
||||
|
||||
disk_usage_pct() {
|
||||
df --output=pcent / | tail -1 | tr -dc '0-9'
|
||||
}
|
||||
|
||||
bytes_to_human() {
|
||||
numfmt --to=iec-i --suffix=B "$1" 2>/dev/null || echo "${1}B"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 1: Check if cleanup is needed
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
log "Disk usage: ${usage}% (threshold: ${THRESHOLD}%)"
|
||||
|
||||
if [ "$usage" -lt "$THRESHOLD" ]; then
|
||||
log "Below threshold, running light cleanup only"
|
||||
AGGRESSIVE=false
|
||||
else
|
||||
log "Above threshold, running aggressive cleanup"
|
||||
AGGRESSIVE=true
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 2: Docker cleanup (always runs, safe)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- Docker cleanup ---"
|
||||
|
||||
# Remove stopped containers
|
||||
stopped=$(docker ps -aq --filter status=exited --filter status=dead 2>/dev/null | wc -l)
|
||||
if [ "$stopped" -gt 0 ]; then
|
||||
docker rm $(docker ps -aq --filter status=exited --filter status=dead) 2>/dev/null || true
|
||||
log "Removed ${stopped} stopped containers"
|
||||
fi
|
||||
|
||||
# Remove dangling images (untagged layers)
|
||||
dangling=$(docker images -q --filter dangling=true 2>/dev/null | wc -l)
|
||||
if [ "$dangling" -gt 0 ]; then
|
||||
docker rmi $(docker images -q --filter dangling=true) 2>/dev/null || true
|
||||
log "Removed ${dangling} dangling images"
|
||||
fi
|
||||
|
||||
# Prune build cache
|
||||
docker builder prune -f --filter "until=${DOCKER_IMAGE_MAX_AGE}" 2>/dev/null || true
|
||||
log "Pruned Docker build cache older than ${DOCKER_IMAGE_MAX_AGE}"
|
||||
|
||||
if [ "$AGGRESSIVE" = true ]; then
|
||||
# Remove all images not used by running containers
|
||||
running_images=$(docker ps -q 2>/dev/null | xargs -r docker inspect --format='{{.Image}}' | sort -u)
|
||||
all_images=$(docker images -q 2>/dev/null | sort -u)
|
||||
for img in $all_images; do
|
||||
if ! echo "$running_images" | grep -q "$img"; then
|
||||
docker rmi -f "$img" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
log "Removed unused Docker images (aggressive)"
|
||||
|
||||
# Prune volumes
|
||||
docker volume prune -f 2>/dev/null || true
|
||||
log "Pruned unused Docker volumes"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 3: act_runner action cache cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- Action cache cleanup ---"
|
||||
|
||||
if [ -d "$CACHE_DIR" ]; then
|
||||
before=$(du -sb "$CACHE_DIR" 2>/dev/null | cut -f1)
|
||||
|
||||
# Delete cache entries older than max age
|
||||
find "$CACHE_DIR" -type f -mtime "+${CACHE_MAX_AGE_DAYS}" -delete 2>/dev/null || true
|
||||
find "$CACHE_DIR" -type d -empty -delete 2>/dev/null || true
|
||||
|
||||
after=$(du -sb "$CACHE_DIR" 2>/dev/null | cut -f1)
|
||||
freed=$((before - after))
|
||||
log "Cache cleanup freed $(bytes_to_human $freed) (entries older than ${CACHE_MAX_AGE_DAYS}d)"
|
||||
else
|
||||
log "Cache directory not found: ${CACHE_DIR}"
|
||||
|
||||
# Try common alternative locations
|
||||
for alt in /var/lib/act_runner/.cache/actcache /home/*/.cache/actcache; do
|
||||
if [ -d "$alt" ]; then
|
||||
log "Found cache at: $alt (update CACHE_DIR config)"
|
||||
CACHE_DIR="$alt"
|
||||
find "$CACHE_DIR" -type f -mtime "+${CACHE_MAX_AGE_DAYS}" -delete 2>/dev/null || true
|
||||
find "$CACHE_DIR" -type d -empty -delete 2>/dev/null || true
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 4: Workspace cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- Workspace cleanup ---"
|
||||
|
||||
for ws in "${WORKSPACES[@]}"; do
|
||||
if [ -d "$ws" ]; then
|
||||
# Remove workspace dirs not modified in the last 2 hours
|
||||
# (active builds should be touching files continuously)
|
||||
before=$(du -sb "$ws" 2>/dev/null | cut -f1)
|
||||
find "$ws" -mindepth 1 -maxdepth 1 -type d -mmin +120 -exec rm -rf {} + 2>/dev/null || true
|
||||
after=$(du -sb "$ws" 2>/dev/null | cut -f1)
|
||||
freed=$((before - after))
|
||||
if [ "$freed" -gt 0 ]; then
|
||||
log "Workspace $ws: freed $(bytes_to_human $freed)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 5: System cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- System cleanup ---"
|
||||
|
||||
# apt cache
|
||||
apt-get clean 2>/dev/null || true
|
||||
|
||||
# Truncate large log files (keep last 1000 lines)
|
||||
for logfile in /var/log/syslog /var/log/daemon.log /var/log/kern.log; do
|
||||
if [ -f "$logfile" ] && [ "$(stat -c%s "$logfile" 2>/dev/null)" -gt 104857600 ]; then
|
||||
tail -1000 "$logfile" > "${logfile}.tmp" && mv "${logfile}.tmp" "$logfile"
|
||||
log "Truncated $logfile (was >100MB)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Journal logs older than 3 days
|
||||
journalctl --vacuum-time=3d 2>/dev/null || true
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 6: Emergency cleanup (only if still critical)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
if [ "$usage" -gt 95 ]; then
|
||||
log "CRITICAL: Still at ${usage}% after cleanup"
|
||||
|
||||
# Nuclear option: remove ALL docker data except running containers
|
||||
docker system prune -af --volumes 2>/dev/null || true
|
||||
log "Ran docker system prune -af --volumes"
|
||||
|
||||
# Clear entire action cache
|
||||
if [ -d "$CACHE_DIR" ]; then
|
||||
rm -rf "${CACHE_DIR:?}/"*
|
||||
log "Cleared entire action cache"
|
||||
fi
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
log "After emergency cleanup: ${usage}%"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
log "Cleanup complete. Disk usage: ${usage}%"
|
||||
|
||||
# Report top space consumers for diagnostics
|
||||
log "Top 10 directories under /var:"
|
||||
du -sh /var/*/ 2>/dev/null | sort -rh | head -10 | while read -r line; do
|
||||
log " $line"
|
||||
done
|
||||
10
.gitea/runner/cleanup.timer
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Run CI runner cleanup every 30 minutes
|
||||
|
||||
[Timer]
|
||||
OnBootSec=5min
|
||||
OnUnitActiveSec=30min
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -22,6 +22,17 @@ jobs:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Free disk space
|
||||
run: |
|
||||
echo "=== Disk usage before cleanup ==="
|
||||
df -h /
|
||||
rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache 2>/dev/null || true
|
||||
rm -rf /usr/local/share/boost /usr/share/swift 2>/dev/null || true
|
||||
apt-get autoremove -y 2>/dev/null || true
|
||||
apt-get clean 2>/dev/null || true
|
||||
echo "=== Disk usage after cleanup ==="
|
||||
df -h /
|
||||
|
||||
- name: Install system prerequisites
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -36,8 +47,12 @@ jobs:
|
||||
submodules: recursive
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Fetch tags (for git describe)
|
||||
run: git fetch --tags --no-recurse-submodules origin
|
||||
- name: Fetch latest tag (for git describe)
|
||||
run: |
|
||||
latest_tag=$(git ls-remote --tags --sort=-v:refname origin 'refs/tags/v*' | grep -v '\^{}' | head -n1 | awk '{print $2}')
|
||||
if [ -n "$latest_tag" ]; then
|
||||
git fetch --no-recurse-submodules --force --depth=1 origin "+${latest_tag}:${latest_tag}"
|
||||
fi
|
||||
|
||||
- name: Install pixi
|
||||
run: |
|
||||
@@ -46,12 +61,16 @@ jobs:
|
||||
export PATH="$HOME/.pixi/bin:$PATH"
|
||||
pixi --version
|
||||
|
||||
- name: Compute cache date key
|
||||
id: cache-date
|
||||
run: echo "date=$(date -u +%Y%m%d)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: https://github.com/actions/cache/restore@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-build-${{ github.ref_name }}-${{ github.sha }}
|
||||
key: ccache-build-${{ github.ref_name }}-${{ steps.cache-date.outputs.date }}
|
||||
restore-keys: |
|
||||
ccache-build-${{ github.ref_name }}-
|
||||
ccache-build-main-
|
||||
@@ -60,6 +79,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p $CCACHE_DIR
|
||||
pixi run ccache -z
|
||||
pixi run ccache -p
|
||||
|
||||
- name: Configure (CMake)
|
||||
run: pixi run cmake --preset conda-linux-release
|
||||
@@ -71,11 +91,11 @@ jobs:
|
||||
run: pixi run ccache -s
|
||||
|
||||
- name: Save ccache
|
||||
if: always()
|
||||
if: always() && steps.ccache-restore.outputs.cache-hit != 'true'
|
||||
uses: https://github.com/actions/cache/save@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-build-${{ github.ref_name }}-${{ github.sha }}
|
||||
key: ccache-build-${{ github.ref_name }}-${{ steps.cache-date.outputs.date }}
|
||||
|
||||
- name: Run C++ unit tests
|
||||
continue-on-error: true
|
||||
|
||||
@@ -3,7 +3,7 @@ name: Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
tags: ["v*", "latest"]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
@@ -31,6 +31,18 @@ jobs:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Free disk space
|
||||
run: |
|
||||
echo "=== Disk usage before cleanup ==="
|
||||
df -h /
|
||||
# Remove pre-installed bloat common in runner images
|
||||
rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache 2>/dev/null || true
|
||||
rm -rf /usr/local/share/boost /usr/share/swift 2>/dev/null || true
|
||||
apt-get autoremove -y 2>/dev/null || true
|
||||
apt-get clean 2>/dev/null || true
|
||||
echo "=== Disk usage after cleanup ==="
|
||||
df -h /
|
||||
|
||||
- name: Install system prerequisites
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -45,8 +57,12 @@ jobs:
|
||||
submodules: recursive
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags --no-recurse-submodules origin
|
||||
- name: Fetch latest tag (for git describe)
|
||||
run: |
|
||||
latest_tag=$(git ls-remote --tags --sort=-v:refname origin 'refs/tags/v*' | grep -v '\^{}' | head -n1 | awk '{print $2}')
|
||||
if [ -n "$latest_tag" ]; then
|
||||
git fetch --no-recurse-submodules --force --depth=1 origin "+${latest_tag}:${latest_tag}"
|
||||
fi
|
||||
|
||||
- name: Install pixi
|
||||
run: |
|
||||
@@ -55,20 +71,26 @@ jobs:
|
||||
export PATH="$HOME/.pixi/bin:$PATH"
|
||||
pixi --version
|
||||
|
||||
- name: Compute cache date key
|
||||
id: cache-date
|
||||
run: echo "date=$(date -u +%Y%m%d)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: https://github.com/actions/cache/restore@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-release-linux-${{ github.sha }}
|
||||
key: ccache-release-linux-${{ steps.cache-date.outputs.date }}
|
||||
restore-keys: |
|
||||
ccache-release-linux-
|
||||
ccache-build-main-
|
||||
|
||||
- name: Prepare ccache
|
||||
run: |
|
||||
mkdir -p $CCACHE_DIR
|
||||
# Ensure ccache is accessible to rattler-build's subprocess
|
||||
export PATH="$(pixi run bash -c 'echo $PATH')"
|
||||
pixi run ccache -z
|
||||
pixi run ccache -p
|
||||
|
||||
- name: Build release package (AppImage)
|
||||
working-directory: package/rattler-build
|
||||
@@ -80,11 +102,19 @@ jobs:
|
||||
run: pixi run ccache -s
|
||||
|
||||
- name: Save ccache
|
||||
if: always()
|
||||
if: always() && steps.ccache-restore.outputs.cache-hit != 'true'
|
||||
uses: https://github.com/actions/cache/save@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-release-linux-${{ github.sha }}
|
||||
key: ccache-release-linux-${{ steps.cache-date.outputs.date }}
|
||||
|
||||
- name: Clean up intermediate build files
|
||||
run: |
|
||||
# Remove pixi package cache and build work dirs to free space for .deb
|
||||
rm -rf package/rattler-build/.pixi/build 2>/dev/null || true
|
||||
find /root/.cache/rattler -type f -delete 2>/dev/null || true
|
||||
echo "=== Disk usage after cleanup ==="
|
||||
df -h /
|
||||
|
||||
- name: Build .deb package
|
||||
run: |
|
||||
@@ -105,7 +135,7 @@ jobs:
|
||||
with:
|
||||
name: release-linux
|
||||
path: |
|
||||
package/rattler-build/linux/*.AppImage
|
||||
package/rattler-build/linux/FreeCAD_*.AppImage
|
||||
package/rattler-build/linux/*.deb
|
||||
package/rattler-build/linux/*-SHA256.txt
|
||||
package/rattler-build/linux/*.sha256
|
||||
@@ -113,174 +143,176 @@ jobs:
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# macOS: DMG (Intel + Apple Silicon)
|
||||
# TODO: Re-enable when macOS runners are available or cross-compilation is set up
|
||||
# ---------------------------------------------------------------------------
|
||||
build-macos:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: macos-13
|
||||
arch: x86_64
|
||||
- runner: macos-14
|
||||
arch: arm64
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache-kindred-create
|
||||
CCACHE_COMPRESS: "true"
|
||||
CCACHE_COMPRESSLEVEL: "6"
|
||||
CCACHE_MAXSIZE: "4G"
|
||||
CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
BUILD_TAG: ${{ github.ref_name || inputs.tag }}
|
||||
CFLAGS: "-O3"
|
||||
CXXFLAGS: "-O3"
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: https://github.com/actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags --no-recurse-submodules origin
|
||||
|
||||
- name: Install pixi
|
||||
run: |
|
||||
curl -fsSL https://pixi.sh/install.sh | bash
|
||||
echo "$HOME/.pixi/bin" >> $GITHUB_PATH
|
||||
export PATH="$HOME/.pixi/bin:$PATH"
|
||||
pixi --version
|
||||
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: https://github.com/actions/cache/restore@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-release-macos-${{ matrix.arch }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-release-macos-${{ matrix.arch }}-
|
||||
|
||||
- name: Prepare ccache
|
||||
run: |
|
||||
mkdir -p $CCACHE_DIR
|
||||
pixi run ccache -z
|
||||
|
||||
- name: Build release package (DMG)
|
||||
working-directory: package/rattler-build
|
||||
run: |
|
||||
pixi install
|
||||
pixi run -e package create_bundle
|
||||
|
||||
- name: Show ccache statistics
|
||||
run: pixi run ccache -s
|
||||
|
||||
- name: Save ccache
|
||||
if: always()
|
||||
uses: https://github.com/actions/cache/save@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-release-macos-${{ matrix.arch }}-${{ github.sha }}
|
||||
|
||||
- name: List built artifacts
|
||||
run: |
|
||||
echo "=== macOS ${{ matrix.arch }} release artifacts ==="
|
||||
ls -lah package/rattler-build/osx/*.dmg* 2>/dev/null || true
|
||||
|
||||
- name: Upload macOS artifacts
|
||||
uses: https://github.com/actions/upload-artifact@v3
|
||||
with:
|
||||
name: release-macos-${{ matrix.arch }}
|
||||
path: |
|
||||
package/rattler-build/osx/*.dmg
|
||||
package/rattler-build/osx/*-SHA256.txt
|
||||
if-no-files-found: error
|
||||
# build-macos:
|
||||
# strategy:
|
||||
# fail-fast: false
|
||||
# matrix:
|
||||
# include:
|
||||
# - runner: macos-13
|
||||
# arch: x86_64
|
||||
# - runner: macos-14
|
||||
# arch: arm64
|
||||
#
|
||||
# runs-on: ${{ matrix.runner }}
|
||||
#
|
||||
# env:
|
||||
# CCACHE_DIR: /tmp/ccache-kindred-create
|
||||
# CCACHE_COMPRESS: "true"
|
||||
# CCACHE_COMPRESSLEVEL: "6"
|
||||
# CCACHE_MAXSIZE: "4G"
|
||||
# CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
|
||||
# CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
# BUILD_TAG: ${{ github.ref_name || inputs.tag }}
|
||||
# CFLAGS: "-O3"
|
||||
# CXXFLAGS: "-O3"
|
||||
#
|
||||
# steps:
|
||||
# - name: Checkout repository
|
||||
# uses: https://github.com/actions/checkout@v4
|
||||
# with:
|
||||
# submodules: recursive
|
||||
# fetch-depth: 1
|
||||
#
|
||||
# - name: Fetch tags
|
||||
# run: git fetch --tags --force --no-recurse-submodules origin
|
||||
#
|
||||
# - name: Install pixi
|
||||
# run: |
|
||||
# curl -fsSL https://pixi.sh/install.sh | bash
|
||||
# echo "$HOME/.pixi/bin" >> $GITHUB_PATH
|
||||
# export PATH="$HOME/.pixi/bin:$PATH"
|
||||
# pixi --version
|
||||
#
|
||||
# - name: Restore ccache
|
||||
# id: ccache-restore
|
||||
# uses: https://github.com/actions/cache/restore@v4
|
||||
# with:
|
||||
# path: /tmp/ccache-kindred-create
|
||||
# key: ccache-release-macos-${{ matrix.arch }}-${{ github.sha }}
|
||||
# restore-keys: |
|
||||
# ccache-release-macos-${{ matrix.arch }}-
|
||||
#
|
||||
# - name: Prepare ccache
|
||||
# run: |
|
||||
# mkdir -p $CCACHE_DIR
|
||||
# pixi run ccache -z
|
||||
#
|
||||
# - name: Build release package (DMG)
|
||||
# working-directory: package/rattler-build
|
||||
# run: |
|
||||
# pixi install
|
||||
# pixi run -e package create_bundle
|
||||
#
|
||||
# - name: Show ccache statistics
|
||||
# run: pixi run ccache -s
|
||||
#
|
||||
# - name: Save ccache
|
||||
# if: always()
|
||||
# uses: https://github.com/actions/cache/save@v4
|
||||
# with:
|
||||
# path: /tmp/ccache-kindred-create
|
||||
# key: ccache-release-macos-${{ matrix.arch }}-${{ github.sha }}
|
||||
#
|
||||
# - name: List built artifacts
|
||||
# run: |
|
||||
# echo "=== macOS ${{ matrix.arch }} release artifacts ==="
|
||||
# ls -lah package/rattler-build/osx/*.dmg* 2>/dev/null || true
|
||||
#
|
||||
# - name: Upload macOS artifacts
|
||||
# uses: https://github.com/actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: release-macos-${{ matrix.arch }}
|
||||
# path: |
|
||||
# package/rattler-build/osx/*.dmg
|
||||
# package/rattler-build/osx/*-SHA256.txt
|
||||
# if-no-files-found: error
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Windows: .exe installer + .7z archive
|
||||
# TODO: Re-enable when Windows runners are available or cross-compilation is set up
|
||||
# ---------------------------------------------------------------------------
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
CCACHE_DIR: C:\ccache-kindred-create
|
||||
CCACHE_COMPRESS: "true"
|
||||
CCACHE_COMPRESSLEVEL: "6"
|
||||
CCACHE_MAXSIZE: "4G"
|
||||
CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
BUILD_TAG: ${{ github.ref_name || inputs.tag }}
|
||||
CFLAGS: "/O2"
|
||||
CXXFLAGS: "/O2"
|
||||
MAKE_INSTALLER: "true"
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: https://github.com/actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Fetch tags
|
||||
shell: bash
|
||||
run: git fetch --tags --no-recurse-submodules origin
|
||||
|
||||
- name: Install pixi
|
||||
shell: bash
|
||||
run: |
|
||||
curl -fsSL https://pixi.sh/install.sh | bash
|
||||
echo "$HOME/.pixi/bin" >> $GITHUB_PATH
|
||||
export PATH="$HOME/.pixi/bin:$PATH"
|
||||
pixi --version
|
||||
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: https://github.com/actions/cache/restore@v4
|
||||
with:
|
||||
path: C:\ccache-kindred-create
|
||||
key: ccache-release-windows-${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-release-windows-
|
||||
|
||||
- name: Build release package
|
||||
shell: bash
|
||||
working-directory: package/rattler-build
|
||||
run: |
|
||||
pixi install
|
||||
pixi run -e package create_bundle
|
||||
|
||||
- name: Save ccache
|
||||
if: always()
|
||||
uses: https://github.com/actions/cache/save@v4
|
||||
with:
|
||||
path: C:\ccache-kindred-create
|
||||
key: ccache-release-windows-${{ github.sha }}
|
||||
|
||||
- name: List built artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== Windows release artifacts ==="
|
||||
ls -lah package/rattler-build/windows/*.7z* 2>/dev/null || true
|
||||
ls -lah package/rattler-build/windows/*.exe 2>/dev/null || true
|
||||
ls -lah package/rattler-build/windows/*-SHA256.txt 2>/dev/null || true
|
||||
|
||||
- name: Upload Windows artifacts
|
||||
uses: https://github.com/actions/upload-artifact@v3
|
||||
with:
|
||||
name: release-windows
|
||||
path: |
|
||||
package/rattler-build/windows/*.7z
|
||||
package/rattler-build/windows/*.exe
|
||||
package/rattler-build/windows/*-SHA256.txt
|
||||
if-no-files-found: error
|
||||
# build-windows:
|
||||
# runs-on: windows-latest
|
||||
#
|
||||
# env:
|
||||
# CCACHE_DIR: C:\ccache-kindred-create
|
||||
# CCACHE_COMPRESS: "true"
|
||||
# CCACHE_COMPRESSLEVEL: "6"
|
||||
# CCACHE_MAXSIZE: "4G"
|
||||
# CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
|
||||
# CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
# BUILD_TAG: ${{ github.ref_name || inputs.tag }}
|
||||
# CFLAGS: "/O2"
|
||||
# CXXFLAGS: "/O2"
|
||||
# MAKE_INSTALLER: "true"
|
||||
#
|
||||
# steps:
|
||||
# - name: Checkout repository
|
||||
# uses: https://github.com/actions/checkout@v4
|
||||
# with:
|
||||
# submodules: recursive
|
||||
# fetch-depth: 1
|
||||
#
|
||||
# - name: Fetch tags
|
||||
# shell: bash
|
||||
# run: git fetch --tags --force --no-recurse-submodules origin
|
||||
#
|
||||
# - name: Install pixi
|
||||
# shell: bash
|
||||
# run: |
|
||||
# curl -fsSL https://pixi.sh/install.sh | bash
|
||||
# echo "$HOME/.pixi/bin" >> $GITHUB_PATH
|
||||
# export PATH="$HOME/.pixi/bin:$PATH"
|
||||
# pixi --version
|
||||
#
|
||||
# - name: Restore ccache
|
||||
# id: ccache-restore
|
||||
# uses: https://github.com/actions/cache/restore@v4
|
||||
# with:
|
||||
# path: C:\ccache-kindred-create
|
||||
# key: ccache-release-windows-${{ github.sha }}
|
||||
# restore-keys: |
|
||||
# ccache-release-windows-
|
||||
#
|
||||
# - name: Build release package
|
||||
# shell: bash
|
||||
# working-directory: package/rattler-build
|
||||
# run: |
|
||||
# pixi install
|
||||
# pixi run -e package create_bundle
|
||||
#
|
||||
# - name: Save ccache
|
||||
# if: always()
|
||||
# uses: https://github.com/actions/cache/save@v4
|
||||
# with:
|
||||
# path: C:\ccache-kindred-create
|
||||
# key: ccache-release-windows-${{ github.sha }}
|
||||
#
|
||||
# - name: List built artifacts
|
||||
# shell: bash
|
||||
# run: |
|
||||
# echo "=== Windows release artifacts ==="
|
||||
# ls -lah package/rattler-build/windows/*.7z* 2>/dev/null || true
|
||||
# ls -lah package/rattler-build/windows/*.exe 2>/dev/null || true
|
||||
# ls -lah package/rattler-build/windows/*-SHA256.txt 2>/dev/null || true
|
||||
#
|
||||
# - name: Upload Windows artifacts
|
||||
# uses: https://github.com/actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: release-windows
|
||||
# path: |
|
||||
# package/rattler-build/windows/*.7z
|
||||
# package/rattler-build/windows/*.exe
|
||||
# package/rattler-build/windows/*-SHA256.txt
|
||||
# if-no-files-found: error
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Create Gitea release from all platform artifacts
|
||||
# ---------------------------------------------------------------------------
|
||||
publish-release:
|
||||
needs: [build-linux, build-macos, build-windows]
|
||||
needs: [build-linux] # TODO: Add build-macos, build-windows when runners are available
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
@@ -313,24 +345,82 @@ jobs:
|
||||
ls -lah release/
|
||||
|
||||
- name: Create release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: release/*
|
||||
title: "Kindred Create ${{ env.BUILD_TAG }}"
|
||||
body: |
|
||||
## Kindred Create ${{ env.BUILD_TAG }}
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
GITEA_URL: ${{ github.server_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
TAG="${BUILD_TAG}"
|
||||
|
||||
### Downloads
|
||||
# Build JSON payload entirely in Python to avoid shell/Python type mismatches
|
||||
PAYLOAD=$(python3 -c "
|
||||
import json, re
|
||||
tag = '${TAG}'
|
||||
prerelease = bool(re.search(r'(rc|beta|alpha)', tag))
|
||||
body = '''## Kindred Create {tag}
|
||||
|
||||
| Platform | File |
|
||||
|----------|------|
|
||||
| Linux (AppImage) | `KindredCreate-*-Linux-x86_64.AppImage` |
|
||||
| Linux (Debian/Ubuntu) | `kindred-create_*.deb` |
|
||||
| macOS (Intel) | `KindredCreate-*-macOS-x86_64.dmg` |
|
||||
| macOS (Apple Silicon) | `KindredCreate-*-macOS-arm64.dmg` |
|
||||
| Windows (Installer) | `KindredCreate-*-Windows-x86_64-installer.exe` |
|
||||
| Windows (Portable) | `KindredCreate-*-Windows-x86_64.7z` |
|
||||
### Downloads
|
||||
|
||||
SHA256 checksums are provided alongside each artifact.
|
||||
prerelease: ${{ contains(github.ref_name, 'rc') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }}
|
||||
api_key: ${{ secrets.RELEASE_TOKEN }}
|
||||
| Platform | File |
|
||||
|----------|------|
|
||||
| Linux (AppImage) | \`KindredCreate-*-Linux-x86_64.AppImage\` |
|
||||
| Linux (Debian/Ubuntu) | \`kindred-create_*.deb\` |
|
||||
|
||||
*macOS and Windows builds are not yet available.*
|
||||
|
||||
SHA256 checksums are provided alongside each artifact.'''.format(tag=tag)
|
||||
print(json.dumps({
|
||||
'tag_name': tag,
|
||||
'name': f'Kindred Create {tag}',
|
||||
'body': body,
|
||||
'prerelease': prerelease,
|
||||
}))
|
||||
")
|
||||
|
||||
# Delete existing release for this tag (if any) so we can recreate
|
||||
existing=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}")
|
||||
if [ "$existing" = "200" ]; then
|
||||
release_id=$(curl -s \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}" | \
|
||||
python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
||||
curl -s -X DELETE \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/${release_id}"
|
||||
echo "Deleted existing release ${release_id} for tag ${TAG}"
|
||||
fi
|
||||
|
||||
# Create release
|
||||
response=$(curl -s -w "\n%{http_code}" -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$PAYLOAD" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases")
|
||||
http_code=$(echo "$response" | tail -1)
|
||||
body=$(echo "$response" | sed '$d')
|
||||
|
||||
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
|
||||
echo "::error::Failed to create release (HTTP ${http_code}): ${body}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
release_id=$(echo "$body" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
||||
echo "Created release ${release_id}"
|
||||
|
||||
# Upload assets
|
||||
for file in release/*; do
|
||||
filename=$(basename "$file")
|
||||
echo "Uploading ${filename}..."
|
||||
upload_resp=$(curl -s -w "\n%{http_code}" -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-F "attachment=@${file}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/${release_id}/assets?name=${filename}")
|
||||
upload_code=$(echo "$upload_resp" | tail -1)
|
||||
if [ "$upload_code" -lt 200 ] || [ "$upload_code" -ge 300 ]; then
|
||||
echo "::warning::Failed to upload ${filename} (HTTP ${upload_code})"
|
||||
else
|
||||
echo " done."
|
||||
fi
|
||||
done
|
||||
|
||||
2
.gitmodules
vendored
@@ -15,4 +15,4 @@
|
||||
url = https://git.kindred-systems.com/forbes/ztools.git
|
||||
[submodule "mods/silo"]
|
||||
path = mods/silo
|
||||
url = https://git.kindred-systems.com/kindred/silo.git
|
||||
url = https://git.kindred-systems.com/kindred/silo-mod.git
|
||||
|
||||
58
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Architecture
|
||||
|
||||
## Bootstrap flow
|
||||
|
||||
```
|
||||
FreeCAD startup
|
||||
└─ src/Mod/Create/Init.py
|
||||
└─ setup_kindred_addons()
|
||||
├─ exec(mods/ztools/ztools/Init.py)
|
||||
└─ exec(mods/silo/freecad/Init.py)
|
||||
|
||||
└─ src/Mod/Create/InitGui.py
|
||||
├─ setup_kindred_workbenches()
|
||||
│ ├─ exec(mods/ztools/ztools/InitGui.py)
|
||||
│ │ ├─ registers ZToolsWorkbench
|
||||
│ │ └─ installs _ZToolsPartDesignManipulator (global)
|
||||
│ └─ exec(mods/silo/freecad/InitGui.py)
|
||||
│ └─ registers SiloWorkbench
|
||||
└─ Deferred setup (QTimer):
|
||||
├─ 1500ms: _register_silo_origin() → registers Silo FileOrigin
|
||||
├─ 2000ms: _setup_silo_auth_panel() → "Database Auth" dock
|
||||
├─ 3000ms: _check_silo_first_start() → settings prompt
|
||||
└─ 4000ms: _setup_silo_activity_panel() → "Database Activity" dock
|
||||
```
|
||||
|
||||
## Key source layout
|
||||
|
||||
```
|
||||
src/Mod/Create/ Kindred bootstrap module (Python)
|
||||
├── Init.py Adds mods/ addon paths, loads Init.py files
|
||||
└── InitGui.py Loads workbenches, installs Silo manipulators
|
||||
|
||||
src/Gui/FileOrigin.h/.cpp FileOrigin base class + LocalFileOrigin
|
||||
src/Gui/CommandOrigin.cpp Origin_Commit/Pull/Push/Info/BOM commands
|
||||
src/Gui/OriginManager.h/.cpp Origin lifecycle management
|
||||
src/Gui/OriginSelectorWidget.h/.cpp UI for origin selection
|
||||
|
||||
mods/ztools/ [submodule] ztools workbench
|
||||
├── ztools/InitGui.py ZToolsWorkbench + PartDesign manipulator
|
||||
├── ztools/ztools/
|
||||
│ ├── commands/ Datum, pattern, pocket, assembly, spreadsheet
|
||||
│ ├── datums/core.py Datum creation via Part::AttachExtension
|
||||
│ └── resources/ Icons, theme utilities
|
||||
└── CatppuccinMocha/ Theme preference pack (QSS)
|
||||
|
||||
mods/silo/ [submodule -> silo-mod.git] FreeCAD workbench
|
||||
├── silo-client/ [submodule -> silo-client.git] shared API client
|
||||
│ └── silo_client/ SiloClient, SiloSettings, CATEGORY_NAMES
|
||||
└── freecad/ FreeCAD workbench (Python)
|
||||
├── InitGui.py SiloWorkbench
|
||||
├── silo_commands.py Commands + FreeCADSiloSettings adapter
|
||||
└── silo_origin.py FileOrigin backend for Silo
|
||||
|
||||
src/Gui/Stylesheets/ QSS themes and SVG assets
|
||||
resources/preferences/ Canonical preference pack (KindredCreate)
|
||||
```
|
||||
|
||||
See [INTEGRATION_PLAN.md](INTEGRATION_PLAN.md) for architecture layers and phase status.
|
||||
@@ -7,7 +7,7 @@ Kindred Create uses Gitea Actions for continuous integration and release builds.
|
||||
| Workflow | Trigger | Purpose | Artifacts |
|
||||
|----------|---------|---------|-----------|
|
||||
| `build.yml` | Push to `main`, pull requests | Build + test | Linux tarball |
|
||||
| `release.yml` | Tags matching `v*` | Multi-platform release | AppImage, .deb, .dmg, .exe, .7z |
|
||||
| `release.yml` | Tags matching `v*` or `latest` | Release build | AppImage, .deb |
|
||||
|
||||
All builds run on public runners in dockerized mode. No host-mode or internal infrastructure is required.
|
||||
|
||||
@@ -34,14 +34,16 @@ Runs on every push to `main` and on pull requests. Builds the project in an Ubun
|
||||
|
||||
### Caching
|
||||
|
||||
ccache is persisted between builds using `actions/cache`. Cache keys are scoped by branch and commit SHA, with fallback to the branch key then `main`.
|
||||
ccache is persisted between builds using `actions/cache`. Cache keys use a date suffix so entries rotate daily (one save per day per branch). Saves are skipped when the exact key already exists, preventing duplicate entries that fill runner storage.
|
||||
|
||||
```
|
||||
Key: ccache-build-{branch}-{sha}
|
||||
Key: ccache-build-{branch}-{YYYYMMDD}
|
||||
Fallback: ccache-build-{branch}-
|
||||
Fallback: ccache-build-main-
|
||||
```
|
||||
|
||||
Release builds use a separate key namespace (`ccache-release-linux-{YYYYMMDD}`) because they compile with different optimization flags (`-O3`). The rattler-build script (`build.sh`) explicitly sets `CCACHE_DIR` and `CCACHE_BASEDIR` since rattler-build does not forward environment variables from the parent process.
|
||||
|
||||
ccache configuration: 4 GB max, zlib compression level 6, sloppy mode for include timestamps and PCH.
|
||||
|
||||
---
|
||||
@@ -63,17 +65,19 @@ Tags containing `rc`, `beta`, or `alpha` are marked as pre-releases.
|
||||
|
||||
### Platform matrix
|
||||
|
||||
| Job | Runner | Container | Preset | Output |
|
||||
|-----|--------|-----------|--------|--------|
|
||||
| `build-linux` | `ubuntu-latest` | `ubuntu:24.04` | `conda-linux-release` | AppImage, .deb |
|
||||
| `build-macos` (Intel) | `macos-13` | native | `conda-macos-release` | .dmg (x86_64) |
|
||||
| `build-macos` (Apple Silicon) | `macos-14` | native | `conda-macos-release` | .dmg (arm64) |
|
||||
| `build-windows` | `windows-latest` | native | `conda-windows-release` | .exe (NSIS), .7z |
|
||||
| Job | Runner | Container | Preset | Output | Status |
|
||||
|-----|--------|-----------|--------|--------|--------|
|
||||
| `build-linux` | `ubuntu-latest` | `ubuntu:24.04` | `conda-linux-release` | AppImage, .deb | Active |
|
||||
| `build-macos` (Intel) | `macos-13` | native | `conda-macos-release` | .dmg (x86_64) | Disabled |
|
||||
| `build-macos` (Apple Silicon) | `macos-14` | native | `conda-macos-release` | .dmg (arm64) | Disabled |
|
||||
| `build-windows` | `windows-latest` | native | `conda-windows-release` | .exe (NSIS), .7z | Disabled |
|
||||
|
||||
All four jobs run concurrently. After all succeed, `publish-release` collects artifacts and creates the Gitea release.
|
||||
Only the Linux build is currently active. macOS and Windows jobs are defined but commented out pending runner availability or cross-compilation support. After `build-linux` succeeds, `publish-release` collects artifacts and creates the Gitea release.
|
||||
|
||||
### Linux build
|
||||
|
||||
Both workflows start with a disk cleanup step that removes pre-installed bloat (dotnet, Android SDK, etc.) to free space for the build.
|
||||
|
||||
Uses the rattler-build packaging pipeline:
|
||||
|
||||
1. `pixi install` in `package/rattler-build/`
|
||||
@@ -81,9 +85,10 @@ Uses the rattler-build packaging pipeline:
|
||||
3. The bundle script:
|
||||
- Copies the pixi conda environment to an AppDir
|
||||
- Strips unnecessary files (includes, static libs, cmake files, `__pycache__`)
|
||||
- Downloads `appimagetool` and creates a squashfs AppImage (zstd compressed)
|
||||
- Generates SHA256 checksums
|
||||
4. `package/debian/build-deb.sh` builds a .deb from the AppDir
|
||||
- Downloads `appimagetool`, extracts it with `--appimage-extract` (FUSE unavailable in containers), and runs via `squashfs-root/AppRun`
|
||||
- Creates a squashfs AppImage (zstd compressed) with SHA256 checksums
|
||||
4. Intermediate build files are cleaned up to free space for the .deb step
|
||||
5. `package/debian/build-deb.sh` builds a .deb from the AppDir
|
||||
- Installs to `/opt/kindred-create/` with wrapper scripts in `/usr/bin/`
|
||||
- Sets up LD_LIBRARY_PATH, QT_PLUGIN_PATH, PYTHONPATH in wrappers
|
||||
- Creates desktop entry, MIME types, AppStream metainfo
|
||||
@@ -123,10 +128,15 @@ Builds natively on Windows runner:
|
||||
|
||||
`publish-release` runs after all platform builds succeed:
|
||||
|
||||
1. Downloads all artifacts from `build-linux`, `build-macos`, `build-windows`
|
||||
2. Collects release files (AppImage, .deb, .dmg, .7z, .exe, checksums)
|
||||
3. Creates a Gitea release via `gitea.com/actions/release-action`
|
||||
4. Requires `RELEASE_TOKEN` secret with repository write permissions
|
||||
1. Downloads all artifacts from completed build jobs
|
||||
2. Collects release files (AppImage, .deb, checksums) into a `release/` directory
|
||||
3. Deletes any existing Gitea release for the same tag (allows re-running)
|
||||
4. Creates a new Gitea release via the REST API (`/api/v1/repos/{owner}/{repo}/releases`)
|
||||
5. Uploads each artifact as a release attachment via the API
|
||||
|
||||
The release payload (tag name, body, prerelease flag) is built entirely in Python to avoid shell/Python type mismatches. Tags containing `rc`, `beta`, or `alpha` are automatically marked as pre-releases.
|
||||
|
||||
Requires `RELEASE_TOKEN` secret with repository write permissions.
|
||||
|
||||
---
|
||||
|
||||
@@ -174,6 +184,27 @@ container:
|
||||
network: bridge
|
||||
```
|
||||
|
||||
### Runner cleanup daemon
|
||||
|
||||
A cleanup script at `.gitea/runner/cleanup.sh` prevents disk exhaustion on self-hosted runners. It uses a tiered approach based on disk usage thresholds:
|
||||
|
||||
| Threshold | Action |
|
||||
|-----------|--------|
|
||||
| 70% | Docker cleanup (stopped containers, dangling images, build cache) |
|
||||
| 80% | Purge act_runner cache entries older than 7 days, clean inactive workspaces |
|
||||
| 90% | System cleanup (apt cache, old logs, journal vacuum to 100 MB) |
|
||||
| 95% | Emergency: remove all act_runner cache entries and Docker images |
|
||||
|
||||
Install via the provided systemd units (`.gitea/runner/cleanup.service` and `.gitea/runner/cleanup.timer`) to run every 30 minutes:
|
||||
|
||||
```bash
|
||||
sudo cp .gitea/runner/cleanup.sh /usr/local/bin/runner-cleanup.sh
|
||||
sudo cp .gitea/runner/cleanup.service /etc/systemd/system/
|
||||
sudo cp .gitea/runner/cleanup.timer /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now cleanup.timer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Secrets
|
||||
@@ -214,11 +245,12 @@ Defined in `CMakePresets.json`. Release builds use:
|
||||
|
||||
### ccache
|
||||
|
||||
Compiler cache is used across all builds to speed up incremental compilation. Cache is persisted between CI runs via `actions/cache`. Configuration:
|
||||
Compiler cache is used across all builds to speed up incremental compilation. Cache is persisted between CI runs via `actions/cache` with date-based key rotation. Configuration:
|
||||
|
||||
- Max size: 4 GB
|
||||
- Compression: zlib level 6
|
||||
- Sloppy mode: include timestamps, PCH defines, time macros
|
||||
- `CCACHE_BASEDIR`: set to workspace root (build workflow) or `$SRC_DIR` (rattler-build) for path normalization across runs
|
||||
|
||||
---
|
||||
|
||||
@@ -243,9 +275,12 @@ The Docker container installs only minimal dependencies. If a new dependency is
|
||||
ccache misses spike when:
|
||||
- The compiler version changes (pixi update)
|
||||
- CMake presets change configuration flags
|
||||
- The cache key doesn't match (new branch, force-pushed SHA)
|
||||
- First build of the day (date-based key rotates daily)
|
||||
- New branch without a prior cache (falls back to `main` cache)
|
||||
|
||||
Check `pixi run ccache -s` output for hit/miss ratios.
|
||||
For release builds, ensure `build.sh` is correctly setting `CCACHE_DIR=/tmp/ccache-kindred-create` -- rattler-build does not forward environment variables from the workflow, so ccache config must be set inside the script.
|
||||
|
||||
Check `pixi run ccache -s` output (printed in the "Show ccache statistics" step) for hit/miss ratios. The "Prepare ccache" step also prints the full ccache configuration via `ccache -p`.
|
||||
|
||||
### Submodule checkout fails
|
||||
|
||||
|
||||
110
docs/COMPONENTS.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Components
|
||||
|
||||
## ztools workbench
|
||||
|
||||
**Registered commands (9):**
|
||||
|
||||
| Command | Function |
|
||||
|---------|----------|
|
||||
| `ZTools_DatumCreator` | Create datum planes, axes, points (16 modes) |
|
||||
| `ZTools_DatumManager` | Manage existing datum objects |
|
||||
| `ZTools_EnhancedPocket` | Flip-side pocket (cut outside sketch profile) |
|
||||
| `ZTools_RotatedLinearPattern` | Linear pattern with incremental rotation |
|
||||
| `ZTools_AssemblyLinearPattern` | Pattern assembly components linearly |
|
||||
| `ZTools_AssemblyPolarPattern` | Pattern assembly components around axis |
|
||||
| `ZTools_SpreadsheetStyle{Bold,Italic,Underline}` | Text style toggles |
|
||||
| `ZTools_SpreadsheetAlign{Left,Center,Right}` | Cell alignment |
|
||||
| `ZTools_Spreadsheet{BgColor,TextColor,QuickAlias}` | Colors and alias creation |
|
||||
|
||||
**PartDesign integration** via `_ZToolsPartDesignManipulator`:
|
||||
- `ZTools_DatumCreator`, `ZTools_DatumManager` → "Part Design Helper Features" toolbar
|
||||
- `ZTools_EnhancedPocket` → "Part Design Modeling Features" toolbar
|
||||
- `ZTools_RotatedLinearPattern` → "Part Design Transformation Features" toolbar
|
||||
- Same commands inserted into Part Design menu after `PartDesign_Boolean`
|
||||
|
||||
**Datum types (7):** offset_from_face, offset_from_plane, midplane, 3_points, normal_to_edge, angled, tangent_to_cylinder. All except tangent_to_cylinder use `Part::AttachExtension` for automatic parametric updates.
|
||||
|
||||
---
|
||||
|
||||
## Origin commands (C++)
|
||||
|
||||
The Origin abstraction (`src/Gui/FileOrigin.h`) provides a backend-agnostic interface for document storage. Commands delegate to the active `FileOrigin` implementation (currently `LocalFileOrigin` for local files, `SiloOrigin` via `mods/silo/freecad/silo_origin.py` for Silo-tracked documents).
|
||||
|
||||
**Registered commands (5):**
|
||||
|
||||
| Command | Function | Icon |
|
||||
|---------|----------|------|
|
||||
| `Origin_Commit` | Commit changes as a new revision | `silo-commit` |
|
||||
| `Origin_Pull` | Pull a specific revision from the origin | `silo-pull` |
|
||||
| `Origin_Push` | Push local changes to the origin | `silo-push` |
|
||||
| `Origin_Info` | Show document information from origin | `silo-info` |
|
||||
| `Origin_BOM` | Show Bill of Materials for this document | `silo-bom` |
|
||||
|
||||
These appear in the File menu and "Origin Tools" toolbar across all workbenches (see `src/Gui/Workbench.cpp`).
|
||||
|
||||
---
|
||||
|
||||
## Silo workbench
|
||||
|
||||
**Registered commands (14):**
|
||||
|
||||
| Command | Function |
|
||||
|---------|----------|
|
||||
| `Silo_New` | Create new Silo-tracked document |
|
||||
| `Silo_Open` | Open file from Silo database |
|
||||
| `Silo_Save` | Save to Silo (create revision) |
|
||||
| `Silo_Commit` | Commit current revision |
|
||||
| `Silo_Pull` | Pull latest revision from server |
|
||||
| `Silo_Push` | Push local changes to server |
|
||||
| `Silo_Info` | View item metadata and history |
|
||||
| `Silo_BOM` | Bill of materials dialog (BOM + Where Used) |
|
||||
| `Silo_TagProjects` | Assign project tags |
|
||||
| `Silo_Rollback` | Rollback to previous revision |
|
||||
| `Silo_SetStatus` | Set revision status (draft/review/released/obsolete) |
|
||||
| `Silo_Settings` | Configure API URL, projects dir, SSL certificates |
|
||||
| `Silo_Auth` | Login/logout authentication panel |
|
||||
|
||||
**Global integration** via the origin system in `src/Gui/`:
|
||||
- File toolbar: `Std_Origin` selector widget + `Std_New`/`Std_Open`/`Std_Save` (delegate to current origin)
|
||||
- Origin Tools toolbar: `Origin_Commit`/`Origin_Pull`/`Origin_Push`/`Origin_Info`/`Origin_BOM` (auto-disable by capability)
|
||||
- Silo origin registered at startup by `src/Mod/Create/InitGui.py`
|
||||
|
||||
**Server architecture:** Go REST API (38+ routes) + PostgreSQL + MinIO S3. Authentication via local (bcrypt), LDAP, or OIDC backends. See `mods/silo/docs/` for server documentation.
|
||||
|
||||
**LibreOffice Calc extension** ([silo-calc](https://git.kindred-systems.com/kindred/silo-calc.git)): BOM management, item creation, and AI-assisted descriptions via OpenRouter API. Shares the same Silo REST API and auth token system via the shared [silo-client](https://git.kindred-systems.com/kindred/silo-client.git) package.
|
||||
|
||||
---
|
||||
|
||||
## Theme
|
||||
|
||||
**Canonical source:** `resources/preferences/KindredCreate/KindredCreate.qss`
|
||||
|
||||
Four copies must stay in sync:
|
||||
1. `resources/preferences/KindredCreate/KindredCreate.qss` (canonical)
|
||||
2. `src/Gui/Stylesheets/KindredCreate.qss`
|
||||
3. `src/Gui/PreferencePacks/KindredCreate/KindredCreate.qss`
|
||||
4. `mods/ztools/CatppuccinMocha/CatppuccinMocha.qss`
|
||||
|
||||
---
|
||||
|
||||
## Icon infrastructure
|
||||
|
||||
### Qt resource icons (`src/Gui/Icons/`)
|
||||
|
||||
5 `silo-*` SVGs registered in `resource.qrc`, used by C++ Origin commands:
|
||||
|
||||
`silo-bom.svg`, `silo-commit.svg`, `silo-info.svg`, `silo-pull.svg`, `silo-push.svg`
|
||||
|
||||
### Silo module icons (`mods/silo/freecad/resources/icons/`)
|
||||
|
||||
10 SVGs loaded at runtime by the `_icon()` function in `silo_commands.py`:
|
||||
|
||||
`silo-auth.svg`, `silo-bom.svg`, `silo-commit.svg`, `silo-info.svg`, `silo-new.svg`, `silo-open.svg`, `silo-pull.svg`, `silo-push.svg`, `silo-save.svg`, `silo.svg`
|
||||
|
||||
### Missing icons
|
||||
|
||||
3 command icon names have no corresponding SVG file: `silo-tag`, `silo-rollback`, `silo-status`. The `_icon()` function returns an empty string for these, so `Silo_TagProjects`, `Silo_Rollback`, and `Silo_SetStatus` render without toolbar icons.
|
||||
|
||||
### Palette
|
||||
|
||||
All silo-* icons use the Catppuccin Mocha color scheme. See `kindred-icons/README.md` for palette specification and icon design standards.
|
||||
@@ -58,11 +58,11 @@ The Python API provides everything needed for feature creation, command registra
|
||||
|
||||
The Create module is a thin Python loader that:
|
||||
- Adds `mods/` addon paths to `sys.path` and executes their `Init.py`/`InitGui.py` files
|
||||
- Installs `SiloMenuManipulator` for global File menu/toolbar injection
|
||||
- Registers the Silo FileOrigin so the origin selector can offer it at startup
|
||||
- Sets up deferred Silo dock panels (auth, activity) via `QTimer`
|
||||
- Handles first-start configuration
|
||||
|
||||
This layer does not contain C++ code. It uses FreeCAD's `WorkbenchManipulator` API for menu/toolbar injection.
|
||||
This layer does not contain C++ code.
|
||||
|
||||
### Layer 4: Kindred Workbenches -- `mods/`
|
||||
|
||||
@@ -116,9 +116,9 @@ Pure Python workbenches following FreeCAD's addon pattern. Self-contained with `
|
||||
|
||||
**Goal:** Silo commands available globally, not just in the Silo workbench.
|
||||
|
||||
**Implementation:** `SiloMenuManipulator` in `src/Mod/Create/InitGui.py` uses `FreeCADGui.addWorkbenchManipulator()` to inject Silo commands into the File menu and toolbar across all workbenches. `Silo_ToggleMode` provides a one-click swap of Ctrl+O/S/N between standard FreeCAD and Silo file commands.
|
||||
**Implementation:** The unified origin system (`FileOrigin`, `OriginManager`, `OriginSelectorWidget`) in `src/Gui/` delegates all file operations (New/Open/Save) to the selected origin. Standard commands (`Std_New`, `Std_Open`, `Std_Save`) and origin commands (`Origin_Commit`, `Origin_Pull`, `Origin_Push`, `Origin_Info`, `Origin_BOM`) are built into the File toolbar and menu. The Silo workbench no longer has its own toolbar — it only provides a menu with admin/management commands.
|
||||
|
||||
**Dock panels:** Database Auth (1500ms) and Database Activity (4000ms) panels are created via deferred QTimers and docked in the right panel area.
|
||||
**Dock panels:** Database Auth (2000ms) and Database Activity (4000ms) panels are created via deferred QTimers and docked in the right panel area.
|
||||
|
||||
### Phase 6: Build system integration -- PARTIAL
|
||||
|
||||
@@ -134,8 +134,10 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/ztools/ztools
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/ztools/CatppuccinMocha
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/ztools)
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/pkg/freecad/
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/freecad/
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/Silo)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/silo-client/
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/silo-client)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
75
docs/KNOWN_ISSUES.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Known Issues
|
||||
|
||||
## Issues
|
||||
|
||||
### Critical
|
||||
|
||||
1. **QSS duplication.** Four copies of the stylesheet must be kept in sync manually. A build step or symlinks should eliminate this.
|
||||
|
||||
2. **WorkbenchManipulator timing.** The `_ZToolsPartDesignManipulator` appends commands by name. If ZToolsWorkbench hasn't been activated when the user switches to PartDesign, the commands may not be registered. The manipulator API tolerates missing commands silently, but buttons won't appear.
|
||||
|
||||
3. ~~**Silo shortcut persistence.**~~ Resolved. `Silo_ToggleMode` removed; file operations now delegate to the selected origin via the unified origin system.
|
||||
|
||||
### High
|
||||
|
||||
4. **Silo authentication not production-hardened.** Local auth (bcrypt) works end-to-end. LDAP (FreeIPA) and OIDC (Keycloak) backends are coded but depend on infrastructure not yet deployed. FreeCAD client has `Silo_Auth` dock panel for login and API token management. Server has session middleware (`alexedwards/scs`), CSRF protection (`nosurf`), and role-based access control (admin/editor/viewer). Migration `009_auth.sql` adds users, api_tokens, and sessions tables.
|
||||
|
||||
5. **No unit tests.** Zero test coverage for ztools and Silo FreeCAD commands. Silo Go backend also lacks tests.
|
||||
|
||||
6. **Assembly solver datum handling is minimal.** The `findPlacement()` fix in `src/Mod/Assembly/UtilsAssembly.py` extracts placement from `obj.Shape.Faces[0]` for `PartDesign::Plane` and from shape vertex for `PartDesign::Point`. Does not handle empty shapes or non-planar datum objects.
|
||||
|
||||
### Medium
|
||||
|
||||
7. **`Silo_BOM` requires Silo-tracked document.** Depends on `SiloPartNumber` property. Unregistered documents show a warning with no registration path.
|
||||
|
||||
8. **PartDesign menu insertion fragility.** `_ZToolsPartDesignManipulator.modifyMenuBar()` inserts after `PartDesign_Boolean`. If upstream renames this command, insertions silently fail.
|
||||
|
||||
9. **tangent_to_cylinder falls back to manual placement.** TangentPlane MapMode requires a vertex reference not collected by the current UI.
|
||||
|
||||
10. **`delete_bom_entry()` bypasses error normalization.** Uses raw `urllib.request` instead of `SiloClient._request()`.
|
||||
|
||||
11. **Missing Silo icons.** Three commands reference icons that don't exist: `silo-tag.svg` (`Silo_TagProjects`), `silo-rollback.svg` (`Silo_Rollback`), `silo-status.svg` (`Silo_SetStatus`). The `_icon()` function returns an empty string, so these commands render without toolbar icons.
|
||||
|
||||
### Fixed (retain for reference)
|
||||
|
||||
12. **OndselSolver Newton-Raphson convergence.** `NewtonRaphson::isConvergedToNumericalLimit()` compared `dxNorms->at(iterNo)` to itself instead of `dxNorms->at(iterNo - 1)`. This prevented convergence detection on complex assemblies, causing solver exhaustion and "grounded object moved" warnings. Fixed in Kindred fork (`src/3rdParty/OndselSolver`). Needs upstreaming to `FreeCAD/OndselSolver`.
|
||||
|
||||
13. **Assembly solver crash on document restore.** `AssemblyObject::onChanged()` called `updateSolveStatus()` when the Group property changed during document restore, triggering the solver while child objects were still deserializing (SIGSEGV). Fixed with `isRestoring()` and `isPerformingTransaction()` guards at `src/Mod/Assembly/App/AssemblyObject.cpp:143`.
|
||||
|
||||
---
|
||||
|
||||
## Incomplete features
|
||||
|
||||
### Silo
|
||||
|
||||
| Feature | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| Authentication | Local auth complete | LDAP/OIDC backends coded, pending infrastructure |
|
||||
| CSRF protection | Implemented | `nosurf` library on web form routes |
|
||||
| File locking | Not implemented | Needed to prevent concurrent edits |
|
||||
| Odoo ERP integration | Stub only | Returns "not yet implemented" |
|
||||
| Part number date segments | Broken | `formatDate()` returns error |
|
||||
| Location/inventory APIs | Tables exist, no handlers | |
|
||||
| CSV import rollback | Not implemented | `bom_handlers.go` |
|
||||
|
||||
### ztools
|
||||
|
||||
| Feature | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| Tangent-to-cylinder attachment | Manual fallback | No vertex ref in UI |
|
||||
| Angled datum live editing | Incomplete | AttachmentOffset not updated in panel |
|
||||
| Assembly pattern undo | Not implemented | |
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
1. **Authentication hardening** -- Deploy FreeIPA and Keycloak infrastructure. End-to-end test LDAP and OIDC flows. Harden token rotation and session expiry.
|
||||
|
||||
2. **BOM-Assembly bridge** -- Auto-populate Silo BOM from Assembly component links on save.
|
||||
|
||||
3. **File locking** -- Pessimistic locks on `Silo_Open` to prevent concurrent edits. Requires server-side lock table and client-side lock display.
|
||||
|
||||
4. **Build system** -- CMake install rules for `mods/` submodules so packages include ztools and Silo without manual steps.
|
||||
|
||||
5. **Test coverage** -- Unit tests for ztools datum creation, Silo FreeCAD commands, and Go API endpoints.
|
||||
31
docs/OVERVIEW.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Kindred Create
|
||||
|
||||
**Last updated:** 2026-02-07
|
||||
**Branch:** main @ `7bec3d5c3b2`
|
||||
**Kindred Create:** v0.1.0
|
||||
**FreeCAD base:** v1.0.0
|
||||
|
||||
## Documentation
|
||||
|
||||
| Document | Contents |
|
||||
|----------|----------|
|
||||
| [ARCHITECTURE.md](ARCHITECTURE.md) | Bootstrap flow, source layout, submodules |
|
||||
| [COMPONENTS.md](COMPONENTS.md) | ztools, Silo, Origin commands, theme, icons |
|
||||
| [KNOWN_ISSUES.md](KNOWN_ISSUES.md) | Bugs, incomplete features, next steps |
|
||||
| [INTEGRATION_PLAN.md](INTEGRATION_PLAN.md) | Architecture layers, integration phases |
|
||||
| [CI_CD.md](CI_CD.md) | Build and release workflows |
|
||||
|
||||
## Submodules
|
||||
|
||||
| Submodule | Path | Source | Pinned commit |
|
||||
|-----------|------|--------|---------------|
|
||||
| ztools | `mods/ztools` | `git.kindred-systems.com/forbes/ztools` | `d2f94c3` |
|
||||
| silo-mod | `mods/silo` | `git.kindred-systems.com/kindred/silo-mod` | `bf0b843` |
|
||||
| OndselSolver | `src/3rdParty/OndselSolver` | `git.kindred-systems.com/kindred/solver` | `5d1988b` |
|
||||
| GSL | `src/3rdParty/GSL` | `github.com/microsoft/GSL` | `756c91a` |
|
||||
| AddonManager | `src/Mod/AddonManager` | `github.com/FreeCAD/AddonManager` | `01e242e` |
|
||||
| googletest | `tests/lib` | `github.com/google/googletest` | `56efe39` |
|
||||
|
||||
The silo submodule was split from a monorepo into three repos: `silo-client` (shared Python API client), `silo-mod` (FreeCAD workbench, used as Create's submodule), and `silo-calc` (LibreOffice Calc extension). The `silo-mod` repo includes `silo-client` as its own submodule.
|
||||
|
||||
OndselSolver is forked from `github.com/FreeCAD/OndselSolver` to carry a Newton-Raphson convergence fix (see [KNOWN_ISSUES.md](KNOWN_ISSUES.md#12)).
|
||||
@@ -1,215 +0,0 @@
|
||||
# Repository State
|
||||
|
||||
**Last updated:** 2026-02-03
|
||||
**Branch:** main @ `0ef9ffcf51`
|
||||
**Kindred Create:** v0.1.0
|
||||
**FreeCAD base:** v1.0.0
|
||||
|
||||
## Submodules
|
||||
|
||||
| Submodule | Path | Source | Pinned commit |
|
||||
|-----------|------|--------|---------------|
|
||||
| ztools | `mods/ztools` | `gitea.kindred.internal/kindred/ztools-0065` | `d2f94c3` |
|
||||
| silo | `mods/silo` | `gitea.kindred.internal/kindred/silo-0062` | `17a10ab` |
|
||||
| OndselSolver | `src/3rdParty/OndselSolver` | `gitea.kindred.internal/kindred/ondsel` | `e32c9cd` |
|
||||
| GSL | `src/3rdParty/GSL` | `github.com/microsoft/GSL` | `756c91a` |
|
||||
| AddonManager | `src/Mod/AddonManager` | `github.com/FreeCAD/AddonManager` | `01e242e` |
|
||||
| googletest | `tests/lib` | `github.com/google/googletest` | `56efe39` |
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### Bootstrap flow
|
||||
|
||||
```
|
||||
FreeCAD startup
|
||||
└─ src/Mod/Create/Init.py
|
||||
└─ setup_kindred_addons()
|
||||
├─ exec(mods/ztools/ztools/Init.py)
|
||||
└─ exec(mods/silo/pkg/freecad/Init.py)
|
||||
|
||||
└─ src/Mod/Create/InitGui.py
|
||||
├─ setup_kindred_workbenches()
|
||||
│ ├─ exec(mods/ztools/ztools/InitGui.py)
|
||||
│ │ ├─ registers ZToolsWorkbench
|
||||
│ │ └─ installs _ZToolsPartDesignManipulator (global)
|
||||
│ └─ exec(mods/silo/pkg/freecad/InitGui.py)
|
||||
│ └─ registers SiloWorkbench
|
||||
└─ Deferred setup (QTimer):
|
||||
├─ 1500ms: _setup_silo_auth_panel() → "Database Auth" dock
|
||||
├─ 2000ms: _setup_silo_menu() → SiloMenuManipulator
|
||||
├─ 3000ms: _check_silo_first_start() → settings prompt
|
||||
└─ 4000ms: _setup_silo_activity_panel() → "Database Activity" dock
|
||||
```
|
||||
|
||||
### Key source layout
|
||||
|
||||
```
|
||||
src/Mod/Create/ Kindred bootstrap module (Python)
|
||||
├── Init.py Adds mods/ addon paths, loads Init.py files
|
||||
└── InitGui.py Loads workbenches, installs Silo manipulators
|
||||
|
||||
mods/ztools/ [submodule] ztools workbench
|
||||
├── ztools/InitGui.py ZToolsWorkbench + PartDesign manipulator
|
||||
├── ztools/ztools/
|
||||
│ ├── commands/ Datum, pattern, pocket, assembly, spreadsheet
|
||||
│ ├── datums/core.py Datum creation via Part::AttachExtension
|
||||
│ └── resources/ Icons, theme utilities
|
||||
└── CatppuccinMocha/ Theme preference pack (QSS)
|
||||
|
||||
mods/silo/ [submodule] Silo parts database
|
||||
├── cmd/ Go server entry points
|
||||
├── internal/ Go API, database, storage packages
|
||||
├── pkg/freecad/ FreeCAD workbench (Python)
|
||||
│ ├── InitGui.py SiloWorkbench
|
||||
│ └── silo_commands.py Commands + SiloClient API
|
||||
├── deployments/ Docker compose configuration
|
||||
└── migrations/ PostgreSQL schema migrations
|
||||
|
||||
src/Gui/Stylesheets/ QSS themes and SVG assets
|
||||
resources/preferences/ Canonical preference pack (KindredCreate)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Component status
|
||||
|
||||
### ztools workbench
|
||||
|
||||
**Registered commands (9):**
|
||||
|
||||
| Command | Function |
|
||||
|---------|----------|
|
||||
| `ZTools_DatumCreator` | Create datum planes, axes, points (16 modes) |
|
||||
| `ZTools_DatumManager` | Manage existing datum objects |
|
||||
| `ZTools_EnhancedPocket` | Flip-side pocket (cut outside sketch profile) |
|
||||
| `ZTools_RotatedLinearPattern` | Linear pattern with incremental rotation |
|
||||
| `ZTools_AssemblyLinearPattern` | Pattern assembly components linearly |
|
||||
| `ZTools_AssemblyPolarPattern` | Pattern assembly components around axis |
|
||||
| `ZTools_SpreadsheetStyle{Bold,Italic,Underline}` | Text style toggles |
|
||||
| `ZTools_SpreadsheetAlign{Left,Center,Right}` | Cell alignment |
|
||||
| `ZTools_Spreadsheet{BgColor,TextColor,QuickAlias}` | Colors and alias creation |
|
||||
|
||||
**PartDesign integration** via `_ZToolsPartDesignManipulator`:
|
||||
- `ZTools_DatumCreator`, `ZTools_DatumManager` → "Part Design Helper Features" toolbar
|
||||
- `ZTools_EnhancedPocket` → "Part Design Modeling Features" toolbar
|
||||
- `ZTools_RotatedLinearPattern` → "Part Design Transformation Features" toolbar
|
||||
- Same commands inserted into Part Design menu after `PartDesign_Boolean`
|
||||
|
||||
**Datum types (7):** offset_from_face, offset_from_plane, midplane, 3_points, normal_to_edge, angled, tangent_to_cylinder. All except tangent_to_cylinder use `Part::AttachExtension` for automatic parametric updates.
|
||||
|
||||
### Silo workbench
|
||||
|
||||
**Registered commands (13):**
|
||||
|
||||
| Command | Function |
|
||||
|---------|----------|
|
||||
| `Silo_New` | Create new Silo-tracked document |
|
||||
| `Silo_Open` | Open file from Silo database |
|
||||
| `Silo_Save` | Save to Silo (create revision) |
|
||||
| `Silo_Commit` | Commit current revision |
|
||||
| `Silo_Pull` | Pull latest revision from server |
|
||||
| `Silo_Push` | Push local changes to server |
|
||||
| `Silo_Info` | View item metadata and history |
|
||||
| `Silo_BOM` | Bill of materials dialog (BOM + Where Used) |
|
||||
| `Silo_TagProjects` | Assign project tags |
|
||||
| `Silo_Rollback` | Rollback to previous revision |
|
||||
| `Silo_SetStatus` | Set revision status (draft/review/released/obsolete) |
|
||||
| `Silo_Settings` | Configure API URL, projects dir, SSL certificates |
|
||||
| `Silo_ToggleMode` | Swap Ctrl+O/S/N between FreeCAD and Silo commands |
|
||||
|
||||
**Global integration** via `SiloMenuManipulator` in `src/Mod/Create/InitGui.py`:
|
||||
- File menu: Silo_New, Silo_Open, Silo_Save, Silo_Commit, Silo_Pull, Silo_Push, Silo_BOM
|
||||
- File toolbar: Silo_ToggleMode button
|
||||
|
||||
**Server architecture:** Go REST API (38 routes) + PostgreSQL + MinIO. See `mods/silo/docs/REPOSITORY_STATUS.md` for route details.
|
||||
|
||||
### Theme
|
||||
|
||||
**Canonical source:** `resources/preferences/KindredCreate/KindredCreate.qss`
|
||||
|
||||
Four copies must stay in sync:
|
||||
1. `resources/preferences/KindredCreate/KindredCreate.qss` (canonical)
|
||||
2. `src/Gui/Stylesheets/KindredCreate.qss`
|
||||
3. `src/Gui/PreferencePacks/KindredCreate/KindredCreate.qss`
|
||||
4. `mods/ztools/CatppuccinMocha/CatppuccinMocha.qss`
|
||||
|
||||
---
|
||||
|
||||
## Known issues
|
||||
|
||||
### Critical
|
||||
|
||||
1. **QSS duplication.** Four copies of the stylesheet must be kept in sync manually. A build step or symlinks should eliminate this.
|
||||
|
||||
2. **WorkbenchManipulator timing.** The `_ZToolsPartDesignManipulator` appends commands by name. If ZToolsWorkbench hasn't been activated when the user switches to PartDesign, the commands may not be registered. The manipulator API tolerates missing commands silently, but buttons won't appear.
|
||||
|
||||
3. **Silo shortcut persistence.** `Silo_ToggleMode` stores original shortcuts in a module-level dict. If FreeCAD crashes with Silo mode on, original shortcuts are lost on next launch.
|
||||
|
||||
### High
|
||||
|
||||
4. **No authentication on Silo server.** All API endpoints are publicly accessible. Required before multi-user deployment.
|
||||
|
||||
5. **No unit tests.** Zero test coverage for ztools and Silo FreeCAD commands. Silo Go backend also lacks tests.
|
||||
|
||||
6. **Assembly solver datum handling is minimal.** The `findPlacement()` fix extracts placement from `obj.Shape.Faces[0]` for `PartDesign::Plane`. Does not handle empty shapes or non-planar datum objects.
|
||||
|
||||
### Medium
|
||||
|
||||
7. **`Silo_BOM` requires Silo-tracked document.** Depends on `SiloPartNumber` property. Unregistered documents show a warning with no registration path.
|
||||
|
||||
8. **PartDesign menu insertion fragility.** `_ZToolsPartDesignManipulator.modifyMenuBar()` inserts after `PartDesign_Boolean`. If upstream renames this command, insertions silently fail.
|
||||
|
||||
9. **tangent_to_cylinder falls back to manual placement.** TangentPlane MapMode requires a vertex reference not collected by the current UI.
|
||||
|
||||
10. **`delete_bom_entry()` bypasses error normalization.** Uses raw `urllib.request` instead of `SiloClient._request()`.
|
||||
|
||||
---
|
||||
|
||||
## Incomplete features
|
||||
|
||||
### Silo
|
||||
|
||||
| Feature | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| Authentication/authorization | Not implemented | Required for multi-user |
|
||||
| File locking | Not implemented | Needed to prevent concurrent edits |
|
||||
| Odoo ERP integration | Stub only | Returns "not yet implemented" |
|
||||
| Part number date segments | Broken | `formatDate()` returns error |
|
||||
| Location/inventory APIs | Tables exist, no handlers | |
|
||||
| CSRF protection | Not implemented | Web UI only |
|
||||
| CSV import rollback | Not implemented | `bom_handlers.go` |
|
||||
|
||||
### ztools
|
||||
|
||||
| Feature | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| Tangent-to-cylinder attachment | Manual fallback | No vertex ref in UI |
|
||||
| Angled datum live editing | Incomplete | AttachmentOffset not updated in panel |
|
||||
| Assembly pattern undo | Not implemented | |
|
||||
|
||||
### Integration plan
|
||||
|
||||
| Phase | Feature | Status |
|
||||
|-------|---------|--------|
|
||||
| 1 | Addon auto-loading | Done |
|
||||
| 2 | Enhanced Pocket as C++ feature | Not started |
|
||||
| 3 | Datum C++ helpers | Not started (Python approach used) |
|
||||
| 4 | Theme moved to Create module | Partial (QSS synced, not relocated) |
|
||||
| 5 | Silo deep integration | Done |
|
||||
| 6 | Build system install rules for mods/ | Partial (CI/CD done, CMake install rules pending) |
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
1. **Authentication** -- LDAP/FreeIPA integration for Silo multi-user deployment. Server needs auth middleware; FreeCAD client needs credential storage.
|
||||
|
||||
2. **BOM-Assembly bridge** -- Auto-populate Silo BOM from Assembly component links on save.
|
||||
|
||||
3. **File locking** -- Pessimistic locks on `Silo_Open` to prevent concurrent edits. Requires server-side lock table and client-side lock display.
|
||||
|
||||
4. **Build system** -- CMake install rules for `mods/` submodules so packages include ztools and Silo without manual steps.
|
||||
|
||||
5. **Test coverage** -- Unit tests for ztools datum creation, Silo FreeCAD commands, and Go API endpoints.
|
||||
9
kindred-icons/AddonManager.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="6" width="9" height="9" rx="1" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<rect x="17" y="6" width="9" height="9" rx="1" fill="none" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<rect x="6" y="17" width="9" height="9" rx="1" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<rect x="17" y="17" width="9" height="9" rx="1" fill="none" stroke="#cba6f7" stroke-width="1.5"/>
|
||||
<line x1="21" y1="19" x2="21" y2="25" stroke="#cba6f7" stroke-width="1.5"/>
|
||||
<line x1="18" y1="22" x2="24" y2="22" stroke="#cba6f7" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 675 B |
99
kindred-icons/AssemblyWorkbench.svg
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
sodipodi:docname="AssemblyWorkbench.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs7" />
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="25"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7" />
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Multiple parts assembled -->
|
||||
<!-- Part 1 - cube -->
|
||||
<path
|
||||
d="M6 18 L6 12 L12 9 L18 12 L18 18 L12 21 Z"
|
||||
fill="#45475a"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M6 12 L12 15 L18 12"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M12 15 L12 21"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1"
|
||||
id="path3" />
|
||||
<!-- Part 2 - connected piece -->
|
||||
<path
|
||||
d="m 15.16,22.52 v -6 l 6,-3 6,3 v 6 l -6,3 z"
|
||||
fill="#45475a"
|
||||
stroke="#94e2d5"
|
||||
stroke-width="1.5"
|
||||
id="path4"
|
||||
style="stroke:#74c7ec;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 15.16,16.52 6,3 6,-3"
|
||||
stroke="#94e2d5"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
id="path5"
|
||||
style="stroke:#74c7ec;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 21.16,19.52 v 6"
|
||||
stroke="#94e2d5"
|
||||
stroke-width="1"
|
||||
id="path6"
|
||||
style="stroke:#74c7ec;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 11.11,13.318525 v -6 l 6,-3 6,3 v 6 l -6,3 z"
|
||||
fill="#45475a"
|
||||
stroke="#94e2d5"
|
||||
stroke-width="1.5"
|
||||
id="path4-6" />
|
||||
<path
|
||||
d="m 11.11,7.318525 6,3 6,-3"
|
||||
stroke="#94e2d5"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
id="path5-2" />
|
||||
<path
|
||||
d="m 17.11,10.318525 v 6"
|
||||
stroke="#94e2d5"
|
||||
stroke-width="1"
|
||||
id="path6-9" />
|
||||
<!-- Connection indicator -->
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
11
kindred-icons/Assembly_CreateAssembly.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Multiple parts -->
|
||||
<rect x="5" y="14" width="8" height="8" rx="1" fill="#45475a" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<rect x="19" y="14" width="8" height="8" rx="1" fill="#45475a" stroke="#94e2d5" stroke-width="1.5"/>
|
||||
<!-- Connection line -->
|
||||
<line x1="13" y1="18" x2="19" y2="18" stroke="#a6e3a1" stroke-width="2" stroke-dasharray="2,2"/>
|
||||
<!-- Plus sign for create -->
|
||||
<circle cx="24" cy="8" r="5" fill="#a6e3a1"/>
|
||||
<path d="M24 5.5 L24 10.5 M21.5 8 L26.5 8" stroke="#1e1e2e" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 678 B |
16
kindred-icons/Assembly_CreateJointDistance.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Two parts -->
|
||||
<rect x="4" y="12" width="8" height="10" rx="1" fill="#45475a" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<rect x="20" y="12" width="8" height="10" rx="1" fill="#45475a" stroke="#94e2d5" stroke-width="1.5"/>
|
||||
<!-- Distance dimension -->
|
||||
<line x1="12" y1="17" x2="20" y2="17" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<line x1="12" y1="14" x2="12" y2="20" stroke="#f9e2af" stroke-width="1"/>
|
||||
<line x1="20" y1="14" x2="20" y2="20" stroke="#f9e2af" stroke-width="1"/>
|
||||
<!-- Arrows -->
|
||||
<path d="M12 17 L14 15 L14 19 Z" fill="#f9e2af"/>
|
||||
<path d="M20 17 L18 15 L18 19 Z" fill="#f9e2af"/>
|
||||
<!-- Distance value -->
|
||||
<rect x="13" y="6" width="6" height="5" rx="1" fill="#313244" stroke="#fab387" stroke-width="1"/>
|
||||
<text x="16" y="10" font-family="monospace" font-size="5" fill="#cdd6f4" text-anchor="middle">d</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 976 B |
12
kindred-icons/Assembly_CreateJointFixed.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Two parts -->
|
||||
<rect x="5" y="10" width="10" height="12" rx="1" fill="#45475a" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<rect x="17" y="10" width="10" height="12" rx="1" fill="#45475a" stroke="#94e2d5" stroke-width="1.5"/>
|
||||
<!-- Fixed joint indicator - lock -->
|
||||
<rect x="13" y="14" width="6" height="6" rx="1" fill="#f9e2af" stroke="#fab387" stroke-width="1"/>
|
||||
<path d="M14 14 L14 12 A2 2 0 0 1 18 12 L18 14" fill="none" stroke="#fab387" stroke-width="1.5"/>
|
||||
<!-- Ground symbol -->
|
||||
<line x1="10" y1="26" x2="22" y2="26" stroke="#6c7086" stroke-width="2"/>
|
||||
<line x1="12" y1="28" x2="20" y2="28" stroke="#6c7086" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 785 B |
12
kindred-icons/Assembly_CreateJointRevolute.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Two parts connected by revolute joint -->
|
||||
<rect x="4" y="12" width="10" height="8" rx="1" fill="#45475a" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<rect x="18" y="12" width="10" height="8" rx="1" fill="#45475a" stroke="#94e2d5" stroke-width="1.5"/>
|
||||
<!-- Revolute joint - hinge circle -->
|
||||
<circle cx="16" cy="16" r="5" fill="#313244" stroke="#f9e2af" stroke-width="2"/>
|
||||
<circle cx="16" cy="16" r="2" fill="#fab387"/>
|
||||
<!-- Rotation arrow -->
|
||||
<path d="M22 6 A8 8 0 0 1 10 6" stroke="#fab387" stroke-width="2" fill="none" stroke-linecap="round"/>
|
||||
<path d="M12 4 L10 6 L12 9" stroke="#fab387" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 820 B |
13
kindred-icons/Assembly_CreateJointSlider.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Rail/track -->
|
||||
<rect x="4" y="14" width="24" height="4" rx="1" fill="#45475a" stroke="#6c7086" stroke-width="1"/>
|
||||
<!-- Sliding part -->
|
||||
<rect x="10" y="10" width="8" height="12" rx="1" fill="#45475a" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<!-- Slide direction arrows -->
|
||||
<path d="M6 8 L4 8 L4 24 L6 24" stroke="#f9e2af" stroke-width="2" fill="none" stroke-linecap="round"/>
|
||||
<path d="M26 8 L28 8 L28 24 L26 24" stroke="#f9e2af" stroke-width="2" fill="none" stroke-linecap="round"/>
|
||||
<!-- Motion arrow -->
|
||||
<path d="M20 16 L26 16" stroke="#94e2d5" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M23 13 L27 16 L23 19" stroke="#94e2d5" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 871 B |
10
kindred-icons/Assembly_InsertLink.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Part being inserted -->
|
||||
<path d="M8 20 L8 12 L14 9 L20 12 L20 20 L14 23 Z" fill="#45475a" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<path d="M8 12 L14 15 L20 12" stroke="#a6e3a1" stroke-width="1" fill="none"/>
|
||||
<path d="M14 15 L14 23" stroke="#a6e3a1" stroke-width="1"/>
|
||||
<!-- Arrow indicating insertion -->
|
||||
<path d="M24 8 L24 18" stroke="#94e2d5" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<path d="M21 15 L24 19 L27 15" stroke="#94e2d5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 668 B |
87
kindred-icons/Constraint_Dimension.svg
Normal file
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="Constraint_Dimension.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs5" />
|
||||
<sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="25"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="19.2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg5" />
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Line being dimensioned -->
|
||||
<!-- Dimension line -->
|
||||
<line
|
||||
x1="6"
|
||||
y1="12"
|
||||
x2="26"
|
||||
y2="12"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1.5"
|
||||
id="line2" />
|
||||
<!-- Extension lines -->
|
||||
<line
|
||||
x1="6"
|
||||
y1="20"
|
||||
x2="6"
|
||||
y2="10"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1"
|
||||
id="line3" />
|
||||
<line
|
||||
x1="26"
|
||||
y1="20"
|
||||
x2="26"
|
||||
y2="10"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1"
|
||||
id="line4" />
|
||||
<!-- Arrows -->
|
||||
<path
|
||||
d="M6 12 L10 10 L10 14 Z"
|
||||
fill="#a6e3a1"
|
||||
id="path4" />
|
||||
<path
|
||||
d="M26 12 L22 10 L22 14 Z"
|
||||
fill="#a6e3a1"
|
||||
id="path5" />
|
||||
<line
|
||||
x1="6"
|
||||
y1="20"
|
||||
x2="26"
|
||||
y2="20"
|
||||
stroke="#f9e2af"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line1" />
|
||||
<!-- Dimension text -->
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
13
kindred-icons/Constraint_Horizontal.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Horizontal line -->
|
||||
<line x1="6" y1="16" x2="26" y2="16" stroke="#f9e2af" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- End points -->
|
||||
<circle cx="6" cy="16" r="2.5" fill="#fab387"/>
|
||||
<circle cx="26" cy="16" r="2.5" fill="#fab387"/>
|
||||
<!-- H indicator -->
|
||||
<text x="16" y="10" font-family="sans-serif" font-size="8" font-weight="bold" fill="#a6e3a1" text-anchor="middle">H</text>
|
||||
<!-- Constraint arrows -->
|
||||
<path d="M10 22 L6 22 L6 20" stroke="#a6e3a1" stroke-width="1.5" fill="none" stroke-linecap="round"/>
|
||||
<path d="M22 22 L26 22 L26 20" stroke="#a6e3a1" stroke-width="1.5" fill="none" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 772 B |
76
kindred-icons/Constraint_Perpendicular.svg
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
sodipodi:docname="Constraint_Perpendicular.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="namedview2"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="25"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Horizontal line -->
|
||||
<path
|
||||
d="m 15.969398,16.225639 h 6.224963 v 5.744963"
|
||||
fill="none"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="2.99007"
|
||||
id="path2"
|
||||
style="stroke-width:1.85574803;stroke-dasharray:none" />
|
||||
<line
|
||||
x1="6"
|
||||
y1="22"
|
||||
x2="26"
|
||||
y2="22"
|
||||
stroke="#f9e2af"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line1" />
|
||||
<!-- Vertical line -->
|
||||
<line
|
||||
x1="16"
|
||||
y1="6"
|
||||
x2="16"
|
||||
y2="22"
|
||||
stroke="#f9e2af"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line2" />
|
||||
<!-- Right angle indicator -->
|
||||
<!-- Intersection point -->
|
||||
<circle
|
||||
cx="16"
|
||||
cy="22"
|
||||
r="2"
|
||||
fill="#fab387"
|
||||
id="circle2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
9
kindred-icons/Constraint_PointOnPoint.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Two lines meeting at a point -->
|
||||
<line x1="6" y1="26" x2="16" y2="16" stroke="#f9e2af" stroke-width="2"/>
|
||||
<line x1="26" y1="6" x2="16" y2="16" stroke="#f9e2af" stroke-width="2"/>
|
||||
<!-- Coincident point -->
|
||||
<circle cx="16" cy="16" r="4" fill="#a6e3a1"/>
|
||||
<circle cx="16" cy="16" r="2" fill="#1e1e2e"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
13
kindred-icons/Constraint_Vertical.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Vertical line -->
|
||||
<line x1="16" y1="6" x2="16" y2="26" stroke="#f9e2af" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- End points -->
|
||||
<circle cx="16" cy="6" r="2.5" fill="#fab387"/>
|
||||
<circle cx="16" cy="26" r="2.5" fill="#fab387"/>
|
||||
<!-- V indicator -->
|
||||
<text x="24" y="18" font-family="sans-serif" font-size="8" font-weight="bold" fill="#a6e3a1" text-anchor="middle">V</text>
|
||||
<!-- Constraint arrows -->
|
||||
<path d="M8 10 L8 6 L10 6" stroke="#a6e3a1" stroke-width="1.5" fill="none" stroke-linecap="round"/>
|
||||
<path d="M8 22 L8 26 L10 26" stroke="#a6e3a1" stroke-width="1.5" fill="none" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 766 B |
117
kindred-icons/Document.svg
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="Document.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect5"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.8970359,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect4"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,2.25625,0,1 @ F,0,0,1,0,1.411235,0,1 @ F,0,0,1,0,1.2732549,0,1 @ F,0,0,1,0,2.25625,0,1 @ F,0,0,1,0,1.875,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="10.90625"
|
||||
inkscape:cy="12.21875"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="m 10.246497,6 h 8.332515 a 3.4070227,3.4070227 22.5 0 1 2.409129,0.9978938 l 2.101779,2.101779 a 3.0739092,3.0739092 67.5 0 1 0.900327,2.1735822 l 0,12.470495 A 2.25625,2.25625 135 0 1 21.733997,26 H 9.8652468 a 1.875,1.875 45 0 1 -1.875,-1.875 V 8.25625 A 2.25625,2.25625 135 0 1 10.246497,6 Z"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
inkscape:path-effect="#path-effect4"
|
||||
inkscape:original-d="M 7.9902468,6 H 19.990247 l 4,4 V 26 H 7.9902468 Z" />
|
||||
<path
|
||||
d="m 19.707388,5.8623613 v 3.4443418 a 0.8970359,0.8970359 45 0 0 0.897036,0.8970359 h 3.385823"
|
||||
fill="none"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.61701"
|
||||
id="path2"
|
||||
style="stroke:#89b4fa;stroke-width:1.5;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:path-effect="#path-effect5"
|
||||
inkscape:original-d="m 19.707388,5.8623613 v 4.3413777 h 4.282859" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="14"
|
||||
x2="21"
|
||||
y2="14"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line2"
|
||||
style="stroke-linecap:round" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="18"
|
||||
x2="21"
|
||||
y2="18"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line3"
|
||||
style="stroke-linecap:round" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="22"
|
||||
x2="17"
|
||||
y2="22"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line4"
|
||||
style="stroke-linecap:round" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
16
kindred-icons/DraftWorkbench.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Drafting tools - pencil and triangle -->
|
||||
<!-- Triangle/Set square -->
|
||||
<path d="M6 26 L6 10 L22 26 Z" fill="#45475a" stroke="#fab387" stroke-width="1.5"/>
|
||||
<!-- Pencil -->
|
||||
<g transform="translate(16, 4) rotate(45)">
|
||||
<rect x="0" y="0" width="4" height="16" rx="0.5" fill="#f9e2af" stroke="#fab387" stroke-width="1"/>
|
||||
<path d="M0 16 L2 20 L4 16 Z" fill="#585b70" stroke="#fab387" stroke-width="0.5"/>
|
||||
<rect x="0" y="0" width="4" height="3" fill="#f38ba8"/>
|
||||
</g>
|
||||
<!-- Grid dots -->
|
||||
<circle cx="10" cy="22" r="1" fill="#6c7086"/>
|
||||
<circle cx="14" cy="22" r="1" fill="#6c7086"/>
|
||||
<circle cx="10" cy="18" r="1" fill="#6c7086"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 790 B |
5
kindred-icons/DrawStyleAsIs.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="16" rx="10" ry="6" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="16" cy="16" r="3" fill="none" stroke="#cdd6f4" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 344 B |
5
kindred-icons/DrawStyleFlatLines.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#89b4fa" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 419 B |
5
kindred-icons/DrawStyleNoShading.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="#585b70" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 419 B |
10
kindred-icons/DrawStylePoints.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="16" cy="4" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="5.5" cy="9.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="26.5" cy="9.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="16" cy="15" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="5.5" cy="22.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="26.5" cy="22.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="16" cy="28" r="1.5" fill="#cdd6f4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 491 B |
5
kindred-icons/DrawStyleShaded.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="#45475a" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 419 B |
5
kindred-icons/DrawStyleWireFrame.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 416 B |
5
kindred-icons/Feature.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 24 L8 12 L16 6 L24 12 L24 24 Z" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M8 12 L16 18 L24 12 M16 18 L16 6" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 314 B |
7
kindred-icons/Geoassembly.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="10" width="8" height="12" rx="1" fill="none" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<rect x="18" y="10" width="8" height="12" rx="1" fill="none" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<line x1="14" y1="14" x2="18" y2="14" stroke="#94e2d5" stroke-width="2"/>
|
||||
<line x1="14" y1="18" x2="18" y2="18" stroke="#94e2d5" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 476 B |
9
kindred-icons/Geofeaturegroup.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="16" cy="16" r="8" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="16" r="4" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="16" y1="4" x2="16" y2="8" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="16" y1="24" x2="16" y2="28" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="4" y1="16" x2="8" y2="16" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="24" y1="16" x2="28" y2="16" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 595 B |
5
kindred-icons/Group.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="10" width="20" height="16" rx="2" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M6 10 L6 8 C6 7 7 6 8 6 L14 6 L16 10" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 323 B |
5
kindred-icons/InTray.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M6 16 L6 24 L26 24 L26 16 L20 16 L18 20 L14 20 L12 16 Z" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M16 6 L16 14 M12 10 L16 14 L20 10" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 325 B |
6
kindred-icons/InTray_missed_notifications.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M6 16 L6 24 L26 24 L26 16 L20 16 L18 20 L14 20 L12 16 Z" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="24" cy="8" r="4" fill="#f38ba8"/>
|
||||
<text x="24" y="11" text-anchor="middle" font-family="sans-serif" font-size="6" font-weight="bold" fill="#313244">!</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 414 B |
6
kindred-icons/Invisible.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="16" rx="10" ry="6" fill="none" stroke="#585b70" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="16" r="3" fill="#585b70"/>
|
||||
<line x1="6" y1="24" x2="26" y2="8" stroke="#f38ba8" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 338 B |
55
kindred-icons/Link.svg
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="Link.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="25.632621"
|
||||
inkscape:cx="14.005591"
|
||||
inkscape:cy="15.839192"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="M 12.013793,20 H 8.0137931 a 4,4 0 0 1 0,-8 h 3.9999999"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 20.013793,12 h 4 a 4,4 0 0 1 0,8 h -4"
|
||||
fill="none"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="path2"
|
||||
style="stroke:#89b4fa;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#89b4fa;stroke-width:1.77369;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 9.6965515,16 H 22.303449"
|
||||
id="path3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
62
kindred-icons/LinkArray.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="10"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="10"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="22"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle3" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="22"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle4" />
|
||||
<line
|
||||
x1="14"
|
||||
y1="10"
|
||||
x2="18"
|
||||
y2="10"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="line1" />
|
||||
<line
|
||||
x1="10"
|
||||
y1="14"
|
||||
x2="10"
|
||||
y2="18"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="line2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
52
kindred-icons/LinkArrayOverlay.svg
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="6"
|
||||
y="6"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<rect
|
||||
x="10"
|
||||
y="10"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="#313244"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="rect3" />
|
||||
<rect
|
||||
x="14"
|
||||
y="14"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="#313244"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect4" />
|
||||
<circle
|
||||
cx="24"
|
||||
cy="8"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 910 B |
35
kindred-icons/LinkElement.svg
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="8"
|
||||
y="8"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<path
|
||||
d="M 18,18 24,24"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<circle
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="3"
|
||||
fill="#cba6f7"
|
||||
id="circle1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 636 B |
48
kindred-icons/LinkGroup.svg
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="6"
|
||||
y="10"
|
||||
width="20"
|
||||
height="14"
|
||||
rx="2"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<circle
|
||||
cx="12"
|
||||
cy="17"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="20"
|
||||
cy="17"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<line
|
||||
x1="15"
|
||||
y1="17"
|
||||
x2="17"
|
||||
y2="17"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="line1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 838 B |
69
kindred-icons/LinkImport.svg
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="LinkImport.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="25.632621"
|
||||
inkscape:cx="14.005591"
|
||||
inkscape:cy="15.800179"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="M 12.013793,20 H 8.0137931 a 4,4 0 0 1 0,-8 h 3.9999999"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 20.013793,12 h 4 a 4,4 0 0 1 0,8 h -4"
|
||||
fill="none"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="path2"
|
||||
style="stroke:#89b4fa;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#89b4fa;stroke-width:1.77369;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 9.6965515,16 H 22.303449"
|
||||
id="path3" />
|
||||
<circle
|
||||
cx="25.513792"
|
||||
cy="-9.2321157"
|
||||
fill="#a6e3a1"
|
||||
id="circle2"
|
||||
style="stroke-width:0.999999"
|
||||
transform="scale(1,-1)"
|
||||
r="5" />
|
||||
<path
|
||||
d="M 25.51379,11.732116 V 6.7321179 m -2.499999,2.4999988 h 5"
|
||||
stroke="#1e1e2e"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
id="path3-7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
42
kindred-icons/LinkImportAll.svg
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="10"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="10"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="20"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle3" />
|
||||
<path
|
||||
d="M 24,18 24,26 18,22 Z"
|
||||
fill="#a6e3a1"
|
||||
id="path1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 764 B |
34
kindred-icons/LinkOverlay.svg
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="6"
|
||||
y="6"
|
||||
width="12"
|
||||
height="12"
|
||||
rx="1.5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<rect
|
||||
x="14"
|
||||
y="14"
|
||||
width="12"
|
||||
height="12"
|
||||
rx="1.5"
|
||||
fill="#313244"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="rect3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 616 B |
42
kindred-icons/LinkReplace.svg
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="16"
|
||||
r="5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="16"
|
||||
r="5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<path
|
||||
d="M 13,12 19,12 M 19,12 17,10 M 19,12 17,14"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 19,20 13,20 M 13,20 15,18 M 13,20 15,22"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 837 B |
62
kindred-icons/LinkSelect.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="LinkSelect.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="25.632621"
|
||||
inkscape:cx="14.005591"
|
||||
inkscape:cy="15.800179"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="M 12.013793,20 H 8.0137931 a 4,4 0 0 1 0,-8 h 3.9999999"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 20.013793,12 h 4 a 4,4 0 0 1 0,8 h -4"
|
||||
fill="none"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="path2"
|
||||
style="stroke:#89b4fa;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#89b4fa;stroke-width:1.77369;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 9.6965515,16 H 22.303449"
|
||||
id="path3" />
|
||||
<rect
|
||||
style="fill:none;stroke:#fab387;stroke-width:1.056;stroke-dasharray:1.05599999, 2.11199999;stroke-linejoin:round;stroke-linecap:round;stroke-dashoffset:15.41759968;stroke-opacity:1"
|
||||
id="rect2"
|
||||
width="28.12822"
|
||||
height="14.785847"
|
||||
x="1.9358902"
|
||||
y="8.6070766" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
19
kindred-icons/MeshWorkbench.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Mesh triangles -->
|
||||
<path d="M16 6 L6 24 L26 24 Z" fill="#45475a" stroke="#f5c2e7" stroke-width="1.5"/>
|
||||
<!-- Internal mesh lines -->
|
||||
<line x1="16" y1="6" x2="11" y2="15" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<line x1="16" y1="6" x2="21" y2="15" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<line x1="11" y1="15" x2="21" y2="15" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<line x1="11" y1="15" x2="6" y2="24" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<line x1="21" y1="15" x2="26" y2="24" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<line x1="11" y1="15" x2="16" y2="24" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<line x1="21" y1="15" x2="16" y2="24" stroke="#f5c2e7" stroke-width="1"/>
|
||||
<!-- Vertices -->
|
||||
<circle cx="16" cy="6" r="2" fill="#f2cdcd"/>
|
||||
<circle cx="6" cy="24" r="2" fill="#f2cdcd"/>
|
||||
<circle cx="26" cy="24" r="2" fill="#f2cdcd"/>
|
||||
<circle cx="11" cy="15" r="1.5" fill="#f2cdcd"/>
|
||||
<circle cx="21" cy="15" r="1.5" fill="#f2cdcd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
11
kindred-icons/PartDesignWorkbench.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- 3D extruded shape representing Part Design -->
|
||||
<path d="M8 22 L8 12 L16 8 L24 12 L24 22 L16 26 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M8 12 L16 16 L24 12" stroke="#89b4fa" stroke-width="1.5" fill="none"/>
|
||||
<path d="M16 16 L16 26" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<!-- Top face highlight -->
|
||||
<path d="M8 12 L16 8 L24 12 L16 16 Z" fill="#74c7ec" fill-opacity="0.3"/>
|
||||
<!-- Gear accent indicating design/engineering -->
|
||||
<circle cx="16" cy="14" r="3" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 682 B |
13
kindred-icons/PartDesign_Body.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- 3D body representation -->
|
||||
<path d="M6 22 L6 10 L16 6 L26 10 L26 22 L16 26 Z" fill="#45475a" stroke="#89b4fa" stroke-width="2"/>
|
||||
<path d="M6 10 L16 14 L26 10" stroke="#89b4fa" stroke-width="2" fill="none"/>
|
||||
<path d="M16 14 L16 26" stroke="#89b4fa" stroke-width="2"/>
|
||||
<!-- Top face highlight -->
|
||||
<path d="M6 10 L16 6 L26 10 L16 14 Z" fill="#74c7ec" fill-opacity="0.4"/>
|
||||
<!-- Origin indicator -->
|
||||
<circle cx="16" cy="16" r="2" fill="#a6e3a1"/>
|
||||
<line x1="16" y1="12" x2="16" y2="20" stroke="#a6e3a1" stroke-width="1"/>
|
||||
<line x1="12" y1="16" x2="20" y2="16" stroke="#a6e3a1" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 750 B |
76
kindred-icons/PartDesign_Chamfer.svg
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="PartDesign_Chamfer.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs5" />
|
||||
<sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="11.136932"
|
||||
inkscape:cy="18.473165"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg5" />
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Block with chamfered edge -->
|
||||
<path
|
||||
d="M 6,24 5.9375,16.0625 11.171008,8.026064 16,6 26,10 V 24 L 16,28 Z M 20.923535,12.327039 26.006643,9.9805673 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
d="M 16,19.88 V 28"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path3"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
d="M 5.721457,16 10.416889,7.8973687 21,12 16.132583,20.145165 Z"
|
||||
fill="#a6e3a1"
|
||||
fill-opacity="0.3"
|
||||
id="path5"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
style="opacity:1;fill:#a6e3a1;fill-opacity:1" />
|
||||
<!-- Chamfer cut on edge -->
|
||||
<!-- Chamfer face -->
|
||||
<path
|
||||
d="M 21.289264,12.075764 15.938527,20.29433"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5847"
|
||||
id="path3-0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
d="M 11.313916,7.9020371 5.8336127,16.235844"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.61498"
|
||||
id="path3-0-3"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
78
kindred-icons/PartDesign_Fillet.svg
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="PartDesign_Fillet.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs5" />
|
||||
<sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="2.8284271"
|
||||
inkscape:cy="17.412504"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg5" />
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Block with chamfered edge -->
|
||||
<path
|
||||
d="M 6,24 6.1584709,15.885723 10.508095,8.6005883 16,6 26,10 V 24 L 16,28 Z M 20.923535,12.327039 26.006643,9.9805673 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
d="M 16,19.88 V 28"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path3"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
d="M 5.721457,16 10.416889,7.8973687 21,12 l -3.708852,3.943415 -1.158565,4.20175 z"
|
||||
fill="#a6e3a1"
|
||||
fill-opacity="0.3"
|
||||
id="path5"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
style="opacity:1;fill:#a6e3a1;fill-opacity:1" />
|
||||
<!-- Chamfer cut on edge -->
|
||||
<!-- Chamfer face -->
|
||||
<path
|
||||
d="m 25.554002,10.020735 c 0,0 -2.839088,1.13525 -4.950437,2.544214 -1.652011,1.102435 -2.601422,2.423855 -3.100562,3.159378 -1.011406,1.490386 -1.47202,3.667857 -1.538841,4.165681 -0.0066,0.04949 -0.01392,7.861307 -0.01392,7.861307 m 7.653323,-14.186366"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5847"
|
||||
id="path3-0"
|
||||
sodipodi:nodetypes="csssc"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="m 16.23145,6.006509 c 0,0 -3.524098,1.0247646 -5.635447,2.4337286 -1.6520107,1.1024351 -2.6014217,2.4238554 -3.1005617,3.1593784 -1.011406,1.490386 -1.47202,3.667857 -1.538841,4.165681 -0.0066,0.04949 0.2070509,8.612608 0.2070509,8.612608"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5847"
|
||||
id="path3-0-6"
|
||||
sodipodi:nodetypes="csssc"
|
||||
style="fill:none" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
13
kindred-icons/PartDesign_Hole.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Block with hole -->
|
||||
<path d="M4 22 L4 10 L16 6 L28 10 L28 22 L16 26 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M4 10 L16 14 L28 10" stroke="#89b4fa" stroke-width="1.5" fill="none"/>
|
||||
<path d="M16 14 L16 26" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<!-- Circular hole on top -->
|
||||
<ellipse cx="16" cy="11" rx="5" ry="2" fill="#1e1e2e" stroke="#f38ba8" stroke-width="1.5"/>
|
||||
<!-- Hole depth indication -->
|
||||
<path d="M11 11 L11 18" stroke="#f38ba8" stroke-width="1" stroke-dasharray="2,1"/>
|
||||
<path d="M21 11 L21 18" stroke="#f38ba8" stroke-width="1" stroke-dasharray="2,1"/>
|
||||
<ellipse cx="16" cy="18" rx="5" ry="2" fill="none" stroke="#f38ba8" stroke-width="1" stroke-dasharray="2,1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 855 B |
64
kindred-icons/PartDesign_NewSketch.svg
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="PartDesign_NewSketch.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="36.25"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Sketch plane -->
|
||||
<path
|
||||
d="m 4,17.158621 12,-8.0000003 12,8.0000003 -12,8 z"
|
||||
fill="#45475a"
|
||||
stroke="#f9e2af"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<!-- Grid on plane -->
|
||||
<!-- Sketch geometry -->
|
||||
<!-- Plus sign for "new" -->
|
||||
<circle
|
||||
cx="23.092838"
|
||||
cy="-10.553846"
|
||||
fill="#a6e3a1"
|
||||
id="circle2"
|
||||
style="stroke-width:0.999999"
|
||||
transform="scale(1,-1)"
|
||||
r="5" />
|
||||
<path
|
||||
d="M 23.092837,13.053846 V 8.0538483 m -2.499999,2.4999987 h 5"
|
||||
stroke="#1e1e2e"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
id="path3-7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
62
kindred-icons/PartDesign_Pad.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Base sketch profile -->
|
||||
<path
|
||||
d="M 6,24 6,20 14,18 26,20 26,24 14,26 Z"
|
||||
fill="#45475a"
|
||||
stroke="#6c7086"
|
||||
stroke-width="1"
|
||||
id="path1" />
|
||||
<!-- Extruded body -->
|
||||
<path
|
||||
d="M 6,20 6,10 14,8 26,10 26,20 14,22 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 6,10 14,12 26,10"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path3" />
|
||||
<path
|
||||
d="M 14,12 V 22"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path4" />
|
||||
<!-- Top face -->
|
||||
<path
|
||||
d="M 6,10 14,8 26,10 14,12 Z"
|
||||
fill="#74c7ec"
|
||||
fill-opacity="0.4"
|
||||
id="path5" />
|
||||
<!-- Extrude arrow -->
|
||||
<path
|
||||
d="M 20,18 V 6"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="path6" />
|
||||
<path
|
||||
d="M 17,9 20,5 23,9"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
id="path7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
67
kindred-icons/PartDesign_Pocket.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Solid block -->
|
||||
<path
|
||||
d="M 4,22 4,10 16,6 28,10 28,22 16,26 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 4,10 16,14 28,10"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 16,14 V 26"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path3" />
|
||||
<!-- Pocket cut-out -->
|
||||
<path
|
||||
d="M 10,12 16,10 22,12 22,18 16,20 10,18 Z"
|
||||
fill="#1e1e2e"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
id="path4" />
|
||||
<path
|
||||
d="M 10,12 16,14 22,12"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
id="path5" />
|
||||
<path
|
||||
d="M 16,14 V 20"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1"
|
||||
id="path6" />
|
||||
<!-- Cut arrow -->
|
||||
<path
|
||||
d="M 16,8 V 16"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
id="path7" />
|
||||
<path
|
||||
d="M 14,13 16,17 18,13"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
id="path8" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
12
kindred-icons/PartDesign_Revolution.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Revolved shape - vase/cone profile -->
|
||||
<ellipse cx="16" cy="24" rx="10" ry="3" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M6 24 Q6 12 12 8 L20 8 Q26 12 26 24" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<ellipse cx="16" cy="8" rx="4" ry="1.5" fill="#74c7ec" fill-opacity="0.4" stroke="#89b4fa" stroke-width="1"/>
|
||||
<!-- Axis line -->
|
||||
<line x1="16" y1="4" x2="16" y2="28" stroke="#a6e3a1" stroke-width="1.5" stroke-dasharray="3,2"/>
|
||||
<!-- Rotation arrow -->
|
||||
<path d="M22 6 A6 6 0 0 1 22 14" stroke="#a6e3a1" stroke-width="2" fill="none" stroke-linecap="round"/>
|
||||
<path d="M20 12 L22 15 L25 13" stroke="#a6e3a1" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 870 B |
9
kindred-icons/PartWorkbench.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Simple 3D primitive - cube with boolean indication -->
|
||||
<path d="M6 20 L6 10 L16 6 L26 10 L26 20 L16 24 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M6 10 L16 14 L26 10" stroke="#89b4fa" stroke-width="1.5" fill="none"/>
|
||||
<path d="M16 14 L16 24" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<!-- Boolean cut-out indication -->
|
||||
<circle cx="18" cy="15" r="4" fill="#313244" stroke="#74c7ec" stroke-width="1.5" stroke-dasharray="2,1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 595 B |
121
kindred-icons/README.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Kindred Create Icons
|
||||
|
||||
This directory contains custom Catppuccin Mocha themed SVG icons that override the default FreeCAD icons.
|
||||
|
||||
## How It Works
|
||||
|
||||
Icons placed in this directory are loaded **before** the default FreeCAD icons. To override an icon, simply create an SVG file with the same name as the original icon.
|
||||
|
||||
For example, to override `document-save.svg`, create `kindred-icons/document-save.svg`.
|
||||
|
||||
## Icon Design Standards
|
||||
|
||||
All Kindred Create icons follow these guidelines:
|
||||
|
||||
### Template
|
||||
|
||||
```svg
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Icon content using Catppuccin Mocha colors -->
|
||||
</svg>
|
||||
```
|
||||
|
||||
### Specifications
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| ViewBox | 32x32 |
|
||||
| Background | Rounded rect, rx=4, fill=`#313244` (surface0) |
|
||||
| Stroke width | 1.5-2.5 for main elements |
|
||||
| Style | Flat, minimal, geometric |
|
||||
|
||||
### Catppuccin Mocha Palette
|
||||
|
||||
| Color | Hex | Usage |
|
||||
|-------|-----|-------|
|
||||
| Base | `#1e1e2e` | Deep backgrounds |
|
||||
| Mantle | `#181825` | Darker backgrounds |
|
||||
| Crust | `#11111b` | Darkest backgrounds |
|
||||
| Surface0 | `#313244` | **Icon backgrounds** |
|
||||
| Surface1 | `#45475a` | Elevated surfaces |
|
||||
| Surface2 | `#585b70` | Higher surfaces |
|
||||
| Overlay0 | `#6c7086` | Subtle elements |
|
||||
| Overlay1 | `#7f849c` | More visible overlays |
|
||||
| Overlay2 | `#9399b2` | Prominent overlays |
|
||||
| Subtext0 | `#a6adc8` | Tertiary text |
|
||||
| Subtext1 | `#bac2de` | Secondary text |
|
||||
| Text | `#cdd6f4` | **Primary text/strokes** |
|
||||
| Lavender | `#b4befe` | Soft purple accent |
|
||||
| Blue | `#89b4fa` | **File operations** |
|
||||
| Sapphire | `#74c7ec` | Links, info |
|
||||
| Sky | `#89dceb` | Light blue accent |
|
||||
| Teal | `#94e2d5` | Success secondary |
|
||||
| Green | `#a6e3a1` | **Edit operations, Creation/Success** |
|
||||
| Yellow | `#f9e2af` | **View operations** |
|
||||
| Peach | `#fab387` | **View accents** |
|
||||
| Maroon | `#eba0ac` | Soft red |
|
||||
| Red | `#f38ba8` | **Deletion/Error** |
|
||||
| Mauve | `#cba6f7` | **System/Settings** |
|
||||
| Lavender | `#b4befe` | **System accents** |
|
||||
| Pink | `#f5c2e7` | Decorative |
|
||||
| Flamingo | `#f2cdcd` | Soft accents |
|
||||
| Rosewater | `#f5e0dc` | Lightest accent |
|
||||
|
||||
### Workbench Color Coding
|
||||
|
||||
Each workbench uses a distinct accent color:
|
||||
|
||||
| Workbench | Primary | Accent |
|
||||
|-----------|---------|--------|
|
||||
| Part Design | Blue `#89b4fa` | Sapphire `#74c7ec` |
|
||||
| Sketcher | Yellow `#f9e2af` | Peach `#fab387` |
|
||||
| Assembly | Green `#a6e3a1` | Teal `#94e2d5` |
|
||||
| TechDraw | Mauve `#cba6f7` | Lavender `#b4befe` |
|
||||
| Spreadsheet | Sky `#89dceb` | Sapphire `#74c7ec` |
|
||||
| Mesh | Pink `#f5c2e7` | Flamingo `#f2cdcd` |
|
||||
| Draft | Peach `#fab387` | Yellow `#f9e2af` |
|
||||
|
||||
## Adding New Icons
|
||||
|
||||
1. Identify the original icon name (e.g., `document-save.svg`)
|
||||
2. Create your SVG using the template above
|
||||
3. Save it in this directory with the exact same filename
|
||||
4. The new icon will be used on next application start
|
||||
|
||||
## Finding Original Icon Names
|
||||
|
||||
Original icons are located in:
|
||||
- `src/Gui/Icons/` - Core GUI icons
|
||||
- `src/Mod/*/Gui/Resources/icons/` - Module-specific icons
|
||||
|
||||
Use the same filename to override.
|
||||
|
||||
## Icon Categories
|
||||
|
||||
The icon set covers these categories:
|
||||
|
||||
| Category | Count | Examples |
|
||||
|----------|-------|----------|
|
||||
| File Operations | 15+ | document-save, document-open, Std_Export |
|
||||
| Edit Operations | 20+ | edit-undo, edit-copy, edit-paste |
|
||||
| View Operations | 35+ | zoom-in, DrawStyle*, Std_View* |
|
||||
| System/Settings | 15+ | preferences-system, help-browser |
|
||||
| Tree View | 15 | Tree_*, tree-* |
|
||||
| Link/Structure | 15+ | Link*, Feature, Group |
|
||||
| Workbenches | 8 | PartDesignWorkbench, SketcherWorkbench |
|
||||
| PartDesign | 8 | PartDesign_Pad, PartDesign_Pocket |
|
||||
| Sketcher | 10+ | Sketcher_Create*, Constraint_* |
|
||||
| Assembly | 6 | Assembly_Create*, Assembly_Insert* |
|
||||
| Navigation | 10+ | button_*, cursor-* |
|
||||
| Selection | 8 | *-selection, clear-selection |
|
||||
| DAG View | 4 | dagView* |
|
||||
|
||||
**Total: 191 icons**
|
||||
|
||||
## Related Issues
|
||||
|
||||
- Epic: https://git.kindred-systems.com/kindred/create/issues/7
|
||||
- Phase 1 (Core): https://git.kindred-systems.com/kindred/create/issues/4
|
||||
- Phase 2 (Workbench): https://git.kindred-systems.com/kindred/create/issues/5
|
||||
- Phase 3 (Complete): https://git.kindred-systems.com/kindred/create/issues/6
|
||||
15
kindred-icons/SketcherWorkbench.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Grid lines representing sketch plane -->
|
||||
<line x1="6" y1="10" x2="26" y2="10" stroke="#45475a" stroke-width="1"/>
|
||||
<line x1="6" y1="16" x2="26" y2="16" stroke="#45475a" stroke-width="1"/>
|
||||
<line x1="6" y1="22" x2="26" y2="22" stroke="#45475a" stroke-width="1"/>
|
||||
<line x1="10" y1="6" x2="10" y2="26" stroke="#45475a" stroke-width="1"/>
|
||||
<line x1="16" y1="6" x2="16" y2="26" stroke="#45475a" stroke-width="1"/>
|
||||
<line x1="22" y1="6" x2="22" y2="26" stroke="#45475a" stroke-width="1"/>
|
||||
<!-- Sketch profile -->
|
||||
<path d="M8 20 L8 12 L14 8 L24 8 L24 18 L18 24 L8 20" fill="none" stroke="#f9e2af" stroke-width="2" stroke-linejoin="round"/>
|
||||
<!-- Constraint point -->
|
||||
<circle cx="8" cy="12" r="2" fill="#fab387"/>
|
||||
<circle cx="24" cy="8" r="2" fill="#fab387"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 911 B |
12
kindred-icons/Sketcher_CreateArc.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Arc -->
|
||||
<path d="M6 24 A14 14 0 0 1 26 24" fill="none" stroke="#f9e2af" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- End points -->
|
||||
<circle cx="6" cy="24" r="2.5" fill="#fab387"/>
|
||||
<circle cx="26" cy="24" r="2.5" fill="#fab387"/>
|
||||
<!-- Center point -->
|
||||
<circle cx="16" cy="24" r="2" fill="#fab387" fill-opacity="0.6"/>
|
||||
<!-- Radius indicator -->
|
||||
<line x1="16" y1="24" x2="16" y2="10" stroke="#fab387" stroke-width="1" stroke-dasharray="2,2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 602 B |
9
kindred-icons/Sketcher_CreateCircle.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Circle -->
|
||||
<circle cx="16" cy="16" r="10" fill="none" stroke="#f9e2af" stroke-width="2.5"/>
|
||||
<!-- Center point -->
|
||||
<circle cx="16" cy="16" r="2.5" fill="#fab387"/>
|
||||
<!-- Radius line -->
|
||||
<line x1="16" y1="16" x2="26" y2="16" stroke="#fab387" stroke-width="1.5" stroke-dasharray="2,2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 435 B |
8
kindred-icons/Sketcher_CreateLine.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Line -->
|
||||
<line x1="6" y1="26" x2="26" y2="6" stroke="#f9e2af" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- End points -->
|
||||
<circle cx="6" cy="26" r="3" fill="#fab387"/>
|
||||
<circle cx="26" cy="6" r="3" fill="#fab387"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 368 B |
11
kindred-icons/Sketcher_CreatePoint.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Point with crosshair -->
|
||||
<circle cx="16" cy="16" r="5" fill="#fab387"/>
|
||||
<circle cx="16" cy="16" r="3" fill="#f9e2af"/>
|
||||
<!-- Crosshair lines -->
|
||||
<line x1="16" y1="6" x2="16" y2="11" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<line x1="16" y1="21" x2="16" y2="26" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<line x1="6" y1="16" x2="11" y2="16" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<line x1="21" y1="16" x2="26" y2="16" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 602 B |
10
kindred-icons/Sketcher_CreateRectangle.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Rectangle -->
|
||||
<rect x="6" y="8" width="20" height="16" rx="1" fill="none" stroke="#f9e2af" stroke-width="2.5"/>
|
||||
<!-- Corner points -->
|
||||
<circle cx="6" cy="8" r="2.5" fill="#fab387"/>
|
||||
<circle cx="26" cy="8" r="2.5" fill="#fab387"/>
|
||||
<circle cx="6" cy="24" r="2.5" fill="#fab387"/>
|
||||
<circle cx="26" cy="24" r="2.5" fill="#fab387"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 481 B |
20
kindred-icons/SpreadsheetWorkbench.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Spreadsheet grid -->
|
||||
<rect x="5" y="5" width="22" height="22" rx="1" fill="#45475a" stroke="#89dceb" stroke-width="1.5"/>
|
||||
<!-- Header row -->
|
||||
<rect x="5" y="5" width="22" height="5" fill="#585b70"/>
|
||||
<!-- Column dividers -->
|
||||
<line x1="12" y1="5" x2="12" y2="27" stroke="#6c7086" stroke-width="1"/>
|
||||
<line x1="20" y1="5" x2="20" y2="27" stroke="#6c7086" stroke-width="1"/>
|
||||
<!-- Row dividers -->
|
||||
<line x1="5" y1="10" x2="27" y2="10" stroke="#6c7086" stroke-width="1"/>
|
||||
<line x1="5" y1="16" x2="27" y2="16" stroke="#6c7086" stroke-width="1"/>
|
||||
<line x1="5" y1="22" x2="27" y2="22" stroke="#6c7086" stroke-width="1"/>
|
||||
<!-- Header labels -->
|
||||
<text x="8" y="9" font-family="monospace" font-size="4" fill="#cdd6f4">A</text>
|
||||
<text x="15" y="9" font-family="monospace" font-size="4" fill="#cdd6f4">B</text>
|
||||
<text x="23" y="9" font-family="monospace" font-size="4" fill="#cdd6f4">C</text>
|
||||
<!-- Cell highlight -->
|
||||
<rect x="12" y="10" width="8" height="6" fill="#74c7ec" fill-opacity="0.3" stroke="#89dceb" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
10
kindred-icons/Std_DuplicateSelection.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Original object -->
|
||||
<rect x="6" y="6" width="12" height="12" rx="2" fill="#45475a" stroke="#6c7086" stroke-width="1.5"/>
|
||||
<!-- Duplicate object -->
|
||||
<rect x="14" y="14" width="12" height="12" rx="2" fill="#45475a" stroke="#94e2d5" stroke-width="1.5"/>
|
||||
<!-- Plus badge -->
|
||||
<circle cx="24" cy="8" r="5" fill="#a6e3a1"/>
|
||||
<path d="M24 5.5 L24 10.5 M21.5 8 L26.5 8" stroke="#1e1e2e" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 574 B |
9
kindred-icons/Std_Export.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Document -->
|
||||
<path d="M8 5 L8 27 L24 27 L24 11 L18 5 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M18 5 L18 11 L24 11" fill="#313244" stroke="#89b4fa" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
<!-- Arrow pointing out of document -->
|
||||
<path d="M12 16 L4 16" stroke="#fab387" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<path d="M7 13 L4 16 L7 19" stroke="#fab387" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 617 B |
6
kindred-icons/Std_HideObjects.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="16" rx="10" ry="6" fill="none" stroke="#585b70" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="16" r="3" fill="#585b70"/>
|
||||
<line x1="6" y1="24" x2="26" y2="8" stroke="#f38ba8" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 338 B |
9
kindred-icons/Std_Import.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Document -->
|
||||
<path d="M8 5 L8 27 L24 27 L24 11 L18 5 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M18 5 L18 11 L24 11" fill="#313244" stroke="#89b4fa" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
<!-- Arrow pointing into document -->
|
||||
<path d="M4 16 L12 16" stroke="#a6e3a1" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<path d="M9 13 L12 16 L9 19" stroke="#a6e3a1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 616 B |
7
kindred-icons/Std_Refresh.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Circular arrow -->
|
||||
<path d="M16 6 A10 10 0 1 1 6 16" fill="none" stroke="#cba6f7" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- Arrow head -->
|
||||
<path d="M16 6 L13 10 L19 10 Z" fill="#b4befe"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 343 B |
14
kindred-icons/Std_SaveAll.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Back floppy -->
|
||||
<path d="M11 4 L11 20 L25 20 L25 8 L21 4 Z" fill="#45475a" stroke="#6c7086" stroke-width="1"/>
|
||||
<!-- Front floppy -->
|
||||
<path d="M5 8 L5 28 L19 28 L19 12 L15 8 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<!-- Metal slider on front -->
|
||||
<rect x="8" y="8" width="6" height="5" rx="1" fill="#1e1e2e" stroke="#6c7086" stroke-width="0.75"/>
|
||||
<!-- Label area on front -->
|
||||
<rect x="7" y="16" width="10" height="5" rx="1" fill="#cdd6f4"/>
|
||||
<!-- Multiple indicator -->
|
||||
<circle cx="24" cy="24" r="5" fill="#a6e3a1"/>
|
||||
<text x="24" y="27" font-family="sans-serif" font-size="8" font-weight="bold" fill="#1e1e2e" text-anchor="middle">2</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 814 B |
6
kindred-icons/Std_SelectVisibleObjects.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="12" rx="8" ry="5" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="12" r="2.5" fill="#fab387"/>
|
||||
<path d="M8 20 L12 24 L24 12" fill="none" stroke="#a6e3a1" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 345 B |
9
kindred-icons/Std_SetAppearance.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="16" cy="16" r="8" fill="none" stroke="#cba6f7" stroke-width="1.5"/>
|
||||
<path d="M16 8 L16 16 L22 16" fill="none" stroke="#b4befe" stroke-width="2"/>
|
||||
<circle cx="16" cy="8" r="2" fill="#f38ba8"/>
|
||||
<circle cx="24" cy="16" r="2" fill="#a6e3a1"/>
|
||||
<circle cx="16" cy="24" r="2" fill="#89b4fa"/>
|
||||
<circle cx="8" cy="16" r="2" fill="#f9e2af"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 479 B |
7
kindred-icons/Std_ShowObjects.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="16" rx="10" ry="6" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="16" r="3" fill="#fab387"/>
|
||||
<rect x="8" y="22" width="6" height="4" rx="1" fill="#a6e3a1"/>
|
||||
<rect x="18" y="22" width="6" height="4" rx="1" fill="#a6e3a1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 397 B |
6
kindred-icons/Std_ShowSelection.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="14" rx="8" ry="5" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="14" r="2.5" fill="#fab387"/>
|
||||
<rect x="10" y="20" width="12" height="6" rx="1" fill="none" stroke="#a6e3a1" stroke-width="1.5" stroke-dasharray="2,2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 389 B |
6
kindred-icons/Std_ToggleClipPlane.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 20 L8 10 L16 6 L24 10 L24 20" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<line x1="4" y1="16" x2="28" y2="16" stroke="#f38ba8" stroke-width="2"/>
|
||||
<path d="M8 20 L16 24 L24 20" fill="none" stroke="#89b4fa" stroke-width="1.5" stroke-dasharray="2,2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 397 B |
8
kindred-icons/Std_ToggleFreeze.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<line x1="16" y1="6" x2="16" y2="26" stroke="#74c7ec" stroke-width="2"/>
|
||||
<line x1="6" y1="16" x2="26" y2="16" stroke="#74c7ec" stroke-width="2"/>
|
||||
<line x1="9" y1="9" x2="23" y2="23" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="23" y1="9" x2="9" y2="23" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="16" r="3" fill="#89dceb"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 474 B |
5
kindred-icons/Std_ToggleNavigation.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="16" cy="16" r="8" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<path d="M16 8 L18 14 L24 16 L18 18 L16 24 L14 18 L8 16 L14 14 Z" fill="#fab387"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 290 B |
9
kindred-icons/Std_ToggleObjects.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="12" cy="12" rx="6" ry="4" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="12" r="2" fill="#fab387"/>
|
||||
<ellipse cx="20" cy="20" rx="6" ry="4" fill="none" stroke="#585b70" stroke-width="1.5"/>
|
||||
<circle cx="20" cy="20" r="2" fill="#585b70"/>
|
||||
<path d="M16 14 L16 18" stroke="#b4befe" stroke-width="1.5"/>
|
||||
<path d="M14 16 L18 16" stroke="#b4befe" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 531 B |
5
kindred-icons/Std_ToggleTransparency.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="8" width="12" height="12" fill="#89b4fa" fill-opacity="0.5" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<rect x="14" y="12" width="12" height="12" fill="#f9e2af" fill-opacity="0.5" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 355 B |
11
kindred-icons/Std_ToggleVisibility.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Eye shape -->
|
||||
<path d="M4 16 Q16 6 28 16 Q16 26 4 16" fill="#45475a" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<!-- Iris -->
|
||||
<circle cx="16" cy="16" r="5" fill="#fab387"/>
|
||||
<!-- Pupil -->
|
||||
<circle cx="16" cy="16" r="2.5" fill="#1e1e2e"/>
|
||||
<!-- Light reflection -->
|
||||
<circle cx="14" cy="14.5" r="1" fill="#cdd6f4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 463 B |
7
kindred-icons/Std_TransformManip.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<line x1="16" y1="6" x2="16" y2="26" stroke="#a6e3a1" stroke-width="2"/>
|
||||
<line x1="6" y1="16" x2="26" y2="16" stroke="#f38ba8" stroke-width="2"/>
|
||||
<line x1="8" y1="8" x2="24" y2="24" stroke="#89b4fa" stroke-width="1.5" stroke-dasharray="2,2"/>
|
||||
<circle cx="16" cy="16" r="4" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 454 B |
5
kindred-icons/Std_ViewBottom.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M6 12 L16 24 L26 12 Z" fill="#fab387" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<text x="16" y="18" text-anchor="middle" font-family="sans-serif" font-size="7" font-weight="bold" fill="#313244">Bo</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 336 B |
5
kindred-icons/Std_ViewDimetric.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M4 17 L16 11 L28 17 L28 23 L16 29 L4 23 Z" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M4 17 L16 23 L28 17 M16 23 L16 29" fill="none" stroke="#313244" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
5
kindred-icons/Std_ViewFront.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="8" y="8" width="16" height="16" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<text x="16" y="20" text-anchor="middle" font-family="sans-serif" font-size="8" font-weight="bold" fill="#313244">F</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 344 B |
11
kindred-icons/Std_ViewHome.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- House shape -->
|
||||
<path d="M16 6 L6 14 L6 26 L26 26 L26 14 Z" fill="#45475a" stroke="#f9e2af" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
<!-- Roof -->
|
||||
<path d="M16 6 L4 16 L6 16 L16 8 L26 16 L28 16 Z" fill="#585b70" stroke="#f9e2af" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
<!-- Door -->
|
||||
<rect x="13" y="18" width="6" height="8" rx="1" fill="#1e1e2e" stroke="#fab387" stroke-width="1"/>
|
||||
<!-- Window -->
|
||||
<rect x="19" y="14" width="4" height="4" rx="0.5" fill="#89dceb" stroke="#74c7ec" stroke-width="0.75"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 667 B |
5
kindred-icons/Std_ViewIsometric.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M6 18 L16 12 L26 18 L26 24 L16 30 L6 24 Z" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M6 18 L16 24 L26 18 M16 24 L16 30" fill="none" stroke="#313244" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
5
kindred-icons/Std_ViewLeft.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M20 6 L8 16 L20 26 Z" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<text x="15" y="20" text-anchor="middle" font-family="sans-serif" font-size="7" font-weight="bold" fill="#313244">L</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 334 B |
5
kindred-icons/Std_ViewRear.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="8" y="8" width="16" height="16" fill="#fab387" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<text x="16" y="20" text-anchor="middle" font-family="sans-serif" font-size="8" font-weight="bold" fill="#313244">B</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 344 B |
5
kindred-icons/Std_ViewRight.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M12 6 L24 16 L12 26 Z" fill="#fab387" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<text x="17" y="20" text-anchor="middle" font-family="sans-serif" font-size="7" font-weight="bold" fill="#313244">R</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 335 B |
13
kindred-icons/Std_ViewScreenShot.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Camera body -->
|
||||
<rect x="5" y="10" width="22" height="14" rx="2" fill="#45475a" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<!-- Lens -->
|
||||
<circle cx="16" cy="17" r="5" fill="#1e1e2e" stroke="#fab387" stroke-width="1.5"/>
|
||||
<circle cx="16" cy="17" r="3" fill="#45475a"/>
|
||||
<circle cx="16" cy="17" r="1.5" fill="#f9e2af"/>
|
||||
<!-- Flash -->
|
||||
<rect x="20" y="12" width="4" height="2" rx="0.5" fill="#cdd6f4"/>
|
||||
<!-- Viewfinder bump -->
|
||||
<rect x="12" y="7" width="8" height="4" rx="1" fill="#585b70" stroke="#f9e2af" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 676 B |
5
kindred-icons/Std_ViewTop.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M6 20 L16 8 L26 20 Z" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<text x="16" y="19" text-anchor="middle" font-family="sans-serif" font-size="7" font-weight="bold" fill="#313244">T</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 334 B |
5
kindred-icons/Std_ViewTrimetric.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M5 16 L16 10 L27 16 L27 24 L16 30 L5 24 Z" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M5 16 L16 22 L27 16 M16 22 L16 30" fill="none" stroke="#313244" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
17
kindred-icons/TechDrawWorkbench.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Drawing sheet -->
|
||||
<rect x="5" y="5" width="22" height="22" rx="1" fill="#45475a" stroke="#cba6f7" stroke-width="1.5"/>
|
||||
<!-- Title block -->
|
||||
<rect x="5" y="22" width="22" height="5" fill="#585b70" stroke="#cba6f7" stroke-width="1"/>
|
||||
<!-- Technical drawing - front view -->
|
||||
<rect x="8" y="8" width="8" height="6" fill="none" stroke="#b4befe" stroke-width="1.5"/>
|
||||
<!-- Hidden line -->
|
||||
<line x1="10" y1="11" x2="14" y2="11" stroke="#b4befe" stroke-width="1" stroke-dasharray="2,1"/>
|
||||
<!-- Dimension line -->
|
||||
<line x1="8" y1="17" x2="16" y2="17" stroke="#cdd6f4" stroke-width="0.75"/>
|
||||
<line x1="8" y1="16" x2="8" y2="18" stroke="#cdd6f4" stroke-width="0.75"/>
|
||||
<line x1="16" y1="16" x2="16" y2="18" stroke="#cdd6f4" stroke-width="0.75"/>
|
||||
<!-- Side view -->
|
||||
<rect x="19" y="8" width="6" height="6" fill="none" stroke="#b4befe" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1008 B |
8
kindred-icons/TextDocument.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 6 L20 6 L24 10 L24 26 L8 26 Z" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M20 6 L20 10 L24 10" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="11" y1="14" x2="21" y2="14" stroke="#cdd6f4" stroke-width="1"/>
|
||||
<line x1="11" y1="17" x2="21" y2="17" stroke="#cdd6f4" stroke-width="1"/>
|
||||
<line x1="11" y1="20" x2="18" y2="20" stroke="#cdd6f4" stroke-width="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 528 B |