Compare commits

...

19 Commits

Author SHA1 Message Date
c0c5c790ca Bump typescript from 5.7.2 to 5.7.3 (#5021)
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.7.2 to 5.7.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.7.2...v5.7.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 16:18:26 -05:00
8b60f75220 custom axis and origin example for helix (#5057)
* custom axis and origin for helix

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* empty

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-14 12:05:36 -08:00
f91ad4331f Bump @types/node from 20.14.9 to 22.10.6 in /packages/codemirror-lsp-client (#5041) 2025-01-14 17:36:46 +00:00
max
59103a2118 Remove Redundant Fillet Button State Test (#5009)
delete obsolete test
2025-01-14 12:09:29 -05:00
max
9737c2550a Hook up chamfer UI with AST-mod (#4694)
* button

* config

* hook up with ast

* cmd bar test

* button states fix and test

* little naming fix

* xState action to actor

* remove button state test updates

* fixture-based approach

* nightly

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Update src/lib/toolbar.ts

Co-authored-by: Frank Noirot <frank@zoo.dev>

---------

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
2025-01-14 12:08:32 -05:00
bf9d01a8dd Bump xstate from 5.17.4 to 5.19.2 (#5027) 2025-01-14 15:39:05 +00:00
702e322f90 ci: Add yarn test of packages/codemirror-lang-kcl (#5035)
* ci: Add yarn test of packages/codemirror-lang-kcl

* Fix CI error running tests

* Fix postcss config error
2025-01-14 09:30:08 -05:00
e82830754d turns on helix from edge (#5036)
* updates for new lib

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* autocomplete

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* bump version

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* bump all the things

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* new samples

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-01-13 23:34:43 +00:00
7806377a5a Disable auto-updater on non-versioned builds (#5042) 2025-01-13 17:40:51 -05:00
859afa2fd8 Upgrade all wasm-bindgen dependencies together (#5037) 2025-01-13 13:24:23 -08:00
0a5f3093fc Fix Cargo.lock to not have changes (#5034) 2025-01-13 15:38:24 -05:00
b65f7939f6 Fix artifact types to be more accurate (#5022) 2025-01-13 15:02:55 -05:00
c35dea5e07 Bump syn from 2.0.95 to 2.0.96 in /src/wasm-lib (#5015)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.95 to 2.0.96.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.95...2.0.96)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-13 10:04:30 -08:00
fc66d4745f Bump handlebars from 6.2.0 to 6.3.0 in /src/wasm-lib (#5012)
Bumps [handlebars](https://github.com/sunng87/handlebars-rust) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/sunng87/handlebars-rust/releases)
- [Changelog](https://github.com/sunng87/handlebars-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sunng87/handlebars-rust/compare/v6.2.0...v6.3.0)

---
updated-dependencies:
- dependency-name: handlebars
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-13 13:03:34 -05:00
b313d26c2a Bump @lezer/generator from 1.7.1 to 1.7.2 (#5018)
Bumps [@lezer/generator](https://github.com/lezer-parser/generator) from 1.7.1 to 1.7.2.
- [Changelog](https://github.com/lezer-parser/generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lezer-parser/generator/compare/1.7.1...1.7.2)

---
updated-dependencies:
- dependency-name: "@lezer/generator"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-13 11:48:13 -05:00
00b94ead62 Add packages to Dependabot updates (#5024) 2025-01-13 11:29:00 -05:00
0531ea1ce9 Change Dependabot PRs to always be made on Mondays (#5025) 2025-01-13 15:30:33 +00:00
5f9a4887c1 Developer workflow: added auto generated workspace file from vitest extension in vscode (#4997)
* chore: added auto generated workspace file from vitest extension in vscode

* fix: auto fmt fixes
2025-01-13 09:57:12 -05:00
da7dfa16d8 Fix lost lints and add new ones (#5011)
* Add eslint-plugin-jsx-a11y dependency

* Add jsx-a11y lint

* Add eslint-plugin-react-hooks dependency

* Add react hooks lints

* Ignore new react hooks lint in tests

* Add eslint-plugin-testing-library dependency

* Add testing-library lint

* Fix yarn lint to use all files recursively
2025-01-13 09:30:14 -05:00
41 changed files with 816 additions and 267 deletions

View File

@ -6,16 +6,24 @@
"plugins": [ "plugins": [
"css-modules", "css-modules",
"jest", "jest",
"jsx-a11y",
"react", "react",
"react-hooks",
"suggest-no-throw", "suggest-no-throw",
"testing-library",
"@typescript-eslint" "@typescript-eslint"
], ],
"extends": [ "extends": [
"plugin:css-modules/recommended" "plugin:css-modules/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended"
], ],
"rules": { "rules": {
"@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error", "@typescript-eslint/no-misused-promises": "error",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"no-restricted-globals": [ "no-restricted-globals": [
"error", "error",
{ {
@ -33,6 +41,9 @@
"overrides": [ "overrides": [
{ {
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure "files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
"extends": [
"plugin:testing-library/react"
],
"rules": { "rules": {
"suggest-no-throw/suggest-no-throw": "off", "suggest-no-throw/suggest-no-throw": "off",
"testing-library/prefer-screen-queries": "off", "testing-library/prefer-screen-queries": "off",
@ -41,6 +52,9 @@
}, },
{ {
"files": ["src/**/*.test.ts"], "files": ["src/**/*.test.ts"],
"extends": [
"plugin:testing-library/react"
],
"rules": { "rules": {
"suggest-no-throw/suggest-no-throw": "off", "suggest-no-throw/suggest-no-throw": "off",
} }

View File

@ -6,23 +6,29 @@
version: 2 version: 2
updates: updates:
- package-ecosystem: 'npm' # See documentation for possible values - package-ecosystem: 'npm' # See documentation for possible values
directory: '/' # Location of package manifests directories:
- '/'
- '/packages/codemirror-lang-kcl/'
- '/packages/codemirror-lsp-client/'
schedule: schedule:
interval: 'weekly' interval: weekly
day: monday
reviewers: reviewers:
- franknoirot - franknoirot
- irev-dev - irev-dev
- package-ecosystem: 'github-actions' # See documentation for possible values - package-ecosystem: 'github-actions' # See documentation for possible values
directory: '/' # Location of package manifests directory: '/' # Location of package manifests
schedule: schedule:
interval: 'weekly' interval: weekly
day: monday
reviewers: reviewers:
- adamchalmers - adamchalmers
- jessfraz - jessfraz
- package-ecosystem: 'cargo' # See documentation for possible values - package-ecosystem: 'cargo' # See documentation for possible values
directory: '/src/wasm-lib/' # Location of package manifests directory: '/src/wasm-lib/' # Location of package manifests
schedule: schedule:
interval: 'weekly' interval: weekly
day: monday
reviewers: reviewers:
- adamchalmers - adamchalmers
- jessfraz - jessfraz
@ -30,3 +36,6 @@ updates:
serde-dependencies: serde-dependencies:
patterns: patterns:
- "serde*" - "serde*"
wasm-bindgen-deps:
patterns:
- "wasm-bindgen*"

View File

@ -0,0 +1,32 @@
name: CodeMirror Lang KCL
on:
pull_request:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
yarn-unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
working-directory: packages/codemirror-lang-kcl
- run: yarn tsc
working-directory: packages/codemirror-lang-kcl
- name: run unit tests
run: yarn test
working-directory: packages/codemirror-lang-kcl

File diff suppressed because one or more lines are too long

View File

@ -75843,7 +75843,6 @@
"required": [ "required": [
"angleStart", "angleStart",
"axis", "axis",
"length",
"radius", "radius",
"revolutions" "revolutions"
], ],
@ -75864,9 +75863,10 @@
"type": "boolean" "type": "boolean"
}, },
"length": { "length": {
"description": "Length of the helix.", "description": "Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used.",
"type": "number", "type": "number",
"format": "double" "format": "double",
"nullable": true
}, },
"radius": { "radius": {
"description": "Radius of the helix.", "description": "Radius of the helix.",
@ -76962,7 +76962,8 @@
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"// Create a helix around the Z axis.\nhelixPath = helix({\n angleStart = 0,\n ccw = true,\n revolutions = 16,\n length = 10,\n radius = 5,\n axis = 'Z'\n})\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn('YZ')\n |> circle({ center = [0, 0], radius = 1 }, %)\n// |> sweep({ path = helixPath }, %)", "// Create a helix around the Z axis.\nhelixPath = helix({\n angleStart = 0,\n ccw = true,\n revolutions = 16,\n length = 10,\n radius = 5,\n axis = 'Z'\n})\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn('YZ')\n |> circle({ center = [0, 0], radius = 1 }, %)\n// |> sweep({ path = helixPath }, %)",
"" "// Create a helix around an edge.\nhelper001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 10], %, $edge001)\n\nhelixPath = helix({\n angleStart = 0,\n ccw = true,\n revolutions = 16,\n length = 10,\n radius = 5,\n axis = edge001\n})\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn('XY')\n |> circle({ center = [0, 0], radius = 1 }, %)\n// |> sweep({ path = helixPath }, %)",
"// Create a helix around a custom axis.\nhelixPath = helix({\n angleStart = 0,\n ccw = true,\n revolutions = 16,\n length = 10,\n radius = 5,\n axis = {\n custom = {\n axis = [0, 0, 1.0],\n origin = [0, 0.25, 0]\n }\n }\n})\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn('XY')\n |> circle({ center = [0, 0], radius = 1 }, %)\n// |> sweep({ path = helixPath }, %)"
] ]
}, },
{ {

View File

@ -19,7 +19,7 @@ Data for a helix.
| `revolutions` |`number`| Number of revolutions. | No | | `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No | | `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No | | `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
| `length` |`number`| Length of the helix. | No | | `length` |`number`| Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. | No |
| `radius` |`number`| Radius of the helix. | No | | `radius` |`number`| Radius of the helix. | No |
| `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No | | `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No |

View File

@ -121,18 +121,23 @@ export class AuthenticatedTronApp {
export const fixtures = { export const fixtures = {
cmdBar: async ({ page }: { page: Page }, use: any) => { cmdBar: async ({ page }: { page: Page }, use: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
await use(new CmdBarFixture(page)) await use(new CmdBarFixture(page))
}, },
editor: async ({ page }: { page: Page }, use: any) => { editor: async ({ page }: { page: Page }, use: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
await use(new EditorFixture(page)) await use(new EditorFixture(page))
}, },
toolbar: async ({ page }: { page: Page }, use: any) => { toolbar: async ({ page }: { page: Page }, use: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
await use(new ToolbarFixture(page)) await use(new ToolbarFixture(page))
}, },
scene: async ({ page }: { page: Page }, use: any) => { scene: async ({ page }: { page: Page }, use: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
await use(new SceneFixture(page)) await use(new SceneFixture(page))
}, },
homePage: async ({ page }: { page: Page }, use: any) => { homePage: async ({ page }: { page: Page }, use: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
await use(new HomePageFixture(page)) await use(new HomePageFixture(page))
}, },
} }

View File

@ -15,6 +15,7 @@ export class ToolbarFixture {
extrudeButton!: Locator extrudeButton!: Locator
loftButton!: Locator loftButton!: Locator
sweepButton!: Locator sweepButton!: Locator
chamferButton!: Locator
shellButton!: Locator shellButton!: Locator
offsetPlaneButton!: Locator offsetPlaneButton!: Locator
startSketchBtn!: Locator startSketchBtn!: Locator
@ -42,6 +43,7 @@ export class ToolbarFixture {
this.extrudeButton = page.getByTestId('extrude') this.extrudeButton = page.getByTestId('extrude')
this.loftButton = page.getByTestId('loft') this.loftButton = page.getByTestId('loft')
this.sweepButton = page.getByTestId('sweep') this.sweepButton = page.getByTestId('sweep')
this.chamferButton = page.getByTestId('chamfer3d')
this.shellButton = page.getByTestId('shell') this.shellButton = page.getByTestId('shell')
this.offsetPlaneButton = page.getByTestId('plane-offset') this.offsetPlaneButton = page.getByTestId('plane-offset')
this.startSketchBtn = page.getByTestId('sketch') this.startSketchBtn = page.getByTestId('sketch')

View File

@ -1032,6 +1032,222 @@ sketch002 = startSketchOn('XZ')
}) })
}) })
test(`Chamfer point-and-click`, async ({
context,
page,
homePage,
scene,
editor,
toolbar,
cmdBar,
}) => {
// TODO: fix this test on windows after the electron migration
test.skip(process.platform === 'win32', 'Skip on windows')
// Code samples
const initialCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-12, -6], %)
|> line([0, 12], %)
|> line([24, 0], %)
|> line([0, -12], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-12, sketch001)
`
const firstChamferDeclaration = 'chamfer({ length = 5, tags = [seg01] }, %)'
const secondChamferDeclaration =
'chamfer({ length = 5, tags = [getOppositeEdge(seg01)] }, %)'
// Locators
const firstEdgeLocation = { x: 600, y: 193 }
const secondEdgeLocation = { x: 600, y: 383 }
const bodyLocation = { x: 630, y: 290 }
const [clickOnFirstEdge] = scene.makeMouseHelpers(
firstEdgeLocation.x,
firstEdgeLocation.y
)
const [clickOnSecondEdge] = scene.makeMouseHelpers(
secondEdgeLocation.x,
secondEdgeLocation.y
)
// Colors
const edgeColorWhite: [number, number, number] = [248, 248, 248]
const edgeColorYellow: [number, number, number] = [251, 251, 40] // Mac:B=67 Ubuntu:B=12
const bodyColor: [number, number, number] = [155, 155, 155]
const chamferColor: [number, number, number] = [168, 168, 168]
const backgroundColor: [number, number, number] = [30, 30, 30]
const lowTolerance = 20
const highTolerance = 40
// Setup
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await test.step(`Verify scene is loaded`, async () => {
// verify modeling scene is loaded
await scene.expectPixelColor(
backgroundColor,
secondEdgeLocation,
lowTolerance
)
// wait for stream to load
await scene.expectPixelColor(bodyColor, bodyLocation, highTolerance)
})
// Test 1: Command bar flow with preselected edges
await test.step(`Select first edge`, async () => {
await scene.expectPixelColor(
edgeColorWhite,
firstEdgeLocation,
lowTolerance
)
await clickOnFirstEdge()
await scene.expectPixelColor(
edgeColorYellow,
firstEdgeLocation,
highTolerance // Ubuntu color mismatch can require high tolerance
)
})
await test.step(`Apply chamfer to the preselected edge`, async () => {
await toolbar.chamferButton.click()
await cmdBar.expectState({
commandName: 'Chamfer',
highlightedHeaderArg: 'selection',
currentArgKey: 'selection',
currentArgValue: '',
headerArguments: {
Selection: '',
Length: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({
commandName: 'Chamfer',
highlightedHeaderArg: 'length',
currentArgKey: 'length',
currentArgValue: '5',
headerArguments: {
Selection: '1 face',
Length: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({
commandName: 'Chamfer',
headerArguments: {
Selection: '1 face',
Length: '5',
},
stage: 'review',
})
await cmdBar.progressCmdBar()
})
await test.step(`Confirm code is added to the editor`, async () => {
await editor.expectEditor.toContain(firstChamferDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: ['|>chamfer({length=5,tags=[seg01]},%)'],
highlightedCode: '',
})
})
await test.step(`Confirm scene has changed`, async () => {
await scene.expectPixelColor(chamferColor, firstEdgeLocation, lowTolerance)
})
// Test 2: Command bar flow without preselected edges
await test.step(`Open chamfer UI without selecting edges`, async () => {
await toolbar.chamferButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'selection',
currentArgValue: '',
headerArguments: {
Selection: '',
Length: '',
},
highlightedHeaderArg: 'selection',
commandName: 'Chamfer',
})
})
await test.step(`Select second edge`, async () => {
await scene.expectPixelColor(
edgeColorWhite,
secondEdgeLocation,
lowTolerance
)
await clickOnSecondEdge()
await scene.expectPixelColor(
edgeColorYellow,
secondEdgeLocation,
highTolerance // Ubuntu color mismatch can require high tolerance
)
})
await test.step(`Apply chamfer to the second edge`, async () => {
await cmdBar.expectState({
commandName: 'Chamfer',
highlightedHeaderArg: 'selection',
currentArgKey: 'selection',
currentArgValue: '',
headerArguments: {
Selection: '',
Length: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({
commandName: 'Chamfer',
highlightedHeaderArg: 'length',
currentArgKey: 'length',
currentArgValue: '5',
headerArguments: {
Selection: '1 sweepEdge',
Length: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({
commandName: 'Chamfer',
headerArguments: {
Selection: '1 sweepEdge',
Length: '5',
},
stage: 'review',
})
await cmdBar.progressCmdBar()
})
await test.step(`Confirm code is added to the editor`, async () => {
await editor.expectEditor.toContain(secondChamferDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: ['length=5,'],
highlightedCode: '',
})
})
await test.step(`Confirm scene has changed`, async () => {
await scene.expectPixelColor(
backgroundColor,
secondEdgeLocation,
lowTolerance
)
})
})
const shellPointAndClickCapCases = [ const shellPointAndClickCapCases = [
{ shouldPreselect: true }, { shouldPreselect: true },
{ shouldPreselect: false }, { shouldPreselect: false },

View File

@ -906,53 +906,6 @@ test.describe('Testing selections', () => {
).not.toBeDisabled() ).not.toBeDisabled()
}) })
test('Fillet button states test', async ({ page, homePage }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
|> startProfileAt([-5, -5], %)
|> line([0, 10], %)
|> line([10, 0], %)
|> line([0, -10], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)`
)
})
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
const selectSegment = () => page.getByText(`line([10, 0], %)`).click()
const selectClose = () => page.getByText(`close(%)`).click()
const clickEmpty = () => page.mouse.click(950, 100)
// Now that we don't disable toolbar buttons based on selection,
// but rather based on a "selection" step in the command palette,
// the fillet button should always be enabled with a good network connection.
// I'm not sure if this test is actually useful anymore.
await selectSegment()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
await clickEmpty()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
// test fillet button with the body in the scene
const codeToAdd = `${await u.codeLocator.allInnerTexts()}
extrude001 = extrude(10, sketch001)`
await u.codeLocator.clear()
await u.codeLocator.fill(codeToAdd)
await selectSegment()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
await selectClose()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
await clickEmpty()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
})
const removeAfterFirstParenthesis = (inputString: string) => { const removeAfterFirstParenthesis = (inputString: string) => {
const index = inputString.indexOf('(') const index = inputString.indexOf('(')
if (index !== -1) { if (index !== -1) {

View File

@ -65,7 +65,7 @@
"vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-protocol": "^3.17.5",
"vscode-uri": "^3.0.8", "vscode-uri": "^3.0.8",
"web-vitals": "^3.5.2", "web-vitals": "^3.5.2",
"xstate": "^5.17.4", "xstate": "^5.19.2",
"yargs": "^17.7.2" "yargs": "^17.7.2"
}, },
"scripts": { "scripts": {
@ -91,8 +91,8 @@
"build:wasm": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings && cd ../.. && yarn isomorphic-copy-wasm && yarn fmt", "build:wasm": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings && cd ../.. && yarn isomorphic-copy-wasm && yarn fmt",
"remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\" || echo \"sed for both mac and linux\"", "remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\" || echo \"sed for both mac and linux\"",
"wasm-prep": "rimraf src/wasm-lib/pkg && mkdirp src/wasm-lib/pkg && rimraf src/wasm-lib/kcl/bindings", "wasm-prep": "rimraf src/wasm-lib/pkg && mkdirp src/wasm-lib/pkg && rimraf src/wasm-lib/kcl/bindings",
"lint-fix": "eslint --fix src/**/*.ts src/**/*.tsx e2e/**/*.ts packages/codemirror-lsp-client/src/**/*.ts", "lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src",
"lint": "eslint --max-warnings 0 src/**/*.ts src/**/*.tsx e2e/**/*.ts packages/codemirror-lsp-client/src/**/*.ts", "lint": "eslint --max-warnings 0 --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src",
"files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json", "files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
"files:set-notes": "./scripts/set-files-notes.sh", "files:set-notes": "./scripts/set-files-notes.sh",
"files:flip-to-nightly": "./scripts/flip-files-to-nightly.sh", "files:flip-to-nightly": "./scripts/flip-files-to-nightly.sh",
@ -149,7 +149,7 @@
"@electron-forge/plugin-vite": "7.4.0", "@electron-forge/plugin-vite": "7.4.0",
"@electron/fuses": "1.8.0", "@electron/fuses": "1.8.0",
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@lezer/generator": "^1.7.1", "@lezer/generator": "^1.7.2",
"@nabla/vite-plugin-eslint": "^2.0.5", "@nabla/vite-plugin-eslint": "^2.0.5",
"@playwright/test": "^1.49.0", "@playwright/test": "^1.49.0",
"@testing-library/jest-dom": "^5.14.1", "@testing-library/jest-dom": "^5.14.1",
@ -183,8 +183,11 @@
"eslint-plugin-css-modules": "^2.12.0", "eslint-plugin-css-modules": "^2.12.0",
"eslint-plugin-import": "^2.30.0", "eslint-plugin-import": "^2.30.0",
"eslint-plugin-jest": "^28.10.0", "eslint-plugin-jest": "^28.10.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.3", "eslint-plugin-react": "^7.37.3",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-suggest-no-throw": "^1.0.0", "eslint-plugin-suggest-no-throw": "^1.0.0",
"eslint-plugin-testing-library": "^7.1.1",
"happy-dom": "^16.3.0", "happy-dom": "^16.3.0",
"http-server": "^14.1.1", "http-server": "^14.1.1",
"husky": "^9.1.5", "husky": "^9.1.5",
@ -198,7 +201,7 @@
"setimmediate": "^1.0.5", "setimmediate": "^1.0.5",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"ts-node": "^10.0.0", "ts-node": "^10.0.0",
"typescript": "^5.7.2", "typescript": "^5.7.3",
"typescript-eslint": "^8.19.1", "typescript-eslint": "^8.19.1",
"vite": "^5.4.6", "vite": "^5.4.6",
"vite-plugin-package-version": "^1.1.0", "vite-plugin-package-version": "^1.1.0",

View File

@ -4,4 +4,5 @@ dist
tsconfig.tsbuildinfo tsconfig.tsbuildinfo
*.d.ts *.d.ts
*.js *.js
!postcss.config.js
!rollup.config.js !rollup.config.js

View File

@ -28,6 +28,7 @@
"@rollup/plugin-typescript": "^12.1.2", "@rollup/plugin-typescript": "^12.1.2",
"rollup": "^4.29.1", "rollup": "^4.29.1",
"rollup-plugin-dts": "^6.1.1", "rollup-plugin-dts": "^6.1.1",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^2.1.8" "vitest": "^2.1.8"
}, },
"files": [ "files": [

View File

@ -0,0 +1 @@
// This is here to prevent using the one in the root of the project.

View File

@ -398,7 +398,7 @@ check-error@^2.1.1:
resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc"
integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==
debug@^4.3.7: debug@^4.1.1, debug@^4.3.7:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
@ -471,6 +471,11 @@ function-bind@^1.1.2:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
globrex@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
hasown@^2.0.2: hasown@^2.0.2:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
@ -647,6 +652,11 @@ tinyspy@^3.0.2:
resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a"
integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==
tsconfck@^3.0.3:
version "3.1.4"
resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.4.tgz#de01a15334962e2feb526824339b51be26712229"
integrity sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==
typescript@^5.7.2: typescript@^5.7.2:
version "5.7.2" version "5.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
@ -663,6 +673,15 @@ vite-node@2.1.8:
pathe "^1.1.2" pathe "^1.1.2"
vite "^5.0.0" vite "^5.0.0"
vite-tsconfig-paths@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz#321f02e4b736a90ff62f9086467faf4e2da857a9"
integrity sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==
dependencies:
debug "^4.1.1"
globrex "^0.1.2"
tsconfck "^3.0.3"
vite@^5.0.0: vite@^5.0.0:
version "5.4.11" version "5.4.11"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"

View File

@ -29,7 +29,7 @@
"vscode-uri": "^3.0.8" "vscode-uri": "^3.0.8"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.14.9", "@types/node": "^22.10.6",
"ts-node": "^10.9.2" "ts-node": "^10.9.2"
} }
} }

View File

@ -109,12 +109,12 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
"@types/node@^20.14.9": "@types/node@^22.10.6":
version "20.14.9" version "22.10.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.9.tgz#12e8e765ab27f8c421a1820c99f5f313a933b420" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.6.tgz#5c6795e71635876039f853cbccd59f523d9e4239"
integrity sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg== integrity sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==
dependencies: dependencies:
undici-types "~5.26.4" undici-types "~6.20.0"
acorn-walk@^8.1.1: acorn-walk@^8.1.1:
version "8.3.3" version "8.3.3"
@ -187,10 +187,10 @@ typescript@^5.7.2:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==
undici-types@~5.26.4: undici-types@~6.20.0:
version "5.26.5" version "6.20.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
v8-compile-cache-lib@^3.0.1: v8-compile-cache-lib@^3.0.1:
version "3.0.1" version "3.0.1"

View File

@ -1,21 +1,21 @@
[ [
{ {
"file": "80-20-rail.kcl", "file": "main.kcl",
"title": "80/20 Rail", "title": "80/20 Rail",
"description": "An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position" "description": "An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position"
}, },
{ {
"file": "a-parametric-bearing-pillow-block.kcl", "file": "main.kcl",
"title": "A Parametric Bearing Pillow Block", "title": "A Parametric Bearing Pillow Block",
"description": "A bearing pillow block, also known as a plummer block or pillow block bearing, is a pedestal used to provide support for a rotating shaft with the help of compatible bearings and various accessories. Housing a bearing, the pillow block provides a secure and stable foundation that allows the shaft to rotate smoothly within its machinery setup. These components are essential in a wide range of mechanical systems and machinery, playing a key role in reducing friction and supporting radial and axial loads." "description": "A bearing pillow block, also known as a plummer block or pillow block bearing, is a pedestal used to provide support for a rotating shaft with the help of compatible bearings and various accessories. Housing a bearing, the pillow block provides a secure and stable foundation that allows the shaft to rotate smoothly within its machinery setup. These components are essential in a wide range of mechanical systems and machinery, playing a key role in reducing friction and supporting radial and axial loads."
}, },
{ {
"file": "ball-bearing.kcl", "file": "main.kcl",
"title": "Ball Bearing", "title": "Ball Bearing",
"description": "A ball bearing is a type of rolling-element bearing that uses balls to maintain the separation between the bearing races. The primary purpose of a ball bearing is to reduce rotational friction and support radial and axial loads." "description": "A ball bearing is a type of rolling-element bearing that uses balls to maintain the separation between the bearing races. The primary purpose of a ball bearing is to reduce rotational friction and support radial and axial loads."
}, },
{ {
"file": "bracket.kcl", "file": "main.kcl",
"title": "Shelf Bracket", "title": "Shelf Bracket",
"description": "This is a bracket that holds a shelf. It is made of aluminum and is designed to hold a force of 300 lbs. The bracket is 6 inches wide and the force is applied at the end of the shelf, 12 inches from the wall. The bracket has a factor of safety of 1.2. The legs of the bracket are 5 inches and 2 inches long. The thickness of the bracket is calculated from the constraints provided." "description": "This is a bracket that holds a shelf. It is made of aluminum and is designed to hold a force of 300 lbs. The bracket is 6 inches wide and the force is applied at the end of the shelf, 12 inches from the wall. The bracket has a factor of safety of 1.2. The legs of the bracket are 5 inches and 2 inches long. The thickness of the bracket is calculated from the constraints provided."
}, },
@ -25,148 +25,128 @@
"description": "Brake calipers are used to squeeze the brake pads against the rotor, causing larger and larger amounts of friction depending on how hard the brakes are pressed." "description": "Brake calipers are used to squeeze the brake pads against the rotor, causing larger and larger amounts of friction depending on how hard the brakes are pressed."
}, },
{ {
"file": "car-wheel.kcl", "file": "main.kcl",
"title": "Car Wheel",
"description": "A sports car wheel with a circular lug pattern and spokes."
},
{
"file": "car-wheel-assembly.kcl",
"title": "Car Wheel Assembly",
"description": "A car wheel assembly with a rotor, tire, and lug nuts."
},
{
"file": "dodecahedron.kcl",
"title": "Hollow Dodecahedron", "title": "Hollow Dodecahedron",
"description": "A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the individual faces of the dodecahedron and extruding inwards." "description": "A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the individual faces of the dodecahedron and extruding inwards."
}, },
{ {
"file": "enclosure.kcl", "file": "main.kcl",
"title": "Enclosure", "title": "Enclosure",
"description": "An enclosure body and sealing lid for storing items" "description": "An enclosure body and sealing lid for storing items"
}, },
{ {
"file": "flange-with-patterns.kcl", "file": "main.kcl",
"title": "Flange", "title": "Flange",
"description": "A flange is a flat rim, collar, or rib, typically forged or cast, that is used to strengthen an object, guide it, or attach it to another object. Flanges are known for their use in various applications, including piping, plumbing, and mechanical engineering, among others." "description": "A flange is a flat rim, collar, or rib, typically forged or cast, that is used to strengthen an object, guide it, or attach it to another object. Flanges are known for their use in various applications, including piping, plumbing, and mechanical engineering, among others."
}, },
{ {
"file": "flange-xy.kcl", "file": "main.kcl",
"title": "Flange with XY coordinates", "title": "Flange with XY coordinates",
"description": "A flange is a flat rim, collar, or rib, typically forged or cast, that is used to strengthen an object, guide it, or attach it to another object. Flanges are known for their use in various applications, including piping, plumbing, and mechanical engineering, among others." "description": "A flange is a flat rim, collar, or rib, typically forged or cast, that is used to strengthen an object, guide it, or attach it to another object. Flanges are known for their use in various applications, including piping, plumbing, and mechanical engineering, among others."
}, },
{ {
"file": "focusrite-scarlett-mounting-bracket.kcl", "file": "main.kcl",
"title": "A mounting bracket for the Focusrite Scarlett Solo audio interface", "title": "A mounting bracket for the Focusrite Scarlett Solo audio interface",
"description": "This is a bracket that holds an audio device underneath a desk or shelf. The audio device has dimensions of 144mm wide, 80mm length and 45mm depth with fillets of 6mm. This mounting bracket is designed to be 3D printed with PLA material" "description": "This is a bracket that holds an audio device underneath a desk or shelf. The audio device has dimensions of 144mm wide, 80mm length and 45mm depth with fillets of 6mm. This mounting bracket is designed to be 3D printed with PLA material"
}, },
{ {
"file": "food-service-spatula.kcl", "file": "main.kcl",
"title": "Food Service Spatula", "title": "Food Service Spatula",
"description": "Use these spatulas for mixing, flipping, and scraping." "description": "Use these spatulas for mixing, flipping, and scraping."
}, },
{ {
"file": "french-press.kcl", "file": "main.kcl",
"title": "French Press", "title": "French Press",
"description": "A french press immersion coffee maker" "description": "A french press immersion coffee maker"
}, },
{ {
"file": "gear.kcl", "file": "main.kcl",
"title": "Spur Gear", "title": "Spur Gear",
"description": "A rotating machine part having cut teeth or, in the case of a cogwheel, inserted teeth (called cogs), which mesh with another toothed part to transmit torque. Geared devices can change the speed, torque, and direction of a power source. The two elements that define a gear are its circular shape and the teeth that are integrated into its outer edge, which are designed to fit into the teeth of another gear." "description": "A rotating machine part having cut teeth or, in the case of a cogwheel, inserted teeth (called cogs), which mesh with another toothed part to transmit torque. Geared devices can change the speed, torque, and direction of a power source. The two elements that define a gear are its circular shape and the teeth that are integrated into its outer edge, which are designed to fit into the teeth of another gear."
}, },
{ {
"file": "gear-rack.kcl", "file": "main.kcl",
"title": "100mm Gear Rack", "title": "100mm Gear Rack",
"description": "A flat bar or rail that is engraved with teeth along its length. These teeth are designed to mesh with the teeth of a gear, known as a pinion. When the pinion, a small cylindrical gear, rotates, its teeth engage with the teeth on the rack, causing the rack to move linearly. Conversely, linear motion applied to the rack will cause the pinion to rotate." "description": "A flat bar or rail that is engraved with teeth along its length. These teeth are designed to mesh with the teeth of a gear, known as a pinion. When the pinion, a small cylindrical gear, rotates, its teeth engage with the teeth on the rack, causing the rack to move linearly. Conversely, linear motion applied to the rack will cause the pinion to rotate."
}, },
{ {
"file": "hex-nut.kcl", "file": "main.kcl",
"title": "Hex nut", "title": "Hex nut",
"description": "A hex nut is a type of fastener with a threaded hole and a hexagonal outer shape, used in a wide variety of applications to secure parts together. The hexagonal shape allows for a greater torque to be applied with wrenches or tools, making it one of the most common nut types in hardware." "description": "A hex nut is a type of fastener with a threaded hole and a hexagonal outer shape, used in a wide variety of applications to secure parts together. The hexagonal shape allows for a greater torque to be applied with wrenches or tools, making it one of the most common nut types in hardware."
}, },
{ {
"file": "i-beam.kcl", "file": "main.kcl",
"title": "I-beam", "title": "I-beam",
"description": "A structural metal beam with an I shaped cross section. Often used in construction" "description": "A structural metal beam with an I shaped cross section. Often used in construction"
}, },
{ {
"file": "kitt.kcl", "file": "main.kcl",
"title": "Kitt", "title": "Kitt",
"description": "The beloved KittyCAD mascot in a voxelized style." "description": "The beloved KittyCAD mascot in a voxelized style."
}, },
{ {
"file": "lego.kcl", "file": "main.kcl",
"title": "Lego Brick", "title": "Lego Brick",
"description": "A standard Lego brick. This is a small, plastic construction block toy that can be interlocked with other blocks to build various structures, models, and figures. There are a lot of hacks used in this code." "description": "A standard Lego brick. This is a small, plastic construction block toy that can be interlocked with other blocks to build various structures, models, and figures. There are a lot of hacks used in this code."
}, },
{ {
"file": "lug-nut.kcl", "file": "main.kcl",
"title": "Lug Nut",
"description": "lug Nuts are essential components used to create secure connections, whether for electrical purposes, like terminating wires or grounding, or for mechanical purposes, such as providing mounting points or reinforcing structural joints."
},
{
"file": "mounting-plate.kcl",
"title": "Mounting Plate", "title": "Mounting Plate",
"description": "A flat piece of material, often metal or plastic, that serves as a support or base for attaching, securing, or mounting various types of equipment, devices, or components." "description": "A flat piece of material, often metal or plastic, that serves as a support or base for attaching, securing, or mounting various types of equipment, devices, or components."
}, },
{ {
"file": "multi-axis-robot.kcl", "file": "globals.kcl",
"title": "Robot Arm", "title": "Global constants for the multi-axis robot",
"description": "A 4 axis robotic arm for industrial use. These machines can be used for assembly, packaging, organization of goods, and quality inspection processes" "description": ""
}, },
{ {
"file": "pipe.kcl", "file": "main.kcl",
"title": "Pipe", "title": "Pipe",
"description": "A tubular section or hollow cylinder, usually but not necessarily of circular cross-section, used mainly to convey substances that can flow." "description": "A tubular section or hollow cylinder, usually but not necessarily of circular cross-section, used mainly to convey substances that can flow."
}, },
{ {
"file": "pipe-flange-assembly.kcl", "file": "main.kcl",
"title": "Pipe and Flange Assembly", "title": "Pipe and Flange Assembly",
"description": "A crucial component in various piping systems, designed to facilitate the connection, disconnection, and access to piping for inspection, cleaning, and modifications. This assembly combines pipes (long cylindrical conduits) with flanges (plate-like fittings) to create a secure yet detachable joint." "description": "A crucial component in various piping systems, designed to facilitate the connection, disconnection, and access to piping for inspection, cleaning, and modifications. This assembly combines pipes (long cylindrical conduits) with flanges (plate-like fittings) to create a secure yet detachable joint."
}, },
{ {
"file": "pipe-with-bend.kcl", "file": "main.kcl",
"title": "Pipe with bend", "title": "Pipe with bend",
"description": "A tubular section or hollow cylinder, usually but not necessarily of circular cross-section, used mainly to convey substances that can flow." "description": "A tubular section or hollow cylinder, usually but not necessarily of circular cross-section, used mainly to convey substances that can flow."
}, },
{ {
"file": "poopy-shoe.kcl", "file": "main.kcl",
"title": "Poopy Shoe", "title": "Poopy Shoe",
"description": "poop shute for bambu labs printer - optimized for printing." "description": "poop shute for bambu labs printer - optimized for printing."
}, },
{ {
"file": "router-template-cross-bar.kcl", "file": "main.kcl",
"title": "Router template for a cross bar", "title": "Router template for a cross bar",
"description": "A guide for routing a notch into a cross bar." "description": "A guide for routing a notch into a cross bar."
}, },
{ {
"file": "router-template-slate.kcl", "file": "main.kcl",
"title": "Router template for a slate", "title": "Router template for a slate",
"description": "A guide for routing a slate for a cross bar." "description": "A guide for routing a slate for a cross bar."
}, },
{ {
"file": "sheet-metal-bracket.kcl", "file": "main.kcl",
"title": "Sheet Metal Bracket", "title": "Sheet Metal Bracket",
"description": "A component typically made from flat sheet metal through various manufacturing processes such as bending, punching, cutting, and forming. These brackets are used to support, attach, or mount other hardware components, often providing a structural or functional base for assembly." "description": "A component typically made from flat sheet metal through various manufacturing processes such as bending, punching, cutting, and forming. These brackets are used to support, attach, or mount other hardware components, often providing a structural or functional base for assembly."
}, },
{ {
"file": "socket-head-cap-screw.kcl", "file": "main.kcl",
"title": "Socket Head Cap Screw", "title": "Socket Head Cap Screw",
"description": "This is for a #10-24 screw that is 1.00 inches long. A socket head cap screw is a type of fastener that is widely used in a variety of applications requiring a high strength fastening solution. It is characterized by its cylindrical head and internal hexagonal drive, which allows for tightening with an Allen wrench or hex key." "description": "This is for a #10-24 screw that is 1.00 inches long. A socket head cap screw is a type of fastener that is widely used in a variety of applications requiring a high strength fastening solution. It is characterized by its cylindrical head and internal hexagonal drive, which allows for tightening with an Allen wrench or hex key."
}, },
{ {
"file": "tire.kcl", "file": "antenna.kcl",
"title": "Tire", "title": "Antenna",
"description": "A tire is a critical component of a vehicle that provides the necessary traction and grip between the car and the road. It supports the vehicle's weight and absorbs shocks from road irregularities." "description": ""
}, },
{ {
"file": "washer.kcl", "file": "main.kcl",
"title": "Washer", "title": "Washer",
"description": "A small, typically disk-shaped component with a hole in the middle, used in a wide range of applications, primarily in conjunction with fasteners like bolts and screws. Washers distribute the load of a fastener across a broader area. This is especially important when the fastening surface is soft or uneven, as it helps to prevent damage to the surface and ensures the load is evenly distributed, reducing the risk of the fastener becoming loose over time." "description": "A small, typically disk-shaped component with a hole in the middle, used in a wide range of applications, primarily in conjunction with fasteners like bolts and screws. Washers distribute the load of a fastener across a broader area. This is especially important when the fastening surface is soft or uneven, as it helps to prevent damage to the surface and ensures the load is evenly distributed, reducing the risk of the fastener becoming loose over time."
},
{
"file": "wheel-rotor.kcl",
"title": "Wheel rotor",
"description": "A component of a disc brake system. It provides a surface for brake pads to press against, generating the friction needed to slow or stop the vehicle."
} }
] ]

View File

@ -148,6 +148,7 @@ function HelpMenuItem({
return ( return (
<li className="p-0 m-0"> <li className="p-0 m-0">
{as === 'a' ? ( {as === 'a' ? (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<a <a
{...(props as React.ComponentProps<'a'>)} {...(props as React.ComponentProps<'a'>)}
onClick={openExternalBrowserIfDesktop( onClick={openExternalBrowserIfDesktop(

View File

@ -18,6 +18,7 @@ export const KclEditorMenu = ({ children }: PropsWithChildren) => {
return ( return (
<Menu> <Menu>
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<div <div
className="relative" className="relative"
onClick={(e) => { onClick={(e) => {

View File

@ -313,6 +313,7 @@ export const Stream = () => {
} }
return ( return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div <div
ref={videoWrapperRef} ref={videoWrapperRef}
className="absolute inset-0 z-0" className="absolute inset-0 z-0"

View File

@ -705,7 +705,7 @@ describe('testing getArtifactsToUpdate', () => {
segIds: [], segIds: [],
id: expect.any(String), id: expect.any(String),
planeId: 'UUID-1', planeId: 'UUID-1',
sweepId: '', sweepId: undefined,
codeRef: { codeRef: {
pathToNode: [['body', '']], pathToNode: [['body', '']],
range: [37, 64, true], range: [37, 64, true],
@ -743,7 +743,7 @@ describe('testing getArtifactsToUpdate', () => {
type: 'segment', type: 'segment',
id: expect.any(String), id: expect.any(String),
pathId: expect.any(String), pathId: expect.any(String),
surfaceId: '', surfaceId: undefined,
edgeIds: [], edgeIds: [],
codeRef: { codeRef: {
range: [70, 86, true], range: [70, 86, true],
@ -770,7 +770,7 @@ describe('testing getArtifactsToUpdate', () => {
id: expect.any(String), id: expect.any(String),
consumedEdgeId: expect.any(String), consumedEdgeId: expect.any(String),
edgeIds: [], edgeIds: [],
surfaceId: '', surfaceId: undefined,
codeRef: { codeRef: {
range: [260, 299, true], range: [260, 299, true],
pathToNode: [['body', '']], pathToNode: [['body', '']],

View File

@ -37,7 +37,7 @@ export interface PathArtifact extends BaseArtifact {
type: 'path' type: 'path'
planeId: ArtifactId planeId: ArtifactId
segIds: Array<ArtifactId> segIds: Array<ArtifactId>
sweepId: ArtifactId sweepId?: ArtifactId
solid2dId?: ArtifactId solid2dId?: ArtifactId
codeRef: CodeRef codeRef: CodeRef
} }
@ -60,7 +60,7 @@ export interface PathArtifactRich extends BaseArtifact {
export interface SegmentArtifact extends BaseArtifact { export interface SegmentArtifact extends BaseArtifact {
type: 'segment' type: 'segment'
pathId: ArtifactId pathId: ArtifactId
surfaceId: ArtifactId surfaceId?: ArtifactId
edgeIds: Array<ArtifactId> edgeIds: Array<ArtifactId>
edgeCutId?: ArtifactId edgeCutId?: ArtifactId
codeRef: CodeRef codeRef: CodeRef
@ -68,7 +68,7 @@ export interface SegmentArtifact extends BaseArtifact {
interface SegmentArtifactRich extends BaseArtifact { interface SegmentArtifactRich extends BaseArtifact {
type: 'segment' type: 'segment'
path: PathArtifact path: PathArtifact
surf: WallArtifact surf?: WallArtifact
edges: Array<SweepEdge> edges: Array<SweepEdge>
edgeCut?: EdgeCut edgeCut?: EdgeCut
codeRef: CodeRef codeRef: CodeRef
@ -120,7 +120,7 @@ interface EdgeCut extends BaseArtifact {
subType: 'fillet' | 'chamfer' subType: 'fillet' | 'chamfer'
consumedEdgeId: ArtifactId consumedEdgeId: ArtifactId
edgeIds: Array<ArtifactId> edgeIds: Array<ArtifactId>
surfaceId: ArtifactId surfaceId?: ArtifactId
codeRef: CodeRef codeRef: CodeRef
} }
@ -308,7 +308,7 @@ export function getArtifactsToUpdate({
id, id,
segIds: [], segIds: [],
planeId: currentPlaneId, planeId: currentPlaneId,
sweepId: '', sweepId: undefined,
codeRef: { range, pathToNode }, codeRef: { range, pathToNode },
}, },
}) })
@ -343,7 +343,7 @@ export function getArtifactsToUpdate({
type: 'segment', type: 'segment',
id, id,
pathId, pathId,
surfaceId: '', surfaceId: undefined,
edgeIds: [], edgeIds: [],
codeRef: { range, pathToNode }, codeRef: { range, pathToNode },
}, },
@ -450,7 +450,8 @@ export function getArtifactsToUpdate({
id: face_id, id: face_id,
segId: curve_id, segId: curve_id,
edgeCutEdgeIds: [], edgeCutEdgeIds: [],
sweepId: path.sweepId, // TODO: Add explicit check for sweepId. Should never use ''
sweepId: path.sweepId ?? '',
pathIds: [], pathIds: [],
}, },
}) })
@ -458,15 +459,17 @@ export function getArtifactsToUpdate({
id: curve_id, id: curve_id,
artifact: { ...seg, surfaceId: face_id }, artifact: { ...seg, surfaceId: face_id },
}) })
const sweep = getArtifact(path.sweepId) if (path.sweepId) {
if (sweep?.type === 'sweep') { const sweep = getArtifact(path.sweepId)
returnArr.push({ if (sweep?.type === 'sweep') {
id: path.sweepId, returnArr.push({
artifact: { id: path.sweepId,
...sweep, artifact: {
surfaceIds: [face_id], ...sweep,
}, surfaceIds: [face_id],
}) },
})
}
} }
} }
} }
@ -483,19 +486,22 @@ export function getArtifactsToUpdate({
id: face_id, id: face_id,
subType: cap === 'bottom' ? 'start' : 'end', subType: cap === 'bottom' ? 'start' : 'end',
edgeCutEdgeIds: [], edgeCutEdgeIds: [],
sweepId: path.sweepId, // TODO: Add explicit check for sweepId. Should never use ''
sweepId: path.sweepId ?? '',
pathIds: [], pathIds: [],
}, },
}) })
const sweep = getArtifact(path.sweepId) if (path.sweepId) {
if (sweep?.type !== 'sweep') return const sweep = getArtifact(path.sweepId)
returnArr.push({ if (sweep?.type !== 'sweep') return
id: path.sweepId, returnArr.push({
artifact: { id: path.sweepId,
...sweep, artifact: {
surfaceIds: [face_id], ...sweep,
}, surfaceIds: [face_id],
}) },
})
}
} }
} }
}) })
@ -533,7 +539,8 @@ export function getArtifactsToUpdate({
? 'adjacent' ? 'adjacent'
: 'opposite', : 'opposite',
segId: cmd.edge_id, segId: cmd.edge_id,
sweepId: path.sweepId, // TODO: Add explicit check for sweepId. Should never use ''
sweepId: path.sweepId ?? '',
}, },
}, },
{ {
@ -544,7 +551,7 @@ export function getArtifactsToUpdate({
}, },
}, },
{ {
id: path.sweepId, id: sweep.id,
artifact: { artifact: {
...sweep, ...sweep,
edgeIds: [response.data.modeling_response.data.edge], edgeIds: [response.data.modeling_response.data.edge],
@ -560,7 +567,7 @@ export function getArtifactsToUpdate({
subType: cmd.cut_type, subType: cmd.cut_type,
consumedEdgeId: cmd.edge_id, consumedEdgeId: cmd.edge_id,
edgeIds: [], edgeIds: [],
surfaceId: '', surfaceId: undefined,
codeRef: { range, pathToNode }, codeRef: { range, pathToNode },
}, },
}) })
@ -722,10 +729,12 @@ export function expandSegment(
{ key: segment.pathId, types: ['path'] }, { key: segment.pathId, types: ['path'] },
artifactGraph artifactGraph
) )
const surf = getArtifactOfTypes( const surf = segment.surfaceId
{ key: segment.surfaceId, types: ['wall'] }, ? getArtifactOfTypes(
artifactGraph { key: segment.surfaceId, types: ['wall'] },
) artifactGraph
)
: undefined
const edges = getArtifactsOfTypes( const edges = getArtifactsOfTypes(
{ keys: segment.edgeIds, types: ['sweepEdge'] }, { keys: segment.edgeIds, types: ['sweepEdge'] },
artifactGraph artifactGraph
@ -842,6 +851,7 @@ export function getSweepFromSuspectedSweepSurface(
artifactGraph artifactGraph
) )
if (err(path)) return path if (err(path)) return path
if (!path.sweepId) return new Error('Path does not have a sweepId')
return getArtifactOfTypes( return getArtifactOfTypes(
{ key: path.sweepId, types: ['sweep'] }, { key: path.sweepId, types: ['sweep'] },
artifactGraph artifactGraph
@ -859,6 +869,7 @@ export function getSweepFromSuspectedPath(
): SweepArtifact | Error { ): SweepArtifact | Error {
const path = getArtifactOfTypes({ key: id, types: ['path'] }, artifactGraph) const path = getArtifactOfTypes({ key: id, types: ['path'] }, artifactGraph)
if (err(path)) return path if (err(path)) return path
if (!path.sweepId) return new Error('Path does not have a sweepId')
return getArtifactOfTypes( return getArtifactOfTypes(
{ key: path.sweepId, types: ['sweep'] }, { key: path.sweepId, types: ['sweep'] },
artifactGraph artifactGraph

View File

@ -56,10 +56,13 @@ export type ModelingCommandSchema = {
edge: Selections edge: Selections
} }
Fillet: { Fillet: {
// todo
selection: Selections selection: Selections
radius: KclCommandValue radius: KclCommandValue
} }
Chamfer: {
selection: Selections
length: KclCommandValue
}
'Offset plane': { 'Offset plane': {
plane: Selections plane: Selections
distance: KclCommandValue distance: KclCommandValue
@ -429,7 +432,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
}, },
Fillet: { Fillet: {
description: 'Fillet edge', description: 'Fillet edge',
icon: 'fillet', icon: 'fillet3d',
status: 'development', status: 'development',
needsReview: true, needsReview: true,
args: { args: {
@ -449,6 +452,28 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
}, },
}, },
}, },
Chamfer: {
description: 'Chamfer edge',
icon: 'chamfer3d',
status: 'development',
needsReview: true,
args: {
selection: {
inputType: 'selection',
selectionTypes: ['segment', 'sweepEdge', 'edgeCutEdge'],
multiple: true,
required: true,
skip: false,
warningMessage:
'Chamfers cannot touch other chamfers yet. This is under development.',
},
length: {
inputType: 'kcl',
defaultValue: KCL_DEFAULT_LENGTH,
required: true,
},
},
},
'Constrain length': { 'Constrain length': {
description: 'Constrain the length of one or more segments.', description: 'Constrain the length of one or more segments.',
icon: 'dimension', icon: 'dimension',

View File

@ -137,7 +137,7 @@ See later source ranges for more context. about the sweep`,
{ key: artifact.pathId, types: ['path'] }, { key: artifact.pathId, types: ['path'] },
artifactGraph artifactGraph
) )
if (!err(path)) { if (!err(path) && path.sweepId) {
const sweep = getArtifactOfTypes( const sweep = getArtifactOfTypes(
{ key: path.sweepId, types: ['sweep'] }, { key: path.sweepId, types: ['sweep'] },
artifactGraph artifactGraph

View File

@ -670,6 +670,7 @@ export function codeToIdSelections(
} }
} }
if (type === 'extrude-wall' && entry.artifact.type === 'segment') { if (type === 'extrude-wall' && entry.artifact.type === 'segment') {
if (!entry.artifact.surfaceId) return
const wall = engineCommandManager.artifactGraph.get( const wall = engineCommandManager.artifactGraph.get(
entry.artifact.surfaceId entry.artifact.surfaceId
) )
@ -714,6 +715,7 @@ export function codeToIdSelections(
(type === 'end-cap' || type === 'start-cap') && (type === 'end-cap' || type === 'start-cap') &&
entry.artifact.type === 'path' entry.artifact.type === 'path'
) { ) {
if (!entry.artifact.sweepId) return
const extrusion = getArtifactOfTypes( const extrusion = getArtifactOfTypes(
{ {
key: entry.artifact.sweepId, key: entry.artifact.sweepId,

View File

@ -173,10 +173,14 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
links: [{ label: 'KCL docs', url: 'https://zoo.dev/docs/kcl/fillet' }], links: [{ label: 'KCL docs', url: 'https://zoo.dev/docs/kcl/fillet' }],
}, },
{ {
id: 'chamfer', id: 'chamfer3d',
onClick: () => console.error('Chamfer not yet implemented'), onClick: ({ commandBarSend }) =>
commandBarSend({
type: 'Find and select command',
data: { name: 'Chamfer', groupId: 'modeling' },
}),
icon: 'chamfer3d', icon: 'chamfer3d',
status: 'kcl-only', status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'kcl-only',
title: 'Chamfer', title: 'Chamfer',
hotkey: 'C', hotkey: 'C',
description: 'Bevel the edges of a 3D solid.', description: 'Bevel the edges of a 3D solid.',

View File

@ -52,6 +52,7 @@ import {
} from 'lang/modifyAst' } from 'lang/modifyAst'
import { import {
applyEdgeTreatmentToSelection, applyEdgeTreatmentToSelection,
ChamferParameters,
EdgeTreatmentType, EdgeTreatmentType,
FilletParameters, FilletParameters,
} from 'lang/modifyAst/addEdgeTreatment' } from 'lang/modifyAst/addEdgeTreatment'
@ -272,6 +273,7 @@ export type ModelingMachineEvent =
| { type: 'Shell'; data?: ModelingCommandSchema['Shell'] } | { type: 'Shell'; data?: ModelingCommandSchema['Shell'] }
| { type: 'Revolve'; data?: ModelingCommandSchema['Revolve'] } | { type: 'Revolve'; data?: ModelingCommandSchema['Revolve'] }
| { type: 'Fillet'; data?: ModelingCommandSchema['Fillet'] } | { type: 'Fillet'; data?: ModelingCommandSchema['Fillet'] }
| { type: 'Chamfer'; data?: ModelingCommandSchema['Chamfer'] }
| { type: 'Offset plane'; data: ModelingCommandSchema['Offset plane'] } | { type: 'Offset plane'; data: ModelingCommandSchema['Offset plane'] }
| { type: 'Text-to-CAD'; data: ModelingCommandSchema['Text-to-CAD'] } | { type: 'Text-to-CAD'; data: ModelingCommandSchema['Text-to-CAD'] }
| { type: 'Prompt-to-edit'; data: ModelingCommandSchema['Prompt-to-edit'] } | { type: 'Prompt-to-edit'; data: ModelingCommandSchema['Prompt-to-edit'] }
@ -1737,6 +1739,33 @@ export const modelingMachine = setup({
if (err(filletResult)) return filletResult if (err(filletResult)) return filletResult
} }
), ),
chamferAstMod: fromPromise(
async ({
input,
}: {
input: ModelingCommandSchema['Chamfer'] | undefined
}) => {
if (!input) {
return new Error('No input provided')
}
// Extract inputs
const ast = kclManager.ast
const { selection, length } = input
const parameters: ChamferParameters = {
type: EdgeTreatmentType.Chamfer,
length,
}
// Apply chamfer to selection
const chamferResult = await applyEdgeTreatmentToSelection(
ast,
selection,
parameters
)
if (err(chamferResult)) return chamferResult
}
),
'submit-prompt-edit': fromPromise( 'submit-prompt-edit': fromPromise(
async ({ input }: { input: ModelingCommandSchema['Prompt-to-edit'] }) => { async ({ input }: { input: ModelingCommandSchema['Prompt-to-edit'] }) => {
console.log('doing thing', input) console.log('doing thing', input)
@ -1821,6 +1850,11 @@ export const modelingMachine = setup({
reenter: true, reenter: true,
}, },
Chamfer: {
target: 'Applying chamfer',
reenter: true,
},
Export: { Export: {
target: 'idle', target: 'idle',
reenter: false, reenter: false,
@ -2650,6 +2684,19 @@ export const modelingMachine = setup({
}, },
}, },
'Applying chamfer': {
invoke: {
src: 'chamferAstMod',
id: 'chamferAstMod',
input: ({ event }) => {
if (event.type !== 'Chamfer') return undefined
return event.data
},
onDone: ['idle'],
onError: ['idle'],
},
},
'Applying Prompt-to-edit': { 'Applying Prompt-to-edit': {
invoke: { invoke: {
src: 'submit-prompt-edit', src: 'submit-prompt-edit',

View File

@ -320,6 +320,11 @@ export function getAutoUpdater(): AppUpdater {
} }
app.on('ready', () => { app.on('ready', () => {
// Disable auto updater on non-versioned builds
if (packageJSON.version === '0.0.0') {
return
}
const autoUpdater = getAutoUpdater() const autoUpdater = getAutoUpdater()
// TODO: we're getting `Error: Response ends without calling any handlers` with our setup, // TODO: we're getting `Error: Response ends without calling any handlers` with our setup,
// so at the moment this isn't worth enabling // so at the moment this isn't worth enabling

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

@ -176,7 +176,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -187,7 +187,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -204,7 +204,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -474,7 +474,7 @@ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -665,7 +665,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -676,7 +676,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -723,7 +723,7 @@ dependencies = [
[[package]] [[package]]
name = "derive-docs" name = "derive-docs"
version = "0.1.33" version = "0.1.34"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"anyhow", "anyhow",
@ -737,7 +737,7 @@ dependencies = [
"rustfmt-wrapper", "rustfmt-wrapper",
"serde", "serde",
"serde_tokenstream", "serde_tokenstream",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -748,7 +748,38 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
]
[[package]]
name = "derive_builder"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]]
name = "derive_builder_macro"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
"syn 2.0.96",
] ]
[[package]] [[package]]
@ -791,7 +822,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -829,7 +860,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -990,7 +1021,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1086,7 +1117,7 @@ dependencies = [
"inflections", "inflections",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1132,17 +1163,18 @@ dependencies = [
[[package]] [[package]]
name = "handlebars" name = "handlebars"
version = "6.2.0" version = "6.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315" checksum = "3d6b224b95c1e668ac0270325ad563b2eef1469fbbb8959bc7c692c844b813d9"
dependencies = [ dependencies = [
"derive_builder",
"log", "log",
"num-order", "num-order",
"pest", "pest",
"pest_derive", "pest_derive",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 1.0.68", "thiserror 2.0.0",
] ]
[[package]] [[package]]
@ -1494,7 +1526,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1684,7 +1716,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-lib" name = "kcl-lib"
version = "0.2.29" version = "0.2.30"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"approx 0.5.1", "approx 0.5.1",
@ -1752,7 +1784,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-test-server" name = "kcl-test-server"
version = "0.1.19" version = "0.1.20"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hyper 0.14.30", "hyper 0.14.30",
@ -1819,9 +1851,9 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-modeling-cmds" name = "kittycad-modeling-cmds"
version = "0.2.86" version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e34a8eeb4fff5167666d1f2bc36c95d08ab3a0f736a02c8d33a8cde21cfd8d" checksum = "ce9e58b34645facea36bc9f4868877bbe6fcac01b92896825e8d4f2f7c71dbd6"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -1852,7 +1884,7 @@ dependencies = [
"kittycad-modeling-cmds-macros-impl", "kittycad-modeling-cmds-macros-impl",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1863,7 +1895,7 @@ checksum = "fdb4ee23cc996aa2dca7584d410e8826e08161e1ac4335bb646d5ede33f37cb3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2013,7 +2045,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2312,7 +2344,7 @@ dependencies = [
"regex", "regex",
"regex-syntax 0.8.5", "regex-syntax 0.8.5",
"structmeta", "structmeta",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2326,7 +2358,7 @@ dependencies = [
"regex", "regex",
"regex-syntax 0.8.5", "regex-syntax 0.8.5",
"structmeta", "structmeta",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2366,7 +2398,7 @@ dependencies = [
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2424,7 +2456,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2554,7 +2586,7 @@ dependencies = [
"proc-macro-error-attr2", "proc-macro-error-attr2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2613,7 +2645,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"pyo3-macros-backend", "pyo3-macros-backend",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -2626,7 +2658,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"pyo3-build-config", "pyo3-build-config",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3161,7 +3193,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde_derive_internals", "serde_derive_internals",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3225,7 +3257,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3236,7 +3268,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3260,7 +3292,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3281,7 +3313,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3430,7 +3462,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"structmeta-derive", "structmeta-derive",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3441,7 +3473,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3463,7 +3495,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion", "rustversion",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3506,9 +3538,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.95" version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3532,7 +3564,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3640,7 +3672,7 @@ checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3651,7 +3683,7 @@ checksum = "22efd00f33f93fa62848a7cab956c3d38c8d43095efda1decfc2b3a5dc0b8972"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3763,7 +3795,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3905,7 +3937,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -3933,7 +3965,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -4016,7 +4048,7 @@ checksum = "0e9d8656589772eeec2cf7a8264d9cda40fb28b9bc53118ceb9e8c07f8f38730"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
"termcolor", "termcolor",
] ]
@ -4159,9 +4191,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.11.0" version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"serde", "serde",
@ -4195,7 +4227,7 @@ dependencies = [
"proc-macro-error2", "proc-macro-error2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -4256,7 +4288,7 @@ dependencies = [
"log", "log",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -4292,7 +4324,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -4673,7 +4705,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
"synstructure", "synstructure",
] ]
@ -4695,7 +4727,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -4715,7 +4747,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
"synstructure", "synstructure",
] ]
@ -4744,7 +4776,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.95", "syn 2.0.96",
] ]
[[package]] [[package]]

View File

@ -76,7 +76,7 @@ members = [
[workspace.dependencies] [workspace.dependencies]
http = "1" http = "1"
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] } kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
kittycad-modeling-cmds = { version = "0.2.86", features = [ kittycad-modeling-cmds = { version = "0.2.89", features = [
"ts-rs", "ts-rs",
"websocket", "websocket",
] } ] }

View File

@ -1,7 +1,7 @@
[package] [package]
name = "derive-docs" name = "derive-docs"
description = "A tool for generating documentation from Rust derive macros" description = "A tool for generating documentation from Rust derive macros"
version = "0.1.33" version = "0.1.34"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"
@ -20,7 +20,7 @@ quote = "1"
regex = "1.11" regex = "1.11"
serde = { version = "1.0.217", features = ["derive"] } serde = { version = "1.0.217", features = ["derive"] }
serde_tokenstream = "0.2" serde_tokenstream = "0.2"
syn = { version = "2.0.95", features = ["full"] } syn = { version = "2.0.96", features = ["full"] }
[dev-dependencies] [dev-dependencies]
anyhow = "1.0.95" anyhow = "1.0.95"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-test-server" name = "kcl-test-server"
description = "A test server for KCL" description = "A test server for KCL"
version = "0.1.19" version = "0.1.20"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-lib" name = "kcl-lib"
description = "KittyCAD Language implementation and tools" description = "KittyCAD Language implementation and tools"
version = "0.2.29" version = "0.2.30"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"
@ -22,7 +22,7 @@ clap = { version = "4.5.23", default-features = false, optional = true, features
] } ] }
convert_case = "0.6.0" convert_case = "0.6.0"
dashmap = "6.1.0" dashmap = "6.1.0"
derive-docs = { version = "0.1.33", path = "../derive-docs" } derive-docs = { version = "0.1.34", path = "../derive-docs" }
dhat = { version = "0.3", optional = true } dhat = { version = "0.3", optional = true }
fnv = "1.0.7" fnv = "1.0.7"
form_urlencoded = "1.2.1" form_urlencoded = "1.2.1"
@ -112,7 +112,7 @@ tabled = ["dep:tabled"]
base64 = "0.22.1" base64 = "0.22.1"
criterion = { version = "0.5.1", features = ["async_tokio"] } criterion = { version = "0.5.1", features = ["async_tokio"] }
expectorate = "1.1.0" expectorate = "1.1.0"
handlebars = "6.2.0" handlebars = "6.3.0"
iai = "0.1" iai = "0.1"
image = { version = "0.25.5", default-features = false, features = ["png"] } image = { version = "0.25.5", default-features = false, features = ["png"] }
insta = { version = "1.41.1", features = ["json", "filters", "redactions"] } insta = { version = "1.41.1", features = ["json", "filters", "redactions"] }

View File

@ -1024,6 +1024,36 @@ mod tests {
assert_eq!(snippet, r#"hole(${0:holeSketch}, ${1:%})${}"#); assert_eq!(snippet, r#"hole(${0:holeSketch}, ${1:%})${}"#);
} }
#[test]
fn get_autocomplete_snippet_helix() {
let helix_fn: Box<dyn StdLibFn> = Box::new(crate::std::helix::Helix);
let snippet = helix_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"helix({
revolutions = ${0:3.14},
angleStart = ${1:3.14},
ccw = ${2:false},
radius = ${3:3.14},
axis = ${4:"X"},
})${}"#
);
}
#[test]
fn get_autocomplete_snippet_helix_revolutions() {
let helix_fn: Box<dyn StdLibFn> = Box::new(crate::std::helix::HelixRevolutions);
let snippet = helix_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"helixRevolutions({
revolutions = ${0:3.14},
angleStart = ${1:3.14},
ccw = ${2:false},
}, ${3:%})${}"#
);
}
// We want to test the snippets we compile at lsp start. // We want to test the snippets we compile at lsp start.
#[test] #[test]
fn get_all_stdlib_autocomplete_snippets() { fn get_all_stdlib_autocomplete_snippets() {

View File

@ -1108,7 +1108,7 @@ impl<'a> FromKclValue<'a> for super::helix::HelixData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?; let obj = arg.as_object()?;
let_field_of!(obj, revolutions); let_field_of!(obj, revolutions);
let_field_of!(obj, length); let_field_of!(obj, length?);
let_field_of!(obj, ccw?); let_field_of!(obj, ccw?);
let_field_of!(obj, radius); let_field_of!(obj, radius);
let_field_of!(obj, axis); let_field_of!(obj, axis);

View File

@ -26,8 +26,9 @@ pub struct HelixData {
/// The default is `false`. /// The default is `false`.
#[serde(default)] #[serde(default)]
pub ccw: bool, pub ccw: bool,
/// Length of the helix. /// Length of the helix. This is not necessary if the helix is created around an edge. If not
pub length: f64, /// given the length of the edge is used.
pub length: Option<f64>,
/// Radius of the helix. /// Radius of the helix.
pub radius: f64, pub radius: f64,
/// Axis to use as mirror. /// Axis to use as mirror.
@ -64,7 +65,7 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// ///
/// ```no_run /// ```no_run
/// // Create a helix around an edge. /// // Create a helix around an edge.
/// /*helper001 = startSketchOn('XZ') /// helper001 = startSketchOn('XZ')
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> line([0, 10], %, $edge001) /// |> line([0, 10], %, $edge001)
/// ///
@ -80,7 +81,29 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('XY') /// springSketch = startSketchOn('XY')
/// |> circle({ center = [0, 0], radius = 1 }, %) /// |> circle({ center = [0, 0], radius = 1 }, %)
/// |> sweep({ path = helixPath }, %)*/ /// //|> sweep({ path = helixPath }, %)
/// ```
///
/// ```no_run
/// // Create a helix around a custom axis.
/// helixPath = helix({
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// length = 10,
/// radius = 5,
/// axis = {
/// custom = {
/// axis = [0, 0, 1.0],
/// origin = [0, 0.25, 0]
/// }
/// }
/// })
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('XY')
/// |> circle({ center = [0, 0], radius = 1 }, %)
/// //|> sweep({ path = helixPath }, %)
/// ``` /// ```
#[stdlib { #[stdlib {
name = "helix", name = "helix",
@ -105,12 +128,20 @@ async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) ->
Axis3dOrEdgeReference::Axis(axis) => { Axis3dOrEdgeReference::Axis(axis) => {
let (axis, origin) = axis.axis_and_origin()?; let (axis, origin) = axis.axis_and_origin()?;
// Make sure they gave us a length.
let Some(length) = data.length else {
return Err(KclError::Semantic(crate::errors::KclErrorDetails {
message: "Length is required when creating a helix around an axis.".to_string(),
source_ranges: vec![args.source_range],
}));
};
args.batch_modeling_cmd( args.batch_modeling_cmd(
exec_state.next_uuid(), exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityMakeHelixFromParams { ModelingCmd::from(mcmd::EntityMakeHelixFromParams {
radius: data.radius, radius: data.radius,
is_clockwise: !data.ccw, is_clockwise: !data.ccw,
length: LengthUnit(data.length), length: LengthUnit(length),
revolutions: data.revolutions, revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start), start_angle: Angle::from_degrees(data.angle_start),
axis, axis,
@ -119,25 +150,21 @@ async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) ->
) )
.await?; .await?;
} }
Axis3dOrEdgeReference::Edge(_edge) => { Axis3dOrEdgeReference::Edge(edge) => {
/*let edge_id = edge.get_engine_id(exec_state, &args)?; let edge_id = edge.get_engine_id(exec_state, &args)?;
args.batch_modeling_cmd( args.batch_modeling_cmd(
exec_state.next_uuid(), exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityMakeHelixFromEdge { ModelingCmd::from(mcmd::EntityMakeHelixFromEdge {
radius: data.radius, radius: data.radius,
is_clockwise: !data.ccw, is_clockwise: !data.ccw,
length: LengthUnit(data.length), length: data.length.map(LengthUnit),
revolutions: data.revolutions, revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start), start_angle: Angle::from_degrees(data.angle_start),
edge_id, edge_id,
}), }),
) )
.await?;*/ .await?;
return Err(KclError::Unimplemented(crate::errors::KclErrorDetails {
message: "Helix around edge is not yet implemented".to_string(),
source_ranges: vec![args.source_range],
}));
} }
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

10
vitest.workspace.ts Normal file
View File

@ -0,0 +1,10 @@
import { defineWorkspace } from 'vitest/config'
export default defineWorkspace([
'./vite.main.config.ts',
'./vite.base.config.ts',
'./vite.config.ts',
'./vite.preload.config.ts',
'./vite.renderer.config.ts',
'./packages/codemirror-lang-kcl/vitest.main.config.ts',
])

115
yarn.lock
View File

@ -1867,10 +1867,10 @@
resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.2.1.tgz#198b278b7869668e1bebbe687586e12a42731049" resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.2.1.tgz#198b278b7869668e1bebbe687586e12a42731049"
integrity sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ== integrity sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==
"@lezer/generator@^1.7.1": "@lezer/generator@^1.7.2":
version "1.7.1" version "1.7.2"
resolved "https://registry.yarnpkg.com/@lezer/generator/-/generator-1.7.1.tgz#90c1a9de2fb4d5a714216fa659058c7859accaab" resolved "https://registry.yarnpkg.com/@lezer/generator/-/generator-1.7.2.tgz#a491c91eb9f117ea803e748fa97574514156a2a3"
integrity sha512-MgPJN9Si+ccxzXl3OAmCeZuUKw4XiPl4y664FX/hnnyG9CTqUPq65N3/VGPA2jD23D7QgMTtNqflta+cPN+5mQ== integrity sha512-CwgULPOPPmH54tv4gki18bElLCdJ1+FBC+nGVSVD08vFWDsMjS7KEjNTph9JOypDnet90ujN3LzQiW3CyVODNQ==
dependencies: dependencies:
"@lezer/common" "^1.1.0" "@lezer/common" "^1.1.0"
"@lezer/lr" "^1.3.0" "@lezer/lr" "^1.3.0"
@ -2552,7 +2552,7 @@
"@typescript-eslint/visitor-keys" "8.19.1" "@typescript-eslint/visitor-keys" "8.19.1"
debug "^4.3.4" debug "^4.3.4"
"@typescript-eslint/scope-manager@8.19.1": "@typescript-eslint/scope-manager@8.19.1", "@typescript-eslint/scope-manager@^8.15.0":
version "8.19.1" version "8.19.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.19.1.tgz#794cfc8add4f373b9cd6fa32e367e7565a0e231b" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.19.1.tgz#794cfc8add4f373b9cd6fa32e367e7565a0e231b"
integrity sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q== integrity sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==
@ -2589,7 +2589,7 @@
semver "^7.6.0" semver "^7.6.0"
ts-api-utils "^2.0.0" ts-api-utils "^2.0.0"
"@typescript-eslint/utils@8.19.1", "@typescript-eslint/utils@^6.0.0 || ^7.0.0 || ^8.0.0": "@typescript-eslint/utils@8.19.1", "@typescript-eslint/utils@^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/utils@^8.15.0":
version "8.19.1" version "8.19.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.19.1.tgz#dd8eabd46b92bf61e573286e1c0ba6bd243a185b" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.19.1.tgz#dd8eabd46b92bf61e573286e1c0ba6bd243a185b"
integrity sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA== integrity sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==
@ -2926,6 +2926,11 @@ aria-query@5.3.0, aria-query@^5.0.0:
dependencies: dependencies:
dequal "^2.0.3" dequal "^2.0.3"
aria-query@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59"
integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==
array-buffer-byte-length@^1.0.1: array-buffer-byte-length@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f"
@ -3076,6 +3081,11 @@ assertion-error@^1.1.0:
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
ast-types-flow@^0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6"
integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==
ast-types@^0.16.1: ast-types@^0.16.1:
version "0.16.1" version "0.16.1"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2"
@ -3139,6 +3149,11 @@ available-typed-arrays@^1.0.7:
dependencies: dependencies:
possible-typed-array-names "^1.0.0" possible-typed-array-names "^1.0.0"
axe-core@^4.10.0:
version "4.10.2"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.2.tgz#85228e3e1d8b8532a27659b332e39b7fa0e022df"
integrity sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==
axios@^0.26.1: axios@^0.26.1:
version "0.26.1" version "0.26.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9"
@ -3146,6 +3161,11 @@ axios@^0.26.1:
dependencies: dependencies:
follow-redirects "^1.14.8" follow-redirects "^1.14.8"
axobject-query@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==
babel-plugin-polyfill-corejs2@^0.4.10: babel-plugin-polyfill-corejs2@^0.4.10:
version "0.4.11" version "0.4.11"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33"
@ -3884,6 +3904,11 @@ d3-force@^3.0.0:
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
damerau-levenshtein@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
data-uri-to-buffer@^4.0.0: data-uri-to-buffer@^4.0.0:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e"
@ -4631,6 +4656,32 @@ eslint-plugin-jest@^28.10.0:
dependencies: dependencies:
"@typescript-eslint/utils" "^6.0.0 || ^7.0.0 || ^8.0.0" "@typescript-eslint/utils" "^6.0.0 || ^7.0.0 || ^8.0.0"
eslint-plugin-jsx-a11y@^6.10.2:
version "6.10.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz#d2812bb23bf1ab4665f1718ea442e8372e638483"
integrity sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==
dependencies:
aria-query "^5.3.2"
array-includes "^3.1.8"
array.prototype.flatmap "^1.3.2"
ast-types-flow "^0.0.8"
axe-core "^4.10.0"
axobject-query "^4.1.0"
damerau-levenshtein "^1.0.8"
emoji-regex "^9.2.2"
hasown "^2.0.2"
jsx-ast-utils "^3.3.5"
language-tags "^1.0.9"
minimatch "^3.1.2"
object.fromentries "^2.0.8"
safe-regex-test "^1.0.3"
string.prototype.includes "^2.0.1"
eslint-plugin-react-hooks@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz#3d34e37d5770866c34b87d5b499f5f0b53bf0854"
integrity sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==
eslint-plugin-react@^7.37.3: eslint-plugin-react@^7.37.3:
version "7.37.3" version "7.37.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz#567549e9251533975c4ea9706f986c3a64832031" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz#567549e9251533975c4ea9706f986c3a64832031"
@ -4660,6 +4711,14 @@ eslint-plugin-suggest-no-throw@^1.0.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-suggest-no-throw/-/eslint-plugin-suggest-no-throw-1.0.0.tgz#facc852aa9acd5e0f4d5e0aff71d6a186e3be8e8" resolved "https://registry.yarnpkg.com/eslint-plugin-suggest-no-throw/-/eslint-plugin-suggest-no-throw-1.0.0.tgz#facc852aa9acd5e0f4d5e0aff71d6a186e3be8e8"
integrity sha512-IoSDNVeH9WRC9T4Nm3HResFthgiPEW8e6YkKzichJ4fZwac0T8qBQ/8qjmv9NeRSEw8q2EbN/THLE/UU38J46g== integrity sha512-IoSDNVeH9WRC9T4Nm3HResFthgiPEW8e6YkKzichJ4fZwac0T8qBQ/8qjmv9NeRSEw8q2EbN/THLE/UU38J46g==
eslint-plugin-testing-library@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.1.1.tgz#df834e821e53fa81c1eb1fad5a0d9ba4c510f9ea"
integrity sha512-nszC833aZPwB6tik1nMkbFqmtgIXTT0sfJEYs0zMBKMlkQ4to2079yUV96SvmLh00ovSBJI4pgcBC1TiIP8mXg==
dependencies:
"@typescript-eslint/scope-manager" "^8.15.0"
"@typescript-eslint/utils" "^8.15.0"
eslint-scope@^7.2.2: eslint-scope@^7.2.2:
version "7.2.2" version "7.2.2"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f"
@ -6392,7 +6451,7 @@ jsonfile@^6.0.1:
optionalDependencies: optionalDependencies:
graceful-fs "^4.1.6" graceful-fs "^4.1.6"
"jsx-ast-utils@^2.4.1 || ^3.0.0": "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5:
version "3.3.5" version "3.3.5"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a"
integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==
@ -6432,6 +6491,18 @@ kill-port@^2.0.1:
get-them-args "1.3.2" get-them-args "1.3.2"
shell-exec "1.0.2" shell-exec "1.0.2"
language-subtag-registry@^0.3.20:
version "0.3.23"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7"
integrity sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==
language-tags@^1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777"
integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==
dependencies:
language-subtag-registry "^0.3.20"
lazy-val@^1.0.4, lazy-val@^1.0.5: lazy-val@^1.0.4, lazy-val@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d"
@ -8630,6 +8701,15 @@ string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2" emoji-regex "^9.2.2"
strip-ansi "^7.0.1" strip-ansi "^7.0.1"
string.prototype.includes@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz#eceef21283640761a81dbe16d6c7171a4edf7d92"
integrity sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
es-abstract "^1.23.3"
string.prototype.matchall@^4.0.12: string.prototype.matchall@^4.0.12:
version "4.0.12" version "4.0.12"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz#6c88740e49ad4956b1332a911e949583a275d4c0" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz#6c88740e49ad4956b1332a911e949583a275d4c0"
@ -9177,15 +9257,10 @@ typescript-eslint@^8.19.1:
"@typescript-eslint/parser" "8.19.1" "@typescript-eslint/parser" "8.19.1"
"@typescript-eslint/utils" "8.19.1" "@typescript-eslint/utils" "8.19.1"
typescript@^5.3.3: typescript@^5.3.3, typescript@^5.7.3:
version "5.5.4" version "5.7.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e"
integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==
typescript@^5.7.2:
version "5.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==
ua-parser-js@^1.0.35, ua-parser-js@^1.0.37: ua-parser-js@^1.0.35, ua-parser-js@^1.0.37:
version "1.0.38" version "1.0.38"
@ -9724,10 +9799,10 @@ xstate@^4.33.4:
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.38.3.tgz#4e15e7ad3aa0ca1eea2010548a5379966d8f1075" resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.38.3.tgz#4e15e7ad3aa0ca1eea2010548a5379966d8f1075"
integrity sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw== integrity sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw==
xstate@^5.17.4: xstate@^5.19.2:
version "5.17.4" version "5.19.2"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.17.4.tgz#334ab2da123973634097f7ca48387ae1589c774e" resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.19.2.tgz#db3f1ee614bbb6a49ad3f0c96ddbf98562d456ba"
integrity sha512-KM2FYVOUJ04HlOO4TY3wEXqoYPR/XsDu+ewm+IWw0vilXqND0jVfvv04tEFwp8Mkk7I/oHXM8t1Ex9xJyUS4ZA== integrity sha512-B8fL2aP0ogn5aviAXFzI5oZseAMqN00fg/TeDa3ZtatyDcViYLIfuQl4y8qmHCiKZgGEzmnTyNtNQL9oeJE2gw==
xterm-addon-fit@^0.5.0: xterm-addon-fit@^0.5.0:
version "0.5.0" version "0.5.0"