@teachinglab/omd 0.6.0 → 0.6.2

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 (198) hide show
  1. package/README.md +257 -251
  2. package/README.old.md +137 -137
  3. package/canvas/core/canvasConfig.js +202 -202
  4. package/canvas/drawing/segment.js +167 -167
  5. package/canvas/drawing/stroke.js +385 -385
  6. package/canvas/events/eventManager.js +444 -444
  7. package/canvas/events/pointerEventHandler.js +262 -262
  8. package/canvas/index.js +48 -48
  9. package/canvas/tools/PointerTool.js +71 -71
  10. package/canvas/tools/tool.js +222 -222
  11. package/canvas/utils/boundingBox.js +377 -377
  12. package/canvas/utils/mathUtils.js +258 -258
  13. package/docs/api/configuration-options.md +198 -198
  14. package/docs/api/eventManager.md +82 -82
  15. package/docs/api/focusFrameManager.md +144 -144
  16. package/docs/api/index.md +105 -105
  17. package/docs/api/main.md +62 -62
  18. package/docs/api/omdBinaryExpressionNode.md +86 -86
  19. package/docs/api/omdCanvas.md +83 -83
  20. package/docs/api/omdConfigManager.md +112 -112
  21. package/docs/api/omdConstantNode.md +52 -52
  22. package/docs/api/omdDisplay.md +87 -87
  23. package/docs/api/omdEquationNode.md +174 -174
  24. package/docs/api/omdEquationSequenceNode.md +258 -258
  25. package/docs/api/omdEquationStack.md +192 -192
  26. package/docs/api/omdFunctionNode.md +82 -82
  27. package/docs/api/omdGroupNode.md +78 -78
  28. package/docs/api/omdHelpers.md +87 -87
  29. package/docs/api/omdLeafNode.md +85 -85
  30. package/docs/api/omdNode.md +201 -201
  31. package/docs/api/omdOperationDisplayNode.md +117 -117
  32. package/docs/api/omdOperatorNode.md +91 -91
  33. package/docs/api/omdParenthesisNode.md +133 -133
  34. package/docs/api/omdPopup.md +191 -191
  35. package/docs/api/omdPowerNode.md +131 -131
  36. package/docs/api/omdRationalNode.md +144 -144
  37. package/docs/api/omdSequenceNode.md +128 -128
  38. package/docs/api/omdSimplification.md +78 -78
  39. package/docs/api/omdSqrtNode.md +144 -144
  40. package/docs/api/omdStepVisualizer.md +146 -146
  41. package/docs/api/omdStepVisualizerHighlighting.md +65 -65
  42. package/docs/api/omdStepVisualizerInteractiveSteps.md +108 -108
  43. package/docs/api/omdStepVisualizerLayout.md +70 -70
  44. package/docs/api/omdStepVisualizerNodeUtils.md +140 -140
  45. package/docs/api/omdStepVisualizerTextBoxes.md +76 -76
  46. package/docs/api/omdToolbar.md +130 -130
  47. package/docs/api/omdTranscriptionService.md +95 -95
  48. package/docs/api/omdTreeDiff.md +169 -169
  49. package/docs/api/omdUnaryExpressionNode.md +137 -137
  50. package/docs/api/omdUtilities.md +82 -82
  51. package/docs/api/omdVariableNode.md +123 -123
  52. package/docs/api/selectTool.md +74 -74
  53. package/docs/api/simplificationEngine.md +97 -97
  54. package/docs/api/simplificationRules.md +76 -76
  55. package/docs/api/simplificationUtils.md +64 -64
  56. package/docs/api/transcribe.md +43 -43
  57. package/docs/api-reference.md +85 -85
  58. package/docs/index.html +453 -453
  59. package/docs/index.md +38 -38
  60. package/docs/omd-objects.md +258 -258
  61. package/index.js +79 -79
  62. package/jsvg/index.js +3 -0
  63. package/jsvg/jsvg.js +898 -898
  64. package/jsvg/jsvgComponents.js +357 -358
  65. package/npm-docs/DOCUMENTATION_SUMMARY.md +220 -220
  66. package/npm-docs/README.md +251 -251
  67. package/npm-docs/api/api-reference.md +85 -85
  68. package/npm-docs/api/configuration-options.md +198 -198
  69. package/npm-docs/api/eventManager.md +82 -82
  70. package/npm-docs/api/expression-nodes.md +561 -561
  71. package/npm-docs/api/focusFrameManager.md +144 -144
  72. package/npm-docs/api/index.md +105 -105
  73. package/npm-docs/api/main.md +62 -62
  74. package/npm-docs/api/omdBinaryExpressionNode.md +86 -86
  75. package/npm-docs/api/omdCanvas.md +83 -83
  76. package/npm-docs/api/omdConfigManager.md +112 -112
  77. package/npm-docs/api/omdConstantNode.md +52 -52
  78. package/npm-docs/api/omdDisplay.md +87 -87
  79. package/npm-docs/api/omdEquationNode.md +174 -174
  80. package/npm-docs/api/omdEquationSequenceNode.md +258 -258
  81. package/npm-docs/api/omdEquationStack.md +192 -192
  82. package/npm-docs/api/omdFunctionNode.md +82 -82
  83. package/npm-docs/api/omdGroupNode.md +78 -78
  84. package/npm-docs/api/omdHelpers.md +87 -87
  85. package/npm-docs/api/omdLeafNode.md +85 -85
  86. package/npm-docs/api/omdNode.md +201 -201
  87. package/npm-docs/api/omdOperationDisplayNode.md +117 -117
  88. package/npm-docs/api/omdOperatorNode.md +91 -91
  89. package/npm-docs/api/omdParenthesisNode.md +133 -133
  90. package/npm-docs/api/omdPopup.md +191 -191
  91. package/npm-docs/api/omdPowerNode.md +131 -131
  92. package/npm-docs/api/omdRationalNode.md +144 -144
  93. package/npm-docs/api/omdSequenceNode.md +128 -128
  94. package/npm-docs/api/omdSimplification.md +78 -78
  95. package/npm-docs/api/omdSqrtNode.md +144 -144
  96. package/npm-docs/api/omdStepVisualizer.md +146 -146
  97. package/npm-docs/api/omdStepVisualizerHighlighting.md +65 -65
  98. package/npm-docs/api/omdStepVisualizerInteractiveSteps.md +108 -108
  99. package/npm-docs/api/omdStepVisualizerLayout.md +70 -70
  100. package/npm-docs/api/omdStepVisualizerNodeUtils.md +140 -140
  101. package/npm-docs/api/omdStepVisualizerTextBoxes.md +76 -76
  102. package/npm-docs/api/omdToolbar.md +130 -130
  103. package/npm-docs/api/omdTranscriptionService.md +95 -95
  104. package/npm-docs/api/omdTreeDiff.md +169 -169
  105. package/npm-docs/api/omdUnaryExpressionNode.md +137 -137
  106. package/npm-docs/api/omdUtilities.md +82 -82
  107. package/npm-docs/api/omdVariableNode.md +123 -123
  108. package/npm-docs/api/selectTool.md +74 -74
  109. package/npm-docs/api/simplificationEngine.md +97 -97
  110. package/npm-docs/api/simplificationRules.md +76 -76
  111. package/npm-docs/api/simplificationUtils.md +64 -64
  112. package/npm-docs/api/transcribe.md +43 -43
  113. package/npm-docs/guides/equations.md +854 -854
  114. package/npm-docs/guides/factory-functions.md +354 -354
  115. package/npm-docs/guides/getting-started.md +318 -318
  116. package/npm-docs/guides/quick-examples.md +525 -525
  117. package/npm-docs/guides/visualizations.md +682 -682
  118. package/npm-docs/index.html +12 -0
  119. package/npm-docs/json-schemas.md +826 -826
  120. package/omd/config/omdConfigManager.js +279 -267
  121. package/omd/core/index.js +158 -158
  122. package/omd/core/omdEquationStack.js +546 -546
  123. package/omd/core/omdUtilities.js +113 -113
  124. package/omd/display/omdDisplay.js +969 -962
  125. package/omd/display/omdToolbar.js +501 -501
  126. package/omd/nodes/omdBinaryExpressionNode.js +459 -459
  127. package/omd/nodes/omdConstantNode.js +141 -141
  128. package/omd/nodes/omdEquationNode.js +1327 -1327
  129. package/omd/nodes/omdFunctionNode.js +351 -351
  130. package/omd/nodes/omdGroupNode.js +67 -67
  131. package/omd/nodes/omdLeafNode.js +76 -76
  132. package/omd/nodes/omdNode.js +556 -556
  133. package/omd/nodes/omdOperationDisplayNode.js +321 -321
  134. package/omd/nodes/omdOperatorNode.js +108 -108
  135. package/omd/nodes/omdParenthesisNode.js +292 -292
  136. package/omd/nodes/omdPowerNode.js +235 -235
  137. package/omd/nodes/omdRationalNode.js +295 -295
  138. package/omd/nodes/omdSqrtNode.js +307 -307
  139. package/omd/nodes/omdUnaryExpressionNode.js +227 -227
  140. package/omd/nodes/omdVariableNode.js +122 -122
  141. package/omd/simplification/omdSimplification.js +140 -140
  142. package/omd/simplification/omdSimplificationEngine.js +887 -887
  143. package/omd/simplification/package.json +5 -5
  144. package/omd/simplification/rules/binaryRules.js +1037 -1037
  145. package/omd/simplification/rules/functionRules.js +111 -111
  146. package/omd/simplification/rules/index.js +48 -48
  147. package/omd/simplification/rules/parenthesisRules.js +19 -19
  148. package/omd/simplification/rules/powerRules.js +143 -143
  149. package/omd/simplification/rules/rationalRules.js +725 -725
  150. package/omd/simplification/rules/sqrtRules.js +48 -48
  151. package/omd/simplification/rules/unaryRules.js +37 -37
  152. package/omd/simplification/simplificationRules.js +31 -31
  153. package/omd/simplification/simplificationUtils.js +1055 -1055
  154. package/omd/step-visualizer/omdStepVisualizer.js +947 -947
  155. package/omd/step-visualizer/omdStepVisualizerHighlighting.js +246 -246
  156. package/omd/step-visualizer/omdStepVisualizerLayout.js +892 -892
  157. package/omd/step-visualizer/omdStepVisualizerTextBoxes.js +200 -200
  158. package/omd/utils/aiNextEquationStep.js +106 -106
  159. package/omd/utils/omdNodeOverlay.js +638 -638
  160. package/omd/utils/omdPopup.js +1203 -1203
  161. package/omd/utils/omdStepVisualizerInteractiveSteps.js +684 -684
  162. package/omd/utils/omdStepVisualizerNodeUtils.js +267 -267
  163. package/omd/utils/omdTranscriptionService.js +123 -123
  164. package/omd/utils/omdTreeDiff.js +733 -733
  165. package/package.json +59 -56
  166. package/readme.html +184 -120
  167. package/src/index.js +74 -74
  168. package/src/json-schemas.md +576 -576
  169. package/src/omd-json-samples.js +147 -147
  170. package/src/omdApp.js +391 -391
  171. package/src/omdAppCanvas.js +335 -335
  172. package/src/omdBalanceHanger.js +199 -199
  173. package/src/omdColor.js +13 -13
  174. package/src/omdCoordinatePlane.js +541 -541
  175. package/src/omdExpression.js +115 -115
  176. package/src/omdFactory.js +150 -150
  177. package/src/omdFunction.js +114 -114
  178. package/src/omdMetaExpression.js +290 -290
  179. package/src/omdNaturalExpression.js +563 -563
  180. package/src/omdNode.js +383 -383
  181. package/src/omdNumber.js +52 -52
  182. package/src/omdNumberLine.js +114 -112
  183. package/src/omdNumberTile.js +118 -118
  184. package/src/omdOperator.js +72 -72
  185. package/src/omdPowerExpression.js +91 -91
  186. package/src/omdProblem.js +259 -259
  187. package/src/omdRatioChart.js +251 -251
  188. package/src/omdRationalExpression.js +114 -114
  189. package/src/omdSampleData.js +215 -215
  190. package/src/omdShapes.js +512 -512
  191. package/src/omdSpinner.js +151 -151
  192. package/src/omdString.js +49 -49
  193. package/src/omdTable.js +498 -498
  194. package/src/omdTapeDiagram.js +244 -244
  195. package/src/omdTerm.js +91 -91
  196. package/src/omdTileEquation.js +349 -349
  197. package/src/omdUtils.js +84 -84
  198. package/src/omdVariable.js +51 -51
