@khanacademy/perseus 19.1.5 → 19.1.6

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 (478) hide show
  1. package/dist/es/index.js +1 -1
  2. package/dist/index.js +1 -1
  3. package/package.json +11 -8
  4. package/.babelrc.js +0 -8
  5. package/.eslintrc.js +0 -12
  6. package/CHANGELOG.md +0 -1432
  7. package/src/__stories__/article-renderer.stories.tsx +0 -100
  8. package/src/__stories__/hints-renderer.stories.tsx +0 -55
  9. package/src/__stories__/server-item-renderer.stories.tsx +0 -44
  10. package/src/__testdata__/article-renderer.testdata.ts +0 -212
  11. package/src/__testdata__/graphie.testdata.ts +0 -51
  12. package/src/__testdata__/renderer.testdata.ts +0 -274
  13. package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
  14. package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
  15. package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
  16. package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
  17. package/src/__tests__/a11y.test.ts +0 -303
  18. package/src/__tests__/article-renderer.test.tsx +0 -130
  19. package/src/__tests__/error-boundary.test.tsx +0 -76
  20. package/src/__tests__/extract-perseus-data.test.ts +0 -1027
  21. package/src/__tests__/init.test.ts +0 -10
  22. package/src/__tests__/jipt-paragraphs.test.ts +0 -32
  23. package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
  24. package/src/__tests__/mock-widget.tsx +0 -33
  25. package/src/__tests__/perseus-markdown.test.ts +0 -764
  26. package/src/__tests__/renderability.test.ts +0 -480
  27. package/src/__tests__/renderer-api.test.tsx +0 -302
  28. package/src/__tests__/renderer.test.tsx +0 -1816
  29. package/src/__tests__/server-item-renderer.test.tsx +0 -582
  30. package/src/__tests__/test-items/image-item.ts +0 -24
  31. package/src/__tests__/test-items/input-number-1-item.ts +0 -26
  32. package/src/__tests__/test-items/input-number-2-item.ts +0 -38
  33. package/src/__tests__/test-items/table-item.ts +0 -29
  34. package/src/__tests__/tex-wrangler.test.ts +0 -82
  35. package/src/__tests__/util.test.ts +0 -40
  36. package/src/__tests__/widget-container.test.tsx +0 -126
  37. package/src/__tests__/widgets.test.ts +0 -91
  38. package/src/a11y.ts +0 -45
  39. package/src/all-widgets.ts +0 -9
  40. package/src/article-renderer.tsx +0 -237
  41. package/src/asset-context.ts +0 -30
  42. package/src/basic-widgets.ts +0 -16
  43. package/src/components/__stories__/button-group.stories.tsx +0 -55
  44. package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
  45. package/src/components/__stories__/graph.stories.tsx +0 -28
  46. package/src/components/__stories__/graphie.stories.tsx +0 -33
  47. package/src/components/__stories__/hud.stories.tsx +0 -35
  48. package/src/components/__stories__/icon.stories.tsx +0 -63
  49. package/src/components/__stories__/image-loader.stories.tsx +0 -63
  50. package/src/components/__stories__/info-tip.stories.tsx +0 -31
  51. package/src/components/__stories__/inline-icon.stories.tsx +0 -40
  52. package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
  53. package/src/components/__stories__/lint.stories.tsx +0 -86
  54. package/src/components/__stories__/math-input.stories.tsx +0 -43
  55. package/src/components/__stories__/math-output.stories.tsx +0 -23
  56. package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
  57. package/src/components/__stories__/number-input.stories.tsx +0 -41
  58. package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
  59. package/src/components/__stories__/range-input.stories.tsx +0 -29
  60. package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
  61. package/src/components/__stories__/sortable.stories.tsx +0 -77
  62. package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
  63. package/src/components/__stories__/svg-image.stories.tsx +0 -74
  64. package/src/components/__stories__/tex.stories.tsx +0 -23
  65. package/src/components/__stories__/text-input.stories.tsx +0 -33
  66. package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
  67. package/src/components/__stories__/tooltip.stories.tsx +0 -52
  68. package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
  69. package/src/components/__stories__/zoomable.stories.tsx +0 -49
  70. package/src/components/__testdata__/sorter.testdata.ts +0 -19
  71. package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
  72. package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
  73. package/src/components/__tests__/math-input.test.tsx +0 -147
  74. package/src/components/__tests__/number-input.test.tsx +0 -128
  75. package/src/components/__tests__/sortable.test.tsx +0 -269
  76. package/src/components/__tests__/sorter.test.tsx +0 -114
  77. package/src/components/__tests__/zoomable.test.tsx +0 -399
  78. package/src/components/button-group.tsx +0 -130
  79. package/src/components/constants.ts +0 -14
  80. package/src/components/fixed-to-responsive.tsx +0 -169
  81. package/src/components/graph.tsx +0 -444
  82. package/src/components/graphie-classes.ts +0 -153
  83. package/src/components/graphie-movables.ts +0 -338
  84. package/src/components/graphie.tsx +0 -400
  85. package/src/components/highlighting/highlightable-content.tsx +0 -240
  86. package/src/components/highlighting/highlights.ts +0 -207
  87. package/src/components/highlighting/ranges.ts +0 -304
  88. package/src/components/highlighting/types.ts +0 -73
  89. package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
  90. package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
  91. package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
  92. package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
  93. package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
  94. package/src/components/highlighting/ui/types.ts +0 -21
  95. package/src/components/highlighting/ui/util.ts +0 -165
  96. package/src/components/highlighting/word-indexer.tsx +0 -152
  97. package/src/components/hud.tsx +0 -167
  98. package/src/components/icon.tsx +0 -141
  99. package/src/components/image-loader.tsx +0 -177
  100. package/src/components/info-tip/info-tip.tsx +0 -144
  101. package/src/components/info-tip.tsx +0 -39
  102. package/src/components/inline-icon.tsx +0 -60
  103. package/src/components/input-with-examples.tsx +0 -249
  104. package/src/components/lint.tsx +0 -459
  105. package/src/components/math-input.tsx +0 -474
  106. package/src/components/math-output.tsx +0 -134
  107. package/src/components/multi-button-group.tsx +0 -135
  108. package/src/components/number-input.tsx +0 -249
  109. package/src/components/prop-check-box.tsx +0 -79
  110. package/src/components/range-input.tsx +0 -60
  111. package/src/components/simple-keypad-input.tsx +0 -88
  112. package/src/components/sortable.tsx +0 -958
  113. package/src/components/stub-tag-editor.tsx +0 -53
  114. package/src/components/svg-image.tsx +0 -779
  115. package/src/components/tex.tsx +0 -67
  116. package/src/components/text-input.tsx +0 -129
  117. package/src/components/text-list-editor.tsx +0 -166
  118. package/src/components/tooltip.tsx +0 -410
  119. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
  120. package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
  121. package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
  122. package/src/components/visibility-observer/visibility-observer.tsx +0 -124
  123. package/src/components/zoomable-tex.tsx +0 -78
  124. package/src/components/zoomable.tsx +0 -304
  125. package/src/components.ts +0 -15
  126. package/src/definition-context.tsx +0 -59
  127. package/src/dependencies.ts +0 -40
  128. package/src/error-boundary.tsx +0 -70
  129. package/src/extra-widgets.ts +0 -75
  130. package/src/hint-renderer.tsx +0 -151
  131. package/src/hints-renderer.tsx +0 -372
  132. package/src/icon-paths.ts +0 -119
  133. package/src/index.ts +0 -171
  134. package/src/init.ts +0 -56
  135. package/src/interaction-tracker.ts +0 -62
  136. package/src/interactive2/__tests__/movable-mock.ts +0 -55
  137. package/src/interactive2/__tests__/movable-point.test.ts +0 -144
  138. package/src/interactive2/interactive-util.test.ts +0 -93
  139. package/src/interactive2/interactive-util.ts +0 -159
  140. package/src/interactive2/movable-helper-methods.ts +0 -166
  141. package/src/interactive2/movable-line-options.ts +0 -419
  142. package/src/interactive2/movable-line.ts +0 -307
  143. package/src/interactive2/movable-point-options.ts +0 -224
  144. package/src/interactive2/movable-point.tsx +0 -585
  145. package/src/interactive2/movable-polygon-options.ts +0 -389
  146. package/src/interactive2/movable-polygon.ts +0 -360
  147. package/src/interactive2/movable.test.ts +0 -249
  148. package/src/interactive2/movable.ts +0 -437
  149. package/src/interactive2/objective_.ts +0 -79
  150. package/src/interactive2/types.ts +0 -17
  151. package/src/interactive2/wrapped-defaults.ts +0 -87
  152. package/src/interactive2/wrapped-ellipse.ts +0 -94
  153. package/src/interactive2/wrapped-line.ts +0 -116
  154. package/src/interactive2/wrapped-path.ts +0 -51
  155. package/src/interactive2.ts +0 -70
  156. package/src/item-version.ts +0 -10
  157. package/src/jipt-paragraphs.ts +0 -49
  158. package/src/jquery.mobile.vmouse.js +0 -545
  159. package/src/loading-context.ts +0 -21
  160. package/src/logging/log.test.ts +0 -39
  161. package/src/logging/log.ts +0 -97
  162. package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
  163. package/src/mixins/changeable.ts +0 -133
  164. package/src/mixins/editor-jsonify.ts +0 -13
  165. package/src/mixins/widget-jsonify-deprecated.ts +0 -23
  166. package/src/mixins/widget-prop-denylist.ts +0 -48
  167. package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
  168. package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
  169. package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
  170. package/src/multi-items/__tests__/items.test.ts +0 -240
  171. package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
  172. package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
  173. package/src/multi-items/__tests__/shapes.test.ts +0 -43
  174. package/src/multi-items/__tests__/trees.test.ts +0 -317
  175. package/src/multi-items/item-types.ts +0 -56
  176. package/src/multi-items/items.ts +0 -176
  177. package/src/multi-items/multi-renderer.tsx +0 -569
  178. package/src/multi-items/prop-type-builders.ts +0 -106
  179. package/src/multi-items/shape-types.ts +0 -52
  180. package/src/multi-items/shapes.ts +0 -52
  181. package/src/multi-items/tree-types.ts +0 -47
  182. package/src/multi-items/trees.ts +0 -360
  183. package/src/multi-items.ts +0 -75
  184. package/src/perseus-api.tsx +0 -188
  185. package/src/perseus-env.ts +0 -27
  186. package/src/perseus-error.ts +0 -17
  187. package/src/perseus-markdown.tsx +0 -405
  188. package/src/perseus-types.ts +0 -1366
  189. package/src/perseus-version.ts +0 -9
  190. package/src/question-paragraph.tsx +0 -34
  191. package/src/renderability.ts +0 -109
  192. package/src/renderer.tsx +0 -2000
  193. package/src/server-item-renderer.tsx +0 -495
  194. package/src/sigfigs.ts +0 -490
  195. package/src/styles/articles.less +0 -749
  196. package/src/styles/constants.ts +0 -94
  197. package/src/styles/global-constants.ts +0 -343
  198. package/src/styles/global-styles.ts +0 -306
  199. package/src/styles/khan-exercise.css +0 -1468
  200. package/src/styles/media-queries.ts +0 -47
  201. package/src/styles/perseus-renderer.less +0 -732
  202. package/src/styles/shared.ts +0 -130
  203. package/src/styles/util.less +0 -47
  204. package/src/styles/variables.boostrap.less +0 -277
  205. package/src/styles/variables.less +0 -56
  206. package/src/styles/variables.shared.less +0 -340
  207. package/src/styles/widgets/categorizer.less +0 -38
  208. package/src/styles/widgets/dropdown.less +0 -3
  209. package/src/styles/widgets/expression.less +0 -65
  210. package/src/styles/widgets/graded-group.less +0 -36
  211. package/src/styles/widgets/grapher.less +0 -12
  212. package/src/styles/widgets/group.less +0 -19
  213. package/src/styles/widgets/image.less +0 -54
  214. package/src/styles/widgets/interactive-graph.less +0 -64
  215. package/src/styles/widgets/label-image.less +0 -57
  216. package/src/styles/widgets/matcher.less +0 -8
  217. package/src/styles/widgets/matrix.less +0 -126
  218. package/src/styles/widgets/measurer.less +0 -20
  219. package/src/styles/widgets/orderer.less +0 -98
  220. package/src/styles/widgets/passage.less +0 -154
  221. package/src/styles/widgets/plotter.less +0 -31
  222. package/src/styles/widgets/radio.less +0 -58
  223. package/src/styles/widgets/reaction-diagram.less +0 -35
  224. package/src/styles/widgets/sequence.less +0 -5
  225. package/src/styles/widgets/sortable.less +0 -113
  226. package/src/styles/widgets/table.less +0 -57
  227. package/src/styles/widgets/unit.less +0 -15
  228. package/src/tex-wrangler.ts +0 -182
  229. package/src/translation-linter.ts +0 -126
  230. package/src/traversal.ts +0 -138
  231. package/src/types.ts +0 -513
  232. package/src/util/a11y.ts +0 -23
  233. package/src/util/answer-types.test.ts +0 -114
  234. package/src/util/answer-types.ts +0 -876
  235. package/src/util/colors.ts +0 -93
  236. package/src/util/drawing-transform.test.ts +0 -67
  237. package/src/util/drawing-transform.ts +0 -102
  238. package/src/util/extract-perseus-data.ts +0 -539
  239. package/src/util/fix-passage-refs.ts +0 -121
  240. package/src/util/geometry.test.ts +0 -75
  241. package/src/util/geometry.ts +0 -312
  242. package/src/util/graph-bounds.ts +0 -23
  243. package/src/util/graph-utils.ts +0 -15
  244. package/src/util/graphie.test.ts +0 -1277
  245. package/src/util/graphie.ts +0 -1576
  246. package/src/util/interactive.ts +0 -4174
  247. package/src/util/interval.ts +0 -4
  248. package/src/util/katex-preprocess.ts +0 -14
  249. package/src/util/math.test.ts +0 -11
  250. package/src/util/math.ts +0 -294
  251. package/src/util/mobile-native-utils.test.ts +0 -22
  252. package/src/util/mobile-native-utils.ts +0 -12
  253. package/src/util/parse-perseus-json.test.ts +0 -10
  254. package/src/util/parse-perseus-json.ts +0 -13
  255. package/src/util/react-render.tsx +0 -27
  256. package/src/util/register-all-widgets-for-testing.ts +0 -13
  257. package/src/util/scroll-utils.ts +0 -155
  258. package/src/util/sizing-utils.ts +0 -46
  259. package/src/util/tex.ts +0 -73
  260. package/src/util/url-utils.ts +0 -34
  261. package/src/util.graphie.test.ts +0 -45
  262. package/src/util.graphie.ts +0 -59
  263. package/src/util.ts +0 -966
  264. package/src/version.ts +0 -10
  265. package/src/widget-container.tsx +0 -199
  266. package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
  267. package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
  268. package/src/widgets/__stories__/definition.stories.tsx +0 -114
  269. package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
  270. package/src/widgets/__stories__/explanation.stories.tsx +0 -18
  271. package/src/widgets/__stories__/expression.stories.tsx +0 -145
  272. package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
  273. package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
  274. package/src/widgets/__stories__/grapher.stories.tsx +0 -46
  275. package/src/widgets/__stories__/group.stories.tsx +0 -14
  276. package/src/widgets/__stories__/iframe.stories.tsx +0 -14
  277. package/src/widgets/__stories__/image.stories.tsx +0 -85
  278. package/src/widgets/__stories__/input-number.stories.tsx +0 -101
  279. package/src/widgets/__stories__/interaction.stories.tsx +0 -14
  280. package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
  281. package/src/widgets/__stories__/label-image.stories.tsx +0 -130
  282. package/src/widgets/__stories__/matcher.stories.tsx +0 -14
  283. package/src/widgets/__stories__/matrix.stories.tsx +0 -14
  284. package/src/widgets/__stories__/number-line.stories.tsx +0 -14
  285. package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
  286. package/src/widgets/__stories__/orderer.stories.tsx +0 -18
  287. package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
  288. package/src/widgets/__stories__/passage.stories.tsx +0 -39
  289. package/src/widgets/__stories__/plotter.stories.tsx +0 -27
  290. package/src/widgets/__stories__/radio.stories.tsx +0 -86
  291. package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
  292. package/src/widgets/__stories__/sorter.stories.tsx +0 -14
  293. package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
  294. package/src/widgets/__stories__/unit.stories.tsx +0 -28
  295. package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
  296. package/src/widgets/__stories__/video.stories.tsx +0 -22
  297. package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
  298. package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
  299. package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
  300. package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
  301. package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
  302. package/src/widgets/__testdata__/expression.testdata.ts +0 -198
  303. package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
  304. package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
  305. package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
  306. package/src/widgets/__testdata__/group.testdata.ts +0 -153
  307. package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
  308. package/src/widgets/__testdata__/image.testdata.ts +0 -36
  309. package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
  310. package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
  311. package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
  312. package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
  313. package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
  314. package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
  315. package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
  316. package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
  317. package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
  318. package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
  319. package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
  320. package/src/widgets/__testdata__/passage.testdata.ts +0 -95
  321. package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
  322. package/src/widgets/__testdata__/radio.testdata.ts +0 -324
  323. package/src/widgets/__testdata__/randomizers.ts +0 -51
  324. package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
  325. package/src/widgets/__testdata__/video.testdata.ts +0 -61
  326. package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
  327. package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
  328. package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
  329. package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
  330. package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
  331. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
  332. package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
  333. package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
  334. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
  335. package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
  336. package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
  337. package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
  338. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
  339. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
  340. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
  341. package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
  342. package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
  343. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
  344. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
  345. package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
  346. package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
  347. package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
  348. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
  349. package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
  350. package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
  351. package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
  352. package/src/widgets/__tests__/categorizer.test.ts +0 -203
  353. package/src/widgets/__tests__/cs-program.test.ts +0 -43
  354. package/src/widgets/__tests__/definition.test.ts +0 -136
  355. package/src/widgets/__tests__/dropdown.test.ts +0 -105
  356. package/src/widgets/__tests__/explanation.test.ts +0 -198
  357. package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
  358. package/src/widgets/__tests__/expression.test.tsx +0 -484
  359. package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
  360. package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
  361. package/src/widgets/__tests__/graded-group.test.ts +0 -232
  362. package/src/widgets/__tests__/grapher.cypress.ts +0 -576
  363. package/src/widgets/__tests__/grapher.test.ts +0 -33
  364. package/src/widgets/__tests__/group.test.tsx +0 -510
  365. package/src/widgets/__tests__/iframe.test.ts +0 -45
  366. package/src/widgets/__tests__/image.test.ts +0 -62
  367. package/src/widgets/__tests__/input-number.test.ts +0 -354
  368. package/src/widgets/__tests__/interaction.test.ts +0 -31
  369. package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
  370. package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
  371. package/src/widgets/__tests__/matcher.test.tsx +0 -176
  372. package/src/widgets/__tests__/matrix.test.ts +0 -82
  373. package/src/widgets/__tests__/number-line.test.ts +0 -79
  374. package/src/widgets/__tests__/numeric-input.test.ts +0 -575
  375. package/src/widgets/__tests__/orderer.test.ts +0 -73
  376. package/src/widgets/__tests__/passage-ref.test.ts +0 -168
  377. package/src/widgets/__tests__/passage.test.tsx +0 -224
  378. package/src/widgets/__tests__/plotter.test.tsx +0 -69
  379. package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
  380. package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
  381. package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
  382. package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
  383. package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
  384. package/src/widgets/__tests__/radio.test.ts +0 -807
  385. package/src/widgets/__tests__/randomizers.test.ts +0 -53
  386. package/src/widgets/__tests__/renderQuestion.tsx +0 -101
  387. package/src/widgets/__tests__/unit.test.tsx +0 -168
  388. package/src/widgets/__tests__/video.test.ts +0 -69
  389. package/src/widgets/categorizer.tsx +0 -344
  390. package/src/widgets/cs-program.tsx +0 -227
  391. package/src/widgets/definition.tsx +0 -121
  392. package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
  393. package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
  394. package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
  395. package/src/widgets/deprecated-standin/index.tsx +0 -58
  396. package/src/widgets/dropdown.tsx +0 -142
  397. package/src/widgets/explanation.tsx +0 -317
  398. package/src/widgets/expression.tsx +0 -707
  399. package/src/widgets/graded-group-answer-bar.tsx +0 -142
  400. package/src/widgets/graded-group-set.tsx +0 -338
  401. package/src/widgets/graded-group.tsx +0 -471
  402. package/src/widgets/grapher/util.tsx +0 -799
  403. package/src/widgets/grapher.tsx +0 -660
  404. package/src/widgets/group.tsx +0 -195
  405. package/src/widgets/iframe.tsx +0 -195
  406. package/src/widgets/image.tsx +0 -312
  407. package/src/widgets/input-number.tsx +0 -412
  408. package/src/widgets/interaction/arrow-picker.tsx +0 -38
  409. package/src/widgets/interaction/color-picker.tsx +0 -69
  410. package/src/widgets/interaction/dash-picker.tsx +0 -45
  411. package/src/widgets/interaction/element-container.tsx +0 -100
  412. package/src/widgets/interaction.tsx +0 -826
  413. package/src/widgets/interactive-graph.tsx +0 -2597
  414. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
  415. package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
  416. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
  417. package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
  418. package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
  419. package/src/widgets/label-image/answer-choices.tsx +0 -88
  420. package/src/widgets/label-image/answer-pill.tsx +0 -103
  421. package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
  422. package/src/widgets/label-image/marker.tsx +0 -268
  423. package/src/widgets/label-image/strings.ts +0 -5
  424. package/src/widgets/label-image/types.ts +0 -27
  425. package/src/widgets/label-image.test.ts +0 -928
  426. package/src/widgets/label-image.tsx +0 -819
  427. package/src/widgets/lights-puzzle.tsx +0 -359
  428. package/src/widgets/matcher.tsx +0 -298
  429. package/src/widgets/matrix.tsx +0 -634
  430. package/src/widgets/measurer.tsx +0 -222
  431. package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
  432. package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
  433. package/src/widgets/molecule/molecule-drawing.ts +0 -173
  434. package/src/widgets/molecule/molecule-layout.ts +0 -362
  435. package/src/widgets/molecule/smiles-parser.ts +0 -296
  436. package/src/widgets/molecule.tsx +0 -172
  437. package/src/widgets/number-line.tsx +0 -862
  438. package/src/widgets/numeric-input.tsx +0 -576
  439. package/src/widgets/orderer.tsx +0 -786
  440. package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
  441. package/src/widgets/passage/passage-markdown.tsx +0 -475
  442. package/src/widgets/passage-ref-target.tsx +0 -76
  443. package/src/widgets/passage-ref.tsx +0 -213
  444. package/src/widgets/passage.tsx +0 -582
  445. package/src/widgets/plotter.tsx +0 -1194
  446. package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
  447. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
  448. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
  449. package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
  450. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
  451. package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
  452. package/src/widgets/radio/base-radio.tsx +0 -511
  453. package/src/widgets/radio/choice-a11y-text.ts +0 -61
  454. package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
  455. package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
  456. package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
  457. package/src/widgets/radio/choice-none-above.tsx +0 -56
  458. package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
  459. package/src/widgets/radio/choice.tsx +0 -359
  460. package/src/widgets/radio/focus-ring.tsx +0 -57
  461. package/src/widgets/radio/option-status.tsx +0 -98
  462. package/src/widgets/radio/util.test.ts +0 -18
  463. package/src/widgets/radio/util.ts +0 -31
  464. package/src/widgets/radio/widget.tsx +0 -520
  465. package/src/widgets/radio.ts +0 -157
  466. package/src/widgets/reaction-diagram.tsx +0 -144
  467. package/src/widgets/sequence.tsx +0 -142
  468. package/src/widgets/simulator.tsx +0 -829
  469. package/src/widgets/sorter.tsx +0 -155
  470. package/src/widgets/table.tsx +0 -393
  471. package/src/widgets/unit.tsx +0 -374
  472. package/src/widgets/video-transcript-link.test.tsx +0 -213
  473. package/src/widgets/video-transcript-link.tsx +0 -84
  474. package/src/widgets/video.tsx +0 -135
  475. package/src/widgets.ts +0 -489
  476. package/src/zoom.ts +0 -555
  477. package/tsconfig-build.json +0 -26
  478. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,876 +0,0 @@
