@things-factory/figure-service 10.1.204 → 10.1.206

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 (83) hide show
  1. package/dist-server/service/figure/event-subscriber.js +5 -0
  2. package/dist-server/service/figure/event-subscriber.js.map +1 -1
  3. package/dist-server/service/figure/figure-format.d.ts +7 -0
  4. package/dist-server/service/figure/figure-format.js +25 -3
  5. package/dist-server/service/figure/figure-format.js.map +1 -1
  6. package/dist-server/service/figure/figure-mutation.js +2 -0
  7. package/dist-server/service/figure/figure-mutation.js.map +1 -1
  8. package/dist-server/service/figure/figure-query.js +3 -5
  9. package/dist-server/service/figure/figure-query.js.map +1 -1
  10. package/dist-server/service/figure/figure-revert.js +1 -1
  11. package/dist-server/service/figure/figure-revert.js.map +1 -1
  12. package/dist-server/tsconfig.tsbuildinfo +1 -1
  13. package/package.json +8 -8
  14. package/recipes/_lib/model.mts +7 -0
  15. package/recipes/base-frame/recipe.json +4 -8
  16. package/recipes/belt-surface/recipe.json +2 -4
  17. package/recipes/bin-row/recipe.json +1 -2
  18. package/recipes/bollard-row/recipe.json +1 -2
  19. package/recipes/cabinet-doors/recipe.json +5 -10
  20. package/recipes/cable-tray/recipe.json +3 -6
  21. package/recipes/canopy/recipe.json +2 -4
  22. package/recipes/cart-handle/recipe.json +1 -2
  23. package/recipes/ceiling-rail-carriage/recipe.json +1 -2
  24. package/recipes/chain-rails/recipe.json +2 -4
  25. package/recipes/column-row/recipe.json +1 -2
  26. package/recipes/conveyor-skirts/recipe.json +4 -8
  27. package/recipes/double-hinged-door/recipe.json +6 -12
  28. package/recipes/drawer-stack/recipe.json +13 -26
  29. package/recipes/drip-tray/recipe.json +2 -4
  30. package/recipes/end-covers/recipe.json +4 -8
  31. package/recipes/ffu-row/recipe.json +1 -2
  32. package/recipes/floor-zone/recipe.json +4 -8
  33. package/recipes/folding-door/recipe.json +3 -6
  34. package/recipes/gantry-frame/recipe.json +1 -2
  35. package/recipes/guard-cover/recipe.json +2 -4
  36. package/recipes/handrail/recipe.json +2 -4
  37. package/recipes/hatch/recipe.json +4 -8
  38. package/recipes/hinged-door/recipe.json +4 -8
  39. package/recipes/hopper/recipe.json +1 -2
  40. package/recipes/ladder/recipe.json +3 -6
  41. package/recipes/lift-updown/recipe.json +2 -4
  42. package/recipes/linear-guide/recipe.json +1 -2
  43. package/recipes/locker-row/recipe.json +1 -2
  44. package/recipes/observation-window/recipe.json +4 -8
  45. package/recipes/operator-panel/recipe.json +4 -8
  46. package/recipes/partition-wall/recipe.json +3 -6
  47. package/recipes/peg-board/facts.md +1 -1
  48. package/recipes/peg-board/recipe.json +1 -2
  49. package/recipes/pipe-run/recipe.json +1 -2
  50. package/recipes/platform/recipe.json +2 -4
  51. package/recipes/pull-cord/recipe.json +1 -2
  52. package/recipes/roll-up-shutter/recipe.json +3 -6
  53. package/recipes/roller-row/recipe.json +2 -4
  54. package/recipes/room-shell/recipe.json +6 -12
  55. package/recipes/safety-fence/recipe.json +2 -4
  56. package/recipes/safety-mat/recipe.json +1 -2
  57. package/recipes/safety-sign-stand/build.mts +2 -1
  58. package/recipes/safety-sign-stand/models/default.json +1 -1
  59. package/recipes/safety-sign-stand/recipe.json +5 -6
  60. package/recipes/shelf-tiers/recipe.json +5 -10
  61. package/recipes/side-guides/recipe.json +2 -4
  62. package/recipes/sign-board/recipe.json +1 -2
  63. package/recipes/sliding-door/recipe.json +7 -14
  64. package/recipes/stairs/recipe.json +1 -2
  65. package/recipes/stopper/recipe.json +1 -2
  66. package/recipes/suction-pads/recipe.json +1 -2
  67. package/recipes/tank/recipe.json +2 -4
  68. package/recipes/toe-board/recipe.json +1 -2
  69. package/recipes/traffic-cones/recipe.json +1 -2
  70. package/recipes/transfer-belts/recipe.json +2 -4
  71. package/recipes/trough/recipe.json +1 -2
  72. package/recipes/turntable/models/default.json +1 -1
  73. package/recipes/turntable/recipe.json +1 -2
  74. package/recipes/workbench-top/recipe.json +2 -4
  75. package/server/service/figure/event-subscriber.ts +4 -0
  76. package/server/service/figure/figure-blueprint-query.test.ts +3 -0
  77. package/server/service/figure/figure-context.test.ts +1 -1
  78. package/server/service/figure/figure-format.ts +27 -5
  79. package/server/service/figure/figure-llm-smoke.test.ts +2 -1
  80. package/server/service/figure/figure-mutation.ts +2 -0
  81. package/server/service/figure/figure-query.ts +3 -6
  82. package/server/service/figure/figure-release-size-db.test.ts +156 -0
  83. package/server/service/figure/figure-revert.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/figure-service",
