@gmb/bitmark-parser-generator 1.35.0 → 2.0.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.
Files changed (290) hide show
  1. package/dist/browser/bitmark-parser-generator.min.js +1 -1
  2. package/dist/browser/bundle-report.html +2 -2
  3. package/dist/cjs/BitmarkParserGenerator.js +8 -3
  4. package/dist/cjs/BitmarkParserGenerator.js.map +1 -1
  5. package/dist/cjs/ast/Ast.js +1 -0
  6. package/dist/cjs/ast/Ast.js.map +1 -1
  7. package/dist/cjs/ast/BaseBuilder.js +91 -54
  8. package/dist/cjs/ast/BaseBuilder.js.map +1 -1
  9. package/dist/cjs/ast/Builder.js +776 -389
  10. package/dist/cjs/ast/Builder.js.map +1 -1
  11. package/dist/cjs/ast/ResourceBuilder.js +516 -252
  12. package/dist/cjs/ast/ResourceBuilder.js.map +1 -1
  13. package/dist/cjs/ast/rules/NodeValidator.js +61 -22
  14. package/dist/cjs/ast/rules/NodeValidator.js.map +1 -1
  15. package/dist/cjs/breakscaping/Breakscape.js +96 -71
  16. package/dist/cjs/breakscaping/Breakscape.js.map +1 -1
  17. package/dist/cjs/config/raw/bits.js +14 -5
  18. package/dist/cjs/config/raw/bits.js.map +1 -1
  19. package/dist/cjs/config/raw/properties.js +7 -2
  20. package/dist/cjs/config/raw/properties.js.map +1 -1
  21. package/dist/cjs/generated/build-info.js +1 -1
  22. package/dist/cjs/generated/build-info.js.map +1 -1
  23. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js +1 -0
  24. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js.map +1 -1
  25. package/dist/cjs/generator/AstWalkerGenerator.js +4 -1
  26. package/dist/cjs/generator/AstWalkerGenerator.js.map +1 -1
  27. package/dist/cjs/generator/bitmark/BitmarkGenerator.js +959 -338
  28. package/dist/cjs/generator/bitmark/BitmarkGenerator.js.map +1 -1
  29. package/dist/cjs/generator/json/JsonGenerator.js +308 -1982
  30. package/dist/cjs/generator/json/JsonGenerator.js.map +1 -1
  31. package/dist/cjs/generator/text/TextGenerator.js +26 -8
  32. package/dist/cjs/generator/text/TextGenerator.js.map +1 -1
  33. package/dist/cjs/index.js.map +1 -1
  34. package/dist/cjs/model/ast/NodeType.js +27 -8
  35. package/dist/cjs/model/ast/NodeType.js.map +1 -1
  36. package/dist/cjs/model/config/enum/PropertyConfigKey.js +1 -0
  37. package/dist/cjs/model/config/enum/PropertyConfigKey.js.map +1 -1
  38. package/dist/cjs/model/enum/BitType.js +1 -2
  39. package/dist/cjs/model/enum/BitType.js.map +1 -1
  40. package/dist/cjs/model/enum/PropertyFormat.js +3 -1
  41. package/dist/cjs/model/enum/PropertyFormat.js.map +1 -1
  42. package/dist/cjs/model/enum/TextFormat.js +1 -1
  43. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserHelper.js +9 -3
  44. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserHelper.js.map +1 -1
  45. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserProcessor.js +49 -131
  46. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserProcessor.js.map +1 -1
  47. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  48. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js +7 -31
  49. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  50. package/dist/cjs/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js +255 -0
  51. package/dist/cjs/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js.map +1 -0
  52. package/dist/cjs/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js +2 -1
  53. package/dist/cjs/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js.map +1 -1
  54. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +175 -129
  55. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  56. package/dist/cjs/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js +8 -2
  57. package/dist/cjs/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js.map +1 -1
  58. package/dist/cjs/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js +61 -0
  59. package/dist/cjs/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js.map +1 -0
  60. package/dist/cjs/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js +11 -5
  61. package/dist/cjs/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js.map +1 -1
  62. package/dist/cjs/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js +21 -17
  63. package/dist/cjs/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js.map +1 -1
  64. package/dist/cjs/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js +50 -0
  65. package/dist/cjs/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js.map +1 -0
  66. package/dist/cjs/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js +2 -15
  67. package/dist/cjs/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js.map +1 -1
  68. package/dist/cjs/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js +2 -4
  69. package/dist/cjs/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js.map +1 -1
  70. package/dist/cjs/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js +4 -1
  71. package/dist/cjs/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js.map +1 -1
  72. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js +2 -4
  73. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js.map +1 -1
  74. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js +5 -5
  75. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js.map +1 -1
  76. package/dist/cjs/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js +5 -6
  77. package/dist/cjs/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js.map +1 -1
  78. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +23 -7
  79. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  80. package/dist/cjs/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js +5 -5
  81. package/dist/cjs/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js.map +1 -1
  82. package/dist/cjs/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js +3 -2
  83. package/dist/cjs/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js.map +1 -1
  84. package/dist/cjs/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js +19 -8
  85. package/dist/cjs/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js.map +1 -1
  86. package/dist/cjs/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js +4 -6
  87. package/dist/cjs/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js.map +1 -1
  88. package/dist/cjs/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js +4 -5
  89. package/dist/cjs/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js.map +1 -1
  90. package/dist/cjs/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js +14 -5
  91. package/dist/cjs/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js.map +1 -1
  92. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +37 -21
  93. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  94. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js +3 -2
  95. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js.map +1 -1
  96. package/dist/cjs/parser/json/JsonParser.js +73 -765
  97. package/dist/cjs/parser/json/JsonParser.js.map +1 -1
  98. package/dist/cjs/parser/text/TextParser.js +61 -2
  99. package/dist/cjs/parser/text/TextParser.js.map +1 -1
  100. package/dist/cjs/utils/BitUtils.js +15 -13
  101. package/dist/cjs/utils/BitUtils.js.map +1 -1
  102. package/dist/esm/BitmarkParserGenerator.js +8 -3
  103. package/dist/esm/BitmarkParserGenerator.js.map +1 -1
  104. package/dist/esm/ast/Ast.js +1 -0
  105. package/dist/esm/ast/Ast.js.map +1 -1
  106. package/dist/esm/ast/BaseBuilder.js +91 -54
  107. package/dist/esm/ast/BaseBuilder.js.map +1 -1
  108. package/dist/esm/ast/Builder.js +776 -389
  109. package/dist/esm/ast/Builder.js.map +1 -1
  110. package/dist/esm/ast/ResourceBuilder.js +516 -252
  111. package/dist/esm/ast/ResourceBuilder.js.map +1 -1
  112. package/dist/esm/ast/rules/NodeValidator.js +61 -22
  113. package/dist/esm/ast/rules/NodeValidator.js.map +1 -1
  114. package/dist/esm/breakscaping/Breakscape.js +96 -71
  115. package/dist/esm/breakscaping/Breakscape.js.map +1 -1
  116. package/dist/esm/config/raw/bits.js +14 -5
  117. package/dist/esm/config/raw/bits.js.map +1 -1
  118. package/dist/esm/config/raw/properties.js +7 -2
  119. package/dist/esm/config/raw/properties.js.map +1 -1
  120. package/dist/esm/generated/build-info.js +1 -1
  121. package/dist/esm/generated/build-info.js.map +1 -1
  122. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js +1 -0
  123. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js.map +1 -1
  124. package/dist/esm/generator/AstWalkerGenerator.js +4 -1
  125. package/dist/esm/generator/AstWalkerGenerator.js.map +1 -1
  126. package/dist/esm/generator/bitmark/BitmarkGenerator.js +959 -338
  127. package/dist/esm/generator/bitmark/BitmarkGenerator.js.map +1 -1
  128. package/dist/esm/generator/json/JsonGenerator.js +308 -1982
  129. package/dist/esm/generator/json/JsonGenerator.js.map +1 -1
  130. package/dist/esm/generator/text/TextGenerator.js +26 -8
  131. package/dist/esm/generator/text/TextGenerator.js.map +1 -1
  132. package/dist/esm/index.js.map +1 -1
  133. package/dist/esm/model/ast/NodeType.js +27 -8
  134. package/dist/esm/model/ast/NodeType.js.map +1 -1
  135. package/dist/esm/model/config/enum/PropertyConfigKey.js +1 -0
  136. package/dist/esm/model/config/enum/PropertyConfigKey.js.map +1 -1
  137. package/dist/esm/model/enum/BitType.js +1 -2
  138. package/dist/esm/model/enum/BitType.js.map +1 -1
  139. package/dist/esm/model/enum/PropertyFormat.js +3 -1
  140. package/dist/esm/model/enum/PropertyFormat.js.map +1 -1
  141. package/dist/esm/model/enum/TextFormat.js +1 -1
  142. package/dist/esm/parser/bitmark/peg/BitmarkPegParserHelper.js +9 -3
  143. package/dist/esm/parser/bitmark/peg/BitmarkPegParserHelper.js.map +1 -1
  144. package/dist/esm/parser/bitmark/peg/BitmarkPegParserProcessor.js +49 -131
  145. package/dist/esm/parser/bitmark/peg/BitmarkPegParserProcessor.js.map +1 -1
  146. package/dist/esm/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  147. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js +7 -31
  148. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  149. package/dist/esm/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js +252 -0
  150. package/dist/esm/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js.map +1 -0
  151. package/dist/esm/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js +2 -1
  152. package/dist/esm/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js.map +1 -1
  153. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +175 -129
  154. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  155. package/dist/esm/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js +8 -2
  156. package/dist/esm/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js.map +1 -1
  157. package/dist/esm/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js +58 -0
  158. package/dist/esm/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js.map +1 -0
  159. package/dist/esm/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js +11 -5
  160. package/dist/esm/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js.map +1 -1
  161. package/dist/esm/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js +21 -17
  162. package/dist/esm/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js.map +1 -1
  163. package/dist/esm/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js +47 -0
  164. package/dist/esm/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js.map +1 -0
  165. package/dist/esm/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js +2 -15
  166. package/dist/esm/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js.map +1 -1
  167. package/dist/esm/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js +2 -4
  168. package/dist/esm/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js.map +1 -1
  169. package/dist/esm/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js +4 -1
  170. package/dist/esm/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js.map +1 -1
  171. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js +2 -4
  172. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js.map +1 -1
  173. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js +5 -5
  174. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js.map +1 -1
  175. package/dist/esm/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js +5 -6
  176. package/dist/esm/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js.map +1 -1
  177. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +23 -7
  178. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  179. package/dist/esm/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js +5 -5
  180. package/dist/esm/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js.map +1 -1
  181. package/dist/esm/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js +3 -2
  182. package/dist/esm/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js.map +1 -1
  183. package/dist/esm/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js +19 -8
  184. package/dist/esm/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js.map +1 -1
  185. package/dist/esm/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js +4 -6
  186. package/dist/esm/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js.map +1 -1
  187. package/dist/esm/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js +4 -5
  188. package/dist/esm/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js.map +1 -1
  189. package/dist/esm/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js +14 -5
  190. package/dist/esm/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js.map +1 -1
  191. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +37 -21
  192. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  193. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js +3 -2
  194. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js.map +1 -1
  195. package/dist/esm/parser/json/JsonParser.js +73 -765
  196. package/dist/esm/parser/json/JsonParser.js.map +1 -1
  197. package/dist/esm/parser/text/TextParser.js +61 -2
  198. package/dist/esm/parser/text/TextParser.js.map +1 -1
  199. package/dist/esm/utils/BitUtils.js +15 -13
  200. package/dist/esm/utils/BitUtils.js.map +1 -1
  201. package/dist/types/BitmarkParserGenerator.d.ts +8 -0
  202. package/dist/types/BitmarkParserGenerator.d.ts.map +1 -1
  203. package/dist/types/ast/Ast.d.ts.map +1 -1
  204. package/dist/types/ast/BaseBuilder.d.ts +31 -21
  205. package/dist/types/ast/BaseBuilder.d.ts.map +1 -1
  206. package/dist/types/ast/Builder.d.ts +279 -441
  207. package/dist/types/ast/Builder.d.ts.map +1 -1
  208. package/dist/types/ast/ResourceBuilder.d.ts +177 -164
  209. package/dist/types/ast/ResourceBuilder.d.ts.map +1 -1
  210. package/dist/types/ast/rules/NodeValidator.d.ts +3 -2
  211. package/dist/types/ast/rules/NodeValidator.d.ts.map +1 -1
  212. package/dist/types/breakscaping/Breakscape.d.ts +6 -5
  213. package/dist/types/breakscaping/Breakscape.d.ts.map +1 -1
  214. package/dist/types/config/raw/bits.d.ts.map +1 -1
  215. package/dist/types/config/raw/properties.d.ts.map +1 -1
  216. package/dist/types/generated/parser/bitmark/bitmark-peggy-parser.d.ts.map +1 -1
  217. package/dist/types/generator/AstWalkerGenerator.d.ts.map +1 -1
  218. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts +89 -55
  219. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts.map +1 -1
  220. package/dist/types/generator/json/JsonGenerator.d.ts +88 -108
  221. package/dist/types/generator/json/JsonGenerator.d.ts.map +1 -1
  222. package/dist/types/generator/text/TextGenerator.d.ts +14 -2
  223. package/dist/types/generator/text/TextGenerator.d.ts.map +1 -1
  224. package/dist/types/index.d.ts +2 -2
  225. package/dist/types/index.d.ts.map +1 -1
  226. package/dist/types/model/ast/NodeType.d.ts +48 -16
  227. package/dist/types/model/ast/NodeType.d.ts.map +1 -1
  228. package/dist/types/model/ast/Nodes.d.ts +64 -440
  229. package/dist/types/model/ast/Nodes.d.ts.map +1 -1
  230. package/dist/types/model/config/enum/ConfigKey.d.ts +2 -0
  231. package/dist/types/model/config/enum/ConfigKey.d.ts.map +1 -1
  232. package/dist/types/model/config/enum/PropertyConfigKey.d.ts +3 -0
  233. package/dist/types/model/config/enum/PropertyConfigKey.d.ts.map +1 -1
  234. package/dist/types/model/enum/BitType.d.ts +2 -4
  235. package/dist/types/model/enum/BitType.d.ts.map +1 -1
  236. package/dist/types/model/enum/PropertyFormat.d.ts +4 -2
  237. package/dist/types/model/enum/PropertyFormat.d.ts.map +1 -1
  238. package/dist/types/model/enum/PropertyTag.d.ts +2 -0
  239. package/dist/types/model/enum/PropertyTag.d.ts.map +1 -1
  240. package/dist/types/model/json/BitJson.d.ts +32 -20
  241. package/dist/types/model/json/BitJson.d.ts.map +1 -1
  242. package/dist/types/model/json/BodyBitJson.d.ts +16 -12
  243. package/dist/types/model/json/BodyBitJson.d.ts.map +1 -1
  244. package/dist/types/model/json/ResourceJson.d.ts +2 -22
  245. package/dist/types/model/json/ResourceJson.d.ts.map +1 -1
  246. package/dist/types/parser/bitmark/peg/BitmarkPegParserHelper.d.ts +3 -2
  247. package/dist/types/parser/bitmark/peg/BitmarkPegParserHelper.d.ts.map +1 -1
  248. package/dist/types/parser/bitmark/peg/BitmarkPegParserProcessor.d.ts +2 -15
  249. package/dist/types/parser/bitmark/peg/BitmarkPegParserProcessor.d.ts.map +1 -1
  250. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts +83 -71
  251. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts.map +1 -1
  252. package/dist/types/parser/bitmark/peg/BitmarkPegParserValidator.d.ts +2 -2
  253. package/dist/types/parser/bitmark/peg/BitmarkPegParserValidator.d.ts.map +1 -1
  254. package/dist/types/parser/bitmark/peg/contentProcessors/BodyContentProcessor.d.ts +37 -0
  255. package/dist/types/parser/bitmark/peg/contentProcessors/BodyContentProcessor.d.ts.map +1 -0
  256. package/dist/types/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.d.ts.map +1 -1
  257. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts +2 -2
  258. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts.map +1 -1
  259. package/dist/types/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.d.ts.map +1 -1
  260. package/dist/types/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.d.ts +15 -0
  261. package/dist/types/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.d.ts.map +1 -0
  262. package/dist/types/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.d.ts.map +1 -1
  263. package/dist/types/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.d.ts.map +1 -1
  264. package/dist/types/parser/bitmark/peg/contentProcessors/FooterContentProcessor.d.ts +16 -0
  265. package/dist/types/parser/bitmark/peg/contentProcessors/FooterContentProcessor.d.ts.map +1 -0
  266. package/dist/types/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.d.ts.map +1 -1
  267. package/dist/types/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.d.ts.map +1 -1
  268. package/dist/types/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.d.ts.map +1 -1
  269. package/dist/types/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.d.ts.map +1 -1
  270. package/dist/types/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.d.ts.map +1 -1
  271. package/dist/types/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.d.ts.map +1 -1
  272. package/dist/types/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.d.ts.map +1 -1
  273. package/dist/types/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.d.ts.map +1 -1
  274. package/dist/types/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.d.ts.map +1 -1
  275. package/dist/types/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.d.ts +2 -2
  276. package/dist/types/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.d.ts.map +1 -1
  277. package/dist/types/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.d.ts.map +1 -1
  278. package/dist/types/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.d.ts.map +1 -1
  279. package/dist/types/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.d.ts +5 -2
  280. package/dist/types/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.d.ts.map +1 -1
  281. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts +1 -1
  282. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts.map +1 -1
  283. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.d.ts.map +1 -1
  284. package/dist/types/parser/json/JsonParser.d.ts +9 -72
  285. package/dist/types/parser/json/JsonParser.d.ts.map +1 -1
  286. package/dist/types/parser/text/TextParser.d.ts +16 -1
  287. package/dist/types/parser/text/TextParser.d.ts.map +1 -1
  288. package/dist/types/utils/BitUtils.d.ts +8 -8
  289. package/dist/types/utils/BitUtils.d.ts.map +1 -1
  290. package/package.json +1 -1
