sysprom 1.14.0 → 1.15.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.
@@ -0,0 +1,414 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Completeness result for a single node.
4
+ */
5
+ declare const CompletenessResult: z.ZodObject<{
6
+ id: z.ZodString;
7
+ type: z.ZodEnum<{
8
+ intent: "intent";
9
+ concept: "concept";
10
+ capability: "capability";
11
+ element: "element";
12
+ realisation: "realisation";
13
+ invariant: "invariant";
14
+ principle: "principle";
15
+ policy: "policy";
16
+ protocol: "protocol";
17
+ stage: "stage";
18
+ role: "role";
19
+ gate: "gate";
20
+ mode: "mode";
21
+ artefact: "artefact";
22
+ artefact_flow: "artefact_flow";
23
+ decision: "decision";
24
+ change: "change";
25
+ view: "view";
26
+ milestone: "milestone";
27
+ version: "version";
28
+ }> & {
29
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
30
+ };
31
+ name: z.ZodString;
32
+ score: z.ZodNumber;
33
+ issues: z.ZodArray<z.ZodString>;
34
+ }, z.core.$strip>;
35
+ /** Completeness result for a single node with score and issues. */
36
+ export type CompletenessResult = z.infer<typeof CompletenessResult>;
37
+ /**
38
+ * Output schema for inferCompletenessOp.
39
+ */
40
+ declare const CompletenessOutput: z.ZodObject<{
41
+ nodes: z.ZodArray<z.ZodObject<{
42
+ id: z.ZodString;
43
+ type: z.ZodEnum<{
44
+ intent: "intent";
45
+ concept: "concept";
46
+ capability: "capability";
47
+ element: "element";
48
+ realisation: "realisation";
49
+ invariant: "invariant";
50
+ principle: "principle";
51
+ policy: "policy";
52
+ protocol: "protocol";
53
+ stage: "stage";
54
+ role: "role";
55
+ gate: "gate";
56
+ mode: "mode";
57
+ artefact: "artefact";
58
+ artefact_flow: "artefact_flow";
59
+ decision: "decision";
60
+ change: "change";
61
+ view: "view";
62
+ milestone: "milestone";
63
+ version: "version";
64
+ }> & {
65
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
66
+ };
67
+ name: z.ZodString;
68
+ score: z.ZodNumber;
69
+ issues: z.ZodArray<z.ZodString>;
70
+ }, z.core.$strip>>;
71
+ averageScore: z.ZodNumber;
72
+ completeNodes: z.ZodNumber;
73
+ incompleteNodes: z.ZodNumber;
74
+ }, z.core.$strip>;
75
+ /** Output of completeness inference operation. */
76
+ export type CompletenessOutput = z.infer<typeof CompletenessOutput>;
77
+ /**
78
+ * Infer completeness of nodes based on expected relationships.
79
+ *
80
+ * Analyses each node to determine if it has expected refinements or
81
+ * relationships, returning a score (0-1) and list of issues for incomplete nodes.
82
+ */
83
+ export declare const inferCompletenessOp: import("./define-operation.js").DefinedOperation<z.ZodObject<{
84
+ doc: z.ZodObject<{
85
+ $schema: z.ZodOptional<z.ZodString>;
86
+ metadata: z.ZodOptional<z.ZodObject<{
87
+ title: z.ZodOptional<z.ZodString>;
88
+ doc_type: z.ZodOptional<z.ZodString>;
89
+ scope: z.ZodOptional<z.ZodString>;
90
+ status: z.ZodOptional<z.ZodString>;
91
+ version: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
92
+ }, z.core.$loose> & {
93
+ is(value: unknown): value is {
94
+ [x: string]: unknown;
95
+ title?: string | undefined;
96
+ doc_type?: string | undefined;
97
+ scope?: string | undefined;
98
+ status?: string | undefined;
99
+ version?: string | number | undefined;
100
+ };
101
+ }>;
102
+ nodes: z.ZodArray<z.ZodObject<{
103
+ id: z.ZodString;
104
+ type: z.ZodEnum<{
105
+ intent: "intent";
106
+ concept: "concept";
107
+ capability: "capability";
108
+ element: "element";
109
+ realisation: "realisation";
110
+ invariant: "invariant";
111
+ principle: "principle";
112
+ policy: "policy";
113
+ protocol: "protocol";
114
+ stage: "stage";
115
+ role: "role";
116
+ gate: "gate";
117
+ mode: "mode";
118
+ artefact: "artefact";
119
+ artefact_flow: "artefact_flow";
120
+ decision: "decision";
121
+ change: "change";
122
+ view: "view";
123
+ milestone: "milestone";
124
+ version: "version";
125
+ }> & {
126
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
127
+ };
128
+ name: z.ZodString;
129
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
130
+ is(value: unknown): value is string | string[];
131
+ }>;
132
+ status: z.ZodOptional<z.ZodEnum<{
133
+ deprecated: "deprecated";
134
+ proposed: "proposed";
135
+ accepted: "accepted";
136
+ active: "active";
137
+ implemented: "implemented";
138
+ adopted: "adopted";
139
+ defined: "defined";
140
+ introduced: "introduced";
141
+ in_progress: "in_progress";
142
+ complete: "complete";
143
+ consolidated: "consolidated";
144
+ experimental: "experimental";
145
+ retired: "retired";
146
+ superseded: "superseded";
147
+ abandoned: "abandoned";
148
+ deferred: "deferred";
149
+ }> & {
150
+ is(value: unknown): value is "deprecated" | "proposed" | "accepted" | "active" | "implemented" | "adopted" | "defined" | "introduced" | "in_progress" | "complete" | "consolidated" | "experimental" | "retired" | "superseded" | "abandoned" | "deferred";
151
+ }>;
152
+ lifecycle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
153
+ context: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
154
+ is(value: unknown): value is string | string[];
155
+ }>;
156
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
157
+ id: z.ZodString;
158
+ description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
159
+ is(value: unknown): value is string | string[];
160
+ };
161
+ }, z.core.$loose> & {
162
+ is(value: unknown): value is {
163
+ [x: string]: unknown;
164
+ id: string;
165
+ description: string | string[];
166
+ };
167
+ }>>;
168
+ selected: z.ZodOptional<z.ZodString>;
169
+ rationale: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
170
+ is(value: unknown): value is string | string[];
171
+ }>;
172
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
173
+ operations: z.ZodOptional<z.ZodArray<z.ZodObject<{
174
+ type: z.ZodEnum<{
175
+ link: "link";
176
+ add: "add";
177
+ update: "update";
178
+ remove: "remove";
179
+ }>;
180
+ target: z.ZodOptional<z.ZodString>;
181
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
182
+ is(value: unknown): value is string | string[];
183
+ }>;
184
+ }, z.core.$loose> & {
185
+ is(value: unknown): value is {
186
+ [x: string]: unknown;
187
+ type: "link" | "add" | "update" | "remove";
188
+ target?: string | undefined;
189
+ description?: string | string[] | undefined;
190
+ };
191
+ }>>;
192
+ plan: z.ZodOptional<z.ZodArray<z.ZodObject<{
193
+ description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
194
+ is(value: unknown): value is string | string[];
195
+ };
196
+ done: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
197
+ }, z.core.$loose> & {
198
+ is(value: unknown): value is {
199
+ [x: string]: unknown;
200
+ description: string | string[];
201
+ done?: boolean | undefined;
202
+ };
203
+ }>>;
204
+ propagation: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
205
+ includes: z.ZodOptional<z.ZodArray<z.ZodString>>;
206
+ input: z.ZodOptional<z.ZodString>;
207
+ output: z.ZodOptional<z.ZodString>;
208
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
209
+ role: z.ZodEnum<{
210
+ output: "output";
211
+ input: "input";
212
+ context: "context";
213
+ evidence: "evidence";
214
+ source: "source";
215
+ standard: "standard";
216
+ prior_art: "prior_art";
217
+ }> & {
218
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
219
+ };
220
+ identifier: z.ZodString;
221
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
222
+ is(value: unknown): value is string | string[];
223
+ }>;
224
+ node_id: z.ZodOptional<z.ZodString>;
225
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
226
+ is(value: unknown): value is string | string[];
227
+ }>;
228
+ }, z.core.$strip> & {
229
+ is(value: unknown): value is {
230
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
231
+ identifier: string;
232
+ description?: string | string[] | undefined;
233
+ node_id?: string | undefined;
234
+ internalised?: string | string[] | undefined;
235
+ };
236
+ }>>;
237
+ readonly subsystem: z.ZodOptional<z.ZodObject</*elided*/ any, z.core.$strip>>;
238
+ }, z.core.$loose>>;
239
+ relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
240
+ from: z.ZodString;
241
+ to: z.ZodString;
242
+ type: z.ZodEnum<{
243
+ refines: "refines";
244
+ realises: "realises";
245
+ implements: "implements";
246
+ depends_on: "depends_on";
247
+ constrained_by: "constrained_by";
248
+ affects: "affects";
249
+ supersedes: "supersedes";
250
+ must_preserve: "must_preserve";
251
+ performs: "performs";
252
+ part_of: "part_of";
253
+ precedes: "precedes";
254
+ must_follow: "must_follow";
255
+ blocks: "blocks";
256
+ routes_to: "routes_to";
257
+ governed_by: "governed_by";
258
+ modifies: "modifies";
259
+ triggered_by: "triggered_by";
260
+ applies_to: "applies_to";
261
+ produces: "produces";
262
+ consumes: "consumes";
263
+ transforms_into: "transforms_into";
264
+ selects: "selects";
265
+ requires: "requires";
266
+ disables: "disables";
267
+ }> & {
268
+ is(value: unknown): value is "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "performs" | "part_of" | "precedes" | "must_follow" | "blocks" | "routes_to" | "governed_by" | "modifies" | "triggered_by" | "applies_to" | "produces" | "consumes" | "transforms_into" | "selects" | "requires" | "disables";
269
+ };
270
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
271
+ is(value: unknown): value is string | string[];
272
+ }>;
273
+ }, z.core.$loose> & {
274
+ is(value: unknown): value is {
275
+ [x: string]: unknown;
276
+ from: string;
277
+ to: string;
278
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "performs" | "part_of" | "precedes" | "must_follow" | "blocks" | "routes_to" | "governed_by" | "modifies" | "triggered_by" | "applies_to" | "produces" | "consumes" | "transforms_into" | "selects" | "requires" | "disables";
279
+ description?: string | string[] | undefined;
280
+ };
281
+ }>>;
282
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
283
+ role: z.ZodEnum<{
284
+ output: "output";
285
+ input: "input";
286
+ context: "context";
287
+ evidence: "evidence";
288
+ source: "source";
289
+ standard: "standard";
290
+ prior_art: "prior_art";
291
+ }> & {
292
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
293
+ };
294
+ identifier: z.ZodString;
295
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
296
+ is(value: unknown): value is string | string[];
297
+ }>;
298
+ node_id: z.ZodOptional<z.ZodString>;
299
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
300
+ is(value: unknown): value is string | string[];
301
+ }>;
302
+ }, z.core.$strip> & {
303
+ is(value: unknown): value is {
304
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
305
+ identifier: string;
306
+ description?: string | string[] | undefined;
307
+ node_id?: string | undefined;
308
+ internalised?: string | string[] | undefined;
309
+ };
310
+ }>>;
311
+ }, z.core.$strip> & {
312
+ is(value: unknown): value is {
313
+ nodes: {
314
+ [x: string]: unknown;
315
+ id: string;
316
+ type: "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
317
+ name: string;
318
+ description?: string | string[] | undefined;
319
+ status?: "deprecated" | "proposed" | "accepted" | "active" | "implemented" | "adopted" | "defined" | "introduced" | "in_progress" | "complete" | "consolidated" | "experimental" | "retired" | "superseded" | "abandoned" | "deferred" | undefined;
320
+ lifecycle?: Record<string, string | boolean> | undefined;
321
+ context?: string | string[] | undefined;
322
+ options?: {
323
+ [x: string]: unknown;
324
+ id: string;
325
+ description: string | string[];
326
+ }[] | undefined;
327
+ selected?: string | undefined;
328
+ rationale?: string | string[] | undefined;
329
+ scope?: string[] | undefined;
330
+ operations?: {
331
+ [x: string]: unknown;
332
+ type: "link" | "add" | "update" | "remove";
333
+ target?: string | undefined;
334
+ description?: string | string[] | undefined;
335
+ }[] | undefined;
336
+ plan?: {
337
+ [x: string]: unknown;
338
+ description: string | string[];
339
+ done?: boolean | undefined;
340
+ }[] | undefined;
341
+ propagation?: Record<string, boolean> | undefined;
342
+ includes?: string[] | undefined;
343
+ input?: string | undefined;
344
+ output?: string | undefined;
345
+ external_references?: {
346
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
347
+ identifier: string;
348
+ description?: string | string[] | undefined;
349
+ node_id?: string | undefined;
350
+ internalised?: string | string[] | undefined;
351
+ }[] | undefined;
352
+ subsystem?: /*elided*/ any | undefined;
353
+ }[];
354
+ $schema?: string | undefined;
355
+ metadata?: {
356
+ [x: string]: unknown;
357
+ title?: string | undefined;
358
+ doc_type?: string | undefined;
359
+ scope?: string | undefined;
360
+ status?: string | undefined;
361
+ version?: string | number | undefined;
362
+ } | undefined;
363
+ relationships?: {
364
+ [x: string]: unknown;
365
+ from: string;
366
+ to: string;
367
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "performs" | "part_of" | "precedes" | "must_follow" | "blocks" | "routes_to" | "governed_by" | "modifies" | "triggered_by" | "applies_to" | "produces" | "consumes" | "transforms_into" | "selects" | "requires" | "disables";
368
+ description?: string | string[] | undefined;
369
+ }[] | undefined;
370
+ external_references?: {
371
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
372
+ identifier: string;
373
+ description?: string | string[] | undefined;
374
+ node_id?: string | undefined;
375
+ internalised?: string | string[] | undefined;
376
+ }[] | undefined;
377
+ };
378
+ };
379
+ }, z.core.$strip>, z.ZodObject<{
380
+ nodes: z.ZodArray<z.ZodObject<{
381
+ id: z.ZodString;
382
+ type: z.ZodEnum<{
383
+ intent: "intent";
384
+ concept: "concept";
385
+ capability: "capability";
386
+ element: "element";
387
+ realisation: "realisation";
388
+ invariant: "invariant";
389
+ principle: "principle";
390
+ policy: "policy";
391
+ protocol: "protocol";
392
+ stage: "stage";
393
+ role: "role";
394
+ gate: "gate";
395
+ mode: "mode";
396
+ artefact: "artefact";
397
+ artefact_flow: "artefact_flow";
398
+ decision: "decision";
399
+ change: "change";
400
+ view: "view";
401
+ milestone: "milestone";
402
+ version: "version";
403
+ }> & {
404
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
405
+ };
406
+ name: z.ZodString;
407
+ score: z.ZodNumber;
408
+ issues: z.ZodArray<z.ZodString>;
409
+ }, z.core.$strip>>;
410
+ averageScore: z.ZodNumber;
411
+ completeNodes: z.ZodNumber;
412
+ incompleteNodes: z.ZodNumber;
413
+ }, z.core.$strip>>;
414
+ export {};
@@ -0,0 +1,131 @@
1
+ import * as z from "zod";
2
+ import { defineOperation } from "./define-operation.js";
3
+ import { SysProMDocument, NodeType } from "../schema.js";
4
+ /**
5
+ * Completeness result for a single node.
6
+ */
7
+ const CompletenessResult = z.object({
8
+ id: z.string(),
9
+ type: NodeType,
10
+ name: z.string(),
11
+ score: z.number().min(0).max(1),
12
+ issues: z.array(z.string()),
13
+ });
14
+ /**
15
+ * Output schema for inferCompletenessOp.
16
+ */
17
+ const CompletenessOutput = z.object({
18
+ nodes: z.array(CompletenessResult),
19
+ averageScore: z.number(),
20
+ completeNodes: z.number(),
21
+ incompleteNodes: z.number(),
22
+ });
23
+ /**
24
+ * Node types that are expected to have downward refinement relationships.
25
+ */
26
+ const REFINEMENT_HIERARCHY = {
27
+ intent: { expectedChildren: ["concept", "capability"], relType: "refines" },
28
+ concept: { expectedChildren: ["capability", "element"], relType: "refines" },
29
+ capability: {
30
+ expectedChildren: ["element", "realisation"],
31
+ relType: "realises",
32
+ },
33
+ element: { expectedChildren: ["realisation"], relType: "implements" },
34
+ decision: { expectedChildren: ["invariant"], relType: "must_preserve" },
35
+ change: { expectedChildren: ["decision"], relType: "implements" },
36
+ };
37
+ /**
38
+ * Infer completeness of nodes based on expected relationships.
39
+ *
40
+ * Analyses each node to determine if it has expected refinements or
41
+ * relationships, returning a score (0-1) and list of issues for incomplete nodes.
42
+ */
43
+ export const inferCompletenessOp = defineOperation({
44
+ name: "infer-completeness",
45
+ description: "Infer completeness of nodes based on expected refinement relationships",
46
+ input: z.object({
47
+ doc: SysProMDocument,
48
+ }),
49
+ output: CompletenessOutput,
50
+ fn: (input) => {
51
+ const typeMap = new Map(input.doc.nodes.map((n) => [n.id, n.type]));
52
+ const results = [];
53
+ for (const node of input.doc.nodes) {
54
+ const issues = [];
55
+ let score = 1.0;
56
+ if (node.type in REFINEMENT_HIERARCHY) {
57
+ const expected = REFINEMENT_HIERARCHY[node.type];
58
+ // For decision: find relationships FROM decision TO invariant (must_preserve)
59
+ // For change: find relationships FROM change TO decision (implements)
60
+ // For others: find relationships TO this node (refines, realises, implements)
61
+ const isOutgoingRel = ["decision", "change"].includes(node.type);
62
+ const children = (input.doc.relationships ?? [])
63
+ .filter((r) => {
64
+ if (isOutgoingRel) {
65
+ return r.from === node.id && r.type === expected.relType;
66
+ }
67
+ return r.to === node.id && r.type === expected.relType;
68
+ })
69
+ .map((r) => ({
70
+ id: isOutgoingRel ? r.to : r.from,
71
+ type: typeMap.get(isOutgoingRel ? r.to : r.from),
72
+ }));
73
+ // Check if any children match expected types
74
+ const validChildren = children.filter((c) => expected.expectedChildren.includes(c.type ?? ""));
75
+ if (validChildren.length === 0) {
76
+ issues.push(`No ${expected.relType} relationships ${isOutgoingRel ? "to" : "from"} ${expected.expectedChildren.join("/")} nodes`);
77
+ score -= 0.5;
78
+ }
79
+ }
80
+ // Check for required fields based on node type
81
+ if (node.type === "decision") {
82
+ if (!node.options || node.options.length === 0) {
83
+ issues.push("Decision has no options");
84
+ score -= 0.25;
85
+ }
86
+ if (!node.selected) {
87
+ issues.push("Decision has no selected option");
88
+ score -= 0.25;
89
+ }
90
+ if (!node.rationale) {
91
+ issues.push("Decision has no rationale");
92
+ score -= 0.1;
93
+ }
94
+ }
95
+ if (node.type === "change") {
96
+ if (!node.scope || node.scope.length === 0) {
97
+ issues.push("Change has no scope");
98
+ score -= 0.2;
99
+ }
100
+ if (!node.plan || node.plan.length === 0) {
101
+ issues.push("Change has no plan");
102
+ score -= 0.1;
103
+ }
104
+ }
105
+ if (node.type === "invariant") {
106
+ if (!node.description) {
107
+ issues.push("Invariant has no description");
108
+ score -= 0.3;
109
+ }
110
+ }
111
+ // Clamp score to [0, 1]
112
+ score = Math.max(0, Math.min(1, score));
113
+ results.push({
114
+ id: node.id,
115
+ type: node.type,
116
+ name: node.name,
117
+ score,
118
+ issues,
119
+ });
120
+ }
121
+ const completeNodes = results.filter((r) => r.score === 1).length;
122
+ const incompleteNodes = results.filter((r) => r.score < 1).length;
123
+ const averageScore = results.reduce((sum, r) => sum + r.score, 0) / results.length;
124
+ return {
125
+ nodes: results,
126
+ averageScore,
127
+ completeNodes,
128
+ incompleteNodes,
129
+ };
130
+ },
131
+ });