summaryrefslogtreecommitdiff
path: root/client/simple/src/js/plugin/Calculator.ts
blob: 95196a8408287acb8a23912fda9c149fa2e83a28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// SPDX-License-Identifier: AGPL-3.0-or-later

import {
  absDependencies,
  addDependencies,
  create,
  divideDependencies,
  eDependencies,
  evaluateDependencies,
  expDependencies,
  factorialDependencies,
  gcdDependencies,
  lcmDependencies,
  log1pDependencies,
  log2Dependencies,
  log10Dependencies,
  logDependencies,
  modDependencies,
  multiplyDependencies,
  nthRootDependencies,
  piDependencies,
  powDependencies,
  roundDependencies,
  signDependencies,
  sqrtDependencies,
  subtractDependencies
} from "mathjs/number";
import { Plugin } from "../Plugin.ts";
import { appendAnswerElement } from "../util/appendAnswerElement.ts";
import { getElement } from "../util/getElement.ts";

/**
 * Parses and solves mathematical expressions. Can do basic arithmetic and
 * evaluate some functions.
 *
 * @example
 * "(3 + 5) / 2" = "4"
 * "e ^ 2 + pi" = "10.530648752520442"
 * "gcd(48, 18) + lcm(4, 5)" = "26"
 *
 * @remarks
 * Depends on `mathjs` library.
 */
export default class Calculator extends Plugin {
  public constructor() {
    super("calculator");
  }

  /**
   * @remarks
   * Compare bundle size after adding or removing features.
   */
  private static readonly math = create({
    ...absDependencies,
    ...addDependencies,
    ...divideDependencies,
    ...eDependencies,
    ...evaluateDependencies,
    ...expDependencies,
    ...factorialDependencies,
    ...gcdDependencies,
    ...lcmDependencies,
    ...log10Dependencies,
    ...log1pDependencies,
    ...log2Dependencies,
    ...logDependencies,
    ...modDependencies,
    ...multiplyDependencies,
    ...nthRootDependencies,
    ...piDependencies,
    ...powDependencies,
    ...roundDependencies,
    ...signDependencies,
    ...sqrtDependencies,
    ...subtractDependencies
  });

  protected async run(): Promise<string | undefined> {
    const searchInput = getElement<HTMLInputElement>("q");
    const node = Calculator.math.parse(searchInput.value);

    try {
      return `${node.toString()} = ${node.evaluate()}`;
    } catch {
      // not a compatible math expression
      return;
    }
  }

  protected async post(result: string): Promise<void> {
    appendAnswerElement(result);
  }
}