@pascal-app/mcp 0.3.1 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/bridge/scene-bridge.d.ts.map +1 -1
- package/dist/bridge/scene-bridge.js +6 -0
- package/dist/operations/scene-operations.js +7 -6
- package/dist/resources/constraints.js +1 -1
- package/dist/templates/empty-studio.d.ts.map +1 -1
- package/dist/templates/empty-studio.js +2 -4
- package/dist/templates/garden-house.js +1 -1
- package/dist/templates/two-bedroom.js +1 -1
- package/dist/tools/construction-tools.d.ts +21 -21
- package/dist/tools/construction-tools.d.ts.map +1 -1
- package/dist/tools/construction-tools.js +81 -33
- package/dist/tools/create-level.d.ts +1 -1
- package/dist/tools/create-level.d.ts.map +1 -1
- package/dist/tools/create-level.js +19 -7
- package/dist/tools/create-wall.d.ts +2 -2
- package/dist/tools/create-wall.d.ts.map +1 -1
- package/dist/tools/create-wall.js +6 -2
- package/dist/tools/cut-opening.d.ts +3 -3
- package/dist/tools/cut-opening.d.ts.map +1 -1
- package/dist/tools/cut-opening.js +3 -2
- package/dist/tools/describe-node.d.ts.map +1 -1
- package/dist/tools/describe-node.js +14 -5
- package/dist/tools/find-nodes.d.ts +2 -2
- package/dist/tools/find-nodes.js +1 -1
- package/dist/tools/measurement.d.ts +37 -0
- package/dist/tools/measurement.d.ts.map +1 -0
- package/dist/tools/measurement.js +94 -0
- package/dist/tools/photo-to-scene/photo-to-scene.d.ts +2 -2
- package/dist/tools/photo-to-scene/photo-to-scene.d.ts.map +1 -1
- package/dist/tools/photo-to-scene/photo-to-scene.js +14 -5
- package/dist/tools/place-item.d.ts +1 -1
- package/dist/tools/place-item.d.ts.map +1 -1
- package/dist/tools/place-item.js +2 -1
- package/dist/tools/room-tools.d.ts +8 -8
- package/dist/tools/room-tools.d.ts.map +1 -1
- package/dist/tools/room-tools.js +17 -7
- package/dist/tools/scene-query.d.ts +4 -0
- package/dist/tools/scene-query.d.ts.map +1 -1
- package/dist/tools/scene-query.js +24 -11
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -251,7 +251,8 @@ plus the element's own height; slabs additionally carry an absolute
|
|
|
251
251
|
|
|
252
252
|
**Heads-up when you compute coordinates outside the editor.** Pascal's
|
|
253
253
|
viewports apply their own rotations on top of the world axes: the 2-D plan
|
|
254
|
-
panel
|
|
254
|
+
panel rotates its content by the user's view rotation (north-aligned = 0°,
|
|
255
|
+
`FLOORPLAN_VIEW_ROTATION_DEG` baseline, north = world −Z), and
|
|
255
256
|
the 3-D "top-down" snap preserves the camera's current azimuth, so when invoked
|
|
256
257
|
from the iso default position, world and screen axes are offset by ~45° until
|
|
257
258
|
you orbit to an axis-aligned view. So a layout authored as if
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/scene-bridge.ts"],"names":[],"mappings":"AACA,OAAO,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,KAAK,SAAS,EAA4B,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAGpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,MAAM,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAC/E,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAAA;AAE5E,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,CAAA;AAC/E,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAA;AACjF,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAC5E,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAA;AAC3D,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,SAAS,EACT,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CACrE,CAAA;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAA+B;IAElD;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAW3C,cAAc,IAAI,eAAe,GAAG,IAAI;IAIxC,gBAAgB,IAAI,IAAI;IAIxB,6EAA6E;IAC7E,WAAW,IAAI,IAAI;IAInB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI;IAI3E,uDAAuD;IACvD,UAAU,IAAI,UAAU,GAAG;QAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"scene-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/scene-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,9 @@ export class SceneBridge {
|
|
|
48
48
|
nodes: state.nodes,
|
|
49
49
|
rootNodeIds: state.rootNodeIds,
|
|
50
50
|
collections: state.collections ?? {},
|
|
51
|
+
...(state.hasExplicitPluginInstallState || state.installedPlugins.length > 0
|
|
52
|
+
? { installedPlugins: state.installedPlugins }
|
|
53
|
+
: {}),
|
|
51
54
|
}));
|
|
52
55
|
}
|
|
53
56
|
/**
|
|
@@ -88,6 +91,9 @@ export class SceneBridge {
|
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
this.setScene(nodes, rootNodeIds);
|
|
94
|
+
if (Array.isArray(obj.installedPlugins)) {
|
|
95
|
+
useScene.getState().setInstalledPlugins(obj.installedPlugins.filter((id) => typeof id === 'string'), { explicit: true });
|
|
96
|
+
}
|
|
91
97
|
}
|
|
92
98
|
/** Read a single node, or `null` if not present. */
|
|
93
99
|
getNode(id) {
|
|
@@ -56,6 +56,7 @@ class SceneOperationsFacade {
|
|
|
56
56
|
nodes: exported.nodes,
|
|
57
57
|
rootNodeIds: exported.rootNodeIds,
|
|
58
58
|
collections: exported.collections,
|
|
59
|
+
installedPlugins: exported.installedPlugins,
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
loadJSON(json) {
|
|
@@ -165,17 +166,17 @@ class SceneOperationsFacade {
|
|
|
165
166
|
return this.requireStore().rename(id, newName, options);
|
|
166
167
|
}
|
|
167
168
|
async appendSceneEvent(options) {
|
|
168
|
-
const
|
|
169
|
-
if (!
|
|
169
|
+
const store = this.requireStore();
|
|
170
|
+
if (!store.appendSceneEvent)
|
|
170
171
|
return null;
|
|
171
|
-
return
|
|
172
|
+
return store.appendSceneEvent(options);
|
|
172
173
|
}
|
|
173
174
|
async listSceneEvents(id, options) {
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
175
|
+
const store = this.requireStore();
|
|
176
|
+
if (!store.listSceneEvents) {
|
|
176
177
|
throw new Error('scene_events_unavailable');
|
|
177
178
|
}
|
|
178
|
-
return
|
|
179
|
+
return store.listSceneEvents(id, options);
|
|
179
180
|
}
|
|
180
181
|
requireBridge() {
|
|
181
182
|
if (!this.#bridge) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empty-studio.d.ts","sourceRoot":"","sources":["../../src/templates/empty-studio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"empty-studio.d.ts","sourceRoot":"","sources":["../../src/templates/empty-studio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAmPpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;;;;CAKX,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_LEVEL_HEIGHT } from '@pascal-app/core';
|
|
1
2
|
/**
|
|
2
3
|
* 40 m² studio apartment — a single open room with one window, one front door
|
|
3
4
|
* and a single "Living/Kitchen" zone. Used as a starting point for small unit
|
|
@@ -117,7 +118,6 @@ function buildNodes() {
|
|
|
117
118
|
metadata: {},
|
|
118
119
|
children: [],
|
|
119
120
|
thickness: 0.1,
|
|
120
|
-
height: 2.5,
|
|
121
121
|
start: [-W, -D],
|
|
122
122
|
end: [W, -D],
|
|
123
123
|
frontSide: 'unknown',
|
|
@@ -132,7 +132,6 @@ function buildNodes() {
|
|
|
132
132
|
metadata: {},
|
|
133
133
|
children: [],
|
|
134
134
|
thickness: 0.1,
|
|
135
|
-
height: 2.5,
|
|
136
135
|
start: [W, -D],
|
|
137
136
|
end: [W, D],
|
|
138
137
|
frontSide: 'unknown',
|
|
@@ -147,7 +146,6 @@ function buildNodes() {
|
|
|
147
146
|
metadata: {},
|
|
148
147
|
children: ['door_front'],
|
|
149
148
|
thickness: 0.1,
|
|
150
|
-
height: 2.5,
|
|
151
149
|
start: [W, D],
|
|
152
150
|
end: [-W, D],
|
|
153
151
|
frontSide: 'unknown',
|
|
@@ -162,7 +160,6 @@ function buildNodes() {
|
|
|
162
160
|
metadata: {},
|
|
163
161
|
children: ['window_w'],
|
|
164
162
|
thickness: 0.1,
|
|
165
|
-
height: 2.5,
|
|
166
163
|
start: [-W, D],
|
|
167
164
|
end: [-W, -D],
|
|
168
165
|
frontSide: 'unknown',
|
|
@@ -192,6 +189,7 @@ function buildNodes() {
|
|
|
192
189
|
visible: true,
|
|
193
190
|
metadata: {},
|
|
194
191
|
level: 0,
|
|
192
|
+
height: DEFAULT_LEVEL_HEIGHT,
|
|
195
193
|
children: [...wallIds, 'zone_living'],
|
|
196
194
|
};
|
|
197
195
|
return {
|
|
@@ -28,7 +28,6 @@ function wall(id, start, end, children = []) {
|
|
|
28
28
|
metadata: {},
|
|
29
29
|
children,
|
|
30
30
|
thickness: WALL_THICKNESS,
|
|
31
|
-
height: WALL_HEIGHT,
|
|
32
31
|
start,
|
|
33
32
|
end,
|
|
34
33
|
frontSide: 'unknown',
|
|
@@ -216,6 +215,7 @@ function buildTemplate() {
|
|
|
216
215
|
visible: true,
|
|
217
216
|
metadata: {},
|
|
218
217
|
level: 0,
|
|
218
|
+
height: WALL_HEIGHT,
|
|
219
219
|
children: [
|
|
220
220
|
'wall_n',
|
|
221
221
|
'wall_e',
|
|
@@ -31,7 +31,6 @@ function wall(id, start, end, children = []) {
|
|
|
31
31
|
metadata: {},
|
|
32
32
|
children,
|
|
33
33
|
thickness: WALL_THICKNESS,
|
|
34
|
-
height: WALL_HEIGHT,
|
|
35
34
|
start,
|
|
36
35
|
end,
|
|
37
36
|
frontSide: 'unknown',
|
|
@@ -240,6 +239,7 @@ function buildTemplate() {
|
|
|
240
239
|
visible: true,
|
|
241
240
|
metadata: {},
|
|
242
241
|
level: 0,
|
|
242
|
+
height: WALL_HEIGHT,
|
|
243
243
|
children: [
|
|
244
244
|
'wall_n',
|
|
245
245
|
'wall_e',
|
|
@@ -4,12 +4,12 @@ import type { SceneOperations } from '../operations';
|
|
|
4
4
|
export declare const createStoryShellInput: {
|
|
5
5
|
levelId: z.ZodString;
|
|
6
6
|
footprint: z.ZodArray<z.ZodArray<z.ZodNumber>>;
|
|
7
|
-
wallHeight: z.
|
|
8
|
-
wallThickness: z.ZodDefault<z.ZodNumber
|
|
7
|
+
wallHeight: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
8
|
+
wallThickness: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
9
9
|
createSlab: z.ZodDefault<z.ZodBoolean>;
|
|
10
10
|
createCeiling: z.ZodDefault<z.ZodBoolean>;
|
|
11
|
-
slabElevation: z.ZodDefault<z.ZodNumber
|
|
12
|
-
ceilingHeight: z.ZodOptional<z.ZodNumber
|
|
11
|
+
slabElevation: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
12
|
+
ceilingHeight: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
13
13
|
namePrefix: z.ZodOptional<z.ZodString>;
|
|
14
14
|
wallMaterialPreset: z.ZodOptional<z.ZodString>;
|
|
15
15
|
slabMaterialPreset: z.ZodOptional<z.ZodString>;
|
|
@@ -28,10 +28,10 @@ export declare const createRoofInput: {
|
|
|
28
28
|
useDedicatedRoofLevel: z.ZodDefault<z.ZodBoolean>;
|
|
29
29
|
roofLevelLabel: z.ZodDefault<z.ZodString>;
|
|
30
30
|
roofLevelElevation: z.ZodOptional<z.ZodNumber>;
|
|
31
|
-
roofLevelHeight: z.ZodOptional<z.ZodNumber
|
|
31
|
+
roofLevelHeight: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
32
32
|
center: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
33
|
-
width: z.ZodNumber
|
|
34
|
-
depth: z.ZodNumber
|
|
33
|
+
width: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
|
|
34
|
+
depth: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
|
|
35
35
|
roofType: z.ZodDefault<z.ZodEnum<{
|
|
36
36
|
flat: "flat";
|
|
37
37
|
hip: "hip";
|
|
@@ -41,10 +41,10 @@ export declare const createRoofInput: {
|
|
|
41
41
|
dutch: "dutch";
|
|
42
42
|
mansard: "mansard";
|
|
43
43
|
}>>;
|
|
44
|
-
pitch: z.ZodDefault<z.ZodNumber
|
|
45
|
-
wallHeight: z.ZodDefault<z.ZodNumber
|
|
46
|
-
wallThickness: z.ZodDefault<z.ZodNumber
|
|
47
|
-
overhang: z.ZodDefault<z.ZodNumber
|
|
44
|
+
pitch: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
45
|
+
wallHeight: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
46
|
+
wallThickness: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
47
|
+
overhang: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
48
48
|
materialPreset: z.ZodOptional<z.ZodString>;
|
|
49
49
|
name: z.ZodOptional<z.ZodString>;
|
|
50
50
|
};
|
|
@@ -59,26 +59,26 @@ export declare const createStairBetweenLevelsInput: {
|
|
|
59
59
|
fromLevelId: z.ZodString;
|
|
60
60
|
toLevelId: z.ZodString;
|
|
61
61
|
position: z.ZodArray<z.ZodNumber>;
|
|
62
|
-
rotation: z.ZodDefault<z.ZodNumber
|
|
63
|
-
width: z.ZodDefault<z.ZodNumber
|
|
64
|
-
runLength: z.ZodDefault<z.ZodNumber
|
|
65
|
-
totalRise: z.
|
|
62
|
+
rotation: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
63
|
+
width: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
64
|
+
runLength: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
65
|
+
totalRise: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
66
66
|
stepCount: z.ZodDefault<z.ZodNumber>;
|
|
67
67
|
railingMode: z.ZodDefault<z.ZodEnum<{
|
|
68
68
|
none: "none";
|
|
69
|
-
left: "left";
|
|
70
|
-
right: "right";
|
|
71
69
|
both: "both";
|
|
70
|
+
right: "right";
|
|
71
|
+
left: "left";
|
|
72
72
|
}>>;
|
|
73
73
|
destinationSlabId: z.ZodOptional<z.ZodString>;
|
|
74
74
|
sourceCeilingId: z.ZodOptional<z.ZodString>;
|
|
75
75
|
createDestinationSlabOpening: z.ZodDefault<z.ZodBoolean>;
|
|
76
76
|
createSourceCeilingOpening: z.ZodDefault<z.ZodBoolean>;
|
|
77
|
-
openingWidth: z.ZodOptional<z.ZodNumber
|
|
78
|
-
openingLength: z.ZodOptional<z.ZodNumber
|
|
79
|
-
openingOffset: z.ZodDefault<z.ZodNumber
|
|
77
|
+
openingWidth: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
78
|
+
openingLength: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
79
|
+
openingOffset: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
80
80
|
openingCenter: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
81
|
-
openingRotation: z.ZodOptional<z.ZodNumber
|
|
81
|
+
openingRotation: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
82
82
|
materialPreset: z.ZodOptional<z.ZodString>;
|
|
83
83
|
name: z.ZodOptional<z.ZodString>;
|
|
84
84
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"construction-tools.d.ts","sourceRoot":"","sources":["../../src/tools/construction-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;
|
|
1
|
+
{"version":3,"file":"construction-tools.d.ts","sourceRoot":"","sources":["../../src/tools/construction-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAcxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAQpD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;CAsBjC,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;CAMlC,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;CA0B3B,CAAA;AAED,eAAO,MAAM,gBAAgB;;;;;;CAM5B,CAAA;AAED,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCzC,CAAA;AAED,eAAO,MAAM,8BAA8B;;;;;;CAM1C,CAAA;AA4GD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAmU1F"}
|
|
@@ -1,18 +1,29 @@
|
|
|
1
|
+
import { resolveStairTotalRise } from '@pascal-app/core';
|
|
1
2
|
import { CeilingNode, getActiveRoofHeight, LevelNode, RoofNode, RoofSegmentNode, SlabNode, StairNode, StairSegmentNode, WallNode, } from '@pascal-app/core/schema';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { publishLiveSceneSnapshot } from './live-sync';
|
|
5
|
+
import { measurement } from './measurement';
|
|
4
6
|
import { NodeIdSchema, Vec2Schema, Vec3Schema } from './schemas';
|
|
5
7
|
const ROOF_TYPES = ['hip', 'gable', 'shed', 'gambrel', 'dutch', 'mansard', 'flat'];
|
|
6
8
|
const RAILING_MODES = ['none', 'left', 'right', 'both'];
|
|
7
9
|
export const createStoryShellInput = {
|
|
8
10
|
levelId: NodeIdSchema,
|
|
9
11
|
footprint: z.array(Vec2Schema).min(3),
|
|
10
|
-
wallHeight:
|
|
11
|
-
|
|
12
|
+
wallHeight: measurement('length', 'm', {
|
|
13
|
+
positive: true,
|
|
14
|
+
description: 'Explicit wall height override. Omit for level-plane-bound walls.',
|
|
15
|
+
}).optional(),
|
|
16
|
+
wallThickness: measurement('length', 'm', {
|
|
17
|
+
positive: true,
|
|
18
|
+
description: 'Wall thickness.',
|
|
19
|
+
}).default(0.16),
|
|
12
20
|
createSlab: z.boolean().default(true),
|
|
13
21
|
createCeiling: z.boolean().default(true),
|
|
14
|
-
slabElevation:
|
|
15
|
-
ceilingHeight:
|
|
22
|
+
slabElevation: measurement('length', 'm', { description: 'Slab elevation.' }).default(0.1),
|
|
23
|
+
ceilingHeight: measurement('length', 'm', {
|
|
24
|
+
positive: true,
|
|
25
|
+
description: 'Ceiling height.',
|
|
26
|
+
}).optional(),
|
|
16
27
|
namePrefix: z.string().optional(),
|
|
17
28
|
wallMaterialPreset: z.string().optional(),
|
|
18
29
|
slabMaterialPreset: z.string().optional(),
|
|
@@ -30,16 +41,23 @@ export const createRoofInput = {
|
|
|
30
41
|
roofLevelId: NodeIdSchema.optional(),
|
|
31
42
|
useDedicatedRoofLevel: z.boolean().default(true),
|
|
32
43
|
roofLevelLabel: z.string().default('Roof'),
|
|
44
|
+
// A level ordinal (story index), not a length — kept numeric.
|
|
33
45
|
roofLevelElevation: z.number().optional(),
|
|
34
|
-
roofLevelHeight:
|
|
46
|
+
roofLevelHeight: measurement('length', 'm', {
|
|
47
|
+
positive: true,
|
|
48
|
+
description: 'Roof level height.',
|
|
49
|
+
}).optional(),
|
|
35
50
|
center: Vec3Schema.optional(),
|
|
36
|
-
width:
|
|
37
|
-
depth:
|
|
51
|
+
width: measurement('length', 'm', { positive: true, description: 'Roof width.' }),
|
|
52
|
+
depth: measurement('length', 'm', { positive: true, description: 'Roof depth.' }),
|
|
38
53
|
roofType: z.enum(ROOF_TYPES).default('hip'),
|
|
39
|
-
pitch:
|
|
40
|
-
wallHeight:
|
|
41
|
-
wallThickness:
|
|
42
|
-
|
|
54
|
+
pitch: measurement('angle', 'deg', { min: 0, max: 85, description: 'Roof pitch.' }).default(35),
|
|
55
|
+
wallHeight: measurement('length', 'm', { min: 0, description: 'Knee-wall height.' }).default(0.35),
|
|
56
|
+
wallThickness: measurement('length', 'm', {
|
|
57
|
+
positive: true,
|
|
58
|
+
description: 'Wall thickness.',
|
|
59
|
+
}).default(0.16),
|
|
60
|
+
overhang: measurement('length', 'm', { min: 0, description: 'Eave overhang.' }).default(0.45),
|
|
43
61
|
materialPreset: z.string().optional(),
|
|
44
62
|
name: z.string().optional(),
|
|
45
63
|
};
|
|
@@ -54,21 +72,33 @@ export const createStairBetweenLevelsInput = {
|
|
|
54
72
|
fromLevelId: NodeIdSchema,
|
|
55
73
|
toLevelId: NodeIdSchema,
|
|
56
74
|
position: Vec3Schema,
|
|
57
|
-
rotation:
|
|
58
|
-
width:
|
|
59
|
-
runLength:
|
|
60
|
-
|
|
75
|
+
rotation: measurement('angle', 'rad', { description: 'Y-axis rotation.' }).default(0),
|
|
76
|
+
width: measurement('length', 'm', { positive: true, description: 'Stair width.' }).default(1),
|
|
77
|
+
runLength: measurement('length', 'm', {
|
|
78
|
+
positive: true,
|
|
79
|
+
description: 'Horizontal run length.',
|
|
80
|
+
}).default(3),
|
|
81
|
+
totalRise: measurement('length', 'm', {
|
|
82
|
+
positive: true,
|
|
83
|
+
description: 'Total vertical rise.',
|
|
84
|
+
}).optional(),
|
|
61
85
|
stepCount: z.number().int().positive().default(14),
|
|
62
86
|
railingMode: z.enum(RAILING_MODES).default('both'),
|
|
63
87
|
destinationSlabId: NodeIdSchema.optional(),
|
|
64
88
|
sourceCeilingId: NodeIdSchema.optional(),
|
|
65
89
|
createDestinationSlabOpening: z.boolean().default(true),
|
|
66
90
|
createSourceCeilingOpening: z.boolean().default(true),
|
|
67
|
-
openingWidth:
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
openingWidth: measurement('length', 'm', {
|
|
92
|
+
positive: true,
|
|
93
|
+
description: 'Floor opening width.',
|
|
94
|
+
}).optional(),
|
|
95
|
+
openingLength: measurement('length', 'm', {
|
|
96
|
+
positive: true,
|
|
97
|
+
description: 'Floor opening length.',
|
|
98
|
+
}).optional(),
|
|
99
|
+
openingOffset: measurement('length', 'm', { min: 0, description: 'Opening offset.' }).default(0),
|
|
70
100
|
openingCenter: Vec2Schema.optional(),
|
|
71
|
-
openingRotation:
|
|
101
|
+
openingRotation: measurement('angle', 'rad', { description: 'Opening rotation.' }).optional(),
|
|
72
102
|
materialPreset: z.string().optional(),
|
|
73
103
|
name: z.string().optional(),
|
|
74
104
|
};
|
|
@@ -174,7 +204,7 @@ export function registerConstructionTools(server, bridge) {
|
|
|
174
204
|
start: points[i],
|
|
175
205
|
end: points[(i + 1) % points.length],
|
|
176
206
|
thickness: wallThickness,
|
|
177
|
-
height: wallHeight,
|
|
207
|
+
...(wallHeight !== undefined ? { height: wallHeight } : {}),
|
|
178
208
|
frontSide: 'exterior',
|
|
179
209
|
backSide: 'interior',
|
|
180
210
|
...(wallMaterialPreset ? { materialPreset: wallMaterialPreset } : {}),
|
|
@@ -189,6 +219,11 @@ export function registerConstructionTools(server, bridge) {
|
|
|
189
219
|
name: namePrefix ? `${namePrefix} Slab` : undefined,
|
|
190
220
|
polygon: points,
|
|
191
221
|
elevation: slabElevation,
|
|
222
|
+
// Grounded solid: underside on the level plane, so the created
|
|
223
|
+
// story slab occupies [0, slabElevation] like the legacy
|
|
224
|
+
// extrude-from-zero model.
|
|
225
|
+
thickness: Math.max(slabElevation, 0),
|
|
226
|
+
recessed: slabElevation < 0,
|
|
192
227
|
...(slabMaterialPreset ? { materialPreset: slabMaterialPreset } : {}),
|
|
193
228
|
metadata: { role: 'story-slab' },
|
|
194
229
|
});
|
|
@@ -197,10 +232,13 @@ export function registerConstructionTools(server, bridge) {
|
|
|
197
232
|
}
|
|
198
233
|
let ceilingId = null;
|
|
199
234
|
if (createCeiling) {
|
|
235
|
+
// Height-less unless the caller pinned one: a new story ceiling
|
|
236
|
+
// follows the level top automatically.
|
|
237
|
+
const explicitCeilingHeight = ceilingHeight ?? wallHeight;
|
|
200
238
|
const ceiling = CeilingNode.parse({
|
|
201
239
|
name: namePrefix ? `${namePrefix} Ceiling` : undefined,
|
|
202
240
|
polygon: points,
|
|
203
|
-
height:
|
|
241
|
+
...(explicitCeilingHeight !== undefined ? { height: explicitCeilingHeight } : {}),
|
|
204
242
|
...(ceilingMaterialPreset ? { materialPreset: ceilingMaterialPreset } : {}),
|
|
205
243
|
metadata: { role: 'story-ceiling' },
|
|
206
244
|
});
|
|
@@ -242,12 +280,12 @@ export function registerConstructionTools(server, bridge) {
|
|
|
242
280
|
const roofLevel = LevelNode.parse({
|
|
243
281
|
name: roofLevelLabel,
|
|
244
282
|
level: roofLevelElevation ?? nextLevelIndex(bridge, buildingId, referenceLevel),
|
|
283
|
+
height: roofLevelHeight ?? Math.max(wallHeight + peakHeight, 0.2),
|
|
245
284
|
children: [],
|
|
246
285
|
metadata: {
|
|
247
286
|
role: 'roof',
|
|
248
287
|
label: roofLevelLabel,
|
|
249
288
|
referenceLevelId: levelId,
|
|
250
|
-
height: roofLevelHeight ?? Math.max(wallHeight + peakHeight, 0.2),
|
|
251
289
|
},
|
|
252
290
|
});
|
|
253
291
|
targetRoofLevelId = roofLevel.id;
|
|
@@ -299,15 +337,7 @@ export function registerConstructionTools(server, bridge) {
|
|
|
299
337
|
if (isRoofLevel(fromLevel) || isRoofLevel(toLevel)) {
|
|
300
338
|
throw new Error('Roof support levels are not occupied stories; create a separate occupied attic/story level if a stair-accessible attic is required');
|
|
301
339
|
}
|
|
302
|
-
const
|
|
303
|
-
segmentType: 'stair',
|
|
304
|
-
width,
|
|
305
|
-
length: runLength,
|
|
306
|
-
height: totalRise,
|
|
307
|
-
stepCount,
|
|
308
|
-
...(materialPreset ? { materialPreset } : {}),
|
|
309
|
-
});
|
|
310
|
-
const stair = StairNode.parse({
|
|
340
|
+
const stairDraft = StairNode.parse({
|
|
311
341
|
name: name ?? 'Stair',
|
|
312
342
|
position: position,
|
|
313
343
|
rotation,
|
|
@@ -317,15 +347,33 @@ export function registerConstructionTools(server, bridge) {
|
|
|
317
347
|
slabOpeningMode: 'none',
|
|
318
348
|
openingOffset,
|
|
319
349
|
width,
|
|
320
|
-
totalRise,
|
|
350
|
+
...(totalRise !== undefined ? { totalRise } : {}),
|
|
321
351
|
stepCount,
|
|
322
352
|
railingMode,
|
|
323
|
-
children: [
|
|
353
|
+
children: [],
|
|
324
354
|
...(materialPreset ? { materialPreset } : {}),
|
|
325
355
|
metadata: {
|
|
326
356
|
openingManaged: 'manual-rectangular',
|
|
327
357
|
},
|
|
328
358
|
});
|
|
359
|
+
const riseNodes = {
|
|
360
|
+
...bridge.getNodes(),
|
|
361
|
+
[fromLevel.id]: {
|
|
362
|
+
...fromLevel,
|
|
363
|
+
children: [...fromLevel.children, stairDraft.id],
|
|
364
|
+
},
|
|
365
|
+
[stairDraft.id]: stairDraft,
|
|
366
|
+
};
|
|
367
|
+
const resolvedTotalRise = resolveStairTotalRise(stairDraft, riseNodes);
|
|
368
|
+
const segment = StairSegmentNode.parse({
|
|
369
|
+
segmentType: 'stair',
|
|
370
|
+
width,
|
|
371
|
+
length: runLength,
|
|
372
|
+
height: resolvedTotalRise,
|
|
373
|
+
stepCount,
|
|
374
|
+
...(materialPreset ? { materialPreset } : {}),
|
|
375
|
+
});
|
|
376
|
+
const stair = { ...stairDraft, children: [segment.id] };
|
|
329
377
|
const openingPolygon = rectangularOpening({
|
|
330
378
|
position: position,
|
|
331
379
|
rotation,
|
|
@@ -4,7 +4,7 @@ import type { SceneOperations } from '../operations';
|
|
|
4
4
|
export declare const createLevelInput: {
|
|
5
5
|
buildingId: z.ZodString;
|
|
6
6
|
elevation: z.ZodOptional<z.ZodNumber>;
|
|
7
|
-
height: z.ZodOptional<z.ZodNumber
|
|
7
|
+
height: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
8
8
|
label: z.ZodOptional<z.ZodString>;
|
|
9
9
|
};
|
|
10
10
|
export declare const createLevelOutput: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-level.d.ts","sourceRoot":"","sources":["../../src/tools/create-level.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;
|
|
1
|
+
{"version":3,"file":"create-level.d.ts","sourceRoot":"","sources":["../../src/tools/create-level.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAIxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAMpD,eAAO,MAAM,gBAAgB;;;;;CAW5B,CAAA;AAED,eAAO,MAAM,iBAAiB;;CAE7B,CAAA;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CA+CpF"}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
import { DEFAULT_LEVEL_HEIGHT } from '@pascal-app/core';
|
|
1
2
|
import { LevelNode } from '@pascal-app/core/schema';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { ErrorCode, throwMcpError } from './errors';
|
|
4
5
|
import { publishLiveSceneSnapshot } from './live-sync';
|
|
6
|
+
import { measurement } from './measurement';
|
|
5
7
|
import { NodeIdSchema } from './schemas';
|
|
6
8
|
export const createLevelInput = {
|
|
7
9
|
buildingId: NodeIdSchema,
|
|
8
|
-
elevation: z
|
|
9
|
-
|
|
10
|
+
elevation: z
|
|
11
|
+
.number()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Legacy parameter; new levels are appended above the building's current top level."),
|
|
14
|
+
height: measurement('length', 'm', {
|
|
15
|
+
min: 0,
|
|
16
|
+
description: 'Stored floor-to-floor storey height.',
|
|
17
|
+
}).optional(),
|
|
10
18
|
label: z.string().optional(),
|
|
11
19
|
};
|
|
12
20
|
export const createLevelOutput = {
|
|
@@ -15,10 +23,10 @@ export const createLevelOutput = {
|
|
|
15
23
|
export function registerCreateLevel(server, bridge) {
|
|
16
24
|
server.registerTool('create_level', {
|
|
17
25
|
title: 'Create level',
|
|
18
|
-
description:
|
|
26
|
+
description: "Append a new level above the given building's current top level. height is stored as the level's floor-to-floor storey height.",
|
|
19
27
|
inputSchema: createLevelInput,
|
|
20
28
|
outputSchema: createLevelOutput,
|
|
21
|
-
}, async ({ buildingId,
|
|
29
|
+
}, async ({ buildingId, height, label }) => {
|
|
22
30
|
const parent = bridge.getNode(buildingId);
|
|
23
31
|
if (!parent) {
|
|
24
32
|
throwMcpError(ErrorCode.InvalidParams, `Building not found: ${buildingId}`);
|
|
@@ -27,12 +35,16 @@ export function registerCreateLevel(server, bridge) {
|
|
|
27
35
|
throwMcpError(ErrorCode.InvalidParams, `Node ${buildingId} is a ${parent.type}, expected building`);
|
|
28
36
|
}
|
|
29
37
|
const metadata = {};
|
|
30
|
-
if (height !== undefined)
|
|
31
|
-
metadata.height = height;
|
|
32
38
|
if (label !== undefined)
|
|
33
39
|
metadata.label = label;
|
|
40
|
+
const existingOrdinals = bridge
|
|
41
|
+
.getChildren(buildingId)
|
|
42
|
+
.filter((node) => node.type === 'level')
|
|
43
|
+
.map((node) => node.level);
|
|
44
|
+
const nextOrdinal = Math.max(-1, ...existingOrdinals) + 1;
|
|
34
45
|
const levelNode = LevelNode.parse({
|
|
35
|
-
level:
|
|
46
|
+
level: nextOrdinal,
|
|
47
|
+
height: height ?? DEFAULT_LEVEL_HEIGHT,
|
|
36
48
|
children: [],
|
|
37
49
|
...(Object.keys(metadata).length > 0 ? { metadata } : {}),
|
|
38
50
|
...(label !== undefined ? { name: label } : {}),
|
|
@@ -5,8 +5,8 @@ export declare const createWallInput: {
|
|
|
5
5
|
levelId: z.ZodString;
|
|
6
6
|
start: z.ZodArray<z.ZodNumber>;
|
|
7
7
|
end: z.ZodArray<z.ZodNumber>;
|
|
8
|
-
thickness: z.ZodOptional<z.ZodNumber
|
|
9
|
-
height: z.ZodOptional<z.ZodNumber
|
|
8
|
+
thickness: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
9
|
+
height: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
|
|
10
10
|
};
|
|
11
11
|
export declare const createWallOutput: {
|
|
12
12
|
wallId: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-wall.d.ts","sourceRoot":"","sources":["../../src/tools/create-wall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"create-wall.d.ts","sourceRoot":"","sources":["../../src/tools/create-wall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAMpD,eAAO,MAAM,eAAe;;;;;;CAS3B,CAAA;AAED,eAAO,MAAM,gBAAgB;;CAE5B,CAAA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAgDnF"}
|
|
@@ -2,13 +2,17 @@ import { WallNode } from '@pascal-app/core/schema';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { ErrorCode, throwMcpError } from './errors';
|
|
4
4
|
import { publishLiveSceneSnapshot } from './live-sync';
|
|
5
|
+
import { measurement } from './measurement';
|
|
5
6
|
import { NodeIdSchema, Vec2Schema } from './schemas';
|
|
6
7
|
export const createWallInput = {
|
|
7
8
|
levelId: NodeIdSchema,
|
|
8
9
|
start: Vec2Schema,
|
|
9
10
|
end: Vec2Schema,
|
|
10
|
-
thickness:
|
|
11
|
-
|
|
11
|
+
thickness: measurement('length', 'm', {
|
|
12
|
+
positive: true,
|
|
13
|
+
description: 'Wall thickness.',
|
|
14
|
+
}).optional(),
|
|
15
|
+
height: measurement('length', 'm', { positive: true, description: 'Wall height.' }).optional(),
|
|
12
16
|
};
|
|
13
17
|
export const createWallOutput = {
|
|
14
18
|
wallId: z.string(),
|
|
@@ -4,12 +4,12 @@ import type { SceneOperations } from '../operations';
|
|
|
4
4
|
export declare const cutOpeningInput: {
|
|
5
5
|
wallId: z.ZodString;
|
|
6
6
|
type: z.ZodEnum<{
|
|
7
|
-
window: "window";
|
|
8
7
|
door: "door";
|
|
8
|
+
window: "window";
|
|
9
9
|
}>;
|
|
10
10
|
position: z.ZodNumber;
|
|
11
|
-
width: z.ZodNumber
|
|
12
|
-
height: z.ZodNumber
|
|
11
|
+
width: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
|
|
12
|
+
height: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
|
|
13
13
|
};
|
|
14
14
|
export declare const cutOpeningOutput: {
|
|
15
15
|
openingId: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cut-opening.d.ts","sourceRoot":"","sources":["../../src/tools/cut-opening.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"cut-opening.d.ts","sourceRoot":"","sources":["../../src/tools/cut-opening.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAOpD,eAAO,MAAM,eAAe;;;;;;;;;CAM3B,CAAA;AAED,eAAO,MAAM,gBAAgB;;CAE5B,CAAA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAyDnF"}
|
|
@@ -3,13 +3,14 @@ import { z } from 'zod';
|
|
|
3
3
|
import { ErrorCode, throwMcpError } from './errors';
|
|
4
4
|
import { wallLength, wallLocalXFromT } from './geometry';
|
|
5
5
|
import { publishLiveSceneSnapshot } from './live-sync';
|
|
6
|
+
import { measurement } from './measurement';
|
|
6
7
|
import { NodeIdSchema } from './schemas';
|
|
7
8
|
export const cutOpeningInput = {
|
|
8
9
|
wallId: NodeIdSchema,
|
|
9
10
|
type: z.enum(['door', 'window']),
|
|
10
11
|
position: z.number().min(0).max(1),
|
|
11
|
-
width:
|
|
12
|
-
height:
|
|
12
|
+
width: measurement('length', 'm', { positive: true, description: 'Opening width.' }),
|
|
13
|
+
height: measurement('length', 'm', { positive: true, description: 'Opening height.' }),
|
|
13
14
|
};
|
|
14
15
|
export const cutOpeningOutput = {
|
|
15
16
|
openingId: z.string(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe-node.d.ts","sourceRoot":"","sources":["../../src/tools/describe-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;
|
|
1
|
+
{"version":3,"file":"describe-node.d.ts","sourceRoot":"","sources":["../../src/tools/describe-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAKpD,eAAO,MAAM,iBAAiB;;CAE7B,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;CAQ9B,CAAA;AA0CD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAgDrF"}
|