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