@pascal-app/core 0.5.0 → 0.6.0

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.
Files changed (99) hide show
  1. package/dist/events/bus.d.ts +39 -4
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/events/bus.js +1 -1
  4. package/dist/hooks/scene-registry/scene-registry.d.ts +1 -0
  5. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  6. package/dist/hooks/scene-registry/scene-registry.js +1 -0
  7. package/dist/hooks/spatial-grid/spatial-grid.d.ts +2 -0
  8. package/dist/hooks/spatial-grid/spatial-grid.d.ts.map +1 -1
  9. package/dist/hooks/spatial-grid/spatial-grid.js +43 -20
  10. package/dist/index.d.ts +6 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +5 -1
  13. package/dist/lib/polygon-geometry.d.ts +3 -0
  14. package/dist/lib/polygon-geometry.d.ts.map +1 -0
  15. package/dist/lib/polygon-geometry.js +90 -0
  16. package/dist/lib/space-detection.d.ts +10 -17
  17. package/dist/lib/space-detection.d.ts.map +1 -1
  18. package/dist/lib/space-detection.js +666 -453
  19. package/dist/material-library.d.ts +18 -0
  20. package/dist/material-library.d.ts.map +1 -0
  21. package/dist/material-library.js +603 -0
  22. package/dist/schema/index.d.ts +10 -4
  23. package/dist/schema/index.d.ts.map +1 -1
  24. package/dist/schema/index.js +6 -4
  25. package/dist/schema/material.d.ts +109 -0
  26. package/dist/schema/material.d.ts.map +1 -1
  27. package/dist/schema/material.js +52 -0
  28. package/dist/schema/nodes/ceiling.d.ts +10 -0
  29. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  30. package/dist/schema/nodes/ceiling.js +6 -0
  31. package/dist/schema/nodes/door.d.ts +1 -0
  32. package/dist/schema/nodes/door.d.ts.map +1 -1
  33. package/dist/schema/nodes/fence.d.ts +85 -0
  34. package/dist/schema/nodes/fence.d.ts.map +1 -0
  35. package/dist/schema/nodes/fence.js +34 -0
  36. package/dist/schema/nodes/item.d.ts +2 -2
  37. package/dist/schema/nodes/level.d.ts +1 -1
  38. package/dist/schema/nodes/level.d.ts.map +1 -1
  39. package/dist/schema/nodes/level.js +2 -0
  40. package/dist/schema/nodes/roof-segment.d.ts +2 -0
  41. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  42. package/dist/schema/nodes/roof-segment.js +1 -0
  43. package/dist/schema/nodes/roof.d.ts +108 -0
  44. package/dist/schema/nodes/roof.d.ts.map +1 -1
  45. package/dist/schema/nodes/roof.js +58 -2
  46. package/dist/schema/nodes/site.d.ts +1 -1
  47. package/dist/schema/nodes/slab.d.ts +10 -0
  48. package/dist/schema/nodes/slab.d.ts.map +1 -1
  49. package/dist/schema/nodes/slab.js +7 -0
  50. package/dist/schema/nodes/stair-segment.d.ts +2 -0
  51. package/dist/schema/nodes/stair-segment.d.ts.map +1 -1
  52. package/dist/schema/nodes/stair-segment.js +1 -0
  53. package/dist/schema/nodes/stair.d.ts +164 -0
  54. package/dist/schema/nodes/stair.d.ts.map +1 -1
  55. package/dist/schema/nodes/stair.js +106 -5
  56. package/dist/schema/nodes/surface-hole-metadata.d.ts +10 -0
  57. package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -0
  58. package/dist/schema/nodes/surface-hole-metadata.js +5 -0
  59. package/dist/schema/nodes/wall.d.ts +87 -1
  60. package/dist/schema/nodes/wall.d.ts.map +1 -1
  61. package/dist/schema/nodes/wall.js +45 -4
  62. package/dist/schema/nodes/window.d.ts +1 -0
  63. package/dist/schema/nodes/window.d.ts.map +1 -1
  64. package/dist/schema/types.d.ts +406 -4
  65. package/dist/schema/types.d.ts.map +1 -1
  66. package/dist/schema/types.js +2 -0
  67. package/dist/store/actions/node-actions.d.ts +1 -1
  68. package/dist/store/actions/node-actions.d.ts.map +1 -1
  69. package/dist/store/actions/node-actions.js +175 -0
  70. package/dist/store/history-control.d.ts +14 -0
  71. package/dist/store/history-control.d.ts.map +1 -0
  72. package/dist/store/history-control.js +22 -0
  73. package/dist/store/use-scene.d.ts.map +1 -1
  74. package/dist/store/use-scene.js +249 -3
  75. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  76. package/dist/systems/ceiling/ceiling-system.js +7 -0
  77. package/dist/systems/fence/fence-system.d.ts +2 -0
  78. package/dist/systems/fence/fence-system.d.ts.map +1 -0
  79. package/dist/systems/fence/fence-system.js +187 -0
  80. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  81. package/dist/systems/roof/roof-system.js +31 -1
  82. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  83. package/dist/systems/slab/slab-system.js +45 -8
  84. package/dist/systems/stair/stair-opening-sync.d.ts +6 -0
  85. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -0
  86. package/dist/systems/stair/stair-opening-sync.js +515 -0
  87. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  88. package/dist/systems/stair/stair-system.js +432 -10
  89. package/dist/systems/wall/wall-curve.d.ts +43 -0
  90. package/dist/systems/wall/wall-curve.d.ts.map +1 -0
  91. package/dist/systems/wall/wall-curve.js +176 -0
  92. package/dist/systems/wall/wall-footprint.d.ts.map +1 -1
  93. package/dist/systems/wall/wall-footprint.js +16 -2
  94. package/dist/systems/wall/wall-mitering.d.ts +7 -0
  95. package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
  96. package/dist/systems/wall/wall-mitering.js +76 -3
  97. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  98. package/dist/systems/wall/wall-system.js +202 -2
  99. package/package.json +3 -3
