@gmb/bitmark-parser-generator 5.23.0 → 5.24.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.
- package/dist/browser/bitmark-parser-generator.min.js +1 -1
- package/dist/browser/bundle-report.html +2 -2
- package/dist/browser/cjs/index.cjs +1866 -154
- package/dist/browser/cjs/index.cjs.map +1 -1
- package/dist/browser/cjs/index.d.cts +20 -0
- package/dist/browser/esm/index.d.ts +20 -0
- package/dist/browser/esm/index.js +1866 -154
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/cli/main.js +1893 -158
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +1893 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +1893 -158
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -729,10 +729,12 @@ var TextFormat2 = {
|
|
|
729
729
|
import "@ncoderz/superenum";
|
|
730
730
|
var CardSetConfigKey = {
|
|
731
731
|
flashcard: "flashcard",
|
|
732
|
+
flashcard1: "flashcard1",
|
|
732
733
|
definitionList: "definitionList",
|
|
733
734
|
elements: "elements",
|
|
734
735
|
statements: "statements",
|
|
735
736
|
quiz: "quiz",
|
|
737
|
+
quizResponses: "quizResponses",
|
|
736
738
|
feedback: "feedback",
|
|
737
739
|
questions: "questions",
|
|
738
740
|
matchPairs: "matchPairs",
|
|
@@ -744,6 +746,7 @@ var CardSetConfigKey = {
|
|
|
744
746
|
pronunciationTable: "pronunciationTable",
|
|
745
747
|
botActionResponses: "botActionResponses",
|
|
746
748
|
exampleBitList: "exampleBitList",
|
|
749
|
+
pageFooterSections: "pageFooterSections",
|
|
747
750
|
clozeList: "clozeList",
|
|
748
751
|
ingredients: "ingredients",
|
|
749
752
|
// DEPRECATED - TO BE REMOVED IN THE FUTURE
|
|
@@ -1160,12 +1163,17 @@ var groupKeys = {
|
|
|
1160
1163
|
group_standardAllBits: "group_standardAllBits",
|
|
1161
1164
|
group_standardItemLead: "group_standardItemLead",
|
|
1162
1165
|
group_standardItemLeadInstructionHint: "group_standardItemLeadInstructionHint",
|
|
1166
|
+
group_standardInstructionHint: "group_standardInstructionHint",
|
|
1163
1167
|
group_standardTags: "group_standardTags",
|
|
1168
|
+
group_standardTagsNoItemLead: "group_standardTagsNoItemLead",
|
|
1164
1169
|
group_imageSource: "group_imageSource",
|
|
1165
1170
|
group_technicalTerm: "group_technicalTerm",
|
|
1166
1171
|
group_person: "group_person",
|
|
1167
1172
|
group_gap: "group_gap",
|
|
1168
1173
|
group_trueFalse: "group_trueFalse",
|
|
1174
|
+
group_trueFalseInlineHighlight: "group_trueFalseInlineHighlight",
|
|
1175
|
+
group_trueFalseInlineSelect: "group_trueFalseInlineSelect",
|
|
1176
|
+
group_trueFalseResponses: "group_trueFalseResponses",
|
|
1169
1177
|
group_markConfig: "group_markConfig",
|
|
1170
1178
|
group_mark: "group_mark",
|
|
1171
1179
|
group_bookCommon: "group_bookCommon",
|
|
@@ -1173,14 +1181,18 @@ var groupKeys = {
|
|
|
1173
1181
|
group_advertisingCommon: "group_advertisingCommon",
|
|
1174
1182
|
group_platformStylesCommon: "group_platformStylesCommon",
|
|
1175
1183
|
group_quizCommon: "group_quizCommon",
|
|
1184
|
+
group_backgroundWallpaper: "group_backgroundWallpaper",
|
|
1185
|
+
group_imageNoZoom: "group_imageNoZoom",
|
|
1176
1186
|
group_resourceBitTags: "group_resourceBitTags",
|
|
1177
1187
|
group_resourceCommon: "group_resourceCommon",
|
|
1178
1188
|
group_resourceImageCommon: "group_resourceImageCommon",
|
|
1189
|
+
group_resourceImageCommonNoZoom: "group_resourceImageCommonNoZoom",
|
|
1179
1190
|
group_resourceAudioCommon: "group_resourceAudioCommon",
|
|
1180
1191
|
group_resourceVideoCommon: "group_resourceVideoCommon",
|
|
1181
1192
|
group_resourceIcon: "group_resourceIcon",
|
|
1182
1193
|
// Alias for image
|
|
1183
1194
|
group_resourceImage: "group_resourceImage",
|
|
1195
|
+
group_resourceImageNoZoom: "group_resourceImageNoZoom",
|
|
1184
1196
|
group_resourceImageEmbed: "group_resourceImageEmbed",
|
|
1185
1197
|
group_resourceImageLink: "group_resourceImageLink",
|
|
1186
1198
|
group_resourceImageResponsive: "group_resourceImageResponsive",
|
|
@@ -1457,6 +1469,7 @@ var propertyKeys = {
|
|
|
1457
1469
|
property_src4x: "@src4x",
|
|
1458
1470
|
property_srcAlt: "@srcAlt",
|
|
1459
1471
|
property_stripePricingTableId: "@stripePricingTableId",
|
|
1472
|
+
property_stripePricingTableDescriptiveName: "@stripePricingTableDescriptiveName",
|
|
1460
1473
|
property_stripePublishableKey: "@stripePublishableKey",
|
|
1461
1474
|
property_subject: "@subject",
|
|
1462
1475
|
property_subtype: "@subtype",
|
|
@@ -2208,7 +2221,7 @@ var CARDSETS = {
|
|
|
2208
2221
|
variants: [
|
|
2209
2222
|
{
|
|
2210
2223
|
jsonKey: "question.text",
|
|
2211
|
-
exportJsonKey: { question: { text: "$" } },
|
|
2224
|
+
exportJsonKey: [{ "@absent": { question: {} } }, { question: { text: "$" } }],
|
|
2212
2225
|
tags: [
|
|
2213
2226
|
{
|
|
2214
2227
|
key: ConfigKey.group_standardTags,
|
|
@@ -2224,6 +2237,136 @@ var CARDSETS = {
|
|
|
2224
2237
|
description: "Icon resource for the flashcard.",
|
|
2225
2238
|
jsonKey: "question.icon|resource(type=image, key=image)",
|
|
2226
2239
|
exportJsonKey: { question: { icon: { type: "image", image: { src: "$" } } } }
|
|
2240
|
+
},
|
|
2241
|
+
{
|
|
2242
|
+
key: ConfigKey.property_example,
|
|
2243
|
+
exportJsonKey: [
|
|
2244
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2245
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2246
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2247
|
+
],
|
|
2248
|
+
description: "Example marker for the flashcard question.",
|
|
2249
|
+
format: TagFormat.bitmarkText,
|
|
2250
|
+
nullable: true
|
|
2251
|
+
}
|
|
2252
|
+
]
|
|
2253
|
+
}
|
|
2254
|
+
]
|
|
2255
|
+
},
|
|
2256
|
+
{
|
|
2257
|
+
name: "answer",
|
|
2258
|
+
variants: [
|
|
2259
|
+
{
|
|
2260
|
+
jsonKey: "answer.text",
|
|
2261
|
+
exportJsonKey: [{ "@absent": { answer: {} } }, { answer: { text: "$" } }],
|
|
2262
|
+
tags: [
|
|
2263
|
+
{
|
|
2264
|
+
key: ConfigKey.group_standardTags,
|
|
2265
|
+
description: "Standard tags for the flashcard."
|
|
2266
|
+
},
|
|
2267
|
+
{
|
|
2268
|
+
exportJsonKey: { title: "$" },
|
|
2269
|
+
key: ConfigKey.tag_title,
|
|
2270
|
+
description: "Title of the flashcard."
|
|
2271
|
+
},
|
|
2272
|
+
{
|
|
2273
|
+
key: ConfigKey.group_resourceIcon,
|
|
2274
|
+
description: "Icon resource for the flashcard.",
|
|
2275
|
+
jsonKey: "answer.icon|resource(type=image, key=image)",
|
|
2276
|
+
exportJsonKey: { answer: { icon: { type: "image", image: { src: "$" } } } }
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
key: ConfigKey.property_example,
|
|
2280
|
+
exportJsonKey: [
|
|
2281
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2282
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2283
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2284
|
+
],
|
|
2285
|
+
description: "Example marker for the flashcard answer.",
|
|
2286
|
+
format: TagFormat.bitmarkText,
|
|
2287
|
+
nullable: true
|
|
2288
|
+
}
|
|
2289
|
+
]
|
|
2290
|
+
},
|
|
2291
|
+
{
|
|
2292
|
+
jsonKey: "alternativeAnswers[].text",
|
|
2293
|
+
exportJsonKey: { alternativeAnswers: [{ text: "$" }] },
|
|
2294
|
+
tags: [
|
|
2295
|
+
{
|
|
2296
|
+
key: ConfigKey.group_standardTags,
|
|
2297
|
+
description: "Standard tags for the flashcard."
|
|
2298
|
+
},
|
|
2299
|
+
{
|
|
2300
|
+
exportJsonKey: { title: "$" },
|
|
2301
|
+
key: ConfigKey.tag_title,
|
|
2302
|
+
description: "Title of the flashcard."
|
|
2303
|
+
},
|
|
2304
|
+
{
|
|
2305
|
+
key: ConfigKey.group_resourceIcon,
|
|
2306
|
+
description: "Icon resource for the flashcard.",
|
|
2307
|
+
jsonKey: "alternativeAnswers[].icon|resource(type=image, key=image)",
|
|
2308
|
+
exportJsonKey: {
|
|
2309
|
+
alternativeAnswers: [{ icon: { type: "image", image: { src: "$" } } }]
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
],
|
|
2313
|
+
repeatCount: Count.infinity
|
|
2314
|
+
}
|
|
2315
|
+
]
|
|
2316
|
+
}
|
|
2317
|
+
]
|
|
2318
|
+
},
|
|
2319
|
+
//
|
|
2320
|
+
// flashcard1 — single-card variant of flashcard. Same shape, but capped
|
|
2321
|
+
// at one card via `sections.default.maxCount = 1` (PLAN-085). Used by
|
|
2322
|
+
// the `flashcard-1` bit type; the multi-card `flashcard` and
|
|
2323
|
+
// `q-and-a-card` bit types continue to use the unbounded `flashcard`
|
|
2324
|
+
// cardset.
|
|
2325
|
+
//
|
|
2326
|
+
[CardSetConfigKey.flashcard1]: {
|
|
2327
|
+
jsonKey: "cards",
|
|
2328
|
+
exportJsonKey: { cards: "$" },
|
|
2329
|
+
sections: {
|
|
2330
|
+
default: {
|
|
2331
|
+
jsonKey: "cards",
|
|
2332
|
+
exportJsonKey: { cards: "$" },
|
|
2333
|
+
isDefault: true,
|
|
2334
|
+
maxCount: 1
|
|
2335
|
+
}
|
|
2336
|
+
},
|
|
2337
|
+
sides: [
|
|
2338
|
+
{
|
|
2339
|
+
name: "question",
|
|
2340
|
+
variants: [
|
|
2341
|
+
{
|
|
2342
|
+
jsonKey: "question.text",
|
|
2343
|
+
exportJsonKey: [{ "@absent": { question: {} } }, { question: { text: "$" } }],
|
|
2344
|
+
tags: [
|
|
2345
|
+
{
|
|
2346
|
+
key: ConfigKey.group_standardTags,
|
|
2347
|
+
description: "Standard tags for the flashcard."
|
|
2348
|
+
},
|
|
2349
|
+
{
|
|
2350
|
+
exportJsonKey: { title: "$" },
|
|
2351
|
+
key: ConfigKey.tag_title,
|
|
2352
|
+
description: "Title of the flashcard."
|
|
2353
|
+
},
|
|
2354
|
+
{
|
|
2355
|
+
key: ConfigKey.group_resourceIcon,
|
|
2356
|
+
description: "Icon resource for the flashcard.",
|
|
2357
|
+
jsonKey: "question.icon|resource(type=image, key=image)",
|
|
2358
|
+
exportJsonKey: { question: { icon: { type: "image", image: { src: "$" } } } }
|
|
2359
|
+
},
|
|
2360
|
+
{
|
|
2361
|
+
key: ConfigKey.property_example,
|
|
2362
|
+
exportJsonKey: [
|
|
2363
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2364
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2365
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2366
|
+
],
|
|
2367
|
+
description: "Example marker for the flashcard question.",
|
|
2368
|
+
format: TagFormat.bitmarkText,
|
|
2369
|
+
nullable: true
|
|
2227
2370
|
}
|
|
2228
2371
|
]
|
|
2229
2372
|
}
|
|
@@ -2234,7 +2377,7 @@ var CARDSETS = {
|
|
|
2234
2377
|
variants: [
|
|
2235
2378
|
{
|
|
2236
2379
|
jsonKey: "answer.text",
|
|
2237
|
-
exportJsonKey: { answer: { text: "$" } },
|
|
2380
|
+
exportJsonKey: [{ "@absent": { answer: {} } }, { answer: { text: "$" } }],
|
|
2238
2381
|
tags: [
|
|
2239
2382
|
{
|
|
2240
2383
|
key: ConfigKey.group_standardTags,
|
|
@@ -2250,6 +2393,17 @@ var CARDSETS = {
|
|
|
2250
2393
|
description: "Icon resource for the flashcard.",
|
|
2251
2394
|
jsonKey: "answer.icon|resource(type=image, key=image)",
|
|
2252
2395
|
exportJsonKey: { answer: { icon: { type: "image", image: { src: "$" } } } }
|
|
2396
|
+
},
|
|
2397
|
+
{
|
|
2398
|
+
key: ConfigKey.property_example,
|
|
2399
|
+
exportJsonKey: [
|
|
2400
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2401
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2402
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2403
|
+
],
|
|
2404
|
+
description: "Example marker for the flashcard answer.",
|
|
2405
|
+
format: TagFormat.bitmarkText,
|
|
2406
|
+
nullable: true
|
|
2253
2407
|
}
|
|
2254
2408
|
]
|
|
2255
2409
|
},
|
|
@@ -2293,7 +2447,7 @@ var CARDSETS = {
|
|
|
2293
2447
|
variants: [
|
|
2294
2448
|
{
|
|
2295
2449
|
jsonKey: "term.text",
|
|
2296
|
-
exportJsonKey: { term: { text: "$" } },
|
|
2450
|
+
exportJsonKey: [{ "@absent": { term: {} } }, { term: { text: "$" } }],
|
|
2297
2451
|
tags: [
|
|
2298
2452
|
{
|
|
2299
2453
|
key: ConfigKey.group_standardTags,
|
|
@@ -2312,6 +2466,17 @@ var CARDSETS = {
|
|
|
2312
2466
|
format: TagFormat.plainText,
|
|
2313
2467
|
jsonKey: "term.icon|resource(type=image, key=image)",
|
|
2314
2468
|
exportJsonKey: { term: { icon: { type: "image", image: { src: "$" } } } }
|
|
2469
|
+
},
|
|
2470
|
+
{
|
|
2471
|
+
key: ConfigKey.property_example,
|
|
2472
|
+
exportJsonKey: [
|
|
2473
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2474
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2475
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2476
|
+
],
|
|
2477
|
+
description: "Example marker for the definition term.",
|
|
2478
|
+
format: TagFormat.bitmarkText,
|
|
2479
|
+
nullable: true
|
|
2315
2480
|
}
|
|
2316
2481
|
]
|
|
2317
2482
|
}
|
|
@@ -2322,7 +2487,7 @@ var CARDSETS = {
|
|
|
2322
2487
|
variants: [
|
|
2323
2488
|
{
|
|
2324
2489
|
jsonKey: "definition.text",
|
|
2325
|
-
exportJsonKey: { definition: { text: "$" } },
|
|
2490
|
+
exportJsonKey: [{ "@absent": { definition: {} } }, { definition: { text: "$" } }],
|
|
2326
2491
|
tags: [
|
|
2327
2492
|
{
|
|
2328
2493
|
key: ConfigKey.group_standardTags,
|
|
@@ -2340,6 +2505,17 @@ var CARDSETS = {
|
|
|
2340
2505
|
description: "Icon resource for the definition.",
|
|
2341
2506
|
jsonKey: "definition.icon|resource(type=image, key=image)",
|
|
2342
2507
|
exportJsonKey: { definition: { icon: { type: "image", image: { src: "$" } } } }
|
|
2508
|
+
},
|
|
2509
|
+
{
|
|
2510
|
+
key: ConfigKey.property_example,
|
|
2511
|
+
exportJsonKey: [
|
|
2512
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2513
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2514
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2515
|
+
],
|
|
2516
|
+
description: "Example marker for the definition.",
|
|
2517
|
+
format: TagFormat.bitmarkText,
|
|
2518
|
+
nullable: true
|
|
2343
2519
|
}
|
|
2344
2520
|
]
|
|
2345
2521
|
},
|
|
@@ -2384,11 +2560,51 @@ var CARDSETS = {
|
|
|
2384
2560
|
{
|
|
2385
2561
|
jsonKey: "key",
|
|
2386
2562
|
exportJsonKey: { key: "$" },
|
|
2563
|
+
format: TextFormat2.plainText,
|
|
2387
2564
|
tags: [
|
|
2388
2565
|
{
|
|
2389
2566
|
key: ConfigKey.group_standardTags,
|
|
2390
2567
|
description: "Standard tags for the match pair."
|
|
2391
2568
|
},
|
|
2569
|
+
{
|
|
2570
|
+
// Pair-level example: emit `isExample` alongside `example`
|
|
2571
|
+
// (matches OLD parser's per-pair allow-list behaviour).
|
|
2572
|
+
//
|
|
2573
|
+
// PLAN-074: a valued cascade source (`[@example:V]` anywhere
|
|
2574
|
+
// in the cardset) fills each pair's `example` with `V`
|
|
2575
|
+
// once per pair from the keys-side cascade fire (single
|
|
2576
|
+
// parsed_variant per pair — no per-value duplication).
|
|
2577
|
+
//
|
|
2578
|
+
// PLAN-076 NOTE: matchPairs (TAG 415) KEEPS `example: '$'`
|
|
2579
|
+
// at the pair-object level. BPG `parseMatchPairs`
|
|
2580
|
+
// (`CardContentProcessor.ts:714-723`) emits ONE example
|
|
2581
|
+
// per PAIR (the `exampleCard` accumulator), placed at the
|
|
2582
|
+
// pair object. Unlike matchMatrix (per-cell example),
|
|
2583
|
+
// matchPairs has no nested per-cell layer, so the pair-key
|
|
2584
|
+
// `[@example:V]` must double-emit as the visible field.
|
|
2585
|
+
// Confirmed via `chaining` fixture: `match-solution-grouped`
|
|
2586
|
+
// expects `example: "packen"` at pair-object level from
|
|
2587
|
+
// `die Koffer[%1][@example:packen]`. Original PLAN-076
|
|
2588
|
+
// draft applied to both keys-side tags; the matchPairs
|
|
2589
|
+
// half was reverted after fixture parity testing.
|
|
2590
|
+
key: ConfigKey.property_example,
|
|
2591
|
+
exportJsonKey: [
|
|
2592
|
+
{ "@keyonly": { isExample: true, "@bit": { isExample: true } } },
|
|
2593
|
+
{
|
|
2594
|
+
predicates: ["@absent", { $cascade: "*" }],
|
|
2595
|
+
rule: {
|
|
2596
|
+
isExample: true,
|
|
2597
|
+
example: "$cascade",
|
|
2598
|
+
"@bit": { isExample: true }
|
|
2599
|
+
}
|
|
2600
|
+
},
|
|
2601
|
+
{ "@absent": { isExample: true } },
|
|
2602
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2603
|
+
],
|
|
2604
|
+
description: "Example marker / value on the match pair.",
|
|
2605
|
+
format: TagFormat.bitmarkText,
|
|
2606
|
+
nullable: true
|
|
2607
|
+
},
|
|
2392
2608
|
{
|
|
2393
2609
|
key: ConfigKey.tag_title,
|
|
2394
2610
|
description: "Title of the match pair.",
|
|
@@ -2397,9 +2613,19 @@ var CARDSETS = {
|
|
|
2397
2613
|
exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
|
|
2398
2614
|
},
|
|
2399
2615
|
{
|
|
2616
|
+
// PLAN-084: gate the key-side `@absent → $ancestor` cascade
|
|
2617
|
+
// synth with `@variantLacksTag=isCaseSensitive` so the rule
|
|
2618
|
+
// only fires when NO variant in the active card explicitly
|
|
2619
|
+
// carries `[@isCaseSensitive]`. When a value-side variant
|
|
2620
|
+
// carries the tag (e.g. `[@isCaseSensitive:false]`), the
|
|
2621
|
+
// synth is skipped here; the value-side explicit fire owns
|
|
2622
|
+
// the pair-level emission.
|
|
2400
2623
|
key: ConfigKey.property_isCaseSensitive,
|
|
2401
2624
|
exportJsonKey: [
|
|
2402
|
-
{
|
|
2625
|
+
{
|
|
2626
|
+
predicates: ["@absent", { "@variantLacksTag": "@isCaseSensitive" }],
|
|
2627
|
+
rule: { isCaseSensitive: "$ancestor" }
|
|
2628
|
+
},
|
|
2403
2629
|
{ isCaseSensitive: "$" }
|
|
2404
2630
|
],
|
|
2405
2631
|
description: "Property to indicate if the match is case sensitive.",
|
|
@@ -2428,10 +2654,85 @@ var CARDSETS = {
|
|
|
2428
2654
|
{
|
|
2429
2655
|
jsonKey: "values[]",
|
|
2430
2656
|
exportJsonKey: { values: ["$"] },
|
|
2657
|
+
format: TextFormat2.plainText,
|
|
2431
2658
|
tags: [
|
|
2432
2659
|
{
|
|
2433
|
-
|
|
2434
|
-
|
|
2660
|
+
// PLAN-084: value-side excludes item/lead/pageNumber/marginNumber.
|
|
2661
|
+
// BPG `parseMatchPairs` does `delete tags.item; delete tags.lead;`
|
|
2662
|
+
// for sideIdx > 0; the schema-side equivalent is to use a
|
|
2663
|
+
// group_standardTags variant that omits group_standardItemLead.
|
|
2664
|
+
key: ConfigKey.group_standardTagsNoItemLead,
|
|
2665
|
+
description: "Standard tags for the match pair (values side, no item/lead)."
|
|
2666
|
+
},
|
|
2667
|
+
{
|
|
2668
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.6: cascade-fired
|
|
2669
|
+
// `@example` from the bit header fills each pair's
|
|
2670
|
+
// `example` with the pair's first value (mirrors BPG's
|
|
2671
|
+
// `fillStringExample(pairs, __defaultExample=values[0])`).
|
|
2672
|
+
//
|
|
2673
|
+
// PLAN-074: the cascade-source-VALUE branch is handled by
|
|
2674
|
+
// TAG 415 (keys side) which fires once per pair — keeping
|
|
2675
|
+
// it here would emit `example` twice per pair (one per
|
|
2676
|
+
// values-side parsed_variant) and merge them into a
|
|
2677
|
+
// multi-paragraph array.
|
|
2678
|
+
//
|
|
2679
|
+
// PLAN-075: bare `$parent` reads the parent variant fire's
|
|
2680
|
+
// source `$` value (the current `++`-iteration's value
|
|
2681
|
+
// text). For single-value pairs this matches the old
|
|
2682
|
+
// `$parent.values[0]`; for multi-value pairs with
|
|
2683
|
+
// `[@example]` attached to a non-first value, it correctly
|
|
2684
|
+
// resolves to that value.
|
|
2685
|
+
//
|
|
2686
|
+
// PLAN-077: dual `[@absent, { '$cascade': '*' }]` rule
|
|
2687
|
+
// routes pair-key `[@example:V]` (a per-pair cascade
|
|
2688
|
+
// source, bound via per-card CascadeCounters scope) and
|
|
2689
|
+
// bit-header `[@example:V]` (cardset cascade) into the
|
|
2690
|
+
// pair-level `example` via `$cascade`. The aggregator in
|
|
2691
|
+
// `populate_variants` fires this rule ONCE per pair (BPG
|
|
2692
|
+
// `parseMatchPairs` `exampleCard` precedence), avoiding
|
|
2693
|
+
// per-iter pollution.
|
|
2694
|
+
key: ConfigKey.property_example,
|
|
2695
|
+
exportJsonKey: [
|
|
2696
|
+
// PLAN-084: bare `[@example]` on a values-side variant fires
|
|
2697
|
+
// once per pair (first-wins, mirrors BPG `parseMatchPairs`
|
|
2698
|
+
// `exampleCard` + `pushDownTree` set-if-null semantic).
|
|
2699
|
+
// `maxEmits: 1` enforced inside the per-pair cascade-counter
|
|
2700
|
+
// scope opened by `build_card_item`.
|
|
2701
|
+
{
|
|
2702
|
+
predicates: ["@keyonly"],
|
|
2703
|
+
maxEmits: 1,
|
|
2704
|
+
rule: {
|
|
2705
|
+
isExample: true,
|
|
2706
|
+
example: "$parent",
|
|
2707
|
+
"@bit": { isExample: true }
|
|
2708
|
+
}
|
|
2709
|
+
},
|
|
2710
|
+
{
|
|
2711
|
+
predicates: ["@absent", { $cascade: "*" }],
|
|
2712
|
+
rule: {
|
|
2713
|
+
isExample: true,
|
|
2714
|
+
example: "$cascade",
|
|
2715
|
+
"@bit": { isExample: true }
|
|
2716
|
+
}
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
"@absent": {
|
|
2720
|
+
isExample: true,
|
|
2721
|
+
example: "$parent",
|
|
2722
|
+
"@bit": { isExample: true }
|
|
2723
|
+
}
|
|
2724
|
+
},
|
|
2725
|
+
// PLAN-084: same cap applies to the explicit-value `[@example:V]`
|
|
2726
|
+
// form so per-`++`-iter values-side fires also first-win.
|
|
2727
|
+
{
|
|
2728
|
+
predicates: [],
|
|
2729
|
+
maxEmits: 1,
|
|
2730
|
+
rule: { isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2731
|
+
}
|
|
2732
|
+
],
|
|
2733
|
+
description: "Example marker / value on the match pair (values side).",
|
|
2734
|
+
format: TagFormat.bitmarkText,
|
|
2735
|
+
nullable: true
|
|
2435
2736
|
},
|
|
2436
2737
|
{
|
|
2437
2738
|
key: ConfigKey.tag_title,
|
|
@@ -2441,9 +2742,13 @@ var CARDSETS = {
|
|
|
2441
2742
|
exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
|
|
2442
2743
|
},
|
|
2443
2744
|
{
|
|
2745
|
+
// PLAN-084: symmetric @variantLacksTag gating with the key-side.
|
|
2444
2746
|
key: ConfigKey.property_isCaseSensitive,
|
|
2445
2747
|
exportJsonKey: [
|
|
2446
|
-
{
|
|
2748
|
+
{
|
|
2749
|
+
predicates: ["@absent", { "@variantLacksTag": "@isCaseSensitive" }],
|
|
2750
|
+
rule: { isCaseSensitive: "$ancestor" }
|
|
2751
|
+
},
|
|
2447
2752
|
{ isCaseSensitive: "$" }
|
|
2448
2753
|
],
|
|
2449
2754
|
description: "Property to indicate if the match is case sensitive.",
|
|
@@ -2469,6 +2774,7 @@ var CARDSETS = {
|
|
|
2469
2774
|
{
|
|
2470
2775
|
jsonKey: "key",
|
|
2471
2776
|
exportJsonKey: { key: "$" },
|
|
2777
|
+
format: TextFormat2.plainText,
|
|
2472
2778
|
tags: [
|
|
2473
2779
|
{
|
|
2474
2780
|
key: ConfigKey.group_standardTags,
|
|
@@ -2498,10 +2804,12 @@ var CARDSETS = {
|
|
|
2498
2804
|
{
|
|
2499
2805
|
jsonKey: "values[]",
|
|
2500
2806
|
exportJsonKey: { values: ["$"] },
|
|
2807
|
+
format: TextFormat2.plainText,
|
|
2501
2808
|
tags: [
|
|
2502
2809
|
{
|
|
2503
|
-
|
|
2504
|
-
|
|
2810
|
+
// PLAN-084: value-side excludes item/lead/pageNumber/marginNumber.
|
|
2811
|
+
key: ConfigKey.group_standardTagsNoItemLead,
|
|
2812
|
+
description: "Standard tags for the audio match pair (values side, no item/lead)."
|
|
2505
2813
|
},
|
|
2506
2814
|
{
|
|
2507
2815
|
key: ConfigKey.tag_title,
|
|
@@ -2534,6 +2842,7 @@ var CARDSETS = {
|
|
|
2534
2842
|
{
|
|
2535
2843
|
jsonKey: "key",
|
|
2536
2844
|
exportJsonKey: { key: "$" },
|
|
2845
|
+
format: TextFormat2.plainText,
|
|
2537
2846
|
tags: [
|
|
2538
2847
|
{
|
|
2539
2848
|
key: ConfigKey.group_standardTags,
|
|
@@ -2563,10 +2872,12 @@ var CARDSETS = {
|
|
|
2563
2872
|
{
|
|
2564
2873
|
jsonKey: "values[]",
|
|
2565
2874
|
exportJsonKey: { values: ["$"] },
|
|
2875
|
+
format: TextFormat2.plainText,
|
|
2566
2876
|
tags: [
|
|
2567
2877
|
{
|
|
2568
|
-
|
|
2569
|
-
|
|
2878
|
+
// PLAN-084: value-side excludes item/lead/pageNumber/marginNumber.
|
|
2879
|
+
key: ConfigKey.group_standardTagsNoItemLead,
|
|
2880
|
+
description: "Standard tags for the image match pair (values side, no item/lead)."
|
|
2570
2881
|
},
|
|
2571
2882
|
{
|
|
2572
2883
|
key: ConfigKey.tag_title,
|
|
@@ -2599,20 +2910,49 @@ var CARDSETS = {
|
|
|
2599
2910
|
{
|
|
2600
2911
|
jsonKey: "key",
|
|
2601
2912
|
exportJsonKey: { key: "$" },
|
|
2913
|
+
format: TextFormat2.plainText,
|
|
2602
2914
|
tags: [
|
|
2603
2915
|
{
|
|
2604
2916
|
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
2605
2917
|
description: "Standard tags for lead, instruction, and hint."
|
|
2606
2918
|
},
|
|
2607
2919
|
{
|
|
2920
|
+
// PLAN-076: drop `example: '$'` from valued rule — pair-key
|
|
2921
|
+
// `[@example:V]` is consumed as the per-pair cascade source.
|
|
2922
|
+
// PLAN-077 R14 follow-up: investigation showed the fixture
|
|
2923
|
+
// reference is INCONSISTENT — bits without a cardset-level
|
|
2924
|
+
// cascade (e.g. bit 3 `[@example:Y]should be...`) expect
|
|
2925
|
+
// pair-level `example: V` at pair scope, but bits WITH a
|
|
2926
|
+
// cardset cascade (e.g. bit 8 `[@example:99]` in title-row
|
|
2927
|
+
// PLUS pair-key `[@example:Y]`) expect NO pair-level
|
|
2928
|
+
// example. Emitting `example: $` here satisfies bit 3 but
|
|
2929
|
+
// breaks bit 8; dropping it satisfies bit 8 but breaks bit
|
|
2930
|
+
// 3. Conditional emission would require runtime gating on
|
|
2931
|
+
// the cardset cascade scope state. Left dropped pending a
|
|
2932
|
+
// dedicated plan — accepted divergence on bit 3's pair-
|
|
2933
|
+
// level emission (cells still get the per-cell `example`
|
|
2934
|
+
// correctly via PLAN-077 §4.2 + §4.3).
|
|
2608
2935
|
key: ConfigKey.property_example,
|
|
2609
2936
|
exportJsonKey: [
|
|
2610
|
-
{
|
|
2611
|
-
|
|
2612
|
-
|
|
2937
|
+
{
|
|
2938
|
+
"@keyonly": {
|
|
2939
|
+
isExample: true,
|
|
2940
|
+
"@bit": { isExample: true },
|
|
2941
|
+
"@card": { isExample: true }
|
|
2942
|
+
}
|
|
2943
|
+
},
|
|
2944
|
+
{
|
|
2945
|
+
"@absent": {
|
|
2946
|
+
isExample: true,
|
|
2947
|
+
"@bit": { isExample: true },
|
|
2948
|
+
"@card": { isExample: true }
|
|
2949
|
+
}
|
|
2950
|
+
},
|
|
2951
|
+
{ isExample: true, "@bit": { isExample: true }, "@card": { isExample: true } }
|
|
2613
2952
|
],
|
|
2614
2953
|
description: "Example text for the match matrix.",
|
|
2615
|
-
format: TagFormat.plainText
|
|
2954
|
+
format: TagFormat.plainText,
|
|
2955
|
+
nullable: true
|
|
2616
2956
|
},
|
|
2617
2957
|
{
|
|
2618
2958
|
key: ConfigKey.tag_title,
|
|
@@ -2640,35 +2980,96 @@ var CARDSETS = {
|
|
|
2640
2980
|
variants: [
|
|
2641
2981
|
{
|
|
2642
2982
|
jsonKey: "cells[{s}].values[]",
|
|
2643
|
-
exportJsonKey:
|
|
2983
|
+
exportJsonKey: [
|
|
2984
|
+
// PLAN-085 / R14: the positional-blank emission for an
|
|
2985
|
+
// effectively-absent cell side fires ONLY when the active
|
|
2986
|
+
// card has at least one `[#]` variant fire. This matches
|
|
2987
|
+
// BPG `extractHeadingCard`'s `isHeading` gate: when no
|
|
2988
|
+
// `[#]` exists anywhere in the title card, BPG returns
|
|
2989
|
+
// undefined and no `heading` is emitted. The phantom
|
|
2990
|
+
// `forValues:['']` placeholder is appropriate only when
|
|
2991
|
+
// the card is being treated as a title-row.
|
|
2992
|
+
{
|
|
2993
|
+
predicates: ["@absent", { "@variantHasTag": "#" }],
|
|
2994
|
+
rule: { "@bit": { heading: { forValues: [""] } } }
|
|
2995
|
+
},
|
|
2996
|
+
{ cells: { $s: { values: ["$"] } } }
|
|
2997
|
+
],
|
|
2998
|
+
format: TextFormat2.plainText,
|
|
2644
2999
|
tags: [
|
|
2645
3000
|
{
|
|
2646
3001
|
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
2647
3002
|
description: "Standard tags for lead, instruction, and hint."
|
|
2648
3003
|
},
|
|
2649
3004
|
{
|
|
3005
|
+
// PLAN-075: bare `$parent` reads the parent variant fire's
|
|
3006
|
+
// source `$` value (the current `++`-iteration's cell text).
|
|
3007
|
+
// Replaces `$parent.values[0]` which pinned to position 0
|
|
3008
|
+
// regardless of which `++`-value `[@example]` was on.
|
|
3009
|
+
//
|
|
3010
|
+
// PLAN-077: dual `[@absent, { '$cascade': '*' }]` rule
|
|
3011
|
+
// routes pair-key `[@example:V]` (a per-pair cascade
|
|
3012
|
+
// source, bound via per-card CascadeCounters scope) and
|
|
3013
|
+
// bit-header `[@example:V]` (cardset cascade) into the
|
|
3014
|
+
// per-cell `example` via `$cascade`. The aggregator in
|
|
3015
|
+
// `populate_variants` fires this rule ONCE per cell (BPG
|
|
3016
|
+
// `parseMatchMatrix` `exampleSide` precedence), avoiding
|
|
3017
|
+
// per-iter pollution.
|
|
3018
|
+
// @card scope-shift writes matrix-row container isExample.
|
|
2650
3019
|
key: ConfigKey.property_example,
|
|
2651
3020
|
exportJsonKey: [
|
|
2652
3021
|
{
|
|
2653
3022
|
"@keyonly": {
|
|
2654
|
-
cells: { $s: { isExample: true, example: "$parent
|
|
2655
|
-
"@bit": { isExample: true }
|
|
3023
|
+
cells: { $s: { isExample: true, example: "$parent" } },
|
|
3024
|
+
"@bit": { isExample: true },
|
|
3025
|
+
"@card": { isExample: true }
|
|
2656
3026
|
}
|
|
2657
3027
|
},
|
|
2658
3028
|
{
|
|
2659
|
-
"@absent"
|
|
3029
|
+
predicates: ["@absent", { $cascade: "*" }],
|
|
3030
|
+
rule: {
|
|
3031
|
+
cells: { $s: { isExample: true, example: "$cascade" } },
|
|
3032
|
+
"@bit": { isExample: true },
|
|
3033
|
+
"@card": { isExample: true }
|
|
3034
|
+
}
|
|
2660
3035
|
},
|
|
2661
|
-
{
|
|
3036
|
+
{
|
|
3037
|
+
"@absent": {
|
|
3038
|
+
cells: { $s: { isExample: true, example: "$parent" } },
|
|
3039
|
+
"@bit": { isExample: true },
|
|
3040
|
+
"@card": { isExample: true }
|
|
3041
|
+
}
|
|
3042
|
+
},
|
|
3043
|
+
{
|
|
3044
|
+
cells: { $s: { isExample: true, example: "$" } },
|
|
3045
|
+
"@bit": { isExample: true },
|
|
3046
|
+
"@card": { isExample: true }
|
|
3047
|
+
}
|
|
2662
3048
|
],
|
|
2663
3049
|
description: "Example text for the match matrix.",
|
|
2664
|
-
format: TagFormat.
|
|
3050
|
+
format: TagFormat.bitmarkText,
|
|
3051
|
+
nullable: true
|
|
2665
3052
|
},
|
|
2666
3053
|
{
|
|
3054
|
+
// PLAN-085 / R14: bare `[#]` on a value-side emits the
|
|
3055
|
+
// empty-string positional blank into `forValues` so the
|
|
3056
|
+
// array stays aligned with the cell positions (matches BPG
|
|
3057
|
+
// `extractHeadingCard`'s "all value-side headings present"
|
|
3058
|
+
// shape). The `@keyonly` rule is required for two reasons:
|
|
3059
|
+
// 1) it provides an emission for bare `[#]` (the `$` sigil
|
|
3060
|
+
// in the unconditional rule has no source for bare); and
|
|
3061
|
+
// 2) the presence of any `@keyonly` rule disables the
|
|
3062
|
+
// optimised-mode `should_suppress_outcome` strip (see
|
|
3063
|
+
// `forward_emit.rs`) so the resulting `forValues: [""]`
|
|
3064
|
+
// survives the all-natural-defaults check.
|
|
2667
3065
|
key: ConfigKey.tag_title,
|
|
2668
3066
|
description: "Title of the match matrix.",
|
|
2669
3067
|
format: TagFormat.plainText,
|
|
2670
3068
|
jsonKey: "^heading.forValues",
|
|
2671
|
-
exportJsonKey:
|
|
3069
|
+
exportJsonKey: [
|
|
3070
|
+
{ "@keyonly": { "@bit": { heading: { forValues: [""] } } } },
|
|
3071
|
+
{ "@bit": { heading: { forValues: ["$"] } } }
|
|
3072
|
+
]
|
|
2672
3073
|
},
|
|
2673
3074
|
{
|
|
2674
3075
|
key: ConfigKey.property_isCaseSensitive,
|
|
@@ -2717,6 +3118,35 @@ var CARDSETS = {
|
|
|
2717
3118
|
{
|
|
2718
3119
|
key: ConfigKey.group_standardTags,
|
|
2719
3120
|
description: "Standard tags for the statement."
|
|
3121
|
+
},
|
|
3122
|
+
{
|
|
3123
|
+
// PLAN-072: cascade-fired `@example` from the bit header
|
|
3124
|
+
// fills each statement entry's `example` with the entry's
|
|
3125
|
+
// own `isCorrect`, mirroring BPG's `pushExampleDownTree`
|
|
3126
|
+
// for the statements cardset. Per-array-item strip removes
|
|
3127
|
+
// `example: false` from incorrect entries so only correct
|
|
3128
|
+
// entries retain `example: true`.
|
|
3129
|
+
key: ConfigKey.property_example,
|
|
3130
|
+
exportJsonKey: [
|
|
3131
|
+
{
|
|
3132
|
+
"@keyonly": {
|
|
3133
|
+
isExample: true,
|
|
3134
|
+
example: true,
|
|
3135
|
+
"@bit": { isExample: true }
|
|
3136
|
+
}
|
|
3137
|
+
},
|
|
3138
|
+
{
|
|
3139
|
+
"@absent": {
|
|
3140
|
+
isExample: true,
|
|
3141
|
+
example: "$parent.isCorrect",
|
|
3142
|
+
"@bit": { isExample: true }
|
|
3143
|
+
}
|
|
3144
|
+
},
|
|
3145
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3146
|
+
],
|
|
3147
|
+
description: "Example marker on the statement. Bare `[@example]` emits the boolean marker; valued `[@example:true|false]` emits the literal value. Cascade from bit-header fills `example` with the entry\u2019s own `isCorrect`.",
|
|
3148
|
+
format: TagFormat.boolean,
|
|
3149
|
+
nullable: true
|
|
2720
3150
|
}
|
|
2721
3151
|
],
|
|
2722
3152
|
bodyAllowed: false
|
|
@@ -2745,6 +3175,71 @@ var CARDSETS = {
|
|
|
2745
3175
|
{
|
|
2746
3176
|
key: ConfigKey.group_standardTags,
|
|
2747
3177
|
description: "Standard tags for the quiz."
|
|
3178
|
+
},
|
|
3179
|
+
{
|
|
3180
|
+
// ALIGN-EXAMPLE-CASCADE §3.2: variant-level cascade for
|
|
3181
|
+
// quiz choices is delegated to group_trueFalse's
|
|
3182
|
+
// chain-child `@example` (`+` chain with maxEmits:1 +
|
|
3183
|
+
// `@parent.isCorrect=true`). Variant-level `@absent`
|
|
3184
|
+
// would over-fire on subsequent correct choices and on
|
|
3185
|
+
// incorrect ones — drop it.
|
|
3186
|
+
key: ConfigKey.property_example,
|
|
3187
|
+
exportJsonKey: [
|
|
3188
|
+
{ "@keyonly": { isExample: true, "@bit": { isExample: true } } },
|
|
3189
|
+
{ isExample: true, "@bit": { isExample: true } }
|
|
3190
|
+
],
|
|
3191
|
+
description: "Example marker on the quiz choice (entry-local only; cascade handled by group_trueFalse chain-children).",
|
|
3192
|
+
format: TagFormat.boolean,
|
|
3193
|
+
nullable: true
|
|
3194
|
+
}
|
|
3195
|
+
],
|
|
3196
|
+
bodyAllowed: false
|
|
3197
|
+
}
|
|
3198
|
+
]
|
|
3199
|
+
}
|
|
3200
|
+
]
|
|
3201
|
+
},
|
|
3202
|
+
//
|
|
3203
|
+
// quiz (responses)
|
|
3204
|
+
//
|
|
3205
|
+
[CardSetConfigKey.quizResponses]: {
|
|
3206
|
+
jsonKey: "quizzes",
|
|
3207
|
+
exportJsonKey: { quizzes: "$" },
|
|
3208
|
+
sides: [
|
|
3209
|
+
{
|
|
3210
|
+
name: "responses",
|
|
3211
|
+
variants: [
|
|
3212
|
+
{
|
|
3213
|
+
jsonKey: null,
|
|
3214
|
+
tags: [
|
|
3215
|
+
{
|
|
3216
|
+
key: ConfigKey.group_trueFalseResponses,
|
|
3217
|
+
description: "Group for true/false questions."
|
|
3218
|
+
},
|
|
3219
|
+
{
|
|
3220
|
+
key: ConfigKey.group_standardTags,
|
|
3221
|
+
description: "Standard tags for the quiz."
|
|
3222
|
+
},
|
|
3223
|
+
{
|
|
3224
|
+
// PLAN-072: cascade-fired `@example` from the bit header
|
|
3225
|
+
// fills each response entry's `example` with the entry's
|
|
3226
|
+
// own `isCorrect`, mirroring BPG's `pushExampleDownTree`
|
|
3227
|
+
// for the quiz-responses cardset (statements-style).
|
|
3228
|
+
key: ConfigKey.property_example,
|
|
3229
|
+
exportJsonKey: [
|
|
3230
|
+
{ "@keyonly": { isExample: true, "@bit": { isExample: true } } },
|
|
3231
|
+
{
|
|
3232
|
+
"@absent": {
|
|
3233
|
+
isExample: true,
|
|
3234
|
+
example: "$parent.isCorrect",
|
|
3235
|
+
"@bit": { isExample: true }
|
|
3236
|
+
}
|
|
3237
|
+
},
|
|
3238
|
+
{ isExample: true, "@bit": { isExample: true } }
|
|
3239
|
+
],
|
|
3240
|
+
description: "Example marker on the quiz response; cascade from bit-header fills `example` with the entry\u2019s own `isCorrect`.",
|
|
3241
|
+
format: TagFormat.boolean,
|
|
3242
|
+
nullable: true
|
|
2748
3243
|
}
|
|
2749
3244
|
],
|
|
2750
3245
|
bodyAllowed: false
|
|
@@ -2770,6 +3265,73 @@ var CARDSETS = {
|
|
|
2770
3265
|
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
2771
3266
|
description: "Standard tags for lead, instruction, and hint."
|
|
2772
3267
|
},
|
|
3268
|
+
{
|
|
3269
|
+
// Feedback choices: `[+]` / `[-]` map to choice + `requireReason`
|
|
3270
|
+
// (NOT `isCorrect` like trueFalse). Shadow the inherited
|
|
3271
|
+
// `tag_true` / `tag_false` from `group_trueFalse` to emit the
|
|
3272
|
+
// feedback-specific shape.
|
|
3273
|
+
//
|
|
3274
|
+
// Chain @example: `[+ X][@example]` writes
|
|
3275
|
+
// `isExample/example` onto the X choice only. BPG's
|
|
3276
|
+
// `setIsExampleFlags` (Builder.ts:4041-4172) does NOT
|
|
3277
|
+
// iterate `cardNode.feedbacks` — so unlike multipleChoice,
|
|
3278
|
+
// there is no bubble to bit-level or feedbacks-level
|
|
3279
|
+
// isExample. Pattern omits `@bit` scope-shift accordingly.
|
|
3280
|
+
// No `@absent`/`@parent.isCorrect` cascade rules either:
|
|
3281
|
+
// BPG's `pushExampleDownTree` (Builder.ts:3777-3849) has
|
|
3282
|
+
// no feedback dispatch, so bit-header `[@example]` does
|
|
3283
|
+
// not flow into feedback choices.
|
|
3284
|
+
key: ConfigKey.tag_true,
|
|
3285
|
+
exportJsonKey: { choices: [{ choice: "$", requireReason: true }] },
|
|
3286
|
+
description: "Reason-required choice for feedback (`[+]`).",
|
|
3287
|
+
maxCount: Count.infinity,
|
|
3288
|
+
format: TagFormat.plainText,
|
|
3289
|
+
chain: [
|
|
3290
|
+
{
|
|
3291
|
+
key: ConfigKey.property_example,
|
|
3292
|
+
exportJsonKey: [
|
|
3293
|
+
{ "@keyonly": { isExample: true, example: true } },
|
|
3294
|
+
{ isExample: true, example: "$" }
|
|
3295
|
+
],
|
|
3296
|
+
description: "Per-choice example marker for feedback `[+]`.",
|
|
3297
|
+
format: TagFormat.boolean,
|
|
3298
|
+
maxCount: 1,
|
|
3299
|
+
nullable: true
|
|
3300
|
+
},
|
|
3301
|
+
{
|
|
3302
|
+
// `[+ X][! foo]` chains `!` (instruction) onto the
|
|
3303
|
+
// choice; same for `[?]` (hint), `[%]` (item),
|
|
3304
|
+
// `[%2]`/`[%3]`/`[%4]` (lead/pageNumber/marginNumber).
|
|
3305
|
+
// Mirrors group_trueFalse's `+` chain shape.
|
|
3306
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
3307
|
+
description: "Item, lead, page number, margin number, instruction and hint chained onto the feedback choice."
|
|
3308
|
+
}
|
|
3309
|
+
]
|
|
3310
|
+
},
|
|
3311
|
+
{
|
|
3312
|
+
key: ConfigKey.tag_false,
|
|
3313
|
+
exportJsonKey: { choices: [{ choice: "$", requireReason: false }] },
|
|
3314
|
+
description: "Reason-not-required choice for feedback (`[-]`).",
|
|
3315
|
+
maxCount: Count.infinity,
|
|
3316
|
+
format: TagFormat.plainText,
|
|
3317
|
+
chain: [
|
|
3318
|
+
{
|
|
3319
|
+
key: ConfigKey.property_example,
|
|
3320
|
+
exportJsonKey: [
|
|
3321
|
+
{ "@keyonly": { isExample: true, example: true } },
|
|
3322
|
+
{ isExample: true, example: "$" }
|
|
3323
|
+
],
|
|
3324
|
+
description: "Per-choice example marker for feedback `[-]`.",
|
|
3325
|
+
format: TagFormat.boolean,
|
|
3326
|
+
maxCount: 1,
|
|
3327
|
+
nullable: true
|
|
3328
|
+
},
|
|
3329
|
+
{
|
|
3330
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
3331
|
+
description: "Item, lead, page number, margin number, instruction and hint chained onto the feedback choice."
|
|
3332
|
+
}
|
|
3333
|
+
]
|
|
3334
|
+
},
|
|
2773
3335
|
{
|
|
2774
3336
|
key: ConfigKey.group_trueFalse,
|
|
2775
3337
|
description: "Group for true/false feedback."
|
|
@@ -2790,31 +3352,71 @@ var CARDSETS = {
|
|
|
2790
3352
|
name: "reason",
|
|
2791
3353
|
variants: [
|
|
2792
3354
|
{
|
|
3355
|
+
// PLAN: feedback.reason — Object-only variant pattern. Per
|
|
3356
|
+
// SYNTAX.md §8.1, sibling tag emissions do NOT auto-wrap
|
|
3357
|
+
// under `reason.*`; each tag here spells out the full path.
|
|
3358
|
+
// Body is a plain string (BPG `parseFeedback` uses
|
|
3359
|
+
// `cardBodyStr ?? ''` for `reason.text`).
|
|
2793
3360
|
jsonKey: "reason.text",
|
|
2794
3361
|
exportJsonKey: { reason: { text: "$" } },
|
|
3362
|
+
format: TextFormat2.plainText,
|
|
2795
3363
|
tags: [
|
|
2796
3364
|
{
|
|
2797
|
-
|
|
2798
|
-
|
|
3365
|
+
// Instruction lands under reason. Hint/item/lead/etc.
|
|
3366
|
+
// omitted: not exercised by any fixture and BPG's
|
|
3367
|
+
// `parseFeedback` spreads only the tags actually present
|
|
3368
|
+
// — adding the rest can be done lazily as fixtures
|
|
3369
|
+
// require them, with the same `{reason: {…}}` wrapper.
|
|
3370
|
+
key: ConfigKey.tag_instruction,
|
|
3371
|
+
exportJsonKey: { reason: { instruction: "$" } },
|
|
3372
|
+
description: "Instruction for the feedback reason.",
|
|
3373
|
+
format: TagFormat.bitmarkText
|
|
2799
3374
|
},
|
|
2800
3375
|
{
|
|
2801
3376
|
key: ConfigKey.property_reasonableNumOfChars,
|
|
2802
3377
|
exportJsonKey: [
|
|
2803
|
-
{ "@absent": { reasonableNumOfChars: "$ancestor" } },
|
|
2804
|
-
{ reasonableNumOfChars: "$" }
|
|
3378
|
+
{ "@absent": { reason: { reasonableNumOfChars: "$ancestor" } } },
|
|
3379
|
+
{ reason: { reasonableNumOfChars: "$" } }
|
|
2805
3380
|
],
|
|
2806
3381
|
description: "Property for reasonable number of characters.",
|
|
2807
3382
|
format: TagFormat.number
|
|
2808
3383
|
},
|
|
2809
3384
|
{
|
|
3385
|
+
// ALIGN-EXAMPLE-CASCADE §3.9: `feedback.reason` is NOT in
|
|
3386
|
+
// BPG's `pushExampleDownTree` dispatch — no bit-header
|
|
3387
|
+
// cascade. Local emission only.
|
|
3388
|
+
//
|
|
3389
|
+
// Both `reason.example` and `feedbacks[].example` are
|
|
3390
|
+
// `TextAst` per BPG's schema — paragraph arrays. Format
|
|
3391
|
+
// here is `bitmarkText` so `$` coerces to a paragraph
|
|
3392
|
+
// array at both write sites.
|
|
2810
3393
|
key: ConfigKey.property_example,
|
|
2811
3394
|
exportJsonKey: [
|
|
2812
|
-
{
|
|
2813
|
-
|
|
2814
|
-
|
|
3395
|
+
{
|
|
3396
|
+
// Bare `[@example]`: reason.example is TextAst — BPG
|
|
3397
|
+
// coerces the boolean default to a paragraph
|
|
3398
|
+
// containing the string "true". feedbacks[].example
|
|
3399
|
+
// is not TextAst, stays a boolean. Two literal writes.
|
|
3400
|
+
"@keyonly": {
|
|
3401
|
+
reason: {
|
|
3402
|
+
isExample: true,
|
|
3403
|
+
example: [{ type: "paragraph", content: [{ text: "true", type: "text" }] }]
|
|
3404
|
+
},
|
|
3405
|
+
isExample: true,
|
|
3406
|
+
example: true,
|
|
3407
|
+
"@bit": { isExample: true }
|
|
3408
|
+
}
|
|
3409
|
+
},
|
|
3410
|
+
{
|
|
3411
|
+
reason: { isExample: true, example: "$" },
|
|
3412
|
+
isExample: true,
|
|
3413
|
+
example: "$",
|
|
3414
|
+
"@bit": { isExample: true }
|
|
3415
|
+
}
|
|
2815
3416
|
],
|
|
2816
|
-
description: "Example text for the feedback.",
|
|
2817
|
-
format: TagFormat.
|
|
3417
|
+
description: "Example text for the feedback reason (entry-local only; no bit-header cascade).",
|
|
3418
|
+
format: TagFormat.bitmarkText,
|
|
3419
|
+
nullable: true
|
|
2818
3420
|
},
|
|
2819
3421
|
{
|
|
2820
3422
|
key: ConfigKey.tag_title,
|
|
@@ -2878,6 +3480,22 @@ var CARDSETS = {
|
|
|
2878
3480
|
{
|
|
2879
3481
|
key: ConfigKey.group_standardTags,
|
|
2880
3482
|
description: "Standard tags for the question."
|
|
3483
|
+
},
|
|
3484
|
+
{
|
|
3485
|
+
// ALIGN-EXAMPLE-CASCADE §3.10: `questions` is NOT in BPG's
|
|
3486
|
+
// `pushExampleDownTree` dispatch — bit-header `[@example]`
|
|
3487
|
+
// does not propagate `example`/`isExample` onto question
|
|
3488
|
+
// entries. Only entry-local `[@example]` fires (handled by
|
|
3489
|
+
// `@keyonly` and the unconditional fallback). No `@absent`
|
|
3490
|
+
// rule.
|
|
3491
|
+
key: ConfigKey.property_example,
|
|
3492
|
+
exportJsonKey: [
|
|
3493
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
3494
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3495
|
+
],
|
|
3496
|
+
description: "Example marker for the question (entry-local only; no bit-header cascade).",
|
|
3497
|
+
format: TagFormat.bitmarkText,
|
|
3498
|
+
nullable: true
|
|
2881
3499
|
}
|
|
2882
3500
|
]
|
|
2883
3501
|
}
|
|
@@ -2904,14 +3522,16 @@ var CARDSETS = {
|
|
|
2904
3522
|
description: "Standard tags for lead, instruction, and hint."
|
|
2905
3523
|
},
|
|
2906
3524
|
{
|
|
3525
|
+
// ALIGN-EXAMPLE-CASCADE §3.11: `elements` is NOT in BPG's
|
|
3526
|
+
// `pushExampleDownTree` dispatch — no bit-header cascade.
|
|
2907
3527
|
key: ConfigKey.property_example,
|
|
2908
3528
|
exportJsonKey: [
|
|
2909
3529
|
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2910
|
-
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2911
3530
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2912
3531
|
],
|
|
2913
|
-
description: "Example text for the element.",
|
|
2914
|
-
format: TagFormat.plainText
|
|
3532
|
+
description: "Example text for the element (entry-local only; no bit-header cascade).",
|
|
3533
|
+
format: TagFormat.plainText,
|
|
3534
|
+
nullable: true
|
|
2915
3535
|
}
|
|
2916
3536
|
],
|
|
2917
3537
|
repeatCount: Count.infinity
|
|
@@ -2923,9 +3543,57 @@ var CARDSETS = {
|
|
|
2923
3543
|
//
|
|
2924
3544
|
// table
|
|
2925
3545
|
//
|
|
3546
|
+
// PLAN-079: supports BOTH source formats and collapses to the same basic
|
|
3547
|
+
// output (`{ columns?, data, columnWidths? }`):
|
|
3548
|
+
//
|
|
3549
|
+
// 1. Basic format — first card carries `[#X]` markers (fire `tag_title`
|
|
3550
|
+
// → `^table.columns[]`); subsequent cards are body rows. Cards have
|
|
3551
|
+
// no qualifier, so they route to the `table-body` (default) section.
|
|
3552
|
+
//
|
|
3553
|
+
// 2. Extended format — `==== table-header ====` / `==== table-footer ====`
|
|
3554
|
+
// qualifiers. The `table-header` section uses `@cardIndex=0` to route
|
|
3555
|
+
// the first header card's cells to `columns` and demote remaining
|
|
3556
|
+
// header cards (rows) into `data`. Per-cell `[@tableRowSpan]` /
|
|
3557
|
+
// `[@tableScope]` / `[@tableCellType]` tags are valid-but-unmapped
|
|
3558
|
+
// here (no per-cell metadata in basic shape) — declared on the cell
|
|
3559
|
+
// variant below.
|
|
3560
|
+
//
|
|
2926
3561
|
[CardSetConfigKey.table]: {
|
|
2927
|
-
jsonKey:
|
|
2928
|
-
exportJsonKey:
|
|
3562
|
+
jsonKey: null,
|
|
3563
|
+
exportJsonKey: null,
|
|
3564
|
+
sections: {
|
|
3565
|
+
"table-header": {
|
|
3566
|
+
// First header card's row of cells → `columns`. Subsequent header
|
|
3567
|
+
// cards' rows → `data` (per-card append; `[$]` shape because
|
|
3568
|
+
// per-card emission fires once per card, multiple fires deep_merge-
|
|
3569
|
+
// append). PLAN-079 + PLAN-080: predicates inside exportJsonKey
|
|
3570
|
+
// both ROUTE cards to this section (when no explicit `==== table-
|
|
3571
|
+
// header ====` qualifier) and SELECT the rule body once routed.
|
|
3572
|
+
// First rule = first card with any `[#]` → `columns`; second rule
|
|
3573
|
+
// = subsequent cards in this section → `data` (per-row append).
|
|
3574
|
+
jsonKey: "table.columns",
|
|
3575
|
+
exportJsonKey: [
|
|
3576
|
+
{
|
|
3577
|
+
predicates: [{ "@cardIndex": 0 }, { "@variantHasTag": "#" }],
|
|
3578
|
+
rule: { "@bit": { table: { columns: "$" } } }
|
|
3579
|
+
},
|
|
3580
|
+
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3581
|
+
{ "@bit": { table: { data: ["$"] } } }
|
|
3582
|
+
]
|
|
3583
|
+
},
|
|
3584
|
+
"table-body": {
|
|
3585
|
+
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3586
|
+
// This is the default section (no qualifier → cards land here).
|
|
3587
|
+
jsonKey: "table.data",
|
|
3588
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3589
|
+
isDefault: true
|
|
3590
|
+
},
|
|
3591
|
+
"table-footer": {
|
|
3592
|
+
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3593
|
+
jsonKey: "table.data",
|
|
3594
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3595
|
+
}
|
|
3596
|
+
},
|
|
2929
3597
|
sides: [
|
|
2930
3598
|
{
|
|
2931
3599
|
name: "cell",
|
|
@@ -2966,6 +3634,8 @@ var CARDSETS = {
|
|
|
2966
3634
|
},
|
|
2967
3635
|
{
|
|
2968
3636
|
key: ConfigKey.property_tableColWidth,
|
|
3637
|
+
jsonKey: "^table.columnWidths[{s}]",
|
|
3638
|
+
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
2969
3639
|
description: "Width for the column.",
|
|
2970
3640
|
format: TagFormat.number
|
|
2971
3641
|
}
|
|
@@ -2984,7 +3654,22 @@ var CARDSETS = {
|
|
|
2984
3654
|
sections: {
|
|
2985
3655
|
"table-header": {
|
|
2986
3656
|
jsonKey: "table.header.rows",
|
|
2987
|
-
|
|
3657
|
+
// PLAN-080: section dispatch via predicates inside exportJsonKey.
|
|
3658
|
+
// Cards with no explicit `==== table-header ====` qualifier
|
|
3659
|
+
// route here if FIRST CARD contains any `[#]` tag in any
|
|
3660
|
+
// variant. Explicit-qualifier cards fall through to the
|
|
3661
|
+
// unconditional fallback rule. Both rules use the per-card
|
|
3662
|
+
// append shape `rows: ['$']` — the runtime triggers per-card
|
|
3663
|
+
// emission whenever the pattern carries predicates, and each
|
|
3664
|
+
// fire appends a single-element array (multi-fire deep-merge
|
|
3665
|
+
// concatenates).
|
|
3666
|
+
exportJsonKey: [
|
|
3667
|
+
{
|
|
3668
|
+
predicates: [{ "@cardIndex": 0 }, { "@variantHasTag": "#" }],
|
|
3669
|
+
rule: { table: { header: { rows: ["$"] } } }
|
|
3670
|
+
},
|
|
3671
|
+
{ table: { header: { rows: ["$"] } } }
|
|
3672
|
+
],
|
|
2988
3673
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
2989
3674
|
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
2990
3675
|
},
|
|
@@ -3017,13 +3702,13 @@ var CARDSETS = {
|
|
|
3017
3702
|
},
|
|
3018
3703
|
{
|
|
3019
3704
|
key: ConfigKey.tag_title,
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
},
|
|
3026
|
-
description: "Title of the table cell."
|
|
3705
|
+
// PLAN-080: the `[#]` tag writes its text to the cell's
|
|
3706
|
+
// `content` field. When the card is in the `table-header`
|
|
3707
|
+
// section, the section's sideExportJsonKey wraps each
|
|
3708
|
+
// cell with `title: true` automatically.
|
|
3709
|
+
jsonKey: "content",
|
|
3710
|
+
exportJsonKey: { content: "$" },
|
|
3711
|
+
description: "Title text of the table cell (header rows)."
|
|
3027
3712
|
},
|
|
3028
3713
|
{
|
|
3029
3714
|
key: ConfigKey.property_tableCellType,
|
|
@@ -3055,6 +3740,9 @@ var CARDSETS = {
|
|
|
3055
3740
|
},
|
|
3056
3741
|
{
|
|
3057
3742
|
key: ConfigKey.property_tableColWidth,
|
|
3743
|
+
// PLAN-080: write to the cell's `colwidth` field.
|
|
3744
|
+
jsonKey: "colwidth",
|
|
3745
|
+
exportJsonKey: { colwidth: "$" },
|
|
3058
3746
|
description: "Width for the column.",
|
|
3059
3747
|
format: TagFormat.number
|
|
3060
3748
|
}
|
|
@@ -3092,7 +3780,8 @@ var CARDSETS = {
|
|
|
3092
3780
|
{
|
|
3093
3781
|
key: ConfigKey.resource_audio,
|
|
3094
3782
|
description: "Audio resource for the pronunciation table.",
|
|
3095
|
-
jsonKey: "audio"
|
|
3783
|
+
jsonKey: "audio",
|
|
3784
|
+
exportJsonKey: { audio: { type: "audio", audio: { src: "$" } } }
|
|
3096
3785
|
}
|
|
3097
3786
|
],
|
|
3098
3787
|
repeatCount: Count.infinity
|
|
@@ -3163,14 +3852,17 @@ var CARDSETS = {
|
|
|
3163
3852
|
format: TagFormat.plainText
|
|
3164
3853
|
},
|
|
3165
3854
|
{
|
|
3855
|
+
// ALIGN-EXAMPLE-CASCADE §3.12: `bot-action-responses` is
|
|
3856
|
+
// NOT in BPG's `pushExampleDownTree` dispatch — no bit-
|
|
3857
|
+
// header cascade.
|
|
3166
3858
|
key: ConfigKey.property_example,
|
|
3167
3859
|
exportJsonKey: [
|
|
3168
3860
|
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
3169
|
-
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
3170
3861
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3171
3862
|
],
|
|
3172
|
-
description: "Example text for the bot action response.",
|
|
3173
|
-
format: TagFormat.plainText
|
|
3863
|
+
description: "Example text for the bot action response (entry-local only; no bit-header cascade).",
|
|
3864
|
+
format: TagFormat.plainText,
|
|
3865
|
+
nullable: true
|
|
3174
3866
|
}
|
|
3175
3867
|
]
|
|
3176
3868
|
}
|
|
@@ -3236,6 +3928,38 @@ var CARDSETS = {
|
|
|
3236
3928
|
]
|
|
3237
3929
|
},
|
|
3238
3930
|
//
|
|
3931
|
+
// page-footer-sections — mirrors example-bit-list but emits cards under
|
|
3932
|
+
// `sections` instead of `listItems`. BPG's JsonGenerator special-cases
|
|
3933
|
+
// BitType.pageFooter in code; this dedicated cardSet expresses the same
|
|
3934
|
+
// routing as pure config so the Rust serializer can pick it up.
|
|
3935
|
+
//
|
|
3936
|
+
[CardSetConfigKey.pageFooterSections]: {
|
|
3937
|
+
jsonKey: "sections",
|
|
3938
|
+
exportJsonKey: { sections: "$" },
|
|
3939
|
+
sides: [
|
|
3940
|
+
{
|
|
3941
|
+
name: "item",
|
|
3942
|
+
variants: [
|
|
3943
|
+
{
|
|
3944
|
+
jsonKey: "body",
|
|
3945
|
+
exportJsonKey: { body: "$" },
|
|
3946
|
+
tags: [
|
|
3947
|
+
{
|
|
3948
|
+
key: ConfigKey.group_standardTags,
|
|
3949
|
+
description: "Standard tags for page-footer section bits."
|
|
3950
|
+
},
|
|
3951
|
+
{
|
|
3952
|
+
exportJsonKey: { title: "$" },
|
|
3953
|
+
key: ConfigKey.tag_title,
|
|
3954
|
+
description: "Title of the page-footer section."
|
|
3955
|
+
}
|
|
3956
|
+
]
|
|
3957
|
+
}
|
|
3958
|
+
]
|
|
3959
|
+
}
|
|
3960
|
+
]
|
|
3961
|
+
},
|
|
3962
|
+
//
|
|
3239
3963
|
// ingredients
|
|
3240
3964
|
//
|
|
3241
3965
|
[CardSetConfigKey.ingredients]: {
|
|
@@ -3566,7 +4290,11 @@ var GROUPS = {
|
|
|
3566
4290
|
{
|
|
3567
4291
|
key: ConfigKey.property_groupTag,
|
|
3568
4292
|
jsonKey: "groupTag.name",
|
|
3569
|
-
|
|
4293
|
+
// PLAN-063: starter-array shape with `@id` declares entity-merge
|
|
4294
|
+
// semantics — repeated `[@groupTag: name]` occurrences with the
|
|
4295
|
+
// same value fold into one entry; chained `@tag` children's
|
|
4296
|
+
// arrays merge as sets.
|
|
4297
|
+
exportJsonKey: { groupTag: [{ "@id": "name", name: "$" }] },
|
|
3570
4298
|
description: "The group tag(s) for the bit",
|
|
3571
4299
|
format: TagFormat.plainText,
|
|
3572
4300
|
maxCount: Count.infinity,
|
|
@@ -3739,6 +4467,24 @@ var GROUPS = {
|
|
|
3739
4467
|
}
|
|
3740
4468
|
]
|
|
3741
4469
|
},
|
|
4470
|
+
[ConfigKey.group_standardInstructionHint]: {
|
|
4471
|
+
type: GroupConfigType.standard,
|
|
4472
|
+
description: "Standard group for instruction and hint tags only (no item/lead/pageNumber/marginNumber chain). Used by sides where item/lead are owned by another side (e.g. matchPairs value-side, which BPG strips item/lead from at sideIdx > 0).",
|
|
4473
|
+
tags: [
|
|
4474
|
+
{
|
|
4475
|
+
exportJsonKey: { instruction: "$" },
|
|
4476
|
+
key: ConfigKey.tag_instruction,
|
|
4477
|
+
name: "Instruction",
|
|
4478
|
+
description: "The instruction for the bit"
|
|
4479
|
+
},
|
|
4480
|
+
{
|
|
4481
|
+
exportJsonKey: { hint: "$" },
|
|
4482
|
+
key: ConfigKey.tag_hint,
|
|
4483
|
+
name: "Hint",
|
|
4484
|
+
description: "The hint for the bit"
|
|
4485
|
+
}
|
|
4486
|
+
]
|
|
4487
|
+
},
|
|
3742
4488
|
[ConfigKey.group_standardTags]: {
|
|
3743
4489
|
type: GroupConfigType.standard,
|
|
3744
4490
|
description: "Standard tags which apply to MOST (but not all) bits",
|
|
@@ -3752,17 +4498,45 @@ var GROUPS = {
|
|
|
3752
4498
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
3753
4499
|
},
|
|
3754
4500
|
{
|
|
3755
|
-
// Bit-level example tag
|
|
3756
|
-
//
|
|
3757
|
-
//
|
|
4501
|
+
// Bit-level example tag (default — non-`isTopLevelExample` bits):
|
|
4502
|
+
// - bare `[@example]`: consume only (records cascade marker, emits
|
|
4503
|
+
// nothing at bit-level — OLD parser scrubs bit-level isExample
|
|
4504
|
+
// for bits NOT in its `isTopLevelExample` allow-list).
|
|
4505
|
+
// - synthesized (descendant cascade): still emits `isExample: true`
|
|
4506
|
+
// at the descendant scope.
|
|
4507
|
+
// - valued `[@example:text]`: emit the example value only; bit-level
|
|
4508
|
+
// `isExample` is left to bubble from descendants.
|
|
4509
|
+
// Bits in the OLD parser's allow-list (flashcard, definitionList,
|
|
4510
|
+
// sequence, multipleChoice, trueFalse, cloze*, mark, interview,
|
|
4511
|
+
// matchMatrix, match, essay, etc.) override this entry with the
|
|
4512
|
+
// legacy emit-isExample shape.
|
|
3758
4513
|
key: ConfigKey.property_example,
|
|
3759
|
-
exportJsonKey: [
|
|
3760
|
-
{ "@keyonly": { isExample: true } },
|
|
3761
|
-
{ "@absent": { isExample: true } },
|
|
3762
|
-
{ isExample: true, example: "$" }
|
|
3763
|
-
],
|
|
4514
|
+
exportJsonKey: [{ "@keyonly": {} }, { "@absent": { isExample: true } }, { example: "$" }],
|
|
3764
4515
|
description: "The example(s) for the bit",
|
|
3765
|
-
format: TagFormat.bitmarkText
|
|
4516
|
+
format: TagFormat.bitmarkText,
|
|
4517
|
+
nullable: true
|
|
4518
|
+
}
|
|
4519
|
+
]
|
|
4520
|
+
},
|
|
4521
|
+
[ConfigKey.group_standardTagsNoItemLead]: {
|
|
4522
|
+
type: GroupConfigType.standard,
|
|
4523
|
+
description: "Standard tags mirror of group_standardTags but excluding the item/lead/pageNumber/marginNumber chain. Used by sides where item/lead are owned by another side (e.g. matchPairs value-side \u2014 BPG `parseMatchPairs` strips tags.item / tags.lead for sideIdx > 0).",
|
|
4524
|
+
tags: [
|
|
4525
|
+
{
|
|
4526
|
+
key: ConfigKey.group_standardAllBits,
|
|
4527
|
+
description: "All standard tags which apply to all bits"
|
|
4528
|
+
},
|
|
4529
|
+
{
|
|
4530
|
+
key: ConfigKey.group_standardInstructionHint,
|
|
4531
|
+
description: "Instruction and hint tags only (no item/lead chain)."
|
|
4532
|
+
},
|
|
4533
|
+
{
|
|
4534
|
+
// Mirror of group_standardTags property_example entry.
|
|
4535
|
+
key: ConfigKey.property_example,
|
|
4536
|
+
exportJsonKey: [{ "@keyonly": {} }, { "@absent": { isExample: true } }, { example: "$" }],
|
|
4537
|
+
description: "The example(s) for the bit",
|
|
4538
|
+
format: TagFormat.bitmarkText,
|
|
4539
|
+
nullable: true
|
|
3766
4540
|
}
|
|
3767
4541
|
]
|
|
3768
4542
|
},
|
|
@@ -3827,8 +4601,8 @@ var GROUPS = {
|
|
|
3827
4601
|
tags: [
|
|
3828
4602
|
{
|
|
3829
4603
|
key: ConfigKey.property_person,
|
|
3830
|
-
jsonKey: "
|
|
3831
|
-
exportJsonKey: {
|
|
4604
|
+
jsonKey: "person.name",
|
|
4605
|
+
exportJsonKey: { person: { name: "$" } },
|
|
3832
4606
|
description: "A person",
|
|
3833
4607
|
format: TagFormat.plainText,
|
|
3834
4608
|
chain: [
|
|
@@ -3848,8 +4622,8 @@ var GROUPS = {
|
|
|
3848
4622
|
{
|
|
3849
4623
|
// Deprecated (parter renamed to person)
|
|
3850
4624
|
key: ConfigKey.property_partner,
|
|
3851
|
-
jsonKey: "
|
|
3852
|
-
exportJsonKey: {
|
|
4625
|
+
jsonKey: "person.name",
|
|
4626
|
+
exportJsonKey: { person: { name: "$" } },
|
|
3853
4627
|
description: "A partner",
|
|
3854
4628
|
format: TagFormat.plainText,
|
|
3855
4629
|
chain: [
|
|
@@ -3873,7 +4647,9 @@ var GROUPS = {
|
|
|
3873
4647
|
description: "Gap chain",
|
|
3874
4648
|
tags: [
|
|
3875
4649
|
{
|
|
3876
|
-
exportJsonKey: {
|
|
4650
|
+
exportJsonKey: {
|
|
4651
|
+
"@body-inline": { type: "gap", attrs: { solutions: ["$"] } }
|
|
4652
|
+
},
|
|
3877
4653
|
key: ConfigKey.tag_gap,
|
|
3878
4654
|
description: "The value of a gap in the content",
|
|
3879
4655
|
maxCount: Count.infinity,
|
|
@@ -3892,27 +4668,37 @@ var GROUPS = {
|
|
|
3892
4668
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
3893
4669
|
},
|
|
3894
4670
|
{
|
|
4671
|
+
// BPG ExampleTagContentProcessor.ts:91-95 reads
|
|
4672
|
+
// `__solutionsAst[length - 1]` — the solution closest to the
|
|
4673
|
+
// `[@example]` tag at parse time. Our chain accumulator is built
|
|
4674
|
+
// incrementally (scope.rs `parent.merge` after each tag), so at
|
|
4675
|
+
// the moment `[@example]` fires, `solutions` only contains the
|
|
4676
|
+
// preceding `[_x]` entries — `[-1]` resolves to the closest one.
|
|
4677
|
+
// E.g. `[_cloze][_gap][@example]` → solutions=["cloze","gap"],
|
|
4678
|
+
// `[-1]`="gap"; `[_solution][@example][_problem]` →
|
|
4679
|
+
// solutions=["solution"], `[-1]`="solution".
|
|
3895
4680
|
key: ConfigKey.property_example,
|
|
3896
4681
|
jsonKey: "example",
|
|
3897
4682
|
exportJsonKey: [
|
|
3898
4683
|
{
|
|
3899
4684
|
"@keyonly": {
|
|
3900
4685
|
isExample: true,
|
|
3901
|
-
example: "$parent.solutions[
|
|
4686
|
+
example: "$parent.solutions[-1]",
|
|
3902
4687
|
"@bit": { isExample: true }
|
|
3903
4688
|
}
|
|
3904
4689
|
},
|
|
3905
4690
|
{
|
|
3906
4691
|
"@absent": {
|
|
3907
4692
|
isExample: true,
|
|
3908
|
-
example: "$parent.solutions[
|
|
4693
|
+
example: "$parent.solutions[-1]",
|
|
3909
4694
|
"@bit": { isExample: true }
|
|
3910
4695
|
}
|
|
3911
4696
|
},
|
|
3912
4697
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3913
4698
|
],
|
|
3914
4699
|
description: "An example for the gap",
|
|
3915
|
-
format: TagFormat.bitmarkText
|
|
4700
|
+
format: TagFormat.bitmarkText,
|
|
4701
|
+
nullable: true
|
|
3916
4702
|
},
|
|
3917
4703
|
{
|
|
3918
4704
|
key: ConfigKey.property_isCaseSensitive,
|
|
@@ -3961,6 +4747,24 @@ var GROUPS = {
|
|
|
3961
4747
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
3962
4748
|
},
|
|
3963
4749
|
{
|
|
4750
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.2: cascade-fired
|
|
4751
|
+
// `@example` from the bit header marks EVERY choice with
|
|
4752
|
+
// `isExample: true` (matches BPG output), but only the
|
|
4753
|
+
// FIRST correct choice gets `example: true` (BPG
|
|
4754
|
+
// `fillBooleanExample(..., firstCorrectOnly=true)`).
|
|
4755
|
+
//
|
|
4756
|
+
// Two `@absent` rules, picked first-match-wins:
|
|
4757
|
+
// 1. Verbose form gated on `@parent.isCorrect=true` with
|
|
4758
|
+
// `maxEmits:1` — fires once for the first correct.
|
|
4759
|
+
// 2. Plain `@absent` — fires on every remaining entry
|
|
4760
|
+
// (subsequent corrects and all incorrects), emitting
|
|
4761
|
+
// `isExample` only.
|
|
4762
|
+
// The `serialize_cards` cascade-counter scope holds the cap
|
|
4763
|
+
// across the whole cardset.
|
|
4764
|
+
// @card scope-shift writes choice-container isExample (e.g.
|
|
4765
|
+
// `quizzes[i].isExample`) — was previously provided by the
|
|
4766
|
+
// universal `bubble_is_example` post-walk, which was removed
|
|
4767
|
+
// in favour of explicit per-tag config. SYNTAX.md §8.
|
|
3964
4768
|
key: ConfigKey.property_example,
|
|
3965
4769
|
jsonKey: "example",
|
|
3966
4770
|
exportJsonKey: [
|
|
@@ -3968,20 +4772,37 @@ var GROUPS = {
|
|
|
3968
4772
|
"@keyonly": {
|
|
3969
4773
|
isExample: true,
|
|
3970
4774
|
example: "$parent.isCorrect",
|
|
3971
|
-
"@bit": { isExample: true }
|
|
4775
|
+
"@bit": { isExample: true },
|
|
4776
|
+
"@card": { isExample: true }
|
|
4777
|
+
}
|
|
4778
|
+
},
|
|
4779
|
+
{
|
|
4780
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
4781
|
+
maxEmits: 1,
|
|
4782
|
+
rule: {
|
|
4783
|
+
isExample: true,
|
|
4784
|
+
example: true,
|
|
4785
|
+
"@bit": { isExample: true },
|
|
4786
|
+
"@card": { isExample: true }
|
|
3972
4787
|
}
|
|
3973
4788
|
},
|
|
3974
4789
|
{
|
|
3975
4790
|
"@absent": {
|
|
3976
4791
|
isExample: true,
|
|
3977
|
-
|
|
3978
|
-
"@
|
|
4792
|
+
"@bit": { isExample: true },
|
|
4793
|
+
"@card": { isExample: true }
|
|
3979
4794
|
}
|
|
3980
4795
|
},
|
|
3981
|
-
{
|
|
4796
|
+
{
|
|
4797
|
+
isExample: true,
|
|
4798
|
+
example: "$",
|
|
4799
|
+
"@bit": { isExample: true },
|
|
4800
|
+
"@card": { isExample: true }
|
|
4801
|
+
}
|
|
3982
4802
|
],
|
|
3983
4803
|
description: "An example for the true/false statement/question",
|
|
3984
|
-
format: TagFormat.
|
|
4804
|
+
format: TagFormat.boolean,
|
|
4805
|
+
nullable: true
|
|
3985
4806
|
}
|
|
3986
4807
|
]
|
|
3987
4808
|
},
|
|
@@ -4013,6 +4834,12 @@ var GROUPS = {
|
|
|
4013
4834
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
4014
4835
|
},
|
|
4015
4836
|
{
|
|
4837
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.2: cascade-fired
|
|
4838
|
+
// `@example` on a `-` (incorrect choice) emits
|
|
4839
|
+
// `isExample: true` only — no `example` (BPG fixtures show
|
|
4840
|
+
// `isExample` on every choice, but `example` only on the
|
|
4841
|
+
// first correct via firstCorrectOnly cascade).
|
|
4842
|
+
// @card scope-shift writes choice-container isExample.
|
|
4016
4843
|
key: ConfigKey.property_example,
|
|
4017
4844
|
jsonKey: "example",
|
|
4018
4845
|
exportJsonKey: [
|
|
@@ -4020,20 +4847,460 @@ var GROUPS = {
|
|
|
4020
4847
|
"@keyonly": {
|
|
4021
4848
|
isExample: true,
|
|
4022
4849
|
example: "$parent.isCorrect",
|
|
4023
|
-
"@bit": { isExample: true }
|
|
4850
|
+
"@bit": { isExample: true },
|
|
4851
|
+
"@card": { isExample: true }
|
|
4024
4852
|
}
|
|
4025
4853
|
},
|
|
4026
4854
|
{
|
|
4027
4855
|
"@absent": {
|
|
4856
|
+
isExample: true,
|
|
4857
|
+
"@bit": { isExample: true },
|
|
4858
|
+
"@card": { isExample: true }
|
|
4859
|
+
}
|
|
4860
|
+
},
|
|
4861
|
+
{
|
|
4862
|
+
isExample: true,
|
|
4863
|
+
example: "$",
|
|
4864
|
+
"@bit": { isExample: true },
|
|
4865
|
+
"@card": { isExample: true }
|
|
4866
|
+
}
|
|
4867
|
+
],
|
|
4868
|
+
description: "An example for the true/false statement/question (incorrect entry \u2014 isExample only on cascade)",
|
|
4869
|
+
format: TagFormat.boolean,
|
|
4870
|
+
nullable: true
|
|
4871
|
+
}
|
|
4872
|
+
]
|
|
4873
|
+
}
|
|
4874
|
+
]
|
|
4875
|
+
},
|
|
4876
|
+
[ConfigKey.group_trueFalseResponses]: {
|
|
4877
|
+
type: GroupConfigType.standard,
|
|
4878
|
+
description: "True/False Responses chain",
|
|
4879
|
+
tags: [
|
|
4880
|
+
{
|
|
4881
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: true }] },
|
|
4882
|
+
key: ConfigKey.tag_true,
|
|
4883
|
+
description: "True value for a true/false statement/question",
|
|
4884
|
+
maxCount: Count.infinity,
|
|
4885
|
+
format: TagFormat.plainText,
|
|
4886
|
+
chain: [
|
|
4887
|
+
{
|
|
4888
|
+
key: ConfigKey.tag_true,
|
|
4889
|
+
jsonKey: "responses[]|set(isCorrect=true)",
|
|
4890
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: true }] },
|
|
4891
|
+
description: "True values for a true/false statement/question",
|
|
4892
|
+
maxCount: Count.infinity,
|
|
4893
|
+
format: TagFormat.plainText
|
|
4894
|
+
},
|
|
4895
|
+
{
|
|
4896
|
+
key: ConfigKey.tag_false,
|
|
4897
|
+
jsonKey: "responses[]|set(isCorrect=false)",
|
|
4898
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: false }] },
|
|
4899
|
+
description: "False values for a true/false statement/question",
|
|
4900
|
+
maxCount: Count.infinity,
|
|
4901
|
+
format: TagFormat.plainText
|
|
4902
|
+
},
|
|
4903
|
+
{
|
|
4904
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
4905
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
4906
|
+
},
|
|
4907
|
+
{
|
|
4908
|
+
// @card scope-shift writes response-container isExample.
|
|
4909
|
+
key: ConfigKey.property_example,
|
|
4910
|
+
jsonKey: "example",
|
|
4911
|
+
exportJsonKey: [
|
|
4912
|
+
{
|
|
4913
|
+
"@keyonly": {
|
|
4028
4914
|
isExample: true,
|
|
4029
4915
|
example: "$parent.isCorrect",
|
|
4030
|
-
"@bit": { isExample: true }
|
|
4916
|
+
"@bit": { isExample: true },
|
|
4917
|
+
"@card": { isExample: true }
|
|
4031
4918
|
}
|
|
4032
4919
|
},
|
|
4033
|
-
{
|
|
4920
|
+
{
|
|
4921
|
+
"@absent": {
|
|
4922
|
+
isExample: "$parent.isCorrect",
|
|
4923
|
+
example: "$parent.isCorrect",
|
|
4924
|
+
"@bit": { isExample: "$parent.isCorrect" },
|
|
4925
|
+
"@card": { isExample: "$parent.isCorrect" }
|
|
4926
|
+
}
|
|
4927
|
+
},
|
|
4928
|
+
{
|
|
4929
|
+
isExample: true,
|
|
4930
|
+
example: "$",
|
|
4931
|
+
"@bit": { isExample: true },
|
|
4932
|
+
"@card": { isExample: true }
|
|
4933
|
+
}
|
|
4034
4934
|
],
|
|
4035
4935
|
description: "An example for the true/false statement/question",
|
|
4036
|
-
format: TagFormat.
|
|
4936
|
+
format: TagFormat.boolean,
|
|
4937
|
+
nullable: true
|
|
4938
|
+
}
|
|
4939
|
+
]
|
|
4940
|
+
},
|
|
4941
|
+
{
|
|
4942
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: false }] },
|
|
4943
|
+
key: ConfigKey.tag_false,
|
|
4944
|
+
description: "False value for a true/false statement/question",
|
|
4945
|
+
maxCount: Count.infinity,
|
|
4946
|
+
format: TagFormat.plainText,
|
|
4947
|
+
chain: [
|
|
4948
|
+
{
|
|
4949
|
+
key: ConfigKey.tag_true,
|
|
4950
|
+
jsonKey: "responses[]|set(isCorrect=true)",
|
|
4951
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: true }] },
|
|
4952
|
+
description: "True values for a true/false statement/question",
|
|
4953
|
+
maxCount: Count.infinity,
|
|
4954
|
+
format: TagFormat.plainText
|
|
4955
|
+
},
|
|
4956
|
+
{
|
|
4957
|
+
key: ConfigKey.tag_false,
|
|
4958
|
+
jsonKey: "responses[]|set(isCorrect=false)",
|
|
4959
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: false }] },
|
|
4960
|
+
description: "False values for a true/false statement/question",
|
|
4961
|
+
maxCount: Count.infinity,
|
|
4962
|
+
format: TagFormat.plainText
|
|
4963
|
+
},
|
|
4964
|
+
{
|
|
4965
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
4966
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
4967
|
+
},
|
|
4968
|
+
{
|
|
4969
|
+
// @card scope-shift writes response-container isExample.
|
|
4970
|
+
key: ConfigKey.property_example,
|
|
4971
|
+
jsonKey: "example",
|
|
4972
|
+
exportJsonKey: [
|
|
4973
|
+
{
|
|
4974
|
+
"@keyonly": {
|
|
4975
|
+
isExample: true,
|
|
4976
|
+
example: "$parent.isCorrect",
|
|
4977
|
+
"@bit": { isExample: true },
|
|
4978
|
+
"@card": { isExample: true }
|
|
4979
|
+
}
|
|
4980
|
+
},
|
|
4981
|
+
{
|
|
4982
|
+
"@absent": {
|
|
4983
|
+
isExample: true,
|
|
4984
|
+
example: "$parent.isCorrect",
|
|
4985
|
+
"@bit": { isExample: true },
|
|
4986
|
+
"@card": { isExample: true }
|
|
4987
|
+
}
|
|
4988
|
+
},
|
|
4989
|
+
{
|
|
4990
|
+
isExample: true,
|
|
4991
|
+
example: "$",
|
|
4992
|
+
"@bit": { isExample: true },
|
|
4993
|
+
"@card": { isExample: true }
|
|
4994
|
+
}
|
|
4995
|
+
],
|
|
4996
|
+
description: "An example for the true/false statement/question",
|
|
4997
|
+
format: TagFormat.boolean,
|
|
4998
|
+
nullable: true
|
|
4999
|
+
}
|
|
5000
|
+
]
|
|
5001
|
+
}
|
|
5002
|
+
]
|
|
5003
|
+
},
|
|
5004
|
+
[ConfigKey.group_trueFalseInlineSelect]: {
|
|
5005
|
+
type: GroupConfigType.standard,
|
|
5006
|
+
description: "True/False chain composed inline (select body-bit). +/- tags are consume-only at bit level.",
|
|
5007
|
+
tags: [
|
|
5008
|
+
{
|
|
5009
|
+
exportJsonKey: {
|
|
5010
|
+
"@body-inline": {
|
|
5011
|
+
type: "select",
|
|
5012
|
+
attrs: { options: [{ text: "$", isCorrect: true }] }
|
|
5013
|
+
}
|
|
5014
|
+
},
|
|
5015
|
+
key: ConfigKey.tag_true,
|
|
5016
|
+
description: "True value for an inline select body bit",
|
|
5017
|
+
maxCount: Count.infinity,
|
|
5018
|
+
format: TagFormat.plainText,
|
|
5019
|
+
chain: [
|
|
5020
|
+
{
|
|
5021
|
+
key: ConfigKey.tag_true,
|
|
5022
|
+
exportJsonKey: {},
|
|
5023
|
+
description: "True values for an inline select body bit",
|
|
5024
|
+
maxCount: Count.infinity,
|
|
5025
|
+
format: TagFormat.plainText
|
|
5026
|
+
},
|
|
5027
|
+
{
|
|
5028
|
+
key: ConfigKey.tag_false,
|
|
5029
|
+
exportJsonKey: {},
|
|
5030
|
+
description: "False values for an inline select body bit",
|
|
5031
|
+
maxCount: Count.infinity,
|
|
5032
|
+
format: TagFormat.plainText
|
|
5033
|
+
},
|
|
5034
|
+
{
|
|
5035
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5036
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5037
|
+
},
|
|
5038
|
+
{
|
|
5039
|
+
// PLAN-083: cascade-fired `@example` from bit header fires
|
|
5040
|
+
// `isExample:true, example:true` on the FIRST CORRECT option
|
|
5041
|
+
// only (BPG `fillBooleanExample(select.options,
|
|
5042
|
+
// firstCorrectOnly=true)`). Mirrors group_trueFalseInlineHighlight.
|
|
5043
|
+
// Every rule also bubbles `@bit:{isExample:true}` (idempotent
|
|
5044
|
+
// OR — any cascade ⇒ bit marked) and
|
|
5045
|
+
// `@body-inline:{attrs:{isExample:true}}` (node-level marker
|
|
5046
|
+
// on the select node).
|
|
5047
|
+
key: ConfigKey.property_example,
|
|
5048
|
+
jsonKey: "example",
|
|
5049
|
+
exportJsonKey: [
|
|
5050
|
+
{
|
|
5051
|
+
"@keyonly": {
|
|
5052
|
+
isExample: true,
|
|
5053
|
+
example: "$parent.isCorrect",
|
|
5054
|
+
"@bit": { isExample: true },
|
|
5055
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5056
|
+
}
|
|
5057
|
+
},
|
|
5058
|
+
{
|
|
5059
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5060
|
+
maxEmits: 1,
|
|
5061
|
+
rule: {
|
|
5062
|
+
isExample: true,
|
|
5063
|
+
example: true,
|
|
5064
|
+
"@bit": { isExample: true },
|
|
5065
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5066
|
+
}
|
|
5067
|
+
},
|
|
5068
|
+
{
|
|
5069
|
+
isExample: true,
|
|
5070
|
+
example: "$",
|
|
5071
|
+
"@bit": { isExample: true },
|
|
5072
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5073
|
+
}
|
|
5074
|
+
],
|
|
5075
|
+
description: "An example for the inline select option (first correct only)",
|
|
5076
|
+
format: TagFormat.boolean,
|
|
5077
|
+
nullable: true
|
|
5078
|
+
}
|
|
5079
|
+
]
|
|
5080
|
+
},
|
|
5081
|
+
{
|
|
5082
|
+
exportJsonKey: {
|
|
5083
|
+
"@body-inline": {
|
|
5084
|
+
type: "select",
|
|
5085
|
+
attrs: { options: [{ text: "$", isCorrect: false }] }
|
|
5086
|
+
}
|
|
5087
|
+
},
|
|
5088
|
+
key: ConfigKey.tag_false,
|
|
5089
|
+
description: "False value for an inline select body bit",
|
|
5090
|
+
maxCount: Count.infinity,
|
|
5091
|
+
format: TagFormat.plainText,
|
|
5092
|
+
chain: [
|
|
5093
|
+
{
|
|
5094
|
+
key: ConfigKey.tag_true,
|
|
5095
|
+
exportJsonKey: {},
|
|
5096
|
+
description: "True values for an inline select body bit",
|
|
5097
|
+
maxCount: Count.infinity,
|
|
5098
|
+
format: TagFormat.plainText
|
|
5099
|
+
},
|
|
5100
|
+
{
|
|
5101
|
+
key: ConfigKey.tag_false,
|
|
5102
|
+
exportJsonKey: {},
|
|
5103
|
+
description: "False values for an inline select body bit",
|
|
5104
|
+
maxCount: Count.infinity,
|
|
5105
|
+
format: TagFormat.plainText
|
|
5106
|
+
},
|
|
5107
|
+
{
|
|
5108
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5109
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5110
|
+
},
|
|
5111
|
+
{
|
|
5112
|
+
// PLAN-083: identical to the `+` lead's chain @example —
|
|
5113
|
+
// cascade reaches the first correct option regardless of
|
|
5114
|
+
// which lead (+/-) opens the chain. Every firing rule bubbles
|
|
5115
|
+
// `@bit:{isExample:true}` and `@body-inline:{attrs:{isExample:true}}`.
|
|
5116
|
+
key: ConfigKey.property_example,
|
|
5117
|
+
jsonKey: "example",
|
|
5118
|
+
exportJsonKey: [
|
|
5119
|
+
{
|
|
5120
|
+
"@keyonly": {
|
|
5121
|
+
isExample: true,
|
|
5122
|
+
example: "$parent.isCorrect",
|
|
5123
|
+
"@bit": { isExample: true },
|
|
5124
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5125
|
+
}
|
|
5126
|
+
},
|
|
5127
|
+
{
|
|
5128
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5129
|
+
maxEmits: 1,
|
|
5130
|
+
rule: {
|
|
5131
|
+
isExample: true,
|
|
5132
|
+
example: true,
|
|
5133
|
+
"@bit": { isExample: true },
|
|
5134
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5135
|
+
}
|
|
5136
|
+
},
|
|
5137
|
+
{
|
|
5138
|
+
isExample: true,
|
|
5139
|
+
example: "$",
|
|
5140
|
+
"@bit": { isExample: true },
|
|
5141
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5142
|
+
}
|
|
5143
|
+
],
|
|
5144
|
+
description: "An example for the inline select option (first correct only)",
|
|
5145
|
+
format: TagFormat.boolean,
|
|
5146
|
+
nullable: true
|
|
5147
|
+
}
|
|
5148
|
+
]
|
|
5149
|
+
}
|
|
5150
|
+
]
|
|
5151
|
+
},
|
|
5152
|
+
[ConfigKey.group_trueFalseInlineHighlight]: {
|
|
5153
|
+
type: GroupConfigType.standard,
|
|
5154
|
+
description: 'True/False chain composed inline (highlight body-bit). +/- tags emit `{type:"highlight", attrs:{texts:[{text,isCorrect?}]}}` inline body nodes. Used by highlight-text bit.',
|
|
5155
|
+
tags: [
|
|
5156
|
+
{
|
|
5157
|
+
exportJsonKey: {
|
|
5158
|
+
"@body-inline": {
|
|
5159
|
+
type: "highlight",
|
|
5160
|
+
attrs: { texts: [{ text: "$", isCorrect: true }] }
|
|
5161
|
+
}
|
|
5162
|
+
},
|
|
5163
|
+
key: ConfigKey.tag_true,
|
|
5164
|
+
description: "Highlighted span in the body (correct)",
|
|
5165
|
+
maxCount: Count.infinity,
|
|
5166
|
+
format: TagFormat.plainText,
|
|
5167
|
+
chain: [
|
|
5168
|
+
{
|
|
5169
|
+
key: ConfigKey.tag_true,
|
|
5170
|
+
exportJsonKey: {},
|
|
5171
|
+
description: "Highlighted span values (correct)",
|
|
5172
|
+
maxCount: Count.infinity,
|
|
5173
|
+
format: TagFormat.plainText
|
|
5174
|
+
},
|
|
5175
|
+
{
|
|
5176
|
+
key: ConfigKey.tag_false,
|
|
5177
|
+
exportJsonKey: {},
|
|
5178
|
+
description: "Highlighted span values (incorrect)",
|
|
5179
|
+
maxCount: Count.infinity,
|
|
5180
|
+
format: TagFormat.plainText
|
|
5181
|
+
},
|
|
5182
|
+
{
|
|
5183
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5184
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5185
|
+
},
|
|
5186
|
+
{
|
|
5187
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.13: cascade-fired
|
|
5188
|
+
// `@example` from the bit header fires `example: true` +
|
|
5189
|
+
// `isExample: true` on the FIRST correct highlight only
|
|
5190
|
+
// (BPG `fillBooleanExample(highlight.texts,
|
|
5191
|
+
// firstCorrectOnly=true)`). Incorrect highlights get
|
|
5192
|
+
// nothing (unlike choices, the highlight-text fixture
|
|
5193
|
+
// shows no `isExample` on incorrect entries).
|
|
5194
|
+
key: ConfigKey.property_example,
|
|
5195
|
+
jsonKey: "example",
|
|
5196
|
+
exportJsonKey: [
|
|
5197
|
+
{
|
|
5198
|
+
"@keyonly": {
|
|
5199
|
+
isExample: true,
|
|
5200
|
+
example: "$parent.isCorrect",
|
|
5201
|
+
"@bit": { isExample: true },
|
|
5202
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5203
|
+
}
|
|
5204
|
+
},
|
|
5205
|
+
{
|
|
5206
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5207
|
+
maxEmits: 1,
|
|
5208
|
+
rule: {
|
|
5209
|
+
isExample: true,
|
|
5210
|
+
example: true,
|
|
5211
|
+
"@bit": { isExample: true },
|
|
5212
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5213
|
+
}
|
|
5214
|
+
},
|
|
5215
|
+
{
|
|
5216
|
+
isExample: true,
|
|
5217
|
+
example: "$",
|
|
5218
|
+
"@bit": { isExample: true },
|
|
5219
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5220
|
+
}
|
|
5221
|
+
],
|
|
5222
|
+
description: "An example for the highlighted span (first correct only)",
|
|
5223
|
+
format: TagFormat.boolean,
|
|
5224
|
+
nullable: true
|
|
5225
|
+
}
|
|
5226
|
+
]
|
|
5227
|
+
},
|
|
5228
|
+
{
|
|
5229
|
+
// PLAN-083 follow-up (2026-05-22): mirror the select `-` lead shape
|
|
5230
|
+
// by writing `isCorrect: false`. Without it, `$parent.isCorrect` in
|
|
5231
|
+
// chain-child @example rules resolves to ParentPathMissing for `-`
|
|
5232
|
+
// entries (e.g. `[-fish][@example]`), so the @keyonly rule falls
|
|
5233
|
+
// through and nothing fires. The natural-default strip removes
|
|
5234
|
+
// `isCorrect: false` from the final texts entries (matches fixture).
|
|
5235
|
+
exportJsonKey: {
|
|
5236
|
+
"@body-inline": {
|
|
5237
|
+
type: "highlight",
|
|
5238
|
+
attrs: { texts: [{ text: "$", isCorrect: false }] }
|
|
5239
|
+
}
|
|
5240
|
+
},
|
|
5241
|
+
key: ConfigKey.tag_false,
|
|
5242
|
+
description: "Highlighted span in the body (incorrect)",
|
|
5243
|
+
maxCount: Count.infinity,
|
|
5244
|
+
format: TagFormat.plainText,
|
|
5245
|
+
chain: [
|
|
5246
|
+
{
|
|
5247
|
+
key: ConfigKey.tag_true,
|
|
5248
|
+
exportJsonKey: {},
|
|
5249
|
+
description: "Highlighted span values (correct)",
|
|
5250
|
+
maxCount: Count.infinity,
|
|
5251
|
+
format: TagFormat.plainText
|
|
5252
|
+
},
|
|
5253
|
+
{
|
|
5254
|
+
key: ConfigKey.tag_false,
|
|
5255
|
+
exportJsonKey: {},
|
|
5256
|
+
description: "Highlighted span values (incorrect)",
|
|
5257
|
+
maxCount: Count.infinity,
|
|
5258
|
+
format: TagFormat.plainText
|
|
5259
|
+
},
|
|
5260
|
+
{
|
|
5261
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5262
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5263
|
+
},
|
|
5264
|
+
{
|
|
5265
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.13: cascade-fired
|
|
5266
|
+
// `@example` on a `-` (incorrect highlight) emits nothing
|
|
5267
|
+
// (highlight-text fixture has no `isExample` on incorrect
|
|
5268
|
+
// entries; firstCorrectOnly cascade skips them entirely).
|
|
5269
|
+
// No `@absent` rule.
|
|
5270
|
+
// PLAN-083: identical to the `+` lead's chain @example —
|
|
5271
|
+
// cascade reaches the first correct option regardless of
|
|
5272
|
+
// which lead (+/-) opens the chain.
|
|
5273
|
+
key: ConfigKey.property_example,
|
|
5274
|
+
jsonKey: "example",
|
|
5275
|
+
exportJsonKey: [
|
|
5276
|
+
{
|
|
5277
|
+
"@keyonly": {
|
|
5278
|
+
isExample: true,
|
|
5279
|
+
example: "$parent.isCorrect",
|
|
5280
|
+
"@bit": { isExample: true },
|
|
5281
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5282
|
+
}
|
|
5283
|
+
},
|
|
5284
|
+
{
|
|
5285
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5286
|
+
maxEmits: 1,
|
|
5287
|
+
rule: {
|
|
5288
|
+
isExample: true,
|
|
5289
|
+
example: true,
|
|
5290
|
+
"@bit": { isExample: true },
|
|
5291
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5292
|
+
}
|
|
5293
|
+
},
|
|
5294
|
+
{
|
|
5295
|
+
isExample: true,
|
|
5296
|
+
example: "$",
|
|
5297
|
+
"@bit": { isExample: true },
|
|
5298
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5299
|
+
}
|
|
5300
|
+
],
|
|
5301
|
+
description: "An example for the highlighted span (first correct only)",
|
|
5302
|
+
format: TagFormat.boolean,
|
|
5303
|
+
nullable: true
|
|
4037
5304
|
}
|
|
4038
5305
|
]
|
|
4039
5306
|
}
|
|
@@ -4046,7 +5313,7 @@ var GROUPS = {
|
|
|
4046
5313
|
{
|
|
4047
5314
|
key: ConfigKey.property_mark,
|
|
4048
5315
|
jsonKey: "marks.mark",
|
|
4049
|
-
exportJsonKey: { marks: { mark:
|
|
5316
|
+
exportJsonKey: { marks: [{ mark: "$" }] },
|
|
4050
5317
|
description: "The mark configuration",
|
|
4051
5318
|
format: TagFormat.plainText,
|
|
4052
5319
|
maxCount: Count.infinity,
|
|
@@ -4070,7 +5337,9 @@ var GROUPS = {
|
|
|
4070
5337
|
description: "Mark chain",
|
|
4071
5338
|
tags: [
|
|
4072
5339
|
{
|
|
4073
|
-
exportJsonKey: {
|
|
5340
|
+
exportJsonKey: {
|
|
5341
|
+
"@body-inline": { type: "mark", attrs: { solution: "$" } }
|
|
5342
|
+
},
|
|
4074
5343
|
key: ConfigKey.tag_mark,
|
|
4075
5344
|
description: "The marked content",
|
|
4076
5345
|
maxCount: Count.infinity,
|
|
@@ -4079,6 +5348,7 @@ var GROUPS = {
|
|
|
4079
5348
|
{
|
|
4080
5349
|
key: ConfigKey.property_mark,
|
|
4081
5350
|
jsonKey: "mark",
|
|
5351
|
+
exportJsonKey: { mark: "$" },
|
|
4082
5352
|
description: "The mark configuration",
|
|
4083
5353
|
format: TagFormat.plainText
|
|
4084
5354
|
},
|
|
@@ -4091,7 +5361,8 @@ var GROUPS = {
|
|
|
4091
5361
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
4092
5362
|
],
|
|
4093
5363
|
description: "An example for the marked content",
|
|
4094
|
-
format: TagFormat.bitmarkText
|
|
5364
|
+
format: TagFormat.bitmarkText,
|
|
5365
|
+
nullable: true
|
|
4095
5366
|
}
|
|
4096
5367
|
]
|
|
4097
5368
|
}
|
|
@@ -4520,6 +5791,42 @@ var GROUPS = {
|
|
|
4520
5791
|
}
|
|
4521
5792
|
]
|
|
4522
5793
|
},
|
|
5794
|
+
[ConfigKey.group_backgroundWallpaper]: {
|
|
5795
|
+
type: GroupConfigType.standard,
|
|
5796
|
+
description: "Background wallpaper tags",
|
|
5797
|
+
tags: [
|
|
5798
|
+
{
|
|
5799
|
+
key: ConfigKey.resource_backgroundWallpaper,
|
|
5800
|
+
exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
|
|
5801
|
+
description: "Background wallpaper for the image, used to set a background for the image",
|
|
5802
|
+
chain: [
|
|
5803
|
+
{
|
|
5804
|
+
key: ConfigKey.group_resourceImageCommon,
|
|
5805
|
+
description: "Common resource image tags for images"
|
|
5806
|
+
}
|
|
5807
|
+
]
|
|
5808
|
+
}
|
|
5809
|
+
]
|
|
5810
|
+
},
|
|
5811
|
+
[ConfigKey.group_imageNoZoom]: {
|
|
5812
|
+
type: GroupConfigType.standard,
|
|
5813
|
+
description: "Image bit tags",
|
|
5814
|
+
tags: [
|
|
5815
|
+
{
|
|
5816
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
5817
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
5818
|
+
},
|
|
5819
|
+
{
|
|
5820
|
+
key: ConfigKey.group_resourceBitTags,
|
|
5821
|
+
description: "Resource bit tags for images, used to define additional properties for images"
|
|
5822
|
+
},
|
|
5823
|
+
{
|
|
5824
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
5825
|
+
description: "Resource image tags for images, used to attach images to the bit",
|
|
5826
|
+
minCount: 1
|
|
5827
|
+
}
|
|
5828
|
+
]
|
|
5829
|
+
},
|
|
4523
5830
|
//
|
|
4524
5831
|
// Resource groups
|
|
4525
5832
|
//
|
|
@@ -4639,6 +5946,58 @@ var GROUPS = {
|
|
|
4639
5946
|
}
|
|
4640
5947
|
]
|
|
4641
5948
|
},
|
|
5949
|
+
[ConfigKey.group_resourceImageCommonNoZoom]: {
|
|
5950
|
+
type: GroupConfigType.standard,
|
|
5951
|
+
description: "Common properties for image resources where @zoomDisabled defaults to true",
|
|
5952
|
+
tags: [
|
|
5953
|
+
{
|
|
5954
|
+
key: ConfigKey.group_resourceCommon,
|
|
5955
|
+
description: "Common resource properties"
|
|
5956
|
+
},
|
|
5957
|
+
{
|
|
5958
|
+
key: ConfigKey.property_src1x,
|
|
5959
|
+
description: "The source URL for the image at 1x resolution",
|
|
5960
|
+
format: TagFormat.plainText
|
|
5961
|
+
},
|
|
5962
|
+
{
|
|
5963
|
+
key: ConfigKey.property_src2x,
|
|
5964
|
+
description: "The source URL for the image at 2x resolution",
|
|
5965
|
+
format: TagFormat.plainText
|
|
5966
|
+
},
|
|
5967
|
+
{
|
|
5968
|
+
key: ConfigKey.property_src3x,
|
|
5969
|
+
description: "The source URL for the image at 3x resolution",
|
|
5970
|
+
format: TagFormat.plainText
|
|
5971
|
+
},
|
|
5972
|
+
{
|
|
5973
|
+
key: ConfigKey.property_src4x,
|
|
5974
|
+
description: "The source URL for the image at 4x resolution",
|
|
5975
|
+
format: TagFormat.plainText
|
|
5976
|
+
},
|
|
5977
|
+
{
|
|
5978
|
+
key: ConfigKey.property_width,
|
|
5979
|
+
description: "The width of the image",
|
|
5980
|
+
format: TagFormat.number
|
|
5981
|
+
},
|
|
5982
|
+
{
|
|
5983
|
+
key: ConfigKey.property_height,
|
|
5984
|
+
description: "The height of the image",
|
|
5985
|
+
format: TagFormat.number
|
|
5986
|
+
},
|
|
5987
|
+
{
|
|
5988
|
+
key: ConfigKey.property_alt,
|
|
5989
|
+
description: "The alternative text for the image",
|
|
5990
|
+
format: TagFormat.plainText
|
|
5991
|
+
},
|
|
5992
|
+
// @zoomDisabled with a true default
|
|
5993
|
+
{
|
|
5994
|
+
key: ConfigKey.property_zoomDisabled,
|
|
5995
|
+
description: "If true, zooming is disabled for the image (defaults to true)",
|
|
5996
|
+
format: TagFormat.boolean,
|
|
5997
|
+
defaultValue: "true"
|
|
5998
|
+
}
|
|
5999
|
+
]
|
|
6000
|
+
},
|
|
4642
6001
|
[ConfigKey.group_resourceAudioCommon]: {
|
|
4643
6002
|
type: GroupConfigType.standard,
|
|
4644
6003
|
description: "Common properties for audio resources",
|
|
@@ -4728,22 +6087,26 @@ var GROUPS = {
|
|
|
4728
6087
|
{
|
|
4729
6088
|
key: ConfigKey.property_src1x,
|
|
4730
6089
|
description: "The source URL for the video at 1x resolution",
|
|
4731
|
-
format: TagFormat.plainText
|
|
6090
|
+
format: TagFormat.plainText,
|
|
6091
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4732
6092
|
},
|
|
4733
6093
|
{
|
|
4734
6094
|
key: ConfigKey.property_src2x,
|
|
4735
6095
|
description: "The source URL for the video at 2x resolution",
|
|
4736
|
-
format: TagFormat.plainText
|
|
6096
|
+
format: TagFormat.plainText,
|
|
6097
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4737
6098
|
},
|
|
4738
6099
|
{
|
|
4739
6100
|
key: ConfigKey.property_src3x,
|
|
4740
6101
|
description: "The source URL for the video at 3x resolution",
|
|
4741
|
-
format: TagFormat.plainText
|
|
6102
|
+
format: TagFormat.plainText,
|
|
6103
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4742
6104
|
},
|
|
4743
6105
|
{
|
|
4744
6106
|
key: ConfigKey.property_src4x,
|
|
4745
6107
|
description: "The source URL for the video at 4x resolution",
|
|
4746
|
-
format: TagFormat.plainText
|
|
6108
|
+
format: TagFormat.plainText,
|
|
6109
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4747
6110
|
}
|
|
4748
6111
|
]
|
|
4749
6112
|
},
|
|
@@ -4756,6 +6119,7 @@ var GROUPS = {
|
|
|
4756
6119
|
tags: [
|
|
4757
6120
|
{
|
|
4758
6121
|
key: ConfigKey.resource_icon,
|
|
6122
|
+
exportJsonKey: { resource: { type: "icon", icon: { src: "$" } } },
|
|
4759
6123
|
description: "The icon resource",
|
|
4760
6124
|
chain: [
|
|
4761
6125
|
{
|
|
@@ -4783,12 +6147,30 @@ var GROUPS = {
|
|
|
4783
6147
|
}
|
|
4784
6148
|
]
|
|
4785
6149
|
},
|
|
6150
|
+
[ConfigKey.group_resourceImageNoZoom]: {
|
|
6151
|
+
type: GroupConfigType.resource,
|
|
6152
|
+
description: "Image resource where @zoomDisabled defaults to true",
|
|
6153
|
+
tags: [
|
|
6154
|
+
{
|
|
6155
|
+
key: ConfigKey.resource_image,
|
|
6156
|
+
exportJsonKey: { resource: { type: "image", image: { src: "$" } } },
|
|
6157
|
+
description: "The image resource (no-zoom default)",
|
|
6158
|
+
chain: [
|
|
6159
|
+
{
|
|
6160
|
+
key: ConfigKey.group_resourceImageCommonNoZoom,
|
|
6161
|
+
description: "Common image properties with @zoomDisabled defaulting to true"
|
|
6162
|
+
}
|
|
6163
|
+
]
|
|
6164
|
+
}
|
|
6165
|
+
]
|
|
6166
|
+
},
|
|
4786
6167
|
[ConfigKey.group_resourceImagePortrait]: {
|
|
4787
6168
|
type: GroupConfigType.resource,
|
|
4788
6169
|
description: "Portrait image resource",
|
|
4789
6170
|
tags: [
|
|
4790
6171
|
{
|
|
4791
6172
|
key: ConfigKey.resource_imagePortrait,
|
|
6173
|
+
exportJsonKey: { resource: { type: "image-portrait", imagePortrait: { src: "$" } } },
|
|
4792
6174
|
description: "The portrait image resource",
|
|
4793
6175
|
chain: [
|
|
4794
6176
|
{
|
|
@@ -4805,6 +6187,7 @@ var GROUPS = {
|
|
|
4805
6187
|
tags: [
|
|
4806
6188
|
{
|
|
4807
6189
|
key: ConfigKey.resource_imageLandscape,
|
|
6190
|
+
exportJsonKey: { resource: { type: "image-landscape", imageLandscape: { src: "$" } } },
|
|
4808
6191
|
description: "The landscape image resource",
|
|
4809
6192
|
chain: [
|
|
4810
6193
|
{
|
|
@@ -4821,6 +6204,7 @@ var GROUPS = {
|
|
|
4821
6204
|
tags: [
|
|
4822
6205
|
{
|
|
4823
6206
|
key: ConfigKey.resource_imageEmbed,
|
|
6207
|
+
exportJsonKey: { resource: { type: "image-embed", imageEmbed: { src: "$" } } },
|
|
4824
6208
|
description: "The embedded image resource",
|
|
4825
6209
|
chain: [
|
|
4826
6210
|
{
|
|
@@ -4994,6 +6378,7 @@ var GROUPS = {
|
|
|
4994
6378
|
tags: [
|
|
4995
6379
|
{
|
|
4996
6380
|
key: ConfigKey.resource_article,
|
|
6381
|
+
exportJsonKey: { resource: { type: "article", article: { body: "$" } } },
|
|
4997
6382
|
description: "The article resource",
|
|
4998
6383
|
chain: [
|
|
4999
6384
|
{
|
|
@@ -5010,6 +6395,7 @@ var GROUPS = {
|
|
|
5010
6395
|
tags: [
|
|
5011
6396
|
{
|
|
5012
6397
|
key: ConfigKey.resource_articleEmbed,
|
|
6398
|
+
exportJsonKey: { resource: { type: "article-embed", articleEmbed: { url: "$" } } },
|
|
5013
6399
|
description: "The embedded article resource",
|
|
5014
6400
|
chain: [
|
|
5015
6401
|
{
|
|
@@ -5026,6 +6412,7 @@ var GROUPS = {
|
|
|
5026
6412
|
tags: [
|
|
5027
6413
|
{
|
|
5028
6414
|
key: ConfigKey.resource_articleLink,
|
|
6415
|
+
exportJsonKey: { resource: { type: "article-link", articleLink: { url: "$" } } },
|
|
5029
6416
|
description: "The link to the article resource",
|
|
5030
6417
|
chain: [
|
|
5031
6418
|
{
|
|
@@ -5296,7 +6683,12 @@ var ConfigHydrator = class {
|
|
|
5296
6683
|
isDefault: v.isDefault,
|
|
5297
6684
|
sideJsonKey: v.sideJsonKey,
|
|
5298
6685
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
5299
|
-
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey")
|
|
6686
|
+
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
6687
|
+
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6688
|
+
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6689
|
+
// as unbounded).
|
|
6690
|
+
minCount: v.minCount,
|
|
6691
|
+
maxCount: v.maxCount
|
|
5300
6692
|
};
|
|
5301
6693
|
}
|
|
5302
6694
|
return out;
|
|
@@ -5511,7 +6903,8 @@ var BITS = {
|
|
|
5511
6903
|
{ isExample: true, example: "$" }
|
|
5512
6904
|
],
|
|
5513
6905
|
description: "The example text for the bit",
|
|
5514
|
-
format: TagFormat.plainText
|
|
6906
|
+
format: TagFormat.plainText,
|
|
6907
|
+
nullable: true
|
|
5515
6908
|
}
|
|
5516
6909
|
],
|
|
5517
6910
|
rootExampleType: ExampleType.string
|
|
@@ -5850,7 +7243,8 @@ var BITS = {
|
|
|
5850
7243
|
{ isExample: true, example: "$" }
|
|
5851
7244
|
],
|
|
5852
7245
|
description: "The example text for the bit",
|
|
5853
|
-
format: TagFormat.plainText
|
|
7246
|
+
format: TagFormat.plainText,
|
|
7247
|
+
nullable: true
|
|
5854
7248
|
}
|
|
5855
7249
|
],
|
|
5856
7250
|
rootExampleType: ExampleType.string
|
|
@@ -6013,7 +7407,8 @@ var BITS = {
|
|
|
6013
7407
|
{ isExample: true, example: "$" }
|
|
6014
7408
|
],
|
|
6015
7409
|
description: "The example text for the bit",
|
|
6016
|
-
format: TagFormat.plainText
|
|
7410
|
+
format: TagFormat.plainText,
|
|
7411
|
+
nullable: true
|
|
6017
7412
|
}
|
|
6018
7413
|
],
|
|
6019
7414
|
rootExampleType: ExampleType.string
|
|
@@ -6164,7 +7559,8 @@ var BITS = {
|
|
|
6164
7559
|
{ isExample: true, example: "$" }
|
|
6165
7560
|
],
|
|
6166
7561
|
description: "The example text for the bit",
|
|
6167
|
-
format: TagFormat.plainText
|
|
7562
|
+
format: TagFormat.plainText,
|
|
7563
|
+
nullable: true
|
|
6168
7564
|
}
|
|
6169
7565
|
],
|
|
6170
7566
|
rootExampleType: ExampleType.string
|
|
@@ -6759,8 +8155,31 @@ var BITS = {
|
|
|
6759
8155
|
description: "Tags for gaps in cloze and multiple choice text bits"
|
|
6760
8156
|
},
|
|
6761
8157
|
{
|
|
6762
|
-
key: ConfigKey.
|
|
8158
|
+
key: ConfigKey.group_trueFalseInlineSelect,
|
|
6763
8159
|
description: "Tags for true/false questions in cloze and multiple choice text bits"
|
|
8160
|
+
},
|
|
8161
|
+
{
|
|
8162
|
+
// Bit-level @isCaseSensitive — empty exportJsonKey (no bit-level emission);
|
|
8163
|
+
// defaultValue 'true' phantom-fires onto the ancestor stack so the gap chain's
|
|
8164
|
+
// `@absent: $ancestor` rule resolves to true. Mirrors BPG Builder.ts:1643-1652
|
|
8165
|
+
// `pushDownTree(... 'isCaseSensitive', data.isCaseSensitive ?? true)` for cloze bits.
|
|
8166
|
+
key: ConfigKey.property_isCaseSensitive,
|
|
8167
|
+
exportJsonKey: {},
|
|
8168
|
+
description: "If the cloze answers are case sensitive",
|
|
8169
|
+
format: TagFormat.boolean,
|
|
8170
|
+
defaultValue: "true"
|
|
8171
|
+
},
|
|
8172
|
+
{
|
|
8173
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
8174
|
+
key: ConfigKey.property_example,
|
|
8175
|
+
exportJsonKey: [
|
|
8176
|
+
{ "@keyonly": { isExample: true } },
|
|
8177
|
+
{ "@absent": { isExample: true } },
|
|
8178
|
+
{ isExample: true, example: "$" }
|
|
8179
|
+
],
|
|
8180
|
+
description: "The example(s) for the bit",
|
|
8181
|
+
format: TagFormat.bitmarkText,
|
|
8182
|
+
nullable: true
|
|
6764
8183
|
}
|
|
6765
8184
|
]
|
|
6766
8185
|
},
|
|
@@ -6799,18 +8218,56 @@ var BITS = {
|
|
|
6799
8218
|
{
|
|
6800
8219
|
key: ConfigKey.group_gap,
|
|
6801
8220
|
description: "Tags for gaps in cloze bits"
|
|
8221
|
+
},
|
|
8222
|
+
{
|
|
8223
|
+
// Override inherited @example: cloze is in OLD parser's
|
|
8224
|
+
// `isTopLevelExample` allow-list, so [@example] at bit-header
|
|
8225
|
+
// emits `isExample: true`.
|
|
8226
|
+
key: ConfigKey.property_example,
|
|
8227
|
+
exportJsonKey: [
|
|
8228
|
+
{ "@keyonly": { isExample: true } },
|
|
8229
|
+
{ "@absent": { isExample: true } },
|
|
8230
|
+
{ isExample: true, example: "$" }
|
|
8231
|
+
],
|
|
8232
|
+
description: "The example(s) for the bit",
|
|
8233
|
+
format: TagFormat.bitmarkText,
|
|
8234
|
+
nullable: true
|
|
6802
8235
|
}
|
|
6803
8236
|
]
|
|
6804
8237
|
},
|
|
6805
8238
|
[BitType2.clozeInstructionGrouped]: {
|
|
6806
8239
|
since: "1.3.0",
|
|
6807
8240
|
baseBitType: BitType2.cloze,
|
|
6808
|
-
description: "Cloze instruction grouped bit, used for cloze questions with grouped instructions"
|
|
8241
|
+
description: "Cloze instruction grouped bit, used for cloze questions with grouped instructions",
|
|
8242
|
+
tags: [
|
|
8243
|
+
{
|
|
8244
|
+
key: ConfigKey.property_quizCountItems,
|
|
8245
|
+
description: "The number of items in the cloze quiz (instruction-grouped default: true)",
|
|
8246
|
+
format: TagFormat.boolean,
|
|
8247
|
+
defaultValue: "true"
|
|
8248
|
+
}
|
|
8249
|
+
// Note: quizStrikethroughSolutions defaults to false for instruction-grouped per OLD
|
|
8250
|
+
// JsonGenerator.ts:1689-1690, which equals the Boolean natural default → no override needed.
|
|
8251
|
+
]
|
|
6809
8252
|
},
|
|
6810
8253
|
[BitType2.clozeSolutionGrouped]: {
|
|
6811
8254
|
since: "1.3.0",
|
|
6812
8255
|
baseBitType: BitType2.cloze,
|
|
6813
|
-
description: "Cloze solution grouped bit, used for cloze questions with grouped solutions"
|
|
8256
|
+
description: "Cloze solution grouped bit, used for cloze questions with grouped solutions",
|
|
8257
|
+
tags: [
|
|
8258
|
+
{
|
|
8259
|
+
key: ConfigKey.property_quizCountItems,
|
|
8260
|
+
description: "The number of items in the cloze quiz (solution-grouped default: true)",
|
|
8261
|
+
format: TagFormat.boolean,
|
|
8262
|
+
defaultValue: "true"
|
|
8263
|
+
},
|
|
8264
|
+
{
|
|
8265
|
+
key: ConfigKey.property_quizStrikethroughSolutions,
|
|
8266
|
+
description: "If the cloze solutions should be strikethrough (solution-grouped default: true)",
|
|
8267
|
+
format: TagFormat.boolean,
|
|
8268
|
+
defaultValue: "true"
|
|
8269
|
+
}
|
|
8270
|
+
]
|
|
6814
8271
|
},
|
|
6815
8272
|
[BitType2.clozeSeveral]: {
|
|
6816
8273
|
since: "3.5.0",
|
|
@@ -6846,6 +8303,17 @@ var BITS = {
|
|
|
6846
8303
|
{
|
|
6847
8304
|
key: ConfigKey.group_quizCommon,
|
|
6848
8305
|
description: "Common tags for quiz bits"
|
|
8306
|
+
},
|
|
8307
|
+
{
|
|
8308
|
+
// PLAN-084 (R12): bit-level @isCaseSensitive — empty exportJsonKey
|
|
8309
|
+
// (no bit-level emission); defaultValue 'true' phantom-fires onto
|
|
8310
|
+
// the ancestor stack so each listItem's gap chain `@absent: $ancestor`
|
|
8311
|
+
// rule resolves to true. Mirrors the cloze bit (bits.ts:1326-1336).
|
|
8312
|
+
key: ConfigKey.property_isCaseSensitive,
|
|
8313
|
+
exportJsonKey: {},
|
|
8314
|
+
description: "If the cloze answers are case sensitive",
|
|
8315
|
+
format: TagFormat.boolean,
|
|
8316
|
+
defaultValue: "true"
|
|
6849
8317
|
}
|
|
6850
8318
|
],
|
|
6851
8319
|
cardSet: CardSetConfigKey.clozeList
|
|
@@ -7012,6 +8480,7 @@ var BITS = {
|
|
|
7012
8480
|
tags: [
|
|
7013
8481
|
{
|
|
7014
8482
|
key: ConfigKey.group_person,
|
|
8483
|
+
exportJsonKey: { partner: { name: "$" } },
|
|
7015
8484
|
description: "Tags for the person in the conversation"
|
|
7016
8485
|
}
|
|
7017
8486
|
]
|
|
@@ -7450,7 +8919,8 @@ var BITS = {
|
|
|
7450
8919
|
{ isExample: true, example: "$" }
|
|
7451
8920
|
],
|
|
7452
8921
|
description: "The example text for the essay bit",
|
|
7453
|
-
format: TagFormat.plainText
|
|
8922
|
+
format: TagFormat.plainText,
|
|
8923
|
+
nullable: true
|
|
7454
8924
|
}
|
|
7455
8925
|
],
|
|
7456
8926
|
rootExampleType: ExampleType.string
|
|
@@ -7484,7 +8954,8 @@ var BITS = {
|
|
|
7484
8954
|
{ isExample: true, example: "$" }
|
|
7485
8955
|
],
|
|
7486
8956
|
description: "The example text for the example bit",
|
|
7487
|
-
format: TagFormat.plainText
|
|
8957
|
+
format: TagFormat.plainText,
|
|
8958
|
+
nullable: true
|
|
7488
8959
|
}
|
|
7489
8960
|
],
|
|
7490
8961
|
rootExampleType: ExampleType.string
|
|
@@ -7570,7 +9041,19 @@ var BITS = {
|
|
|
7570
9041
|
[BitType2.articleAi]: {
|
|
7571
9042
|
since: "1.3.0",
|
|
7572
9043
|
baseBitType: BitType2.article,
|
|
7573
|
-
description: "Article AI bit, used to create AI-generated articles"
|
|
9044
|
+
description: "Article AI bit, used to create AI-generated articles",
|
|
9045
|
+
tags: [
|
|
9046
|
+
{
|
|
9047
|
+
// Shadows the inherited @aiGenerated from the standard group: this
|
|
9048
|
+
// bit type forces aiGenerated:true regardless of source value or
|
|
9049
|
+
// absence. Literal `true` in the export pattern ignores `$`.
|
|
9050
|
+
key: ConfigKey.property_aiGenerated,
|
|
9051
|
+
description: "AI-generated flag, forced true for article-ai bits",
|
|
9052
|
+
format: TagFormat.boolean,
|
|
9053
|
+
defaultValue: "true",
|
|
9054
|
+
exportJsonKey: { aiGenerated: true }
|
|
9055
|
+
}
|
|
9056
|
+
]
|
|
7574
9057
|
},
|
|
7575
9058
|
[BitType2.articleAttachment]: {
|
|
7576
9059
|
since: "1.3.0",
|
|
@@ -7895,7 +9378,19 @@ var BITS = {
|
|
|
7895
9378
|
[BitType2.noteAi]: {
|
|
7896
9379
|
since: "1.3.0",
|
|
7897
9380
|
baseBitType: BitType2.note,
|
|
7898
|
-
description: "Note AI bit, used to create AI-generated notes in articles or books"
|
|
9381
|
+
description: "Note AI bit, used to create AI-generated notes in articles or books",
|
|
9382
|
+
tags: [
|
|
9383
|
+
{
|
|
9384
|
+
// Shadows the inherited @aiGenerated from the standard group: this
|
|
9385
|
+
// bit type forces aiGenerated:true regardless of source value or
|
|
9386
|
+
// absence. Literal `true` in the export pattern ignores `$`.
|
|
9387
|
+
key: ConfigKey.property_aiGenerated,
|
|
9388
|
+
description: "AI-generated flag, forced true for article-ai bits",
|
|
9389
|
+
format: TagFormat.boolean,
|
|
9390
|
+
defaultValue: "true",
|
|
9391
|
+
exportJsonKey: { aiGenerated: true }
|
|
9392
|
+
}
|
|
9393
|
+
]
|
|
7899
9394
|
},
|
|
7900
9395
|
[BitType2.notebookArticle]: {
|
|
7901
9396
|
since: "1.3.0",
|
|
@@ -8020,7 +9515,19 @@ var BITS = {
|
|
|
8020
9515
|
[BitType2.summaryAi]: {
|
|
8021
9516
|
since: "1.3.0",
|
|
8022
9517
|
baseBitType: BitType2.summary,
|
|
8023
|
-
description: "AI-generated summary bit"
|
|
9518
|
+
description: "AI-generated summary bit",
|
|
9519
|
+
tags: [
|
|
9520
|
+
{
|
|
9521
|
+
// Shadows the inherited @aiGenerated from the standard group: this
|
|
9522
|
+
// bit type forces aiGenerated:true regardless of source value or
|
|
9523
|
+
// absence. Literal `true` in the export pattern ignores `$`.
|
|
9524
|
+
key: ConfigKey.property_aiGenerated,
|
|
9525
|
+
description: "AI-generated flag, forced true for article-ai bits",
|
|
9526
|
+
format: TagFormat.boolean,
|
|
9527
|
+
defaultValue: "true",
|
|
9528
|
+
exportJsonKey: { aiGenerated: true }
|
|
9529
|
+
}
|
|
9530
|
+
]
|
|
8024
9531
|
},
|
|
8025
9532
|
[BitType2.videoTranscript]: {
|
|
8026
9533
|
since: "1.3.0",
|
|
@@ -8294,7 +9801,7 @@ var BITS = {
|
|
|
8294
9801
|
description: "Product ID for the module product, used to link to a specific product",
|
|
8295
9802
|
format: TagFormat.plainText,
|
|
8296
9803
|
minCount: 1,
|
|
8297
|
-
maxCount:
|
|
9804
|
+
maxCount: 1
|
|
8298
9805
|
}
|
|
8299
9806
|
]
|
|
8300
9807
|
},
|
|
@@ -8347,10 +9854,13 @@ var BITS = {
|
|
|
8347
9854
|
description: "Resource bit tags for logo grave images, used to define additional properties"
|
|
8348
9855
|
},
|
|
8349
9856
|
{
|
|
8350
|
-
// Image resource
|
|
8351
|
-
|
|
9857
|
+
// Image resource — fully-expanded shape so each `&image` emission
|
|
9858
|
+
// produces a complete `{type, image: {src}}` object inside the
|
|
9859
|
+
// `images[]` array. Chain attrs like `[@zoomDisabled]` fold under
|
|
9860
|
+
// `images[].image` via the `[]` last-element-merge semantic.
|
|
9861
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
8352
9862
|
description: "Resource image tags for logo grave images, used to attach images",
|
|
8353
|
-
exportJsonKey: { images: "$" },
|
|
9863
|
+
exportJsonKey: { images: [{ type: "image", image: { src: "$" } }] },
|
|
8354
9864
|
minCount: 1,
|
|
8355
9865
|
maxCount: Count.infinity
|
|
8356
9866
|
}
|
|
@@ -8640,6 +10150,10 @@ var BITS = {
|
|
|
8640
10150
|
tags: [
|
|
8641
10151
|
{
|
|
8642
10152
|
key: ConfigKey.property_book,
|
|
10153
|
+
// Starter-array shape: each `[@book:value]` chain appends a fresh
|
|
10154
|
+
// `{ book, reference }` entry. The chained `►` (tag_reference) lands
|
|
10155
|
+
// inside the most-recently-appended entry as `reference: $`.
|
|
10156
|
+
exportJsonKey: { book: [{ book: "$" }] },
|
|
8643
10157
|
description: "Book reference for the page, used to link to a specific book",
|
|
8644
10158
|
maxCount: Count.infinity,
|
|
8645
10159
|
chain: [
|
|
@@ -8707,7 +10221,9 @@ var BITS = {
|
|
|
8707
10221
|
format: TagFormat.plainText
|
|
8708
10222
|
}
|
|
8709
10223
|
],
|
|
8710
|
-
|
|
10224
|
+
// page-footer emits cards under `sections` (vs `listItems` for the
|
|
10225
|
+
// sibling exampleList / assignmentList bits) — see JsonGenerator.ts.
|
|
10226
|
+
cardSet: CardSetConfigKey.pageFooterSections
|
|
8711
10227
|
},
|
|
8712
10228
|
[BitType2.legend]: {
|
|
8713
10229
|
since: "3.12.0",
|
|
@@ -8749,6 +10265,20 @@ var BITS = {
|
|
|
8749
10265
|
since: "1.34.0",
|
|
8750
10266
|
baseBitType: BitType2._standard,
|
|
8751
10267
|
description: "Definition list bit, used to create lists of definitions in articles or books",
|
|
10268
|
+
tags: [
|
|
10269
|
+
{
|
|
10270
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10271
|
+
key: ConfigKey.property_example,
|
|
10272
|
+
exportJsonKey: [
|
|
10273
|
+
{ "@keyonly": { isExample: true } },
|
|
10274
|
+
{ "@absent": { isExample: true } },
|
|
10275
|
+
{ isExample: true, example: "$" }
|
|
10276
|
+
],
|
|
10277
|
+
description: "The example(s) for the bit",
|
|
10278
|
+
format: TagFormat.bitmarkText,
|
|
10279
|
+
nullable: true
|
|
10280
|
+
}
|
|
10281
|
+
],
|
|
8752
10282
|
cardSet: CardSetConfigKey.definitionList
|
|
8753
10283
|
},
|
|
8754
10284
|
[BitType2.metaSearchDefaultTerms]: {
|
|
@@ -8771,6 +10301,18 @@ var BITS = {
|
|
|
8771
10301
|
{
|
|
8772
10302
|
key: ConfigKey.group_quizCommon,
|
|
8773
10303
|
description: "Common quiz tags for flashcards"
|
|
10304
|
+
},
|
|
10305
|
+
{
|
|
10306
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10307
|
+
key: ConfigKey.property_example,
|
|
10308
|
+
exportJsonKey: [
|
|
10309
|
+
{ "@keyonly": { isExample: true } },
|
|
10310
|
+
{ "@absent": { isExample: true } },
|
|
10311
|
+
{ isExample: true, example: "$" }
|
|
10312
|
+
],
|
|
10313
|
+
description: "The example(s) for the bit",
|
|
10314
|
+
format: TagFormat.bitmarkText,
|
|
10315
|
+
nullable: true
|
|
8774
10316
|
}
|
|
8775
10317
|
],
|
|
8776
10318
|
cardSet: CardSetConfigKey.flashcard
|
|
@@ -8778,7 +10320,11 @@ var BITS = {
|
|
|
8778
10320
|
[BitType2.flashcard1]: {
|
|
8779
10321
|
since: "1.3.0",
|
|
8780
10322
|
baseBitType: BitType2.flashcard,
|
|
8781
|
-
description: "Flashcard 1 bit"
|
|
10323
|
+
description: "Flashcard 1 bit",
|
|
10324
|
+
// PLAN-085: use the flashcard1 cardset (sections.default.maxCount=1)
|
|
10325
|
+
// instead of inheriting `flashcard`'s unbounded cardset, since this
|
|
10326
|
+
// bit type structurally allows only a single card.
|
|
10327
|
+
cardSet: CardSetConfigKey.flashcard1
|
|
8782
10328
|
},
|
|
8783
10329
|
[BitType2.qAndACard]: {
|
|
8784
10330
|
since: "3.25.0",
|
|
@@ -8813,8 +10359,24 @@ var BITS = {
|
|
|
8813
10359
|
description: "Common quiz tags for highlighted text"
|
|
8814
10360
|
},
|
|
8815
10361
|
{
|
|
8816
|
-
|
|
8817
|
-
|
|
10362
|
+
// Dedicated highlight inline-select chain: tag_true / tag_false
|
|
10363
|
+
// emit `{type:"highlight", attrs:{texts:[{text,isCorrect?}]}}`
|
|
10364
|
+
// inline body nodes via @body-inline. Bit shares no tag IDs with
|
|
10365
|
+
// multiple-choice / multiple-choice-1 (which use group_trueFalse).
|
|
10366
|
+
key: ConfigKey.group_trueFalseInlineHighlight,
|
|
10367
|
+
description: "True/False quiz tags for highlighted text (inline body nodes)"
|
|
10368
|
+
},
|
|
10369
|
+
{
|
|
10370
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10371
|
+
key: ConfigKey.property_example,
|
|
10372
|
+
exportJsonKey: [
|
|
10373
|
+
{ "@keyonly": { isExample: true } },
|
|
10374
|
+
{ "@absent": { isExample: true } },
|
|
10375
|
+
{ isExample: true, example: "$" }
|
|
10376
|
+
],
|
|
10377
|
+
description: "The example(s) for the bit",
|
|
10378
|
+
format: TagFormat.bitmarkText,
|
|
10379
|
+
nullable: true
|
|
8818
10380
|
}
|
|
8819
10381
|
]
|
|
8820
10382
|
},
|
|
@@ -8824,15 +10386,8 @@ var BITS = {
|
|
|
8824
10386
|
description: "Image bit, used to create images in articles or books",
|
|
8825
10387
|
tags: [
|
|
8826
10388
|
{
|
|
8827
|
-
key: ConfigKey.
|
|
8828
|
-
|
|
8829
|
-
description: "Background wallpaper for the image, used to set a background for the image",
|
|
8830
|
-
chain: [
|
|
8831
|
-
{
|
|
8832
|
-
key: ConfigKey.group_resourceImageCommon,
|
|
8833
|
-
description: "Common resource image tags for images"
|
|
8834
|
-
}
|
|
8835
|
-
]
|
|
10389
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
10390
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
8836
10391
|
},
|
|
8837
10392
|
{
|
|
8838
10393
|
key: ConfigKey.group_resourceBitTags,
|
|
@@ -8935,8 +10490,15 @@ var BITS = {
|
|
|
8935
10490
|
},
|
|
8936
10491
|
[BitType2.imageSeparator]: {
|
|
8937
10492
|
since: "1.4.15",
|
|
8938
|
-
baseBitType: BitType2.
|
|
8939
|
-
description: "Image separator bit, used to create separators in articles or books"
|
|
10493
|
+
baseBitType: BitType2._standard,
|
|
10494
|
+
description: "Image separator bit, used to create separators in articles or books",
|
|
10495
|
+
tags: [
|
|
10496
|
+
{
|
|
10497
|
+
key: ConfigKey.group_imageNoZoom,
|
|
10498
|
+
description: "Image no zoom tags for images, used to define whether images should have zoom functionality"
|
|
10499
|
+
}
|
|
10500
|
+
],
|
|
10501
|
+
resourceAttachmentAllowed: false
|
|
8940
10502
|
},
|
|
8941
10503
|
[BitType2.imageSeparatorAlt]: {
|
|
8942
10504
|
since: "1.16.0",
|
|
@@ -8975,15 +10537,20 @@ var BITS = {
|
|
|
8975
10537
|
},
|
|
8976
10538
|
[BitType2.pageBanner]: {
|
|
8977
10539
|
since: "1.4.3",
|
|
8978
|
-
baseBitType: BitType2.
|
|
10540
|
+
baseBitType: BitType2._standard,
|
|
8979
10541
|
description: "Page banner bit, used to create banners for pages in articles or books",
|
|
8980
10542
|
tags: [
|
|
8981
10543
|
{
|
|
8982
10544
|
key: ConfigKey.property_slug,
|
|
8983
10545
|
description: "Slug for the page banner, used to identify the banner in the system",
|
|
8984
10546
|
format: TagFormat.plainText
|
|
10547
|
+
},
|
|
10548
|
+
{
|
|
10549
|
+
key: ConfigKey.group_imageNoZoom,
|
|
10550
|
+
description: "Image no zoom tags for images, used to define whether images should have zoom functionality"
|
|
8985
10551
|
}
|
|
8986
|
-
]
|
|
10552
|
+
],
|
|
10553
|
+
resourceAttachmentAllowed: false
|
|
8987
10554
|
},
|
|
8988
10555
|
[BitType2.pageHero]: {
|
|
8989
10556
|
since: "1.11.0",
|
|
@@ -8998,7 +10565,7 @@ var BITS = {
|
|
|
8998
10565
|
},
|
|
8999
10566
|
[BitType2.tableImage]: {
|
|
9000
10567
|
since: "1.5.15",
|
|
9001
|
-
baseBitType: BitType2.
|
|
10568
|
+
baseBitType: BitType2.tableExtended,
|
|
9002
10569
|
description: "Table image bit, used to create images in tables in articles or books",
|
|
9003
10570
|
tags: [
|
|
9004
10571
|
{
|
|
@@ -9007,15 +10574,8 @@ var BITS = {
|
|
|
9007
10574
|
format: TagFormat.bitmarkText
|
|
9008
10575
|
},
|
|
9009
10576
|
{
|
|
9010
|
-
key: ConfigKey.
|
|
9011
|
-
|
|
9012
|
-
description: "Background wallpaper for the image, used to set a background for the image",
|
|
9013
|
-
chain: [
|
|
9014
|
-
{
|
|
9015
|
-
key: ConfigKey.group_resourceImageCommon,
|
|
9016
|
-
description: "Common resource image tags for images"
|
|
9017
|
-
}
|
|
9018
|
-
]
|
|
10577
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
10578
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
9019
10579
|
},
|
|
9020
10580
|
{
|
|
9021
10581
|
key: ConfigKey.group_resourceBitTags,
|
|
@@ -9158,10 +10718,10 @@ var BITS = {
|
|
|
9158
10718
|
description: "Resource bit tags for logo grave images, used to define additional properties"
|
|
9159
10719
|
},
|
|
9160
10720
|
{
|
|
9161
|
-
// Image resource
|
|
9162
|
-
key: ConfigKey.
|
|
10721
|
+
// Image resource — fully-expanded shape (see BitType.extractorImage).
|
|
10722
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
9163
10723
|
description: "Resource image tags for logo grave images, used to attach images",
|
|
9164
|
-
exportJsonKey: { logos: "$" },
|
|
10724
|
+
exportJsonKey: { logos: [{ type: "image", image: { src: "$" } }] },
|
|
9165
10725
|
minCount: 1,
|
|
9166
10726
|
maxCount: Count.infinity
|
|
9167
10727
|
}
|
|
@@ -9171,7 +10731,17 @@ var BITS = {
|
|
|
9171
10731
|
[BitType2.prototypeImages]: {
|
|
9172
10732
|
since: "1.6.1",
|
|
9173
10733
|
baseBitType: BitType2.imagesLogoGrave,
|
|
9174
|
-
description: "Prototype images bit, used to create prototype images in articles or books"
|
|
10734
|
+
description: "Prototype images bit, used to create prototype images in articles or books",
|
|
10735
|
+
tags: [
|
|
10736
|
+
{
|
|
10737
|
+
// Override inherited `logos` wrapper with `images` for this bit type.
|
|
10738
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
10739
|
+
description: "Resource image tags for prototype images",
|
|
10740
|
+
exportJsonKey: { images: [{ type: "image", image: { src: "$" } }] },
|
|
10741
|
+
minCount: 1,
|
|
10742
|
+
maxCount: Count.infinity
|
|
10743
|
+
}
|
|
10744
|
+
]
|
|
9175
10745
|
},
|
|
9176
10746
|
[BitType2.internalLink]: {
|
|
9177
10747
|
since: "1.3.0",
|
|
@@ -9201,6 +10771,18 @@ var BITS = {
|
|
|
9201
10771
|
exportJsonKey: {},
|
|
9202
10772
|
description: "Reasonable number of characters for the interview, used to limit input size",
|
|
9203
10773
|
format: TagFormat.number
|
|
10774
|
+
},
|
|
10775
|
+
{
|
|
10776
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10777
|
+
key: ConfigKey.property_example,
|
|
10778
|
+
exportJsonKey: [
|
|
10779
|
+
{ "@keyonly": { isExample: true } },
|
|
10780
|
+
{ "@absent": { isExample: true } },
|
|
10781
|
+
{ isExample: true, example: "$" }
|
|
10782
|
+
],
|
|
10783
|
+
description: "The example(s) for the bit",
|
|
10784
|
+
format: TagFormat.bitmarkText,
|
|
10785
|
+
nullable: true
|
|
9204
10786
|
}
|
|
9205
10787
|
],
|
|
9206
10788
|
cardSet: CardSetConfigKey.questions
|
|
@@ -9559,6 +11141,18 @@ var BITS = {
|
|
|
9559
11141
|
{
|
|
9560
11142
|
key: ConfigKey.group_mark,
|
|
9561
11143
|
description: "Mark tags, used to define the content of marks"
|
|
11144
|
+
},
|
|
11145
|
+
{
|
|
11146
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11147
|
+
key: ConfigKey.property_example,
|
|
11148
|
+
exportJsonKey: [
|
|
11149
|
+
{ "@keyonly": { isExample: true } },
|
|
11150
|
+
{ "@absent": { isExample: true } },
|
|
11151
|
+
{ isExample: true, example: "$" }
|
|
11152
|
+
],
|
|
11153
|
+
description: "The example(s) for the bit",
|
|
11154
|
+
format: TagFormat.bitmarkText,
|
|
11155
|
+
nullable: true
|
|
9562
11156
|
}
|
|
9563
11157
|
]
|
|
9564
11158
|
},
|
|
@@ -9578,6 +11172,23 @@ var BITS = {
|
|
|
9578
11172
|
description: "Case sensitivity for matching pairs, used to define if matches are case-sensitive",
|
|
9579
11173
|
format: TagFormat.boolean,
|
|
9580
11174
|
defaultValue: "true"
|
|
11175
|
+
},
|
|
11176
|
+
{
|
|
11177
|
+
// Override inherited @example: in `isTopLevelExample` allow-list
|
|
11178
|
+
// (covers match, matchAll, matchReverse, matchAllReverse,
|
|
11179
|
+
// matchSolutionGrouped, matchMatrix, matchAudio, matchPicture).
|
|
11180
|
+
// Bit-level fires emit only `isExample`; the @example value (when
|
|
11181
|
+
// provided) is recorded in the ancestor stack and consumed by
|
|
11182
|
+
// per-pair/per-cell variant overrides — not surfaced at bit scope.
|
|
11183
|
+
key: ConfigKey.property_example,
|
|
11184
|
+
exportJsonKey: [
|
|
11185
|
+
{ "@keyonly": { isExample: true } },
|
|
11186
|
+
{ "@absent": { isExample: true } },
|
|
11187
|
+
{ isExample: true }
|
|
11188
|
+
],
|
|
11189
|
+
description: "The example(s) for the bit",
|
|
11190
|
+
format: TagFormat.bitmarkText,
|
|
11191
|
+
nullable: true
|
|
9581
11192
|
}
|
|
9582
11193
|
],
|
|
9583
11194
|
cardSet: CardSetConfigKey.matchPairs
|
|
@@ -9662,6 +11273,18 @@ var BITS = {
|
|
|
9662
11273
|
{
|
|
9663
11274
|
key: ConfigKey.group_trueFalse,
|
|
9664
11275
|
description: "True/False tags for multiple choice 1 questions"
|
|
11276
|
+
},
|
|
11277
|
+
{
|
|
11278
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11279
|
+
key: ConfigKey.property_example,
|
|
11280
|
+
exportJsonKey: [
|
|
11281
|
+
{ "@keyonly": { isExample: true } },
|
|
11282
|
+
{ "@absent": { isExample: true } },
|
|
11283
|
+
{ isExample: true, example: "$" }
|
|
11284
|
+
],
|
|
11285
|
+
description: "The example(s) for the bit",
|
|
11286
|
+
format: TagFormat.bitmarkText,
|
|
11287
|
+
nullable: true
|
|
9665
11288
|
}
|
|
9666
11289
|
]
|
|
9667
11290
|
},
|
|
@@ -9683,8 +11306,20 @@ var BITS = {
|
|
|
9683
11306
|
{
|
|
9684
11307
|
key: ConfigKey.group_trueFalse,
|
|
9685
11308
|
description: "True/False tags for multiple choice questions"
|
|
9686
|
-
}
|
|
11309
|
+
},
|
|
9687
11310
|
// This is actually for multiple-choice-1, but we support it here as well (as many bits are wrong)
|
|
11311
|
+
{
|
|
11312
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11313
|
+
key: ConfigKey.property_example,
|
|
11314
|
+
exportJsonKey: [
|
|
11315
|
+
{ "@keyonly": { isExample: true } },
|
|
11316
|
+
{ "@absent": { isExample: true } },
|
|
11317
|
+
{ isExample: true, example: "$" }
|
|
11318
|
+
],
|
|
11319
|
+
description: "The example(s) for the bit",
|
|
11320
|
+
format: TagFormat.bitmarkText,
|
|
11321
|
+
nullable: true
|
|
11322
|
+
}
|
|
9688
11323
|
],
|
|
9689
11324
|
cardSet: CardSetConfigKey.quiz
|
|
9690
11325
|
},
|
|
@@ -9704,8 +11339,20 @@ var BITS = {
|
|
|
9704
11339
|
description: "Common quiz tags for multiple choice text questions"
|
|
9705
11340
|
},
|
|
9706
11341
|
{
|
|
9707
|
-
key: ConfigKey.
|
|
11342
|
+
key: ConfigKey.group_trueFalseInlineSelect,
|
|
9708
11343
|
description: "True/False tags for multiple choice text questions"
|
|
11344
|
+
},
|
|
11345
|
+
{
|
|
11346
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11347
|
+
key: ConfigKey.property_example,
|
|
11348
|
+
exportJsonKey: [
|
|
11349
|
+
{ "@keyonly": { isExample: true } },
|
|
11350
|
+
{ "@absent": { isExample: true } },
|
|
11351
|
+
{ isExample: true, example: "$" }
|
|
11352
|
+
],
|
|
11353
|
+
description: "The example(s) for the bit",
|
|
11354
|
+
format: TagFormat.bitmarkText,
|
|
11355
|
+
nullable: true
|
|
9709
11356
|
}
|
|
9710
11357
|
]
|
|
9711
11358
|
},
|
|
@@ -9730,8 +11377,20 @@ var BITS = {
|
|
|
9730
11377
|
description: "Common quiz tags for multiple response 1 questions"
|
|
9731
11378
|
},
|
|
9732
11379
|
{
|
|
9733
|
-
key: ConfigKey.
|
|
11380
|
+
key: ConfigKey.group_trueFalseResponses,
|
|
9734
11381
|
description: "True/False tags for multiple response 1 questions"
|
|
11382
|
+
},
|
|
11383
|
+
{
|
|
11384
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11385
|
+
key: ConfigKey.property_example,
|
|
11386
|
+
exportJsonKey: [
|
|
11387
|
+
{ "@keyonly": { isExample: true } },
|
|
11388
|
+
{ "@absent": { isExample: true } },
|
|
11389
|
+
{ isExample: true, example: "$" }
|
|
11390
|
+
],
|
|
11391
|
+
description: "The example(s) for the bit",
|
|
11392
|
+
format: TagFormat.bitmarkText,
|
|
11393
|
+
nullable: true
|
|
9735
11394
|
}
|
|
9736
11395
|
]
|
|
9737
11396
|
},
|
|
@@ -9751,12 +11410,24 @@ var BITS = {
|
|
|
9751
11410
|
description: "Common quiz tags for multiple response questions"
|
|
9752
11411
|
},
|
|
9753
11412
|
{
|
|
9754
|
-
key: ConfigKey.
|
|
11413
|
+
key: ConfigKey.group_trueFalseResponses,
|
|
9755
11414
|
description: "True/False tags for multiple response questions"
|
|
9756
|
-
}
|
|
11415
|
+
},
|
|
9757
11416
|
// This is actually for multiple-response-1, but we support it here as well (as many bits are wrong)
|
|
11417
|
+
{
|
|
11418
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11419
|
+
key: ConfigKey.property_example,
|
|
11420
|
+
exportJsonKey: [
|
|
11421
|
+
{ "@keyonly": { isExample: true } },
|
|
11422
|
+
{ "@absent": { isExample: true } },
|
|
11423
|
+
{ isExample: true, example: "$" }
|
|
11424
|
+
],
|
|
11425
|
+
description: "The example(s) for the bit",
|
|
11426
|
+
format: TagFormat.bitmarkText,
|
|
11427
|
+
nullable: true
|
|
11428
|
+
}
|
|
9758
11429
|
],
|
|
9759
|
-
cardSet: CardSetConfigKey.
|
|
11430
|
+
cardSet: CardSetConfigKey.quizResponses
|
|
9760
11431
|
},
|
|
9761
11432
|
[BitType2.coachSelfReflectionMultipleResponse]: {
|
|
9762
11433
|
since: "1.3.0",
|
|
@@ -10006,6 +11677,8 @@ var BITS = {
|
|
|
10006
11677
|
},
|
|
10007
11678
|
{
|
|
10008
11679
|
key: ConfigKey.resource_platformIcon,
|
|
11680
|
+
jsonKey: "platformIcon|resource(type=image, key=image)",
|
|
11681
|
+
exportJsonKey: { platformIcon: { type: "image", image: { src: "$" } } },
|
|
10009
11682
|
description: "The platform icon",
|
|
10010
11683
|
chain: [
|
|
10011
11684
|
{
|
|
@@ -10041,6 +11714,8 @@ var BITS = {
|
|
|
10041
11714
|
tags: [
|
|
10042
11715
|
{
|
|
10043
11716
|
key: ConfigKey.resource_platformLogo,
|
|
11717
|
+
jsonKey: "platformLogo|resource(type=image, key=image)",
|
|
11718
|
+
exportJsonKey: { platformLogo: { type: "image", image: { src: "$" } } },
|
|
10044
11719
|
description: "The platform logo",
|
|
10045
11720
|
chain: [
|
|
10046
11721
|
{
|
|
@@ -10252,7 +11927,8 @@ var BITS = {
|
|
|
10252
11927
|
{ isExample: true, example: "$" }
|
|
10253
11928
|
],
|
|
10254
11929
|
description: "The example text for the review note bit",
|
|
10255
|
-
format: TagFormat.plainText
|
|
11930
|
+
format: TagFormat.plainText,
|
|
11931
|
+
nullable: true
|
|
10256
11932
|
}
|
|
10257
11933
|
],
|
|
10258
11934
|
rootExampleType: ExampleType.string
|
|
@@ -10339,7 +12015,8 @@ var BITS = {
|
|
|
10339
12015
|
{ isExample: true, example: "$" }
|
|
10340
12016
|
],
|
|
10341
12017
|
description: "The example flag for the bit (boolean)",
|
|
10342
|
-
format: TagFormat.
|
|
12018
|
+
format: TagFormat.boolean,
|
|
12019
|
+
nullable: true
|
|
10343
12020
|
}
|
|
10344
12021
|
],
|
|
10345
12022
|
cardSet: CardSetConfigKey.elements,
|
|
@@ -10613,15 +12290,8 @@ var BITS = {
|
|
|
10613
12290
|
format: TagFormat.bitmarkText
|
|
10614
12291
|
},
|
|
10615
12292
|
{
|
|
10616
|
-
key: ConfigKey.
|
|
10617
|
-
|
|
10618
|
-
description: "Background wallpaper for the image, used to set a background for the image",
|
|
10619
|
-
chain: [
|
|
10620
|
-
{
|
|
10621
|
-
key: ConfigKey.group_resourceImageCommon,
|
|
10622
|
-
description: "Common resource image tags for images"
|
|
10623
|
-
}
|
|
10624
|
-
]
|
|
12293
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
12294
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
10625
12295
|
},
|
|
10626
12296
|
{
|
|
10627
12297
|
key: ConfigKey.group_resourceBitTags,
|
|
@@ -10998,16 +12668,20 @@ var BITS = {
|
|
|
10998
12668
|
format: TagFormat.plainText
|
|
10999
12669
|
},
|
|
11000
12670
|
{
|
|
11001
|
-
|
|
12671
|
+
// PLAN-067 Edit #1: true-false-1's `+` / `-` emit a flat
|
|
12672
|
+
// `{ statement, isCorrect }` at bit root (single-statement bit),
|
|
12673
|
+
// not a `choices[]` array. Format is bitmarkText so the statement
|
|
12674
|
+
// body renders as a ProseMirror tree, matching reference fixtures.
|
|
12675
|
+
exportJsonKey: { statement: "$", isCorrect: true },
|
|
11002
12676
|
key: ConfigKey.tag_true,
|
|
11003
12677
|
description: "Tag for the true option in the true/false question",
|
|
11004
|
-
format: TagFormat.
|
|
12678
|
+
format: TagFormat.bitmarkText
|
|
11005
12679
|
},
|
|
11006
12680
|
{
|
|
11007
|
-
exportJsonKey: {
|
|
12681
|
+
exportJsonKey: { statement: "$", isCorrect: false },
|
|
11008
12682
|
key: ConfigKey.tag_false,
|
|
11009
12683
|
description: "Tag for the false option in the true/false question",
|
|
11010
|
-
format: TagFormat.
|
|
12684
|
+
format: TagFormat.bitmarkText
|
|
11011
12685
|
},
|
|
11012
12686
|
{
|
|
11013
12687
|
// Override inherited @example from group_standardTags: boolean root
|
|
@@ -11018,14 +12692,24 @@ var BITS = {
|
|
|
11018
12692
|
// sufficient for `[+...]` (correct) statements which dominate the
|
|
11019
12693
|
// fixtures; `[-...]` (incorrect) bits with bare `[@example]` would
|
|
11020
12694
|
// need either a runtime extension or an explicit `[@example:false]`.
|
|
12695
|
+
//
|
|
12696
|
+
// Format is `boolean` so `[@example:false]` coerces to JSON `false`
|
|
12697
|
+
// (a natural default that gets stripped in optimised mode, matching
|
|
12698
|
+
// BPG's `rootExampleType: boolean`). PlainText would emit the
|
|
12699
|
+
// STRING `"false"` which doesn't strip.
|
|
11021
12700
|
key: ConfigKey.property_example,
|
|
11022
12701
|
exportJsonKey: [
|
|
11023
12702
|
{ "@keyonly": { isExample: true, example: true } },
|
|
11024
12703
|
{ "@absent": { isExample: true, example: true } },
|
|
12704
|
+
// `[@example:false]`: emit `isExample: true` only — `example: false`
|
|
12705
|
+
// is the natural default for boolean, stripped in optimised mode.
|
|
12706
|
+
// Mirrors BPG `removeUnwantedProperties` `ignoreAllFalse: true`.
|
|
12707
|
+
{ "@value=false": { isExample: true } },
|
|
11025
12708
|
{ isExample: true, example: "$" }
|
|
11026
12709
|
],
|
|
11027
12710
|
description: "The example flag for the bit (boolean)",
|
|
11028
|
-
format: TagFormat.
|
|
12711
|
+
format: TagFormat.boolean,
|
|
12712
|
+
nullable: true
|
|
11029
12713
|
}
|
|
11030
12714
|
],
|
|
11031
12715
|
rootExampleType: ExampleType.boolean
|
|
@@ -11049,6 +12733,18 @@ var BITS = {
|
|
|
11049
12733
|
key: ConfigKey.property_labelFalse,
|
|
11050
12734
|
description: "Label for the false option in the true/false question",
|
|
11051
12735
|
format: TagFormat.plainText
|
|
12736
|
+
},
|
|
12737
|
+
{
|
|
12738
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
12739
|
+
key: ConfigKey.property_example,
|
|
12740
|
+
exportJsonKey: [
|
|
12741
|
+
{ "@keyonly": { isExample: true } },
|
|
12742
|
+
{ "@absent": { isExample: true } },
|
|
12743
|
+
{ isExample: true, example: "$" }
|
|
12744
|
+
],
|
|
12745
|
+
description: "The example(s) for the bit",
|
|
12746
|
+
format: TagFormat.bitmarkText,
|
|
12747
|
+
nullable: true
|
|
11052
12748
|
}
|
|
11053
12749
|
],
|
|
11054
12750
|
cardSet: CardSetConfigKey.statements
|
|
@@ -11238,6 +12934,11 @@ var BITS = {
|
|
|
11238
12934
|
baseBitType: BitType2.vendorStripePricingTable,
|
|
11239
12935
|
description: "Stripe pricing table bit with print-on-request customer/product IDs, used to embed Stripe pricing tables tied to a specific print-on-request customer and product",
|
|
11240
12936
|
tags: [
|
|
12937
|
+
{
|
|
12938
|
+
key: ConfigKey.property_stripePricingTableDescriptiveName,
|
|
12939
|
+
description: "Descriptive name for the Stripe pricing table",
|
|
12940
|
+
format: TagFormat.plainText
|
|
12941
|
+
},
|
|
11241
12942
|
{
|
|
11242
12943
|
key: ConfigKey.property_printOnRequestCustomerId,
|
|
11243
12944
|
description: "Print-on-request customer ID, used to identify the customer for the print-on-request flow",
|
|
@@ -11714,7 +13415,7 @@ var instance2 = new Config();
|
|
|
11714
13415
|
// src/generated/package_info.ts
|
|
11715
13416
|
var PACKAGE_INFO = {
|
|
11716
13417
|
"name": "@gmb/bitmark-parser-generator",
|
|
11717
|
-
"version": "5.
|
|
13418
|
+
"version": "5.24.0",
|
|
11718
13419
|
"author": "Get More Brain Ltd",
|
|
11719
13420
|
"license": "ISC",
|
|
11720
13421
|
"description": "A bitmark parser and generator using Peggy.js"
|
|
@@ -12679,6 +14380,8 @@ var NodeType = {
|
|
|
12679
14380
|
stillImageFilmLink: "stillImageFilmLink",
|
|
12680
14381
|
stripePricingTableId: "stripePricingTableId",
|
|
12681
14382
|
stripePricingTableIdValue: "stripePricingTableIdValue",
|
|
14383
|
+
stripePricingTableDescriptiveName: "stripePricingTableDescriptiveName",
|
|
14384
|
+
stripePricingTableDescriptiveNameValue: "stripePricingTableDescriptiveNameValue",
|
|
12682
14385
|
stripePublishableKey: "stripePublishableKey",
|
|
12683
14386
|
stripePublishableKeyValue: "stripePublishableKeyValue",
|
|
12684
14387
|
subject: "subject",
|
|
@@ -26104,6 +27807,12 @@ var Builder = class extends BaseBuilder {
|
|
|
26104
27807
|
data.stripePricingTableId,
|
|
26105
27808
|
options
|
|
26106
27809
|
),
|
|
27810
|
+
stripePricingTableDescriptiveName: this.toAstProperty(
|
|
27811
|
+
bitType,
|
|
27812
|
+
ConfigKey.property_stripePricingTableDescriptiveName,
|
|
27813
|
+
data.stripePricingTableDescriptiveName,
|
|
27814
|
+
options
|
|
27815
|
+
),
|
|
26107
27816
|
stripePublishableKey: this.toAstProperty(
|
|
26108
27817
|
bitType,
|
|
26109
27818
|
ConfigKey.property_stripePublishableKey,
|
|
@@ -34331,6 +36040,7 @@ function buildCards(context, bitType, textFormat, parsedCardSet, statementV1, st
|
|
|
34331
36040
|
const cardSetType = bitConfig.cardSet?.configKey;
|
|
34332
36041
|
switch (cardSetType) {
|
|
34333
36042
|
case CardSetConfigKey.flashcard:
|
|
36043
|
+
case CardSetConfigKey.flashcard1:
|
|
34334
36044
|
case CardSetConfigKey.definitionList:
|
|
34335
36045
|
result = parseFlashcardOrDefinitionList(context, bitType, processedCardSet);
|
|
34336
36046
|
break;
|
|
@@ -34344,6 +36054,7 @@ function buildCards(context, bitType, textFormat, parsedCardSet, statementV1, st
|
|
|
34344
36054
|
result = parseFeedback(context, bitType, processedCardSet);
|
|
34345
36055
|
break;
|
|
34346
36056
|
case CardSetConfigKey.quiz:
|
|
36057
|
+
case CardSetConfigKey.quizResponses:
|
|
34347
36058
|
result = parseQuiz(context, bitType, processedCardSet, choicesV1, responsesV1);
|
|
34348
36059
|
break;
|
|
34349
36060
|
case CardSetConfigKey.questions:
|
|
@@ -34370,6 +36081,7 @@ function buildCards(context, bitType, textFormat, parsedCardSet, statementV1, st
|
|
|
34370
36081
|
break;
|
|
34371
36082
|
case CardSetConfigKey.clozeList:
|
|
34372
36083
|
case CardSetConfigKey.exampleBitList:
|
|
36084
|
+
case CardSetConfigKey.pageFooterSections:
|
|
34373
36085
|
case CardSetConfigKey.bookReferenceList:
|
|
34374
36086
|
result = parseCardBits(context, bitType, textFormat, processedCardSet);
|
|
34375
36087
|
break;
|