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