@@ -1,202 +1,202 @@
1
- # omdNode
2
-
3
- The abstract base class for all nodes in the mathematical expression tree. It provides the core functionality for tree structure (parent-child relationships), layout calculations, rendering, and provenance tracking. All specific mathematical elements (constants, variables, operators, functions, equations) extend this class.
4
-
5
- ## Class Definition
6
-
7
- ```javascript
8
- export class omdNode extends omdMetaExpression
9
- ```
10
-
11
- This class is not meant to be instantiated directly. Instead, you should use one of its concrete subclasses (e.g., `omdConstantNode`, `omdBinaryExpressionNode`).
12
-
13
- ### Key Concepts
14
-
15
- - **AST (Abstract Syntax Tree):** Each `omdNode` is typically created from a node in the math.js AST, providing a structured representation of the mathematical expression.
16
- - **Tree Structure:** Nodes are organized in a hierarchical tree with `parent` and `childList` properties, enabling traversal and manipulation of the expression.
17
- - **Layout:** The `computeDimensions()` and `updateLayout()` methods are fundamental for determining the size and position of a node and its children, ensuring correct visual rendering.
18
- - **Provenance:** The `provenance` array on each node tracks its history. When a node is cloned (e.g., during a simplification step), the new node's provenance array will contain the ID of the original node, creating a traceable link back to its predecessor. This is crucial for features like step-by-step explanations and highlighting.
19
-
20
- ## Public Properties
21
-
22
- - **`id`** (`number`): A unique identifier for each node instance, automatically assigned upon creation.
23
- - **`type`** (`string`): A string indicating the specific type of the OMD node (e.g., `"omdConstantNode"`, `"omdBinaryExpressionNode"`).
24
- - **`parent`** (`omdNode` | `null`): A reference to the parent node in the expression tree. `null` for the root node.
25
- - **`astNodeData`** (`object`): The original math.js AST node from which this `omdNode` was created. This preserves the raw parsed data.
26
- - **`provenance`** (`Array<number>`): An array of IDs from which this node was derived. This forms a historical chain, linking a node back through transformations or simplifications.
27
- - **`argumentNodeList`** (`object`): A map (or object) containing references to the node's structurally significant children (e.g., `left`, `right` for binary expressions, `args` for functions). This is used for recursive operations and provenance tracking.
28
- - **`isExplainHighlighted`** (`boolean`): A flag indicating if the node is currently highlighted for explanation purposes. This acts as a lock, preventing other highlights from overriding it.
29
- - **`x`** (`number`): The x-coordinate of the node's top-left corner relative to its parent.
30
- - **`y`** (`number`): The y-coordinate of the node's top-left corner relative to its parent.
31
- - **`width`** (`number`): The calculated width of the node's bounding box.
32
- - **`height`** (`number`): The calculated height of the node's bounding box.
33
- - **`fontSize`** (`number`): The base font size applied to this node and its children.
34
- - **`svgElement`** (`SVGElement`): The root SVG element that represents this node visually.
35
-
36
- ## Public Methods
37
-
38
- ### `initialize()`
39
-
40
- Initializes the node by recursively computing its dimensions and updating its layout. This method should be called after a node and its children have been fully constructed to ensure proper sizing and positioning.
41
-
42
- ### `clone()`
43
-
44
- Creates a deep, structural clone of the node. The new node will have a new `id`, and its `provenance` will link back to the original node's `id`, establishing a historical connection.
45
-
46
- - **Returns**: `omdNode` - A new instance of the same type as the original, with all children also cloned.
47
-
48
- ### `replaceWith(newNode, options)`
49
-
50
- Replaces this node with a `newNode` in the expression tree. This updates all parent and child references and triggers a re-layout and re-rendering of the affected parts of the SVG.
51
-
52
- - **`newNode`** (`omdNode`): The node to substitute in.
53
- - **`options`** (`object`, optional): Configuration for the replacement.
54
- - `updateLayout` (`boolean`): If `true` (default), the layout of the entire tree will be recalculated upwards from the point of replacement.
55
- - **Returns**: `boolean` - `true` if the replacement was successful.
56
-
57
- ### `simplify()`
58
-
59
- Asynchronously attempts to simplify the expression rooted at this node by invoking the central simplification engine (`simplifyStep`).
60
-
61
- - **Returns**: `Promise<object>` - A promise that resolves to an object like `{ success, foldedCount, newRoot, message }`. Throws an error if the `simplifyStep` function is not set.
62
-
63
- ### `toMathJSNode()`
64
-
65
- Converts the `omdNode` and its children back into a math.js-compatible AST object. This method must be implemented by all concrete subclasses.
66
-
67
- - **Returns**: `object` - The math.js AST node.
68
- - **Throws**: `Error` if not implemented by the subclass.
69
-
70
- ### `toString()`
71
-
72
- Converts the node into a human-readable string representation. It typically uses the `toMathJSNode()` method internally to leverage math.js's string conversion capabilities.
73
-
74
- - **Returns**: `string`.
75
-
76
- ### `render()`
77
-
78
- Generates or retrieves the SVG representation of the node. This method calls `renderSelf()` if the SVG element has not been created yet.
79
-
80
- - **Returns**: `SVGElement` - The root SVG element representing this node.
81
-
82
- ### `renderSelf()`
83
-
84
- Abstract method that must be implemented by subclasses. This method is responsible for creating the specific SVG elements and structure for the node's visual representation.
85
-
86
- - **Returns**: `SVGElement` - The SVG element created for this node.
87
- - **Throws**: `Error` if not implemented by the subclass.
88
-
89
- ### `setFontSize(size)`
90
-
91
- Sets the base font size for this node and recursively propagates the new font size to all its children.
92
-
93
- - **`size`** (`number`): The font size in pixels.
94
-
95
- ### `moveTo(x, y)`
96
-
97
- Moves the node to a new absolute position (`x`, `y`) relative to its parent. It also recursively moves all children by the same delta.
98
-
99
- - **`x`** (`number`): The new x-coordinate.
100
- - **`y`** (`number`): The new y-coordinate.
101
-
102
- ### `show()`
103
-
104
- Makes the node and its SVG representation visible.
105
-
106
- ### `hide()`
107
-
108
- Hides the node and its SVG representation.
109
-
110
- ### `getDepth()`
111
-
112
- Calculates the depth of the node in the expression tree (0 for the root node).
113
-
114
- - **Returns**: `number` - The depth of the node.
115
-
116
- ### `findParentOfType(type)`
117
-
118
- Traverses up the tree to find the nearest parent node of a specific type.
119
-
120
- - **`type`** (`string`): The `type` property of the node to search for (e.g., `"omdEquationNode"`).
121
- - **Returns**: `omdNode` | `null` - The found parent node or `null` if not found.
122
-
123
- ### `validateProvenance(nodeMap)`
124
-
125
- Validates the provenance integrity of this node and all its descendants. It checks for duplicate IDs, invalid references, and self-references in the `provenance` arrays.
126
-
127
- - **`nodeMap`** (`Map`, optional): An optional map of all known nodes in the system, used for cross-referencing provenance IDs.
128
- - **Returns**: `Array<object>` - An array of validation issues found, each describing the type of issue, the node involved, and relevant IDs.
129
-
130
- ### `setHighlight(highlightOn, color)`
131
-
132
- Applies or removes a highlight from the node's background. If `isExplainHighlighted` is `true`, this method will not override the existing explanation highlight.
133
-
134
- - **`highlightOn`** (`boolean`): `true` to highlight, `false` to remove.
135
- - **`color`** (`string`, optional): The color of the highlight. Defaults to `omdColor.highlightColor`.
136
-
137
- ### `lowlight()`
138
-
139
- Reduces the opacity of the node's background. Similar to `setHighlight`, it respects the `isExplainHighlighted` lock.
140
-
141
- ### `setFillColor(color)`
142
-
143
- Sets the fill color of the node's background rectangle. This method also respects the `isExplainHighlighted` lock.
144
-
145
- ## Abstract Methods (to be implemented by subclasses)
146
-
147
- - **`computeDimensions()`**: Calculates the `width` and `height` of the node based on its content and children. Provides a default empty implementation.
148
- - **`updateLayout()`**: Positions the node's children relative to itself. Provides a default empty implementation.
149
- - **`getAlignmentBaseline()`**: Returns the vertical y-coordinate within the node's bounding box that should be used for alignment with its siblings. By default, this is the vertical center (`this.height / 2`).
150
- - **`isConstant()`**: Determines if the node represents a constant numerical value. Returns `false` by default.
151
- - **`getValue()`**: Retrieves the numerical value of a constant node. Throws an error if the node is not constant.
152
- - **`getRationalValue()`**: Retrieves the rational value of a constant node as a numerator/denominator pair. Throws an error if the node is not a constant rational expression.
153
-
154
- ## Internal Methods
155
-
156
- - **`_syncProvenanceFrom(originalNode)`**: Recursively walks a cloned node tree and sets the provenance of each node to point back to the corresponding node in the original tree. This is a crucial part of maintaining the provenance chain during cloning operations.
157
- - **`replaceNodeInParent(newNode)`**: Helper method used by `replaceWith` to update specific references to this node within its parent's `argumentNodeList` and other properties.
158
- - **`updateSvg(newNode)`**: Helper method used by `replaceWith` to perform the actual DOM manipulation (replacing SVG elements).
159
- - **`updateLayoutUpwards()`**: Traverses up the tree from this node's parent to re-calculate dimensions and layouts for all ancestors, ensuring the entire affected tree is correctly rendered after a change.
160
- - **`_validateStepsProvenance(issues)`**: Helper for `validateProvenance` to check provenance within steps.
161
- - **`_findOrphanedNodes(issues)`**: Helper for `validateProvenance` to find nodes in the `nodeMap` that are no longer part of the active tree.
162
- - **`_collectAllProvenanceIds(newNodeMap)`**: Collects all provenance IDs from nodes in a given map.
163
- - **`_collectNodeProvenanceIds(node, referencedIds, processedNodes)`**: Recursively collects provenance IDs for a single node.
164
- - **`_preserveReferencedNodes(referencedIds, newNodeMap)`**: Ensures that historical nodes referenced in provenance chains are kept in the `nodeMap`.
165
- - **`_preserveNodeAndContext(id, newNodeMap, processedIds)`**: Preserves a historical node and its relevant parent/sibling context.
166
- - **`_preserveParentContext(node, newNodeMap)`**: Preserves the parent nodes of a historical node.
167
- - **`_preserveSiblingContext(node, newNodeMap)`**: Preserves the sibling nodes of a historical node.
168
-
169
- ## Example
170
-
171
- ```javascript
172
- // omdNode is an abstract class - use concrete subclasses
173
- import { omdConstantNode } from './omdConstantNode.js';
174
- import { omdBinaryExpressionNode } from './omdBinaryExpressionNode.js';
175
- import { omdDisplay } from '../display/omdDisplay.js';
176
-
177
- // Create a simple expression tree
178
- const two = new omdConstantNode({ value: 2 });
179
- const x = new omdVariableNode({ name: 'x' });
180
- const twoX = new omdBinaryExpressionNode({
181
- type: 'OperatorNode', op: '*', fn: 'multiply',
182
- args: [two.astNodeData, x.astNodeData],
183
- implicit: true
184
- });
185
-
186
- // Initialize the root node (this will recursively initialize children)
187
- twoX.initialize();
188
-
189
- // Render it using omdDisplay
190
- const container = document.getElementById('math-container');
191
- const display = new omdDisplay(container);
192
- display.render(twoX);
193
-
194
- console.log(twoX.toString()); // Output: 2x
195
- ```
196
-
197
- ## See Also
198
-
199
- - [`omdLeafNode`](./omdLeafNode.md) - The base class for nodes with no children (constants, variables, operators).
200
- - [`omdBinaryExpressionNode`](./omdBinaryExpressionNode.md) - For nodes with two children (e.g., addition, subtraction, multiplication).
201
- - [`omdFunctionNode`](./omdFunctionNode.md) - For function calls (e.g., `sin(x)`).
1
+ # omdNode
2
+
3
+ The abstract base class for all nodes in the mathematical expression tree. It provides the core functionality for tree structure (parent-child relationships), layout calculations, rendering, and provenance tracking. All specific mathematical elements (constants, variables, operators, functions, equations) extend this class.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class omdNode extends omdMetaExpression
9
+ ```
10
+
11
+ This class is not meant to be instantiated directly. Instead, you should use one of its concrete subclasses (e.g., `omdConstantNode`, `omdBinaryExpressionNode`).
12
+
13
+ ### Key Concepts
14
+
15
+ - **AST (Abstract Syntax Tree):** Each `omdNode` is typically created from a node in the math.js AST, providing a structured representation of the mathematical expression.
16
+ - **Tree Structure:** Nodes are organized in a hierarchical tree with `parent` and `childList` properties, enabling traversal and manipulation of the expression.
17
+ - **Layout:** The `computeDimensions()` and `updateLayout()` methods are fundamental for determining the size and position of a node and its children, ensuring correct visual rendering.
18
+ - **Provenance:** The `provenance` array on each node tracks its history. When a node is cloned (e.g., during a simplification step), the new node's provenance array will contain the ID of the original node, creating a traceable link back to its predecessor. This is crucial for features like step-by-step explanations and highlighting.
19
+
20
+ ## Public Properties
21
+
22
+ - **`id`** (`number`): A unique identifier for each node instance, automatically assigned upon creation.
23
+ - **`type`** (`string`): A string indicating the specific type of the OMD node (e.g., `"omdConstantNode"`, `"omdBinaryExpressionNode"`).
24
+ - **`parent`** (`omdNode` | `null`): A reference to the parent node in the expression tree. `null` for the root node.
25
+ - **`astNodeData`** (`object`): The original math.js AST node from which this `omdNode` was created. This preserves the raw parsed data.
26
+ - **`provenance`** (`Array<number>`): An array of IDs from which this node was derived. This forms a historical chain, linking a node back through transformations or simplifications.
27
+ - **`argumentNodeList`** (`object`): A map (or object) containing references to the node's structurally significant children (e.g., `left`, `right` for binary expressions, `args` for functions). This is used for recursive operations and provenance tracking.
28
+ - **`isExplainHighlighted`** (`boolean`): A flag indicating if the node is currently highlighted for explanation purposes. This acts as a lock, preventing other highlights from overriding it.
29
+ - **`x`** (`number`): The x-coordinate of the node's top-left corner relative to its parent.
30
+ - **`y`** (`number`): The y-coordinate of the node's top-left corner relative to its parent.
31
+ - **`width`** (`number`): The calculated width of the node's bounding box.
32
+ - **`height`** (`number`): The calculated height of the node's bounding box.
33
+ - **`fontSize`** (`number`): The base font size applied to this node and its children.
34
+ - **`svgElement`** (`SVGElement`): The root SVG element that represents this node visually.
35
+
36
+ ## Public Methods
37
+
38
+ ### `initialize()`
39
+
40
+ Initializes the node by recursively computing its dimensions and updating its layout. This method should be called after a node and its children have been fully constructed to ensure proper sizing and positioning.
41
+
42
+ ### `clone()`
43
+
44
+ Creates a deep, structural clone of the node. The new node will have a new `id`, and its `provenance` will link back to the original node's `id`, establishing a historical connection.
45
+
46
+ - **Returns**: `omdNode` - A new instance of the same type as the original, with all children also cloned.
47
+
48
+ ### `replaceWith(newNode, options)`
49
+
50
+ Replaces this node with a `newNode` in the expression tree. This updates all parent and child references and triggers a re-layout and re-rendering of the affected parts of the SVG.
51
+
52
+ - **`newNode`** (`omdNode`): The node to substitute in.
53
+ - **`options`** (`object`, optional): Configuration for the replacement.
54
+ - `updateLayout` (`boolean`): If `true` (default), the layout of the entire tree will be recalculated upwards from the point of replacement.
55
+ - **Returns**: `boolean` - `true` if the replacement was successful.
56
+
57
+ ### `simplify()`
58
+
59
+ Asynchronously attempts to simplify the expression rooted at this node by invoking the central simplification engine (`simplifyStep`).
60
+
61
+ - **Returns**: `Promise<object>` - A promise that resolves to an object like `{ success, foldedCount, newRoot, message }`. Throws an error if the `simplifyStep` function is not set.
62
+
63
+ ### `toMathJSNode()`
64
+
65
+ Converts the `omdNode` and its children back into a math.js-compatible AST object. This method must be implemented by all concrete subclasses.
66
+
67
+ - **Returns**: `object` - The math.js AST node.
68
+ - **Throws**: `Error` if not implemented by the subclass.
69
+
70
+ ### `toString()`
71
+
72
+ Converts the node into a human-readable string representation. It typically uses the `toMathJSNode()` method internally to leverage math.js's string conversion capabilities.
73
+
74
+ - **Returns**: `string`.
75
+
76
+ ### `render()`
77
+
78
+ Generates or retrieves the SVG representation of the node. This method calls `renderSelf()` if the SVG element has not been created yet.
79
+
80
+ - **Returns**: `SVGElement` - The root SVG element representing this node.
81
+
82
+ ### `renderSelf()`
83
+
84
+ Abstract method that must be implemented by subclasses. This method is responsible for creating the specific SVG elements and structure for the node's visual representation.
85
+
86
+ - **Returns**: `SVGElement` - The SVG element created for this node.
87
+ - **Throws**: `Error` if not implemented by the subclass.
88
+
89
+ ### `setFontSize(size)`
90
+
91
+ Sets the base font size for this node and recursively propagates the new font size to all its children.
92
+
93
+ - **`size`** (`number`): The font size in pixels.
94
+
95
+ ### `moveTo(x, y)`
96
+
97
+ Moves the node to a new absolute position (`x`, `y`) relative to its parent. It also recursively moves all children by the same delta.
98
+
99
+ - **`x`** (`number`): The new x-coordinate.
100
+ - **`y`** (`number`): The new y-coordinate.
101
+
102
+ ### `show()`
103
+
104
+ Makes the node and its SVG representation visible.
105
+
106
+ ### `hide()`
107
+
108
+ Hides the node and its SVG representation.
109
+
110
+ ### `getDepth()`
111
+
112
+ Calculates the depth of the node in the expression tree (0 for the root node).
113
+
114
+ - **Returns**: `number` - The depth of the node.
115
+
116
+ ### `findParentOfType(type)`
117
+
118
+ Traverses up the tree to find the nearest parent node of a specific type.
119
+
120
+ - **`type`** (`string`): The `type` property of the node to search for (e.g., `"omdEquationNode"`).
121
+ - **Returns**: `omdNode` | `null` - The found parent node or `null` if not found.
122
+
123
+ ### `validateProvenance(nodeMap)`
124
+
125
+ Validates the provenance integrity of this node and all its descendants. It checks for duplicate IDs, invalid references, and self-references in the `provenance` arrays.
126
+
127
+ - **`nodeMap`** (`Map`, optional): An optional map of all known nodes in the system, used for cross-referencing provenance IDs.
128
+ - **Returns**: `Array<object>` - An array of validation issues found, each describing the type of issue, the node involved, and relevant IDs.
129
+
130
+ ### `setHighlight(highlightOn, color)`
131
+
132
+ Applies or removes a highlight from the node's background. If `isExplainHighlighted` is `true`, this method will not override the existing explanation highlight.
133
+
134
+ - **`highlightOn`** (`boolean`): `true` to highlight, `false` to remove.
135
+ - **`color`** (`string`, optional): The color of the highlight. Defaults to `omdColor.highlightColor`.
136
+
137
+ ### `lowlight()`
138
+
139
+ Reduces the opacity of the node's background. Similar to `setHighlight`, it respects the `isExplainHighlighted` lock.
140
+
141
+ ### `setFillColor(color)`
142
+
143
+ Sets the fill color of the node's background rectangle. This method also respects the `isExplainHighlighted` lock.
144
+
145
+ ## Abstract Methods (to be implemented by subclasses)
146
+
147
+ - **`computeDimensions()`**: Calculates the `width` and `height` of the node based on its content and children. Provides a default empty implementation.
148
+ - **`updateLayout()`**: Positions the node's children relative to itself. Provides a default empty implementation.
149
+ - **`getAlignmentBaseline()`**: Returns the vertical y-coordinate within the node's bounding box that should be used for alignment with its siblings. By default, this is the vertical center (`this.height / 2`).
150
+ - **`isConstant()`**: Determines if the node represents a constant numerical value. Returns `false` by default.
151
+ - **`getValue()`**: Retrieves the numerical value of a constant node. Throws an error if the node is not constant.
152
+ - **`getRationalValue()`**: Retrieves the rational value of a constant node as a numerator/denominator pair. Throws an error if the node is not a constant rational expression.
153
+
154
+ ## Internal Methods
155
+
156
+ - **`_syncProvenanceFrom(originalNode)`**: Recursively walks a cloned node tree and sets the provenance of each node to point back to the corresponding node in the original tree. This is a crucial part of maintaining the provenance chain during cloning operations.
157
+ - **`replaceNodeInParent(newNode)`**: Helper method used by `replaceWith` to update specific references to this node within its parent's `argumentNodeList` and other properties.
158
+ - **`updateSvg(newNode)`**: Helper method used by `replaceWith` to perform the actual DOM manipulation (replacing SVG elements).
159
+ - **`updateLayoutUpwards()`**: Traverses up the tree from this node's parent to re-calculate dimensions and layouts for all ancestors, ensuring the entire affected tree is correctly rendered after a change.
160
+ - **`_validateStepsProvenance(issues)`**: Helper for `validateProvenance` to check provenance within steps.
161
+ - **`_findOrphanedNodes(issues)`**: Helper for `validateProvenance` to find nodes in the `nodeMap` that are no longer part of the active tree.
162
+ - **`_collectAllProvenanceIds(newNodeMap)`**: Collects all provenance IDs from nodes in a given map.
163
+ - **`_collectNodeProvenanceIds(node, referencedIds, processedNodes)`**: Recursively collects provenance IDs for a single node.
164
+ - **`_preserveReferencedNodes(referencedIds, newNodeMap)`**: Ensures that historical nodes referenced in provenance chains are kept in the `nodeMap`.
165
+ - **`_preserveNodeAndContext(id, newNodeMap, processedIds)`**: Preserves a historical node and its relevant parent/sibling context.
166
+ - **`_preserveParentContext(node, newNodeMap)`**: Preserves the parent nodes of a historical node.
167
+ - **`_preserveSiblingContext(node, newNodeMap)`**: Preserves the sibling nodes of a historical node.
168
+
169
+ ## Example
170
+
171
+ ```javascript
172
+ // omdNode is an abstract class - use concrete subclasses
173
+ import { omdConstantNode } from './omdConstantNode.js';
174
+ import { omdBinaryExpressionNode } from './omdBinaryExpressionNode.js';
175
+ import { omdDisplay } from '../display/omdDisplay.js';
176
+
177
+ // Create a simple expression tree
178
+ const two = new omdConstantNode({ value: 2 });
179
+ const x = new omdVariableNode({ name: 'x' });
180
+ const twoX = new omdBinaryExpressionNode({
181
+ type: 'OperatorNode', op: '*', fn: 'multiply',
182
+ args: [two.astNodeData, x.astNodeData],
183
+ implicit: true
184
+ });
185
+
186
+ // Initialize the root node (this will recursively initialize children)
187
+ twoX.initialize();
188
+
189
+ // Render it using omdDisplay
190
+ const container = document.getElementById('math-container');
191
+ const display = new omdDisplay(container);
192
+ display.render(twoX);
193
+
194
+ console.log(twoX.toString()); // Output: 2x
195
+ ```
196
+
197
+ ## See Also
198
+
199
+ - [`omdLeafNode`](./omdLeafNode.md) - The base class for nodes with no children (constants, variables, operators).
200
+ - [`omdBinaryExpressionNode`](./omdBinaryExpressionNode.md) - For nodes with two children (e.g., addition, subtraction, multiplication).
201
+ - [`omdFunctionNode`](./omdFunctionNode.md) - For function calls (e.g., `sin(x)`).
202
202
  - [`omdEquationNode`](./omdEquationNode.md) - For representing mathematical equations.