@gmb/bitmark-parser-generator 1.35.0 → 2.0.0

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