@doenet/doenetml 0.6.0-alpha1

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 (549) hide show
  1. package/.prettierrc +3 -0
  2. package/LICENSE +661 -0
  3. package/README.md +146 -0
  4. package/cypress/e2e/ActivityViewer/activityVariants.cy.js +1770 -0
  5. package/cypress/e2e/ActivityViewer/compiledActivity.cy.js +83 -0
  6. package/cypress/e2e/ActivityViewer/relationshipsAmongPages.cy.js +697 -0
  7. package/cypress/e2e/answerValidation/errorinnumbers.cy.js +2125 -0
  8. package/cypress/e2e/answerValidation/factoring.cy.js +1945 -0
  9. package/cypress/e2e/answerValidation/factoringOldAlgorithm.cy.js +892 -0
  10. package/cypress/e2e/answerValidation/functionanswers.cy.js +314 -0
  11. package/cypress/e2e/answerValidation/matchingpatterns.cy.js +287 -0
  12. package/cypress/e2e/answerValidation/matchpartial.cy.js +6711 -0
  13. package/cypress/e2e/answerValidation/pointlocation.cy.js +3989 -0
  14. package/cypress/e2e/answerValidation/symbolicequality.cy.js +1893 -0
  15. package/cypress/e2e/answerValidation/videoProgress.cy.js +210 -0
  16. package/cypress/e2e/assignNames/basiccopy.cy.js +2376 -0
  17. package/cypress/e2e/assignNames/collections.cy.js +9247 -0
  18. package/cypress/e2e/assignNames/selects.cy.js +105 -0
  19. package/cypress/e2e/assignNames/sequences.cy.js +1964 -0
  20. package/cypress/e2e/baseComponent/basecomponentproperties.cy.js +999 -0
  21. package/cypress/e2e/baseComponent/doenetMLtext.cy.js +427 -0
  22. package/cypress/e2e/chemistry/atom.cy.js +201 -0
  23. package/cypress/e2e/chemistry/ion.cy.js +608 -0
  24. package/cypress/e2e/chemistry/ioniccompound.cy.js +133 -0
  25. package/cypress/e2e/dynamicalsystem/cobwebpolyline.cy.js +2653 -0
  26. package/cypress/e2e/dynamicalsystem/equilibriumcurve.cy.js +311 -0
  27. package/cypress/e2e/dynamicalsystem/equilibriumline.cy.js +279 -0
  28. package/cypress/e2e/dynamicalsystem/equilibriumpoint.cy.js +283 -0
  29. package/cypress/e2e/dynamicalsystem/odesystem.cy.js +1834 -0
  30. package/cypress/e2e/equality/mathexpressions.cy.js +948 -0
  31. package/cypress/e2e/graphing/graphreferences.cy.js +978 -0
  32. package/cypress/e2e/graphing/graphreferences2.cy.js +615 -0
  33. package/cypress/e2e/linearAlgebra/eigenDecomposition.cy.js +401 -0
  34. package/cypress/e2e/tagSpecific/angle.cy.js +3898 -0
  35. package/cypress/e2e/tagSpecific/animatefromsequence.cy.js +2306 -0
  36. package/cypress/e2e/tagSpecific/answer.cy.js +31647 -0
  37. package/cypress/e2e/tagSpecific/bestfitline.cy.js +612 -0
  38. package/cypress/e2e/tagSpecific/blockquote.cy.js +30 -0
  39. package/cypress/e2e/tagSpecific/boolean.cy.js +742 -0
  40. package/cypress/e2e/tagSpecific/booleaninput.cy.js +1283 -0
  41. package/cypress/e2e/tagSpecific/booleanlist.cy.js +588 -0
  42. package/cypress/e2e/tagSpecific/booleanoperators.cy.js +596 -0
  43. package/cypress/e2e/tagSpecific/booleanoperatorsonmath.cy.js +498 -0
  44. package/cypress/e2e/tagSpecific/callaction.cy.js +2835 -0
  45. package/cypress/e2e/tagSpecific/choiceinput.cy.js +3205 -0
  46. package/cypress/e2e/tagSpecific/circle.cy.js +22036 -0
  47. package/cypress/e2e/tagSpecific/codeeditor.cy.js +1995 -0
  48. package/cypress/e2e/tagSpecific/collect.cy.js +5035 -0
  49. package/cypress/e2e/tagSpecific/componentsize.cy.js +502 -0
  50. package/cypress/e2e/tagSpecific/conditionalcontent.cy.js +3495 -0
  51. package/cypress/e2e/tagSpecific/contentBrowser.cy.js +335 -0
  52. package/cypress/e2e/tagSpecific/contentpicker.cy.js +261 -0
  53. package/cypress/e2e/tagSpecific/copy.cy.js +12627 -0
  54. package/cypress/e2e/tagSpecific/copy2.cy.js +5698 -0
  55. package/cypress/e2e/tagSpecific/curve.bezier.cy.js +12440 -0
  56. package/cypress/e2e/tagSpecific/curve.cy.js +1716 -0
  57. package/cypress/e2e/tagSpecific/curve.function.cy.js +1471 -0
  58. package/cypress/e2e/tagSpecific/curve.parametrized.cy.js +920 -0
  59. package/cypress/e2e/tagSpecific/document.cy.js +234 -0
  60. package/cypress/e2e/tagSpecific/endpoint.cy.js +197 -0
  61. package/cypress/e2e/tagSpecific/evaluate.cy.js +8895 -0
  62. package/cypress/e2e/tagSpecific/extract.cy.js +2282 -0
  63. package/cypress/e2e/tagSpecific/feedback.cy.js +2941 -0
  64. package/cypress/e2e/tagSpecific/function.cy.js +9450 -0
  65. package/cypress/e2e/tagSpecific/functioniterates.cy.js +1178 -0
  66. package/cypress/e2e/tagSpecific/functionoperators.cy.js +4047 -0
  67. package/cypress/e2e/tagSpecific/graph.cy.js +2491 -0
  68. package/cypress/e2e/tagSpecific/group.cy.js +683 -0
  69. package/cypress/e2e/tagSpecific/hint.cy.js +204 -0
  70. package/cypress/e2e/tagSpecific/image.cy.js +770 -0
  71. package/cypress/e2e/tagSpecific/integer.cy.js +206 -0
  72. package/cypress/e2e/tagSpecific/label.cy.js +800 -0
  73. package/cypress/e2e/tagSpecific/legend.cy.js +1001 -0
  74. package/cypress/e2e/tagSpecific/line.cy.js +12167 -0
  75. package/cypress/e2e/tagSpecific/linesegment.cy.js +4749 -0
  76. package/cypress/e2e/tagSpecific/lorem.cy.js +289 -0
  77. package/cypress/e2e/tagSpecific/map.cy.js +4476 -0
  78. package/cypress/e2e/tagSpecific/matchespattern.cy.js +693 -0
  79. package/cypress/e2e/tagSpecific/math.cy.js +10990 -0
  80. package/cypress/e2e/tagSpecific/mathdisplay.cy.js +2689 -0
  81. package/cypress/e2e/tagSpecific/mathinput.cy.js +15628 -0
  82. package/cypress/e2e/tagSpecific/mathinputgraph.cy.js +566 -0
  83. package/cypress/e2e/tagSpecific/mathlist.cy.js +4073 -0
  84. package/cypress/e2e/tagSpecific/mathoperators.cy.js +13851 -0
  85. package/cypress/e2e/tagSpecific/matrix.cy.js +8825 -0
  86. package/cypress/e2e/tagSpecific/matrixinput.cy.js +16277 -0
  87. package/cypress/e2e/tagSpecific/module.cy.js +1771 -0
  88. package/cypress/e2e/tagSpecific/number.cy.js +2221 -0
  89. package/cypress/e2e/tagSpecific/numberlist.cy.js +1285 -0
  90. package/cypress/e2e/tagSpecific/p.cy.js +72 -0
  91. package/cypress/e2e/tagSpecific/paginator.cy.js +2983 -0
  92. package/cypress/e2e/tagSpecific/parabola.cy.js +14331 -0
  93. package/cypress/e2e/tagSpecific/paragraphmarkup.cy.js +104 -0
  94. package/cypress/e2e/tagSpecific/periodicset.cy.js +1439 -0
  95. package/cypress/e2e/tagSpecific/piecewisefunction.cy.js +1055 -0
  96. package/cypress/e2e/tagSpecific/pluralize.cy.js +274 -0
  97. package/cypress/e2e/tagSpecific/point.cy.js +8895 -0
  98. package/cypress/e2e/tagSpecific/point2.cy.js +10259 -0
  99. package/cypress/e2e/tagSpecific/polygon.cy.js +5039 -0
  100. package/cypress/e2e/tagSpecific/polyline.cy.js +4704 -0
  101. package/cypress/e2e/tagSpecific/problem.cy.js +2768 -0
  102. package/cypress/e2e/tagSpecific/ray.cy.js +10770 -0
  103. package/cypress/e2e/tagSpecific/rectangle.cy.js +2143 -0
  104. package/cypress/e2e/tagSpecific/ref.cy.js +420 -0
  105. package/cypress/e2e/tagSpecific/regularPolygon.cy.js +1006 -0
  106. package/cypress/e2e/tagSpecific/regularPolygon2.cy.js +100 -0
  107. package/cypress/e2e/tagSpecific/regularPolygon3.cy.js +777 -0
  108. package/cypress/e2e/tagSpecific/samplerandomnumbers.cy.js +3619 -0
  109. package/cypress/e2e/tagSpecific/sectioning.cy.js +3530 -0
  110. package/cypress/e2e/tagSpecific/select.cy.js +5376 -0
  111. package/cypress/e2e/tagSpecific/selectfromsequence.cy.js +3846 -0
  112. package/cypress/e2e/tagSpecific/selectrandomnumbers.cy.js +2914 -0
  113. package/cypress/e2e/tagSpecific/sequence.cy.js +2093 -0
  114. package/cypress/e2e/tagSpecific/shuffle.cy.js +490 -0
  115. package/cypress/e2e/tagSpecific/sidebyside.cy.js +8057 -0
  116. package/cypress/e2e/tagSpecific/singlecharactercomponents.cy.js +72 -0
  117. package/cypress/e2e/tagSpecific/slider.cy.js +914 -0
  118. package/cypress/e2e/tagSpecific/solution.cy.js +109 -0
  119. package/cypress/e2e/tagSpecific/solveequations.cy.js +1026 -0
  120. package/cypress/e2e/tagSpecific/sort.cy.js +1685 -0
  121. package/cypress/e2e/tagSpecific/spreadsheet.cy.js +5971 -0
  122. package/cypress/e2e/tagSpecific/subsetofreals.cy.js +2725 -0
  123. package/cypress/e2e/tagSpecific/substitute.cy.js +2646 -0
  124. package/cypress/e2e/tagSpecific/tabular.cy.js +36 -0
  125. package/cypress/e2e/tagSpecific/text.cy.js +975 -0
  126. package/cypress/e2e/tagSpecific/textinput.cy.js +2177 -0
  127. package/cypress/e2e/tagSpecific/textlist.cy.js +369 -0
  128. package/cypress/e2e/tagSpecific/triangle.cy.js +1936 -0
  129. package/cypress/e2e/tagSpecific/triggerset.cy.js +2023 -0
  130. package/cypress/e2e/tagSpecific/updatevalue.cy.js +3288 -0
  131. package/cypress/e2e/tagSpecific/vector.cy.js +20183 -0
  132. package/cypress/e2e/tagSpecific/video.cy.js +612 -0
  133. package/cypress/e2e/tagSpecific/when.cy.js +202 -0
  134. package/cypress/e2e/variants/specifysinglevariant.cy.js +6726 -0
  135. package/cypress/e2e/variants/uniquevariants.cy.js +4846 -0
  136. package/cypress/fixtures/example.json +5 -0
  137. package/cypress/support/commands.js +32 -0
  138. package/cypress/support/e2e.js +31 -0
  139. package/cypress.config.js +18 -0
  140. package/docs/codeSnippet.jsx +11 -0
  141. package/docs/index.html +133 -0
  142. package/docs/index.jsx +138 -0
  143. package/docs/prism.css +3 -0
  144. package/index.html +14 -0
  145. package/index.js +21 -0
  146. package/media/answer_example.png +0 -0
  147. package/media/graph_example.png +0 -0
  148. package/media/graph_markup_example.png +0 -0
  149. package/package.json +83 -0
  150. package/public/favicon.ico +0 -0
  151. package/public/fonts/files/open-sans-v18-latin-700.woff +0 -0
  152. package/public/fonts/files/open-sans-v18-latin-700.woff2 +0 -0
  153. package/public/fonts/files/open-sans-v18-latin-700italic.woff +0 -0
  154. package/public/fonts/files/open-sans-v18-latin-700italic.woff2 +0 -0
  155. package/public/fonts/files/open-sans-v18-latin-italic.woff +0 -0
  156. package/public/fonts/files/open-sans-v18-latin-italic.woff2 +0 -0
  157. package/public/fonts/files/open-sans-v18-latin-light-italic.woff +0 -0
  158. package/public/fonts/files/open-sans-v18-latin-light-italic.woff2 +0 -0
  159. package/public/fonts/files/open-sans-v18-latin-light.woff +0 -0
  160. package/public/fonts/files/open-sans-v18-latin-light.woff2 +0 -0
  161. package/public/fonts/files/open-sans-v18-latin-regular.woff +0 -0
  162. package/public/fonts/files/open-sans-v18-latin-regular.woff2 +0 -0
  163. package/src/Core/ComponentTypes.js +426 -0
  164. package/src/Core/Core.js +11852 -0
  165. package/src/Core/CoreWorker.js +127 -0
  166. package/src/Core/Dependencies.js +8226 -0
  167. package/src/Core/Numerics.js +473 -0
  168. package/src/Core/ParameterStack.js +36 -0
  169. package/src/Core/ReadOnlyProxyHandler.js +41 -0
  170. package/src/Core/StateProxyHandler.js +88 -0
  171. package/src/Core/components/Aliases.js +67 -0
  172. package/src/Core/components/Angle.js +758 -0
  173. package/src/Core/components/AnimateFromSequence.js +922 -0
  174. package/src/Core/components/Answer.js +2087 -0
  175. package/src/Core/components/AsList.js +83 -0
  176. package/src/Core/components/AttractTo.js +245 -0
  177. package/src/Core/components/AttractToAngles.js +262 -0
  178. package/src/Core/components/AttractToConstraint.js +104 -0
  179. package/src/Core/components/AttractToGrid.js +315 -0
  180. package/src/Core/components/Award.js +906 -0
  181. package/src/Core/components/BestFitLine.js +318 -0
  182. package/src/Core/components/BezierControls.js +719 -0
  183. package/src/Core/components/BlockQuote.js +35 -0
  184. package/src/Core/components/Boolean.js +500 -0
  185. package/src/Core/components/BooleanInput.js +330 -0
  186. package/src/Core/components/BooleanList.js +396 -0
  187. package/src/Core/components/BooleanOperators.js +35 -0
  188. package/src/Core/components/BooleanOperatorsOfMath.js +148 -0
  189. package/src/Core/components/CallAction.js +261 -0
  190. package/src/Core/components/Caption.js +73 -0
  191. package/src/Core/components/Case.js +56 -0
  192. package/src/Core/components/Cell.js +439 -0
  193. package/src/Core/components/CellBlock.js +64 -0
  194. package/src/Core/components/Chart.js +795 -0
  195. package/src/Core/components/Choice.js +266 -0
  196. package/src/Core/components/ChoiceInput.js +1407 -0
  197. package/src/Core/components/Circle.js +2884 -0
  198. package/src/Core/components/CodeEditor.js +647 -0
  199. package/src/Core/components/CodeViewer.js +294 -0
  200. package/src/Core/components/CollaborateGroupSetup.js +46 -0
  201. package/src/Core/components/CollaborateGroups.js +119 -0
  202. package/src/Core/components/Collect.js +850 -0
  203. package/src/Core/components/Column.js +608 -0
  204. package/src/Core/components/ConditionalContent.js +468 -0
  205. package/src/Core/components/ConsiderAsResponses.js +49 -0
  206. package/src/Core/components/ConstrainTo.js +161 -0
  207. package/src/Core/components/ConstrainToAngles.js +244 -0
  208. package/src/Core/components/ConstrainToGraph.js +142 -0
  209. package/src/Core/components/ConstrainToGrid.js +175 -0
  210. package/src/Core/components/ConstraintUnion.js +119 -0
  211. package/src/Core/components/Constraints.js +497 -0
  212. package/src/Core/components/ContentBrowser.js +441 -0
  213. package/src/Core/components/ContentPicker.js +263 -0
  214. package/src/Core/components/ControlVectors.js +25 -0
  215. package/src/Core/components/Coords.js +63 -0
  216. package/src/Core/components/Copy.js +3412 -0
  217. package/src/Core/components/Curve.js +4130 -0
  218. package/src/Core/components/CustomAttribute.js +175 -0
  219. package/src/Core/components/DataFrame.js +357 -0
  220. package/src/Core/components/DiscreteSimulationResultList.js +342 -0
  221. package/src/Core/components/DiscreteSimulationResultPolyline.js +581 -0
  222. package/src/Core/components/Divisions.js +55 -0
  223. package/src/Core/components/Document.js +888 -0
  224. package/src/Core/components/Embed.js +65 -0
  225. package/src/Core/components/Endpoint.js +62 -0
  226. package/src/Core/components/Evaluate.js +321 -0
  227. package/src/Core/components/Extract.js +656 -0
  228. package/src/Core/components/Extrema.js +556 -0
  229. package/src/Core/components/Feedback.js +200 -0
  230. package/src/Core/components/FeedbackDefinitions.js +97 -0
  231. package/src/Core/components/Figure.js +148 -0
  232. package/src/Core/components/Footnote.js +73 -0
  233. package/src/Core/components/Function.js +5344 -0
  234. package/src/Core/components/FunctionIterates.js +306 -0
  235. package/src/Core/components/FunctionOperators.js +702 -0
  236. package/src/Core/components/Graph.js +1679 -0
  237. package/src/Core/components/Group.js +7 -0
  238. package/src/Core/components/HasSameFactoring.js +407 -0
  239. package/src/Core/components/Hint.js +241 -0
  240. package/src/Core/components/Image.js +524 -0
  241. package/src/Core/components/Indexing.js +79 -0
  242. package/src/Core/components/IntComma.js +64 -0
  243. package/src/Core/components/Integer.js +81 -0
  244. package/src/Core/components/Intersection.js +328 -0
  245. package/src/Core/components/Interval.js +29 -0
  246. package/src/Core/components/Label.js +492 -0
  247. package/src/Core/components/Latex.js +104 -0
  248. package/src/Core/components/Legend.js +329 -0
  249. package/src/Core/components/Line.js +2040 -0
  250. package/src/Core/components/LineSegment.js +882 -0
  251. package/src/Core/components/Lists.js +180 -0
  252. package/src/Core/components/Lorem.js +249 -0
  253. package/src/Core/components/MMeMen.js +377 -0
  254. package/src/Core/components/Map.js +873 -0
  255. package/src/Core/components/Markers.js +101 -0
  256. package/src/Core/components/MatchesPattern.js +339 -0
  257. package/src/Core/components/Math.js +2552 -0
  258. package/src/Core/components/MathInput.js +948 -0
  259. package/src/Core/components/MathList.js +828 -0
  260. package/src/Core/components/MathOperators.js +1286 -0
  261. package/src/Core/components/Matrix.js +497 -0
  262. package/src/Core/components/MatrixInput.js +3157 -0
  263. package/src/Core/components/MdMdnMrow.js +394 -0
  264. package/src/Core/components/Module.js +16 -0
  265. package/src/Core/components/Number.js +1031 -0
  266. package/src/Core/components/NumberList.js +550 -0
  267. package/src/Core/components/Option.js +24 -0
  268. package/src/Core/components/P.js +71 -0
  269. package/src/Core/components/Paginator.js +338 -0
  270. package/src/Core/components/Panel.js +126 -0
  271. package/src/Core/components/Parabola.js +1561 -0
  272. package/src/Core/components/ParagraphMarkup.js +59 -0
  273. package/src/Core/components/Pegboard.js +43 -0
  274. package/src/Core/components/PeriodicSet.js +291 -0
  275. package/src/Core/components/PiecewiseFunction.js +832 -0
  276. package/src/Core/components/Pluralize.js +198 -0
  277. package/src/Core/components/Point.js +1295 -0
  278. package/src/Core/components/Polygon.js +408 -0
  279. package/src/Core/components/Polyline.js +841 -0
  280. package/src/Core/components/RandomizedTextList.js +225 -0
  281. package/src/Core/components/Ray.js +1737 -0
  282. package/src/Core/components/Rectangle.js +1535 -0
  283. package/src/Core/components/Ref.js +350 -0
  284. package/src/Core/components/RegionBetweenCurveXAxis.js +124 -0
  285. package/src/Core/components/RegionHalfPlane.js +107 -0
  286. package/src/Core/components/RegularPolygon.js +2118 -0
  287. package/src/Core/components/RenderDoenetML.js +181 -0
  288. package/src/Core/components/Row.js +780 -0
  289. package/src/Core/components/SampleRandomNumbers.js +653 -0
  290. package/src/Core/components/Sectioning.js +303 -0
  291. package/src/Core/components/Select.js +947 -0
  292. package/src/Core/components/SelectFromSequence.js +1242 -0
  293. package/src/Core/components/SelectRandomNumbers.js +225 -0
  294. package/src/Core/components/Sequence.js +444 -0
  295. package/src/Core/components/Setup.js +53 -0
  296. package/src/Core/components/Shuffle.js +470 -0
  297. package/src/Core/components/SideBySide.js +2130 -0
  298. package/src/Core/components/SingleCharacterComponents.js +41 -0
  299. package/src/Core/components/Slider.js +819 -0
  300. package/src/Core/components/SolutionContainer.js +67 -0
  301. package/src/Core/components/Solutions.js +334 -0
  302. package/src/Core/components/SolveEquations.js +568 -0
  303. package/src/Core/components/Sort.js +398 -0
  304. package/src/Core/components/Sources.js +108 -0
  305. package/src/Core/components/Split.js +205 -0
  306. package/src/Core/components/Spreadsheet.js +1507 -0
  307. package/src/Core/components/StyleDefinitions.js +111 -0
  308. package/src/Core/components/SubsetOfReals.js +348 -0
  309. package/src/Core/components/SubsetOfRealsInput.js +1474 -0
  310. package/src/Core/components/Substitute.js +496 -0
  311. package/src/Core/components/SummaryStatistics.js +652 -0
  312. package/src/Core/components/Table.js +145 -0
  313. package/src/Core/components/Tabular.js +384 -0
  314. package/src/Core/components/Template.js +360 -0
  315. package/src/Core/components/Text.js +341 -0
  316. package/src/Core/components/TextInput.js +566 -0
  317. package/src/Core/components/TextList.js +442 -0
  318. package/src/Core/components/TextListFromString.js +137 -0
  319. package/src/Core/components/TextOperatorsOfMath.js +21 -0
  320. package/src/Core/components/Triangle.js +280 -0
  321. package/src/Core/components/TriggerSet.js +189 -0
  322. package/src/Core/components/TupleList.js +43 -0
  323. package/src/Core/components/UpdateValue.js +435 -0
  324. package/src/Core/components/VariantControl.js +36 -0
  325. package/src/Core/components/Vector.js +2478 -0
  326. package/src/Core/components/Verbatim.js +125 -0
  327. package/src/Core/components/Video.js +673 -0
  328. package/src/Core/components/When.js +198 -0
  329. package/src/Core/components/abstract/AngleListComponent.js +140 -0
  330. package/src/Core/components/abstract/BaseComponent.js +1496 -0
  331. package/src/Core/components/abstract/BlockComponent.js +5 -0
  332. package/src/Core/components/abstract/BooleanBaseOperator.js +88 -0
  333. package/src/Core/components/abstract/BooleanBaseOperatorOfMath.js +100 -0
  334. package/src/Core/components/abstract/BooleanBaseOperatorOneInput.js +44 -0
  335. package/src/Core/components/abstract/ComponentSize.js +789 -0
  336. package/src/Core/components/abstract/ComponentWithSelectableType.js +537 -0
  337. package/src/Core/components/abstract/CompositeComponent.js +142 -0
  338. package/src/Core/components/abstract/ConstraintComponent.js +19 -0
  339. package/src/Core/components/abstract/FunctionBaseOperator.js +680 -0
  340. package/src/Core/components/abstract/GraphicalComponent.js +56 -0
  341. package/src/Core/components/abstract/InlineComponent.js +5 -0
  342. package/src/Core/components/abstract/InlineRenderInlineChildren.js +63 -0
  343. package/src/Core/components/abstract/Input.js +192 -0
  344. package/src/Core/components/abstract/IntervalListComponent.js +218 -0
  345. package/src/Core/components/abstract/LineListComponent.js +114 -0
  346. package/src/Core/components/abstract/MathBaseOperator.js +631 -0
  347. package/src/Core/components/abstract/MathBaseOperatorOneInput.js +112 -0
  348. package/src/Core/components/abstract/PointListComponent.js +238 -0
  349. package/src/Core/components/abstract/SectioningComponent.js +1262 -0
  350. package/src/Core/components/abstract/SingleCharacterInline.js +23 -0
  351. package/src/Core/components/abstract/TextBaseOperatorOfMath.js +47 -0
  352. package/src/Core/components/abstract/TextOrInline.js +66 -0
  353. package/src/Core/components/abstract/VariableName.js +31 -0
  354. package/src/Core/components/abstract/VariableNameList.js +83 -0
  355. package/src/Core/components/abstract/VectorListComponent.js +235 -0
  356. package/src/Core/components/chemistry/Atom.js +910 -0
  357. package/src/Core/components/chemistry/ElectronConfiguration.js +36 -0
  358. package/src/Core/components/chemistry/Ion.js +684 -0
  359. package/src/Core/components/chemistry/IonicCompound.js +189 -0
  360. package/src/Core/components/chemistry/OrbitalDiagram.js +175 -0
  361. package/src/Core/components/chemistry/OrbitalDiagramInput.js +753 -0
  362. package/src/Core/components/chemistry/index.js +6 -0
  363. package/src/Core/components/commonsugar/breakstrings.js +627 -0
  364. package/src/Core/components/commonsugar/lists.js +177 -0
  365. package/src/Core/components/dynamicalSystems/CobwebPolyline.js +913 -0
  366. package/src/Core/components/dynamicalSystems/EquilibriumCurve.js +95 -0
  367. package/src/Core/components/dynamicalSystems/EquilibriumLine.js +93 -0
  368. package/src/Core/components/dynamicalSystems/EquilibriumPoint.js +93 -0
  369. package/src/Core/components/dynamicalSystems/ODESystem.js +943 -0
  370. package/src/Core/components/dynamicalSystems/index.js +5 -0
  371. package/src/Core/components/linearAlgebra/EigenDecomposition.js +294 -0
  372. package/src/Core/utils/array.js +30 -0
  373. package/src/Core/utils/booleanLogic.js +965 -0
  374. package/src/Core/utils/checkEquality.js +818 -0
  375. package/src/Core/utils/cid.js +29 -0
  376. package/src/Core/utils/componentInfoObjects.js +100 -0
  377. package/src/Core/utils/constraints.js +23 -0
  378. package/src/Core/utils/copy.js +572 -0
  379. package/src/Core/utils/deepFunctions.js +173 -0
  380. package/src/Core/utils/descendants.js +252 -0
  381. package/src/Core/utils/enumeration.js +234 -0
  382. package/src/Core/utils/feedback.js +84 -0
  383. package/src/Core/utils/function.js +1343 -0
  384. package/src/Core/utils/graphical.js +196 -0
  385. package/src/Core/utils/label.js +396 -0
  386. package/src/Core/utils/math.js +1056 -0
  387. package/src/Core/utils/naming.js +45 -0
  388. package/src/Core/utils/periodicSetEquality.js +403 -0
  389. package/src/Core/utils/randomNumbers.js +70 -0
  390. package/src/Core/utils/retrieveMedia.js +98 -0
  391. package/src/Core/utils/retrieveTextFile.js +140 -0
  392. package/src/Core/utils/returnAllPossibleVariants.js +73 -0
  393. package/src/Core/utils/rounding.js +316 -0
  394. package/src/Core/utils/sequence.js +754 -0
  395. package/src/Core/utils/serializedStateProcessing.js +4049 -0
  396. package/src/Core/utils/size.js +22 -0
  397. package/src/Core/utils/stateVariables.js +138 -0
  398. package/src/Core/utils/style.js +535 -0
  399. package/src/Core/utils/subset-of-reals.js +796 -0
  400. package/src/Core/utils/table.js +41 -0
  401. package/src/Core/utils/text.js +16 -0
  402. package/src/Core/utils/triggering.js +167 -0
  403. package/src/Core/utils/variants.js +477 -0
  404. package/src/DoenetML.css +308 -0
  405. package/src/DoenetML.jsx +201 -0
  406. package/src/Parser/doenet.grammar +90 -0
  407. package/src/Parser/doenet.js +33 -0
  408. package/src/Parser/doenet.terms.js +20 -0
  409. package/src/Parser/parser.js +266 -0
  410. package/src/Parser/tokens.js +129 -0
  411. package/src/Tools/CodeMirror.jsx +440 -0
  412. package/src/Tools/DarkmodeController.jsx +21 -0
  413. package/src/Tools/Footers/MathInputSelector.jsx +34 -0
  414. package/src/Tools/Footers/VirtualKeyboard.jsx +751 -0
  415. package/src/Tools/cypressTest/CypressTest.jsx +341 -0
  416. package/src/Tools/cypressTest/index.html +102 -0
  417. package/src/Tools/cypressTest/index.jsx +40 -0
  418. package/src/Viewer/ActivityViewer.jsx +1461 -0
  419. package/src/Viewer/PageViewer.jsx +1329 -0
  420. package/src/Viewer/renderers/alert.jsx +17 -0
  421. package/src/Viewer/renderers/angle.jsx +209 -0
  422. package/src/Viewer/renderers/answer.jsx +206 -0
  423. package/src/Viewer/renderers/asList.jsx +25 -0
  424. package/src/Viewer/renderers/blockQuote.jsx +41 -0
  425. package/src/Viewer/renderers/boolean.jsx +17 -0
  426. package/src/Viewer/renderers/booleanInput.css +105 -0
  427. package/src/Viewer/renderers/booleanInput.jsx +636 -0
  428. package/src/Viewer/renderers/button.jsx +369 -0
  429. package/src/Viewer/renderers/c.jsx +17 -0
  430. package/src/Viewer/renderers/callAction.jsx +18 -0
  431. package/src/Viewer/renderers/cell.jsx +59 -0
  432. package/src/Viewer/renderers/chart.jsx +83 -0
  433. package/src/Viewer/renderers/choiceInput.css +223 -0
  434. package/src/Viewer/renderers/choiceInput.jsx +535 -0
  435. package/src/Viewer/renderers/circle.jsx +990 -0
  436. package/src/Viewer/renderers/cobwebPolyline.jsx +442 -0
  437. package/src/Viewer/renderers/codeEditor.jsx +248 -0
  438. package/src/Viewer/renderers/codeViewer.jsx +105 -0
  439. package/src/Viewer/renderers/containerBlock.jsx +41 -0
  440. package/src/Viewer/renderers/containerInline.jsx +17 -0
  441. package/src/Viewer/renderers/contentBrowser.jsx +159 -0
  442. package/src/Viewer/renderers/contentPicker.jsx +160 -0
  443. package/src/Viewer/renderers/curve.jsx +1072 -0
  444. package/src/Viewer/renderers/ellipsis.jsx +17 -0
  445. package/src/Viewer/renderers/em.jsx +17 -0
  446. package/src/Viewer/renderers/embed.jsx +110 -0
  447. package/src/Viewer/renderers/feedback.jsx +74 -0
  448. package/src/Viewer/renderers/figure.jsx +131 -0
  449. package/src/Viewer/renderers/footnote.jsx +52 -0
  450. package/src/Viewer/renderers/graph.jsx +925 -0
  451. package/src/Viewer/renderers/hint.jsx +142 -0
  452. package/src/Viewer/renderers/image.jsx +581 -0
  453. package/src/Viewer/renderers/jsxgraph-distrib/jsxgraphcore.mjs +2 -0
  454. package/src/Viewer/renderers/jsxgraph-distrib/jsxgraphcore.mjs.map +1 -0
  455. package/src/Viewer/renderers/label.jsx +470 -0
  456. package/src/Viewer/renderers/legend.jsx +306 -0
  457. package/src/Viewer/renderers/line.jsx +511 -0
  458. package/src/Viewer/renderers/lineSegment.jsx +754 -0
  459. package/src/Viewer/renderers/list.jsx +111 -0
  460. package/src/Viewer/renderers/lq.jsx +12 -0
  461. package/src/Viewer/renderers/lsq.jsx +12 -0
  462. package/src/Viewer/renderers/math.jsx +582 -0
  463. package/src/Viewer/renderers/mathInput.css +10 -0
  464. package/src/Viewer/renderers/mathInput.jsx +425 -0
  465. package/src/Viewer/renderers/mathInputog.jsx +534 -0
  466. package/src/Viewer/renderers/mathList.jsx +39 -0
  467. package/src/Viewer/renderers/matrixInput.jsx +317 -0
  468. package/src/Viewer/renderers/mdash.jsx +12 -0
  469. package/src/Viewer/renderers/nbsp.jsx +12 -0
  470. package/src/Viewer/renderers/ndash.jsx +12 -0
  471. package/src/Viewer/renderers/number.jsx +454 -0
  472. package/src/Viewer/renderers/numberList.jsx +35 -0
  473. package/src/Viewer/renderers/orbitalDiagram.jsx +247 -0
  474. package/src/Viewer/renderers/orbitalDiagramInput.jsx +450 -0
  475. package/src/Viewer/renderers/p.jsx +38 -0
  476. package/src/Viewer/renderers/paginatorControls.jsx +41 -0
  477. package/src/Viewer/renderers/pegboard.jsx +239 -0
  478. package/src/Viewer/renderers/point.jsx +649 -0
  479. package/src/Viewer/renderers/polygon.jsx +612 -0
  480. package/src/Viewer/renderers/polyline.jsx +608 -0
  481. package/src/Viewer/renderers/pre.jsx +34 -0
  482. package/src/Viewer/renderers/q.jsx +17 -0
  483. package/src/Viewer/renderers/ray.jsx +410 -0
  484. package/src/Viewer/renderers/ref.jsx +149 -0
  485. package/src/Viewer/renderers/regionBetweenCurveXAxis.jsx +182 -0
  486. package/src/Viewer/renderers/renderDoenetML.jsx +56 -0
  487. package/src/Viewer/renderers/row.jsx +31 -0
  488. package/src/Viewer/renderers/rq.jsx +12 -0
  489. package/src/Viewer/renderers/rsq.jsx +12 -0
  490. package/src/Viewer/renderers/section.jsx +427 -0
  491. package/src/Viewer/renderers/sideBySide.jsx +80 -0
  492. package/src/Viewer/renderers/slider.jsx +800 -0
  493. package/src/Viewer/renderers/solution.jsx +134 -0
  494. package/src/Viewer/renderers/spreadsheet.jsx +83 -0
  495. package/src/Viewer/renderers/sq.jsx +17 -0
  496. package/src/Viewer/renderers/styles/global.css +14 -0
  497. package/src/Viewer/renderers/subsetOfRealsInput.jsx +392 -0
  498. package/src/Viewer/renderers/summaryStatistics.jsx +83 -0
  499. package/src/Viewer/renderers/table.jsx +78 -0
  500. package/src/Viewer/renderers/tabular.jsx +58 -0
  501. package/src/Viewer/renderers/tag.jsx +26 -0
  502. package/src/Viewer/renderers/text.jsx +439 -0
  503. package/src/Viewer/renderers/textInput.jsx +774 -0
  504. package/src/Viewer/renderers/textList.jsx +30 -0
  505. package/src/Viewer/renderers/triggerSet.jsx +52 -0
  506. package/src/Viewer/renderers/updateValue.jsx +30 -0
  507. package/src/Viewer/renderers/utils/css.js +13 -0
  508. package/src/Viewer/renderers/utils/graph.js +159 -0
  509. package/src/Viewer/renderers/utils/offGraphIndicators.js +91 -0
  510. package/src/Viewer/renderers/vector.jsx +678 -0
  511. package/src/Viewer/renderers/video.jsx +494 -0
  512. package/src/Viewer/useDoenetRenderer.jsx +128 -0
  513. package/src/main.jsx +16 -0
  514. package/src/media/fonts/files/open-sans-v18-latin-700.woff +0 -0
  515. package/src/media/fonts/files/open-sans-v18-latin-700.woff2 +0 -0
  516. package/src/media/fonts/files/open-sans-v18-latin-700italic.woff +0 -0
  517. package/src/media/fonts/files/open-sans-v18-latin-700italic.woff2 +0 -0
  518. package/src/media/fonts/files/open-sans-v18-latin-italic.woff +0 -0
  519. package/src/media/fonts/files/open-sans-v18-latin-italic.woff2 +0 -0
  520. package/src/media/fonts/files/open-sans-v18-latin-light-italic.woff +0 -0
  521. package/src/media/fonts/files/open-sans-v18-latin-light-italic.woff2 +0 -0
  522. package/src/media/fonts/files/open-sans-v18-latin-light.woff +0 -0
  523. package/src/media/fonts/files/open-sans-v18-latin-light.woff2 +0 -0
  524. package/src/media/fonts/files/open-sans-v18-latin-regular.woff +0 -0
  525. package/src/media/fonts/files/open-sans-v18-latin-regular.woff2 +0 -0
  526. package/src/test/testCode.doenet +26 -0
  527. package/src/test/testViewer.jsx +158 -0
  528. package/src/uiComponents/ActionButton.jsx +157 -0
  529. package/src/uiComponents/ActionButtonGroup.jsx +93 -0
  530. package/src/uiComponents/Button.jsx +160 -0
  531. package/src/uiComponents/ButtonGroup.jsx +56 -0
  532. package/src/uiComponents/ToggleButton.jsx +194 -0
  533. package/src/uiComponents/ToggleButtonGroup.jsx +77 -0
  534. package/src/utils/activityUtils.js +713 -0
  535. package/src/utils/array.js +17 -0
  536. package/src/utils/cid.js +34 -0
  537. package/src/utils/componentInfoObjects.js +89 -0
  538. package/src/utils/deepFunctions.js +165 -0
  539. package/src/utils/enumeration.js +226 -0
  540. package/src/utils/math.js +624 -0
  541. package/src/utils/naming.js +44 -0
  542. package/src/utils/retrieveTextFile.js +156 -0
  543. package/src/utils/returnAllPossibleVariants.js +81 -0
  544. package/src/utils/sequence.js +715 -0
  545. package/src/utils/serialize.js +29 -0
  546. package/src/utils/serializedStateProcessing.js +2587 -0
  547. package/src/utils/subset-of-reals.js +783 -0
  548. package/src/utils/url.js +19 -0
  549. package/vite.config.js +14 -0
