@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,4476 @@
1
+ import { cesc, cesc2 } from "../../../../src/utils/url";
2
+
3
+ function nInDOM(n) {
4
+ if (n < 0) {
5
+ return `−${Math.abs(n)}`;
6
+ } else {
7
+ return String(n);
8
+ }
9
+ }
10
+
11
+ describe("Map Tag Tests", function () {
12
+ beforeEach(() => {
13
+ cy.clearIndexedDB();
14
+ cy.visit("/src/Tools/cypressTest/");
15
+ });
16
+
17
+ it("single map of maths", () => {
18
+ cy.window().then(async (win) => {
19
+ win.postMessage(
20
+ {
21
+ doenetML: `
22
+ <text>a</text>
23
+ <aslist>
24
+ <map>
25
+ <template><math>sin(2$x) + $i</math></template>
26
+ <sources alias="x" indexAlias="i">
27
+ <math>x</math>
28
+ <math>y</math>
29
+ </sources>
30
+ </map>
31
+ </aslist>
32
+ `,
33
+ },
34
+ "*",
35
+ );
36
+ });
37
+
38
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
39
+
40
+ cy.window().then(async (win) => {
41
+ let stateVariables = await win.returnAllStateVariables1();
42
+ let replacements = stateVariables["/_map1"].replacements;
43
+ let mathr1Name =
44
+ stateVariables[replacements[0].componentName].replacements[0]
45
+ .componentName;
46
+ let mathr1Anchor = "#" + mathr1Name;
47
+ let mathr2Name =
48
+ stateVariables[replacements[1].componentName].replacements[0]
49
+ .componentName;
50
+ let mathr2Anchor = "#" + mathr2Name;
51
+
52
+ cy.log("Test values displayed in browser");
53
+ cy.get(`${cesc2(mathr1Anchor)} .mjx-mrow`)
54
+ .eq(0)
55
+ .invoke("text")
56
+ .then((text) => {
57
+ expect(text.trim()).equal("sin(2x)+1");
58
+ });
59
+ cy.get(`${cesc2(mathr2Anchor)} .mjx-mrow`)
60
+ .eq(0)
61
+ .invoke("text")
62
+ .then((text) => {
63
+ expect(text.trim()).equal("sin(2y)+2");
64
+ });
65
+
66
+ cy.log("Test internal values are set to the correct values");
67
+ cy.window().then(() => {
68
+ expect(stateVariables[mathr1Name].stateValues.value).eqls([
69
+ "+",
70
+ ["apply", "sin", ["*", 2, "x"]],
71
+ 1,
72
+ ]);
73
+ expect(stateVariables[mathr2Name].stateValues.value).eqls([
74
+ "+",
75
+ ["apply", "sin", ["*", 2, "y"]],
76
+ 2,
77
+ ]);
78
+ });
79
+ });
80
+ });
81
+
82
+ it("single map of texts", () => {
83
+ cy.window().then(async (win) => {
84
+ win.postMessage(
85
+ {
86
+ doenetML: `
87
+ <text>a</text>
88
+ <map >
89
+ <template><text>You are a $animal!</text> </template>
90
+ <sources alias="animal"><text>squirrel</text><text>bat</text></sources>
91
+ </map>
92
+ `,
93
+ },
94
+ "*",
95
+ );
96
+ });
97
+
98
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
99
+ cy.window().then(async (win) => {
100
+ let stateVariables = await win.returnAllStateVariables1();
101
+ let replacements = stateVariables["/_map1"].replacements;
102
+ let textr1Name =
103
+ stateVariables[replacements[0].componentName].replacements[0]
104
+ .componentName;
105
+ let textr1Anchor = "#" + textr1Name;
106
+ let textr2Name =
107
+ stateVariables[replacements[1].componentName].replacements[0]
108
+ .componentName;
109
+ let textr2Anchor = "#" + textr2Name;
110
+
111
+ cy.log("Test values displayed in browser");
112
+ cy.get(cesc2(textr1Anchor)).should("have.text", "You are a squirrel!");
113
+ cy.get(cesc2(textr2Anchor)).should("have.text", "You are a bat!");
114
+
115
+ cy.log("Test internal values are set to the correct values");
116
+ cy.window().then(() => {
117
+ expect(stateVariables[textr1Name].stateValues.value).eq(
118
+ "You are a squirrel!",
119
+ );
120
+ });
121
+ });
122
+ });
123
+
124
+ it("single map of sequence", () => {
125
+ cy.window().then(async (win) => {
126
+ win.postMessage(
127
+ {
128
+ doenetML: `
129
+ <text>a</text>
130
+ <map>
131
+ <template><math simplify>$n^2</math> </template>
132
+ <sources alias="n"><sequence from="1" to="5"/></sources>
133
+ </map>
134
+ `,
135
+ },
136
+ "*",
137
+ );
138
+ });
139
+
140
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
141
+
142
+ cy.window().then(async (win) => {
143
+ let stateVariables = await win.returnAllStateVariables1();
144
+ let replacements = stateVariables["/_map1"].replacements;
145
+ let mathrNames = replacements.map(
146
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
147
+ );
148
+ let mathrAnchors = mathrNames.map((x) => cesc2("#" + x));
149
+
150
+ cy.log("Test values displayed in browser");
151
+ cy.get(`${mathrAnchors[0]} .mjx-mrow`)
152
+ .eq(0)
153
+ .invoke("text")
154
+ .then((text) => {
155
+ expect(text.trim()).equal("1");
156
+ });
157
+ cy.get(`${mathrAnchors[1]} .mjx-mrow`)
158
+ .eq(0)
159
+ .invoke("text")
160
+ .then((text) => {
161
+ expect(text.trim()).equal("4");
162
+ });
163
+ cy.get(`${mathrAnchors[2]} .mjx-mrow`)
164
+ .eq(0)
165
+ .invoke("text")
166
+ .then((text) => {
167
+ expect(text.trim()).equal("9");
168
+ });
169
+ cy.get(`${mathrAnchors[3]} .mjx-mrow`)
170
+ .eq(0)
171
+ .invoke("text")
172
+ .then((text) => {
173
+ expect(text.trim()).equal("16");
174
+ });
175
+ cy.get(`${mathrAnchors[4]} .mjx-mrow`)
176
+ .eq(0)
177
+ .invoke("text")
178
+ .then((text) => {
179
+ expect(text.trim()).equal("25");
180
+ });
181
+
182
+ cy.log("Test internal values are set to the correct values");
183
+ cy.window().then(() => {
184
+ expect(stateVariables[mathrNames[0]].stateValues.value).eq(1);
185
+ expect(stateVariables[mathrNames[1]].stateValues.value).eq(4);
186
+ expect(stateVariables[mathrNames[2]].stateValues.value).eq(9);
187
+ expect(stateVariables[mathrNames[3]].stateValues.value).eq(16);
188
+ expect(stateVariables[mathrNames[4]].stateValues.value).eq(25);
189
+ });
190
+ });
191
+ });
192
+
193
+ it("triple parallel map", () => {
194
+ cy.window().then(async (win) => {
195
+ win.postMessage(
196
+ {
197
+ doenetML: `
198
+ <text>a</text>
199
+ <aslist>
200
+ <map behavior="parallel">
201
+ <template><math>($l, $m, $n)</math><math>($i, $j, $k)</math></template>
202
+ <sources alias="l" indexalias="i"><sequence from="1" to="5"/></sources>
203
+ <sources alias="m" indexalias="j"><sequence from="21" to="23"/></sources>
204
+ <sources alias="n" indexalias="k"><sequence from="-5" to="-21" step="-3"/></sources>
205
+ </map>
206
+ </aslist>
207
+ `,
208
+ },
209
+ "*",
210
+ );
211
+ });
212
+
213
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
214
+
215
+ cy.window().then(async (win) => {
216
+ let stateVariables = await win.returnAllStateVariables1();
217
+ let replacements = stateVariables["/_map1"].replacements;
218
+ let mathrNames = replacements.reduce(
219
+ (a, c) => [
220
+ ...a,
221
+ ...stateVariables[c.componentName].replacements.map(
222
+ (x) => x.componentName,
223
+ ),
224
+ ],
225
+ [],
226
+ );
227
+ let mathrAnchors = mathrNames.map((x) => cesc2("#" + x));
228
+
229
+ cy.log("Test values displayed in browser");
230
+ cy.get(`${mathrAnchors[0]} .mjx-mrow`)
231
+ .eq(0)
232
+ .invoke("text")
233
+ .then((text) => {
234
+ expect(text.trim()).equal("(1,21,−5)");
235
+ });
236
+ cy.get(`${mathrAnchors[1]} .mjx-mrow`)
237
+ .eq(0)
238
+ .invoke("text")
239
+ .then((text) => {
240
+ expect(text.trim()).equal("(1,1,1)");
241
+ });
242
+ cy.get(`${mathrAnchors[2]} .mjx-mrow`)
243
+ .eq(0)
244
+ .invoke("text")
245
+ .then((text) => {
246
+ expect(text.trim()).equal("(2,22,−8)");
247
+ });
248
+ cy.get(`${mathrAnchors[3]} .mjx-mrow`)
249
+ .eq(0)
250
+ .invoke("text")
251
+ .then((text) => {
252
+ expect(text.trim()).equal("(2,2,2)");
253
+ });
254
+ cy.get(`${mathrAnchors[4]} .mjx-mrow`)
255
+ .eq(0)
256
+ .invoke("text")
257
+ .then((text) => {
258
+ expect(text.trim()).equal("(3,23,−11)");
259
+ });
260
+ cy.get(`${mathrAnchors[5]} .mjx-mrow`)
261
+ .eq(0)
262
+ .invoke("text")
263
+ .then((text) => {
264
+ expect(text.trim()).equal("(3,3,3)");
265
+ });
266
+
267
+ cy.log("Test internal values are set to the correct values");
268
+ cy.window().then(() => {
269
+ expect(stateVariables[mathrNames[0]].stateValues.value).eqls([
270
+ "tuple",
271
+ 1,
272
+ 21,
273
+ -5,
274
+ ]);
275
+ expect(stateVariables[mathrNames[1]].stateValues.value).eqls([
276
+ "tuple",
277
+ 1,
278
+ 1,
279
+ 1,
280
+ ]);
281
+ expect(stateVariables[mathrNames[2]].stateValues.value).eqls([
282
+ "tuple",
283
+ 2,
284
+ 22,
285
+ -8,
286
+ ]);
287
+ expect(stateVariables[mathrNames[3]].stateValues.value).eqls([
288
+ "tuple",
289
+ 2,
290
+ 2,
291
+ 2,
292
+ ]);
293
+ expect(stateVariables[mathrNames[4]].stateValues.value).eqls([
294
+ "tuple",
295
+ 3,
296
+ 23,
297
+ -11,
298
+ ]);
299
+ expect(stateVariables[mathrNames[5]].stateValues.value).eqls([
300
+ "tuple",
301
+ 3,
302
+ 3,
303
+ 3,
304
+ ]);
305
+ });
306
+ });
307
+ });
308
+
309
+ it("triple combination map", () => {
310
+ cy.window().then(async (win) => {
311
+ win.postMessage(
312
+ {
313
+ doenetML: `
314
+ <text>a</text>
315
+ <map behavior="combination">
316
+ <template><math>($l, $m, $n)</math><math>($i, $j, $k)</math></template>
317
+ <sources alias="l" indexalias="i"><sequence from="1" to="3"/></sources>
318
+ <sources alias="m" indexalias="j"><sequence from="21" to="23" step="2"/></sources>
319
+ <sources alias="n" indexalias="k"><sequence from="-5" to="-8" step="-3"/></sources>
320
+ </map>
321
+ `,
322
+ },
323
+ "*",
324
+ );
325
+ });
326
+
327
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
328
+
329
+ cy.window().then(async (win) => {
330
+ let stateVariables = await win.returnAllStateVariables1();
331
+ let replacements = stateVariables["/_map1"].replacements;
332
+ let mathrNames = replacements.reduce(
333
+ (a, c) => [
334
+ ...a,
335
+ ...stateVariables[c.componentName].replacements.map(
336
+ (x) => x.componentName,
337
+ ),
338
+ ],
339
+ [],
340
+ );
341
+ let mathrAnchors = mathrNames.map((x) => cesc2("#" + x));
342
+
343
+ cy.log("Test values displayed in browser");
344
+ cy.get(`${mathrAnchors[0]} .mjx-mrow`)
345
+ .eq(0)
346
+ .invoke("text")
347
+ .then((text) => {
348
+ expect(text.trim()).equal("(1,21,−5)");
349
+ });
350
+ cy.get(`${mathrAnchors[1]} .mjx-mrow`)
351
+ .eq(0)
352
+ .invoke("text")
353
+ .then((text) => {
354
+ expect(text.trim()).equal("(1,1,1)");
355
+ });
356
+ cy.get(`${mathrAnchors[2]} .mjx-mrow`)
357
+ .eq(0)
358
+ .invoke("text")
359
+ .then((text) => {
360
+ expect(text.trim()).equal("(1,21,−8)");
361
+ });
362
+ cy.get(`${mathrAnchors[3]} .mjx-mrow`)
363
+ .eq(0)
364
+ .invoke("text")
365
+ .then((text) => {
366
+ expect(text.trim()).equal("(1,1,2)");
367
+ });
368
+ cy.get(`${mathrAnchors[4]} .mjx-mrow`)
369
+ .eq(0)
370
+ .invoke("text")
371
+ .then((text) => {
372
+ expect(text.trim()).equal("(1,23,−5)");
373
+ });
374
+ cy.get(`${mathrAnchors[5]} .mjx-mrow`)
375
+ .eq(0)
376
+ .invoke("text")
377
+ .then((text) => {
378
+ expect(text.trim()).equal("(1,2,1)");
379
+ });
380
+ cy.get(`${mathrAnchors[6]} .mjx-mrow`)
381
+ .eq(0)
382
+ .invoke("text")
383
+ .then((text) => {
384
+ expect(text.trim()).equal("(1,23,−8)");
385
+ });
386
+ cy.get(`${mathrAnchors[7]} .mjx-mrow`)
387
+ .eq(0)
388
+ .invoke("text")
389
+ .then((text) => {
390
+ expect(text.trim()).equal("(1,2,2)");
391
+ });
392
+ cy.get(`${mathrAnchors[8]} .mjx-mrow`)
393
+ .eq(0)
394
+ .invoke("text")
395
+ .then((text) => {
396
+ expect(text.trim()).equal("(2,21,−5)");
397
+ });
398
+ cy.get(`${mathrAnchors[9]} .mjx-mrow`)
399
+ .eq(0)
400
+ .invoke("text")
401
+ .then((text) => {
402
+ expect(text.trim()).equal("(2,1,1)");
403
+ });
404
+ cy.get(`${mathrAnchors[10]} .mjx-mrow`)
405
+ .eq(0)
406
+ .invoke("text")
407
+ .then((text) => {
408
+ expect(text.trim()).equal("(2,21,−8)");
409
+ });
410
+ cy.get(`${mathrAnchors[11]} .mjx-mrow`)
411
+ .eq(0)
412
+ .invoke("text")
413
+ .then((text) => {
414
+ expect(text.trim()).equal("(2,1,2)");
415
+ });
416
+ cy.get(`${mathrAnchors[12]} .mjx-mrow`)
417
+ .eq(0)
418
+ .invoke("text")
419
+ .then((text) => {
420
+ expect(text.trim()).equal("(2,23,−5)");
421
+ });
422
+ cy.get(`${mathrAnchors[13]} .mjx-mrow`)
423
+ .eq(0)
424
+ .invoke("text")
425
+ .then((text) => {
426
+ expect(text.trim()).equal("(2,2,1)");
427
+ });
428
+ cy.get(`${mathrAnchors[14]} .mjx-mrow`)
429
+ .eq(0)
430
+ .invoke("text")
431
+ .then((text) => {
432
+ expect(text.trim()).equal("(2,23,−8)");
433
+ });
434
+ cy.get(`${mathrAnchors[15]} .mjx-mrow`)
435
+ .eq(0)
436
+ .invoke("text")
437
+ .then((text) => {
438
+ expect(text.trim()).equal("(2,2,2)");
439
+ });
440
+ cy.get(`${mathrAnchors[16]} .mjx-mrow`)
441
+ .eq(0)
442
+ .invoke("text")
443
+ .then((text) => {
444
+ expect(text.trim()).equal("(3,21,−5)");
445
+ });
446
+ cy.get(`${mathrAnchors[17]} .mjx-mrow`)
447
+ .eq(0)
448
+ .invoke("text")
449
+ .then((text) => {
450
+ expect(text.trim()).equal("(3,1,1)");
451
+ });
452
+ cy.get(`${mathrAnchors[18]} .mjx-mrow`)
453
+ .eq(0)
454
+ .invoke("text")
455
+ .then((text) => {
456
+ expect(text.trim()).equal("(3,21,−8)");
457
+ });
458
+ cy.get(`${mathrAnchors[19]} .mjx-mrow`)
459
+ .eq(0)
460
+ .invoke("text")
461
+ .then((text) => {
462
+ expect(text.trim()).equal("(3,1,2)");
463
+ });
464
+ cy.get(`${mathrAnchors[20]} .mjx-mrow`)
465
+ .eq(0)
466
+ .invoke("text")
467
+ .then((text) => {
468
+ expect(text.trim()).equal("(3,23,−5)");
469
+ });
470
+ cy.get(`${mathrAnchors[21]} .mjx-mrow`)
471
+ .eq(0)
472
+ .invoke("text")
473
+ .then((text) => {
474
+ expect(text.trim()).equal("(3,2,1)");
475
+ });
476
+ cy.get(`${mathrAnchors[22]} .mjx-mrow`)
477
+ .eq(0)
478
+ .invoke("text")
479
+ .then((text) => {
480
+ expect(text.trim()).equal("(3,23,−8)");
481
+ });
482
+ cy.get(`${mathrAnchors[23]} .mjx-mrow`)
483
+ .eq(0)
484
+ .invoke("text")
485
+ .then((text) => {
486
+ expect(text.trim()).equal("(3,2,2)");
487
+ });
488
+
489
+ cy.log("Test internal values are set to the correct values");
490
+ cy.window().then(() => {
491
+ expect(stateVariables[mathrNames[0]].stateValues.value).eqls([
492
+ "tuple",
493
+ 1,
494
+ 21,
495
+ -5,
496
+ ]);
497
+ expect(stateVariables[mathrNames[1]].stateValues.value).eqls([
498
+ "tuple",
499
+ 1,
500
+ 1,
501
+ 1,
502
+ ]);
503
+ expect(stateVariables[mathrNames[2]].stateValues.value).eqls([
504
+ "tuple",
505
+ 1,
506
+ 21,
507
+ -8,
508
+ ]);
509
+ expect(stateVariables[mathrNames[3]].stateValues.value).eqls([
510
+ "tuple",
511
+ 1,
512
+ 1,
513
+ 2,
514
+ ]);
515
+ expect(stateVariables[mathrNames[4]].stateValues.value).eqls([
516
+ "tuple",
517
+ 1,
518
+ 23,
519
+ -5,
520
+ ]);
521
+ expect(stateVariables[mathrNames[5]].stateValues.value).eqls([
522
+ "tuple",
523
+ 1,
524
+ 2,
525
+ 1,
526
+ ]);
527
+ expect(stateVariables[mathrNames[6]].stateValues.value).eqls([
528
+ "tuple",
529
+ 1,
530
+ 23,
531
+ -8,
532
+ ]);
533
+ expect(stateVariables[mathrNames[7]].stateValues.value).eqls([
534
+ "tuple",
535
+ 1,
536
+ 2,
537
+ 2,
538
+ ]);
539
+ expect(stateVariables[mathrNames[8]].stateValues.value).eqls([
540
+ "tuple",
541
+ 2,
542
+ 21,
543
+ -5,
544
+ ]);
545
+ expect(stateVariables[mathrNames[9]].stateValues.value).eqls([
546
+ "tuple",
547
+ 2,
548
+ 1,
549
+ 1,
550
+ ]);
551
+ expect(stateVariables[mathrNames[10]].stateValues.value).eqls([
552
+ "tuple",
553
+ 2,
554
+ 21,
555
+ -8,
556
+ ]);
557
+ expect(stateVariables[mathrNames[11]].stateValues.value).eqls([
558
+ "tuple",
559
+ 2,
560
+ 1,
561
+ 2,
562
+ ]);
563
+ expect(stateVariables[mathrNames[12]].stateValues.value).eqls([
564
+ "tuple",
565
+ 2,
566
+ 23,
567
+ -5,
568
+ ]);
569
+ expect(stateVariables[mathrNames[13]].stateValues.value).eqls([
570
+ "tuple",
571
+ 2,
572
+ 2,
573
+ 1,
574
+ ]);
575
+ expect(stateVariables[mathrNames[14]].stateValues.value).eqls([
576
+ "tuple",
577
+ 2,
578
+ 23,
579
+ -8,
580
+ ]);
581
+ expect(stateVariables[mathrNames[15]].stateValues.value).eqls([
582
+ "tuple",
583
+ 2,
584
+ 2,
585
+ 2,
586
+ ]);
587
+ expect(stateVariables[mathrNames[16]].stateValues.value).eqls([
588
+ "tuple",
589
+ 3,
590
+ 21,
591
+ -5,
592
+ ]);
593
+ expect(stateVariables[mathrNames[17]].stateValues.value).eqls([
594
+ "tuple",
595
+ 3,
596
+ 1,
597
+ 1,
598
+ ]);
599
+ expect(stateVariables[mathrNames[18]].stateValues.value).eqls([
600
+ "tuple",
601
+ 3,
602
+ 21,
603
+ -8,
604
+ ]);
605
+ expect(stateVariables[mathrNames[19]].stateValues.value).eqls([
606
+ "tuple",
607
+ 3,
608
+ 1,
609
+ 2,
610
+ ]);
611
+ expect(stateVariables[mathrNames[20]].stateValues.value).eqls([
612
+ "tuple",
613
+ 3,
614
+ 23,
615
+ -5,
616
+ ]);
617
+ expect(stateVariables[mathrNames[21]].stateValues.value).eqls([
618
+ "tuple",
619
+ 3,
620
+ 2,
621
+ 1,
622
+ ]);
623
+ expect(stateVariables[mathrNames[22]].stateValues.value).eqls([
624
+ "tuple",
625
+ 3,
626
+ 23,
627
+ -8,
628
+ ]);
629
+ expect(stateVariables[mathrNames[23]].stateValues.value).eqls([
630
+ "tuple",
631
+ 3,
632
+ 2,
633
+ 2,
634
+ ]);
635
+ });
636
+ });
637
+ });
638
+
639
+ it("two nested maps", () => {
640
+ cy.window().then(async (win) => {
641
+ win.postMessage(
642
+ {
643
+ doenetML: `
644
+ <text>a</text>
645
+ <aslist>
646
+ <map>
647
+ <template><map>
648
+ <template><math simplify>$m+$n</math><math simplify>$i+2$j</math></template>
649
+ <sources alias="m" indexalias="i"><sequence from="1" to="2"/></sources>
650
+ </map></template>
651
+ <sources alias="n" indexalias="j"><number>-10</number><number>5</number></sources>
652
+ </map>
653
+ </aslist>
654
+ `,
655
+ },
656
+ "*",
657
+ );
658
+ });
659
+
660
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
661
+ cy.window().then(async (win) => {
662
+ let stateVariables = await win.returnAllStateVariables1();
663
+ let replacements = stateVariables["/_map1"].replacements;
664
+ let mathrNames = replacements.reduce(
665
+ (a, c) => [
666
+ ...a,
667
+ ...stateVariables[
668
+ stateVariables[c.componentName].replacements[0].componentName
669
+ ].replacements.reduce(
670
+ (a1, c1) => [
671
+ ...a1,
672
+ ...stateVariables[c1.componentName].replacements.map(
673
+ (x) => x.componentName,
674
+ ),
675
+ ],
676
+ [],
677
+ ),
678
+ ],
679
+ [],
680
+ );
681
+ let mathrAnchors = mathrNames.map((x) => cesc2("#" + x));
682
+
683
+ cy.log("Test values displayed in browser");
684
+ cy.get(`${mathrAnchors[0]} .mjx-mrow`)
685
+ .eq(0)
686
+ .invoke("text")
687
+ .then((text) => {
688
+ expect(text.trim()).equal("−9");
689
+ });
690
+ cy.get(`${mathrAnchors[1]} .mjx-mrow`)
691
+ .eq(0)
692
+ .invoke("text")
693
+ .then((text) => {
694
+ expect(text.trim()).equal("3");
695
+ });
696
+ cy.get(`${mathrAnchors[2]} .mjx-mrow`)
697
+ .eq(0)
698
+ .invoke("text")
699
+ .then((text) => {
700
+ expect(text.trim()).equal("−8");
701
+ });
702
+ cy.get(`${mathrAnchors[3]} .mjx-mrow`)
703
+ .eq(0)
704
+ .invoke("text")
705
+ .then((text) => {
706
+ expect(text.trim()).equal("4");
707
+ });
708
+ cy.get(`${mathrAnchors[4]} .mjx-mrow`)
709
+ .eq(0)
710
+ .invoke("text")
711
+ .then((text) => {
712
+ expect(text.trim()).equal("6");
713
+ });
714
+ cy.get(`${mathrAnchors[5]} .mjx-mrow`)
715
+ .eq(0)
716
+ .invoke("text")
717
+ .then((text) => {
718
+ expect(text.trim()).equal("5");
719
+ });
720
+ cy.get(`${mathrAnchors[6]} .mjx-mrow`)
721
+ .eq(0)
722
+ .invoke("text")
723
+ .then((text) => {
724
+ expect(text.trim()).equal("7");
725
+ });
726
+ cy.get(`${mathrAnchors[7]} .mjx-mrow`)
727
+ .eq(0)
728
+ .invoke("text")
729
+ .then((text) => {
730
+ expect(text.trim()).equal("6");
731
+ });
732
+
733
+ cy.log("Test internal values are set to the correct values");
734
+ cy.window().then(() => {
735
+ expect(stateVariables[mathrNames[0]].stateValues.value).eq(-9);
736
+ expect(stateVariables[mathrNames[1]].stateValues.value).eq(3);
737
+ expect(stateVariables[mathrNames[2]].stateValues.value).eq(-8);
738
+ expect(stateVariables[mathrNames[3]].stateValues.value).eq(4);
739
+ expect(stateVariables[mathrNames[4]].stateValues.value).eq(6);
740
+ expect(stateVariables[mathrNames[5]].stateValues.value).eq(5);
741
+ expect(stateVariables[mathrNames[6]].stateValues.value).eq(7);
742
+ expect(stateVariables[mathrNames[7]].stateValues.value).eq(6);
743
+ });
744
+ });
745
+ });
746
+
747
+ it("three nested maps with graphs and copied", () => {
748
+ cy.window().then(async (win) => {
749
+ win.postMessage(
750
+ {
751
+ doenetML: `
752
+ <text>a</text>
753
+ <map>
754
+ <template><graph>
755
+ <map>
756
+ <template><map>
757
+ <template><point>($l+$n, $m)</point><point>($i+2*$k, $j)</point></template>
758
+ <sources alias="l" indexalias="i"><sequence from="1" to="2"/></sources>
759
+ </map></template>
760
+ <sources alias="m" indexalias="j"><sequence from="-5" to="5" step="10"/></sources>
761
+ </map>
762
+ </graph></template>
763
+ <sources alias="n" indexalias="k"><sequence from="-10" to="5" step="15"/></sources>
764
+ </map>
765
+ <copy name="mapcopy" target="_map1" />
766
+ `,
767
+ },
768
+ "*",
769
+ );
770
+ });
771
+
772
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
773
+
774
+ cy.log("Test internal values are set to the correct values");
775
+ cy.window().then(async (win) => {
776
+ let stateVariables = await win.returnAllStateVariables1();
777
+ let graphNames = stateVariables["/_map1"].replacements.map(
778
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
779
+ );
780
+ let graphChildNames = graphNames.map((x) =>
781
+ stateVariables[x].activeChildren.map((x) => x.componentName),
782
+ );
783
+ let graphNames2 = stateVariables["/mapcopy"].replacements.map(
784
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
785
+ );
786
+ let graph2ChildNames = graphNames2.map((x) =>
787
+ stateVariables[x].activeChildren.map((x) => x.componentName),
788
+ );
789
+
790
+ expect(
791
+ stateVariables[graphNames[0]].stateValues.graphicalDescendants.length,
792
+ ).eq(8);
793
+ expect(
794
+ stateVariables[graphNames[1]].stateValues.graphicalDescendants.length,
795
+ ).eq(8);
796
+ expect(
797
+ stateVariables[graphNames2[0]].stateValues.graphicalDescendants.length,
798
+ ).eq(8);
799
+ expect(
800
+ stateVariables[graphNames2[1]].stateValues.graphicalDescendants.length,
801
+ ).eq(8);
802
+
803
+ expect(stateVariables[graphChildNames[0][0]].stateValues.xs[0]).eq(-9);
804
+ expect(stateVariables[graphChildNames[0][0]].stateValues.xs[1]).eq(-5);
805
+ expect(stateVariables[graphChildNames[0][1]].stateValues.xs[0]).eq(3);
806
+ expect(stateVariables[graphChildNames[0][1]].stateValues.xs[1]).eq(1);
807
+ expect(stateVariables[graphChildNames[0][2]].stateValues.xs[0]).eq(-8);
808
+ expect(stateVariables[graphChildNames[0][2]].stateValues.xs[1]).eq(-5);
809
+ expect(stateVariables[graphChildNames[0][3]].stateValues.xs[0]).eq(4);
810
+ expect(stateVariables[graphChildNames[0][3]].stateValues.xs[1]).eq(1);
811
+ expect(stateVariables[graphChildNames[0][4]].stateValues.xs[0]).eq(-9);
812
+ expect(stateVariables[graphChildNames[0][4]].stateValues.xs[1]).eq(5);
813
+ expect(stateVariables[graphChildNames[0][5]].stateValues.xs[0]).eq(3);
814
+ expect(stateVariables[graphChildNames[0][5]].stateValues.xs[1]).eq(2);
815
+ expect(stateVariables[graphChildNames[0][6]].stateValues.xs[0]).eq(-8);
816
+ expect(stateVariables[graphChildNames[0][6]].stateValues.xs[1]).eq(5);
817
+ expect(stateVariables[graphChildNames[0][7]].stateValues.xs[0]).eq(4);
818
+ expect(stateVariables[graphChildNames[0][7]].stateValues.xs[1]).eq(2);
819
+
820
+ expect(stateVariables[graphChildNames[1][0]].stateValues.xs[0]).eq(6);
821
+ expect(stateVariables[graphChildNames[1][0]].stateValues.xs[1]).eq(-5);
822
+ expect(stateVariables[graphChildNames[1][1]].stateValues.xs[0]).eq(5);
823
+ expect(stateVariables[graphChildNames[1][1]].stateValues.xs[1]).eq(1);
824
+ expect(stateVariables[graphChildNames[1][2]].stateValues.xs[0]).eq(7);
825
+ expect(stateVariables[graphChildNames[1][2]].stateValues.xs[1]).eq(-5);
826
+ expect(stateVariables[graphChildNames[1][3]].stateValues.xs[0]).eq(6);
827
+ expect(stateVariables[graphChildNames[1][3]].stateValues.xs[1]).eq(1);
828
+ expect(stateVariables[graphChildNames[1][4]].stateValues.xs[0]).eq(6);
829
+ expect(stateVariables[graphChildNames[1][4]].stateValues.xs[1]).eq(5);
830
+ expect(stateVariables[graphChildNames[1][5]].stateValues.xs[0]).eq(5);
831
+ expect(stateVariables[graphChildNames[1][5]].stateValues.xs[1]).eq(2);
832
+ expect(stateVariables[graphChildNames[1][6]].stateValues.xs[0]).eq(7);
833
+ expect(stateVariables[graphChildNames[1][6]].stateValues.xs[1]).eq(5);
834
+ expect(stateVariables[graphChildNames[1][7]].stateValues.xs[0]).eq(6);
835
+ expect(stateVariables[graphChildNames[1][7]].stateValues.xs[1]).eq(2);
836
+
837
+ expect(stateVariables[graph2ChildNames[0][0]].stateValues.xs[0]).eq(-9);
838
+ expect(stateVariables[graph2ChildNames[0][0]].stateValues.xs[1]).eq(-5);
839
+ expect(stateVariables[graph2ChildNames[0][1]].stateValues.xs[0]).eq(3);
840
+ expect(stateVariables[graph2ChildNames[0][1]].stateValues.xs[1]).eq(1);
841
+ expect(stateVariables[graph2ChildNames[0][2]].stateValues.xs[0]).eq(-8);
842
+ expect(stateVariables[graph2ChildNames[0][2]].stateValues.xs[1]).eq(-5);
843
+ expect(stateVariables[graph2ChildNames[0][3]].stateValues.xs[0]).eq(4);
844
+ expect(stateVariables[graph2ChildNames[0][3]].stateValues.xs[1]).eq(1);
845
+ expect(stateVariables[graph2ChildNames[0][4]].stateValues.xs[0]).eq(-9);
846
+ expect(stateVariables[graph2ChildNames[0][4]].stateValues.xs[1]).eq(5);
847
+ expect(stateVariables[graph2ChildNames[0][5]].stateValues.xs[0]).eq(3);
848
+ expect(stateVariables[graph2ChildNames[0][5]].stateValues.xs[1]).eq(2);
849
+ expect(stateVariables[graph2ChildNames[0][6]].stateValues.xs[0]).eq(-8);
850
+ expect(stateVariables[graph2ChildNames[0][6]].stateValues.xs[1]).eq(5);
851
+ expect(stateVariables[graph2ChildNames[0][7]].stateValues.xs[0]).eq(4);
852
+ expect(stateVariables[graph2ChildNames[0][7]].stateValues.xs[1]).eq(2);
853
+
854
+ expect(stateVariables[graph2ChildNames[1][0]].stateValues.xs[0]).eq(6);
855
+ expect(stateVariables[graph2ChildNames[1][0]].stateValues.xs[1]).eq(-5);
856
+ expect(stateVariables[graph2ChildNames[1][1]].stateValues.xs[0]).eq(5);
857
+ expect(stateVariables[graph2ChildNames[1][1]].stateValues.xs[1]).eq(1);
858
+ expect(stateVariables[graph2ChildNames[1][2]].stateValues.xs[0]).eq(7);
859
+ expect(stateVariables[graph2ChildNames[1][2]].stateValues.xs[1]).eq(-5);
860
+ expect(stateVariables[graph2ChildNames[1][3]].stateValues.xs[0]).eq(6);
861
+ expect(stateVariables[graph2ChildNames[1][3]].stateValues.xs[1]).eq(1);
862
+ expect(stateVariables[graph2ChildNames[1][4]].stateValues.xs[0]).eq(6);
863
+ expect(stateVariables[graph2ChildNames[1][4]].stateValues.xs[1]).eq(5);
864
+ expect(stateVariables[graph2ChildNames[1][5]].stateValues.xs[0]).eq(5);
865
+ expect(stateVariables[graph2ChildNames[1][5]].stateValues.xs[1]).eq(2);
866
+ expect(stateVariables[graph2ChildNames[1][6]].stateValues.xs[0]).eq(7);
867
+ expect(stateVariables[graph2ChildNames[1][6]].stateValues.xs[1]).eq(5);
868
+ expect(stateVariables[graph2ChildNames[1][7]].stateValues.xs[0]).eq(6);
869
+ expect(stateVariables[graph2ChildNames[1][7]].stateValues.xs[1]).eq(2);
870
+ });
871
+ });
872
+
873
+ it("three nested maps with graphs and assignnames", () => {
874
+ cy.window().then(async (win) => {
875
+ win.postMessage(
876
+ {
877
+ doenetML: `
878
+ <text>a</text>
879
+ <map assignnames="u v">
880
+ <template newNamespace>
881
+ <graph>
882
+ <map assignnames="u v">
883
+ <template newNamespace>
884
+ <map assignnames="u v">
885
+ <template newNamespace>
886
+ <point name="A">($l+$n, $m)</point>
887
+ </template>
888
+ <sources alias="l"><sequence from="1" to="2"/></sources>
889
+ </map>
890
+ </template>
891
+ <sources alias="m"><sequence from="-5" to="5" step="10"/></sources>
892
+ </map>
893
+ </graph>
894
+ </template>
895
+ <sources alias="n"><sequence from="-10" to="5" step="15"/></sources>
896
+ </map>
897
+ <copy assignNames="c1" prop="coords" target="/u/u/u/A" />
898
+ <copy assignNames="c2" prop="coords" target="/u/u/v/A" />
899
+ <copy assignNames="c3" prop="coords" target="/u/v/u/A" />
900
+ <copy assignNames="c4" prop="coords" target="/u/v/v/A" />
901
+ <copy assignNames="c5" prop="coords" target="/v/u/u/A" />
902
+ <copy assignNames="c6" prop="coords" target="/v/u/v/A" />
903
+ <copy assignNames="c7" prop="coords" target="/v/v/u/A" />
904
+ <copy assignNames="c8" prop="coords" target="/v/v/v/A" />
905
+ `,
906
+ },
907
+ "*",
908
+ );
909
+ });
910
+
911
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); // to wait for page to load
912
+
913
+ cy.log("Test values displayed in browser");
914
+ cy.get(cesc(`#\\/c1`) + ` .mjx-mrow`)
915
+ .eq(0)
916
+ .invoke("text")
917
+ .then((text) => {
918
+ expect(text.trim()).equal("(−9,−5)");
919
+ });
920
+ cy.get(cesc(`#\\/c2`) + ` .mjx-mrow`)
921
+ .eq(0)
922
+ .invoke("text")
923
+ .then((text) => {
924
+ expect(text.trim()).equal("(−8,−5)");
925
+ });
926
+ cy.get(cesc(`#\\/c3`) + ` .mjx-mrow`)
927
+ .eq(0)
928
+ .invoke("text")
929
+ .then((text) => {
930
+ expect(text.trim()).equal("(−9,5)");
931
+ });
932
+ cy.get(cesc(`#\\/c4`) + ` .mjx-mrow`)
933
+ .eq(0)
934
+ .invoke("text")
935
+ .then((text) => {
936
+ expect(text.trim()).equal("(−8,5)");
937
+ });
938
+ cy.get(cesc(`#\\/c5`) + ` .mjx-mrow`)
939
+ .eq(0)
940
+ .invoke("text")
941
+ .then((text) => {
942
+ expect(text.trim()).equal("(6,−5)");
943
+ });
944
+ cy.get(cesc(`#\\/c6`) + ` .mjx-mrow`)
945
+ .eq(0)
946
+ .invoke("text")
947
+ .then((text) => {
948
+ expect(text.trim()).equal("(7,−5)");
949
+ });
950
+ cy.get(cesc(`#\\/c7`) + ` .mjx-mrow`)
951
+ .eq(0)
952
+ .invoke("text")
953
+ .then((text) => {
954
+ expect(text.trim()).equal("(6,5)");
955
+ });
956
+ cy.get(cesc(`#\\/c8`) + ` .mjx-mrow`)
957
+ .eq(0)
958
+ .invoke("text")
959
+ .then((text) => {
960
+ expect(text.trim()).equal("(7,5)");
961
+ });
962
+
963
+ cy.log("Test internal values are set to the correct values");
964
+ cy.window().then(async (win) => {
965
+ let stateVariables = await win.returnAllStateVariables1();
966
+
967
+ expect(
968
+ stateVariables["/u/_graph1"].stateValues.graphicalDescendants.length,
969
+ ).eq(4);
970
+ expect(
971
+ stateVariables["/v/_graph1"].stateValues.graphicalDescendants.length,
972
+ ).eq(4);
973
+ expect(stateVariables["/u/u/u/A"].stateValues.xs[0]).eq(-9);
974
+ expect(stateVariables["/u/u/u/A"].stateValues.xs[1]).eq(-5);
975
+ expect(stateVariables["/u/u/v/A"].stateValues.xs[0]).eq(-8);
976
+ expect(stateVariables["/u/u/v/A"].stateValues.xs[1]).eq(-5);
977
+ expect(stateVariables["/u/v/u/A"].stateValues.xs[0]).eq(-9);
978
+ expect(stateVariables["/u/v/u/A"].stateValues.xs[1]).eq(5);
979
+ expect(stateVariables["/u/v/v/A"].stateValues.xs[0]).eq(-8);
980
+ expect(stateVariables["/u/v/v/A"].stateValues.xs[1]).eq(5);
981
+ expect(stateVariables["/v/u/u/A"].stateValues.xs[0]).eq(6);
982
+ expect(stateVariables["/v/u/u/A"].stateValues.xs[1]).eq(-5);
983
+ expect(stateVariables["/v/u/v/A"].stateValues.xs[0]).eq(7);
984
+ expect(stateVariables["/v/u/v/A"].stateValues.xs[1]).eq(-5);
985
+ expect(stateVariables["/v/v/u/A"].stateValues.xs[0]).eq(6);
986
+ expect(stateVariables["/v/v/u/A"].stateValues.xs[1]).eq(5);
987
+ expect(stateVariables["/v/v/v/A"].stateValues.xs[0]).eq(7);
988
+ expect(stateVariables["/v/v/v/A"].stateValues.xs[1]).eq(5);
989
+ });
990
+ });
991
+
992
+ it("combination map nested inside map with graphs", () => {
993
+ cy.window().then(async (win) => {
994
+ win.postMessage(
995
+ {
996
+ doenetML: `
997
+ <text>a</text>
998
+ <map>
999
+ <template><graph>
1000
+ <map behavior="combination">
1001
+ <template><point>($l+$n, $m)</point></template>
1002
+ <sources alias="l"><sequence from="1" to="2"/></sources>
1003
+ <sources alias="m"><sequence from="-5" to="5" step="10"/></sources>
1004
+ </map>
1005
+ </graph></template>
1006
+ <sources alias="n"><sequence from="-10" to="5" step="15"/></sources>
1007
+ </map>
1008
+ `,
1009
+ },
1010
+ "*",
1011
+ );
1012
+ });
1013
+
1014
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1015
+ cy.log("Test internal values are set to the correct values");
1016
+ cy.window().then(async (win) => {
1017
+ let stateVariables = await win.returnAllStateVariables1();
1018
+ let graphNames = stateVariables["/_map1"].replacements.map(
1019
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1020
+ );
1021
+ let graphChildNames = graphNames.map((x) =>
1022
+ stateVariables[x].activeChildren.map((x) => x.componentName),
1023
+ );
1024
+
1025
+ expect(
1026
+ stateVariables[graphNames[0]].stateValues.graphicalDescendants.length,
1027
+ ).eq(4);
1028
+ expect(
1029
+ stateVariables[graphNames[1]].stateValues.graphicalDescendants.length,
1030
+ ).eq(4);
1031
+ expect(stateVariables[graphChildNames[0][0]].stateValues.xs[0]).eq(-9);
1032
+ expect(stateVariables[graphChildNames[0][0]].stateValues.xs[1]).eq(-5);
1033
+ expect(stateVariables[graphChildNames[0][1]].stateValues.xs[0]).eq(-9);
1034
+ expect(stateVariables[graphChildNames[0][1]].stateValues.xs[1]).eq(5);
1035
+ expect(stateVariables[graphChildNames[0][2]].stateValues.xs[0]).eq(-8);
1036
+ expect(stateVariables[graphChildNames[0][2]].stateValues.xs[1]).eq(-5);
1037
+ expect(stateVariables[graphChildNames[0][3]].stateValues.xs[0]).eq(-8);
1038
+ expect(stateVariables[graphChildNames[0][3]].stateValues.xs[1]).eq(5);
1039
+
1040
+ expect(stateVariables[graphChildNames[1][0]].stateValues.xs[0]).eq(6);
1041
+ expect(stateVariables[graphChildNames[1][0]].stateValues.xs[1]).eq(-5);
1042
+ expect(stateVariables[graphChildNames[1][1]].stateValues.xs[0]).eq(6);
1043
+ expect(stateVariables[graphChildNames[1][1]].stateValues.xs[1]).eq(5);
1044
+ expect(stateVariables[graphChildNames[1][2]].stateValues.xs[0]).eq(7);
1045
+ expect(stateVariables[graphChildNames[1][2]].stateValues.xs[1]).eq(-5);
1046
+ expect(stateVariables[graphChildNames[1][3]].stateValues.xs[0]).eq(7);
1047
+ expect(stateVariables[graphChildNames[1][3]].stateValues.xs[1]).eq(5);
1048
+ });
1049
+ });
1050
+
1051
+ it("map with copies", () => {
1052
+ cy.window().then(async (win) => {
1053
+ win.postMessage(
1054
+ {
1055
+ doenetML: `
1056
+ <text>a</text>
1057
+ <map>
1058
+ <template newNamespace><math simplify>
1059
+ <copy target="n" name="b"/> + <copy target="j" name="i"/> + <copy target="../a" />
1060
+ + <math name="q">z</math> + <copy target="q" /> + <copy target="b" /> +<copy target="i" />
1061
+ </math><math>x</math></template>
1062
+ <sources alias="n" indexalias="j"><sequence from="1" to="2"/></sources>
1063
+ </map>
1064
+ <math name="a">x</math>
1065
+ <copy name="mapcopy" target="_map1" />
1066
+ `,
1067
+ },
1068
+ "*",
1069
+ );
1070
+ });
1071
+
1072
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1073
+ cy.window().then(async (win) => {
1074
+ let stateVariables = await win.returnAllStateVariables1();
1075
+ let replacementNames = stateVariables["/_map1"].replacements.reduce(
1076
+ (a, c) => [
1077
+ ...a,
1078
+ ...stateVariables[c.componentName].replacements.map(
1079
+ (x) => x.componentName,
1080
+ ),
1081
+ ],
1082
+ [],
1083
+ );
1084
+ let replacementAnchors = replacementNames.map((x) => cesc2("#" + x));
1085
+ let replacementNames2 = stateVariables["/mapcopy"].replacements.reduce(
1086
+ (a, c) => [
1087
+ ...a,
1088
+ ...stateVariables[c.componentName].replacements.map(
1089
+ (x) => x.componentName,
1090
+ ),
1091
+ ],
1092
+ [],
1093
+ );
1094
+ let replacementAnchors2 = replacementNames2.map((x) => cesc2("#" + x));
1095
+
1096
+ cy.log("Test values displayed in browser");
1097
+ cy.get(`${replacementAnchors[0]} .mjx-mrow`)
1098
+ .eq(0)
1099
+ .invoke("text")
1100
+ .then((text) => {
1101
+ expect(text.trim()).equal("x+2z+4");
1102
+ });
1103
+ cy.get(`${replacementAnchors[1]} .mjx-mrow`)
1104
+ .eq(0)
1105
+ .invoke("text")
1106
+ .then((text) => {
1107
+ expect(text.trim()).equal("x");
1108
+ });
1109
+ cy.get(`${replacementAnchors[2]} .mjx-mrow`)
1110
+ .eq(0)
1111
+ .invoke("text")
1112
+ .then((text) => {
1113
+ expect(text.trim()).equal("x+2z+8");
1114
+ });
1115
+ cy.get(`${replacementAnchors[3]} .mjx-mrow`)
1116
+ .eq(0)
1117
+ .invoke("text")
1118
+ .then((text) => {
1119
+ expect(text.trim()).equal("x");
1120
+ });
1121
+
1122
+ cy.get(`${cesc2("#/a")} .mjx-mrow`)
1123
+ .eq(0)
1124
+ .invoke("text")
1125
+ .then((text) => {
1126
+ expect(text.trim()).equal("x");
1127
+ });
1128
+
1129
+ cy.get(`${replacementAnchors2[0]} .mjx-mrow`)
1130
+ .eq(0)
1131
+ .invoke("text")
1132
+ .then((text) => {
1133
+ expect(text.trim()).equal("x+2z+4");
1134
+ });
1135
+ cy.get(`${replacementAnchors2[1]} .mjx-mrow`)
1136
+ .eq(0)
1137
+ .invoke("text")
1138
+ .then((text) => {
1139
+ expect(text.trim()).equal("x");
1140
+ });
1141
+ cy.get(`${replacementAnchors2[2]} .mjx-mrow`)
1142
+ .eq(0)
1143
+ .invoke("text")
1144
+ .then((text) => {
1145
+ expect(text.trim()).equal("x+2z+8");
1146
+ });
1147
+ cy.get(`${replacementAnchors2[3]} .mjx-mrow`)
1148
+ .eq(0)
1149
+ .invoke("text")
1150
+ .then((text) => {
1151
+ expect(text.trim()).equal("x");
1152
+ });
1153
+ });
1154
+ });
1155
+
1156
+ it("map with copies, extended dynamically", () => {
1157
+ cy.window().then(async (win) => {
1158
+ win.postMessage(
1159
+ {
1160
+ doenetML: `
1161
+ <text>a</text>
1162
+ <number name="length">1</number>
1163
+ <map>
1164
+ <template newnamespace><math simplify>
1165
+ <copy target="n" name="b"/> + <copy target="j" name="i"/> + <copy target="../a" />
1166
+ + <math name="q">z</math> + <copy target="q" /> + <copy target="b" /> +<copy target="i" />
1167
+ </math><math>x</math></template>
1168
+ <sources alias="n" indexalias="j"><sequence from="1" length="$length"/></sources>
1169
+ </map>
1170
+ <math name="a">x</math>
1171
+ <copy name="mapcopy" target="_map1" />
1172
+
1173
+ <updatevalue target="length" newValue="2$length" >
1174
+ <label>double</label>
1175
+ </updatevalue>
1176
+ `,
1177
+ },
1178
+ "*",
1179
+ );
1180
+ });
1181
+
1182
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1183
+ cy.window().then(async (win) => {
1184
+ let stateVariables = await win.returnAllStateVariables1();
1185
+ let replacementNames = stateVariables["/_map1"].replacements.reduce(
1186
+ (a, c) => [
1187
+ ...a,
1188
+ ...stateVariables[c.componentName].replacements.map(
1189
+ (x) => x.componentName,
1190
+ ),
1191
+ ],
1192
+ [],
1193
+ );
1194
+ let replacementAnchors = replacementNames.map((x) => cesc2("#" + x));
1195
+ let replacementNames2 = stateVariables["/mapcopy"].replacements.reduce(
1196
+ (a, c) => [
1197
+ ...a,
1198
+ ...stateVariables[c.componentName].replacements.map(
1199
+ (x) => x.componentName,
1200
+ ),
1201
+ ],
1202
+ [],
1203
+ );
1204
+ let replacementAnchors2 = replacementNames2.map((x) => cesc2("#" + x));
1205
+
1206
+ cy.log("Test values displayed in browser");
1207
+ cy.get(`${replacementAnchors[0]} .mjx-mrow`)
1208
+ .eq(0)
1209
+ .invoke("text")
1210
+ .then((text) => {
1211
+ expect(text.trim()).equal("x+2z+4");
1212
+ });
1213
+ cy.get(`${replacementAnchors[1]} .mjx-mrow`)
1214
+ .eq(0)
1215
+ .invoke("text")
1216
+ .then((text) => {
1217
+ expect(text.trim()).equal("x");
1218
+ });
1219
+ cy.get(`${cesc2("#/a")} .mjx-mrow`)
1220
+ .eq(0)
1221
+ .invoke("text")
1222
+ .then((text) => {
1223
+ expect(text.trim()).equal("x");
1224
+ });
1225
+ cy.get(`${replacementAnchors2[0]} .mjx-mrow`)
1226
+ .eq(0)
1227
+ .invoke("text")
1228
+ .then((text) => {
1229
+ expect(text.trim()).equal("x+2z+4");
1230
+ });
1231
+ cy.get(`${replacementAnchors2[1]} .mjx-mrow`)
1232
+ .eq(0)
1233
+ .invoke("text")
1234
+ .then((text) => {
1235
+ expect(text.trim()).equal("x");
1236
+ });
1237
+ });
1238
+
1239
+ cy.log("Double the length then test again");
1240
+ cy.get(cesc2("#/_updatevalue1_button")).click(); //Update Button
1241
+ cy.get(cesc2("#/length")).should("contain.text", "2");
1242
+
1243
+ cy.window().then(async (win) => {
1244
+ let stateVariables = await win.returnAllStateVariables1();
1245
+ let replacementNames = stateVariables["/_map1"].replacements.reduce(
1246
+ (a, c) => [
1247
+ ...a,
1248
+ ...stateVariables[c.componentName].replacements.map(
1249
+ (x) => x.componentName,
1250
+ ),
1251
+ ],
1252
+ [],
1253
+ );
1254
+ let replacementAnchors = replacementNames.map((x) => cesc2("#" + x));
1255
+ let replacementNames2 = stateVariables["/mapcopy"].replacements.reduce(
1256
+ (a, c) => [
1257
+ ...a,
1258
+ ...stateVariables[c.componentName].replacements.map(
1259
+ (x) => x.componentName,
1260
+ ),
1261
+ ],
1262
+ [],
1263
+ );
1264
+ let replacementAnchors2 = replacementNames2.map((x) => cesc2("#" + x));
1265
+
1266
+ cy.get(`${replacementAnchors[0]} .mjx-mrow`)
1267
+ .eq(0)
1268
+ .invoke("text")
1269
+ .then((text) => {
1270
+ expect(text.trim()).equal("x+2z+4");
1271
+ });
1272
+ cy.get(`${replacementAnchors[1]} .mjx-mrow`)
1273
+ .eq(0)
1274
+ .invoke("text")
1275
+ .then((text) => {
1276
+ expect(text.trim()).equal("x");
1277
+ });
1278
+ cy.get(`${replacementAnchors[2]} .mjx-mrow`)
1279
+ .eq(0)
1280
+ .invoke("text")
1281
+ .then((text) => {
1282
+ expect(text.trim()).equal("x+2z+8");
1283
+ });
1284
+ cy.get(`${replacementAnchors[3]} .mjx-mrow`)
1285
+ .eq(0)
1286
+ .invoke("text")
1287
+ .then((text) => {
1288
+ expect(text.trim()).equal("x");
1289
+ });
1290
+ cy.get(`${cesc2("#/a")} .mjx-mrow`)
1291
+ .eq(0)
1292
+ .invoke("text")
1293
+ .then((text) => {
1294
+ expect(text.trim()).equal("x");
1295
+ });
1296
+ cy.get(`${replacementAnchors2[0]} .mjx-mrow`)
1297
+ .eq(0)
1298
+ .invoke("text")
1299
+ .then((text) => {
1300
+ expect(text.trim()).equal("x+2z+4");
1301
+ });
1302
+ cy.get(`${replacementAnchors2[1]} .mjx-mrow`)
1303
+ .eq(0)
1304
+ .invoke("text")
1305
+ .then((text) => {
1306
+ expect(text.trim()).equal("x");
1307
+ });
1308
+ cy.get(`${replacementAnchors2[2]} .mjx-mrow`)
1309
+ .eq(0)
1310
+ .invoke("text")
1311
+ .then((text) => {
1312
+ expect(text.trim()).equal("x+2z+8");
1313
+ });
1314
+ cy.get(`${replacementAnchors2[3]} .mjx-mrow`)
1315
+ .eq(0)
1316
+ .invoke("text")
1317
+ .then((text) => {
1318
+ expect(text.trim()).equal("x");
1319
+ });
1320
+ });
1321
+
1322
+ cy.log("Double the length again then test one more time");
1323
+ cy.get(cesc2("#/_updatevalue1_button")).click(); //Update Button
1324
+ cy.get(cesc2("#/length")).should("contain.text", "4");
1325
+
1326
+ cy.window().then(async (win) => {
1327
+ let stateVariables = await win.returnAllStateVariables1();
1328
+ let replacementNames = stateVariables["/_map1"].replacements.reduce(
1329
+ (a, c) => [
1330
+ ...a,
1331
+ ...stateVariables[c.componentName].replacements.map(
1332
+ (x) => x.componentName,
1333
+ ),
1334
+ ],
1335
+ [],
1336
+ );
1337
+ let replacementAnchors = replacementNames.map((x) => cesc2("#" + x));
1338
+ let replacementNames2 = stateVariables["/mapcopy"].replacements.reduce(
1339
+ (a, c) => [
1340
+ ...a,
1341
+ ...stateVariables[c.componentName].replacements.map(
1342
+ (x) => x.componentName,
1343
+ ),
1344
+ ],
1345
+ [],
1346
+ );
1347
+ let replacementAnchors2 = replacementNames2.map((x) => cesc2("#" + x));
1348
+
1349
+ cy.get(`${replacementAnchors[0]} .mjx-mrow`)
1350
+ .eq(0)
1351
+ .invoke("text")
1352
+ .then((text) => {
1353
+ expect(text.trim()).equal("x+2z+4");
1354
+ });
1355
+ cy.get(`${replacementAnchors[1]} .mjx-mrow`)
1356
+ .eq(0)
1357
+ .invoke("text")
1358
+ .then((text) => {
1359
+ expect(text.trim()).equal("x");
1360
+ });
1361
+ cy.get(`${replacementAnchors[2]} .mjx-mrow`)
1362
+ .eq(0)
1363
+ .invoke("text")
1364
+ .then((text) => {
1365
+ expect(text.trim()).equal("x+2z+8");
1366
+ });
1367
+ cy.get(`${replacementAnchors[3]} .mjx-mrow`)
1368
+ .eq(0)
1369
+ .invoke("text")
1370
+ .then((text) => {
1371
+ expect(text.trim()).equal("x");
1372
+ });
1373
+ cy.get(`${replacementAnchors[4]} .mjx-mrow`)
1374
+ .eq(0)
1375
+ .invoke("text")
1376
+ .then((text) => {
1377
+ expect(text.trim()).equal("x+2z+12");
1378
+ });
1379
+ cy.get(`${replacementAnchors[5]} .mjx-mrow`)
1380
+ .eq(0)
1381
+ .invoke("text")
1382
+ .then((text) => {
1383
+ expect(text.trim()).equal("x");
1384
+ });
1385
+ cy.get(`${replacementAnchors[6]} .mjx-mrow`)
1386
+ .eq(0)
1387
+ .invoke("text")
1388
+ .then((text) => {
1389
+ expect(text.trim()).equal("x+2z+16");
1390
+ });
1391
+ cy.get(`${replacementAnchors[7]} .mjx-mrow`)
1392
+ .eq(0)
1393
+ .invoke("text")
1394
+ .then((text) => {
1395
+ expect(text.trim()).equal("x");
1396
+ });
1397
+ cy.get(`${cesc2("#/a")} .mjx-mrow`)
1398
+ .eq(0)
1399
+ .invoke("text")
1400
+ .then((text) => {
1401
+ expect(text.trim()).equal("x");
1402
+ });
1403
+ cy.get(`${replacementAnchors2[0]} .mjx-mrow`)
1404
+ .eq(0)
1405
+ .invoke("text")
1406
+ .then((text) => {
1407
+ expect(text.trim()).equal("x+2z+4");
1408
+ });
1409
+ cy.get(`${replacementAnchors2[1]} .mjx-mrow`)
1410
+ .eq(0)
1411
+ .invoke("text")
1412
+ .then((text) => {
1413
+ expect(text.trim()).equal("x");
1414
+ });
1415
+ cy.get(`${replacementAnchors2[2]} .mjx-mrow`)
1416
+ .eq(0)
1417
+ .invoke("text")
1418
+ .then((text) => {
1419
+ expect(text.trim()).equal("x+2z+8");
1420
+ });
1421
+ cy.get(`${replacementAnchors2[3]} .mjx-mrow`)
1422
+ .eq(0)
1423
+ .invoke("text")
1424
+ .then((text) => {
1425
+ expect(text.trim()).equal("x");
1426
+ });
1427
+ cy.get(`${replacementAnchors2[4]} .mjx-mrow`)
1428
+ .eq(0)
1429
+ .invoke("text")
1430
+ .then((text) => {
1431
+ expect(text.trim()).equal("x+2z+12");
1432
+ });
1433
+ cy.get(`${replacementAnchors2[5]} .mjx-mrow`)
1434
+ .eq(0)
1435
+ .invoke("text")
1436
+ .then((text) => {
1437
+ expect(text.trim()).equal("x");
1438
+ });
1439
+ cy.get(`${replacementAnchors2[6]} .mjx-mrow`)
1440
+ .eq(0)
1441
+ .invoke("text")
1442
+ .then((text) => {
1443
+ expect(text.trim()).equal("x+2z+16");
1444
+ });
1445
+ cy.get(`${replacementAnchors2[7]} .mjx-mrow`)
1446
+ .eq(0)
1447
+ .invoke("text")
1448
+ .then((text) => {
1449
+ expect(text.trim()).equal("x");
1450
+ });
1451
+ });
1452
+ });
1453
+
1454
+ it("map with copied template", () => {
1455
+ cy.window().then(async (win) => {
1456
+ win.postMessage(
1457
+ {
1458
+ doenetML: `
1459
+ <text>a</text>
1460
+ <map>
1461
+ <template><math simplify="full">sin(<copy target="i"/><copy target="x"/>)</math></template>
1462
+ <sources alias="x" indexalias="i"><math>x</math><math>y</math></sources>
1463
+ </map>
1464
+
1465
+ <map>
1466
+ <copy target="_template1" />
1467
+ <sources alias="x" indexalias="i"><math>q</math><math>p</math></sources>
1468
+ </map>
1469
+
1470
+ <copy name="mapcopy" target="_map2" />
1471
+ `,
1472
+ },
1473
+ "*",
1474
+ );
1475
+ });
1476
+
1477
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1478
+ cy.window().then(async (win) => {
1479
+ let stateVariables = await win.returnAllStateVariables1();
1480
+ let replacementNames = stateVariables["/_map1"].replacements.map(
1481
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1482
+ );
1483
+ let replacementAnchors = replacementNames.map((x) => cesc2("#" + x));
1484
+ let replacementNames2 = stateVariables["/_map2"].replacements.map(
1485
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1486
+ );
1487
+ let replacementAnchors2 = replacementNames2.map((x) => cesc2("#" + x));
1488
+ let replacementNames3 = stateVariables["/mapcopy"].replacements.map(
1489
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1490
+ );
1491
+ let replacementAnchors3 = replacementNames3.map((x) => cesc2("#" + x));
1492
+
1493
+ cy.log("Test values displayed in browser");
1494
+ cy.get(`${replacementAnchors[0]} .mjx-mrow`)
1495
+ .eq(0)
1496
+ .invoke("text")
1497
+ .then((text) => {
1498
+ expect(text.trim()).equal("sin(x)");
1499
+ });
1500
+ cy.get(`${replacementAnchors[1]} .mjx-mrow`)
1501
+ .eq(0)
1502
+ .invoke("text")
1503
+ .then((text) => {
1504
+ expect(text.trim()).equal("sin(2y)");
1505
+ });
1506
+ cy.get(`${replacementAnchors2[0]} .mjx-mrow`)
1507
+ .eq(0)
1508
+ .invoke("text")
1509
+ .then((text) => {
1510
+ expect(text.trim()).equal("sin(q)");
1511
+ });
1512
+ cy.get(`${replacementAnchors2[1]} .mjx-mrow`)
1513
+ .eq(0)
1514
+ .invoke("text")
1515
+ .then((text) => {
1516
+ expect(text.trim()).equal("sin(2p)");
1517
+ });
1518
+ cy.get(`${replacementAnchors3[0]} .mjx-mrow`)
1519
+ .eq(0)
1520
+ .invoke("text")
1521
+ .then((text) => {
1522
+ expect(text.trim()).equal("sin(q)");
1523
+ });
1524
+ cy.get(`${replacementAnchors3[1]} .mjx-mrow`)
1525
+ .eq(0)
1526
+ .invoke("text")
1527
+ .then((text) => {
1528
+ expect(text.trim()).equal("sin(2p)");
1529
+ });
1530
+ });
1531
+ });
1532
+
1533
+ it("map with new namespace but no new namespace on template", () => {
1534
+ cy.window().then(async (win) => {
1535
+ win.postMessage(
1536
+ {
1537
+ doenetML: `
1538
+ <text>a</text>
1539
+ <map newNamespace>
1540
+ <template><math simplify="full">sin($i$x)</math></template>
1541
+ <sources alias="x" indexalias="i"><math>x</math><math>y</math></sources>
1542
+ </map>
1543
+
1544
+ <copy name="mapcopy" target="_map1" />
1545
+ `,
1546
+ },
1547
+ "*",
1548
+ );
1549
+ });
1550
+
1551
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1552
+ cy.window().then(async (win) => {
1553
+ let stateVariables = await win.returnAllStateVariables1();
1554
+ let replacementNames = stateVariables["/_map1"].replacements.map(
1555
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1556
+ );
1557
+ let replacementAnchors = replacementNames.map((x) => cesc2("#" + x));
1558
+ let replacementNames2 = stateVariables["/mapcopy"].replacements.map(
1559
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1560
+ );
1561
+ let replacementAnchors2 = replacementNames2.map((x) => cesc2("#" + x));
1562
+
1563
+ cy.log("Test values displayed in browser");
1564
+ cy.get(`${replacementAnchors[0]} .mjx-mrow`)
1565
+ .eq(0)
1566
+ .invoke("text")
1567
+ .then((text) => {
1568
+ expect(text.trim()).equal("sin(x)");
1569
+ });
1570
+ cy.get(`${replacementAnchors[1]} .mjx-mrow`)
1571
+ .eq(0)
1572
+ .invoke("text")
1573
+ .then((text) => {
1574
+ expect(text.trim()).equal("sin(2y)");
1575
+ });
1576
+ cy.get(`${replacementAnchors2[0]} .mjx-mrow`)
1577
+ .eq(0)
1578
+ .invoke("text")
1579
+ .then((text) => {
1580
+ expect(text.trim()).equal("sin(x)");
1581
+ });
1582
+ cy.get(`${replacementAnchors2[1]} .mjx-mrow`)
1583
+ .eq(0)
1584
+ .invoke("text")
1585
+ .then((text) => {
1586
+ expect(text.trim()).equal("sin(2y)");
1587
+ });
1588
+ });
1589
+ });
1590
+
1591
+ it("graph with new namespace and assignnames", () => {
1592
+ cy.window().then(async (win) => {
1593
+ win.postMessage(
1594
+ {
1595
+ doenetML: `
1596
+ <text>a</text>
1597
+ <copy target="/hi/c/_point1" prop="coords" assignNames="c1" />
1598
+ <copy target="/hi/s/_point1" prop="coords" assignNames="c2" />
1599
+ <copy target="/hi/q/_point1" prop="coords" assignNames="c3" />
1600
+
1601
+ <grapH Name="hi" newNamespace >
1602
+ <map assignnames="q c s">
1603
+ <template newnamespace><point>($m, $n)</point></template>
1604
+ <sources alias="m"><sequence from="1" to="2"/></sources>
1605
+ <sources alias="n"><sequence from="-3" to="-2"/></sources>
1606
+ </map>
1607
+ </graph>
1608
+ `,
1609
+ },
1610
+ "*",
1611
+ );
1612
+ });
1613
+
1614
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1615
+
1616
+ cy.log("Test values displayed in browser");
1617
+
1618
+ cy.get(cesc(`#\\/c1`) + ` .mjx-mrow`)
1619
+ .eq(0)
1620
+ .invoke("text")
1621
+ .then((text) => {
1622
+ expect(text.trim()).equal("(1,−2)");
1623
+ });
1624
+ cy.get(cesc(`#\\/c2`) + ` .mjx-mrow`)
1625
+ .eq(0)
1626
+ .invoke("text")
1627
+ .then((text) => {
1628
+ expect(text.trim()).equal("(2,−3)");
1629
+ });
1630
+ cy.get(cesc(`#\\/c3`) + ` .mjx-mrow`)
1631
+ .eq(0)
1632
+ .invoke("text")
1633
+ .then((text) => {
1634
+ expect(text.trim()).equal("(1,−3)");
1635
+ });
1636
+
1637
+ cy.log("Test internal values are set to the correct values");
1638
+ cy.window().then(async (win) => {
1639
+ let stateVariables = await win.returnAllStateVariables1();
1640
+
1641
+ let replacementNames = stateVariables["/hi/_map1"].replacements.map(
1642
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1643
+ );
1644
+
1645
+ expect(stateVariables["/hi"].stateValues.graphicalDescendants.length).eq(
1646
+ 4,
1647
+ );
1648
+ expect(stateVariables["/hi/q/_point1"].stateValues.xs[0]).eq(1);
1649
+ expect(stateVariables["/hi/q/_point1"].stateValues.xs[1]).eq(-3);
1650
+ expect(stateVariables["/hi/c/_point1"].stateValues.xs[0]).eq(1);
1651
+ expect(stateVariables["/hi/c/_point1"].stateValues.xs[1]).eq(-2);
1652
+ expect(stateVariables["/hi/s/_point1"].stateValues.xs[0]).eq(2);
1653
+ expect(stateVariables["/hi/s/_point1"].stateValues.xs[1]).eq(-3);
1654
+ expect(stateVariables[replacementNames[3]].stateValues.xs[0]).eq(2);
1655
+ expect(stateVariables[replacementNames[3]].stateValues.xs[1]).eq(-2);
1656
+ });
1657
+ });
1658
+
1659
+ it("map copying source of other map", () => {
1660
+ cy.window().then(async (win) => {
1661
+ win.postMessage(
1662
+ {
1663
+ doenetML: `
1664
+ <text>a</text>
1665
+ <map assignnames="u v w">
1666
+ <template newNamespace><math>(<copy target="n"/>, <copy target="../e/_copy1" />)</math></template>
1667
+ <sources alias="n"><sequence from="1" to="3"/></sources>
1668
+ </map>
1669
+ <map assignnames="c d e">
1670
+ <template newNamespace><math>sin(<copy target="n"/>)</math></template>
1671
+ <sources alias="n"><sequence from="4" to="6"/></sources>
1672
+ </map>
1673
+ `,
1674
+ },
1675
+ "*",
1676
+ );
1677
+ });
1678
+
1679
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1680
+
1681
+ cy.log("Test values displayed in browser");
1682
+ cy.get(`${cesc2("#/u/_math1")} .mjx-mrow`)
1683
+ .eq(0)
1684
+ .invoke("text")
1685
+ .then((text) => {
1686
+ expect(text.trim()).equal("(1,6)");
1687
+ });
1688
+ cy.get(`${cesc2("#/v/_math1")} .mjx-mrow`)
1689
+ .eq(0)
1690
+ .invoke("text")
1691
+ .then((text) => {
1692
+ expect(text.trim()).equal("(2,6)");
1693
+ });
1694
+ cy.get(`${cesc2("#/w/_math1")} .mjx-mrow`)
1695
+ .eq(0)
1696
+ .invoke("text")
1697
+ .then((text) => {
1698
+ expect(text.trim()).equal("(3,6)");
1699
+ });
1700
+ cy.get(`${cesc2("#/c/_math1")} .mjx-mrow`)
1701
+ .eq(0)
1702
+ .invoke("text")
1703
+ .then((text) => {
1704
+ expect(text.trim()).equal("sin(4)");
1705
+ });
1706
+ cy.get(`${cesc2("#/d/_math1")} .mjx-mrow`)
1707
+ .eq(0)
1708
+ .invoke("text")
1709
+ .then((text) => {
1710
+ expect(text.trim()).equal("sin(5)");
1711
+ });
1712
+ cy.get(`${cesc2("#/e/_math1")} .mjx-mrow`)
1713
+ .eq(0)
1714
+ .invoke("text")
1715
+ .then((text) => {
1716
+ expect(text.trim()).equal("sin(6)");
1717
+ });
1718
+ });
1719
+
1720
+ it("map length depending on other map", () => {
1721
+ cy.window().then(async (win) => {
1722
+ win.postMessage(
1723
+ {
1724
+ doenetML: `
1725
+ <text>a</text>
1726
+ <map>
1727
+ <template><map>
1728
+ <template><math>($a, $b)</math></template>
1729
+ <sources alias="a"><sequence from="1" to="$b" /></sources>
1730
+ </map></template>
1731
+ <sources alias="b"><sequence from="1" to="3"/></sources>
1732
+ </map>
1733
+ `,
1734
+ },
1735
+ "*",
1736
+ );
1737
+ });
1738
+
1739
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1740
+ cy.window().then(async (win) => {
1741
+ let stateVariables = await win.returnAllStateVariables1();
1742
+ let replacementNames = stateVariables["/_map1"].replacements.map(
1743
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1744
+ );
1745
+ let replacementAnchors = replacementNames.map((x) =>
1746
+ stateVariables[x].replacements.map((y) =>
1747
+ cesc2(
1748
+ "#" + stateVariables[y.componentName].replacements[0].componentName,
1749
+ ),
1750
+ ),
1751
+ );
1752
+
1753
+ cy.log("Test values displayed in browser");
1754
+ cy.get(`${replacementAnchors[0][0]} .mjx-mrow`)
1755
+ .eq(0)
1756
+ .invoke("text")
1757
+ .then((text) => {
1758
+ expect(text.trim()).equal("(1,1)");
1759
+ });
1760
+ cy.get(`${replacementAnchors[1][0]} .mjx-mrow`)
1761
+ .eq(0)
1762
+ .invoke("text")
1763
+ .then((text) => {
1764
+ expect(text.trim()).equal("(1,2)");
1765
+ });
1766
+ cy.get(`${replacementAnchors[1][1]} .mjx-mrow`)
1767
+ .eq(0)
1768
+ .invoke("text")
1769
+ .then((text) => {
1770
+ expect(text.trim()).equal("(2,2)");
1771
+ });
1772
+ cy.get(`${replacementAnchors[2][0]} .mjx-mrow`)
1773
+ .eq(0)
1774
+ .invoke("text")
1775
+ .then((text) => {
1776
+ expect(text.trim()).equal("(1,3)");
1777
+ });
1778
+ cy.get(`${replacementAnchors[2][1]} .mjx-mrow`)
1779
+ .eq(0)
1780
+ .invoke("text")
1781
+ .then((text) => {
1782
+ expect(text.trim()).equal("(2,3)");
1783
+ });
1784
+ cy.get(`${replacementAnchors[2][2]} .mjx-mrow`)
1785
+ .eq(0)
1786
+ .invoke("text")
1787
+ .then((text) => {
1788
+ expect(text.trim()).equal("(3,3)");
1789
+ });
1790
+ });
1791
+ });
1792
+
1793
+ it("map begins zero length, copied multiple times", () => {
1794
+ cy.window().then(async (win) => {
1795
+ win.postMessage(
1796
+ {
1797
+ doenetML: `
1798
+ <text>a</text>
1799
+
1800
+ <p>
1801
+ <map>
1802
+ <template><math simplify>$n^2</math><text>,</text></template>
1803
+ <sources alias="n">
1804
+ <sequence from="$sequenceFrom" to="$sequenceTo" length="$sequenceCount" />
1805
+ </sources>
1806
+ </map>
1807
+ </p>
1808
+
1809
+ <mathinput name="sequenceFrom" prefill="1"/>
1810
+ <mathinput name="sequenceTo" prefill="2"/>
1811
+ <mathinput name="sequenceCount" prefill="0"/>
1812
+
1813
+ <p><copy name="copymap2" target="_map1" /></p>
1814
+ <p><copy name="copymap3" target="copymap2" /></p>
1815
+
1816
+ <copy name="copymapthroughp" target="_p1" />
1817
+ <copy name="copymapthroughp2" target="copymapthroughp" />
1818
+ <copy name="copymapthroughp3" target="copymapthroughp2" />
1819
+
1820
+ <copy prop="value" target="sequenceCount" assignNames="sequenceCount2" />
1821
+ <copy prop="value" target="sequenceTo" assignNames="sequenceTo2" />
1822
+ `,
1823
+ },
1824
+ "*",
1825
+ );
1826
+ });
1827
+
1828
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
1829
+ cy.window().then(async (win) => {
1830
+ let stateVariables = await win.returnAllStateVariables1();
1831
+ let p4 = stateVariables["/copymapthroughp"].replacements[0];
1832
+ let p4Anchor = cesc2("#" + p4.componentName);
1833
+ let p5 = stateVariables["/copymapthroughp2"].replacements[0];
1834
+ let p5Anchor = cesc2("#" + p5.componentName);
1835
+ let p6 = stateVariables["/copymapthroughp3"].replacements[0];
1836
+ let p6Anchor = cesc2("#" + p6.componentName);
1837
+
1838
+ cy.log("At beginning, nothing shown");
1839
+ cy.get(cesc2("#/_p1"))
1840
+ .invoke("text")
1841
+ .then((text) => {
1842
+ expect(text.trim()).equal("");
1843
+ });
1844
+ cy.get(cesc2("#/_p2"))
1845
+ .invoke("text")
1846
+ .then((text) => {
1847
+ expect(text.trim()).equal("");
1848
+ });
1849
+ cy.get(cesc2("#/_p3"))
1850
+ .invoke("text")
1851
+ .then((text) => {
1852
+ expect(text.trim()).equal("");
1853
+ });
1854
+ cy.get(p4Anchor)
1855
+ .invoke("text")
1856
+ .then((text) => {
1857
+ expect(text.trim()).equal("");
1858
+ });
1859
+ cy.get(p5Anchor)
1860
+ .invoke("text")
1861
+ .then((text) => {
1862
+ expect(text.trim()).equal("");
1863
+ });
1864
+ cy.get(p6Anchor)
1865
+ .invoke("text")
1866
+ .then((text) => {
1867
+ expect(text.trim()).equal("");
1868
+ });
1869
+
1870
+ cy.log("make sequence length 1");
1871
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
1872
+ "{end}{backspace}1{enter}",
1873
+ { force: true },
1874
+ );
1875
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "1");
1876
+
1877
+ cy.window().then(async (win) => {
1878
+ let stateVariables = await win.returnAllStateVariables1();
1879
+ let map1mathNames = stateVariables["/_map1"].replacements.map(
1880
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1881
+ );
1882
+ let map1mathAnchors = map1mathNames.map((x) => cesc2("#" + x));
1883
+ let map2mathNames = stateVariables["/copymap2"].replacements.map(
1884
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1885
+ );
1886
+ let map2mathAnchors = map2mathNames.map((x) => cesc2("#" + x));
1887
+ let map3mathNames = stateVariables["/copymap3"].replacements.map(
1888
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
1889
+ );
1890
+ let map3mathAnchors = map3mathNames.map((x) => cesc2("#" + x));
1891
+ let map4mathNames = stateVariables[
1892
+ stateVariables["/copymapthroughp"].replacements[0].componentName
1893
+ ].activeChildren
1894
+ .filter((x) => x.componentType === "math")
1895
+ .map((x) => x.componentName);
1896
+ let map4mathAnchors = map4mathNames.map((x) => cesc2("#" + x));
1897
+ let map5mathNames = stateVariables[
1898
+ stateVariables["/copymapthroughp2"].replacements[0].componentName
1899
+ ].activeChildren
1900
+ .filter((x) => x.componentType === "math")
1901
+ .map((x) => x.componentName);
1902
+ let map5mathAnchors = map5mathNames.map((x) => cesc2("#" + x));
1903
+ let map6mathNames = stateVariables[
1904
+ stateVariables["/copymapthroughp3"].replacements[0].componentName
1905
+ ].activeChildren
1906
+ .filter((x) => x.componentType === "math")
1907
+ .map((x) => x.componentName);
1908
+ let map6mathAnchors = map6mathNames.map((x) => cesc2("#" + x));
1909
+
1910
+ cy.get(cesc2("#/_p1"))
1911
+ .children(map1mathAnchors[0])
1912
+ .find(".mjx-mrow")
1913
+ .eq(0)
1914
+ .invoke("text")
1915
+ .then((text) => {
1916
+ expect(text.trim()).equal("1");
1917
+ });
1918
+ cy.get(cesc2("#/_p2"))
1919
+ .children(map2mathAnchors[0])
1920
+ .find(".mjx-mrow")
1921
+ .eq(0)
1922
+ .invoke("text")
1923
+ .then((text) => {
1924
+ expect(text.trim()).equal("1");
1925
+ });
1926
+ cy.get(cesc2("#/_p3"))
1927
+ .children(map3mathAnchors[0])
1928
+ .find(".mjx-mrow")
1929
+ .eq(0)
1930
+ .invoke("text")
1931
+ .then((text) => {
1932
+ expect(text.trim()).equal("1");
1933
+ });
1934
+ cy.get(p4Anchor)
1935
+ .children(map4mathAnchors[0])
1936
+ .find(".mjx-mrow")
1937
+ .eq(0)
1938
+ .invoke("text")
1939
+ .then((text) => {
1940
+ expect(text.trim()).equal("1");
1941
+ });
1942
+ cy.get(p5Anchor)
1943
+ .children(map5mathAnchors[0])
1944
+ .find(".mjx-mrow")
1945
+ .eq(0)
1946
+ .invoke("text")
1947
+ .then((text) => {
1948
+ expect(text.trim()).equal("1");
1949
+ });
1950
+ cy.get(p6Anchor)
1951
+ .children(map6mathAnchors[0])
1952
+ .find(".mjx-mrow")
1953
+ .eq(0)
1954
+ .invoke("text")
1955
+ .then((text) => {
1956
+ expect(text.trim()).equal("1");
1957
+ });
1958
+ });
1959
+
1960
+ cy.log("make sequence length 0 again");
1961
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
1962
+ "{end}{backspace}0{enter}",
1963
+ { force: true },
1964
+ );
1965
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "0");
1966
+
1967
+ cy.get(cesc2("#/_p1"))
1968
+ .invoke("text")
1969
+ .then((text) => {
1970
+ expect(text.trim()).equal("");
1971
+ });
1972
+ cy.get(cesc2("#/_p2"))
1973
+ .invoke("text")
1974
+ .then((text) => {
1975
+ expect(text.trim()).equal("");
1976
+ });
1977
+ cy.get(cesc2("#/_p3"))
1978
+ .invoke("text")
1979
+ .then((text) => {
1980
+ expect(text.trim()).equal("");
1981
+ });
1982
+ cy.get(p4Anchor)
1983
+ .invoke("text")
1984
+ .then((text) => {
1985
+ expect(text.trim()).equal("");
1986
+ });
1987
+ cy.get(p5Anchor)
1988
+ .invoke("text")
1989
+ .then((text) => {
1990
+ expect(text.trim()).equal("");
1991
+ });
1992
+ cy.get(p6Anchor)
1993
+ .invoke("text")
1994
+ .then((text) => {
1995
+ expect(text.trim()).equal("");
1996
+ });
1997
+
1998
+ cy.log("make sequence length 2");
1999
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
2000
+ "{end}{backspace}2{enter}",
2001
+ { force: true },
2002
+ );
2003
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "2");
2004
+
2005
+ cy.window().then(async (win) => {
2006
+ let stateVariables = await win.returnAllStateVariables1();
2007
+ let map1mathNames = stateVariables["/_map1"].replacements.map(
2008
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2009
+ );
2010
+ let map1mathAnchors = map1mathNames.map((x) => cesc2("#" + x));
2011
+ let map2mathNames = stateVariables["/copymap2"].replacements.map(
2012
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2013
+ );
2014
+ let map2mathAnchors = map2mathNames.map((x) => cesc2("#" + x));
2015
+ let map3mathNames = stateVariables["/copymap3"].replacements.map(
2016
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2017
+ );
2018
+ let map3mathAnchors = map3mathNames.map((x) => cesc2("#" + x));
2019
+ let map4mathNames = stateVariables[
2020
+ stateVariables["/copymapthroughp"].replacements[0].componentName
2021
+ ].activeChildren
2022
+ .filter((x) => x.componentType === "math")
2023
+ .map((x) => x.componentName);
2024
+ let map4mathAnchors = map4mathNames.map((x) => cesc2("#" + x));
2025
+ let map5mathNames = stateVariables[
2026
+ stateVariables["/copymapthroughp2"].replacements[0].componentName
2027
+ ].activeChildren
2028
+ .filter((x) => x.componentType === "math")
2029
+ .map((x) => x.componentName);
2030
+ let map5mathAnchors = map5mathNames.map((x) => cesc2("#" + x));
2031
+ let map6mathNames = stateVariables[
2032
+ stateVariables["/copymapthroughp3"].replacements[0].componentName
2033
+ ].activeChildren
2034
+ .filter((x) => x.componentType === "math")
2035
+ .map((x) => x.componentName);
2036
+ let map6mathAnchors = map6mathNames.map((x) => cesc2("#" + x));
2037
+
2038
+ cy.get(cesc2("#/_p1"))
2039
+ .children(map1mathAnchors[0])
2040
+ .find(".mjx-mrow")
2041
+ .eq(0)
2042
+ .invoke("text")
2043
+ .then((text) => {
2044
+ expect(text.trim()).equal("1");
2045
+ });
2046
+ cy.get(cesc2("#/_p1"))
2047
+ .children(map1mathAnchors[1])
2048
+ .find(".mjx-mrow")
2049
+ .eq(0)
2050
+ .invoke("text")
2051
+ .then((text) => {
2052
+ expect(text.trim()).equal("4");
2053
+ });
2054
+ cy.get(cesc2("#/_p2"))
2055
+ .children(map2mathAnchors[0])
2056
+ .find(".mjx-mrow")
2057
+ .eq(0)
2058
+ .invoke("text")
2059
+ .then((text) => {
2060
+ expect(text.trim()).equal("1");
2061
+ });
2062
+ cy.get(cesc2("#/_p2"))
2063
+ .children(map2mathAnchors[1])
2064
+ .find(".mjx-mrow")
2065
+ .eq(0)
2066
+ .invoke("text")
2067
+ .then((text) => {
2068
+ expect(text.trim()).equal("4");
2069
+ });
2070
+ cy.get(cesc2("#/_p3"))
2071
+ .children(map3mathAnchors[0])
2072
+ .find(".mjx-mrow")
2073
+ .eq(0)
2074
+ .invoke("text")
2075
+ .then((text) => {
2076
+ expect(text.trim()).equal("1");
2077
+ });
2078
+ cy.get(cesc2("#/_p3"))
2079
+ .children(map3mathAnchors[1])
2080
+ .find(".mjx-mrow")
2081
+ .eq(0)
2082
+ .invoke("text")
2083
+ .then((text) => {
2084
+ expect(text.trim()).equal("4");
2085
+ });
2086
+ cy.get(p4Anchor)
2087
+ .children(map4mathAnchors[0])
2088
+ .find(".mjx-mrow")
2089
+ .eq(0)
2090
+ .invoke("text")
2091
+ .then((text) => {
2092
+ expect(text.trim()).equal("1");
2093
+ });
2094
+ cy.get(p4Anchor)
2095
+ .children(map4mathAnchors[1])
2096
+ .find(".mjx-mrow")
2097
+ .eq(0)
2098
+ .invoke("text")
2099
+ .then((text) => {
2100
+ expect(text.trim()).equal("4");
2101
+ });
2102
+ cy.get(p5Anchor)
2103
+ .children(map5mathAnchors[0])
2104
+ .find(".mjx-mrow")
2105
+ .eq(0)
2106
+ .invoke("text")
2107
+ .then((text) => {
2108
+ expect(text.trim()).equal("1");
2109
+ });
2110
+ cy.get(p5Anchor)
2111
+ .children(map5mathAnchors[1])
2112
+ .find(".mjx-mrow")
2113
+ .eq(0)
2114
+ .invoke("text")
2115
+ .then((text) => {
2116
+ expect(text.trim()).equal("4");
2117
+ });
2118
+ cy.get(p6Anchor)
2119
+ .children(map6mathAnchors[0])
2120
+ .find(".mjx-mrow")
2121
+ .eq(0)
2122
+ .invoke("text")
2123
+ .then((text) => {
2124
+ expect(text.trim()).equal("1");
2125
+ });
2126
+ cy.get(p6Anchor)
2127
+ .children(map6mathAnchors[1])
2128
+ .find(".mjx-mrow")
2129
+ .eq(0)
2130
+ .invoke("text")
2131
+ .then((text) => {
2132
+ expect(text.trim()).equal("4");
2133
+ });
2134
+ });
2135
+
2136
+ cy.log("change limits");
2137
+ cy.get(cesc2("#/sequenceFrom") + " textarea").type(
2138
+ "{end}{backspace}3{enter}",
2139
+ { force: true },
2140
+ );
2141
+ cy.get(cesc2("#/sequenceTo") + " textarea").type(
2142
+ "{end}{backspace}5{enter}",
2143
+ { force: true },
2144
+ );
2145
+ cy.get(cesc2("#/sequenceTo2")).should("contain.text", "5");
2146
+
2147
+ cy.window().then(async (win) => {
2148
+ let stateVariables = await win.returnAllStateVariables1();
2149
+ let map1mathNames = stateVariables["/_map1"].replacements.map(
2150
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2151
+ );
2152
+ let map1mathAnchors = map1mathNames.map((x) => cesc2("#" + x));
2153
+ let map2mathNames = stateVariables["/copymap2"].replacements.map(
2154
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2155
+ );
2156
+ let map2mathAnchors = map2mathNames.map((x) => cesc2("#" + x));
2157
+ let map3mathNames = stateVariables["/copymap3"].replacements.map(
2158
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2159
+ );
2160
+ let map3mathAnchors = map3mathNames.map((x) => cesc2("#" + x));
2161
+ let map4mathNames = stateVariables[
2162
+ stateVariables["/copymapthroughp"].replacements[0].componentName
2163
+ ].activeChildren
2164
+ .filter((x) => x.componentType === "math")
2165
+ .map((x) => x.componentName);
2166
+ let map4mathAnchors = map4mathNames.map((x) => cesc2("#" + x));
2167
+ let map5mathNames = stateVariables[
2168
+ stateVariables["/copymapthroughp2"].replacements[0].componentName
2169
+ ].activeChildren
2170
+ .filter((x) => x.componentType === "math")
2171
+ .map((x) => x.componentName);
2172
+ let map5mathAnchors = map5mathNames.map((x) => cesc2("#" + x));
2173
+ let map6mathNames = stateVariables[
2174
+ stateVariables["/copymapthroughp3"].replacements[0].componentName
2175
+ ].activeChildren
2176
+ .filter((x) => x.componentType === "math")
2177
+ .map((x) => x.componentName);
2178
+ let map6mathAnchors = map6mathNames.map((x) => cesc2("#" + x));
2179
+
2180
+ cy.get(cesc2("#/_p1"))
2181
+ .children(map1mathAnchors[0])
2182
+ .find(".mjx-mrow")
2183
+ .eq(0)
2184
+ .invoke("text")
2185
+ .then((text) => {
2186
+ expect(text.trim()).equal("9");
2187
+ });
2188
+ cy.get(cesc2("#/_p1"))
2189
+ .children(map1mathAnchors[1])
2190
+ .find(".mjx-mrow")
2191
+ .eq(0)
2192
+ .invoke("text")
2193
+ .then((text) => {
2194
+ expect(text.trim()).equal("25");
2195
+ });
2196
+ cy.get(cesc2("#/_p2"))
2197
+ .children(map2mathAnchors[0])
2198
+ .find(".mjx-mrow")
2199
+ .eq(0)
2200
+ .invoke("text")
2201
+ .then((text) => {
2202
+ expect(text.trim()).equal("9");
2203
+ });
2204
+ cy.get(cesc2("#/_p2"))
2205
+ .children(map2mathAnchors[1])
2206
+ .find(".mjx-mrow")
2207
+ .eq(0)
2208
+ .invoke("text")
2209
+ .then((text) => {
2210
+ expect(text.trim()).equal("25");
2211
+ });
2212
+ cy.get(cesc2("#/_p3"))
2213
+ .children(map3mathAnchors[0])
2214
+ .find(".mjx-mrow")
2215
+ .eq(0)
2216
+ .invoke("text")
2217
+ .then((text) => {
2218
+ expect(text.trim()).equal("9");
2219
+ });
2220
+ cy.get(cesc2("#/_p3"))
2221
+ .children(map3mathAnchors[1])
2222
+ .find(".mjx-mrow")
2223
+ .eq(0)
2224
+ .invoke("text")
2225
+ .then((text) => {
2226
+ expect(text.trim()).equal("25");
2227
+ });
2228
+ cy.get(p4Anchor)
2229
+ .children(map4mathAnchors[0])
2230
+ .find(".mjx-mrow")
2231
+ .eq(0)
2232
+ .invoke("text")
2233
+ .then((text) => {
2234
+ expect(text.trim()).equal("9");
2235
+ });
2236
+ cy.get(p4Anchor)
2237
+ .children(map4mathAnchors[1])
2238
+ .find(".mjx-mrow")
2239
+ .eq(0)
2240
+ .invoke("text")
2241
+ .then((text) => {
2242
+ expect(text.trim()).equal("25");
2243
+ });
2244
+ cy.get(p5Anchor)
2245
+ .children(map5mathAnchors[0])
2246
+ .find(".mjx-mrow")
2247
+ .eq(0)
2248
+ .invoke("text")
2249
+ .then((text) => {
2250
+ expect(text.trim()).equal("9");
2251
+ });
2252
+ cy.get(p5Anchor)
2253
+ .children(map5mathAnchors[1])
2254
+ .find(".mjx-mrow")
2255
+ .eq(0)
2256
+ .invoke("text")
2257
+ .then((text) => {
2258
+ expect(text.trim()).equal("25");
2259
+ });
2260
+ cy.get(p6Anchor)
2261
+ .children(map6mathAnchors[0])
2262
+ .find(".mjx-mrow")
2263
+ .eq(0)
2264
+ .invoke("text")
2265
+ .then((text) => {
2266
+ expect(text.trim()).equal("9");
2267
+ });
2268
+ cy.get(p6Anchor)
2269
+ .children(map6mathAnchors[1])
2270
+ .find(".mjx-mrow")
2271
+ .eq(0)
2272
+ .invoke("text")
2273
+ .then((text) => {
2274
+ expect(text.trim()).equal("25");
2275
+ });
2276
+ });
2277
+
2278
+ cy.log("make sequence length 0 again");
2279
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
2280
+ "{end}{backspace}0{enter}",
2281
+ { force: true },
2282
+ );
2283
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "0");
2284
+
2285
+ cy.get(cesc2("#/_p1"))
2286
+ .invoke("text")
2287
+ .then((text) => {
2288
+ expect(text.trim()).equal("");
2289
+ });
2290
+ cy.get(cesc2("#/_p2"))
2291
+ .invoke("text")
2292
+ .then((text) => {
2293
+ expect(text.trim()).equal("");
2294
+ });
2295
+ cy.get(cesc2("#/_p3"))
2296
+ .invoke("text")
2297
+ .then((text) => {
2298
+ expect(text.trim()).equal("");
2299
+ });
2300
+ cy.get(p4Anchor)
2301
+ .invoke("text")
2302
+ .then((text) => {
2303
+ expect(text.trim()).equal("");
2304
+ });
2305
+ cy.get(p5Anchor)
2306
+ .invoke("text")
2307
+ .then((text) => {
2308
+ expect(text.trim()).equal("");
2309
+ });
2310
+ cy.get(p6Anchor)
2311
+ .invoke("text")
2312
+ .then((text) => {
2313
+ expect(text.trim()).equal("");
2314
+ });
2315
+
2316
+ cy.log("make sequence length 3");
2317
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
2318
+ "{end}{backspace}3{enter}",
2319
+ { force: true },
2320
+ );
2321
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "3");
2322
+
2323
+ cy.window().then(async (win) => {
2324
+ let stateVariables = await win.returnAllStateVariables1();
2325
+ let map1mathNames = stateVariables["/_map1"].replacements.map(
2326
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2327
+ );
2328
+ let map1mathAnchors = map1mathNames.map((x) => cesc2("#" + x));
2329
+ let map2mathNames = stateVariables["/copymap2"].replacements.map(
2330
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2331
+ );
2332
+ let map2mathAnchors = map2mathNames.map((x) => cesc2("#" + x));
2333
+ let map3mathNames = stateVariables["/copymap3"].replacements.map(
2334
+ (x) => stateVariables[x.componentName].replacements[0].componentName,
2335
+ );
2336
+ let map3mathAnchors = map3mathNames.map((x) => cesc2("#" + x));
2337
+ let map4mathNames = stateVariables[
2338
+ stateVariables["/copymapthroughp"].replacements[0].componentName
2339
+ ].activeChildren
2340
+ .filter((x) => x.componentType === "math")
2341
+ .map((x) => x.componentName);
2342
+ let map4mathAnchors = map4mathNames.map((x) => cesc2("#" + x));
2343
+ let map5mathNames = stateVariables[
2344
+ stateVariables["/copymapthroughp2"].replacements[0].componentName
2345
+ ].activeChildren
2346
+ .filter((x) => x.componentType === "math")
2347
+ .map((x) => x.componentName);
2348
+ let map5mathAnchors = map5mathNames.map((x) => cesc2("#" + x));
2349
+ let map6mathNames = stateVariables[
2350
+ stateVariables["/copymapthroughp3"].replacements[0].componentName
2351
+ ].activeChildren
2352
+ .filter((x) => x.componentType === "math")
2353
+ .map((x) => x.componentName);
2354
+ let map6mathAnchors = map6mathNames.map((x) => cesc2("#" + x));
2355
+
2356
+ cy.get(cesc2("#/_p1"))
2357
+ .children(map1mathAnchors[0])
2358
+ .find(".mjx-mrow")
2359
+ .eq(0)
2360
+ .invoke("text")
2361
+ .then((text) => {
2362
+ expect(text.trim()).equal("9");
2363
+ });
2364
+ cy.get(cesc2("#/_p1"))
2365
+ .children(map1mathAnchors[1])
2366
+ .find(".mjx-mrow")
2367
+ .eq(0)
2368
+ .invoke("text")
2369
+ .then((text) => {
2370
+ expect(text.trim()).equal("16");
2371
+ });
2372
+ cy.get(cesc2("#/_p1"))
2373
+ .children(map1mathAnchors[2])
2374
+ .find(".mjx-mrow")
2375
+ .eq(0)
2376
+ .invoke("text")
2377
+ .then((text) => {
2378
+ expect(text.trim()).equal("25");
2379
+ });
2380
+ cy.get(cesc2("#/_p2"))
2381
+ .children(map2mathAnchors[0])
2382
+ .find(".mjx-mrow")
2383
+ .eq(0)
2384
+ .invoke("text")
2385
+ .then((text) => {
2386
+ expect(text.trim()).equal("9");
2387
+ });
2388
+ cy.get(cesc2("#/_p2"))
2389
+ .children(map2mathAnchors[1])
2390
+ .find(".mjx-mrow")
2391
+ .eq(0)
2392
+ .invoke("text")
2393
+ .then((text) => {
2394
+ expect(text.trim()).equal("16");
2395
+ });
2396
+ cy.get(cesc2("#/_p2"))
2397
+ .children(map2mathAnchors[2])
2398
+ .find(".mjx-mrow")
2399
+ .eq(0)
2400
+ .invoke("text")
2401
+ .then((text) => {
2402
+ expect(text.trim()).equal("25");
2403
+ });
2404
+ cy.get(cesc2("#/_p3"))
2405
+ .children(map3mathAnchors[0])
2406
+ .find(".mjx-mrow")
2407
+ .eq(0)
2408
+ .invoke("text")
2409
+ .then((text) => {
2410
+ expect(text.trim()).equal("9");
2411
+ });
2412
+ cy.get(cesc2("#/_p3"))
2413
+ .children(map3mathAnchors[1])
2414
+ .find(".mjx-mrow")
2415
+ .eq(0)
2416
+ .invoke("text")
2417
+ .then((text) => {
2418
+ expect(text.trim()).equal("16");
2419
+ });
2420
+ cy.get(cesc2("#/_p3"))
2421
+ .children(map3mathAnchors[2])
2422
+ .find(".mjx-mrow")
2423
+ .eq(0)
2424
+ .invoke("text")
2425
+ .then((text) => {
2426
+ expect(text.trim()).equal("25");
2427
+ });
2428
+ cy.get(p4Anchor)
2429
+ .children(map4mathAnchors[0])
2430
+ .find(".mjx-mrow")
2431
+ .eq(0)
2432
+ .invoke("text")
2433
+ .then((text) => {
2434
+ expect(text.trim()).equal("9");
2435
+ });
2436
+ cy.get(p4Anchor)
2437
+ .children(map4mathAnchors[1])
2438
+ .find(".mjx-mrow")
2439
+ .eq(0)
2440
+ .invoke("text")
2441
+ .then((text) => {
2442
+ expect(text.trim()).equal("16");
2443
+ });
2444
+ cy.get(p4Anchor)
2445
+ .children(map4mathAnchors[2])
2446
+ .find(".mjx-mrow")
2447
+ .eq(0)
2448
+ .invoke("text")
2449
+ .then((text) => {
2450
+ expect(text.trim()).equal("25");
2451
+ });
2452
+ cy.get(p5Anchor)
2453
+ .children(map5mathAnchors[0])
2454
+ .find(".mjx-mrow")
2455
+ .eq(0)
2456
+ .invoke("text")
2457
+ .then((text) => {
2458
+ expect(text.trim()).equal("9");
2459
+ });
2460
+ cy.get(p5Anchor)
2461
+ .children(map5mathAnchors[1])
2462
+ .find(".mjx-mrow")
2463
+ .eq(0)
2464
+ .invoke("text")
2465
+ .then((text) => {
2466
+ expect(text.trim()).equal("16");
2467
+ });
2468
+ cy.get(p5Anchor)
2469
+ .children(map5mathAnchors[2])
2470
+ .find(".mjx-mrow")
2471
+ .eq(0)
2472
+ .invoke("text")
2473
+ .then((text) => {
2474
+ expect(text.trim()).equal("25");
2475
+ });
2476
+ cy.get(p6Anchor)
2477
+ .children(map6mathAnchors[0])
2478
+ .find(".mjx-mrow")
2479
+ .eq(0)
2480
+ .invoke("text")
2481
+ .then((text) => {
2482
+ expect(text.trim()).equal("9");
2483
+ });
2484
+ cy.get(p6Anchor)
2485
+ .children(map6mathAnchors[1])
2486
+ .find(".mjx-mrow")
2487
+ .eq(0)
2488
+ .invoke("text")
2489
+ .then((text) => {
2490
+ expect(text.trim()).equal("16");
2491
+ });
2492
+ cy.get(p6Anchor)
2493
+ .children(map6mathAnchors[2])
2494
+ .find(".mjx-mrow")
2495
+ .eq(0)
2496
+ .invoke("text")
2497
+ .then((text) => {
2498
+ expect(text.trim()).equal("25");
2499
+ });
2500
+ });
2501
+ });
2502
+ });
2503
+
2504
+ it("map with circular dependence in template", () => {
2505
+ cy.window().then(async (win) => {
2506
+ win.postMessage(
2507
+ {
2508
+ doenetML: `
2509
+ <text>a</text>
2510
+ <graph>
2511
+ <map assignnames="a b c">
2512
+ <template newNamespace><point>
2513
+ (<copy target="../q" />$n^2,
2514
+ <copy prop="x" target="_point2" />)
2515
+ </point><point>
2516
+ (<copy target="../r" />$n,
2517
+ <copy prop="x" target="_point1" />)
2518
+ </point></template>
2519
+ <sources alias='n'>
2520
+ <sequence from="2" to="4" />
2521
+ </sources>
2522
+ </map>
2523
+ </graph>
2524
+ <math name="q">1</math>
2525
+ <math name="r">1</math>
2526
+ <copy assignNames="c1" prop="coords" target="a/_point1" />
2527
+ <copy assignNames="c2" prop="coords" target="a/_point2" />
2528
+ <copy assignNames="c3" prop="coords" target="b/_point1" />
2529
+ <copy assignNames="c4" prop="coords" target="b/_point2" />
2530
+ <copy assignNames="c5" prop="coords" target="c/_point1" />
2531
+ <copy assignNames="c6" prop="coords" target="c/_point2" />
2532
+ `,
2533
+ },
2534
+ "*",
2535
+ );
2536
+ });
2537
+
2538
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
2539
+
2540
+ cy.log("Test values displayed in browser");
2541
+
2542
+ cy.get(cesc(`#\\/c1`) + ` .mjx-mrow`)
2543
+ .eq(0)
2544
+ .invoke("text")
2545
+ .then((text) => {
2546
+ expect(text.trim()).equal("(4,2)");
2547
+ });
2548
+ cy.get(cesc(`#\\/c2`) + ` .mjx-mrow`)
2549
+ .eq(0)
2550
+ .invoke("text")
2551
+ .then((text) => {
2552
+ expect(text.trim()).equal("(2,4)");
2553
+ });
2554
+ cy.get(cesc(`#\\/c3`) + ` .mjx-mrow`)
2555
+ .eq(0)
2556
+ .invoke("text")
2557
+ .then((text) => {
2558
+ expect(text.trim()).equal("(9,3)");
2559
+ });
2560
+ cy.get(cesc(`#\\/c4`) + ` .mjx-mrow`)
2561
+ .eq(0)
2562
+ .invoke("text")
2563
+ .then((text) => {
2564
+ expect(text.trim()).equal("(3,9)");
2565
+ });
2566
+ cy.get(cesc(`#\\/c5`) + ` .mjx-mrow`)
2567
+ .eq(0)
2568
+ .invoke("text")
2569
+ .then((text) => {
2570
+ expect(text.trim()).equal("(16,4)");
2571
+ });
2572
+ cy.get(cesc(`#\\/c6`) + ` .mjx-mrow`)
2573
+ .eq(0)
2574
+ .invoke("text")
2575
+ .then((text) => {
2576
+ expect(text.trim()).equal("(4,16)");
2577
+ });
2578
+ cy.get(`${cesc2("#/q")} .mjx-mrow`)
2579
+ .eq(0)
2580
+ .invoke("text")
2581
+ .then((text) => {
2582
+ expect(text.trim()).equal("1");
2583
+ });
2584
+ cy.get(`${cesc2("#/r")} .mjx-mrow`)
2585
+ .eq(0)
2586
+ .invoke("text")
2587
+ .then((text) => {
2588
+ expect(text.trim()).equal("1");
2589
+ });
2590
+
2591
+ cy.window().then(async (win) => {
2592
+ let r = 1;
2593
+ let q = 1;
2594
+ let s = [2, 3, 4];
2595
+ let xs1 = s.map((v) => v * v * q);
2596
+ let xs2 = s.map((v) => v * r);
2597
+ let ns = ["a", "b", "c"];
2598
+ let stateVariables = await win.returnAllStateVariables1();
2599
+ expect(
2600
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
2601
+ ).eq(6);
2602
+ for (let ind = 0; ind < 3; ind++) {
2603
+ let namespace = ns[ind];
2604
+ expect(stateVariables[`/${namespace}/_point1`].stateValues.xs[0]).eq(
2605
+ xs1[ind],
2606
+ );
2607
+ expect(stateVariables[`/${namespace}/_point1`].stateValues.xs[1]).eq(
2608
+ xs2[ind],
2609
+ );
2610
+ expect(stateVariables[`/${namespace}/_point2`].stateValues.xs[0]).eq(
2611
+ xs2[ind],
2612
+ );
2613
+ expect(stateVariables[`/${namespace}/_point2`].stateValues.xs[1]).eq(
2614
+ xs1[ind],
2615
+ );
2616
+ }
2617
+ });
2618
+
2619
+ cy.log("move point a1");
2620
+ cy.window().then(async (win) => {
2621
+ let r = 1.3;
2622
+ let q = -2.1;
2623
+ let s = [2, 3, 4];
2624
+ let xs1 = s.map((v) => v * v * q);
2625
+ let xs2 = s.map((v) => v * r);
2626
+ let ns = ["a", "b", "c"];
2627
+
2628
+ await win.callAction1({
2629
+ actionName: "movePoint",
2630
+ componentName: "/a/_point1",
2631
+ args: { x: xs1[0], y: xs2[0] },
2632
+ });
2633
+ let stateVariables = await win.returnAllStateVariables1();
2634
+ for (let ind = 0; ind < 3; ind++) {
2635
+ let namespace = ns[ind];
2636
+ expect(
2637
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[0],
2638
+ ).closeTo(xs1[ind], 1e-14);
2639
+ expect(
2640
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[1],
2641
+ ).closeTo(xs2[ind], 1e-14);
2642
+ expect(
2643
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[0],
2644
+ ).closeTo(xs2[ind], 1e-14);
2645
+ expect(
2646
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[1],
2647
+ ).closeTo(xs1[ind], 1e-14);
2648
+ }
2649
+ });
2650
+
2651
+ cy.log("move point a2");
2652
+ cy.window().then(async (win) => {
2653
+ let r = 0.7;
2654
+ let q = 1.8;
2655
+ let s = [2, 3, 4];
2656
+ let xs1 = s.map((v) => v * v * q);
2657
+ let xs2 = s.map((v) => v * r);
2658
+ let ns = ["a", "b", "c"];
2659
+
2660
+ await win.callAction1({
2661
+ actionName: "movePoint",
2662
+ componentName: "/a/_point2",
2663
+ args: { x: xs2[0], y: xs1[0] },
2664
+ });
2665
+ let stateVariables = await win.returnAllStateVariables1();
2666
+ for (let ind = 0; ind < 3; ind++) {
2667
+ let namespace = ns[ind];
2668
+ expect(
2669
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[0],
2670
+ ).closeTo(xs1[ind], 1e-14);
2671
+ expect(
2672
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[1],
2673
+ ).closeTo(xs2[ind], 1e-14);
2674
+ expect(
2675
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[0],
2676
+ ).closeTo(xs2[ind], 1e-14);
2677
+ expect(
2678
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[1],
2679
+ ).closeTo(xs1[ind], 1e-14);
2680
+ }
2681
+ });
2682
+
2683
+ cy.log("move point b1");
2684
+ cy.window().then(async (win) => {
2685
+ let r = -0.2;
2686
+ let q = 0.3;
2687
+ let s = [2, 3, 4];
2688
+ let xs1 = s.map((v) => v * v * q);
2689
+ let xs2 = s.map((v) => v * r);
2690
+ let ns = ["a", "b", "c"];
2691
+
2692
+ await win.callAction1({
2693
+ actionName: "movePoint",
2694
+ componentName: "/b/_point1",
2695
+ args: { x: xs1[1], y: xs2[1] },
2696
+ });
2697
+ let stateVariables = await win.returnAllStateVariables1();
2698
+ for (let ind = 0; ind < 3; ind++) {
2699
+ let namespace = ns[ind];
2700
+ expect(
2701
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[0],
2702
+ ).closeTo(xs1[ind], 1e-14);
2703
+ expect(
2704
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[1],
2705
+ ).closeTo(xs2[ind], 1e-14);
2706
+ expect(
2707
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[0],
2708
+ ).closeTo(xs2[ind], 1e-14);
2709
+ expect(
2710
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[1],
2711
+ ).closeTo(xs1[ind], 1e-14);
2712
+ }
2713
+ });
2714
+
2715
+ cy.log("move point b2");
2716
+ cy.window().then(async (win) => {
2717
+ let r = 0.6;
2718
+ let q = 0.35;
2719
+ let s = [2, 3, 4];
2720
+ let xs1 = s.map((v) => v * v * q);
2721
+ let xs2 = s.map((v) => v * r);
2722
+ let ns = ["a", "b", "c"];
2723
+
2724
+ await win.callAction1({
2725
+ actionName: "movePoint",
2726
+ componentName: "/b/_point2",
2727
+ args: { x: xs2[1], y: xs1[1] },
2728
+ });
2729
+ let stateVariables = await win.returnAllStateVariables1();
2730
+ for (let ind = 0; ind < 3; ind++) {
2731
+ let namespace = ns[ind];
2732
+ expect(
2733
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[0],
2734
+ ).closeTo(xs1[ind], 1e-14);
2735
+ expect(
2736
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[1],
2737
+ ).closeTo(xs2[ind], 1e-14);
2738
+ expect(
2739
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[0],
2740
+ ).closeTo(xs2[ind], 1e-14);
2741
+ expect(
2742
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[1],
2743
+ ).closeTo(xs1[ind], 1e-14);
2744
+ }
2745
+ });
2746
+
2747
+ cy.log("move point c1");
2748
+ cy.window().then(async (win) => {
2749
+ let r = -0.21;
2750
+ let q = -0.46;
2751
+ let s = [2, 3, 4];
2752
+ let xs1 = s.map((v) => v * v * q);
2753
+ let xs2 = s.map((v) => v * r);
2754
+ let ns = ["a", "b", "c"];
2755
+
2756
+ await win.callAction1({
2757
+ actionName: "movePoint",
2758
+ componentName: "/c/_point1",
2759
+ args: { x: xs1[2], y: xs2[2] },
2760
+ });
2761
+ let stateVariables = await win.returnAllStateVariables1();
2762
+ for (let ind = 0; ind < 3; ind++) {
2763
+ let namespace = ns[ind];
2764
+ expect(
2765
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[0],
2766
+ ).closeTo(xs1[ind], 1e-14);
2767
+ expect(
2768
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[1],
2769
+ ).closeTo(xs2[ind], 1e-14);
2770
+ expect(
2771
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[0],
2772
+ ).closeTo(xs2[ind], 1e-14);
2773
+ expect(
2774
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[1],
2775
+ ).closeTo(xs1[ind], 1e-14);
2776
+ }
2777
+ });
2778
+
2779
+ cy.log("move point c2");
2780
+ cy.window().then(async (win) => {
2781
+ let r = 0.37;
2782
+ let q = -0.73;
2783
+ let s = [2, 3, 4];
2784
+ let xs1 = s.map((v) => v * v * q);
2785
+ let xs2 = s.map((v) => v * r);
2786
+ let ns = ["a", "b", "c"];
2787
+
2788
+ await win.callAction1({
2789
+ actionName: "movePoint",
2790
+ componentName: "/c/_point2",
2791
+ args: { x: xs2[2], y: xs1[2] },
2792
+ });
2793
+ let stateVariables = await win.returnAllStateVariables1();
2794
+ for (let ind = 0; ind < 3; ind++) {
2795
+ let namespace = ns[ind];
2796
+ expect(
2797
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[0],
2798
+ ).closeTo(xs1[ind], 1e-14);
2799
+ expect(
2800
+ stateVariables[`/${namespace}/_point1`].stateValues.xs[1],
2801
+ ).closeTo(xs2[ind], 1e-14);
2802
+ expect(
2803
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[0],
2804
+ ).closeTo(xs2[ind], 1e-14);
2805
+ expect(
2806
+ stateVariables[`/${namespace}/_point2`].stateValues.xs[1],
2807
+ ).closeTo(xs1[ind], 1e-14);
2808
+ }
2809
+ });
2810
+ });
2811
+
2812
+ it("two maps with mutual copies, begin zero length, copied multiple times", () => {
2813
+ cy.window().then(async (win) => {
2814
+ win.postMessage(
2815
+ {
2816
+ doenetML: `
2817
+ <text>a</text>
2818
+ <graph>
2819
+ <map assignnames="a b c">
2820
+ <template newNamespace><point>
2821
+ (-$n, $n<copy prop="x" target="../q/_point1" />)
2822
+ </point></template>
2823
+ <sources alias="n">
2824
+ <sequence from="$sequenceFrom" to="$sequenceTo" length="$sequenceCount" />
2825
+ </sources>
2826
+ </map>
2827
+ <map assignnames="q r s">
2828
+ <template newNamespace><point>
2829
+ ($n, $n<copy prop="x" target="../a/_point1" />)
2830
+ </point></template>
2831
+ <sources alias="n">
2832
+ <sequence from="$sequenceFrom" to="$sequenceTo" length="$sequenceCount" />
2833
+ </sources>
2834
+ </map>
2835
+ </graph>
2836
+
2837
+ <mathinput name="sequenceFrom" prefill="1"/>
2838
+ <mathinput name="sequenceTo" prefill="2"/>
2839
+ <mathinput name="sequenceCount" prefill="0"/>
2840
+
2841
+ <graph>
2842
+ <copy name="copymap1" target="_map1" newNamespace />
2843
+ <copy name="copymap2" target="_map2" newNamespace />
2844
+ </graph>
2845
+ <graph>
2846
+ <copy name="copymap1b" target="copymap1" newNamespace />
2847
+ <copy name="copymap2b" target="copymap2" newNamespace />
2848
+ </graph>
2849
+
2850
+ <copy name="g4" target="_graph1" newNamespace />
2851
+ <p><collect componentTypes="point" target="_graph1"/></p>
2852
+ <copy prop="value" target="sequenceCount" assignNames="sequenceCount2" />
2853
+ <copy prop="value" target="sequenceTo" assignNames="sequenceTo2" />
2854
+ `,
2855
+ },
2856
+ "*",
2857
+ );
2858
+ });
2859
+
2860
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
2861
+
2862
+ cy.log("At beginning, nothing shown");
2863
+ cy.get(cesc2("#/_p1"))
2864
+ .invoke("text")
2865
+ .then((text) => {
2866
+ expect(text.trim()).equal("");
2867
+ });
2868
+
2869
+ cy.window().then(async (win) => {
2870
+ let stateVariables = await win.returnAllStateVariables1();
2871
+ expect(
2872
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
2873
+ ).eq(0);
2874
+ expect(
2875
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
2876
+ ).eq(0);
2877
+ expect(
2878
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
2879
+ ).eq(0);
2880
+ expect(
2881
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
2882
+ ).eq(0);
2883
+ });
2884
+
2885
+ cy.log("make sequence length 1");
2886
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
2887
+ "{end}{backspace}1{enter}",
2888
+ { force: true },
2889
+ );
2890
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "1");
2891
+
2892
+ cy.window().then(async (win) => {
2893
+ let stateVariables = await win.returnAllStateVariables1();
2894
+ let coords1Anchor = cesc2(
2895
+ "#" + stateVariables["/_collect1"].replacements[0].componentName,
2896
+ );
2897
+ let coords2Anchor = cesc2(
2898
+ "#" + stateVariables["/_collect1"].replacements[1].componentName,
2899
+ );
2900
+
2901
+ cy.get(cesc2("#/_p1"))
2902
+ .children(coords1Anchor)
2903
+ .find(".mjx-mrow")
2904
+ .eq(0)
2905
+ .invoke("text")
2906
+ .then((text) => {
2907
+ expect(text.trim()).equal("(−1,1)");
2908
+ });
2909
+ cy.get(cesc2("#/_p1"))
2910
+ .children(coords2Anchor)
2911
+ .find(".mjx-mrow")
2912
+ .eq(0)
2913
+ .invoke("text")
2914
+ .then((text) => {
2915
+ expect(text.trim()).equal("(1,−1)");
2916
+ });
2917
+
2918
+ cy.window().then(async (win) => {
2919
+ let stateVariables = await win.returnAllStateVariables1();
2920
+ expect(
2921
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
2922
+ ).eq(2);
2923
+ expect(
2924
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
2925
+ ).eq(2);
2926
+ expect(
2927
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
2928
+ ).eq(2);
2929
+ expect(
2930
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
2931
+ ).eq(2);
2932
+ expect(stateVariables["/a/_point1"].stateValues.coords).eqls([
2933
+ "vector",
2934
+ -1,
2935
+ 1,
2936
+ ]);
2937
+ expect(stateVariables["/q/_point1"].stateValues.coords).eqls([
2938
+ "vector",
2939
+ 1,
2940
+ -1,
2941
+ ]);
2942
+ expect(stateVariables["/copymap1/a/_point1"].stateValues.coords).eqls([
2943
+ "vector",
2944
+ -1,
2945
+ 1,
2946
+ ]);
2947
+ expect(stateVariables["/copymap2/q/_point1"].stateValues.coords).eqls([
2948
+ "vector",
2949
+ 1,
2950
+ -1,
2951
+ ]);
2952
+ expect(stateVariables["/copymap1b/a/_point1"].stateValues.coords).eqls([
2953
+ "vector",
2954
+ -1,
2955
+ 1,
2956
+ ]);
2957
+ expect(stateVariables["/copymap2b/q/_point1"].stateValues.coords).eqls([
2958
+ "vector",
2959
+ 1,
2960
+ -1,
2961
+ ]);
2962
+ expect(stateVariables["/g4/a/_point1"].stateValues.coords).eqls([
2963
+ "vector",
2964
+ -1,
2965
+ 1,
2966
+ ]);
2967
+ expect(stateVariables["/g4/q/_point1"].stateValues.coords).eqls([
2968
+ "vector",
2969
+ 1,
2970
+ -1,
2971
+ ]);
2972
+ });
2973
+ });
2974
+
2975
+ cy.log("make sequence length 0 again");
2976
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
2977
+ "{end}{backspace}0{enter}",
2978
+ { force: true },
2979
+ );
2980
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "0");
2981
+
2982
+ cy.get(cesc2("#/_p1"))
2983
+ .invoke("text")
2984
+ .then((text) => {
2985
+ expect(text.trim()).equal("");
2986
+ });
2987
+
2988
+ cy.window().then(async (win) => {
2989
+ let stateVariables = await win.returnAllStateVariables1();
2990
+ expect(
2991
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
2992
+ ).eq(0);
2993
+ expect(
2994
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
2995
+ ).eq(0);
2996
+ expect(
2997
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
2998
+ ).eq(0);
2999
+ expect(
3000
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
3001
+ ).eq(0);
3002
+ });
3003
+
3004
+ cy.log("make sequence length 2");
3005
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
3006
+ "{end}{backspace}2{enter}",
3007
+ { force: true },
3008
+ );
3009
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "2");
3010
+
3011
+ cy.window().then(async (win) => {
3012
+ let stateVariables = await win.returnAllStateVariables1();
3013
+ let coords1Anchor = cesc2(
3014
+ "#" + stateVariables["/_collect1"].replacements[0].componentName,
3015
+ );
3016
+ let coords2Anchor = cesc2(
3017
+ "#" + stateVariables["/_collect1"].replacements[1].componentName,
3018
+ );
3019
+ let coords3Anchor = cesc2(
3020
+ "#" + stateVariables["/_collect1"].replacements[2].componentName,
3021
+ );
3022
+ let coords4Anchor = cesc2(
3023
+ "#" + stateVariables["/_collect1"].replacements[3].componentName,
3024
+ );
3025
+
3026
+ cy.get(cesc2("#/_p1"))
3027
+ .children(coords1Anchor)
3028
+ .find(".mjx-mrow")
3029
+ .eq(0)
3030
+ .invoke("text")
3031
+ .then((text) => {
3032
+ expect(text.trim()).equal("(−1,1)");
3033
+ });
3034
+ cy.get(cesc2("#/_p1"))
3035
+ .children(coords2Anchor)
3036
+ .find(".mjx-mrow")
3037
+ .eq(0)
3038
+ .invoke("text")
3039
+ .then((text) => {
3040
+ expect(text.trim()).equal("(−2,2)");
3041
+ });
3042
+ cy.get(cesc2("#/_p1"))
3043
+ .children(coords3Anchor)
3044
+ .find(".mjx-mrow")
3045
+ .eq(0)
3046
+ .invoke("text")
3047
+ .then((text) => {
3048
+ expect(text.trim()).equal("(1,−1)");
3049
+ });
3050
+ cy.get(cesc2("#/_p1"))
3051
+ .children(coords4Anchor)
3052
+ .find(".mjx-mrow")
3053
+ .eq(0)
3054
+ .invoke("text")
3055
+ .then((text) => {
3056
+ expect(text.trim()).equal("(2,−2)");
3057
+ });
3058
+
3059
+ cy.window().then(async (win) => {
3060
+ let stateVariables = await win.returnAllStateVariables1();
3061
+ expect(
3062
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
3063
+ ).eq(4);
3064
+ expect(
3065
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
3066
+ ).eq(4);
3067
+ expect(
3068
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
3069
+ ).eq(4);
3070
+ expect(
3071
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
3072
+ ).eq(4);
3073
+ expect(stateVariables["/a/_point1"].stateValues.coords).eqls([
3074
+ "vector",
3075
+ -1,
3076
+ 1,
3077
+ ]);
3078
+ expect(stateVariables["/q/_point1"].stateValues.coords).eqls([
3079
+ "vector",
3080
+ 1,
3081
+ -1,
3082
+ ]);
3083
+ expect(stateVariables["/copymap1/a/_point1"].stateValues.coords).eqls([
3084
+ "vector",
3085
+ -1,
3086
+ 1,
3087
+ ]);
3088
+ expect(stateVariables["/copymap2/q/_point1"].stateValues.coords).eqls([
3089
+ "vector",
3090
+ 1,
3091
+ -1,
3092
+ ]);
3093
+ expect(stateVariables["/copymap1b/a/_point1"].stateValues.coords).eqls([
3094
+ "vector",
3095
+ -1,
3096
+ 1,
3097
+ ]);
3098
+ expect(stateVariables["/copymap2b/q/_point1"].stateValues.coords).eqls([
3099
+ "vector",
3100
+ 1,
3101
+ -1,
3102
+ ]);
3103
+ expect(stateVariables["/g4/a/_point1"].stateValues.coords).eqls([
3104
+ "vector",
3105
+ -1,
3106
+ 1,
3107
+ ]);
3108
+ expect(stateVariables["/g4/q/_point1"].stateValues.coords).eqls([
3109
+ "vector",
3110
+ 1,
3111
+ -1,
3112
+ ]);
3113
+ expect(stateVariables["/b/_point1"].stateValues.coords).eqls([
3114
+ "vector",
3115
+ -2,
3116
+ 2,
3117
+ ]);
3118
+ expect(stateVariables["/r/_point1"].stateValues.coords).eqls([
3119
+ "vector",
3120
+ 2,
3121
+ -2,
3122
+ ]);
3123
+ expect(stateVariables["/copymap1/b/_point1"].stateValues.coords).eqls([
3124
+ "vector",
3125
+ -2,
3126
+ 2,
3127
+ ]);
3128
+ expect(stateVariables["/copymap2/r/_point1"].stateValues.coords).eqls([
3129
+ "vector",
3130
+ 2,
3131
+ -2,
3132
+ ]);
3133
+ expect(stateVariables["/copymap1b/b/_point1"].stateValues.coords).eqls([
3134
+ "vector",
3135
+ -2,
3136
+ 2,
3137
+ ]);
3138
+ expect(stateVariables["/copymap2b/r/_point1"].stateValues.coords).eqls([
3139
+ "vector",
3140
+ 2,
3141
+ -2,
3142
+ ]);
3143
+ expect(stateVariables["/g4/b/_point1"].stateValues.coords).eqls([
3144
+ "vector",
3145
+ -2,
3146
+ 2,
3147
+ ]);
3148
+ expect(stateVariables["/g4/r/_point1"].stateValues.coords).eqls([
3149
+ "vector",
3150
+ 2,
3151
+ -2,
3152
+ ]);
3153
+ });
3154
+ });
3155
+
3156
+ cy.log("change limits");
3157
+ cy.get(cesc2("#/sequenceFrom") + " textarea").type(
3158
+ "{end}{backspace}3{enter}",
3159
+ { force: true },
3160
+ );
3161
+ cy.get(cesc2("#/sequenceTo") + " textarea").type(
3162
+ "{end}{backspace}5{enter}",
3163
+ { force: true },
3164
+ );
3165
+ cy.get(cesc2("#/sequenceTo2")).should("contain.text", "5");
3166
+
3167
+ cy.window().then(async (win) => {
3168
+ let stateVariables = await win.returnAllStateVariables1();
3169
+ let coords1Anchor = cesc2(
3170
+ "#" + stateVariables["/_collect1"].replacements[0].componentName,
3171
+ );
3172
+ let coords2Anchor = cesc2(
3173
+ "#" + stateVariables["/_collect1"].replacements[1].componentName,
3174
+ );
3175
+ let coords3Anchor = cesc2(
3176
+ "#" + stateVariables["/_collect1"].replacements[2].componentName,
3177
+ );
3178
+ let coords4Anchor = cesc2(
3179
+ "#" + stateVariables["/_collect1"].replacements[3].componentName,
3180
+ );
3181
+
3182
+ cy.get(cesc2("#/_p1"))
3183
+ .children(coords1Anchor)
3184
+ .find(".mjx-mrow")
3185
+ .eq(0)
3186
+ .invoke("text")
3187
+ .then((text) => {
3188
+ expect(text.trim()).equal("(−3,9)");
3189
+ });
3190
+ cy.get(cesc2("#/_p1"))
3191
+ .children(coords2Anchor)
3192
+ .find(".mjx-mrow")
3193
+ .eq(0)
3194
+ .invoke("text")
3195
+ .then((text) => {
3196
+ expect(text.trim()).equal("(−5,15)");
3197
+ });
3198
+ cy.get(cesc2("#/_p1"))
3199
+ .children(coords3Anchor)
3200
+ .find(".mjx-mrow")
3201
+ .eq(0)
3202
+ .invoke("text")
3203
+ .then((text) => {
3204
+ expect(text.trim()).equal("(3,−9)");
3205
+ });
3206
+ cy.get(cesc2("#/_p1"))
3207
+ .children(coords4Anchor)
3208
+ .find(".mjx-mrow")
3209
+ .eq(0)
3210
+ .invoke("text")
3211
+ .then((text) => {
3212
+ expect(text.trim()).equal("(5,−15)");
3213
+ });
3214
+
3215
+ cy.window().then(async (win) => {
3216
+ let stateVariables = await win.returnAllStateVariables1();
3217
+ expect(
3218
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
3219
+ ).eq(4);
3220
+ expect(
3221
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
3222
+ ).eq(4);
3223
+ expect(
3224
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
3225
+ ).eq(4);
3226
+ expect(
3227
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
3228
+ ).eq(4);
3229
+ expect(stateVariables["/a/_point1"].stateValues.coords).eqls([
3230
+ "vector",
3231
+ -3,
3232
+ 9,
3233
+ ]);
3234
+ expect(stateVariables["/q/_point1"].stateValues.coords).eqls([
3235
+ "vector",
3236
+ 3,
3237
+ -9,
3238
+ ]);
3239
+ expect(stateVariables["/copymap1/a/_point1"].stateValues.coords).eqls([
3240
+ "vector",
3241
+ -3,
3242
+ 9,
3243
+ ]);
3244
+ expect(stateVariables["/copymap2/q/_point1"].stateValues.coords).eqls([
3245
+ "vector",
3246
+ 3,
3247
+ -9,
3248
+ ]);
3249
+ expect(stateVariables["/copymap1b/a/_point1"].stateValues.coords).eqls([
3250
+ "vector",
3251
+ -3,
3252
+ 9,
3253
+ ]);
3254
+ expect(stateVariables["/copymap2b/q/_point1"].stateValues.coords).eqls([
3255
+ "vector",
3256
+ 3,
3257
+ -9,
3258
+ ]);
3259
+ expect(stateVariables["/g4/a/_point1"].stateValues.coords).eqls([
3260
+ "vector",
3261
+ -3,
3262
+ 9,
3263
+ ]);
3264
+ expect(stateVariables["/g4/q/_point1"].stateValues.coords).eqls([
3265
+ "vector",
3266
+ 3,
3267
+ -9,
3268
+ ]);
3269
+ expect(stateVariables["/b/_point1"].stateValues.coords).eqls([
3270
+ "vector",
3271
+ -5,
3272
+ 15,
3273
+ ]);
3274
+ expect(stateVariables["/r/_point1"].stateValues.coords).eqls([
3275
+ "vector",
3276
+ 5,
3277
+ -15,
3278
+ ]);
3279
+ expect(stateVariables["/copymap1/b/_point1"].stateValues.coords).eqls([
3280
+ "vector",
3281
+ -5,
3282
+ 15,
3283
+ ]);
3284
+ expect(stateVariables["/copymap2/r/_point1"].stateValues.coords).eqls([
3285
+ "vector",
3286
+ 5,
3287
+ -15,
3288
+ ]);
3289
+ expect(stateVariables["/copymap1b/b/_point1"].stateValues.coords).eqls([
3290
+ "vector",
3291
+ -5,
3292
+ 15,
3293
+ ]);
3294
+ expect(stateVariables["/copymap2b/r/_point1"].stateValues.coords).eqls([
3295
+ "vector",
3296
+ 5,
3297
+ -15,
3298
+ ]);
3299
+ expect(stateVariables["/g4/b/_point1"].stateValues.coords).eqls([
3300
+ "vector",
3301
+ -5,
3302
+ 15,
3303
+ ]);
3304
+ expect(stateVariables["/g4/r/_point1"].stateValues.coords).eqls([
3305
+ "vector",
3306
+ 5,
3307
+ -15,
3308
+ ]);
3309
+ });
3310
+ });
3311
+
3312
+ cy.log("make sequence length 0 again");
3313
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
3314
+ "{end}{backspace}0{enter}",
3315
+ { force: true },
3316
+ );
3317
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "0");
3318
+
3319
+ cy.get(cesc2("#/_p1"))
3320
+ .invoke("text")
3321
+ .then((text) => {
3322
+ expect(text.trim()).equal("");
3323
+ });
3324
+
3325
+ cy.window().then(async (win) => {
3326
+ let stateVariables = await win.returnAllStateVariables1();
3327
+ expect(
3328
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
3329
+ ).eq(0);
3330
+ expect(
3331
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
3332
+ ).eq(0);
3333
+ expect(
3334
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
3335
+ ).eq(0);
3336
+ expect(
3337
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
3338
+ ).eq(0);
3339
+ });
3340
+
3341
+ cy.log("make sequence length 3");
3342
+ cy.get(cesc2("#/sequenceCount") + " textarea").type(
3343
+ "{end}{backspace}3{enter}",
3344
+ { force: true },
3345
+ );
3346
+ cy.get(cesc2("#/sequenceCount2")).should("contain.text", "3");
3347
+
3348
+ cy.window().then(async (win) => {
3349
+ let stateVariables = await win.returnAllStateVariables1();
3350
+ let coords1Anchor = cesc2(
3351
+ "#" + stateVariables["/_collect1"].replacements[0].componentName,
3352
+ );
3353
+ let coords2Anchor = cesc2(
3354
+ "#" + stateVariables["/_collect1"].replacements[1].componentName,
3355
+ );
3356
+ let coords3Anchor = cesc2(
3357
+ "#" + stateVariables["/_collect1"].replacements[2].componentName,
3358
+ );
3359
+ let coords4Anchor = cesc2(
3360
+ "#" + stateVariables["/_collect1"].replacements[3].componentName,
3361
+ );
3362
+ let coords5Anchor = cesc2(
3363
+ "#" + stateVariables["/_collect1"].replacements[4].componentName,
3364
+ );
3365
+ let coords6Anchor = cesc2(
3366
+ "#" + stateVariables["/_collect1"].replacements[5].componentName,
3367
+ );
3368
+
3369
+ cy.get(cesc2("#/_p1"))
3370
+ .children(coords1Anchor)
3371
+ .find(".mjx-mrow")
3372
+ .eq(0)
3373
+ .invoke("text")
3374
+ .then((text) => {
3375
+ expect(text.trim()).equal("(−3,9)");
3376
+ });
3377
+ cy.get(cesc2("#/_p1"))
3378
+ .children(coords2Anchor)
3379
+ .find(".mjx-mrow")
3380
+ .eq(0)
3381
+ .invoke("text")
3382
+ .then((text) => {
3383
+ expect(text.trim()).equal("(−4,12)");
3384
+ });
3385
+ cy.get(cesc2("#/_p1"))
3386
+ .children(coords3Anchor)
3387
+ .find(".mjx-mrow")
3388
+ .eq(0)
3389
+ .invoke("text")
3390
+ .then((text) => {
3391
+ expect(text.trim()).equal("(−5,15)");
3392
+ });
3393
+ cy.get(cesc2("#/_p1"))
3394
+ .children(coords4Anchor)
3395
+ .find(".mjx-mrow")
3396
+ .eq(0)
3397
+ .invoke("text")
3398
+ .then((text) => {
3399
+ expect(text.trim()).equal("(3,−9)");
3400
+ });
3401
+ cy.get(cesc2("#/_p1"))
3402
+ .children(coords5Anchor)
3403
+ .find(".mjx-mrow")
3404
+ .eq(0)
3405
+ .invoke("text")
3406
+ .then((text) => {
3407
+ expect(text.trim()).equal("(4,−12)");
3408
+ });
3409
+ cy.get(cesc2("#/_p1"))
3410
+ .children(coords6Anchor)
3411
+ .find(".mjx-mrow")
3412
+ .eq(0)
3413
+ .invoke("text")
3414
+ .then((text) => {
3415
+ expect(text.trim()).equal("(5,−15)");
3416
+ });
3417
+
3418
+ cy.window().then(async (win) => {
3419
+ let stateVariables = await win.returnAllStateVariables1();
3420
+ expect(
3421
+ stateVariables["/_graph1"].stateValues.graphicalDescendants.length,
3422
+ ).eq(6);
3423
+ expect(
3424
+ stateVariables["/_graph2"].stateValues.graphicalDescendants.length,
3425
+ ).eq(6);
3426
+ expect(
3427
+ stateVariables["/_graph3"].stateValues.graphicalDescendants.length,
3428
+ ).eq(6);
3429
+ expect(
3430
+ stateVariables["/g4/_graph1"].stateValues.graphicalDescendants.length,
3431
+ ).eq(6);
3432
+ expect(stateVariables["/a/_point1"].stateValues.coords).eqls([
3433
+ "vector",
3434
+ -3,
3435
+ 9,
3436
+ ]);
3437
+ expect(stateVariables["/q/_point1"].stateValues.coords).eqls([
3438
+ "vector",
3439
+ 3,
3440
+ -9,
3441
+ ]);
3442
+ expect(stateVariables["/copymap1/a/_point1"].stateValues.coords).eqls([
3443
+ "vector",
3444
+ -3,
3445
+ 9,
3446
+ ]);
3447
+ expect(stateVariables["/copymap2/q/_point1"].stateValues.coords).eqls([
3448
+ "vector",
3449
+ 3,
3450
+ -9,
3451
+ ]);
3452
+ expect(stateVariables["/copymap1b/a/_point1"].stateValues.coords).eqls([
3453
+ "vector",
3454
+ -3,
3455
+ 9,
3456
+ ]);
3457
+ expect(stateVariables["/copymap2b/q/_point1"].stateValues.coords).eqls([
3458
+ "vector",
3459
+ 3,
3460
+ -9,
3461
+ ]);
3462
+ expect(stateVariables["/g4/a/_point1"].stateValues.coords).eqls([
3463
+ "vector",
3464
+ -3,
3465
+ 9,
3466
+ ]);
3467
+ expect(stateVariables["/g4/q/_point1"].stateValues.coords).eqls([
3468
+ "vector",
3469
+ 3,
3470
+ -9,
3471
+ ]);
3472
+ expect(stateVariables["/b/_point1"].stateValues.coords).eqls([
3473
+ "vector",
3474
+ -4,
3475
+ 12,
3476
+ ]);
3477
+ expect(stateVariables["/r/_point1"].stateValues.coords).eqls([
3478
+ "vector",
3479
+ 4,
3480
+ -12,
3481
+ ]);
3482
+ expect(stateVariables["/copymap1/b/_point1"].stateValues.coords).eqls([
3483
+ "vector",
3484
+ -4,
3485
+ 12,
3486
+ ]);
3487
+ expect(stateVariables["/copymap2/r/_point1"].stateValues.coords).eqls([
3488
+ "vector",
3489
+ 4,
3490
+ -12,
3491
+ ]);
3492
+ expect(stateVariables["/copymap1b/b/_point1"].stateValues.coords).eqls([
3493
+ "vector",
3494
+ -4,
3495
+ 12,
3496
+ ]);
3497
+ expect(stateVariables["/copymap2b/r/_point1"].stateValues.coords).eqls([
3498
+ "vector",
3499
+ 4,
3500
+ -12,
3501
+ ]);
3502
+ expect(stateVariables["/g4/b/_point1"].stateValues.coords).eqls([
3503
+ "vector",
3504
+ -4,
3505
+ 12,
3506
+ ]);
3507
+ expect(stateVariables["/g4/r/_point1"].stateValues.coords).eqls([
3508
+ "vector",
3509
+ 4,
3510
+ -12,
3511
+ ]);
3512
+ expect(stateVariables["/c/_point1"].stateValues.coords).eqls([
3513
+ "vector",
3514
+ -5,
3515
+ 15,
3516
+ ]);
3517
+ expect(stateVariables["/s/_point1"].stateValues.coords).eqls([
3518
+ "vector",
3519
+ 5,
3520
+ -15,
3521
+ ]);
3522
+ expect(stateVariables["/copymap1/c/_point1"].stateValues.coords).eqls([
3523
+ "vector",
3524
+ -5,
3525
+ 15,
3526
+ ]);
3527
+ expect(stateVariables["/copymap2/s/_point1"].stateValues.coords).eqls([
3528
+ "vector",
3529
+ 5,
3530
+ -15,
3531
+ ]);
3532
+ expect(stateVariables["/copymap1b/c/_point1"].stateValues.coords).eqls([
3533
+ "vector",
3534
+ -5,
3535
+ 15,
3536
+ ]);
3537
+ expect(stateVariables["/copymap2b/s/_point1"].stateValues.coords).eqls([
3538
+ "vector",
3539
+ 5,
3540
+ -15,
3541
+ ]);
3542
+ expect(stateVariables["/g4/c/_point1"].stateValues.coords).eqls([
3543
+ "vector",
3544
+ -5,
3545
+ 15,
3546
+ ]);
3547
+ expect(stateVariables["/g4/s/_point1"].stateValues.coords).eqls([
3548
+ "vector",
3549
+ 5,
3550
+ -15,
3551
+ ]);
3552
+ });
3553
+ });
3554
+ });
3555
+
3556
+ it("map points to adapt to math", () => {
3557
+ cy.window().then(async (win) => {
3558
+ win.postMessage(
3559
+ {
3560
+ doenetML: `
3561
+ <text>a</text>
3562
+ <p>Number of points: <mathinput name="number"/></p>
3563
+ <p>Step size: <mathinput name="step" /></p>
3564
+
3565
+ <math>
3566
+ <map>
3567
+ <template><point>($n, sin($n))</point></template>
3568
+ <sources alias="n">
3569
+ <sequence from="2" length="$number" step="$step" />
3570
+ </sources>
3571
+ </map>
3572
+ </math>
3573
+ <copy prop="value" target="number" assignNames="number2" />
3574
+ <copy prop="value" target="step" assignNames="step2" />
3575
+ `,
3576
+ },
3577
+ "*",
3578
+ );
3579
+ });
3580
+
3581
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
3582
+
3583
+ cy.window().then(async (win) => {
3584
+ let stateVariables = await win.returnAllStateVariables1();
3585
+ expect(stateVariables["/_math1"].activeChildren.length).eq(0);
3586
+ });
3587
+
3588
+ cy.get(cesc2("#/number") + " textarea").type("10{enter}", { force: true });
3589
+ cy.get(cesc2("#/number2")).should("contain.text", "10");
3590
+ cy.window().then(async (win) => {
3591
+ let stateVariables = await win.returnAllStateVariables1();
3592
+ expect(stateVariables["/_math1"].activeChildren.length).eq(0);
3593
+ });
3594
+
3595
+ cy.get(cesc2("#/step") + " textarea").type("1{enter}", { force: true });
3596
+ cy.get(cesc2("#/step2")).should("contain.text", "1");
3597
+ cy.window().then(async (win) => {
3598
+ let stateVariables = await win.returnAllStateVariables1();
3599
+ expect(stateVariables["/_math1"].activeChildren.length).eq(10);
3600
+ for (let i = 0; i < 10; i++) {
3601
+ let j = i + 2;
3602
+ expect(
3603
+ stateVariables[
3604
+ stateVariables["/_math1"].activeChildren[i].componentName
3605
+ ].stateValues.value,
3606
+ ).eqls(["vector", j, ["apply", "sin", j]]);
3607
+ }
3608
+ });
3609
+
3610
+ cy.get(cesc2("#/number") + " textarea").type(
3611
+ "{end}{backspace}{backspace}20{enter}",
3612
+ { force: true },
3613
+ );
3614
+ cy.get(cesc2("#/number2")).should("contain.text", "20");
3615
+
3616
+ cy.window().then(async (win) => {
3617
+ let stateVariables = await win.returnAllStateVariables1();
3618
+ expect(stateVariables["/_math1"].activeChildren.length).eq(20);
3619
+ for (let i = 0; i < 20; i++) {
3620
+ let j = i + 2;
3621
+ expect(
3622
+ stateVariables[
3623
+ stateVariables["/_math1"].activeChildren[i].componentName
3624
+ ].stateValues.value,
3625
+ ).eqls(["vector", j, ["apply", "sin", j]]);
3626
+ }
3627
+ });
3628
+
3629
+ cy.get(cesc2("#/step") + " textarea").type("{end}{backspace}0.5{enter}", {
3630
+ force: true,
3631
+ });
3632
+ cy.get(cesc2("#/step2")).should("contain.text", "0.5");
3633
+ cy.window().then(async (win) => {
3634
+ let stateVariables = await win.returnAllStateVariables1();
3635
+ expect(stateVariables["/_math1"].activeChildren.length).eq(20);
3636
+ for (let i = 0; i < 20; i++) {
3637
+ let j = 2 + i * 0.5;
3638
+ if (Number.isInteger(j)) {
3639
+ expect(
3640
+ stateVariables[
3641
+ stateVariables["/_math1"].activeChildren[i].componentName
3642
+ ].stateValues.value,
3643
+ ).eqls(["vector", j, ["apply", "sin", j]]);
3644
+ } else {
3645
+ let val =
3646
+ stateVariables[
3647
+ stateVariables["/_math1"].activeChildren[i].componentName
3648
+ ].stateValues.value;
3649
+ expect(val[0]).eq("vector");
3650
+ expect(val[1]).eq(j);
3651
+ expect(val[2]).closeTo(Math.sin(j), 1e14);
3652
+ }
3653
+ }
3654
+ });
3655
+
3656
+ cy.get(cesc2("#/number") + " textarea").type(
3657
+ "{end}{backspace}{backspace}10{enter}",
3658
+ { force: true },
3659
+ );
3660
+ cy.get(cesc2("#/number2")).should("contain.text", "10");
3661
+ cy.window().then(async (win) => {
3662
+ let stateVariables = await win.returnAllStateVariables1();
3663
+ expect(stateVariables["/_math1"].activeChildren.length).eq(10);
3664
+ for (let i = 0; i < 10; i++) {
3665
+ let j = 2 + i * 0.5;
3666
+ if (Number.isInteger(j)) {
3667
+ expect(
3668
+ stateVariables[
3669
+ stateVariables["/_math1"].activeChildren[i].componentName
3670
+ ].stateValues.value,
3671
+ ).eqls(["vector", j, ["apply", "sin", j]]);
3672
+ } else {
3673
+ let val =
3674
+ stateVariables[
3675
+ stateVariables["/_math1"].activeChildren[i].componentName
3676
+ ].stateValues.value;
3677
+ expect(val[0]).eq("vector");
3678
+ expect(val[1]).eq(j);
3679
+ expect(val[2]).closeTo(Math.sin(j), 1e14);
3680
+ }
3681
+ }
3682
+ });
3683
+
3684
+ cy.get(cesc2("#/step") + " textarea").type(
3685
+ "{ctrl+home}{shift+end}{backspace}{enter}",
3686
+ { force: true },
3687
+ );
3688
+ cy.get(cesc2("#/step2")).should("contain.text", "\uff3f");
3689
+ cy.window().then(async (win) => {
3690
+ let stateVariables = await win.returnAllStateVariables1();
3691
+ expect(stateVariables["/_math1"].activeChildren.length).eq(0);
3692
+ });
3693
+
3694
+ cy.get(cesc2("#/number") + " textarea").type(
3695
+ "{end}{backspace}{backspace}5{enter}",
3696
+ { force: true },
3697
+ );
3698
+ cy.get(cesc2("#/number2")).should("contain.text", "5");
3699
+ cy.window().then(async (win) => {
3700
+ let stateVariables = await win.returnAllStateVariables1();
3701
+ expect(stateVariables["/_math1"].activeChildren.length).eq(0);
3702
+ });
3703
+
3704
+ cy.get(cesc2("#/step") + " textarea").type("-3{enter}", { force: true });
3705
+ cy.get(cesc2("#/step2")).should("contain.text", `${nInDOM(-3)}`);
3706
+ cy.window().then(async (win) => {
3707
+ let stateVariables = await win.returnAllStateVariables1();
3708
+ expect(stateVariables["/_math1"].activeChildren.length).eq(5);
3709
+ for (let i = 0; i < 5; i++) {
3710
+ let j = 2 - i * 3;
3711
+ expect(
3712
+ stateVariables[
3713
+ stateVariables["/_math1"].activeChildren[i].componentName
3714
+ ].stateValues.value,
3715
+ ).eqls(["vector", j, ["apply", "sin", j]]);
3716
+ }
3717
+ });
3718
+ });
3719
+
3720
+ it("map inside sources of map", () => {
3721
+ cy.window().then(async (win) => {
3722
+ win.postMessage(
3723
+ {
3724
+ doenetML: `
3725
+ <text>a</text>
3726
+ <p>Number of points: <mathinput name="number"/></p>
3727
+
3728
+ <map name="m1" assignNames="p1 p2 p3">
3729
+ <template newNamespace><point name="pt">($n, 2$n)</point></template>
3730
+ <sources alias="n">
3731
+ <sequence length="$number" />
3732
+ </sources>
3733
+ </map>
3734
+
3735
+ <map name="m2" assignNames="q1 q2 q3">
3736
+ <template newNamespace>
3737
+ <point name="pt">(<copy target="p" prop="x" />^2, <copy target="p" prop="y" />^2)</point>
3738
+ </template>
3739
+ <sources alias="p">
3740
+ <copy target="m1" />
3741
+ </sources>
3742
+ </map>
3743
+
3744
+ p1a: <copy target="p1" assignNames="p1a" />,
3745
+ p1b: <copy target="p1/pt" assignNames="p1b" />,
3746
+ p2a: <copy target="p2" assignNames="p2a" />,
3747
+ p2b: <copy target="p2/pt" assignNames="p2b" />,
3748
+ p3a: <copy target="p3" assignNames="p3a" />,
3749
+ p3b: <copy target="p3/pt" assignNames="p3b" />,
3750
+
3751
+ q1a: <copy target="q1" assignNames="q1a" />,
3752
+ q1b: <copy target="q1/pt" assignNames="q1b" />,
3753
+ q2a: <copy target="q2" assignNames="q2a" />,
3754
+ q2b: <copy target="q2/pt" assignNames="q2b" />,
3755
+ q3a: <copy target="q3" assignNames="q3a" />,
3756
+ q3b: <copy target="q3/pt" assignNames="q3b" />,
3757
+
3758
+ <p><copy prop="value" target="number" assignNames="number2" /></p>
3759
+
3760
+ `,
3761
+ },
3762
+ "*",
3763
+ );
3764
+ });
3765
+
3766
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
3767
+
3768
+ cy.get(cesc2("#/p1/pt")).should("not.exist");
3769
+ cy.get(cesc2("#/p1a/pt")).should("not.exist");
3770
+ cy.get(cesc2("#/p1b")).should("not.exist");
3771
+ cy.get(cesc2("#/p2/pt")).should("not.exist");
3772
+ cy.get(cesc2("#/p2a/pt")).should("not.exist");
3773
+ cy.get(cesc2("#/p2b")).should("not.exist");
3774
+ cy.get(cesc2("#/p3/pt")).should("not.exist");
3775
+ cy.get(cesc2("#/p3a/pt")).should("not.exist");
3776
+ cy.get(cesc2("#/p3b")).should("not.exist");
3777
+
3778
+ cy.get(cesc2("#/q1/pt")).should("not.exist");
3779
+ cy.get(cesc2("#/q1a/pt")).should("not.exist");
3780
+ cy.get(cesc2("#/q1b")).should("not.exist");
3781
+ cy.get(cesc2("#/q2/pt")).should("not.exist");
3782
+ cy.get(cesc2("#/q2a/pt")).should("not.exist");
3783
+ cy.get(cesc2("#/q2b")).should("not.exist");
3784
+ cy.get(cesc2("#/q3/pt")).should("not.exist");
3785
+ cy.get(cesc2("#/q3a/pt")).should("not.exist");
3786
+ cy.get(cesc2("#/q3b")).should("not.exist");
3787
+
3788
+ cy.log("set number to be 2");
3789
+ cy.get(cesc2("#/number") + " textarea").type("{end}{backspace}2{enter}", {
3790
+ force: true,
3791
+ });
3792
+ cy.get(cesc2("#/number")).should("contain.text", "2");
3793
+
3794
+ cy.get(cesc2("#/p1/pt"))
3795
+ .find(".mjx-mrow")
3796
+ .eq(0)
3797
+ .invoke("text")
3798
+ .then((text) => {
3799
+ expect(text.trim()).equal("(1,2)");
3800
+ });
3801
+ cy.get(cesc2("#/p1a/pt"))
3802
+ .find(".mjx-mrow")
3803
+ .eq(0)
3804
+ .invoke("text")
3805
+ .then((text) => {
3806
+ expect(text.trim()).equal("(1,2)");
3807
+ });
3808
+ cy.get(cesc2("#/p1b"))
3809
+ .find(".mjx-mrow")
3810
+ .eq(0)
3811
+ .invoke("text")
3812
+ .then((text) => {
3813
+ expect(text.trim()).equal("(1,2)");
3814
+ });
3815
+
3816
+ cy.get(cesc2("#/p2/pt"))
3817
+ .find(".mjx-mrow")
3818
+ .eq(0)
3819
+ .invoke("text")
3820
+ .then((text) => {
3821
+ expect(text.trim()).equal("(2,4)");
3822
+ });
3823
+ cy.get(cesc2("#/p2a/pt"))
3824
+ .find(".mjx-mrow")
3825
+ .eq(0)
3826
+ .invoke("text")
3827
+ .then((text) => {
3828
+ expect(text.trim()).equal("(2,4)");
3829
+ });
3830
+ cy.get(cesc2("#/p2b"))
3831
+ .find(".mjx-mrow")
3832
+ .eq(0)
3833
+ .invoke("text")
3834
+ .then((text) => {
3835
+ expect(text.trim()).equal("(2,4)");
3836
+ });
3837
+
3838
+ cy.get(cesc2("#/p3/pt")).should("not.exist");
3839
+ cy.get(cesc2("#/p3a/pt")).should("not.exist");
3840
+ cy.get(cesc2("#/p3b")).should("not.exist");
3841
+
3842
+ cy.get(cesc2("#/q1/pt"))
3843
+ .find(".mjx-mrow")
3844
+ .eq(0)
3845
+ .invoke("text")
3846
+ .then((text) => {
3847
+ expect(text.trim()).equal("(1,4)");
3848
+ });
3849
+ cy.get(cesc2("#/q1a/pt"))
3850
+ .find(".mjx-mrow")
3851
+ .eq(0)
3852
+ .invoke("text")
3853
+ .then((text) => {
3854
+ expect(text.trim()).equal("(1,4)");
3855
+ });
3856
+ cy.get(cesc2("#/q1b"))
3857
+ .find(".mjx-mrow")
3858
+ .eq(0)
3859
+ .invoke("text")
3860
+ .then((text) => {
3861
+ expect(text.trim()).equal("(1,4)");
3862
+ });
3863
+
3864
+ cy.get(cesc2("#/q2/pt"))
3865
+ .find(".mjx-mrow")
3866
+ .eq(0)
3867
+ .invoke("text")
3868
+ .then((text) => {
3869
+ expect(text.trim()).equal("(4,16)");
3870
+ });
3871
+ cy.get(cesc2("#/q2a/pt"))
3872
+ .find(".mjx-mrow")
3873
+ .eq(0)
3874
+ .invoke("text")
3875
+ .then((text) => {
3876
+ expect(text.trim()).equal("(4,16)");
3877
+ });
3878
+ cy.get(cesc2("#/q2b"))
3879
+ .find(".mjx-mrow")
3880
+ .eq(0)
3881
+ .invoke("text")
3882
+ .then((text) => {
3883
+ expect(text.trim()).equal("(4,16)");
3884
+ });
3885
+
3886
+ cy.get(cesc2("#/q3/pt")).should("not.exist");
3887
+ cy.get(cesc2("#/q3a/pt")).should("not.exist");
3888
+ cy.get(cesc2("#/q3b")).should("not.exist");
3889
+
3890
+ cy.log("set number to be 1");
3891
+ cy.get(cesc2("#/number") + " textarea").type("{end}{backspace}1{enter}", {
3892
+ force: true,
3893
+ });
3894
+ cy.get(cesc2("#/number")).should("contain.text", "1");
3895
+
3896
+ cy.get(cesc2("#/p1/pt"))
3897
+ .find(".mjx-mrow")
3898
+ .eq(0)
3899
+ .invoke("text")
3900
+ .then((text) => {
3901
+ expect(text.trim()).equal("(1,2)");
3902
+ });
3903
+ cy.get(cesc2("#/p1a/pt"))
3904
+ .find(".mjx-mrow")
3905
+ .eq(0)
3906
+ .invoke("text")
3907
+ .then((text) => {
3908
+ expect(text.trim()).equal("(1,2)");
3909
+ });
3910
+ cy.get(cesc2("#/p1b"))
3911
+ .find(".mjx-mrow")
3912
+ .eq(0)
3913
+ .invoke("text")
3914
+ .then((text) => {
3915
+ expect(text.trim()).equal("(1,2)");
3916
+ });
3917
+
3918
+ cy.get(cesc2("#/p2/pt")).should("not.exist");
3919
+ cy.get(cesc2("#/p2a/pt")).should("not.exist");
3920
+ cy.get(cesc2("#/p2b")).should("not.exist");
3921
+ cy.get(cesc2("#/p3/pt")).should("not.exist");
3922
+ cy.get(cesc2("#/p3a/pt")).should("not.exist");
3923
+ cy.get(cesc2("#/p3b")).should("not.exist");
3924
+
3925
+ cy.get(cesc2("#/q1/pt"))
3926
+ .find(".mjx-mrow")
3927
+ .eq(0)
3928
+ .invoke("text")
3929
+ .then((text) => {
3930
+ expect(text.trim()).equal("(1,4)");
3931
+ });
3932
+ cy.get(cesc2("#/q1a/pt"))
3933
+ .find(".mjx-mrow")
3934
+ .eq(0)
3935
+ .invoke("text")
3936
+ .then((text) => {
3937
+ expect(text.trim()).equal("(1,4)");
3938
+ });
3939
+ cy.get(cesc2("#/q1b"))
3940
+ .find(".mjx-mrow")
3941
+ .eq(0)
3942
+ .invoke("text")
3943
+ .then((text) => {
3944
+ expect(text.trim()).equal("(1,4)");
3945
+ });
3946
+
3947
+ cy.get(cesc2("#/q2/pt")).should("not.exist");
3948
+ cy.get(cesc2("#/q2a/pt")).should("not.exist");
3949
+ cy.get(cesc2("#/q2b")).should("not.exist");
3950
+ cy.get(cesc2("#/q3/pt")).should("not.exist");
3951
+ cy.get(cesc2("#/q3a/pt")).should("not.exist");
3952
+ cy.get(cesc2("#/q3b")).should("not.exist");
3953
+
3954
+ cy.log("set number to be 3");
3955
+ cy.get(cesc2("#/number") + " textarea").type("{end}{backspace}3{enter}", {
3956
+ force: true,
3957
+ });
3958
+ cy.get(cesc2("#/number")).should("contain.text", "3");
3959
+
3960
+ cy.get(cesc2("#/p1/pt"))
3961
+ .find(".mjx-mrow")
3962
+ .eq(0)
3963
+ .invoke("text")
3964
+ .then((text) => {
3965
+ expect(text.trim()).equal("(1,2)");
3966
+ });
3967
+ cy.get(cesc2("#/p1a/pt"))
3968
+ .find(".mjx-mrow")
3969
+ .eq(0)
3970
+ .invoke("text")
3971
+ .then((text) => {
3972
+ expect(text.trim()).equal("(1,2)");
3973
+ });
3974
+ cy.get(cesc2("#/p1b"))
3975
+ .find(".mjx-mrow")
3976
+ .eq(0)
3977
+ .invoke("text")
3978
+ .then((text) => {
3979
+ expect(text.trim()).equal("(1,2)");
3980
+ });
3981
+
3982
+ cy.get(cesc2("#/p2/pt"))
3983
+ .find(".mjx-mrow")
3984
+ .eq(0)
3985
+ .invoke("text")
3986
+ .then((text) => {
3987
+ expect(text.trim()).equal("(2,4)");
3988
+ });
3989
+ cy.get(cesc2("#/p2a/pt"))
3990
+ .find(".mjx-mrow")
3991
+ .eq(0)
3992
+ .invoke("text")
3993
+ .then((text) => {
3994
+ expect(text.trim()).equal("(2,4)");
3995
+ });
3996
+ cy.get(cesc2("#/p2b"))
3997
+ .find(".mjx-mrow")
3998
+ .eq(0)
3999
+ .invoke("text")
4000
+ .then((text) => {
4001
+ expect(text.trim()).equal("(2,4)");
4002
+ });
4003
+
4004
+ cy.get(cesc2("#/p3/pt"))
4005
+ .find(".mjx-mrow")
4006
+ .eq(0)
4007
+ .invoke("text")
4008
+ .then((text) => {
4009
+ expect(text.trim()).equal("(3,6)");
4010
+ });
4011
+ cy.get(cesc2("#/p3a/pt"))
4012
+ .find(".mjx-mrow")
4013
+ .eq(0)
4014
+ .invoke("text")
4015
+ .then((text) => {
4016
+ expect(text.trim()).equal("(3,6)");
4017
+ });
4018
+ cy.get(cesc2("#/p3b"))
4019
+ .find(".mjx-mrow")
4020
+ .eq(0)
4021
+ .invoke("text")
4022
+ .then((text) => {
4023
+ expect(text.trim()).equal("(3,6)");
4024
+ });
4025
+
4026
+ cy.get(cesc2("#/q1/pt"))
4027
+ .find(".mjx-mrow")
4028
+ .eq(0)
4029
+ .invoke("text")
4030
+ .then((text) => {
4031
+ expect(text.trim()).equal("(1,4)");
4032
+ });
4033
+ cy.get(cesc2("#/q1a/pt"))
4034
+ .find(".mjx-mrow")
4035
+ .eq(0)
4036
+ .invoke("text")
4037
+ .then((text) => {
4038
+ expect(text.trim()).equal("(1,4)");
4039
+ });
4040
+ cy.get(cesc2("#/q1b"))
4041
+ .find(".mjx-mrow")
4042
+ .eq(0)
4043
+ .invoke("text")
4044
+ .then((text) => {
4045
+ expect(text.trim()).equal("(1,4)");
4046
+ });
4047
+
4048
+ cy.get(cesc2("#/q2/pt"))
4049
+ .find(".mjx-mrow")
4050
+ .eq(0)
4051
+ .invoke("text")
4052
+ .then((text) => {
4053
+ expect(text.trim()).equal("(4,16)");
4054
+ });
4055
+ cy.get(cesc2("#/q2a/pt"))
4056
+ .find(".mjx-mrow")
4057
+ .eq(0)
4058
+ .invoke("text")
4059
+ .then((text) => {
4060
+ expect(text.trim()).equal("(4,16)");
4061
+ });
4062
+ cy.get(cesc2("#/q2b"))
4063
+ .find(".mjx-mrow")
4064
+ .eq(0)
4065
+ .invoke("text")
4066
+ .then((text) => {
4067
+ expect(text.trim()).equal("(4,16)");
4068
+ });
4069
+
4070
+ cy.get(cesc2("#/q3/pt"))
4071
+ .find(".mjx-mrow")
4072
+ .eq(0)
4073
+ .invoke("text")
4074
+ .then((text) => {
4075
+ expect(text.trim()).equal("(9,36)");
4076
+ });
4077
+ cy.get(cesc2("#/q3a/pt"))
4078
+ .find(".mjx-mrow")
4079
+ .eq(0)
4080
+ .invoke("text")
4081
+ .then((text) => {
4082
+ expect(text.trim()).equal("(9,36)");
4083
+ });
4084
+ cy.get(cesc2("#/q3b"))
4085
+ .find(".mjx-mrow")
4086
+ .eq(0)
4087
+ .invoke("text")
4088
+ .then((text) => {
4089
+ expect(text.trim()).equal("(9,36)");
4090
+ });
4091
+
4092
+ cy.log("set number back to zero");
4093
+ cy.get(cesc2("#/number") + " textarea").type("{end}{backspace}0{enter}", {
4094
+ force: true,
4095
+ });
4096
+ cy.get(cesc2("#/number")).should("contain.text", "0");
4097
+
4098
+ cy.get(cesc2("#/p1/pt")).should("not.exist");
4099
+ cy.get(cesc2("#/p1a/pt")).should("not.exist");
4100
+ cy.get(cesc2("#/p1b")).should("not.exist");
4101
+ cy.get(cesc2("#/p2/pt")).should("not.exist");
4102
+ cy.get(cesc2("#/p2a/pt")).should("not.exist");
4103
+ cy.get(cesc2("#/p2b")).should("not.exist");
4104
+ cy.get(cesc2("#/p3/pt")).should("not.exist");
4105
+ cy.get(cesc2("#/p3a/pt")).should("not.exist");
4106
+ cy.get(cesc2("#/p3b")).should("not.exist");
4107
+
4108
+ cy.get(cesc2("#/q1/pt")).should("not.exist");
4109
+ cy.get(cesc2("#/q1a/pt")).should("not.exist");
4110
+ cy.get(cesc2("#/q1b")).should("not.exist");
4111
+ cy.get(cesc2("#/q2/pt")).should("not.exist");
4112
+ cy.get(cesc2("#/q2a/pt")).should("not.exist");
4113
+ cy.get(cesc2("#/q2b")).should("not.exist");
4114
+ cy.get(cesc2("#/q3/pt")).should("not.exist");
4115
+ cy.get(cesc2("#/q3a/pt")).should("not.exist");
4116
+ cy.get(cesc2("#/q3b")).should("not.exist");
4117
+
4118
+ cy.log("set number back to 1");
4119
+ cy.get(cesc2("#/number") + " textarea").type("{end}{backspace}1{enter}", {
4120
+ force: true,
4121
+ });
4122
+ cy.get(cesc2("#/number")).should("contain.text", "1");
4123
+
4124
+ cy.get(cesc2("#/p1/pt"))
4125
+ .find(".mjx-mrow")
4126
+ .eq(0)
4127
+ .invoke("text")
4128
+ .then((text) => {
4129
+ expect(text.trim()).equal("(1,2)");
4130
+ });
4131
+ cy.get(cesc2("#/p1a/pt"))
4132
+ .find(".mjx-mrow")
4133
+ .eq(0)
4134
+ .invoke("text")
4135
+ .then((text) => {
4136
+ expect(text.trim()).equal("(1,2)");
4137
+ });
4138
+ cy.get(cesc2("#/p1b"))
4139
+ .find(".mjx-mrow")
4140
+ .eq(0)
4141
+ .invoke("text")
4142
+ .then((text) => {
4143
+ expect(text.trim()).equal("(1,2)");
4144
+ });
4145
+
4146
+ cy.get(cesc2("#/p2/pt")).should("not.exist");
4147
+ cy.get(cesc2("#/p2a/pt")).should("not.exist");
4148
+ cy.get(cesc2("#/p2b")).should("not.exist");
4149
+ cy.get(cesc2("#/p3/pt")).should("not.exist");
4150
+ cy.get(cesc2("#/p3a/pt")).should("not.exist");
4151
+ cy.get(cesc2("#/p3b")).should("not.exist");
4152
+
4153
+ cy.get(cesc2("#/q1/pt"))
4154
+ .find(".mjx-mrow")
4155
+ .eq(0)
4156
+ .invoke("text")
4157
+ .then((text) => {
4158
+ expect(text.trim()).equal("(1,4)");
4159
+ });
4160
+ cy.get(cesc2("#/q1a/pt"))
4161
+ .find(".mjx-mrow")
4162
+ .eq(0)
4163
+ .invoke("text")
4164
+ .then((text) => {
4165
+ expect(text.trim()).equal("(1,4)");
4166
+ });
4167
+ cy.get(cesc2("#/q1b"))
4168
+ .find(".mjx-mrow")
4169
+ .eq(0)
4170
+ .invoke("text")
4171
+ .then((text) => {
4172
+ expect(text.trim()).equal("(1,4)");
4173
+ });
4174
+
4175
+ cy.get(cesc2("#/q2/pt")).should("not.exist");
4176
+ cy.get(cesc2("#/q2a/pt")).should("not.exist");
4177
+ cy.get(cesc2("#/q2b")).should("not.exist");
4178
+ cy.get(cesc2("#/q3/pt")).should("not.exist");
4179
+ cy.get(cesc2("#/q3a/pt")).should("not.exist");
4180
+ cy.get(cesc2("#/q3b")).should("not.exist");
4181
+ });
4182
+
4183
+ it("can override fixed of source index", () => {
4184
+ cy.window().then(async (win) => {
4185
+ win.postMessage(
4186
+ {
4187
+ doenetML: `
4188
+ <text>a</text>
4189
+ <map assignNames="a b">
4190
+ <template newNamespace>
4191
+ <copy target="i" assignNames="ind" />
4192
+ <mathinput bindValueTo="$ind" />
4193
+ </template>
4194
+ <sources indexAlias="i"><text>red</text><text>yellow</text></sources>
4195
+ </map>
4196
+ <map assignNames="c d">
4197
+ <template newNamespace>
4198
+ <copy target="i" assignNames="ind" fixed="false" />
4199
+ <mathinput bindValueTo="$ind" />
4200
+ </template>
4201
+ <sources indexAlias="i"><text>red</text><text>yellow</text></sources>
4202
+ </map>
4203
+
4204
+
4205
+ `,
4206
+ },
4207
+ "*",
4208
+ );
4209
+ });
4210
+
4211
+ cy.get(cesc2("#/_text1")).should("have.text", "a"); //wait for window to load
4212
+
4213
+ cy.get(cesc2("#/a/ind")).should("have.text", "1");
4214
+ cy.get(cesc2("#/b/ind")).should("have.text", "2");
4215
+ cy.get(cesc2("#/c/ind")).should("have.text", "1");
4216
+ cy.get(cesc2("#/d/ind")).should("have.text", "2");
4217
+
4218
+ cy.get(cesc2("#/a/_mathinput1") + " textarea").type(
4219
+ "{end}{backspace}3{enter}",
4220
+ { force: true },
4221
+ );
4222
+ cy.get(cesc2("#/b/_mathinput1") + " textarea").type(
4223
+ "{end}{backspace}4{enter}",
4224
+ { force: true },
4225
+ );
4226
+ cy.get(cesc2("#/c/_mathinput1") + " textarea").type(
4227
+ "{end}{backspace}5{enter}",
4228
+ { force: true },
4229
+ );
4230
+ cy.get(cesc2("#/d/_mathinput1") + " textarea").type(
4231
+ "{end}{backspace}6{enter}",
4232
+ { force: true },
4233
+ );
4234
+
4235
+ cy.get(cesc2("#/d/ind")).should("have.text", "6");
4236
+ cy.get(cesc2("#/a/ind")).should("have.text", "1");
4237
+ cy.get(cesc2("#/b/ind")).should("have.text", "2");
4238
+ cy.get(cesc2("#/c/ind")).should("have.text", "5");
4239
+
4240
+ cy.get(cesc2("#/a/_mathinput1") + " textarea").type("{end}x{enter}", {
4241
+ force: true,
4242
+ });
4243
+ cy.get(cesc2("#/b/_mathinput1") + " textarea").type("{end}x{enter}", {
4244
+ force: true,
4245
+ });
4246
+ cy.get(cesc2("#/c/_mathinput1") + " textarea").type("{end}x{enter}", {
4247
+ force: true,
4248
+ });
4249
+ cy.get(cesc2("#/d/_mathinput1") + " textarea").type("{end}x{enter}", {
4250
+ force: true,
4251
+ });
4252
+
4253
+ cy.get(cesc2("#/d/ind")).should("have.text", "NaN");
4254
+ cy.get(cesc2("#/a/ind")).should("have.text", "1");
4255
+ cy.get(cesc2("#/b/ind")).should("have.text", "2");
4256
+ cy.get(cesc2("#/c/ind")).should("have.text", "NaN");
4257
+
4258
+ cy.get(cesc2("#/a/_mathinput1") + " textarea").type(
4259
+ "{ctrl+home}{shift+end}{backspace}7{enter}",
4260
+ { force: true },
4261
+ );
4262
+ cy.get(cesc2("#/b/_mathinput1") + " textarea").type(
4263
+ "{ctrl+home}{shift+end}{backspace}8{enter}",
4264
+ { force: true },
4265
+ );
4266
+ cy.get(cesc2("#/c/_mathinput1") + " textarea").type(
4267
+ "{ctrl+home}{shift+end}{backspace}9{enter}",
4268
+ { force: true },
4269
+ );
4270
+ cy.get(cesc2("#/d/_mathinput1") + " textarea").type(
4271
+ "{ctrl+home}{shift+end}{backspace}10{enter}",
4272
+ { force: true },
4273
+ );
4274
+
4275
+ cy.get(cesc2("#/d/ind")).should("have.text", "10");
4276
+ cy.get(cesc2("#/a/ind")).should("have.text", "1");
4277
+ cy.get(cesc2("#/b/ind")).should("have.text", "2");
4278
+ cy.get(cesc2("#/c/ind")).should("have.text", "9");
4279
+ });
4280
+
4281
+ it("maps hide dynamically", () => {
4282
+ cy.window().then(async (win) => {
4283
+ win.postMessage(
4284
+ {
4285
+ doenetML: `
4286
+ <text>a</text>
4287
+
4288
+ <booleaninput name='h1' prefill="false" >
4289
+ <label>Hide first map</label>
4290
+ </booleaninput>
4291
+ <booleaninput name='h2' prefill="true" >
4292
+ <label>Hide second map</label>
4293
+ </booleaninput>
4294
+ <p>Length of map 1: <mathinput name="n1" prefill="4" /></p>
4295
+ <p>Length of map 2: <mathinput name="n2" prefill="4" /></p>
4296
+
4297
+ <p name="m1">map 1: <map hide="$h1">
4298
+ <template>hi$a </template>
4299
+ <sources alias="a"><sequence length="$n1" /></sources>
4300
+ </map></p>
4301
+ <p name="m2">map 2: <map hide="$h2">
4302
+ <template>hi$a </template>
4303
+ <sources alias="a"><sequence length="$n2" /></sources>
4304
+ </map></p>
4305
+
4306
+ <p>
4307
+ <copy prop="value" target="h1" assignNames="h1a" />
4308
+ <copy prop="value" target="h2" assignNames="h2a" />
4309
+ <copy prop="value" target="n1" assignNames="n1a" />
4310
+ <copy prop="value" target="n2" assignNames="n2a" />
4311
+ </p>
4312
+ `,
4313
+ },
4314
+ "*",
4315
+ );
4316
+ });
4317
+
4318
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load
4319
+
4320
+ cy.get(cesc("#\\/m1")).should("have.text", "map 1: hi1 hi2 hi3 hi4 ");
4321
+ cy.get(cesc("#\\/m2")).should("have.text", "map 2: ");
4322
+
4323
+ cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}6{enter}", {
4324
+ force: true,
4325
+ });
4326
+ cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}6{enter}", {
4327
+ force: true,
4328
+ });
4329
+ cy.get(cesc("#\\/n2a")).should("contain.text", "6");
4330
+ cy.get(cesc("#\\/n1a")).should("contain.text", "6");
4331
+
4332
+ cy.get(cesc("#\\/m1")).should(
4333
+ "have.text",
4334
+ "map 1: hi1 hi2 hi3 hi4 hi5 hi6 ",
4335
+ );
4336
+ cy.get(cesc("#\\/m2")).should("have.text", "map 2: ");
4337
+
4338
+ cy.get(cesc("#\\/h1")).click();
4339
+ cy.get(cesc("#\\/h2")).click();
4340
+ cy.get(cesc("#\\/h2a")).should("contain.text", "false");
4341
+ cy.get(cesc("#\\/h1a")).should("contain.text", "true");
4342
+
4343
+ cy.get(cesc("#\\/m1")).should("have.text", "map 1: ");
4344
+ cy.get(cesc("#\\/m2")).should(
4345
+ "have.text",
4346
+ "map 2: hi1 hi2 hi3 hi4 hi5 hi6 ",
4347
+ );
4348
+
4349
+ cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}8{enter}", {
4350
+ force: true,
4351
+ });
4352
+ cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}8{enter}", {
4353
+ force: true,
4354
+ });
4355
+ cy.get(cesc("#\\/n2a")).should("contain.text", "8");
4356
+ cy.get(cesc("#\\/n1a")).should("contain.text", "8");
4357
+
4358
+ cy.get(cesc("#\\/m1")).should("have.text", "map 1: ");
4359
+ cy.get(cesc("#\\/m2")).should(
4360
+ "have.text",
4361
+ "map 2: hi1 hi2 hi3 hi4 hi5 hi6 hi7 hi8 ",
4362
+ );
4363
+
4364
+ cy.get(cesc("#\\/h1")).click();
4365
+ cy.get(cesc("#\\/h2")).click();
4366
+ cy.get(cesc("#\\/h2a")).should("contain.text", "true");
4367
+ cy.get(cesc("#\\/h1a")).should("contain.text", "false");
4368
+
4369
+ cy.get(cesc("#\\/m1")).should(
4370
+ "have.text",
4371
+ "map 1: hi1 hi2 hi3 hi4 hi5 hi6 hi7 hi8 ",
4372
+ );
4373
+ cy.get(cesc("#\\/m2")).should("have.text", "map 2: ");
4374
+
4375
+ cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}3{enter}", {
4376
+ force: true,
4377
+ });
4378
+ cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}3{enter}", {
4379
+ force: true,
4380
+ });
4381
+ cy.get(cesc("#\\/n2a")).should("contain.text", "3");
4382
+ cy.get(cesc("#\\/n1a")).should("contain.text", "3");
4383
+
4384
+ cy.get(cesc("#\\/m1")).should("have.text", "map 1: hi1 hi2 hi3 ");
4385
+ cy.get(cesc("#\\/m2")).should("have.text", "map 2: ");
4386
+
4387
+ cy.get(cesc("#\\/h1")).click();
4388
+ cy.get(cesc("#\\/h2")).click();
4389
+ cy.get(cesc("#\\/h2a")).should("contain.text", "false");
4390
+ cy.get(cesc("#\\/h1a")).should("contain.text", "true");
4391
+
4392
+ cy.get(cesc("#\\/m1")).should("have.text", "map 1: ");
4393
+ cy.get(cesc("#\\/m2")).should("have.text", "map 2: hi1 hi2 hi3 ");
4394
+
4395
+ cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}4{enter}", {
4396
+ force: true,
4397
+ });
4398
+ cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}4{enter}", {
4399
+ force: true,
4400
+ });
4401
+ cy.get(cesc("#\\/n2a")).should("contain.text", "4");
4402
+ cy.get(cesc("#\\/n1a")).should("contain.text", "4");
4403
+
4404
+ cy.get(cesc("#\\/m1")).should("have.text", "map 1: ");
4405
+ cy.get(cesc("#\\/m2")).should("have.text", "map 2: hi1 hi2 hi3 hi4 ");
4406
+ });
4407
+
4408
+ it("properly create unique name to avoid duplicate names", () => {
4409
+ cy.window().then(async (win) => {
4410
+ win.postMessage(
4411
+ {
4412
+ doenetML: `
4413
+ <text>a</text>
4414
+ <map assignNames='(n1) (n2) '>
4415
+ <template>
4416
+ <number>$i</number>
4417
+ <number>10*$i</number>
4418
+ </template>
4419
+
4420
+ <sources alias='i'><sequence from='1' to='2' /></sources>
4421
+ </map>
4422
+ `,
4423
+ },
4424
+ "*",
4425
+ );
4426
+ });
4427
+
4428
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load
4429
+
4430
+ cy.get(cesc("#\\/n1")).should("have.text", "1");
4431
+ cy.get(cesc("#\\/n2")).should("have.text", "2");
4432
+
4433
+ cy.window().then(async (win) => {
4434
+ let stateVariables = await win.returnAllStateVariables1();
4435
+ let n1a = stateVariables[
4436
+ stateVariables["/_map1"].replacements[0].componentName
4437
+ ].replacements.filter((s) => s.componentType)[1].componentName;
4438
+ let n2a = stateVariables[
4439
+ stateVariables["/_map1"].replacements[1].componentName
4440
+ ].replacements.filter((s) => s.componentType)[1].componentName;
4441
+
4442
+ expect(stateVariables["/n1"].stateValues.value).eq(1);
4443
+ expect(stateVariables[n1a].stateValues.value).eq(10);
4444
+ expect(stateVariables["/n2"].stateValues.value).eq(2);
4445
+ expect(stateVariables[n2a].stateValues.value).eq(20);
4446
+ });
4447
+ });
4448
+
4449
+ it("bug for isResponse and parallel is fixed", () => {
4450
+ cy.window().then(async (win) => {
4451
+ win.postMessage(
4452
+ {
4453
+ doenetML: `
4454
+ <map isResponse behavior="parallel" assignNames="(p1) (p2)">
4455
+ <template>
4456
+ <p>hi $v</p>
4457
+ </template>
4458
+ <sources alias="v"><sequence length="2" /></sources>
4459
+ </map>
4460
+ `,
4461
+ },
4462
+ "*",
4463
+ );
4464
+ });
4465
+
4466
+ cy.get(cesc("#\\/p1")).should("have.text", "hi 1");
4467
+ cy.get(cesc("#\\/p2")).should("have.text", "hi 2");
4468
+
4469
+ cy.window().then(async (win) => {
4470
+ let stateVariables = await win.returnAllStateVariables1();
4471
+
4472
+ expect(stateVariables["/p1"].stateValues.isResponse).eq(true);
4473
+ expect(stateVariables["/p2"].stateValues.isResponse).eq(true);
4474
+ });
4475
+ });
4476
+ });