@fasl-work/caos-app-shell 0.12.0 → 0.13.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.
@@ -1,141 +1,659 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/fsantibanezleal/CAOS_APP_SHELL/blob/main/src/content/executive.schema.json",
4
- "title": "CAOS executive view data, version 1.0.0",
5
- "description": "The one data file a CAOS product fills for the executive view of its Introduction (content/executive.json). Every text is { en, es }; nothing outside these fields is allowed. The writing limits (30 words per sentence, an answer of at most 2 sentences, one sentence for initiative, vision, statement, exec_problem and caption, no equation, no inline citation), the four_cs rule (absent until FOUR_CS names the 4 C's) and the sources-by-field rule are checked by validateExecutive in executive.ts, on top of this structure.",
6
- "type": "object",
7
- "additionalProperties": false,
8
- "required": ["executive", "organisation", "initiative", "why_now", "vision", "outcomes", "dialogue", "illustrations", "sources"],
9
- "properties": {
10
- "executive": { "$ref": "#/$defs/text", "description": "One C-suite role, never a list." },
11
- "organisation": { "$ref": "#/$defs/text", "description": "One industry and one context, never several regions." },
12
- "initiative": { "$ref": "#/$defs/text", "description": "One sentence: what that executive owns and must achieve." },
13
- "why_now": {
14
- "type": "object",
15
- "additionalProperties": false,
16
- "required": ["figure", "deadline"],
17
- "properties": {
18
- "figure": { "$ref": "#/$defs/figure" },
19
- "deadline": { "$ref": "#/$defs/text", "description": "One date or deadline, for example 'by 1 December 2026'." }
20
- }
21
- },
22
- "vision": { "$ref": "#/$defs/text", "description": "One sentence: what changes for the executive's business. Comes first in section 2." },
23
- "outcomes": {
24
- "type": "array",
25
- "minItems": 3,
26
- "maxItems": 5,
27
- "items": {
28
- "type": "object",
29
- "additionalProperties": false,
30
- "required": ["capability", "outcome", "proof"],
31
- "properties": {
32
- "capability": { "$ref": "#/$defs/text", "description": "What the product does, in plain words." },
33
- "outcome": { "$ref": "#/$defs/text", "description": "The business result, non-technical." },
34
- "proof": {
35
- "type": "object",
36
- "additionalProperties": false,
37
- "required": ["value", "unit", "statement"],
38
- "properties": {
39
- "value": { "$ref": "#/$defs/text" },
40
- "unit": { "$ref": "#/$defs/text" },
41
- "statement": { "$ref": "#/$defs/text", "description": "A one-line statement of the proof point." }
42
- }
43
- }
44
- }
45
- }
46
- },
47
- "four_cs": {
48
- "type": "array",
49
- "minItems": 4,
50
- "maxItems": 4,
51
- "description": "Exactly 4 rows in the owner's order. Absent while FOUR_CS is empty; required, with c equal to the name, once it holds 4 names.",
52
- "items": {
53
- "type": "object",
54
- "additionalProperties": false,
55
- "required": ["c", "exec_problem"],
56
- "properties": {
57
- "c": { "$ref": "#/$defs/text" },
58
- "exec_problem": { "$ref": "#/$defs/text", "description": "One sentence tying the C to this executive's problem." }
59
- }
60
- }
61
- },
62
- "dialogue": {
63
- "type": "array",
64
- "minItems": 3,
65
- "maxItems": 5,
66
- "items": {
67
- "type": "object",
68
- "additionalProperties": false,
69
- "required": ["question", "answer"],
70
- "properties": {
71
- "question": { "$ref": "#/$defs/text", "description": "A business question that executive asks." },
72
- "answer": { "$ref": "#/$defs/text", "description": "At most 2 sentences." }
73
- }
74
- }
75
- },
76
- "illustrations": {
77
- "type": "object",
78
- "additionalProperties": false,
79
- "required": ["initiative", "problem", "solution"],
80
- "properties": {
81
- "initiative": { "$ref": "#/$defs/illustration" },
82
- "problem": { "$ref": "#/$defs/illustration" },
83
- "solution": { "$ref": "#/$defs/illustration" }
84
- }
85
- },
86
- "sources": {
87
- "type": "array",
88
- "minItems": 1,
89
- "description": "The source of every figure (why_now.figure and each outcomes[i].proof), by field path; shown as numbered notes, never inline.",
90
- "items": {
91
- "type": "object",
92
- "additionalProperties": false,
93
- "required": ["field", "source"],
94
- "properties": {
95
- "field": { "type": "string", "minLength": 1 },
96
- "source": { "$ref": "#/$defs/text" }
97
- }
98
- }
99
- }
100
- },
101
- "$defs": {
102
- "text": {
103
- "type": "object",
104
- "additionalProperties": false,
105
- "required": ["en", "es"],
106
- "properties": {
107
- "en": { "type": "string", "minLength": 1 },
108
- "es": { "type": "string", "minLength": 1 }
109
- }
110
- },
111
- "figure": {
112
- "type": "object",
113
- "additionalProperties": false,
114
- "required": ["value", "unit"],
115
- "properties": {
116
- "value": { "$ref": "#/$defs/text" },
117
- "unit": { "$ref": "#/$defs/text" }
118
- }
119
- },
120
- "illustration": {
121
- "type": "object",
122
- "additionalProperties": false,
123
- "required": ["file", "caption"],
124
- "properties": {
125
- "file": {
126
- "description": "The inline SVG: one path, or one path per language.",
127
- "anyOf": [
128
- { "type": "string", "minLength": 1 },
129
- {
130
- "type": "object",
131
- "additionalProperties": false,
132
- "required": ["en", "es"],
133
- "properties": { "en": { "type": "string", "minLength": 1 }, "es": { "type": "string", "minLength": 1 } }
134
- }
135
- ]
136
- },
137
- "caption": { "$ref": "#/$defs/text", "description": "One sentence saying what the reader should take from the illustration." }
138
- }
139
- }
140
- }
141
- }
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/fsantibanezleal/CAOS_APP_SHELL/blob/main/src/content/executive.schema.json",
4
+ "title": "CAOS executive view data, version 2.0.0",
5
+ "description": "The one data file a CAOS product fills for the executive view of its Introduction (content/executive.json): the industry's problem framed for a decision maker, general and never tied to a client or written as a pitch. Every text is { en, es }; nothing outside these fields is allowed. The floors are minimum and maximum counts of rows (minItems, maxItems). The writing limits (30 words per sentence, one sentence for key messages, captions, actions and the like, two for the key statement, at least 25 words in a paragraph, no equation, no inline citation, no promotional or client-bound wording), the 4 C's rule (exactly the 4 C's of FOUR_CS, in order, each c equal to its name), the owners that are roles of the current situation, the weights of the causes and the sources-by-id rules (every citation names a source, every source is cited, a source is an https link whose title and note cite no file) are checked by validateExecutive in executive.ts, on top of this structure.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "title",
10
+ "key_statement",
11
+ "headline_figures",
12
+ "pain",
13
+ "context",
14
+ "situation",
15
+ "trends",
16
+ "proposal",
17
+ "illustrations",
18
+ "sources"
19
+ ],
20
+ "properties": {
21
+ "title": {
22
+ "$ref": "#/$defs/text",
23
+ "description": "The problem's title: the industry's problem, not a product name."
24
+ },
25
+ "key_statement": {
26
+ "$ref": "#/$defs/text",
27
+ "description": "One or two sentences naming the pain and the direction proposed."
28
+ },
29
+ "headline_figures": {
30
+ "type": "array",
31
+ "minItems": 2,
32
+ "maxItems": 3,
33
+ "description": "Two or three headline figures, each a short heading, one figure and its linked source.",
34
+ "items": {
35
+ "$ref": "#/$defs/figure"
36
+ }
37
+ },
38
+ "pain": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": [
42
+ "key_message",
43
+ "paragraphs",
44
+ "bearers",
45
+ "figures",
46
+ "causes"
47
+ ],
48
+ "properties": {
49
+ "key_message": {
50
+ "$ref": "#/$defs/text",
51
+ "description": "One line: what a reader who stops here takes away."
52
+ },
53
+ "paragraphs": {
54
+ "type": "array",
55
+ "minItems": 2,
56
+ "maxItems": 3,
57
+ "description": "Two paragraphs (at least 25 words each): what goes wrong, for whom, how big.",
58
+ "items": {
59
+ "$ref": "#/$defs/text"
60
+ }
61
+ },
62
+ "bearers": {
63
+ "type": "array",
64
+ "minItems": 3,
65
+ "maxItems": 5,
66
+ "items": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": [
70
+ "who",
71
+ "cost",
72
+ "measure"
73
+ ],
74
+ "properties": {
75
+ "who": {
76
+ "$ref": "#/$defs/text",
77
+ "description": "Who bears it."
78
+ },
79
+ "cost": {
80
+ "$ref": "#/$defs/text",
81
+ "description": "The cost in money, time, risk or harm."
82
+ },
83
+ "measure": {
84
+ "$ref": "#/$defs/text",
85
+ "description": "How it is measured."
86
+ }
87
+ }
88
+ }
89
+ },
90
+ "figures": {
91
+ "type": "array",
92
+ "minItems": 2,
93
+ "maxItems": 4,
94
+ "description": "At least two sourced industry figures.",
95
+ "items": {
96
+ "$ref": "#/$defs/figure"
97
+ }
98
+ },
99
+ "causes": {
100
+ "type": "array",
101
+ "minItems": 3,
102
+ "maxItems": 5,
103
+ "description": "Three to five non-overlapping branches, weighted by size.",
104
+ "items": {
105
+ "type": "object",
106
+ "additionalProperties": false,
107
+ "required": [
108
+ "cause",
109
+ "weight"
110
+ ],
111
+ "properties": {
112
+ "cause": {
113
+ "$ref": "#/$defs/text",
114
+ "description": "One branch of the problem; branches do not overlap."
115
+ },
116
+ "weight": {
117
+ "type": "integer",
118
+ "minimum": 1,
119
+ "maximum": 100,
120
+ "description": "The size of the branch as a percent of the whole; the weights add to at most 100."
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ },
127
+ "context": {
128
+ "type": "object",
129
+ "additionalProperties": false,
130
+ "required": [
131
+ "key_message",
132
+ "paragraphs",
133
+ "setting",
134
+ "forces",
135
+ "evidence"
136
+ ],
137
+ "properties": {
138
+ "key_message": {
139
+ "$ref": "#/$defs/text",
140
+ "description": "One line: what a reader who stops here takes away."
141
+ },
142
+ "paragraphs": {
143
+ "type": "array",
144
+ "minItems": 1,
145
+ "maxItems": 2,
146
+ "description": "One or two paragraphs (at least 25 words each).",
147
+ "items": {
148
+ "$ref": "#/$defs/text"
149
+ }
150
+ },
151
+ "setting": {
152
+ "$ref": "#/$defs/text",
153
+ "description": "The class of organisations, rules, data and technology the problem lives in."
154
+ },
155
+ "forces": {
156
+ "type": "array",
157
+ "minItems": 3,
158
+ "maxItems": 4,
159
+ "items": {
160
+ "type": "object",
161
+ "additionalProperties": false,
162
+ "required": [
163
+ "force",
164
+ "direction"
165
+ ],
166
+ "properties": {
167
+ "force": {
168
+ "$ref": "#/$defs/text",
169
+ "description": "A force that keeps the pain going."
170
+ },
171
+ "direction": {
172
+ "$ref": "#/$defs/direction"
173
+ }
174
+ }
175
+ }
176
+ },
177
+ "evidence": {
178
+ "type": "array",
179
+ "minItems": 1,
180
+ "maxItems": 4,
181
+ "description": "At least one sourced rule or figure.",
182
+ "items": {
183
+ "type": "object",
184
+ "additionalProperties": false,
185
+ "required": [
186
+ "statement",
187
+ "source"
188
+ ],
189
+ "properties": {
190
+ "statement": {
191
+ "$ref": "#/$defs/text",
192
+ "description": "One sourced rule or figure."
193
+ },
194
+ "source": {
195
+ "$ref": "#/$defs/sourceId"
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+ },
202
+ "situation": {
203
+ "type": "object",
204
+ "additionalProperties": false,
205
+ "required": [
206
+ "key_message",
207
+ "roles",
208
+ "interaction",
209
+ "state_of_the_art",
210
+ "status"
211
+ ],
212
+ "properties": {
213
+ "key_message": {
214
+ "$ref": "#/$defs/text",
215
+ "description": "One line: what a reader who stops here takes away."
216
+ },
217
+ "roles": {
218
+ "type": "array",
219
+ "minItems": 3,
220
+ "maxItems": 5,
221
+ "items": {
222
+ "type": "object",
223
+ "additionalProperties": false,
224
+ "required": [
225
+ "role",
226
+ "decides",
227
+ "needs"
228
+ ],
229
+ "properties": {
230
+ "role": {
231
+ "$ref": "#/$defs/text",
232
+ "description": "A role involved; a family of roles, never a person or an organisation."
233
+ },
234
+ "decides": {
235
+ "$ref": "#/$defs/text",
236
+ "description": "What it decides."
237
+ },
238
+ "needs": {
239
+ "$ref": "#/$defs/text",
240
+ "description": "What it needs."
241
+ }
242
+ }
243
+ }
244
+ },
245
+ "interaction": {
246
+ "$ref": "#/$defs/text",
247
+ "description": "One sentence on how the roles interact."
248
+ },
249
+ "state_of_the_art": {
250
+ "type": "array",
251
+ "minItems": 3,
252
+ "maxItems": 5,
253
+ "items": {
254
+ "type": "object",
255
+ "additionalProperties": false,
256
+ "required": [
257
+ "approach",
258
+ "achieves",
259
+ "falls_short",
260
+ "source"
261
+ ],
262
+ "properties": {
263
+ "approach": {
264
+ "$ref": "#/$defs/text",
265
+ "description": "An approach in use, described fairly."
266
+ },
267
+ "achieves": {
268
+ "$ref": "#/$defs/text",
269
+ "description": "What it achieves."
270
+ },
271
+ "falls_short": {
272
+ "$ref": "#/$defs/text",
273
+ "description": "Where it falls short."
274
+ },
275
+ "source": {
276
+ "$ref": "#/$defs/sourceId"
277
+ }
278
+ }
279
+ }
280
+ },
281
+ "status": {
282
+ "type": "object",
283
+ "additionalProperties": false,
284
+ "required": [
285
+ "heading",
286
+ "value",
287
+ "unit",
288
+ "date",
289
+ "source"
290
+ ],
291
+ "properties": {
292
+ "heading": {
293
+ "$ref": "#/$defs/text"
294
+ },
295
+ "value": {
296
+ "$ref": "#/$defs/text"
297
+ },
298
+ "unit": {
299
+ "$ref": "#/$defs/text"
300
+ },
301
+ "date": {
302
+ "$ref": "#/$defs/text",
303
+ "description": "The date of the figure."
304
+ },
305
+ "source": {
306
+ "$ref": "#/$defs/sourceId"
307
+ }
308
+ },
309
+ "description": "One sourced status figure with its date."
310
+ }
311
+ }
312
+ },
313
+ "trends": {
314
+ "type": "object",
315
+ "additionalProperties": false,
316
+ "required": [
317
+ "key_message",
318
+ "items"
319
+ ],
320
+ "properties": {
321
+ "key_message": {
322
+ "$ref": "#/$defs/text",
323
+ "description": "One line: what a reader who stops here takes away."
324
+ },
325
+ "items": {
326
+ "type": "array",
327
+ "minItems": 3,
328
+ "maxItems": 5,
329
+ "items": {
330
+ "type": "object",
331
+ "additionalProperties": false,
332
+ "required": [
333
+ "trend",
334
+ "kind",
335
+ "direction",
336
+ "horizon",
337
+ "signal",
338
+ "effect",
339
+ "confidence"
340
+ ],
341
+ "properties": {
342
+ "trend": {
343
+ "$ref": "#/$defs/text"
344
+ },
345
+ "kind": {
346
+ "type": "string",
347
+ "enum": [
348
+ "regulatory",
349
+ "technological",
350
+ "market",
351
+ "practice"
352
+ ]
353
+ },
354
+ "direction": {
355
+ "$ref": "#/$defs/direction"
356
+ },
357
+ "horizon": {
358
+ "type": "string",
359
+ "enum": [
360
+ "now",
361
+ "two_years",
362
+ "ten_years"
363
+ ]
364
+ },
365
+ "signal": {
366
+ "type": "object",
367
+ "additionalProperties": false,
368
+ "required": [
369
+ "statement",
370
+ "source"
371
+ ],
372
+ "properties": {
373
+ "statement": {
374
+ "$ref": "#/$defs/text",
375
+ "description": "The sourced signal."
376
+ },
377
+ "source": {
378
+ "$ref": "#/$defs/sourceId"
379
+ }
380
+ }
381
+ },
382
+ "effect": {
383
+ "$ref": "#/$defs/text",
384
+ "description": "Its effect on the roles of the current situation."
385
+ },
386
+ "confidence": {
387
+ "type": "string",
388
+ "enum": [
389
+ "low",
390
+ "medium",
391
+ "high"
392
+ ]
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ },
399
+ "proposal": {
400
+ "type": "object",
401
+ "additionalProperties": false,
402
+ "required": [
403
+ "key_message",
404
+ "paragraphs",
405
+ "four_cs",
406
+ "actions",
407
+ "risks",
408
+ "unknowns"
409
+ ],
410
+ "properties": {
411
+ "key_message": {
412
+ "$ref": "#/$defs/text",
413
+ "description": "One line: what a reader who stops here takes away."
414
+ },
415
+ "paragraphs": {
416
+ "type": "array",
417
+ "minItems": 1,
418
+ "maxItems": 2,
419
+ "description": "The approach at the level of the problem, tied to its causes (at least 25 words each).",
420
+ "items": {
421
+ "$ref": "#/$defs/text"
422
+ }
423
+ },
424
+ "four_cs": {
425
+ "type": "array",
426
+ "minItems": 4,
427
+ "maxItems": 4,
428
+ "description": "Required: exactly 4 rows, the 4 C's of FOUR_CS in order (Choice, Context, Cost, Control), each c equal to the name in both languages.",
429
+ "items": {
430
+ "type": "object",
431
+ "additionalProperties": false,
432
+ "required": [
433
+ "c",
434
+ "applies"
435
+ ],
436
+ "properties": {
437
+ "c": {
438
+ "$ref": "#/$defs/text",
439
+ "description": "The C's name."
440
+ },
441
+ "applies": {
442
+ "$ref": "#/$defs/text",
443
+ "description": "One sentence: what this C means for the proposal."
444
+ }
445
+ }
446
+ }
447
+ },
448
+ "actions": {
449
+ "type": "array",
450
+ "minItems": 3,
451
+ "maxItems": 6,
452
+ "items": {
453
+ "type": "object",
454
+ "additionalProperties": false,
455
+ "required": [
456
+ "action",
457
+ "owner",
458
+ "horizon",
459
+ "check"
460
+ ],
461
+ "properties": {
462
+ "action": {
463
+ "$ref": "#/$defs/text"
464
+ },
465
+ "owner": {
466
+ "$ref": "#/$defs/text",
467
+ "description": "A role of the current situation, written as there."
468
+ },
469
+ "horizon": {
470
+ "$ref": "#/$defs/text"
471
+ },
472
+ "check": {
473
+ "$ref": "#/$defs/text",
474
+ "description": "How success is checked."
475
+ }
476
+ }
477
+ }
478
+ },
479
+ "risks": {
480
+ "type": "array",
481
+ "minItems": 1,
482
+ "maxItems": 4,
483
+ "items": {
484
+ "$ref": "#/$defs/text"
485
+ }
486
+ },
487
+ "unknowns": {
488
+ "type": "array",
489
+ "minItems": 1,
490
+ "maxItems": 4,
491
+ "items": {
492
+ "$ref": "#/$defs/text"
493
+ }
494
+ },
495
+ "handoff": {
496
+ "$ref": "#/$defs/text",
497
+ "description": "Optional: one closing line on the part of the problem the work explores."
498
+ }
499
+ }
500
+ },
501
+ "illustrations": {
502
+ "type": "object",
503
+ "additionalProperties": false,
504
+ "required": [
505
+ "pain",
506
+ "situation",
507
+ "proposal"
508
+ ],
509
+ "properties": {
510
+ "pain": {
511
+ "$ref": "#/$defs/illustration"
512
+ },
513
+ "situation": {
514
+ "$ref": "#/$defs/illustration"
515
+ },
516
+ "proposal": {
517
+ "$ref": "#/$defs/illustration"
518
+ }
519
+ }
520
+ },
521
+ "sources": {
522
+ "type": "array",
523
+ "minItems": 1,
524
+ "description": "The sources, each a link; the notes are numbered in the order of first use. Every figure and every state-of-the-art or trend claim names one by id.",
525
+ "items": {
526
+ "type": "object",
527
+ "additionalProperties": false,
528
+ "required": [
529
+ "id",
530
+ "title",
531
+ "url"
532
+ ],
533
+ "properties": {
534
+ "id": {
535
+ "type": "string",
536
+ "pattern": "^[a-z0-9][a-z0-9-]*$",
537
+ "x-pattern-message": "must be lower case letters, digits and hyphens",
538
+ "description": "The id the figures and claims cite."
539
+ },
540
+ "title": {
541
+ "$ref": "#/$defs/text",
542
+ "description": "The publication, in plain words."
543
+ },
544
+ "url": {
545
+ "type": "string",
546
+ "minLength": 1,
547
+ "pattern": "^https://[^\\s]+$",
548
+ "x-pattern-message": "must be an https:// link (the page or document itself, no other scheme, no spaces)",
549
+ "description": "The https link to the page or document."
550
+ },
551
+ "note": {
552
+ "$ref": "#/$defs/text",
553
+ "description": "Optional, at most one sentence, for example a page number. Never a file name or number."
554
+ }
555
+ }
556
+ }
557
+ }
558
+ },
559
+ "$defs": {
560
+ "text": {
561
+ "type": "object",
562
+ "additionalProperties": false,
563
+ "required": [
564
+ "en",
565
+ "es"
566
+ ],
567
+ "properties": {
568
+ "en": {
569
+ "type": "string",
570
+ "minLength": 1
571
+ },
572
+ "es": {
573
+ "type": "string",
574
+ "minLength": 1
575
+ }
576
+ }
577
+ },
578
+ "sourceId": {
579
+ "type": "string",
580
+ "minLength": 1,
581
+ "description": "The id of an entry of sources."
582
+ },
583
+ "direction": {
584
+ "type": "string",
585
+ "enum": [
586
+ "rising",
587
+ "easing",
588
+ "steady"
589
+ ],
590
+ "description": "Where the force or the trend is heading."
591
+ },
592
+ "figure": {
593
+ "type": "object",
594
+ "additionalProperties": false,
595
+ "required": [
596
+ "heading",
597
+ "value",
598
+ "unit",
599
+ "source"
600
+ ],
601
+ "properties": {
602
+ "heading": {
603
+ "$ref": "#/$defs/text",
604
+ "description": "A short heading."
605
+ },
606
+ "value": {
607
+ "$ref": "#/$defs/text"
608
+ },
609
+ "unit": {
610
+ "$ref": "#/$defs/text"
611
+ },
612
+ "source": {
613
+ "$ref": "#/$defs/sourceId"
614
+ }
615
+ }
616
+ },
617
+ "illustration": {
618
+ "type": "object",
619
+ "additionalProperties": false,
620
+ "required": [
621
+ "file",
622
+ "caption"
623
+ ],
624
+ "properties": {
625
+ "file": {
626
+ "description": "The inline SVG: one path, or one path per language.",
627
+ "anyOf": [
628
+ {
629
+ "type": "string",
630
+ "minLength": 1
631
+ },
632
+ {
633
+ "type": "object",
634
+ "additionalProperties": false,
635
+ "required": [
636
+ "en",
637
+ "es"
638
+ ],
639
+ "properties": {
640
+ "en": {
641
+ "type": "string",
642
+ "minLength": 1
643
+ },
644
+ "es": {
645
+ "type": "string",
646
+ "minLength": 1
647
+ }
648
+ }
649
+ }
650
+ ]
651
+ },
652
+ "caption": {
653
+ "$ref": "#/$defs/text",
654
+ "description": "One sentence saying what the reader should take from the illustration."
655
+ }
656
+ }
657
+ }
658
+ }
659
+ }