@lydt/geogebra-studio 0.0.0-stage → 0.4.0-rc.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 (189) hide show
  1. package/.agents/plugins/marketplace.json +21 -0
  2. package/.codex-plugin/plugin.json +21 -0
  3. package/.mcp.json +18 -0
  4. package/LICENSE +339 -0
  5. package/LICENSE-MIT +21 -0
  6. package/README.md +108 -2
  7. package/README.zh-CN.md +89 -0
  8. package/THIRD_PARTY_NOTICES.md +35 -0
  9. package/dist/cli.d.ts +27 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +234 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/export/files.d.ts +4 -0
  14. package/dist/export/files.d.ts.map +1 -0
  15. package/dist/export/files.js +44 -0
  16. package/dist/export/files.js.map +1 -0
  17. package/dist/export/gikz.d.ts +11 -0
  18. package/dist/export/gikz.d.ts.map +1 -0
  19. package/dist/export/gikz.js +28 -0
  20. package/dist/export/gikz.js.map +1 -0
  21. package/dist/export/html.d.ts +14 -0
  22. package/dist/export/html.d.ts.map +1 -0
  23. package/dist/export/html.js +97 -0
  24. package/dist/export/html.js.map +1 -0
  25. package/dist/export/semantic.d.ts +43 -0
  26. package/dist/export/semantic.d.ts.map +1 -0
  27. package/dist/export/semantic.js +212 -0
  28. package/dist/export/semantic.js.map +1 -0
  29. package/dist/export/viewer-themes.d.ts +76 -0
  30. package/dist/export/viewer-themes.d.ts.map +1 -0
  31. package/dist/export/viewer-themes.js +169 -0
  32. package/dist/export/viewer-themes.js.map +1 -0
  33. package/dist/export/workspace.d.ts +4 -0
  34. package/dist/export/workspace.d.ts.map +1 -0
  35. package/dist/export/workspace.js +25 -0
  36. package/dist/export/workspace.js.map +1 -0
  37. package/dist/gikz-browser.js +770 -0
  38. package/dist/index.d.ts +5 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +84 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/server.d.ts +35 -0
  43. package/dist/server.d.ts.map +1 -0
  44. package/dist/server.js +187 -0
  45. package/dist/server.js.map +1 -0
  46. package/dist/studio/artifact.d.ts +37 -0
  47. package/dist/studio/artifact.d.ts.map +1 -0
  48. package/dist/studio/artifact.js +61 -0
  49. package/dist/studio/artifact.js.map +1 -0
  50. package/dist/studio/browser.d.ts +7 -0
  51. package/dist/studio/browser.d.ts.map +1 -0
  52. package/dist/studio/browser.js +67 -0
  53. package/dist/studio/browser.js.map +1 -0
  54. package/dist/studio/install.d.ts +4 -0
  55. package/dist/studio/install.d.ts.map +1 -0
  56. package/dist/studio/install.js +60 -0
  57. package/dist/studio/install.js.map +1 -0
  58. package/dist/tools/apps-api-tools.d.ts +4 -0
  59. package/dist/tools/apps-api-tools.d.ts.map +1 -0
  60. package/dist/tools/apps-api-tools.js +96 -0
  61. package/dist/tools/apps-api-tools.js.map +1 -0
  62. package/dist/tools/educational-templates.d.ts +33 -0
  63. package/dist/tools/educational-templates.d.ts.map +1 -0
  64. package/dist/tools/educational-templates.js +261 -0
  65. package/dist/tools/educational-templates.js.map +1 -0
  66. package/dist/tools/export-tools.d.ts +3 -0
  67. package/dist/tools/export-tools.d.ts.map +1 -0
  68. package/dist/tools/export-tools.js +118 -0
  69. package/dist/tools/export-tools.js.map +1 -0
  70. package/dist/tools/geogebra-tools.d.ts +15 -0
  71. package/dist/tools/geogebra-tools.d.ts.map +1 -0
  72. package/dist/tools/geogebra-tools.js +3442 -0
  73. package/dist/tools/geogebra-tools.js.map +1 -0
  74. package/dist/tools/index.d.ts +43 -0
  75. package/dist/tools/index.d.ts.map +1 -0
  76. package/dist/tools/index.js +183 -0
  77. package/dist/tools/index.js.map +1 -0
  78. package/dist/tools/performance-tools.d.ts +7 -0
  79. package/dist/tools/performance-tools.d.ts.map +1 -0
  80. package/dist/tools/performance-tools.js +312 -0
  81. package/dist/tools/performance-tools.js.map +1 -0
  82. package/dist/tools/templates/algebra-templates.d.ts +7 -0
  83. package/dist/tools/templates/algebra-templates.d.ts.map +1 -0
  84. package/dist/tools/templates/algebra-templates.js +568 -0
  85. package/dist/tools/templates/algebra-templates.js.map +1 -0
  86. package/dist/tools/templates/geometry-templates.d.ts +7 -0
  87. package/dist/tools/templates/geometry-templates.d.ts.map +1 -0
  88. package/dist/tools/templates/geometry-templates.js +492 -0
  89. package/dist/tools/templates/geometry-templates.js.map +1 -0
  90. package/dist/types/geogebra.d.ts +103 -0
  91. package/dist/types/geogebra.d.ts.map +1 -0
  92. package/dist/types/geogebra.js +34 -0
  93. package/dist/types/geogebra.js.map +1 -0
  94. package/dist/types/mcp.d.ts +125 -0
  95. package/dist/types/mcp.d.ts.map +1 -0
  96. package/dist/types/mcp.js +19 -0
  97. package/dist/types/mcp.js.map +1 -0
  98. package/dist/utils/app-info.d.ts +12 -0
  99. package/dist/utils/app-info.d.ts.map +1 -0
  100. package/dist/utils/app-info.js +30 -0
  101. package/dist/utils/app-info.js.map +1 -0
  102. package/dist/utils/errors.d.ts +37 -0
  103. package/dist/utils/errors.d.ts.map +1 -0
  104. package/dist/utils/errors.js +72 -0
  105. package/dist/utils/errors.js.map +1 -0
  106. package/dist/utils/gemini-compatibility.d.ts +39 -0
  107. package/dist/utils/gemini-compatibility.d.ts.map +1 -0
  108. package/dist/utils/gemini-compatibility.js +154 -0
  109. package/dist/utils/gemini-compatibility.js.map +1 -0
  110. package/dist/utils/geogebra-instance.d.ts +252 -0
  111. package/dist/utils/geogebra-instance.d.ts.map +1 -0
  112. package/dist/utils/geogebra-instance.js +1560 -0
  113. package/dist/utils/geogebra-instance.js.map +1 -0
  114. package/dist/utils/geogebra-mock.d.ts +172 -0
  115. package/dist/utils/geogebra-mock.d.ts.map +1 -0
  116. package/dist/utils/geogebra-mock.js +732 -0
  117. package/dist/utils/geogebra-mock.js.map +1 -0
  118. package/dist/utils/logger.d.ts +4 -0
  119. package/dist/utils/logger.d.ts.map +1 -0
  120. package/dist/utils/logger.js +46 -0
  121. package/dist/utils/logger.js.map +1 -0
  122. package/dist/utils/performance/index.d.ts +76 -0
  123. package/dist/utils/performance/index.d.ts.map +1 -0
  124. package/dist/utils/performance/index.js +163 -0
  125. package/dist/utils/performance/index.js.map +1 -0
  126. package/dist/utils/performance/instance-pool.d.ts +78 -0
  127. package/dist/utils/performance/instance-pool.d.ts.map +1 -0
  128. package/dist/utils/performance/instance-pool.js +268 -0
  129. package/dist/utils/performance/instance-pool.js.map +1 -0
  130. package/dist/utils/validation.d.ts +92 -0
  131. package/dist/utils/validation.d.ts.map +1 -0
  132. package/dist/utils/validation.js +557 -0
  133. package/dist/utils/validation.js.map +1 -0
  134. package/dist/widget.html +110 -0
  135. package/docs/APPS-API-BRIDGE.md +28 -0
  136. package/docs/MODERNIZATION.md +15 -0
  137. package/docs/TANGENT-REGRESSION.md +34 -0
  138. package/docs/VALIDATION.md +26 -0
  139. package/docs/VISUAL-STANDARD.md +26 -0
  140. package/docs/images/native-construction.png +0 -0
  141. package/examples/tangent-construction.json +26 -0
  142. package/gikz/LICENSE +339 -0
  143. package/gikz/PROVENANCE.md +8 -0
  144. package/gikz/browser.cjs +2 -0
  145. package/gikz/cli.cjs +195 -0
  146. package/gikz/core.cjs +806 -0
  147. package/mcp.json +20 -0
  148. package/package.json +107 -4
  149. package/plugin.json +35 -0
  150. package/runtime/package.json +4 -0
  151. package/scripts/build-plugin.cjs +15 -0
  152. package/scripts/build-widget.cjs +7 -0
  153. package/skills/geogebra-construct/SKILL.md +40 -0
  154. package/skills/geogebra-setup/SKILL.md +37 -0
  155. package/skills/geometry-export/SKILL.md +31 -0
  156. package/src/cli.ts +212 -0
  157. package/src/export/files.ts +26 -0
  158. package/src/export/gikz.ts +22 -0
  159. package/src/export/html.ts +108 -0
  160. package/src/export/semantic.ts +180 -0
  161. package/src/export/viewer-themes.ts +165 -0
  162. package/src/export/workspace.ts +15 -0
  163. package/src/index.ts +71 -0
  164. package/src/server.ts +168 -0
  165. package/src/studio/artifact.ts +50 -0
  166. package/src/studio/browser.ts +38 -0
  167. package/src/studio/install.ts +43 -0
  168. package/src/tools/apps-api-tools.ts +96 -0
  169. package/src/tools/educational-templates.ts +299 -0
  170. package/src/tools/export-tools.ts +110 -0
  171. package/src/tools/geogebra-tools.ts +3836 -0
  172. package/src/tools/index.ts +192 -0
  173. package/src/tools/performance-tools.ts +322 -0
  174. package/src/tools/templates/algebra-templates.ts +619 -0
  175. package/src/tools/templates/geometry-templates.ts +550 -0
  176. package/src/types/geogebra.ts +140 -0
  177. package/src/types/global.d.ts +31 -0
  178. package/src/types/mcp.ts +141 -0
  179. package/src/utils/app-info.ts +35 -0
  180. package/src/utils/errors.ts +97 -0
  181. package/src/utils/gemini-compatibility.ts +193 -0
  182. package/src/utils/geogebra-instance.ts +1712 -0
  183. package/src/utils/geogebra-mock.ts +867 -0
  184. package/src/utils/logger.ts +60 -0
  185. package/src/utils/performance/index.ts +211 -0
  186. package/src/utils/performance/instance-pool.ts +323 -0
  187. package/src/utils/validation.ts +647 -0
  188. package/tsconfig.json +35 -0
  189. package/widget/main.ts +12 -0
