@khanacademy/perseus 0.0.1 → 0.2.1

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 (507) hide show
  1. package/.babelrc.js +1 -1
  2. package/CHANGELOG.md +29 -0
  3. package/dist/es/index.css +4361 -0
  4. package/dist/es/index.js +7 -1
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.css +4361 -0
  7. package/dist/index.js +7 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/strings.js +148 -46
  10. package/package.json +50 -4
  11. package/src/README.md +35 -0
  12. package/src/__stories__/item-renderer.stories.jsx +27 -0
  13. package/src/__stories__/server-item-renderer.stories.jsx +27 -0
  14. package/src/__testdata__/item-renderer_testdata.js +161 -0
  15. package/src/__testdata__/renderer_testdata.js +123 -0
  16. package/src/__tests__/__snapshots__/item-renderer_test.jsx.snap +233 -0
  17. package/src/__tests__/__snapshots__/perseus-markdown_test.jsx.snap +516 -0
  18. package/src/__tests__/__snapshots__/pure-markdown_test.js.snap +113 -0
  19. package/src/__tests__/__snapshots__/renderer_test.jsx.snap +576 -0
  20. package/src/__tests__/__snapshots__/server-item-renderer_test.jsx.snap +306 -0
  21. package/src/__tests__/a11y_test.jsx +304 -0
  22. package/src/__tests__/item-renderer_test.jsx +892 -0
  23. package/src/__tests__/mock-asset-loading-widget.jsx +57 -0
  24. package/src/__tests__/mock-widget.jsx +35 -0
  25. package/src/__tests__/perseus-markdown_test.jsx +747 -0
  26. package/src/__tests__/pure-markdown_test.js +552 -0
  27. package/src/__tests__/renderability_test.jsx +481 -0
  28. package/src/__tests__/renderer-api_test.jsx +333 -0
  29. package/src/__tests__/renderer_test.jsx +1792 -0
  30. package/src/__tests__/server-item-renderer_test.jsx +516 -0
  31. package/src/__tests__/test-items/image-item.js +25 -0
  32. package/src/__tests__/test-items/input-number-1-item.js +27 -0
  33. package/src/__tests__/test-items/input-number-2-item.js +39 -0
  34. package/src/__tests__/test-items/table-item.js +30 -0
  35. package/src/__tests__/tex-wrangler_test.js +83 -0
  36. package/src/__tests__/util_test.js +41 -0
  37. package/src/a11y.js +46 -0
  38. package/src/all-widgets.js +9 -0
  39. package/src/article-renderer.jsx +215 -0
  40. package/src/asset-context.js +30 -0
  41. package/src/basic-widgets.js +13 -0
  42. package/src/components/__stories__/button-group.stories.jsx +61 -0
  43. package/src/components/__stories__/fixed-to-responsive.stories.jsx +132 -0
  44. package/src/components/__stories__/graph.stories.jsx +27 -0
  45. package/src/components/__stories__/graphie.stories.jsx +28 -0
  46. package/src/components/__stories__/hud.stories.jsx +36 -0
  47. package/src/components/__stories__/icon.stories.jsx +56 -0
  48. package/src/components/__stories__/image-loader.stories.jsx +60 -0
  49. package/src/components/__stories__/info-tip.stories.jsx +33 -0
  50. package/src/components/__stories__/inline-icon.stories.jsx +39 -0
  51. package/src/components/__stories__/input-with-examples.stories.jsx +51 -0
  52. package/src/components/__stories__/lint.stories.jsx +40 -0
  53. package/src/components/__stories__/math-input.stories.jsx +29 -0
  54. package/src/components/__stories__/math-output.stories.jsx +24 -0
  55. package/src/components/__stories__/multi-button-group.stories.jsx +69 -0
  56. package/src/components/__stories__/number-input.stories.jsx +42 -0
  57. package/src/components/__stories__/possible-answers.stories.jsx +22 -0
  58. package/src/components/__stories__/prop-check-box.stories.jsx +62 -0
  59. package/src/components/__stories__/range-input.stories.jsx +28 -0
  60. package/src/components/__stories__/simple-keypad-input.stories.jsx +28 -0
  61. package/src/components/__stories__/sortable.stories.jsx +73 -0
  62. package/src/components/__stories__/stub-tag-editor.stories.jsx +44 -0
  63. package/src/components/__stories__/svg-image.stories.jsx +60 -0
  64. package/src/components/__stories__/tex.stories.jsx +18 -0
  65. package/src/components/__stories__/text-buttons.stories.jsx +51 -0
  66. package/src/components/__stories__/text-input.stories.jsx +34 -0
  67. package/src/components/__stories__/text-list-editor.stories.jsx +33 -0
  68. package/src/components/__stories__/zoomable-tex.stories.jsx +39 -0
  69. package/src/components/__stories__/zoomable.stories.jsx +40 -0
  70. package/src/components/__testdata__/sorter_testdata.js +20 -0
  71. package/src/components/__tests__/__snapshots__/sortable_test.jsx.snap +79 -0
  72. package/src/components/__tests__/__snapshots__/sorter_test.jsx.snap +297 -0
  73. package/src/components/__tests__/number-input_test.jsx +112 -0
  74. package/src/components/__tests__/sortable_test.jsx +234 -0
  75. package/src/components/__tests__/sorter_test.jsx +111 -0
  76. package/src/components/__tests__/zoomable_test.jsx +388 -0
  77. package/src/components/button-group.jsx +131 -0
  78. package/src/components/constants.js +15 -0
  79. package/src/components/fixed-to-responsive.jsx +164 -0
  80. package/src/components/graph.jsx +415 -0
  81. package/src/components/graphie-classes.jsx +148 -0
  82. package/src/components/graphie-movables.jsx +342 -0
  83. package/src/components/graphie.jsx +353 -0
  84. package/src/components/highlighting/highlightable-content.jsx +245 -0
  85. package/src/components/highlighting/highlights.js +208 -0
  86. package/src/components/highlighting/ranges.js +299 -0
  87. package/src/components/highlighting/types.js +73 -0
  88. package/src/components/highlighting/ui/highlight-renderer.jsx +179 -0
  89. package/src/components/highlighting/ui/highlight-set-renderer.jsx +190 -0
  90. package/src/components/highlighting/ui/highlight-tooltip.jsx +153 -0
  91. package/src/components/highlighting/ui/highlighting-ui.jsx +163 -0
  92. package/src/components/highlighting/ui/selection-tracker.jsx +195 -0
  93. package/src/components/highlighting/ui/types.js +21 -0
  94. package/src/components/highlighting/ui/util.js +166 -0
  95. package/src/components/highlighting/word-indexer.jsx +155 -0
  96. package/src/components/hud.jsx +179 -0
  97. package/src/components/icon.jsx +149 -0
  98. package/src/components/image-loader.jsx +175 -0
  99. package/src/components/info-tip/info-tip.jsx +146 -0
  100. package/src/components/info-tip.jsx +38 -0
  101. package/src/components/inline-icon.jsx +81 -0
  102. package/src/components/input-with-examples.jsx +231 -0
  103. package/src/components/lint.jsx +454 -0
  104. package/src/components/math-input.jsx +282 -0
  105. package/src/components/math-output.jsx +128 -0
  106. package/src/components/multi-button-group.jsx +137 -0
  107. package/src/components/new-tooltip/README.md +110 -0
  108. package/src/components/new-tooltip/__stories__/flexible-position.stories.jsx +437 -0
  109. package/src/components/new-tooltip/__stories__/new-tooltip.stories.jsx +665 -0
  110. package/src/components/new-tooltip/__stories__/tooltip-arrow.stories.jsx +70 -0
  111. package/src/components/new-tooltip/__stories__/tooltip-bubble.stories.jsx +98 -0
  112. package/src/components/new-tooltip/__tests__/style-constants_test.js +8 -0
  113. package/src/components/new-tooltip/__tests__/util_test.js +47 -0
  114. package/src/components/new-tooltip/flexible-position.jsx +182 -0
  115. package/src/components/new-tooltip/new-tooltip.jsx +399 -0
  116. package/src/components/new-tooltip/style-constants.js +13 -0
  117. package/src/components/new-tooltip/tooltip-arrow.jsx +184 -0
  118. package/src/components/new-tooltip/tooltip-bubble.jsx +223 -0
  119. package/src/components/new-tooltip/tooltip-portal.jsx +101 -0
  120. package/src/components/new-tooltip/tooltip-positioner.jsx +529 -0
  121. package/src/components/new-tooltip/types.js +183 -0
  122. package/src/components/new-tooltip/util.js +27 -0
  123. package/src/components/number-input.jsx +253 -0
  124. package/src/components/possible-answers.jsx +36 -0
  125. package/src/components/prop-check-box.jsx +80 -0
  126. package/src/components/range-input.jsx +61 -0
  127. package/src/components/simple-keypad-input.jsx +91 -0
  128. package/src/components/sortable.jsx +873 -0
  129. package/src/components/stub-tag-editor.jsx +54 -0
  130. package/src/components/svg-image.jsx +762 -0
  131. package/src/components/tex-buttons.jsx +322 -0
  132. package/src/components/tex.jsx +70 -0
  133. package/src/components/text-input.jsx +82 -0
  134. package/src/components/text-list-editor.jsx +157 -0
  135. package/src/components/tooltip.jsx +395 -0
  136. package/src/components/visibility-observer/__stories__/visibility-observer.stories.jsx +140 -0
  137. package/src/components/visibility-observer/get-scroll-parent.js +45 -0
  138. package/src/components/visibility-observer/visibility-observer.js +109 -0
  139. package/src/components/visibility-observer/visibility-observer.jsx +123 -0
  140. package/src/components/zoomable-tex.jsx +70 -0
  141. package/src/components/zoomable.jsx +304 -0
  142. package/src/components.js +17 -0
  143. package/src/dependencies.js +22 -0
  144. package/src/error-boundary.jsx +48 -0
  145. package/src/extra-widgets.js +75 -0
  146. package/src/gorgon/README +40 -0
  147. package/src/gorgon/__tests__/matcher_test.js +497 -0
  148. package/src/gorgon/__tests__/rule_test.js +101 -0
  149. package/src/gorgon/__tests__/rules_test.js +487 -0
  150. package/src/gorgon/__tests__/selector-parser_test.js +52 -0
  151. package/src/gorgon/__tests__/tree-transformer_test.js +446 -0
  152. package/src/gorgon/gorgon.js +290 -0
  153. package/src/gorgon/proptypes.js +29 -0
  154. package/src/gorgon/rule.js +413 -0
  155. package/src/gorgon/rules/absolute-url.js +24 -0
  156. package/src/gorgon/rules/all-rules.js +72 -0
  157. package/src/gorgon/rules/blockquoted-math.js +10 -0
  158. package/src/gorgon/rules/blockquoted-widget.js +10 -0
  159. package/src/gorgon/rules/double-spacing-after-terminal.js +12 -0
  160. package/src/gorgon/rules/extra-content-spacing.js +12 -0
  161. package/src/gorgon/rules/heading-level-1.js +14 -0
  162. package/src/gorgon/rules/heading-level-skip.js +20 -0
  163. package/src/gorgon/rules/heading-sentence-case.js +11 -0
  164. package/src/gorgon/rules/heading-title-case.js +63 -0
  165. package/src/gorgon/rules/image-alt-text.js +21 -0
  166. package/src/gorgon/rules/image-in-table.js +10 -0
  167. package/src/gorgon/rules/image-spaces-around-urls.js +35 -0
  168. package/src/gorgon/rules/image-widget.js +50 -0
  169. package/src/gorgon/rules/link-click-here.js +11 -0
  170. package/src/gorgon/rules/lint-utils.js +48 -0
  171. package/src/gorgon/rules/long-paragraph.js +14 -0
  172. package/src/gorgon/rules/math-adjacent.js +10 -0
  173. package/src/gorgon/rules/math-align-extra-break.js +11 -0
  174. package/src/gorgon/rules/math-align-linebreaks.js +43 -0
  175. package/src/gorgon/rules/math-empty.js +10 -0
  176. package/src/gorgon/rules/math-font-size.js +12 -0
  177. package/src/gorgon/rules/math-frac.js +10 -0
  178. package/src/gorgon/rules/math-nested.js +11 -0
  179. package/src/gorgon/rules/math-starts-with-space.js +12 -0
  180. package/src/gorgon/rules/math-text-empty.js +10 -0
  181. package/src/gorgon/rules/math-without-dollars.js +14 -0
  182. package/src/gorgon/rules/nested-lists.js +11 -0
  183. package/src/gorgon/rules/profanity.js +10 -0
  184. package/src/gorgon/rules/table-missing-cells.js +20 -0
  185. package/src/gorgon/rules/unbalanced-code-delimiters.js +14 -0
  186. package/src/gorgon/rules/unescaped-dollar.js +10 -0
  187. package/src/gorgon/rules/widget-in-table.js +10 -0
  188. package/src/gorgon/selector.js +506 -0
  189. package/src/gorgon/tree-transformer.js +588 -0
  190. package/src/hint-renderer.jsx +159 -0
  191. package/src/hints-renderer.jsx +359 -0
  192. package/src/icon-paths.js +120 -0
  193. package/src/index.js +149 -2
  194. package/src/init.js +49 -0
  195. package/src/interaction-tracker.js +60 -0
  196. package/src/interactive2/__tests__/movable-mock.js +48 -0
  197. package/src/interactive2/__tests__/movable-point_test.js +146 -0
  198. package/src/interactive2/interactive-util.js +152 -0
  199. package/src/interactive2/movable-helper-methods.js +160 -0
  200. package/src/interactive2/movable-line-options.js +392 -0
  201. package/src/interactive2/movable-line.js +322 -0
  202. package/src/interactive2/movable-point-options.js +190 -0
  203. package/src/interactive2/movable-point.jsx +603 -0
  204. package/src/interactive2/movable-polygon-options.js +351 -0
  205. package/src/interactive2/movable-polygon.js +368 -0
  206. package/src/interactive2/movable.js +273 -0
  207. package/src/interactive2/objective_.js +79 -0
  208. package/src/interactive2/types.js +3 -0
  209. package/src/interactive2/wrapped-defaults.js +86 -0
  210. package/src/interactive2/wrapped-ellipse.js +87 -0
  211. package/src/interactive2/wrapped-line.js +109 -0
  212. package/src/interactive2/wrapped-path.js +47 -0
  213. package/src/interactive2.js +91 -0
  214. package/src/item-renderer.jsx +518 -0
  215. package/src/item-version.js +12 -0
  216. package/src/jipt-paragraphs.js +44 -0
  217. package/src/jquery.mobile.vmouse.js +545 -0
  218. package/src/keypad-context.js +33 -0
  219. package/src/loading-context.js +20 -0
  220. package/src/logging/log.js +107 -0
  221. package/src/logging/log_test.js +41 -0
  222. package/src/mixins/changeable.jsx +115 -0
  223. package/src/mixins/editor-jsonify.jsx +13 -0
  224. package/src/mixins/provide-keypad.jsx +129 -0
  225. package/src/mixins/widget-jsonify-deprecated.jsx +23 -0
  226. package/src/mixins/widget-prop-blacklist.js +36 -0
  227. package/src/multi-items/__stories__/multi-renderer.stories.js +88 -0
  228. package/src/multi-items/__testdata__/multi-renderer_testdata.js +174 -0
  229. package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +994 -0
  230. package/src/multi-items/__tests__/items_test.js +245 -0
  231. package/src/multi-items/__tests__/multi-renderer_test.js +903 -0
  232. package/src/multi-items/__tests__/prop-type-builders_test.js +134 -0
  233. package/src/multi-items/__tests__/shapes_test.js +44 -0
  234. package/src/multi-items/__tests__/trees_test.js +316 -0
  235. package/src/multi-items/item-types.js +55 -0
  236. package/src/multi-items/items.js +176 -0
  237. package/src/multi-items/multi-renderer.jsx +543 -0
  238. package/src/multi-items/prop-type-builders.js +105 -0
  239. package/src/multi-items/shape-types.js +47 -0
  240. package/src/multi-items/shapes.js +53 -0
  241. package/src/multi-items/tree-types.js +42 -0
  242. package/src/multi-items/trees.js +345 -0
  243. package/src/multi-items.js +76 -0
  244. package/src/not-gorgon.js +129 -0
  245. package/src/perseus-api.jsx +270 -0
  246. package/src/perseus-env.js +26 -0
  247. package/src/perseus-error.js +19 -0
  248. package/src/perseus-markdown.jsx +433 -0
  249. package/src/perseus-types.js +1597 -0
  250. package/src/pure-markdown.js +347 -0
  251. package/src/question-paragraph.jsx +30 -0
  252. package/src/renderability.jsx +108 -0
  253. package/src/renderer.jsx +1932 -0
  254. package/src/server-item-renderer.jsx +467 -0
  255. package/src/sigfigs.jsx +492 -0
  256. package/src/styles/articles.less +748 -0
  257. package/src/styles/constants.js +119 -0
  258. package/src/styles/global-constants.js +350 -0
  259. package/src/styles/global-styles.js +307 -0
  260. package/src/styles/khan-exercise.css +1304 -0
  261. package/src/styles/media-queries.js +48 -0
  262. package/src/styles/perseus-renderer.less +1007 -0
  263. package/src/styles/shared.js +132 -0
  264. package/src/styles/util.less +47 -0
  265. package/src/styles/variables.boostrap.less +301 -0
  266. package/src/styles/variables.less +68 -0
  267. package/src/styles/variables.shared.less +356 -0
  268. package/src/styles/widgets/categorizer.less +39 -0
  269. package/src/styles/widgets/definition.less +86 -0
  270. package/src/styles/widgets/dropdown.less +3 -0
  271. package/src/styles/widgets/expression.less +147 -0
  272. package/src/styles/widgets/graded-group.less +36 -0
  273. package/src/styles/widgets/grapher.less +11 -0
  274. package/src/styles/widgets/group.less +19 -0
  275. package/src/styles/widgets/image.less +29 -0
  276. package/src/styles/widgets/interactive-graph.less +61 -0
  277. package/src/styles/widgets/label-image.less +41 -0
  278. package/src/styles/widgets/matcher.less +8 -0
  279. package/src/styles/widgets/matrix.less +120 -0
  280. package/src/styles/widgets/measurer.less +20 -0
  281. package/src/styles/widgets/orderer.less +97 -0
  282. package/src/styles/widgets/passage.less +151 -0
  283. package/src/styles/widgets/plotter.less +33 -0
  284. package/src/styles/widgets/radio.less +52 -0
  285. package/src/styles/widgets/reaction-diagram.less +35 -0
  286. package/src/styles/widgets/sequence.less +5 -0
  287. package/src/styles/widgets/sortable.less +127 -0
  288. package/src/styles/widgets/table.less +56 -0
  289. package/src/styles/widgets/transformer.less +28 -0
  290. package/src/styles/widgets/unit.less +14 -0
  291. package/src/tex-wrangler.js +176 -0
  292. package/src/traversal.jsx +141 -0
  293. package/src/types.js +538 -0
  294. package/src/util/a11y.js +24 -0
  295. package/src/util/answer-types.js +862 -0
  296. package/src/util/answer-types_test.js +115 -0
  297. package/src/util/colors.js +94 -0
  298. package/src/util/fix-passage-refs.jsx +122 -0
  299. package/src/util/graph-utils.js +16 -0
  300. package/src/util/graphie.js +1586 -0
  301. package/src/util/interactive.js +4078 -0
  302. package/src/util/katex-preprocess.js +16 -0
  303. package/src/util/math.js +296 -0
  304. package/src/util/mobile-native-utils.js +14 -0
  305. package/src/util/mobile-native-utils_test.js +24 -0
  306. package/src/util/register-all-widgets-for-testing.js +12 -0
  307. package/src/util/scroll-utils.js +162 -0
  308. package/src/util/sizing-utils.js +46 -0
  309. package/src/util/tex.js +203 -0
  310. package/src/util/url-utils.js +36 -0
  311. package/src/util.js +990 -0
  312. package/src/version.js +11 -0
  313. package/src/widget-container.jsx +174 -0
  314. package/src/widgets/__stories__/categorizer.stories.jsx +15 -0
  315. package/src/widgets/__stories__/cs-program.stories.jsx +15 -0
  316. package/src/widgets/__stories__/definition.stories.jsx +38 -0
  317. package/src/widgets/__stories__/dropdown.stories.jsx +15 -0
  318. package/src/widgets/__stories__/explanation.stories.jsx +19 -0
  319. package/src/widgets/__stories__/expression.stories.jsx +26 -0
  320. package/src/widgets/__stories__/graded-group-set.stories.jsx +32 -0
  321. package/src/widgets/__stories__/graded-group.stories.jsx +32 -0
  322. package/src/widgets/__stories__/grapher.stories.jsx +47 -0
  323. package/src/widgets/__stories__/group.stories.jsx +15 -0
  324. package/src/widgets/__stories__/iframe.stories.jsx +15 -0
  325. package/src/widgets/__stories__/image.stories.jsx +62 -0
  326. package/src/widgets/__stories__/input-number.stories.jsx +90 -0
  327. package/src/widgets/__stories__/interaction.stories.jsx +15 -0
  328. package/src/widgets/__stories__/interactive-graph.stories.jsx +61 -0
  329. package/src/widgets/__stories__/matcher.stories.jsx +15 -0
  330. package/src/widgets/__stories__/matrix.stories.jsx +15 -0
  331. package/src/widgets/__stories__/number-line.stories.jsx +15 -0
  332. package/src/widgets/__stories__/numeric-input.stories.jsx +19 -0
  333. package/src/widgets/__stories__/orderer.stories.jsx +15 -0
  334. package/src/widgets/__stories__/passage-ref.stories.jsx +19 -0
  335. package/src/widgets/__stories__/passage.stories.jsx +19 -0
  336. package/src/widgets/__stories__/radio.stories.jsx +82 -0
  337. package/src/widgets/__stories__/sorter.stories.jsx +15 -0
  338. package/src/widgets/__stories__/transformer.stories.jsx +15 -0
  339. package/src/widgets/__stories__/unit.stories.jsx +45 -0
  340. package/src/widgets/__stories__/video-transcript-link.stories.jsx +24 -0
  341. package/src/widgets/__stories__/video.stories.jsx +15 -0
  342. package/src/widgets/__testdata__/categorizer_testdata.js +50 -0
  343. package/src/widgets/__testdata__/cs-program_testdata.js +28 -0
  344. package/src/widgets/__testdata__/dropdown_testdata.js +34 -0
  345. package/src/widgets/__testdata__/explanation_testdata.js +56 -0
  346. package/src/widgets/__testdata__/expression_testdata.js +95 -0
  347. package/src/widgets/__testdata__/graded-group-set_testdata.js +358 -0
  348. package/src/widgets/__testdata__/graded-group_testdata.js +79 -0
  349. package/src/widgets/__testdata__/grapher_testdata.js +376 -0
  350. package/src/widgets/__testdata__/group_testdata.js +156 -0
  351. package/src/widgets/__testdata__/iframe_testdata.js +36 -0
  352. package/src/widgets/__testdata__/image_testdata.js +38 -0
  353. package/src/widgets/__testdata__/input-number_testdata.js +73 -0
  354. package/src/widgets/__testdata__/interaction_testdata.js +264 -0
  355. package/src/widgets/__testdata__/interactive-graph_testdata.js +646 -0
  356. package/src/widgets/__testdata__/matcher_testdata.js +34 -0
  357. package/src/widgets/__testdata__/matrix_testdata.js +29 -0
  358. package/src/widgets/__testdata__/number-line_testdata.js +31 -0
  359. package/src/widgets/__testdata__/numeric-input_testdata.js +266 -0
  360. package/src/widgets/__testdata__/orderer_testdata.js +58 -0
  361. package/src/widgets/__testdata__/passage-ref_testdata.js +41 -0
  362. package/src/widgets/__testdata__/passage_testdata.js +71 -0
  363. package/src/widgets/__testdata__/radio_testdata.js +210 -0
  364. package/src/widgets/__testdata__/sorter_testdata.js +20 -0
  365. package/src/widgets/__testdata__/transformer_testdata.js +109 -0
  366. package/src/widgets/__testdata__/video_testdata.js +22 -0
  367. package/src/widgets/__tests__/__snapshots__/categorizer_test.jsx.snap +928 -0
  368. package/src/widgets/__tests__/__snapshots__/cs-program_test.jsx.snap +75 -0
  369. package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +99 -0
  370. package/src/widgets/__tests__/__snapshots__/dropdown_test.jsx.snap +143 -0
  371. package/src/widgets/__tests__/__snapshots__/explanation_test.js.snap +473 -0
  372. package/src/widgets/__tests__/__snapshots__/expression_test.jsx.snap +38 -0
  373. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +754 -0
  374. package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +310 -0
  375. package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +863 -0
  376. package/src/widgets/__tests__/__snapshots__/grapher_test.jsx.snap +2880 -0
  377. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +1154 -0
  378. package/src/widgets/__tests__/__snapshots__/iframe_test.jsx.snap +69 -0
  379. package/src/widgets/__tests__/__snapshots__/image_test.jsx.snap +388 -0
  380. package/src/widgets/__tests__/__snapshots__/input-number_test.jsx.snap +978 -0
  381. package/src/widgets/__tests__/__snapshots__/interaction_test.jsx.snap +311 -0
  382. package/src/widgets/__tests__/__snapshots__/interactive-graph_test.jsx.snap +2915 -0
  383. package/src/widgets/__tests__/__snapshots__/matcher_test.jsx.snap +1039 -0
  384. package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +450 -0
  385. package/src/widgets/__tests__/__snapshots__/number-line_test.jsx.snap +888 -0
  386. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +930 -0
  387. package/src/widgets/__tests__/__snapshots__/orderer_test.jsx.snap +275 -0
  388. package/src/widgets/__tests__/__snapshots__/passage-ref_test.jsx.snap +446 -0
  389. package/src/widgets/__tests__/__snapshots__/passage_test.jsx.snap +1988 -0
  390. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +7107 -0
  391. package/src/widgets/__tests__/__snapshots__/video_test.jsx.snap +163 -0
  392. package/src/widgets/__tests__/categorizer_test.jsx +205 -0
  393. package/src/widgets/__tests__/cs-program_test.jsx +45 -0
  394. package/src/widgets/__tests__/definition_test.js +152 -0
  395. package/src/widgets/__tests__/dropdown_test.jsx +106 -0
  396. package/src/widgets/__tests__/explanation_test.js +199 -0
  397. package/src/widgets/__tests__/expression_test.jsx +439 -0
  398. package/src/widgets/__tests__/graded-group-set-jipt_test.jsx +33 -0
  399. package/src/widgets/__tests__/graded-group-set_test.jsx +270 -0
  400. package/src/widgets/__tests__/graded-group_test.jsx +233 -0
  401. package/src/widgets/__tests__/grapher.cypress.jsx +486 -0
  402. package/src/widgets/__tests__/grapher_test.jsx +35 -0
  403. package/src/widgets/__tests__/group_test.jsx +512 -0
  404. package/src/widgets/__tests__/iframe_test.jsx +47 -0
  405. package/src/widgets/__tests__/image_test.jsx +65 -0
  406. package/src/widgets/__tests__/input-number_test.jsx +360 -0
  407. package/src/widgets/__tests__/interaction_test.jsx +33 -0
  408. package/src/widgets/__tests__/interactive-graph.cypress.jsx +697 -0
  409. package/src/widgets/__tests__/interactive-graph_test.jsx +105 -0
  410. package/src/widgets/__tests__/matcher_test.jsx +157 -0
  411. package/src/widgets/__tests__/matrix_test.jsx +84 -0
  412. package/src/widgets/__tests__/number-line_test.jsx +81 -0
  413. package/src/widgets/__tests__/numeric-input_test.jsx +574 -0
  414. package/src/widgets/__tests__/orderer_test.jsx +75 -0
  415. package/src/widgets/__tests__/passage-ref_test.jsx +166 -0
  416. package/src/widgets/__tests__/passage_test.jsx +133 -0
  417. package/src/widgets/__tests__/radio/base-radio_test.jsx +82 -0
  418. package/src/widgets/__tests__/radio_test.jsx +651 -0
  419. package/src/widgets/__tests__/renderQuestion.jsx +66 -0
  420. package/src/widgets/__tests__/unit_test.jsx +144 -0
  421. package/src/widgets/__tests__/video_test.jsx +55 -0
  422. package/src/widgets/categorizer.jsx +338 -0
  423. package/src/widgets/cs-program.jsx +227 -0
  424. package/src/widgets/definition.jsx +141 -0
  425. package/src/widgets/dropdown.jsx +143 -0
  426. package/src/widgets/explanation.jsx +315 -0
  427. package/src/widgets/expression.jsx +652 -0
  428. package/src/widgets/graded-group-answer-bar.jsx +152 -0
  429. package/src/widgets/graded-group-set.jsx +285 -0
  430. package/src/widgets/graded-group.jsx +448 -0
  431. package/src/widgets/grapher/util.jsx +806 -0
  432. package/src/widgets/grapher.jsx +663 -0
  433. package/src/widgets/group.jsx +213 -0
  434. package/src/widgets/iframe.jsx +198 -0
  435. package/src/widgets/image.jsx +310 -0
  436. package/src/widgets/input-number.jsx +411 -0
  437. package/src/widgets/interaction/arrow-picker.jsx +39 -0
  438. package/src/widgets/interaction/color-picker.jsx +69 -0
  439. package/src/widgets/interaction/dash-picker.jsx +46 -0
  440. package/src/widgets/interaction/element-container.jsx +97 -0
  441. package/src/widgets/interaction.jsx +742 -0
  442. package/src/widgets/interactive-graph.jsx +2820 -0
  443. package/src/widgets/label-image/__stories__/answer-choices.stories.jsx +93 -0
  444. package/src/widgets/label-image/__stories__/marker.stories.jsx +172 -0
  445. package/src/widgets/label-image/answer-choices.jsx +311 -0
  446. package/src/widgets/label-image/marker.jsx +365 -0
  447. package/src/widgets/label-image/types.js +33 -0
  448. package/src/widgets/label-image.jsx +841 -0
  449. package/src/widgets/label-image_test.js +840 -0
  450. package/src/widgets/lights-puzzle.jsx +356 -0
  451. package/src/widgets/matcher.jsx +271 -0
  452. package/src/widgets/matrix.jsx +616 -0
  453. package/src/widgets/measurer.jsx +215 -0
  454. package/src/widgets/molecule/__tests__/layout_test.jsx +159 -0
  455. package/src/widgets/molecule/__tests__/parser_test.jsx +142 -0
  456. package/src/widgets/molecule/molecule-drawing.jsx +175 -0
  457. package/src/widgets/molecule/molecule-layout.jsx +367 -0
  458. package/src/widgets/molecule/smiles-parser.jsx +300 -0
  459. package/src/widgets/molecule.jsx +172 -0
  460. package/src/widgets/number-line.jsx +858 -0
  461. package/src/widgets/numeric-input.jsx +622 -0
  462. package/src/widgets/orderer.jsx +753 -0
  463. package/src/widgets/passage/__tests__/passage-markdown_test.jsx +382 -0
  464. package/src/widgets/passage/get-line-height-for-node.js +10 -0
  465. package/src/widgets/passage/passage-markdown.jsx +416 -0
  466. package/src/widgets/passage-ref-target.jsx +70 -0
  467. package/src/widgets/passage-ref.jsx +198 -0
  468. package/src/widgets/passage.jsx +601 -0
  469. package/src/widgets/plotter.jsx +1198 -0
  470. package/src/widgets/radio/__stories__/base-radio.stories.jsx +40 -0
  471. package/src/widgets/radio/__stories__/choice-icon.stories.jsx +157 -0
  472. package/src/widgets/radio/__stories__/choice-none-above.stories.jsx +26 -0
  473. package/src/widgets/radio/__stories__/cross-out-button.stories.jsx +64 -0
  474. package/src/widgets/radio/__stories__/cross-out-menu.stories.jsx +59 -0
  475. package/src/widgets/radio/__stories__/cross-out-tooltip.stories.jsx +59 -0
  476. package/src/widgets/radio/__stories__/focus-ring.stories.jsx +38 -0
  477. package/src/widgets/radio/__stories__/option-status.stories.jsx +118 -0
  478. package/src/widgets/radio/__stories__/toggleable-radio-button.stories.jsx +28 -0
  479. package/src/widgets/radio/base-radio.jsx +642 -0
  480. package/src/widgets/radio/choice-icon.jsx +468 -0
  481. package/src/widgets/radio/choice-none-above.jsx +54 -0
  482. package/src/widgets/radio/choice.jsx +692 -0
  483. package/src/widgets/radio/choice.jsx.fixture.js +64 -0
  484. package/src/widgets/radio/cross-out-button.jsx +136 -0
  485. package/src/widgets/radio/cross-out-menu-wrapper.jsx +492 -0
  486. package/src/widgets/radio/cross-out-tooltip.jsx +129 -0
  487. package/src/widgets/radio/focus-ring.jsx +51 -0
  488. package/src/widgets/radio/option-status.jsx +89 -0
  489. package/src/widgets/radio/toggleable-radio-button.jsx +133 -0
  490. package/src/widgets/radio/util.js +32 -0
  491. package/src/widgets/radio/util_test.js +19 -0
  492. package/src/widgets/radio/widget.jsx +470 -0
  493. package/src/widgets/radio.jsx +156 -0
  494. package/src/widgets/reaction-diagram.jsx +137 -0
  495. package/src/widgets/sequence.jsx +140 -0
  496. package/src/widgets/simulator.jsx +808 -0
  497. package/src/widgets/sorter.jsx +146 -0
  498. package/src/widgets/table.jsx +394 -0
  499. package/src/widgets/transformer.jsx +2876 -0
  500. package/src/widgets/unit.jsx +372 -0
  501. package/src/widgets/video-transcript-link.jsx +84 -0
  502. package/src/widgets/video-transcript-link_test.js +211 -0
  503. package/src/widgets/video.jsx +126 -0
  504. package/src/widgets.js +431 -0
  505. package/src/zoom.js +539 -0
  506. package/README.md +0 -3
  507. package/src/__tests__/index.test.js +0 -14