@@ -1,12 +1,19 @@
1
1
  import dedent from 'dedent';
2
2
  import { z } from 'zod';
3
3
  import { BaseNode, nodeType, objectId } from '../base';
4
- import { MaterialSchema } from '../material';
4
+ import { MaterialSchema as MaterialSchemaSchema } from '../material';
5
5
  import { RoofSegmentNode } from './roof-segment';
6
6
  export const RoofNode = BaseNode.extend({
7
7
  id: objectId('roof'),
8
8
  type: nodeType('roof'),
9
- material: MaterialSchema.optional(),
9
+ material: MaterialSchemaSchema.optional(),
10
+ materialPreset: z.string().optional(),
11
+ topMaterial: MaterialSchemaSchema.optional(),
12
+ topMaterialPreset: z.string().optional(),
13
+ edgeMaterial: MaterialSchemaSchema.optional(),
14
+ edgeMaterialPreset: z.string().optional(),
15
+ wallMaterial: MaterialSchemaSchema.optional(),
16
+ wallMaterialPreset: z.string().optional(),
10
17
  position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
11
18
  // Rotation around Y axis in radians
12
19
  rotation: z.number().default(0),
@@ -20,3 +27,52 @@ export const RoofNode = BaseNode.extend({
20
27
  - rotation: rotation around Y axis
21
28
  - children: array of RoofSegmentNode IDs
22
29
  `);
30
+ function getLegacyRoofSurfaceMaterial(node) {
31
+ return {
32
+ material: node.material,
33
+ materialPreset: node.materialPreset,
34
+ };
35
+ }
36
+ export function getEffectiveRoofSurfaceMaterial(node, role) {
37
+ if (role === 'top') {
38
+ if (node.topMaterial !== undefined || typeof node.topMaterialPreset === 'string') {
39
+ return {
40
+ material: node.topMaterial,
41
+ materialPreset: typeof node.topMaterialPreset === 'string' ? node.topMaterialPreset : undefined,
42
+ };
43
+ }
44
+ }
45
+ if (role === 'edge') {
46
+ if (node.edgeMaterial !== undefined || typeof node.edgeMaterialPreset === 'string') {
47
+ return {
48
+ material: node.edgeMaterial,
49
+ materialPreset: typeof node.edgeMaterialPreset === 'string' ? node.edgeMaterialPreset : undefined,
50
+ };
51
+ }
52
+ }
53
+ if (role === 'wall') {
54
+ if (node.wallMaterial !== undefined || typeof node.wallMaterialPreset === 'string') {
55
+ return {
56
+ material: node.wallMaterial,
57
+ materialPreset: typeof node.wallMaterialPreset === 'string' ? node.wallMaterialPreset : undefined,
58
+ };
59
+ }
60
+ }
61
+ if (role === 'edge') {
62
+ if (node.wallMaterial !== undefined || typeof node.wallMaterialPreset === 'string') {
63
+ return {
64
+ material: node.wallMaterial,
65
+ materialPreset: typeof node.wallMaterialPreset === 'string' ? node.wallMaterialPreset : undefined,
66
+ };
67
+ }
68
+ }
69
+ if (role === 'wall') {
70
+ if (node.edgeMaterial !== undefined || typeof node.edgeMaterialPreset === 'string') {
71
+ return {
72
+ material: node.edgeMaterial,
73
+ materialPreset: typeof node.edgeMaterialPreset === 'string' ? node.edgeMaterialPreset : undefined,
74
+ };
75
+ }
76
+ }
77
+ return getLegacyRoofSurfaceMaterial(node);
78
+ }
@@ -80,8 +80,8 @@ export declare const SiteNode: z.ZodObject<{
80
80
  dimensions: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
81
81
  attachTo: z.ZodOptional<z.ZodEnum<{
82
82
  wall: "wall";
83
- "wall-side": "wall-side";
84
83
  ceiling: "ceiling";
84
+ "wall-side": "wall-side";
85
85
  }>>;
86
86
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
87
87
  offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
@@ -18,6 +18,7 @@ export declare const SlabNode: z.ZodObject<{
18
18
  id: z.ZodDefault<z.ZodTemplateLiteral<`slab_${string}`>>;
19
19
  type: z.ZodDefault<z.ZodLiteral<"slab">>;
20
20
  material: z.ZodOptional<z.ZodObject<{
21
+ id: z.ZodOptional<z.ZodString>;
21
22
  preset: z.ZodOptional<z.ZodEnum<{
22
23
  custom: "custom";
23
24
  white: "white";
@@ -48,9 +49,18 @@ export declare const SlabNode: z.ZodObject<{
48
49
  scale: z.ZodOptional<z.ZodNumber>;
49
50
  }, z.core.$strip>>;
50
51
  }, z.core.$strip>>;
52
+ materialPreset: z.ZodOptional<z.ZodString>;
51
53
  polygon: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
52
54
  holes: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>>;
55
+ holeMetadata: z.ZodDefault<z.ZodArray<z.ZodObject<{
56
+ source: z.ZodDefault<z.ZodEnum<{
57
+ stair: "stair";
58
+ manual: "manual";
59
+ }>>;
60
+ stairId: z.ZodOptional<z.ZodString>;
61
+ }, z.core.$strip>>>;
53
62
  elevation: z.ZodDefault<z.ZodNumber>;
63
+ autoFromWalls: z.ZodDefault<z.ZodBoolean>;
54
64
  }, z.core.$strip>;
55
65
  export type SlabNode = z.infer<typeof SlabNode>;
56
66
  //# sourceMappingURL=slab.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slab.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/slab.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAapB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA"}
1
+ {"version":3,"file":"slab.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/slab.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmBpB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA"}
@@ -2,15 +2,22 @@ import dedent from 'dedent';
2
2
  import { z } from 'zod';
3
3
  import { BaseNode, nodeType, objectId } from '../base';
4
4
  import { MaterialSchema } from '../material';
5
+ import { SurfaceHoleMetadata } from './surface-hole-metadata';
5
6
  export const SlabNode = BaseNode.extend({
6
7
  id: objectId('slab'),
7
8
  type: nodeType('slab'),
8
9
  material: MaterialSchema.optional(),
10
+ materialPreset: z.string().optional(),
9
11
  polygon: z.array(z.tuple([z.number(), z.number()])),
10
12
  holes: z.array(z.array(z.tuple([z.number(), z.number()]))).default([]),
13
+ holeMetadata: z.array(SurfaceHoleMetadata).default([]),
11
14
  elevation: z.number().default(0.05), // Elevation in meters
15
+ autoFromWalls: z.boolean().default(false),
12
16
  }).describe(dedent `
13
17
  Slab node - used to represent a slab/floor in the building
14
18
  - polygon: array of [x, z] points defining the slab boundary
19
+ - holes: array of [x, z] polygons representing cutouts in the slab
20
+ - holeMetadata: metadata parallel to holes, used to preserve manual and stair-managed cutouts
15
21
  - elevation: elevation in meters
22
+ - autoFromWalls: whether the slab is automatically generated from a closed wall loop
16
23
  `);
@@ -29,6 +29,7 @@ export declare const StairSegmentNode: z.ZodObject<{
29
29
  id: z.ZodDefault<z.ZodTemplateLiteral<`sseg_${string}`>>;
30
30
  type: z.ZodDefault<z.ZodLiteral<"stair-segment">>;
31
31
  material: z.ZodOptional<z.ZodObject<{
32
+ id: z.ZodOptional<z.ZodString>;
32
33
  preset: z.ZodOptional<z.ZodEnum<{
33
34
  custom: "custom";
34
35
  white: "white";
@@ -59,6 +60,7 @@ export declare const StairSegmentNode: z.ZodObject<{
59
60
  scale: z.ZodOptional<z.ZodNumber>;
60
61
  }, z.core.$strip>>;
61
62
  }, z.core.$strip>>;
63
+ materialPreset: z.ZodOptional<z.ZodString>;
62
64
  position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
63
65
  rotation: z.ZodDefault<z.ZodNumber>;
64
66
  segmentType: z.ZodDefault<z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"stair-segment.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/stair-segment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,gBAAgB;;;EAA+B,CAAA;AAE5D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,cAAc;;;;EAAqC,CAAA;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqC5B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
1
+ {"version":3,"file":"stair-segment.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/stair-segment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,gBAAgB;;;EAA+B,CAAA;AAE5D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,cAAc;;;;EAAqC,CAAA;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsC5B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
@@ -8,6 +8,7 @@ export const StairSegmentNode = BaseNode.extend({
8
8
  id: objectId('sseg'),
9
9
  type: nodeType('stair-segment'),
10
10
  material: MaterialSchema.optional(),
11
+ materialPreset: z.string().optional(),
11
12
  position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
12
13
  // Rotation around Y axis in radians
13
14
  rotation: z.number().default(0),
@@ -1,4 +1,33 @@
1
1
  import { z } from 'zod';
2
+ import { type MaterialSchema } from '../material';
3
+ export declare const StairRailingMode: z.ZodEnum<{
4
+ left: "left";
5
+ right: "right";
6
+ none: "none";
7
+ both: "both";
8
+ }>;
9
+ export declare const StairType: z.ZodEnum<{
10
+ straight: "straight";
11
+ curved: "curved";
12
+ spiral: "spiral";
13
+ }>;
14
+ export declare const StairTopLandingMode: z.ZodEnum<{
15
+ none: "none";
16
+ integrated: "integrated";
17
+ }>;
18
+ export declare const StairSlabOpeningMode: z.ZodEnum<{
19
+ none: "none";
20
+ destination: "destination";
21
+ }>;
22
+ export type StairRailingMode = z.infer<typeof StairRailingMode>;
23
+ export type StairType = z.infer<typeof StairType>;
24
+ export type StairTopLandingMode = z.infer<typeof StairTopLandingMode>;
25
+ export type StairSlabOpeningMode = z.infer<typeof StairSlabOpeningMode>;
26
+ export type StairSurfaceMaterialRole = 'railing' | 'tread' | 'side';
27
+ export type StairSurfaceMaterialSpec = {
28
+ material?: MaterialSchema;
29
+ materialPreset?: string;
30
+ };
2
31
  export declare const StairNode: z.ZodObject<{
3
32
  object: z.ZodDefault<z.ZodLiteral<"node">>;
4
33
  name: z.ZodOptional<z.ZodString>;
@@ -18,6 +47,7 @@ export declare const StairNode: z.ZodObject<{
18
47
  id: z.ZodDefault<z.ZodTemplateLiteral<`stair_${string}`>>;
19
48
  type: z.ZodDefault<z.ZodLiteral<"stair">>;
20
49
  material: z.ZodOptional<z.ZodObject<{
50
+ id: z.ZodOptional<z.ZodString>;
21
51
  preset: z.ZodOptional<z.ZodEnum<{
22
52
  custom: "custom";
23
53
  white: "white";
@@ -48,9 +78,143 @@ export declare const StairNode: z.ZodObject<{
48
78
  scale: z.ZodOptional<z.ZodNumber>;
49
79
  }, z.core.$strip>>;
50
80
  }, z.core.$strip>>;
81
+ materialPreset: z.ZodOptional<z.ZodString>;
82
+ railingMaterial: z.ZodOptional<z.ZodObject<{
83
+ id: z.ZodOptional<z.ZodString>;
84
+ preset: z.ZodOptional<z.ZodEnum<{
85
+ custom: "custom";
86
+ white: "white";
87
+ brick: "brick";
88
+ concrete: "concrete";
89
+ wood: "wood";
90
+ glass: "glass";
91
+ metal: "metal";
92
+ plaster: "plaster";
93
+ tile: "tile";
94
+ marble: "marble";
95
+ }>>;
96
+ properties: z.ZodOptional<z.ZodObject<{
97
+ color: z.ZodDefault<z.ZodString>;
98
+ roughness: z.ZodDefault<z.ZodNumber>;
99
+ metalness: z.ZodDefault<z.ZodNumber>;
100
+ opacity: z.ZodDefault<z.ZodNumber>;
101
+ transparent: z.ZodDefault<z.ZodBoolean>;
102
+ side: z.ZodDefault<z.ZodEnum<{
103
+ front: "front";
104
+ back: "back";
105
+ double: "double";
106
+ }>>;
107
+ }, z.core.$strip>>;
108
+ texture: z.ZodOptional<z.ZodObject<{
109
+ url: z.ZodString;
110
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
111
+ scale: z.ZodOptional<z.ZodNumber>;
112
+ }, z.core.$strip>>;
113
+ }, z.core.$strip>>;
114
+ railingMaterialPreset: z.ZodOptional<z.ZodString>;
115
+ treadMaterial: z.ZodOptional<z.ZodObject<{
116
+ id: z.ZodOptional<z.ZodString>;
117
+ preset: z.ZodOptional<z.ZodEnum<{
118
+ custom: "custom";
119
+ white: "white";
120
+ brick: "brick";
121
+ concrete: "concrete";
122
+ wood: "wood";
123
+ glass: "glass";
124
+ metal: "metal";
125
+ plaster: "plaster";
126
+ tile: "tile";
127
+ marble: "marble";
128
+ }>>;
129
+ properties: z.ZodOptional<z.ZodObject<{
130
+ color: z.ZodDefault<z.ZodString>;
131
+ roughness: z.ZodDefault<z.ZodNumber>;
132
+ metalness: z.ZodDefault<z.ZodNumber>;
133
+ opacity: z.ZodDefault<z.ZodNumber>;
134
+ transparent: z.ZodDefault<z.ZodBoolean>;
135
+ side: z.ZodDefault<z.ZodEnum<{
136
+ front: "front";
137
+ back: "back";
138
+ double: "double";
139
+ }>>;
140
+ }, z.core.$strip>>;
141
+ texture: z.ZodOptional<z.ZodObject<{
142
+ url: z.ZodString;
143
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
144
+ scale: z.ZodOptional<z.ZodNumber>;
145
+ }, z.core.$strip>>;
146
+ }, z.core.$strip>>;
147
+ treadMaterialPreset: z.ZodOptional<z.ZodString>;
148
+ sideMaterial: z.ZodOptional<z.ZodObject<{
149
+ id: z.ZodOptional<z.ZodString>;
150
+ preset: z.ZodOptional<z.ZodEnum<{
151
+ custom: "custom";
152
+ white: "white";
153
+ brick: "brick";
154
+ concrete: "concrete";
155
+ wood: "wood";
156
+ glass: "glass";
157
+ metal: "metal";
158
+ plaster: "plaster";
159
+ tile: "tile";
160
+ marble: "marble";
161
+ }>>;
162
+ properties: z.ZodOptional<z.ZodObject<{
163
+ color: z.ZodDefault<z.ZodString>;
164
+ roughness: z.ZodDefault<z.ZodNumber>;
165
+ metalness: z.ZodDefault<z.ZodNumber>;
166
+ opacity: z.ZodDefault<z.ZodNumber>;
167
+ transparent: z.ZodDefault<z.ZodBoolean>;
168
+ side: z.ZodDefault<z.ZodEnum<{
169
+ front: "front";
170
+ back: "back";
171
+ double: "double";
172
+ }>>;
173
+ }, z.core.$strip>>;
174
+ texture: z.ZodOptional<z.ZodObject<{
175
+ url: z.ZodString;
176
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
177
+ scale: z.ZodOptional<z.ZodNumber>;
178
+ }, z.core.$strip>>;
179
+ }, z.core.$strip>>;
180
+ sideMaterialPreset: z.ZodOptional<z.ZodString>;
51
181
  position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
52
182
  rotation: z.ZodDefault<z.ZodNumber>;
183
+ stairType: z.ZodDefault<z.ZodEnum<{
184
+ straight: "straight";
185
+ curved: "curved";
186
+ spiral: "spiral";
187
+ }>>;
188
+ fromLevelId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
189
+ toLevelId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
190
+ slabOpeningMode: z.ZodDefault<z.ZodEnum<{
191
+ none: "none";
192
+ destination: "destination";
193
+ }>>;
194
+ openingOffset: z.ZodDefault<z.ZodNumber>;
195
+ width: z.ZodDefault<z.ZodNumber>;
196
+ totalRise: z.ZodDefault<z.ZodNumber>;
197
+ stepCount: z.ZodDefault<z.ZodNumber>;
198
+ thickness: z.ZodDefault<z.ZodNumber>;
199
+ fillToFloor: z.ZodDefault<z.ZodBoolean>;
200
+ innerRadius: z.ZodDefault<z.ZodNumber>;
201
+ sweepAngle: z.ZodDefault<z.ZodNumber>;
202
+ topLandingMode: z.ZodDefault<z.ZodEnum<{
203
+ none: "none";
204
+ integrated: "integrated";
205
+ }>>;
206
+ topLandingDepth: z.ZodDefault<z.ZodNumber>;
207
+ showCenterColumn: z.ZodDefault<z.ZodBoolean>;
208
+ showStepSupports: z.ZodDefault<z.ZodBoolean>;
209
+ railingMode: z.ZodDefault<z.ZodEnum<{
210
+ left: "left";
211
+ right: "right";
212
+ none: "none";
213
+ both: "both";
214
+ }>>;
215
+ railingHeight: z.ZodDefault<z.ZodNumber>;
53
216
  children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`sseg_${string}`>>>>;
54
217
  }, z.core.$strip>;
55
218
  export type StairNode = z.infer<typeof StairNode>;
219
+ export declare function getEffectiveStairSurfaceMaterial(node: StairNode, role: StairSurfaceMaterialRole): StairSurfaceMaterialSpec;
56
220
  //# sourceMappingURL=stair.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stair.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/stair.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
1
+ {"version":3,"file":"stair.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/stair.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,KAAK,cAAc,EAA0C,MAAM,aAAa,CAAA;AAGzF,eAAO,MAAM,gBAAgB;;;;;EAA4C,CAAA;AACzE,eAAO,MAAM,SAAS;;;;EAA2C,CAAA;AACjE,eAAO,MAAM,mBAAmB;;;EAAiC,CAAA;AACjE,eAAO,MAAM,oBAAoB;;;EAAkC,CAAA;AAEnE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AACjD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AACrE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACvE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;AACnE,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AASjD,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,wBAAwB,GAC7B,wBAAwB,CA2D1B"}
@@ -1,22 +1,123 @@
1
1
  import dedent from 'dedent';
2
2
  import { z } from 'zod';
3
3
  import { BaseNode, nodeType, objectId } from '../base';
4
- import { MaterialSchema } from '../material';
4
+ import { MaterialSchema as MaterialSchemaSchema } from '../material';
5
5
  import { StairSegmentNode } from './stair-segment';
6
+ export const StairRailingMode = z.enum(['none', 'left', 'right', 'both']);
7
+ export const StairType = z.enum(['straight', 'curved', 'spiral']);
8
+ export const StairTopLandingMode = z.enum(['none', 'integrated']);
9
+ export const StairSlabOpeningMode = z.enum(['none', 'destination']);
6
10
  export const StairNode = BaseNode.extend({
7
11
  id: objectId('stair'),
8
12
  type: nodeType('stair'),
9
- material: MaterialSchema.optional(),
13
+ material: MaterialSchemaSchema.optional(),
14
+ materialPreset: z.string().optional(),
15
+ railingMaterial: MaterialSchemaSchema.optional(),
16
+ railingMaterialPreset: z.string().optional(),
17
+ treadMaterial: MaterialSchemaSchema.optional(),
18
+ treadMaterialPreset: z.string().optional(),
19
+ sideMaterial: MaterialSchemaSchema.optional(),
20
+ sideMaterialPreset: z.string().optional(),
10
21
  position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
11
22
  // Rotation around Y axis in radians
12
23
  rotation: z.number().default(0),
24
+ stairType: StairType.default('straight'),
25
+ fromLevelId: z.string().nullable().default(null),
26
+ toLevelId: z.string().nullable().default(null),
27
+ slabOpeningMode: StairSlabOpeningMode.default('none'),
28
+ openingOffset: z.number().default(0),
29
+ width: z.number().default(1.0),
30
+ totalRise: z.number().default(2.5),
31
+ stepCount: z.number().default(10),
32
+ thickness: z.number().default(0.25),
33
+ fillToFloor: z.boolean().default(true),
34
+ innerRadius: z.number().default(0.9),
35
+ sweepAngle: z.number().default(Math.PI / 2),
36
+ topLandingMode: StairTopLandingMode.default('none'),
37
+ topLandingDepth: z.number().default(0.9),
38
+ showCenterColumn: z.boolean().default(true),
39
+ showStepSupports: z.boolean().default(true),
40
+ railingMode: StairRailingMode.default('none'),
41
+ railingHeight: z.number().default(0.92),
13
42
  // Child stair segment IDs
14
43
  children: z.array(StairSegmentNode.shape.id).default([]),
15
44
  }).describe(dedent `
16
45
  Stair node - a container for stair segments.
17
- Acts as a group that holds one or more StairSegmentNodes (flights and landings).
18
- Segments chain together based on their attachmentSide to form complex staircase shapes.
46
+ Acts as a group that either holds one or more StairSegmentNodes (straight stairs)
47
+ or stores stair-level geometry properties for curved stairs.
19
48
  - position: center position of the stair group
20
49
  - rotation: rotation around Y axis
21
- - children: array of StairSegmentNode IDs
50
+ - stairType: straight (segment-based), curved (arc-based), or spiral
51
+ - fromLevelId / toLevelId: source and destination levels used for auto slab cutouts
52
+ - slabOpeningMode: whether a destination-level slab opening is generated for this stair
53
+ - openingOffset: extra opening expansion applied after the cutout polygon is computed
54
+ - width: stair width
55
+ - totalRise: total stair height
56
+ - stepCount: number of visible steps
57
+ - thickness: stair slab / tread thickness
58
+ - fillToFloor: whether the stair mass fills down to the floor or uses tread thickness only
59
+ - innerRadius: inner curve radius for curved stairs
60
+ - sweepAngle: total curved stair sweep in radians
61
+ - topLandingMode: optional integrated top landing for spiral stairs
62
+ - topLandingDepth: depth used to size the integrated spiral top landing
63
+ - showCenterColumn: whether spiral stairs render a center column
64
+ - showStepSupports: whether spiral stairs render step support brackets
65
+ - railingMode: whether to render railings and on which side(s)
66
+ - railingHeight: top height of the railing above the stair surface
67
+ - children: array of StairSegmentNode IDs for straight stairs
22
68
  `);
69
+ function getLegacyStairSurfaceMaterial(node) {
70
+ return {
71
+ material: node.material,
72
+ materialPreset: node.materialPreset,
73
+ };
74
+ }
75
+ export function getEffectiveStairSurfaceMaterial(node, role) {
76
+ if (role === 'railing') {
77
+ if (node.railingMaterial !== undefined || typeof node.railingMaterialPreset === 'string') {
78
+ return {
79
+ material: node.railingMaterial,
80
+ materialPreset: typeof node.railingMaterialPreset === 'string' ? node.railingMaterialPreset : undefined,
81
+ };
82
+ }
83
+ }
84
+ if (role === 'tread') {
85
+ if (node.treadMaterial !== undefined || typeof node.treadMaterialPreset === 'string') {
86
+ return {
87
+ material: node.treadMaterial,
88
+ materialPreset: typeof node.treadMaterialPreset === 'string' ? node.treadMaterialPreset : undefined,
89
+ };
90
+ }
91
+ }
92
+ if (role === 'side') {
93
+ if (node.sideMaterial !== undefined || typeof node.sideMaterialPreset === 'string') {
94
+ return {
95
+ material: node.sideMaterial,
96
+ materialPreset: typeof node.sideMaterialPreset === 'string' ? node.sideMaterialPreset : undefined,
97
+ };
98
+ }
99
+ }
100
+ const treadFallback = {
101
+ material: node.treadMaterial,
102
+ materialPreset: typeof node.treadMaterialPreset === 'string' ? node.treadMaterialPreset : undefined,
103
+ };
104
+ const sideFallback = {
105
+ material: node.sideMaterial,
106
+ materialPreset: typeof node.sideMaterialPreset === 'string' ? node.sideMaterialPreset : undefined,
107
+ };
108
+ if (role === 'tread' && (sideFallback.material !== undefined || sideFallback.materialPreset !== undefined)) {
109
+ return sideFallback;
110
+ }
111
+ if (role === 'side' && (treadFallback.material !== undefined || treadFallback.materialPreset !== undefined)) {
112
+ return treadFallback;
113
+ }
114
+ if (role === 'railing') {
115
+ if (treadFallback.material !== undefined || treadFallback.materialPreset !== undefined) {
116
+ return treadFallback;
117
+ }
118
+ if (sideFallback.material !== undefined || sideFallback.materialPreset !== undefined) {
119
+ return sideFallback;
120
+ }
121
+ }
122
+ return getLegacyStairSurfaceMaterial(node);
123
+ }
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ export declare const SurfaceHoleMetadata: z.ZodObject<{
3
+ source: z.ZodDefault<z.ZodEnum<{
4
+ stair: "stair";
5
+ manual: "manual";
6
+ }>>;
7
+ stairId: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strip>;
9
+ export type SurfaceHoleMetadata = z.infer<typeof SurfaceHoleMetadata>;
10
+ //# sourceMappingURL=surface-hole-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-hole-metadata.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/surface-hole-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,mBAAmB;;;;;;iBAG9B,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+ export const SurfaceHoleMetadata = z.object({
3
+ source: z.enum(['manual', 'stair']).default('manual'),
4
+ stairId: z.string().optional(),
5
+ });
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { MaterialSchema } from '../material';
2
3
  export declare const WallNode: z.ZodObject<{
3
4
  object: z.ZodDefault<z.ZodLiteral<"node">>;
4
5
  name: z.ZodOptional<z.ZodString>;
@@ -17,8 +18,9 @@ export declare const WallNode: z.ZodObject<{
17
18
  metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
18
19
  id: z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>;
19
20
  type: z.ZodDefault<z.ZodLiteral<"wall">>;
20
- children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>>>;
21
+ children: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`door_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`window_${string}`>>]>>>;
21
22
  material: z.ZodOptional<z.ZodObject<{
23
+ id: z.ZodOptional<z.ZodString>;
22
24
  preset: z.ZodOptional<z.ZodEnum<{
23
25
  custom: "custom";
24
26
  white: "white";
@@ -49,8 +51,76 @@ export declare const WallNode: z.ZodObject<{
49
51
  scale: z.ZodOptional<z.ZodNumber>;
50
52
  }, z.core.$strip>>;
51
53
  }, z.core.$strip>>;
54
+ materialPreset: z.ZodOptional<z.ZodString>;
55
+ interiorMaterial: z.ZodOptional<z.ZodObject<{
56
+ id: z.ZodOptional<z.ZodString>;
57
+ preset: z.ZodOptional<z.ZodEnum<{
58
+ custom: "custom";
59
+ white: "white";
60
+ brick: "brick";
61
+ concrete: "concrete";
62
+ wood: "wood";
63
+ glass: "glass";
64
+ metal: "metal";
65
+ plaster: "plaster";
66
+ tile: "tile";
67
+ marble: "marble";
68
+ }>>;
69
+ properties: z.ZodOptional<z.ZodObject<{
70
+ color: z.ZodDefault<z.ZodString>;
71
+ roughness: z.ZodDefault<z.ZodNumber>;
72
+ metalness: z.ZodDefault<z.ZodNumber>;
73
+ opacity: z.ZodDefault<z.ZodNumber>;
74
+ transparent: z.ZodDefault<z.ZodBoolean>;
75
+ side: z.ZodDefault<z.ZodEnum<{
76
+ front: "front";
77
+ back: "back";
78
+ double: "double";
79
+ }>>;
80
+ }, z.core.$strip>>;
81
+ texture: z.ZodOptional<z.ZodObject<{
82
+ url: z.ZodString;
83
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
84
+ scale: z.ZodOptional<z.ZodNumber>;
85
+ }, z.core.$strip>>;
86
+ }, z.core.$strip>>;
87
+ interiorMaterialPreset: z.ZodOptional<z.ZodString>;
88
+ exteriorMaterial: z.ZodOptional<z.ZodObject<{
89
+ id: z.ZodOptional<z.ZodString>;
90
+ preset: z.ZodOptional<z.ZodEnum<{
91
+ custom: "custom";
92
+ white: "white";
93
+ brick: "brick";
94
+ concrete: "concrete";
95
+ wood: "wood";
96
+ glass: "glass";
97
+ metal: "metal";
98
+ plaster: "plaster";
99
+ tile: "tile";
100
+ marble: "marble";
101
+ }>>;
102
+ properties: z.ZodOptional<z.ZodObject<{
103
+ color: z.ZodDefault<z.ZodString>;
104
+ roughness: z.ZodDefault<z.ZodNumber>;
105
+ metalness: z.ZodDefault<z.ZodNumber>;
106
+ opacity: z.ZodDefault<z.ZodNumber>;
107
+ transparent: z.ZodDefault<z.ZodBoolean>;
108
+ side: z.ZodDefault<z.ZodEnum<{
109
+ front: "front";
110
+ back: "back";
111
+ double: "double";
112
+ }>>;
113
+ }, z.core.$strip>>;
114
+ texture: z.ZodOptional<z.ZodObject<{
115
+ url: z.ZodString;
116
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
117
+ scale: z.ZodOptional<z.ZodNumber>;
118
+ }, z.core.$strip>>;
119
+ }, z.core.$strip>>;
120
+ exteriorMaterialPreset: z.ZodOptional<z.ZodString>;
52
121
  thickness: z.ZodOptional<z.ZodNumber>;
53
122
  height: z.ZodOptional<z.ZodNumber>;
123
+ curveOffset: z.ZodOptional<z.ZodNumber>;
54
124
  start: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
55
125
  end: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
56
126
  frontSide: z.ZodDefault<z.ZodEnum<{
@@ -65,4 +135,20 @@ export declare const WallNode: z.ZodObject<{
65
135
  }>>;
66
136
  }, z.core.$strip>;
67
137
  export type WallNode = z.infer<typeof WallNode>;
138
+ export type WallSurfaceSide = 'interior' | 'exterior';
139
+ export type WallSurfaceMaterialSpec = {
140
+ material?: z.infer<typeof MaterialSchema>;
141
+ materialPreset?: string;
142
+ };
143
+ type WallSurfaceMaterialSource = {
144
+ material?: z.infer<typeof MaterialSchema>;
145
+ materialPreset?: string;
146
+ interiorMaterial?: z.infer<typeof MaterialSchema>;
147
+ interiorMaterialPreset?: string;
148
+ exteriorMaterial?: z.infer<typeof MaterialSchema>;
149
+ exteriorMaterialPreset?: string;
150
+ };
151
+ export declare function getEffectiveWallSurfaceMaterial(wall: WallSurfaceMaterialSource, side: WallSurfaceSide): WallSurfaceMaterialSpec;
152
+ export declare function getWallSurfaceMaterialSignature(spec: WallSurfaceMaterialSpec): string;
153
+ export {};
68
154
  //# sourceMappingURL=wall.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wall.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/wall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQvB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwBpB,CAAA;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA"}
1
+ {"version":3,"file":"wall.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/wall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAK5C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCpB,CAAA;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAE/C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,CAAA;AAErD,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACzC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACzC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACjD,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACjD,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,CAAA;AAuBD,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,yBAAyB,EAC/B,IAAI,EAAE,eAAe,GACpB,uBAAuB,CAUzB;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAKrF"}