@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
|
@@ -778,10 +778,12 @@ var TextFormat2 = {
|
|
|
778
778
|
var import_superenum7 = require("@ncoderz/superenum");
|
|
779
779
|
var CardSetConfigKey = {
|
|
780
780
|
flashcard: "flashcard",
|
|
781
|
+
flashcard1: "flashcard1",
|
|
781
782
|
definitionList: "definitionList",
|
|
782
783
|
elements: "elements",
|
|
783
784
|
statements: "statements",
|
|
784
785
|
quiz: "quiz",
|
|
786
|
+
quizResponses: "quizResponses",
|
|
785
787
|
feedback: "feedback",
|
|
786
788
|
questions: "questions",
|
|
787
789
|
matchPairs: "matchPairs",
|
|
@@ -793,6 +795,7 @@ var CardSetConfigKey = {
|
|
|
793
795
|
pronunciationTable: "pronunciationTable",
|
|
794
796
|
botActionResponses: "botActionResponses",
|
|
795
797
|
exampleBitList: "exampleBitList",
|
|
798
|
+
pageFooterSections: "pageFooterSections",
|
|
796
799
|
clozeList: "clozeList",
|
|
797
800
|
ingredients: "ingredients",
|
|
798
801
|
// DEPRECATED - TO BE REMOVED IN THE FUTURE
|
|
@@ -1209,12 +1212,17 @@ var groupKeys = {
|
|
|
1209
1212
|
group_standardAllBits: "group_standardAllBits",
|
|
1210
1213
|
group_standardItemLead: "group_standardItemLead",
|
|
1211
1214
|
group_standardItemLeadInstructionHint: "group_standardItemLeadInstructionHint",
|
|
1215
|
+
group_standardInstructionHint: "group_standardInstructionHint",
|
|
1212
1216
|
group_standardTags: "group_standardTags",
|
|
1217
|
+
group_standardTagsNoItemLead: "group_standardTagsNoItemLead",
|
|
1213
1218
|
group_imageSource: "group_imageSource",
|
|
1214
1219
|
group_technicalTerm: "group_technicalTerm",
|
|
1215
1220
|
group_person: "group_person",
|
|
1216
1221
|
group_gap: "group_gap",
|
|
1217
1222
|
group_trueFalse: "group_trueFalse",
|
|
1223
|
+
group_trueFalseInlineHighlight: "group_trueFalseInlineHighlight",
|
|
1224
|
+
group_trueFalseInlineSelect: "group_trueFalseInlineSelect",
|
|
1225
|
+
group_trueFalseResponses: "group_trueFalseResponses",
|
|
1218
1226
|
group_markConfig: "group_markConfig",
|
|
1219
1227
|
group_mark: "group_mark",
|
|
1220
1228
|
group_bookCommon: "group_bookCommon",
|
|
@@ -1222,14 +1230,18 @@ var groupKeys = {
|
|
|
1222
1230
|
group_advertisingCommon: "group_advertisingCommon",
|
|
1223
1231
|
group_platformStylesCommon: "group_platformStylesCommon",
|
|
1224
1232
|
group_quizCommon: "group_quizCommon",
|
|
1233
|
+
group_backgroundWallpaper: "group_backgroundWallpaper",
|
|
1234
|
+
group_imageNoZoom: "group_imageNoZoom",
|
|
1225
1235
|
group_resourceBitTags: "group_resourceBitTags",
|
|
1226
1236
|
group_resourceCommon: "group_resourceCommon",
|
|
1227
1237
|
group_resourceImageCommon: "group_resourceImageCommon",
|
|
1238
|
+
group_resourceImageCommonNoZoom: "group_resourceImageCommonNoZoom",
|
|
1228
1239
|
group_resourceAudioCommon: "group_resourceAudioCommon",
|
|
1229
1240
|
group_resourceVideoCommon: "group_resourceVideoCommon",
|
|
1230
1241
|
group_resourceIcon: "group_resourceIcon",
|
|
1231
1242
|
// Alias for image
|
|
1232
1243
|
group_resourceImage: "group_resourceImage",
|
|
1244
|
+
group_resourceImageNoZoom: "group_resourceImageNoZoom",
|
|
1233
1245
|
group_resourceImageEmbed: "group_resourceImageEmbed",
|
|
1234
1246
|
group_resourceImageLink: "group_resourceImageLink",
|
|
1235
1247
|
group_resourceImageResponsive: "group_resourceImageResponsive",
|
|
@@ -1506,6 +1518,7 @@ var propertyKeys = {
|
|
|
1506
1518
|
property_src4x: "@src4x",
|
|
1507
1519
|
property_srcAlt: "@srcAlt",
|
|
1508
1520
|
property_stripePricingTableId: "@stripePricingTableId",
|
|
1521
|
+
property_stripePricingTableDescriptiveName: "@stripePricingTableDescriptiveName",
|
|
1509
1522
|
property_stripePublishableKey: "@stripePublishableKey",
|
|
1510
1523
|
property_subject: "@subject",
|
|
1511
1524
|
property_subtype: "@subtype",
|
|
@@ -2257,7 +2270,7 @@ var CARDSETS = {
|
|
|
2257
2270
|
variants: [
|
|
2258
2271
|
{
|
|
2259
2272
|
jsonKey: "question.text",
|
|
2260
|
-
exportJsonKey: { question: { text: "$" } },
|
|
2273
|
+
exportJsonKey: [{ "@absent": { question: {} } }, { question: { text: "$" } }],
|
|
2261
2274
|
tags: [
|
|
2262
2275
|
{
|
|
2263
2276
|
key: ConfigKey.group_standardTags,
|
|
@@ -2273,6 +2286,136 @@ var CARDSETS = {
|
|
|
2273
2286
|
description: "Icon resource for the flashcard.",
|
|
2274
2287
|
jsonKey: "question.icon|resource(type=image, key=image)",
|
|
2275
2288
|
exportJsonKey: { question: { icon: { type: "image", image: { src: "$" } } } }
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
key: ConfigKey.property_example,
|
|
2292
|
+
exportJsonKey: [
|
|
2293
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2294
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2295
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2296
|
+
],
|
|
2297
|
+
description: "Example marker for the flashcard question.",
|
|
2298
|
+
format: TagFormat.bitmarkText,
|
|
2299
|
+
nullable: true
|
|
2300
|
+
}
|
|
2301
|
+
]
|
|
2302
|
+
}
|
|
2303
|
+
]
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
name: "answer",
|
|
2307
|
+
variants: [
|
|
2308
|
+
{
|
|
2309
|
+
jsonKey: "answer.text",
|
|
2310
|
+
exportJsonKey: [{ "@absent": { answer: {} } }, { answer: { text: "$" } }],
|
|
2311
|
+
tags: [
|
|
2312
|
+
{
|
|
2313
|
+
key: ConfigKey.group_standardTags,
|
|
2314
|
+
description: "Standard tags for the flashcard."
|
|
2315
|
+
},
|
|
2316
|
+
{
|
|
2317
|
+
exportJsonKey: { title: "$" },
|
|
2318
|
+
key: ConfigKey.tag_title,
|
|
2319
|
+
description: "Title of the flashcard."
|
|
2320
|
+
},
|
|
2321
|
+
{
|
|
2322
|
+
key: ConfigKey.group_resourceIcon,
|
|
2323
|
+
description: "Icon resource for the flashcard.",
|
|
2324
|
+
jsonKey: "answer.icon|resource(type=image, key=image)",
|
|
2325
|
+
exportJsonKey: { answer: { icon: { type: "image", image: { src: "$" } } } }
|
|
2326
|
+
},
|
|
2327
|
+
{
|
|
2328
|
+
key: ConfigKey.property_example,
|
|
2329
|
+
exportJsonKey: [
|
|
2330
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2331
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2332
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2333
|
+
],
|
|
2334
|
+
description: "Example marker for the flashcard answer.",
|
|
2335
|
+
format: TagFormat.bitmarkText,
|
|
2336
|
+
nullable: true
|
|
2337
|
+
}
|
|
2338
|
+
]
|
|
2339
|
+
},
|
|
2340
|
+
{
|
|
2341
|
+
jsonKey: "alternativeAnswers[].text",
|
|
2342
|
+
exportJsonKey: { alternativeAnswers: [{ text: "$" }] },
|
|
2343
|
+
tags: [
|
|
2344
|
+
{
|
|
2345
|
+
key: ConfigKey.group_standardTags,
|
|
2346
|
+
description: "Standard tags for the flashcard."
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
exportJsonKey: { title: "$" },
|
|
2350
|
+
key: ConfigKey.tag_title,
|
|
2351
|
+
description: "Title of the flashcard."
|
|
2352
|
+
},
|
|
2353
|
+
{
|
|
2354
|
+
key: ConfigKey.group_resourceIcon,
|
|
2355
|
+
description: "Icon resource for the flashcard.",
|
|
2356
|
+
jsonKey: "alternativeAnswers[].icon|resource(type=image, key=image)",
|
|
2357
|
+
exportJsonKey: {
|
|
2358
|
+
alternativeAnswers: [{ icon: { type: "image", image: { src: "$" } } }]
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
],
|
|
2362
|
+
repeatCount: Count.infinity
|
|
2363
|
+
}
|
|
2364
|
+
]
|
|
2365
|
+
}
|
|
2366
|
+
]
|
|
2367
|
+
},
|
|
2368
|
+
//
|
|
2369
|
+
// flashcard1 — single-card variant of flashcard. Same shape, but capped
|
|
2370
|
+
// at one card via `sections.default.maxCount = 1` (PLAN-085). Used by
|
|
2371
|
+
// the `flashcard-1` bit type; the multi-card `flashcard` and
|
|
2372
|
+
// `q-and-a-card` bit types continue to use the unbounded `flashcard`
|
|
2373
|
+
// cardset.
|
|
2374
|
+
//
|
|
2375
|
+
[CardSetConfigKey.flashcard1]: {
|
|
2376
|
+
jsonKey: "cards",
|
|
2377
|
+
exportJsonKey: { cards: "$" },
|
|
2378
|
+
sections: {
|
|
2379
|
+
default: {
|
|
2380
|
+
jsonKey: "cards",
|
|
2381
|
+
exportJsonKey: { cards: "$" },
|
|
2382
|
+
isDefault: true,
|
|
2383
|
+
maxCount: 1
|
|
2384
|
+
}
|
|
2385
|
+
},
|
|
2386
|
+
sides: [
|
|
2387
|
+
{
|
|
2388
|
+
name: "question",
|
|
2389
|
+
variants: [
|
|
2390
|
+
{
|
|
2391
|
+
jsonKey: "question.text",
|
|
2392
|
+
exportJsonKey: [{ "@absent": { question: {} } }, { question: { text: "$" } }],
|
|
2393
|
+
tags: [
|
|
2394
|
+
{
|
|
2395
|
+
key: ConfigKey.group_standardTags,
|
|
2396
|
+
description: "Standard tags for the flashcard."
|
|
2397
|
+
},
|
|
2398
|
+
{
|
|
2399
|
+
exportJsonKey: { title: "$" },
|
|
2400
|
+
key: ConfigKey.tag_title,
|
|
2401
|
+
description: "Title of the flashcard."
|
|
2402
|
+
},
|
|
2403
|
+
{
|
|
2404
|
+
key: ConfigKey.group_resourceIcon,
|
|
2405
|
+
description: "Icon resource for the flashcard.",
|
|
2406
|
+
jsonKey: "question.icon|resource(type=image, key=image)",
|
|
2407
|
+
exportJsonKey: { question: { icon: { type: "image", image: { src: "$" } } } }
|
|
2408
|
+
},
|
|
2409
|
+
{
|
|
2410
|
+
key: ConfigKey.property_example,
|
|
2411
|
+
exportJsonKey: [
|
|
2412
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2413
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2414
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2415
|
+
],
|
|
2416
|
+
description: "Example marker for the flashcard question.",
|
|
2417
|
+
format: TagFormat.bitmarkText,
|
|
2418
|
+
nullable: true
|
|
2276
2419
|
}
|
|
2277
2420
|
]
|
|
2278
2421
|
}
|
|
@@ -2283,7 +2426,7 @@ var CARDSETS = {
|
|
|
2283
2426
|
variants: [
|
|
2284
2427
|
{
|
|
2285
2428
|
jsonKey: "answer.text",
|
|
2286
|
-
exportJsonKey: { answer: { text: "$" } },
|
|
2429
|
+
exportJsonKey: [{ "@absent": { answer: {} } }, { answer: { text: "$" } }],
|
|
2287
2430
|
tags: [
|
|
2288
2431
|
{
|
|
2289
2432
|
key: ConfigKey.group_standardTags,
|
|
@@ -2299,6 +2442,17 @@ var CARDSETS = {
|
|
|
2299
2442
|
description: "Icon resource for the flashcard.",
|
|
2300
2443
|
jsonKey: "answer.icon|resource(type=image, key=image)",
|
|
2301
2444
|
exportJsonKey: { answer: { icon: { type: "image", image: { src: "$" } } } }
|
|
2445
|
+
},
|
|
2446
|
+
{
|
|
2447
|
+
key: ConfigKey.property_example,
|
|
2448
|
+
exportJsonKey: [
|
|
2449
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2450
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2451
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2452
|
+
],
|
|
2453
|
+
description: "Example marker for the flashcard answer.",
|
|
2454
|
+
format: TagFormat.bitmarkText,
|
|
2455
|
+
nullable: true
|
|
2302
2456
|
}
|
|
2303
2457
|
]
|
|
2304
2458
|
},
|
|
@@ -2342,7 +2496,7 @@ var CARDSETS = {
|
|
|
2342
2496
|
variants: [
|
|
2343
2497
|
{
|
|
2344
2498
|
jsonKey: "term.text",
|
|
2345
|
-
exportJsonKey: { term: { text: "$" } },
|
|
2499
|
+
exportJsonKey: [{ "@absent": { term: {} } }, { term: { text: "$" } }],
|
|
2346
2500
|
tags: [
|
|
2347
2501
|
{
|
|
2348
2502
|
key: ConfigKey.group_standardTags,
|
|
@@ -2361,6 +2515,17 @@ var CARDSETS = {
|
|
|
2361
2515
|
format: TagFormat.plainText,
|
|
2362
2516
|
jsonKey: "term.icon|resource(type=image, key=image)",
|
|
2363
2517
|
exportJsonKey: { term: { icon: { type: "image", image: { src: "$" } } } }
|
|
2518
|
+
},
|
|
2519
|
+
{
|
|
2520
|
+
key: ConfigKey.property_example,
|
|
2521
|
+
exportJsonKey: [
|
|
2522
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2523
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2524
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2525
|
+
],
|
|
2526
|
+
description: "Example marker for the definition term.",
|
|
2527
|
+
format: TagFormat.bitmarkText,
|
|
2528
|
+
nullable: true
|
|
2364
2529
|
}
|
|
2365
2530
|
]
|
|
2366
2531
|
}
|
|
@@ -2371,7 +2536,7 @@ var CARDSETS = {
|
|
|
2371
2536
|
variants: [
|
|
2372
2537
|
{
|
|
2373
2538
|
jsonKey: "definition.text",
|
|
2374
|
-
exportJsonKey: { definition: { text: "$" } },
|
|
2539
|
+
exportJsonKey: [{ "@absent": { definition: {} } }, { definition: { text: "$" } }],
|
|
2375
2540
|
tags: [
|
|
2376
2541
|
{
|
|
2377
2542
|
key: ConfigKey.group_standardTags,
|
|
@@ -2389,6 +2554,17 @@ var CARDSETS = {
|
|
|
2389
2554
|
description: "Icon resource for the definition.",
|
|
2390
2555
|
jsonKey: "definition.icon|resource(type=image, key=image)",
|
|
2391
2556
|
exportJsonKey: { definition: { icon: { type: "image", image: { src: "$" } } } }
|
|
2557
|
+
},
|
|
2558
|
+
{
|
|
2559
|
+
key: ConfigKey.property_example,
|
|
2560
|
+
exportJsonKey: [
|
|
2561
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2562
|
+
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2563
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2564
|
+
],
|
|
2565
|
+
description: "Example marker for the definition.",
|
|
2566
|
+
format: TagFormat.bitmarkText,
|
|
2567
|
+
nullable: true
|
|
2392
2568
|
}
|
|
2393
2569
|
]
|
|
2394
2570
|
},
|
|
@@ -2433,11 +2609,51 @@ var CARDSETS = {
|
|
|
2433
2609
|
{
|
|
2434
2610
|
jsonKey: "key",
|
|
2435
2611
|
exportJsonKey: { key: "$" },
|
|
2612
|
+
format: TextFormat2.plainText,
|
|
2436
2613
|
tags: [
|
|
2437
2614
|
{
|
|
2438
2615
|
key: ConfigKey.group_standardTags,
|
|
2439
2616
|
description: "Standard tags for the match pair."
|
|
2440
2617
|
},
|
|
2618
|
+
{
|
|
2619
|
+
// Pair-level example: emit `isExample` alongside `example`
|
|
2620
|
+
// (matches OLD parser's per-pair allow-list behaviour).
|
|
2621
|
+
//
|
|
2622
|
+
// PLAN-074: a valued cascade source (`[@example:V]` anywhere
|
|
2623
|
+
// in the cardset) fills each pair's `example` with `V`
|
|
2624
|
+
// once per pair from the keys-side cascade fire (single
|
|
2625
|
+
// parsed_variant per pair — no per-value duplication).
|
|
2626
|
+
//
|
|
2627
|
+
// PLAN-076 NOTE: matchPairs (TAG 415) KEEPS `example: '$'`
|
|
2628
|
+
// at the pair-object level. BPG `parseMatchPairs`
|
|
2629
|
+
// (`CardContentProcessor.ts:714-723`) emits ONE example
|
|
2630
|
+
// per PAIR (the `exampleCard` accumulator), placed at the
|
|
2631
|
+
// pair object. Unlike matchMatrix (per-cell example),
|
|
2632
|
+
// matchPairs has no nested per-cell layer, so the pair-key
|
|
2633
|
+
// `[@example:V]` must double-emit as the visible field.
|
|
2634
|
+
// Confirmed via `chaining` fixture: `match-solution-grouped`
|
|
2635
|
+
// expects `example: "packen"` at pair-object level from
|
|
2636
|
+
// `die Koffer[%1][@example:packen]`. Original PLAN-076
|
|
2637
|
+
// draft applied to both keys-side tags; the matchPairs
|
|
2638
|
+
// half was reverted after fixture parity testing.
|
|
2639
|
+
key: ConfigKey.property_example,
|
|
2640
|
+
exportJsonKey: [
|
|
2641
|
+
{ "@keyonly": { isExample: true, "@bit": { isExample: true } } },
|
|
2642
|
+
{
|
|
2643
|
+
predicates: ["@absent", { $cascade: "*" }],
|
|
2644
|
+
rule: {
|
|
2645
|
+
isExample: true,
|
|
2646
|
+
example: "$cascade",
|
|
2647
|
+
"@bit": { isExample: true }
|
|
2648
|
+
}
|
|
2649
|
+
},
|
|
2650
|
+
{ "@absent": { isExample: true } },
|
|
2651
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2652
|
+
],
|
|
2653
|
+
description: "Example marker / value on the match pair.",
|
|
2654
|
+
format: TagFormat.bitmarkText,
|
|
2655
|
+
nullable: true
|
|
2656
|
+
},
|
|
2441
2657
|
{
|
|
2442
2658
|
key: ConfigKey.tag_title,
|
|
2443
2659
|
description: "Title of the match pair.",
|
|
@@ -2446,9 +2662,19 @@ var CARDSETS = {
|
|
|
2446
2662
|
exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
|
|
2447
2663
|
},
|
|
2448
2664
|
{
|
|
2665
|
+
// PLAN-084: gate the key-side `@absent → $ancestor` cascade
|
|
2666
|
+
// synth with `@variantLacksTag=isCaseSensitive` so the rule
|
|
2667
|
+
// only fires when NO variant in the active card explicitly
|
|
2668
|
+
// carries `[@isCaseSensitive]`. When a value-side variant
|
|
2669
|
+
// carries the tag (e.g. `[@isCaseSensitive:false]`), the
|
|
2670
|
+
// synth is skipped here; the value-side explicit fire owns
|
|
2671
|
+
// the pair-level emission.
|
|
2449
2672
|
key: ConfigKey.property_isCaseSensitive,
|
|
2450
2673
|
exportJsonKey: [
|
|
2451
|
-
{
|
|
2674
|
+
{
|
|
2675
|
+
predicates: ["@absent", { "@variantLacksTag": "@isCaseSensitive" }],
|
|
2676
|
+
rule: { isCaseSensitive: "$ancestor" }
|
|
2677
|
+
},
|
|
2452
2678
|
{ isCaseSensitive: "$" }
|
|
2453
2679
|
],
|
|
2454
2680
|
description: "Property to indicate if the match is case sensitive.",
|
|
@@ -2477,10 +2703,85 @@ var CARDSETS = {
|
|
|
2477
2703
|
{
|
|
2478
2704
|
jsonKey: "values[]",
|
|
2479
2705
|
exportJsonKey: { values: ["$"] },
|
|
2706
|
+
format: TextFormat2.plainText,
|
|
2480
2707
|
tags: [
|
|
2481
2708
|
{
|
|
2482
|
-
|
|
2483
|
-
|
|
2709
|
+
// PLAN-084: value-side excludes item/lead/pageNumber/marginNumber.
|
|
2710
|
+
// BPG `parseMatchPairs` does `delete tags.item; delete tags.lead;`
|
|
2711
|
+
// for sideIdx > 0; the schema-side equivalent is to use a
|
|
2712
|
+
// group_standardTags variant that omits group_standardItemLead.
|
|
2713
|
+
key: ConfigKey.group_standardTagsNoItemLead,
|
|
2714
|
+
description: "Standard tags for the match pair (values side, no item/lead)."
|
|
2715
|
+
},
|
|
2716
|
+
{
|
|
2717
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.6: cascade-fired
|
|
2718
|
+
// `@example` from the bit header fills each pair's
|
|
2719
|
+
// `example` with the pair's first value (mirrors BPG's
|
|
2720
|
+
// `fillStringExample(pairs, __defaultExample=values[0])`).
|
|
2721
|
+
//
|
|
2722
|
+
// PLAN-074: the cascade-source-VALUE branch is handled by
|
|
2723
|
+
// TAG 415 (keys side) which fires once per pair — keeping
|
|
2724
|
+
// it here would emit `example` twice per pair (one per
|
|
2725
|
+
// values-side parsed_variant) and merge them into a
|
|
2726
|
+
// multi-paragraph array.
|
|
2727
|
+
//
|
|
2728
|
+
// PLAN-075: bare `$parent` reads the parent variant fire's
|
|
2729
|
+
// source `$` value (the current `++`-iteration's value
|
|
2730
|
+
// text). For single-value pairs this matches the old
|
|
2731
|
+
// `$parent.values[0]`; for multi-value pairs with
|
|
2732
|
+
// `[@example]` attached to a non-first value, it correctly
|
|
2733
|
+
// resolves to that value.
|
|
2734
|
+
//
|
|
2735
|
+
// PLAN-077: dual `[@absent, { '$cascade': '*' }]` rule
|
|
2736
|
+
// routes pair-key `[@example:V]` (a per-pair cascade
|
|
2737
|
+
// source, bound via per-card CascadeCounters scope) and
|
|
2738
|
+
// bit-header `[@example:V]` (cardset cascade) into the
|
|
2739
|
+
// pair-level `example` via `$cascade`. The aggregator in
|
|
2740
|
+
// `populate_variants` fires this rule ONCE per pair (BPG
|
|
2741
|
+
// `parseMatchPairs` `exampleCard` precedence), avoiding
|
|
2742
|
+
// per-iter pollution.
|
|
2743
|
+
key: ConfigKey.property_example,
|
|
2744
|
+
exportJsonKey: [
|
|
2745
|
+
// PLAN-084: bare `[@example]` on a values-side variant fires
|
|
2746
|
+
// once per pair (first-wins, mirrors BPG `parseMatchPairs`
|
|
2747
|
+
// `exampleCard` + `pushDownTree` set-if-null semantic).
|
|
2748
|
+
// `maxEmits: 1` enforced inside the per-pair cascade-counter
|
|
2749
|
+
// scope opened by `build_card_item`.
|
|
2750
|
+
{
|
|
2751
|
+
predicates: ["@keyonly"],
|
|
2752
|
+
maxEmits: 1,
|
|
2753
|
+
rule: {
|
|
2754
|
+
isExample: true,
|
|
2755
|
+
example: "$parent",
|
|
2756
|
+
"@bit": { isExample: true }
|
|
2757
|
+
}
|
|
2758
|
+
},
|
|
2759
|
+
{
|
|
2760
|
+
predicates: ["@absent", { $cascade: "*" }],
|
|
2761
|
+
rule: {
|
|
2762
|
+
isExample: true,
|
|
2763
|
+
example: "$cascade",
|
|
2764
|
+
"@bit": { isExample: true }
|
|
2765
|
+
}
|
|
2766
|
+
},
|
|
2767
|
+
{
|
|
2768
|
+
"@absent": {
|
|
2769
|
+
isExample: true,
|
|
2770
|
+
example: "$parent",
|
|
2771
|
+
"@bit": { isExample: true }
|
|
2772
|
+
}
|
|
2773
|
+
},
|
|
2774
|
+
// PLAN-084: same cap applies to the explicit-value `[@example:V]`
|
|
2775
|
+
// form so per-`++`-iter values-side fires also first-win.
|
|
2776
|
+
{
|
|
2777
|
+
predicates: [],
|
|
2778
|
+
maxEmits: 1,
|
|
2779
|
+
rule: { isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2780
|
+
}
|
|
2781
|
+
],
|
|
2782
|
+
description: "Example marker / value on the match pair (values side).",
|
|
2783
|
+
format: TagFormat.bitmarkText,
|
|
2784
|
+
nullable: true
|
|
2484
2785
|
},
|
|
2485
2786
|
{
|
|
2486
2787
|
key: ConfigKey.tag_title,
|
|
@@ -2490,9 +2791,13 @@ var CARDSETS = {
|
|
|
2490
2791
|
exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
|
|
2491
2792
|
},
|
|
2492
2793
|
{
|
|
2794
|
+
// PLAN-084: symmetric @variantLacksTag gating with the key-side.
|
|
2493
2795
|
key: ConfigKey.property_isCaseSensitive,
|
|
2494
2796
|
exportJsonKey: [
|
|
2495
|
-
{
|
|
2797
|
+
{
|
|
2798
|
+
predicates: ["@absent", { "@variantLacksTag": "@isCaseSensitive" }],
|
|
2799
|
+
rule: { isCaseSensitive: "$ancestor" }
|
|
2800
|
+
},
|
|
2496
2801
|
{ isCaseSensitive: "$" }
|
|
2497
2802
|
],
|
|
2498
2803
|
description: "Property to indicate if the match is case sensitive.",
|
|
@@ -2518,6 +2823,7 @@ var CARDSETS = {
|
|
|
2518
2823
|
{
|
|
2519
2824
|
jsonKey: "key",
|
|
2520
2825
|
exportJsonKey: { key: "$" },
|
|
2826
|
+
format: TextFormat2.plainText,
|
|
2521
2827
|
tags: [
|
|
2522
2828
|
{
|
|
2523
2829
|
key: ConfigKey.group_standardTags,
|
|
@@ -2547,10 +2853,12 @@ var CARDSETS = {
|
|
|
2547
2853
|
{
|
|
2548
2854
|
jsonKey: "values[]",
|
|
2549
2855
|
exportJsonKey: { values: ["$"] },
|
|
2856
|
+
format: TextFormat2.plainText,
|
|
2550
2857
|
tags: [
|
|
2551
2858
|
{
|
|
2552
|
-
|
|
2553
|
-
|
|
2859
|
+
// PLAN-084: value-side excludes item/lead/pageNumber/marginNumber.
|
|
2860
|
+
key: ConfigKey.group_standardTagsNoItemLead,
|
|
2861
|
+
description: "Standard tags for the audio match pair (values side, no item/lead)."
|
|
2554
2862
|
},
|
|
2555
2863
|
{
|
|
2556
2864
|
key: ConfigKey.tag_title,
|
|
@@ -2583,6 +2891,7 @@ var CARDSETS = {
|
|
|
2583
2891
|
{
|
|
2584
2892
|
jsonKey: "key",
|
|
2585
2893
|
exportJsonKey: { key: "$" },
|
|
2894
|
+
format: TextFormat2.plainText,
|
|
2586
2895
|
tags: [
|
|
2587
2896
|
{
|
|
2588
2897
|
key: ConfigKey.group_standardTags,
|
|
@@ -2612,10 +2921,12 @@ var CARDSETS = {
|
|
|
2612
2921
|
{
|
|
2613
2922
|
jsonKey: "values[]",
|
|
2614
2923
|
exportJsonKey: { values: ["$"] },
|
|
2924
|
+
format: TextFormat2.plainText,
|
|
2615
2925
|
tags: [
|
|
2616
2926
|
{
|
|
2617
|
-
|
|
2618
|
-
|
|
2927
|
+
// PLAN-084: value-side excludes item/lead/pageNumber/marginNumber.
|
|
2928
|
+
key: ConfigKey.group_standardTagsNoItemLead,
|
|
2929
|
+
description: "Standard tags for the image match pair (values side, no item/lead)."
|
|
2619
2930
|
},
|
|
2620
2931
|
{
|
|
2621
2932
|
key: ConfigKey.tag_title,
|
|
@@ -2648,20 +2959,49 @@ var CARDSETS = {
|
|
|
2648
2959
|
{
|
|
2649
2960
|
jsonKey: "key",
|
|
2650
2961
|
exportJsonKey: { key: "$" },
|
|
2962
|
+
format: TextFormat2.plainText,
|
|
2651
2963
|
tags: [
|
|
2652
2964
|
{
|
|
2653
2965
|
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
2654
2966
|
description: "Standard tags for lead, instruction, and hint."
|
|
2655
2967
|
},
|
|
2656
2968
|
{
|
|
2969
|
+
// PLAN-076: drop `example: '$'` from valued rule — pair-key
|
|
2970
|
+
// `[@example:V]` is consumed as the per-pair cascade source.
|
|
2971
|
+
// PLAN-077 R14 follow-up: investigation showed the fixture
|
|
2972
|
+
// reference is INCONSISTENT — bits without a cardset-level
|
|
2973
|
+
// cascade (e.g. bit 3 `[@example:Y]should be...`) expect
|
|
2974
|
+
// pair-level `example: V` at pair scope, but bits WITH a
|
|
2975
|
+
// cardset cascade (e.g. bit 8 `[@example:99]` in title-row
|
|
2976
|
+
// PLUS pair-key `[@example:Y]`) expect NO pair-level
|
|
2977
|
+
// example. Emitting `example: $` here satisfies bit 3 but
|
|
2978
|
+
// breaks bit 8; dropping it satisfies bit 8 but breaks bit
|
|
2979
|
+
// 3. Conditional emission would require runtime gating on
|
|
2980
|
+
// the cardset cascade scope state. Left dropped pending a
|
|
2981
|
+
// dedicated plan — accepted divergence on bit 3's pair-
|
|
2982
|
+
// level emission (cells still get the per-cell `example`
|
|
2983
|
+
// correctly via PLAN-077 §4.2 + §4.3).
|
|
2657
2984
|
key: ConfigKey.property_example,
|
|
2658
2985
|
exportJsonKey: [
|
|
2659
|
-
{
|
|
2660
|
-
|
|
2661
|
-
|
|
2986
|
+
{
|
|
2987
|
+
"@keyonly": {
|
|
2988
|
+
isExample: true,
|
|
2989
|
+
"@bit": { isExample: true },
|
|
2990
|
+
"@card": { isExample: true }
|
|
2991
|
+
}
|
|
2992
|
+
},
|
|
2993
|
+
{
|
|
2994
|
+
"@absent": {
|
|
2995
|
+
isExample: true,
|
|
2996
|
+
"@bit": { isExample: true },
|
|
2997
|
+
"@card": { isExample: true }
|
|
2998
|
+
}
|
|
2999
|
+
},
|
|
3000
|
+
{ isExample: true, "@bit": { isExample: true }, "@card": { isExample: true } }
|
|
2662
3001
|
],
|
|
2663
3002
|
description: "Example text for the match matrix.",
|
|
2664
|
-
format: TagFormat.plainText
|
|
3003
|
+
format: TagFormat.plainText,
|
|
3004
|
+
nullable: true
|
|
2665
3005
|
},
|
|
2666
3006
|
{
|
|
2667
3007
|
key: ConfigKey.tag_title,
|
|
@@ -2689,35 +3029,96 @@ var CARDSETS = {
|
|
|
2689
3029
|
variants: [
|
|
2690
3030
|
{
|
|
2691
3031
|
jsonKey: "cells[{s}].values[]",
|
|
2692
|
-
exportJsonKey:
|
|
3032
|
+
exportJsonKey: [
|
|
3033
|
+
// PLAN-085 / R14: the positional-blank emission for an
|
|
3034
|
+
// effectively-absent cell side fires ONLY when the active
|
|
3035
|
+
// card has at least one `[#]` variant fire. This matches
|
|
3036
|
+
// BPG `extractHeadingCard`'s `isHeading` gate: when no
|
|
3037
|
+
// `[#]` exists anywhere in the title card, BPG returns
|
|
3038
|
+
// undefined and no `heading` is emitted. The phantom
|
|
3039
|
+
// `forValues:['']` placeholder is appropriate only when
|
|
3040
|
+
// the card is being treated as a title-row.
|
|
3041
|
+
{
|
|
3042
|
+
predicates: ["@absent", { "@variantHasTag": "#" }],
|
|
3043
|
+
rule: { "@bit": { heading: { forValues: [""] } } }
|
|
3044
|
+
},
|
|
3045
|
+
{ cells: { $s: { values: ["$"] } } }
|
|
3046
|
+
],
|
|
3047
|
+
format: TextFormat2.plainText,
|
|
2693
3048
|
tags: [
|
|
2694
3049
|
{
|
|
2695
3050
|
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
2696
3051
|
description: "Standard tags for lead, instruction, and hint."
|
|
2697
3052
|
},
|
|
2698
3053
|
{
|
|
3054
|
+
// PLAN-075: bare `$parent` reads the parent variant fire's
|
|
3055
|
+
// source `$` value (the current `++`-iteration's cell text).
|
|
3056
|
+
// Replaces `$parent.values[0]` which pinned to position 0
|
|
3057
|
+
// regardless of which `++`-value `[@example]` was on.
|
|
3058
|
+
//
|
|
3059
|
+
// PLAN-077: dual `[@absent, { '$cascade': '*' }]` rule
|
|
3060
|
+
// routes pair-key `[@example:V]` (a per-pair cascade
|
|
3061
|
+
// source, bound via per-card CascadeCounters scope) and
|
|
3062
|
+
// bit-header `[@example:V]` (cardset cascade) into the
|
|
3063
|
+
// per-cell `example` via `$cascade`. The aggregator in
|
|
3064
|
+
// `populate_variants` fires this rule ONCE per cell (BPG
|
|
3065
|
+
// `parseMatchMatrix` `exampleSide` precedence), avoiding
|
|
3066
|
+
// per-iter pollution.
|
|
3067
|
+
// @card scope-shift writes matrix-row container isExample.
|
|
2699
3068
|
key: ConfigKey.property_example,
|
|
2700
3069
|
exportJsonKey: [
|
|
2701
3070
|
{
|
|
2702
3071
|
"@keyonly": {
|
|
2703
|
-
cells: { $s: { isExample: true, example: "$parent
|
|
2704
|
-
"@bit": { isExample: true }
|
|
3072
|
+
cells: { $s: { isExample: true, example: "$parent" } },
|
|
3073
|
+
"@bit": { isExample: true },
|
|
3074
|
+
"@card": { isExample: true }
|
|
2705
3075
|
}
|
|
2706
3076
|
},
|
|
2707
3077
|
{
|
|
2708
|
-
"@absent"
|
|
3078
|
+
predicates: ["@absent", { $cascade: "*" }],
|
|
3079
|
+
rule: {
|
|
3080
|
+
cells: { $s: { isExample: true, example: "$cascade" } },
|
|
3081
|
+
"@bit": { isExample: true },
|
|
3082
|
+
"@card": { isExample: true }
|
|
3083
|
+
}
|
|
2709
3084
|
},
|
|
2710
|
-
{
|
|
3085
|
+
{
|
|
3086
|
+
"@absent": {
|
|
3087
|
+
cells: { $s: { isExample: true, example: "$parent" } },
|
|
3088
|
+
"@bit": { isExample: true },
|
|
3089
|
+
"@card": { isExample: true }
|
|
3090
|
+
}
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
cells: { $s: { isExample: true, example: "$" } },
|
|
3094
|
+
"@bit": { isExample: true },
|
|
3095
|
+
"@card": { isExample: true }
|
|
3096
|
+
}
|
|
2711
3097
|
],
|
|
2712
3098
|
description: "Example text for the match matrix.",
|
|
2713
|
-
format: TagFormat.
|
|
3099
|
+
format: TagFormat.bitmarkText,
|
|
3100
|
+
nullable: true
|
|
2714
3101
|
},
|
|
2715
3102
|
{
|
|
3103
|
+
// PLAN-085 / R14: bare `[#]` on a value-side emits the
|
|
3104
|
+
// empty-string positional blank into `forValues` so the
|
|
3105
|
+
// array stays aligned with the cell positions (matches BPG
|
|
3106
|
+
// `extractHeadingCard`'s "all value-side headings present"
|
|
3107
|
+
// shape). The `@keyonly` rule is required for two reasons:
|
|
3108
|
+
// 1) it provides an emission for bare `[#]` (the `$` sigil
|
|
3109
|
+
// in the unconditional rule has no source for bare); and
|
|
3110
|
+
// 2) the presence of any `@keyonly` rule disables the
|
|
3111
|
+
// optimised-mode `should_suppress_outcome` strip (see
|
|
3112
|
+
// `forward_emit.rs`) so the resulting `forValues: [""]`
|
|
3113
|
+
// survives the all-natural-defaults check.
|
|
2716
3114
|
key: ConfigKey.tag_title,
|
|
2717
3115
|
description: "Title of the match matrix.",
|
|
2718
3116
|
format: TagFormat.plainText,
|
|
2719
3117
|
jsonKey: "^heading.forValues",
|
|
2720
|
-
exportJsonKey:
|
|
3118
|
+
exportJsonKey: [
|
|
3119
|
+
{ "@keyonly": { "@bit": { heading: { forValues: [""] } } } },
|
|
3120
|
+
{ "@bit": { heading: { forValues: ["$"] } } }
|
|
3121
|
+
]
|
|
2721
3122
|
},
|
|
2722
3123
|
{
|
|
2723
3124
|
key: ConfigKey.property_isCaseSensitive,
|
|
@@ -2766,6 +3167,35 @@ var CARDSETS = {
|
|
|
2766
3167
|
{
|
|
2767
3168
|
key: ConfigKey.group_standardTags,
|
|
2768
3169
|
description: "Standard tags for the statement."
|
|
3170
|
+
},
|
|
3171
|
+
{
|
|
3172
|
+
// PLAN-072: cascade-fired `@example` from the bit header
|
|
3173
|
+
// fills each statement entry's `example` with the entry's
|
|
3174
|
+
// own `isCorrect`, mirroring BPG's `pushExampleDownTree`
|
|
3175
|
+
// for the statements cardset. Per-array-item strip removes
|
|
3176
|
+
// `example: false` from incorrect entries so only correct
|
|
3177
|
+
// entries retain `example: true`.
|
|
3178
|
+
key: ConfigKey.property_example,
|
|
3179
|
+
exportJsonKey: [
|
|
3180
|
+
{
|
|
3181
|
+
"@keyonly": {
|
|
3182
|
+
isExample: true,
|
|
3183
|
+
example: true,
|
|
3184
|
+
"@bit": { isExample: true }
|
|
3185
|
+
}
|
|
3186
|
+
},
|
|
3187
|
+
{
|
|
3188
|
+
"@absent": {
|
|
3189
|
+
isExample: true,
|
|
3190
|
+
example: "$parent.isCorrect",
|
|
3191
|
+
"@bit": { isExample: true }
|
|
3192
|
+
}
|
|
3193
|
+
},
|
|
3194
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3195
|
+
],
|
|
3196
|
+
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`.",
|
|
3197
|
+
format: TagFormat.boolean,
|
|
3198
|
+
nullable: true
|
|
2769
3199
|
}
|
|
2770
3200
|
],
|
|
2771
3201
|
bodyAllowed: false
|
|
@@ -2794,6 +3224,71 @@ var CARDSETS = {
|
|
|
2794
3224
|
{
|
|
2795
3225
|
key: ConfigKey.group_standardTags,
|
|
2796
3226
|
description: "Standard tags for the quiz."
|
|
3227
|
+
},
|
|
3228
|
+
{
|
|
3229
|
+
// ALIGN-EXAMPLE-CASCADE §3.2: variant-level cascade for
|
|
3230
|
+
// quiz choices is delegated to group_trueFalse's
|
|
3231
|
+
// chain-child `@example` (`+` chain with maxEmits:1 +
|
|
3232
|
+
// `@parent.isCorrect=true`). Variant-level `@absent`
|
|
3233
|
+
// would over-fire on subsequent correct choices and on
|
|
3234
|
+
// incorrect ones — drop it.
|
|
3235
|
+
key: ConfigKey.property_example,
|
|
3236
|
+
exportJsonKey: [
|
|
3237
|
+
{ "@keyonly": { isExample: true, "@bit": { isExample: true } } },
|
|
3238
|
+
{ isExample: true, "@bit": { isExample: true } }
|
|
3239
|
+
],
|
|
3240
|
+
description: "Example marker on the quiz choice (entry-local only; cascade handled by group_trueFalse chain-children).",
|
|
3241
|
+
format: TagFormat.boolean,
|
|
3242
|
+
nullable: true
|
|
3243
|
+
}
|
|
3244
|
+
],
|
|
3245
|
+
bodyAllowed: false
|
|
3246
|
+
}
|
|
3247
|
+
]
|
|
3248
|
+
}
|
|
3249
|
+
]
|
|
3250
|
+
},
|
|
3251
|
+
//
|
|
3252
|
+
// quiz (responses)
|
|
3253
|
+
//
|
|
3254
|
+
[CardSetConfigKey.quizResponses]: {
|
|
3255
|
+
jsonKey: "quizzes",
|
|
3256
|
+
exportJsonKey: { quizzes: "$" },
|
|
3257
|
+
sides: [
|
|
3258
|
+
{
|
|
3259
|
+
name: "responses",
|
|
3260
|
+
variants: [
|
|
3261
|
+
{
|
|
3262
|
+
jsonKey: null,
|
|
3263
|
+
tags: [
|
|
3264
|
+
{
|
|
3265
|
+
key: ConfigKey.group_trueFalseResponses,
|
|
3266
|
+
description: "Group for true/false questions."
|
|
3267
|
+
},
|
|
3268
|
+
{
|
|
3269
|
+
key: ConfigKey.group_standardTags,
|
|
3270
|
+
description: "Standard tags for the quiz."
|
|
3271
|
+
},
|
|
3272
|
+
{
|
|
3273
|
+
// PLAN-072: cascade-fired `@example` from the bit header
|
|
3274
|
+
// fills each response entry's `example` with the entry's
|
|
3275
|
+
// own `isCorrect`, mirroring BPG's `pushExampleDownTree`
|
|
3276
|
+
// for the quiz-responses cardset (statements-style).
|
|
3277
|
+
key: ConfigKey.property_example,
|
|
3278
|
+
exportJsonKey: [
|
|
3279
|
+
{ "@keyonly": { isExample: true, "@bit": { isExample: true } } },
|
|
3280
|
+
{
|
|
3281
|
+
"@absent": {
|
|
3282
|
+
isExample: true,
|
|
3283
|
+
example: "$parent.isCorrect",
|
|
3284
|
+
"@bit": { isExample: true }
|
|
3285
|
+
}
|
|
3286
|
+
},
|
|
3287
|
+
{ isExample: true, "@bit": { isExample: true } }
|
|
3288
|
+
],
|
|
3289
|
+
description: "Example marker on the quiz response; cascade from bit-header fills `example` with the entry\u2019s own `isCorrect`.",
|
|
3290
|
+
format: TagFormat.boolean,
|
|
3291
|
+
nullable: true
|
|
2797
3292
|
}
|
|
2798
3293
|
],
|
|
2799
3294
|
bodyAllowed: false
|
|
@@ -2819,6 +3314,73 @@ var CARDSETS = {
|
|
|
2819
3314
|
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
2820
3315
|
description: "Standard tags for lead, instruction, and hint."
|
|
2821
3316
|
},
|
|
3317
|
+
{
|
|
3318
|
+
// Feedback choices: `[+]` / `[-]` map to choice + `requireReason`
|
|
3319
|
+
// (NOT `isCorrect` like trueFalse). Shadow the inherited
|
|
3320
|
+
// `tag_true` / `tag_false` from `group_trueFalse` to emit the
|
|
3321
|
+
// feedback-specific shape.
|
|
3322
|
+
//
|
|
3323
|
+
// Chain @example: `[+ X][@example]` writes
|
|
3324
|
+
// `isExample/example` onto the X choice only. BPG's
|
|
3325
|
+
// `setIsExampleFlags` (Builder.ts:4041-4172) does NOT
|
|
3326
|
+
// iterate `cardNode.feedbacks` — so unlike multipleChoice,
|
|
3327
|
+
// there is no bubble to bit-level or feedbacks-level
|
|
3328
|
+
// isExample. Pattern omits `@bit` scope-shift accordingly.
|
|
3329
|
+
// No `@absent`/`@parent.isCorrect` cascade rules either:
|
|
3330
|
+
// BPG's `pushExampleDownTree` (Builder.ts:3777-3849) has
|
|
3331
|
+
// no feedback dispatch, so bit-header `[@example]` does
|
|
3332
|
+
// not flow into feedback choices.
|
|
3333
|
+
key: ConfigKey.tag_true,
|
|
3334
|
+
exportJsonKey: { choices: [{ choice: "$", requireReason: true }] },
|
|
3335
|
+
description: "Reason-required choice for feedback (`[+]`).",
|
|
3336
|
+
maxCount: Count.infinity,
|
|
3337
|
+
format: TagFormat.plainText,
|
|
3338
|
+
chain: [
|
|
3339
|
+
{
|
|
3340
|
+
key: ConfigKey.property_example,
|
|
3341
|
+
exportJsonKey: [
|
|
3342
|
+
{ "@keyonly": { isExample: true, example: true } },
|
|
3343
|
+
{ isExample: true, example: "$" }
|
|
3344
|
+
],
|
|
3345
|
+
description: "Per-choice example marker for feedback `[+]`.",
|
|
3346
|
+
format: TagFormat.boolean,
|
|
3347
|
+
maxCount: 1,
|
|
3348
|
+
nullable: true
|
|
3349
|
+
},
|
|
3350
|
+
{
|
|
3351
|
+
// `[+ X][! foo]` chains `!` (instruction) onto the
|
|
3352
|
+
// choice; same for `[?]` (hint), `[%]` (item),
|
|
3353
|
+
// `[%2]`/`[%3]`/`[%4]` (lead/pageNumber/marginNumber).
|
|
3354
|
+
// Mirrors group_trueFalse's `+` chain shape.
|
|
3355
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
3356
|
+
description: "Item, lead, page number, margin number, instruction and hint chained onto the feedback choice."
|
|
3357
|
+
}
|
|
3358
|
+
]
|
|
3359
|
+
},
|
|
3360
|
+
{
|
|
3361
|
+
key: ConfigKey.tag_false,
|
|
3362
|
+
exportJsonKey: { choices: [{ choice: "$", requireReason: false }] },
|
|
3363
|
+
description: "Reason-not-required choice for feedback (`[-]`).",
|
|
3364
|
+
maxCount: Count.infinity,
|
|
3365
|
+
format: TagFormat.plainText,
|
|
3366
|
+
chain: [
|
|
3367
|
+
{
|
|
3368
|
+
key: ConfigKey.property_example,
|
|
3369
|
+
exportJsonKey: [
|
|
3370
|
+
{ "@keyonly": { isExample: true, example: true } },
|
|
3371
|
+
{ isExample: true, example: "$" }
|
|
3372
|
+
],
|
|
3373
|
+
description: "Per-choice example marker for feedback `[-]`.",
|
|
3374
|
+
format: TagFormat.boolean,
|
|
3375
|
+
maxCount: 1,
|
|
3376
|
+
nullable: true
|
|
3377
|
+
},
|
|
3378
|
+
{
|
|
3379
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
3380
|
+
description: "Item, lead, page number, margin number, instruction and hint chained onto the feedback choice."
|
|
3381
|
+
}
|
|
3382
|
+
]
|
|
3383
|
+
},
|
|
2822
3384
|
{
|
|
2823
3385
|
key: ConfigKey.group_trueFalse,
|
|
2824
3386
|
description: "Group for true/false feedback."
|
|
@@ -2839,31 +3401,71 @@ var CARDSETS = {
|
|
|
2839
3401
|
name: "reason",
|
|
2840
3402
|
variants: [
|
|
2841
3403
|
{
|
|
3404
|
+
// PLAN: feedback.reason — Object-only variant pattern. Per
|
|
3405
|
+
// SYNTAX.md §8.1, sibling tag emissions do NOT auto-wrap
|
|
3406
|
+
// under `reason.*`; each tag here spells out the full path.
|
|
3407
|
+
// Body is a plain string (BPG `parseFeedback` uses
|
|
3408
|
+
// `cardBodyStr ?? ''` for `reason.text`).
|
|
2842
3409
|
jsonKey: "reason.text",
|
|
2843
3410
|
exportJsonKey: { reason: { text: "$" } },
|
|
3411
|
+
format: TextFormat2.plainText,
|
|
2844
3412
|
tags: [
|
|
2845
3413
|
{
|
|
2846
|
-
|
|
2847
|
-
|
|
3414
|
+
// Instruction lands under reason. Hint/item/lead/etc.
|
|
3415
|
+
// omitted: not exercised by any fixture and BPG's
|
|
3416
|
+
// `parseFeedback` spreads only the tags actually present
|
|
3417
|
+
// — adding the rest can be done lazily as fixtures
|
|
3418
|
+
// require them, with the same `{reason: {…}}` wrapper.
|
|
3419
|
+
key: ConfigKey.tag_instruction,
|
|
3420
|
+
exportJsonKey: { reason: { instruction: "$" } },
|
|
3421
|
+
description: "Instruction for the feedback reason.",
|
|
3422
|
+
format: TagFormat.bitmarkText
|
|
2848
3423
|
},
|
|
2849
3424
|
{
|
|
2850
3425
|
key: ConfigKey.property_reasonableNumOfChars,
|
|
2851
3426
|
exportJsonKey: [
|
|
2852
|
-
{ "@absent": { reasonableNumOfChars: "$ancestor" } },
|
|
2853
|
-
{ reasonableNumOfChars: "$" }
|
|
3427
|
+
{ "@absent": { reason: { reasonableNumOfChars: "$ancestor" } } },
|
|
3428
|
+
{ reason: { reasonableNumOfChars: "$" } }
|
|
2854
3429
|
],
|
|
2855
3430
|
description: "Property for reasonable number of characters.",
|
|
2856
3431
|
format: TagFormat.number
|
|
2857
3432
|
},
|
|
2858
3433
|
{
|
|
3434
|
+
// ALIGN-EXAMPLE-CASCADE §3.9: `feedback.reason` is NOT in
|
|
3435
|
+
// BPG's `pushExampleDownTree` dispatch — no bit-header
|
|
3436
|
+
// cascade. Local emission only.
|
|
3437
|
+
//
|
|
3438
|
+
// Both `reason.example` and `feedbacks[].example` are
|
|
3439
|
+
// `TextAst` per BPG's schema — paragraph arrays. Format
|
|
3440
|
+
// here is `bitmarkText` so `$` coerces to a paragraph
|
|
3441
|
+
// array at both write sites.
|
|
2859
3442
|
key: ConfigKey.property_example,
|
|
2860
3443
|
exportJsonKey: [
|
|
2861
|
-
{
|
|
2862
|
-
|
|
2863
|
-
|
|
3444
|
+
{
|
|
3445
|
+
// Bare `[@example]`: reason.example is TextAst — BPG
|
|
3446
|
+
// coerces the boolean default to a paragraph
|
|
3447
|
+
// containing the string "true". feedbacks[].example
|
|
3448
|
+
// is not TextAst, stays a boolean. Two literal writes.
|
|
3449
|
+
"@keyonly": {
|
|
3450
|
+
reason: {
|
|
3451
|
+
isExample: true,
|
|
3452
|
+
example: [{ type: "paragraph", content: [{ text: "true", type: "text" }] }]
|
|
3453
|
+
},
|
|
3454
|
+
isExample: true,
|
|
3455
|
+
example: true,
|
|
3456
|
+
"@bit": { isExample: true }
|
|
3457
|
+
}
|
|
3458
|
+
},
|
|
3459
|
+
{
|
|
3460
|
+
reason: { isExample: true, example: "$" },
|
|
3461
|
+
isExample: true,
|
|
3462
|
+
example: "$",
|
|
3463
|
+
"@bit": { isExample: true }
|
|
3464
|
+
}
|
|
2864
3465
|
],
|
|
2865
|
-
description: "Example text for the feedback.",
|
|
2866
|
-
format: TagFormat.
|
|
3466
|
+
description: "Example text for the feedback reason (entry-local only; no bit-header cascade).",
|
|
3467
|
+
format: TagFormat.bitmarkText,
|
|
3468
|
+
nullable: true
|
|
2867
3469
|
},
|
|
2868
3470
|
{
|
|
2869
3471
|
key: ConfigKey.tag_title,
|
|
@@ -2927,6 +3529,22 @@ var CARDSETS = {
|
|
|
2927
3529
|
{
|
|
2928
3530
|
key: ConfigKey.group_standardTags,
|
|
2929
3531
|
description: "Standard tags for the question."
|
|
3532
|
+
},
|
|
3533
|
+
{
|
|
3534
|
+
// ALIGN-EXAMPLE-CASCADE §3.10: `questions` is NOT in BPG's
|
|
3535
|
+
// `pushExampleDownTree` dispatch — bit-header `[@example]`
|
|
3536
|
+
// does not propagate `example`/`isExample` onto question
|
|
3537
|
+
// entries. Only entry-local `[@example]` fires (handled by
|
|
3538
|
+
// `@keyonly` and the unconditional fallback). No `@absent`
|
|
3539
|
+
// rule.
|
|
3540
|
+
key: ConfigKey.property_example,
|
|
3541
|
+
exportJsonKey: [
|
|
3542
|
+
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
3543
|
+
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3544
|
+
],
|
|
3545
|
+
description: "Example marker for the question (entry-local only; no bit-header cascade).",
|
|
3546
|
+
format: TagFormat.bitmarkText,
|
|
3547
|
+
nullable: true
|
|
2930
3548
|
}
|
|
2931
3549
|
]
|
|
2932
3550
|
}
|
|
@@ -2953,14 +3571,16 @@ var CARDSETS = {
|
|
|
2953
3571
|
description: "Standard tags for lead, instruction, and hint."
|
|
2954
3572
|
},
|
|
2955
3573
|
{
|
|
3574
|
+
// ALIGN-EXAMPLE-CASCADE §3.11: `elements` is NOT in BPG's
|
|
3575
|
+
// `pushExampleDownTree` dispatch — no bit-header cascade.
|
|
2956
3576
|
key: ConfigKey.property_example,
|
|
2957
3577
|
exportJsonKey: [
|
|
2958
3578
|
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2959
|
-
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
2960
3579
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
2961
3580
|
],
|
|
2962
|
-
description: "Example text for the element.",
|
|
2963
|
-
format: TagFormat.plainText
|
|
3581
|
+
description: "Example text for the element (entry-local only; no bit-header cascade).",
|
|
3582
|
+
format: TagFormat.plainText,
|
|
3583
|
+
nullable: true
|
|
2964
3584
|
}
|
|
2965
3585
|
],
|
|
2966
3586
|
repeatCount: Count.infinity
|
|
@@ -2972,9 +3592,57 @@ var CARDSETS = {
|
|
|
2972
3592
|
//
|
|
2973
3593
|
// table
|
|
2974
3594
|
//
|
|
3595
|
+
// PLAN-079: supports BOTH source formats and collapses to the same basic
|
|
3596
|
+
// output (`{ columns?, data, columnWidths? }`):
|
|
3597
|
+
//
|
|
3598
|
+
// 1. Basic format — first card carries `[#X]` markers (fire `tag_title`
|
|
3599
|
+
// → `^table.columns[]`); subsequent cards are body rows. Cards have
|
|
3600
|
+
// no qualifier, so they route to the `table-body` (default) section.
|
|
3601
|
+
//
|
|
3602
|
+
// 2. Extended format — `==== table-header ====` / `==== table-footer ====`
|
|
3603
|
+
// qualifiers. The `table-header` section uses `@cardIndex=0` to route
|
|
3604
|
+
// the first header card's cells to `columns` and demote remaining
|
|
3605
|
+
// header cards (rows) into `data`. Per-cell `[@tableRowSpan]` /
|
|
3606
|
+
// `[@tableScope]` / `[@tableCellType]` tags are valid-but-unmapped
|
|
3607
|
+
// here (no per-cell metadata in basic shape) — declared on the cell
|
|
3608
|
+
// variant below.
|
|
3609
|
+
//
|
|
2975
3610
|
[CardSetConfigKey.table]: {
|
|
2976
|
-
jsonKey:
|
|
2977
|
-
exportJsonKey:
|
|
3611
|
+
jsonKey: null,
|
|
3612
|
+
exportJsonKey: null,
|
|
3613
|
+
sections: {
|
|
3614
|
+
"table-header": {
|
|
3615
|
+
// First header card's row of cells → `columns`. Subsequent header
|
|
3616
|
+
// cards' rows → `data` (per-card append; `[$]` shape because
|
|
3617
|
+
// per-card emission fires once per card, multiple fires deep_merge-
|
|
3618
|
+
// append). PLAN-079 + PLAN-080: predicates inside exportJsonKey
|
|
3619
|
+
// both ROUTE cards to this section (when no explicit `==== table-
|
|
3620
|
+
// header ====` qualifier) and SELECT the rule body once routed.
|
|
3621
|
+
// First rule = first card with any `[#]` → `columns`; second rule
|
|
3622
|
+
// = subsequent cards in this section → `data` (per-row append).
|
|
3623
|
+
jsonKey: "table.columns",
|
|
3624
|
+
exportJsonKey: [
|
|
3625
|
+
{
|
|
3626
|
+
predicates: [{ "@cardIndex": 0 }, { "@variantHasTag": "#" }],
|
|
3627
|
+
rule: { "@bit": { table: { columns: "$" } } }
|
|
3628
|
+
},
|
|
3629
|
+
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3630
|
+
{ "@bit": { table: { data: ["$"] } } }
|
|
3631
|
+
]
|
|
3632
|
+
},
|
|
3633
|
+
"table-body": {
|
|
3634
|
+
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3635
|
+
// This is the default section (no qualifier → cards land here).
|
|
3636
|
+
jsonKey: "table.data",
|
|
3637
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3638
|
+
isDefault: true
|
|
3639
|
+
},
|
|
3640
|
+
"table-footer": {
|
|
3641
|
+
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3642
|
+
jsonKey: "table.data",
|
|
3643
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3644
|
+
}
|
|
3645
|
+
},
|
|
2978
3646
|
sides: [
|
|
2979
3647
|
{
|
|
2980
3648
|
name: "cell",
|
|
@@ -3015,6 +3683,8 @@ var CARDSETS = {
|
|
|
3015
3683
|
},
|
|
3016
3684
|
{
|
|
3017
3685
|
key: ConfigKey.property_tableColWidth,
|
|
3686
|
+
jsonKey: "^table.columnWidths[{s}]",
|
|
3687
|
+
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
3018
3688
|
description: "Width for the column.",
|
|
3019
3689
|
format: TagFormat.number
|
|
3020
3690
|
}
|
|
@@ -3033,7 +3703,22 @@ var CARDSETS = {
|
|
|
3033
3703
|
sections: {
|
|
3034
3704
|
"table-header": {
|
|
3035
3705
|
jsonKey: "table.header.rows",
|
|
3036
|
-
|
|
3706
|
+
// PLAN-080: section dispatch via predicates inside exportJsonKey.
|
|
3707
|
+
// Cards with no explicit `==== table-header ====` qualifier
|
|
3708
|
+
// route here if FIRST CARD contains any `[#]` tag in any
|
|
3709
|
+
// variant. Explicit-qualifier cards fall through to the
|
|
3710
|
+
// unconditional fallback rule. Both rules use the per-card
|
|
3711
|
+
// append shape `rows: ['$']` — the runtime triggers per-card
|
|
3712
|
+
// emission whenever the pattern carries predicates, and each
|
|
3713
|
+
// fire appends a single-element array (multi-fire deep-merge
|
|
3714
|
+
// concatenates).
|
|
3715
|
+
exportJsonKey: [
|
|
3716
|
+
{
|
|
3717
|
+
predicates: [{ "@cardIndex": 0 }, { "@variantHasTag": "#" }],
|
|
3718
|
+
rule: { table: { header: { rows: ["$"] } } }
|
|
3719
|
+
},
|
|
3720
|
+
{ table: { header: { rows: ["$"] } } }
|
|
3721
|
+
],
|
|
3037
3722
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3038
3723
|
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3039
3724
|
},
|
|
@@ -3066,13 +3751,13 @@ var CARDSETS = {
|
|
|
3066
3751
|
},
|
|
3067
3752
|
{
|
|
3068
3753
|
key: ConfigKey.tag_title,
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
},
|
|
3075
|
-
description: "Title of the table cell."
|
|
3754
|
+
// PLAN-080: the `[#]` tag writes its text to the cell's
|
|
3755
|
+
// `content` field. When the card is in the `table-header`
|
|
3756
|
+
// section, the section's sideExportJsonKey wraps each
|
|
3757
|
+
// cell with `title: true` automatically.
|
|
3758
|
+
jsonKey: "content",
|
|
3759
|
+
exportJsonKey: { content: "$" },
|
|
3760
|
+
description: "Title text of the table cell (header rows)."
|
|
3076
3761
|
},
|
|
3077
3762
|
{
|
|
3078
3763
|
key: ConfigKey.property_tableCellType,
|
|
@@ -3104,6 +3789,9 @@ var CARDSETS = {
|
|
|
3104
3789
|
},
|
|
3105
3790
|
{
|
|
3106
3791
|
key: ConfigKey.property_tableColWidth,
|
|
3792
|
+
// PLAN-080: write to the cell's `colwidth` field.
|
|
3793
|
+
jsonKey: "colwidth",
|
|
3794
|
+
exportJsonKey: { colwidth: "$" },
|
|
3107
3795
|
description: "Width for the column.",
|
|
3108
3796
|
format: TagFormat.number
|
|
3109
3797
|
}
|
|
@@ -3141,7 +3829,8 @@ var CARDSETS = {
|
|
|
3141
3829
|
{
|
|
3142
3830
|
key: ConfigKey.resource_audio,
|
|
3143
3831
|
description: "Audio resource for the pronunciation table.",
|
|
3144
|
-
jsonKey: "audio"
|
|
3832
|
+
jsonKey: "audio",
|
|
3833
|
+
exportJsonKey: { audio: { type: "audio", audio: { src: "$" } } }
|
|
3145
3834
|
}
|
|
3146
3835
|
],
|
|
3147
3836
|
repeatCount: Count.infinity
|
|
@@ -3212,14 +3901,17 @@ var CARDSETS = {
|
|
|
3212
3901
|
format: TagFormat.plainText
|
|
3213
3902
|
},
|
|
3214
3903
|
{
|
|
3904
|
+
// ALIGN-EXAMPLE-CASCADE §3.12: `bot-action-responses` is
|
|
3905
|
+
// NOT in BPG's `pushExampleDownTree` dispatch — no bit-
|
|
3906
|
+
// header cascade.
|
|
3215
3907
|
key: ConfigKey.property_example,
|
|
3216
3908
|
exportJsonKey: [
|
|
3217
3909
|
{ "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
3218
|
-
{ "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
|
|
3219
3910
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3220
3911
|
],
|
|
3221
|
-
description: "Example text for the bot action response.",
|
|
3222
|
-
format: TagFormat.plainText
|
|
3912
|
+
description: "Example text for the bot action response (entry-local only; no bit-header cascade).",
|
|
3913
|
+
format: TagFormat.plainText,
|
|
3914
|
+
nullable: true
|
|
3223
3915
|
}
|
|
3224
3916
|
]
|
|
3225
3917
|
}
|
|
@@ -3285,6 +3977,38 @@ var CARDSETS = {
|
|
|
3285
3977
|
]
|
|
3286
3978
|
},
|
|
3287
3979
|
//
|
|
3980
|
+
// page-footer-sections — mirrors example-bit-list but emits cards under
|
|
3981
|
+
// `sections` instead of `listItems`. BPG's JsonGenerator special-cases
|
|
3982
|
+
// BitType.pageFooter in code; this dedicated cardSet expresses the same
|
|
3983
|
+
// routing as pure config so the Rust serializer can pick it up.
|
|
3984
|
+
//
|
|
3985
|
+
[CardSetConfigKey.pageFooterSections]: {
|
|
3986
|
+
jsonKey: "sections",
|
|
3987
|
+
exportJsonKey: { sections: "$" },
|
|
3988
|
+
sides: [
|
|
3989
|
+
{
|
|
3990
|
+
name: "item",
|
|
3991
|
+
variants: [
|
|
3992
|
+
{
|
|
3993
|
+
jsonKey: "body",
|
|
3994
|
+
exportJsonKey: { body: "$" },
|
|
3995
|
+
tags: [
|
|
3996
|
+
{
|
|
3997
|
+
key: ConfigKey.group_standardTags,
|
|
3998
|
+
description: "Standard tags for page-footer section bits."
|
|
3999
|
+
},
|
|
4000
|
+
{
|
|
4001
|
+
exportJsonKey: { title: "$" },
|
|
4002
|
+
key: ConfigKey.tag_title,
|
|
4003
|
+
description: "Title of the page-footer section."
|
|
4004
|
+
}
|
|
4005
|
+
]
|
|
4006
|
+
}
|
|
4007
|
+
]
|
|
4008
|
+
}
|
|
4009
|
+
]
|
|
4010
|
+
},
|
|
4011
|
+
//
|
|
3288
4012
|
// ingredients
|
|
3289
4013
|
//
|
|
3290
4014
|
[CardSetConfigKey.ingredients]: {
|
|
@@ -3615,7 +4339,11 @@ var GROUPS = {
|
|
|
3615
4339
|
{
|
|
3616
4340
|
key: ConfigKey.property_groupTag,
|
|
3617
4341
|
jsonKey: "groupTag.name",
|
|
3618
|
-
|
|
4342
|
+
// PLAN-063: starter-array shape with `@id` declares entity-merge
|
|
4343
|
+
// semantics — repeated `[@groupTag: name]` occurrences with the
|
|
4344
|
+
// same value fold into one entry; chained `@tag` children's
|
|
4345
|
+
// arrays merge as sets.
|
|
4346
|
+
exportJsonKey: { groupTag: [{ "@id": "name", name: "$" }] },
|
|
3619
4347
|
description: "The group tag(s) for the bit",
|
|
3620
4348
|
format: TagFormat.plainText,
|
|
3621
4349
|
maxCount: Count.infinity,
|
|
@@ -3788,6 +4516,24 @@ var GROUPS = {
|
|
|
3788
4516
|
}
|
|
3789
4517
|
]
|
|
3790
4518
|
},
|
|
4519
|
+
[ConfigKey.group_standardInstructionHint]: {
|
|
4520
|
+
type: GroupConfigType.standard,
|
|
4521
|
+
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).",
|
|
4522
|
+
tags: [
|
|
4523
|
+
{
|
|
4524
|
+
exportJsonKey: { instruction: "$" },
|
|
4525
|
+
key: ConfigKey.tag_instruction,
|
|
4526
|
+
name: "Instruction",
|
|
4527
|
+
description: "The instruction for the bit"
|
|
4528
|
+
},
|
|
4529
|
+
{
|
|
4530
|
+
exportJsonKey: { hint: "$" },
|
|
4531
|
+
key: ConfigKey.tag_hint,
|
|
4532
|
+
name: "Hint",
|
|
4533
|
+
description: "The hint for the bit"
|
|
4534
|
+
}
|
|
4535
|
+
]
|
|
4536
|
+
},
|
|
3791
4537
|
[ConfigKey.group_standardTags]: {
|
|
3792
4538
|
type: GroupConfigType.standard,
|
|
3793
4539
|
description: "Standard tags which apply to MOST (but not all) bits",
|
|
@@ -3801,17 +4547,45 @@ var GROUPS = {
|
|
|
3801
4547
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
3802
4548
|
},
|
|
3803
4549
|
{
|
|
3804
|
-
// Bit-level example tag
|
|
3805
|
-
//
|
|
3806
|
-
//
|
|
4550
|
+
// Bit-level example tag (default — non-`isTopLevelExample` bits):
|
|
4551
|
+
// - bare `[@example]`: consume only (records cascade marker, emits
|
|
4552
|
+
// nothing at bit-level — OLD parser scrubs bit-level isExample
|
|
4553
|
+
// for bits NOT in its `isTopLevelExample` allow-list).
|
|
4554
|
+
// - synthesized (descendant cascade): still emits `isExample: true`
|
|
4555
|
+
// at the descendant scope.
|
|
4556
|
+
// - valued `[@example:text]`: emit the example value only; bit-level
|
|
4557
|
+
// `isExample` is left to bubble from descendants.
|
|
4558
|
+
// Bits in the OLD parser's allow-list (flashcard, definitionList,
|
|
4559
|
+
// sequence, multipleChoice, trueFalse, cloze*, mark, interview,
|
|
4560
|
+
// matchMatrix, match, essay, etc.) override this entry with the
|
|
4561
|
+
// legacy emit-isExample shape.
|
|
3807
4562
|
key: ConfigKey.property_example,
|
|
3808
|
-
exportJsonKey: [
|
|
3809
|
-
{ "@keyonly": { isExample: true } },
|
|
3810
|
-
{ "@absent": { isExample: true } },
|
|
3811
|
-
{ isExample: true, example: "$" }
|
|
3812
|
-
],
|
|
4563
|
+
exportJsonKey: [{ "@keyonly": {} }, { "@absent": { isExample: true } }, { example: "$" }],
|
|
3813
4564
|
description: "The example(s) for the bit",
|
|
3814
|
-
format: TagFormat.bitmarkText
|
|
4565
|
+
format: TagFormat.bitmarkText,
|
|
4566
|
+
nullable: true
|
|
4567
|
+
}
|
|
4568
|
+
]
|
|
4569
|
+
},
|
|
4570
|
+
[ConfigKey.group_standardTagsNoItemLead]: {
|
|
4571
|
+
type: GroupConfigType.standard,
|
|
4572
|
+
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).",
|
|
4573
|
+
tags: [
|
|
4574
|
+
{
|
|
4575
|
+
key: ConfigKey.group_standardAllBits,
|
|
4576
|
+
description: "All standard tags which apply to all bits"
|
|
4577
|
+
},
|
|
4578
|
+
{
|
|
4579
|
+
key: ConfigKey.group_standardInstructionHint,
|
|
4580
|
+
description: "Instruction and hint tags only (no item/lead chain)."
|
|
4581
|
+
},
|
|
4582
|
+
{
|
|
4583
|
+
// Mirror of group_standardTags property_example entry.
|
|
4584
|
+
key: ConfigKey.property_example,
|
|
4585
|
+
exportJsonKey: [{ "@keyonly": {} }, { "@absent": { isExample: true } }, { example: "$" }],
|
|
4586
|
+
description: "The example(s) for the bit",
|
|
4587
|
+
format: TagFormat.bitmarkText,
|
|
4588
|
+
nullable: true
|
|
3815
4589
|
}
|
|
3816
4590
|
]
|
|
3817
4591
|
},
|
|
@@ -3876,8 +4650,8 @@ var GROUPS = {
|
|
|
3876
4650
|
tags: [
|
|
3877
4651
|
{
|
|
3878
4652
|
key: ConfigKey.property_person,
|
|
3879
|
-
jsonKey: "
|
|
3880
|
-
exportJsonKey: {
|
|
4653
|
+
jsonKey: "person.name",
|
|
4654
|
+
exportJsonKey: { person: { name: "$" } },
|
|
3881
4655
|
description: "A person",
|
|
3882
4656
|
format: TagFormat.plainText,
|
|
3883
4657
|
chain: [
|
|
@@ -3897,8 +4671,8 @@ var GROUPS = {
|
|
|
3897
4671
|
{
|
|
3898
4672
|
// Deprecated (parter renamed to person)
|
|
3899
4673
|
key: ConfigKey.property_partner,
|
|
3900
|
-
jsonKey: "
|
|
3901
|
-
exportJsonKey: {
|
|
4674
|
+
jsonKey: "person.name",
|
|
4675
|
+
exportJsonKey: { person: { name: "$" } },
|
|
3902
4676
|
description: "A partner",
|
|
3903
4677
|
format: TagFormat.plainText,
|
|
3904
4678
|
chain: [
|
|
@@ -3922,7 +4696,9 @@ var GROUPS = {
|
|
|
3922
4696
|
description: "Gap chain",
|
|
3923
4697
|
tags: [
|
|
3924
4698
|
{
|
|
3925
|
-
exportJsonKey: {
|
|
4699
|
+
exportJsonKey: {
|
|
4700
|
+
"@body-inline": { type: "gap", attrs: { solutions: ["$"] } }
|
|
4701
|
+
},
|
|
3926
4702
|
key: ConfigKey.tag_gap,
|
|
3927
4703
|
description: "The value of a gap in the content",
|
|
3928
4704
|
maxCount: Count.infinity,
|
|
@@ -3941,27 +4717,37 @@ var GROUPS = {
|
|
|
3941
4717
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
3942
4718
|
},
|
|
3943
4719
|
{
|
|
4720
|
+
// BPG ExampleTagContentProcessor.ts:91-95 reads
|
|
4721
|
+
// `__solutionsAst[length - 1]` — the solution closest to the
|
|
4722
|
+
// `[@example]` tag at parse time. Our chain accumulator is built
|
|
4723
|
+
// incrementally (scope.rs `parent.merge` after each tag), so at
|
|
4724
|
+
// the moment `[@example]` fires, `solutions` only contains the
|
|
4725
|
+
// preceding `[_x]` entries — `[-1]` resolves to the closest one.
|
|
4726
|
+
// E.g. `[_cloze][_gap][@example]` → solutions=["cloze","gap"],
|
|
4727
|
+
// `[-1]`="gap"; `[_solution][@example][_problem]` →
|
|
4728
|
+
// solutions=["solution"], `[-1]`="solution".
|
|
3944
4729
|
key: ConfigKey.property_example,
|
|
3945
4730
|
jsonKey: "example",
|
|
3946
4731
|
exportJsonKey: [
|
|
3947
4732
|
{
|
|
3948
4733
|
"@keyonly": {
|
|
3949
4734
|
isExample: true,
|
|
3950
|
-
example: "$parent.solutions[
|
|
4735
|
+
example: "$parent.solutions[-1]",
|
|
3951
4736
|
"@bit": { isExample: true }
|
|
3952
4737
|
}
|
|
3953
4738
|
},
|
|
3954
4739
|
{
|
|
3955
4740
|
"@absent": {
|
|
3956
4741
|
isExample: true,
|
|
3957
|
-
example: "$parent.solutions[
|
|
4742
|
+
example: "$parent.solutions[-1]",
|
|
3958
4743
|
"@bit": { isExample: true }
|
|
3959
4744
|
}
|
|
3960
4745
|
},
|
|
3961
4746
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
3962
4747
|
],
|
|
3963
4748
|
description: "An example for the gap",
|
|
3964
|
-
format: TagFormat.bitmarkText
|
|
4749
|
+
format: TagFormat.bitmarkText,
|
|
4750
|
+
nullable: true
|
|
3965
4751
|
},
|
|
3966
4752
|
{
|
|
3967
4753
|
key: ConfigKey.property_isCaseSensitive,
|
|
@@ -4010,6 +4796,24 @@ var GROUPS = {
|
|
|
4010
4796
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
4011
4797
|
},
|
|
4012
4798
|
{
|
|
4799
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.2: cascade-fired
|
|
4800
|
+
// `@example` from the bit header marks EVERY choice with
|
|
4801
|
+
// `isExample: true` (matches BPG output), but only the
|
|
4802
|
+
// FIRST correct choice gets `example: true` (BPG
|
|
4803
|
+
// `fillBooleanExample(..., firstCorrectOnly=true)`).
|
|
4804
|
+
//
|
|
4805
|
+
// Two `@absent` rules, picked first-match-wins:
|
|
4806
|
+
// 1. Verbose form gated on `@parent.isCorrect=true` with
|
|
4807
|
+
// `maxEmits:1` — fires once for the first correct.
|
|
4808
|
+
// 2. Plain `@absent` — fires on every remaining entry
|
|
4809
|
+
// (subsequent corrects and all incorrects), emitting
|
|
4810
|
+
// `isExample` only.
|
|
4811
|
+
// The `serialize_cards` cascade-counter scope holds the cap
|
|
4812
|
+
// across the whole cardset.
|
|
4813
|
+
// @card scope-shift writes choice-container isExample (e.g.
|
|
4814
|
+
// `quizzes[i].isExample`) — was previously provided by the
|
|
4815
|
+
// universal `bubble_is_example` post-walk, which was removed
|
|
4816
|
+
// in favour of explicit per-tag config. SYNTAX.md §8.
|
|
4013
4817
|
key: ConfigKey.property_example,
|
|
4014
4818
|
jsonKey: "example",
|
|
4015
4819
|
exportJsonKey: [
|
|
@@ -4017,20 +4821,37 @@ var GROUPS = {
|
|
|
4017
4821
|
"@keyonly": {
|
|
4018
4822
|
isExample: true,
|
|
4019
4823
|
example: "$parent.isCorrect",
|
|
4020
|
-
"@bit": { isExample: true }
|
|
4824
|
+
"@bit": { isExample: true },
|
|
4825
|
+
"@card": { isExample: true }
|
|
4826
|
+
}
|
|
4827
|
+
},
|
|
4828
|
+
{
|
|
4829
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
4830
|
+
maxEmits: 1,
|
|
4831
|
+
rule: {
|
|
4832
|
+
isExample: true,
|
|
4833
|
+
example: true,
|
|
4834
|
+
"@bit": { isExample: true },
|
|
4835
|
+
"@card": { isExample: true }
|
|
4021
4836
|
}
|
|
4022
4837
|
},
|
|
4023
4838
|
{
|
|
4024
4839
|
"@absent": {
|
|
4025
4840
|
isExample: true,
|
|
4026
|
-
|
|
4027
|
-
"@
|
|
4841
|
+
"@bit": { isExample: true },
|
|
4842
|
+
"@card": { isExample: true }
|
|
4028
4843
|
}
|
|
4029
4844
|
},
|
|
4030
|
-
{
|
|
4845
|
+
{
|
|
4846
|
+
isExample: true,
|
|
4847
|
+
example: "$",
|
|
4848
|
+
"@bit": { isExample: true },
|
|
4849
|
+
"@card": { isExample: true }
|
|
4850
|
+
}
|
|
4031
4851
|
],
|
|
4032
4852
|
description: "An example for the true/false statement/question",
|
|
4033
|
-
format: TagFormat.
|
|
4853
|
+
format: TagFormat.boolean,
|
|
4854
|
+
nullable: true
|
|
4034
4855
|
}
|
|
4035
4856
|
]
|
|
4036
4857
|
},
|
|
@@ -4062,6 +4883,12 @@ var GROUPS = {
|
|
|
4062
4883
|
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
4063
4884
|
},
|
|
4064
4885
|
{
|
|
4886
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.2: cascade-fired
|
|
4887
|
+
// `@example` on a `-` (incorrect choice) emits
|
|
4888
|
+
// `isExample: true` only — no `example` (BPG fixtures show
|
|
4889
|
+
// `isExample` on every choice, but `example` only on the
|
|
4890
|
+
// first correct via firstCorrectOnly cascade).
|
|
4891
|
+
// @card scope-shift writes choice-container isExample.
|
|
4065
4892
|
key: ConfigKey.property_example,
|
|
4066
4893
|
jsonKey: "example",
|
|
4067
4894
|
exportJsonKey: [
|
|
@@ -4069,20 +4896,460 @@ var GROUPS = {
|
|
|
4069
4896
|
"@keyonly": {
|
|
4070
4897
|
isExample: true,
|
|
4071
4898
|
example: "$parent.isCorrect",
|
|
4072
|
-
"@bit": { isExample: true }
|
|
4899
|
+
"@bit": { isExample: true },
|
|
4900
|
+
"@card": { isExample: true }
|
|
4073
4901
|
}
|
|
4074
4902
|
},
|
|
4075
4903
|
{
|
|
4076
4904
|
"@absent": {
|
|
4905
|
+
isExample: true,
|
|
4906
|
+
"@bit": { isExample: true },
|
|
4907
|
+
"@card": { isExample: true }
|
|
4908
|
+
}
|
|
4909
|
+
},
|
|
4910
|
+
{
|
|
4911
|
+
isExample: true,
|
|
4912
|
+
example: "$",
|
|
4913
|
+
"@bit": { isExample: true },
|
|
4914
|
+
"@card": { isExample: true }
|
|
4915
|
+
}
|
|
4916
|
+
],
|
|
4917
|
+
description: "An example for the true/false statement/question (incorrect entry \u2014 isExample only on cascade)",
|
|
4918
|
+
format: TagFormat.boolean,
|
|
4919
|
+
nullable: true
|
|
4920
|
+
}
|
|
4921
|
+
]
|
|
4922
|
+
}
|
|
4923
|
+
]
|
|
4924
|
+
},
|
|
4925
|
+
[ConfigKey.group_trueFalseResponses]: {
|
|
4926
|
+
type: GroupConfigType.standard,
|
|
4927
|
+
description: "True/False Responses chain",
|
|
4928
|
+
tags: [
|
|
4929
|
+
{
|
|
4930
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: true }] },
|
|
4931
|
+
key: ConfigKey.tag_true,
|
|
4932
|
+
description: "True value for a true/false statement/question",
|
|
4933
|
+
maxCount: Count.infinity,
|
|
4934
|
+
format: TagFormat.plainText,
|
|
4935
|
+
chain: [
|
|
4936
|
+
{
|
|
4937
|
+
key: ConfigKey.tag_true,
|
|
4938
|
+
jsonKey: "responses[]|set(isCorrect=true)",
|
|
4939
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: true }] },
|
|
4940
|
+
description: "True values for a true/false statement/question",
|
|
4941
|
+
maxCount: Count.infinity,
|
|
4942
|
+
format: TagFormat.plainText
|
|
4943
|
+
},
|
|
4944
|
+
{
|
|
4945
|
+
key: ConfigKey.tag_false,
|
|
4946
|
+
jsonKey: "responses[]|set(isCorrect=false)",
|
|
4947
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: false }] },
|
|
4948
|
+
description: "False values for a true/false statement/question",
|
|
4949
|
+
maxCount: Count.infinity,
|
|
4950
|
+
format: TagFormat.plainText
|
|
4951
|
+
},
|
|
4952
|
+
{
|
|
4953
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
4954
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
4955
|
+
},
|
|
4956
|
+
{
|
|
4957
|
+
// @card scope-shift writes response-container isExample.
|
|
4958
|
+
key: ConfigKey.property_example,
|
|
4959
|
+
jsonKey: "example",
|
|
4960
|
+
exportJsonKey: [
|
|
4961
|
+
{
|
|
4962
|
+
"@keyonly": {
|
|
4077
4963
|
isExample: true,
|
|
4078
4964
|
example: "$parent.isCorrect",
|
|
4079
|
-
"@bit": { isExample: true }
|
|
4965
|
+
"@bit": { isExample: true },
|
|
4966
|
+
"@card": { isExample: true }
|
|
4080
4967
|
}
|
|
4081
4968
|
},
|
|
4082
|
-
{
|
|
4969
|
+
{
|
|
4970
|
+
"@absent": {
|
|
4971
|
+
isExample: "$parent.isCorrect",
|
|
4972
|
+
example: "$parent.isCorrect",
|
|
4973
|
+
"@bit": { isExample: "$parent.isCorrect" },
|
|
4974
|
+
"@card": { isExample: "$parent.isCorrect" }
|
|
4975
|
+
}
|
|
4976
|
+
},
|
|
4977
|
+
{
|
|
4978
|
+
isExample: true,
|
|
4979
|
+
example: "$",
|
|
4980
|
+
"@bit": { isExample: true },
|
|
4981
|
+
"@card": { isExample: true }
|
|
4982
|
+
}
|
|
4083
4983
|
],
|
|
4084
4984
|
description: "An example for the true/false statement/question",
|
|
4085
|
-
format: TagFormat.
|
|
4985
|
+
format: TagFormat.boolean,
|
|
4986
|
+
nullable: true
|
|
4987
|
+
}
|
|
4988
|
+
]
|
|
4989
|
+
},
|
|
4990
|
+
{
|
|
4991
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: false }] },
|
|
4992
|
+
key: ConfigKey.tag_false,
|
|
4993
|
+
description: "False value for a true/false statement/question",
|
|
4994
|
+
maxCount: Count.infinity,
|
|
4995
|
+
format: TagFormat.plainText,
|
|
4996
|
+
chain: [
|
|
4997
|
+
{
|
|
4998
|
+
key: ConfigKey.tag_true,
|
|
4999
|
+
jsonKey: "responses[]|set(isCorrect=true)",
|
|
5000
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: true }] },
|
|
5001
|
+
description: "True values for a true/false statement/question",
|
|
5002
|
+
maxCount: Count.infinity,
|
|
5003
|
+
format: TagFormat.plainText
|
|
5004
|
+
},
|
|
5005
|
+
{
|
|
5006
|
+
key: ConfigKey.tag_false,
|
|
5007
|
+
jsonKey: "responses[]|set(isCorrect=false)",
|
|
5008
|
+
exportJsonKey: { responses: [{ response: "$", isCorrect: false }] },
|
|
5009
|
+
description: "False values for a true/false statement/question",
|
|
5010
|
+
maxCount: Count.infinity,
|
|
5011
|
+
format: TagFormat.plainText
|
|
5012
|
+
},
|
|
5013
|
+
{
|
|
5014
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5015
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5016
|
+
},
|
|
5017
|
+
{
|
|
5018
|
+
// @card scope-shift writes response-container isExample.
|
|
5019
|
+
key: ConfigKey.property_example,
|
|
5020
|
+
jsonKey: "example",
|
|
5021
|
+
exportJsonKey: [
|
|
5022
|
+
{
|
|
5023
|
+
"@keyonly": {
|
|
5024
|
+
isExample: true,
|
|
5025
|
+
example: "$parent.isCorrect",
|
|
5026
|
+
"@bit": { isExample: true },
|
|
5027
|
+
"@card": { isExample: true }
|
|
5028
|
+
}
|
|
5029
|
+
},
|
|
5030
|
+
{
|
|
5031
|
+
"@absent": {
|
|
5032
|
+
isExample: true,
|
|
5033
|
+
example: "$parent.isCorrect",
|
|
5034
|
+
"@bit": { isExample: true },
|
|
5035
|
+
"@card": { isExample: true }
|
|
5036
|
+
}
|
|
5037
|
+
},
|
|
5038
|
+
{
|
|
5039
|
+
isExample: true,
|
|
5040
|
+
example: "$",
|
|
5041
|
+
"@bit": { isExample: true },
|
|
5042
|
+
"@card": { isExample: true }
|
|
5043
|
+
}
|
|
5044
|
+
],
|
|
5045
|
+
description: "An example for the true/false statement/question",
|
|
5046
|
+
format: TagFormat.boolean,
|
|
5047
|
+
nullable: true
|
|
5048
|
+
}
|
|
5049
|
+
]
|
|
5050
|
+
}
|
|
5051
|
+
]
|
|
5052
|
+
},
|
|
5053
|
+
[ConfigKey.group_trueFalseInlineSelect]: {
|
|
5054
|
+
type: GroupConfigType.standard,
|
|
5055
|
+
description: "True/False chain composed inline (select body-bit). +/- tags are consume-only at bit level.",
|
|
5056
|
+
tags: [
|
|
5057
|
+
{
|
|
5058
|
+
exportJsonKey: {
|
|
5059
|
+
"@body-inline": {
|
|
5060
|
+
type: "select",
|
|
5061
|
+
attrs: { options: [{ text: "$", isCorrect: true }] }
|
|
5062
|
+
}
|
|
5063
|
+
},
|
|
5064
|
+
key: ConfigKey.tag_true,
|
|
5065
|
+
description: "True value for an inline select body bit",
|
|
5066
|
+
maxCount: Count.infinity,
|
|
5067
|
+
format: TagFormat.plainText,
|
|
5068
|
+
chain: [
|
|
5069
|
+
{
|
|
5070
|
+
key: ConfigKey.tag_true,
|
|
5071
|
+
exportJsonKey: {},
|
|
5072
|
+
description: "True values for an inline select body bit",
|
|
5073
|
+
maxCount: Count.infinity,
|
|
5074
|
+
format: TagFormat.plainText
|
|
5075
|
+
},
|
|
5076
|
+
{
|
|
5077
|
+
key: ConfigKey.tag_false,
|
|
5078
|
+
exportJsonKey: {},
|
|
5079
|
+
description: "False values for an inline select body bit",
|
|
5080
|
+
maxCount: Count.infinity,
|
|
5081
|
+
format: TagFormat.plainText
|
|
5082
|
+
},
|
|
5083
|
+
{
|
|
5084
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5085
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5086
|
+
},
|
|
5087
|
+
{
|
|
5088
|
+
// PLAN-083: cascade-fired `@example` from bit header fires
|
|
5089
|
+
// `isExample:true, example:true` on the FIRST CORRECT option
|
|
5090
|
+
// only (BPG `fillBooleanExample(select.options,
|
|
5091
|
+
// firstCorrectOnly=true)`). Mirrors group_trueFalseInlineHighlight.
|
|
5092
|
+
// Every rule also bubbles `@bit:{isExample:true}` (idempotent
|
|
5093
|
+
// OR — any cascade ⇒ bit marked) and
|
|
5094
|
+
// `@body-inline:{attrs:{isExample:true}}` (node-level marker
|
|
5095
|
+
// on the select node).
|
|
5096
|
+
key: ConfigKey.property_example,
|
|
5097
|
+
jsonKey: "example",
|
|
5098
|
+
exportJsonKey: [
|
|
5099
|
+
{
|
|
5100
|
+
"@keyonly": {
|
|
5101
|
+
isExample: true,
|
|
5102
|
+
example: "$parent.isCorrect",
|
|
5103
|
+
"@bit": { isExample: true },
|
|
5104
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5105
|
+
}
|
|
5106
|
+
},
|
|
5107
|
+
{
|
|
5108
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5109
|
+
maxEmits: 1,
|
|
5110
|
+
rule: {
|
|
5111
|
+
isExample: true,
|
|
5112
|
+
example: true,
|
|
5113
|
+
"@bit": { isExample: true },
|
|
5114
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5115
|
+
}
|
|
5116
|
+
},
|
|
5117
|
+
{
|
|
5118
|
+
isExample: true,
|
|
5119
|
+
example: "$",
|
|
5120
|
+
"@bit": { isExample: true },
|
|
5121
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5122
|
+
}
|
|
5123
|
+
],
|
|
5124
|
+
description: "An example for the inline select option (first correct only)",
|
|
5125
|
+
format: TagFormat.boolean,
|
|
5126
|
+
nullable: true
|
|
5127
|
+
}
|
|
5128
|
+
]
|
|
5129
|
+
},
|
|
5130
|
+
{
|
|
5131
|
+
exportJsonKey: {
|
|
5132
|
+
"@body-inline": {
|
|
5133
|
+
type: "select",
|
|
5134
|
+
attrs: { options: [{ text: "$", isCorrect: false }] }
|
|
5135
|
+
}
|
|
5136
|
+
},
|
|
5137
|
+
key: ConfigKey.tag_false,
|
|
5138
|
+
description: "False value for an inline select body bit",
|
|
5139
|
+
maxCount: Count.infinity,
|
|
5140
|
+
format: TagFormat.plainText,
|
|
5141
|
+
chain: [
|
|
5142
|
+
{
|
|
5143
|
+
key: ConfigKey.tag_true,
|
|
5144
|
+
exportJsonKey: {},
|
|
5145
|
+
description: "True values for an inline select body bit",
|
|
5146
|
+
maxCount: Count.infinity,
|
|
5147
|
+
format: TagFormat.plainText
|
|
5148
|
+
},
|
|
5149
|
+
{
|
|
5150
|
+
key: ConfigKey.tag_false,
|
|
5151
|
+
exportJsonKey: {},
|
|
5152
|
+
description: "False values for an inline select body bit",
|
|
5153
|
+
maxCount: Count.infinity,
|
|
5154
|
+
format: TagFormat.plainText
|
|
5155
|
+
},
|
|
5156
|
+
{
|
|
5157
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5158
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5159
|
+
},
|
|
5160
|
+
{
|
|
5161
|
+
// PLAN-083: identical to the `+` lead's chain @example —
|
|
5162
|
+
// cascade reaches the first correct option regardless of
|
|
5163
|
+
// which lead (+/-) opens the chain. Every firing rule bubbles
|
|
5164
|
+
// `@bit:{isExample:true}` and `@body-inline:{attrs:{isExample:true}}`.
|
|
5165
|
+
key: ConfigKey.property_example,
|
|
5166
|
+
jsonKey: "example",
|
|
5167
|
+
exportJsonKey: [
|
|
5168
|
+
{
|
|
5169
|
+
"@keyonly": {
|
|
5170
|
+
isExample: true,
|
|
5171
|
+
example: "$parent.isCorrect",
|
|
5172
|
+
"@bit": { isExample: true },
|
|
5173
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5174
|
+
}
|
|
5175
|
+
},
|
|
5176
|
+
{
|
|
5177
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5178
|
+
maxEmits: 1,
|
|
5179
|
+
rule: {
|
|
5180
|
+
isExample: true,
|
|
5181
|
+
example: true,
|
|
5182
|
+
"@bit": { isExample: true },
|
|
5183
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5184
|
+
}
|
|
5185
|
+
},
|
|
5186
|
+
{
|
|
5187
|
+
isExample: true,
|
|
5188
|
+
example: "$",
|
|
5189
|
+
"@bit": { isExample: true },
|
|
5190
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5191
|
+
}
|
|
5192
|
+
],
|
|
5193
|
+
description: "An example for the inline select option (first correct only)",
|
|
5194
|
+
format: TagFormat.boolean,
|
|
5195
|
+
nullable: true
|
|
5196
|
+
}
|
|
5197
|
+
]
|
|
5198
|
+
}
|
|
5199
|
+
]
|
|
5200
|
+
},
|
|
5201
|
+
[ConfigKey.group_trueFalseInlineHighlight]: {
|
|
5202
|
+
type: GroupConfigType.standard,
|
|
5203
|
+
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.',
|
|
5204
|
+
tags: [
|
|
5205
|
+
{
|
|
5206
|
+
exportJsonKey: {
|
|
5207
|
+
"@body-inline": {
|
|
5208
|
+
type: "highlight",
|
|
5209
|
+
attrs: { texts: [{ text: "$", isCorrect: true }] }
|
|
5210
|
+
}
|
|
5211
|
+
},
|
|
5212
|
+
key: ConfigKey.tag_true,
|
|
5213
|
+
description: "Highlighted span in the body (correct)",
|
|
5214
|
+
maxCount: Count.infinity,
|
|
5215
|
+
format: TagFormat.plainText,
|
|
5216
|
+
chain: [
|
|
5217
|
+
{
|
|
5218
|
+
key: ConfigKey.tag_true,
|
|
5219
|
+
exportJsonKey: {},
|
|
5220
|
+
description: "Highlighted span values (correct)",
|
|
5221
|
+
maxCount: Count.infinity,
|
|
5222
|
+
format: TagFormat.plainText
|
|
5223
|
+
},
|
|
5224
|
+
{
|
|
5225
|
+
key: ConfigKey.tag_false,
|
|
5226
|
+
exportJsonKey: {},
|
|
5227
|
+
description: "Highlighted span values (incorrect)",
|
|
5228
|
+
maxCount: Count.infinity,
|
|
5229
|
+
format: TagFormat.plainText
|
|
5230
|
+
},
|
|
5231
|
+
{
|
|
5232
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5233
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5234
|
+
},
|
|
5235
|
+
{
|
|
5236
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.13: cascade-fired
|
|
5237
|
+
// `@example` from the bit header fires `example: true` +
|
|
5238
|
+
// `isExample: true` on the FIRST correct highlight only
|
|
5239
|
+
// (BPG `fillBooleanExample(highlight.texts,
|
|
5240
|
+
// firstCorrectOnly=true)`). Incorrect highlights get
|
|
5241
|
+
// nothing (unlike choices, the highlight-text fixture
|
|
5242
|
+
// shows no `isExample` on incorrect entries).
|
|
5243
|
+
key: ConfigKey.property_example,
|
|
5244
|
+
jsonKey: "example",
|
|
5245
|
+
exportJsonKey: [
|
|
5246
|
+
{
|
|
5247
|
+
"@keyonly": {
|
|
5248
|
+
isExample: true,
|
|
5249
|
+
example: "$parent.isCorrect",
|
|
5250
|
+
"@bit": { isExample: true },
|
|
5251
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5252
|
+
}
|
|
5253
|
+
},
|
|
5254
|
+
{
|
|
5255
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5256
|
+
maxEmits: 1,
|
|
5257
|
+
rule: {
|
|
5258
|
+
isExample: true,
|
|
5259
|
+
example: true,
|
|
5260
|
+
"@bit": { isExample: true },
|
|
5261
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5262
|
+
}
|
|
5263
|
+
},
|
|
5264
|
+
{
|
|
5265
|
+
isExample: true,
|
|
5266
|
+
example: "$",
|
|
5267
|
+
"@bit": { isExample: true },
|
|
5268
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5269
|
+
}
|
|
5270
|
+
],
|
|
5271
|
+
description: "An example for the highlighted span (first correct only)",
|
|
5272
|
+
format: TagFormat.boolean,
|
|
5273
|
+
nullable: true
|
|
5274
|
+
}
|
|
5275
|
+
]
|
|
5276
|
+
},
|
|
5277
|
+
{
|
|
5278
|
+
// PLAN-083 follow-up (2026-05-22): mirror the select `-` lead shape
|
|
5279
|
+
// by writing `isCorrect: false`. Without it, `$parent.isCorrect` in
|
|
5280
|
+
// chain-child @example rules resolves to ParentPathMissing for `-`
|
|
5281
|
+
// entries (e.g. `[-fish][@example]`), so the @keyonly rule falls
|
|
5282
|
+
// through and nothing fires. The natural-default strip removes
|
|
5283
|
+
// `isCorrect: false` from the final texts entries (matches fixture).
|
|
5284
|
+
exportJsonKey: {
|
|
5285
|
+
"@body-inline": {
|
|
5286
|
+
type: "highlight",
|
|
5287
|
+
attrs: { texts: [{ text: "$", isCorrect: false }] }
|
|
5288
|
+
}
|
|
5289
|
+
},
|
|
5290
|
+
key: ConfigKey.tag_false,
|
|
5291
|
+
description: "Highlighted span in the body (incorrect)",
|
|
5292
|
+
maxCount: Count.infinity,
|
|
5293
|
+
format: TagFormat.plainText,
|
|
5294
|
+
chain: [
|
|
5295
|
+
{
|
|
5296
|
+
key: ConfigKey.tag_true,
|
|
5297
|
+
exportJsonKey: {},
|
|
5298
|
+
description: "Highlighted span values (correct)",
|
|
5299
|
+
maxCount: Count.infinity,
|
|
5300
|
+
format: TagFormat.plainText
|
|
5301
|
+
},
|
|
5302
|
+
{
|
|
5303
|
+
key: ConfigKey.tag_false,
|
|
5304
|
+
exportJsonKey: {},
|
|
5305
|
+
description: "Highlighted span values (incorrect)",
|
|
5306
|
+
maxCount: Count.infinity,
|
|
5307
|
+
format: TagFormat.plainText
|
|
5308
|
+
},
|
|
5309
|
+
{
|
|
5310
|
+
key: ConfigKey.group_standardItemLeadInstructionHint,
|
|
5311
|
+
description: "Item, lead, page number, margin number, instruction and hint tags"
|
|
5312
|
+
},
|
|
5313
|
+
{
|
|
5314
|
+
// PLAN-072 + ALIGN-EXAMPLE-CASCADE §3.13: cascade-fired
|
|
5315
|
+
// `@example` on a `-` (incorrect highlight) emits nothing
|
|
5316
|
+
// (highlight-text fixture has no `isExample` on incorrect
|
|
5317
|
+
// entries; firstCorrectOnly cascade skips them entirely).
|
|
5318
|
+
// No `@absent` rule.
|
|
5319
|
+
// PLAN-083: identical to the `+` lead's chain @example —
|
|
5320
|
+
// cascade reaches the first correct option regardless of
|
|
5321
|
+
// which lead (+/-) opens the chain.
|
|
5322
|
+
key: ConfigKey.property_example,
|
|
5323
|
+
jsonKey: "example",
|
|
5324
|
+
exportJsonKey: [
|
|
5325
|
+
{
|
|
5326
|
+
"@keyonly": {
|
|
5327
|
+
isExample: true,
|
|
5328
|
+
example: "$parent.isCorrect",
|
|
5329
|
+
"@bit": { isExample: true },
|
|
5330
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5331
|
+
}
|
|
5332
|
+
},
|
|
5333
|
+
{
|
|
5334
|
+
predicates: ["@absent", { "@parent.isCorrect": true }],
|
|
5335
|
+
maxEmits: 1,
|
|
5336
|
+
rule: {
|
|
5337
|
+
isExample: true,
|
|
5338
|
+
example: true,
|
|
5339
|
+
"@bit": { isExample: true },
|
|
5340
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5341
|
+
}
|
|
5342
|
+
},
|
|
5343
|
+
{
|
|
5344
|
+
isExample: true,
|
|
5345
|
+
example: "$",
|
|
5346
|
+
"@bit": { isExample: true },
|
|
5347
|
+
"@body-inline": { attrs: { isExample: true } }
|
|
5348
|
+
}
|
|
5349
|
+
],
|
|
5350
|
+
description: "An example for the highlighted span (first correct only)",
|
|
5351
|
+
format: TagFormat.boolean,
|
|
5352
|
+
nullable: true
|
|
4086
5353
|
}
|
|
4087
5354
|
]
|
|
4088
5355
|
}
|
|
@@ -4095,7 +5362,7 @@ var GROUPS = {
|
|
|
4095
5362
|
{
|
|
4096
5363
|
key: ConfigKey.property_mark,
|
|
4097
5364
|
jsonKey: "marks.mark",
|
|
4098
|
-
exportJsonKey: { marks: { mark:
|
|
5365
|
+
exportJsonKey: { marks: [{ mark: "$" }] },
|
|
4099
5366
|
description: "The mark configuration",
|
|
4100
5367
|
format: TagFormat.plainText,
|
|
4101
5368
|
maxCount: Count.infinity,
|
|
@@ -4119,7 +5386,9 @@ var GROUPS = {
|
|
|
4119
5386
|
description: "Mark chain",
|
|
4120
5387
|
tags: [
|
|
4121
5388
|
{
|
|
4122
|
-
exportJsonKey: {
|
|
5389
|
+
exportJsonKey: {
|
|
5390
|
+
"@body-inline": { type: "mark", attrs: { solution: "$" } }
|
|
5391
|
+
},
|
|
4123
5392
|
key: ConfigKey.tag_mark,
|
|
4124
5393
|
description: "The marked content",
|
|
4125
5394
|
maxCount: Count.infinity,
|
|
@@ -4128,6 +5397,7 @@ var GROUPS = {
|
|
|
4128
5397
|
{
|
|
4129
5398
|
key: ConfigKey.property_mark,
|
|
4130
5399
|
jsonKey: "mark",
|
|
5400
|
+
exportJsonKey: { mark: "$" },
|
|
4131
5401
|
description: "The mark configuration",
|
|
4132
5402
|
format: TagFormat.plainText
|
|
4133
5403
|
},
|
|
@@ -4140,7 +5410,8 @@ var GROUPS = {
|
|
|
4140
5410
|
{ isExample: true, example: "$", "@bit": { isExample: true } }
|
|
4141
5411
|
],
|
|
4142
5412
|
description: "An example for the marked content",
|
|
4143
|
-
format: TagFormat.bitmarkText
|
|
5413
|
+
format: TagFormat.bitmarkText,
|
|
5414
|
+
nullable: true
|
|
4144
5415
|
}
|
|
4145
5416
|
]
|
|
4146
5417
|
}
|
|
@@ -4569,6 +5840,42 @@ var GROUPS = {
|
|
|
4569
5840
|
}
|
|
4570
5841
|
]
|
|
4571
5842
|
},
|
|
5843
|
+
[ConfigKey.group_backgroundWallpaper]: {
|
|
5844
|
+
type: GroupConfigType.standard,
|
|
5845
|
+
description: "Background wallpaper tags",
|
|
5846
|
+
tags: [
|
|
5847
|
+
{
|
|
5848
|
+
key: ConfigKey.resource_backgroundWallpaper,
|
|
5849
|
+
exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
|
|
5850
|
+
description: "Background wallpaper for the image, used to set a background for the image",
|
|
5851
|
+
chain: [
|
|
5852
|
+
{
|
|
5853
|
+
key: ConfigKey.group_resourceImageCommon,
|
|
5854
|
+
description: "Common resource image tags for images"
|
|
5855
|
+
}
|
|
5856
|
+
]
|
|
5857
|
+
}
|
|
5858
|
+
]
|
|
5859
|
+
},
|
|
5860
|
+
[ConfigKey.group_imageNoZoom]: {
|
|
5861
|
+
type: GroupConfigType.standard,
|
|
5862
|
+
description: "Image bit tags",
|
|
5863
|
+
tags: [
|
|
5864
|
+
{
|
|
5865
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
5866
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
5867
|
+
},
|
|
5868
|
+
{
|
|
5869
|
+
key: ConfigKey.group_resourceBitTags,
|
|
5870
|
+
description: "Resource bit tags for images, used to define additional properties for images"
|
|
5871
|
+
},
|
|
5872
|
+
{
|
|
5873
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
5874
|
+
description: "Resource image tags for images, used to attach images to the bit",
|
|
5875
|
+
minCount: 1
|
|
5876
|
+
}
|
|
5877
|
+
]
|
|
5878
|
+
},
|
|
4572
5879
|
//
|
|
4573
5880
|
// Resource groups
|
|
4574
5881
|
//
|
|
@@ -4688,6 +5995,58 @@ var GROUPS = {
|
|
|
4688
5995
|
}
|
|
4689
5996
|
]
|
|
4690
5997
|
},
|
|
5998
|
+
[ConfigKey.group_resourceImageCommonNoZoom]: {
|
|
5999
|
+
type: GroupConfigType.standard,
|
|
6000
|
+
description: "Common properties for image resources where @zoomDisabled defaults to true",
|
|
6001
|
+
tags: [
|
|
6002
|
+
{
|
|
6003
|
+
key: ConfigKey.group_resourceCommon,
|
|
6004
|
+
description: "Common resource properties"
|
|
6005
|
+
},
|
|
6006
|
+
{
|
|
6007
|
+
key: ConfigKey.property_src1x,
|
|
6008
|
+
description: "The source URL for the image at 1x resolution",
|
|
6009
|
+
format: TagFormat.plainText
|
|
6010
|
+
},
|
|
6011
|
+
{
|
|
6012
|
+
key: ConfigKey.property_src2x,
|
|
6013
|
+
description: "The source URL for the image at 2x resolution",
|
|
6014
|
+
format: TagFormat.plainText
|
|
6015
|
+
},
|
|
6016
|
+
{
|
|
6017
|
+
key: ConfigKey.property_src3x,
|
|
6018
|
+
description: "The source URL for the image at 3x resolution",
|
|
6019
|
+
format: TagFormat.plainText
|
|
6020
|
+
},
|
|
6021
|
+
{
|
|
6022
|
+
key: ConfigKey.property_src4x,
|
|
6023
|
+
description: "The source URL for the image at 4x resolution",
|
|
6024
|
+
format: TagFormat.plainText
|
|
6025
|
+
},
|
|
6026
|
+
{
|
|
6027
|
+
key: ConfigKey.property_width,
|
|
6028
|
+
description: "The width of the image",
|
|
6029
|
+
format: TagFormat.number
|
|
6030
|
+
},
|
|
6031
|
+
{
|
|
6032
|
+
key: ConfigKey.property_height,
|
|
6033
|
+
description: "The height of the image",
|
|
6034
|
+
format: TagFormat.number
|
|
6035
|
+
},
|
|
6036
|
+
{
|
|
6037
|
+
key: ConfigKey.property_alt,
|
|
6038
|
+
description: "The alternative text for the image",
|
|
6039
|
+
format: TagFormat.plainText
|
|
6040
|
+
},
|
|
6041
|
+
// @zoomDisabled with a true default
|
|
6042
|
+
{
|
|
6043
|
+
key: ConfigKey.property_zoomDisabled,
|
|
6044
|
+
description: "If true, zooming is disabled for the image (defaults to true)",
|
|
6045
|
+
format: TagFormat.boolean,
|
|
6046
|
+
defaultValue: "true"
|
|
6047
|
+
}
|
|
6048
|
+
]
|
|
6049
|
+
},
|
|
4691
6050
|
[ConfigKey.group_resourceAudioCommon]: {
|
|
4692
6051
|
type: GroupConfigType.standard,
|
|
4693
6052
|
description: "Common properties for audio resources",
|
|
@@ -4777,22 +6136,26 @@ var GROUPS = {
|
|
|
4777
6136
|
{
|
|
4778
6137
|
key: ConfigKey.property_src1x,
|
|
4779
6138
|
description: "The source URL for the video at 1x resolution",
|
|
4780
|
-
format: TagFormat.plainText
|
|
6139
|
+
format: TagFormat.plainText,
|
|
6140
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4781
6141
|
},
|
|
4782
6142
|
{
|
|
4783
6143
|
key: ConfigKey.property_src2x,
|
|
4784
6144
|
description: "The source URL for the video at 2x resolution",
|
|
4785
|
-
format: TagFormat.plainText
|
|
6145
|
+
format: TagFormat.plainText,
|
|
6146
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4786
6147
|
},
|
|
4787
6148
|
{
|
|
4788
6149
|
key: ConfigKey.property_src3x,
|
|
4789
6150
|
description: "The source URL for the video at 3x resolution",
|
|
4790
|
-
format: TagFormat.plainText
|
|
6151
|
+
format: TagFormat.plainText,
|
|
6152
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4791
6153
|
},
|
|
4792
6154
|
{
|
|
4793
6155
|
key: ConfigKey.property_src4x,
|
|
4794
6156
|
description: "The source URL for the video at 4x resolution",
|
|
4795
|
-
format: TagFormat.plainText
|
|
6157
|
+
format: TagFormat.plainText,
|
|
6158
|
+
exportJsonKey: { thumbnails: [{ src: "$" }] }
|
|
4796
6159
|
}
|
|
4797
6160
|
]
|
|
4798
6161
|
},
|
|
@@ -4805,6 +6168,7 @@ var GROUPS = {
|
|
|
4805
6168
|
tags: [
|
|
4806
6169
|
{
|
|
4807
6170
|
key: ConfigKey.resource_icon,
|
|
6171
|
+
exportJsonKey: { resource: { type: "icon", icon: { src: "$" } } },
|
|
4808
6172
|
description: "The icon resource",
|
|
4809
6173
|
chain: [
|
|
4810
6174
|
{
|
|
@@ -4832,12 +6196,30 @@ var GROUPS = {
|
|
|
4832
6196
|
}
|
|
4833
6197
|
]
|
|
4834
6198
|
},
|
|
6199
|
+
[ConfigKey.group_resourceImageNoZoom]: {
|
|
6200
|
+
type: GroupConfigType.resource,
|
|
6201
|
+
description: "Image resource where @zoomDisabled defaults to true",
|
|
6202
|
+
tags: [
|
|
6203
|
+
{
|
|
6204
|
+
key: ConfigKey.resource_image,
|
|
6205
|
+
exportJsonKey: { resource: { type: "image", image: { src: "$" } } },
|
|
6206
|
+
description: "The image resource (no-zoom default)",
|
|
6207
|
+
chain: [
|
|
6208
|
+
{
|
|
6209
|
+
key: ConfigKey.group_resourceImageCommonNoZoom,
|
|
6210
|
+
description: "Common image properties with @zoomDisabled defaulting to true"
|
|
6211
|
+
}
|
|
6212
|
+
]
|
|
6213
|
+
}
|
|
6214
|
+
]
|
|
6215
|
+
},
|
|
4835
6216
|
[ConfigKey.group_resourceImagePortrait]: {
|
|
4836
6217
|
type: GroupConfigType.resource,
|
|
4837
6218
|
description: "Portrait image resource",
|
|
4838
6219
|
tags: [
|
|
4839
6220
|
{
|
|
4840
6221
|
key: ConfigKey.resource_imagePortrait,
|
|
6222
|
+
exportJsonKey: { resource: { type: "image-portrait", imagePortrait: { src: "$" } } },
|
|
4841
6223
|
description: "The portrait image resource",
|
|
4842
6224
|
chain: [
|
|
4843
6225
|
{
|
|
@@ -4854,6 +6236,7 @@ var GROUPS = {
|
|
|
4854
6236
|
tags: [
|
|
4855
6237
|
{
|
|
4856
6238
|
key: ConfigKey.resource_imageLandscape,
|
|
6239
|
+
exportJsonKey: { resource: { type: "image-landscape", imageLandscape: { src: "$" } } },
|
|
4857
6240
|
description: "The landscape image resource",
|
|
4858
6241
|
chain: [
|
|
4859
6242
|
{
|
|
@@ -4870,6 +6253,7 @@ var GROUPS = {
|
|
|
4870
6253
|
tags: [
|
|
4871
6254
|
{
|
|
4872
6255
|
key: ConfigKey.resource_imageEmbed,
|
|
6256
|
+
exportJsonKey: { resource: { type: "image-embed", imageEmbed: { src: "$" } } },
|
|
4873
6257
|
description: "The embedded image resource",
|
|
4874
6258
|
chain: [
|
|
4875
6259
|
{
|
|
@@ -5043,6 +6427,7 @@ var GROUPS = {
|
|
|
5043
6427
|
tags: [
|
|
5044
6428
|
{
|
|
5045
6429
|
key: ConfigKey.resource_article,
|
|
6430
|
+
exportJsonKey: { resource: { type: "article", article: { body: "$" } } },
|
|
5046
6431
|
description: "The article resource",
|
|
5047
6432
|
chain: [
|
|
5048
6433
|
{
|
|
@@ -5059,6 +6444,7 @@ var GROUPS = {
|
|
|
5059
6444
|
tags: [
|
|
5060
6445
|
{
|
|
5061
6446
|
key: ConfigKey.resource_articleEmbed,
|
|
6447
|
+
exportJsonKey: { resource: { type: "article-embed", articleEmbed: { url: "$" } } },
|
|
5062
6448
|
description: "The embedded article resource",
|
|
5063
6449
|
chain: [
|
|
5064
6450
|
{
|
|
@@ -5075,6 +6461,7 @@ var GROUPS = {
|
|
|
5075
6461
|
tags: [
|
|
5076
6462
|
{
|
|
5077
6463
|
key: ConfigKey.resource_articleLink,
|
|
6464
|
+
exportJsonKey: { resource: { type: "article-link", articleLink: { url: "$" } } },
|
|
5078
6465
|
description: "The link to the article resource",
|
|
5079
6466
|
chain: [
|
|
5080
6467
|
{
|
|
@@ -5345,7 +6732,12 @@ var ConfigHydrator = class {
|
|
|
5345
6732
|
isDefault: v.isDefault,
|
|
5346
6733
|
sideJsonKey: v.sideJsonKey,
|
|
5347
6734
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
5348
|
-
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey")
|
|
6735
|
+
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
6736
|
+
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6737
|
+
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6738
|
+
// as unbounded).
|
|
6739
|
+
minCount: v.minCount,
|
|
6740
|
+
maxCount: v.maxCount
|
|
5349
6741
|
};
|
|
5350
6742
|
}
|
|
5351
6743
|
return out;
|
|
@@ -5560,7 +6952,8 @@ var BITS = {
|
|
|
5560
6952
|
{ isExample: true, example: "$" }
|
|
5561
6953
|
],
|
|
5562
6954
|
description: "The example text for the bit",
|
|
5563
|
-
format: TagFormat.plainText
|
|
6955
|
+
format: TagFormat.plainText,
|
|
6956
|
+
nullable: true
|
|
5564
6957
|
}
|
|
5565
6958
|
],
|
|
5566
6959
|
rootExampleType: ExampleType.string
|
|
@@ -5899,7 +7292,8 @@ var BITS = {
|
|
|
5899
7292
|
{ isExample: true, example: "$" }
|
|
5900
7293
|
],
|
|
5901
7294
|
description: "The example text for the bit",
|
|
5902
|
-
format: TagFormat.plainText
|
|
7295
|
+
format: TagFormat.plainText,
|
|
7296
|
+
nullable: true
|
|
5903
7297
|
}
|
|
5904
7298
|
],
|
|
5905
7299
|
rootExampleType: ExampleType.string
|
|
@@ -6062,7 +7456,8 @@ var BITS = {
|
|
|
6062
7456
|
{ isExample: true, example: "$" }
|
|
6063
7457
|
],
|
|
6064
7458
|
description: "The example text for the bit",
|
|
6065
|
-
format: TagFormat.plainText
|
|
7459
|
+
format: TagFormat.plainText,
|
|
7460
|
+
nullable: true
|
|
6066
7461
|
}
|
|
6067
7462
|
],
|
|
6068
7463
|
rootExampleType: ExampleType.string
|
|
@@ -6213,7 +7608,8 @@ var BITS = {
|
|
|
6213
7608
|
{ isExample: true, example: "$" }
|
|
6214
7609
|
],
|
|
6215
7610
|
description: "The example text for the bit",
|
|
6216
|
-
format: TagFormat.plainText
|
|
7611
|
+
format: TagFormat.plainText,
|
|
7612
|
+
nullable: true
|
|
6217
7613
|
}
|
|
6218
7614
|
],
|
|
6219
7615
|
rootExampleType: ExampleType.string
|
|
@@ -6808,8 +8204,31 @@ var BITS = {
|
|
|
6808
8204
|
description: "Tags for gaps in cloze and multiple choice text bits"
|
|
6809
8205
|
},
|
|
6810
8206
|
{
|
|
6811
|
-
key: ConfigKey.
|
|
8207
|
+
key: ConfigKey.group_trueFalseInlineSelect,
|
|
6812
8208
|
description: "Tags for true/false questions in cloze and multiple choice text bits"
|
|
8209
|
+
},
|
|
8210
|
+
{
|
|
8211
|
+
// Bit-level @isCaseSensitive — empty exportJsonKey (no bit-level emission);
|
|
8212
|
+
// defaultValue 'true' phantom-fires onto the ancestor stack so the gap chain's
|
|
8213
|
+
// `@absent: $ancestor` rule resolves to true. Mirrors BPG Builder.ts:1643-1652
|
|
8214
|
+
// `pushDownTree(... 'isCaseSensitive', data.isCaseSensitive ?? true)` for cloze bits.
|
|
8215
|
+
key: ConfigKey.property_isCaseSensitive,
|
|
8216
|
+
exportJsonKey: {},
|
|
8217
|
+
description: "If the cloze answers are case sensitive",
|
|
8218
|
+
format: TagFormat.boolean,
|
|
8219
|
+
defaultValue: "true"
|
|
8220
|
+
},
|
|
8221
|
+
{
|
|
8222
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
8223
|
+
key: ConfigKey.property_example,
|
|
8224
|
+
exportJsonKey: [
|
|
8225
|
+
{ "@keyonly": { isExample: true } },
|
|
8226
|
+
{ "@absent": { isExample: true } },
|
|
8227
|
+
{ isExample: true, example: "$" }
|
|
8228
|
+
],
|
|
8229
|
+
description: "The example(s) for the bit",
|
|
8230
|
+
format: TagFormat.bitmarkText,
|
|
8231
|
+
nullable: true
|
|
6813
8232
|
}
|
|
6814
8233
|
]
|
|
6815
8234
|
},
|
|
@@ -6848,18 +8267,56 @@ var BITS = {
|
|
|
6848
8267
|
{
|
|
6849
8268
|
key: ConfigKey.group_gap,
|
|
6850
8269
|
description: "Tags for gaps in cloze bits"
|
|
8270
|
+
},
|
|
8271
|
+
{
|
|
8272
|
+
// Override inherited @example: cloze is in OLD parser's
|
|
8273
|
+
// `isTopLevelExample` allow-list, so [@example] at bit-header
|
|
8274
|
+
// emits `isExample: true`.
|
|
8275
|
+
key: ConfigKey.property_example,
|
|
8276
|
+
exportJsonKey: [
|
|
8277
|
+
{ "@keyonly": { isExample: true } },
|
|
8278
|
+
{ "@absent": { isExample: true } },
|
|
8279
|
+
{ isExample: true, example: "$" }
|
|
8280
|
+
],
|
|
8281
|
+
description: "The example(s) for the bit",
|
|
8282
|
+
format: TagFormat.bitmarkText,
|
|
8283
|
+
nullable: true
|
|
6851
8284
|
}
|
|
6852
8285
|
]
|
|
6853
8286
|
},
|
|
6854
8287
|
[BitType2.clozeInstructionGrouped]: {
|
|
6855
8288
|
since: "1.3.0",
|
|
6856
8289
|
baseBitType: BitType2.cloze,
|
|
6857
|
-
description: "Cloze instruction grouped bit, used for cloze questions with grouped instructions"
|
|
8290
|
+
description: "Cloze instruction grouped bit, used for cloze questions with grouped instructions",
|
|
8291
|
+
tags: [
|
|
8292
|
+
{
|
|
8293
|
+
key: ConfigKey.property_quizCountItems,
|
|
8294
|
+
description: "The number of items in the cloze quiz (instruction-grouped default: true)",
|
|
8295
|
+
format: TagFormat.boolean,
|
|
8296
|
+
defaultValue: "true"
|
|
8297
|
+
}
|
|
8298
|
+
// Note: quizStrikethroughSolutions defaults to false for instruction-grouped per OLD
|
|
8299
|
+
// JsonGenerator.ts:1689-1690, which equals the Boolean natural default → no override needed.
|
|
8300
|
+
]
|
|
6858
8301
|
},
|
|
6859
8302
|
[BitType2.clozeSolutionGrouped]: {
|
|
6860
8303
|
since: "1.3.0",
|
|
6861
8304
|
baseBitType: BitType2.cloze,
|
|
6862
|
-
description: "Cloze solution grouped bit, used for cloze questions with grouped solutions"
|
|
8305
|
+
description: "Cloze solution grouped bit, used for cloze questions with grouped solutions",
|
|
8306
|
+
tags: [
|
|
8307
|
+
{
|
|
8308
|
+
key: ConfigKey.property_quizCountItems,
|
|
8309
|
+
description: "The number of items in the cloze quiz (solution-grouped default: true)",
|
|
8310
|
+
format: TagFormat.boolean,
|
|
8311
|
+
defaultValue: "true"
|
|
8312
|
+
},
|
|
8313
|
+
{
|
|
8314
|
+
key: ConfigKey.property_quizStrikethroughSolutions,
|
|
8315
|
+
description: "If the cloze solutions should be strikethrough (solution-grouped default: true)",
|
|
8316
|
+
format: TagFormat.boolean,
|
|
8317
|
+
defaultValue: "true"
|
|
8318
|
+
}
|
|
8319
|
+
]
|
|
6863
8320
|
},
|
|
6864
8321
|
[BitType2.clozeSeveral]: {
|
|
6865
8322
|
since: "3.5.0",
|
|
@@ -6895,6 +8352,17 @@ var BITS = {
|
|
|
6895
8352
|
{
|
|
6896
8353
|
key: ConfigKey.group_quizCommon,
|
|
6897
8354
|
description: "Common tags for quiz bits"
|
|
8355
|
+
},
|
|
8356
|
+
{
|
|
8357
|
+
// PLAN-084 (R12): bit-level @isCaseSensitive — empty exportJsonKey
|
|
8358
|
+
// (no bit-level emission); defaultValue 'true' phantom-fires onto
|
|
8359
|
+
// the ancestor stack so each listItem's gap chain `@absent: $ancestor`
|
|
8360
|
+
// rule resolves to true. Mirrors the cloze bit (bits.ts:1326-1336).
|
|
8361
|
+
key: ConfigKey.property_isCaseSensitive,
|
|
8362
|
+
exportJsonKey: {},
|
|
8363
|
+
description: "If the cloze answers are case sensitive",
|
|
8364
|
+
format: TagFormat.boolean,
|
|
8365
|
+
defaultValue: "true"
|
|
6898
8366
|
}
|
|
6899
8367
|
],
|
|
6900
8368
|
cardSet: CardSetConfigKey.clozeList
|
|
@@ -7061,6 +8529,7 @@ var BITS = {
|
|
|
7061
8529
|
tags: [
|
|
7062
8530
|
{
|
|
7063
8531
|
key: ConfigKey.group_person,
|
|
8532
|
+
exportJsonKey: { partner: { name: "$" } },
|
|
7064
8533
|
description: "Tags for the person in the conversation"
|
|
7065
8534
|
}
|
|
7066
8535
|
]
|
|
@@ -7499,7 +8968,8 @@ var BITS = {
|
|
|
7499
8968
|
{ isExample: true, example: "$" }
|
|
7500
8969
|
],
|
|
7501
8970
|
description: "The example text for the essay bit",
|
|
7502
|
-
format: TagFormat.plainText
|
|
8971
|
+
format: TagFormat.plainText,
|
|
8972
|
+
nullable: true
|
|
7503
8973
|
}
|
|
7504
8974
|
],
|
|
7505
8975
|
rootExampleType: ExampleType.string
|
|
@@ -7533,7 +9003,8 @@ var BITS = {
|
|
|
7533
9003
|
{ isExample: true, example: "$" }
|
|
7534
9004
|
],
|
|
7535
9005
|
description: "The example text for the example bit",
|
|
7536
|
-
format: TagFormat.plainText
|
|
9006
|
+
format: TagFormat.plainText,
|
|
9007
|
+
nullable: true
|
|
7537
9008
|
}
|
|
7538
9009
|
],
|
|
7539
9010
|
rootExampleType: ExampleType.string
|
|
@@ -7619,7 +9090,19 @@ var BITS = {
|
|
|
7619
9090
|
[BitType2.articleAi]: {
|
|
7620
9091
|
since: "1.3.0",
|
|
7621
9092
|
baseBitType: BitType2.article,
|
|
7622
|
-
description: "Article AI bit, used to create AI-generated articles"
|
|
9093
|
+
description: "Article AI bit, used to create AI-generated articles",
|
|
9094
|
+
tags: [
|
|
9095
|
+
{
|
|
9096
|
+
// Shadows the inherited @aiGenerated from the standard group: this
|
|
9097
|
+
// bit type forces aiGenerated:true regardless of source value or
|
|
9098
|
+
// absence. Literal `true` in the export pattern ignores `$`.
|
|
9099
|
+
key: ConfigKey.property_aiGenerated,
|
|
9100
|
+
description: "AI-generated flag, forced true for article-ai bits",
|
|
9101
|
+
format: TagFormat.boolean,
|
|
9102
|
+
defaultValue: "true",
|
|
9103
|
+
exportJsonKey: { aiGenerated: true }
|
|
9104
|
+
}
|
|
9105
|
+
]
|
|
7623
9106
|
},
|
|
7624
9107
|
[BitType2.articleAttachment]: {
|
|
7625
9108
|
since: "1.3.0",
|
|
@@ -7944,7 +9427,19 @@ var BITS = {
|
|
|
7944
9427
|
[BitType2.noteAi]: {
|
|
7945
9428
|
since: "1.3.0",
|
|
7946
9429
|
baseBitType: BitType2.note,
|
|
7947
|
-
description: "Note AI bit, used to create AI-generated notes in articles or books"
|
|
9430
|
+
description: "Note AI bit, used to create AI-generated notes in articles or books",
|
|
9431
|
+
tags: [
|
|
9432
|
+
{
|
|
9433
|
+
// Shadows the inherited @aiGenerated from the standard group: this
|
|
9434
|
+
// bit type forces aiGenerated:true regardless of source value or
|
|
9435
|
+
// absence. Literal `true` in the export pattern ignores `$`.
|
|
9436
|
+
key: ConfigKey.property_aiGenerated,
|
|
9437
|
+
description: "AI-generated flag, forced true for article-ai bits",
|
|
9438
|
+
format: TagFormat.boolean,
|
|
9439
|
+
defaultValue: "true",
|
|
9440
|
+
exportJsonKey: { aiGenerated: true }
|
|
9441
|
+
}
|
|
9442
|
+
]
|
|
7948
9443
|
},
|
|
7949
9444
|
[BitType2.notebookArticle]: {
|
|
7950
9445
|
since: "1.3.0",
|
|
@@ -8069,7 +9564,19 @@ var BITS = {
|
|
|
8069
9564
|
[BitType2.summaryAi]: {
|
|
8070
9565
|
since: "1.3.0",
|
|
8071
9566
|
baseBitType: BitType2.summary,
|
|
8072
|
-
description: "AI-generated summary bit"
|
|
9567
|
+
description: "AI-generated summary bit",
|
|
9568
|
+
tags: [
|
|
9569
|
+
{
|
|
9570
|
+
// Shadows the inherited @aiGenerated from the standard group: this
|
|
9571
|
+
// bit type forces aiGenerated:true regardless of source value or
|
|
9572
|
+
// absence. Literal `true` in the export pattern ignores `$`.
|
|
9573
|
+
key: ConfigKey.property_aiGenerated,
|
|
9574
|
+
description: "AI-generated flag, forced true for article-ai bits",
|
|
9575
|
+
format: TagFormat.boolean,
|
|
9576
|
+
defaultValue: "true",
|
|
9577
|
+
exportJsonKey: { aiGenerated: true }
|
|
9578
|
+
}
|
|
9579
|
+
]
|
|
8073
9580
|
},
|
|
8074
9581
|
[BitType2.videoTranscript]: {
|
|
8075
9582
|
since: "1.3.0",
|
|
@@ -8343,7 +9850,7 @@ var BITS = {
|
|
|
8343
9850
|
description: "Product ID for the module product, used to link to a specific product",
|
|
8344
9851
|
format: TagFormat.plainText,
|
|
8345
9852
|
minCount: 1,
|
|
8346
|
-
maxCount:
|
|
9853
|
+
maxCount: 1
|
|
8347
9854
|
}
|
|
8348
9855
|
]
|
|
8349
9856
|
},
|
|
@@ -8396,10 +9903,13 @@ var BITS = {
|
|
|
8396
9903
|
description: "Resource bit tags for logo grave images, used to define additional properties"
|
|
8397
9904
|
},
|
|
8398
9905
|
{
|
|
8399
|
-
// Image resource
|
|
8400
|
-
|
|
9906
|
+
// Image resource — fully-expanded shape so each `&image` emission
|
|
9907
|
+
// produces a complete `{type, image: {src}}` object inside the
|
|
9908
|
+
// `images[]` array. Chain attrs like `[@zoomDisabled]` fold under
|
|
9909
|
+
// `images[].image` via the `[]` last-element-merge semantic.
|
|
9910
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
8401
9911
|
description: "Resource image tags for logo grave images, used to attach images",
|
|
8402
|
-
exportJsonKey: { images: "$" },
|
|
9912
|
+
exportJsonKey: { images: [{ type: "image", image: { src: "$" } }] },
|
|
8403
9913
|
minCount: 1,
|
|
8404
9914
|
maxCount: Count.infinity
|
|
8405
9915
|
}
|
|
@@ -8689,6 +10199,10 @@ var BITS = {
|
|
|
8689
10199
|
tags: [
|
|
8690
10200
|
{
|
|
8691
10201
|
key: ConfigKey.property_book,
|
|
10202
|
+
// Starter-array shape: each `[@book:value]` chain appends a fresh
|
|
10203
|
+
// `{ book, reference }` entry. The chained `►` (tag_reference) lands
|
|
10204
|
+
// inside the most-recently-appended entry as `reference: $`.
|
|
10205
|
+
exportJsonKey: { book: [{ book: "$" }] },
|
|
8692
10206
|
description: "Book reference for the page, used to link to a specific book",
|
|
8693
10207
|
maxCount: Count.infinity,
|
|
8694
10208
|
chain: [
|
|
@@ -8756,7 +10270,9 @@ var BITS = {
|
|
|
8756
10270
|
format: TagFormat.plainText
|
|
8757
10271
|
}
|
|
8758
10272
|
],
|
|
8759
|
-
|
|
10273
|
+
// page-footer emits cards under `sections` (vs `listItems` for the
|
|
10274
|
+
// sibling exampleList / assignmentList bits) — see JsonGenerator.ts.
|
|
10275
|
+
cardSet: CardSetConfigKey.pageFooterSections
|
|
8760
10276
|
},
|
|
8761
10277
|
[BitType2.legend]: {
|
|
8762
10278
|
since: "3.12.0",
|
|
@@ -8798,6 +10314,20 @@ var BITS = {
|
|
|
8798
10314
|
since: "1.34.0",
|
|
8799
10315
|
baseBitType: BitType2._standard,
|
|
8800
10316
|
description: "Definition list bit, used to create lists of definitions in articles or books",
|
|
10317
|
+
tags: [
|
|
10318
|
+
{
|
|
10319
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10320
|
+
key: ConfigKey.property_example,
|
|
10321
|
+
exportJsonKey: [
|
|
10322
|
+
{ "@keyonly": { isExample: true } },
|
|
10323
|
+
{ "@absent": { isExample: true } },
|
|
10324
|
+
{ isExample: true, example: "$" }
|
|
10325
|
+
],
|
|
10326
|
+
description: "The example(s) for the bit",
|
|
10327
|
+
format: TagFormat.bitmarkText,
|
|
10328
|
+
nullable: true
|
|
10329
|
+
}
|
|
10330
|
+
],
|
|
8801
10331
|
cardSet: CardSetConfigKey.definitionList
|
|
8802
10332
|
},
|
|
8803
10333
|
[BitType2.metaSearchDefaultTerms]: {
|
|
@@ -8820,6 +10350,18 @@ var BITS = {
|
|
|
8820
10350
|
{
|
|
8821
10351
|
key: ConfigKey.group_quizCommon,
|
|
8822
10352
|
description: "Common quiz tags for flashcards"
|
|
10353
|
+
},
|
|
10354
|
+
{
|
|
10355
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10356
|
+
key: ConfigKey.property_example,
|
|
10357
|
+
exportJsonKey: [
|
|
10358
|
+
{ "@keyonly": { isExample: true } },
|
|
10359
|
+
{ "@absent": { isExample: true } },
|
|
10360
|
+
{ isExample: true, example: "$" }
|
|
10361
|
+
],
|
|
10362
|
+
description: "The example(s) for the bit",
|
|
10363
|
+
format: TagFormat.bitmarkText,
|
|
10364
|
+
nullable: true
|
|
8823
10365
|
}
|
|
8824
10366
|
],
|
|
8825
10367
|
cardSet: CardSetConfigKey.flashcard
|
|
@@ -8827,7 +10369,11 @@ var BITS = {
|
|
|
8827
10369
|
[BitType2.flashcard1]: {
|
|
8828
10370
|
since: "1.3.0",
|
|
8829
10371
|
baseBitType: BitType2.flashcard,
|
|
8830
|
-
description: "Flashcard 1 bit"
|
|
10372
|
+
description: "Flashcard 1 bit",
|
|
10373
|
+
// PLAN-085: use the flashcard1 cardset (sections.default.maxCount=1)
|
|
10374
|
+
// instead of inheriting `flashcard`'s unbounded cardset, since this
|
|
10375
|
+
// bit type structurally allows only a single card.
|
|
10376
|
+
cardSet: CardSetConfigKey.flashcard1
|
|
8831
10377
|
},
|
|
8832
10378
|
[BitType2.qAndACard]: {
|
|
8833
10379
|
since: "3.25.0",
|
|
@@ -8862,8 +10408,24 @@ var BITS = {
|
|
|
8862
10408
|
description: "Common quiz tags for highlighted text"
|
|
8863
10409
|
},
|
|
8864
10410
|
{
|
|
8865
|
-
|
|
8866
|
-
|
|
10411
|
+
// Dedicated highlight inline-select chain: tag_true / tag_false
|
|
10412
|
+
// emit `{type:"highlight", attrs:{texts:[{text,isCorrect?}]}}`
|
|
10413
|
+
// inline body nodes via @body-inline. Bit shares no tag IDs with
|
|
10414
|
+
// multiple-choice / multiple-choice-1 (which use group_trueFalse).
|
|
10415
|
+
key: ConfigKey.group_trueFalseInlineHighlight,
|
|
10416
|
+
description: "True/False quiz tags for highlighted text (inline body nodes)"
|
|
10417
|
+
},
|
|
10418
|
+
{
|
|
10419
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10420
|
+
key: ConfigKey.property_example,
|
|
10421
|
+
exportJsonKey: [
|
|
10422
|
+
{ "@keyonly": { isExample: true } },
|
|
10423
|
+
{ "@absent": { isExample: true } },
|
|
10424
|
+
{ isExample: true, example: "$" }
|
|
10425
|
+
],
|
|
10426
|
+
description: "The example(s) for the bit",
|
|
10427
|
+
format: TagFormat.bitmarkText,
|
|
10428
|
+
nullable: true
|
|
8867
10429
|
}
|
|
8868
10430
|
]
|
|
8869
10431
|
},
|
|
@@ -8873,15 +10435,8 @@ var BITS = {
|
|
|
8873
10435
|
description: "Image bit, used to create images in articles or books",
|
|
8874
10436
|
tags: [
|
|
8875
10437
|
{
|
|
8876
|
-
key: ConfigKey.
|
|
8877
|
-
|
|
8878
|
-
description: "Background wallpaper for the image, used to set a background for the image",
|
|
8879
|
-
chain: [
|
|
8880
|
-
{
|
|
8881
|
-
key: ConfigKey.group_resourceImageCommon,
|
|
8882
|
-
description: "Common resource image tags for images"
|
|
8883
|
-
}
|
|
8884
|
-
]
|
|
10438
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
10439
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
8885
10440
|
},
|
|
8886
10441
|
{
|
|
8887
10442
|
key: ConfigKey.group_resourceBitTags,
|
|
@@ -8984,8 +10539,15 @@ var BITS = {
|
|
|
8984
10539
|
},
|
|
8985
10540
|
[BitType2.imageSeparator]: {
|
|
8986
10541
|
since: "1.4.15",
|
|
8987
|
-
baseBitType: BitType2.
|
|
8988
|
-
description: "Image separator bit, used to create separators in articles or books"
|
|
10542
|
+
baseBitType: BitType2._standard,
|
|
10543
|
+
description: "Image separator bit, used to create separators in articles or books",
|
|
10544
|
+
tags: [
|
|
10545
|
+
{
|
|
10546
|
+
key: ConfigKey.group_imageNoZoom,
|
|
10547
|
+
description: "Image no zoom tags for images, used to define whether images should have zoom functionality"
|
|
10548
|
+
}
|
|
10549
|
+
],
|
|
10550
|
+
resourceAttachmentAllowed: false
|
|
8989
10551
|
},
|
|
8990
10552
|
[BitType2.imageSeparatorAlt]: {
|
|
8991
10553
|
since: "1.16.0",
|
|
@@ -9024,15 +10586,20 @@ var BITS = {
|
|
|
9024
10586
|
},
|
|
9025
10587
|
[BitType2.pageBanner]: {
|
|
9026
10588
|
since: "1.4.3",
|
|
9027
|
-
baseBitType: BitType2.
|
|
10589
|
+
baseBitType: BitType2._standard,
|
|
9028
10590
|
description: "Page banner bit, used to create banners for pages in articles or books",
|
|
9029
10591
|
tags: [
|
|
9030
10592
|
{
|
|
9031
10593
|
key: ConfigKey.property_slug,
|
|
9032
10594
|
description: "Slug for the page banner, used to identify the banner in the system",
|
|
9033
10595
|
format: TagFormat.plainText
|
|
10596
|
+
},
|
|
10597
|
+
{
|
|
10598
|
+
key: ConfigKey.group_imageNoZoom,
|
|
10599
|
+
description: "Image no zoom tags for images, used to define whether images should have zoom functionality"
|
|
9034
10600
|
}
|
|
9035
|
-
]
|
|
10601
|
+
],
|
|
10602
|
+
resourceAttachmentAllowed: false
|
|
9036
10603
|
},
|
|
9037
10604
|
[BitType2.pageHero]: {
|
|
9038
10605
|
since: "1.11.0",
|
|
@@ -9047,7 +10614,7 @@ var BITS = {
|
|
|
9047
10614
|
},
|
|
9048
10615
|
[BitType2.tableImage]: {
|
|
9049
10616
|
since: "1.5.15",
|
|
9050
|
-
baseBitType: BitType2.
|
|
10617
|
+
baseBitType: BitType2.tableExtended,
|
|
9051
10618
|
description: "Table image bit, used to create images in tables in articles or books",
|
|
9052
10619
|
tags: [
|
|
9053
10620
|
{
|
|
@@ -9056,15 +10623,8 @@ var BITS = {
|
|
|
9056
10623
|
format: TagFormat.bitmarkText
|
|
9057
10624
|
},
|
|
9058
10625
|
{
|
|
9059
|
-
key: ConfigKey.
|
|
9060
|
-
|
|
9061
|
-
description: "Background wallpaper for the image, used to set a background for the image",
|
|
9062
|
-
chain: [
|
|
9063
|
-
{
|
|
9064
|
-
key: ConfigKey.group_resourceImageCommon,
|
|
9065
|
-
description: "Common resource image tags for images"
|
|
9066
|
-
}
|
|
9067
|
-
]
|
|
10626
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
10627
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
9068
10628
|
},
|
|
9069
10629
|
{
|
|
9070
10630
|
key: ConfigKey.group_resourceBitTags,
|
|
@@ -9207,10 +10767,10 @@ var BITS = {
|
|
|
9207
10767
|
description: "Resource bit tags for logo grave images, used to define additional properties"
|
|
9208
10768
|
},
|
|
9209
10769
|
{
|
|
9210
|
-
// Image resource
|
|
9211
|
-
key: ConfigKey.
|
|
10770
|
+
// Image resource — fully-expanded shape (see BitType.extractorImage).
|
|
10771
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
9212
10772
|
description: "Resource image tags for logo grave images, used to attach images",
|
|
9213
|
-
exportJsonKey: { logos: "$" },
|
|
10773
|
+
exportJsonKey: { logos: [{ type: "image", image: { src: "$" } }] },
|
|
9214
10774
|
minCount: 1,
|
|
9215
10775
|
maxCount: Count.infinity
|
|
9216
10776
|
}
|
|
@@ -9220,7 +10780,17 @@ var BITS = {
|
|
|
9220
10780
|
[BitType2.prototypeImages]: {
|
|
9221
10781
|
since: "1.6.1",
|
|
9222
10782
|
baseBitType: BitType2.imagesLogoGrave,
|
|
9223
|
-
description: "Prototype images bit, used to create prototype images in articles or books"
|
|
10783
|
+
description: "Prototype images bit, used to create prototype images in articles or books",
|
|
10784
|
+
tags: [
|
|
10785
|
+
{
|
|
10786
|
+
// Override inherited `logos` wrapper with `images` for this bit type.
|
|
10787
|
+
key: ConfigKey.group_resourceImageNoZoom,
|
|
10788
|
+
description: "Resource image tags for prototype images",
|
|
10789
|
+
exportJsonKey: { images: [{ type: "image", image: { src: "$" } }] },
|
|
10790
|
+
minCount: 1,
|
|
10791
|
+
maxCount: Count.infinity
|
|
10792
|
+
}
|
|
10793
|
+
]
|
|
9224
10794
|
},
|
|
9225
10795
|
[BitType2.internalLink]: {
|
|
9226
10796
|
since: "1.3.0",
|
|
@@ -9250,6 +10820,18 @@ var BITS = {
|
|
|
9250
10820
|
exportJsonKey: {},
|
|
9251
10821
|
description: "Reasonable number of characters for the interview, used to limit input size",
|
|
9252
10822
|
format: TagFormat.number
|
|
10823
|
+
},
|
|
10824
|
+
{
|
|
10825
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
10826
|
+
key: ConfigKey.property_example,
|
|
10827
|
+
exportJsonKey: [
|
|
10828
|
+
{ "@keyonly": { isExample: true } },
|
|
10829
|
+
{ "@absent": { isExample: true } },
|
|
10830
|
+
{ isExample: true, example: "$" }
|
|
10831
|
+
],
|
|
10832
|
+
description: "The example(s) for the bit",
|
|
10833
|
+
format: TagFormat.bitmarkText,
|
|
10834
|
+
nullable: true
|
|
9253
10835
|
}
|
|
9254
10836
|
],
|
|
9255
10837
|
cardSet: CardSetConfigKey.questions
|
|
@@ -9608,6 +11190,18 @@ var BITS = {
|
|
|
9608
11190
|
{
|
|
9609
11191
|
key: ConfigKey.group_mark,
|
|
9610
11192
|
description: "Mark tags, used to define the content of marks"
|
|
11193
|
+
},
|
|
11194
|
+
{
|
|
11195
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11196
|
+
key: ConfigKey.property_example,
|
|
11197
|
+
exportJsonKey: [
|
|
11198
|
+
{ "@keyonly": { isExample: true } },
|
|
11199
|
+
{ "@absent": { isExample: true } },
|
|
11200
|
+
{ isExample: true, example: "$" }
|
|
11201
|
+
],
|
|
11202
|
+
description: "The example(s) for the bit",
|
|
11203
|
+
format: TagFormat.bitmarkText,
|
|
11204
|
+
nullable: true
|
|
9611
11205
|
}
|
|
9612
11206
|
]
|
|
9613
11207
|
},
|
|
@@ -9627,6 +11221,23 @@ var BITS = {
|
|
|
9627
11221
|
description: "Case sensitivity for matching pairs, used to define if matches are case-sensitive",
|
|
9628
11222
|
format: TagFormat.boolean,
|
|
9629
11223
|
defaultValue: "true"
|
|
11224
|
+
},
|
|
11225
|
+
{
|
|
11226
|
+
// Override inherited @example: in `isTopLevelExample` allow-list
|
|
11227
|
+
// (covers match, matchAll, matchReverse, matchAllReverse,
|
|
11228
|
+
// matchSolutionGrouped, matchMatrix, matchAudio, matchPicture).
|
|
11229
|
+
// Bit-level fires emit only `isExample`; the @example value (when
|
|
11230
|
+
// provided) is recorded in the ancestor stack and consumed by
|
|
11231
|
+
// per-pair/per-cell variant overrides — not surfaced at bit scope.
|
|
11232
|
+
key: ConfigKey.property_example,
|
|
11233
|
+
exportJsonKey: [
|
|
11234
|
+
{ "@keyonly": { isExample: true } },
|
|
11235
|
+
{ "@absent": { isExample: true } },
|
|
11236
|
+
{ isExample: true }
|
|
11237
|
+
],
|
|
11238
|
+
description: "The example(s) for the bit",
|
|
11239
|
+
format: TagFormat.bitmarkText,
|
|
11240
|
+
nullable: true
|
|
9630
11241
|
}
|
|
9631
11242
|
],
|
|
9632
11243
|
cardSet: CardSetConfigKey.matchPairs
|
|
@@ -9711,6 +11322,18 @@ var BITS = {
|
|
|
9711
11322
|
{
|
|
9712
11323
|
key: ConfigKey.group_trueFalse,
|
|
9713
11324
|
description: "True/False tags for multiple choice 1 questions"
|
|
11325
|
+
},
|
|
11326
|
+
{
|
|
11327
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11328
|
+
key: ConfigKey.property_example,
|
|
11329
|
+
exportJsonKey: [
|
|
11330
|
+
{ "@keyonly": { isExample: true } },
|
|
11331
|
+
{ "@absent": { isExample: true } },
|
|
11332
|
+
{ isExample: true, example: "$" }
|
|
11333
|
+
],
|
|
11334
|
+
description: "The example(s) for the bit",
|
|
11335
|
+
format: TagFormat.bitmarkText,
|
|
11336
|
+
nullable: true
|
|
9714
11337
|
}
|
|
9715
11338
|
]
|
|
9716
11339
|
},
|
|
@@ -9732,8 +11355,20 @@ var BITS = {
|
|
|
9732
11355
|
{
|
|
9733
11356
|
key: ConfigKey.group_trueFalse,
|
|
9734
11357
|
description: "True/False tags for multiple choice questions"
|
|
9735
|
-
}
|
|
11358
|
+
},
|
|
9736
11359
|
// This is actually for multiple-choice-1, but we support it here as well (as many bits are wrong)
|
|
11360
|
+
{
|
|
11361
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11362
|
+
key: ConfigKey.property_example,
|
|
11363
|
+
exportJsonKey: [
|
|
11364
|
+
{ "@keyonly": { isExample: true } },
|
|
11365
|
+
{ "@absent": { isExample: true } },
|
|
11366
|
+
{ isExample: true, example: "$" }
|
|
11367
|
+
],
|
|
11368
|
+
description: "The example(s) for the bit",
|
|
11369
|
+
format: TagFormat.bitmarkText,
|
|
11370
|
+
nullable: true
|
|
11371
|
+
}
|
|
9737
11372
|
],
|
|
9738
11373
|
cardSet: CardSetConfigKey.quiz
|
|
9739
11374
|
},
|
|
@@ -9753,8 +11388,20 @@ var BITS = {
|
|
|
9753
11388
|
description: "Common quiz tags for multiple choice text questions"
|
|
9754
11389
|
},
|
|
9755
11390
|
{
|
|
9756
|
-
key: ConfigKey.
|
|
11391
|
+
key: ConfigKey.group_trueFalseInlineSelect,
|
|
9757
11392
|
description: "True/False tags for multiple choice text questions"
|
|
11393
|
+
},
|
|
11394
|
+
{
|
|
11395
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11396
|
+
key: ConfigKey.property_example,
|
|
11397
|
+
exportJsonKey: [
|
|
11398
|
+
{ "@keyonly": { isExample: true } },
|
|
11399
|
+
{ "@absent": { isExample: true } },
|
|
11400
|
+
{ isExample: true, example: "$" }
|
|
11401
|
+
],
|
|
11402
|
+
description: "The example(s) for the bit",
|
|
11403
|
+
format: TagFormat.bitmarkText,
|
|
11404
|
+
nullable: true
|
|
9758
11405
|
}
|
|
9759
11406
|
]
|
|
9760
11407
|
},
|
|
@@ -9779,8 +11426,20 @@ var BITS = {
|
|
|
9779
11426
|
description: "Common quiz tags for multiple response 1 questions"
|
|
9780
11427
|
},
|
|
9781
11428
|
{
|
|
9782
|
-
key: ConfigKey.
|
|
11429
|
+
key: ConfigKey.group_trueFalseResponses,
|
|
9783
11430
|
description: "True/False tags for multiple response 1 questions"
|
|
11431
|
+
},
|
|
11432
|
+
{
|
|
11433
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11434
|
+
key: ConfigKey.property_example,
|
|
11435
|
+
exportJsonKey: [
|
|
11436
|
+
{ "@keyonly": { isExample: true } },
|
|
11437
|
+
{ "@absent": { isExample: true } },
|
|
11438
|
+
{ isExample: true, example: "$" }
|
|
11439
|
+
],
|
|
11440
|
+
description: "The example(s) for the bit",
|
|
11441
|
+
format: TagFormat.bitmarkText,
|
|
11442
|
+
nullable: true
|
|
9784
11443
|
}
|
|
9785
11444
|
]
|
|
9786
11445
|
},
|
|
@@ -9800,12 +11459,24 @@ var BITS = {
|
|
|
9800
11459
|
description: "Common quiz tags for multiple response questions"
|
|
9801
11460
|
},
|
|
9802
11461
|
{
|
|
9803
|
-
key: ConfigKey.
|
|
11462
|
+
key: ConfigKey.group_trueFalseResponses,
|
|
9804
11463
|
description: "True/False tags for multiple response questions"
|
|
9805
|
-
}
|
|
11464
|
+
},
|
|
9806
11465
|
// This is actually for multiple-response-1, but we support it here as well (as many bits are wrong)
|
|
11466
|
+
{
|
|
11467
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
11468
|
+
key: ConfigKey.property_example,
|
|
11469
|
+
exportJsonKey: [
|
|
11470
|
+
{ "@keyonly": { isExample: true } },
|
|
11471
|
+
{ "@absent": { isExample: true } },
|
|
11472
|
+
{ isExample: true, example: "$" }
|
|
11473
|
+
],
|
|
11474
|
+
description: "The example(s) for the bit",
|
|
11475
|
+
format: TagFormat.bitmarkText,
|
|
11476
|
+
nullable: true
|
|
11477
|
+
}
|
|
9807
11478
|
],
|
|
9808
|
-
cardSet: CardSetConfigKey.
|
|
11479
|
+
cardSet: CardSetConfigKey.quizResponses
|
|
9809
11480
|
},
|
|
9810
11481
|
[BitType2.coachSelfReflectionMultipleResponse]: {
|
|
9811
11482
|
since: "1.3.0",
|
|
@@ -10055,6 +11726,8 @@ var BITS = {
|
|
|
10055
11726
|
},
|
|
10056
11727
|
{
|
|
10057
11728
|
key: ConfigKey.resource_platformIcon,
|
|
11729
|
+
jsonKey: "platformIcon|resource(type=image, key=image)",
|
|
11730
|
+
exportJsonKey: { platformIcon: { type: "image", image: { src: "$" } } },
|
|
10058
11731
|
description: "The platform icon",
|
|
10059
11732
|
chain: [
|
|
10060
11733
|
{
|
|
@@ -10090,6 +11763,8 @@ var BITS = {
|
|
|
10090
11763
|
tags: [
|
|
10091
11764
|
{
|
|
10092
11765
|
key: ConfigKey.resource_platformLogo,
|
|
11766
|
+
jsonKey: "platformLogo|resource(type=image, key=image)",
|
|
11767
|
+
exportJsonKey: { platformLogo: { type: "image", image: { src: "$" } } },
|
|
10093
11768
|
description: "The platform logo",
|
|
10094
11769
|
chain: [
|
|
10095
11770
|
{
|
|
@@ -10301,7 +11976,8 @@ var BITS = {
|
|
|
10301
11976
|
{ isExample: true, example: "$" }
|
|
10302
11977
|
],
|
|
10303
11978
|
description: "The example text for the review note bit",
|
|
10304
|
-
format: TagFormat.plainText
|
|
11979
|
+
format: TagFormat.plainText,
|
|
11980
|
+
nullable: true
|
|
10305
11981
|
}
|
|
10306
11982
|
],
|
|
10307
11983
|
rootExampleType: ExampleType.string
|
|
@@ -10388,7 +12064,8 @@ var BITS = {
|
|
|
10388
12064
|
{ isExample: true, example: "$" }
|
|
10389
12065
|
],
|
|
10390
12066
|
description: "The example flag for the bit (boolean)",
|
|
10391
|
-
format: TagFormat.
|
|
12067
|
+
format: TagFormat.boolean,
|
|
12068
|
+
nullable: true
|
|
10392
12069
|
}
|
|
10393
12070
|
],
|
|
10394
12071
|
cardSet: CardSetConfigKey.elements,
|
|
@@ -10662,15 +12339,8 @@ var BITS = {
|
|
|
10662
12339
|
format: TagFormat.bitmarkText
|
|
10663
12340
|
},
|
|
10664
12341
|
{
|
|
10665
|
-
key: ConfigKey.
|
|
10666
|
-
|
|
10667
|
-
description: "Background wallpaper for the image, used to set a background for the image",
|
|
10668
|
-
chain: [
|
|
10669
|
-
{
|
|
10670
|
-
key: ConfigKey.group_resourceImageCommon,
|
|
10671
|
-
description: "Common resource image tags for images"
|
|
10672
|
-
}
|
|
10673
|
-
]
|
|
12342
|
+
key: ConfigKey.group_backgroundWallpaper,
|
|
12343
|
+
description: "Background wallpaper tags for images, used to define background properties for images"
|
|
10674
12344
|
},
|
|
10675
12345
|
{
|
|
10676
12346
|
key: ConfigKey.group_resourceBitTags,
|
|
@@ -11047,16 +12717,20 @@ var BITS = {
|
|
|
11047
12717
|
format: TagFormat.plainText
|
|
11048
12718
|
},
|
|
11049
12719
|
{
|
|
11050
|
-
|
|
12720
|
+
// PLAN-067 Edit #1: true-false-1's `+` / `-` emit a flat
|
|
12721
|
+
// `{ statement, isCorrect }` at bit root (single-statement bit),
|
|
12722
|
+
// not a `choices[]` array. Format is bitmarkText so the statement
|
|
12723
|
+
// body renders as a ProseMirror tree, matching reference fixtures.
|
|
12724
|
+
exportJsonKey: { statement: "$", isCorrect: true },
|
|
11051
12725
|
key: ConfigKey.tag_true,
|
|
11052
12726
|
description: "Tag for the true option in the true/false question",
|
|
11053
|
-
format: TagFormat.
|
|
12727
|
+
format: TagFormat.bitmarkText
|
|
11054
12728
|
},
|
|
11055
12729
|
{
|
|
11056
|
-
exportJsonKey: {
|
|
12730
|
+
exportJsonKey: { statement: "$", isCorrect: false },
|
|
11057
12731
|
key: ConfigKey.tag_false,
|
|
11058
12732
|
description: "Tag for the false option in the true/false question",
|
|
11059
|
-
format: TagFormat.
|
|
12733
|
+
format: TagFormat.bitmarkText
|
|
11060
12734
|
},
|
|
11061
12735
|
{
|
|
11062
12736
|
// Override inherited @example from group_standardTags: boolean root
|
|
@@ -11067,14 +12741,24 @@ var BITS = {
|
|
|
11067
12741
|
// sufficient for `[+...]` (correct) statements which dominate the
|
|
11068
12742
|
// fixtures; `[-...]` (incorrect) bits with bare `[@example]` would
|
|
11069
12743
|
// need either a runtime extension or an explicit `[@example:false]`.
|
|
12744
|
+
//
|
|
12745
|
+
// Format is `boolean` so `[@example:false]` coerces to JSON `false`
|
|
12746
|
+
// (a natural default that gets stripped in optimised mode, matching
|
|
12747
|
+
// BPG's `rootExampleType: boolean`). PlainText would emit the
|
|
12748
|
+
// STRING `"false"` which doesn't strip.
|
|
11070
12749
|
key: ConfigKey.property_example,
|
|
11071
12750
|
exportJsonKey: [
|
|
11072
12751
|
{ "@keyonly": { isExample: true, example: true } },
|
|
11073
12752
|
{ "@absent": { isExample: true, example: true } },
|
|
12753
|
+
// `[@example:false]`: emit `isExample: true` only — `example: false`
|
|
12754
|
+
// is the natural default for boolean, stripped in optimised mode.
|
|
12755
|
+
// Mirrors BPG `removeUnwantedProperties` `ignoreAllFalse: true`.
|
|
12756
|
+
{ "@value=false": { isExample: true } },
|
|
11074
12757
|
{ isExample: true, example: "$" }
|
|
11075
12758
|
],
|
|
11076
12759
|
description: "The example flag for the bit (boolean)",
|
|
11077
|
-
format: TagFormat.
|
|
12760
|
+
format: TagFormat.boolean,
|
|
12761
|
+
nullable: true
|
|
11078
12762
|
}
|
|
11079
12763
|
],
|
|
11080
12764
|
rootExampleType: ExampleType.boolean
|
|
@@ -11098,6 +12782,18 @@ var BITS = {
|
|
|
11098
12782
|
key: ConfigKey.property_labelFalse,
|
|
11099
12783
|
description: "Label for the false option in the true/false question",
|
|
11100
12784
|
format: TagFormat.plainText
|
|
12785
|
+
},
|
|
12786
|
+
{
|
|
12787
|
+
// Override inherited @example: in `isTopLevelExample` allow-list.
|
|
12788
|
+
key: ConfigKey.property_example,
|
|
12789
|
+
exportJsonKey: [
|
|
12790
|
+
{ "@keyonly": { isExample: true } },
|
|
12791
|
+
{ "@absent": { isExample: true } },
|
|
12792
|
+
{ isExample: true, example: "$" }
|
|
12793
|
+
],
|
|
12794
|
+
description: "The example(s) for the bit",
|
|
12795
|
+
format: TagFormat.bitmarkText,
|
|
12796
|
+
nullable: true
|
|
11101
12797
|
}
|
|
11102
12798
|
],
|
|
11103
12799
|
cardSet: CardSetConfigKey.statements
|
|
@@ -11287,6 +12983,11 @@ var BITS = {
|
|
|
11287
12983
|
baseBitType: BitType2.vendorStripePricingTable,
|
|
11288
12984
|
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",
|
|
11289
12985
|
tags: [
|
|
12986
|
+
{
|
|
12987
|
+
key: ConfigKey.property_stripePricingTableDescriptiveName,
|
|
12988
|
+
description: "Descriptive name for the Stripe pricing table",
|
|
12989
|
+
format: TagFormat.plainText
|
|
12990
|
+
},
|
|
11290
12991
|
{
|
|
11291
12992
|
key: ConfigKey.property_printOnRequestCustomerId,
|
|
11292
12993
|
description: "Print-on-request customer ID, used to identify the customer for the print-on-request flow",
|
|
@@ -11763,7 +13464,7 @@ var instance2 = new Config();
|
|
|
11763
13464
|
// src/generated/package_info.ts
|
|
11764
13465
|
var PACKAGE_INFO = {
|
|
11765
13466
|
"name": "@gmb/bitmark-parser-generator",
|
|
11766
|
-
"version": "5.
|
|
13467
|
+
"version": "5.24.0",
|
|
11767
13468
|
"author": "Get More Brain Ltd",
|
|
11768
13469
|
"license": "ISC",
|
|
11769
13470
|
"description": "A bitmark parser and generator using Peggy.js"
|
|
@@ -12728,6 +14429,8 @@ var NodeType = {
|
|
|
12728
14429
|
stillImageFilmLink: "stillImageFilmLink",
|
|
12729
14430
|
stripePricingTableId: "stripePricingTableId",
|
|
12730
14431
|
stripePricingTableIdValue: "stripePricingTableIdValue",
|
|
14432
|
+
stripePricingTableDescriptiveName: "stripePricingTableDescriptiveName",
|
|
14433
|
+
stripePricingTableDescriptiveNameValue: "stripePricingTableDescriptiveNameValue",
|
|
12731
14434
|
stripePublishableKey: "stripePublishableKey",
|
|
12732
14435
|
stripePublishableKeyValue: "stripePublishableKeyValue",
|
|
12733
14436
|
subject: "subject",
|
|
@@ -26153,6 +27856,12 @@ var Builder = class extends BaseBuilder {
|
|
|
26153
27856
|
data.stripePricingTableId,
|
|
26154
27857
|
options
|
|
26155
27858
|
),
|
|
27859
|
+
stripePricingTableDescriptiveName: this.toAstProperty(
|
|
27860
|
+
bitType,
|
|
27861
|
+
ConfigKey.property_stripePricingTableDescriptiveName,
|
|
27862
|
+
data.stripePricingTableDescriptiveName,
|
|
27863
|
+
options
|
|
27864
|
+
),
|
|
26156
27865
|
stripePublishableKey: this.toAstProperty(
|
|
26157
27866
|
bitType,
|
|
26158
27867
|
ConfigKey.property_stripePublishableKey,
|
|
@@ -34380,6 +36089,7 @@ function buildCards(context, bitType, textFormat, parsedCardSet, statementV1, st
|
|
|
34380
36089
|
const cardSetType = bitConfig.cardSet?.configKey;
|
|
34381
36090
|
switch (cardSetType) {
|
|
34382
36091
|
case CardSetConfigKey.flashcard:
|
|
36092
|
+
case CardSetConfigKey.flashcard1:
|
|
34383
36093
|
case CardSetConfigKey.definitionList:
|
|
34384
36094
|
result = parseFlashcardOrDefinitionList(context, bitType, processedCardSet);
|
|
34385
36095
|
break;
|
|
@@ -34393,6 +36103,7 @@ function buildCards(context, bitType, textFormat, parsedCardSet, statementV1, st
|
|
|
34393
36103
|
result = parseFeedback(context, bitType, processedCardSet);
|
|
34394
36104
|
break;
|
|
34395
36105
|
case CardSetConfigKey.quiz:
|
|
36106
|
+
case CardSetConfigKey.quizResponses:
|
|
34396
36107
|
result = parseQuiz(context, bitType, processedCardSet, choicesV1, responsesV1);
|
|
34397
36108
|
break;
|
|
34398
36109
|
case CardSetConfigKey.questions:
|
|
@@ -34419,6 +36130,7 @@ function buildCards(context, bitType, textFormat, parsedCardSet, statementV1, st
|
|
|
34419
36130
|
break;
|
|
34420
36131
|
case CardSetConfigKey.clozeList:
|
|
34421
36132
|
case CardSetConfigKey.exampleBitList:
|
|
36133
|
+
case CardSetConfigKey.pageFooterSections:
|
|
34422
36134
|
case CardSetConfigKey.bookReferenceList:
|
|
34423
36135
|
result = parseCardBits(context, bitType, textFormat, processedCardSet);
|
|
34424
36136
|
break;
|