Compare commits

..

5 Commits

Author SHA1 Message Date
a91d8c07b6 Regenerate docs 2023-09-18 10:45:14 -05:00
d8102252e1 Remove dbg 2023-09-18 10:28:14 -05:00
1d8b0cb12f Use angle object in more places 2023-09-18 10:19:39 -05:00
88685c24cc More conversions 2023-09-18 10:16:28 -05:00
118b642cc5 Start using rich angles 2023-09-18 10:14:15 -05:00
68 changed files with 843 additions and 1539 deletions

View File

@ -4,11 +4,12 @@ on:
pull_request:
push:
branches:
- main
- main
release:
types: [published]
jobs:
check-format:
runs-on: 'ubuntu-20.04'
steps:
@ -32,16 +33,18 @@ jobs:
- run: yarn install
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
workspaces: "./src/wasm-lib"
- run: yarn build:wasm
- run: yarn tsc
build-test-web:
runs-on: ubuntu-20.04
outputs:
version: ${{ steps.export_version.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
@ -53,7 +56,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
workspaces: "./src/wasm-lib"
- run: yarn build:wasm
@ -66,6 +69,7 @@ jobs:
- id: export_version
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
build-apps:
needs: [check-format, build-test-web, check-types]
runs-on: ${{ matrix.os }}
@ -73,6 +77,7 @@ jobs:
matrix:
os: [macos-latest, ubuntu-20.04, windows-latest]
steps:
- uses: actions/checkout@v4
- name: install ubuntu system dependencies
@ -99,7 +104,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
workspaces: "./src/wasm-lib"
- name: wasm prep
shell: bash
@ -109,6 +114,18 @@ jobs:
cd ../../
cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
- name: macos sed
if: matrix.os == 'macos-latest'
shell: bash
run: |
sed -i '' 's/import.meta.url//g' "./src/wasm-lib/pkg/wasm_lib.js"
- name: ubuntu and windows sed
if: matrix.os != 'macos-latest'
shell: bash
run: |
sed -i 's/import.meta.url//g' "./src/wasm-lib/pkg/wasm_lib.js"
- name: Fix format
run: yarn fmt
@ -119,29 +136,29 @@ jobs:
- name: Prepare Windows certificate and variables
if: matrix.os == 'windows-latest'
run: |
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
cat /d/Certificate_pkcs12.p12
echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH
echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH
echo "C:\Program Files\DigiCert\DigiCert One Signing Manager Tools" >> $GITHUB_PATH
shell: bash
run: |
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
cat /d/Certificate_pkcs12.p12
echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH
echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH
echo "C:\Program Files\DigiCert\DigiCert One Signing Manager Tools" >> $GITHUB_PATH
shell: bash
- name: Setup Windows certicate with SSM KSP
if: matrix.os == 'windows-latest'
run: |
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
msiexec /i smtools-windows-x64.msi /quiet /qn
smksp_registrar.exe list
smctl.exe keypair ls
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
smksp_cert_sync.exe
shell: cmd
run: |
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
msiexec /i smtools-windows-x64.msi /quiet /qn
smksp_registrar.exe list
smctl.exe keypair ls
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
smksp_cert_sync.exe
shell: cmd
- name: Build and sign the app for the current platform
uses: tauri-apps/tauri-action@v0
@ -160,6 +177,7 @@ jobs:
with:
path: ${{ matrix.os == 'macos-latest' && 'src-tauri/target/universal-apple-darwin/release/bundle/*/*' || 'src-tauri/target/release/bundle/*/*' }}
publish-apps-release:
runs-on: ubuntu-20.04
if: github.event_name == 'release'
@ -169,6 +187,7 @@ jobs:
PUB_DATE: ${{ github.event.release.created_at }}
NOTES: ${{ github.event.release.body }}
steps:
- uses: actions/download-artifact@v3
- name: Generate the update static endpoint

View File

@ -514,10 +514,18 @@
],
"returnValue": {
"name": "",
"type": "number",
"type": "Angle",
"schema": {
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"required": true
},
@ -983,10 +991,18 @@
],
"returnValue": {
"name": "",
"type": "number",
"type": "Angle",
"schema": {
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"required": true
},
@ -1016,8 +1032,16 @@
"properties": {
"angle": {
"description": "The angle of the line.",
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"length": {
"description": "The length of the line.",
@ -1033,10 +1057,24 @@
{
"description": "An angle and length.",
"type": "array",
"items": {
"type": "number",
"format": "double"
},
"items": [
{
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
{
"type": "number",
"format": "double"
}
],
"maxItems": 2,
"minItems": 2
}
@ -1937,8 +1975,16 @@
"properties": {
"angle": {
"description": "The angle of the line.",
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"length": {
"description": "The length of the line.",
@ -1954,10 +2000,24 @@
{
"description": "An angle and length.",
"type": "array",
"items": {
"type": "number",
"format": "double"
},
"items": [
{
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
{
"type": "number",
"format": "double"
}
],
"maxItems": 2,
"minItems": 2
}
@ -2858,8 +2918,16 @@
"properties": {
"angle": {
"description": "The angle of the line.",
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"length": {
"description": "The length of the line.",
@ -2875,10 +2943,24 @@
{
"description": "An angle and length.",
"type": "array",
"items": {
"type": "number",
"format": "double"
},
"items": [
{
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
{
"type": "number",
"format": "double"
}
],
"maxItems": 2,
"minItems": 2
}
@ -3775,8 +3857,16 @@
"properties": {
"angle": {
"description": "The angle of the line.",
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"intersectTag": {
"description": "The tag of the line to intersect with.",
@ -4690,8 +4780,16 @@
"properties": {
"angle": {
"description": "The angle of the line.",
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"tag": {
"description": "The tag.",
@ -4707,10 +4805,24 @@
{
"description": "An angle and point to draw to.",
"type": "array",
"items": {
"type": "number",
"format": "double"
},
"items": [
{
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
{
"type": "number",
"format": "double"
}
],
"maxItems": 2,
"minItems": 2
}
@ -5611,8 +5723,16 @@
"properties": {
"angle": {
"description": "The angle of the line.",
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"tag": {
"description": "The tag.",
@ -5628,10 +5748,24 @@
{
"description": "An angle and point to draw to.",
"type": "array",
"items": {
"type": "number",
"format": "double"
},
"items": [
{
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
{
"type": "number",
"format": "double"
}
],
"maxItems": 2,
"minItems": 2
}
@ -13889,10 +14023,18 @@
],
"returnValue": {
"name": "",
"type": "number",
"type": "Angle",
"schema": {
"type": "number",
"format": "double"
"type": "object",
"required": [
"degrees"
],
"properties": {
"degrees": {
"type": "number",
"format": "double"
}
}
},
"required": true
},

View File

@ -106,7 +106,7 @@ Returns the angle to match the given length for x.
```
angleToMatchLengthX(segment_name: string, to: number, sketch_group: SketchGroup) -> number
angleToMatchLengthX(segment_name: string, to: number, sketch_group: SketchGroup) -> Angle
```
#### Arguments
@ -179,7 +179,12 @@ angleToMatchLengthX(segment_name: string, to: number, sketch_group: SketchGroup)
#### Returns
* `number`
* `Angle`
```
{
degrees: number,
}
```
@ -190,7 +195,7 @@ Returns the angle to match the given length for y.
```
angleToMatchLengthY(segment_name: string, to: number, sketch_group: SketchGroup) -> number
angleToMatchLengthY(segment_name: string, to: number, sketch_group: SketchGroup) -> Angle
```
#### Arguments
@ -263,7 +268,12 @@ angleToMatchLengthY(segment_name: string, to: number, sketch_group: SketchGroup)
#### Returns
* `number`
* `Angle`
```
{
degrees: number,
}
```
@ -283,13 +293,15 @@ angledLine(data: AngledLineData, sketch_group: SketchGroup) -> SketchGroup
```
{
// The angle of the line.
angle: number,
angle: {
degrees: number,
},
// The length of the line.
length: number,
// The tag.
tag: string,
} |
[number]
string
```
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
```
@ -439,13 +451,15 @@ angledLineOfXLength(data: AngledLineData, sketch_group: SketchGroup) -> SketchGr
```
{
// The angle of the line.
angle: number,
angle: {
degrees: number,
},
// The length of the line.
length: number,
// The tag.
tag: string,
} |
[number]
string
```
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
```
@ -595,13 +609,15 @@ angledLineOfYLength(data: AngledLineData, sketch_group: SketchGroup) -> SketchGr
```
{
// The angle of the line.
angle: number,
angle: {
degrees: number,
},
// The length of the line.
length: number,
// The tag.
tag: string,
} |
[number]
string
```
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
```
@ -751,7 +767,9 @@ angledLineThatIntersects(data: AngeledLineThatIntersectsData, sketch_group: Sket
```
{
// The angle of the line.
angle: number,
angle: {
degrees: number,
},
// The tag of the line to intersect with.
intersectTag: string,
// The offset from the intersecting line.
@ -908,13 +926,15 @@ angledLineToX(data: AngledLineToData, sketch_group: SketchGroup) -> SketchGroup
```
{
// The angle of the line.
angle: number,
angle: {
degrees: number,
},
// The tag.
tag: string,
// The point to draw to.
to: number,
} |
[number]
string
```
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
```
@ -1064,13 +1084,15 @@ angledLineToY(data: AngledLineToData, sketch_group: SketchGroup) -> SketchGroup
```
{
// The angle of the line.
angle: number,
angle: {
degrees: number,
},
// The tag.
tag: string,
// The point to draw to.
to: number,
} |
[number]
string
```
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
```
@ -2680,7 +2702,7 @@ Returns the angle of the segment.
```
segAng(segment_name: string, sketch_group: SketchGroup) -> number
segAng(segment_name: string, sketch_group: SketchGroup) -> Angle
```
#### Arguments
@ -2752,7 +2774,12 @@ segAng(segment_name: string, sketch_group: SketchGroup) -> number
#### Returns
* `number`
* `Angle`
```
{
degrees: number,
}
```

View File

@ -1,6 +1,6 @@
{
"name": "untitled-app",
"version": "0.8.2",
"version": "0.7.1",
"private": true,
"dependencies": {
"@codemirror/autocomplete": "^6.9.0",
@ -57,22 +57,20 @@
"zustand": "^4.1.4"
},
"scripts": {
"start": "BROWSER=none vite",
"start": "vite",
"build": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source \"$HOME/.cargo/env\" && curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -y && yarn build:wasm && vite build",
"build:local": "vite build",
"build:both": "vite build",
"build:both:local": "yarn build:wasm && vite build",
"pretest": "yarn remove-importmeta",
"test": "vitest --mode development",
"test:nowatch": "vitest run --mode development",
"test:rust": "(cd src/wasm-lib && cargo test --all && cargo clippy --all --tests)",
"test:cov": "vitest run --coverage --mode development",
"simpleserver:ci": "yarn pretest && http-server ./public --cors -p 3000 &",
"simpleserver": "yarn pretest && http-server ./public --cors -p 3000",
"simpleserver:ci": "http-server ./public --cors -p 3000 &",
"simpleserver": "http-server ./public --cors -p 3000",
"fmt": "prettier --write ./src",
"fmt-check": "prettier --check ./src",
"build:wasm": "(cd src/wasm-lib && wasm-pack build --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn fmt",
"build:wasm-clean": "yarn wasm-prep && yarn build:wasm",
"build:wasm": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn fmt && yarn remove-importmeta",
"remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\" || echo \"sed for both mac and linux\"",
"wasm-prep": "rm -rf src/wasm-lib/pkg && mkdir src/wasm-lib/pkg && rm -rf src/wasm-lib/kcl/bindings",
"lint": "eslint --fix src",

26
src-tauri/Cargo.lock generated
View File

@ -2182,17 +2182,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "os_info"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e"
dependencies = [
"log",
"serde",
"winapi",
]
[[package]]
name = "overload"
version = "0.1.1"
@ -3480,19 +3469,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sys-locale"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8a11bd9c338fdba09f7881ab41551932ad42e405f61d01e8406baea71c07aee"
dependencies = [
"js-sys",
"libc",
"wasm-bindgen",
"web-sys",
"windows-sys 0.45.0",
]
[[package]]
name = "system-deps"
version = "5.0.0"
@ -3628,7 +3604,6 @@ dependencies = [
"objc",
"once_cell",
"open",
"os_info",
"percent-encoding",
"rand 0.8.5",
"raw-window-handle",
@ -3641,7 +3616,6 @@ dependencies = [
"serde_repr",
"serialize-to-javascript",
"state",
"sys-locale",
"tar",
"tauri-macros",
"tauri-runtime",

View File

@ -20,7 +20,7 @@ kittycad = "0.2.25"
oauth2 = "4.4.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tauri = { version = "1.4.1", features = [ "os-all", "dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "updater", "devtools"] }
tauri = { version = "1.4.1", features = ["dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "updater", "devtools"] }
tauri-plugin-fs-extra = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tokio = { version = "1.32.0", features = ["time"] }
toml = "0.8.0"

View File

@ -6,7 +6,6 @@ use std::io::Read;
use anyhow::Result;
use oauth2::TokenResponse;
use tauri::{InvokeError, Manager};
const DEFAULT_HOST: &str = "https://api.kittycad.io";
/// This command returns the a json string parse from a toml file at the path.
#[tauri::command]
@ -89,34 +88,11 @@ async fn login(app: tauri::AppHandle, host: &str) -> Result<String, InvokeError>
///This command returns the KittyCAD user info given a token.
/// The string returned from this method is the user info as a json string.
#[tauri::command]
async fn get_user(
token: Option<String>,
hostname: &str,
) -> Result<kittycad::types::User, InvokeError> {
// Use the host passed in if it's set.
// Otherwise, use the default host.
let host = if hostname.is_empty() {
DEFAULT_HOST.to_string()
} else {
hostname.to_string()
};
// Change the baseURL to the one we want.
let mut baseurl = host.to_string();
if !host.starts_with("http://") && !host.starts_with("https://") {
baseurl = format!("https://{host}");
if host.starts_with("localhost") {
baseurl = format!("http://{host}")
}
}
async fn get_user(token: Option<String>) -> Result<kittycad::types::User, InvokeError> {
println!("Getting user info...");
// use kittycad library to fetch the user info from /user/me
let mut client = kittycad::Client::new(token.unwrap());
if baseurl != DEFAULT_HOST {
client.set_base_url(&baseurl);
}
let client = kittycad::Client::new(token.unwrap());
let user_info: kittycad::types::User = client
.users()

View File

@ -8,7 +8,7 @@
},
"package": {
"productName": "kittycad-modeling",
"version": "0.8.2"
"version": "0.7.1"
},
"tauri": {
"allowlist": {
@ -36,9 +36,6 @@
"https://api.dev.kittycad.io/*"
]
},
"os": {
"all": true
},
"shell": {
"open": true
},

View File

@ -6,9 +6,9 @@ export const Auth = ({ children }: React.PropsWithChildren) => {
const {
auth: { state },
} = useGlobalStateContext()
const isLoggingIn = state.matches('checkIfLoggedIn')
const isLoggedIn = state.matches('checkIfLoggedIn')
return isLoggingIn ? (
return isLoggedIn ? (
<Loading>Loading KittyCAD Modeling App...</Loading>
) : (
<>{children}</>

View File

@ -130,7 +130,6 @@ const router = createBrowserRouter(
path: paths.INDEX,
loader: () =>
isTauri() ? redirect(paths.HOME) : redirect(paths.FILE + '/new'),
errorElement: <ErrorPage />,
},
{
path: paths.FILE + '/:id',
@ -141,6 +140,7 @@ const router = createBrowserRouter(
{!isTauri() && import.meta.env.PROD && <DownloadAppBanner />}
</Auth>
),
errorElement: <ErrorPage />,
id: paths.FILE,
loader: async ({
request,

View File

@ -23,8 +23,7 @@ export const CodeMenu = ({ children }: PropsWithChildren) => {
<div
className="relative"
onClick={(e) => {
const target = e.target as HTMLElement
if (e.eventPhase === 3 && target.closest('a') === null) {
if (e.eventPhase === 3) {
e.stopPropagation()
e.preventDefault()
}

View File

@ -62,7 +62,7 @@ export const CommandBarProvider = ({
const CommandBar = () => {
const { commands, commandBarOpen, setCommandBarOpen } = useCommandsContext()
useHotkeys(['meta+k', 'meta+/'], () => {
useHotkeys('meta+k', () => {
if (commands.length === 0) return
setCommandBarOpen(!commandBarOpen)
})
@ -221,10 +221,10 @@ const CommandBar = () => {
<Combobox
value={selectedCommand}
onChange={handleCommandSelection}
className="relative w-full max-w-xl p-2 mx-auto border rounded shadow-lg bg-chalkboard-10 dark:bg-chalkboard-100 dark:border-chalkboard-70"
className="rounded relative mx-auto p-2 bg-chalkboard-10 dark:bg-chalkboard-100 border dark:border-chalkboard-70 max-w-xl w-full shadow-lg"
as="div"
>
<div className="flex items-center gap-2">
<div className="flex gap-2 items-center">
<ActionIcon icon={faSearch} size="xl" className="rounded-sm" />
<div>
{inSubCommand && (
@ -235,7 +235,7 @@ const CommandBar = () => {
)}
<Combobox.Input
onChange={(event) => setQuery(event.target.value)}
className="w-full bg-transparent focus:outline-none"
className="bg-transparent focus:outline-none w-full"
onKeyDown={(event) => {
if (event.metaKey && event.key === 'k')
setCommandBarOpen(false)
@ -264,12 +264,12 @@ const CommandBar = () => {
/>
</div>
</div>
<Combobox.Options static className="overflow-y-auto max-h-96">
<Combobox.Options static className="max-h-96 overflow-y-auto">
{filteredCommands?.map((commandResult) => (
<Combobox.Option
key={commandResult.item.name}
value={commandResult}
className="px-2 py-1 my-2 first:mt-4 last:mb-4 ui-active:bg-liquid-10 dark:ui-active:bg-liquid-90"
className="my-2 first:mt-4 last:mb-4 ui-active:bg-liquid-10 dark:ui-active:bg-liquid-90 py-1 px-2"
>
<p>{commandResult.item.name}</p>
{(commandResult.item as SubCommand).description && (

View File

@ -54,8 +54,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M10 3L10.3536 3.35355L12.3536 5.35355L11.6465 6.06066L10.5 4.91421V11.5854C11.0826 11.7913 11.5 12.3469 11.5 13C11.5 13.8284 10.8284 14.5 10 14.5C9.17157 14.5 8.5 13.8284 8.5 13C8.5 12.3469 8.91741 11.7913 9.5 11.5854V4.91421L8.35356 6.06066L7.64645 5.35355L9.64645 3.35355L10 3ZM1.95887 12.3282L8 8.63644V9.80838L2.91773 12.9142L10 17.2423L17.0823 12.9142L12 9.80838V8.63644L18.0411 12.3282L19 12.9142L19 14.9683H18V13.5253L10.5 18.1087V19.9683H9.5V18.1087L2 13.5253V14.9683H1L1 12.9142L1.95887 12.3282Z"
fill="currentColor"
/>
@ -70,8 +70,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M4 9.5H16V11.5H4V9.5Z"
fill="currentColor"
/>
@ -86,8 +86,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M15.5 6C16.3284 6 17 5.32843 17 4.5C17 3.67157 16.3284 3 15.5 3C14.6716 3 14 3.67157 14 4.5C14 4.73107 14.0522 4.94993 14.1456 5.14543L5.14543 14.1456C4.94993 14.0522 4.73107 14 4.5 14C3.67157 14 3 14.6716 3 15.5C3 16.3284 3.67157 17 4.5 17C5.32843 17 6 16.3284 6 15.5C6 15.2679 5.94729 15.0482 5.8532 14.852L14.852 5.8532C15.0482 5.94729 15.2679 6 15.5 6Z"
fill="currentColor"
/>
@ -102,8 +102,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M10 2.29289L10.3536 2.64645L12.3536 4.64645L11.6465 5.35355L10.5 4.20711V8V9.50001H12L15.7929 9.50001L14.6465 8.35356L15.3536 7.64645L17.3536 9.64645L17.7071 10L17.3536 10.3536L15.3536 12.3536L14.6465 11.6465L15.7929 10.5H12H10.5V12V15.7929L11.6465 14.6464L12.3536 15.3536L10.3536 17.3536L10 17.7071L9.64645 17.3536L7.64645 15.3536L8.35356 14.6464L9.50001 15.7929V12V10.5H8.00001H4.20712L5.35357 11.6465L4.64646 12.3536L2.64646 10.3536L2.29291 10L2.64646 9.64645L4.64646 7.64645L5.35357 8.35356L4.20712 9.50001H8.00001H9.50001V8V4.20711L8.35356 5.35355L7.64645 4.64645L9.64645 2.64645L10 2.29289Z"
fill="currentColor"
/>
@ -118,8 +118,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 16V4H6V16H8ZM14 16V4H12V16H14Z"
fill="currentColor"
/>
@ -134,8 +134,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.8037 13.4035L15.5509 14.1635L16.3682 16.8386L13.5521 16.1346L12.8186 15.3885L14.8037 13.4035ZM14.1025 12.6903L12.1175 14.6754L3.48609 5.89624C2.94588 5.34678 2.94963 4.46456 3.49448 3.91971C4.04591 3.36828 4.94112 3.37208 5.48786 3.92817L14.1025 12.6903ZM6.20094 3.22709L16.4357 13.6371L17.5003 17.1216L17.8412 18.2376L16.7091 17.9546L13.0364 17.0364L2.77301 6.59732C1.84793 5.6564 1.85434 4.14564 2.78737 3.2126C3.73167 2.2683 5.26468 2.27481 6.20094 3.22709Z"
fill="currentColor"
/>
@ -150,8 +150,8 @@ export const CustomIcon = ({
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M11 4V16H9V4H11Z"
fill="currentColor"
/>

View File

@ -30,11 +30,7 @@ export const DebugPanel = ({ className, ...props }: CollapsiblePanelProps) => {
return (
<CollapsiblePanel
{...props}
className={
'!absolute overflow-hidden !h-auto bottom-5 right-5 ' + className
}
// header height, top-5, and bottom-5
style={{ maxHeight: 'calc(100% - 3rem - 1.25rem - 1.25rem)' }}
className={'!absolute !h-auto bottom-5 right-5 ' + className}
>
<section className="p-4 flex flex-col gap-4">
<Xyz

View File

@ -1,12 +1,4 @@
import { isTauri } from 'lib/isTauri'
import { useRouteError, isRouteErrorResponse } from 'react-router-dom'
import { ActionButton } from './ActionButton'
import {
faBug,
faHome,
faRefresh,
faTrash,
} from '@fortawesome/free-solid-svg-icons'
import { useRouteError } from 'react-router-dom'
export const ErrorPage = () => {
let error = useRouteError()
@ -19,43 +11,7 @@ export const ErrorPage = () => {
<h1 className="text-4xl mb-8 font-bold">
An unexpected error occurred
</h1>
{isRouteErrorResponse(error) && (
<p className="mb-8">
{error.status}: {error.data}
</p>
)}
<div className="flex justify-between gap-2 mt-6">
{isTauri() && (
<ActionButton Element="link" to={'/'} icon={{ icon: faHome }}>
Go Home
</ActionButton>
)}
<ActionButton
Element="button"
icon={{ icon: faRefresh }}
onClick={() => window.location.reload()}
>
Reload
</ActionButton>
<ActionButton
Element="button"
icon={{ icon: faTrash }}
onClick={() => {
window.localStorage.clear()
}}
>
Clear storage
</ActionButton>
<ActionButton
Element="link"
icon={{ icon: faBug }}
target="_blank"
rel="noopener noreferrer"
to="https://discord.com/channels/915388055236509727/1138967922614743060"
>
Report Bug
</ActionButton>
</div>
<p>{String(error)}</p>
</section>
</div>
)

View File

@ -24,11 +24,7 @@ export const MemoryPanel = ({
<CollapsiblePanel {...props}>
<div className="h-full relative">
<div className="absolute inset-0 flex flex-col items-start">
<div
className="overflow-y-auto h-full console-tile w-full"
style={{ marginBottom: 36 }}
>
{/* 36px is the height of PanelHeader */}
<div className=" h-full console-tile w-full">
<ReactJson
src={ProcessedMemory}
collapsed={1}

View File

@ -0,0 +1,42 @@
import { invoke } from '@tauri-apps/api/tauri'
import { open } from '@tauri-apps/api/dialog'
import { useStore } from '../useStore'
export const OpenFileButton = () => {
const { setCode } = useStore((s) => ({
setCode: s.setCode,
}))
const handleClick = async () => {
const selected = await open({
multiple: false,
directory: false,
filters: [
{
name: 'CAD',
extensions: ['toml'],
},
],
})
if (Array.isArray(selected)) {
// User selected multiple files
// We should not get here, since multiple is false.
} else if (selected === null) {
// User cancelled the selection
// Do nothing.
} else {
// User selected a single file
// We want to invoke our command to read the file.
const json: string = await invoke('read_toml', { path: selected })
const packageDetails = JSON.parse(json).package
if (packageDetails.main) {
const absPath = [
...selected.split('/').slice(0, -1),
packageDetails.main,
].join('/')
const file: string = await invoke('read_txt_file', { path: absPath })
setCode(file)
}
}
}
return <button onClick={() => handleClick()}>Open File</button>
}

View File

@ -16,8 +16,8 @@ const ProjectSidebarMenu = ({
}) => {
return renderAsLink ? (
<Link
to={paths.HOME}
className="h-9 max-h-min min-w-max border-0 p-0.5 pr-2 flex items-center gap-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50"
to={'../'}
className="flex items-center gap-4 my-2"
data-testid="project-sidebar-link"
>
<img
@ -26,7 +26,7 @@ const ProjectSidebarMenu = ({
className="h-9 w-auto"
/>
<span
className="text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap hidden lg:block"
className="text-sm text-chalkboard-110 dark:text-chalkboard-20 min-w-max truncate"
data-testid="project-sidebar-link-name"
>
{project?.name ? project.name : 'KittyCAD Modeling App'}
@ -43,7 +43,7 @@ const ProjectSidebarMenu = ({
alt="KittyCAD App"
className="h-full w-auto"
/>
<span className="text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap hidden lg:block">
<span className="text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap hidden 2xl:block">
{isTauri() && project?.name ? project.name : 'KittyCAD Modeling App'}
</span>
</Popover.Button>

View File

@ -2,7 +2,7 @@ import { Popover, Transition } from '@headlessui/react'
import { ActionButton } from './ActionButton'
import { faBars, faGear, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { useLocation, useNavigate } from 'react-router-dom'
import { useNavigate } from 'react-router-dom'
import { Fragment, useState } from 'react'
import { paths } from '../Router'
import makeUrlPathRelative from '../lib/makeUrlPathRelative'
@ -12,7 +12,6 @@ import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
type User = Models['User_type']
const UserSidebarMenu = ({ user }: { user?: User }) => {
const location = useLocation()
const displayedName = getDisplayName(user)
const [imageLoadFailed, setImageLoadFailed] = useState(false)
const navigate = useNavigate()
@ -127,11 +126,7 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
// since /settings is a nested route the sidebar doesn't close
// automatically when navigating to it
close()
navigate(
(location.pathname.endsWith('/')
? location.pathname.slice(0, -1)
: location.pathname) + paths.SETTINGS
)
navigate(makeUrlPathRelative(paths.SETTINGS))
}}
>
Settings

View File

@ -5,6 +5,8 @@ import init, {
} from '../../wasm-lib/pkg/wasm_lib'
import { FromServer, IntoServer } from './codec'
let server: null | Server
export default class Server {
readonly initOutput: InitOutput
readonly #intoServer: IntoServer
@ -24,8 +26,12 @@ export default class Server {
intoServer: IntoServer,
fromServer: FromServer
): Promise<Server> {
const initOutput = await init()
const server = new Server(initOutput, intoServer, fromServer)
if (null == server) {
const initOutput = await init()
server = new Server(initOutput, intoServer, fromServer)
} else {
console.warn('Server already initialized; ignoring')
}
return server
}

View File

@ -1,13 +0,0 @@
import { useLocation } from 'react-router-dom'
export function useDotDotSlash(): (count?: number) => string {
const location = useLocation()
const dotDotSlash = (count = 1): string => {
// since we can't use relative paths (../) for windows
if (location.pathname === '/') return ''
const path = location.pathname.slice(0, location.pathname.lastIndexOf('/'))
if (count <= 1) return path
return dotDotSlash(count - 1)
}
return dotDotSlash
}

View File

@ -31,14 +31,6 @@ body.dark {
@apply text-chalkboard-10;
}
select {
@apply bg-chalkboard-20;
}
.dark select {
@apply bg-chalkboard-90;
}
::-webkit-scrollbar {
@apply w-2 h-2 rounded-sm;
@apply bg-chalkboard-20;

View File

@ -1512,7 +1512,7 @@ const yo = { a: { b: { c: '123' } } }
// this is a comment
const key = 'c'`
const nonCodeMetaInstance = {
type: 'NonCodeNode',
type: 'NoneCodeNode',
start: code.indexOf('\n// this is a comment'),
end: code.indexOf('const key'),
value: {
@ -1521,17 +1521,17 @@ const key = 'c'`
},
}
const { nonCodeMeta } = parser_wasm(code)
expect(nonCodeMeta.nonCodeNodes[0]).toEqual(nonCodeMetaInstance)
expect(nonCodeMeta.noneCodeNodes[0]).toEqual(nonCodeMetaInstance)
// extra whitespace won't change it's position (0) or value (NB the start end would have changed though)
const codeWithExtraStartWhitespace = '\n\n\n' + code
const { nonCodeMeta: nonCodeMeta2 } = parser_wasm(
codeWithExtraStartWhitespace
)
expect(nonCodeMeta2.nonCodeNodes[0].value).toStrictEqual(
expect(nonCodeMeta2.noneCodeNodes[0].value).toStrictEqual(
nonCodeMetaInstance.value
)
expect(nonCodeMeta2.nonCodeNodes[0].start).not.toBe(
expect(nonCodeMeta2.noneCodeNodes[0].start).not.toBe(
nonCodeMetaInstance.start
)
})
@ -1548,9 +1548,9 @@ const key = 'c'`
const { body } = parser_wasm(code)
const indexOfSecondLineToExpression = 2
const sketchNonCodeMeta = (body as any)[0].declarations[0].init.nonCodeMeta
.nonCodeNodes
.noneCodeNodes
expect(sketchNonCodeMeta[indexOfSecondLineToExpression]).toEqual({
type: 'NonCodeNode',
type: 'NoneCodeNode',
start: 106,
end: 166,
value: {
@ -1571,9 +1571,9 @@ const key = 'c'`
const { body } = parser_wasm(code)
const sketchNonCodeMeta = (body[0] as any).declarations[0].init.nonCodeMeta
.nonCodeNodes
.noneCodeNodes
expect(sketchNonCodeMeta[3]).toEqual({
type: 'NonCodeNode',
type: 'NoneCodeNode',
start: 125,
end: 141,
value: {

View File

@ -33,5 +33,5 @@ export type SyntaxType =
| 'PipeExpression'
| 'PipeSubstitution'
| 'Literal'
| 'NonCodeNode'
| 'NoneCodeNode'
| 'UnaryExpression'

View File

@ -106,7 +106,7 @@ describe('Testing addSketchTo', () => {
body: [],
start: 0,
end: 0,
nonCodeMeta: { nonCodeNodes: {}, start: null },
nonCodeMeta: { noneCodeNodes: {}, start: null },
},
'yz'
)

View File

@ -537,7 +537,7 @@ export function createPipeExpression(
start: 0,
end: 0,
body,
nonCodeMeta: { nonCodeNodes: {}, start: null },
nonCodeMeta: { noneCodeNodes: {}, start: null },
}
}

View File

@ -4,7 +4,6 @@ import withBaseURL from '../lib/withBaseURL'
import { CommandBarMeta } from '../lib/commands'
import { isTauri } from 'lib/isTauri'
import { invoke } from '@tauri-apps/api'
import { VITE_KC_API_BASE_URL } from 'env'
const SKIP_AUTH =
import.meta.env.VITE_KC_SKIP_AUTH === 'true' && import.meta.env.DEV
@ -133,7 +132,6 @@ async function getUser(context: UserContext) {
.catch((err) => console.error('error from Browser getUser', err))
: invoke<Models['User_type'] | Record<'error_code', unknown>>('get_user', {
token: context.token,
hostname: VITE_KC_API_BASE_URL,
}).catch((err) => console.error('error from Tauri getUser', err))
const user = await userPromise

View File

@ -26,7 +26,7 @@ export default function Units() {
} = useGlobalStateContext()
return (
<div className="fixed inset-0 z-50 grid items-end justify-start px-4 pointer-events-none">
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
<div
className={
'max-w-2xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
@ -35,12 +35,11 @@ export default function Units() {
>
<SettingsSection
title="Camera Controls"
description="How you want to control the camera in the 3D view. Try them out above and choose the one that feels most comfortable to you."
className="my-4 last-of-type:mb-12"
description="How you want to control the camera in the 3D view. Try them out in the 3D view."
>
<select
id="camera-controls"
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
value={cameraControls}
onChange={(e) => {
send({
@ -55,7 +54,7 @@ export default function Units() {
</option>
))}
</select>
<ul className="mx-4 my-2 text-sm leading-relaxed">
<ul className="text-sm my-2 mx-4 leading-relaxed">
<li>
<strong>Pan:</strong>{' '}
{cameraMouseDragGuards[cameraControls].pan.description}
@ -73,7 +72,7 @@ export default function Units() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -2,8 +2,6 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { Platform, platform } from '@tauri-apps/api/os'
import { useEffect, useState } from 'react'
export default function CmdK() {
const { buttonDownInStream } = useStore((s) => ({
@ -11,17 +9,9 @@ export default function CmdK() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.USER_MENU)
const [platformName, setPlatformName] = useState<Platform | ''>('')
useEffect(() => {
async function getPlatform() {
setPlatformName(await platform())
}
getPlatform()
}, [setPlatformName])
return (
<div className="fixed inset-0 z-50 grid items-end justify-center pointer-events-none">
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
<div
className={
'max-w-full xl:max-w-4xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
@ -30,17 +20,8 @@ export default function CmdK() {
>
<h2 className="text-2xl">Command Bar</h2>
<p className="my-4">
Press{' '}
{platformName === 'win32' ? (
<>
<kbd>Win</kbd> + <kbd>/</kbd>
</>
) : (
<>
<kbd>OS</kbd> + <kbd>K</kbd>
</>
)}{' '}
to open the command bar. Try changing your theme with it.
Press <kbd>Cmd/Win</kbd> + <kbd>K</kbd> to open the command bar. Try
changing your camera controls with it.
</p>
<p className="my-4">
We are working on a command bar that will allow you to quickly see and
@ -60,7 +41,7 @@ export default function CmdK() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -60,7 +60,7 @@ export default function CodeEditor() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -40,7 +40,7 @@ export default function Export() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -7,13 +7,13 @@ import { bracket } from 'lib/exampleKcl'
export default function FutureWork() {
const dismiss = useDismiss()
const { deferredSetCode } = useStore((s) => ({
deferredSetCode: s.deferredSetCode,
const { setCode } = useStore((s) => ({
setCode: s.setCode,
}))
useEffect(() => {
deferredSetCode(bracket)
}, [deferredSetCode])
setCode(bracket)
}, [setCode])
return (
<div className="fixed grid justify-center items-center inset-0 bg-chalkboard-100/50 z-50">
@ -34,7 +34,7 @@ export default function FutureWork() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -47,7 +47,7 @@ export default function FutureWork() {
</ActionButton>
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{ icon: faArrowRight }}
>
Finish

View File

@ -30,46 +30,46 @@ export default function InteractiveNumbers() {
</p>
<p className="my-4">
Try changing the value of <code>width</code> on line 3 by holding
the <kbd>Alt</kbd> (or <kbd>Option</kbd>) key and dragging the
number left and right. You can hold down different modifier keys to
change the value by different increments:
the <kbd>Alt</kbd> key and dragging the number left and right. You
can hold down different modifier keys to change the value by
different increments:
<table className="border-collapse text-sm mx-auto my-4">
<tbody>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt + Shift + Cmd/Win</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
0.01
</td>
</tr>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt + Cmd/Win</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
0.1
</td>
</tr>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
1
</td>
</tr>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt + Shift</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
10
</td>
</tr>
</tbody>
</table>
</p>
<table className="border-collapse text-sm mx-auto my-4">
<tbody>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt + Shift + Cmd/Win</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
0.01
</td>
</tr>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt + Cmd/Win</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
0.1
</td>
</tr>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
1
</td>
</tr>
<tr>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70">
<kbd>Alt + Shift</kbd>
</td>
<td className="border border-solid w-1/2 py-1 px-2 border-chalkboard-40 dark:border-chalkboard-70 text-right">
10
</td>
</tr>
</tbody>
</table>
<p className="my-4">
Our code editor is built with{' '}
<a
@ -100,7 +100,7 @@ export default function InteractiveNumbers() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -2,7 +2,7 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
import { Themes, getSystemTheme } from 'lib/theme'
import { Themes } from 'lib/theme'
import { bracket } from 'lib/exampleKcl'
import { useStore } from 'useStore'
import {
@ -20,8 +20,9 @@ function OnboardingWithNewFile() {
const navigate = useNavigate()
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.INDEX)
const { deferredSetCode } = useStore((s) => ({
deferredSetCode: s.deferredSetCode,
const { setCode, code } = useStore((s) => ({
code: s.code,
setCode: s.setCode,
}))
const {
settings: {
@ -51,7 +52,7 @@ function OnboardingWithNewFile() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -65,7 +66,7 @@ function OnboardingWithNewFile() {
<ActionButton
Element="button"
onClick={() => {
deferredSetCode(bracket)
setCode(bracket)
next()
}}
icon={{ icon: faArrowRight }}
@ -89,7 +90,7 @@ function OnboardingWithNewFile() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -116,9 +117,9 @@ function OnboardingWithNewFile() {
}
export default function Introduction() {
const { deferredSetCode, code } = useStore((s) => ({
const { setCode, code } = useStore((s) => ({
code: s.code,
deferredSetCode: s.deferredSetCode,
setCode: s.setCode,
}))
const {
settings: {
@ -127,24 +128,19 @@ export default function Introduction() {
},
},
} = useGlobalStateContext()
const getLogoTheme = () =>
theme === Themes.Light ||
(theme === Themes.System && getSystemTheme() === Themes.Light)
? '-dark'
: ''
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.CAMERA)
useEffect(() => {
if (code === '') deferredSetCode(bracket)
}, [code, deferredSetCode])
if (code === '') setCode(bracket)
}, [code, setCode])
return !(code !== '' && code !== bracket) ? (
<div className="fixed grid place-content-center inset-0 bg-chalkboard-110/50 z-50">
<div className="max-w-3xl bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded">
<h1 className="text-2xl font-bold flex gap-4 flex-wrap items-center">
<img
src={`/kcma-logomark${getLogoTheme()}.svg`}
src={`/kcma-logomark${theme === Themes.Light ? '-dark' : ''}.svg`}
alt="KittyCAD Modeling App"
className="max-w-full h-20"
/>
@ -177,7 +173,7 @@ export default function Introduction() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -3,7 +3,7 @@ import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
import { Themes, getSystemTheme } from 'lib/theme'
import { Themes } from 'lib/theme'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
export default function ParametricModeling() {
@ -15,11 +15,6 @@ export default function ParametricModeling() {
context: { theme },
},
} = useGlobalStateContext()
const getImageTheme = () =>
theme === Themes.Light ||
(theme === Themes.System && getSystemTheme() === Themes.Light)
? '-dark'
: ''
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.INTERACTIVE_NUMBERS)
@ -45,7 +40,9 @@ export default function ParametricModeling() {
</p>
<figure className="my-4 w-3/4 mx-auto">
<img
src={`/onboarding-bracket${getImageTheme()}.png`}
src={`/onboarding-bracket${
theme === Themes.Light ? '-dark' : ''
}.png`}
alt="Bracket"
/>
<figcaption className="text-small italic text-center">
@ -54,13 +51,13 @@ export default function ParametricModeling() {
</figure>
<p className="my-4">
We are able to easily calculate the thickness of the material based
on the width of the bracket to meet a set safety factor on line 6.
on the width of the bracket to meet a set safety factor on line 13.
</p>
</section>
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -31,7 +31,7 @@ export default function ProjectMenu() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -5,16 +5,16 @@ import { useStore } from 'useStore'
import { useEffect } from 'react'
export default function Sketching() {
const { deferredSetCode, buttonDownInStream } = useStore((s) => ({
deferredSetCode: s.deferredSetCode,
const { setCode, buttonDownInStream } = useStore((s) => ({
setCode: s.setCode,
buttonDownInStream: s.buttonDownInStream,
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.FUTURE_WORK)
useEffect(() => {
deferredSetCode('')
}, [deferredSetCode])
setCode('')
}, [setCode])
return (
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
@ -38,7 +38,7 @@ export default function Sketching() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -41,7 +41,7 @@ export default function Streaming() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -66,7 +66,7 @@ export default function Units() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -22,13 +22,13 @@ export default function UserMenu() {
<h2 className="text-2xl">User Menu</h2>
<p className="my-4">
Click your avatar on the upper right to open the user menu. You can
change your settings, sign out, or request a feature.
change your settings, sign out, or report a bug.
</p>
</section>
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={dismiss}
onClick={() => dismiss('../../')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -1,5 +1,5 @@
import { useHotkeys } from 'react-hotkeys-hook'
import { Outlet, useRouteLoaderData, useNavigate } from 'react-router-dom'
import { Outlet, useNavigate } from 'react-router-dom'
import Introduction from './Introduction'
import Camera from './Camera'
import Sketching from './Sketching'
@ -15,7 +15,6 @@ import UserMenu from './UserMenu'
import ProjectMenu from './ProjectMenu'
import Export from './Export'
import FutureWork from './FutureWork'
import { IndexLoaderData, paths } from 'Router'
export const onboardingPaths = {
INDEX: '/',
@ -90,44 +89,37 @@ export function useNextClick(newStatus: string) {
settings: { send },
} = useGlobalStateContext()
const navigate = useNavigate()
const { project } = useRouteLoaderData(paths.FILE) as IndexLoaderData
return useCallback(() => {
send({
type: 'Set Onboarding Status',
data: { onboardingStatus: newStatus },
})
navigate(
paths.FILE +
'/' +
encodeURIComponent(project?.path || 'new') +
paths.ONBOARDING.INDEX.slice(0, -1) +
newStatus
)
}, [project, newStatus, send, navigate])
navigate((newStatus !== onboardingPaths.CAMERA ? '..' : '.') + newStatus)
}, [newStatus, send, navigate])
}
export function useDismiss() {
const routeData = useRouteLoaderData(paths.FILE) as IndexLoaderData
const {
settings: { send },
} = useGlobalStateContext()
const navigate = useNavigate()
return useCallback(() => {
send({
type: 'Set Onboarding Status',
data: { onboardingStatus: 'dismissed' },
})
navigate(
paths.FILE + '/' + encodeURIComponent(routeData?.project?.path || 'new')
)
}, [send, navigate, routeData])
return useCallback(
(path: string) => {
send({
type: 'Set Onboarding Status',
data: { onboardingStatus: 'dismissed' },
})
navigate(path)
},
[send, navigate]
)
}
const Onboarding = () => {
const dismiss = useDismiss()
useHotkeys('esc', dismiss)
useHotkeys('esc', () => dismiss('../'))
return (
<>

View File

@ -23,14 +23,12 @@ import {
cameraMouseDragGuards,
} from 'lib/cameraControls'
import { UnitSystem } from 'machines/settingsMachine'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export const Settings = () => {
const loaderData = useRouteLoaderData(paths.FILE) as IndexLoaderData
const navigate = useNavigate()
const location = useLocation()
const dotDotSlash = useDotDotSlash()
useHotkeys('esc', () => navigate(dotDotSlash()))
useHotkeys('esc', () => navigate('../'))
const {
settings: {
send,
@ -64,11 +62,11 @@ export const Settings = () => {
}
return (
<div className="fixed inset-0 z-40 overflow-auto body-bg">
<div className="body-bg fixed inset-0 z-40 overflow-auto">
<AppHeader showToolbar={false} project={loaderData?.project}>
<ActionButton
Element="link"
to={location.pathname.replace(paths.SETTINGS, '')}
to={'../'}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -80,9 +78,9 @@ export const Settings = () => {
Close
</ActionButton>
</AppHeader>
<div className="max-w-5xl mx-auto my-24">
<div className="my-24 max-w-5xl mx-auto">
<h1 className="text-4xl font-bold">User Settings</h1>
<p className="max-w-2xl mt-6">
<p className="mt-6 max-w-2xl">
Don't see the feature you want? Check to see if it's on{' '}
<a
href="https://github.com/KittyCAD/modeling-app/discussions"
@ -100,7 +98,7 @@ export const Settings = () => {
>
<select
id="camera-controls"
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
value={cameraControls}
onChange={(e) => {
send({
@ -115,7 +113,7 @@ export const Settings = () => {
</option>
))}
</select>
<ul className="mx-4 my-2 text-sm leading-relaxed">
<ul className="text-sm my-2 mx-4 leading-relaxed">
<li>
<strong>Pan:</strong>{' '}
{cameraMouseDragGuards[cameraControls].pan.description}
@ -136,7 +134,7 @@ export const Settings = () => {
title="Default Directory"
description="Where newly-created projects are saved on your local computer"
>
<div className="flex w-full gap-4 p-1 border rounded border-chalkboard-30">
<div className="w-full flex gap-4 p-1 rounded border border-chalkboard-30">
<input
className="flex-1 px-2 bg-transparent"
value={defaultDirectory}
@ -163,7 +161,7 @@ export const Settings = () => {
description="Name template for new projects. Use $n to include an incrementing index"
>
<input
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
defaultValue={defaultProjectName}
onBlur={(e) => {
const newValue = e.target.value.trim() || DEFAULT_PROJECT_NAME
@ -207,7 +205,7 @@ export const Settings = () => {
>
<select
id="base-unit"
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
value={baseUnit}
onChange={(e) => {
send({
@ -241,7 +239,7 @@ export const Settings = () => {
>
<select
id="settings-theme"
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
value={theme}
onChange={(e) => {
send({
@ -269,7 +267,7 @@ export const Settings = () => {
type: 'Set Onboarding Status',
data: { onboardingStatus: '' },
})
navigate(dotDotSlash(1) + paths.ONBOARDING.INDEX)
navigate('..' + paths.ONBOARDING.INDEX)
}}
icon={{ icon: faArrowRotateBack }}
>
@ -285,22 +283,15 @@ export const Settings = () => {
interface SettingsSectionProps extends React.PropsWithChildren {
title: string
description?: string
className?: string
}
export function SettingsSection({
title,
description,
className,
children,
}: SettingsSectionProps) {
return (
<section
className={
'my-16 last-of-type:mb-24 grid grid-cols-2 gap-12 items-start ' +
className
}
>
<section className="my-16 last-of-type:mb-24 grid grid-cols-2 gap-12 items-start">
<div className="w-80">
<h2 className="text-2xl">{title}</h2>
<p className="mt-2 text-sm">{description}</p>

View File

@ -322,7 +322,7 @@ export const useStore = create<StoreState>()(
end: 0,
body: [],
nonCodeMeta: {
nonCodeNodes: {},
noneCodeNodes: {},
start: null,
},
},
@ -554,7 +554,7 @@ async function executeCode({
end: 0,
body: [],
nonCodeMeta: {
nonCodeNodes: {},
noneCodeNodes: {},
start: null,
},
},

211
src/wasm-lib/Cargo.lock generated
View File

@ -41,9 +41,9 @@ dependencies = [
[[package]]
name = "aho-corasick"
version = "1.1.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0"
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
dependencies = [
"memchr",
]
@ -79,9 +79,9 @@ dependencies = [
[[package]]
name = "anstyle"
version = "1.0.3"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea"
[[package]]
name = "anstyle-parse"
@ -205,9 +205,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
version = "0.21.4"
version = "0.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
[[package]]
name = "bigdecimal"
@ -312,9 +312,9 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.14.0"
version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "bytemuck"
@ -330,9 +330,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.5.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
dependencies = [
"serde",
]
@ -363,9 +363,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.31"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877"
dependencies = [
"android-tzdata",
"iana-time-zone",
@ -387,9 +387,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.4"
version = "4.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136"
checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6"
dependencies = [
"clap_builder",
"clap_derive",
@ -397,9 +397,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.4"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56"
checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08"
dependencies = [
"anstream",
"anstyle",
@ -593,7 +593,7 @@ checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
[[package]]
name = "derive-docs"
version = "0.1.4"
version = "0.1.3"
dependencies = [
"convert_case",
"expectorate",
@ -606,6 +606,20 @@ dependencies = [
"syn 2.0.37",
]
[[package]]
name = "derive-docs"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fe5c5ea065cfabc5a7c5e8ed616e369fbf108c4be01e0e5609bc9846a732664"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"serde",
"serde_tokenstream",
"syn 2.0.37",
]
[[package]]
name = "diff"
version = "0.1.13"
@ -678,9 +692,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.3"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
dependencies = [
"errno-dragonfly",
"libc",
@ -710,9 +724,9 @@ dependencies = [
[[package]]
name = "exr"
version = "1.71.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8"
checksum = "d1e481eb11a482815d3e9d618db8c42a93207134662873809335a92327440c18"
dependencies = [
"bit_field",
"flume",
@ -776,10 +790,14 @@ dependencies = [
[[package]]
name = "flume"
version = "0.11.0"
version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
dependencies = [
"futures-core",
"futures-sink",
"nanorand",
"pin-project",
"spin 0.9.8",
]
@ -1209,6 +1227,17 @@ dependencies = [
"web-sys",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.2",
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "ipnet"
version = "2.8.0"
@ -1222,7 +1251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi 0.3.2",
"rustix",
"rustix 0.38.9",
"windows-sys 0.48.0",
]
@ -1281,14 +1310,14 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.1.30"
version = "0.1.29"
dependencies = [
"anyhow",
"async-trait",
"bson",
"clap",
"dashmap",
"derive-docs",
"derive-docs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"expectorate",
"futures",
"itertools 0.11.0",
@ -1316,10 +1345,12 @@ dependencies = [
[[package]]
name = "kittycad"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9cf962b1e81a0b4eb923a727e761b40672cbacc7f5f0b75e13579d346352bc7"
dependencies = [
"anyhow",
"async-trait",
"base64 0.21.4",
"base64 0.21.2",
"bytes",
"chrono",
"data-encoding",
@ -1367,9 +1398,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
version = "0.2.148"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "libloading"
@ -1389,9 +1420,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.4.7"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
[[package]]
name = "lock_api"
@ -1442,9 +1479,9 @@ checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef"
[[package]]
name = "memchr"
version = "2.6.3"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
@ -1498,6 +1535,15 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "nanorand"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
dependencies = [
"getrandom",
]
[[package]]
name = "newline-converter"
version = "0.3.0"
@ -1585,9 +1631,9 @@ checksum = "049950a25a8f69e9673ed52fc58749548cee71194f6c3a8a04b80863637ce722"
[[package]]
name = "object"
version = "0.32.1"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
dependencies = [
"memchr",
]
@ -1607,7 +1653,7 @@ checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2"
[[package]]
name = "openapitor"
version = "0.0.9"
source = "git+https://github.com/KittyCAD/kittycad.rs?branch=main#0d121f6881da91b4a30bee18bbfe50e4a2096073"
source = "git+https://github.com/KittyCAD/kittycad.rs?branch=main#3d74c1dfb41146a268a644e9fde2c19a8cd66895"
dependencies = [
"Inflector",
"anyhow",
@ -1751,7 +1797,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"regex-syntax 0.7.5",
"regex-syntax 0.7.4",
"structmeta",
"syn 2.0.37",
]
@ -1770,11 +1816,10 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "pest"
version = "2.7.3"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33"
checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
@ -2015,25 +2060,25 @@ dependencies = [
[[package]]
name = "regex"
version = "1.9.5"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax 0.7.5",
"regex-syntax 0.7.4",
]
[[package]]
name = "regex-automata"
version = "0.3.8"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.7.5",
"regex-syntax 0.7.4",
]
[[package]]
@ -2056,9 +2101,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.7.5"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "reqwest"
@ -2066,7 +2111,7 @@ version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
dependencies = [
"base64 0.21.4",
"base64 0.21.2",
"bytes",
"encoding_rs",
"futures-core",
@ -2221,22 +2266,36 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.13"
version = "0.37.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
dependencies = [
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys 0.3.8",
"windows-sys 0.48.0",
]
[[package]]
name = "rustix"
version = "0.38.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bfe0f2582b4931a45d1fa608f8a8722e8b3c7ac54dd6d5f3b3212791fedef49"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
"linux-raw-sys 0.4.5",
"windows-sys 0.48.0",
]
[[package]]
name = "rustls"
version = "0.21.7"
version = "0.21.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb"
dependencies = [
"log",
"ring",
@ -2262,14 +2321,14 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
dependencies = [
"base64 0.21.4",
"base64 0.21.2",
]
[[package]]
name = "rustls-webpki"
version = "0.101.5"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed"
checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d"
dependencies = [
"ring",
"untrusted",
@ -2642,9 +2701,9 @@ dependencies = [
[[package]]
name = "socket2"
version = "0.5.4"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
dependencies = [
"libc",
"windows-sys 0.48.0",
@ -2746,7 +2805,7 @@ dependencies = [
"cfg-if",
"fastrand",
"redox_syscall 0.3.5",
"rustix",
"rustix 0.38.9",
"windows-sys 0.48.0",
]
@ -2772,11 +2831,11 @@ dependencies = [
[[package]]
name = "terminal_size"
version = "0.3.0"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
dependencies = [
"rustix",
"rustix 0.37.23",
"windows-sys 0.48.0",
]
@ -2823,9 +2882,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.28"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48"
checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07"
dependencies = [
"deranged",
"itoa",
@ -2844,9 +2903,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "time-macros"
version = "0.2.14"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572"
checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9"
dependencies = [
"time-core",
]
@ -2880,7 +2939,7 @@ dependencies = [
"parking_lot 0.12.1",
"pin-project-lite",
"signal-hook-registry",
"socket2 0.5.4",
"socket2 0.5.3",
"tokio-macros",
"windows-sys 0.48.0",
]
@ -3163,9 +3222,9 @@ dependencies = [
[[package]]
name = "typenum"
version = "1.17.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "ucd-trie"
@ -3190,9 +3249,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
version = "1.0.12"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-normalization"
@ -3229,9 +3288,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "2.4.1"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
dependencies = [
"form_urlencoded",
"idna",
@ -3282,9 +3341,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.4.0"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
dependencies = [
"same-file",
"winapi-util",

View File

@ -11,8 +11,7 @@ crate-type = ["cdylib"]
bson = { version = "2.7.0", features = ["uuid-1", "chrono"] }
gloo-utils = "0.2.0"
kcl-lib = { path = "kcl" }
#kittycad = { version = "0.2.25", default-features = false, features = ["js"] }
kittycad = { git = "https://github.com/KittyCAD/kittycad.rs", branch = "achalmers/relative-path-segments" }
kittycad = { version = "0.2.25", default-features = false, features = ["js"] }
serde_json = "1.0.107"
uuid = { version = "1.4.1", features = ["v4", "js", "serde"] }
wasm-bindgen = "0.2.87"
@ -21,8 +20,7 @@ wasm-bindgen-futures = "0.4.37"
[dev-dependencies]
anyhow = "1"
image = "0.24.7"
#kittycad = "0.2.25"
kittycad = { git = "https://github.com/KittyCAD/kittycad.rs", branch = "achalmers/relative-path-segments" }
kittycad = "0.2.25"
pretty_assertions = "1.4.0"
reqwest = { version = "0.11.20", default-features = false }
tokio = { version = "1.32.0", features = ["rt-multi-thread", "macros", "time"] }

View File

@ -1,7 +1,7 @@
[package]
name = "derive-docs"
description = "A tool for generating documentation from Rust derive macros"
version = "0.1.4"
version = "0.1.3"
edition = "2021"
license = "MIT"

View File

@ -212,12 +212,6 @@ fn do_stdlib_inner(
quote! {
Vec<#ty_ident>
}
} else if ty_string.starts_with("Box<") {
let ty_string = ty_string.trim_start_matches("Box<").trim_end_matches('>');
let ty_ident = format_ident!("{}", ty_string);
quote! {
#ty_ident
}
} else {
let ty_ident = format_ident!("{}", ty_string);
quote! {
@ -256,15 +250,7 @@ fn do_stdlib_inner(
.replace("Result < ", "")
.replace(", KclError >", "");
let return_type = if !ret_ty_string.is_empty() {
let ret_ty_string = if ret_ty_string.starts_with("Box <") {
ret_ty_string
.trim_start_matches("Box <")
.trim_end_matches('>')
.trim()
.to_string()
} else {
ret_ty_string.trim().to_string()
};
let ret_ty_string = ret_ty_string.trim().to_string();
let ret_ty_ident = format_ident!("{}", ret_ty_string);
let ret_ty_string = clean_type(&ret_ty_string);
quote! {
@ -489,9 +475,6 @@ fn clean_type(t: &str) -> String {
if t.starts_with("Vec<") {
t = t.replace("Vec<", "[").replace('>', "]");
}
if t.starts_with("Box<") {
t = t.replace("Box<", "").replace('>', "");
}
if t == "f64" {
return "number".to_string();
@ -581,26 +564,4 @@ mod tests {
assert!(errors.is_empty());
expectorate::assert_contents("tests/show.gen", &openapitor::types::get_text_fmt(&item).unwrap());
}
#[test]
fn test_stdlib_box() {
let (item, errors) = do_stdlib(
quote! {
name = "show",
},
quote! {
fn inner_show(
/// The args to do shit to.
args: Box<f64>
) -> Box<f64> {
args
}
},
)
.unwrap();
let _expected = quote! {};
assert!(errors.is_empty());
expectorate::assert_contents("tests/box.gen", &openapitor::types::get_text_fmt(&item).unwrap());
}
}

View File

@ -1,70 +0,0 @@
#[allow(non_camel_case_types, missing_docs)]
#[doc = "Std lib function: show"]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
#[ts(export)]
pub(crate) struct Show {}
#[allow(non_upper_case_globals, missing_docs)]
#[doc = "Std lib function: show"]
pub(crate) const Show: Show = Show {};
impl crate::docs::StdLibFn for Show {
fn name(&self) -> String {
"show".to_string()
}
fn summary(&self) -> String {
"".to_string()
}
fn description(&self) -> String {
"".to_string()
}
fn tags(&self) -> Vec<String> {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "number".to_string(),
schema: f64::json_schema(&mut generator),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "number".to_string(),
schema: f64::json_schema(&mut generator),
required: true,
})
}
fn unpublished(&self) -> bool {
false
}
fn deprecated(&self) -> bool {
false
}
fn std_lib_fn(&self) -> crate::std::StdFn {
show
}
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
Box::new(self.clone())
}
}
fn inner_show(#[doc = r" The args to do shit to."] args: Box<f64>) -> Box<f64> {
args
}

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language"
version = "0.1.30"
version = "0.1.29"
edition = "2021"
license = "MIT"
@ -10,16 +10,16 @@ license = "MIT"
[dependencies]
anyhow = { version = "1.0.75", features = ["backtrace"] }
async-trait = "0.1.73"
clap = { version = "4.4.3", features = ["cargo", "derive", "env", "unicode"], optional = true }
clap = { version = "4.4.3", features = ["cargo", "derive", "env", "unicode"] }
dashmap = "5.5.3"
#derive-docs = { version = "0.1.4" }
derive-docs = { path = "../derive-docs" }
kittycad = { git = "https://github.com/KittyCAD/kittycad.rs", branch = "achalmers/relative-path-segments", default-features = false, features = ["js"] }
derive-docs = { version = "0.1.3" }
#derive-docs = { path = "../derive-docs" }
kittycad = { version = "0.2.25", default-features = false, features = ["js"] }
lazy_static = "1.4.0"
parse-display = "0.8.2"
regex = "1.7.1"
schemars = { version = "0.8", features = ["impl_json_schema", "url", "uuid1"] }
serde = { version = "1.0.188", features = ["derive"] }
serde = {version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
thiserror = "1.0.48"
ts-rs = { version = "7", package = "ts-rs-json-value", features = ["serde-json-impl", "schemars-impl", "uuid-impl"] }
@ -42,7 +42,6 @@ tower-lsp = { version = "0.20.0", features = ["proposed"] }
[features]
default = ["engine"]
cli = ["dep:clap"]
engine = []
[profile.release]

View File

@ -23,7 +23,7 @@ pub struct Program {
pub start: usize,
pub end: usize,
pub body: Vec<BodyItem>,
pub non_code_meta: NonCodeMeta,
pub non_code_meta: NoneCodeMeta,
}
impl Program {
@ -81,7 +81,7 @@ impl Program {
"\n".to_string()
};
let custom_white_space_or_comment = match self.non_code_meta.non_code_nodes.get(&index) {
let custom_white_space_or_comment = match self.non_code_meta.none_code_nodes.get(&index) {
Some(custom_white_space_or_comment) => custom_white_space_or_comment.format(&indentation),
None => String::new(),
};
@ -640,26 +640,26 @@ impl BinaryPart {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub struct NonCodeNode {
pub struct NoneCodeNode {
pub start: usize,
pub end: usize,
pub value: NonCodeValue,
pub value: NoneCodeValue,
}
impl NonCodeNode {
impl NoneCodeNode {
pub fn value(&self) -> String {
match &self.value {
NonCodeValue::InlineComment { value } => value.clone(),
NonCodeValue::BlockComment { value } => value.clone(),
NonCodeValue::NewLineBlockComment { value } => value.clone(),
NonCodeValue::NewLine => "\n\n".to_string(),
NoneCodeValue::InlineComment { value } => value.clone(),
NoneCodeValue::BlockComment { value } => value.clone(),
NoneCodeValue::NewLineBlockComment { value } => value.clone(),
NoneCodeValue::NewLine => "\n\n".to_string(),
}
}
pub fn format(&self, indentation: &str) -> String {
match &self.value {
NonCodeValue::InlineComment { value } => format!(" // {}\n", value),
NonCodeValue::BlockComment { value } => {
NoneCodeValue::InlineComment { value } => format!(" // {}\n", value),
NoneCodeValue::BlockComment { value } => {
let add_start_new_line = if self.start == 0 { "" } else { "\n" };
if value.contains('\n') {
format!("{}{}/* {} */\n", add_start_new_line, indentation, value)
@ -667,7 +667,7 @@ impl NonCodeNode {
format!("{}{}// {}\n", add_start_new_line, indentation, value)
}
}
NonCodeValue::NewLineBlockComment { value } => {
NoneCodeValue::NewLineBlockComment { value } => {
let add_start_new_line = if self.start == 0 { "" } else { "\n\n" };
if value.contains('\n') {
format!("{}{}/* {} */\n", add_start_new_line, indentation, value)
@ -675,7 +675,7 @@ impl NonCodeNode {
format!("{}{}// {}\n", add_start_new_line, indentation, value)
}
}
NonCodeValue::NewLine => "\n\n".to_string(),
NoneCodeValue::NewLine => "\n\n".to_string(),
}
}
}
@ -683,7 +683,7 @@ impl NonCodeNode {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum NonCodeValue {
pub enum NoneCodeValue {
/// An inline comment.
/// An example of this is the following: `1 + 1 // This is an inline comment`.
InlineComment {
@ -715,32 +715,32 @@ pub enum NonCodeValue {
#[derive(Debug, Default, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct NonCodeMeta {
pub non_code_nodes: HashMap<usize, NonCodeNode>,
pub start: Option<NonCodeNode>,
pub struct NoneCodeMeta {
pub none_code_nodes: HashMap<usize, NoneCodeNode>,
pub start: Option<NoneCodeNode>,
}
// implement Deserialize manually because we to force the keys of non_code_nodes to be usize
// and by default the ts type { [statementIndex: number]: NonCodeNode } serializes to a string i.e. "0", "1", etc.
impl<'de> Deserialize<'de> for NonCodeMeta {
fn deserialize<D>(deserializer: D) -> Result<NonCodeMeta, D::Error>
// implement Deserialize manually because we to force the keys of none_code_nodes to be usize
// and by default the ts type { [statementIndex: number]: NoneCodeNode } serializes to a string i.e. "0", "1", etc.
impl<'de> Deserialize<'de> for NoneCodeMeta {
fn deserialize<D>(deserializer: D) -> Result<NoneCodeMeta, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct NonCodeMetaHelper {
non_code_nodes: HashMap<String, NonCodeNode>,
start: Option<NonCodeNode>,
struct NoneCodeMetaHelper {
none_code_nodes: HashMap<String, NoneCodeNode>,
start: Option<NoneCodeNode>,
}
let helper = NonCodeMetaHelper::deserialize(deserializer)?;
let mut non_code_nodes = HashMap::new();
for (key, value) in helper.non_code_nodes {
non_code_nodes.insert(key.parse().map_err(serde::de::Error::custom)?, value);
let helper = NoneCodeMetaHelper::deserialize(deserializer)?;
let mut none_code_nodes = HashMap::new();
for (key, value) in helper.none_code_nodes {
none_code_nodes.insert(key.parse().map_err(serde::de::Error::custom)?, value);
}
Ok(NonCodeMeta {
non_code_nodes,
Ok(NoneCodeMeta {
none_code_nodes,
start: helper.start,
})
}
@ -871,11 +871,6 @@ impl CallExpression {
match &self.function {
Function::StdLib { func } => {
/* let source_range: SourceRange = self.into();
println!(
"Calling stdlib function: {}, source_range: {:?}, args: {:?}",
fn_name, source_range, fn_args
);*/
// Attempt to call the function.
let mut args = crate::std::Args::new(fn_args, self.into(), engine);
let result = func.std_lib_fn()(&mut args)?;
@ -1820,11 +1815,10 @@ impl MemberExpression {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
};
}
.get_json_value()?;
let array_json = array.get_json_value()?;
if let serde_json::Value::Array(array) = array_json {
if let serde_json::Value::Array(array) = array {
if let Some(value) = array.get(index) {
Ok(MemoryItem::UserVal(UserVal {
value: value.clone(),
@ -1872,11 +1866,10 @@ impl MemberExpression {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
};
}
.get_json_value()?;
let object_json = object.get_json_value()?;
if let serde_json::Value::Object(map) = object_json {
if let serde_json::Value::Object(map) = object {
if let Some(value) = map.get(&property_name) {
Ok(MemoryItem::UserVal(UserVal {
value: value.clone(),
@ -1971,9 +1964,7 @@ impl BinaryExpression {
let should_wrap_right = match &self.right {
BinaryPart::BinaryExpression(bin_exp) => {
self.precedence() > bin_exp.precedence()
|| self.operator == BinaryOperator::Sub
|| self.operator == BinaryOperator::Div
self.precedence() > bin_exp.precedence() || self.operator == BinaryOperator::Sub
}
_ => false,
};
@ -2238,7 +2229,7 @@ pub struct PipeExpression {
pub start: usize,
pub end: usize,
pub body: Vec<Value>,
pub non_code_meta: NonCodeMeta,
pub non_code_meta: NoneCodeMeta,
}
impl_value_meta!(PipeExpression);
@ -2283,7 +2274,7 @@ impl PipeExpression {
let indentation = options.get_indentation(indentation_level + 1);
let mut s = statement.recast(options, indentation_level + 1, true);
let non_code_meta = self.non_code_meta.clone();
if let Some(non_code_meta_value) = non_code_meta.non_code_nodes.get(&index) {
if let Some(non_code_meta_value) = non_code_meta.none_code_nodes.get(&index) {
s += non_code_meta_value.format(&indentation).trim_end_matches('\n')
}
@ -2680,7 +2671,7 @@ show(part001)"#;
#[test]
fn test_recast_with_std_and_non_stdlib() {
let some_program_string = r#"{"body":[{"type":"VariableDeclaration","start":0,"end":0,"declarations":[{"type":"VariableDeclarator","start":0,"end":0,"id":{"type":"Identifier","start":0,"end":0,"name":"part001"},"init":{"type":"PipeExpression","start":0,"end":0,"body":[{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"startSketchAt"},"function":{"type":"StdLib","func":{"name":"startSketchAt","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false}},"optional":false,"arguments":[{"type":"Literal","start":0,"end":0,"value":"default","raw":"default"}]},{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"ry"},"function":{"type":"InMemory"},"optional":false,"arguments":[{"type":"Literal","start":0,"end":0,"value":90,"raw":"90"},{"type":"PipeSubstitution","start":0,"end":0}]},{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"line"},"function":{"type":"StdLib","func":{"name":"line","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false}},"optional":false,"arguments":[{"type":"Literal","start":0,"end":0,"value":"default","raw":"default"},{"type":"PipeSubstitution","start":0,"end":0}]}],"nonCodeMeta":{"nonCodeNodes":{},"start":null}}}],"kind":"const"},{"type":"ExpressionStatement","start":0,"end":0,"expression":{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"show"},"function":{"type":"StdLib","func":{"name":"show","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false}},"optional":false,"arguments":[{"type":"Identifier","start":0,"end":0,"name":"part001"}]}}],"start":0,"end":0,"nonCodeMeta":{"nonCodeNodes":{},"start":null}}"#;
let some_program_string = r#"{"body":[{"type":"VariableDeclaration","start":0,"end":0,"declarations":[{"type":"VariableDeclarator","start":0,"end":0,"id":{"type":"Identifier","start":0,"end":0,"name":"part001"},"init":{"type":"PipeExpression","start":0,"end":0,"body":[{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"startSketchAt"},"function":{"type":"StdLib","func":{"name":"startSketchAt","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false}},"optional":false,"arguments":[{"type":"Literal","start":0,"end":0,"value":"default","raw":"default"}]},{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"ry"},"function":{"type":"InMemory"},"optional":false,"arguments":[{"type":"Literal","start":0,"end":0,"value":90,"raw":"90"},{"type":"PipeSubstitution","start":0,"end":0}]},{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"line"},"function":{"type":"StdLib","func":{"name":"line","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false}},"optional":false,"arguments":[{"type":"Literal","start":0,"end":0,"value":"default","raw":"default"},{"type":"PipeSubstitution","start":0,"end":0}]}],"nonCodeMeta":{"noneCodeNodes":{},"start":null}}}],"kind":"const"},{"type":"ExpressionStatement","start":0,"end":0,"expression":{"type":"CallExpression","start":0,"end":0,"callee":{"type":"Identifier","start":0,"end":0,"name":"show"},"function":{"type":"StdLib","func":{"name":"show","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false}},"optional":false,"arguments":[{"type":"Identifier","start":0,"end":0,"name":"part001"}]}}],"start":0,"end":0,"nonCodeMeta":{"noneCodeNodes":{},"start":null}}"#;
let some_program: crate::ast::types::Program = serde_json::from_str(some_program_string).unwrap();
let recasted = some_program.recast(&Default::default(), 0);
@ -2896,7 +2887,7 @@ const things = "things"
let some_program_string = r#"let b = {
"end": 141,
"start": 125,
"type": "NonCodeNode",
"type": "NoneCodeNode",
"value": "
// a comment
"
@ -3076,20 +3067,4 @@ show(firstExtrude)
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted.trim(), some_program_string);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_recast_math_nested_parens() {
let some_program_string = r#"const distance = 5
const p = 3
const FOS = 2
const sigmaAllow = 8
const width = 20
const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted.trim(), some_program_string);
}
}

View File

@ -104,7 +104,14 @@ impl EngineManager for EngineConnection {
source_range: crate::executor::SourceRange,
cmd: kittycad::types::ModelingCmd,
) -> Result<(), KclError> {
futures::executor::block_on(self.send_modeling_cmd_get_response(id, source_range, cmd))?;
futures::executor::block_on(self.tcp_send(WebSocketRequest::ModelingCmdReq { cmd, cmd_id: id })).map_err(
|e| {
KclError::Engine(KclErrorDetails {
message: format!("Failed to send modeling command: {}", e),
source_ranges: vec![source_range],
})
},
)?;
Ok(())
}

View File

@ -101,8 +101,8 @@ impl ProgramReturn {
#[serde(tag = "type")]
pub enum MemoryItem {
UserVal(UserVal),
SketchGroup(Box<SketchGroup>),
ExtrudeGroup(Box<ExtrudeGroup>),
SketchGroup(SketchGroup),
ExtrudeGroup(ExtrudeGroup),
#[ts(skip)]
ExtrudeTransform(ExtrudeTransform),
#[ts(skip)]
@ -159,12 +159,10 @@ impl MemoryItem {
if let MemoryItem::UserVal(user_val) = self {
Ok(user_val.value.clone())
} else {
serde_json::to_value(self).map_err(|err| {
KclError::Semantic(KclErrorDetails {
message: format!("Cannot convert memory item to json value: {:?}", err),
source_ranges: self.clone().into(),
})
})
Err(KclError::Semantic(KclErrorDetails {
message: format!("Not a user value: {:?}", self),
source_ranges: self.clone().into(),
}))
}
}
@ -601,10 +599,6 @@ pub fn execute(
let memory_item = memory.get(&identifier.name, identifier.into())?;
args.push(memory_item.clone());
}
Value::CallExpression(call_expr) => {
let result = call_expr.execute(memory, &mut pipe_info, engine)?;
args.push(result);
}
// We do nothing for the rest.
_ => (),
}
@ -1179,16 +1173,6 @@ show(thisBox)
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_math_execute_with_pi() {
let ast = r#"const myVar = pi() * 2"#;
let memory = parse_execute(ast).await.unwrap();
assert_eq!(
serde_json::json!(std::f64::consts::TAU),
memory.root.get("myVar").unwrap().get_json_value().unwrap()
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_math_define_decimal_without_leading_zero() {
let ast = r#"let thing = .4 + 7"#;
@ -1199,22 +1183,6 @@ show(thisBox)
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_zero_param_fn() {
let ast = r#"const sigmaAllow = 35000 // psi
const leg1 = 5 // inches
const leg2 = 8 // inches
fn thickness = () => { return 0.56 }
const bracket = startSketchAt([0,0])
|> line([0, leg1], %)
|> line([leg2, 0], %)
|> line([0, -thickness()], %)
|> line([-leg2 + thickness(), 0], %)
"#;
parse_execute(ast).await.unwrap();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_math_negative_variable_in_binary_expression() {
let ast = r#"const sigmaAllow = 35000 // psi

View File

@ -1,5 +1,3 @@
#![recursion_limit = "1024"]
pub mod ast;
pub mod docs;
pub mod engine;

View File

@ -422,8 +422,9 @@ impl ReversePolishNotation {
{
let closing_brace = self.parser.find_closing_brace(1, 0, "")?;
let mut new_stack = stack;
let call_expression = self.parser.make_call_expression(0)?;
new_stack.push(MathExpression::CallExpression(Box::new(call_expression.expression)));
new_stack.push(MathExpression::CallExpression(Box::new(
self.parser.make_call_expression(0)?.expression,
)));
return self.build_tree(&reverse_polish_notation_tokens[closing_brace + 1..], new_stack);
}
if reverse_polish_notation_tokens[1].token_type == TokenType::Period

View File

@ -3,8 +3,8 @@ use std::{collections::HashMap, str::FromStr};
use crate::{
ast::types::{
ArrayExpression, BinaryExpression, BinaryPart, BodyItem, CallExpression, ExpressionStatement,
FunctionExpression, Identifier, Literal, LiteralIdentifier, MemberExpression, MemberObject, NonCodeMeta,
NonCodeNode, NonCodeValue, ObjectExpression, ObjectKeyInfo, ObjectProperty, PipeExpression, PipeSubstitution,
FunctionExpression, Identifier, Literal, LiteralIdentifier, MemberExpression, MemberObject, NoneCodeMeta,
NoneCodeNode, NoneCodeValue, ObjectExpression, ObjectKeyInfo, ObjectProperty, PipeExpression, PipeSubstitution,
Program, ReturnStatement, UnaryExpression, UnaryOperator, Value, VariableDeclaration, VariableDeclarator,
VariableKind,
},
@ -26,7 +26,7 @@ struct TokenReturn {
struct TokenReturnWithNonCode {
token: Option<Token>,
index: usize,
non_code_node: Option<NonCodeNode>,
non_code_node: Option<NoneCodeNode>,
}
#[derive(Debug, PartialEq, Clone)]
@ -57,7 +57,7 @@ struct ArrayReturn {
struct PipeBodyReturn {
body: Vec<Value>,
last_index: usize,
non_code_meta: NonCodeMeta,
non_code_meta: NoneCodeMeta,
}
#[derive(Debug, PartialEq, Clone)]
@ -136,7 +136,7 @@ struct ReturnStatementResult {
struct BodyResult {
body: Vec<BodyItem>,
last_index: usize,
non_code_meta: NonCodeMeta,
non_code_meta: NoneCodeMeta,
}
#[derive(Debug, PartialEq, Clone)]
@ -183,8 +183,8 @@ impl Parser {
let body = self.make_body(
0,
vec![],
NonCodeMeta {
non_code_nodes: HashMap::new(),
NoneCodeMeta {
none_code_nodes: HashMap::new(),
start: None,
},
)?;
@ -269,7 +269,7 @@ impl Parser {
Ok(index + 1)
}
fn make_non_code_node(&self, index: usize) -> Result<(Option<NonCodeNode>, usize), KclError> {
fn make_none_code_node(&self, index: usize) -> Result<(Option<NoneCodeNode>, usize), KclError> {
let end_index = self.find_end_of_non_code_node(index)?;
let start_index = self.find_start_of_non_code_node(index)?;
let non_code_tokens = self.tokens[index..end_index].to_vec();
@ -286,10 +286,10 @@ impl Parser {
.contains("\n\n")
{
return Ok((
Some(NonCodeNode {
Some(NoneCodeNode {
start: self.tokens[start_index].start,
end: self.tokens[end_index - 1].end,
value: NonCodeValue::NewLine,
value: NoneCodeValue::NewLine,
}),
end_index - 1,
));
@ -330,17 +330,17 @@ impl Parser {
let is_new_line_comment =
start_end_string.starts_with('\n') || start_end_string.contains('\n') || start_index == 0 || index == 0;
let node = NonCodeNode {
let node = NoneCodeNode {
start: self.tokens[start_index].start,
end: self.tokens[end_index - 1].end,
value: if start_end_string.starts_with("\n\n") && is_new_line_comment {
// Preserve if they want a whitespace line before the comment.
// But let's just allow one.
NonCodeValue::NewLineBlockComment { value: full_string }
NoneCodeValue::NewLineBlockComment { value: full_string }
} else if is_new_line_comment {
NonCodeValue::BlockComment { value: full_string }
NoneCodeValue::BlockComment { value: full_string }
} else {
NonCodeValue::InlineComment { value: full_string }
NoneCodeValue::InlineComment { value: full_string }
},
};
Ok((Some(node), end_index - 1))
@ -366,7 +366,7 @@ impl Parser {
};
if is_not_code_token(token) {
let non_code_node = self.make_non_code_node(new_index)?;
let non_code_node = self.make_none_code_node(new_index)?;
let new_new_index = non_code_node.1 + 1;
let bonus_non_code_node = non_code_node.0;
@ -777,7 +777,6 @@ impl Parser {
});
}
}
if current_token.token_type == TokenType::Word
|| current_token.token_type == TokenType::Number
|| current_token.token_type == TokenType::String
@ -1028,13 +1027,13 @@ impl Parser {
&self,
index: usize,
previous_values: Vec<Value>,
previous_non_code_meta: Option<NonCodeMeta>,
previous_non_code_meta: Option<NoneCodeMeta>,
) -> Result<PipeBodyReturn, KclError> {
let non_code_meta = match previous_non_code_meta {
Some(meta) => meta,
None => NonCodeMeta {
None => NoneCodeMeta {
start: None,
non_code_nodes: HashMap::new(),
none_code_nodes: HashMap::new(),
},
};
let current_token = self.get_token(index)?;
@ -1061,10 +1060,10 @@ impl Parser {
non_code_meta,
});
}
let mut _non_code_meta: NonCodeMeta;
let mut _non_code_meta: NoneCodeMeta;
if let Some(node) = next_pipe.non_code_node {
_non_code_meta = non_code_meta;
_non_code_meta.non_code_nodes.insert(previous_values.len(), node);
_non_code_meta.none_code_nodes.insert(previous_values.len(), node);
} else {
_non_code_meta = non_code_meta;
}
@ -1250,15 +1249,7 @@ impl Parser {
})
})?;
let closing_brace_token = self.get_token(closing_brace_index)?;
// Account for if we have no args.
let args = if brace_token.index + 1 == closing_brace_index {
ArgumentsReturn {
arguments: vec![],
last_index: closing_brace_index,
}
} else {
self.make_arguments(brace_token.index, vec![])?
};
let args = self.make_arguments(brace_token.index, vec![])?;
let function = if let Some(stdlib_fn) = self.stdlib.get(&callee.name) {
crate::ast::types::Function::StdLib { func: stdlib_fn }
} else {
@ -1596,7 +1587,7 @@ impl Parser {
&self,
token_index: usize,
previous_body: Vec<BodyItem>,
previous_non_code_meta: NonCodeMeta,
previous_non_code_meta: NoneCodeMeta,
) -> Result<BodyResult, KclError> {
let mut non_code_meta = previous_non_code_meta;
if self.tokens.is_empty() {
@ -1629,7 +1620,7 @@ impl Parser {
if previous_body.is_empty() {
non_code_meta.start = next_token.non_code_node;
} else {
non_code_meta.non_code_nodes.insert(previous_body.len(), node.clone());
non_code_meta.none_code_nodes.insert(previous_body.len(), node.clone());
}
}
return self.make_body(next_token.index, previous_body, non_code_meta);
@ -1637,14 +1628,14 @@ impl Parser {
let next = self.next_meaningful_token(token_index, None)?;
if let Some(node) = &next.non_code_node {
non_code_meta.non_code_nodes.insert(previous_body.len(), node.clone());
non_code_meta.none_code_nodes.insert(previous_body.len(), node.clone());
}
if token.token_type == TokenType::Keyword && VariableKind::from_str(&token.value).is_ok() {
let declaration = self.make_variable_declaration(token_index)?;
let next_thing = self.next_meaningful_token(declaration.last_index, None)?;
if let Some(node) = &next_thing.non_code_node {
non_code_meta.non_code_nodes.insert(previous_body.len(), node.clone());
non_code_meta.none_code_nodes.insert(previous_body.len(), node.clone());
}
let mut _previous_body = previous_body;
_previous_body.push(BodyItem::VariableDeclaration(VariableDeclaration {
@ -1665,7 +1656,7 @@ impl Parser {
let statement = self.make_return_statement(token_index)?;
let next_thing = self.next_meaningful_token(statement.last_index, None)?;
if let Some(node) = &next_thing.non_code_node {
non_code_meta.non_code_nodes.insert(previous_body.len(), node.clone());
non_code_meta.none_code_nodes.insert(previous_body.len(), node.clone());
}
let mut _previous_body = previous_body;
_previous_body.push(BodyItem::ReturnStatement(ReturnStatement {
@ -1689,7 +1680,7 @@ impl Parser {
let expression = self.make_expression_statement(token_index)?;
let next_thing = self.next_meaningful_token(expression.last_index, None)?;
if let Some(node) = &next_thing.non_code_node {
non_code_meta.non_code_nodes.insert(previous_body.len(), node.clone());
non_code_meta.none_code_nodes.insert(previous_body.len(), node.clone());
}
let mut _previous_body = previous_body;
_previous_body.push(BodyItem::ExpressionStatement(ExpressionStatement {
@ -1712,7 +1703,7 @@ impl Parser {
&& next_thing_token.token_type == TokenType::Operator
{
if let Some(node) = &next_thing.non_code_node {
non_code_meta.non_code_nodes.insert(previous_body.len(), node.clone());
non_code_meta.none_code_nodes.insert(previous_body.len(), node.clone());
}
let expression = self.make_expression_statement(token_index)?;
let mut _previous_body = previous_body;
@ -1743,8 +1734,8 @@ impl Parser {
BodyResult {
body: vec![],
last_index: next_token_index,
non_code_meta: NonCodeMeta {
non_code_nodes: HashMap::new(),
non_code_meta: NoneCodeMeta {
none_code_nodes: HashMap::new(),
start: None,
},
}
@ -1752,8 +1743,8 @@ impl Parser {
self.make_body(
next_token_index,
vec![],
NonCodeMeta {
non_code_nodes: HashMap::new(),
NoneCodeMeta {
none_code_nodes: HashMap::new(),
start: None,
},
)?
@ -1879,16 +1870,16 @@ mod tests {
);
}
#[test]
fn test_make_non_code_node() {
fn test_make_none_code_node() {
let tokens = crate::tokeniser::lexer("log(5, \"hello\", aIdentifier)");
let parser = Parser::new(tokens);
let index = 4;
let expected_output = (None, 4);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
let index = 7;
let expected_output = (None, 7);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
let tokens = crate::tokeniser::lexer(
r#"
const yo = { a: { b: { c: '123' } } }
@ -1898,28 +1889,28 @@ const key = 'c'"#,
let parser = Parser::new(tokens);
let index = 0;
let expected_output = (None, 0);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
let index = 2;
let expected_output = (None, 2);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
let index = 2;
let expected_output = (None, 2);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
let index = 29;
let expected_output = (
Some(NonCodeNode {
Some(NoneCodeNode {
start: 38,
end: 60,
value: NonCodeValue::BlockComment {
value: NoneCodeValue::BlockComment {
value: "this is a comment".to_string(),
},
}),
31,
);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
let tokens = crate::tokeniser::lexer(
r#"const mySketch = startSketchAt([0,0])
|> lineTo({ to: [0, 1], tag: 'myPath' }, %)
@ -1932,16 +1923,16 @@ const key = 'c'"#,
let parser = Parser::new(tokens);
let index = 57;
let expected_output = (
Some(NonCodeNode {
Some(NoneCodeNode {
start: 106,
end: 166,
value: NonCodeValue::BlockComment {
value: NoneCodeValue::BlockComment {
value: "this is\n a comment\n spanning a few lines".to_string(),
},
}),
59,
);
assert_eq!(parser.make_non_code_node(index).unwrap(), expected_output);
assert_eq!(parser.make_none_code_node(index).unwrap(), expected_output);
}
#[test]
@ -2914,8 +2905,8 @@ show(mySk1)"#;
.make_body(
0,
vec![],
NonCodeMeta {
non_code_nodes: HashMap::new(),
NoneCodeMeta {
none_code_nodes: HashMap::new(),
start: None,
},
)
@ -2952,8 +2943,8 @@ show(mySk1)"#;
})),
})),
})],
non_code_meta: NonCodeMeta {
non_code_nodes: Default::default(),
non_code_meta: NoneCodeMeta {
none_code_nodes: Default::default(),
start: None,
},
};
@ -3287,8 +3278,8 @@ e
}],
kind: VariableKind::Const,
})],
non_code_meta: NonCodeMeta {
non_code_nodes: Default::default(),
non_code_meta: NoneCodeMeta {
none_code_nodes: Default::default(),
start: None,
},
};
@ -3365,19 +3356,6 @@ e
);
}
#[test]
fn zero_param_function() {
let program = r#"
fn firstPrimeNumber = () => {
return 2
}
firstPrimeNumber()
"#;
let tokens = crate::tokeniser::lexer(program);
let parser = crate::parser::Parser::new(tokens);
let _ast = parser.ast().unwrap();
}
#[test]
fn test_keyword_ok_in_fn_args_return() {
let some_program_string = r#"fn thing = (param) => {
@ -3430,47 +3408,4 @@ thing(false)
r#"syntax: KclErrorDetails { source_ranges: [SourceRange([0, 2])], message: "Expected a `let` variable kind, found: `fn`" }"#
);
}
#[test]
fn test_member_expression_sketch_group() {
let some_program_string = r#"fn cube = (pos, scale) => {
const sg = startSketchAt(pos)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const b1 = cube([0,0], 10)
const b2 = cube([3,3], 4)
const pt1 = b1[0]
const pt2 = b2[0]
show(b1)
show(b2)"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
parser.ast().unwrap();
}
#[test]
fn test_math_with_stdlib() {
let some_program_string = r#"const d2r = pi() / 2
let other_thing = 2 * cos(3)"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
parser.ast().unwrap();
}
#[test]
#[ignore] // ignore until more stack fixes
fn test_parse_pipes_on_pipes() {
let code = include_str!("../../tests/executor/inputs/pipes_on_pipes.kcl");
let tokens = crate::tokeniser::lexer(code);
let parser = crate::parser::Parser::new(tokens);
parser.ast().unwrap();
}
}

View File

@ -3,7 +3,6 @@
use std::collections::HashMap;
use anyhow::Result;
#[cfg(feature = "cli")]
use clap::Parser;
use dashmap::DashMap;
use tower_lsp::{jsonrpc::Result as RpcResult, lsp_types::*, Client, LanguageServer};
@ -11,15 +10,14 @@ use tower_lsp::{jsonrpc::Result as RpcResult, lsp_types::*, Client, LanguageServ
use crate::{ast::types::VariableKind, executor::SourceRange, parser::PIPE_OPERATOR};
/// A subcommand for running the server.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "cli", derive(Parser))]
#[derive(Parser, Clone, Debug)]
pub struct Server {
/// Port that the server should listen
#[cfg_attr(feature = "cli", clap(long, default_value = "8080"))]
#[clap(long, default_value = "8080")]
pub socket: i32,
/// Listen over stdin and stdout instead of a tcp socket.
#[cfg_attr(feature = "cli", clap(short, long, default_value = "false"))]
#[clap(short, long, default_value = "false")]
pub stdio: bool,
}

View File

@ -23,7 +23,7 @@ pub fn extrude(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "extrude"
}]
fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<ExtrudeGroup>, KclError> {
fn inner_extrude(length: f64, sketch_group: SketchGroup, args: &mut Args) -> Result<ExtrudeGroup, KclError> {
let id = uuid::Uuid::new_v4();
let cmd = kittycad::types::ModelingCmd::Extrude {
@ -33,7 +33,7 @@ fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -
};
args.send_modeling_cmd(id, cmd)?;
Ok(Box::new(ExtrudeGroup {
Ok(ExtrudeGroup {
id,
// TODO, this is just an empty array now, should be deleted. This
// comment was originally in the JS code.
@ -42,13 +42,13 @@ fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -
position: sketch_group.position,
rotation: sketch_group.rotation,
meta: sketch_group.meta,
}))
})
}
/// Returns the extrude wall transform.
pub fn get_extrude_wall_transform(args: &mut Args) -> Result<MemoryItem, KclError> {
let (surface_name, extrude_group) = args.get_path_name_extrude_group()?;
let result = inner_get_extrude_wall_transform(&surface_name, *extrude_group, args)?;
let result = inner_get_extrude_wall_transform(&surface_name, extrude_group, args)?;
Ok(MemoryItem::ExtrudeTransform(result))
}

View File

@ -179,7 +179,7 @@ impl<'a> Args<'a> {
Ok((numbers[0], numbers[1]))
}
fn get_segment_name_sketch_group(&self) -> Result<(String, Box<SketchGroup>), KclError> {
fn get_segment_name_sketch_group(&self) -> Result<(String, SketchGroup), KclError> {
// Iterate over our args, the first argument should be a UserVal with a string value.
// The second argument should be a SketchGroup.
let first_value = self
@ -221,7 +221,7 @@ impl<'a> Args<'a> {
Ok((segment_name, sketch_group))
}
fn get_sketch_group(&self) -> Result<Box<SketchGroup>, KclError> {
fn get_sketch_group(&self) -> Result<SketchGroup, KclError> {
let first_value = self.args.first().ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a SketchGroup as the first argument, found `{:?}`", self.args),
@ -263,7 +263,7 @@ impl<'a> Args<'a> {
Ok(data)
}
fn get_data_and_sketch_group<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Box<SketchGroup>), KclError> {
fn get_data_and_sketch_group<T: serde::de::DeserializeOwned>(&self) -> Result<(T, SketchGroup), KclError> {
let first_value = self
.args
.first()
@ -301,7 +301,7 @@ impl<'a> Args<'a> {
Ok((data, sketch_group))
}
fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, Box<SketchGroup>), KclError> {
fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, SketchGroup), KclError> {
// Iterate over our args, the first argument should be a UserVal with a string value.
// The second argument should be a number.
// The third argument should be a SketchGroup.
@ -357,7 +357,7 @@ impl<'a> Args<'a> {
Ok((segment_name, to_number, sketch_group))
}
fn get_number_sketch_group(&self) -> Result<(f64, Box<SketchGroup>), KclError> {
fn get_number_sketch_group(&self) -> Result<(f64, SketchGroup), KclError> {
// Iterate over our args, the first argument should be a number.
// The second argument should be a SketchGroup.
let first_value = self
@ -392,7 +392,7 @@ impl<'a> Args<'a> {
Ok((number, sketch_group))
}
fn get_path_name_extrude_group(&self) -> Result<(String, Box<ExtrudeGroup>), KclError> {
fn get_path_name_extrude_group(&self) -> Result<(String, ExtrudeGroup), KclError> {
// Iterate over our args, the first argument should be a UserVal with a string value.
// The second argument should be a ExtrudeGroup.
let first_value = self
@ -454,7 +454,7 @@ pub fn show(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "show",
}]
fn inner_show(_sketch: Box<SketchGroup>) {}
fn inner_show(_sketch: SketchGroup) {}
/// Returns the length of the given leg.
pub fn leg_length(args: &mut Args) -> Result<MemoryItem, KclError> {

View File

@ -22,7 +22,7 @@ pub fn segment_end_x(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "segEndX",
}]
fn inner_segment_end_x(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
fn inner_segment_end_x(segment_name: &str, sketch_group: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
let line = sketch_group.get_base_by_name_or_start(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
@ -48,7 +48,7 @@ pub fn segment_end_y(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "segEndY",
}]
fn inner_segment_end_y(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
fn inner_segment_end_y(segment_name: &str, sketch_group: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
let line = sketch_group.get_base_by_name_or_start(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
@ -74,7 +74,7 @@ pub fn last_segment_x(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "lastSegX",
}]
fn inner_last_segment_x(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
fn inner_last_segment_x(sketch_group: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
let last_line = sketch_group
.value
.last()
@ -104,7 +104,7 @@ pub fn last_segment_y(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "lastSegY",
}]
fn inner_last_segment_y(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
fn inner_last_segment_y(sketch_group: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
let last_line = sketch_group
.value
.last()
@ -133,7 +133,7 @@ pub fn segment_length(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "segLen",
}]
fn inner_segment_length(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
fn inner_segment_length(segment_name: &str, sketch_group: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
@ -155,14 +155,20 @@ pub fn segment_angle(args: &mut Args) -> Result<MemoryItem, KclError> {
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
let result = inner_segment_angle(&segment_name, sketch_group, args)?;
args.make_user_val_from_f64(result)
let j = serde_json::to_value(result).map_err(|e| {
KclError::Type(KclErrorDetails {
message: format!("Could not serialize KCL value {result:?}: {e}"),
source_ranges: vec![args.source_range],
})
})?;
args.make_user_val_from_json(j)
}
/// Returns the angle of the segment.
#[stdlib {
name = "segAng",
}]
fn inner_segment_angle(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
fn inner_segment_angle(segment_name: &str, sketch_group: SketchGroup, args: &mut Args) -> Result<Angle, KclError> {
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
@ -174,9 +180,7 @@ fn inner_segment_angle(segment_name: &str, sketch_group: Box<SketchGroup>, args:
})?;
let line = path.get_base();
let result = Angle::between(line.from.into(), line.to.into());
Ok(result.degrees())
Ok(Angle::between(line.from.into(), line.to.into()))
}
/// Returns the angle to match the given length for x.
@ -193,7 +197,7 @@ pub fn angle_to_match_length_x(args: &mut Args) -> Result<MemoryItem, KclError>
fn inner_angle_to_match_length_x(
segment_name: &str,
to: f64,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
@ -248,7 +252,7 @@ pub fn angle_to_match_length_y(args: &mut Args) -> Result<MemoryItem, KclError>
fn inner_angle_to_match_length_y(
segment_name: &str,
to: f64,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {

View File

@ -34,7 +34,7 @@ pub enum LineToData {
/// Draw a line to a point.
pub fn line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (LineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (LineToData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_line_to(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -44,11 +44,7 @@ pub fn line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "lineTo",
}]
fn inner_line_to(
data: LineToData,
sketch_group: Box<SketchGroup>,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
fn inner_line_to(data: LineToData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let to = match data {
LineToData::PointWithTag { to, .. } => to,
@ -67,7 +63,6 @@ fn inner_line_to(
y: to[1],
z: 0.0,
},
relative: false,
},
},
)?;
@ -112,7 +107,7 @@ pub enum AxisLineToData {
/// Draw a line to a point on the x-axis.
pub fn x_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AxisLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AxisLineToData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_x_line_to(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -122,11 +117,7 @@ pub fn x_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "xLineTo",
}]
fn inner_x_line_to(
data: AxisLineToData,
sketch_group: Box<SketchGroup>,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
fn inner_x_line_to(data: AxisLineToData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let line_to_data = match data {
@ -141,7 +132,7 @@ fn inner_x_line_to(
/// Draw a line to a point on the y-axis.
pub fn y_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AxisLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AxisLineToData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_y_line_to(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -151,11 +142,7 @@ pub fn y_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "yLineTo",
}]
fn inner_y_line_to(
data: AxisLineToData,
sketch_group: Box<SketchGroup>,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
fn inner_y_line_to(data: AxisLineToData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let line_to_data = match data {
@ -185,7 +172,7 @@ pub enum LineData {
/// Draw a line.
pub fn line(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (LineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (LineData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_line(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -195,14 +182,13 @@ pub fn line(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "line",
}]
fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
fn inner_line(data: LineData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let inner_args = match &data {
LineData::PointWithTag { to, .. } => *to,
LineData::Point(to) => *to,
};
let delta = inner_args;
let to = [from.x + inner_args[0], from.y + inner_args[1]];
let id = uuid::Uuid::new_v4();
@ -213,11 +199,10 @@ fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: &mut Args) -
path: sketch_group.id,
segment: kittycad::types::PathSegment::Line {
end: Point3D {
x: delta[0],
y: delta[1],
x: to[0],
y: to[1],
z: 0.0,
},
relative: true
},
},
)?;
@ -262,7 +247,7 @@ pub enum AxisLineData {
/// Draw a line on the x-axis.
pub fn x_line(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AxisLineData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_x_line(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -272,11 +257,7 @@ pub fn x_line(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "xLine",
}]
fn inner_x_line(
data: AxisLineData,
sketch_group: Box<SketchGroup>,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
fn inner_x_line(data: AxisLineData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let line_data = match data {
AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [length, 0.0], tag },
AxisLineData::Length(length) => LineData::Point([length, 0.0]),
@ -288,7 +269,7 @@ fn inner_x_line(
/// Draw a line on the y-axis.
pub fn y_line(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AxisLineData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_y_line(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -298,11 +279,7 @@ pub fn y_line(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "yLine",
}]
fn inner_y_line(
data: AxisLineData,
sketch_group: Box<SketchGroup>,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
fn inner_y_line(data: AxisLineData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let line_data = match data {
AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [0.0, length], tag },
AxisLineData::Length(length) => LineData::Point([0.0, length]),
@ -320,19 +297,19 @@ pub enum AngledLineData {
/// An angle and length with a tag.
AngleWithTag {
/// The angle of the line.
angle: f64,
angle: Angle,
/// The length of the line.
length: f64,
/// The tag.
tag: String,
},
/// An angle and length.
AngleAndLength([f64; 2]),
AngleAndLength(Angle, f64),
}
/// Draw an angled line.
pub fn angled_line(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AngledLineData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_angled_line(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -344,25 +321,17 @@ pub fn angled_line(args: &mut Args) -> Result<MemoryItem, KclError> {
}]
fn inner_angled_line(
data: AngledLineData,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let (angle, length) = match &data {
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
AngledLineData::AngleAndLength(angle_and_length) => (angle_and_length[0], angle_and_length[1]),
AngledLineData::AngleAndLength(angle, length) => (*angle, *length),
};
//double check me on this one - mike
let delta: [f64; 2] = [
length * f64::cos(angle.to_radians()),
length * f64::sin(angle.to_radians()),
];
let relative = true;
let to: [f64; 2] = [
from.x + delta[0],
from.y + delta[1],
from.x + length * f64::cos(angle.radians()),
from.y + length * f64::sin(angle.radians()),
];
let id = uuid::Uuid::new_v4();
@ -389,11 +358,10 @@ fn inner_angled_line(
path: sketch_group.id,
segment: kittycad::types::PathSegment::Line {
end: Point3D {
x: delta[0],
y: delta[1],
x: to[0],
y: to[1],
z: 0.0,
},
relative: relative,
},
},
)?;
@ -405,7 +373,7 @@ fn inner_angled_line(
/// Draw an angled line of a given x length.
pub fn angled_line_of_x_length(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AngledLineData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_angled_line_of_x_length(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -417,15 +385,15 @@ pub fn angled_line_of_x_length(args: &mut Args) -> Result<MemoryItem, KclError>
}]
fn inner_angled_line_of_x_length(
data: AngledLineData,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
) -> Result<SketchGroup, KclError> {
let (angle, length) = match &data {
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
AngledLineData::AngleAndLength(angle_and_length) => (angle_and_length[0], angle_and_length[1]),
AngledLineData::AngleAndLength(angle, length) => (*angle, *length),
};
let to = get_y_component(Angle::from_degrees(angle), length);
let to = get_y_component(angle, length);
let new_sketch_group = inner_line(
if let AngledLineData::AngleWithTag { tag, .. } = data {
@ -448,19 +416,19 @@ pub enum AngledLineToData {
/// An angle and point with a tag.
AngleWithTag {
/// The angle of the line.
angle: f64,
angle: Angle,
/// The point to draw to.
to: f64,
/// The tag.
tag: String,
},
/// An angle and point to draw to.
AngleAndPoint([f64; 2]),
AngleAndPoint(Angle, f64),
}
/// Draw an angled line to a given x coordinate.
pub fn angled_line_to_x(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AngledLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AngledLineToData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_angled_line_to_x(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -472,17 +440,17 @@ pub fn angled_line_to_x(args: &mut Args) -> Result<MemoryItem, KclError> {
}]
fn inner_angled_line_to_x(
data: AngledLineToData,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let (angle, x_to) = match &data {
AngledLineToData::AngleWithTag { angle, to, .. } => (*angle, *to),
AngledLineToData::AngleAndPoint(angle_and_to) => (angle_and_to[0], angle_and_to[1]),
AngledLineToData::AngleAndPoint(angle, to) => (*angle, *to),
};
let x_component = x_to - from.x;
let y_component = x_component * f64::tan(angle.to_radians());
let y_component = x_component * f64::tan(angle.radians());
let y_to = from.y + y_component;
let new_sketch_group = inner_line_to(
@ -499,7 +467,7 @@ fn inner_angled_line_to_x(
/// Draw an angled line of a given y length.
pub fn angled_line_of_y_length(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AngledLineData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_angled_line_of_y_length(data, sketch_group, args)?;
@ -512,15 +480,15 @@ pub fn angled_line_of_y_length(args: &mut Args) -> Result<MemoryItem, KclError>
}]
fn inner_angled_line_of_y_length(
data: AngledLineData,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
) -> Result<SketchGroup, KclError> {
let (angle, length) = match &data {
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
AngledLineData::AngleAndLength(angle_and_length) => (angle_and_length[0], angle_and_length[1]),
AngledLineData::AngleAndLength(angle, length) => (*angle, *length),
};
let to = get_x_component(Angle::from_degrees(angle), length);
let to = get_x_component(angle, length);
let new_sketch_group = inner_line(
if let AngledLineData::AngleWithTag { tag, .. } = data {
@ -537,7 +505,7 @@ fn inner_angled_line_of_y_length(
/// Draw an angled line to a given y coordinate.
pub fn angled_line_to_y(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AngledLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AngledLineToData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_angled_line_to_y(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -549,17 +517,17 @@ pub fn angled_line_to_y(args: &mut Args) -> Result<MemoryItem, KclError> {
}]
fn inner_angled_line_to_y(
data: AngledLineToData,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let (angle, y_to) = match &data {
AngledLineToData::AngleWithTag { angle, to, .. } => (*angle, *to),
AngledLineToData::AngleAndPoint(angle_and_to) => (angle_and_to[0], angle_and_to[1]),
AngledLineToData::AngleAndPoint(angle, to) => (*angle, *to),
};
let y_component = y_to - from.y;
let x_component = y_component / f64::tan(angle.to_radians());
let x_component = y_component / f64::tan(angle.radians());
let x_to = from.x + x_component;
let new_sketch_group = inner_line_to(
@ -581,7 +549,7 @@ fn inner_angled_line_to_y(
// TODO: make sure the docs on the args below are correct.
pub struct AngeledLineThatIntersectsData {
/// The angle of the line.
pub angle: f64,
pub angle: Angle,
/// The tag of the line to intersect with.
pub intersect_tag: String,
/// The offset from the intersecting line.
@ -592,7 +560,7 @@ pub struct AngeledLineThatIntersectsData {
/// Draw an angled line that intersects with a given line.
pub fn angled_line_that_intersects(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (AngeledLineThatIntersectsData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (AngeledLineThatIntersectsData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_angled_line_that_intersects(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
}
@ -603,9 +571,9 @@ pub fn angled_line_that_intersects(args: &mut Args) -> Result<MemoryItem, KclErr
}]
fn inner_angled_line_that_intersects(
data: AngeledLineThatIntersectsData,
sketch_group: Box<SketchGroup>,
sketch_group: SketchGroup,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
) -> Result<SketchGroup, KclError> {
let intersect_path = sketch_group
.get_path_by_name(&data.intersect_tag)
.ok_or_else(|| {
@ -649,7 +617,7 @@ pub fn start_sketch_at(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "startSketchAt",
}]
fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<SketchGroup, KclError> {
let to = match &data {
LineData::PointWithTag { to, .. } => *to,
LineData::Point(to) => *to,
@ -693,7 +661,7 @@ fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGr
start: current_path,
meta: vec![args.source_range.into()],
};
Ok(Box::new(sketch_group))
Ok(sketch_group)
}
/// Close the current sketch.
@ -709,7 +677,7 @@ pub fn close(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "close",
}]
fn inner_close(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
fn inner_close(sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let to: Point2d = sketch_group.start.from.into();
@ -788,7 +756,7 @@ pub enum ArcData {
/// Draw an arc.
pub fn arc(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (ArcData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (ArcData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_arc(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -798,7 +766,7 @@ pub fn arc(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "arc",
}]
fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
fn inner_arc(data: ArcData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from: Point2d = sketch_group.get_coords_from_paths()?;
let (center, angle_start, angle_end, radius, end) = match &data {
@ -844,14 +812,9 @@ fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: &mut Args) ->
angle_end: angle_end.degrees(),
center: center.into(),
radius,
relative: false,
},
},
)?;
// TODO: Dont do this (move path pen) - mike
// lets review what the needs are here and see if any existing arc endpoints can accomplish this
// Move the path pen to the end of the arc.
// Since that is where we want to draw the next path.
// TODO: the engine should automatically move the pen to the end of the arc.
@ -920,7 +883,7 @@ pub enum BezierData {
/// Draw a bezier curve.
pub fn bezier_curve(args: &mut Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group): (BezierData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
let (data, sketch_group): (BezierData, SketchGroup) = args.get_data_and_sketch_group()?;
let new_sketch_group = inner_bezier_curve(data, sketch_group, args)?;
Ok(MemoryItem::SketchGroup(new_sketch_group))
@ -930,11 +893,7 @@ pub fn bezier_curve(args: &mut Args) -> Result<MemoryItem, KclError> {
#[stdlib {
name = "bezierCurve",
}]
fn inner_bezier_curve(
data: BezierData,
sketch_group: Box<SketchGroup>,
args: &mut Args,
) -> Result<Box<SketchGroup>, KclError> {
fn inner_bezier_curve(data: BezierData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
let from = sketch_group.get_coords_from_paths()?;
let (to, control1, control2) = match &data {
@ -944,8 +903,6 @@ fn inner_bezier_curve(
BezierData::Points { to, control1, control2 } => (to, control1, control2),
};
let relative = true;
let delta = to;
let to = [from.x + to[0], from.y + to[1]];
let id = uuid::Uuid::new_v4();
@ -956,21 +913,20 @@ fn inner_bezier_curve(
path: sketch_group.id,
segment: kittycad::types::PathSegment::Bezier {
control1: Point3D {
x: control1[0],
y: control1[1],
x: from.x + control1[0],
y: from.y + control1[1],
z: 0.0,
},
control2: Point3D {
x: control2[0],
y: control2[1],
x: from.x + control2[0],
y: from.y + control2[1],
z: 0.0,
},
end: Point3D {
x: delta[0],
y: delta[1],
x: to[0],
y: to[1],
z: 0.0,
},
relative: relative
},
},
)?;

View File

@ -5,7 +5,10 @@ use crate::{
executor::{Point2d, SourceRange},
};
#[derive(Clone, Copy, Default, PartialOrd, PartialEq, Debug)]
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Default, PartialOrd, PartialEq, Debug, ts_rs::TS, Serialize, Deserialize, JsonSchema)]
pub struct Angle {
degrees: f64,
}
@ -125,10 +128,10 @@ pub fn distance_between_points(point_a: Point2d, point_b: Point2d) -> f64 {
((y2 - y1).powi(2) + (x2 - x1).powi(2)).sqrt()
}
pub fn calculate_intersection_of_two_lines(line1: &[Point2d; 2], line2_angle: f64, line2_point: Point2d) -> Point2d {
pub fn calculate_intersection_of_two_lines(line1: &[Point2d; 2], line2_angle: Angle, line2_point: Point2d) -> Point2d {
let line2_point_b = Point2d {
x: line2_point.x + f64::cos(line2_angle.to_radians()) * 10.0,
y: line2_point.y + f64::sin(line2_angle.to_radians()) * 10.0,
x: line2_point.x + f64::cos(line2_angle.radians()) * 10.0,
y: line2_point.y + f64::sin(line2_angle.radians()) * 10.0,
};
intersect(line1[0], line1[1], line2_point, line2_point_b)
}
@ -159,7 +162,7 @@ pub fn intersect(p1: Point2d, p2: Point2d, p3: Point2d, p4: Point2d) -> Point2d
pub fn intersection_with_parallel_line(
line1: &[Point2d; 2],
line1_offset: f64,
line2_angle: f64,
line2_angle: Angle,
line2_point: Point2d,
) -> Point2d {
calculate_intersection_of_two_lines(&offset_line(line1_offset, line1[0], line1[1]), line2_angle, line2_point)

View File

@ -1,470 +0,0 @@
const svg = startSketchAt([0, 0])
|> lineTo([22.687663, -2.7664351], %) // MoveRelative
|> lineTo([15.687664000000002, -5.7664351], %) // MoveRelative
|> bezierCurve({ control1: [9.6876636, -13.766435], control2: [12.350729000000001, -9.156355099999999], to: [12.350729000000001, -9.156355099999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [3.6876636000000005, -32.766435], control2: [6.962245000000001, -20.186315], to: [4.8344949, -25.885455]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [5.0392261000000005, -58.571125], control2: [2.9675173000000004, -41.612785], to: [3.0190312000000006, -49.894795]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [10.687664000000002, -73.766435], control2: [6.693877800000001, -63.826655], to: [8.2887432, -68.804835]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [20.375163, -80.578935], control2: [16.045534000000004, -78.630635], to: [16.045534000000004, -78.630635]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [30.062663, -82.266435], control2: [24.812782, -81.936245], to: [24.812782, -81.936245]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [41.125163, -79.516435], control2: [35.794902, -82.039475], to: [35.794902, -82.039475]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [49.687663, -72.766435], control2: [45.867323, -76.907555], to: [45.867323, -76.907555]}, %) // CubicBezierRelative
|> lineTo([50.687663, -69.766435], %) // LineRelative
|> lineTo([50.687663, -62.766435], %) // VerticalLineHorizonal
|> lineTo([48.687663, -57.891435], %) // LineRelative
|> bezierCurve({ control1: [46.351725, -31.692225], control2: [46.191183, -48.997725], to: [46.295503000000004, -40.884555000000006]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [47.7736, -20.934404999999998], control2: [46.687663, -25.766435], to: [46.687663, -25.766435]}, %) // CubicBezierRelative
|> lineTo([48.687663, -16.766434999999998], %) // LineRelative
|> lineTo([47.687663, -9.766435099999999], %) // LineRelative
|> bezierCurve({ control1: [40.687663, -3.766435099999999], control2: [44.488820000000004, -6.310115099999999], to: [44.488820000000004, -6.310115099999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [22.687663, -2.766435099999999], control2: [34.632213, -2.2525750999999987], to: [28.903189, -2.550245099999999]}, %) // CubicBezierRelative
// StopRelative
|> lineTo([116.68767, -9.766435099999999], %) // MoveRelative
|> bezierCurve({ control1: [108.68767, -15.766434999999998], control2: [112.22719, -12.236704999999999], to: [112.22719, -12.236704999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [102.37517, -28.953934999999998], control2: [105.79825, -20.100575], to: [103.93048, -23.991764999999997]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [101.68767, -47.766435], control2: [101.45837999999999, -35.371444999999994], to: [101.28287, -41.289805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [110.31267, -61.203935], control2: [103.94304, -53.097335], to: [106.65406999999999, -56.725305]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [116.68767, -66.766435], control2: [113.42043, -64.74899500000001], to: [113.42043, -64.74899500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [134.68767, -64.766435], control2: [123.4012, -67.124495], to: [128.03363, -66.429955]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [143.68767, -60.766435], control2: [139.37985, -63.042205], to: [139.37985, -63.042205]}, %) // CubicBezierRelative
|> lineTo([148.68767, -55.766435], %) // LineRelative
|> lineTo([149.68767, -54.766435], %) // LineRelative
|> bezierCurve({ control1: [149.75017, -46.078935], control2: [149.71427, -51.870655], to: [149.73387, -48.974805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [150.68767, -36.766435], control2: [149.97673, -41.121905], to: [149.97673, -41.121905]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [158.68767, -30.766435], control2: [154.62517, -32.891435], to: [154.62517, -32.891435]}, %) // CubicBezierRelative
|> lineTo([160.68767, -26.766435], %) // LineRelative
|> lineTo([160.68767, -20.766435], %) // VerticalLineHorizonal
|> bezierCurve({ control1: [149.68767, -9.8289351], control2: [157.40521999999999, -16.321455], to: [154.13992, -13.098555000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [145.68767, -7.766435100000001], control2: [148.36767, -9.148315100000001], to: [147.04767, -8.4676851]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [116.68767, -9.7664351], control2: [135.27527, -6.278955100000001], to: [126.6914, -6.2357151]}, %) // CubicBezierRelative
// StopRelative
|> lineTo([60.687663, -9.7664351], %) // MoveRelative
|> lineTo([54.687663, -13.766435000000001], %) // MoveRelative
|> bezierCurve({ control1: [48.937663, -25.516435], control2: [50.481933, -19.450155000000002], to: [50.481933, -19.450155000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [47.687663, -41.766435], control2: [47.773086, -31.339325000000002], to: [47.261382, -35.869545]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [50.687663, -56.766435], control2: [48.8286, -49.471785000000004], to: [48.8286, -49.471785000000004]}, %) // CubicBezierRelative
|> lineTo([54.687663, -62.766435], %) // LineRelative
|> lineTo([60.687663, -66.766435], %) // LineRelative
|> bezierCurve({ control1: [69.562663, -67.203935], control2: [64.985029, -67.361225], to: [64.985029, -67.361225]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [74.17985, -67.199935], control2: [71.84817100000001, -67.201935], to: [71.84817100000001, -67.201935]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [86.687663, -63.766335], control2: [78.823333, -66.75328499999999], to: [82.418032, -65.599655]}, %) // CubicBezierRelative
|> lineTo([86.687663, -61.766335], %) // VerticalLineHorizonal
|> lineTo([90.687663, -60.766335], %) // LineRelative
|> lineTo([95.687663, -56.766335], %) // LineRelative
|> lineTo([98.687663, -49.766335], %) // LineRelative
|> bezierCurve({ control1: [97.562663, -37.578835], control2: [98.934927, -43.021825], to: [98.934927, -43.021825]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [95.687663, -32.766335], control2: [96.943913, -35.990714999999994], to: [96.325163, -34.402584999999995]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [86.687663, -27.766334999999998], control2: [90.389309, -28.854045], to: [90.389309, -28.854045]}, %) // CubicBezierRelative
|> lineTo([84.687663, -23.766334999999998], %) // LineRelative
|> lineTo([82.687663, -22.766334999999998], %) // LineRelative
|> lineTo([79.687663, -17.766334999999998], %) // LineRelative
|> lineTo([77.687663, -17.766334999999998], %) // HorizontalLineRelative
|> lineTo([75.687663, -13.766334999999998], %) // LineRelative
|> bezierCurve({ control1: [67.687663, -9.766335099999997], control2: [72.005138, -11.383034999999998], to: [72.005138, -11.383034999999998]}, %) // CubicBezierRelative
|> lineTo([60.687663, -9.766335099999997], %) // HorizontalLineRelative
// StopRelative
|> lineTo([295.68767, -33.766435], %) // MoveAbsolute
|> bezierCurve({ control1: [286.31267, -36.578935], control2: [292.56461, -34.710375], to: [289.43947000000003, -35.647445000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [242.00408000000002, -50.172685], control2: [271.51088000000004, -41.004795], to: [256.74729, -45.555595000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [234.31267000000003, -52.578935], control2: [239.46591, -50.966755], to: [236.92775, -51.760815]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [227.28923000000003, -54.785975], control2: [231.99494, -53.307255], to: [229.67720000000003, -54.035585000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [208.68767000000003, -59.766435], control2: [221.12295000000003, -56.635855], to: [214.94597000000005, -58.261215]}, %) // CubicBezierRelative
|> lineTo([208.68767000000003, -57.766435], %) // VerticalLineHorizonal
|> lineTo([212.68767000000003, -55.766435], %) // LineRelative
|> bezierCurve({ control1: [217.68767000000003, -48.766435], control2: [215.57281000000003, -52.830805], to: [215.57281000000003, -52.830805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [218.68767000000003, -37.766435], control2: [218.84802000000002, -43.253935], to: [218.84802000000002, -43.253935]}, %) // CubicBezierRelative
|> lineTo([215.68767000000003, -31.766435], %) // LineRelative
|> bezierCurve({ control1: [208.68767000000003, -26.766435], control2: [212.58234000000002, -28.940575000000003], to: [212.58234000000002, -28.940575000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [192.68767000000003, -22.766435], control2: [203.18777000000003, -24.627585], to: [198.58520000000001, -23.608945000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [174.68767000000003, -24.766435], control2: [186.30665000000002, -22.492965], to: [180.86041000000003, -23.137525]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [170.12517000000003, -25.953935], control2: [173.18205000000003, -25.158315], to: [171.67642000000004, -25.550185000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [161.43767000000003, -31.016435], control2: [165.49678000000003, -27.618325000000002], to: [165.49678000000003, -27.618325000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [152.68767000000003, -41.766435], control2: [157.93412000000004, -34.519995], to: [155.07957000000002, -37.431115]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [152.68767000000003, -50.766435], control2: [151.93767000000003, -46.266435], to: [151.93767000000003, -46.266435]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [160.43767000000003, -61.578935], control2: [156.18761000000003, -57.582325], to: [156.18761000000003, -57.582325]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [164.68767000000003, -64.766435], control2: [162.54142000000002, -63.156755000000004], to: [162.54142000000002, -63.156755000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [180.68767000000003, -67.766435], control2: [172.62751000000003, -66.921865], to: [172.62751000000003, -66.921865]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [158.81267000000003, -75.266435], control2: [173.47790000000003, -70.856345], to: [166.33463000000003, -73.047575]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [138.52752000000004, -81.543785], control2: [148.62236000000001, -78.25548500000001], to: [148.62236000000001, -78.25548500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [130.12517000000003, -82.828935], control2: [134.68767000000003, -82.766435], to: [134.68767000000003, -82.766435]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [125.68767000000003, -81.766435], control2: [128.66080000000002, -82.478315], to: [127.19642000000003, -82.127685]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [117.68767000000003, -75.766435], control2: [122.99559000000002, -79.800785], to: [120.32975000000002, -77.798805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [107.68767000000003, -72.766435], control2: [113.16586000000002, -73.682455], to: [113.16586000000002, -73.682455]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [84.93766300000003, -73.953935], control2: [99.87842800000003, -72.226315], to: [92.61523300000002, -72.36835500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [80.68766300000003, -75.766435], control2: [83.53516300000003, -74.552065], to: [82.13266300000002, -75.15018500000001]}, %) // CubicBezierRelative
|> lineTo([75.68766300000003, -80.766435], %) // LineRelative
|> lineTo([76.68766300000003, -84.766435], %) // LineRelative
|> lineTo([81.68766300000003, -87.766435], %) // LineRelative
|> bezierCurve({ control1: [93.93766300000003, -87.891435], control2: [85.76704300000003, -87.950845], to: [89.85495700000003, -87.974265]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [105.68767000000003, -87.766435], control2: [97.85393000000003, -87.821635], to: [101.77078000000003, -87.772355]}, %) // CubicBezierRelative
|> lineTo([106.68767000000003, -88.766435], %) // LineRelative
|> lineTo([99.68766300000003, -90.766435], %) // LineRelative
|> lineTo([95.75016300000003, -93.266435], %) // LineRelative
|> bezierCurve({ control1: [83.68766300000003, -97.766435], control2: [91.68766300000003, -95.766435], to: [91.68766300000003, -95.766435]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [68.68766300000003, -102.76643], control2: [78.56377900000003, -99.248045], to: [73.64162800000003, -100.78485]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [52.68766300000003, -101.76643], control2: [63.09091200000003, -102.95723], to: [58.18407400000003, -102.86573]}, %) // CubicBezierRelative
|> lineTo([48.68766300000003, -106.76643], %) // LineRelative
|> lineTo([48.68766300000003, -114.76643], %) // VerticalLineHorizonal
|> lineTo([51.68766300000003, -121.76643], %) // LineRelative
|> lineTo([56.68766300000003, -123.76643], %) // LineRelative
|> lineTo([61.68766300000003, -123.76643], %) // HorizontalLineRelative
|> lineTo([64.68766300000003, -118.76643], %) // LineRelative
|> lineTo([69.68766300000003, -115.76643], %) // LineRelative
|> lineTo([69.68766300000003, -113.76643], %) // VerticalLineHorizonal
|> lineTo([75.68766300000003, -113.76643], %) // HorizontalLineRelative
|> lineTo([79.68766300000003, -110.76643], %) // LineRelative
|> lineTo([79.68766300000003, -108.76643], %) // VerticalLineHorizonal
|> lineTo([85.68766300000003, -109.76643], %) // LineRelative
|> lineTo([88.68766300000003, -106.76643], %) // LineRelative
|> lineTo([88.68766300000003, -102.76643], %) // VerticalLineHorizonal
|> bezierCurve({ control1: [99.68766300000003, -101.76643], control2: [93.93766300000003, -102.01643], to: [93.93766300000003, -102.01643]}, %) // CubicBezierRelative
|> lineTo([103.68767000000003, -105.76643], %) // LineRelative
|> lineTo([106.68767000000003, -106.76643], %) // LineRelative
|> bezierCurve({ control1: [107.68767000000003, -102.76643], control2: [107.18267000000003, -104.78643], to: [107.18267000000003, -104.78643]}, %) // CubicBezierRelative
|> lineTo([116.68767000000003, -102.76643], %) // HorizontalLineRelative
|> lineTo([113.68767000000003, -108.76643], %) // LineRelative
|> bezierCurve({ control1: [101.68767000000003, -114.76643], control2: [109.73020000000002, -110.84932], to: [105.72846000000003, -112.85018]}, %) // CubicBezierRelative
|> lineTo([97.68766300000003, -118.76643], %) // LineRelative
|> lineTo([97.68766300000003, -125.76643], %) // VerticalLineHorizonal
|> lineTo([101.68767000000003, -128.76643], %) // LineRelative
|> bezierCurve({ control1: [115.75017000000003, -126.57893000000001], control2: [106.58566000000002, -128.61801000000003], to: [110.98125000000003, -127.69757000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [124.93767000000003, -122.01643000000001], control2: [120.74370000000002, -124.95192000000002], to: [120.74370000000002, -124.95192000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [134.68767000000003, -111.76643000000001], control2: [128.66063000000003, -118.78987000000001], to: [131.76465000000002, -115.73339000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [136.68767000000003, -96.76643500000002], control2: [137.05397000000002, -104.69775000000001], to: [137.05397000000002, -104.69775000000001]}, %) // CubicBezierRelative
|> lineTo([135.68767000000003, -95.76643500000002], %) // LineRelative
|> lineTo([144.68767000000003, -91.76643500000002], %) // LineRelative
|> lineTo([144.68767000000003, -89.76643500000002], %) // VerticalLineHorizonal
|> bezierCurve({ control1: [149.18767000000003, -88.95393500000002], control2: [146.91517000000002, -89.36425500000001], to: [146.91517000000002, -89.36425500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [158.81267000000003, -86.20393500000002], control2: [154.52930000000003, -87.94347500000002], to: [154.52930000000003, -87.94347500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [170.68767000000003, -83.76643500000002], control2: [162.68767000000003, -84.76643500000002], to: [162.68767000000003, -84.76643500000002]}, %) // CubicBezierRelative
|> lineTo([169.68767000000003, -87.76643500000002], %) // LineRelative
|> bezierCurve({ control1: [173.81267000000003, -124.20393000000001], control2: [169.31325000000004, -100.37193000000002], to: [170.34211000000002, -112.05696000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [175.68767000000003, -129.76643], control2: [174.43142000000003, -126.03956000000001], to: [175.05017000000004, -127.87518000000001]}, %) // CubicBezierRelative
|> lineTo([177.68767000000003, -129.76643], %) // HorizontalLineRelative
|> lineTo([179.68767000000003, -133.76643], %) // LineRelative
|> lineTo([185.68767000000003, -138.76643], %) // LineRelative
|> bezierCurve({ control1: [202.68767000000003, -139.76643], control2: [191.47452, -140.21315], to: [196.74116000000004, -140.04174]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [210.68767000000003, -135.76643], control2: [207.25921000000002, -138.23436], to: [207.25921000000002, -138.23436]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [215.35564000000002, -128.27815], control2: [213.71484000000004, -132.0027], to: [213.71484000000004, -132.0027]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [216.91033000000002, -104.88753000000001], control2: [217.63118000000003, -120.57069000000001], to: [217.01741, -112.86275]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [214.68767000000003, -85.76643500000002], control2: [216.67209000000003, -98.33796500000001], to: [216.17402, -92.15775500000001]}, %) // CubicBezierRelative
|> lineTo([210.68767000000003, -78.76643500000002], %) // LineRelative
|> lineTo([207.68767000000003, -78.76643500000002], %) // HorizontalLineRelative
|> lineTo([207.68767000000003, -75.76643500000002], %) // VerticalLineHorizonal
|> lineTo([203.68767000000003, -74.76643500000002], %) // LineRelative
|> lineTo([204.68767000000003, -70.76643500000002], %) // LineRelative
|> lineTo([209.50017000000003, -70.01643500000002], %) // LineRelative
|> bezierCurve({ control1: [226.68767000000003, -64.76643500000002], control2: [215.57464000000002, -68.78927500000002], to: [220.89892000000003, -66.95330500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [247.31267000000003, -58.578935000000016], control2: [233.53624000000002, -62.60005500000001], to: [240.40800000000002, -60.55978500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [277.21111, -48.92659500000001], control2: [257.37096, -55.63882500000002], to: [267.2794, -52.26503500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [299.68767, -41.766435000000016], control2: [284.67443000000003, -46.437325000000016], to: [292.16675000000004, -44.07484500000001]}, %) // CubicBezierRelative
|> lineTo([299.68767, -39.766435000000016], %) // VerticalLineHorizonal
|> bezierCurve({ control1: [306.50017, -39.328935000000016], control2: [301.93580000000003, -39.62206500000001], to: [304.18392, -39.477685000000015]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [316.68767, -37.766435000000016], control2: [313.07319, -39.10529500000001], to: [313.07319, -39.10529500000001]}, %) // CubicBezierRelative
|> lineTo([316.68767, -35.766435000000016], %) // VerticalLineHorizonal
|> lineTo([320.56267, -35.016435000000016], %) // LineRelative
|> bezierCurve({ control1: [335.68767, -29.766435000000016], control2: [325.89187000000004, -33.71663500000002], to: [330.60815, -31.833685000000017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [343.56267, -27.266435000000016], control2: [339.5858, -28.528935000000015], to: [339.5858, -28.528935000000015]}, %) // CubicBezierRelative
|> lineTo([350.68767, -24.766435000000016], %) // LineRelative
|> lineTo([354.68767, -20.766435000000016], %) // LineRelative
|> bezierCurve({ control1: [295.68767, -33.766435000000016], control2: [334.809, -20.766435000000016], to: [314.44364, -27.758665000000015]}, %) // CubicBezierRelative
// StopRelative
|> lineTo([299.68767, -66.76643500000002], %) // MoveRelative
|> bezierCurve({ control1: [285.00017, -76.64143500000002], control2: [293.75788, -69.23718500000001], to: [289.90768, -72.43500500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [276.37517, -85.70393500000002], control2: [279.86247000000003, -81.42042500000002], to: [279.86247000000003, -81.42042500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [273.68767, -88.76643500000002], control2: [275.48830000000004, -86.71456500000002], to: [274.60142, -87.72518500000001]}, %) // CubicBezierRelative
|> lineTo([267.68767, -91.76643500000002], %) // LineRelative
|> lineTo([264.68767, -96.76643500000002], %) // LineRelative
|> bezierCurve({ control1: [266.68767, -111.76643000000001], control2: [264.32138000000003, -104.69775000000001], to: [264.32138000000003, -104.69775000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [278.68767, -123.76643000000001], control2: [270.61411000000004, -116.17816000000002], to: [274.2035, -120.01380000000002]}, %) // CubicBezierRelative
|> lineTo([282.93767, -126.01643000000001], %) // LineRelative
|> bezierCurve({ control1: [303.68767, -126.76643000000001], control2: [289.896, -127.11512000000002], to: [296.66137000000003, -126.99871000000002]}, %) // CubicBezierRelative
|> lineTo([305.68767, -125.76643000000001], %) // LineRelative
|> lineTo([310.68767, -124.76643000000001], %) // LineRelative
|> lineTo([317.68767, -122.76643000000001], %) // LineRelative
|> bezierCurve({ control1: [324.37517, -113.14143000000001], control2: [322.56495, -117.43458000000001], to: [322.56495, -117.43458000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [327.68767, -96.76643500000002], control2: [326.02173000000005, -107.65292000000001], to: [327.05405, -102.46899000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [323.37517, -79.39143500000002], control2: [327.04242000000005, -90.45732500000001], to: [325.54155000000003, -85.36362500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [320.68767, -73.76643500000002], control2: [322.48830000000004, -77.53518500000001], to: [321.60142, -75.67893500000001]}, %) // CubicBezierRelative
|> lineTo([315.68767, -68.76643500000002], %) // LineRelative
|> bezierCurve({ control1: [305.43767, -66.32893500000002], control2: [310.76687000000004, -66.51488500000002], to: [310.76687000000004, -66.51488500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [299.68767, -66.76643500000002], control2: [302.59142, -66.54550500000002], to: [302.59142, -66.54550500000002]}, %) // CubicBezierRelative
// StopRelative
|> lineTo([240.68767000000003, -68.76643500000002], %) // MoveRelative
|> bezierCurve({ control1: [222.68767000000003, -80.76643500000002], control2: [233.66999, -72.11131500000002], to: [228.65800000000002, -75.79116500000002]}, %) // CubicBezierRelative
|> lineTo([219.68767000000003, -86.76643500000002], %) // LineRelative
|> bezierCurve({ control1: [222.55095000000003, -116.67268000000001], control2: [219.05386000000001, -97.26953500000002], to: [220.04332000000002, -106.46619000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [227.68767000000003, -130.76643], control2: [223.91824000000003, -121.59681000000002], to: [225.39892000000003, -126.18894000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.43377000000004, -136.4969], control2: [232.25590000000003, -134.74853000000002], to: [232.25590000000003, -134.74853000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [249.75017000000003, -138.07893], control2: [241.08415000000005, -137.88476], to: [244.90570000000002, -138.13253]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [254.34783000000002, -138.06723000000002], control2: [251.26740000000004, -138.07493000000002], to: [252.78463000000002, -138.07093]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [265.68767, -135.76644000000002], control2: [259.20097000000004, -137.88174000000004], to: [259.20097000000004, -137.88174000000004]}, %) // CubicBezierRelative
|> lineTo([265.68767, -132.76644000000002], %) // VerticalLineHorizonal
|> lineTo([267.68767, -132.76644000000002], %) // HorizontalLineRelative
|> bezierCurve({ control1: [268.56267, -122.32894000000002], control2: [268.96128000000004, -128.41242000000003], to: [268.96128000000004, -128.41242000000003]}, %) // CubicBezierRelative
|> lineTo([267.68767, -115.76644000000002], %) // LineRelative
|> lineTo([262.68767, -110.76644000000002], %) // LineRelative
|> lineTo([259.68767, -104.76644000000002], %) // LineRelative
|> lineTo([259.68767, -96.76644500000002], %) // VerticalLineHorizonal
|> lineTo([263.68767, -91.76644500000002], %) // LineRelative
|> lineTo([263.68767, -88.76644500000002], %) // VerticalLineHorizonal
|> lineTo([265.68767, -88.76644500000002], %) // HorizontalLineRelative
|> bezierCurve({ control1: [265.68767, -74.76644500000002], control2: [265.77327, -84.10056500000002], to: [265.76887000000005, -79.43241500000002]}, %) // CubicBezierRelative
|> lineTo([263.68767, -71.76644500000002], %) // LineRelative
|> lineTo([257.68767, -68.76644500000002], %) // LineRelative
|> bezierCurve({ control1: [240.68767000000003, -68.76644500000002], control2: [251.63750000000002, -68.30105500000002], to: [246.62747000000002, -68.01396500000001]}, %) // CubicBezierRelative
// StopRelative
|> lineTo([348.06267, -71.45394500000002], %) // MoveRelative
|> bezierCurve({ control1: [336.68767, -78.76644500000002], control2: [342.24112, -73.65657500000002], to: [342.24112, -73.65657500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [331.68767, -85.76644500000002], control2: [333.86052, -82.22373500000002], to: [333.86052, -82.22373500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [330.68767, -113.76644000000002], control2: [329.44062, -94.75465500000001], to: [330.36224000000004, -104.56387000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [333.68767, -125.76644000000002], control2: [331.54987, -120.49367000000002], to: [331.54987, -120.49367000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [339.68767, -134.76644000000002], control2: [336.35378000000003, -130.85268000000002], to: [336.35378000000003, -130.85268000000002]}, %) // CubicBezierRelative
|> lineTo([344.68767, -136.76644000000002], %) // LineRelative
|> bezierCurve({ control1: [354.50017, -136.89144000000002], control2: [347.95588000000004, -136.90388000000002], to: [351.22938000000005, -136.93595000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [359.7072, -136.83674000000002], control2: [357.07765, -136.86434000000003], to: [357.07765, -136.86434000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [363.68767, -136.76644000000002], control2: [361.02076, -136.81354000000002], to: [362.33431, -136.79034000000001]}, %) // CubicBezierRelative
|> lineTo([364.68767, -133.76644000000002], %) // LineRelative
|> lineTo([369.68767, -132.76644000000002], %) // LineRelative
|> lineTo([374.68767, -127.76644000000002], %) // LineRelative
|> lineTo([375.68767, -125.76644000000002], %) // LineRelative
|> lineTo([378.68767, -124.76644000000002], %) // LineRelative
|> lineTo([381.68767, -119.76644000000002], %) // LineRelative
|> bezierCurve({ control1: [383.68767, -90.76644500000002], control2: [383.35291, -110.03795000000002], to: [384.23553000000004, -100.62782000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [376.68767, -74.76644500000002], control2: [381.89678000000004, -84.77624500000002], to: [379.89992, -80.12019500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [361.68767, -69.76644500000002], control2: [371.66314, -72.44743500000001], to: [367.11478000000005, -70.85187500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [348.06267, -71.45394500000002], control2: [353.98599, -69.38331500000002], to: [353.98599, -69.38331500000002]}, %) // CubicBezierRelative
// StopRelative
|> lineTo([420.68767, -75.76644500000002], %) // MoveRelative
|> lineTo([414.68767, -78.76644500000002], %) // MoveRelative
|> lineTo([411.68767, -81.76644500000002], %) // MoveRelative
|> bezierCurve({ control1: [394.68767, -89.76644500000002], control2: [406.10302, -84.70574500000002], to: [400.49226000000004, -87.27876500000002]}, %) // CubicBezierRelative
|> lineTo([390.68767, -93.76644500000002], %) // LineRelative
|> bezierCurve({ control1: [387.00017, -105.95394000000002], control2: [388.81932, -97.84915500000002], to: [387.7277, -101.52261000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [386.68767, -123.76644000000002], control2: [386.61176, -111.93554000000002], to: [386.45034000000004, -117.77373000000001]}, %) // CubicBezierRelative
|> lineTo([389.68767, -129.76644000000002], %) // LineRelative
|> bezierCurve({ control1: [401.68767, -140.76644000000002], control2: [393.59112000000005, -133.6699], to: [397.39354000000003, -137.31580000000002]}, %) // CubicBezierRelative
|> lineTo([406.68767, -142.76644000000002], %) // LineRelative
|> bezierCurve({ control1: [419.18767, -141.64144000000002], control2: [414.16723, -143.08983], to: [414.16723, -143.08983]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [431.68767, -133.76644000000002], control2: [424.08865000000003, -139.59937000000002], to: [427.61672000000004, -137.15890000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [438.81267, -125.32894000000002], control2: [436.54426, -129.29261000000002], to: [436.54426, -129.29261000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [443.68767, -106.76644000000002], control2: [441.36597, -119.11592000000002], to: [442.65924, -113.42420000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [442.68767, -87.76644500000002], control2: [443.82181, -100.36380000000001], to: [443.70527000000004, -94.09420500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [438.68767, -79.76644500000002], control2: [441.01966000000004, -83.40792500000002], to: [441.01966000000004, -83.40792500000002]}, %) // CubicBezierRelative
|> lineTo([434.68767, -76.76644500000002], %) // LineRelative
|> bezierCurve({ control1: [420.68767, -75.76644500000002], control2: [428.38627, -75.54725500000002], to: [428.38627, -75.54725500000002]}, %) // CubicBezierRelative
|> lineTo([119.83194, -25.193075], %) // MoveRelative
|> bezierCurve({ control1: [126.83194, -26.193075], control2: [122.14194, -25.523075], to: [124.45194000000001, -25.853075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [129.83194, -32.193075], control2: [127.82194, -28.173075], to: [128.81194, -30.153075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [130.83194, -33.193075], control2: [130.16194000000002, -32.523075], to: [130.49194, -32.853075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [131.83194, -41.193075], control2: [131.16194000000002, -35.833075], to: [131.49194, -38.473075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [133.83194, -38.193075], control2: [132.49194, -40.203075], to: [133.15194, -39.213075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [135.26944, -32.068075], control2: [134.30631, -36.171825], to: [134.78069, -34.150575]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [136.83194, -26.193075], control2: [135.78506000000002, -30.129325], to: [136.30069, -28.190575]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [139.83194, -25.193075], control2: [137.82194, -25.863075000000002], to: [138.81194, -25.533075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [137.39444, -44.318075], control2: [139.51153, -31.793465], to: [139.18359, -37.939365]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [133.83194, -52.193075], control2: [135.83194, -48.193075], to: [135.83194, -48.193075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [129.83194, -51.193075], control2: [132.51194, -51.863075], to: [131.19194000000002, -51.533075000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [124.83194, -41.193075], control2: [126.83194, -46.193075], to: [126.83194, -46.193075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [120.83194, -51.193075], control2: [123.51194000000001, -44.493075], to: [122.19194, -47.793075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [117.83194, -51.193075], control2: [119.84194000000001, -51.193075], to: [118.85194, -51.193075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [116.83194, -50.193075], control2: [117.50194, -50.863075], to: [117.17194, -50.533075000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [118.83194, -26.193075], control2: [116.5899, -41.883314999999996], to: [116.78264, -34.269515]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [119.83194, -25.193075], control2: [119.16194, -25.863075000000002], to: [119.49194, -25.533075]}, %) // CubicBezierRelative
|> lineTo([65.254392, -26.686845], %) // MoveRelative
|> bezierCurve({ control1: [69.254392, -26.686845], control2: [66.57439199999999, -26.686845], to: [67.894392, -26.686845]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [70.254392, -32.686845000000005], control2: [69.584392, -28.666845000000002], to: [69.91439199999999, -30.646845000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [69.254392, -35.686845000000005], control2: [69.924392, -33.67684500000001], to: [69.594392, -34.666845]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [69.254392, -44.686845000000005], control2: [69.21439199999999, -38.686575000000005], to: [69.210922, -41.687155000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [72.629392, -39.374345000000005], control2: [70.36814199999999, -42.93371500000001], to: [71.481892, -41.180595000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [78.254392, -30.686845000000005], control2: [74.483601, -36.465155], to: [76.34075899999999, -33.557295]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [81.254392, -30.686845000000005], control2: [79.24439199999999, -30.686845000000005], to: [80.234392, -30.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [80.004392, -42.811845000000005], control2: [81.254392, -38.686845000000005], to: [81.254392, -38.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [74.254392, -52.686845000000005], control2: [78.254392, -46.686845000000005], to: [78.254392, -46.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [73.254392, -53.686845000000005], control2: [73.924392, -53.016845], to: [73.594392, -53.346845]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [67.254392, -53.686845000000005], control2: [71.27439199999999, -53.686845000000005], to: [69.294392, -53.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [61.254391999999996, -48.686845000000005], control2: [65.27439199999999, -52.03684500000001], to: [63.294391999999995, -50.38684500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [60.254391999999996, -46.686845000000005], control2: [60.924392, -48.02684500000001], to: [60.594392, -47.366845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [61.254391999999996, -28.686845000000005], control2: [60.10475399999999, -40.47687500000001], to: [60.373141, -34.855605000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [65.254392, -26.686845000000005], control2: [62.574391999999996, -28.026845000000005], to: [63.894391999999996, -27.366845000000005]}, %) // CubicBezierRelative
|> lineTo([185.48371, -31.108985], %) // MoveRelative
|> bezierCurve({ control1: [197.48371, -31.108985], control2: [189.48289, -31.028185], to: [193.48463, -31.022985000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [198.48371, -36.108985000000004], control2: [197.81371000000001, -32.758985], to: [198.14371, -34.408985]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [197.48371, -38.108985000000004], control2: [198.15371, -36.768985], to: [197.82371, -37.428985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [189.48371, -38.108985000000004], control2: [194.84371000000002, -38.108985000000004], to: [192.20371, -38.108985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.48371, -42.108985000000004], control2: [189.15371, -39.428985000000004], to: [188.82371, -40.748985000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [196.48371, -43.108985000000004], control2: [191.12371, -42.438985], to: [193.76371, -42.768985]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [196.48371, -47.108985000000004], control2: [196.48371, -44.428985000000004], to: [196.48371, -45.748985000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [191.54621, -48.983985000000004], control2: [194.85433, -47.727735], to: [193.22496, -48.346485]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [186.48371, -51.108985000000004], control2: [189.87558, -49.685235000000006], to: [188.20496, -50.38648500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [185.48371, -53.108985000000004], control2: [186.15371, -51.768985], to: [185.82371, -52.428985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [195.48371, -52.108985000000004], control2: [188.78371, -52.778985000000006], to: [192.08371, -52.44898500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [193.48371, -56.108985000000004], control2: [194.82371, -53.428985000000004], to: [194.16371, -54.748985000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.48371, -58.108985000000004], control2: [191.83371, -56.768985], to: [190.18371, -57.428985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [183.48371, -58.108985000000004], control2: [186.83371, -58.108985000000004], to: [185.18371, -58.108985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [179.48371, -55.108985000000004], control2: [182.16371, -57.118985], to: [180.84371000000002, -56.12898500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [180.79621, -38.046485000000004], control2: [178.95086, -49.019255], to: [179.50181, -44.025395]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [182.48371, -33.108985000000004], control2: [181.35308, -36.41710500000001], to: [181.90996, -34.787735000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [185.48371, -31.108985000000004], control2: [183.47371, -32.44898500000001], to: [184.46371, -31.788985000000004]}, %) // CubicBezierRelative
|> lineTo([248.52117, -92.100105], %) // MoveRelative
|> bezierCurve({ control1: [252.52117, -92.100105], control2: [249.84117, -92.100105], to: [251.16117, -92.100105]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [253.52117, -99.100105], control2: [252.85117000000002, -94.410105], to: [253.18117, -96.720105]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [248.89617, -100.8501], control2: [251.99492, -99.677605], to: [250.46867, -100.2551]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [237.52117, -107.1001], control2: [243.22058, -103.02548], to: [243.22058, -103.02548]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.52117, -109.1001], control2: [237.19117, -107.7601], to: [236.86117000000002, -108.42009999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [252.52117, -108.1001], control2: [241.80117, -108.7701], to: [247.08117000000001, -108.4401]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [253.52117, -112.1001], control2: [252.85117000000002, -109.42009999999999], to: [253.18117, -110.7401]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [248.52117, -117.1001], control2: [251.87117, -113.7501], to: [250.22117, -115.4001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [234.52117, -118.1001], control2: [242.52117, -118.1001], to: [242.52117, -118.1001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [231.52117, -112.1001], control2: [233.53117, -116.1201], to: [232.54117000000002, -114.1401]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [231.52117, -104.1001], control2: [231.52117, -109.4601], to: [231.52117, -106.8201]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.52117, -99.100105], control2: [233.17117000000002, -102.45009999999999], to: [234.82117000000002, -100.8001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.52117, -97.100105], control2: [236.52117, -98.440105], to: [236.52117, -97.780105]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [248.52117, -92.100105], control2: [240.49514000000002, -95.372295], to: [244.49777, -93.709465]}, %) // CubicBezierRelative
|> lineTo([299.09756, -85.781585], %) // MoveRelative
|> bezierCurve({ control1: [305.09756, -85.781585], control2: [301.07756, -85.781585], to: [303.05755999999997, -85.781585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [307.09756, -86.781585], control2: [305.75756, -86.111585], to: [306.41756, -86.441585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [308.09756, -97.781585], control2: [307.48978999999997, -90.442425], to: [307.81822999999997, -94.110415]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [309.09756, -102.78158], control2: [308.42755999999997, -99.43158500000001], to: [308.75756, -101.08158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [307.09756, -104.78158], control2: [308.43755999999996, -103.44158], to: [307.77756, -104.10158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [306.09756, -108.78158], control2: [306.76756, -106.10158], to: [306.43755999999996, -107.42158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [301.09756, -113.78158], control2: [304.43089, -110.44825], to: [302.76423, -112.11491000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [301.09756, -105.78158], control2: [301.09756, -111.14158], to: [301.09756, -108.50158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [298.09756, -106.78158], control2: [300.10756, -106.11158], to: [299.11755999999997, -106.44158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [294.09756, -105.78158], control2: [296.77756, -106.45158], to: [295.45756, -106.12158000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [293.09756, -111.78158], control2: [293.76756, -107.76158000000001], to: [293.43755999999996, -109.74158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [290.09756, -114.78158], control2: [292.10756, -112.77158], to: [291.11755999999997, -113.76158000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [290.09756, -100.78158], control2: [290.09756, -110.16158], to: [290.09756, -105.54158000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [292.09756, -100.78158], control2: [290.75756, -100.78158], to: [291.41756, -100.78158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [293.34756, -95.531585], control2: [292.51006, -99.049085], to: [292.92256, -97.316585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [295.09756, -89.781585], control2: [293.92506, -93.63408500000001], to: [294.50255999999996, -91.736585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [299.09756, -85.781585], control2: [296.41756, -88.46158500000001], to: [297.73756, -87.141585]}, %) // CubicBezierRelative
|> lineTo([419.93938, -96.155625], %) // MoveRelative
|> bezierCurve({ control1: [424.75188, -96.218125], control2: [422.32157, -96.186525], to: [422.32157, -96.186525]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [425.75188, -102.21812], control2: [425.08188, -98.198125], to: [425.41188000000005, -100.17812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [417.75188, -104.21812], control2: [423.11188000000004, -102.87812], to: [420.47188000000006, -103.53811999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [415.75188, -107.21812], control2: [416.76188, -105.70312], to: [416.76188, -105.70312]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [422.75188, -108.21812], control2: [418.06188000000003, -107.54812], to: [420.37188000000003, -107.87812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [423.75188, -112.21812], control2: [423.08188, -109.53811999999999], to: [423.41188000000005, -110.85812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [413.75188, -117.21812], control2: [418.80188000000004, -114.69312], to: [418.80188000000004, -114.69312]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [422.75188, -117.21812], control2: [416.72188000000006, -117.21812], to: [419.69188, -117.21812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [421.75188, -120.21812], control2: [422.42188000000004, -118.20812], to: [422.09188, -119.19812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [418.75188, -122.21812], control2: [420.76188, -120.87812], to: [419.77188, -121.53811999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [411.75188, -123.21812], control2: [416.44188, -122.54812], to: [414.13188, -122.87812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [407.75188, -121.21812], control2: [410.43188000000004, -122.55812], to: [409.11188000000004, -121.89812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [409.18938, -103.59312], control2: [407.53385000000003, -114.968], to: [407.63543000000004, -109.67378]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [411.75188, -97.218125], control2: [410.75188, -99.218125], to: [410.75188, -99.218125]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [419.93938, -96.155625], control2: [414.75188, -96.218125], to: [414.75188, -96.218125]}, %) // CubicBezierRelative
|> lineTo([198.29461, -92.109945], %) // MoveRelative
|> bezierCurve({ control1: [202.29461, -92.109945], control2: [199.61461, -92.109945], to: [200.93461, -92.109945]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [205.29461, -97.109945], control2: [203.28461000000001, -93.759945], to: [204.27461, -95.409945]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [205.29461, -104.10994], control2: [205.29461, -99.419945], to: [205.29461, -101.72994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -103.10994], control2: [204.63461, -103.77994], to: [203.97461, -103.44994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -101.10994], control2: [203.29461, -102.44994], to: [203.29461, -101.78994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [195.29461, -105.10994], control2: [200.58634, -102.35660999999999], to: [197.91966, -103.69645]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [194.29461, -108.10994], control2: [194.96461, -106.09993999999999], to: [194.63461, -107.08994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [201.29461, -110.10994], control2: [196.60461, -108.76993999999999], to: [198.91461, -109.42993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -112.10994], control2: [201.95461, -110.76993999999999], to: [202.61461, -111.42993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -117.10994], control2: [203.29461, -113.75994], to: [203.29461, -115.40993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [195.29461, -120.10994], control2: [200.65652, -118.18306], to: [197.98453, -119.17430999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [190.29461, -120.10994], control2: [193.64461, -120.10994], to: [191.99461, -120.10994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.29461, -117.10994], control2: [189.63461, -119.11994], to: [188.97461, -118.12993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [194.29461, -114.10994], control2: [190.27461, -116.11994], to: [192.25461, -115.12993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.29461, -110.10994], control2: [192.31461000000002, -112.78994], to: [190.33461, -111.46994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [186.29461, -107.10994], control2: [187.63461, -109.11994], to: [186.97461, -108.12993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [187.29461, -101.10994], control2: [186.62461000000002, -105.12993999999999], to: [186.95461, -103.14994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [191.29461, -96.109945], control2: [188.61461, -99.45994499999999], to: [189.93461, -97.809945]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [198.29461, -92.109945], control2: [193.60461, -94.789945], to: [195.91461, -93.469945]}, %) // CubicBezierRelative
|> lineTo([0, -0], %) // MoveRelative
|> bezierCurve({ control1: [3, -1], control2: [0.99, -0.33], to: [1.98, -0.66]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [3, -4], control2: [3, -1.99], to: [3, -2.98]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [8, -4], control2: [4.65, -4], to: [6.3, -4]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [13, -6], control2: [10.475, -4.99], to: [10.475, -4.99]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [13, -10], control2: [13, -7.32], to: [13, -8.64]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [7, -12], control2: [11.02, -10.66], to: [9.04, -11.32]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [3, -12], control2: [5.68, -12], to: [4.36, -12] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -19], control2: [2.01, -14.31], to: [1.02, -16.62] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-2, -18], control2: [-0.66, -18.67], to: [-1.32, -18.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-3, -8], control2: [-2.383986, -14.672121], to: [-2.7150643, -11.337819] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-4, -5], control2: [-3.33, -7.01], to: [-3.66, -6.02] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-1, -5], control2: [-3.01, -5], to: [-2.02, -5]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [0, -0], control2: [-0.6699999999999999, -3.35], to: [-0.33999999999999997, -1.7000000000000002]}, %) // CubicBezierRelative
|> lineTo([0, -0], %) // MoveRelative
|> bezierCurve({ control1: [7, -0], control2: [2.31, -0], to: [4.62, -0]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [17, -5], control2: [12.3125, -2.3125], to: [12.3125, -2.3125]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [19, -8], control2: [17.99, -6.485], to: [17.99, -6.485]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [17, -14], control2: [18.333333, -10], to: [17.666667, -12]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [15, -14], control2: [16.34, -14], to: [15.68, -14]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [14, -9], control2: [14.67, -12.35], to: [14.34, -10.7] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [6, -8], control2: [11.36, -8.67], to: [8.72, -8.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [6, -6], control2: [6, -7.34], to: [6, -6.68] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -5], control2: [4.35, -5.67], to: [2.7, -5.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [0.67, -3.35], to: [0.34, -1.7] }, %) // CubicBezierAbsolute
|> lineTo([-19.467588, -31.053017], %) // MoveRelative
|> bezierCurve({ control1: [-12.467588, -32.053017], control2: [-17.157588, -31.383017], to: [-14.847587999999998, -31.713017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-10.467588, -34.053017], control2: [-11.807587999999999, -32.713016999999994], to: [-11.147587999999999, -33.373017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-10.467588, -39.053017], control2: [-10.467588, -35.703016999999996], to: [-10.467588, -37.353016999999994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-14.467588, -37.053017], control2: [-11.787588, -38.393017], to: [-13.107588, -37.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-14.467588, -40.053017], control2: [-14.467588, -38.043017], to: [-14.467588, -39.033016999999994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-26.467588, -40.053017], control2: [-18.427588, -40.053017], to: [-22.387588, -40.053017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-24.467588, -38.053017], control2: [-25.807588, -39.393017], to: [-25.147588, -38.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-17.467588, -36.053017], control2: [-22.157588, -37.393017], to: [-19.847588, -36.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-21.467588, -34.053017], control2: [-18.787588, -35.393017], to: [-20.107588, -34.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-21.467588, -32.053017], control2: [-21.467588, -33.393017], to: [-21.467588, -32.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-19.467588, -31.053016999999997], control2: [-20.807588, -31.723017], to: [-20.147588, -31.393016999999997]}, %) // CubicBezierRelative
|> lineTo([0, -0], %) // MoveRelative
|> bezierCurve({ control1: [16, -3], control2: [5.4494016, -0.77848594], to: [10.65681, -1.7240142]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [18, -4], control2: [16.66, -3.33], to: [17.32, -3.66]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [18, -6], control2: [18, -4.66], to: [18, -5.32]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [14, -8], control2: [16.02, -6.99], to: [16.02, -6.99] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [7, -7], control2: [11.69, -7.67], to: [9.38, -7.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -3], control2: [5.02, -5.68], to: [3.04, -4.36] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -8], control2: [1, -4.65], to: [1, -6.3] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-3, -7], control2: [-0.32, -7.67], to: [-1.64, -7.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-4, -3], control2: [-3.33, -5.68], to: [-3.66, -4.36] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [-2.68, -2.01], to: [-1.36, -1.02] }, %) // CubicBezierAbsolute
|> lineTo([0, -0], %) // MoveAbsolute
|> bezierCurve({ control1: [7, -0], control2: [2.31, -0], to: [4.62, -0] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [7, -4], control2: [7, -1.32], to: [7, -2.64] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [9, -5], control2: [7.66, -4.33], to: [8.32, -4.66] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [5, -7], control2: [7.02, -5.99], to: [7.02, -5.99] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [8, -8], control2: [5.99, -7.33], to: [6.98, -7.66] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [5, -12], control2: [7.01, -9.32], to: [6.02, -10.64] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [6, -18], control2: [5.33, -13.98], to: [5.66, -15.96] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [2, -21], control2: [4.68, -18.99], to: [3.36, -19.98] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -21], control2: [1.34, -21], to: [0.68, -21] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [2, -3], control2: [-0.18556857, -14.319532], to: [0.34378347, -9.6248661] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -3], control2: [1.34, -3], to: [0.68, -3] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [0, -2.01], to: [0, -1.02] }, %) // CubicBezierAbsolute
|> lineTo([0, -0], %) // MoveRelative
|> bezierCurve({ control1: [1, -4], control2: [0.33, -1.32], to: [0.66, -2.64]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [9, -4], control2: [3.64, -4], to: [6.28, -4]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [12, -1], control2: [9.99, -3.01], to: [10.98, -2.02]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [12, -3], control2: [12, -1.6600000000000001], to: [12, -2.3200000000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [15, -4], control2: [12.99, -3.33], to: [13.98, -3.66]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [12, -6], control2: [14.01, -4.66], to: [13.02, -5.32] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [2, -7], control2: [8.6740937, -6.4007116], to: [5.3398344, -6.7397532] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [9, -11], control2: [5.465, -8.98], to: [5.465, -8.98] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [9, -12], control2: [9, -11.33], to: [9, -11.66] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -11], control2: [6.36, -11.67], to: [3.72, -11.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-2, -9], control2: [0.01, -10.34], to: [-0.98, -9.68] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-2, -4], control2: [-2, -7.35], to: [-2, -5.7] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-4, -3], control2: [-2.66, -3.67], to: [-3.32, -3.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -2], control2: [-2.68, -2.67], to: [-1.36, -2.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [0, -1.34], to: [0, -0.68] }, %) // CubicBezierAbsolute
|> close(%);
show(svg);

View File

@ -85,25 +85,6 @@ show(fnBox)"#;
twenty_twenty::assert_image("tests/executor/outputs/function_sketch.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_execute_with_function_sketch_with_position() {
let code = r#"fn box = (p, h, l, w) => {
const myBox = startSketchAt(p)
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, -l], %)
|> close(%)
|> extrude(h, %)
return myBox
}
show(box([0,0], 3, 6, 10))"#;
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/function_sketch_with_position.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_execute_with_angled_line() {
let code = r#"const part001 = startSketchAt([4.83, 12.56])
@ -146,58 +127,3 @@ show(bracket)"#;
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/parametric.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_execute_engine_error_return() {
let code = r#"const part001 = startSketchAt([5.5229, 5.25217])
|> line([10.50433, -1.19122], %)
|> line([8.01362, -5.48731], %)
|> line([-1.02877, -6.76825], %)
|> line([-11.53311, 2.81559], %)
|> extrude(4, %)
"#;
let result = execute_and_snapshot(code).await;
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"engine: KclErrorDetails { source_ranges: [SourceRange([193, 206])], message: "Modeling command failed: Some([ApiError { error_code: BadRequest, message: \"The path is not closed. Solid2D construction requires a closed path!\" }])" }"#,
);
}
#[tokio::test(flavor = "multi_thread")]
#[ignore] // ignore until more stack fixes
async fn serial_test_execute_pipes_on_pipes() {
let code = include_str!("inputs/pipes_on_pipes.kcl");
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/pipes_on_pipes.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_member_expression_sketch_group() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchAt(pos)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const b1 = cube([0,0], 10)
const b2 = cube([3,3], 4)
const pt1 = b1.value[0]
const pt2 = b2.value[0]
show(b1)
show(b2)"#;
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image(
"tests/executor/outputs/member_expression_sketch_group.png",
&result,
1.0,
);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 41 KiB