3
- "version": "10.1.204",
3
+ "version": "10.1.206",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "@things-factory:registry": "https://registry.npmjs.org"
@@ -25,18 +25,18 @@
25
25
  "test:templates": "node --test scripts/templates.test.mts"
26
26
  },
27
27
  "dependencies": {
28
- "@hatiolab/figure-model": "^0.9.4",
28
+ "@hatiolab/figure-model": "^0.9.6",
29
29
  "@operato/typeorm-history": "^10.0.0",
30
- "@things-factory/ai-client-base": "^10.1.203",
31
- "@things-factory/attachment-base": "^10.1.203",
32
- "@things-factory/auth-base": "^10.1.203",
30
+ "@things-factory/ai-client-base": "^10.1.206",
31
+ "@things-factory/attachment-base": "^10.1.206",
32
+ "@things-factory/auth-base": "^10.1.206",
33
33
  "@things-factory/env": "^10.1.149",
34
- "@things-factory/setting-base": "^10.1.203",
35
- "@things-factory/shell": "^10.1.188",
34
+ "@things-factory/setting-base": "^10.1.206",
35
+ "@things-factory/shell": "^10.1.206",
36
36
  "graphql-scalars": "^1.22.4",
37
37
  "graphql-upload": "^15.0.2",
38
38
  "jszip": "^3.10.1",
39
39
  "koa-router": "^7.4.0"
40
40
  },
41
- "gitHead": "b85c845b52c08389413c0038b2b3b4b4f952ada1"
41
+ "gitHead": "18588a058a4a6cb21c379b2da5517e077c6442ba"
42
42
  }