@@ -7,22 +7,29 @@ import { ResourceTag } from '../model/enum/ResourceTag';
7
7
  import { TextFormat } from '../model/enum/TextFormat';
8
8
  import { ArrayUtils } from '../utils/ArrayUtils';
9
9
  import { BitUtils } from '../utils/BitUtils';
10
+ import { BooleanUtils } from '../utils/BooleanUtils';
10
11
  import { NumberUtils } from '../utils/NumberUtils';
11
12
  import { ObjectUtils } from '../utils/ObjectUtils';
13
+ import { StringUtils } from '../utils/StringUtils';
12
14
  import { env } from '../utils/env/Env';
13
15
  import { BaseBuilder } from './BaseBuilder';
16
+ import { ResourceBuilder } from './ResourceBuilder';
14
17
  import { NodeValidator } from './rules/NodeValidator';
15
18
  /**
16
19
  * Builder to build bitmark AST node programmatically
17
20
  */
18
21
  class Builder extends BaseBuilder {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.resourceBuilder = new ResourceBuilder();
25
+ }
19
26
  /**
20
27
  * Build bitmark node
21
28
  *
22
29
  * @param data - data for the node
23
30
  * @returns
24
31
  */
25
- bitmark(data) {
32
+ buildBitmark(data) {
26
33
  const { bits, errors } = data;
27
34
  const node = {
28
35
  bits,
@@ -38,49 +45,44 @@ class Builder extends BaseBuilder {
38
45
  * @param data - data for the node
39
46
  * @returns
40
47
  */
41
- bit(data) {
42
- var _a;
43
- const { bitType, bitLevel, textFormat, resourceType, isCommented, id, internalComment, externalId, spaceId, padletId, jupyterId, jupyterExecutionCount, isPublic, aiGenerated, machineTranslated, analyticsTag, feedbackEngine, feedbackType, disableFeedback, releaseVersion, releaseKind, releaseDate, ageRange, lang, language, publisher, publisherName, theme, computerLanguage, target, slug, tag, reductionTag, bubbleTag, levelCEFRp, levelCEFR, levelILR, levelACTFL, icon, iconTag, colorTag, flashcardSet, subtype, bookAlias, coverImage, coverColor, publications, author, subject, date, dateEnd, location, kind, hasMarkAsDone, processHandIn, action, showInIndex, blockId, pageNo, x, y, width, height, index, classification, availableClassifications, allowedBit, tableFixedHeader, tableSearch, tableSort, tablePagination, tablePaginationLimit, tableHeight, tableWhitespaceNoWrap, tableAutoWidth, tableResizableColumns, quizCountItems, quizStrikethroughSolutions, codeLineNumbers, codeMinimap, stripePricingTableId, stripePublishableKey, thumbImage, scormSource, posterImage, focusX, focusY, pointerLeft, pointerTop, listItemIndent, backgroundWallpaper, hasBookNavigation, duration, referenceProperty, deeplink, externalLink, externalLinkText, videoCallLink, vendorUrl, search, bot, list, textReference, isTracked, isInfoOnly, imageFirst, activityType, labelTrue, labelFalse, content2Buy, mailingList, buttonCaption, callToActionUrl, caption, book, quotedPerson, partialAnswer, reasonableNumOfChars, sampleSolution, additionalSolutions, resolved, resolvedDate, resolvedBy, maxCreatedBits, maxDisplayLevel, page, productId, product, productList, productVideo, productVideoList, productFolder, technicalTerm, servings, ratingLevelStart, ratingLevelEnd, ratingLevelSelected, title, subtitle, level, toc, progress, anchor, reference, referenceEnd, isCaseSensitive, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, imageSource, person, markConfig, extraProperties, imagePlaceholder, resources: _resources, body, footer, markup, parser, } = data;
44
- const bitConfig = Config.getBitConfig(bitType);
45
- // Convert resources into an array
46
- const resources = ArrayUtils.asArray(_resources);
48
+ buildBit(data) {
49
+ var _a, _b, _c, _d, _e, _f, _g, _h;
50
+ const bitConfig = Config.getBitConfig(data.bitType);
51
+ const textFormat = (_a = TextFormat.fromValue(data.textFormat)) !== null && _a !== void 0 ? _a : bitConfig.textFormatDefault;
52
+ // Validate and convert resources, and ensure it is an array
53
+ // const resources = ArrayUtils.asArray(resourcesIn);
47
54
  // Set the card node data
48
- const cardNode = this.cardNode(data);
55
+ const cardNode = this.buildCardNode(data.bitType, textFormat, data);
49
56
  // Add reasonableNumOfChars to the bit only for essay bits (in other cases it will be pushed down the tree)
50
- const reasonableNumOfCharsProperty = Config.isOfBitType(bitType, BitType.essay)
51
- ? this.toAstProperty(PropertyConfigKey.reasonableNumOfChars, reasonableNumOfChars)
57
+ const reasonableNumOfCharsProperty = Config.isOfBitType(data.bitType, BitType.essay)
58
+ ? this.toAstProperty(PropertyConfigKey.reasonableNumOfChars, data.reasonableNumOfChars)
52
59
  : undefined;
60
+ const convertedExample = Object.assign({}, this.toExample(data.__isDefaultExample, data.example));
53
61
  // NOTE: Node order is important and is defined here
54
- const node = Object.assign(Object.assign({ bitType,
55
- bitLevel, textFormat: (_a = TextFormat.fromValue(textFormat)) !== null && _a !== void 0 ? _a : bitConfig.textFormatDefault, resourceType: ResourceTag.fromValue(resourceType), isCommented, id: this.toAstProperty(PropertyConfigKey.id, id), internalComment: this.toAstProperty(PropertyConfigKey.internalComment, internalComment), externalId: this.toAstProperty(PropertyConfigKey.externalId, externalId), spaceId: this.toAstProperty(PropertyConfigKey.spaceId, spaceId), padletId: this.toAstProperty(PropertyConfigKey.padletId, padletId), jupyterId: this.toAstProperty(PropertyConfigKey.jupyterId, jupyterId), jupyterExecutionCount: this.toAstProperty(PropertyConfigKey.jupyterExecutionCount, jupyterExecutionCount), isPublic: this.toAstProperty(PropertyConfigKey.isPublic, isPublic), aiGenerated: this.toAstProperty(PropertyConfigKey.aiGenerated, aiGenerated), machineTranslated: this.toAstProperty(PropertyConfigKey.machineTranslated, machineTranslated), analyticsTag: this.toAstProperty(PropertyConfigKey.analyticsTag, analyticsTag), feedbackEngine: this.toAstProperty(PropertyConfigKey.feedbackEngine, feedbackEngine), feedbackType: this.toAstProperty(PropertyConfigKey.feedbackType, feedbackType), disableFeedback: this.toAstProperty(PropertyConfigKey.disableFeedback, disableFeedback), releaseVersion: this.toAstProperty(PropertyConfigKey.releaseVersion, releaseVersion), releaseKind: this.toAstProperty(PropertyConfigKey.releaseKind, releaseKind), releaseDate: this.toAstProperty(PropertyConfigKey.releaseDate, releaseDate), book, ageRange: this.toAstProperty(PropertyConfigKey.ageRange, ageRange), lang: this.toAstProperty(PropertyConfigKey.lang, lang), language: this.toAstProperty(PropertyConfigKey.language, language), publisher: this.toAstProperty(PropertyConfigKey.publisher, publisher), publisherName: this.toAstProperty(PropertyConfigKey.publisherName, publisherName), theme: this.toAstProperty(PropertyConfigKey.theme, theme), computerLanguage: this.toAstProperty(PropertyConfigKey.computerLanguage, computerLanguage), target: this.toAstProperty(PropertyConfigKey.target, target), slug: this.toAstProperty(PropertyConfigKey.slug, slug), tag: this.toAstProperty(PropertyConfigKey.tag, tag), reductionTag: this.toAstProperty(PropertyConfigKey.reductionTag, reductionTag), bubbleTag: this.toAstProperty(PropertyConfigKey.bubbleTag, bubbleTag), levelCEFRp: this.toAstProperty(PropertyConfigKey.levelCEFRp, levelCEFRp), levelCEFR: this.toAstProperty(PropertyConfigKey.levelCEFR, levelCEFR), levelILR: this.toAstProperty(PropertyConfigKey.levelILR, levelILR), levelACTFL: this.toAstProperty(PropertyConfigKey.levelACTFL, levelACTFL), icon: this.toAstProperty(PropertyConfigKey.icon, icon), iconTag: this.toAstProperty(PropertyConfigKey.iconTag, iconTag), colorTag: this.toAstProperty(PropertyConfigKey.colorTag, colorTag), flashcardSet: this.toAstProperty(PropertyConfigKey.flashcardSet, flashcardSet), subtype: this.toAstProperty(PropertyConfigKey.subtype, subtype), bookAlias: this.toAstProperty(PropertyConfigKey.bookAlias, bookAlias), coverImage: this.toAstProperty(PropertyConfigKey.coverImage, coverImage), coverColor: this.toAstProperty(PropertyConfigKey.coverColor, coverColor), publications: this.toAstProperty(PropertyConfigKey.publications, publications), author: this.toAstProperty(PropertyConfigKey.author, author), subject: this.toAstProperty(PropertyConfigKey.subject, subject), date: this.toAstProperty(PropertyConfigKey.date, date), dateEnd: this.toAstProperty(PropertyConfigKey.dateEnd, dateEnd), location: this.toAstProperty(PropertyConfigKey.location, location), kind: this.toAstProperty(PropertyConfigKey.kind, kind), hasMarkAsDone: this.toAstProperty(PropertyConfigKey.hasMarkAsDone, hasMarkAsDone), processHandIn: this.toAstProperty(PropertyConfigKey.processHandIn, processHandIn), action: this.toAstProperty(PropertyConfigKey.action, action), showInIndex: this.toAstProperty(PropertyConfigKey.showInIndex, showInIndex), blockId: this.toAstProperty(PropertyConfigKey.blockId, blockId), pageNo: this.toAstProperty(PropertyConfigKey.pageNo, pageNo), x: this.toAstProperty(PropertyConfigKey.x, x), y: this.toAstProperty(PropertyConfigKey.y, y), width: this.toAstProperty(PropertyConfigKey.width, width), height: this.toAstProperty(PropertyConfigKey.height, height), index: this.toAstProperty(PropertyConfigKey.index, index), classification: this.toAstProperty(PropertyConfigKey.classification, classification), availableClassifications: this.toAstProperty(PropertyConfigKey.availableClassifications, availableClassifications), allowedBit: this.toAstProperty(PropertyConfigKey.allowedBit, allowedBit), tableFixedHeader: this.toAstProperty(PropertyConfigKey.tableFixedHeader, tableFixedHeader), tableSearch: this.toAstProperty(PropertyConfigKey.tableSearch, tableSearch), tableSort: this.toAstProperty(PropertyConfigKey.tableSort, tableSort), tablePagination: this.toAstProperty(PropertyConfigKey.tablePagination, tablePagination), tablePaginationLimit: this.toAstProperty(PropertyConfigKey.tablePaginationLimit, tablePaginationLimit), tableHeight: this.toAstProperty(PropertyConfigKey.tableHeight, tableHeight), tableWhitespaceNoWrap: this.toAstProperty(PropertyConfigKey.tableWhitespaceNoWrap, tableWhitespaceNoWrap), tableAutoWidth: this.toAstProperty(PropertyConfigKey.tableAutoWidth, tableAutoWidth), tableResizableColumns: this.toAstProperty(PropertyConfigKey.tableResizableColumns, tableResizableColumns), quizCountItems: this.toAstProperty(PropertyConfigKey.quizCountItems, quizCountItems), quizStrikethroughSolutions: this.toAstProperty(PropertyConfigKey.quizStrikethroughSolutions, quizStrikethroughSolutions), codeLineNumbers: this.toAstProperty(PropertyConfigKey.codeLineNumbers, codeLineNumbers), codeMinimap: this.toAstProperty(PropertyConfigKey.codeMinimap, codeMinimap), stripePricingTableId: this.toAstProperty(PropertyConfigKey.stripePricingTableId, stripePricingTableId), stripePublishableKey: this.toAstProperty(PropertyConfigKey.stripePublishableKey, stripePublishableKey), thumbImage: this.toAstProperty(PropertyConfigKey.thumbImage, thumbImage), scormSource: this.toAstProperty(PropertyConfigKey.scormSource, scormSource), posterImage: this.toAstProperty(PropertyConfigKey.posterImage, posterImage), focusX: this.toAstProperty(PropertyConfigKey.focusX, focusX), focusY: this.toAstProperty(PropertyConfigKey.focusY, focusY), pointerLeft: this.toAstProperty(PropertyConfigKey.pointerLeft, pointerLeft), pointerTop: this.toAstProperty(PropertyConfigKey.pointerTop, pointerTop), listItemIndent: this.toAstProperty(PropertyConfigKey.listItemIndent, listItemIndent), backgroundWallpaper: this.toAstProperty(PropertyConfigKey.backgroundWallpaper, backgroundWallpaper), hasBookNavigation: this.toAstProperty(PropertyConfigKey.hasBookNavigation, hasBookNavigation), deeplink: this.toAstProperty(PropertyConfigKey.deeplink, deeplink), externalLink: this.toAstProperty(PropertyConfigKey.externalLink, externalLink), externalLinkText: this.toAstProperty(PropertyConfigKey.externalLinkText, externalLinkText), videoCallLink: this.toAstProperty(PropertyConfigKey.videoCallLink, videoCallLink), vendorUrl: this.toAstProperty(PropertyConfigKey.vendorUrl, vendorUrl), search: this.toAstProperty(PropertyConfigKey.search, search), bot: this.toAstProperty(PropertyConfigKey.bot, bot), duration: this.toAstProperty(PropertyConfigKey.duration, duration), referenceProperty: this.toAstProperty(PropertyConfigKey.property_reference, referenceProperty), list: this.toAstProperty(PropertyConfigKey.list, list), textReference: this.toAstProperty(PropertyConfigKey.textReference, textReference), isTracked: this.toAstProperty(PropertyConfigKey.isTracked, isTracked), isInfoOnly: this.toAstProperty(PropertyConfigKey.isInfoOnly, isInfoOnly), imageFirst: this.toAstProperty(PropertyConfigKey.imageFirst, imageFirst), activityType: this.toAstProperty(PropertyConfigKey.activityType, activityType), labelTrue: this.toAstProperty(PropertyConfigKey.labelTrue, labelTrue), labelFalse: this.toAstProperty(PropertyConfigKey.labelFalse, labelFalse), content2Buy: this.toAstProperty(PropertyConfigKey.content2Buy, content2Buy), mailingList: this.toAstProperty(PropertyConfigKey.mailingList, mailingList), buttonCaption: this.toAstProperty(PropertyConfigKey.buttonCaption, buttonCaption), callToActionUrl: this.toAstProperty(PropertyConfigKey.callToActionUrl, callToActionUrl), caption, quotedPerson: this.toAstProperty(PropertyConfigKey.quotedPerson, quotedPerson), partialAnswer: this.toAstProperty(PropertyConfigKey.partialAnswer, partialAnswer), reasonableNumOfChars: reasonableNumOfCharsProperty, sampleSolution: this.toAstProperty(PropertyConfigKey.property_sampleSolution, sampleSolution), additionalSolutions: this.toAstProperty(PropertyConfigKey.additionalSolutions, additionalSolutions), resolved: this.toAstProperty(PropertyConfigKey.resolved, resolved), resolvedDate: this.toAstProperty(PropertyConfigKey.resolvedDate, resolvedDate), resolvedBy: this.toAstProperty(PropertyConfigKey.resolvedBy, resolvedBy), maxCreatedBits: this.toAstProperty(PropertyConfigKey.maxCreatedBits, maxCreatedBits), maxDisplayLevel: this.toAstProperty(PropertyConfigKey.maxDisplayLevel, maxDisplayLevel), page: this.toAstProperty(PropertyConfigKey.page, page), productId: this.toAstProperty(PropertyConfigKey.productId, productId), product: this.toAstProperty(PropertyConfigKey.product, product), productList: this.toAstProperty(PropertyConfigKey.productList, productList), productVideo: this.toAstProperty(PropertyConfigKey.productVideo, productVideo), productVideoList: this.toAstProperty(PropertyConfigKey.productVideoList, productVideoList), productFolder: this.toAstProperty(PropertyConfigKey.productFolder, productFolder), technicalTerm,
56
- servings,
57
- ratingLevelStart,
58
- ratingLevelEnd, ratingLevelSelected: this.toAstProperty(PropertyConfigKey.ratingLevelSelected, ratingLevelSelected), title,
59
- subtitle, level: NumberUtils.asNumber(level), toc: this.toAstProperty(PropertyConfigKey.toc, toc), progress: this.toAstProperty(PropertyConfigKey.progress, progress), anchor,
60
- reference,
61
- referenceEnd,
62
- markConfig, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
63
- instruction }, this.toExample(isDefaultExample, example)), { imageSource,
64
- person,
65
- imagePlaceholder,
66
- resources,
67
- body,
68
- cardNode,
69
- footer,
70
- markup,
71
- parser,
62
+ const node = Object.assign(Object.assign({ bitType: data.bitType, bitLevel: data.bitLevel, textFormat, resourceType: ResourceTag.fromValue(data.resourceType), isCommented: data.isCommented,
63
+ // Properties
64
+ id: this.toAstProperty(PropertyConfigKey.id, data.id), internalComment: this.toAstProperty(PropertyConfigKey.internalComment, data.internalComment), externalId: this.toAstProperty(PropertyConfigKey.externalId, data.externalId), spaceId: this.toAstProperty(PropertyConfigKey.spaceId, data.spaceId), padletId: this.toAstProperty(PropertyConfigKey.padletId, data.padletId), jupyterId: this.toAstProperty(PropertyConfigKey.jupyterId, data.jupyterId), jupyterExecutionCount: this.toAstProperty(PropertyConfigKey.jupyterExecutionCount, data.jupyterExecutionCount), isPublic: this.toAstProperty(PropertyConfigKey.isPublic, data.isPublic), aiGenerated: this.toAstProperty(PropertyConfigKey.aiGenerated, data.aiGenerated), machineTranslated: this.toAstProperty(PropertyConfigKey.machineTranslated, data.machineTranslated), analyticsTag: this.toAstProperty(PropertyConfigKey.analyticsTag, data.analyticsTag), feedbackEngine: this.toAstProperty(PropertyConfigKey.feedbackEngine, data.feedbackEngine), feedbackType: this.toAstProperty(PropertyConfigKey.feedbackType, data.feedbackType), disableFeedback: this.toAstProperty(PropertyConfigKey.disableFeedback, data.disableFeedback), releaseVersion: this.toAstProperty(PropertyConfigKey.releaseVersion, data.releaseVersion), releaseKind: this.toAstProperty(PropertyConfigKey.releaseKind, data.releaseKind), releaseDate: this.toAstProperty(PropertyConfigKey.releaseDate, data.releaseDate), book: data.book, ageRange: this.toAstProperty(PropertyConfigKey.ageRange, data.ageRange), lang: this.toAstProperty(PropertyConfigKey.lang, data.lang), language: this.toAstProperty(PropertyConfigKey.language, data.language), publisher: this.toAstProperty(PropertyConfigKey.publisher, data.publisher), publisherName: this.toAstProperty(PropertyConfigKey.publisherName, data.publisherName), theme: this.toAstProperty(PropertyConfigKey.theme, data.theme), computerLanguage: this.toAstProperty(PropertyConfigKey.computerLanguage, data.computerLanguage), target: this.toAstProperty(PropertyConfigKey.target, data.target), slug: this.toAstProperty(PropertyConfigKey.slug, data.slug), tag: this.toAstProperty(PropertyConfigKey.tag, data.tag), reductionTag: this.toAstProperty(PropertyConfigKey.reductionTag, data.reductionTag), bubbleTag: this.toAstProperty(PropertyConfigKey.bubbleTag, data.bubbleTag), levelCEFRp: this.toAstProperty(PropertyConfigKey.levelCEFRp, data.levelCEFRp), levelCEFR: this.toAstProperty(PropertyConfigKey.levelCEFR, data.levelCEFR), levelILR: this.toAstProperty(PropertyConfigKey.levelILR, data.levelILR), levelACTFL: this.toAstProperty(PropertyConfigKey.levelACTFL, data.levelACTFL), icon: this.toAstProperty(PropertyConfigKey.icon, data.icon), iconTag: this.toAstProperty(PropertyConfigKey.iconTag, data.iconTag), colorTag: this.toAstProperty(PropertyConfigKey.colorTag, data.colorTag), flashcardSet: this.toAstProperty(PropertyConfigKey.flashcardSet, data.flashcardSet), subtype: this.toAstProperty(PropertyConfigKey.subtype, data.subtype), bookAlias: this.toAstProperty(PropertyConfigKey.bookAlias, data.bookAlias), coverImage: this.toAstProperty(PropertyConfigKey.coverImage, data.coverImage), coverColor: this.toAstProperty(PropertyConfigKey.coverColor, data.coverColor), publications: this.toAstProperty(PropertyConfigKey.publications, data.publications), author: this.toAstProperty(PropertyConfigKey.author, data.author), subject: this.toAstProperty(PropertyConfigKey.subject, data.subject), date: this.toAstProperty(PropertyConfigKey.date, data.date), dateEnd: this.toAstProperty(PropertyConfigKey.dateEnd, data.dateEnd), location: this.toAstProperty(PropertyConfigKey.location, data.location), kind: this.toAstProperty(PropertyConfigKey.kind, data.kind), hasMarkAsDone: this.toAstProperty(PropertyConfigKey.hasMarkAsDone, data.hasMarkAsDone), processHandIn: this.toAstProperty(PropertyConfigKey.processHandIn, data.processHandIn), action: this.toAstProperty(PropertyConfigKey.action, data.action), showInIndex: this.toAstProperty(PropertyConfigKey.showInIndex, data.showInIndex), blockId: this.toAstProperty(PropertyConfigKey.blockId, data.blockId), pageNo: this.toAstProperty(PropertyConfigKey.pageNo, data.pageNo), x: this.toAstProperty(PropertyConfigKey.x, data.x), y: this.toAstProperty(PropertyConfigKey.y, data.y), width: this.toAstProperty(PropertyConfigKey.width, data.width), height: this.toAstProperty(PropertyConfigKey.height, data.height), index: this.toAstProperty(PropertyConfigKey.index, data.index), classification: this.toAstProperty(PropertyConfigKey.classification, data.classification), availableClassifications: this.toAstProperty(PropertyConfigKey.availableClassifications, data.availableClassifications), allowedBit: this.toAstProperty(PropertyConfigKey.allowedBit, data.allowedBit), tableFixedHeader: this.toAstProperty(PropertyConfigKey.tableFixedHeader, data.tableFixedHeader), tableSearch: this.toAstProperty(PropertyConfigKey.tableSearch, data.tableSearch), tableSort: this.toAstProperty(PropertyConfigKey.tableSort, data.tableSort), tablePagination: this.toAstProperty(PropertyConfigKey.tablePagination, data.tablePagination), tablePaginationLimit: this.toAstProperty(PropertyConfigKey.tablePaginationLimit, data.tablePaginationLimit), tableHeight: this.toAstProperty(PropertyConfigKey.tableHeight, data.tableHeight), tableWhitespaceNoWrap: this.toAstProperty(PropertyConfigKey.tableWhitespaceNoWrap, data.tableWhitespaceNoWrap), tableAutoWidth: this.toAstProperty(PropertyConfigKey.tableAutoWidth, data.tableAutoWidth), tableResizableColumns: this.toAstProperty(PropertyConfigKey.tableResizableColumns, data.tableResizableColumns), tableColumnMinWidth: this.toAstProperty(PropertyConfigKey.tableColumnMinWidth, data.tableColumnMinWidth), quizCountItems: this.toAstProperty(PropertyConfigKey.quizCountItems, data.quizCountItems), quizStrikethroughSolutions: this.toAstProperty(PropertyConfigKey.quizStrikethroughSolutions, data.quizStrikethroughSolutions), codeLineNumbers: this.toAstProperty(PropertyConfigKey.codeLineNumbers, data.codeLineNumbers), codeMinimap: this.toAstProperty(PropertyConfigKey.codeMinimap, data.codeMinimap), stripePricingTableId: this.toAstProperty(PropertyConfigKey.stripePricingTableId, data.stripePricingTableId), stripePublishableKey: this.toAstProperty(PropertyConfigKey.stripePublishableKey, data.stripePublishableKey), thumbImage: this.toAstProperty(PropertyConfigKey.thumbImage, data.thumbImage), scormSource: this.toAstProperty(PropertyConfigKey.scormSource, data.scormSource), posterImage: this.toAstProperty(PropertyConfigKey.posterImage, data.posterImage), focusX: this.toAstProperty(PropertyConfigKey.focusX, data.focusX), focusY: this.toAstProperty(PropertyConfigKey.focusY, data.focusY), pointerLeft: this.toAstProperty(PropertyConfigKey.pointerLeft, data.pointerLeft), pointerTop: this.toAstProperty(PropertyConfigKey.pointerTop, data.pointerTop), listItemIndent: this.toAstProperty(PropertyConfigKey.listItemIndent, data.listItemIndent), backgroundWallpaper: this.toAstProperty(PropertyConfigKey.backgroundWallpaper, data.backgroundWallpaper), hasBookNavigation: this.toAstProperty(PropertyConfigKey.hasBookNavigation, data.hasBookNavigation), duration: this.toAstProperty(PropertyConfigKey.duration, data.duration), deeplink: this.toAstProperty(PropertyConfigKey.deeplink, data.deeplink), externalLink: this.toAstProperty(PropertyConfigKey.externalLink, data.externalLink), externalLinkText: this.toAstProperty(PropertyConfigKey.externalLinkText, data.externalLinkText), videoCallLink: this.toAstProperty(PropertyConfigKey.videoCallLink, data.videoCallLink), vendorUrl: this.toAstProperty(PropertyConfigKey.vendorUrl, data.vendorUrl), search: this.toAstProperty(PropertyConfigKey.search, data.search), list: this.toAstProperty(PropertyConfigKey.list, data.list), textReference: this.toAstProperty(PropertyConfigKey.textReference, data.textReference), isTracked: this.toAstProperty(PropertyConfigKey.isTracked, data.isTracked), isInfoOnly: this.toAstProperty(PropertyConfigKey.isInfoOnly, data.isInfoOnly), imageFirst: this.toAstProperty(PropertyConfigKey.imageFirst, data.imageFirst), activityType: this.toAstProperty(PropertyConfigKey.activityType, data.activityType), labelTrue: this.toAstProperty(PropertyConfigKey.labelTrue, data.labelTrue), labelFalse: this.toAstProperty(PropertyConfigKey.labelFalse, data.labelFalse), content2Buy: this.toAstProperty(PropertyConfigKey.content2Buy, data.content2Buy), mailingList: this.toAstProperty(PropertyConfigKey.mailingList, data.mailingList), buttonCaption: this.toAstProperty(PropertyConfigKey.buttonCaption, data.buttonCaption), callToActionUrl: this.toAstProperty(PropertyConfigKey.callToActionUrl, data.callToActionUrl), caption: this.handleJsonText(data.caption), quotedPerson: this.toAstProperty(PropertyConfigKey.quotedPerson, data.quotedPerson), reasonableNumOfChars: reasonableNumOfCharsProperty, resolved: this.toAstProperty(PropertyConfigKey.resolved, data.resolved), resolvedDate: this.toAstProperty(PropertyConfigKey.resolvedDate, data.resolvedDate), resolvedBy: this.toAstProperty(PropertyConfigKey.resolvedBy, data.resolvedBy), maxCreatedBits: this.toAstProperty(PropertyConfigKey.maxCreatedBits, data.maxCreatedBits), maxDisplayLevel: this.toAstProperty(PropertyConfigKey.maxDisplayLevel, data.maxDisplayLevel), page: this.toAstProperty(PropertyConfigKey.page, data.page), productId: this.toAstProperty(PropertyConfigKey.productId, data.productId), product: this.toAstProperty(PropertyConfigKey.product, data.product), productList: this.toAstProperty(PropertyConfigKey.productList, data.productList), productVideo: this.toAstProperty(PropertyConfigKey.productVideo, data.productVideo), productVideoList: this.toAstProperty(PropertyConfigKey.productVideoList, data.productVideoList), productFolder: this.toAstProperty(PropertyConfigKey.productFolder, data.productFolder), technicalTerm: this.buildTechnicalTerm(data.technicalTerm), servings: this.buildServings(data.servings), ratingLevelStart: this.buildRatingLevelStartEnd(data.ratingLevelStart), ratingLevelEnd: this.buildRatingLevelStartEnd(data.ratingLevelEnd), ratingLevelSelected: this.toAstProperty(PropertyConfigKey.ratingLevelSelected, data.ratingLevelSelected), markConfig: this.buildMarkConfigs(data.markConfig), imageSource: this.buildImageSource(data.imageSource), person: this.buildPerson(data.bitType, data.person), bot: this.toAstProperty(PropertyConfigKey.bot, data.bot), referenceProperty: this.toAstProperty(PropertyConfigKey.property_reference, data.referenceProperty),
65
+ // Book data
66
+ title: this.handleJsonText(data.title), subtitle: this.handleJsonText(data.subtitle), level: NumberUtils.asNumber(data.level), toc: this.toAstProperty(PropertyConfigKey.toc, data.toc), progress: this.toAstProperty(PropertyConfigKey.progress, data.progress), anchor: data.anchor, reference: data.reference, referenceEnd: data.referenceEnd,
67
+ // Item, Lead, Hint, Instruction
68
+ item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), pageNumber: this.handleJsonText(data.pageNumber), marginNumber: this.handleJsonText(data.marginNumber), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), partialAnswer: this.toAstProperty(PropertyConfigKey.partialAnswer, data.partialAnswer), sampleSolution: this.toAstProperty(PropertyConfigKey.property_sampleSolution, data.sampleSolution), additionalSolutions: this.toAstProperty(PropertyConfigKey.additionalSolutions, data.additionalSolutions) }, this.toExample(data.__isDefaultExample, data.example)), {
69
+ // Person
70
+ // Body
71
+ body: this.buildBody(textFormat, data.body), imagePlaceholder: ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(data.bitType, ResourceTag.image, (_b = data.imagePlaceholder) === null || _b === void 0 ? void 0 : _b.image)), resources: ArrayUtils.asArray(this.resourceBuilder.resourceFromResourceJson(data.bitType, data.resources)), cardNode, footer: this.buildFooter(data.footer), markup: data.markup, parser: data.parser,
72
72
  // Must always be last in the AST so key clashes are avoided correctly with other properties
73
- extraProperties: this.parseExtraProperties(extraProperties) });
73
+ extraProperties: this.parseExtraProperties(data.extraProperties),
74
+ // Private properties
75
+ __isDefaultExample: (_c = data.__isDefaultExample) !== null && _c !== void 0 ? _c : false });
74
76
  // Push reasonableNumOfChars down the tree for the interview bit
75
- if (Config.isOfBitType(bitType, BitType.interview)) {
76
- this.pushDownTree(undefined, undefined, cardNode, 'questions', PropertyConfigKey.reasonableNumOfChars, reasonableNumOfChars);
77
+ if (Config.isOfBitType(data.bitType, BitType.interview)) {
78
+ this.pushDownTree(undefined, undefined, cardNode, 'questions', PropertyConfigKey.reasonableNumOfChars, data.reasonableNumOfChars);
77
79
  }
78
80
  // Push isCaseSensitive down the tree for the cloze, match and match-matrix bits
79
- this.pushDownTree(body, [BodyBitType.gap], undefined, undefined, PropertyConfigKey.isCaseSensitive, isCaseSensitive);
80
- this.pushDownTree(undefined, undefined, cardNode, 'pairs', PropertyConfigKey.isCaseSensitive, isCaseSensitive);
81
- this.pushDownTree(undefined, undefined, cardNode, ['matrix', 'cells'], PropertyConfigKey.isCaseSensitive, isCaseSensitive);
82
- // If isDefaultExample is set at the bit level, push the default example down the tree to the relevant nodes
83
- this.pushExampleDownTree(body, cardNode, isDefaultExample, example);
81
+ this.pushDownTree([data.body, ...((_e = (_d = cardNode === null || cardNode === void 0 ? void 0 : cardNode.cardBits) === null || _d === void 0 ? void 0 : _d.map((cardBit) => cardBit.body)) !== null && _e !== void 0 ? _e : [])], [BodyBitType.gap], undefined, 'isCaseSensitive', PropertyConfigKey.isCaseSensitive, (_f = data.isCaseSensitive) !== null && _f !== void 0 ? _f : true);
82
+ this.pushDownTree(undefined, undefined, cardNode, 'pairs', PropertyConfigKey.isCaseSensitive, (_g = data.isCaseSensitive) !== null && _g !== void 0 ? _g : true);
83
+ this.pushDownTree(undefined, undefined, cardNode, ['matrix', 'cells'], PropertyConfigKey.isCaseSensitive, (_h = data.isCaseSensitive) !== null && _h !== void 0 ? _h : true);
84
+ // If __isDefaultExample is set at the bit level, push the default example down the tree to the relevant nodes
85
+ this.pushExampleDownTree(data.body, cardNode, data.__isDefaultExample, convertedExample.example);
84
86
  // Set default values
85
87
  this.setDefaultBitValues(node);
86
88
  // Set the 'isExample' flags
@@ -90,45 +92,88 @@ class Builder extends BaseBuilder {
90
92
  // Remove Unset Optionals
91
93
  ObjectUtils.removeUnwantedProperties(node, {
92
94
  ignoreAllFalse: true,
93
- ignoreEmptyString: ['example'],
95
+ ignoreUndefined: ['example'],
96
+ ignoreEmptyArrays: ['item', 'lead', 'pageNumber', 'marginNumber', 'hint', 'instruction'],
94
97
  });
95
98
  // Validate and correct invalid bits as much as possible
96
99
  return NodeValidator.validateBit(node);
97
100
  }
101
+ /**
102
+ * Build choice[] node
103
+ *
104
+ * @param data - data for the node
105
+ * @returns
106
+ */
107
+ buildChoices(data) {
108
+ if (!Array.isArray(data))
109
+ return undefined;
110
+ const nodes = data.map((d) => this.buildChoice(d)).filter((d) => d != null);
111
+ return nodes.length > 0 ? nodes : undefined;
112
+ }
98
113
  /**
99
114
  * Build choice node
100
115
  *
101
116
  * @param data - data for the node
102
117
  * @returns
103
118
  */
104
- choice(data) {
105
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
119
+ buildChoice(data) {
120
+ var _a;
121
+ if (!data)
122
+ return undefined;
106
123
  // NOTE: Node order is important and is defined here
107
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
108
- instruction }, this.toExampleBoolean(isDefaultExample, example));
124
+ const node = Object.assign({ choice: (_a = data.choice) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
109
125
  // Remove Unset Optionals
110
126
  ObjectUtils.removeUnwantedProperties(node, {
111
127
  ignoreAllFalse: true,
128
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
129
+ ignoreUndefined: ['example'],
112
130
  });
113
131
  return node;
114
132
  }
133
+ /**
134
+ * Build response[] node
135
+ *
136
+ * @param data - data for the node
137
+ * @returns
138
+ */
139
+ buildResponses(data) {
140
+ if (!Array.isArray(data))
141
+ return undefined;
142
+ const nodes = data.map((d) => this.buildResponse(d)).filter((d) => d != null);
143
+ return nodes.length > 0 ? nodes : undefined;
144
+ }
115
145
  /**
116
146
  * Build response node
117
147
  *
118
148
  * @param data - data for the node
119
149
  * @returns
120
150
  */
121
- response(data) {
122
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
151
+ buildResponse(data) {
152
+ var _a;
153
+ if (!data)
154
+ return undefined;
123
155
  // NOTE: Node order is important and is defined here
124
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
125
- instruction }, this.toExampleBoolean(isDefaultExample, example));
156
+ const node = Object.assign({ response: (_a = data.response) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
126
157
  // Remove Unset Optionals
127
158
  ObjectUtils.removeUnwantedProperties(node, {
128
159
  ignoreAllFalse: true,
160
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
161
+ ignoreUndefined: ['example'],
129
162
  });
130
163
  return node;
131
164
  }
165
+ /**
166
+ * Build bot response[] node
167
+ *
168
+ * @param data - data for the node
169
+ * @returns
170
+ */
171
+ buildBotResponses(data) {
172
+ if (!Array.isArray(data))
173
+ return undefined;
174
+ const nodes = data.map((d) => this.botResponse(d)).filter((d) => d != null);
175
+ return nodes.length > 0 ? nodes : undefined;
176
+ }
132
177
  /**
133
178
  * Build bot response node
134
179
  *
@@ -136,44 +181,79 @@ class Builder extends BaseBuilder {
136
181
  * @returns
137
182
  */
138
183
  botResponse(data) {
139
- const { response, reaction, feedback, item, lead, pageNumber, marginNumber, hint } = data;
184
+ var _a, _b, _c;
185
+ if (!data)
186
+ return undefined;
140
187
  // NOTE: Node order is important and is defined here
141
188
  const node = {
142
- response,
143
- reaction,
144
- feedback,
145
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
146
- hint,
189
+ response: (_a = data.response) !== null && _a !== void 0 ? _a : '',
190
+ reaction: (_b = data.reaction) !== null && _b !== void 0 ? _b : '',
191
+ feedback: (_c = data.feedback) !== null && _c !== void 0 ? _c : '',
192
+ item: this.handleJsonText(data.item),
193
+ lead: this.handleJsonText(data.lead),
194
+ hint: this.handleJsonText(data.hint),
147
195
  };
148
196
  // Remove Unset Optionals
149
197
  ObjectUtils.removeUnwantedProperties(node, {
150
198
  ignoreEmptyString: ['response', 'reaction', 'feedback'],
199
+ ignoreAllFalse: true,
200
+ ignoreEmptyArrays: ['item'],
201
+ ignoreUndefined: ['example'],
151
202
  });
152
203
  return node;
153
204
  }
205
+ /**
206
+ * Build quiz[] node
207
+ *
208
+ * @param data - data for the node
209
+ * @returns
210
+ */
211
+ buildQuizzes(data) {
212
+ if (!Array.isArray(data))
213
+ return undefined;
214
+ const nodes = data.map((d) => this.buildQuiz(d)).filter((d) => d != null);
215
+ return nodes.length > 0 ? nodes : undefined;
216
+ }
154
217
  /**
155
218
  * Build quiz node
156
219
  *
157
220
  * @param data - data for the node
158
221
  * @returns
159
222
  */
160
- quiz(data) {
161
- const { choices, responses, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
162
- // Push isDefaultExample down the tree
163
- this.pushExampleDownTreeBoolean(isDefaultExample, example, true, choices);
164
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, responses);
223
+ buildQuiz(data) {
224
+ if (!data)
225
+ return undefined;
226
+ const convertedExample = Object.assign({}, this.toExample(data.__isDefaultExample, data.__defaultExample));
227
+ let choices;
228
+ let responses;
229
+ if (data.choices) {
230
+ choices = this.buildChoices(data.choices);
231
+ // Push __isDefaultExample down the tree
232
+ this.pushExampleDownTreeBoolean(data.__isDefaultExample, convertedExample.example, true, choices);
233
+ }
234
+ else if (data.responses) {
235
+ responses = this.buildResponses(data.responses);
236
+ // Push __isDefaultExample down the tree
237
+ this.pushExampleDownTreeBoolean(data.__isDefaultExample, convertedExample.example, false, responses);
238
+ }
239
+ else {
240
+ // No choices or responses, not a valid quiz
241
+ return undefined;
242
+ }
165
243
  // NOTE: Node order is important and is defined here
166
244
  const node = {
167
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
168
- hint,
169
- instruction,
170
- isExample: isDefaultExample || example != null,
171
- choices,
172
- responses,
245
+ item: this.handleJsonText(data.item),
246
+ lead: this.handleJsonText(data.lead),
247
+ hint: this.handleJsonText(data.hint),
248
+ instruction: this.handleJsonText(data.instruction),
249
+ isExample: !!data.__defaultExample,
250
+ choices: choices,
251
+ responses: responses,
173
252
  };
174
253
  // Remove Unset Optionals
175
254
  ObjectUtils.removeUnwantedProperties(node, {
176
255
  ignoreAllFalse: true,
256
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
177
257
  });
178
258
  return node;
179
259
  }
@@ -183,69 +263,126 @@ class Builder extends BaseBuilder {
183
263
  * @param data - data for the node
184
264
  * @returns
185
265
  */
186
- heading(data) {
187
- var _a;
188
- const { forKeys, forValues } = data;
189
- if (forKeys == null)
266
+ buildHeading(data) {
267
+ var _a, _b, _c;
268
+ if (!data)
269
+ return undefined;
270
+ if (data.forKeys == null)
190
271
  return undefined;
191
272
  // NOTE: Node order is important and is defined here
192
273
  const node = {
193
- forKeys: forKeys || Breakscape.EMPTY_STRING,
194
- forValues: (_a = ArrayUtils.asArray(forValues)) !== null && _a !== void 0 ? _a : [],
274
+ forKeys: (_a = data.forKeys) !== null && _a !== void 0 ? _a : '',
275
+ forValues: (_c = (_b = data.forValues) !== null && _b !== void 0 ? _b : data.__forValuesDefault) !== null && _c !== void 0 ? _c : '',
195
276
  };
196
277
  // Remove Unset Optionals
197
- // ObjectUtils.removeUnwantedProperties(node);
278
+ ObjectUtils.removeUnwantedProperties(node, {
279
+ ignoreAllFalse: true,
280
+ ignoreEmptyString: ['forKeys', 'forValues'],
281
+ ignoreEmptyArrays: ['forValues'],
282
+ });
198
283
  return node;
199
284
  }
285
+ /**
286
+ * Build pair[] node
287
+ *
288
+ * @param data - data for the node
289
+ * @returns
290
+ */
291
+ buildPairs(bitType, data) {
292
+ if (!Array.isArray(data))
293
+ return undefined;
294
+ const nodes = data.map((d) => this.buildPair(bitType, d)).filter((d) => d != null);
295
+ return nodes.length > 0 ? nodes : undefined;
296
+ }
200
297
  /**
201
298
  * Build pair node
202
299
  *
203
300
  * @param data - data for the node
204
301
  * @returns
205
302
  */
206
- pair(data) {
207
- const { key, keyAudio, keyImage, values, item, lead, pageNumber, marginNumber, hint, instruction, isCaseSensitive, isDefaultExample, example, } = data;
303
+ buildPair(bitType, data) {
304
+ var _a, _b, _c, _d;
305
+ if (!data)
306
+ return undefined;
307
+ // Set default example
308
+ const defaultExample = Array.isArray(data.__valuesAst) && data.__valuesAst.length > 0 ? data.__valuesAst[0] : null;
309
+ // Process the keyAudio and keyImage resources
310
+ const keyAudio = (_a = ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(bitType, ResourceTag.audio, data.keyAudio))) === null || _a === void 0 ? void 0 : _a.audio;
311
+ const keyImage = (_b = ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(bitType, ResourceTag.image, data.keyImage))) === null || _b === void 0 ? void 0 : _b.image;
208
312
  // NOTE: Node order is important and is defined here
209
- const node = Object.assign(Object.assign({ key,
210
- keyAudio,
211
- keyImage, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
212
- instruction }, this.toExample(isDefaultExample, example)), { isCaseSensitive,
213
- values });
313
+ const node = Object.assign(Object.assign({ key: (_c = data.key) !== null && _c !== void 0 ? _c : '', keyAudio,
314
+ keyImage, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), isCaseSensitive: data.isCaseSensitive }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { values: (_d = data.values) !== null && _d !== void 0 ? _d : [], __valuesAst: data.__valuesAst });
214
315
  // Remove Unset Optionals
215
316
  ObjectUtils.removeUnwantedProperties(node, {
216
317
  ignoreAllFalse: true,
318
+ ignoreEmptyArrays: ['item', 'hint', 'instruction', 'values'],
319
+ ignoreUndefined: ['example', 'isCaseSensitive'],
217
320
  });
321
+ // if (node.key) {
322
+ // delete node.keyAudio;
323
+ // delete node.keyImage;
324
+ // }
325
+ // if (node.keyAudio != null) {
326
+ // delete node.key;
327
+ // delete node.keyImage;
328
+ // }
329
+ // if (node.keyImage != null) {
330
+ // delete node.key;
331
+ // delete node.keyAudio;
332
+ // }
218
333
  return node;
219
334
  }
335
+ /**
336
+ * Build matrix[] node
337
+ *
338
+ * @param data - data for the node
339
+ * @returns
340
+ */
341
+ buildMatricies(data) {
342
+ if (!Array.isArray(data))
343
+ return undefined;
344
+ const nodes = data.map((d) => this.buildMatrix(d)).filter((d) => d != null);
345
+ return nodes.length > 0 ? nodes : undefined;
346
+ }
220
347
  /**
221
348
  * Build matrix node
222
349
  *
223
350
  * @param data - data for the node
224
351
  * @returns
225
352
  */
226
- matrix(data) {
227
- const { key, cells, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample } = data;
353
+ buildMatrix(data) {
354
+ var _a, _b, _c;
355
+ if (!data)
356
+ return undefined;
357
+ // const convertedExample = {
358
+ // ...this.toExample(__isDefaultExample, example),
359
+ // };
360
+ // // Push __isDefaultExample down the tree
361
+ // this.pushExampleDownTreeBoolean(__isDefaultExample, convertedExample.example, true, choices);
362
+ // this.pushExampleDownTreeBoolean(__isDefaultExample, convertedExample.example, false, responses);
228
363
  let isExample = false;
229
364
  // Set isExample for matrix based on isExample for cells
230
- for (const c of cells !== null && cells !== void 0 ? cells : []) {
231
- if (isDefaultExample && !c.isExample) {
232
- c.isDefaultExample = true;
365
+ for (const c of (_a = data.cells) !== null && _a !== void 0 ? _a : []) {
366
+ if (data.__isDefaultExample && !c.isExample) {
233
367
  c.isExample = true;
234
368
  }
235
369
  isExample = c.isExample ? true : isExample;
236
370
  }
237
371
  // NOTE: Node order is important and is defined here
238
372
  const node = {
239
- key,
240
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
241
- hint,
242
- instruction,
373
+ key: (_b = data.key) !== null && _b !== void 0 ? _b : '',
374
+ item: this.handleJsonText(data.item),
375
+ lead: this.handleJsonText(data.lead),
376
+ hint: this.handleJsonText(data.hint),
377
+ instruction: this.handleJsonText(data.instruction),
243
378
  isExample,
244
- cells,
379
+ cells: ((_c = data.cells) !== null && _c !== void 0 ? _c : []).map((c) => this.buildMatrixCell(c)).filter((c) => c != null),
245
380
  };
246
381
  // Remove Unset Optionals
247
382
  ObjectUtils.removeUnwantedProperties(node, {
248
383
  ignoreAllFalse: true,
384
+ ignoreEmptyArrays: ['hint', 'item', 'cells'],
385
+ ignoreUndefined: ['isCaseSensitive'],
249
386
  });
250
387
  return node;
251
388
  }
@@ -255,15 +392,19 @@ class Builder extends BaseBuilder {
255
392
  * @param data - data for the node
256
393
  * @returns
257
394
  */
258
- matrixCell(data) {
259
- const { values, item, lead, pageNumber, marginNumber, hint, instruction, isCaseSensitive, isDefaultExample, example, } = data;
395
+ buildMatrixCell(data) {
396
+ var _a;
397
+ if (!data)
398
+ return undefined;
399
+ // Set default example
400
+ const defaultExample = Array.isArray(data.__valuesAst) && data.__valuesAst.length > 0 ? data.__valuesAst[0] : null;
260
401
  // NOTE: Node order is important and is defined here
261
- const node = Object.assign({ values, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
262
- instruction,
263
- isCaseSensitive }, this.toExample(isDefaultExample, example));
402
+ const node = Object.assign(Object.assign({ values: (_a = data.values) !== null && _a !== void 0 ? _a : [], item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), isCaseSensitive: data.isCaseSensitive }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { __valuesAst: data.__valuesAst });
264
403
  // Remove Unset Optionals
265
404
  ObjectUtils.removeUnwantedProperties(node, {
266
405
  ignoreAllFalse: true,
406
+ ignoreEmptyArrays: ['instruction', 'item', 'values'],
407
+ ignoreUndefined: ['example', 'isCaseSensitive'],
267
408
  });
268
409
  return node;
269
410
  }
@@ -273,12 +414,14 @@ class Builder extends BaseBuilder {
273
414
  * @param data - data for the node
274
415
  * @returns
275
416
  */
276
- table(data) {
277
- const { columns, rows } = data;
417
+ buildTable(dataIn) {
418
+ var _a, _b;
419
+ if (!dataIn)
420
+ return undefined;
278
421
  // NOTE: Node order is important and is defined here
279
422
  const node = {
280
- columns,
281
- rows,
423
+ columns: (_a = dataIn.columns) !== null && _a !== void 0 ? _a : [],
424
+ data: ((_b = dataIn.data) !== null && _b !== void 0 ? _b : []).map((row) => row !== null && row !== void 0 ? row : []),
282
425
  };
283
426
  // Remove Unset Optionals
284
427
  // ObjectUtils.removeUnwantedProperties(node, {
@@ -287,95 +430,234 @@ class Builder extends BaseBuilder {
287
430
  return node;
288
431
  }
289
432
  /**
290
- * Build question node
433
+ * Build question[] node
291
434
  *
292
435
  * @param data - data for the node
293
436
  * @returns
294
437
  */
295
- question(data) {
296
- const { question, partialAnswer, item, lead, pageNumber, marginNumber, hint, instruction, reasonableNumOfChars, sampleSolution, additionalSolutions, isDefaultExample, example, } = data;
297
- // NOTE: Node order is important and is defined here
298
- const node = Object.assign(Object.assign({ itemLead: this.itemLead(item, lead, pageNumber, marginNumber), question,
299
- partialAnswer,
300
- hint,
301
- instruction }, this.toExample(isDefaultExample, example)), { reasonableNumOfChars,
302
- sampleSolution,
303
- additionalSolutions });
304
- // Remove Unset Optionals
305
- ObjectUtils.removeUnwantedProperties(node, {
306
- ignoreEmptyString: ['question'],
307
- ignoreAllFalse: true,
308
- });
309
- return node;
438
+ buildQuestions(data) {
439
+ if (!Array.isArray(data))
440
+ return undefined;
441
+ const nodes = data.map((d) => this.buildQuestion(d)).filter((d) => d != null);
442
+ return nodes.length > 0 ? nodes : undefined;
310
443
  }
311
444
  /**
312
- * Build ingredient node
445
+ * Build question node
313
446
  *
314
447
  * @param data - data for the node
315
448
  * @returns
316
449
  */
317
- ingredient(data) {
318
- const { title, checked, item, quantity, unit, unitAbbr, decimalPlaces, disableCalculation } = data;
450
+ buildQuestion(data) {
451
+ var _a, _b, _c, _d, _e;
452
+ if (!data)
453
+ return undefined;
454
+ // Set default example
455
+ const defaultExample = data.__sampleSolutionAst;
319
456
  // NOTE: Node order is important and is defined here
320
- const node = {
321
- title,
322
- checked: checked !== null && checked !== void 0 ? checked : false,
323
- item,
324
- quantity,
325
- unit,
326
- unitAbbr,
327
- decimalPlaces,
328
- disableCalculation,
329
- };
457
+ const node = Object.assign(Object.assign({ question: (_a = data.question) !== null && _a !== void 0 ? _a : '', partialAnswer: (_b = data.partialAnswer) !== null && _b !== void 0 ? _b : '', sampleSolution: (_c = data.sampleSolution) !== null && _c !== void 0 ? _c : '', additionalSolutions: ((_d = data.additionalSolutions) !== null && _d !== void 0 ? _d : undefined), reasonableNumOfChars: ((_e = data.reasonableNumOfChars) !== null && _e !== void 0 ? _e : undefined), item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { __sampleSolutionAst: data.__sampleSolutionAst });
330
458
  // Remove Unset Optionals
331
459
  ObjectUtils.removeUnwantedProperties(node, {
332
460
  ignoreAllFalse: true,
461
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
462
+ ignoreUndefined: ['example'],
463
+ ignoreEmptyString: ['question', 'partialAnswer', 'sampleSolution'],
333
464
  });
334
465
  return node;
335
466
  }
336
467
  /**
337
- * Build body node
468
+ * Build ingredient[] node
338
469
  *
339
470
  * @param data - data for the node
340
471
  * @returns
341
472
  */
342
- body(data) {
343
- const { bodyParts, bodyJson } = data;
344
- const node = {
345
- bodyParts,
346
- bodyJson,
347
- };
348
- return node;
473
+ buildIngredients(data) {
474
+ if (!Array.isArray(data))
475
+ return undefined;
476
+ const nodes = data.map((d) => this.buildIngredient(d)).filter((d) => d != null);
477
+ return nodes.length > 0 ? nodes : undefined;
349
478
  }
350
479
  /**
351
- * Build bodyPartText node
480
+ * Build ingredient node
352
481
  *
353
482
  * @param data - data for the node
354
- * @param isPlain - true if plain text, otherwise false
355
483
  * @returns
356
484
  */
357
- bodyText(data, isPlain) {
358
- const { text } = data;
485
+ buildIngredient(data) {
486
+ var _a, _b, _c, _d, _e, _f, _g, _h;
487
+ if (!data)
488
+ return undefined;
359
489
  // NOTE: Node order is important and is defined here
360
490
  const node = {
361
- type: BodyBitType.text,
362
- data: {
363
- bodyText: text,
364
- isPlain,
365
- },
491
+ title: (_a = data.title) !== null && _a !== void 0 ? _a : '',
492
+ checked: (_b = data.checked) !== null && _b !== void 0 ? _b : false,
493
+ item: (_c = data.item) !== null && _c !== void 0 ? _c : '',
494
+ quantity: (_d = data.quantity) !== null && _d !== void 0 ? _d : 0,
495
+ unit: (_e = data.unit) !== null && _e !== void 0 ? _e : '',
496
+ unitAbbr: (_f = data.unitAbbr) !== null && _f !== void 0 ? _f : '',
497
+ decimalPlaces: (_g = data.decimalPlaces) !== null && _g !== void 0 ? _g : 1,
498
+ disableCalculation: (_h = data.disableCalculation) !== null && _h !== void 0 ? _h : false,
366
499
  };
500
+ // Remove Unset Optionals
501
+ ObjectUtils.removeUnwantedProperties(node, {
502
+ ignoreAllFalse: true,
503
+ // ignoreAllEmptyArrays: true,
504
+ // ignoreUndefined: ['example'],
505
+ ignoreEmptyString: ['item', 'unit'],
506
+ });
367
507
  return node;
368
508
  }
369
509
  /**
370
- * Build footer node
510
+ * Build body node
511
+ * - Handles JSON, Bitmark text, and plain text
512
+ * - body: set to either string, TextAst, or JSON
513
+ * - bodyBits: set to array of BodyBitJson (will be validated and merged into body if it is a string)
514
+ * - placeholders: set to placeholders from v2 JSON when body is a v2 JSON string
515
+ * - bodyString: set to the original string if body is a string (only used for card body)
371
516
  *
372
517
  * @param data - data for the node
373
518
  * @returns
374
519
  */
375
- footer(data) {
376
- const { footerParts } = data;
520
+ buildBody(textFormat, data) {
521
+ if (!data)
522
+ return undefined;
523
+ let body;
524
+ const bodyBits = [];
525
+ const placeholders = data.placeholders;
526
+ const bodyString = data.bodyString;
527
+ // Handle JSON type body
528
+ const handleJsonBody = () => {
529
+ // Attempt to parse a string body as JSON to support the legacy format
530
+ if (typeof data.body === 'string') {
531
+ try {
532
+ body = JSON.parse(data.body);
533
+ }
534
+ catch (e) {
535
+ // Could not parse JSON - set body to null
536
+ body = null;
537
+ }
538
+ }
539
+ else {
540
+ body = data.body;
541
+ }
542
+ };
543
+ // Handle Bitmark text type body (both AST v3 and plain text v2)
544
+ const handleBitmarkTextBody = () => {
545
+ var _a;
546
+ let rawBody = data.body;
547
+ let bodyStr;
548
+ const placeholderNodes = {};
549
+ // TODO - process body bits through the correct builders.
550
+ if (StringUtils.isString(data.body)) {
551
+ // Body is a string (legacy bitmark v2, or not bitmark--/++)
552
+ bodyStr = ((_a = data.body) !== null && _a !== void 0 ? _a : '').trim();
553
+ rawBody = [];
554
+ }
555
+ else if (Array.isArray(data.body)) {
556
+ // Body is an array (prosemirror like JSON)
557
+ // Already in the correct format
558
+ }
559
+ else {
560
+ // body is invalid
561
+ rawBody = [];
562
+ }
563
+ if (placeholders) {
564
+ for (const [key, val] of Object.entries(placeholders)) {
565
+ // const bit = this.bodyBitToAst(val);
566
+ // placeholderNodes[key] = bit as BodyBit;
567
+ placeholderNodes[key] = val;
568
+ }
569
+ }
570
+ if (bodyStr) {
571
+ // Breakscape
572
+ bodyStr = Breakscape.breakscape(bodyStr, {
573
+ textFormat: TextFormat.bitmarkMinusMinus, // Treat as bitmark-- for v2 text
574
+ });
575
+ // Convert placeholders {1} to [!1], etc.
576
+ let index = 0;
577
+ const newPlaceholderNodes = [];
578
+ for (const [key, val] of Object.entries(placeholderNodes)) {
579
+ if (bodyStr) {
580
+ const newKey = `[!${index}]`;
581
+ bodyStr = bodyStr.replace(`${key}`, newKey);
582
+ newPlaceholderNodes.push(val);
583
+ index++;
584
+ }
585
+ }
586
+ // Convert the body string to AST
587
+ rawBody = this.textParser.toAst(bodyStr, {
588
+ textFormat: TextFormat.bitmarkMinusMinus, // Treat as bitmark-- for v2 text
589
+ });
590
+ const replaceBitsRecursive = (bodyText) => {
591
+ for (let i = 0, len = bodyText.length; i < len; i++) {
592
+ const bodyPart = bodyText[i];
593
+ if (bodyPart.type === 'bit') {
594
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
595
+ const index = bodyPart.index;
596
+ if (newPlaceholderNodes[index] != null) {
597
+ bodyText[i] = newPlaceholderNodes[index];
598
+ }
599
+ }
600
+ else {
601
+ if (bodyPart.content)
602
+ replaceBitsRecursive(bodyPart.content);
603
+ }
604
+ }
605
+ };
606
+ // Replace the placeholders with the AST
607
+ replaceBitsRecursive(rawBody);
608
+ }
609
+ // Process the body bits to ensure they are valid
610
+ this.textParser.walkBodyBits(rawBody, (parent, index, bodyBit) => {
611
+ // Ensure the body bit is valid
612
+ let parsedBit;
613
+ switch (bodyBit.type) {
614
+ case BodyBitType.gap:
615
+ parsedBit = this.buildGap(bodyBit);
616
+ break;
617
+ case BodyBitType.mark:
618
+ parsedBit = this.buildMark(bodyBit);
619
+ break;
620
+ case BodyBitType.select:
621
+ parsedBit = this.buildSelect(bodyBit);
622
+ break;
623
+ case BodyBitType.highlight:
624
+ parsedBit = this.buildHighlight(bodyBit);
625
+ break;
626
+ default:
627
+ // TODO?? Ensure other parts are valid
628
+ }
629
+ if (parsedBit != undefined) {
630
+ parent[index] = parsedBit;
631
+ bodyBits.push(parsedBit);
632
+ }
633
+ });
634
+ // Set the body
635
+ body = rawBody;
636
+ // Mark the body as text
637
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
638
+ body.__tag = 'text';
639
+ };
640
+ const handlePlainTextBody = () => {
641
+ body = data.body;
642
+ };
643
+ const isBitmarkText = textFormat === TextFormat.bitmarkMinusMinus || textFormat === TextFormat.bitmarkPlusPlus;
644
+ if (textFormat === TextFormat.json) {
645
+ // JSON
646
+ handleJsonBody();
647
+ }
648
+ else if (isBitmarkText) {
649
+ // Bitmark text (either ast or string)
650
+ handleBitmarkTextBody();
651
+ }
652
+ else {
653
+ // Text but not bitmark (plain text)
654
+ handlePlainTextBody();
655
+ }
377
656
  const node = {
378
- footerParts,
657
+ body,
658
+ bodyBits,
659
+ bodyString,
660
+ // Placeholders are only ever parsed into AST, never stored directly
379
661
  };
380
662
  return node;
381
663
  }
@@ -385,12 +667,11 @@ class Builder extends BaseBuilder {
385
667
  * @param data - data for the node
386
668
  * @returns
387
669
  */
388
- footerText(data, isPlain) {
389
- const { text } = data;
390
- // NOTE: Node order is important and is defined here
670
+ buildFooter(data) {
671
+ if (!data)
672
+ return undefined;
391
673
  const node = {
392
- footerText: text,
393
- isPlain,
674
+ footer: this.handleJsonText(data.footer),
394
675
  };
395
676
  return node;
396
677
  }
@@ -400,38 +681,54 @@ class Builder extends BaseBuilder {
400
681
  * @param data - data for the node
401
682
  * @returns
402
683
  */
403
- gap(data) {
404
- const { solutions, item, lead, pageNumber, marginNumber, hint, instruction, isCaseSensitive, isDefaultExample, example, } = data;
405
- // const defaultExample = Array.isArray(solutions) && solutions.length === 1 ? solutions[0] : null;
684
+ buildGap(data) {
685
+ var _a;
686
+ if (!data)
687
+ return undefined;
688
+ // Set default example
689
+ const defaultExample = Array.isArray(data.__solutionsAst) && data.__solutionsAst.length > 0 ? data.__solutionsAst[0] : null;
406
690
  // NOTE: Node order is important and is defined here
407
- const node = {
408
- type: BodyBitType.gap,
409
- data: Object.assign({ solutions, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
410
- instruction,
411
- isCaseSensitive }, this.toExample(isDefaultExample, example)),
412
- };
691
+ const node = Object.assign(Object.assign({ type: BodyBitType.gap, solutions: (_a = data.solutions) !== null && _a !== void 0 ? _a : [], item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), isCaseSensitive: data.isCaseSensitive }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { __solutionsAst: data.__solutionsAst });
413
692
  // Remove Unset Optionals
414
693
  ObjectUtils.removeUnwantedProperties(node, {
415
694
  ignoreAllFalse: true,
695
+ ignoreAllEmptyArrays: true,
696
+ ignoreUndefined: ['example', 'isCaseSensitive'],
416
697
  });
417
698
  return node;
418
699
  }
700
+ /**
701
+ * Build mark configs node
702
+ *
703
+ * @param data - data for the node
704
+ * @returns
705
+ */
706
+ buildMarkConfigs(data) {
707
+ if (!Array.isArray(data))
708
+ return undefined;
709
+ const nodes = data.map((d) => this.buildMarkConfig(d)).filter((d) => d != null);
710
+ return nodes.length > 0 ? nodes : undefined;
711
+ }
419
712
  /**
420
713
  * Build mark config node
421
714
  *
422
715
  * @param data - data for the node
423
716
  * @returns
424
717
  */
425
- markConfig(data) {
426
- const { mark, color, emphasis } = data;
718
+ buildMarkConfig(data) {
719
+ var _a, _b, _c;
720
+ if (!data)
721
+ return undefined;
427
722
  // NOTE: Node order is important and is defined here
428
723
  const node = {
429
- mark,
430
- color,
431
- emphasis,
724
+ mark: (_a = data.mark) !== null && _a !== void 0 ? _a : 'unknown',
725
+ color: (_b = data.color) !== null && _b !== void 0 ? _b : '',
726
+ emphasis: (_c = data.emphasis) !== null && _c !== void 0 ? _c : '',
432
727
  };
433
728
  // Remove Unset Optionals
434
- ObjectUtils.removeUnwantedProperties(node);
729
+ ObjectUtils.removeUnwantedProperties(node, {
730
+ ignoreAllEmptyString: true,
731
+ });
435
732
  return node;
436
733
  }
437
734
  /**
@@ -440,17 +737,19 @@ class Builder extends BaseBuilder {
440
737
  * @param data - data for the node
441
738
  * @returns
442
739
  */
443
- mark(data) {
444
- const { solution, mark, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
740
+ buildMark(data) {
741
+ var _a, _b;
742
+ if (!data)
743
+ return undefined;
445
744
  // NOTE: Node order is important and is defined here
446
- const node = {
447
- type: BodyBitType.mark,
448
- data: Object.assign({ solution,
449
- mark, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
450
- instruction }, this.toExample(isDefaultExample, example)),
451
- };
745
+ const node = Object.assign({ type: BodyBitType.mark, solution: (_a = data.solution) !== null && _a !== void 0 ? _a : '', mark: (_b = data.mark) !== null && _b !== void 0 ? _b : '', item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, true));
452
746
  // Remove Unset Optionals
453
- ObjectUtils.removeUnwantedProperties(node);
747
+ ObjectUtils.removeUnwantedProperties(node, {
748
+ ignoreAllFalse: true,
749
+ ignoreAllEmptyArrays: true,
750
+ ignoreUndefined: ['example'],
751
+ ignoreEmptyString: ['solution', 'mark'],
752
+ });
454
753
  return node;
455
754
  }
456
755
  /**
@@ -459,40 +758,49 @@ class Builder extends BaseBuilder {
459
758
  * @param data - data for the node
460
759
  * @returns
461
760
  */
462
- select(data) {
463
- const { options, prefix, postfix, item, lead, pageNumber, marginNumber, hint, instruction } = data;
761
+ buildSelect(data) {
762
+ var _a, _b, _c;
763
+ if (!data)
764
+ return undefined;
464
765
  // NOTE: Node order is important and is defined here
465
- const node = {
466
- type: BodyBitType.select,
467
- data: {
468
- prefix,
469
- options,
470
- postfix,
471
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
472
- hint,
473
- instruction,
474
- },
475
- };
766
+ const node = Object.assign(Object.assign({ type: BodyBitType.select, options: (_a = this.buildSelectOptions(data.options)) !== null && _a !== void 0 ? _a : [], prefix: (_b = data.prefix) !== null && _b !== void 0 ? _b : '', postfix: (_c = data.postfix) !== null && _c !== void 0 ? _c : '', item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(false, undefined, undefined)), { __hintString: data.__hintString, __instructionString: data.__instructionString });
476
767
  // Remove Unset Optionals
477
768
  ObjectUtils.removeUnwantedProperties(node, {
478
769
  ignoreAllFalse: true,
770
+ ignoreAllEmptyArrays: true,
771
+ ignoreEmptyString: ['prefix', 'postfix'],
479
772
  });
480
773
  return node;
481
774
  }
775
+ /**
776
+ * Build selectOption[] node
777
+ *
778
+ * @param data - data for the node
779
+ * @returns
780
+ */
781
+ buildSelectOptions(data) {
782
+ if (!Array.isArray(data))
783
+ return undefined;
784
+ const nodes = data.map((d) => this.buildSelectOption(d)).filter((d) => d != null);
785
+ return nodes.length > 0 ? nodes : undefined;
786
+ }
482
787
  /**
483
788
  * Build selectOption node
484
789
  *
485
790
  * @param data - data for the node
486
791
  * @returns
487
792
  */
488
- selectOption(data) {
489
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
793
+ buildSelectOption(data) {
794
+ var _a;
795
+ if (!data)
796
+ return undefined;
490
797
  // NOTE: Node order is important and is defined here
491
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
492
- instruction }, this.toExample(isDefaultExample, example));
798
+ const node = Object.assign({ text: (_a = data.text) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
493
799
  // Remove Unset Optionals
494
800
  ObjectUtils.removeUnwantedProperties(node, {
495
801
  ignoreAllFalse: true,
802
+ ignoreAllEmptyArrays: true,
803
+ ignoreUndefined: ['example'],
496
804
  });
497
805
  return node;
498
806
  }
@@ -502,95 +810,143 @@ class Builder extends BaseBuilder {
502
810
  * @param data - data for the node
503
811
  * @returns
504
812
  */
505
- highlight(data) {
506
- const { texts, prefix, postfix, item, lead, pageNumber, marginNumber, hint, instruction } = data;
813
+ buildHighlight(data) {
814
+ var _a, _b, _c;
815
+ if (!data)
816
+ return undefined;
507
817
  // NOTE: Node order is important and is defined here
508
- const node = {
509
- type: BodyBitType.highlight,
510
- data: {
511
- prefix,
512
- texts,
513
- postfix,
514
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
515
- hint,
516
- instruction,
517
- },
518
- };
818
+ const node = Object.assign({ type: BodyBitType.highlight, texts: (_a = this.buildHighlightTexts(data.texts)) !== null && _a !== void 0 ? _a : [], prefix: (_b = data.prefix) !== null && _b !== void 0 ? _b : '', postfix: (_c = data.postfix) !== null && _c !== void 0 ? _c : '', item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(false, undefined, undefined));
519
819
  // Remove Unset Optionals
520
820
  ObjectUtils.removeUnwantedProperties(node, {
521
821
  ignoreAllFalse: true,
822
+ ignoreAllEmptyArrays: true,
823
+ ignoreEmptyString: ['prefix', 'postfix'],
522
824
  });
523
825
  return node;
524
826
  }
827
+ /**
828
+ * Build highlightText[] node
829
+ *
830
+ * @param data - data for the node
831
+ * @returns
832
+ */
833
+ buildHighlightTexts(data) {
834
+ if (!Array.isArray(data))
835
+ return undefined;
836
+ const nodes = data.map((d) => this.buildHighlightText(d)).filter((d) => d != null);
837
+ return nodes.length > 0 ? nodes : undefined;
838
+ }
525
839
  /**
526
840
  * Build highlightText node
527
841
  *
528
842
  * @param data - data for the node
529
843
  * @returns
530
844
  */
531
- highlightText(data) {
532
- const { text, isCorrect, isHighlighted, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, } = data;
845
+ buildHighlightText(data) {
846
+ var _a;
847
+ if (!data)
848
+ return undefined;
533
849
  // NOTE: Node order is important and is defined here
534
- const node = Object.assign({ text, isCorrect: !!isCorrect, isHighlighted: !!isHighlighted, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
535
- instruction }, this.toExample(isDefaultExample, example));
850
+ const node = Object.assign({ text: (_a = data.text) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, isHighlighted: !!data.isHighlighted, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
536
851
  // Remove Unset Optionals
537
852
  ObjectUtils.removeUnwantedProperties(node, {
538
853
  ignoreAllFalse: true,
854
+ ignoreAllEmptyArrays: true,
855
+ ignoreUndefined: ['example'],
539
856
  });
540
857
  return node;
541
858
  }
859
+ /**
860
+ * Build flashcards node
861
+ *
862
+ * @param data - data for the node
863
+ * @returns
864
+ */
865
+ buildFlashcards(data) {
866
+ if (!Array.isArray(data))
867
+ return undefined;
868
+ const nodes = data.map((d) => this.buildFlashcard(d)).filter((d) => d != null);
869
+ return nodes.length > 0 ? nodes : undefined;
870
+ }
542
871
  /**
543
872
  * Build flashcard node
544
873
  *
545
874
  * @param data - data for the node
546
875
  * @returns
547
876
  */
548
- flashcard(data) {
549
- const { question, answer, alternativeAnswers, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, } = data;
877
+ buildFlashcard(data) {
878
+ if (!data)
879
+ return undefined;
550
880
  // NOTE: Node order is important and is defined here
551
- const node = Object.assign({ question,
552
- answer,
553
- alternativeAnswers, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
554
- instruction }, this.toExampleBoolean(isDefaultExample, example));
881
+ const node = Object.assign({ question: this.handleJsonText(data.question), answer: this.handleJsonText(data.answer), alternativeAnswers: this.handleJsonText(data.alternativeAnswers), item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, true));
555
882
  // Remove Unset Optionals
556
883
  ObjectUtils.removeUnwantedProperties(node, {
557
884
  ignoreAllFalse: true,
885
+ ignoreEmptyArrays: ['question', 'answer', 'alternativeAnswers', 'item', 'hint', 'instruction'],
886
+ ignoreUndefined: ['example'],
558
887
  });
559
888
  return node;
560
889
  }
890
+ /**
891
+ * Build definitionListItem[] node
892
+ *
893
+ * @param data - data for the node
894
+ * @returns
895
+ */
896
+ buildDefinitionList(data) {
897
+ if (!Array.isArray(data))
898
+ return undefined;
899
+ const nodes = data.map((d) => this.buildDefinitionListItem(d)).filter((d) => d != null);
900
+ return nodes.length > 0 ? nodes : undefined;
901
+ }
561
902
  /**
562
903
  * Build definitionListItem node
563
904
  *
564
905
  * @param data - data for the node
565
906
  * @returns
566
907
  */
567
- definitionListItem(data) {
568
- const { term, description, alternativeDefinitions, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, } = data;
908
+ buildDefinitionListItem(data) {
909
+ if (!data)
910
+ return undefined;
569
911
  // NOTE: Node order is important and is defined here
570
- const node = Object.assign({ term,
571
- description,
572
- alternativeDefinitions, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
573
- instruction }, this.toExampleBoolean(isDefaultExample, example));
912
+ const node = Object.assign({ term: this.handleJsonText(data.term, TextFormat.bitmarkMinusMinus), definition: this.handleJsonText(data.definition), alternativeDefinitions: this.handleJsonText(data.alternativeDefinitions), item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, true));
574
913
  // Remove Unset Optionals
575
914
  ObjectUtils.removeUnwantedProperties(node, {
576
915
  ignoreAllFalse: true,
916
+ ignoreEmptyArrays: ['question', 'answer', 'alternativeDefinitions', 'item', 'hint', 'instruction'],
917
+ ignoreUndefined: ['example'],
577
918
  });
578
919
  return node;
579
920
  }
921
+ /**
922
+ * Build statement[] node
923
+ *
924
+ * @param data - data for the node
925
+ * @returns
926
+ */
927
+ buildStatements(data) {
928
+ if (!Array.isArray(data))
929
+ return undefined;
930
+ const nodes = data.map((d) => this.buildStatement(d)).filter((d) => d != null);
931
+ return nodes.length > 0 ? nodes : undefined;
932
+ }
580
933
  /**
581
934
  * Build statement node
582
935
  *
583
936
  * @param data - data for the node
584
937
  * @returns
585
938
  */
586
- statement(data) {
587
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
939
+ buildStatement(data) {
940
+ var _a;
941
+ if (!data)
942
+ return undefined;
588
943
  // NOTE: Node order is important and is defined here
589
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
590
- instruction }, this.toExampleBoolean(isDefaultExample, example));
944
+ const node = Object.assign({ statement: (_a = data.statement) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
591
945
  // Remove Unset Optionals
592
946
  ObjectUtils.removeUnwantedProperties(node, {
593
947
  ignoreAllFalse: true,
948
+ // ignoreAllEmptyArrays: true,
949
+ ignoreUndefined: ['example'],
594
950
  });
595
951
  return node;
596
952
  }
@@ -600,19 +956,23 @@ class Builder extends BaseBuilder {
600
956
  * @param data - data for the node
601
957
  * @returns
602
958
  */
603
- imageSource(data) {
959
+ buildImageSource(data) {
960
+ if (!data)
961
+ return undefined;
604
962
  const { url, mockupId, size, format, trim } = data;
605
963
  // NOTE: Node order is important and is defined here
606
964
  const node = {
607
- url,
608
- mockupId,
609
- size,
610
- format,
611
- trim,
965
+ url: url !== null && url !== void 0 ? url : '',
966
+ mockupId: mockupId !== null && mockupId !== void 0 ? mockupId : '',
967
+ size: (size !== null && size !== void 0 ? size : null),
968
+ format: (format !== null && format !== void 0 ? format : null),
969
+ trim: (BooleanUtils.isBoolean(trim) ? trim : null),
612
970
  };
613
971
  // Remove Unset Optionals
614
972
  ObjectUtils.removeUnwantedProperties(node, {
615
973
  ignoreFalse: ['trim'],
974
+ ignoreEmptyString: ['url', 'mockupId'],
975
+ ignoreAllUndefined: true,
616
976
  });
617
977
  return node;
618
978
  }
@@ -622,16 +982,23 @@ class Builder extends BaseBuilder {
622
982
  * @param data - data for the node
623
983
  * @returns
624
984
  */
625
- person(data) {
985
+ buildPerson(bitType, data) {
986
+ var _a;
987
+ if (!data)
988
+ return undefined;
626
989
  const { name, title, avatarImage } = data;
990
+ // { name: string; title?: string; avatarImage?: ImageResourceJson }
627
991
  // NOTE: Node order is important and is defined here
628
992
  const node = {
629
- name,
630
- title,
631
- avatarImage,
993
+ name: name !== null && name !== void 0 ? name : '',
994
+ title: (title !== null && title !== void 0 ? title : undefined),
995
+ avatarImage: (_a = ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(bitType, ResourceTag.image, avatarImage))) === null || _a === void 0 ? void 0 : _a.image,
632
996
  };
633
997
  // Remove Unset Optionals
634
- ObjectUtils.removeUnwantedProperties(node);
998
+ ObjectUtils.removeUnwantedProperties(node, {
999
+ ignoreEmptyString: ['name'],
1000
+ ignoreAllUndefined: true,
1001
+ });
635
1002
  return node;
636
1003
  }
637
1004
  /**
@@ -640,15 +1007,20 @@ class Builder extends BaseBuilder {
640
1007
  * @param data - data for the node
641
1008
  * @returns
642
1009
  */
643
- technicalTerm(data) {
1010
+ buildTechnicalTerm(data) {
1011
+ if (!data)
1012
+ return undefined;
644
1013
  const { technicalTerm, lang } = data;
645
1014
  // NOTE: Node order is important and is defined here
646
1015
  const node = {
647
- technicalTerm,
648
- lang,
1016
+ technicalTerm: technicalTerm !== null && technicalTerm !== void 0 ? technicalTerm : '',
1017
+ lang: lang !== null && lang !== void 0 ? lang : '',
649
1018
  };
650
1019
  // Remove Unset Optionals
651
- ObjectUtils.removeUnwantedProperties(node);
1020
+ ObjectUtils.removeUnwantedProperties(node, {
1021
+ ignoreEmptyString: ['technicalTerm'],
1022
+ // ignoreAllUndefined: true,
1023
+ });
652
1024
  return node;
653
1025
  }
654
1026
  /**
@@ -657,19 +1029,24 @@ class Builder extends BaseBuilder {
657
1029
  * @param data - data for the node
658
1030
  * @returns
659
1031
  */
660
- servings(data) {
1032
+ buildServings(data) {
1033
+ if (!data)
1034
+ return undefined;
661
1035
  const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = data;
662
1036
  // NOTE: Node order is important and is defined here
663
1037
  const node = {
664
- servings,
665
- unit,
666
- unitAbbr,
667
- decimalPlaces,
668
- disableCalculation,
669
- hint,
1038
+ servings: servings !== null && servings !== void 0 ? servings : 0,
1039
+ unit: unit !== null && unit !== void 0 ? unit : '',
1040
+ unitAbbr: unitAbbr !== null && unitAbbr !== void 0 ? unitAbbr : '',
1041
+ decimalPlaces: decimalPlaces !== null && decimalPlaces !== void 0 ? decimalPlaces : 1,
1042
+ disableCalculation: disableCalculation !== null && disableCalculation !== void 0 ? disableCalculation : false,
1043
+ hint: hint !== null && hint !== void 0 ? hint : '',
670
1044
  };
671
1045
  // Remove Unset Optionals
672
- ObjectUtils.removeUnwantedProperties(node);
1046
+ ObjectUtils.removeUnwantedProperties(node, {
1047
+ ignoreEmptyString: ['servings', 'unit'],
1048
+ // ignoreAllUndefined: true,
1049
+ });
673
1050
  return node;
674
1051
  }
675
1052
  /**
@@ -678,15 +1055,20 @@ class Builder extends BaseBuilder {
678
1055
  * @param data - data for the node
679
1056
  * @returns
680
1057
  */
681
- ratingLevelStartEnd(data) {
1058
+ buildRatingLevelStartEnd(data) {
1059
+ if (!data)
1060
+ return undefined;
682
1061
  const { level, label } = data;
683
1062
  // NOTE: Node order is important and is defined here
684
1063
  const node = {
685
- level,
686
- label,
1064
+ level: level !== null && level !== void 0 ? level : 0,
1065
+ label: this.handleJsonText(label),
687
1066
  };
688
1067
  // Remove Unset Optionals
689
- ObjectUtils.removeUnwantedProperties(node);
1068
+ ObjectUtils.removeUnwantedProperties(node, {
1069
+ // ignoreEmptyArrays: ['servings', 'unit'],
1070
+ // ignoreAllUndefined: true,
1071
+ });
690
1072
  return node;
691
1073
  }
692
1074
  /**
@@ -695,15 +1077,22 @@ class Builder extends BaseBuilder {
695
1077
  * @param data - data for the node
696
1078
  * @returns
697
1079
  */
698
- captionDefinition(data) {
699
- const { term, description } = data;
1080
+ buildCaptionDefinition(data) {
1081
+ var _a, _b;
1082
+ if (!data)
1083
+ return undefined;
700
1084
  // NOTE: Node order is important and is defined here
701
1085
  const node = {
702
- term,
703
- description,
1086
+ // term: this.convertJsonTextToAstText(data.term),
1087
+ // description: this.convertJsonTextToAstText(data.description),
1088
+ term: (_a = data.term) !== null && _a !== void 0 ? _a : '',
1089
+ definition: (_b = data.definition) !== null && _b !== void 0 ? _b : '',
704
1090
  };
705
1091
  // Remove Unset Optionals
706
- ObjectUtils.removeUnwantedProperties(node);
1092
+ ObjectUtils.removeUnwantedProperties(node, {
1093
+ ignoreEmptyString: ['term', 'description'],
1094
+ // ignoreAllUndefined: true,
1095
+ });
707
1096
  return node;
708
1097
  }
709
1098
  /**
@@ -712,32 +1101,39 @@ class Builder extends BaseBuilder {
712
1101
  * @param data - data for the node
713
1102
  * @returns
714
1103
  */
715
- captionDefinitionList(data) {
716
- const { columns, definitions } = data;
1104
+ buildCaptionDefinitionList(data) {
1105
+ var _a, _b;
1106
+ if (!data)
1107
+ return undefined;
717
1108
  // NOTE: Node order is important and is defined here
718
1109
  const node = {
719
- columns,
720
- definitions,
1110
+ columns: (_a = data.columns) !== null && _a !== void 0 ? _a : [],
1111
+ definitions: ((_b = data.definitions) !== null && _b !== void 0 ? _b : [])
1112
+ .map((d) => {
1113
+ return this.buildCaptionDefinition({
1114
+ term: d.term,
1115
+ definition: d.definition,
1116
+ });
1117
+ })
1118
+ .filter((d) => d != null),
721
1119
  };
722
1120
  // Remove Unset Optionals
723
- ObjectUtils.removeUnwantedProperties(node);
1121
+ ObjectUtils.removeUnwantedProperties(node, {
1122
+ ignoreAllEmptyArrays: true,
1123
+ });
724
1124
  return node;
725
1125
  }
726
- //
727
- // Private
728
- //
729
- itemLead(item, lead, pageNumber, marginNumber) {
730
- let node;
731
- // NOTE: Node order is important and is defined here
732
- if (item || lead || pageNumber || marginNumber) {
733
- node = {
734
- item,
735
- lead,
736
- pageNumber,
737
- marginNumber,
738
- };
739
- }
740
- return node;
1126
+ /**
1127
+ * Build card bit[] node
1128
+ *
1129
+ * @param data - data for the node
1130
+ * @returns
1131
+ */
1132
+ buildCardBits(textFormat, data) {
1133
+ if (!Array.isArray(data))
1134
+ return undefined;
1135
+ const nodes = data.map((d) => this.buildCardBit(textFormat, d)).filter((d) => d != null);
1136
+ return nodes.length > 0 ? nodes : undefined;
741
1137
  }
742
1138
  /**
743
1139
  * Build card bit node
@@ -745,116 +1141,101 @@ class Builder extends BaseBuilder {
745
1141
  * @param data - data for the node
746
1142
  * @returns
747
1143
  */
748
- cardBit(data) {
749
- const { item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, extraProperties, body, } = data;
1144
+ buildCardBit(textFormat, data) {
1145
+ var _a;
1146
+ if (!data)
1147
+ return undefined;
750
1148
  // NOTE: Node order is important and is defined here
751
- const node = Object.assign(Object.assign({ itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
752
- instruction }, this.toExample(isDefaultExample, example)), { body,
1149
+ const node = Object.assign(Object.assign({ item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example)), { __isDefaultExample: (_a = data.__isDefaultExample) !== null && _a !== void 0 ? _a : false, body: this.buildBody(textFormat, data.body),
753
1150
  // Must always be last in the AST so key clashes are avoided correctly with other properties
754
- extraProperties: this.parseExtraProperties(extraProperties) });
1151
+ extraProperties: this.parseExtraProperties(data.extraProperties) });
755
1152
  // Remove Unset Optionals
756
1153
  ObjectUtils.removeUnwantedProperties(node, {
757
1154
  ignoreAllFalse: true,
758
- ignoreEmptyString: ['example'],
1155
+ // ignoreEmptyArrays: ['example'],
1156
+ ignoreUndefined: ['example'],
759
1157
  });
760
1158
  // Validate and correct invalid bits as much as possible
761
1159
  return NodeValidator.validateCardBit(node);
762
1160
  }
763
- cardNode(data) {
764
- let node;
765
- const { questions, elements, flashcards, definitions, statement, statements, choices, responses, quizzes, heading, pairs, matrix, table, botResponses, ingredients, captionDefinitionList, cardBits, } = data;
766
- if (questions ||
767
- elements ||
768
- flashcards ||
769
- definitions ||
770
- statement ||
771
- statements ||
772
- choices ||
773
- responses ||
774
- quizzes ||
775
- heading ||
776
- pairs ||
777
- matrix ||
778
- table ||
779
- botResponses ||
780
- ingredients ||
781
- captionDefinitionList ||
782
- cardBits) {
783
- node = {
784
- questions,
785
- elements,
786
- flashcards,
787
- definitions,
788
- statement,
789
- statements,
790
- choices,
791
- responses,
792
- quizzes,
793
- heading,
794
- pairs,
795
- matrix,
796
- table,
797
- botResponses,
798
- ingredients,
799
- captionDefinitionList,
800
- cardBits,
801
- };
802
- // Remove Unset Optionals
803
- ObjectUtils.removeUnwantedProperties(node);
804
- }
805
- return node;
1161
+ //
1162
+ // Private
1163
+ //
1164
+ buildCardNode(bitType, textFormat, data) {
1165
+ const node = {
1166
+ questions: this.buildQuestions(data.questions),
1167
+ elements: data.elements,
1168
+ flashcards: this.buildFlashcards(data.flashcards),
1169
+ definitions: this.buildDefinitionList(data.definitions),
1170
+ statement: this.buildStatement(data.statement),
1171
+ statements: this.buildStatements(data.statements),
1172
+ choices: this.buildChoices(data.choices),
1173
+ responses: this.buildResponses(data.responses),
1174
+ quizzes: this.buildQuizzes(data.quizzes),
1175
+ heading: this.buildHeading(data.heading),
1176
+ pairs: this.buildPairs(bitType, data.pairs),
1177
+ matrix: this.buildMatricies(data.matrix),
1178
+ table: this.buildTable(data.table),
1179
+ botResponses: this.buildBotResponses(data.botResponses),
1180
+ ingredients: this.buildIngredients(data.ingredients),
1181
+ captionDefinitionList: this.buildCaptionDefinitionList(data.captionDefinitionList),
1182
+ cardBits: this.buildCardBits(textFormat, data.cardBits),
1183
+ };
1184
+ // Remove Unset Optionals
1185
+ ObjectUtils.removeUnwantedProperties(node);
1186
+ return Object.keys(node).length > 0 ? node : undefined;
806
1187
  }
807
1188
  /**
808
1189
  * Set examples down the tree
809
1190
  *
810
1191
  * @param body
811
1192
  * @param cardNode
812
- * @param isDefaultExample
1193
+ * @param __isDefaultExample
813
1194
  * @param example
814
1195
  * @returns true if any of the answers has an example, otherwise undefined
815
1196
  */
816
- pushExampleDownTree(body, cardNode, isDefaultExample, example) {
817
- if (isDefaultExample || example) {
1197
+ pushExampleDownTree(body, cardNode, __isDefaultExample, example) {
1198
+ if (__isDefaultExample || example != null) {
818
1199
  if (cardNode) {
819
- this.pushExampleDownTreeString(isDefaultExample, example, cardNode.pairs);
820
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, cardNode.flashcards);
821
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, cardNode.definitions);
822
- this.pushExampleDownTreeBoolean(isDefaultExample, example, true, cardNode.choices);
823
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, cardNode.responses, cardNode.statements, cardNode.statement);
1200
+ this.pushExampleDownTreeString(__isDefaultExample, example, cardNode.pairs);
1201
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, cardNode.flashcards);
1202
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, cardNode.definitions);
1203
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, true, cardNode.choices);
1204
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, cardNode.responses, cardNode.statements, cardNode.statement);
824
1205
  if (cardNode.quizzes) {
825
1206
  for (const quiz of cardNode.quizzes) {
826
- this.pushExampleDownTreeBoolean(isDefaultExample, example, true, quiz.choices);
827
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, quiz.responses);
1207
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, true, quiz.choices);
1208
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, quiz.responses);
828
1209
  }
829
1210
  }
830
1211
  if (cardNode.matrix) {
831
1212
  for (const m of cardNode.matrix) {
832
- this.pushExampleDownTreeString(isDefaultExample, example, m.cells);
1213
+ this.pushExampleDownTreeString(__isDefaultExample, example, m.cells);
833
1214
  }
834
1215
  }
835
1216
  }
836
1217
  if (body) {
837
- this.pushExampleDownTreeBodyBits(isDefaultExample, example, body);
1218
+ this.pushExampleDownTreeBodyBits(__isDefaultExample, example, body);
838
1219
  }
839
1220
  }
840
1221
  }
841
1222
  /**
842
1223
  * Set examples for boolean nodes
843
1224
  *
844
- * @param isDefaultExample
1225
+ * @param __isDefaultExample
845
1226
  * @param example
846
1227
  * @param onlyCorrect
847
1228
  * @param nodes
848
1229
  * @returns true if any of the answers has an example, otherwise undefined
849
1230
  */
850
- pushExampleDownTreeBoolean(isDefaultExample, example, onlyCorrect, ...nodes) {
851
- if (!isDefaultExample && !example)
1231
+ pushExampleDownTreeBoolean(__isDefaultExample, example, onlyCorrect, ...nodes) {
1232
+ if (!__isDefaultExample && example == null)
852
1233
  return;
853
1234
  if (Array.isArray(nodes)) {
854
1235
  for (const ds of nodes) {
855
1236
  if (ds) {
856
1237
  const exampleNodes = Array.isArray(ds) ? ds : [ds];
857
- BitUtils.fillBooleanExample(exampleNodes, isDefaultExample, example, onlyCorrect);
1238
+ BitUtils.fillBooleanExample(exampleNodes, __isDefaultExample, example, onlyCorrect);
858
1239
  }
859
1240
  }
860
1241
  }
@@ -862,49 +1243,48 @@ class Builder extends BaseBuilder {
862
1243
  /**
863
1244
  * Set examples for string nodes
864
1245
  *
865
- * @param isDefaultExample
1246
+ * @param __isDefaultExample
866
1247
  * @param example
867
1248
  * @param nodes
868
1249
  * @returns true if any of the answers has an example, otherwise undefined
869
1250
  */
870
- pushExampleDownTreeString(isDefaultExample, example, ...nodes) {
871
- if (!isDefaultExample && !example)
1251
+ pushExampleDownTreeString(__isDefaultExample, example, ...nodes) {
1252
+ if (!__isDefaultExample && !example)
872
1253
  return;
873
1254
  if (Array.isArray(nodes)) {
874
1255
  for (const ds of nodes) {
875
1256
  if (ds) {
876
1257
  const exampleNodes = Array.isArray(ds) ? ds : [ds];
877
- BitUtils.fillStringExample(exampleNodes, isDefaultExample, example, false);
1258
+ BitUtils.fillStringExample(exampleNodes, __isDefaultExample, example, false);
878
1259
  }
879
1260
  }
880
1261
  }
881
1262
  }
882
- pushExampleDownTreeBodyBits(isDefaultExample, example, body) {
883
- if (!isDefaultExample && !example)
884
- return;
885
- if (!body || !body.bodyParts || body.bodyParts.length === 0)
1263
+ pushExampleDownTreeBodyBits(__isDefaultExample, example, body) {
1264
+ if (!__isDefaultExample && !example)
886
1265
  return;
887
- for (const part of body.bodyParts) {
1266
+ const bodyBitsJson = this.textParser.extractBodyBits(body === null || body === void 0 ? void 0 : body.body);
1267
+ for (const part of bodyBitsJson) {
888
1268
  if (part) {
889
1269
  switch (part.type) {
890
1270
  case BodyBitType.gap: {
891
1271
  const gap = part;
892
- BitUtils.fillStringExample([gap.data], isDefaultExample, example, false);
1272
+ BitUtils.fillStringExample([gap], __isDefaultExample, example, false);
893
1273
  break;
894
1274
  }
895
1275
  case BodyBitType.mark: {
896
1276
  const mark = part;
897
- BitUtils.fillBooleanExample([mark.data], isDefaultExample, example, false);
1277
+ BitUtils.fillBooleanExample([mark], __isDefaultExample, example, false);
898
1278
  break;
899
1279
  }
900
1280
  case BodyBitType.select: {
901
1281
  const select = part;
902
- BitUtils.fillBooleanExample(select.data.options, isDefaultExample, example, true);
1282
+ BitUtils.fillBooleanExample(select.options, __isDefaultExample, example, true);
903
1283
  break;
904
1284
  }
905
1285
  case BodyBitType.highlight: {
906
1286
  const highlight = part;
907
- BitUtils.fillBooleanExample(highlight.data.texts, isDefaultExample, example, true);
1287
+ BitUtils.fillBooleanExample(highlight.texts, __isDefaultExample, example, true);
908
1288
  break;
909
1289
  }
910
1290
  }
@@ -916,7 +1296,7 @@ class Builder extends BaseBuilder {
916
1296
  *
917
1297
  * This function is not type safe and should be used with care
918
1298
  *
919
- * @param body set if the value should be passed down the body to the body bits
1299
+ * @param body/body[] set if the value should be passed down the body to the body bits / card body bits
920
1300
  * @param bodyBitTypes body bit types to push the value down to
921
1301
  * @param cardNode set if the value should be passed down the card node
922
1302
  * @param path path for the value
@@ -938,14 +1318,22 @@ class Builder extends BaseBuilder {
938
1318
  }
939
1319
  }
940
1320
  // Add value to body bit types if required
941
- if (bodyBitTypes && body && body.bodyParts && body.bodyParts.length > 0) {
942
- for (const part of body.bodyParts) {
943
- if (part) {
944
- if (bodyBitTypes.indexOf(part.type) !== -1) {
945
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
946
- const data = part.data;
947
- if (data[path] == null) {
948
- data[path] = value;
1321
+ if (body) {
1322
+ const bodyArray = (Array.isArray(body) ? body : [body]);
1323
+ for (const b of bodyArray) {
1324
+ if (b && b.body && bodyBitTypes) {
1325
+ const bodyBitsJson = this.textParser.extractBodyBits(b.body);
1326
+ if (bodyBitTypes && bodyBitsJson && bodyBitsJson.length > 0) {
1327
+ for (const part of bodyBitsJson) {
1328
+ if (part) {
1329
+ if (bodyBitTypes.indexOf(part.type) !== -1) {
1330
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1331
+ const data = part;
1332
+ if (data[path] == null) {
1333
+ data[path] = value;
1334
+ }
1335
+ }
1336
+ }
949
1337
  }
950
1338
  }
951
1339
  }
@@ -973,12 +1361,12 @@ class Builder extends BaseBuilder {
973
1361
  * @param bit
974
1362
  */
975
1363
  setIsExampleFlags(bit) {
1364
+ // bit.isExample = false;
976
1365
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
977
- bit.isExample = false;
978
1366
  const checkIsExample = (example) => {
979
1367
  if (!example)
980
1368
  return false;
981
- if (example.isDefaultExample || example.example != undefined) {
1369
+ if ( /*example.__isDefaultExample ||*/example.isExample || example.example != undefined) {
982
1370
  example.isExample = true;
983
1371
  bit.isExample = true;
984
1372
  }
@@ -994,32 +1382,31 @@ class Builder extends BaseBuilder {
994
1382
  };
995
1383
  const { body, cardNode } = bit;
996
1384
  // Body bit level
997
- if (body && body.bodyParts) {
998
- for (const bodyPart of body.bodyParts) {
999
- switch (bodyPart.type) {
1000
- case BodyBitType.gap:
1001
- case BodyBitType.mark: {
1002
- checkIsExample(bodyPart.data);
1003
- break;
1004
- }
1005
- case BodyBitType.select: {
1006
- const select = bodyPart;
1007
- let hasExample = false;
1008
- for (const option of select.data.options) {
1009
- hasExample = checkIsExample(option) ? true : hasExample;
1010
- }
1011
- select.data.isExample = hasExample;
1012
- break;
1385
+ const bodyBitsJson = this.textParser.extractBodyBits(body === null || body === void 0 ? void 0 : body.body);
1386
+ for (const bodyPart of bodyBitsJson) {
1387
+ switch (bodyPart.type) {
1388
+ case BodyBitType.gap:
1389
+ case BodyBitType.mark: {
1390
+ checkIsExample(bodyPart);
1391
+ break;
1392
+ }
1393
+ case BodyBitType.select: {
1394
+ const select = bodyPart;
1395
+ let hasExample = false;
1396
+ for (const option of select.options) {
1397
+ hasExample = checkIsExample(option) ? true : hasExample;
1013
1398
  }
1014
- case BodyBitType.highlight: {
1015
- const highlight = bodyPart;
1016
- let hasExample = false;
1017
- for (const text of highlight.data.texts) {
1018
- hasExample = checkIsExample(text) ? true : hasExample;
1019
- }
1020
- highlight.data.isExample = hasExample;
1021
- break;
1399
+ select.isExample = hasExample;
1400
+ break;
1401
+ }
1402
+ case BodyBitType.highlight: {
1403
+ const highlight = bodyPart;
1404
+ let hasExample = false;
1405
+ for (const text of highlight.texts) {
1406
+ hasExample = checkIsExample(text) ? true : hasExample;
1022
1407
  }
1408
+ highlight.isExample = hasExample;
1409
+ break;
1023
1410
  }
1024
1411
  }
1025
1412
  }