mani-calc 1.2.1 → 2.1.0
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/FRIEND_SETUP.md +132 -0
- package/README.md +373 -493
- package/SETUP.bat +126 -0
- package/bin/overlay.js +87 -19
- package/package.json +14 -3
- package/scripts/install-autostart.js +84 -0
- package/scripts/uninstall-autostart.js +49 -0
- package/src/core/currency-converter.js +191 -0
- package/src/core/date-time-calculator.js +376 -0
- package/src/core/programmer-calc.js +265 -0
- package/src/core/settings-manager.js +179 -0
- package/src/core/utilities.js +402 -0
- package/src/index.js +174 -17
- package/src/ui/floating-search.js +343 -2
- package/src/ui/overlay.html +178 -11
package/src/ui/overlay.html
CHANGED
|
@@ -27,16 +27,103 @@
|
|
|
27
27
|
--shortcut-bg: rgba(0, 0, 0, 0.02);
|
|
28
28
|
--key-bg: rgba(0, 0, 0, 0.1);
|
|
29
29
|
--border-color: rgba(0, 0, 0, 0.1);
|
|
30
|
+
--result-bg: rgba(0, 217, 255, 0.05);
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/* Dark Theme (default) */
|
|
32
34
|
body.dark {
|
|
33
35
|
--bg-color: rgba(30, 30, 30, 0.95);
|
|
34
36
|
--text-color: #eee;
|
|
35
37
|
--icon-color: #00D9FF;
|
|
36
|
-
--hint-color: #
|
|
38
|
+
--hint-color: #888;
|
|
37
39
|
--shortcut-bg: rgba(255, 255, 255, 0.05);
|
|
38
40
|
--key-bg: rgba(255, 255, 255, 0.1);
|
|
39
41
|
--border-color: rgba(255, 255, 255, 0.1);
|
|
42
|
+
--result-bg: rgba(0, 217, 255, 0.08);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Midnight Blue Theme */
|
|
46
|
+
body.midnight {
|
|
47
|
+
--bg-color: rgba(10, 22, 40, 0.95);
|
|
48
|
+
--text-color: #e0e8f0;
|
|
49
|
+
--icon-color: #4a9eff;
|
|
50
|
+
--hint-color: #6a8aaa;
|
|
51
|
+
--shortcut-bg: rgba(74, 158, 255, 0.05);
|
|
52
|
+
--key-bg: rgba(74, 158, 255, 0.15);
|
|
53
|
+
--border-color: rgba(74, 158, 255, 0.2);
|
|
54
|
+
--result-bg: rgba(74, 158, 255, 0.1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Forest Green Theme */
|
|
58
|
+
body.forest {
|
|
59
|
+
--bg-color: rgba(26, 47, 26, 0.95);
|
|
60
|
+
--text-color: #d0e8d0;
|
|
61
|
+
--icon-color: #4caf50;
|
|
62
|
+
--hint-color: #7ab87a;
|
|
63
|
+
--shortcut-bg: rgba(76, 175, 80, 0.05);
|
|
64
|
+
--key-bg: rgba(76, 175, 80, 0.15);
|
|
65
|
+
--border-color: rgba(76, 175, 80, 0.2);
|
|
66
|
+
--result-bg: rgba(76, 175, 80, 0.1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Sunset Orange Theme */
|
|
70
|
+
body.sunset {
|
|
71
|
+
--bg-color: rgba(45, 26, 26, 0.95);
|
|
72
|
+
--text-color: #f0e0d8;
|
|
73
|
+
--icon-color: #ff6b35;
|
|
74
|
+
--hint-color: #cc8866;
|
|
75
|
+
--shortcut-bg: rgba(255, 107, 53, 0.05);
|
|
76
|
+
--key-bg: rgba(255, 107, 53, 0.15);
|
|
77
|
+
--border-color: rgba(255, 107, 53, 0.2);
|
|
78
|
+
--result-bg: rgba(255, 107, 53, 0.1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Royal Purple Theme */
|
|
82
|
+
body.purple {
|
|
83
|
+
--bg-color: rgba(26, 26, 46, 0.95);
|
|
84
|
+
--text-color: #e8e0f0;
|
|
85
|
+
--icon-color: #9c27b0;
|
|
86
|
+
--hint-color: #aa77bb;
|
|
87
|
+
--shortcut-bg: rgba(156, 39, 176, 0.05);
|
|
88
|
+
--key-bg: rgba(156, 39, 176, 0.15);
|
|
89
|
+
--border-color: rgba(156, 39, 176, 0.2);
|
|
90
|
+
--result-bg: rgba(156, 39, 176, 0.1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Neon Glow Theme */
|
|
94
|
+
body.neon {
|
|
95
|
+
--bg-color: rgba(13, 13, 13, 0.95);
|
|
96
|
+
--text-color: #f0fff0;
|
|
97
|
+
--icon-color: #39ff14;
|
|
98
|
+
--hint-color: #55aa44;
|
|
99
|
+
--shortcut-bg: rgba(57, 255, 20, 0.05);
|
|
100
|
+
--key-bg: rgba(57, 255, 20, 0.15);
|
|
101
|
+
--border-color: rgba(57, 255, 20, 0.3);
|
|
102
|
+
--result-bg: rgba(57, 255, 20, 0.08);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Deep Ocean Theme */
|
|
106
|
+
body.ocean {
|
|
107
|
+
--bg-color: rgba(10, 25, 41, 0.95);
|
|
108
|
+
--text-color: #e0f4f8;
|
|
109
|
+
--icon-color: #00bcd4;
|
|
110
|
+
--hint-color: #5599aa;
|
|
111
|
+
--shortcut-bg: rgba(0, 188, 212, 0.05);
|
|
112
|
+
--key-bg: rgba(0, 188, 212, 0.15);
|
|
113
|
+
--border-color: rgba(0, 188, 212, 0.2);
|
|
114
|
+
--result-bg: rgba(0, 188, 212, 0.1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Light Theme */
|
|
118
|
+
body.light {
|
|
119
|
+
--bg-color: rgba(255, 255, 255, 0.98);
|
|
120
|
+
--text-color: #222;
|
|
121
|
+
--icon-color: #0066cc;
|
|
122
|
+
--hint-color: #666;
|
|
123
|
+
--shortcut-bg: rgba(0, 0, 0, 0.03);
|
|
124
|
+
--key-bg: rgba(0, 0, 0, 0.08);
|
|
125
|
+
--border-color: rgba(0, 0, 0, 0.1);
|
|
126
|
+
--result-bg: rgba(0, 102, 204, 0.05);
|
|
40
127
|
}
|
|
41
128
|
|
|
42
129
|
.container {
|
|
@@ -88,9 +175,12 @@
|
|
|
88
175
|
|
|
89
176
|
.result-container {
|
|
90
177
|
padding: 12px 20px;
|
|
91
|
-
background:
|
|
178
|
+
background: var(--result-bg);
|
|
92
179
|
display: none;
|
|
93
180
|
animation: slideDown 0.2s ease;
|
|
181
|
+
white-space: pre-wrap;
|
|
182
|
+
max-height: 300px;
|
|
183
|
+
overflow-y: auto;
|
|
94
184
|
}
|
|
95
185
|
|
|
96
186
|
.result-container.show {
|
|
@@ -204,6 +294,7 @@
|
|
|
204
294
|
input.value = '';
|
|
205
295
|
resultContainer.classList.remove('show');
|
|
206
296
|
shortcuts.classList.remove('show');
|
|
297
|
+
ipcRenderer.send('resize-window', 80);
|
|
207
298
|
});
|
|
208
299
|
|
|
209
300
|
// Handle input
|
|
@@ -215,11 +306,11 @@
|
|
|
215
306
|
return;
|
|
216
307
|
}
|
|
217
308
|
|
|
218
|
-
// Debounce for live preview
|
|
309
|
+
// Debounce for live preview (100ms for fast response)
|
|
219
310
|
clearTimeout(debounceTimer);
|
|
220
311
|
debounceTimer = setTimeout(() => {
|
|
221
312
|
processQuery(query, true);
|
|
222
|
-
},
|
|
313
|
+
}, 100);
|
|
223
314
|
});
|
|
224
315
|
|
|
225
316
|
// Handle Enter key
|
|
@@ -234,16 +325,66 @@
|
|
|
234
325
|
}
|
|
235
326
|
});
|
|
236
327
|
|
|
328
|
+
// Simple math evaluator for live preview
|
|
329
|
+
function evaluateMathExpression(expr) {
|
|
330
|
+
try {
|
|
331
|
+
// Clean the expression
|
|
332
|
+
let cleanExpr = expr.trim();
|
|
333
|
+
|
|
334
|
+
// Replace ^ with ** for exponentiation
|
|
335
|
+
cleanExpr = cleanExpr.replace(/\^/g, '**');
|
|
336
|
+
|
|
337
|
+
// Replace × with *
|
|
338
|
+
cleanExpr = cleanExpr.replace(/×/g, '*');
|
|
339
|
+
|
|
340
|
+
// Replace ÷ with /
|
|
341
|
+
cleanExpr = cleanExpr.replace(/÷/g, '/');
|
|
342
|
+
|
|
343
|
+
// Handle implicit multiplication (e.g., "2(3+4)" -> "2*(3+4)")
|
|
344
|
+
cleanExpr = cleanExpr.replace(/(\d)\(/g, '$1*(');
|
|
345
|
+
|
|
346
|
+
// Security: Only allow safe math characters
|
|
347
|
+
if (!/^[\d\s\+\-\*\/\(\)\.\,\%]+$/.test(cleanExpr)) {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Handle percentage (e.g., "50%" -> "0.5")
|
|
352
|
+
cleanExpr = cleanExpr.replace(/(\d+(?:\.\d+)?)\s*%/g, '($1/100)');
|
|
353
|
+
|
|
354
|
+
// Evaluate using Function (safer than eval for math expressions)
|
|
355
|
+
const result = Function('"use strict"; return (' + cleanExpr + ')')();
|
|
356
|
+
|
|
357
|
+
// Check if result is valid
|
|
358
|
+
if (typeof result === 'number' && !isNaN(result) && isFinite(result)) {
|
|
359
|
+
// Round to reasonable precision
|
|
360
|
+
if (Math.abs(result - Math.round(result)) < 1e-10) {
|
|
361
|
+
return Math.round(result);
|
|
362
|
+
}
|
|
363
|
+
return Math.round(result * 1e10) / 1e10;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return null;
|
|
367
|
+
} catch (e) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
237
372
|
// Process query
|
|
238
373
|
function processQuery(query, isPreview) {
|
|
239
374
|
if (!isPreview) {
|
|
240
375
|
ipcRenderer.send('process-query', query);
|
|
241
376
|
} else {
|
|
242
|
-
// Show preview for calculations
|
|
377
|
+
// Show live preview for calculations
|
|
243
378
|
try {
|
|
244
|
-
//
|
|
245
|
-
|
|
246
|
-
|
|
379
|
+
// Try to evaluate the expression live
|
|
380
|
+
const result = evaluateMathExpression(query);
|
|
381
|
+
|
|
382
|
+
if (result !== null) {
|
|
383
|
+
// Show the live result immediately
|
|
384
|
+
showResult(`= ${result}`, 'Press Enter to copy to clipboard', 'success');
|
|
385
|
+
} else if (/^[\d\s\+\-\*\/\(\)\.\^×÷]+$/.test(query)) {
|
|
386
|
+
// It looks like a math expression but couldn't be evaluated yet
|
|
387
|
+
showResult('...', 'Keep typing or press Enter', 'success');
|
|
247
388
|
}
|
|
248
389
|
} catch (error) {
|
|
249
390
|
// Ignore preview errors
|
|
@@ -251,17 +392,37 @@
|
|
|
251
392
|
}
|
|
252
393
|
}
|
|
253
394
|
|
|
254
|
-
//
|
|
395
|
+
// Available themes
|
|
396
|
+
const themes = ['dark', 'light', 'midnight', 'forest', 'sunset', 'purple', 'neon', 'ocean'];
|
|
397
|
+
let currentThemeIndex = 0;
|
|
398
|
+
|
|
399
|
+
// Apply theme by name
|
|
400
|
+
function applyTheme(themeName) {
|
|
401
|
+
themes.forEach(t => document.body.classList.remove(t));
|
|
402
|
+
if (themeName && themes.includes(themeName)) {
|
|
403
|
+
document.body.classList.add(themeName);
|
|
404
|
+
currentThemeIndex = themes.indexOf(themeName);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Handle theme toggle (cycle through themes)
|
|
255
409
|
ipcRenderer.on('toggle-theme', () => {
|
|
256
|
-
|
|
410
|
+
currentThemeIndex = (currentThemeIndex + 1) % themes.length;
|
|
411
|
+
applyTheme(themes[currentThemeIndex]);
|
|
257
412
|
});
|
|
258
413
|
|
|
259
414
|
// Handle result from main process
|
|
260
415
|
ipcRenderer.on('query-result', (event, result) => {
|
|
261
416
|
if (result.error) {
|
|
262
417
|
showResult(`✗ ${result.error}`, '', 'error');
|
|
418
|
+
} else if (result.type === 'theme') {
|
|
419
|
+
// Apply the theme and show success
|
|
420
|
+
applyTheme(result.themeId);
|
|
421
|
+
showResult(`✓ ${result.formatted}`, '', 'success');
|
|
263
422
|
} else if (result.type === 'system_command') {
|
|
264
|
-
showResult(`✓ ${result.formatted}`, '
|
|
423
|
+
showResult(`✓ ${result.formatted}`, '', 'system');
|
|
424
|
+
} else if (result.type === 'info') {
|
|
425
|
+
showResult(`ℹ️ ${result.formatted}`, '', 'success');
|
|
265
426
|
} else {
|
|
266
427
|
showResult(`✓ ${result.formatted}`, 'Copied to clipboard', 'success');
|
|
267
428
|
}
|
|
@@ -273,6 +434,12 @@
|
|
|
273
434
|
resultText.className = `result-text ${type}`;
|
|
274
435
|
resultHint.textContent = hint;
|
|
275
436
|
resultContainer.classList.add('show');
|
|
437
|
+
|
|
438
|
+
// Calculate new height
|
|
439
|
+
setTimeout(() => {
|
|
440
|
+
const height = document.body.offsetHeight;
|
|
441
|
+
ipcRenderer.send('resize-window', height);
|
|
442
|
+
}, 10);
|
|
276
443
|
}
|
|
277
444
|
|
|
278
445
|
// Auto-focus on load
|