@@ -40,6 +40,13 @@ export class Model {
40
40
  on(part: string, to: string, toFace: string, align?: Record<string, unknown>, gap?: number): this {
41
41
  return this.do({ kind: 'attach', part, to: { part: to, face: toFace }, ...(align ? { align } : {}), ...(gap ? { gap } : {}) } as FigureAuthoringAction)
42
42
  }
43
+ /**
44
+ * Fastened to a point on another part's curved surface (ADR-0140 3.9): on a cylinder's side `around` its push axis in
45
+ * degrees and `along` it, on a sphere `toward` its outward normal there.
46
+ */
47
+ onSurface(part: string, to: string, surface: Record<string, unknown>): this {
48
+ return this.do({ kind: 'attach', part, to: { part: to, surface } } as FigureAuthoringAction)
49
+ }
43
50
  /**
44
51
  * A part's colour. The palette is the figure's, shared by every template put into it: a token named for its value
45
52
  * (`palette.tpl-5c7c96`) means two templates never recolour each other's parts. The name given says what it is for.
@@ -97,8 +97,7 @@
97
97
  "of": "part",
98
98
  "part": "{target}",
99
99
  "axis": "x"
100
- },
101
- "narrowRange": true
100
+ }
102
101
  },
103
102
  {
104
103
  "kind": "link-dimension",
@@ -108,8 +107,7 @@
108
107
  "of": "part",
109
108
  "part": "{target}",
110
109
  "axis": "x"
111
- },
112
- "narrowRange": true
110
+ }
113
111
  },
114
112
  {
115
113
  "kind": "link-dimension",
@@ -120,8 +118,7 @@
120
118
  "part": "{target}",
121
119
  "axis": "z"
122
120
  },
123
- "plus": -160,
124
- "narrowRange": true
121
+ "plus": -160
125
122
  },
126
123
  {
127
124
  "kind": "link-dimension",
@@ -132,8 +129,7 @@
132
129
  "part": "{target}",
133
130
  "axis": "z"
134
131
  },
135
- "plus": -160,
136
- "narrowRange": true
132
+ "plus": -160
137
133
  },
138
134
  {
139
135
  "kind": "set-joint",
@@ -69,8 +69,7 @@
69
69
  "of": "part",
70
70
  "part": "{target}",
71
71
  "axis": "x"
72
- },
73
- "narrowRange": true
72
+ }
74
73
  },
75
74
  {
76
75
  "kind": "link-dimension",
@@ -83,8 +82,7 @@
83
82
  },
84
83
  "times": {
85
84
  "param": "width"
86
- },
87
- "narrowRange": true
85
+ }
88
86
  },
89
87
  {
90
88
  "kind": "set-joint",
@@ -69,8 +69,7 @@
69
69
  "param": "pitch"
70
70
  }
71
71
  }
72
- },
73
- "narrowRange": true
72
+ }
74
73
  },
75
74
  {
76
75
  "kind": "set-material",
@@ -84,8 +84,7 @@
84
84
  "param": "pitch"
85
85
  }
86
86
  }
87
- },
88
- "narrowRange": true
87
+ }
89
88
  },
90
89
  {
91
90
  "kind": "set-material",
@@ -64,8 +64,7 @@
64
64
  "part": "{target}",
65
65
  "axis": "x"
66
66
  },
67
- "times": 0.98,
68
- "narrowRange": true
67
+ "times": 0.98
69
68
  },
70
69
  {
71
70
  "when": {
@@ -112,8 +111,7 @@
112
111
  "part": "{target}",
113
112
  "axis": "x"
114
113
  },
115
- "times": 0.49,
116
- "narrowRange": true
114
+ "times": 0.49
117
115
  },
118
116
  {
119
117
  "kind": "link-dimension",
@@ -124,8 +122,7 @@
124
122
  "part": "{target}",
125
123
  "axis": "y"
126
124
  },
127
- "times": 0.98,
128
- "narrowRange": true
125
+ "times": 0.98
129
126
  },
130
127
  {
131
128
  "when": {
@@ -139,8 +136,7 @@
139
136
  "of": "part",
140
137
  "part": "{id}-left",
141
138
  "axis": "x"
142
- },
143
- "narrowRange": true
139
+ }
144
140
  },
145
141
  {
146
142
  "when": {
@@ -154,8 +150,7 @@
154
150
  "of": "part",
155
151
  "part": "{id}-left",
156
152
  "axis": "y"
157
- },
158
- "narrowRange": true
153
+ }
159
154
  },
160
155
  {
161
156
  "kind": "set-joint",
@@ -79,8 +79,7 @@
79
79
  "of": "part",
80
80
  "part": "{target}",
81
81
  "axis": "x"
82
- },
83
- "narrowRange": true
82
+ }
84
83
  },
85
84
  {
86
85
  "kind": "link-dimension",
@@ -90,8 +89,7 @@
90
89
  "of": "part",
91
90
  "part": "{id}-floor",
92
91
  "axis": "x"
93
- },
94
- "narrowRange": true
92
+ }
95
93
  },
96
94
  {
97
95
  "kind": "link-dimension",
@@ -101,8 +99,7 @@
101
99
  "of": "part",
102
100
  "part": "{id}-floor",
103
101
  "axis": "x"
104
- },
105
- "narrowRange": true
102
+ }
106
103
  },
107
104
  {
108
105
  "kind": "set-joint",
@@ -109,8 +109,7 @@
109
109
  "of": "part",
110
110
  "part": "{target}",
111
111
  "axis": "x"
112
- },
113
- "narrowRange": true
112
+ }
114
113
  },
115
114
  {
116
115
  "kind": "link-dimension",
@@ -120,8 +119,7 @@
120
119
  "of": "part",
121
120
  "part": "{target}",
122
121
  "axis": "z"
123
- },
124
- "narrowRange": true
122
+ }
125
123
  },
126
124
  {
127
125
  "kind": "set-joint",
@@ -61,8 +61,7 @@
61
61
  "of": "part",
62
62
  "part": "{target}",
63
63
  "axis": "x"
64
- },
65
- "narrowRange": true
64
+ }
66
65
  },
67
66
  {
68
67
  "kind": "set-joint",
@@ -50,8 +50,7 @@
50
50
  "of": "part",
51
51
  "part": "{target}",
52
52
  "axis": "x"
53
- },
54
- "narrowRange": true
53
+ }
55
54
  },
56
55
  {
57
56
  "kind": "set-joint",
@@ -65,8 +65,7 @@
65
65
  "of": "part",
66
66
  "part": "{target}",
67
67
  "axis": "x"
68
- },
69
- "narrowRange": true
68
+ }
70
69
  },
71
70
  {
72
71
  "kind": "link-dimension",
@@ -76,8 +75,7 @@
76
75
  "of": "part",
77
76
  "part": "{target}",
78
77
  "axis": "x"
79
- },
80
- "narrowRange": true
78
+ }
81
79
  },
82
80
  {
83
81
  "kind": "set-joint",
@@ -85,8 +85,7 @@
85
85
  "param": "pitch"
86
86
  }
87
87
  }
88
- },
89
- "narrowRange": true
88
+ }
90
89
  },
91
90
  {
92
91
  "kind": "set-material",
@@ -49,8 +49,7 @@
49
49
  "of": "part",
50
50
  "part": "{target}",
51
51
  "axis": "x"
52
- },
53
- "narrowRange": true
52
+ }
54
53
  },
55
54
  {
56
55
  "kind": "link-dimension",
@@ -60,8 +59,7 @@
60
59
  "of": "part",
61
60
  "part": "{target}",
62
61
  "axis": "y"
63
- },
64
- "narrowRange": true
62
+ }
65
63
  },
66
64
  {
67
65
  "kind": "link-dimension",
@@ -71,8 +69,7 @@
71
69
  "of": "part",
72
70
  "part": "{target}",
73
71
  "axis": "x"
74
- },
75
- "narrowRange": true
72
+ }
76
73
  },
77
74
  {
78
75
  "kind": "link-dimension",
@@ -82,8 +79,7 @@
82
79
  "of": "part",
83
80
  "part": "{target}",
84
81
  "axis": "y"
85
- },
86
- "narrowRange": true
82
+ }
87
83
  },
88
84
  {
89
85
  "kind": "set-joint",
@@ -97,8 +97,7 @@
97
97
  },
98
98
  "times": {
99
99
  "param": "share"
100
- },
101
- "narrowRange": true
100
+ }
102
101
  },
103
102
  {
104
103
  "kind": "link-dimension",
@@ -111,8 +110,7 @@
111
110
  },
112
111
  "times": {
113
112
  "param": "height"
114
- },
115
- "narrowRange": true
113
+ }
116
114
  },
117
115
  {
118
116
  "kind": "link-dimension",
@@ -124,8 +122,7 @@
124
122
  "axis": "x"
125
123
  },
126
124
  "times": 0.5,
127
- "plus": -105,
128
- "narrowRange": true
125
+ "plus": -105
129
126
  },
130
127
  {
131
128
  "kind": "link-dimension",
@@ -136,8 +133,7 @@
136
133
  "part": "{id}-frame",
137
134
  "axis": "y"
138
135
  },
139
- "plus": -110,
140
- "narrowRange": true
136
+ "plus": -110
141
137
  },
142
138
  {
143
139
  "kind": "link-dimension",
@@ -149,8 +145,7 @@
149
145
  "axis": "x"
150
146
  },
151
147
  "times": 0.5,
152
- "plus": -105,
153
- "narrowRange": true
148
+ "plus": -105
154
149
  },
155
150
  {
156
151
  "kind": "link-dimension",
@@ -161,8 +156,7 @@
161
156
  "part": "{id}-frame",
162
157
  "axis": "y"
163
158
  },
164
- "plus": -110,
165
- "narrowRange": true
159
+ "plus": -110
166
160
  },
167
161
  {
168
162
  "kind": "set-joint",
@@ -189,8 +189,7 @@
189
189
  "part": "{target}",
190
190
  "axis": "x"
191
191
  },
192
- "times": 0.95,
193
- "narrowRange": true
192
+ "times": 0.95
194
193
  },
195
194
  {
196
195
  "when": {
@@ -205,8 +204,7 @@
205
204
  "part": "{target}",
206
205
  "axis": "y"
207
206
  },
208
- "times": 0.45,
209
- "narrowRange": true
207
+ "times": 0.45
210
208
  },
211
209
  {
212
210
  "when": {
@@ -221,8 +219,7 @@
221
219
  "part": "{target}",
222
220
  "axis": "y"
223
221
  },
224
- "times": 0.3,
225
- "narrowRange": true
222
+ "times": 0.3
226
223
  },
227
224
  {
228
225
  "when": {
@@ -237,8 +234,7 @@
237
234
  "part": "{target}",
238
235
  "axis": "y"
239
236
  },
240
- "times": 0.225,
241
- "narrowRange": true
237
+ "times": 0.225
242
238
  },
243
239
  {
244
240
  "kind": "link-dimension",
@@ -249,8 +245,7 @@
249
245
  "part": "{target}",
250
246
  "axis": "x"
251
247
  },
252
- "times": 0.95,
253
- "narrowRange": true
248
+ "times": 0.95
254
249
  },
255
250
  {
256
251
  "when": {
@@ -265,8 +260,7 @@
265
260
  "part": "{target}",
266
261
  "axis": "y"
267
262
  },
268
- "times": 0.45,
269
- "narrowRange": true
263
+ "times": 0.45
270
264
  },
271
265
  {
272
266
  "when": {
@@ -357,8 +351,7 @@
357
351
  "part": "{target}",
358
352
  "axis": "y"
359
353
  },
360
- "times": 0.3,
361
- "narrowRange": true
354
+ "times": 0.3
362
355
  },
363
356
  {
364
357
  "when": {
@@ -373,8 +366,7 @@
373
366
  "part": "{target}",
374
367
  "axis": "y"
375
368
  },
376
- "times": 0.225,
377
- "narrowRange": true
369
+ "times": 0.225
378
370
  },
379
371
  {
380
372
  "when": {
@@ -392,8 +384,7 @@
392
384
  "part": "{target}",
393
385
  "axis": "x"
394
386
  },
395
- "times": 0.95,
396
- "narrowRange": true
387
+ "times": 0.95
397
388
  },
398
389
  {
399
390
  "when": {
@@ -408,8 +399,7 @@
408
399
  "part": "{target}",
409
400
  "axis": "y"
410
401
  },
411
- "times": 0.3,
412
- "narrowRange": true
402
+ "times": 0.3
413
403
  },
414
404
  {
415
405
  "when": {
@@ -538,8 +528,7 @@
538
528
  "part": "{target}",
539
529
  "axis": "y"
540
530
  },
541
- "times": 0.225,
542
- "narrowRange": true
531
+ "times": 0.225
543
532
  },
544
533
  {
545
534
  "when": {
@@ -554,8 +543,7 @@
554
543
  "part": "{target}",
555
544
  "axis": "x"
556
545
  },
557
- "times": 0.95,
558
- "narrowRange": true
546
+ "times": 0.95
559
547
  },
560
548
  {
561
549
  "when": {
@@ -570,8 +558,7 @@
570
558
  "part": "{target}",
571
559
  "axis": "y"
572
560
  },
573
- "times": 0.225,
574
- "narrowRange": true
561
+ "times": 0.225
575
562
  },
576
563
  {
577
564
  "when": {
@@ -42,8 +42,7 @@
42
42
  "of": "part",
43
43
  "part": "{target}",
44
44
  "axis": "x"
45
- },
46
- "narrowRange": true
45
+ }
47
46
  },
48
47
  {
49
48
  "kind": "link-dimension",
@@ -53,8 +52,7 @@
53
52
  "of": "part",
54
53
  "part": "{target}",
55
54
  "axis": "z"
56
- },
57
- "narrowRange": true
55
+ }
58
56
  },
59
57
  {
60
58
  "kind": "set-joint",
@@ -49,8 +49,7 @@
49
49
  "of": "part",
50
50
  "part": "{target}",
51
51
  "axis": "y"
52
- },
53
- "narrowRange": true
52
+ }
54
53
  },
55
54
  {
56
55
  "kind": "link-dimension",
@@ -60,8 +59,7 @@
60
59
  "of": "part",
61
60
  "part": "{target}",
62
61
  "axis": "z"
63
- },
64
- "narrowRange": true
62
+ }
65
63
  },
66
64
  {
67
65
  "kind": "link-dimension",
@@ -71,8 +69,7 @@
71
69
  "of": "part",
72
70
  "part": "{target}",
73
71
  "axis": "y"
74
- },
75
- "narrowRange": true
72
+ }
76
73
  },
77
74
  {
78
75
  "kind": "link-dimension",
@@ -82,8 +79,7 @@
82
79
  "of": "part",
83
80
  "part": "{target}",
84
81
  "axis": "z"
85
- },
86
- "narrowRange": true
82
+ }
87
83
  },
88
84
  {
89
85
  "kind": "set-joint",
@@ -64,8 +64,7 @@
64
64
  "param": "pitch"
65
65
  }
66
66
  }
67
- },
68
- "narrowRange": true
67
+ }
69
68
  },
70
69
  {
71
70
  "kind": "set-material",
@@ -97,8 +97,7 @@
97
97
  "of": "part",
98
98
  "part": "{target}",
99
99
  "axis": "x"
100
- },
101
- "narrowRange": true
100
+ }
102
101
  },
103
102
  {
104
103
  "kind": "link-dimension",
@@ -108,8 +107,7 @@
108
107
  "of": "part",
109
108
  "part": "{target}",
110
109
  "axis": "x"
111
- },
112
- "narrowRange": true
110
+ }
113
111
  },
114
112
  {
115
113
  "kind": "link-dimension",
@@ -119,8 +117,7 @@
119
117
  "of": "part",
120
118
  "part": "{target}",
121
119
  "axis": "z"
122
- },
123
- "narrowRange": true
120
+ }
124
121
  },
125
122
  {
126
123
  "kind": "link-dimension",
@@ -130,8 +127,7 @@
130
127
  "of": "part",
131
128
  "part": "{target}",
132
129
  "axis": "z"
133
- },
134
- "narrowRange": true
130
+ }
135
131
  },
136
132
  {
137
133
  "kind": "set-joint",
@@ -82,8 +82,7 @@
82
82
  },
83
83
  "times": {
84
84
  "param": "share"
85
- },
86
- "narrowRange": true
85
+ }
87
86
  },
88
87
  {
89
88
  "kind": "link-dimension",
@@ -95,8 +94,7 @@
95
94
  "axis": "x"
96
95
  },
97
96
  "times": 0.5,
98
- "plus": -105,
99
- "narrowRange": true
97
+ "plus": -105
100
98
  },
101
99
  {
102
100
  "kind": "link-dimension",
@@ -106,8 +104,7 @@
106
104
  "of": "part",
107
105
  "part": "{id}-panel-1",
108
106
  "axis": "x"
109
- },
110
- "narrowRange": true
107
+ }
111
108
  },
112
109
  {
113
110
  "kind": "set-joint",
@@ -81,8 +81,7 @@
81
81
  "of": "part",
82
82
  "part": "{target}",
83
83
  "axis": "x"
84
- },
85
- "narrowRange": true
84
+ }
86
85
  },
87
86
  {
88
87
  "kind": "set-joint",
@@ -37,8 +37,7 @@
37
37
  "of": "part",
38
38
  "part": "{target}",
39
39
  "axis": "x"
40
- },
41
- "narrowRange": true
40
+ }
42
41
  },
43
42
  {
44
43
  "kind": "link-dimension",
@@ -48,8 +47,7 @@
48
47
  "of": "part",
49
48
  "part": "{target}",
50
49
  "axis": "z"
51
- },
52
- "narrowRange": true
50
+ }
53
51
  },
54
52
  {
55
53
  "kind": "set-joint",