@gmb/bitmark-parser-generator 5.21.0 → 5.23.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.
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  BitmarkStringGenerator: () => BitmarkStringGenerator,
32
32
  BitmarkVersion: () => BitmarkVersion,
33
33
  BodyTextFormat: () => BodyTextFormat,
34
+ BoundingBoxIndex: () => BoundingBoxIndex,
34
35
  Builder: () => Builder,
35
36
  CardSetVersion: () => CardSetVersion,
36
37
  InfoFormat: () => InfoFormat,
@@ -326,6 +327,7 @@ var BitType2 = {
326
327
  footNote: "foot-note",
327
328
  formFreeText: "form-free-text",
328
329
  formula: "formula",
330
+ formulaImage: "formula-image",
329
331
  gapText: "gap-text",
330
332
  gapTextInstructionGrouped: "gap-text-instruction-grouped",
331
333
  glossaryTerm: "glossary-term",
@@ -681,6 +683,7 @@ var BitType2 = {
681
683
  vendorPadletEmbed: "vendor-padlet-embed",
682
684
  vendorStripePricingTable: "vendor-stripe-pricing-table",
683
685
  vendorStripePricingTableExternal: "vendor-stripe-pricing-table-external",
686
+ vendorStripePricingTablePrintOnRequest: "vendor-stripe-pricing-table-print-on-request",
684
687
  video: "video",
685
688
  videoEmbed: "video-embed",
686
689
  videoEmbedLandscape: "video-embed-landscape",
@@ -749,8 +752,10 @@ var TagFormat = {
749
752
  // If the value is treated as a boolean
750
753
  invertedBoolean: "invertedBoolean",
751
754
  // If the value is treated as a boolean with the value inverted (e.g. isLongAnswer ==> isShortAnswer = false)
752
- enumeration: "enumeration"
755
+ enumeration: "enumeration",
753
756
  // If the value is treated as an enumeration (the value is a string that must be one of a predefined set of values)
757
+ coordinates: "coordinates"
758
+ // Comma-separated list of 4 numbers (e.g. bounding-box x, y, x1, y1)
754
759
  };
755
760
 
756
761
  // src/model/enum/TextFormat.ts
@@ -835,7 +840,11 @@ var AbstractTagConfig = class {
835
840
  // Default: 0
836
841
  __publicField(this, "chain");
837
842
  __publicField(this, "jsonKey");
838
- // If the json key is different from the tag
843
+ // Legacy string-form jsonKey
844
+ __publicField(this, "exportJsonKey");
845
+ // New JSON-pattern jsonKey (export-only)
846
+ __publicField(this, "hasExportJsonKey");
847
+ // True iff exportJsonKey was explicitly set
839
848
  __publicField(this, "deprecated");
840
849
  this.type = params.type;
841
850
  this.configKey = params.configKey;
@@ -844,6 +853,8 @@ var AbstractTagConfig = class {
844
853
  this.minCount = params.minCount;
845
854
  this.chain = params.chain;
846
855
  this.jsonKey = params.jsonKey;
856
+ this.exportJsonKey = params.exportJsonKey;
857
+ this.hasExportJsonKey = params.hasExportJsonKey;
847
858
  this.deprecated = params.deprecated;
848
859
  }
849
860
  };
@@ -853,7 +864,6 @@ var MarkupTagConfig = class extends AbstractTagConfig {
853
864
  constructor(params) {
854
865
  super({
855
866
  type: BitTagConfigKeyType.tag,
856
- jsonKey: void 0,
857
867
  ...params
858
868
  });
859
869
  __publicField(this, "type", BitTagConfigKeyType.tag);
@@ -965,8 +975,8 @@ var ResourceTagConfig = class extends AbstractTagConfig {
965
975
 
966
976
  // src/model/config/CardVariantConfig.ts
967
977
  var CardVariantConfig = class {
968
- // JSON path for body text
969
- constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey) {
978
+ // Body text format. Default: bitmark++
979
+ constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
970
980
  __publicField(this, "tags");
971
981
  __publicField(this, "bodyAllowed");
972
982
  // Default: true
@@ -976,11 +986,19 @@ var CardVariantConfig = class {
976
986
  // Default: 1
977
987
  // JSON mapping fields
978
988
  __publicField(this, "jsonKey");
989
+ // JSON path for body text (legacy)
990
+ __publicField(this, "exportJsonKey");
991
+ // New JSON-pattern jsonKey
992
+ __publicField(this, "hasExportJsonKey");
993
+ __publicField(this, "format");
979
994
  this.tags = tags2;
980
995
  this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
981
996
  this.bodyRequired = bodyRequired;
982
997
  this.repeatCount = repeatCount;
983
998
  this.jsonKey = jsonKey;
999
+ this.exportJsonKey = exportJsonKey;
1000
+ this.hasExportJsonKey = hasExportJsonKey;
1001
+ this.format = format;
984
1002
  }
985
1003
  toString(options) {
986
1004
  const opts = Object.assign({}, options);
@@ -1004,14 +1022,18 @@ ${tag.toString(opts)}`;
1004
1022
 
1005
1023
  // src/model/config/CardSideConfig.ts
1006
1024
  var CardSideConfig = class {
1007
- constructor(name, repeat, variants, jsonKey) {
1025
+ constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
1008
1026
  __publicField(this, "name");
1009
1027
  __publicField(this, "repeat");
1010
1028
  __publicField(this, "jsonKey");
1029
+ __publicField(this, "exportJsonKey");
1030
+ __publicField(this, "hasExportJsonKey");
1011
1031
  __publicField(this, "variants");
1012
1032
  this.name = name;
1013
1033
  this.repeat = repeat;
1014
1034
  this.jsonKey = jsonKey;
1035
+ this.exportJsonKey = exportJsonKey;
1036
+ this.hasExportJsonKey = hasExportJsonKey;
1015
1037
  this.variants = variants;
1016
1038
  }
1017
1039
  toString(options) {
@@ -1033,13 +1055,17 @@ var CardSideConfig = class {
1033
1055
 
1034
1056
  // src/model/config/CardSetConfig.ts
1035
1057
  var CardSetConfig = class {
1036
- constructor(configKey, jsonKey, sections, sides) {
1058
+ constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
1037
1059
  __publicField(this, "configKey");
1038
1060
  __publicField(this, "jsonKey");
1061
+ __publicField(this, "exportJsonKey");
1062
+ __publicField(this, "hasExportJsonKey");
1039
1063
  __publicField(this, "sections");
1040
1064
  __publicField(this, "sides");
1041
1065
  this.configKey = configKey;
1042
1066
  this.jsonKey = jsonKey;
1067
+ this.exportJsonKey = exportJsonKey;
1068
+ this.hasExportJsonKey = hasExportJsonKey;
1043
1069
  this.sections = sections;
1044
1070
  this.sides = sides;
1045
1071
  }
@@ -1334,6 +1360,7 @@ var propertyKeys = {
1334
1360
  property_formula: "@formula",
1335
1361
  property_fullName: "@fullName",
1336
1362
  property_groupTag: "@groupTag",
1363
+ property_gUri: "@gUri",
1337
1364
  property_handInAcceptFileType: "@handInAcceptFileType",
1338
1365
  property_handInInstruction: "@handInInstruction",
1339
1366
  property_handInRequirement: "@handInRequirement",
@@ -1392,6 +1419,8 @@ var propertyKeys = {
1392
1419
  property_padletId: "@padletId",
1393
1420
  property_page: "@page",
1394
1421
  property_printParentChapterLevel: "@printParentChapterLevel",
1422
+ property_printOnRequestCustomerId: "@printOnRequestCustomerId",
1423
+ property_printOnRequestProductId: "@printOnRequestProductId",
1395
1424
  property_pageNo: "@pageNo",
1396
1425
  property_partialAnswer: "@partialAnswer",
1397
1426
  property_partner: "@partner",
@@ -1467,6 +1496,7 @@ var propertyKeys = {
1467
1496
  property_siteName: "@siteName",
1468
1497
  property_size: "@size",
1469
1498
  property_slug: "@slug",
1499
+ property_sourceBB: "@sourceBB",
1470
1500
  property_sourceDocument: "@sourceDocument",
1471
1501
  property_sourceRL: "@sourceRL",
1472
1502
  property_spaceId: "@spaceId",
@@ -2220,25 +2250,29 @@ var CARDSETS = {
2220
2250
  //
2221
2251
  [CardSetConfigKey.flashcard]: {
2222
2252
  jsonKey: "cards",
2253
+ exportJsonKey: { cards: "$" },
2223
2254
  sides: [
2224
2255
  {
2225
2256
  name: "question",
2226
2257
  variants: [
2227
2258
  {
2228
2259
  jsonKey: "question.text",
2260
+ exportJsonKey: { question: { text: "$" } },
2229
2261
  tags: [
2230
2262
  {
2231
2263
  key: ConfigKey.group_standardTags,
2232
2264
  description: "Standard tags for the flashcard."
2233
2265
  },
2234
2266
  {
2267
+ exportJsonKey: { title: "$" },
2235
2268
  key: ConfigKey.tag_title,
2236
2269
  description: "Title of the flashcard."
2237
2270
  },
2238
2271
  {
2239
2272
  key: ConfigKey.group_resourceIcon,
2240
2273
  description: "Icon resource for the flashcard.",
2241
- jsonKey: "question.icon"
2274
+ jsonKey: "question.icon|resource(type=image, key=image)",
2275
+ exportJsonKey: { question: { icon: { type: "image", image: { src: "$" } } } }
2242
2276
  }
2243
2277
  ]
2244
2278
  }
@@ -2249,36 +2283,45 @@ var CARDSETS = {
2249
2283
  variants: [
2250
2284
  {
2251
2285
  jsonKey: "answer.text",
2286
+ exportJsonKey: { answer: { text: "$" } },
2252
2287
  tags: [
2253
2288
  {
2254
2289
  key: ConfigKey.group_standardTags,
2255
2290
  description: "Standard tags for the flashcard."
2256
2291
  },
2257
2292
  {
2293
+ exportJsonKey: { title: "$" },
2258
2294
  key: ConfigKey.tag_title,
2259
2295
  description: "Title of the flashcard."
2260
2296
  },
2261
2297
  {
2262
2298
  key: ConfigKey.group_resourceIcon,
2263
2299
  description: "Icon resource for the flashcard.",
2264
- jsonKey: "answer.icon"
2300
+ jsonKey: "answer.icon|resource(type=image, key=image)",
2301
+ exportJsonKey: { answer: { icon: { type: "image", image: { src: "$" } } } }
2265
2302
  }
2266
2303
  ]
2267
2304
  },
2268
2305
  {
2269
2306
  jsonKey: "alternativeAnswers[].text",
2307
+ exportJsonKey: { alternativeAnswers: [{ text: "$" }] },
2270
2308
  tags: [
2271
2309
  {
2272
2310
  key: ConfigKey.group_standardTags,
2273
2311
  description: "Standard tags for the flashcard."
2274
2312
  },
2275
2313
  {
2314
+ exportJsonKey: { title: "$" },
2276
2315
  key: ConfigKey.tag_title,
2277
2316
  description: "Title of the flashcard."
2278
2317
  },
2279
2318
  {
2280
2319
  key: ConfigKey.group_resourceIcon,
2281
- description: "Icon resource for the flashcard."
2320
+ description: "Icon resource for the flashcard.",
2321
+ jsonKey: "alternativeAnswers[].icon|resource(type=image, key=image)",
2322
+ exportJsonKey: {
2323
+ alternativeAnswers: [{ icon: { type: "image", image: { src: "$" } } }]
2324
+ }
2282
2325
  }
2283
2326
  ],
2284
2327
  repeatCount: Count.infinity
@@ -2292,12 +2335,14 @@ var CARDSETS = {
2292
2335
  //
2293
2336
  [CardSetConfigKey.definitionList]: {
2294
2337
  jsonKey: "definitions",
2338
+ exportJsonKey: { definitions: "$" },
2295
2339
  sides: [
2296
2340
  {
2297
2341
  name: "term",
2298
2342
  variants: [
2299
2343
  {
2300
2344
  jsonKey: "term.text",
2345
+ exportJsonKey: { term: { text: "$" } },
2301
2346
  tags: [
2302
2347
  {
2303
2348
  key: ConfigKey.group_standardTags,
@@ -2306,12 +2351,16 @@ var CARDSETS = {
2306
2351
  {
2307
2352
  key: ConfigKey.tag_title,
2308
2353
  description: "Title of the definition.",
2309
- jsonKey: "^heading.forKeys"
2354
+ format: TagFormat.plainText,
2355
+ jsonKey: "^heading.forKeys",
2356
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2310
2357
  },
2311
2358
  {
2312
2359
  key: ConfigKey.group_resourceIcon,
2313
2360
  description: "Icon resource for the definition.",
2314
- jsonKey: "term.icon"
2361
+ format: TagFormat.plainText,
2362
+ jsonKey: "term.icon|resource(type=image, key=image)",
2363
+ exportJsonKey: { term: { icon: { type: "image", image: { src: "$" } } } }
2315
2364
  }
2316
2365
  ]
2317
2366
  }
@@ -2322,6 +2371,7 @@ var CARDSETS = {
2322
2371
  variants: [
2323
2372
  {
2324
2373
  jsonKey: "definition.text",
2374
+ exportJsonKey: { definition: { text: "$" } },
2325
2375
  tags: [
2326
2376
  {
2327
2377
  key: ConfigKey.group_standardTags,
@@ -2330,29 +2380,38 @@ var CARDSETS = {
2330
2380
  {
2331
2381
  key: ConfigKey.tag_title,
2332
2382
  description: "Title of the definition.",
2333
- jsonKey: "^heading.forValues"
2383
+ format: TagFormat.plainText,
2384
+ jsonKey: "^heading.forValues",
2385
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2334
2386
  },
2335
2387
  {
2336
2388
  key: ConfigKey.group_resourceIcon,
2337
2389
  description: "Icon resource for the definition.",
2338
- jsonKey: "definition.icon"
2390
+ jsonKey: "definition.icon|resource(type=image, key=image)",
2391
+ exportJsonKey: { definition: { icon: { type: "image", image: { src: "$" } } } }
2339
2392
  }
2340
2393
  ]
2341
2394
  },
2342
2395
  {
2343
2396
  jsonKey: "alternativeDefinitions[].text",
2397
+ exportJsonKey: { alternativeDefinitions: [{ text: "$" }] },
2344
2398
  tags: [
2345
2399
  {
2346
2400
  key: ConfigKey.group_standardTags,
2347
2401
  description: "Standard tags for the definition."
2348
2402
  },
2349
2403
  {
2404
+ exportJsonKey: { title: "$" },
2350
2405
  key: ConfigKey.tag_title,
2351
2406
  description: "Title of the definition."
2352
2407
  },
2353
2408
  {
2354
2409
  key: ConfigKey.group_resourceIcon,
2355
- description: "Icon resource for the definition."
2410
+ description: "Icon resource for the definition.",
2411
+ jsonKey: "alternativeDefinitions[].icon|resource(type=image, key=image)",
2412
+ exportJsonKey: {
2413
+ alternativeDefinitions: [{ icon: { type: "image", image: { src: "$" } } }]
2414
+ }
2356
2415
  }
2357
2416
  ],
2358
2417
  repeatCount: Count.infinity
@@ -2366,12 +2425,14 @@ var CARDSETS = {
2366
2425
  //
2367
2426
  [CardSetConfigKey.matchPairs]: {
2368
2427
  jsonKey: "pairs",
2428
+ exportJsonKey: { pairs: "$" },
2369
2429
  sides: [
2370
2430
  {
2371
2431
  name: "key",
2372
2432
  variants: [
2373
2433
  {
2374
2434
  jsonKey: "key",
2435
+ exportJsonKey: { key: "$" },
2375
2436
  tags: [
2376
2437
  {
2377
2438
  key: ConfigKey.group_standardTags,
@@ -2380,22 +2441,30 @@ var CARDSETS = {
2380
2441
  {
2381
2442
  key: ConfigKey.tag_title,
2382
2443
  description: "Title of the match pair.",
2383
- jsonKey: "^heading.forKeys"
2444
+ format: TagFormat.plainText,
2445
+ jsonKey: "^heading.forKeys",
2446
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2384
2447
  },
2385
2448
  {
2386
2449
  key: ConfigKey.property_isCaseSensitive,
2450
+ exportJsonKey: [
2451
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2452
+ { isCaseSensitive: "$" }
2453
+ ],
2387
2454
  description: "Property to indicate if the match is case sensitive.",
2388
2455
  format: TagFormat.boolean
2389
2456
  },
2390
2457
  {
2391
2458
  key: ConfigKey.resource_audio,
2392
2459
  description: "Audio resource for the match pair.",
2393
- jsonKey: "keyAudio"
2460
+ jsonKey: "keyAudio",
2461
+ exportJsonKey: { keyAudio: "$" }
2394
2462
  },
2395
2463
  {
2396
2464
  key: ConfigKey.resource_image,
2397
2465
  description: "Image resource for the match pair.",
2398
- jsonKey: "keyImage"
2466
+ jsonKey: "keyImage",
2467
+ exportJsonKey: { keyImage: "$" }
2399
2468
  }
2400
2469
  ]
2401
2470
  }
@@ -2407,6 +2476,7 @@ var CARDSETS = {
2407
2476
  variants: [
2408
2477
  {
2409
2478
  jsonKey: "values[]",
2479
+ exportJsonKey: { values: ["$"] },
2410
2480
  tags: [
2411
2481
  {
2412
2482
  key: ConfigKey.group_standardTags,
@@ -2415,10 +2485,16 @@ var CARDSETS = {
2415
2485
  {
2416
2486
  key: ConfigKey.tag_title,
2417
2487
  description: "Title of the match pair.",
2418
- jsonKey: "^heading.forValues"
2488
+ format: TagFormat.plainText,
2489
+ jsonKey: "^heading.forValues",
2490
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2419
2491
  },
2420
2492
  {
2421
2493
  key: ConfigKey.property_isCaseSensitive,
2494
+ exportJsonKey: [
2495
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2496
+ { isCaseSensitive: "$" }
2497
+ ],
2422
2498
  description: "Property to indicate if the match is case sensitive.",
2423
2499
  format: TagFormat.boolean
2424
2500
  }
@@ -2434,12 +2510,14 @@ var CARDSETS = {
2434
2510
  //
2435
2511
  [CardSetConfigKey.matchAudioPairs]: {
2436
2512
  jsonKey: "pairs",
2513
+ exportJsonKey: { pairs: "$" },
2437
2514
  sides: [
2438
2515
  {
2439
2516
  name: "key",
2440
2517
  variants: [
2441
2518
  {
2442
2519
  jsonKey: "key",
2520
+ exportJsonKey: { key: "$" },
2443
2521
  tags: [
2444
2522
  {
2445
2523
  key: ConfigKey.group_standardTags,
@@ -2448,12 +2526,15 @@ var CARDSETS = {
2448
2526
  {
2449
2527
  key: ConfigKey.tag_title,
2450
2528
  description: "Title of the audio match pair.",
2451
- jsonKey: "^heading.forKeys"
2529
+ format: TagFormat.plainText,
2530
+ jsonKey: "^heading.forKeys",
2531
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2452
2532
  },
2453
2533
  {
2454
2534
  key: ConfigKey.resource_audio,
2455
2535
  description: "Audio resource for the match pair.",
2456
- jsonKey: "keyAudio"
2536
+ jsonKey: "keyAudio",
2537
+ exportJsonKey: { keyAudio: "$" }
2457
2538
  }
2458
2539
  ]
2459
2540
  }
@@ -2465,6 +2546,7 @@ var CARDSETS = {
2465
2546
  variants: [
2466
2547
  {
2467
2548
  jsonKey: "values[]",
2549
+ exportJsonKey: { values: ["$"] },
2468
2550
  tags: [
2469
2551
  {
2470
2552
  key: ConfigKey.group_standardTags,
@@ -2473,7 +2555,9 @@ var CARDSETS = {
2473
2555
  {
2474
2556
  key: ConfigKey.tag_title,
2475
2557
  description: "Title of the audio match pair.",
2476
- jsonKey: "^heading.forValues"
2558
+ format: TagFormat.plainText,
2559
+ jsonKey: "^heading.forValues",
2560
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2477
2561
  },
2478
2562
  {
2479
2563
  key: ConfigKey.resource_audio,
@@ -2491,12 +2575,14 @@ var CARDSETS = {
2491
2575
  //
2492
2576
  [CardSetConfigKey.matchImagePairs]: {
2493
2577
  jsonKey: "pairs",
2578
+ exportJsonKey: { pairs: "$" },
2494
2579
  sides: [
2495
2580
  {
2496
2581
  name: "key",
2497
2582
  variants: [
2498
2583
  {
2499
2584
  jsonKey: "key",
2585
+ exportJsonKey: { key: "$" },
2500
2586
  tags: [
2501
2587
  {
2502
2588
  key: ConfigKey.group_standardTags,
@@ -2505,12 +2591,15 @@ var CARDSETS = {
2505
2591
  {
2506
2592
  key: ConfigKey.tag_title,
2507
2593
  description: "Title of the image match pair.",
2508
- jsonKey: "^heading.forKeys"
2594
+ format: TagFormat.plainText,
2595
+ jsonKey: "^heading.forKeys",
2596
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2509
2597
  },
2510
2598
  {
2511
2599
  key: ConfigKey.resource_image,
2512
2600
  description: "Image resource for the match pair.",
2513
- jsonKey: "keyImage"
2601
+ jsonKey: "keyImage",
2602
+ exportJsonKey: { keyImage: "$" }
2514
2603
  }
2515
2604
  ]
2516
2605
  }
@@ -2522,6 +2611,7 @@ var CARDSETS = {
2522
2611
  variants: [
2523
2612
  {
2524
2613
  jsonKey: "values[]",
2614
+ exportJsonKey: { values: ["$"] },
2525
2615
  tags: [
2526
2616
  {
2527
2617
  key: ConfigKey.group_standardTags,
@@ -2530,7 +2620,9 @@ var CARDSETS = {
2530
2620
  {
2531
2621
  key: ConfigKey.tag_title,
2532
2622
  description: "Title of the image match pair.",
2533
- jsonKey: "^heading.forValues"
2623
+ format: TagFormat.plainText,
2624
+ jsonKey: "^heading.forValues",
2625
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2534
2626
  },
2535
2627
  {
2536
2628
  key: ConfigKey.resource_image,
@@ -2548,12 +2640,14 @@ var CARDSETS = {
2548
2640
  //
2549
2641
  [CardSetConfigKey.matchMatrix]: {
2550
2642
  jsonKey: "matrix",
2643
+ exportJsonKey: { matrix: "$" },
2551
2644
  sides: [
2552
2645
  {
2553
2646
  name: "key",
2554
2647
  variants: [
2555
2648
  {
2556
2649
  jsonKey: "key",
2650
+ exportJsonKey: { key: "$" },
2557
2651
  tags: [
2558
2652
  {
2559
2653
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2561,16 +2655,27 @@ var CARDSETS = {
2561
2655
  },
2562
2656
  {
2563
2657
  key: ConfigKey.property_example,
2658
+ exportJsonKey: [
2659
+ { "@keyonly": { isExample: true, "@bit": { isExample: true } } },
2660
+ { "@absent": { isExample: true, "@bit": { isExample: true } } },
2661
+ { isExample: true, example: "$", "@bit": { isExample: true } }
2662
+ ],
2564
2663
  description: "Example text for the match matrix.",
2565
2664
  format: TagFormat.plainText
2566
2665
  },
2567
2666
  {
2568
2667
  key: ConfigKey.tag_title,
2569
2668
  description: "Title of the match matrix.",
2570
- jsonKey: "^heading.forKeys"
2669
+ format: TagFormat.plainText,
2670
+ jsonKey: "^heading.forKeys",
2671
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2571
2672
  },
2572
2673
  {
2573
2674
  key: ConfigKey.property_isCaseSensitive,
2675
+ exportJsonKey: [
2676
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2677
+ { isCaseSensitive: "$" }
2678
+ ],
2574
2679
  description: "Property to indicate if the match is case sensitive.",
2575
2680
  format: TagFormat.boolean
2576
2681
  }
@@ -2584,6 +2689,7 @@ var CARDSETS = {
2584
2689
  variants: [
2585
2690
  {
2586
2691
  jsonKey: "cells[{s}].values[]",
2692
+ exportJsonKey: { cells: { $s: { values: ["$"] } } },
2587
2693
  tags: [
2588
2694
  {
2589
2695
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2591,16 +2697,34 @@ var CARDSETS = {
2591
2697
  },
2592
2698
  {
2593
2699
  key: ConfigKey.property_example,
2700
+ exportJsonKey: [
2701
+ {
2702
+ "@keyonly": {
2703
+ cells: { $s: { isExample: true, example: "$parent.values[0]" } },
2704
+ "@bit": { isExample: true }
2705
+ }
2706
+ },
2707
+ {
2708
+ "@absent": { cells: { $s: { isExample: true, example: "$parent.values[0]" } } }
2709
+ },
2710
+ { cells: { $s: { isExample: true, example: "$" } }, "@bit": { isExample: true } }
2711
+ ],
2594
2712
  description: "Example text for the match matrix.",
2595
2713
  format: TagFormat.plainText
2596
2714
  },
2597
2715
  {
2598
2716
  key: ConfigKey.tag_title,
2599
2717
  description: "Title of the match matrix.",
2600
- jsonKey: "^heading.forValues"
2718
+ format: TagFormat.plainText,
2719
+ jsonKey: "^heading.forValues",
2720
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2601
2721
  },
2602
2722
  {
2603
2723
  key: ConfigKey.property_isCaseSensitive,
2724
+ exportJsonKey: [
2725
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2726
+ { isCaseSensitive: "$" }
2727
+ ],
2604
2728
  description: "Property to indicate if the match is case sensitive.",
2605
2729
  format: TagFormat.boolean
2606
2730
  }
@@ -2616,23 +2740,27 @@ var CARDSETS = {
2616
2740
  //
2617
2741
  [CardSetConfigKey.statements]: {
2618
2742
  jsonKey: "statements",
2743
+ exportJsonKey: { statements: "$" },
2619
2744
  sides: [
2620
2745
  {
2621
2746
  name: "statement",
2622
2747
  variants: [
2623
2748
  {
2624
2749
  jsonKey: "statement",
2750
+ exportJsonKey: { statement: "$" },
2625
2751
  tags: [
2626
2752
  {
2627
2753
  key: ConfigKey.tag_true,
2628
2754
  description: "Tag for true statements.",
2629
2755
  jsonKey: "statement|set(isCorrect=true)",
2756
+ exportJsonKey: { statement: "$", isCorrect: true },
2630
2757
  maxCount: 1
2631
2758
  },
2632
2759
  {
2633
2760
  key: ConfigKey.tag_false,
2634
2761
  description: "Tag for false statements.",
2635
2762
  jsonKey: "statement|set(isCorrect=false)",
2763
+ exportJsonKey: { statement: "$", isCorrect: false },
2636
2764
  maxCount: 1
2637
2765
  },
2638
2766
  {
@@ -2651,6 +2779,7 @@ var CARDSETS = {
2651
2779
  //
2652
2780
  [CardSetConfigKey.quiz]: {
2653
2781
  jsonKey: "quizzes",
2782
+ exportJsonKey: { quizzes: "$" },
2654
2783
  sides: [
2655
2784
  {
2656
2785
  name: "choices",
@@ -2678,6 +2807,7 @@ var CARDSETS = {
2678
2807
  //
2679
2808
  [CardSetConfigKey.feedback]: {
2680
2809
  jsonKey: "feedbacks",
2810
+ exportJsonKey: { feedbacks: "$" },
2681
2811
  sides: [
2682
2812
  {
2683
2813
  name: "choices",
@@ -2696,7 +2826,9 @@ var CARDSETS = {
2696
2826
  {
2697
2827
  key: ConfigKey.tag_title,
2698
2828
  description: "Title of the feedback.",
2699
- jsonKey: "^heading.forKeys"
2829
+ format: TagFormat.plainText,
2830
+ jsonKey: "^heading.forKeys",
2831
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2700
2832
  }
2701
2833
  ],
2702
2834
  bodyAllowed: false
@@ -2708,6 +2840,7 @@ var CARDSETS = {
2708
2840
  variants: [
2709
2841
  {
2710
2842
  jsonKey: "reason.text",
2843
+ exportJsonKey: { reason: { text: "$" } },
2711
2844
  tags: [
2712
2845
  {
2713
2846
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2715,18 +2848,29 @@ var CARDSETS = {
2715
2848
  },
2716
2849
  {
2717
2850
  key: ConfigKey.property_reasonableNumOfChars,
2851
+ exportJsonKey: [
2852
+ { "@absent": { reasonableNumOfChars: "$ancestor" } },
2853
+ { reasonableNumOfChars: "$" }
2854
+ ],
2718
2855
  description: "Property for reasonable number of characters.",
2719
2856
  format: TagFormat.number
2720
2857
  },
2721
2858
  {
2722
2859
  key: ConfigKey.property_example,
2860
+ exportJsonKey: [
2861
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
2862
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
2863
+ { isExample: true, example: "$", "@bit": { isExample: true } }
2864
+ ],
2723
2865
  description: "Example text for the feedback.",
2724
2866
  format: TagFormat.plainText
2725
2867
  },
2726
2868
  {
2727
2869
  key: ConfigKey.tag_title,
2728
2870
  description: "Title of the feedback.",
2729
- jsonKey: "^heading.forValues"
2871
+ format: TagFormat.plainText,
2872
+ jsonKey: "^heading.forValues",
2873
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2730
2874
  }
2731
2875
  ],
2732
2876
  bodyAllowed: true
@@ -2740,21 +2884,29 @@ var CARDSETS = {
2740
2884
  //
2741
2885
  [CardSetConfigKey.questions]: {
2742
2886
  jsonKey: "questions",
2887
+ exportJsonKey: { questions: "$" },
2743
2888
  sides: [
2744
2889
  {
2745
2890
  name: "question",
2746
2891
  variants: [
2747
2892
  {
2748
2893
  jsonKey: "question",
2894
+ exportJsonKey: { question: "$" },
2749
2895
  tags: [
2750
2896
  {
2751
2897
  key: ConfigKey.property_reasonableNumOfChars,
2898
+ exportJsonKey: [
2899
+ { "@absent": { reasonableNumOfChars: "$ancestor" } },
2900
+ { reasonableNumOfChars: "$" }
2901
+ ],
2752
2902
  description: "Property for reasonable number of characters.",
2753
2903
  format: TagFormat.number
2754
2904
  },
2755
2905
  {
2906
+ exportJsonKey: { sampleSolution: "$" },
2756
2907
  key: ConfigKey.tag_sampleSolution,
2757
- description: "Sample solution for the question."
2908
+ description: "Sample solution for the question.",
2909
+ format: TagFormat.plainText
2758
2910
  },
2759
2911
  {
2760
2912
  key: ConfigKey.property_sampleSolution,
@@ -2794,6 +2946,7 @@ var CARDSETS = {
2794
2946
  variants: [
2795
2947
  {
2796
2948
  jsonKey: "elements[]",
2949
+ exportJsonKey: { elements: ["$"] },
2797
2950
  tags: [
2798
2951
  {
2799
2952
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2801,6 +2954,11 @@ var CARDSETS = {
2801
2954
  },
2802
2955
  {
2803
2956
  key: ConfigKey.property_example,
2957
+ exportJsonKey: [
2958
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
2959
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
2960
+ { isExample: true, example: "$", "@bit": { isExample: true } }
2961
+ ],
2804
2962
  description: "Example text for the element.",
2805
2963
  format: TagFormat.plainText
2806
2964
  }
@@ -2816,6 +2974,7 @@ var CARDSETS = {
2816
2974
  //
2817
2975
  [CardSetConfigKey.table]: {
2818
2976
  jsonKey: "table.data",
2977
+ exportJsonKey: { table: { data: "$" } },
2819
2978
  sides: [
2820
2979
  {
2821
2980
  name: "cell",
@@ -2831,6 +2990,7 @@ var CARDSETS = {
2831
2990
  {
2832
2991
  key: ConfigKey.tag_title,
2833
2992
  jsonKey: "^table.columns[]",
2993
+ exportJsonKey: { "@bit": { table: { columns: ["$"] } } },
2834
2994
  description: "Title of the table."
2835
2995
  },
2836
2996
  {
@@ -2871,18 +3031,34 @@ var CARDSETS = {
2871
3031
  [CardSetConfigKey.tableExtended]: {
2872
3032
  jsonKey: null,
2873
3033
  sections: {
2874
- "table-header": { jsonKey: "table.header.rows", sideJsonKey: "cells[{s}]|set(title=true)" },
2875
- "table-body": { jsonKey: "table.body.rows", isDefault: true },
2876
- "table-footer": { jsonKey: "table.footer.rows", sideJsonKey: "cells[{s}]|set(title=true)" }
3034
+ "table-header": {
3035
+ jsonKey: "table.header.rows",
3036
+ exportJsonKey: { table: { header: { rows: "$" } } },
3037
+ sideJsonKey: "cells[{s}]|set(title=true)",
3038
+ sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
3039
+ },
3040
+ "table-body": {
3041
+ jsonKey: "table.body.rows",
3042
+ exportJsonKey: { table: { body: { rows: "$" } } },
3043
+ isDefault: true
3044
+ },
3045
+ "table-footer": {
3046
+ jsonKey: "table.footer.rows",
3047
+ exportJsonKey: { table: { footer: { rows: "$" } } },
3048
+ sideJsonKey: "cells[{s}]|set(title=true)",
3049
+ sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
3050
+ }
2877
3051
  },
2878
3052
  sides: [
2879
3053
  {
2880
3054
  name: "cell",
2881
3055
  repeat: true,
2882
3056
  jsonKey: "cells[{s}]",
3057
+ exportJsonKey: { cells: { $s: "$" } },
2883
3058
  variants: [
2884
3059
  {
2885
3060
  jsonKey: "content",
3061
+ exportJsonKey: { content: "$" },
2886
3062
  tags: [
2887
3063
  {
2888
3064
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2891,29 +3067,38 @@ var CARDSETS = {
2891
3067
  {
2892
3068
  key: ConfigKey.tag_title,
2893
3069
  jsonKey: ".",
3070
+ exportJsonKey: {
3071
+ "@bit": {
3072
+ table: { header: { rows: { cells: { cells: { $s: { content: "$" } } } } } }
3073
+ }
3074
+ },
2894
3075
  description: "Title of the table cell."
2895
3076
  },
2896
3077
  {
2897
3078
  key: ConfigKey.property_tableCellType,
2898
3079
  jsonKey: "title|bool(th)",
3080
+ exportJsonKey: [{ "@value=th": { title: true } }],
2899
3081
  description: "Table cell type (th/td).",
2900
3082
  format: TagFormat.plainText
2901
3083
  },
2902
3084
  {
2903
3085
  key: ConfigKey.property_tableRowSpan,
2904
3086
  jsonKey: "rowspan",
3087
+ exportJsonKey: { rowspan: "$" },
2905
3088
  description: "Number of rows the cell spans.",
2906
3089
  format: TagFormat.number
2907
3090
  },
2908
3091
  {
2909
3092
  key: ConfigKey.property_tableColSpan,
2910
3093
  jsonKey: "colspan",
3094
+ exportJsonKey: { colspan: "$" },
2911
3095
  description: "Number of columns the cell spans.",
2912
3096
  format: TagFormat.number
2913
3097
  },
2914
3098
  {
2915
3099
  key: ConfigKey.property_tableScope,
2916
3100
  jsonKey: "scope",
3101
+ exportJsonKey: { scope: "$" },
2917
3102
  description: "Scope attribute for header cells.",
2918
3103
  format: TagFormat.plainText
2919
3104
  },
@@ -2934,6 +3119,7 @@ var CARDSETS = {
2934
3119
  //
2935
3120
  [CardSetConfigKey.pronunciationTable]: {
2936
3121
  jsonKey: "pronunciationTable.data",
3122
+ exportJsonKey: { pronunciationTable: { data: "$" } },
2937
3123
  sides: [
2938
3124
  {
2939
3125
  name: "cell",
@@ -2941,12 +3127,14 @@ var CARDSETS = {
2941
3127
  variants: [
2942
3128
  {
2943
3129
  jsonKey: "body",
3130
+ exportJsonKey: { body: "$" },
2944
3131
  tags: [
2945
3132
  {
2946
3133
  key: ConfigKey.group_standardItemLeadInstructionHint,
2947
3134
  description: "Standard tags for lead, instruction, and hint."
2948
3135
  },
2949
3136
  {
3137
+ exportJsonKey: { title: "$" },
2950
3138
  key: ConfigKey.tag_title,
2951
3139
  description: "Title of the pronunciation table."
2952
3140
  },
@@ -2967,12 +3155,15 @@ var CARDSETS = {
2967
3155
  //
2968
3156
  [CardSetConfigKey.botActionResponses]: {
2969
3157
  jsonKey: "responses",
3158
+ exportJsonKey: { responses: "$" },
2970
3159
  sides: [
2971
3160
  {
2972
3161
  name: "response",
2973
3162
  variants: [
2974
3163
  {
2975
3164
  jsonKey: "feedback",
3165
+ exportJsonKey: { feedback: "$" },
3166
+ format: TextFormat2.plainText,
2976
3167
  tags: [
2977
3168
  {
2978
3169
  key: ConfigKey.property_reaction,
@@ -2980,16 +3171,53 @@ var CARDSETS = {
2980
3171
  format: TagFormat.plainText
2981
3172
  },
2982
3173
  {
2983
- key: ConfigKey.group_standardItemLead,
2984
- description: "Item, lead, page number, and margin number for the bot action response."
3174
+ key: ConfigKey.tag_item,
3175
+ jsonKey: "item",
3176
+ exportJsonKey: { item: "$" },
3177
+ format: TagFormat.plainText,
3178
+ description: "The item for the bit",
3179
+ chain: [
3180
+ {
3181
+ key: ConfigKey.tag_item,
3182
+ jsonKey: "lead",
3183
+ exportJsonKey: { lead: "$" },
3184
+ description: "The lead for the bit",
3185
+ maxCount: 1,
3186
+ chain: [
3187
+ {
3188
+ key: ConfigKey.tag_item,
3189
+ jsonKey: "pageNumber",
3190
+ exportJsonKey: { pageNumber: "$" },
3191
+ description: "The page number for the bit",
3192
+ maxCount: 1,
3193
+ chain: [
3194
+ {
3195
+ key: ConfigKey.tag_item,
3196
+ jsonKey: "marginNumber",
3197
+ exportJsonKey: { marginNumber: "$" },
3198
+ description: "The margin number for the bit",
3199
+ maxCount: 1
3200
+ }
3201
+ ]
3202
+ }
3203
+ ]
3204
+ }
3205
+ ]
2985
3206
  },
2986
3207
  {
2987
3208
  key: ConfigKey.tag_instruction,
2988
3209
  description: "The response label for the bot action.",
2989
- jsonKey: "response"
3210
+ jsonKey: "response",
3211
+ exportJsonKey: { response: "$" },
3212
+ format: TagFormat.plainText
2990
3213
  },
2991
3214
  {
2992
3215
  key: ConfigKey.property_example,
3216
+ exportJsonKey: [
3217
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
3218
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
3219
+ { isExample: true, example: "$", "@bit": { isExample: true } }
3220
+ ],
2993
3221
  description: "Example text for the bot action response.",
2994
3222
  format: TagFormat.plainText
2995
3223
  }
@@ -3004,12 +3232,14 @@ var CARDSETS = {
3004
3232
  //
3005
3233
  [CardSetConfigKey.clozeList]: {
3006
3234
  jsonKey: "listItems",
3235
+ exportJsonKey: { listItems: "$" },
3007
3236
  sides: [
3008
3237
  {
3009
3238
  name: "content",
3010
3239
  variants: [
3011
3240
  {
3012
3241
  jsonKey: "body",
3242
+ exportJsonKey: { body: "$" },
3013
3243
  tags: [
3014
3244
  {
3015
3245
  key: ConfigKey.group_standardTags,
@@ -3030,18 +3260,21 @@ var CARDSETS = {
3030
3260
  //
3031
3261
  [CardSetConfigKey.exampleBitList]: {
3032
3262
  jsonKey: "listItems",
3263
+ exportJsonKey: { listItems: "$" },
3033
3264
  sides: [
3034
3265
  {
3035
3266
  name: "item",
3036
3267
  variants: [
3037
3268
  {
3038
3269
  jsonKey: "body",
3270
+ exportJsonKey: { body: "$" },
3039
3271
  tags: [
3040
3272
  {
3041
3273
  key: ConfigKey.group_standardTags,
3042
3274
  description: "Standard tags for example bits."
3043
3275
  },
3044
3276
  {
3277
+ exportJsonKey: { title: "$" },
3045
3278
  key: ConfigKey.tag_title,
3046
3279
  description: "Title of the example bit."
3047
3280
  }
@@ -3056,28 +3289,35 @@ var CARDSETS = {
3056
3289
  //
3057
3290
  [CardSetConfigKey.ingredients]: {
3058
3291
  jsonKey: "ingredients",
3292
+ exportJsonKey: { ingredients: "$" },
3059
3293
  sides: [
3060
3294
  {
3061
3295
  name: "ingredient",
3062
3296
  variants: [
3063
3297
  {
3064
3298
  jsonKey: "ingredient",
3299
+ exportJsonKey: { ingredient: "$" },
3065
3300
  tags: [
3066
3301
  {
3302
+ exportJsonKey: { title: "$" },
3067
3303
  key: ConfigKey.tag_title,
3068
3304
  description: "Title of the ingredient."
3069
3305
  },
3070
3306
  {
3071
3307
  key: ConfigKey.tag_true,
3072
3308
  description: "Checked state for the ingredient.",
3073
- jsonKey: "ingredient|set(checked=true)",
3309
+ jsonKey: "|set(checked=true)",
3310
+ exportJsonKey: { checked: true, $: "$" },
3074
3311
  maxCount: 1
3312
+ // nullable: true,
3075
3313
  },
3076
3314
  {
3077
3315
  key: ConfigKey.tag_false,
3078
3316
  description: "Unchecked state for the ingredient.",
3079
- jsonKey: "ingredient|set(checked=false)",
3317
+ jsonKey: "|set(checked=false)",
3318
+ exportJsonKey: { checked: false, $: "$" },
3080
3319
  maxCount: 1
3320
+ // nullable: true,
3081
3321
  },
3082
3322
  {
3083
3323
  key: ConfigKey.group_standardItemLead,
@@ -3086,9 +3326,12 @@ var CARDSETS = {
3086
3326
  {
3087
3327
  key: ConfigKey.tag_instruction,
3088
3328
  description: "The quantity of the ingredient.",
3089
- jsonKey: "quantity"
3329
+ jsonKey: "quantity",
3330
+ exportJsonKey: { quantity: "$" },
3331
+ format: TagFormat.number
3090
3332
  },
3091
3333
  {
3334
+ exportJsonKey: { hint: "$" },
3092
3335
  key: ConfigKey.tag_hint,
3093
3336
  description: "The hint for the ingredient."
3094
3337
  },
@@ -3124,6 +3367,7 @@ var CARDSETS = {
3124
3367
  //
3125
3368
  [CardSetConfigKey.bookReferenceList]: {
3126
3369
  jsonKey: "bookReferences",
3370
+ exportJsonKey: { bookReferences: "$" },
3127
3371
  sides: [
3128
3372
  {
3129
3373
  name: "reference",
@@ -3183,6 +3427,11 @@ var GROUPS = {
3183
3427
  format: TagFormat.plainText,
3184
3428
  maxCount: Count.infinity
3185
3429
  },
3430
+ {
3431
+ key: ConfigKey.property_gUri,
3432
+ description: "Global URI for the bit",
3433
+ format: TagFormat.plainText
3434
+ },
3186
3435
  {
3187
3436
  key: ConfigKey.property_customerId,
3188
3437
  description: "The customer-specific identifier for the bit",
@@ -3366,12 +3615,14 @@ var GROUPS = {
3366
3615
  {
3367
3616
  key: ConfigKey.property_groupTag,
3368
3617
  jsonKey: "groupTag.name",
3618
+ exportJsonKey: { groupTag: { name: "$" } },
3369
3619
  description: "The group tag(s) for the bit",
3370
3620
  format: TagFormat.plainText,
3371
3621
  maxCount: Count.infinity,
3372
3622
  chain: [
3373
3623
  {
3374
3624
  key: ConfigKey.property_tag,
3625
+ exportJsonKey: { tags: ["$"] },
3375
3626
  description: "The tag(s) for the group",
3376
3627
  format: TagFormat.plainText,
3377
3628
  maxCount: Count.infinity
@@ -3402,6 +3653,12 @@ var GROUPS = {
3402
3653
  format: TagFormat.plainText,
3403
3654
  maxCount: Count.infinity
3404
3655
  },
3656
+ {
3657
+ key: ConfigKey.property_sourceBB,
3658
+ description: "The source bounding box(es) for the bit (x, y, x1, y1)",
3659
+ format: TagFormat.coordinates,
3660
+ maxCount: Count.infinity
3661
+ },
3405
3662
  {
3406
3663
  key: ConfigKey.property_levelCEFRp,
3407
3664
  description: "The CEFRp level for the bit",
@@ -3439,8 +3696,10 @@ var GROUPS = {
3439
3696
  maxCount: Count.infinity
3440
3697
  },
3441
3698
  {
3699
+ exportJsonKey: { anchor: "$" },
3442
3700
  key: ConfigKey.tag_anchor,
3443
3701
  name: "Anchor",
3702
+ format: TagFormat.plainText,
3444
3703
  description: "The anchor for the bit"
3445
3704
  },
3446
3705
  {
@@ -3475,23 +3734,27 @@ var GROUPS = {
3475
3734
  {
3476
3735
  key: ConfigKey.tag_item,
3477
3736
  jsonKey: "item",
3737
+ exportJsonKey: { item: "$" },
3478
3738
  description: "The item for the bit",
3479
3739
  chain: [
3480
3740
  {
3481
3741
  key: ConfigKey.tag_item,
3482
3742
  jsonKey: "lead",
3743
+ exportJsonKey: { lead: "$" },
3483
3744
  description: "The lead for the bit",
3484
3745
  maxCount: 1,
3485
3746
  chain: [
3486
3747
  {
3487
3748
  key: ConfigKey.tag_item,
3488
3749
  jsonKey: "pageNumber",
3750
+ exportJsonKey: { pageNumber: "$" },
3489
3751
  description: "The page number for the bit",
3490
3752
  maxCount: 1,
3491
3753
  chain: [
3492
3754
  {
3493
3755
  key: ConfigKey.tag_item,
3494
3756
  jsonKey: "marginNumber",
3757
+ exportJsonKey: { marginNumber: "$" },
3495
3758
  description: "The margin number for the bit",
3496
3759
  maxCount: 1
3497
3760
  }
@@ -3512,11 +3775,13 @@ var GROUPS = {
3512
3775
  description: "Item, lead, page number, and margin number tags"
3513
3776
  },
3514
3777
  {
3778
+ exportJsonKey: { instruction: "$" },
3515
3779
  key: ConfigKey.tag_instruction,
3516
3780
  name: "Instruction",
3517
3781
  description: "The instruction for the bit"
3518
3782
  },
3519
3783
  {
3784
+ exportJsonKey: { hint: "$" },
3520
3785
  key: ConfigKey.tag_hint,
3521
3786
  name: "Hint",
3522
3787
  description: "The hint for the bit"
@@ -3536,9 +3801,17 @@ var GROUPS = {
3536
3801
  description: "Item, lead, page number, margin number, instruction and hint tags"
3537
3802
  },
3538
3803
  {
3804
+ // Bit-level example tag: bare/synthesized records the marker only;
3805
+ // valued [@example:text] emits `isExample: true` and `example` as
3806
+ // PM-rendered rich text (bitmark+ format).
3539
3807
  key: ConfigKey.property_example,
3808
+ exportJsonKey: [
3809
+ { "@keyonly": { isExample: true } },
3810
+ { "@absent": { isExample: true } },
3811
+ { isExample: true, example: "$" }
3812
+ ],
3540
3813
  description: "The example(s) for the bit",
3541
- format: TagFormat.plainText
3814
+ format: TagFormat.bitmarkText
3542
3815
  }
3543
3816
  ]
3544
3817
  },
@@ -3549,6 +3822,7 @@ var GROUPS = {
3549
3822
  {
3550
3823
  key: ConfigKey.property_imageSource,
3551
3824
  jsonKey: "imageSource.url",
3825
+ exportJsonKey: { imageSource: { url: "$" } },
3552
3826
  description: "The source of an image",
3553
3827
  format: TagFormat.plainText,
3554
3828
  chain: [
@@ -3583,6 +3857,7 @@ var GROUPS = {
3583
3857
  {
3584
3858
  key: ConfigKey.property_technicalTerm,
3585
3859
  jsonKey: "technicalTerm.technicalTerm",
3860
+ exportJsonKey: { technicalTerm: { technicalTerm: "$" } },
3586
3861
  description: "The technical term",
3587
3862
  format: TagFormat.plainText,
3588
3863
  chain: [
@@ -3601,7 +3876,8 @@ var GROUPS = {
3601
3876
  tags: [
3602
3877
  {
3603
3878
  key: ConfigKey.property_person,
3604
- jsonKey: "person.name",
3879
+ jsonKey: "partner.name",
3880
+ exportJsonKey: { partner: { name: "$" } },
3605
3881
  description: "A person",
3606
3882
  format: TagFormat.plainText,
3607
3883
  chain: [
@@ -3612,6 +3888,8 @@ var GROUPS = {
3612
3888
  },
3613
3889
  {
3614
3890
  key: ConfigKey.group_resourceImage,
3891
+ jsonKey: "avatarImage|resource(type=image, key=image)",
3892
+ exportJsonKey: { avatarImage: { type: "image", image: { src: "$" } } },
3615
3893
  description: "The image of the person"
3616
3894
  }
3617
3895
  ]
@@ -3620,6 +3898,7 @@ var GROUPS = {
3620
3898
  // Deprecated (parter renamed to person)
3621
3899
  key: ConfigKey.property_partner,
3622
3900
  jsonKey: "partner.name",
3901
+ exportJsonKey: { partner: { name: "$" } },
3623
3902
  description: "A partner",
3624
3903
  format: TagFormat.plainText,
3625
3904
  chain: [
@@ -3630,6 +3909,8 @@ var GROUPS = {
3630
3909
  },
3631
3910
  {
3632
3911
  key: ConfigKey.group_resourceImage,
3912
+ jsonKey: "avatarImage|resource(type=image, key=image)",
3913
+ exportJsonKey: { avatarImage: { type: "image", image: { src: "$" } } },
3633
3914
  description: "The image of the partner"
3634
3915
  }
3635
3916
  ]
@@ -3641,15 +3922,19 @@ var GROUPS = {
3641
3922
  description: "Gap chain",
3642
3923
  tags: [
3643
3924
  {
3925
+ exportJsonKey: { solutions: [["$"]] },
3644
3926
  key: ConfigKey.tag_gap,
3645
3927
  description: "The value of a gap in the content",
3646
3928
  maxCount: Count.infinity,
3929
+ format: TagFormat.plainText,
3647
3930
  chain: [
3648
3931
  {
3649
3932
  key: ConfigKey.tag_gap,
3650
3933
  jsonKey: "solutions[]",
3934
+ exportJsonKey: { solutions: ["$"] },
3651
3935
  description: "Alternative values for the gaps in the content",
3652
- maxCount: Count.infinity
3936
+ maxCount: Count.infinity,
3937
+ format: TagFormat.plainText
3653
3938
  },
3654
3939
  {
3655
3940
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -3658,12 +3943,33 @@ var GROUPS = {
3658
3943
  {
3659
3944
  key: ConfigKey.property_example,
3660
3945
  jsonKey: "example",
3946
+ exportJsonKey: [
3947
+ {
3948
+ "@keyonly": {
3949
+ isExample: true,
3950
+ example: "$parent.solutions[0]",
3951
+ "@bit": { isExample: true }
3952
+ }
3953
+ },
3954
+ {
3955
+ "@absent": {
3956
+ isExample: true,
3957
+ example: "$parent.solutions[0]",
3958
+ "@bit": { isExample: true }
3959
+ }
3960
+ },
3961
+ { isExample: true, example: "$", "@bit": { isExample: true } }
3962
+ ],
3661
3963
  description: "An example for the gap",
3662
- format: TagFormat.plainText
3964
+ format: TagFormat.bitmarkText
3663
3965
  },
3664
3966
  {
3665
3967
  key: ConfigKey.property_isCaseSensitive,
3666
3968
  jsonKey: "isCaseSensitive",
3969
+ exportJsonKey: [
3970
+ { "@absent": { isCaseSensitive: "$ancestor" } },
3971
+ { isCaseSensitive: "$" }
3972
+ ],
3667
3973
  description: "If true, the gap text is case sensitive",
3668
3974
  format: TagFormat.boolean,
3669
3975
  defaultValue: "true"
@@ -3677,21 +3983,27 @@ var GROUPS = {
3677
3983
  description: "True/False chain",
3678
3984
  tags: [
3679
3985
  {
3986
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
3680
3987
  key: ConfigKey.tag_true,
3681
3988
  description: "True value for a true/false statement/question",
3682
3989
  maxCount: Count.infinity,
3990
+ format: TagFormat.plainText,
3683
3991
  chain: [
3684
3992
  {
3685
3993
  key: ConfigKey.tag_true,
3686
3994
  jsonKey: "choices[]|set(isCorrect=true)",
3995
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
3687
3996
  description: "True values for a true/false statement/question",
3688
- maxCount: Count.infinity
3997
+ maxCount: Count.infinity,
3998
+ format: TagFormat.plainText
3689
3999
  },
3690
4000
  {
3691
4001
  key: ConfigKey.tag_false,
3692
4002
  jsonKey: "choices[]|set(isCorrect=false)",
4003
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
3693
4004
  description: "False values for a true/false statement/question",
3694
- maxCount: Count.infinity
4005
+ maxCount: Count.infinity,
4006
+ format: TagFormat.plainText
3695
4007
  },
3696
4008
  {
3697
4009
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -3700,27 +4012,50 @@ var GROUPS = {
3700
4012
  {
3701
4013
  key: ConfigKey.property_example,
3702
4014
  jsonKey: "example",
4015
+ exportJsonKey: [
4016
+ {
4017
+ "@keyonly": {
4018
+ isExample: true,
4019
+ example: "$parent.isCorrect",
4020
+ "@bit": { isExample: true }
4021
+ }
4022
+ },
4023
+ {
4024
+ "@absent": {
4025
+ isExample: true,
4026
+ example: "$parent.isCorrect",
4027
+ "@bit": { isExample: true }
4028
+ }
4029
+ },
4030
+ { isExample: true, example: "$", "@bit": { isExample: true } }
4031
+ ],
3703
4032
  description: "An example for the true/false statement/question",
3704
- format: TagFormat.plainText
4033
+ format: TagFormat.bitmarkText
3705
4034
  }
3706
4035
  ]
3707
4036
  },
3708
4037
  {
4038
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
3709
4039
  key: ConfigKey.tag_false,
3710
4040
  description: "False value for a true/false statement/question",
3711
4041
  maxCount: Count.infinity,
4042
+ format: TagFormat.plainText,
3712
4043
  chain: [
3713
4044
  {
3714
4045
  key: ConfigKey.tag_true,
3715
4046
  jsonKey: "choices[]|set(isCorrect=true)",
4047
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
3716
4048
  description: "True values for a true/false statement/question",
3717
- maxCount: Count.infinity
4049
+ maxCount: Count.infinity,
4050
+ format: TagFormat.plainText
3718
4051
  },
3719
4052
  {
3720
4053
  key: ConfigKey.tag_false,
3721
4054
  jsonKey: "choices[]|set(isCorrect=false)",
4055
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
3722
4056
  description: "False values for a true/false statement/question",
3723
- maxCount: Count.infinity
4057
+ maxCount: Count.infinity,
4058
+ format: TagFormat.plainText
3724
4059
  },
3725
4060
  {
3726
4061
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -3729,8 +4064,25 @@ var GROUPS = {
3729
4064
  {
3730
4065
  key: ConfigKey.property_example,
3731
4066
  jsonKey: "example",
4067
+ exportJsonKey: [
4068
+ {
4069
+ "@keyonly": {
4070
+ isExample: true,
4071
+ example: "$parent.isCorrect",
4072
+ "@bit": { isExample: true }
4073
+ }
4074
+ },
4075
+ {
4076
+ "@absent": {
4077
+ isExample: true,
4078
+ example: "$parent.isCorrect",
4079
+ "@bit": { isExample: true }
4080
+ }
4081
+ },
4082
+ { isExample: true, example: "$", "@bit": { isExample: true } }
4083
+ ],
3732
4084
  description: "An example for the true/false statement/question",
3733
- format: TagFormat.plainText
4085
+ format: TagFormat.bitmarkText
3734
4086
  }
3735
4087
  ]
3736
4088
  }
@@ -3743,6 +4095,7 @@ var GROUPS = {
3743
4095
  {
3744
4096
  key: ConfigKey.property_mark,
3745
4097
  jsonKey: "marks.mark",
4098
+ exportJsonKey: { marks: { mark: ["$"] } },
3746
4099
  description: "The mark configuration",
3747
4100
  format: TagFormat.plainText,
3748
4101
  maxCount: Count.infinity,
@@ -3766,9 +4119,11 @@ var GROUPS = {
3766
4119
  description: "Mark chain",
3767
4120
  tags: [
3768
4121
  {
4122
+ exportJsonKey: { solution: ["$"] },
3769
4123
  key: ConfigKey.tag_mark,
3770
4124
  description: "The marked content",
3771
4125
  maxCount: Count.infinity,
4126
+ format: TagFormat.plainText,
3772
4127
  chain: [
3773
4128
  {
3774
4129
  key: ConfigKey.property_mark,
@@ -3779,8 +4134,13 @@ var GROUPS = {
3779
4134
  {
3780
4135
  key: ConfigKey.property_example,
3781
4136
  jsonKey: "example",
4137
+ exportJsonKey: [
4138
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
4139
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
4140
+ { isExample: true, example: "$", "@bit": { isExample: true } }
4141
+ ],
3782
4142
  description: "An example for the marked content",
3783
- format: TagFormat.plainText
4143
+ format: TagFormat.bitmarkText
3784
4144
  }
3785
4145
  ]
3786
4146
  }
@@ -3868,7 +4228,9 @@ var GROUPS = {
3868
4228
  key: ConfigKey.tag_title,
3869
4229
  name: "Title",
3870
4230
  description: "The title of the book",
3871
- maxCount: 2
4231
+ maxCount: 2,
4232
+ jsonKey: "title|multi(count=2, key=subtitle)",
4233
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
3872
4234
  },
3873
4235
  {
3874
4236
  key: ConfigKey.property_subtype,
@@ -3883,6 +4245,8 @@ var GROUPS = {
3883
4245
  },
3884
4246
  {
3885
4247
  key: ConfigKey.resource_coverImage,
4248
+ jsonKey: "coverImage|resource(type=image, key=image)",
4249
+ exportJsonKey: { coverImage: { type: "image", image: { src: "$" } } },
3886
4250
  description: "The cover image of the book",
3887
4251
  chain: [
3888
4252
  {
@@ -3899,6 +4263,8 @@ var GROUPS = {
3899
4263
  },
3900
4264
  {
3901
4265
  key: ConfigKey.resource_backgroundImage,
4266
+ jsonKey: "backgroundImage|resource(type=image, key=image)",
4267
+ exportJsonKey: { backgroundImage: { type: "image", image: { src: "$" } } },
3902
4268
  description: "The background image of the book",
3903
4269
  chain: [
3904
4270
  {
@@ -4058,9 +4424,21 @@ var GROUPS = {
4058
4424
  format: TagFormat.plainText,
4059
4425
  chain: [
4060
4426
  {
4427
+ exportJsonKey: { reference: "$" },
4061
4428
  key: ConfigKey.tag_reference,
4062
- description: "The reference(s) for the book(s) in the learning path",
4063
- maxCount: 2
4429
+ format: TagFormat.plainText,
4430
+ description: "The reference for the book(s) in the learning path",
4431
+ maxCount: 1,
4432
+ chain: [
4433
+ {
4434
+ key: ConfigKey.tag_reference,
4435
+ jsonKey: "referenceEnd",
4436
+ exportJsonKey: { referenceEnd: "$" },
4437
+ format: TagFormat.plainText,
4438
+ description: "The referenceEnd for the book(s) in the learning path",
4439
+ maxCount: 1
4440
+ }
4441
+ ]
4064
4442
  }
4065
4443
  ]
4066
4444
  }
@@ -4200,6 +4578,8 @@ var GROUPS = {
4200
4578
  tags: [
4201
4579
  {
4202
4580
  key: ConfigKey.resource_imagePlaceholder,
4581
+ jsonKey: "imagePlaceholder|resource(type=image, key=image)",
4582
+ exportJsonKey: { imagePlaceholder: { type: "image", image: { src: "$" } } },
4203
4583
  description: "Placeholder image for the resource",
4204
4584
  chain: [
4205
4585
  {
@@ -4384,6 +4764,7 @@ var GROUPS = {
4384
4764
  {
4385
4765
  key: ConfigKey.property_posterImage,
4386
4766
  jsonKey: "posterImage.src",
4767
+ exportJsonKey: { posterImage: { src: "$" } },
4387
4768
  description: "The poster image for the video",
4388
4769
  format: TagFormat.plainText,
4389
4770
  chain: [
@@ -4440,6 +4821,7 @@ var GROUPS = {
4440
4821
  tags: [
4441
4822
  {
4442
4823
  key: ConfigKey.resource_image,
4824
+ exportJsonKey: { resource: { type: "image", image: { src: "$" } } },
4443
4825
  description: "The image resource",
4444
4826
  chain: [
4445
4827
  {
@@ -4504,6 +4886,7 @@ var GROUPS = {
4504
4886
  tags: [
4505
4887
  {
4506
4888
  key: ConfigKey.resource_imageLink,
4889
+ exportJsonKey: { resource: { type: "image-link", imageLink: { url: "$" } } },
4507
4890
  description: "The link to the image resource",
4508
4891
  chain: [
4509
4892
  {
@@ -4520,6 +4903,7 @@ var GROUPS = {
4520
4903
  tags: [
4521
4904
  {
4522
4905
  key: ConfigKey.resource_audio,
4906
+ exportJsonKey: { resource: { type: "audio", audio: { src: "$" } } },
4523
4907
  description: "The audio resource",
4524
4908
  chain: [
4525
4909
  {
@@ -4536,6 +4920,7 @@ var GROUPS = {
4536
4920
  tags: [
4537
4921
  {
4538
4922
  key: ConfigKey.resource_audioEmbed,
4923
+ exportJsonKey: { resource: { type: "audio-embed", audioEmbed: { src: "$" } } },
4539
4924
  description: "The embedded audio resource",
4540
4925
  chain: [
4541
4926
  {
@@ -4552,6 +4937,7 @@ var GROUPS = {
4552
4937
  tags: [
4553
4938
  {
4554
4939
  key: ConfigKey.resource_audioLink,
4940
+ exportJsonKey: { resource: { type: "audio-link", audioLink: { url: "$" } } },
4555
4941
  description: "The link to the audio resource",
4556
4942
  chain: [
4557
4943
  {
@@ -4568,6 +4954,7 @@ var GROUPS = {
4568
4954
  tags: [
4569
4955
  {
4570
4956
  key: ConfigKey.resource_video,
4957
+ exportJsonKey: { resource: { type: "video", video: { src: "$" } } },
4571
4958
  description: "The video resource",
4572
4959
  chain: [
4573
4960
  {
@@ -4584,6 +4971,7 @@ var GROUPS = {
4584
4971
  tags: [
4585
4972
  {
4586
4973
  key: ConfigKey.resource_videoEmbed,
4974
+ exportJsonKey: { resource: { type: "video-embed", videoEmbed: { url: "$" } } },
4587
4975
  description: "The embedded video resource",
4588
4976
  chain: [
4589
4977
  {
@@ -4600,6 +4988,7 @@ var GROUPS = {
4600
4988
  tags: [
4601
4989
  {
4602
4990
  key: ConfigKey.resource_videoLink,
4991
+ exportJsonKey: { resource: { type: "video-link", videoLink: { url: "$" } } },
4603
4992
  description: "The link to the video resource",
4604
4993
  chain: [
4605
4994
  {
@@ -4616,6 +5005,9 @@ var GROUPS = {
4616
5005
  tags: [
4617
5006
  {
4618
5007
  key: ConfigKey.resource_stillImageFilmEmbed,
5008
+ exportJsonKey: {
5009
+ resource: { type: "still-image-film-embed", stillImageFilmEmbed: { url: "$" } }
5010
+ },
4619
5011
  description: "The embedded still image film resource",
4620
5012
  chain: [
4621
5013
  {
@@ -4632,6 +5024,9 @@ var GROUPS = {
4632
5024
  tags: [
4633
5025
  {
4634
5026
  key: ConfigKey.resource_stillImageFilmLink,
5027
+ exportJsonKey: {
5028
+ resource: { type: "still-image-film-link", stillImageFilmLink: { url: "$" } }
5029
+ },
4635
5030
  description: "The link to the still image film resource",
4636
5031
  chain: [
4637
5032
  {
@@ -4696,6 +5091,7 @@ var GROUPS = {
4696
5091
  tags: [
4697
5092
  {
4698
5093
  key: ConfigKey.resource_document,
5094
+ exportJsonKey: { resource: { type: "document", document: { url: "$" } } },
4699
5095
  description: "The document resource",
4700
5096
  chain: [
4701
5097
  {
@@ -4712,6 +5108,7 @@ var GROUPS = {
4712
5108
  tags: [
4713
5109
  {
4714
5110
  key: ConfigKey.resource_documentEmbed,
5111
+ exportJsonKey: { resource: { type: "document-embed", documentEmbed: { url: "$" } } },
4715
5112
  description: "The embedded document resource",
4716
5113
  chain: [
4717
5114
  {
@@ -4728,6 +5125,7 @@ var GROUPS = {
4728
5125
  tags: [
4729
5126
  {
4730
5127
  key: ConfigKey.resource_documentLink,
5128
+ exportJsonKey: { resource: { type: "document-link", documentLink: { url: "$" } } },
4731
5129
  description: "The link to the document resource",
4732
5130
  chain: [
4733
5131
  {
@@ -4744,6 +5142,7 @@ var GROUPS = {
4744
5142
  tags: [
4745
5143
  {
4746
5144
  key: ConfigKey.resource_documentDownload,
5145
+ exportJsonKey: { resource: { type: "document-download", documentDownload: { url: "$" } } },
4747
5146
  description: "The downloadable document resource",
4748
5147
  chain: [
4749
5148
  {
@@ -4760,6 +5159,7 @@ var GROUPS = {
4760
5159
  tags: [
4761
5160
  {
4762
5161
  key: ConfigKey.resource_appLink,
5162
+ exportJsonKey: { resource: { type: "app-link", appLink: { url: "$" } } },
4763
5163
  description: "The link to the app resource",
4764
5164
  chain: [
4765
5165
  {
@@ -4776,6 +5176,7 @@ var GROUPS = {
4776
5176
  tags: [
4777
5177
  {
4778
5178
  key: ConfigKey.resource_websiteLink,
5179
+ exportJsonKey: { resource: { type: "website-link", websiteLink: { url: "$" } } },
4779
5180
  description: "The link to the website resource",
4780
5181
  chain: [
4781
5182
  {
@@ -4833,6 +5234,8 @@ var GROUPS = {
4833
5234
  tags: [
4834
5235
  {
4835
5236
  key: ConfigKey.resource_previewImage,
5237
+ jsonKey: "previewImage|resource(type=image, key=image)",
5238
+ exportJsonKey: { previewImage: { type: "image", image: { src: "$" } } },
4836
5239
  description: "The preview image resource",
4837
5240
  chain: [
4838
5241
  {
@@ -4849,6 +5252,8 @@ var GROUPS = {
4849
5252
  tags: [
4850
5253
  {
4851
5254
  key: ConfigKey.resource_previewVideo,
5255
+ jsonKey: "previewVideo|resource(type=video, key=video)",
5256
+ exportJsonKey: { previewVideo: { type: "video", video: { src: "$" } } },
4852
5257
  description: "The preview video resource",
4853
5258
  chain: [
4854
5259
  {
@@ -4913,20 +5318,48 @@ var ConfigHydrator = class {
4913
5318
  _side.name,
4914
5319
  _side.repeat ?? false,
4915
5320
  variantsOfSide,
4916
- _side.jsonKey
5321
+ _side.jsonKey,
5322
+ _side.exportJsonKey,
5323
+ Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
4917
5324
  );
4918
5325
  sides.push(sideConfig);
4919
5326
  }
4920
5327
  const cardSetConfig = new CardSetConfig(
4921
5328
  _cardSet,
4922
5329
  _cardSetConfig.jsonKey,
4923
- _cardSetConfig.sections,
5330
+ _cardSetConfig.exportJsonKey,
5331
+ Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
5332
+ this.hydrateCardSections(_cardSetConfig.sections),
4924
5333
  sides
4925
5334
  );
4926
5335
  return cardSetConfig;
4927
5336
  }
5337
+ hydrateCardSections(sections) {
5338
+ if (!sections) return void 0;
5339
+ const out = {};
5340
+ for (const [k, v] of Object.entries(sections)) {
5341
+ out[k] = {
5342
+ jsonKey: v.jsonKey,
5343
+ exportJsonKey: v.exportJsonKey,
5344
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
5345
+ isDefault: v.isDefault,
5346
+ sideJsonKey: v.sideJsonKey,
5347
+ sideExportJsonKey: v.sideExportJsonKey,
5348
+ hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey")
5349
+ };
5350
+ }
5351
+ return out;
5352
+ }
4928
5353
  hydrateTagConfig(_tag) {
4929
- const { key: _configKey, maxCount, minCount, chain: _chain, deprecated } = _tag;
5354
+ const {
5355
+ key: _configKey,
5356
+ maxCount,
5357
+ minCount,
5358
+ chain: _chain,
5359
+ deprecated,
5360
+ jsonKey,
5361
+ exportJsonKey
5362
+ } = _tag;
4930
5363
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
4931
5364
  if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
4932
5365
  const tag = (0, import_superenum15.Enum)(Tag).fromValue(configKey);
@@ -4941,6 +5374,9 @@ var ConfigHydrator = class {
4941
5374
  maxCount: maxCount ?? MAX_COUNT_DEFAULT,
4942
5375
  minCount: minCount ?? MIN_COUNT_DEFAULT,
4943
5376
  chain,
5377
+ jsonKey,
5378
+ exportJsonKey,
5379
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
4944
5380
  deprecated
4945
5381
  });
4946
5382
  return {
@@ -4959,7 +5395,8 @@ var ConfigHydrator = class {
4959
5395
  format,
4960
5396
  values,
4961
5397
  defaultValue,
4962
- jsonKey
5398
+ jsonKey,
5399
+ exportJsonKey
4963
5400
  } = _tag;
4964
5401
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
4965
5402
  if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
@@ -4975,6 +5412,8 @@ var ConfigHydrator = class {
4975
5412
  minCount: minCount ?? MIN_COUNT_DEFAULT,
4976
5413
  chain,
4977
5414
  jsonKey,
5415
+ exportJsonKey,
5416
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
4978
5417
  format,
4979
5418
  values,
4980
5419
  defaultValue,
@@ -4987,7 +5426,15 @@ var ConfigHydrator = class {
4987
5426
  };
4988
5427
  }
4989
5428
  hydrateResourceTagConfig(_tag) {
4990
- const { key: _configKey, maxCount, minCount, chain: _chain, deprecated, jsonKey } = _tag;
5429
+ const {
5430
+ key: _configKey,
5431
+ maxCount,
5432
+ minCount,
5433
+ chain: _chain,
5434
+ deprecated,
5435
+ jsonKey,
5436
+ exportJsonKey
5437
+ } = _tag;
4991
5438
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
4992
5439
  if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
4993
5440
  const tag = _configKey.substring(1);
@@ -5002,6 +5449,8 @@ var ConfigHydrator = class {
5002
5449
  minCount: minCount ?? MIN_COUNT_DEFAULT,
5003
5450
  chain,
5004
5451
  jsonKey,
5452
+ exportJsonKey,
5453
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
5005
5454
  deprecated
5006
5455
  });
5007
5456
  return {
@@ -5033,14 +5482,25 @@ var ConfigHydrator = class {
5033
5482
  };
5034
5483
  }
5035
5484
  hydrateCardVariantConfig(_variant) {
5036
- const { tags: _tags, bodyAllowed, bodyRequired, repeatCount, jsonKey } = _variant;
5485
+ const {
5486
+ tags: _tags,
5487
+ bodyAllowed,
5488
+ bodyRequired,
5489
+ repeatCount,
5490
+ jsonKey,
5491
+ exportJsonKey,
5492
+ format
5493
+ } = _variant;
5037
5494
  const tags2 = this.hydrateTagsConfig(_tags);
5038
5495
  const cardSetConfig = new CardVariantConfig(
5039
5496
  tags2.tags,
5040
5497
  bodyAllowed,
5041
5498
  bodyRequired,
5042
5499
  repeatCount,
5043
- jsonKey
5500
+ jsonKey,
5501
+ exportJsonKey,
5502
+ Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
5503
+ format
5044
5504
  );
5045
5505
  return cardSetConfig;
5046
5506
  }
@@ -5078,6 +5538,7 @@ var BITS = {
5078
5538
  description: "Common tags for quiz bits"
5079
5539
  },
5080
5540
  {
5541
+ exportJsonKey: { title: "$" },
5081
5542
  key: ConfigKey.tag_title,
5082
5543
  description: "The title of the flashcard quiz"
5083
5544
  },
@@ -5086,6 +5547,20 @@ var BITS = {
5086
5547
  description: "The flashcard set to use for the app flashcards",
5087
5548
  format: TagFormat.plainText,
5088
5549
  maxCount: Count.infinity
5550
+ },
5551
+ {
5552
+ // Override inherited @example from group_standardTags: string root
5553
+ // example. Bare/synthesized emits `example: "true"` (a text literal
5554
+ // that field-coerces to a paragraph "true" in bitmark+ contexts);
5555
+ // valued [@example:text] emits the user's text via `$`.
5556
+ key: ConfigKey.property_example,
5557
+ exportJsonKey: [
5558
+ { "@keyonly": { isExample: true, example: "true" } },
5559
+ { "@absent": { isExample: true, example: "true" } },
5560
+ { isExample: true, example: "$" }
5561
+ ],
5562
+ description: "The example text for the bit",
5563
+ format: TagFormat.plainText
5089
5564
  }
5090
5565
  ],
5091
5566
  rootExampleType: ExampleType.string
@@ -5167,6 +5642,7 @@ var BITS = {
5167
5642
  description: "Article bit, used for articles / paragraphs",
5168
5643
  tags: [
5169
5644
  {
5645
+ exportJsonKey: { title: "$" },
5170
5646
  key: ConfigKey.tag_title,
5171
5647
  description: "The title of the article"
5172
5648
  }
@@ -5273,7 +5749,9 @@ var BITS = {
5273
5749
  {
5274
5750
  key: ConfigKey.tag_title,
5275
5751
  description: "Title and subtitle of the catalog item",
5276
- maxCount: 2
5752
+ maxCount: 2,
5753
+ jsonKey: "title|multi(count=2, key=subtitle)",
5754
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5277
5755
  },
5278
5756
  {
5279
5757
  key: ConfigKey.property_coverImage,
@@ -5282,6 +5760,8 @@ var BITS = {
5282
5760
  },
5283
5761
  {
5284
5762
  key: ConfigKey.resource_coverImage,
5763
+ jsonKey: "coverImage|resource(type=image, key=image)",
5764
+ exportJsonKey: { coverImage: { type: "image", image: { src: "$" } } },
5285
5765
  description: "Cover image of the catalog item",
5286
5766
  chain: [
5287
5767
  {
@@ -5409,6 +5889,17 @@ var BITS = {
5409
5889
  key: ConfigKey.group_previewVideos,
5410
5890
  description: "Array of preview videos for the catalog item",
5411
5891
  maxCount: Count.infinity
5892
+ },
5893
+ {
5894
+ // Override inherited @example from group_standardTags: string root example.
5895
+ key: ConfigKey.property_example,
5896
+ exportJsonKey: [
5897
+ { "@keyonly": { isExample: true, example: "true" } },
5898
+ { "@absent": { isExample: true, example: "true" } },
5899
+ { isExample: true, example: "$" }
5900
+ ],
5901
+ description: "The example text for the bit",
5902
+ format: TagFormat.plainText
5412
5903
  }
5413
5904
  ],
5414
5905
  rootExampleType: ExampleType.string
@@ -5421,7 +5912,9 @@ var BITS = {
5421
5912
  {
5422
5913
  key: ConfigKey.tag_title,
5423
5914
  description: "Title and subtitle of the catalog item",
5424
- maxCount: 2
5915
+ maxCount: 2,
5916
+ jsonKey: "title|multi(count=2, key=subtitle)",
5917
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5425
5918
  },
5426
5919
  {
5427
5920
  key: ConfigKey.property_coverImage,
@@ -5430,6 +5923,8 @@ var BITS = {
5430
5923
  },
5431
5924
  {
5432
5925
  key: ConfigKey.resource_coverImage,
5926
+ jsonKey: "coverImage|resource(type=image, key=image)",
5927
+ exportJsonKey: { coverImage: { type: "image", image: { src: "$" } } },
5433
5928
  description: "Cover image of the catalog item",
5434
5929
  chain: [
5435
5930
  {
@@ -5557,6 +6052,17 @@ var BITS = {
5557
6052
  key: ConfigKey.group_previewVideos,
5558
6053
  description: "Array of preview videos for the catalog item",
5559
6054
  maxCount: Count.infinity
6055
+ },
6056
+ {
6057
+ // Override inherited @example from group_standardTags: string root example.
6058
+ key: ConfigKey.property_example,
6059
+ exportJsonKey: [
6060
+ { "@keyonly": { isExample: true, example: "true" } },
6061
+ { "@absent": { isExample: true, example: "true" } },
6062
+ { isExample: true, example: "$" }
6063
+ ],
6064
+ description: "The example text for the bit",
6065
+ format: TagFormat.plainText
5560
6066
  }
5561
6067
  ],
5562
6068
  rootExampleType: ExampleType.string
@@ -5569,7 +6075,9 @@ var BITS = {
5569
6075
  {
5570
6076
  key: ConfigKey.tag_title,
5571
6077
  description: "Title and subtitle of the catalog item",
5572
- maxCount: 2
6078
+ maxCount: 2,
6079
+ jsonKey: "title|multi(count=2, key=subtitle)",
6080
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5573
6081
  },
5574
6082
  {
5575
6083
  key: ConfigKey.property_coverImage,
@@ -5695,6 +6203,17 @@ var BITS = {
5695
6203
  key: ConfigKey.group_previewVideos,
5696
6204
  description: "Array of preview videos for the catalog item",
5697
6205
  maxCount: Count.infinity
6206
+ },
6207
+ {
6208
+ // Override inherited @example from group_standardTags: string root example.
6209
+ key: ConfigKey.property_example,
6210
+ exportJsonKey: [
6211
+ { "@keyonly": { isExample: true, example: "true" } },
6212
+ { "@absent": { isExample: true, example: "true" } },
6213
+ { isExample: true, example: "$" }
6214
+ ],
6215
+ description: "The example text for the bit",
6216
+ format: TagFormat.plainText
5698
6217
  }
5699
6218
  ],
5700
6219
  rootExampleType: ExampleType.string
@@ -5896,11 +6415,15 @@ var BITS = {
5896
6415
  description: "Bit alias, used to create an alias for a bit",
5897
6416
  tags: [
5898
6417
  {
6418
+ exportJsonKey: { reference: "$" },
5899
6419
  key: ConfigKey.tag_reference,
6420
+ format: TagFormat.plainText,
5900
6421
  description: "The reference to the bit that this alias points to"
5901
6422
  },
5902
6423
  {
6424
+ exportJsonKey: { anchor: "$" },
5903
6425
  key: ConfigKey.tag_anchor,
6426
+ format: TagFormat.plainText,
5904
6427
  description: "The anchor for the bit alias, used for linking"
5905
6428
  }
5906
6429
  ]
@@ -6098,8 +6621,10 @@ var BITS = {
6098
6621
  {
6099
6622
  key: ConfigKey.tag_title,
6100
6623
  description: "The title of the book cover",
6101
- maxCount: 2
6624
+ maxCount: 2,
6102
6625
  // title & subtitle
6626
+ jsonKey: "title|multi(count=2, key=subtitle)",
6627
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
6103
6628
  },
6104
6629
  {
6105
6630
  key: ConfigKey.property_coverColor,
@@ -6243,12 +6768,16 @@ var BITS = {
6243
6768
  description: "Chapter bit, used to define chapters in books or articles",
6244
6769
  tags: [
6245
6770
  {
6771
+ exportJsonKey: { anchor: "$" },
6246
6772
  key: ConfigKey.tag_anchor,
6773
+ format: TagFormat.plainText,
6247
6774
  description: "The anchor for the chapter, used for linking"
6248
6775
  },
6249
6776
  {
6250
6777
  key: ConfigKey.tag_title,
6251
- description: "The title of the chapter"
6778
+ description: "The title of the chapter",
6779
+ jsonKey: "title|setMulti(level)",
6780
+ exportJsonKey: { title: "$", level: "$level" }
6252
6781
  },
6253
6782
  {
6254
6783
  key: ConfigKey.property_toc,
@@ -6301,6 +6830,7 @@ var BITS = {
6301
6830
  },
6302
6831
  {
6303
6832
  key: ConfigKey.property_isCaseSensitive,
6833
+ exportJsonKey: {},
6304
6834
  description: "If the cloze answers are case sensitive",
6305
6835
  format: TagFormat.boolean,
6306
6836
  defaultValue: "true"
@@ -6398,6 +6928,11 @@ var BITS = {
6398
6928
  description: "Formula bit, used for mathematical formulas in articles or documents",
6399
6929
  textFormatDefault: TextFormat2.latex
6400
6930
  },
6931
+ [BitType2.formulaImage]: {
6932
+ since: "5.23.0",
6933
+ baseBitType: BitType2.formula,
6934
+ description: "Formula image bit, used for mathematical formulas rendered as images"
6935
+ },
6401
6936
  [BitType2.smartStandardFormula]: {
6402
6937
  since: "3.11.0",
6403
6938
  baseBitType: BitType2.formula,
@@ -6750,6 +7285,7 @@ var BITS = {
6750
7285
  {
6751
7286
  key: ConfigKey.property_servings,
6752
7287
  jsonKey: "servings.servings",
7288
+ exportJsonKey: { servings: { servings: "$" } },
6753
7289
  description: "The number of servings for the ingredients",
6754
7290
  format: TagFormat.number,
6755
7291
  chain: [
@@ -6775,8 +7311,10 @@ var BITS = {
6775
7311
  format: TagFormat.boolean
6776
7312
  },
6777
7313
  {
7314
+ exportJsonKey: { hint: "$" },
6778
7315
  key: ConfigKey.tag_hint,
6779
- description: "Hint for the ingredient, used to provide additional information"
7316
+ description: "Hint for the ingredient, used to provide additional information",
7317
+ format: TagFormat.plainText
6780
7318
  }
6781
7319
  ]
6782
7320
  }
@@ -6951,6 +7489,17 @@ var BITS = {
6951
7489
  description: "Reference for the essay, used to link to external resources",
6952
7490
  format: TagFormat.plainText,
6953
7491
  maxCount: Count.infinity
7492
+ },
7493
+ {
7494
+ // Override inherited @example from group_standardTags: string root example.
7495
+ key: ConfigKey.property_example,
7496
+ exportJsonKey: [
7497
+ { "@keyonly": { isExample: true, example: "true" } },
7498
+ { "@absent": { isExample: true, example: "true" } },
7499
+ { isExample: true, example: "$" }
7500
+ ],
7501
+ description: "The example text for the essay bit",
7502
+ format: TagFormat.plainText
6954
7503
  }
6955
7504
  ],
6956
7505
  rootExampleType: ExampleType.string
@@ -6971,8 +7520,20 @@ var BITS = {
6971
7520
  description: "Example bit, used to provide examples in articles or books",
6972
7521
  tags: [
6973
7522
  {
7523
+ exportJsonKey: { title: "$" },
6974
7524
  key: ConfigKey.tag_title,
6975
7525
  description: "The title of the example"
7526
+ },
7527
+ {
7528
+ // Override inherited @example from group_standardTags: string root example.
7529
+ key: ConfigKey.property_example,
7530
+ exportJsonKey: [
7531
+ { "@keyonly": { isExample: true, example: "true" } },
7532
+ { "@absent": { isExample: true, example: "true" } },
7533
+ { isExample: true, example: "$" }
7534
+ ],
7535
+ description: "The example text for the example bit",
7536
+ format: TagFormat.plainText
6976
7537
  }
6977
7538
  ],
6978
7539
  rootExampleType: ExampleType.string
@@ -7838,6 +8399,7 @@ var BITS = {
7838
8399
  // Image resource
7839
8400
  key: ConfigKey.group_resourceImage,
7840
8401
  description: "Resource image tags for logo grave images, used to attach images",
8402
+ exportJsonKey: { images: "$" },
7841
8403
  minCount: 1,
7842
8404
  maxCount: Count.infinity
7843
8405
  }
@@ -8001,15 +8563,29 @@ var BITS = {
8001
8563
  format: TagFormat.plainText,
8002
8564
  chain: [
8003
8565
  {
8566
+ exportJsonKey: { reference: "$" },
8004
8567
  key: ConfigKey.tag_reference,
8568
+ format: TagFormat.plainText,
8005
8569
  description: "Reference tag for the book, used to link to the book in the system",
8006
- maxCount: 2
8570
+ maxCount: 1,
8571
+ chain: [
8572
+ {
8573
+ key: ConfigKey.tag_reference,
8574
+ jsonKey: "referenceEnd",
8575
+ exportJsonKey: { referenceEnd: "$" },
8576
+ format: TagFormat.plainText,
8577
+ description: "End reference tag for the book, used to specify a range",
8578
+ maxCount: 1
8579
+ }
8580
+ ]
8007
8581
  }
8008
8582
  ]
8009
8583
  },
8010
8584
  {
8011
8585
  /* Allow incorrectly chained reference tag */
8586
+ exportJsonKey: { reference: "$" },
8012
8587
  key: ConfigKey.tag_reference,
8588
+ format: TagFormat.plainText,
8013
8589
  description: "Reference tag for the book, used to link to the book in the system"
8014
8590
  },
8015
8591
  {
@@ -8054,16 +8630,41 @@ var BITS = {
8054
8630
  format: TagFormat.plainText,
8055
8631
  chain: [
8056
8632
  {
8633
+ exportJsonKey: { reference: "$" },
8057
8634
  key: ConfigKey.tag_reference,
8635
+ format: TagFormat.plainText,
8058
8636
  description: "Reference tag for the book, used to link to the book in the system",
8059
- maxCount: 2
8637
+ maxCount: 1,
8638
+ chain: [
8639
+ {
8640
+ key: ConfigKey.tag_reference,
8641
+ jsonKey: "referenceEnd",
8642
+ exportJsonKey: { referenceEnd: "$" },
8643
+ format: TagFormat.plainText,
8644
+ description: "End reference tag for the book, used to specify a range",
8645
+ maxCount: 1
8646
+ }
8647
+ ]
8060
8648
  }
8061
8649
  ]
8062
8650
  },
8063
8651
  {
8064
8652
  /* Allow incorrectly chained reference tag */
8653
+ exportJsonKey: { reference: "$" },
8065
8654
  key: ConfigKey.tag_reference,
8066
- description: "Reference tag for the book, used to link to the book in the system"
8655
+ format: TagFormat.plainText,
8656
+ description: "Reference tag for the book, used to link to the book in the system",
8657
+ maxCount: 1,
8658
+ chain: [
8659
+ {
8660
+ key: ConfigKey.tag_reference,
8661
+ jsonKey: "referenceEnd",
8662
+ exportJsonKey: { referenceEnd: "$" },
8663
+ format: TagFormat.plainText,
8664
+ description: "End reference tag for the book, used to specify a range",
8665
+ maxCount: 1
8666
+ }
8667
+ ]
8067
8668
  },
8068
8669
  {
8069
8670
  key: ConfigKey.property_buttonCaption,
@@ -8092,9 +8693,21 @@ var BITS = {
8092
8693
  maxCount: Count.infinity,
8093
8694
  chain: [
8094
8695
  {
8696
+ exportJsonKey: { reference: "$" },
8095
8697
  key: ConfigKey.tag_reference,
8698
+ format: TagFormat.plainText,
8096
8699
  description: "Reference tag for the book, used to link to the book in the system",
8097
- maxCount: 2
8700
+ maxCount: 1,
8701
+ chain: [
8702
+ {
8703
+ key: ConfigKey.tag_reference,
8704
+ jsonKey: "referenceEnd",
8705
+ exportJsonKey: { referenceEnd: "$" },
8706
+ format: TagFormat.plainText,
8707
+ description: "End reference tag for the book, used to specify a range",
8708
+ maxCount: 1
8709
+ }
8710
+ ]
8098
8711
  }
8099
8712
  ]
8100
8713
  },
@@ -8261,6 +8874,7 @@ var BITS = {
8261
8874
  tags: [
8262
8875
  {
8263
8876
  key: ConfigKey.resource_backgroundWallpaper,
8877
+ exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
8264
8878
  description: "Background wallpaper for the image, used to set a background for the image",
8265
8879
  chain: [
8266
8880
  {
@@ -8443,6 +9057,7 @@ var BITS = {
8443
9057
  },
8444
9058
  {
8445
9059
  key: ConfigKey.resource_backgroundWallpaper,
9060
+ exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
8446
9061
  description: "Background wallpaper for the image, used to set a background for the image",
8447
9062
  chain: [
8448
9063
  {
@@ -8595,6 +9210,7 @@ var BITS = {
8595
9210
  // Image resource
8596
9211
  key: ConfigKey.group_resourceImage,
8597
9212
  description: "Resource image tags for logo grave images, used to attach images",
9213
+ exportJsonKey: { logos: "$" },
8598
9214
  minCount: 1,
8599
9215
  maxCount: Count.infinity
8600
9216
  }
@@ -8612,7 +9228,9 @@ var BITS = {
8612
9228
  description: "Internal link bit, used to create links to other bits in articles or books",
8613
9229
  tags: [
8614
9230
  {
9231
+ exportJsonKey: { reference: "$" },
8615
9232
  key: ConfigKey.tag_reference,
9233
+ format: TagFormat.plainText,
8616
9234
  description: "Reference tag for the internal link, used to link to the target bit"
8617
9235
  }
8618
9236
  ]
@@ -8629,6 +9247,7 @@ var BITS = {
8629
9247
  },
8630
9248
  {
8631
9249
  key: ConfigKey.property_reasonableNumOfChars,
9250
+ exportJsonKey: {},
8632
9251
  description: "Reasonable number of characters for the interview, used to limit input size",
8633
9252
  format: TagFormat.number
8634
9253
  }
@@ -9004,6 +9623,7 @@ var BITS = {
9004
9623
  },
9005
9624
  {
9006
9625
  key: ConfigKey.property_isCaseSensitive,
9626
+ exportJsonKey: {},
9007
9627
  description: "Case sensitivity for matching pairs, used to define if matches are case-sensitive",
9008
9628
  format: TagFormat.boolean,
9009
9629
  defaultValue: "true"
@@ -9056,6 +9676,7 @@ var BITS = {
9056
9676
  tags: [
9057
9677
  {
9058
9678
  key: ConfigKey.property_reasonableNumOfChars,
9679
+ exportJsonKey: {},
9059
9680
  description: "Reasonable number of characters for feedback, used to limit input size",
9060
9681
  format: TagFormat.number
9061
9682
  }
@@ -9197,6 +9818,7 @@ var BITS = {
9197
9818
  description: "Page bit, used to create pages in articles or books",
9198
9819
  tags: [
9199
9820
  {
9821
+ exportJsonKey: { title: "$" },
9200
9822
  key: ConfigKey.tag_title,
9201
9823
  description: "Title of the page, used to display the page title"
9202
9824
  },
@@ -9555,6 +10177,8 @@ var BITS = {
9555
10177
  },
9556
10178
  {
9557
10179
  key: ConfigKey.resource_platformBackgroundImage,
10180
+ jsonKey: "platformBackgroundImage|resource(type=image, key=image)",
10181
+ exportJsonKey: { platformBackgroundImage: { type: "image", image: { src: "$" } } },
9558
10182
  description: "The platform section chat background image",
9559
10183
  chain: [
9560
10184
  {
@@ -9648,6 +10272,7 @@ var BITS = {
9648
10272
  description: "Review note bit, used to create review notes in articles or books",
9649
10273
  tags: [
9650
10274
  {
10275
+ exportJsonKey: { title: "$" },
9651
10276
  key: ConfigKey.tag_title,
9652
10277
  description: "Title of the review note, used to display the note title"
9653
10278
  },
@@ -9666,6 +10291,17 @@ var BITS = {
9666
10291
  key: ConfigKey.property_resolvedBy,
9667
10292
  description: "Resolved by for the review note, used to define who resolved the note",
9668
10293
  format: TagFormat.plainText
10294
+ },
10295
+ {
10296
+ // Override inherited @example from group_standardTags: string root example.
10297
+ key: ConfigKey.property_example,
10298
+ exportJsonKey: [
10299
+ { "@keyonly": { isExample: true, example: "true" } },
10300
+ { "@absent": { isExample: true, example: "true" } },
10301
+ { isExample: true, example: "$" }
10302
+ ],
10303
+ description: "The example text for the review note bit",
10304
+ format: TagFormat.plainText
9669
10305
  }
9670
10306
  ],
9671
10307
  rootExampleType: ExampleType.string
@@ -9718,11 +10354,15 @@ var BITS = {
9718
10354
  tags: [
9719
10355
  // Not sure if these are actually valid here, but include them as they are in the test bit.
9720
10356
  {
10357
+ exportJsonKey: { anchor: "$" },
9721
10358
  key: ConfigKey.tag_anchor,
10359
+ format: TagFormat.plainText,
9722
10360
  description: "Anchor for the sample solution, used to link to the solution"
9723
10361
  },
9724
10362
  {
10363
+ exportJsonKey: { reference: "$" },
9725
10364
  key: ConfigKey.tag_reference,
10365
+ format: TagFormat.plainText,
9726
10366
  description: "Reference for the sample solution, used to link to the source of the solution"
9727
10367
  }
9728
10368
  ]
@@ -9736,6 +10376,19 @@ var BITS = {
9736
10376
  {
9737
10377
  key: ConfigKey.group_quizCommon,
9738
10378
  description: "Common quiz tags for sequences"
10379
+ },
10380
+ {
10381
+ // Override inherited @example from group_standardTags: this bit has
10382
+ // a boolean root example (rootExampleType: boolean), so bit-level
10383
+ // [@example] writes `example: true` in addition to `isExample: true`.
10384
+ key: ConfigKey.property_example,
10385
+ exportJsonKey: [
10386
+ { "@keyonly": { isExample: true, example: true } },
10387
+ { "@absent": { isExample: true, example: true } },
10388
+ { isExample: true, example: "$" }
10389
+ ],
10390
+ description: "The example flag for the bit (boolean)",
10391
+ format: TagFormat.plainText
9739
10392
  }
9740
10393
  ],
9741
10394
  cardSet: CardSetConfigKey.elements,
@@ -9843,6 +10496,7 @@ var BITS = {
9843
10496
  {
9844
10497
  key: ConfigKey.property_ratingLevelStart,
9845
10498
  jsonKey: "ratingLevelStart.level",
10499
+ exportJsonKey: { ratingLevelStart: { level: "$" } },
9846
10500
  description: "Start level for the rating survey, used to define the lowest rating",
9847
10501
  format: TagFormat.number,
9848
10502
  chain: [
@@ -9856,6 +10510,7 @@ var BITS = {
9856
10510
  {
9857
10511
  key: ConfigKey.property_ratingLevelEnd,
9858
10512
  jsonKey: "ratingLevelEnd.level",
10513
+ exportJsonKey: { ratingLevelEnd: { level: "$" } },
9859
10514
  description: "End level for the rating survey, used to define the highest rating",
9860
10515
  format: TagFormat.number,
9861
10516
  chain: [
@@ -10008,6 +10663,7 @@ var BITS = {
10008
10663
  },
10009
10664
  {
10010
10665
  key: ConfigKey.resource_backgroundWallpaper,
10666
+ exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
10011
10667
  description: "Background wallpaper for the image, used to set a background for the image",
10012
10668
  chain: [
10013
10669
  {
@@ -10391,12 +11047,34 @@ var BITS = {
10391
11047
  format: TagFormat.plainText
10392
11048
  },
10393
11049
  {
11050
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
10394
11051
  key: ConfigKey.tag_true,
10395
- description: "Tag for the true option in the true/false question"
11052
+ description: "Tag for the true option in the true/false question",
11053
+ format: TagFormat.plainText
10396
11054
  },
10397
11055
  {
11056
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
10398
11057
  key: ConfigKey.tag_false,
10399
- description: "Tag for the false option in the true/false question"
11058
+ description: "Tag for the false option in the true/false question",
11059
+ format: TagFormat.plainText
11060
+ },
11061
+ {
11062
+ // Override inherited @example from group_standardTags: boolean root
11063
+ // example. Note: the legacy reference parser ties the bare-form
11064
+ // example value to `statement.isCorrect`, but the statement is not
11065
+ // yet emitted when this tag fires at bit-header. The pattern below
11066
+ // emits a literal `true` for bare/synthesized and `$` for valued —
11067
+ // sufficient for `[+...]` (correct) statements which dominate the
11068
+ // fixtures; `[-...]` (incorrect) bits with bare `[@example]` would
11069
+ // need either a runtime extension or an explicit `[@example:false]`.
11070
+ key: ConfigKey.property_example,
11071
+ exportJsonKey: [
11072
+ { "@keyonly": { isExample: true, example: true } },
11073
+ { "@absent": { isExample: true, example: true } },
11074
+ { isExample: true, example: "$" }
11075
+ ],
11076
+ description: "The example flag for the bit (boolean)",
11077
+ format: TagFormat.plainText
10400
11078
  }
10401
11079
  ],
10402
11080
  rootExampleType: ExampleType.boolean
@@ -10604,6 +11282,25 @@ var BITS = {
10604
11282
  baseBitType: BitType2.vendorStripePricingTable,
10605
11283
  description: "External Stripe pricing table bit, used to embed external Stripe pricing tables in articles or books"
10606
11284
  },
11285
+ [BitType2.vendorStripePricingTablePrintOnRequest]: {
11286
+ since: "5.21.0",
11287
+ baseBitType: BitType2.vendorStripePricingTable,
11288
+ 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
+ tags: [
11290
+ {
11291
+ key: ConfigKey.property_printOnRequestCustomerId,
11292
+ description: "Print-on-request customer ID, used to identify the customer for the print-on-request flow",
11293
+ format: TagFormat.plainText,
11294
+ minCount: 1
11295
+ },
11296
+ {
11297
+ key: ConfigKey.property_printOnRequestProductId,
11298
+ description: "Print-on-request product ID, used to identify the product for the print-on-request flow",
11299
+ format: TagFormat.plainText,
11300
+ minCount: 1
11301
+ }
11302
+ ]
11303
+ },
10607
11304
  [BitType2.video]: {
10608
11305
  since: "1.3.0",
10609
11306
  baseBitType: BitType2._standard,
@@ -10960,6 +11657,8 @@ var Config = class {
10960
11657
  maxCount: 1,
10961
11658
  chain: tag.chain,
10962
11659
  jsonKey: tag.jsonKey,
11660
+ exportJsonKey: tag.exportJsonKey,
11661
+ hasExportJsonKey: tag.hasExportJsonKey,
10963
11662
  deprecated: tag.deprecated
10964
11663
  });
10965
11664
  finalResourceTags[k] = newTag;
@@ -11064,7 +11763,7 @@ var instance2 = new Config();
11064
11763
  // src/generated/package_info.ts
11065
11764
  var PACKAGE_INFO = {
11066
11765
  "name": "@gmb/bitmark-parser-generator",
11067
- "version": "5.21.0",
11766
+ "version": "5.23.0",
11068
11767
  "author": "Get More Brain Ltd",
11069
11768
  "license": "ISC",
11070
11769
  "description": "A bitmark parser and generator using Peggy.js"
@@ -11658,6 +12357,8 @@ var NodeType = {
11658
12357
  gmbExternalShopItems: "gmbExternalShopItems",
11659
12358
  groupTag: "groupTag",
11660
12359
  groupTagValue: "groupTagValue",
12360
+ gUri: "gUri",
12361
+ gUriValue: "gUriValue",
11661
12362
  handInAcceptFileType: "handInAcceptFileType",
11662
12363
  handInAcceptFileTypeValue: "handInAcceptFileTypeValue",
11663
12364
  handInInstruction: "handInInstruction",
@@ -11879,6 +12580,10 @@ var NodeType = {
11879
12580
  previewVideoValue: "previewVideoValue",
11880
12581
  printParentChapterLevel: "printParentChapterLevel",
11881
12582
  printParentChapterLevelValue: "printParentChapterLevelValue",
12583
+ printOnRequestCustomerId: "printOnRequestCustomerId",
12584
+ printOnRequestCustomerIdValue: "printOnRequestCustomerIdValue",
12585
+ printOnRequestProductId: "printOnRequestProductId",
12586
+ printOnRequestProductIdValue: "printOnRequestProductIdValue",
11882
12587
  processHandIn: "processHandIn",
11883
12588
  processHandInLocation: "processHandInLocation",
11884
12589
  processHandInLocationValue: "processHandInLocationValue",
@@ -11996,6 +12701,8 @@ var NodeType = {
11996
12701
  solution: "solution",
11997
12702
  solutions: "solutions",
11998
12703
  solutionsValue: "solutionsValue",
12704
+ sourceBB: "sourceBB",
12705
+ sourceBBValue: "sourceBBValue",
11999
12706
  sourceDocument: "sourceDocument",
12000
12707
  sourceDocumentValue: "sourceDocumentValue",
12001
12708
  sourceRL: "sourceRL",
@@ -12633,6 +13340,17 @@ function convertBasicToExtendedTableFormat(table) {
12633
13340
  }))
12634
13341
  };
12635
13342
  }
13343
+ if (Array.isArray(table.columnWidths) && table.columnWidths.length > 0) {
13344
+ const targetCells = tableExtended.header?.rows[0]?.cells ?? tableExtended.body?.rows[0]?.cells;
13345
+ if (targetCells) {
13346
+ for (let i = 0; i < table.columnWidths.length; i++) {
13347
+ const width = table.columnWidths[i];
13348
+ if (typeof width === "number" && width > 0 && targetCells[i]) {
13349
+ targetCells[i].colwidth = width;
13350
+ }
13351
+ }
13352
+ }
13353
+ }
12636
13354
  return tableExtended;
12637
13355
  }
12638
13356
  function convertExtendedToBasicTableFormat(tableExtended) {
@@ -12644,7 +13362,23 @@ function convertExtendedToBasicTableFormat(tableExtended) {
12644
13362
  return row.cells.map((cell) => cell?.content).filter((content) => content !== void 0);
12645
13363
  };
12646
13364
  const dataRows = [];
13365
+ const widths = [];
13366
+ let hasAnyWidth = false;
13367
+ let maxCellCount = 0;
13368
+ const collectWidths = (cells) => {
13369
+ if (!cells) return;
13370
+ if (cells.length > maxCellCount) maxCellCount = cells.length;
13371
+ cells.forEach((cell, idx) => {
13372
+ if (cell && typeof cell.colwidth === "number" && cell.colwidth > 0) {
13373
+ widths[idx] = cell.colwidth;
13374
+ hasAnyWidth = true;
13375
+ }
13376
+ });
13377
+ };
12647
13378
  const headRows = tableExtended.header?.rows ?? [];
13379
+ headRows.forEach((row) => collectWidths(row?.cells));
13380
+ (tableExtended.body?.rows ?? []).forEach((row) => collectWidths(row?.cells));
13381
+ (tableExtended.footer?.rows ?? []).forEach((row) => collectWidths(row?.cells));
12648
13382
  if (headRows.length > 0) {
12649
13383
  const primaryHeader = extractRowCells(headRows[0]);
12650
13384
  if (primaryHeader.length > 0) {
@@ -12674,6 +13408,15 @@ function convertExtendedToBasicTableFormat(tableExtended) {
12674
13408
  if (dataRows.length > 0) {
12675
13409
  table.data = dataRows;
12676
13410
  }
13411
+ if (hasAnyWidth) {
13412
+ const columnCount = table.columns?.length ?? maxCellCount;
13413
+ const columnWidths = new Array(columnCount).fill(null);
13414
+ for (let i = 0; i < columnCount; i++) {
13415
+ const w = widths[i];
13416
+ if (typeof w === "number") columnWidths[i] = w;
13417
+ }
13418
+ table.columnWidths = columnWidths;
13419
+ }
12677
13420
  return table;
12678
13421
  }
12679
13422
  function normalizeTableFormat(bitType, table) {
@@ -24840,6 +25583,7 @@ var Builder = class extends BaseBuilder {
24840
25583
  isCommented: data.isCommented,
24841
25584
  // Properties
24842
25585
  id: this.toAstProperty(bitType, ConfigKey.property_id, data.id, options),
25586
+ gUri: this.toAstProperty(bitType, ConfigKey.property_gUri, data.gUri, options),
24843
25587
  internalComment: this.toAstProperty(
24844
25588
  bitType,
24845
25589
  ConfigKey.property_internalComment,
@@ -25051,6 +25795,7 @@ var Builder = class extends BaseBuilder {
25051
25795
  data.extractorInternal,
25052
25796
  options
25053
25797
  ),
25798
+ sourceBB: this.normaliseSourceBB(data.sourceBB),
25054
25799
  levelCEFRp: this.toAstProperty(
25055
25800
  bitType,
25056
25801
  ConfigKey.property_levelCEFRp,
@@ -25695,6 +26440,18 @@ var Builder = class extends BaseBuilder {
25695
26440
  data.printParentChapterLevel,
25696
26441
  options
25697
26442
  ),
26443
+ printOnRequestCustomerId: this.toAstProperty(
26444
+ bitType,
26445
+ ConfigKey.property_printOnRequestCustomerId,
26446
+ data.printOnRequestCustomerId,
26447
+ options
26448
+ ),
26449
+ printOnRequestProductId: this.toAstProperty(
26450
+ bitType,
26451
+ ConfigKey.property_printOnRequestProductId,
26452
+ data.printOnRequestProductId,
26453
+ options
26454
+ ),
25698
26455
  platformBrandTarget: this.toAstProperty(
25699
26456
  bitType,
25700
26457
  ConfigKey.property_platformBrandTarget,
@@ -26059,6 +26816,19 @@ var Builder = class extends BaseBuilder {
26059
26816
  nodes = Object.values(combinedNodes);
26060
26817
  return nodes.length > 0 ? nodes : void 0;
26061
26818
  }
26819
+ /**
26820
+ * Normalise a sourceBB input into the AST shape (always number[][]).
26821
+ * Accepts a single 4-number tuple or an array of tuples; returns undefined when empty.
26822
+ */
26823
+ normaliseSourceBB(data) {
26824
+ if (data == null) return void 0;
26825
+ if (!Array.isArray(data) || data.length === 0) return void 0;
26826
+ const isNested = data.some(Array.isArray);
26827
+ const tuples = (isNested ? data : [data]).filter(
26828
+ (t) => Array.isArray(t) && t.length === 4 && t.every((n) => typeof n === "number")
26829
+ );
26830
+ return tuples.length > 0 ? tuples : void 0;
26831
+ }
26062
26832
  /**
26063
26833
  * Build groupTag node
26064
26834
  *
@@ -26527,6 +27297,17 @@ var Builder = class extends BaseBuilder {
26527
27297
  (row) => (row || []).map((cell) => this.handleJsonText(context, TextLocation2.tag, cell))
26528
27298
  );
26529
27299
  }
27300
+ if (Array.isArray(nodeTable.columnWidths)) {
27301
+ const columnCount = Array.isArray(nodeTable.columns) ? nodeTable.columns.length : void 0;
27302
+ const source = columnCount != null ? nodeTable.columnWidths.slice(0, columnCount) : nodeTable.columnWidths;
27303
+ const normalized = source.map((w) => typeof w === "number" && w > 0 ? w : null);
27304
+ const hasAny = normalized.some((w) => w != null);
27305
+ if (hasAny) {
27306
+ nodeTable.columnWidths = normalized;
27307
+ } else {
27308
+ delete nodeTable.columnWidths;
27309
+ }
27310
+ }
26530
27311
  const buildSection = (section) => {
26531
27312
  if (!section || !Array.isArray(section.rows)) return void 0;
26532
27313
  const rows = section.rows.map((row) => {
@@ -28367,6 +29148,23 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
28367
29148
  format: TagFormat.plainText
28368
29149
  });
28369
29150
  }
29151
+ // bitmarkAst -> bits -> bitsValue -> sourceBB
29152
+ enter_sourceBB(node, route) {
29153
+ const parent = this.getParentNode(route);
29154
+ if (parent?.key !== NodeType.bitsValue) return false;
29155
+ const tuples = node.value;
29156
+ if (!Array.isArray(tuples) || tuples.length === 0) return false;
29157
+ this.writeProperty(
29158
+ "sourceBB",
29159
+ tuples.map((t) => t.join(", ")),
29160
+ route,
29161
+ {
29162
+ format: TagFormat.plainText,
29163
+ array: true
29164
+ }
29165
+ );
29166
+ return false;
29167
+ }
28370
29168
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> additionalSolutions -> additionalSolutionsValue
28371
29169
  leaf_additionalSolutionsValue(node, route) {
28372
29170
  const parent = this.getParentNode(route, 2);
@@ -30490,6 +31288,16 @@ var JsonGenerator = class extends AstWalkerGenerator {
30490
31288
  enter_ratingLevelEnd(node, route) {
30491
31289
  return this.standardHandler(node, route, NodeType.bitsValue, { array: false });
30492
31290
  }
31291
+ // bitmarkAst -> bits -> bitsValue -> sourceBB
31292
+ enter_sourceBB(node, route) {
31293
+ const tuples = node.value;
31294
+ const parent = this.getParentNode(route);
31295
+ if (parent?.key !== NodeType.bitsValue) return false;
31296
+ if (tuples && tuples.length > 0) {
31297
+ this.bitJson.sourceBB = tuples.length === 1 ? tuples[0] : tuples;
31298
+ }
31299
+ return false;
31300
+ }
30493
31301
  // bitmarkAst -> bits -> bitsValue -> productId
30494
31302
  enter_productId(node, route) {
30495
31303
  const productIds = node.value;
@@ -31517,6 +32325,10 @@ var JsonGenerator = class extends AstWalkerGenerator {
31517
32325
  if (instance2.isOfBitType(bitType, BitType2.vendorStripePricingTable)) {
31518
32326
  if (bitJson.stripePricingTableId == null) bitJson.stripePricingTableId = "";
31519
32327
  if (bitJson.stripePublishableKey == null) bitJson.stripePublishableKey = "";
32328
+ if (instance2.isOfBitType(bitType, BitType2.vendorStripePricingTablePrintOnRequest)) {
32329
+ if (bitJson.printOnRequestCustomerId == null) bitJson.printOnRequestCustomerId = "";
32330
+ if (bitJson.printOnRequestProductId == null) bitJson.printOnRequestProductId = "";
32331
+ }
31520
32332
  }
31521
32333
  if (instance2.isOfBitType(bitType, BitType2.callToAction)) {
31522
32334
  if (bitJson.buttonCaption == null) bitJson.buttonCaption = "";
@@ -35164,6 +35976,17 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
35164
35976
  format: TextFormat2.bitmarkText,
35165
35977
  location: TextLocation2.tag
35166
35978
  });
35979
+ case TagFormat.coordinates:
35980
+ const coordRaw = instance3.unbreakscape(v2, {
35981
+ format: TextFormat2.plainText,
35982
+ location: TextLocation2.tag
35983
+ });
35984
+ if (coordRaw == null) return void 0;
35985
+ const coordParts = coordRaw.split(",").map((p) => instance6.asNumber(p.trim()));
35986
+ if (coordParts.length !== 4 || coordParts.some((n) => n == null)) {
35987
+ return void 0;
35988
+ }
35989
+ return coordParts;
35167
35990
  }
35168
35991
  }
35169
35992
  return instance3.unbreakscape(v2, {
@@ -35200,6 +36023,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
35200
36023
  minCount: 1,
35201
36024
  chain: void 0,
35202
36025
  jsonKey: void 0,
36026
+ exportJsonKey: void 0,
36027
+ hasExportJsonKey: false,
35203
36028
  format: TagFormat.bitmarkText,
35204
36029
  values: void 0,
35205
36030
  defaultValue: void 0,
@@ -35210,19 +36035,18 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
35210
36035
  }
35211
36036
 
35212
36037
  // src/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.ts
35213
- function referenceTagContentProcessor(_context, _contentDepth, _tagsConfig, content, target, isReferenceEnd) {
35214
- const { value } = content;
36038
+ function referenceTagContentProcessor(context, _contentDepth, tagsConfig, content, target) {
36039
+ const { value, chain } = content;
35215
36040
  const trimmedStringValue = stringUtils.trimmedString(value);
35216
- if (isReferenceEnd) {
35217
- target.referenceEnd = instance3.unbreakscape(trimmedStringValue, {
35218
- format: TextFormat2.bitmarkText,
35219
- location: TextLocation2.tag
35220
- });
35221
- } else {
35222
- target.reference = instance3.unbreakscape(trimmedStringValue, {
35223
- format: TextFormat2.bitmarkText,
35224
- location: TextLocation2.tag
35225
- });
36041
+ target.reference = instance3.unbreakscape(trimmedStringValue, {
36042
+ format: TextFormat2.bitmarkText,
36043
+ location: TextLocation2.tag
36044
+ });
36045
+ if (Array.isArray(chain) && chain.length > 0) {
36046
+ const sub = context.bitContentProcessor(ContentDepth.Chain, tagsConfig, chain);
36047
+ if (sub.reference != null) {
36048
+ target.referenceEnd = sub.reference;
36049
+ }
35226
36050
  }
35227
36051
  }
35228
36052
 
@@ -35908,7 +36732,6 @@ var BitmarkPegParserProcessor = class {
35908
36732
  result.markConfig = [];
35909
36733
  result.extraProperties = {};
35910
36734
  result.internalComments = [];
35911
- let seenReference = false;
35912
36735
  let inFooter = false;
35913
36736
  const bodyParts = [];
35914
36737
  let bodyTextPart = instance3.EMPTY_STRING;
@@ -35944,15 +36767,7 @@ var BitmarkPegParserProcessor = class {
35944
36767
  defaultTagContentProcessor(this.context, contentDepth, tagsConfig, content, result);
35945
36768
  break;
35946
36769
  case TypeKey.Reference:
35947
- referenceTagContentProcessor(
35948
- this.context,
35949
- contentDepth,
35950
- tagsConfig,
35951
- content,
35952
- result,
35953
- seenReference
35954
- );
35955
- seenReference = true;
36770
+ referenceTagContentProcessor(this.context, contentDepth, tagsConfig, content, result);
35956
36771
  break;
35957
36772
  case TypeKey.Title:
35958
36773
  titleTagContentProcessor(this.context, contentDepth, tagsConfig, content, result);
@@ -40332,6 +41147,117 @@ var JsonStringGenerator = class {
40332
41147
  }
40333
41148
  };
40334
41149
 
41150
+ // src/utils/BoundingBox.ts
41151
+ function toBbox(arr) {
41152
+ if (!Array.isArray(arr) || arr.length !== 4) return null;
41153
+ if (!arr.every(Number.isFinite)) return null;
41154
+ return [arr[0], arr[1], arr[2], arr[3]];
41155
+ }
41156
+ function parseSourceBB(sourceBB) {
41157
+ if (sourceBB == null) return [];
41158
+ if (!Array.isArray(sourceBB) || sourceBB.length === 0) return [];
41159
+ const isNested = sourceBB.some(Array.isArray);
41160
+ const candidates = isNested ? sourceBB : [sourceBB];
41161
+ const out = [];
41162
+ for (const candidate of candidates) {
41163
+ const box = toBbox(candidate);
41164
+ if (box) out.push(box);
41165
+ }
41166
+ return out;
41167
+ }
41168
+ function boundingBoxIntersects(a, b) {
41169
+ return a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1];
41170
+ }
41171
+ function boundingBoxUnion(boxes) {
41172
+ if (boxes.length === 0) return null;
41173
+ let [x0, y0, x1, y1] = boxes[0];
41174
+ for (let i = 1; i < boxes.length; i++) {
41175
+ const b = boxes[i];
41176
+ if (b[0] < x0) x0 = b[0];
41177
+ if (b[1] < y0) y0 = b[1];
41178
+ if (b[2] > x1) x1 = b[2];
41179
+ if (b[3] > y1) y1 = b[3];
41180
+ }
41181
+ return [x0, y0, x1, y1];
41182
+ }
41183
+ var BoundingBoxIndex = class _BoundingBoxIndex {
41184
+ constructor(entries) {
41185
+ __publicField(this, "_entries");
41186
+ __publicField(this, "bitmarkParser", new BitmarkParserGenerator());
41187
+ this._entries = entries;
41188
+ }
41189
+ /**
41190
+ * Build an index from already-parsed bits. Bits without a parseable
41191
+ * `sourceBB` are dropped. Order of the input is preserved.
41192
+ *
41193
+ * Pass `options.sourceRL` to scope the index to a single source page —
41194
+ * bits whose `sourceRL` doesn't match (or is absent) are excluded.
41195
+ */
41196
+ static fromBits(wrappers, options) {
41197
+ const filterSourceRL = options?.sourceRL;
41198
+ const entries = [];
41199
+ for (const wrapper of wrappers) {
41200
+ if (!wrapper?.bit) continue;
41201
+ if (filterSourceRL !== void 0 && wrapper.bit.sourceRL !== filterSourceRL) {
41202
+ continue;
41203
+ }
41204
+ const boxes = parseSourceBB(wrapper.bit.sourceBB);
41205
+ if (boxes.length === 0) continue;
41206
+ entries.push({ bit: wrapper.bit, wrapper, boxes });
41207
+ }
41208
+ return new _BoundingBoxIndex(entries);
41209
+ }
41210
+ /** All bits with at least one valid `sourceBB`, in input order. */
41211
+ get entries() {
41212
+ return this._entries;
41213
+ }
41214
+ /**
41215
+ * Bits whose ANY `sourceBB` box intersects `query` (strict overlap —
41216
+ * touching-only edges do NOT count as an intersection).
41217
+ */
41218
+ intersecting(query) {
41219
+ const matches = [];
41220
+ for (const entry of this._entries) {
41221
+ if (entry.boxes.some((box) => boundingBoxIntersects(query, box))) {
41222
+ matches.push(entry);
41223
+ }
41224
+ }
41225
+ return matches;
41226
+ }
41227
+ /**
41228
+ * Flat list of every individual `sourceBB` box that intersects `query`.
41229
+ * For a multi-box bit, only the boxes that themselves intersected are
41230
+ * returned.
41231
+ */
41232
+ intersectingBoxes(query) {
41233
+ const matches = [];
41234
+ for (const entry of this._entries) {
41235
+ for (const box of entry.boxes) {
41236
+ if (boundingBoxIntersects(query, box)) matches.push(box);
41237
+ }
41238
+ }
41239
+ return matches;
41240
+ }
41241
+ /**
41242
+ * Smallest axis-aligned box that fully encloses every individual `sourceBB`
41243
+ * box that intersected the query. For a multi-box bit, only the boxes that
41244
+ * themselves intersected contribute to the union — non-intersecting boxes
41245
+ * from the same bit are ignored. Returns `null` if no box matches.
41246
+ */
41247
+ enclosingBoundingBox(query) {
41248
+ return boundingBoxUnion(this.intersectingBoxes(query));
41249
+ }
41250
+ /** Render selected bits back to bitmark text. Empty input returns `''`. */
41251
+ toBitmark(entries) {
41252
+ if (entries.length === 0) return "";
41253
+ const wrappers = entries.map((e) => e.wrapper);
41254
+ return this.bitmarkParser.convert(wrappers, {
41255
+ outputFormat: Output.bitmark,
41256
+ bitmarkOptions: { prettifyJson: true }
41257
+ });
41258
+ }
41259
+ };
41260
+
40335
41261
  // src/index.ts
40336
41262
  init();
40337
41263
  // Annotate the CommonJS export names for ESM import in node:
@@ -40345,6 +41271,7 @@ init();
40345
41271
  BitmarkStringGenerator,
40346
41272
  BitmarkVersion,
40347
41273
  BodyTextFormat,
41274
+ BoundingBoxIndex,
40348
41275
  Builder,
40349
41276
  CardSetVersion,
40350
41277
  InfoFormat,