Compare commits
15 Commits
v0.8.0
...
paultag/us
Author | SHA1 | Date | |
---|---|---|---|
e578b961d8 | |||
b67c16cc9d | |||
ad482641ef | |||
9ee24845a1 | |||
e69d263252 | |||
111738f38e | |||
e34501cc5a | |||
c767c1c3a6 | |||
e399a8f938 | |||
59d5f2524a | |||
b47ebd14d2 | |||
e74bcd0695 | |||
22161ec386 | |||
ada46c4317 | |||
6675fa8d1e |
2
.github/workflows/cargo-clippy.yml
vendored
@ -54,4 +54,4 @@ jobs:
|
||||
- name: Run clippy
|
||||
run: |
|
||||
cd "${{ matrix.dir }}"
|
||||
cargo clippy --all --tests -- -D warnings
|
||||
cargo clippy --all --tests --benches -- -D warnings
|
||||
|
37
.github/workflows/cargo-criterion.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '**.rs'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- .github/workflows/cargo-criterion.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.rs'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- .github/workflows/cargo-criterion.yml
|
||||
workflow_dispatch:
|
||||
permissions: read-all
|
||||
name: cargo criterion
|
||||
jobs:
|
||||
cargocriterion:
|
||||
name: cargo criterion
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cargo install cargo-criterion
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
- name: Benchmark kcl library
|
||||
shell: bash
|
||||
run: |-
|
||||
cd src/wasm-lib/kcl; cargo criterion
|
||||
|
2
.gitignore
vendored
@ -22,6 +22,8 @@ npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
src/wasm-lib/.idea
|
||||
|
||||
# rust
|
||||
src/wasm-lib/target
|
||||
src/wasm-lib/bindings
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "untitled-app",
|
||||
"version": "0.8.0",
|
||||
"version": "0.8.2",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.9.0",
|
||||
@ -65,7 +65,7 @@
|
||||
"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:rust": "(cd src/wasm-lib && cargo test --all && cargo clippy --all --tests --benches)",
|
||||
"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",
|
||||
|
26
src-tauri/Cargo.lock
generated
@ -2182,6 +2182,17 @@ 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"
|
||||
@ -3469,6 +3480,19 @@ 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"
|
||||
@ -3604,6 +3628,7 @@ dependencies = [
|
||||
"objc",
|
||||
"once_cell",
|
||||
"open",
|
||||
"os_info",
|
||||
"percent-encoding",
|
||||
"rand 0.8.5",
|
||||
"raw-window-handle",
|
||||
@ -3616,6 +3641,7 @@ dependencies = [
|
||||
"serde_repr",
|
||||
"serialize-to-javascript",
|
||||
"state",
|
||||
"sys-locale",
|
||||
"tar",
|
||||
"tauri-macros",
|
||||
"tauri-runtime",
|
||||
|
@ -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 = ["dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "updater", "devtools"] }
|
||||
tauri = { version = "1.4.1", features = [ "os-all", "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"
|
||||
|
@ -6,6 +6,7 @@ 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]
|
||||
@ -88,11 +89,34 @@ 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>) -> Result<kittycad::types::User, InvokeError> {
|
||||
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}")
|
||||
}
|
||||
}
|
||||
println!("Getting user info...");
|
||||
|
||||
// use kittycad library to fetch the user info from /user/me
|
||||
let client = kittycad::Client::new(token.unwrap());
|
||||
let mut client = kittycad::Client::new(token.unwrap());
|
||||
|
||||
if baseurl != DEFAULT_HOST {
|
||||
client.set_base_url(&baseurl);
|
||||
}
|
||||
|
||||
let user_info: kittycad::types::User = client
|
||||
.users()
|
||||
|
@ -8,7 +8,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "kittycad-modeling",
|
||||
"version": "0.8.0"
|
||||
"version": "0.8.2"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
@ -36,6 +36,9 @@
|
||||
"https://api.dev.kittycad.io/*"
|
||||
]
|
||||
},
|
||||
"os": {
|
||||
"all": true
|
||||
},
|
||||
"shell": {
|
||||
"open": true
|
||||
},
|
||||
|
@ -6,9 +6,9 @@ export const Auth = ({ children }: React.PropsWithChildren) => {
|
||||
const {
|
||||
auth: { state },
|
||||
} = useGlobalStateContext()
|
||||
const isLoggedIn = state.matches('checkIfLoggedIn')
|
||||
const isLoggingIn = state.matches('checkIfLoggedIn')
|
||||
|
||||
return isLoggedIn ? (
|
||||
return isLoggingIn ? (
|
||||
<Loading>Loading KittyCAD Modeling App...</Loading>
|
||||
) : (
|
||||
<>{children}</>
|
||||
|
@ -130,6 +130,7 @@ const router = createBrowserRouter(
|
||||
path: paths.INDEX,
|
||||
loader: () =>
|
||||
isTauri() ? redirect(paths.HOME) : redirect(paths.FILE + '/new'),
|
||||
errorElement: <ErrorPage />,
|
||||
},
|
||||
{
|
||||
path: paths.FILE + '/:id',
|
||||
@ -140,7 +141,6 @@ const router = createBrowserRouter(
|
||||
{!isTauri() && import.meta.env.PROD && <DownloadAppBanner />}
|
||||
</Auth>
|
||||
),
|
||||
errorElement: <ErrorPage />,
|
||||
id: paths.FILE,
|
||||
loader: async ({
|
||||
request,
|
||||
|
@ -62,7 +62,7 @@ export const CommandBarProvider = ({
|
||||
|
||||
const CommandBar = () => {
|
||||
const { commands, commandBarOpen, setCommandBarOpen } = useCommandsContext()
|
||||
useHotkeys('meta+k', () => {
|
||||
useHotkeys(['meta+k', 'meta+/'], () => {
|
||||
if (commands.length === 0) return
|
||||
setCommandBarOpen(!commandBarOpen)
|
||||
})
|
||||
@ -221,10 +221,10 @@ const CommandBar = () => {
|
||||
<Combobox
|
||||
value={selectedCommand}
|
||||
onChange={handleCommandSelection}
|
||||
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"
|
||||
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"
|
||||
as="div"
|
||||
>
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<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="bg-transparent focus:outline-none w-full"
|
||||
className="w-full bg-transparent focus:outline-none"
|
||||
onKeyDown={(event) => {
|
||||
if (event.metaKey && event.key === 'k')
|
||||
setCommandBarOpen(false)
|
||||
@ -264,12 +264,12 @@ const CommandBar = () => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Combobox.Options static className="max-h-96 overflow-y-auto">
|
||||
<Combobox.Options static className="overflow-y-auto max-h-96">
|
||||
{filteredCommands?.map((commandResult) => (
|
||||
<Combobox.Option
|
||||
key={commandResult.item.name}
|
||||
value={commandResult}
|
||||
className="my-2 first:mt-4 last:mb-4 ui-active:bg-liquid-10 dark:ui-active:bg-liquid-90 py-1 px-2"
|
||||
className="px-2 py-1 my-2 first:mt-4 last:mb-4 ui-active:bg-liquid-10 dark:ui-active:bg-liquid-90"
|
||||
>
|
||||
<p>{commandResult.item.name}</p>
|
||||
{(commandResult.item as SubCommand).description && (
|
||||
|
@ -30,7 +30,11 @@ export const DebugPanel = ({ className, ...props }: CollapsiblePanelProps) => {
|
||||
return (
|
||||
<CollapsiblePanel
|
||||
{...props}
|
||||
className={'!absolute !h-auto bottom-5 right-5 ' + className}
|
||||
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)' }}
|
||||
>
|
||||
<section className="p-4 flex flex-col gap-4">
|
||||
<Xyz
|
||||
|
@ -1,4 +1,12 @@
|
||||
import { useRouteError } from 'react-router-dom'
|
||||
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'
|
||||
|
||||
export const ErrorPage = () => {
|
||||
let error = useRouteError()
|
||||
@ -11,7 +19,43 @@ export const ErrorPage = () => {
|
||||
<h1 className="text-4xl mb-8 font-bold">
|
||||
An unexpected error occurred
|
||||
</h1>
|
||||
<p>{String(error)}</p>
|
||||
{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>
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
|
@ -24,7 +24,11 @@ export const MemoryPanel = ({
|
||||
<CollapsiblePanel {...props}>
|
||||
<div className="h-full relative">
|
||||
<div className="absolute inset-0 flex flex-col items-start">
|
||||
<div className=" h-full console-tile w-full">
|
||||
<div
|
||||
className="overflow-y-auto h-full console-tile w-full"
|
||||
style={{ marginBottom: 36 }}
|
||||
>
|
||||
{/* 36px is the height of PanelHeader */}
|
||||
<ReactJson
|
||||
src={ProcessedMemory}
|
||||
collapsed={1}
|
||||
|
@ -1,42 +0,0 @@
|
||||
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>
|
||||
}
|
@ -5,8 +5,6 @@ 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
|
||||
@ -26,12 +24,8 @@ export default class Server {
|
||||
intoServer: IntoServer,
|
||||
fromServer: FromServer
|
||||
): Promise<Server> {
|
||||
if (null == server) {
|
||||
const initOutput = await init()
|
||||
server = new Server(initOutput, intoServer, fromServer)
|
||||
} else {
|
||||
console.warn('Server already initialized; ignoring')
|
||||
}
|
||||
const initOutput = await init()
|
||||
const server = new Server(initOutput, intoServer, fromServer)
|
||||
return server
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,55 @@ import { _executor } from '../lang/executor'
|
||||
import { useStore } from '../useStore'
|
||||
import { EngineCommandManager } from '../lang/std/engineConnection'
|
||||
|
||||
class EngineCommandManagerSingleton {
|
||||
width: number
|
||||
height: number
|
||||
engineCommandManager?: EngineCommandManager
|
||||
|
||||
constructor() {
|
||||
this.width = 0
|
||||
this.height = 0
|
||||
}
|
||||
|
||||
get({
|
||||
setMediaStream,
|
||||
setIsStreamReady,
|
||||
width,
|
||||
height,
|
||||
token,
|
||||
}: {
|
||||
setMediaStream: (stream: MediaStream) => void
|
||||
setIsStreamReady: (isStreamReady: boolean) => void
|
||||
width: number
|
||||
height: number
|
||||
token?: string
|
||||
}): EngineCommandManager {
|
||||
if (
|
||||
this.engineCommandManager !== undefined &&
|
||||
this.width == width &&
|
||||
this.height == height
|
||||
) {
|
||||
return this.engineCommandManager
|
||||
}
|
||||
|
||||
const ecm = new EngineCommandManager({
|
||||
setMediaStream,
|
||||
setIsStreamReady,
|
||||
width: width,
|
||||
height: height,
|
||||
token,
|
||||
})
|
||||
|
||||
this.engineCommandManager = ecm
|
||||
this.width = width
|
||||
this.height = height
|
||||
|
||||
return ecm
|
||||
}
|
||||
}
|
||||
|
||||
const engineManagerSingleton = new EngineCommandManagerSingleton()
|
||||
|
||||
export function useSetupEngineManager(
|
||||
streamRef: React.RefObject<HTMLDivElement>,
|
||||
token?: string
|
||||
@ -35,7 +84,7 @@ export function useSetupEngineManager(
|
||||
streamHeight: quadHeight,
|
||||
})
|
||||
if (!width || !height) return
|
||||
const eng = new EngineCommandManager({
|
||||
const eng = engineManagerSingleton.get({
|
||||
setMediaStream,
|
||||
setIsStreamReady,
|
||||
width: quadWidth,
|
||||
|
@ -31,6 +31,14 @@ 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;
|
||||
|
@ -4,6 +4,7 @@ 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
|
||||
@ -132,6 +133,7 @@ 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
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
cameraMouseDragGuards,
|
||||
cameraSystems,
|
||||
} from 'lib/cameraControls'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function Units() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -25,10 +24,9 @@ export default function Units() {
|
||||
},
|
||||
},
|
||||
} = useGlobalStateContext()
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||
<div className="fixed inset-0 z-50 grid items-end justify-start px-4 pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-2xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
@ -38,10 +36,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"
|
||||
>
|
||||
<select
|
||||
id="camera-controls"
|
||||
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
||||
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
|
||||
value={cameraControls}
|
||||
onChange={(e) => {
|
||||
send({
|
||||
@ -56,7 +55,7 @@ export default function Units() {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<ul className="text-sm my-2 mx-4 leading-relaxed">
|
||||
<ul className="mx-4 my-2 text-sm leading-relaxed">
|
||||
<li>
|
||||
<strong>Pan:</strong>{' '}
|
||||
{cameraMouseDragGuards[cameraControls].pan.description}
|
||||
@ -74,7 +73,7 @@ export default function Units() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -2,7 +2,8 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
|
||||
import { ActionButton } from '../../components/ActionButton'
|
||||
import { onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useStore } from '../../useStore'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
import { Platform, platform } from '@tauri-apps/api/os'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export default function CmdK() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -10,10 +11,17 @@ export default function CmdK() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.USER_MENU)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
const [platformName, setPlatformName] = useState<Platform | ''>('')
|
||||
|
||||
useEffect(() => {
|
||||
async function getPlatform() {
|
||||
setPlatformName(await platform())
|
||||
}
|
||||
getPlatform()
|
||||
}, [setPlatformName])
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||
<div className="fixed inset-0 z-50 grid items-end justify-center pointer-events-none">
|
||||
<div
|
||||
className={
|
||||
'max-w-full xl:max-w-4xl flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
||||
@ -22,8 +30,17 @@ export default function CmdK() {
|
||||
>
|
||||
<h2 className="text-2xl">Command Bar</h2>
|
||||
<p className="my-4">
|
||||
Press <kbd>Cmd/Win</kbd> + <kbd>K</kbd> to open the command bar. Try
|
||||
changing your theme with it.
|
||||
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.
|
||||
</p>
|
||||
<p className="my-4">
|
||||
We are working on a command bar that will allow you to quickly see and
|
||||
@ -43,7 +60,7 @@ export default function CmdK() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -3,7 +3,6 @@ import { ActionButton } from '../../components/ActionButton'
|
||||
import { onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useStore } from '../../useStore'
|
||||
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function CodeEditor() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -11,7 +10,6 @@ export default function CodeEditor() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.PARAMETRIC_MODELING)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
||||
@ -62,7 +60,7 @@ export default function CodeEditor() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -2,7 +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 { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function Export() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -10,7 +9,6 @@ export default function Export() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.SKETCHING)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||
@ -42,7 +40,7 @@ export default function Export() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -4,14 +4,12 @@ import { useDismiss } from '.'
|
||||
import { useEffect } from 'react'
|
||||
import { useStore } from 'useStore'
|
||||
import { bracket } from 'lib/exampleKcl'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function FutureWork() {
|
||||
const dismiss = useDismiss()
|
||||
const { deferredSetCode } = useStore((s) => ({
|
||||
deferredSetCode: s.deferredSetCode,
|
||||
}))
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
useEffect(() => {
|
||||
deferredSetCode(bracket)
|
||||
@ -36,7 +34,7 @@ export default function FutureWork() {
|
||||
<div className="flex justify-between mt-6">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
@ -49,7 +47,7 @@ export default function FutureWork() {
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{ icon: faArrowRight }}
|
||||
>
|
||||
Finish
|
||||
|
@ -3,7 +3,6 @@ import { ActionButton } from '../../components/ActionButton'
|
||||
import { onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useStore } from '../../useStore'
|
||||
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function InteractiveNumbers() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -11,7 +10,6 @@ export default function InteractiveNumbers() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.COMMAND_K)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
||||
@ -102,7 +100,7 @@ export default function InteractiveNumbers() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -15,15 +15,13 @@ import { isTauri } from 'lib/isTauri'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { paths } from 'Router'
|
||||
import { useEffect } from 'react'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
function OnboardingWithNewFile() {
|
||||
const navigate = useNavigate()
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.INDEX)
|
||||
const { setCode } = useStore((s) => ({
|
||||
setCode: s.setCode,
|
||||
const { deferredSetCode } = useStore((s) => ({
|
||||
deferredSetCode: s.deferredSetCode,
|
||||
}))
|
||||
const {
|
||||
settings: {
|
||||
@ -53,7 +51,7 @@ function OnboardingWithNewFile() {
|
||||
<div className="flex justify-between mt-6">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash())}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
@ -67,7 +65,7 @@ function OnboardingWithNewFile() {
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => {
|
||||
setCode(bracket)
|
||||
deferredSetCode(bracket)
|
||||
next()
|
||||
}}
|
||||
icon={{ icon: faArrowRight }}
|
||||
@ -91,7 +89,7 @@ function OnboardingWithNewFile() {
|
||||
<div className="flex justify-between mt-6">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash())}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
@ -118,9 +116,9 @@ function OnboardingWithNewFile() {
|
||||
}
|
||||
|
||||
export default function Introduction() {
|
||||
const { setCode, code } = useStore((s) => ({
|
||||
const { deferredSetCode, code } = useStore((s) => ({
|
||||
code: s.code,
|
||||
setCode: s.setCode,
|
||||
deferredSetCode: s.deferredSetCode,
|
||||
}))
|
||||
const {
|
||||
settings: {
|
||||
@ -136,11 +134,10 @@ export default function Introduction() {
|
||||
: ''
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.CAMERA)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
useEffect(() => {
|
||||
if (code === '') setCode(bracket)
|
||||
}, [code, setCode])
|
||||
if (code === '') deferredSetCode(bracket)
|
||||
}, [code, deferredSetCode])
|
||||
|
||||
return !(code !== '' && code !== bracket) ? (
|
||||
<div className="fixed grid place-content-center inset-0 bg-chalkboard-110/50 z-50">
|
||||
@ -180,7 +177,7 @@ export default function Introduction() {
|
||||
<div className="flex justify-between mt-6">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash())}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -5,7 +5,6 @@ import { useStore } from '../../useStore'
|
||||
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
|
||||
import { Themes, getSystemTheme } from 'lib/theme'
|
||||
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function ParametricModeling() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -23,7 +22,6 @@ export default function ParametricModeling() {
|
||||
: ''
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.INTERACTIVE_NUMBERS)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
||||
@ -62,7 +60,7 @@ export default function ParametricModeling() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -3,7 +3,6 @@ import { ActionButton } from '../../components/ActionButton'
|
||||
import { onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useStore } from '../../useStore'
|
||||
import { isTauri } from 'lib/isTauri'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function ProjectMenu() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -11,7 +10,6 @@ export default function ProjectMenu() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.EXPORT)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
||||
@ -33,7 +31,7 @@ export default function ProjectMenu() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -3,7 +3,6 @@ import { ActionButton } from '../../components/ActionButton'
|
||||
import { onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useStore } from 'useStore'
|
||||
import { useEffect } from 'react'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function Sketching() {
|
||||
const { deferredSetCode, buttonDownInStream } = useStore((s) => ({
|
||||
@ -16,7 +15,6 @@ export default function Sketching() {
|
||||
useEffect(() => {
|
||||
deferredSetCode('')
|
||||
}, [deferredSetCode])
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||
@ -40,7 +38,7 @@ export default function Sketching() {
|
||||
<div className="flex justify-between mt-6">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -2,7 +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 { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function Streaming() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -10,7 +9,6 @@ export default function Streaming() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.EDITOR)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-start items-center inset-0 z-50 pointer-events-none">
|
||||
@ -43,7 +41,7 @@ export default function Streaming() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -6,7 +6,6 @@ import { Toggle } from '../../components/Toggle/Toggle'
|
||||
import { onboardingPaths, useDismiss, useNextClick } from '.'
|
||||
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
||||
import { UnitSystem } from 'machines/settingsMachine'
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function Units() {
|
||||
const dismiss = useDismiss()
|
||||
@ -17,7 +16,6 @@ export default function Units() {
|
||||
context: { unitSystem, baseUnit },
|
||||
},
|
||||
} = useGlobalStateContext()
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid place-content-center inset-0 bg-chalkboard-110/50 z-50">
|
||||
@ -68,7 +66,7 @@ export default function Units() {
|
||||
<div className="flex justify-between mt-6">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -2,7 +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 { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
|
||||
export default function UserMenu() {
|
||||
const { buttonDownInStream } = useStore((s) => ({
|
||||
@ -10,7 +9,6 @@ export default function UserMenu() {
|
||||
}))
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
||||
const dotDotSlash = useDotDotSlash()
|
||||
|
||||
return (
|
||||
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
||||
@ -30,7 +28,7 @@ export default function UserMenu() {
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => dismiss(dotDotSlash(2))}
|
||||
onClick={dismiss}
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { Outlet, useRouteLoaderData, useNavigate } from 'react-router-dom'
|
||||
import Introduction from './Introduction'
|
||||
import Camera from './Camera'
|
||||
import Sketching from './Sketching'
|
||||
@ -15,6 +15,7 @@ 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: '/',
|
||||
@ -89,42 +90,44 @@ export function useNextClick(newStatus: string) {
|
||||
settings: { send },
|
||||
} = useGlobalStateContext()
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const lastSlashIndex = location.pathname.lastIndexOf('/')
|
||||
const { project } = useRouteLoaderData(paths.FILE) as IndexLoaderData
|
||||
|
||||
return useCallback(() => {
|
||||
send({
|
||||
type: 'Set Onboarding Status',
|
||||
data: { onboardingStatus: newStatus },
|
||||
})
|
||||
navigate(location.pathname.slice(0, lastSlashIndex) + newStatus)
|
||||
}, [location, lastSlashIndex, newStatus, send, navigate])
|
||||
navigate(
|
||||
paths.FILE +
|
||||
'/' +
|
||||
encodeURIComponent(project?.path || 'new') +
|
||||
paths.ONBOARDING.INDEX.slice(0, -1) +
|
||||
newStatus
|
||||
)
|
||||
}, [project, newStatus, send, navigate])
|
||||
}
|
||||
|
||||
export function useDismiss() {
|
||||
const routeData = useRouteLoaderData(paths.FILE) as IndexLoaderData
|
||||
const {
|
||||
settings: { send },
|
||||
} = useGlobalStateContext()
|
||||
const navigate = useNavigate()
|
||||
|
||||
return useCallback(
|
||||
(path: string) => {
|
||||
send({
|
||||
type: 'Set Onboarding Status',
|
||||
data: { onboardingStatus: 'dismissed' },
|
||||
})
|
||||
console.log('yoyo', window.location.pathname, path)
|
||||
navigate(path)
|
||||
},
|
||||
[send, navigate]
|
||||
)
|
||||
return useCallback(() => {
|
||||
send({
|
||||
type: 'Set Onboarding Status',
|
||||
data: { onboardingStatus: 'dismissed' },
|
||||
})
|
||||
navigate(
|
||||
paths.FILE + '/' + encodeURIComponent(routeData?.project?.path || 'new')
|
||||
)
|
||||
}, [send, navigate, routeData])
|
||||
}
|
||||
|
||||
const Onboarding = () => {
|
||||
const location = useLocation()
|
||||
const dismiss = useDismiss()
|
||||
const lastSlashIndex = location.pathname.lastIndexOf('/')
|
||||
useHotkeys('esc', () => dismiss(location.pathname.slice(0, lastSlashIndex)))
|
||||
useHotkeys('esc', dismiss)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -64,7 +64,7 @@ export const Settings = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-bg fixed inset-0 z-40 overflow-auto">
|
||||
<div className="fixed inset-0 z-40 overflow-auto body-bg">
|
||||
<AppHeader showToolbar={false} project={loaderData?.project}>
|
||||
<ActionButton
|
||||
Element="link"
|
||||
@ -80,9 +80,9 @@ export const Settings = () => {
|
||||
Close
|
||||
</ActionButton>
|
||||
</AppHeader>
|
||||
<div className="my-24 max-w-5xl mx-auto">
|
||||
<div className="max-w-5xl mx-auto my-24">
|
||||
<h1 className="text-4xl font-bold">User Settings</h1>
|
||||
<p className="mt-6 max-w-2xl">
|
||||
<p className="max-w-2xl mt-6">
|
||||
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 +100,7 @@ export const Settings = () => {
|
||||
>
|
||||
<select
|
||||
id="camera-controls"
|
||||
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
||||
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
|
||||
value={cameraControls}
|
||||
onChange={(e) => {
|
||||
send({
|
||||
@ -115,7 +115,7 @@ export const Settings = () => {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<ul className="text-sm my-2 mx-4 leading-relaxed">
|
||||
<ul className="mx-4 my-2 text-sm leading-relaxed">
|
||||
<li>
|
||||
<strong>Pan:</strong>{' '}
|
||||
{cameraMouseDragGuards[cameraControls].pan.description}
|
||||
@ -136,7 +136,7 @@ export const Settings = () => {
|
||||
title="Default Directory"
|
||||
description="Where newly-created projects are saved on your local computer"
|
||||
>
|
||||
<div className="w-full flex gap-4 p-1 rounded border border-chalkboard-30">
|
||||
<div className="flex w-full gap-4 p-1 border rounded border-chalkboard-30">
|
||||
<input
|
||||
className="flex-1 px-2 bg-transparent"
|
||||
value={defaultDirectory}
|
||||
@ -163,7 +163,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 border border-chalkboard-30 bg-transparent"
|
||||
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
|
||||
defaultValue={defaultProjectName}
|
||||
onBlur={(e) => {
|
||||
const newValue = e.target.value.trim() || DEFAULT_PROJECT_NAME
|
||||
@ -207,7 +207,7 @@ export const Settings = () => {
|
||||
>
|
||||
<select
|
||||
id="base-unit"
|
||||
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
||||
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
|
||||
value={baseUnit}
|
||||
onChange={(e) => {
|
||||
send({
|
||||
@ -241,7 +241,7 @@ export const Settings = () => {
|
||||
>
|
||||
<select
|
||||
id="settings-theme"
|
||||
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
||||
className="block w-full px-3 py-1 bg-transparent border border-chalkboard-30"
|
||||
value={theme}
|
||||
onChange={(e) => {
|
||||
send({
|
||||
@ -285,15 +285,22 @@ 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">
|
||||
<section
|
||||
className={
|
||||
'my-16 last-of-type:mb-24 grid grid-cols-2 gap-12 items-start ' +
|
||||
className
|
||||
}
|
||||
>
|
||||
<div className="w-80">
|
||||
<h2 className="text-2xl">{title}</h2>
|
||||
<p className="mt-2 text-sm">{description}</p>
|
||||
|
146
src/wasm-lib/Cargo.lock
generated
@ -63,6 +63,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anes"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.5.0"
|
||||
@ -337,6 +343,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
@ -374,6 +386,33 @@ dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ciborium"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"ciborium-ll",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ciborium-io"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656"
|
||||
|
||||
[[package]]
|
||||
name = "ciborium-ll"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"half 1.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.1"
|
||||
@ -507,6 +546,42 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
|
||||
dependencies = [
|
||||
"anes",
|
||||
"cast",
|
||||
"ciborium",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"is-terminal",
|
||||
"itertools 0.10.5",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.10.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.8"
|
||||
@ -593,7 +668,7 @@ checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
||||
|
||||
[[package]]
|
||||
name = "derive-docs"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"expectorate",
|
||||
@ -606,20 +681,6 @@ 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"
|
||||
@ -730,7 +791,7 @@ checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"flume",
|
||||
"half",
|
||||
"half 2.2.1",
|
||||
"lebe",
|
||||
"miniz_oxide",
|
||||
"rayon-core",
|
||||
@ -997,6 +1058,12 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.2.1"
|
||||
@ -1301,8 +1368,9 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bson",
|
||||
"clap",
|
||||
"criterion",
|
||||
"dashmap",
|
||||
"derive-docs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derive-docs",
|
||||
"expectorate",
|
||||
"futures",
|
||||
"itertools 0.11.0",
|
||||
@ -1620,6 +1688,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "openapitor"
|
||||
version = "0.0.9"
|
||||
@ -1853,6 +1927,34 @@ version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
"plotters-svg",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.10"
|
||||
@ -2867,6 +2969,16 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "derive-docs"
|
||||
description = "A tool for generating documentation from Rust derive macros"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -212,6 +212,12 @@ 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! {
|
||||
@ -250,7 +256,15 @@ fn do_stdlib_inner(
|
||||
.replace("Result < ", "")
|
||||
.replace(", KclError >", "");
|
||||
let return_type = if !ret_ty_string.is_empty() {
|
||||
let ret_ty_string = ret_ty_string.trim().to_string();
|
||||
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_ident = format_ident!("{}", ret_ty_string);
|
||||
let ret_ty_string = clean_type(&ret_ty_string);
|
||||
quote! {
|
||||
@ -475,6 +489,9 @@ 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();
|
||||
@ -564,4 +581,26 @@ 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());
|
||||
}
|
||||
}
|
||||
|
70
src/wasm-lib/derive-docs/tests/box.gen
Normal file
@ -0,0 +1,70 @@
|
||||
#[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
|
||||
}
|
@ -12,8 +12,8 @@ anyhow = { version = "1.0.75", features = ["backtrace"] }
|
||||
async-trait = "0.1.73"
|
||||
clap = { version = "4.4.3", features = ["cargo", "derive", "env", "unicode"], optional = true }
|
||||
dashmap = "5.5.3"
|
||||
derive-docs = { version = "0.1.3" }
|
||||
#derive-docs = { path = "../derive-docs" }
|
||||
#derive-docs = { version = "0.1.4" }
|
||||
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"
|
||||
@ -50,7 +50,12 @@ panic = "abort"
|
||||
debug = true
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5.1"
|
||||
expectorate = "1.0.7"
|
||||
itertools = "0.11.0"
|
||||
pretty_assertions = "1.4.0"
|
||||
tokio = { version = "1.32.0", features = ["rt-multi-thread", "macros", "time"] }
|
||||
|
||||
[[bench]]
|
||||
name = "compiler_benchmark"
|
||||
harness = false
|
||||
|
27
src/wasm-lib/kcl/benches/compiler_benchmark.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
pub fn criterion_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("parse + lex cube program", |b| b.iter(lex_and_parse_cube));
|
||||
}
|
||||
|
||||
fn lex_and_parse_cube() {
|
||||
let program = 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 pt1 = b1[0]
|
||||
show(b1)"#;
|
||||
let tokens = kcl_lib::tokeniser::lexer(program);
|
||||
let parser = kcl_lib::parser::Parser::new(tokens);
|
||||
parser.ast().unwrap();
|
||||
}
|
||||
|
||||
criterion_group!(benches, criterion_benchmark);
|
||||
criterion_main!(benches);
|
@ -871,6 +871,11 @@ 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)?;
|
||||
@ -1815,10 +1820,11 @@ impl MemberExpression {
|
||||
let value = memory.get(&identifier.name, identifier.into())?;
|
||||
value.clone()
|
||||
}
|
||||
}
|
||||
.get_json_value()?;
|
||||
};
|
||||
|
||||
if let serde_json::Value::Array(array) = array {
|
||||
let array_json = array.get_json_value()?;
|
||||
|
||||
if let serde_json::Value::Array(array) = array_json {
|
||||
if let Some(value) = array.get(index) {
|
||||
Ok(MemoryItem::UserVal(UserVal {
|
||||
value: value.clone(),
|
||||
@ -1866,10 +1872,11 @@ impl MemberExpression {
|
||||
let value = memory.get(&identifier.name, identifier.into())?;
|
||||
value.clone()
|
||||
}
|
||||
}
|
||||
.get_json_value()?;
|
||||
};
|
||||
|
||||
if let serde_json::Value::Object(map) = object {
|
||||
let object_json = object.get_json_value()?;
|
||||
|
||||
if let serde_json::Value::Object(map) = object_json {
|
||||
if let Some(value) = map.get(&property_name) {
|
||||
Ok(MemoryItem::UserVal(UserVal {
|
||||
value: value.clone(),
|
||||
|
@ -101,8 +101,8 @@ impl ProgramReturn {
|
||||
#[serde(tag = "type")]
|
||||
pub enum MemoryItem {
|
||||
UserVal(UserVal),
|
||||
SketchGroup(SketchGroup),
|
||||
ExtrudeGroup(ExtrudeGroup),
|
||||
SketchGroup(Box<SketchGroup>),
|
||||
ExtrudeGroup(Box<ExtrudeGroup>),
|
||||
#[ts(skip)]
|
||||
ExtrudeTransform(ExtrudeTransform),
|
||||
#[ts(skip)]
|
||||
@ -159,10 +159,12 @@ impl MemoryItem {
|
||||
if let MemoryItem::UserVal(user_val) = self {
|
||||
Ok(user_val.value.clone())
|
||||
} else {
|
||||
Err(KclError::Semantic(KclErrorDetails {
|
||||
message: format!("Not a user value: {:?}", self),
|
||||
source_ranges: self.clone().into(),
|
||||
}))
|
||||
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(),
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,6 +601,10 @@ 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.
|
||||
_ => (),
|
||||
}
|
||||
@ -1173,6 +1179,16 @@ 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"#;
|
||||
@ -1183,6 +1199,22 @@ 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
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
pub mod ast;
|
||||
pub mod docs;
|
||||
pub mod engine;
|
||||
|
@ -422,9 +422,8 @@ impl ReversePolishNotation {
|
||||
{
|
||||
let closing_brace = self.parser.find_closing_brace(1, 0, "")?;
|
||||
let mut new_stack = stack;
|
||||
new_stack.push(MathExpression::CallExpression(Box::new(
|
||||
self.parser.make_call_expression(0)?.expression,
|
||||
)));
|
||||
let call_expression = self.parser.make_call_expression(0)?;
|
||||
new_stack.push(MathExpression::CallExpression(Box::new(call_expression.expression)));
|
||||
return self.build_tree(&reverse_polish_notation_tokens[closing_brace + 1..], new_stack);
|
||||
}
|
||||
if reverse_polish_notation_tokens[1].token_type == TokenType::Period
|
||||
|
@ -777,6 +777,7 @@ impl Parser {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if current_token.token_type == TokenType::Word
|
||||
|| current_token.token_type == TokenType::Number
|
||||
|| current_token.token_type == TokenType::String
|
||||
@ -1249,7 +1250,15 @@ impl Parser {
|
||||
})
|
||||
})?;
|
||||
let closing_brace_token = self.get_token(closing_brace_index)?;
|
||||
let args = self.make_arguments(brace_token.index, vec![])?;
|
||||
// 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 function = if let Some(stdlib_fn) = self.stdlib.get(&callee.name) {
|
||||
crate::ast::types::Function::StdLib { func: stdlib_fn }
|
||||
} else {
|
||||
@ -3356,6 +3365,19 @@ 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) => {
|
||||
@ -3408,4 +3430,47 @@ 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();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ pub fn extrude(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "extrude"
|
||||
}]
|
||||
fn inner_extrude(length: f64, sketch_group: SketchGroup, args: &mut Args) -> Result<ExtrudeGroup, KclError> {
|
||||
fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<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: SketchGroup, args: &mut Args) -> Res
|
||||
};
|
||||
args.send_modeling_cmd(id, cmd)?;
|
||||
|
||||
Ok(ExtrudeGroup {
|
||||
Ok(Box::new(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: SketchGroup, args: &mut Args) -> Res
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ impl<'a> Args<'a> {
|
||||
Ok((numbers[0], numbers[1]))
|
||||
}
|
||||
|
||||
fn get_segment_name_sketch_group(&self) -> Result<(String, SketchGroup), KclError> {
|
||||
fn get_segment_name_sketch_group(&self) -> Result<(String, Box<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<SketchGroup, KclError> {
|
||||
fn get_sketch_group(&self) -> Result<Box<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, SketchGroup), KclError> {
|
||||
fn get_data_and_sketch_group<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Box<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, SketchGroup), KclError> {
|
||||
fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, Box<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, SketchGroup), KclError> {
|
||||
fn get_number_sketch_group(&self) -> Result<(f64, Box<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, ExtrudeGroup), KclError> {
|
||||
fn get_path_name_extrude_group(&self) -> Result<(String, Box<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: SketchGroup) {}
|
||||
fn inner_show(_sketch: Box<SketchGroup>) {}
|
||||
|
||||
/// Returns the length of the given leg.
|
||||
pub fn leg_length(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
|
@ -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: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
|
||||
fn inner_segment_end_x(segment_name: &str, sketch_group: Box<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: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
|
||||
fn inner_segment_end_y(segment_name: &str, sketch_group: Box<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: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
|
||||
fn inner_last_segment_x(sketch_group: Box<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: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
|
||||
fn inner_last_segment_y(sketch_group: Box<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: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
|
||||
fn inner_segment_length(segment_name: &str, sketch_group: Box<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!(
|
||||
@ -162,7 +162,7 @@ pub fn segment_angle(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "segAng",
|
||||
}]
|
||||
fn inner_segment_angle(segment_name: &str, sketch_group: SketchGroup, args: &mut Args) -> Result<f64, KclError> {
|
||||
fn inner_segment_angle(segment_name: &str, sketch_group: Box<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!(
|
||||
@ -193,7 +193,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: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<f64, KclError> {
|
||||
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
||||
@ -248,7 +248,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: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<f64, KclError> {
|
||||
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
||||
|
@ -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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (LineToData, Box<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,7 +44,11 @@ pub fn line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "lineTo",
|
||||
}]
|
||||
fn inner_line_to(data: LineToData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_line_to(
|
||||
data: LineToData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
let to = match data {
|
||||
LineToData::PointWithTag { to, .. } => to,
|
||||
@ -107,7 +111,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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AxisLineToData, Box<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))
|
||||
@ -117,7 +121,11 @@ pub fn x_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "xLineTo",
|
||||
}]
|
||||
fn inner_x_line_to(data: AxisLineToData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_x_line_to(
|
||||
data: AxisLineToData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
|
||||
let line_to_data = match data {
|
||||
@ -132,7 +140,7 @@ fn inner_x_line_to(data: AxisLineToData, sketch_group: SketchGroup, args: &mut A
|
||||
|
||||
/// 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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AxisLineToData, Box<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))
|
||||
@ -142,7 +150,11 @@ pub fn y_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "yLineTo",
|
||||
}]
|
||||
fn inner_y_line_to(data: AxisLineToData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_y_line_to(
|
||||
data: AxisLineToData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
|
||||
let line_to_data = match data {
|
||||
@ -172,7 +184,7 @@ pub enum LineData {
|
||||
|
||||
/// Draw a line.
|
||||
pub fn line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (LineData, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (LineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_line(data, sketch_group, args)?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
@ -182,7 +194,7 @@ pub fn line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "line",
|
||||
}]
|
||||
fn inner_line(data: LineData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
let inner_args = match &data {
|
||||
LineData::PointWithTag { to, .. } => *to,
|
||||
@ -247,7 +259,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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_x_line(data, sketch_group, args)?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
@ -257,7 +269,11 @@ pub fn x_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "xLine",
|
||||
}]
|
||||
fn inner_x_line(data: AxisLineData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_x_line(
|
||||
data: AxisLineData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<Box<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]),
|
||||
@ -269,7 +285,7 @@ fn inner_x_line(data: AxisLineData, sketch_group: SketchGroup, args: &mut Args)
|
||||
|
||||
/// Draw a line on the y-axis.
|
||||
pub fn y_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (AxisLineData, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_y_line(data, sketch_group, args)?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
@ -279,7 +295,11 @@ pub fn y_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "yLine",
|
||||
}]
|
||||
fn inner_y_line(data: AxisLineData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_y_line(
|
||||
data: AxisLineData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<Box<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]),
|
||||
@ -309,7 +329,7 @@ pub enum AngledLineData {
|
||||
|
||||
/// Draw an angled line.
|
||||
pub fn angled_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (AngledLineData, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_angled_line(data, sketch_group, args)?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
@ -321,9 +341,9 @@ pub fn angled_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
}]
|
||||
fn inner_angled_line(
|
||||
data: AngledLineData,
|
||||
sketch_group: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<SketchGroup, KclError> {
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
let (angle, length) = match &data {
|
||||
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
|
||||
@ -373,7 +393,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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AngledLineData, Box<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))
|
||||
@ -385,9 +405,9 @@ pub fn angled_line_of_x_length(args: &mut Args) -> Result<MemoryItem, KclError>
|
||||
}]
|
||||
fn inner_angled_line_of_x_length(
|
||||
data: AngledLineData,
|
||||
sketch_group: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<SketchGroup, KclError> {
|
||||
) -> Result<Box<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]),
|
||||
@ -428,7 +448,7 @@ pub enum AngledLineToData {
|
||||
|
||||
/// 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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AngledLineToData, Box<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))
|
||||
@ -440,9 +460,9 @@ pub fn angled_line_to_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
}]
|
||||
fn inner_angled_line_to_x(
|
||||
data: AngledLineToData,
|
||||
sketch_group: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<SketchGroup, KclError> {
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
let (angle, x_to) = match &data {
|
||||
AngledLineToData::AngleWithTag { angle, to, .. } => (*angle, *to),
|
||||
@ -467,7 +487,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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_angled_line_of_y_length(data, sketch_group, args)?;
|
||||
|
||||
@ -480,9 +500,9 @@ pub fn angled_line_of_y_length(args: &mut Args) -> Result<MemoryItem, KclError>
|
||||
}]
|
||||
fn inner_angled_line_of_y_length(
|
||||
data: AngledLineData,
|
||||
sketch_group: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<SketchGroup, KclError> {
|
||||
) -> Result<Box<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]),
|
||||
@ -505,7 +525,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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AngledLineToData, Box<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))
|
||||
@ -517,9 +537,9 @@ pub fn angled_line_to_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
}]
|
||||
fn inner_angled_line_to_y(
|
||||
data: AngledLineToData,
|
||||
sketch_group: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<SketchGroup, KclError> {
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
let (angle, y_to) = match &data {
|
||||
AngledLineToData::AngleWithTag { angle, to, .. } => (*angle, *to),
|
||||
@ -560,7 +580,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, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (AngeledLineThatIntersectsData, Box<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))
|
||||
}
|
||||
@ -571,9 +591,9 @@ pub fn angled_line_that_intersects(args: &mut Args) -> Result<MemoryItem, KclErr
|
||||
}]
|
||||
fn inner_angled_line_that_intersects(
|
||||
data: AngeledLineThatIntersectsData,
|
||||
sketch_group: SketchGroup,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<SketchGroup, KclError> {
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let intersect_path = sketch_group
|
||||
.get_path_by_name(&data.intersect_tag)
|
||||
.ok_or_else(|| {
|
||||
@ -617,7 +637,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<SketchGroup, KclError> {
|
||||
fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
||||
let to = match &data {
|
||||
LineData::PointWithTag { to, .. } => *to,
|
||||
LineData::Point(to) => *to,
|
||||
@ -661,7 +681,7 @@ fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<SketchGroup,
|
||||
start: current_path,
|
||||
meta: vec![args.source_range.into()],
|
||||
};
|
||||
Ok(sketch_group)
|
||||
Ok(Box::new(sketch_group))
|
||||
}
|
||||
|
||||
/// Close the current sketch.
|
||||
@ -677,7 +697,7 @@ pub fn close(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "close",
|
||||
}]
|
||||
fn inner_close(sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_close(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
let to: Point2d = sketch_group.start.from.into();
|
||||
|
||||
@ -756,7 +776,7 @@ pub enum ArcData {
|
||||
|
||||
/// Draw an arc.
|
||||
pub fn arc(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (ArcData, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (ArcData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_arc(data, sketch_group, args)?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
@ -766,7 +786,7 @@ pub fn arc(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "arc",
|
||||
}]
|
||||
fn inner_arc(data: ArcData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
||||
|
||||
let (center, angle_start, angle_end, radius, end) = match &data {
|
||||
@ -883,7 +903,7 @@ pub enum BezierData {
|
||||
|
||||
/// Draw a bezier curve.
|
||||
pub fn bezier_curve(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (BezierData, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||
let (data, sketch_group): (BezierData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_bezier_curve(data, sketch_group, args)?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
@ -893,7 +913,11 @@ pub fn bezier_curve(args: &mut Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "bezierCurve",
|
||||
}]
|
||||
fn inner_bezier_curve(data: BezierData, sketch_group: SketchGroup, args: &mut Args) -> Result<SketchGroup, KclError> {
|
||||
fn inner_bezier_curve(
|
||||
data: BezierData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: &mut Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from = sketch_group.get_coords_from_paths()?;
|
||||
|
||||
let (to, control1, control2) = match &data {
|
||||
|
470
src/wasm-lib/tests/executor/inputs/pipes_on_pipes.kcl
Normal file
@ -0,0 +1,470 @@
|
||||
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);
|
@ -85,6 +85,25 @@ 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])
|
||||
@ -145,3 +164,40 @@ async fn serial_test_execute_engine_error_return() {
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 72 KiB |