@@ -0,0 +1,732 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MockGeoGebraInstance = void 0;
7
+ const geogebra_1 = require("../types/geogebra");
8
+ const logger_1 = __importDefault(require("./logger"));
9
+ const crypto_1 = require("crypto");
10
+ /**
11
+ * Mock GeoGebra Instance for demonstration and testing
12
+ * This provides the same interface as the full implementation
13
+ * but uses in-memory simulation instead of a real browser instance
14
+ */
15
+ class MockGeoGebraInstance {
16
+ isInitialized = false;
17
+ lastActivity = new Date();
18
+ objects = new Map();
19
+ animatingObjects = new Set();
20
+ animationSpeeds = new Map();
21
+ tracedObjects = new Set();
22
+ isAnimating = false;
23
+ id;
24
+ config;
25
+ constructor(config = {}) {
26
+ this.id = (0, crypto_1.randomUUID)();
27
+ this.config = {
28
+ appName: 'graphing',
29
+ width: 800,
30
+ height: 600,
31
+ showMenuBar: false,
32
+ showToolBar: false,
33
+ showAlgebraInput: false,
34
+ showResetIcon: false,
35
+ enableRightClick: true,
36
+ language: 'en',
37
+ ...config
38
+ };
39
+ logger_1.default.info(`Created Mock GeoGebra instance ${this.id}`, { config: this.config });
40
+ }
41
+ /**
42
+ * Initialize the mock instance
43
+ */
44
+ async initialize() {
45
+ try {
46
+ logger_1.default.info(`Initializing Mock GeoGebra instance ${this.id}`);
47
+ // Simulate initialization delay
48
+ await new Promise(resolve => setTimeout(resolve, 100));
49
+ this.isInitialized = true;
50
+ this.updateActivity();
51
+ logger_1.default.info(`Mock GeoGebra instance ${this.id} initialized successfully`);
52
+ }
53
+ catch (error) {
54
+ logger_1.default.error(`Failed to initialize Mock GeoGebra instance ${this.id}`, error);
55
+ throw new geogebra_1.GeoGebraConnectionError(`Failed to initialize GeoGebra: ${error instanceof Error ? error.message : String(error)}`);
56
+ }
57
+ }
58
+ /**
59
+ * Execute a GeoGebra command (mock implementation)
60
+ */
61
+ async evalCommand(command) {
62
+ this.ensureInitialized();
63
+ this.updateActivity();
64
+ try {
65
+ logger_1.default.debug(`Executing mock command on instance ${this.id}: ${command}`);
66
+ // Parse basic commands
67
+ const result = this.parseCommand(command);
68
+ logger_1.default.debug(`Mock command executed successfully on instance ${this.id}: ${command}`);
69
+ return {
70
+ success: true,
71
+ result: result
72
+ };
73
+ }
74
+ catch (error) {
75
+ logger_1.default.error(`Mock command execution failed on instance ${this.id}`, { command, error });
76
+ return {
77
+ success: false,
78
+ error: error instanceof Error ? error.message : String(error)
79
+ };
80
+ }
81
+ }
82
+ /**
83
+ * Parse and execute basic GeoGebra commands
84
+ */
85
+ parseCommand(command) {
86
+ const trimmed = command.trim();
87
+ // Point creation: A = (x, y)
88
+ const pointMatch = trimmed.match(/^([A-Za-z]\w*)\s*=\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)$/);
89
+ if (pointMatch && pointMatch[1] && pointMatch[2] && pointMatch[3]) {
90
+ const [, name, x, y] = pointMatch;
91
+ this.objects.set(name, {
92
+ name,
93
+ type: 'point',
94
+ visible: true,
95
+ defined: true,
96
+ x: parseFloat(x),
97
+ y: parseFloat(y),
98
+ z: 0,
99
+ color: '#0000FF'
100
+ });
101
+ return `Point ${name} created at (${x}, ${y})`;
102
+ }
103
+ // Slider creation: name = Slider(min, max, increment, speed, width, isAngle, horizontal, animating, random)
104
+ const sliderMatch = trimmed.match(/^([A-Za-z]\w*)\s*=\s*Slider\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*(?:\s*,\s*(\d+(?:\.\d+)?))?\s*.*?\)$/);
105
+ if (sliderMatch && sliderMatch[1] && sliderMatch[2] && sliderMatch[3]) {
106
+ const [, name, min, max, _increment] = sliderMatch;
107
+ const defaultValue = parseFloat(min);
108
+ this.objects.set(name, {
109
+ name,
110
+ type: 'slider',
111
+ visible: true,
112
+ defined: true,
113
+ value: defaultValue,
114
+ color: '#0073E6'
115
+ });
116
+ return `Slider ${name} created with range [${min}, ${max}], current value: ${defaultValue}`;
117
+ }
118
+ // Line creation: l = Line(A, B)
119
+ const lineMatch = trimmed.match(/^([A-Za-z]\w*)\s*=\s*Line\s*\(\s*([A-Za-z]\w*)\s*,\s*([A-Za-z]\w*)\s*\)$/);
120
+ if (lineMatch && lineMatch[1] && lineMatch[2] && lineMatch[3]) {
121
+ const [, name, point1, point2] = lineMatch;
122
+ if (!this.objects.has(point1) || !this.objects.has(point2)) {
123
+ throw new Error(`Points ${point1} or ${point2} do not exist`);
124
+ }
125
+ this.objects.set(name, {
126
+ name,
127
+ type: 'line',
128
+ visible: true,
129
+ defined: true,
130
+ color: '#000000'
131
+ });
132
+ return `Line ${name} created through points ${point1} and ${point2}`;
133
+ }
134
+ // Function creation: f(x) = expression
135
+ const functionMatch = trimmed.match(/^([A-Za-z]\w*)\s*\(\s*x\s*\)\s*=\s*(.+)$/);
136
+ if (functionMatch && functionMatch[1] && functionMatch[2]) {
137
+ const [, name, expression] = functionMatch;
138
+ this.objects.set(name, {
139
+ name,
140
+ type: 'function',
141
+ visible: true,
142
+ defined: true,
143
+ value: expression,
144
+ color: '#FF0000'
145
+ });
146
+ return `Function ${name}(x) = ${expression} created`;
147
+ }
148
+ // Parametric curve creation: name = Curve(x_expr, y_expr, param, start, end)
149
+ const parametricMatch = trimmed.match(/^([A-Za-z]\w*)\s*=\s*Curve\s*\(\s*(.+?)\s*,\s*(.+?)\s*,\s*([A-Za-z]\w*)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)$/);
150
+ if (parametricMatch && parametricMatch[1] && parametricMatch[2] && parametricMatch[3] && parametricMatch[4] && parametricMatch[5] && parametricMatch[6]) {
151
+ const [, name, xExpr, yExpr, param, tMin, tMax] = parametricMatch;
152
+ this.objects.set(name, {
153
+ name,
154
+ type: 'curve',
155
+ visible: true,
156
+ defined: true,
157
+ value: `Parametric: x(${param}) = ${xExpr}, y(${param}) = ${yExpr}, ${param} ∈ [${tMin}, ${tMax}]`,
158
+ color: '#00AA00'
159
+ });
160
+ return `Parametric curve ${name} created: x(${param}) = ${xExpr}, y(${param}) = ${yExpr}, ${param} ∈ [${tMin}, ${tMax}]`;
161
+ }
162
+ // Implicit curve creation: name = ImplicitCurve(expression)
163
+ const implicitMatch = trimmed.match(/^([A-Za-z]\w*)\s*=\s*ImplicitCurve\s*\(\s*(.+)\s*\)$/);
164
+ if (implicitMatch && implicitMatch[1] && implicitMatch[2]) {
165
+ const [, name, expression] = implicitMatch;
166
+ this.objects.set(name, {
167
+ name,
168
+ type: 'implicitcurve',
169
+ visible: true,
170
+ defined: true,
171
+ value: `Implicit: ${expression} = 0`,
172
+ color: '#AA0000'
173
+ });
174
+ return `Implicit curve ${name} created: ${expression} = 0`;
175
+ }
176
+ // Styling commands: SetColor, SetLineThickness, SetLineStyle
177
+ const setColorMatch = trimmed.match(/^SetColor\s*\(\s*([A-Za-z]\w*)\s*,\s*"([^"]+)"\s*\)$/);
178
+ if (setColorMatch && setColorMatch[1] && setColorMatch[2]) {
179
+ const [, name, color] = setColorMatch;
180
+ const obj = this.objects.get(name);
181
+ if (obj) {
182
+ obj.color = color;
183
+ return `Color of ${name} set to ${color}`;
184
+ }
185
+ return `Object ${name} not found for color setting`;
186
+ }
187
+ const setThicknessMatch = trimmed.match(/^SetLineThickness\s*\(\s*([A-Za-z]\w*)\s*,\s*(\d+)\s*\)$/);
188
+ if (setThicknessMatch && setThicknessMatch[1] && setThicknessMatch[2]) {
189
+ const [, name, thickness] = setThicknessMatch;
190
+ const obj = this.objects.get(name);
191
+ if (obj) {
192
+ // Store thickness in a custom property (mock doesn't have thickness in type)
193
+ obj.thickness = parseInt(thickness);
194
+ return `Line thickness of ${name} set to ${thickness}`;
195
+ }
196
+ return `Object ${name} not found for thickness setting`;
197
+ }
198
+ const setStyleMatch = trimmed.match(/^SetLineStyle\s*\(\s*([A-Za-z]\w*)\s*,\s*(\d+)\s*\)$/);
199
+ if (setStyleMatch && setStyleMatch[1] && setStyleMatch[2]) {
200
+ const [, name, lineType] = setStyleMatch;
201
+ const obj = this.objects.get(name);
202
+ if (obj) {
203
+ const style = lineType === '10' ? 'dashed' : lineType === '20' ? 'dotted' : 'solid';
204
+ obj.style = style;
205
+ return `Line style of ${name} set to ${style}`;
206
+ }
207
+ return `Object ${name} not found for style setting`;
208
+ }
209
+ // Circle creation: Circle((x, y), r)
210
+ const circleMatch = trimmed.match(/^Circle\s*\(\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)\s*,\s*(\d+(?:\.\d+)?)\s*\)$/);
211
+ if (circleMatch && circleMatch[1] && circleMatch[2] && circleMatch[3]) {
212
+ const [, x, y, r] = circleMatch;
213
+ const name = `circle_${Date.now()}`;
214
+ this.objects.set(name, {
215
+ name,
216
+ type: 'circle',
217
+ visible: true,
218
+ defined: true,
219
+ x: parseFloat(x),
220
+ y: parseFloat(y),
221
+ value: parseFloat(r),
222
+ color: '#00FF00'
223
+ });
224
+ return `Circle created at (${x}, ${y}) with radius ${r}`;
225
+ }
226
+ // CAS Operations
227
+ // Solve equation: Solve(equation)
228
+ const solveMatch = trimmed.match(/^Solve\s*\(\s*(.+)\s*\)$/);
229
+ if (solveMatch && solveMatch[1]) {
230
+ const [, equation] = solveMatch;
231
+ return this.mockSolveEquation(equation);
232
+ }
233
+ // Solve equation for variable: Solve(equation, variable)
234
+ const solveVarMatch = trimmed.match(/^Solve\s*\(\s*(.+?)\s*,\s*([a-zA-Z]\w*)\s*\)$/);
235
+ if (solveVarMatch && solveVarMatch[1] && solveVarMatch[2]) {
236
+ const [, equation, variable] = solveVarMatch;
237
+ return this.mockSolveEquation(equation, variable);
238
+ }
239
+ // Differentiate with respect to variable: Derivative(expression, variable)
240
+ const derivativeVarMatch = trimmed.match(/^Derivative\s*\(\s*(.+?)\s*,\s*([a-zA-Z]\w*)\s*\)$/);
241
+ if (derivativeVarMatch && derivativeVarMatch[1] && derivativeVarMatch[2]) {
242
+ const [, expression, variable] = derivativeVarMatch;
243
+ return this.mockDifferentiate(expression, variable);
244
+ }
245
+ // Differentiate: Derivative(expression)
246
+ const derivativeMatch = trimmed.match(/^Derivative\s*\(\s*(.+)\s*\)$/);
247
+ if (derivativeMatch && derivativeMatch[1]) {
248
+ const [, expression] = derivativeMatch;
249
+ return this.mockDifferentiate(expression);
250
+ }
251
+ // Integrate with respect to variable: Integral(expression, variable)
252
+ const integralVarMatch = trimmed.match(/^Integral\s*\(\s*(.+?)\s*,\s*([a-zA-Z]\w*)\s*\)$/);
253
+ if (integralVarMatch && integralVarMatch[1] && integralVarMatch[2]) {
254
+ const [, expression, variable] = integralVarMatch;
255
+ return this.mockIntegrate(expression, variable);
256
+ }
257
+ // Integrate: Integral(expression)
258
+ const integralMatch = trimmed.match(/^Integral\s*\(\s*(.+)\s*\)$/);
259
+ if (integralMatch && integralMatch[1]) {
260
+ const [, expression] = integralMatch;
261
+ return this.mockIntegrate(expression);
262
+ }
263
+ // Simplify: Simplify(expression)
264
+ const simplifyMatch = trimmed.match(/^Simplify\s*\(\s*(.+)\s*\)$/);
265
+ if (simplifyMatch && simplifyMatch[1]) {
266
+ const [, expression] = simplifyMatch;
267
+ return this.mockSimplify(expression);
268
+ }
269
+ // Generic command (just acknowledge)
270
+ return `Command executed: ${command}`;
271
+ }
272
+ /**
273
+ * Execute command and get labels of created objects
274
+ */
275
+ async evalCommandGetLabels(command) {
276
+ this.ensureInitialized();
277
+ this.updateActivity();
278
+ try {
279
+ const beforeObjects = new Set(this.objects.keys());
280
+ await this.evalCommand(command);
281
+ const afterObjects = new Set(this.objects.keys());
282
+ const newLabels = Array.from(afterObjects).filter(label => !beforeObjects.has(label));
283
+ logger_1.default.debug(`Mock command executed on instance ${this.id}, labels: ${newLabels.join(', ')}`);
284
+ return newLabels;
285
+ }
286
+ catch (error) {
287
+ logger_1.default.error(`Failed to execute mock command with labels on instance ${this.id}`, { command, error });
288
+ throw new geogebra_1.GeoGebraCommandError(`Failed to execute command: ${error instanceof Error ? error.message : String(error)}`, command);
289
+ }
290
+ }
291
+ /**
292
+ * Delete an object
293
+ */
294
+ async deleteObject(objName) {
295
+ this.ensureInitialized();
296
+ this.updateActivity();
297
+ try {
298
+ const deleted = this.objects.delete(objName);
299
+ if (deleted) {
300
+ logger_1.default.debug(`Deleted object ${objName} from mock instance ${this.id}`);
301
+ }
302
+ return deleted;
303
+ }
304
+ catch (error) {
305
+ logger_1.default.error(`Failed to delete object ${objName} on mock instance ${this.id}`, error);
306
+ return false;
307
+ }
308
+ }
309
+ /**
310
+ * Check if object exists
311
+ */
312
+ async exists(objName) {
313
+ this.ensureInitialized();
314
+ this.updateActivity();
315
+ return this.objects.has(objName);
316
+ }
317
+ /**
318
+ * Check if object is defined
319
+ */
320
+ async isDefined(objName) {
321
+ this.ensureInitialized();
322
+ this.updateActivity();
323
+ const obj = this.objects.get(objName);
324
+ return obj ? obj.defined : false;
325
+ }
326
+ /**
327
+ * Get all object names
328
+ */
329
+ async getAllObjectNames(type) {
330
+ this.ensureInitialized();
331
+ this.updateActivity();
332
+ if (type) {
333
+ return Array.from(this.objects.values())
334
+ .filter(obj => obj.type === type)
335
+ .map(obj => obj.name);
336
+ }
337
+ return Array.from(this.objects.keys());
338
+ }
339
+ /**
340
+ * Get object information
341
+ */
342
+ async getObjectInfo(objName) {
343
+ this.ensureInitialized();
344
+ this.updateActivity();
345
+ return this.objects.get(objName) || null;
346
+ }
347
+ /**
348
+ * Get X coordinate of object
349
+ */
350
+ async getXcoord(objName) {
351
+ this.ensureInitialized();
352
+ this.updateActivity();
353
+ const obj = this.objects.get(objName);
354
+ return obj?.x || 0;
355
+ }
356
+ /**
357
+ * Get Y coordinate of object
358
+ */
359
+ async getYcoord(objName) {
360
+ this.ensureInitialized();
361
+ this.updateActivity();
362
+ const obj = this.objects.get(objName);
363
+ return obj?.y || 0;
364
+ }
365
+ /**
366
+ * Get Z coordinate of object
367
+ */
368
+ async getZcoord(objName) {
369
+ this.ensureInitialized();
370
+ this.updateActivity();
371
+ const obj = this.objects.get(objName);
372
+ return obj?.z || 0;
373
+ }
374
+ /**
375
+ * Get value of object
376
+ */
377
+ async getValue(objName) {
378
+ this.ensureInitialized();
379
+ this.updateActivity();
380
+ const obj = this.objects.get(objName);
381
+ return typeof obj?.value === 'number' ? obj.value : 0;
382
+ }
383
+ /**
384
+ * Get value as string
385
+ */
386
+ async getValueString(objName) {
387
+ this.ensureInitialized();
388
+ this.updateActivity();
389
+ const obj = this.objects.get(objName);
390
+ return obj?.value?.toString() || '';
391
+ }
392
+ /**
393
+ * Create new construction
394
+ */
395
+ async newConstruction() {
396
+ this.ensureInitialized();
397
+ this.updateActivity();
398
+ this.objects.clear();
399
+ logger_1.default.debug(`New construction created on mock instance ${this.id}`);
400
+ }
401
+ /**
402
+ * Reset to initial state
403
+ */
404
+ async reset() {
405
+ this.ensureInitialized();
406
+ this.updateActivity();
407
+ this.objects.clear();
408
+ logger_1.default.debug(`Mock instance ${this.id} reset to initial state`);
409
+ }
410
+ /**
411
+ * Refresh all views
412
+ */
413
+ async refreshViews() {
414
+ this.ensureInitialized();
415
+ this.updateActivity();
416
+ logger_1.default.debug(`Views refreshed on mock instance ${this.id}`);
417
+ }
418
+ /**
419
+ * Set coordinate system bounds (mock implementation)
420
+ */
421
+ async setCoordSystem(xmin, xmax, ymin, ymax) {
422
+ this.ensureInitialized();
423
+ this.updateActivity();
424
+ logger_1.default.debug(`Mock coordinate system set on instance ${this.id}: x[${xmin}, ${xmax}], y[${ymin}, ${ymax}]`);
425
+ }
426
+ /**
427
+ * Set axes visibility (mock implementation)
428
+ */
429
+ async setAxesVisible(xAxis, yAxis) {
430
+ this.ensureInitialized();
431
+ this.updateActivity();
432
+ logger_1.default.debug(`Mock axes visibility set on instance ${this.id}: x=${xAxis}, y=${yAxis}`);
433
+ }
434
+ /**
435
+ * Set grid visibility (mock implementation)
436
+ */
437
+ async setGridVisible(visible) {
438
+ this.ensureInitialized();
439
+ this.updateActivity();
440
+ logger_1.default.debug(`Mock instance ${this.id}: Set grid visible: ${visible}`);
441
+ }
442
+ /**
443
+ * Check if instance is ready
444
+ */
445
+ async isReady() {
446
+ return this.isInitialized;
447
+ }
448
+ /**
449
+ * Export construction as PNG (base64) - Mock implementation with enhanced parameters
450
+ */
451
+ async exportPNG(scale = 1, transparent = false, dpi = 72, width, height) {
452
+ this.ensureInitialized();
453
+ this.updateActivity();
454
+ // Return a simple base64 encoded placeholder PNG
455
+ const placeholderPNG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
456
+ logger_1.default.debug(`Mock PNG exported from instance ${this.id} with scale ${scale}, transparent ${transparent}, dpi ${dpi}, dimensions ${width}x${height}`);
457
+ return placeholderPNG;
458
+ }
459
+ /**
460
+ * Export construction as SVG - Mock implementation
461
+ */
462
+ async exportSVG() {
463
+ this.ensureInitialized();
464
+ this.updateActivity();
465
+ // Return a simple SVG with mock construction
466
+ const mockSVG = `<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
467
+ <rect width="800" height="600" fill="white"/>
468
+ <text x="400" y="300" text-anchor="middle" font-family="Arial" font-size="20">Mock GeoGebra Construction</text>
469
+ ${Array.from(this.objects.values()).map(obj => {
470
+ if (obj.type === 'point') {
471
+ return `<circle cx="${(obj.x || 0) * 50 + 400}" cy="${(obj.y || 0) * -50 + 300}" r="3" fill="${obj.color || '#0000FF'}"/>`;
472
+ }
473
+ return '';
474
+ }).join('\n ')}
475
+ </svg>`;
476
+ logger_1.default.debug(`Mock SVG exported from instance ${this.id}`);
477
+ return mockSVG.trim();
478
+ }
479
+ /**
480
+ * Export construction as PDF (base64) - Mock implementation
481
+ */
482
+ async exportPDF() {
483
+ this.ensureInitialized();
484
+ this.updateActivity();
485
+ logger_1.default.debug(`Mock PDF export from instance ${this.id}`);
486
+ // Return mock PDF data (base64 encoded)
487
+ const mockPdfData = 'JVBERi0xLjQKJcOkw7zDtsOgCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nDPQM1Qo5ypUMFAw0DMwULBVqOZSUDBQykvMTbVSUDC2UshIzStRyMnPS7VVqAUAYQsKZAplbmRzdHJlYW0KZW5kb2JqCgozIDAgb2JqCjI4CmVuZG9iagoKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgNCAwIFI+PgplbmRvYmoKCjQgMCBvYmoKPDwvVHlwZS9QYWdlcy9LaWRzWzUgMCBSXS9Db3VudCAxPj4KZW5kb2JqCgo1IDAgb2JqCjw8L1R5cGUvUGFnZS9QYXJlbnQgNCAwIFIvTWVkaWFCb3hbMCAwIDYxMiA3OTJdL0NvbnRlbnRzIDIgMCBSPj4KZW5kb2JqCgp4cmVmCjAgNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAyOTQgMDAwMDAgbiAKMDAwMDAwMDAwOSAwMDAwMCBuIAowMDAwMDAwMjc0IDAwMDAwIG4gCjAwMDAwMDAzNDMgMDAwMDAgbiAKMDAwMDAwMDQwMCAwMDAwMCBuIAp0cmFpbGVyCjw8L1NpemUgNi9Sb290IDEgMCBSPj4Kc3RhcnR4cmVmCjUwMwolJUVPRg==';
488
+ return mockPdfData;
489
+ }
490
+ /**
491
+ * Export animation as frames (GEB-17 enhancement)
492
+ */
493
+ async exportAnimation(options = {}) {
494
+ this.ensureInitialized();
495
+ this.updateActivity();
496
+ const { duration = 5000, // 5 seconds
497
+ frameRate = 10, // 10 fps
498
+ format = 'frames', width = 800, height = 600 } = options;
499
+ logger_1.default.debug(`Mock animation export from instance ${this.id}`, { duration, frameRate, format, width, height });
500
+ // Calculate number of frames
501
+ const totalFrames = Math.ceil((duration / 1000) * frameRate);
502
+ // Generate mock frame data
503
+ const frames = [];
504
+ for (let i = 0; i < totalFrames; i++) {
505
+ // Generate a simple mock PNG frame (base64 encoded)
506
+ const mockFrameData = `iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==_frame_${i}`;
507
+ frames.push(mockFrameData);
508
+ }
509
+ logger_1.default.debug(`Mock animation export completed: ${frames.length} frames generated`);
510
+ if (format === 'frames') {
511
+ return frames;
512
+ }
513
+ else {
514
+ // For GIF format, return a mock GIF data string
515
+ return 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7_mock_gif';
516
+ }
517
+ }
518
+ /**
519
+ * Cleanup resources
520
+ */
521
+ async cleanup() {
522
+ logger_1.default.info(`Cleaning up Mock GeoGebra instance ${this.id}`);
523
+ this.objects.clear();
524
+ this.isInitialized = false;
525
+ logger_1.default.info(`Mock GeoGebra instance ${this.id} cleaned up successfully`);
526
+ }
527
+ /**
528
+ * Get instance state
529
+ */
530
+ getState() {
531
+ return {
532
+ id: this.id,
533
+ isReady: this.isInitialized,
534
+ lastActivity: this.lastActivity,
535
+ config: this.config
536
+ };
537
+ }
538
+ /**
539
+ * Update last activity timestamp
540
+ */
541
+ updateActivity() {
542
+ this.lastActivity = new Date();
543
+ }
544
+ /**
545
+ * Ensure instance is initialized
546
+ */
547
+ ensureInitialized() {
548
+ if (!this.isInitialized) {
549
+ throw new geogebra_1.GeoGebraConnectionError('Mock GeoGebra instance not initialized');
550
+ }
551
+ }
552
+ /**
553
+ * Mock implementation of equation solving
554
+ */
555
+ mockSolveEquation(equation, variable) {
556
+ logger_1.default.debug(`Mock solving equation: ${equation}${variable ? ` for ${variable}` : ''}`);
557
+ // Simple mock responses for common cases
558
+ if (equation.includes('x^2')) {
559
+ return variable ?
560
+ `{${variable} = -√(solution), ${variable} = √(solution)}` :
561
+ `Solutions: x = -√(solution), x = √(solution)`;
562
+ }
563
+ if (equation.includes('x =') || equation.includes('= x')) {
564
+ const match = equation.match(/(-?\d+(?:\.\d+)?)/);
565
+ const value = match ? match[1] : '0';
566
+ return variable ?
567
+ `{${variable} = ${value}}` :
568
+ `Solution: x = ${value}`;
569
+ }
570
+ // Linear equation pattern
571
+ if (equation.match(/\d*x\s*[+-]/)) {
572
+ return variable ?
573
+ `{${variable} = solution_value}` :
574
+ `Solution: x = solution_value`;
575
+ }
576
+ return `Mock solution for equation: ${equation}`;
577
+ }
578
+ /**
579
+ * Mock implementation of differentiation
580
+ */
581
+ mockDifferentiate(expression, variable = 'x') {
582
+ logger_1.default.debug(`Mock differentiating: ${expression} with respect to ${variable}`);
583
+ // Simple mock responses for common cases
584
+ if (expression === variable) {
585
+ return '1';
586
+ }
587
+ if (expression.includes(`${variable}^2`)) {
588
+ return `2*${variable}`;
589
+ }
590
+ if (expression.includes(`${variable}^3`)) {
591
+ return `3*${variable}^2`;
592
+ }
593
+ if (expression.includes(`sin(${variable})`)) {
594
+ return `cos(${variable})`;
595
+ }
596
+ if (expression.includes(`cos(${variable})`)) {
597
+ return `-sin(${variable})`;
598
+ }
599
+ if (expression.includes(`e^${variable}`)) {
600
+ return `e^${variable}`;
601
+ }
602
+ if (!expression.includes(variable)) {
603
+ return '0';
604
+ }
605
+ return `d/d${variable}(${expression})`;
606
+ }
607
+ /**
608
+ * Mock implementation of integration
609
+ */
610
+ mockIntegrate(expression, variable = 'x') {
611
+ logger_1.default.debug(`Mock integrating: ${expression} with respect to ${variable}`);
612
+ // Simple mock responses for common cases
613
+ if (expression === '1') {
614
+ return variable;
615
+ }
616
+ if (expression === variable) {
617
+ return `${variable}^2/2`;
618
+ }
619
+ if (expression.includes(`${variable}^2`)) {
620
+ return `${variable}^3/3`;
621
+ }
622
+ if (expression.includes(`${variable}^3`)) {
623
+ return `${variable}^4/4`;
624
+ }
625
+ if (expression.includes(`sin(${variable})`)) {
626
+ return `-cos(${variable})`;
627
+ }
628
+ if (expression.includes(`cos(${variable})`)) {
629
+ return `sin(${variable})`;
630
+ }
631
+ if (expression.includes(`e^${variable}`)) {
632
+ return `e^${variable}`;
633
+ }
634
+ return `∫(${expression}, ${variable})dx`;
635
+ }
636
+ /**
637
+ * Mock implementation of expression simplification
638
+ */
639
+ mockSimplify(expression) {
640
+ logger_1.default.debug(`Mock simplifying: ${expression}`);
641
+ // Simple mock simplifications
642
+ let simplified = expression;
643
+ // Remove unnecessary parentheses and spaces
644
+ simplified = simplified.replace(/\s+/g, '');
645
+ simplified = simplified.replace(/\(([^()]+)\)/g, '$1');
646
+ // Combine like terms (very basic)
647
+ simplified = simplified.replace(/(\d+)\*x\+(\d+)\*x/g, (_match, a, b) => {
648
+ return `${parseInt(a) + parseInt(b)}*x`;
649
+ });
650
+ // Basic arithmetic
651
+ simplified = simplified.replace(/(\d+)\+(\d+)/g, (_match, a, b) => {
652
+ return `${parseInt(a) + parseInt(b)}`;
653
+ });
654
+ simplified = simplified.replace(/(\d+)\*1/g, '$1');
655
+ simplified = simplified.replace(/1\*(\d+)/g, '$1');
656
+ simplified = simplified.replace(/\+0/g, '');
657
+ simplified = simplified.replace(/0\+/g, '');
658
+ return simplified === expression ? expression : simplified;
659
+ }
660
+ /**
661
+ * Animation Methods
662
+ */
663
+ async setAnimating(objName, animate) {
664
+ this.ensureInitialized();
665
+ this.updateActivity();
666
+ if (!this.objects.has(objName)) {
667
+ throw new Error(`Object ${objName} does not exist`);
668
+ }
669
+ if (animate) {
670
+ this.animatingObjects.add(objName);
671
+ if (!this.animationSpeeds.has(objName)) {
672
+ this.animationSpeeds.set(objName, 1); // Default speed
673
+ }
674
+ }
675
+ else {
676
+ this.animatingObjects.delete(objName);
677
+ }
678
+ logger_1.default.debug(`Mock instance ${this.id}: Set animating for ${objName}: ${animate}`);
679
+ }
680
+ async setAnimationSpeed(objName, speed) {
681
+ this.ensureInitialized();
682
+ this.updateActivity();
683
+ if (!this.objects.has(objName)) {
684
+ throw new Error(`Object ${objName} does not exist`);
685
+ }
686
+ this.animationSpeeds.set(objName, speed);
687
+ logger_1.default.debug(`Mock instance ${this.id}: Set animation speed for ${objName}: ${speed}`);
688
+ }
689
+ async startAnimation() {
690
+ this.ensureInitialized();
691
+ this.updateActivity();
692
+ this.isAnimating = true;
693
+ logger_1.default.debug(`Mock instance ${this.id}: Started animation for ${this.animatingObjects.size} objects`);
694
+ }
695
+ async stopAnimation() {
696
+ this.ensureInitialized();
697
+ this.updateActivity();
698
+ this.isAnimating = false;
699
+ logger_1.default.debug(`Mock instance ${this.id}: Stopped animation`);
700
+ }
701
+ async isAnimationRunning() {
702
+ this.ensureInitialized();
703
+ this.updateActivity();
704
+ return this.isAnimating && this.animatingObjects.size > 0;
705
+ }
706
+ async setTrace(objName, flag) {
707
+ this.ensureInitialized();
708
+ this.updateActivity();
709
+ if (!this.objects.has(objName)) {
710
+ throw new Error(`Object ${objName} does not exist`);
711
+ }
712
+ if (flag) {
713
+ this.tracedObjects.add(objName);
714
+ }
715
+ else {
716
+ this.tracedObjects.delete(objName);
717
+ }
718
+ logger_1.default.debug(`Mock instance ${this.id}: Set trace for ${objName}: ${flag}`);
719
+ }
720
+ async setValue(objName, value) {
721
+ this.ensureInitialized();
722
+ this.updateActivity();
723
+ const obj = this.objects.get(objName);
724
+ if (!obj) {
725
+ throw new Error(`Object ${objName} does not exist`);
726
+ }
727
+ obj.value = value;
728
+ logger_1.default.debug(`Mock instance ${this.id}: Set value for ${objName}: ${value}`);
729
+ }
730
+ }
731
+ exports.MockGeoGebraInstance = MockGeoGebraInstance;
732
+ //# sourceMappingURL=geogebra-mock.js.map