@@ -0,0 +1,160 @@
1
+ /* eslint-disable @babel/no-invalid-this */
2
+ // @flow
3
+ /**
4
+ * MovableThing convenience methods
5
+ *
6
+ * Usually added to a Movable* class through
7
+ * InteractiveUtils.addMovableHelperMethodsTo(), but these implementations
8
+ * are simply for convenience.
9
+ */
10
+
11
+ import {point as kpoint} from "@khanacademy/kmath";
12
+ import _ from "underscore";
13
+
14
+ import {Errors} from "../logging/log.js";
15
+ import {PerseusError} from "../perseus-error.js";
16
+
17
+ /* Local helper methods. */
18
+
19
+ function getKey(eventName, id) {
20
+ return eventName + ":" + id;
21
+ }
22
+
23
+ function getEventName(key) {
24
+ return key.split(":")[0];
25
+ }
26
+
27
+ const MovableHelperMethods: $FlowFixMe = {
28
+ /**
29
+ * Fire an onSomething type event to all functions in listeners
30
+ */
31
+ _fireEvent: function (listeners, currentValue, previousValue) {
32
+ _.invoke(listeners, "call", this, currentValue, previousValue);
33
+ },
34
+
35
+ /**
36
+ * Combine the array of constraints functions
37
+ * Returns either an [x, y] coordinate or false
38
+ */
39
+ _applyConstraints: function (current, previous, extraOptions) {
40
+ let skipRemaining = false;
41
+
42
+ return _.reduce(
43
+ this.state.constraints,
44
+ (memo, constraint) => {
45
+ // A move that has been cancelled won't be propagated to later
46
+ // constraints calls
47
+ if (memo === false) {
48
+ return false;
49
+ }
50
+
51
+ if (skipRemaining) {
52
+ return memo;
53
+ }
54
+
55
+ const result = constraint.call(this, memo, previous, {
56
+ onSkipRemaining: () => {
57
+ skipRemaining = true;
58
+ },
59
+ ...extraOptions,
60
+ });
61
+
62
+ if (result === false) {
63
+ // Returning false cancels the move
64
+ return false;
65
+ }
66
+ if (kpoint.is(result, 2)) {
67
+ // Returning a coord from constraints overrides the move
68
+ return result;
69
+ }
70
+ if (result === true || result == null) {
71
+ // Returning true or undefined allow the move to occur
72
+ return memo;
73
+ }
74
+ // Anything else is an error
75
+ throw new PerseusError(
76
+ "Constraint returned invalid result: " + result,
77
+ Errors.Internal,
78
+ );
79
+ },
80
+ current,
81
+ this,
82
+ );
83
+ },
84
+
85
+ /**
86
+ * Call all draw functions, and update our prevState for the next
87
+ * draw function
88
+ */
89
+ draw: function () {
90
+ const currState = this.cloneState();
91
+ MovableHelperMethods._fireEvent.call(
92
+ this,
93
+ this.state.draw,
94
+ currState,
95
+ this.prevState,
96
+ );
97
+ this.prevState = currState;
98
+ },
99
+
100
+ /**
101
+ * Add a listener to any event: startMove, constraints, onMove, onMoveEnd,
102
+ * etc. If a listener is already bound to the given eventName and id, then
103
+ * it is overwritten by func.
104
+ *
105
+ * eventName: the string name of the event to listen to. one of:
106
+ * "onMoveStart", "onMove", "onMoveEnd", "draw", "remove"
107
+ *
108
+ * id: a string id that can be used to remove this event at a later time
109
+ * note: adding multiple listeners with the same id is undefined behavior
110
+ *
111
+ * func: the function to call when the event happens, which is called
112
+ * with the event's standard parameters [usually (coord, prevCoord) or
113
+ * (state, prevState)]
114
+ */
115
+ listen: function (eventName, id, func) {
116
+ this._listenerMap = this._listenerMap || {};
117
+
118
+ // If there's an existing handler, replace it by using its index in
119
+ // `this.state[eventName]`; otherwise, add this handler to the end
120
+ const key = getKey(eventName, id);
121
+ const index = (this._listenerMap[key] =
122
+ this._listenerMap[key] || this.state[eventName].length);
123
+ this.state[eventName][index] = func;
124
+ },
125
+
126
+ /**
127
+ * Remove a previously added listener, by the id specified in the
128
+ * corresponding listen() call
129
+ *
130
+ * If the given id has not been registered already, this is a no-op
131
+ */
132
+ unlisten: function (eventName, id) {
133
+ this._listenerMap = this._listenerMap || {};
134
+
135
+ const key = getKey(eventName, id);
136
+ const index = this._listenerMap[key];
137
+ if (index !== undefined) {
138
+ // Remove handler from list of event handlers and listenerMap
139
+ this.state[eventName].splice(index, 1);
140
+ delete this._listenerMap[key];
141
+
142
+ // Re-index existing events: if they occur after `index`, decrement
143
+ const keys = _.keys(this._listenerMap);
144
+ _.each(
145
+ keys,
146
+ function (key) {
147
+ if (
148
+ getEventName(key) === eventName &&
149
+ this._listenerMap[key] > index
150
+ ) {
151
+ this._listenerMap[key]--;
152
+ }
153
+ },
154
+ this,
155
+ );
156
+ }
157
+ },
158
+ };
159
+
160
+ export default MovableHelperMethods;
@@ -0,0 +1,392 @@
1
+ /* eslint-disable @babel/no-invalid-this */
2
+ // @flow
3
+ /**
4
+ * A library of options to pass to add/draw/remove/constraints
5
+ */
6
+ import {vector as kvector, point as kpoint} from "@khanacademy/kmath";
7
+ import _ from "underscore";
8
+
9
+ import KhanMath from "../util/math.js";
10
+
11
+ import WrappedLine from "./wrapped-line.js";
12
+ import WrappedPath from "./wrapped-path.js";
13
+
14
+ import type {Coord} from "./types.js";
15
+
16
+ /**
17
+ * Helper functions
18
+ */
19
+ const getScaledAngle = function (line) {
20
+ const scaledA = line.graphie.scalePoint(line.coord(0));
21
+ const scaledZ = line.graphie.scalePoint(line.coord(1));
22
+ return kvector.polarDegFromCart(kvector.subtract(scaledZ, scaledA))[1];
23
+ };
24
+
25
+ // Given `coord` and `angle`, find the point where a line extended
26
+ // from `coord` in the direction of `angle` would be clipped by the
27
+ // edge of the graphie canvas. Then draw an arrowhead at that point
28
+ // pointing in the direction of `angle`.
29
+ const getClipPoint = function (graph, coord: Coord, angle: number) {
30
+ // Actually put the arrowheads 4px from the edge so they have
31
+ // a bit of room
32
+ const xExtent = graph.range[0][1] - graph.range[0][0];
33
+ const yExtent = graph.range[1][1] - graph.range[1][0];
34
+
35
+ // shoot a point off into the distance ...
36
+ const distance = xExtent + yExtent;
37
+ // we need to scale the point according to the scale of the axes
38
+ const angleVec = graph.unscaleVector(kvector.cartFromPolarDeg(1, angle));
39
+ const distVec = kvector.scale(kvector.normalize(angleVec), distance);
40
+ const farCoord = kvector.add(coord, distVec);
41
+ const scaledAngle = kvector.polarDegFromCart(angleVec)[1];
42
+ // ... and then bring it back
43
+ const clipPoint = graph.constrainToBoundsOnAngle(
44
+ farCoord,
45
+ 4,
46
+ (scaledAngle * Math.PI) / 180,
47
+ );
48
+ return clipPoint;
49
+ };
50
+
51
+ // Given `coord` and `angle`, find the point where a line extended
52
+ // from `coord` in the direction of `angle` would be clipped by the
53
+ // edge of the graphie canvas. Then draw an arrowhead at that point
54
+ // pointing in the direction of `angle`.
55
+ const createArrow = function (graph, style) {
56
+ // Points that define the arrowhead
57
+ const center = [0.75, 0];
58
+ let points = [
59
+ [-3, 4],
60
+ [-2.75, 2.5],
61
+ [0, 0.25],
62
+ center,
63
+ [0, -0.25],
64
+ [-2.75, -2.5],
65
+ [-3, -4],
66
+ ];
67
+
68
+ // Scale points by 1.4 around (0.75, 0)
69
+ const scale = 1.4;
70
+ points = _.map(points, function (point) {
71
+ const pv = kvector.subtract(point, center);
72
+ const pvScaled = kvector.scale(pv, scale);
73
+ return kvector.add(center, pvScaled);
74
+ });
75
+
76
+ // We can't just pass in a path to `graph.fixedPath` as we need to modify
77
+ // the points in some way, so instead we provide a function for creating
78
+ // the path once the points have been transformed
79
+ const createCubicPath = function (points) {
80
+ let path = "M" + points[0][0] + " " + points[0][1];
81
+ for (let i = 1; i < points.length; i += 3) {
82
+ path +=
83
+ "C" +
84
+ points[i][0] +
85
+ " " +
86
+ points[i][1] +
87
+ " " +
88
+ points[i + 1][0] +
89
+ " " +
90
+ points[i + 1][1] +
91
+ " " +
92
+ points[i + 2][0] +
93
+ " " +
94
+ points[i + 2][1];
95
+ }
96
+ return path;
97
+ };
98
+
99
+ // Create arrowhead
100
+ const unscaledPoints = _.map(points, graph.unscalePoint);
101
+ const options = {
102
+ center: graph.unscalePoint(center),
103
+ createPath: createCubicPath,
104
+ };
105
+ // $FlowFixMe[invalid-constructor]
106
+ const arrowHead = new WrappedPath(graph, unscaledPoints, options);
107
+ arrowHead.attr(
108
+ _.extend(
109
+ {
110
+ "stroke-linejoin": "round",
111
+ "stroke-linecap": "round",
112
+ "stroke-dasharray": "",
113
+ },
114
+ style,
115
+ ),
116
+ );
117
+
118
+ // Add custom function for transforming arrowheads that accounts for
119
+ // center, scaling, etc.
120
+ // $FlowFixMe[prop-missing]
121
+ arrowHead.toCoordAtAngle = function (coord: Coord, angle: number) {
122
+ const clipPoint = graph.scalePoint(getClipPoint(graph, coord, angle));
123
+ arrowHead.transform(
124
+ "translateX(" +
125
+ (clipPoint[0] + scale * center[0]) +
126
+ "px) " +
127
+ "translateY(" +
128
+ (clipPoint[1] + scale * center[1]) +
129
+ "px) " +
130
+ "translateZ(0) " +
131
+ "rotate(" +
132
+ (360 - KhanMath.bound(angle)) +
133
+ "deg)",
134
+ );
135
+ };
136
+
137
+ return arrowHead;
138
+ };
139
+
140
+ /**
141
+ * MovableLine option functions
142
+ */
143
+ const add = {
144
+ // We do this in add as well as in standard so that we can call
145
+ // pointsToFront after the first draw (which adds `this.visibleShape`)
146
+ draw: function () {
147
+ this.draw();
148
+ },
149
+
150
+ pointsToFront: function (state: $FlowFixMe) {
151
+ _.invoke(state.points, "toFront");
152
+ },
153
+ };
154
+
155
+ // $FlowFixMe[prop-missing]
156
+ add.standard = [add.draw, add.pointsToFront];
157
+
158
+ const modify = {
159
+ draw: function () {
160
+ this.draw();
161
+ },
162
+ };
163
+
164
+ // $FlowFixMe[prop-missing]
165
+ modify.standard = [modify.draw];
166
+
167
+ const draw = {
168
+ basic: function (state: $FlowFixMe) {
169
+ const graphie = this.graphie;
170
+ let start = this.coord(0);
171
+ let end = this.coord(1);
172
+
173
+ if (!this.state.visibleShape) {
174
+ const options = {
175
+ thickness: 10,
176
+ };
177
+ // $FlowFixMe[invalid-constructor]
178
+ this.state.visibleShape = new WrappedLine(
179
+ graphie,
180
+ start,
181
+ end,
182
+ options,
183
+ );
184
+ this.state.visibleShape.attr(this.normalStyle());
185
+ this.state.visibleShape.toFront();
186
+
187
+ if (this.mouseTarget()) {
188
+ this.mouseTarget().toFront();
189
+ }
190
+ }
191
+
192
+ // Compute angle
193
+ const angle = getScaledAngle(this);
194
+
195
+ // Extend start, end if necessary (i.e., if not a line segment)
196
+ if (state.extendLine) {
197
+ start = getClipPoint(graphie, start, 360 - angle);
198
+ end = getClipPoint(graphie, end, (540 - angle) % 360);
199
+ } else if (state.extendRay) {
200
+ end = getClipPoint(graphie, end, 360 - angle);
201
+ }
202
+
203
+ // Move elements
204
+ const elements = [this.state.visibleShape];
205
+
206
+ if (this.mouseTarget()) {
207
+ elements.push(this.mouseTarget());
208
+ }
209
+ _.each(elements, function (element) {
210
+ element.moveTo(start, end);
211
+ });
212
+ },
213
+
214
+ arrows: function (state: $FlowFixMe) {
215
+ // Create arrows, if not yet created
216
+ if (this._arrows == null) {
217
+ this._arrows = [];
218
+ if (state.extendLine) {
219
+ this._arrows.push(
220
+ createArrow(this.graphie, this.normalStyle()),
221
+ );
222
+ this._arrows.push(
223
+ createArrow(this.graphie, this.normalStyle()),
224
+ );
225
+ } else if (state.extendRay) {
226
+ this._arrows.push(
227
+ createArrow(this.graphie, this.normalStyle()),
228
+ );
229
+ }
230
+ }
231
+
232
+ // Transform arrows
233
+ const angle = getScaledAngle(this);
234
+ const angleForArrow = [360 - angle, (540 - angle) % 360];
235
+ _.each(
236
+ this._arrows,
237
+ function (arrow, i) {
238
+ arrow.toCoordAtAngle(this.coord(i), angleForArrow[i]);
239
+ },
240
+ this,
241
+ );
242
+ },
243
+
244
+ highlight: function (state: $FlowFixMe, prevState: $FlowFixMe) {
245
+ // TODO(jack): Figure out a way to highlight the points attached to
246
+ // the line. Maybe this means an additional isHovering: []
247
+ // function to state of movable/movablepoint to define [additional?]
248
+ // times it should be highlighted
249
+ if (state.isHovering && !prevState.isHovering) {
250
+ state.visibleShape.animate(state.highlightStyle, 50);
251
+ } else if (!state.isHovering && prevState.isHovering) {
252
+ state.visibleShape.animate(state.normalStyle, 50);
253
+ }
254
+ },
255
+ };
256
+
257
+ // $FlowFixMe[prop-missing]
258
+ draw.standard = [draw.basic, draw.arrows, draw.highlight];
259
+
260
+ const remove = {
261
+ basic: function () {
262
+ if (this.state.visibleShape) {
263
+ this.state.visibleShape.remove();
264
+ }
265
+ },
266
+
267
+ arrows: function () {
268
+ if (this._arrows != null) {
269
+ _.invoke(this._arrows, "remove");
270
+ }
271
+ this._arrows = null;
272
+ },
273
+ };
274
+
275
+ // $FlowFixMe[prop-missing]
276
+ remove.standard = [remove.basic, remove.arrows];
277
+
278
+ const constraints = {
279
+ fixed: function (): () => boolean {
280
+ return function () {
281
+ return false;
282
+ };
283
+ },
284
+
285
+ snap: function (snap: $FlowFixMe): (Coord, Coord) => $FlowFixMe {
286
+ return function (coord: Coord, prevCoord: Coord) {
287
+ if (snap === null) {
288
+ return true;
289
+ }
290
+ let delta = kvector.subtract(coord, prevCoord);
291
+ snap = snap || this.graphie.snap;
292
+ delta = kpoint.roundTo(delta, snap);
293
+ return kvector.add(prevCoord, delta);
294
+ };
295
+ },
296
+
297
+ bound: function (
298
+ range: $FlowFixMe,
299
+ snap: $FlowFixMe,
300
+ paddingPx: number,
301
+ ): ($FlowFixMe, $FlowFixMe) => $FlowFixMe {
302
+ if (paddingPx === undefined) {
303
+ if (range === undefined) {
304
+ paddingPx = 10;
305
+ } else {
306
+ paddingPx = 0;
307
+ }
308
+ }
309
+ return function (coord: Coord, prevCoord: Coord) {
310
+ const graphie = this.graphie;
311
+ const delta = kvector.subtract(coord, prevCoord);
312
+ range = range || graphie.range;
313
+ // A null snap means no snap; an undefined snap means
314
+ // default to graphie's
315
+ if (snap === undefined) {
316
+ snap = graphie.snap;
317
+ }
318
+
319
+ // Calculate the bounds for both points
320
+ let absoluteLower = graphie.unscalePoint([
321
+ paddingPx,
322
+ graphie.ypixels - paddingPx,
323
+ ]);
324
+ let absoluteUpper = graphie.unscalePoint([
325
+ graphie.xpixels - paddingPx,
326
+ paddingPx,
327
+ ]);
328
+ if (snap) {
329
+ absoluteLower = kpoint.ceilTo(absoluteLower, snap);
330
+ absoluteUpper = kpoint.floorTo(absoluteUpper, snap);
331
+ }
332
+
333
+ // Calculate the bounds for the delta.
334
+ const deltaBounds = _.map(
335
+ this.coords(),
336
+ function (coord: Coord, i: number) {
337
+ const max = kvector.subtract(absoluteUpper, coord);
338
+ const min = kvector.subtract(absoluteLower, coord);
339
+ return [min, max];
340
+ },
341
+ );
342
+
343
+ // bound the delta by the calculated bounds
344
+ const boundedDelta = _.reduce(
345
+ deltaBounds,
346
+ function (delta, bound) {
347
+ const lower = bound[0];
348
+ const upper = bound[1];
349
+ const deltaX = Math.max(
350
+ lower[0],
351
+ Math.min(upper[0], delta[0]),
352
+ );
353
+ const deltaY = Math.max(
354
+ lower[1],
355
+ Math.min(upper[1], delta[1]),
356
+ );
357
+ return [deltaX, deltaY];
358
+ },
359
+ delta,
360
+ );
361
+
362
+ return kvector.add(prevCoord, boundedDelta);
363
+ };
364
+ },
365
+ };
366
+
367
+ // $FlowFixMe[prop-missing]
368
+ constraints.standard = null;
369
+
370
+ const onMove = {
371
+ updatePoints: function (coord: Coord, prevCoord: Coord) {
372
+ const actualDelta = kvector.subtract(coord, prevCoord);
373
+ _.each(this.state.points, function (point) {
374
+ point.setCoord(kvector.add(point.coord(), actualDelta));
375
+ });
376
+ },
377
+ };
378
+
379
+ // $FlowFixMe[prop-missing]
380
+ onMove.standard = null;
381
+
382
+ export default {
383
+ add: add,
384
+ modify: modify,
385
+ draw: draw,
386
+ remove: remove,
387
+
388
+ onMoveStart: {standard: null},
389
+ constraints: constraints,
390
+ onMove: onMove,
391
+ onMoveEnd: {standard: null},
392
+ };