1
- /* eslint-disable no-useless-escape */
2
- import * as KAS from "@khanacademy/kas";
3
- import * as i18n from "@khanacademy/wonder-blocks-i18n";
4
- import $ from "jquery";
5
- import _ from "underscore";
6
-
7
- import {Errors} from "../logging/log";
8
- import {PerseusError} from "../perseus-error";
9
-
10
- import KhanMath from "./math";
11
-
12
- const MAXERROR_EPSILON = Math.pow(2, -42);
13
-
14
- type Guess = any;
15
- type Predicate = any;
16
-
17
- // TOOD(kevinb): Figure out how this relates to KEScore in
18
- // perseus-all-package/types.js and see if there's a way to
19
- // unify these types.
20
- type Score = {
21
- empty: boolean;
22
- correct: boolean;
23
- message: string | null | undefined;
24
- suppressAlmostThere?: boolean | null | undefined;
25
- guess: Guess;
26
- // It would be nice if we could ungraded required
27
- ungraded?: boolean;
28
- };
29
-
30
- export const errors = {
31
- APPROXIMATED_PI_ERROR: i18n._(
32
- "Your answer is close, but you may " +
33
- "have approximated pi. Enter your " +
34
- "answer as a multiple of pi, like " +
35
- "<code>12\\ \\text{pi}</code> or " +
36
- "<code>2/3\\ \\text{pi}</code>",
37
- ) as string,
38
- EXTRA_SYMBOLS_ERROR: i18n._(
39
- "We could not understand your " +
40
- "answer. Please check your answer for extra " +
41
- "text or symbols.",
42
- ) as string,
43
- NEEDS_TO_BE_SIMPLFIED_ERROR: i18n._(
44
- "Your answer is almost correct, " + "but it needs to be simplified.",
45
- ) as string,
46
- MISSING_PERCENT_ERROR: i18n._(
47
- "Your answer is almost correct, " +
48
- "but it is missing a " +
49
- "<code>\\%</code> at the end.",
50
- ) as string,
51
- MULTIPLICATION_SIGN_ERROR: i18n._(
52
- "I'm a computer. I only understand " +
53
- "multiplication if you use an asterisk " +
54
- "(*) as the multiplication sign.",
55
- ) as string,
56
- WRONG_CASE_ERROR: i18n._(
57
- "Your answer includes use of a variable with the wrong case.",
58
- ) as string,
59
- WRONG_LETTER_ERROR: i18n._(
60
- "Your answer includes a wrong variable letter.",
61
- ) as string,
62
- } as const;
63
-
64
- /*
65
- * Answer types
66
- *
67
- * Utility for creating answerable questions displayed in exercises
68
- *
69
- * Different answer types produce different kinds of input displays, and do
70
- * different kinds of checking on the solutions.
71
- *
72
- * Each of the objects contain two functions, setup and createValidator.
73
- *
74
- * The setup function takes a solutionarea and solution, and performs setup
75
- * within the solutionarea, and then returns an object which contains:
76
- *
77
- * answer: a function which, when called, will retrieve the current answer from
78
- * the solutionarea, which can then be validated using the validator
79
- * function
80
- * validator: a function returned from the createValidator function (defined
81
- * below)
82
- * solution: the correct answer to the problem
83
- * showGuess: a function which, when given a guess, shows the guess within the
84
- * provided solutionarea
85
- * showGuessCustom: a function which displays parts of a guess that are not
86
- * within the solutionarea; currently only used for custom
87
- * answers
88
- *
89
- * The createValidator function only takes a solution, and it returns a
90
- * function which can be used to validate an answer.
91
- *
92
- * The resulting validator function returns:
93
- * - true: if the answer is fully correct
94
- * - false: if the answer is incorrect
95
- * - "" (the empty string): if no answer has been provided (e.g. the answer box
96
- * is left unfilled)
97
- * - a string: if there is some slight error
98
- *
99
- * In most cases, setup and createValidator don't really need the solution DOM
100
- * element so we have setupFunctional and createValidatorFunctional for them
101
- * which take only $solution.text() and $solution.data(). This makes it easier
102
- * to reuse specific answer types.
103
- *
104
- * TODO(alpert): Think of a less-absurd name for createValidatorFunctional.
105
- *
106
- */
107
-
108
- const KhanAnswerTypes = {
109
- /*
110
- * predicate answer type
111
- *
112
- * performs simple predicate-based checking of a numeric solution, with
113
- * different kinds of number formats
114
- *
115
- * Uses the data-forms option on the solution to choose which number formats
116
- * are acceptable. Available data-forms:
117
- *
118
- * - integer: 3
119
- * - proper: 3/5
120
- * - improper: 5/3
121
- * - pi: 3 pi
122
- * - log: log(5)
123
- * - percent: 15%
124
- * - mixed: 1 1/3
125
- * - decimal: 1.7
126
- *
127
- * The solution should be a predicate of the form:
128
- *
129
- * function(guess, maxError) {
130
- * return abs(guess - 3) < maxError;
131
- * }
132
- *
133
- */
134
- predicate: {
135
- defaultForms: "integer, proper, improper, mixed, decimal",
136
- createValidatorFunctional: function (
137
- predicate: Predicate,
138
- options: any,
139
- ): (arg1: Guess) => Score {
140
- // Extract the options from the given solution object
141
- options = _.extend(
142
- {
143
- simplify: "required",
144
- ratio: false,
145
- forms: KhanAnswerTypes.predicate.defaultForms,
146
- },
147
- options,
148
- );
149
- let acceptableForms;
150
- // this is maintaining backwards compatibility
151
- // TODO(merlob) fix all places that depend on this, then delete
152
- if (!_.isArray(options.forms)) {
153
- acceptableForms = options.forms.split(/\s*,\s*/);
154
- } else {
155
- acceptableForms = options.forms;
156
- }
157
-
158
- // TODO(jack): remove options.inexact in favor of options.maxError
159
- if (options.inexact === undefined) {
160
- // If we aren't allowing inexact, ensure that we don't have a
161
- // large maxError as well.
162
- options.maxError = 0;
163
- }
164
- // Allow a small tolerance on maxError, to avoid numerical
165
- // representation issues (2.3 should be correct for a solution of
166
- // 2.45 with maxError=0.15).
167
- options.maxError = +options.maxError + MAXERROR_EPSILON;
168
-
169
- // If percent is an acceptable form, make sure it's the last one
170
- // in the list so we don't prematurely complain about not having
171
- // a percent sign when the user entered the correct answer in a
172
- // different form (such as a decimal or fraction)
173
- if (_.contains(acceptableForms, "percent")) {
174
- acceptableForms = _.without(acceptableForms, "percent");
175
- acceptableForms.push("percent");
176
- }
177
-
178
- // Take text looking like a fraction, and turn it into a number
179
- const fractionTransformer = function (text) {
180
- text = text
181
- // Replace unicode minus sign with hyphen
182
- .replace(/\u2212/, "-")
183
- // Remove space after +, -
184
- .replace(/([+-])\s+/g, "$1")
185
- // Remove leading/trailing whitespace
186
- .replace(/(^\s*)|(\s*$)/gi, "");
187
-
188
- // Extract numerator and denominator
189
- const match = text.match(/^([+-]?\d+)\s*\/\s*([+-]?\d+)$/);
190
- // Fractions are represented as "-\frac{numerator}{denominator}"
191
- // in Mobile device input instead of "numerator/denominator" as
192
- // in web-browser.
193
- const mobileDeviceMatch = text.match(
194
- /^([+-]?)\\frac\{([+-]?\d+)\}\{([+-]?\d+)\}$/,
195
- );
196
- const parsedInt = parseInt(text, 10);
197
- if (match || mobileDeviceMatch) {
198
- let num;
199
- let denom;
200
- let simplified = true;
201
- if (match) {
202
- num = parseFloat(match[1]);
203
- denom = parseFloat(match[2]);
204
- } else {
205
- num = parseFloat(mobileDeviceMatch[2]);
206
- if (mobileDeviceMatch[1] === "-") {
207
- if (num < 0) {
208
- simplified = false;
209
- }
210
- num = -num;
211
- }
212
- denom = parseFloat(mobileDeviceMatch[3]);
213
- }
214
-
215
- simplified =
216
- simplified &&
217
- denom > 0 &&
218
- (options.ratio || denom !== 1) &&
219
- KhanMath.getGCD(num, denom) === 1;
220
- return [
221
- {
222
- value: num / denom,
223
- exact: simplified,
224
- },
225
- ];
226
- }
227
- if (!isNaN(parsedInt) && "" + parsedInt === text) {
228
- return [
229
- {
230
- value: parsedInt,
231
- exact: true,
232
- },
233
- ];
234
- }
235
-
236
- return [];
237
- };
238
-
239
- /*
240
- * Different forms of numbers
241
- *
242
- * Each function returns a list of objects of the form:
243
- *
244
- * {
245
- * value: numerical value,
246
- * exact: true/false
247
- * }
248
- */
249
- const forms = {
250
- // integer, which is encompassed by decimal
251
- integer: function (text) {
252
- // Compare the decimal form to the decimal form rounded to
253
- // an integer. Only accept if the user actually entered an
254
- // integer.
255
- const decimal = forms.decimal(text);
256
- const rounded = forms.decimal(text, 1);
257
- if (
258
- (decimal[0].value != null &&
259
- decimal[0].value === rounded[0].value) ||
260
- (decimal[1].value != null &&
261
- decimal[1].value === rounded[1].value)
262
- ) {
263
- return decimal;
264
- }
265
- return [];
266
- },
267
-
268
- // A proper fraction
269
- proper: function (text) {
270
- return $.map(fractionTransformer(text), function (o) {
271
- // All fractions that are less than 1
272
- if (Math.abs(o.value) < 1) {
273
- return [o];
274
- }
275
- return [];
276
- });
277
- },
278
-
279
- // an improper fraction
280
- improper: function (text) {
281
- return $.map(fractionTransformer(text), function (o) {
282
- // All fractions that are greater than 1
283
- if (Math.abs(o.value) >= 1) {
284
- return [o];
285
- }
286
- return [];
287
- });
288
- },
289
-
290
- // pi-like numbers
291
- pi: function (text) {
292
- let match;
293
- let possibilities: any[] = [];
294
-
295
- // Replace unicode minus sign with hyphen
296
- text = text.replace(/\u2212/, "-");
297
-
298
- // - pi
299
- // (Note: we also support \pi (for TeX), p, tau (and \tau,
300
- // and t), pau.)
301
- if (
302
- (match = text.match(
303
- /^([+-]?)\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
304
- ))
305
- ) {
306
- possibilities = [
307
- {
308
- value: parseFloat(match[1] + "1"),
309
- exact: true,
310
- },
311
- ];
312
-
313
- // 5 / 6 pi
314
- } else if (
315
- (match = text.match(
316
- /^([+-]?\s*\d+\s*(?:\/\s*[+-]?\s*\d+)?)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
317
- ))
318
- ) {
319
- possibilities = fractionTransformer(match[1]);
320
-
321
- // 4 5 / 6 pi
322
- } else if (
323
- (match = text.match(
324
- /^([+-]?)\s*(\d+)\s*([+-]?\d+)\s*\/\s*([+-]?\d+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
325
- ))
326
- ) {
327
- const sign = parseFloat(match[1] + "1");
328
- const integ = parseFloat(match[2]);
329
- const num = parseFloat(match[3]);
330
- const denom = parseFloat(match[4]);
331
- const simplified =
332
- num < denom && KhanMath.getGCD(num, denom) === 1;
333
-
334
- possibilities = [
335
- {
336
- value: sign * (integ + num / denom),
337
- exact: simplified,
338
- },
339
- ];
340
-
341
- // 5 pi / 6
342
- } else if (
343
- (match = text.match(
344
- /^([+-]?\s*\d+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)\s*(?:\/\s*([+-]?\s*\d+))?$/i,
345
- ))
346
- ) {
347
- possibilities = fractionTransformer(
348
- match[1] + "/" + match[3],
349
- );
350
-
351
- // - pi / 4
352
- } else if (
353
- (match = text.match(
354
- /^([+-]?)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)\s*(?:\/\s*([+-]?\d+))?$/i,
355
- ))
356
- ) {
357
- possibilities = fractionTransformer(
358
- match[1] + "1/" + match[3],
359
- );
360
-
361
- // 0
362
- } else if (text === "0") {
363
- possibilities = [{value: 0, exact: true}];
364
-
365
- // 0.5 pi (fallback)
366
- } else if (
367
- (match = text.match(
368
- /^(.+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
369
- ))
370
- ) {
371
- possibilities = forms.decimal(match[1]);
372
- } else {
373
- possibilities = _.reduce(
374
- KhanAnswerTypes.predicate.defaultForms.split(
375
- /\s*,\s*/,
376
- ),
377
- function (memo, form) {
378
- return memo.concat(forms[form](text));
379
- },
380
- [],
381
- );
382
-
383
- // If the answer is a floating point number that's
384
- // near a multiple of pi, mark is as being possibly
385
- // an approximation of pi. We actually check if
386
- // it's a plausible approximation of pi/12, since
387
- // sometimes the correct answer is like pi/3 or pi/4.
388
- // We also say it's a pi-approximation if it involves
389
- // x/7 (since 22/7 is an approximation of pi.)
390
- // Never mark an integer as being an approximation
391
- // of pi.
392
- let approximatesPi = false;
393
- const number = parseFloat(text);
394
- if (!isNaN(number) && number !== parseInt(text)) {
395
- const piMult = Math.PI / 12;
396
- const roundedNumber =
397
- piMult * Math.round(number / piMult);
398
- if (Math.abs(number - roundedNumber) < 0.01) {
399
- approximatesPi = true;
400
- }
401
- } else if (text.match(/\/\s*7/)) {
402
- approximatesPi = true;
403
- }
404
- if (approximatesPi) {
405
- _.each(possibilities, function (possibility) {
406
- possibility.piApprox = true;
407
- });
408
- }
409
- return possibilities;
410
- }
411
-
412
- let multiplier = Math.PI;
413
- if (text.match(/\\?tau|t|\u03c4/)) {
414
- multiplier = Math.PI * 2;
415
- }
416
-
417
- // We're taking an early stand along side xkcd in the
418
- // inevitable ti vs. pau debate... http://xkcd.com/1292
419
- if (text.match(/pau/)) {
420
- multiplier = Math.PI * 1.5;
421
- }
422
-
423
- $.each(possibilities, function (ix, possibility) {
424
- possibility.value *= multiplier;
425
- });
426
- return possibilities;
427
- },
428
-
429
- // Converts '' to 1 and '-' to -1 so you can write "[___] x"
430
- // and accept sane things
431
- coefficient: function (text) {
432
- let possibilities:
433
- | Array<never>
434
- | Array<{
435
- exact: boolean;
436
- value: number;
437
- }> = [];
438
-
439
- // Replace unicode minus sign with hyphen
440
- text = text.replace(/\u2212/, "-");
441
-
442
- if (text === "") {
443
- possibilities = [{value: 1, exact: true}];
444
- } else if (text === "-") {
445
- possibilities = [{value: -1, exact: true}];
446
- }
447
- return possibilities;
448
- },
449
-
450
- // simple log(c) form
451
- log: function (text) {
452
- let match;
453
- let possibilities = [];
454
-
455
- // Replace unicode minus sign with hyphen
456
- text = text.replace(/\u2212/, "-");
457
- text = text.replace(/[ \(\)]/g, "");
458
-
459
- if ((match = text.match(/^log\s*(\S+)\s*$/i))) {
460
- // @ts-expect-error - TS2322 - Type '{ value: number | undefined; exact: boolean; }[]' is not assignable to type 'never[]'.
461
- possibilities = forms.decimal(match[1]);
462
- } else if (text === "0") {
463
- // @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'never'. | TS2322 - Type 'boolean' is not assignable to type 'never'.
464
- possibilities = [{value: 0, exact: true}];
465
- }
466
- return possibilities;
467
- },
468
-
469
- // Numbers with percent signs
470
- percent: function (text) {
471
- text = $.trim(text);
472
- // store whether or not there is a percent sign
473
- let hasPercentSign = false;
474
-
475
- if (text.indexOf("%") === text.length - 1) {
476
- text = $.trim(text.substring(0, text.length - 1));
477
- hasPercentSign = true;
478
- }
479
-
480
- const transformed = forms.decimal(text);
481
- $.each(transformed, function (ix, t) {
482
- t.exact = hasPercentSign;
483
- // @ts-expect-error - TS2532 - Object is possibly 'undefined'.
484
- t.value = t.value / 100;
485
- });
486
- return transformed;
487
- },
488
-
489
- // Mixed numbers, like 1 3/4
490
- mixed: function (text) {
491
- const match = text
492
- // Replace unicode minus sign with hyphen
493
- .replace(/\u2212/, "-")
494
- // Remove space after +, -
495
- .replace(/([+-])\s+/g, "$1")
496
- // Extract integer, numerator and denominator
497
- .match(/^([+-]?)(\d+)\s+(\d+)\s*\/\s*(\d+)$/);
498
-
499
- if (match) {
500
- const sign = parseFloat(match[1] + "1");
501
- const integ = parseFloat(match[2]);
502
- const num = parseFloat(match[3]);
503
- const denom = parseFloat(match[4]);
504
- const simplified =
505
- num < denom && KhanMath.getGCD(num, denom) === 1;
506
-
507
- return [
508
- {
509
- value: sign * (integ + num / denom),
510
- exact: simplified,
511
- },
512
- ];
513
- }
514
-
515
- return [];
516
- },
517
-
518
- // Decimal numbers -- compare entered text rounded to
519
- // 'precision' Reciprical of the precision against the correct
520
- // answer. We round to 1/1e10 by default, which is healthily
521
- // less than machine epsilon but should be more than any real
522
- // decimal answer would use. (The 'integer' answer type uses
523
- // precision == 1.)
524
- decimal: function (text: string, precision = 1e10) {
525
- const normal = function (text) {
526
- text = $.trim(text);
527
-
528
- const match = text
529
- // Replace unicode minus sign with hyphen
530
- .replace(/\u2212/, "-")
531
- // Remove space after +, -
532
- .replace(/([+-])\s+/g, "$1")
533
- // Extract integer, numerator and denominator. If
534
- // commas or spaces are used, they must be in the
535
- // "correct" places
536
- .match(
537
- /^([+-]?(?:\d{1,3}(?:[, ]?\d{3})*\.?|\d{0,3}(?:[, ]?\d{3})*\.(?:\d{3}[, ]?)*\d{1,3}))$/,
538
- );
539
-
540
- // You can't start a number with `0,`, to prevent us
541
- // interpeting '0.342' as correct for '342'
542
- const badLeadingZero = text.match(/^0[0,]*,/);
543
-
544
- if (match && !badLeadingZero) {
545
- let x = parseFloat(match[1].replace(/[, ]/g, ""));
546
-
547
- if (options.inexact === undefined) {
548
- x = Math.round(x * precision) / precision;
549
- }
550
-
551
- return x;
552
- }
553
- };
554
-
555
- const commas = function (text: string) {
556
- text = text.replace(/([\.,])/g, function (_, c) {
557
- return c === "." ? "," : ".";
558
- });
559
- return normal(text);
560
- };
561
-
562
- return [
563
- {value: normal(text), exact: true},
564
- {value: commas(text), exact: true},
565
- ];
566
- },
567
- } as const;
568
-
569
- // validator function
570
- return function (guess: Guess): Score {
571
- // The fallback variable is used in place of the answer, if no
572
- // answer is provided (i.e. the field is left blank)
573
- const fallback =
574
- options.fallback != null ? "" + options.fallback : "";
575
-
576
- guess = $.trim(guess) || fallback;
577
-
578
- const score: Score = {
579
- empty: guess === "",
580
- correct: false,
581
- message: null as string | null | undefined,
582
- guess: guess,
583
- };
584
-
585
- // iterate over all the acceptable forms, and if one of the
586
- // answers is correct, return true
587
- $.each(acceptableForms, function (i, form) {
588
- const transformed = forms[form](guess);
589
- for (let j = 0, l = transformed.length; j < l; j++) {
590
- const val = transformed[j].value;
591
- const exact = transformed[j].exact;
592
- const piApprox = transformed[j].piApprox;
593
- // If a string was returned, and it exactly matches,
594
- // return true
595
- if (predicate(val, options.maxError)) {
596
- // If the exact correct number was returned,
597
- // return true
598
- if (exact || options.simplify === "optional") {
599
- score.correct = true;
600
- score.message = options.message || null;
601
- // If the answer is correct, don't say it's
602
- // empty. This happens, for example, with the
603
- // coefficient type where guess === "" but is
604
- // interpreted as "1" which is correct.
605
- score.empty = false;
606
- } else if (form === "percent") {
607
- // Otherwise, an error was returned
608
- score.empty = true;
609
- score.message = errors.MISSING_PERCENT_ERROR;
610
- } else {
611
- if (options.simplify !== "enforced") {
612
- score.empty = true;
613
- }
614
- score.message =
615
- errors.NEEDS_TO_BE_SIMPLFIED_ERROR;
616
- }
617
- // The return false below stops the looping of the
618
- // callback since predicate check succeeded.
619
- // No more forms to look to verify the user guess.
620
- return false;
621
- }
622
- if (piApprox && predicate(val, Math.abs(val * 0.001))) {
623
- score.empty = true;
624
- score.message = errors.APPROXIMATED_PI_ERROR;
625
- }
626
- }
627
- });
628
-
629
- if (score.correct === false) {
630
- let interpretedGuess = false;
631
- _.each(forms, function (form) {
632
- const anyAreNaN = _.any(form(guess), function (t) {
633
- return t.value != null && !_.isNaN(t.value);
634
- });
635
-
636
- if (anyAreNaN) {
637
- interpretedGuess = true;
638
- }
639
- });
640
- if (!interpretedGuess) {
641
- score.empty = true;
642
- score.message = errors.EXTRA_SYMBOLS_ERROR;
643
- return score;
644
- }
645
- }
646
-
647
- return score;
648
- };
649
- },
650
- },
651
-
652
- /*
653
- * number answer type
654
- *
655
- * wraps the predicate answer type to performs simple number-based checking
656
- * of a solution
657
- */
658
- number: {
659
- convertToPredicate: function (
660
- correctAnswer: string,
661
- options: any,
662
- ): Predicate {
663
- const correctFloat = parseFloat(correctAnswer);
664
-
665
- return [
666
- function (guess: Predicate, maxError: Predicate) {
667
- return Math.abs(guess - correctFloat) < maxError;
668
- },
669
- $.extend({}, options, {type: "predicate"}),
670
- ];
671
- },
672
- createValidatorFunctional: function (
673
- correctAnswer: string,
674
- options: any,
675
- ): (arg1: Guess) => Score {
676
- return KhanAnswerTypes.predicate.createValidatorFunctional(
677
- // @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
678
- ...KhanAnswerTypes.number.convertToPredicate(
679
- correctAnswer,
680
- options,
681
- ),
682
- );
683
- },
684
- },
685
-
686
- /*
687
- * The expression answer type parses a given expression or equation
688
- * and semantically compares it to the solution. In addition, instant
689
- * feedback is provided by rendering the last answer that fully parsed.
690
- *
691
- * Parsing options:
692
- * functions (e.g. data-functions="f g h")
693
- * A space or comma separated list of single-letter variables that
694
- * should be interpreted as functions. Case sensitive. "e" and "i"
695
- * are reserved.
696
- *
697
- * no functions specified: f(x+y) == fx + fy
698
- * with "f" as a function: f(x+y) != fx + fy
699
- *
700
- * Comparison options:
701
- * same-form (e.g. data-same-form)
702
- * If present, the answer must match the solution's structure in
703
- * addition to evaluating the same. Commutativity and excess negation
704
- * are ignored, but all other changes will trigger a rejection. Useful
705
- * for requiring a particular form of an equation, or if the answer
706
- * must be factored.
707
- *
708
- * example question: Factor x^2 + x - 2
709
- * example solution: (x-1)(x+2)
710
- * accepted answers: (x-1)(x+2), (x+2)(x-1), ---(-x-2)(-1+x), etc.
711
- * rejected answers: x^2+x-2, x*x+x-2, x(x+1)-2, (x-1)(x+2)^1, etc.
712
- * rejection message: Your answer is not in the correct form
713
- *
714
- * simplify (e.g. data-simplify)
715
- * If present, the answer must be fully expanded and simplified. Use
716
- * carefully - simplification is hard and there may be bugs, or you
717
- * might not agree on the definition of "simplified" used. You will
718
- * get an error if the provided solution is not itself fully expanded
719
- * and simplified.
720
- *
721
- * example question: Simplify ((n*x^5)^5) / (n^(-2)*x^2)^-3
722
- * example solution: x^31 / n
723
- * accepted answers: x^31 / n, x^31 / n^1, x^31 * n^(-1), etc.
724
- * rejected answers: (x^25 * n^5) / (x^(-6) * n^6), etc.
725
- * rejection message: Your answer is not fully expanded and simplified
726
- *
727
- * Rendering options:
728
- * times (e.g. data-times)
729
- * If present, explicit multiplication (such as between numbers) will
730
- * be rendered with a cross/x symbol (TeX: \times) instead of the usual
731
- * center dot (TeX: \cdot).
732
- *
733
- * normal rendering: 2 * 3^x -> 2 \cdot 3^{x}
734
- * but with "times": 2 * 3^x -> 2 \times 3^{x}
735
- */
736
- expression: {
737
- parseSolution: function (solutionString: string, options: any): any {
738
- let solution = KAS.parse(solutionString, options);
739
- if (!solution.parsed) {
740
- throw new PerseusError(
741
- "The provided solution (" +
742
- solutionString +
743
- ") didn't parse.",
744
- Errors.InvalidInput,
745
- );
746
- } else if (options.simplified && !solution.expr.isSimplified()) {
747
- throw new PerseusError(
748
- "The provided solution (" +
749
- solutionString +
750
- ") isn't fully expanded and simplified.",
751
- Errors.InvalidInput,
752
- );
753
- } else {
754
- solution = solution.expr;
755
- }
756
- return solution;
757
- },
758
-
759
- createValidatorFunctional: function (
760
- solution: any,
761
- options: any,
762
- ): (arg1: Guess) => Score {
763
- return function (guess: Guess): Score {
764
- const score = {
765
- empty: false,
766
- correct: false,
767
- message: null as string | null | undefined,
768
- guess: guess,
769
- // Setting `ungraded` to true indicates that if the
770
- // guess doesn't match any of the solutions, the guess
771
- // shouldn't be marked as incorrect; instead, `message`
772
- // should be shown to the user. This is different from
773
- // setting `empty` to true, since the behavior of `empty`
774
- // is that `message` only will be shown if the guess is
775
- // graded as empty for every solution.
776
- ungraded: false,
777
- } as const;
778
-
779
- // Don't bother parsing an empty input
780
- if (!guess) {
781
- // @ts-expect-error - TS2540 - Cannot assign to 'empty' because it is a read-only property.
782
- score.empty = true;
783
- return score;
784
- }
785
-
786
- const answer = KAS.parse(guess, options);
787
-
788
- // An unsuccessful parse doesn't count as wrong
789
- if (!answer.parsed) {
790
- // @ts-expect-error - TS2540 - Cannot assign to 'empty' because it is a read-only property.
791
- score.empty = true;
792
- return score;
793
- }
794
-
795
- // Solution will need to be parsed again if we're creating
796
- // this from a multiple question type
797
- if (typeof solution === "string") {
798
- solution = KhanAnswerTypes.expression.parseSolution(
799
- solution,
800
- options,
801
- );
802
- }
803
-
804
- const result = KAS.compare(answer.expr, solution, options);
805
-
806
- if (result.equal) {
807
- // Correct answer
808
- // @ts-expect-error - TS2540 - Cannot assign to 'correct' because it is a read-only property.
809
- score.correct = true;
810
- } else if (
811
- result.wrongVariableNames ||
812
- result.wrongVariableCase
813
- ) {
814
- // We don't want to give people an error for getting the
815
- // variable names or the variable case wrong.
816
- // TODO(aasmund): This should ideally have been handled
817
- // under the `result.message` condition, but the
818
- // KAS messages currently aren't translatable.
819
- // @ts-expect-error - TS2540 - Cannot assign to 'ungraded' because it is a read-only property.
820
- score.ungraded = true;
821
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
822
- score.message = result.wrongVariableCase
823
- ? errors.WRONG_CASE_ERROR
824
- : errors.WRONG_LETTER_ERROR;
825
- // Don't tell the use they're "almost there" in this case, that may not be true and isn't helpful.
826
- // @ts-expect-error - TS2339 - Property 'suppressAlmostThere' does not exist on type '{ readonly empty: false; readonly correct: false; readonly message: string | null | undefined; readonly guess: any; readonly ungraded: false; }'.
827
- score.suppressAlmostThere = true;
828
- } else if (result.message) {
829
- // Nearly correct answer
830
- // TODO(aasmund): This message also isn't translatable;
831
- // need to fix that in KAS
832
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
833
- score.message = result.message;
834
- } else {
835
- // Replace x with * and see if it would have been correct
836
- // TODO(aasmund): I think this branch is effectively dead,
837
- // because the replacement will only work in situations
838
- // where the variables are wrong (except if the variable
839
- // is x, in which case the replacement won't work either),
840
- // which is handled by another branch. When we implement a
841
- // more sophisticated variable check, revive this or
842
- // remove it completely if it will never come into play.
843
- const answerX = KAS.parse(
844
- guess.replace(/[xX]/g, "*"),
845
- options,
846
- );
847
- if (answerX.parsed) {
848
- const resultX = KAS.compare(
849
- answerX.expr,
850
- solution,
851
- options,
852
- );
853
- if (resultX.equal) {
854
- // @ts-expect-error - TS2540 - Cannot assign to 'ungraded' because it is a read-only property.
855
- score.ungraded = true;
856
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
857
- score.message = errors.MULTIPLICATION_SIGN_ERROR;
858
- } else if (resultX.message) {
859
- // TODO(aasmund): I18nize `score.message`
860
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
861
- score.message =
862
- resultX.message +
863
- " Also, I'm a computer. I only understand " +
864
- "multiplication if you use an " +
865
- "asterisk (*) as the multiplication " +
866
- "sign.";
867
- }
868
- }
869
- }
870
- return score;
871
- };
872
- },
873
- },
874
- } as const;
875
-
876
- export default KhanAnswerTypes;