@@ -0,0 +1,1474 @@
1
+ import BlockComponent from "./abstract/BlockComponent";
2
+ import me from "math-expressions";
3
+ import subsets, {
4
+ buildSubsetFromMathExpression,
5
+ } from "../utils/subset-of-reals";
6
+
7
+ export default class SubsetOfRealsInput extends BlockComponent {
8
+ constructor(args) {
9
+ super(args);
10
+
11
+ Object.assign(this.actions, {
12
+ addPoint: this.addPoint.bind(this),
13
+ deletePoint: this.deletePoint.bind(this),
14
+ movePoint: this.movePoint.bind(this),
15
+ togglePoint: this.togglePoint.bind(this),
16
+ toggleInterval: this.toggleInterval.bind(this),
17
+ clear: this.clear.bind(this),
18
+ setToR: this.setToR.bind(this),
19
+ recordVisibilityChange: this.recordVisibilityChange.bind(this),
20
+ });
21
+ }
22
+ static componentType = "subsetOfRealsInput";
23
+
24
+ static variableForPlainMacro = "subsetValue";
25
+ static variableForPlainCopy = "subsetValue";
26
+
27
+ static createAttributesObject() {
28
+ let attributes = super.createAttributesObject();
29
+ attributes.xmin = {
30
+ createComponentOfType: "number",
31
+ createStateVariable: "xmin",
32
+ defaultValue: -10,
33
+ public: true,
34
+ forRenderer: true,
35
+ };
36
+ attributes.xmax = {
37
+ createComponentOfType: "number",
38
+ createStateVariable: "xmax",
39
+ defaultValue: 10,
40
+ public: true,
41
+ forRenderer: true,
42
+ };
43
+ attributes.width = {
44
+ createComponentOfType: "_componentSize",
45
+ createStateVariable: "width",
46
+ defaultValue: 800,
47
+ public: true,
48
+ forRenderer: true,
49
+ };
50
+ attributes.height = {
51
+ createComponentOfType: "_componentSize",
52
+ createStateVariable: "height",
53
+ defaultValue: 300,
54
+ public: true,
55
+ forRenderer: true,
56
+ };
57
+ attributes.xlabel = {
58
+ createComponentOfType: "text",
59
+ createStateVariable: "xlabel",
60
+ defaultValue: "",
61
+ public: true,
62
+ forRenderer: true,
63
+ };
64
+ //interval type buttons includeIntervalBasedControls
65
+ //point type buttons includePointBasedControls
66
+
67
+ attributes.dx = {
68
+ createComponentOfType: "number",
69
+ createStateVariable: "dx",
70
+ defaultValue: 0.5,
71
+ public: true,
72
+ };
73
+
74
+ attributes.variable = {
75
+ createComponentOfType: "_variableName",
76
+ createStateVariable: "variable",
77
+ defaultValue: me.fromAst("x"),
78
+ public: true,
79
+ };
80
+ attributes.format = {
81
+ createComponentOfType: "text",
82
+ createStateVariable: "format",
83
+ defaultValue: "text",
84
+ public: true,
85
+ };
86
+ attributes.prefill = {
87
+ createComponentOfType: "text",
88
+ createStateVariable: "prefill",
89
+ defaultValue: "",
90
+ public: true,
91
+ };
92
+
93
+ attributes.bindValueTo = {
94
+ createComponentOfType: "subsetOfReals",
95
+ };
96
+ return attributes;
97
+ }
98
+
99
+ static returnStateVariableDefinitions() {
100
+ let stateVariableDefinitions = super.returnStateVariableDefinitions();
101
+
102
+ stateVariableDefinitions.subsetValue = {
103
+ public: true,
104
+ shadowingInstructions: {
105
+ createComponentOfType: "subsetOfReals",
106
+ },
107
+ hasEssential: true,
108
+ returnDependencies: () => ({
109
+ bindValueTo: {
110
+ dependencyType: "attributeComponent",
111
+ attributeName: "bindValueTo",
112
+ variableNames: ["subsetValue"],
113
+ },
114
+ prefill: {
115
+ dependencyType: "stateVariable",
116
+ variableName: "prefill",
117
+ },
118
+ variable: {
119
+ dependencyType: "stateVariable",
120
+ variableName: "variable",
121
+ },
122
+ format: {
123
+ dependencyType: "stateVariable",
124
+ variableName: "format",
125
+ },
126
+ }),
127
+ definition: function ({ dependencyValues }) {
128
+ if (!dependencyValues.bindValueTo) {
129
+ // TODO: should we round prefill using dx?
130
+ return {
131
+ useEssentialOrDefaultValue: {
132
+ subsetValue: {
133
+ get defaultValue() {
134
+ return parseValueIntoSubset({
135
+ inputString: dependencyValues.prefill,
136
+ format: dependencyValues.format,
137
+ variable: dependencyValues.variable,
138
+ });
139
+ },
140
+ },
141
+ },
142
+ };
143
+ }
144
+
145
+ return {
146
+ setValue: {
147
+ subsetValue: dependencyValues.bindValueTo.stateValues.subsetValue,
148
+ },
149
+ };
150
+ },
151
+ inverseDefinition({ desiredStateVariableValues, dependencyValues }) {
152
+ if (dependencyValues.bindValueTo) {
153
+ return {
154
+ success: true,
155
+ instructions: [
156
+ {
157
+ setDependency: "bindValueTo",
158
+ desiredValue: desiredStateVariableValues.subsetValue,
159
+ variableIndex: 0,
160
+ },
161
+ ],
162
+ };
163
+ }
164
+ // subsetValue is essential; give it the desired value
165
+
166
+ return {
167
+ success: true,
168
+ instructions: [
169
+ {
170
+ setEssentialValue: "subsetValue",
171
+ value: desiredStateVariableValues.subsetValue,
172
+ },
173
+ ],
174
+ };
175
+ },
176
+ };
177
+
178
+ stateVariableDefinitions.pointsFromSubset = {
179
+ additionalStateVariablesDefined: ["intervalsFromSubset"],
180
+ returnDependencies: () => ({
181
+ subsetValue: {
182
+ dependencyType: "stateVariable",
183
+ variableName: "subsetValue",
184
+ },
185
+ }),
186
+ definition({ dependencyValues }) {
187
+ function mergePointsIntervals(result1, result2) {
188
+ let points = [];
189
+ let intervals = [];
190
+
191
+ if (result1.points) {
192
+ points = result1.points;
193
+ }
194
+ if (result1.intervals) {
195
+ intervals = result1.intervals;
196
+ }
197
+
198
+ if (result2.points) {
199
+ let valuesIn1 = points.map((x) => x.value);
200
+
201
+ for (let pt of result2.points) {
202
+ let indIn1 = valuesIn1.indexOf(pt.value);
203
+
204
+ if (indIn1 === -1) {
205
+ points.push(pt);
206
+ } else {
207
+ points[indIn1].inSubset ||= pt.inSubset;
208
+ }
209
+ }
210
+ }
211
+
212
+ if (result2.intervals) {
213
+ intervals.push(...result2.intervals);
214
+ }
215
+
216
+ return { points, intervals };
217
+ }
218
+
219
+ function pointsIntervalsFromSubset(subset) {
220
+ if (subset === null || subset.isEmpty()) {
221
+ return {};
222
+ }
223
+
224
+ if (subset instanceof subsets.Union) {
225
+ let points = [];
226
+ let intervals = [];
227
+ for (let sub2 of subset.subsets) {
228
+ let result = pointsIntervalsFromSubset(sub2);
229
+ ({ points, intervals } = mergePointsIntervals(
230
+ { points, intervals },
231
+ result,
232
+ ));
233
+ }
234
+
235
+ return { points, intervals };
236
+ } else if (subset instanceof subsets.RealLine) {
237
+ return { intervals: [[-Infinity, Infinity]] };
238
+ } else if (subset instanceof subsets.Singleton) {
239
+ return { points: [{ value: subset.element, inSubset: true }] };
240
+ } else if (subset instanceof subsets.OpenInterval) {
241
+ let intervals = [[subset.left, subset.right]];
242
+ let points = [];
243
+ if (Number.isFinite(subset.left)) {
244
+ points.push({ value: subset.left, inSubset: false });
245
+ }
246
+ if (Number.isFinite(subset.right)) {
247
+ points.push({ value: subset.right, inSubset: false });
248
+ }
249
+ return { intervals, points };
250
+ }
251
+
252
+ // shouldn't get here
253
+ return {};
254
+ }
255
+
256
+ let { points, intervals } = pointsIntervalsFromSubset(
257
+ dependencyValues.subsetValue,
258
+ );
259
+
260
+ let pointsFromSubset = points ? points : [];
261
+ let intervalsFromSubset = intervals ? intervals : [];
262
+
263
+ pointsFromSubset.sort((a, b) => a.value - b.value);
264
+ intervalsFromSubset.sort((a, b) => a[0] - b[0]);
265
+
266
+ return { setValue: { pointsFromSubset, intervalsFromSubset } };
267
+ },
268
+ };
269
+
270
+ stateVariableDefinitions.additionalPoints = {
271
+ defaultValue: [],
272
+ hasEssential: true,
273
+ returnDependencies: () => ({}),
274
+ definition() {
275
+ return {
276
+ useEssentialOrDefaultValue: {
277
+ additionalPoints: true,
278
+ },
279
+ };
280
+ },
281
+ inverseDefinition({ desiredStateVariableValues }) {
282
+ if (
283
+ desiredStateVariableValues.additionalPoints.every(Number.isFinite)
284
+ ) {
285
+ return {
286
+ success: true,
287
+ instructions: [
288
+ {
289
+ setEssentialValue: "additionalPoints",
290
+ value: [...desiredStateVariableValues.additionalPoints].sort(
291
+ (a, b) => a - b,
292
+ ),
293
+ },
294
+ ],
295
+ };
296
+ } else {
297
+ return { success: false };
298
+ }
299
+ },
300
+ };
301
+
302
+ stateVariableDefinitions.points = {
303
+ additionalStateVariablesDefined: [
304
+ { variableName: "intervals", forRenderer: true },
305
+ ],
306
+ forRenderer: true,
307
+ returnDependencies: () => ({
308
+ pointsFromSubset: {
309
+ dependencyType: "stateVariable",
310
+ variableName: "pointsFromSubset",
311
+ },
312
+ intervalsFromSubset: {
313
+ dependencyType: "stateVariable",
314
+ variableName: "intervalsFromSubset",
315
+ },
316
+ additionalPoints: {
317
+ dependencyType: "stateVariable",
318
+ variableName: "additionalPoints",
319
+ },
320
+ }),
321
+ definition({ dependencyValues }) {
322
+ let pointsSub = [...dependencyValues.pointsFromSubset];
323
+ let intervalsSub = [...dependencyValues.intervalsFromSubset];
324
+ let additionalPoints = [...dependencyValues.additionalPoints].sort(
325
+ (a, b) => a - b,
326
+ );
327
+
328
+ let points = [];
329
+ let intervals = [];
330
+
331
+ let intervalInd = 0;
332
+
333
+ let nextAdditionalPoint = Infinity;
334
+ let additionalPointInd = 0;
335
+ if (additionalPoints.length > 0) {
336
+ nextAdditionalPoint = additionalPoints[0];
337
+ }
338
+ let nextInterval = intervalsSub[0];
339
+
340
+ let lastIntervalEnd = -Infinity;
341
+
342
+ // append point at Infinity for simplicity
343
+ pointsSub.push({ value: Infinity, inSubset: false });
344
+
345
+ for (let point of pointsSub) {
346
+ let inSubset = false;
347
+ if (nextInterval && nextInterval[0] < point.value) {
348
+ inSubset = true;
349
+ }
350
+
351
+ while (nextAdditionalPoint < point.value) {
352
+ // add extra point. Will be inSubset if inside an interval
353
+
354
+ // skip if point is on top of previous point
355
+ if (nextAdditionalPoint !== lastIntervalEnd) {
356
+ points.push({
357
+ value: nextAdditionalPoint,
358
+ inSubset,
359
+ isAdditional: true,
360
+ additionalPointInd,
361
+ });
362
+
363
+ intervals.push({
364
+ left: lastIntervalEnd,
365
+ right: nextAdditionalPoint,
366
+ inSubset,
367
+ });
368
+
369
+ lastIntervalEnd = nextAdditionalPoint;
370
+ }
371
+
372
+ additionalPointInd++;
373
+ nextAdditionalPoint = additionalPoints[additionalPointInd];
374
+ if (nextAdditionalPoint === undefined) {
375
+ nextAdditionalPoint = Infinity;
376
+ }
377
+ }
378
+
379
+ points.push(point);
380
+
381
+ intervals.push({
382
+ left: lastIntervalEnd,
383
+ right: point.value,
384
+ inSubset,
385
+ });
386
+
387
+ lastIntervalEnd = point.value;
388
+
389
+ if (inSubset) {
390
+ intervalInd++;
391
+ nextInterval = intervalsSub[intervalInd];
392
+ }
393
+ }
394
+
395
+ // delete extra point at infinity
396
+ points = points.slice(0, points.length - 1);
397
+
398
+ return {
399
+ setValue: { points, intervals },
400
+ };
401
+ },
402
+ };
403
+
404
+ return stateVariableDefinitions;
405
+ }
406
+
407
+ async addPoint({
408
+ value,
409
+ actionId,
410
+ sourceInformation = {},
411
+ skipRendererUpdate = false,
412
+ }) {
413
+ let dx = await this.stateValues.dx;
414
+ let roundedValue =
415
+ Math.round(
416
+ Math.max(
417
+ await this.stateValues.xmin,
418
+ Math.min(await this.stateValues.xmax, value),
419
+ ) / dx,
420
+ ) * dx;
421
+
422
+ // add point only if not equal to another point
423
+ // (which could happen due to rounding)
424
+
425
+ let pointsFromSubset = [...(await this.stateValues.pointsFromSubset)];
426
+ let intervalsFromSubset = [...(await this.stateValues.intervalsFromSubset)];
427
+ let additionalPoints = [...(await this.stateValues.additionalPoints)];
428
+
429
+ if (!additionalPoints.includes(roundedValue)) {
430
+ let subsetPointValues = pointsFromSubset.map((x) => x.value);
431
+
432
+ if (!subsetPointValues.includes(roundedValue)) {
433
+ let insideInterval = false;
434
+ for (let interval of intervalsFromSubset) {
435
+ if (interval[0] < roundedValue && interval[1] > roundedValue) {
436
+ insideInterval = true;
437
+ break;
438
+ }
439
+ }
440
+
441
+ // the new point should be in the subset
442
+
443
+ if (insideInterval) {
444
+ // if point is inside an interval, make it an additional point
445
+ additionalPoints.push(roundedValue);
446
+ return await this.coreFunctions.performUpdate({
447
+ updateInstructions: [
448
+ {
449
+ componentName: this.componentName,
450
+ updateType: "updateValue",
451
+ stateVariable: "additionalPoints",
452
+ value: additionalPoints,
453
+ },
454
+ ],
455
+ actionId,
456
+ sourceInformation,
457
+ skipRendererUpdate,
458
+ event: {
459
+ verb: "interacted",
460
+ object: {
461
+ componentName: this.componentName,
462
+ componentType: this.componentType,
463
+ },
464
+ result: {
465
+ addedPoint: roundedValue,
466
+ intervalsFromSubset,
467
+ pointsFromSubset,
468
+ additionalPoints,
469
+ },
470
+ },
471
+ });
472
+ } else {
473
+ // if point is not inside an interval, add a point
474
+ pointsFromSubset.push({
475
+ value: roundedValue,
476
+ inSubset: true,
477
+ });
478
+
479
+ let updateInstructions = await this.createUpdateInstructions({
480
+ intervalsFromSubset,
481
+ pointsFromSubset,
482
+ modifiedAdditionalPoints: false,
483
+ additionalPoints,
484
+ });
485
+
486
+ return await this.coreFunctions.performUpdate({
487
+ updateInstructions,
488
+ actionId,
489
+ sourceInformation,
490
+ skipRendererUpdate,
491
+ event: {
492
+ verb: "interacted",
493
+ object: {
494
+ componentName: this.componentName,
495
+ componentType: this.componentType,
496
+ },
497
+ result: {
498
+ addedPoint: roundedValue,
499
+ intervalsFromSubset,
500
+ pointsFromSubset,
501
+ additionalPoints,
502
+ },
503
+ },
504
+ });
505
+ }
506
+ }
507
+ }
508
+
509
+ this.coreFunctions.resolveAction({ actionId });
510
+ }
511
+
512
+ async deletePoint({
513
+ pointInd,
514
+ actionId,
515
+ sourceInformation = {},
516
+ skipRendererUpdate = false,
517
+ }) {
518
+ let point = await this.stateValues.points[pointInd];
519
+ let additionalPoints = [...(await this.stateValues.additionalPoints)];
520
+ let pointsFromSubset = [...(await this.stateValues.pointsFromSubset)];
521
+ let intervalsFromSubset = [...(await this.stateValues.intervalsFromSubset)];
522
+
523
+ if (point.isAdditional) {
524
+ additionalPoints.splice(point.additionalPointInd, 1);
525
+ return await this.coreFunctions.performUpdate({
526
+ updateInstructions: [
527
+ {
528
+ componentName: this.componentName,
529
+ updateType: "updateValue",
530
+ stateVariable: "additionalPoints",
531
+ value: additionalPoints,
532
+ },
533
+ ],
534
+ actionId,
535
+ sourceInformation,
536
+ skipRendererUpdate,
537
+ event: {
538
+ verb: "interacted",
539
+ object: {
540
+ componentName: this.componentName,
541
+ componentType: this.componentType,
542
+ },
543
+ result: {
544
+ deletedPoint: point.value,
545
+ intervalsFromSubset,
546
+ pointsFromSubset,
547
+ additionalPoints,
548
+ },
549
+ },
550
+ });
551
+ } else {
552
+ // removing a point defining the subset
553
+ // recalculate subset
554
+
555
+ let modifiedAdditionalPoints = false;
556
+
557
+ let pointSubsetInd = pointsFromSubset
558
+ .map((x) => x.value)
559
+ .indexOf(point.value);
560
+
561
+ let leftIntervalInd = intervalsFromSubset
562
+ .map((x) => x[1])
563
+ .indexOf(point.value);
564
+ let rightIntervalInd = intervalsFromSubset
565
+ .map((x) => x[0])
566
+ .indexOf(point.value);
567
+
568
+ if (leftIntervalInd !== -1) {
569
+ if (rightIntervalInd !== -1) {
570
+ // have intervals on both sides of points
571
+ // merge the intervals
572
+ intervalsFromSubset[leftIntervalInd] = [
573
+ intervalsFromSubset[leftIntervalInd][0],
574
+ intervalsFromSubset[rightIntervalInd][1],
575
+ ];
576
+ intervalsFromSubset.splice(rightIntervalInd, 1);
577
+
578
+ pointsFromSubset.splice(pointSubsetInd, 1);
579
+ } else {
580
+ // interval on the left but not on the right
581
+ // remove the interval on the left
582
+
583
+ let leftPoint = (await this.stateValues.points)[pointInd - 1];
584
+ if (leftPoint && leftPoint.isAdditional) {
585
+ // shorten the interval to end at the additional point
586
+ // and turn the additional point to a subset point
587
+ intervalsFromSubset[leftIntervalInd] = [
588
+ intervalsFromSubset[leftIntervalInd][0],
589
+ leftPoint.value,
590
+ ];
591
+
592
+ additionalPoints.splice(point.additionalPointInd, 1);
593
+ modifiedAdditionalPoints = true;
594
+
595
+ pointsFromSubset.splice(pointSubsetInd, 1, leftPoint);
596
+ } else {
597
+ // since bordered by a subset point (or -Infinity)
598
+ // just remove the interval and the point
599
+ intervalsFromSubset.splice(leftIntervalInd, 1);
600
+ pointsFromSubset.splice(pointSubsetInd, 1);
601
+
602
+ if (leftPoint && !leftPoint.inSubset) {
603
+ // if left point isn't in subset
604
+ // and don't have an interval to its left
605
+ // it is not longer part of the subset
606
+ let leftLeftIntervalInd = intervalsFromSubset
607
+ .map((x) => x[1])
608
+ .indexOf(leftPoint.value);
609
+ if (leftLeftIntervalInd === -1) {
610
+ // so that point doesn't disappear, add it to additionalPoints
611
+ additionalPoints.push(leftPoint.value);
612
+ modifiedAdditionalPoints = true;
613
+ }
614
+ }
615
+ }
616
+ }
617
+ } else {
618
+ // don't have left interval
619
+
620
+ if (rightIntervalInd !== -1) {
621
+ // interval on the right but not on the left
622
+ // remove the interval on the right
623
+
624
+ let rightPoint = (await this.stateValues.points)[pointInd + 1];
625
+ if (rightPoint && rightPoint.isAdditional) {
626
+ // shorten the interval to end at the additional point
627
+ // and turn the additional point to a subset point
628
+ intervalsFromSubset[rightIntervalInd] = [
629
+ rightPoint.value,
630
+ intervalsFromSubset[rightIntervalInd][1],
631
+ ];
632
+
633
+ additionalPoints.splice(point.additionalPointInd, 1);
634
+ modifiedAdditionalPoints = true;
635
+
636
+ pointsFromSubset.splice(pointSubsetInd, 1, rightPoint);
637
+ } else {
638
+ // since bordered by a subset point
639
+ // just remove the interval and the point
640
+ intervalsFromSubset.splice(rightIntervalInd, 1);
641
+ pointsFromSubset.splice(pointSubsetInd, 1);
642
+
643
+ if (rightPoint && !rightPoint.inSubset) {
644
+ // if right point isn't in subset
645
+ // and don't have an interval to its right
646
+ // it is not longer part of the subset
647
+ let rightRightIntervalInd = intervalsFromSubset
648
+ .map((x) => x[0])
649
+ .indexOf(rightPoint.value);
650
+ if (rightRightIntervalInd === -1) {
651
+ // so that point doesn't disappear, add it to additionalPoints
652
+ additionalPoints.push(rightPoint.value);
653
+ modifiedAdditionalPoints = true;
654
+ }
655
+ }
656
+ }
657
+ } else {
658
+ // don't have interval on either side
659
+ // just remove the point
660
+ pointsFromSubset.splice(pointSubsetInd, 1);
661
+ }
662
+ }
663
+
664
+ let updateInstructions = await this.createUpdateInstructions({
665
+ intervalsFromSubset,
666
+ pointsFromSubset,
667
+ modifiedAdditionalPoints,
668
+ additionalPoints,
669
+ });
670
+
671
+ return await this.coreFunctions.performUpdate({
672
+ updateInstructions,
673
+ actionId,
674
+ sourceInformation,
675
+ skipRendererUpdate,
676
+ event: {
677
+ verb: "interacted",
678
+ object: {
679
+ componentName: this.componentName,
680
+ componentType: this.componentType,
681
+ },
682
+ result: {
683
+ deletedPoint: point.value,
684
+ intervalsFromSubset,
685
+ pointsFromSubset,
686
+ additionalPoints,
687
+ },
688
+ },
689
+ });
690
+ }
691
+ }
692
+
693
+ async createUpdateInstructions({
694
+ intervalsFromSubset,
695
+ pointsFromSubset,
696
+ modifiedAdditionalPoints,
697
+ additionalPoints,
698
+ }) {
699
+ let dx = await this.stateValues.dx;
700
+ let roundValue = (x) => Math.round(x / dx) * dx;
701
+
702
+ // rebuild subset
703
+ let pieces = [];
704
+ for (let interval of intervalsFromSubset) {
705
+ pieces.push(
706
+ new subsets.OpenInterval(
707
+ roundValue(interval[0]),
708
+ roundValue(interval[1]),
709
+ ),
710
+ );
711
+ }
712
+ for (let point of pointsFromSubset) {
713
+ if (point.inSubset) {
714
+ pieces.push(new subsets.Singleton(roundValue(point.value)));
715
+ }
716
+ }
717
+
718
+ let newSubset;
719
+ if (pieces.length === 0) {
720
+ newSubset = new subsets.EmptySet();
721
+ } else if (pieces.length === 1) {
722
+ newSubset = pieces[0];
723
+ } else {
724
+ newSubset = new subsets.Union(pieces);
725
+ }
726
+
727
+ let updateInstructions = [
728
+ {
729
+ componentName: this.componentName,
730
+ updateType: "updateValue",
731
+ stateVariable: "subsetValue",
732
+ value: newSubset,
733
+ },
734
+ ];
735
+
736
+ if (modifiedAdditionalPoints) {
737
+ updateInstructions.push({
738
+ componentName: this.componentName,
739
+ updateType: "updateValue",
740
+ stateVariable: "additionalPoints",
741
+ value: additionalPoints.map(roundValue),
742
+ });
743
+ }
744
+ return updateInstructions;
745
+ }
746
+
747
+ async movePoint({
748
+ pointInd,
749
+ value,
750
+ transient,
751
+ actionId,
752
+ sourceInformation = {},
753
+ skipRendererUpdate = false,
754
+ }) {
755
+ let dx = await this.stateValues.dx;
756
+
757
+ let roundedValue =
758
+ Math.round(
759
+ Math.max(
760
+ await this.stateValues.xmin,
761
+ Math.min(await this.stateValues.xmax, value),
762
+ ) / dx,
763
+ ) * dx;
764
+
765
+ let points = await this.stateValues.points;
766
+ let point = points[pointInd];
767
+
768
+ // value cannot cross another point
769
+ let leftPoint = points[pointInd - 1];
770
+ if (leftPoint) {
771
+ roundedValue = Math.max(roundedValue, leftPoint.value + dx);
772
+ }
773
+ let rightPoint = points[pointInd + 1];
774
+ if (rightPoint) {
775
+ roundedValue = Math.min(roundedValue, rightPoint.value - dx);
776
+ }
777
+
778
+ let additionalPoints = [...(await this.stateValues.additionalPoints)];
779
+ let pointsFromSubset = [...(await this.stateValues.pointsFromSubset)];
780
+ let intervalsFromSubset = [...(await this.stateValues.intervalsFromSubset)];
781
+
782
+ if (point.isAdditional) {
783
+ additionalPoints[point.additionalPointInd] = roundedValue;
784
+ if (transient) {
785
+ return await this.coreFunctions.performUpdate({
786
+ updateInstructions: [
787
+ {
788
+ componentName: this.componentName,
789
+ updateType: "updateValue",
790
+ stateVariable: "additionalPoints",
791
+ value: additionalPoints,
792
+ },
793
+ ],
794
+ transient: true,
795
+ actionId,
796
+ sourceInformation,
797
+ skipRendererUpdate,
798
+ });
799
+ } else {
800
+ return await this.coreFunctions.performUpdate({
801
+ updateInstructions: [
802
+ {
803
+ componentName: this.componentName,
804
+ updateType: "updateValue",
805
+ stateVariable: "additionalPoints",
806
+ value: additionalPoints,
807
+ },
808
+ ],
809
+ actionId,
810
+ sourceInformation,
811
+ skipRendererUpdate,
812
+ event: {
813
+ verb: "interacted",
814
+ object: {
815
+ componentName: this.componentName,
816
+ componentType: this.componentType,
817
+ },
818
+ result: {
819
+ movedPoint: roundedValue,
820
+ intervalsFromSubset,
821
+ pointsFromSubset,
822
+ additionalPoints,
823
+ },
824
+ },
825
+ });
826
+ }
827
+ } else {
828
+ let pointSubsetInd = pointsFromSubset
829
+ .map((x) => x.value)
830
+ .indexOf(point.value);
831
+ let leftIntervalInd = intervalsFromSubset
832
+ .map((x) => x[1])
833
+ .indexOf(point.value);
834
+ let rightIntervalInd = intervalsFromSubset
835
+ .map((x) => x[0])
836
+ .indexOf(point.value);
837
+
838
+ pointsFromSubset[pointSubsetInd] = {
839
+ value: roundedValue,
840
+ inSubset: pointsFromSubset[pointSubsetInd].inSubset,
841
+ };
842
+
843
+ if (leftIntervalInd !== -1) {
844
+ intervalsFromSubset[leftIntervalInd] = [
845
+ intervalsFromSubset[leftIntervalInd][0],
846
+ roundedValue,
847
+ ];
848
+ }
849
+ if (rightIntervalInd !== -1) {
850
+ intervalsFromSubset[rightIntervalInd] = [
851
+ roundedValue,
852
+ intervalsFromSubset[rightIntervalInd][1],
853
+ ];
854
+ }
855
+
856
+ let updateInstructions = await this.createUpdateInstructions({
857
+ intervalsFromSubset,
858
+ pointsFromSubset,
859
+ modifiedAdditionalPoints: false,
860
+ });
861
+
862
+ if (transient) {
863
+ return await this.coreFunctions.performUpdate({
864
+ updateInstructions,
865
+ transient: true,
866
+ actionId,
867
+ sourceInformation,
868
+ skipRendererUpdate,
869
+ });
870
+ } else {
871
+ return await this.coreFunctions.performUpdate({
872
+ updateInstructions,
873
+ actionId,
874
+ sourceInformation,
875
+ skipRendererUpdate,
876
+ event: {
877
+ verb: "interacted",
878
+ object: {
879
+ componentName: this.componentName,
880
+ componentType: this.componentType,
881
+ },
882
+ result: {
883
+ movedPoint: roundedValue,
884
+ intervalsFromSubset,
885
+ pointsFromSubset,
886
+ additionalPoints,
887
+ },
888
+ },
889
+ });
890
+ }
891
+ }
892
+ }
893
+
894
+ async togglePoint({
895
+ pointInd,
896
+ actionId,
897
+ sourceInformation = {},
898
+ skipRendererUpdate = false,
899
+ }) {
900
+ let point = (await this.stateValues.points)[pointInd];
901
+
902
+ let pointsFromSubset = [...(await this.stateValues.pointsFromSubset)];
903
+ let intervalsFromSubset = [...(await this.stateValues.intervalsFromSubset)];
904
+ let additionalPoints = [...(await this.stateValues.additionalPoints)];
905
+
906
+ let modifiedAdditionalPoints = false;
907
+
908
+ if (point.isAdditional) {
909
+ // after toggling, point is no longer additional
910
+
911
+ additionalPoints.splice(point.additionalPointInd, 1);
912
+
913
+ modifiedAdditionalPoints = true;
914
+
915
+ if (point.inSubset) {
916
+ // point is in the middle of a interval
917
+ // split that interval
918
+
919
+ for (let [ind, interval] of intervalsFromSubset.entries()) {
920
+ if (interval[0] < point.value && interval[1] > point.value) {
921
+ // replace interval with two new
922
+ let newIntervals = [
923
+ [interval[0], point.value],
924
+ [point.value, interval[1]],
925
+ ];
926
+
927
+ intervalsFromSubset.splice(ind, 1, ...newIntervals);
928
+ break;
929
+ }
930
+ }
931
+ } else {
932
+ // point is not in the middle of interval
933
+ // so it becomes a point in the subset
934
+ pointsFromSubset.push({
935
+ value: point.value,
936
+ inSubset: true,
937
+ });
938
+ }
939
+ } else {
940
+ // have a point that is already part of the subset
941
+
942
+ let pointSubsetInd = pointsFromSubset
943
+ .map((x) => x.value)
944
+ .indexOf(point.value);
945
+
946
+ let leftIntervalInd = intervalsFromSubset
947
+ .map((x) => x[1])
948
+ .indexOf(point.value);
949
+ let rightIntervalInd = intervalsFromSubset
950
+ .map((x) => x[0])
951
+ .indexOf(point.value);
952
+
953
+ if (leftIntervalInd !== -1) {
954
+ if (rightIntervalInd !== -1) {
955
+ // have intervals on both sides of points
956
+ // merge the intervals and point becomes additional
957
+ intervalsFromSubset[leftIntervalInd] = [
958
+ intervalsFromSubset[leftIntervalInd][0],
959
+ intervalsFromSubset[rightIntervalInd][1],
960
+ ];
961
+ intervalsFromSubset.splice(rightIntervalInd, 1);
962
+
963
+ pointsFromSubset.splice(pointSubsetInd, 1);
964
+ additionalPoints.push(point.value);
965
+ modifiedAdditionalPoints = true;
966
+ } else {
967
+ // since interval on only one side
968
+ // simply toggle point
969
+ pointsFromSubset[pointSubsetInd] = {
970
+ value: point.value,
971
+ inSubset: !point.inSubset,
972
+ };
973
+ }
974
+ } else {
975
+ // don't have left interval
976
+
977
+ if (rightIntervalInd !== -1) {
978
+ // since interval on only one side
979
+ // simply toggle point
980
+ pointsFromSubset[pointSubsetInd] = {
981
+ value: point.value,
982
+ inSubset: !point.inSubset,
983
+ };
984
+ } else {
985
+ // don't have interval on either side
986
+ // so was an isolated point that toggled off
987
+ // point becomes additional
988
+ pointsFromSubset.splice(pointSubsetInd, 1);
989
+ additionalPoints.push(point.value);
990
+ modifiedAdditionalPoints = true;
991
+ }
992
+ }
993
+ }
994
+
995
+ let updateInstructions = await this.createUpdateInstructions({
996
+ intervalsFromSubset,
997
+ pointsFromSubset,
998
+ modifiedAdditionalPoints,
999
+ additionalPoints,
1000
+ });
1001
+
1002
+ return await this.coreFunctions.performUpdate({
1003
+ updateInstructions,
1004
+ actionId,
1005
+ sourceInformation,
1006
+ skipRendererUpdate,
1007
+ event: {
1008
+ verb: "interacted",
1009
+ object: {
1010
+ componentName: this.componentName,
1011
+ componentType: this.componentType,
1012
+ },
1013
+ result: {
1014
+ toggledPoint: point.value,
1015
+ intervalsFromSubset,
1016
+ pointsFromSubset,
1017
+ additionalPoints,
1018
+ },
1019
+ },
1020
+ });
1021
+ }
1022
+
1023
+ async toggleInterval({
1024
+ intervalInd,
1025
+ actionId,
1026
+ sourceInformation = {},
1027
+ skipRendererUpdate = false,
1028
+ }) {
1029
+ let interval = (await this.stateValues.intervals)[intervalInd];
1030
+
1031
+ let points = await this.stateValues.points;
1032
+ let leftPoint = points[intervalInd - 1];
1033
+ let rightPoint = points[intervalInd];
1034
+
1035
+ let pointsFromSubset = [...(await this.stateValues.pointsFromSubset)];
1036
+ let intervalsFromSubset = [...(await this.stateValues.intervalsFromSubset)];
1037
+ let additionalPoints = [...(await this.stateValues.additionalPoints)];
1038
+
1039
+ let modifiedAdditionalPoints = false;
1040
+
1041
+ if (interval.inSubset) {
1042
+ let intervalSubsetInd, intervalSubset;
1043
+
1044
+ // find interval in subset containing interval
1045
+ for (let [ind, interval2] of intervalsFromSubset.entries()) {
1046
+ if (interval2[0] <= interval.left && interval2[1] >= interval.right) {
1047
+ intervalSubset = interval2;
1048
+ intervalSubsetInd = ind;
1049
+ break;
1050
+ }
1051
+ }
1052
+
1053
+ if (interval.left === intervalSubset[0]) {
1054
+ if (interval.right === intervalSubset[1]) {
1055
+ // interval is an interval from the subset
1056
+ // just remove the interval
1057
+ intervalsFromSubset.splice(intervalSubsetInd, 1);
1058
+
1059
+ if (leftPoint && !leftPoint.inSubset) {
1060
+ // if leftPoint doesn't have an interval to the left
1061
+ // then it is no longer part of the subset
1062
+ // and becomes additional
1063
+ let leftLeftIntervalInd = intervalsFromSubset
1064
+ .map((x) => x[1])
1065
+ .indexOf(leftPoint.value);
1066
+ if (leftLeftIntervalInd === -1) {
1067
+ let leftPointSubsetInd = pointsFromSubset
1068
+ .map((x) => x.value)
1069
+ .indexOf(leftPoint.value);
1070
+ pointsFromSubset.splice(leftPointSubsetInd, 1);
1071
+ additionalPoints.push(leftPoint.value);
1072
+ modifiedAdditionalPoints = true;
1073
+ }
1074
+ }
1075
+
1076
+ if (rightPoint && !rightPoint.inSubset) {
1077
+ // if rightPoint doesn't have an interval to the right
1078
+ // then it is no longer part of the subset
1079
+ // and becomes additional
1080
+ let rightRightIntervalInd = intervalsFromSubset
1081
+ .map((x) => x[0])
1082
+ .indexOf(rightPoint.value);
1083
+ if (rightRightIntervalInd === -1) {
1084
+ let rightPointSubsetInd = pointsFromSubset
1085
+ .map((x) => x.value)
1086
+ .indexOf(rightPoint.value);
1087
+ pointsFromSubset.splice(rightPointSubsetInd, 1);
1088
+ additionalPoints.push(rightPoint.value);
1089
+ modifiedAdditionalPoints = true;
1090
+ }
1091
+ }
1092
+ } else {
1093
+ // just left point of interval is in subset
1094
+
1095
+ // remove left portion of intervalSubset
1096
+ intervalsFromSubset[intervalSubsetInd] = [
1097
+ interval.right,
1098
+ intervalSubset[1],
1099
+ ];
1100
+
1101
+ if (leftPoint && !leftPoint.inSubset) {
1102
+ // if leftPoint doesn't have an interval to the left
1103
+ // then it is no longer part of the subset
1104
+ // and becomes additional
1105
+ let leftLeftIntervalInd = intervalsFromSubset
1106
+ .map((x) => x[1])
1107
+ .indexOf(leftPoint.value);
1108
+ if (leftLeftIntervalInd === -1) {
1109
+ let leftPointSubsetInd = pointsFromSubset
1110
+ .map((x) => x.value)
1111
+ .indexOf(leftPoint.value);
1112
+ pointsFromSubset.splice(leftPointSubsetInd, 1);
1113
+ additionalPoints.push(leftPoint.value);
1114
+ modifiedAdditionalPoints = true;
1115
+ }
1116
+ }
1117
+
1118
+ // rightPoint becomes part of the subset
1119
+ pointsFromSubset.push({
1120
+ value: rightPoint.value,
1121
+ inSubset: true,
1122
+ });
1123
+
1124
+ additionalPoints.splice(rightPoint.additionalPointInd, 1);
1125
+ modifiedAdditionalPoints = true;
1126
+ }
1127
+ } else {
1128
+ // left point is not in subset
1129
+ if (interval.right === intervalSubset[1]) {
1130
+ // just right point of interval is in subset
1131
+
1132
+ // remove right portion of intervalSubset
1133
+ intervalsFromSubset[intervalSubsetInd] = [
1134
+ intervalSubset[0],
1135
+ interval.left,
1136
+ ];
1137
+
1138
+ if (rightPoint && !rightPoint.inSubset) {
1139
+ // if rightPoint doesn't have an interval to the right
1140
+ // then it is no longer part of the subset
1141
+ // and becomes additional
1142
+ let rightRightIntervalInd = intervalsFromSubset
1143
+ .map((x) => x[0])
1144
+ .indexOf(rightPoint.value);
1145
+ if (rightRightIntervalInd === -1) {
1146
+ let rightPointSubsetInd = pointsFromSubset
1147
+ .map((x) => x.value)
1148
+ .indexOf(rightPoint.value);
1149
+ pointsFromSubset.splice(rightPointSubsetInd, 1);
1150
+ additionalPoints.push(rightPoint.value);
1151
+ modifiedAdditionalPoints = true;
1152
+ }
1153
+ }
1154
+
1155
+ // leftPoint becomes part of the subset
1156
+ pointsFromSubset.push({
1157
+ value: leftPoint.value,
1158
+ inSubset: true,
1159
+ });
1160
+
1161
+ additionalPoints.splice(leftPoint.additionalPointInd, 1);
1162
+ modifiedAdditionalPoints = true;
1163
+ } else {
1164
+ // neither endpoint of interval is in subset
1165
+ // remove middle portion intervalSubset to create two new intervals
1166
+
1167
+ let newIntervals = [
1168
+ [intervalSubset[0], interval.left],
1169
+ [interval.right, intervalSubset[1]],
1170
+ ];
1171
+ intervalsFromSubset.splice(intervalSubsetInd, 1, ...newIntervals);
1172
+
1173
+ // leftPoint and rightPoint become part of the subset
1174
+ pointsFromSubset.push({
1175
+ value: leftPoint.value,
1176
+ inSubset: true,
1177
+ });
1178
+ pointsFromSubset.push({
1179
+ value: rightPoint.value,
1180
+ inSubset: true,
1181
+ });
1182
+
1183
+ additionalPoints.splice(rightPoint.additionalPointInd, 1);
1184
+ additionalPoints.splice(leftPoint.additionalPointInd, 1);
1185
+ modifiedAdditionalPoints = true;
1186
+ }
1187
+ }
1188
+ } else {
1189
+ // interval is not in subset
1190
+
1191
+ // determine if have adjacent interval in subset
1192
+
1193
+ let leftIntervalInd = intervalsFromSubset
1194
+ .map((x) => x[1])
1195
+ .indexOf(interval.left);
1196
+ let rightIntervalInd = intervalsFromSubset
1197
+ .map((x) => x[0])
1198
+ .indexOf(interval.right);
1199
+
1200
+ if (leftIntervalInd === -1) {
1201
+ if (rightIntervalInd === -1) {
1202
+ // no adjacent intervals
1203
+
1204
+ // add the interval to the subset
1205
+ intervalsFromSubset.push([interval.left, interval.right]);
1206
+
1207
+ // if either endpoint is additional
1208
+ // it is no longer additional
1209
+ // Note: we don't need to add it to the subset
1210
+ // as isSubset must be false
1211
+
1212
+ if (rightPoint && rightPoint.isAdditional) {
1213
+ additionalPoints.splice(rightPoint.additionalPointInd, 1);
1214
+ modifiedAdditionalPoints = true;
1215
+ }
1216
+ if (leftPoint && leftPoint.isAdditional) {
1217
+ additionalPoints.splice(leftPoint.additionalPointInd, 1);
1218
+ modifiedAdditionalPoints = true;
1219
+ }
1220
+ } else {
1221
+ // just interval to right is in subset
1222
+
1223
+ if (rightPoint.inSubset) {
1224
+ // extend interval that is on the right
1225
+ intervalsFromSubset[rightIntervalInd] = [
1226
+ interval.left,
1227
+ intervalsFromSubset[rightIntervalInd][1],
1228
+ ];
1229
+
1230
+ // point becomes additional
1231
+ additionalPoints.push(rightPoint.value);
1232
+ modifiedAdditionalPoints = true;
1233
+
1234
+ // Note: don't need to remove rightPoint from pointsFromSubset
1235
+ // since the Union will eliminate it
1236
+ } else {
1237
+ // add the interval to the subset
1238
+ intervalsFromSubset.push([interval.left, interval.right]);
1239
+ }
1240
+
1241
+ // if left endpoint is additional
1242
+ // it is no longer additional
1243
+ // Note: we don't need to add it to the subset
1244
+ // as isSubset must be false
1245
+
1246
+ if (leftPoint && leftPoint.isAdditional) {
1247
+ additionalPoints.splice(leftPoint.additionalPointInd, 1);
1248
+ modifiedAdditionalPoints = true;
1249
+ }
1250
+ }
1251
+ } else {
1252
+ // interval to left is in subset
1253
+
1254
+ if (rightIntervalInd === -1) {
1255
+ // just interval to left is in subset
1256
+
1257
+ if (leftPoint.inSubset) {
1258
+ // extend interval that is on the left
1259
+ intervalsFromSubset[leftIntervalInd] = [
1260
+ intervalsFromSubset[leftIntervalInd][0],
1261
+ interval.right,
1262
+ ];
1263
+
1264
+ // point becomes additional
1265
+ additionalPoints.push(leftPoint.value);
1266
+ modifiedAdditionalPoints = true;
1267
+
1268
+ // Note: don't need to remove leftPoint from pointsFromSubset
1269
+ // since the Union will eliminate it
1270
+ } else {
1271
+ // add the interval to the subset
1272
+ intervalsFromSubset.push([interval.left, interval.right]);
1273
+ }
1274
+
1275
+ // if right endpoint is additional
1276
+ // it is no longer additional
1277
+ // Note: we don't need to add it to the subset
1278
+ // as isSubset must be false
1279
+
1280
+ if (rightPoint && rightPoint.isAdditional) {
1281
+ additionalPoints.splice(rightPoint.additionalPointInd, 1);
1282
+ modifiedAdditionalPoints = true;
1283
+ }
1284
+ } else {
1285
+ // both adjacent intervals are in the subset
1286
+ if (leftPoint.inSubset) {
1287
+ if (rightPoint.inSubset) {
1288
+ // merge intervals
1289
+ let newInterval = [
1290
+ intervalsFromSubset[leftIntervalInd][0],
1291
+ intervalsFromSubset[rightIntervalInd][1],
1292
+ ];
1293
+
1294
+ intervalsFromSubset.splice(leftIntervalInd, 2, newInterval);
1295
+
1296
+ // point becomes additional
1297
+ additionalPoints.push(leftPoint.value);
1298
+ additionalPoints.push(rightPoint.value);
1299
+ modifiedAdditionalPoints = true;
1300
+
1301
+ // Note: don't need to remove points from pointsFromSubset
1302
+ // since the Union will eliminate it
1303
+ } else {
1304
+ // just left point is in subset
1305
+ // extend interval that is on the left
1306
+ intervalsFromSubset[leftIntervalInd] = [
1307
+ intervalsFromSubset[leftIntervalInd][0],
1308
+ interval.right,
1309
+ ];
1310
+
1311
+ // left point becomes additional
1312
+ additionalPoints.push(leftPoint.value);
1313
+ modifiedAdditionalPoints = true;
1314
+
1315
+ // Note: don't need to remove leftPoint from pointsFromSubset
1316
+ // since the Union will eliminate it
1317
+ }
1318
+ } else {
1319
+ // left point is not in subset
1320
+
1321
+ if (rightPoint.inSubset) {
1322
+ // just right point is in subset
1323
+ // extend interval that is on the right
1324
+ intervalsFromSubset[rightIntervalInd] = [
1325
+ interval.left,
1326
+ intervalsFromSubset[rightIntervalInd][1],
1327
+ ];
1328
+
1329
+ // right point becomes additional
1330
+ additionalPoints.push(rightPoint.value);
1331
+ modifiedAdditionalPoints = true;
1332
+
1333
+ // Note: don't need to remove rightPoint from pointsFromSubset
1334
+ // since the Union will eliminate it
1335
+ } else {
1336
+ // neither point is in subset
1337
+ // add the interval to the subset
1338
+ intervalsFromSubset.push([interval.left, interval.right]);
1339
+ }
1340
+ }
1341
+ }
1342
+ }
1343
+ }
1344
+
1345
+ let updateInstructions = await this.createUpdateInstructions({
1346
+ intervalsFromSubset,
1347
+ pointsFromSubset,
1348
+ modifiedAdditionalPoints,
1349
+ additionalPoints,
1350
+ });
1351
+
1352
+ return await this.coreFunctions.performUpdate({
1353
+ updateInstructions,
1354
+ actionId,
1355
+ sourceInformation,
1356
+ skipRendererUpdate,
1357
+ event: {
1358
+ verb: "interacted",
1359
+ object: {
1360
+ componentName: this.componentName,
1361
+ componentType: this.componentType,
1362
+ },
1363
+ result: {
1364
+ toggledInterval: [interval.left, interval.right],
1365
+ intervalsFromSubset,
1366
+ pointsFromSubset,
1367
+ additionalPoints,
1368
+ },
1369
+ },
1370
+ });
1371
+ }
1372
+
1373
+ async clear({
1374
+ actionId,
1375
+ sourceInformation = {},
1376
+ skipRendererUpdate = false,
1377
+ }) {
1378
+ let updateInstructions = await this.createUpdateInstructions({
1379
+ intervalsFromSubset: [],
1380
+ pointsFromSubset: [],
1381
+ modifiedAdditionalPoints: true,
1382
+ additionalPoints: [],
1383
+ });
1384
+
1385
+ return await this.coreFunctions.performUpdate({
1386
+ updateInstructions,
1387
+ actionId,
1388
+ sourceInformation,
1389
+ skipRendererUpdate,
1390
+ event: {
1391
+ verb: "interacted",
1392
+ object: {
1393
+ componentName: this.componentName,
1394
+ componentType: this.componentType,
1395
+ },
1396
+ result: {
1397
+ cleared: true,
1398
+ intervalsFromSubset: [],
1399
+ pointsFromSubset: [],
1400
+ additionalPoints: [],
1401
+ },
1402
+ },
1403
+ });
1404
+ }
1405
+
1406
+ async setToR({
1407
+ actionId,
1408
+ sourceInformation = {},
1409
+ skipRendererUpdate = false,
1410
+ }) {
1411
+ let updateInstructions = await this.createUpdateInstructions({
1412
+ intervalsFromSubset: [[-Infinity, Infinity]],
1413
+ pointsFromSubset: [],
1414
+ modifiedAdditionalPoints: true,
1415
+ additionalPoints: [],
1416
+ });
1417
+
1418
+ return await this.coreFunctions.performUpdate({
1419
+ updateInstructions,
1420
+ actionId,
1421
+ sourceInformation,
1422
+ skipRendererUpdate,
1423
+ event: {
1424
+ verb: "interacted",
1425
+ object: {
1426
+ componentName: this.componentName,
1427
+ componentType: this.componentType,
1428
+ },
1429
+ result: {
1430
+ setToR: true,
1431
+ intervalsFromSubset: [[-Infinity, Infinity]],
1432
+ pointsFromSubset: [],
1433
+ additionalPoints: [],
1434
+ },
1435
+ },
1436
+ });
1437
+ }
1438
+
1439
+ recordVisibilityChange({ isVisible, actionId }) {
1440
+ this.coreFunctions.requestRecordEvent({
1441
+ verb: "visibilityChanged",
1442
+ object: {
1443
+ componentName: this.componentName,
1444
+ componentType: this.componentType,
1445
+ },
1446
+ result: { isVisible },
1447
+ });
1448
+ this.coreFunctions.resolveAction({ actionId });
1449
+ }
1450
+ }
1451
+
1452
+ function parseValueIntoSubset({ inputString, format, variable }) {
1453
+ if (!inputString) {
1454
+ return new subsets.EmptySet();
1455
+ }
1456
+
1457
+ let expression;
1458
+ if (format === "latex") {
1459
+ try {
1460
+ expression = me.fromLatex(inputString);
1461
+ } catch (e) {
1462
+ console.warn(`Invalid latex for subsetOfRealsInput: ${inputString}`);
1463
+ return new subsets.EmptySet();
1464
+ }
1465
+ } else if (format === "text") {
1466
+ try {
1467
+ expression = me.fromText(inputString);
1468
+ } catch (e) {
1469
+ console.warn(`Invalid text for subsetOfRealsInput: ${inputString}`);
1470
+ return new subsets.EmptySet();
1471
+ }
1472
+ }
1473
+ return buildSubsetFromMathExpression(expression, variable);
1474
+ }